[Libreoffice-commits] core.git: framework/inc framework/source framework/uiconfig framework/UIConfig_startmodule.mk include/framework include/sfx2 include/vcl sfx2/source svtools/source vcl/inc vcl/source vcl/unx

Szymon KÅ‚os (via logerrit) logerrit at kemper.freedesktop.org
Tue Apr 6 09:59:03 UTC 2021


 framework/UIConfig_startmodule.mk                   |    1 
 framework/inc/uielement/toolbarmanager.hxx          |   76 ++
 framework/inc/uielement/toolbarwrapper.hxx          |   11 
 framework/source/fwe/classes/sfxhelperfunctions.cxx |   23 
 framework/source/uielement/subtoolbarcontroller.cxx |   14 
 framework/source/uielement/toolbarmanager.cxx       |  713 +++++++++++++++-----
 framework/source/uielement/toolbarwrapper.cxx       |   30 
 framework/uiconfig/startmodule/ui/managedtoolbar.ui |   21 
 include/framework/sfxhelperfunctions.hxx            |   19 
 include/sfx2/tbxctrl.hxx                            |    1 
 include/vcl/weld.hxx                                |    1 
 sfx2/source/appl/app.cxx                            |   12 
 sfx2/source/toolbox/tbxitem.cxx                     |    1 
 svtools/source/control/toolbarmenu.cxx              |    2 
 vcl/inc/salvtables.hxx                              |    2 
 vcl/source/app/salvtables.cxx                       |    9 
 vcl/unx/gtk3/gtk3gtkinst.cxx                        |   14 
 17 files changed, 780 insertions(+), 170 deletions(-)

New commits:
commit ac1aefd5174258d9bcb41465ce566ed1a0819f3d
Author:     Szymon Kłos <szymon.klos at collabora.com>
AuthorDate: Wed Mar 10 16:20:07 2021 +0100
Commit:     Szymon Kłos <szymon.klos at collabora.com>
CommitDate: Tue Apr 6 11:58:20 2021 +0200

    Extend ToolBarManager to build weld::Toolbar
    
    - used for SubToolBarController eg. framework shape toolbar popup
    present in the sidebar fontwork panel
    - add separate implementation for vcl and weld based ToolBarManager
    - provide basic functionality for weld based (just inserting standard items with icons
    and controllers)
    - not implemented: addons items merging etc.
    
    Change-Id: I8e460f34abd512d70e95a1d484d728b7d809ce9d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113387
    Tested-by: Jenkins
    Reviewed-by: Szymon Kłos <szymon.klos at collabora.com>

diff --git a/framework/UIConfig_startmodule.mk b/framework/UIConfig_startmodule.mk
index 14cf6283493f..8ead37282e8e 100644
--- a/framework/UIConfig_startmodule.mk
+++ b/framework/UIConfig_startmodule.mk
@@ -14,6 +14,7 @@ $(eval $(call gb_UIConfig_add_menubarfiles,modules/StartModule,\
 ))
 
 $(eval $(call gb_UIConfig_add_uifiles,modules/StartModule,\
+	framework/uiconfig/startmodule/ui/managedtoolbar \
 	framework/uiconfig/startmodule/ui/subtoolbar \
 ))
 
diff --git a/framework/inc/uielement/toolbarmanager.hxx b/framework/inc/uielement/toolbarmanager.hxx
index e9578bda6aad..8a87c2a6b78a 100644
--- a/framework/inc/uielement/toolbarmanager.hxx
+++ b/framework/inc/uielement/toolbarmanager.hxx
@@ -33,11 +33,14 @@
 #include <com/sun/star/uno/XComponentContext.hpp>
 #include <com/sun/star/util/XURLTransformer.hpp>
 
+#include <framework/addonsoptions.hxx>
+
 #include <rtl/ustring.hxx>
 #include <cppuhelper/implbase.hxx>
 #include <cppuhelper/interfacecontainer.hxx>
 
 #include <tools/link.hxx>
+#include <vcl/weld.hxx>
 #include <vcl/window.hxx>
 #include <vcl/timer.hxx>
 #include <vcl/toolbox.hxx>
@@ -51,6 +54,55 @@ class Menu;
 namespace framework
 {
 
+class ToolBarManager;
+
+class ToolBarManagerImpl
+{
+public:
+    virtual ~ToolBarManagerImpl() = default;
+    virtual void Init() = 0;
+    virtual void Destroy() = 0;
+    virtual css::uno::Reference<css::awt::XWindow> GetInterface() = 0;
+    virtual css::uno::Reference<css::frame::XStatusListener> CreateToolBoxController(
+                            const css::uno::Reference<css::frame::XFrame>& rFrame,
+                            ToolBoxItemId nId,
+                            const OUString& aCommandURL ) = 0;
+    virtual void InsertItem(ToolBoxItemId nId,
+                            const OUString& rString,
+                            const OUString& rCommandURL,
+                            const OUString& rTooltip,
+                            const OUString& rLabel,
+                            ToolBoxItemBits nItemBits) = 0;
+    virtual void InsertSeparator() = 0;
+    virtual void InsertSpace() = 0;
+    virtual void InsertBreak() = 0;
+    virtual ToolBoxItemId GetItemId(sal_uInt16 nPos) = 0;
+    virtual ToolBoxItemId GetCurItemId() = 0;
+    virtual OUString GetItemCommand(ToolBoxItemId nId) = 0;
+    virtual sal_uInt16 GetItemCount() = 0;
+    virtual void SetItemCheckable(ToolBoxItemId nId) = 0;
+    virtual void HideItem(ToolBoxItemId nId, const OUString& rCommandURL) = 0;
+    virtual bool IsItemVisible(ToolBoxItemId nId, const OUString& rCommandURL) = 0;
+    virtual void Clear() = 0;
+    virtual void SetName(const OUString& rName) = 0;
+    virtual void SetHelpId(const OString& rHelpId) = 0;
+    virtual bool WillUsePopupMode() = 0;
+    virtual bool IsReallyVisible() = 0;
+    virtual void SetIconSize(ToolBoxButtonSize eSize) = 0;
+    virtual vcl::ImageType GetImageSize() = 0;
+    virtual void ConnectCallbacks(ToolBarManager* pManager) = 0;
+    virtual void SetMenuType(ToolBoxMenuType eType) = 0;
+    virtual void MergeToolbar(ToolBoxItemId nItemId,
+                              const OUString& rModuleIdentifier,
+                              CommandToInfoMap& rCommandMap,
+                              MergeToolbarInstruction& rInstruction) = 0;
+    virtual void SetItemImage(ToolBoxItemId nId,
+                              const OUString& rCommandURL,
+                              const Image& rImage) = 0;
+    virtual void UpdateSize() = 0;
+    virtual void SetItemWindow(ToolBoxItemId nItemId, vcl::Window* pNewWindow) = 0;
+};
+
 typedef ::cppu::WeakImplHelper<
            css::frame::XFrameActionListener,
            css::lang::XComponent,
@@ -64,6 +116,11 @@ class ToolBarManager final : public ToolbarManager_Base
                         const css::uno::Reference< css::frame::XFrame >& rFrame,
                         const OUString& rResourceName,
                         ToolBox* pToolBar );
+        ToolBarManager( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
+                        const css::uno::Reference< css::frame::XFrame >& rFrame,
+                        const OUString& rResourceName,
+                        weld::Toolbar* pToolBar,
+                        weld::Builder* pBuilder );
         virtual ~ToolBarManager() override;
 
         ToolBox* GetToolBar() const;
@@ -100,6 +157,13 @@ class ToolBarManager final : public ToolbarManager_Base
             EXEC_CMD_DOCKALLTOOLBARS
         };
 
+        enum ClickAction
+        {
+            Click,
+            DblClick,
+            Execute
+        };
+
         struct ExecuteInfo
         {
             OUString                                            aToolbarResName;
@@ -108,8 +172,10 @@ class ToolBarManager final : public ToolbarManager_Base
             css::uno::Reference< css::awt::XWindow >            xWindow;
         };
 
-    private:
-        DECL_LINK(Click, ToolBox *, void);
+    public:
+        void OnClick(bool bUseExecute = false);
+        void OnDropdownClick(bool bCreatePopupWindow = true);
+
         DECL_LINK(DropdownClick, ToolBox *, void);
         DECL_LINK(DoubleClick, ToolBox *, void);
         DECL_LINK(Select, ToolBox *, void);
@@ -124,6 +190,8 @@ class ToolBarManager final : public ToolbarManager_Base
         DECL_LINK( OverflowEventListener, VclWindowEvent&, void );
         DECL_STATIC_LINK( ToolBarManager, ExecuteHdl_Impl, void*, void );
 
+    private:
+        void Init();
         void AddCustomizeMenuItems(ToolBox const * pToolBar);
         void InitImageManager();
         void RemoveControllers();
@@ -137,7 +205,7 @@ class ToolBarManager final : public ToolbarManager_Base
         ToolBoxItemBits ConvertStyleToToolboxItemBits( sal_Int32 nStyle );
         css::uno::Reference< css::frame::XModel > GetModelFromFrame() const;
         bool IsPluginMode() const;
