framework/source/uielement/spinfieldtoolbarcontroller.cxx |   10 -
 include/vcl/formatter.hxx                                 |    6 -
 include/vcl/weldutils.hxx                                 |    6 -
 vcl/inc/salvtables.hxx                                    |    2 
 vcl/source/app/salvtables.cxx                             |   13 --
 vcl/source/app/weldutils.cxx                              |    8 -
 vcl/source/control/field2.cxx                             |   12 --
 vcl/source/control/fmtfield.cxx                           |   77 +++++++-------
 vcl/source/control/longcurr.cxx                           |    6 -
 9 files changed, 65 insertions(+), 75 deletions(-)

New commits:
commit f6f79531d84f59188bbff3d97cef79140b2eb3ad
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Tue Feb 18 21:55:33 2025 +0100
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Wed Feb 19 22:42:01 2025 +0100

    vcl: Return ref in Formatter::GetOrCreateFormatter
    
    This makes it more obvious that it's non-null.
    Drop 2 corresponding `DBG_ASSERT`s that were
    checking exactly this.
    
    Change-Id: I5b2de299664d93b3ba71582a2c7907b17bbbc9b2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181912
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>

diff --git a/include/vcl/formatter.hxx b/include/vcl/formatter.hxx
index f7246767bb85..4e40fd43a8bb 100644
--- a/include/vcl/formatter.hxx
+++ b/include/vcl/formatter.hxx
@@ -198,7 +198,7 @@ public:
     sal_uLong   GetFormatKey() const                { return m_nFormatKey; }
     void    SetFormatKey(sal_uLong nFormatKey);
 
