From 671427803a1b676141d60692780cadc6f95c6be6 Mon Sep 17 00:00:00 2001 From: xiaoyifang <105986+xiaoyifang@users.noreply.github.com> Date: Mon, 5 Jun 2023 21:22:20 +0800 Subject: [PATCH] fix: replace suggestion list with QCompleter (#808) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: replace suggestionList with QCompleter * 🎨 apply clang-format changes * fix: code smells --------- Co-authored-by: xiaoyifang --- goldendict.pro | 2 - src/dict/dictionary.hh | 15 ++- src/dict/mediawiki.cc | 7 +- src/ui/mainwindow.cc | 157 +++++++++++++++-------- src/ui/mainwindow.hh | 10 +- src/ui/mainwindow.ui | 7 +- src/ui/scanpopup.cc | 62 ++++----- src/ui/scanpopup.hh | 1 - src/ui/translatebox.cc | 285 +++++++---------------------------------- src/ui/translatebox.hh | 47 ++----- src/wordfinder.cc | 195 ++++++++++++---------------- src/wordfinder.hh | 5 +- src/wordlist.cc | 109 ---------------- src/wordlist.hh | 45 ------- 14 files changed, 286 insertions(+), 661 deletions(-) delete mode 100644 src/wordlist.cc delete mode 100644 src/wordlist.hh diff --git a/goldendict.pro b/goldendict.pro index 4e2580be..814c21aa 100644 --- a/goldendict.pro +++ b/goldendict.pro @@ -409,7 +409,6 @@ HEADERS += \ src/webmultimediadownload.hh \ src/weburlrequestinterceptor.hh \ src/wordfinder.hh \ - src/wordlist.hh \ src/zipfile.hh \ thirdparty/tomlplusplus/toml++/toml.h @@ -530,7 +529,6 @@ SOURCES += \ src/webmultimediadownload.cc \ src/weburlrequestinterceptor.cc \ src/wordfinder.cc \ - src/wordlist.cc \ src/zipfile.cc \ thirdparty/fmt/format.cc diff --git a/src/dict/dictionary.hh b/src/dict/dictionary.hh index c016193f..e1220e02 100644 --- a/src/dict/dictionary.hh +++ b/src/dict/dictionary.hh @@ -220,16 +220,21 @@ class WordSearchRequestInstant: public WordSearchRequest public: WordSearchRequestInstant() - { finish(); } + { + finish(); + } - virtual void cancel() - {} + void cancel() override {} vector< WordMatch > & getMatches() - { return matches; } + { + return matches; + } void setUncertain( bool value ) - { uncertain = value; } + { + uncertain = value; + } }; /// A helper class for synchronous data read implementations. diff --git a/src/dict/mediawiki.cc b/src/dict/mediawiki.cc index 6b372a37..c99aa574 100644 --- a/src/dict/mediawiki.cc +++ b/src/dict/mediawiki.cc @@ -123,7 +123,7 @@ MediaWikiWordSearchRequest::MediaWikiWordSearchRequest( wstring const & str, QNetworkAccessManager & mgr ) : isCancelling( false ) { - GD_DPRINTF( "request begin\n" ); + GD_DPRINTF( "wiki request begin\n" ); QUrl reqUrl( url + "/api.php?action=query&list=allpages&aplimit=40&format=xml" ); GlobalBroadcaster::instance()->addWhitelist( reqUrl.host() ); @@ -188,8 +188,9 @@ void MediaWikiWordSearchRequest::downloadFinished() QMutexLocker _( &dataMutex ); - for( int x = 0; x < nl.length(); ++x ) - matches.push_back( gd::toWString( nl.item( x ).toElement().attribute( "title" ) ) ); + qDebug() << "matches" << matches.size(); + for ( int x = 0; x < nl.length(); ++x ) + matches.emplace_back( gd::toWString( nl.item( x ).toElement().attribute( "title" ) ) ); } } GD_DPRINTF( "done.\n" ); diff --git a/src/ui/mainwindow.cc b/src/ui/mainwindow.cc index 65d20c61..5501a2db 100644 --- a/src/ui/mainwindow.cc +++ b/src/ui/mainwindow.cc @@ -35,6 +35,8 @@ #include #include #include +#include "weburlrequestinterceptor.hh" +#include "folding.hh" #include #include @@ -46,6 +48,7 @@ #include "help.hh" #include "ui_authentication.h" #include "resourceschemehandler.hh" +#include #include "globalregex.hh" @@ -55,8 +58,6 @@ #ifdef Q_OS_WIN32 #include - #include "wstring.hh" - #include "wstring_qt.hh" #endif #include @@ -315,22 +316,19 @@ MainWindow::MainWindow( Config::Class & cfg_ ): { groupList = groupListInDock; translateLine = ui.translateLine; - wordList = ui.wordList; } else { groupList = groupListInToolbar; translateLine = translateBox->translateLine(); - wordList = translateBox->wordList(); } - wordList->attachFinder( &wordFinder ); + connect( &wordFinder, &WordFinder::updated, this, &MainWindow::prefixMatchUpdated ); + connect( &wordFinder, &WordFinder::finished, this, &MainWindow::prefixMatchFinished ); - // for the old UI: - ui.wordList->setTranslateLine( ui.translateLine ); groupList->setFocusPolicy( Qt::ClickFocus ); - wordList->setFocusPolicy( Qt::ClickFocus ); + ui.wordList->setFocusPolicy( Qt::ClickFocus ); - wordListDefaultFont = wordList->font(); + wordListDefaultFont = ui.wordList->font(); translateLineDefaultFont = translateLine->font(); groupListDefaultFont = groupList->font(); @@ -627,7 +625,7 @@ MainWindow::MainWindow( Config::Class & cfg_ ): connect( ui.translateLine, &QLineEdit::textChanged, this, &MainWindow::translateInputChanged ); - connect( translateBox->translateLine(), &QLineEdit::textChanged, this, &MainWindow::translateInputChanged ); + connect( translateBox->translateLine(), &QLineEdit::textEdited, this, &MainWindow::translateInputChanged ); connect( ui.translateLine, &QLineEdit::returnPressed, [ this ]() { translateInputFinished( true ); @@ -638,17 +636,8 @@ MainWindow::MainWindow( Config::Class & cfg_ ): connect( ui.wordList, &QListWidget::itemSelectionChanged, this, &MainWindow::wordListSelectionChanged ); - connect( translateBox->wordList(), - SIGNAL( itemDoubleClicked( QListWidgetItem * ) ), - this, - SLOT( wordListItemActivated( QListWidgetItem * ) ) ); - connect( ui.wordList, &QListWidget::itemClicked, this, &MainWindow::wordListItemActivated ); - connect( ui.wordList, &WordList::statusBarMessage, this, &MainWindow::showStatusBarMessage ); - - connect( translateBox->wordList(), &WordList::statusBarMessage, this, &MainWindow::showStatusBarMessage ); - connect( ui.dictsList, &QListWidget::itemSelectionChanged, this, &MainWindow::dictsListSelectionChanged ); connect( ui.dictsList, &QListWidget::itemDoubleClicked, this, &MainWindow::dictsListItemActivated ); @@ -661,10 +650,8 @@ MainWindow::MainWindow( Config::Class & cfg_ ): translateBox->translateLine()->installEventFilter( this ); ui.wordList->installEventFilter( this ); - translateBox->wordList()->installEventFilter( this ); ui.wordList->viewport()->installEventFilter( this ); - translateBox->wordList()->viewport()->installEventFilter( this ); ui.dictsList->installEventFilter( this ); ui.dictsList->viewport()->installEventFilter( this ); @@ -889,6 +876,83 @@ MainWindow::MainWindow( Config::Class & cfg_ ): useSmallIconsInToolbarsTriggered(); } +void MainWindow::prefixMatchUpdated() +{ + updateMatchResults( false ); +} + +void MainWindow::prefixMatchFinished() +{ + updateMatchResults( true ); +} + +void MainWindow::updateMatchResults( bool finished ) +{ + WordFinder::SearchResults const & results = wordFinder.getResults(); + + if ( cfg.preferences.searchInDock ) { + ui.wordList->setUpdatesEnabled( false ); + //clear all existed items + ui.wordList->clear(); + + for ( const auto & result : results ) { + auto i = new QListWidgetItem( result.first, ui.wordList ); + i->setToolTip( result.first ); + + if ( result.second ) { + QFont f = i->font(); + f.setItalic( true ); + i->setFont( f ); + } + + i->setTextAlignment( Qt::AlignLeft ); + } + + if ( ui.wordList->count() ) { + ui.wordList->scrollToItem( ui.wordList->item( 0 ), QAbstractItemView::PositionAtTop ); + ui.wordList->setCurrentItem( nullptr, QItemSelectionModel::Clear ); + } + + ui.wordList->setUpdatesEnabled( true ); + ui.wordList->unsetCursor(); + } + else { + + QStringList _results; + _results.clear(); + + for ( const auto & result : results ) { + _results << result.first; + } + translateBox->setModel( _results ); + } + + if ( finished ) { + + refreshTranslateLine(); + + if ( !wordFinder.getErrorString().isEmpty() ) + emit showStatusBarMessage( tr( "WARNING: %1" ).arg( wordFinder.getErrorString() ), + 20000, + QPixmap( ":/icons/error.svg" ) ); + } +} + +void MainWindow::refreshTranslateLine() +{ + if ( !translateLine ) + return; + + // Visually mark the input line to mark if there's no results + bool setMark = wordFinder.getResults().empty() && !wordFinder.wasSearchUncertain(); + + if ( translateLine->property( "noResults" ).toBool() != setMark ) { + translateLine->setProperty( "noResults", setMark ); + + Utils::Widget::setNoResultColor( translateLine, setMark ); + } +} + void MainWindow::clipboardChange( QClipboard::Mode m ) { if ( !scanPopup ) { @@ -963,9 +1027,10 @@ void MainWindow::updateSearchPaneAndBar( bool searchInDock ) groupList = groupListInDock; translateLine = ui.translateLine; - wordList = ui.wordList; translateBoxToolBarAction->setVisible( false ); + + translateBox->setPopupEnabled( false ); } else { @@ -988,7 +1053,6 @@ void MainWindow::updateSearchPaneAndBar( bool searchInDock ) groupList = groupListInToolbar; translateLine = translateBox->translateLine(); - wordList = translateBox->wordList(); translateBoxToolBarAction->setVisible( true ); } @@ -1003,8 +1067,6 @@ void MainWindow::updateSearchPaneAndBar( bool searchInDock ) // reset the flag when switching UI modes wordListSelChanged = false; - wordList->attachFinder( &wordFinder ); - updateGroupList(); applyWordsZoomLevel(); @@ -1014,7 +1076,6 @@ void MainWindow::updateSearchPaneAndBar( bool searchInDock ) void MainWindow::mousePressEvent( QMouseEvent * event ) { - if ( handleBackForwardMouseButtons( event ) ) { return; } @@ -2197,7 +2258,7 @@ void MainWindow::updateCurrentGroupProperty() if ( grp && translateLine->property( "currentGroup" ).toString() != grp->name ) { translateLine->setProperty( "currentGroup", grp->name ); - wordList->setProperty( "currentGroup", grp->name ); + ui.wordList->setProperty( "currentGroup", grp->name ); QString ss = styleSheet(); // Only update stylesheet if it mentions currentGroup, as updating the @@ -2231,8 +2292,8 @@ void MainWindow::updateSuggestionList( QString const & newValue ) // If some word is selected in the word list, unselect it. This prevents // triggering a set of spurious activation signals when the list changes. - if ( wordList->selectionModel()->hasSelection() ) - wordList->setCurrentItem( 0, QItemSelectionModel::Clear ); + if ( ui.wordList->selectionModel()->hasSelection() ) + ui.wordList->setCurrentItem( 0, QItemSelectionModel::Clear ); QString req = newValue.trimmed(); @@ -2240,8 +2301,8 @@ void MainWindow::updateSuggestionList( QString const & newValue ) { // An empty request always results in an empty result wordFinder.cancel(); - wordList->clear(); - wordList->unsetCursor(); + ui.wordList->clear(); + ui.wordList->unsetCursor(); // Reset the noResults mark if it's on right now if ( translateLine->property( "noResults" ).toBool() ) @@ -2253,8 +2314,7 @@ void MainWindow::updateSuggestionList( QString const & newValue ) return; } - wordList->setCursor( Qt::WaitCursor ); - + ui.wordList->setCursor( Qt::WaitCursor ); wordFinder.prefixMatch( req, getActiveDicts() ); } @@ -2393,19 +2453,14 @@ bool MainWindow::eventFilter( QObject * obj, QEvent * ev ) if ( ev->type() == QEvent::MouseButtonPress ) { QMouseEvent * event = static_cast< QMouseEvent * >( ev ); - // clicks outside of the word list should hide it. - if ( obj != translateBox->wordList() && obj != translateBox->wordList()->viewport() ) { - translateBox->setPopupEnabled( false ); - } - return handleBackForwardMouseButtons( event ); } if ( ev->type() == QEvent::KeyPress ) { - QKeyEvent * keyevent = static_cast< QKeyEvent * >( ev ); + auto keyevent = dynamic_cast< QKeyEvent * >( ev ); - bool handleCtrlTab = ( obj == translateLine || obj == wordList || obj == ui.historyList || obj == ui.favoritesTree - || obj == ui.dictsList || obj == groupList ); + bool handleCtrlTab = ( obj == translateLine || obj == ui.wordList || obj == ui.historyList + || obj == ui.favoritesTree || obj == ui.dictsList || obj == groupList ); if ( keyevent->modifiers() == Qt::ControlModifier && keyevent->key() == Qt::Key_Tab ) { if ( cfg.preferences.mruTabOrder ) { @@ -2436,10 +2491,10 @@ bool MainWindow::eventFilter( QObject * obj, QEvent * ev ) if ( cfg.preferences.searchInDock ) { - if ( keyEvent->matches( QKeySequence::MoveToNextLine ) && wordList->count() ) + if ( keyEvent->matches( QKeySequence::MoveToNextLine ) && ui.wordList->count() ) { - wordList->setFocus( Qt::ShortcutFocusReason ); - wordList->setCurrentRow( 0, QItemSelectionModel::ClearAndSelect ); + ui.wordList->setFocus( Qt::ShortcutFocusReason ); + ui.wordList->setCurrentRow( 0, QItemSelectionModel::ClearAndSelect ); return true; } } @@ -2451,18 +2506,18 @@ bool MainWindow::eventFilter( QObject * obj, QEvent * ev ) return false; } } - else if ( obj == wordList ) { + else if ( obj == ui.wordList ) { if ( ev->type() == QEvent::KeyPress ) { QKeyEvent * keyEvent = static_cast< QKeyEvent * >( ev ); - if ( keyEvent->matches( QKeySequence::MoveToPreviousLine ) && !wordList->currentRow() ) { - wordList->setCurrentRow( 0, QItemSelectionModel::Clear ); + if ( keyEvent->matches( QKeySequence::MoveToPreviousLine ) && !ui.wordList->currentRow() ) { + ui.wordList->setCurrentRow( 0, QItemSelectionModel::Clear ); translateLine->setFocus( Qt::ShortcutFocusReason ); return true; } if ( keyEvent->matches( QKeySequence::InsertParagraphSeparator ) && - wordList->selectedItems().size() ) + ui.wordList->selectedItems().size() ) { if ( cfg.preferences.searchInDock ) { @@ -2508,7 +2563,7 @@ void MainWindow::wordListItemActivated( QListWidgetItem * item ) void MainWindow::wordListSelectionChanged() { - QList< QListWidgetItem * > selected = wordList->selectedItems(); + QList< QListWidgetItem * > selected = ui.wordList->selectedItems(); if ( selected.size() ) { @@ -3438,8 +3493,8 @@ void MainWindow::applyWordsZoomLevel() font.setPointSize( ps ); } - if ( wordList->font().pointSize() != ps ) - wordList->setFont( font ); + if ( ui.wordList->font().pointSize() != ps ) + ui.wordList->setFont( font ); font = translateLineDefaultFont; diff --git a/src/ui/mainwindow.hh b/src/ui/mainwindow.hh index 341d86ff..efa2f741 100644 --- a/src/ui/mainwindow.hh +++ b/src/ui/mainwindow.hh @@ -11,7 +11,6 @@ #include #include #include "ui_mainwindow.h" -#include "folding.hh" #include "config.hh" #include "dict/dictionary.hh" #include "article_netmgr.hh" @@ -26,13 +25,11 @@ #include "mainstatusbar.hh" #include "mruqmenu.hh" #include "translatebox.hh" -#include "wordlist.hh" #include "dictheadwords.hh" #include "fulltextsearch.hh" #include "base_type.hh" #include "hotkeywrapper.hh" -#include "weburlrequestinterceptor.hh" #include "resourceschemehandler.hh" #include "iframeschemehandler.hh" #ifdef HAVE_X11 @@ -141,7 +138,7 @@ private: // in a separate thread AudioPlayerFactory audioPlayerFactory; - WordList * wordList; + //current active translateLine; QLineEdit * translateLine; WordFinder wordFinder; @@ -462,7 +459,10 @@ private slots: void clipboardChange( QClipboard::Mode m ); void inspectElement( QWebEnginePage * ); - + void prefixMatchUpdated(); + void prefixMatchFinished(); + void updateMatchResults( bool finished ); + void refreshTranslateLine(); signals: /// Retranslate Ctrl(Shift) + Click on dictionary pane to dictionary toolbar void clickOnDictPane( QString const & id ); diff --git a/src/ui/mainwindow.ui b/src/ui/mainwindow.ui index 30c4d3a2..056fbc21 100644 --- a/src/ui/mainwindow.ui +++ b/src/ui/mainwindow.ui @@ -192,7 +192,7 @@ - + @@ -607,11 +607,6 @@
historypanewidget.hh
1 - - WordList - QListWidget -
wordlist.hh
-
FavoritesPaneWidget QWidget diff --git a/src/ui/scanpopup.cc b/src/ui/scanpopup.cc index 062fb228..7dc84264 100644 --- a/src/ui/scanpopup.cc +++ b/src/ui/scanpopup.cc @@ -111,14 +111,12 @@ ScanPopup::ScanPopup( QWidget * parent, connect( definition, &ArticleView::sendWordToHistory, this, &ScanPopup::sendWordToHistory ); connect( definition, &ArticleView::typingEvent, this, &ScanPopup::typingEvent ); - wordListDefaultFont = ui.translateBox->wordList()->font(); + wordListDefaultFont = ui.translateBox->completerWidget()->font(); translateLineDefaultFont = ui.translateBox->font(); groupListDefaultFont = ui.groupList->font(); ui.mainLayout->addWidget( definition ); - ui.translateBox->wordList()->attachFinder( &wordFinder ); - ui.translateBox->wordList()->setFocusPolicy(Qt::ClickFocus); ui.translateBox->translateLine()->installEventFilter( this ); definition->installEventFilter(this); this->installEventFilter(this); @@ -127,15 +125,6 @@ ScanPopup::ScanPopup( QWidget * parent, connect( ui.translateBox->translateLine(), &QLineEdit::returnPressed, this, &ScanPopup::translateInputFinished ); - connect( ui.translateBox->wordList(), &QListWidget::itemClicked, this, &ScanPopup::wordListItemActivated ); - - connect( ui.translateBox->wordList(), - SIGNAL( itemDoubleClicked( QListWidgetItem * ) ), - this, - SLOT( wordListItemActivated( QListWidgetItem * ) ) ); - - connect( ui.translateBox->wordList(), &WordList::statusBarMessage, this, &ScanPopup::showStatusBarMessage ); - ui.pronounceButton->setDisabled( true ); ui.groupList->fill( groups ); @@ -155,7 +144,7 @@ ScanPopup::ScanPopup( QWidget * parent, Config::Group * grp = cfg.getGroup( cfg.lastPopupGroupId ); if( igrp && grp ) igrp->checkMutedDictionaries( &grp->popupMutedDictionaries ); - dictionaryBar.setMutedDictionaries( grp ? &grp->popupMutedDictionaries : 0 ); + dictionaryBar.setMutedDictionaries( grp ? &grp->popupMutedDictionaries : nullptr ); } addToolBar( Qt::RightToolBarArea, &dictionaryBar ); @@ -280,10 +269,9 @@ ScanPopup::ScanPopup( QWidget * parent, #ifdef HAVE_X11 scanFlag = new ScanFlag( this ); - connect( scanFlag, &ScanFlag::requestScanPopup, - this, [=]{ + connect( scanFlag, &ScanFlag::requestScanPopup, this, [ this ] { translateWordFromSelection(); - }); + } ); // Use delay show to prevent multiple popups while selection in progress selectionDelayTimer.setSingleShot( true ); @@ -362,11 +350,11 @@ void ScanPopup::applyWordsZoomLevel() font.setPointSize( ps ); } - if ( ui.translateBox->wordList()->font().pointSize() != ps ) - ui.translateBox->wordList()->setFont( font ); + if ( ui.translateBox->completerWidget()->font().pointSize() != ps ) + ui.translateBox->completerWidget()->setFont( font ); font = translateLineDefaultFont; - ps = font.pointSize(); + ps = font.pointSize(); if ( cfg.preferences.wordsZoomLevel != 0 ) { @@ -413,12 +401,12 @@ Qt::WindowFlags ScanPopup::unpinnedWindowFlags() const void ScanPopup::translateWordFromClipboard() { - return translateWordFromClipboard(QClipboard::Clipboard); + return translateWordFromClipboard( QClipboard::Clipboard ); } void ScanPopup::translateWordFromSelection() { - return translateWordFromClipboard(QClipboard::Selection); + return translateWordFromClipboard( QClipboard::Selection ); } void ScanPopup::editGroupRequested() @@ -627,7 +615,7 @@ void ScanPopup::currentGroupChanged( int ) dictionaryBar.setMutedDictionaries( &grp->popupMutedDictionaries ); } else - dictionaryBar.setMutedDictionaries( 0 ); + dictionaryBar.setMutedDictionaries( nullptr ); } updateDictionaryBar(); @@ -641,11 +629,6 @@ void ScanPopup::currentGroupChanged( int ) cfg.lastPopupGroupId = ui.groupList->getCurrentGroup(); } -void ScanPopup::wordListItemActivated( QListWidgetItem * item ) -{ - showTranslationFor( item->text() ); -} - void ScanPopup::translateInputChanged( QString const & text ) { updateSuggestionList( text ); @@ -659,7 +642,6 @@ void ScanPopup::updateSuggestionList() void ScanPopup::updateSuggestionList( QString const & text ) { mainStatusBar->clearMessage(); - ui.translateBox->wordList()->setCurrentItem( 0, QItemSelectionModel::Clear ); QString req = text.trimmed(); @@ -667,8 +649,6 @@ void ScanPopup::updateSuggestionList( QString const & text ) { // An empty request always results in an empty result wordFinder.cancel(); - ui.translateBox->wordList()->clear(); - ui.translateBox->wordList()->unsetCursor(); // Reset the noResults mark if it's on right now if ( ui.translateBox->translateLine()->property( "noResults" ).toBool() ) @@ -681,8 +661,6 @@ void ScanPopup::updateSuggestionList( QString const & text ) return; } - ui.translateBox->wordList()->setCursor( Qt::WaitCursor ); - wordFinder.prefixMatch( req, getActiveDicts() ); } @@ -959,9 +937,20 @@ void ScanPopup::prefixMatchFinished() { ui.queryError->setToolTip( wordFinder.getErrorString() ); ui.queryError->show(); + showStatusBarMessage( tr( "WARNING: %1" ).arg( wordFinder.getErrorString() ), + 20000, + QPixmap( ":/icons/error.svg" ) ); } - else + else { ui.queryError->hide(); + auto results = wordFinder.getResults(); + QStringList _results; + for ( auto const & [ fst, snd ] : results ) { + _results << fst; + } + + ui.translateBox->setModel( _results ); + } } } @@ -1121,10 +1110,9 @@ void ScanPopup::updateDictionaryBar() if( currentId == Instances::Group::AllGroupId ) dictionaryBar.setMutedDictionaries( &cfg.popupMutedDictionaries ); - else - { - Config::Group * grp = cfg.getGroup( currentId ); - dictionaryBar.setMutedDictionaries( grp ? &grp->popupMutedDictionaries : 0 ); + else { + Config::Group * group = cfg.getGroup( currentId ); + dictionaryBar.setMutedDictionaries( group ? &group->popupMutedDictionaries : nullptr ); } setDictionaryIconSize(); diff --git a/src/ui/scanpopup.hh b/src/ui/scanpopup.hh index c4e56890..0bfa2515 100644 --- a/src/ui/scanpopup.hh +++ b/src/ui/scanpopup.hh @@ -222,7 +222,6 @@ private slots: void translateInputChanged(QString const & text); void translateInputFinished(); - void wordListItemActivated( QListWidgetItem * ); void focusTranslateLine(); diff --git a/src/ui/translatebox.cc b/src/ui/translatebox.cc index 903b0a07..18a66843 100644 --- a/src/ui/translatebox.cc +++ b/src/ui/translatebox.cc @@ -11,209 +11,50 @@ #include #include #include - -namespace -{ -#define MAX_POPUP_ROWS 17 -} - -CompletionList::CompletionList(TranslateBox * parent) : WordList(parent), - translateBox(parent) -{ -#ifdef Q_OS_WIN - setWindowFlags(Qt::ToolTip); -#else - setParent( parent->window() ); - setAutoFillBackground( true ); -#endif - - connect( this, &QAbstractItemView::activated, this, &CompletionList::acceptCurrentEntry ); - - connect( this, &QListWidget::itemClicked, this, &CompletionList::acceptCurrentEntry ); - - translateBox->window()->installEventFilter(this); -} - -bool CompletionList::eventFilter( QObject * obj, QEvent * ev ) -{ - // when the main window is moved or resized, hide the word list suggestions - if ( obj != this && !isAncestorOf( qobject_cast< QWidget * >( obj ) ) - && ( ev->type() == QEvent::Move || ev->type() == QEvent::Resize ) ) - { - translateBox->setPopupEnabled( false ); - return false; - } - - return QWidget::eventFilter( obj, ev ); -} - -int CompletionList::preferredHeight() const -{ -#if( QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) ) - const QSize itemSizeHint = itemDelegate()->sizeHint( viewOptions(), model()->index( 0, 0 ) ); -#else - QStyleOptionViewItem option; - initViewItemOption( &option ); - const QSize itemSizeHint = itemDelegate()->sizeHint(option, model()->index( 0, 0 ) ); -#endif - int rows = qMin( count(), MAX_POPUP_ROWS ); - - int scrollBarHeight = 0; - - bool hBarIsVisible = horizontalScrollBar()->maximum() > 0; - - if ( hBarIsVisible ) - scrollBarHeight += QApplication::style()->pixelMetric( QStyle::PM_ScrollBarExtent ); - - return rows == 0 ? 0 : itemSizeHint.height() * rows + frameWidth() * 2 + scrollBarHeight; -} - -bool CompletionList::acceptCurrentEntry() -{ - if (!isVisible()) - { - return false; - } - - const QModelIndex index = currentIndex(); - if ( !index.isValid() ) - { - return false; - } - - emit doubleClicked(index); - translateBox->setPopupEnabled( false ); - - return true; -} +#include TranslateBox::TranslateBox( QWidget * parent ): - QWidget( parent ), - word_list( new CompletionList( this ) ), - translate_line( new QLineEdit( this ) ), - m_popupEnabled( false ) + QWidget( parent ), + translate_line( new QLineEdit( this ) ), + m_popupEnabled( false ) { - // initially hidden - word_list->hide(); + completer = new QCompleter( words, this ); + resize( 200, 90 ); + QSizePolicy sizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred ); + sizePolicy.setHorizontalStretch( 0 ); + sizePolicy.setVerticalStretch( 0 ); + setSizePolicy( sizePolicy ); - resize(200, 90); - QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); - sizePolicy.setHorizontalStretch(0); - sizePolicy.setVerticalStretch(0); - setSizePolicy(sizePolicy); - // setMinimumSize(QSize(800, 0)); - - setFocusProxy(translate_line); - translate_line->setObjectName("translateLine"); + setFocusProxy( translate_line ); + translate_line->setObjectName( "translateLine" ); translate_line->setPlaceholderText( tr( "Type a word or phrase to search dictionaries" ) ); - word_list->setTranslateLine(translate_line); - // completer = new QCompleter(m_completionList->model(), this); - // completer->setCaseSensitivity(Qt::CaseInsensitive); - // completer->setCompletionMode(QCompleter::InlineCompletion); + auto layout = new QHBoxLayout( this ); + setLayout( layout ); + layout->setContentsMargins( 0, 0, 0, 0 ); + layout->addWidget( translate_line ); - QHBoxLayout *layout = new QHBoxLayout(this); - setLayout(layout); - layout->setContentsMargins(0,0,0,0); - layout->addWidget(translate_line); + auto dropdown = new QAction( QIcon( ":/icons/1downarrow.svg" ), tr( "Drop-down" ), this ); + connect( dropdown, &QAction::triggered, this, &TranslateBox::rightButtonClicked ); - QAction * dropdown = new QAction( QIcon(":/icons/1downarrow.svg"), tr("Drop-down"),this); - connect( dropdown,&QAction::triggered,this, &TranslateBox::rightButtonClicked ); + translate_line->addAction( dropdown, QLineEdit::TrailingPosition ); + translate_line->addAction( new QAction( QIcon( ":/icons/system-search.svg" ), "", this ), + QLineEdit::LeadingPosition ); - translate_line->addAction( dropdown,QLineEdit::TrailingPosition); - translate_line->addAction( new QAction(QIcon(":/icons/system-search.svg"),"",this),QLineEdit::LeadingPosition); - - translate_line->setFocusPolicy(Qt::ClickFocus); + translate_line->setFocusPolicy( Qt::ClickFocus ); translate_line->installEventFilter( this ); - this->installEventFilter( this ); - connect( translate_line, &QLineEdit::textChanged, this, &TranslateBox::onTextEdit ); + translate_line->setCompleter( completer ); + completer->setCompletionMode( QCompleter::UnfilteredPopupCompletion ); + completer->setMaxVisibleItems( 16 ); - - connect( word_list, &WordList::contentChanged, this, &TranslateBox::showPopup ); + connect( completer, QOverload< const QString & >::of( &QCompleter::activated ), this, [ = ]( const QString & text ) { + emit translate_line->returnPressed(); + } ); } -bool TranslateBox::eventFilter(QObject *obj, QEvent *event) -{ - // hide the suggestions list when the window is not active - if ( event->type() == QEvent::WindowDeactivate ) - { - if (!word_list->isActiveWindow()) - { - setPopupEnabled( false ); - } - return false; - } - - if (obj == translate_line && event->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = static_cast(event); - switch (keyEvent->key()) { - case Qt::Key_Up: - case Qt::Key_Down: - case Qt::Key_PageUp: - case Qt::Key_PageDown: - if ( !word_list->isVisible() ) - { - setPopupEnabled( true ); - } - else - { - QApplication::sendEvent(word_list, event); - } - return true; - case Qt::Key_Enter: - case Qt::Key_Return: - return word_list->acceptCurrentEntry(); - case Qt::Key_Escape: - setPopupEnabled( false ); - return true; - case Qt::Key_Tab: - if ( !word_list->isVisible() ) - { - setPopupEnabled( true ); - } - else - { - QKeyEvent event( QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier ); - QApplication::sendEvent( word_list, &event ); - } - return true; - case Qt::Key_Backtab: - if ( !word_list->isVisible() ) - { - setPopupEnabled( true ); - } - else - { - QKeyEvent event( QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier ); - QApplication::sendEvent( word_list, &event ); - } - return true; - default: - break; - } - } else if (obj == translate_line && event->type() == QEvent::FocusOut) { -#if defined(Q_OS_WIN) - QFocusEvent *fev = static_cast(event); - if (fev->reason() != Qt::ActiveWindowFocusReason || - (fev->reason() == Qt::ActiveWindowFocusReason && !word_list->isActiveWindow())) -#endif - setPopupEnabled( false ); - } else if (obj == translate_line && event->type() == QEvent::FocusIn) { - // By default, focusing the traslate line does not show - // the popup window. - } else if (obj == this && event->type() == QEvent::ShortcutOverride) { - QKeyEvent *ke = static_cast(event); - if (ke->key() == Qt::Key_Escape && !ke->modifiers() && word_list->isVisible() ) { - event->accept(); - return true; - } - } - return QWidget::eventFilter(obj, event); -} - -void TranslateBox::setText( QString text, bool showPopup ) +void TranslateBox::setText( const QString & text, bool showPopup ) { setPopupEnabled( showPopup ); translate_line->setText( text ); @@ -232,56 +73,22 @@ void TranslateBox::setSizePolicy( QSizePolicy policy ) translate_line->setSizePolicy( policy ); } +void TranslateBox::setModel( QStringList & _words ) +{ + auto model = (QStringListModel *)( completer->model() ); + + model->setStringList( _words ); +} + void TranslateBox::showPopup() { - // completer->setCompletionPrefix( m_fileLineEdit->text() ); - // qDebug() << "COMPLETION:" << completer->currentCompletion(); - - // Don't allow recursive call - if( translateBoxMutex.tryLock() ) - translateBoxMutex.unlock(); - else - return; - QMutexLocker _( &translateBoxMutex ); - - if (translate_line->text().trimmed().isEmpty() || word_list->count() == 0) - { - // nothing to show - if (word_list->isVisible()) - { - word_list->hide(); - translate_line->setFocus(); - } - return; + if ( m_popupEnabled ) { + completer->popup()->show(); + completer->complete(); } - - if ( !m_popupEnabled ) - { - word_list->hide(); - return; + else { + completer->popup()->hide(); } - - int preferredHeight = word_list->preferredHeight(); - - QPoint origin( translate_line->x(), translate_line->y() + translate_line->height() ); - - if ( word_list->isWindow() ) - { - origin = mapToGlobal( origin ); - } - else - { - origin = mapTo( window(), origin ); - preferredHeight = qMin( translate_line->window()->height() - origin.y(), preferredHeight ); - } - - const QSize size(width(), preferredHeight); - const QRect rect( origin, size ); - - word_list->setGeometry(rect); - word_list->show(); - word_list->raise(); - translate_line->setFocus(); } QLineEdit * TranslateBox::translateLine() @@ -289,18 +96,16 @@ QLineEdit * TranslateBox::translateLine() return translate_line; } -WordList * TranslateBox::wordList() +QWidget * TranslateBox::completerWidget() { - return word_list; + return completer->widget(); } void TranslateBox::rightButtonClicked() { setPopupEnabled( !m_popupEnabled ); } - -void TranslateBox::onTextEdit() +void TranslateBox::setSizePolicy( QSizePolicy::Policy hor, QSizePolicy::Policy ver ) { - if ( translate_line->hasFocus() ) - setPopupEnabled( true ); + setSizePolicy( QSizePolicy( hor, ver ) ); } diff --git a/src/ui/translatebox.hh b/src/ui/translatebox.hh index 41e72168..c0205589 100644 --- a/src/ui/translatebox.hh +++ b/src/ui/translatebox.hh @@ -4,51 +4,25 @@ #ifndef TRANSLATEBOX_HH #define TRANSLATEBOX_HH -#include "wordlist.hh" - - #include #include #include #include - -class TranslateBox; - -class CompletionList : public WordList -{ - Q_OBJECT - -public: - CompletionList(TranslateBox * parent); - int preferredHeight() const; - virtual void setTranslateLine(QLineEdit * line) - { - WordList::setTranslateLine( line ); - setFocusProxy( line ); - } - -public slots: - bool acceptCurrentEntry(); - -private: - virtual bool eventFilter( QObject *, QEvent * ); - TranslateBox * translateBox; -}; +#include class TranslateBox : public QWidget { Q_OBJECT public: - explicit TranslateBox(QWidget * parent = 0); + explicit TranslateBox( QWidget * parent = nullptr ); QLineEdit * translateLine(); - WordList * wordList(); - void setText(QString text, bool showPopup=true); - void setSizePolicy(QSizePolicy policy); - inline void setSizePolicy(QSizePolicy::Policy hor, QSizePolicy::Policy ver) - { setSizePolicy(QSizePolicy(hor, ver)); } + QWidget * completerWidget(); + void setText( const QString & text, bool showPopup = true ); + void setSizePolicy( QSizePolicy policy ); + void setSizePolicy( QSizePolicy::Policy hor, QSizePolicy::Policy ver ); -signals: + void setModel( QStringList & _words ); public slots: void setPopupEnabled(bool enable); @@ -56,15 +30,12 @@ public slots: private slots: void showPopup(); void rightButtonClicked(); - void onTextEdit(); private: - bool eventFilter(QObject *obj, QEvent *event); - CompletionList * word_list; QLineEdit * translate_line; bool m_popupEnabled; - QMutex translateBoxMutex; - // QCompleter * completer; // disabled for now + QCompleter * completer; + QStringList words; }; #endif // TRANSLATEBOX_HH diff --git a/src/wordfinder.cc b/src/wordfinder.cc index 2c840f48..ed98d15e 100644 --- a/src/wordfinder.cc +++ b/src/wordfinder.cc @@ -131,28 +131,23 @@ void WordFinder::startSearch() allWordWritings[ 0 ] = gd::toWString( inputWord ); - for( size_t x = 0; x < inputDicts->size(); ++x ) - { - vector< wstring > writings = (*inputDicts)[ x ]->getAlternateWritings( allWordWritings[ 0 ] ); + for ( const auto & inputDict : *inputDicts ) { + vector< wstring > writings = inputDict->getAlternateWritings( allWordWritings[ 0 ] ); allWordWritings.insert( allWordWritings.end(), writings.begin(), writings.end() ); } // Query each dictionary for all word writings - for( size_t x = 0; x < inputDicts->size(); ++x ) - { - if ( ( (*inputDicts)[ x ]->getFeatures() & requestedFeatures ) != requestedFeatures ) + for ( const auto & inputDict : *inputDicts ) { + if ( ( inputDict->getFeatures() & requestedFeatures ) != requestedFeatures ) continue; - for( size_t y = 0; y < allWordWritings.size(); ++y ) - { - try - { - sptr< Dictionary::WordSearchRequest > sr = - ( searchType == PrefixMatch || searchType == ExpressionMatch ) ? - (*inputDicts)[ x ]->prefixMatch( allWordWritings[ y ], requestedMaxResults ) : - (*inputDicts)[ x ]->stemmedMatch( allWordWritings[ y ], stemmedMinLength, stemmedMaxSuffixVariation, requestedMaxResults ); + for ( const auto & allWordWriting : allWordWritings ) { + try { + sptr< Dictionary::WordSearchRequest > sr = ( searchType == PrefixMatch || searchType == ExpressionMatch ) ? + inputDict->prefixMatch( allWordWriting, requestedMaxResults ) : + inputDict->stemmedMatch( allWordWriting, stemmedMinLength, stemmedMaxSuffixVariation, requestedMaxResults ); connect( sr.get(), &Dictionary::Request::finished, this, &WordFinder::requestFinished, Qt::QueuedConnection ); @@ -161,7 +156,9 @@ void WordFinder::startSearch() catch( std::exception & e ) { gdWarning( "Word \"%s\" search error (%s) in \"%s\"\n", - inputWord.toUtf8().data(), e.what(), (*inputDicts)[ x ]->getName().c_str() ); + inputWord.toUtf8().data(), + e.what(), + inputDict->getName().c_str() ); } } } @@ -191,15 +188,12 @@ void WordFinder::requestFinished() bool newResults = false; // See how many new requests have finished, and if we have any new results - for( list< sptr< Dictionary::WordSearchRequest > >::iterator i = - queuedRequests.begin(); i != queuedRequests.end(); ) - { - if ( (*i)->isFinished() ) - { - if ( searchInProgress && !(*i)->getErrorString().isEmpty() ) + for ( auto i = queuedRequests.begin(); i != queuedRequests.end(); ) { + if ( ( *i )->isFinished() ) { + if ( searchInProgress && !( *i )->getErrorString().isEmpty() ) searchErrorString = tr( "Failed to query some dictionaries." ); - if ( (*i)->isUncertain() ) + if ( ( *i )->isUncertain() ) searchResultsUncertain = true; if ( (*i)->matchesCount() ) @@ -233,8 +227,7 @@ void WordFinder::requestFinished() return; } - if ( newResults && queuedRequests.size() && !updateResultsTimer.isActive() ) - { + if ( newResults && !queuedRequests.empty() && !updateResultsTimer.isActive() ) { // If we have got some new results, but not all of them, we would start a // timer to update a user some time in the future updateResultsTimer.start(); @@ -297,17 +290,13 @@ void WordFinder::updateResults() wstring original = Folding::applySimpleCaseOnly( allWordWritings[ 0 ] ); - for( list< sptr< Dictionary::WordSearchRequest > >::iterator i = - finishedRequests.begin(); i != finishedRequests.end(); ) - { - for( size_t count = (*i)->matchesCount(), x = 0; x < count; ++x ) - { - wstring match = (**i)[ x ].word; - int weight = (**i)[ x ].weight; + for ( auto i = finishedRequests.begin(); i != finishedRequests.end(); ) { + for ( size_t count = ( *i )->matchesCount(), x = 0; x < count; ++x ) { + wstring match = ( **i )[ x ].word; + int weight = ( **i )[ x ].weight; wstring lowerCased = Folding::applySimpleCaseOnly( match ); - if( searchType == ExpressionMatch ) - { + if ( searchType == ExpressionMatch ) { unsigned ws; for( ws = 0; ws < allWordWritings.size(); ws++ ) @@ -330,9 +319,8 @@ void WordFinder::updateResults() } weight = ws; } - pair< ResultsIndex::iterator, bool > insertResult = - resultsIndex.insert( pair< wstring, ResultsArray::iterator >( lowerCased, - resultsArray.end() ) ); + auto insertResult = + resultsIndex.insert( pair< wstring, ResultsArray::iterator >( lowerCased, resultsArray.end() ) ); if ( !insertResult.second ) { @@ -347,7 +335,7 @@ void WordFinder::updateResults() } else { - resultsArray.push_back( OneResult() ); + resultsArray.emplace_back(); resultsArray.back().word = match; resultsArray.back().rank = INT_MAX; @@ -361,14 +349,11 @@ void WordFinder::updateResults() size_t maxSearchResults = 500; - if ( resultsArray.size() ) - { - if ( searchType == PrefixMatch ) - { + if ( !resultsArray.empty() ) { + if ( searchType == PrefixMatch ) { /// Assign each result a category, storing it in the rank's field - - enum Category - { + + enum Category { ExactMatch, ExactNoFullCaseMatch, ExactNoDiaMatch, @@ -385,66 +370,55 @@ void WordFinder::updateResults() Multiplier = 256 // Categories should be multiplied by Multiplier }; - for( unsigned wr = 0; wr < allWordWritings.size(); ++wr ) - { - wstring target = Folding::applySimpleCaseOnly( allWordWritings[ wr ] ); + for ( const auto & allWordWriting : allWordWritings ) { + wstring target = Folding::applySimpleCaseOnly( allWordWriting ); wstring targetNoFullCase = Folding::applyFullCaseOnly( target ); - wstring targetNoDia = Folding::applyDiacriticsOnly( targetNoFullCase ); - wstring targetNoPunct = Folding::applyPunctOnly( targetNoDia ); - wstring targetNoWs = Folding::applyWhitespaceOnly( targetNoPunct ); - + wstring targetNoDia = Folding::applyDiacriticsOnly( targetNoFullCase ); + wstring targetNoPunct = Folding::applyPunctOnly( targetNoDia ); + wstring targetNoWs = Folding::applyWhitespaceOnly( targetNoPunct ); + wstring::size_type matchPos = 0; - - for( ResultsIndex::const_iterator i = resultsIndex.begin(), j = resultsIndex.end(); - i != j; ++i ) - { + + for ( const auto & i : resultsIndex ) { wstring resultNoFullCase, resultNoDia, resultNoPunct, resultNoWs; int rank; - - if ( i->first == target ) + + if ( i.first == target ) rank = ExactMatch * Multiplier; - else - if ( ( resultNoFullCase = Folding::applyFullCaseOnly( i->first ) ) == targetNoFullCase ) + else if ( ( resultNoFullCase = Folding::applyFullCaseOnly( i.first ) ) == targetNoFullCase ) rank = ExactNoFullCaseMatch * Multiplier; - else - if ( ( resultNoDia = Folding::applyDiacriticsOnly( resultNoFullCase ) ) == targetNoDia ) + else if ( ( resultNoDia = Folding::applyDiacriticsOnly( resultNoFullCase ) ) == targetNoDia ) rank = ExactNoDiaMatch * Multiplier; - else - if ( ( resultNoPunct = Folding::applyPunctOnly( resultNoDia ) ) == targetNoPunct ) + else if ( ( resultNoPunct = Folding::applyPunctOnly( resultNoDia ) ) == targetNoPunct ) rank = ExactNoPunctMatch * Multiplier; - else - if ( ( resultNoWs = Folding::applyWhitespaceOnly( resultNoPunct ) ) == targetNoWs ) + else if ( ( resultNoWs = Folding::applyWhitespaceOnly( resultNoPunct ) ) == targetNoWs ) rank = ExactNoWsMatch * Multiplier; - else - if ( hasSurroundedWithWs( i->first, target, matchPos ) ) + else if ( hasSurroundedWithWs( i.first, target, matchPos ) ) rank = ExactInsideMatch * Multiplier + matchPos; - else - if ( hasSurroundedWithWs( resultNoDia, targetNoDia, matchPos ) ) + else if ( hasSurroundedWithWs( resultNoDia, targetNoDia, matchPos ) ) rank = ExactNoDiaInsideMatch * Multiplier + matchPos; - else - if ( hasSurroundedWithWs( resultNoPunct, targetNoPunct, matchPos ) ) + else if ( hasSurroundedWithWs( resultNoPunct, targetNoPunct, matchPos ) ) rank = ExactNoPunctInsideMatch * Multiplier + matchPos; - else - if ( i->first.size() > target.size() && i->first.compare( 0, target.size(), target ) == 0 ) - rank = PrefixMatch * Multiplier + saturated( i->first.size() ); - else - if ( resultNoDia.size() > targetNoDia.size() && resultNoDia.compare( 0, targetNoDia.size(), targetNoDia ) == 0 ) - rank = PrefixNoDiaMatch * Multiplier + saturated( i->first.size() ); - else - if ( resultNoPunct.size() > targetNoPunct.size() && resultNoPunct.compare( 0, targetNoPunct.size(), targetNoPunct ) == 0 ) - rank = PrefixNoPunctMatch * Multiplier + saturated( i->first.size() ); - else - if ( resultNoWs.size() > targetNoWs.size() && resultNoWs.compare( 0, targetNoWs.size(), targetNoWs ) == 0 ) - rank = PrefixNoWsMatch * Multiplier + saturated( i->first.size() ); + else if ( i.first.size() > target.size() && i.first.compare( 0, target.size(), target ) == 0 ) + rank = PrefixMatch * Multiplier + saturated( i.first.size() ); + else if ( resultNoDia.size() > targetNoDia.size() + && resultNoDia.compare( 0, targetNoDia.size(), targetNoDia ) == 0 ) + rank = PrefixNoDiaMatch * Multiplier + saturated( i.first.size() ); + else if ( resultNoPunct.size() > targetNoPunct.size() + && resultNoPunct.compare( 0, targetNoPunct.size(), targetNoPunct ) == 0 ) + rank = PrefixNoPunctMatch * Multiplier + saturated( i.first.size() ); + else if ( resultNoWs.size() > targetNoWs.size() + && resultNoWs.compare( 0, targetNoWs.size(), targetNoWs ) == 0 ) + rank = PrefixNoWsMatch * Multiplier + saturated( i.first.size() ); else rank = WorstMatch * Multiplier; - if ( i->second->rank > rank ) - i->second->rank = rank; // We store the best rank of any writing + if ( i.second->rank > rank ) + i.second->rank = rank; // We store the best rank of any writing } } - + resultsArray.sort( SortByRank() ); } else @@ -456,29 +430,26 @@ void WordFinder::updateResults() // in their beginnings, and second, the length of the strings. Here we assign // only the first one, storing it in rank. Then we sort the results using // SortByRankAndLength. - for( unsigned wr = 0; wr < allWordWritings.size(); ++wr ) - { - wstring target = Folding::apply( allWordWritings[ wr ] ); - - for( ResultsIndex::const_iterator i = resultsIndex.begin(), j = resultsIndex.end(); - i != j; ++i ) - { - wstring resultFolded = Folding::apply( i->first ); - + for ( const auto & allWordWriting : allWordWritings ) { + wstring target = Folding::apply( allWordWriting ); + + for ( const auto & i : resultsIndex ) { + wstring resultFolded = Folding::apply( i.first ); + int charsInCommon = 0; - - for( wchar const * t = target.c_str(), * r = resultFolded.c_str(); - *t && *t == *r; ++t, ++r, ++charsInCommon ) ; - + + for ( wchar const *t = target.c_str(), *r = resultFolded.c_str(); *t && *t == *r; ++t, ++r, ++charsInCommon ) + ; + int rank = -charsInCommon; // Negated so the lesser-than // comparison would yield right // results. - if ( i->second->rank > rank ) - i->second->rank = rank; // We store the best rank of any writing + if ( i.second->rank > rank ) + i.second->rank = rank; // We store the best rank of any writing } } - + resultsArray.sort( SortByRankAndLength() ); maxSearchResults = 15; @@ -488,24 +459,18 @@ void WordFinder::updateResults() searchResults.clear(); searchResults.reserve( resultsArray.size() < maxSearchResults ? resultsArray.size() : maxSearchResults ); - for( ResultsArray::const_iterator i = resultsArray.begin(), j = resultsArray.end(); - i != j; ++i ) - { - //GD_DPRINTF( "%d: %ls\n", i->second, i->first.c_str() ); - + for ( const auto & i : resultsArray ) { if ( searchResults.size() < maxSearchResults ) - searchResults.push_back( std::pair< QString, bool >( QString::fromStdU32String( i->word ), i->wasSuggested ) ); + searchResults.emplace_back( QString::fromStdU32String( i.word ), i.wasSuggested ); else break; } - if ( queuedRequests.size() ) - { + if ( !queuedRequests.empty() ) { // There are still some unhandled results. emit updated(); } - else - { + else { // That were all of them. searchInProgress = false; emit finished(); @@ -514,8 +479,6 @@ void WordFinder::updateResults() void WordFinder::cancelSearches() { - for( list< sptr< Dictionary::WordSearchRequest > >::iterator i = - queuedRequests.begin(); i != queuedRequests.end(); ++i ) - (*i)->cancel(); + for ( auto & queuedRequest : queuedRequests ) + queuedRequest->cancel(); } - diff --git a/src/wordfinder.hh b/src/wordfinder.hh index 8e6d49c6..1838a735 100644 --- a/src/wordfinder.hh +++ b/src/wordfinder.hh @@ -22,15 +22,14 @@ class WordFinder: public QObject public: - typedef std::vector< std::pair< QString, bool > > SearchResults; // bool is a "was suggested" flag + using SearchResults = std::vector< std::pair< QString, bool > >; // bool is a "was suggested" flag private: SearchResults searchResults; QString searchErrorString; bool searchResultsUncertain; - std::list< sptr< Dictionary::WordSearchRequest > > queuedRequests, - finishedRequests; + std::list< sptr< Dictionary::WordSearchRequest > > queuedRequests, finishedRequests; bool searchInProgress; QTimer updateResultsTimer; diff --git a/src/wordlist.cc b/src/wordlist.cc deleted file mode 100644 index dca31671..00000000 --- a/src/wordlist.cc +++ /dev/null @@ -1,109 +0,0 @@ -/* This file is (c) 2013 Tvangeste - * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ - - -#include "wordlist.hh" - -WordList::WordList( QWidget * parent ) : QListWidget( parent ) -, listItemDelegate( itemDelegate() ) -{ - wordFinder = 0; - translateLine = 0; - setItemDelegate( &listItemDelegate ); -} - -void WordList::attachFinder( WordFinder * finder ) -{ - // qDebug() << "Attaching the word finder..." << finder; - - if ( wordFinder == finder ) - return; - - if ( wordFinder ) - { - disconnect( wordFinder, &WordFinder::updated, this, &WordList::prefixMatchUpdated ); - disconnect( wordFinder, &WordFinder::finished, this, &WordList::prefixMatchFinished ); - } - - wordFinder = finder; - - connect( wordFinder, &WordFinder::updated, this, &WordList::prefixMatchUpdated ); - connect( wordFinder, &WordFinder::finished, this, &WordList::prefixMatchFinished ); -} - -void WordList::prefixMatchUpdated() -{ - updateMatchResults( false ); -} - -void WordList::prefixMatchFinished() -{ - updateMatchResults( true ); -} - -void WordList::updateMatchResults( bool finished ) -{ - WordFinder::SearchResults const & results = wordFinder->getResults(); - - setUpdatesEnabled( false ); - //clear all existed items - clear(); - - for( unsigned x = 0; x < results.size(); ++x ) - { - QListWidgetItem * i = new QListWidgetItem( results[ x ].first, this ); - i->setToolTip( results[ x ].first ); - - if( results[ x ].second ) - { - QFont f = i->font(); - f.setItalic( true ); - i->setFont( f ); - } - - i->setTextAlignment( Qt::AlignLeft ); - } - - if ( count() ) - { - scrollToItem( item( 0 ), QAbstractItemView::PositionAtTop ); - setCurrentItem( 0, QItemSelectionModel::Clear ); - } - - setUpdatesEnabled( true ); - - if ( finished ) - { - unsetCursor(); - - refreshTranslateLine(); - - if ( !wordFinder->getErrorString().isEmpty() ) - emit statusBarMessage(tr("WARNING: %1").arg(wordFinder->getErrorString()), - 20000, QPixmap(":/icons/error.svg")); - } - - if( !results.empty() && results.front().first.isRightToLeft() ) - setLayoutDirection( Qt::RightToLeft ); - else - setLayoutDirection( Qt::LeftToRight ); - - emit contentChanged(); -} - -void WordList::refreshTranslateLine() -{ - if ( !translateLine ) - return; - - // Visually mark the input line to mark if there's no results - bool setMark = wordFinder->getResults().empty() && !wordFinder->wasSearchUncertain(); - - if ( translateLine->property( "noResults" ).toBool() != setMark ) - { - translateLine->setProperty( "noResults", setMark ); - - Utils::Widget::setNoResultColor( translateLine, setMark ); - } - -} diff --git a/src/wordlist.hh b/src/wordlist.hh deleted file mode 100644 index 26a04bae..00000000 --- a/src/wordlist.hh +++ /dev/null @@ -1,45 +0,0 @@ -/* This file is (c) 2013 Tvangeste - * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ - -#ifndef WORDLIST_HH -#define WORDLIST_HH - -#include -#include - -#include "wordfinder.hh" -#include "delegate.hh" - -class WordList : public QListWidget -{ - Q_OBJECT -public: - explicit WordList(QWidget * parent = 0); - void attachFinder(WordFinder * finder); - virtual void setTranslateLine(QLineEdit * line) - { translateLine = line; } - -protected: - -signals: - void statusBarMessage(QString const & message, int timeout = 0, QPixmap const & pixmap = QPixmap()); - void contentChanged(); - -public slots: - -private slots: - void prefixMatchUpdated(); - void prefixMatchFinished(); - void updateMatchResults( bool finished ); - -private: - void refreshTranslateLine(); - - WordFinder * wordFinder; - QLineEdit * translateLine; - WordListItemDelegate listItemDelegate; - - QVector< QSize > resizedSizes; -}; - -#endif // WORDLIST_HH