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;
 

Reply via email to