tdf#130857 Formatter: Pass string to convert to double
Instead of letting the implementations set for
Formatter::m_aInputHdl via Formatter::SetInputHdl
always retrieve the current text and parse
that one, pass the text to convert as a parameter
instead.
Introduce a new struct Formatter::ParseResult
so that both, the state (which describes whether
parsing was successful and/or a handler was set)
and the value can still be returned at the same time.
(Link/The handlers only supports a single param. So far,
the state was returned by the function result and
the value was returned via an out param, but the
single param is now used for an input param to pass the
text.)
Make it the responsibility of Formatter::ImplGetValue
to pass the current text instead of having the handlers
read it themselves.
Rename the members accordingly:
* Formatter::m_aInputHdl -> Formatter:m_aParseTextHdl
* Formatter::SetInputHdl -> Formatter::SetParseTextHdl
This is similar to
Change-Id: I6b3fbccc89b89446a1ea367a80aeed3a7b583298
Author: Michael Weghorn <m.weghorn@posteo.de>
Date: Tue Feb 18 20:29:20 2025 +0100
tdf#130857 Let Formatter:m_aOutputHdl convert double to text
(but for the conversion the other way around) and
commit 15ad64a412
Author: Michael Weghorn <m.weghorn@posteo.de>
Date: Sat Feb 15 11:22:54 2025 +0100
tdf#130857 weld: Let SpinButton input hdl only parse value from string
(which is a similar change, but in weld::SpinButton).
No change in behavior is intended by this change
by itself.
The primary motivation is to allow reusing the
logic to convert a string to a value in order
to implement QtDoubleSpinBox::valueFromText
for QtInstanceFormattedSpinButton.
Change-Id: If6837409aadbe9cc37fdbb4c0650f5e1305229f7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181942
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
This commit is contained in:
@@ -62,7 +62,7 @@ public:
|
||||
|
||||
DECL_LINK(ValueChangedHdl, weld::FormattedSpinButton&, void);
|
||||
DECL_LINK(FormatOutputHdl, double, std::optional<OUString>);
|
||||
DECL_LINK(ParseInputHdl, double*, TriState);
|
||||
DECL_STATIC_LINK(SpinfieldControl, ParseInputHdl, const OUString&, Formatter::ParseResult);
|
||||
DECL_LINK(ModifyHdl, weld::Entry&, void);
|
||||
DECL_LINK(ActivateHdl, weld::Entry&, bool);
|
||||
DECL_LINK(FocusInHdl, weld::Widget&, void);
|
||||
@@ -85,7 +85,7 @@ SpinfieldControl::SpinfieldControl(vcl::Window* pParent, SpinfieldToolbarControl
|
||||
m_xWidget->connect_focus_out(LINK(this, SpinfieldControl, FocusOutHdl));
|
||||
Formatter& rFormatter = m_xWidget->GetFormatter();
|
||||
rFormatter.SetFormatValueHdl(LINK(this, SpinfieldControl, FormatOutputHdl));
|
||||
rFormatter.SetInputHdl(LINK(this, SpinfieldControl, ParseInputHdl));
|
||||
rFormatter.SetParseTextHdl(LINK(this, SpinfieldControl, ParseInputHdl));
|
||||
m_xWidget->connect_value_changed(LINK(this, SpinfieldControl, ValueChangedHdl));
|
||||
m_xWidget->connect_changed(LINK(this, SpinfieldControl, ModifyHdl));
|
||||
m_xWidget->connect_activate(LINK(this, SpinfieldControl, ActivateHdl));
|
||||
@@ -103,10 +103,10 @@ IMPL_LINK(SpinfieldControl, KeyInputHdl, const ::KeyEvent&, rKEvt, bool)
|
||||
return ChildKeyInput(rKEvt);
|
||||
}
|
||||
|
||||
IMPL_LINK(SpinfieldControl, ParseInputHdl, double*, result, TriState)
|
||||
IMPL_STATIC_LINK(SpinfieldControl, ParseInputHdl, const OUString&, rText, Formatter::ParseResult)
|
||||
{
|
||||
*result = m_xWidget->get_text().toDouble();
|
||||
return TRISTATE_TRUE;
|
||||
const double fValue = rText.toDouble();
|
||||
return Formatter::ParseResult(TRISTATE_TRUE, fValue);
|
||||
}
|
||||
|
||||
SpinfieldControl::~SpinfieldControl()
|
||||
|
@@ -99,6 +99,28 @@ public:
|
||||
UNLESS_MERGELIBS(VCL_DLLPUBLIC) static SvNumberFormatter* GetFormatter();
|
||||
};
|
||||
|
||||
/**
|
||||
* This struct gets returned by the handlers that can be set via Formatter::SetParseTextHdl
|
||||
* and describes the result of trying to convert text to a double value.
|
||||
*/
|
||||
struct ParseResult
|
||||
{
|
||||
ParseResult()
|
||||
: ParseResult(TRISTATE_INDET, 0.0)
|
||||
{
|
||||
}
|
||||
|
||||
ParseResult(TriState eState, double fValue)
|
||||
: m_eState(eState)
|
||||
, m_fValue(fValue)
|
||||
{
|
||||
}
|
||||
|
||||
TriState m_eState;
|
||||
// if m_eState is TRISTATE_TRUE, this contains the value
|
||||
double m_fValue;
|
||||
};
|
||||
|
||||
protected:
|
||||
OUString m_sLastValidText;
|
||||
// Has nothing to do with the current value. It is the last text, which was valid at input (checked by CheckText,
|
||||
@@ -143,7 +165,7 @@ protected:
|
||||
|
||||
bool m_bUseInputStringForFormatting;
|
||||
|
||||
Link<double*, TriState> m_aInputHdl;
|
||||
Link<const OUString&, ParseResult> m_aParseTextHdl;
|
||||
Link<double, std::optional<OUString>> m_aFormatValueHdl;
|
||||
|
||||
public:
|
||||
@@ -242,7 +264,7 @@ public:
|
||||
bool TreatingAsNumber() const { return m_bTreatAsNumber; }
|
||||
void TreatAsNumber(bool bDoSo) { m_bTreatAsNumber = bDoSo; }
|
||||
|
||||
void SetInputHdl(const Link<double*,TriState>& rLink) { m_aInputHdl = rLink; }
|
||||
void SetParseTextHdl(const Link<const OUString&, ParseResult>& rLink) { m_aParseTextHdl = rLink; }
|
||||
void SetFormatValueHdl(const Link<double, std::optional<OUString>>& rLink) { m_aFormatValueHdl = rLink; }
|
||||
|
||||
OUString FormatValue(double fValue);
|
||||
|
@@ -285,7 +285,7 @@ public:
|
||||
|
||||
private:
|
||||
DECL_DLLPRIVATE_LINK(FormatOutputHdl, double, std::optional<OUString>);
|
||||
DECL_DLLPRIVATE_LINK(ParseInputHdl, double*, TriState);
|
||||
DECL_DLLPRIVATE_LINK(ParseInputHdl, const OUString&, Formatter::ParseResult);
|
||||
|
||||
SAL_DLLPRIVATE void Init();
|
||||
|
||||
@@ -313,7 +313,7 @@ public:
|
||||
|
||||
private:
|
||||
DECL_DLLPRIVATE_LINK(FormatOutputHdl, double, std::optional<OUString>);
|
||||
DECL_DLLPRIVATE_LINK(ParseInputHdl, double*, TriState);
|
||||
DECL_DLLPRIVATE_LINK(ParseInputHdl, const OUString&, Formatter::ParseResult);
|
||||
DECL_DLLPRIVATE_LINK(CursorChangedHdl, weld::Entry&, void);
|
||||
|
||||
SAL_DLLPRIVATE void Init();
|
||||
@@ -346,7 +346,7 @@ public:
|
||||
|
||||
private:
|
||||
DECL_DLLPRIVATE_LINK(FormatOutputHdl, double, std::optional<OUString>);
|
||||
DECL_DLLPRIVATE_LINK(ParseInputHdl, double*, TriState);
|
||||
DECL_DLLPRIVATE_LINK(ParseInputHdl, const OUString&, Formatter::ParseResult);
|
||||
DECL_DLLPRIVATE_LINK(CursorChangedHdl, weld::Entry&, void);
|
||||
|
||||
SAL_DLLPRIVATE void Init();
|
||||
|
@@ -681,7 +681,7 @@ private:
|
||||
DECL_LINK(UpDownHdl, SpinField&, void);
|
||||
DECL_LINK(LoseFocusHdl, Control&, void);
|
||||
DECL_LINK(OutputHdl, double, std::optional<OUString>);
|
||||
DECL_LINK(InputHdl, double*, TriState);
|
||||
DECL_LINK(InputHdl, const OUString&, Formatter::ParseResult);
|
||||
DECL_LINK(ActivateHdl, Edit&, bool);
|
||||
|
||||
public:
|
||||
|
@@ -5856,7 +5856,7 @@ SalInstanceSpinButton::SalInstanceSpinButton(FormattedField* pButton, SalInstanc
|
||||
m_xButton->SetDownHdl(LINK(this, SalInstanceSpinButton, UpDownHdl));
|
||||
m_xButton->SetLoseFocusHdl(LINK(this, SalInstanceSpinButton, LoseFocusHdl));
|
||||
m_rFormatter.SetFormatValueHdl(LINK(this, SalInstanceSpinButton, OutputHdl));
|
||||
m_rFormatter.SetInputHdl(LINK(this, SalInstanceSpinButton, InputHdl));
|
||||
m_rFormatter.SetParseTextHdl(LINK(this, SalInstanceSpinButton, InputHdl));
|
||||
if (Edit* pEdit = m_xButton->GetSubEdit())
|
||||
pEdit->SetActivateHdl(LINK(this, SalInstanceSpinButton, ActivateHdl));
|
||||
else
|
||||
@@ -5913,7 +5913,7 @@ SalInstanceSpinButton::~SalInstanceSpinButton()
|
||||
pEdit->SetActivateHdl(Link<Edit&, bool>());
|
||||
else
|
||||
m_xButton->SetActivateHdl(Link<Edit&, bool>());
|
||||
m_rFormatter.SetInputHdl(Link<double*, TriState>());
|
||||
m_rFormatter.SetParseTextHdl(Link<const OUString&, Formatter::ParseResult>());
|
||||
m_rFormatter.SetFormatValueHdl(Link<double, std::optional<OUString>>());
|
||||
m_xButton->SetLoseFocusHdl(Link<Control&, void>());
|
||||
m_xButton->SetDownHdl(Link<SpinField&, void>());
|
||||
@@ -5936,13 +5936,12 @@ IMPL_LINK(SalInstanceSpinButton, OutputHdl, double, fValue, std::optional<OUStri
|
||||
return format_floating_point_value(fValue);
|
||||
}
|
||||
|
||||
IMPL_LINK(SalInstanceSpinButton, InputHdl, double*, pResult, TriState)
|
||||
IMPL_LINK(SalInstanceSpinButton, InputHdl, const OUString&, rText, Formatter::ParseResult)
|
||||
{
|
||||
double fResult;
|
||||
TriState eRet = parse_text(get_text(), &fResult);
|
||||
if (eRet == TRISTATE_TRUE)
|
||||
*pResult = fResult;
|
||||
return eRet;
|
||||
double fResult = 0;
|
||||
TriState eRet = parse_text(rText, &fResult);
|
||||
|
||||
return Formatter::ParseResult(eRet, fResult);
|
||||
}
|
||||
|
||||
SalInstanceFormattedSpinButton::SalInstanceFormattedSpinButton(FormattedField* pButton,
|
||||
|
@@ -318,7 +318,7 @@ LongCurrencyFormatter::LongCurrencyFormatter(weld::FormattedSpinButton& rSpinBut
|
||||
void LongCurrencyFormatter::Init()
|
||||
{
|
||||
SetFormatValueHdl(LINK(this, LongCurrencyFormatter, FormatOutputHdl));
|
||||
SetInputHdl(LINK(this, LongCurrencyFormatter, ParseInputHdl));
|
||||
SetParseTextHdl(LINK(this, LongCurrencyFormatter, ParseInputHdl));
|
||||
}
|
||||
|
||||
void LongCurrencyFormatter::SetUseThousandSep(bool b)
|
||||
@@ -358,7 +358,7 @@ void TimeFormatter::Init()
|
||||
DisableRemainderFactor(); //so with hh::mm::ss, incrementing mm will not reset ss
|
||||
|
||||
SetFormatValueHdl(LINK(this, TimeFormatter, FormatOutputHdl));
|
||||
SetInputHdl(LINK(this, TimeFormatter, ParseInputHdl));
|
||||
SetParseTextHdl(LINK(this, TimeFormatter, ParseInputHdl));
|
||||
|
||||
SetMin(tools::Time(0, 0));
|
||||
SetMax(tools::Time(23, 59, 59, 999999999));
|
||||
@@ -442,7 +442,7 @@ DateFormatter::DateFormatter(weld::Entry& rEntry)
|
||||
void DateFormatter::Init()
|
||||
{
|
||||
SetFormatValueHdl(LINK(this, DateFormatter, FormatOutputHdl));
|
||||
SetInputHdl(LINK(this, DateFormatter, ParseInputHdl));
|
||||
SetParseTextHdl(LINK(this, DateFormatter, ParseInputHdl));
|
||||
|
||||
SetMin(Date(1, 1, 1900));
|
||||
SetMax(Date(31, 12, 2200));
|
||||
|
@@ -2252,17 +2252,19 @@ namespace weld
|
||||
return std::optional<OUString>(FormatNumber(fValue));
|
||||
}
|
||||
|
||||
IMPL_LINK(DateFormatter, ParseInputHdl, double*, result, TriState)
|
||||
IMPL_LINK(DateFormatter, ParseInputHdl, const OUString&, rText, Formatter::ParseResult)
|
||||
{
|
||||
const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper();
|
||||
|
||||
Date aResult(Date::EMPTY);
|
||||
bool bRet = ::DateFormatter::TextToDate(GetEntryText(), aResult, ResolveSystemFormat(m_eFormat, rLocaleDataWrapper),
|
||||
bool bRet = ::DateFormatter::TextToDate(rText, aResult, ResolveSystemFormat(m_eFormat, rLocaleDataWrapper),
|
||||
rLocaleDataWrapper, GetCalendarWrapper());
|
||||
if (bRet)
|
||||
*result = aResult.GetDate();
|
||||
|
||||
return bRet ? TRISTATE_TRUE : TRISTATE_FALSE;
|
||||
double fValue = 0;
|
||||
if (bRet)
|
||||
fValue = aResult.GetDate();
|
||||
|
||||
return Formatter::ParseResult(bRet ? TRISTATE_TRUE : TRISTATE_FALSE, fValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3148,16 +3150,17 @@ namespace weld
|
||||
return std::optional<OUString>(FormatNumber(fValue));
|
||||
}
|
||||
|
||||
IMPL_LINK(TimeFormatter, ParseInputHdl, double*, result, TriState)
|
||||
IMPL_LINK(TimeFormatter, ParseInputHdl, const OUString&, rText, Formatter::ParseResult)
|
||||
{
|
||||
const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper();
|
||||
|
||||
double fValue = 0.0;
|
||||
tools::Time aResult(tools::Time::EMPTY);
|
||||
bool bRet = ::TimeFormatter::TextToTime(GetEntryText(), aResult, m_eFormat, m_bDuration, rLocaleDataWrapper);
|
||||
bool bRet = ::TimeFormatter::TextToTime(rText, aResult, m_eFormat, m_bDuration, rLocaleDataWrapper);
|
||||
if (bRet)
|
||||
*result = ConvertValue(aResult);
|
||||
fValue = ConvertValue(aResult);
|
||||
|
||||
return bRet ? TRISTATE_TRUE : TRISTATE_FALSE;
|
||||
return Formatter::ParseResult(bRet ? TRISTATE_TRUE : TRISTATE_FALSE, fValue);
|
||||
}
|
||||
|
||||
IMPL_LINK(TimeFormatter, CursorChangedHdl, weld::Entry&, rEntry, void)
|
||||
|
@@ -800,15 +800,14 @@ bool Formatter::ImplGetValue(double& dNewVal)
|
||||
return true;
|
||||
|
||||
bool bUseExternalFormatterValue = false;
|
||||
if (m_aInputHdl.IsSet())
|
||||
if (m_aParseTextHdl.IsSet())
|
||||
{
|
||||
double fResult;
|
||||
auto eState = m_aInputHdl.Call(&fResult);
|
||||
bUseExternalFormatterValue = eState != TRISTATE_INDET;
|
||||
ParseResult aResult = m_aParseTextHdl.Call(sText);
|
||||
bUseExternalFormatterValue = aResult.m_eState != TRISTATE_INDET;
|
||||
if (bUseExternalFormatterValue)
|
||||
{
|
||||
if (eState == TRISTATE_TRUE)
|
||||
dNewVal = fResult;
|
||||
if (aResult.m_eState == TRISTATE_TRUE)
|
||||
dNewVal = aResult.m_fValue;
|
||||
else
|
||||
dNewVal = m_dCurrentValue;
|
||||
}
|
||||
|
@@ -225,17 +225,18 @@ namespace weld
|
||||
return std::optional<OUString>(aText);
|
||||
}
|
||||
|
||||
IMPL_LINK(LongCurrencyFormatter, ParseInputHdl, double*, result, TriState)
|
||||
IMPL_LINK(LongCurrencyFormatter, ParseInputHdl, const OUString&, rText, Formatter::ParseResult)
|
||||
{
|
||||
const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper();
|
||||
|
||||
BigInt value;
|
||||
bool bRet = ImplCurrencyGetValue(GetEntryText(), value, GetDecimalDigits(), rLocaleDataWrapper);
|
||||
bool bRet = ImplCurrencyGetValue(rText, value, GetDecimalDigits(), rLocaleDataWrapper);
|
||||
|
||||
double fValue = 0;
|
||||
if (bRet)
|
||||
*result = double(value) / weld::SpinButton::Power10(GetDecimalDigits());
|
||||
fValue = double(value) / weld::SpinButton::Power10(GetDecimalDigits());
|
||||
|
||||
return bRet ? TRISTATE_TRUE : TRISTATE_FALSE;
|
||||
return Formatter::ParseResult(bRet ? TRISTATE_TRUE : TRISTATE_FALSE, fValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user