summaryrefslogtreecommitdiffstats
path: root/sfx2/source/toolbox
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /sfx2/source/toolbox
parentInitial commit. (diff)
downloadlibreoffice-upstream.tar.xz
libreoffice-upstream.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sfx2/source/toolbox')
-rw-r--r--sfx2/source/toolbox/tbxitem.cxx506
-rw-r--r--sfx2/source/toolbox/weldutils.cxx203
2 files changed, 709 insertions, 0 deletions
diff --git a/sfx2/source/toolbox/tbxitem.cxx b/sfx2/source/toolbox/tbxitem.cxx
new file mode 100644
index 000000000..e61503f94
--- /dev/null
+++ b/sfx2/source/toolbox/tbxitem.cxx
@@ -0,0 +1,506 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#ifdef __sun
+#include <ctime>
+#endif
+
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/util/URLTransformer.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/frame/status/ItemStatus.hpp>
+#include <com/sun/star/ui/XUIElementFactory.hpp>
+#include <com/sun/star/frame/status/Visibility.hpp>
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/visitem.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/toolbox.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include <vcl/InterimItemWindow.hxx>
+#include <sfx2/tbxctrl.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/msg.hxx>
+#include <sfx2/msgpool.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/module.hxx>
+#include <sfx2/app.hxx>
+#include <unoctitm.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::frame::status;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::ui;
+
+
+SFX_IMPL_TOOLBOX_CONTROL_ARG(SfxToolBoxControl, SfxStringItem, true);
+
+rtl::Reference<svt::ToolboxController> SfxToolBoxControllerFactory( const Reference< XFrame >& rFrame, ToolBox* pToolbox, ToolBoxItemId nID, const OUString& aCommandURL )
+{
+ SolarMutexGuard aGuard;
+
+ URL aTargetURL;
+ aTargetURL.Complete = aCommandURL;
+ Reference < XURLTransformer > xTrans( URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
+ xTrans->parseStrict( aTargetURL );
+ if ( !aTargetURL.Arguments.isEmpty() )
+ return nullptr;
+
+ Reference < XController > xController;
+ Reference < XModel > xModel;
+ if ( rFrame.is() )
+ {
+ xController = rFrame->getController();
+ if ( xController.is() )
+ xModel = xController->getModel();
+ }
+
+ SfxObjectShell* pObjShell = SfxObjectShell::GetShellFromComponent(xModel);
+ SfxModule* pModule = pObjShell ? pObjShell->GetModule() : nullptr;
+ SfxSlotPool* pSlotPool = nullptr;
+
+ if ( pModule )
+ pSlotPool = pModule->GetSlotPool();
+ else
+ pSlotPool = &(SfxSlotPool::GetSlotPool());
+
+ const SfxSlot* pSlot = pSlotPool->GetUnoSlot( aTargetURL.Path );
+ if ( pSlot )
+ {
+ sal_uInt16 nSlotId = pSlot->GetSlotId();
+ if ( nSlotId > 0 )
+ return SfxToolBoxControl::CreateControl( nSlotId, nID, pToolbox, pModule );
+ }
+
+ return nullptr;
+}
+
+struct SfxToolBoxControl_Impl
+{
+ VclPtr<ToolBox> pBox;
+ bool bShowString;
+ ToolBoxItemId nTbxId;
+ sal_uInt16 nSlotId;
+};
+
+SfxToolBoxControl::SfxToolBoxControl(
+ sal_uInt16 nSlotID,
+ ToolBoxItemId nID,
+ ToolBox& rBox,
+ bool bShowStringItems )
+ : pImpl( new SfxToolBoxControl_Impl )
+{
+ pImpl->pBox = &rBox;
+ pImpl->bShowString = bShowStringItems;
+ pImpl->nTbxId = nID;
+ pImpl->nSlotId = nSlotID;
+}
+
+
+SfxToolBoxControl::~SfxToolBoxControl()
+{
+}
+
+
+ToolBox& SfxToolBoxControl::GetToolBox() const
+{
+ return *pImpl->pBox;
+}
+ToolBoxItemId SfxToolBoxControl::GetId() const
+{
+ return pImpl->nTbxId;
+}
+unsigned short SfxToolBoxControl::GetSlotId() const
+{
+ return pImpl->nSlotId;
+}
+
+
+void SAL_CALL SfxToolBoxControl::dispose()
+{
+ if ( m_bDisposed )
+ return;
+
+ svt::ToolboxController::dispose();
+
+ // Remove and destroy our item window at our toolbox
+ SolarMutexGuard aGuard;
+ VclPtr< vcl::Window > pWindow = pImpl->pBox->GetItemWindow( pImpl->nTbxId );
+ pImpl->pBox->SetItemWindow( pImpl->nTbxId, nullptr );
+ pWindow.disposeAndClear();
+}
+
+
+void SfxToolBoxControl::RegisterToolBoxControl( SfxModule* pMod, const SfxTbxCtrlFactory& rFact)
+{
+ SfxGetpApp()->RegisterToolBoxControl_Impl( pMod, rFact );
+}
+
+rtl::Reference<SfxToolBoxControl> SfxToolBoxControl::CreateControl( sal_uInt16 nSlotId, ToolBoxItemId nTbxId, ToolBox *pBox, SfxModule const * pMod )
+{
+ SolarMutexGuard aGuard;
+
+ SfxApplication *pApp = SfxGetpApp();
+
+ SfxSlotPool *pSlotPool;
+ if ( pMod )
+ pSlotPool = pMod->GetSlotPool();
+ else
+ pSlotPool = &SfxSlotPool::GetSlotPool();
+ const std::type_info* aSlotType = pSlotPool->GetSlotType( nSlotId );
+ if ( aSlotType )
+ {
+ if ( pMod )
+ {
+ SfxTbxCtrlFactory *pFact = pMod->GetTbxCtrlFactory(*aSlotType, nSlotId);
+ if ( pFact )
+ return pFact->pCtor( nSlotId, nTbxId, *pBox );
+ }
+
+ SfxTbxCtrlFactory* pFact = pApp->GetTbxCtrlFactory(*aSlotType, nSlotId);
+ if (pFact)
+ return pFact->pCtor( nSlotId, nTbxId, *pBox );
+ }
+
+ return nullptr;
+}
+
+SfxItemState SfxToolBoxControl::GetItemState(
+ const SfxPoolItem* pState )
+/* [Description]
+
+ Static method for determining the status of the SfxPoolItem-pointer,
+ used in the method <SfxControllerItem::StateChanged(const SfxPoolItem*)>.
+
+ [Return value]
+
+ SfxItemState SfxItemState::UNKNOWN
+ Enabled, however no further status information is available.
+ Typical for <Slot>s, which are temporarily disabled a
+ anyway but other than that do not change their appearance.
+
+ SfxItemState::DISABLED
+ Disabled, no further status information is available.
+ All other displayed values should be reset to the default
+ if possible.
+
+ SfxItemState::DONTCARE
+ Enabled but there were only ambiguous values available
+ (i.e. none that could be queried).
+
+ SfxItemState::DEFAULT
+ Enabled and with available values which can be queried
+ through'pState'. The type is thus by the Slot clearly
+ defined in the entire Program.
+*/
+
+{
+ return !pState
+ ? SfxItemState::DISABLED
+ : IsInvalidItem(pState)
+ ? SfxItemState::DONTCARE
+ : pState->IsVoidItem() && !pState->Which()
+ ? SfxItemState::UNKNOWN
+ : SfxItemState::DEFAULT;
+}
+
+void SfxToolBoxControl::Dispatch(
+ const Reference< XDispatchProvider >& rProvider,
+ const OUString& rCommand,
+ Sequence< ::PropertyValue > const & aArgs )
+{
+ if ( rProvider.is() )
+ {
+ css::util::URL aTargetURL;
+ aTargetURL.Complete = rCommand;
+ Reference < XURLTransformer > xTrans( URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
+ xTrans->parseStrict( aTargetURL );
+
+ Reference < XDispatch > xDispatch = rProvider->queryDispatch( aTargetURL, OUString(), 0 );
+ if ( xDispatch.is() )
+ xDispatch->dispatch( aTargetURL, aArgs );
+ }
+}
+
+void SfxToolBoxControl::Dispatch( const OUString& aCommand, css::uno::Sequence< css::beans::PropertyValue > const & aArgs )
+{
+ Reference < XController > xController;
+
+ SolarMutexGuard aGuard;
+ if ( getFrameInterface().is() )
+ xController = getFrameInterface()->getController();
+
+ Reference < XDispatchProvider > xProvider( xController, UNO_QUERY );
+ if ( xProvider.is() )
+ {
+ css::util::URL aTargetURL;
+ aTargetURL.Complete = aCommand;
+ getURLTransformer()->parseStrict( aTargetURL );
+
+ Reference < XDispatch > xDispatch = xProvider->queryDispatch( aTargetURL, OUString(), 0 );
+ if ( xDispatch.is() )
+ xDispatch->dispatch( aTargetURL, aArgs );
+ }
+}
+
+// XStatusListener
+void SAL_CALL SfxToolBoxControl::statusChanged( const FeatureStateEvent& rEvent )
+{
+ SfxViewFrame* pViewFrame = nullptr;
+ Reference < XController > xController;
+
+ SolarMutexGuard aGuard;
+ if ( getFrameInterface().is() )
+ xController = getFrameInterface()->getController();
+
+ Reference < XDispatchProvider > xProvider( xController, UNO_QUERY );
+ if ( xProvider.is() )
+ {
+ Reference < XDispatch > xDisp = xProvider->queryDispatch( rEvent.FeatureURL, OUString(), 0 );
+ if ( xDisp.is() )
+ {
+ Reference< XUnoTunnel > xTunnel( xDisp, UNO_QUERY );
+ if (auto pDisp = comphelper::getFromUnoTunnel<SfxOfficeDispatch>(xTunnel))
+ pViewFrame = pDisp->GetDispatcher_Impl()->GetFrame();
+ }
+ }
+
+ sal_uInt16 nSlotId = 0;
+ SfxSlotPool& rPool = SfxSlotPool::GetSlotPool( pViewFrame );
+ const SfxSlot* pSlot = rPool.GetUnoSlot( rEvent.FeatureURL.Path );
+ if ( pSlot )
+ nSlotId = pSlot->GetSlotId();
+ else if ( m_aCommandURL == rEvent.FeatureURL.Path )
+ nSlotId = GetSlotId();
+
+ if ( nSlotId <= 0 )
+ return;
+
+ if ( rEvent.Requery )
+ svt::ToolboxController::statusChanged( rEvent );
+ else
+ {
+ SfxItemState eState = SfxItemState::DISABLED;
+ std::unique_ptr<SfxPoolItem> pItem;
+ if ( rEvent.IsEnabled )
+ {
+ eState = SfxItemState::DEFAULT;
+ css::uno::Type aType = rEvent.State.getValueType();
+
+ if ( aType == cppu::UnoType<void>::get() )
+ {
+ pItem.reset(new SfxVoidItem( nSlotId ));
+ eState = SfxItemState::UNKNOWN;
+ }
+ else if ( aType == cppu::UnoType<bool>::get() )
+ {
+ bool bTemp = false;
+ rEvent.State >>= bTemp ;
+ pItem.reset(new SfxBoolItem( nSlotId, bTemp ));
+ }
+ else if ( aType == ::cppu::UnoType< ::cppu::UnoUnsignedShortType >::get())
+ {
+ sal_uInt16 nTemp = 0;
+ rEvent.State >>= nTemp ;
+ pItem.reset(new SfxUInt16Item( nSlotId, nTemp ));
+ }
+ else if ( aType == cppu::UnoType<sal_uInt32>::get() )
+ {
+ sal_uInt32 nTemp = 0;
+ rEvent.State >>= nTemp ;
+ pItem.reset(new SfxUInt32Item( nSlotId, nTemp ));
+ }
+ else if ( aType == cppu::UnoType<OUString>::get() )
+ {
+ OUString sTemp ;
+ rEvent.State >>= sTemp ;
+ pItem.reset(new SfxStringItem( nSlotId, sTemp ));
+ }
+ else if ( aType == cppu::UnoType< css::frame::status::ItemStatus>::get() )
+ {
+ ItemStatus aItemStatus;
+ rEvent.State >>= aItemStatus;
+ SfxItemState tmpState = static_cast<SfxItemState>(aItemStatus.State);
+ // make sure no-one tries to send us a combination of states
+ if (tmpState != SfxItemState::UNKNOWN && tmpState != SfxItemState::DISABLED &&
+ tmpState != SfxItemState::DONTCARE &&
+ tmpState != SfxItemState::DEFAULT && tmpState != SfxItemState::SET)
+ throw css::uno::RuntimeException("unknown status");
+ eState = tmpState;
+ pItem.reset(new SfxVoidItem( nSlotId ));
+ }
+ else if ( aType == cppu::UnoType< css::frame::status::Visibility>::get() )
+ {
+ Visibility aVisibilityStatus;
+ rEvent.State >>= aVisibilityStatus;
+ pItem.reset(new SfxVisibilityItem( nSlotId, aVisibilityStatus.bVisible ));
+ }
+ else
+ {
+ if ( pSlot )
+ pItem = pSlot->GetType()->CreateItem();
+ if ( pItem )
+ {
+ pItem->SetWhich( nSlotId );
+ pItem->PutValue( rEvent.State, 0 );
+ }
+ else
+ pItem.reset(new SfxVoidItem( nSlotId ));
+ }
+ }
+
+ StateChangedAtToolBoxControl( nSlotId, eState, pItem.get() );
+ }
+}
+
+// XToolbarController
+void SAL_CALL SfxToolBoxControl::execute( sal_Int16 KeyModifier )
+{
+ SolarMutexGuard aGuard;
+ Select( static_cast<sal_uInt16>(KeyModifier) );
+}
+
+void SAL_CALL SfxToolBoxControl::click()
+{
+ SolarMutexGuard aGuard;
+ Click();
+}
+
+void SAL_CALL SfxToolBoxControl::doubleClick()
+{
+ SolarMutexGuard aGuard;
+ DoubleClick();
+}
+
+Reference< css::awt::XWindow > SAL_CALL SfxToolBoxControl::createPopupWindow()
+{
+ SolarMutexGuard aGuard;
+ CreatePopupWindow();
+ return nullptr;
+}
+
+Reference< css::awt::XWindow > SAL_CALL SfxToolBoxControl::createItemWindow( const Reference< css::awt::XWindow >& rParent )
+{
+ SolarMutexGuard aGuard;
+ return VCLUnoHelper::GetInterface( CreateItemWindow( VCLUnoHelper::GetWindow( rParent )));
+}
+
+void SfxToolBoxControl::StateChangedAtToolBoxControl
+(
+ sal_uInt16 /*nSlotId*/,
+ SfxItemState eState,
+ const SfxPoolItem* pState
+)
+{
+ DBG_ASSERT( pImpl->pBox != nullptr, "setting state to dangling ToolBox" );
+
+ // enabled/disabled-Flag correcting the lump sum
+ pImpl->pBox->EnableItem( GetId(), eState != SfxItemState::DISABLED );
+
+ ToolBoxItemBits nItemBits = pImpl->pBox->GetItemBits( GetId() );
+ nItemBits &= ~ToolBoxItemBits::CHECKABLE;
+ ::TriState eTri = TRISTATE_FALSE;
+ switch ( eState )
+ {
+ case SfxItemState::DEFAULT:
+ if ( pState )
+ {
+ if ( auto pBoolItem = dynamic_cast< const SfxBoolItem* >(pState) )
+ {
+ // BoolItem for checking
+ if ( pBoolItem->GetValue() )
+ eTri = TRISTATE_TRUE;
+ nItemBits |= ToolBoxItemBits::CHECKABLE;
+ }
+ else if ( auto pEnumItem = dynamic_cast< const SfxEnumItemInterface *>( pState ) )
+ {
+ if (pEnumItem->HasBoolValue())
+ {
+ // EnumItem is handled as Bool
+ if (pEnumItem->GetBoolValue())
+ eTri = TRISTATE_TRUE;
+ nItemBits |= ToolBoxItemBits::CHECKABLE;
+ }
+ }
+ else if ( pImpl->bShowString )
+ {
+ if (auto pStringItem = dynamic_cast< const SfxStringItem *>( pState ) )
+ pImpl->pBox->SetItemText(GetId(), pStringItem->GetValue() );
+ }
+ }
+ break;
+
+ case SfxItemState::DONTCARE:
+ {
+ eTri = TRISTATE_INDET;
+ nItemBits |= ToolBoxItemBits::CHECKABLE;
+ }
+ break;
+
+ default: break; // do nothing
+ }
+
+ pImpl->pBox->SetItemState( GetId(), eTri );
+ pImpl->pBox->SetItemBits( GetId(), nItemBits );
+}
+
+
+void SfxToolBoxControl::Select( sal_uInt16 nSelectModifier )
+{
+ svt::ToolboxController::execute( nSelectModifier );
+}
+
+
+void SfxToolBoxControl::DoubleClick()
+{
+}
+
+
+void SfxToolBoxControl::Click()
+{
+}
+
+void SfxToolBoxControl::CreatePopupWindow()
+{
+}
+
+VclPtr<InterimItemWindow> SfxToolBoxControl::CreateItemWindow(vcl::Window*)
+{
+ return VclPtr<InterimItemWindow>();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/source/toolbox/weldutils.cxx b/sfx2/source/toolbox/weldutils.cxx
new file mode 100644
index 000000000..5c1f1c58f
--- /dev/null
+++ b/sfx2/source/toolbox/weldutils.cxx
@@ -0,0 +1,203 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 <officecfg/Office/Common.hxx>
+#include <com/sun/star/frame/XSubToolbarController.hpp>
+#include <sidebar/ControllerFactory.hxx>
+#include <sfx2/weldutils.hxx>
+#include <vcl/commandinfoprovider.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/weld.hxx>
+
+namespace
+{
+bool lcl_RTLizeCommandURL(OUString& rCommandURL)
+{
+ if (rCommandURL == ".uno:ParaLeftToRight")
+ {
+ rCommandURL = ".uno:ParaRightToLeft";
+ return true;
+ }
+ if (rCommandURL == ".uno:ParaRightToLeft")
+ {
+ rCommandURL = ".uno:ParaLeftToRight";
+ return true;
+ }
+ if (rCommandURL == ".uno:LeftPara")
+ {
+ rCommandURL = ".uno:RightPara";
+ return true;
+ }
+ if (rCommandURL == ".uno:RightPara")
+ {
+ rCommandURL = ".uno:LeftPara";
+ return true;
+ }
+ if (rCommandURL == ".uno:AlignLeft")
+ {
+ rCommandURL = ".uno:AlignRight";
+ return true;
+ }
+ if (rCommandURL == ".uno:AlignRight")
+ {
+ rCommandURL = ".uno:AlignLeft";
+ return true;
+ }
+ return false;
+}
+}
+
+// for now all controllers are in the sidebar
+vcl::ImageType ToolbarUnoDispatcher::GetIconSize()
+{
+ vcl::ImageType eType = vcl::ImageType::Size16;
+ switch (static_cast<ToolBoxButtonSize>(officecfg::Office::Common::Misc::SidebarIconSize::get()))
+ {
+ case ToolBoxButtonSize::Large:
+ eType = vcl::ImageType::Size26;
+ break;
+ case ToolBoxButtonSize::Size32:
+ eType = vcl::ImageType::Size32;
+ break;
+ case ToolBoxButtonSize::DontCare:
+ case ToolBoxButtonSize::Small:
+ break;
+ }
+ return eType;
+}
+
+ToolbarUnoDispatcher::ToolbarUnoDispatcher(weld::Toolbar& rToolbar, weld::Builder& rBuilder,
+ const css::uno::Reference<css::frame::XFrame>& rFrame,
+ bool bSideBar)
+ : m_xFrame(rFrame)
+ , m_pToolbar(&rToolbar)
+ , m_pBuilder(&rBuilder)
+ , m_bSideBar(bSideBar)
+{
+ rToolbar.connect_clicked(LINK(this, ToolbarUnoDispatcher, SelectHdl));
+ rToolbar.connect_menu_toggled(LINK(this, ToolbarUnoDispatcher, ToggleMenuHdl));
+
+ OUString aModuleName(vcl::CommandInfoProvider::GetModuleIdentifier(rFrame));
+ vcl::ImageType eSize = GetIconSize();
+ rToolbar.set_icon_size(eSize);
+
+ bool bRTL = AllSettings::GetLayoutRTL();
+
+ for (int i = 0, nItems = rToolbar.get_n_items(); i < nItems; ++i)
+ {
+ OString sIdent(rToolbar.get_item_ident(i));
+ if (!sIdent.startsWith(".uno:"))
+ continue;
+ OUString sCommand = OUString::fromUtf8(sIdent);
+ if (bRTL && lcl_RTLizeCommandURL(sCommand))
+ rToolbar.set_item_ident(i, sCommand.toUtf8());
+
+ auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(sCommand, aModuleName);
+ OUString aLabel(vcl::CommandInfoProvider::GetLabelForCommand(aProperties));
+ rToolbar.set_item_label(i, aLabel);
+ OUString aTooltip(
+ vcl::CommandInfoProvider::GetTooltipForCommand(sCommand, aProperties, rFrame));
+ rToolbar.set_item_tooltip_text(i, aTooltip);
+ auto xImage(vcl::CommandInfoProvider::GetXGraphicForCommand(sCommand, rFrame, eSize));
+ rToolbar.set_item_image(i, xImage);
+
+ CreateController(sCommand);
+ }
+
+ m_aToolbarOptions.AddListenerLink(LINK(this, ToolbarUnoDispatcher, ChangedIconSizeHandler));
+}
+
+void ToolbarUnoDispatcher::CreateController(const OUString& rCommand)
+{
+ css::uno::Reference<css::frame::XToolbarController> xController(
+ sfx2::sidebar::ControllerFactory::CreateToolBoxController(
+ *m_pToolbar, *m_pBuilder, rCommand, m_xFrame, m_xFrame->getController(), m_bSideBar));
+
+ if (xController.is())
+ maControllers.insert(std::make_pair(rCommand, xController));
+}
+
+css::uno::Reference<css::frame::XToolbarController>
+ToolbarUnoDispatcher::GetControllerForCommand(const OUString& rCommand) const
+{
+ ControllerContainer::const_iterator iController(maControllers.find(rCommand));
+ if (iController != maControllers.end())
+ return iController->second;
+
+ return css::uno::Reference<css::frame::XToolbarController>();
+}
+
+IMPL_LINK(ToolbarUnoDispatcher, SelectHdl, const OString&, rCommand, void)
+{
+ css::uno::Reference<css::frame::XToolbarController> xController(
+ GetControllerForCommand(OUString::fromUtf8(rCommand)));
+
+ if (xController.is())
+ xController->execute(0);
+}
+
+IMPL_LINK(ToolbarUnoDispatcher, ToggleMenuHdl, const OString&, rCommand, void)
+{
+ css::uno::Reference<css::frame::XToolbarController> xController(
+ GetControllerForCommand(OUString::fromUtf8(rCommand)));
+
+ if (xController.is())
+ xController->click();
+}
+
+IMPL_LINK_NOARG(ToolbarUnoDispatcher, ChangedIconSizeHandler, LinkParamNone*, void)
+{
+ vcl::ImageType eSize = GetIconSize();
+ m_pToolbar->set_icon_size(eSize);
+
+ for (int i = 0, nItems = m_pToolbar->get_n_items(); i < nItems; ++i)
+ {
+ OUString sCommand = OUString::fromUtf8(m_pToolbar->get_item_ident(i));
+ auto xImage(vcl::CommandInfoProvider::GetXGraphicForCommand(sCommand, m_xFrame, eSize));
+ m_pToolbar->set_item_image(i, xImage);
+ }
+
+ for (auto const& it : maControllers)
+ {
+ css::uno::Reference<css::frame::XSubToolbarController> xController(it.second,
+ css::uno::UNO_QUERY);
+ if (xController.is() && xController->opensSubToolbar())
+ {
+ // The button should show the last function that was selected from the
+ // dropdown. The controller should know better than us what it was.
+ xController->updateImage();
+ }
+ }
+}
+
+void ToolbarUnoDispatcher::dispose()
+{
+ if (!m_pToolbar)
+ return;
+
+ m_aToolbarOptions.RemoveListenerLink(LINK(this, ToolbarUnoDispatcher, ChangedIconSizeHandler));
+
+ ControllerContainer aControllers;
+ aControllers.swap(maControllers);
+ for (auto const& controller : aControllers)
+ {
+ css::uno::Reference<css::lang::XComponent> xComponent(controller.second,
+ css::uno::UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+
+ m_pToolbar->connect_clicked(Link<const OString&, void>());
+ m_pToolbar = nullptr;
+ m_pBuilder = nullptr;
+}
+
+ToolbarUnoDispatcher::~ToolbarUnoDispatcher() { dispose(); }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */