merge the formfield patch from ooo-build
[ooovba.git] / framework / source / uielement / menubarmanager.cxx
blob6e71139a2e17be1be288b8bfd15e3c45915be990
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: menubarmanager.cxx,v $
10 * $Revision: 1.52.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"
35 //_________________________________________________________________________________________________________________
36 // my own includes
37 //_________________________________________________________________________________________________________________
38 #include <uielement/menubarmanager.hxx>
39 #include <xml/menuconfiguration.hxx>
40 #include <classes/bmkmenu.hxx>
41 #include <classes/addonmenu.hxx>
42 #include <helper/imageproducer.hxx>
43 #include <threadhelp/resetableguard.hxx>
44 #include "classes/addonsoptions.hxx"
45 #include <classes/fwkresid.hxx>
46 #include <classes/menumanager.hxx>
47 #include <helper/acceleratorinfo.hxx>
48 #include <helper/mischelper.hxx>
49 #include <classes/menuextensionsupplier.hxx>
50 #include <classes/resource.hrc>
51 #include <services.h>
53 //_________________________________________________________________________________________________________________
54 // interface includes
55 //_________________________________________________________________________________________________________________
56 #include <com/sun/star/frame/XDispatch.hpp>
57 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
58 #include <com/sun/star/lang/DisposedException.hpp>
59 #include <com/sun/star/beans/XPropertySet.hpp>
60 #include <com/sun/star/frame/XFramesSupplier.hpp>
61 #include <com/sun/star/frame/XDesktop.hpp>
62 #include <com/sun/star/container/XEnumeration.hpp>
63 #include <com/sun/star/util/XStringWidth.hpp>
64 #include <com/sun/star/uno/XComponentContext.hpp>
65 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
66 #include <com/sun/star/frame/XPopupMenuController.hpp>
67 #include <com/sun/star/frame/XUIControllerRegistration.hpp>
68 #ifndef _COM_SUN_STAR_LANG_XSYSTEMDEPENDENT_HPP_
69 #include <com/sun/star/lang/SystemDependent.hpp>
70 #endif
71 #include <com/sun/star/ui/ItemType.hpp>
72 #include <com/sun/star/ui/ImageType.hpp>
73 #include <com/sun/star/container/XNameAccess.hpp>
74 #include <com/sun/star/frame/XModuleManager.hpp>
75 #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
76 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
77 #include <com/sun/star/ui/ItemStyle.hpp>
78 #include <com/sun/star/frame/status/Visibility.hpp>
80 //_________________________________________________________________________________________________________________
81 // includes of other projects
82 //_________________________________________________________________________________________________________________
83 #include <comphelper/processfactory.hxx>
84 #include <comphelper/extract.hxx>
85 #include <svtools/menuoptions.hxx>
86 #include <svtools/historyoptions.hxx>
87 #include <svtools/pathoptions.hxx>
88 #include <svtools/cmdoptions.hxx>
89 #include <unotools/localfilehelper.hxx>
90 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
91 #include <toolkit/unohlp.hxx>
92 #endif
93 #include <tools/urlobj.hxx>
94 #include <vcl/svapp.hxx>
95 #include <vcl/window.hxx>
96 #include <vos/mutex.hxx>
97 #include <vcl/svapp.hxx>
98 #include <osl/file.hxx>
99 #include <cppuhelper/implbase1.hxx>
100 #include <svtools/acceleratorexecute.hxx>
101 #include <rtl/logfile.hxx>
102 #include "svtools/miscopt.hxx"
103 #include <classes/addonmenu.hxx>
104 #include <uielement/menubarmerger.hxx>
105 #include <dispatch/uieventloghelper.hxx>
107 // Be careful removing this "bad" construct. There are serious problems
108 // with #define STRICT and including windows.h. Changing this needs some
109 // redesign on other projects, too. Especially sal/main.h which defines
110 // HINSTANCE depending on STRCIT!!!!!!!!!!!!!!!
111 struct SystemMenuData
113 unsigned long nSize;
114 long hMenu;
117 //_________________________________________________________________________________________________________________
118 // namespace
119 //_________________________________________________________________________________________________________________
121 using namespace ::cppu;
122 using namespace ::vos;
123 using namespace ::com::sun::star;
124 using namespace ::com::sun::star::uno;
125 using namespace ::com::sun::star::util;
126 using namespace ::com::sun::star::beans;
127 using namespace ::com::sun::star::frame;
128 using namespace ::com::sun::star::container;
129 using namespace ::com::sun::star::lang;
130 using namespace ::com::sun::star::frame;
131 using namespace ::com::sun::star::ui;
133 static const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL";
134 static const char ITEM_DESCRIPTOR_HELPURL[] = "HelpURL";
135 static const char ITEM_DESCRIPTOR_CONTAINER[] = "ItemDescriptorContainer";
136 static const char ITEM_DESCRIPTOR_LABEL[] = "Label";
137 static const char ITEM_DESCRIPTOR_TYPE[] = "Type";
138 static const char ITEM_DESCRIPTOR_MODULEIDENTIFIER[] = "ModuleIdentifier";
139 static const char ITEM_DESCRIPTOR_DISPATCHPROVIDER[] = "DispatchProvider";
140 static const char ITEM_DESCRIPTOR_STYLE[] = "Style";
142 const sal_Int32 LEN_DESCRIPTOR_COMMANDURL = 10;
143 const sal_Int32 LEN_DESCRIPTOR_HELPURL = 7;
144 const sal_Int32 LEN_DESCRIPTOR_CONTAINER = 23;
145 const sal_Int32 LEN_DESCRIPTOR_LABEL = 5;
146 const sal_Int32 LEN_DESCRIPTOR_TYPE = 4;
147 const sal_Int32 LEN_DESCRIPTOR_MODULEIDENTIFIER = 16;
148 const sal_Int32 LEN_DESCRIPTOR_DISPATCHPROVIDER = 16;
149 static const sal_Int32 ITEM_DESCRIPTOR_STYLE_LEN = 5;
151 const sal_uInt16 ADDONMENU_MERGE_ITEMID_START = 1500;
153 class StringLength : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XStringWidth >
155 public:
156 StringLength() {}
157 virtual ~StringLength() {}
159 // XStringWidth
160 sal_Int32 SAL_CALL queryStringWidth( const ::rtl::OUString& aString )
161 throw (RuntimeException)
163 return aString.getLength();
167 namespace framework
170 // special menu ids/command ids for dynamic popup menus
171 #define SID_SFX_START 5000
172 #define SID_NEWDOCDIRECT (SID_SFX_START + 537)
173 #define SID_AUTOPILOTMENU (SID_SFX_START + 1381)
174 #define SID_PICKLIST (SID_SFX_START + 510)
175 #define SID_MDIWINDOWLIST (SID_SFX_START + 610)
176 #define SID_ADDONLIST (SID_SFX_START + 1677)
177 #define SID_HELPMENU (SID_SFX_START + 410)
179 #define SFX_REFERER_USER "private:user"
181 const ::rtl::OUString aCmdHelpIndex( RTL_CONSTASCII_USTRINGPARAM( ".uno:HelpIndex" ));
182 const ::rtl::OUString aCmdToolsMenu( RTL_CONSTASCII_USTRINGPARAM( ".uno:ToolsMenu" ));
183 const ::rtl::OUString aCmdHelpMenu( RTL_CONSTASCII_USTRINGPARAM( ".uno:HelpMenu" ));
184 const ::rtl::OUString aSlotHelpMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5410" ));
186 const ::rtl::OUString aSpecialFileMenu( RTL_CONSTASCII_USTRINGPARAM( "file" ));
187 const ::rtl::OUString aSpecialWindowMenu( RTL_CONSTASCII_USTRINGPARAM( "window" ));
188 const ::rtl::OUString aSlotSpecialFileMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5510" ));
189 const ::rtl::OUString aSlotSpecialWindowMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5610" ));
190 const ::rtl::OUString aSlotSpecialToolsMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:6677" ));
192 // special uno commands for picklist and window list
193 const ::rtl::OUString aSpecialFileCommand( RTL_CONSTASCII_USTRINGPARAM( ".uno:PickList" ));
194 const ::rtl::OUString aSpecialWindowCommand( RTL_CONSTASCII_USTRINGPARAM( ".uno:WindowList" ));
196 const ::rtl::OUString UNO_COMMAND( RTL_CONSTASCII_USTRINGPARAM( ".uno:" ));
198 static sal_Int16 getImageTypeFromBools( sal_Bool bBig, sal_Bool bHighContrast )
200 sal_Int16 n( 0 );
201 if ( bBig )
202 n |= ::com::sun::star::ui::ImageType::SIZE_LARGE;
203 if ( bHighContrast )
204 n |= ::com::sun::star::ui::ImageType::COLOR_HIGHCONTRAST;
205 return n;
208 // #110897#
209 MenuBarManager::MenuBarManager(
210 const Reference< XMultiServiceFactory >& xServiceFactory,
211 const Reference< XFrame >& rFrame,
212 const Reference< XURLTransformer >& _xURLTransformer,
213 const Reference< XDispatchProvider >& rDispatchProvider,
214 const rtl::OUString& rModuleIdentifier,
215 Menu* pMenu, sal_Bool bDelete, sal_Bool bDeleteChildren )
216 : ThreadHelpBase( &Application::GetSolarMutex() ), OWeakObject()
217 , m_bDisposed( sal_False )
218 , m_bRetrieveImages( sal_False )
219 , m_bAcceleratorCfg( sal_False )
220 , m_bModuleIdentified( sal_False )
221 , m_aListenerContainer( m_aLock.getShareableOslMutex() )
222 , mxServiceFactory(xServiceFactory)
223 , m_xURLTransformer(_xURLTransformer)
224 , m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() )
226 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MenuBarManager" );
227 m_xPopupMenuControllerRegistration = Reference< ::com::sun::star::frame::XUIControllerRegistration >(
228 getServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.PopupMenuControllerFactory" ))),
229 UNO_QUERY );
230 FillMenuManager( pMenu, rFrame, rDispatchProvider, rModuleIdentifier, bDelete, bDeleteChildren );
233 // #110897#
234 MenuBarManager::MenuBarManager(
235 const Reference< XMultiServiceFactory >& xServiceFactory,
236 const Reference< XFrame >& rFrame,
237 const Reference< XURLTransformer >& _xURLTransformer,
238 AddonMenu* pAddonMenu,
239 sal_Bool bDelete,
240 sal_Bool bDeleteChildren )
241 : ThreadHelpBase( &Application::GetSolarMutex() )
242 , OWeakObject()
243 , m_bDisposed( sal_False )
244 , m_bRetrieveImages( sal_True )
245 , m_bAcceleratorCfg( sal_False )
246 , m_bModuleIdentified( sal_False )
247 , m_aListenerContainer( m_aLock.getShareableOslMutex() )
248 , mxServiceFactory(xServiceFactory)
249 , m_xURLTransformer(_xURLTransformer)
250 , m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() )
252 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MenuBarManager" );
253 Init(rFrame,pAddonMenu,bDelete,bDeleteChildren);
256 // #110897#
257 MenuBarManager::MenuBarManager(
258 const Reference< XMultiServiceFactory >& xServiceFactory,
259 const Reference< XFrame >& rFrame,
260 const Reference< XURLTransformer >& _xURLTransformer,
261 AddonPopupMenu* pAddonPopupMenu,
262 sal_Bool bDelete,
263 sal_Bool bDeleteChildren )
264 : ThreadHelpBase( &Application::GetSolarMutex() )
265 , OWeakObject()
266 , m_bDisposed( sal_False )
267 , m_bRetrieveImages( sal_True )
268 , m_bAcceleratorCfg( sal_False )
269 , m_bModuleIdentified( sal_False )
270 , m_aListenerContainer( m_aLock.getShareableOslMutex() )
271 , mxServiceFactory(xServiceFactory)
272 , m_xURLTransformer(_xURLTransformer)
273 , m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() )
275 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MenuBarManager" );
276 Init(rFrame,pAddonPopupMenu,bDelete,bDeleteChildren,true);
279 Any SAL_CALL MenuBarManager::queryInterface( const Type & rType ) throw ( RuntimeException )
281 Any a = ::cppu::queryInterface(
282 rType ,
283 SAL_STATIC_CAST( ::com::sun::star::frame::XStatusListener*, this ),
284 SAL_STATIC_CAST( ::com::sun::star::frame::XFrameActionListener*, this ),
285 SAL_STATIC_CAST( ::com::sun::star::ui::XUIConfigurationListener*, this ),
286 SAL_STATIC_CAST( XEventListener*, (XStatusListener *)this ),
287 SAL_STATIC_CAST( XComponent*, this ),
288 SAL_STATIC_CAST( ::com::sun::star::awt::XSystemDependentMenuPeer*, this ));
290 if ( a.hasValue() )
291 return a;
293 return OWeakObject::queryInterface( rType );
297 void SAL_CALL MenuBarManager::acquire() throw()
299 OWeakObject::acquire();
303 void SAL_CALL MenuBarManager::release() throw()
305 OWeakObject::release();
309 Any SAL_CALL MenuBarManager::getMenuHandle( const Sequence< sal_Int8 >& /*ProcessId*/, sal_Int16 SystemType ) throw (RuntimeException)
311 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::getMenuHandle" );
312 ResetableGuard aGuard( m_aLock );
314 if ( m_bDisposed )
315 throw com::sun::star::lang::DisposedException();
317 Any a;
319 if ( m_pVCLMenu )
321 OGuard aSolarGuard( Application::GetSolarMutex() );
323 SystemMenuData aSystemMenuData;
324 aSystemMenuData.nSize = sizeof( SystemMenuData );
326 m_pVCLMenu->GetSystemMenuData( &aSystemMenuData );
327 #ifdef QUARTZ
328 if( SystemType == SystemDependent::SYSTEM_MAC )
331 #elif (defined WNT)
332 if( SystemType == SystemDependent::SYSTEM_WIN32 )
334 a <<= (long) aSystemMenuData.hMenu;
336 #elif (defined UNX)
337 if( SystemType == SystemDependent::SYSTEM_XWINDOW )
340 #endif
343 return a;
346 MenuBarManager::~MenuBarManager()
348 // stop asynchronous settings timer
349 m_xDeferedItemContainer.clear();
350 m_aAsyncSettingsTimer.Stop();
352 DBG_ASSERT( OWeakObject::m_refCount == 0, "Who wants to delete an object with refcount > 0!" );
355 void MenuBarManager::Destroy()
357 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Destroy" );
358 OGuard aGuard( Application::GetSolarMutex() );
360 if ( !m_bDisposed )
362 // stop asynchronous settings timer and
363 // release defered item container reference
364 m_aAsyncSettingsTimer.Stop();
365 m_xDeferedItemContainer.clear();
366 RemoveListener();
368 std::vector< MenuItemHandler* >::iterator p;
369 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
371 MenuItemHandler* pItemHandler = *p;
372 pItemHandler->xMenuItemDispatch.clear();
373 pItemHandler->xSubMenuManager.clear();
374 pItemHandler->xPopupMenu.clear();
375 delete pItemHandler;
377 m_aMenuItemHandlerVector.clear();
379 if ( m_bDeleteMenu )
381 delete m_pVCLMenu;
382 m_pVCLMenu = 0;
387 // XComponent
388 void SAL_CALL MenuBarManager::dispose() throw( RuntimeException )
390 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::dispose" );
391 Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
393 EventObject aEvent( xThis );
394 m_aListenerContainer.disposeAndClear( aEvent );
397 ResetableGuard aGuard( m_aLock );
398 // RemoveListener();
399 Destroy();
400 m_bDisposed = sal_True;
402 if ( m_xDocImageManager.is() )
406 m_xDocImageManager->removeConfigurationListener(
407 Reference< XUIConfigurationListener >(
408 static_cast< OWeakObject* >( this ), UNO_QUERY ));
410 catch ( Exception& )
414 if ( m_xModuleImageManager.is() )
418 m_xModuleImageManager->removeConfigurationListener(
419 Reference< XUIConfigurationListener >(
420 static_cast< OWeakObject* >( this ), UNO_QUERY ));
422 catch ( Exception& )
426 m_xDocImageManager.clear();
427 m_xModuleImageManager.clear();
428 m_xGlobalAcceleratorManager.clear();
429 m_xModuleAcceleratorManager.clear();
430 m_xDocAcceleratorManager.clear();
431 m_xUICommandLabels.clear();
432 m_xPopupMenuControllerRegistration.clear();
433 mxServiceFactory.clear();
437 void SAL_CALL MenuBarManager::addEventListener( const Reference< XEventListener >& xListener ) throw( RuntimeException )
439 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::addEventListener" );
440 ResetableGuard aGuard( m_aLock );
442 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
443 if ( m_bDisposed )
444 throw DisposedException();
446 m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
449 void SAL_CALL MenuBarManager::removeEventListener( const Reference< XEventListener >& xListener ) throw( RuntimeException )
451 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::removeEventListener" );
452 ResetableGuard aGuard( m_aLock );
453 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
454 m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
457 void SAL_CALL MenuBarManager::elementInserted( const ::com::sun::star::ui::ConfigurationEvent& Event )
458 throw (RuntimeException)
460 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::elementInserted" );
461 ResetableGuard aGuard( m_aLock );
463 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
464 if ( m_bDisposed )
465 return;
467 sal_Int16 nImageType = sal_Int16();
468 sal_Int16 nCurrentImageType = getImageTypeFromBools( sal_False, m_bWasHiContrast );
469 if (( Event.aInfo >>= nImageType ) &&
470 ( nImageType == nCurrentImageType ))
471 RequestImages();
474 void SAL_CALL MenuBarManager::elementRemoved( const ::com::sun::star::ui::ConfigurationEvent& Event )
475 throw (RuntimeException)
477 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::elementRemoved" );
478 elementInserted(Event);
481 void SAL_CALL MenuBarManager::elementReplaced( const ::com::sun::star::ui::ConfigurationEvent& Event )
482 throw (RuntimeException)
484 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::elementReplaced" );
485 elementInserted(Event);
488 // XFrameActionListener
489 void SAL_CALL MenuBarManager::frameAction( const FrameActionEvent& Action )
490 throw ( RuntimeException )
492 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::frameAction" );
493 ResetableGuard aGuard( m_aLock );
495 if ( m_bDisposed )
496 throw com::sun::star::lang::DisposedException();
498 if ( Action.Action == FrameAction_CONTEXT_CHANGED )
500 std::vector< MenuItemHandler* >::iterator p;
501 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
503 // Clear dispatch reference as we will requery it later o
504 MenuItemHandler* pItemHandler = *p;
505 pItemHandler->xMenuItemDispatch.clear();
510 // XStatusListener
511 void SAL_CALL MenuBarManager::statusChanged( const FeatureStateEvent& Event )
512 throw ( RuntimeException )
514 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::statusChanged" );
515 ::rtl::OUString aFeatureURL = Event.FeatureURL.Complete;
517 OGuard aSolarGuard( Application::GetSolarMutex() );
519 ResetableGuard aGuard( m_aLock );
521 if ( m_bDisposed )
522 return;
524 // We have to check all menu entries as there can be identical entries in a popup menu.
525 std::vector< MenuItemHandler* >::iterator p;
526 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
528 MenuItemHandler* pMenuItemHandler = *p;
529 if ( pMenuItemHandler->aMenuItemURL == aFeatureURL )
531 sal_Bool bCheckmark( sal_False );
532 sal_Bool bMenuItemEnabled( m_pVCLMenu->IsItemEnabled( pMenuItemHandler->nItemId ));
533 sal_Bool bEnabledItem( Event.IsEnabled );
534 rtl::OUString aItemText;
535 status::Visibility aVisibilityStatus;
537 #ifdef UNIX
538 // #b6673979# enable some slots hardly, because UNIX clipboard does not notify all changes
539 // Can be removed if follow up task will be fixed directly within applications.
540 if (
541 ( pMenuItemHandler->aMenuItemURL.equalsAscii (".uno:Paste" ) ) ||
542 ( pMenuItemHandler->aMenuItemURL.equalsAscii (".uno:PasteSpecial" ) ) ||
543 ( pMenuItemHandler->aMenuItemURL.equalsAscii (".uno:PasteClipboard") ) // special for draw/impress
545 bEnabledItem = sal_True;
546 #endif
548 // Enable/disable item
549 if ( bEnabledItem != bMenuItemEnabled )
550 m_pVCLMenu->EnableItem( pMenuItemHandler->nItemId, bEnabledItem );
552 if ( Event.State >>= bCheckmark )
554 // Checkmark
555 m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, TRUE );
556 m_pVCLMenu->CheckItem( pMenuItemHandler->nItemId, bCheckmark );
557 m_pVCLMenu->SetItemBits( pMenuItemHandler->nItemId,
558 m_pVCLMenu->GetItemBits( pMenuItemHandler->nItemId ) | MIB_CHECKABLE );
560 else if ( Event.State >>= aItemText )
562 // Replacement for place holders
563 if ( aItemText.matchAsciiL( "($1)", 4 ))
565 String aResStr = String( FwkResId( STR_UPDATEDOC ));
566 rtl::OUString aTmp( aResStr );
567 aTmp += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
568 aTmp += aItemText.copy( 4 );
569 aItemText = aTmp;
571 else if ( aItemText.matchAsciiL( "($2)", 4 ))
573 String aResStr = String( FwkResId( STR_CLOSEDOC_ANDRETURN ));
574 rtl::OUString aTmp( aResStr );
575 aTmp += aItemText.copy( 4 );
576 aItemText = aTmp;
578 else if ( aItemText.matchAsciiL( "($3)", 4 ))
580 String aResStr = String( FwkResId( STR_SAVECOPYDOC ));
581 rtl::OUString aTmp( aResStr );
582 aTmp += aItemText.copy( 4 );
583 aItemText = aTmp;
586 m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, TRUE );
587 m_pVCLMenu->SetItemText( pMenuItemHandler->nItemId, aItemText );
589 else if ( Event.State >>= aVisibilityStatus )
591 // Visibility
592 m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, aVisibilityStatus.bVisible );
594 else
595 m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, TRUE );
598 if ( Event.Requery )
600 // Release dispatch object - will be requeried on the next activate!
601 pMenuItemHandler->xMenuItemDispatch.clear();
607 // Helper to retrieve own structure from item ID
608 MenuBarManager::MenuItemHandler* MenuBarManager::GetMenuItemHandler( USHORT nItemId )
610 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::GetMenuItemHandler" );
611 ResetableGuard aGuard( m_aLock );
613 std::vector< MenuItemHandler* >::iterator p;
614 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
616 MenuItemHandler* pItemHandler = *p;
617 if ( pItemHandler->nItemId == nItemId )
618 return pItemHandler;
621 return 0;
624 // Helper to set request images flag
625 void MenuBarManager::RequestImages()
627 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RequestImages" );
628 // must be locked from callee
629 // ResetableGuard aGuard( m_aLock );
631 m_bRetrieveImages = sal_True;
632 const sal_uInt32 nCount = m_aMenuItemHandlerVector.size();
633 for ( sal_uInt32 i = 0; i < nCount; ++i )
635 MenuItemHandler* pItemHandler = m_aMenuItemHandlerVector[i];
636 if ( pItemHandler->xSubMenuManager.is() )
638 MenuBarManager* pMenuBarManager = (MenuBarManager*)(pItemHandler->xSubMenuManager.get());
639 pMenuBarManager->RequestImages();
644 // Helper to reset objects to prepare shutdown
645 void MenuBarManager::RemoveListener()
647 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RemoveListener" );
648 ResetableGuard aGuard( m_aLock );
650 // Check service manager reference. Remove listener can be called due
651 // to a disposing call from the frame and therefore we already removed
652 // our listeners and release the service manager reference!
653 Reference< XMultiServiceFactory > xServiceManager = getServiceFactory();
654 if ( xServiceManager.is() )
656 std::vector< MenuItemHandler* >::iterator p;
657 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
659 MenuItemHandler* pItemHandler = *p;
660 if ( pItemHandler->xMenuItemDispatch.is() )
662 URL aTargetURL;
663 aTargetURL.Complete = pItemHandler->aMenuItemURL;
664 m_xURLTransformer->parseStrict( aTargetURL );
666 pItemHandler->xMenuItemDispatch->removeStatusListener(
667 static_cast< XStatusListener* >( this ), aTargetURL );
670 pItemHandler->xMenuItemDispatch.clear();
671 if ( pItemHandler->xPopupMenu.is() )
674 // Remove popup menu from menu structure
675 OGuard aGuard2( Application::GetSolarMutex() );
676 m_pVCLMenu->SetPopupMenu( pItemHandler->nItemId, 0 );
679 Reference< com::sun::star::lang::XEventListener > xEventListener( pItemHandler->xPopupMenuController, UNO_QUERY );
680 if ( xEventListener.is() )
682 EventObject aEventObject;
683 aEventObject.Source = (OWeakObject *)this;
684 xEventListener->disposing( aEventObject );
687 // We now provide a popup menu controller to external code.
688 // Therefore the life-time must be explicitly handled via
689 // dispose!!
692 Reference< XComponent > xComponent( pItemHandler->xPopupMenuController, UNO_QUERY );
693 if ( xComponent.is() )
694 xComponent->dispose();
696 catch ( RuntimeException& )
698 throw;
700 catch ( Exception& )
704 // Release references to controller and popup menu
705 pItemHandler->xPopupMenuController.clear();
706 pItemHandler->xPopupMenu.clear();
709 Reference< XComponent > xComponent( pItemHandler->xSubMenuManager, UNO_QUERY );
710 if ( xComponent.is() )
711 xComponent->dispose();
717 if ( m_xFrame.is() )
718 m_xFrame->removeFrameActionListener( Reference< XFrameActionListener >(
719 static_cast< OWeakObject* >( this ), UNO_QUERY ));
721 catch ( Exception& )
725 m_xFrame = 0;
728 void SAL_CALL MenuBarManager::disposing( const EventObject& Source ) throw ( RuntimeException )
730 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::disposing(evt)" );
731 MenuItemHandler* pMenuItemDisposing = NULL;
733 ResetableGuard aGuard( m_aLock );
735 std::vector< MenuItemHandler* >::iterator p;
736 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
738 MenuItemHandler* pMenuItemHandler = *p;
739 if ( pMenuItemHandler->xMenuItemDispatch.is() &&
740 pMenuItemHandler->xMenuItemDispatch == Source.Source )
742 // disposing called from menu item dispatcher, remove listener
743 pMenuItemDisposing = pMenuItemHandler;
744 break;
748 if ( pMenuItemDisposing )
750 // Release references to the dispatch object
751 URL aTargetURL;
752 aTargetURL.Complete = pMenuItemDisposing->aMenuItemURL;
754 // Check reference of service manager before we use it. Reference could
755 // be cleared due to RemoveListener call!
756 Reference< XMultiServiceFactory > xServiceManager( getServiceFactory() );
757 if ( xServiceManager.is() )
759 m_xURLTransformer->parseStrict( aTargetURL );
761 pMenuItemDisposing->xMenuItemDispatch->removeStatusListener(
762 static_cast< XStatusListener* >( this ), aTargetURL );
763 pMenuItemDisposing->xMenuItemDispatch = Reference< XDispatch >();
764 if ( pMenuItemDisposing->xPopupMenu.is() )
766 Reference< com::sun::star::lang::XEventListener > xEventListener( pMenuItemDisposing->xPopupMenuController, UNO_QUERY );
767 if ( xEventListener.is() )
768 xEventListener->disposing( Source );
771 // Remove popup menu from menu structure as we release our reference to
772 // the controller.
773 OGuard aGuard2( Application::GetSolarMutex() );
774 m_pVCLMenu->SetPopupMenu( pMenuItemDisposing->nItemId, 0 );
777 pMenuItemDisposing->xPopupMenuController.clear();
778 pMenuItemDisposing->xPopupMenu.clear();
781 return;
783 else if ( Source.Source == m_xFrame )
785 // Our frame gets disposed. We have to remove all our listeners
786 RemoveListener();
788 else if ( Source.Source == Reference< XInterface >( m_xDocImageManager, UNO_QUERY ))
789 m_xDocImageManager.clear();
790 else if ( Source.Source == Reference< XInterface >( m_xModuleImageManager, UNO_QUERY ))
791 m_xModuleImageManager.clear();
795 void MenuBarManager::CheckAndAddMenuExtension( Menu* pMenu )
797 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::CheckAndAddMenuExtension" );
798 static const char REFERENCECOMMAND_AFTER[] = ".uno:OnlineRegistrationDlg";
799 static const char REFERENCECOMMAND_BEFORE[] = ".uno:About";
801 // retrieve menu extension item
802 MenuExtensionItem aMenuItem( GetMenuExtension() );
803 if (( aMenuItem.aURL.getLength() > 0 ) &&
804 ( aMenuItem.aLabel.getLength() > 0 ))
806 // remove all old window list entries from menu
807 sal_uInt16 nNewItemId( 0 );
808 sal_uInt16 nInsertPos( MENU_APPEND );
809 sal_uInt16 nAfterPos( MENU_APPEND );
810 sal_uInt16 nBeforePos( MENU_APPEND );
811 String aCommandAfter( String::CreateFromAscii ( REFERENCECOMMAND_AFTER ));
812 String aCommandBefore( String::CreateFromAscii ( REFERENCECOMMAND_BEFORE ));
813 for ( sal_uInt16 n = 0; n < pMenu->GetItemCount(); n++ )
815 sal_uInt16 nItemId = pMenu->GetItemId( n );
816 nNewItemId = std::max( nItemId, nNewItemId );
817 if ( pMenu->GetItemCommand( nItemId ) == aCommandAfter )
818 nAfterPos = n+1;
819 else if ( pMenu->GetItemCommand( nItemId ) == aCommandBefore )
820 nBeforePos = n;
822 ++nNewItemId;
824 if ( nAfterPos != MENU_APPEND )
825 nInsertPos = nAfterPos;
826 else if ( nBeforePos != MENU_APPEND )
827 nInsertPos = nBeforePos;
829 pMenu->InsertItem( nNewItemId, aMenuItem.aLabel, 0, nInsertPos );
830 pMenu->SetItemCommand( nNewItemId, aMenuItem.aURL );
834 static void lcl_CheckForChildren(Menu* pMenu, USHORT nItemId)
836 if (PopupMenu* pThisPopup = pMenu->GetPopupMenu( nItemId ))
837 pMenu->EnableItem( nItemId, pThisPopup->GetItemCount() ? true : false );
840 //_________________________________________________________________________________________________________________
841 // vcl handler
842 //_________________________________________________________________________________________________________________
844 IMPL_LINK( MenuBarManager, Activate, Menu *, pMenu )
846 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Activate" );
847 if ( pMenu == m_pVCLMenu )
849 // set/unset hiding disabled menu entries
850 sal_Bool bDontHide = SvtMenuOptions().IsEntryHidingEnabled();
851 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
852 sal_Bool bShowMenuImages = rSettings.GetUseImagesInMenus();
853 sal_Bool bHasDisabledEntries = SvtCommandOptions().HasEntries( SvtCommandOptions::CMDOPTION_DISABLED );
855 ResetableGuard aGuard( m_aLock );
857 sal_uInt16 nFlag = pMenu->GetMenuFlags();
858 if ( bDontHide )
859 nFlag &= ~MENU_FLAG_HIDEDISABLEDENTRIES;
860 else
861 nFlag |= MENU_FLAG_HIDEDISABLEDENTRIES;
862 pMenu->SetMenuFlags( nFlag );
864 if ( m_bActive )
865 return 0;
867 m_bActive = TRUE;
869 ::rtl::OUString aMenuCommand( m_aMenuItemCommand );
870 if ( m_aMenuItemCommand == aSpecialWindowMenu ||
871 m_aMenuItemCommand == aSlotSpecialWindowMenu ||
872 aMenuCommand == aSpecialWindowCommand )
873 MenuManager::UpdateSpecialWindowMenu( pMenu,getServiceFactory(),m_aLock );
875 // Check if some modes have changed so we have to update our menu images
876 sal_Bool bIsHiContrast = rSettings.GetHighContrastMode();
877 sal_Int16 nSymbolsStyle = SvtMiscOptions().GetCurrentSymbolsStyle();
879 if ( m_bRetrieveImages ||
880 m_bWasHiContrast != bIsHiContrast ||
881 bShowMenuImages != m_bShowMenuImages ||
882 nSymbolsStyle != m_nSymbolsStyle )
884 // The mode changed so we have to replace all images
885 m_bWasHiContrast = bIsHiContrast;
886 m_bShowMenuImages = bShowMenuImages;
887 m_bRetrieveImages = sal_False;
888 m_nSymbolsStyle = nSymbolsStyle;
889 MenuManager::FillMenuImages(m_xFrame,pMenu,bIsHiContrast,bShowMenuImages);
892 // Try to map commands to labels
893 for ( USHORT nPos = 0; nPos < pMenu->GetItemCount(); nPos++ )
895 USHORT nItemId = pMenu->GetItemId( nPos );
896 if (( pMenu->GetItemType( nPos ) != MENUITEM_SEPARATOR ) &&
897 ( pMenu->GetItemText( nItemId ).Len() == 0 ))
899 String aCommand = pMenu->GetItemCommand( nItemId );
900 if ( aCommand.Len() > 0 )
901 pMenu->SetItemText( nItemId, RetrieveLabelFromCommand( aCommand ));
905 // Try to set accelerator keys
907 RetrieveShortcuts( m_aMenuItemHandlerVector );
908 std::vector< MenuItemHandler* >::iterator p;
909 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
911 MenuItemHandler* pMenuItemHandler = *p;
913 // Set key code, workaround for hard-coded shortcut F1 mapped to .uno:HelpIndex
914 // Only non-popup menu items can have a short-cut
915 if ( pMenuItemHandler->aMenuItemURL == aCmdHelpIndex )
917 KeyCode aKeyCode( KEY_F1 );
918 pMenu->SetAccelKey( pMenuItemHandler->nItemId, aKeyCode );
920 else if ( pMenu->GetPopupMenu( pMenuItemHandler->nItemId ) == 0 )
921 pMenu->SetAccelKey( pMenuItemHandler->nItemId, pMenuItemHandler->aKeyCode );
925 URL aTargetURL;
927 // Use provided dispatch provider => fallback to frame as dispatch provider
928 Reference< XDispatchProvider > xDispatchProvider;
929 if ( m_xDispatchProvider.is() )
930 xDispatchProvider = m_xDispatchProvider;
931 else
932 xDispatchProvider = Reference< XDispatchProvider >( m_xFrame, UNO_QUERY );
934 if ( xDispatchProvider.is() )
936 KeyCode aEmptyKeyCode;
937 SvtCommandOptions aCmdOptions;
938 std::vector< MenuItemHandler* >::iterator p;
939 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
941 MenuItemHandler* pMenuItemHandler = *p;
942 if ( pMenuItemHandler )
944 if ( !pMenuItemHandler->xMenuItemDispatch.is() &&
945 !pMenuItemHandler->xSubMenuManager.is() )
947 // There is no dispatch mechanism for the special window list menu items,
948 // because they are handled directly through XFrame->activate!!!
949 // Don't update dispatches for special file menu items.
950 if ( !(( pMenuItemHandler->nItemId >= START_ITEMID_WINDOWLIST &&
951 pMenuItemHandler->nItemId < END_ITEMID_WINDOWLIST )))
953 Reference< XDispatch > xMenuItemDispatch;
955 ::rtl::OUString aItemCommand = pMenu->GetItemCommand( pMenuItemHandler->nItemId );
956 if ( !aItemCommand.getLength() )
958 aItemCommand = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
959 aItemCommand += ::rtl::OUString::valueOf( (sal_Int32)pMenuItemHandler->nItemId );
960 pMenu->SetItemCommand( pMenuItemHandler->nItemId, aItemCommand );
963 aTargetURL.Complete = aItemCommand;
965 m_xURLTransformer->parseStrict( aTargetURL );
967 if ( bHasDisabledEntries )
969 if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aTargetURL.Path ))
970 pMenu->HideItem( pMenuItemHandler->nItemId );
973 if ( m_bIsBookmarkMenu )
974 xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, pMenuItemHandler->aTargetFrame, 0 );
975 else
976 xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
978 sal_Bool bPopupMenu( sal_False );
979 if ( !pMenuItemHandler->xPopupMenuController.is() &&
980 m_xPopupMenuControllerRegistration->hasController( aItemCommand, rtl::OUString() ))
982 bPopupMenu = CreatePopupMenuController( pMenuItemHandler );
984 else if ( pMenuItemHandler->xPopupMenuController.is() )
986 // Force update of popup menu
987 pMenuItemHandler->xPopupMenuController->updatePopupMenu();
988 bPopupMenu = sal_True;
989 if (PopupMenu* pThisPopup = pMenu->GetPopupMenu( pMenuItemHandler->nItemId ))
990 pMenu->EnableItem( pMenuItemHandler->nItemId, pThisPopup->GetItemCount() ? true : false );
993 lcl_CheckForChildren(pMenu, pMenuItemHandler->nItemId);
995 if ( xMenuItemDispatch.is() )
997 pMenuItemHandler->xMenuItemDispatch = xMenuItemDispatch;
998 pMenuItemHandler->aMenuItemURL = aTargetURL.Complete;
1000 if ( !bPopupMenu )
1002 // We need only an update to reflect the current state
1003 xMenuItemDispatch->addStatusListener( static_cast< XStatusListener* >( this ), aTargetURL );
1004 xMenuItemDispatch->removeStatusListener( static_cast< XStatusListener* >( this ), aTargetURL );
1007 else if ( !bPopupMenu )
1008 pMenu->EnableItem( pMenuItemHandler->nItemId, sal_False );
1011 else if ( pMenuItemHandler->xPopupMenuController.is() )
1013 // Force update of popup menu
1014 pMenuItemHandler->xPopupMenuController->updatePopupMenu();
1015 lcl_CheckForChildren(pMenu, pMenuItemHandler->nItemId);
1017 else if ( pMenuItemHandler->xMenuItemDispatch.is() )
1019 // We need an update to reflect the current state
1022 aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
1023 m_xURLTransformer->parseStrict( aTargetURL );
1025 pMenuItemHandler->xMenuItemDispatch->addStatusListener(
1026 static_cast< XStatusListener* >( this ), aTargetURL );
1027 pMenuItemHandler->xMenuItemDispatch->removeStatusListener(
1028 static_cast< XStatusListener* >( this ), aTargetURL );
1030 catch ( Exception& )
1034 else if ( pMenuItemHandler->xSubMenuManager.is() )
1035 lcl_CheckForChildren(pMenu, pMenuItemHandler->nItemId);
1041 return 1;
1045 IMPL_LINK( MenuBarManager, Deactivate, Menu *, pMenu )
1047 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Deactivate" );
1048 if ( pMenu == m_pVCLMenu )
1050 m_bActive = sal_False;
1051 if ( pMenu->IsMenuBar() && m_xDeferedItemContainer.is() )
1053 // Start timer to handle settings asynchronous
1054 // Changing the menu inside this handler leads to
1055 // a crash under X!
1056 m_aAsyncSettingsTimer.SetTimeoutHdl(LINK(this, MenuBarManager, AsyncSettingsHdl));
1057 m_aAsyncSettingsTimer.SetTimeout(10);
1058 m_aAsyncSettingsTimer.Start();
1062 return 1;
1065 IMPL_LINK( MenuBarManager, AsyncSettingsHdl, Timer*,)
1067 OGuard aGuard( Application::GetSolarMutex() );
1068 Reference< XInterface > xSelfHold(
1069 static_cast< ::cppu::OWeakObject* >( this ), UNO_QUERY_THROW );
1071 m_aAsyncSettingsTimer.Stop();
1072 if ( !m_bActive && m_xDeferedItemContainer.is() )
1074 SetItemContainer( m_xDeferedItemContainer );
1075 m_xDeferedItemContainer.clear();
1078 return 0;
1081 IMPL_LINK( MenuBarManager, Select, Menu *, pMenu )
1083 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Select" );
1084 URL aTargetURL;
1085 Sequence<PropertyValue> aArgs;
1086 Reference< XDispatch > xDispatch;
1089 ResetableGuard aGuard( m_aLock );
1091 USHORT nCurItemId = pMenu->GetCurItemId();
1092 USHORT nCurPos = pMenu->GetItemPos( nCurItemId );
1093 if ( pMenu == m_pVCLMenu &&
1094 pMenu->GetItemType( nCurPos ) != MENUITEM_SEPARATOR )
1096 if ( nCurItemId >= START_ITEMID_WINDOWLIST &&
1097 nCurItemId <= END_ITEMID_WINDOWLIST )
1099 // window list menu item selected
1101 // #110897#
1102 // Reference< XFramesSupplier > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( DESKTOP_SERVICE ), UNO_QUERY );
1103 Reference< XFramesSupplier > xDesktop( getServiceFactory()->createInstance( SERVICENAME_DESKTOP ), UNO_QUERY );
1105 if ( xDesktop.is() )
1107 USHORT nTaskId = START_ITEMID_WINDOWLIST;
1108 Reference< XIndexAccess > xList( xDesktop->getFrames(), UNO_QUERY );
1109 sal_Int32 nCount = xList->getCount();
1110 for ( sal_Int32 i=0; i<nCount; ++i )
1112 Reference< XFrame > xFrame;
1113 xList->getByIndex(i) >>= xFrame;
1114 if ( xFrame.is() && nTaskId == nCurItemId )
1116 Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
1117 pWin->GrabFocus();
1118 pWin->ToTop( TOTOP_RESTOREWHENMIN );
1119 break;
1122 nTaskId++;
1126 else
1128 MenuItemHandler* pMenuItemHandler = GetMenuItemHandler( nCurItemId );
1129 if ( pMenuItemHandler && pMenuItemHandler->xMenuItemDispatch.is() )
1131 aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
1132 m_xURLTransformer->parseStrict( aTargetURL );
1134 if ( m_bIsBookmarkMenu )
1136 // bookmark menu item selected
1137 aArgs.realloc( 1 );
1138 aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" ));
1139 aArgs[0].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SFX_REFERER_USER ));
1142 xDispatch = pMenuItemHandler->xMenuItemDispatch;
1148 if ( xDispatch.is() )
1150 const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1151 if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
1152 UiEventLogHelper(::rtl::OUString::createFromAscii("MenuBarManager")).log(getServiceFactory(), m_xFrame, aTargetURL, aArgs);
1153 xDispatch->dispatch( aTargetURL, aArgs );
1154 Application::AcquireSolarMutex( nRef );
1157 return 1;
1161 IMPL_LINK( MenuBarManager, Highlight, Menu *, EMPTYARG )
1163 return 0;
1166 sal_Bool MenuBarManager::MustBeHidden( PopupMenu* pPopupMenu, const Reference< XURLTransformer >& rTransformer )
1168 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MustBeHidden" );
1169 if ( pPopupMenu )
1171 URL aTargetURL;
1172 SvtCommandOptions aCmdOptions;
1174 sal_uInt16 nCount = pPopupMenu->GetItemCount();
1175 sal_uInt16 nHideCount( 0 );
1177 for ( sal_uInt16 i = 0; i < nCount; i++ )
1179 sal_uInt16 nId = pPopupMenu->GetItemId( i );
1180 if ( nId > 0 )
1182 PopupMenu* pSubPopupMenu = pPopupMenu->GetPopupMenu( nId );
1183 if ( pSubPopupMenu )
1185 if ( MustBeHidden( pSubPopupMenu, rTransformer ))
1187 pPopupMenu->HideItem( nId );
1188 ++nHideCount;
1191 else
1193 aTargetURL.Complete = pPopupMenu->GetItemCommand( nId );
1194 rTransformer->parseStrict( aTargetURL );
1196 if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aTargetURL.Path ))
1197 ++nHideCount;
1200 else
1201 ++nHideCount;
1204 return ( nCount == nHideCount );
1207 return sal_True;
1209 String MenuBarManager::RetrieveLabelFromCommand( const String& aCmdURL )
1211 return framework::RetrieveLabelFromCommand(aCmdURL,mxServiceFactory,m_xUICommandLabels,m_xFrame,m_aModuleIdentifier,m_bModuleIdentified,"Label");
1216 sal_Bool MenuBarManager::CreatePopupMenuController( MenuItemHandler* pMenuItemHandler )
1218 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::CreatePopupMenuController" );
1219 rtl::OUString aItemCommand( pMenuItemHandler->aMenuItemURL );
1221 // Try instanciate a popup menu controller. It is stored in the menu item handler.
1222 Reference< XMultiComponentFactory > xPopupMenuControllerFactory( m_xPopupMenuControllerRegistration, UNO_QUERY );
1223 if ( xPopupMenuControllerFactory.is() )
1225 Sequence< Any > aSeq( 2 );
1226 PropertyValue aPropValue;
1228 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleName" ));
1229 aPropValue.Value <<= m_aModuleIdentifier;
1230 aSeq[0] <<= aPropValue;
1231 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
1232 aPropValue.Value <<= m_xFrame;
1233 aSeq[1] <<= aPropValue;
1235 Reference< XComponentContext > xComponentContext;
1236 Reference< XPropertySet > xProps( getServiceFactory(), UNO_QUERY );
1238 xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>=
1239 xComponentContext;
1241 Reference< XPopupMenuController > xPopupMenuController(
1242 xPopupMenuControllerFactory->createInstanceWithArgumentsAndContext(
1243 aItemCommand,
1244 aSeq,
1245 xComponentContext ),
1246 UNO_QUERY );
1248 if ( xPopupMenuController.is() )
1250 // Provide our awt popup menu to the popup menu controller
1251 pMenuItemHandler->xPopupMenuController = xPopupMenuController;
1252 xPopupMenuController->setPopupMenu( pMenuItemHandler->xPopupMenu );
1253 return sal_True;
1257 return sal_False;
1260 void MenuBarManager::FillMenuManager( Menu* pMenu, const Reference< XFrame >& rFrame, const Reference< XDispatchProvider >& rDispatchProvider, const rtl::OUString& rModuleIdentifier, sal_Bool bDelete, sal_Bool bDeleteChildren )
1262 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillMenuManager" );
1263 m_xFrame = rFrame;
1264 m_bActive = sal_False;
1265 m_bDeleteMenu = bDelete;
1266 m_bDeleteChildren = bDeleteChildren;
1267 m_pVCLMenu = pMenu;
1268 m_bInitialized = sal_False;
1269 m_bIsBookmarkMenu = sal_False;
1270 m_xDispatchProvider = rDispatchProvider;
1272 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
1273 m_bWasHiContrast = rSettings.GetHighContrastMode();
1274 m_bShowMenuImages = rSettings.GetUseImagesInMenus();
1275 m_bRetrieveImages = sal_False;
1277 sal_Int32 nAddonsURLPrefixLength = ADDONSPOPUPMENU_URL_PREFIX.getLength();
1279 // Add root as ui configuration listener
1280 RetrieveImageManagers();
1282 if ( pMenu->IsMenuBar() && rFrame.is() )
1284 // First merge all addon popup menus into our structure
1285 USHORT nPos = 0;
1286 for ( nPos = 0; nPos < pMenu->GetItemCount(); nPos++ )
1288 USHORT nItemId = pMenu->GetItemId( nPos );
1289 ::rtl::OUString aCommand = pMenu->GetItemCommand( nItemId );
1290 if ( nItemId == SID_MDIWINDOWLIST ||
1291 aCommand == aSpecialWindowCommand )
1293 // Retrieve addon popup menus and add them to our menu bar
1294 Reference< com::sun::star::frame::XModel > xModel;
1295 Reference< com::sun::star::frame::XController > xController( rFrame->getController(), UNO_QUERY );
1296 if ( xController.is() )
1297 xModel = Reference< com::sun::star::frame::XModel >( xController->getModel(), UNO_QUERY );
1298 framework::AddonMenuManager::MergeAddonPopupMenus( rFrame, xModel, nPos, (MenuBar *)pMenu );
1299 break;
1303 // Merge the Add-Ons help menu items into the Office help menu
1304 framework::AddonMenuManager::MergeAddonHelpMenu( rFrame, (MenuBar *)pMenu );
1307 String aEmpty;
1308 sal_Bool bAccessibilityEnabled( Application::GetSettings().GetMiscSettings().GetEnableATToolSupport() );
1309 USHORT nItemCount = pMenu->GetItemCount();
1310 ::rtl::OUString aItemCommand;
1311 m_aMenuItemHandlerVector.reserve(nItemCount);
1312 for ( USHORT i = 0; i < nItemCount; i++ )
1314 USHORT nItemId = FillItemCommand(aItemCommand,pMenu, i );
1316 // Set module identifier when provided from outside
1317 if ( rModuleIdentifier.getLength() > 0 )
1319 m_aModuleIdentifier = rModuleIdentifier;
1320 m_bModuleIdentified = sal_True;
1323 if (( pMenu->IsMenuBar() || bAccessibilityEnabled ) &&
1324 ( pMenu->GetItemText( nItemId ).Len() == 0 ))
1326 if ( aItemCommand.getLength() > 0 )
1327 pMenu->SetItemText( nItemId, RetrieveLabelFromCommand( aItemCommand ));
1330 Reference< XDispatch > xDispatch;
1331 Reference< XStatusListener > xStatusListener;
1332 PopupMenu* pPopup = pMenu->GetPopupMenu( nItemId );
1333 bool bItemShowMenuImages = m_bShowMenuImages;
1334 MenuItemBits nBits = pMenu->GetItemBits( nItemId );
1335 // overwrite the show icons on menu option?
1336 if ( nBits )
1337 bItemShowMenuImages = ( ( nBits & MIB_ICON ) == MIB_ICON );
1338 if ( pPopup )
1340 // Retrieve module identifier from Help Command entry
1341 rtl::OUString aModuleIdentifier( rModuleIdentifier );
1342 if ( pMenu->GetHelpCommand( nItemId ).Len() > 0 )
1344 aModuleIdentifier = pMenu->GetHelpCommand( nItemId );
1345 pMenu->SetHelpCommand( nItemId, aEmpty );
1348 if ( m_xPopupMenuControllerRegistration.is() &&
1349 pPopup->GetItemCount() == 0 &&
1350 m_xPopupMenuControllerRegistration->hasController( aItemCommand, rtl::OUString() )
1353 // Check if we have to create a popup menu for a uno based popup menu controller.
1354 // We have to set an empty popup menu into our menu structure so the controller also
1355 // works with inplace OLE. Remove old dummy popup menu!
1356 MenuItemHandler* pItemHandler = new MenuItemHandler( nItemId, xStatusListener, xDispatch );
1357 VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu;
1358 PopupMenu* pNewPopupMenu = (PopupMenu *)pVCLXPopupMenu->GetMenu();
1359 pMenu->SetPopupMenu( nItemId, pNewPopupMenu );
1360 pItemHandler->xPopupMenu = Reference< com::sun::star::awt::XPopupMenu >( (OWeakObject *)pVCLXPopupMenu, UNO_QUERY );
1361 pItemHandler->aMenuItemURL = aItemCommand;
1362 m_aMenuItemHandlerVector.push_back( pItemHandler );
1363 delete pPopup;
1365 if ( bAccessibilityEnabled )
1367 if ( CreatePopupMenuController( pItemHandler ))
1368 pItemHandler->xPopupMenuController->updatePopupMenu();
1370 lcl_CheckForChildren(pMenu, nItemId);
1372 else if (( aItemCommand.getLength() > nAddonsURLPrefixLength ) &&
1373 ( aItemCommand.indexOf( ADDONSPOPUPMENU_URL_PREFIX ) == 0 ))
1375 // A special addon popup menu, must be created with a different ctor
1376 // #110897#
1377 MenuBarManager* pSubMenuManager = new MenuBarManager( getServiceFactory(), m_xFrame, m_xURLTransformer,(AddonPopupMenu *)pPopup, bDeleteChildren, bDeleteChildren );
1378 AddMenu(pSubMenuManager,aItemCommand,nItemId);
1380 else
1382 Reference< XDispatchProvider > xPopupMenuDispatchProvider( rDispatchProvider );
1384 // Retrieve possible attributes struct
1385 MenuConfiguration::Attributes* pAttributes = (MenuConfiguration::Attributes *)(pMenu->GetUserValue( nItemId ));
1386 if ( pAttributes )
1387 xPopupMenuDispatchProvider = pAttributes->xDispatchProvider;
1389 // Check if this is the help menu. Add menu item if needed
1390 if ( nItemId == SID_HELPMENU || aItemCommand == aSlotHelpMenu || aItemCommand == aCmdHelpMenu )
1392 // Check if this is the help menu. Add menu item if needed
1393 CheckAndAddMenuExtension( pPopup );
1395 else if (( nItemId == SID_ADDONLIST || aItemCommand == aSlotSpecialToolsMenu || aItemCommand == aCmdToolsMenu ) &&
1396 AddonMenuManager::HasAddonMenuElements() )
1398 // Create addon popup menu if there exist elements and this is the tools popup menu
1399 USHORT nCount = 0;
1400 AddonMenu* pSubMenu = AddonMenuManager::CreateAddonMenu( rFrame );
1401 if ( pSubMenu && ( pSubMenu->GetItemCount() > 0 ))
1403 if ( pPopup->GetItemType( nCount-1 ) != MENUITEM_SEPARATOR )
1404 pPopup->InsertSeparator();
1406 // Use resource to load popup menu title
1407 String aAddonsStrRes = String( FwkResId( STR_MENU_ADDONS ));
1408 pPopup->InsertItem( ITEMID_ADDONLIST, aAddonsStrRes );
1409 pPopup->SetPopupMenu( ITEMID_ADDONLIST, pSubMenu );
1411 // Set item command for popup menu to enable it for GetImageFromURL
1412 const ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
1413 ::rtl::OUString aNewItemCommand( aSlotString );
1414 aNewItemCommand += ::rtl::OUString::valueOf( (sal_Int32)ITEMID_ADDONLIST );
1415 pPopup->SetItemCommand( ITEMID_ADDONLIST, aNewItemCommand );
1417 else
1418 delete pSubMenu;
1421 if ( nItemId == ITEMID_ADDONLIST )
1423 // Create control structure within the "Tools" sub menu for the Add-Ons popup menu
1424 // #110897# MenuBarManager* pSubMenuManager = new MenuBarManager( rFrame, pSubMenu, sal_True, sal_False );
1425 AddonMenu* pSubMenu = dynamic_cast< AddonMenu* >( pPopup );
1426 if ( pSubMenu )
1428 MenuBarManager* pSubMenuManager = new MenuBarManager( getServiceFactory(), m_xFrame, m_xURLTransformer,pSubMenu, sal_True, sal_False );
1429 AddMenu(pSubMenuManager,aItemCommand,nItemId);
1430 pSubMenuManager->m_aMenuItemCommand = ::rtl::OUString();
1432 // Set image for the addon popup menu item
1433 if ( bItemShowMenuImages && !pPopup->GetItemImage( ITEMID_ADDONLIST ))
1435 Reference< XFrame > xTemp( rFrame );
1436 Image aImage = GetImageFromURL( xTemp, aItemCommand, FALSE, m_bWasHiContrast );
1437 if ( !!aImage )
1438 pPopup->SetItemImage( ITEMID_ADDONLIST, aImage );
1442 else
1444 // #110897# MenuBarManager* pSubMenuManager = new MenuBarManager( rFrame, pPopupMenu, bDeleteChildren, bDeleteChildren );
1445 MenuBarManager* pSubMenuMgr = new MenuBarManager( getServiceFactory(), rFrame, m_xURLTransformer,rDispatchProvider, aModuleIdentifier, pPopup, bDeleteChildren, bDeleteChildren );
1446 AddMenu(pSubMenuMgr,aItemCommand,nItemId);
1450 else if ( pMenu->GetItemType( i ) != MENUITEM_SEPARATOR )
1452 if ( bItemShowMenuImages )
1454 if ( AddonMenuManager::IsAddonMenuId( nItemId ))
1456 // Add-Ons uses images from different places
1457 Image aImage;
1458 rtl::OUString aImageId;
1460 MenuConfiguration::Attributes* pMenuAttributes =
1461 (MenuConfiguration::Attributes*)pMenu->GetUserValue( nItemId );
1463 if ( pMenuAttributes && pMenuAttributes->aImageId.getLength() > 0 )
1465 // Retrieve image id from menu attributes
1466 aImage = GetImageFromURL( m_xFrame, aImageId, FALSE, m_bWasHiContrast );
1469 if ( !aImage )
1471 aImage = GetImageFromURL( m_xFrame, aItemCommand, FALSE, m_bWasHiContrast );
1472 if ( !aImage )
1473 aImage = AddonsOptions().GetImageFromURL( aItemCommand, FALSE, m_bWasHiContrast );
1476 if ( !!aImage )
1477 pMenu->SetItemImage( nItemId, aImage );
1478 else
1479 m_bRetrieveImages = sal_True;
1481 m_bRetrieveImages = sal_True;
1484 MenuItemHandler* pItemHandler = new MenuItemHandler( nItemId, xStatusListener, xDispatch );
1485 pItemHandler->aMenuItemURL = aItemCommand;
1487 if ( m_xPopupMenuControllerRegistration.is() &&
1488 m_xPopupMenuControllerRegistration->hasController( aItemCommand, rtl::OUString() ))
1490 // Check if we have to create a popup menu for a uno based popup menu controller.
1491 // We have to set an empty popup menu into our menu structure so the controller also
1492 // works with inplace OLE.
1493 VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu;
1494 PopupMenu* pPopupMenu = (PopupMenu *)pVCLXPopupMenu->GetMenu();
1495 pMenu->SetPopupMenu( pItemHandler->nItemId, pPopupMenu );
1496 pItemHandler->xPopupMenu = Reference< com::sun::star::awt::XPopupMenu >( (OWeakObject *)pVCLXPopupMenu, UNO_QUERY );
1498 if ( bAccessibilityEnabled && CreatePopupMenuController( pItemHandler ) )
1500 pItemHandler->xPopupMenuController->updatePopupMenu();
1503 lcl_CheckForChildren(pMenu, pItemHandler->nItemId);
1506 m_aMenuItemHandlerVector.push_back( pItemHandler );
1510 if ( bAccessibilityEnabled )
1512 RetrieveShortcuts( m_aMenuItemHandlerVector );
1513 std::vector< MenuItemHandler* >::iterator p;
1514 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
1516 MenuItemHandler* pMenuItemHandler = *p;
1518 // Set key code, workaround for hard-coded shortcut F1 mapped to .uno:HelpIndex
1519 // Only non-popup menu items can have a short-cut
1520 if ( pMenuItemHandler->aMenuItemURL == aCmdHelpIndex )
1522 KeyCode aKeyCode( KEY_F1 );
1523 pMenu->SetAccelKey( pMenuItemHandler->nItemId, aKeyCode );
1525 else if ( pMenu->GetPopupMenu( pMenuItemHandler->nItemId ) == 0 )
1526 pMenu->SetAccelKey( pMenuItemHandler->nItemId, pMenuItemHandler->aKeyCode );
1530 SetHdl();
1533 void MenuBarManager::impl_RetrieveShortcutsFromConfiguration(
1534 const Reference< XAcceleratorConfiguration >& rAccelCfg,
1535 const Sequence< rtl::OUString >& rCommands,
1536 std::vector< MenuItemHandler* >& aMenuShortCuts )
1538 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::impl_RetrieveShortcutsFromConfiguration" );
1539 if ( rAccelCfg.is() )
1543 com::sun::star::awt::KeyEvent aKeyEvent;
1544 Sequence< Any > aSeqKeyCode = rAccelCfg->getPreferredKeyEventsForCommandList( rCommands );
1545 for ( sal_Int32 i = 0; i < aSeqKeyCode.getLength(); i++ )
1547 if ( aSeqKeyCode[i] >>= aKeyEvent )
1548 aMenuShortCuts[i]->aKeyCode = svt::AcceleratorExecute::st_AWTKey2VCLKey( aKeyEvent );
1551 catch ( IllegalArgumentException& )
1557 void MenuBarManager::RetrieveShortcuts( std::vector< MenuItemHandler* >& aMenuShortCuts )
1559 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RetrieveShortcuts" );
1560 if ( !m_bModuleIdentified )
1562 m_bModuleIdentified = sal_True;
1563 Reference< XModuleManager > xModuleManager;
1564 xModuleManager = Reference< XModuleManager >( getServiceFactory()->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW );
1568 m_aModuleIdentifier = xModuleManager->identify( m_xFrame );
1570 catch( Exception& )
1575 if ( m_bModuleIdentified )
1577 Reference< XAcceleratorConfiguration > xDocAccelCfg( m_xDocAcceleratorManager );
1578 Reference< XAcceleratorConfiguration > xModuleAccelCfg( m_xModuleAcceleratorManager );
1579 Reference< XAcceleratorConfiguration > xGlobalAccelCfg( m_xGlobalAcceleratorManager );
1581 if ( !m_bAcceleratorCfg )
1583 // Retrieve references on demand
1584 m_bAcceleratorCfg = sal_True;
1585 if ( !xDocAccelCfg.is() )
1587 Reference< XController > xController = m_xFrame->getController();
1588 Reference< XModel > xModel;
1589 if ( xController.is() )
1591 xModel = xController->getModel();
1592 if ( xModel.is() )
1594 Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY );
1595 if ( xSupplier.is() )
1597 Reference< XUIConfigurationManager > xDocUICfgMgr( xSupplier->getUIConfigurationManager(), UNO_QUERY );
1598 if ( xDocUICfgMgr.is() )
1600 xDocAccelCfg = Reference< XAcceleratorConfiguration >( xDocUICfgMgr->getShortCutManager(), UNO_QUERY );
1601 m_xDocAcceleratorManager = xDocAccelCfg;
1608 if ( !xModuleAccelCfg.is() )
1610 Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier( getServiceFactory()->createInstance(
1611 SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ),
1612 UNO_QUERY );
1615 Reference< XUIConfigurationManager > xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier );
1616 if ( xUICfgMgr.is() )
1618 xModuleAccelCfg = Reference< XAcceleratorConfiguration >( xUICfgMgr->getShortCutManager(), UNO_QUERY );
1619 m_xModuleAcceleratorManager = xModuleAccelCfg;
1622 catch ( RuntimeException& )
1624 throw;
1626 catch ( Exception& )
1631 if ( !xGlobalAccelCfg.is() )
1633 xGlobalAccelCfg = Reference< XAcceleratorConfiguration >( getServiceFactory()->createInstance(
1634 SERVICENAME_GLOBALACCELERATORCONFIGURATION ),
1635 UNO_QUERY );
1636 m_xGlobalAcceleratorManager = xGlobalAccelCfg;
1640 KeyCode aEmptyKeyCode;
1641 Sequence< rtl::OUString > aSeq( aMenuShortCuts.size() );
1642 const sal_uInt32 nCount = aMenuShortCuts.size();
1643 for ( sal_uInt32 i = 0; i < nCount; ++i )
1645 aSeq[i] = aMenuShortCuts[i]->aMenuItemURL;
1646 aMenuShortCuts[i]->aKeyCode = aEmptyKeyCode;
1649 if ( m_xGlobalAcceleratorManager.is() )
1650 impl_RetrieveShortcutsFromConfiguration( xGlobalAccelCfg, aSeq, aMenuShortCuts );
1651 if ( m_xModuleAcceleratorManager.is() )
1652 impl_RetrieveShortcutsFromConfiguration( xModuleAccelCfg, aSeq, aMenuShortCuts );
1653 if ( m_xDocAcceleratorManager.is() )
1654 impl_RetrieveShortcutsFromConfiguration( xGlobalAccelCfg, aSeq, aMenuShortCuts );
1658 void MenuBarManager::RetrieveImageManagers()
1660 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RetrieveImageManagers" );
1661 if ( !m_xDocImageManager.is() )
1663 Reference< XController > xController = m_xFrame->getController();
1664 Reference< XModel > xModel;
1665 if ( xController.is() )
1667 xModel = xController->getModel();
1668 if ( xModel.is() )
1670 Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY );
1671 if ( xSupplier.is() )
1673 Reference< XUIConfigurationManager > xDocUICfgMgr( xSupplier->getUIConfigurationManager(), UNO_QUERY );
1674 m_xDocImageManager = Reference< XImageManager >( xDocUICfgMgr->getImageManager(), UNO_QUERY );
1675 m_xDocImageManager->addConfigurationListener(
1676 Reference< XUIConfigurationListener >(
1677 static_cast< OWeakObject* >( this ), UNO_QUERY ));
1683 Reference< XModuleManager > xModuleManager;
1684 if ( m_aModuleIdentifier.getLength() == 0 )
1685 xModuleManager.set( getServiceFactory()->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW );
1689 if ( xModuleManager.is() )
1690 m_aModuleIdentifier = xModuleManager->identify( Reference< XInterface >( m_xFrame, UNO_QUERY ) );
1692 catch( Exception& )
1696 if ( !m_xModuleImageManager.is() )
1698 Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier( getServiceFactory()->createInstance(
1699 SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ),
1700 UNO_QUERY );
1701 Reference< XUIConfigurationManager > xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier );
1702 m_xModuleImageManager.set( xUICfgMgr->getImageManager(), UNO_QUERY );
1703 m_xModuleImageManager->addConfigurationListener( Reference< XUIConfigurationListener >(
1704 static_cast< OWeakObject* >( this ), UNO_QUERY ));
1708 void MenuBarManager::FillMenuWithConfiguration(
1709 USHORT& nId,
1710 Menu* pMenu,
1711 const ::rtl::OUString& rModuleIdentifier,
1712 const Reference< XIndexAccess >& rItemContainer,
1713 const Reference< XURLTransformer >& rTransformer )
1715 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillMenuWithConfiguration" );
1716 Reference< XDispatchProvider > xEmptyDispatchProvider;
1717 MenuBarManager::FillMenu( nId, pMenu, rModuleIdentifier, rItemContainer, xEmptyDispatchProvider );
1719 // Merge add-on menu entries into the menu bar
1720 MenuBarManager::MergeAddonMenus( static_cast< Menu* >( pMenu ),
1721 AddonsOptions().GetMergeMenuInstructions(),
1722 rModuleIdentifier );
1724 sal_Bool bHasDisabledEntries = SvtCommandOptions().HasEntries( SvtCommandOptions::CMDOPTION_DISABLED );
1725 if ( bHasDisabledEntries )
1727 sal_uInt16 nCount = pMenu->GetItemCount();
1728 for ( sal_uInt16 i = 0; i < nCount; i++ )
1730 sal_uInt16 nID = pMenu->GetItemId( i );
1731 if ( nID > 0 )
1733 PopupMenu* pPopupMenu = pMenu->GetPopupMenu( nID );
1734 if ( pPopupMenu )
1736 if ( MustBeHidden( pPopupMenu, rTransformer ))
1737 pMenu->HideItem( nId );
1744 void MenuBarManager::FillMenu(
1745 USHORT& nId,
1746 Menu* pMenu,
1747 const rtl::OUString& rModuleIdentifier,
1748 const Reference< XIndexAccess >& rItemContainer,
1749 const Reference< XDispatchProvider >& rDispatchProvider )
1751 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillMenu" );
1752 // Fill menu bar with container contents
1753 for ( sal_Int32 n = 0; n < rItemContainer->getCount(); n++ )
1755 Sequence< PropertyValue > aProp;
1756 rtl::OUString aCommandURL;
1757 rtl::OUString aLabel;
1758 rtl::OUString aHelpURL;
1759 rtl::OUString aModuleIdentifier( rModuleIdentifier );
1760 sal_uInt16 nType = 0;
1761 Reference< XIndexAccess > xIndexContainer;
1762 Reference< XDispatchProvider > xDispatchProvider( rDispatchProvider );
1763 sal_Int16 nStyle = 0;
1766 if ( rItemContainer->getByIndex( n ) >>= aProp )
1768 for ( int i = 0; i < aProp.getLength(); i++ )
1770 rtl::OUString aPropName = aProp[i].Name;
1771 if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_COMMANDURL,
1772 LEN_DESCRIPTOR_COMMANDURL ))
1773 aProp[i].Value >>= aCommandURL;
1774 else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_HELPURL,
1775 LEN_DESCRIPTOR_HELPURL ))
1776 aProp[i].Value >>= aHelpURL;
1777 else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_CONTAINER,
1778 LEN_DESCRIPTOR_CONTAINER ))
1779 aProp[i].Value >>= xIndexContainer;
1780 else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_LABEL,
1781 LEN_DESCRIPTOR_LABEL ))
1782 aProp[i].Value >>= aLabel;
1783 else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_TYPE,
1784 LEN_DESCRIPTOR_TYPE ))
1785 aProp[i].Value >>= nType;
1786 else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_MODULEIDENTIFIER,
1787 LEN_DESCRIPTOR_MODULEIDENTIFIER ))
1788 aProp[i].Value >>= aModuleIdentifier;
1789 else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_DISPATCHPROVIDER,
1790 LEN_DESCRIPTOR_DISPATCHPROVIDER ))
1791 aProp[i].Value >>= xDispatchProvider;
1792 else if ( aProp[i].Name.equalsAsciiL( ITEM_DESCRIPTOR_STYLE, ITEM_DESCRIPTOR_STYLE_LEN ))
1793 aProp[i].Value >>= nStyle;
1796 if ( nType == ::com::sun::star::ui::ItemType::DEFAULT )
1798 pMenu->InsertItem( nId, aLabel );
1799 pMenu->SetItemCommand( nId, aCommandURL );
1801 sal_Int32 nHelpId = aHelpURL.toInt32();
1802 if ( nHelpId > 0 )
1803 pMenu->SetHelpId( nId, (USHORT)nHelpId );
1804 if ( nStyle )
1806 MenuItemBits nBits = pMenu->GetItemBits( nId );
1807 if ( nStyle & ::com::sun::star::ui::ItemStyle::ICON )
1808 nBits |= MIB_ICON;
1809 if ( nStyle & ::com::sun::star::ui::ItemStyle::TEXT )
1810 nBits |= MIB_TEXT;
1811 pMenu->SetItemBits( nId, nBits );
1813 if ( xIndexContainer.is() )
1815 PopupMenu* pNewPopupMenu = new PopupMenu;
1816 pMenu->SetPopupMenu( nId, pNewPopupMenu );
1818 if ( xDispatchProvider.is() )
1820 // Use attributes struct to transport special dispatch provider
1821 MenuConfiguration::Attributes* pAttributes = new MenuConfiguration::Attributes;
1822 pAttributes->xDispatchProvider = xDispatchProvider;
1823 pMenu->SetUserValue( nId, (ULONG)( pAttributes ));
1826 // Use help command to transport module identifier
1827 if ( aModuleIdentifier.getLength() > 0 )
1828 pMenu->SetHelpCommand( nId, aModuleIdentifier );
1830 ++nId;
1831 FillMenu( nId, pNewPopupMenu, aModuleIdentifier, xIndexContainer, xDispatchProvider );
1833 else
1834 ++nId;
1836 else
1838 pMenu->InsertSeparator();
1839 ++nId;
1843 catch ( IndexOutOfBoundsException& )
1845 break;
1850 void MenuBarManager::MergeAddonMenus(
1851 Menu* pMenuBar,
1852 const MergeMenuInstructionContainer& aMergeInstructionContainer,
1853 const ::rtl::OUString& rModuleIdentifier )
1855 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MergeAddonMenus" );
1856 // set start value for the item ID for the new addon menu items
1857 sal_uInt16 nItemId = ADDONMENU_MERGE_ITEMID_START;
1859 const sal_uInt32 nCount = aMergeInstructionContainer.size();
1860 for ( sal_uInt32 i = 0; i < nCount; i++ )
1862 const MergeMenuInstruction& rMergeInstruction = aMergeInstructionContainer[i];
1864 if ( MenuBarMerger::IsCorrectContext( rMergeInstruction.aMergeContext, rModuleIdentifier ))
1866 ::std::vector< ::rtl::OUString > aMergePath;
1868 // retrieve the merge path from the merge point string
1869 MenuBarMerger::RetrieveReferencePath( rMergeInstruction.aMergePoint, aMergePath );
1871 // convert the sequence/sequence property value to a more convenient vector<>
1872 AddonMenuContainer aMergeMenuItems;
1873 MenuBarMerger::GetSubMenu( rMergeInstruction.aMergeMenu, aMergeMenuItems );
1875 // try to find the reference point for our merge operation
1876 Menu* pMenu = pMenuBar;
1877 ReferencePathInfo aResult = MenuBarMerger::FindReferencePath( aMergePath, pMenu );
1879 if ( aResult.eResult == RP_OK )
1881 // normal merge operation
1882 MenuBarMerger::ProcessMergeOperation( aResult.pPopupMenu,
1883 aResult.nPos,
1884 nItemId,
1885 rMergeInstruction.aMergeCommand,
1886 rMergeInstruction.aMergeCommandParameter,
1887 rModuleIdentifier,
1888 aMergeMenuItems );
1890 else
1892 // fallback
1893 MenuBarMerger::ProcessFallbackOperation( aResult,
1894 nItemId,
1895 rMergeInstruction.aMergeCommand,
1896 rMergeInstruction.aMergeFallback,
1897 aMergePath,
1898 rModuleIdentifier,
1899 aMergeMenuItems );
1905 void MenuBarManager::SetItemContainer( const Reference< XIndexAccess >& rItemContainer )
1907 RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::MenuBarManager::SetItemContainer" );
1909 ResetableGuard aGuard( m_aLock );
1911 Reference< XFrame > xFrame = m_xFrame;
1913 if ( !m_bModuleIdentified )
1915 m_bModuleIdentified = sal_True;
1916 Reference< XModuleManager > xModuleManager;
1917 xModuleManager = Reference< XModuleManager >( getServiceFactory()->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW );
1921 m_aModuleIdentifier = xModuleManager->identify( xFrame );
1923 catch( Exception& )
1928 // Clear MenuBarManager structures
1930 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
1932 // Check active state as we cannot change our VCL menu during activation by the user
1933 if ( m_bActive )
1935 m_xDeferedItemContainer = rItemContainer;
1936 return;
1939 RemoveListener();
1940 std::vector< MenuItemHandler* >::iterator p;
1941 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
1943 MenuItemHandler* pItemHandler = *p;
1944 pItemHandler->xMenuItemDispatch.clear();
1945 pItemHandler->xSubMenuManager.clear();
1946 delete pItemHandler;
1948 m_aMenuItemHandlerVector.clear();
1950 // Remove top-level parts
1951 m_pVCLMenu->Clear();
1953 USHORT nId = 1;
1955 // Fill menu bar with container contents
1956 FillMenuWithConfiguration( nId, (Menu *)m_pVCLMenu, m_aModuleIdentifier, rItemContainer, m_xURLTransformer );
1958 // Refill menu manager again
1959 Reference< XDispatchProvider > xDispatchProvider;
1960 FillMenuManager( m_pVCLMenu, xFrame, xDispatchProvider, m_aModuleIdentifier, sal_False, sal_True );
1962 // add itself as frame action listener
1963 m_xFrame->addFrameActionListener( Reference< XFrameActionListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
1967 void MenuBarManager::GetPopupController( PopupControllerCache& rPopupController )
1969 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::GetPopupController" );
1970 String aPopupScheme = String::CreateFromAscii( "vnd.sun.star.popup:" );
1972 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
1974 std::vector< MenuItemHandler* >::iterator p;
1975 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
1977 MenuItemHandler* pItemHandler = *p;
1978 if ( pItemHandler->xPopupMenuController.is() )
1980 Reference< XDispatchProvider > xDispatchProvider( pItemHandler->xPopupMenuController, UNO_QUERY );
1982 PopupControllerEntry aPopupControllerEntry;
1983 aPopupControllerEntry.m_xDispatchProvider = xDispatchProvider;
1985 // Just use the main part of the URL for popup menu controllers
1986 sal_Int32 nQueryPart( 0 );
1987 sal_Int32 nSchemePart( 0 );
1988 rtl::OUString aMainURL( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.popup:" ));
1989 rtl::OUString aMenuURL( pItemHandler->aMenuItemURL );
1991 nSchemePart = aMenuURL.indexOf( ':' );
1992 if (( nSchemePart > 0 ) &&
1993 ( aMenuURL.getLength() > ( nSchemePart+1 )))
1995 nQueryPart = aMenuURL.indexOf( '?', nSchemePart );
1996 if ( nQueryPart > 0 )
1997 aMainURL += aMenuURL.copy( nSchemePart, nQueryPart-nSchemePart );
1998 else if ( nQueryPart == -1 )
1999 aMainURL += aMenuURL.copy( nSchemePart+1 );
2001 rPopupController.insert( PopupControllerCache::value_type(
2002 aMainURL, aPopupControllerEntry ));
2005 if ( pItemHandler->xSubMenuManager.is() )
2007 MenuBarManager* pMenuBarManager = (MenuBarManager*)(pItemHandler->xSubMenuManager.get());
2008 if ( pMenuBarManager )
2009 pMenuBarManager->GetPopupController( rPopupController );
2014 // #110897#
2015 const Reference< XMultiServiceFactory >& MenuBarManager::getServiceFactory()
2017 // #110897#
2018 return mxServiceFactory;
2021 void MenuBarManager::AddMenu(MenuBarManager* pSubMenuManager,const ::rtl::OUString& _sItemCommand,USHORT _nItemId)
2023 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::AddMenu" );
2024 Reference< XStatusListener > xSubMenuManager( static_cast< OWeakObject *>( pSubMenuManager ), UNO_QUERY );
2025 m_xFrame->addFrameActionListener( Reference< XFrameActionListener >( xSubMenuManager, UNO_QUERY ));
2027 // store menu item command as we later have to know which menu is active (see Activate handler)
2028 pSubMenuManager->m_aMenuItemCommand = _sItemCommand;
2029 Reference< XDispatch > xDispatch;
2030 MenuItemHandler* pMenuItemHandler = new MenuItemHandler(
2031 _nItemId,
2032 xSubMenuManager,
2033 xDispatch );
2034 pMenuItemHandler->aMenuItemURL = _sItemCommand;
2035 m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
2038 USHORT MenuBarManager::FillItemCommand(::rtl::OUString& _rItemCommand,Menu* _pMenu,USHORT _nIndex) const
2040 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillItemCommand" );
2041 USHORT nItemId = _pMenu->GetItemId( _nIndex );
2043 _rItemCommand = _pMenu->GetItemCommand( nItemId );
2044 if ( !_rItemCommand.getLength() )
2046 const static ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
2047 _rItemCommand = aSlotString;
2048 _rItemCommand += ::rtl::OUString::valueOf( (sal_Int32)nItemId );
2049 _pMenu->SetItemCommand( nItemId, _rItemCommand );
2051 return nItemId;
2053 void MenuBarManager::Init(const Reference< XFrame >& rFrame,AddonMenu* pAddonMenu,sal_Bool bDelete,sal_Bool bDeleteChildren,bool _bHandlePopUp)
2055 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Init" );
2056 m_bActive = sal_False;
2057 m_bDeleteMenu = bDelete;
2058 m_bDeleteChildren = bDeleteChildren;
2059 m_pVCLMenu = pAddonMenu;
2060 m_xFrame = rFrame;
2061 m_bInitialized = sal_False;
2062 m_bIsBookmarkMenu = sal_True;
2064 rtl::OUString aModuleIdentifier;
2065 m_xPopupMenuControllerRegistration = Reference< ::com::sun::star::frame::XUIControllerRegistration >(
2066 getServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.PopupMenuControllerFactory" ))),
2067 UNO_QUERY );
2069 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
2070 m_bWasHiContrast = rSettings.GetHighContrastMode();
2072 Reference< XStatusListener > xStatusListener;
2073 Reference< XDispatch > xDispatch;
2074 USHORT nItemCount = pAddonMenu->GetItemCount();
2075 ::rtl::OUString aItemCommand;
2076 m_aMenuItemHandlerVector.reserve(nItemCount);
2077 for ( USHORT i = 0; i < nItemCount; i++ )
2079 USHORT nItemId = FillItemCommand(aItemCommand,pAddonMenu, i );
2081 PopupMenu* pPopupMenu = pAddonMenu->GetPopupMenu( nItemId );
2082 if ( pPopupMenu )
2084 // #110897#
2085 Reference< XDispatchProvider > xDispatchProvider;
2086 MenuBarManager* pSubMenuManager = new MenuBarManager( getServiceFactory(), rFrame, m_xURLTransformer,xDispatchProvider, aModuleIdentifier, pPopupMenu, _bHandlePopUp ? sal_False : bDeleteChildren, _bHandlePopUp ? sal_False : bDeleteChildren );
2088 Reference< XStatusListener > xSubMenuManager( static_cast< OWeakObject *>( pSubMenuManager ), UNO_QUERY );
2090 // store menu item command as we later have to know which menu is active (see Acivate handler)
2091 pSubMenuManager->m_aMenuItemCommand = aItemCommand;
2093 MenuItemHandler* pMenuItemHandler = new MenuItemHandler(
2094 nItemId,
2095 xSubMenuManager,
2096 xDispatch );
2097 m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
2099 else
2101 if ( pAddonMenu->GetItemType( i ) != MENUITEM_SEPARATOR )
2103 MenuConfiguration::Attributes* pAddonAttributes = (MenuConfiguration::Attributes *)(pAddonMenu->GetUserValue( nItemId ));
2104 MenuItemHandler* pMenuItemHandler = new MenuItemHandler( nItemId, xStatusListener, xDispatch );
2106 if ( pAddonAttributes )
2108 // read additional attributes from attributes struct and AddonMenu implementation will delete all attributes itself!!
2109 pMenuItemHandler->aTargetFrame = pAddonAttributes->aTargetFrame;
2112 pMenuItemHandler->aMenuItemURL = aItemCommand;
2113 if ( _bHandlePopUp )
2115 // Check if we have to create a popup menu for a uno based popup menu controller.
2116 // We have to set an empty popup menu into our menu structure so the controller also
2117 // works with inplace OLE.
2118 if ( m_xPopupMenuControllerRegistration.is() &&
2119 m_xPopupMenuControllerRegistration->hasController( aItemCommand, rtl::OUString() ))
2121 VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu;
2122 PopupMenu* pCtlPopupMenu = (PopupMenu *)pVCLXPopupMenu->GetMenu();
2123 pAddonMenu->SetPopupMenu( pMenuItemHandler->nItemId, pCtlPopupMenu );
2124 pMenuItemHandler->xPopupMenu = Reference< com::sun::star::awt::XPopupMenu >( (OWeakObject *)pVCLXPopupMenu, UNO_QUERY );
2128 m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
2133 SetHdl();
2136 void MenuBarManager::SetHdl()
2138 m_pVCLMenu->SetHighlightHdl( LINK( this, MenuBarManager, Highlight ));
2139 m_pVCLMenu->SetActivateHdl( LINK( this, MenuBarManager, Activate ));
2140 m_pVCLMenu->SetDeactivateHdl( LINK( this, MenuBarManager, Deactivate ));
2141 m_pVCLMenu->SetSelectHdl( LINK( this, MenuBarManager, Select ));
2143 if ( !m_xURLTransformer.is() && mxServiceFactory.is() )
2144 m_xURLTransformer.set( mxServiceFactory->createInstance(
2145 SERVICENAME_URLTRANSFORMER),
2146 UNO_QUERY );