summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2020-01-09 15:45:46 +0000
committerCaolán McNamara <caolanm@redhat.com>2020-01-10 15:13:45 +0100
commit14e26096f0476b8ecb70511c304a0cdf5440ef7a (patch)
tree9aca765b2599b23ad5d88e37877c345c1a71c254
parent9b97efd4228489f2e54a948e676917e50902fd33 (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.hxx1
-rw-r--r--include/svtools/popupwindowcontroller.hxx6
-rw-r--r--include/svtools/toolbarmenu.hxx31
-rw-r--r--include/svx/ParaLineSpacingPopup.hxx1
-rw-r--r--include/svx/tbcontrl.hxx2
-rw-r--r--include/vcl/weld.hxx8
-rw-r--r--sfx2/source/toolbox/weldutils.cxx10
-rw-r--r--svtools/source/control/toolbarmenu.cxx48
-rw-r--r--svtools/source/uno/popupwindowcontroller.cxx27
-rw-r--r--svx/UIConfig_svx.mk1
-rw-r--r--svx/source/sidebar/paragraph/ParaLineSpacingControl.cxx4
-rw-r--r--svx/source/sidebar/paragraph/ParaLineSpacingControl.hxx2
-rw-r--r--svx/source/sidebar/paragraph/ParaLineSpacingPopup.cxx32
-rw-r--r--svx/source/tbxctrls/bulletsnumbering.cxx34
-rw-r--r--svx/source/tbxctrls/tbcontrl.cxx84
-rw-r--r--svx/uiconfig/ui/colorwindow.ui2
-rw-r--r--svx/uiconfig/ui/toolbarpopover.ui21
-rw-r--r--vcl/source/app/salvtables.cxx37
-rw-r--r--vcl/unx/gtk3/gtk3gtkinst.cxx20
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);
}
}