-        void HandleClick(void ( SAL_CALL css::frame::XToolbarController::*_pClick )(  ));
+        void HandleClick(ClickAction eAction);
         void setToolBarImage(const Image& _aImage,const CommandToInfoMap::const_iterator& _pIter);
         void impl_elementChanged(bool _bRemove,const css::ui::ConfigurationEvent& Event );
 
@@ -146,12 +214,12 @@ class ToolBarManager final : public ToolbarManager_Base
         typedef std::unordered_map<OUString, SubToolBarControllerVector>                                                SubToolBarToSubToolBarControllerMap;
 
         bool m_bDisposed : 1,
-             m_bAddedToTaskPaneList : 1,
              m_bFrameActionRegistered : 1,
              m_bUpdateControllers : 1;
 
         sal_Int16 m_eSymbolSize;
 
+        std::unique_ptr<ToolBarManagerImpl>                          m_pImpl;
         VclPtr<ToolBox>                                              m_pToolBar;
 
         OUString                                                     m_aModuleIdentifier;
diff --git a/framework/inc/uielement/toolbarwrapper.hxx b/framework/inc/uielement/toolbarwrapper.hxx
index c2c93728cb5f..904dfa6c7019 100644
--- a/framework/inc/uielement/toolbarwrapper.hxx
+++ b/framework/inc/uielement/toolbarwrapper.hxx
@@ -25,6 +25,13 @@
 #include <com/sun/star/ui/XUIFunctionListener.hpp>
 #include <com/sun/star/uno/XComponentContext.hpp>
 
+namespace weld
+{
+    class Builder;
+    class Container;
+    class Toolbar;
+}
+
 namespace framework
 {
 
@@ -69,6 +76,10 @@ class ToolBarWrapper final : public css::ui::XUIFunctionListener,
 
         css::uno::Reference< css::lang::XComponent >            m_xToolBarManager;
         css::uno::Reference< css::uno::XComponentContext >      m_xContext;
+
+        std::unique_ptr<weld::Builder>                          m_xBuilder;
+        std::unique_ptr<weld::Container>                        m_xTopLevel;
+        std::unique_ptr<weld::Toolbar>                          m_xWeldedToolbar;
 };
 
 }
diff --git a/framework/source/fwe/classes/sfxhelperfunctions.cxx b/framework/source/fwe/classes/sfxhelperfunctions.cxx
index 9adc5931a7e3..06f48f1fe695 100644
--- a/framework/source/fwe/classes/sfxhelperfunctions.cxx
+++ b/framework/source/fwe/classes/sfxhelperfunctions.cxx
@@ -24,6 +24,7 @@
 #include <svtools/statusbarcontroller.hxx>
 
 static pfunc_setToolBoxControllerCreator   pToolBoxControllerCreator   = nullptr;
+static pfunc_setWeldToolBoxControllerCreator pWeldToolBoxControllerCreator = nullptr;
 static pfunc_setStatusBarControllerCreator pStatusBarControllerCreator = nullptr;
 static pfunc_getRefreshToolbars            pRefreshToolbars            = nullptr;
 static pfunc_createDockingWindow           pCreateDockingWindow        = nullptr;
@@ -57,6 +58,28 @@ rtl::Reference<svt::ToolboxController> CreateToolBoxController( const Reference<
         return nullptr;
 }
 
