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