diff options
Diffstat (limited to 'framework/source/uielement/toolbarmanager.cxx')
-rw-r--r-- | framework/source/uielement/toolbarmanager.cxx | 2356 |
1 files changed, 2356 insertions, 0 deletions
diff --git a/framework/source/uielement/toolbarmanager.cxx b/framework/source/uielement/toolbarmanager.cxx new file mode 100644 index 000000000000..8162307f87ad --- /dev/null +++ b/framework/source/uielement/toolbarmanager.cxx @@ -0,0 +1,2356 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" +#include <uielement/toolbarmanager.hxx> + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + + +#ifndef __FRAMEWORK_UIELEMENT_TOOLBAR_HXX +#include <uielement/toolbar.hxx> +#endif +#ifndef __FRAMEWORK_UIELEMENT_GENERICTOOLBARCONTROLLER_HXX +#include <uielement/generictoolbarcontroller.hxx> +#endif +#include <threadhelp/resetableguard.hxx> +#include "services.h" +#include "general.h" +#include "properties.h" +#include <framework/imageproducer.hxx> +#include <framework/sfxhelperfunctions.hxx> +#include <classes/fwkresid.hxx> +#ifndef __FRAMEWORK_CLASES_RESOURCE_HRC_ +#include <classes/resource.hrc> +#endif +#include <framework/addonsoptions.hxx> +#include <uielement/toolbarmerger.hxx> +#include <framework/acceleratorinfo.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/ui/ItemType.hpp> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/awt/XDockableWindow.hpp> +#include <com/sun/star/frame/XLayoutManager.hpp> +#ifndef _COM_SUN_STAR_UI_XDOCKINGAREA_HPP_ +#include <com/sun/star/ui/DockingArea.hpp> +#endif +#include <com/sun/star/graphic/XGraphic.hpp> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/frame/XModuleManager.hpp> +#include <com/sun/star/ui/XUIElementSettings.hpp> +#include <com/sun/star/ui/XUIConfigurationPersistence.hpp> +#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp> +#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp> +#include <com/sun/star/ui/ImageType.hpp> +#include <com/sun/star/ui/UIElementType.hpp> +#include <comphelper/sequence.hxx> +#include <com/sun/star/frame/status/Visibility.hpp> +#include <com/sun/star/lang/DisposedException.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ +#include <svtools/imgdef.hxx> +#include <svtools/toolboxcontroller.hxx> +#include <unotools/cmdoptions.hxx> +#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ +#include <toolkit/unohlp.hxx> +#endif +#include <comphelper/mediadescriptor.hxx> +#include <svtools/miscopt.hxx> +#include <svl/imageitm.hxx> +#include <svtools/framestatuslistener.hxx> +#include <vcl/svapp.hxx> +#include <vcl/menu.hxx> +#include <vcl/syswin.hxx> +#include <vcl/taskpanelist.hxx> +#include <rtl/logfile.hxx> +#include <svtools/menuoptions.hxx> +#include <unotools/cmdoptions.hxx> +#include <boost/bind.hpp> +#include <svtools/acceleratorexecute.hxx> + +//_________________________________________________________________________________________________________________ +// namespaces +//_________________________________________________________________________________________________________________ + +using rtl::OUString; + +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::graphic; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::ui; +using namespace ::com::sun::star; + +namespace framework +{ + +static const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL"; +static const char ITEM_DESCRIPTOR_HELPURL[] = "HelpURL"; +static const char ITEM_DESCRIPTOR_TOOLTIP[] = "Tooltip"; +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_VISIBLE[] = "IsVisible"; +static const char ITEM_DESCRIPTOR_WIDTH[] = "Width"; +static const char ITEM_DESCRIPTOR_STYLE[] = "Style"; + +static const sal_Int32 ITEM_DESCRIPTOR_COMMANDURL_LEN = 10; +static const sal_Int32 ITEM_DESCRIPTOR_HELPURL_LEN = 7; +static const sal_Int32 ITEM_DESCRIPTOR_TOOLTIP_LEN = 7; +static const sal_Int32 ITEM_DESCRIPTOR_CONTAINER_LEN = 23; +static const sal_Int32 ITEM_DESCRIPTOR_LABEL_LEN = 5; +static const sal_Int32 ITEM_DESCRIPTOR_TYPE_LEN = 4; +static const sal_Int32 ITEM_DESCRIPTOR_VISIBLE_LEN = 9; +static const sal_Int32 ITEM_DESCRIPTOR_WIDTH_LEN = 5; +static const sal_Int32 ITEM_DESCRIPTOR_STYLE_LEN = 5; + +static const char HELPID_PREFIX[] = "helpid:"; +static const char HELPID_PREFIX_TESTTOOL[] = ".HelpId:"; +//static sal_Int32 HELPID_PREFIX_LENGTH = 7; +static const sal_uInt16 STARTID_CUSTOMIZE_POPUPMENU = 1000; + +#define MENUPREFIX "private:resource/menubar/" + +class ImageOrientationListener : public svt::FrameStatusListener +{ + public: + ImageOrientationListener( const Reference< XStatusListener > rReceiver, + const Reference< XMultiServiceFactory > rServiceManager, + const Reference< XFrame > rFrame ); + virtual ~ImageOrientationListener(); + + virtual void SAL_CALL statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw ( ::com::sun::star::uno::RuntimeException ); + + private: + Reference< XStatusListener > m_xReceiver; +}; + +ImageOrientationListener::ImageOrientationListener( + const Reference< XStatusListener > rReceiver, + const Reference< XMultiServiceFactory > rServiceManager, + const Reference< XFrame > rFrame ) : + FrameStatusListener( rServiceManager, rFrame ), + m_xReceiver( rReceiver ) +{ +} + +ImageOrientationListener::~ImageOrientationListener() +{ +} + +void SAL_CALL ImageOrientationListener::statusChanged( const FeatureStateEvent& Event ) +throw ( RuntimeException ) +{ + if ( m_xReceiver.is() ) + m_xReceiver->statusChanged( Event ); +} + +//***************************************************************************************************************** + +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; +} + +static ::com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManager > getLayoutManagerFromFrame( + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame ) +{ + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager; + + Reference< XPropertySet > xPropSet( rFrame, UNO_QUERY ); + if ( xPropSet.is() ) + { + try + { + xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))) >>= xLayoutManager; + } + catch ( RuntimeException& ) + { + throw; + } + catch ( Exception& ) + { + } + } + + return xLayoutManager; +} + +//***************************************************************************************************************** +// XInterface, XTypeProvider, XServiceInfo +//***************************************************************************************************************** +DEFINE_XINTERFACE_6 ( ToolBarManager , + OWeakObject , + DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider ), + DIRECT_INTERFACE( ::com::sun::star::lang::XComponent ), + DIRECT_INTERFACE( ::com::sun::star::frame::XFrameActionListener ), + DIRECT_INTERFACE( ::com::sun::star::ui::XUIConfigurationListener ), + DIRECT_INTERFACE( ::com::sun::star::frame::XStatusListener ), + DERIVED_INTERFACE( ::com::sun::star::lang::XEventListener, ::com::sun::star::frame::XFrameActionListener ) + ) + +DEFINE_XTYPEPROVIDER_6 ( ToolBarManager , + ::com::sun::star::lang::XTypeProvider , + ::com::sun::star::lang::XComponent , + ::com::sun::star::ui::XUIConfigurationListener , + ::com::sun::star::frame::XFrameActionListener , + ::com::sun::star::frame::XStatusListener , + ::com::sun::star::lang::XEventListener + ) + +ToolBarManager::ToolBarManager( const Reference< XMultiServiceFactory >& rServiceManager, + const Reference< XFrame >& rFrame, + const rtl::OUString& rResourceName, + ToolBar* pToolBar ) : + ThreadHelpBase( &Application::GetSolarMutex() ), + OWeakObject(), + m_bDisposed( sal_False ), + m_bIsHiContrast( pToolBar->GetSettings().GetStyleSettings().GetHighContrastMode() ), + m_bSmallSymbols( !SvtMiscOptions().AreCurrentSymbolsLarge() ), + m_bModuleIdentified( sal_False ), + m_bAddedToTaskPaneList( sal_True ), + m_bFrameActionRegistered( sal_False ), + m_bUpdateControllers( sal_False ), + m_bImageOrientationRegistered( sal_False ), + m_bImageMirrored( sal_False ), + m_bCanBeCustomized( sal_True ), + m_lImageRotation( 0 ), + m_pToolBar( pToolBar ), + m_aResourceName( rResourceName ), + m_xFrame( rFrame ), + m_aListenerContainer( m_aLock.getShareableOslMutex() ), + m_xServiceManager( rServiceManager ), + m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() ), + m_bAcceleratorCfg( sal_False ) +{ + Window* pWindow = m_pToolBar; + while ( pWindow && !pWindow->IsSystemWindow() ) + pWindow = pWindow->GetParent(); + + if ( pWindow ) + ((SystemWindow *)pWindow)->GetTaskPaneList()->AddWindow( m_pToolBar ); + + if ( m_xServiceManager.is() ) + { + m_xToolbarControllerRegistration = Reference< XUIControllerRegistration >( + m_xServiceManager->createInstance( SERVICENAME_TOOLBARCONTROLLERFACTORY ), + UNO_QUERY ); + + m_xURLTransformer.set( m_xServiceManager->createInstance( + SERVICENAME_URLTRANSFORMER), + UNO_QUERY ); + } + + m_pToolBar->SetSelectHdl( LINK( this, ToolBarManager, Select) ); + m_pToolBar->SetActivateHdl( LINK( this, ToolBarManager, Activate) ); + m_pToolBar->SetDeactivateHdl( LINK( this, ToolBarManager, Deactivate) ); + m_pToolBar->SetClickHdl( LINK( this, ToolBarManager, Click ) ); + m_pToolBar->SetDropdownClickHdl( LINK( this, ToolBarManager, DropdownClick ) ); + m_pToolBar->SetDoubleClickHdl( LINK( this, ToolBarManager, DoubleClick ) ); + m_pToolBar->SetStateChangedHdl( LINK( this, ToolBarManager, StateChanged ) ); + m_pToolBar->SetDataChangedHdl( LINK( this, ToolBarManager, DataChanged ) ); + m_pToolBar->SetToolboxButtonSize( m_bSmallSymbols ? TOOLBOX_BUTTONSIZE_SMALL : TOOLBOX_BUTTONSIZE_LARGE ); + + // enables a menu for clipped items and customization + SvtCommandOptions aCmdOptions; + sal_uInt16 nMenuType = TOOLBOX_MENUTYPE_CLIPPEDITEMS; + if ( !aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, ::rtl::OUString::createFromAscii( "CreateDialog" ))) + nMenuType |= TOOLBOX_MENUTYPE_CUSTOMIZE; + //added for issue33668 by shizhoubo + m_pToolBar->SetCommandHdl( LINK( this, ToolBarManager, Command ) ); + //end + m_pToolBar->SetMenuType( nMenuType ); + m_pToolBar->SetMenuButtonHdl( LINK( this, ToolBarManager, MenuButton ) ); + m_pToolBar->GetMenu()->SetSelectHdl( LINK( this, ToolBarManager, MenuSelect ) ); + m_pToolBar->GetMenu()->SetDeactivateHdl( LINK( this, ToolBarManager, MenuDeactivate ) ); + + // set name for testtool, the useful part is after the last '/' + sal_Int32 idx = rResourceName.lastIndexOf('/'); + idx++; // will become 0 if '/' not found: use full string + ::rtl::OString aHelpIdAsString( HELPID_PREFIX_TESTTOOL ); + ::rtl::OUString aToolbarName = rResourceName.copy( idx ); + aHelpIdAsString += rtl::OUStringToOString( aToolbarName, RTL_TEXTENCODING_UTF8 );; + m_pToolBar->SetHelpId( aHelpIdAsString ); + + m_aAsyncUpdateControllersTimer.SetTimeout( 50 ); + m_aAsyncUpdateControllersTimer.SetTimeoutHdl( LINK( this, ToolBarManager, AsyncUpdateControllersHdl ) ); +} + +ToolBarManager::~ToolBarManager() +{ + OSL_ASSERT( m_pToolBar == 0 ); + OSL_ASSERT( !m_bAddedToTaskPaneList ); +} + +void ToolBarManager::Destroy() +{ + ResetableGuard aGuard( m_aLock ); + if ( m_bAddedToTaskPaneList ) + { + Window* pWindow = m_pToolBar; + while ( pWindow && !pWindow->IsSystemWindow() ) + pWindow = pWindow->GetParent(); + + if ( pWindow ) + ((SystemWindow *)pWindow)->GetTaskPaneList()->RemoveWindow( m_pToolBar ); + m_bAddedToTaskPaneList = sal_False; + } + + // Delete the additional add-ons data + for ( sal_uInt16 i = 0; i < m_pToolBar->GetItemCount(); i++ ) + { + sal_uInt16 nItemId = m_pToolBar->GetItemId( i ); + if ( nItemId > 0 ) + delete static_cast< AddonsParams* >( m_pToolBar->GetItemData( nItemId )); + } + + // Hide toolbar as lazy delete can destroy the toolbar much later. + m_pToolBar->Hide(); + /* #i99167# removed change for i93173 since there is some weird crash */ + // #i93173# delete toolbar lazily as we can still be in one of its handlers + m_pToolBar->doLazyDelete(); + + Link aEmpty; + m_pToolBar->SetSelectHdl( aEmpty ); + m_pToolBar->SetActivateHdl( aEmpty ); + m_pToolBar->SetDeactivateHdl( aEmpty ); + m_pToolBar->SetClickHdl( aEmpty ); + m_pToolBar->SetDropdownClickHdl( aEmpty ); + m_pToolBar->SetDoubleClickHdl( aEmpty ); + m_pToolBar->SetStateChangedHdl( aEmpty ); + m_pToolBar->SetDataChangedHdl( aEmpty ); + +// delete m_pToolBar; + m_pToolBar = 0; +} + +ToolBox* ToolBarManager::GetToolBar() const +{ + ResetableGuard aGuard( m_aLock ); + return m_pToolBar; +} + +void ToolBarManager::CheckAndUpdateImages() +{ + ResetableGuard aGuard( m_aLock ); + sal_Bool bRefreshImages = sal_False; + + // Check if high contrast/normal mode have changed + if ( m_pToolBar->GetSettings().GetStyleSettings().GetHighContrastMode() ) + { + if ( !m_bIsHiContrast ) + { + bRefreshImages = sal_True; + m_bIsHiContrast = sal_True; + } + } + else if ( m_bIsHiContrast ) + { + bRefreshImages = sal_True; + m_bIsHiContrast = sal_False; + } + + SvtMiscOptions aMiscOptions; + bool bCurrentSymbolsSmall = !aMiscOptions.AreCurrentSymbolsLarge(); + if ( m_bSmallSymbols != bCurrentSymbolsSmall ) + { + bRefreshImages = sal_True; + m_bSmallSymbols = bCurrentSymbolsSmall; + } + + sal_Int16 nCurrentSymbolsStyle = aMiscOptions.GetCurrentSymbolsStyle(); + if ( m_nSymbolsStyle != nCurrentSymbolsStyle ) + { + bRefreshImages = sal_True; + m_nSymbolsStyle = nCurrentSymbolsStyle; + } + + // Refresh images if requested + if ( bRefreshImages ) + RefreshImages(); +} + +void ToolBarManager::RefreshImages() +{ + ResetableGuard aGuard( m_aLock ); + + sal_Bool bBigImages( SvtMiscOptions().AreCurrentSymbolsLarge() ); + for ( sal_uInt16 nPos = 0; nPos < m_pToolBar->GetItemCount(); nPos++ ) + { + sal_uInt16 nId( m_pToolBar->GetItemId( nPos ) ); + + if ( nId > 0 ) + { + ::rtl::OUString aCommandURL = m_pToolBar->GetItemCommand( nId ); + Image aImage = GetImageFromURL( m_xFrame, aCommandURL, bBigImages, m_bIsHiContrast ); + // Try also to query for add-on images before giving up and use an + // empty image. + if ( !aImage ) + aImage = QueryAddonsImage( aCommandURL, bBigImages, m_bIsHiContrast ); + m_pToolBar->SetItemImage( nId, aImage ); + } + } + + m_pToolBar->SetToolboxButtonSize( bBigImages ? TOOLBOX_BUTTONSIZE_LARGE : TOOLBOX_BUTTONSIZE_SMALL ); + ::Size aSize = m_pToolBar->CalcWindowSizePixel(); + m_pToolBar->SetOutputSizePixel( aSize ); +} + +void ToolBarManager::UpdateImageOrientation() +{ + ResetableGuard aGuard( m_aLock ); + + if ( m_xUICommandLabels.is() ) + { + sal_Int32 i; + Sequence< rtl::OUString > aSeqMirrorCmd; + Sequence< rtl::OUString > aSeqRotateCmd; + m_xUICommandLabels->getByName( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDMIRRORIMAGELIST ))) >>= aSeqMirrorCmd; + m_xUICommandLabels->getByName( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDROTATEIMAGELIST ))) >>= aSeqRotateCmd; + + CommandToInfoMap::iterator pIter; + for ( i = 0; i < aSeqMirrorCmd.getLength(); i++ ) + { + rtl::OUString aMirrorCmd = aSeqMirrorCmd[i]; + pIter = m_aCommandMap.find( aMirrorCmd ); + if ( pIter != m_aCommandMap.end() ) + pIter->second.bMirrored = sal_True; + } + for ( i = 0; i < aSeqRotateCmd.getLength(); i++ ) + { + rtl::OUString aRotateCmd = aSeqRotateCmd[i]; + pIter = m_aCommandMap.find( aRotateCmd ); + if ( pIter != m_aCommandMap.end() ) + pIter->second.bRotated = sal_True; + } + } + + for ( sal_uInt16 nPos = 0; nPos < m_pToolBar->GetItemCount(); nPos++ ) + { + sal_uInt16 nId = m_pToolBar->GetItemId( nPos ); + if ( nId > 0 ) + { + rtl::OUString aCmd = m_pToolBar->GetItemCommand( nId ); + + CommandToInfoMap::const_iterator pIter = m_aCommandMap.find( aCmd ); + if ( pIter != m_aCommandMap.end() ) + { + if ( pIter->second.bRotated ) + { + m_pToolBar->SetItemImageMirrorMode( nId, sal_False ); + m_pToolBar->SetItemImageAngle( nId, m_lImageRotation ); + } + if ( pIter->second.bMirrored ) + m_pToolBar->SetItemImageMirrorMode( nId, m_bImageMirrored ); + } + } + } +} + +void ToolBarManager::UpdateControllers() +{ + RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::ToolBarManager::UpdateControllers" ); + + if ( !m_bUpdateControllers ) + { + m_bUpdateControllers = sal_True; + ToolBarControllerMap::iterator pIter = m_aControllerMap.begin(); + + while ( pIter != m_aControllerMap.end() ) + { + try + { + Reference< XUpdatable > xUpdatable( pIter->second, UNO_QUERY ); + if ( xUpdatable.is() ) + xUpdatable->update(); + } + catch ( Exception& ) + { + } + ++pIter; + } + } + m_bUpdateControllers = sal_False; +} +//for update toolbar controller via Support Visible by shizhoubo +void ToolBarManager::UpdateController( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XToolbarController > xController) +{ + RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::ToolBarManager::UpdateControllers" ); + + if ( !m_bUpdateControllers ) + { + m_bUpdateControllers = sal_True; + try + { if(xController.is()) + { + Reference< XUpdatable > xUpdatable( xController, UNO_QUERY ); + if ( xUpdatable.is() ) + xUpdatable->update(); + } + } + catch ( Exception& ) + { + } + + /* m_bUpdateControllers = sal_True; + ToolBarControllerMap::iterator pIter = m_aControllerMap.begin(); + + while ( pIter != m_aControllerMap.end() ) + { + try + { + Reference< XUpdatable > xUpdatable( pIter->second, UNO_QUERY ); + if ( xUpdatable.is() ) + xUpdatable->update(); + } + catch ( Exception& ) + { + } + ++pIter; + }*/ + + } + m_bUpdateControllers = sal_False; +} +//end +void ToolBarManager::frameAction( const FrameActionEvent& Action ) +throw ( RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + if ( Action.Action == FrameAction_CONTEXT_CHANGED ) + m_aAsyncUpdateControllersTimer.Start(); +} + +void SAL_CALL ToolBarManager::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) +throw ( ::com::sun::star::uno::RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + if ( m_bDisposed ) + return; + + if ( Event.FeatureURL.Complete.equalsAscii( ".uno:ImageOrientation" )) + { + SfxImageItem aItem( 1, 0 ); + aItem.PutValue( Event.State ); + + m_lImageRotation = aItem.GetRotation(); + m_bImageMirrored = aItem.IsMirrored(); + UpdateImageOrientation(); + } +} + +void SAL_CALL ToolBarManager::disposing( const EventObject& Source ) throw ( RuntimeException ) +{ + { + ResetableGuard aGuard( m_aLock ); + if ( m_bDisposed ) + return; + } + + RemoveControllers(); + + { + ResetableGuard aGuard( m_aLock ); + 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& ) + { + } + } + + if ( m_xImageOrientationListener.is() ) + { + ImageOrientationListener* pImageOrientation = + (ImageOrientationListener*)m_xImageOrientationListener.get(); + pImageOrientation->unbindListener(); + m_xImageOrientationListener.clear(); + } + + m_xDocImageManager.clear(); + m_xModuleImageManager.clear(); + + if ( Source.Source == Reference< XInterface >( m_xFrame, UNO_QUERY )) + m_xFrame.clear(); + + m_xServiceManager.clear(); + } +} + +// XComponent +void SAL_CALL ToolBarManager::dispose() throw( RuntimeException ) +{ + Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY ); + + EventObject aEvent( xThis ); + m_aListenerContainer.disposeAndClear( aEvent ); + + { + ResetableGuard aGuard( m_aLock ); + + // stop timer to prevent timer events after dispose + m_aAsyncUpdateControllersTimer.Stop(); + + RemoveControllers(); + + if ( m_xDocImageManager.is() ) + { + try + { + m_xDocImageManager->removeConfigurationListener( + Reference< XUIConfigurationListener >( + static_cast< OWeakObject* >( this ), UNO_QUERY )); + } + catch ( Exception& ) + { + } + } + m_xDocImageManager.clear(); + if ( m_xModuleImageManager.is() ) + { + try + { + m_xModuleImageManager->removeConfigurationListener( + Reference< XUIConfigurationListener >( + static_cast< OWeakObject* >( this ), UNO_QUERY )); + } + catch ( Exception& ) + { + } + } + m_xModuleImageManager.clear(); + + ImplClearPopupMenu( m_pToolBar ); + + // We have to destroy our toolbar instance now. + Destroy(); + + if ( m_bFrameActionRegistered && m_xFrame.is() ) + { + try + { + m_xFrame->removeFrameActionListener( Reference< XFrameActionListener >( + static_cast< ::cppu::OWeakObject *>( this ), UNO_QUERY )); + } + catch ( Exception& ) + { + } + } + + if ( m_xImageOrientationListener.is() ) + { + ImageOrientationListener* pImageOrientation = + (ImageOrientationListener*)m_xImageOrientationListener.get(); + pImageOrientation->unbindListener(); + m_xImageOrientationListener.clear(); + } + + m_xFrame.clear(); + m_xServiceManager.clear(); + m_xGlobalAcceleratorManager.clear(); + m_xModuleAcceleratorManager.clear(); + m_xDocAcceleratorManager.clear(); + + m_bDisposed = sal_True; + } +} + +void SAL_CALL ToolBarManager::addEventListener( const Reference< XEventListener >& xListener ) throw( RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + if ( m_bDisposed ) + throw DisposedException(); + + m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener ); +} + +void SAL_CALL ToolBarManager::removeEventListener( const Reference< XEventListener >& xListener ) throw( RuntimeException ) +{ + m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener ); +} + +// XUIConfigurationListener +void SAL_CALL ToolBarManager::elementInserted( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException) +{ + impl_elementChanged(false,Event); +} + +void SAL_CALL ToolBarManager::elementRemoved( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException) +{ + impl_elementChanged(true,Event); +} +void ToolBarManager::impl_elementChanged(bool _bRemove,const ::com::sun::star::ui::ConfigurationEvent& Event ) +{ + ResetableGuard aGuard( m_aLock ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + if ( m_bDisposed ) + return; + + Reference< XNameAccess > xNameAccess; + sal_Int16 nImageType = sal_Int16(); + sal_Int16 nCurrentImageType = getImageTypeFromBools( + SvtMiscOptions().AreCurrentSymbolsLarge(), + m_bIsHiContrast ); + + if (( Event.aInfo >>= nImageType ) && + ( nImageType == nCurrentImageType ) && + ( Event.Element >>= xNameAccess )) + { + sal_Int16 nImageInfo( 1 ); + Reference< XInterface > xIfacDocImgMgr( m_xDocImageManager, UNO_QUERY ); + if ( xIfacDocImgMgr == Event.Source ) + nImageInfo = 0; + + Sequence< rtl::OUString > aSeq = xNameAccess->getElementNames(); + for ( sal_Int32 i = 0; i < aSeq.getLength(); i++ ) + { + CommandToInfoMap::iterator pIter = m_aCommandMap.find( aSeq[i] ); + if ( pIter != m_aCommandMap.end() && ( pIter->second.nImageInfo >= nImageInfo )) + { + if ( _bRemove ) + { + Image aImage; + if (( pIter->second.nImageInfo == 0 ) && ( pIter->second.nImageInfo == nImageInfo )) + { + // Special case: An image from the document image manager has been removed. + // It is possible that we have a image at our module image manager. Before + // we can remove our image we have to ask our module image manager. + Sequence< rtl::OUString > aCmdURLSeq( 1 ); + Sequence< Reference< XGraphic > > aGraphicSeq; + aCmdURLSeq[0] = pIter->first; + aGraphicSeq = m_xModuleImageManager->getImages( nImageType, aCmdURLSeq ); + aImage = Image( aGraphicSeq[0] ); + } + + setToolBarImage(aImage,pIter); + } // if ( _bRemove ) + else + { + Reference< XGraphic > xGraphic; + if ( xNameAccess->getByName( aSeq[i] ) >>= xGraphic ) + { + Image aImage( xGraphic ); + setToolBarImage(aImage,pIter); + } + pIter->second.nImageInfo = nImageInfo; + } + } + } + } +} +void ToolBarManager::setToolBarImage(const Image& _aImage,const CommandToInfoMap::const_iterator& _pIter) +{ + const ::std::vector< sal_uInt16 >& _rIDs = _pIter->second.aIds; + m_pToolBar->SetItemImage( _pIter->second.nId, _aImage ); + ::std::for_each(_rIDs.begin(),_rIDs.end(),::boost::bind(&ToolBar::SetItemImage,m_pToolBar,_1,_aImage)); +} + +void SAL_CALL ToolBarManager::elementReplaced( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException) +{ + impl_elementChanged(false,Event); +} + +void ToolBarManager::RemoveControllers() +{ + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + return; + + m_aSubToolBarControllerMap.clear(); + + + // i90033 + // Remove item window pointers from the toolbar. They were + // destroyed by the dispose() at the XComponent. This is needed + // as VCL code later tries to access the item window data in certain + // dtors where the item window is already invalid! + for ( sal_uInt16 i = 0; i < m_pToolBar->GetItemCount(); i++ ) + { + sal_uInt16 nItemId = m_pToolBar->GetItemId( i ); + if ( nItemId > 0 ) + { + Reference< XComponent > xComponent( m_aControllerMap[ nItemId ], UNO_QUERY ); + if ( xComponent.is() ) + { + try + { + xComponent->dispose(); + } + catch ( Exception& ) + { + } + } + m_pToolBar->SetItemWindow(nItemId, 0); + } + } + m_aControllerMap.clear(); +} + +uno::Sequence< beans::PropertyValue > ToolBarManager::GetPropsForCommand( const ::rtl::OUString& rCmdURL ) +{ + Sequence< PropertyValue > aPropSeq; + + // Retrieve properties for command + try + { + if ( !m_bModuleIdentified ) + { + Reference< XModuleManager > xModuleManager( m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW ); + Reference< XInterface > xIfac( m_xFrame, UNO_QUERY ); + + m_bModuleIdentified = sal_True; + m_aModuleIdentifier = xModuleManager->identify( xIfac ); + + if ( m_aModuleIdentifier.getLength() > 0 ) + { + Reference< XNameAccess > xNameAccess( m_xServiceManager->createInstance( SERVICENAME_UICOMMANDDESCRIPTION ), UNO_QUERY ); + if ( xNameAccess.is() ) + xNameAccess->getByName( m_aModuleIdentifier ) >>= m_xUICommandLabels; + } + } + + if ( m_xUICommandLabels.is() ) + { + if ( rCmdURL.getLength() > 0 ) + m_xUICommandLabels->getByName( rCmdURL ) >>= aPropSeq; + } + } + catch ( Exception& ) + { + } + + return aPropSeq; +} + +::rtl::OUString ToolBarManager::RetrieveLabelFromCommand( const ::rtl::OUString& aCmdURL ) +{ + ::rtl::OUString aLabel; + Sequence< PropertyValue > aPropSeq; + + // Retrieve popup menu labels + aPropSeq = GetPropsForCommand( aCmdURL ); + for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ ) + { + if ( aPropSeq[i].Name.equalsAscii( "Name" )) + { + aPropSeq[i].Value >>= aLabel; + break; + } + } + return aLabel; +} + +sal_Int32 ToolBarManager::RetrievePropertiesFromCommand( const ::rtl::OUString& aCmdURL ) +{ + sal_Int32 nProperties(0); + Sequence< PropertyValue > aPropSeq; + + // Retrieve popup menu labels + aPropSeq = GetPropsForCommand( aCmdURL ); + for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ ) + { + if ( aPropSeq[i].Name.equalsAscii( "Properties" )) + { + aPropSeq[i].Value >>= nProperties; + break; + } + } + return nProperties; +} + +void ToolBarManager::CreateControllers() +{ + RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::ToolBarManager::CreateControllers" ); + + Reference< XMultiComponentFactory > xToolbarControllerFactory( m_xToolbarControllerRegistration, UNO_QUERY ); + Reference< XComponentContext > xComponentContext; + Reference< XPropertySet > xProps( m_xServiceManager, UNO_QUERY ); + Reference< XWindow > xToolbarWindow = VCLUnoHelper::GetInterface( m_pToolBar ); + + css::util::URL aURL; + sal_Bool bHasDisabledEntries = SvtCommandOptions().HasEntries( SvtCommandOptions::CMDOPTION_DISABLED ); + SvtCommandOptions aCmdOptions; + + if ( xProps.is() ) + xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xComponentContext; + + for ( sal_uInt16 i = 0; i < m_pToolBar->GetItemCount(); i++ ) + { + sal_uInt16 nId = m_pToolBar->GetItemId( i ); + if ( nId == 0 ) + continue; + + rtl::OUString aLoadURL( RTL_CONSTASCII_USTRINGPARAM( ".uno:OpenUrl" )); + rtl::OUString aCommandURL( m_pToolBar->GetItemCommand( nId )); + sal_Bool bInit( sal_True ); + sal_Bool bCreate( sal_True ); + Reference< XStatusListener > xController; + CommandToInfoMap::iterator pCommandIter = m_aCommandMap.find( aCommandURL ); + sal_Int16 nWidth = ( pCommandIter != m_aCommandMap.end() ? pCommandIter->second.nWidth : 0 ); + + svt::ToolboxController* pController( 0 ); + + if ( bHasDisabledEntries ) + { + aURL.Complete = aCommandURL; + m_xURLTransformer->parseStrict( aURL ); + if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aURL.Path )) + { + m_aControllerMap[ nId ] = xController; + m_pToolBar->HideItem( nId ); + continue; + } + } + + if ( m_xToolbarControllerRegistration.is() && + m_xToolbarControllerRegistration->hasController( aCommandURL, m_aModuleIdentifier )) + { + if ( xToolbarControllerFactory.is() ) + { + PropertyValue aPropValue; + std::vector< Any > aPropertyVector; + + aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleName" )); + aPropValue.Value <<= m_aModuleIdentifier; + aPropertyVector.push_back( makeAny( aPropValue )); + aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" )); + aPropValue.Value <<= m_xFrame; + aPropertyVector.push_back( makeAny( aPropValue )); + aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" )); + aPropValue.Value <<= m_xServiceManager; + aPropertyVector.push_back( makeAny( aPropValue )); + aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" )); + aPropValue.Value <<= xToolbarWindow; + aPropertyVector.push_back( makeAny( aPropValue )); + + if ( nWidth > 0 ) + { + aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Width" )); + aPropValue.Value <<= nWidth; + aPropertyVector.push_back( makeAny( aPropValue )); + } + + Sequence< Any > aArgs( comphelper::containerToSequence( aPropertyVector )); + xController = Reference< XStatusListener >( xToolbarControllerFactory->createInstanceWithArgumentsAndContext( + aCommandURL, aArgs, xComponentContext ), + UNO_QUERY ); + bInit = sal_False; // Initialization is done through the factory service + } + } + + if (( aCommandURL == aLoadURL ) && ( !m_pToolBar->IsItemVisible(nId))) + bCreate = sal_False; + + if ( !xController.is() && m_pToolBar && bCreate ) + { + pController = CreateToolBoxController( m_xFrame, m_pToolBar, nId, aCommandURL ); + if ( !pController ) + { + if ( m_pToolBar->GetItemData( nId ) != 0 ) + { + // retrieve additional parameters + ::rtl::OUString aControlType = static_cast< AddonsParams* >( m_pToolBar->GetItemData( nId ))->aControlType; + + Reference< XStatusListener > xStatusListener( + ToolBarMerger::CreateController( m_xServiceManager, + m_xFrame, + m_pToolBar, + aCommandURL, + nId, + nWidth, + aControlType ), UNO_QUERY ); + + xController = xStatusListener; + } + else + { + MenuDescriptionMap::iterator it = m_aMenuMap.find( nId ); + if ( it == m_aMenuMap.end() ) + { + xController = Reference< XStatusListener >( + new GenericToolbarController( m_xServiceManager, m_xFrame, m_pToolBar, nId, aCommandURL )); + + // Accessibility support: Set toggle button role for specific commands + sal_Int32 nProps = RetrievePropertiesFromCommand( aCommandURL ); + if ( nProps & UICOMMANDDESCRIPTION_PROPERTIES_TOGGLEBUTTON ) + m_pToolBar->SetItemBits( nId, m_pToolBar->GetItemBits( nId ) | TIB_CHECKABLE ); + } + else + xController = Reference< XStatusListener >( + new MenuToolbarController( m_xServiceManager, m_xFrame, m_pToolBar, nId, aCommandURL, m_aModuleIdentifier, m_aMenuMap[ nId ] )); + } + } + else if ( pController ) + { + xController = Reference< XStatusListener >( static_cast< ::cppu::OWeakObject *>( pController ), UNO_QUERY ); + } + } + + // Associate ID and controller to be able to retrieve + // the controller from the ID later. + m_aControllerMap[ nId ] = xController; + + // Fill sub-toolbars into our hash-map + Reference< XSubToolbarController > xSubToolBar( xController, UNO_QUERY ); + if ( xSubToolBar.is() && xSubToolBar->opensSubToolbar() ) + { + rtl::OUString aSubToolBarName = xSubToolBar->getSubToolbarName(); + if ( aSubToolBarName.getLength() != 0 ) + { + SubToolBarToSubToolBarControllerMap::iterator pIter = + m_aSubToolBarControllerMap.find( aSubToolBarName ); + if ( pIter == m_aSubToolBarControllerMap.end() ) + { + SubToolBarControllerVector aSubToolBarVector; + aSubToolBarVector.push_back( xSubToolBar ); + m_aSubToolBarControllerMap.insert( + SubToolBarToSubToolBarControllerMap::value_type( + aSubToolBarName, aSubToolBarVector )); + } + else + pIter->second.push_back( xSubToolBar ); + } + } + + Reference< XInitialization > xInit( xController, UNO_QUERY ); + if ( xInit.is() ) + { + if ( bInit ) + { + PropertyValue aPropValue; + std::vector< Any > aPropertyVector; + + aPropValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" )); + aPropValue.Value <<= m_xFrame; + aPropertyVector.push_back( makeAny( aPropValue )); + aPropValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" )); + aPropValue.Value <<= aCommandURL; + aPropertyVector.push_back( makeAny( aPropValue )); + aPropValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" )); + aPropValue.Value <<= m_xServiceManager; + aPropertyVector.push_back( makeAny( aPropValue )); + aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" )); + aPropValue.Value <<= xToolbarWindow; + aPropertyVector.push_back( makeAny( aPropValue )); + aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleName" )); + aPropValue.Value <<= m_aModuleIdentifier; + aPropertyVector.push_back( makeAny( aPropValue )); + + if ( nWidth > 0 ) + { + aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Width" )); + aPropValue.Value <<= nWidth; + aPropertyVector.push_back( makeAny( aPropValue )); + } + + Sequence< Any > aArgs( comphelper::containerToSequence( aPropertyVector )); + xInit->initialize( aArgs ); + //for Support Visiblitly by shizhoubo + if (pController) + { + // rtl::OUString aCommandURL = pController->m_aCommandURL; + if(aCommandURL == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:SwitchXFormsDesignMode" )) || + aCommandURL == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ViewDataSourceBrowser" )) || + aCommandURL == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ParaLeftToRight" )) || + aCommandURL == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ParaRightToLeft" )) + ) + pController->setFastPropertyValue_NoBroadcast(1,makeAny(sal_True)); + } + + //end + } + + // Request a item window from the toolbar controller and set it at the VCL toolbar + Reference< XToolbarController > xTbxController( xController, UNO_QUERY ); + if ( xTbxController.is() && xToolbarWindow.is() ) + { + Reference< XWindow > xWindow = xTbxController->createItemWindow( xToolbarWindow ); + if ( xWindow.is() ) + { + Window* pItemWin = VCLUnoHelper::GetWindow( xWindow ); + if ( pItemWin ) + { + WindowType nType = pItemWin->GetType(); + if ( nType == WINDOW_LISTBOX || nType == WINDOW_MULTILISTBOX || nType == WINDOW_COMBOBOX ) + pItemWin->SetAccessibleName( m_pToolBar->GetItemText( nId ) ); + m_pToolBar->SetItemWindow( nId, pItemWin ); + } + } + } + } + //for update Controller via support visiable state by shizhoubo + Reference< XPropertySet > xPropSet( xController, UNO_QUERY ); + if ( xPropSet.is() ) + { + try + { + sal_Bool bSupportVisiable = sal_True; + Any a( xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SupportsVisiable" ))) ); + a >>= bSupportVisiable; + if ( bSupportVisiable ) + { + Reference< XToolbarController > xTbxController( xController, UNO_QUERY ); + UpdateController(xTbxController); + } + } + catch ( RuntimeException& ) + { + throw; + } + catch ( Exception& ) + { + } + } + //end + + } + + AddFrameActionListener(); + AddImageOrientationListener(); +} + +void ToolBarManager::AddFrameActionListener() +{ + if ( !m_bFrameActionRegistered && m_xFrame.is() ) + { + m_bFrameActionRegistered = sal_True; + m_xFrame->addFrameActionListener( Reference< XFrameActionListener >( + static_cast< ::cppu::OWeakObject *>( this ), UNO_QUERY )); + } +} + +void ToolBarManager::AddImageOrientationListener() +{ + if ( !m_bImageOrientationRegistered && m_xFrame.is() ) + { + m_bImageOrientationRegistered = sal_True; + ImageOrientationListener* pImageOrientation = new ImageOrientationListener( + Reference< XStatusListener >( static_cast< ::cppu::OWeakObject *>( this ), UNO_QUERY ), + m_xServiceManager, + m_xFrame ); + m_xImageOrientationListener = Reference< XComponent >( static_cast< ::cppu::OWeakObject *>( + pImageOrientation ), UNO_QUERY ); + pImageOrientation->addStatusListener( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ImageOrientation" ))); + pImageOrientation->bindListener(); + } +} + +sal_uInt16 ToolBarManager::ConvertStyleToToolboxItemBits( sal_Int32 nStyle ) +{ + sal_uInt16 nItemBits( 0 ); + if ( nStyle & ::com::sun::star::ui::ItemStyle::RADIO_CHECK ) + nItemBits |= TIB_RADIOCHECK; + if ( nStyle & ::com::sun::star::ui::ItemStyle::ALIGN_LEFT ) + nItemBits |= TIB_LEFT; + if ( nStyle & ::com::sun::star::ui::ItemStyle::AUTO_SIZE ) + nItemBits |= TIB_AUTOSIZE; + if ( nStyle & ::com::sun::star::ui::ItemStyle::DROP_DOWN ) + nItemBits |= TIB_DROPDOWN; + if ( nStyle & ::com::sun::star::ui::ItemStyle::REPEAT ) + nItemBits |= TIB_REPEAT; + if ( nStyle & ::com::sun::star::ui::ItemStyle::DROPDOWN_ONLY ) + nItemBits |= TIB_DROPDOWNONLY; + if ( nStyle & ::com::sun::star::ui::ItemStyle::TEXT ) + nItemBits |= TIB_TEXT_ONLY; + if ( nStyle & ::com::sun::star::ui::ItemStyle::ICON ) + nItemBits |= TIB_ICON_ONLY; + + return nItemBits; +} + +void ToolBarManager::FillToolbar( const Reference< XIndexAccess >& rItemContainer ) +{ + ::rtl::OString aTbxName = rtl::OUStringToOString( m_aResourceName, RTL_TEXTENCODING_ASCII_US ); + + RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::ToolBarManager::FillToolbar" ); + RTL_LOGFILE_CONTEXT_TRACE1( aLog, "framework (cd100003) ::ToolBarManager::FillToolbar %s", aTbxName.getStr() ); + + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + return; + + sal_uInt16 nId( 1 ); + ::rtl::OUString aHelpIdPrefix( RTL_CONSTASCII_USTRINGPARAM( HELPID_PREFIX )); + + Reference< XModuleManager > xModuleManager( Reference< XModuleManager >( + m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY )); + if ( !m_xDocImageManager.is() ) + { + Reference< XModel > xModel( GetModelFromFrame() ); + if ( xModel.is() ) + { + Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY ); + if ( xSupplier.is() ) + { + m_xDocUICfgMgr.set( xSupplier->getUIConfigurationManager(), UNO_QUERY ); + m_xDocImageManager = Reference< XImageManager >( m_xDocUICfgMgr->getImageManager(), UNO_QUERY ); + m_xDocImageManager->addConfigurationListener( + Reference< XUIConfigurationListener >( + static_cast< OWeakObject* >( this ), UNO_QUERY )); + } + } + } + + try + { + if ( xModuleManager.is() ) + m_aModuleIdentifier = xModuleManager->identify( Reference< XInterface >( m_xFrame, UNO_QUERY ) ); + } + catch( Exception& ) + { + } + + if ( !m_xModuleImageManager.is() ) + { + Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier( m_xServiceManager->createInstance( + SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ), + UNO_QUERY ); + m_xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier ); + m_xModuleImageManager = Reference< XImageManager >( m_xUICfgMgr->getImageManager(), UNO_QUERY ); + m_xModuleImageManager->addConfigurationListener( Reference< XUIConfigurationListener >( + static_cast< OWeakObject* >( this ), UNO_QUERY )); + } + + RemoveControllers(); + + // reset and fill command map + m_pToolBar->Clear(); + m_aControllerMap.clear(); + m_aCommandMap.clear(); + + m_aMenuMap.clear(); + + CommandInfo aCmdInfo; + for ( sal_Int32 n = 0; n < rItemContainer->getCount(); n++ ) + { + Sequence< PropertyValue > aProp; + rtl::OUString aCommandURL; + rtl::OUString aLabel; + rtl::OUString aHelpURL; + rtl::OUString aTooltip; + sal_uInt16 nType( ::com::sun::star::ui::ItemType::DEFAULT ); + sal_uInt16 nWidth( 0 ); + sal_Bool bIsVisible( sal_True ); + sal_uInt32 nStyle( 0 ); + + Reference< XIndexAccess > aMenuDesc; + try + { + if ( rItemContainer->getByIndex( n ) >>= aProp ) + { + for ( int i = 0; i < aProp.getLength(); i++ ) + { + if ( aProp[i].Name.equalsAsciiL( ITEM_DESCRIPTOR_COMMANDURL, ITEM_DESCRIPTOR_COMMANDURL_LEN )) + { + aProp[i].Value >>= aCommandURL; + if ( aCommandURL.compareToAscii(MENUPREFIX, RTL_CONSTASCII_LENGTH(MENUPREFIX) ) == 0 ) + { + try + { + Reference< XIndexAccess > xMenuContainer; + if ( m_xDocUICfgMgr.is() ) + xMenuContainer = m_xDocUICfgMgr->getSettings( aCommandURL, sal_False ); + if ( !xMenuContainer.is() && m_xUICfgMgr.is() ) + xMenuContainer = m_xUICfgMgr->getSettings( aCommandURL, sal_False ); + if ( xMenuContainer.is() && xMenuContainer->getCount() ) + { + Sequence< PropertyValue > aProps; + // drop down menu info is currently + // the first ( and only ) menu + // in the menusettings container + xMenuContainer->getByIndex(0) >>= aProps; + for ( sal_Int32 index=0; index<aProps.getLength(); ++index ) + { + if ( aProps[ index ].Name.equalsAsciiL( ITEM_DESCRIPTOR_CONTAINER, ITEM_DESCRIPTOR_CONTAINER_LEN )) + + { + aProps[ index ].Value >>= aMenuDesc; + break; + } + } + } + } + catch( Exception& ) + { + } + } + } + else if ( aProp[i].Name.equalsAsciiL( ITEM_DESCRIPTOR_HELPURL, ITEM_DESCRIPTOR_HELPURL_LEN )) + aProp[i].Value >>= aHelpURL; + else if ( aProp[i].Name.equalsAsciiL( ITEM_DESCRIPTOR_TOOLTIP, ITEM_DESCRIPTOR_TOOLTIP_LEN )) + aProp[i].Value >>= aTooltip; + else if ( aProp[i].Name.equalsAsciiL( ITEM_DESCRIPTOR_LABEL, ITEM_DESCRIPTOR_LABEL_LEN )) + aProp[i].Value >>= aLabel; + else if ( aProp[i].Name.equalsAsciiL( ITEM_DESCRIPTOR_TYPE, ITEM_DESCRIPTOR_TYPE_LEN )) + aProp[i].Value >>= nType; + else if ( aProp[i].Name.equalsAsciiL( ITEM_DESCRIPTOR_VISIBLE, ITEM_DESCRIPTOR_VISIBLE_LEN )) + aProp[i].Value >>= bIsVisible; + else if ( aProp[i].Name.equalsAsciiL( ITEM_DESCRIPTOR_WIDTH, ITEM_DESCRIPTOR_WIDTH_LEN )) + aProp[i].Value >>= nWidth; + else if ( aProp[i].Name.equalsAsciiL( ITEM_DESCRIPTOR_STYLE, ITEM_DESCRIPTOR_STYLE_LEN )) + aProp[i].Value >>= nStyle; + } + + if (( nType == ::com::sun::star::ui::ItemType::DEFAULT ) && ( aCommandURL.getLength() > 0 )) + { + ::rtl::OUString aString( RetrieveLabelFromCommand( aCommandURL )); + + sal_uInt16 nItemBits = ConvertStyleToToolboxItemBits( nStyle ); + if ( aMenuDesc.is() ) + m_aMenuMap[ nId ] = aMenuDesc; + m_pToolBar->InsertItem( nId, aString, nItemBits ); + m_pToolBar->SetItemCommand( nId, aCommandURL ); + if ( aTooltip.getLength() ) + { + m_pToolBar->SetQuickHelpText( nId, aTooltip ); + } + else + { + ::rtl::OUString sQuickHelp( aString ); + ::rtl::OUString sShortCut; + if( RetrieveShortcut( aCommandURL, sShortCut ) ) + { + sQuickHelp += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " (" ) ); + sQuickHelp += sShortCut; + sQuickHelp += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ")" ) ); + } + + m_pToolBar->SetQuickHelpText( nId, sQuickHelp ); + } + + if ( aLabel.getLength() > 0 ) + { + m_pToolBar->SetItemText( nId, aLabel ); + } + else + { + m_pToolBar->SetItemText( nId, aString ); + } + m_pToolBar->EnableItem( nId, sal_True ); + m_pToolBar->SetItemState( nId, STATE_NOCHECK ); + + // Fill command map. It stores all our commands and from what + // image manager we got our image. So we can decide if we have to use an + // image from a notification message. + CommandToInfoMap::iterator pIter = m_aCommandMap.find( aCommandURL ); + if ( pIter == m_aCommandMap.end()) + { + aCmdInfo.nId = nId; + aCmdInfo.nWidth = nWidth; + m_aCommandMap.insert( CommandToInfoMap::value_type( aCommandURL, aCmdInfo )); + } + else + { + pIter->second.aIds.push_back( nId ); + } + + if ( !bIsVisible ) + m_pToolBar->HideItem( nId ); + + ++nId; + } + else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_LINE ) + { + m_pToolBar->InsertSeparator(); + } + else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_SPACE ) + { + m_pToolBar->InsertSpace(); + } + else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_LINEBREAK ) + { + m_pToolBar->InsertBreak(); + } + } + } + catch ( ::com::sun::star::lang::IndexOutOfBoundsException& ) + { + break; + } + } + + // Support add-on toolbar merging here. Working directly on the toolbar object is much + // simpler and faster. + const sal_uInt16 TOOLBAR_ITEM_STARTID = 1000; + + MergeToolbarInstructionContainer aMergeInstructionContainer; + + // Retrieve the toolbar name from the resource name + ::rtl::OUString aToolbarName( m_aResourceName ); + sal_Int32 nIndex = aToolbarName.lastIndexOf( '/' ); + if (( nIndex > 0 ) && ( nIndex < aToolbarName.getLength() )) + aToolbarName = aToolbarName.copy( nIndex+1 ); + + AddonsOptions().GetMergeToolbarInstructions( aToolbarName, aMergeInstructionContainer ); + + if ( !aMergeInstructionContainer.empty() ) + { + sal_uInt16 nItemId( TOOLBAR_ITEM_STARTID ); + const sal_uInt32 nCount = aMergeInstructionContainer.size(); + for ( sal_uInt32 i=0; i < nCount; i++ ) + { + MergeToolbarInstruction& rInstruction = aMergeInstructionContainer[i]; + if ( ToolBarMerger::IsCorrectContext( rInstruction.aMergeContext, m_aModuleIdentifier )) + { + ReferenceToolbarPathInfo aRefPoint = ToolBarMerger::FindReferencePoint( m_pToolBar, rInstruction.aMergePoint ); + + // convert the sequence< sequence< propertyvalue > > structure to + // something we can better handle. A vector with item data + AddonToolbarItemContainer aItems; + ToolBarMerger::ConvertSeqSeqToVector( rInstruction.aMergeToolbarItems, aItems ); + + if ( aRefPoint.bResult ) + { + ToolBarMerger::ProcessMergeOperation( m_xFrame, + m_pToolBar, + aRefPoint.nPos, + nItemId, + m_aCommandMap, + m_aModuleIdentifier, + rInstruction.aMergeCommand, + rInstruction.aMergeCommandParameter, + aItems ); + } + else + { + ToolBarMerger::ProcessMergeFallback( m_xFrame, + m_pToolBar, + aRefPoint.nPos, + nItemId, + m_aCommandMap, + m_aModuleIdentifier, + rInstruction.aMergeCommand, + rInstruction.aMergeFallback, + aItems ); + } + } + } + } + + // Request images for all toolbar items. Must be done before CreateControllers as + // some controllers need access to the image. + RequestImages(); + + // Create controllers after we set the images. There are controllers which needs + // an image at the toolbar at creation time! + CreateControllers(); + + // Notify controllers that they are now correctly initialized and can start listening + // toolbars that will open in popup mode will be updated immediately to avoid flickering + if( m_pToolBar->WillUsePopupMode() ) + UpdateControllers(); + else if ( m_pToolBar->IsReallyVisible() ) + m_aAsyncUpdateControllersTimer.Start(); + + // Try to retrieve UIName from the container property set and set it as the title + // if it is not empty. + Reference< XPropertySet > xPropSet( rItemContainer, UNO_QUERY ); + if ( xPropSet.is() ) + { + try + { + rtl::OUString aUIName; + xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))) >>= aUIName; + if ( aUIName.getLength() > 0 ) + m_pToolBar->SetText( aUIName ); + } + catch ( Exception& ) + { + } + } +} + +void ToolBarManager::RequestImages() +{ + RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::ToolBarManager::RequestImages" ); + + // Request images from image manager + Sequence< rtl::OUString > aCmdURLSeq( m_aCommandMap.size() ); + Sequence< Reference< XGraphic > > aDocGraphicSeq; + Sequence< Reference< XGraphic > > aModGraphicSeq; + + sal_uInt32 i = 0; + CommandToInfoMap::iterator pIter = m_aCommandMap.begin(); + CommandToInfoMap::iterator pEnd = m_aCommandMap.end(); + while ( pIter != pEnd ) + { + aCmdURLSeq[i++] = pIter->first; + ++pIter; + } + + sal_Bool bBigImages( SvtMiscOptions().AreCurrentSymbolsLarge() ); + m_bIsHiContrast = m_pToolBar->GetSettings().GetStyleSettings().GetHighContrastMode(); + sal_Int16 p = getImageTypeFromBools( SvtMiscOptions().AreCurrentSymbolsLarge(), m_bIsHiContrast ); + + if ( m_xDocImageManager.is() ) + aDocGraphicSeq = m_xDocImageManager->getImages( p, aCmdURLSeq ); + aModGraphicSeq = m_xModuleImageManager->getImages( p, aCmdURLSeq ); + + i = 0; + pIter = m_aCommandMap.begin(); + while ( pIter != pEnd ) + { + rtl::OUString aCommandURL = aCmdURLSeq[i]; + + Image aImage; + if ( aDocGraphicSeq.getLength() > 0 ) + aImage = Image( aDocGraphicSeq[i] ); + if ( !aImage ) + { + aImage = Image( aModGraphicSeq[i] ); + // Try also to query for add-on images before giving up and use an + // empty image. + if ( !aImage ) + aImage = QueryAddonsImage( aCmdURLSeq[i], bBigImages, m_bIsHiContrast ); + + pIter->second.nImageInfo = 1; // mark image as module based + } + else + { + pIter->second.nImageInfo = 0; // mark image as document based + } + setToolBarImage(aImage,pIter); + ++pIter; + ++i; + } +} + +void ToolBarManager::notifyRegisteredControllers( const rtl::OUString& aUIElementName, const rtl::OUString& aCommand ) +{ + ResetableGuard aGuard( m_aLock ); + if ( !m_aSubToolBarControllerMap.empty() ) + { + SubToolBarToSubToolBarControllerMap::const_iterator pIter = + m_aSubToolBarControllerMap.find( aUIElementName ); + + if ( pIter != m_aSubToolBarControllerMap.end() ) + { + const SubToolBarControllerVector& rSubToolBarVector = pIter->second; + if ( !rSubToolBarVector.empty() ) + { + SubToolBarControllerVector aNotifyVector = rSubToolBarVector; + aGuard.unlock(); + + const sal_uInt32 nCount = aNotifyVector.size(); + for ( sal_uInt32 i=0; i < nCount; i++ ) + { + try + { + Reference< XSubToolbarController > xController = aNotifyVector[i]; + if ( xController.is() ) + xController->functionSelected( aCommand ); + } + catch ( RuntimeException& e ) + { + throw e; + } + catch ( Exception& ) + { + } + } + } + } + } +} +long ToolBarManager::HandleClick(void ( SAL_CALL XToolbarController::*_pClick )()) +{ + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + return 1; + + sal_uInt16 nId( m_pToolBar->GetCurItemId() ); + ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId ); + if ( pIter != m_aControllerMap.end() ) + { + Reference< XToolbarController > xController( pIter->second, UNO_QUERY ); + + if ( xController.is() ) + (xController.get()->*_pClick)( ); + } // if ( pIter != m_aControllerMap.end() ) + return 1; +} + +IMPL_LINK( ToolBarManager, Click, ToolBox*, EMPTYARG ) +{ + return HandleClick(&XToolbarController::click); +} + +IMPL_LINK( ToolBarManager, DropdownClick, ToolBox*, EMPTYARG ) +{ + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + return 1; + + sal_uInt16 nId( m_pToolBar->GetCurItemId() ); + ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId ); + if ( pIter != m_aControllerMap.end() ) + { + Reference< XToolbarController > xController( pIter->second, UNO_QUERY ); + + if ( xController.is() ) + { + Reference< XWindow > xWin = xController->createPopupWindow(); + if ( xWin.is() ) + xWin->setFocus(); + } + } + return 1; +} + +IMPL_LINK( ToolBarManager, DoubleClick, ToolBox*, EMPTYARG ) +{ + return HandleClick(&XToolbarController::doubleClick); +} + +void ToolBarManager::ImplClearPopupMenu( ToolBox *pToolBar ) +{ + if ( m_bDisposed ) + return; + + PopupMenu *pMenu = pToolBar->GetMenu(); + + // remove config entries from menu, so we have a clean menu to start with + // remove submenu first + PopupMenu* pItemMenu = pMenu->GetPopupMenu( 1 ); + if( pItemMenu ) + { + pItemMenu->Clear(); + delete pItemMenu; + pItemMenu = NULL; + pMenu->SetPopupMenu( 1, pItemMenu ); + } + + // remove all items that were not added by the toolbar itself + sal_uInt16 i; + for( i=0; i<pMenu->GetItemCount(); ) + { + if( pMenu->GetItemId( i ) < TOOLBOX_MENUITEM_START ) + pMenu->RemoveItem( i ); + else + i++; + } +} + +IMPL_LINK( ToolBarManager, MenuDeactivate, Menu*, pMenu ) +{ + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + return 1; + + if( pMenu != m_pToolBar->GetMenu() ) + return 1; + + ImplClearPopupMenu( m_pToolBar ); + + return 0; +} + +Reference< XModel > ToolBarManager::GetModelFromFrame() const +{ + Reference< XController > xController = m_xFrame->getController(); + Reference< XModel > xModel; + if ( xController.is() ) + xModel = xController->getModel(); + + return xModel; +} + +sal_Bool ToolBarManager::IsPluginMode() const +{ + sal_Bool bPluginMode( sal_False ); + + if ( m_xFrame.is() ) + { + Reference< XModel > xModel = GetModelFromFrame(); + if ( xModel.is() ) + { + Sequence< PropertyValue > aSeq = xModel->getArgs(); + comphelper::MediaDescriptor aMediaDescriptor( aSeq ); + bPluginMode = aMediaDescriptor.getUnpackedValueOrDefault< sal_Bool >( + comphelper::MediaDescriptor::PROP_VIEWONLY(), sal_False ); + } + } + + return bPluginMode; +} + +bool ToolBarManager::MenuItemAllowed( sal_uInt16 ) const +{ + return true; +} + +//added for i33668 by shizhoubo : 200804 +PopupMenu * ToolBarManager::GetToolBarCustomMeun(ToolBox* pToolBar) +{ + PopupMenu *pMenu = pToolBar->GetMenu(); + // remove all entries before inserting new ones + ImplClearPopupMenu( pToolBar ); + // No config menu entries if command ".uno:ConfigureDialog" is not enabled + Reference< XDispatch > xDisp; + com::sun::star::util::URL aURL; + if ( m_xFrame.is() ) + { + Reference< XDispatchProvider > xProv( m_xFrame, UNO_QUERY ); + aURL.Complete = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ConfigureDialog" )); + m_xURLTransformer->parseStrict( aURL ); + if ( xProv.is() ) + xDisp = xProv->queryDispatch( aURL, ::rtl::OUString(), 0 ); + + if ( !xDisp.is() || IsPluginMode() ) + return 0; + } + + // popup menu for quick customization + sal_Bool bHideDisabledEntries = !SvtMenuOptions().IsEntryHidingEnabled(); + PopupMenu aPopupMenu( FwkResId( POPUPMENU_TOOLBAR_QUICKCUSTOMIZATION )); + + if ( m_pToolBar->IsCustomize() ) + { + sal_uInt16 nPos( 0 ); + PopupMenu* pItemMenu( aPopupMenu.GetPopupMenu( 1 )); + + sal_Bool bIsFloating( sal_False ); + + DockingManager* pDockMgr = Window::GetDockingManager(); + if ( pDockMgr ) + bIsFloating = pDockMgr->IsFloating( m_pToolBar ); + + if ( !bIsFloating ) + { + aPopupMenu.EnableItem( MENUITEM_TOOLBAR_DOCKTOOLBAR, sal_False ); + aPopupMenu.EnableItem( MENUITEM_TOOLBAR_DOCKALLTOOLBAR, sal_False ); + Reference< XDockableWindow > xDockable( VCLUnoHelper::GetInterface( m_pToolBar ), UNO_QUERY ); + if( xDockable.is() ) + aPopupMenu.CheckItem( MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION, xDockable->isLocked() ); + } + else + aPopupMenu.EnableItem( MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION, sal_False ); + + if ( !m_bCanBeCustomized ) + { + // Non-configurable toolbars should disable configuration menu items + aPopupMenu.EnableItem( MENUITEM_TOOLBAR_VISIBLEBUTTON, sal_False ); + aPopupMenu.EnableItem( MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR, sal_False ); + } + + // Disable menu item CLOSE if the toolbar has no closer + //added for issue64028 by shizhoubo + if( !(pToolBar->GetFloatStyle() & WB_CLOSEABLE) ) + aPopupMenu.EnableItem(MENUITEM_TOOLBAR_CLOSE, sal_False); + //end + + pItemMenu->SetMenuFlags (pItemMenu->GetMenuFlags () | + MENU_FLAG_SHOWCHECKIMAGES); + + for ( nPos = 0; nPos < m_pToolBar->GetItemCount(); ++nPos ) + { + if ( m_pToolBar->GetItemType(nPos) == TOOLBOXITEM_BUTTON ) + { + sal_uInt16 nId = m_pToolBar->GetItemId(nPos); + ::rtl::OUString aCommandURL = m_pToolBar->GetItemCommand( nId ); + pItemMenu->InsertItem( STARTID_CUSTOMIZE_POPUPMENU+nPos, m_pToolBar->GetItemText( nId ), MIB_CHECKABLE ); + pItemMenu->CheckItem( STARTID_CUSTOMIZE_POPUPMENU+nPos, m_pToolBar->IsItemVisible( nId ) ); + pItemMenu->SetItemCommand( STARTID_CUSTOMIZE_POPUPMENU+nPos, aCommandURL ); + pItemMenu->SetItemImage( STARTID_CUSTOMIZE_POPUPMENU+nPos, + GetImageFromURL( m_xFrame, + aCommandURL, + sal_False, + m_bIsHiContrast )); + } + else + { + pItemMenu->InsertSeparator(); + } + } + } + else + { + sal_uInt16 nPos = aPopupMenu.GetItemPos( MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR ); + if ( nPos != MENU_ITEM_NOTFOUND ) + aPopupMenu.RemoveItem( nPos ); + } + + // copy all menu items to the toolbar menu + if( pMenu->GetItemCount() ) + pMenu->InsertSeparator(); + + sal_uInt16 i; + for( i=0; i< aPopupMenu.GetItemCount(); i++) + { + sal_uInt16 nId = aPopupMenu.GetItemId( i ); + if ( MenuItemAllowed( nId )) + pMenu->CopyItem( aPopupMenu, i, MENU_APPEND ); + } + + // set submenu to toolbar menu + if( aPopupMenu.GetPopupMenu( 1 ) ) + { + // create an own submenu to avoid auto-delete when resource menu is deleted + PopupMenu *pItemMenu = new PopupMenu(); + + pItemMenu->SetMenuFlags (pItemMenu->GetMenuFlags () | + MENU_FLAG_SHOWCHECKIMAGES); + + for( i=0; i< aPopupMenu.GetPopupMenu( 1 )->GetItemCount(); i++) + pItemMenu->CopyItem( *aPopupMenu.GetPopupMenu( 1 ), i, MENU_APPEND ); + + pMenu->SetPopupMenu( 1, pItemMenu ); + } + + if ( bHideDisabledEntries ) + pMenu->RemoveDisabledEntries(); + + return pMenu; +} + +// addd for 33668 by shizhoubo +IMPL_LINK( ToolBarManager, Command, CommandEvent*, pCmdEvt ) +{ + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + return 1; + if ( pCmdEvt->GetCommand() != COMMAND_CONTEXTMENU ) + return 0; + + PopupMenu * pMenu = GetToolBarCustomMeun(m_pToolBar); + if (pMenu) + { + // make sure all disabled entries will be shown + pMenu->SetMenuFlags( pMenu->GetMenuFlags() | MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES ); + ::Point aPoint( pCmdEvt->GetMousePosPixel() ); + pMenu->Execute( m_pToolBar, aPoint ); + } + + return 0; +} +//end + +IMPL_LINK( ToolBarManager, MenuButton, ToolBox*, pToolBar ) +{ + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + return 1; + //modify for i33668 by shizhoubo:2008:04 + GetToolBarCustomMeun(pToolBar); + //end + return 0; + } + +IMPL_LINK( ToolBarManager, MenuSelect, Menu*, pMenu ) +{ + // We have to hold a reference to ourself as it is possible that we will be disposed and + // our refcount could be zero (destruction) otherwise. + Reference< XInterface > xInterface( static_cast< OWeakObject* >( this ), UNO_QUERY ); + + { + // The guard must be in its own context as the we can get destroyed when our + // own xInterface reference get destroyed! + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + return 1; + + switch ( pMenu->GetCurItemId() ) + { + case MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR: + { + Reference< XDispatch > xDisp; + com::sun::star::util::URL aURL; + if ( m_xFrame.is() ) + { + Reference< XDispatchProvider > xProv( m_xFrame, UNO_QUERY ); + aURL.Complete = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ConfigureDialog" )); + m_xURLTransformer->parseStrict( aURL ); + if ( xProv.is() ) + xDisp = xProv->queryDispatch( aURL, ::rtl::OUString(), 0 ); + } + + if ( xDisp.is() ) + { + Sequence< PropertyValue > aPropSeq( 1 ); + + aPropSeq[ 0 ].Name = + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ResourceURL")); + aPropSeq[ 0 ].Value <<= m_aResourceName; + + xDisp->dispatch( aURL, aPropSeq ); + } + break; + } + + case MENUITEM_TOOLBAR_DOCKTOOLBAR: + { + ExecuteInfo* pExecuteInfo = new ExecuteInfo; + + pExecuteInfo->aToolbarResName = m_aResourceName; + pExecuteInfo->nCmd = EXEC_CMD_DOCKTOOLBAR; + pExecuteInfo->xLayoutManager = getLayoutManagerFromFrame( m_xFrame ); + + Application::PostUserEvent( STATIC_LINK(0, ToolBarManager, ExecuteHdl_Impl), pExecuteInfo ); + break; + } + + case MENUITEM_TOOLBAR_DOCKALLTOOLBAR: + { + ExecuteInfo* pExecuteInfo = new ExecuteInfo; + + pExecuteInfo->aToolbarResName = m_aResourceName; + pExecuteInfo->nCmd = EXEC_CMD_DOCKALLTOOLBARS; + pExecuteInfo->xLayoutManager = getLayoutManagerFromFrame( m_xFrame ); + + Application::PostUserEvent( STATIC_LINK(0, ToolBarManager, ExecuteHdl_Impl), pExecuteInfo ); + break; + } + + case MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION: + { + Reference< XLayoutManager > xLayoutManager = getLayoutManagerFromFrame( m_xFrame ); + if ( xLayoutManager.is() ) + { + Reference< XDockableWindow > xDockable( VCLUnoHelper::GetInterface( m_pToolBar ), UNO_QUERY ); + + if( xDockable->isLocked() ) + xLayoutManager->unlockWindow( m_aResourceName ); + else + xLayoutManager->lockWindow( m_aResourceName ); + } + break; + } + + case MENUITEM_TOOLBAR_CLOSE: + { + ExecuteInfo* pExecuteInfo = new ExecuteInfo; + + pExecuteInfo->aToolbarResName = m_aResourceName; + pExecuteInfo->nCmd = EXEC_CMD_CLOSETOOLBAR; + pExecuteInfo->xLayoutManager = getLayoutManagerFromFrame( m_xFrame ); + pExecuteInfo->xWindow = VCLUnoHelper::GetInterface( m_pToolBar ); + + Application::PostUserEvent( STATIC_LINK(0, ToolBarManager, ExecuteHdl_Impl), pExecuteInfo ); + } + + default: + { + sal_uInt16 nId = pMenu->GetCurItemId(); + if(( nId > 0 ) && ( nId < TOOLBOX_MENUITEM_START )) + { + // toggle toolbar button visibility + rtl::OUString aCommand = pMenu->GetItemCommand( nId ); + + Reference< XLayoutManager > xLayoutManager = getLayoutManagerFromFrame( m_xFrame ); + if ( xLayoutManager.is() ) + { + Reference< XUIElementSettings > xUIElementSettings( xLayoutManager->getElement( m_aResourceName ), UNO_QUERY ); + if ( xUIElementSettings.is() ) + { + Reference< XIndexContainer > xItemContainer( xUIElementSettings->getSettings( sal_True ), UNO_QUERY ); + sal_Int32 nCount = xItemContainer->getCount(); + for ( sal_Int32 i = 0; i < nCount; i++ ) + { + Sequence< PropertyValue > aProp; + sal_Int32 nVisibleIndex( -1 ); + rtl::OUString aCommandURL; + sal_Bool bVisible( sal_False ); + + if ( xItemContainer->getByIndex( i ) >>= aProp ) + { + for ( sal_Int32 j = 0; j < aProp.getLength(); j++ ) + { + if ( aProp[j].Name.equalsAscii( ITEM_DESCRIPTOR_COMMANDURL )) + { + aProp[j].Value >>= aCommandURL; + } + else if ( aProp[j].Name.equalsAscii( ITEM_DESCRIPTOR_VISIBLE )) + { + aProp[j].Value >>= bVisible; + nVisibleIndex = j; + } + } + + if (( aCommandURL == aCommand ) && ( nVisibleIndex >= 0 )) + { + // We have found the requested item, toggle the visible flag + // and write back the configuration settings to the toolbar + aProp[nVisibleIndex].Value = makeAny( !bVisible ); + try + { + xItemContainer->replaceByIndex( i, makeAny( aProp )); + xUIElementSettings->setSettings( Reference< XIndexAccess >( xItemContainer, UNO_QUERY )); + Reference< XPropertySet > xPropSet( xUIElementSettings, UNO_QUERY ); + if ( xPropSet.is() ) + { + Reference< XUIConfigurationPersistence > xUICfgMgr; + if (( xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ConfigurationSource" ))) >>= xUICfgMgr ) && ( xUICfgMgr.is() )) + xUICfgMgr->store(); + } + } + catch ( Exception& ) + { + } + + break; + } + } + } + } + } + } + break; + } + } + + // remove all entries - deactivate is not reliable + // The method checks if we are already disposed and in that case does nothing! + ImplClearPopupMenu( m_pToolBar ); + } + + return 1; +} + +IMPL_LINK( ToolBarManager, Select, ToolBox*, EMPTYARG ) +{ + if ( m_bDisposed ) + return 1; + + sal_Int16 nKeyModifier( (sal_Int16)m_pToolBar->GetModifier() ); + sal_uInt16 nId( m_pToolBar->GetCurItemId() ); + + ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId ); + if ( pIter != m_aControllerMap.end() ) + { + Reference< XToolbarController > xController( pIter->second, UNO_QUERY ); + + if ( xController.is() ) + xController->execute( nKeyModifier ); + } + + return 1; +} + +IMPL_LINK( ToolBarManager, Highlight, ToolBox*, EMPTYARG ) +{ + return 1; +} + +IMPL_LINK( ToolBarManager, Activate, ToolBox*, EMPTYARG ) +{ + return 1; +} + +IMPL_LINK( ToolBarManager, Deactivate, ToolBox*, EMPTYARG ) +{ + return 1; +} + +IMPL_LINK( ToolBarManager, StateChanged, StateChangedType*, pStateChangedType ) +{ + if ( m_bDisposed ) + return 1; + + if ( *pStateChangedType == STATE_CHANGE_CONTROLBACKGROUND ) + { + // Check if we need to get new images for normal/high contrast mode + CheckAndUpdateImages(); + } + else if ( *pStateChangedType == STATE_CHANGE_VISIBLE ) + { + if ( m_pToolBar->IsReallyVisible() ) + m_aAsyncUpdateControllersTimer.Start(); + } + else if ( *pStateChangedType == STATE_CHANGE_INITSHOW ) + { + m_aAsyncUpdateControllersTimer.Start(); + } + return 1; +} + +IMPL_LINK( ToolBarManager, DataChanged, DataChangedEvent*, pDataChangedEvent ) +{ + if ((( pDataChangedEvent->GetType() == DATACHANGED_SETTINGS ) || + ( pDataChangedEvent->GetType() == DATACHANGED_DISPLAY )) && + ( pDataChangedEvent->GetFlags() & SETTINGS_STYLE )) + { + // Check if we need to get new images for normal/high contrast mode + CheckAndUpdateImages(); + } + + for ( sal_uInt16 nPos = 0; nPos < m_pToolBar->GetItemCount(); ++nPos ) + { + const sal_uInt16 nId = m_pToolBar->GetItemId(nPos); + Window* pWindow = m_pToolBar->GetItemWindow( nId ); + if ( pWindow ) + { + const DataChangedEvent& rDCEvt( *pDataChangedEvent ); + pWindow->DataChanged( rDCEvt ); + } + } + + if ( !m_pToolBar->IsFloatingMode() && + m_pToolBar->IsVisible() ) + { + // Resize toolbar, layout manager is resize listener and will calc + // the layout automatically. + ::Size aSize( m_pToolBar->CalcWindowSizePixel() ); + m_pToolBar->SetOutputSizePixel( aSize ); + } + + return 1; +} + +IMPL_LINK( ToolBarManager, AsyncUpdateControllersHdl, Timer *, EMPTYARG ) +{ + // The guard must be in its own context as the we can get destroyed when our + // own xInterface reference get destroyed! + Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY ); + + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + return 1; + + // Request to update our controllers + m_aAsyncUpdateControllersTimer.Stop(); + UpdateControllers(); + + return 0; +} + +IMPL_STATIC_LINK_NOINSTANCE( ToolBarManager, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo ) +{ + try + { + // Asynchronous execution as this can lead to our own destruction! + if (( pExecuteInfo->nCmd == EXEC_CMD_CLOSETOOLBAR ) && + ( pExecuteInfo->xLayoutManager.is() ) && + ( pExecuteInfo->xWindow.is() )) + { + // Use docking window close to close the toolbar. The layout manager is + // listener and will react correctly according to the context sensitive + // flag of our toolbar. + Window* pWin = VCLUnoHelper::GetWindow( pExecuteInfo->xWindow ); + DockingWindow* pDockWin = dynamic_cast< DockingWindow* >( pWin ); + if ( pDockWin ) + pDockWin->Close(); + } + else if (( pExecuteInfo->nCmd == EXEC_CMD_DOCKTOOLBAR ) && + ( pExecuteInfo->xLayoutManager.is() )) + { + ::com::sun::star::awt::Point aPoint; + aPoint.X = aPoint.Y = SAL_MAX_INT32; + pExecuteInfo->xLayoutManager->dockWindow( pExecuteInfo->aToolbarResName, + DockingArea_DOCKINGAREA_DEFAULT, + aPoint ); + } + else if (( pExecuteInfo->nCmd == EXEC_CMD_DOCKALLTOOLBARS ) && + ( pExecuteInfo->xLayoutManager.is() )) + { + pExecuteInfo->xLayoutManager->dockAllWindows( UIElementType::TOOLBAR ); + } + } + catch ( Exception& ) + { + } + + delete pExecuteInfo; + return 0; +} + +Image ToolBarManager::QueryAddonsImage( const ::rtl::OUString& aCommandURL, bool bBigImages, bool bHiContrast ) +{ + Image aImage = framework::AddonsOptions().GetImageFromURL( aCommandURL, bBigImages, bHiContrast ); + return aImage; +} + +bool ToolBarManager::impl_RetrieveShortcutsFromConfiguration( + const Reference< XAcceleratorConfiguration >& rAccelCfg, + const rtl::OUString& rCommand, + rtl::OUString& rShortCut ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ToolBarManager::impl_RetrieveShortcutsFromConfiguration" ); + if ( rAccelCfg.is() ) + { + try + { + com::sun::star::awt::KeyEvent aKeyEvent; + Sequence< OUString > aCommands(1); + aCommands[0] = rCommand; + + Sequence< Any > aSeqKeyCode( rAccelCfg->getPreferredKeyEventsForCommandList( aCommands ) ); + if( aSeqKeyCode.getLength() == 1 ) + { + if ( aSeqKeyCode[0] >>= aKeyEvent ) + { + rShortCut = svt::AcceleratorExecute::st_AWTKey2VCLKey( aKeyEvent ).GetName(); + return true; + } + } + } + catch ( IllegalArgumentException& ) + { + } + } + + return false; +} + +bool ToolBarManager::RetrieveShortcut( const rtl::OUString& rCommandURL, rtl::OUString& rShortCut ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ToolBarManager::RetrieveShortcuts" ); + 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( m_xServiceManager->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 >( m_xServiceManager->createInstance( + SERVICENAME_GLOBALACCELERATORCONFIGURATION ), + UNO_QUERY ); + m_xGlobalAcceleratorManager = xGlobalAccelCfg; + } + } + + bool bFound = false; + + if ( m_xGlobalAcceleratorManager.is() ) + bFound = impl_RetrieveShortcutsFromConfiguration( xGlobalAccelCfg, rCommandURL, rShortCut ); + if ( !bFound && m_xModuleAcceleratorManager.is() ) + bFound = impl_RetrieveShortcutsFromConfiguration( xModuleAccelCfg, rCommandURL, rShortCut ); + if ( !bFound && m_xDocAcceleratorManager.is() ) + impl_RetrieveShortcutsFromConfiguration( xGlobalAccelCfg, rCommandURL, rShortCut ); + + if( bFound ) + return true; + } + return false; +} + +} + + + |