+pfunc_setWeldToolBoxControllerCreator SetWeldToolBoxControllerCreator( pfunc_setWeldToolBoxControllerCreator pSetWeldToolBoxControllerCreator )
+{
+    ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+    pfunc_setWeldToolBoxControllerCreator pOldSetToolBoxControllerCreator = pWeldToolBoxControllerCreator;
+    pWeldToolBoxControllerCreator = pSetWeldToolBoxControllerCreator;
+    return pOldSetToolBoxControllerCreator;
+}
+
+css::uno::Reference<css::frame::XToolbarController> CreateWeldToolBoxController( const Reference< XFrame >& rFrame, weld::Toolbar* pToolbar, weld::Builder* pBuilder, const OUString& aCommandURL )
+{
+    pfunc_setWeldToolBoxControllerCreator pFactory = nullptr;
+    {
+        ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+        pFactory = pWeldToolBoxControllerCreator;
+    }
+
+    if ( pFactory )
+        return (*pFactory)( rFrame, pToolbar, pBuilder, aCommandURL );
+    else
+        return nullptr;
+}
+
 pfunc_setStatusBarControllerCreator SetStatusBarControllerCreator( pfunc_setStatusBarControllerCreator pSetStatusBarControllerCreator )
 {
     ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
diff --git a/framework/source/uielement/subtoolbarcontroller.cxx b/framework/source/uielement/subtoolbarcontroller.cxx
index 8615bacb9560..b9a30df0a1cd 100644
--- a/framework/source/uielement/subtoolbarcontroller.cxx
+++ b/framework/source/uielement/subtoolbarcontroller.cxx
@@ -46,6 +46,7 @@ namespace {
 
 class SubToolBarController : public ToolBarBase
 {
+    DECL_LINK(OnPopoverClose, weld::Popover&, void);
     OUString m_aSubTbName;
     OUString m_aLastCommand;
     css::uno::Reference< css::ui::XUIElement > m_xUIElement;
@@ -242,7 +243,6 @@ std::unique_ptr<WeldToolbarPopup> SubToolBarController::weldPopupWindow()
 
     // create element with factory
     static css::uno::WeakReference< css::ui::XUIElementFactoryManager > xWeakUIElementFactory;
-    css::uno::Reference< css::ui::XUIElement > xUIElement;
     css::uno::Reference< css::ui::XUIElementFactoryManager > xUIElementFactory = xWeakUIElementFactory;
     if ( !xUIElementFactory.is() )
     {
@@ -261,13 +261,17 @@ std::unique_ptr<WeldToolbarPopup> SubToolBarController::weldPopupWindow()
 
     try
     {
-        xUIElement = xUIElementFactory->createUIElement( "private:resource/toolbar/" + m_aSubTbName, aPropSeq );
+        m_xUIElement = xUIElementFactory->createUIElement( "private:resource/toolbar/" + m_aSubTbName, aPropSeq );
     }
     catch ( css::container::NoSuchElementException& )
     {}
     catch ( css::lang::IllegalArgumentException& )
     {}
 
+    weld::Popover* pPopover = dynamic_cast<weld::Popover*>(pPopup->getTopLevel());
+    if (pPopover)
+        pPopover->connect_closed(LINK(this, SubToolBarController, OnPopoverClose));
+
     return pPopup;
 }
 
@@ -498,6 +502,12 @@ void SubToolBarController::initialize( const css::uno::Sequence< css::uno::Any >
     updateImage();
 }
 
+IMPL_LINK_NOARG(SubToolBarController, OnPopoverClose, weld::Popover&, void)
+{
+    disposeUIElement();
+    m_xUIElement = nullptr;
+}
+
 void SubToolBarController::dispose()
 {
     if ( m_bDisposed )
diff --git a/framework/source/uielement/toolbarmanager.cxx b/framework/source/uielement/toolbarmanager.cxx
index c50d25650082..655bf0c8d0df 100644
--- a/framework/source/uielement/toolbarmanager.cxx
+++ b/framework/source/uielement/toolbarmanager.cxx
@@ -31,7 +31,6 @@
 #include <classes/fwkresid.hxx>
 #include <classes/resource.hxx>
 #include <strings.hrc>
-#include <framework/addonsoptions.hxx>
 #include <uielement/toolbarmerger.hxx>
 
 #include <com/sun/star/ui/ItemType.hpp>
@@ -63,6 +62,7 @@
 #include <svtools/miscopt.hxx>
 #include <svtools/imgdef.hxx>
 #include <vcl/event.hxx>
+#include <vcl/graph.hxx>
 #include <vcl/svapp.hxx>
 #include <vcl/menu.hxx>
 #include <vcl/syswin.hxx>
@@ -70,6 +70,7 @@
 #include <vcl/toolbox.hxx>
 #include <vcl/settings.hxx>
 #include <vcl/commandinfoprovider.hxx>
+#include <vcl/weldutils.hxx>
 #include <tools/debug.hxx>
 
 #include <svtools/menuoptions.hxx>
@@ -132,6 +133,436 @@ sal_Int16 getCurrentImageType()
     return nImageType;
 }
 
+class VclToolBarManager : public ToolBarManagerImpl
+{
+    DECL_LINK(Click, ToolBox*, void);
+
+public:
+    VclToolBarManager(VclPtr<ToolBox> pToolbar)
+    : m_pToolBar(pToolbar)
+    , m_bAddedToTaskPaneList(true)
+    , m_pManager(nullptr)
+    {}
+
+    ~VclToolBarManager()
+    {
+        OSL_ASSERT( !m_bAddedToTaskPaneList );
+    }
+
+    virtual void Init() override
+    {
+        vcl::Window* pWindow = m_pToolBar;
+        while ( pWindow && !pWindow->IsSystemWindow() )
+            pWindow = pWindow->GetParent();
+
+        if ( pWindow )
+            static_cast<SystemWindow *>(pWindow)->GetTaskPaneList()->AddWindow( m_pToolBar );
+    }
+
+    virtual void Destroy() override
+    {
+        OSL_ASSERT( m_pToolBar != nullptr );
+        SolarMutexGuard g;
+        if ( m_bAddedToTaskPaneList )
+        {
+            vcl::Window* pWindow = m_pToolBar;
+            while ( pWindow && !pWindow->IsSystemWindow() )
+                pWindow = pWindow->GetParent();
+
+            if ( pWindow )
+                static_cast<SystemWindow *>(pWindow)->GetTaskPaneList()->RemoveWindow( m_pToolBar );
+            m_bAddedToTaskPaneList = false;
+        }
+
+        // Delete the additional add-ons data
+        for ( ToolBox::ImplToolItems::size_type i = 0; i < m_pToolBar->GetItemCount(); i++ )
+        {
+            ToolBoxItemId nItemId = m_pToolBar->GetItemId( i );
+            if ( nItemId > ToolBoxItemId(0) )
+                delete static_cast< AddonsParams* >( m_pToolBar->GetItemData( nItemId ));
+        }
+
+        // tdf#119390 this will reparent the toolbar, so focus is restored from a
+        // floating toolbar to the last focused control of the application window.
+        m_pToolBar->SetParentToDefaultWindow();
+        // #i93173# note we can still be in one of the toolbar's handlers
+        m_pToolBar->SetSelectHdl( Link<ToolBox *, void>() );
+        m_pToolBar->SetActivateHdl( Link<ToolBox *, void>() );
+        m_pToolBar->SetDeactivateHdl( Link<ToolBox *, void>() );
+        m_pToolBar->SetClickHdl( Link<ToolBox *, void>() );
+        m_pToolBar->SetDropdownClickHdl( Link<ToolBox *, void>() );
+        m_pToolBar->SetDoubleClickHdl( Link<ToolBox *, void>() );
+        m_pToolBar->SetStateChangedHdl( Link<StateChangedType const *, void>() );
+        m_pToolBar->SetDataChangedHdl( Link<DataChangedEvent const *, void>() );
+
+        m_pToolBar.disposeAndClear();
+    }
+
+    virtual css::uno::Reference<css::awt::XWindow> GetInterface() override
+    {
+        return VCLUnoHelper::GetInterface(m_pToolBar);
+    }
+
+    virtual css::uno::Reference<css::frame::XStatusListener> CreateToolBoxController(
+        const css::uno::Reference<css::frame::XFrame>& rFrame,
+        ToolBoxItemId nId,
+        const OUString& rCommandURL ) override
+    {
+        rtl::Reference<svt::ToolboxController> pController
+            = ::framework::CreateToolBoxController( rFrame, m_pToolBar, nId, rCommandURL );
+        css::uno::Reference<css::frame::XStatusListener> xListener;
+        if (pController)
+            xListener = pController;
+        return xListener;
+    }
+
+    virtual void ConnectCallbacks(ToolBarManager* pManager) override
+    {
+        m_pManager = pManager;
+        m_pToolBar->SetSelectHdl( LINK( pManager, ToolBarManager, Select) );
+        m_pToolBar->SetClickHdl( LINK( this, VclToolBarManager, Click ) );
+        m_pToolBar->SetDropdownClickHdl( LINK( pManager, ToolBarManager, DropdownClick ) );
+        m_pToolBar->SetDoubleClickHdl( LINK( pManager, ToolBarManager, DoubleClick ) );
+        m_pToolBar->SetStateChangedHdl( LINK( pManager, ToolBarManager, StateChanged ) );
+        m_pToolBar->SetDataChangedHdl( LINK( pManager, ToolBarManager, DataChanged ) );
+
+        m_pToolBar->SetMenuButtonHdl( LINK( pManager, ToolBarManager, MenuButton ) );
+        m_pToolBar->SetMenuExecuteHdl( LINK( pManager, ToolBarManager, MenuPreExecute ) );
+        m_pToolBar->GetMenu()->SetSelectHdl( LINK( pManager, ToolBarManager, MenuSelect ) );
+    }
+
+    virtual void InsertItem(ToolBoxItemId nId,
+                            const OUString& rString,
+                            const OUString& rCommandURL,
+                            const OUString& rTooltip,
+                            const OUString& rLabel,
+                            ToolBoxItemBits nItemBits) override
+    {
+        m_pToolBar->InsertItem( nId, rString, nItemBits );
+        m_pToolBar->SetItemCommand( nId, rCommandURL );
+        m_pToolBar->SetQuickHelpText(nId, rTooltip);
+        m_pToolBar->SetItemText( nId, rLabel );
+        m_pToolBar->EnableItem( nId );
+        m_pToolBar->SetItemState( nId, TRISTATE_FALSE );
+    }
+
+    virtual void InsertSeparator() override
+    {
+        m_pToolBar->InsertSeparator();
+    }
+
+    virtual void InsertSpace() override
+    {
+        m_pToolBar->InsertSpace();
+    }
+
+    virtual void InsertBreak() override
+    {
+        m_pToolBar->InsertBreak();
+    }
+
+    virtual ToolBoxItemId GetItemId(sal_uInt16 nPos) override
+    {
+        return m_pToolBar->GetItemId(nPos);
+    }
+
+    virtual ToolBoxItemId GetCurItemId() override
+    {
+        return m_pToolBar->GetCurItemId();
+    }
+
+    virtual OUString GetItemCommand(ToolBoxItemId nId) override
+    {
+        return m_pToolBar->GetItemCommand(nId);
+    }
+
+    virtual sal_uInt16 GetItemCount() override
+    {
+        return m_pToolBar->GetItemCount();
+    }
+
+    virtual void SetItemCheckable(ToolBoxItemId nId) override
+    {
+        m_pToolBar->SetItemBits( nId, m_pToolBar->GetItemBits( nId ) | ToolBoxItemBits::CHECKABLE );
+    }
+
+    virtual void HideItem(ToolBoxItemId nId, const OUString& /*rCommandURL*/) override
+    {
+        m_pToolBar->HideItem( nId );
+    }
+
+    virtual bool IsItemVisible(ToolBoxItemId nId, const OUString& /*rCommandURL*/) override
+    {
+        return m_pToolBar->IsItemVisible(nId);
+    }
+
+    virtual void Clear() override
+    {
+        m_pToolBar->Clear();
+    }
+
+    virtual void SetName(const OUString& rName) override
+    {
+        m_pToolBar->SetText( rName );
+    }
+
+    virtual void SetHelpId(const OString& rHelpId) override
+    {
+        m_pToolBar->SetHelpId( rHelpId );
+    }
+
+    virtual bool WillUsePopupMode() override
+    {
+        return m_pToolBar->WillUsePopupMode();
+    }
+
+    virtual bool IsReallyVisible() override
+    {
+        return m_pToolBar->IsReallyVisible();
+    }
+
+    virtual void SetIconSize(ToolBoxButtonSize eSize) override
+    {
+        m_pToolBar->SetToolboxButtonSize(eSize);
+    }
+
+    virtual vcl::ImageType GetImageSize() override
+    {
+        return m_pToolBar->GetImageSize();
+    }
+
+    virtual void SetMenuType(ToolBoxMenuType eType) override
+    {
+        m_pToolBar->SetMenuType( eType );
+    }
+
+    virtual void MergeToolbar(ToolBoxItemId nItemId,
+                              const OUString& rModuleIdentifier,
+                              CommandToInfoMap& rCommandMap,
+                              MergeToolbarInstruction& rInstruction) override
+    {
+        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_pToolBar,
+                                                    aRefPoint.nPos,
+                                                    nItemId,
+                                                    rCommandMap,
+                                                    rModuleIdentifier,
+                                                    rInstruction.aMergeCommand,
+                                                    rInstruction.aMergeCommandParameter,
+                                                    aItems );
+        }
+        else
+        {
+            ToolBarMerger::ProcessMergeFallback( m_pToolBar,
+                                                    nItemId,
+                                                    rCommandMap,
+                                                    rModuleIdentifier,
+                                                    rInstruction.aMergeCommand,
+                                                    rInstruction.aMergeFallback,
+                                                    aItems );
+        }
+    }
+
+    virtual void SetItemImage(ToolBoxItemId nId,
+                              const OUString& /*rCommandURL*/,
+                              const Image& rImage) override
+    {
+        m_pToolBar->SetItemImage(nId, rImage);
+    }
+
+    virtual void UpdateSize() override
+    {
+        ::Size aSize = m_pToolBar->CalcWindowSizePixel();
+        m_pToolBar->SetOutputSizePixel( aSize );
+    }
+
+    virtual void SetItemWindow(ToolBoxItemId nItemId, vcl::Window* pNewWindow) override
+    {
+        m_pToolBar->SetItemWindow( nItemId, pNewWindow );
+    }
+
+private:
+    VclPtr<ToolBox> m_pToolBar;
+    bool m_bAddedToTaskPaneList;
+    ToolBarManager* m_pManager;
+};
+
+IMPL_LINK_NOARG(VclToolBarManager, Click, ToolBox*, void)
+{
+    m_pManager->OnClick();
+}
+
+class WeldToolBarManager : public ToolBarManagerImpl
+{
+    DECL_LINK(Click, const OString&, void);
+    DECL_LINK(ToggleMenuHdl, const OString&, void);
+
+public:
+    WeldToolBarManager(weld::Toolbar* pToolbar,
+                       weld::Builder* pBuilder)
+    : m_pWeldedToolBar(pToolbar)
+    , m_pBuilder(pBuilder)
+    , m_pManager(nullptr)
+    , m_nCurrentId(0)
+    {}
+
+    virtual void Init() override {}
+
+    virtual void Destroy() override {}
+
+    virtual css::uno::Reference<css::awt::XWindow> GetInterface() override
+    {
+        return new weld::TransportAsXWindow(m_pWeldedToolBar);
+    }
+
+    virtual css::uno::Reference<css::frame::XStatusListener> CreateToolBoxController(
+        const css::uno::Reference<css::frame::XFrame>& rFrame,
+        ToolBoxItemId /*nId*/,
+        const OUString& rCommandURL ) override
+    {
+        css::uno::Reference<css::frame::XToolbarController> xController
+            = ::framework::CreateWeldToolBoxController(rFrame, m_pWeldedToolBar, m_pBuilder, rCommandURL);
+        css::uno::Reference<css::frame::XStatusListener> xListener;
+        if (xController.is())
+            xListener = css::uno::Reference<css::frame::XStatusListener>( xController, UNO_QUERY );
+        return xListener;
+    }
+
+    virtual void ConnectCallbacks(ToolBarManager* pManager) override
+    {
+        m_pManager = pManager;
+        m_pWeldedToolBar->connect_clicked(LINK(this, WeldToolBarManager, Click));
+        m_pWeldedToolBar->connect_menu_toggled(LINK(this, WeldToolBarManager, ToggleMenuHdl));
+    }
+
+    virtual void InsertItem(ToolBoxItemId nId,
+                            const OUString& /*rString*/,
+                            const OUString& rCommandURL,
+                            const OUString& rTooltip,
+                            const OUString& rLabel,
+                            ToolBoxItemBits /*nItemBits*/) override
+    {
+        OString sId = OUStringToOString(rCommandURL, RTL_TEXTENCODING_UTF8);
+        m_aCommandToId[sId] = nId;
+        m_aIdToCommand[nId] = sId;
+        m_aCommandOrder.push_back(sId);
+
+        m_pWeldedToolBar->insert_item(m_aCommandOrder.size(), rCommandURL);
+        m_pWeldedToolBar->set_item_tooltip_text(sId, rTooltip);
+        m_pWeldedToolBar->set_item_label( sId, rLabel );
+        m_pWeldedToolBar->set_item_sensitive( sId, true );
+        m_pWeldedToolBar->set_item_active( sId, false );
+    }
+
+    virtual void InsertSeparator() override
+    {
+        m_pWeldedToolBar->append_separator("");
+    }
+
+    virtual void InsertSpace() override {}
+
+    virtual void InsertBreak() override {}
+
+    virtual ToolBoxItemId GetItemId(sal_uInt16 nPos) override
+    {
+        return m_aCommandToId[m_aCommandOrder[nPos]];
+    }
+
+    virtual ToolBoxItemId GetCurItemId() override
+    {
+        return m_nCurrentId;
+    }
+
+    virtual OUString GetItemCommand(ToolBoxItemId nId) override
+    {
+        return OStringToOUString(m_aIdToCommand[nId], RTL_TEXTENCODING_UTF8);
+    }
+
+    virtual sal_uInt16 GetItemCount() override
+    {
+        return m_aCommandOrder.size();
+    }
+
+    virtual void SetItemCheckable(ToolBoxItemId /*nId*/) override {}
+
+    virtual void HideItem(ToolBoxItemId /*nId*/, const OUString& rCommandURL) override
+    {
+        OString sId = OUStringToOString(rCommandURL, RTL_TEXTENCODING_UTF8);
+        m_pWeldedToolBar->set_item_visible(sId, false);
+    }
+
+    virtual bool IsItemVisible(ToolBoxItemId /*nId*/, const OUString& rCommandURL) override
+    {
+        OString sId = OUStringToOString(rCommandURL, RTL_TEXTENCODING_UTF8);
+        return m_pWeldedToolBar->get_item_visible(sId);
+    }
+
+    virtual void Clear() override {}
+
+    virtual void SetName(const OUString& /*rName*/) override {}
+
+    virtual void SetHelpId(const OString& /*rHelpId*/) override {}
+
+    virtual bool WillUsePopupMode() override { return true; }
+
+    virtual bool IsReallyVisible() override { return true; }
+
+    virtual void SetIconSize(ToolBoxButtonSize /*eSize*/) override {}
+
+    virtual vcl::ImageType GetImageSize() override
+    {
+        return vcl::ImageType::Size32;
+    }
+
+    virtual void SetMenuType(ToolBoxMenuType /*eType*/) override {}
+
+    virtual void MergeToolbar(ToolBoxItemId /*nItemId*/,
+                              const OUString& /*rModuleIdentifier*/,
+                              CommandToInfoMap& /*rCommandMap*/,
+                              MergeToolbarInstruction& /*rInstruction*/) override {}
+
+    virtual void SetItemImage(ToolBoxItemId /*nId*/,
+                              const OUString& rCommandURL,
+                              const Image& rImage) override
+    {
+        OString sId = OUStringToOString(rCommandURL, RTL_TEXTENCODING_UTF8);
+        m_pWeldedToolBar->set_item_image(sId, Graphic(rImage).GetXGraphic());
+    }
+
+    virtual void UpdateSize() override {}
+
+    virtual void SetItemWindow(ToolBoxItemId /*nItemId*/, vcl::Window* /*pNewWindow*/) override {}
+
+private:
+    weld::Toolbar* m_pWeldedToolBar;
+    weld::Builder* m_pBuilder;
+    ToolBarManager* m_pManager;
+    ToolBoxItemId m_nCurrentId;
+    std::map<const OString, ToolBoxItemId> m_aCommandToId;
+    std::map<ToolBoxItemId, OString> m_aIdToCommand;
+    std::vector<OString> m_aCommandOrder;
+};
+
+IMPL_LINK(WeldToolBarManager, Click, const OString&, rCommand, void)
+{
+    m_nCurrentId = m_aCommandToId[rCommand];
+    m_pManager->OnClick(true);
+}
+
+IMPL_LINK(WeldToolBarManager, ToggleMenuHdl, const OString&, rCommand, void)
+{
+    m_nCurrentId = m_aCommandToId[rCommand];
+    m_pManager->OnDropdownClick(false);
+}
+
 } // end anonymous namespace
 
 //  XInterface, XTypeProvider, XServiceInfo
