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