Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / framework / source / uielement / toolbarsmenucontroller.cxx
blob1378645ce07ee6e9e0da5cd8b9f15c9d53015e5e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <uielement/toolbarsmenucontroller.hxx>
22 #include <algorithm>
23 #include <string_view>
24 #include <unordered_map>
26 #include <services.h>
27 #include <strings.hrc>
28 #include <classes/fwkresid.hxx>
29 #include <framework/sfxhelperfunctions.hxx>
30 #include <uiconfiguration/windowstateproperties.hxx>
32 #include <com/sun/star/beans/PropertyValue.hpp>
33 #include <com/sun/star/awt/MenuItemStyle.hpp>
34 #include <com/sun/star/frame/ModuleManager.hpp>
35 #include <com/sun/star/frame/XDispatchProvider.hpp>
36 #include <com/sun/star/util/XURLTransformer.hpp>
37 #include <com/sun/star/beans/XPropertySet.hpp>
38 #include <com/sun/star/frame/XLayoutManager.hpp>
39 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
40 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
41 #include <com/sun/star/ui/UIElementType.hpp>
42 #include <com/sun/star/ui/theWindowStateConfiguration.hpp>
44 #include <comphelper/propertyvalue.hxx>
45 #include <officecfg/Office/Common.hxx>
46 #include <vcl/svapp.hxx>
47 #include <vcl/settings.hxx>
48 #include <vcl/commandinfoprovider.hxx>
49 #include <rtl/ustrbuf.hxx>
50 #include <toolkit/awt/vclxmenu.hxx>
51 #include <toolkit/helper/vclunohelper.hxx>
52 #include <vcl/window.hxx>
53 #include <unotools/cmdoptions.hxx>
54 #include <unotools/collatorwrapper.hxx>
55 #include <unotools/syslocale.hxx>
56 #include <cppuhelper/supportsservice.hxx>
58 // Defines
60 using namespace ::com::sun::star;
61 using namespace ::com::sun::star::uno;
62 using namespace ::com::sun::star::lang;
63 using namespace ::com::sun::star::frame;
64 using namespace ::com::sun::star::beans;
65 using namespace ::com::sun::star::util;
66 using namespace ::com::sun::star::container;
67 using namespace ::com::sun::star::ui;
69 constexpr OUStringLiteral CMD_RESTOREVISIBILITY = u".cmd:RestoreVisibility";
70 constexpr OUStringLiteral CMD_LOCKTOOLBARS = u".uno:ToolbarLock";
72 constexpr OUStringLiteral STATIC_CMD_PART = u".uno:AvailableToolbars?Toolbar:string=";
73 const char STATIC_INTERNAL_CMD_PART[] = ".cmd:";
75 namespace framework
78 typedef std::unordered_map< OUString, OUString > ToolbarHashMap;
80 namespace {
82 struct ToolBarEntry
84 OUString aUIName;
85 OUString aCommand;
86 bool bVisible;
87 const CollatorWrapper* pCollatorWrapper;
92 static bool CompareToolBarEntry( const ToolBarEntry& aOne, const ToolBarEntry& aTwo )
94 sal_Int32 nComp = aOne.pCollatorWrapper->compareString( aOne.aUIName, aTwo.aUIName );
96 return nComp < 0;
99 static Reference< XLayoutManager > getLayoutManagerFromFrame( const Reference< XFrame >& rFrame )
101 Reference< XPropertySet > xPropSet( rFrame, UNO_QUERY );
102 Reference< XLayoutManager > xLayoutManager;
106 xPropSet->getPropertyValue("LayoutManager") >>= xLayoutManager;
108 catch ( const UnknownPropertyException& )
112 return xLayoutManager;
115 namespace {
117 struct ToolBarInfo
119 OUString aToolBarResName;
120 OUString aToolBarUIName;
125 // XInterface, XTypeProvider, XServiceInfo
127 OUString SAL_CALL ToolbarsMenuController::getImplementationName()
129 return "com.sun.star.comp.framework.ToolBarsMenuController";
132 sal_Bool SAL_CALL ToolbarsMenuController::supportsService( const OUString& sServiceName )
134 return cppu::supportsService(this, sServiceName);
137 css::uno::Sequence< OUString > SAL_CALL ToolbarsMenuController::getSupportedServiceNames()
139 return { SERVICENAME_POPUPMENUCONTROLLER };
142 constexpr OUStringLiteral g_aPropUIName( u"UIName" );
143 constexpr OUStringLiteral g_aPropResourceURL( u"ResourceURL" );
145 ToolbarsMenuController::ToolbarsMenuController( const css::uno::Reference< css::uno::XComponentContext >& xContext ) :
146 svt::PopupMenuControllerBase( xContext ),
147 m_xContext( xContext ),
148 m_bResetActive( false ),
149 m_aIntlWrapper(SvtSysLocale().GetUILanguageTag())
153 ToolbarsMenuController::~ToolbarsMenuController()
157 void ToolbarsMenuController::addCommand(
158 Reference< css::awt::XPopupMenu > const & rPopupMenu, const OUString& rCommandURL, const OUString& rLabel )
160 sal_uInt16 nItemId = m_xPopupMenu->getItemCount()+1;
162 OUString aLabel;
163 if ( rLabel.isEmpty() )
165 auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(rCommandURL, m_aModuleName);
166 aLabel = vcl::CommandInfoProvider::GetMenuLabelForCommand(aProperties);
168 else
169 aLabel = rLabel;
171 rPopupMenu->insertItem( nItemId, aLabel, 0, nItemId );
172 rPopupMenu->setCommand( nItemId, rCommandURL );
174 bool bInternal = rCommandURL.startsWith( STATIC_INTERNAL_CMD_PART );
175 if ( !bInternal )
177 if ( !getDispatchFromCommandURL( rCommandURL ).is() )
178 m_xPopupMenu->enableItem( nItemId, false );
181 SolarMutexGuard aSolarMutexGuard;
183 css::uno::Reference<css::graphic::XGraphic> xGraphic;
184 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
186 if ( rSettings.GetUseImagesInMenus() )
187 xGraphic = vcl::CommandInfoProvider::GetXGraphicForCommand(rCommandURL, m_xFrame);
189 if (xGraphic.is())
190 rPopupMenu->setItemImage(nItemId, xGraphic, false);
192 m_aCommandVector.push_back( rCommandURL );
195 Reference< XDispatch > ToolbarsMenuController::getDispatchFromCommandURL( const OUString& rCommandURL )
197 URL aTargetURL;
198 Reference< XURLTransformer > xURLTransformer;
199 Reference< XFrame > xFrame;
202 SolarMutexGuard aSolarMutexGuard;
203 xURLTransformer = m_xURLTransformer;
204 xFrame = m_xFrame;
207 aTargetURL.Complete = rCommandURL;
208 xURLTransformer->parseStrict( aTargetURL );
209 Reference< XDispatchProvider > xDispatchProvider( xFrame, UNO_QUERY );
210 if ( xDispatchProvider.is() )
211 return xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
212 else
213 return Reference< XDispatch >();
216 static void fillHashMap( const Sequence< Sequence< css::beans::PropertyValue > >& rSeqToolBars,
217 ToolbarHashMap& rHashMap )
219 for ( Sequence< css::beans::PropertyValue > const & props : rSeqToolBars )
221 OUString aResourceURL;
222 OUString aUIName;
223 for ( css::beans::PropertyValue const & prop : props )
225 if ( prop.Name == "ResourceURL" )
226 prop.Value >>= aResourceURL;
227 else if ( prop.Name == "UIName" )
228 prop.Value >>= aUIName;
231 if ( !aResourceURL.isEmpty() &&
232 rHashMap.find( aResourceURL ) == rHashMap.end() )
233 rHashMap.emplace( aResourceURL, aUIName );
237 // private function
238 Sequence< Sequence< css::beans::PropertyValue > > ToolbarsMenuController::getLayoutManagerToolbars( const Reference< css::frame::XLayoutManager >& rLayoutManager )
240 std::vector< ToolBarInfo > aToolBarArray;
241 const Sequence< Reference< XUIElement > > aUIElements = rLayoutManager->getElements();
242 for ( Reference< XUIElement > const & xUIElement : aUIElements )
244 Reference< XPropertySet > xPropSet( xUIElement, UNO_QUERY );
245 if ( xPropSet.is() && xUIElement.is() )
249 OUString aResName;
250 sal_Int16 nType( -1 );
251 xPropSet->getPropertyValue("Type") >>= nType;
252 xPropSet->getPropertyValue("ResourceURL") >>= aResName;
254 if (( nType == css::ui::UIElementType::TOOLBAR ) &&
255 !aResName.isEmpty() )
257 ToolBarInfo aToolBarInfo;
259 aToolBarInfo.aToolBarResName = aResName;
261 SolarMutexGuard aGuard;
262 Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY );
263 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
264 if ( pWindow )
265 aToolBarInfo.aToolBarUIName = pWindow->GetText();
267 aToolBarArray.push_back( aToolBarInfo );
270 catch ( const Exception& )
276 Sequence< Sequence< css::beans::PropertyValue > > aSeq( aToolBarArray.size() );
277 auto pSeq = aSeq.getArray();
278 const sal_uInt32 nCount = aToolBarArray.size();
279 for ( sal_uInt32 i = 0; i < nCount; i++ )
281 Sequence< css::beans::PropertyValue > aTbSeq{
282 comphelper::makePropertyValue(g_aPropUIName, aToolBarArray[i].aToolBarUIName),
283 comphelper::makePropertyValue(g_aPropResourceURL, aToolBarArray[i].aToolBarResName)
285 pSeq[i] = aTbSeq;
288 return aSeq;
292 void ToolbarsMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu > const & rPopupMenu )
294 if( officecfg::Office::Common::Misc::DisableUICustomization::get() )
295 return;
297 SolarMutexGuard aSolarMutexGuard;
298 resetPopupMenu( rPopupMenu );
300 m_aCommandVector.clear();
302 // Retrieve layout manager for additional information
303 Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( m_xFrame ));
305 m_bResetActive = false;
306 if ( !xLayoutManager.is() )
307 return;
309 ToolbarHashMap aToolbarHashMap;
311 if ( m_xDocCfgMgr.is() )
313 Sequence< Sequence< css::beans::PropertyValue > > aSeqDocToolBars =
314 m_xDocCfgMgr->getUIElementsInfo( UIElementType::TOOLBAR );
315 fillHashMap( aSeqDocToolBars, aToolbarHashMap );
318 if ( m_xModuleCfgMgr.is() )
320 Sequence< Sequence< css::beans::PropertyValue > > aSeqToolBars =
321 m_xModuleCfgMgr->getUIElementsInfo( UIElementType::TOOLBAR );
322 fillHashMap( aSeqToolBars, aToolbarHashMap );
325 std::vector< ToolBarEntry > aSortedTbs;
326 OUString aStaticCmdPart( STATIC_CMD_PART );
328 Sequence< Sequence< css::beans::PropertyValue > > aSeqFrameToolBars = getLayoutManagerToolbars( xLayoutManager );
329 fillHashMap( aSeqFrameToolBars, aToolbarHashMap );
331 for (auto const& toolbar : aToolbarHashMap)
333 OUString aUIName = toolbar.second;
334 bool bHideFromMenu( false );
335 bool bContextSensitive( false );
336 if ( aUIName.isEmpty() &&
337 m_xPersistentWindowState.is() )
339 bool bVisible( false );
343 Sequence< PropertyValue > aWindowState;
344 Any a( m_xPersistentWindowState->getByName( toolbar.first ));
346 if ( a >>= aWindowState )
348 for ( PropertyValue const & prop : std::as_const(aWindowState) )
350 if ( prop.Name == WINDOWSTATE_PROPERTY_UINAME )
351 prop.Value >>= aUIName;
352 else if ( prop.Name == WINDOWSTATE_PROPERTY_HIDEFROMENU )
353 prop.Value >>= bHideFromMenu;
354 else if ( prop.Name == WINDOWSTATE_PROPERTY_CONTEXT )
355 prop.Value >>= bContextSensitive;
356 else if ( prop.Name == WINDOWSTATE_PROPERTY_VISIBLE )
357 prop.Value >>= bVisible;
361 catch ( const Exception& )
365 // Check if we have to enable/disable "Reset" menu item
366 if ( bContextSensitive && !bVisible )
367 m_bResetActive = true;
371 if ( !aUIName.isEmpty() && !bHideFromMenu )
373 ToolBarEntry aTbEntry;
374 aTbEntry.aUIName = aUIName;
375 aTbEntry.aCommand = toolbar.first;
376 aTbEntry.bVisible = xLayoutManager->isElementVisible( toolbar.first );
377 aTbEntry.pCollatorWrapper = m_aIntlWrapper.getCaseCollator();
378 aSortedTbs.push_back( aTbEntry );
382 // sort toolbars
383 std::sort( aSortedTbs.begin(), aSortedTbs.end(), CompareToolBarEntry );
385 sal_Int16 nIndex( 1 );
386 const sal_uInt32 nCount = aSortedTbs.size();
387 for ( sal_uInt32 i = 0; i < nCount; i++ )
389 sal_uInt16 nItemCount = m_xPopupMenu->getItemCount();
390 m_xPopupMenu->insertItem( nIndex, aSortedTbs[i].aUIName, css::awt::MenuItemStyle::CHECKABLE, nItemCount );
391 if ( aSortedTbs[i].bVisible )
392 m_xPopupMenu->checkItem( nIndex, true );
394 OUStringBuffer aStrBuf( aStaticCmdPart );
396 sal_Int32 n = aSortedTbs[i].aCommand.lastIndexOf( '/' );
397 if (( n > 0 ) && (( n+1 ) < aSortedTbs[i].aCommand.getLength() ))
398 aStrBuf.append( aSortedTbs[i].aCommand.subView(n+1) );
400 OUString aCmd( aStrBuf.makeStringAndClear() );
402 // Store complete uno-command so it can also be dispatched. This is necessary to support
403 // the test tool!
404 rPopupMenu->setCommand( nIndex, aCmd );
405 ++nIndex;
408 // Create commands for non-toolbars
410 bool bAddCommand( true );
411 SvtCommandOptions aCmdOptions;
413 if ( aCmdOptions.HasEntriesDisabled() && aCmdOptions.LookupDisabled("ConfigureDialog"))
414 bAddCommand = false;
416 if ( bAddCommand )
418 // Create command for configure
419 if ( m_xPopupMenu->getItemCount() > 0 )
421 sal_uInt16 nItemCount = m_xPopupMenu->getItemCount();
422 m_xPopupMenu->insertSeparator( nItemCount+1 );
425 addCommand( m_xPopupMenu, ".uno:ConfigureDialog", "" );
428 // Add separator if no configure has been added
429 if ( !bAddCommand )
431 // Create command for configure
432 if ( m_xPopupMenu->getItemCount() > 0 )
434 sal_uInt16 nItemCount = m_xPopupMenu->getItemCount();
435 m_xPopupMenu->insertSeparator( nItemCount+1 );
439 OUString aLabelStr(FwkResId(STR_RESTORE_TOOLBARS));
440 addCommand( m_xPopupMenu, CMD_RESTOREVISIBILITY, aLabelStr );
441 aLabelStr = FwkResId(STR_LOCK_TOOLBARS);
442 addCommand( m_xPopupMenu, CMD_LOCKTOOLBARS, aLabelStr );
445 // XEventListener
446 void SAL_CALL ToolbarsMenuController::disposing( const EventObject& )
448 Reference< css::awt::XMenuListener > xHolder(this);
450 std::unique_lock aLock( m_aMutex );
451 m_xFrame.clear();
452 m_xDispatch.clear();
453 m_xDocCfgMgr.clear();
454 m_xModuleCfgMgr.clear();
455 m_xContext.clear();
457 if ( m_xPopupMenu.is() )
458 m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(this) );
459 m_xPopupMenu.clear();
462 // XStatusListener
463 void SAL_CALL ToolbarsMenuController::statusChanged( const FeatureStateEvent& Event )
465 OUString aFeatureURL( Event.FeatureURL.Complete );
467 // All other status events will be processed here
468 std::unique_lock aLock( m_aMutex );
469 Reference< css::awt::XPopupMenu > xPopupMenu( m_xPopupMenu );
470 aLock.unlock();
472 if ( !xPopupMenu.is() )
473 return;
475 SolarMutexGuard aGuard;
477 bool bSetCheckmark = false;
478 bool bCheckmark = false;
479 for (sal_Int16 i = 0, nCount = xPopupMenu->getItemCount(); i < nCount; ++i)
481 sal_Int16 nId = xPopupMenu->getItemId(i);
482 if ( nId == 0 )
483 continue;
485 OUString aCmd = xPopupMenu->getCommand(nId);
486 if ( aCmd == aFeatureURL )
488 // Enable/disable item
489 xPopupMenu->enableItem(nId, Event.IsEnabled);
491 // Checkmark
492 if ( Event.State >>= bCheckmark )
493 bSetCheckmark = true;
495 if ( bSetCheckmark )
496 xPopupMenu->checkItem(nId, bCheckmark);
497 else
499 OUString aItemText;
501 if ( Event.State >>= aItemText )
502 xPopupMenu->setItemText(nId, aItemText);
508 // XMenuListener
509 void SAL_CALL ToolbarsMenuController::itemSelected( const css::awt::MenuEvent& rEvent )
511 Reference< css::awt::XPopupMenu > xPopupMenu;
512 Reference< XComponentContext > xContext;
513 Reference< XURLTransformer > xURLTransformer;
514 Reference< XFrame > xFrame;
515 Reference< XNameAccess > xPersistentWindowState;
518 std::unique_lock aLock(m_aMutex);
519 xPopupMenu = m_xPopupMenu;
520 xContext = m_xContext;
521 xURLTransformer = m_xURLTransformer;
522 xFrame = m_xFrame;
523 xPersistentWindowState = m_xPersistentWindowState;
526 if ( !xPopupMenu.is() )
527 return;
529 SolarMutexGuard aSolarMutexGuard;
531 OUString aCmd(xPopupMenu->getCommand(rEvent.MenuId));
532 if ( aCmd.startsWith( STATIC_INTERNAL_CMD_PART ) )
534 // Command to restore the visibility of all context sensitive toolbars
535 Reference< XNameReplace > xNameReplace( xPersistentWindowState, UNO_QUERY );
536 if ( xPersistentWindowState.is() && xNameReplace.is() )
540 Sequence< OUString > aElementNames = xPersistentWindowState->getElementNames();
541 sal_Int32 nCount = aElementNames.getLength();
542 bool bRefreshToolbars( false );
544 for ( sal_Int32 i = 0; i < nCount; i++ )
548 OUString aElementName = aElementNames[i];
549 Sequence< PropertyValue > aWindowState;
551 if ( xPersistentWindowState->getByName( aElementName ) >>= aWindowState )
553 bool bVisible( false );
554 bool bContextSensitive( false );
555 sal_Int32 nVisibleIndex( -1 );
556 for ( sal_Int32 j = 0; j < aWindowState.getLength(); j++ )
558 if ( aWindowState[j].Name == WINDOWSTATE_PROPERTY_VISIBLE )
560 aWindowState[j].Value >>= bVisible;
561 nVisibleIndex = j;
563 else if ( aWindowState[j].Name == WINDOWSTATE_PROPERTY_CONTEXT )
564 aWindowState[j].Value >>= bContextSensitive;
567 if ( !bVisible && bContextSensitive && nVisibleIndex >= 0 )
569 // Default is: Every context sensitive toolbar is visible
570 aWindowState.getArray()[nVisibleIndex].Value <<= true;
571 xNameReplace->replaceByName( aElementName, Any( aWindowState ));
572 bRefreshToolbars = true;
576 catch ( const NoSuchElementException& )
581 if ( bRefreshToolbars )
583 Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( xFrame ));
584 if ( xLayoutManager.is() )
586 Reference< XPropertySet > xPropSet( xLayoutManager, UNO_QUERY );
587 if ( xPropSet.is() )
591 xPropSet->setPropertyValue("RefreshContextToolbarVisibility", Any( true ));
593 catch ( const RuntimeException& )
596 catch ( const Exception& )
601 RefreshToolbars( xFrame );
604 catch ( const RuntimeException& )
606 throw;
608 catch ( const Exception& )
613 else if ( aCmd.indexOf( STATIC_CMD_PART ) < 0 )
615 URL aTargetURL;
616 Sequence<PropertyValue> aArgs;
618 aTargetURL.Complete = aCmd;
619 xURLTransformer->parseStrict( aTargetURL );
620 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
621 if ( xDispatchProvider.is() )
623 Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch(
624 aTargetURL, OUString(), 0 );
626 ExecuteInfo* pExecuteInfo = new ExecuteInfo;
627 pExecuteInfo->xDispatch = xDispatch;
628 pExecuteInfo->aTargetURL = aTargetURL;
629 pExecuteInfo->aArgs = aArgs;
630 Application::PostUserEvent( LINK(nullptr, ToolbarsMenuController, ExecuteHdl_Impl), pExecuteInfo );
633 else
635 Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( xFrame ));
636 if ( xLayoutManager.is() )
638 // Extract toolbar name from the combined uno-command.
639 sal_Int32 nIndex = aCmd.indexOf( '=' );
640 if (( nIndex > 0 ) && (( nIndex+1 ) < aCmd.getLength() ))
642 OUString aToolBarResName = OUString::Concat("private:resource/toolbar/") + aCmd.subView(nIndex+1);
644 const bool bShow(!xPopupMenu->isItemChecked(rEvent.MenuId));
645 if ( bShow )
647 xLayoutManager->createElement( aToolBarResName );
648 xLayoutManager->showElement( aToolBarResName );
650 else
652 // closing means:
653 // hide and destroy element
654 xLayoutManager->hideElement( aToolBarResName );
655 xLayoutManager->destroyElement( aToolBarResName );
662 void SAL_CALL ToolbarsMenuController::itemActivated( const css::awt::MenuEvent& )
664 std::vector< OUString > aCmdVector;
665 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
666 Reference< XURLTransformer > xURLTransformer( m_xURLTransformer );
668 std::unique_lock aLock( m_aMutex );
669 fillPopupMenu( m_xPopupMenu );
670 aCmdVector = m_aCommandVector;
673 // Update status for all commands inside our toolbars popup menu
674 const sal_uInt32 nCount = aCmdVector.size();
675 for ( sal_uInt32 i = 0; i < nCount; i++ )
677 bool bInternal = aCmdVector[i].startsWith( STATIC_INTERNAL_CMD_PART );
679 if ( !bInternal )
681 URL aTargetURL;
682 aTargetURL.Complete = aCmdVector[i];
683 xURLTransformer->parseStrict( aTargetURL );
684 Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
685 if ( xDispatch.is() )
687 xDispatch->addStatusListener( static_cast< XStatusListener* >(this), aTargetURL );
688 xDispatch->removeStatusListener( static_cast< XStatusListener* >(this), aTargetURL );
691 else if ( aCmdVector[i] == CMD_RESTOREVISIBILITY )
693 // Special code to determine the enable/disable state of this command
694 FeatureStateEvent aFeatureStateEvent;
695 aFeatureStateEvent.FeatureURL.Complete = aCmdVector[i];
696 aFeatureStateEvent.IsEnabled = m_bResetActive; // is context sensitive toolbar non visible
697 statusChanged( aFeatureStateEvent );
702 // XPopupMenuController
703 void SAL_CALL ToolbarsMenuController::setPopupMenu( const Reference< css::awt::XPopupMenu >& xPopupMenu )
705 std::unique_lock aLock( m_aMutex );
707 throwIfDisposed(aLock);
709 if ( m_xFrame.is() && !m_xPopupMenu.is() )
711 // Create popup menu on demand
712 SolarMutexGuard aSolarMutexGuard;
714 m_xPopupMenu = dynamic_cast<VCLXPopupMenu*>(xPopupMenu.get());
715 assert(bool(xPopupMenu) == bool(m_xPopupMenu) && "we only support VCLXPopupMenu");
716 m_xPopupMenu->addMenuListener( Reference< css::awt::XMenuListener >(this) );
717 fillPopupMenu( m_xPopupMenu );
721 // XInitialization
722 void ToolbarsMenuController::initializeImpl( std::unique_lock<std::mutex>& rGuard, const Sequence< Any >& aArguments )
724 bool bInitialized( m_bInitialized );
725 if ( bInitialized )
726 return;
728 svt::PopupMenuControllerBase::initializeImpl(rGuard, aArguments);
730 if ( !m_bInitialized )
731 return;
733 Reference< XModuleManager2 > xModuleManager = ModuleManager::create( m_xContext );
734 Reference< XNameAccess > xPersistentWindowStateSupplier = css::ui::theWindowStateConfiguration::get( m_xContext );
736 // Retrieve persistent window state reference for our module
739 OUString aModuleIdentifier = xModuleManager->identify( m_xFrame );
740 xPersistentWindowStateSupplier->getByName( aModuleIdentifier ) >>= m_xPersistentWindowState;
742 Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier =
743 theModuleUIConfigurationManagerSupplier::get( m_xContext );
744 m_xModuleCfgMgr = xModuleCfgSupplier->getUIConfigurationManager( aModuleIdentifier );
746 Reference< XController > xController = m_xFrame->getController();
747 Reference< XModel > xModel;
748 if ( xController.is() )
749 xModel = xController->getModel();
750 if ( xModel.is() )
752 Reference< XUIConfigurationManagerSupplier > xUIConfigurationManagerSupplier( xModel, UNO_QUERY );
753 if ( xUIConfigurationManagerSupplier.is() )
754 m_xDocCfgMgr = xUIConfigurationManagerSupplier->getUIConfigurationManager();
757 catch ( const Exception& )
762 IMPL_STATIC_LINK( ToolbarsMenuController, ExecuteHdl_Impl, void*, p, void )
764 ExecuteInfo* pExecuteInfo = static_cast<ExecuteInfo*>(p);
767 // Asynchronous execution as this can lead to our own destruction!
768 // Framework can recycle our current frame and the layout manager disposes all user interface
769 // elements if a component gets detached from its frame!
770 if ( pExecuteInfo->xDispatch.is() )
772 pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
775 catch ( const Exception& )
779 delete pExecuteInfo;
784 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
785 framework_ToolbarsMenuController_get_implementation(
786 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
788 return cppu::acquire(new framework::ToolbarsMenuController(context));
791 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */