include/svx/dialog/ThemeColorsPaneBase.hxx                           |   54 +++
 include/svx/dialog/ThemeDialog.hxx                                   |   18 -
 officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu      |   11 
 officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu |    8 
 sd/Library_sd.mk                                                     |    1 
 sd/source/ui/controller/ThemeColorsToolBoxControl.cxx                |  149 
++++++++++
 sd/source/ui/controller/ThemeColorsToolBoxControl.hxx                |   68 
++++
 sd/uiconfig/simpress/ui/notebookbar_online.ui                        |   24 +
 sd/util/sd.component                                                 |    4 
 solenv/sanitizers/ui/modules/simpress.suppr                          |    1 
 svx/Library_svx.mk                                                   |    1 
 svx/UIConfig_svx.mk                                                  |    1 
 svx/source/dialog/ThemeColorsPaneBase.cxx                            |  131 
++++++++
 svx/source/dialog/ThemeDialog.cxx                                    |   96 
------
 svx/uiconfig/ui/themeselectorpanel.ui                                |   49 +++
 vcl/jsdialog/enabled.cxx                                             |    1 
 vcl/workben/cgmfuzzer.cxx                                            |    2 
 17 files changed, 515 insertions(+), 104 deletions(-)

New commits:
commit 8339c14edc68806cd4acb17c3d9bbcc8810c12b0
Author:     Samuel Mehrbrodt <[email protected]>
AuthorDate: Fri Sep 12 13:10:11 2025 +0300
Commit:     Samuel Mehrbrodt <[email protected]>
CommitDate: Mon Jan 26 14:24:04 2026 +0100

    Add a Notebookbar widget for theme colors
    
    Co-authored-by: Banobe Pascal <[email protected]>
    Change-Id: I1becca9852745b9972d270e280f386d1803d2731
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190867
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Szymon Kłos <[email protected]>
    Reviewed-by: Samuel Mehrbrodt <[email protected]>

