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