diff --git a/articleview.cc b/articleview.cc index 4741a6982..61db18c7d 100644 --- a/articleview.cc +++ b/articleview.cc @@ -217,6 +217,14 @@ QString dictionaryIdFromScrollTo( QString const & scrollTo ) return scrollTo.mid( scrollToPrefixLength ); } +QString scrollToFromUrl( QUrl const & url ) +{ + QString value = Qt4x5::Url::queryItemValue( url, "scrollto" ); + if( isScrollTo( value ) ) + return value; + return QString(); +} + QString searchStatusMessageNoMatches() { return ArticleView::tr( "Phrase not found" ); @@ -261,6 +269,7 @@ ArticleView::ArticleView( QWidget * parent, ArticleNetworkAccessManager & nm, goForwardAction( this ), selectCurrentArticleAction( this ), copyAsTextAction( this ), + jumpToTargetArticleAction( this ), inspectAction( this ), openSearchAction( openSearchAction_ ), searchIsOpened( false ), @@ -349,6 +358,12 @@ ArticleView::ArticleView( QWidget * parent, ArticleNetworkAccessManager & nm, connect( ©AsTextAction, SIGNAL( triggered() ), this, SLOT( copyAsText() ) ); + jumpToTargetArticleAction.setShortcut( QKeySequence( "Alt+T" ) ); + jumpToTargetArticleAction.setText( tr( "Jump to Target Article" ) ); + ui.definition->addAction( &jumpToTargetArticleAction ); + connect( &jumpToTargetArticleAction, SIGNAL( triggered() ), + this, SLOT( jumpToTargetArticle() ) ); + inspectAction.setShortcut( QKeySequence( Qt::Key_F12 ) ); inspectAction.setText( tr( "Inspect" ) ); ui.definition->addAction( &inspectAction ); @@ -615,9 +630,10 @@ void ArticleView::loadFinished( bool ) } } else + if( cfg.preferences.autoScrollToTargetArticle ) { - QString const scrollTo = Qt4x5::Url::queryItemValue( url, "scrollto" ); - if( isScrollTo( scrollTo ) ) + QString const scrollTo = scrollToFromUrl( url ); + if( !scrollTo.isEmpty() ) { // There is no active article saved in history, but we have it as a parameter. // setCurrentArticle will save it and scroll there. @@ -1928,10 +1944,15 @@ void ArticleView::contextMenuRequested( QPoint const & pos ) menu.addAction( ui.definition->pageAction( QWebPage::SelectAll ) ); } + QStringList const ids = getArticlesList(); + + QString const scrollTo = scrollToFromUrl( ui.definition->url() ); + if( !scrollTo.isEmpty() && ids.contains( dictionaryIdFromScrollTo( scrollTo ) ) ) + menu.addAction( &jumpToTargetArticleAction ); + map< QAction *, QString > tableOfContents; // Add table of contents - QStringList ids = getArticlesList(); if ( !menu.isEmpty() && ids.size() ) menu.addSeparator(); @@ -2093,6 +2114,15 @@ void ArticleView::contextMenuRequested( QPoint const & pos ) #endif } +void ArticleView::jumpToTargetArticle() +{ + QString const scrollTo = scrollToFromUrl( ui.definition->url() ); + // When there is no "scrollto" query item in the current definition's URL + // and this slot's action is triggered via the shortcut - do nothing. + if( !scrollTo.isEmpty() ) + setCurrentArticle( scrollTo, true ); +} + void ArticleView::resourceDownloadFinished() { if ( resourceDownloadRequests.empty() ) diff --git a/articleview.hh b/articleview.hh index a9047aac9..e403846c5 100644 --- a/articleview.hh +++ b/articleview.hh @@ -37,7 +37,7 @@ class ArticleView: public QFrame QAction pasteAction, articleUpAction, articleDownAction, goBackAction, goForwardAction, selectCurrentArticleAction, - copyAsTextAction, inspectAction; + copyAsTextAction, jumpToTargetArticleAction, inspectAction; QAction & openSearchAction; bool searchIsOpened; bool expandOptionalParts; @@ -273,6 +273,8 @@ private slots: void linkHovered( const QString & link, const QString & title, const QString & textContent ); void contextMenuRequested( QPoint const & ); + void jumpToTargetArticle(); + void resourceDownloadFinished(); /// We handle pasting by attempting to define the word in clipboard. diff --git a/config.cc b/config.cc index e0e6f1b7e..42f891d88 100644 --- a/config.cc +++ b/config.cc @@ -221,6 +221,7 @@ Preferences::Preferences(): autoStart( false ), doubleClickTranslates( true ), selectWordBySingleClick( false ), + autoScrollToTargetArticle( true ), escKeyHidesMainWindow( false ), alwaysOnTop ( false ), searchInDock ( false ), @@ -871,6 +872,9 @@ Class load() THROW_SPEC( exError ) if ( !preferences.namedItem( "selectWordBySingleClick" ).isNull() ) c.preferences.selectWordBySingleClick = ( preferences.namedItem( "selectWordBySingleClick" ).toElement().text() == "1" ); + if ( !preferences.namedItem( "autoScrollToTargetArticle" ).isNull() ) + c.preferences.autoScrollToTargetArticle = ( preferences.namedItem( "autoScrollToTargetArticle" ).toElement().text() == "1" ); + if ( !preferences.namedItem( "escKeyHidesMainWindow" ).isNull() ) c.preferences.escKeyHidesMainWindow = ( preferences.namedItem( "escKeyHidesMainWindow" ).toElement().text() == "1" ); @@ -1741,6 +1745,10 @@ void save( Class const & c ) THROW_SPEC( exError ) opt.appendChild( dd.createTextNode( c.preferences.selectWordBySingleClick ? "1":"0" ) ); preferences.appendChild( opt ); + opt = dd.createElement( "autoScrollToTargetArticle" ); + opt.appendChild( dd.createTextNode( c.preferences.autoScrollToTargetArticle ? "1":"0" ) ); + preferences.appendChild( opt ); + opt = dd.createElement( "escKeyHidesMainWindow" ); opt.appendChild( dd.createTextNode( c.preferences.escKeyHidesMainWindow ? "1":"0" ) ); preferences.appendChild( opt ); diff --git a/config.hh b/config.hh index b38a91b42..60703615c 100644 --- a/config.hh +++ b/config.hh @@ -293,6 +293,7 @@ struct Preferences bool autoStart; bool doubleClickTranslates; bool selectWordBySingleClick; + bool autoScrollToTargetArticle; bool escKeyHidesMainWindow; bool alwaysOnTop; diff --git a/preferences.cc b/preferences.cc index 1e83f78fe..d37218424 100644 --- a/preferences.cc +++ b/preferences.cc @@ -169,6 +169,7 @@ Preferences::Preferences( QWidget * parent, Config::Class & cfg_ ): ui.cbAutostart->setChecked( p.autoStart ); ui.doubleClickTranslates->setChecked( p.doubleClickTranslates ); ui.selectBySingleClick->setChecked( p.selectWordBySingleClick); + ui.autoScrollToTargetArticle->setChecked( p.autoScrollToTargetArticle ); ui.escKeyHidesMainWindow->setChecked( p.escKeyHidesMainWindow ); ui.enableMainWindowHotkey->setChecked( p.enableMainWindowHotkey ); @@ -387,6 +388,7 @@ Config::Preferences Preferences::getPreferences() p.autoStart = ui.cbAutostart->isChecked(); p.doubleClickTranslates = ui.doubleClickTranslates->isChecked(); p.selectWordBySingleClick = ui.selectBySingleClick->isChecked(); + p.autoScrollToTargetArticle = ui.autoScrollToTargetArticle->isChecked(); p.escKeyHidesMainWindow = ui.escKeyHidesMainWindow->isChecked(); p.enableMainWindowHotkey = ui.enableMainWindowHotkey->isChecked(); diff --git a/preferences.ui b/preferences.ui index 073fad178..6a6f69810 100644 --- a/preferences.ui +++ b/preferences.ui @@ -369,6 +369,23 @@ be the last ones. + + + + Normally, clicking on a link, double-clicking on a word or looking up +selection in an article loads the translation and almost immediately +scrolls to the article from the same dictionary. With this option off, +however, the article from the topmost dictionary is shown. +Once the translation is loaded, pressing Alt+T scrolls to the target article. + + + Automatically scroll to target article + + + true + + +