-    SvNumberFormatter*  GetOrCreateFormatter() const { return m_pFormatter ? 
m_pFormatter : const_cast<Formatter*>(this)->CreateFormatter(); }
+    SvNumberFormatter& GetOrCreateFormatter() const { return m_pFormatter ? 
*m_pFormatter : *const_cast<Formatter*>(this)->CreateFormatter(); }
 
     SvNumberFormatter*  GetFormatter() const    { return m_pFormatter; }
     void    SetFormatter(SvNumberFormatter* pFormatter, bool bResetFormat = 
true);
diff --git a/vcl/source/app/weldutils.cxx b/vcl/source/app/weldutils.cxx
index 92b421757e1e..801a76f4eda6 100644
--- a/vcl/source/app/weldutils.cxx
+++ b/vcl/source/app/weldutils.cxx
@@ -280,7 +280,7 @@ bool DoubleNumericFormatter::CheckText(const OUString& 
sText) const
 void DoubleNumericFormatter::ResetConformanceTester()
 {
     // the thousands and the decimal separator are language dependent
-    const SvNumberformat* pFormatEntry = 
GetOrCreateFormatter()->GetEntry(m_nFormatKey);
+    const SvNumberformat* pFormatEntry = 
GetOrCreateFormatter().GetEntry(m_nFormatKey);
 
     sal_Unicode cSeparatorThousand = ',';
     sal_Unicode cSeparatorDecimal = '.';
diff --git a/vcl/source/control/fmtfield.cxx b/vcl/source/control/fmtfield.cxx
index 3dc7f1ac9a29..3de297e380ef 100644
--- a/vcl/source/control/fmtfield.cxx
+++ b/vcl/source/control/fmtfield.cxx
@@ -281,7 +281,7 @@ void Formatter::SetFieldText(const OUString& rStr, const 
Selection& rNewSelectio
 
 void Formatter::SetTextFormatted(const OUString& rStr)
 {
-    SAL_INFO_IF(GetOrCreateFormatter()->IsTextFormat(m_nFormatKey), "svtools",
+    SAL_INFO_IF(GetOrCreateFormatter().IsTextFormat(m_nFormatKey), "svtools",
         "FormattedField::SetTextFormatted : valid only with text formats !");
 
     m_sCurrentTextValue = rStr;
@@ -291,13 +291,13 @@ void Formatter::SetTextFormatted(const OUString& rStr)
     // IsNumberFormat changes the format key parameter
     sal_uInt32 nTempFormatKey = static_cast< sal_uInt32 >( m_nFormatKey );
     if( IsUsingInputStringForFormatting() &&
-        GetOrCreateFormatter()->IsNumberFormat(m_sCurrentTextValue, 
nTempFormatKey, dNumber) )
+        GetOrCreateFormatter().IsNumberFormat(m_sCurrentTextValue, 
nTempFormatKey, dNumber) )
     {
-        sFormatted = GetOrCreateFormatter()->GetInputLineString(dNumber, 
m_nFormatKey);
+        sFormatted = GetOrCreateFormatter().GetInputLineString(dNumber, 
m_nFormatKey);
     }
     else
     {
-        GetOrCreateFormatter()->GetOutputString(m_sCurrentTextValue,
+        GetOrCreateFormatter().GetOutputString(m_sCurrentTextValue,
                                             m_nFormatKey,
                                             sFormatted,
                                             &m_pLastOutputColor);
@@ -507,7 +507,7 @@ void Formatter::SetFormatter(SvNumberFormatter* pFormatter, 
bool bResetFormat)
 
 OUString Formatter::GetFormat(LanguageType& eLang) const
 {
-    const SvNumberformat* pFormatEntry = 
GetOrCreateFormatter()->GetEntry(m_nFormatKey);
+    const SvNumberformat* pFormatEntry = 
GetOrCreateFormatter().GetEntry(m_nFormatKey);
     DBG_ASSERT(pFormatEntry != nullptr, "FormattedField::GetFormat: no number 
format for the given format key.");
     OUString sFormatString = pFormatEntry ? pFormatEntry->GetFormatstring() : 
OUString();
     eLang = pFormatEntry ? pFormatEntry->GetLanguage() : LANGUAGE_DONTKNOW;
@@ -517,13 +517,13 @@ OUString Formatter::GetFormat(LanguageType& eLang) const
 
 bool Formatter::SetFormat(const OUString& rFormatString, LanguageType eLang)
 {
-    sal_uInt32 nNewKey = GetOrCreateFormatter()->TestNewString(rFormatString, 
eLang);
+    sal_uInt32 nNewKey = GetOrCreateFormatter().TestNewString(rFormatString, 
eLang);
     if (nNewKey == NUMBERFORMAT_ENTRY_NOT_FOUND)
     {
         sal_Int32 nCheckPos;
         SvNumFormatType nType;
         OUString rFormat(rFormatString);
-        if (!GetOrCreateFormatter()->PutEntry(rFormat, nCheckPos, nType, 
nNewKey, eLang))
+        if (!GetOrCreateFormatter().PutEntry(rFormat, nCheckPos, nType, 
nNewKey, eLang))
             return false;
         DBG_ASSERT(nNewKey != NUMBERFORMAT_ENTRY_NOT_FOUND, 
"FormattedField::SetFormatString : PutEntry returned an invalid key !");
     }
@@ -535,25 +535,25 @@ bool Formatter::SetFormat(const OUString& rFormatString, 
LanguageType eLang)
 
 bool Formatter::GetThousandsSep() const
 {
-    DBG_ASSERT(!GetOrCreateFormatter()->IsTextFormat(m_nFormatKey),
+    DBG_ASSERT(!GetOrCreateFormatter().IsTextFormat(m_nFormatKey),
         "FormattedField::GetThousandsSep : Are you sure what you are doing 
when setting the precision of a text format?");
 
     bool bThousand, IsRed;
     sal_uInt16 nPrecision, nLeadingCnt;
-    GetOrCreateFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, 
IsRed, nPrecision, nLeadingCnt);
+    GetOrCreateFormatter().GetFormatSpecialInfo(m_nFormatKey, bThousand, 
IsRed, nPrecision, nLeadingCnt);
 
     return bThousand;
 }
 
 void Formatter::SetThousandsSep(bool _bUseSeparator)
 {
-    DBG_ASSERT(!GetOrCreateFormatter()->IsTextFormat(m_nFormatKey),
+    DBG_ASSERT(!GetOrCreateFormatter().IsTextFormat(m_nFormatKey),
         "FormattedField::SetThousandsSep : Are you sure what you are doing 
when setting the precision of a text format?");
 
     // get the current settings
     bool bThousand, IsRed;
     sal_uInt16 nPrecision, nLeadingCnt;
-    GetOrCreateFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, 
IsRed, nPrecision, nLeadingCnt);
+    GetOrCreateFormatter().GetFormatSpecialInfo(m_nFormatKey, bThousand, 
IsRed, nPrecision, nLeadingCnt);
     if (bThousand == _bUseSeparator)
         return;
 
@@ -562,12 +562,12 @@ void Formatter::SetThousandsSep(bool _bUseSeparator)
     GetFormat(eLang);
 
     // generate a new format ...
-    OUString sFmtDescription = 
GetOrCreateFormatter()->GenerateFormat(m_nFormatKey, eLang, _bUseSeparator, 
IsRed, nPrecision, nLeadingCnt);
+    OUString sFmtDescription = 
GetOrCreateFormatter().GenerateFormat(m_nFormatKey, eLang, _bUseSeparator, 
IsRed, nPrecision, nLeadingCnt);
     // ... and introduce it to the formatter
     sal_Int32 nCheckPos = 0;
     sal_uInt32 nNewKey;
     SvNumFormatType nType;
-    GetOrCreateFormatter()->PutEntry(sFmtDescription, nCheckPos, nType, 
nNewKey, eLang);
+    GetOrCreateFormatter().PutEntry(sFmtDescription, nCheckPos, nType, 
nNewKey, eLang);
 
     // set the new key
     ImplSetFormatKey(nNewKey);
@@ -576,25 +576,25 @@ void Formatter::SetThousandsSep(bool _bUseSeparator)
 
 sal_uInt16 Formatter::GetDecimalDigits() const
 {
-    DBG_ASSERT(!GetOrCreateFormatter()->IsTextFormat(m_nFormatKey),
+    DBG_ASSERT(!GetOrCreateFormatter().IsTextFormat(m_nFormatKey),
         "FormattedField::GetDecimalDigits : Are you sure what you are doing 
when setting the precision of a text format?");
 
     bool bThousand, IsRed;
     sal_uInt16 nPrecision, nLeadingCnt;
-    GetOrCreateFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, 
IsRed, nPrecision, nLeadingCnt);
+    GetOrCreateFormatter().GetFormatSpecialInfo(m_nFormatKey, bThousand, 
IsRed, nPrecision, nLeadingCnt);
 
     return nPrecision;
 }
 
 void Formatter::SetDecimalDigits(sal_uInt16 _nPrecision)
 {
-    DBG_ASSERT(!GetOrCreateFormatter()->IsTextFormat(m_nFormatKey),
+    DBG_ASSERT(!GetOrCreateFormatter().IsTextFormat(m_nFormatKey),
         "FormattedField::SetDecimalDigits : Are you sure what you are doing 
when setting the precision of a text format?");
 
     // get the current settings
     bool bThousand, IsRed;
     sal_uInt16 nPrecision, nLeadingCnt;
-    GetOrCreateFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, 
IsRed, nPrecision, nLeadingCnt);
+    GetOrCreateFormatter().GetFormatSpecialInfo(m_nFormatKey, bThousand, 
IsRed, nPrecision, nLeadingCnt);
     if (nPrecision == _nPrecision)
         return;
 
@@ -603,12 +603,12 @@ void Formatter::SetDecimalDigits(sal_uInt16 _nPrecision)
     GetFormat(eLang);
 
     // generate a new format ...
-    OUString sFmtDescription = 
GetOrCreateFormatter()->GenerateFormat(m_nFormatKey, eLang, bThousand, IsRed, 
_nPrecision, nLeadingCnt);
+    OUString sFmtDescription = 
GetOrCreateFormatter().GenerateFormat(m_nFormatKey, eLang, bThousand, IsRed, 
_nPrecision, nLeadingCnt);
     // ... and introduce it to the formatter
     sal_Int32 nCheckPos = 0;
     sal_uInt32 nNewKey;
     SvNumFormatType nType;
-    GetOrCreateFormatter()->PutEntry(sFmtDescription, nCheckPos, nType, 
nNewKey, eLang);
+    GetOrCreateFormatter().PutEntry(sFmtDescription, nCheckPos, nType, 
nNewKey, eLang);
 
     // set the new key
     ImplSetFormatKey(nNewKey);
@@ -741,8 +741,6 @@ void Formatter::ImplSetValue(double dVal, bool bForce)
     if (!bForce && (dVal == GetValue()))
         return;
 
-    DBG_ASSERT(GetOrCreateFormatter() != nullptr, 
"FormattedField::ImplSetValue : can't set a value without a formatter !");
-
     m_ValueState = valueDouble;
     UpdateCurrentValue(dVal);
 
@@ -753,23 +751,23 @@ void Formatter::ImplSetValue(double dVal, bool bForce)
     if (!aText.has_value())
     {
         OUString sNewText;
-        if (GetOrCreateFormatter()->IsTextFormat(m_nFormatKey))
+        if (GetOrCreateFormatter().IsTextFormat(m_nFormatKey))
         {
             // first convert the number as string in standard format
             OUString sTemp;
-            GetOrCreateFormatter()->GetOutputString(dVal, 0, sTemp, 
&m_pLastOutputColor);
+            GetOrCreateFormatter().GetOutputString(dVal, 0, sTemp, 
&m_pLastOutputColor);
             // then encode the string in the corresponding text format
-            GetOrCreateFormatter()->GetOutputString(sTemp, m_nFormatKey, 
sNewText, &m_pLastOutputColor);
+            GetOrCreateFormatter().GetOutputString(sTemp, m_nFormatKey, 
sNewText, &m_pLastOutputColor);
         }
         else
         {
             if( IsUsingInputStringForFormatting())
             {
-                sNewText = GetOrCreateFormatter()->GetInputLineString(dVal, 
m_nFormatKey);
+                sNewText = GetOrCreateFormatter().GetInputLineString(dVal, 
m_nFormatKey);
             }
             else
             {
-                GetOrCreateFormatter()->GetOutputString(dVal, m_nFormatKey, 
sNewText, &m_pLastOutputColor);
+                GetOrCreateFormatter().GetOutputString(dVal, m_nFormatKey, 
sNewText, &m_pLastOutputColor);
             }
         }
         aText = sNewText;
@@ -814,16 +812,14 @@ bool Formatter::ImplGetValue(double& dNewVal)
 
     if (!bUseExternalFormatterValue)
     {
-        DBG_ASSERT(GetOrCreateFormatter() != nullptr, 
"FormattedField::ImplGetValue : can't give you a current value without a 
formatter !");
-
         sal_uInt32 nFormatKey = m_nFormatKey; // IsNumberFormat changes the 
FormatKey!
 
-        if (GetOrCreateFormatter()->IsTextFormat(nFormatKey) && 
m_bTreatAsNumber)
+        if (GetOrCreateFormatter().IsTextFormat(nFormatKey) && 
m_bTreatAsNumber)
             // for detection of values like "1,1" in fields that are formatted 
as text
             nFormatKey = 0;
 
         // special treatment for percentage formatting
-        if (GetOrCreateFormatter()->GetType(m_nFormatKey) == 
SvNumFormatType::PERCENT)
+        if (GetOrCreateFormatter().GetType(m_nFormatKey) == 
SvNumFormatType::PERCENT)
         {
             // the language of our format
             LanguageType eLanguage = 
m_pFormatter->GetEntry(m_nFormatKey)->GetLanguage();
@@ -840,7 +836,7 @@ bool Formatter::ImplGetValue(double& dNewVal)
             // into 0.03. Without this, the formatter would give us the double 
3 for an input '3',
             // which equals 300 percent.
         }
-        if (!GetOrCreateFormatter()->IsNumberFormat(sText, nFormatKey, 
dNewVal))
+        if (!GetOrCreateFormatter().IsNumberFormat(sText, nFormatKey, dNewVal))
             return false;
     }
 
@@ -1021,7 +1017,7 @@ void DoubleNumericField::ResetConformanceTester()
 {
     // the thousands and the decimal separator are language dependent
     Formatter& rFormatter = GetFormatter();
-    const SvNumberformat* pFormatEntry = 
rFormatter.GetOrCreateFormatter()->GetEntry(rFormatter.GetFormatKey());
+    const SvNumberformat* pFormatEntry = 
rFormatter.GetOrCreateFormatter().GetEntry(rFormatter.GetFormatKey());
 
     sal_Unicode cSeparatorThousand = ',';
     sal_Unicode cSeparatorDecimal = '.';
@@ -1267,7 +1263,7 @@ bool FormattedField::EventNotify(NotifyEvent& rNEvt)
             case KEY_PAGEDOWN:
             {
                 Formatter& rFormatter = GetFormatter();
-                if (!nMod && 
rFormatter.GetOrCreateFormatter()->IsTextFormat(rFormatter.GetFormatKey()))
+                if (!nMod && 
rFormatter.GetOrCreateFormatter().IsTextFormat(rFormatter.GetFormatKey()))
                 {
                     // the base class would translate this into calls to 
Up/Down/First/Last,
                     // but we don't want this if we are text-formatted
@@ -1285,7 +1281,7 @@ bool FormattedField::EventNotify(NotifyEvent& rNEvt)
             const CommandWheelData* pData = 
rNEvt.GetCommandEvent()->GetWheelData();
             Formatter& rFormatter = GetFormatter();
             if ((pData->GetMode() == CommandWheelMode::SCROLL) &&
-                
rFormatter.GetOrCreateFormatter()->IsTextFormat(rFormatter.GetFormatKey()))
+                
rFormatter.GetOrCreateFormatter().IsTextFormat(rFormatter.GetFormatKey()))
             {
                 // same as above : prevent the base class from doing 
Up/Down-calls
                 // (normally I should put this test into the Up/Down methods 
itself, shouldn't I ?)
commit 20e1c3d2f35afba1adf0e5852a83a753efaf500d
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Tue Feb 18 20:29:20 2025 +0100
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Wed Feb 19 22:41:50 2025 +0100

    tdf#130857 Let Formatter:m_aOutputHdl convert double to text
    
    So far, the Formatter:m_aOutputHdl output handler set via
    Formatter::SetOutputHdl did not receive any parameter
    and had the responsibility to set the text based on
    the current value, i.e. first retrieve the current
    value, then convert it to a text representation, and
    then set that text in the formatter.
    
    Change semantics so that the method instead receives
    the (double) value to format as a parameter and
    returns the formatted string.
    
    Passing the current value as a double and using the
    returned string to update the text is now the responsibility
    of the only caller, Formatter::ImplSetValue.
    
    Adjust the naming accordingly:
    
    * Formatter:m_aOutputHdl -> Formatter::m_aFormatValueHdl
    * Formatter::SetOutputHdl -> Formatter::SetFormatValueHdl
    
    This is similar to the change done elsewhere in
    
        commit 76396a371eb7dfef79963d00fea54a989f54fbbc
        Author: Michael Weghorn <m.wegh...@posteo.de>
        Date:   Sat Feb 15 13:44:50 2025 +0100
    
            tdf#130857 weld: Abstract from "input"/"output" SpinButton signals
    
    (and changes referenced from its commit message)
    and is one step towards supporting value <-> text
    conversion in QtInstanceFormattedSpinButton as well.
    
    No change in behavior is intended by this commit.
    
    Change-Id: I6b3fbccc89b89446a1ea367a80aeed3a7b583298
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181911
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>

diff --git a/framework/source/uielement/spinfieldtoolbarcontroller.cxx 
b/framework/source/uielement/spinfieldtoolbarcontroller.cxx
index 65ed36e3be9b..13ffcdc0cb44 100644
--- a/framework/source/uielement/spinfieldtoolbarcontroller.cxx
+++ b/framework/source/uielement/spinfieldtoolbarcontroller.cxx
@@ -61,7 +61,7 @@ public:
     OUString get_entry_text() const { return m_xWidget->get_text(); }
 
     DECL_LINK(ValueChangedHdl, weld::FormattedSpinButton&, void);
-    DECL_LINK(FormatOutputHdl, LinkParamNone*, bool);
+    DECL_LINK(FormatOutputHdl, double, std::optional<OUString>);
     DECL_LINK(ParseInputHdl, double*, TriState);
     DECL_LINK(ModifyHdl, weld::Entry&, void);
     DECL_LINK(ActivateHdl, weld::Entry&, bool);
@@ -84,7 +84,7 @@ SpinfieldControl::SpinfieldControl(vcl::Window* pParent, 
SpinfieldToolbarControl
     m_xWidget->connect_focus_in(LINK(this, SpinfieldControl, FocusInHdl));
     m_xWidget->connect_focus_out(LINK(this, SpinfieldControl, FocusOutHdl));
     Formatter& rFormatter = m_xWidget->GetFormatter();
-    rFormatter.SetOutputHdl(LINK(this, SpinfieldControl, FormatOutputHdl));
+    rFormatter.SetFormatValueHdl(LINK(this, SpinfieldControl, 
FormatOutputHdl));
     rFormatter.SetInputHdl(LINK(this, SpinfieldControl, ParseInputHdl));
     m_xWidget->connect_value_changed(LINK(this, SpinfieldControl, 
ValueChangedHdl));
     m_xWidget->connect_changed(LINK(this, SpinfieldControl, ModifyHdl));
@@ -156,11 +156,9 @@ IMPL_LINK_NOARG(SpinfieldControl, ActivateHdl, 
weld::Entry&, bool)
     return bConsumed;
 }
 
-IMPL_LINK_NOARG(SpinfieldControl, FormatOutputHdl, LinkParamNone*, bool)
+IMPL_LINK(SpinfieldControl, FormatOutputHdl, double, fValue, 
std::optional<OUString>)
 {
-    OUString aText = 
m_pSpinfieldToolbarController->FormatOutputString(m_xWidget->GetFormatter().GetValue());
-    m_xWidget->set_text(aText);
-    return true;
+    return 
std::optional<OUString>(m_pSpinfieldToolbarController->FormatOutputString(fValue));
 }
 
 SpinfieldToolbarController::SpinfieldToolbarController(
diff --git a/include/vcl/formatter.hxx b/include/vcl/formatter.hxx
index cb1665459904..f7246767bb85 100644
--- a/include/vcl/formatter.hxx
+++ b/include/vcl/formatter.hxx
@@ -144,7 +144,7 @@ protected:
     bool                m_bUseInputStringForFormatting;
 
     Link<double*, TriState> m_aInputHdl;
-    Link<LinkParamNone*, bool> m_aOutputHdl;
+    Link<double, std::optional<OUString>> m_aFormatValueHdl;
 
 public:
     Formatter();
@@ -243,7 +243,7 @@ public:
     void    TreatAsNumber(bool bDoSo) { m_bTreatAsNumber = bDoSo; }
 
     void    SetInputHdl(const Link<double*,TriState>& rLink) { m_aInputHdl = 
rLink; }
-    void    SetOutputHdl(const Link<LinkParamNone*, bool>& rLink) { 
m_aOutputHdl = rLink; }
+    void    SetFormatValueHdl(const Link<double, std::optional<OUString>>& 
rLink) { m_aFormatValueHdl = rLink; }
 public:
 
     //The following methods are interesting, if m_bTreatAsNumber is set to 
sal_False
diff --git a/include/vcl/weldutils.hxx b/include/vcl/weldutils.hxx
index dcf7128c2b7f..05a8ba2b22bd 100644
--- a/include/vcl/weldutils.hxx
+++ b/include/vcl/weldutils.hxx
@@ -284,7 +284,7 @@ public:
     SAL_DLLPRIVATE virtual ~LongCurrencyFormatter() override;
 
 private:
-    DECL_DLLPRIVATE_LINK(FormatOutputHdl, LinkParamNone*, bool);
+    DECL_DLLPRIVATE_LINK(FormatOutputHdl, double, std::optional<OUString>);
     DECL_DLLPRIVATE_LINK(ParseInputHdl, double*, TriState);
 
     SAL_DLLPRIVATE void Init();
@@ -312,7 +312,7 @@ public:
     virtual ~TimeFormatter() override;
 
 private:
-    DECL_DLLPRIVATE_LINK(FormatOutputHdl, LinkParamNone*, bool);
+    DECL_DLLPRIVATE_LINK(FormatOutputHdl, double, std::optional<OUString>);
     DECL_DLLPRIVATE_LINK(ParseInputHdl, double*, TriState);
     DECL_DLLPRIVATE_LINK(CursorChangedHdl, weld::Entry&, void);
 
@@ -345,7 +345,7 @@ public:
     virtual ~DateFormatter() override;
 
 private:
-    DECL_DLLPRIVATE_LINK(FormatOutputHdl, LinkParamNone*, bool);
+    DECL_DLLPRIVATE_LINK(FormatOutputHdl, double, std::optional<OUString>);
     DECL_DLLPRIVATE_LINK(ParseInputHdl, double*, TriState);
     DECL_DLLPRIVATE_LINK(CursorChangedHdl, weld::Entry&, void);
 
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index 19b292e500ab..5be5314157c9 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -680,7 +680,7 @@ protected:
 private:
     DECL_LINK(UpDownHdl, SpinField&, void);
     DECL_LINK(LoseFocusHdl, Control&, void);
-    DECL_LINK(OutputHdl, LinkParamNone*, bool);
+    DECL_LINK(OutputHdl, double, std::optional<OUString>);
     DECL_LINK(InputHdl, double*, TriState);
     DECL_LINK(ActivateHdl, Edit&, bool);
 
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index ca2078879c26..89c024ab220d 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -5855,7 +5855,7 @@ 
SalInstanceSpinButton::SalInstanceSpinButton(FormattedField* pButton, SalInstanc
     m_xButton->SetUpHdl(LINK(this, SalInstanceSpinButton, UpDownHdl));
     m_xButton->SetDownHdl(LINK(this, SalInstanceSpinButton, UpDownHdl));
     m_xButton->SetLoseFocusHdl(LINK(this, SalInstanceSpinButton, 
LoseFocusHdl));
-    m_rFormatter.SetOutputHdl(LINK(this, SalInstanceSpinButton, OutputHdl));
+    m_rFormatter.SetFormatValueHdl(LINK(this, SalInstanceSpinButton, 
OutputHdl));
     m_rFormatter.SetInputHdl(LINK(this, SalInstanceSpinButton, InputHdl));
     if (Edit* pEdit = m_xButton->GetSubEdit())
         pEdit->SetActivateHdl(LINK(this, SalInstanceSpinButton, ActivateHdl));
@@ -5914,7 +5914,7 @@ SalInstanceSpinButton::~SalInstanceSpinButton()
     else
         m_xButton->SetActivateHdl(Link<Edit&, bool>());
     m_rFormatter.SetInputHdl(Link<double*, TriState>());
-    m_rFormatter.SetOutputHdl(Link<LinkParamNone*, bool>());
+    m_rFormatter.SetFormatValueHdl(Link<double, std::optional<OUString>>());
     m_xButton->SetLoseFocusHdl(Link<Control&, void>());
     m_xButton->SetDownHdl(Link<SpinField&, void>());
     m_xButton->SetUpHdl(Link<SpinField&, void>());
@@ -5931,14 +5931,9 @@ IMPL_LINK_NOARG(SalInstanceSpinButton, UpDownHdl, 
SpinField&, void) { signal_val
 
 IMPL_LINK_NOARG(SalInstanceSpinButton, LoseFocusHdl, Control&, void) { 
signal_value_changed(); }
 
-IMPL_LINK_NOARG(SalInstanceSpinButton, OutputHdl, LinkParamNone*, bool)
+IMPL_LINK(SalInstanceSpinButton, OutputHdl, double, fValue, 
std::optional<OUString>)
 {
-    std::optional<OUString> aText = 
format_floating_point_value(get_floating_point_value());
-    if (!aText.has_value())
-        return false;
-
-    set_text(aText.value());
-    return true;
+    return format_floating_point_value(fValue);
 }
 
 IMPL_LINK(SalInstanceSpinButton, InputHdl, double*, pResult, TriState)
diff --git a/vcl/source/app/weldutils.cxx b/vcl/source/app/weldutils.cxx
index 9cc759dcdf12..92b421757e1e 100644
--- a/vcl/source/app/weldutils.cxx
+++ b/vcl/source/app/weldutils.cxx
@@ -317,7 +317,7 @@ 
LongCurrencyFormatter::LongCurrencyFormatter(weld::FormattedSpinButton& rSpinBut
 
 void LongCurrencyFormatter::Init()
 {
-    SetOutputHdl(LINK(this, LongCurrencyFormatter, FormatOutputHdl));
+    SetFormatValueHdl(LINK(this, LongCurrencyFormatter, FormatOutputHdl));
     SetInputHdl(LINK(this, LongCurrencyFormatter, ParseInputHdl));
 }
 
@@ -357,7 +357,7 @@ void TimeFormatter::Init()
 {
     DisableRemainderFactor(); //so with hh::mm::ss, incrementing mm will not 
reset ss
 
-    SetOutputHdl(LINK(this, TimeFormatter, FormatOutputHdl));
+    SetFormatValueHdl(LINK(this, TimeFormatter, FormatOutputHdl));
     SetInputHdl(LINK(this, TimeFormatter, ParseInputHdl));
 
     SetMin(tools::Time(0, 0));
@@ -441,7 +441,7 @@ DateFormatter::DateFormatter(weld::Entry& rEntry)
 
 void DateFormatter::Init()
 {
-    SetOutputHdl(LINK(this, DateFormatter, FormatOutputHdl));
+    SetFormatValueHdl(LINK(this, DateFormatter, FormatOutputHdl));
     SetInputHdl(LINK(this, DateFormatter, ParseInputHdl));
 
     SetMin(Date(1, 1, 1900));
diff --git a/vcl/source/control/field2.cxx b/vcl/source/control/field2.cxx
index ac47e1166567..fc0cab000da8 100644
--- a/vcl/source/control/field2.cxx
+++ b/vcl/source/control/field2.cxx
@@ -2247,11 +2247,9 @@ namespace weld
         return ::DateFormatter::FormatDate(Date(nValue), m_eFormat, 
rLocaleData, m_aStaticFormatter);
     }
 
-    IMPL_LINK_NOARG(DateFormatter, FormatOutputHdl, LinkParamNone*, bool)
+    IMPL_LINK(DateFormatter, FormatOutputHdl, double, fValue, 
std::optional<OUString>)
     {
-        OUString sText = FormatNumber(GetValue());
-        ImplSetTextImpl(sText, nullptr);
-        return true;
+        return std::optional<OUString>(FormatNumber(fValue));
     }
 
     IMPL_LINK(DateFormatter, ParseInputHdl, double*, result, TriState)
@@ -3145,11 +3143,9 @@ namespace weld
         return ::TimeFormatter::FormatTime(ConvertValue(nValue), m_eFormat, 
m_eTimeFormat, m_bDuration, rLocaleData);
     }
 
-    IMPL_LINK_NOARG(TimeFormatter, FormatOutputHdl, LinkParamNone*, bool)
+    IMPL_LINK(TimeFormatter, FormatOutputHdl, double, fValue, 
std::optional<OUString>)
     {
-        OUString sText = FormatNumber(GetValue());
-        ImplSetTextImpl(sText, nullptr);
-        return true;
+        return std::optional<OUString>(FormatNumber(fValue));
     }
 
     IMPL_LINK(TimeFormatter, ParseInputHdl, double*, result, TriState)
diff --git a/vcl/source/control/fmtfield.cxx b/vcl/source/control/fmtfield.cxx
index 0210f4e8727a..3dc7f1ac9a29 100644
--- a/vcl/source/control/fmtfield.cxx
+++ b/vcl/source/control/fmtfield.cxx
@@ -746,7 +746,11 @@ void Formatter::ImplSetValue(double dVal, bool bForce)
     m_ValueState = valueDouble;
     UpdateCurrentValue(dVal);
 
-    if (!m_aOutputHdl.IsSet() || !m_aOutputHdl.Call(nullptr))
+    std::optional<OUString> aText;
+    if (m_aFormatValueHdl.IsSet())
+        aText = m_aFormatValueHdl.Call(dVal);
+
+    if (!aText.has_value())
     {
         OUString sNewText;
         if (GetOrCreateFormatter()->IsTextFormat(m_nFormatKey))
@@ -768,10 +772,13 @@ void Formatter::ImplSetValue(double dVal, bool bForce)
                 GetOrCreateFormatter()->GetOutputString(dVal, m_nFormatKey, 
sNewText, &m_pLastOutputColor);
             }
         }
-        ImplSetTextImpl(sNewText, nullptr);
-        DBG_ASSERT(CheckText(sNewText), "FormattedField::ImplSetValue : 
formatted string doesn't match the criteria !");
+        aText = sNewText;
     }
 
+    assert(aText.has_value());
+    ImplSetTextImpl(*aText, nullptr);
+    DBG_ASSERT(CheckText(*aText), "FormattedField::ImplSetValue : formatted 
string doesn't match the criteria !");
+
     m_ValueState = valueDouble;
 }
 
diff --git a/vcl/source/control/longcurr.cxx b/vcl/source/control/longcurr.cxx
index 39f3e295147a..a1698afb1f90 100644
--- a/vcl/source/control/longcurr.cxx
+++ b/vcl/source/control/longcurr.cxx
@@ -211,11 +211,10 @@ bool ImplCurrencyGetValue( const OUString& rStr, BigInt& 
rValue,
 
 namespace weld
 {
-    IMPL_LINK_NOARG(LongCurrencyFormatter, FormatOutputHdl, LinkParamNone*, 
bool)
+    IMPL_LINK(LongCurrencyFormatter, FormatOutputHdl, double, fValue, 
std::optional<OUString>)
     {
         const LocaleDataWrapper& rLocaleDataWrapper = 
Application::GetSettings().GetLocaleDataWrapper();
         const OUString& rCurrencySymbol = !m_aCurrencySymbol.isEmpty() ? 
m_aCurrencySymbol : rLocaleDataWrapper.getCurrSymbol();
-        double fValue = GetValue();
         sal_uInt16 nDecimalDigits = GetDecimalDigits();
         if (nDecimalDigits)
         {
@@ -223,8 +222,7 @@ namespace weld
             fValue = std::round(fValue * 
weld::SpinButton::Power10(nDecimalDigits));
         }
         OUString aText = ImplGetCurr(rLocaleDataWrapper, fValue, 
GetDecimalDigits(), rCurrencySymbol, m_bThousandSep);
-        ImplSetTextImpl(aText, nullptr);
-        return true;
+        return std::optional<OUString>(aText);
     }
 
     IMPL_LINK(LongCurrencyFormatter, ParseInputHdl, double*, result, TriState)

Reply via email to