commit 314bfa63d35f6d811b6173fa675c578a3a233b4b
Author: Koji Yokota <yok...@lyx.org>
Date:   Sat Apr 12 11:52:39 2025 +0900

    Indicating currently selected theme in PrefColors dialog
---
 lib/scripts/prefs2prefs_prefs.py |  5 +--
 src/LyXRC.cpp                    | 20 +++++++++++
 src/LyXRC.h                      |  3 ++
 src/frontends/qt/GuiPrefs.cpp    | 72 ++++++++++++++++++++++++++++++++++------
 src/frontends/qt/GuiPrefs.h      | 13 ++++++--
 5 files changed, 97 insertions(+), 16 deletions(-)

diff --git a/lib/scripts/prefs2prefs_prefs.py b/lib/scripts/prefs2prefs_prefs.py
index 5544c6aed2..06d06a297f 100644
--- a/lib/scripts/prefs2prefs_prefs.py
+++ b/lib/scripts/prefs2prefs_prefs.py
@@ -170,8 +170,9 @@
 #   Add option to configure ui style
 #   No conversion necessary.
 
-# Incremented to format 39, by spitz
-#   Add \color_scheme {system|light|dark}
+# Incremented to format 39
+#   Add \color_scheme {system|light|dark}, by spitz
+#   Add \ui_theme, by koji
 #   No conversion necessary.
 
 # NOTE: The format should also be updated in LYXRC.cpp and
diff --git a/src/LyXRC.cpp b/src/LyXRC.cpp
index 4309fc41d4..59c6657d10 100644
--- a/src/LyXRC.cpp
+++ b/src/LyXRC.cpp
@@ -199,6 +199,7 @@ LexerKeyword lyxrcTags[] = {
        { "\\thesaurusdir_path", LyXRC::RC_THESAURUSDIRPATH },
        { "\\ui_file", LyXRC::RC_UIFILE },
        { "\\ui_style", LyXRC::RC_UI_STYLE },
+    { "\\ui_theme", LyXRC::RC_UI_THEME },
        { "\\use_converter_cache", LyXRC::RC_USE_CONVERTER_CACHE },
        { "\\use_converter_needauth", LyXRC::RC_USE_CONVERTER_NEEDAUTH },
        { "\\use_converter_needauth_forbidden", 
LyXRC::RC_USE_CONVERTER_NEEDAUTH_FORBIDDEN },
@@ -679,6 +680,11 @@ LyXRC::ReturnValues LyXRC::read(Lexer & lexrc, bool 
check_format)
                        break;
                }
 
+               case RC_UI_THEME:
+                       if (lexrc.next())
+                               ui_theme = lexrc.getString();
+                       break;
+
                case RC_AUTOREGIONDELETE:
                        // Auto region delete defaults to true
                        lexrc >> auto_region_delete;
@@ -2091,6 +2097,15 @@ void LyXRC::write(ostream & os, bool 
ignore_system_lyxrc, string const & name) c
                << "# COLOR SECTION ###################################\n"
                << "#\n\n";
 
+       // fall through
+       case RC_UI_THEME:
+               if (ignore_system_lyxrc ||
+                       ui_theme != system_lyxrc.ui_theme)
+                       os << "\\ui_theme \"" << ui_theme << "\"\n";
+
+               if (tag != RC_LAST)
+                       break;
+
        // fall through
        case RC_SET_COLOR:
                for (int i = 0; i < Color_ignore; ++i) {
@@ -3064,6 +3079,7 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC 
const & lyxrc_new)
                // fall through
        case LyXRC::RC_GEOMETRY_SESSION:
        case LyXRC::RC_SERVERPIPE:
+       case LyXRC::RC_UI_THEME:
        case LyXRC::RC_SET_COLOR:
        case LyXRC::RC_SHOW_BANNER:
        case LyXRC::RC_OPEN_BUFFERS_IN_TABS:
