framework/inc/uielement/toolbarmanager.hxx | 10 + framework/inc/uielement/toolbarmerger.hxx | 2 framework/inc/uielement/toolbarwrapper.hxx | 16 - framework/source/uielement/toolbarmanager.cxx | 224 ++++++++++++++------------ framework/source/uielement/toolbarmerger.cxx | 8 framework/source/uielement/toolbarwrapper.cxx | 116 +++++++++---- include/sfx2/notebookbar/SfxNotebookBar.hxx | 2 sfx2/source/appl/workwin.cxx | 2 sfx2/source/notebookbar/SfxNotebookBar.cxx | 5 9 files changed, 233 insertions(+), 152 deletions(-)
New commits: commit 9bc1ffa2153d2474b023e0860d3c9c68ee18727b Author: Maxim Monastirsky <momonas...@gmail.com> AuthorDate: Mon Jun 6 22:50:14 2022 +0300 Commit: Maxim Monastirsky <momonas...@gmail.com> CommitDate: Mon Jun 13 18:47:01 2022 +0200 tdf#125040 Make single mode toolbar context aware This patch modifies the "Standard (Single Mode)" toolbar to have an optional context-aware section, given that a corresponding singlemode-<context-name>.xml files exist. This is a lot like the "Contextual Single" NB, except that it's implemented with regular toolbars, so docking/ customization/extensions/uno api etc. are all working. In addition, the "Single Toolbar" mode was modified to not show any other contextual toolbar. (But of course the single mode toolbar itself is perfectly usable outside of this mode.) Change-Id: Id746d9df59340a81962a8689b132941deea54b6c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135591 Tested-by: Jenkins Reviewed-by: Maxim Monastirsky <momonas...@gmail.com> diff --git a/framework/inc/uielement/toolbarmanager.hxx b/framework/inc/uielement/toolbarmanager.hxx index 1cfddd99ef45..746b40ebc787 100644 --- a/framework/inc/uielement/toolbarmanager.hxx +++ b/framework/inc/uielement/toolbarmanager.hxx @@ -94,6 +94,7 @@ public: virtual void ConnectCallbacks(ToolBarManager* pManager) = 0; virtual void SetMenuType(ToolBoxMenuType eType) = 0; virtual void MergeToolbar(ToolBoxItemId & rItemId, + sal_uInt16 nFirstItem, const OUString& rModuleIdentifier, CommandToInfoMap& rCommandMap, MergeToolbarInstruction& rInstruction) = 0; @@ -144,7 +145,9 @@ class ToolBarManager final : public ToolbarManager_Base void CheckAndUpdateImages(); void RequestImages(); - void FillToolbar( const css::uno::Reference< css::container::XIndexAccess >& rToolBarData ); + void FillToolbar( const css::uno::Reference< css::container::XIndexAccess >& rToolBarData, + const css::uno::Reference< css::container::XIndexAccess >& rContextData, + const OUString& rContextToolbarName ); void FillAddonToolbar( const css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > >& rAddonToolbar ); void FillOverflowToolbar( ToolBox const * pParent ); void notifyRegisteredControllers( const OUString& aUIElementName, const OUString& aCommand ); @@ -193,6 +196,9 @@ class ToolBarManager final : public ToolbarManager_Base private: void Init(); + void FillToolbarFromContainer(const css::uno::Reference< css::container::XIndexAccess >& rItemContainer, + const OUString& rResourceName, ToolBoxItemId& nId, ToolBoxItemId& nAddonId); + void ToggleButton(const OUString& rResourceName, std::u16string_view rCommand); void AddCustomizeMenuItems(ToolBox const * pToolBar); void InitImageManager(); void RemoveControllers(); @@ -219,12 +225,14 @@ class ToolBarManager final : public ToolbarManager_Base m_bUpdateControllers : 1; sal_Int16 m_eSymbolSize; + sal_uInt16 m_nContextMinPos; std::unique_ptr<ToolBarManagerImpl> m_pImpl; VclPtr<ToolBox> m_pToolBar; OUString m_aModuleIdentifier; OUString m_aResourceName; + OUString m_aContextResourceName; css::uno::Reference< css::util::XURLTransformer > m_xURLTransformer; css::uno::Reference< css::frame::XFrame > m_xFrame; diff --git a/framework/inc/uielement/toolbarmerger.hxx b/framework/inc/uielement/toolbarmerger.hxx index 837507baa386..b84ca2005e39 100644 --- a/framework/inc/uielement/toolbarmerger.hxx +++ b/framework/inc/uielement/toolbarmerger.hxx @@ -75,7 +75,7 @@ class ToolBarMerger OUString& rControlType, sal_uInt16& rWidth ); - static ReferenceToolbarPathInfo FindReferencePoint( const ToolBox* pToolbar, + static ReferenceToolbarPathInfo FindReferencePoint( const ToolBox* pToolbar, sal_uInt16 nFirstItem, std::u16string_view rReferencePoint ); static bool ProcessMergeOperation( ToolBox* pToolbar, diff --git a/framework/inc/uielement/toolbarwrapper.hxx b/framework/inc/uielement/toolbarwrapper.hxx index da90455b21da..a1bfbd0b09c9 100644 --- a/framework/inc/uielement/toolbarwrapper.hxx +++ b/framework/inc/uielement/toolbarwrapper.hxx @@ -23,6 +23,7 @@ #include <com/sun/star/lang/XComponent.hpp> #include <com/sun/star/ui/XUIFunctionListener.hpp> +#include <com/sun/star/ui/XContextChangeEventListener.hpp> #include <com/sun/star/uno/XComponentContext.hpp> #include <memory> @@ -37,19 +38,14 @@ namespace weld namespace framework { -class ToolBarManager; -class ToolBarWrapper final : public css::ui::XUIFunctionListener, - public UIConfigElementWrapperBase +class ToolBarWrapper final : public cppu::ImplInheritanceHelper<UIConfigElementWrapperBase, + css::ui::XUIFunctionListener, + css::ui::XContextChangeEventListener> { public: ToolBarWrapper( const css::uno::Reference< css::uno::XComponentContext >& xContext ); virtual ~ToolBarWrapper() override; - // XInterface - virtual void SAL_CALL acquire() noexcept override; - virtual void SAL_CALL release() noexcept override; - virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type & rType ) override; - // XComponent virtual void SAL_CALL dispose() override; @@ -68,6 +64,9 @@ class ToolBarWrapper final : public css::ui::XUIFunctionListener, // XUIFunctionListener virtual void SAL_CALL functionExecute( const OUString& aUIElementName, const OUString& aCommand ) override; + // XContextChangeEventListener + virtual void SAL_CALL notifyContextChangeEvent( const css::ui::ContextChangeEventObject& aEvent ) override; + // XEventListener using cppu::OPropertySetHelper::disposing; virtual void SAL_CALL disposing( const css::lang::EventObject& aEvent ) override; @@ -78,6 +77,7 @@ class ToolBarWrapper final : public css::ui::XUIFunctionListener, css::uno::Reference< css::lang::XComponent > m_xToolBarManager; css::uno::Reference< css::uno::XComponentContext > m_xContext; + css::uno::Reference< css::ui::XUIElement > m_xSubElement; std::unique_ptr<weld::Builder> m_xBuilder; std::unique_ptr<weld::Container> m_xTopLevel; diff --git a/framework/source/uielement/toolbarmanager.cxx b/framework/source/uielement/toolbarmanager.cxx index 4d56884ffbb2..e9de797e689a 100644 --- a/framework/source/uielement/toolbarmanager.cxx +++ b/framework/source/uielement/toolbarmanager.cxx @@ -333,12 +333,12 @@ public: m_pToolBar->SetMenuType( eType ); } - virtual void MergeToolbar(ToolBoxItemId & rItemId, + virtual void MergeToolbar(ToolBoxItemId & rItemId, sal_uInt16 nFirstItem, const OUString& rModuleIdentifier, CommandToInfoMap& rCommandMap, MergeToolbarInstruction& rInstruction) override { - ReferenceToolbarPathInfo aRefPoint = ToolBarMerger::FindReferencePoint( m_pToolBar, rInstruction.aMergePoint ); + ReferenceToolbarPathInfo aRefPoint = ToolBarMerger::FindReferencePoint( m_pToolBar, nFirstItem, rInstruction.aMergePoint ); // convert the sequence< sequence< propertyvalue > > structure to // something we can better handle. A vector with item data @@ -522,6 +522,7 @@ public: virtual void SetMenuType(ToolBoxMenuType /*eType*/) override {} virtual void MergeToolbar(ToolBoxItemId & /*rItemId*/, + sal_uInt16 /*nFirstItem*/, const OUString& /*rModuleIdentifier*/, CommandToInfoMap& /*rCommandMap*/, MergeToolbarInstruction& /*rInstruction*/) override {} @@ -572,6 +573,7 @@ ToolBarManager::ToolBarManager( const Reference< XComponentContext >& rxContext, m_bFrameActionRegistered( false ), m_bUpdateControllers( false ), m_eSymbolSize(SvtMiscOptions().GetCurrentSymbolsSize()), + m_nContextMinPos(0), m_pImpl( new VclToolBarManager( pToolBar ) ), m_pToolBar( pToolBar ), m_aResourceName(std::move( aResourceName )), @@ -592,6 +594,7 @@ ToolBarManager::ToolBarManager( const Reference< XComponentContext >& rxContext, m_bFrameActionRegistered( false ), m_bUpdateControllers( false ), m_eSymbolSize( SvtMiscOptions().GetCurrentSymbolsSize() ), + m_nContextMinPos(0), m_pImpl( new WeldToolBarManager( pToolBar, pBuilder ) ), m_pToolBar( nullptr ), m_aResourceName(std::move( aResourceName )), @@ -1332,7 +1335,9 @@ void ToolBarManager::InitImageManager() } } -void ToolBarManager::FillToolbar( const Reference< XIndexAccess >& rItemContainer ) +void ToolBarManager::FillToolbar( const Reference< XIndexAccess >& rItemContainer, + const Reference< XIndexAccess >& rContextData, + const OUString& rContextToolbarName ) { OString aTbxName = OUStringToOString( m_aResourceName, RTL_TEXTENCODING_ASCII_US ); SAL_INFO( "fwk.uielement", "framework (cd100003) ::ToolBarManager::FillToolbar " << aTbxName ); @@ -1351,7 +1356,54 @@ void ToolBarManager::FillToolbar( const Reference< XIndexAccess >& rItemContaine m_aControllerMap.clear(); m_aCommandMap.clear(); - ToolBoxItemId nId( 1 ); + ToolBoxItemId nId(1), nAddonId(1000); + FillToolbarFromContainer( rItemContainer, m_aResourceName, nId, nAddonId ); + m_aContextResourceName = rContextToolbarName; + if ( rContextData.is() ) + { + m_pImpl->InsertSeparator(); + FillToolbarFromContainer( rContextData, m_aContextResourceName, nId, nAddonId ); + } + + // 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_pImpl->WillUsePopupMode() ) + UpdateControllers(); + else if ( m_pImpl->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() ) + return; + + try + { + OUString aUIName; + xPropSet->getPropertyValue("UIName") >>= aUIName; + if ( !aUIName.isEmpty() ) + m_pImpl->SetName( aUIName ); + } + catch (const Exception&) + { + } +} + +void ToolBarManager::FillToolbarFromContainer( const Reference< XIndexAccess >& rItemContainer, + const OUString& rResourceName, ToolBoxItemId& nId, ToolBoxItemId& nAddonId ) +{ + m_nContextMinPos = m_pImpl->GetItemCount(); CommandInfo aCmdInfo; for ( sal_Int32 n = 0; n < rItemContainer->getCount(); n++ ) { @@ -1447,12 +1499,10 @@ void ToolBarManager::FillToolbar( const Reference< XIndexAccess >& rItemContaine // Support add-on toolbar merging here. Working directly on the toolbar object is much // simpler and faster. - constexpr sal_uInt16 TOOLBAR_ITEM_STARTID = 1000; - MergeToolbarInstructionContainer aMergeInstructionContainer; // Retrieve the toolbar name from the resource name - OUString aToolbarName( m_aResourceName ); + OUString aToolbarName( rResourceName ); sal_Int32 nIndex = aToolbarName.lastIndexOf( '/' ); if (( nIndex > 0 ) && ( nIndex < aToolbarName.getLength() )) aToolbarName = aToolbarName.copy( nIndex+1 ); @@ -1461,51 +1511,16 @@ void ToolBarManager::FillToolbar( const Reference< XIndexAccess >& rItemContaine if ( !aMergeInstructionContainer.empty() ) { - ToolBoxItemId 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 )) { - m_pImpl->MergeToolbar(nItemId, m_aModuleIdentifier, m_aCommandMap, rInstruction); + m_pImpl->MergeToolbar(nAddonId, m_nContextMinPos, m_aModuleIdentifier, m_aCommandMap, rInstruction); } } } - - // 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_pImpl->WillUsePopupMode() ) - UpdateControllers(); - else if ( m_pImpl->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() ) - return; - - try - { - OUString aUIName; - xPropSet->getPropertyValue("UIName") >>= aUIName; - if ( !aUIName.isEmpty() ) - m_pImpl->SetName( aUIName ); - } - catch (const Exception&) - { - } } void ToolBarManager::FillAddonToolbar( const Sequence< Sequence< PropertyValue > >& rAddonToolbar ) @@ -1991,6 +2006,66 @@ void ToolBarManager::AddCustomizeMenuItems(ToolBox const * pToolBar) pMenu->RemoveDisabledEntries(); } +void ToolBarManager::ToggleButton( const OUString& rResourceName, std::u16string_view rCommand ) +{ + Reference< XLayoutManager > xLayoutManager = getLayoutManagerFromFrame( m_xFrame ); + if ( !xLayoutManager.is() ) + return; + + Reference< XUIElementSettings > xUIElementSettings( xLayoutManager->getElement( rResourceName ), UNO_QUERY ); + if ( !xUIElementSettings.is() ) + return; + + Reference< XIndexContainer > xItemContainer( xUIElementSettings->getSettings( true ), UNO_QUERY ); + sal_Int32 nCount = xItemContainer->getCount(); + for ( sal_Int32 i = 0; i < nCount; i++ ) + { + Sequence< PropertyValue > aProp; + sal_Int32 nVisibleIndex( -1 ); + OUString aCommandURL; + bool bVisible( false ); + + if ( xItemContainer->getByIndex( i ) >>= aProp ) + { + for ( sal_Int32 j = 0; j < aProp.getLength(); j++ ) + { + if ( aProp[j].Name == ITEM_DESCRIPTOR_COMMANDURL ) + { + aProp[j].Value >>= aCommandURL; + } + else if ( aProp[j].Name == ITEM_DESCRIPTOR_VISIBLE ) + { + aProp[j].Value >>= bVisible; + nVisibleIndex = j; + } + } + + if (( aCommandURL == rCommand ) && ( nVisibleIndex >= 0 )) + { + // We have found the requested item, toggle the visible flag + // and write back the configuration settings to the toolbar + aProp.getArray()[nVisibleIndex].Value <<= !bVisible; + try + { + xItemContainer->replaceByIndex( i, Any( aProp )); + xUIElementSettings->setSettings( xItemContainer ); + Reference< XPropertySet > xPropSet( xUIElementSettings, UNO_QUERY ); + if ( xPropSet.is() ) + { + Reference< XUIConfigurationPersistence > xUICfgMgr; + if (( xPropSet->getPropertyValue("ConfigurationSource") >>= xUICfgMgr ) && ( xUICfgMgr.is() )) + xUICfgMgr->store(); + } + } + catch (const Exception&) + { + } + break; + } + } + } +} + IMPL_LINK( ToolBarManager, MenuButton, ToolBox*, pToolBar, void ) { SolarMutexGuard g; @@ -2158,64 +2233,11 @@ IMPL_LINK( ToolBarManager, MenuSelect, Menu*, pMenu, bool ) { // toggle toolbar button visibility 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( true ), UNO_QUERY ); - sal_Int32 nCount = xItemContainer->getCount(); - for ( sal_Int32 i = 0; i < nCount; i++ ) - { - Sequence< PropertyValue > aProp; - sal_Int32 nVisibleIndex( -1 ); - OUString aCommandURL; - bool bVisible( false ); - - if ( xItemContainer->getByIndex( i ) >>= aProp ) - { - for ( sal_Int32 j = 0; j < aProp.getLength(); j++ ) - { - if ( aProp[j].Name == ITEM_DESCRIPTOR_COMMANDURL ) - { - aProp[j].Value >>= aCommandURL; - } - else if ( aProp[j].Name == 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.getArray()[nVisibleIndex].Value <<= !bVisible; - try - { - xItemContainer->replaceByIndex( i, Any( aProp )); - xUIElementSettings->setSettings( xItemContainer ); - Reference< XPropertySet > xPropSet( xUIElementSettings, UNO_QUERY ); - if ( xPropSet.is() ) - { - Reference< XUIConfigurationPersistence > xUICfgMgr; - if (( xPropSet->getPropertyValue("ConfigurationSource") >>= xUICfgMgr ) && ( xUICfgMgr.is() )) - xUICfgMgr->store(); - } - } - catch (const Exception&) - { - } - - break; - } - } - } - } - } + if (m_aContextResourceName.isEmpty() || + nId - STARTID_CUSTOMIZE_POPUPMENU < m_nContextMinPos) + ToggleButton(m_aResourceName, aCommand); + else + ToggleButton(m_aContextResourceName, aCommand); } break; } diff --git a/framework/source/uielement/toolbarmerger.cxx b/framework/source/uielement/toolbarmerger.cxx index 2657873c3b22..db9416af66bc 100644 --- a/framework/source/uielement/toolbarmerger.cxx +++ b/framework/source/uielement/toolbarmerger.cxx @@ -216,6 +216,10 @@ void ToolBarMerger::ConvertSequenceToValues( Must be a valid pointer to a toolbar with items which should be searched. +@param + nFirstItem + + First toolbar item to search from. @param rReferencePoint @@ -228,7 +232,7 @@ void ToolBarMerger::ConvertSequenceToValues( position of the reference point and the toolbar used. */ ReferenceToolbarPathInfo ToolBarMerger::FindReferencePoint( - const ToolBox* pToolbar, + const ToolBox* pToolbar, sal_uInt16 nFirstItem, std::u16string_view rReferencePoint ) { ReferenceToolbarPathInfo aResult; @@ -237,7 +241,7 @@ ReferenceToolbarPathInfo ToolBarMerger::FindReferencePoint( const ToolBox::ImplToolItems::size_type nSize( pToolbar->GetItemCount() ); - for ( ToolBox::ImplToolItems::size_type i = 0; i < nSize; i++ ) + for ( ToolBox::ImplToolItems::size_type i = nFirstItem; i < nSize; i++ ) { const ToolBoxItemId nItemId = pToolbar->GetItemId( i ); if ( nItemId > ToolBoxItemId(0) ) diff --git a/framework/source/uielement/toolbarwrapper.cxx b/framework/source/uielement/toolbarwrapper.cxx index 9bf9a4bd714a..146cddf2867d 100644 --- a/framework/source/uielement/toolbarwrapper.cxx +++ b/framework/source/uielement/toolbarwrapper.cxx @@ -20,11 +20,11 @@ #include <uielement/toolbarwrapper.hxx> #include <uielement/toolbarmanager.hxx> +#include <com/sun/star/ui/ContextChangeEventMultiplexer.hpp> #include <com/sun/star/ui/UIElementType.hpp> #include <com/sun/star/lang/DisposedException.hpp> #include <toolkit/helper/vclunohelper.hxx> -#include <cppuhelper/queryinterface.hxx> #include <vcl/svapp.hxx> #include <vcl/toolbox.hxx> @@ -43,7 +43,7 @@ namespace framework { ToolBarWrapper::ToolBarWrapper( const Reference< XComponentContext >& rxContext ) : - UIConfigElementWrapperBase( UIElementType::TOOLBAR ), + ImplInheritanceHelper( UIElementType::TOOLBAR ), m_xContext( rxContext ) { } @@ -55,29 +55,6 @@ ToolBarWrapper::~ToolBarWrapper() m_xBuilder.reset(nullptr); } -// XInterface -void SAL_CALL ToolBarWrapper::acquire() noexcept -{ - UIConfigElementWrapperBase::acquire(); -} - -void SAL_CALL ToolBarWrapper::release() noexcept -{ - UIConfigElementWrapperBase::release(); -} - -uno::Any SAL_CALL ToolBarWrapper::queryInterface( const uno::Type & rType ) -{ - Any a = ::cppu::queryInterface( - rType , - static_cast< css::ui::XUIFunctionListener* >(this) ); - - if( a.hasValue() ) - return a; - - return UIConfigElementWrapperBase::queryInterface( rType ); -} - // XComponent void SAL_CALL ToolBarWrapper::dispose() { @@ -94,6 +71,14 @@ void SAL_CALL ToolBarWrapper::dispose() SolarMutexGuard g; + auto xMultiplexer( ContextChangeEventMultiplexer::get( m_xContext ) ); + xMultiplexer->removeAllContextChangeEventListeners( this ); + + Reference< XComponent > xComponent( m_xSubElement, UNO_QUERY ); + if ( xComponent.is() ) + xComponent->removeEventListener( Reference< XUIConfigurationListener >( this )); + m_xSubElement.clear(); + if ( m_xToolBarManager.is() ) m_xToolBarManager->dispose(); m_xToolBarManager.clear(); @@ -134,9 +119,23 @@ void SAL_CALL ToolBarWrapper::initialize( const Sequence< Any >& aArguments ) if ( !(xFrame.is() && m_xConfigSource.is()) ) return; + OUString aContextPart; + if ( m_aResourceURL.startsWith( "private:resource/toolbar/singlemode", &aContextPart ) && aContextPart.isEmpty() ) + { + auto xMultiplexer( ContextChangeEventMultiplexer::get( m_xContext ) ); + try + { + xMultiplexer->addContextChangeEventListener( this, xFrame->getController() ); + } + catch( const Exception& ) + { + } + } + // Create VCL based toolbar which will be filled with settings data VclPtr<ToolBox> pToolBar; rtl::Reference<ToolBarManager> pToolBarManager; + if ( aContextPart.isEmpty() ) { SolarMutexGuard aSolarMutexGuard; if ( !xParentWindow.is() ) @@ -171,7 +170,7 @@ void SAL_CALL ToolBarWrapper::initialize( const Sequence< Any >& aArguments ) if ( m_xConfigData.is() && (pToolBar || m_xWeldedToolbar) && pToolBarManager ) { // Fill toolbar with container contents - pToolBarManager->FillToolbar( m_xConfigData ); + impl_fillNewData(); if (pToolBar) { pToolBar->EnableCustomize(); @@ -199,9 +198,10 @@ void SAL_CALL ToolBarWrapper::initialize( const Sequence< Any >& aArguments ) } // XEventListener -void SAL_CALL ToolBarWrapper::disposing( const css::lang::EventObject& ) +void SAL_CALL ToolBarWrapper::disposing( const css::lang::EventObject& aEvent ) { - // nothing todo + if ( aEvent.Source == m_xSubElement ) + m_xSubElement.clear(); } // XUpdatable @@ -225,22 +225,21 @@ void SAL_CALL ToolBarWrapper::updateSettings() if ( m_bDisposed ) throw DisposedException(); - if ( !m_xToolBarManager.is() ) - return; - if ( m_xConfigSource.is() && m_bPersistent ) { try { - ToolBarManager* pToolBarManager = static_cast< ToolBarManager *>( m_xToolBarManager.get() ); - m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, false ); if ( m_xConfigData.is() ) - pToolBarManager->FillToolbar( m_xConfigData ); + impl_fillNewData(); } catch ( const NoSuchElementException& ) { } + + auto pContainer( m_aListenerContainer.getContainer( cppu::UnoType< XEventListener >::get() ) ); + if ( pContainer ) + pContainer->forEach< XUIElementSettings >([]( const Reference<XUIElementSettings>& xListener ){ xListener->updateSettings(); }); } else if ( !m_bPersistent ) { @@ -250,10 +249,55 @@ void SAL_CALL ToolBarWrapper::updateSettings() void ToolBarWrapper::impl_fillNewData() { - // Transient toolbar => Fill toolbar with new data ToolBarManager* pToolBarManager = static_cast< ToolBarManager *>( m_xToolBarManager.get() ); if ( pToolBarManager ) - pToolBarManager->FillToolbar( m_xConfigData ); + { + Reference< XUIElementSettings > xUIElementSettings( m_xSubElement, UNO_QUERY ); + Reference< XIndexAccess > xContextData = xUIElementSettings.is() ? xUIElementSettings->getSettings( false ) : nullptr; + OUString aContextToolbar = xContextData.is() ? m_xSubElement->getResourceURL() : OUString(); + pToolBarManager->FillToolbar( m_xConfigData, xContextData, aContextToolbar ); + } +} + +//XContextChangeEventListener +void SAL_CALL ToolBarWrapper::notifyContextChangeEvent( const ContextChangeEventObject& aEvent ) +{ + SolarMutexGuard g; + + if ( m_bDisposed ) + throw DisposedException(); + + if ( aEvent.ContextName.isEmpty() ) + return; + + const OUString aContextToolbar( m_aResourceURL + "-" + aEvent.ContextName.toAsciiLowerCase() ); + if ( m_xSubElement.is() && m_xSubElement->getResourceURL() == aContextToolbar ) + return; + + Reference< XComponent > xComponent( m_xSubElement, UNO_QUERY ); + if ( xComponent.is() ) + xComponent->removeEventListener( Reference< XUIConfigurationListener >( this )); + m_xSubElement.clear(); + + Reference< XLayoutManager > xLayoutManager; + Reference< XPropertySet > xPropSet( m_xWeakFrame.get(), UNO_QUERY ); + if ( xPropSet.is() ) + xPropSet->getPropertyValue("LayoutManager") >>= xLayoutManager; + if ( !xLayoutManager.is() ) + return; + + xLayoutManager->createElement( aContextToolbar ); + m_xSubElement.set( xLayoutManager->getElement( aContextToolbar ) ); + xComponent.set( m_xSubElement, UNO_QUERY ); + if ( xComponent.is() ) + xComponent->addEventListener( Reference< XUIConfigurationListener >( this )); + + if ( m_xConfigData.is() ) + { + xLayoutManager->lock(); + impl_fillNewData(); + xLayoutManager->unlock(); + } } // XUIElement interface diff --git a/include/sfx2/notebookbar/SfxNotebookBar.hxx b/include/sfx2/notebookbar/SfxNotebookBar.hxx index 66286b87cdb9..96f5805f50e0 100644 --- a/include/sfx2/notebookbar/SfxNotebookBar.hxx +++ b/include/sfx2/notebookbar/SfxNotebookBar.hxx @@ -44,7 +44,7 @@ public: static void CloseMethod(SfxBindings& rBindings); static void CloseMethod(SystemWindow* pSysWindow); - static bool IsActive(); + static bool IsActive(bool bConsiderSingleToolbar = false); /// Function to be called from the sdi's ExecMethod. static void ExecMethod(SfxBindings& rBindings, const OUString& rUIName); diff --git a/sfx2/source/appl/workwin.cxx b/sfx2/source/appl/workwin.cxx index 4874db7ee5f6..fb3955ee2c5c 100644 --- a/sfx2/source/appl/workwin.cxx +++ b/sfx2/source/appl/workwin.cxx @@ -1195,7 +1195,7 @@ void SfxWorkWindow::UpdateObjectBars_Impl2() // Iterate over all Toolboxes xLayoutManager->lock(); - const bool isNotebookBarActive = sfx2::SfxNotebookBar::IsActive(); + const bool isNotebookBarActive = sfx2::SfxNotebookBar::IsActive(true); for ( auto const & n: aObjBarList ) { ToolbarId eId = n.eId; diff --git a/sfx2/source/notebookbar/SfxNotebookBar.cxx b/sfx2/source/notebookbar/SfxNotebookBar.cxx index 451c94cf3966..ec1f5bf33c0d 100644 --- a/sfx2/source/notebookbar/SfxNotebookBar.cxx +++ b/sfx2/source/notebookbar/SfxNotebookBar.cxx @@ -221,7 +221,7 @@ void SfxNotebookBar::UnlockNotebookBar() m_bLock = false; } -bool SfxNotebookBar::IsActive() +bool SfxNotebookBar::IsActive(bool bConsiderSingleToolbar) { if (m_bHide) return false; @@ -265,6 +265,9 @@ bool SfxNotebookBar::IsActive() OUString aActive = comphelper::getString( aAppNode.getNodeValue( "Active" ) ); + if (bConsiderSingleToolbar && aActive == "Single") + return true; + if (comphelper::LibreOfficeKit::isActive() && aActive == "notebookbar_online.ui") return true;