weld NumberFormatPropertyPanel

including GtkMenuToolButton hackery to support a toggled state

Change-Id: Ia1cf5fd7d56c2e475194cd2d0431611f278f5a33
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/85873
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/include/svx/tbcontrl.hxx b/include/svx/tbcontrl.hxx
index 9e6c387..315fd9e 100644
--- a/include/svx/tbcontrl.hxx
+++ b/include/svx/tbcontrl.hxx
@@ -264,6 +264,9 @@ private:
    OUString     m_aFormatString;
    LanguageType m_eLanguage;
    sal_uInt32   m_nFormatKey;

    weld::Toolbar* m_pToolbar;
    std::unique_ptr<svtools::ToolbarPopupBase> m_xPopover;
public:
    static void GetCurrencySymbols( std::vector<OUString>& rList, bool bFlag,
                                    std::vector<sal_uInt16>& rCurrencyList );
@@ -274,9 +277,14 @@ public:
    // XToolbarController
    virtual void SAL_CALL execute( sal_Int16 nSelectModifier ) override;

    // XComponent
    virtual void SAL_CALL dispose() override;

    using svt::ToolboxController::createPopupWindow;
    virtual VclPtr<vcl::Window> createPopupWindow( vcl::Window* pParent ) override;

    void EndPopupMode();

    // XServiceInfo
    virtual OUString SAL_CALL getImplementationName() override;
    virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
diff --git a/sc/source/ui/sidebar/NumberFormatPropertyPanel.cxx b/sc/source/ui/sidebar/NumberFormatPropertyPanel.cxx
index 7d8a840..a1d3c4e 100644
--- a/sc/source/ui/sidebar/NumberFormatPropertyPanel.cxx
+++ b/sc/source/ui/sidebar/NumberFormatPropertyPanel.cxx
@@ -38,26 +38,25 @@ NumberFormatPropertyPanel::NumberFormatPropertyPanel(
    vcl::Window* pParent,
    const css::uno::Reference<css::frame::XFrame>& rxFrame,
    SfxBindings* pBindings)
  : PanelLayout(pParent,"NumberFormatPropertyPanel", "modules/scalc/ui/sidebarnumberformat.ui", rxFrame),
    maNumFormatControl(SID_NUMBER_TYPE_FORMAT, *pBindings, *this),
    maFormatControl(SID_NUMBER_FORMAT, *pBindings, *this),

    mnCategorySelected(0),
    maContext(),
    mpBindings(pBindings)
    : PanelLayout(pParent,"NumberFormatPropertyPanel", "modules/scalc/ui/sidebarnumberformat.ui", rxFrame, true)
    , mxLbCategory(m_xBuilder->weld_combo_box("category"))
    , mxTBCategory(m_xBuilder->weld_toolbar("numberformat"))
    , mxCatagoryDispatch(new ToolbarUnoDispatcher(*mxTBCategory, rxFrame))
    , mxFtDecimals(m_xBuilder->weld_label("decimalplaceslabel"))
    , mxEdDecimals(m_xBuilder->weld_spin_button("decimalplaces"))
    , mxFtDenominator(m_xBuilder->weld_label("denominatorplaceslabel"))
    , mxEdDenominator(m_xBuilder->weld_spin_button("denominatorplaces"))
    , mxFtLeadZeroes(m_xBuilder->weld_label("leadingzeroeslabel"))
    , mxEdLeadZeroes(m_xBuilder->weld_spin_button("leadingzeroes"))
    , mxBtnNegRed(m_xBuilder->weld_check_button("negativenumbersred"))
    , mxBtnThousand(m_xBuilder->weld_check_button("thousandseparator"))
    , mxBtnEngineering(m_xBuilder->weld_check_button("engineeringnotation"))
    , maNumFormatControl(SID_NUMBER_TYPE_FORMAT, *pBindings, *this)
    , maFormatControl(SID_NUMBER_FORMAT, *pBindings, *this)
    , mnCategorySelected(0)
    , maContext()
    , mpBindings(pBindings)
{
    get(mpLbCategory,     "category");
    get(mpTBCategory,     "numberformat");
    get(mpFtDecimals,     "decimalplaceslabel");
    get(mpEdDecimals,     "decimalplaces");
    get(mpFtDenominator,  "denominatorplaceslabel");
    get(mpEdDenominator,  "denominatorplaces");
    get(mpFtLeadZeroes,   "leadingzeroeslabel");
    get(mpEdLeadZeroes,   "leadingzeroes");
    get(mpBtnNegRed,      "negativenumbersred");
    get(mpBtnThousand,    "thousandseparator");
    get(mpBtnEngineering, "engineeringnotation");

    Initialize();
}

@@ -68,17 +67,18 @@ NumberFormatPropertyPanel::~NumberFormatPropertyPanel()

