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