Update ooo320-m1
[ooovba.git] / framework / source / uielement / toolbarsmenucontroller.cxx
bloba90e847020fa8e69fb06ae1f3a2b2d56025b55b0
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: toolbarsmenucontroller.cxx,v $
10 * $Revision: 1.21.40.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_framework.hxx"
33 #include <uielement/toolbarsmenucontroller.hxx>
35 #include <algorithm>
37 //_________________________________________________________________________________________________________________
38 // my own includes
39 //_________________________________________________________________________________________________________________
40 #include <threadhelp/resetableguard.hxx>
41 #include "services.h"
42 #ifndef __FRAMEWORK_CLASSES_RESOURCE_HRC_
43 #include <classes/resource.hrc>
44 #endif
45 #include <classes/fwkresid.hxx>
46 #include <uiconfiguration/windowstateconfiguration.hxx>
47 #include <helper/imageproducer.hxx>
48 #include <classes/sfxhelperfunctions.hxx>
50 //_________________________________________________________________________________________________________________
51 // interface includes
52 //_________________________________________________________________________________________________________________
53 #include <com/sun/star/awt/XDevice.hpp>
54 #include <com/sun/star/beans/PropertyValue.hpp>
55 #include <com/sun/star/awt/MenuItemStyle.hpp>
56 #include <com/sun/star/frame/XDispatchProvider.hpp>
57 #include <com/sun/star/container/XNameContainer.hpp>
58 #include <com/sun/star/beans/XPropertySet.hpp>
59 #include <com/sun/star/frame/XLayoutManager.hpp>
60 #include <com/sun/star/ui/XUIElementSettings.hpp>
61 #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
62 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
63 #include <com/sun/star/ui/UIElementType.hpp>
64 #include <com/sun/star/lang/DisposedException.hpp>
66 //_________________________________________________________________________________________________________________
67 // includes of other projects
68 //_________________________________________________________________________________________________________________
70 #ifndef _VCL_MENU_HXX_
71 #include <vcl/menu.hxx>
72 #endif
73 #include <vcl/svapp.hxx>
74 #include <vcl/i18nhelp.hxx>
75 #include <vcl/image.hxx>
76 #include <tools/urlobj.hxx>
77 #include <rtl/ustrbuf.hxx>
78 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
79 #include <toolkit/unohlp.hxx>
80 #endif
81 #include <vcl/window.hxx>
82 #include <svtools/menuoptions.hxx>
83 #include <svtools/cmdoptions.hxx>
84 #include <dispatch/uieventloghelper.hxx>
85 #include <rtl/logfile.hxx>
86 #include <svtools/miscopt.hxx>
88 //_________________________________________________________________________________________________________________
89 // Defines
90 //_________________________________________________________________________________________________________________
93 using namespace ::com::sun::star;
94 using namespace ::com::sun::star::uno;
95 using namespace ::com::sun::star::lang;
96 using namespace ::com::sun::star::frame;
97 using namespace ::com::sun::star::beans;
98 using namespace ::com::sun::star::util;
99 using namespace ::com::sun::star::container;
100 using namespace ::com::sun::star::frame;
101 using namespace ::com::sun::star::ui;
103 static const char CONFIGURE_TOOLBARS_CMD[] = "ConfigureDialog";
104 static const char CONFIGURE_TOOLBARS[] = ".uno:ConfigureDialog";
105 static const char CMD_COLORBAR[] = ".uno:ColorControl";
106 static const char CMD_HYPERLINKBAR[] = ".uno:InsertHyperlink";
107 static const char CMD_FORMULABAR[] = ".uno:InsertFormula";
108 static const char CMD_INPUTLINEBAR[] = ".uno:InputLineVisible";
109 static const char CMD_RESTOREVISIBILITY[] = ".cmd:RestoreVisibility";
110 static const char ITEM_DESCRIPTOR_RESOURCEURL[] = "ResourceURL";
111 static const char ITEM_DESCRIPTOR_UINAME[] = "UIName";
112 static const char STATIC_PRIVATE_TB_RESOURCE[] = "private:resource/toolbar/";
114 static const char STATIC_CMD_PART[] = ".uno:AvailableToolbars?Toolbar:string=";
115 static const char STATIC_INTERNAL_CMD_PART[] = ".cmd:";
117 namespace framework
120 typedef std::hash_map< rtl::OUString, rtl::OUString, OUStringHashCode, ::std::equal_to< ::rtl::OUString > > ToolbarHashMap;
122 struct ToolBarEntry
124 rtl::OUString aUIName;
125 rtl::OUString aCommand;
126 sal_Bool bVisible;
127 sal_Bool bContextSensitive;
128 const CollatorWrapper* pCollatorWrapper;
131 sal_Bool CompareToolBarEntry( const ToolBarEntry& aOne, const ToolBarEntry& aTwo )
133 sal_Int32 nComp = aOne.pCollatorWrapper->compareString( aOne.aUIName, aTwo.aUIName );
135 if ( nComp < 0 )
136 return sal_True;
137 else if ( nComp > 0 )
138 return sal_False;
139 else
140 return sal_False;
143 Reference< XLayoutManager > getLayoutManagerFromFrame( const Reference< XFrame >& rFrame )
145 Reference< XPropertySet > xPropSet( rFrame, UNO_QUERY );
146 Reference< XLayoutManager > xLayoutManager;
150 xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))) >>= xLayoutManager;
152 catch ( UnknownPropertyException& )
156 return xLayoutManager;
159 struct ToolBarInfo
161 rtl::OUString aToolBarResName;
162 rtl::OUString aToolBarUIName;
165 DEFINE_XSERVICEINFO_MULTISERVICE ( ToolbarsMenuController ,
166 OWeakObject ,
167 SERVICENAME_POPUPMENUCONTROLLER ,
168 IMPLEMENTATIONNAME_TOOLBARSMENUCONTROLLER
171 DEFINE_INIT_SERVICE ( ToolbarsMenuController, {} )
173 ToolbarsMenuController::ToolbarsMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
174 PopupMenuControllerBase( xServiceManager ),
175 m_aPropUIName( RTL_CONSTASCII_USTRINGPARAM( "UIName" )),
176 m_aPropResourceURL( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" )),
177 m_bModuleIdentified( sal_False ),
178 m_bResetActive( sal_False ),
179 m_aIntlWrapper( xServiceManager, Application::GetSettings().GetLocale() )
183 ToolbarsMenuController::~ToolbarsMenuController()
187 void ToolbarsMenuController::addCommand(
188 Reference< css::awt::XPopupMenu >& rPopupMenu, const rtl::OUString& rCommandURL, USHORT nHelpId, const rtl::OUString& rLabel )
190 USHORT nItemId = m_xPopupMenu->getItemCount()+1;
192 rtl::OUString aLabel;
193 if ( rLabel.getLength() == 0 )
194 aLabel = getUINameFromCommand( rCommandURL );
195 else
196 aLabel = rLabel;
198 rPopupMenu->insertItem( nItemId, aLabel, 0, nItemId );
199 Reference< awt::XMenuExtended > xMenuExtended( m_xPopupMenu, UNO_QUERY );
200 xMenuExtended->setCommand( nItemId, rCommandURL );
202 bool bInternal = ( rCommandURL.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_INTERNAL_CMD_PART ))) == 0);
203 if ( !bInternal )
205 if ( !getDispatchFromCommandURL( rCommandURL ).is() )
206 m_xPopupMenu->enableItem( nItemId, sal_False );
209 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
211 Image aImage;
212 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
214 if ( rSettings.GetUseImagesInMenus() )
215 aImage = GetImageFromURL( m_xFrame, rCommandURL, FALSE, rSettings.GetHighContrastMode() );
217 VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXPopupMenu::GetImplementation( rPopupMenu );
218 if ( pPopupMenu )
220 PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
221 if ( !!aImage )
222 pVCLPopupMenu->SetItemImage( nItemId, aImage );
223 pVCLPopupMenu->SetHelpId( nItemId, nHelpId );
226 m_aCommandVector.push_back( rCommandURL );
229 Reference< XDispatch > ToolbarsMenuController::getDispatchFromCommandURL( const rtl::OUString& rCommandURL )
231 URL aTargetURL;
232 Sequence<PropertyValue> aArgs;
233 Reference< XURLTransformer > xURLTransformer;
234 Reference< XFrame > xFrame;
237 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
238 xURLTransformer = m_xURLTransformer;
239 xFrame = m_xFrame;
242 aTargetURL.Complete = rCommandURL;
243 xURLTransformer->parseStrict( aTargetURL );
244 Reference< XDispatchProvider > xDispatchProvider( xFrame, UNO_QUERY );
245 if ( xDispatchProvider.is() )
246 return xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
247 else
248 return Reference< XDispatch >();
251 // private function
252 rtl::OUString ToolbarsMenuController::getUINameFromCommand( const rtl::OUString& rCommandURL )
254 rtl::OUString aLabel;
256 if ( !m_bModuleIdentified )
260 Reference< XModuleManager > xModuleManager( m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW );
261 m_aModuleIdentifier = xModuleManager->identify( m_xFrame );
262 Reference< XNameAccess > xNameAccess( m_xServiceManager->createInstance(
263 SERVICENAME_UICOMMANDDESCRIPTION ),
264 UNO_QUERY );
265 xNameAccess->getByName( m_aModuleIdentifier ) >>= m_xUICommandDescription;
267 catch ( Exception& )
272 if ( m_xUICommandDescription.is() )
276 Sequence< PropertyValue > aPropSeq;
277 rtl::OUString aStr;
278 if ( m_xUICommandDescription->getByName( rCommandURL ) >>= aPropSeq )
280 for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
282 if ( aPropSeq[i].Name.equalsAscii( "Label" ))
284 aPropSeq[i].Value >>= aStr;
285 break;
289 aLabel = aStr;
291 catch ( Exception& )
296 return aLabel;
299 static void fillHashMap( const Sequence< Sequence< ::com::sun::star::beans::PropertyValue > >& rSeqToolBars,
300 ToolbarHashMap& rHashMap )
302 for ( sal_Int32 i = 0; i < rSeqToolBars.getLength(); i++ )
304 rtl::OUString aResourceURL;
305 rtl::OUString aUIName;
306 const PropertyValue* pProperties = rSeqToolBars[i].getConstArray();
307 for ( sal_Int32 j = 0; j < rSeqToolBars[i].getLength(); j++ )
309 if ( pProperties[j].Name.equalsAscii( ITEM_DESCRIPTOR_RESOURCEURL) )
310 pProperties[j].Value >>= aResourceURL;
311 else if ( pProperties[j].Name.equalsAscii( ITEM_DESCRIPTOR_UINAME) )
312 pProperties[j].Value >>= aUIName;
315 if ( aResourceURL.getLength() > 0 &&
316 rHashMap.find( aResourceURL ) == rHashMap.end() )
317 rHashMap.insert( ToolbarHashMap::value_type( aResourceURL, aUIName ));
321 // private function
322 Sequence< Sequence< com::sun::star::beans::PropertyValue > > ToolbarsMenuController::getLayoutManagerToolbars( const Reference< ::com::sun::star::frame::XLayoutManager >& rLayoutManager )
324 std::vector< ToolBarInfo > aToolBarArray;
325 Sequence< Reference< XUIElement > > aUIElements = rLayoutManager->getElements();
326 for ( sal_Int32 i = 0; i < aUIElements.getLength(); i++ )
328 Reference< XUIElement > xUIElement( aUIElements[i] );
329 Reference< XPropertySet > xPropSet( aUIElements[i], UNO_QUERY );
330 if ( xPropSet.is() && xUIElement.is() )
334 rtl::OUString aResName;
335 sal_Int16 nType( -1 );
336 xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ))) >>= nType;
337 xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" ))) >>= aResName;
339 if (( nType == ::com::sun::star::ui::UIElementType::TOOLBAR ) &&
340 ( aResName.getLength() > 0 ))
342 ToolBarInfo aToolBarInfo;
344 aToolBarInfo.aToolBarResName = aResName;
346 vos::OGuard aGuard( Application::GetSolarMutex() );
347 Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY );
348 Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
349 if ( pWindow )
350 aToolBarInfo.aToolBarUIName = pWindow->GetText();
352 aToolBarArray.push_back( aToolBarInfo );
355 catch ( Exception& )
361 Sequence< com::sun::star::beans::PropertyValue > aTbSeq( 2 );
362 aTbSeq[0].Name = m_aPropUIName;
363 aTbSeq[1].Name = m_aPropResourceURL;
365 Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeq( aToolBarArray.size() );
366 const sal_uInt32 nCount = aToolBarArray.size();
367 for ( sal_uInt32 i = 0; i < nCount; i++ )
369 aTbSeq[0].Value <<= aToolBarArray[i].aToolBarUIName;
370 aTbSeq[1].Value <<= aToolBarArray[i].aToolBarResName;
371 aSeq[i] = aTbSeq;
374 return aSeq;
377 sal_Bool ToolbarsMenuController::isContextSensitiveToolbarNonVisible()
379 return m_bResetActive;
382 void ToolbarsMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopupMenu )
384 if( SvtMiscOptions().DisableUICustomization() )
385 return;
387 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
388 resetPopupMenu( rPopupMenu );
390 m_aCommandVector.clear();
392 // Retrieve layout manager for additional information
393 rtl::OUString aEmptyString;
394 Reference< awt::XMenuExtended > xMenuExtended( rPopupMenu, UNO_QUERY );
395 Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( m_xFrame ));
397 m_bResetActive = sal_False;
398 if ( xLayoutManager.is() )
400 ToolbarHashMap aToolbarHashMap;
402 if ( m_xDocCfgMgr.is() )
404 Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeqDocToolBars =
405 m_xDocCfgMgr->getUIElementsInfo( UIElementType::TOOLBAR );
406 fillHashMap( aSeqDocToolBars, aToolbarHashMap );
409 if ( m_xModuleCfgMgr.is() )
411 Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeqToolBars =
412 m_xModuleCfgMgr->getUIElementsInfo( UIElementType::TOOLBAR );
413 fillHashMap( aSeqToolBars, aToolbarHashMap );
416 std::vector< ToolBarEntry > aSortedTbs;
417 rtl::OUString aStaticCmdPart( RTL_CONSTASCII_USTRINGPARAM( STATIC_CMD_PART ));
419 Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeqFrameToolBars = getLayoutManagerToolbars( xLayoutManager );
420 fillHashMap( aSeqFrameToolBars, aToolbarHashMap );
422 ToolbarHashMap::const_iterator pIter = aToolbarHashMap.begin();
423 while ( pIter != aToolbarHashMap.end() )
425 rtl::OUString aUIName = pIter->second;
426 sal_Bool bHideFromMenu( sal_False );
427 sal_Bool bContextSensitive( sal_False );
428 sal_Bool bVisible( sal_False );
429 if ( aUIName.getLength() == 0 &&
430 m_xPersistentWindowState.is() )
434 Sequence< PropertyValue > aWindowState;
435 Any a( m_xPersistentWindowState->getByName( pIter->first ));
437 if ( a >>= aWindowState )
439 for ( sal_Int32 i = 0; i < aWindowState.getLength(); i++ )
441 if ( aWindowState[i].Name.equalsAscii( WINDOWSTATE_PROPERTY_UINAME ))
442 aWindowState[i].Value >>= aUIName;
443 else if ( aWindowState[i].Name.equalsAscii( WINDOWSTATE_PROPERTY_HIDEFROMENU ))
444 aWindowState[i].Value >>= bHideFromMenu;
445 else if ( aWindowState[i].Name.equalsAscii( WINDOWSTATE_PROPERTY_CONTEXT ))
446 aWindowState[i].Value >>= bContextSensitive;
447 else if ( aWindowState[i].Name.equalsAscii( WINDOWSTATE_PROPERTY_VISIBLE ))
448 aWindowState[i].Value >>= bVisible;
452 catch ( Exception& )
456 // Check if we have to enable/disable "Reset" menu item
457 if ( bContextSensitive && !bVisible )
458 m_bResetActive = sal_True;
462 if (( aUIName.getLength() > 0 ) && ( !bHideFromMenu ))
464 ToolBarEntry aTbEntry;
465 aTbEntry.aUIName = aUIName;
466 aTbEntry.aCommand = pIter->first;
467 aTbEntry.bVisible = xLayoutManager->isElementVisible( pIter->first );
468 aTbEntry.bContextSensitive = bContextSensitive;
469 aTbEntry.pCollatorWrapper = m_aIntlWrapper.getCaseCollator();
470 aSortedTbs.push_back( aTbEntry );
472 pIter++;
475 // sort toolbars
476 std::sort( aSortedTbs.begin(), aSortedTbs.end(), CompareToolBarEntry );
478 sal_Int16 nIndex( 1 );
479 const sal_uInt32 nCount = aSortedTbs.size();
480 for ( sal_uInt32 i = 0; i < nCount; i++ )
482 USHORT nItemCount = m_xPopupMenu->getItemCount();
483 m_xPopupMenu->insertItem( nIndex, aSortedTbs[i].aUIName, css::awt::MenuItemStyle::CHECKABLE, nItemCount );
484 if ( aSortedTbs[i].bVisible )
485 m_xPopupMenu->checkItem( nIndex, sal_True );
488 vos::OGuard aGuard( Application::GetSolarMutex() );
489 VCLXPopupMenu* pXPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( m_xPopupMenu );
490 PopupMenu* pVCLPopupMenu = (PopupMenu *)pXPopupMenu->GetMenu();
492 pVCLPopupMenu->SetUserValue( nIndex, ULONG( aSortedTbs[i].bContextSensitive ? 1L : 0L ));
495 // use VCL popup menu pointer to set vital information that are not part of the awt implementation
496 rtl::OUStringBuffer aStrBuf( aStaticCmdPart );
498 sal_Int32 n = aSortedTbs[i].aCommand.lastIndexOf( '/' );
499 if (( n > 0 ) && (( n+1 ) < aSortedTbs[i].aCommand.getLength() ))
500 aStrBuf.append( aSortedTbs[i].aCommand.copy( n+1 ));
502 rtl::OUString aCmd( aStrBuf.makeStringAndClear() );
504 // Store complete uno-command so it can also be dispatched. This is necessary to support
505 // the test tool!
506 xMenuExtended->setCommand( nIndex, aCmd );
507 ++nIndex;
510 // Create commands for non-toolbars
511 if ( m_aModuleIdentifier.equalsAscii( "com.sun.star.text.TextDocument" ) ||
512 m_aModuleIdentifier.equalsAscii( "com.sun.star.text.WebDocument" ) ||
513 m_aModuleIdentifier.equalsAscii( "com.sun.star.text.GlobalDocument" ) ||
514 m_aModuleIdentifier.equalsAscii( "com.sun.star.drawing.DrawingDocument" ) ||
515 m_aModuleIdentifier.equalsAscii( "com.sun.star.presentation.PresentationDocument" ) ||
516 m_aModuleIdentifier.equalsAscii( "com.sun.star.sheet.SpreadsheetDocument" ))
518 addCommand( m_xPopupMenu, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CMD_HYPERLINKBAR )), 10360, aEmptyString );
519 if ( m_aModuleIdentifier.equalsAscii( "com.sun.star.drawing.DrawingDocument" ) ||
520 m_aModuleIdentifier.equalsAscii( "com.sun.star.presentation.PresentationDocument" ))
521 addCommand( m_xPopupMenu, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CMD_COLORBAR )), 10417, aEmptyString );
522 else if ( m_aModuleIdentifier.equalsAscii( "com.sun.star.sheet.SpreadsheetDocument" ))
523 addCommand( m_xPopupMenu, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CMD_INPUTLINEBAR )), 26241, aEmptyString );
524 else
525 addCommand( m_xPopupMenu, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CMD_FORMULABAR )), 20128, aEmptyString );
528 sal_Bool bAddCommand( sal_True );
529 SvtCommandOptions aCmdOptions;
530 rtl::OUString aConfigureToolbar( RTL_CONSTASCII_USTRINGPARAM( CONFIGURE_TOOLBARS ));
532 if ( aCmdOptions.HasEntries( SvtCommandOptions::CMDOPTION_DISABLED ))
534 if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED,
535 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CONFIGURE_TOOLBARS_CMD ))))
536 bAddCommand = sal_False;
539 if ( bAddCommand )
541 // Create command for configure
542 if ( m_xPopupMenu->getItemCount() > 0 )
544 USHORT nItemCount = m_xPopupMenu->getItemCount();
545 m_xPopupMenu->insertSeparator( nItemCount+1 );
548 addCommand( m_xPopupMenu, aConfigureToolbar, 5904, aEmptyString );
551 // Add separator if no configure has been added
552 if ( !bAddCommand )
554 // Create command for configure
555 if ( m_xPopupMenu->getItemCount() > 0 )
557 USHORT nItemCount = m_xPopupMenu->getItemCount();
558 m_xPopupMenu->insertSeparator( nItemCount+1 );
562 String aLabelStr = String( FwkResId( STR_RESTORE_TOOLBARS ));
563 rtl::OUString aRestoreCmd( RTL_CONSTASCII_USTRINGPARAM( CMD_RESTOREVISIBILITY ));
564 addCommand( m_xPopupMenu, aRestoreCmd, 9999, aLabelStr );
568 // XEventListener
569 void SAL_CALL ToolbarsMenuController::disposing( const EventObject& ) throw ( RuntimeException )
571 Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY );
573 ResetableGuard aLock( m_aLock );
574 m_xFrame.clear();
575 m_xDispatch.clear();
576 m_xDocCfgMgr.clear();
577 m_xModuleCfgMgr.clear();
578 m_xServiceManager.clear();
580 if ( m_xPopupMenu.is() )
581 m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY ));
582 m_xPopupMenu.clear();
585 // XStatusListener
586 void SAL_CALL ToolbarsMenuController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException )
588 rtl::OUString aFeatureURL( Event.FeatureURL.Complete );
590 // All other status events will be processed here
591 sal_Bool bSetCheckmark = sal_False;
592 sal_Bool bCheckmark = sal_False;
594 ResetableGuard aLock( m_aLock );
595 Reference< css::awt::XPopupMenu > xPopupMenu( m_xPopupMenu );
596 aLock.unlock();
598 if ( xPopupMenu.is() )
600 vos::OGuard aGuard( Application::GetSolarMutex() );
601 VCLXPopupMenu* pXPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( xPopupMenu );
602 PopupMenu* pVCLPopupMenu = (PopupMenu *)pXPopupMenu->GetMenu();
604 for ( USHORT i = 0; i < pVCLPopupMenu->GetItemCount(); i++ )
606 USHORT nId = pVCLPopupMenu->GetItemId( i );
607 if ( nId == 0 )
608 continue;
610 rtl::OUString aCmd = pVCLPopupMenu->GetItemCommand( nId );
611 if ( aCmd == aFeatureURL )
613 // Enable/disable item
614 pVCLPopupMenu->EnableItem( nId, Event.IsEnabled );
616 // Checkmark
617 if ( Event.State >>= bCheckmark )
618 bSetCheckmark = sal_True;
620 if ( bSetCheckmark )
621 pVCLPopupMenu->CheckItem( nId, bCheckmark );
622 else
624 rtl::OUString aItemText;
626 if ( Event.State >>= aItemText )
627 pVCLPopupMenu->SetItemText( nId, aItemText );
634 // XMenuListener
635 void SAL_CALL ToolbarsMenuController::select( const css::awt::MenuEvent& rEvent ) throw (RuntimeException)
637 Reference< css::awt::XPopupMenu > xPopupMenu;
638 Reference< XMultiServiceFactory > xServiceManager;
639 Reference< XURLTransformer > xURLTransformer;
640 Reference< XFrame > xFrame;
641 Reference< XNameAccess > xPersistentWindowState;
643 ResetableGuard aLock( m_aLock );
644 xPopupMenu = m_xPopupMenu;
645 xServiceManager = m_xServiceManager;
646 xURLTransformer = m_xURLTransformer;
647 xFrame = m_xFrame;
648 xPersistentWindowState = m_xPersistentWindowState;
649 aLock.unlock();
651 if ( xPopupMenu.is() )
653 VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXPopupMenu::GetImplementation( xPopupMenu );
654 if ( pPopupMenu )
656 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
657 PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
659 rtl::OUString aCmd( pVCLPopupMenu->GetItemCommand( rEvent.MenuId ));
660 if ( aCmd.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_INTERNAL_CMD_PART ))) == 0 )
662 // Command to restore the visibility of all context sensitive toolbars
663 Reference< XNameReplace > xNameReplace( xPersistentWindowState, UNO_QUERY );
664 if ( xPersistentWindowState.is() && xNameReplace.is() )
668 Sequence< rtl::OUString > aElementNames = xPersistentWindowState->getElementNames();
669 sal_Int32 nCount = aElementNames.getLength();
670 bool bRefreshToolbars( false );
672 for ( sal_Int32 i = 0; i < nCount; i++ )
676 rtl::OUString aElementName = aElementNames[i];
677 Sequence< PropertyValue > aWindowState;
679 if ( xPersistentWindowState->getByName( aElementName ) >>= aWindowState )
681 sal_Bool bVisible( sal_False );
682 sal_Bool bContextSensitive( sal_False );
683 sal_Int32 nVisibleIndex( -1 );
684 for ( sal_Int32 j = 0; j < aWindowState.getLength(); j++ )
686 if ( aWindowState[j].Name.equalsAscii( WINDOWSTATE_PROPERTY_VISIBLE ))
688 aWindowState[j].Value >>= bVisible;
689 nVisibleIndex = j;
691 else if ( aWindowState[j].Name.equalsAscii( WINDOWSTATE_PROPERTY_CONTEXT ))
692 aWindowState[j].Value >>= bContextSensitive;
695 if ( !bVisible && bContextSensitive && nVisibleIndex >= 0 )
697 // Default is: Every context sensitive toolbar is visible
698 aWindowState[nVisibleIndex].Value <<= sal_True;
699 xNameReplace->replaceByName( aElementName, makeAny( aWindowState ));
700 bRefreshToolbars = true;
704 catch ( NoSuchElementException& )
709 if ( bRefreshToolbars )
711 Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( xFrame ));
712 if ( xLayoutManager.is() )
714 Reference< XPropertySet > xPropSet( xLayoutManager, UNO_QUERY );
715 if ( xPropSet.is() )
719 xPropSet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RefreshContextToolbarVisibility" )), makeAny( sal_True ));
721 catch ( RuntimeException& )
724 catch ( Exception& )
729 RefreshToolbars( xFrame );
732 catch ( RuntimeException& )
734 throw;
736 catch ( Exception& )
741 else if ( aCmd.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_CMD_PART ))) < 0 )
743 URL aTargetURL;
744 Sequence<PropertyValue> aArgs;
746 aTargetURL.Complete = aCmd;
747 xURLTransformer->parseStrict( aTargetURL );
748 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
749 if ( xDispatchProvider.is() )
751 Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch(
752 aTargetURL, ::rtl::OUString(), 0 );
754 ExecuteInfo* pExecuteInfo = new ExecuteInfo;
755 pExecuteInfo->xDispatch = xDispatch;
756 pExecuteInfo->aTargetURL = aTargetURL;
757 pExecuteInfo->aArgs = aArgs;
758 if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
759 UiEventLogHelper(::rtl::OUString::createFromAscii("ToolbarsMenuController")).log(m_xServiceManager, m_xFrame, aTargetURL, aArgs);
760 Application::PostUserEvent( STATIC_LINK(0, ToolbarsMenuController, ExecuteHdl_Impl), pExecuteInfo );
763 else
765 Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( xFrame ));
766 if ( xLayoutManager.is() )
768 // Extract toolbar name from the combined uno-command.
769 sal_Int32 nIndex = aCmd.indexOf( '=' );
770 if (( nIndex > 0 ) && (( nIndex+1 ) < aCmd.getLength() ))
772 rtl::OUStringBuffer aBuf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_PRIVATE_TB_RESOURCE )));
773 aBuf.append( aCmd.copy( nIndex+1 ));
775 sal_Bool bShow( !pVCLPopupMenu->IsItemChecked( rEvent.MenuId ));
776 rtl::OUString aToolBarResName( aBuf.makeStringAndClear() );
777 if ( bShow )
779 xLayoutManager->createElement( aToolBarResName );
780 xLayoutManager->showElement( aToolBarResName );
782 else
784 // closing means:
785 // hide and destroy element
786 xLayoutManager->hideElement( aToolBarResName );
787 xLayoutManager->destroyElement( aToolBarResName );
796 void SAL_CALL ToolbarsMenuController::activate( const css::awt::MenuEvent& ) throw (RuntimeException)
798 std::vector< rtl::OUString > aCmdVector;
799 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
800 Reference< XURLTransformer > xURLTransformer( m_xURLTransformer );
802 ResetableGuard aLock( m_aLock );
803 fillPopupMenu( m_xPopupMenu );
804 aCmdVector = m_aCommandVector;
807 // Update status for all commands inside our toolbars popup menu
808 const sal_uInt32 nCount = aCmdVector.size();
809 for ( sal_uInt32 i = 0; i < nCount; i++ )
811 bool bInternal = ( aCmdVector[i].indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_INTERNAL_CMD_PART ))) == 0);
813 if ( !bInternal )
815 URL aTargetURL;
816 aTargetURL.Complete = aCmdVector[i];
817 xURLTransformer->parseStrict( aTargetURL );
818 Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
819 if ( xDispatch.is() )
821 xDispatch->addStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL );
822 xDispatch->removeStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL );
825 else if ( aCmdVector[i].equalsAscii( CMD_RESTOREVISIBILITY ))
827 // Special code to determine the enable/disable state of this command
828 FeatureStateEvent aFeatureStateEvent;
829 aFeatureStateEvent.FeatureURL.Complete = aCmdVector[i];
830 aFeatureStateEvent.IsEnabled = isContextSensitiveToolbarNonVisible();
831 statusChanged( aFeatureStateEvent );
836 // XPopupMenuController
837 void SAL_CALL ToolbarsMenuController::setPopupMenu( const Reference< css::awt::XPopupMenu >& xPopupMenu ) throw ( RuntimeException )
839 ResetableGuard aLock( m_aLock );
841 if ( m_bDisposed )
842 throw DisposedException();
844 if ( m_xFrame.is() && !m_xPopupMenu.is() )
846 // Create popup menu on demand
847 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
849 m_xPopupMenu = xPopupMenu;
850 m_xPopupMenu->addMenuListener( Reference< css::awt::XMenuListener >( (OWeakObject*)this, UNO_QUERY ));
851 fillPopupMenu( m_xPopupMenu );
855 // XInitialization
856 void SAL_CALL ToolbarsMenuController::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
858 ResetableGuard aLock( m_aLock );
859 sal_Bool bInitalized( m_bInitialized );
860 if ( !bInitalized )
862 PopupMenuControllerBase::initialize(aArguments);
864 if ( m_bInitialized )
866 Reference< XModuleManager > xModuleManager( m_xServiceManager->createInstance(
867 SERVICENAME_MODULEMANAGER ),
868 UNO_QUERY );
869 Reference< XNameAccess > xPersistentWindowStateSupplier( m_xServiceManager->createInstance(
870 SERVICENAME_WINDOWSTATECONFIGURATION ),
871 UNO_QUERY );
873 // Retrieve persistent window state reference for our module
874 if ( xPersistentWindowStateSupplier.is() && xModuleManager.is() )
876 rtl::OUString aModuleIdentifier;
879 aModuleIdentifier = xModuleManager->identify( m_xFrame );
880 xPersistentWindowStateSupplier->getByName( aModuleIdentifier ) >>= m_xPersistentWindowState;
882 Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier;
883 if ( m_xServiceManager.is() )
884 xModuleCfgSupplier = Reference< XModuleUIConfigurationManagerSupplier >(
885 m_xServiceManager->createInstance( SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ), UNO_QUERY );
886 m_xModuleCfgMgr = xModuleCfgSupplier->getUIConfigurationManager( aModuleIdentifier );
888 Reference< XController > xController = m_xFrame->getController();
889 Reference< XModel > xModel;
890 if ( xController.is() )
891 xModel = xController->getModel();
892 if ( xModel.is() )
894 Reference< XUIConfigurationManagerSupplier > xUIConfigurationManagerSupplier( xModel, UNO_QUERY );
895 if ( xUIConfigurationManagerSupplier.is() )
896 m_xDocCfgMgr = xUIConfigurationManagerSupplier->getUIConfigurationManager();
898 m_aModuleIdentifier = aModuleIdentifier;
900 catch ( Exception& )
908 IMPL_STATIC_LINK_NOINSTANCE( ToolbarsMenuController, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo )
912 // Asynchronous execution as this can lead to our own destruction!
913 // Framework can recycle our current frame and the layout manager disposes all user interface
914 // elements if a component gets detached from its frame!
915 if ( pExecuteInfo->xDispatch.is() )
917 pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
920 catch ( Exception& )
924 delete pExecuteInfo;
925 return 0;