@@ -141,10 +572,10 @@ ToolBarManager::ToolBarManager( const Reference< XComponentContext >& rxContext,
                                 const OUString& rResourceName,
                                 ToolBox* pToolBar ) :
     m_bDisposed( false ),
-    m_bAddedToTaskPaneList( true ),
     m_bFrameActionRegistered( false ),
     m_bUpdateControllers( false ),
     m_eSymbolSize(SvtMiscOptions().GetCurrentSymbolsSize()),
+    m_pImpl( new VclToolBarManager( pToolBar ) ),
     m_pToolBar( pToolBar ),
     m_aResourceName( rResourceName ),
     m_xFrame( rFrame ),
@@ -152,31 +583,44 @@ ToolBarManager::ToolBarManager( const Reference< XComponentContext >& rxContext,
     m_xContext( rxContext ),
     m_sIconTheme( SvtMiscOptions().GetIconTheme() )
 {
-    OSL_ASSERT( m_xContext.is() );
+    Init();
+}
 
-    vcl::Window* pWindow = m_pToolBar;
-    while ( pWindow && !pWindow->IsSystemWindow() )
-        pWindow = pWindow->GetParent();
+ToolBarManager::ToolBarManager( const Reference< XComponentContext >& rxContext,
+                                const Reference< XFrame >& rFrame,
+                                const OUString& rResourceName,
+                                weld::Toolbar* pToolBar,
+                                weld::Builder* pBuilder ) :
+    m_bDisposed( false ),
+    m_bFrameActionRegistered( false ),
+    m_bUpdateControllers( false ),
+    m_eSymbolSize( SvtMiscOptions().GetCurrentSymbolsSize() ),
+    m_pImpl( new WeldToolBarManager( pToolBar, pBuilder ) ),
+    m_pToolBar( nullptr ),
+    m_aResourceName( rResourceName ),
+    m_xFrame( rFrame ),
+    m_aListenerContainer( m_mutex ),
+    m_xContext( rxContext ),
+    m_sIconTheme( SvtMiscOptions().GetIconTheme() )
+{
+    Init();
+}
 
-    if ( pWindow )
-        static_cast<SystemWindow *>(pWindow)->GetTaskPaneList()->AddWindow( m_pToolBar );
+void ToolBarManager::Init()
+{
+    OSL_ASSERT( m_xContext.is() );
 
     m_xToolbarControllerFactory = frame::theToolbarControllerFactory::get( m_xContext );
     m_xURLTransformer = URLTransformer::create( m_xContext );
 
-    m_pToolBar->SetSelectHdl( LINK( this, ToolBarManager, Select) );
-    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_pImpl->ConnectCallbacks(this);
 
     if (m_eSymbolSize == SFX_SYMBOLS_SIZE_LARGE)
-        m_pToolBar->SetToolboxButtonSize(ToolBoxButtonSize::Large);
+        m_pImpl->SetIconSize(ToolBoxButtonSize::Large);
     else if (m_eSymbolSize == SFX_SYMBOLS_SIZE_32)
-        m_pToolBar->SetToolboxButtonSize(ToolBoxButtonSize::Size32);
+        m_pImpl->SetIconSize(ToolBoxButtonSize::Size32);
     else
-        m_pToolBar->SetToolboxButtonSize(ToolBoxButtonSize::Small);
+        m_pImpl->SetIconSize(ToolBoxButtonSize::Small);
 
     // enables a menu for clipped items and customization
     SvtCommandOptions aCmdOptions;
@@ -184,18 +628,15 @@ ToolBarManager::ToolBarManager( const Reference< XComponentContext >& rxContext,
     if ( !aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, "CreateDialog"))
          nMenuType |= ToolBoxMenuType::Customize;
 
-    m_pToolBar->SetMenuType( nMenuType );
-    m_pToolBar->SetMenuButtonHdl( LINK( this, ToolBarManager, MenuButton ) );
-    m_pToolBar->SetMenuExecuteHdl( LINK( this, ToolBarManager, MenuPreExecute ) );
-    m_pToolBar->GetMenu()->SetSelectHdl( LINK( this, ToolBarManager, MenuSelect ) );
+    m_pImpl->SetMenuType( nMenuType );
 
     // set name for testtool, the useful part is after the last '/'
-    sal_Int32 idx = rResourceName.lastIndexOf('/');
+    sal_Int32 idx = m_aResourceName.lastIndexOf('/');
     idx++; // will become 0 if '/' not found: use full string
     OString  aHelpIdAsString( ".HelpId:" );
-    OUString  aToolbarName = rResourceName.copy( idx );
+    OUString  aToolbarName = m_aResourceName.copy( idx );
     aHelpIdAsString += OUStringToOString( aToolbarName, RTL_TEXTENCODING_UTF8 );
-    m_pToolBar->SetHelpId( aHelpIdAsString );
+    m_pImpl->SetHelpId( aHelpIdAsString );
 
     m_aAsyncUpdateControllersTimer.SetTimeout( 50 );
     m_aAsyncUpdateControllersTimer.SetInvokeHandler( LINK( this, ToolBarManager, AsyncUpdateControllersHdl ) );
@@ -208,46 +649,11 @@ ToolBarManager::~ToolBarManager()
 {
     assert(!m_aAsyncUpdateControllersTimer.IsActive());
     assert(!m_pToolBar); // must be disposed by ToolbarLayoutManager
-    OSL_ASSERT( !m_bAddedToTaskPaneList );
 }
 
 void ToolBarManager::Destroy()
 {
-    OSL_ASSERT( m_pToolBar != nullptr );
-    SolarMutexGuard g;
-    if ( m_bAddedToTaskPaneList )
-    {
-        vcl::Window* pWindow = m_pToolBar;
-        while ( pWindow && !pWindow->IsSystemWindow() )
-            pWindow = pWindow->GetParent();
-
-        if ( pWindow )
-            static_cast<SystemWindow *>(pWindow)->GetTaskPaneList()->RemoveWindow( m_pToolBar );
-        m_bAddedToTaskPaneList = false;
-    }
-
-    // Delete the additional add-ons data
-    for ( ToolBox::ImplToolItems::size_type i = 0; i < m_pToolBar->GetItemCount(); i++ )
-    {
-        ToolBoxItemId nItemId = m_pToolBar->GetItemId( i );
-        if ( nItemId > ToolBoxItemId(0) )
-            delete static_cast< AddonsParams* >( m_pToolBar->GetItemData( nItemId ));
-    }
-
-    // tdf#119390 this will reparent the toolbar, so focus is restored from a
-    // floating toolbar to the last focused control of the application window.
-    m_pToolBar->SetParentToDefaultWindow();
-    // #i93173# note we can still be in one of the toolbar's handlers
-    m_pToolBar->SetSelectHdl( Link<ToolBox *, void>() );
-    m_pToolBar->SetActivateHdl( Link<ToolBox *, void>() );
-    m_pToolBar->SetDeactivateHdl( Link<ToolBox *, void>() );
-    m_pToolBar->SetClickHdl( Link<ToolBox *, void>() );
-    m_pToolBar->SetDropdownClickHdl( Link<ToolBox *, void>() );
-    m_pToolBar->SetDoubleClickHdl( Link<ToolBox *, void>() );
-    m_pToolBar->SetStateChangedHdl( Link<StateChangedType const *, void>() );
-    m_pToolBar->SetDataChangedHdl( Link<DataChangedEvent const *, void>() );
-
-    m_pToolBar.disposeAndClear();
+    m_pImpl->Destroy();
 
     SvtMiscOptions().RemoveListenerLink( LINK( this, ToolBarManager, MiscOptionsChanged ) );
 }
@@ -289,11 +695,11 @@ void ToolBarManager::RefreshImages()
     SolarMutexGuard g;
 
     if (m_eSymbolSize == SFX_SYMBOLS_SIZE_LARGE)
-        m_pToolBar->SetToolboxButtonSize(ToolBoxButtonSize::Large);
+        m_pImpl->SetIconSize(ToolBoxButtonSize::Large);
     else if (m_eSymbolSize == SFX_SYMBOLS_SIZE_32)
-        m_pToolBar->SetToolboxButtonSize(ToolBoxButtonSize::Size32);
+        m_pImpl->SetIconSize(ToolBoxButtonSize::Size32);
     else
-        m_pToolBar->SetToolboxButtonSize(ToolBoxButtonSize::Small);
+        m_pImpl->SetIconSize(ToolBoxButtonSize::Small);
 
     for ( auto const& it : m_aControllerMap )
     {
@@ -306,20 +712,19 @@ void ToolBarManager::RefreshImages()
         }
         else
         {
-            OUString aCommandURL = m_pToolBar->GetItemCommand( it.first );
-            vcl::ImageType eImageType = m_pToolBar->GetImageSize();
+            OUString aCommandURL = m_pImpl->GetItemCommand( it.first );
+            vcl::ImageType eImageType = m_pImpl->GetImageSize();
             Image aImage = vcl::CommandInfoProvider::GetImageForCommand(aCommandURL, m_xFrame, eImageType);
             // Try also to query for add-on images before giving up and use an
             // empty image.
             bool bBigImages = eImageType != vcl::ImageType::Size16;
             if ( !aImage )
                 aImage = Image(framework::AddonsOptions().GetImageFromURL(aCommandURL, bBigImages));
-            m_pToolBar->SetItemImage( it.first, aImage );
+            m_pImpl->SetItemImage( it.first, aCommandURL, aImage );
         }
     }
 
-    ::Size aSize = m_pToolBar->CalcWindowSizePixel();
-    m_pToolBar->SetOutputSizePixel( aSize );
+    m_pImpl->UpdateSize();
 }
 
 void ToolBarManager::UpdateControllers()
