tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / framework / source / uielement / toolbarmanager.cxx
blob914a0b1b2671b938a368d3d3251d1ea655de80ec
1 /*
2 * This file is part of the LibreOffice project.
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * This file incorporates work covered by the following license notice:
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #include <sal/config.h>
20 #include <sal/log.hxx>
22 #include <cassert>
24 #include <uielement/toolbarmanager.hxx>
26 #include <framework/generictoolbarcontroller.hxx>
27 #include <officecfg/Office/Common.hxx>
28 #include <uielement/styletoolbarcontroller.hxx>
29 #include <properties.h>
30 #include <framework/sfxhelperfunctions.hxx>
31 #include <classes/fwkresid.hxx>
32 #include <classes/resource.hxx>
33 #include <strings.hrc>
34 #include <uielement/toolbarmerger.hxx>
36 #include <com/sun/star/ui/ItemType.hpp>
37 #include <com/sun/star/frame/XDispatchProvider.hpp>
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/awt/XDockableWindow.hpp>
40 #include <com/sun/star/frame/XLayoutManager.hpp>
41 #include <com/sun/star/ui/DockingArea.hpp>
42 #include <com/sun/star/graphic/XGraphic.hpp>
43 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
44 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
45 #include <com/sun/star/frame/ModuleManager.hpp>
46 #include <com/sun/star/frame/theToolbarControllerFactory.hpp>
47 #include <com/sun/star/ui/ItemStyle.hpp>
48 #include <com/sun/star/ui/XUIElementSettings.hpp>
49 #include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
50 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
51 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
52 #include <com/sun/star/ui/ImageType.hpp>
53 #include <com/sun/star/ui/UIElementType.hpp>
54 #include <com/sun/star/lang/DisposedException.hpp>
55 #include <com/sun/star/util/URLTransformer.hpp>
57 #include <svtools/toolboxcontroller.hxx>
58 #include <unotools/cmdoptions.hxx>
59 #include <toolkit/helper/vclunohelper.hxx>
60 #include <unotools/mediadescriptor.hxx>
61 #include <comphelper/propertyvalue.hxx>
62 #include <comphelper/propertysequence.hxx>
63 #include <svtools/miscopt.hxx>
64 #include <svtools/imgdef.hxx>
65 #include <utility>
66 #include <vcl/event.hxx>
67 #include <vcl/graph.hxx>
68 #include <vcl/svapp.hxx>
69 #include <vcl/menu.hxx>
70 #include <vcl/syswin.hxx>
71 #include <vcl/taskpanelist.hxx>
72 #include <vcl/toolbox.hxx>
73 #include <vcl/settings.hxx>
74 #include <vcl/commandinfoprovider.hxx>
75 #include <vcl/weldutils.hxx>
76 #include <tools/debug.hxx>
78 // namespaces
80 using namespace ::com::sun::star::awt;
81 using namespace ::com::sun::star::beans;
82 using namespace ::com::sun::star::uno;
83 using namespace ::com::sun::star::lang;
84 using namespace ::com::sun::star::frame;
85 using namespace ::com::sun::star::graphic;
86 using namespace ::com::sun::star::util;
87 using namespace ::com::sun::star::container;
88 using namespace ::com::sun::star::ui;
89 using namespace ::com::sun::star;
91 namespace framework
94 const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL";
95 const char ITEM_DESCRIPTOR_VISIBLE[] = "IsVisible";
97 const sal_uInt16 STARTID_CUSTOMIZE_POPUPMENU = 1000;
99 static css::uno::Reference< css::frame::XLayoutManager > getLayoutManagerFromFrame(
100 css::uno::Reference< css::frame::XFrame > const & rFrame )
102 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
104 Reference< XPropertySet > xPropSet( rFrame, UNO_QUERY );
105 if ( xPropSet.is() )
109 xPropSet->getPropertyValue(u"LayoutManager"_ustr) >>= xLayoutManager;
111 catch (const RuntimeException&)
113 throw;
115 catch (const Exception&)
120 return xLayoutManager;
122 namespace
125 sal_Int16 getCurrentImageType()
127 sal_Int16 nImageType = css::ui::ImageType::SIZE_DEFAULT;
128 sal_Int16 nCurrentSymbolSize = SvtMiscOptions::GetCurrentSymbolsSize();
129 if (nCurrentSymbolSize == SFX_SYMBOLS_SIZE_LARGE)
130 nImageType |= css::ui::ImageType::SIZE_LARGE;
131 else if (nCurrentSymbolSize == SFX_SYMBOLS_SIZE_32)
132 nImageType |= css::ui::ImageType::SIZE_32;
133 return nImageType;
136 class VclToolBarManager : public ToolBarManagerImpl
138 DECL_LINK(Click, ToolBox*, void);
140 public:
141 VclToolBarManager(VclPtr<ToolBox> pToolbar)
142 : m_pToolBar(std::move(pToolbar))
143 , m_bAddedToTaskPaneList(true)
144 , m_pManager(nullptr)
147 ~VclToolBarManager()
149 OSL_ASSERT( !m_bAddedToTaskPaneList );
152 virtual void Init() override
154 vcl::Window* pWindow = m_pToolBar;
155 while ( pWindow && !pWindow->IsSystemWindow() )
156 pWindow = pWindow->GetParent();
158 if ( pWindow )
159 static_cast<SystemWindow *>(pWindow)->GetTaskPaneList()->AddWindow( m_pToolBar );
162 virtual void Destroy() override
164 OSL_ASSERT( m_pToolBar != nullptr );
165 SolarMutexGuard g;
166 if ( m_bAddedToTaskPaneList )
168 vcl::Window* pWindow = m_pToolBar;
169 while ( pWindow && !pWindow->IsSystemWindow() )
170 pWindow = pWindow->GetParent();
172 if ( pWindow )
173 static_cast<SystemWindow *>(pWindow)->GetTaskPaneList()->RemoveWindow( m_pToolBar );
174 m_bAddedToTaskPaneList = false;
177 // Delete the additional add-ons data
178 for ( ToolBox::ImplToolItems::size_type i = 0; i < m_pToolBar->GetItemCount(); i++ )
180 ToolBoxItemId nItemId = m_pToolBar->GetItemId( i );
181 if ( nItemId > ToolBoxItemId(0) )
182 delete static_cast< AddonsParams* >( m_pToolBar->GetItemData( nItemId ));
185 // #i93173# note we can still be in one of the toolbar's handlers
186 m_pToolBar->SetSelectHdl( Link<ToolBox *, void>() );
187 m_pToolBar->SetActivateHdl( Link<ToolBox *, void>() );
188 m_pToolBar->SetDeactivateHdl( Link<ToolBox *, void>() );
189 m_pToolBar->SetClickHdl( Link<ToolBox *, void>() );
190 m_pToolBar->SetDropdownClickHdl( Link<ToolBox *, void>() );
191 m_pToolBar->SetDoubleClickHdl( Link<ToolBox *, void>() );
192 m_pToolBar->SetStateChangedHdl( Link<StateChangedType const *, void>() );
193 m_pToolBar->SetDataChangedHdl( Link<DataChangedEvent const *, void>() );
195 m_pToolBar.disposeAndClear();
198 virtual css::uno::Reference<css::awt::XWindow> GetInterface() override
200 return VCLUnoHelper::GetInterface(m_pToolBar);
203 virtual void ConnectCallbacks(ToolBarManager* pManager) override
205 m_pManager = pManager;
206 m_pToolBar->SetSelectHdl( LINK( pManager, ToolBarManager, Select) );
207 m_pToolBar->SetClickHdl( LINK( this, VclToolBarManager, Click ) );
208 m_pToolBar->SetDropdownClickHdl( LINK( pManager, ToolBarManager, DropdownClick ) );
209 m_pToolBar->SetDoubleClickHdl( LINK( pManager, ToolBarManager, DoubleClick ) );
210 m_pToolBar->SetStateChangedHdl( LINK( pManager, ToolBarManager, StateChanged ) );
211 m_pToolBar->SetDataChangedHdl( LINK( pManager, ToolBarManager, DataChanged ) );
213 m_pToolBar->SetMenuButtonHdl( LINK( pManager, ToolBarManager, MenuButton ) );
214 m_pToolBar->SetMenuExecuteHdl( LINK( pManager, ToolBarManager, MenuPreExecute ) );
215 m_pToolBar->GetMenu()->SetSelectHdl( LINK( pManager, ToolBarManager, MenuSelect ) );
218 virtual void InsertItem(ToolBoxItemId nId,
219 const OUString& rCommandURL,
220 const OUString& rTooltip,
221 const OUString& rLabel,
222 ToolBoxItemBits nItemBits) override
224 m_pToolBar->InsertItem( nId, rLabel, rCommandURL, nItemBits );
225 m_pToolBar->SetQuickHelpText(nId, rTooltip);
226 m_pToolBar->EnableItem( nId );
227 m_pToolBar->SetItemState( nId, TRISTATE_FALSE );
230 virtual void InsertSeparator() override
232 m_pToolBar->InsertSeparator();
235 virtual void InsertSpace() override
237 m_pToolBar->InsertSpace();
240 virtual void InsertBreak() override
242 m_pToolBar->InsertBreak();
245 virtual ToolBoxItemId GetItemId(sal_uInt16 nPos) override
247 return m_pToolBar->GetItemId(nPos);
250 virtual ToolBoxItemId GetCurItemId() override
252 return m_pToolBar->GetCurItemId();
255 virtual OUString GetItemCommand(ToolBoxItemId nId) override
257 return m_pToolBar->GetItemCommand(nId);
260 virtual sal_uInt16 GetItemCount() override
262 return m_pToolBar->GetItemCount();
265 virtual void SetItemCheckable(ToolBoxItemId nId) override
267 m_pToolBar->SetItemBits( nId, m_pToolBar->GetItemBits( nId ) | ToolBoxItemBits::CHECKABLE );
270 virtual void HideItem(ToolBoxItemId nId, const OUString& /*rCommandURL*/) override
272 m_pToolBar->HideItem( nId );
275 virtual bool IsItemVisible(ToolBoxItemId nId, const OUString& /*rCommandURL*/) override
277 return m_pToolBar->IsItemVisible(nId);
280 virtual void Clear() override
282 m_pToolBar->Clear();
285 virtual void SetName(const OUString& rName) override
287 m_pToolBar->SetText( rName );
290 virtual void SetHelpId(const OUString& rHelpId) override
292 m_pToolBar->SetHelpId( rHelpId );
295 virtual bool WillUsePopupMode() override
297 return m_pToolBar->WillUsePopupMode();
300 virtual bool IsReallyVisible() override
302 return m_pToolBar->IsReallyVisible();
305 virtual void SetIconSize(ToolBoxButtonSize eSize) override
307 m_pToolBar->SetToolboxButtonSize(eSize);
310 virtual vcl::ImageType GetImageSize() override
312 return m_pToolBar->GetImageSize();
315 virtual void SetMenuType(ToolBoxMenuType eType) override
317 m_pToolBar->SetMenuType( eType );
320 virtual void MergeToolbar(ToolBoxItemId & rItemId, sal_uInt16 nFirstItem,
321 const OUString& rModuleIdentifier,
322 CommandToInfoMap& rCommandMap,
323 MergeToolbarInstruction& rInstruction) override
325 ReferenceToolbarPathInfo aRefPoint = ToolBarMerger::FindReferencePoint( m_pToolBar, nFirstItem, rInstruction.aMergePoint );
327 // convert the sequence< sequence< propertyvalue > > structure to
328 // something we can better handle. A vector with item data
329 AddonToolbarItemContainer aItems;
330 ToolBarMerger::ConvertSeqSeqToVector( rInstruction.aMergeToolbarItems, aItems );
332 if ( aRefPoint.bResult )
334 ToolBarMerger::ProcessMergeOperation( m_pToolBar,
335 aRefPoint.nPos,
336 rItemId,
337 rCommandMap,
338 rModuleIdentifier,
339 rInstruction.aMergeCommand,
340 rInstruction.aMergeCommandParameter,
341 aItems );
343 else
345 ToolBarMerger::ProcessMergeFallback( m_pToolBar,
346 rItemId,
347 rCommandMap,
348 rModuleIdentifier,
349 rInstruction.aMergeCommand,
350 rInstruction.aMergeFallback,
351 aItems );
355 virtual void SetItemImage(ToolBoxItemId nId,
356 const OUString& /*rCommandURL*/,
357 const Image& rImage) override
359 m_pToolBar->SetItemImage(nId, rImage);
362 virtual void UpdateSize() override
364 ::Size aSize = m_pToolBar->CalcWindowSizePixel();
365 m_pToolBar->SetOutputSizePixel( aSize );
368 virtual void SetItemWindow(ToolBoxItemId nItemId, vcl::Window* pNewWindow) override
370 m_pToolBar->SetItemWindow( nItemId, pNewWindow );
373 private:
374 VclPtr<ToolBox> m_pToolBar;
375 bool m_bAddedToTaskPaneList;
376 ToolBarManager* m_pManager;
379 IMPL_LINK_NOARG(VclToolBarManager, Click, ToolBox*, void)
381 m_pManager->OnClick();
384 class WeldToolBarManager : public ToolBarManagerImpl
386 DECL_LINK(Click, const OUString&, void);
387 DECL_LINK(ToggleMenuHdl, const OUString&, void);
389 public:
390 WeldToolBarManager(weld::Toolbar* pToolbar,
391 weld::Builder* pBuilder)
392 : m_pWeldedToolBar(pToolbar)
393 , m_pBuilder(pBuilder)
394 , m_pManager(nullptr)
395 , m_nCurrentId(0)
398 virtual void Init() override {}
400 virtual void Destroy() override {}
402 virtual css::uno::Reference<css::awt::XWindow> GetInterface() override
404 return new weld::TransportAsXWindow(m_pWeldedToolBar, m_pBuilder);
407 virtual void ConnectCallbacks(ToolBarManager* pManager) override
409 m_pManager = pManager;
410 m_pWeldedToolBar->connect_clicked(LINK(this, WeldToolBarManager, Click));
411 m_pWeldedToolBar->connect_menu_toggled(LINK(this, WeldToolBarManager, ToggleMenuHdl));
414 virtual void InsertItem(ToolBoxItemId nId,
415 const OUString& rCommandURL,
416 const OUString& rTooltip,
417 const OUString& rLabel,
418 ToolBoxItemBits /*nItemBits*/) override
420 m_aCommandToId[rCommandURL] = nId;
421 m_aIdToCommand[nId] = rCommandURL;
422 m_aCommandOrder.push_back(rCommandURL);
424 m_pWeldedToolBar->insert_item(m_aCommandOrder.size(), rCommandURL);
425 m_pWeldedToolBar->set_item_tooltip_text(rCommandURL, rTooltip);
426 m_pWeldedToolBar->set_item_label(rCommandURL, rLabel);
427 m_pWeldedToolBar->set_item_sensitive(rCommandURL, true);
428 m_pWeldedToolBar->set_item_active(rCommandURL, false);
431 virtual void InsertSeparator() override
433 m_pWeldedToolBar->append_separator(u""_ustr);
436 virtual void InsertSpace() override {}
438 virtual void InsertBreak() override {}
440 virtual ToolBoxItemId GetItemId(sal_uInt16 nPos) override
442 return m_aCommandToId[m_aCommandOrder[nPos]];
445 virtual ToolBoxItemId GetCurItemId() override
447 return m_nCurrentId;
450 virtual OUString GetItemCommand(ToolBoxItemId nId) override
452 return m_aIdToCommand[nId];
455 virtual sal_uInt16 GetItemCount() override
457 return m_aCommandOrder.size();
460 virtual void SetItemCheckable(ToolBoxItemId /*nId*/) override {}
462 virtual void HideItem(ToolBoxItemId /*nId*/, const OUString& rCommandURL) override
464 m_pWeldedToolBar->set_item_visible(rCommandURL, false);
467 virtual bool IsItemVisible(ToolBoxItemId /*nId*/, const OUString& rCommandURL) override
469 return m_pWeldedToolBar->get_item_visible(rCommandURL);
472 virtual void Clear() override {}
474 virtual void SetName(const OUString& /*rName*/) override {}
476 virtual void SetHelpId(const OUString& /*rHelpId*/) override {}
478 virtual bool WillUsePopupMode() override { return true; }
480 virtual bool IsReallyVisible() override { return true; }
482 virtual void SetIconSize(ToolBoxButtonSize /*eSize*/) override {}
484 virtual vcl::ImageType GetImageSize() override
486 return vcl::ImageType::Size32;
489 virtual void SetMenuType(ToolBoxMenuType /*eType*/) override {}
491 virtual void MergeToolbar(ToolBoxItemId & /*rItemId*/,
492 sal_uInt16 /*nFirstItem*/,
493 const OUString& /*rModuleIdentifier*/,
494 CommandToInfoMap& /*rCommandMap*/,
495 MergeToolbarInstruction& /*rInstruction*/) override {}
497 virtual void SetItemImage(ToolBoxItemId /*nId*/,
498 const OUString& rCommandURL,
499 const Image& rImage) override
501 m_pWeldedToolBar->set_item_image(rCommandURL, Graphic(rImage).GetXGraphic());
504 virtual void UpdateSize() override {}
506 virtual void SetItemWindow(ToolBoxItemId /*nItemId*/, vcl::Window* /*pNewWindow*/) override {}
508 private:
509 weld::Toolbar* m_pWeldedToolBar;
510 weld::Builder* m_pBuilder;
511 ToolBarManager* m_pManager;
512 ToolBoxItemId m_nCurrentId;
513 std::map<const OUString, ToolBoxItemId> m_aCommandToId;
514 std::map<ToolBoxItemId, OUString> m_aIdToCommand;
515 std::vector<OUString> m_aCommandOrder;
518 IMPL_LINK(WeldToolBarManager, Click, const OUString&, rCommand, void)
520 m_nCurrentId = m_aCommandToId[rCommand];
521 m_pManager->OnClick(true);
524 IMPL_LINK(WeldToolBarManager, ToggleMenuHdl, const OUString&, rCommand, void)
526 m_nCurrentId = m_aCommandToId[rCommand];
527 m_pManager->OnDropdownClick(false);
530 } // end anonymous namespace
532 // XInterface, XTypeProvider, XServiceInfo
534 ToolBarManager::ToolBarManager( const Reference< XComponentContext >& rxContext,
535 const Reference< XFrame >& rFrame,
536 OUString aResourceName,
537 ToolBox* pToolBar ) :
538 m_bDisposed( false ),
539 m_bFrameActionRegistered( false ),
540 m_bUpdateControllers( false ),
541 m_eSymbolSize(SvtMiscOptions::GetCurrentSymbolsSize()),
542 m_nContextMinPos(0),
543 m_pImpl( new VclToolBarManager( pToolBar ) ),
544 m_pToolBar( pToolBar ),
545 m_pWeldedToolBar( nullptr ),
546 m_aResourceName(std::move( aResourceName )),
547 m_xFrame( rFrame ),
548 m_xContext( rxContext ),
549 m_aAsyncUpdateControllersTimer( "framework::ToolBarManager m_aAsyncUpdateControllersTimer" ),
550 m_sIconTheme( SvtMiscOptions::GetIconTheme() )
552 Init();
555 ToolBarManager::ToolBarManager( const Reference< XComponentContext >& rxContext,
556 const Reference< XFrame >& rFrame,
557 OUString aResourceName,
558 weld::Toolbar* pToolBar,
559 weld::Builder* pBuilder ) :
560 m_bDisposed( false ),
561 m_bFrameActionRegistered( false ),
562 m_bUpdateControllers( false ),
563 m_eSymbolSize( SvtMiscOptions::GetCurrentSymbolsSize() ),
564 m_nContextMinPos(0),
565 m_pImpl( new WeldToolBarManager( pToolBar, pBuilder ) ),
566 m_pWeldedToolBar( pToolBar ),
567 m_aResourceName(std::move( aResourceName )),
568 m_xFrame( rFrame ),
569 m_xContext( rxContext ),
570 m_aAsyncUpdateControllersTimer( "framework::ToolBarManager m_aAsyncUpdateControllersTimer" ),
571 m_sIconTheme( SvtMiscOptions::GetIconTheme() )
573 Init();
576 void ToolBarManager::Init()
578 OSL_ASSERT( m_xContext.is() );
580 m_pImpl->Init();
582 m_xToolbarControllerFactory = frame::theToolbarControllerFactory::get( m_xContext );
583 m_xURLTransformer = URLTransformer::create( m_xContext );
585 m_pImpl->ConnectCallbacks(this);
587 if (m_eSymbolSize == SFX_SYMBOLS_SIZE_LARGE)
588 m_pImpl->SetIconSize(ToolBoxButtonSize::Large);
589 else if (m_eSymbolSize == SFX_SYMBOLS_SIZE_32)
590 m_pImpl->SetIconSize(ToolBoxButtonSize::Size32);
591 else
592 m_pImpl->SetIconSize(ToolBoxButtonSize::Small);
594 // enables a menu for clipped items and customization
595 SvtCommandOptions aCmdOptions;
596 ToolBoxMenuType nMenuType = ToolBoxMenuType::ClippedItems;
597 if ( !aCmdOptions.LookupDisabled( u"CreateDialog"_ustr))
598 nMenuType |= ToolBoxMenuType::Customize;
600 m_pImpl->SetMenuType( nMenuType );
602 // set name for testtool, the useful part is after the last '/'
603 sal_Int32 idx = m_aResourceName.lastIndexOf('/');
604 idx++; // will become 0 if '/' not found: use full string
605 std::u16string_view aToolbarName = m_aResourceName.subView( idx );
606 OUString aHelpIdAsString = ".HelpId:" + OUString::Concat(aToolbarName);
607 m_pImpl->SetHelpId( aHelpIdAsString );
609 m_aAsyncUpdateControllersTimer.SetTimeout( 50 );
610 m_aAsyncUpdateControllersTimer.SetInvokeHandler( LINK( this, ToolBarManager, AsyncUpdateControllersHdl ) );
612 SvtMiscOptions().AddListenerLink( LINK( this, ToolBarManager, MiscOptionsChanged ) );
615 ToolBarManager::~ToolBarManager()
617 assert(!m_aAsyncUpdateControllersTimer.IsActive());
618 assert(!m_pToolBar); // must be disposed by ToolbarLayoutManager
621 void ToolBarManager::Destroy()
623 m_pImpl->Destroy();
625 SvtMiscOptions().RemoveListenerLink( LINK( this, ToolBarManager, MiscOptionsChanged ) );
628 ToolBox* ToolBarManager::GetToolBar() const
630 SolarMutexGuard g;
631 return m_pToolBar;
634 void ToolBarManager::CheckAndUpdateImages()
636 SolarMutexGuard g;
637 bool bRefreshImages = false;
639 sal_Int16 eNewSymbolSize = SvtMiscOptions::GetCurrentSymbolsSize();
641 if (m_eSymbolSize != eNewSymbolSize )
643 bRefreshImages = true;
644 m_eSymbolSize = eNewSymbolSize;
647 const OUString sCurrentIconTheme = SvtMiscOptions::GetIconTheme();
648 if ( m_sIconTheme != sCurrentIconTheme )
650 bRefreshImages = true;
651 m_sIconTheme = sCurrentIconTheme;
654 // Refresh images if requested
655 if ( bRefreshImages )
656 RefreshImages();
659 void ToolBarManager::RefreshImages()
661 SolarMutexGuard g;
663 if (m_eSymbolSize == SFX_SYMBOLS_SIZE_LARGE)
664 m_pImpl->SetIconSize(ToolBoxButtonSize::Large);
665 else if (m_eSymbolSize == SFX_SYMBOLS_SIZE_32)
666 m_pImpl->SetIconSize(ToolBoxButtonSize::Size32);
667 else
668 m_pImpl->SetIconSize(ToolBoxButtonSize::Small);
670 for ( auto const& it : m_aControllerMap )
672 Reference< XSubToolbarController > xController( it.second, UNO_QUERY );
673 if ( xController.is() && xController->opensSubToolbar() )
675 // The button should show the last function that was selected from the
676 // dropdown. The controller should know better than us what it was.
677 xController->updateImage();
679 else
681 OUString aCommandURL = m_pImpl->GetItemCommand( it.first );
682 vcl::ImageType eImageType = m_pImpl->GetImageSize();
683 Image aImage = vcl::CommandInfoProvider::GetImageForCommand(aCommandURL, m_xFrame, eImageType);
684 // Try also to query for add-on images before giving up and use an
685 // empty image.
686 bool bBigImages = eImageType != vcl::ImageType::Size16;
687 if ( !aImage )
688 aImage = Image(framework::AddonsOptions().GetImageFromURL(aCommandURL, bBigImages));
689 m_pImpl->SetItemImage( it.first, aCommandURL, aImage );
693 m_pImpl->UpdateSize();
696 void ToolBarManager::UpdateControllers()
699 if( officecfg::Office::Common::Misc::DisableUICustomization::get() )
701 Any a;
702 Reference< XLayoutManager > xLayoutManager;
703 Reference< XPropertySet > xFramePropSet( m_xFrame, UNO_QUERY );
704 if ( xFramePropSet.is() )
705 a = xFramePropSet->getPropertyValue(u"LayoutManager"_ustr);
706 a >>= xLayoutManager;
707 Reference< XDockableWindow > xDockable( m_pImpl->GetInterface(), UNO_QUERY );
708 if ( xLayoutManager.is() && xDockable.is() )
710 css::awt::Point aPoint;
711 aPoint.X = aPoint.Y = SAL_MAX_INT32;
712 xLayoutManager->dockWindow( m_aResourceName, DockingArea_DOCKINGAREA_DEFAULT, aPoint );
713 xLayoutManager->lockWindow( m_aResourceName );
717 if ( !m_bUpdateControllers )
719 m_bUpdateControllers = true;
720 for (auto const& controller : m_aControllerMap)
724 Reference< XUpdatable > xUpdatable( controller.second, UNO_QUERY );
725 if ( xUpdatable.is() )
726 xUpdatable->update();
728 catch (const Exception&)
733 m_bUpdateControllers = false;
736 //for update toolbar controller via Support Visible
737 void ToolBarManager::UpdateController( const css::uno::Reference< css::frame::XToolbarController >& xController)
740 if ( !m_bUpdateControllers )
742 m_bUpdateControllers = true;
744 { if(xController.is())
746 Reference< XUpdatable > xUpdatable( xController, UNO_QUERY );
747 if ( xUpdatable.is() )
748 xUpdatable->update();
751 catch (const Exception&)
756 m_bUpdateControllers = false;
759 void ToolBarManager::frameAction( const FrameActionEvent& Action )
761 SolarMutexGuard g;
762 if ( Action.Action == FrameAction_CONTEXT_CHANGED && !m_bDisposed )
764 if (m_aImageController)
765 m_aImageController->update();
766 m_aAsyncUpdateControllersTimer.Start();
770 void SAL_CALL ToolBarManager::disposing( const EventObject& Source )
772 SolarMutexGuard g;
774 if ( m_bDisposed )
775 return;
777 RemoveControllers();
779 if ( m_xDocImageManager.is() )
783 m_xDocImageManager->removeConfigurationListener(
784 Reference< XUIConfigurationListener >(this) );
786 catch (const Exception&)
791 if ( m_xModuleImageManager.is() )
795 m_xModuleImageManager->removeConfigurationListener(
796 Reference< XUIConfigurationListener >(this) );
798 catch (const Exception&)
803 m_xDocImageManager.clear();
804 m_xModuleImageManager.clear();
806 if ( Source.Source == Reference< XInterface >( m_xFrame, UNO_QUERY ))
807 m_xFrame.clear();
809 m_xContext.clear();
812 // XComponent
813 void SAL_CALL ToolBarManager::dispose()
815 Reference< XComponent > xThis(this);
818 EventObject aEvent( xThis );
819 std::unique_lock aGuard(m_mutex);
820 m_aListenerContainer.disposeAndClear( aGuard, aEvent );
823 SolarMutexGuard g;
825 if (m_bDisposed)
827 return;
830 RemoveControllers();
832 if ( m_xDocImageManager.is() )
836 m_xDocImageManager->removeConfigurationListener(
837 Reference< XUIConfigurationListener >(this) );
839 catch (const Exception&)
843 m_xDocImageManager.clear();
844 if ( m_xModuleImageManager.is() )
848 m_xModuleImageManager->removeConfigurationListener(
849 Reference< XUIConfigurationListener >(this) );
851 catch (const Exception&)
855 m_xModuleImageManager.clear();
857 if ( m_aOverflowManager.is() )
859 m_aOverflowManager->dispose();
860 m_aOverflowManager.clear();
863 // We have to destroy our toolbar instance now.
864 Destroy();
865 m_pToolBar.clear();
867 if ( m_bFrameActionRegistered && m_xFrame.is() )
871 m_xFrame->removeFrameActionListener( Reference< XFrameActionListener >(this) );
873 catch (const Exception&)
878 m_xFrame.clear();
879 m_xContext.clear();
881 // stop timer to prevent timer events after dispose
882 // do it last because other calls could restart timer in StateChanged()
883 m_aAsyncUpdateControllersTimer.Stop();
885 m_bDisposed = true;
889 void SAL_CALL ToolBarManager::addEventListener( const Reference< XEventListener >& xListener )
891 SolarMutexGuard g;
893 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
894 if ( m_bDisposed )
895 throw DisposedException();
897 std::unique_lock aGuard(m_mutex);
898 m_aListenerContainer.addInterface( aGuard, xListener );
901 void SAL_CALL ToolBarManager::removeEventListener( const Reference< XEventListener >& xListener )
903 std::unique_lock aGuard(m_mutex);
904 m_aListenerContainer.removeInterface( aGuard, xListener );
907 // XUIConfigurationListener
908 void SAL_CALL ToolBarManager::elementInserted( const css::ui::ConfigurationEvent& Event )
910 impl_elementChanged(false,Event);
913 void SAL_CALL ToolBarManager::elementRemoved( const css::ui::ConfigurationEvent& Event )
915 impl_elementChanged(true,Event);
917 void ToolBarManager::impl_elementChanged(bool const isRemove,
918 const css::ui::ConfigurationEvent& Event)
920 SolarMutexGuard g;
922 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
923 if ( m_bDisposed )
924 return;
926 Reference< XNameAccess > xNameAccess;
927 sal_Int16 nImageType = sal_Int16();
928 sal_Int16 nCurrentImageType = getCurrentImageType();
930 if (!(( Event.aInfo >>= nImageType ) &&
931 ( nImageType == nCurrentImageType ) &&
932 ( Event.Element >>= xNameAccess )))
933 return;
935 sal_Int16 nImageInfo( 1 );
936 Reference< XInterface > xIfacDocImgMgr( m_xDocImageManager, UNO_QUERY );
937 if ( xIfacDocImgMgr == Event.Source )
938 nImageInfo = 0;
940 const Sequence< OUString > aSeq = xNameAccess->getElementNames();
941 for ( OUString const & commandName : aSeq )
943 CommandToInfoMap::iterator pIter = m_aCommandMap.find( commandName );
944 if ( pIter != m_aCommandMap.end() && ( pIter->second.nImageInfo >= nImageInfo ))
946 if (isRemove)
948 Image aImage;
949 if (( pIter->second.nImageInfo == 0 ) && ( pIter->second.nImageInfo == nImageInfo ))
951 // Special case: An image from the document image manager has been removed.
952 // It is possible that we have an image at our module image manager. Before
953 // we can remove our image we have to ask our module image manager.
954 Sequence< OUString > aCmdURLSeq{ pIter->first };
955 Sequence< Reference< XGraphic > > aGraphicSeq;
956 aGraphicSeq = m_xModuleImageManager->getImages( nImageType, aCmdURLSeq );
957 aImage = Image( aGraphicSeq[0] );
960 setToolBarImage(aImage,pIter);
961 } // if (isRemove)
962 else
964 Reference< XGraphic > xGraphic;
965 if ( xNameAccess->getByName( commandName ) >>= xGraphic )
967 Image aImage( xGraphic );
968 setToolBarImage(aImage,pIter);
970 pIter->second.nImageInfo = nImageInfo;
975 void ToolBarManager::setToolBarImage(const Image& rImage,
976 const CommandToInfoMap::const_iterator& rIter)
978 const ::std::vector<ToolBoxItemId>& rIDs = rIter->second.aIds;
979 m_pImpl->SetItemImage( rIter->second.nId, rIter->first, rImage );
980 for (auto const& it : rIDs)
982 m_pImpl->SetItemImage(it, rIter->first, rImage);
986 void SAL_CALL ToolBarManager::elementReplaced( const css::ui::ConfigurationEvent& Event )
988 impl_elementChanged(false,Event);
991 void ToolBarManager::RemoveControllers()
993 DBG_TESTSOLARMUTEX();
994 assert(!m_bDisposed);
996 m_aSubToolBarControllerMap.clear();
998 if (m_aImageController)
999 m_aImageController->dispose();
1000 m_aImageController.clear();
1002 // i90033
1003 // Remove item window pointers from the toolbar. They were
1004 // destroyed by the dispose() at the XComponent. This is needed
1005 // as VCL code later tries to access the item window data in certain
1006 // dtors where the item window is already invalid!
1007 for ( ToolBox::ImplToolItems::size_type i = 0; i < m_pImpl->GetItemCount(); i++ )
1009 ToolBoxItemId nItemId = m_pImpl->GetItemId( i );
1010 if ( nItemId > ToolBoxItemId(0) )
1012 Reference< XComponent > xComponent( m_aControllerMap[ nItemId ], UNO_QUERY );
1013 if ( xComponent.is() )
1017 xComponent->dispose();
1019 catch (const Exception&)
1023 m_pImpl->SetItemWindow(nItemId, nullptr);
1026 m_aControllerMap.clear();
1029 void ToolBarManager::CreateControllers()
1031 Reference< XWindow > xToolbarWindow = m_pImpl->GetInterface();
1033 css::util::URL aURL;
1034 bool bHasDisabledEntries = SvtCommandOptions().HasEntriesDisabled();
1035 SvtCommandOptions aCmdOptions;
1037 for ( ToolBox::ImplToolItems::size_type i = 0; i < m_pImpl->GetItemCount(); i++ )
1039 ToolBoxItemId nId = m_pImpl->GetItemId( i );
1040 if ( nId == ToolBoxItemId(0) )
1041 continue;
1043 bool bInit( true );
1044 bool bCreate( true );
1045 Reference< XStatusListener > xController;
1047 OUString aCommandURL( m_pImpl->GetItemCommand( nId ) );
1048 // Command can be just an alias to another command.
1049 auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(aCommandURL, m_aModuleIdentifier);
1050 OUString aRealCommandURL( vcl::CommandInfoProvider::GetRealCommandForCommand(aProperties) );
1051 if ( !aRealCommandURL.isEmpty() )
1052 aCommandURL = aRealCommandURL;
1054 if ( bHasDisabledEntries )
1056 aURL.Complete = aCommandURL;
1057 m_xURLTransformer->parseStrict( aURL );
1058 if ( aCmdOptions.LookupDisabled( aURL.Path ))
1060 m_aControllerMap[ nId ] = xController;
1061 m_pImpl->HideItem( nId, aCommandURL );
1062 continue;
1066 if ( m_xToolbarControllerFactory.is() &&
1067 m_xToolbarControllerFactory->hasController( aCommandURL, m_aModuleIdentifier ))
1069 Reference<XMultiServiceFactory> xMSF(m_xContext->getServiceManager(), UNO_QUERY_THROW);
1070 Sequence< Any > aArgs( comphelper::InitAnyPropertySequence( {
1071 { "ModuleIdentifier", Any(m_aModuleIdentifier) },
1072 { "Frame", Any(m_xFrame) },
1073 { "ServiceManager", Any(xMSF) },
1074 { "ParentWindow", Any(xToolbarWindow) },
1075 { "Identifier", Any(sal_uInt16(nId)) },
1076 } ));
1077 xController.set( m_xToolbarControllerFactory->createInstanceWithArgumentsAndContext( aCommandURL, aArgs, m_xContext ),
1078 UNO_QUERY );
1079 bInit = false; // Initialization is done through the factory service
1082 if (( aCommandURL == ".uno:OpenUrl" ) && ( !m_pImpl->IsItemVisible(nId, aCommandURL)))
1083 bCreate = false;
1085 if ( !xController.is() && bCreate )
1087 if ( m_pToolBar )
1088 xController = CreateToolBoxController( m_xFrame, m_pToolBar, nId, aCommandURL );
1089 if ( !xController )
1091 if ( aCommandURL.startsWith( ".uno:StyleApply?" ) )
1093 xController.set( new StyleToolbarController( m_xContext, m_xFrame, aCommandURL ));
1094 m_pImpl->SetItemCheckable( nId );
1096 else if ( aCommandURL.startsWith( "private:resource/" ) )
1098 xController.set( m_xContext->getServiceManager()->createInstanceWithContext(
1099 u"com.sun.star.comp.framework.GenericPopupToolbarController"_ustr, m_xContext ), UNO_QUERY );
1101 else if ( m_pToolBar && m_pToolBar->GetItemData( nId ) != nullptr )
1103 // retrieve additional parameters
1104 OUString aControlType = static_cast< AddonsParams* >( m_pToolBar->GetItemData( nId ))->aControlType;
1105 sal_uInt16 nWidth = static_cast< AddonsParams* >( m_pToolBar->GetItemData( nId ))->nWidth;
1107 xController.set(
1108 ToolBarMerger::CreateController( m_xContext,
1109 m_xFrame,
1110 m_pToolBar,
1111 aCommandURL,
1112 nId,
1113 nWidth,
1114 aControlType ).get(), UNO_QUERY );
1117 else
1119 if ( m_pToolBar )
1120 xController.set( new GenericToolbarController( m_xContext, m_xFrame, m_pToolBar, nId, aCommandURL ));
1121 else
1122 xController.set( new GenericToolbarController( m_xContext, m_xFrame, *m_pWeldedToolBar, aCommandURL ));
1127 // Accessibility support: Set toggle button role for specific commands
1128 const sal_Int32 nProps = vcl::CommandInfoProvider::GetPropertiesForCommand(aCommandURL, m_aModuleIdentifier);
1129 if (nProps & UICOMMANDDESCRIPTION_PROPERTIES_TOGGLEBUTTON)
1130 m_pImpl->SetItemCheckable(nId);
1132 // Associate ID and controller to be able to retrieve
1133 // the controller from the ID later.
1134 m_aControllerMap[ nId ] = xController;
1136 // Fill sub-toolbars into our hash-map
1137 Reference< XSubToolbarController > xSubToolBar( xController, UNO_QUERY );
1138 if ( xSubToolBar.is() && xSubToolBar->opensSubToolbar() )
1140 OUString aSubToolBarName = xSubToolBar->getSubToolbarName();
1141 if ( !aSubToolBarName.isEmpty() )
1143 SubToolBarToSubToolBarControllerMap::iterator pIter =
1144 m_aSubToolBarControllerMap.find( aSubToolBarName );
1145 if ( pIter == m_aSubToolBarControllerMap.end() )
1147 SubToolBarControllerVector aSubToolBarVector;
1148 aSubToolBarVector.push_back( xSubToolBar );
1149 m_aSubToolBarControllerMap.emplace(
1150 aSubToolBarName, aSubToolBarVector );
1152 else
1153 pIter->second.push_back( xSubToolBar );
1157 Reference< XInitialization > xInit( xController, UNO_QUERY );
1158 if ( xInit.is() )
1160 if ( bInit )
1162 Reference<XMultiServiceFactory> xMSF(m_xContext->getServiceManager(), UNO_QUERY_THROW);
1163 Sequence< Any > aArgs( comphelper::InitAnyPropertySequence( {
1164 { "Frame", Any(m_xFrame) },
1165 { "CommandURL", Any(aCommandURL) },
1166 { "ServiceManager", Any(xMSF) },
1167 { "ParentWindow", Any(xToolbarWindow) },
1168 { "ModuleIdentifier", Any(m_aModuleIdentifier) },
1169 { "Identifier", Any(sal_uInt16(nId)) },
1170 } ));
1172 xInit->initialize( aArgs );
1175 // Request an item window from the toolbar controller and set it at the VCL toolbar
1176 Reference< XToolbarController > xTbxController( xController, UNO_QUERY );
1177 if ( xTbxController.is() && xToolbarWindow.is() )
1179 Reference< XWindow > xWindow = xTbxController->createItemWindow( xToolbarWindow );
1180 if ( xWindow.is() )
1182 VclPtr<vcl::Window> pItemWin = VCLUnoHelper::GetWindow( xWindow );
1183 if ( pItemWin )
1185 WindowType nType = pItemWin->GetType();
1186 if ( m_pToolBar && (nType == WindowType::LISTBOX || nType == WindowType::MULTILISTBOX || nType == WindowType::COMBOBOX) )
1187 pItemWin->SetAccessibleName( m_pToolBar->GetItemText( nId ) );
1188 m_pImpl->SetItemWindow( nId, pItemWin );
1194 //for update Controller via support visible state
1195 Reference< XPropertySet > xPropSet( xController, UNO_QUERY );
1196 if ( xPropSet.is() )
1200 bool bSupportVisible = true;
1201 Any a( xPropSet->getPropertyValue(u"SupportsVisible"_ustr) );
1202 a >>= bSupportVisible;
1203 if (bSupportVisible)
1205 Reference< XToolbarController > xTbxController( xController, UNO_QUERY );
1206 UpdateController(xTbxController);
1209 catch (const RuntimeException&)
1211 throw;
1213 catch (const Exception&)
1219 AddFrameActionListener();
1222 void ToolBarManager::AddFrameActionListener()
1224 if ( !m_bFrameActionRegistered && m_xFrame.is() )
1226 m_bFrameActionRegistered = true;
1227 m_xFrame->addFrameActionListener( Reference< XFrameActionListener >(this) );
1231 // static
1232 ToolBoxItemBits ToolBarManager::ConvertStyleToToolboxItemBits( sal_Int32 nStyle )
1234 ToolBoxItemBits nItemBits( ToolBoxItemBits::NONE );
1235 if ( nStyle & css::ui::ItemStyle::RADIO_CHECK )
1236 nItemBits |= ToolBoxItemBits::RADIOCHECK;
1237 if ( nStyle & css::ui::ItemStyle::ALIGN_LEFT )
1238 nItemBits |= ToolBoxItemBits::LEFT;
1239 if ( nStyle & css::ui::ItemStyle::AUTO_SIZE )
1240 nItemBits |= ToolBoxItemBits::AUTOSIZE;
1241 if ( nStyle & css::ui::ItemStyle::DROP_DOWN )
1242 nItemBits |= ToolBoxItemBits::DROPDOWN;
1243 if ( nStyle & css::ui::ItemStyle::REPEAT )
1244 nItemBits |= ToolBoxItemBits::REPEAT;
1245 if ( nStyle & css::ui::ItemStyle::DROPDOWN_ONLY )
1246 nItemBits |= ToolBoxItemBits::DROPDOWNONLY;
1247 if ( nStyle & css::ui::ItemStyle::TEXT )
1248 nItemBits |= ToolBoxItemBits::TEXT_ONLY;
1249 if ( nStyle & css::ui::ItemStyle::ICON )
1250 nItemBits |= ToolBoxItemBits::ICON_ONLY;
1252 return nItemBits;
1255 void ToolBarManager::InitImageManager()
1257 Reference< XModuleManager2 > xModuleManager = ModuleManager::create( m_xContext );
1258 if ( !m_xDocImageManager.is() )
1260 Reference< XModel > xModel( GetModelFromFrame() );
1261 if ( xModel.is() )
1263 Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY );
1264 if ( xSupplier.is() )
1266 Reference< XUIConfigurationManager > xDocUICfgMgr = xSupplier->getUIConfigurationManager();
1267 m_xDocImageManager.set( xDocUICfgMgr->getImageManager(), UNO_QUERY );
1268 m_xDocImageManager->addConfigurationListener(
1269 Reference< XUIConfigurationListener >(this) );
1276 m_aModuleIdentifier = xModuleManager->identify( Reference< XInterface >( m_xFrame, UNO_QUERY ) );
1278 catch (const Exception&)
1282 if ( !m_xModuleImageManager.is() )
1284 Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier =
1285 theModuleUIConfigurationManagerSupplier::get( m_xContext );
1286 Reference< XUIConfigurationManager > xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier );
1287 m_xModuleImageManager.set( xUICfgMgr->getImageManager(), UNO_QUERY );
1288 m_xModuleImageManager->addConfigurationListener( Reference< XUIConfigurationListener >(this) );
1292 void ToolBarManager::FillToolbar( const Reference< XIndexAccess >& rItemContainer,
1293 const Reference< XIndexAccess >& rContextData,
1294 const OUString& rContextToolbarName )
1296 OString aTbxName = OUStringToOString( m_aResourceName, RTL_TEXTENCODING_ASCII_US );
1297 SAL_INFO( "fwk.uielement", "framework (cd100003) ::ToolBarManager::FillToolbar " << aTbxName );
1299 SolarMutexGuard g;
1301 if ( m_bDisposed )
1302 return;
1304 InitImageManager();
1306 RemoveControllers();
1308 // reset and fill command map
1309 m_pImpl->Clear();
1310 m_aControllerMap.clear();
1311 m_aCommandMap.clear();
1313 ToolBoxItemId nId(1), nAddonId(1000);
1314 FillToolbarFromContainer( rItemContainer, m_aResourceName, nId, nAddonId );
1315 m_aContextResourceName = rContextToolbarName;
1316 if ( rContextData.is() )
1318 m_pImpl->InsertSeparator();
1319 FillToolbarFromContainer( rContextData, m_aContextResourceName, nId, nAddonId );
1322 // Request images for all toolbar items. Must be done before CreateControllers as
1323 // some controllers need access to the image.
1324 RequestImages();
1326 // Create controllers after we set the images. There are controllers which needs
1327 // an image at the toolbar at creation time!
1328 CreateControllers();
1330 // Notify controllers that they are now correctly initialized and can start listening
1331 // toolbars that will open in popup mode will be updated immediately to avoid flickering
1332 if( m_pImpl->WillUsePopupMode() )
1333 UpdateControllers();
1334 else if ( m_pImpl->IsReallyVisible() )
1336 m_aAsyncUpdateControllersTimer.Start();
1339 // Try to retrieve UIName from the container property set and set it as the title
1340 // if it is not empty.
1341 Reference< XPropertySet > xPropSet( rItemContainer, UNO_QUERY );
1342 if ( !xPropSet.is() )
1343 return;
1347 OUString aUIName;
1348 xPropSet->getPropertyValue(u"UIName"_ustr) >>= aUIName;
1349 if ( !aUIName.isEmpty() )
1350 m_pImpl->SetName( aUIName );
1352 catch (const Exception&)
1357 void ToolBarManager::FillToolbarFromContainer( const Reference< XIndexAccess >& rItemContainer,
1358 const OUString& rResourceName, ToolBoxItemId& nId, ToolBoxItemId& nAddonId )
1360 m_nContextMinPos = m_pImpl->GetItemCount();
1361 CommandInfo aCmdInfo;
1362 for ( sal_Int32 n = 0; n < rItemContainer->getCount(); n++ )
1364 Sequence< PropertyValue > aProps;
1365 OUString aCommandURL;
1366 OUString aLabel;
1367 OUString aTooltip;
1368 sal_uInt16 nType( css::ui::ItemType::DEFAULT );
1369 sal_uInt32 nStyle( 0 );
1373 if ( rItemContainer->getByIndex( n ) >>= aProps )
1375 bool bIsVisible( true );
1376 for (PropertyValue const& prop : aProps)
1378 if ( prop.Name == ITEM_DESCRIPTOR_COMMANDURL )
1379 prop.Value >>= aCommandURL;
1380 else if ( prop.Name == "Label" )
1381 prop.Value >>= aLabel;
1382 else if ( prop.Name == "Tooltip" )
1383 prop.Value >>= aTooltip;
1384 else if ( prop.Name == "Type" )
1385 prop.Value >>= nType;
1386 else if ( prop.Name == ITEM_DESCRIPTOR_VISIBLE )
1387 prop.Value >>= bIsVisible;
1388 else if ( prop.Name == "Style" )
1389 prop.Value >>= nStyle;
1392 if (!aCommandURL.isEmpty() && vcl::CommandInfoProvider::IsExperimental(aCommandURL, m_aModuleIdentifier) &&
1393 !officecfg::Office::Common::Misc::ExperimentalMode::get())
1395 continue;
1398 if (( nType == css::ui::ItemType::DEFAULT ) && !aCommandURL.isEmpty() )
1400 auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(aCommandURL, m_aModuleIdentifier);
1401 if (!aProperties.hasElements()) // E.g., user-provided macro command?
1402 aProperties = std::move(aProps); // Use existing info, including user-provided Label
1404 ToolBoxItemBits nItemBits = ConvertStyleToToolboxItemBits( nStyle );
1406 if ( aTooltip.isEmpty() )
1407 aTooltip = vcl::CommandInfoProvider::GetTooltipForCommand(aCommandURL, aProperties, m_xFrame);
1409 if ( aLabel.isEmpty() )
1410 aLabel = vcl::CommandInfoProvider::GetLabelForCommand(aProperties);
1412 m_pImpl->InsertItem(nId, aCommandURL, aTooltip, aLabel, nItemBits);
1414 // Fill command map. It stores all our commands and from what
1415 // image manager we got our image. So we can decide if we have to use an
1416 // image from a notification message.
1417 auto pIter = m_aCommandMap.emplace( aCommandURL, aCmdInfo );
1418 if ( pIter.second )
1420 aCmdInfo.nId = nId;
1421 pIter.first->second.nId = nId;
1423 else
1425 pIter.first->second.aIds.push_back( nId );
1428 if ( !bIsVisible )
1429 m_pImpl->HideItem( nId, aCommandURL );
1431 ++nId;
1433 else if ( nType == css::ui::ItemType::SEPARATOR_LINE )
1435 m_pImpl->InsertSeparator();
1437 else if ( nType == css::ui::ItemType::SEPARATOR_SPACE )
1439 m_pImpl->InsertSpace();
1441 else if ( nType == css::ui::ItemType::SEPARATOR_LINEBREAK )
1443 m_pImpl->InsertBreak();
1447 catch (const css::lang::IndexOutOfBoundsException&)
1449 break;
1453 // Support add-on toolbar merging here. Working directly on the toolbar object is much
1454 // simpler and faster.
1455 MergeToolbarInstructionContainer aMergeInstructionContainer;
1457 // Retrieve the toolbar name from the resource name
1458 OUString aToolbarName( rResourceName );
1459 sal_Int32 nIndex = aToolbarName.lastIndexOf( '/' );
1460 if (( nIndex > 0 ) && ( nIndex < aToolbarName.getLength() ))
1461 aToolbarName = aToolbarName.copy( nIndex+1 );
1463 AddonsOptions().GetMergeToolbarInstructions( aToolbarName, aMergeInstructionContainer );
1465 if ( !aMergeInstructionContainer.empty() )
1467 const sal_uInt32 nCount = aMergeInstructionContainer.size();
1468 for ( sal_uInt32 i=0; i < nCount; i++ )
1470 MergeToolbarInstruction& rInstruction = aMergeInstructionContainer[i];
1471 if ( ToolBarMerger::IsCorrectContext( rInstruction.aMergeContext, m_aModuleIdentifier ))
1473 m_pImpl->MergeToolbar(nAddonId, m_nContextMinPos, m_aModuleIdentifier, m_aCommandMap, rInstruction);
1479 void ToolBarManager::FillAddonToolbar( const Sequence< Sequence< PropertyValue > >& rAddonToolbar )
1481 if (!m_pToolBar)
1482 return;
1484 SolarMutexGuard g;
1486 if ( m_bDisposed )
1487 return;
1489 InitImageManager();
1491 RemoveControllers();
1493 // reset and fill command map
1494 m_pToolBar->Clear();
1495 m_aControllerMap.clear();
1496 m_aCommandMap.clear();
1498 ToolBoxItemId nId( 1 );
1499 CommandInfo aCmdInfo;
1500 for ( const Sequence< PropertyValue >& rSeq : rAddonToolbar )
1502 OUString aURL;
1503 OUString aTitle;
1504 OUString aContext;
1505 OUString aTarget;
1506 OUString aControlType;
1507 sal_uInt16 nWidth( 0 );
1509 ToolBarMerger::ConvertSequenceToValues( rSeq, aURL, aTitle, aTarget, aContext, aControlType, nWidth );
1511 if ( ToolBarMerger::IsCorrectContext( aContext, m_aModuleIdentifier ) )
1513 if ( aURL == "private:separator" )
1515 ToolBox::ImplToolItems::size_type nCount = m_pToolBar->GetItemCount();
1516 if ( nCount > 0 && m_pToolBar->GetItemType( nCount-1 ) != ToolBoxItemType::SEPARATOR )
1517 m_pToolBar->InsertSeparator();
1519 else
1521 m_pToolBar->InsertItem( nId, aTitle, aURL );
1523 OUString aShortcut(vcl::CommandInfoProvider::GetCommandShortcut(aURL, m_xFrame));
1524 if (!aShortcut.isEmpty())
1525 m_pToolBar->SetQuickHelpText(nId, aTitle + " (" + aShortcut + ")");
1527 // Create AddonsParams to hold additional information we will need in the future
1528 AddonsParams* pRuntimeItemData = new AddonsParams;
1529 pRuntimeItemData->aControlType = aControlType;
1530 pRuntimeItemData->nWidth = nWidth;
1531 m_pToolBar->SetItemData( nId, pRuntimeItemData );
1533 // Fill command map. It stores all our commands and from what
1534 // image manager we got our image. So we can decide if we have to use an
1535 // image from a notification message.
1536 auto pIter = m_aCommandMap.emplace( aURL, aCmdInfo );
1537 if ( pIter.second )
1539 aCmdInfo.nId = nId;
1540 pIter.first->second.nId = nId;
1542 else
1544 pIter.first->second.aIds.push_back( nId );
1546 ++nId;
1551 // Don't setup images yet, AddonsToolbarWrapper::populateImages does that.
1552 // (But some controllers might need an image at the toolbar at creation time!)
1553 CreateControllers();
1555 // Notify controllers that they are now correctly initialized and can start listening.
1556 UpdateControllers();
1559 void ToolBarManager::FillOverflowToolbar( ToolBox const * pParent )
1561 if (!m_pToolBar)
1562 return;
1564 CommandInfo aCmdInfo;
1565 bool bInsertSeparator = false;
1566 for ( ToolBox::ImplToolItems::size_type i = 0; i < pParent->GetItemCount(); ++i )
1568 ToolBoxItemId nId = pParent->GetItemId( i );
1569 if ( pParent->IsItemClipped( nId ) )
1571 if ( bInsertSeparator )
1573 m_pToolBar->InsertSeparator();
1574 bInsertSeparator = false;
1577 const OUString aCommandURL( pParent->GetItemCommand( nId ) );
1578 m_pToolBar->InsertItem( nId, pParent->GetItemText( nId ), aCommandURL );
1579 m_pToolBar->SetQuickHelpText( nId, pParent->GetQuickHelpText( nId ) );
1581 // Handle possible add-on controls.
1582 AddonsParams* pAddonParams = static_cast< AddonsParams* >( pParent->GetItemData( nId ) );
1583 if ( pAddonParams )
1584 m_pToolBar->SetItemData( nId, new AddonsParams( *pAddonParams ) );
1586 // Fill command map. It stores all our commands and from what
1587 // image manager we got our image. So we can decide if we have to use an
1588 // image from a notification message.
1589 auto pIter = m_aCommandMap.emplace( aCommandURL, aCmdInfo );
1590 if ( pIter.second )
1592 aCmdInfo.nId = nId;
1593 pIter.first->second.nId = nId;
1595 else
1597 pIter.first->second.aIds.push_back( nId );
1600 else
1602 ToolBoxItemType eType = pParent->GetItemType( i );
1603 if ( m_pToolBar->GetItemCount() &&
1604 ( eType == ToolBoxItemType::SEPARATOR || eType == ToolBoxItemType::BREAK ) )
1605 bInsertSeparator = true;
1609 InitImageManager();
1611 // Request images for all toolbar items. Must be done before CreateControllers as
1612 // some controllers need access to the image.
1613 RequestImages();
1615 // Create controllers after we set the images. There are controllers which needs
1616 // an image at the toolbar at creation time!
1617 CreateControllers();
1619 // Notify controllers that they are now correctly initialized and can start listening
1620 // toolbars that will open in popup mode will be updated immediately to avoid flickering
1621 UpdateControllers();
1624 void ToolBarManager::RequestImages()
1627 // Request images from image manager
1628 Sequence< OUString > aCmdURLSeq( comphelper::mapKeysToSequence(m_aCommandMap) );
1629 Sequence< Reference< XGraphic > > aDocGraphicSeq;
1630 Sequence< Reference< XGraphic > > aModGraphicSeq;
1632 sal_Int16 nImageType = getCurrentImageType();
1634 if ( m_xDocImageManager.is() )
1635 aDocGraphicSeq = m_xDocImageManager->getImages(nImageType, aCmdURLSeq);
1636 aModGraphicSeq = m_xModuleImageManager->getImages(nImageType, aCmdURLSeq);
1638 sal_uInt32 i = 0;
1639 CommandToInfoMap::iterator pIter = m_aCommandMap.begin();
1640 CommandToInfoMap::iterator pEnd = m_aCommandMap.end();
1641 while ( pIter != pEnd )
1643 Image aImage;
1644 if ( aDocGraphicSeq.hasElements() )
1645 aImage = Image( aDocGraphicSeq[i] );
1646 if ( !aImage )
1648 aImage = Image( aModGraphicSeq[i] );
1649 // Try also to query for add-on images before giving up and use an
1650 // empty image.
1651 if ( !aImage )
1652 aImage = Image(framework::AddonsOptions().GetImageFromURL(aCmdURLSeq[i], SvtMiscOptions::AreCurrentSymbolsLarge()));
1654 pIter->second.nImageInfo = 1; // mark image as module based
1656 else
1658 pIter->second.nImageInfo = 0; // mark image as document based
1660 setToolBarImage(aImage,pIter);
1661 ++pIter;
1662 ++i;
1665 assert(!m_aImageController); // an existing one isn't disposed here
1666 m_aImageController = new ImageOrientationController(m_xContext, m_xFrame, m_pImpl->GetInterface(), m_aModuleIdentifier);
1667 m_aImageController->update();
1670 void ToolBarManager::notifyRegisteredControllers( const OUString& aUIElementName, const OUString& aCommand )
1672 SolarMutexClearableGuard aGuard;
1673 if ( m_aSubToolBarControllerMap.empty() )
1674 return;
1676 SubToolBarToSubToolBarControllerMap::const_iterator pIter =
1677 m_aSubToolBarControllerMap.find( aUIElementName );
1679 if ( pIter == m_aSubToolBarControllerMap.end() )
1680 return;
1682 const SubToolBarControllerVector& rSubToolBarVector = pIter->second;
1683 if ( rSubToolBarVector.empty() )
1684 return;
1686 SubToolBarControllerVector aNotifyVector = rSubToolBarVector;
1687 aGuard.clear();
1689 const sal_uInt32 nCount = aNotifyVector.size();
1690 for ( sal_uInt32 i=0; i < nCount; i++ )
1694 const Reference< XSubToolbarController >& xController = aNotifyVector[i];
1695 if ( xController.is() )
1696 xController->functionSelected( aCommand );
1698 catch (const RuntimeException&)
1700 throw;
1702 catch (const Exception&)
1708 void ToolBarManager::HandleClick(ClickAction eClickAction)
1710 SolarMutexGuard g;
1712 if ( m_bDisposed )
1713 return;
1715 ToolBoxItemId nId( m_pImpl->GetCurItemId() );
1716 ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
1717 if ( pIter == m_aControllerMap.end() )
1718 return;
1720 Reference< XToolbarController > xController( pIter->second, UNO_QUERY );
1722 if ( xController.is() )
1724 switch (eClickAction)
1726 case ClickAction::Click:
1727 xController->click();
1728 break;
1730 case ClickAction::DblClick:
1731 xController->doubleClick();
1732 break;
1734 case ClickAction::Execute:
1735 xController->execute(0);
1736 break;
1741 void ToolBarManager::OnClick(bool bUseExecute)
1743 if (bUseExecute)
1744 HandleClick(ClickAction::Execute);
1745 else
1746 HandleClick(ClickAction::Click);
1749 IMPL_LINK_NOARG(ToolBarManager, DropdownClick, ToolBox *, void)
1751 OnDropdownClick(true);
1754 void ToolBarManager::OnDropdownClick(bool bCreatePopupWindow)
1756 SolarMutexGuard g;
1758 if ( m_bDisposed )
1759 return;
1761 ToolBoxItemId nId( m_pImpl->GetCurItemId() );
1762 ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
1763 if ( pIter == m_aControllerMap.end() )
1764 return;
1766 Reference< XToolbarController > xController( pIter->second, UNO_QUERY );
1768 if ( xController.is() )
1770 if (bCreatePopupWindow)
1772 Reference< XWindow > xWin = xController->createPopupWindow();
1773 if ( xWin.is() )
1774 xWin->setFocus();
1776 else
1778 xController->click();
1783 IMPL_LINK_NOARG(ToolBarManager, DoubleClick, ToolBox *, void)
1785 HandleClick(ClickAction::DblClick);
1788 Reference< XModel > ToolBarManager::GetModelFromFrame() const
1790 Reference< XController > xController = m_xFrame->getController();
1791 Reference< XModel > xModel;
1792 if ( xController.is() )
1793 xModel = xController->getModel();
1795 return xModel;
1798 bool ToolBarManager::IsPluginMode() const
1800 bool bPluginMode( false );
1802 if ( m_xFrame.is() )
1804 Reference< XModel > xModel = GetModelFromFrame();
1805 if ( xModel.is() )
1807 Sequence< PropertyValue > aSeq = xModel->getArgs();
1808 utl::MediaDescriptor aMediaDescriptor( aSeq );
1809 bPluginMode = aMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_VIEWONLY, false );
1813 return bPluginMode;
1816 void ToolBarManager::AddCustomizeMenuItems(ToolBox const * pToolBar)
1818 if (!m_pToolBar)
1819 return;
1821 // No config menu entries if command ".uno:ConfigureDialog" is not enabled
1822 Reference< XDispatch > xDisp;
1823 css::util::URL aURL;
1824 if ( m_xFrame.is() )
1826 Reference< XDispatchProvider > xProv( m_xFrame, UNO_QUERY );
1827 aURL.Complete = ".uno:ConfigureDialog";
1828 m_xURLTransformer->parseStrict( aURL );
1829 if ( xProv.is() )
1830 xDisp = xProv->queryDispatch( aURL, OUString(), 0 );
1832 if ( !xDisp.is() || IsPluginMode() )
1833 return;
1836 // popup menu for quick customization
1837 bool bHideDisabledEntries = !officecfg::Office::Common::View::Menu::DontHideDisabledEntry::get();
1839 ::PopupMenu *pMenu = pToolBar->GetMenu();
1841 // copy all menu items 'Visible buttons, Customize toolbar, Dock toolbar,
1842 // Dock all Toolbars) from the loaded resource into the toolbar menu
1843 sal_uInt16 nGroupLen = pMenu->GetItemCount();
1844 if (nGroupLen)
1845 pMenu->InsertSeparator();
1847 VclPtr<PopupMenu> xVisibleItemsPopupMenu;
1849 if (!m_aResourceName.startsWith("private:resource/toolbar/addon_"))
1851 pMenu->InsertItem(MENUITEM_TOOLBAR_VISIBLEBUTTON, FwkResId(STR_TOOLBAR_VISIBLE_BUTTONS));
1852 xVisibleItemsPopupMenu = VclPtr<PopupMenu>::Create();
1853 pMenu->SetPopupMenu(MENUITEM_TOOLBAR_VISIBLEBUTTON, xVisibleItemsPopupMenu);
1855 if (m_pToolBar->IsCustomize())
1857 pMenu->InsertItem(MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR, FwkResId(STR_TOOLBAR_CUSTOMIZE_TOOLBAR));
1858 pMenu->SetItemCommand(MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR, u".uno:ConfigureToolboxVisible"_ustr);
1860 pMenu->InsertSeparator();
1863 if (pToolBar->IsFloatingMode())
1865 pMenu->InsertItem(MENUITEM_TOOLBAR_DOCKTOOLBAR, FwkResId(STR_TOOLBAR_DOCK_TOOLBAR));
1866 pMenu->SetAccelKey(MENUITEM_TOOLBAR_DOCKTOOLBAR, vcl::KeyCode(KEY_F10, true, true, false, false));
1868 else
1870 pMenu->InsertItem(MENUITEM_TOOLBAR_UNDOCKTOOLBAR, FwkResId(STR_TOOLBAR_UNDOCK_TOOLBAR));
1871 pMenu->SetAccelKey(MENUITEM_TOOLBAR_UNDOCKTOOLBAR, vcl::KeyCode(KEY_F10, true, true, false, false));
1874 pMenu->InsertItem(MENUITEM_TOOLBAR_DOCKALLTOOLBAR, FwkResId(STR_TOOLBAR_DOCK_ALL_TOOLBARS));
1875 pMenu->InsertSeparator();
1876 pMenu->InsertItem(MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION, FwkResId(STR_TOOLBAR_LOCK_TOOLBAR), MenuItemBits::CHECKABLE);
1877 pMenu->InsertItem(MENUITEM_TOOLBAR_CLOSE, FwkResId(STR_TOOLBAR_CLOSE_TOOLBAR));
1879 if (m_pToolBar->IsCustomize())
1881 bool bIsFloating( false );
1883 DockingManager* pDockMgr = vcl::Window::GetDockingManager();
1884 if ( pDockMgr )
1885 bIsFloating = pDockMgr->IsFloating( m_pToolBar );
1887 if ( !bIsFloating )
1889 pMenu->EnableItem(MENUITEM_TOOLBAR_DOCKALLTOOLBAR, false);
1890 Reference< XDockableWindow > xDockable( VCLUnoHelper::GetInterface( m_pToolBar ), UNO_QUERY );
1891 if( xDockable.is() )
1892 pMenu->CheckItem(MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION, xDockable->isLocked());
1894 else
1895 pMenu->EnableItem(MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION, false);
1897 if (officecfg::Office::Common::Misc::DisableUICustomization::get())
1899 pMenu->EnableItem(MENUITEM_TOOLBAR_VISIBLEBUTTON, false);
1900 pMenu->EnableItem(MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR, false);
1901 pMenu->EnableItem(MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION, false);
1904 // Disable menu item CLOSE if the toolbar has no closer
1905 if( !(pToolBar->GetFloatStyle() & WB_CLOSEABLE) )
1906 pMenu->EnableItem(MENUITEM_TOOLBAR_CLOSE, false);
1908 // Temporary stores a Command --> Url map to update contextual menu with the
1909 // correct icons. The popup icons are by default the same as those in the
1910 // toolbar. They are not correct for contextual popup menu.
1911 std::map< OUString, Image > commandToImage;
1913 if (xVisibleItemsPopupMenu)
1915 // Go through all toolbar items and add them to the context menu
1916 for ( ToolBox::ImplToolItems::size_type nPos = 0; nPos < m_pToolBar->GetItemCount(); ++nPos )
1918 if ( m_pToolBar->GetItemType(nPos) == ToolBoxItemType::BUTTON )
1920 ToolBoxItemId nId = m_pToolBar->GetItemId(nPos);
1921 OUString aCommandURL = m_pToolBar->GetItemCommand( nId );
1922 xVisibleItemsPopupMenu->InsertItem( STARTID_CUSTOMIZE_POPUPMENU+nPos, m_pToolBar->GetItemText( nId ), MenuItemBits::CHECKABLE );
1923 xVisibleItemsPopupMenu->CheckItem( STARTID_CUSTOMIZE_POPUPMENU+nPos, m_pToolBar->IsItemVisible( nId ) );
1924 xVisibleItemsPopupMenu->SetItemCommand( STARTID_CUSTOMIZE_POPUPMENU+nPos, aCommandURL );
1925 Image aImage(vcl::CommandInfoProvider::GetImageForCommand(aCommandURL, m_xFrame));
1926 commandToImage[aCommandURL] = aImage;
1927 xVisibleItemsPopupMenu->SetItemImage( STARTID_CUSTOMIZE_POPUPMENU+nPos, aImage );
1928 vcl::KeyCode aKeyCodeShortCut = vcl::CommandInfoProvider::GetCommandKeyCodeShortcut( aCommandURL, m_xFrame );
1929 xVisibleItemsPopupMenu->SetAccelKey( STARTID_CUSTOMIZE_POPUPMENU+nPos, aKeyCodeShortCut );
1931 else
1933 xVisibleItemsPopupMenu->InsertSeparator();
1938 // Now we go through all the contextual menu to update the icons
1939 // and accelerator key shortcuts
1940 std::map< OUString, Image >::iterator it;
1941 for ( sal_uInt16 nPos = 0; nPos < pMenu->GetItemCount(); ++nPos )
1943 sal_uInt16 nId = pMenu->GetItemId( nPos );
1944 OUString cmdUrl = pMenu->GetItemCommand( nId );
1945 it = commandToImage.find( cmdUrl );
1946 if (it != commandToImage.end()) {
1947 pMenu->SetItemImage( nId, it->second );
1949 vcl::KeyCode aKeyCodeShortCut = vcl::CommandInfoProvider::GetCommandKeyCodeShortcut( cmdUrl, m_xFrame );
1950 if ( aKeyCodeShortCut.GetFullCode() != 0 )
1951 pMenu->SetAccelKey( nId, aKeyCodeShortCut );
1955 // Set the title of the menu
1956 pMenu->SetText( pToolBar->GetText() );
1958 if ( bHideDisabledEntries )
1959 pMenu->RemoveDisabledEntries();
1962 void ToolBarManager::ToggleButton( const OUString& rResourceName, std::u16string_view rCommand )
1964 Reference< XLayoutManager > xLayoutManager = getLayoutManagerFromFrame( m_xFrame );
1965 if ( !xLayoutManager.is() )
1966 return;
1968 Reference< XUIElementSettings > xUIElementSettings( xLayoutManager->getElement( rResourceName ), UNO_QUERY );
1969 if ( !xUIElementSettings.is() )
1970 return;
1972 Reference< XIndexContainer > xItemContainer( xUIElementSettings->getSettings( true ), UNO_QUERY );
1973 sal_Int32 nCount = xItemContainer->getCount();
1974 for ( sal_Int32 i = 0; i < nCount; i++ )
1976 Sequence< PropertyValue > aProp;
1977 sal_Int32 nVisibleIndex( -1 );
1978 OUString aCommandURL;
1979 bool bVisible( false );
1981 if ( xItemContainer->getByIndex( i ) >>= aProp )
1983 for ( sal_Int32 j = 0; j < aProp.getLength(); j++ )
1985 if ( aProp[j].Name == ITEM_DESCRIPTOR_COMMANDURL )
1987 aProp[j].Value >>= aCommandURL;
1989 else if ( aProp[j].Name == ITEM_DESCRIPTOR_VISIBLE )
1991 aProp[j].Value >>= bVisible;
1992 nVisibleIndex = j;
1996 if (( aCommandURL == rCommand ) && ( nVisibleIndex >= 0 ))
1998 // We have found the requested item, toggle the visible flag
1999 // and write back the configuration settings to the toolbar
2000 aProp.getArray()[nVisibleIndex].Value <<= !bVisible;
2003 xItemContainer->replaceByIndex( i, Any( aProp ));
2004 xUIElementSettings->setSettings( xItemContainer );
2005 Reference< XPropertySet > xPropSet( xUIElementSettings, UNO_QUERY );
2006 if ( xPropSet.is() )
2008 Reference< XUIConfigurationPersistence > xUICfgMgr;
2009 if (( xPropSet->getPropertyValue(u"ConfigurationSource"_ustr) >>= xUICfgMgr ) && ( xUICfgMgr.is() ))
2010 xUICfgMgr->store();
2013 catch (const Exception&)
2016 break;
2022 IMPL_LINK( ToolBarManager, MenuButton, ToolBox*, pToolBar, void )
2024 SolarMutexGuard g;
2026 if ( m_bDisposed )
2027 return;
2029 assert( !m_aOverflowManager.is() );
2031 VclPtrInstance<ToolBox> pOverflowToolBar( pToolBar, WB_BORDER | WB_SCROLL );
2032 pOverflowToolBar->SetLineSpacing(true);
2033 m_aOverflowManager.set( new ToolBarManager( m_xContext, m_xFrame, OUString(), pOverflowToolBar ) );
2034 m_aOverflowManager->FillOverflowToolbar( pToolBar );
2036 ::Size aActSize( pOverflowToolBar->GetSizePixel() );
2037 ::Size aSize( pOverflowToolBar->CalcWindowSizePixel() );
2038 aSize.setWidth( aActSize.Width() );
2039 pOverflowToolBar->SetOutputSizePixel( aSize );
2041 aSize = pOverflowToolBar->CalcPopupWindowSizePixel();
2042 pOverflowToolBar->SetSizePixel( aSize );
2044 pOverflowToolBar->EnableDocking();
2045 pOverflowToolBar->AddEventListener( LINK( this, ToolBarManager, OverflowEventListener ) );
2046 vcl::Window::GetDockingManager()->StartPopupMode( pToolBar, pOverflowToolBar, FloatWinPopupFlags::AllMouseButtonClose );
2048 // send HOME key to subtoolbar in order to select first item if keyboard activated
2049 if(pToolBar->IsKeyEvent() )
2051 ::KeyEvent aEvent( 0, vcl::KeyCode( KEY_HOME ) );
2052 pOverflowToolBar->KeyInput(aEvent);
2056 IMPL_LINK( ToolBarManager, OverflowEventListener, VclWindowEvent&, rWindowEvent, void )
2058 if ( rWindowEvent.GetId() != VclEventId::WindowEndPopupMode )
2059 return;
2061 if ( m_aOverflowManager.is() )
2063 m_aOverflowManager->dispose();
2064 m_aOverflowManager.clear();
2068 IMPL_LINK( ToolBarManager, MenuPreExecute, ToolBox*, pToolBar, void )
2070 SolarMutexGuard g;
2072 if ( m_bDisposed )
2073 return;
2075 AddCustomizeMenuItems( pToolBar );
2078 IMPL_LINK( ToolBarManager, MenuSelect, Menu*, pMenu, bool )
2080 // We have to hold a reference to ourself as it is possible that we will be disposed and
2081 // our refcount could be zero (destruction) otherwise.
2082 Reference< XInterface > xKeepAlive( static_cast< OWeakObject* >( this ), UNO_QUERY );
2085 // The guard must be in its own context as the we can get destroyed when our
2086 // own xInterface reference get destroyed!
2087 SolarMutexGuard g;
2089 if ( m_bDisposed )
2090 return true;
2092 switch ( pMenu->GetCurItemId() )
2094 case MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR:
2096 Reference< XDispatch > xDisp;
2097 css::util::URL aURL;
2098 if ( m_xFrame.is() )
2100 Reference< XDispatchProvider > xProv( m_xFrame, UNO_QUERY );
2101 aURL.Complete = ".uno:ConfigureDialog";
2102 m_xURLTransformer->parseStrict( aURL );
2103 if ( xProv.is() )
2104 xDisp = xProv->queryDispatch( aURL, OUString(), 0 );
2107 if ( xDisp.is() )
2109 Sequence< PropertyValue > aPropSeq{ comphelper::makePropertyValue(
2110 u"ResourceURL"_ustr, m_aResourceName) };
2112 xDisp->dispatch( aURL, aPropSeq );
2114 break;
2117 case MENUITEM_TOOLBAR_UNDOCKTOOLBAR:
2119 ExecuteInfo* pExecuteInfo = new ExecuteInfo;
2121 pExecuteInfo->aToolbarResName = m_aResourceName;
2122 pExecuteInfo->nCmd = EXEC_CMD_UNDOCKTOOLBAR;
2123 pExecuteInfo->xLayoutManager = getLayoutManagerFromFrame( m_xFrame );
2125 Application::PostUserEvent( LINK(nullptr, ToolBarManager, ExecuteHdl_Impl), pExecuteInfo );
2126 break;
2129 case MENUITEM_TOOLBAR_DOCKTOOLBAR:
2131 ExecuteInfo* pExecuteInfo = new ExecuteInfo;
2133 pExecuteInfo->aToolbarResName = m_aResourceName;
2134 pExecuteInfo->nCmd = EXEC_CMD_DOCKTOOLBAR;
2135 pExecuteInfo->xLayoutManager = getLayoutManagerFromFrame( m_xFrame );
2137 Application::PostUserEvent( LINK(nullptr, ToolBarManager, ExecuteHdl_Impl), pExecuteInfo );
2138 break;
2141 case MENUITEM_TOOLBAR_DOCKALLTOOLBAR:
2143 ExecuteInfo* pExecuteInfo = new ExecuteInfo;
2145 pExecuteInfo->aToolbarResName = m_aResourceName;
2146 pExecuteInfo->nCmd = EXEC_CMD_DOCKALLTOOLBARS;
2147 pExecuteInfo->xLayoutManager = getLayoutManagerFromFrame( m_xFrame );
2149 Application::PostUserEvent( LINK(nullptr, ToolBarManager, ExecuteHdl_Impl), pExecuteInfo );
2150 break;
2153 case MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION:
2155 Reference< XLayoutManager > xLayoutManager = getLayoutManagerFromFrame( m_xFrame );
2156 if ( xLayoutManager.is() )
2158 Reference< XDockableWindow > xDockable( VCLUnoHelper::GetInterface( m_pToolBar ), UNO_QUERY );
2160 if( xDockable->isLocked() )
2161 xLayoutManager->unlockWindow( m_aResourceName );
2162 else
2163 xLayoutManager->lockWindow( m_aResourceName );
2165 break;
2168 case MENUITEM_TOOLBAR_CLOSE:
2170 ExecuteInfo* pExecuteInfo = new ExecuteInfo;
2172 pExecuteInfo->aToolbarResName = m_aResourceName;
2173 pExecuteInfo->nCmd = EXEC_CMD_CLOSETOOLBAR;
2174 pExecuteInfo->xLayoutManager = getLayoutManagerFromFrame( m_xFrame );
2175 pExecuteInfo->xWindow = VCLUnoHelper::GetInterface( m_pToolBar );
2177 Application::PostUserEvent( LINK(nullptr, ToolBarManager, ExecuteHdl_Impl), pExecuteInfo );
2178 break;
2181 default:
2183 sal_uInt16 nId = pMenu->GetCurItemId();
2184 if(( nId > 0 ) && ( nId < TOOLBOX_MENUITEM_START ))
2185 // Items in the "enable/disable" sub-menu
2187 // toggle toolbar button visibility
2188 OUString aCommand = pMenu->GetItemCommand( nId );
2189 if (m_aContextResourceName.isEmpty() ||
2190 nId - STARTID_CUSTOMIZE_POPUPMENU < m_nContextMinPos)
2191 ToggleButton(m_aResourceName, aCommand);
2192 else
2193 ToggleButton(m_aContextResourceName, aCommand);
2195 break;
2200 return true;
2203 IMPL_LINK_NOARG(ToolBarManager, Select, ToolBox *, void)
2205 if ( m_bDisposed )
2206 return;
2208 sal_Int16 nKeyModifier( static_cast<sal_Int16>(m_pToolBar->GetModifier()) );
2209 ToolBoxItemId nId( m_pToolBar->GetCurItemId() );
2211 ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
2212 if ( pIter != m_aControllerMap.end() )
2214 Reference< XToolbarController > xController( pIter->second, UNO_QUERY );
2216 if ( xController.is() )
2217 xController->execute( nKeyModifier );
2221 IMPL_LINK( ToolBarManager, StateChanged, StateChangedType const *, pStateChangedType, void )
2223 if ( m_bDisposed )
2224 return;
2226 if ( *pStateChangedType == StateChangedType::ControlBackground )
2228 CheckAndUpdateImages();
2230 else if ( *pStateChangedType == StateChangedType::Visible )
2232 if ( m_pToolBar->IsReallyVisible() )
2234 m_aAsyncUpdateControllersTimer.Start();
2237 else if ( *pStateChangedType == StateChangedType::InitShow )
2239 m_aAsyncUpdateControllersTimer.Start();
2243 IMPL_LINK( ToolBarManager, DataChanged, DataChangedEvent const *, pDataChangedEvent, void )
2245 if ((( pDataChangedEvent->GetType() == DataChangedEventType::SETTINGS ) ||
2246 ( pDataChangedEvent->GetType() == DataChangedEventType::DISPLAY )) &&
2247 ( pDataChangedEvent->GetFlags() & AllSettingsFlags::STYLE ))
2249 CheckAndUpdateImages();
2252 for ( ToolBox::ImplToolItems::size_type nPos = 0; nPos < m_pToolBar->GetItemCount(); ++nPos )
2254 const ToolBoxItemId nId = m_pToolBar->GetItemId(nPos);
2255 vcl::Window* pWindow = m_pToolBar->GetItemWindow( nId );
2256 if ( pWindow )
2258 const DataChangedEvent& rDCEvt( *pDataChangedEvent );
2259 pWindow->DataChanged( rDCEvt );
2263 if ( !m_pToolBar->IsFloatingMode() &&
2264 m_pToolBar->IsVisible() )
2266 // Resize toolbar, layout manager is resize listener and will calc
2267 // the layout automatically.
2268 ::Size aSize( m_pToolBar->CalcWindowSizePixel() );
2269 m_pToolBar->SetOutputSizePixel( aSize );
2273 IMPL_LINK_NOARG(ToolBarManager, MiscOptionsChanged, LinkParamNone*, void)
2275 CheckAndUpdateImages();
2278 IMPL_LINK_NOARG(ToolBarManager, AsyncUpdateControllersHdl, Timer *, void)
2280 // The guard must be in its own context as the we can get destroyed when our
2281 // own xInterface reference get destroyed!
2282 Reference< XComponent > xThis(this);
2284 SolarMutexGuard g;
2286 if ( m_bDisposed )
2287 return;
2289 // Request to update our controllers
2290 m_aAsyncUpdateControllersTimer.Stop();
2291 UpdateControllers();
2294 IMPL_STATIC_LINK( ToolBarManager, ExecuteHdl_Impl, void*, p, void )
2296 ExecuteInfo* pExecuteInfo = static_cast<ExecuteInfo*>(p);
2299 // Asynchronous execution as this can lead to our own destruction!
2300 if (( pExecuteInfo->nCmd == EXEC_CMD_CLOSETOOLBAR ) &&
2301 ( pExecuteInfo->xLayoutManager.is() ) &&
2302 ( pExecuteInfo->xWindow.is() ))
2304 // Use docking window close to close the toolbar. The toolbar layout manager is
2305 // listener and will react correctly according to the context sensitive
2306 // flag of our toolbar.
2307 VclPtr<vcl::Window> pWin = VCLUnoHelper::GetWindow( pExecuteInfo->xWindow );
2308 DockingWindow* pDockWin = dynamic_cast< DockingWindow* >( pWin.get() );
2309 if ( pDockWin )
2310 pDockWin->Close();
2312 else if (( pExecuteInfo->nCmd == EXEC_CMD_UNDOCKTOOLBAR ) &&
2313 ( pExecuteInfo->xLayoutManager.is() ))
2315 pExecuteInfo->xLayoutManager->floatWindow( pExecuteInfo->aToolbarResName );
2317 else if (( pExecuteInfo->nCmd == EXEC_CMD_DOCKTOOLBAR ) &&
2318 ( pExecuteInfo->xLayoutManager.is() ))
2320 css::awt::Point aPoint;
2321 aPoint.X = aPoint.Y = SAL_MAX_INT32;
2322 pExecuteInfo->xLayoutManager->dockWindow( pExecuteInfo->aToolbarResName,
2323 DockingArea_DOCKINGAREA_DEFAULT,
2324 aPoint );
2326 else if (( pExecuteInfo->nCmd == EXEC_CMD_DOCKALLTOOLBARS ) &&
2327 ( pExecuteInfo->xLayoutManager.is() ))
2329 pExecuteInfo->xLayoutManager->dockAllWindows( UIElementType::TOOLBAR );
2332 catch (const Exception&)
2336 delete pExecuteInfo;
2340 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */