/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: toolbarsmenucontroller.cxx,v $ * $Revision: 1.21.40.1 $ * * 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 * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_framework.hxx" #include #include //_________________________________________________________________________________________________________________ // my own includes //_________________________________________________________________________________________________________________ #include #include "services.h" #ifndef __FRAMEWORK_CLASSES_RESOURCE_HRC_ #include #endif #include #include #include #include //_________________________________________________________________________________________________________________ // interface includes //_________________________________________________________________________________________________________________ #include #include #include #include #include #include #include #include #ifndef _COM_SUN_STAR_UI_XMODULEUICONFIGURATIONMANAGER_HPP_ #include #endif #include #ifndef _COM_SUN_STAR_UI_UIElementType_HPP_ #include #endif //_________________________________________________________________________________________________________________ // includes of other projects //_________________________________________________________________________________________________________________ #ifndef _VCL_MENU_HXX_ #include #endif #include #include #include #include #include #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ #include #endif #include #include #include #include //_________________________________________________________________________________________________________________ // Defines //_________________________________________________________________________________________________________________ // using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::frame; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::util; using namespace ::com::sun::star::container; using namespace ::com::sun::star::frame; using namespace ::com::sun::star::ui; static const char CONFIGURE_TOOLBARS_CMD[] = "ConfigureDialog"; static const char CONFIGURE_TOOLBARS[] = ".uno:ConfigureDialog"; static const char CMD_COLORBAR[] = ".uno:ColorControl"; static const char CMD_HYPERLINKBAR[] = ".uno:InsertHyperlink"; static const char CMD_FORMULABAR[] = ".uno:InsertFormula"; static const char CMD_INPUTLINEBAR[] = ".uno:InputLineVisible"; static const char CMD_RESTOREVISIBILITY[] = ".cmd:RestoreVisibility"; static const char ITEM_DESCRIPTOR_RESOURCEURL[] = "ResourceURL"; static const char ITEM_DESCRIPTOR_UINAME[] = "UIName"; static const char STATIC_PRIVATE_TB_RESOURCE[] = "private:resource/toolbar/"; static const char STATIC_CMD_PART[] = ".uno:AvailableToolbars?Toolbar:string="; static const char STATIC_INTERNAL_CMD_PART[] = ".cmd:"; namespace framework { typedef std::hash_map< rtl::OUString, rtl::OUString, OUStringHashCode, ::std::equal_to< ::rtl::OUString > > ToolbarHashMap; struct ToolBarEntry { rtl::OUString aUIName; rtl::OUString aCommand; sal_Bool bVisible; sal_Bool bContextSensitive; const CollatorWrapper* pCollatorWrapper; }; sal_Bool CompareToolBarEntry( const ToolBarEntry& aOne, const ToolBarEntry& aTwo ) { sal_Int32 nComp = aOne.pCollatorWrapper->compareString( aOne.aUIName, aTwo.aUIName ); if ( nComp < 0 ) return sal_True; else if ( nComp > 0 ) return sal_False; else return sal_False; } Reference< XLayoutManager > getLayoutManagerFromFrame( const Reference< XFrame >& rFrame ) { Reference< XPropertySet > xPropSet( rFrame, UNO_QUERY ); Reference< XLayoutManager > xLayoutManager; try { Any aValue = xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))); aValue >>= xLayoutManager; } catch ( UnknownPropertyException& ) { } return xLayoutManager; } struct ToolBarInfo { rtl::OUString aToolBarResName; rtl::OUString aToolBarUIName; }; DEFINE_XSERVICEINFO_MULTISERVICE ( ToolbarsMenuController , OWeakObject , SERVICENAME_POPUPMENUCONTROLLER , IMPLEMENTATIONNAME_TOOLBARSMENUCONTROLLER ) DEFINE_INIT_SERVICE ( ToolbarsMenuController, {} ) ToolbarsMenuController::ToolbarsMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) : PopupMenuControllerBase( xServiceManager ), m_aPropUIName( RTL_CONSTASCII_USTRINGPARAM( "UIName" )), m_aPropResourceURL( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" )), m_bModuleIdentified( sal_False ), m_bResetActive( sal_False ), m_aIntlWrapper( xServiceManager, Application::GetSettings().GetLocale() ) { } ToolbarsMenuController::~ToolbarsMenuController() { } void ToolbarsMenuController::addCommand( Reference< css::awt::XPopupMenu >& rPopupMenu, const rtl::OUString& rCommandURL, USHORT nHelpId, const rtl::OUString& rLabel ) { USHORT nItemId = m_xPopupMenu->getItemCount()+1; rtl::OUString aLabel; if ( rLabel.getLength() == 0 ) aLabel = getUINameFromCommand( rCommandURL ); else aLabel = rLabel; rPopupMenu->insertItem( nItemId, aLabel, 0, nItemId ); Reference< awt::XMenuExtended > xMenuExtended( m_xPopupMenu, UNO_QUERY ); xMenuExtended->setCommand( nItemId, rCommandURL ); bool bInternal = ( rCommandURL.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_INTERNAL_CMD_PART ))) == 0); if ( !bInternal ) { if ( !getDispatchFromCommandURL( rCommandURL ).is() ) m_xPopupMenu->enableItem( nItemId, sal_False ); } vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); Image aImage; const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings(); if ( rSettings.GetUseImagesInMenus() ) aImage = GetImageFromURL( m_xFrame, rCommandURL, FALSE, rSettings.GetMenuColor().IsDark() ); VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXPopupMenu::GetImplementation( rPopupMenu ); if ( pPopupMenu ) { PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu(); if ( !!aImage ) pVCLPopupMenu->SetItemImage( nItemId, aImage ); pVCLPopupMenu->SetHelpId( nItemId, nHelpId ); } m_aCommandVector.push_back( rCommandURL ); } Reference< XDispatch > ToolbarsMenuController::getDispatchFromCommandURL( const rtl::OUString& rCommandURL ) { URL aTargetURL; Sequence aArgs; Reference< XURLTransformer > xURLTransformer; Reference< XFrame > xFrame; { vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); xURLTransformer = m_xURLTransformer; xFrame = m_xFrame; } aTargetURL.Complete = rCommandURL; xURLTransformer->parseStrict( aTargetURL ); Reference< XDispatchProvider > xDispatchProvider( xFrame, UNO_QUERY ); if ( xDispatchProvider.is() ) return xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); else return Reference< XDispatch >(); } // private function rtl::OUString ToolbarsMenuController::getUINameFromCommand( const rtl::OUString& rCommandURL ) { rtl::OUString aLabel; if ( !m_bModuleIdentified ) { try { Reference< XModuleManager > xModuleManager( m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW ); m_aModuleIdentifier = xModuleManager->identify( m_xFrame ); Reference< XNameAccess > xNameAccess( m_xServiceManager->createInstance( SERVICENAME_UICOMMANDDESCRIPTION ), UNO_QUERY ); Any a = xNameAccess->getByName( m_aModuleIdentifier ); a >>= m_xUICommandDescription; } catch ( Exception& ) { } } if ( m_xUICommandDescription.is() ) { try { Sequence< PropertyValue > aPropSeq; rtl::OUString aStr; Any a( m_xUICommandDescription->getByName( rCommandURL )); if ( a >>= aPropSeq ) { for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ ) { if ( aPropSeq[i].Name.equalsAscii( "Label" )) { aPropSeq[i].Value >>= aStr; break; } } } aLabel = aStr; } catch ( Exception& ) { } } return aLabel; } static void fillHashMap( const Sequence< Sequence< ::com::sun::star::beans::PropertyValue > >& rSeqToolBars, ToolbarHashMap& rHashMap ) { for ( sal_Int32 i = 0; i < rSeqToolBars.getLength(); i++ ) { rtl::OUString aResourceURL; rtl::OUString aUIName; const PropertyValue* pProperties = rSeqToolBars[i].getConstArray(); for ( sal_Int32 j = 0; j < rSeqToolBars[i].getLength(); j++ ) { if ( pProperties[j].Name.equalsAscii( ITEM_DESCRIPTOR_RESOURCEURL) ) pProperties[j].Value >>= aResourceURL; else if ( pProperties[j].Name.equalsAscii( ITEM_DESCRIPTOR_UINAME) ) pProperties[j].Value >>= aUIName; } if ( aResourceURL.getLength() > 0 && rHashMap.find( aResourceURL ) == rHashMap.end() ) rHashMap.insert( ToolbarHashMap::value_type( aResourceURL, aUIName )); } } // private function Sequence< Sequence< com::sun::star::beans::PropertyValue > > ToolbarsMenuController::getLayoutManagerToolbars( const Reference< ::com::sun::star::frame::XLayoutManager >& rLayoutManager ) { std::vector< ToolBarInfo > aToolBarArray; Sequence< Reference< XUIElement > > aUIElements = rLayoutManager->getElements(); for ( sal_Int32 i = 0; i < aUIElements.getLength(); i++ ) { Reference< XUIElement > xUIElement( aUIElements[i] ); Reference< XPropertySet > xPropSet( aUIElements[i], UNO_QUERY ); if ( xPropSet.is() && xUIElement.is() ) { try { rtl::OUString aResName; sal_Int16 nType( -1 ); xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ))) >>= nType; xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" ))) >>= aResName; if (( nType == ::com::sun::star::ui::UIElementType::TOOLBAR ) && ( aResName.getLength() > 0 )) { ToolBarInfo aToolBarInfo; aToolBarInfo.aToolBarResName = aResName; vos::OGuard aGuard( Application::GetSolarMutex() ); Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY ); Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); if ( pWindow ) aToolBarInfo.aToolBarUIName = pWindow->GetText(); aToolBarArray.push_back( aToolBarInfo ); } } catch ( Exception& ) { } } } Sequence< com::sun::star::beans::PropertyValue > aTbSeq( 2 ); aTbSeq[0].Name = m_aPropUIName; aTbSeq[1].Name = m_aPropResourceURL; Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeq( aToolBarArray.size() ); for ( sal_uInt32 i = 0; i < aToolBarArray.size(); i++ ) { aTbSeq[0].Value <<= aToolBarArray[i].aToolBarUIName; aTbSeq[1].Value <<= aToolBarArray[i].aToolBarResName; aSeq[i] = aTbSeq; } return aSeq; } sal_Bool ToolbarsMenuController::isContextSensitiveToolbarNonVisible() { return m_bResetActive; } void ToolbarsMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopupMenu ) { vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); resetPopupMenu( rPopupMenu ); m_aCommandVector.clear(); // Retrieve layout manager for additional information rtl::OUString aEmptyString; Reference< awt::XMenuExtended > xMenuExtended( rPopupMenu, UNO_QUERY ); Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( m_xFrame )); m_bResetActive = sal_False; if ( xLayoutManager.is() ) { ToolbarHashMap aToolbarHashMap; if ( m_xDocCfgMgr.is() ) { Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeqDocToolBars = m_xDocCfgMgr->getUIElementsInfo( UIElementType::TOOLBAR ); fillHashMap( aSeqDocToolBars, aToolbarHashMap ); } if ( m_xModuleCfgMgr.is() ) { Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeqToolBars = m_xModuleCfgMgr->getUIElementsInfo( UIElementType::TOOLBAR ); fillHashMap( aSeqToolBars, aToolbarHashMap ); } std::vector< ToolBarEntry > aSortedTbs; rtl::OUString aStaticCmdPart( RTL_CONSTASCII_USTRINGPARAM( STATIC_CMD_PART )); Sequence< Sequence< com::sun::star::beans::PropertyValue > > aSeqFrameToolBars = getLayoutManagerToolbars( xLayoutManager ); fillHashMap( aSeqFrameToolBars, aToolbarHashMap ); ToolbarHashMap::const_iterator pIter = aToolbarHashMap.begin(); while ( pIter != aToolbarHashMap.end() ) { rtl::OUString aUIName = pIter->second; sal_Bool bHideFromMenu( sal_False ); sal_Bool bContextSensitive( sal_False ); sal_Bool bVisible( sal_False ); if ( aUIName.getLength() == 0 && m_xPersistentWindowState.is() ) { try { Sequence< PropertyValue > aWindowState; Any a( m_xPersistentWindowState->getByName( pIter->first )); if ( a >>= aWindowState ) { for ( sal_Int32 i = 0; i < aWindowState.getLength(); i++ ) { if ( aWindowState[i].Name.equalsAscii( WINDOWSTATE_PROPERTY_UINAME )) aWindowState[i].Value >>= aUIName; else if ( aWindowState[i].Name.equalsAscii( WINDOWSTATE_PROPERTY_HIDEFROMENU )) aWindowState[i].Value >>= bHideFromMenu; else if ( aWindowState[i].Name.equalsAscii( WINDOWSTATE_PROPERTY_CONTEXT )) aWindowState[i].Value >>= bContextSensitive; else if ( aWindowState[i].Name.equalsAscii( WINDOWSTATE_PROPERTY_VISIBLE )) aWindowState[i].Value >>= bVisible; } } } catch ( Exception& ) { } // Check if we have to enable/disable "Reset" menu item if ( bContextSensitive && !bVisible ) m_bResetActive = sal_True; } if (( aUIName.getLength() > 0 ) && ( !bHideFromMenu )) { ToolBarEntry aTbEntry; aTbEntry.aUIName = aUIName; aTbEntry.aCommand = pIter->first; aTbEntry.bVisible = xLayoutManager->isElementVisible( pIter->first ); aTbEntry.bContextSensitive = bContextSensitive; aTbEntry.pCollatorWrapper = m_aIntlWrapper.getCaseCollator(); aSortedTbs.push_back( aTbEntry ); } pIter++; } // sort toolbars std::sort( aSortedTbs.begin(), aSortedTbs.end(), CompareToolBarEntry ); sal_Int16 nIndex( 1 ); for ( sal_uInt32 i = 0; i < aSortedTbs.size(); i++ ) { USHORT nItemCount = m_xPopupMenu->getItemCount(); m_xPopupMenu->insertItem( nIndex, aSortedTbs[i].aUIName, css::awt::MenuItemStyle::CHECKABLE, nItemCount ); if ( aSortedTbs[i].bVisible ) m_xPopupMenu->checkItem( nIndex, sal_True ); { vos::OGuard aGuard( Application::GetSolarMutex() ); VCLXPopupMenu* pXPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( m_xPopupMenu ); PopupMenu* pVCLPopupMenu = (PopupMenu *)pXPopupMenu->GetMenu(); pVCLPopupMenu->SetUserValue( nIndex, ULONG( aSortedTbs[i].bContextSensitive ? 1L : 0L )); } // use VCL popup menu pointer to set vital information that are not part of the awt implementation rtl::OUStringBuffer aStrBuf( aStaticCmdPart ); sal_Int32 n = aSortedTbs[i].aCommand.lastIndexOf( '/' ); if (( n > 0 ) && (( n+1 ) < aSortedTbs[i].aCommand.getLength() )) aStrBuf.append( aSortedTbs[i].aCommand.copy( n+1 )); rtl::OUString aCmd( aStrBuf.makeStringAndClear() ); // Store complete uno-command so it can also be dispatched. This is necessary to support // the test tool! xMenuExtended->setCommand( nIndex, aCmd ); ++nIndex; } // Create commands for non-toolbars if ( m_aModuleIdentifier.equalsAscii( "com.sun.star.text.TextDocument" ) || m_aModuleIdentifier.equalsAscii( "com.sun.star.text.WebDocument" ) || m_aModuleIdentifier.equalsAscii( "com.sun.star.text.GlobalDocument" ) || m_aModuleIdentifier.equalsAscii( "com.sun.star.drawing.DrawingDocument" ) || m_aModuleIdentifier.equalsAscii( "com.sun.star.presentation.PresentationDocument" ) || m_aModuleIdentifier.equalsAscii( "com.sun.star.sheet.SpreadsheetDocument" )) { addCommand( m_xPopupMenu, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CMD_HYPERLINKBAR )), 10360, aEmptyString ); if ( m_aModuleIdentifier.equalsAscii( "com.sun.star.drawing.DrawingDocument" ) || m_aModuleIdentifier.equalsAscii( "com.sun.star.presentation.PresentationDocument" )) addCommand( m_xPopupMenu, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CMD_COLORBAR )), 10417, aEmptyString ); else if ( m_aModuleIdentifier.equalsAscii( "com.sun.star.sheet.SpreadsheetDocument" )) addCommand( m_xPopupMenu, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CMD_INPUTLINEBAR )), 26241, aEmptyString ); else addCommand( m_xPopupMenu, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CMD_FORMULABAR )), 20128, aEmptyString ); } sal_Bool bAddCommand( sal_True ); SvtCommandOptions aCmdOptions; rtl::OUString aConfigureToolbar( RTL_CONSTASCII_USTRINGPARAM( CONFIGURE_TOOLBARS )); if ( aCmdOptions.HasEntries( SvtCommandOptions::CMDOPTION_DISABLED )) { if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CONFIGURE_TOOLBARS_CMD )))) bAddCommand = sal_False; } if ( bAddCommand ) { // Create command for configure if ( m_xPopupMenu->getItemCount() > 0 ) { USHORT nItemCount = m_xPopupMenu->getItemCount(); m_xPopupMenu->insertSeparator( nItemCount+1 ); } addCommand( m_xPopupMenu, aConfigureToolbar, 5904, aEmptyString ); } // Add separator if no configure has been added if ( !bAddCommand ) { // Create command for configure if ( m_xPopupMenu->getItemCount() > 0 ) { USHORT nItemCount = m_xPopupMenu->getItemCount(); m_xPopupMenu->insertSeparator( nItemCount+1 ); } } String aLabelStr = String( FwkResId( STR_RESTORE_TOOLBARS )); rtl::OUString aRestoreCmd( RTL_CONSTASCII_USTRINGPARAM( CMD_RESTOREVISIBILITY )); addCommand( m_xPopupMenu, aRestoreCmd, 9999, aLabelStr ); } } // XEventListener void SAL_CALL ToolbarsMenuController::disposing( const EventObject& ) throw ( RuntimeException ) { Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY ); ResetableGuard aLock( m_aLock ); m_xFrame.clear(); m_xDispatch.clear(); m_xDocCfgMgr.clear(); m_xModuleCfgMgr.clear(); m_xServiceManager.clear(); if ( m_xPopupMenu.is() ) m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY )); m_xPopupMenu.clear(); } // XStatusListener void SAL_CALL ToolbarsMenuController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException ) { rtl::OUString aFeatureURL( Event.FeatureURL.Complete ); // All other status events will be processed here sal_Bool bSetCheckmark = sal_False; sal_Bool bCheckmark = sal_False; ResetableGuard aLock( m_aLock ); Reference< css::awt::XPopupMenu > xPopupMenu( m_xPopupMenu ); aLock.unlock(); if ( xPopupMenu.is() ) { vos::OGuard aGuard( Application::GetSolarMutex() ); VCLXPopupMenu* pXPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( xPopupMenu ); PopupMenu* pVCLPopupMenu = (PopupMenu *)pXPopupMenu->GetMenu(); for ( USHORT i = 0; i < pVCLPopupMenu->GetItemCount(); i++ ) { USHORT nId = pVCLPopupMenu->GetItemId( i ); if ( nId == 0 ) continue; rtl::OUString aCmd = pVCLPopupMenu->GetItemCommand( nId ); if ( aCmd == aFeatureURL ) { // Enable/disable item pVCLPopupMenu->EnableItem( nId, Event.IsEnabled ); // Checkmark if ( Event.State >>= bCheckmark ) bSetCheckmark = sal_True; if ( bSetCheckmark ) pVCLPopupMenu->CheckItem( nId, bCheckmark ); else { rtl::OUString aItemText; if ( Event.State >>= aItemText ) pVCLPopupMenu->SetItemText( nId, aItemText ); } } } } } // XMenuListener void SAL_CALL ToolbarsMenuController::highlight( const css::awt::MenuEvent& ) throw (RuntimeException) { } void SAL_CALL ToolbarsMenuController::select( const css::awt::MenuEvent& rEvent ) throw (RuntimeException) { Reference< css::awt::XPopupMenu > xPopupMenu; Reference< XMultiServiceFactory > xServiceManager; Reference< XURLTransformer > xURLTransformer; Reference< XFrame > xFrame; Reference< XNameAccess > xPersistentWindowState; ResetableGuard aLock( m_aLock ); xPopupMenu = m_xPopupMenu; xServiceManager = m_xServiceManager; xURLTransformer = m_xURLTransformer; xFrame = m_xFrame; xPersistentWindowState = m_xPersistentWindowState; aLock.unlock(); if ( xPopupMenu.is() ) { VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXPopupMenu::GetImplementation( xPopupMenu ); if ( pPopupMenu ) { vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu(); rtl::OUString aCmd( pVCLPopupMenu->GetItemCommand( rEvent.MenuId )); if ( aCmd.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_INTERNAL_CMD_PART ))) == 0 ) { // Command to restore the visibility of all context sensitive toolbars Reference< XNameReplace > xNameReplace( xPersistentWindowState, UNO_QUERY ); if ( xPersistentWindowState.is() && xNameReplace.is() ) { try { Sequence< rtl::OUString > aElementNames = xPersistentWindowState->getElementNames(); sal_Int32 nCount = aElementNames.getLength(); bool bRefreshToolbars( false ); for ( sal_Int32 i = 0; i < nCount; i++ ) { try { rtl::OUString aElementName = aElementNames[i]; Sequence< PropertyValue > aWindowState; Any a( xPersistentWindowState->getByName( aElementName )); if ( a >>= aWindowState ) { sal_Bool bVisible( sal_False ); sal_Bool bContextSensitive( sal_False ); sal_Int32 nVisibleIndex( -1 ); for ( sal_Int32 j = 0; j < aWindowState.getLength(); j++ ) { if ( aWindowState[j].Name.equalsAscii( WINDOWSTATE_PROPERTY_VISIBLE )) { aWindowState[j].Value >>= bVisible; nVisibleIndex = j; } else if ( aWindowState[j].Name.equalsAscii( WINDOWSTATE_PROPERTY_CONTEXT )) aWindowState[j].Value >>= bContextSensitive; } if ( !bVisible && bContextSensitive && nVisibleIndex >= 0 ) { // Default is: Every context sensitive toolbar is visible aWindowState[nVisibleIndex].Value = makeAny( sal_True ); xNameReplace->replaceByName( aElementName, makeAny( aWindowState )); bRefreshToolbars = true; } } } catch ( NoSuchElementException& ) { } } if ( bRefreshToolbars ) { Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( xFrame )); if ( xLayoutManager.is() ) { Reference< XPropertySet > xPropSet( xLayoutManager, UNO_QUERY ); if ( xPropSet.is() ) { try { xPropSet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RefreshContextToolbarVisibility" )), makeAny( sal_True )); } catch ( RuntimeException& ) { } catch ( Exception& ) { } } } RefreshToolbars( xFrame ); } } catch ( RuntimeException& ) { throw; } catch ( Exception& ) { } } } else if ( aCmd.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_CMD_PART ))) < 0 ) { URL aTargetURL; Sequence aArgs; aTargetURL.Complete = aCmd; xURLTransformer->parseStrict( aTargetURL ); Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); if ( xDispatchProvider.is() ) { Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); ExecuteInfo* pExecuteInfo = new ExecuteInfo; pExecuteInfo->xDispatch = xDispatch; pExecuteInfo->aTargetURL = aTargetURL; pExecuteInfo->aArgs = aArgs; if(::comphelper::UiEventsLogger::isEnabled()) //#i88653# UiEventLogHelper(::rtl::OUString::createFromAscii("ToolbarsMenuController")).log(m_xServiceManager, m_xFrame, aTargetURL, aArgs); Application::PostUserEvent( STATIC_LINK(0, ToolbarsMenuController, ExecuteHdl_Impl), pExecuteInfo ); } } else { Reference< XLayoutManager > xLayoutManager( getLayoutManagerFromFrame( xFrame )); if ( xLayoutManager.is() ) { // Extract toolbar name from the combined uno-command. sal_Int32 nIndex = aCmd.indexOf( '=' ); if (( nIndex > 0 ) && (( nIndex+1 ) < aCmd.getLength() )) { rtl::OUStringBuffer aBuf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_PRIVATE_TB_RESOURCE ))); aBuf.append( aCmd.copy( nIndex+1 )); sal_Bool bShow( !pVCLPopupMenu->IsItemChecked( rEvent.MenuId )); rtl::OUString aToolBarResName( aBuf.makeStringAndClear() ); if ( bShow ) { xLayoutManager->createElement( aToolBarResName ); xLayoutManager->showElement( aToolBarResName ); } else { // closing means: // hide and destroy element xLayoutManager->hideElement( aToolBarResName ); xLayoutManager->destroyElement( aToolBarResName ); } } } } } } } void SAL_CALL ToolbarsMenuController::activate( const css::awt::MenuEvent& ) throw (RuntimeException) { std::vector< rtl::OUString > aCmdVector; Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); Reference< XURLTransformer > xURLTransformer( m_xURLTransformer ); { ResetableGuard aLock( m_aLock ); fillPopupMenu( m_xPopupMenu ); aCmdVector = m_aCommandVector; } // Update status for all commands inside our toolbars popup menu for ( sal_uInt32 i=0; i < aCmdVector.size(); i++ ) { bool bInternal = ( aCmdVector[i].indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATIC_INTERNAL_CMD_PART ))) == 0); if ( !bInternal ) { URL aTargetURL; aTargetURL.Complete = aCmdVector[i]; xURLTransformer->parseStrict( aTargetURL ); Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); if ( xDispatch.is() ) { xDispatch->addStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL ); xDispatch->removeStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL ); } } else if ( aCmdVector[i].equalsAscii( CMD_RESTOREVISIBILITY )) { // Special code to determine the enable/disable state of this command FeatureStateEvent aFeatureStateEvent; aFeatureStateEvent.FeatureURL.Complete = aCmdVector[i]; aFeatureStateEvent.IsEnabled = isContextSensitiveToolbarNonVisible(); statusChanged( aFeatureStateEvent ); } } } void SAL_CALL ToolbarsMenuController::deactivate( const css::awt::MenuEvent& ) throw (RuntimeException) { } // XPopupMenuController void SAL_CALL ToolbarsMenuController::setPopupMenu( const Reference< css::awt::XPopupMenu >& xPopupMenu ) throw ( RuntimeException ) { ResetableGuard aLock( m_aLock ); if ( m_bDisposed ) throw DisposedException(); if ( m_xFrame.is() && !m_xPopupMenu.is() ) { // Create popup menu on demand vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); m_xPopupMenu = xPopupMenu; m_xPopupMenu->addMenuListener( Reference< css::awt::XMenuListener >( (OWeakObject*)this, UNO_QUERY )); fillPopupMenu( m_xPopupMenu ); } } // XInitialization void SAL_CALL ToolbarsMenuController::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException ) { const rtl::OUString aFrameName( RTL_CONSTASCII_USTRINGPARAM( "Frame" )); const rtl::OUString aCommandURLName( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" )); ResetableGuard aLock( m_aLock ); sal_Bool bInitalized( m_bInitialized ); if ( !bInitalized ) { PropertyValue aPropValue; rtl::OUString aCommandURL; Reference< XFrame > xFrame; for ( int i = 0; i < aArguments.getLength(); i++ ) { if ( aArguments[i] >>= aPropValue ) { if ( aPropValue.Name.equalsAscii( "Frame" )) aPropValue.Value >>= xFrame; else if ( aPropValue.Name.equalsAscii( "CommandURL" )) aPropValue.Value >>= aCommandURL; } } if ( xFrame.is() && aCommandURL.getLength() ) { m_xFrame = xFrame; m_aCommandURL = aCommandURL; m_bInitialized = true; m_aBaseURL = determineBaseURL( aCommandURL ); Reference< XModuleManager > xModuleManager( m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY ); Reference< XNameAccess > xPersistentWindowStateSupplier( m_xServiceManager->createInstance( SERVICENAME_WINDOWSTATECONFIGURATION ), UNO_QUERY ); // Retrieve persistent window state reference for our module if ( xPersistentWindowStateSupplier.is() && xModuleManager.is() ) { rtl::OUString aModuleIdentifier; try { aModuleIdentifier = xModuleManager->identify( m_xFrame ); xPersistentWindowStateSupplier->getByName( aModuleIdentifier ) >>= m_xPersistentWindowState; Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier; if ( m_xServiceManager.is() ) xModuleCfgSupplier = Reference< XModuleUIConfigurationManagerSupplier >( m_xServiceManager->createInstance( SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ), UNO_QUERY ); m_xModuleCfgMgr = xModuleCfgSupplier->getUIConfigurationManager( aModuleIdentifier ); Reference< XController > xController = m_xFrame->getController(); Reference< XModel > xModel; if ( xController.is() ) xModel = xController->getModel(); if ( xModel.is() ) { Reference< XUIConfigurationManagerSupplier > xUIConfigurationManagerSupplier( xModel, UNO_QUERY ); if ( xUIConfigurationManagerSupplier.is() ) m_xDocCfgMgr = xUIConfigurationManagerSupplier->getUIConfigurationManager(); } m_aModuleIdentifier = aModuleIdentifier; } catch ( Exception& ) { } } m_xURLTransformer = Reference< XURLTransformer >( m_xServiceManager->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), UNO_QUERY ); } } } IMPL_STATIC_LINK_NOINSTANCE( ToolbarsMenuController, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo ) { try { // Asynchronous execution as this can lead to our own destruction! // Framework can recycle our current frame and the layout manager disposes all user interface // elements if a component gets detached from its frame! if ( pExecuteInfo->xDispatch.is() ) { pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs ); } } catch ( Exception& ) { } delete pExecuteInfo; return 0; } }