@@ -333,7 +738,7 @@ void ToolBarManager::UpdateControllers()
         if ( xFramePropSet.is() )
             a = xFramePropSet->getPropertyValue("LayoutManager");
         a >>= xLayoutManager;
-        Reference< XDockableWindow > xDockable( VCLUnoHelper::GetInterface( m_pToolBar ), UNO_QUERY );
+        Reference< XDockableWindow > xDockable( m_pImpl->GetInterface(), UNO_QUERY );
         if ( xLayoutManager.is() && xDockable.is() )
         {
             css::awt::Point aPoint;
@@ -605,10 +1010,10 @@ void ToolBarManager::setToolBarImage(const Image& rImage,
         const CommandToInfoMap::const_iterator& rIter)
 {
     const ::std::vector<ToolBoxItemId>& rIDs = rIter->second.aIds;
-    m_pToolBar->SetItemImage( rIter->second.nId, rImage );
+    m_pImpl->SetItemImage( rIter->second.nId, rIter->first, rImage );
     for (auto const& it : rIDs)
     {
-        m_pToolBar->SetItemImage(it, rImage);
+        m_pImpl->SetItemImage(it, rIter->first, rImage);
     }
 }
 
@@ -629,9 +1034,9 @@ void ToolBarManager::RemoveControllers()
     // 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 ( ToolBox::ImplToolItems::size_type i = 0; i < m_pToolBar->GetItemCount(); i++ )
+    for ( ToolBox::ImplToolItems::size_type i = 0; i < m_pImpl->GetItemCount(); i++ )
     {
-        ToolBoxItemId nItemId = m_pToolBar->GetItemId( i );
+        ToolBoxItemId nItemId = m_pImpl->GetItemId( i );
         if ( nItemId > ToolBoxItemId(0) )
         {
             Reference< XComponent > xComponent( m_aControllerMap[ nItemId ], UNO_QUERY );
@@ -645,7 +1050,7 @@ void ToolBarManager::RemoveControllers()
                 {
                 }
             }
-            m_pToolBar->SetItemWindow(nItemId, nullptr);
+            m_pImpl->SetItemWindow(nItemId, nullptr);
         }
     }
     m_aControllerMap.clear();