@@ -3230,6 +3246,10 @@ string const LyXRC::getDescription(LyXRCTags tag)
                str = _("Possibility to enforce a particular color scheme 
(system|dark|light)");
                break;
 
+       case LyXRC::RC_UI_THEME:
+               str = _("Current UI theme if it has a name, otherwise empty");
+               break;
+
        case RC_DEFFILE:
                str = _("Command definition file. Can either specify an 
absolute path, or LyX will look in its global and local commands/ 
directories.");
                break;
diff --git a/src/LyXRC.h b/src/LyXRC.h
index ed86e97da9..c69311d16d 100644
--- a/src/LyXRC.h
+++ b/src/LyXRC.h
@@ -176,6 +176,7 @@ public:
                RC_THESAURUSDIRPATH,
                RC_UIFILE,
                RC_UI_STYLE,
+               RC_UI_THEME,
                RC_USELASTFILEPOS,
                RC_USER_EMAIL,
                RC_USER_INITIALS,
@@ -354,6 +355,8 @@ public:
        bool use_tooltip = true;
        /// Use the colors from current system theme?
        bool use_system_colors = false;
+       /// Current ui theme if named
+       std::string ui_theme;
        /// use native file dialog or our own ?
        bool use_native_filedialog = true;
        /// Spellchecker engine: aspell, hunspell, etc
diff --git a/src/frontends/qt/GuiPrefs.cpp b/src/frontends/qt/GuiPrefs.cpp
index ddd7fb85b6..d8fa25dd1f 100644
--- a/src/frontends/qt/GuiPrefs.cpp
+++ b/src/frontends/qt/GuiPrefs.cpp
@@ -1081,10 +1081,8 @@ PrefColors::PrefColors(GuiPreferences * form)
                this, SLOT(changeSysColor()));
        connect(themesMenuPB, SIGNAL(clicked()),
                this, SLOT(openThemeMenu()));
-       connect(themesLW,
-               SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
-               this,
-               SLOT(loadTheme(QListWidgetItem*,QListWidgetItem*)));
+       connect(themesLW, SIGNAL(currentRowChanged(int)),
+               this, SLOT(loadTheme(int)));
        connect(undoColorPB, SIGNAL(clicked()),
                undo_stack_, SLOT(undo()));
 }
@@ -1099,6 +1097,9 @@ void PrefColors::applyRC(LyXRC & rc) const
                        form_->setColor(lcolors_[i], newcolors_[i]);
        rc.use_system_colors = syscolorsCB->isChecked();
 
+       if (toqstr(rc.ui_theme) != theme_name_)
+               rc.ui_theme = theme_name_.toStdString();
+
        if (oldrc.use_system_colors != rc.use_system_colors)
                guiApp->colorCache().clear();
 }
@@ -1176,14 +1177,53 @@ void PrefColors::changeColor(int const &row, bool const 
&is_dark_mode)
        QColor const c = form_->getColor(QColor(color));
 
        if (setColor(colorsTV_model_.item(row, is_dark_mode), c, color)) {
-               themesLW->setCurrentRow(themesLW->currentRow(),
-                                       QItemSelectionModel::Deselect);
+               setCurrentTheme(row);
                // emit signal
                changed();
        }
 }
 
 
+void PrefColors::setCurrentTheme(int const color_row)
+{
+       if (newcolors_[color_row] != theme_colors_[color_row])
+               dismissCurrentTheme();
+       else {
+               // now that current row matched, check for other color_row's if 
they
+               // make up the current theme
+               // note: we won't care about matches with other themes since it 
would
+               // rarely happen and doesn't convey much useful information.
+               // its implementation cost (esp. cpu time) would exceed the 
benefit.
+               for (int col = 0; col < colorsTV_model_.rowCount(); ++col) {
+                       if (col == color_row) continue;
+                       if (newcolors_[col] != theme_colors_[col]) {
+                               dismissCurrentTheme();
+                               break;
+                       }
+               }
+               // all colors matched
+               theme_name_ = last_theme_name_;
+               // set the theme indicator
+               for (int theme_row = 0; theme_row < themesLW->count(); 
++theme_row) {
+                       if (themesLW->item(theme_row)->text() == theme_name_) {
+                               themesLW->setCurrentRow(theme_row);
+                               break;
+                       }
+               }
+       }
+}
+
+
+void PrefColors::dismissCurrentTheme()
+{
+       if (!theme_name_.isEmpty())
+               last_theme_name_ = theme_name_;
+       theme_name_ = "";
+       themesLW->setCurrentRow(themesLW->currentRow(),
+                               QItemSelectionModel::Deselect);
+}
+
+
 bool PrefColors::setSwatch(QStandardItem *item, QColor const &color)
 {
        QModelIndex index = colorsTV_model_.indexFromItem(item);
@@ -1504,14 +1544,13 @@ void PrefColors::importTheme()
 }
 
 
