opt: rewrite solo mode in the dictionary bar (#1073)

* action: output new syntax

* opt: dictionary bar modification,Ctrl for solo selection, Shift restore

* opt: only the first Ctrl + Click event store the existed dictionaries

* [autofix.ci] apply automated fixes

* opt: ctrl switch between single and all dictionaries

* doc: add shortcut document about solo mode

---------

Co-authored-by: YiFang Xiao <yifang.xiao@noreply.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
xiaoyifang 2023-08-21 21:04:04 +08:00 committed by GitHub
parent 8cd29d527a
commit 3359f6636a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 74 additions and 55 deletions

View file

@ -13,7 +13,7 @@ DictionaryBar::DictionaryBar( QWidget * parent,
QString const & _editDictionaryCommand, QString const & _editDictionaryCommand,
unsigned short const & maxDictionaryRefsInContextMenu_ ): unsigned short const & maxDictionaryRefsInContextMenu_ ):
QToolBar( tr( "&Dictionary Bar" ), parent ), QToolBar( tr( "&Dictionary Bar" ), parent ),
mutedDictionaries( 0 ), mutedDictionaries( nullptr ),
configEvents( events ), configEvents( events ),
editDictionaryCommand( _editDictionaryCommand ), editDictionaryCommand( _editDictionaryCommand ),
maxDictionaryRefsInContextMenu( maxDictionaryRefsInContextMenu_ ) maxDictionaryRefsInContextMenu( maxDictionaryRefsInContextMenu_ )
@ -52,16 +52,16 @@ void DictionaryBar::setDictionaries( vector< sptr< Dictionary::Class > > const &
clear(); clear();
dictActions.clear(); dictActions.clear();
for ( unsigned x = 0; x < dictionaries.size(); ++x ) { for ( const auto & dictionary : dictionaries ) {
QIcon icon = dictionaries[ x ]->getIcon(); 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 ) ); QAction * action = addAction( icon, elideDictName( dictName ) );
action->setToolTip( dictName ); // Tooltip need not be shortened action->setToolTip( dictName ); // Tooltip need not be shortened
QString id = QString::fromStdString( dictionaries[ x ]->getId() ); QString id = QString::fromStdString( dictionary->getId() );
action->setData( id ); action->setData( id );
@ -91,21 +91,21 @@ void DictionaryBar::showContextMenu( QContextMenuEvent * event, bool extended )
{ {
QMenu menu( this ); 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; const QAction * infoAction = nullptr;
QAction * headwordsAction = NULL; const QAction * headwordsAction = nullptr;
QAction * editDictAction = NULL; const QAction * editDictAction = nullptr;
QAction * openDictFolderAction = NULL; const QAction * openDictFolderAction = nullptr;
QString dictFilename; QString dictFilename;
QAction * dictAction = actionAt( event->x(), event->y() ); const QAction * dictAction = actionAt( event->x(), event->y() );
if ( dictAction ) { if ( dictAction ) {
Dictionary::Class * pDict = NULL; Dictionary::Class * pDict = nullptr;
QString id = dictAction->data().toString(); QString const id = dictAction->data().toString();
for ( unsigned i = 0; i < allDictionaries.size(); i++ ) { for ( const auto & dictionary : allDictionaries ) {
if ( id.compare( allDictionaries[ i ]->getId().c_str() ) == 0 ) { if ( id.compare( dictionary->getId().c_str() ) == 0 ) {
pDict = allDictionaries[ i ].get(); pDict = dictionary.get();
break; break;
} }
} }
@ -134,7 +134,7 @@ void DictionaryBar::showContextMenu( QContextMenuEvent * event, bool extended )
unsigned refsAdded = 0; 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. // Enough! Or the menu would become too large.
if ( refsAdded++ >= maxDictionaryRefsInContextMenu && !extended ) { 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 // 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->setCheckable( true );
action->setChecked( ( *i )->isChecked() ); action->setChecked( dictAction->isChecked() );
action->setData( QVariant::fromValue( (void *)*i ) ); action->setData( QVariant::fromValue( (void *)dictAction ) );
// Force "icon in menu" on all platforms, for // Force "icon in menu" on all platforms, for
// usability reasons. // usability reasons.
action->setIconVisibleInMenu( true ); action->setIconVisibleInMenu( true );
@ -156,17 +156,16 @@ void DictionaryBar::showContextMenu( QContextMenuEvent * event, bool extended )
connect( this, &DictionaryBar::closePopupMenu, &menu, &QWidget::close ); connect( this, &DictionaryBar::closePopupMenu, &menu, &QWidget::close );
QAction * result = menu.exec( event->globalPos() ); const QAction * result = menu.exec( event->globalPos() );
if ( result && result == infoAction ) { if ( result && result == infoAction ) {
QString id = dictAction->data().toString(); QString const id = dictAction->data().toString();
emit showDictionaryInfo( id ); emit showDictionaryInfo( id );
return; return;
} }
if ( result && result == headwordsAction ) { if ( result && result == headwordsAction ) {
std::string id = dictAction->data().toString().toStdString(); std::string const id = dictAction->data().toString().toStdString();
// TODO: use `Dictionary::class*` instead of `QString id` at action->setData to remove all similar `for` loops
for ( const auto & dict : allDictionaries ) { for ( const auto & dict : allDictionaries ) {
if ( id == dict->getId() ) { if ( id == dict->getId() ) {
emit showDictionaryHeadwords( dict.get() ); emit showDictionaryHeadwords( dict.get() );
@ -177,14 +176,14 @@ void DictionaryBar::showContextMenu( QContextMenuEvent * event, bool extended )
} }
if ( result && result == openDictFolderAction ) { if ( result && result == openDictFolderAction ) {
QString id = dictAction->data().toString(); QString const id = dictAction->data().toString();
emit openDictionaryFolder( id ); emit openDictionaryFolder( id );
return; return;
} }
if ( result && result == editDictAction ) { if ( result && result == editDictAction ) {
QString command( editDictionaryCommand ); QString command( editDictionaryCommand );
command.replace( "%GDDICT%", "\"" + dictFilename + "\"" ); command.replace( "%GDDICT%", QString( R"("%1")" ).arg( dictFilename ) );
if ( !QProcess::startDetached( command, QStringList() ) ) if ( !QProcess::startDetached( command, QStringList() ) )
QApplication::beep(); QApplication::beep();
} }
@ -212,11 +211,11 @@ void DictionaryBar::mutedDictionariesChanged()
setUpdatesEnabled( false ); setUpdatesEnabled( false );
for ( QList< QAction * >::iterator i = dictActions.begin(); i != dictActions.end(); ++i ) { for ( const auto & dictAction : dictActions ) {
bool isUnmuted = !mutedDictionaries->contains( ( *i )->data().toString() ); bool const isUnmuted = !mutedDictionaries->contains( dictAction->data().toString() );
if ( isUnmuted != ( *i )->isChecked() ) if ( isUnmuted != dictAction->isChecked() )
( *i )->setChecked( isUnmuted ); dictAction->setChecked( isUnmuted );
} }
setUpdatesEnabled( true ); setUpdatesEnabled( true );
@ -227,15 +226,14 @@ void DictionaryBar::actionWasTriggered( QAction * action )
if ( !mutedDictionaries ) if ( !mutedDictionaries )
return; return;
QString id = action->data().toString(); QString const id = action->data().toString();
if ( id.isEmpty() ) if ( id.isEmpty() )
return; // Some weird action, not our button return; // Some weird action, not our button
if ( QApplication::keyboardModifiers() & ( Qt::ControlModifier | Qt::ShiftModifier ) ) { if ( QApplication::keyboardModifiers() & ( Qt::ControlModifier | Qt::ShiftModifier ) ) {
// Solo mode -- either use the dictionary exclusively, or toggle // Ctrl ,solo mode with single dictionary
// back all dictionaries if we do that already. // Shift,toggle back the previous dictionaries
// Are we solo already? // Are we solo already?
bool isSolo = true; bool isSolo = true;
@ -243,35 +241,41 @@ void DictionaryBar::actionWasTriggered( QAction * action )
// For solo, all dictionaries must be unchecked, since we're handling // For solo, all dictionaries must be unchecked, since we're handling
// the result of the dictionary being (un)checked, and in case we were // 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. // 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 ) { for ( const auto & dictAction : dictActions ) {
if ( ( *i )->isChecked() ) { if ( dictAction->isChecked() ) {
isSolo = false; isSolo = false;
break; break;
} }
} }
if ( QApplication::keyboardModifiers() & Qt::ShiftModifier ) {
if ( isSolo ) { if ( enterSoloMode ) {
// Restore or clear all the dictionaries
if ( QApplication::keyboardModifiers() & Qt::ShiftModifier )
*mutedDictionaries = storedMutedSet; *mutedDictionaries = storedMutedSet;
else {
for ( QList< QAction * >::iterator i = dictActions.begin(); i != dictActions.end(); ++i ) storedMutedSet.clear();
mutedDictionaries->remove( ( *i )->data().toString() ); enterSoloMode = false;
} }
storedMutedSet.clear();
} }
else { else {
// Save dictionaries state // Save dictionaries state
storedMutedSet = *mutedDictionaries; if ( !enterSoloMode ) {
storedMutedSet = *mutedDictionaries;
enterSoloMode = true;
}
// Make dictionary solo if ( isSolo ) {
for ( QList< QAction * >::iterator i = dictActions.begin(); i != dictActions.end(); ++i ) { for ( const auto & dictAction : dictActions )
QString dictId = ( *i )->data().toString(); mutedDictionaries->remove( dictAction->data().toString() );
}
else {
// Make dictionary solo
for ( const auto & dictAction : dictActions ) {
QString const dictId = dictAction->data().toString();
if ( dictId == id ) if ( dictId == id )
mutedDictionaries->remove( dictId ); mutedDictionaries->remove( dictId );
else else
mutedDictionaries->insert( dictId ); mutedDictionaries->insert( dictId );
}
} }
} }
configEvents.signalMutedDictionariesChanged(); configEvents.signalMutedDictionariesChanged();
@ -305,10 +309,10 @@ void DictionaryBar::dictsPaneClicked( const QString & id )
if ( !isVisible() ) if ( !isVisible() )
return; return;
for ( QList< QAction * >::iterator i = dictActions.begin(); i != dictActions.end(); ++i ) { for ( const auto & dictAction : dictActions ) {
QString dictId = ( *i )->data().toString(); QString const dictId = dictAction->data().toString();
if ( dictId == id ) { if ( dictId == id ) {
( *i )->activate( QAction::Trigger ); dictAction->activate( QAction::Trigger );
break; break;
} }
} }

View file

@ -59,6 +59,8 @@ private:
Config::MutedDictionaries * mutedDictionaries; Config::MutedDictionaries * mutedDictionaries;
Config::Events & configEvents; Config::Events & configEvents;
Config::MutedDictionaries storedMutedSet; Config::MutedDictionaries storedMutedSet;
bool enterSoloMode = false;
QString editDictionaryCommand; QString editDictionaryCommand;
// how many dictionaries should be shown in the context menu: // how many dictionaries should be shown in the context menu:
unsigned short const & maxDictionaryRefsInContextMenu; unsigned short const & maxDictionaryRefsInContextMenu;

View file

@ -53,3 +53,16 @@
| F3 | Dictionaries dialog | | F3 | Dictionaries dialog |
| F4 | GoldenDict preferences | | F4 | GoldenDict preferences |
| F12 | Inspector | | 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 |