@@ -653,15 +1058,15 @@ void ToolBarManager::RemoveControllers()
 
 void ToolBarManager::CreateControllers()
 {
-    Reference< XWindow > xToolbarWindow = VCLUnoHelper::GetInterface( m_pToolBar );
+    Reference< XWindow > xToolbarWindow = m_pImpl->GetInterface();
 
     css::util::URL      aURL;
     bool                bHasDisabledEntries = SvtCommandOptions().HasEntries( SvtCommandOptions::CMDOPTION_DISABLED );
     SvtCommandOptions   aCmdOptions;
 
-    for ( ToolBox::ImplToolItems::size_type i = 0; i < m_pToolBar->GetItemCount(); i++ )
+    for ( ToolBox::ImplToolItems::size_type i = 0; i < m_pImpl->GetItemCount(); i++ )
     {
-        ToolBoxItemId nId = m_pToolBar->GetItemId( i );
+        ToolBoxItemId nId = m_pImpl->GetItemId( i );
         if ( nId == ToolBoxItemId(0) )
             continue;
 
@@ -671,7 +1076,7 @@ void ToolBarManager::CreateControllers()
 
         rtl::Reference<svt::ToolboxController> pController;
 
-        OUString aCommandURL( m_pToolBar->GetItemCommand( nId ) );
+        OUString aCommandURL( m_pImpl->GetItemCommand( nId ) );
         // Command can be just an alias to another command.
         auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(aCommandURL, m_aModuleIdentifier);
         OUString aRealCommandURL( vcl::CommandInfoProvider::GetRealCommandForCommand(aProperties) );
@@ -685,7 +1090,7 @@ void ToolBarManager::CreateControllers()
             if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aURL.Path ))
             {
                 m_aControllerMap[ nId ] = xController;
-                m_pToolBar->HideItem( nId );
+                m_pImpl->HideItem( nId, aCommandURL );
                 continue;
             }
         }
@@ -719,26 +1124,25 @@ void ToolBarManager::CreateControllers()
             bInit = false; // Initialization is done through the factory service
         }
 
-        if (( aCommandURL == ".uno:OpenUrl" ) && ( !m_pToolBar->IsItemVisible(nId)))
+        if (( aCommandURL == ".uno:OpenUrl" ) && ( !m_pImpl->IsItemVisible(nId, aCommandURL)))
             bCreate = false;
 
         if ( !xController.is() && bCreate )
         {
-            pController = CreateToolBoxController( m_xFrame, m_pToolBar, nId, aCommandURL );
-            if ( !pController )
+            xController = m_pImpl->CreateToolBoxController( m_xFrame, nId, aCommandURL );
+            if ( !xController )
             {
-
                 if ( aCommandURL.startsWith( ".uno:StyleApply?" ) )
                 {
                     xController.set( new StyleToolbarController( m_xContext, m_xFrame, aCommandURL ));
-                    m_pToolBar->SetItemBits( nId, m_pToolBar->GetItemBits( nId ) | ToolBoxItemBits::CHECKABLE );
+                    m_pImpl->SetItemCheckable( nId );
                 }
                 else if ( aCommandURL.startsWith( "private:resource/" ) )
                 {
                     xController.set( m_xContext->getServiceManager()->createInstanceWithContext(
                         "com.sun.star.comp.framework.GenericPopupToolbarController", m_xContext ), UNO_QUERY );
                 }
-                else if ( m_pToolBar->GetItemData( nId ) != nullptr )
+                else if ( m_pToolBar && m_pToolBar->GetItemData( nId ) != nullptr )
                 {
                     // retrieve additional parameters
                     OUString aControlType = static_cast< AddonsParams* >( m_pToolBar->GetItemData( nId ))->aControlType;
@@ -755,7 +1159,7 @@ void ToolBarManager::CreateControllers()
 
                     xController = xStatusListener;
                 }
-                else
+                else if (m_pToolBar)
                 {
                     xController.set(
                         new GenericToolbarController( m_xContext, m_xFrame, m_pToolBar, nId, aCommandURL ));
@@ -763,13 +1167,9 @@ void ToolBarManager::CreateControllers()
                     // Accessibility support: Set toggle button role for specific commands
                     sal_Int32 nProps = vcl::CommandInfoProvider::GetPropertiesForCommand(aCommandURL, m_aModuleIdentifier);
                     if ( nProps & UICOMMANDDESCRIPTION_PROPERTIES_TOGGLEBUTTON )
-                        m_pToolBar->SetItemBits( nId, m_pToolBar->GetItemBits( nId ) | ToolBoxItemBits::CHECKABLE );
+                        m_pImpl->SetItemCheckable( nId );
                 }
             }
-            else if ( pController )
-            {
-                xController = pController;
-            }
         }
 
         // Associate ID and controller to be able to retrieve
@@ -846,9 +1246,9 @@ void ToolBarManager::CreateControllers()
                     if ( pItemWin )
                     {
                         WindowType nType = pItemWin->GetType();
-                        if ( nType == WindowType::LISTBOX || nType == WindowType::MULTILISTBOX || nType == WindowType::COMBOBOX )
+                        if ( m_pToolBar && (nType == WindowType::LISTBOX || nType == WindowType::MULTILISTBOX || nType == WindowType::COMBOBOX) )
                             pItemWin->SetAccessibleName( m_pToolBar->GetItemText( nId ) );
-                        m_pToolBar->SetItemWindow( nId, pItemWin );
+                        m_pImpl->SetItemWindow( nId, pItemWin );
                     }
                 }
             }
@@ -969,7 +1369,7 @@ void ToolBarManager::FillToolbar( const Reference< XIndexAccess >& rItemContaine
     RemoveControllers();
 
     // reset and fill command map
-    m_pToolBar->Clear();
+    m_pImpl->Clear();
     m_aControllerMap.clear();
     m_aCommandMap.clear();
 
@@ -1017,23 +1417,14 @@ void ToolBarManager::FillToolbar( const Reference< XIndexAccess >& rItemContaine
                     OUString aString(vcl::CommandInfoProvider::GetLabelForCommand(aProperties));
 
                     ToolBoxItemBits nItemBits = ConvertStyleToToolboxItemBits( nStyle );
-                    m_pToolBar->InsertItem( nId, aString, nItemBits );
-                    m_pToolBar->SetItemCommand( nId, aCommandURL );
-                    if ( !aTooltip.isEmpty() )
-                        m_pToolBar->SetQuickHelpText(nId, aTooltip);
-                    else
-                        m_pToolBar->SetQuickHelpText(nId, vcl::CommandInfoProvider::GetTooltipForCommand(aCommandURL, aProperties, m_xFrame));
 
-                    if ( !aLabel.isEmpty() )
-                    {
-                        m_pToolBar->SetItemText( nId, aLabel );
-                    }
-                    else
-                    {
-                        m_pToolBar->SetItemText( nId, aString );
-                    }
-                    m_pToolBar->EnableItem( nId );
-                    m_pToolBar->SetItemState( nId, TRISTATE_FALSE );
+                    if ( aTooltip.isEmpty() )
+                        aTooltip = vcl::CommandInfoProvider::GetTooltipForCommand(aCommandURL, aProperties, m_xFrame);
+
+                    if ( aLabel.isEmpty() )
+                        aLabel = aString;
+
+                    m_pImpl->InsertItem(nId, aString, aCommandURL, aTooltip, aLabel, nItemBits);
 
                     // 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
@@ -1050,21 +1441,21 @@ void ToolBarManager::FillToolbar( const Reference< XIndexAccess >& rItemContaine
                     }
 
                     if ( !bIsVisible )
-                        m_pToolBar->HideItem( nId );
+                        m_pImpl->HideItem( nId, aCommandURL );
 
                     ++nId;
                 }
                 else if ( nType == css::ui::ItemType::SEPARATOR_LINE )
                 {
-                    m_pToolBar->InsertSeparator();
+                    m_pImpl->InsertSeparator();
                 }
                 else if ( nType == css::ui::ItemType::SEPARATOR_SPACE )
                 {
-                    m_pToolBar->InsertSpace();
+                    m_pImpl->InsertSpace();
                 }
                 else if ( nType == css::ui::ItemType::SEPARATOR_LINEBREAK )
                 {
-                    m_pToolBar->InsertBreak();
+                    m_pImpl->InsertBreak();
                 }
             }
         }
@@ -1097,34 +1488,7 @@ void ToolBarManager::FillToolbar( const Reference< XIndexAccess >& rItemContaine
             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_pToolBar,
-                                                          aRefPoint.nPos,
-                                                          nItemId,
-                                                          m_aCommandMap,
-                                                          m_aModuleIdentifier,
-                                                          rInstruction.aMergeCommand,
-                                                          rInstruction.aMergeCommandParameter,
-                                                          aItems );
-                }
-                else
-                {
-                    ToolBarMerger::ProcessMergeFallback( m_pToolBar,
-                                                         nItemId,
-                                                         m_aCommandMap,
-                                                         m_aModuleIdentifier,
-                                                         rInstruction.aMergeCommand,
-                                                         rInstruction.aMergeFallback,
-                                                         aItems );
-                }
+                m_pImpl->MergeToolbar(nItemId, m_aModuleIdentifier, m_aCommandMap, rInstruction);
             }
         }
     }
