diff options
author | Caolán McNamara <caolanm@redhat.com> | 2020-07-02 16:46:46 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2020-07-03 18:08:47 +0200 |
commit | 97ccd327c66660c9f7c9e625e3c5469b2ce42622 (patch) | |
tree | eb1b665299a34595f5570f0d1b97ce698936617a /vcl/source | |
parent | 643df295fa72b0d252460ae98104e347ce76cc22 (diff) |
change FormattedField so it doesn't inherit from Formatter but provides one
Change-Id: I728380fb4e2ed914c4b96c0915075af097846c55
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97825
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl/source')
-rw-r--r-- | vcl/source/app/salvtables.cxx | 81 | ||||
-rw-r--r-- | vcl/source/app/weldutils.cxx | 2 | ||||
-rw-r--r-- | vcl/source/control/fmtfield.cxx | 411 | ||||
-rw-r--r-- | vcl/source/uitest/uiobject.cxx | 2 | ||||
-rw-r--r-- | vcl/source/window/builder.cxx | 11 |
5 files changed, 267 insertions, 240 deletions
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 6e1bac5e91b3..e670a8fe4d6b 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -5207,13 +5207,14 @@ SalInstanceSpinButton::SalInstanceSpinButton(FormattedField* pButton, SalInstanc bool bTakeOwnership) : SalInstanceEntry(pButton, pBuilder, bTakeOwnership) , m_xButton(pButton) + , m_pFormatter(m_xButton->GetFormatter()) { - m_xButton->SetThousandsSep(false); //off by default, MetricSpinButton enables it + m_pFormatter->SetThousandsSep(false); //off by default, MetricSpinButton enables it m_xButton->SetUpHdl(LINK(this, SalInstanceSpinButton, UpDownHdl)); m_xButton->SetDownHdl(LINK(this, SalInstanceSpinButton, UpDownHdl)); m_xButton->SetLoseFocusHdl(LINK(this, SalInstanceSpinButton, LoseFocusHdl)); - m_xButton->SetOutputHdl(LINK(this, SalInstanceSpinButton, OutputHdl)); - m_xButton->SetInputHdl(LINK(this, SalInstanceSpinButton, InputHdl)); + m_pFormatter->SetOutputHdl(LINK(this, SalInstanceSpinButton, OutputHdl)); + m_pFormatter->SetInputHdl(LINK(this, SalInstanceSpinButton, InputHdl)); if (Edit* pEdit = m_xButton->GetSubEdit()) pEdit->SetActivateHdl(LINK(this, SalInstanceSpinButton, ActivateHdl)); else @@ -5222,40 +5223,40 @@ SalInstanceSpinButton::SalInstanceSpinButton(FormattedField* pButton, SalInstanc int SalInstanceSpinButton::get_value() const { - return fromField(m_xButton->GetValue()); - } + return fromField(m_pFormatter->GetValue()); +} void SalInstanceSpinButton::set_value(int value) { - m_xButton->SetValue(toField(value)); - } + m_pFormatter->SetValue(toField(value)); +} void SalInstanceSpinButton::set_range(int min, int max) { - m_xButton->SetMinValue(toField(min)); - m_xButton->SetMaxValue(toField(max)); + m_pFormatter->SetMinValue(toField(min)); + m_pFormatter->SetMaxValue(toField(max)); } void SalInstanceSpinButton::get_range(int& min, int& max) const { - min = fromField(m_xButton->GetMinValue()); - max = fromField(m_xButton->GetMaxValue()); + min = fromField(m_pFormatter->GetMinValue()); + max = fromField(m_pFormatter->GetMaxValue()); } void SalInstanceSpinButton::set_increments(int step, int /*page*/) { - m_xButton->SetSpinSize(toField(step)); + m_pFormatter->SetSpinSize(toField(step)); } void SalInstanceSpinButton::get_increments(int& step, int& page) const { - step = fromField(m_xButton->GetSpinSize()); - page = fromField(m_xButton->GetSpinSize()); + step = fromField(m_pFormatter->GetSpinSize()); + page = fromField(m_pFormatter->GetSpinSize()); } void SalInstanceSpinButton::set_digits(unsigned int digits) { - m_xButton->SetDecimalDigits(digits); + m_pFormatter->SetDecimalDigits(digits); } // SpinButton may be comprised of multiple subwidgets, consider the lot as @@ -5268,18 +5269,18 @@ bool SalInstanceSpinButton::has_focus() const //so with hh::mm::ss, incrementing mm will not reset ss void SalInstanceSpinButton::DisableRemainderFactor() { - m_xButton->DisableRemainderFactor(); + m_pFormatter->DisableRemainderFactor(); } //off by default for direct SpinButtons, MetricSpinButton enables it void SalInstanceSpinButton::SetUseThousandSep() { - m_xButton->SetThousandsSep(true); + m_pFormatter->SetThousandsSep(true); } unsigned int SalInstanceSpinButton::get_digits() const { - return m_xButton->GetDecimalDigits(); + return m_pFormatter->GetDecimalDigits(); } SalInstanceSpinButton::~SalInstanceSpinButton() @@ -5288,8 +5289,8 @@ SalInstanceSpinButton::~SalInstanceSpinButton() pEdit->SetActivateHdl(Link<Edit&, bool>()); else m_xButton->SetActivateHdl(Link<Edit&, bool>()); - m_xButton->SetInputHdl(Link<sal_Int64*, TriState>()); - m_xButton->SetOutputHdl(Link<LinkParamNone*, bool>()); + m_pFormatter->SetInputHdl(Link<sal_Int64*, TriState>()); + m_pFormatter->SetOutputHdl(Link<LinkParamNone*, bool>()); m_xButton->SetLoseFocusHdl(Link<Control&, void>()); m_xButton->SetDownHdl(Link<SpinField&, void>()); m_xButton->SetUpHdl(Link<SpinField&, void>()); @@ -5324,6 +5325,7 @@ class SalInstanceFormattedSpinButton : public SalInstanceEntry, { private: VclPtr<FormattedField> m_xButton; + Formatter* m_pFormatter; DECL_LINK(OutputHdl, LinkParamNone*, bool); DECL_LINK(InputHdl, sal_Int64*, TriState); @@ -5333,61 +5335,62 @@ public: bool bTakeOwnership) : SalInstanceEntry(pButton, pBuilder, bTakeOwnership) , m_xButton(pButton) + , m_pFormatter(m_xButton->GetFormatter()) { - m_xButton->SetOutputHdl(LINK(this, SalInstanceFormattedSpinButton, OutputHdl)); - m_xButton->SetInputHdl(LINK(this, SalInstanceFormattedSpinButton, InputHdl)); + m_pFormatter->SetOutputHdl(LINK(this, SalInstanceFormattedSpinButton, OutputHdl)); + m_pFormatter->SetInputHdl(LINK(this, SalInstanceFormattedSpinButton, InputHdl)); // #i6278# allow more decimal places than the output format. As // the numbers shown in the edit fields are used for input, it makes more // sense to display the values in the input format rather than the output // format. - m_xButton->UseInputStringForFormatting(); + m_pFormatter->UseInputStringForFormatting(); } virtual ~SalInstanceFormattedSpinButton() override { - m_xButton->SetInputHdl(Link<sal_Int64*, TriState>()); - m_xButton->SetOutputHdl(Link<LinkParamNone*, bool>()); + m_pFormatter->SetInputHdl(Link<sal_Int64*, TriState>()); + m_pFormatter->SetOutputHdl(Link<LinkParamNone*, bool>()); } - virtual double get_value() const override { return m_xButton->GetValue(); } + virtual double get_value() const override { return m_pFormatter->GetValue(); } - virtual void set_value(double value) override { m_xButton->SetValue(value); } + virtual void set_value(double value) override { m_pFormatter->SetValue(value); } virtual void set_range(double min, double max) override { - m_xButton->SetMinValue(min); - m_xButton->SetMaxValue(max); + m_pFormatter->SetMinValue(min); + m_pFormatter->SetMaxValue(max); } virtual void get_range(double& min, double& max) const override { - min = m_xButton->GetMinValue(); - max = m_xButton->GetMaxValue(); + min = m_pFormatter->GetMinValue(); + max = m_pFormatter->GetMaxValue(); } virtual void set_increments(double step, double /*page*/) override { - m_xButton->SetSpinSize(step); + m_pFormatter->SetSpinSize(step); } virtual void set_formatter(SvNumberFormatter* pFormatter) override { - m_xButton->SetFormatter(pFormatter); + m_pFormatter->SetFormatter(pFormatter); } - virtual SvNumberFormatter* get_formatter() override { return m_xButton->GetFormatter(); } + virtual SvNumberFormatter* get_formatter() override { return m_pFormatter->GetFormatter(); } - virtual sal_Int32 get_format_key() const override { return m_xButton->GetFormatKey(); } + virtual sal_Int32 get_format_key() const override { return m_pFormatter->GetFormatKey(); } virtual void set_format_key(sal_Int32 nFormatKey) override { - m_xButton->SetFormatKey(nFormatKey); + m_pFormatter->SetFormatKey(nFormatKey); } - virtual void treat_as_number(bool bSet) override { m_xButton->TreatAsNumber(bSet); } + virtual void treat_as_number(bool bSet) override { m_pFormatter->TreatAsNumber(bSet); } - virtual void set_digits(unsigned int digits) override { m_xButton->SetDecimalDigits(digits); } + virtual void set_digits(unsigned int digits) override { m_pFormatter->SetDecimalDigits(digits); } }; IMPL_LINK_NOARG(SalInstanceFormattedSpinButton, OutputHdl, LinkParamNone*, bool) @@ -5408,7 +5411,7 @@ IMPL_LINK(SalInstanceFormattedSpinButton, InputHdl, sal_Int64*, pResult, TriStat double value; TriState eRet = m_aInputHdl.Call(&value) ? TRISTATE_TRUE : TRISTATE_FALSE; if (eRet == TRISTATE_TRUE) - *pResult = std::round(value * weld::SpinButton::Power10(m_xButton->GetDecimalDigits())); + *pResult = std::round(value * weld::SpinButton::Power10(m_pFormatter->GetDecimalDigits())); return eRet; } diff --git a/vcl/source/app/weldutils.cxx b/vcl/source/app/weldutils.cxx index 9cb6dfd53296..2b175e403304 100644 --- a/vcl/source/app/weldutils.cxx +++ b/vcl/source/app/weldutils.cxx @@ -159,7 +159,7 @@ SelectionOptions FormattedEntry::GetEntrySelectionOptions() const { return m_eOp void FormattedEntry::FieldModified() { m_aModifyHdl.Call(*m_xEntry); } -IMPL_LINK_NOARG(FormattedEntry, ModifyHdl, weld::Entry&, void) { impl_Modify(); } +IMPL_LINK_NOARG(FormattedEntry, ModifyHdl, weld::Entry&, void) { Modify(); } IMPL_LINK_NOARG(FormattedEntry, FocusOutHdl, weld::Widget&, void) { EntryLostFocus(); } } diff --git a/vcl/source/control/fmtfield.cxx b/vcl/source/control/fmtfield.cxx index f3a703cc3306..d67b0b9ba792 100644 --- a/vcl/source/control/fmtfield.cxx +++ b/vcl/source/control/fmtfield.cxx @@ -48,50 +48,6 @@ using namespace ::com::sun::star::util; namespace validation { - namespace { - - // the states of our automat. - enum State - { - START, // at the very start of the string - NUM_START, // the very start of the number - - DIGIT_PRE_COMMA, // some pre-comma digits are read, perhaps including some thousand separators - - DIGIT_POST_COMMA, // reading digits after the comma - EXPONENT_START, // at the very start of the exponent value - // (means: not including the "e" which denotes the exponent) - EXPONENT_DIGIT, // currently reading the digits of the exponent - - END // reached the end of the string - }; - - } - - // a row in the transition table (means the set of states to be reached from a given state) - typedef ::std::map< sal_Unicode, State > StateTransitions; - - // a single transition - typedef StateTransitions::value_type Transition; - - // the complete transition table - typedef ::std::map< State, StateTransitions > TransitionTable; - - // the validator class - class NumberValidator - { - private: - TransitionTable m_aTransitions; - - public: - NumberValidator( const sal_Unicode _cThSep, const sal_Unicode _cDecSep ); - - bool isValidNumericFragment( const OUString& _rText ); - - private: - bool implValidateNormalized( const OUString& _rText ); - }; - static void lcl_insertStopTransition( StateTransitions& _rRow ) { _rRow.insert( Transition( '_', END ) ); @@ -266,10 +222,10 @@ namespace validation } } -SvNumberFormatter* FormattedField::StaticFormatter::s_cFormatter = nullptr; -sal_uLong FormattedField::StaticFormatter::s_nReferences = 0; +SvNumberFormatter* Formatter::StaticFormatter::s_cFormatter = nullptr; +sal_uLong Formatter::StaticFormatter::s_nReferences = 0; -SvNumberFormatter* FormattedField::StaticFormatter::GetFormatter() +SvNumberFormatter* Formatter::StaticFormatter::GetFormatter() { if (!s_cFormatter) { @@ -282,12 +238,12 @@ SvNumberFormatter* FormattedField::StaticFormatter::GetFormatter() return s_cFormatter; } -FormattedField::StaticFormatter::StaticFormatter() +Formatter::StaticFormatter::StaticFormatter() { ++s_nReferences; } -FormattedField::StaticFormatter::~StaticFormatter() +Formatter::StaticFormatter::~StaticFormatter() { if (--s_nReferences == 0) { @@ -334,7 +290,7 @@ void Formatter::SetFieldText(const OUString& rStr, const Selection& rNewSelectio void Formatter::SetTextFormatted(const OUString& rStr) { - SAL_INFO_IF(ImplGetFormatter()->IsTextFormat(m_nFormatKey), "svtools", + SAL_INFO_IF(GetOrCreateFormatter()->IsTextFormat(m_nFormatKey), "svtools", "FormattedField::SetTextFormatted : valid only with text formats !"); m_sCurrentTextValue = rStr; @@ -344,13 +300,13 @@ void Formatter::SetTextFormatted(const OUString& rStr) // IsNumberFormat changes the format key parameter sal_uInt32 nTempFormatKey = static_cast< sal_uInt32 >( m_nFormatKey ); if( IsUsingInputStringForFormatting() && - ImplGetFormatter()->IsNumberFormat(m_sCurrentTextValue, nTempFormatKey, dNumber) ) + GetOrCreateFormatter()->IsNumberFormat(m_sCurrentTextValue, nTempFormatKey, dNumber) ) { - ImplGetFormatter()->GetInputLineString(dNumber, m_nFormatKey, sFormatted); + GetOrCreateFormatter()->GetInputLineString(dNumber, m_nFormatKey, sFormatted); } else { - ImplGetFormatter()->GetOutputString(m_sCurrentTextValue, + GetOrCreateFormatter()->GetOutputString(m_sCurrentTextValue, m_nFormatKey, sFormatted, &m_pLastOutputColor); @@ -422,7 +378,7 @@ void Formatter::SetAutoColor(bool _bAutomatic) } } -void Formatter::impl_Modify(bool makeValueDirty) +void Formatter::Modify(bool makeValueDirty) { if (!IsStrictFormat()) { @@ -497,7 +453,7 @@ void Formatter::ImplSetFormatKey(sal_uLong nFormatKey) bool bNeedFormatter = (m_pFormatter == nullptr) && (nFormatKey != 0); if (bNeedFormatter) { - ImplGetFormatter(); // this creates a standard formatter + GetOrCreateFormatter(); // this creates a standard formatter // It might happen that the standard formatter makes no sense here, but it takes a default // format. Thus, it is possible to set one of the other standard keys (which are spanning @@ -560,7 +516,7 @@ void Formatter::SetFormatter(SvNumberFormatter* pFormatter, bool bResetFormat) OUString Formatter::GetFormat(LanguageType& eLang) const { - const SvNumberformat* pFormatEntry = ImplGetFormatter()->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; @@ -570,13 +526,13 @@ OUString Formatter::GetFormat(LanguageType& eLang) const bool Formatter::SetFormat(const OUString& rFormatString, LanguageType eLang) { - sal_uInt32 nNewKey = ImplGetFormatter()->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 (!ImplGetFormatter()->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 !"); } @@ -588,25 +544,25 @@ bool Formatter::SetFormat(const OUString& rFormatString, LanguageType eLang) bool Formatter::GetThousandsSep() const { - DBG_ASSERT(!ImplGetFormatter()->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; - ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nLeadingCnt); + GetOrCreateFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nLeadingCnt); return bThousand; } void Formatter::SetThousandsSep(bool _bUseSeparator) { - DBG_ASSERT(!ImplGetFormatter()->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; - ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nLeadingCnt); + GetOrCreateFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nLeadingCnt); if (bThousand == _bUseSeparator) return; @@ -615,12 +571,12 @@ void Formatter::SetThousandsSep(bool _bUseSeparator) GetFormat(eLang); // generate a new format ... - OUString sFmtDescription = ImplGetFormatter()->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; - ImplGetFormatter()->PutEntry(sFmtDescription, nCheckPos, nType, nNewKey, eLang); + GetOrCreateFormatter()->PutEntry(sFmtDescription, nCheckPos, nType, nNewKey, eLang); // set the new key ImplSetFormatKey(nNewKey); @@ -629,25 +585,25 @@ void Formatter::SetThousandsSep(bool _bUseSeparator) sal_uInt16 Formatter::GetDecimalDigits() const { - DBG_ASSERT(!ImplGetFormatter()->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; - ImplGetFormatter()->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(!ImplGetFormatter()->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; - ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nLeadingCnt); + GetOrCreateFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nLeadingCnt); if (nPrecision == _nPrecision) return; @@ -656,12 +612,12 @@ void Formatter::SetDecimalDigits(sal_uInt16 _nPrecision) GetFormat(eLang); // generate a new format ... - OUString sFmtDescription = ImplGetFormatter()->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; - ImplGetFormatter()->PutEntry(sFmtDescription, nCheckPos, nType, nNewKey, eLang); + GetOrCreateFormatter()->PutEntry(sFmtDescription, nCheckPos, nType, nNewKey, eLang); // set the new key ImplSetFormatKey(nNewKey); @@ -688,7 +644,7 @@ void Formatter::EntryLostFocus() if (TreatingAsNumber()) { ImplSetValue(m_dCurrentValue, true); - impl_Modify(); + Modify(); m_ValueState = valueDouble; } else @@ -723,7 +679,7 @@ void Formatter::Commit() // don't reparse it from the text // (can lead to data loss when the format is lossy, // as is e.g. our default date format: 2-digit year!) - impl_Modify(false); + Modify(false); } } @@ -795,7 +751,7 @@ void Formatter::ImplSetValue(double dVal, bool bForce) if (!bForce && (dVal == GetValue())) return; - DBG_ASSERT(ImplGetFormatter() != nullptr, "FormattedField::ImplSetValue : can't set a value without a formatter !"); + DBG_ASSERT(GetOrCreateFormatter() != nullptr, "FormattedField::ImplSetValue : can't set a value without a formatter !"); m_ValueState = valueDouble; m_dCurrentValue = dVal; @@ -803,23 +759,23 @@ void Formatter::ImplSetValue(double dVal, bool bForce) if (!m_aOutputHdl.IsSet() || !m_aOutputHdl.Call(nullptr)) { OUString sNewText; - if (ImplGetFormatter()->IsTextFormat(m_nFormatKey)) + if (GetOrCreateFormatter()->IsTextFormat(m_nFormatKey)) { // first convert the number as string in standard format OUString sTemp; - ImplGetFormatter()->GetOutputString(dVal, 0, sTemp, &m_pLastOutputColor); + GetOrCreateFormatter()->GetOutputString(dVal, 0, sTemp, &m_pLastOutputColor); // then encode the string in the corresponding text format - ImplGetFormatter()->GetOutputString(sTemp, m_nFormatKey, sNewText, &m_pLastOutputColor); + GetOrCreateFormatter()->GetOutputString(sTemp, m_nFormatKey, sNewText, &m_pLastOutputColor); } else { if( IsUsingInputStringForFormatting()) { - ImplGetFormatter()->GetInputLineString(dVal, m_nFormatKey, sNewText); + GetOrCreateFormatter()->GetInputLineString(dVal, m_nFormatKey, sNewText); } else { - ImplGetFormatter()->GetOutputString(dVal, m_nFormatKey, sNewText, &m_pLastOutputColor); + GetOrCreateFormatter()->GetOutputString(dVal, m_nFormatKey, sNewText, &m_pLastOutputColor); } } ImplSetTextImpl(sNewText, nullptr); @@ -860,16 +816,16 @@ bool Formatter::ImplGetValue(double& dNewVal) if (!bUseExternalFormatterValue) { - DBG_ASSERT(ImplGetFormatter() != nullptr, "FormattedField::ImplGetValue : can't give you a current value without a formatter !"); + 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 (ImplGetFormatter()->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 (ImplGetFormatter()->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(); @@ -886,7 +842,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 (!ImplGetFormatter()->IsNumberFormat(sText, nFormatKey, dNewVal)) + if (!GetOrCreateFormatter()->IsNumberFormat(sText, nFormatKey, dNewVal)) return false; } @@ -922,38 +878,150 @@ void Formatter::DisableRemainderFactor() m_bDisableRemainderFactor = true; } - void Formatter::UseInputStringForFormatting() { m_bUseInputStringForFormatting = true; } -DoubleNumericField::DoubleNumericField(vcl::Window* pParent, WinBits nStyle) - : FormattedField(pParent, nStyle) +namespace { - ResetConformanceTester(); -} + class FieldFormatter : public Formatter + { + private: + FormattedField& m_rSpinButton; + public: + FieldFormatter(FormattedField& rSpinButton) + : m_rSpinButton(rSpinButton) + { + } -DoubleNumericField::~DoubleNumericField() = default; + // Formatter overrides + virtual Selection GetEntrySelection() const override + { + return m_rSpinButton.GetSelection(); + } -void DoubleNumericField::FormatChanged(FORMAT_CHANGE_TYPE nWhat) -{ - ResetConformanceTester(); - FormattedField::FormatChanged(nWhat); + virtual OUString GetEntryText() const override + { + return m_rSpinButton.GetText(); + } + + void SetEntryText(const OUString& rText, const Selection& rSel) override + { + m_rSpinButton.SpinField::SetText(rText, rSel); + } + + virtual void SetEntryTextColor(const Color* pColor) override + { + if (pColor) + m_rSpinButton.SetControlForeground(*pColor); + else + m_rSpinButton.SetControlForeground(); + } + + virtual SelectionOptions GetEntrySelectionOptions() const override + { + return m_rSpinButton.GetSettings().GetStyleSettings().GetSelectionOptions(); + } + + virtual void FieldModified() override + { + m_rSpinButton.SpinField::Modify(); + } + }; + + class DoubleNumericFormatter : public FieldFormatter + { + private: + DoubleNumericField& m_rNumericSpinButton; + public: + DoubleNumericFormatter(DoubleNumericField& rNumericSpinButton) + : FieldFormatter(rNumericSpinButton) + , m_rNumericSpinButton(rNumericSpinButton) + { + } + + virtual bool CheckText(const OUString& sText) const override + { + // We'd like to implement this using the NumberFormatter::IsNumberFormat, but unfortunately, this doesn't + // recognize fragments of numbers (like, for instance "1e", which happens during entering e.g. "1e10") + // Thus, the roundabout way via a regular expression + return m_rNumericSpinButton.GetNumberValidator().isValidNumericFragment(sText); + } + + virtual void FormatChanged(FORMAT_CHANGE_TYPE nWhat) override + { + m_rNumericSpinButton.ResetConformanceTester(); + FieldFormatter::FormatChanged(nWhat); + } + }; + + class DoubleCurrencyFormatter : public FieldFormatter + { + private: + DoubleCurrencyField& m_rCurrencySpinButton; + bool m_bChangingFormat; + public: + DoubleCurrencyFormatter(DoubleCurrencyField& rNumericSpinButton) + : FieldFormatter(rNumericSpinButton) + , m_rCurrencySpinButton(rNumericSpinButton) + , m_bChangingFormat(false) + { + } + + virtual void FormatChanged(FORMAT_CHANGE_TYPE nWhat) override + { + if (m_bChangingFormat) + { + FieldFormatter::FormatChanged(nWhat); + return; + } + + switch (nWhat) + { + case FORMAT_CHANGE_TYPE::FORMATTER: + case FORMAT_CHANGE_TYPE::PRECISION: + case FORMAT_CHANGE_TYPE::THOUSANDSSEP: + // the aspects which changed don't take our currency settings into account (in fact, they most probably + // destroyed them) + m_rCurrencySpinButton.UpdateCurrencyFormat(); + break; + case FORMAT_CHANGE_TYPE::KEYONLY: + OSL_FAIL("DoubleCurrencyField::FormatChanged : somebody modified my key !"); + // We always build our own format from the settings we get via special methods (setCurrencySymbol etc.). + // Nobody but ourself should modify the format key directly! + break; + default: break; + } + + FieldFormatter::FormatChanged(nWhat); + } + + void GuardSetFormat(const OUString& rString, LanguageType eLanguage) + { + // set this new basic format + m_bChangingFormat = true; + SetFormat(rString, eLanguage); + m_bChangingFormat = false; + } + + }; } -bool DoubleNumericField::CheckText(const OUString& sText) const +DoubleNumericField::DoubleNumericField(vcl::Window* pParent, WinBits nStyle) + : FormattedField(pParent, nStyle) { - // We'd like to implement this using the NumberFormatter::IsNumberFormat, but unfortunately, this doesn't - // recognize fragments of numbers (like, for instance "1e", which happens during entering e.g. "1e10") - // Thus, the roundabout way via a regular expression - return m_pNumberValidator->isValidNumericFragment( sText ); + m_xFormatter.reset(new DoubleNumericFormatter(*this)); + ResetConformanceTester(); } +DoubleNumericField::~DoubleNumericField() = default; + void DoubleNumericField::ResetConformanceTester() { // the thousands and the decimal separator are language dependent - const SvNumberformat* pFormatEntry = ImplGetFormatter()->GetEntry(m_nFormatKey); + Formatter* pFormatter = GetFormatter(); + const SvNumberformat* pFormatEntry = pFormatter->GetOrCreateFormatter()->GetEntry(pFormatter->GetFormatKey()); sal_Unicode cSeparatorThousand = ','; sal_Unicode cSeparatorDecimal = '.'; @@ -973,10 +1041,11 @@ void DoubleNumericField::ResetConformanceTester() m_pNumberValidator.reset(new validation::NumberValidator( cSeparatorThousand, cSeparatorDecimal )); } + DoubleCurrencyField::DoubleCurrencyField(vcl::Window* pParent, WinBits nStyle) :FormattedField(pParent, nStyle) - ,m_bChangingFormat(false) { + m_xFormatter.reset(new DoubleCurrencyFormatter(*this)); m_bPrependCurrSym = false; // initialize with a system currency format @@ -984,34 +1053,6 @@ DoubleCurrencyField::DoubleCurrencyField(vcl::Window* pParent, WinBits nStyle) UpdateCurrencyFormat(); } -void DoubleCurrencyField::FormatChanged(FORMAT_CHANGE_TYPE nWhat) -{ - if (m_bChangingFormat) - { - FormattedField::FormatChanged(nWhat); - return; - } - - switch (nWhat) - { - case FORMAT_CHANGE_TYPE::FORMATTER: - case FORMAT_CHANGE_TYPE::PRECISION: - case FORMAT_CHANGE_TYPE::THOUSANDSSEP: - // the aspects which changed don't take our currency settings into account (in fact, they most probably - // destroyed them) - UpdateCurrencyFormat(); - break; - case FORMAT_CHANGE_TYPE::KEYONLY: - OSL_FAIL("DoubleCurrencyField::FormatChanged : somebody modified my key !"); - // We always build our own format from the settings we get via special methods (setCurrencySymbol etc.). - // Nobody but ourself should modify the format key directly! - break; - default: break; - } - - FormattedField::FormatChanged(nWhat); -} - void DoubleCurrencyField::setCurrencySymbol(const OUString& rSymbol) { if (m_sCurrencySymbol == rSymbol) @@ -1019,7 +1060,7 @@ void DoubleCurrencyField::setCurrencySymbol(const OUString& rSymbol) m_sCurrencySymbol = rSymbol; UpdateCurrencyFormat(); - FormatChanged(FORMAT_CHANGE_TYPE::CURRENCY_SYMBOL); + m_xFormatter->FormatChanged(FORMAT_CHANGE_TYPE::CURRENCY_SYMBOL); } void DoubleCurrencyField::setPrependCurrSym(bool _bPrepend) @@ -1029,16 +1070,16 @@ void DoubleCurrencyField::setPrependCurrSym(bool _bPrepend) m_bPrependCurrSym = _bPrepend; UpdateCurrencyFormat(); - FormatChanged(FORMAT_CHANGE_TYPE::CURRSYM_POSITION); + m_xFormatter->FormatChanged(FORMAT_CHANGE_TYPE::CURRSYM_POSITION); } void DoubleCurrencyField::UpdateCurrencyFormat() { // the old settings LanguageType eLanguage; - GetFormat(eLanguage); - bool bThSep = GetThousandsSep(); - sal_uInt16 nDigits = GetDecimalDigits(); + m_xFormatter->GetFormat(eLanguage); + bool bThSep = m_xFormatter->GetThousandsSep(); + sal_uInt16 nDigits = m_xFormatter->GetDecimalDigits(); // build a new format string with the base class' and my own settings @@ -1102,9 +1143,7 @@ void DoubleCurrencyField::UpdateCurrencyFormat() } // set this new basic format - m_bChangingFormat = true; - SetFormat(sNewFormat.makeStringAndClear(), eLanguage); - m_bChangingFormat = false; + static_cast<DoubleCurrencyFormatter*>(m_xFormatter.get())->GuardSetFormat(sNewFormat.makeStringAndClear(), eLanguage); } FormattedField::FormattedField(vcl::Window* pParent, WinBits nStyle) @@ -1114,21 +1153,21 @@ FormattedField::FormattedField(vcl::Window* pParent, WinBits nStyle) void FormattedField::SetText(const OUString& rStr) { - SetFieldText(rStr, Selection(0, 0)); + GetFormatter()->SetFieldText(rStr, Selection(0, 0)); } void FormattedField::SetText(const OUString& rStr, const Selection& rNewSelection) { - SetFieldText(rStr, rNewSelection); + GetFormatter()->SetFieldText(rStr, rNewSelection); SetSelection(rNewSelection); } bool FormattedField::set_property(const OString &rKey, const OUString &rValue) { if (rKey == "digits") - SetDecimalDigits(rValue.toInt32()); + GetFormatter()->SetDecimalDigits(rValue.toInt32()); else if (rKey == "wrap") - m_bWrapOnLimits = toBool(rValue); + GetFormatter()->SetWrapOnLimits(toBool(rValue)); else return SpinField::set_property(rKey, rValue); return true; @@ -1136,18 +1175,19 @@ bool FormattedField::set_property(const OString &rKey, const OUString &rValue) void FormattedField::Up() { - auto nScale = weld::SpinButton::Power10(GetDecimalDigits()); + Formatter* pFormatter = GetFormatter(); + auto nScale = weld::SpinButton::Power10(pFormatter->GetDecimalDigits()); - sal_Int64 nValue = std::round(GetValue() * nScale); - sal_Int64 nSpinSize = std::round(m_dSpinSize * nScale); - sal_Int64 nRemainder = m_bDisableRemainderFactor ? 0 : nValue % nSpinSize; + sal_Int64 nValue = std::round(pFormatter->GetValue() * nScale); + sal_Int64 nSpinSize = std::round(pFormatter->GetSpinSize() * nScale); + sal_Int64 nRemainder = pFormatter->GetDisableRemainderFactor() ? 0 : nValue % nSpinSize; if (nValue >= 0) nValue = (nRemainder == 0) ? nValue + nSpinSize : nValue + nSpinSize - nRemainder; else nValue = (nRemainder == 0) ? nValue + nSpinSize : nValue - nRemainder; // setValue handles under- and overflows (min/max) automatically - SetValue(static_cast<double>(nValue) / nScale); + pFormatter->SetValue(static_cast<double>(nValue) / nScale); SetModifyFlag(); Modify(); @@ -1156,18 +1196,19 @@ void FormattedField::Up() void FormattedField::Down() { - auto nScale = weld::SpinButton::Power10(GetDecimalDigits()); + Formatter* pFormatter = GetFormatter(); + auto nScale = weld::SpinButton::Power10(pFormatter->GetDecimalDigits()); - sal_Int64 nValue = std::round(GetValue() * nScale); - sal_Int64 nSpinSize = std::round(m_dSpinSize * nScale); - sal_Int64 nRemainder = m_bDisableRemainderFactor ? 0 : nValue % nSpinSize; + sal_Int64 nValue = std::round(pFormatter->GetValue() * nScale); + sal_Int64 nSpinSize = std::round(pFormatter->GetSpinSize() * nScale); + sal_Int64 nRemainder = pFormatter->GetDisableRemainderFactor() ? 0 : nValue % nSpinSize; if (nValue >= 0) nValue = (nRemainder == 0) ? nValue - nSpinSize : nValue - nRemainder; else nValue = (nRemainder == 0) ? nValue - nSpinSize : nValue - nSpinSize - nRemainder; // setValue handles under- and overflows (min/max) automatically - SetValue(static_cast<double>(nValue) / nScale); + pFormatter->SetValue(static_cast<double>(nValue) / nScale); SetModifyFlag(); Modify(); @@ -1176,9 +1217,10 @@ void FormattedField::Down() void FormattedField::First() { - if (m_bHasMin) + Formatter* pFormatter = GetFormatter(); + if (pFormatter->HasMinValue()) { - SetValue(m_dMinValue); + pFormatter->SetValue(pFormatter->GetMinValue()); SetModifyFlag(); Modify(); } @@ -1188,9 +1230,10 @@ void FormattedField::First() void FormattedField::Last() { - if (m_bHasMax) + Formatter* pFormatter = GetFormatter(); + if (pFormatter->HasMaxValue()) { - SetValue(m_dMaxValue); + pFormatter->SetValue(pFormatter->GetMaxValue()); SetModifyFlag(); Modify(); } @@ -1200,19 +1243,18 @@ void FormattedField::Last() void FormattedField::Modify() { - impl_Modify(); + GetFormatter()->Modify(); } bool FormattedField::PreNotify(NotifyEvent& rNEvt) { if (rNEvt.GetType() == MouseNotifyEvent::KEYINPUT) - m_aLastSelection = GetSelection(); + GetFormatter()->SetLastSelection(GetSelection()); return SpinField::PreNotify(rNEvt); } bool FormattedField::EventNotify(NotifyEvent& rNEvt) { - if ((rNEvt.GetType() == MouseNotifyEvent::KEYINPUT) && !IsReadOnly()) { const KeyEvent& rKEvt = *rNEvt.GetKeyEvent(); @@ -1223,12 +1265,15 @@ bool FormattedField::EventNotify(NotifyEvent& rNEvt) case KEY_DOWN: case KEY_PAGEUP: case KEY_PAGEDOWN: - if (!nMod && ImplGetFormatter()->IsTextFormat(m_nFormatKey)) + { + Formatter* pFormatter = GetFormatter(); + if (!nMod && pFormatter->GetOrCreateFormatter()->IsTextFormat(pFormatter->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 return true; } + } } } @@ -1238,7 +1283,9 @@ bool FormattedField::EventNotify(NotifyEvent& rNEvt) if (pCommand->GetCommand() == CommandEventId::Wheel) { const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData(); - if ((pData->GetMode() == CommandWheelMode::SCROLL) && ImplGetFormatter()->IsTextFormat(m_nFormatKey)) + Formatter* pFormatter = GetFormatter(); + if ((pData->GetMode() == CommandWheelMode::SCROLL) && + pFormatter->GetOrCreateFormatter()->IsTextFormat(pFormatter->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 ?) @@ -1249,42 +1296,16 @@ bool FormattedField::EventNotify(NotifyEvent& rNEvt) } if (rNEvt.GetType() == MouseNotifyEvent::LOSEFOCUS) - EntryLostFocus(); + GetFormatter()->EntryLostFocus(); return SpinField::EventNotify( rNEvt ); } -Selection FormattedField::GetEntrySelection() const -{ - return GetSelection(); -} - -OUString FormattedField::GetEntryText() const -{ - return GetText(); -} - -void FormattedField::SetEntryText(const OUString& rText, const Selection& rSel) -{ - SpinField::SetText(rText, rSel); -} - -void FormattedField::SetEntryTextColor(const Color* pColor) -{ - if (pColor) - SetControlForeground(*pColor); - else - SetControlForeground(); -} - -SelectionOptions FormattedField::GetEntrySelectionOptions() const -{ - return GetSettings().GetStyleSettings().GetSelectionOptions(); -} - -void FormattedField::FieldModified() +Formatter* FormattedField::GetFormatter() { - SpinField::Modify(); + if (!m_xFormatter) + m_xFormatter.reset(new FieldFormatter(*this)); + return m_xFormatter.get(); } // currently used by online @@ -1292,12 +1313,13 @@ void FormattedField::SetValueFromString(const OUString& rStr) { sal_Int32 nEnd; rtl_math_ConversionStatus eStatus; - double fValue = ::rtl::math::stringToDouble(rStr, '.', GetDecimalDigits(), &eStatus, &nEnd ); + Formatter* pFormatter = GetFormatter(); + double fValue = ::rtl::math::stringToDouble(rStr, '.', pFormatter->GetDecimalDigits(), &eStatus, &nEnd ); if (eStatus == rtl_math_ConversionStatus_Ok && nEnd == rStr.getLength()) { - SetValue(fValue); + pFormatter->SetValue(fValue); SetModifyFlag(); Modify(); @@ -1313,9 +1335,10 @@ void FormattedField::SetValueFromString(const OUString& rStr) void FormattedField::DumpAsPropertyTree(tools::JsonWriter& rJsonWriter) { SpinField::DumpAsPropertyTree(rJsonWriter); - rJsonWriter.put("min", GetMinValue()); - rJsonWriter.put("max", GetMaxValue()); - rJsonWriter.put("value", GetValue()); + Formatter* pFormatter = GetFormatter(); + rJsonWriter.put("min", pFormatter->GetMinValue()); + rJsonWriter.put("max", pFormatter->GetMaxValue()); + rJsonWriter.put("value", pFormatter->GetValue()); } FactoryFunction FormattedField::GetUITestFactory() const diff --git a/vcl/source/uitest/uiobject.cxx b/vcl/source/uitest/uiobject.cxx index 947dda576c73..c8170a17caee 100644 --- a/vcl/source/uitest/uiobject.cxx +++ b/vcl/source/uitest/uiobject.cxx @@ -1374,7 +1374,7 @@ void FormattedFieldUIObject::execute(const OUString& rAction, StringMap FormattedFieldUIObject::get_state() { StringMap aMap = EditUIObject::get_state(); - aMap["Value"] = OUString::number(mxFormattedField->GetValue()); + aMap["Value"] = OUString::number(mxFormattedField->GetFormatter()->GetValue()); return aMap; } diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx index 422babaae27a..85ee2ca4f4f1 100644 --- a/vcl/source/window/builder.cxx +++ b/vcl/source/window/builder.cxx @@ -1951,7 +1951,7 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString & { connectFormattedFormatterAdjustment(id, sAdjustment); VclPtrInstance<FormattedField> xField(pParent, nBits); - xField->SetMinValue(0); + xField->GetFormatter()->SetMinValue(0); xWindow = xField; } } @@ -4411,10 +4411,11 @@ void VclBuilder::mungeAdjustment(FormattedField &rTarget, const Adjustment &rAdj SAL_INFO("vcl.builder", "unhandled property :" << rKey); } - rTarget.SetMinValue(nMinValue); - rTarget.SetMaxValue(nMaxValue); - rTarget.SetValue(nValue); - rTarget.SetSpinSize(nSpinSize); + Formatter* pFormatter = rTarget.GetFormatter(); + pFormatter->SetMinValue(nMinValue); + pFormatter->SetMaxValue(nMaxValue); + pFormatter->SetValue(nValue); + pFormatter->SetSpinSize(nSpinSize); } void VclBuilder::mungeAdjustment(ScrollBar &rTarget, const Adjustment &rAdjustment) |