From 3762f22e769a288f89b177f4bc6c1fa602704528 Mon Sep 17 00:00:00 2001 From: Tvangeste Date: Sun, 5 Jun 2011 13:49:50 +0200 Subject: [PATCH] Implemented Dictionaries Pane, to show dicts in which results were found. It is a separate detacheable pane, which could also be enabled/disabled, it tracks the current tab's contains, and lists those dictionaries that contributed their content to the current translation. Clicking on dictionary name jumps to the appropriate article from this dictionary, which improves the navigation flow. The Dictionaries Pane: * Shows both dictionaries' names and icons. * Does not consume resources when hidden. * Properly styled. * Properly handles app-wide shortcuts (Esc, Ctrl-L, Alt-D, Enter, Alt-Up/Down). --- articleview.cc | 26 ++++++++++ articleview.hh | 13 +++-- dictspanewidget.hh | 23 +++++++++ goldendict.pro | 3 +- mainwindow.cc | 114 ++++++++++++++++++++++++++++++++++++++++- mainwindow.hh | 11 ++++ mainwindow.ui | 33 ++++++++++++ qt-style-st-lingvo.css | 2 +- qt-style.css | 2 +- 9 files changed, 218 insertions(+), 9 deletions(-) create mode 100644 dictspanewidget.hh diff --git a/articleview.cc b/articleview.cc index 6bf106e0..a2e1d449 100644 --- a/articleview.cc +++ b/articleview.cc @@ -366,6 +366,32 @@ QString ArticleView::getCurrentArticle() return QString(); } +void ArticleView::jumpToDictionary(QString const & dictName) +{ + // Find the dictionary with the specified name + + for( unsigned x = allDictionaries.size(); x--; ) + { + + if ( QString::fromUtf8( allDictionaries[ x ]->getName().c_str()) == dictName ) + { + + // Check that one of the articles belongs to the specified dictionary. + + QStringList ids = getArticlesList(); + for( QStringList::const_iterator i = ids.constBegin(); i != ids.constEnd(); ++i ) + { + if ( allDictionaries[ x ]->getId() == i->toUtf8().data() ) { + setCurrentArticle( "gdfrom-" + *i, true ); + break; + } + } + + break; + } + } +} + void ArticleView::setCurrentArticle( QString const & id, bool moveToIt ) { if ( !id.startsWith( "gdfrom-" ) ) diff --git a/articleview.hh b/articleview.hh index 94a8779b..83c98bef 100644 --- a/articleview.hh +++ b/articleview.hh @@ -142,7 +142,15 @@ public: /// Closes search if it's open and returns true. Returns false if it /// wasn't open. bool closeSearch(); - + + /// Jumps to the article specified by the dictionary name, + /// by executing a javascript code. + void jumpToDictionary( QString const & ); + + /// Returns all articles current present in view, as a list of dictionary + /// string ids. + QStringList getArticlesList(); + signals: void iconChanged( ArticleView *, QIcon const & icon ); @@ -201,9 +209,6 @@ private: /// returns 0. unsigned getGroup( QUrl const & ); - /// Returns all articles current present in view, as a list of dictionary - /// string ids. - QStringList getArticlesList(); /// Returns current article in the view, in the form of "gdfrom-xxx" id. QString getCurrentArticle(); diff --git a/dictspanewidget.hh b/dictspanewidget.hh new file mode 100644 index 00000000..c9d8e42b --- /dev/null +++ b/dictspanewidget.hh @@ -0,0 +1,23 @@ +/* This file is (c) 2008-2011 Konstantin Isakov + * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ + +#ifndef __DICTSPANEWIDGET_HH_INCLUDED__ +#define __DICTSPANEWIDGET_HH_INCLUDED__ + +#include +#include + +/// A widget holding the contents of the 'Dictionaries pane' docklet. +class DictsPaneWidget: public QWidget +{ +public: + + DictsPaneWidget( QWidget * parent = 0 ): QWidget( parent ) + {} + + virtual QSize sizeHint() const + { return QSize( 204, 204 ); } + +}; + +#endif diff --git a/goldendict.pro b/goldendict.pro index e9c173f4..487dbc6a 100644 --- a/goldendict.pro +++ b/goldendict.pro @@ -161,7 +161,8 @@ HEADERS += folding.hh \ country.hh \ about.hh \ programs.hh \ - parsecmdline.hh + parsecmdline.hh \ + dictspanewidget.hh FORMS += groups.ui \ dictgroupwidget.ui \ mainwindow.ui \ diff --git a/mainwindow.cc b/mainwindow.cc index b8d16a76..594dd586 100644 --- a/mainwindow.cc +++ b/mainwindow.cc @@ -26,6 +26,7 @@ MainWindow::MainWindow( Config::Class & cfg_ ): trayIcon( 0 ), groupLabel( &searchPaneTitleBar ), groupList( &searchPaneTitleBar ), + foundInDictsLabel( &dictsPaneTitleBar ), escAction( this ), focusTranslateLineAction( this ), addTabAction( this ), @@ -68,6 +69,15 @@ MainWindow::MainWindow( Config::Class & cfg_ ): ui.searchPane->setTitleBarWidget( &searchPaneTitleBar ); + // Make the dictionaries pane's titlebar + foundInDictsLabel.setText( tr( "Found in Dictionaries:" ) ); + dictsPaneTitleBarLayout.addWidget( &foundInDictsLabel ); + dictsPaneTitleBar.setLayout( &dictsPaneTitleBarLayout ); + ui.dictsPane->setTitleBarWidget( &dictsPaneTitleBar ); + + connect( ui.dictsPane, SIGNAL( visibilityChanged( bool ) ), + this, SLOT( dictsPaneVisibilityChanged ( bool ) ) ); + // Make the toolbar navToolbar = addToolBar( tr( "Navigation" ) ); navToolbar->setObjectName( "navToolbar" ); @@ -154,9 +164,12 @@ MainWindow::MainWindow( Config::Class & cfg_ ): this, SLOT( focusTranslateLine() ) ); ui.centralWidget->addAction( &escAction ); + ui.dictsPane->addAction( &escAction ); ui.searchPaneWidget->addAction( &escAction ); groupList.addAction( &escAction ); + ui.centralWidget->addAction( &focusTranslateLineAction ); + ui.dictsPane->addAction( &focusTranslateLineAction ); ui.searchPaneWidget->addAction( &focusTranslateLineAction ); groupList.addAction( &focusTranslateLineAction ); @@ -239,6 +252,7 @@ MainWindow::MainWindow( Config::Class & cfg_ ): // Populate 'View' menu ui.menuView->addAction( ui.searchPane->toggleViewAction() ); + ui.menuView->addAction( ui.dictsPane->toggleViewAction() ); ui.menuView->addSeparator(); ui.menuView->addAction( dictionaryBar.toggleViewAction() ); ui.menuView->addAction( navToolbar->toggleViewAction() ); @@ -350,6 +364,9 @@ MainWindow::MainWindow( Config::Class & cfg_ ): connect( ui.wordList, SIGNAL( itemSelectionChanged() ), this, SLOT( wordListSelectionChanged() ) ); + connect( ui.dictsList, SIGNAL( itemSelectionChanged() ), + this, SLOT( dictsListSelectionChanged() ) ); + connect( &wordFinder, SIGNAL( updated() ), this, SLOT( prefixMatchUpdated() ) ); connect( &wordFinder, SIGNAL( finished() ), @@ -360,6 +377,7 @@ MainWindow::MainWindow( Config::Class & cfg_ ): ui.translateLine->installEventFilter( this ); ui.wordList->installEventFilter( this ); + ui.dictsList->installEventFilter(this); if ( cfg.mainWindowGeometry.size() ) restoreGeometry( cfg.mainWindowGeometry ); @@ -961,11 +979,14 @@ void MainWindow::pageLoaded( ArticleView * view ) if ( cfg.preferences.pronounceOnLoadMain ) pronounce( view ); + + updateFoundInDictsList(); } void MainWindow::tabSwitched( int ) { updatePronounceAvailability(); + updateFoundInDictsList(); } void MainWindow::tabMenuRequested(QPoint pos) @@ -995,6 +1016,53 @@ void MainWindow::pronounce( ArticleView * view ) dynamic_cast< ArticleView & >( *( ui.tabWidget->currentWidget() ) ).playSound(); } +void MainWindow::dictsPaneVisibilityChanged( bool visible ) +{ + if (visible) { + updateFoundInDictsList(); + } +} + +void MainWindow::updateFoundInDictsList() +{ + if (!ui.dictsList->isVisible()) + { + // nothing to do, the list is not visible + return; + } + + ui.dictsList->clear(); + + if ( QWidget * cw = ui.tabWidget->currentWidget() ) + { + ArticleView & view = dynamic_cast< ArticleView & >( *( cw ) ); + + QStringList ids = view.getArticlesList(); + + for( QStringList::const_iterator i = ids.constBegin(); i != ids.constEnd(); ++i) + { + // Find this dictionary + + for( unsigned x = dictionaries.size(); x--; ) + { + if ( dictionaries[ x ]->getId() == i->toUtf8().data() ) + { + QString dictName = QString::fromUtf8( dictionaries[ x ]->getName().c_str() ); + QListWidgetItem * item = + new QListWidgetItem( + dictionaries[ x ]->getIcon(), + dictName, + ui.dictsList, QListWidgetItem::Type ); + item->setToolTip(dictName); + + ui.dictsList->addItem( item ); + break; + } + } + } + } +} + void MainWindow::updatePronounceAvailability() { bool pronounceEnabled = ui.tabWidget->count() > 0 && @@ -1343,7 +1411,34 @@ bool MainWindow::eventFilter( QObject * obj, QEvent * ev ) // Handle typing events used to initiate new lookups if ( keyEvent->modifiers() & - ( Qt::ControlModifier | Qt::ShiftModifier | Qt::AltModifier | Qt::MetaModifier ) ) + ( Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier ) ) + return false; // A non-typing modifier is pressed + + if ( keyEvent->key() == Qt::Key_Space || + keyEvent->key() == Qt::Key_Backspace || + keyEvent->key() == Qt::Key_Tab ) + return false; // Those key have other uses than to start typing + // or don't make sense + + QString text = keyEvent->text(); + + if ( text.size() ) + { + typingEvent( text ); + return true; + } + } + } + else + if (obj == ui.dictsList) { + if ( ev->type() == /*QEvent::KeyPress*/ 6 ) + { + QKeyEvent * keyEvent = static_cast< QKeyEvent * >( ev ); + + // Handle typing events used to initiate new lookups + + if ( keyEvent->modifiers() & + ( Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier ) ) return false; // A non-typing modifier is pressed if ( keyEvent->key() == Qt::Key_Space || @@ -1380,6 +1475,20 @@ void MainWindow::wordListSelectionChanged() wordListItemActivated( selected.front() ); } +void MainWindow::dictsListItemActivated( QListWidgetItem * item ) +{ + ArticleView & view = dynamic_cast< ArticleView & >( *( ui.tabWidget->currentWidget() ) ); + view.jumpToDictionary( item->text() ); +} + +void MainWindow::dictsListSelectionChanged() +{ + QList< QListWidgetItem * > selected = ui.dictsList->selectedItems(); + + if ( selected.size() ) + dictsListItemActivated( selected.front() ); +} + void MainWindow::openLinkInNewTab( QUrl const & url, QUrl const & referrer, QString const & fromArticle, @@ -1404,7 +1513,7 @@ void MainWindow::typingEvent( QString const & t ) focusTranslateLine(); else { - if ( ui.searchPane->isFloating() ) + if ( ui.searchPane->isFloating() || ui.dictsPane->isFloating() ) ui.searchPane->activateWindow(); ui.translateLine->setText( t ); @@ -1434,6 +1543,7 @@ void MainWindow::showTranslationFor( QString const & inWord, view.showDefinition( inWord, group ); updatePronounceAvailability(); + updateFoundInDictsList(); // Add to history diff --git a/mainwindow.hh b/mainwindow.hh index 1f49fb53..bfcee33f 100644 --- a/mainwindow.hh +++ b/mainwindow.hh @@ -58,6 +58,10 @@ private: QLabel groupLabel; GroupComboBox groupList; + QWidget dictsPaneTitleBar; + QHBoxLayout dictsPaneTitleBarLayout; + QLabel foundInDictsLabel; + /// Fonts saved before words zooming is in effect, so it could be reset back. QFont wordListDefaultFont, translateLineDefaultFont; @@ -120,6 +124,8 @@ private: void updatePronounceAvailability(); + void updateFoundInDictsList(); + /// Updates word search request and active article view in response to /// muting or unmuting dictionaries, or showing/hiding dictionary bar. void applyMutedDictionariesState(); @@ -232,6 +238,11 @@ private slots: void wordListItemActivated( QListWidgetItem * ); void wordListSelectionChanged(); + void dictsListItemActivated( QListWidgetItem * ); + void dictsListSelectionChanged(); + + void dictsPaneVisibilityChanged ( bool ); + /// Creates a new tab, which is to be populated then with some content. ArticleView * createNewTab( bool switchToIt, QString const & name ); diff --git a/mainwindow.ui b/mainwindow.ui index 90205231..f55e9e8a 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -244,6 +244,33 @@ + + + Dictionaries Pane + + + 2 + + + + + 2 + + + 1 + + + 2 + + + 1 + + + + + + + @@ -381,6 +408,12 @@
searchpanewidget.hh
1 + + DictsPaneWidget + QWidget +
dictspanewidget.hh
+ 1 +
translateLine diff --git a/qt-style-st-lingvo.css b/qt-style-st-lingvo.css index bb6be444..4e738c45 100644 --- a/qt-style-st-lingvo.css +++ b/qt-style-st-lingvo.css @@ -1,4 +1,4 @@ -MainWindow #searchPane #translateLine, MainWindow #searchPane #wordList +MainWindow #searchPane #translateLine, MainWindow #searchPane #wordList, MainWindow #dictsPane #dictsList { background: white; } diff --git a/qt-style.css b/qt-style.css index ce7d1111..bcd7468a 100644 --- a/qt-style.css +++ b/qt-style.css @@ -1,4 +1,4 @@ -MainWindow #searchPane #translateLine, MainWindow #searchPane #wordList +MainWindow #searchPane #translateLine, MainWindow #searchPane #wordList, MainWindow #dictsPane #dictsList { background: #fefdeb; color: black;