diff --git a/src/ui/dictionarybar.cc b/src/ui/dictionarybar.cc index 9ab4c1a4..31057e2c 100644 --- a/src/ui/dictionarybar.cc +++ b/src/ui/dictionarybar.cc @@ -13,7 +13,7 @@ DictionaryBar::DictionaryBar( QWidget * parent, QString const & _editDictionaryCommand, unsigned short const & maxDictionaryRefsInContextMenu_ ): QToolBar( tr( "&Dictionary Bar" ), parent ), - mutedDictionaries( 0 ), + mutedDictionaries( nullptr ), configEvents( events ), editDictionaryCommand( _editDictionaryCommand ), maxDictionaryRefsInContextMenu( maxDictionaryRefsInContextMenu_ ) @@ -52,16 +52,16 @@ void DictionaryBar::setDictionaries( vector< sptr< Dictionary::Class > > const & clear(); dictActions.clear(); - for ( unsigned x = 0; x < dictionaries.size(); ++x ) { - QIcon icon = dictionaries[ x ]->getIcon(); + for ( const auto & dictionary : dictionaries ) { + QIcon icon = dictionary->getIcon(); - QString dictName = QString::fromUtf8( dictionaries[ x ]->getName().c_str() ); + QString dictName = QString::fromUtf8( dictionary->getName().c_str() ); QAction * action = addAction( icon, elideDictName( dictName ) ); action->setToolTip( dictName ); // Tooltip need not be shortened - QString id = QString::fromStdString( dictionaries[ x ]->getId() ); + QString id = QString::fromStdString( dictionary->getId() ); action->setData( id ); @@ -91,21 +91,21 @@ void DictionaryBar::showContextMenu( QContextMenuEvent * event, bool extended ) { QMenu menu( this ); - QAction * editAction = menu.addAction( QIcon( ":/icons/bookcase.svg" ), tr( "Edit this group" ) ); + const QAction * editAction = menu.addAction( QIcon( ":/icons/bookcase.svg" ), tr( "Edit this group" ) ); - QAction * infoAction = NULL; - QAction * headwordsAction = NULL; - QAction * editDictAction = NULL; - QAction * openDictFolderAction = NULL; + const QAction * infoAction = nullptr; + const QAction * headwordsAction = nullptr; + const QAction * editDictAction = nullptr; + const QAction * openDictFolderAction = nullptr; QString dictFilename; - QAction * dictAction = actionAt( event->x(), event->y() ); + const QAction * dictAction = actionAt( event->x(), event->y() ); if ( dictAction ) { - Dictionary::Class * pDict = NULL; - QString id = dictAction->data().toString(); - for ( unsigned i = 0; i < allDictionaries.size(); i++ ) { - if ( id.compare( allDictionaries[ i ]->getId().c_str() ) == 0 ) { - pDict = allDictionaries[ i ].get(); + Dictionary::Class * pDict = nullptr; + QString const id = dictAction->data().toString(); + for ( const auto & dictionary : allDictionaries ) { + if ( id.compare( dictionary->getId().c_str() ) == 0 ) { + pDict = dictionary.get(); break; } } @@ -134,7 +134,7 @@ void DictionaryBar::showContextMenu( QContextMenuEvent * event, bool extended ) unsigned refsAdded = 0; - for ( QList< QAction * >::iterator i = dictActions.begin(); i != dictActions.end(); ++i ) { + for ( const auto & dictAction : dictActions ) { // Enough! Or the menu would become too large. if ( refsAdded++ >= maxDictionaryRefsInContextMenu && !extended ) { @@ -144,11 +144,11 @@ void DictionaryBar::showContextMenu( QContextMenuEvent * event, bool extended ) } // We need new action, since the one we have has text elided - QAction * action = menu.addAction( ( *i )->icon(), ( *i )->toolTip() ); + QAction * action = menu.addAction( dictAction->icon(), dictAction->toolTip() ); action->setCheckable( true ); - action->setChecked( ( *i )->isChecked() ); - action->setData( QVariant::fromValue( (void *)*i ) ); + action->setChecked( dictAction->isChecked() ); + action->setData( QVariant::fromValue( (void *)dictAction ) ); // Force "icon in menu" on all platforms, for // usability reasons. action->setIconVisibleInMenu( true ); @@ -156,17 +156,16 @@ void DictionaryBar::showContextMenu( QContextMenuEvent * event, bool extended ) connect( this, &DictionaryBar::closePopupMenu, &menu, &QWidget::close ); - QAction * result = menu.exec( event->globalPos() ); + const QAction * result = menu.exec( event->globalPos() ); if ( result && result == infoAction ) { - QString id = dictAction->data().toString(); + QString const id = dictAction->data().toString(); emit showDictionaryInfo( id ); return; } if ( result && result == headwordsAction ) { - std::string id = dictAction->data().toString().toStdString(); - // TODO: use `Dictionary::class*` instead of `QString id` at action->setData to remove all similar `for` loops + std::string const id = dictAction->data().toString().toStdString(); for ( const auto & dict : allDictionaries ) { if ( id == dict->getId() ) { emit showDictionaryHeadwords( dict.get() ); @@ -177,14 +176,14 @@ void DictionaryBar::showContextMenu( QContextMenuEvent * event, bool extended ) } if ( result && result == openDictFolderAction ) { - QString id = dictAction->data().toString(); + QString const id = dictAction->data().toString(); emit openDictionaryFolder( id ); return; } if ( result && result == editDictAction ) { QString command( editDictionaryCommand ); - command.replace( "%GDDICT%", "\"" + dictFilename + "\"" ); + command.replace( "%GDDICT%", QString( R"("%1")" ).arg( dictFilename ) ); if ( !QProcess::startDetached( command, QStringList() ) ) QApplication::beep(); } @@ -212,11 +211,11 @@ void DictionaryBar::mutedDictionariesChanged() setUpdatesEnabled( false ); - for ( QList< QAction * >::iterator i = dictActions.begin(); i != dictActions.end(); ++i ) { - bool isUnmuted = !mutedDictionaries->contains( ( *i )->data().toString() ); + for ( const auto & dictAction : dictActions ) { + bool const isUnmuted = !mutedDictionaries->contains( dictAction->data().toString() ); - if ( isUnmuted != ( *i )->isChecked() ) - ( *i )->setChecked( isUnmuted ); + if ( isUnmuted != dictAction->isChecked() ) + dictAction->setChecked( isUnmuted ); } setUpdatesEnabled( true ); @@ -227,15 +226,14 @@ void DictionaryBar::actionWasTriggered( QAction * action ) if ( !mutedDictionaries ) return; - QString id = action->data().toString(); + QString const id = action->data().toString(); if ( id.isEmpty() ) return; // Some weird action, not our button if ( QApplication::keyboardModifiers() & ( Qt::ControlModifier | Qt::ShiftModifier ) ) { - // Solo mode -- either use the dictionary exclusively, or toggle - // back all dictionaries if we do that already. - + // Ctrl ,solo mode with single dictionary + // Shift,toggle back the previous dictionaries // Are we solo already? bool isSolo = true; @@ -243,35 +241,41 @@ void DictionaryBar::actionWasTriggered( QAction * action ) // For solo, all dictionaries must be unchecked, since we're handling // the result of the dictionary being (un)checked, and in case we were // in solo, now we would end up with no dictionaries being checked at all. - for ( QList< QAction * >::iterator i = dictActions.begin(); i != dictActions.end(); ++i ) { - if ( ( *i )->isChecked() ) { + for ( const auto & dictAction : dictActions ) { + if ( dictAction->isChecked() ) { isSolo = false; break; } } - - if ( isSolo ) { - // Restore or clear all the dictionaries - if ( QApplication::keyboardModifiers() & Qt::ShiftModifier ) + if ( QApplication::keyboardModifiers() & Qt::ShiftModifier ) { + if ( enterSoloMode ) { *mutedDictionaries = storedMutedSet; - else { - for ( QList< QAction * >::iterator i = dictActions.begin(); i != dictActions.end(); ++i ) - mutedDictionaries->remove( ( *i )->data().toString() ); + + storedMutedSet.clear(); + enterSoloMode = false; } - storedMutedSet.clear(); } else { // Save dictionaries state - storedMutedSet = *mutedDictionaries; + if ( !enterSoloMode ) { + storedMutedSet = *mutedDictionaries; + enterSoloMode = true; + } - // Make dictionary solo - for ( QList< QAction * >::iterator i = dictActions.begin(); i != dictActions.end(); ++i ) { - QString dictId = ( *i )->data().toString(); + if ( isSolo ) { + for ( const auto & dictAction : dictActions ) + mutedDictionaries->remove( dictAction->data().toString() ); + } + else { + // Make dictionary solo + for ( const auto & dictAction : dictActions ) { + QString const dictId = dictAction->data().toString(); - if ( dictId == id ) - mutedDictionaries->remove( dictId ); - else - mutedDictionaries->insert( dictId ); + if ( dictId == id ) + mutedDictionaries->remove( dictId ); + else + mutedDictionaries->insert( dictId ); + } } } configEvents.signalMutedDictionariesChanged(); @@ -305,10 +309,10 @@ void DictionaryBar::dictsPaneClicked( const QString & id ) if ( !isVisible() ) return; - for ( QList< QAction * >::iterator i = dictActions.begin(); i != dictActions.end(); ++i ) { - QString dictId = ( *i )->data().toString(); + for ( const auto & dictAction : dictActions ) { + QString const dictId = dictAction->data().toString(); if ( dictId == id ) { - ( *i )->activate( QAction::Trigger ); + dictAction->activate( QAction::Trigger ); break; } } diff --git a/src/ui/dictionarybar.hh b/src/ui/dictionarybar.hh index 5e6c2576..22071017 100644 --- a/src/ui/dictionarybar.hh +++ b/src/ui/dictionarybar.hh @@ -59,6 +59,8 @@ private: Config::MutedDictionaries * mutedDictionaries; Config::Events & configEvents; Config::MutedDictionaries storedMutedSet; + + bool enterSoloMode = false; QString editDictionaryCommand; // how many dictionaries should be shown in the context menu: unsigned short const & maxDictionaryRefsInContextMenu; diff --git a/website/docs/ui_shortcuts.md b/website/docs/ui_shortcuts.md index 633b01b1..ca069551 100644 --- a/website/docs/ui_shortcuts.md +++ b/website/docs/ui_shortcuts.md @@ -53,3 +53,16 @@ | F3 | Dictionaries dialog | | F4 | GoldenDict preferences | | F12 | Inspector | + + +# Solo mode in the dictionary bar +Ctrl+Click, Enter solo mode, toggle between single & all dictionaries +Shift+Click, Exit solo mode, restore the previous dictionaries. + +For example, there are 4 dictionaries A,B,C,D with ABC selected. +| Cases| Note| +|--------|--------| +| Ctrl+Click A|select A only| +| Ctrl+Click A, Ctrl+Click B | select B only| +| Ctrl+Click A, Ctrl+Click A | A,B,C,D selected(all dictionaries selected)| +| Ctrl+Click A, Shift+Click any dictionary| A,B,C selected |