diff --git a/include/svx/dialog/ThemeColorsPaneBase.hxx 
b/include/svx/dialog/ThemeColorsPaneBase.hxx
new file mode 100644
index 000000000000..22fe401279c0
--- /dev/null
+++ b/include/svx/dialog/ThemeColorsPaneBase.hxx
@@ -0,0 +1,54 @@
+/* -*- 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 <svx/svxdllapi.h>
+#include <vcl/weld.hxx>
+#include <vcl/vclptr.hxx>
+#include <docmodel/theme/ColorSet.hxx>
+#include <memory>
+#include <vector>
+
+namespace model
+{
+class Theme;
+}
+class VirtualDevice;
+
+namespace svx
+{
+/// Base class for theme color selection functionality
+class SVX_DLLPUBLIC ThemeColorsPaneBase
+{
+protected:
+    std::unique_ptr<weld::IconView> mxIconViewThemeColors;
+    std::vector<model::ColorSet> maColorSets;
+    std::shared_ptr<model::ColorSet> mpCurrentColorSet;
+
+    void initColorSets(model::Theme* pTheme = nullptr);
+    static VclPtr<VirtualDevice> CreateColorSetPreview(const model::ColorSet& 
rColorSet);
+
+public:
+    explicit ThemeColorsPaneBase(std::unique_ptr<weld::IconView> xIconView);
+    virtual ~ThemeColorsPaneBase();
+
+    DECL_LINK(SelectionChangedHdl, weld::IconView&, void);
+    DECL_LINK(ItemActivatedHdl, weld::IconView&, bool);
+
+    std::shared_ptr<model::ColorSet> const& getCurrentColorSet() { return 
mpCurrentColorSet; }
+
+protected:
+    /// Override this to handle theme color activation
+    virtual void onColorSetActivated() {}
+};
+
+} // end svx namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/include/svx/dialog/ThemeDialog.hxx 
b/include/svx/dialog/ThemeDialog.hxx
index b252d18183c5..5b5726f69684 100644
--- a/include/svx/dialog/ThemeDialog.hxx
+++ b/include/svx/dialog/ThemeDialog.hxx
@@ -13,7 +13,7 @@
 #include <vcl/weld.hxx>
 #include <svx/svdpage.hxx>
 #include <svx/dialog/ThemeColorEditDialog.hxx>
-
+#include <svx/dialog/ThemeColorsPaneBase.hxx>
 namespace model
 {
 class Theme;
@@ -23,32 +23,26 @@ class ColorListBox;
 
 namespace svx
 {
-class SVX_DLLPUBLIC ThemeDialog final : public weld::GenericDialogController
+class SVX_DLLPUBLIC ThemeDialog final : public weld::GenericDialogController,
+                                        public ThemeColorsPaneBase
 {
 private:
     weld::Window* mpWindow;
     model::Theme* mpTheme;
     std::shared_ptr<svx::ThemeColorEditDialog> mxSubDialog;
-    std::vector<model::ColorSet> maColorSets;
 
-    std::unique_ptr<weld::IconView> mxIconViewThemeColors;
     std::unique_ptr<weld::Button> mxAdd;
 
-    std::shared_ptr<model::ColorSet> mpCurrentColorSet;
-
     void runThemeColorEditDialog();
-    void initColorSets();
-    static VclPtr<VirtualDevice> CreateColorSetPreview(const model::ColorSet& 
rColorSet);
+
+protected:
+    void onColorSetActivated() override;
 
 public:
     ThemeDialog(weld::Window* pParent, model::Theme* pTheme);
     virtual ~ThemeDialog() override;
 
-    DECL_LINK(ItemActivatedHdl, weld::IconView&, bool);
-    DECL_LINK(SelectionChangedHdl, weld::IconView&, void);
     DECL_LINK(ButtonClicked, weld::Button&, void);
-
-    std::shared_ptr<model::ColorSet> const& getCurrentColorSet() { return 
mpCurrentColorSet; }
 };
 
 } // end svx namespace
diff --git a/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu 
b/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu
index 348202e8e3d3..af57163c882d 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/Controller.xcu
@@ -1130,6 +1130,17 @@
           <value>com.sun.star.comp.sd.SlideMasterPagesAllToolBoxControl</value>
         </prop>
       </node>
+      <node oor:name="ThemeColorsPane" oor:op="replace">
+        <prop oor:name="Command">
+          <value>.uno:ThemeSelectorPanel</value>
+        </prop>
+        <prop oor:name="Module">
+          <value>com.sun.star.presentation.PresentationDocument</value>
+        </prop>
+        <prop oor:name="Controller">
+          <value>com.sun.star.comp.sd.ThemeColorsToolBoxControl</value>
+        </prop>
+      </node>
       <node oor:name="BulletsToolBox" oor:op="replace">
         <prop oor:name="Command">
           <value>.uno:DefaultBullet</value>
diff --git 
a/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu 
b/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
index effdca00d2c2..0b3cc508a2a8 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu
@@ -3155,6 +3155,14 @@ bit 3 (0x8): #define 
UICOMMANDDESCRIPTION_PROPERTIES_TOGGLEBUTTON 8
           <value>1</value>
         </prop>
       </node>
+      <node oor:name=".uno:ThemeSelectorPanel" oor:op="replace">
+        <prop oor:name="Label" oor:type="xs:string">
+          <value xml:lang="en-US">Theme...</value>
+        </prop>
+        <prop oor:name="Properties" oor:type="xs:int">
+          <value>1</value>
+        </prop>
+      </node>
 
       <node oor:name=".uno:InsertTimeField" oor:op="replace">
         <prop oor:name="Label" oor:type="xs:string">
diff --git a/sd/Library_sd.mk b/sd/Library_sd.mk
index 012c1ad49522..4695244dea53 100644
--- a/sd/Library_sd.mk
+++ b/sd/Library_sd.mk
@@ -229,6 +229,7 @@ $(eval $(call gb_Library_add_exception_objects,sd,\
        sd/source/ui/controller/slidelayoutcontroller \
        sd/source/ui/controller/displaymodecontroller \
        sd/source/ui/controller/SlideTransitionsToolBoxControl \
+       sd/source/ui/controller/ThemeColorsToolBoxControl \
        sd/source/ui/dlg/AnimationChildWindow \
        sd/source/ui/dlg/LayerTabBar \
        sd/source/ui/dlg/NavigatorChildWindow \
diff --git a/sd/source/ui/controller/ThemeColorsToolBoxControl.cxx 
b/sd/source/ui/controller/ThemeColorsToolBoxControl.cxx
new file mode 100644
index 000000000000..e2190170a081
--- /dev/null
+++ b/sd/source/ui/controller/ThemeColorsToolBoxControl.cxx
@@ -0,0 +1,149 @@
+/* -*- 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/.
+ */
+
+#include "ThemeColorsToolBoxControl.hxx"
+#include <ViewShellBase.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <sfx2/viewsh.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <vcl/svapp.hxx>
+#include <svx/dialog/ThemeColorsPaneBase.hxx>
+#include <theme/ThemeColorChanger.hxx>
+#include <DrawDocShell.hxx>
+#include <drawview.hxx>
+#include <svx/svdpagv.hxx>
+#include <DrawViewShell.hxx>
+
+ThemeColorsToolBoxControl::ThemeColorsToolBoxControl() {}
+
+ThemeColorsToolBoxControl::~ThemeColorsToolBoxControl() {}
+
+void SAL_CALL ThemeColorsToolBoxControl::dispose()
+{
+    SolarMutexGuard aSolarMutexGuard;
+    m_xVclBox.disposeAndClear();
+    svt::ToolboxController::dispose();
+}
+
+void SAL_CALL
+ThemeColorsToolBoxControl::statusChanged(const css::frame::FeatureStateEvent& 
/*rEvent*/)
+{
+}
+
+css::uno::Reference<css::awt::XWindow>
+ThemeColorsToolBoxControl::createItemWindow(const 
css::uno::Reference<css::awt::XWindow>& rParent)
+{
+    css::uno::Reference<css::awt::XWindow> xItemWindow;
+
+    VclPtr<vcl::Window> pParent = VCLUnoHelper::GetWindow(rParent);
+    if (pParent)
+    {
+        SolarMutexGuard aSolarMutexGuard;
+
+        sd::ViewShellBase* pViewShellBase = nullptr;
+        if (SfxViewShell* pViewShell = SfxViewShell::Current())
+        {
+            pViewShellBase = dynamic_cast<sd::ViewShellBase*>(pViewShell);
+        }
+
+        if (pViewShellBase)
+        {
+            m_xVclBox = VclPtr<ThemeColorsPaneWrapper>::Create(pParent, 
*pViewShellBase);
+            xItemWindow = VCLUnoHelper::GetInterface(m_xVclBox.get());
+        }
+    }
+    return xItemWindow;
+}
+
+void SAL_CALL ThemeColorsToolBoxControl::update() {}
+
+OUString SAL_CALL ThemeColorsToolBoxControl::getImplementationName()
+{
+    return u"com.sun.star.comp.sd.ThemeColorsToolBoxControl"_ustr;
+}
+
+sal_Bool SAL_CALL ThemeColorsToolBoxControl::supportsService(const OUString& 
rServiceName)
+{
+    return cppu::supportsService(this, rServiceName);
+}
+
+css::uno::Sequence<OUString> SAL_CALL 
ThemeColorsToolBoxControl::getSupportedServiceNames()
+{
+    return { u"com.sun.star.frame.ToolbarController"_ustr };
+}
+
+// Export function for service registration
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+com_sun_star_comp_sd_ThemeColorsToolBoxControl_get_implementation(
+    css::uno::XComponentContext* /*rxContext*/, 
css::uno::Sequence<css::uno::Any> const&)
+{
+    return cppu::acquire(new ThemeColorsToolBoxControl());
+}
+
+ThemeColorsPaneWrapper::ThemeColorsPaneWrapper(vcl::Window* pParent, 
sd::ViewShellBase& rBase)
+    : InterimItemWindow(pParent, u"svx/ui/themeselectorpanel.ui"_ustr, 
u"ThemeSelectorPanel"_ustr,
+                        true, 
reinterpret_cast<sal_uInt64>(SfxViewShell::Current()))
+    , 
svx::ThemeColorsPaneBase(m_xBuilder->weld_icon_view(u"iconview_theme_colors"_ustr))
+    , mrViewShellBase(rBase)
+{
+    // Override selection handler to apply theme on single click
+    if (mxIconViewThemeColors)
+        mxIconViewThemeColors->connect_selection_changed(
+            LINK(this, ThemeColorsPaneWrapper, SelectionChangedHdl));
+
+    initColorSets();
+    SetOptimalSize();
+}
+
+ThemeColorsPaneWrapper::~ThemeColorsPaneWrapper() { disposeOnce(); }
+
+void ThemeColorsPaneWrapper::SetOptimalSize() { 
SetSizePixel(GetOptimalSize()); }
+
+void ThemeColorsPaneWrapper::dispose()
+{
+    mxIconViewThemeColors.reset();
+    InterimItemWindow::dispose();
+}
+
+void ThemeColorsPaneWrapper::onColorSetActivated()
+{
+    if (!mpCurrentColorSet)
+        return;
+    sd::DrawViewShell* pViewShell
+        = 
dynamic_cast<sd::DrawViewShell*>(mrViewShellBase.GetMainViewShell().get());
+    if (!pViewShell)
+        return;
+    SdrPageView* pPageView = pViewShell->GetDrawView()->GetSdrPageView();
+    if (!pPageView)
+        return;
+    SdrPage* pPage = pPageView->GetPage();
+    if (!pPage)
+        return;
+    SdrPage* pMasterPage = &pPage->TRG_GetMasterPage();
+    if (!pMasterPage)
+        return;
+    sd::DrawDocShell* pDocShell = mrViewShellBase.GetDocShell();
+    if (!pDocShell)
+        return;
+
+    // Apply the theme
+    sd::ThemeColorChanger aChanger(pMasterPage, pDocShell);
+    aChanger.apply(mpCurrentColorSet);
+}
+
+IMPL_LINK_NOARG(ThemeColorsPaneWrapper, SelectionChangedHdl, weld::IconView&, 
void)
+{
+    // Call base class selection handler first to update mpCurrentColorSet
+    svx::ThemeColorsPaneBase::SelectionChangedHdl(*mxIconViewThemeColors);
+
+    // Apply theme on single-click
+    onColorSetActivated();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/sd/source/ui/controller/ThemeColorsToolBoxControl.hxx 
b/sd/source/ui/controller/ThemeColorsToolBoxControl.hxx
new file mode 100644
index 000000000000..9e9b876da7d8
--- /dev/null
+++ b/sd/source/ui/controller/ThemeColorsToolBoxControl.hxx
@@ -0,0 +1,68 @@
+/* -*- 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/.
+ */
+
+#include <svtools/toolboxcontroller.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <vcl/vclptr.hxx>
+#include <vcl/InterimItemWindow.hxx>
+#include <svx/dialog/ThemeColorsPaneBase.hxx>
+
+namespace sd
+{
+class ViewShellBase;
+}
+
+// Used to put theme colors pane to the notebookbar
+
+class ThemeColorsPaneWrapper final : public InterimItemWindow, public 
svx::ThemeColorsPaneBase
+{
+private:
+    sd::ViewShellBase& mrViewShellBase;
+
+public:
+    ThemeColorsPaneWrapper(vcl::Window* pParent, sd::ViewShellBase& rBase);
+    virtual ~ThemeColorsPaneWrapper() override;
+    virtual void dispose() override;
+    void SetOptimalSize();
+
+    DECL_LINK(SelectionChangedHdl, weld::IconView&, void);
+
+protected:
+    void onColorSetActivated() override;
+};
+
+class ThemeColorsToolBoxControl final
+    : public cppu::ImplInheritanceHelper<svt::ToolboxController, 
css::lang::XServiceInfo>
+{
+    VclPtr<ThemeColorsPaneWrapper> m_xVclBox;
+
+public:
+    ThemeColorsToolBoxControl();
+    virtual ~ThemeColorsToolBoxControl() override;
+
+    // XStatusListener
+    virtual void SAL_CALL statusChanged(const css::frame::FeatureStateEvent& 
rEvent) override;
+
+    // XToolbarController
+    virtual css::uno::Reference<css::awt::XWindow>
+        SAL_CALL createItemWindow(const 
css::uno::Reference<css::awt::XWindow>& rParent) override;
+
+    // XComponent
+    virtual void SAL_CALL dispose() override;
+
+    // XUpdatable
+    virtual void SAL_CALL update() override;
+
+    // XServiceInfo
+    virtual OUString SAL_CALL getImplementationName() override;
+    virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) 
override;
+    virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() 
override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/sd/uiconfig/simpress/ui/notebookbar_online.ui 
b/sd/uiconfig/simpress/ui/notebookbar_online.ui
index 7cf1dc7e8448..aed825f9046d 100644
--- a/sd/uiconfig/simpress/ui/notebookbar_online.ui
+++ b/sd/uiconfig/simpress/ui/notebookbar_online.ui
@@ -121,6 +121,30 @@
             <property name="position">2</property>
           </packing>
         </child>
+        <child>
+          <object class="sfxlo-NotebookbarToolBox" id="theme_colors_pane">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="margin-start">5</property>
+            <child>
+              <object class="GtkToolButton" id="Theme-ThemeColorsPane">
+                <property name="visible">True</property>
+                <property name="can-focus">False</property>
+                <property name="action-name">.uno:ThemeSelectorPanel</property>
+                <property name="use-underline">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="homogeneous">True</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">5</property>
+          </packing>
+        </child>
       </object>
       <packing>
         <property name="left-attach">0</property>
diff --git a/sd/util/sd.component b/sd/util/sd.component
index e20b1ebbcebb..42fb776c1c3f 100644
--- a/sd/util/sd.component
+++ b/sd/util/sd.component
@@ -65,6 +65,10 @@
     
constructor="com_sun_star_comp_sd_SlideTransitionsToolBoxControl_get_implementation">
     <service name="com.sun.star.frame.ToolbarController"/>
   </implementation>
+  <implementation name="com.sun.star.comp.sd.ThemeColorsToolBoxControl"
+    
constructor="com_sun_star_comp_sd_ThemeColorsToolBoxControl_get_implementation">
+    <service name="com.sun.star.frame.ToolbarController"/>
+  </implementation>
   <implementation name="com.sun.star.comp.sd.SlideLayoutController"
       
constructor="com_sun_star_comp_sd_SlideLayoutController_get_implementation">
     <service name="com.sun.star.frame.ToolbarController"/>
diff --git a/solenv/sanitizers/ui/modules/simpress.suppr 
b/solenv/sanitizers/ui/modules/simpress.suppr
index e8b3ce3f7d93..4b14930cf99d 100644
--- a/solenv/sanitizers/ui/modules/simpress.suppr
+++ b/solenv/sanitizers/ui/modules/simpress.suppr
@@ -29,4 +29,5 @@ 
sd/uiconfig/simpress/ui/notebookbar_online.ui://GtkToolButton[@id='Home-CharFont
 
sd/uiconfig/simpress/ui/notebookbar_online.ui://GtkToolButton[@id='Home-FontHeight']
 button-no-label
 
sd/uiconfig/simpress/ui/notebookbar_online.ui://GtkToolButton[@id='MasterSlide-MasterSlidePane']
 button-no-label
 
sd/uiconfig/simpress/ui/notebookbar_online.ui://GtkToolButton[@id='Transitions-SlideTransitionsPane']
 button-no-label
+sd/uiconfig/simpress/ui/notebookbar_online.ui://GtkToolButton[@id='Theme-ThemeColorsPane']
 button-no-label
 
diff --git a/svx/Library_svx.mk b/svx/Library_svx.mk
index 0e65029f9e2d..3bb70ec04823 100644
--- a/svx/Library_svx.mk
+++ b/svx/Library_svx.mk
@@ -179,6 +179,7 @@ $(eval $(call gb_Library_add_exception_objects,svx,\
     svx/source/dialog/swframeexample \
     svx/source/dialog/swframeposstrings \
     svx/source/dialog/ThemeColorValueSet \
+    svx/source/dialog/ThemeColorsPaneBase \
     svx/source/dialog/ThemeDialog \
     svx/source/dialog/ThemeColorEditDialog \
     svx/source/dialog/txencbox \
diff --git a/svx/UIConfig_svx.mk b/svx/UIConfig_svx.mk
index fc000f936e69..d09cbb46bdcc 100644
--- a/svx/UIConfig_svx.mk
+++ b/svx/UIConfig_svx.mk
@@ -147,6 +147,7 @@ $(eval $(call gb_UIConfig_add_uifiles,svx,\
        svx/uiconfig/ui/textunderlinecontrol \
        svx/uiconfig/ui/themedialog \
        svx/uiconfig/ui/themecoloreditdialog \
+       svx/uiconfig/ui/themeselectorpanel \
        svx/uiconfig/ui/toolbarpopover \
        svx/uiconfig/ui/xmlsecstatmenu \
        svx/uiconfig/ui/xformspage \
diff --git a/svx/source/dialog/ThemeColorsPaneBase.cxx 
b/svx/source/dialog/ThemeColorsPaneBase.cxx
new file mode 100644
index 000000000000..d337e810e5e8
--- /dev/null
+++ b/svx/source/dialog/ThemeColorsPaneBase.cxx
@@ -0,0 +1,131 @@
+/* -*- 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/.
+ */
+
+#include <svx/dialog/ThemeColorsPaneBase.hxx>
+#include <docmodel/theme/ColorSet.hxx>
+#include <docmodel/theme/Theme.hxx>
+#include <svx/ColorSets.hxx>
+#include <vcl/virdev.hxx>
+#include <tools/color.hxx>
+
+namespace svx
+{
+ThemeColorsPaneBase::ThemeColorsPaneBase(std::unique_ptr<weld::IconView> 
xIconView)
+    : mxIconViewThemeColors(std::move(xIconView))
+{
+    if (mxIconViewThemeColors)
+    {
+        mxIconViewThemeColors->connect_selection_changed(
+            LINK(this, ThemeColorsPaneBase, SelectionChangedHdl));
+        mxIconViewThemeColors->connect_item_activated(
+            LINK(this, ThemeColorsPaneBase, ItemActivatedHdl));
+    }
+}
+
+ThemeColorsPaneBase::~ThemeColorsPaneBase() = default;
+
+void ThemeColorsPaneBase::initColorSets(model::Theme* pTheme)
+{
+    maColorSets.clear();
+    if (mxIconViewThemeColors)
+        mxIconViewThemeColors->clear();
+
+    if (pTheme)
+        maColorSets.push_back(*pTheme->getColorSet());
+
+    auto const& rColorSetVector = ColorSets::get().getColorSetVector();
+    maColorSets.insert(maColorSets.end(), rColorSetVector.begin(), 
rColorSetVector.end());
+
+    if (mxIconViewThemeColors)
+    {
+        for (size_t i = 0; i < maColorSets.size(); ++i)
+        {
+            auto const& rColorSet = maColorSets[i];
+            VclPtr<VirtualDevice> pVirDev = CreateColorSetPreview(rColorSet);
+
+            OUString sId = OUString::number(i);
+            OUString sName = rColorSet.getName();
+            mxIconViewThemeColors->insert(-1, &sName, &sId, pVirDev, nullptr);
+        }
+
+        if (!maColorSets.empty())
+        {
+            mxIconViewThemeColors->select(0);
+            mpCurrentColorSet = 
std::make_shared<model::ColorSet>(maColorSets[0]);
+        }
+    }
+}
+
+VclPtr<VirtualDevice> ThemeColorsPaneBase::CreateColorSetPreview(const 
model::ColorSet& rColorSet)
+{
+    VclPtr<VirtualDevice> pVDev = VclPtr<VirtualDevice>::Create();
+    const Size aSize(100, 50);
+    pVDev->SetOutputSizePixel(aSize);
+
+    const int nRows = 2;
+    const int nCols = 4;
+    const int nHorizontalPadding = 9;
+    const int nVerticalPadding = 3;
+    const int nMargin = 3;
+
+    const int nAvailableWidth = aSize.Width() - (2 * nHorizontalPadding);
+    const int nAvailableHeight = aSize.Height() - (2 * nVerticalPadding);
+    const int nColorCellHeight = (nAvailableHeight - ((nRows - 1) * nMargin)) 
/ nRows;
+    const int nColorCellWidth = (nAvailableWidth - ((nCols - 1) * nMargin)) / 
nCols;
+
+    // Draw border around entire color set
+    pVDev->SetLineColor(COL_LIGHTGRAY);
+    pVDev->DrawRect(tools::Rectangle(Point(0, 0), aSize));
+
+    for (int i = 0; i < 8; ++i)
+    {
+        const int nCol = i / 2;
+        const int nRow = i % 2;
+
+        const int nX = nHorizontalPadding + (nCol * (nColorCellWidth + 
nMargin));
+        const int nY = nVerticalPadding + (nRow * (nColorCellHeight + 
nMargin));
+
+        const tools::Rectangle aRect(Point(nX, nY), Size(nColorCellWidth, 
nColorCellHeight));
+
+        Color aColor = rColorSet.getColor(static_cast<model::ThemeColorType>(i 
+ 2));
+
+        pVDev->SetLineColor(COL_LIGHTGRAY);
+        pVDev->SetFillColor(aColor);
+        pVDev->DrawRect(aRect);
+    }
+    return pVDev;
+}
+
+IMPL_LINK_NOARG(ThemeColorsPaneBase, SelectionChangedHdl, weld::IconView&, 
void)
+{
+    if (!mxIconViewThemeColors)
+        return;
+
+    OUString sId = mxIconViewThemeColors->get_selected_id();
+    if (sId.isEmpty())
+        return;
+
+    sal_uInt32 nIndex = sId.toUInt32();
+
+    if (nIndex >= maColorSets.size())
+        return;
+
+    mpCurrentColorSet = std::make_shared<model::ColorSet>(maColorSets[nIndex]);
+}
+
+IMPL_LINK(ThemeColorsPaneBase, ItemActivatedHdl, weld::IconView&, 
/*rIconView*/, bool)
+{
+    SelectionChangedHdl(*mxIconViewThemeColors);
+    onColorSetActivated();
+    return true;
+}
+
+} // end svx namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/svx/source/dialog/ThemeDialog.cxx 
b/svx/source/dialog/ThemeDialog.cxx
index cbc4248cb371..7d3486dfbdfe 100644
--- a/svx/source/dialog/ThemeDialog.cxx
+++ b/svx/source/dialog/ThemeDialog.cxx
@@ -19,23 +19,14 @@ namespace svx
 {
 ThemeDialog::ThemeDialog(weld::Window* pParent, model::Theme* pTheme)
     : GenericDialogController(pParent, u"svx/ui/themedialog.ui"_ustr, 
u"ThemeDialog"_ustr)
+    , 
ThemeColorsPaneBase(m_xBuilder->weld_icon_view(u"iconview_theme_colors"_ustr))
     , mpWindow(pParent)
     , mpTheme(pTheme)
-    , 
mxIconViewThemeColors(m_xBuilder->weld_icon_view(u"iconview_theme_colors"_ustr))
     , mxAdd(m_xBuilder->weld_button(u"button_add"_ustr))
 {
-    mxIconViewThemeColors->connect_item_activated(LINK(this, ThemeDialog, 
ItemActivatedHdl));
-    mxIconViewThemeColors->connect_selection_changed(LINK(this, ThemeDialog, 
SelectionChangedHdl));
-
     mxAdd->connect_clicked(LINK(this, ThemeDialog, ButtonClicked));
 
-    initColorSets();
-
-    if (!maColorSets.empty())
-    {
-        mxIconViewThemeColors->select(0);
-        mpCurrentColorSet = std::make_shared<model::ColorSet>(maColorSets[0]);
-    }
+    initColorSets(pTheme);
 }
 
 ThemeDialog::~ThemeDialog()
@@ -44,86 +35,10 @@ ThemeDialog::~ThemeDialog()
         mxSubDialog->response(RET_CANCEL);
 }
 
-void ThemeDialog::initColorSets()
-{
-    if (mpTheme)
-        maColorSets.push_back(*mpTheme->getColorSet());
-
-    auto const& rColorSetVector = ColorSets::get().getColorSetVector();
-    maColorSets.insert(maColorSets.end(), rColorSetVector.begin(), 
rColorSetVector.end());
-
-    for (size_t i = 0; i < maColorSets.size(); ++i)
-    {
-        auto const& rColorSet = maColorSets[i];
-        VclPtr<VirtualDevice> pVirDev = CreateColorSetPreview(rColorSet);
-
-        OUString sId = OUString::number(i);
-        OUString sName = rColorSet.getName();
-        mxIconViewThemeColors->insert(-1, &sName, &sId, pVirDev, nullptr);
-    }
-}
-
-VclPtr<VirtualDevice> ThemeDialog::CreateColorSetPreview(const 
model::ColorSet& rColorSet)
+void ThemeDialog::onColorSetActivated()
 {
-    VclPtr<VirtualDevice> pVDev = VclPtr<VirtualDevice>::Create();
-    const Size aSize(100, 50);
-    pVDev->SetOutputSizePixel(aSize);
-
-    const int nRows = 2;
-    const int nCols = 4;
-    const int nHorizontalPadding = 9;
-    const int nVerticalPadding = 3;
-    const int nMargin = 3;
-
-    const int nAvailableWidth = aSize.Width() - (2 * nHorizontalPadding);
-    const int nAvailableHeight = aSize.Height() - (2 * nVerticalPadding);
-
-    const int nColorCellHeight = (nAvailableHeight - ((nRows - 1) * nMargin)) 
/ nRows;
-    const int nColorCellWidth = (nAvailableWidth - ((nCols - 1) * nMargin)) / 
nCols;
-
-    // Draw border around entire color set
-    pVDev->SetLineColor(COL_LIGHTGRAY);
-    pVDev->DrawRect(tools::Rectangle(Point(0, 0), aSize));
-
-    for (int i = 0; i < 8; ++i)
-    {
-        const int nCol = i / 2;
-        const int nRow = i % 2;
-
-        const int nX = nHorizontalPadding + (nCol * (nColorCellWidth + 
nMargin));
-        const int nY = nVerticalPadding + (nRow * (nColorCellHeight + 
nMargin));
-
-        const tools::Rectangle aRect(Point(nX, nY), Size(nColorCellWidth, 
nColorCellHeight));
-
-        Color aColor = rColorSet.getColor(static_cast<model::ThemeColorType>(i 
+ 2));
-
-        pVDev->SetLineColor(COL_LIGHTGRAY);
-        pVDev->SetFillColor(aColor);
-        pVDev->DrawRect(aRect);
-    }
-    return pVDev;
-}
-
-IMPL_LINK(ThemeDialog, ItemActivatedHdl, weld::IconView&, iter, bool)
-{
-    SelectionChangedHdl(iter);
     if (!comphelper::LibreOfficeKit::isActive())
         m_xDialog->response(RET_OK);
-    return true;
-}
-
-IMPL_LINK_NOARG(ThemeDialog, SelectionChangedHdl, weld::IconView&, void)
-{
-    OUString sId = mxIconViewThemeColors->get_selected_id();
-    if (sId.isEmpty())
-        return;
-
-    sal_uInt32 nIndex = sId.toUInt32();
-
-    if (nIndex >= maColorSets.size())
-        return;
-
-    mpCurrentColorSet = std::make_shared<model::ColorSet>(maColorSets[nIndex]);
 }
 
 void ThemeDialog::runThemeColorEditDialog()
@@ -144,10 +59,7 @@ void ThemeDialog::runThemeColorEditDialog()
         if (!aColorSet.getName().isEmpty())
         {
             ColorSets::get().insert(aColorSet, 
ColorSets::IdenticalNameAction::AutoRename);
-            maColorSets.clear();
-            mxIconViewThemeColors->clear();
-
-            initColorSets();
+            initColorSets(mpTheme);
 
             mxIconViewThemeColors->select(maColorSets.size() - 1);
             mpCurrentColorSet
diff --git a/svx/uiconfig/ui/themeselectorpanel.ui 
b/svx/uiconfig/ui/themeselectorpanel.ui
new file mode 100644
index 000000000000..ffb8ce551452
--- /dev/null
+++ b/svx/uiconfig/ui/themeselectorpanel.ui
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.40.0 -->
+<interface domain="svx">
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkTreeStore" id="liststore1">
+    <columns>
+      <!-- column-name expander -->
+      <column type="GdkPixbuf"/>
+      <!-- column-name text -->
+      <column type="gchararray"/>
+      <!-- column-name id -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
+  <object class="GtkBox" id="ThemeSelectorPanel">
+    <property name="visible">True</property>
+    <property name="can-focus">False</property>
+    <property name="hexpand">True</property>
+    <property name="spacing">6</property>
+    <child>
+      <object class="GtkScrolledWindow">
+        <property name="width-request">360</property>
+        <property name="height-request">65</property>
+        <property name="visible">True</property>
+        <property name="can-focus">True</property>
+        <property name="valign">center</property>
+        <property name="hscrollbar-policy">never</property>
+        <property name="vscrollbar-policy">always</property>
+        <property name="shadow-type">in</property>
+        <property name="min-content-width">70</property>
+        <child>
+          <object class="GtkIconView" id="iconview_theme_colors">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="margin">6</property>
+            <property name="model">liststore1</property>
+            <property name="columns">3</property>
+            <property name="item-width">70</property>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">False</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/vcl/jsdialog/enabled.cxx b/vcl/jsdialog/enabled.cxx
index 7d872632fe5f..caa818aa84b1 100644
--- a/vcl/jsdialog/enabled.cxx
+++ b/vcl/jsdialog/enabled.cxx
@@ -514,6 +514,7 @@ constexpr auto NotebookbarList
         { u"svx/ui/fontnamebox.ui" },
         { u"svx/ui/fontsizebox.ui" },
         { u"svx/ui/stylespreview.ui" },
+        { u"svx/ui/themeselectorpanel.ui" },
         // not interim builder, but regular builder:
         { u"modules/simpress/ui/masterpagepanelall.ui" },
         { u"modules/simpress/ui/slidetransitionspanel.ui" }
diff --git a/vcl/workben/cgmfuzzer.cxx b/vcl/workben/cgmfuzzer.cxx
index 5b8e075341f9..12383df54e95 100644
--- a/vcl/workben/cgmfuzzer.cxx
+++ b/vcl/workben/cgmfuzzer.cxx
@@ -65,6 +65,7 @@ void 
com_sun_star_comp_sd_InsertSlideController_get_implementation( void );
 void com_sun_star_comp_sd_SlideLayoutController_get_implementation( void );
 void com_sun_star_comp_sd_DisplayModeController_get_implementation( void );
 void com_sun_star_comp_sd_SlideTransitionsToolBoxControl_get_implementation( 
void );
+void com_sun_star_comp_sd_ThemeColorsToolBoxControl_get_implementation( void );
 void ucb_UcbCommandEnvironment_get_implementation( void );
 void ucb_UcbContentProviderProxyFactory_get_implementation( void );
 void ucb_UcbPropertiesManager_get_implementation( void );
@@ -136,6 +137,7 @@ lo_get_constructor_map(void)
         { "com_sun_star_comp_sd_SlideLayoutController_get_implementation", 
com_sun_star_comp_sd_SlideLayoutController_get_implementation },
         { "com_sun_star_comp_sd_DisplayModeController_get_implementation", 
com_sun_star_comp_sd_DisplayModeController_get_implementation },
         { 
"com_sun_star_comp_sd_SlideTransitionsToolBoxControl_get_implementation", 
com_sun_star_comp_sd_SlideTransitionsToolBoxControl_get_implementation },
+        { "com_sun_star_comp_sd_ThemeColorsToolBoxControl_get_implementation", 
com_sun_star_comp_sd_ThemeColorsToolBoxControl_get_implementation },
         { "ucb_UcbCommandEnvironment_get_implementation", 
ucb_UcbCommandEnvironment_get_implementation, },
         { "ucb_UcbContentProviderProxyFactory_get_implementation", 
ucb_UcbContentProviderProxyFactory_get_implementation },
         { "ucb_UcbPropertiesManager_get_implementation", 
ucb_UcbPropertiesManager_get_implementation },

Reply via email to