summaryrefslogtreecommitdiff
path: root/svtools
diff options
context:
space:
mode:
authorMaxim Monastirsky <momonasmon@gmail.com>2017-02-09 00:31:24 +0200
committerMaxim Monastirsky <momonasmon@gmail.com>2017-02-09 22:49:51 +0000
commit54d5b1828ec73d0475e0ddb6e31394a7e1904a1b (patch)
tree95ea5cb85d31f4cd9d79d0fedb600c5a556ba361 /svtools
parent8dc38dd9b132805191e0d20d00fb7559121fda15 (diff)
tdf#105672 framework managed menu button
This adds a menu button that can use a popup menu controller to manage its menu. It supports 2 cases: - Use any controller that is registered in Controller.xcu, by specifing its .uno command. - Manage an arbitrary popup menu with MenuBarManager (assuming its items have proper .uno commands in their MenuItemData::aCommandStr). It means that a menu that was defined in a .ui file, can be used inside that .ui file without any additional code. This commit uses the new control to fix some currently non-working buttons in Calc's Notebookbar (but there are more that can be fixed the same way). It's not clear how long we will continue to use buttons (instead of toolboxes) for the Notebookbar, but hopefully this control will be useful in other places too. Change-Id: Ie00cde7cd7e39948948960ca2eff76e9db837109 Reviewed-on: https://gerrit.libreoffice.org/34103 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Maxim Monastirsky <momonasmon@gmail.com>
Diffstat (limited to 'svtools')
-rw-r--r--svtools/Library_svt.mk1
-rw-r--r--svtools/source/control/managedmenubutton.cxx122
2 files changed, 123 insertions, 0 deletions
diff --git a/svtools/Library_svt.mk b/svtools/Library_svt.mk
index f778453846ee..2f3ca6a97a3a 100644
--- a/svtools/Library_svt.mk
+++ b/svtools/Library_svt.mk
@@ -122,6 +122,7 @@ $(eval $(call gb_Library_add_exception_objects,svt,\
svtools/source/control/hyperlabel \
svtools/source/control/indexentryres \
svtools/source/control/inettbc \
+ svtools/source/control/managedmenubutton \
svtools/source/control/roadmap \
svtools/source/control/ruler \
svtools/source/control/scriptedtext \
diff --git a/svtools/source/control/managedmenubutton.cxx b/svtools/source/control/managedmenubutton.cxx
new file mode 100644
index 000000000000..45e9d98ca1a8
--- /dev/null
+++ b/svtools/source/control/managedmenubutton.cxx
@@ -0,0 +1,122 @@
+/* -*- 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 <comphelper/processfactory.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <toolkit/awt/vclxmenu.hxx>
+#include <vcl/builderfactory.hxx>
+#include <vcl/menu.hxx>
+#include <vcl/menubtn.hxx>
+
+#include <com/sun/star/frame/theDesktop.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/frame/thePopupMenuControllerFactory.hpp>
+#include <com/sun/star/frame/XPopupMenuController.hpp>
+
+namespace {
+
+class ManagedMenuButton : public MenuButton
+{
+public:
+ ManagedMenuButton(vcl::Window* pParent, WinBits nStyle);
+ ~ManagedMenuButton() override;
+
+ void Activate() override;
+ void dispose() override;
+
+private:
+ rtl::Reference<VCLXPopupMenu> m_xPopupMenu;
+ css::uno::Reference<css::frame::XPopupMenuController> m_xPopupController;
+};
+
+ManagedMenuButton::ManagedMenuButton(vcl::Window* pParent, WinBits nStyle)
+ : MenuButton(pParent, nStyle)
+{
+ SetImageAlign(ImageAlign::Left);
+}
+
+ManagedMenuButton::~ManagedMenuButton()
+{
+ disposeOnce();
+}
+
+void ManagedMenuButton::dispose()
+{
+ css::uno::Reference<css::lang::XComponent> xComponent(m_xPopupController, css::uno::UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose();
+
+ m_xPopupMenu.clear();
+ m_xPopupController.clear();
+ MenuButton::dispose();
+}
+
+void ManagedMenuButton::Activate()
+{
+ if (!GetPopupMenu())
+ SetPopupMenu(VclPtr<PopupMenu>::Create());
+
+ MenuButton::Activate();
+
+ if (m_xPopupController.is())
+ {
+ m_xPopupController->updatePopupMenu();
+ return;
+ }
+
+ if (!m_xPopupMenu.is())
+ m_xPopupMenu.set(new VCLXPopupMenu(GetPopupMenu()));
+
+ // FIXME: get the frame from the parent VclBuilder.
+ css::uno::Reference<css::uno::XComponentContext> xContext(comphelper::getProcessComponentContext());
+ css::uno::Reference<css::frame::XDesktop2> xDesktop(css::frame::theDesktop::get(xContext));
+ css::uno::Reference<css::frame::XFrame> xFrame(xDesktop->getActiveFrame());
+ if (!xFrame.is())
+ return;
+
+ OUString aModuleName;
+ try
+ {
+ css::uno::Reference<css::frame::XModuleManager> xModuleManager(css::frame::ModuleManager::create(xContext));
+ aModuleName = xModuleManager->identify(xFrame);
+ }
+ catch( const css::uno::Exception& )
+ {}
+
+ css::uno::Sequence<css::uno::Any> aArgs {
+ css::uno::makeAny(comphelper::makePropertyValue("ModuleIdentifier", aModuleName)),
+ css::uno::makeAny(comphelper::makePropertyValue("Frame", css::uno::makeAny(xFrame))),
+ css::uno::makeAny(comphelper::makePropertyValue("InToolbar", css::uno::makeAny(true)))
+ };
+
+ const OUString aCommand(GetCommand());
+ if (!aCommand.isEmpty() && GetPopupMenu()->GetItemCount() == 0)
+ {
+ css::uno::Reference<css::frame::XUIControllerFactory> xPopupMenuControllerFactory =
+ css::frame::thePopupMenuControllerFactory::get(xContext);
+
+ if (xPopupMenuControllerFactory->hasController(aCommand, aModuleName))
+ m_xPopupController.set(xPopupMenuControllerFactory->createInstanceWithArgumentsAndContext(
+ aCommand, aArgs, xContext), css::uno::UNO_QUERY);
+ }
+
+ // No registered controller found, use one the can handle arbitrary menus (e.g. defined in .ui file).
+ if (!m_xPopupController.is())
+ m_xPopupController.set(xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
+ "com.sun.star.comp.framework.ResourceMenuController", aArgs, xContext), css::uno::UNO_QUERY);
+
+ if (m_xPopupController.is())
+ m_xPopupController->setPopupMenu(m_xPopupMenu.get());
+}
+
+}
+
+VCL_BUILDER_FACTORY_ARGS(ManagedMenuButton, WB_CLIPCHILDREN|WB_CENTER|WB_VCENTER|WB_FLATBUTTON)
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */