cui/Library_cui.mk                    |    1 
 cui/UIConfig_cui.mk                   |    1 
 cui/source/dialogs/toolbarmodedlg.cxx |   22 +++--
 cui/source/dialogs/toolbartabpage.cxx |  129 ++++++++++++++++++++++++++++++++++
 cui/source/inc/toolbartabpage.hxx     |   31 ++++++++
 cui/uiconfig/ui/toolbarmodedialog.ui  |   24 ++++++
 cui/uiconfig/ui/toolbartabpage.ui     |   82 +++++++++++++++++++++
 7 files changed, 280 insertions(+), 10 deletions(-)

New commits:
commit 4ab26f4ea0c627844531144a6a903c357a604a5e
Author:     Heiko Tietze <tietze.he...@gmail.com>
AuthorDate: Mon May 26 12:03:40 2025 +0200
Commit:     Heiko Tietze <heiko.tie...@documentfoundation.org>
CommitDate: Mon May 26 17:10:44 2025 +0200

    Resolves tdf#158880 - Let users select multiple toolbars at once
    
    Tab added to the UIPicker aka ToolbarModeDialog showing
    all toolbars likewise in the main menu
    
    Change-Id: I71d52ca88dc14012a70911c20f9252e578798a74
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185788
    Tested-by: Jenkins
    Reviewed-by: Heiko Tietze <heiko.tie...@documentfoundation.org>

