LCOV - code coverage report
Current view: top level - framework/source/uielement - menubarmanager.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 580 968 59.9 %
Date: 2014-11-03 Functions: 38 57 66.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10