-void PrefColors::loadTheme(QListWidgetItem* current_item,
-                                    QListWidgetItem* previous_item)
+void PrefColors::loadTheme(int const row)
 {
-       Q_UNUSED(previous_item)
+       if (row < 0) return;
 
-       
loadImportThemeCommon(FileName(fromqstr(theme_fullpaths_[themesLW->row(current_item)])));
+       loadImportThemeCommon(FileName(fromqstr(theme_fullpaths_[row])));
        // state variables below are used for suggestion in dialogs
-       theme_filename_ = 
onlyFileName(theme_fullpaths_[themesLW->row(current_item)]);
+       theme_filename_ = onlyFileName(theme_fullpaths_[row]);
        theme_name_ = removeExtension(theme_filename_).replace('_', ' ');
 }
 
@@ -1632,6 +1671,10 @@ void PrefColors::initializeThemesLW()
                themes.emplace(guiname + "_usr", std::make_pair(filename, 
true));
        }
        themesLW->clear();
+
+       if (toqstr(lyxrc.ui_theme) != theme_name_)
+               theme_name_ = toqstr(lyxrc.ui_theme);
+
        // themes are already sorted with GUI name as std::map sorts its entries
        for (const auto & theme : themes) {
                QListWidgetItem* item = new QListWidgetItem;
@@ -1641,6 +1684,11 @@ void PrefColors::initializeThemesLW()
                else
                        item->setIcon(sys_theme_icon);
                themesLW->addItem(item);
+
+               // current theme is indicated by selection
+               if (item->text() == theme_name_)
+                       themesLW->setCurrentItem(item);
+
                theme_fullpaths_.push_back(theme.second.first);
                if (theme.first.right(3) == "sys")
                        isSysThemes_.push_back(true);
@@ -4398,6 +4446,7 @@ void SetColor::redo()
        // set button statuses
        parent_->setResetButtonStatus(false);
        parent_->setUndoRedoButtonStatuses(false);
+       parent_->setCurrentTheme(item_.row());
 }
 
 
@@ -4408,6 +4457,7 @@ void SetColor::undo()
        // set button statuses
        parent_->setResetButtonStatus(true);
        parent_->setUndoRedoButtonStatuses(true);
+       parent_->setCurrentTheme(item_.row());
 }
 
 
diff --git a/src/frontends/qt/GuiPrefs.h b/src/frontends/qt/GuiPrefs.h
index 7b5ebf3320..382eca41d9 100644
--- a/src/frontends/qt/GuiPrefs.h
+++ b/src/frontends/qt/GuiPrefs.h
@@ -290,8 +290,7 @@ private Q_SLOTS:
        bool resetDarkColor() { return resetColor(true);  }
        void openThemeMenu();
        void saveTheme();
-       void loadTheme(QListWidgetItem* current_item,
-                      QListWidgetItem* previous_item);
+       void loadTheme(int const row);
        void removeTheme();
        void exportTheme();
        void importTheme();
@@ -314,6 +313,12 @@ private:
        QColor getCurrentThemeColor(int const &row, bool const &is_dark_color);
        ///
        ColorPair getCurrentThemeColors(int const &row);
+       /// After a color change of \p row, set a theme name of the current 
color
+       /// set in theme_name and indicates it in themesLW.
+       void setCurrentTheme(int const row);
+       /// Empty the current theme name and deselect the corresponding item in
+       /// themesLW.
+       void dismissCurrentTheme();
        /// Set color swatches for both light and dark colors by row.
        bool setSwatches(size_type const &row, ColorPair colors);
        /// Set color swatch at item.
@@ -364,8 +369,10 @@ private:
        QMenu theme_menu_;
        std::vector<bool> isSysThemes_;
        std::vector<QString> theme_fullpaths_;
-       /// holds currently selected theme
+       /// name of current theme
        QString theme_name_ = "";
+       /// name of last theme name
+       QString last_theme_name_ = "";
        /// holds filename of currently selected theme
        QString theme_filename_;
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
https://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to