1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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>
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:";
85 typedef std::unordered_map
< OUString
, OUString
, OUStringHash
, std::equal_to
< OUString
> > ToolbarHashMap
;
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
);
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
;
124 OUString aToolBarResName
;
125 OUString aToolBarUIName
;
128 DEFINE_XSERVICEINFO_MULTISERVICE_2 ( ToolbarsMenuController
,
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;
157 if ( rLabel
.isEmpty() )
158 aLabel
= getUINameFromCommand( rCommandURL
);
162 rPopupMenu
->insertItem( nItemId
, aLabel
, 0, nItemId
);
163 rPopupMenu
->setCommand( nItemId
, rCommandURL
);
165 bool bInternal
= rCommandURL
.startsWith( STATIC_INTERNAL_CMD_PART
);
168 if ( !getDispatchFromCommandURL( rCommandURL
).is() )
169 m_xPopupMenu
->enableItem( nItemId
, sal_False
);
172 SolarMutexGuard aSolarMutexGuard
;
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
));
183 PopupMenu
* pVCLPopupMenu
= static_cast<PopupMenu
*>(pPopupMenu
->GetMenu());
185 pVCLPopupMenu
->SetItemImage( nItemId
, aImage
);
188 m_aCommandVector
.push_back( rCommandURL
);
191 Reference
< XDispatch
> ToolbarsMenuController::getDispatchFromCommandURL( const OUString
& rCommandURL
)
194 Reference
< XURLTransformer
> xURLTransformer
;
195 Reference
< XFrame
> xFrame
;
198 SolarMutexGuard aSolarMutexGuard
;
199 xURLTransformer
= m_xURLTransformer
;
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 );
209 return Reference
< XDispatch
>();
213 OUString
ToolbarsMenuController::getUINameFromCommand( const OUString
& rCommandURL
)
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
;
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
;
250 catch ( const Exception
& )
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
;
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
));
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() )
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
);
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
;
337 void ToolbarsMenuController::fillPopupMenu( Reference
< css::awt::XPopupMenu
>& rPopupMenu
)
339 if( SvtMiscOptions().DisableUICustomization() )
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
);
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
);
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
462 rPopupMenu
->setCommand( nIndex
, aCmd
);
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
);
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
)))
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
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
);
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
);
531 m_xDocCfgMgr
.clear();
532 m_xModuleCfgMgr
.clear();
535 if ( m_xPopupMenu
.is() )
536 m_xPopupMenu
->removeMenuListener( Reference
< css::awt::XMenuListener
>(( OWeakObject
*)this, UNO_QUERY
));
537 m_xPopupMenu
.clear();
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
);
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");
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
);
568 OUString aCmd
= pVCLPopupMenu
->GetItemCommand( nId
);
569 if ( aCmd
== aFeatureURL
)
571 // Enable/disable item
572 pVCLPopupMenu
->EnableItem( nId
, Event
.IsEnabled
);
575 if ( Event
.State
>>= bCheckmark
)
576 bSetCheckmark
= true;
579 pVCLPopupMenu
->CheckItem( nId
, bCheckmark
);
584 if ( Event
.State
>>= aItemText
)
585 pVCLPopupMenu
->SetItemText( nId
, aItemText
);
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
;
606 xPersistentWindowState
= m_xPersistentWindowState
;
609 if ( xPopupMenu
.is() )
611 VCLXPopupMenu
* pPopupMenu
= static_cast<VCLXPopupMenu
*>(VCLXPopupMenu::GetImplementation( xPopupMenu
));
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
;
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
);
677 xPropSet
->setPropertyValue("RefreshContextToolbarVisibility", makeAny( sal_True
));
679 catch ( const RuntimeException
& )
682 catch ( const Exception
& )
687 RefreshToolbars( xFrame
);
690 catch ( const RuntimeException
& )
694 catch ( const Exception
& )
699 else if ( aCmd
.indexOf( STATIC_CMD_PART
) < 0 )
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
);
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() );
735 xLayoutManager
->createElement( aToolBarResName
);
736 xLayoutManager
->showElement( aToolBarResName
);
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
);
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
);
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
);
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
);
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();
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
& )
876 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */