diff --git a/icons/star_blue_other.svg b/icons/star_blue_other.svg
new file mode 100644
index 000000000..2cd5e4fb3
--- /dev/null
+++ b/icons/star_blue_other.svg
@@ -0,0 +1,127 @@
+
+
diff --git a/icons/star_other.svg b/icons/star_other.svg
new file mode 100644
index 000000000..8c2e8d5a0
--- /dev/null
+++ b/icons/star_other.svg
@@ -0,0 +1,167 @@
+
+
diff --git a/resources.qrc b/resources.qrc
index 3120262bc..b31b35f50 100644
--- a/resources.qrc
+++ b/resources.qrc
@@ -75,6 +75,8 @@
icons/sources.png
icons/star.svg
icons/star_blue.svg
+ icons/star_other.svg
+ icons/star_blue_other.svg
icons/system-search.svg
icons/windows-list.svg
icons/wizard.svg
diff --git a/src/common/globalbroadcaster.hh b/src/common/globalbroadcaster.hh
index 0be64a5c2..e8a241f48 100644
--- a/src/common/globalbroadcaster.hh
+++ b/src/common/globalbroadcaster.hh
@@ -39,7 +39,8 @@ public:
QString translateLineText{};
//hold the dictionary id;
QSet< QString > collapsedDicts;
- QMap< QString, QSet< QString > > folderFavoritesMap;
+ //key hold the headword, value holds the folders.
+ QMap< QString, QSet< QString > > wordFavoriteFolderMap;
QMap< unsigned, QString > groupFolderMap;
PronounceEngine pronounce_engine;
QString getAbbrName( QString const & text );
diff --git a/src/ui/favoritemanager.cc b/src/ui/favoritemanager.cc
new file mode 100644
index 000000000..e5afd1de7
--- /dev/null
+++ b/src/ui/favoritemanager.cc
@@ -0,0 +1,28 @@
+//
+// Created by xiaoyifang on 2025/2/21.
+//
+
+#include "favoritemanager.hh"
+#include "globalbroadcaster.hh"
+FavoriteType FavoriteManager::determineFavoriteType( const QString & word, unsigned groupId )
+{
+ QString folder = GlobalBroadcaster::instance()->groupFolderMap[ groupId ];
+ return determineFavoriteType( word, folder );
+}
+
+FavoriteType FavoriteManager::determineFavoriteType( const QString & word, const QString & folder )
+{
+ if ( !GlobalBroadcaster::instance()->wordFavoriteFolderMap.contains( word ) ) {
+ return FavoriteType::EMPTY;
+ }
+
+ if ( GlobalBroadcaster::instance()->wordFavoriteFolderMap[ word ].contains( folder ) ) {
+ if ( GlobalBroadcaster::instance()->wordFavoriteFolderMap[ word ].size() == 1 ) {
+ return FavoriteType::FULL;
+ }
+ else {
+ return FavoriteType::FULL_OTHER;
+ }
+ }
+ return FavoriteType::EMPTY_OTHER;
+}
diff --git a/src/ui/favoritemanager.hh b/src/ui/favoritemanager.hh
new file mode 100644
index 000000000..58c6e4817
--- /dev/null
+++ b/src/ui/favoritemanager.hh
@@ -0,0 +1,21 @@
+/* This file is (c) 2025 gd-ng community
+* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
+
+#pragma once
+
+#include
+enum class FavoriteType {
+ EMPTY,
+ //current group is empty while other group is not empty
+ EMPTY_OTHER,
+ FULL,
+ FULL_OTHER
+};
+
+class FavoriteManager
+{
+
+public:
+ static FavoriteType determineFavoriteType( QString const & word, unsigned group );
+ static FavoriteType determineFavoriteType( const QString & word, const QString & folder );
+};
diff --git a/src/ui/favoritespanewidget.cc b/src/ui/favoritespanewidget.cc
index f9b80d8e1..ef412f76f 100644
--- a/src/ui/favoritespanewidget.cc
+++ b/src/ui/favoritespanewidget.cc
@@ -274,12 +274,12 @@ void FavoritesPaneWidget::clearAllItems()
void FavoritesPaneWidget::addHeadword( QString const & path, QString const & headword )
{
m_favoritesModel->addNewHeadword( path, headword );
- GlobalBroadcaster::instance()->folderFavoritesMap[ path ].insert( headword );
+ GlobalBroadcaster::instance()->wordFavoriteFolderMap[ headword ].insert( path );
}
bool FavoritesPaneWidget::removeHeadword( QString const & path, QString const & headword )
{
- GlobalBroadcaster::instance()->folderFavoritesMap[ path ].remove( headword );
+ GlobalBroadcaster::instance()->wordFavoriteFolderMap[ headword ].remove( path );
return m_favoritesModel->removeHeadword( path, headword );
}
@@ -761,7 +761,7 @@ void FavoritesModel::addFolder( TreeItem * parent, QDomNode & node )
}
parent->appendChild( new TreeItem( word, parent, TreeItem::Word ) );
- GlobalBroadcaster::instance()->folderFavoritesMap[ parent->data().toString() ].insert( word );
+ GlobalBroadcaster::instance()->wordFavoriteFolderMap[ word ].insert( parent->data().toString() );
}
}
dirty = true;
diff --git a/src/ui/mainwindow.cc b/src/ui/mainwindow.cc
index 5d6606e94..9b782414a 100644
--- a/src/ui/mainwindow.cc
+++ b/src/ui/mainwindow.cc
@@ -54,6 +54,7 @@
#include
#include "globalregex.hh"
+#include "favoritemanager.hh"
#ifdef Q_OS_MAC
#include "macos/macmouseover.hh"
@@ -176,8 +177,10 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
headwordsDlg( nullptr ),
ftsIndexing( dictionaries ),
ftsDlg( nullptr ),
- starIcon( ":/icons/star.svg" ),
- blueStarIcon( ":/icons/star_blue.svg" )
+ emptyStarIcon( ":/icons/star.svg" ),
+ fullStarIcon( ":/icons/star_blue.svg" ),
+ emptyOtherStarIcon( ":/icons/star_other.svg" ),
+ fullOtherStarIcon( ":/icons/star_blue_other.svg" )
{
if ( QThreadPool::globalInstance()->maxThreadCount() < MIN_THREAD_COUNT ) {
QThreadPool::globalInstance()->setMaxThreadCount( MIN_THREAD_COUNT );
@@ -298,7 +301,7 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
navToolbar->widgetForAction( navToolbar->addSeparator() )->setObjectName( "separatorBeforeAddToFavorites" );
- addToFavorites = navToolbar->addAction( starIcon, tr( "Add current tab to Favorites" ) );
+ addToFavorites = navToolbar->addAction( emptyStarIcon, tr( "Add current tab to Favorites" ) );
navToolbar->widgetForAction( addToFavorites )->setObjectName( "addToFavoritesButton" );
connect( addToFavorites, &QAction::triggered, this, &MainWindow::handleAddToFavoritesButton );
@@ -1997,18 +2000,33 @@ void MainWindow::titleChanged( ArticleView * view, QString const & title )
if ( index == ui.tabWidget->currentIndex() ) {
// Set icon for "Add to Favorites" action
- if ( isWordPresentedInFavorites( title, cfg.lastMainGroupId ) ) {
- addToFavorites->setIcon( blueStarIcon );
- addToFavorites->setToolTip( tr( "Remove current tab from Favorites" ) );
- }
- else {
- addToFavorites->setIcon( starIcon );
- addToFavorites->setToolTip( tr( "Add current tab to Favorites" ) );
- }
+ updateFavoriteIcon( title );
updateWindowTitle();
}
}
+void MainWindow::updateFavoriteIcon( const QString & title )
+{
+ auto favoriteType = FavoriteManager::determineFavoriteType( title, this->cfg.lastMainGroupId );
+ switch ( favoriteType ) {
+ case FavoriteType::EMPTY:
+ this->addToFavorites->setIcon( this->emptyStarIcon );
+ this->addToFavorites->setToolTip( tr( "Add current tab to Favorites" ) );
+ break;
+ case FavoriteType::FULL:
+ this->addToFavorites->setIcon( this->fullStarIcon );
+ this->addToFavorites->setToolTip( tr( "Remove current tab from Favorites" ) );
+ break;
+ case FavoriteType::EMPTY_OTHER:
+ this->addToFavorites->setIcon( this->emptyOtherStarIcon );
+ this->addToFavorites->setToolTip( tr( "Add current tab to Favorites" ) );
+ break;
+ case FavoriteType::FULL_OTHER:
+ this->addToFavorites->setIcon( this->fullOtherStarIcon );
+ this->addToFavorites->setToolTip( tr( "Remove current tab from Favorites" ) );
+ break;
+ }
+}
void MainWindow::iconChanged( ArticleView * view, QIcon const & icon )
{
@@ -2066,14 +2084,7 @@ void MainWindow::tabSwitched( int )
if ( view ) {
headword = view->getCurrentWord();
}
- if ( isWordPresentedInFavorites( headword, cfg.lastMainGroupId ) ) {
- addToFavorites->setIcon( blueStarIcon );
- addToFavorites->setToolTip( tr( "Remove current tab from Favorites" ) );
- }
- else {
- addToFavorites->setIcon( starIcon );
- addToFavorites->setToolTip( tr( "Add current tab to Favorites" ) );
- }
+ updateFavoriteIcon( headword );
if ( view ) {
groupList->setCurrentGroup( view->getCurrentGroupId() );
@@ -4259,7 +4270,7 @@ void MainWindow::addCurrentTabToFavorites()
ui.favoritesPaneWidget->addHeadword( folder, headword );
- addToFavorites->setIcon( blueStarIcon );
+ addToFavorites->setIcon( fullStarIcon );
addToFavorites->setToolTip( tr( "Remove current tab from Favorites" ) );
}
@@ -4275,8 +4286,9 @@ void MainWindow::handleAddToFavoritesButton()
return;
}
auto headword = view->getCurrentWord();
+ auto favoriteType = FavoriteManager::determineFavoriteType( headword, folder );
- if ( ui.favoritesPaneWidget->isHeadwordPresent( folder, headword ) ) {
+ if ( favoriteType == FavoriteType::FULL || favoriteType == FavoriteType::FULL_OTHER ) {
QMessageBox mb( QMessageBox::Question,
"GoldenDict",
tr( "Remove headword \"%1\" from Favorites?" ).arg( headword ),
@@ -4284,14 +4296,24 @@ void MainWindow::handleAddToFavoritesButton()
this );
if ( mb.exec() == QMessageBox::Yes ) {
if ( ui.favoritesPaneWidget->removeHeadword( folder, headword ) ) {
- addToFavorites->setIcon( starIcon );
+ if ( favoriteType == FavoriteType::FULL ) {
+ addToFavorites->setIcon( emptyStarIcon );
+ }
+ else {
+ addToFavorites->setIcon( emptyOtherStarIcon );
+ }
addToFavorites->setToolTip( tr( "Add current tab to Favorites" ) );
}
}
}
else {
ui.favoritesPaneWidget->addHeadword( folder, headword );
- addToFavorites->setIcon( blueStarIcon );
+ if ( favoriteType == FavoriteType::EMPTY ) {
+ addToFavorites->setIcon( fullStarIcon );
+ }
+ else {
+ addToFavorites->setIcon( fullOtherStarIcon );
+ }
addToFavorites->setToolTip( tr( "Remove current tab from Favorites" ) );
}
}
@@ -4341,7 +4363,7 @@ void MainWindow::addAllTabsToFavorites()
auto headword = view->getCurrentWord();
ui.favoritesPaneWidget->addHeadword( folder, headword );
}
- addToFavorites->setIcon( blueStarIcon );
+ addToFavorites->setIcon( fullStarIcon );
addToFavorites->setToolTip( tr( "Remove current tab from Favorites" ) );
}
diff --git a/src/ui/mainwindow.hh b/src/ui/mainwindow.hh
index 4c805138a..81f9efca4 100644
--- a/src/ui/mainwindow.hh
+++ b/src/ui/mainwindow.hh
@@ -170,7 +170,7 @@ private:
FTS::FullTextSearchDialog * ftsDlg;
- QIcon starIcon, blueStarIcon;
+ QIcon emptyStarIcon, fullStarIcon, emptyOtherStarIcon, fullOtherStarIcon;
LocalSchemeHandler * localSchemeHandler;
IframeSchemeHandler * iframeSchemeHandler;
@@ -266,6 +266,7 @@ private:
bool isWordPresentedInFavorites( QString const & word, unsigned groupId );
void errorMessageOnStatusBar( const QString & errStr );
int getIconSize();
+ void updateFavoriteIcon( const QString & title );
private slots:
diff --git a/src/ui/scanpopup.cc b/src/ui/scanpopup.cc
index 112232ae2..284f7a245 100644
--- a/src/ui/scanpopup.cc
+++ b/src/ui/scanpopup.cc
@@ -15,6 +15,7 @@
#define MouseOver MacMouseOver
#endif
#include "base_type.hh"
+#include "favoritemanager.hh"
static const Qt::WindowFlags defaultUnpinnedWindowFlags =
@@ -1118,9 +1119,24 @@ void ScanPopup::on_sendWordToFavoritesButton_clicked()
return;
}
unsigned groupId = ui.groupList->getCurrentGroup();
- auto current_exist = isWordPresentedInFavorites( definition->getTitle(), groupId );
- //if current_exist=false( not exist ), after click ,the word should be in the favorite which is blueStar
- ui.sendWordToFavoritesButton->setIcon( !current_exist ? blueStarIcon : starIcon );
+ auto favoriteType = FavoriteManager::determineFavoriteType( definition->getTitle(), groupId );
+ bool current_exist = false;
+ switch ( favoriteType ) {
+ case FavoriteType::EMPTY:
+ ui.sendWordToFavoritesButton->setIcon( fullIcon );
+ break;
+ case FavoriteType::EMPTY_OTHER:
+ ui.sendWordToFavoritesButton->setIcon( fullFullIcon );
+ break;
+ case FavoriteType::FULL:
+ current_exist = true;
+ ui.sendWordToFavoritesButton->setIcon( emptyIcon );
+ break;
+ case FavoriteType::FULL_OTHER:
+ current_exist = true;
+ ui.sendWordToFavoritesButton->setIcon( emptyFullIcon );
+ break;
+ }
emit sendWordToFavorites( definition->getTitle(), cfg.lastPopupGroupId, current_exist );
}
@@ -1202,14 +1218,30 @@ void ScanPopup::titleChanged( ArticleView *, QString const & title ) const
unsigned groupId = ui.groupList->getCurrentGroup();
// Set icon for "Add to Favorites" button
- ui.sendWordToFavoritesButton->setIcon( isWordPresentedInFavorites( title, groupId ) ? blueStarIcon : starIcon );
+
+ auto favoriteType = FavoriteManager::determineFavoriteType( title, groupId );
+ switch ( favoriteType ) {
+ case FavoriteType::EMPTY:
+ ui.sendWordToFavoritesButton->setIcon( emptyIcon );
+
+ break;
+ case FavoriteType::EMPTY_OTHER:
+ ui.sendWordToFavoritesButton->setIcon( emptyFullIcon );
+ break;
+ case FavoriteType::FULL:
+ ui.sendWordToFavoritesButton->setIcon( fullIcon );
+ break;
+ case FavoriteType::FULL_OTHER:
+ ui.sendWordToFavoritesButton->setIcon( fullFullIcon );
+ break;
+ }
}
bool ScanPopup::isWordPresentedInFavorites( QString const & word, unsigned groupId ) const
{
QString folder = GlobalBroadcaster::instance()->groupFolderMap[ groupId ];
- return GlobalBroadcaster::instance()->folderFavoritesMap[ folder ].contains( word );
+ return GlobalBroadcaster::instance()->wordFavoriteFolderMap[ word ].contains( folder );
}
#ifdef HAVE_X11
diff --git a/src/ui/scanpopup.hh b/src/ui/scanpopup.hh
index b5df0ab8c..9d8111254 100644
--- a/src/ui/scanpopup.hh
+++ b/src/ui/scanpopup.hh
@@ -160,8 +160,10 @@ private:
QTimer mouseGrabPollTimer;
- QIcon starIcon = QIcon( ":/icons/star.svg" );
- QIcon blueStarIcon = QIcon( ":/icons/star_blue.svg" );
+ QIcon emptyIcon = QIcon( ":/icons/star.svg" );
+ QIcon fullIcon = QIcon( ":/icons/star_blue.svg" );
+ QIcon emptyFullIcon = QIcon( ":/icons/star_other.svg" );
+ QIcon fullFullIcon = QIcon( ":/icons/star_blue_other.svg" );
void handleInputWord( QString const &, bool forcePopup = false );
void engagePopup( bool forcePopup, bool giveFocus = false );