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