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