void NumberFormatPropertyPanel::dispose()
{
    mpLbCategory.clear();
    mpTBCategory.clear();
    mpFtDecimals.clear();
    mpEdDecimals.clear();
    mpFtDenominator.clear();
    mpEdDenominator.clear();
    mpFtLeadZeroes.clear();
    mpEdLeadZeroes.clear();
    mpBtnNegRed.clear();
    mpBtnThousand.clear();
    mpBtnEngineering.clear();
    mxLbCategory.reset();
    mxCatagoryDispatch.reset();
    mxTBCategory.reset();
    mxFtDecimals.reset();
    mxEdDecimals.reset();
    mxFtDenominator.reset();
    mxEdDenominator.reset();
    mxFtLeadZeroes.reset();
    mxEdLeadZeroes.reset();
    mxBtnNegRed.reset();
    mxBtnThousand.reset();
    mxBtnEngineering.reset();

    maNumFormatControl.dispose();
    maFormatControl.dispose();
@@ -88,24 +88,23 @@ void NumberFormatPropertyPanel::dispose()

void NumberFormatPropertyPanel::Initialize()
{
    mpLbCategory->SetSelectHdl ( LINK(this, NumberFormatPropertyPanel, NumFormatSelectHdl) );
    mpLbCategory->SelectEntryPos(0);
    mpLbCategory->SetDropDownLineCount(mpLbCategory->GetEntryCount());
    mxLbCategory->connect_changed( LINK(this, NumberFormatPropertyPanel, NumFormatSelectHdl) );
    mxLbCategory->set_active(0);

    Link<Edit&,void> aLink = LINK(this, NumberFormatPropertyPanel, NumFormatValueHdl);
    Link<weld::SpinButton&,void> aLink = LINK(this, NumberFormatPropertyPanel, NumFormatValueHdl);

    mpEdDecimals->SetModifyHdl( aLink );
    mpEdDenominator->SetModifyHdl( aLink );
    mpEdLeadZeroes->SetModifyHdl( aLink );
    mxEdDecimals->connect_value_changed( aLink );
    mxEdDenominator->connect_value_changed( aLink );
    mxEdLeadZeroes->connect_value_changed( aLink );

    mpBtnNegRed->SetClickHdl( LINK(this, NumberFormatPropertyPanel, NumFormatValueClickHdl) );
    mpBtnThousand->SetClickHdl( LINK(this, NumberFormatPropertyPanel, NumFormatValueClickHdl) );
    mpBtnEngineering->SetClickHdl( LINK(this, NumberFormatPropertyPanel, NumFormatValueClickHdl) );
    mxBtnNegRed->connect_toggled( LINK(this, NumberFormatPropertyPanel, NumFormatValueClickHdl) );
    mxBtnThousand->connect_toggled( LINK(this, NumberFormatPropertyPanel, NumFormatValueClickHdl) );
    mxBtnEngineering->connect_toggled( LINK(this, NumberFormatPropertyPanel, NumFormatValueClickHdl) );
}

IMPL_LINK( NumberFormatPropertyPanel, NumFormatSelectHdl, ListBox&, rBox, void )
IMPL_LINK( NumberFormatPropertyPanel, NumFormatSelectHdl, weld::ComboBox&, rBox, void )
{
    const sal_Int32 nVal = rBox.GetSelectedEntryPos();
    const sal_Int32 nVal = rBox.get_active();
    if( nVal != mnCategorySelected )
    {
        SfxUInt16Item aItem( SID_NUMBER_TYPE_FORMAT,  nVal );
@@ -115,24 +114,25 @@ IMPL_LINK( NumberFormatPropertyPanel, NumFormatSelectHdl, ListBox&, rBox, void )
    }
}

IMPL_LINK_NOARG( NumberFormatPropertyPanel, NumFormatValueClickHdl, Button*, void )
IMPL_LINK_NOARG( NumberFormatPropertyPanel, NumFormatValueClickHdl, weld::ToggleButton&, void )
{
    NumFormatValueHdl(*mpEdDecimals);
    NumFormatValueHdl(*mxEdDecimals);
}
IMPL_LINK_NOARG( NumberFormatPropertyPanel, NumFormatValueHdl, Edit&, void )

IMPL_LINK_NOARG( NumberFormatPropertyPanel, NumFormatValueHdl, weld::SpinButton&, void )
{
    OUString    aFormat;
    OUString    sBreak = ",";
    bool        bThousand   = ( mpBtnThousand->IsVisible() && mpBtnThousand->IsEnabled() && mpBtnThousand->IsChecked() )
                           || ( mpBtnEngineering->IsVisible() && mpBtnEngineering->IsEnabled() && mpBtnEngineering->IsChecked() );
    bool        bNegRed     =  mpBtnNegRed->IsEnabled() && mpBtnNegRed->IsChecked();
    sal_uInt16  nPrecision  = (mpEdDecimals->IsEnabled() && mpEdDecimals->IsVisible())
                            ? static_cast<sal_uInt16>(mpEdDecimals->GetValue())
                            : (mpEdDenominator->IsEnabled() && mpEdDenominator->IsVisible())
                                ? static_cast<sal_uInt16>(mpEdDenominator->GetValue())
    bool        bThousand   = ( mxBtnThousand->get_visible() && mxBtnThousand->get_sensitive() && mxBtnThousand->get_active() )
                           || ( mxBtnEngineering->get_visible() && mxBtnEngineering->get_sensitive() && mxBtnEngineering->get_active() );
    bool        bNegRed     =  mxBtnNegRed->get_sensitive() && mxBtnNegRed->get_active();
    sal_uInt16  nPrecision  = (mxEdDecimals->get_sensitive() && mxEdDecimals->get_visible())
                            ? static_cast<sal_uInt16>(mxEdDecimals->get_value())
                            : (mxEdDenominator->get_sensitive() && mxEdDenominator->get_visible())
                                ? static_cast<sal_uInt16>(mxEdDenominator->get_value())
                                : sal_uInt16(0);
    sal_uInt16  nLeadZeroes = (mpEdLeadZeroes->IsEnabled())
                            ? static_cast<sal_uInt16>(mpEdLeadZeroes->GetValue())
    sal_uInt16  nLeadZeroes = (mxEdLeadZeroes->get_sensitive())
                            ? static_cast<sal_uInt16>(mxEdLeadZeroes->get_value())
                            : sal_uInt16(0);

    OUString sThousand = OUString::number(static_cast<sal_Int32>(bThousand));
@@ -200,30 +200,30 @@ void NumberFormatPropertyPanel::NotifyItemUpdate(
                const SfxInt16Item* pItem = static_cast<const SfxInt16Item*>(pState);
                sal_uInt16 nVal = pItem->GetValue();
                mnCategorySelected = nVal;
                mpLbCategory->SelectEntryPos(nVal);
                mxLbCategory->set_active(nVal);
                if( nVal < 4 ||  // General, Number, Percent and Currency
                    nVal == 6 || // scientific also
                    nVal == 7 )  // fraction
                {
                    bool bIsScientific ( nVal == 6 );// For scientific, Thousand separator is replaced by Engineering notation
                    bool bIsFraction ( nVal == 7 );  // For fraction, Decimal places is replaced by Denominator places
                    mpBtnThousand->Show(!bIsScientific);
                    mpBtnThousand->Enable(!bIsScientific);
                    mpBtnThousand->Check(false);
                    mpBtnEngineering->Show(bIsScientific);
                    mpBtnEngineering->Enable(bIsScientific);
                    mpBtnEngineering->Check(false);
                    mpBtnNegRed->Enable();
                    mpFtDenominator->Show(bIsFraction);
                    mpEdDenominator->Show(bIsFraction);
                    mpFtDenominator->Enable(bIsFraction);
                    mpEdDenominator->Enable(bIsFraction);
                    mpFtDecimals->Show(!bIsFraction);
                    mpEdDecimals->Show(!bIsFraction);
                    mpFtDecimals->Enable(!bIsFraction);
                    mpEdDecimals->Enable(!bIsFraction);
                    mpFtLeadZeroes->Enable();
                    mpEdLeadZeroes->Enable();
                    mxBtnThousand->set_visible(!bIsScientific);
                    mxBtnThousand->set_sensitive(!bIsScientific);
                    mxBtnThousand->set_active(false);
                    mxBtnEngineering->set_visible(bIsScientific);
                    mxBtnEngineering->set_sensitive(bIsScientific);
                    mxBtnEngineering->set_active(false);
                    mxBtnNegRed->set_sensitive(true);
                    mxFtDenominator->set_visible(bIsFraction);
                    mxEdDenominator->set_visible(bIsFraction);
                    mxFtDenominator->set_sensitive(bIsFraction);
                    mxEdDenominator->set_sensitive(bIsFraction);
                    mxFtDecimals->set_visible(!bIsFraction);
                    mxEdDecimals->set_visible(!bIsFraction);
                    mxFtDecimals->set_sensitive(!bIsFraction);
                    mxEdDecimals->set_sensitive(!bIsFraction);
                    mxFtLeadZeroes->set_sensitive(true);
                    mxEdLeadZeroes->set_sensitive(true);
                }
                else
                    DisableControls();
@@ -231,7 +231,7 @@ void NumberFormatPropertyPanel::NotifyItemUpdate(
            else
            {
                DisableControls();
                mpLbCategory->SetNoSelection();
                mxLbCategory->set_active(-1);
                mnCategorySelected = 0;
            }
        }
@@ -266,18 +266,18 @@ void NumberFormatPropertyPanel::NotifyItemUpdate(
                nPrecision  =    0;
                nLeadZeroes =    1;
            }
            if ( mpBtnThousand->IsVisible() )
                mpBtnThousand->Check(bThousand);
            else if ( mpBtnEngineering->IsVisible() )
                mpBtnEngineering->Check(bThousand);
            mpBtnNegRed->Check(bNegRed);
            if ( mpLbCategory->GetSelectedEntryPos() == 0 )
                mpEdDecimals->SetText(""); // tdf#44399
            else if ( mpEdDecimals->IsVisible() )
                mpEdDecimals->SetValue(nPrecision);
            else if ( mpEdDenominator->IsVisible() )
                mpEdDenominator->SetValue(nPrecision);
            mpEdLeadZeroes->SetValue(nLeadZeroes);
            if ( mxBtnThousand->get_visible() )
                mxBtnThousand->set_active(bThousand);
            else if ( mxBtnEngineering->get_visible() )
                mxBtnEngineering->set_active(bThousand);
            mxBtnNegRed->set_active(bNegRed);
            if ( mxLbCategory->get_active() == 0 )
                mxEdDecimals->set_text(""); // tdf#44399
            else if ( mxEdDecimals->get_visible() )
                mxEdDecimals->set_value(nPrecision);
            else if ( mxEdDenominator->get_visible() )
                mxEdDenominator->set_value(nPrecision);
            mxEdLeadZeroes->set_value(nLeadZeroes);
        }
        break;
    default:
@@ -287,18 +287,18 @@ void NumberFormatPropertyPanel::NotifyItemUpdate(

void NumberFormatPropertyPanel::DisableControls()
{
    mpBtnEngineering->Hide();
    mpBtnThousand->Show();
    mpBtnThousand->Disable();
    mpBtnNegRed->Disable();
    mpFtDenominator->Hide();
    mpEdDenominator->Hide();
    mpFtDecimals->Show();
    mpEdDecimals->Show();
    mpFtDecimals->Disable();
    mpEdDecimals->Disable();
    mpFtLeadZeroes->Disable();
    mpEdLeadZeroes->Disable();
    mxBtnEngineering->hide();
    mxBtnThousand->show();
    mxBtnThousand->set_sensitive(false);
    mxBtnNegRed->set_sensitive(false);
    mxFtDenominator->hide();
    mxEdDenominator->hide();
    mxFtDecimals->show();
    mxEdDecimals->show();
    mxFtDecimals->set_sensitive(false);
    mxEdDecimals->set_sensitive(false);
    mxFtLeadZeroes->set_sensitive(false);
    mxEdLeadZeroes->set_sensitive(false);
}

}} // end of namespace ::sc::sidebar
diff --git a/sc/source/ui/sidebar/NumberFormatPropertyPanel.hxx b/sc/source/ui/sidebar/NumberFormatPropertyPanel.hxx
index 0406f33..74eaa1f3 100644
--- a/sc/source/ui/sidebar/NumberFormatPropertyPanel.hxx
+++ b/sc/source/ui/sidebar/NumberFormatPropertyPanel.hxx
@@ -21,12 +21,8 @@

#include <sfx2/sidebar/ControllerItem.hxx>
#include <sfx2/sidebar/IContextChangeReceiver.hxx>
#include <sfx2/weldutils.hxx>
#include <svx/sidebar/PanelLayout.hxx>
#include <vcl/fixed.hxx>
#include <vcl/lstbox.hxx>
#include <vcl/field.hxx>
#include <vcl/button.hxx>
#include <vcl/toolbox.hxx>

class Edit;

@@ -66,17 +62,18 @@ public:
    virtual void dispose() override;
private:
    //ui controls
    VclPtr<ListBox>                                mpLbCategory;
    VclPtr<ToolBox>                                mpTBCategory;
    VclPtr<FixedText>                              mpFtDecimals;
    VclPtr<NumericField>                           mpEdDecimals;
    VclPtr<FixedText>                              mpFtDenominator;
    VclPtr<NumericField>                           mpEdDenominator;
    VclPtr<FixedText>                              mpFtLeadZeroes;
    VclPtr<NumericField>                           mpEdLeadZeroes;
    VclPtr<CheckBox>                               mpBtnNegRed;
    VclPtr<CheckBox>                               mpBtnThousand;
    VclPtr<CheckBox>                               mpBtnEngineering;
    std::unique_ptr<weld::ComboBox> mxLbCategory;
    std::unique_ptr<weld::Toolbar> mxTBCategory;
    std::unique_ptr<ToolbarUnoDispatcher> mxCatagoryDispatch;
    std::unique_ptr<weld::Label> mxFtDecimals;
    std::unique_ptr<weld::SpinButton> mxEdDecimals;
    std::unique_ptr<weld::Label> mxFtDenominator;
    std::unique_ptr<weld::SpinButton> mxEdDenominator;
    std::unique_ptr<weld::Label> mxFtLeadZeroes;
    std::unique_ptr<weld::SpinButton> mxEdLeadZeroes;
    std::unique_ptr<weld::CheckButton> mxBtnNegRed;
    std::unique_ptr<weld::CheckButton> mxBtnThousand;
    std::unique_ptr<weld::CheckButton> mxBtnEngineering;

    ::sfx2::sidebar::ControllerItem         maNumFormatControl;
    ::sfx2::sidebar::ControllerItem         maFormatControl;
@@ -86,9 +83,9 @@ private:
    vcl::EnumContext                        maContext;
    SfxBindings* const                      mpBindings;

    DECL_LINK(NumFormatSelectHdl, ListBox&, void);
    DECL_LINK(NumFormatValueHdl, Edit&, void);
    DECL_LINK(NumFormatValueClickHdl, Button*, void);
    DECL_LINK(NumFormatSelectHdl, weld::ComboBox&, void);
    DECL_LINK(NumFormatValueHdl, weld::SpinButton&, void);
    DECL_LINK(NumFormatValueClickHdl, weld::ToggleButton&, void);

    void Initialize();
    void DisableControls();
diff --git a/sc/uiconfig/scalc/ui/sidebarnumberformat.ui b/sc/uiconfig/scalc/ui/sidebarnumberformat.ui
index 21857e4..291d5b6 100644
--- a/sc/uiconfig/scalc/ui/sidebarnumberformat.ui
+++ b/sc/uiconfig/scalc/ui/sidebarnumberformat.ui
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<!-- Generated with glade 3.22.1 -->
<interface domain="sc">
  <requires lib="gtk+" version="3.18"/>
  <requires lib="LibreOffice" version="1.0"/>
  <object class="GtkAdjustment" id="adjustment1">
    <property name="upper">20</property>
    <property name="step_increment">1</property>
@@ -13,6 +12,11 @@
    <property name="step_increment">1</property>
    <property name="page_increment">1</property>
  </object>
  <object class="GtkAdjustment" id="adjustment3">
    <property name="upper">20</property>
    <property name="step_increment">1</property>
    <property name="page_increment">10</property>
  </object>
  <object class="GtkGrid" id="NumberFormatPropertyPanel">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
@@ -36,6 +40,7 @@
                <property name="can_focus">True</property>
                <property name="has_tooltip">True</property>
                <property name="tooltip_text" translatable="yes" context="sidebarnumberformat|category|tooltip_text">Select a category of contents.</property>
                <property name="valign">center</property>
                <property name="hexpand">True</property>
                <items>
                  <item translatable="yes" context="sidebarnumberformat|category">General</item>
@@ -61,44 +66,43 @@
              </packing>
            </child>
            <child>
              <object class="sfxlo-SidebarToolBox" id="numberformat">
              <object class="GtkToolbar" id="numberformat">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="toolbar_style">icons</property>
                <property name="show_arrow">False</property>
                <property name="icon_size">2</property>
                <child>
                  <object class="GtkToolButton" id="currency">
                  <object class="GtkMenuToolButton" id=".uno:NumberFormatCurrency">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="action_name">.uno:NumberFormatCurrency</property>
                    <property name="use_underline">True</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="homogeneous">True</property>
                    <property name="homogeneous">False</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkToolButton" id="percent">
                  <object class="GtkToggleToolButton" id=".uno:NumberFormatPercent">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="action_name">.uno:NumberFormatPercent</property>
                    <property name="use_underline">True</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="homogeneous">True</property>
                    <property name="homogeneous">False</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkToolButton" id="numericfield">
                  <object class="GtkToggleToolButton" id=".uno:NumberFormatDecimal">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="action_name">.uno:NumberFormatDecimal</property>
                    <property name="use_underline">True</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="homogeneous">True</property>
                    <property name="homogeneous">False</property>
                  </packing>
                </child>
              </object>
@@ -126,6 +130,19 @@
                <property name="orientation">vertical</property>
                <property name="spacing">6</property>
                <child>
                  <object class="GtkLabel" id="denominatorplaceslabel">
                    <property name="can_focus">False</property>
                    <property name="label" translatable="yes" context="sidebarnumberformat|denominatorplaceslabel">Den_ominator places:</property>
                    <property name="use_underline">True</property>
                    <property name="mnemonic_widget">denominatorplaces</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">0</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkLabel" id="decimalplaceslabel">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
@@ -145,7 +162,7 @@
                    <property name="can_focus">True</property>
                    <property name="has_tooltip">True</property>
                    <property name="tooltip_text" translatable="yes" context="sidebarnumberformat|decimalplaces|tooltip_text">Enter the number of decimal places that you want to display.</property>
                    <property name="adjustment">adjustment1</property>
                    <property name="adjustment">adjustment3</property>
                    <child internal-child="accessible">
                      <object class="AtkObject" id="decimalplaces-atkobject">
                        <property name="AtkObject::accessible-name" translatable="yes" context="sidebarnumberformat|decimalplaces-atkobject">Decimal Places</property>
@@ -159,22 +176,7 @@
                  </packing>
                </child>
                <child>
                  <object class="GtkLabel" id="denominatorplaceslabel">
                    <property name="visible">False</property>
                    <property name="can_focus">False</property>
                    <property name="label" translatable="yes" context="sidebarnumberformat|denominatorplaceslabel">Den_ominator places:</property>
                    <property name="use_underline">True</property>
                    <property name="mnemonic_widget">denominatorplaces</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">0</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkSpinButton" id="denominatorplaces">
                    <property name="visible">False</property>
                    <property name="can_focus">True</property>
                    <property name="has_tooltip">True</property>
                    <property name="tooltip_text" translatable="yes" context="sidebarnumberformat|denominatorplaces|tooltip_text">Enter the number of places for the denominator that you want to display.</property>
@@ -292,7 +294,6 @@
        <child>
          <object class="GtkCheckButton" id="engineeringnotation">
            <property name="label" translatable="yes" context="sidebarnumberformat|engineeringnotation">_Engineering notation</property>
            <property name="visible">False</property>
            <property name="can_focus">True</property>
            <property name="receives_default">False</property>
            <property name="has_tooltip">True</property>
diff --git a/svx/UIConfig_svx.mk b/svx/UIConfig_svx.mk
index 6193d0c..689e59f 100644
--- a/svx/UIConfig_svx.mk
+++ b/svx/UIConfig_svx.mk
@@ -26,6 +26,7 @@ $(eval $(call gb_UIConfig_add_uifiles,svx,\
	svx/uiconfig/ui/chinesedictionary \
	svx/uiconfig/ui/classificationdialog \
	svx/uiconfig/ui/colorwindow \
	svx/uiconfig/ui/currencywindow \
	svx/uiconfig/ui/colsmenu \
	svx/uiconfig/ui/compressgraphicdialog \
	svx/uiconfig/ui/convertmenu \
diff --git a/svx/source/tbxctrls/tbcontrl.cxx b/svx/source/tbxctrls/tbcontrl.cxx
index 50eaa75..b4c7ca5 100644
--- a/svx/source/tbxctrls/tbcontrl.cxx
+++ b/svx/source/tbxctrls/tbcontrl.cxx
@@ -32,6 +32,7 @@
#include <vcl/bitmapaccess.hxx>
#include <vcl/menubtn.hxx>
#include <vcl/vclptr.hxx>
#include <vcl/weldutils.hxx>
#include <svtools/valueset.hxx>
#include <svtools/ctrlbox.hxx>
#include <svl/style.hxx>
@@ -3740,16 +3741,167 @@ void SvxSimpleUndoRedoController::StateChanged( sal_uInt16, SfxItemState eState,
SvxCurrencyToolBoxControl::SvxCurrencyToolBoxControl( const css::uno::Reference<css::uno::XComponentContext>& rContext ) :
    PopupWindowController( rContext, nullptr, OUString() ),
    m_eLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() ),
    m_nFormatKey( NUMBERFORMAT_ENTRY_NOT_FOUND )
    m_nFormatKey( NUMBERFORMAT_ENTRY_NOT_FOUND ),
    m_pToolbar(nullptr)
{
}

SvxCurrencyToolBoxControl::~SvxCurrencyToolBoxControl() {}

namespace
{

    class ToolbarPopup : public svtools::ToolbarPopupBase
    {
    protected:
        std::unique_ptr<weld::Builder> m_xBuilder;
        std::unique_ptr<weld::Container> m_xTopLevel;
    public:
        ToolbarPopup(const css::uno::Reference<css::frame::XFrame>& rFrame, weld::Widget* pParent, const OUString& rUIFile, const OString& rId)
            : ToolbarPopupBase(rFrame)
            , m_xBuilder(Application::CreateBuilder(pParent, rUIFile))
            , m_xTopLevel(m_xBuilder->weld_container(rId))
        {
        }
        weld::Container* getTopLevel()
        {
            return m_xTopLevel.get();
        }
    };

    class CurrencyList_Impl : public ToolbarPopup
    {
    private:
        rtl::Reference<SvxCurrencyToolBoxControl> m_xControl;
        std::unique_ptr<weld::Label> m_xLabel;
        std::unique_ptr<weld::TreeView> m_xCurrencyLb;
        std::unique_ptr<weld::Button> m_xOkBtn;
        OUString&       m_rSelectedFormat;
        LanguageType&   m_eSelectedLanguage;

        std::vector<OUString> m_aFormatEntries;
        LanguageType          m_eFormatLanguage;
        DECL_LINK(RowActivatedHdl, weld::TreeView&, bool);
        DECL_LINK(FocusHdl, weld::Widget&, void);
        DECL_LINK(OKHdl, weld::Button&, void);

    public:
        CurrencyList_Impl(SvxCurrencyToolBoxControl* pControl, weld::Widget* pParent, OUString& rSelectedFormat, LanguageType& eSelectedLanguage)
            : ToolbarPopup(pControl->getFrameInterface(), pParent, "svx/ui/currencywindow.ui", "CurrencyWindow")
            , m_xControl(pControl)
            , m_xLabel(m_xBuilder->weld_label("label"))
            , m_xCurrencyLb(m_xBuilder->weld_tree_view("currency"))
            , m_xOkBtn(m_xBuilder->weld_button("ok"))
            , m_rSelectedFormat(rSelectedFormat)
            , m_eSelectedLanguage(eSelectedLanguage)
        {
            m_xTopLevel->connect_focus_in(LINK(this, CurrencyList_Impl, FocusHdl));

            m_xCurrencyLb->set_size_request(-1, m_xCurrencyLb->get_height_rows(12));

            std::vector< OUString > aList;
            std::vector< sal_uInt16 > aCurrencyList;
            const NfCurrencyTable& rCurrencyTable = SvNumberFormatter::GetTheCurrencyTable();
            sal_uInt16 nLen = rCurrencyTable.size();

            SvNumberFormatter aFormatter( m_xControl->getContext(), LANGUAGE_SYSTEM );
            m_eFormatLanguage = aFormatter.GetLanguage();

            SvxCurrencyToolBoxControl::GetCurrencySymbols( aList, true, aCurrencyList );

            sal_uInt16 nPos = 0, nCount = 0;
            sal_Int32 nSelectedPos = -1;
            bool bIsSymbol;
            NfWSStringsDtor aStringsDtor;

            for( const auto& rItem : aList )
            {
                sal_uInt16& rCurrencyIndex = aCurrencyList[ nCount ];
                if ( rCurrencyIndex < nLen )
                {
                    m_xCurrencyLb->append_text(rItem);
                    const NfCurrencyEntry& aCurrencyEntry = rCurrencyTable[ rCurrencyIndex ];

                    bIsSymbol = nPos >= nLen;

                    sal_uInt16 nDefaultFormat = aFormatter.GetCurrencyFormatStrings( aStringsDtor, aCurrencyEntry, bIsSymbol );
                    const OUString& rFormatStr = aStringsDtor[ nDefaultFormat ];
                    m_aFormatEntries.push_back( rFormatStr );
                    if( rFormatStr == m_rSelectedFormat )
                        nSelectedPos = nPos;
                    ++nPos;
                }
                ++nCount;
            }
            // enable multiple selection enabled so we can start with nothing selected
            m_xCurrencyLb->set_selection_mode(SelectionMode::Multiple);
            m_xCurrencyLb->connect_row_activated( LINK( this, CurrencyList_Impl, RowActivatedHdl ) );
            m_xLabel->set_label(SvxResId(RID_SVXSTR_TBLAFMT_CURRENCY));
            m_xCurrencyLb->select( nSelectedPos );
            m_xOkBtn->connect_clicked(LINK(this, CurrencyList_Impl, OKHdl));
        }

    };

    IMPL_LINK_NOARG(CurrencyList_Impl, FocusHdl, weld::Widget&, void)
    {
        m_xCurrencyLb->grab_focus();
    }

    IMPL_LINK_NOARG(CurrencyList_Impl, OKHdl, weld::Button&, void)
    {
        RowActivatedHdl(*m_xCurrencyLb);
    }

    IMPL_LINK_NOARG(CurrencyList_Impl, RowActivatedHdl, weld::TreeView&, bool)
    {
        if (!m_xControl.is())
            return true;

        // multiple selection enabled so we can start with nothing selected,
        // so force single selection after something is picked
        int nSelected = m_xCurrencyLb->get_selected_index();
        if (nSelected == -1)
            return true;

        m_xCurrencyLb->set_selection_mode(SelectionMode::Single);

        m_rSelectedFormat = m_aFormatEntries[nSelected];
        m_eSelectedLanguage = m_eFormatLanguage;

        m_xControl->execute(nSelected + 1);

        m_xControl->EndPopupMode();

        return true;
    }
}

void SvxCurrencyToolBoxControl::EndPopupMode()
{
    m_pToolbar->set_menu_item_active(m_aCommandURL.toUtf8(), false);
}

void SvxCurrencyToolBoxControl::dispose()
{
    m_xPopover.reset();
    svt::PopupWindowController::dispose();
}

void SvxCurrencyToolBoxControl::initialize( const css::uno::Sequence< css::uno::Any >& rArguments )
{
    PopupWindowController::initialize(rArguments);

    if (weld::TransportAsXWindow* pTunnel = dynamic_cast<weld::TransportAsXWindow*>(getParent().get()))
    {
        m_pToolbar = dynamic_cast<weld::Toolbar*>(pTunnel->getWidget());
        assert(m_pToolbar && "must be a toolbar");
        auto xPopover = std::make_unique<CurrencyList_Impl>(this, m_pToolbar, m_aFormatString, m_eLanguage);
        m_pToolbar->set_item_popover(m_aCommandURL.toUtf8(), xPopover->getTopLevel());
        m_xPopover = std::move(xPopover);
        return;
    }

    ToolBox* pToolBox = nullptr;
    sal_uInt16 nId = 0;
    if (getToolboxId(nId, &pToolBox) && pToolBox->GetItemCommand(nId) == m_aCommandURL)
diff --git a/svx/uiconfig/ui/currencywindow.ui b/svx/uiconfig/ui/currencywindow.ui
new file mode 100644
index 0000000..982536c
--- /dev/null
+++ b/svx/uiconfig/ui/currencywindow.ui
@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface domain="svx">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
      <!-- column-name id -->
      <column type="gchararray"/>
    </columns>
  </object>
  <object class="GtkPopover" id="CurrencyWindow">
    <property name="can_focus">False</property>
    <property name="no_show_all">True</property>
    <property name="border_width">4</property>
    <child>
      <object class="GtkBox">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <property name="spacing">6</property>
        <child>
          <object class="GtkLabel" id="label">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="use_underline">True</property>
            <property name="mnemonic_widget">currency</property>
            <property name="xalign">0</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkScrolledWindow">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="hexpand">True</property>
            <property name="vexpand">True</property>
            <property name="hscrollbar_policy">never</property>
            <property name="shadow_type">in</property>
            <child>
              <object class="GtkTreeView" id="currency">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <property name="model">liststore1</property>
                <property name="headers_visible">False</property>
                <property name="headers_clickable">False</property>
                <property name="search_column">0</property>
                <property name="show_expanders">False</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="selection"/>
                </child>
                <child>
                  <object class="GtkTreeViewColumn" id="treeviewcolumn1">
                    <child>
                      <object class="GtkCellRendererText" id="cellrenderertext1"/>
                      <attributes>
                        <attribute name="text">0</attribute>
                      </attributes>
                    </child>
                  </object>
                </child>
              </object>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="ok">
            <property name="label">gtk-ok</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <property name="use_stock">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">2</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 1addc51..6630ee1 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -7052,6 +7052,17 @@ private:
            gtk_container_forall(GTK_CONTAINER(pWidget), find_menu_button, user_data);
    }

    static void find_menupeer_button(GtkWidget *pWidget, gpointer user_data)
    {
        if (g_strcmp0(gtk_widget_get_name(pWidget), "GtkButton") == 0)
        {
            GtkWidget **ppButton = static_cast<GtkWidget**>(user_data);
            *ppButton = pWidget;
        }
        else if (GTK_IS_CONTAINER(pWidget))
            gtk_container_forall(GTK_CONTAINER(pWidget), find_menupeer_button, user_data);
    }

    static void collect(GtkWidget* pItem, gpointer widget)
    {
        if (GTK_IS_TOOL_BUTTON(pItem))
@@ -7139,8 +7150,24 @@ public:
        disable_item_notify_events();

        GtkToolButton* pToolButton = m_aMap.find(rIdent)->second;
        assert(GTK_IS_TOGGLE_TOOL_BUTTON(pToolButton) || !bActive);
        if (GTK_IS_TOGGLE_TOOL_BUTTON(pToolButton))

        assert(GTK_IS_TOGGLE_TOOL_BUTTON(pToolButton) || GTK_IS_MENU_TOOL_BUTTON(pToolButton) || !bActive);
        if (GTK_IS_MENU_TOOL_BUTTON(pToolButton))
        {
            GtkButton* pButton = nullptr;
            // there is no GtkMenuToggleToolButton so abuse the CHECKED state of the GtkMenuToolButton button
            // to emulate one
            find_menupeer_button(GTK_WIDGET(pToolButton), &pButton);
            if (pButton)
            {
                GtkStyleContext *pWidgetContext = gtk_widget_get_style_context(GTK_WIDGET(pButton));
                auto eState = gtk_style_context_get_state(pWidgetContext) & ~GTK_STATE_FLAG_CHECKED;
                if (bActive)
                    eState |= GTK_STATE_FLAG_CHECKED;
                gtk_style_context_set_state(pWidgetContext, static_cast<GtkStateFlags>(eState));
            }
        }
        else if (GTK_IS_TOGGLE_TOOL_BUTTON(pToolButton))
            gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(pToolButton), bActive);

        enable_item_notify_events();
@@ -7148,12 +7175,25 @@ public:

    virtual bool get_item_active(const OString& rIdent) const override
    {
        auto aFind = m_aMenuButtonMap.find(rIdent);
        if (aFind != m_aMenuButtonMap.end())
            return aFind->second->get_active();

        GtkToolButton* pToolButton = m_aMap.find(rIdent)->second;
        return gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(pToolButton));

        assert(GTK_IS_TOGGLE_TOOL_BUTTON(pToolButton) || GTK_IS_MENU_TOOL_BUTTON(pToolButton));
        if (GTK_IS_MENU_TOOL_BUTTON(pToolButton))
        {
            GtkButton* pButton = nullptr;
            // there is no GtkMenuToggleToolButton so abuse the CHECKED state of the GtkMenuToolButton button
            // to emulate one
            find_menupeer_button(GTK_WIDGET(pToolButton), &pButton);
            if (pButton)
            {
                GtkStyleContext *pWidgetContext = gtk_widget_get_style_context(GTK_WIDGET(pButton));
                return gtk_style_context_get_state(pWidgetContext) & GTK_STATE_FLAG_CHECKED;
            }
        }
        else if (GTK_IS_TOGGLE_TOOL_BUTTON(pToolButton))
            return gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(pToolButton));

        return false;
    }

    virtual void set_menu_item_active(const OString& rIdent, bool bActive) override