cui/source/options/appearance.cxx | 73 +++++++------ cui/source/options/appearance.hxx | 4 cui/uiconfig/ui/appearance.ui | 17 ++- include/vcl/settings.hxx | 9 + include/vcl/themecolors.hxx | 11 + officecfg/registry/schema/org/openoffice/Office/Common.xcs | 7 + svtools/source/config/colorcfg.cxx | 20 +++ vcl/osx/salframe.cxx | 1 vcl/qt5/QtFrame.cxx | 1 vcl/source/app/settings.cxx | 15 ++ vcl/unx/gtk3/salnativewidgets-gtk.cxx | 1 vcl/win/window/salframe.cxx | 1 12 files changed, 114 insertions(+), 46 deletions(-)
New commits: commit c7c7a2e5dfeb23304758c78aece1d439c8ceead2 Author: Sahil Gautam <[email protected]> AuthorDate: Wed Dec 25 23:13:47 2024 +0530 Commit: Sahil Gautam <[email protected]> CommitDate: Mon Jan 26 09:49:55 2026 +0100 tdf#164393 [API CHANGE] Make the "Automatic" theme Customizable + enable the "Customizations" section for the "Default" theme. by default the system colors will be used. If the system theme changes then only those colors will persist which were set explicitly by the user. (well explained in the comments near colorcfg.cxx changes) + add a "Reset all" button to reset all the theme colors to system colors. Pressing this button sets all the values to Automatic (system colors) irrespective of which theme is being used. We have plans for integrating the ExtensionManger with Themes so that we can reload the extension when the colors are reset. Change-Id: Ic811415b24a353b9cfcf7c633a5621b595ec27d1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/179406 Tested-by: Jenkins Reviewed-by: Heiko Tietze <[email protected]> Reviewed-by: Sahil Gautam <[email protected]> (cherry picked from commit 924c7de80afa47a93705e5d073c35f2d81f4ed5a) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198083 Reviewed-by: Sahil Gautam <[email protected]> Tested-by: Jenkins CollaboraOffice <[email protected]> diff --git a/cui/source/options/appearance.cxx b/cui/source/options/appearance.cxx index 77a4c01bb931..c0a170708383 100644 --- a/cui/source/options/appearance.cxx +++ b/cui/source/options/appearance.cxx @@ -104,6 +104,7 @@ SvxAppearanceTabPage::SvxAppearanceTabPage(weld::Container* pPage, , m_xColorChangeBtn((new ColorListBox(m_xBuilder->weld_menu_button(u"colorsdropdownbtn"_ustr), [this] { return GetFrameWeld(); }))) , m_xShowInDocumentChkBtn(m_xBuilder->weld_check_button(u"showindocumentchkbtn"_ustr)) + , m_xResetAllBtn(m_xBuilder->weld_button(u"resetallbtn"_ustr)) , m_xColorRadioBtn(m_xBuilder->weld_radio_button(u"colorradiobtn"_ustr)) , m_xImageRadioBtn(m_xBuilder->weld_radio_button(u"imageradiobtn"_ustr)) , m_xStretchedRadioBtn(m_xBuilder->weld_radio_button(u"stretchedradiobtn"_ustr)) @@ -113,15 +114,6 @@ SvxAppearanceTabPage::SvxAppearanceTabPage(weld::Container* pPage, InitThemes(); InitAppearance(); InitCustomization(); - UpdateControlsState(); -} - -void SvxAppearanceTabPage::UpdateControlsState() -{ - // in case of AUTOMATIC_COLOR_SCHEME, disable all the controls - bool bEnableControls = m_xSchemeList->get_active_id() != AUTOMATIC_COLOR_SCHEME; - m_xShowInDocumentChkBtn->set_sensitive(bEnableControls); - EnableImageControls(bEnableControls && GetActiveEntry() == static_cast<int>(APPBACKGROUND)); } void SvxAppearanceTabPage::LoadSchemeList() @@ -173,29 +165,19 @@ OUString SvxAppearanceTabPage::GetAllStrings() bool SvxAppearanceTabPage::FillItemSet(SfxItemSet* /* rSet */) { - // commit appearance value + // commit appearance value if changed if (eCurrentAppearanceMode != static_cast<Appearance>(MiscSettings::GetAppColorMode())) { MiscSettings::SetAppColorMode(static_cast<int>(eCurrentAppearanceMode)); - m_bRestartRequired = true; - // for automatic scheme, restart is not required as customizations section is disabled - if (pColorConfig->GetCurrentSchemeName() == AUTOMATIC_COLOR_SCHEME) - UpdateOldAppearance(); + // if themes disabled then change the document colors as per the new appearance mode. + if (ThemeColors::IsThemeDisabled()) + UpdateDocumentAppearance(); } // commit ColorConfig if (pColorConfig->IsModified()) pColorConfig->Commit(); - // commit LibreOfficeTheme, enable it if the current scheme is not Automatic - if (m_xSchemeList->get_value_changed_from_saved()) - { - ThemeState eLibreOfficeThemeState = m_xSchemeList->get_active_id() != AUTOMATIC_COLOR_SCHEME - ? ThemeState::ENABLED - : ThemeState::DISABLED; - ThemeColors::SetThemeState(eLibreOfficeThemeState); - } - return true; } @@ -244,6 +226,12 @@ IMPL_LINK_NOARG(SvxAppearanceTabPage, AppearanceChangeHdl, weld::Toggleable&, vo eCurrentAppearanceMode = Appearance::DARK; // set the extension theme on light/dark + // restart iff appearance was toggled and theme was enabled + m_bRestartRequired = false; + if (eCurrentAppearanceMode != static_cast<Appearance>(MiscSettings::GetAppColorMode()) + && !ThemeColors::IsThemeDisabled()) + m_bRestartRequired = true; + UpdateColorDropdown(); } @@ -331,10 +319,9 @@ IMPL_LINK_NOARG(SvxAppearanceTabPage, SchemeChangeHdl, weld::ComboBox&, void) else pColorConfig->LoadScheme(m_xSchemeList->get_active_text()); - if (m_xSchemeList->get_value_changed_from_saved()) + if (m_xSchemeList->get_value_changed_from_saved() && !ThemeColors::IsThemeDisabled()) m_bRestartRequired = true; - UpdateControlsState(); UpdateRemoveBtnState(); } @@ -448,6 +435,28 @@ IMPL_LINK_NOARG(SvxAppearanceTabPage, BitmapChangeHdl, weld::ComboBox&, void) m_bRestartRequired = true; } +IMPL_LINK_NOARG(SvxAppearanceTabPage, ResetAllBtnHdl, weld::Button&, void) +{ + // load default document colors + ColorConfigValue aValue; + for (size_t i = 0; i < ColorConfigEntryCount; ++i) + { + aValue.nDarkColor = COL_AUTO; + aValue.nLightColor = COL_AUTO; + pColorConfig->SetColorValue(static_cast<ColorConfigEntry>(i), aValue); + } + pColorConfig->Commit(); + + // RESET state for themes just prevents the theme colors from being used before + // they are realoaded from the StyleSettings, please read the comment above + // ColorConfig::SetupTheme()'s definition + if (!ThemeColors::IsThemeDisabled()) + { + ThemeColors::ResetTheme(); + m_bRestartRequired = true; + } +} + void SvxAppearanceTabPage::InitThemes() { // init schemes combobox @@ -491,6 +500,7 @@ void SvxAppearanceTabPage::InitCustomization() m_xColorChangeBtn->SetSelectHdl(LINK(this, SvxAppearanceTabPage, ColorValueChgHdl)); m_xShowInDocumentChkBtn->connect_toggled(LINK(this, SvxAppearanceTabPage, ShowInDocumentHdl)); m_xBitmapDropDownBtn->connect_changed(LINK(this, SvxAppearanceTabPage, BitmapChangeHdl)); + m_xResetAllBtn->connect_clicked(LINK(this, SvxAppearanceTabPage, ResetAllBtnHdl)); m_xColorRadioBtn->connect_toggled(LINK(this, SvxAppearanceTabPage, ColorImageToggleHdl)); m_xStretchedRadioBtn->connect_toggled( @@ -550,11 +560,8 @@ void SvxAppearanceTabPage::UpdateColorDropdown() // if the user changes appearance options for automatic theme, then follow the old behaviour // and change the document colors to light/dark based on the choice. -void SvxAppearanceTabPage::UpdateOldAppearance() +void SvxAppearanceTabPage::UpdateDocumentAppearance() { - if (pColorConfig->GetCurrentSchemeName() != AUTOMATIC_COLOR_SCHEME) - return; - ColorConfigValue aValue; bool bIsDarkModeEnabled = IsDarkModeEnabled(); for (size_t i = 0; i < WINDOWCOLOR; ++i) @@ -709,9 +716,11 @@ void SvxAppearanceTabPage::FillItemsList() aRegistryEntries.at(static_cast<ColorConfigEntry>(i))); m_xColorEntryBtn->append_separator("SeparatorID"); - for (size_t i = WINDOWCOLOR; i <= INACTIVEBORDERCOLOR; ++i) - m_xColorEntryBtn->append(OUString(cNames[i].cName), - aRegistryEntries.at(static_cast<ColorConfigEntry>(i))); + // don't show UI customization options if theme is disabled + if (!ThemeColors::IsThemeDisabled()) + for (size_t i = WINDOWCOLOR; i <= INACTIVEBORDERCOLOR; ++i) + m_xColorEntryBtn->append(OUString(cNames[i].cName), + aRegistryEntries.at(static_cast<ColorConfigEntry>(i))); } size_t SvxAppearanceTabPage::GetActiveEntry() diff --git a/cui/source/options/appearance.hxx b/cui/source/options/appearance.hxx index 418e5410034d..9225fb2cdea0 100644 --- a/cui/source/options/appearance.hxx +++ b/cui/source/options/appearance.hxx @@ -54,6 +54,7 @@ private: std::unique_ptr<weld::ComboBox> m_xColorEntryBtn; std::unique_ptr<ColorListBox> m_xColorChangeBtn; std::unique_ptr<weld::CheckButton> m_xShowInDocumentChkBtn; + std::unique_ptr<weld::Button> m_xResetAllBtn; std::unique_ptr<weld::RadioButton> m_xColorRadioBtn; std::unique_ptr<weld::RadioButton> m_xImageRadioBtn; @@ -74,6 +75,7 @@ private: DECL_LINK(ColorImageToggleHdl, weld::Toggleable&, void); DECL_LINK(StretchedTiledToggleHdl, weld::Toggleable&, void); DECL_LINK(BitmapChangeHdl, weld::ComboBox&, void); + DECL_LINK(ResetAllBtnHdl, weld::Button&, void); void InitThemes(); void InitAppearance(); @@ -84,7 +86,7 @@ private: void UpdateRemoveBtnState(); void EnableImageControls(bool bEnabled); void UpdateColorDropdown(); - void UpdateOldAppearance(); + void UpdateDocumentAppearance(); bool IsDarkModeEnabled(); void FillItemsList(); size_t GetActiveEntry(); diff --git a/cui/uiconfig/ui/appearance.ui b/cui/uiconfig/ui/appearance.ui index abad57bb20fe..9a0a464c8c40 100644 --- a/cui/uiconfig/ui/appearance.ui +++ b/cui/uiconfig/ui/appearance.ui @@ -257,7 +257,7 @@ <property name="orientation">vertical</property> <property name="spacing">3</property> <child> - <!-- n-columns=2 n-rows=4 --> + <!-- n-columns=2 n-rows=5 --> <object class="GtkGrid"> <property name="visible">True</property> <property name="can-focus">False</property> @@ -426,6 +426,21 @@ <property name="top-attach">3</property> </packing> </child> + <child> + <object class="GtkButton" id="resetallbtn"> + <property name="label" translatable="yes" context="appearancetabpage|resetallbtn">Reset All</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">4</property> + </packing> + </child> + <child> + <placeholder/> + </child> <child> <placeholder/> </child> diff --git a/include/vcl/settings.hxx b/include/vcl/settings.hxx index 4c4f77e31c50..c605531cf9e4 100644 --- a/include/vcl/settings.hxx +++ b/include/vcl/settings.hxx @@ -230,6 +230,9 @@ public: SAL_DLLPRIVATE void Set3DColors( const Color& rColor ); + void SetSystemColorsLoaded( bool bLoaded ); + bool GetSystemColorsLoaded() const; + void SetFaceColor( const Color& rColor ); const Color& GetFaceColor() const; @@ -254,7 +257,7 @@ public: const Color& GetDarkShadowColor() const; void SetDefaultButtonTextColor( const Color& rColor ); - SAL_DLLPRIVATE const Color& GetDefaultButtonTextColor() const; + const Color& GetDefaultButtonTextColor() const; void SetButtonTextColor( const Color& rColor ); const Color& GetButtonTextColor() const; @@ -386,7 +389,7 @@ public: const Color& GetMenuBarColor() const; void SetMenuBarRolloverColor( const Color& rColor ); - SAL_DLLPRIVATE const Color& GetMenuBarRolloverColor() const; + const Color& GetMenuBarRolloverColor() const; void SetMenuBorderColor( const Color& rColor ); const Color& GetMenuBorderColor() const; @@ -398,7 +401,7 @@ public: const Color& GetMenuBarTextColor() const; void SetMenuBarRolloverTextColor( const Color& rColor ); - SAL_DLLPRIVATE const Color& GetMenuBarRolloverTextColor() const; + const Color& GetMenuBarRolloverTextColor() const; void SetMenuBarHighlightTextColor( const Color& rColor ); const Color& GetMenuBarHighlightTextColor() const; diff --git a/include/vcl/themecolors.hxx b/include/vcl/themecolors.hxx index 3e23368bd351..80bc1308565d 100644 --- a/include/vcl/themecolors.hxx +++ b/include/vcl/themecolors.hxx @@ -18,6 +18,7 @@ enum class ThemeState { DISABLED = 0, ENABLED = 1, + RESET = 2, }; class VCL_DLLPUBLIC ThemeColors @@ -42,13 +43,13 @@ public: static bool IsThemeDisabled() { return GetThemeState() == ThemeState::DISABLED; }; static bool IsThemeEnabled() { return GetThemeState() == ThemeState::ENABLED; }; + static bool IsThemeReset() { return GetThemeState() == ThemeState::RESET; } + static void ResetTheme() { SetThemeState(ThemeState::RESET); } // !IsThemeCached means that the ThemeColors object doesn't have the colors from the registry yet. - static bool VclPluginCanUseThemeColors() - { - return IsThemeCached() - && !ThemeColors::IsAutomaticTheme(ThemeColors::GetThemeColors().GetThemeName()); - }; + // IsThemeReset means that the user pressed the Reset All button and the UI colors in the registry + // are not valid anymore => read from the system again + static bool VclPluginCanUseThemeColors() { return IsThemeCached() && !IsThemeReset(); }; void SetWindowColor(const Color& rColor) { m_aWindowColor = rColor; } void SetWindowTextColor(const Color& rColor) { m_aWindowTextColor = rColor; } diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs b/officecfg/registry/schema/org/openoffice/Office/Common.xcs index 41fcf02e20b3..777c59a6ce5a 100644 --- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs +++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs @@ -5193,8 +5193,13 @@ <desc>Enabled</desc> </info> </enumeration> + <enumeration oor:value="2"> + <info> + <desc>Reset</desc> + </info> + </enumeration> </constraints> - <value>0</value> + <value>1</value> </prop> <prop oor:name="ApplicationAppearance" oor:type="xs:short" oor:nillable="false"> <info> diff --git a/svtools/source/config/colorcfg.cxx b/svtools/source/config/colorcfg.cxx index 7df881439615..c49a33f65426 100644 --- a/svtools/source/config/colorcfg.cxx +++ b/svtools/source/config/colorcfg.cxx @@ -431,7 +431,9 @@ IMPL_LINK( ColorConfig_Impl, DataChangedEventListener, VclSimpleEvent&, rEvent, } } -// Loads the ThemeColors (ExpertConfig Colors) into static ThemeColors::maThemeColors +// caches registry colors into the static ThemeColors::m_aThemeColors object. if the color +// value is set to COL_AUTO, the ColorConfig::GetColorValue function calls ColorConfig::GetDefaultColor() +// which returns some hard coded colors for the document, and StyleSettings colors for the UI (lcl_GetDefaultUIColor). void ColorConfig::LoadThemeColorsFromRegistry() { ThemeColors& rThemeColors = ThemeColors::GetThemeColors(); @@ -480,13 +482,25 @@ void ColorConfig::LoadThemeColorsFromRegistry() void ColorConfig::SetupTheme() { - if (ThemeColors::IsThemeDisabled() - || ThemeColors::IsAutomaticTheme(GetCurrentSchemeName())) + if (ThemeColors::IsThemeDisabled()) { ThemeColors::SetThemeCached(false); return; } + // When the theme is set to RESET, the IsThemeReset conditional doesn't let the theme to be loaded + // as explained above, and returns if the StyleSettings doesn't have system colors loaded. IsThemeReset + // is also used in VclPluginCanUseThemeColors where it prevents the VCL_PLUGINs from using theme colors. + if (ThemeColors::IsThemeReset()) + { + if (!Application::GetSettings().GetStyleSettings().GetSystemColorsLoaded()) + return; + ThemeColors::SetThemeState(ThemeState::ENABLED); + } + + // When the application is started for the first time, themes is set to ENABLED. + // that would skip the first two checks for IsThemeDisabled and IsThemeReset in the + // ColorConfig::SetupTheme function and call LoadThemeColorsFromRegistry(); if (!ThemeColors::IsThemeCached()) { // registry to ColorConfig::m_pImpl diff --git a/vcl/osx/salframe.cxx b/vcl/osx/salframe.cxx index b01dece4582d..5744ce563d40 100644 --- a/vcl/osx/salframe.cxx +++ b/vcl/osx/salframe.cxx @@ -1742,6 +1742,7 @@ SAL_WNODEPRECATED_DECLARATIONS_POP if (ThemeColors::VclPluginCanUseThemeColors()) lcl_LoadColorsFromTheme(aStyleSettings); + aStyleSettings.SetSystemColorsLoaded(true); rSettings.SetStyleSettings( aStyleSettings ); diff --git a/vcl/qt5/QtFrame.cxx b/vcl/qt5/QtFrame.cxx index cd9f705044e4..417c9b1bf75d 100644 --- a/vcl/qt5/QtFrame.cxx +++ b/vcl/qt5/QtFrame.cxx @@ -1229,6 +1229,7 @@ void QtFrame::UpdateSettings(AllSettings& rSettings) // Cursor blink interval int nFlashTime = QApplication::cursorFlashTime(); style.SetCursorBlinkTime(nFlashTime != 0 ? nFlashTime / 2 : STYLE_CURSOR_NOBLINKTIME); + style.SetSystemColorsLoaded(true); rSettings.SetStyleSettings(style); } diff --git a/vcl/source/app/settings.cxx b/vcl/source/app/settings.cxx index cdd83f275bc5..e8959c4d57f5 100644 --- a/vcl/source/app/settings.cxx +++ b/vcl/source/app/settings.cxx @@ -233,6 +233,7 @@ struct ImplStyleData bool mbSkipDisabledInMenus : 1; bool mbHideDisabledMenuItems : 1; bool mbPreferredContextMenuShortcuts : 1; + bool mbSystemColorsLoaded : 1; //mbPrimaryButtonWarpsSlider == true for "jump to here" behavior for primary button, otherwise //primary means scroll by single page. Secondary button takes the alternative behaviour bool mbPrimaryButtonWarpsSlider : 1; @@ -589,6 +590,7 @@ void ImplStyleData::SetStandardStyles() mbSkipDisabledInMenus = false; mbHideDisabledMenuItems = false; mbPreferredContextMenuShortcuts = true; + mbSystemColorsLoaded = false; mbPrimaryButtonWarpsSlider = false; } @@ -603,6 +605,18 @@ StyleSettings::SetFaceColor( const Color& rColor ) mxData->maColors.maFaceColor = rColor; } +void +StyleSettings::SetSystemColorsLoaded( bool bLoaded ) +{ + mxData->mbSystemColorsLoaded = bLoaded; +} + +bool +StyleSettings::GetSystemColorsLoaded() const +{ + return mxData->mbSystemColorsLoaded; +} + const Color& StyleSettings::GetFaceColor() const { @@ -2233,6 +2247,7 @@ bool ImplStyleData::operator==(const ImplStyleData& rSet) const (mbSkipDisabledInMenus == rSet.mbSkipDisabledInMenus) && (mbHideDisabledMenuItems == rSet.mbHideDisabledMenuItems) && (mbPreferredContextMenuShortcuts == rSet.mbPreferredContextMenuShortcuts) && + (mbSystemColorsLoaded == rSet.mbSystemColorsLoaded) && (meContextMenuShortcuts == rSet.meContextMenuShortcuts) && (mbPrimaryButtonWarpsSlider == rSet.mbPrimaryButtonWarpsSlider) && (mnEdgeBlending == rSet.mnEdgeBlending) && diff --git a/vcl/unx/gtk3/salnativewidgets-gtk.cxx b/vcl/unx/gtk3/salnativewidgets-gtk.cxx index c3bbda65728f..e88d823781aa 100644 --- a/vcl/unx/gtk3/salnativewidgets-gtk.cxx +++ b/vcl/unx/gtk3/salnativewidgets-gtk.cxx @@ -2705,6 +2705,7 @@ bool GtkSalGraphics::updateSettings(AllSettings& rSettings) // High contrast aStyleSet.SetHighContrastMode(g_strcmp0(pThemeName, "HighContrast") == 0); g_free(pThemeName); + aStyleSet.SetSystemColorsLoaded(true); // finally update the collected settings rSettings.SetStyleSettings( aStyleSet ); diff --git a/vcl/win/window/salframe.cxx b/vcl/win/window/salframe.cxx index d7a137f7a65a..26b8780d96b2 100644 --- a/vcl/win/window/salframe.cxx +++ b/vcl/win/window/salframe.cxx @@ -3018,6 +3018,7 @@ void WinSalFrame::UpdateSettings( AllSettings& rSettings ) aStyleSettings.SetMenuColor(aStyleSettings.GetWindowColor()); if (ThemeColors::VclPluginCanUseThemeColors()) lcl_LoadColorsFromTheme(aStyleSettings); + aStyleSettings.SetSystemColorsLoaded(true); rSettings.SetMouseSettings( aMouseSettings ); rSettings.SetStyleSettings( aStyleSettings );
