diff options
author | Maxim Monastirsky <momonasmon@gmail.com> | 2017-02-09 00:31:24 +0200 |
---|---|---|
committer | Maxim Monastirsky <momonasmon@gmail.com> | 2017-02-09 22:49:51 +0000 |
commit | 54d5b1828ec73d0475e0ddb6e31394a7e1904a1b (patch) | |
tree | 95ea5cb85d31f4cd9d79d0fedb600c5a556ba361 /svtools | |
parent | 8dc38dd9b132805191e0d20d00fb7559121fda15 (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.mk | 1 | ||||
-rw-r--r-- | svtools/source/control/managedmenubutton.cxx | 122 |
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: */ |