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