diff options
author | Caolán McNamara <caolanm@redhat.com> | 2020-01-09 15:45:46 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2020-01-10 15:13:45 +0100 |
commit | 14e26096f0476b8ecb70511c304a0cdf5440ef7a (patch) | |
tree | 9aca765b2599b23ad5d88e37877c345c1a71c254 | |
parent | 9b97efd4228489f2e54a948e676917e50902fd33 (diff) |
make welded toolbars on-demand that were previously on-demand
Change-Id: I795723260deb317093e83d951d968e0b3d3a1850
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86531
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r-- | include/sfx2/weldutils.hxx | 1 | ||||
-rw-r--r-- | include/svtools/popupwindowcontroller.hxx | 6 | ||||
-rw-r--r-- | include/svtools/toolbarmenu.hxx | 31 | ||||
-rw-r--r-- | include/svx/ParaLineSpacingPopup.hxx | 1 | ||||
-rw-r--r-- | include/svx/tbcontrl.hxx | 2 | ||||
-rw-r--r-- | include/vcl/weld.hxx | 8 | ||||
-rw-r--r-- | sfx2/source/toolbox/weldutils.cxx | 10 | ||||
-rw-r--r-- | svtools/source/control/toolbarmenu.cxx | 48 | ||||
-rw-r--r-- | svtools/source/uno/popupwindowcontroller.cxx | 27 | ||||
-rw-r--r-- | svx/UIConfig_svx.mk | 1 | ||||
-rw-r--r-- | svx/source/sidebar/paragraph/ParaLineSpacingControl.cxx | 4 | ||||
-rw-r--r-- | svx/source/sidebar/paragraph/ParaLineSpacingControl.hxx | 2 | ||||
-rw-r--r-- | svx/source/sidebar/paragraph/ParaLineSpacingPopup.cxx | 32 | ||||
-rw-r--r-- | svx/source/tbxctrls/bulletsnumbering.cxx | 34 | ||||
-rw-r--r-- | svx/source/tbxctrls/tbcontrl.cxx | 84 | ||||
-rw-r--r-- | svx/uiconfig/ui/colorwindow.ui | 2 | ||||
-rw-r--r-- | svx/uiconfig/ui/toolbarpopover.ui | 21 | ||||
-rw-r--r-- | vcl/source/app/salvtables.cxx | 37 | ||||
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkinst.cxx | 20 |
19 files changed, 267 insertions, 104 deletions
diff --git a/include/sfx2/weldutils.hxx b/include/sfx2/weldutils.hxx index cfcf545d9002..2486ca97307e 100644 --- a/include/sfx2/weldutils.hxx +++ b/include/sfx2/weldutils.hxx @@ -33,6 +33,7 @@ private: weld::Toolbar* m_pToolbar; DECL_LINK(SelectHdl, const OString&, void); + DECL_LINK(ToggleMenuHdl, const OString&, void); void CreateController(const OUString& rCommand); diff --git a/include/svtools/popupwindowcontroller.hxx b/include/svtools/popupwindowcontroller.hxx index be39cc8e2b69..f1df441a4979 100644 --- a/include/svtools/popupwindowcontroller.hxx +++ b/include/svtools/popupwindowcontroller.hxx @@ -33,6 +33,7 @@ namespace vcl { class Window; } class InterimToolbarPopup; +class ToolbarPopupContainer; class WeldToolbarPopup; namespace svt @@ -46,11 +47,13 @@ public: PopupWindowController( const css::uno::Reference< css::uno::XComponentContext >& rxContext, const css::uno::Reference< css::frame::XFrame >& xFrame, const OUString& aCommandURL ); + virtual ~PopupWindowController() override; void EndPopupMode(); virtual VclPtr<vcl::Window> createPopupWindow( vcl::Window* pParent ) = 0; + virtual std::unique_ptr<WeldToolbarPopup> weldPopupWindow(); // XServiceInfo virtual OUString SAL_CALL getImplementationName() override = 0; @@ -65,9 +68,10 @@ public: // XToolbarController virtual css::uno::Reference< css::awt::XWindow > SAL_CALL createPopupWindow() override; + virtual void SAL_CALL click() override; protected: - std::unique_ptr<WeldToolbarPopup> mxPopover; + std::unique_ptr<ToolbarPopupContainer> mxPopoverContainer; VclPtr<InterimToolbarPopup> mxInterimPopover; private: diff --git a/include/svtools/toolbarmenu.hxx b/include/svtools/toolbarmenu.hxx index 1ff5079e569a..f06611817797 100644 --- a/include/svtools/toolbarmenu.hxx +++ b/include/svtools/toolbarmenu.hxx @@ -173,16 +173,41 @@ public: virtual void GrabFocus() = 0; }; +// we want to create WeldToolbarPopup on-demand when a toolbar dropdown is +// clicked, but the widget to be shown must exist before the dropdown +// is activated, so ToolbarPopupContainer is that widget and the +// contents of the on-demand created WeldToolbarPopup is placed +// within the ToolbarPopupContainer +class SVT_DLLPUBLIC ToolbarPopupContainer +{ +private: + DECL_LINK(FocusHdl, weld::Widget&, void); + +protected: + std::unique_ptr<weld::Builder> m_xBuilder; + std::unique_ptr<weld::Container> m_xTopLevel; + std::unique_ptr<weld::Container> m_xContainer; + std::unique_ptr<WeldToolbarPopup> m_xPopup; +public: + ToolbarPopupContainer(weld::Widget* pParent); + ~ToolbarPopupContainer(); + weld::Container* getTopLevel() { return m_xTopLevel.get(); } + weld::Container* getContainer() { return m_xContainer.get(); } + + void setPopover(std::unique_ptr<WeldToolbarPopup> xPopup); + void unsetPopover(); +}; + class SVT_DLLPUBLIC InterimToolbarPopup : public svtools::ToolbarPopup { protected: VclPtr<vcl::Window> m_xBox; std::unique_ptr<weld::Builder> m_xBuilder; std::unique_ptr<weld::Container> m_xContainer; - - WeldToolbarPopup* m_pPopup; + std::unique_ptr<WeldToolbarPopup> m_xPopup; public: - InterimToolbarPopup(const css::uno::Reference<css::frame::XFrame>& rFrame, vcl::Window* pParent, WeldToolbarPopup* pPopup); + InterimToolbarPopup(const css::uno::Reference<css::frame::XFrame>& rFrame, vcl::Window* pParent, + std::unique_ptr<WeldToolbarPopup> xPopup); weld::Container* getContainer() { return m_xContainer.get(); } virtual void dispose() override; virtual ~InterimToolbarPopup() override; diff --git a/include/svx/ParaLineSpacingPopup.hxx b/include/svx/ParaLineSpacingPopup.hxx index 743894ce31e0..4d22cdc8bd2c 100644 --- a/include/svx/ParaLineSpacingPopup.hxx +++ b/include/svx/ParaLineSpacingPopup.hxx @@ -34,6 +34,7 @@ public: using svt::ToolboxController::createPopupWindow; virtual VclPtr<vcl::Window> createPopupWindow( vcl::Window* pParent ) override; + virtual std::unique_ptr<WeldToolbarPopup> weldPopupWindow() override; // XServiceInfo virtual OUString SAL_CALL getImplementationName() override; diff --git a/include/svx/tbcontrl.hxx b/include/svx/tbcontrl.hxx index 226160e422c0..e812ce4685d8 100644 --- a/include/svx/tbcontrl.hxx +++ b/include/svx/tbcontrl.hxx @@ -231,6 +231,7 @@ public: using svt::ToolboxController::createPopupWindow; virtual VclPtr<vcl::Window> createPopupWindow( vcl::Window* pParent ) override; + virtual std::unique_ptr<WeldToolbarPopup> weldPopupWindow() override; // XSubToolbarController virtual sal_Bool SAL_CALL opensSubToolbar() override; @@ -279,6 +280,7 @@ public: using svt::ToolboxController::createPopupWindow; virtual VclPtr<vcl::Window> createPopupWindow( vcl::Window* pParent ) override; + virtual std::unique_ptr<WeldToolbarPopup> weldPopupWindow() override; // XServiceInfo virtual OUString SAL_CALL getImplementationName() override; diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx index e205ea2459c6..6d99c3516589 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -1956,10 +1956,10 @@ class VCL_DLLPUBLIC Toolbar : virtual public Widget { protected: Link<const OString&, void> m_aClickHdl; - Link<const OString&, void> m_aShowMenuHdl; + Link<const OString&, void> m_aToggleMenuHdl; void signal_clicked(const OString& rIdent) { m_aClickHdl.Call(rIdent); } - void signal_show_menu(const OString& rIdent) { m_aShowMenuHdl.Call(rIdent); } + void signal_toggle_menu(const OString& rIdent) { m_aToggleMenuHdl.Call(rIdent); } public: virtual void set_item_sensitive(const OString& rIdent, bool bSensitive) = 0; @@ -1997,9 +1997,7 @@ public: virtual vcl::ImageType get_icon_size() const = 0; void connect_clicked(const Link<const OString&, void>& rLink) { m_aClickHdl = rLink; } - // m_aShowMenuHdl is called before the menu is shown. - // It can be used to populate the menu on demand with set_item_popover/set_item_menu - void connect_show_menu(const Link<const OString&, void>& rLink) { m_aShowMenuHdl = rLink; } + void connect_menu_toggled(const Link<const OString&, void>& rLink) { m_aToggleMenuHdl = rLink; } }; class VCL_DLLPUBLIC SizeGroup diff --git a/sfx2/source/toolbox/weldutils.cxx b/sfx2/source/toolbox/weldutils.cxx index 52cf254d7b9a..112f285297c5 100644 --- a/sfx2/source/toolbox/weldutils.cxx +++ b/sfx2/source/toolbox/weldutils.cxx @@ -58,6 +58,7 @@ ToolbarUnoDispatcher::ToolbarUnoDispatcher(weld::Toolbar& rToolbar, , m_pToolbar(&rToolbar) { rToolbar.connect_clicked(LINK(this, ToolbarUnoDispatcher, SelectHdl)); + rToolbar.connect_menu_toggled(LINK(this, ToolbarUnoDispatcher, ToggleMenuHdl)); OUString aModuleName(vcl::CommandInfoProvider::GetModuleIdentifier(rFrame)); vcl::ImageType eSize = rToolbar.get_icon_size(); @@ -111,6 +112,15 @@ IMPL_LINK(ToolbarUnoDispatcher, SelectHdl, const OString&, rCommand, void) xController->execute(0); } +IMPL_LINK(ToolbarUnoDispatcher, ToggleMenuHdl, const OString&, rCommand, void) +{ + css::uno::Reference<css::frame::XToolbarController> xController( + GetControllerForCommand(OUString::fromUtf8(rCommand))); + + if (xController.is()) + xController->click(); +} + void ToolbarUnoDispatcher::dispose() { if (!m_pToolbar) diff --git a/svtools/source/control/toolbarmenu.cxx b/svtools/source/control/toolbarmenu.cxx index 7b12d910a81e..7d74380a2d10 100644 --- a/svtools/source/control/toolbarmenu.cxx +++ b/svtools/source/control/toolbarmenu.cxx @@ -1537,27 +1537,65 @@ IMPL_LINK_NOARG(WeldToolbarPopup, FocusHdl, weld::Widget&, void) GrabFocus(); } -InterimToolbarPopup::InterimToolbarPopup(const css::uno::Reference<css::frame::XFrame>& rFrame, vcl::Window* pParent, WeldToolbarPopup* pPopup) +ToolbarPopupContainer::ToolbarPopupContainer(weld::Widget* pParent) + : m_xBuilder(Application::CreateBuilder(pParent, "svx/ui/toolbarpopover.ui")) + , m_xTopLevel(m_xBuilder->weld_container("ToolbarPopover")) + , m_xContainer(m_xBuilder->weld_container("container")) +{ + m_xTopLevel->connect_focus_in(LINK(this, ToolbarPopupContainer, FocusHdl)); +} + +void ToolbarPopupContainer::setPopover(std::unique_ptr<WeldToolbarPopup> xPopup) +{ + m_xPopup = std::move(xPopup); + // move the WeldToolbarPopup contents into this toolbar so on-demand contents can appear inside a preexisting gtk popover + // because the arrow for the popover is only enabled if there's a popover set + m_xPopup->getTopLevel()->move(m_xPopup->getContainer(), m_xContainer.get()); + m_xPopup->GrabFocus(); +} + +void ToolbarPopupContainer::unsetPopover() +{ + if (!m_xPopup) + return; + m_xContainer->move(m_xPopup->getContainer(), m_xPopup->getTopLevel()); + m_xPopup.reset(); +} + +ToolbarPopupContainer::~ToolbarPopupContainer() +{ + unsetPopover(); +} + +IMPL_LINK_NOARG(ToolbarPopupContainer, FocusHdl, weld::Widget&, void) +{ + if (m_xPopup) + m_xPopup->GrabFocus(); +} + +InterimToolbarPopup::InterimToolbarPopup(const css::uno::Reference<css::frame::XFrame>& rFrame, vcl::Window* pParent, + std::unique_ptr<WeldToolbarPopup> xPopup) : ToolbarPopup(rFrame, pParent, "InterimDockParent", "svx/ui/interimdockparent.ui") , m_xBox(get<vcl::Window>("box")) , m_xBuilder(Application::CreateInterimBuilder(m_xBox.get(), "svx/ui/interimparent.ui")) , m_xContainer(m_xBuilder->weld_container("container")) - , m_pPopup(pPopup) + , m_xPopup(std::move(xPopup)) { // move the WeldToolbarPopup contents into this interim toolbar so welded contents can appear as a dropdown in an unwelded toolbar - m_pPopup->getTopLevel()->move(m_pPopup->getContainer(), m_xContainer.get()); + m_xPopup->getTopLevel()->move(m_xPopup->getContainer(), m_xContainer.get()); } void InterimToolbarPopup::GetFocus() { ToolbarPopup::GetFocus(); - m_pPopup->GrabFocus(); + m_xPopup->GrabFocus(); } void InterimToolbarPopup::dispose() { // move the contents back where it belongs - m_xContainer->move(m_pPopup->getContainer(), m_pPopup->getTopLevel()); + m_xContainer->move(m_xPopup->getContainer(), m_xPopup->getTopLevel()); + m_xPopup.reset(); m_xContainer.reset(); m_xBox.clear(); ToolbarPopup::dispose(); diff --git a/svtools/source/uno/popupwindowcontroller.cxx b/svtools/source/uno/popupwindowcontroller.cxx index 7b1e3357424d..50135adbe453 100644 --- a/svtools/source/uno/popupwindowcontroller.cxx +++ b/svtools/source/uno/popupwindowcontroller.cxx @@ -177,7 +177,7 @@ sal_Bool SAL_CALL PopupWindowController::supportsService( const OUString& Servic void SAL_CALL PopupWindowController::dispose() { mxInterimPopover.clear(); - mxPopover.reset(); + mxPopoverContainer.reset(); mxImpl.reset(); svt::ToolboxController::dispose(); } @@ -207,8 +207,20 @@ void SAL_CALL PopupWindowController::statusChanged( const frame::FeatureStateEve } } +std::unique_ptr<WeldToolbarPopup> PopupWindowController::weldPopupWindow() +{ + return nullptr; +} + Reference< awt::XWindow > SAL_CALL PopupWindowController::createPopupWindow() { + if (m_pToolbar) + { + mxPopoverContainer->unsetPopover(); + mxPopoverContainer->setPopover(weldPopupWindow()); + return Reference<awt::XWindow>(); + } + VclPtr< ToolBox > pToolBox = dynamic_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ).get() ); if( pToolBox ) { @@ -237,6 +249,19 @@ Reference< awt::XWindow > SAL_CALL PopupWindowController::createPopupWindow() return Reference< awt::XWindow >(); } +void SAL_CALL PopupWindowController::click() +{ + if (m_pToolbar) + { + if (m_pToolbar->get_menu_item_active(m_aCommandURL.toUtf8())) + createPopupWindow(); + else + mxPopoverContainer->unsetPopover(); + } + + svt::ToolboxController::click(); +} + void PopupWindowController::EndPopupMode() { if (m_pToolbar) diff --git a/svx/UIConfig_svx.mk b/svx/UIConfig_svx.mk index 070e52ade41f..f81460e52571 100644 --- a/svx/UIConfig_svx.mk +++ b/svx/UIConfig_svx.mk @@ -106,6 +106,7 @@ $(eval $(call gb_UIConfig_add_uifiles,svx,\ svx/uiconfig/ui/textcontrolchardialog \ svx/uiconfig/ui/textcontrolparadialog \ svx/uiconfig/ui/textunderlinecontrol \ + svx/uiconfig/ui/toolbarpopover \ svx/uiconfig/ui/xmlsecstatmenu \ svx/uiconfig/ui/xformspage \ svx/uiconfig/ui/zoommenu \ diff --git a/svx/source/sidebar/paragraph/ParaLineSpacingControl.cxx b/svx/source/sidebar/paragraph/ParaLineSpacingControl.cxx index 6a7b7b578222..93ced9fece15 100644 --- a/svx/source/sidebar/paragraph/ParaLineSpacingControl.cxx +++ b/svx/source/sidebar/paragraph/ParaLineSpacingControl.cxx @@ -94,7 +94,7 @@ ParaLineSpacingControl::ParaLineSpacingControl(SvxLineSpacingToolBoxControl* pCo SetFieldUnit(*mxLineDistAtMetricBox, eUnit); - SyncFromDocument(); + Initialize(); } void ParaLineSpacingControl::GrabFocus() @@ -106,7 +106,7 @@ ParaLineSpacingControl::~ParaLineSpacingControl() { } -void ParaLineSpacingControl::SyncFromDocument() +void ParaLineSpacingControl::Initialize() { const SfxPoolItem* pItem(nullptr); SfxViewFrame* pCurrent = SfxViewFrame::Current(); diff --git a/svx/source/sidebar/paragraph/ParaLineSpacingControl.hxx b/svx/source/sidebar/paragraph/ParaLineSpacingControl.hxx index 6d999159212f..3f5c12f8ca21 100644 --- a/svx/source/sidebar/paragraph/ParaLineSpacingControl.hxx +++ b/svx/source/sidebar/paragraph/ParaLineSpacingControl.hxx @@ -35,7 +35,7 @@ public: virtual ~ParaLineSpacingControl() override; /// Setup the widgets with values from the document. - void SyncFromDocument(); + void Initialize(); virtual void GrabFocus() override; diff --git a/svx/source/sidebar/paragraph/ParaLineSpacingPopup.cxx b/svx/source/sidebar/paragraph/ParaLineSpacingPopup.cxx index 90099ac75511..470e5eb7e3fd 100644 --- a/svx/source/sidebar/paragraph/ParaLineSpacingPopup.cxx +++ b/svx/source/sidebar/paragraph/ParaLineSpacingPopup.cxx @@ -37,24 +37,16 @@ void SvxLineSpacingToolBoxControl::initialize( const css::uno::Sequence< css::un { PopupWindowController::initialize(rArguments); + if (m_pToolbar) + { + mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar)); + m_pToolbar->set_item_popover(m_aCommandURL.toUtf8(), mxPopoverContainer->getTopLevel()); + } + ToolBox* pToolBox = nullptr; sal_uInt16 nId = 0; - bool bVcl = getToolboxId(nId, &pToolBox); - - weld::Widget* pParent; - if (pToolBox) - pParent = pToolBox->GetFrameWeld(); - else - pParent = m_pToolbar; - mxPopover = std::make_unique<ParaLineSpacingControl>(this, pParent); - - if (bVcl && pToolBox->GetItemCommand(nId) == m_aCommandURL) + if (getToolboxId(nId, &pToolBox) && pToolBox->GetItemCommand(nId) == m_aCommandURL) pToolBox->SetItemBits(nId, ToolBoxItemBits::DROPDOWNONLY | pToolBox->GetItemBits(nId)); - else if (m_pToolbar) - { - const OString aId(m_aCommandURL.toUtf8()); - m_pToolbar->set_item_popover(aId, mxPopover->getTopLevel()); - } } void SAL_CALL SvxLineSpacingToolBoxControl::execute(sal_Int16 /*KeyModifier*/) @@ -72,11 +64,15 @@ void SAL_CALL SvxLineSpacingToolBoxControl::execute(sal_Int16 /*KeyModifier*/) } } -VclPtr<vcl::Window> SvxLineSpacingToolBoxControl::createPopupWindow( vcl::Window* pParent ) +std::unique_ptr<WeldToolbarPopup> SvxLineSpacingToolBoxControl::weldPopupWindow() { - dynamic_cast<ParaLineSpacingControl&>(*mxPopover).SyncFromDocument(); + return std::make_unique<ParaLineSpacingControl>(this, m_pToolbar); +} - mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent, mxPopover.get()); +VclPtr<vcl::Window> SvxLineSpacingToolBoxControl::createPopupWindow( vcl::Window* pParent ) +{ + mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent, + std::make_unique<ParaLineSpacingControl>(this, pParent->GetFrameWeld())); mxInterimPopover->Show(); diff --git a/svx/source/tbxctrls/bulletsnumbering.cxx b/svx/source/tbxctrls/bulletsnumbering.cxx index d33f790a5250..ba63a41b8838 100644 --- a/svx/source/tbxctrls/bulletsnumbering.cxx +++ b/svx/source/tbxctrls/bulletsnumbering.cxx @@ -53,6 +53,7 @@ class NumberingToolBoxControl : public svt::PopupWindowController public: explicit NumberingToolBoxControl( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); virtual VclPtr<vcl::Window> createPopupWindow( vcl::Window* pParent ) override; + std::unique_ptr<WeldToolbarPopup> weldPopupWindow() override; // XInitialization virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override; @@ -185,9 +186,15 @@ NumberingToolBoxControl::NumberingToolBoxControl( const css::uno::Reference< css { } +std::unique_ptr<WeldToolbarPopup> NumberingToolBoxControl::weldPopupWindow() +{ + return std::make_unique<NumberingPopup>(*this, m_pToolbar, mePageType); +} + VclPtr<vcl::Window> NumberingToolBoxControl::createPopupWindow( vcl::Window* pParent ) { - mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent, mxPopover.get()); + mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent, + std::make_unique<NumberingPopup>(*this, pParent->GetFrameWeld(), mePageType)); mxInterimPopover->Show(); @@ -203,24 +210,19 @@ void SAL_CALL NumberingToolBoxControl::initialize( const css::uno::Sequence< css else if ( m_aCommandURL == ".uno:SetOutline" ) mePageType = NumberingPageType::OUTLINE; - ToolBoxItemBits nBits = ( mePageType == NumberingPageType::OUTLINE ) ? ToolBoxItemBits::DROPDOWNONLY : ToolBoxItemBits::DROPDOWN; + if (m_pToolbar) + { + mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar)); + m_pToolbar->set_item_popover(m_aCommandURL.toUtf8(), mxPopoverContainer->getTopLevel()); + return; + } + ToolBox* pToolBox = nullptr; sal_uInt16 nId = 0; - bool bVcl = getToolboxId(nId, &pToolBox); - - weld::Widget* pParent; - if (pToolBox) - pParent = pToolBox->GetFrameWeld(); - else - pParent = m_pToolbar; - mxPopover = std::make_unique<NumberingPopup>(*this, pParent, mePageType); - - if (bVcl) - pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | nBits ); - else if (m_pToolbar) + if (getToolboxId(nId, &pToolBox)) { - const OString aId(m_aCommandURL.toUtf8()); - m_pToolbar->set_item_popover(aId, mxPopover->getTopLevel()); + ToolBoxItemBits nBits = ( mePageType == NumberingPageType::OUTLINE ) ? ToolBoxItemBits::DROPDOWNONLY : ToolBoxItemBits::DROPDOWN; + pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | nBits ); } } diff --git a/svx/source/tbxctrls/tbcontrl.cxx b/svx/source/tbxctrls/tbcontrl.cxx index 322bf970b54e..2f11f9f34aa0 100644 --- a/svx/source/tbxctrls/tbcontrl.cxx +++ b/svx/source/tbxctrls/tbcontrl.cxx @@ -3378,32 +3378,12 @@ void SvxColorToolBoxControl::initialize( const css::uno::Sequence<css::uno::Any> auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(getCommandURL(), getModuleName()); OUString aCommandLabel = vcl::CommandInfoProvider::GetLabelForCommand(aProperties); + OString aId(m_aCommandURL.toUtf8()); + if (m_pToolbar) { - EnsurePaletteManager(); - - const css::uno::Reference<css::awt::XWindow> xParent = m_xFrame->getContainerWindow(); - weld::Window* pParentFrame = Application::GetFrameWeld(xParent); - - const OString aId(m_aCommandURL.toUtf8()); - - auto xPopover = std::make_unique<ColorWindow>( - m_aCommandURL, - m_xPaletteManager, - m_aColorStatus, - m_nSlotId, - m_xFrame, - pParentFrame, - MenuOrToolMenuButton(m_pToolbar, aId), - m_aColorSelectFunction); - - if ( m_bSplitButton ) - xPopover->SetSelectedHdl( LINK( this, SvxColorToolBoxControl, SelectedHdl ) ); - - mxPopover = std::move(xPopover); - - m_pToolbar->set_item_popover(aId, mxPopover->getTopLevel()); - + mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar)); + m_pToolbar->set_item_popover(aId, mxPopoverContainer->getTopLevel()); m_xBtnUpdater.reset(new svx::ToolboxButtonColorUpdater(m_nSlotId, aId, m_pToolbar, !m_bSplitButton, aCommandLabel, m_xFrame)); return; } @@ -3460,6 +3440,31 @@ void SvxColorToolBoxControl::setColorSelectFunction(const ColorSelectFunction& a m_xPaletteManager->SetColorSelectFunction(aColorSelectFunction); } +std::unique_ptr<WeldToolbarPopup> SvxColorToolBoxControl::weldPopupWindow() +{ + EnsurePaletteManager(); + + const css::uno::Reference<css::awt::XWindow> xParent = m_xFrame->getContainerWindow(); + weld::Window* pParentFrame = Application::GetFrameWeld(xParent); + + const OString aId(m_aCommandURL.toUtf8()); + + auto xPopover = std::make_unique<ColorWindow>( + m_aCommandURL, + m_xPaletteManager, + m_aColorStatus, + m_nSlotId, + m_xFrame, + pParentFrame, + MenuOrToolMenuButton(m_pToolbar, aId), + m_aColorSelectFunction); + + if ( m_bSplitButton ) + xPopover->SetSelectedHdl( LINK( this, SvxColorToolBoxControl, SelectedHdl ) ); + + return xPopover; +} + VclPtr<vcl::Window> SvxColorToolBoxControl::createPopupWindow( vcl::Window* pParent ) { EnsurePaletteManager(); @@ -3819,29 +3824,28 @@ void SvxCurrencyToolBoxControl::initialize( const css::uno::Sequence< css::uno:: { PopupWindowController::initialize(rArguments); + if (m_pToolbar) + { + mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar)); + m_pToolbar->set_item_popover(m_aCommandURL.toUtf8(), mxPopoverContainer->getTopLevel()); + return; + } + ToolBox* pToolBox = nullptr; sal_uInt16 nId = 0; - bool bVcl = getToolboxId(nId, &pToolBox); - - weld::Widget* pParent; - if (pToolBox) - pParent = pToolBox->GetFrameWeld(); - else - pParent = m_pToolbar; - mxPopover = std::make_unique<SvxCurrencyList_Impl>(this, pParent, m_aFormatString, m_eLanguage); - - if (bVcl && pToolBox->GetItemCommand(nId) == m_aCommandURL) + if (getToolboxId(nId, &pToolBox) && pToolBox->GetItemCommand(nId) == m_aCommandURL) pToolBox->SetItemBits(nId, ToolBoxItemBits::DROPDOWN | pToolBox->GetItemBits(nId)); - else if (m_pToolbar) - { - const OString aId(m_aCommandURL.toUtf8()); - m_pToolbar->set_item_popover(aId, mxPopover->getTopLevel()); - } +} + +std::unique_ptr<WeldToolbarPopup> SvxCurrencyToolBoxControl::weldPopupWindow() +{ + return std::make_unique<SvxCurrencyList_Impl>(this, m_pToolbar, m_aFormatString, m_eLanguage); } VclPtr<vcl::Window> SvxCurrencyToolBoxControl::createPopupWindow( vcl::Window* pParent ) { - mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent, mxPopover.get()); + mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent, + std::make_unique<SvxCurrencyList_Impl>(this, pParent->GetFrameWeld(), m_aFormatString, m_eLanguage)); mxInterimPopover->Show(); diff --git a/svx/uiconfig/ui/colorwindow.ui b/svx/uiconfig/ui/colorwindow.ui index 853ce6831900..23f53b866543 100644 --- a/svx/uiconfig/ui/colorwindow.ui +++ b/svx/uiconfig/ui/colorwindow.ui @@ -25,7 +25,7 @@ <property name="no_show_all">True</property> <property name="border_width">4</property> <child> - <object class="GtkBox" id="box1"> + <object class="GtkBox" id="container"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="orientation">vertical</property> diff --git a/svx/uiconfig/ui/toolbarpopover.ui b/svx/uiconfig/ui/toolbarpopover.ui new file mode 100644 index 000000000000..828bc6e9dc1c --- /dev/null +++ b/svx/uiconfig/ui/toolbarpopover.ui @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.22.1 --> +<interface domain="svx"> + <requires lib="gtk+" version="3.18"/> + <object class="GtkPopover" id="ToolbarPopover"> + <property name="can_focus">False</property> + <property name="no_show_all">True</property> + <property name="border_width">4</property> + <child> + <object class="GtkBox" id="container"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <child> + <placeholder/> + </child> + </object> + </child> + </object> +</interface> diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 3ef767cb13fe..0dd8825754dc 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -950,8 +950,11 @@ private: std::map<sal_uInt16, VclPtr<vcl::Window>> m_aFloats; std::map<sal_uInt16, VclPtr<PopupMenu>> m_aMenus; + OString m_sStartShowIdent; + DECL_LINK(ClickHdl, ToolBox*, void); DECL_LINK(DropdownClick, ToolBox*, void); + DECL_LINK(MenuToggleListener, VclWindowEvent&, void); public: SalInstanceToolbar(ToolBox* pToolBox, SalInstanceBuilder* pBuilder, bool bTakeOwnership) @@ -1024,6 +1027,9 @@ public: sal_uInt16 nItemId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)); assert (m_xToolBox->GetItemBits(nItemId) & ToolBoxItemBits::DROPDOWN); + if (rIdent == m_sStartShowIdent) + return true; + auto aFloat = m_aFloats.find(nItemId); if (aFloat != m_aFloats.end()) { @@ -1045,9 +1051,17 @@ public: vcl::Window* pFloat = pPopoverWidget ? pPopoverWidget->getWidget() : nullptr; if (pFloat) + { + pFloat->AddEventListener(LINK(this, SalInstanceToolbar, MenuToggleListener)); pFloat->EnableDocking(); + } sal_uInt16 nId = m_xToolBox->GetItemId(OUString::fromUtf8(rIdent)); + auto xOldFloat = m_aFloats[nId]; + if (xOldFloat) + { + xOldFloat->RemoveEventListener(LINK(this, SalInstanceToolbar, MenuToggleListener)); + } m_aFloats[nId] = pFloat; m_aMenus[nId] = nullptr; } @@ -1161,9 +1175,26 @@ IMPL_LINK_NOARG(SalInstanceToolbar, DropdownClick, ToolBox*, void) { sal_uInt16 nItemId = m_xToolBox->GetCurItemId(); - OString sIdent = m_xToolBox->GetItemCommand(nItemId).toUtf8(); - signal_show_menu(sIdent); - set_menu_item_active(sIdent, true); + m_sStartShowIdent = m_xToolBox->GetItemCommand(nItemId).toUtf8(); + signal_toggle_menu(m_sStartShowIdent); + set_menu_item_active(m_sStartShowIdent, true); + m_sStartShowIdent.clear(); +} + +IMPL_LINK(SalInstanceToolbar, MenuToggleListener, VclWindowEvent&, rEvent, void) +{ + if (rEvent.GetId() == VclEventId::WindowEndPopupMode) + { + for (auto& rFloat : m_aFloats) + { + if (rEvent.GetWindow() == rFloat.second) + { + sal_uInt16 nItemId = rFloat.first; + signal_toggle_menu(m_xToolBox->GetItemCommand(nItemId).toUtf8()); + break; + } + } + } } namespace { diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx index bc53e4cf3cce..d52fb782df6a 100644 --- a/vcl/unx/gtk3/gtk3gtkinst.cxx +++ b/vcl/unx/gtk3/gtk3gtkinst.cxx @@ -7118,7 +7118,7 @@ private: if (pMenuButton) { m_aMenuButtonMap[id] = std::make_unique<GtkInstanceMenuButton>(pMenuButton, m_pBuilder, false); - g_signal_connect(pToolItem, "show-menu", G_CALLBACK(signalItemShowMenu), this); + g_signal_connect(pMenuButton, "toggled", G_CALLBACK(signalItemToggled), this); } g_signal_connect(pToolItem, "clicked", G_CALLBACK(signalItemClicked), this); } @@ -7136,17 +7136,23 @@ private: signal_clicked(OString(pStr, pStr ? strlen(pStr) : 0)); } - static void signalItemShowMenu(GtkMenuToolButton* pItem, gpointer widget) + static void signalItemToggled(GtkToggleButton* pItem, gpointer widget) { GtkInstanceToolbar* pThis = static_cast<GtkInstanceToolbar*>(widget); SolarMutexGuard aGuard; - pThis->signal_item_show_menu(pItem); + pThis->signal_item_toggled(pItem); } - void signal_item_show_menu(GtkMenuToolButton* pItem) + void signal_item_toggled(GtkToggleButton* pItem) { - const gchar* pStr = gtk_buildable_get_name(GTK_BUILDABLE(pItem)); - signal_show_menu(OString(pStr, pStr ? strlen(pStr) : 0)); + for (auto& a : m_aMenuButtonMap) + { + if (a.second->getWidget() == GTK_WIDGET(pItem)) + { + signal_toggle_menu(a.first); + break; + } + } } static void set_item_image(GtkToolButton* pItem, const css::uno::Reference<css::graphic::XGraphic>& rIcon) @@ -7189,7 +7195,6 @@ public: for (auto& a : m_aMap) { g_signal_handlers_block_by_func(a.second, reinterpret_cast<void*>(signalItemClicked), this); - g_signal_handlers_block_by_func(a.second, reinterpret_cast<void*>(signalItemShowMenu), this); } } @@ -7197,7 +7202,6 @@ public: { for (auto& a : m_aMap) { - g_signal_handlers_unblock_by_func(a.second, reinterpret_cast<void*>(signalItemShowMenu), this); g_signal_handlers_unblock_by_func(a.second, reinterpret_cast<void*>(signalItemClicked), this); } } |