diff --git a/cui/Library_cui.mk b/cui/Library_cui.mk
index da1ad94c0608..26e92f3548be 100644
--- a/cui/Library_cui.mk
+++ b/cui/Library_cui.mk
@@ -163,6 +163,7 @@ $(eval $(call gb_Library_add_exception_objects,cui,\
     cui/source/dialogs/toolbarmodedlg \
     cui/source/dialogs/whatsnewtabpage \
     cui/source/dialogs/uitabpage \
+    cui/source/dialogs/toolbartabpage \
     cui/source/dialogs/welcomedlg \
     cui/source/dialogs/zoom \
     cui/source/factory/cuiexp \
diff --git a/cui/UIConfig_cui.mk b/cui/UIConfig_cui.mk
index cbafc04faf8e..57cc6215eb82 100644
--- a/cui/UIConfig_cui.mk
+++ b/cui/UIConfig_cui.mk
@@ -223,6 +223,7 @@ $(eval $(call gb_UIConfig_add_uifiles,cui,\
        cui/uiconfig/ui/thesaurus \
        cui/uiconfig/ui/toolbarmodedialog \
        cui/uiconfig/ui/uitabpage \
+       cui/uiconfig/ui/toolbartabpage \
        cui/uiconfig/ui/transparencytabpage \
        cui/uiconfig/ui/tsaurldialog \
        cui/uiconfig/ui/twolinespage \
diff --git a/cui/source/dialogs/toolbarmodedlg.cxx 
b/cui/source/dialogs/toolbarmodedlg.cxx
index 2b259e9701cc..5a7f2383488b 100644
--- a/cui/source/dialogs/toolbarmodedlg.cxx
+++ b/cui/source/dialogs/toolbarmodedlg.cxx
@@ -8,6 +8,7 @@
  */
 
 #include <toolbarmodedlg.hxx>
+#include <toolbartabpage.hxx>
 
 #include <comphelper/dispatchcommand.hxx>
 #include <dialmgr.hxx>
@@ -26,24 +27,25 @@ ToolbarmodeDialog::ToolbarmodeDialog(weld::Window* pParent)
     , m_xResetBtn(m_xBuilder->weld_button(u"reset"_ustr)) // Apply to All
 {
     AddTabPage("uimode", UITabPage::Create, nullptr);
+    AddTabPage("toolbars", ToolbarTabPage::Create, nullptr);
 
     m_xOKBtn->set_visible(false);
     m_xHelpBtn->set_visible(false);
     m_xCancelBtn->set_label(CuiResId(RID_CUISTR_HYPDLG_CLOSEBUT)); // "close"
+
+    m_xApplyBtn->set_label(
+        CuiResId(RID_CUISTR_UI_APPLY).replaceFirst("%MODULE", 
UITabPage::GetCurrentApp()));
+    m_xApplyBtn->set_from_icon_name("sw/res/sc20558.png");
+    m_xResetBtn->set_label(CuiResId(RID_CUISTR_UI_APPLYALL));
+    m_xApplyBtn->connect_clicked(LINK(this, ToolbarmodeDialog, OnApplyClick));
+    m_xResetBtn->connect_clicked(LINK(this, ToolbarmodeDialog, OnApplyClick));
 }
 
 void ToolbarmodeDialog::ActivatePage(const OUString& rPage)
 {
-    if (rPage == "uimode")
-    {
-        m_xApplyBtn->set_label(
-            CuiResId(RID_CUISTR_UI_APPLY).replaceFirst("%MODULE", 
UITabPage::GetCurrentApp()));
-        m_xApplyBtn->set_from_icon_name("sw/res/sc20558.png");
-        m_xResetBtn->set_label(CuiResId(RID_CUISTR_UI_APPLYALL));
-
-        m_xApplyBtn->connect_clicked(LINK(this, ToolbarmodeDialog, 
OnApplyClick));
-        m_xResetBtn->connect_clicked(LINK(this, ToolbarmodeDialog, 
OnApplyClick));
-    }
+    const bool bOn(rPage == "uimode");
+    m_xApplyBtn->set_visible(bOn); // preferrably set_active() but not (yet) 
available
+    m_xResetBtn->set_visible(bOn);
 }
 
 IMPL_LINK(ToolbarmodeDialog, OnApplyClick, weld::Button&, rButton, void)
diff --git a/cui/source/dialogs/toolbartabpage.cxx 
b/cui/source/dialogs/toolbartabpage.cxx
new file mode 100644
index 000000000000..d1a76ae8526e
--- /dev/null
+++ b/cui/source/dialogs/toolbartabpage.cxx
@@ -0,0 +1,129 @@
+/* -*- 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 <sal/config.h>
+
+#include <toolbartabpage.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/ui/UIElementType.hpp>
+#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/theWindowStateConfiguration.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <vcl/commandinfoprovider.hxx>
+
+std::unique_ptr<SfxTabPage> ToolbarTabPage::Create(weld::Container* pPage,
+                                                   weld::DialogController* 
pController,
+                                                   const SfxItemSet* rAttr)
+{
+    return std::make_unique<ToolbarTabPage>(pPage, pController, *rAttr);
+}
+
+ToolbarTabPage::ToolbarTabPage(weld::Container* pPage, weld::DialogController* 
pController,
+                               const SfxItemSet& rAttr)
+    : SfxTabPage(pPage, pController, u"cui/ui/toolbartabpage.ui"_ustr, 
u"ToolbarTabPage"_ustr,
+                 &rAttr)
+    , m_pToolbarList(m_xBuilder->weld_tree_view(u"tvToolbarList"_ustr))
+{
+    m_pToolbarList->enable_toggle_buttons(weld::ColumnToggleType::Check);
+    m_pToolbarList->connect_toggled(LINK(this, ToolbarTabPage, ToggleHdl));
+}
+
+void ToolbarTabPage::Reset(const SfxItemSet* /* rSet*/)
+{
+    css::uno::Reference<css::uno::XComponentContext> xContext(
+        comphelper::getProcessComponentContext());
+    if (!xContext)
+        return;
+    css::uno::Reference<css::frame::XFrame> xFrame
+        = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
+    if (!xFrame)
+        return;
+    css::uno::Reference<css::ui::XModuleUIConfigurationManagerSupplier> 
xSupplier
+        = css::ui::theModuleUIConfigurationManagerSupplier::get(xContext);
+    if (!xSupplier)
+        return;
+    const OUString sModuleId = 
vcl::CommandInfoProvider::GetModuleIdentifier(xFrame);
+    css::uno::Reference<css::ui::XUIConfigurationManager> xUIConfigMgr(
+        xSupplier->getUIConfigurationManager(sModuleId));
+    if (!xUIConfigMgr)
+        return;
+    css::uno::Reference<css::container::XNameAccess> xUICmdDescription
+        = css::ui::theWindowStateConfiguration::get(xContext);
+    if (!xUICmdDescription)
+        return;
+    css::uno::Reference<css::container::XNameAccess> xModuleConf;
+    xUICmdDescription->getByName(sModuleId) >>= xModuleConf;
+    if (!xModuleConf)
+        return;
+
+    css::uno::Reference<css::beans::XPropertySet> xPropSet(xFrame, 
css::uno::UNO_QUERY);
+    xPropSet->getPropertyValue(u"LayoutManager"_ustr) >>= m_xLayoutManager;
+
+    css::uno::Sequence<css::uno::Sequence<css::beans::PropertyValue>> 
aSeqDocToolBars;
+    aSeqDocToolBars = 
xUIConfigMgr->getUIElementsInfo(css::ui::UIElementType::TOOLBAR);
+
+    for (css::uno::Sequence<css::beans::PropertyValue> const& props : 
aSeqDocToolBars)
+    {
+        for (css::beans::PropertyValue const& prop : props)
+        {
+            if (prop.Name == u"ResourceURL"_ustr)
+            {
+                css::uno::Sequence<css::beans::PropertyValue> aCmdProps;
+                OUString sResourceURL;
+                OUString sUIName;
+                bool bHide = true;
+
+                prop.Value >>= sResourceURL;
+
+                if (xModuleConf->hasByName(sResourceURL))
+                {
+                    xModuleConf->getByName(sResourceURL) >>= aCmdProps;
+                    for (const auto& aCmdProp : aCmdProps)
+                    {
+                        if (aCmdProp.Name == u"UIName"_ustr)
+                            aCmdProp.Value >>= sUIName;
+                        else if (aCmdProp.Name == u"HideFromToolbarMenu"_ustr)
+                            aCmdProp.Value >>= bHide;
+                    }
+                    if (!bHide)
+                    {
+                        m_pToolbarList->append();
+                        const int nRow = m_pToolbarList->n_children() - 1;
+                        m_pToolbarList->set_id(nRow, sResourceURL);
+                        m_pToolbarList->set_text(nRow, sUIName, 0);
+                        const bool bShow = 
m_xLayoutManager->isElementVisible(sResourceURL);
+                        m_pToolbarList->set_toggle(nRow, bShow ? TRISTATE_TRUE 
: TRISTATE_FALSE);
+                    }
+                }
+            }
+        }
+    }
+    m_pToolbarList->make_sorted();
+}
+
+IMPL_LINK(ToolbarTabPage, ToggleHdl, const weld::TreeView::iter_col&, rRowCol, 
void)
+{
+    const int nRow(m_pToolbarList->get_iter_index_in_parent(rRowCol.first));
+    m_pToolbarList->select(nRow);
+    OUString sToolbarUrl(m_pToolbarList->get_id(nRow));
+    if (m_pToolbarList->get_toggle(nRow) == TRISTATE_TRUE)
+    {
+        m_xLayoutManager->createElement(sToolbarUrl);
+        m_xLayoutManager->showElement(sToolbarUrl);
+    }
+    else
+    {
+        m_xLayoutManager->hideElement(sToolbarUrl);
+        m_xLayoutManager->destroyElement(sToolbarUrl);
+    }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
\ No newline at end of file
diff --git a/cui/source/inc/toolbartabpage.hxx 
b/cui/source/inc/toolbartabpage.hxx
new file mode 100644
index 000000000000..5283d6766e3e
--- /dev/null
+++ b/cui/source/inc/toolbartabpage.hxx
@@ -0,0 +1,31 @@
+/* -*- 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 <com/sun/star/frame/XLayoutManager.hpp>
+
+#include <sfx2/tabdlg.hxx>
+class ToolbarTabPage : public SfxTabPage
+{
+private:
+    css::uno::Reference<css::frame::XLayoutManager> m_xLayoutManager;
+    std::unique_ptr<weld::TreeView> m_pToolbarList;
+    virtual void Reset(const SfxItemSet* /* rSet*/) override;
+    DECL_LINK(ToggleHdl, const weld::TreeView::iter_col&, void);
+
+public:
+    ToolbarTabPage(weld::Container* pPage, weld::DialogController* pController,
+                   const SfxItemSet& rSet);
+    static std::unique_ptr<SfxTabPage>
+    Create(weld::Container* pPage, weld::DialogController* pController, const 
SfxItemSet* rSet);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/cui/uiconfig/ui/toolbarmodedialog.ui 
b/cui/uiconfig/ui/toolbarmodedialog.ui
index 67ed53a7304b..8185590ab444 100644
--- a/cui/uiconfig/ui/toolbarmodedialog.ui
+++ b/cui/uiconfig/ui/toolbarmodedialog.ui
@@ -128,6 +128,30 @@
                 <property name="tab-fill">False</property>
               </packing>
             </child>
+            <child>
+              <!-- n-columns=1 n-rows=1 -->
+              <object class="GtkGrid">
+                <property name="visible">True</property>
+                <property name="can-focus">False</property>
+                <child>
+                  <placeholder/>
+                </child>
+              </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="toolbars">
+                <property name="visible">True</property>
+                <property name="can-focus">False</property>
+                <property name="label" translatable="yes" 
context="toolbarmodedialog|toolbars">Toolbars</property>
+              </object>
+              <packing>
+                <property name="position">1</property>
+                <property name="tab-fill">False</property>
+              </packing>
+            </child>
           </object>
           <packing>
             <property name="expand">False</property>
diff --git a/cui/uiconfig/ui/toolbartabpage.ui 
b/cui/uiconfig/ui/toolbartabpage.ui
new file mode 100644
index 000000000000..fa4195c9ecbf
--- /dev/null
+++ b/cui/uiconfig/ui/toolbartabpage.ui
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.40.0 -->
+<interface domain="cui">
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkTreeStore" id="listStore">
+    <columns>
+      <!-- column-name checkbox -->
+      <column type="gboolean"/>
+      <!-- column-name text -->
+      <column type="gchararray"/>
+      <!-- column-name id -->
+      <column type="gchararray"/>
+      <!-- column-name checkvis1 -->
+      <column type="gboolean"/>
+      <!-- column-name checktri1 -->
+      <column type="gboolean"/>
+    </columns>
+  </object>
+  <object class="GtkBox" id="ToolbarTabPage">
+    <property name="visible">True</property>
+    <property name="can-focus">False</property>
+    <property name="margin-start">6</property>
+    <property name="margin-end">6</property>
+    <property name="margin-top">6</property>
+    <property name="margin-bottom">6</property>
+    <property name="hexpand">True</property>
+    <property name="vexpand">True</property>
+    <property name="orientation">vertical</property>
+    <child>
+      <object class="GtkScrolledWindow">
+        <property name="width-request">40</property>
+        <property name="height-request">30</property>
+        <property name="visible">True</property>
+        <property name="can-focus">True</property>
+        <property name="hexpand">True</property>
+        <property name="vexpand">True</property>
+        <property name="shadow-type">in</property>
+        <child>
+          <object class="GtkTreeView" id="tvToolbarList">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="receives-default">True</property>
+            <property name="hexpand">True</property>
+            <property name="vexpand">True</property>
+            <property name="model">listStore</property>
+            <property name="headers-visible">False</property>
+            <property name="headers-clickable">False</property>
+            <property name="enable-search">False</property>
+            <property name="show-expanders">False</property>
+            <child internal-child="selection">
+              <object class="GtkTreeSelection"/>
+            </child>
+            <child>
+              <object class="GtkTreeViewColumn" id="column1">
+                <property name="resizable">True</property>
+                <property name="expand">True</property>
+                <child>
+                  <object class="GtkCellRendererToggle" id="cbRender"/>
+                  <attributes>
+                    <attribute name="active">0</attribute>
+                    <attribute name="visible">3</attribute>
+                  </attributes>
+                </child>
+                <child>
+                  <object class="GtkCellRendererText" id="lbRender"/>
+                  <attributes>
+                    <attribute name="text">1</attribute>
+                  </attributes>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+  </object>
+</interface>

Reply via email to