1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
30 
31 
32 //_________________________________________________________________________________________________________________
33 //	my own includes
34 //_________________________________________________________________________________________________________________
35 #include <uielement/menubarmanager.hxx>
36 #include <framework/menuconfiguration.hxx>
37 #include <framework/bmkmenu.hxx>
38 #include <framework/addonmenu.hxx>
39 #include <framework/imageproducer.hxx>
40 #include <threadhelp/resetableguard.hxx>
41 #include "framework/addonsoptions.hxx"
42 #include <classes/fwkresid.hxx>
43 #include <classes/menumanager.hxx>
44 #include <framework/acceleratorinfo.hxx>
45 #include <helper/mischelper.hxx>
46 #include <framework/menuextensionsupplier.hxx>
47 #include <classes/resource.hrc>
48 #include <services.h>
49 
50 //_________________________________________________________________________________________________________________
51 //	interface includes
52 //_________________________________________________________________________________________________________________
53 #include <com/sun/star/frame/XDispatch.hpp>
54 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
55 #include <com/sun/star/lang/DisposedException.hpp>
56 #include <com/sun/star/beans/XPropertySet.hpp>
57 #include <com/sun/star/frame/XFramesSupplier.hpp>
58 #include <com/sun/star/frame/XDesktop.hpp>
59 #include <com/sun/star/container/XEnumeration.hpp>
60 #include <com/sun/star/util/XStringWidth.hpp>
61 #include <com/sun/star/uno/XComponentContext.hpp>
62 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
63 #include <com/sun/star/frame/XPopupMenuController.hpp>
64 #include <com/sun/star/frame/XUIControllerRegistration.hpp>
65 #ifndef _COM_SUN_STAR_LANG_XSYSTEMDEPENDENT_HPP_
66 #include <com/sun/star/lang/SystemDependent.hpp>
67 #endif
68 #include <com/sun/star/ui/ItemType.hpp>
69 #include <com/sun/star/ui/ImageType.hpp>
70 #include <com/sun/star/container/XNameAccess.hpp>
71 #include <com/sun/star/frame/XModuleManager.hpp>
72 #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
73 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
74 #include <com/sun/star/ui/ItemStyle.hpp>
75 #include <com/sun/star/frame/status/Visibility.hpp>
76 
77 //_________________________________________________________________________________________________________________
78 //	includes of other projects
79 //_________________________________________________________________________________________________________________
80 #include <comphelper/processfactory.hxx>
81 #include <comphelper/extract.hxx>
82 #include <svtools/menuoptions.hxx>
83 #include <unotools/historyoptions.hxx>
84 #include <unotools/pathoptions.hxx>
85 #include <unotools/cmdoptions.hxx>
86 #include <unotools/localfilehelper.hxx>
87 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
88 #include <toolkit/unohlp.hxx>
89 #endif
90 #include <tools/urlobj.hxx>
91 #include <vcl/svapp.hxx>
92 #include <vcl/window.hxx>
93 #include <vos/mutex.hxx>
94 #include <vcl/svapp.hxx>
95 #include <osl/file.hxx>
96 #include <cppuhelper/implbase1.hxx>
97 #include <svtools/acceleratorexecute.hxx>
98 #include <rtl/logfile.hxx>
99 #include "svtools/miscopt.hxx"
100 #include <framework/addonmenu.hxx>
101 #include <uielement/menubarmerger.hxx>
102 #include <dispatch/uieventloghelper.hxx>
103 
104 // Be careful removing this "bad" construct. There are serious problems
105 // with #define STRICT and including windows.h. Changing this needs some
106 // redesign on other projects, too. Especially sal/main.h which defines
107 // HINSTANCE depending on STRCIT!!!!!!!!!!!!!!!
108 struct SystemMenuData
109 {
110     unsigned long nSize;
111 	long          hMenu;
112 };
113 
114 //_________________________________________________________________________________________________________________
115 //	namespace
116 //_________________________________________________________________________________________________________________
117 
118 using namespace ::cppu;
119 using namespace ::vos;
120 using namespace ::com::sun::star;
121 using namespace ::com::sun::star::uno;
122 using namespace ::com::sun::star::util;
123 using namespace ::com::sun::star::beans;
124 using namespace ::com::sun::star::frame;
125 using namespace ::com::sun::star::container;
126 using namespace ::com::sun::star::lang;
127 using namespace ::com::sun::star::frame;
128 using namespace ::com::sun::star::ui;
129 
130 static const char ITEM_DESCRIPTOR_COMMANDURL[]        = "CommandURL";
131 static const char ITEM_DESCRIPTOR_HELPURL[]           = "HelpURL";
132 static const char ITEM_DESCRIPTOR_CONTAINER[]         = "ItemDescriptorContainer";
133 static const char ITEM_DESCRIPTOR_LABEL[]             = "Label";
134 static const char ITEM_DESCRIPTOR_TYPE[]              = "Type";
135 static const char ITEM_DESCRIPTOR_MODULEIDENTIFIER[]  = "ModuleIdentifier";
136 static const char ITEM_DESCRIPTOR_DISPATCHPROVIDER[]  = "DispatchProvider";
137 static const char ITEM_DESCRIPTOR_STYLE[]             = "Style";
138 static const char ITEM_DESCRIPTOR_ISVISIBLE[]         = "IsVisible";
139 static const char ITEM_DESCRIPTOR_ENABLED[]           = "Enabled";
140 
141 static const sal_Int32 LEN_DESCRIPTOR_COMMANDURL       = 10;
142 static const sal_Int32 LEN_DESCRIPTOR_HELPURL          = 7;
143 static const sal_Int32 LEN_DESCRIPTOR_CONTAINER        = 23;
144 static const sal_Int32 LEN_DESCRIPTOR_LABEL            = 5;
145 static const sal_Int32 LEN_DESCRIPTOR_TYPE             = 4;
146 static const sal_Int32 LEN_DESCRIPTOR_MODULEIDENTIFIER = 16;
147 static const sal_Int32 LEN_DESCRIPTOR_DISPATCHPROVIDER = 16;
148 static const sal_Int32 LEN_DESCRIPTOR_STYLE            = 5;
149 static const sal_Int32 LEN_DESCRIPTOR_ISVISIBLE        = 9;
150 static const sal_Int32 LEN_DESCRIPTOR_ENABLED          = 7;
151 
152 const sal_uInt16 ADDONMENU_MERGE_ITEMID_START = 1500;
153 
154 class StringLength : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XStringWidth >
155 {
156 	public:
157 		StringLength() {}
158 		virtual ~StringLength() {}
159 
160 		// XStringWidth
161 		sal_Int32 SAL_CALL queryStringWidth( const ::rtl::OUString& aString )
162 			throw (RuntimeException)
163 		{
164 			return aString.getLength();
165 		}
166 };
167 
168 namespace framework
169 {
170 
171 // special menu ids/command ids for dynamic popup menus
172 #define SID_SFX_START			5000
173 #define SID_NEWDOCDIRECT		(SID_SFX_START + 537)
174 #define SID_AUTOPILOTMENU		(SID_SFX_START + 1381)
175 #define SID_PICKLIST			(SID_SFX_START + 510)
176 #define SID_MDIWINDOWLIST		(SID_SFX_START + 610)
177 #define SID_ADDONLIST			(SID_SFX_START + 1677)
178 #define SID_HELPMENU			(SID_SFX_START + 410)
179 
180 #define SFX_REFERER_USER		"private:user"
181 
182 const ::rtl::OUString aCmdHelpIndex( RTL_CONSTASCII_USTRINGPARAM( ".uno:HelpIndex" ));
183 const ::rtl::OUString aCmdToolsMenu( RTL_CONSTASCII_USTRINGPARAM( ".uno:ToolsMenu" ));
184 const ::rtl::OUString aCmdHelpMenu( RTL_CONSTASCII_USTRINGPARAM( ".uno:HelpMenu" ));
185 const ::rtl::OUString aSlotHelpMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5410" ));
186 
187 const ::rtl::OUString aSpecialFileMenu( RTL_CONSTASCII_USTRINGPARAM( "file" ));
188 const ::rtl::OUString aSpecialWindowMenu( RTL_CONSTASCII_USTRINGPARAM( "window" ));
189 const ::rtl::OUString aSlotSpecialFileMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5510" ));
190 const ::rtl::OUString aSlotSpecialWindowMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5610" ));
191 const ::rtl::OUString aSlotSpecialToolsMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:6677" ));
192 
193 // special uno commands for picklist and window list
194 const ::rtl::OUString aSpecialFileCommand( RTL_CONSTASCII_USTRINGPARAM( ".uno:PickList" ));
195 const ::rtl::OUString aSpecialWindowCommand( RTL_CONSTASCII_USTRINGPARAM( ".uno:WindowList" ));
196 
197 const ::rtl::OUString UNO_COMMAND( RTL_CONSTASCII_USTRINGPARAM( ".uno:" ));
198 
199 static sal_Int16 getImageTypeFromBools( sal_Bool bBig, sal_Bool bHighContrast )
200 {
201     sal_Int16 n( 0 );
202     if ( bBig )
203         n |= ::com::sun::star::ui::ImageType::SIZE_LARGE;
204     if ( bHighContrast )
205         n |= ::com::sun::star::ui::ImageType::COLOR_HIGHCONTRAST;
206     return n;
207 }
208 
209 // #110897#
210 MenuBarManager::MenuBarManager(
211 	const Reference< XMultiServiceFactory >& xServiceFactory,
212 	const Reference< XFrame >& rFrame,
213     const Reference< XURLTransformer >& _xURLTransformer,
214     const Reference< XDispatchProvider >& rDispatchProvider,
215     const rtl::OUString& rModuleIdentifier,
216     Menu* pMenu, sal_Bool bDelete, sal_Bool bDeleteChildren )
217 : ThreadHelpBase( &Application::GetSolarMutex() ), OWeakObject()
218     , m_bDisposed( sal_False )
219     , m_bRetrieveImages( sal_False )
220     , m_bAcceleratorCfg( sal_False )
221     , m_bModuleIdentified( sal_False )
222     , m_aListenerContainer( m_aLock.getShareableOslMutex() )
223     , mxServiceFactory(xServiceFactory)
224     , m_xURLTransformer(_xURLTransformer)
225     , m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() )
226 {
227     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MenuBarManager" );
228     m_xPopupMenuControllerRegistration = Reference< ::com::sun::star::frame::XUIControllerRegistration >(
229 		getServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.PopupMenuControllerFactory" ))),
230 		UNO_QUERY );
231 	FillMenuManager( pMenu, rFrame, rDispatchProvider, rModuleIdentifier, bDelete, bDeleteChildren );
232 }
233 
234 // #110897#
235 MenuBarManager::MenuBarManager(
236 	const Reference< XMultiServiceFactory >& xServiceFactory,
237 	const Reference< XFrame >& rFrame,
238     const Reference< XURLTransformer >& _xURLTransformer,
239     AddonMenu* pAddonMenu,
240     sal_Bool bDelete,
241     sal_Bool bDeleteChildren )
242 :   ThreadHelpBase( &Application::GetSolarMutex() )
243     , OWeakObject()
244     , m_bDisposed( sal_False )
245     , m_bRetrieveImages( sal_True )
246     , m_bAcceleratorCfg( sal_False )
247     , m_bModuleIdentified( sal_False )
248     , m_aListenerContainer( m_aLock.getShareableOslMutex() )
249     , mxServiceFactory(xServiceFactory)
250     , m_xURLTransformer(_xURLTransformer)
251     , m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() )
252 {
253     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MenuBarManager" );
254     Init(rFrame,pAddonMenu,bDelete,bDeleteChildren);
255 }
256 
257 // #110897#
258 MenuBarManager::MenuBarManager(
259 	const Reference< XMultiServiceFactory >& xServiceFactory,
260 	const Reference< XFrame >& rFrame,
261     const Reference< XURLTransformer >& _xURLTransformer,
262     AddonPopupMenu* pAddonPopupMenu,
263     sal_Bool bDelete,
264     sal_Bool bDeleteChildren )
265 :     ThreadHelpBase( &Application::GetSolarMutex() )
266     , OWeakObject()
267     , m_bDisposed( sal_False )
268     , m_bRetrieveImages( sal_True )
269     , m_bAcceleratorCfg( sal_False )
270     , m_bModuleIdentified( sal_False )
271     , m_aListenerContainer( m_aLock.getShareableOslMutex() )
272     , mxServiceFactory(xServiceFactory)
273     , m_xURLTransformer(_xURLTransformer)
274     , m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() )
275 {
276     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MenuBarManager" );
277     Init(rFrame,pAddonPopupMenu,bDelete,bDeleteChildren,true);
278 }
279 
280 Any SAL_CALL MenuBarManager::queryInterface( const Type & rType ) throw ( RuntimeException )
281 {
282 	Any a = ::cppu::queryInterface(
283 				rType ,
284 				SAL_STATIC_CAST( ::com::sun::star::frame::XStatusListener*, this ),
285 				SAL_STATIC_CAST( ::com::sun::star::frame::XFrameActionListener*, this ),
286                 SAL_STATIC_CAST( ::com::sun::star::ui::XUIConfigurationListener*, this ),
287 				SAL_STATIC_CAST( XEventListener*, (XStatusListener *)this ),
288 				SAL_STATIC_CAST( XComponent*, this ),
289 				SAL_STATIC_CAST( ::com::sun::star::awt::XSystemDependentMenuPeer*, this ));
290 
291 	if ( a.hasValue() )
292 		return a;
293 
294 	return OWeakObject::queryInterface( rType );
295 }
296 
297 
298 void SAL_CALL MenuBarManager::acquire() throw()
299 {
300     OWeakObject::acquire();
301 }
302 
303 
304 void SAL_CALL MenuBarManager::release() throw()
305 {
306     OWeakObject::release();
307 }
308 
309 
310 Any SAL_CALL MenuBarManager::getMenuHandle( const Sequence< sal_Int8 >& /*ProcessId*/, sal_Int16 SystemType ) throw (RuntimeException)
311 {
312     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::getMenuHandle" );
313 	ResetableGuard aGuard( m_aLock );
314 
315 	if ( m_bDisposed )
316 	    throw com::sun::star::lang::DisposedException();
317 
318     Any a;
319 
320     if ( m_pVCLMenu )
321     {
322         OGuard	aSolarGuard( Application::GetSolarMutex() );
323 
324         SystemMenuData aSystemMenuData;
325         aSystemMenuData.nSize = sizeof( SystemMenuData );
326 
327         m_pVCLMenu->GetSystemMenuData( &aSystemMenuData );
328 #ifdef QUARTZ
329         if( SystemType == SystemDependent::SYSTEM_MAC )
330         {
331         }
332 #elif (defined WNT)
333 		if( SystemType == SystemDependent::SYSTEM_WIN32 )
334 		{
335             a <<= (long) aSystemMenuData.hMenu;
336 		}
337 #elif (defined UNX)
338 		if( SystemType == SystemDependent::SYSTEM_XWINDOW )
339 		{
340 		}
341 #endif
342     }
343 
344     return a;
345 }
346 
347 MenuBarManager::~MenuBarManager()
348 {
349     // stop asynchronous settings timer
350     m_xDeferedItemContainer.clear();
351     m_aAsyncSettingsTimer.Stop();
352 
353     DBG_ASSERT( OWeakObject::m_refCount == 0, "Who wants to delete an object with refcount > 0!" );
354 }
355 
356 void MenuBarManager::Destroy()
357 {
358     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Destroy" );
359     OGuard	aGuard( Application::GetSolarMutex() );
360 
361     if ( !m_bDisposed )
362     {
363         // stop asynchronous settings timer and
364         // release defered item container reference
365         m_aAsyncSettingsTimer.Stop();
366         m_xDeferedItemContainer.clear();
367         RemoveListener();
368 
369         std::vector< MenuItemHandler* >::iterator p;
370 	    for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
371 	    {
372             MenuItemHandler* pItemHandler = *p;
373 		    pItemHandler->xMenuItemDispatch.clear();
374 		    pItemHandler->xSubMenuManager.clear();
375 	        pItemHandler->xPopupMenu.clear();
376 		    delete pItemHandler;
377 	    }
378         m_aMenuItemHandlerVector.clear();
379 
380 	    if ( m_bDeleteMenu )
381         {
382 		    delete m_pVCLMenu;
383             m_pVCLMenu = 0;
384         }
385     }
386 }
387 
388 // XComponent
389 void SAL_CALL MenuBarManager::dispose() throw( RuntimeException )
390 {
391     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::dispose" );
392     Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
393 
394     EventObject aEvent( xThis );
395     m_aListenerContainer.disposeAndClear( aEvent );
396 
397 	{
398 	    ResetableGuard aGuard( m_aLock );
399 //        RemoveListener();
400         Destroy();
401         m_bDisposed = sal_True;
402 
403         if ( m_xDocImageManager.is() )
404         {
405             try
406             {
407                 m_xDocImageManager->removeConfigurationListener(
408                     Reference< XUIConfigurationListener >(
409                         static_cast< OWeakObject* >( this ), UNO_QUERY ));
410             }
411             catch ( Exception& )
412             {
413             }
414         }
415         if ( m_xModuleImageManager.is() )
416         {
417             try
418             {
419                 m_xModuleImageManager->removeConfigurationListener(
420                     Reference< XUIConfigurationListener >(
421                         static_cast< OWeakObject* >( this ), UNO_QUERY ));
422             }
423             catch ( Exception& )
424             {
425             }
426         }
427         m_xDocImageManager.clear();
428         m_xModuleImageManager.clear();
429         m_xGlobalAcceleratorManager.clear();
430         m_xModuleAcceleratorManager.clear();
431         m_xDocAcceleratorManager.clear();
432         m_xUICommandLabels.clear();
433         m_xPopupMenuControllerRegistration.clear();
434         mxServiceFactory.clear();
435     }
436 }
437 
438 void SAL_CALL MenuBarManager::addEventListener( const Reference< XEventListener >& xListener ) throw( RuntimeException )
439 {
440     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::addEventListener" );
441 	ResetableGuard aGuard( m_aLock );
442 
443 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
444     if ( m_bDisposed )
445         throw DisposedException();
446 
447     m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
448 }
449 
450 void SAL_CALL MenuBarManager::removeEventListener( const Reference< XEventListener >& xListener ) throw( RuntimeException )
451 {
452     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::removeEventListener" );
453 	ResetableGuard aGuard( m_aLock );
454 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
455     m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
456 }
457 
458 void SAL_CALL MenuBarManager::elementInserted( const ::com::sun::star::ui::ConfigurationEvent& Event )
459 throw (RuntimeException)
460 {
461     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::elementInserted" );
462 	ResetableGuard aGuard( m_aLock );
463 
464     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
465     if ( m_bDisposed )
466         return;
467 
468     sal_Int16 nImageType = sal_Int16();
469     sal_Int16 nCurrentImageType = getImageTypeFromBools( sal_False, m_bWasHiContrast );
470     if (( Event.aInfo >>= nImageType ) &&
471         ( nImageType == nCurrentImageType ))
472         RequestImages();
473 }
474 
475 void SAL_CALL MenuBarManager::elementRemoved( const ::com::sun::star::ui::ConfigurationEvent& Event )
476 throw (RuntimeException)
477 {
478     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::elementRemoved" );
479 	elementInserted(Event);
480 }
481 
482 void SAL_CALL MenuBarManager::elementReplaced( const ::com::sun::star::ui::ConfigurationEvent& Event )
483 throw (RuntimeException)
484 {
485     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::elementReplaced" );
486 	elementInserted(Event);
487 }
488 
489 // XFrameActionListener
490 void SAL_CALL MenuBarManager::frameAction( const FrameActionEvent& Action )
491 throw ( RuntimeException )
492 {
493     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::frameAction" );
494     ResetableGuard aGuard( m_aLock );
495 
496 	if ( m_bDisposed )
497 	    throw com::sun::star::lang::DisposedException();
498 
499     if ( Action.Action == FrameAction_CONTEXT_CHANGED )
500     {
501         std::vector< MenuItemHandler* >::iterator p;
502 	    for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
503 	    {
504             // Clear dispatch reference as we will requery it later o
505             MenuItemHandler* pItemHandler = *p;
506 		    pItemHandler->xMenuItemDispatch.clear();
507         }
508     }
509 }
510 
511 // XStatusListener
512 void SAL_CALL MenuBarManager::statusChanged( const FeatureStateEvent& Event )
513 throw ( RuntimeException )
514 {
515     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::statusChanged" );
516 	::rtl::OUString aFeatureURL = Event.FeatureURL.Complete;
517 
518     OGuard	aSolarGuard( Application::GetSolarMutex() );
519 	{
520 		ResetableGuard aGuard( m_aLock );
521 
522 		if ( m_bDisposed )
523 		    return;
524 
525         // We have to check all menu entries as there can be identical entries in a popup menu.
526         std::vector< MenuItemHandler* >::iterator p;
527 		for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
528 		{
529 			MenuItemHandler* pMenuItemHandler = *p;
530 			if ( pMenuItemHandler->aMenuItemURL == aFeatureURL )
531 		    {
532 			    sal_Bool            bCheckmark( sal_False );
533 			    sal_Bool            bMenuItemEnabled( m_pVCLMenu->IsItemEnabled( pMenuItemHandler->nItemId ));
534                 sal_Bool            bEnabledItem( Event.IsEnabled );
535                 rtl::OUString       aItemText;
536                 status::Visibility  aVisibilityStatus;
537 
538                 #ifdef UNIX
539                 // #b6673979# enable some slots hardly, because UNIX clipboard does not notify all changes
540                 // Can be removed if follow up task will be fixed directly within applications.
541                 if (
542                     ( pMenuItemHandler->aMenuItemURL.equalsAscii (".uno:Paste"         ) ) ||
543                     ( pMenuItemHandler->aMenuItemURL.equalsAscii (".uno:PasteSpecial"  ) ) ||
544                     ( pMenuItemHandler->aMenuItemURL.equalsAscii (".uno:PasteClipboard") )      // special for draw/impress
545                    )
546                     bEnabledItem = sal_True;
547                 #endif
548 
549                 // Enable/disable item
550 			    if ( bEnabledItem != bMenuItemEnabled )
551 			        m_pVCLMenu->EnableItem( pMenuItemHandler->nItemId, bEnabledItem );
552 
553 			    if ( Event.State >>= bCheckmark )
554                 {
555                     // Checkmark or RadioButton
556                     m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, sal_True );
557                     m_pVCLMenu->CheckItem( pMenuItemHandler->nItemId, bCheckmark );
558 
559                     MenuItemBits nBits = m_pVCLMenu->GetItemBits( pMenuItemHandler->nItemId );
560                     //If not already designated RadioButton set as CheckMark
561                     if (!(nBits & MIB_RADIOCHECK))
562                         m_pVCLMenu->SetItemBits( pMenuItemHandler->nItemId, nBits | MIB_CHECKABLE );
563                 }
564                 else if ( Event.State >>= aItemText )
565                 {
566                     // Replacement for place holders
567                     if ( aItemText.matchAsciiL( "($1)", 4 ))
568                     {
569 					    String aResStr = String( FwkResId( STR_UPDATEDOC ));
570                         rtl::OUString aTmp( aResStr );
571                         aTmp += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
572                         aTmp += aItemText.copy( 4 );
573                         aItemText = aTmp;
574                     }
575                     else if ( aItemText.matchAsciiL( "($2)", 4 ))
576                     {
577 					    String aResStr = String( FwkResId( STR_CLOSEDOC_ANDRETURN ));
578                         rtl::OUString aTmp( aResStr );
579                         aTmp += aItemText.copy( 4 );
580                         aItemText = aTmp;
581                     }
582                     else if ( aItemText.matchAsciiL( "($3)", 4 ))
583                     {
584 					    String aResStr = String( FwkResId( STR_SAVECOPYDOC ));
585                         rtl::OUString aTmp( aResStr );
586                         aTmp += aItemText.copy( 4 );
587                         aItemText = aTmp;
588                     }
589 
590                     m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, sal_True );
591                     m_pVCLMenu->SetItemText( pMenuItemHandler->nItemId, aItemText );
592                 }
593                 else if ( Event.State >>= aVisibilityStatus )
594                 {
595                     // Visibility
596                     m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, aVisibilityStatus.bVisible );
597                 }
598                 else
599                     m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, sal_True );
600 		    }
601 
602 		    if ( Event.Requery )
603 		    {
604                 // Release dispatch object - will be requeried on the next activate!
605                 pMenuItemHandler->xMenuItemDispatch.clear();
606 		    }
607         }
608 	}
609 }
610 
611 // Helper to retrieve own structure from item ID
612 MenuBarManager::MenuItemHandler* MenuBarManager::GetMenuItemHandler( sal_uInt16 nItemId )
613 {
614     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::GetMenuItemHandler" );
615 	ResetableGuard aGuard( m_aLock );
616 
617 	std::vector< MenuItemHandler* >::iterator p;
618 	for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
619 	{
620 		MenuItemHandler* pItemHandler = *p;
621 		if ( pItemHandler->nItemId == nItemId )
622 			return pItemHandler;
623 	}
624 
625 	return 0;
626 }
627 
628 // Helper to set request images flag
629 void MenuBarManager::RequestImages()
630 {
631     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RequestImages" );
632     // must be locked from callee
633 	// ResetableGuard aGuard( m_aLock );
634 
635     m_bRetrieveImages = sal_True;
636     const sal_uInt32 nCount = m_aMenuItemHandlerVector.size();
637     for ( sal_uInt32 i = 0; i < nCount; ++i )
638     {
639 		MenuItemHandler* pItemHandler = m_aMenuItemHandlerVector[i];
640 		if ( pItemHandler->xSubMenuManager.is() )
641         {
642             MenuBarManager* pMenuBarManager = (MenuBarManager*)(pItemHandler->xSubMenuManager.get());
643             pMenuBarManager->RequestImages();
644         }
645 	}
646 }
647 
648 // Helper to reset objects to prepare shutdown
649 void MenuBarManager::RemoveListener()
650 {
651     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RemoveListener" );
652 	ResetableGuard aGuard( m_aLock );
653 
654     // Check service manager reference. Remove listener can be called due
655     // to a disposing call from the frame and therefore we already removed
656     // our listeners and release the service manager reference!
657     Reference< XMultiServiceFactory > xServiceManager = getServiceFactory();
658     if ( xServiceManager.is() )
659     {
660 	    std::vector< MenuItemHandler* >::iterator p;
661 	    for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
662 	    {
663 		    MenuItemHandler* pItemHandler = *p;
664 		    if ( pItemHandler->xMenuItemDispatch.is() )
665 		    {
666 			    URL aTargetURL;
667 			    aTargetURL.Complete	= pItemHandler->aMenuItemURL;
668 			    m_xURLTransformer->parseStrict( aTargetURL );
669 
670 			    pItemHandler->xMenuItemDispatch->removeStatusListener(
671 				    static_cast< XStatusListener* >( this ), aTargetURL );
672 		    }
673 
674 		    pItemHandler->xMenuItemDispatch.clear();
675 		    if ( pItemHandler->xPopupMenu.is() )
676             {
677 		        {
678                     // Remove popup menu from menu structure
679 		            OGuard	aGuard2( Application::GetSolarMutex() );
680                     m_pVCLMenu->SetPopupMenu( pItemHandler->nItemId, 0 );
681                 }
682 
683                 Reference< com::sun::star::lang::XEventListener > xEventListener( pItemHandler->xPopupMenuController, UNO_QUERY );
684                 if ( xEventListener.is() )
685                 {
686                     EventObject aEventObject;
687                     aEventObject.Source = (OWeakObject *)this;
688                     xEventListener->disposing( aEventObject );
689                 }
690 
691                 // We now provide a popup menu controller to external code.
692                 // Therefore the life-time must be explicitly handled via
693                 // dispose!!
694                 try
695                 {
696                     Reference< XComponent > xComponent( pItemHandler->xPopupMenuController, UNO_QUERY );
697                     if ( xComponent.is() )
698                         xComponent->dispose();
699                 }
700                 catch ( RuntimeException& )
701                 {
702                     throw;
703                 }
704                 catch ( Exception& )
705                 {
706                 }
707 
708                 // Release references to controller and popup menu
709                 pItemHandler->xPopupMenuController.clear();
710                 pItemHandler->xPopupMenu.clear();
711             }
712 
713 		    Reference< XComponent > xComponent( pItemHandler->xSubMenuManager, UNO_QUERY );
714 		    if ( xComponent.is() )
715 		        xComponent->dispose();
716 	    }
717     }
718 
719     try
720     {
721         if ( m_xFrame.is() )
722             m_xFrame->removeFrameActionListener( Reference< XFrameActionListener >(
723                                                     static_cast< OWeakObject* >( this ), UNO_QUERY ));
724     }
725     catch ( Exception& )
726     {
727     }
728 
729 	m_xFrame = 0;
730 }
731 
732 void SAL_CALL MenuBarManager::disposing( const EventObject& Source ) throw ( RuntimeException )
733 {
734     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::disposing(evt)" );
735     MenuItemHandler* pMenuItemDisposing = NULL;
736 
737     ResetableGuard aGuard( m_aLock );
738 
739 	std::vector< MenuItemHandler* >::iterator p;
740 	for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
741 	{
742 		MenuItemHandler* pMenuItemHandler = *p;
743 		if ( pMenuItemHandler->xMenuItemDispatch.is() &&
744              pMenuItemHandler->xMenuItemDispatch == Source.Source )
745 		{
746 	        // disposing called from menu item dispatcher, remove listener
747 			pMenuItemDisposing = pMenuItemHandler;
748 			break;
749 		}
750 	}
751 
752     if ( pMenuItemDisposing )
753 	{
754         // Release references to the dispatch object
755 		URL aTargetURL;
756 		aTargetURL.Complete	= pMenuItemDisposing->aMenuItemURL;
757 
758         // Check reference of service manager before we use it. Reference could
759         // be cleared due to RemoveListener call!
760         Reference< XMultiServiceFactory > xServiceManager( getServiceFactory() );
761         if ( xServiceManager.is() )
762         {
763 		    m_xURLTransformer->parseStrict( aTargetURL );
764 
765 		    pMenuItemDisposing->xMenuItemDispatch->removeStatusListener(
766 			    static_cast< XStatusListener* >( this ), aTargetURL );
767 		    pMenuItemDisposing->xMenuItemDispatch = Reference< XDispatch >();
768 		    if ( pMenuItemDisposing->xPopupMenu.is() )
769             {
770                 Reference< com::sun::star::lang::XEventListener > xEventListener( pMenuItemDisposing->xPopupMenuController, UNO_QUERY );
771                 if ( xEventListener.is() )
772                     xEventListener->disposing( Source );
773 
774                 {
775                     // Remove popup menu from menu structure as we release our reference to
776                     // the controller.
777 		            OGuard	aGuard2( Application::GetSolarMutex() );
778                     m_pVCLMenu->SetPopupMenu( pMenuItemDisposing->nItemId, 0 );
779                 }
780 
781                 pMenuItemDisposing->xPopupMenuController.clear();
782                 pMenuItemDisposing->xPopupMenu.clear();
783             }
784         }
785         return;
786 	}
787 	else if ( Source.Source == m_xFrame )
788 	{
789         // Our frame gets disposed. We have to remove all our listeners
790 	    RemoveListener();
791 	}
792     else if ( Source.Source == Reference< XInterface >( m_xDocImageManager, UNO_QUERY ))
793         m_xDocImageManager.clear();
794     else if ( Source.Source == Reference< XInterface >( m_xModuleImageManager, UNO_QUERY ))
795         m_xModuleImageManager.clear();
796 }
797 
798 
799 void MenuBarManager::CheckAndAddMenuExtension( Menu* pMenu )
800 {
801     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::CheckAndAddMenuExtension" );
802     static const char REFERENCECOMMAND_AFTER[]          = ".uno:OnlineRegistrationDlg";
803     static const char REFERENCECOMMAND_BEFORE[]         = ".uno:About";
804 
805     // retrieve menu extension item
806     MenuExtensionItem aMenuItem( GetMenuExtension() );
807     if (( aMenuItem.aURL.getLength() > 0 ) &&
808         ( aMenuItem.aLabel.getLength() > 0 ))
809     {
810         // remove all old window list entries from menu
811         sal_uInt16 nNewItemId( 0 );
812         sal_uInt16 nInsertPos( MENU_APPEND );
813         sal_uInt16 nAfterPos( MENU_APPEND );
814         sal_uInt16 nBeforePos( MENU_APPEND );
815         String     aCommandAfter( String::CreateFromAscii ( REFERENCECOMMAND_AFTER ));
816         String     aCommandBefore( String::CreateFromAscii ( REFERENCECOMMAND_BEFORE ));
817         for ( sal_uInt16 n = 0; n < pMenu->GetItemCount(); n++ )
818         {
819             sal_uInt16 nItemId = pMenu->GetItemId( n );
820             nNewItemId = std::max( nItemId, nNewItemId );
821             if ( pMenu->GetItemCommand( nItemId ) == aCommandAfter )
822                 nAfterPos = n+1;
823             else if ( pMenu->GetItemCommand( nItemId ) == aCommandBefore )
824                 nBeforePos = n;
825         }
826         ++nNewItemId;
827 
828         if ( nAfterPos != MENU_APPEND )
829             nInsertPos = nAfterPos;
830         else if ( nBeforePos != MENU_APPEND )
831             nInsertPos = nBeforePos;
832 
833         pMenu->InsertItem( nNewItemId, aMenuItem.aLabel, 0, nInsertPos );
834         pMenu->SetItemCommand( nNewItemId, aMenuItem.aURL );
835     }
836 }
837 
838 static void lcl_CheckForChildren(Menu* pMenu, sal_uInt16 nItemId)
839 {
840     if (PopupMenu* pThisPopup = pMenu->GetPopupMenu( nItemId ))
841         pMenu->EnableItem( nItemId, pThisPopup->GetItemCount() ? true : false );
842 }
843 
844 //_________________________________________________________________________________________________________________
845 // vcl handler
846 //_________________________________________________________________________________________________________________
847 
848 IMPL_LINK( MenuBarManager, Activate, Menu *, pMenu )
849 {
850     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Activate" );
851 	if ( pMenu == m_pVCLMenu )
852 	{
853 		// set/unset hiding disabled menu entries
854 		sal_Bool bDontHide			 = SvtMenuOptions().IsEntryHidingEnabled();
855 		const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
856 		sal_Bool bShowMenuImages	 = rSettings.GetUseImagesInMenus();
857         sal_Bool bHasDisabledEntries = SvtCommandOptions().HasEntries( SvtCommandOptions::CMDOPTION_DISABLED );
858 
859         ResetableGuard aGuard( m_aLock );
860 
861 		sal_uInt16 nFlag = pMenu->GetMenuFlags();
862 		if ( bDontHide )
863 			nFlag &= ~MENU_FLAG_HIDEDISABLEDENTRIES;
864 		else
865 			nFlag |= MENU_FLAG_HIDEDISABLEDENTRIES;
866 		pMenu->SetMenuFlags( nFlag );
867 
868 		if ( m_bActive )
869 			return 0;
870 
871 		m_bActive = sal_True;
872 
873 		::rtl::OUString aMenuCommand( m_aMenuItemCommand );
874         if ( m_aMenuItemCommand == aSpecialWindowMenu ||
875              m_aMenuItemCommand == aSlotSpecialWindowMenu ||
876 			 aMenuCommand == aSpecialWindowCommand )
877              MenuManager::UpdateSpecialWindowMenu( pMenu,getServiceFactory(),m_aLock );
878 
879 		// Check if some modes have changed so we have to update our menu images
880 		sal_Bool bIsHiContrast = rSettings.GetHighContrastMode();
881 		sal_Int16 nSymbolsStyle = SvtMiscOptions().GetCurrentSymbolsStyle();
882 
883 		if ( m_bRetrieveImages ||
884              m_bWasHiContrast != bIsHiContrast ||
885              bShowMenuImages != m_bShowMenuImages ||
886              nSymbolsStyle != m_nSymbolsStyle )
887 		{
888 			// The mode changed so we have to replace all images
889 			m_bWasHiContrast	= bIsHiContrast;
890 			m_bShowMenuImages	= bShowMenuImages;
891 			m_bRetrieveImages	= sal_False;
892 			m_nSymbolsStyle		= nSymbolsStyle;
893             MenuManager::FillMenuImages(m_xFrame,pMenu,bIsHiContrast,bShowMenuImages);
894 		}
895 
896         // Try to map commands to labels
897         for ( sal_uInt16 nPos = 0; nPos < pMenu->GetItemCount(); nPos++ )
898         {
899             sal_uInt16 nItemId = pMenu->GetItemId( nPos );
900             if (( pMenu->GetItemType( nPos ) != MENUITEM_SEPARATOR ) &&
901                 ( pMenu->GetItemText( nItemId ).Len() == 0 ))
902             {
903                 String aCommand = pMenu->GetItemCommand( nItemId );
904                 if ( aCommand.Len() > 0 )
905                     pMenu->SetItemText( nItemId, RetrieveLabelFromCommand( aCommand ));
906             }
907         }
908 
909         // Try to set accelerator keys
910         {
911             RetrieveShortcuts( m_aMenuItemHandlerVector );
912             std::vector< MenuItemHandler* >::iterator p;
913 		    for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
914 		    {
915 		        MenuItemHandler* pMenuItemHandler = *p;
916 
917                 // Set key code, workaround for hard-coded shortcut F1 mapped to .uno:HelpIndex
918                 // Only non-popup menu items can have a short-cut
919                 if ( pMenuItemHandler->aMenuItemURL == aCmdHelpIndex )
920                 {
921                     KeyCode aKeyCode( KEY_F1 );
922                     pMenu->SetAccelKey( pMenuItemHandler->nItemId, aKeyCode );
923                 }
924                 else if ( pMenu->GetPopupMenu( pMenuItemHandler->nItemId ) == 0 )
925                     pMenu->SetAccelKey( pMenuItemHandler->nItemId, pMenuItemHandler->aKeyCode );
926             }
927         }
928 
929 		URL aTargetURL;
930 
931         // Use provided dispatch provider => fallback to frame as dispatch provider
932         Reference< XDispatchProvider > xDispatchProvider;
933         if ( m_xDispatchProvider.is() )
934             xDispatchProvider = m_xDispatchProvider;
935         else
936             xDispatchProvider = Reference< XDispatchProvider >( m_xFrame, UNO_QUERY );
937 
938 		if ( xDispatchProvider.is() )
939 		{
940             KeyCode             aEmptyKeyCode;
941             SvtCommandOptions   aCmdOptions;
942 			std::vector< MenuItemHandler* >::iterator p;
943 			for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
944 			{
945 				MenuItemHandler* pMenuItemHandler = *p;
946 				if ( pMenuItemHandler )
947                 {
948                     if ( !pMenuItemHandler->xMenuItemDispatch.is() &&
949                          !pMenuItemHandler->xSubMenuManager.is()      )
950                     {
951 					    // There is no dispatch mechanism for the special window list menu items,
952 					    // because they are handled directly through XFrame->activate!!!
953                         // Don't update dispatches for special file menu items.
954 					    if ( !(( pMenuItemHandler->nItemId >= START_ITEMID_WINDOWLIST &&
955 					             pMenuItemHandler->nItemId < END_ITEMID_WINDOWLIST )))
956 					    {
957                             Reference< XDispatch > xMenuItemDispatch;
958 
959                             ::rtl::OUString aItemCommand = pMenu->GetItemCommand( pMenuItemHandler->nItemId );
960 						    if ( !aItemCommand.getLength() )
961 						    {
962 							    aItemCommand = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
963 							    aItemCommand += ::rtl::OUString::valueOf( (sal_Int32)pMenuItemHandler->nItemId );
964 							    pMenu->SetItemCommand( pMenuItemHandler->nItemId, aItemCommand );
965 						    }
966 
967                             aTargetURL.Complete = aItemCommand;
968 
969                             m_xURLTransformer->parseStrict( aTargetURL );
970 
971                             if ( bHasDisabledEntries )
972                             {
973                                 if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aTargetURL.Path ))
974                                     pMenu->HideItem( pMenuItemHandler->nItemId );
975                             }
976 
977 						    if ( m_bIsBookmarkMenu )
978 							    xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, pMenuItemHandler->aTargetFrame, 0 );
979 						    else
980 							    xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
981 
982                             sal_Bool bPopupMenu( sal_False );
983                             if ( !pMenuItemHandler->xPopupMenuController.is() &&
984                                  m_xPopupMenuControllerRegistration->hasController( aItemCommand, rtl::OUString() ))
985                             {
986                                 bPopupMenu = CreatePopupMenuController( pMenuItemHandler );
987                             }
988                             else if ( pMenuItemHandler->xPopupMenuController.is() )
989                             {
990                                 // Force update of popup menu
991                                 pMenuItemHandler->xPopupMenuController->updatePopupMenu();
992                                 bPopupMenu = sal_True;
993 								if (PopupMenu*  pThisPopup = pMenu->GetPopupMenu( pMenuItemHandler->nItemId ))
994                                     pMenu->EnableItem( pMenuItemHandler->nItemId, pThisPopup->GetItemCount() ? true : false );
995                             }
996 
997 							lcl_CheckForChildren(pMenu, pMenuItemHandler->nItemId);
998 
999                             if ( xMenuItemDispatch.is() )
1000 						    {
1001 							    pMenuItemHandler->xMenuItemDispatch = xMenuItemDispatch;
1002 							    pMenuItemHandler->aMenuItemURL		= aTargetURL.Complete;
1003 
1004                                 if ( !bPopupMenu )
1005                                 {
1006                                     // We need only an update to reflect the current state
1007                                     xMenuItemDispatch->addStatusListener( static_cast< XStatusListener* >( this ), aTargetURL );
1008                                     xMenuItemDispatch->removeStatusListener( static_cast< XStatusListener* >( this ), aTargetURL );
1009                                 }
1010 						    }
1011 						    else if ( !bPopupMenu )
1012 							    pMenu->EnableItem( pMenuItemHandler->nItemId, sal_False );
1013 					    }
1014 				    }
1015                     else if ( pMenuItemHandler->xPopupMenuController.is() )
1016                     {
1017                         // Force update of popup menu
1018                         pMenuItemHandler->xPopupMenuController->updatePopupMenu();
1019 						lcl_CheckForChildren(pMenu, pMenuItemHandler->nItemId);
1020                     }
1021                     else if ( pMenuItemHandler->xMenuItemDispatch.is() )
1022                     {
1023                         // We need an update to reflect the current state
1024                         try
1025                         {
1026                             aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
1027                             m_xURLTransformer->parseStrict( aTargetURL );
1028 
1029                             pMenuItemHandler->xMenuItemDispatch->addStatusListener(
1030                                                                     static_cast< XStatusListener* >( this ), aTargetURL );
1031                             pMenuItemHandler->xMenuItemDispatch->removeStatusListener(
1032                                                                     static_cast< XStatusListener* >( this ), aTargetURL );
1033                         }
1034                         catch ( Exception& )
1035                         {
1036                         }
1037                     }
1038                     else if ( pMenuItemHandler->xSubMenuManager.is() )
1039 						lcl_CheckForChildren(pMenu, pMenuItemHandler->nItemId);
1040                 }
1041 			}
1042 		}
1043 	}
1044 
1045 	return 1;
1046 }
1047 
1048 
1049 IMPL_LINK( MenuBarManager, Deactivate, Menu *, pMenu )
1050 {
1051     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Deactivate" );
1052 	if ( pMenu == m_pVCLMenu )
1053     {
1054         m_bActive = sal_False;
1055         if ( pMenu->IsMenuBar() && m_xDeferedItemContainer.is() )
1056         {
1057             // Start timer to handle settings asynchronous
1058             // Changing the menu inside this handler leads to
1059             // a crash under X!
1060             m_aAsyncSettingsTimer.SetTimeoutHdl(LINK(this, MenuBarManager, AsyncSettingsHdl));
1061             m_aAsyncSettingsTimer.SetTimeout(10);
1062             m_aAsyncSettingsTimer.Start();
1063         }
1064     }
1065 
1066 	return 1;
1067 }
1068 
1069 IMPL_LINK( MenuBarManager, AsyncSettingsHdl, Timer*,)
1070 {
1071     OGuard	aGuard( Application::GetSolarMutex() );
1072     Reference< XInterface > xSelfHold(
1073         static_cast< ::cppu::OWeakObject* >( this ), UNO_QUERY_THROW );
1074 
1075     m_aAsyncSettingsTimer.Stop();
1076     if ( !m_bActive && m_xDeferedItemContainer.is() )
1077     {
1078         SetItemContainer( m_xDeferedItemContainer );
1079         m_xDeferedItemContainer.clear();
1080     }
1081 
1082 	return 0;
1083 }
1084 
1085 IMPL_LINK( MenuBarManager, Select, Menu *, pMenu )
1086 {
1087     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Select" );
1088 	URL						aTargetURL;
1089 	Sequence<PropertyValue>	aArgs;
1090 	Reference< XDispatch >	xDispatch;
1091 
1092 	{
1093 		ResetableGuard aGuard( m_aLock );
1094 
1095 		sal_uInt16 nCurItemId = pMenu->GetCurItemId();
1096         sal_uInt16 nCurPos    = pMenu->GetItemPos( nCurItemId );
1097 		if ( pMenu == m_pVCLMenu &&
1098 			 pMenu->GetItemType( nCurPos ) != MENUITEM_SEPARATOR )
1099 		{
1100 			if ( nCurItemId >= START_ITEMID_WINDOWLIST &&
1101 				 nCurItemId <= END_ITEMID_WINDOWLIST )
1102 			{
1103 				// window list menu item selected
1104 
1105 				// #110897#
1106                 // Reference< XFramesSupplier > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( DESKTOP_SERVICE ), UNO_QUERY );
1107                 Reference< XFramesSupplier > xDesktop( getServiceFactory()->createInstance( SERVICENAME_DESKTOP ), UNO_QUERY );
1108 
1109 				if ( xDesktop.is() )
1110 				{
1111 					sal_uInt16 nTaskId = START_ITEMID_WINDOWLIST;
1112                     Reference< XIndexAccess > xList( xDesktop->getFrames(), UNO_QUERY );
1113                     sal_Int32 nCount = xList->getCount();
1114                     for ( sal_Int32 i=0; i<nCount; ++i )
1115 					{
1116                         Reference< XFrame > xFrame;
1117                         xList->getByIndex(i) >>= xFrame;
1118                         if ( xFrame.is() && nTaskId == nCurItemId )
1119 						{
1120                             Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
1121 							pWin->GrabFocus();
1122 							pWin->ToTop( TOTOP_RESTOREWHENMIN );
1123 							break;
1124 						}
1125 
1126 						nTaskId++;
1127 					}
1128 				}
1129 			}
1130 			else
1131 			{
1132 				MenuItemHandler* pMenuItemHandler = GetMenuItemHandler( nCurItemId );
1133 				if ( pMenuItemHandler && pMenuItemHandler->xMenuItemDispatch.is() )
1134 				{
1135 					aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
1136                     m_xURLTransformer->parseStrict( aTargetURL );
1137 
1138                     if ( m_bIsBookmarkMenu )
1139 					{
1140 						// bookmark menu item selected
1141 						aArgs.realloc( 1 );
1142 						aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" ));
1143 						aArgs[0].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SFX_REFERER_USER ));
1144 					}
1145 
1146 					xDispatch = pMenuItemHandler->xMenuItemDispatch;
1147 				}
1148 			}
1149 		}
1150 	}
1151 
1152 	if ( xDispatch.is() )
1153     {
1154         const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1155         if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
1156             UiEventLogHelper(::rtl::OUString::createFromAscii("MenuBarManager")).log(getServiceFactory(), m_xFrame, aTargetURL, aArgs);
1157 		xDispatch->dispatch( aTargetURL, aArgs );
1158         Application::AcquireSolarMutex( nRef );
1159     }
1160 
1161 	return 1;
1162 }
1163 
1164 
1165 IMPL_LINK( MenuBarManager, Highlight, Menu *, EMPTYARG )
1166 {
1167 	return 0;
1168 }
1169 
1170 sal_Bool MenuBarManager::MustBeHidden( PopupMenu* pPopupMenu, const Reference< XURLTransformer >& rTransformer )
1171 {
1172     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MustBeHidden" );
1173     if ( pPopupMenu )
1174     {
1175         URL               aTargetURL;
1176         SvtCommandOptions aCmdOptions;
1177 
1178         sal_uInt16 nCount = pPopupMenu->GetItemCount();
1179         sal_uInt16 nHideCount( 0 );
1180 
1181         for ( sal_uInt16 i = 0; i < nCount; i++ )
1182         {
1183             sal_uInt16 nId = pPopupMenu->GetItemId( i );
1184             if ( nId > 0 )
1185             {
1186                 PopupMenu* pSubPopupMenu = pPopupMenu->GetPopupMenu( nId );
1187                 if ( pSubPopupMenu )
1188                 {
1189                     if ( MustBeHidden( pSubPopupMenu, rTransformer ))
1190                     {
1191                         pPopupMenu->HideItem( nId );
1192                         ++nHideCount;
1193                     }
1194                 }
1195                 else
1196                 {
1197                     aTargetURL.Complete = pPopupMenu->GetItemCommand( nId );
1198                     rTransformer->parseStrict( aTargetURL );
1199 
1200                     if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aTargetURL.Path ))
1201                         ++nHideCount;
1202                 }
1203             }
1204             else
1205                 ++nHideCount;
1206         }
1207 
1208         return ( nCount == nHideCount );
1209     }
1210 
1211     return sal_True;
1212 }
1213 String MenuBarManager::RetrieveLabelFromCommand( const String& aCmdURL )
1214 {
1215     return framework::RetrieveLabelFromCommand(aCmdURL,mxServiceFactory,m_xUICommandLabels,m_xFrame,m_aModuleIdentifier,m_bModuleIdentified,"Label");
1216 }
1217 
1218 
1219 
1220 sal_Bool MenuBarManager::CreatePopupMenuController( MenuItemHandler* pMenuItemHandler )
1221 {
1222     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::CreatePopupMenuController" );
1223     rtl::OUString aItemCommand( pMenuItemHandler->aMenuItemURL );
1224 
1225     // Try instanciate a popup menu controller. It is stored in the menu item handler.
1226     Reference< XMultiComponentFactory > xPopupMenuControllerFactory( m_xPopupMenuControllerRegistration, UNO_QUERY );
1227     if ( xPopupMenuControllerFactory.is() )
1228     {
1229         Sequence< Any > aSeq( 2 );
1230         PropertyValue aPropValue;
1231 
1232         aPropValue.Name         = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleName" ));
1233         aPropValue.Value      <<= m_aModuleIdentifier;
1234         aSeq[0] <<= aPropValue;
1235         aPropValue.Name         = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
1236         aPropValue.Value      <<= m_xFrame;
1237         aSeq[1] <<= aPropValue;
1238 
1239         Reference< XComponentContext > xComponentContext;
1240         Reference< XPropertySet >      xProps( getServiceFactory(), UNO_QUERY );
1241 
1242 		xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>=
1243             xComponentContext;
1244 
1245         Reference< XPopupMenuController > xPopupMenuController(
1246                                                 xPopupMenuControllerFactory->createInstanceWithArgumentsAndContext(
1247                                                     aItemCommand,
1248                                                     aSeq,
1249                                                     xComponentContext ),
1250                                                 UNO_QUERY );
1251 
1252         if ( xPopupMenuController.is() )
1253         {
1254             // Provide our awt popup menu to the popup menu controller
1255             pMenuItemHandler->xPopupMenuController = xPopupMenuController;
1256             xPopupMenuController->setPopupMenu( pMenuItemHandler->xPopupMenu );
1257             return sal_True;
1258         }
1259     }
1260 
1261     return sal_False;
1262 }
1263 
1264 void MenuBarManager::FillMenuManager( Menu* pMenu, const Reference< XFrame >& rFrame, const Reference< XDispatchProvider >& rDispatchProvider, const rtl::OUString& rModuleIdentifier, sal_Bool bDelete, sal_Bool bDeleteChildren )
1265 {
1266     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillMenuManager" );
1267 	m_xFrame			= rFrame;
1268 	m_bActive			= sal_False;
1269 	m_bDeleteMenu		= bDelete;
1270 	m_bDeleteChildren	= bDeleteChildren;
1271 	m_pVCLMenu			= pMenu;
1272 	m_bInitialized		= sal_False;
1273 	m_bIsBookmarkMenu	= sal_False;
1274     m_xDispatchProvider = rDispatchProvider;
1275 
1276 	const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
1277 	m_bWasHiContrast	= rSettings.GetHighContrastMode();
1278 	m_bShowMenuImages	= rSettings.GetUseImagesInMenus();
1279     m_bRetrieveImages   = sal_False;
1280 
1281 	sal_Int32 nAddonsURLPrefixLength = ADDONSPOPUPMENU_URL_PREFIX.getLength();
1282 
1283     // Add root as ui configuration listener
1284     RetrieveImageManagers();
1285 
1286     if ( pMenu->IsMenuBar() && rFrame.is() )
1287 	{
1288         // First merge all addon popup menus into our structure
1289         sal_uInt16 nPos = 0;
1290         for ( nPos = 0; nPos < pMenu->GetItemCount(); nPos++ )
1291         {
1292             sal_uInt16          nItemId  = pMenu->GetItemId( nPos );
1293             ::rtl::OUString aCommand = pMenu->GetItemCommand( nItemId );
1294             if ( nItemId == SID_MDIWINDOWLIST ||
1295                  aCommand == aSpecialWindowCommand )
1296             {
1297 		        // Retrieve addon popup menus and add them to our menu bar
1298 		        Reference< com::sun::star::frame::XModel >		xModel;
1299 		        Reference< com::sun::star::frame::XController >	xController( rFrame->getController(), UNO_QUERY );
1300 		        if ( xController.is() )
1301 			        xModel = Reference< com::sun::star::frame::XModel >( xController->getModel(), UNO_QUERY );
1302 		        framework::AddonMenuManager::MergeAddonPopupMenus( rFrame, xModel, nPos, (MenuBar *)pMenu );
1303                 break;
1304             }
1305         }
1306 
1307         // Merge the Add-Ons help menu items into the Office help menu
1308         framework::AddonMenuManager::MergeAddonHelpMenu( rFrame, (MenuBar *)pMenu );
1309     }
1310 
1311     String      aEmpty;
1312     sal_Bool    bAccessibilityEnabled( Application::GetSettings().GetMiscSettings().GetEnableATToolSupport() );
1313     sal_uInt16 nItemCount = pMenu->GetItemCount();
1314     ::rtl::OUString aItemCommand;
1315     m_aMenuItemHandlerVector.reserve(nItemCount);
1316 	for ( sal_uInt16 i = 0; i < nItemCount; i++ )
1317 	{
1318         sal_uInt16 nItemId = FillItemCommand(aItemCommand,pMenu, i );
1319 
1320         // Set module identifier when provided from outside
1321         if ( rModuleIdentifier.getLength() > 0 )
1322         {
1323             m_aModuleIdentifier = rModuleIdentifier;
1324             m_bModuleIdentified = sal_True;
1325         }
1326 
1327         if (( pMenu->IsMenuBar() || bAccessibilityEnabled ) &&
1328 			( pMenu->GetItemText( nItemId ).Len() == 0 ))
1329         {
1330             if ( aItemCommand.getLength() > 0 )
1331                 pMenu->SetItemText( nItemId, RetrieveLabelFromCommand( aItemCommand ));
1332         }
1333 
1334         Reference< XDispatch > xDispatch;
1335 		Reference< XStatusListener > xStatusListener;
1336 		PopupMenu* pPopup = pMenu->GetPopupMenu( nItemId );
1337         bool bItemShowMenuImages = m_bShowMenuImages;
1338         MenuItemBits nBits =  pMenu->GetItemBits( nItemId );
1339         // overwrite the show icons on menu option?
1340         if ( nBits )
1341             bItemShowMenuImages = ( ( nBits & MIB_ICON ) == MIB_ICON );
1342 		if ( pPopup )
1343 		{
1344             // Retrieve module identifier from Help Command entry
1345             rtl::OUString aModuleIdentifier( rModuleIdentifier );
1346             if ( pMenu->GetHelpCommand( nItemId ).Len() > 0 )
1347             {
1348                 aModuleIdentifier = pMenu->GetHelpCommand( nItemId );
1349                 pMenu->SetHelpCommand( nItemId, aEmpty );
1350             }
1351 
1352             if ( m_xPopupMenuControllerRegistration.is() &&
1353                  pPopup->GetItemCount() == 0 &&
1354                  m_xPopupMenuControllerRegistration->hasController( aItemCommand, rtl::OUString() )
1355                   )
1356             {
1357                 // Check if we have to create a popup menu for a uno based popup menu controller.
1358                 // We have to set an empty popup menu into our menu structure so the controller also
1359                 // works with inplace OLE. Remove old dummy popup menu!
1360                 MenuItemHandler* pItemHandler = new MenuItemHandler( nItemId, xStatusListener, xDispatch );
1361                 VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu;
1362                 PopupMenu* pNewPopupMenu = (PopupMenu *)pVCLXPopupMenu->GetMenu();
1363                 pMenu->SetPopupMenu( nItemId, pNewPopupMenu );
1364                 pItemHandler->xPopupMenu = Reference< com::sun::star::awt::XPopupMenu >( (OWeakObject *)pVCLXPopupMenu, UNO_QUERY );
1365                 pItemHandler->aMenuItemURL = aItemCommand;
1366                 m_aMenuItemHandlerVector.push_back( pItemHandler );
1367                 delete pPopup;
1368 
1369                 if ( bAccessibilityEnabled )
1370                 {
1371                     if ( CreatePopupMenuController( pItemHandler ))
1372                         pItemHandler->xPopupMenuController->updatePopupMenu();
1373                 }
1374 				lcl_CheckForChildren(pMenu, nItemId);
1375             }
1376             else if (( aItemCommand.getLength() > nAddonsURLPrefixLength ) &&
1377 				     ( aItemCommand.indexOf( ADDONSPOPUPMENU_URL_PREFIX ) == 0 ))
1378 			{
1379 				// A special addon popup menu, must be created with a different ctor
1380 				// #110897#
1381                 MenuBarManager* pSubMenuManager = new MenuBarManager( getServiceFactory(), m_xFrame, m_xURLTransformer,(AddonPopupMenu *)pPopup, bDeleteChildren, bDeleteChildren );
1382                 AddMenu(pSubMenuManager,aItemCommand,nItemId);
1383 			}
1384 			else
1385 			{
1386                 Reference< XDispatchProvider > xPopupMenuDispatchProvider( rDispatchProvider );
1387 
1388                 // Retrieve possible attributes struct
1389 				MenuConfiguration::Attributes* pAttributes = (MenuConfiguration::Attributes *)(pMenu->GetUserValue( nItemId ));
1390                 if ( pAttributes )
1391                     xPopupMenuDispatchProvider = pAttributes->xDispatchProvider;
1392 
1393                 // Check if this is the help menu. Add menu item if needed
1394                 if ( nItemId == SID_HELPMENU || aItemCommand == aSlotHelpMenu || aItemCommand == aCmdHelpMenu )
1395                 {
1396                     // Check if this is the help menu. Add menu item if needed
1397                     CheckAndAddMenuExtension( pPopup );
1398                 }
1399                 else if (( nItemId == SID_ADDONLIST || aItemCommand == aSlotSpecialToolsMenu || aItemCommand == aCmdToolsMenu ) &&
1400 					     AddonMenuManager::HasAddonMenuElements() )
1401                 {
1402                     // Create addon popup menu if there exist elements and this is the tools popup menu
1403 					sal_uInt16      nCount   = 0;
1404 					AddonMenu*  pSubMenu = AddonMenuManager::CreateAddonMenu( rFrame );
1405 					if ( pSubMenu && ( pSubMenu->GetItemCount() > 0 ))
1406 					{
1407 						if ( pPopup->GetItemType( nCount-1 ) != MENUITEM_SEPARATOR )
1408 							pPopup->InsertSeparator();
1409 
1410 					    // Use resource to load popup menu title
1411 					    String aAddonsStrRes = String( FwkResId( STR_MENU_ADDONS ));
1412 					    pPopup->InsertItem( ITEMID_ADDONLIST, aAddonsStrRes );
1413 					    pPopup->SetPopupMenu( ITEMID_ADDONLIST, pSubMenu );
1414 
1415 					    // Set item command for popup menu to enable it for GetImageFromURL
1416 						const ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
1417                         ::rtl::OUString aNewItemCommand( aSlotString );
1418 					    aNewItemCommand += ::rtl::OUString::valueOf( (sal_Int32)ITEMID_ADDONLIST );
1419 					    pPopup->SetItemCommand( ITEMID_ADDONLIST, aNewItemCommand );
1420 					}
1421 					else
1422 					    delete pSubMenu;
1423 				}
1424 
1425                 if ( nItemId == ITEMID_ADDONLIST )
1426                 {
1427 			        // Create control structure within the "Tools" sub menu for the Add-Ons popup menu
1428                     // #110897# MenuBarManager* pSubMenuManager = new MenuBarManager( rFrame, pSubMenu, sal_True, sal_False );
1429                     AddonMenu* pSubMenu = dynamic_cast< AddonMenu* >( pPopup );
1430                     if ( pSubMenu )
1431                     {
1432                         MenuBarManager* pSubMenuManager = new MenuBarManager( getServiceFactory(), m_xFrame, m_xURLTransformer,pSubMenu, sal_True, sal_False );
1433                         AddMenu(pSubMenuManager,aItemCommand,nItemId);
1434                         pSubMenuManager->m_aMenuItemCommand = ::rtl::OUString();
1435 
1436 			            // Set image for the addon popup menu item
1437 			            if ( bItemShowMenuImages && !pPopup->GetItemImage( ITEMID_ADDONLIST ))
1438 			            {
1439                             Reference< XFrame > xTemp( rFrame );
1440                             Image aImage = GetImageFromURL( xTemp, aItemCommand, sal_False, m_bWasHiContrast );
1441         		            if ( !!aImage )
1442            			            pPopup->SetItemImage( ITEMID_ADDONLIST, aImage );
1443 			            }
1444                     }
1445                 }
1446                 else
1447                 {
1448                     // #110897# MenuBarManager* pSubMenuManager = new MenuBarManager( rFrame, pPopupMenu, bDeleteChildren, bDeleteChildren );
1449                     MenuBarManager* pSubMenuMgr = new MenuBarManager( getServiceFactory(), rFrame, m_xURLTransformer,rDispatchProvider, aModuleIdentifier, pPopup, bDeleteChildren, bDeleteChildren );
1450                     AddMenu(pSubMenuMgr,aItemCommand,nItemId);
1451                 }
1452 			}
1453 		}
1454         else if ( pMenu->GetItemType( i ) != MENUITEM_SEPARATOR )
1455 		{
1456             if ( bItemShowMenuImages )
1457 			{
1458 			    if ( AddonMenuManager::IsAddonMenuId( nItemId ))
1459 			    {
1460                     // Add-Ons uses images from different places
1461                     Image           aImage;
1462                     rtl::OUString   aImageId;
1463 
1464 					MenuConfiguration::Attributes* pMenuAttributes =
1465 						(MenuConfiguration::Attributes*)pMenu->GetUserValue( nItemId );
1466 
1467 					if ( pMenuAttributes && pMenuAttributes->aImageId.getLength() > 0 )
1468 					{
1469 						// Retrieve image id from menu attributes
1470 						aImage = GetImageFromURL( m_xFrame, aImageId, sal_False, m_bWasHiContrast );
1471                     }
1472 
1473 	                if ( !aImage )
1474 	                {
1475 						aImage = GetImageFromURL( m_xFrame, aItemCommand, sal_False, m_bWasHiContrast );
1476 	                    if ( !aImage )
1477                             aImage = AddonsOptions().GetImageFromURL( aItemCommand, sal_False, m_bWasHiContrast );
1478                     }
1479 
1480 		            if ( !!aImage )
1481 		                pMenu->SetItemImage( nItemId, aImage );
1482                     else
1483                         m_bRetrieveImages = sal_True;
1484 			    }
1485                 m_bRetrieveImages = sal_True;
1486             }
1487 
1488             MenuItemHandler* pItemHandler = new MenuItemHandler( nItemId, xStatusListener, xDispatch );
1489             pItemHandler->aMenuItemURL = aItemCommand;
1490 
1491             if ( m_xPopupMenuControllerRegistration.is() &&
1492                  m_xPopupMenuControllerRegistration->hasController( aItemCommand, rtl::OUString() ))
1493             {
1494                 // Check if we have to create a popup menu for a uno based popup menu controller.
1495                 // We have to set an empty popup menu into our menu structure so the controller also
1496                 // works with inplace OLE.
1497                 VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu;
1498                 PopupMenu* pPopupMenu = (PopupMenu *)pVCLXPopupMenu->GetMenu();
1499                 pMenu->SetPopupMenu( pItemHandler->nItemId, pPopupMenu );
1500                 pItemHandler->xPopupMenu = Reference< com::sun::star::awt::XPopupMenu >( (OWeakObject *)pVCLXPopupMenu, UNO_QUERY );
1501 
1502                 if ( bAccessibilityEnabled && CreatePopupMenuController( pItemHandler ) )
1503                 {
1504                     pItemHandler->xPopupMenuController->updatePopupMenu();
1505 				}
1506 
1507 				lcl_CheckForChildren(pMenu, pItemHandler->nItemId);
1508             }
1509 
1510 			m_aMenuItemHandlerVector.push_back( pItemHandler );
1511 		}
1512 	}
1513 
1514     if ( bAccessibilityEnabled )
1515     {
1516         RetrieveShortcuts( m_aMenuItemHandlerVector );
1517         std::vector< MenuItemHandler* >::iterator p;
1518 		for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
1519 		{
1520 		    MenuItemHandler* pMenuItemHandler = *p;
1521 
1522             // Set key code, workaround for hard-coded shortcut F1 mapped to .uno:HelpIndex
1523             // Only non-popup menu items can have a short-cut
1524             if ( pMenuItemHandler->aMenuItemURL == aCmdHelpIndex )
1525             {
1526                 KeyCode aKeyCode( KEY_F1 );
1527                 pMenu->SetAccelKey( pMenuItemHandler->nItemId, aKeyCode );
1528             }
1529             else if ( pMenu->GetPopupMenu( pMenuItemHandler->nItemId ) == 0 )
1530                 pMenu->SetAccelKey( pMenuItemHandler->nItemId, pMenuItemHandler->aKeyCode );
1531         }
1532     }
1533 
1534     SetHdl();
1535 }
1536 
1537 void MenuBarManager::impl_RetrieveShortcutsFromConfiguration(
1538     const Reference< XAcceleratorConfiguration >& rAccelCfg,
1539     const Sequence< rtl::OUString >& rCommands,
1540     std::vector< MenuItemHandler* >& aMenuShortCuts )
1541 {
1542     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::impl_RetrieveShortcutsFromConfiguration" );
1543     if ( rAccelCfg.is() )
1544     {
1545         try
1546         {
1547             com::sun::star::awt::KeyEvent aKeyEvent;
1548             Sequence< Any > aSeqKeyCode = rAccelCfg->getPreferredKeyEventsForCommandList( rCommands );
1549             for ( sal_Int32 i = 0; i < aSeqKeyCode.getLength(); i++ )
1550             {
1551                 if ( aSeqKeyCode[i] >>= aKeyEvent )
1552                     aMenuShortCuts[i]->aKeyCode = svt::AcceleratorExecute::st_AWTKey2VCLKey( aKeyEvent );
1553             }
1554         }
1555         catch ( IllegalArgumentException& )
1556         {
1557         }
1558     }
1559 }
1560 
1561 void MenuBarManager::RetrieveShortcuts( std::vector< MenuItemHandler* >& aMenuShortCuts )
1562 {
1563     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RetrieveShortcuts" );
1564     if ( !m_bModuleIdentified )
1565     {
1566         m_bModuleIdentified = sal_True;
1567         Reference< XModuleManager > xModuleManager;
1568         xModuleManager = Reference< XModuleManager >( getServiceFactory()->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW );
1569 
1570         try
1571         {
1572             m_aModuleIdentifier = xModuleManager->identify( m_xFrame );
1573         }
1574         catch( Exception& )
1575         {
1576         }
1577     }
1578 
1579     if ( m_bModuleIdentified )
1580     {
1581         Reference< XAcceleratorConfiguration > xDocAccelCfg( m_xDocAcceleratorManager );
1582         Reference< XAcceleratorConfiguration > xModuleAccelCfg( m_xModuleAcceleratorManager );
1583         Reference< XAcceleratorConfiguration > xGlobalAccelCfg( m_xGlobalAcceleratorManager );
1584 
1585         if ( !m_bAcceleratorCfg )
1586         {
1587             // Retrieve references on demand
1588             m_bAcceleratorCfg = sal_True;
1589             if ( !xDocAccelCfg.is() )
1590             {
1591                 Reference< XController > xController = m_xFrame->getController();
1592                 Reference< XModel > xModel;
1593                 if ( xController.is() )
1594                 {
1595                     xModel = xController->getModel();
1596                     if ( xModel.is() )
1597                     {
1598                         Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY );
1599                         if ( xSupplier.is() )
1600                         {
1601                             Reference< XUIConfigurationManager > xDocUICfgMgr( xSupplier->getUIConfigurationManager(), UNO_QUERY );
1602                             if ( xDocUICfgMgr.is() )
1603                             {
1604                                 xDocAccelCfg = Reference< XAcceleratorConfiguration >( xDocUICfgMgr->getShortCutManager(), UNO_QUERY );
1605                                 m_xDocAcceleratorManager = xDocAccelCfg;
1606                             }
1607                         }
1608                     }
1609                 }
1610             }
1611 
1612             if ( !xModuleAccelCfg.is() )
1613             {
1614                 Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier( getServiceFactory()->createInstance(
1615                                                                                             SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ),
1616                                                                                         UNO_QUERY );
1617                 try
1618                 {
1619                     Reference< XUIConfigurationManager > xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier );
1620                     if ( xUICfgMgr.is() )
1621                     {
1622                         xModuleAccelCfg = Reference< XAcceleratorConfiguration >( xUICfgMgr->getShortCutManager(), UNO_QUERY );
1623                         m_xModuleAcceleratorManager = xModuleAccelCfg;
1624                     }
1625                 }
1626                 catch ( RuntimeException& )
1627                 {
1628                     throw;
1629                 }
1630                 catch ( Exception& )
1631                 {
1632                 }
1633             }
1634 
1635             if ( !xGlobalAccelCfg.is() )
1636             {
1637                 xGlobalAccelCfg = Reference< XAcceleratorConfiguration >( getServiceFactory()->createInstance(
1638                                                                             SERVICENAME_GLOBALACCELERATORCONFIGURATION ),
1639                                                                           UNO_QUERY );
1640                 m_xGlobalAcceleratorManager = xGlobalAccelCfg;
1641             }
1642         }
1643 
1644         KeyCode aEmptyKeyCode;
1645         Sequence< rtl::OUString > aSeq( aMenuShortCuts.size() );
1646         const sal_uInt32 nCount = aMenuShortCuts.size();
1647         for ( sal_uInt32 i = 0; i < nCount; ++i )
1648         {
1649             aSeq[i] = aMenuShortCuts[i]->aMenuItemURL;
1650             aMenuShortCuts[i]->aKeyCode = aEmptyKeyCode;
1651         }
1652 
1653         if ( m_xGlobalAcceleratorManager.is() )
1654             impl_RetrieveShortcutsFromConfiguration( xGlobalAccelCfg, aSeq, aMenuShortCuts );
1655         if ( m_xModuleAcceleratorManager.is() )
1656             impl_RetrieveShortcutsFromConfiguration( xModuleAccelCfg, aSeq, aMenuShortCuts );
1657         if ( m_xDocAcceleratorManager.is() )
1658             impl_RetrieveShortcutsFromConfiguration( xGlobalAccelCfg, aSeq, aMenuShortCuts );
1659     }
1660 }
1661 
1662 void MenuBarManager::RetrieveImageManagers()
1663 {
1664     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RetrieveImageManagers" );
1665     if ( !m_xDocImageManager.is() )
1666     {
1667         Reference< XController > xController = m_xFrame->getController();
1668         Reference< XModel > xModel;
1669         if ( xController.is() )
1670         {
1671             xModel = xController->getModel();
1672             if ( xModel.is() )
1673             {
1674                 Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY );
1675                 if ( xSupplier.is() )
1676                 {
1677                     Reference< XUIConfigurationManager > xDocUICfgMgr( xSupplier->getUIConfigurationManager(), UNO_QUERY );
1678                     m_xDocImageManager = Reference< XImageManager >( xDocUICfgMgr->getImageManager(), UNO_QUERY );
1679                     m_xDocImageManager->addConfigurationListener(
1680                                             Reference< XUIConfigurationListener >(
1681                                                 static_cast< OWeakObject* >( this ), UNO_QUERY ));
1682                 }
1683             }
1684         }
1685     }
1686 
1687     Reference< XModuleManager > xModuleManager;
1688     if ( m_aModuleIdentifier.getLength() == 0 )
1689         xModuleManager.set( getServiceFactory()->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW );
1690 
1691     try
1692     {
1693         if ( xModuleManager.is() )
1694             m_aModuleIdentifier = xModuleManager->identify( Reference< XInterface >( m_xFrame, UNO_QUERY ) );
1695     }
1696     catch( Exception& )
1697     {
1698     }
1699 
1700     if ( !m_xModuleImageManager.is() )
1701     {
1702         Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier( getServiceFactory()->createInstance(
1703                                                                                     SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ),
1704                                                                                   UNO_QUERY );
1705         Reference< XUIConfigurationManager > xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier );
1706         m_xModuleImageManager.set( xUICfgMgr->getImageManager(), UNO_QUERY );
1707         m_xModuleImageManager->addConfigurationListener( Reference< XUIConfigurationListener >(
1708                                                             static_cast< OWeakObject* >( this ), UNO_QUERY ));
1709     }
1710 }
1711 
1712 void MenuBarManager::FillMenuWithConfiguration(
1713     sal_uInt16&                             nId,
1714     Menu*                               pMenu,
1715     const ::rtl::OUString&              rModuleIdentifier,
1716     const Reference< XIndexAccess >&    rItemContainer,
1717     const Reference< XURLTransformer >& rTransformer )
1718 {
1719     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillMenuWithConfiguration" );
1720     Reference< XDispatchProvider > xEmptyDispatchProvider;
1721     MenuBarManager::FillMenu( nId, pMenu, rModuleIdentifier, rItemContainer, xEmptyDispatchProvider );
1722 
1723     // Merge add-on menu entries into the menu bar
1724     MenuBarManager::MergeAddonMenus( static_cast< Menu* >( pMenu ),
1725                                      AddonsOptions().GetMergeMenuInstructions(),
1726                                      rModuleIdentifier );
1727 
1728     sal_Bool bHasDisabledEntries = SvtCommandOptions().HasEntries( SvtCommandOptions::CMDOPTION_DISABLED );
1729     if ( bHasDisabledEntries )
1730     {
1731         sal_uInt16 nCount = pMenu->GetItemCount();
1732 	    for ( sal_uInt16 i = 0; i < nCount; i++ )
1733         {
1734             sal_uInt16 nID = pMenu->GetItemId( i );
1735             if ( nID > 0 )
1736             {
1737                 PopupMenu* pPopupMenu = pMenu->GetPopupMenu( nID );
1738                 if ( pPopupMenu )
1739                 {
1740                     if ( MustBeHidden( pPopupMenu, rTransformer ))
1741                         pMenu->HideItem( nId );
1742                 }
1743             }
1744         }
1745     }
1746 }
1747 
1748 void MenuBarManager::FillMenu(
1749     sal_uInt16&                               nId,
1750     Menu*                                 pMenu,
1751     const rtl::OUString&                  rModuleIdentifier,
1752     const Reference< XIndexAccess >&      rItemContainer,
1753     const Reference< XDispatchProvider >& rDispatchProvider )
1754 {
1755     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillMenu" );
1756     // Fill menu bar with container contents
1757     for ( sal_Int32 n = 0; n < rItemContainer->getCount(); n++ )
1758     {
1759         Sequence< PropertyValue >       aProp;
1760         rtl::OUString                   aCommandURL;
1761         rtl::OUString                   aLabel;
1762         rtl::OUString                   aHelpURL;
1763         rtl::OUString                   aModuleIdentifier( rModuleIdentifier );
1764 	    sal_Bool                        bShow(sal_True);
1765 	    sal_Bool                        bEnabled(sal_True);
1766         sal_uInt16                      nType = 0;
1767         Reference< XIndexAccess >       xIndexContainer;
1768         Reference< XDispatchProvider >  xDispatchProvider( rDispatchProvider );
1769         sal_Int16 nStyle = 0;
1770         try
1771         {
1772             if ( rItemContainer->getByIndex( n ) >>= aProp )
1773             {
1774                 for ( int i = 0; i < aProp.getLength(); i++ )
1775                 {
1776                     rtl::OUString aPropName = aProp[i].Name;
1777                     if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_COMMANDURL, LEN_DESCRIPTOR_COMMANDURL ))
1778                         aProp[i].Value >>= aCommandURL;
1779                     else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_HELPURL, LEN_DESCRIPTOR_HELPURL ))
1780                         aProp[i].Value >>= aHelpURL;
1781                     else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_CONTAINER, LEN_DESCRIPTOR_CONTAINER ))
1782                         aProp[i].Value >>= xIndexContainer;
1783                     else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_LABEL, LEN_DESCRIPTOR_LABEL ))
1784                         aProp[i].Value >>= aLabel;
1785                     else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_TYPE, LEN_DESCRIPTOR_TYPE ))
1786                         aProp[i].Value >>= nType;
1787                     else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_MODULEIDENTIFIER, LEN_DESCRIPTOR_MODULEIDENTIFIER ))
1788                         aProp[i].Value >>= aModuleIdentifier;
1789                     else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_DISPATCHPROVIDER, LEN_DESCRIPTOR_DISPATCHPROVIDER ))
1790                         aProp[i].Value >>= xDispatchProvider;
1791                     else if ( aProp[i].Name.equalsAsciiL( ITEM_DESCRIPTOR_STYLE, LEN_DESCRIPTOR_STYLE ))
1792                         aProp[i].Value >>= nStyle;
1793                     else if ( aProp[i].Name.equalsAsciiL( ITEM_DESCRIPTOR_ISVISIBLE, LEN_DESCRIPTOR_ISVISIBLE ))
1794 		                aProp[i].Value >>= bShow;
1795                     else if ( aProp[i].Name.equalsAsciiL( ITEM_DESCRIPTOR_ENABLED, LEN_DESCRIPTOR_ENABLED ))
1796 		                aProp[i].Value >>= bEnabled;
1797                 }
1798 
1799                 if ( nType == ::com::sun::star::ui::ItemType::DEFAULT )
1800                 {
1801                     pMenu->InsertItem( nId, aLabel );
1802                     pMenu->SetItemCommand( nId, aCommandURL );
1803 
1804                     if ( nStyle )
1805                     {
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                         if ( nStyle & ::com::sun::star::ui::ItemStyle::RADIO_CHECK )
1812                            nBits |= MIB_RADIOCHECK;
1813                         pMenu->SetItemBits( nId, nBits );
1814                     }
1815 
1816                     if ( !bShow )
1817 		                pMenu->HideItem( nId );
1818 
1819                     if ( !bEnabled)
1820                         pMenu->EnableItem( nId, sal_False );
1821 
1822                     if ( xIndexContainer.is() )
1823                     {
1824                         PopupMenu* pNewPopupMenu = new PopupMenu;
1825                         pMenu->SetPopupMenu( nId, pNewPopupMenu );
1826 
1827                         if ( xDispatchProvider.is() )
1828                         {
1829 				            // Use attributes struct to transport special dispatch provider
1830                             MenuConfiguration::Attributes* pAttributes = new MenuConfiguration::Attributes;
1831                             pAttributes->xDispatchProvider = xDispatchProvider;
1832                             pMenu->SetUserValue( nId, (sal_uIntPtr)( pAttributes ));
1833                         }
1834 
1835                         // Use help command to transport module identifier
1836                         if ( aModuleIdentifier.getLength() > 0 )
1837                             pMenu->SetHelpCommand( nId, aModuleIdentifier );
1838 
1839                         ++nId;
1840                         FillMenu( nId, pNewPopupMenu, aModuleIdentifier, xIndexContainer, xDispatchProvider );
1841                     }
1842                     else
1843                         ++nId;
1844                 }
1845                 else
1846                 {
1847                     pMenu->InsertSeparator();
1848                     ++nId;
1849                 }
1850             }
1851         }
1852         catch ( IndexOutOfBoundsException& )
1853         {
1854             break;
1855         }
1856     }
1857 }
1858 
1859 void MenuBarManager::MergeAddonMenus(
1860     Menu* pMenuBar,
1861     const MergeMenuInstructionContainer& aMergeInstructionContainer,
1862     const ::rtl::OUString& rModuleIdentifier )
1863 {
1864     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MergeAddonMenus" );
1865     // set start value for the item ID for the new addon menu items
1866     sal_uInt16 nItemId = ADDONMENU_MERGE_ITEMID_START;
1867 
1868     const sal_uInt32 nCount = aMergeInstructionContainer.size();
1869     for ( sal_uInt32 i = 0; i < nCount; i++ )
1870     {
1871         const MergeMenuInstruction& rMergeInstruction = aMergeInstructionContainer[i];
1872 
1873         if ( MenuBarMerger::IsCorrectContext( rMergeInstruction.aMergeContext, rModuleIdentifier ))
1874         {
1875             ::std::vector< ::rtl::OUString > aMergePath;
1876 
1877             // retrieve the merge path from the merge point string
1878             MenuBarMerger::RetrieveReferencePath( rMergeInstruction.aMergePoint, aMergePath );
1879 
1880             // convert the sequence/sequence property value to a more convenient vector<>
1881             AddonMenuContainer aMergeMenuItems;
1882             MenuBarMerger::GetSubMenu( rMergeInstruction.aMergeMenu, aMergeMenuItems );
1883 
1884             // try to find the reference point for our merge operation
1885             Menu* pMenu = pMenuBar;
1886             ReferencePathInfo aResult = MenuBarMerger::FindReferencePath( aMergePath, pMenu );
1887 
1888             if ( aResult.eResult == RP_OK )
1889             {
1890                 // normal merge operation
1891                 MenuBarMerger::ProcessMergeOperation( aResult.pPopupMenu,
1892                                                       aResult.nPos,
1893                                                       nItemId,
1894                                                       rMergeInstruction.aMergeCommand,
1895                                                       rMergeInstruction.aMergeCommandParameter,
1896                                                       rModuleIdentifier,
1897                                                       aMergeMenuItems );
1898             }
1899             else
1900             {
1901                 // fallback
1902                 MenuBarMerger::ProcessFallbackOperation( aResult,
1903                                                          nItemId,
1904                                                          rMergeInstruction.aMergeCommand,
1905                                                          rMergeInstruction.aMergeFallback,
1906                                                          aMergePath,
1907                                                          rModuleIdentifier,
1908                                                          aMergeMenuItems );
1909             }
1910         }
1911     }
1912 }
1913 
1914 void MenuBarManager::SetItemContainer( const Reference< XIndexAccess >& rItemContainer )
1915 {
1916     RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::MenuBarManager::SetItemContainer" );
1917 
1918     ResetableGuard aGuard( m_aLock );
1919 
1920     Reference< XFrame > xFrame = m_xFrame;
1921 
1922     if ( !m_bModuleIdentified )
1923     {
1924         m_bModuleIdentified = sal_True;
1925         Reference< XModuleManager > xModuleManager;
1926         xModuleManager = Reference< XModuleManager >( getServiceFactory()->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW );
1927 
1928         try
1929         {
1930             m_aModuleIdentifier = xModuleManager->identify( xFrame );
1931         }
1932         catch( Exception& )
1933         {
1934         }
1935     }
1936 
1937     // Clear MenuBarManager structures
1938     {
1939         vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
1940 
1941         // Check active state as we cannot change our VCL menu during activation by the user
1942         if ( m_bActive )
1943         {
1944             m_xDeferedItemContainer = rItemContainer;
1945             return;
1946         }
1947 
1948         RemoveListener();
1949 	    std::vector< MenuItemHandler* >::iterator p;
1950 	    for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
1951 	    {
1952 		    MenuItemHandler* pItemHandler = *p;
1953 		    pItemHandler->xMenuItemDispatch.clear();
1954 		    pItemHandler->xSubMenuManager.clear();
1955 		    delete pItemHandler;
1956 	    }
1957         m_aMenuItemHandlerVector.clear();
1958 
1959         // Remove top-level parts
1960 	    m_pVCLMenu->Clear();
1961 
1962         sal_uInt16          nId = 1;
1963 
1964         // Fill menu bar with container contents
1965         FillMenuWithConfiguration( nId, (Menu *)m_pVCLMenu, m_aModuleIdentifier, rItemContainer, m_xURLTransformer );
1966 
1967         // Refill menu manager again
1968         Reference< XDispatchProvider > xDispatchProvider;
1969         FillMenuManager( m_pVCLMenu, xFrame, xDispatchProvider, m_aModuleIdentifier, sal_False, sal_True );
1970 
1971         // add itself as frame action listener
1972         m_xFrame->addFrameActionListener( Reference< XFrameActionListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
1973     }
1974 }
1975 
1976 void MenuBarManager::GetPopupController( PopupControllerCache& rPopupController )
1977 {
1978     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::GetPopupController" );
1979     String aPopupScheme = String::CreateFromAscii( "vnd.sun.star.popup:" );
1980 
1981     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
1982 
1983     std::vector< MenuItemHandler* >::iterator p;
1984     for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
1985     {
1986         MenuItemHandler* pItemHandler = *p;
1987         if ( pItemHandler->xPopupMenuController.is() )
1988         {
1989             Reference< XDispatchProvider > xDispatchProvider( pItemHandler->xPopupMenuController, UNO_QUERY );
1990 
1991             PopupControllerEntry aPopupControllerEntry;
1992             aPopupControllerEntry.m_xDispatchProvider = xDispatchProvider;
1993 
1994             // Just use the main part of the URL for popup menu controllers
1995             sal_Int32     nQueryPart( 0 );
1996             sal_Int32     nSchemePart( 0 );
1997             rtl::OUString aMainURL( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.popup:" ));
1998             rtl::OUString aMenuURL( pItemHandler->aMenuItemURL );
1999 
2000             nSchemePart = aMenuURL.indexOf( ':' );
2001             if (( nSchemePart > 0 ) &&
2002                 ( aMenuURL.getLength() > ( nSchemePart+1 )))
2003             {
2004                 nQueryPart  = aMenuURL.indexOf( '?', nSchemePart );
2005                 if ( nQueryPart > 0 )
2006                     aMainURL += aMenuURL.copy( nSchemePart, nQueryPart-nSchemePart );
2007                 else if ( nQueryPart == -1 )
2008                     aMainURL += aMenuURL.copy( nSchemePart+1 );
2009 
2010                 rPopupController.insert( PopupControllerCache::value_type(
2011                                            aMainURL, aPopupControllerEntry ));
2012             }
2013         }
2014         if ( pItemHandler->xSubMenuManager.is() )
2015         {
2016             MenuBarManager* pMenuBarManager = (MenuBarManager*)(pItemHandler->xSubMenuManager.get());
2017             if ( pMenuBarManager )
2018                 pMenuBarManager->GetPopupController( rPopupController );
2019         }
2020     }
2021 }
2022 
2023 // #110897#
2024 const Reference< XMultiServiceFactory >& MenuBarManager::getServiceFactory()
2025 {
2026 	// #110897#
2027 	return mxServiceFactory;
2028 }
2029 
2030 void MenuBarManager::AddMenu(MenuBarManager* pSubMenuManager,const ::rtl::OUString& _sItemCommand,sal_uInt16 _nItemId)
2031 {
2032     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::AddMenu" );
2033 	Reference< XStatusListener > xSubMenuManager( static_cast< OWeakObject *>( pSubMenuManager ), UNO_QUERY );
2034     m_xFrame->addFrameActionListener( Reference< XFrameActionListener >( xSubMenuManager, UNO_QUERY ));
2035 
2036 	// store menu item command as we later have to know which menu is active (see Activate handler)
2037 	pSubMenuManager->m_aMenuItemCommand = _sItemCommand;
2038     Reference< XDispatch > xDispatch;
2039 	MenuItemHandler* pMenuItemHandler = new MenuItemHandler(
2040 												_nItemId,
2041 												xSubMenuManager,
2042 												xDispatch );
2043     pMenuItemHandler->aMenuItemURL = _sItemCommand;
2044 	m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
2045 }
2046 
2047 sal_uInt16 MenuBarManager::FillItemCommand(::rtl::OUString& _rItemCommand,Menu* _pMenu,sal_uInt16 _nIndex) const
2048 {
2049     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillItemCommand" );
2050     sal_uInt16 nItemId = _pMenu->GetItemId( _nIndex );
2051 
2052 	_rItemCommand = _pMenu->GetItemCommand( nItemId );
2053 	if ( !_rItemCommand.getLength() )
2054 	{
2055         const static ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
2056 		_rItemCommand = aSlotString;
2057 		_rItemCommand += ::rtl::OUString::valueOf( (sal_Int32)nItemId );
2058 		_pMenu->SetItemCommand( nItemId, _rItemCommand );
2059 	}
2060     return nItemId;
2061 }
2062 void MenuBarManager::Init(const Reference< XFrame >& rFrame,AddonMenu* pAddonMenu,sal_Bool bDelete,sal_Bool bDeleteChildren,bool _bHandlePopUp)
2063 {
2064     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Init" );
2065 	m_bActive			= sal_False;
2066 	m_bDeleteMenu		= bDelete;
2067 	m_bDeleteChildren	= bDeleteChildren;
2068 	m_pVCLMenu			= pAddonMenu;
2069 	m_xFrame			= rFrame;
2070 	m_bInitialized		= sal_False;
2071 	m_bIsBookmarkMenu	= sal_True;
2072 
2073     rtl::OUString aModuleIdentifier;
2074     m_xPopupMenuControllerRegistration = Reference< ::com::sun::star::frame::XUIControllerRegistration >(
2075 		getServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.PopupMenuControllerFactory" ))),
2076 		UNO_QUERY );
2077 
2078 	const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
2079 	m_bWasHiContrast	= rSettings.GetHighContrastMode();
2080 
2081     Reference< XStatusListener > xStatusListener;
2082     Reference< XDispatch > xDispatch;
2083 	sal_uInt16 nItemCount = pAddonMenu->GetItemCount();
2084     ::rtl::OUString aItemCommand;
2085     m_aMenuItemHandlerVector.reserve(nItemCount);
2086 	for ( sal_uInt16 i = 0; i < nItemCount; i++ )
2087 	{
2088         sal_uInt16 nItemId = FillItemCommand(aItemCommand,pAddonMenu, i );
2089 
2090 		PopupMenu* pPopupMenu = pAddonMenu->GetPopupMenu( nItemId );
2091 		if ( pPopupMenu )
2092 		{
2093 			// #110897#
2094 			Reference< XDispatchProvider > xDispatchProvider;
2095             MenuBarManager* pSubMenuManager = new MenuBarManager( getServiceFactory(), rFrame, m_xURLTransformer,xDispatchProvider, aModuleIdentifier, pPopupMenu, _bHandlePopUp ? sal_False : bDeleteChildren, _bHandlePopUp ? sal_False : bDeleteChildren );
2096 
2097 		    Reference< XStatusListener > xSubMenuManager( static_cast< OWeakObject *>( pSubMenuManager ), UNO_QUERY );
2098 
2099 		    // store menu item command as we later have to know which menu is active (see Acivate handler)
2100 		    pSubMenuManager->m_aMenuItemCommand = aItemCommand;
2101 
2102 		    MenuItemHandler* pMenuItemHandler = new MenuItemHandler(
2103 													    nItemId,
2104 													    xSubMenuManager,
2105 													    xDispatch );
2106             m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
2107 		}
2108 		else
2109 		{
2110 			if ( pAddonMenu->GetItemType( i ) != MENUITEM_SEPARATOR )
2111 			{
2112 				MenuConfiguration::Attributes* pAddonAttributes = (MenuConfiguration::Attributes *)(pAddonMenu->GetUserValue( nItemId ));
2113 				MenuItemHandler* pMenuItemHandler = new MenuItemHandler( nItemId, xStatusListener, xDispatch );
2114 
2115 				if ( pAddonAttributes )
2116 				{
2117 					// read additional attributes from attributes struct and AddonMenu implementation will delete all attributes itself!!
2118 					pMenuItemHandler->aTargetFrame = pAddonAttributes->aTargetFrame;
2119 				}
2120 
2121                 pMenuItemHandler->aMenuItemURL = aItemCommand;
2122                 if ( _bHandlePopUp )
2123                 {
2124                     // Check if we have to create a popup menu for a uno based popup menu controller.
2125                     // We have to set an empty popup menu into our menu structure so the controller also
2126                     // works with inplace OLE.
2127                     if ( m_xPopupMenuControllerRegistration.is() &&
2128                         m_xPopupMenuControllerRegistration->hasController( aItemCommand, rtl::OUString() ))
2129                     {
2130                         VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu;
2131                         PopupMenu* pCtlPopupMenu = (PopupMenu *)pVCLXPopupMenu->GetMenu();
2132                         pAddonMenu->SetPopupMenu( pMenuItemHandler->nItemId, pCtlPopupMenu );
2133                         pMenuItemHandler->xPopupMenu = Reference< com::sun::star::awt::XPopupMenu >( (OWeakObject *)pVCLXPopupMenu, UNO_QUERY );
2134 
2135                     }
2136                 }
2137 				m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
2138 			}
2139 		}
2140 	}
2141 
2142 	SetHdl();
2143 }
2144 
2145 void MenuBarManager::SetHdl()
2146 {
2147 	m_pVCLMenu->SetHighlightHdl( LINK( this, MenuBarManager, Highlight ));
2148 	m_pVCLMenu->SetActivateHdl( LINK( this, MenuBarManager, Activate ));
2149 	m_pVCLMenu->SetDeactivateHdl( LINK( this, MenuBarManager, Deactivate ));
2150 	m_pVCLMenu->SetSelectHdl( LINK( this, MenuBarManager, Select ));
2151 
2152     if ( !m_xURLTransformer.is() && mxServiceFactory.is() )
2153         m_xURLTransformer.set( mxServiceFactory->createInstance(
2154                                                                 SERVICENAME_URLTRANSFORMER),
2155                                                              UNO_QUERY );
2156 }
2157 
2158 }
2159