tdf#145296 better fix to launch dialog when active radiobutton is clicked

Uses a mouse-release workaround to detect the case of clicking on an
already active radiobutton which gives a result basically
indistinguishable from the pre 7.2 experience

Change-Id: Ic7ac6fa20843466b1d0c77586e25f4aabf814328
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124286
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Tested-by: Jenkins
diff --git a/svx/source/tbxctrls/extrusioncontrols.cxx b/svx/source/tbxctrls/extrusioncontrols.cxx
index 6e040da..e51c479 100644
--- a/svx/source/tbxctrls/extrusioncontrols.cxx
+++ b/svx/source/tbxctrls/extrusioncontrols.cxx
@@ -341,6 +341,7 @@ ExtrusionDepthWindow::ExtrusionDepthWindow(svt::PopupWindowController* pControl,
    , meUnit(FieldUnit::NONE)
    , mfDepth( -1.0 )
    , mbSettingValue(false)
    , mbCommandDispatched(false)
{
    mxDepth0->connect_toggled(LINK(this, ExtrusionDepthWindow, SelectHdl));
    mxDepth1->connect_toggled(LINK(this, ExtrusionDepthWindow, SelectHdl));
@@ -349,6 +350,7 @@ ExtrusionDepthWindow::ExtrusionDepthWindow(svt::PopupWindowController* pControl,
    mxDepth4->connect_toggled(LINK(this, ExtrusionDepthWindow, SelectHdl));
    mxInfinity->connect_toggled(LINK(this, ExtrusionDepthWindow, SelectHdl));
    mxCustom->connect_toggled(LINK(this, ExtrusionDepthWindow, SelectHdl));
    mxCustom->connect_mouse_release(LINK(this, ExtrusionDepthWindow, MouseReleaseHdl));

    AddStatusListener( gsExtrusionDepth );
    AddStatusListener( gsMetricUnit );
@@ -443,23 +445,33 @@ void ExtrusionDepthWindow::statusChanged(
    }
}

void ExtrusionDepthWindow::DispatchDepthDialog()
{
    Sequence< PropertyValue > aArgs( 2 );
    aArgs[0].Name = "Depth";
    aArgs[0].Value <<= mfDepth;
    aArgs[1].Name = "Metric";
    aArgs[1].Value <<= static_cast<sal_Int32>( meUnit );

    rtl::Reference<svt::PopupWindowController> xControl(mxControl);
    xControl->EndPopupMode();
    xControl->dispatchCommand(".uno:ExtrusionDepthDialog", aArgs);
    mbCommandDispatched = true;
}

IMPL_LINK(ExtrusionDepthWindow, SelectHdl, weld::Toggleable&, rButton, void)
{
    if (mbSettingValue || !rButton.get_active())
        return;

    if (mxCustom->get_active())
    {
        Sequence< PropertyValue > aArgs( 2 );
        aArgs[0].Name = "Depth";
        aArgs[0].Value <<= mfDepth;
        aArgs[1].Name = "Metric";
        aArgs[1].Value <<= static_cast<sal_Int32>( meUnit );
    // see MouseReleaseHdl for mbCommandDispatched check, there's no guarantee
    // this toggle will happen before that mouse release though it does in
    // practice for vcl and gtk
    if (mbCommandDispatched)
        return;

        rtl::Reference<svt::PopupWindowController> xControl(mxControl);
        xControl->EndPopupMode();
        xControl->dispatchCommand(".uno:ExtrusionDepthDialog", aArgs);
    }
    if (mxCustom->get_active())
        DispatchDepthDialog();
    else
    {
        double fDepth;
@@ -490,12 +502,31 @@ IMPL_LINK(ExtrusionDepthWindow, SelectHdl, weld::Toggleable&, rButton, void)
        aArgs[0].Value <<= fDepth;

        mxControl->dispatchCommand( gsExtrusionDepth,  aArgs );
        mbCommandDispatched = true;
        implSetDepth( fDepth );

        mxControl->EndPopupMode();
    }
}

IMPL_LINK_NOARG(ExtrusionDepthWindow, MouseReleaseHdl, const MouseEvent&, bool)
{
    /*
     tdf#145296 if the "custom" radiobutton was presented preselected as
     toggled on and the user clicked on it then there's no toggled signal sent
     because the item was already toggled on and didn't change state.

     So if that happens launch the custom spacing dialog explicitly here on
     mouse release.
    */
    if (mxCustom->get_active() && !mbCommandDispatched)
    {
        DispatchDepthDialog();
        return true;
    }
    return false;
}

// ExtrusionDirectionControl
ExtrusionDepthController::ExtrusionDepthController(
    const Reference< XComponentContext >& rxContext
diff --git a/svx/source/tbxctrls/extrusioncontrols.hxx b/svx/source/tbxctrls/extrusioncontrols.hxx
index 0f0f54d..7e00434 100644
--- a/svx/source/tbxctrls/extrusioncontrols.hxx
+++ b/svx/source/tbxctrls/extrusioncontrols.hxx
@@ -104,12 +104,16 @@ private:
    FieldUnit   meUnit;
    double      mfDepth;
    bool        mbSettingValue;
    bool        mbCommandDispatched;

    DECL_LINK( SelectHdl, weld::Toggleable&, void );
    DECL_LINK( MouseReleaseHdl, const MouseEvent&, bool );

    void    implFillStrings( FieldUnit eUnit );
    void    implSetDepth( double fDepth );

    void    DispatchDepthDialog();

public:
    ExtrusionDepthWindow(svt::PopupWindowController* pControl, weld::Widget* pParentWindow);
    virtual void GrabFocus() override;
diff --git a/svx/source/tbxctrls/fontworkgallery.cxx b/svx/source/tbxctrls/fontworkgallery.cxx
index a5c812c..7bfec4b 100644
--- a/svx/source/tbxctrls/fontworkgallery.cxx
+++ b/svx/source/tbxctrls/fontworkgallery.cxx
@@ -477,13 +477,17 @@ private:
    std::unique_ptr<weld::RadioButton> mxVeryLoose;
    std::unique_ptr<weld::RadioButton> mxCustom;
    std::unique_ptr<weld::CheckButton> mxKernPairs;
    sal_Int32 mnCharacterSpacing;
    bool mbSettingValue;
    bool mbCommandDispatched;

    DECL_LINK( KernSelectHdl, weld::Toggleable&, void );
    DECL_LINK( SelectHdl, weld::Toggleable&, void );
    DECL_LINK( MouseReleaseHdl, const MouseEvent&, bool );

    void    implSetCharacterSpacing( sal_Int32 nCharacterSpacing, bool bEnabled );
    void    implSetKernCharacterPairs(bool bKernOnOff, bool bEnabled);
    void    DispatchSpacingDialog();
};

}
@@ -501,7 +505,9 @@ FontworkCharacterSpacingWindow::FontworkCharacterSpacingWindow(svt::PopupWindowC
    , mxVeryLoose(m_xBuilder->weld_radio_button("veryloose"))
    , mxCustom(m_xBuilder->weld_radio_button("custom"))
    , mxKernPairs(m_xBuilder->weld_check_button("kernpairs"))
    , mnCharacterSpacing(0)
    , mbSettingValue(false)
    , mbCommandDispatched(false)
{
    mxVeryTight->connect_toggled(LINK(this, FontworkCharacterSpacingWindow, SelectHdl));
    mxTight->connect_toggled(LINK(this, FontworkCharacterSpacingWindow, SelectHdl));
@@ -509,6 +515,7 @@ FontworkCharacterSpacingWindow::FontworkCharacterSpacingWindow(svt::PopupWindowC
    mxLoose->connect_toggled(LINK(this, FontworkCharacterSpacingWindow, SelectHdl));
    mxVeryLoose->connect_toggled(LINK(this, FontworkCharacterSpacingWindow, SelectHdl));
    mxCustom->connect_toggled(LINK(this, FontworkCharacterSpacingWindow, SelectHdl));
    mxCustom->connect_mouse_release(LINK(this, FontworkCharacterSpacingWindow, MouseReleaseHdl));

    mxKernPairs->connect_toggled(LINK(this, FontworkCharacterSpacingWindow, KernSelectHdl));

@@ -563,6 +570,8 @@ void FontworkCharacterSpacingWindow::implSetCharacterSpacing( sal_Int32 nCharact
            break;
    }

    mnCharacterSpacing = nCharacterSpacing;

    mbSettingValue = bSettingValue;
}

@@ -613,12 +622,25 @@ IMPL_LINK_NOARG(FontworkCharacterSpacingWindow, KernSelectHdl, weld::Toggleable&
    aArgs[0].Value <<= bKernOnOff;

    mxControl->dispatchCommand( gsFontworkKernCharacterPairs, aArgs );
    mbCommandDispatched = true;

    implSetKernCharacterPairs(bKernOnOff, true);

    mxControl->EndPopupMode();
}

void FontworkCharacterSpacingWindow::DispatchSpacingDialog()
{
    Sequence< PropertyValue > aArgs( 1 );
    aArgs[0].Name = OUString(gsFontworkCharacterSpacing).copy(5);
    aArgs[0].Value <<= mnCharacterSpacing;

    rtl::Reference<svt::PopupWindowController> xControl(mxControl);
    xControl->EndPopupMode();
    xControl->dispatchCommand(".uno:FontworkCharacterSpacingDialog", aArgs);
    mbCommandDispatched = true;
}

IMPL_LINK(FontworkCharacterSpacingWindow, SelectHdl, weld::Toggleable&, rButton, void)
{
    if (!rButton.get_active())
@@ -627,16 +649,14 @@ IMPL_LINK(FontworkCharacterSpacingWindow, SelectHdl, weld::Toggleable&, rButton,
    if (mbSettingValue)
        return;

    if (mxCustom->get_active())
    {
        Sequence< PropertyValue > aArgs( 1 );
        aArgs[0].Name = OUString(gsFontworkCharacterSpacing).copy(5);
        aArgs[0].Value <<= sal_Int32(100);
    // see MouseReleaseHdl for mbCommandDispatched check, there's no guarantee
    // this toggle will happen before that mouse release though it does in
    // practice for vcl and gtk
    if (mbCommandDispatched)
        return;

        rtl::Reference<svt::PopupWindowController> xControl(mxControl);
        xControl->EndPopupMode();
        xControl->dispatchCommand(".uno:FontworkCharacterSpacingDialog", aArgs);
    }
    if (mxCustom->get_active())
        DispatchSpacingDialog();
    else
    {
        sal_Int32 nCharacterSpacing;
@@ -656,6 +676,7 @@ IMPL_LINK(FontworkCharacterSpacingWindow, SelectHdl, weld::Toggleable&, rButton,
        aArgs[0].Value <<= nCharacterSpacing;

        mxControl->dispatchCommand( gsFontworkCharacterSpacing,  aArgs );
        mbCommandDispatched = true;

        implSetCharacterSpacing( nCharacterSpacing, true );
    }
@@ -663,6 +684,24 @@ IMPL_LINK(FontworkCharacterSpacingWindow, SelectHdl, weld::Toggleable&, rButton,
    mxControl->EndPopupMode();
}

IMPL_LINK_NOARG(FontworkCharacterSpacingWindow, MouseReleaseHdl, const MouseEvent&, bool)
{
    /*
     tdf#145296 if the "custom" radiobutton was presented preselected as
     toggled on and the user clicked on it then there's no toggled signal sent
     because the item was already toggled on and didn't change state.

     So if that happens launch the custom spacing dialog explicitly here on
     mouse release.
    */
    if (mxCustom->get_active() && !mbCommandDispatched)
    {
        DispatchSpacingDialog();
        return true;
    }
    return false;
}

namespace {

class FontworkCharacterSpacingControl : public svt::PopupWindowController