@@ -1139,9 +1503,9 @@ void ToolBarManager::FillToolbar( const Reference< XIndexAccess >& rItemContaine
 
     // 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() )
+    if( m_pImpl->WillUsePopupMode() )
         UpdateControllers();
-    else if ( m_pToolBar->IsReallyVisible() )
+    else if ( m_pImpl->IsReallyVisible() )
     {
         m_aAsyncUpdateControllersTimer.Start();
     }
@@ -1157,7 +1521,7 @@ void ToolBarManager::FillToolbar( const Reference< XIndexAccess >& rItemContaine
         OUString aUIName;
         xPropSet->getPropertyValue("UIName") >>= aUIName;
         if ( !aUIName.isEmpty() )
-            m_pToolBar->SetText( aUIName );
+            m_pImpl->SetName( aUIName );
     }
     catch (const Exception&)
     {
@@ -1166,6 +1530,9 @@ void ToolBarManager::FillToolbar( const Reference< XIndexAccess >& rItemContaine
 
 void ToolBarManager::FillAddonToolbar( const Sequence< Sequence< PropertyValue > >& rAddonToolbar )
 {
+    if (!m_pToolBar)
+        return;
+
     SolarMutexGuard g;
 
     if ( m_bDisposed )
@@ -1244,6 +1611,9 @@ void ToolBarManager::FillAddonToolbar( const Sequence< Sequence< PropertyValue >
 
 void ToolBarManager::FillOverflowToolbar( ToolBox const * pParent )
 {
+    if (!m_pToolBar)
+        return;
+
     CommandInfo aCmdInfo;
     bool bInsertSeparator = false;
     for ( ToolBox::ImplToolItems::size_type i = 0; i < pParent->GetItemCount(); ++i )
@@ -1387,37 +1757,60 @@ void ToolBarManager::notifyRegisteredControllers( const OUString& aUIElementName
     }
 }
 
-void ToolBarManager::HandleClick(void ( SAL_CALL XToolbarController::*_pClick )())
+void ToolBarManager::HandleClick(ClickAction eClickAction)
 {
     SolarMutexGuard g;
 
     if ( m_bDisposed )
         return;
 
-    ToolBoxItemId nId( m_pToolBar->GetCurItemId() );
+    ToolBoxItemId nId( m_pImpl->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)( );
+        {
+            switch (eClickAction)
+            {
+                case ClickAction::Click:
+                    xController->click();
+                    break;
+
+                case ClickAction::DblClick:
+                    xController->doubleClick();
+                    break;
+
+                case ClickAction::Execute:
+                    xController->execute(0);
+                    break;
+            }
+        }
     }
 }
 
-IMPL_LINK_NOARG(ToolBarManager, Click, ToolBox *, void)
+void ToolBarManager::OnClick(bool bUseExecute)
 {
-    HandleClick(&XToolbarController::click);
+    if (bUseExecute)
+        HandleClick(ClickAction::Execute);
+    else
+        HandleClick(ClickAction::Click);
 }
 
 IMPL_LINK_NOARG(ToolBarManager, DropdownClick, ToolBox *, void)
+{
+    OnDropdownClick(true);
+}
+
+void ToolBarManager::OnDropdownClick(bool bCreatePopupWindow)
 {
     SolarMutexGuard g;
 
     if ( m_bDisposed )
         return;
 
-    ToolBoxItemId nId( m_pToolBar->GetCurItemId() );
+    ToolBoxItemId nId( m_pImpl->GetCurItemId() );
     ToolBarControllerMap::const_iterator pIter = m_aControllerMap.find( nId );
     if ( pIter != m_aControllerMap.end() )
     {
@@ -1425,16 +1818,23 @@ IMPL_LINK_NOARG(ToolBarManager, DropdownClick, ToolBox *, void)
 
         if ( xController.is() )
         {
-            Reference< XWindow > xWin = xController->createPopupWindow();
-            if ( xWin.is() )
-                xWin->setFocus();
+            if (bCreatePopupWindow)
+            {
+                Reference< XWindow > xWin = xController->createPopupWindow();
+                if ( xWin.is() )
+                    xWin->setFocus();
+            }
+            else
+            {
+                xController->click();
+            }
         }
     }
 }
 
 IMPL_LINK_NOARG(ToolBarManager, DoubleClick, ToolBox *, void)
 {
-    HandleClick(&XToolbarController::doubleClick);
+    HandleClick(ClickAction::DblClick);
 }
 
 Reference< XModel > ToolBarManager::GetModelFromFrame() const
@@ -1467,6 +1867,9 @@ bool ToolBarManager::IsPluginMode() const
 
 void ToolBarManager::AddCustomizeMenuItems(ToolBox const * pToolBar)
 {
+    if (!m_pToolBar)
+        return;
+
     // No config menu entries if command ".uno:ConfigureDialog" is not enabled
     Reference< XDispatch > xDisp;
     css::util::URL aURL;
diff --git a/framework/source/uielement/toolbarwrapper.cxx b/framework/source/uielement/toolbarwrapper.cxx
index 1a701e286186..794b507cdee2 100644
--- a/framework/source/uielement/toolbarwrapper.cxx
+++ b/framework/source/uielement/toolbarwrapper.cxx
@@ -28,6 +28,7 @@
 
 #include <vcl/svapp.hxx>
 #include <vcl/toolbox.hxx>
+#include <vcl/weldutils.hxx>
 
 using namespace com::sun::star;
 using namespace com::sun::star::uno;
@@ -49,6 +50,9 @@ ToolBarWrapper::ToolBarWrapper( const Reference< XComponentContext >& rxContext
 
 ToolBarWrapper::~ToolBarWrapper()
 {
+    m_xWeldedToolbar.reset(nullptr);
+    m_xTopLevel.reset(nullptr);
+    m_xBuilder.reset(nullptr);
 }
 
 // XInterface
@@ -148,20 +152,34 @@ void SAL_CALL ToolBarWrapper::initialize( const Sequence< Any >& aArguments )
             m_xToolBarManager = pToolBarManager;
             pToolBar->WillUsePopupMode( bPopupMode );
         }
+        else if (weld::TransportAsXWindow* pTunnel = dynamic_cast<weld::TransportAsXWindow*>(xParentWindow.get()))
+        {
+            m_xBuilder.reset(Application::CreateBuilder(pTunnel->getWidget(), "modules/StartModule/ui/managedtoolbar.ui"));
+            m_xTopLevel = m_xBuilder->weld_container("toolbarcontainer");
+            m_xWeldedToolbar = m_xBuilder->weld_toolbar("managedtoolbar");
+            if ( m_xWeldedToolbar )
+            {
+                pToolBarManager = new ToolBarManager( m_xContext, xFrame, m_aResourceURL, m_xWeldedToolbar.get(), m_xBuilder.get() );
+                m_xToolBarManager = pToolBarManager;
+            }
+        }
     }
 
     try
     {
         m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, false );
-        if ( m_xConfigData.is() && pToolBar && pToolBarManager )
+        if ( m_xConfigData.is() && (pToolBar || m_xWeldedToolbar) && pToolBarManager )
         {
             // Fill toolbar with container contents
             pToolBarManager->FillToolbar( m_xConfigData );
-            pToolBar->EnableCustomize();
-            ::Size aActSize( pToolBar->GetSizePixel() );
-            ::Size aSize( pToolBar->CalcWindowSizePixel() );
-            aSize.setWidth( aActSize.Width() );
-            pToolBar->SetOutputSizePixel( aSize );
+            if (pToolBar)
+            {
+                pToolBar->EnableCustomize();
+                ::Size aActSize( pToolBar->GetSizePixel() );
+                ::Size aSize( pToolBar->CalcWindowSizePixel() );
+                aSize.setWidth( aActSize.Width() );
+                pToolBar->SetOutputSizePixel( aSize );
+            }
         }
     }
     catch ( const NoSuchElementException& )
diff --git a/framework/uiconfig/startmodule/ui/managedtoolbar.ui b/framework/uiconfig/startmodule/ui/managedtoolbar.ui
new file mode 100644
index 000000000000..5771eb8ac5f8
--- /dev/null
+++ b/framework/uiconfig/startmodule/ui/managedtoolbar.ui
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.4 -->
+<interface domain="sfx">
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkBox" id="toolbarcontainer">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="orientation">vertical</property>
+    <child>
+      <object class="GtkToolbar" id="managedtoolbar">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+      <packing>
+        <property name="expand">True</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/include/framework/sfxhelperfunctions.hxx b/include/framework/sfxhelperfunctions.hxx
index 4858960f7edf..c7575fa53caa 100644
--- a/include/framework/sfxhelperfunctions.hxx
+++ b/include/framework/sfxhelperfunctions.hxx
@@ -25,13 +25,17 @@
 #include <rtl/ref.hxx>
 #include <vcl/toolbox.hxx>
 
-namespace com::sun::star::frame { class XFrame; }
+namespace com::sun::star::frame { class XFrame; class XToolbarController; }
 namespace com::sun::star::uno { template <typename > class Reference; }
 namespace svt { class StatusbarController; }
 namespace svt { class ToolboxController; }
 
 class StatusBar;
 class ToolBox;
+namespace weld {
+    class Toolbar;
+    class Builder;
+};
 
 typedef rtl::Reference<svt::ToolboxController> ( *pfunc_setToolBoxControllerCreator)(
     const css::uno::Reference< css::frame::XFrame >& rFrame,
@@ -39,6 +43,12 @@ typedef rtl::Reference<svt::ToolboxController> ( *pfunc_setToolBoxControllerCrea
     ToolBoxItemId nID,
     const OUString& aCommandURL );
 
+typedef css::uno::Reference<css::frame::XToolbarController> ( *pfunc_setWeldToolBoxControllerCreator)(
+    const css::uno::Reference< css::frame::XFrame >& rFrame,
+    weld::Toolbar* pToolbar,
+    weld::Builder* pBuilder,
+    const OUString& aCommandURL );
+
 typedef rtl::Reference<svt::StatusbarController> ( *pfunc_setStatusBarControllerCreator)(
     const css::uno::Reference< css::frame::XFrame >& rFrame,
     StatusBar* pStatusBar,
@@ -66,6 +76,13 @@ FWK_DLLPUBLIC rtl::Reference<svt::ToolboxController> CreateToolBoxController(
     ToolBoxItemId nID,
     const OUString& aCommandURL );
 
+FWK_DLLPUBLIC pfunc_setWeldToolBoxControllerCreator SetWeldToolBoxControllerCreator( pfunc_setWeldToolBoxControllerCreator pSetToolBoxControllerCreator );
+FWK_DLLPUBLIC css::uno::Reference<css::frame::XToolbarController> CreateWeldToolBoxController(
+    const css::uno::Reference< css::frame::XFrame >& rFrame,
+    weld::Toolbar* pToolbar,
+    weld::Builder* pBuilder,
+    const OUString& aCommandURL );
+
 FWK_DLLPUBLIC pfunc_setStatusBarControllerCreator SetStatusBarControllerCreator( pfunc_setStatusBarControllerCreator pSetStatusBarControllerCreator );
 FWK_DLLPUBLIC rtl::Reference<svt::StatusbarController> CreateStatusBarController(
     const css::uno::Reference< css::frame::XFrame >& rFrame,
diff --git a/include/sfx2/tbxctrl.hxx b/include/sfx2/tbxctrl.hxx
index 7150d64adbcf..6de697a12197 100644
--- a/include/sfx2/tbxctrl.hxx
+++ b/include/sfx2/tbxctrl.hxx
@@ -31,6 +31,7 @@
 namespace com::sun::star::frame { class XDispatchProvider; }
 namespace com::sun::star::frame { class XFrame; }
 namespace vcl { class Window; }
+namespace com::sun::star::frame { class XToolbarController; }
 
 class InterimItemWindow;
 class SfxToolBoxControl;
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 46ae951f3b94..0ecea6e3fb54 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -2323,6 +2323,7 @@ public:
         = 0;
     virtual void set_item_image(const OString& rIdent, VirtualDevice* pDevice) = 0;
 
+    virtual void insert_item(int pos, const OUString& rId) = 0;
     virtual void insert_separator(int pos, const OUString& rId) = 0;
     void append_separator(const OUString& rId) { insert_separator(-1, rId); }
 
diff --git a/sfx2/source/appl/app.cxx b/sfx2/source/appl/app.cxx
index 227cae7f240b..78358b32fe22 100644
--- a/sfx2/source/appl/app.cxx
+++ b/sfx2/source/appl/app.cxx
@@ -49,6 +49,7 @@
 #include <sfx2/stbitem.hxx>
 #include <sfx2/dockwin.hxx>
 #include <shellimpl.hxx>
+#include <sidebar/ControllerFactory.hxx>
 
 #include <svtools/helpopt.hxx>
 #include <unotools/viewoptions.hxx>
@@ -93,6 +94,16 @@ SfxModule* SfxApplication::GetModule(SfxToolsModule nSharedLib)
     return g_pSfxApplication->pImpl->aModules[nSharedLib].get();
 }
 
+namespace {
+    css::uno::Reference<css::frame::XToolbarController> SfxWeldToolBoxControllerFactory( const css::uno::Reference< css::frame::XFrame >& rFrame, weld::Toolbar* pToolbar, weld::Builder* pBuilder, const OUString& aCommandURL )
+    {
+        SolarMutexGuard aGuard;
+
+        return sfx2::sidebar::ControllerFactory::CreateToolBoxController(
+                *pToolbar, *pBuilder, aCommandURL, rFrame, rFrame->getController(), false);
+    }
+}
+
 SfxApplication* SfxApplication::GetOrCreate()
 {
     // SFX on demand
@@ -110,6 +121,7 @@ SfxApplication* SfxApplication::GetOrCreate()
 
         ::framework::SetRefreshToolbars( RefreshToolbars );
         ::framework::SetToolBoxControllerCreator( SfxToolBoxControllerFactory );
+        ::framework::SetWeldToolBoxControllerCreator( SfxWeldToolBoxControllerFactory );
         ::framework::SetStatusBarControllerCreator( SfxStatusBarControllerFactory );
         ::framework::SetDockingWindowCreator( SfxDockingWindowFactory );
         ::framework::SetIsDockingWindowVisible( IsDockingWindowVisible );
diff --git a/sfx2/source/toolbox/tbxitem.cxx b/sfx2/source/toolbox/tbxitem.cxx
index f07aa2d82a86..2212494dc1d4 100644
--- a/sfx2/source/toolbox/tbxitem.cxx
+++ b/sfx2/source/toolbox/tbxitem.cxx
@@ -53,6 +53,7 @@
 #include <sfx2/viewfrm.hxx>
 #include <sfx2/module.hxx>
 #include <sfx2/app.hxx>
+#include <sidebar/ControllerFactory.hxx>
 #include <unoctitm.hxx>
 #include <ctrlfactoryimpl.hxx>
 
diff --git a/svtools/source/control/toolbarmenu.cxx b/svtools/source/control/toolbarmenu.cxx
index 4149afa4b7a7..949cd747b2a1 100644
--- a/svtools/source/control/toolbarmenu.cxx
+++ b/svtools/source/control/toolbarmenu.cxx
@@ -115,7 +115,7 @@ WeldToolbarPopup::WeldToolbarPopup(const css::uno::Reference<css::frame::XFrame>
                                    weld::Widget* pParent, const OUString& rUIFile,
                                    const OString& rId)
     : m_xBuilder(Application::CreateBuilder(pParent, rUIFile))
-    , m_xTopLevel(m_xBuilder->weld_container(rId))
+    , m_xTopLevel(m_xBuilder->weld_popover(rId))
     , m_xContainer(m_xBuilder->weld_container("container"))
     , m_xFrame(rFrame)
 {
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index 1afffdfe280d..60041654521f 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -1214,6 +1214,8 @@ public:
 
     virtual void set_item_menu(const OString& rIdent, weld::Menu* pMenu) override;
 
+    virtual void insert_item(int pos, const OUString& rId) override;
+
     virtual void insert_separator(int pos, const OUString& /*rId*/) override;
 
     virtual int get_n_items() const override;
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 656211e13cf3..b185c0f00836 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -971,6 +971,13 @@ void SalInstanceToolbar::set_item_menu(const OString& rIdent, weld::Menu* pMenu)
     m_aFloats[nId] = nullptr;
 }
 
+void SalInstanceToolbar::insert_item(int pos, const OUString& rId)
+{
+    ToolBoxItemId nId(pos);
+    m_xToolBox->InsertItem(nId, rId, ToolBoxItemBits::ICON_ONLY);
+    m_xToolBox->SetItemCommand(nId, rId);
+}
+
 void SalInstanceToolbar::insert_separator(int pos, const OUString& /*rId*/)
 {
     auto nInsertPos = pos == -1 ? ToolBox::APPEND : pos;
@@ -6644,6 +6651,8 @@ public:
     {
     }
 
+    ~SalInstancePopover() { signal_closed(); }
+
     virtual void popup_at_rect(weld::Widget* pParent, const tools::Rectangle& rRect) override
     {
         SalInstanceWidget* pVclWidget = dynamic_cast<SalInstanceWidget*>(pParent);
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 377ac47461de..10df2ee6e317 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -8783,10 +8783,21 @@ public:
         return aFind->second->get_active();
     }
 
+    virtual void insert_item(int pos, const OUString& rId) override
+    {
+        OString sId = OUStringToOString(rId, RTL_TEXTENCODING_UTF8);
+        GtkToolItem* pItem = gtk_tool_button_new(nullptr, sId.getStr());
+        gtk_buildable_set_name(GTK_BUILDABLE(pItem), sId.getStr());
+        gtk_toolbar_insert(m_pToolbar, pItem, pos);
+        gtk_widget_show(GTK_WIDGET(pItem));
+        add_to_map(pItem, nullptr);
+    }
+
     virtual void insert_separator(int pos, const OUString& rId) override
     {
+        OString sId = OUStringToOString(rId, RTL_TEXTENCODING_UTF8);
         GtkToolItem* pItem = gtk_separator_tool_item_new();
-        gtk_buildable_set_name(GTK_BUILDABLE(pItem), OUStringToOString(rId, RTL_TEXTENCODING_UTF8).getStr());
+        gtk_buildable_set_name(GTK_BUILDABLE(pItem), sId.getStr());
         gtk_toolbar_insert(m_pToolbar, pItem, pos);
         gtk_widget_show(GTK_WIDGET(pItem));
     }
@@ -16715,6 +16726,7 @@ public:
         if (m_pClosedEvent)
             Application::RemoveUserEvent(m_pClosedEvent);
         g_signal_handler_disconnect(m_pPopover, m_nSignalId);
+        signal_closed();
     }
 };
 


More information about the Libreoffice-commits mailing list