GUI result list: improve behaviour of paging with either links or keys and buttons

Always shift to next/prev top of page when using links. Follow logical progression of page sections
when using pageup/down keys or arrow buttons. Fixes issue #177
This commit is contained in:
Jean-Francois Dockes 2022-08-18 12:13:42 +02:00
parent 3404c2f726
commit 426fee8a86
2 changed files with 34 additions and 11 deletions

View File

@ -106,9 +106,7 @@ function saveLoc(ev)
} }
)raw"); )raw");
bool RclWebPage::acceptNavigationRequest(const QUrl& url, bool RclWebPage::acceptNavigationRequest(const QUrl& url, NavigationType tp, bool isMainFrame)
NavigationType tp,
bool isMainFrame)
{ {
Q_UNUSED(isMainFrame); Q_UNUSED(isMainFrame);
LOGDEB0("QWebEnginePage::acceptNavigationRequest. Type: " << LOGDEB0("QWebEnginePage::acceptNavigationRequest. Type: " <<
@ -315,6 +313,7 @@ ResList::ResList(QWidget* parent, const char* name)
this, SLOT(onLinkClicked(const QUrl &))); this, SLOT(onLinkClicked(const QUrl &)));
#else #else
LOGDEB("Reslist: using Webengine\n"); LOGDEB("Reslist: using Webengine\n");
connect(page(), SIGNAL(loadFinished(bool)), this, SLOT(runStoredJS(bool)));
#endif #endif
settings()->setAttribute(QWEBSETTINGS::JavascriptEnabled, true); settings()->setAttribute(QWEBSETTINGS::JavascriptEnabled, true);
#else #else
@ -389,8 +388,17 @@ void ResList::setRclMain(RclMain *m, bool ismain)
} }
} }
void ResList::runStoredJS() void ResList::runStoredJS(bool res)
{ {
if (m_js.isEmpty()) {
return;
}
LOGDEB0("ResList::runStoredJS: res " << res << " cnt " << m_js_countdown <<
" m_js [" << qs2utf8s(m_js) << "]\n");
if (m_js_countdown > 0) {
m_js_countdown--;
return;
}
runJS(m_js); runJS(m_js);
m_js.clear(); m_js.clear();
} }
@ -633,19 +641,23 @@ void ResList::resPageUpOrBack()
#if defined(USING_WEBKIT) #if defined(USING_WEBKIT)
if (scrollIsAtTop()) { if (scrollIsAtTop()) {
resultPageBack(); resultPageBack();
runJS("window.scrollBy(0,50000);");
} else { } else {
page()->mainFrame()->scroll(0, -int(0.9*geometry().height())); page()->mainFrame()->scroll(0, -int(0.9*geometry().height()));
} }
setupArrows(); setupArrows();
#elif defined(USING_WEBENGINE) #elif defined(USING_WEBENGINE)
if (scrollIsAtTop()) { if (scrollIsAtTop()) {
// Displaypage first calls resetview() which causes a page load event. We want to run the js
// on the second event.
m_js_countdown = 1;
m_js = "window.scrollBy(0,50000);";
resultPageBack(); resultPageBack();
runJS("window.scrollBy(0,50000);");
} else { } else {
QString js = QString("window.scrollBy(%1, %2);").arg(0).arg(-int(0.9*geometry().height())); QString js = QString("window.scrollBy(%1, %2);").arg(0).arg(-int(0.9*geometry().height()));
runJS(js); runJS(js);
} }
setupArrows(); QTimer::singleShot(50, this, SLOT(setupArrows()));
#else #else
int vpos = verticalScrollBar()->value(); int vpos = verticalScrollBar()->value();
verticalScrollBar()->triggerAction(QAbstractSlider::SliderPageStepSub); verticalScrollBar()->triggerAction(QAbstractSlider::SliderPageStepSub);
@ -666,12 +678,11 @@ void ResList::resPageDownOrNext()
#elif defined(USING_WEBENGINE) #elif defined(USING_WEBENGINE)
if (scrollIsAtBottom()) { if (scrollIsAtBottom()) {
resultPageNext(); resultPageNext();
runJS("window.scrollTo(0, 0);");
} else { } else {
QString js = QString("window.scrollBy(%1, %2);").arg(0).arg(int(0.9*geometry().height())); QString js = QString("window.scrollBy(%1, %2);").arg(0).arg(int(0.9*geometry().height()));
runJS(js); runJS(js);
} }
setupArrows(); QTimer::singleShot(50, this, SLOT(setupArrows()));
#else #else
int vpos = verticalScrollBar()->value(); int vpos = verticalScrollBar()->value();
verticalScrollBar()->triggerAction(QAbstractSlider::SliderPageStepAdd); verticalScrollBar()->triggerAction(QAbstractSlider::SliderPageStepAdd);
@ -747,6 +758,9 @@ void ResList::resultPageBack()
if (m_pager->hasPrev()) { if (m_pager->hasPrev()) {
m_pager->resultPageBack(); m_pager->resultPageBack();
displayPage(); displayPage();
#ifdef USING_WEBENGINE
runJS("window.scrollTo(0,0);");
#endif
} }
} }
@ -757,6 +771,9 @@ void ResList::resultPageFirst()
m_pager->setPageSize(prefs.respagesize); m_pager->setPageSize(prefs.respagesize);
m_pager->resultPageFirst(); m_pager->resultPageFirst();
displayPage(); displayPage();
#ifdef USING_WEBENGINE
runJS("window.scrollTo(0,0);");
#endif
} }
// Fill up result list window with next screen of hits // Fill up result list window with next screen of hits
@ -765,6 +782,9 @@ void ResList::resultPageNext()
if (m_pager->hasNext()) { if (m_pager->hasNext()) {
m_pager->resultPageNext(); m_pager->resultPageNext();
displayPage(); displayPage();
#ifdef USING_WEBENGINE
runJS("window.scrollTo(0,0);");
#endif
} }
} }
@ -835,7 +855,7 @@ void ResList::displayPage()
LOGDEB0("ResList::displayPg: hasNext " << m_pager->hasNext() << LOGDEB0("ResList::displayPg: hasNext " << m_pager->hasNext() <<
" atBot " << scrollIsAtBottom() << " hasPrev " << " atBot " << scrollIsAtBottom() << " hasPrev " <<
m_pager->hasPrev() << " at Top " << scrollIsAtTop() << " \n"); m_pager->hasPrev() << " at Top " << scrollIsAtTop() << " \n");
setupArrows(); QTimer::singleShot(100, this, SLOT(setupArrows()));
// Possibly color paragraph of current preview if any // Possibly color paragraph of current preview if any
previewExposed(m_curPvDoc); previewExposed(m_curPvDoc);

