bump product version to 4.1.6.2
[LibreOffice.git] / framework / source / uielement / toolbarsmenucontroller.cxx
blobd992c621c18122a42e1cd54e10db7c046e771567
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 <threadhelp/resetableguard.hxx>
25 #include "services.h"
26 #include <classes/resource.hrc>
27 #include <classes/fwkresid.hxx>
28 #include <uiconfiguration/windowstateconfiguration.hxx>
29 #include <framework/imageproducer.hxx>
30 #include <framework/sfxhelperfunctions.hxx>
32 #include <com/sun/star/awt/XDevice.hpp>
33 #include <com/sun/star/beans/PropertyValue.hpp>
34 #include <com/sun/star/awt/MenuItemStyle.hpp>
35 #include <com/sun/star/frame/ModuleManager.hpp>
36 #include <com/sun/star/frame/XDispatchProvider.hpp>
37 #include <com/sun/star/frame/UICommandDescription.hpp>
38 #include <com/sun/star/container/XNameContainer.hpp>
39 #include <com/sun/star/beans/XPropertySet.hpp>
40 #include <com/sun/star/frame/XLayoutManager.hpp>
41 #include <com/sun/star/ui/XUIElementSettings.hpp>
42 #include <com/sun/star/ui/ModuleUIConfigurationManagerSupplier.hpp>
43 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
44 #include <com/sun/star/ui/UIElementType.hpp>
45 #include <com/sun/star/ui/WindowStateConfiguration.hpp>
47 #include <vcl/menu.hxx>
48 #include <vcl/svapp.hxx>
49 #include <vcl/i18nhelp.hxx>
50 #include <vcl/image.hxx>
51 #include <rtl/ustrbuf.hxx>
52 #include <toolkit/unohlp.hxx>
53 #include <vcl/window.hxx>
54 #include <svtools/menuoptions.hxx>
55 #include <unotools/cmdoptions.hxx>
56 #include <rtl/logfile.hxx>
57 #include <svtools/miscopt.hxx>
59 //_________________________________________________________________________________________________________________
60 // Defines
61 //_________________________________________________________________________________________________________________
63 using namespace ::com::sun::star;
64 using namespace ::com::sun::star::uno;
65 using namespace ::com::sun::star::lang;
66 using namespace ::com::sun::star::frame;
67 using namespace ::com::sun::star::beans;
68 using namespace ::com::sun::star::util;
69 using namespace ::com::sun::star::container;
70 using namespace ::com::sun::star::ui;
72 static const char CONFIGURE_TOOLBARS_CMD[] = "ConfigureDialog";
73 static const char CONFIGURE_TOOLBARS[] = ".uno:ConfigureDialog";
74 static const char CMD_COLORBAR[] = ".uno:ColorControl";
75 static const char CMD_FORMULABAR[] = ".uno:InsertFormula";
76 static const char CMD_INPUTLINEBAR[] = ".uno:InputLineVisible";
77 static const char CMD_RESTOREVISIBILITY[] = ".cmd:RestoreVisibility";
78 static const char ITEM_DESCRIPTOR_RESOURCEURL[] = "ResourceURL";
79 static const char ITEM_DESCRIPTOR_UINAME[] = "UIName";
80 static const char STATIC_PRIVATE_TB_RESOURCE[] = "private:resource/toolbar/";
82 static const char STATIC_CMD_PART[] = ".uno:AvailableToolbars?Toolbar:string=";
83 static const char STATIC_INTERNAL_CMD_PART[] = ".cmd:";
85 namespace framework
88 typedef boost::unordered_map< OUString, OUString, OUStringHash, ::std::equal_to< OUString > > ToolbarHashMap;
90 struct ToolBarEntry
92 OUString aUIName;
93 OUString aCommand;
94 sal_Bool bVisible;
95 sal_Bool bContextSensitive;
96 const CollatorWrapper* pCollatorWrapper;
99 sal_Bool CompareToolBarEntry( const ToolBarEntry& aOne, const ToolBarEntry& aTwo )
101 sal_Int32 nComp = aOne.pCollatorWrapper->compareString( aOne.aUIName, aTwo.aUIName );
103 if ( nComp < 0 )
104 return sal_True;
105 else
106 return sal_False;
109 Reference< XLayoutManager > getLayoutManagerFromFrame( const Reference< XFrame >& rFrame )
111 Reference< XPropertySet > xPropSet( rFrame, UNO_QUERY );
112 Reference< XLayoutManager > xLayoutManager;
116 xPropSet->getPropertyValue( OUString( "LayoutManager" )) >>= xLayoutManager;
118 catch ( const UnknownPropertyException& )
122 return xLayoutManager;
125 struct ToolBarInfo
127 OUString aToolBarResName;
128 OUString aToolBarUIName;
131 DEFINE_XSERVICEINFO_MULTISERVICE ( ToolbarsMenuController ,
132 OWeakObject ,
133 SERVICENAME_POPUPMENUCONTROLLER ,
134 IMPLEMENTATIONNAME_TOOLBARSMENUCONTROLLER
137 DEFINE_INIT_SERVICE ( ToolbarsMenuController, {} )
139 ToolbarsMenuController::ToolbarsMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
140 svt::PopupMenuControllerBase( xServiceManager ),
141 m_aPropUIName( "UIName" ),
142 m_aPropResourceURL( "ResourceURL" ),
143 m_bModuleIdentified( sal_False ),
144 m_bResetActive( sal_False ),
145 m_aIntlWrapper( comphelper::getComponentContext(xServiceManager), Application::GetSettings().GetLanguageTag() )
149 ToolbarsMenuController::~ToolbarsMenuController()
153 void ToolbarsMenuController::addCommand(
154 Reference< css::awt::XPopupMenu >& rPopupMenu, const OUString& rCommandURL, const OUString& rLabel )
156 sal_uInt16 nItemId = m_xPopupMenu->getItemCount()+1;
158 OUString aLabel;
159 if ( rLabel.isEmpty() )
160 aLabel = getUINameFromCommand( rCommandURL );
161 else
162 aLabel = rLabel;
164 rPopupMenu->insertItem( nItemId, aLabel, 0, nItemId );
165 Reference< awt::XMenuExtended > xMenuExtended( m_xPopupMenu, UNO_QUERY );
166 xMenuExtended->setCommand( nItemId, rCommandURL );
168 bool bInternal = ( rCommandURL.indexOf( STATIC_INTERNAL_CMD_PART ) == 0);
169 if ( !bInternal )
171 if ( !getDispatchFromCommandURL( rCommandURL ).is() )
172 m_xPopupMenu->enableItem( nItemId, sal_False );
175 SolarMutexGuard aSolarMutexGuard;
177 Image aImage;
178 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
180 if ( rSettings.GetUseImagesInMenus() )
181 aImage = GetImageFromURL( m_xFrame, rCommandURL, false );
183 VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXPopupMenu::GetImplementation( rPopupMenu );
184 if ( pPopupMenu )
186 PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
187 if ( !!aImage )
188 pVCLPopupMenu->SetItemImage( nItemId, aImage );
191 m_aCommandVector.push_back( rCommandURL );
194 Reference< XDispatch > ToolbarsMenuController::getDispatchFromCommandURL( const OUString& rCommandURL )
196 URL aTargetURL;
197 Sequence<PropertyValue> aArgs;
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 // private function
217 OUString ToolbarsMenuController::getUINameFromCommand( const OUString& rCommandURL )
219 OUString aLabel;
221 if ( !m_bModuleIdentified )
225 Reference< XModuleManager2 > xModuleManager = ModuleManager::create( comphelper::getComponentContext(m_xServiceManager) );
226 m_aModuleIdentifier = xModuleManager->identify( m_xFrame );
227 Reference< XNameAccess > xNameAccess = frame::UICommandDescription::create( comphelper::getComponentContext(m_xServiceManager) );
228 xNameAccess->getByName( m_aModuleIdentifier ) >>= m_xUICommandDescription;
230 catch ( const Exception& )
235 if ( m_xUICommandDescription.is() )
239 Sequence< PropertyValue > aPropSeq;
240 OUString aStr;
241 if ( m_xUICommandDescription->getByName( rCommandURL ) >>= aPropSeq )
243 for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
245 if ( aPropSeq[i].Name == "Label" )
247 aPropSeq[i].Value >>= aStr;
248 break;
252 aLabel = aStr;
254 catch ( const Exception& )
259 return aLabel;
262 static void fillHashMap( const Sequence< Sequence< ::com::sun::star::beans::PropertyValue > >& rSeqToolBars,
263 ToolbarHashMap& rHashMap )
265 for ( sal_Int32 i = 0; i < rSeqToolBars.getLength(); i++ )
267 OUString aResourceURL;
268 OUString aUIName;
269 const PropertyValue* pProperties = rSeqToolBars[i].getConstArray();
270 for ( sal_Int32 j = 0; j < rSeqToolBars[i].getLength(); j++ )
272 if ( pProperties[j].Name == ITEM_DESCRIPTOR_RESOURCEURL )
273 pProperties[j].Value >>= aResourceURL;
274 else if ( pProperties[j].Name == ITEM_DESCRIPTOR_UINAME )
275 pProperties[j].Value >>= aUIName;
278 if ( !aResourceURL.isEmpty() &&
279 rHashMap.find( aResourceURL ) == rHashMap.end() )
280 rHashMap.insert( ToolbarHashMap::value_type( aResourceURL, aUIName ));
284 // private function
285 Sequence< Sequence< com::sun::star::beans::PropertyValue > > ToolbarsMenuController::getLayoutManagerToolbars( const Reference< ::com::sun::star::frame::XLayoutManager >& rLayoutManager )
287 std::vector< ToolBarInfo > aToolBarArray;
288 Sequence< Reference< XUIElement > > aUIElements = rLayoutManager->getElements();
289 for ( sal_Int32 i = 0; i < aUIElements.getLength(); i++ )
291 Reference< XUIElement > xUIElement( aUIElements[i] );
292 Reference< XPropertySet > xPropSet( aUIElements[i], UNO_QUERY );
293 if ( xPropSet.is() && xUIElement.is() )
297 OUString aResName;
298 sal_Int16 nType( -1 );
299 xPropSet->getPropertyValue( OUString( "Type" )) >>= nType;
300 xPropSet->getPropertyValue( OUString( "ResourceURL" )) >>= aResName;
302 if (( nType == ::com::sun::star::ui::UIElementType::TOOLBAR ) &&
303 !aResName.isEmpty() )
305 ToolBarInfo aToolBarInfo;
307 aToolBarInfo.aToolBarResName = aResName;
309 SolarMutexGuard aGuard;
310 Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY );
311 Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
312 if ( pWindow )
313 aToolBarInfo.aToolBarUIName = pWindow->GetText();
315 aToolBarArray.push_back( aToolBarInfo );
318 catch ( const Exception& )
324 Sequence< com::sun::star::beans::PropertyValue > aTbSeq( 2 );
325 aTbSeq[0].Name = m_aPropUIName;
326 aTbSeq[1].Name = m_aPropResourceURL;
328 Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeq( aToolBarArray.size() );
329 const sal_uInt32 nCount = aToolBarArray.size();
330 for ( sal_uInt32 i = 0; i < nCount; i++ )
332 aTbSeq[0].Value <<= aToolBarArray[i].aToolBarUIName;
333 aTbSeq[1].Value <<= aToolBarArray[i].aToolBarResName;
334 aSeq[i] = aTbSeq;
337 return aSeq;
340 sal_Bool ToolbarsMenuController::isContextSensitiveToolbarNonVisible()
342 return m_bResetActive;
345 void ToolbarsMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopupMenu )
347 if( SvtMiscOptions().DisableUICustomization() )
348 return;
350 SolarMutexGuard aSolarMutexGuard;
351 resetPopupMenu( rPopupMenu );
353 m_aCommandVector.clear();
355 // Retrieve layout manager for additional information
356 OUString aEmptyString;
357 Reference< awt::XMenuExtended > xMenuExtended( rPopupMenu, UNO_QUERY );
358 Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( m_xFrame ));
360 m_bResetActive = sal_False;
361 if ( xLayoutManager.is() )
363 ToolbarHashMap aToolbarHashMap;
365 if ( m_xDocCfgMgr.is() )
367 Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeqDocToolBars =
368 m_xDocCfgMgr->getUIElementsInfo( UIElementType::TOOLBAR );
369 fillHashMap( aSeqDocToolBars, aToolbarHashMap );
372 if ( m_xModuleCfgMgr.is() )
374 Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeqToolBars =
375 m_xModuleCfgMgr->getUIElementsInfo( UIElementType::TOOLBAR );
376 fillHashMap( aSeqToolBars, aToolbarHashMap );
379 std::vector< ToolBarEntry > aSortedTbs;
380 OUString aStaticCmdPart( STATIC_CMD_PART );
382 Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeqFrameToolBars = getLayoutManagerToolbars( xLayoutManager );
383 fillHashMap( aSeqFrameToolBars, aToolbarHashMap );
385 ToolbarHashMap::const_iterator pIter = aToolbarHashMap.begin();
386 while ( pIter != aToolbarHashMap.end() )
388 OUString aUIName = pIter->second;
389 sal_Bool bHideFromMenu( sal_False );
390 sal_Bool bContextSensitive( sal_False );
391 sal_Bool bVisible( sal_False );
392 if ( aUIName.isEmpty() &&
393 m_xPersistentWindowState.is() )
397 Sequence< PropertyValue > aWindowState;
398 Any a( m_xPersistentWindowState->getByName( pIter->first ));
400 if ( a >>= aWindowState )
402 for ( sal_Int32 i = 0; i < aWindowState.getLength(); i++ )
404 if ( aWindowState[i].Name == WINDOWSTATE_PROPERTY_UINAME )
405 aWindowState[i].Value >>= aUIName;
406 else if ( aWindowState[i].Name == WINDOWSTATE_PROPERTY_HIDEFROMENU )
407 aWindowState[i].Value >>= bHideFromMenu;
408 else if ( aWindowState[i].Name == WINDOWSTATE_PROPERTY_CONTEXT )
409 aWindowState[i].Value >>= bContextSensitive;
410 else if ( aWindowState[i].Name == WINDOWSTATE_PROPERTY_VISIBLE )
411 aWindowState[i].Value >>= bVisible;
415 catch ( const Exception& )
419 // Check if we have to enable/disable "Reset" menu item
420 if ( bContextSensitive && !bVisible )
421 m_bResetActive = sal_True;
425 if ( !aUIName.isEmpty() && !bHideFromMenu )
427 ToolBarEntry aTbEntry;
428 aTbEntry.aUIName = aUIName;
429 aTbEntry.aCommand = pIter->first;
430 aTbEntry.bVisible = xLayoutManager->isElementVisible( pIter->first );
431 aTbEntry.bContextSensitive = bContextSensitive;
432 aTbEntry.pCollatorWrapper = m_aIntlWrapper.getCaseCollator();
433 aSortedTbs.push_back( aTbEntry );
435 ++pIter;
438 // sort toolbars
439 std::sort( aSortedTbs.begin(), aSortedTbs.end(), CompareToolBarEntry );
441 sal_Int16 nIndex( 1 );
442 const sal_uInt32 nCount = aSortedTbs.size();
443 for ( sal_uInt32 i = 0; i < nCount; i++ )
445 sal_uInt16 nItemCount = m_xPopupMenu->getItemCount();
446 m_xPopupMenu->insertItem( nIndex, aSortedTbs[i].aUIName, css::awt::MenuItemStyle::CHECKABLE, nItemCount );
447 if ( aSortedTbs[i].bVisible )
448 m_xPopupMenu->checkItem( nIndex, sal_True );
451 SolarMutexGuard aGuard;
452 VCLXPopupMenu* pXPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( m_xPopupMenu );
453 PopupMenu* pVCLPopupMenu = (PopupMenu *)pXPopupMenu->GetMenu();
455 pVCLPopupMenu->SetUserValue( nIndex, sal_uIntPtr( aSortedTbs[i].bContextSensitive ? 1L : 0L ));
458 // use VCL popup menu pointer to set vital information that are not part of the awt implementation
459 OUStringBuffer aStrBuf( aStaticCmdPart );
461 sal_Int32 n = aSortedTbs[i].aCommand.lastIndexOf( '/' );
462 if (( n > 0 ) && (( n+1 ) < aSortedTbs[i].aCommand.getLength() ))
463 aStrBuf.append( aSortedTbs[i].aCommand.copy( n+1 ));
465 OUString aCmd( aStrBuf.makeStringAndClear() );
467 // Store complete uno-command so it can also be dispatched. This is necessary to support
468 // the test tool!
469 xMenuExtended->setCommand( nIndex, aCmd );
470 ++nIndex;
473 // Create commands for non-toolbars
474 if ( m_aModuleIdentifier == "com.sun.star.text.TextDocument" ||
475 m_aModuleIdentifier == "com.sun.star.text.WebDocument" ||
476 m_aModuleIdentifier == "com.sun.star.text.GlobalDocument" ||
477 m_aModuleIdentifier == "com.sun.star.drawing.DrawingDocument" ||
478 m_aModuleIdentifier == "com.sun.star.presentation.PresentationDocument" ||
479 m_aModuleIdentifier == "com.sun.star.sheet.SpreadsheetDocument" )
481 if ( m_aModuleIdentifier == "com.sun.star.drawing.DrawingDocument" ||
482 m_aModuleIdentifier == "com.sun.star.presentation.PresentationDocument" )
483 addCommand( m_xPopupMenu, OUString( CMD_COLORBAR ), aEmptyString );
484 else if ( m_aModuleIdentifier == "com.sun.star.sheet.SpreadsheetDocument" )
485 addCommand( m_xPopupMenu, OUString( CMD_INPUTLINEBAR ), aEmptyString );
486 else
487 addCommand( m_xPopupMenu, OUString( CMD_FORMULABAR ), aEmptyString );
490 sal_Bool bAddCommand( sal_True );
491 SvtCommandOptions aCmdOptions;
492 OUString aConfigureToolbar( CONFIGURE_TOOLBARS );
494 if ( aCmdOptions.HasEntries( SvtCommandOptions::CMDOPTION_DISABLED ))
496 if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED,
497 OUString( CONFIGURE_TOOLBARS_CMD )))
498 bAddCommand = sal_False;
501 if ( bAddCommand )
503 // Create command for configure
504 if ( m_xPopupMenu->getItemCount() > 0 )
506 sal_uInt16 nItemCount = m_xPopupMenu->getItemCount();
507 m_xPopupMenu->insertSeparator( nItemCount+1 );
510 addCommand( m_xPopupMenu, aConfigureToolbar, aEmptyString );
513 // Add separator if no configure has been added
514 if ( !bAddCommand )
516 // Create command for configure
517 if ( m_xPopupMenu->getItemCount() > 0 )
519 sal_uInt16 nItemCount = m_xPopupMenu->getItemCount();
520 m_xPopupMenu->insertSeparator( nItemCount+1 );
524 String aLabelStr = String( FwkResId( STR_RESTORE_TOOLBARS ));
525 OUString aRestoreCmd( CMD_RESTOREVISIBILITY );
526 addCommand( m_xPopupMenu, aRestoreCmd, aLabelStr );
530 // XEventListener
531 void SAL_CALL ToolbarsMenuController::disposing( const EventObject& ) throw ( RuntimeException )
533 Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY );
535 osl::MutexGuard aLock( m_aMutex );
536 m_xFrame.clear();
537 m_xDispatch.clear();
538 m_xDocCfgMgr.clear();
539 m_xModuleCfgMgr.clear();
540 m_xServiceManager.clear();
542 if ( m_xPopupMenu.is() )
543 m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY ));
544 m_xPopupMenu.clear();
547 // XStatusListener
548 void SAL_CALL ToolbarsMenuController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException )
550 OUString aFeatureURL( Event.FeatureURL.Complete );
552 // All other status events will be processed here
553 sal_Bool bSetCheckmark = sal_False;
554 sal_Bool bCheckmark = sal_False;
556 osl::ClearableMutexGuard aLock( m_aMutex );
557 Reference< css::awt::XPopupMenu > xPopupMenu( m_xPopupMenu );
558 aLock.clear();
560 if ( xPopupMenu.is() )
562 SolarMutexGuard aGuard;
563 VCLXPopupMenu* pXPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( xPopupMenu );
564 PopupMenu* pVCLPopupMenu = (PopupMenu *)pXPopupMenu->GetMenu();
566 for ( sal_uInt16 i = 0; i < pVCLPopupMenu->GetItemCount(); i++ )
568 sal_uInt16 nId = pVCLPopupMenu->GetItemId( i );
569 if ( nId == 0 )
570 continue;
572 OUString aCmd = pVCLPopupMenu->GetItemCommand( nId );
573 if ( aCmd == aFeatureURL )
575 // Enable/disable item
576 pVCLPopupMenu->EnableItem( nId, Event.IsEnabled );
578 // Checkmark
579 if ( Event.State >>= bCheckmark )
580 bSetCheckmark = sal_True;
582 if ( bSetCheckmark )
583 pVCLPopupMenu->CheckItem( nId, bCheckmark );
584 else
586 OUString aItemText;
588 if ( Event.State >>= aItemText )
589 pVCLPopupMenu->SetItemText( nId, aItemText );
596 // XMenuListener
597 void SAL_CALL ToolbarsMenuController::select( const css::awt::MenuEvent& rEvent ) throw (RuntimeException)
599 Reference< css::awt::XPopupMenu > xPopupMenu;
600 Reference< XMultiServiceFactory > xServiceManager;
601 Reference< XURLTransformer > xURLTransformer;
602 Reference< XFrame > xFrame;
603 Reference< XNameAccess > xPersistentWindowState;
605 osl::ClearableMutexGuard aLock( m_aMutex );
606 xPopupMenu = m_xPopupMenu;
607 xServiceManager = m_xServiceManager;
608 xURLTransformer = m_xURLTransformer;
609 xFrame = m_xFrame;
610 xPersistentWindowState = m_xPersistentWindowState;
611 aLock.clear();
613 if ( xPopupMenu.is() )
615 VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXPopupMenu::GetImplementation( xPopupMenu );
616 if ( pPopupMenu )
618 SolarMutexGuard aSolarMutexGuard;
619 PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
621 OUString aCmd( pVCLPopupMenu->GetItemCommand( rEvent.MenuId ));
622 if ( aCmd.indexOf( STATIC_INTERNAL_CMD_PART ) == 0 )
624 // Command to restore the visibility of all context sensitive toolbars
625 Reference< XNameReplace > xNameReplace( xPersistentWindowState, UNO_QUERY );
626 if ( xPersistentWindowState.is() && xNameReplace.is() )
630 Sequence< OUString > aElementNames = xPersistentWindowState->getElementNames();
631 sal_Int32 nCount = aElementNames.getLength();
632 bool bRefreshToolbars( false );
634 for ( sal_Int32 i = 0; i < nCount; i++ )
638 OUString aElementName = aElementNames[i];
639 Sequence< PropertyValue > aWindowState;
641 if ( xPersistentWindowState->getByName( aElementName ) >>= aWindowState )
643 sal_Bool bVisible( sal_False );
644 sal_Bool bContextSensitive( sal_False );
645 sal_Int32 nVisibleIndex( -1 );
646 for ( sal_Int32 j = 0; j < aWindowState.getLength(); j++ )
648 if ( aWindowState[j].Name == WINDOWSTATE_PROPERTY_VISIBLE )
650 aWindowState[j].Value >>= bVisible;
651 nVisibleIndex = j;
653 else if ( aWindowState[j].Name == WINDOWSTATE_PROPERTY_CONTEXT )
654 aWindowState[j].Value >>= bContextSensitive;
657 if ( !bVisible && bContextSensitive && nVisibleIndex >= 0 )
659 // Default is: Every context sensitive toolbar is visible
660 aWindowState[nVisibleIndex].Value <<= sal_True;
661 xNameReplace->replaceByName( aElementName, makeAny( aWindowState ));
662 bRefreshToolbars = true;
666 catch ( const NoSuchElementException& )
671 if ( bRefreshToolbars )
673 Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( xFrame ));
674 if ( xLayoutManager.is() )
676 Reference< XPropertySet > xPropSet( xLayoutManager, UNO_QUERY );
677 if ( xPropSet.is() )
681 xPropSet->setPropertyValue( OUString( "RefreshContextToolbarVisibility" ), makeAny( sal_True ));
683 catch ( const RuntimeException& )
686 catch ( const Exception& )
691 RefreshToolbars( xFrame );
694 catch ( const RuntimeException& )
696 throw;
698 catch ( const Exception& )
703 else if ( aCmd.indexOf( STATIC_CMD_PART ) < 0 )
705 URL aTargetURL;
706 Sequence<PropertyValue> aArgs;
708 aTargetURL.Complete = aCmd;
709 xURLTransformer->parseStrict( aTargetURL );
710 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
711 if ( xDispatchProvider.is() )
713 Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch(
714 aTargetURL, OUString(), 0 );
716 ExecuteInfo* pExecuteInfo = new ExecuteInfo;
717 pExecuteInfo->xDispatch = xDispatch;
718 pExecuteInfo->aTargetURL = aTargetURL;
719 pExecuteInfo->aArgs = aArgs;
720 Application::PostUserEvent( STATIC_LINK(0, ToolbarsMenuController, ExecuteHdl_Impl), pExecuteInfo );
723 else
725 Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( xFrame ));
726 if ( xLayoutManager.is() )
728 // Extract toolbar name from the combined uno-command.
729 sal_Int32 nIndex = aCmd.indexOf( '=' );
730 if (( nIndex > 0 ) && (( nIndex+1 ) < aCmd.getLength() ))
732 OUStringBuffer aBuf( OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_PRIVATE_TB_RESOURCE) ));
733 aBuf.append( aCmd.copy( nIndex+1 ));
735 sal_Bool bShow( !pVCLPopupMenu->IsItemChecked( rEvent.MenuId ));
736 OUString aToolBarResName( aBuf.makeStringAndClear() );
737 if ( bShow )
739 xLayoutManager->createElement( aToolBarResName );
740 xLayoutManager->showElement( aToolBarResName );
742 else
744 // closing means:
745 // hide and destroy element
746 xLayoutManager->hideElement( aToolBarResName );
747 xLayoutManager->destroyElement( aToolBarResName );
756 void SAL_CALL ToolbarsMenuController::activate( const css::awt::MenuEvent& ) throw (RuntimeException)
758 std::vector< OUString > aCmdVector;
759 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
760 Reference< XURLTransformer > xURLTransformer( m_xURLTransformer );
762 osl::MutexGuard aLock( m_aMutex );
763 fillPopupMenu( m_xPopupMenu );
764 aCmdVector = m_aCommandVector;
767 // Update status for all commands inside our toolbars popup menu
768 const sal_uInt32 nCount = aCmdVector.size();
769 for ( sal_uInt32 i = 0; i < nCount; i++ )
771 bool bInternal = ( aCmdVector[i].indexOf( STATIC_INTERNAL_CMD_PART ) == 0);
773 if ( !bInternal )
775 URL aTargetURL;
776 aTargetURL.Complete = aCmdVector[i];
777 xURLTransformer->parseStrict( aTargetURL );
778 Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
779 if ( xDispatch.is() )
781 xDispatch->addStatusListener( (static_cast< XStatusListener* >(this)), aTargetURL );
782 xDispatch->removeStatusListener( (static_cast< XStatusListener* >(this)), aTargetURL );
785 else if ( aCmdVector[i] == CMD_RESTOREVISIBILITY )
787 // Special code to determine the enable/disable state of this command
788 FeatureStateEvent aFeatureStateEvent;
789 aFeatureStateEvent.FeatureURL.Complete = aCmdVector[i];
790 aFeatureStateEvent.IsEnabled = isContextSensitiveToolbarNonVisible();
791 statusChanged( aFeatureStateEvent );
796 // XPopupMenuController
797 void SAL_CALL ToolbarsMenuController::setPopupMenu( const Reference< css::awt::XPopupMenu >& xPopupMenu ) throw ( RuntimeException )
799 osl::MutexGuard aLock( m_aMutex );
801 throwIfDisposed();
803 if ( m_xFrame.is() && !m_xPopupMenu.is() )
805 // Create popup menu on demand
806 SolarMutexGuard aSolarMutexGuard;
808 m_xPopupMenu = xPopupMenu;
809 m_xPopupMenu->addMenuListener( Reference< css::awt::XMenuListener >( (OWeakObject*)this, UNO_QUERY ));
810 fillPopupMenu( m_xPopupMenu );
814 // XInitialization
815 void SAL_CALL ToolbarsMenuController::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
817 osl::MutexGuard aLock( m_aMutex );
818 sal_Bool bInitalized( m_bInitialized );
819 if ( !bInitalized )
821 svt::PopupMenuControllerBase::initialize(aArguments);
823 if ( m_bInitialized )
825 Reference< XModuleManager2 > xModuleManager = ModuleManager::create( comphelper::getComponentContext(m_xServiceManager) );
826 Reference< XNameAccess > xPersistentWindowStateSupplier = ::com::sun::star::ui::WindowStateConfiguration::create( comphelper::getComponentContext(m_xServiceManager) );
828 // Retrieve persistent window state reference for our module
829 OUString aModuleIdentifier;
832 aModuleIdentifier = xModuleManager->identify( m_xFrame );
833 xPersistentWindowStateSupplier->getByName( aModuleIdentifier ) >>= m_xPersistentWindowState;
835 Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier =
836 ModuleUIConfigurationManagerSupplier::create( comphelper::getComponentContext(m_xServiceManager) );
837 m_xModuleCfgMgr = xModuleCfgSupplier->getUIConfigurationManager( aModuleIdentifier );
839 Reference< XController > xController = m_xFrame->getController();
840 Reference< XModel > xModel;
841 if ( xController.is() )
842 xModel = xController->getModel();
843 if ( xModel.is() )
845 Reference< XUIConfigurationManagerSupplier > xUIConfigurationManagerSupplier( xModel, UNO_QUERY );
846 if ( xUIConfigurationManagerSupplier.is() )
847 m_xDocCfgMgr = xUIConfigurationManagerSupplier->getUIConfigurationManager();
849 m_aModuleIdentifier = aModuleIdentifier;
851 catch ( const Exception& )
858 IMPL_STATIC_LINK_NOINSTANCE( ToolbarsMenuController, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo )
862 // Asynchronous execution as this can lead to our own destruction!
863 // Framework can recycle our current frame and the layout manager disposes all user interface
864 // elements if a component gets detached from its frame!
865 if ( pExecuteInfo->xDispatch.is() )
867 pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
870 catch ( const Exception& )
874 delete pExecuteInfo;
875 return 0;
880 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */