fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / framework / source / uielement / menubarmanager.cxx
blob9e360738bcc8e3cd088321896fff817fc4ad39c9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <uielement/menubarmanager.hxx>
21 #include <framework/menuconfiguration.hxx>
22 #include <framework/bmkmenu.hxx>
23 #include <framework/addonmenu.hxx>
24 #include <framework/imageproducer.hxx>
25 #include <framework/addonsoptions.hxx>
26 #include <classes/fwkresid.hxx>
27 #include <classes/menumanager.hxx>
28 #include <helper/mischelper.hxx>
29 #include <framework/menuextensionsupplier.hxx>
30 #include <classes/resource.hrc>
31 #include <services.h>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/frame/XDispatch.hpp>
35 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
36 #include <com/sun/star/lang/DisposedException.hpp>
37 #include <com/sun/star/frame/XFramesSupplier.hpp>
38 #include <com/sun/star/frame/Desktop.hpp>
39 #include <com/sun/star/container/XEnumeration.hpp>
40 #include <com/sun/star/util/XStringWidth.hpp>
41 #include <com/sun/star/uno/XComponentContext.hpp>
42 #include <com/sun/star/uno/XCurrentContext.hpp>
43 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
44 #include <com/sun/star/frame/XPopupMenuController.hpp>
45 #include <com/sun/star/frame/thePopupMenuControllerFactory.hpp>
46 #include <com/sun/star/lang/SystemDependent.hpp>
47 #include <com/sun/star/ui/GlobalAcceleratorConfiguration.hpp>
48 #include <com/sun/star/ui/ItemType.hpp>
49 #include <com/sun/star/ui/ImageType.hpp>
50 #include <com/sun/star/container/XNameAccess.hpp>
51 #include <com/sun/star/frame/ModuleManager.hpp>
52 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
53 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
54 #include <com/sun/star/ui/ItemStyle.hpp>
55 #include <com/sun/star/frame/status/Visibility.hpp>
56 #include <com/sun/star/util/URLTransformer.hpp>
58 #include <comphelper/processfactory.hxx>
59 #include <comphelper/extract.hxx>
60 #include <svtools/menuoptions.hxx>
61 #include <svtools/javainteractionhandler.hxx>
62 #include <uno/current_context.hxx>
63 #include <unotools/historyoptions.hxx>
64 #include <unotools/pathoptions.hxx>
65 #include <unotools/cmdoptions.hxx>
66 #include <unotools/localfilehelper.hxx>
67 #include <toolkit/helper/vclunohelper.hxx>
68 #include <vcl/svapp.hxx>
69 #include <vcl/window.hxx>
70 #include <vcl/menu.hxx>
71 #include <vcl/settings.hxx>
72 #include <osl/mutex.hxx>
73 #include <osl/file.hxx>
74 #include <cppuhelper/implbase1.hxx>
75 #include <cppuhelper/queryinterface.hxx>
76 #include <svtools/acceleratorexecute.hxx>
77 #include <svtools/miscopt.hxx>
78 #include <uielement/menubarmerger.hxx>
79 #include <tools/urlobj.hxx>
81 // Be careful removing this "bad" construct. There are serious problems
82 // with #define STRICT and including windows.h. Changing this needs some
83 // redesign on other projects, too. Especially sal/main.h which defines
84 // HINSTANCE depending on STRICT!!!!!!!!!!!!!!!
85 struct SystemMenuData
87 unsigned long nSize;
88 long hMenu;
91 using namespace ::cppu;
92 using namespace ::com::sun::star;
93 using namespace ::com::sun::star::uno;
94 using namespace ::com::sun::star::util;
95 using namespace ::com::sun::star::beans;
96 using namespace ::com::sun::star::frame;
97 using namespace ::com::sun::star::container;
98 using namespace ::com::sun::star::lang;
99 using namespace ::com::sun::star::ui;
101 const sal_uInt16 ADDONMENU_MERGE_ITEMID_START = 1500;
103 namespace framework
106 // special menu ids/command ids for dynamic popup menus
107 #define SID_SFX_START 5000
108 #define SID_MDIWINDOWLIST (SID_SFX_START + 610)
109 #define SID_ADDONLIST (SID_SFX_START + 1677)
110 #define SID_HELPMENU (SID_SFX_START + 410)
112 #define aCmdHelpIndex ".uno:HelpIndex"
113 #define aCmdToolsMenu ".uno:ToolsMenu"
114 #define aCmdHelpMenu ".uno:HelpMenu"
115 #define aSlotHelpMenu "slot:5410"
117 #define aSpecialWindowMenu "window"
118 #define aSlotSpecialWindowMenu "slot:5610"
119 #define aSlotSpecialToolsMenu "slot:6677"
121 // special uno commands for window list
122 #define aSpecialWindowCommand ".uno:WindowList"
124 static sal_Int16 getImageTypeFromBools( bool bBig )
126 sal_Int16 n( 0 );
127 if ( bBig )
128 n |= ::com::sun::star::ui::ImageType::SIZE_LARGE;
129 return n;
132 MenuBarManager::MenuBarManager(
133 const Reference< XComponentContext >& rxContext,
134 const Reference< XFrame >& rFrame,
135 const Reference< XURLTransformer >& _xURLTransformer,
136 const Reference< XDispatchProvider >& rDispatchProvider,
137 const OUString& rModuleIdentifier,
138 Menu* pMenu, bool bDelete, bool bDeleteChildren ):
139 OWeakObject()
140 , m_bDisposed( false )
141 , m_bRetrieveImages( false )
142 , m_bAcceleratorCfg( false )
143 , m_bModuleIdentified( false )
144 , m_aListenerContainer( m_mutex )
145 , m_xContext(rxContext)
146 , m_xURLTransformer(_xURLTransformer)
147 , m_sIconTheme( SvtMiscOptions().GetIconTheme() )
149 m_xPopupMenuControllerFactory = frame::thePopupMenuControllerFactory::get(m_xContext);
150 FillMenuManager( pMenu, rFrame, rDispatchProvider, rModuleIdentifier, bDelete, bDeleteChildren );
153 MenuBarManager::MenuBarManager(
154 const Reference< XComponentContext >& rxContext,
155 const Reference< XFrame >& rFrame,
156 const Reference< XURLTransformer >& _xURLTransformer,
157 Menu* pAddonMenu,
158 bool bDelete,
159 bool bDeleteChildren,
160 bool popup):
161 OWeakObject()
162 , m_bDisposed( false )
163 , m_bRetrieveImages( true )
164 , m_bAcceleratorCfg( false )
165 , m_bModuleIdentified( false )
166 , m_aListenerContainer( m_mutex )
167 , m_xContext(rxContext)
168 , m_xURLTransformer(_xURLTransformer)
169 , m_sIconTheme( SvtMiscOptions().GetIconTheme() )
171 Init(rFrame,pAddonMenu,bDelete,bDeleteChildren, popup);
174 Any SAL_CALL MenuBarManager::queryInterface( const Type & rType ) throw ( RuntimeException, std::exception )
176 Any a = ::cppu::queryInterface(
177 rType ,
178 (static_cast< ::com::sun::star::frame::XStatusListener* >(this)),
179 (static_cast< ::com::sun::star::frame::XFrameActionListener* >(this)),
180 (static_cast< ::com::sun::star::ui::XUIConfigurationListener* >(this)),
181 (static_cast< XEventListener* >((XStatusListener *)this)),
182 (static_cast< XComponent* >(this)),
183 (static_cast< ::com::sun::star::awt::XSystemDependentMenuPeer* >(this)));
185 if ( a.hasValue() )
186 return a;
188 return OWeakObject::queryInterface( rType );
191 void SAL_CALL MenuBarManager::acquire() throw()
193 OWeakObject::acquire();
196 void SAL_CALL MenuBarManager::release() throw()
198 OWeakObject::release();
201 Any SAL_CALL MenuBarManager::getMenuHandle( const Sequence< sal_Int8 >& /*ProcessId*/, sal_Int16 SystemType ) throw (RuntimeException, std::exception)
203 SolarMutexGuard aSolarGuard;
205 if ( m_bDisposed )
206 throw com::sun::star::lang::DisposedException();
208 Any a;
210 if ( m_pVCLMenu )
212 SystemMenuData aSystemMenuData;
213 aSystemMenuData.nSize = sizeof( SystemMenuData );
215 m_pVCLMenu->GetSystemMenuData( &aSystemMenuData );
216 #ifdef _WIN32
217 if( SystemType == SystemDependent::SYSTEM_WIN32 )
219 a <<= (long) aSystemMenuData.hMenu;
221 #else
222 (void) SystemType;
223 #endif
226 return a;
229 MenuBarManager::~MenuBarManager()
231 // stop asynchronous settings timer
232 m_xDeferedItemContainer.clear();
233 m_aAsyncSettingsTimer.Stop();
235 DBG_ASSERT( OWeakObject::m_refCount == 0, "Who wants to delete an object with refcount > 0!" );
238 void MenuBarManager::Destroy()
240 SolarMutexGuard aGuard;
242 if ( !m_bDisposed )
244 // stop asynchronous settings timer and
245 // release defered item container reference
246 m_aAsyncSettingsTimer.Stop();
247 m_xDeferedItemContainer.clear();
248 RemoveListener();
250 std::vector< MenuItemHandler* >::iterator p;
251 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
253 MenuItemHandler* pItemHandler = *p;
254 pItemHandler->xMenuItemDispatch.clear();
255 pItemHandler->xSubMenuManager.clear();
256 pItemHandler->xPopupMenu.clear();
257 delete pItemHandler;
259 m_aMenuItemHandlerVector.clear();
261 if ( m_bDeleteMenu )
263 delete m_pVCLMenu;
264 m_pVCLMenu = 0;
269 // XComponent
270 void SAL_CALL MenuBarManager::dispose() throw( RuntimeException, std::exception )
272 Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
274 EventObject aEvent( xThis );
275 m_aListenerContainer.disposeAndClear( aEvent );
278 SolarMutexGuard g;
279 Destroy();
280 m_bDisposed = true;
282 if ( m_xDocImageManager.is() )
286 m_xDocImageManager->removeConfigurationListener(
287 Reference< XUIConfigurationListener >(
288 static_cast< OWeakObject* >( this ), UNO_QUERY ));
290 catch ( const Exception& )
294 if ( m_xModuleImageManager.is() )
298 m_xModuleImageManager->removeConfigurationListener(
299 Reference< XUIConfigurationListener >(
300 static_cast< OWeakObject* >( this ), UNO_QUERY ));
302 catch ( const Exception& )
306 m_xDocImageManager.clear();
307 m_xModuleImageManager.clear();
308 Reference< XComponent > xCompGAM( m_xGlobalAcceleratorManager, UNO_QUERY );
309 if ( xCompGAM.is() )
310 xCompGAM->dispose();
311 m_xGlobalAcceleratorManager.clear();
312 m_xModuleAcceleratorManager.clear();
313 m_xDocAcceleratorManager.clear();
314 m_xUICommandLabels.clear();
315 m_xPopupMenuControllerFactory.clear();
316 m_xContext.clear();
320 void SAL_CALL MenuBarManager::addEventListener( const Reference< XEventListener >& xListener ) throw( RuntimeException, std::exception )
322 SolarMutexGuard g;
324 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
325 if ( m_bDisposed )
326 throw DisposedException();
328 m_aListenerContainer.addInterface( cppu::UnoType<XEventListener>::get(), xListener );
331 void SAL_CALL MenuBarManager::removeEventListener( const Reference< XEventListener >& xListener ) throw( RuntimeException, std::exception )
333 SolarMutexGuard g;
334 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
335 m_aListenerContainer.removeInterface( cppu::UnoType<XEventListener>::get(), xListener );
338 void SAL_CALL MenuBarManager::elementInserted( const ::com::sun::star::ui::ConfigurationEvent& Event )
339 throw (RuntimeException, std::exception)
341 SolarMutexGuard g;
343 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
344 if ( m_bDisposed )
345 return;
347 sal_Int16 nImageType = sal_Int16();
348 sal_Int16 nCurrentImageType = getImageTypeFromBools( false );
349 if (( Event.aInfo >>= nImageType ) &&
350 ( nImageType == nCurrentImageType ))
351 RequestImages();
354 void SAL_CALL MenuBarManager::elementRemoved( const ::com::sun::star::ui::ConfigurationEvent& Event )
355 throw (RuntimeException, std::exception)
357 elementInserted(Event);
360 void SAL_CALL MenuBarManager::elementReplaced( const ::com::sun::star::ui::ConfigurationEvent& Event )
361 throw (RuntimeException, std::exception)
363 elementInserted(Event);
366 // XFrameActionListener
367 void SAL_CALL MenuBarManager::frameAction( const FrameActionEvent& Action )
368 throw ( RuntimeException, std::exception )
370 SolarMutexGuard g;
372 if ( m_bDisposed )
373 throw com::sun::star::lang::DisposedException();
375 if ( Action.Action == FrameAction_CONTEXT_CHANGED )
377 std::vector< MenuItemHandler* >::iterator p;
378 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
380 // Clear dispatch reference as we will requery it later o
381 MenuItemHandler* pItemHandler = *p;
382 pItemHandler->xMenuItemDispatch.clear();
387 // XStatusListener
388 void SAL_CALL MenuBarManager::statusChanged( const FeatureStateEvent& Event )
389 throw ( RuntimeException, std::exception )
391 OUString aFeatureURL = Event.FeatureURL.Complete;
393 SolarMutexGuard aSolarGuard;
395 vcl::MenuInvalidator::Invalidated();
398 if ( m_bDisposed )
399 return;
401 // We have to check all menu entries as there can be identical entries in a popup menu.
402 std::vector< MenuItemHandler* >::iterator p;
403 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
405 MenuItemHandler* pMenuItemHandler = *p;
406 if ( pMenuItemHandler->aMenuItemURL == aFeatureURL )
408 bool bCheckmark( false );
409 bool bMenuItemEnabled( m_pVCLMenu->IsItemEnabled( pMenuItemHandler->nItemId ));
410 bool bEnabledItem( Event.IsEnabled );
411 OUString aItemText;
412 status::Visibility aVisibilityStatus;
414 #ifdef UNIX
415 //enable some slots hardly, because UNIX clipboard does not notify all changes
416 // Can be removed if follow up task will be fixed directly within applications.
417 // Note: PasteSpecial is handled specifically by calc
418 if ( pMenuItemHandler->aMenuItemURL == ".uno:Paste"
419 || pMenuItemHandler->aMenuItemURL == ".uno:PasteClipboard" ) // special for draw/impress
420 bEnabledItem = true;
421 #endif
423 // Enable/disable item
424 if ( bEnabledItem != bMenuItemEnabled )
425 m_pVCLMenu->EnableItem( pMenuItemHandler->nItemId, bEnabledItem );
427 if ( Event.State >>= bCheckmark )
429 // Checkmark or RadioButton
430 m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, true );
431 m_pVCLMenu->CheckItem( pMenuItemHandler->nItemId, bCheckmark );
433 MenuItemBits nBits = m_pVCLMenu->GetItemBits( pMenuItemHandler->nItemId );
434 //If not already designated RadioButton set as CheckMark
435 if (!(nBits & MenuItemBits::RADIOCHECK))
436 m_pVCLMenu->SetItemBits( pMenuItemHandler->nItemId, nBits | MenuItemBits::CHECKABLE );
438 else if ( Event.State >>= aItemText )
440 INetURLObject aURL( aFeatureURL );
441 OUString aEnumPart = aURL.GetURLPath().getToken( 1, '.' );
442 if ( !aEnumPart.isEmpty() && aURL.GetProtocol() == INetProtocol::Uno )
444 // Checkmark or RadioButton
445 m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, true );
446 m_pVCLMenu->CheckItem( pMenuItemHandler->nItemId, aItemText == aEnumPart );
448 MenuItemBits nBits = m_pVCLMenu->GetItemBits( pMenuItemHandler->nItemId );
449 //If not already designated RadioButton set as CheckMark
450 if (!(nBits & MenuItemBits::RADIOCHECK))
451 m_pVCLMenu->SetItemBits( pMenuItemHandler->nItemId, nBits | MenuItemBits::CHECKABLE );
453 else
455 // Replacement for place holders
456 if ( aItemText.startsWith("($1)") )
458 OUString aTmp(FWK_RESSTR(STR_UPDATEDOC));
459 aTmp += " ";
460 aTmp += aItemText.copy( 4 );
461 aItemText = aTmp;
463 else if ( aItemText.startsWith("($2)") )
465 OUString aTmp(FWK_RESSTR(STR_CLOSEDOC_ANDRETURN));
466 aTmp += aItemText.copy( 4 );
467 aItemText = aTmp;
469 else if ( aItemText.startsWith("($3)") )
471 OUString aTmp(FWK_RESSTR(STR_SAVECOPYDOC));
472 aTmp += aItemText.copy( 4 );
473 aItemText = aTmp;
476 m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, true );
477 m_pVCLMenu->SetItemText( pMenuItemHandler->nItemId, aItemText );
480 else if ( Event.State >>= aVisibilityStatus )
482 // Visibility
483 m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, aVisibilityStatus.bVisible );
485 else
486 m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, true );
489 if ( Event.Requery )
491 // Release dispatch object - will be requeried on the next activate!
492 pMenuItemHandler->xMenuItemDispatch.clear();
498 // Helper to retrieve own structure from item ID
499 MenuBarManager::MenuItemHandler* MenuBarManager::GetMenuItemHandler( sal_uInt16 nItemId )
501 SolarMutexGuard g;
503 std::vector< MenuItemHandler* >::iterator p;
504 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
506 MenuItemHandler* pItemHandler = *p;
507 if ( pItemHandler->nItemId == nItemId )
508 return pItemHandler;
511 return 0;
514 // Helper to set request images flag
515 void MenuBarManager::RequestImages()
518 m_bRetrieveImages = true;
519 const sal_uInt32 nCount = m_aMenuItemHandlerVector.size();
520 for ( sal_uInt32 i = 0; i < nCount; ++i )
522 MenuItemHandler* pItemHandler = m_aMenuItemHandlerVector[i];
523 if ( pItemHandler->xSubMenuManager.is() )
525 MenuBarManager* pMenuBarManager = static_cast<MenuBarManager*>(pItemHandler->xSubMenuManager.get());
526 pMenuBarManager->RequestImages();
531 // Helper to reset objects to prepare shutdown
532 void MenuBarManager::RemoveListener()
534 SolarMutexGuard g;
536 // Check service manager reference. Remove listener can be called due
537 // to a disposing call from the frame and therefore we already removed
538 // our listeners and release the service manager reference!
539 if ( m_xContext.is() )
541 std::vector< MenuItemHandler* >::iterator p;
542 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
544 MenuItemHandler* pItemHandler = *p;
545 if ( pItemHandler->xMenuItemDispatch.is() )
547 URL aTargetURL;
548 aTargetURL.Complete = pItemHandler->aMenuItemURL;
549 m_xURLTransformer->parseStrict( aTargetURL );
551 pItemHandler->xMenuItemDispatch->removeStatusListener(
552 static_cast< XStatusListener* >( this ), aTargetURL );
555 pItemHandler->xMenuItemDispatch.clear();
556 if ( pItemHandler->xPopupMenu.is() )
559 // Remove popup menu from menu structure
560 m_pVCLMenu->SetPopupMenu( pItemHandler->nItemId, 0 );
563 Reference< com::sun::star::lang::XEventListener > xEventListener( pItemHandler->xPopupMenuController, UNO_QUERY );
564 if ( xEventListener.is() )
566 EventObject aEventObject;
567 aEventObject.Source = (OWeakObject *)this;
568 xEventListener->disposing( aEventObject );
571 // We now provide a popup menu controller to external code.
572 // Therefore the life-time must be explicitly handled via
573 // dispose!!
576 Reference< XComponent > xComponent( pItemHandler->xPopupMenuController, UNO_QUERY );
577 if ( xComponent.is() )
578 xComponent->dispose();
580 catch ( const RuntimeException& )
582 throw;
584 catch ( const Exception& )
588 // Release references to controller and popup menu
589 pItemHandler->xPopupMenuController.clear();
590 pItemHandler->xPopupMenu.clear();
593 Reference< XComponent > xComponent( pItemHandler->xSubMenuManager, UNO_QUERY );
594 if ( xComponent.is() )
595 xComponent->dispose();
601 if ( m_xFrame.is() )
602 m_xFrame->removeFrameActionListener( Reference< XFrameActionListener >(
603 static_cast< OWeakObject* >( this ), UNO_QUERY ));
605 catch ( const Exception& )
609 m_xFrame = 0;
612 void SAL_CALL MenuBarManager::disposing( const EventObject& Source ) throw ( RuntimeException, std::exception )
614 MenuItemHandler* pMenuItemDisposing = NULL;
616 SolarMutexGuard g;
618 std::vector< MenuItemHandler* >::iterator p;
619 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
621 MenuItemHandler* pMenuItemHandler = *p;
622 if ( pMenuItemHandler->xMenuItemDispatch.is() &&
623 pMenuItemHandler->xMenuItemDispatch == Source.Source )
625 // disposing called from menu item dispatcher, remove listener
626 pMenuItemDisposing = pMenuItemHandler;
627 break;
631 if ( pMenuItemDisposing )
633 // Release references to the dispatch object
634 URL aTargetURL;
635 aTargetURL.Complete = pMenuItemDisposing->aMenuItemURL;
637 // Check reference of service manager before we use it. Reference could
638 // be cleared due to RemoveListener call!
639 if ( m_xContext.is() )
641 m_xURLTransformer->parseStrict( aTargetURL );
643 pMenuItemDisposing->xMenuItemDispatch->removeStatusListener(
644 static_cast< XStatusListener* >( this ), aTargetURL );
645 pMenuItemDisposing->xMenuItemDispatch.clear();
646 if ( pMenuItemDisposing->xPopupMenu.is() )
648 Reference< com::sun::star::lang::XEventListener > xEventListener( pMenuItemDisposing->xPopupMenuController, UNO_QUERY );
649 if ( xEventListener.is() )
650 xEventListener->disposing( Source );
653 // Remove popup menu from menu structure as we release our reference to
654 // the controller.
655 m_pVCLMenu->SetPopupMenu( pMenuItemDisposing->nItemId, 0 );
658 pMenuItemDisposing->xPopupMenuController.clear();
659 pMenuItemDisposing->xPopupMenu.clear();
662 return;
664 else if ( Source.Source == m_xFrame )
666 // Our frame gets disposed. We have to remove all our listeners
667 RemoveListener();
669 else if ( Source.Source == Reference< XInterface >( m_xDocImageManager, UNO_QUERY ))
670 m_xDocImageManager.clear();
671 else if ( Source.Source == Reference< XInterface >( m_xModuleImageManager, UNO_QUERY ))
672 m_xModuleImageManager.clear();
675 void MenuBarManager::CheckAndAddMenuExtension( Menu* pMenu )
678 // retrieve menu extension item
679 MenuExtensionItem aMenuItem( GetMenuExtension() );
680 if (( !aMenuItem.aURL.isEmpty() ) &&
681 ( !aMenuItem.aLabel.isEmpty() ))
683 // remove all old window list entries from menu
684 sal_uInt16 nNewItemId( 0 );
685 sal_uInt16 nInsertPos( MENU_APPEND );
686 sal_uInt16 nBeforePos( MENU_APPEND );
687 OUString aCommandBefore( ".uno:About" );
688 for ( sal_uInt16 n = 0; n < pMenu->GetItemCount(); n++ )
690 sal_uInt16 nItemId = pMenu->GetItemId( n );
691 nNewItemId = std::max( nItemId, nNewItemId );
692 if ( pMenu->GetItemCommand( nItemId ) == aCommandBefore )
693 nBeforePos = n;
695 ++nNewItemId;
697 if ( nBeforePos != MENU_APPEND )
698 nInsertPos = nBeforePos;
700 pMenu->InsertItem(nNewItemId, aMenuItem.aLabel, MenuItemBits::NONE, OString(), nInsertPos);
701 pMenu->SetItemCommand( nNewItemId, aMenuItem.aURL );
705 static void lcl_CheckForChildren(Menu* pMenu, sal_uInt16 nItemId)
707 if (PopupMenu* pThisPopup = pMenu->GetPopupMenu( nItemId ))
708 pMenu->EnableItem( nItemId, pThisPopup->GetItemCount() != 0 );
711 // vcl handler
713 namespace {
715 class QuietInteractionContext:
716 public cppu::WeakImplHelper1< com::sun::star::uno::XCurrentContext >,
717 private boost::noncopyable
719 public:
720 QuietInteractionContext(
721 com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext >
722 const & context):
723 context_(context) {}
725 private:
726 virtual ~QuietInteractionContext() {}
728 virtual com::sun::star::uno::Any SAL_CALL getValueByName(
729 OUString const & Name)
730 throw (com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
732 return Name != JAVA_INTERACTION_HANDLER_NAME && context_.is()
733 ? context_->getValueByName(Name)
734 : com::sun::star::uno::Any();
737 com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext >
738 context_;
743 IMPL_LINK_TYPED( MenuBarManager, Activate, Menu *, pMenu, bool )
745 if ( pMenu == m_pVCLMenu )
747 com::sun::star::uno::ContextLayer layer(
748 new QuietInteractionContext(
749 com::sun::star::uno::getCurrentContext()));
751 // set/unset hiding disabled menu entries
752 bool bDontHide = SvtMenuOptions().IsEntryHidingEnabled();
753 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
754 bool bShowMenuImages = rSettings.GetUseImagesInMenus();
755 bool bHasDisabledEntries = SvtCommandOptions().HasEntries( SvtCommandOptions::CMDOPTION_DISABLED );
757 SolarMutexGuard g;
759 MenuFlags nFlag = pMenu->GetMenuFlags();
760 if ( bDontHide )
761 nFlag &= ~MenuFlags::HideDisabledEntries;
762 else
763 nFlag |= MenuFlags::HideDisabledEntries;
764 pMenu->SetMenuFlags( nFlag );
766 if ( m_bActive )
767 return false;
769 m_bActive = true;
771 OUString aMenuCommand( m_aMenuItemCommand );
772 if ( m_aMenuItemCommand == aSpecialWindowMenu || m_aMenuItemCommand == aSlotSpecialWindowMenu || aMenuCommand == aSpecialWindowCommand )
773 MenuManager::UpdateSpecialWindowMenu( pMenu, m_xContext );
775 // Check if some modes have changed so we have to update our menu images
776 OUString sIconTheme = SvtMiscOptions().GetIconTheme();
778 if ( m_bRetrieveImages ||
779 bShowMenuImages != m_bShowMenuImages ||
780 sIconTheme != m_sIconTheme )
782 m_bShowMenuImages = bShowMenuImages;
783 m_bRetrieveImages = false;
784 m_sIconTheme = sIconTheme;
785 MenuManager::FillMenuImages( m_xFrame, pMenu, bShowMenuImages );
788 // Try to map commands to labels
789 for ( sal_uInt16 nPos = 0; nPos < pMenu->GetItemCount(); nPos++ )
791 sal_uInt16 nItemId = pMenu->GetItemId( nPos );
792 if (( pMenu->GetItemType( nPos ) != MenuItemType::SEPARATOR ) &&
793 ( pMenu->GetItemText( nItemId ).isEmpty() ))
795 OUString aCommand = pMenu->GetItemCommand( nItemId );
796 if ( !aCommand.isEmpty() ) {
797 pMenu->SetItemText( nItemId, RetrieveLabelFromCommand( aCommand ));
802 // Try to set accelerator keys
804 RetrieveShortcuts( m_aMenuItemHandlerVector );
805 std::vector< MenuItemHandler* >::iterator p;
806 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
808 MenuItemHandler* pMenuItemHandler = *p;
810 // Set key code, workaround for hard-coded shortcut F1 mapped to .uno:HelpIndex
811 // Only non-popup menu items can have a short-cut
812 if ( pMenuItemHandler->aMenuItemURL == aCmdHelpIndex )
814 vcl::KeyCode aKeyCode( KEY_F1 );
815 pMenu->SetAccelKey( pMenuItemHandler->nItemId, aKeyCode );
817 else if ( pMenu->GetPopupMenu( pMenuItemHandler->nItemId ) == 0 )
818 pMenu->SetAccelKey( pMenuItemHandler->nItemId, pMenuItemHandler->aKeyCode );
822 URL aTargetURL;
824 // Use provided dispatch provider => fallback to frame as dispatch provider
825 Reference< XDispatchProvider > xDispatchProvider;
826 if ( m_xDispatchProvider.is() )
827 xDispatchProvider = m_xDispatchProvider;
828 else
829 xDispatchProvider = Reference< XDispatchProvider >( m_xFrame, UNO_QUERY );
831 if ( xDispatchProvider.is() )
833 vcl::KeyCode aEmptyKeyCode;
834 SvtCommandOptions aCmdOptions;
835 std::vector< MenuItemHandler* >::iterator p;
836 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
838 MenuItemHandler* pMenuItemHandler = *p;
839 if ( pMenuItemHandler )
841 if ( !pMenuItemHandler->xMenuItemDispatch.is() &&
842 !pMenuItemHandler->xSubMenuManager.is() )
844 // There is no dispatch mechanism for the special window list menu items,
845 // because they are handled directly through XFrame->activate!!!
846 // Don't update dispatches for special file menu items.
847 if ( !(( pMenuItemHandler->nItemId >= START_ITEMID_WINDOWLIST &&
848 pMenuItemHandler->nItemId < END_ITEMID_WINDOWLIST )))
850 Reference< XDispatch > xMenuItemDispatch;
852 OUString aItemCommand = pMenu->GetItemCommand( pMenuItemHandler->nItemId );
853 if ( aItemCommand.isEmpty() )
855 aItemCommand = "slot:" + OUString::number( pMenuItemHandler->nItemId );
856 pMenu->SetItemCommand( pMenuItemHandler->nItemId, aItemCommand );
859 aTargetURL.Complete = aItemCommand;
861 m_xURLTransformer->parseStrict( aTargetURL );
863 if ( bHasDisabledEntries )
865 if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aTargetURL.Path ))
866 pMenu->HideItem( pMenuItemHandler->nItemId );
869 if ( m_bIsBookmarkMenu )
870 xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, pMenuItemHandler->aTargetFrame, 0 );
871 else
872 xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
874 bool bPopupMenu( false );
875 if ( !pMenuItemHandler->xPopupMenuController.is() &&
876 m_xPopupMenuControllerFactory->hasController( aItemCommand, OUString() ))
878 bPopupMenu = CreatePopupMenuController( pMenuItemHandler );
880 else if ( pMenuItemHandler->xPopupMenuController.is() )
882 // Force update of popup menu
883 pMenuItemHandler->xPopupMenuController->updatePopupMenu();
884 bPopupMenu = true;
885 if (PopupMenu* pThisPopup = pMenu->GetPopupMenu( pMenuItemHandler->nItemId ))
886 pMenu->EnableItem( pMenuItemHandler->nItemId, pThisPopup->GetItemCount() != 0 );
889 lcl_CheckForChildren(pMenu, pMenuItemHandler->nItemId);
891 if ( xMenuItemDispatch.is() )
893 pMenuItemHandler->xMenuItemDispatch = xMenuItemDispatch;
894 pMenuItemHandler->aMenuItemURL = aTargetURL.Complete;
896 if ( !bPopupMenu )
898 xMenuItemDispatch->addStatusListener( static_cast< XStatusListener* >( this ), aTargetURL );
899 xMenuItemDispatch->removeStatusListener( static_cast< XStatusListener* >( this ), aTargetURL );
900 xMenuItemDispatch->addStatusListener( static_cast< XStatusListener* >( this ), aTargetURL );
903 else if ( !bPopupMenu )
904 pMenu->EnableItem( pMenuItemHandler->nItemId, false );
907 else if ( pMenuItemHandler->xPopupMenuController.is() )
909 // Force update of popup menu
910 pMenuItemHandler->xPopupMenuController->updatePopupMenu();
911 lcl_CheckForChildren(pMenu, pMenuItemHandler->nItemId);
913 else if ( pMenuItemHandler->xMenuItemDispatch.is() )
915 // We need an update to reflect the current state
918 aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
919 m_xURLTransformer->parseStrict( aTargetURL );
921 pMenuItemHandler->xMenuItemDispatch->addStatusListener(
922 static_cast< XStatusListener* >( this ), aTargetURL );
923 pMenuItemHandler->xMenuItemDispatch->removeStatusListener(
924 static_cast< XStatusListener* >( this ), aTargetURL );
926 catch ( const Exception& )
930 else if ( pMenuItemHandler->xSubMenuManager.is() )
931 lcl_CheckForChildren(pMenu, pMenuItemHandler->nItemId);
937 return true;
940 IMPL_LINK_TYPED( MenuBarManager, Deactivate, Menu *, pMenu, bool )
942 if ( pMenu == m_pVCLMenu )
944 m_bActive = false;
945 if ( pMenu->IsMenuBar() && m_xDeferedItemContainer.is() )
947 // Start timer to handle settings asynchronous
948 // Changing the menu inside this handler leads to
949 // a crash under X!
950 m_aAsyncSettingsTimer.SetTimeoutHdl(LINK(this, MenuBarManager, AsyncSettingsHdl));
951 m_aAsyncSettingsTimer.SetTimeout(10);
952 m_aAsyncSettingsTimer.Start();
956 return true;
959 IMPL_LINK_NOARG_TYPED( MenuBarManager, AsyncSettingsHdl, Timer*, void)
961 SolarMutexGuard g;
962 Reference< XInterface > xSelfHold(
963 static_cast< ::cppu::OWeakObject* >( this ), UNO_QUERY_THROW );
965 m_aAsyncSettingsTimer.Stop();
966 if ( !m_bActive && m_xDeferedItemContainer.is() )
968 SetItemContainer( m_xDeferedItemContainer );
969 m_xDeferedItemContainer.clear();
973 IMPL_LINK( MenuBarManager, Select, Menu *, pMenu )
975 URL aTargetURL;
976 Sequence<PropertyValue> aArgs;
977 Reference< XDispatch > xDispatch;
980 SolarMutexGuard g;
982 sal_uInt16 nCurItemId = pMenu->GetCurItemId();
983 sal_uInt16 nCurPos = pMenu->GetItemPos( nCurItemId );
984 if ( pMenu == m_pVCLMenu &&
985 pMenu->GetItemType( nCurPos ) != MenuItemType::SEPARATOR )
987 if ( nCurItemId >= START_ITEMID_WINDOWLIST &&
988 nCurItemId <= END_ITEMID_WINDOWLIST )
990 // window list menu item selected
992 Reference< XDesktop2 > xDesktop = Desktop::create( m_xContext );
994 sal_uInt16 nTaskId = START_ITEMID_WINDOWLIST;
995 Reference< XIndexAccess > xList( xDesktop->getFrames(), UNO_QUERY );
996 sal_Int32 nCount = xList->getCount();
997 for ( sal_Int32 i=0; i<nCount; ++i )
999 Reference< XFrame > xFrame;
1000 xList->getByIndex(i) >>= xFrame;
1001 if ( xFrame.is() && nTaskId == nCurItemId )
1003 vcl::Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
1004 pWin->GrabFocus();
1005 pWin->ToTop( TOTOP_RESTOREWHENMIN );
1006 break;
1009 nTaskId++;
1012 else
1014 MenuItemHandler* pMenuItemHandler = GetMenuItemHandler( nCurItemId );
1015 if ( pMenuItemHandler && pMenuItemHandler->xMenuItemDispatch.is() )
1017 aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
1018 m_xURLTransformer->parseStrict( aTargetURL );
1020 if ( m_bIsBookmarkMenu )
1022 // bookmark menu item selected
1023 aArgs.realloc( 1 );
1024 aArgs[0].Name = "Referer";
1025 aArgs[0].Value <<= OUString( "private:user" );
1028 xDispatch = pMenuItemHandler->xMenuItemDispatch;
1034 if ( xDispatch.is() )
1036 SolarMutexReleaser aReleaser;
1037 xDispatch->dispatch( aTargetURL, aArgs );
1040 return 1;
1043 IMPL_LINK_NOARG_TYPED(MenuBarManager, Highlight, Menu *, bool)
1045 return false;
1048 bool MenuBarManager::MustBeHidden( PopupMenu* pPopupMenu, const Reference< XURLTransformer >& rTransformer )
1050 if ( pPopupMenu )
1052 URL aTargetURL;
1053 SvtCommandOptions aCmdOptions;
1055 sal_uInt16 nCount = pPopupMenu->GetItemCount();
1056 sal_uInt16 nHideCount( 0 );
1058 for ( sal_uInt16 i = 0; i < nCount; i++ )
1060 sal_uInt16 nId = pPopupMenu->GetItemId( i );
1061 if ( nId > 0 )
1063 PopupMenu* pSubPopupMenu = pPopupMenu->GetPopupMenu( nId );
1064 if ( pSubPopupMenu )
1066 if ( MustBeHidden( pSubPopupMenu, rTransformer ))
1068 pPopupMenu->HideItem( nId );
1069 ++nHideCount;
1072 else
1074 aTargetURL.Complete = pPopupMenu->GetItemCommand( nId );
1075 rTransformer->parseStrict( aTargetURL );
1077 if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aTargetURL.Path ))
1078 ++nHideCount;
1081 else
1082 ++nHideCount;
1085 return ( nCount == nHideCount );
1088 return true;
1091 OUString MenuBarManager::RetrieveLabelFromCommand(const OUString& rCmdURL)
1093 return framework::RetrieveLabelFromCommand(rCmdURL, m_xContext, m_xUICommandLabels,m_xFrame,m_aModuleIdentifier,m_bModuleIdentified,"Label");
1096 bool MenuBarManager::CreatePopupMenuController( MenuItemHandler* pMenuItemHandler )
1098 OUString aItemCommand( pMenuItemHandler->aMenuItemURL );
1100 // Try instanciate a popup menu controller. It is stored in the menu item handler.
1101 if ( !m_xPopupMenuControllerFactory.is() )
1102 return false;
1104 Sequence< Any > aSeq( 2 );
1105 PropertyValue aPropValue;
1107 aPropValue.Name = "ModuleIdentifier";
1108 aPropValue.Value <<= m_aModuleIdentifier;
1109 aSeq[0] <<= aPropValue;
1110 aPropValue.Name = "Frame";
1111 aPropValue.Value <<= m_xFrame;
1112 aSeq[1] <<= aPropValue;
1114 Reference< XPopupMenuController > xPopupMenuController(
1115 m_xPopupMenuControllerFactory->createInstanceWithArgumentsAndContext(
1116 aItemCommand,
1117 aSeq,
1118 m_xContext ),
1119 UNO_QUERY );
1121 if ( xPopupMenuController.is() )
1123 // Provide our awt popup menu to the popup menu controller
1124 pMenuItemHandler->xPopupMenuController = xPopupMenuController;
1125 xPopupMenuController->setPopupMenu( pMenuItemHandler->xPopupMenu );
1126 return true;
1129 return false;
1132 void MenuBarManager::FillMenuManager( Menu* pMenu, const Reference< XFrame >& rFrame, const Reference< XDispatchProvider >& rDispatchProvider, const OUString& rModuleIdentifier, bool bDelete, bool bDeleteChildren )
1134 m_xFrame = rFrame;
1135 m_bActive = false;
1136 m_bDeleteMenu = bDelete;
1137 m_bDeleteChildren = bDeleteChildren;
1138 m_pVCLMenu = pMenu;
1139 m_bInitialized = false;
1140 m_bIsBookmarkMenu = false;
1141 m_xDispatchProvider = rDispatchProvider;
1143 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
1144 m_bShowMenuImages = rSettings.GetUseImagesInMenus();
1145 m_bRetrieveImages = false;
1147 // Add root as ui configuration listener
1148 RetrieveImageManagers();
1150 if ( pMenu->IsMenuBar() && rFrame.is() )
1152 // First merge all addon popup menus into our structure
1153 sal_uInt16 nPos = 0;
1154 for ( nPos = 0; nPos < pMenu->GetItemCount(); nPos++ )
1156 sal_uInt16 nItemId = pMenu->GetItemId( nPos );
1157 OUString aCommand = pMenu->GetItemCommand( nItemId );
1158 if ( nItemId == SID_MDIWINDOWLIST || aCommand == aSpecialWindowCommand ||
1159 nItemId == SID_HELPMENU || aCommand == aCmdHelpMenu )
1161 // Retrieve addon popup menus and add them to our menu bar
1162 framework::AddonMenuManager::MergeAddonPopupMenus( rFrame, nPos, static_cast<MenuBar *>(pMenu), m_xContext );
1163 break;
1167 // Merge the Add-Ons help menu items into the Office help menu
1168 framework::AddonMenuManager::MergeAddonHelpMenu( rFrame, static_cast<MenuBar *>(pMenu), m_xContext );
1171 OUString aEmpty;
1172 bool bAccessibilityEnabled( Application::GetSettings().GetMiscSettings().GetEnableATToolSupport() );
1173 sal_uInt16 nItemCount = pMenu->GetItemCount();
1174 OUString aItemCommand;
1175 m_aMenuItemHandlerVector.reserve(nItemCount);
1176 for ( sal_uInt16 i = 0; i < nItemCount; i++ )
1178 sal_uInt16 nItemId = FillItemCommand(aItemCommand,pMenu, i );
1180 // Set module identifier when provided from outside
1181 if ( !rModuleIdentifier.isEmpty() )
1183 m_aModuleIdentifier = rModuleIdentifier;
1184 m_bModuleIdentified = true;
1187 if (( pMenu->IsMenuBar() || bAccessibilityEnabled ) &&
1188 ( pMenu->GetItemText( nItemId ).isEmpty() ))
1190 if ( !aItemCommand.isEmpty() )
1191 pMenu->SetItemText( nItemId, RetrieveLabelFromCommand( aItemCommand ));
1194 Reference< XDispatch > xDispatch;
1195 Reference< XStatusListener > xStatusListener;
1196 PopupMenu* pPopup = pMenu->GetPopupMenu( nItemId );
1197 bool bItemShowMenuImages = m_bShowMenuImages;
1198 // overwrite the show icons on menu option?
1199 if (!bItemShowMenuImages)
1201 MenuItemBits nBits = pMenu->GetItemBits( nItemId );
1202 bItemShowMenuImages = ( ( nBits & MenuItemBits::ICON ) == MenuItemBits::ICON );
1204 if ( pPopup )
1206 // Retrieve module identifier from Help Command entry
1207 OUString aModuleIdentifier( rModuleIdentifier );
1208 if (!pMenu->GetHelpCommand(nItemId).isEmpty())
1210 aModuleIdentifier = pMenu->GetHelpCommand( nItemId );
1211 pMenu->SetHelpCommand( nItemId, aEmpty );
1214 if ( m_xPopupMenuControllerFactory.is() &&
1215 pPopup->GetItemCount() == 0 &&
1216 m_xPopupMenuControllerFactory->hasController( aItemCommand, OUString() )
1219 // Check if we have to create a popup menu for a uno based popup menu controller.
1220 // We have to set an empty popup menu into our menu structure so the controller also
1221 // works with inplace OLE. Remove old dummy popup menu!
1222 MenuItemHandler* pItemHandler = new MenuItemHandler( nItemId, xStatusListener, xDispatch );
1223 VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu;
1224 PopupMenu* pNewPopupMenu = static_cast<PopupMenu *>(pVCLXPopupMenu->GetMenu());
1225 pMenu->SetPopupMenu( nItemId, pNewPopupMenu );
1226 pItemHandler->xPopupMenu = Reference< com::sun::star::awt::XPopupMenu >( (OWeakObject *)pVCLXPopupMenu, UNO_QUERY );
1227 pItemHandler->aMenuItemURL = aItemCommand;
1228 m_aMenuItemHandlerVector.push_back( pItemHandler );
1229 delete pPopup;
1231 if ( bAccessibilityEnabled )
1233 if ( CreatePopupMenuController( pItemHandler ))
1234 pItemHandler->xPopupMenuController->updatePopupMenu();
1236 lcl_CheckForChildren(pMenu, nItemId);
1238 else if ( aItemCommand.startsWith( ADDONSPOPUPMENU_URL_PREFIX_STR ) )
1240 // A special addon popup menu, must be created with a different ctor
1241 MenuBarManager* pSubMenuManager = new MenuBarManager( m_xContext, m_xFrame, m_xURLTransformer,
1242 pPopup, bDeleteChildren, bDeleteChildren, true );
1243 AddMenu(pSubMenuManager,aItemCommand,nItemId);
1245 else
1247 Reference< XDispatchProvider > xPopupMenuDispatchProvider( rDispatchProvider );
1249 // Retrieve possible attributes struct
1250 MenuAttributes* pAttributes = reinterpret_cast<MenuAttributes *>(pMenu->GetUserValue( nItemId ));
1251 if ( pAttributes )
1252 xPopupMenuDispatchProvider = pAttributes->xDispatchProvider;
1254 // Check if this is the help menu. Add menu item if needed
1255 if ( nItemId == SID_HELPMENU || aItemCommand == aSlotHelpMenu || aItemCommand == aCmdHelpMenu )
1257 // Check if this is the help menu. Add menu item if needed
1258 CheckAndAddMenuExtension( pPopup );
1260 else if (( nItemId == SID_ADDONLIST || aItemCommand == aSlotSpecialToolsMenu || aItemCommand == aCmdToolsMenu ) &&
1261 AddonMenuManager::HasAddonMenuElements() )
1263 // Create addon popup menu if there exist elements and this is the tools popup menu
1264 AddonMenu* pSubMenu = AddonMenuManager::CreateAddonMenu(rFrame, m_xContext);
1265 if ( pSubMenu && ( pSubMenu->GetItemCount() > 0 ))
1267 sal_uInt16 nCount = 0;
1268 if ( pPopup->GetItemType( nCount-1 ) != MenuItemType::SEPARATOR )
1269 pPopup->InsertSeparator();
1271 // Use resource to load popup menu title
1272 OUString aAddonsStrRes(FWK_RESSTR(STR_MENU_ADDONS));
1273 pPopup->InsertItem( ITEMID_ADDONLIST, aAddonsStrRes );
1274 pPopup->SetPopupMenu( ITEMID_ADDONLIST, pSubMenu );
1276 // Set item command for popup menu to enable it for GetImageFromURL
1277 OUString aNewItemCommand = "slot:" + OUString::number( ITEMID_ADDONLIST );
1278 pPopup->SetItemCommand( ITEMID_ADDONLIST, aNewItemCommand );
1280 else
1281 delete pSubMenu;
1284 if ( nItemId == ITEMID_ADDONLIST )
1286 AddonMenu* pSubMenu = dynamic_cast< AddonMenu* >( pPopup );
1287 if ( pSubMenu )
1289 MenuBarManager* pSubMenuManager = new MenuBarManager( m_xContext, m_xFrame, m_xURLTransformer,pSubMenu, true, false, false );
1290 AddMenu(pSubMenuManager,aItemCommand,nItemId);
1291 (pSubMenuManager->m_aMenuItemCommand).clear();
1293 // Set image for the addon popup menu item
1294 if ( bItemShowMenuImages && !pPopup->GetItemImage( ITEMID_ADDONLIST ))
1296 Reference< XFrame > xTemp( rFrame );
1297 Image aImage = GetImageFromURL( xTemp, aItemCommand, false );
1298 if ( !!aImage )
1299 pPopup->SetItemImage( ITEMID_ADDONLIST, aImage );
1303 else
1305 MenuBarManager* pSubMenuMgr = new MenuBarManager( m_xContext, rFrame, m_xURLTransformer,rDispatchProvider, aModuleIdentifier, pPopup, bDeleteChildren, bDeleteChildren );
1306 AddMenu(pSubMenuMgr,aItemCommand,nItemId);
1310 else if ( pMenu->GetItemType( i ) != MenuItemType::SEPARATOR )
1312 if ( bItemShowMenuImages )
1314 if ( AddonMenuManager::IsAddonMenuId( nItemId ))
1316 // Add-Ons uses images from different places
1317 Image aImage;
1318 OUString aImageId;
1320 MenuAttributes* pMenuAttributes =
1321 reinterpret_cast<MenuAttributes*>(pMenu->GetUserValue( nItemId ));
1323 if ( pMenuAttributes && !pMenuAttributes->aImageId.isEmpty() )
1325 // Retrieve image id from menu attributes
1326 aImage = GetImageFromURL( m_xFrame, aImageId, false );
1329 if ( !aImage )
1331 aImage = GetImageFromURL( m_xFrame, aItemCommand, false );
1332 if ( !aImage )
1333 aImage = AddonsOptions().GetImageFromURL( aItemCommand, false );
1336 if ( !!aImage )
1337 pMenu->SetItemImage( nItemId, aImage );
1338 else
1339 m_bRetrieveImages = true;
1341 m_bRetrieveImages = true;
1344 MenuItemHandler* pItemHandler = new MenuItemHandler( nItemId, xStatusListener, xDispatch );
1345 pItemHandler->aMenuItemURL = aItemCommand;
1347 if ( m_xPopupMenuControllerFactory.is() &&
1348 m_xPopupMenuControllerFactory->hasController( aItemCommand, OUString() ))
1350 // Check if we have to create a popup menu for a uno based popup menu controller.
1351 // We have to set an empty popup menu into our menu structure so the controller also
1352 // works with inplace OLE.
1353 VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu;
1354 PopupMenu* pPopupMenu = static_cast<PopupMenu *>(pVCLXPopupMenu->GetMenu());
1355 pMenu->SetPopupMenu( pItemHandler->nItemId, pPopupMenu );
1356 pItemHandler->xPopupMenu = Reference< com::sun::star::awt::XPopupMenu >( (OWeakObject *)pVCLXPopupMenu, UNO_QUERY );
1358 if ( bAccessibilityEnabled && CreatePopupMenuController( pItemHandler ) )
1360 pItemHandler->xPopupMenuController->updatePopupMenu();
1363 lcl_CheckForChildren(pMenu, pItemHandler->nItemId);
1366 m_aMenuItemHandlerVector.push_back( pItemHandler );
1370 if ( bAccessibilityEnabled )
1372 RetrieveShortcuts( m_aMenuItemHandlerVector );
1373 std::vector< MenuItemHandler* >::iterator p;
1374 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
1376 MenuItemHandler* pMenuItemHandler = *p;
1378 // Set key code, workaround for hard-coded shortcut F1 mapped to .uno:HelpIndex
1379 // Only non-popup menu items can have a short-cut
1380 if ( pMenuItemHandler->aMenuItemURL == aCmdHelpIndex )
1382 vcl::KeyCode aKeyCode( KEY_F1 );
1383 pMenu->SetAccelKey( pMenuItemHandler->nItemId, aKeyCode );
1385 else if ( pMenu->GetPopupMenu( pMenuItemHandler->nItemId ) == 0 )
1386 pMenu->SetAccelKey( pMenuItemHandler->nItemId, pMenuItemHandler->aKeyCode );
1390 SetHdl();
1393 void MenuBarManager::impl_RetrieveShortcutsFromConfiguration(
1394 const Reference< XAcceleratorConfiguration >& rAccelCfg,
1395 const Sequence< OUString >& rCommands,
1396 std::vector< MenuItemHandler* >& aMenuShortCuts )
1398 if ( rAccelCfg.is() )
1402 com::sun::star::awt::KeyEvent aKeyEvent;
1403 Sequence< Any > aSeqKeyCode = rAccelCfg->getPreferredKeyEventsForCommandList( rCommands );
1404 for ( sal_Int32 i = 0; i < aSeqKeyCode.getLength(); i++ )
1406 if ( aSeqKeyCode[i] >>= aKeyEvent )
1407 aMenuShortCuts[i]->aKeyCode = svt::AcceleratorExecute::st_AWTKey2VCLKey( aKeyEvent );
1410 catch ( const IllegalArgumentException& )
1416 void MenuBarManager::RetrieveShortcuts( std::vector< MenuItemHandler* >& aMenuShortCuts )
1418 if ( !m_bModuleIdentified )
1420 m_bModuleIdentified = true;
1421 Reference< XModuleManager2 > xModuleManager = ModuleManager::create( m_xContext );
1425 m_aModuleIdentifier = xModuleManager->identify( m_xFrame );
1427 catch( const Exception& )
1432 if ( m_bModuleIdentified )
1434 Reference< XAcceleratorConfiguration > xDocAccelCfg( m_xDocAcceleratorManager );
1435 Reference< XAcceleratorConfiguration > xModuleAccelCfg( m_xModuleAcceleratorManager );
1436 Reference< XAcceleratorConfiguration > xGlobalAccelCfg( m_xGlobalAcceleratorManager );
1438 if ( !m_bAcceleratorCfg )
1440 // Retrieve references on demand
1441 m_bAcceleratorCfg = true;
1442 if ( !xDocAccelCfg.is() )
1444 Reference< XController > xController = m_xFrame->getController();
1445 Reference< XModel > xModel;
1446 if ( xController.is() )
1448 xModel = xController->getModel();
1449 if ( xModel.is() )
1451 Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY );
1452 if ( xSupplier.is() )
1454 Reference< XUIConfigurationManager > xDocUICfgMgr( xSupplier->getUIConfigurationManager(), UNO_QUERY );
1455 if ( xDocUICfgMgr.is() )
1457 xDocAccelCfg = xDocUICfgMgr->getShortCutManager();
1458 m_xDocAcceleratorManager = xDocAccelCfg;
1465 if ( !xModuleAccelCfg.is() )
1467 Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier =
1468 theModuleUIConfigurationManagerSupplier::get( m_xContext );
1471 Reference< XUIConfigurationManager > xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier );
1472 if ( xUICfgMgr.is() )
1474 xModuleAccelCfg = xUICfgMgr->getShortCutManager();
1475 m_xModuleAcceleratorManager = xModuleAccelCfg;
1478 catch ( const RuntimeException& )
1480 throw;
1482 catch ( const Exception& )
1487 if ( !xGlobalAccelCfg.is() ) try
1489 xGlobalAccelCfg = GlobalAcceleratorConfiguration::create( m_xContext );
1490 m_xGlobalAcceleratorManager = xGlobalAccelCfg;
1492 catch ( const css::uno::DeploymentException& )
1494 SAL_WARN("fwk.uielement", "GlobalAcceleratorConfiguration"
1495 " not available. This should happen only on mobile platforms.");
1499 vcl::KeyCode aEmptyKeyCode;
1500 Sequence< OUString > aSeq( aMenuShortCuts.size() );
1501 const sal_uInt32 nCount = aMenuShortCuts.size();
1502 for ( sal_uInt32 i = 0; i < nCount; ++i )
1504 aSeq[i] = aMenuShortCuts[i]->aMenuItemURL;
1505 aMenuShortCuts[i]->aKeyCode = aEmptyKeyCode;
1508 if ( m_xGlobalAcceleratorManager.is() )
1509 impl_RetrieveShortcutsFromConfiguration( xGlobalAccelCfg, aSeq, aMenuShortCuts );
1510 if ( m_xModuleAcceleratorManager.is() )
1511 impl_RetrieveShortcutsFromConfiguration( xModuleAccelCfg, aSeq, aMenuShortCuts );
1512 if ( m_xDocAcceleratorManager.is() )
1513 impl_RetrieveShortcutsFromConfiguration( xDocAccelCfg, aSeq, aMenuShortCuts );
1517 void MenuBarManager::RetrieveImageManagers()
1519 if ( !m_xDocImageManager.is() )
1521 Reference< XController > xController = m_xFrame->getController();
1522 Reference< XModel > xModel;
1523 if ( xController.is() )
1525 xModel = xController->getModel();
1526 if ( xModel.is() )
1528 Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY );
1529 if ( xSupplier.is() )
1531 Reference< XUIConfigurationManager > xDocUICfgMgr( xSupplier->getUIConfigurationManager(), UNO_QUERY );
1532 m_xDocImageManager = Reference< XImageManager >( xDocUICfgMgr->getImageManager(), UNO_QUERY );
1533 m_xDocImageManager->addConfigurationListener(
1534 Reference< XUIConfigurationListener >(
1535 static_cast< OWeakObject* >( this ), UNO_QUERY ));
1541 Reference< XModuleManager2 > xModuleManager;
1542 if ( m_aModuleIdentifier.isEmpty() )
1543 xModuleManager.set( ModuleManager::create( m_xContext ) );
1547 if ( xModuleManager.is() )
1548 m_aModuleIdentifier = xModuleManager->identify( Reference< XInterface >( m_xFrame, UNO_QUERY ) );
1550 catch( const Exception& )
1554 if ( !m_xModuleImageManager.is() )
1556 Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier =
1557 theModuleUIConfigurationManagerSupplier::get( m_xContext );
1558 Reference< XUIConfigurationManager > xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier );
1559 m_xModuleImageManager.set( xUICfgMgr->getImageManager(), UNO_QUERY );
1560 m_xModuleImageManager->addConfigurationListener( Reference< XUIConfigurationListener >(
1561 static_cast< OWeakObject* >( this ), UNO_QUERY ));
1565 void MenuBarManager::FillMenuWithConfiguration(
1566 sal_uInt16& nId,
1567 Menu* pMenu,
1568 const OUString& rModuleIdentifier,
1569 const Reference< XIndexAccess >& rItemContainer,
1570 const Reference< XURLTransformer >& rTransformer )
1572 Reference< XDispatchProvider > xEmptyDispatchProvider;
1573 MenuBarManager::FillMenu( nId, pMenu, rModuleIdentifier, rItemContainer, xEmptyDispatchProvider );
1575 // Merge add-on menu entries into the menu bar
1576 MenuBarManager::MergeAddonMenus( static_cast< Menu* >( pMenu ),
1577 AddonsOptions().GetMergeMenuInstructions(),
1578 rModuleIdentifier );
1580 bool bHasDisabledEntries = SvtCommandOptions().HasEntries( SvtCommandOptions::CMDOPTION_DISABLED );
1581 if ( bHasDisabledEntries )
1583 sal_uInt16 nCount = pMenu->GetItemCount();
1584 for ( sal_uInt16 i = 0; i < nCount; i++ )
1586 sal_uInt16 nID = pMenu->GetItemId( i );
1587 if ( nID > 0 )
1589 PopupMenu* pPopupMenu = pMenu->GetPopupMenu( nID );
1590 if ( pPopupMenu )
1592 if ( MustBeHidden( pPopupMenu, rTransformer ))
1593 pMenu->HideItem( nId );
1600 void MenuBarManager::FillMenu(
1601 sal_uInt16& nId,
1602 Menu* pMenu,
1603 const OUString& rModuleIdentifier,
1604 const Reference< XIndexAccess >& rItemContainer,
1605 const Reference< XDispatchProvider >& rDispatchProvider )
1607 // Fill menu bar with container contents
1608 for ( sal_Int32 n = 0; n < rItemContainer->getCount(); n++ )
1610 Sequence< PropertyValue > aProp;
1611 OUString aCommandURL;
1612 OUString aLabel;
1613 OUString aHelpURL;
1614 OUString aModuleIdentifier( rModuleIdentifier );
1615 sal_uInt16 nType = 0;
1616 Reference< XIndexAccess > xIndexContainer;
1617 Reference< XDispatchProvider > xDispatchProvider( rDispatchProvider );
1618 sal_Int16 nStyle = 0;
1621 if ( rItemContainer->getByIndex( n ) >>= aProp )
1623 bool bShow = true;
1624 bool bEnabled = true;
1626 for ( int i = 0; i < aProp.getLength(); i++ )
1628 OUString aPropName = aProp[i].Name;
1629 if ( aPropName == "CommandURL" )
1630 aProp[i].Value >>= aCommandURL;
1631 else if ( aPropName == "HelpURL" )
1632 aProp[i].Value >>= aHelpURL;
1633 else if ( aPropName == "ItemDescriptorContainer" )
1634 aProp[i].Value >>= xIndexContainer;
1635 else if ( aPropName == "Label" )
1636 aProp[i].Value >>= aLabel;
1637 else if ( aPropName == "Type" )
1638 aProp[i].Value >>= nType;
1639 else if ( aPropName == "ModuleIdentifier" )
1640 aProp[i].Value >>= aModuleIdentifier;
1641 else if ( aPropName == "DispatchProvider" )
1642 aProp[i].Value >>= xDispatchProvider;
1643 else if ( aPropName == "Style" )
1644 aProp[i].Value >>= nStyle;
1645 else if ( aPropName == "IsVisible" )
1646 aProp[i].Value >>= bShow;
1647 else if ( aPropName == "Enabled" )
1648 aProp[i].Value >>= bEnabled;
1651 if ( nType == ::com::sun::star::ui::ItemType::DEFAULT )
1653 pMenu->InsertItem( nId, aLabel );
1654 pMenu->SetItemCommand( nId, aCommandURL );
1656 if ( nStyle )
1658 MenuItemBits nBits = pMenu->GetItemBits( nId );
1659 if ( nStyle & ::com::sun::star::ui::ItemStyle::ICON )
1660 nBits |= MenuItemBits::ICON;
1661 if ( nStyle & ::com::sun::star::ui::ItemStyle::TEXT )
1662 nBits |= MenuItemBits::TEXT;
1663 if ( nStyle & ::com::sun::star::ui::ItemStyle::RADIO_CHECK )
1664 nBits |= MenuItemBits::RADIOCHECK;
1665 pMenu->SetItemBits( nId, nBits );
1668 if ( !bShow )
1669 pMenu->HideItem( nId );
1671 if ( !bEnabled)
1672 pMenu->EnableItem( nId, false );
1674 if ( xIndexContainer.is() )
1676 PopupMenu* pNewPopupMenu = new PopupMenu;
1677 pMenu->SetPopupMenu( nId, pNewPopupMenu );
1679 if ( xDispatchProvider.is() )
1681 // Use attributes struct to transport special dispatch provider
1682 sal_uIntPtr nAttributePtr = MenuAttributes::CreateAttribute(xDispatchProvider);
1683 pMenu->SetUserValue(nId, nAttributePtr, MenuAttributes::ReleaseAttribute);
1686 // Use help command to transport module identifier
1687 if ( !aModuleIdentifier.isEmpty() )
1688 pMenu->SetHelpCommand( nId, aModuleIdentifier );
1690 ++nId;
1691 FillMenu( nId, pNewPopupMenu, aModuleIdentifier, xIndexContainer, xDispatchProvider );
1693 else
1694 ++nId;
1696 else
1698 pMenu->InsertSeparator();
1699 ++nId;
1703 catch ( const IndexOutOfBoundsException& )
1705 break;
1710 void MenuBarManager::MergeAddonMenus(
1711 Menu* pMenuBar,
1712 const MergeMenuInstructionContainer& aMergeInstructionContainer,
1713 const OUString& rModuleIdentifier )
1715 // set start value for the item ID for the new addon menu items
1716 sal_uInt16 nItemId = ADDONMENU_MERGE_ITEMID_START;
1718 const sal_uInt32 nCount = aMergeInstructionContainer.size();
1719 for ( sal_uInt32 i = 0; i < nCount; i++ )
1721 const MergeMenuInstruction& rMergeInstruction = aMergeInstructionContainer[i];
1723 if ( MenuBarMerger::IsCorrectContext( rMergeInstruction.aMergeContext, rModuleIdentifier ))
1725 ::std::vector< OUString > aMergePath;
1727 // retrieve the merge path from the merge point string
1728 MenuBarMerger::RetrieveReferencePath( rMergeInstruction.aMergePoint, aMergePath );
1730 // convert the sequence/sequence property value to a more convenient vector<>
1731 AddonMenuContainer aMergeMenuItems;
1732 MenuBarMerger::GetSubMenu( rMergeInstruction.aMergeMenu, aMergeMenuItems );
1734 // try to find the reference point for our merge operation
1735 Menu* pMenu = pMenuBar;
1736 ReferencePathInfo aResult = MenuBarMerger::FindReferencePath( aMergePath, pMenu );
1738 if ( aResult.eResult == RP_OK )
1740 // normal merge operation
1741 MenuBarMerger::ProcessMergeOperation( aResult.pPopupMenu,
1742 aResult.nPos,
1743 nItemId,
1744 rMergeInstruction.aMergeCommand,
1745 rMergeInstruction.aMergeCommandParameter,
1746 rModuleIdentifier,
1747 aMergeMenuItems );
1749 else
1751 // fallback
1752 MenuBarMerger::ProcessFallbackOperation( aResult,
1753 nItemId,
1754 rMergeInstruction.aMergeCommand,
1755 rMergeInstruction.aMergeFallback,
1756 aMergePath,
1757 rModuleIdentifier,
1758 aMergeMenuItems );
1764 void MenuBarManager::SetItemContainer( const Reference< XIndexAccess >& rItemContainer )
1766 SolarMutexGuard aSolarMutexGuard;
1768 Reference< XFrame > xFrame = m_xFrame;
1770 if ( !m_bModuleIdentified )
1772 m_bModuleIdentified = true;
1773 Reference< XModuleManager2 > xModuleManager = ModuleManager::create( m_xContext );
1777 m_aModuleIdentifier = xModuleManager->identify( xFrame );
1779 catch( const Exception& )
1784 // Clear MenuBarManager structures
1786 // Check active state as we cannot change our VCL menu during activation by the user
1787 if ( m_bActive )
1789 m_xDeferedItemContainer = rItemContainer;
1790 return;
1793 RemoveListener();
1794 std::vector< MenuItemHandler* >::iterator p;
1795 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
1797 MenuItemHandler* pItemHandler = *p;
1798 pItemHandler->xMenuItemDispatch.clear();
1799 pItemHandler->xSubMenuManager.clear();
1800 delete pItemHandler;
1802 m_aMenuItemHandlerVector.clear();
1804 // Remove top-level parts
1805 m_pVCLMenu->Clear();
1807 sal_uInt16 nId = 1;
1809 // Fill menu bar with container contents
1810 FillMenuWithConfiguration( nId, m_pVCLMenu, m_aModuleIdentifier, rItemContainer, m_xURLTransformer );
1812 // Refill menu manager again
1813 Reference< XDispatchProvider > xDispatchProvider;
1814 FillMenuManager( m_pVCLMenu, xFrame, xDispatchProvider, m_aModuleIdentifier, false, true );
1816 // add itself as frame action listener
1817 m_xFrame->addFrameActionListener( Reference< XFrameActionListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
1821 void MenuBarManager::GetPopupController( PopupControllerCache& rPopupController )
1824 SolarMutexGuard aSolarMutexGuard;
1826 std::vector< MenuItemHandler* >::iterator p;
1827 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
1829 MenuItemHandler* pItemHandler = *p;
1830 if ( pItemHandler->xPopupMenuController.is() )
1832 Reference< XDispatchProvider > xDispatchProvider( pItemHandler->xPopupMenuController, UNO_QUERY );
1834 PopupControllerEntry aPopupControllerEntry;
1835 aPopupControllerEntry.m_xDispatchProvider = xDispatchProvider;
1837 // Just use the main part of the URL for popup menu controllers
1838 sal_Int32 nQueryPart( 0 );
1839 sal_Int32 nSchemePart( 0 );
1840 OUString aMainURL( "vnd.sun.star.popup:" );
1841 OUString aMenuURL( pItemHandler->aMenuItemURL );
1843 nSchemePart = aMenuURL.indexOf( ':' );
1844 if (( nSchemePart > 0 ) &&
1845 ( aMenuURL.getLength() > ( nSchemePart+1 )))
1847 nQueryPart = aMenuURL.indexOf( '?', nSchemePart );
1848 if ( nQueryPart > 0 )
1849 aMainURL += aMenuURL.copy( nSchemePart, nQueryPart-nSchemePart );
1850 else if ( nQueryPart == -1 )
1851 aMainURL += aMenuURL.copy( nSchemePart+1 );
1853 rPopupController.insert( PopupControllerCache::value_type(
1854 aMainURL, aPopupControllerEntry ));
1857 if ( pItemHandler->xSubMenuManager.is() )
1859 MenuBarManager* pMenuBarManager = static_cast<MenuBarManager*>(pItemHandler->xSubMenuManager.get());
1860 if ( pMenuBarManager )
1861 pMenuBarManager->GetPopupController( rPopupController );
1866 void MenuBarManager::AddMenu(MenuBarManager* pSubMenuManager,const OUString& _sItemCommand,sal_uInt16 _nItemId)
1868 Reference< XStatusListener > xSubMenuManager( static_cast< OWeakObject *>( pSubMenuManager ), UNO_QUERY );
1869 m_xFrame->addFrameActionListener( Reference< XFrameActionListener >( xSubMenuManager, UNO_QUERY ));
1871 // store menu item command as we later have to know which menu is active (see Activate handler)
1872 pSubMenuManager->m_aMenuItemCommand = _sItemCommand;
1873 Reference< XDispatch > xDispatch;
1874 MenuItemHandler* pMenuItemHandler = new MenuItemHandler(
1875 _nItemId,
1876 xSubMenuManager,
1877 xDispatch );
1878 pMenuItemHandler->aMenuItemURL = _sItemCommand;
1879 m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
1882 sal_uInt16 MenuBarManager::FillItemCommand(OUString& _rItemCommand, Menu* _pMenu,sal_uInt16 _nIndex) const
1884 sal_uInt16 nItemId = _pMenu->GetItemId( _nIndex );
1886 _rItemCommand = _pMenu->GetItemCommand( nItemId );
1887 if ( _rItemCommand.isEmpty() )
1889 _rItemCommand = "slot:" + OUString::number( nItemId );
1890 _pMenu->SetItemCommand( nItemId, _rItemCommand );
1892 return nItemId;
1894 void MenuBarManager::Init(const Reference< XFrame >& rFrame,Menu* pAddonMenu,bool bDelete,bool bDeleteChildren,bool _bHandlePopUp)
1896 m_bActive = false;
1897 m_bDeleteMenu = bDelete;
1898 m_bDeleteChildren = bDeleteChildren;
1899 m_pVCLMenu = pAddonMenu;
1900 m_xFrame = rFrame;
1901 m_bInitialized = false;
1902 m_bIsBookmarkMenu = true;
1903 m_bShowMenuImages = true;
1905 OUString aModuleIdentifier;
1906 m_xPopupMenuControllerFactory = frame::thePopupMenuControllerFactory::get(
1907 ::comphelper::getProcessComponentContext());
1909 Reference< XStatusListener > xStatusListener;
1910 Reference< XDispatch > xDispatch;
1911 sal_uInt16 nItemCount = pAddonMenu->GetItemCount();
1912 OUString aItemCommand;
1913 m_aMenuItemHandlerVector.reserve(nItemCount);
1914 for ( sal_uInt16 i = 0; i < nItemCount; i++ )
1916 sal_uInt16 nItemId = FillItemCommand(aItemCommand,pAddonMenu, i );
1918 PopupMenu* pPopupMenu = pAddonMenu->GetPopupMenu( nItemId );
1919 if ( pPopupMenu )
1921 Reference< XDispatchProvider > xDispatchProvider;
1922 MenuBarManager* pSubMenuManager = new MenuBarManager( m_xContext, rFrame, m_xURLTransformer,xDispatchProvider, aModuleIdentifier, pPopupMenu, !_bHandlePopUp && bDeleteChildren, !_bHandlePopUp && bDeleteChildren );
1924 Reference< XStatusListener > xSubMenuManager( static_cast< OWeakObject *>( pSubMenuManager ), UNO_QUERY );
1926 // store menu item command as we later have to know which menu is active (see Acivate handler)
1927 pSubMenuManager->m_aMenuItemCommand = aItemCommand;
1929 MenuItemHandler* pMenuItemHandler = new MenuItemHandler(
1930 nItemId,
1931 xSubMenuManager,
1932 xDispatch );
1933 m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
1935 else
1937 if ( pAddonMenu->GetItemType( i ) != MenuItemType::SEPARATOR )
1939 MenuAttributes* pAddonAttributes = reinterpret_cast<MenuAttributes *>(pAddonMenu->GetUserValue( nItemId ));
1940 MenuItemHandler* pMenuItemHandler = new MenuItemHandler( nItemId, xStatusListener, xDispatch );
1942 if ( pAddonAttributes )
1944 // read additional attributes from attributes struct and AddonMenu implementation will delete all attributes itself!!
1945 pMenuItemHandler->aTargetFrame = pAddonAttributes->aTargetFrame;
1948 pMenuItemHandler->aMenuItemURL = aItemCommand;
1949 if ( _bHandlePopUp )
1951 // Check if we have to create a popup menu for a uno based popup menu controller.
1952 // We have to set an empty popup menu into our menu structure so the controller also
1953 // works with inplace OLE.
1954 if ( m_xPopupMenuControllerFactory.is() &&
1955 m_xPopupMenuControllerFactory->hasController( aItemCommand, OUString() ))
1957 VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu;
1958 PopupMenu* pCtlPopupMenu = static_cast<PopupMenu *>(pVCLXPopupMenu->GetMenu());
1959 pAddonMenu->SetPopupMenu( pMenuItemHandler->nItemId, pCtlPopupMenu );
1960 pMenuItemHandler->xPopupMenu = Reference< com::sun::star::awt::XPopupMenu >( (OWeakObject *)pVCLXPopupMenu, UNO_QUERY );
1964 m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
1969 SetHdl();
1972 void MenuBarManager::SetHdl()
1974 m_pVCLMenu->SetHighlightHdl( LINK( this, MenuBarManager, Highlight ));
1975 m_pVCLMenu->SetActivateHdl( LINK( this, MenuBarManager, Activate ));
1976 m_pVCLMenu->SetDeactivateHdl( LINK( this, MenuBarManager, Deactivate ));
1977 m_pVCLMenu->SetSelectHdl( LINK( this, MenuBarManager, Select ));
1979 if ( !m_xURLTransformer.is() && m_xContext.is() )
1980 m_xURLTransformer.set( URLTransformer::create( m_xContext) );
1985 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */