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>