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>
diff --git a/include/sfx2/weldutils.hxx b/include/sfx2/weldutils.hxx
index cfcf545..2486ca9 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 be39cc8..f1df441 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 1ff5079..f066118 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 743894c..4d22cdc 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 226160e..e812ce4 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 e205ea2..6d99c35 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 52cf254..112f285 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 7b12d91..7d74380 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 7b1e335..50135ad 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 070e52ad..f81460e 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 6a7b7b5..93ced9f 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 6d99915..3f5c12f 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 90099ac7..470e5eb 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*/)
}
}
std::unique_ptr<WeldToolbarPopup> SvxLineSpacingToolBoxControl::weldPopupWindow()
{
return std::make_unique<ParaLineSpacingControl>(this, m_pToolbar);
}
VclPtr<vcl::Window> SvxLineSpacingToolBoxControl::createPopupWindow( vcl::Window* pParent )
{
dynamic_cast<ParaLineSpacingControl&>(*mxPopover).SyncFromDocument();
mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent, mxPopover.get());
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 d33f790..ba63a41 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 322bf97..2f11f9f 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 853ce68..23f53b8 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 0000000..828bc6e
--- /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 3ef767c..0dd8825 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 bc53e4c..d52fb78 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);
}
}