fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / framework / source / uielement / toolbarsmenucontroller.cxx
blob1f7de7e056cbc3045ae82292c17e83920e455af8
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>
24 #include "services.h"
25 #include <classes/resource.hrc>
26 #include <classes/fwkresid.hxx>
27 #include <framework/imageproducer.hxx>
28 #include <framework/sfxhelperfunctions.hxx>
29 #include <uiconfiguration/windowstateproperties.hxx>
31 #include <com/sun/star/awt/XDevice.hpp>
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/frame/theUICommandDescription.hpp>
37 #include <com/sun/star/container/XNameContainer.hpp>
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/frame/XLayoutManager.hpp>
40 #include <com/sun/star/ui/XUIElementSettings.hpp>
41 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
42 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
43 #include <com/sun/star/ui/UIElementType.hpp>
44 #include <com/sun/star/ui/theWindowStateConfiguration.hpp>
46 #include <vcl/menu.hxx>
47 #include <vcl/svapp.hxx>
48 #include <vcl/i18nhelp.hxx>
49 #include <vcl/image.hxx>
50 #include <vcl/settings.hxx>
51 #include <rtl/ustrbuf.hxx>
52 #include <toolkit/helper/vclunohelper.hxx>
53 #include <vcl/window.hxx>
54 #include <svtools/menuoptions.hxx>
55 #include <unotools/cmdoptions.hxx>
56 #include <svtools/miscopt.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 static const char CONFIGURE_TOOLBARS_CMD[] = "ConfigureDialog";
70 static const char CONFIGURE_TOOLBARS[] = ".uno:ConfigureDialog";
71 static const char CMD_COLORBAR[] = ".uno:ColorControl";
72 static const char CMD_FORMULABAR[] = ".uno:InsertFormula";
73 static const char CMD_INPUTLINEBAR[] = ".uno:InputLineVisible";
74 static const char CMD_RESTOREVISIBILITY[] = ".cmd:RestoreVisibility";
75 static const char ITEM_DESCRIPTOR_RESOURCEURL[] = "ResourceURL";
76 static const char ITEM_DESCRIPTOR_UINAME[] = "UIName";
77 static const char STATIC_PRIVATE_TB_RESOURCE[] = "private:resource/toolbar/";
79 static const char STATIC_CMD_PART[] = ".uno:AvailableToolbars?Toolbar:string=";
80 static const char STATIC_INTERNAL_CMD_PART[] = ".cmd:";
82 namespace framework
85 typedef std::unordered_map< OUString, OUString, OUStringHash, std::equal_to< OUString > > ToolbarHashMap;
87 struct ToolBarEntry
89 OUString aUIName;
90 OUString aCommand;
91 bool bVisible;
92 bool bContextSensitive;
93 const CollatorWrapper* pCollatorWrapper;
96 bool CompareToolBarEntry( const ToolBarEntry& aOne, const ToolBarEntry& aTwo )
98 sal_Int32 nComp = aOne.pCollatorWrapper->compareString( aOne.aUIName, aTwo.aUIName );
100 if ( nComp < 0 )
101 return true;
102 else
103 return false;
106 Reference< XLayoutManager > getLayoutManagerFromFrame( const Reference< XFrame >& rFrame )
108 Reference< XPropertySet > xPropSet( rFrame, UNO_QUERY );
109 Reference< XLayoutManager > xLayoutManager;
113 xPropSet->getPropertyValue("LayoutManager") >>= xLayoutManager;
115 catch ( const UnknownPropertyException& )
119 return xLayoutManager;
122 struct ToolBarInfo
124 OUString aToolBarResName;
125 OUString aToolBarUIName;
128 DEFINE_XSERVICEINFO_MULTISERVICE_2 ( ToolbarsMenuController ,
129 OWeakObject ,
130 SERVICENAME_POPUPMENUCONTROLLER ,
131 IMPLEMENTATIONNAME_TOOLBARSMENUCONTROLLER
134 DEFINE_INIT_SERVICE ( ToolbarsMenuController, {} )
136 ToolbarsMenuController::ToolbarsMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xContext ) :
137 svt::PopupMenuControllerBase( xContext ),
138 m_xContext( xContext ),
139 m_aPropUIName( "UIName" ),
140 m_aPropResourceURL( "ResourceURL" ),
141 m_bModuleIdentified( false ),
142 m_bResetActive( false ),
143 m_aIntlWrapper( xContext, Application::GetSettings().GetLanguageTag() )
147 ToolbarsMenuController::~ToolbarsMenuController()
151 void ToolbarsMenuController::addCommand(
152 Reference< css::awt::XPopupMenu >& rPopupMenu, const OUString& rCommandURL, const OUString& rLabel )
154 sal_uInt16 nItemId = m_xPopupMenu->getItemCount()+1;
156 OUString aLabel;
157 if ( rLabel.isEmpty() )
158 aLabel = getUINameFromCommand( rCommandURL );
159 else
160 aLabel = rLabel;
162 rPopupMenu->insertItem( nItemId, aLabel, 0, nItemId );
163 rPopupMenu->setCommand( nItemId, rCommandURL );
165 bool bInternal = rCommandURL.startsWith( STATIC_INTERNAL_CMD_PART );
166 if ( !bInternal )
168 if ( !getDispatchFromCommandURL( rCommandURL ).is() )
169 m_xPopupMenu->enableItem( nItemId, sal_False );
172 SolarMutexGuard aSolarMutexGuard;
174 Image aImage;
175 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
177 if ( rSettings.GetUseImagesInMenus() )
178 aImage = GetImageFromURL( m_xFrame, rCommandURL, false );
180 VCLXPopupMenu* pPopupMenu = static_cast<VCLXPopupMenu *>(VCLXPopupMenu::GetImplementation( rPopupMenu ));
181 if ( pPopupMenu )
183 PopupMenu* pVCLPopupMenu = static_cast<PopupMenu *>(pPopupMenu->GetMenu());
184 if ( !!aImage )
185 pVCLPopupMenu->SetItemImage( nItemId, aImage );
188 m_aCommandVector.push_back( rCommandURL );
191 Reference< XDispatch > ToolbarsMenuController::getDispatchFromCommandURL( const OUString& rCommandURL )
193 URL aTargetURL;
194 Reference< XURLTransformer > xURLTransformer;
195 Reference< XFrame > xFrame;
198 SolarMutexGuard aSolarMutexGuard;
199 xURLTransformer = m_xURLTransformer;
200 xFrame = m_xFrame;
203 aTargetURL.Complete = rCommandURL;
204 xURLTransformer->parseStrict( aTargetURL );
205 Reference< XDispatchProvider > xDispatchProvider( xFrame, UNO_QUERY );
206 if ( xDispatchProvider.is() )
207 return xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
208 else
209 return Reference< XDispatch >();
212 // private function
213 OUString ToolbarsMenuController::getUINameFromCommand( const OUString& rCommandURL )
215 OUString aLabel;
217 if ( !m_bModuleIdentified )
221 Reference< XModuleManager2 > xModuleManager = ModuleManager::create( m_xContext );
222 m_aModuleIdentifier = xModuleManager->identify( m_xFrame );
223 Reference< XNameAccess > xNameAccess = frame::theUICommandDescription::get( m_xContext );
224 xNameAccess->getByName( m_aModuleIdentifier ) >>= m_xUICommandDescription;
226 catch ( const Exception& )
231 if ( m_xUICommandDescription.is() )
235 Sequence< PropertyValue > aPropSeq;
236 OUString aStr;
237 if ( m_xUICommandDescription->getByName( rCommandURL ) >>= aPropSeq )
239 for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
241 if ( aPropSeq[i].Name == "Label" )
243 aPropSeq[i].Value >>= aStr;
244 break;
248 aLabel = aStr;
250 catch ( const Exception& )
255 return aLabel;
258 static void fillHashMap( const Sequence< Sequence< ::com::sun::star::beans::PropertyValue > >& rSeqToolBars,
259 ToolbarHashMap& rHashMap )
261 for ( sal_Int32 i = 0; i < rSeqToolBars.getLength(); i++ )
263 OUString aResourceURL;
264 OUString aUIName;
265 const PropertyValue* pProperties = rSeqToolBars[i].getConstArray();
266 for ( sal_Int32 j = 0; j < rSeqToolBars[i].getLength(); j++ )
268 if ( pProperties[j].Name == ITEM_DESCRIPTOR_RESOURCEURL )
269 pProperties[j].Value >>= aResourceURL;
270 else if ( pProperties[j].Name == ITEM_DESCRIPTOR_UINAME )
271 pProperties[j].Value >>= aUIName;
274 if ( !aResourceURL.isEmpty() &&
275 rHashMap.find( aResourceURL ) == rHashMap.end() )
276 rHashMap.insert( ToolbarHashMap::value_type( aResourceURL, aUIName ));
280 // private function
281 Sequence< Sequence< com::sun::star::beans::PropertyValue > > ToolbarsMenuController::getLayoutManagerToolbars( const Reference< ::com::sun::star::frame::XLayoutManager >& rLayoutManager )
283 std::vector< ToolBarInfo > aToolBarArray;
284 Sequence< Reference< XUIElement > > aUIElements = rLayoutManager->getElements();
285 for ( sal_Int32 i = 0; i < aUIElements.getLength(); i++ )
287 Reference< XUIElement > xUIElement( aUIElements[i] );
288 Reference< XPropertySet > xPropSet( aUIElements[i], UNO_QUERY );
289 if ( xPropSet.is() && xUIElement.is() )
293 OUString aResName;
294 sal_Int16 nType( -1 );
295 xPropSet->getPropertyValue("Type") >>= nType;
296 xPropSet->getPropertyValue("ResourceURL") >>= aResName;
298 if (( nType == ::com::sun::star::ui::UIElementType::TOOLBAR ) &&
299 !aResName.isEmpty() )
301 ToolBarInfo aToolBarInfo;
303 aToolBarInfo.aToolBarResName = aResName;
305 SolarMutexGuard aGuard;
306 Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY );
307 vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
308 if ( pWindow )
309 aToolBarInfo.aToolBarUIName = pWindow->GetText();
311 aToolBarArray.push_back( aToolBarInfo );
314 catch ( const Exception& )
320 Sequence< com::sun::star::beans::PropertyValue > aTbSeq( 2 );
321 aTbSeq[0].Name = m_aPropUIName;
322 aTbSeq[1].Name = m_aPropResourceURL;
324 Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeq( aToolBarArray.size() );
325 const sal_uInt32 nCount = aToolBarArray.size();
326 for ( sal_uInt32 i = 0; i < nCount; i++ )
328 aTbSeq[0].Value <<= aToolBarArray[i].aToolBarUIName;
329 aTbSeq[1].Value <<= aToolBarArray[i].aToolBarResName;
330 aSeq[i] = aTbSeq;
333 return aSeq;
337 void ToolbarsMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopupMenu )
339 if( SvtMiscOptions().DisableUICustomization() )
340 return;
342 SolarMutexGuard aSolarMutexGuard;
343 resetPopupMenu( rPopupMenu );
345 m_aCommandVector.clear();
347 // Retrieve layout manager for additional information
348 OUString aEmptyString;
349 Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( m_xFrame ));
351 m_bResetActive = false;
352 if ( xLayoutManager.is() )
354 ToolbarHashMap aToolbarHashMap;
356 if ( m_xDocCfgMgr.is() )
358 Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeqDocToolBars =
359 m_xDocCfgMgr->getUIElementsInfo( UIElementType::TOOLBAR );
360 fillHashMap( aSeqDocToolBars, aToolbarHashMap );
363 if ( m_xModuleCfgMgr.is() )
365 Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeqToolBars =
366 m_xModuleCfgMgr->getUIElementsInfo( UIElementType::TOOLBAR );
367 fillHashMap( aSeqToolBars, aToolbarHashMap );
370 std::vector< ToolBarEntry > aSortedTbs;
371 OUString aStaticCmdPart( STATIC_CMD_PART );
373 Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeqFrameToolBars = getLayoutManagerToolbars( xLayoutManager );
374 fillHashMap( aSeqFrameToolBars, aToolbarHashMap );
376 ToolbarHashMap::const_iterator pIter = aToolbarHashMap.begin();
377 while ( pIter != aToolbarHashMap.end() )
379 OUString aUIName = pIter->second;
380 bool bHideFromMenu( false );
381 bool bContextSensitive( false );
382 if ( aUIName.isEmpty() &&
383 m_xPersistentWindowState.is() )
385 bool bVisible( false );
389 Sequence< PropertyValue > aWindowState;
390 Any a( m_xPersistentWindowState->getByName( pIter->first ));
392 if ( a >>= aWindowState )
394 for ( sal_Int32 i = 0; i < aWindowState.getLength(); i++ )
396 if ( aWindowState[i].Name == WINDOWSTATE_PROPERTY_UINAME )
397 aWindowState[i].Value >>= aUIName;
398 else if ( aWindowState[i].Name == WINDOWSTATE_PROPERTY_HIDEFROMENU )
399 aWindowState[i].Value >>= bHideFromMenu;
400 else if ( aWindowState[i].Name == WINDOWSTATE_PROPERTY_CONTEXT )
401 aWindowState[i].Value >>= bContextSensitive;
402 else if ( aWindowState[i].Name == WINDOWSTATE_PROPERTY_VISIBLE )
403 aWindowState[i].Value >>= bVisible;
407 catch ( const Exception& )
411 // Check if we have to enable/disable "Reset" menu item
412 if ( bContextSensitive && !bVisible )
413 m_bResetActive = true;
417 if ( !aUIName.isEmpty() && !bHideFromMenu )
419 ToolBarEntry aTbEntry;
420 aTbEntry.aUIName = aUIName;
421 aTbEntry.aCommand = pIter->first;
422 aTbEntry.bVisible = xLayoutManager->isElementVisible( pIter->first );
423 aTbEntry.bContextSensitive = bContextSensitive;
424 aTbEntry.pCollatorWrapper = m_aIntlWrapper.getCaseCollator();
425 aSortedTbs.push_back( aTbEntry );
427 ++pIter;
430 // sort toolbars
431 std::sort( aSortedTbs.begin(), aSortedTbs.end(), CompareToolBarEntry );
433 sal_Int16 nIndex( 1 );
434 const sal_uInt32 nCount = aSortedTbs.size();
435 for ( sal_uInt32 i = 0; i < nCount; i++ )
437 sal_uInt16 nItemCount = m_xPopupMenu->getItemCount();
438 m_xPopupMenu->insertItem( nIndex, aSortedTbs[i].aUIName, css::awt::MenuItemStyle::CHECKABLE, nItemCount );
439 if ( aSortedTbs[i].bVisible )
440 m_xPopupMenu->checkItem( nIndex, sal_True );
443 SolarMutexGuard aGuard;
444 VCLXPopupMenu* pXPopupMenu = static_cast<VCLXPopupMenu *>(VCLXMenu::GetImplementation( m_xPopupMenu ));
445 PopupMenu* pVCLPopupMenu = pXPopupMenu ? static_cast<PopupMenu *>(pXPopupMenu->GetMenu()) : NULL;
446 assert(pVCLPopupMenu);
447 if (pVCLPopupMenu)
448 pVCLPopupMenu->SetUserValue( nIndex, sal_uIntPtr( aSortedTbs[i].bContextSensitive ? 1L : 0L ));
451 // use VCL popup menu pointer to set vital information that are not part of the awt implementation
452 OUStringBuffer aStrBuf( aStaticCmdPart );
454 sal_Int32 n = aSortedTbs[i].aCommand.lastIndexOf( '/' );
455 if (( n > 0 ) && (( n+1 ) < aSortedTbs[i].aCommand.getLength() ))
456 aStrBuf.append( aSortedTbs[i].aCommand.copy( n+1 ));
458 OUString aCmd( aStrBuf.makeStringAndClear() );
460 // Store complete uno-command so it can also be dispatched. This is necessary to support
461 // the test tool!
462 rPopupMenu->setCommand( nIndex, aCmd );
463 ++nIndex;
466 // Create commands for non-toolbars
467 if ( m_aModuleIdentifier == "com.sun.star.text.TextDocument" ||
468 m_aModuleIdentifier == "com.sun.star.text.WebDocument" ||
469 m_aModuleIdentifier == "com.sun.star.text.GlobalDocument" ||
470 m_aModuleIdentifier == "com.sun.star.drawing.DrawingDocument" ||
471 m_aModuleIdentifier == "com.sun.star.presentation.PresentationDocument" ||
472 m_aModuleIdentifier == "com.sun.star.sheet.SpreadsheetDocument" )
474 if ( m_aModuleIdentifier == "com.sun.star.drawing.DrawingDocument" ||
475 m_aModuleIdentifier == "com.sun.star.presentation.PresentationDocument" )
476 addCommand( m_xPopupMenu, OUString( CMD_COLORBAR ), aEmptyString );
477 else if ( m_aModuleIdentifier == "com.sun.star.sheet.SpreadsheetDocument" )
478 addCommand( m_xPopupMenu, OUString( CMD_INPUTLINEBAR ), aEmptyString );
479 else
480 addCommand( m_xPopupMenu, OUString( CMD_FORMULABAR ), aEmptyString );
483 bool bAddCommand( true );
484 SvtCommandOptions aCmdOptions;
485 OUString aConfigureToolbar( CONFIGURE_TOOLBARS );
487 if ( aCmdOptions.HasEntries( SvtCommandOptions::CMDOPTION_DISABLED ))
489 if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED,
490 OUString( CONFIGURE_TOOLBARS_CMD )))
491 bAddCommand = false;
494 if ( bAddCommand )
496 // Create command for configure
497 if ( m_xPopupMenu->getItemCount() > 0 )
499 sal_uInt16 nItemCount = m_xPopupMenu->getItemCount();
500 m_xPopupMenu->insertSeparator( nItemCount+1 );
503 addCommand( m_xPopupMenu, aConfigureToolbar, aEmptyString );
506 // Add separator if no configure has been added
507 if ( !bAddCommand )
509 // Create command for configure
510 if ( m_xPopupMenu->getItemCount() > 0 )
512 sal_uInt16 nItemCount = m_xPopupMenu->getItemCount();
513 m_xPopupMenu->insertSeparator( nItemCount+1 );
517 OUString aLabelStr(FWK_RESSTR(STR_RESTORE_TOOLBARS));
518 OUString aRestoreCmd( CMD_RESTOREVISIBILITY );
519 addCommand( m_xPopupMenu, aRestoreCmd, aLabelStr );
523 // XEventListener
524 void SAL_CALL ToolbarsMenuController::disposing( const EventObject& ) throw ( RuntimeException, std::exception )
526 Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY );
528 osl::MutexGuard aLock( m_aMutex );
529 m_xFrame.clear();
530 m_xDispatch.clear();
531 m_xDocCfgMgr.clear();
532 m_xModuleCfgMgr.clear();
533 m_xContext.clear();
535 if ( m_xPopupMenu.is() )
536 m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY ));
537 m_xPopupMenu.clear();
540 // XStatusListener
541 void SAL_CALL ToolbarsMenuController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException, std::exception )
543 OUString aFeatureURL( Event.FeatureURL.Complete );
545 // All other status events will be processed here
546 osl::ClearableMutexGuard aLock( m_aMutex );
547 Reference< css::awt::XPopupMenu > xPopupMenu( m_xPopupMenu );
548 aLock.clear();
550 if ( xPopupMenu.is() )
552 SolarMutexGuard aGuard;
553 VCLXPopupMenu* pXPopupMenu = static_cast<VCLXPopupMenu *>(VCLXMenu::GetImplementation( xPopupMenu ));
554 PopupMenu* pVCLPopupMenu = pXPopupMenu ? static_cast<PopupMenu *>(pXPopupMenu->GetMenu()) : NULL;
556 SAL_WARN_IF(!pVCLPopupMenu, "framework", "worrying lack of popup menu");
557 if (!pVCLPopupMenu)
558 return;
560 bool bSetCheckmark = false;
561 bool bCheckmark = false;
562 for ( sal_uInt16 i = 0; i < pVCLPopupMenu->GetItemCount(); i++ )
564 sal_uInt16 nId = pVCLPopupMenu->GetItemId( i );
565 if ( nId == 0 )
566 continue;
568 OUString aCmd = pVCLPopupMenu->GetItemCommand( nId );
569 if ( aCmd == aFeatureURL )
571 // Enable/disable item
572 pVCLPopupMenu->EnableItem( nId, Event.IsEnabled );
574 // Checkmark
575 if ( Event.State >>= bCheckmark )
576 bSetCheckmark = true;
578 if ( bSetCheckmark )
579 pVCLPopupMenu->CheckItem( nId, bCheckmark );
580 else
582 OUString aItemText;
584 if ( Event.State >>= aItemText )
585 pVCLPopupMenu->SetItemText( nId, aItemText );
592 // XMenuListener
593 void SAL_CALL ToolbarsMenuController::itemSelected( const css::awt::MenuEvent& rEvent ) throw (RuntimeException, std::exception)
595 Reference< css::awt::XPopupMenu > xPopupMenu;
596 Reference< XComponentContext > xContext;
597 Reference< XURLTransformer > xURLTransformer;
598 Reference< XFrame > xFrame;
599 Reference< XNameAccess > xPersistentWindowState;
601 osl::ClearableMutexGuard aLock( m_aMutex );
602 xPopupMenu = m_xPopupMenu;
603 xContext = m_xContext;
604 xURLTransformer = m_xURLTransformer;
605 xFrame = m_xFrame;
606 xPersistentWindowState = m_xPersistentWindowState;
607 aLock.clear();
609 if ( xPopupMenu.is() )
611 VCLXPopupMenu* pPopupMenu = static_cast<VCLXPopupMenu *>(VCLXPopupMenu::GetImplementation( xPopupMenu ));
612 if ( pPopupMenu )
614 SolarMutexGuard aSolarMutexGuard;
615 PopupMenu* pVCLPopupMenu = static_cast<PopupMenu *>(pPopupMenu->GetMenu());
617 OUString aCmd( pVCLPopupMenu->GetItemCommand( rEvent.MenuId ));
618 if ( aCmd.startsWith( STATIC_INTERNAL_CMD_PART ) )
620 // Command to restore the visibility of all context sensitive toolbars
621 Reference< XNameReplace > xNameReplace( xPersistentWindowState, UNO_QUERY );
622 if ( xPersistentWindowState.is() && xNameReplace.is() )
626 Sequence< OUString > aElementNames = xPersistentWindowState->getElementNames();
627 sal_Int32 nCount = aElementNames.getLength();
628 bool bRefreshToolbars( false );
630 for ( sal_Int32 i = 0; i < nCount; i++ )
634 OUString aElementName = aElementNames[i];
635 Sequence< PropertyValue > aWindowState;
637 if ( xPersistentWindowState->getByName( aElementName ) >>= aWindowState )
639 bool bVisible( false );
640 bool bContextSensitive( false );
641 sal_Int32 nVisibleIndex( -1 );
642 for ( sal_Int32 j = 0; j < aWindowState.getLength(); j++ )
644 if ( aWindowState[j].Name == WINDOWSTATE_PROPERTY_VISIBLE )
646 aWindowState[j].Value >>= bVisible;
647 nVisibleIndex = j;
649 else if ( aWindowState[j].Name == WINDOWSTATE_PROPERTY_CONTEXT )
650 aWindowState[j].Value >>= bContextSensitive;
653 if ( !bVisible && bContextSensitive && nVisibleIndex >= 0 )
655 // Default is: Every context sensitive toolbar is visible
656 aWindowState[nVisibleIndex].Value <<= sal_True;
657 xNameReplace->replaceByName( aElementName, makeAny( aWindowState ));
658 bRefreshToolbars = true;
662 catch ( const NoSuchElementException& )
667 if ( bRefreshToolbars )
669 Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( xFrame ));
670 if ( xLayoutManager.is() )
672 Reference< XPropertySet > xPropSet( xLayoutManager, UNO_QUERY );
673 if ( xPropSet.is() )
677 xPropSet->setPropertyValue("RefreshContextToolbarVisibility", makeAny( sal_True ));
679 catch ( const RuntimeException& )
682 catch ( const Exception& )
687 RefreshToolbars( xFrame );
690 catch ( const RuntimeException& )
692 throw;
694 catch ( const Exception& )
699 else if ( aCmd.indexOf( STATIC_CMD_PART ) < 0 )
701 URL aTargetURL;
702 Sequence<PropertyValue> aArgs;
704 aTargetURL.Complete = aCmd;
705 xURLTransformer->parseStrict( aTargetURL );
706 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
707 if ( xDispatchProvider.is() )
709 Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch(
710 aTargetURL, OUString(), 0 );
712 ExecuteInfo* pExecuteInfo = new ExecuteInfo;
713 pExecuteInfo->xDispatch = xDispatch;
714 pExecuteInfo->aTargetURL = aTargetURL;
715 pExecuteInfo->aArgs = aArgs;
716 Application::PostUserEvent( LINK(0, ToolbarsMenuController, ExecuteHdl_Impl), pExecuteInfo );
719 else
721 Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( xFrame ));
722 if ( xLayoutManager.is() )
724 // Extract toolbar name from the combined uno-command.
725 sal_Int32 nIndex = aCmd.indexOf( '=' );
726 if (( nIndex > 0 ) && (( nIndex+1 ) < aCmd.getLength() ))
728 OUStringBuffer aBuf( STATIC_PRIVATE_TB_RESOURCE );
729 aBuf.append( aCmd.copy( nIndex+1 ));
731 bool bShow( !pVCLPopupMenu->IsItemChecked( rEvent.MenuId ));
732 OUString aToolBarResName( aBuf.makeStringAndClear() );
733 if ( bShow )
735 xLayoutManager->createElement( aToolBarResName );
736 xLayoutManager->showElement( aToolBarResName );
738 else
740 // closing means:
741 // hide and destroy element
742 xLayoutManager->hideElement( aToolBarResName );
743 xLayoutManager->destroyElement( aToolBarResName );
752 void SAL_CALL ToolbarsMenuController::itemActivated( const css::awt::MenuEvent& ) throw (RuntimeException, std::exception)
754 std::vector< OUString > aCmdVector;
755 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
756 Reference< XURLTransformer > xURLTransformer( m_xURLTransformer );
758 osl::MutexGuard aLock( m_aMutex );
759 fillPopupMenu( m_xPopupMenu );
760 aCmdVector = m_aCommandVector;
763 // Update status for all commands inside our toolbars popup menu
764 const sal_uInt32 nCount = aCmdVector.size();
765 for ( sal_uInt32 i = 0; i < nCount; i++ )
767 bool bInternal = aCmdVector[i].startsWith( STATIC_INTERNAL_CMD_PART );
769 if ( !bInternal )
771 URL aTargetURL;
772 aTargetURL.Complete = aCmdVector[i];
773 xURLTransformer->parseStrict( aTargetURL );
774 Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
775 if ( xDispatch.is() )
777 xDispatch->addStatusListener( (static_cast< XStatusListener* >(this)), aTargetURL );
778 xDispatch->removeStatusListener( (static_cast< XStatusListener* >(this)), aTargetURL );
781 else if ( aCmdVector[i] == CMD_RESTOREVISIBILITY )
783 // Special code to determine the enable/disable state of this command
784 FeatureStateEvent aFeatureStateEvent;
785 aFeatureStateEvent.FeatureURL.Complete = aCmdVector[i];
786 aFeatureStateEvent.IsEnabled = isContextSensitiveToolbarNonVisible();
787 statusChanged( aFeatureStateEvent );
792 // XPopupMenuController
793 void SAL_CALL ToolbarsMenuController::setPopupMenu( const Reference< css::awt::XPopupMenu >& xPopupMenu ) throw ( RuntimeException, std::exception )
795 osl::MutexGuard aLock( m_aMutex );
797 throwIfDisposed();
799 if ( m_xFrame.is() && !m_xPopupMenu.is() )
801 // Create popup menu on demand
802 SolarMutexGuard aSolarMutexGuard;
804 m_xPopupMenu = xPopupMenu;
805 m_xPopupMenu->addMenuListener( Reference< css::awt::XMenuListener >( (OWeakObject*)this, UNO_QUERY ));
806 fillPopupMenu( m_xPopupMenu );
810 // XInitialization
811 void SAL_CALL ToolbarsMenuController::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException, std::exception )
813 osl::MutexGuard aLock( m_aMutex );
814 bool bInitalized( m_bInitialized );
815 if ( !bInitalized )
817 svt::PopupMenuControllerBase::initialize(aArguments);
819 if ( m_bInitialized )
821 Reference< XModuleManager2 > xModuleManager = ModuleManager::create( m_xContext );
822 Reference< XNameAccess > xPersistentWindowStateSupplier = ::com::sun::star::ui::theWindowStateConfiguration::get( m_xContext );
824 // Retrieve persistent window state reference for our module
825 OUString aModuleIdentifier;
828 aModuleIdentifier = xModuleManager->identify( m_xFrame );
829 xPersistentWindowStateSupplier->getByName( aModuleIdentifier ) >>= m_xPersistentWindowState;
831 Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier =
832 theModuleUIConfigurationManagerSupplier::get( m_xContext );
833 m_xModuleCfgMgr = xModuleCfgSupplier->getUIConfigurationManager( aModuleIdentifier );
835 Reference< XController > xController = m_xFrame->getController();
836 Reference< XModel > xModel;
837 if ( xController.is() )
838 xModel = xController->getModel();
839 if ( xModel.is() )
841 Reference< XUIConfigurationManagerSupplier > xUIConfigurationManagerSupplier( xModel, UNO_QUERY );
842 if ( xUIConfigurationManagerSupplier.is() )
843 m_xDocCfgMgr = xUIConfigurationManagerSupplier->getUIConfigurationManager();
845 m_aModuleIdentifier = aModuleIdentifier;
847 catch ( const Exception& )
854 IMPL_STATIC_LINK( ToolbarsMenuController, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo )
858 // Asynchronous execution as this can lead to our own destruction!
859 // Framework can recycle our current frame and the layout manager disposes all user interface
860 // elements if a component gets detached from its frame!
861 if ( pExecuteInfo->xDispatch.is() )
863 pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
866 catch ( const Exception& )
870 delete pExecuteInfo;
871 return 0;
876 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */