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