include/sfx2/namedcolor.hxx | 57 +++++++++++++++++++++++++++++++++ include/sfx2/objsh.hxx | 4 ++ include/svx/Palette.hxx | 50 ---------------------------- include/svx/PaletteManager.hxx | 1 include/svx/colorwindow.hxx | 3 - include/svx/tbcontrl.hxx | 1 sfx2/Library_sfx.mk | 1 sfx2/source/doc/objcont.cxx | 15 ++++++++ sfx2/source/inc/objshimp.hxx | 4 ++ svx/inc/tbxcolorupdate.hxx | 8 +++- svx/source/tbxctrls/PaletteManager.cxx | 9 ++++- svx/source/tbxctrls/tbcontrl.cxx | 15 +------- svx/source/tbxctrls/tbxcolorupdate.cxx | 57 +++++++++++++++++++++++++++------ 13 files changed, 145 insertions(+), 80 deletions(-)
New commits: commit 1345619e0b3c2825c2ae50ada2c209d4ad8461ad Author: Maxim Monastirsky <momonas...@gmail.com> AuthorDate: Sun Jul 2 17:31:38 2023 +0300 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Wed Sep 6 09:37:18 2023 +0200 tdf#154270 Sync toolbar button recent colors As the last used color is stored per button instance, these will go out of sync with several buttons being visible (e.g. a toolbar and a sidebar, or a toolbar overflow popup), and will reset whenever the toolbar resets (e.g. change in selection, switch from print preview, or customization). Fix that by storing the last colors per-document, and notifying other buttons on changes. Keep the last color also stored per-button for now, as a fallback for reportdesign (which isn't sfx2 based). Change-Id: I866f1de5c8ff6f56c47dc4b6b5acf52957d4e6c5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153943 Tested-by: Jenkins Reviewed-by: Maxim Monastirsky <momonas...@gmail.com> Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156519 diff --git a/include/sfx2/namedcolor.hxx b/include/sfx2/namedcolor.hxx new file mode 100644 index 000000000000..fc7941686fbd --- /dev/null +++ b/include/sfx2/namedcolor.hxx @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <sal/config.h> +#include <sfx2/dllapi.h> + +#include <docmodel/color/ComplexColor.hxx> +#include <docmodel/theme/ThemeColorType.hxx> + +struct SFX2_DLLPUBLIC NamedColor +{ + Color m_aColor; + OUString m_aName; + sal_Int16 m_nThemeIndex = -1; + sal_Int16 m_nLumMod = 10000; + sal_Int16 m_nLumOff = 0; + + NamedColor() = default; + + NamedColor(Color const& rColor, OUString const& rName) + : m_aColor(rColor) + , m_aName(rName) + { + } + + model::ComplexColor getComplexColor() + { + model::ComplexColor aComplexColor; + + auto eThemeColorType = model::convertToThemeColorType(m_nThemeIndex); + + if (eThemeColorType != model::ThemeColorType::Unknown) + { + aComplexColor.setSchemeColor(eThemeColorType); + + if (m_nLumMod != 10000) + aComplexColor.addTransformation({ model::TransformationType::LumMod, m_nLumMod }); + + if (m_nLumMod != 0) + aComplexColor.addTransformation({ model::TransformationType::LumOff, m_nLumOff }); + } + + aComplexColor.setFinalColor(m_aColor); + + return aComplexColor; + } +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx index b29fb43d77e4..9b7db5347597 100644 --- a/include/sfx2/objsh.hxx +++ b/include/sfx2/objsh.hxx @@ -47,6 +47,7 @@ namespace weld {class Button; } namespace model {class ColorSet; } +struct NamedColor; class SbxValue; class SbxArray; class BasicManager; @@ -558,6 +559,9 @@ public: GetDialogContainer(); StarBASIC* GetBasic() const; + std::optional<NamedColor> GetRecentColor(sal_uInt16 nSlotId); + void SetRecentColor(sal_uInt16 nSlotId, const NamedColor& rColor); + virtual std::set<Color> GetDocColors(); virtual std::shared_ptr<model::ColorSet> GetThemeColors(); diff --git a/include/svx/Palette.hxx b/include/svx/Palette.hxx index c108a1679d98..5bf63762b75c 100644 --- a/include/svx/Palette.hxx +++ b/include/svx/Palette.hxx @@ -20,60 +20,12 @@ #pragma once #include <sal/config.h> +#include <sfx2/namedcolor.hxx> #include <functional> -#include <rtl/ustring.hxx> -#include <tools/color.hxx> -#include <svx/svxdllapi.h> - -#include <docmodel/color/ComplexColor.hxx> -#include <docmodel/theme/ThemeColorType.hxx> - class SvxColorValueSet; -struct SVXCORE_DLLPUBLIC NamedColor -{ - Color m_aColor; - OUString m_aName; - sal_Int16 m_nThemeIndex = -1; - sal_Int16 m_nLumMod = 10000; - sal_Int16 m_nLumOff = 0; - - NamedColor() = default; - - NamedColor(Color const& rColor, OUString const& rName) - : m_aColor(rColor) - , m_aName(rName) - {} - - model::ComplexColor getComplexColor() - { - model::ComplexColor aComplexColor; - - auto eThemeColorType = model::convertToThemeColorType(m_nThemeIndex); - - if (eThemeColorType != model::ThemeColorType::Unknown) - { - aComplexColor.setSchemeColor(eThemeColorType); - - if (m_nLumMod != 10000) - aComplexColor.addTransformation({model::TransformationType::LumMod, m_nLumMod}); - - if (m_nLumOff != 0) - aComplexColor.addTransformation({model::TransformationType::LumOff, m_nLumOff}); - } - else - { - aComplexColor.setColor(m_aColor); - } - - aComplexColor.setFinalColor(m_aColor); - - return aComplexColor; - } -}; - typedef std::function<void(const OUString&, const NamedColor&)> ColorSelectFunction; class Palette diff --git a/include/svx/PaletteManager.hxx b/include/svx/PaletteManager.hxx index 5a5000bc0076..f2711b2e022a 100644 --- a/include/svx/PaletteManager.hxx +++ b/include/svx/PaletteManager.hxx @@ -71,6 +71,7 @@ public: tools::Long GetColorCount() const; tools::Long GetRecentColorCount() const; void AddRecentColor(const Color& rRecentColor, const OUString& rColorName, bool bFront = true); + void SetSplitButtonColor(const NamedColor& rColor); void SetBtnUpdater(svx::ToolboxButtonColorUpdaterBase* pBtnUpdater); void PopupColorPicker(weld::Window* pParent, const OUString& aCommand, const Color& rInitialColor); diff --git a/include/svx/colorwindow.hxx b/include/svx/colorwindow.hxx index 0a2e0a5ffeb8..c0feb10f1f61 100644 --- a/include/svx/colorwindow.hxx +++ b/include/svx/colorwindow.hxx @@ -99,7 +99,6 @@ private: std::unique_ptr<weld::CustomWeld> mxRecentColorSetWin; weld::Button* mpDefaultButton; - Link<const NamedColor&, void> maSelectedLink; DECL_DLLPRIVATE_LINK(SelectHdl, ValueSet*, void); DECL_DLLPRIVATE_LINK(SelectPaletteHdl, weld::ComboBox&, void); DECL_DLLPRIVATE_LINK(AutoColorClickHdl, weld::Button&, void); @@ -128,8 +127,6 @@ public: virtual void statusChanged( const css::frame::FeatureStateEvent& rEvent ) override; - void SetSelectedHdl( const Link<const NamedColor&, void>& rLink ) { maSelectedLink = rLink; } - virtual void GrabFocus() override; }; diff --git a/include/svx/tbcontrl.hxx b/include/svx/tbcontrl.hxx index 6eafd38d87b9..11d41ee4ddde 100644 --- a/include/svx/tbcontrl.hxx +++ b/include/svx/tbcontrl.hxx @@ -210,7 +210,6 @@ class SVXCORE_DLLPUBLIC SvxColorToolBoxControl final : public cppu::ImplInherita bool m_bSplitButton; sal_uInt16 m_nSlotId; ColorSelectFunction m_aColorSelectFunction; - DECL_DLLPRIVATE_LINK(SelectedHdl, const NamedColor&, void); weld::Window* GetParentFrame() const; diff --git a/sfx2/Library_sfx.mk b/sfx2/Library_sfx.mk index 72f6bbaa9f0c..a9f503f3ad8a 100644 --- a/sfx2/Library_sfx.mk +++ b/sfx2/Library_sfx.mk @@ -53,6 +53,7 @@ $(eval $(call gb_Library_use_libraries,sfx,\ comphelper \ cppu \ cppuhelper \ + docmodel \ drawinglayercore \ drawinglayer \ fwk \ diff --git a/sfx2/source/doc/objcont.cxx b/sfx2/source/doc/objcont.cxx index d075dec517b7..fb75f3fdffc3 100644 --- a/sfx2/source/doc/objcont.cxx +++ b/sfx2/source/doc/objcont.cxx @@ -314,6 +314,21 @@ std::shared_ptr<SfxDocumentInfoDialog> SfxObjectShell::CreateDocumentInfoDialog( return std::make_shared<SfxDocumentInfoDialog>(pParent, rSet); } +std::optional<NamedColor> SfxObjectShell::GetRecentColor(sal_uInt16 nSlotId) +{ + auto it = pImpl->m_aRecentColors.find(nSlotId); + if (it != pImpl->m_aRecentColors.end()) + return it->second; + + return std::nullopt; +} + +void SfxObjectShell::SetRecentColor(sal_uInt16 nSlotId, const NamedColor& rColor) +{ + pImpl->m_aRecentColors[nSlotId] = rColor; + Broadcast(SfxHint(SfxHintId::ColorsChanged)); +} + std::set<Color> SfxObjectShell::GetDocColors() { std::set<Color> empty; diff --git a/sfx2/source/inc/objshimp.hxx b/sfx2/source/inc/objshimp.hxx index 192470e5542d..1bece81ce1c0 100644 --- a/sfx2/source/inc/objshimp.hxx +++ b/sfx2/source/inc/objshimp.hxx @@ -26,6 +26,7 @@ #include <sfx2/objsh.hxx> #include <sfx2/docmacromode.hxx> +#include <sfx2/namedcolor.hxx> #include <bitset.hxx> #include <vcl/timer.hxx> @@ -133,6 +134,9 @@ struct SfxObjectShell_Impl final : public ::sfx2::IMacroDocumentAccess /// Holds Infobars until View is fully loaded std::vector<InfobarData> m_aPendingInfobars; + // Recent colors used by toolbar buttons + std::unordered_map<sal_uInt16, NamedColor> m_aRecentColors; + SfxObjectShell_Impl( SfxObjectShell& _rDocShell ); virtual ~SfxObjectShell_Impl(); diff --git a/svx/inc/tbxcolorupdate.hxx b/svx/inc/tbxcolorupdate.hxx index 81aa1c9c12fb..075c7b28dde7 100644 --- a/svx/inc/tbxcolorupdate.hxx +++ b/svx/inc/tbxcolorupdate.hxx @@ -25,6 +25,7 @@ #include <vcl/vclptr.hxx> #include <vcl/toolbox.hxx> #include <vcl/toolboxid.hxx> +#include <svl/lstner.hxx> #include <svx/Palette.hxx> #include <com/sun/star/drawing/LineStyle.hpp> #include <com/sun/star/frame/FeatureStateEvent.hpp> @@ -48,15 +49,17 @@ namespace svx formerly known as SvxTbxButtonColorUpdater_Impl, residing in svx/source/tbxctrls/colorwindow.hxx. */ - class ToolboxButtonColorUpdaterBase + class ToolboxButtonColorUpdaterBase : public SfxListener { public: ToolboxButtonColorUpdaterBase(bool bWideButton, OUString aCommandLabel, - OUString aCommandURL, + OUString aCommandURL, sal_uInt16 nSlotId, css::uno::Reference<css::frame::XFrame> xFrame); virtual ~ToolboxButtonColorUpdaterBase(); + void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override; + void SetRecentColor(const NamedColor& rNamedColor); void Update( const NamedColor& rNamedColor ); void Update( const Color& rColor, bool bForceUpdate = false ); Color const & GetCurrentColor() const { return maCurColor; } @@ -69,6 +72,7 @@ namespace svx protected: bool mbWideButton; bool mbWasHiContrastMode; + sal_uInt16 mnSlotId; Color maCurColor; tools::Rectangle maUpdRect; Size maBmpSize; diff --git a/svx/source/tbxctrls/PaletteManager.cxx b/svx/source/tbxctrls/PaletteManager.cxx index 343448c8e788..1a48c403feb2 100644 --- a/svx/source/tbxctrls/PaletteManager.cxx +++ b/svx/source/tbxctrls/PaletteManager.cxx @@ -382,6 +382,12 @@ void PaletteManager::AddRecentColor(const Color& rRecentColor, const OUString& r batch->commit(); } +void PaletteManager::SetSplitButtonColor(const NamedColor& rColor) +{ + if (mpBtnUpdater) + mpBtnUpdater->SetRecentColor(rColor); +} + void PaletteManager::SetBtnUpdater(svx::ToolboxButtonColorUpdaterBase* pBtnUpdater) { mpBtnUpdater = pBtnUpdater; @@ -405,8 +411,7 @@ void PaletteManager::PopupColorPicker(weld::Window* pParent, const OUString& aCo Color aLastColor = m_pColorDlg->GetColor(); OUString sColorName = "#" + aLastColor.AsRGBHexString().toAsciiUpperCase(); NamedColor aNamedColor(aLastColor, sColorName); - if (mpBtnUpdater) - mpBtnUpdater->Update(aNamedColor); + SetSplitButtonColor(aNamedColor); AddRecentColor(aLastColor, sColorName); maColorSelectFunction(aCommandCopy, aNamedColor); } diff --git a/svx/source/tbxctrls/tbcontrl.cxx b/svx/source/tbxctrls/tbcontrl.cxx index eb7ab2e61410..06cefd08062a 100644 --- a/svx/source/tbxctrls/tbcontrl.cxx +++ b/svx/source/tbxctrls/tbcontrl.cxx @@ -2226,7 +2226,7 @@ IMPL_LINK(ColorWindow, SelectHdl, ValueSet*, pColorSet, void) mxPaletteManager->ReloadRecentColorSet(*mxRecentColorSet); } - maSelectedLink.Call(aNamedColor); + mxPaletteManager->SetSplitButtonColor(aNamedColor); // deliberate take a copy here in case maMenuButton.set_inactive // triggers a callback that destroys ourself @@ -2272,7 +2272,7 @@ IMPL_LINK(ColorWindow, AutoColorClickHdl, weld::Button&, rButton, void) mxRecentColorSet->SetNoSelection(); mpDefaultButton = &rButton; - maSelectedLink.Call(aNamedColor); + mxPaletteManager->SetSplitButtonColor(aNamedColor); // deliberate take a copy here in case maMenuButton.set_inactive // triggers a callback that destroys ourself @@ -3636,9 +3636,6 @@ std::unique_ptr<WeldToolbarPopup> SvxColorToolBoxControl::weldPopupWindow() [this] { return GetParentFrame(); }, m_aColorSelectFunction); - if ( m_bSplitButton ) - xPopover->SetSelectedHdl( LINK( this, SvxColorToolBoxControl, SelectedHdl ) ); - return xPopover; } @@ -3661,9 +3658,6 @@ VclPtr<vcl::Window> SvxColorToolBoxControl::createVclPopupWindow( vcl::Window* p [this] { return GetParentFrame(); }, m_aColorSelectFunction); - if ( m_bSplitButton ) - xPopover->SetSelectedHdl( LINK( this, SvxColorToolBoxControl, SelectedHdl ) ); - mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent, std::move(xPopover), true); @@ -3676,11 +3670,6 @@ VclPtr<vcl::Window> SvxColorToolBoxControl::createVclPopupWindow( vcl::Window* p return mxInterimPopover; } -IMPL_LINK(SvxColorToolBoxControl, SelectedHdl, const NamedColor&, rColor, void) -{ - m_xBtnUpdater->Update(rColor); -} - void SvxColorToolBoxControl::statusChanged( const css::frame::FeatureStateEvent& rEvent ) { ToolBox* pToolBox = nullptr; diff --git a/svx/source/tbxctrls/tbxcolorupdate.cxx b/svx/source/tbxctrls/tbxcolorupdate.cxx index 7a27b5a12f8e..edd835736268 100644 --- a/svx/source/tbxctrls/tbxcolorupdate.cxx +++ b/svx/source/tbxctrls/tbxcolorupdate.cxx @@ -17,6 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <sfx2/sfxbasemodel.hxx> #include <sfx2/objsh.hxx> #include <svx/drawitem.hxx> #include <tbxcolorupdate.hxx> @@ -40,10 +41,11 @@ namespace svx { ToolboxButtonColorUpdaterBase::ToolboxButtonColorUpdaterBase(bool bWideButton, OUString aCommandLabel, - OUString aCommandURL, + OUString aCommandURL, sal_uInt16 nSlotId, css::uno::Reference<css::frame::XFrame> xFrame) : mbWideButton(bWideButton) , mbWasHiContrastMode(Application::GetSettings().GetStyleSettings().GetHighContrastMode()) + , mnSlotId(nSlotId) , maCurColor(COL_TRANSPARENT) , meImageType(vcl::ImageType::Size16) , maCommandLabel(std::move(aCommandLabel)) @@ -54,6 +56,23 @@ namespace svx void ToolboxButtonColorUpdaterBase::Init(sal_uInt16 nSlotId) { + if (mbWideButton) + { + Update(COL_TRANSPARENT, true); + return; + } + + if (rtl::Reference xModel = dynamic_cast<SfxBaseModel*>(mxFrame->getController()->getModel().get())) + { + auto pDocSh = xModel->GetObjectShell(); + StartListening(*pDocSh); + if (auto oColor = pDocSh->GetRecentColor(nSlotId)) + { + Update(*oColor); + return; + } + } + switch (nSlotId) { case SID_ATTR_CHAR_COLOR: @@ -80,11 +99,32 @@ namespace svx } } + void ToolboxButtonColorUpdaterBase::Notify(SfxBroadcaster& rBC, const SfxHint& rHint) + { + if (rHint.GetId() == SfxHintId::Dying) + { + EndListeningAll(); + } + else if (rHint.GetId() == SfxHintId::ColorsChanged) + { + if (auto oColor = static_cast<SfxObjectShell&>(rBC).GetRecentColor(mnSlotId)) + Update(*oColor); + } + } + + void ToolboxButtonColorUpdaterBase::SetRecentColor(const NamedColor &rNamedColor) + { + if (rtl::Reference xModel = dynamic_cast<SfxBaseModel*>(mxFrame->getController()->getModel().get())) + xModel->GetObjectShell()->SetRecentColor(mnSlotId, rNamedColor); + else if (!mbWideButton) + Update(rNamedColor); + } + VclToolboxButtonColorUpdater::VclToolboxButtonColorUpdater( sal_uInt16 nSlotId, ToolBoxItemId nTbxBtnId, ToolBox* pToolBox, bool bWideButton, const OUString& rCommandLabel, const OUString& rCommandURL, const css::uno::Reference<css::frame::XFrame>& rFrame) - : ToolboxButtonColorUpdaterBase(bWideButton, rCommandLabel, rCommandURL, rFrame) + : ToolboxButtonColorUpdaterBase(bWideButton, rCommandLabel, rCommandURL, nSlotId, rFrame) , mnBtnId(nTbxBtnId) , mpTbx(pToolBox) { @@ -138,14 +178,11 @@ namespace svx void ToolboxButtonColorUpdaterBase::Update(const NamedColor &rNamedColor) { Update(rNamedColor.m_aColor); - if (!mbWideButton) - { - // Also show the current color as QuickHelpText - OUString colorSuffix = OUString(" (%1)").replaceFirst("%1", rNamedColor.m_aName); - OUString colorHelpText = maCommandLabel + colorSuffix; - SetQuickHelpText(colorHelpText); - } + // Also show the current color as QuickHelpText + OUString colorSuffix = OUString(" (%1)").replaceFirst("%1", rNamedColor.m_aName); + OUString colorHelpText = maCommandLabel + colorSuffix; + SetQuickHelpText(colorHelpText); } void ToolboxButtonColorUpdaterBase::Update(const Color& rColor, bool bForceUpdate) @@ -250,7 +287,7 @@ namespace svx ToolboxButtonColorUpdater::ToolboxButtonColorUpdater(sal_uInt16 nSlotId, const OUString& rTbxBtnId, weld::Toolbar* ptrTbx, bool bWideButton, const OUString& rCommandLabel, const css::uno::Reference<css::frame::XFrame>& rFrame) - : ToolboxButtonColorUpdaterBase(bWideButton, rCommandLabel, rTbxBtnId, rFrame) + : ToolboxButtonColorUpdaterBase(bWideButton, rCommandLabel, rTbxBtnId, nSlotId, rFrame) , msBtnId(rTbxBtnId) , mpTbx(ptrTbx) {