View File

@ -125,9 +125,10 @@ public slots:
virtual void onLinkClicked(const QUrl &); virtual void onLinkClicked(const QUrl &);
virtual void onPopupJsDone(const QVariant&); virtual void onPopupJsDone(const QVariant&);
void runJS(const QString& js); void runJS(const QString& js);
void runStoredJS();
protected slots: protected slots:
virtual void languageChange(); virtual void languageChange();
void runStoredJS(bool);
void setupArrows();
private: private:
QtGuiResListPager *m_pager{0}; QtGuiResListPager *m_pager{0};
@ -150,7 +151,10 @@ private:
virtual int docnumfromparnum(int); virtual int docnumfromparnum(int);
virtual std::pair<int,int> parnumfromdocnum(int); virtual std::pair<int,int> parnumfromdocnum(int);
#endif #endif
// Running js after page load. Sometimes we don't want to do it on the first event (which may be
// a reset), hence the countdown.
QString m_js; QString m_js;
int m_js_countdown{0};
RclMain *m_rclmain{0}; RclMain *m_rclmain{0};
bool m_ismainres{true}; bool m_ismainres{true};
@ -160,7 +164,6 @@ private:
void resetView(); void resetView();
bool scrollIsAtTop(); bool scrollIsAtTop();
bool scrollIsAtBottom(); bool scrollIsAtBottom();
void setupArrows();
}; };
#ifdef USING_WEBENGINE #ifdef USING_WEBENGINE