| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_framework.hxx" |
| |
| |
| //_________________________________________________________________________________________________________________ |
| // my own includes |
| //_________________________________________________________________________________________________________________ |
| #include <uielement/menubarmanager.hxx> |
| #include <framework/menuconfiguration.hxx> |
| #include <framework/bmkmenu.hxx> |
| #include <framework/addonmenu.hxx> |
| #include <framework/imageproducer.hxx> |
| #include <threadhelp/resetableguard.hxx> |
| #include "framework/addonsoptions.hxx" |
| #include <classes/fwkresid.hxx> |
| #include <classes/menumanager.hxx> |
| #include <framework/acceleratorinfo.hxx> |
| #include <helper/mischelper.hxx> |
| #include <framework/menuextensionsupplier.hxx> |
| #include <classes/resource.hrc> |
| #include <services.h> |
| |
| //_________________________________________________________________________________________________________________ |
| // interface includes |
| //_________________________________________________________________________________________________________________ |
| #include <com/sun/star/frame/XDispatch.hpp> |
| #include <com/sun/star/lang/XMultiServiceFactory.hpp> |
| #include <com/sun/star/lang/DisposedException.hpp> |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| #include <com/sun/star/frame/XFramesSupplier.hpp> |
| #include <com/sun/star/frame/XDesktop.hpp> |
| #include <com/sun/star/container/XEnumeration.hpp> |
| #include <com/sun/star/util/XStringWidth.hpp> |
| #include <com/sun/star/uno/XComponentContext.hpp> |
| #include <com/sun/star/lang/XMultiComponentFactory.hpp> |
| #include <com/sun/star/frame/XPopupMenuController.hpp> |
| #include <com/sun/star/frame/PopupMenuControllerFactory.hpp> |
| #ifndef _COM_SUN_STAR_LANG_XSYSTEMDEPENDENT_HPP_ |
| #include <com/sun/star/lang/SystemDependent.hpp> |
| #endif |
| #include <com/sun/star/ui/ItemType.hpp> |
| #include <com/sun/star/ui/ImageType.hpp> |
| #include <com/sun/star/container/XNameAccess.hpp> |
| #include <com/sun/star/frame/XModuleManager.hpp> |
| #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp> |
| #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp> |
| #include <com/sun/star/ui/ItemStyle.hpp> |
| #include <com/sun/star/frame/status/Visibility.hpp> |
| |
| //_________________________________________________________________________________________________________________ |
| // includes of other projects |
| //_________________________________________________________________________________________________________________ |
| #include <comphelper/processfactory.hxx> |
| #include <comphelper/extract.hxx> |
| #include <svtools/menuoptions.hxx> |
| #include <unotools/historyoptions.hxx> |
| #include <unotools/pathoptions.hxx> |
| #include <unotools/cmdoptions.hxx> |
| #include <unotools/localfilehelper.hxx> |
| #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ |
| #include <toolkit/unohlp.hxx> |
| #endif |
| #include <tools/urlobj.hxx> |
| #include <vcl/svapp.hxx> |
| #include <vcl/window.hxx> |
| #include <vos/mutex.hxx> |
| #include <vcl/svapp.hxx> |
| #include <osl/file.hxx> |
| #include <cppuhelper/implbase1.hxx> |
| #include <svtools/acceleratorexecute.hxx> |
| #include <rtl/logfile.hxx> |
| #include "svtools/miscopt.hxx" |
| #include <framework/addonmenu.hxx> |
| #include <uielement/menubarmerger.hxx> |
| #include <dispatch/uieventloghelper.hxx> |
| |
| // Be careful removing this "bad" construct. There are serious problems |
| // with #define STRICT and including windows.h. Changing this needs some |
| // redesign on other projects, too. Especially sal/main.h which defines |
| // HINSTANCE depending on STRCIT!!!!!!!!!!!!!!! |
| struct SystemMenuData |
| { |
| unsigned long nSize; |
| long hMenu; |
| }; |
| |
| //_________________________________________________________________________________________________________________ |
| // namespace |
| //_________________________________________________________________________________________________________________ |
| |
| using namespace ::cppu; |
| using namespace ::vos; |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::util; |
| using namespace ::com::sun::star::beans; |
| using namespace ::com::sun::star::frame; |
| using namespace ::com::sun::star::container; |
| using namespace ::com::sun::star::lang; |
| using namespace ::com::sun::star::frame; |
| using namespace ::com::sun::star::ui; |
| |
| static const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL"; |
| static const char ITEM_DESCRIPTOR_HELPURL[] = "HelpURL"; |
| static const char ITEM_DESCRIPTOR_CONTAINER[] = "ItemDescriptorContainer"; |
| static const char ITEM_DESCRIPTOR_LABEL[] = "Label"; |
| static const char ITEM_DESCRIPTOR_TYPE[] = "Type"; |
| static const char ITEM_DESCRIPTOR_MODULEIDENTIFIER[] = "ModuleIdentifier"; |
| static const char ITEM_DESCRIPTOR_DISPATCHPROVIDER[] = "DispatchProvider"; |
| static const char ITEM_DESCRIPTOR_STYLE[] = "Style"; |
| static const char ITEM_DESCRIPTOR_ISVISIBLE[] = "IsVisible"; |
| static const char ITEM_DESCRIPTOR_ENABLED[] = "Enabled"; |
| |
| static const sal_Int32 LEN_DESCRIPTOR_COMMANDURL = 10; |
| static const sal_Int32 LEN_DESCRIPTOR_HELPURL = 7; |
| static const sal_Int32 LEN_DESCRIPTOR_CONTAINER = 23; |
| static const sal_Int32 LEN_DESCRIPTOR_LABEL = 5; |
| static const sal_Int32 LEN_DESCRIPTOR_TYPE = 4; |
| static const sal_Int32 LEN_DESCRIPTOR_MODULEIDENTIFIER = 16; |
| static const sal_Int32 LEN_DESCRIPTOR_DISPATCHPROVIDER = 16; |
| static const sal_Int32 LEN_DESCRIPTOR_STYLE = 5; |
| static const sal_Int32 LEN_DESCRIPTOR_ISVISIBLE = 9; |
| static const sal_Int32 LEN_DESCRIPTOR_ENABLED = 7; |
| |
| const sal_uInt16 ADDONMENU_MERGE_ITEMID_START = 1500; |
| |
| class StringLength : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XStringWidth > |
| { |
| public: |
| StringLength() {} |
| virtual ~StringLength() {} |
| |
| // XStringWidth |
| sal_Int32 SAL_CALL queryStringWidth( const ::rtl::OUString& aString ) |
| throw (RuntimeException) |
| { |
| return aString.getLength(); |
| } |
| }; |
| |
| namespace framework |
| { |
| |
| // special menu ids/command ids for dynamic popup menus |
| #define SID_SFX_START 5000 |
| #define SID_NEWDOCDIRECT (SID_SFX_START + 537) |
| #define SID_AUTOPILOTMENU (SID_SFX_START + 1381) |
| #define SID_PICKLIST (SID_SFX_START + 510) |
| #define SID_MDIWINDOWLIST (SID_SFX_START + 610) |
| #define SID_ADDONLIST (SID_SFX_START + 1677) |
| #define SID_HELPMENU (SID_SFX_START + 410) |
| |
| #define SFX_REFERER_USER "private:user" |
| |
| const ::rtl::OUString aCmdHelpIndex( RTL_CONSTASCII_USTRINGPARAM( ".uno:HelpIndex" )); |
| const ::rtl::OUString aCmdToolsMenu( RTL_CONSTASCII_USTRINGPARAM( ".uno:ToolsMenu" )); |
| const ::rtl::OUString aCmdHelpMenu( RTL_CONSTASCII_USTRINGPARAM( ".uno:HelpMenu" )); |
| const ::rtl::OUString aSlotHelpMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5410" )); |
| |
| const ::rtl::OUString aSpecialFileMenu( RTL_CONSTASCII_USTRINGPARAM( "file" )); |
| const ::rtl::OUString aSpecialWindowMenu( RTL_CONSTASCII_USTRINGPARAM( "window" )); |
| const ::rtl::OUString aSlotSpecialFileMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5510" )); |
| const ::rtl::OUString aSlotSpecialWindowMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5610" )); |
| const ::rtl::OUString aSlotSpecialToolsMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:6677" )); |
| |
| // special uno commands for picklist and window list |
| const ::rtl::OUString aSpecialFileCommand( RTL_CONSTASCII_USTRINGPARAM( ".uno:PickList" )); |
| const ::rtl::OUString aSpecialWindowCommand( RTL_CONSTASCII_USTRINGPARAM( ".uno:WindowList" )); |
| |
| const ::rtl::OUString UNO_COMMAND( RTL_CONSTASCII_USTRINGPARAM( ".uno:" )); |
| |
| static sal_Int16 getImageTypeFromBools( sal_Bool bBig, sal_Bool bHighContrast ) |
| { |
| sal_Int16 n( 0 ); |
| if ( bBig ) |
| n |= ::com::sun::star::ui::ImageType::SIZE_LARGE; |
| if ( bHighContrast ) |
| n |= ::com::sun::star::ui::ImageType::COLOR_HIGHCONTRAST; |
| return n; |
| } |
| |
| // #110897# |
| MenuBarManager::MenuBarManager( |
| const Reference< XMultiServiceFactory >& xServiceFactory, |
| const Reference< XFrame >& rFrame, |
| const Reference< XURLTransformer >& _xURLTransformer, |
| const Reference< XDispatchProvider >& rDispatchProvider, |
| const rtl::OUString& rModuleIdentifier, |
| Menu* pMenu, sal_Bool bDelete, sal_Bool bDeleteChildren ) |
| : ThreadHelpBase( &Application::GetSolarMutex() ), OWeakObject() |
| , m_bDisposed( sal_False ) |
| , m_bRetrieveImages( sal_False ) |
| , m_bAcceleratorCfg( sal_False ) |
| , m_bModuleIdentified( sal_False ) |
| , m_aListenerContainer( m_aLock.getShareableOslMutex() ) |
| , mxServiceFactory(xServiceFactory) |
| , m_xURLTransformer(_xURLTransformer) |
| , m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MenuBarManager" ); |
| m_xPopupMenuControllerFactory = frame::PopupMenuControllerFactory::create( |
| ::comphelper::getProcessComponentContext() ); |
| FillMenuManager( pMenu, rFrame, rDispatchProvider, rModuleIdentifier, bDelete, bDeleteChildren ); |
| } |
| |
| // #110897# |
| MenuBarManager::MenuBarManager( |
| const Reference< XMultiServiceFactory >& xServiceFactory, |
| const Reference< XFrame >& rFrame, |
| const Reference< XURLTransformer >& _xURLTransformer, |
| AddonMenu* pAddonMenu, |
| sal_Bool bDelete, |
| sal_Bool bDeleteChildren ) |
| : ThreadHelpBase( &Application::GetSolarMutex() ) |
| , OWeakObject() |
| , m_bDisposed( sal_False ) |
| , m_bRetrieveImages( sal_True ) |
| , m_bAcceleratorCfg( sal_False ) |
| , m_bModuleIdentified( sal_False ) |
| , m_aListenerContainer( m_aLock.getShareableOslMutex() ) |
| , mxServiceFactory(xServiceFactory) |
| , m_xURLTransformer(_xURLTransformer) |
| , m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MenuBarManager" ); |
| Init(rFrame,pAddonMenu,bDelete,bDeleteChildren); |
| } |
| |
| // #110897# |
| MenuBarManager::MenuBarManager( |
| const Reference< XMultiServiceFactory >& xServiceFactory, |
| const Reference< XFrame >& rFrame, |
| const Reference< XURLTransformer >& _xURLTransformer, |
| AddonPopupMenu* pAddonPopupMenu, |
| sal_Bool bDelete, |
| sal_Bool bDeleteChildren ) |
| : ThreadHelpBase( &Application::GetSolarMutex() ) |
| , OWeakObject() |
| , m_bDisposed( sal_False ) |
| , m_bRetrieveImages( sal_True ) |
| , m_bAcceleratorCfg( sal_False ) |
| , m_bModuleIdentified( sal_False ) |
| , m_aListenerContainer( m_aLock.getShareableOslMutex() ) |
| , mxServiceFactory(xServiceFactory) |
| , m_xURLTransformer(_xURLTransformer) |
| , m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MenuBarManager" ); |
| Init(rFrame,pAddonPopupMenu,bDelete,bDeleteChildren,true); |
| } |
| |
| Any SAL_CALL MenuBarManager::queryInterface( const Type & rType ) throw ( RuntimeException ) |
| { |
| Any a = ::cppu::queryInterface( |
| rType , |
| SAL_STATIC_CAST( ::com::sun::star::frame::XStatusListener*, this ), |
| SAL_STATIC_CAST( ::com::sun::star::frame::XFrameActionListener*, this ), |
| SAL_STATIC_CAST( ::com::sun::star::ui::XUIConfigurationListener*, this ), |
| SAL_STATIC_CAST( XEventListener*, (XStatusListener *)this ), |
| SAL_STATIC_CAST( XComponent*, this ), |
| SAL_STATIC_CAST( ::com::sun::star::awt::XSystemDependentMenuPeer*, this )); |
| |
| if ( a.hasValue() ) |
| return a; |
| |
| return OWeakObject::queryInterface( rType ); |
| } |
| |
| |
| void SAL_CALL MenuBarManager::acquire() throw() |
| { |
| OWeakObject::acquire(); |
| } |
| |
| |
| void SAL_CALL MenuBarManager::release() throw() |
| { |
| OWeakObject::release(); |
| } |
| |
| |
| Any SAL_CALL MenuBarManager::getMenuHandle( const Sequence< sal_Int8 >& /*ProcessId*/, sal_Int16 SystemType ) throw (RuntimeException) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::getMenuHandle" ); |
| ResetableGuard aGuard( m_aLock ); |
| |
| if ( m_bDisposed ) |
| throw com::sun::star::lang::DisposedException(); |
| |
| Any a; |
| |
| if ( m_pVCLMenu ) |
| { |
| OGuard aSolarGuard( Application::GetSolarMutex() ); |
| |
| SystemMenuData aSystemMenuData; |
| aSystemMenuData.nSize = sizeof( SystemMenuData ); |
| |
| m_pVCLMenu->GetSystemMenuData( &aSystemMenuData ); |
| #ifdef QUARTZ |
| if( SystemType == SystemDependent::SYSTEM_MAC ) |
| { |
| } |
| #elif (defined WNT) |
| if( SystemType == SystemDependent::SYSTEM_WIN32 ) |
| { |
| a <<= (long) aSystemMenuData.hMenu; |
| } |
| #elif (defined UNX) |
| if( SystemType == SystemDependent::SYSTEM_XWINDOW ) |
| { |
| } |
| #endif |
| } |
| |
| return a; |
| } |
| |
| MenuBarManager::~MenuBarManager() |
| { |
| // stop asynchronous settings timer |
| m_xDeferedItemContainer.clear(); |
| m_aAsyncSettingsTimer.Stop(); |
| |
| DBG_ASSERT( OWeakObject::m_refCount == 0, "Who wants to delete an object with refcount > 0!" ); |
| } |
| |
| void MenuBarManager::Destroy() |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Destroy" ); |
| OGuard aGuard( Application::GetSolarMutex() ); |
| |
| if ( !m_bDisposed ) |
| { |
| // stop asynchronous settings timer and |
| // release defered item container reference |
| m_aAsyncSettingsTimer.Stop(); |
| m_xDeferedItemContainer.clear(); |
| RemoveListener(); |
| |
| std::vector< MenuItemHandler* >::iterator p; |
| for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) |
| { |
| MenuItemHandler* pItemHandler = *p; |
| pItemHandler->xMenuItemDispatch.clear(); |
| pItemHandler->xSubMenuManager.clear(); |
| pItemHandler->xPopupMenu.clear(); |
| delete pItemHandler; |
| } |
| m_aMenuItemHandlerVector.clear(); |
| |
| if ( m_bDeleteMenu ) |
| { |
| delete m_pVCLMenu; |
| m_pVCLMenu = 0; |
| } |
| } |
| } |
| |
| // XComponent |
| void SAL_CALL MenuBarManager::dispose() throw( RuntimeException ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::dispose" ); |
| Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY ); |
| |
| EventObject aEvent( xThis ); |
| m_aListenerContainer.disposeAndClear( aEvent ); |
| |
| { |
| ResetableGuard aGuard( m_aLock ); |
| // RemoveListener(); |
| Destroy(); |
| m_bDisposed = sal_True; |
| |
| if ( m_xDocImageManager.is() ) |
| { |
| try |
| { |
| m_xDocImageManager->removeConfigurationListener( |
| Reference< XUIConfigurationListener >( |
| static_cast< OWeakObject* >( this ), UNO_QUERY )); |
| } |
| catch ( Exception& ) |
| { |
| } |
| } |
| if ( m_xModuleImageManager.is() ) |
| { |
| try |
| { |
| m_xModuleImageManager->removeConfigurationListener( |
| Reference< XUIConfigurationListener >( |
| static_cast< OWeakObject* >( this ), UNO_QUERY )); |
| } |
| catch ( Exception& ) |
| { |
| } |
| } |
| m_xDocImageManager.clear(); |
| m_xModuleImageManager.clear(); |
| Reference< XComponent > xCompGAM( m_xGlobalAcceleratorManager, UNO_QUERY ); |
| if ( xCompGAM.is() ) |
| xCompGAM->dispose(); |
| m_xGlobalAcceleratorManager.clear(); |
| m_xModuleAcceleratorManager.clear(); |
| m_xDocAcceleratorManager.clear(); |
| m_xUICommandLabels.clear(); |
| m_xPopupMenuControllerFactory.clear(); |
| mxServiceFactory.clear(); |
| } |
| } |
| |
| void SAL_CALL MenuBarManager::addEventListener( const Reference< XEventListener >& xListener ) throw( RuntimeException ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::addEventListener" ); |
| ResetableGuard aGuard( m_aLock ); |
| |
| /* SAFE AREA ----------------------------------------------------------------------------------------------- */ |
| if ( m_bDisposed ) |
| throw DisposedException(); |
| |
| m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener ); |
| } |
| |
| void SAL_CALL MenuBarManager::removeEventListener( const Reference< XEventListener >& xListener ) throw( RuntimeException ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::removeEventListener" ); |
| ResetableGuard aGuard( m_aLock ); |
| /* SAFE AREA ----------------------------------------------------------------------------------------------- */ |
| m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener ); |
| } |
| |
| void SAL_CALL MenuBarManager::elementInserted( const ::com::sun::star::ui::ConfigurationEvent& Event ) |
| throw (RuntimeException) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::elementInserted" ); |
| ResetableGuard aGuard( m_aLock ); |
| |
| /* SAFE AREA ----------------------------------------------------------------------------------------------- */ |
| if ( m_bDisposed ) |
| return; |
| |
| sal_Int16 nImageType = sal_Int16(); |
| sal_Int16 nCurrentImageType = getImageTypeFromBools( sal_False, m_bWasHiContrast ); |
| if (( Event.aInfo >>= nImageType ) && |
| ( nImageType == nCurrentImageType )) |
| RequestImages(); |
| } |
| |
| void SAL_CALL MenuBarManager::elementRemoved( const ::com::sun::star::ui::ConfigurationEvent& Event ) |
| throw (RuntimeException) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::elementRemoved" ); |
| elementInserted(Event); |
| } |
| |
| void SAL_CALL MenuBarManager::elementReplaced( const ::com::sun::star::ui::ConfigurationEvent& Event ) |
| throw (RuntimeException) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::elementReplaced" ); |
| elementInserted(Event); |
| } |
| |
| // XFrameActionListener |
| void SAL_CALL MenuBarManager::frameAction( const FrameActionEvent& Action ) |
| throw ( RuntimeException ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::frameAction" ); |
| ResetableGuard aGuard( m_aLock ); |
| |
| if ( m_bDisposed ) |
| throw com::sun::star::lang::DisposedException(); |
| |
| if ( Action.Action == FrameAction_CONTEXT_CHANGED ) |
| { |
| std::vector< MenuItemHandler* >::iterator p; |
| for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) |
| { |
| // Clear dispatch reference as we will requery it later o |
| MenuItemHandler* pItemHandler = *p; |
| pItemHandler->xMenuItemDispatch.clear(); |
| } |
| } |
| } |
| |
| // XStatusListener |
| void SAL_CALL MenuBarManager::statusChanged( const FeatureStateEvent& Event ) |
| throw ( RuntimeException ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::statusChanged" ); |
| ::rtl::OUString aFeatureURL = Event.FeatureURL.Complete; |
| |
| OGuard aSolarGuard( Application::GetSolarMutex() ); |
| { |
| ResetableGuard aGuard( m_aLock ); |
| |
| if ( m_bDisposed ) |
| return; |
| |
| // We have to check all menu entries as there can be identical entries in a popup menu. |
| std::vector< MenuItemHandler* >::iterator p; |
| for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) |
| { |
| MenuItemHandler* pMenuItemHandler = *p; |
| if ( pMenuItemHandler->aMenuItemURL == aFeatureURL ) |
| { |
| sal_Bool bCheckmark( sal_False ); |
| sal_Bool bMenuItemEnabled( m_pVCLMenu->IsItemEnabled( pMenuItemHandler->nItemId )); |
| sal_Bool bEnabledItem( Event.IsEnabled ); |
| rtl::OUString aItemText; |
| status::Visibility aVisibilityStatus; |
| |
| #ifdef UNIX |
| // #b6673979# enable some slots hardly, because UNIX clipboard does not notify all changes |
| // Can be removed if follow up task will be fixed directly within applications. |
| if ( |
| ( pMenuItemHandler->aMenuItemURL.equalsAscii (".uno:Paste" ) ) || |
| ( pMenuItemHandler->aMenuItemURL.equalsAscii (".uno:PasteSpecial" ) ) || |
| ( pMenuItemHandler->aMenuItemURL.equalsAscii (".uno:PasteClipboard") ) // special for draw/impress |
| ) |
| bEnabledItem = sal_True; |
| #endif |
| |
| // Enable/disable item |
| if ( bEnabledItem != bMenuItemEnabled ) |
| m_pVCLMenu->EnableItem( pMenuItemHandler->nItemId, bEnabledItem ); |
| |
| if ( Event.State >>= bCheckmark ) |
| { |
| // Checkmark or RadioButton |
| m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, sal_True ); |
| m_pVCLMenu->CheckItem( pMenuItemHandler->nItemId, bCheckmark ); |
| |
| MenuItemBits nBits = m_pVCLMenu->GetItemBits( pMenuItemHandler->nItemId ); |
| //If not already designated RadioButton set as CheckMark |
| if (!(nBits & MIB_RADIOCHECK)) |
| m_pVCLMenu->SetItemBits( pMenuItemHandler->nItemId, nBits | MIB_CHECKABLE ); |
| } |
| else if ( Event.State >>= aItemText ) |
| { |
| // Replacement for place holders |
| if ( aItemText.matchAsciiL( "($1)", 4 )) |
| { |
| String aResStr = String( FwkResId( STR_UPDATEDOC )); |
| rtl::OUString aTmp( aResStr ); |
| aTmp += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " )); |
| aTmp += aItemText.copy( 4 ); |
| aItemText = aTmp; |
| } |
| else if ( aItemText.matchAsciiL( "($2)", 4 )) |
| { |
| String aResStr = String( FwkResId( STR_CLOSEDOC_ANDRETURN )); |
| rtl::OUString aTmp( aResStr ); |
| aTmp += aItemText.copy( 4 ); |
| aItemText = aTmp; |
| } |
| else if ( aItemText.matchAsciiL( "($3)", 4 )) |
| { |
| String aResStr = String( FwkResId( STR_SAVECOPYDOC )); |
| rtl::OUString aTmp( aResStr ); |
| aTmp += aItemText.copy( 4 ); |
| aItemText = aTmp; |
| } |
| |
| m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, sal_True ); |
| m_pVCLMenu->SetItemText( pMenuItemHandler->nItemId, aItemText ); |
| } |
| else if ( Event.State >>= aVisibilityStatus ) |
| { |
| // Visibility |
| m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, aVisibilityStatus.bVisible ); |
| } |
| else |
| m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, sal_True ); |
| } |
| |
| if ( Event.Requery ) |
| { |
| // Release dispatch object - will be requeried on the next activate! |
| pMenuItemHandler->xMenuItemDispatch.clear(); |
| } |
| } |
| } |
| } |
| |
| // Helper to retrieve own structure from item ID |
| MenuBarManager::MenuItemHandler* MenuBarManager::GetMenuItemHandler( sal_uInt16 nItemId ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::GetMenuItemHandler" ); |
| ResetableGuard aGuard( m_aLock ); |
| |
| std::vector< MenuItemHandler* >::iterator p; |
| for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) |
| { |
| MenuItemHandler* pItemHandler = *p; |
| if ( pItemHandler->nItemId == nItemId ) |
| return pItemHandler; |
| } |
| |
| return 0; |
| } |
| |
| // Helper to set request images flag |
| void MenuBarManager::RequestImages() |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RequestImages" ); |
| // must be locked from callee |
| // ResetableGuard aGuard( m_aLock ); |
| |
| m_bRetrieveImages = sal_True; |
| const sal_uInt32 nCount = m_aMenuItemHandlerVector.size(); |
| for ( sal_uInt32 i = 0; i < nCount; ++i ) |
| { |
| MenuItemHandler* pItemHandler = m_aMenuItemHandlerVector[i]; |
| if ( pItemHandler->xSubMenuManager.is() ) |
| { |
| MenuBarManager* pMenuBarManager = (MenuBarManager*)(pItemHandler->xSubMenuManager.get()); |
| pMenuBarManager->RequestImages(); |
| } |
| } |
| } |
| |
| // Helper to reset objects to prepare shutdown |
| void MenuBarManager::RemoveListener() |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RemoveListener" ); |
| ResetableGuard aGuard( m_aLock ); |
| |
| // Check service manager reference. Remove listener can be called due |
| // to a disposing call from the frame and therefore we already removed |
| // our listeners and release the service manager reference! |
| Reference< XMultiServiceFactory > xServiceManager = getServiceFactory(); |
| if ( xServiceManager.is() ) |
| { |
| std::vector< MenuItemHandler* >::iterator p; |
| for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) |
| { |
| MenuItemHandler* pItemHandler = *p; |
| if ( pItemHandler->xMenuItemDispatch.is() ) |
| { |
| URL aTargetURL; |
| aTargetURL.Complete = pItemHandler->aMenuItemURL; |
| m_xURLTransformer->parseStrict( aTargetURL ); |
| |
| pItemHandler->xMenuItemDispatch->removeStatusListener( |
| static_cast< XStatusListener* >( this ), aTargetURL ); |
| } |
| |
| pItemHandler->xMenuItemDispatch.clear(); |
| if ( pItemHandler->xPopupMenu.is() ) |
| { |
| { |
| // Remove popup menu from menu structure |
| OGuard aGuard2( Application::GetSolarMutex() ); |
| m_pVCLMenu->SetPopupMenu( pItemHandler->nItemId, 0 ); |
| } |
| |
| Reference< com::sun::star::lang::XEventListener > xEventListener( pItemHandler->xPopupMenuController, UNO_QUERY ); |
| if ( xEventListener.is() ) |
| { |
| EventObject aEventObject; |
| aEventObject.Source = (OWeakObject *)this; |
| xEventListener->disposing( aEventObject ); |
| } |
| |
| // We now provide a popup menu controller to external code. |
| // Therefore the life-time must be explicitly handled via |
| // dispose!! |
| try |
| { |
| Reference< XComponent > xComponent( pItemHandler->xPopupMenuController, UNO_QUERY ); |
| if ( xComponent.is() ) |
| xComponent->dispose(); |
| } |
| catch ( RuntimeException& ) |
| { |
| throw; |
| } |
| catch ( Exception& ) |
| { |
| } |
| |
| // Release references to controller and popup menu |
| pItemHandler->xPopupMenuController.clear(); |
| pItemHandler->xPopupMenu.clear(); |
| } |
| |
| Reference< XComponent > xComponent( pItemHandler->xSubMenuManager, UNO_QUERY ); |
| if ( xComponent.is() ) |
| xComponent->dispose(); |
| } |
| } |
| |
| try |
| { |
| if ( m_xFrame.is() ) |
| m_xFrame->removeFrameActionListener( Reference< XFrameActionListener >( |
| static_cast< OWeakObject* >( this ), UNO_QUERY )); |
| } |
| catch ( Exception& ) |
| { |
| } |
| |
| m_xFrame = 0; |
| } |
| |
| void SAL_CALL MenuBarManager::disposing( const EventObject& Source ) throw ( RuntimeException ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::disposing(evt)" ); |
| MenuItemHandler* pMenuItemDisposing = NULL; |
| |
| ResetableGuard aGuard( m_aLock ); |
| |
| std::vector< MenuItemHandler* >::iterator p; |
| for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) |
| { |
| MenuItemHandler* pMenuItemHandler = *p; |
| if ( pMenuItemHandler->xMenuItemDispatch.is() && |
| pMenuItemHandler->xMenuItemDispatch == Source.Source ) |
| { |
| // disposing called from menu item dispatcher, remove listener |
| pMenuItemDisposing = pMenuItemHandler; |
| break; |
| } |
| } |
| |
| if ( pMenuItemDisposing ) |
| { |
| // Release references to the dispatch object |
| URL aTargetURL; |
| aTargetURL.Complete = pMenuItemDisposing->aMenuItemURL; |
| |
| // Check reference of service manager before we use it. Reference could |
| // be cleared due to RemoveListener call! |
| Reference< XMultiServiceFactory > xServiceManager( getServiceFactory() ); |
| if ( xServiceManager.is() ) |
| { |
| m_xURLTransformer->parseStrict( aTargetURL ); |
| |
| pMenuItemDisposing->xMenuItemDispatch->removeStatusListener( |
| static_cast< XStatusListener* >( this ), aTargetURL ); |
| pMenuItemDisposing->xMenuItemDispatch = Reference< XDispatch >(); |
| if ( pMenuItemDisposing->xPopupMenu.is() ) |
| { |
| Reference< com::sun::star::lang::XEventListener > xEventListener( pMenuItemDisposing->xPopupMenuController, UNO_QUERY ); |
| if ( xEventListener.is() ) |
| xEventListener->disposing( Source ); |
| |
| { |
| // Remove popup menu from menu structure as we release our reference to |
| // the controller. |
| OGuard aGuard2( Application::GetSolarMutex() ); |
| m_pVCLMenu->SetPopupMenu( pMenuItemDisposing->nItemId, 0 ); |
| } |
| |
| pMenuItemDisposing->xPopupMenuController.clear(); |
| pMenuItemDisposing->xPopupMenu.clear(); |
| } |
| } |
| return; |
| } |
| else if ( Source.Source == m_xFrame ) |
| { |
| // Our frame gets disposed. We have to remove all our listeners |
| RemoveListener(); |
| } |
| else if ( Source.Source == Reference< XInterface >( m_xDocImageManager, UNO_QUERY )) |
| m_xDocImageManager.clear(); |
| else if ( Source.Source == Reference< XInterface >( m_xModuleImageManager, UNO_QUERY )) |
| m_xModuleImageManager.clear(); |
| } |
| |
| |
| void MenuBarManager::CheckAndAddMenuExtension( Menu* pMenu ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::CheckAndAddMenuExtension" ); |
| static const char REFERENCECOMMAND_AFTER[] = ".uno:HelpSupport"; |
| static const char REFERENCECOMMAND_BEFORE[] = ".uno:About"; |
| |
| // retrieve menu extension item |
| MenuExtensionItem aMenuItem( GetMenuExtension() ); |
| if (( aMenuItem.aURL.getLength() > 0 ) && |
| ( aMenuItem.aLabel.getLength() > 0 )) |
| { |
| // remove all old window list entries from menu |
| sal_uInt16 nNewItemId( 0 ); |
| sal_uInt16 nInsertPos( MENU_APPEND ); |
| sal_uInt16 nAfterPos( MENU_APPEND ); |
| sal_uInt16 nBeforePos( MENU_APPEND ); |
| String aCommandAfter( String::CreateFromAscii ( REFERENCECOMMAND_AFTER )); |
| String aCommandBefore( String::CreateFromAscii ( REFERENCECOMMAND_BEFORE )); |
| for ( sal_uInt16 n = 0; n < pMenu->GetItemCount(); n++ ) |
| { |
| sal_uInt16 nItemId = pMenu->GetItemId( n ); |
| nNewItemId = std::max( nItemId, nNewItemId ); |
| if ( pMenu->GetItemCommand( nItemId ) == aCommandAfter ) |
| nAfterPos = n+1; |
| else if ( pMenu->GetItemCommand( nItemId ) == aCommandBefore ) |
| nBeforePos = n; |
| } |
| ++nNewItemId; |
| |
| if ( nAfterPos != MENU_APPEND ) |
| nInsertPos = nAfterPos; |
| else if ( nBeforePos != MENU_APPEND ) |
| nInsertPos = nBeforePos; |
| |
| pMenu->InsertItem( nNewItemId, aMenuItem.aLabel, 0, nInsertPos ); |
| pMenu->SetItemCommand( nNewItemId, aMenuItem.aURL ); |
| } |
| } |
| |
| static void lcl_CheckForChildren(Menu* pMenu, sal_uInt16 nItemId) |
| { |
| if (PopupMenu* pThisPopup = pMenu->GetPopupMenu( nItemId )) |
| pMenu->EnableItem( nItemId, pThisPopup->GetItemCount() ? true : false ); |
| } |
| |
| //_________________________________________________________________________________________________________________ |
| // vcl handler |
| //_________________________________________________________________________________________________________________ |
| |
| IMPL_LINK( MenuBarManager, Activate, Menu *, pMenu ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Activate" ); |
| if ( pMenu == m_pVCLMenu ) |
| { |
| // set/unset hiding disabled menu entries |
| sal_Bool bDontHide = SvtMenuOptions().IsEntryHidingEnabled(); |
| const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings(); |
| sal_Bool bShowMenuImages = rSettings.GetUseImagesInMenus(); |
| sal_Bool bHasDisabledEntries = SvtCommandOptions().HasEntries( SvtCommandOptions::CMDOPTION_DISABLED ); |
| |
| ResetableGuard aGuard( m_aLock ); |
| |
| sal_uInt16 nFlag = pMenu->GetMenuFlags(); |
| if ( bDontHide ) |
| nFlag &= ~MENU_FLAG_HIDEDISABLEDENTRIES; |
| else |
| nFlag |= MENU_FLAG_HIDEDISABLEDENTRIES; |
| pMenu->SetMenuFlags( nFlag ); |
| |
| if ( m_bActive ) |
| return 0; |
| |
| m_bActive = sal_True; |
| |
| ::rtl::OUString aMenuCommand( m_aMenuItemCommand ); |
| if ( m_aMenuItemCommand == aSpecialWindowMenu || |
| m_aMenuItemCommand == aSlotSpecialWindowMenu || |
| aMenuCommand == aSpecialWindowCommand ) |
| MenuManager::UpdateSpecialWindowMenu( pMenu,getServiceFactory(),m_aLock ); |
| |
| // Check if some modes have changed so we have to update our menu images |
| sal_Bool bIsHiContrast = rSettings.GetHighContrastMode(); |
| sal_Int16 nSymbolsStyle = SvtMiscOptions().GetCurrentSymbolsStyle(); |
| |
| if ( m_bRetrieveImages || |
| m_bWasHiContrast != bIsHiContrast || |
| bShowMenuImages != m_bShowMenuImages || |
| nSymbolsStyle != m_nSymbolsStyle ) |
| { |
| // The mode changed so we have to replace all images |
| m_bWasHiContrast = bIsHiContrast; |
| m_bShowMenuImages = bShowMenuImages; |
| m_bRetrieveImages = sal_False; |
| m_nSymbolsStyle = nSymbolsStyle; |
| MenuManager::FillMenuImages(m_xFrame,pMenu,bIsHiContrast,bShowMenuImages); |
| } |
| |
| // Try to map commands to labels |
| for ( sal_uInt16 nPos = 0; nPos < pMenu->GetItemCount(); nPos++ ) |
| { |
| sal_uInt16 nItemId = pMenu->GetItemId( nPos ); |
| if (( pMenu->GetItemType( nPos ) != MENUITEM_SEPARATOR ) && |
| ( pMenu->GetItemText( nItemId ).Len() == 0 )) |
| { |
| String aCommand = pMenu->GetItemCommand( nItemId ); |
| if ( aCommand.Len() > 0 ) |
| pMenu->SetItemText( nItemId, RetrieveLabelFromCommand( aCommand )); |
| } |
| } |
| |
| // Try to set accelerator keys |
| { |
| RetrieveShortcuts( m_aMenuItemHandlerVector ); |
| std::vector< MenuItemHandler* >::iterator p; |
| for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) |
| { |
| MenuItemHandler* pMenuItemHandler = *p; |
| |
| // Set key code, workaround for hard-coded shortcut F1 mapped to .uno:HelpIndex |
| // Only non-popup menu items can have a short-cut |
| if ( pMenuItemHandler->aMenuItemURL == aCmdHelpIndex ) |
| { |
| KeyCode aKeyCode( KEY_F1 ); |
| pMenu->SetAccelKey( pMenuItemHandler->nItemId, aKeyCode ); |
| } |
| else if ( pMenu->GetPopupMenu( pMenuItemHandler->nItemId ) == 0 ) |
| pMenu->SetAccelKey( pMenuItemHandler->nItemId, pMenuItemHandler->aKeyCode ); |
| } |
| } |
| |
| URL aTargetURL; |
| |
| // Use provided dispatch provider => fallback to frame as dispatch provider |
| Reference< XDispatchProvider > xDispatchProvider; |
| if ( m_xDispatchProvider.is() ) |
| xDispatchProvider = m_xDispatchProvider; |
| else |
| xDispatchProvider = Reference< XDispatchProvider >( m_xFrame, UNO_QUERY ); |
| |
| if ( xDispatchProvider.is() ) |
| { |
| KeyCode aEmptyKeyCode; |
| SvtCommandOptions aCmdOptions; |
| std::vector< MenuItemHandler* >::iterator p; |
| for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) |
| { |
| MenuItemHandler* pMenuItemHandler = *p; |
| if ( pMenuItemHandler ) |
| { |
| if ( !pMenuItemHandler->xMenuItemDispatch.is() && |
| !pMenuItemHandler->xSubMenuManager.is() ) |
| { |
| // There is no dispatch mechanism for the special window list menu items, |
| // because they are handled directly through XFrame->activate!!! |
| // Don't update dispatches for special file menu items. |
| if ( !(( pMenuItemHandler->nItemId >= START_ITEMID_WINDOWLIST && |
| pMenuItemHandler->nItemId < END_ITEMID_WINDOWLIST ))) |
| { |
| Reference< XDispatch > xMenuItemDispatch; |
| |
| ::rtl::OUString aItemCommand = pMenu->GetItemCommand( pMenuItemHandler->nItemId ); |
| if ( !aItemCommand.getLength() ) |
| { |
| aItemCommand = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:" )); |
| aItemCommand += ::rtl::OUString::valueOf( (sal_Int32)pMenuItemHandler->nItemId ); |
| pMenu->SetItemCommand( pMenuItemHandler->nItemId, aItemCommand ); |
| } |
| |
| aTargetURL.Complete = aItemCommand; |
| |
| m_xURLTransformer->parseStrict( aTargetURL ); |
| |
| if ( bHasDisabledEntries ) |
| { |
| if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aTargetURL.Path )) |
| pMenu->HideItem( pMenuItemHandler->nItemId ); |
| } |
| |
| if ( m_bIsBookmarkMenu ) |
| xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, pMenuItemHandler->aTargetFrame, 0 ); |
| else |
| xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); |
| |
| sal_Bool bPopupMenu( sal_False ); |
| if ( !pMenuItemHandler->xPopupMenuController.is() && |
| m_xPopupMenuControllerFactory->hasController( aItemCommand, rtl::OUString() )) |
| { |
| bPopupMenu = CreatePopupMenuController( pMenuItemHandler ); |
| } |
| else if ( pMenuItemHandler->xPopupMenuController.is() ) |
| { |
| // Force update of popup menu |
| pMenuItemHandler->xPopupMenuController->updatePopupMenu(); |
| bPopupMenu = sal_True; |
| if (PopupMenu* pThisPopup = pMenu->GetPopupMenu( pMenuItemHandler->nItemId )) |
| pMenu->EnableItem( pMenuItemHandler->nItemId, pThisPopup->GetItemCount() ? true : false ); |
| } |
| |
| lcl_CheckForChildren(pMenu, pMenuItemHandler->nItemId); |
| |
| if ( xMenuItemDispatch.is() ) |
| { |
| pMenuItemHandler->xMenuItemDispatch = xMenuItemDispatch; |
| pMenuItemHandler->aMenuItemURL = aTargetURL.Complete; |
| |
| if ( !bPopupMenu ) |
| { |
| // We need only an update to reflect the current state |
| xMenuItemDispatch->addStatusListener( static_cast< XStatusListener* >( this ), aTargetURL ); |
| xMenuItemDispatch->removeStatusListener( static_cast< XStatusListener* >( this ), aTargetURL ); |
| } |
| } |
| else if ( !bPopupMenu ) |
| pMenu->EnableItem( pMenuItemHandler->nItemId, sal_False ); |
| } |
| } |
| else if ( pMenuItemHandler->xPopupMenuController.is() ) |
| { |
| // Force update of popup menu |
| pMenuItemHandler->xPopupMenuController->updatePopupMenu(); |
| lcl_CheckForChildren(pMenu, pMenuItemHandler->nItemId); |
| } |
| else if ( pMenuItemHandler->xMenuItemDispatch.is() ) |
| { |
| // We need an update to reflect the current state |
| try |
| { |
| aTargetURL.Complete = pMenuItemHandler->aMenuItemURL; |
| m_xURLTransformer->parseStrict( aTargetURL ); |
| |
| pMenuItemHandler->xMenuItemDispatch->addStatusListener( |
| static_cast< XStatusListener* >( this ), aTargetURL ); |
| pMenuItemHandler->xMenuItemDispatch->removeStatusListener( |
| static_cast< XStatusListener* >( this ), aTargetURL ); |
| } |
| catch ( Exception& ) |
| { |
| } |
| } |
| else if ( pMenuItemHandler->xSubMenuManager.is() ) |
| lcl_CheckForChildren(pMenu, pMenuItemHandler->nItemId); |
| } |
| } |
| } |
| } |
| |
| return 1; |
| } |
| |
| |
| IMPL_LINK( MenuBarManager, Deactivate, Menu *, pMenu ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Deactivate" ); |
| if ( pMenu == m_pVCLMenu ) |
| { |
| m_bActive = sal_False; |
| if ( pMenu->IsMenuBar() && m_xDeferedItemContainer.is() ) |
| { |
| // Start timer to handle settings asynchronous |
| // Changing the menu inside this handler leads to |
| // a crash under X! |
| m_aAsyncSettingsTimer.SetTimeoutHdl(LINK(this, MenuBarManager, AsyncSettingsHdl)); |
| m_aAsyncSettingsTimer.SetTimeout(10); |
| m_aAsyncSettingsTimer.Start(); |
| } |
| } |
| |
| return 1; |
| } |
| |
| IMPL_LINK( MenuBarManager, AsyncSettingsHdl, Timer*,) |
| { |
| OGuard aGuard( Application::GetSolarMutex() ); |
| Reference< XInterface > xSelfHold( |
| static_cast< ::cppu::OWeakObject* >( this ), UNO_QUERY_THROW ); |
| |
| m_aAsyncSettingsTimer.Stop(); |
| if ( !m_bActive && m_xDeferedItemContainer.is() ) |
| { |
| SetItemContainer( m_xDeferedItemContainer ); |
| m_xDeferedItemContainer.clear(); |
| } |
| |
| return 0; |
| } |
| |
| IMPL_LINK( MenuBarManager, Select, Menu *, pMenu ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Select" ); |
| URL aTargetURL; |
| Sequence<PropertyValue> aArgs; |
| Reference< XDispatch > xDispatch; |
| |
| { |
| ResetableGuard aGuard( m_aLock ); |
| |
| sal_uInt16 nCurItemId = pMenu->GetCurItemId(); |
| sal_uInt16 nCurPos = pMenu->GetItemPos( nCurItemId ); |
| if ( pMenu == m_pVCLMenu && |
| pMenu->GetItemType( nCurPos ) != MENUITEM_SEPARATOR ) |
| { |
| if ( nCurItemId >= START_ITEMID_WINDOWLIST && |
| nCurItemId <= END_ITEMID_WINDOWLIST ) |
| { |
| // window list menu item selected |
| |
| // #110897# |
| // Reference< XFramesSupplier > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( DESKTOP_SERVICE ), UNO_QUERY ); |
| Reference< XFramesSupplier > xDesktop( getServiceFactory()->createInstance( SERVICENAME_DESKTOP ), UNO_QUERY ); |
| |
| if ( xDesktop.is() ) |
| { |
| sal_uInt16 nTaskId = START_ITEMID_WINDOWLIST; |
| Reference< XIndexAccess > xList( xDesktop->getFrames(), UNO_QUERY ); |
| sal_Int32 nCount = xList->getCount(); |
| for ( sal_Int32 i=0; i<nCount; ++i ) |
| { |
| Reference< XFrame > xFrame; |
| xList->getByIndex(i) >>= xFrame; |
| if ( xFrame.is() && nTaskId == nCurItemId ) |
| { |
| Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() ); |
| pWin->GrabFocus(); |
| pWin->ToTop( TOTOP_RESTOREWHENMIN ); |
| break; |
| } |
| |
| nTaskId++; |
| } |
| } |
| } |
| else |
| { |
| MenuItemHandler* pMenuItemHandler = GetMenuItemHandler( nCurItemId ); |
| if ( pMenuItemHandler && pMenuItemHandler->xMenuItemDispatch.is() ) |
| { |
| aTargetURL.Complete = pMenuItemHandler->aMenuItemURL; |
| m_xURLTransformer->parseStrict( aTargetURL ); |
| |
| if ( m_bIsBookmarkMenu ) |
| { |
| // bookmark menu item selected |
| aArgs.realloc( 1 ); |
| aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" )); |
| aArgs[0].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SFX_REFERER_USER )); |
| } |
| |
| xDispatch = pMenuItemHandler->xMenuItemDispatch; |
| } |
| } |
| } |
| } |
| |
| if ( xDispatch.is() ) |
| { |
| const sal_uInt32 nRef = Application::ReleaseSolarMutex(); |
| if(::comphelper::UiEventsLogger::isEnabled()) //#i88653# |
| UiEventLogHelper(::rtl::OUString::createFromAscii("MenuBarManager")).log(getServiceFactory(), m_xFrame, aTargetURL, aArgs); |
| xDispatch->dispatch( aTargetURL, aArgs ); |
| Application::AcquireSolarMutex( nRef ); |
| } |
| |
| return 1; |
| } |
| |
| |
| IMPL_LINK( MenuBarManager, Highlight, Menu *, EMPTYARG ) |
| { |
| return 0; |
| } |
| |
| sal_Bool MenuBarManager::MustBeHidden( PopupMenu* pPopupMenu, const Reference< XURLTransformer >& rTransformer ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MustBeHidden" ); |
| if ( pPopupMenu ) |
| { |
| URL aTargetURL; |
| SvtCommandOptions aCmdOptions; |
| |
| sal_uInt16 nCount = pPopupMenu->GetItemCount(); |
| sal_uInt16 nHideCount( 0 ); |
| |
| for ( sal_uInt16 i = 0; i < nCount; i++ ) |
| { |
| sal_uInt16 nId = pPopupMenu->GetItemId( i ); |
| if ( nId > 0 ) |
| { |
| PopupMenu* pSubPopupMenu = pPopupMenu->GetPopupMenu( nId ); |
| if ( pSubPopupMenu ) |
| { |
| if ( MustBeHidden( pSubPopupMenu, rTransformer )) |
| { |
| pPopupMenu->HideItem( nId ); |
| ++nHideCount; |
| } |
| } |
| else |
| { |
| aTargetURL.Complete = pPopupMenu->GetItemCommand( nId ); |
| rTransformer->parseStrict( aTargetURL ); |
| |
| if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aTargetURL.Path )) |
| ++nHideCount; |
| } |
| } |
| else |
| ++nHideCount; |
| } |
| |
| return ( nCount == nHideCount ); |
| } |
| |
| return sal_True; |
| } |
| String MenuBarManager::RetrieveLabelFromCommand( const String& aCmdURL ) |
| { |
| return framework::RetrieveLabelFromCommand(aCmdURL,mxServiceFactory,m_xUICommandLabels,m_xFrame,m_aModuleIdentifier,m_bModuleIdentified,"Label"); |
| } |
| |
| |
| |
| sal_Bool MenuBarManager::CreatePopupMenuController( MenuItemHandler* pMenuItemHandler ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::CreatePopupMenuController" ); |
| rtl::OUString aItemCommand( pMenuItemHandler->aMenuItemURL ); |
| |
| // Try instanciate a popup menu controller. It is stored in the menu item handler. |
| if ( !m_xPopupMenuControllerFactory.is() ) |
| return sal_False; |
| |
| Sequence< Any > aSeq( 2 ); |
| PropertyValue aPropValue; |
| |
| aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleIdentifier" )); |
| aPropValue.Value <<= m_aModuleIdentifier; |
| aSeq[0] <<= aPropValue; |
| aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" )); |
| aPropValue.Value <<= m_xFrame; |
| aSeq[1] <<= aPropValue; |
| |
| Reference< XComponentContext > xComponentContext; |
| Reference< XPropertySet > xProps( getServiceFactory(), UNO_QUERY ); |
| |
| xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= |
| xComponentContext; |
| |
| Reference< XPopupMenuController > xPopupMenuController( |
| m_xPopupMenuControllerFactory->createInstanceWithArgumentsAndContext( |
| aItemCommand, |
| aSeq, |
| xComponentContext ), |
| UNO_QUERY ); |
| |
| if ( xPopupMenuController.is() ) |
| { |
| // Provide our awt popup menu to the popup menu controller |
| pMenuItemHandler->xPopupMenuController = xPopupMenuController; |
| xPopupMenuController->setPopupMenu( pMenuItemHandler->xPopupMenu ); |
| return sal_True; |
| } |
| |
| return sal_False; |
| } |
| |
| void MenuBarManager::FillMenuManager( Menu* pMenu, const Reference< XFrame >& rFrame, const Reference< XDispatchProvider >& rDispatchProvider, const rtl::OUString& rModuleIdentifier, sal_Bool bDelete, sal_Bool bDeleteChildren ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillMenuManager" ); |
| m_xFrame = rFrame; |
| m_bActive = sal_False; |
| m_bDeleteMenu = bDelete; |
| m_bDeleteChildren = bDeleteChildren; |
| m_pVCLMenu = pMenu; |
| m_bInitialized = sal_False; |
| m_bIsBookmarkMenu = sal_False; |
| m_xDispatchProvider = rDispatchProvider; |
| |
| const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings(); |
| m_bWasHiContrast = rSettings.GetHighContrastMode(); |
| m_bShowMenuImages = rSettings.GetUseImagesInMenus(); |
| m_bRetrieveImages = sal_False; |
| |
| sal_Int32 nAddonsURLPrefixLength = ADDONSPOPUPMENU_URL_PREFIX.getLength(); |
| |
| // Add root as ui configuration listener |
| RetrieveImageManagers(); |
| |
| if ( pMenu->IsMenuBar() && rFrame.is() ) |
| { |
| // First merge all addon popup menus into our structure |
| sal_uInt16 nPos = 0; |
| for ( nPos = 0; nPos < pMenu->GetItemCount(); nPos++ ) |
| { |
| sal_uInt16 nItemId = pMenu->GetItemId( nPos ); |
| ::rtl::OUString aCommand = pMenu->GetItemCommand( nItemId ); |
| if ( nItemId == SID_MDIWINDOWLIST || |
| aCommand == aSpecialWindowCommand ) |
| { |
| // Retrieve addon popup menus and add them to our menu bar |
| framework::AddonMenuManager::MergeAddonPopupMenus( rFrame, nPos, (MenuBar *)pMenu, mxServiceFactory ); |
| break; |
| } |
| } |
| |
| // Merge the Add-Ons help menu items into the Office help menu |
| framework::AddonMenuManager::MergeAddonHelpMenu( rFrame, (MenuBar *)pMenu, mxServiceFactory ); |
| } |
| |
| String aEmpty; |
| sal_Bool bAccessibilityEnabled( Application::GetSettings().GetMiscSettings().GetEnableATToolSupport() ); |
| sal_uInt16 nItemCount = pMenu->GetItemCount(); |
| ::rtl::OUString aItemCommand; |
| m_aMenuItemHandlerVector.reserve(nItemCount); |
| for ( sal_uInt16 i = 0; i < nItemCount; i++ ) |
| { |
| sal_uInt16 nItemId = FillItemCommand(aItemCommand,pMenu, i ); |
| |
| // Set module identifier when provided from outside |
| if ( rModuleIdentifier.getLength() > 0 ) |
| { |
| m_aModuleIdentifier = rModuleIdentifier; |
| m_bModuleIdentified = sal_True; |
| } |
| |
| if (( pMenu->IsMenuBar() || bAccessibilityEnabled ) && |
| ( pMenu->GetItemText( nItemId ).Len() == 0 )) |
| { |
| if ( aItemCommand.getLength() > 0 ) |
| pMenu->SetItemText( nItemId, RetrieveLabelFromCommand( aItemCommand )); |
| } |
| |
| Reference< XDispatch > xDispatch; |
| Reference< XStatusListener > xStatusListener; |
| PopupMenu* pPopup = pMenu->GetPopupMenu( nItemId ); |
| bool bItemShowMenuImages = m_bShowMenuImages; |
| MenuItemBits nBits = pMenu->GetItemBits( nItemId ); |
| // overwrite the show icons on menu option? |
| if ( nBits ) |
| bItemShowMenuImages = ( ( nBits & MIB_ICON ) == MIB_ICON ); |
| if ( pPopup ) |
| { |
| // Retrieve module identifier from Help Command entry |
| rtl::OUString aModuleIdentifier( rModuleIdentifier ); |
| if ( pMenu->GetHelpCommand( nItemId ).Len() > 0 ) |
| { |
| aModuleIdentifier = pMenu->GetHelpCommand( nItemId ); |
| pMenu->SetHelpCommand( nItemId, aEmpty ); |
| } |
| |
| if ( m_xPopupMenuControllerFactory.is() && |
| pPopup->GetItemCount() == 0 && |
| m_xPopupMenuControllerFactory->hasController( aItemCommand, rtl::OUString() ) |
| ) |
| { |
| // Check if we have to create a popup menu for a uno based popup menu controller. |
| // We have to set an empty popup menu into our menu structure so the controller also |
| // works with inplace OLE. Remove old dummy popup menu! |
| MenuItemHandler* pItemHandler = new MenuItemHandler( nItemId, xStatusListener, xDispatch ); |
| VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu; |
| PopupMenu* pNewPopupMenu = (PopupMenu *)pVCLXPopupMenu->GetMenu(); |
| pMenu->SetPopupMenu( nItemId, pNewPopupMenu ); |
| pItemHandler->xPopupMenu = Reference< com::sun::star::awt::XPopupMenu >( (OWeakObject *)pVCLXPopupMenu, UNO_QUERY ); |
| pItemHandler->aMenuItemURL = aItemCommand; |
| m_aMenuItemHandlerVector.push_back( pItemHandler ); |
| delete pPopup; |
| |
| if ( bAccessibilityEnabled ) |
| { |
| if ( CreatePopupMenuController( pItemHandler )) |
| pItemHandler->xPopupMenuController->updatePopupMenu(); |
| } |
| lcl_CheckForChildren(pMenu, nItemId); |
| } |
| else if (( aItemCommand.getLength() > nAddonsURLPrefixLength ) && |
| ( aItemCommand.indexOf( ADDONSPOPUPMENU_URL_PREFIX ) == 0 )) |
| { |
| // A special addon popup menu, must be created with a different ctor |
| // #110897# |
| MenuBarManager* pSubMenuManager = new MenuBarManager( getServiceFactory(), m_xFrame, m_xURLTransformer,(AddonPopupMenu *)pPopup, bDeleteChildren, bDeleteChildren ); |
| AddMenu(pSubMenuManager,aItemCommand,nItemId); |
| } |
| else |
| { |
| Reference< XDispatchProvider > xPopupMenuDispatchProvider( rDispatchProvider ); |
| |
| // Retrieve possible attributes struct |
| MenuConfiguration::Attributes* pAttributes = (MenuConfiguration::Attributes *)(pMenu->GetUserValue( nItemId )); |
| if ( pAttributes ) |
| xPopupMenuDispatchProvider = pAttributes->xDispatchProvider; |
| |
| // Check if this is the help menu. Add menu item if needed |
| if ( nItemId == SID_HELPMENU || aItemCommand == aSlotHelpMenu || aItemCommand == aCmdHelpMenu ) |
| { |
| // Check if this is the help menu. Add menu item if needed |
| CheckAndAddMenuExtension( pPopup ); |
| } |
| else if (( nItemId == SID_ADDONLIST || aItemCommand == aSlotSpecialToolsMenu || aItemCommand == aCmdToolsMenu ) && |
| AddonMenuManager::HasAddonMenuElements() ) |
| { |
| // Create addon popup menu if there exist elements and this is the tools popup menu |
| sal_uInt16 nCount = 0; |
| AddonMenu* pSubMenu = AddonMenuManager::CreateAddonMenu( rFrame, mxServiceFactory ); |
| if ( pSubMenu && ( pSubMenu->GetItemCount() > 0 )) |
| { |
| if ( pPopup->GetItemType( nCount-1 ) != MENUITEM_SEPARATOR ) |
| pPopup->InsertSeparator(); |
| |
| // Use resource to load popup menu title |
| String aAddonsStrRes = String( FwkResId( STR_MENU_ADDONS )); |
| pPopup->InsertItem( ITEMID_ADDONLIST, aAddonsStrRes ); |
| pPopup->SetPopupMenu( ITEMID_ADDONLIST, pSubMenu ); |
| |
| // Set item command for popup menu to enable it for GetImageFromURL |
| const ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" )); |
| ::rtl::OUString aNewItemCommand( aSlotString ); |
| aNewItemCommand += ::rtl::OUString::valueOf( (sal_Int32)ITEMID_ADDONLIST ); |
| pPopup->SetItemCommand( ITEMID_ADDONLIST, aNewItemCommand ); |
| } |
| else |
| delete pSubMenu; |
| } |
| |
| if ( nItemId == ITEMID_ADDONLIST ) |
| { |
| // Create control structure within the "Tools" sub menu for the Add-Ons popup menu |
| // #110897# MenuBarManager* pSubMenuManager = new MenuBarManager( rFrame, pSubMenu, sal_True, sal_False ); |
| AddonMenu* pSubMenu = dynamic_cast< AddonMenu* >( pPopup ); |
| if ( pSubMenu ) |
| { |
| MenuBarManager* pSubMenuManager = new MenuBarManager( getServiceFactory(), m_xFrame, m_xURLTransformer,pSubMenu, sal_True, sal_False ); |
| AddMenu(pSubMenuManager,aItemCommand,nItemId); |
| pSubMenuManager->m_aMenuItemCommand = ::rtl::OUString(); |
| |
| // Set image for the addon popup menu item |
| if ( bItemShowMenuImages && !pPopup->GetItemImage( ITEMID_ADDONLIST )) |
| { |
| Reference< XFrame > xTemp( rFrame ); |
| Image aImage = GetImageFromURL( xTemp, aItemCommand, sal_False, m_bWasHiContrast ); |
| if ( !!aImage ) |
| pPopup->SetItemImage( ITEMID_ADDONLIST, aImage ); |
| } |
| } |
| } |
| else |
| { |
| // #110897# MenuBarManager* pSubMenuManager = new MenuBarManager( rFrame, pPopupMenu, bDeleteChildren, bDeleteChildren ); |
| MenuBarManager* pSubMenuMgr = new MenuBarManager( getServiceFactory(), rFrame, m_xURLTransformer,rDispatchProvider, aModuleIdentifier, pPopup, bDeleteChildren, bDeleteChildren ); |
| AddMenu(pSubMenuMgr,aItemCommand,nItemId); |
| } |
| } |
| } |
| else if ( pMenu->GetItemType( i ) != MENUITEM_SEPARATOR ) |
| { |
| if ( bItemShowMenuImages ) |
| { |
| if ( AddonMenuManager::IsAddonMenuId( nItemId )) |
| { |
| // Add-Ons uses images from different places |
| Image aImage; |
| rtl::OUString aImageId; |
| |
| MenuConfiguration::Attributes* pMenuAttributes = |
| (MenuConfiguration::Attributes*)pMenu->GetUserValue( nItemId ); |
| |
| if ( pMenuAttributes && pMenuAttributes->aImageId.getLength() > 0 ) |
| { |
| // Retrieve image id from menu attributes |
| aImage = GetImageFromURL( m_xFrame, aImageId, sal_False, m_bWasHiContrast ); |
| } |
| |
| if ( !aImage ) |
| { |
| aImage = GetImageFromURL( m_xFrame, aItemCommand, sal_False, m_bWasHiContrast ); |
| if ( !aImage ) |
| aImage = AddonsOptions().GetImageFromURL( aItemCommand, sal_False, m_bWasHiContrast ); |
| } |
| |
| if ( !!aImage ) |
| pMenu->SetItemImage( nItemId, aImage ); |
| else |
| m_bRetrieveImages = sal_True; |
| } |
| m_bRetrieveImages = sal_True; |
| } |
| |
| MenuItemHandler* pItemHandler = new MenuItemHandler( nItemId, xStatusListener, xDispatch ); |
| pItemHandler->aMenuItemURL = aItemCommand; |
| |
| if ( m_xPopupMenuControllerFactory.is() && |
| m_xPopupMenuControllerFactory->hasController( aItemCommand, rtl::OUString() )) |
| { |
| // Check if we have to create a popup menu for a uno based popup menu controller. |
| // We have to set an empty popup menu into our menu structure so the controller also |
| // works with inplace OLE. |
| VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu; |
| PopupMenu* pPopupMenu = (PopupMenu *)pVCLXPopupMenu->GetMenu(); |
| pMenu->SetPopupMenu( pItemHandler->nItemId, pPopupMenu ); |
| pItemHandler->xPopupMenu = Reference< com::sun::star::awt::XPopupMenu >( (OWeakObject *)pVCLXPopupMenu, UNO_QUERY ); |
| |
| if ( bAccessibilityEnabled && CreatePopupMenuController( pItemHandler ) ) |
| { |
| pItemHandler->xPopupMenuController->updatePopupMenu(); |
| } |
| |
| lcl_CheckForChildren(pMenu, pItemHandler->nItemId); |
| } |
| |
| m_aMenuItemHandlerVector.push_back( pItemHandler ); |
| } |
| } |
| |
| if ( bAccessibilityEnabled ) |
| { |
| RetrieveShortcuts( m_aMenuItemHandlerVector ); |
| std::vector< MenuItemHandler* >::iterator p; |
| for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) |
| { |
| MenuItemHandler* pMenuItemHandler = *p; |
| |
| // Set key code, workaround for hard-coded shortcut F1 mapped to .uno:HelpIndex |
| // Only non-popup menu items can have a short-cut |
| if ( pMenuItemHandler->aMenuItemURL == aCmdHelpIndex ) |
| { |
| KeyCode aKeyCode( KEY_F1 ); |
| pMenu->SetAccelKey( pMenuItemHandler->nItemId, aKeyCode ); |
| } |
| else if ( pMenu->GetPopupMenu( pMenuItemHandler->nItemId ) == 0 ) |
| pMenu->SetAccelKey( pMenuItemHandler->nItemId, pMenuItemHandler->aKeyCode ); |
| } |
| } |
| |
| SetHdl(); |
| } |
| |
| void MenuBarManager::impl_RetrieveShortcutsFromConfiguration( |
| const Reference< XAcceleratorConfiguration >& rAccelCfg, |
| const Sequence< rtl::OUString >& rCommands, |
| std::vector< MenuItemHandler* >& aMenuShortCuts ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::impl_RetrieveShortcutsFromConfiguration" ); |
| if ( rAccelCfg.is() ) |
| { |
| try |
| { |
| com::sun::star::awt::KeyEvent aKeyEvent; |
| Sequence< Any > aSeqKeyCode = rAccelCfg->getPreferredKeyEventsForCommandList( rCommands ); |
| for ( sal_Int32 i = 0; i < aSeqKeyCode.getLength(); i++ ) |
| { |
| if ( aSeqKeyCode[i] >>= aKeyEvent ) |
| aMenuShortCuts[i]->aKeyCode = svt::AcceleratorExecute::st_AWTKey2VCLKey( aKeyEvent ); |
| } |
| } |
| catch ( IllegalArgumentException& ) |
| { |
| } |
| } |
| } |
| |
| void MenuBarManager::RetrieveShortcuts( std::vector< MenuItemHandler* >& aMenuShortCuts ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RetrieveShortcuts" ); |
| if ( !m_bModuleIdentified ) |
| { |
| m_bModuleIdentified = sal_True; |
| Reference< XModuleManager > xModuleManager; |
| xModuleManager = Reference< XModuleManager >( getServiceFactory()->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW ); |
| |
| try |
| { |
| m_aModuleIdentifier = xModuleManager->identify( m_xFrame ); |
| } |
| catch( Exception& ) |
| { |
| } |
| } |
| |
| if ( m_bModuleIdentified ) |
| { |
| Reference< XAcceleratorConfiguration > xDocAccelCfg( m_xDocAcceleratorManager ); |
| Reference< XAcceleratorConfiguration > xModuleAccelCfg( m_xModuleAcceleratorManager ); |
| Reference< XAcceleratorConfiguration > xGlobalAccelCfg( m_xGlobalAcceleratorManager ); |
| |
| if ( !m_bAcceleratorCfg ) |
| { |
| // Retrieve references on demand |
| m_bAcceleratorCfg = sal_True; |
| if ( !xDocAccelCfg.is() ) |
| { |
| Reference< XController > xController = m_xFrame->getController(); |
| Reference< XModel > xModel; |
| if ( xController.is() ) |
| { |
| xModel = xController->getModel(); |
| if ( xModel.is() ) |
| { |
| Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY ); |
| if ( xSupplier.is() ) |
| { |
| Reference< XUIConfigurationManager > xDocUICfgMgr( xSupplier->getUIConfigurationManager(), UNO_QUERY ); |
| if ( xDocUICfgMgr.is() ) |
| { |
| xDocAccelCfg = Reference< XAcceleratorConfiguration >( xDocUICfgMgr->getShortCutManager(), UNO_QUERY ); |
| m_xDocAcceleratorManager = xDocAccelCfg; |
| } |
| } |
| } |
| } |
| } |
| |
| if ( !xModuleAccelCfg.is() ) |
| { |
| Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier( getServiceFactory()->createInstance( |
| SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ), |
| UNO_QUERY ); |
| try |
| { |
| Reference< XUIConfigurationManager > xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier ); |
| if ( xUICfgMgr.is() ) |
| { |
| xModuleAccelCfg = Reference< XAcceleratorConfiguration >( xUICfgMgr->getShortCutManager(), UNO_QUERY ); |
| m_xModuleAcceleratorManager = xModuleAccelCfg; |
| } |
| } |
| catch ( RuntimeException& ) |
| { |
| throw; |
| } |
| catch ( Exception& ) |
| { |
| } |
| } |
| |
| if ( !xGlobalAccelCfg.is() ) |
| { |
| xGlobalAccelCfg = Reference< XAcceleratorConfiguration >( getServiceFactory()->createInstance( |
| SERVICENAME_GLOBALACCELERATORCONFIGURATION ), |
| UNO_QUERY ); |
| m_xGlobalAcceleratorManager = xGlobalAccelCfg; |
| } |
| } |
| |
| KeyCode aEmptyKeyCode; |
| Sequence< rtl::OUString > aSeq( aMenuShortCuts.size() ); |
| const sal_uInt32 nCount = aMenuShortCuts.size(); |
| for ( sal_uInt32 i = 0; i < nCount; ++i ) |
| { |
| aSeq[i] = aMenuShortCuts[i]->aMenuItemURL; |
| aMenuShortCuts[i]->aKeyCode = aEmptyKeyCode; |
| } |
| |
| if ( m_xGlobalAcceleratorManager.is() ) |
| impl_RetrieveShortcutsFromConfiguration( xGlobalAccelCfg, aSeq, aMenuShortCuts ); |
| if ( m_xModuleAcceleratorManager.is() ) |
| impl_RetrieveShortcutsFromConfiguration( xModuleAccelCfg, aSeq, aMenuShortCuts ); |
| if ( m_xDocAcceleratorManager.is() ) |
| impl_RetrieveShortcutsFromConfiguration( xGlobalAccelCfg, aSeq, aMenuShortCuts ); |
| } |
| } |
| |
| void MenuBarManager::RetrieveImageManagers() |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RetrieveImageManagers" ); |
| if ( !m_xDocImageManager.is() ) |
| { |
| Reference< XController > xController = m_xFrame->getController(); |
| Reference< XModel > xModel; |
| if ( xController.is() ) |
| { |
| xModel = xController->getModel(); |
| if ( xModel.is() ) |
| { |
| Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY ); |
| if ( xSupplier.is() ) |
| { |
| Reference< XUIConfigurationManager > xDocUICfgMgr( xSupplier->getUIConfigurationManager(), UNO_QUERY ); |
| m_xDocImageManager = Reference< XImageManager >( xDocUICfgMgr->getImageManager(), UNO_QUERY ); |
| m_xDocImageManager->addConfigurationListener( |
| Reference< XUIConfigurationListener >( |
| static_cast< OWeakObject* >( this ), UNO_QUERY )); |
| } |
| } |
| } |
| } |
| |
| Reference< XModuleManager > xModuleManager; |
| if ( m_aModuleIdentifier.getLength() == 0 ) |
| xModuleManager.set( getServiceFactory()->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW ); |
| |
| try |
| { |
| if ( xModuleManager.is() ) |
| m_aModuleIdentifier = xModuleManager->identify( Reference< XInterface >( m_xFrame, UNO_QUERY ) ); |
| } |
| catch( Exception& ) |
| { |
| } |
| |
| if ( !m_xModuleImageManager.is() ) |
| { |
| Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier( getServiceFactory()->createInstance( |
| SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ), |
| UNO_QUERY ); |
| Reference< XUIConfigurationManager > xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier ); |
| m_xModuleImageManager.set( xUICfgMgr->getImageManager(), UNO_QUERY ); |
| m_xModuleImageManager->addConfigurationListener( Reference< XUIConfigurationListener >( |
| static_cast< OWeakObject* >( this ), UNO_QUERY )); |
| } |
| } |
| |
| void MenuBarManager::FillMenuWithConfiguration( |
| sal_uInt16& nId, |
| Menu* pMenu, |
| const ::rtl::OUString& rModuleIdentifier, |
| const Reference< XIndexAccess >& rItemContainer, |
| const Reference< XURLTransformer >& rTransformer ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillMenuWithConfiguration" ); |
| Reference< XDispatchProvider > xEmptyDispatchProvider; |
| MenuBarManager::FillMenu( nId, pMenu, rModuleIdentifier, rItemContainer, xEmptyDispatchProvider ); |
| |
| // Merge add-on menu entries into the menu bar |
| MenuBarManager::MergeAddonMenus( static_cast< Menu* >( pMenu ), |
| AddonsOptions().GetMergeMenuInstructions(), |
| rModuleIdentifier ); |
| |
| sal_Bool bHasDisabledEntries = SvtCommandOptions().HasEntries( SvtCommandOptions::CMDOPTION_DISABLED ); |
| if ( bHasDisabledEntries ) |
| { |
| sal_uInt16 nCount = pMenu->GetItemCount(); |
| for ( sal_uInt16 i = 0; i < nCount; i++ ) |
| { |
| sal_uInt16 nID = pMenu->GetItemId( i ); |
| if ( nID > 0 ) |
| { |
| PopupMenu* pPopupMenu = pMenu->GetPopupMenu( nID ); |
| if ( pPopupMenu ) |
| { |
| if ( MustBeHidden( pPopupMenu, rTransformer )) |
| pMenu->HideItem( nId ); |
| } |
| } |
| } |
| } |
| } |
| |
| void MenuBarManager::FillMenu( |
| sal_uInt16& nId, |
| Menu* pMenu, |
| const rtl::OUString& rModuleIdentifier, |
| const Reference< XIndexAccess >& rItemContainer, |
| const Reference< XDispatchProvider >& rDispatchProvider ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillMenu" ); |
| // Fill menu bar with container contents |
| for ( sal_Int32 n = 0; n < rItemContainer->getCount(); n++ ) |
| { |
| Sequence< PropertyValue > aProp; |
| rtl::OUString aCommandURL; |
| rtl::OUString aLabel; |
| rtl::OUString aHelpURL; |
| rtl::OUString aModuleIdentifier( rModuleIdentifier ); |
| sal_Bool bShow(sal_True); |
| sal_Bool bEnabled(sal_True); |
| sal_uInt16 nType = 0; |
| Reference< XIndexAccess > xIndexContainer; |
| Reference< XDispatchProvider > xDispatchProvider( rDispatchProvider ); |
| sal_Int16 nStyle = 0; |
| try |
| { |
| if ( rItemContainer->getByIndex( n ) >>= aProp ) |
| { |
| for ( int i = 0; i < aProp.getLength(); i++ ) |
| { |
| rtl::OUString aPropName = aProp[i].Name; |
| if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_COMMANDURL, LEN_DESCRIPTOR_COMMANDURL )) |
| aProp[i].Value >>= aCommandURL; |
| else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_HELPURL, LEN_DESCRIPTOR_HELPURL )) |
| aProp[i].Value >>= aHelpURL; |
| else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_CONTAINER, LEN_DESCRIPTOR_CONTAINER )) |
| aProp[i].Value >>= xIndexContainer; |
| else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_LABEL, LEN_DESCRIPTOR_LABEL )) |
| aProp[i].Value >>= aLabel; |
| else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_TYPE, LEN_DESCRIPTOR_TYPE )) |
| aProp[i].Value >>= nType; |
| else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_MODULEIDENTIFIER, LEN_DESCRIPTOR_MODULEIDENTIFIER )) |
| aProp[i].Value >>= aModuleIdentifier; |
| else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_DISPATCHPROVIDER, LEN_DESCRIPTOR_DISPATCHPROVIDER )) |
| aProp[i].Value >>= xDispatchProvider; |
| else if ( aProp[i].Name.equalsAsciiL( ITEM_DESCRIPTOR_STYLE, LEN_DESCRIPTOR_STYLE )) |
| aProp[i].Value >>= nStyle; |
| else if ( aProp[i].Name.equalsAsciiL( ITEM_DESCRIPTOR_ISVISIBLE, LEN_DESCRIPTOR_ISVISIBLE )) |
| aProp[i].Value >>= bShow; |
| else if ( aProp[i].Name.equalsAsciiL( ITEM_DESCRIPTOR_ENABLED, LEN_DESCRIPTOR_ENABLED )) |
| aProp[i].Value >>= bEnabled; |
| } |
| |
| if ( nType == ::com::sun::star::ui::ItemType::DEFAULT ) |
| { |
| pMenu->InsertItem( nId, aLabel ); |
| pMenu->SetItemCommand( nId, aCommandURL ); |
| |
| if ( nStyle ) |
| { |
| MenuItemBits nBits = pMenu->GetItemBits( nId ); |
| if ( nStyle & ::com::sun::star::ui::ItemStyle::ICON ) |
| nBits |= MIB_ICON; |
| if ( nStyle & ::com::sun::star::ui::ItemStyle::TEXT ) |
| nBits |= MIB_TEXT; |
| if ( nStyle & ::com::sun::star::ui::ItemStyle::RADIO_CHECK ) |
| nBits |= MIB_RADIOCHECK; |
| pMenu->SetItemBits( nId, nBits ); |
| } |
| |
| if ( !bShow ) |
| pMenu->HideItem( nId ); |
| |
| if ( !bEnabled) |
| pMenu->EnableItem( nId, sal_False ); |
| |
| if ( xIndexContainer.is() ) |
| { |
| PopupMenu* pNewPopupMenu = new PopupMenu; |
| pMenu->SetPopupMenu( nId, pNewPopupMenu ); |
| |
| if ( xDispatchProvider.is() ) |
| { |
| // Use attributes struct to transport special dispatch provider |
| MenuConfiguration::Attributes* pAttributes = new MenuConfiguration::Attributes; |
| pAttributes->xDispatchProvider = xDispatchProvider; |
| pMenu->SetUserValue( nId, (sal_uIntPtr)( pAttributes )); |
| } |
| |
| // Use help command to transport module identifier |
| if ( aModuleIdentifier.getLength() > 0 ) |
| pMenu->SetHelpCommand( nId, aModuleIdentifier ); |
| |
| ++nId; |
| FillMenu( nId, pNewPopupMenu, aModuleIdentifier, xIndexContainer, xDispatchProvider ); |
| } |
| else |
| ++nId; |
| } |
| else |
| { |
| pMenu->InsertSeparator(); |
| ++nId; |
| } |
| } |
| } |
| catch ( IndexOutOfBoundsException& ) |
| { |
| break; |
| } |
| } |
| } |
| |
| void MenuBarManager::MergeAddonMenus( |
| Menu* pMenuBar, |
| const MergeMenuInstructionContainer& aMergeInstructionContainer, |
| const ::rtl::OUString& rModuleIdentifier ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MergeAddonMenus" ); |
| // set start value for the item ID for the new addon menu items |
| sal_uInt16 nItemId = ADDONMENU_MERGE_ITEMID_START; |
| |
| const sal_uInt32 nCount = aMergeInstructionContainer.size(); |
| for ( sal_uInt32 i = 0; i < nCount; i++ ) |
| { |
| const MergeMenuInstruction& rMergeInstruction = aMergeInstructionContainer[i]; |
| |
| if ( MenuBarMerger::IsCorrectContext( rMergeInstruction.aMergeContext, rModuleIdentifier )) |
| { |
| ::std::vector< ::rtl::OUString > aMergePath; |
| |
| // retrieve the merge path from the merge point string |
| MenuBarMerger::RetrieveReferencePath( rMergeInstruction.aMergePoint, aMergePath ); |
| |
| // convert the sequence/sequence property value to a more convenient vector<> |
| AddonMenuContainer aMergeMenuItems; |
| MenuBarMerger::GetSubMenu( rMergeInstruction.aMergeMenu, aMergeMenuItems ); |
| |
| // try to find the reference point for our merge operation |
| Menu* pMenu = pMenuBar; |
| ReferencePathInfo aResult = MenuBarMerger::FindReferencePath( aMergePath, pMenu ); |
| |
| if ( aResult.eResult == RP_OK ) |
| { |
| // normal merge operation |
| MenuBarMerger::ProcessMergeOperation( aResult.pPopupMenu, |
| aResult.nPos, |
| nItemId, |
| rMergeInstruction.aMergeCommand, |
| rMergeInstruction.aMergeCommandParameter, |
| rModuleIdentifier, |
| aMergeMenuItems ); |
| } |
| else |
| { |
| // fallback |
| MenuBarMerger::ProcessFallbackOperation( aResult, |
| nItemId, |
| rMergeInstruction.aMergeCommand, |
| rMergeInstruction.aMergeFallback, |
| aMergePath, |
| rModuleIdentifier, |
| aMergeMenuItems ); |
| } |
| } |
| } |
| } |
| |
| void MenuBarManager::SetItemContainer( const Reference< XIndexAccess >& rItemContainer ) |
| { |
| RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::MenuBarManager::SetItemContainer" ); |
| |
| ResetableGuard aGuard( m_aLock ); |
| |
| Reference< XFrame > xFrame = m_xFrame; |
| |
| if ( !m_bModuleIdentified ) |
| { |
| m_bModuleIdentified = sal_True; |
| Reference< XModuleManager > xModuleManager; |
| xModuleManager = Reference< XModuleManager >( getServiceFactory()->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW ); |
| |
| try |
| { |
| m_aModuleIdentifier = xModuleManager->identify( xFrame ); |
| } |
| catch( Exception& ) |
| { |
| } |
| } |
| |
| // Clear MenuBarManager structures |
| { |
| vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); |
| |
| // Check active state as we cannot change our VCL menu during activation by the user |
| if ( m_bActive ) |
| { |
| m_xDeferedItemContainer = rItemContainer; |
| return; |
| } |
| |
| RemoveListener(); |
| std::vector< MenuItemHandler* >::iterator p; |
| for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) |
| { |
| MenuItemHandler* pItemHandler = *p; |
| pItemHandler->xMenuItemDispatch.clear(); |
| pItemHandler->xSubMenuManager.clear(); |
| delete pItemHandler; |
| } |
| m_aMenuItemHandlerVector.clear(); |
| |
| // Remove top-level parts |
| m_pVCLMenu->Clear(); |
| |
| sal_uInt16 nId = 1; |
| |
| // Fill menu bar with container contents |
| FillMenuWithConfiguration( nId, (Menu *)m_pVCLMenu, m_aModuleIdentifier, rItemContainer, m_xURLTransformer ); |
| |
| // Refill menu manager again |
| Reference< XDispatchProvider > xDispatchProvider; |
| FillMenuManager( m_pVCLMenu, xFrame, xDispatchProvider, m_aModuleIdentifier, sal_False, sal_True ); |
| |
| // add itself as frame action listener |
| m_xFrame->addFrameActionListener( Reference< XFrameActionListener >( static_cast< OWeakObject* >( this ), UNO_QUERY )); |
| } |
| } |
| |
| void MenuBarManager::GetPopupController( PopupControllerCache& rPopupController ) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::GetPopupController" ); |
| String aPopupScheme = String::CreateFromAscii( "vnd.sun.star.popup:" ); |
| |
| vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); |
| |
| std::vector< MenuItemHandler* >::iterator p; |
| for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) |
| { |
| MenuItemHandler* pItemHandler = *p; |
| if ( pItemHandler->xPopupMenuController.is() ) |
| { |
| Reference< XDispatchProvider > xDispatchProvider( pItemHandler->xPopupMenuController, UNO_QUERY ); |
| |
| PopupControllerEntry aPopupControllerEntry; |
| aPopupControllerEntry.m_xDispatchProvider = xDispatchProvider; |
| |
| // Just use the main part of the URL for popup menu controllers |
| sal_Int32 nQueryPart( 0 ); |
| sal_Int32 nSchemePart( 0 ); |
| rtl::OUString aMainURL( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.popup:" )); |
| rtl::OUString aMenuURL( pItemHandler->aMenuItemURL ); |
| |
| nSchemePart = aMenuURL.indexOf( ':' ); |
| if (( nSchemePart > 0 ) && |
| ( aMenuURL.getLength() > ( nSchemePart+1 ))) |
| { |
| nQueryPart = aMenuURL.indexOf( '?', nSchemePart ); |
| if ( nQueryPart > 0 ) |
| aMainURL += aMenuURL.copy( nSchemePart, nQueryPart-nSchemePart ); |
| else if ( nQueryPart == -1 ) |
| aMainURL += aMenuURL.copy( nSchemePart+1 ); |
| |
| rPopupController.insert( PopupControllerCache::value_type( |
| aMainURL, aPopupControllerEntry )); |
| } |
| } |
| if ( pItemHandler->xSubMenuManager.is() ) |
| { |
| MenuBarManager* pMenuBarManager = (MenuBarManager*)(pItemHandler->xSubMenuManager.get()); |
| if ( pMenuBarManager ) |
| pMenuBarManager->GetPopupController( rPopupController ); |
| } |
| } |
| } |
| |
| // #110897# |
| const Reference< XMultiServiceFactory >& MenuBarManager::getServiceFactory() |
| { |
| // #110897# |
| return mxServiceFactory; |
| } |
| |
| void MenuBarManager::AddMenu(MenuBarManager* pSubMenuManager,const ::rtl::OUString& _sItemCommand,sal_uInt16 _nItemId) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::AddMenu" ); |
| Reference< XStatusListener > xSubMenuManager( static_cast< OWeakObject *>( pSubMenuManager ), UNO_QUERY ); |
| m_xFrame->addFrameActionListener( Reference< XFrameActionListener >( xSubMenuManager, UNO_QUERY )); |
| |
| // store menu item command as we later have to know which menu is active (see Activate handler) |
| pSubMenuManager->m_aMenuItemCommand = _sItemCommand; |
| Reference< XDispatch > xDispatch; |
| MenuItemHandler* pMenuItemHandler = new MenuItemHandler( |
| _nItemId, |
| xSubMenuManager, |
| xDispatch ); |
| pMenuItemHandler->aMenuItemURL = _sItemCommand; |
| m_aMenuItemHandlerVector.push_back( pMenuItemHandler ); |
| } |
| |
| sal_uInt16 MenuBarManager::FillItemCommand(::rtl::OUString& _rItemCommand,Menu* _pMenu,sal_uInt16 _nIndex) const |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillItemCommand" ); |
| sal_uInt16 nItemId = _pMenu->GetItemId( _nIndex ); |
| |
| _rItemCommand = _pMenu->GetItemCommand( nItemId ); |
| if ( !_rItemCommand.getLength() ) |
| { |
| const static ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" )); |
| _rItemCommand = aSlotString; |
| _rItemCommand += ::rtl::OUString::valueOf( (sal_Int32)nItemId ); |
| _pMenu->SetItemCommand( nItemId, _rItemCommand ); |
| } |
| return nItemId; |
| } |
| void MenuBarManager::Init(const Reference< XFrame >& rFrame,AddonMenu* pAddonMenu,sal_Bool bDelete,sal_Bool bDeleteChildren,bool _bHandlePopUp) |
| { |
| RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Init" ); |
| m_bActive = sal_False; |
| m_bDeleteMenu = bDelete; |
| m_bDeleteChildren = bDeleteChildren; |
| m_pVCLMenu = pAddonMenu; |
| m_xFrame = rFrame; |
| m_bInitialized = sal_False; |
| m_bIsBookmarkMenu = sal_True; |
| |
| rtl::OUString aModuleIdentifier; |
| m_xPopupMenuControllerFactory = frame::PopupMenuControllerFactory::create( |
| ::comphelper::getProcessComponentContext()); |
| |
| const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings(); |
| m_bWasHiContrast = rSettings.GetHighContrastMode(); |
| |
| Reference< XStatusListener > xStatusListener; |
| Reference< XDispatch > xDispatch; |
| sal_uInt16 nItemCount = pAddonMenu->GetItemCount(); |
| ::rtl::OUString aItemCommand; |
| m_aMenuItemHandlerVector.reserve(nItemCount); |
| for ( sal_uInt16 i = 0; i < nItemCount; i++ ) |
| { |
| sal_uInt16 nItemId = FillItemCommand(aItemCommand,pAddonMenu, i ); |
| |
| PopupMenu* pPopupMenu = pAddonMenu->GetPopupMenu( nItemId ); |
| if ( pPopupMenu ) |
| { |
| // #110897# |
| Reference< XDispatchProvider > xDispatchProvider; |
| MenuBarManager* pSubMenuManager = new MenuBarManager( getServiceFactory(), rFrame, m_xURLTransformer,xDispatchProvider, aModuleIdentifier, pPopupMenu, _bHandlePopUp ? sal_False : bDeleteChildren, _bHandlePopUp ? sal_False : bDeleteChildren ); |
| |
| Reference< XStatusListener > xSubMenuManager( static_cast< OWeakObject *>( pSubMenuManager ), UNO_QUERY ); |
| |
| // store menu item command as we later have to know which menu is active (see Acivate handler) |
| pSubMenuManager->m_aMenuItemCommand = aItemCommand; |
| |
| MenuItemHandler* pMenuItemHandler = new MenuItemHandler( |
| nItemId, |
| xSubMenuManager, |
| xDispatch ); |
| m_aMenuItemHandlerVector.push_back( pMenuItemHandler ); |
| } |
| else |
| { |
| if ( pAddonMenu->GetItemType( i ) != MENUITEM_SEPARATOR ) |
| { |
| MenuConfiguration::Attributes* pAddonAttributes = (MenuConfiguration::Attributes *)(pAddonMenu->GetUserValue( nItemId )); |
| MenuItemHandler* pMenuItemHandler = new MenuItemHandler( nItemId, xStatusListener, xDispatch ); |
| |
| if ( pAddonAttributes ) |
| { |
| // read additional attributes from attributes struct and AddonMenu implementation will delete all attributes itself!! |
| pMenuItemHandler->aTargetFrame = pAddonAttributes->aTargetFrame; |
| } |
| |
| pMenuItemHandler->aMenuItemURL = aItemCommand; |
| if ( _bHandlePopUp ) |
| { |
| // Check if we have to create a popup menu for a uno based popup menu controller. |
| // We have to set an empty popup menu into our menu structure so the controller also |
| // works with inplace OLE. |
| if ( m_xPopupMenuControllerFactory.is() && |
| m_xPopupMenuControllerFactory->hasController( aItemCommand, rtl::OUString() )) |
| { |
| VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu; |
| PopupMenu* pCtlPopupMenu = (PopupMenu *)pVCLXPopupMenu->GetMenu(); |
| pAddonMenu->SetPopupMenu( pMenuItemHandler->nItemId, pCtlPopupMenu ); |
| pMenuItemHandler->xPopupMenu = Reference< com::sun::star::awt::XPopupMenu >( (OWeakObject *)pVCLXPopupMenu, UNO_QUERY ); |
| |
| } |
| } |
| m_aMenuItemHandlerVector.push_back( pMenuItemHandler ); |
| } |
| } |
| } |
| |
| SetHdl(); |
| } |
| |
| void MenuBarManager::SetHdl() |
| { |
| m_pVCLMenu->SetHighlightHdl( LINK( this, MenuBarManager, Highlight )); |
| m_pVCLMenu->SetActivateHdl( LINK( this, MenuBarManager, Activate )); |
| m_pVCLMenu->SetDeactivateHdl( LINK( this, MenuBarManager, Deactivate )); |
| m_pVCLMenu->SetSelectHdl( LINK( this, MenuBarManager, Select )); |
| |
| if ( !m_xURLTransformer.is() && mxServiceFactory.is() ) |
| m_xURLTransformer.set( mxServiceFactory->createInstance( |
| SERVICENAME_URLTRANSFORMER), |
| UNO_QUERY ); |
| } |
| |
| } |