include/vcl/fmtfield.hxx | 229 ---------------- include/vcl/formatter.hxx | 261 ++++++++++++++++++ solenv/clang-format/blacklist | 1 vcl/inc/salvtables.hxx | 2 vcl/source/app/salvtables.cxx | 10 vcl/source/control/fmtfield.cxx | 569 +++++++++++++++++++++------------------- 6 files changed, 583 insertions(+), 489 deletions(-)
New commits: commit 175eba0d87cc0d4693920341077617ef443809b4 Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Wed Jul 1 15:49:57 2020 +0100 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Wed Jul 1 21:12:51 2020 +0200 split Formatter part of FormattedField from SpinButton part Change-Id: Ic1454d63a17bd3ec1d70cd5eef5895aee2d919ec Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97642 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caol...@redhat.com> diff --git a/include/vcl/fmtfield.hxx b/include/vcl/fmtfield.hxx index be6c82ff003a..08fc7d9174f8 100644 --- a/include/vcl/fmtfield.hxx +++ b/include/vcl/fmtfield.hxx @@ -20,147 +20,15 @@ #ifndef INCLUDED_VCL_FMTFIELD_HXX #define INCLUDED_VCL_FMTFIELD_HXX -#include <config_options.h> +#include <vcl/formatter.hxx> #include <vcl/spinfld.hxx> -#include <memory> - -class SvNumberFormatter; - -namespace validation { class NumberValidator; } - -enum class FORMAT_CHANGE_TYPE -{ - KEYONLY = 0x00, // only a new key was set - FORMATTER = 0x01, // a new formatter was set, usually implies a change of the key, too - PRECISION = 0x02, // a new precision was set - THOUSANDSSEP = 0x03, // the thousands separator setting changed - CURRENCY_SYMBOL = 0x10, - CURRSYM_POSITION = 0x20, -}; - class VCL_DLLPUBLIC FormattedField : public SpinField + , public Formatter { -private: - // A SvNumberFormatter is very expensive (regarding time and space), it is a Singleton - class StaticFormatter - { - static SvNumberFormatter* s_cFormatter; - static sal_uLong s_nReferences; - public: - StaticFormatter(); - ~StaticFormatter(); - - operator SvNumberFormatter* () { return GetFormatter(); } - UNLESS_MERGELIBS(VCL_DLLPUBLIC) static SvNumberFormatter* GetFormatter(); - }; - -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, - // not yet through formatter) - Selection m_aLastSelection; - - double m_dMinValue; - double m_dMaxValue; - bool m_bHasMin : 1; - bool m_bHasMax : 1; - - bool m_bWrapOnLimits : 1; - bool m_bStrictFormat : 1; - - bool m_bEnableEmptyField : 1; - bool m_bAutoColor : 1; - bool m_bEnableNaN : 1; - bool m_bDisableRemainderFactor : 1; - enum valueState { valueDirty, valueString, valueDouble }; - valueState m_ValueState; - double m_dCurrentValue; - double m_dDefaultValue; - - sal_uLong m_nFormatKey; - SvNumberFormatter* m_pFormatter; - StaticFormatter m_aStaticFormatter; - - double m_dSpinSize; - double m_dSpinFirst; - double m_dSpinLast; - - // There is a difference, when text formatting is enabled, if LostFocus formats the current String and displays it, - // or if a double is created from the String and then - bool m_bTreatAsNumber; - // And with the following members we can use it for formatted text output as well ... - OUString m_sCurrentTextValue; - OUString m_sDefaultText; - - // The last color from the Formatter at the last output operation (not we would use it, but you can get it) - Color* m_pLastOutputColor; - - bool m_bUseInputStringForFormatting; - public: FormattedField(vcl::Window* pParent, WinBits nStyle); - // Min-/Max-management - bool HasMinValue() const { return m_bHasMin; } - void ClearMinValue() { m_bHasMin = false; } - void SetMinValue(double dMin); - double GetMinValue() const { return m_dMinValue; } - - bool HasMaxValue() const { return m_bHasMax; } - void ClearMaxValue() { m_bHasMax = false; } - void SetMaxValue(double dMax); - double GetMaxValue() const { return m_dMaxValue; } - - // Current value - void SetValue(double dVal); - double GetValue(); - // The default implementation uses a formatter, if available - - void SetTextValue(const OUString& rText); - // The String is transformed to a double (with a formatter) and SetValue is called afterwards - // - void SetValueFromString(const OUString& rStr); - - bool IsEmptyFieldEnabled() const { return m_bEnableEmptyField; } - void EnableEmptyField(bool bEnable); - // If disabled, the value will be reset to the last valid value on leave - - void SetDefaultValue(double dDefault) { m_dDefaultValue = dDefault; m_ValueState = valueDirty; } - // If the current String is invalid, GetValue() returns this value - double GetDefaultValue() const { return m_dDefaultValue; } - - // Settings for the format - sal_uLong GetFormatKey() const { return m_nFormatKey; } - void SetFormatKey(sal_uLong nFormatKey); - - SvNumberFormatter* GetFormatter() const { return m_pFormatter; } - void SetFormatter(SvNumberFormatter* pFormatter, bool bResetFormat = true); - // If bResetFormat is sal_False, the old format is tried to be kept. (expensive, if it is no default format, available in all formatters) - // If sal_True, the new FormatKey is set to zero - - bool GetThousandsSep() const; - void SetThousandsSep(bool _bUseSeparator); - // the is no check if the current format is numeric, so be cautious when calling these functions - - void DisableRemainderFactor(); - - sal_uInt16 GetDecimalDigits() const; - void SetDecimalDigits(sal_uInt16 _nPrecision); - // There is no check if the current format is numeric, so be cautious when calling these functions - - SvNumberFormatter* StandardFormatter() { return m_aStaticFormatter; } - // If no new Formatter is created explicitly, this can be used in SetFormatter... - - OUString GetFormat(LanguageType& eLang) const; - bool SetFormat(const OUString& rFormatString, LanguageType eLang); - // sal_False, if the FormatString could not be set (and very probably is invalid) - // This Object is shared via all instances, so be careful! - - bool IsStrictFormat() const { return m_bStrictFormat; } - void SetStrictFormat(bool bEnable) { m_bStrictFormat = bEnable; } - // Check format during input - // Spin-Handling virtual void Up() override; virtual void Down() override; @@ -170,104 +38,29 @@ public: // Default Implementation: Current double is set to the first or last value virtual bool set_property(const OString &rKey, const OUString &rValue) override; - - void SetSpinSize(double dStep) { m_dSpinSize = dStep; } - double GetSpinSize() const { return m_dSpinSize; } - - void SetSpinFirst(double dFirst) { m_dSpinFirst = dFirst; } - double GetSpinFirst() const { return m_dSpinFirst; } - - void SetSpinLast(double dLast) { m_dSpinLast = dLast; } - double GetSpinLast() const { return m_dSpinLast; } - - bool TreatingAsNumber() const { return m_bTreatAsNumber; } - void TreatAsNumber(bool bDoSo) { m_bTreatAsNumber = bDoSo; } - - void SetOutputHdl(const Link<Edit&, bool>& rLink) { m_aOutputHdl = rLink; } - void SetInputHdl(const Link<sal_Int64*,TriState>& rLink) { m_aInputHdl = rLink; } public: virtual void SetText( const OUString& rStr ) override; virtual void SetText( const OUString& rStr, const Selection& rNewSelection ) override; - //The following methods are interesting, if m_bTreatAsNumber is set to sal_False - //If someone does not care about all the double handling and just wants to print the text formatted. - //(((The text will be formatted, using the Formatter, and then set) - void SetTextFormatted(const OUString& rText); - OUString const & GetTextValue() const; - - void SetDefaultText(const OUString& rDefault) { m_sDefaultText = rDefault; } - const OUString& GetDefaultText() const { return m_sDefaultText; } - - // The last colour from the Formatter's last output operation. Output operations get triggered by: - // SetValue, SetTextValue, SetTextFormatted, also indirectly via SetMin - / -MaxValue - Color* GetLastOutputColor() const { return m_pLastOutputColor; } - - /** reformats the current text. Interesting if the user entered some text in an "input format", and - this should be formatted in the "output format" (which may differ, e.g. by additional numeric - digits or such). - */ - void Commit(); - - // enable automatic coloring. if set to sal_True, and the format the field is working with for any current value - // says that it has to be painted in a special color (e.g. a format where negative numbers should be printed - // red), the text is painted with that color automatically. - // The color used is the same as returned by GetLastOutputColor() - void SetAutoColor(bool _bAutomatic); - - /** enables handling of not-a-number value. - - When this is set to <FALSE/> (the default), then invalid inputs (i.e. text which cannot be - interpreted, according to the current formatting) will be handled as if the default value - has been entered. GetValue the will return this default value. - - When set to <TRUE/>, then GetValue will return NaN (not a number, see <method scope="rtl::math">isNan</method>) - when the current input is invalid. - - Note that setting this to <TRUE/> implies that upon leaving the control, the input - will *not* be corrected to a valid value. For example, if the user enters "foo" in the - control, and then tabs out of it, the text "foo" will persist, and GetValue will - return NaN in subsequent calls. - */ - void EnableNotANumber( bool _bEnable ); - - /** When being set to true, the strings in the field are formatted using the - InputLine format. That's also what you get in Calc when you edit a cell - using F2 - */ - void UseInputStringForFormatting(); - bool IsUsingInputStringForFormatting() const { return m_bUseInputStringForFormatting;} + void SetValueFromString(const OUString& rStr); // currently used by online virtual void DumpAsPropertyTree(tools::JsonWriter&) override; virtual FactoryFunction GetUITestFactory() const override; + // Formatter overrides + virtual Selection GetEntrySelection() const override; + virtual OUString GetEntryText() const override; + virtual void SetEntryText(const OUString& rText, const Selection& rSel) override; + virtual void SetEntryTextColor(const Color* pColor) override; + virtual SelectionOptions GetEntrySelectionOptions() const override; + virtual void FieldModified() override; + protected: virtual bool EventNotify(NotifyEvent& rNEvt) override; - void impl_Modify(bool makeValueDirty = true); virtual void Modify() override; - // Override CheckText for input-time checks - virtual bool CheckText(const OUString&) const { return true; } - - // any aspect of the current format has changed - virtual void FormatChanged(FORMAT_CHANGE_TYPE nWhat); - - void ImplSetTextImpl(const OUString& rNew, Selection const * pNewSel); - void ImplSetValue(double dValue, bool bForce); - bool ImplGetValue(double& dNewVal); - - void ImplSetFormatKey(sal_uLong nFormatKey); - // SetFormatKey without FormatChanged notification - - SvNumberFormatter* CreateFormatter() { SetFormatter(StandardFormatter()); return m_pFormatter; } - SvNumberFormatter* ImplGetFormatter() const { return m_pFormatter ? m_pFormatter : const_cast<FormattedField*>(this)->CreateFormatter(); } - bool PreNotify(NotifyEvent& rNEvt) override; - - void ReFormat(); -private: - Link<Edit&, bool> m_aOutputHdl; - Link<sal_Int64*, TriState> m_aInputHdl; }; class UNLESS_MERGELIBS(VCL_DLLPUBLIC) DoubleNumericField final : public FormattedField diff --git a/include/vcl/formatter.hxx b/include/vcl/formatter.hxx new file mode 100644 index 000000000000..8f02969635e9 --- /dev/null +++ b/include/vcl/formatter.hxx @@ -0,0 +1,261 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <config_options.h> +#include <vcl/settings.hxx> +#include <memory> + +class SvNumberFormatter; + +namespace validation { class NumberValidator; } + +enum class FORMAT_CHANGE_TYPE +{ + KEYONLY = 0x00, // only a new key was set + FORMATTER = 0x01, // a new formatter was set, usually implies a change of the key, too + PRECISION = 0x02, // a new precision was set + THOUSANDSSEP = 0x03, // the thousands separator setting changed + CURRENCY_SYMBOL = 0x10, + CURRSYM_POSITION = 0x20, +}; + +class VCL_DLLPUBLIC Formatter +{ +private: + // A SvNumberFormatter is very expensive (regarding time and space), it is a Singleton + class StaticFormatter + { + static SvNumberFormatter* s_cFormatter; + static sal_uLong s_nReferences; + public: + StaticFormatter(); + ~StaticFormatter(); + + operator SvNumberFormatter* () { return GetFormatter(); } + UNLESS_MERGELIBS(VCL_DLLPUBLIC) static SvNumberFormatter* GetFormatter(); + }; + +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, + // not yet through formatter) + Selection m_aLastSelection; + + double m_dMinValue; + double m_dMaxValue; + bool m_bHasMin : 1; + bool m_bHasMax : 1; + + bool m_bWrapOnLimits : 1; + bool m_bStrictFormat : 1; + + bool m_bEnableEmptyField : 1; + bool m_bAutoColor : 1; + bool m_bEnableNaN : 1; + bool m_bDisableRemainderFactor : 1; + enum valueState { valueDirty, valueString, valueDouble }; + valueState m_ValueState; + double m_dCurrentValue; + double m_dDefaultValue; + + sal_uLong m_nFormatKey; + SvNumberFormatter* m_pFormatter; + StaticFormatter m_aStaticFormatter; + + double m_dSpinSize; + double m_dSpinFirst; + double m_dSpinLast; + + // There is a difference, when text formatting is enabled, if LostFocus formats the current String and displays it, + // or if a double is created from the String and then + bool m_bTreatAsNumber; + // And with the following members we can use it for formatted text output as well ... + OUString m_sCurrentTextValue; + OUString m_sDefaultText; + + // The last color from the Formatter at the last output operation (not we would use it, but you can get it) + Color* m_pLastOutputColor; + + bool m_bUseInputStringForFormatting; + + Link<sal_Int64*, TriState> m_aInputHdl; + Link<LinkParamNone*, bool> m_aOutputHdl; + +public: + Formatter(); + virtual ~Formatter(); + + void SetFieldText(const OUString& rText, const Selection& rNewSelection); + + virtual Selection GetEntrySelection() const = 0; + virtual OUString GetEntryText() const = 0; + virtual SelectionOptions GetEntrySelectionOptions() const = 0; + virtual void SetEntryText(const OUString& rText, const Selection& rSel) = 0; + virtual void SetEntryTextColor(const Color* pColor) = 0; + virtual void FieldModified() = 0; + + // Min-/Max-management + bool HasMinValue() const { return m_bHasMin; } + void ClearMinValue() { m_bHasMin = false; } + void SetMinValue(double dMin); + double GetMinValue() const { return m_dMinValue; } + + bool HasMaxValue() const { return m_bHasMax; } + void ClearMaxValue() { m_bHasMax = false; } + void SetMaxValue(double dMax); + double GetMaxValue() const { return m_dMaxValue; } + + // Current value + void SetValue(double dVal); + double GetValue(); + // The default implementation uses a formatter, if available + + void SetTextValue(const OUString& rText); + // The String is transformed to a double (with a formatter) and SetValue is called afterwards + + bool IsEmptyFieldEnabled() const { return m_bEnableEmptyField; } + void EnableEmptyField(bool bEnable); + // If disabled, the value will be reset to the last valid value on leave + + void SetDefaultValue(double dDefault) { m_dDefaultValue = dDefault; m_ValueState = valueDirty; } + // If the current String is invalid, GetValue() returns this value + double GetDefaultValue() const { return m_dDefaultValue; } + + // Settings for the format + sal_uLong GetFormatKey() const { return m_nFormatKey; } + void SetFormatKey(sal_uLong nFormatKey); + + SvNumberFormatter* GetFormatter() const { return m_pFormatter; } + void SetFormatter(SvNumberFormatter* pFormatter, bool bResetFormat = true); + // If bResetFormat is sal_False, the old format is tried to be kept. (expensive, if it is no default format, available in all formatters) + // If sal_True, the new FormatKey is set to zero + + bool GetThousandsSep() const; + void SetThousandsSep(bool _bUseSeparator); + // the is no check if the current format is numeric, so be cautious when calling these functions + + void DisableRemainderFactor(); + + sal_uInt16 GetDecimalDigits() const; + void SetDecimalDigits(sal_uInt16 _nPrecision); + // There is no check if the current format is numeric, so be cautious when calling these functions + + SvNumberFormatter* StandardFormatter() { return m_aStaticFormatter; } + // If no new Formatter is created explicitly, this can be used in SetFormatter... + + OUString GetFormat(LanguageType& eLang) const; + bool SetFormat(const OUString& rFormatString, LanguageType eLang); + // sal_False, if the FormatString could not be set (and very probably is invalid) + // This Object is shared via all instances, so be careful! + + bool IsStrictFormat() const { return m_bStrictFormat; } + void SetStrictFormat(bool bEnable) { m_bStrictFormat = bEnable; } + // Check format during input + + void SetSpinSize(double dStep) { m_dSpinSize = dStep; } + double GetSpinSize() const { return m_dSpinSize; } + + void SetSpinFirst(double dFirst) { m_dSpinFirst = dFirst; } + double GetSpinFirst() const { return m_dSpinFirst; } + + void SetSpinLast(double dLast) { m_dSpinLast = dLast; } + double GetSpinLast() const { return m_dSpinLast; } + + bool TreatingAsNumber() const { return m_bTreatAsNumber; } + void TreatAsNumber(bool bDoSo) { m_bTreatAsNumber = bDoSo; } + + void SetInputHdl(const Link<sal_Int64*,TriState>& rLink) { m_aInputHdl = rLink; } + void SetOutputHdl(const Link<LinkParamNone*, bool>& rLink) { m_aOutputHdl = rLink; } +public: + + //The following methods are interesting, if m_bTreatAsNumber is set to sal_False + //If someone does not care about all the double handling and just wants to print the text formatted. + //(((The text will be formatted, using the Formatter, and then set) + void SetTextFormatted(const OUString& rText); + OUString const & GetTextValue() const; + + void SetDefaultText(const OUString& rDefault) { m_sDefaultText = rDefault; } + const OUString& GetDefaultText() const { return m_sDefaultText; } + + // The last colour from the Formatter's last output operation. Output operations get triggered by: + // SetValue, SetTextValue, SetTextFormatted, also indirectly via SetMin - / -MaxValue + Color* GetLastOutputColor() const { return m_pLastOutputColor; } + + /** reformats the current text. Interesting if the user entered some text in an "input format", and + this should be formatted in the "output format" (which may differ, e.g. by additional numeric + digits or such). + */ + void Commit(); + + // enable automatic coloring. if set to sal_True, and the format the field is working with for any current value + // says that it has to be painted in a special color (e.g. a format where negative numbers should be printed + // red), the text is painted with that color automatically. + // The color used is the same as returned by GetLastOutputColor() + void SetAutoColor(bool _bAutomatic); + + /** enables handling of not-a-number value. + + When this is set to <FALSE/> (the default), then invalid inputs (i.e. text which cannot be + interpreted, according to the current formatting) will be handled as if the default value + has been entered. GetValue the will return this default value. + + When set to <TRUE/>, then GetValue will return NaN (not a number, see <method scope="rtl::math">isNan</method>) + when the current input is invalid. + + Note that setting this to <TRUE/> implies that upon leaving the control, the input + will *not* be corrected to a valid value. For example, if the user enters "foo" in the + control, and then tabs out of it, the text "foo" will persist, and GetValue will + return NaN in subsequent calls. + */ + void EnableNotANumber( bool _bEnable ); + + /** When being set to true, the strings in the field are formatted using the + InputLine format. That's also what you get in Calc when you edit a cell + using F2 + */ + void UseInputStringForFormatting(); + bool IsUsingInputStringForFormatting() const { return m_bUseInputStringForFormatting;} + +protected: + void impl_Modify(bool makeValueDirty = true); + + // Override CheckText for input-time checks + virtual bool CheckText(const OUString&) const { return true; } + + // any aspect of the current format has changed + virtual void FormatChanged(FORMAT_CHANGE_TYPE nWhat); + + void ImplSetTextImpl(const OUString& rNew, Selection const * pNewSel); + void ImplSetValue(double dValue, bool bForce); + bool ImplGetValue(double& dNewVal); + + void ImplSetFormatKey(sal_uLong nFormatKey); + // SetFormatKey without FormatChanged notification + + void EntryLostFocus(); + + SvNumberFormatter* CreateFormatter() { SetFormatter(StandardFormatter()); return m_pFormatter; } + SvNumberFormatter* ImplGetFormatter() const { return m_pFormatter ? m_pFormatter : const_cast<Formatter*>(this)->CreateFormatter(); } + + void ReFormat(); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/solenv/clang-format/blacklist b/solenv/clang-format/blacklist index 52d307c81f1b..65e2e76c035a 100644 --- a/solenv/clang-format/blacklist +++ b/solenv/clang-format/blacklist @@ -7350,6 +7350,7 @@ include/vcl/extoutdevdata.hxx include/vcl/field.hxx include/vcl/fixed.hxx include/vcl/floatwin.hxx +include/vcl/formatter.hxx include/vcl/fmtfield.hxx include/vcl/fntstyle.hxx include/vcl/font.hxx diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx index 7e1e0dc9defa..d44ad491a628 100644 --- a/vcl/inc/salvtables.hxx +++ b/vcl/inc/salvtables.hxx @@ -619,7 +619,7 @@ private: DECL_LINK(UpDownHdl, SpinField&, void); DECL_LINK(LoseFocusHdl, Control&, void); - DECL_LINK(OutputHdl, Edit&, bool); + DECL_LINK(OutputHdl, LinkParamNone*, bool); DECL_LINK(InputHdl, sal_Int64*, TriState); DECL_LINK(ActivateHdl, Edit&, bool); diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index cd1109bb4f36..67f26faf9e59 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -5300,7 +5300,7 @@ SalInstanceSpinButton::~SalInstanceSpinButton() else m_xButton->SetActivateHdl(Link<Edit&, bool>()); m_xButton->SetInputHdl(Link<sal_Int64*, TriState>()); - m_xButton->SetOutputHdl(Link<Edit&, bool>()); + m_xButton->SetOutputHdl(Link<LinkParamNone*, bool>()); m_xButton->SetLoseFocusHdl(Link<Control&, void>()); m_xButton->SetDownHdl(Link<SpinField&, void>()); m_xButton->SetUpHdl(Link<SpinField&, void>()); @@ -5317,7 +5317,7 @@ IMPL_LINK_NOARG(SalInstanceSpinButton, UpDownHdl, SpinField&, void) { signal_val IMPL_LINK_NOARG(SalInstanceSpinButton, LoseFocusHdl, Control&, void) { signal_value_changed(); } -IMPL_LINK_NOARG(SalInstanceSpinButton, OutputHdl, Edit&, bool) { return signal_output(); } +IMPL_LINK_NOARG(SalInstanceSpinButton, OutputHdl, LinkParamNone*, bool) { return signal_output(); } IMPL_LINK(SalInstanceSpinButton, InputHdl, sal_Int64*, pResult, TriState) { @@ -5336,7 +5336,7 @@ class SalInstanceFormattedSpinButton : public SalInstanceEntry, private: VclPtr<FormattedField> m_xButton; - DECL_LINK(OutputHdl, Edit&, bool); + DECL_LINK(OutputHdl, LinkParamNone*, bool); DECL_LINK(InputHdl, sal_Int64*, TriState); public: @@ -5358,7 +5358,7 @@ public: virtual ~SalInstanceFormattedSpinButton() override { m_xButton->SetInputHdl(Link<sal_Int64*, TriState>()); - m_xButton->SetOutputHdl(Link<Edit&, bool>()); + m_xButton->SetOutputHdl(Link<LinkParamNone*, bool>()); } virtual double get_value() const override { return m_xButton->GetValue(); } @@ -5401,7 +5401,7 @@ public: virtual void set_digits(unsigned int digits) override { m_xButton->SetDecimalDigits(digits); } }; -IMPL_LINK_NOARG(SalInstanceFormattedSpinButton, OutputHdl, Edit&, bool) +IMPL_LINK_NOARG(SalInstanceFormattedSpinButton, OutputHdl, LinkParamNone*, bool) { // allow an explicit handler if (!m_aOutputHdl.IsSet()) diff --git a/vcl/source/control/fmtfield.cxx b/vcl/source/control/fmtfield.cxx index c00a721250dc..f3a703cc3306 100644 --- a/vcl/source/control/fmtfield.cxx +++ b/vcl/source/control/fmtfield.cxx @@ -296,9 +296,8 @@ FormattedField::StaticFormatter::~StaticFormatter() } } -FormattedField::FormattedField(vcl::Window* pParent, WinBits nStyle) - :SpinField(pParent, nStyle, WindowType::FORMATTEDFIELD) - ,m_aLastSelection(0,0) +Formatter::Formatter() + :m_aLastSelection(0,0) ,m_dMinValue(0) ,m_dMaxValue(0) ,m_bHasMin(false) @@ -323,21 +322,17 @@ FormattedField::FormattedField(vcl::Window* pParent, WinBits nStyle) { } -void FormattedField::SetText(const OUString& rStr) +Formatter::~Formatter() { - - SpinField::SetText(rStr); - m_ValueState = valueDirty; } -void FormattedField::SetText( const OUString& rStr, const Selection& rNewSelection ) +void Formatter::SetFieldText(const OUString& rStr, const Selection& rNewSelection) { - - SpinField::SetText( rStr, rNewSelection ); + SetEntryText(rStr, rNewSelection); m_ValueState = valueDirty; } -void FormattedField::SetTextFormatted(const OUString& rStr) +void Formatter::SetTextFormatted(const OUString& rStr) { SAL_INFO_IF(ImplGetFormatter()->IsTextFormat(m_nFormatKey), "svtools", "FormattedField::SetTextFormatted : valid only with text formats !"); @@ -362,11 +357,11 @@ void FormattedField::SetTextFormatted(const OUString& rStr) } // calculate the new selection - Selection aSel(GetSelection()); + Selection aSel(GetEntrySelection()); Selection aNewSel(aSel); aNewSel.Justify(); sal_Int32 nNewLen = sFormatted.getLength(); - sal_Int32 nCurrentLen = GetText().getLength(); + sal_Int32 nCurrentLen = GetEntryText().getLength(); if ((nNewLen > nCurrentLen) && (aNewSel.Max() == nCurrentLen)) { // the new text is longer and the cursor was behind the last char (of the old text) if (aNewSel.Min() == 0) @@ -374,7 +369,7 @@ void FormattedField::SetTextFormatted(const OUString& rStr) aNewSel.Max() = nNewLen; if (!nCurrentLen) { // there wasn't really a previous selection (as there was no previous text), we're setting a new one -> check the selection options - SelectionOptions nSelOptions = GetSettings().GetStyleSettings().GetSelectionOptions(); + SelectionOptions nSelOptions = GetEntrySelectionOptions(); if (nSelOptions & SelectionOptions::ShowFirst) { // selection should be from right to left -> swap min and max aNewSel.Min() = aNewSel.Max(); @@ -392,21 +387,21 @@ void FormattedField::SetTextFormatted(const OUString& rStr) aNewSel.Max() = nNewLen; else aNewSel = aSel; // don't use the justified version - SpinField::SetText(sFormatted, aNewSel); + SetEntryText(sFormatted, aNewSel); m_ValueState = valueString; } -OUString const & FormattedField::GetTextValue() const +OUString const & Formatter::GetTextValue() const { if (m_ValueState != valueString ) { - const_cast<FormattedField*>(this)->m_sCurrentTextValue = GetText(); - const_cast<FormattedField*>(this)->m_ValueState = valueString; + const_cast<Formatter*>(this)->m_sCurrentTextValue = GetEntryText(); + const_cast<Formatter*>(this)->m_ValueState = valueString; } return m_sCurrentTextValue; } -void FormattedField::EnableNotANumber( bool _bEnable ) +void Formatter::EnableNotANumber(bool _bEnable) { if ( m_bEnableNaN == _bEnable ) return; @@ -414,37 +409,34 @@ void FormattedField::EnableNotANumber( bool _bEnable ) m_bEnableNaN = _bEnable; } -void FormattedField::SetAutoColor(bool _bAutomatic) +void Formatter::SetAutoColor(bool _bAutomatic) { if (_bAutomatic == m_bAutoColor) return; m_bAutoColor = _bAutomatic; if (m_bAutoColor) - { // if auto color is switched on, adjust the current text color, too - if (m_pLastOutputColor) - SetControlForeground(*m_pLastOutputColor); - else - SetControlForeground(); + { + // if auto color is switched on, adjust the current text color, too + SetEntryTextColor(m_pLastOutputColor); } } -void FormattedField::impl_Modify(bool makeValueDirty) +void Formatter::impl_Modify(bool makeValueDirty) { - if (!IsStrictFormat()) { if(makeValueDirty) m_ValueState = valueDirty; - SpinField::Modify(); + FieldModified(); return; } - OUString sCheck = GetText(); + OUString sCheck = GetEntryText(); if (CheckText(sCheck)) { m_sLastValidText = sCheck; - m_aLastSelection = GetSelection(); + m_aLastSelection = GetEntrySelection(); if(makeValueDirty) m_ValueState = valueDirty; } @@ -453,35 +445,23 @@ void FormattedField::impl_Modify(bool makeValueDirty) ImplSetTextImpl(m_sLastValidText, &m_aLastSelection); } - SpinField::Modify(); -} - -void FormattedField::Modify() -{ - - impl_Modify(); + FieldModified(); } -void FormattedField::ImplSetTextImpl(const OUString& rNew, Selection const * pNewSel) +void Formatter::ImplSetTextImpl(const OUString& rNew, Selection const * pNewSel) { - if (m_bAutoColor) - { - if (m_pLastOutputColor) - SetControlForeground(*m_pLastOutputColor); - else - SetControlForeground(); - } + SetEntryTextColor(m_pLastOutputColor); if (pNewSel) - SpinField::SetText(rNew, *pNewSel); + SetEntryText(rNew, *pNewSel); else { - Selection aSel(GetSelection()); + Selection aSel(GetEntrySelection()); aSel.Justify(); sal_Int32 nNewLen = rNew.getLength(); - sal_Int32 nCurrentLen = GetText().getLength(); + sal_Int32 nCurrentLen = GetEntryText().getLength(); if ((nNewLen > nCurrentLen) && (aSel.Max() == nCurrentLen)) { // new text is longer and the cursor is behind the last char @@ -504,20 +484,13 @@ void FormattedField::ImplSetTextImpl(const OUString& rNew, Selection const * pNe } else if (aSel.Max() > nNewLen) aSel.Max() = nNewLen; - SpinField::SetText(rNew, aSel); + SetEntryText(rNew, aSel); } m_ValueState = valueDirty; // not always necessary, but better re-evaluate for safety reasons } -bool FormattedField::PreNotify(NotifyEvent& rNEvt) -{ - if (rNEvt.GetType() == MouseNotifyEvent::KEYINPUT) - m_aLastSelection = GetSelection(); - return SpinField::PreNotify(rNEvt); -} - -void FormattedField::ImplSetFormatKey(sal_uLong nFormatKey) +void Formatter::ImplSetFormatKey(sal_uLong nFormatKey) { m_nFormatKey = nFormatKey; @@ -536,14 +509,14 @@ void FormattedField::ImplSetFormatKey(sal_uLong nFormatKey) } } -void FormattedField::SetFormatKey(sal_uLong nFormatKey) +void Formatter::SetFormatKey(sal_uLong nFormatKey) { bool bNoFormatter = (m_pFormatter == nullptr); ImplSetFormatKey(nFormatKey); FormatChanged((bNoFormatter && (m_pFormatter != nullptr)) ? FORMAT_CHANGE_TYPE::FORMATTER : FORMAT_CHANGE_TYPE::KEYONLY); } -void FormattedField::SetFormatter(SvNumberFormatter* pFormatter, bool bResetFormat) +void Formatter::SetFormatter(SvNumberFormatter* pFormatter, bool bResetFormat) { if (bResetFormat) @@ -585,7 +558,7 @@ void FormattedField::SetFormatter(SvNumberFormatter* pFormatter, bool bResetForm FormatChanged(FORMAT_CHANGE_TYPE::FORMATTER); } -OUString FormattedField::GetFormat(LanguageType& eLang) const +OUString Formatter::GetFormat(LanguageType& eLang) const { const SvNumberformat* pFormatEntry = ImplGetFormatter()->GetEntry(m_nFormatKey); DBG_ASSERT(pFormatEntry != nullptr, "FormattedField::GetFormat: no number format for the given format key."); @@ -595,7 +568,7 @@ OUString FormattedField::GetFormat(LanguageType& eLang) const return sFormatString; } -bool FormattedField::SetFormat(const OUString& rFormatString, LanguageType eLang) +bool Formatter::SetFormat(const OUString& rFormatString, LanguageType eLang) { sal_uInt32 nNewKey = ImplGetFormatter()->TestNewString(rFormatString, eLang); if (nNewKey == NUMBERFORMAT_ENTRY_NOT_FOUND) @@ -613,7 +586,7 @@ bool FormattedField::SetFormat(const OUString& rFormatString, LanguageType eLang return true; } -bool FormattedField::GetThousandsSep() const +bool Formatter::GetThousandsSep() const { DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey), "FormattedField::GetThousandsSep : Are you sure what you are doing when setting the precision of a text format?"); @@ -625,7 +598,7 @@ bool FormattedField::GetThousandsSep() const return bThousand; } -void FormattedField::SetThousandsSep(bool _bUseSeparator) +void Formatter::SetThousandsSep(bool _bUseSeparator) { DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey), "FormattedField::SetThousandsSep : Are you sure what you are doing when setting the precision of a text format?"); @@ -654,7 +627,7 @@ void FormattedField::SetThousandsSep(bool _bUseSeparator) FormatChanged(FORMAT_CHANGE_TYPE::THOUSANDSSEP); } -sal_uInt16 FormattedField::GetDecimalDigits() const +sal_uInt16 Formatter::GetDecimalDigits() const { DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey), "FormattedField::GetDecimalDigits : Are you sure what you are doing when setting the precision of a text format?"); @@ -666,7 +639,7 @@ sal_uInt16 FormattedField::GetDecimalDigits() const return nPrecision; } -void FormattedField::SetDecimalDigits(sal_uInt16 _nPrecision) +void Formatter::SetDecimalDigits(sal_uInt16 _nPrecision) { DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey), "FormattedField::SetDecimalDigits : Are you sure what you are doing when setting the precision of a text format?"); @@ -695,7 +668,7 @@ void FormattedField::SetDecimalDigits(sal_uInt16 _nPrecision) FormatChanged(FORMAT_CHANGE_TYPE::PRECISION); } -void FormattedField::FormatChanged( FORMAT_CHANGE_TYPE _nWhat ) +void Formatter::FormatChanged(FORMAT_CHANGE_TYPE _nWhat) { m_pLastOutputColor = nullptr; @@ -705,16 +678,46 @@ void FormattedField::FormatChanged( FORMAT_CHANGE_TYPE _nWhat ) ReFormat(); } -void FormattedField::Commit() +void Formatter::EntryLostFocus() +{ + // special treatment for empty texts + if (GetEntryText().isEmpty()) + { + if (!IsEmptyFieldEnabled()) + { + if (TreatingAsNumber()) + { + ImplSetValue(m_dCurrentValue, true); + impl_Modify(); + m_ValueState = valueDouble; + } + else + { + OUString sNew = GetTextValue(); + if (!sNew.isEmpty()) + SetTextFormatted(sNew); + else + SetTextFormatted(m_sDefaultText); + m_ValueState = valueString; + } + } + } + else + { + Commit(); + } +} + +void Formatter::Commit() { // remember the old text - OUString sOld( GetText() ); + OUString sOld(GetEntryText()); // do the reformat ReFormat(); // did the text change? - if ( GetText() != sOld ) + if (GetEntryText() != sOld) { // consider the field as modified, // but we already have the most recent value; // don't reparse it from the text @@ -724,9 +727,9 @@ void FormattedField::Commit() } } -void FormattedField::ReFormat() +void Formatter::ReFormat() { - if (!IsEmptyFieldEnabled() || !GetText().isEmpty()) + if (!IsEmptyFieldEnabled() || !GetEntryText().isEmpty()) { if (TreatingAsNumber()) { @@ -740,78 +743,8 @@ void FormattedField::ReFormat() } } -bool FormattedField::EventNotify(NotifyEvent& rNEvt) -{ - - if ((rNEvt.GetType() == MouseNotifyEvent::KEYINPUT) && !IsReadOnly()) - { - const KeyEvent& rKEvt = *rNEvt.GetKeyEvent(); - sal_uInt16 nMod = rKEvt.GetKeyCode().GetModifier(); - switch ( rKEvt.GetKeyCode().GetCode() ) - { - case KEY_UP: - case KEY_DOWN: - case KEY_PAGEUP: - case KEY_PAGEDOWN: - if (!nMod && ImplGetFormatter()->IsTextFormat(m_nFormatKey)) - { - // 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; - } - } - } - - if ((rNEvt.GetType() == MouseNotifyEvent::COMMAND) && !IsReadOnly()) - { - const CommandEvent* pCommand = rNEvt.GetCommandEvent(); - if (pCommand->GetCommand() == CommandEventId::Wheel) - { - const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData(); - if ((pData->GetMode() == CommandWheelMode::SCROLL) && ImplGetFormatter()->IsTextFormat(m_nFormatKey)) - { - // 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 ?) - // FS - 71553 - 19.01.00 - return true; - } - } - } - if (rNEvt.GetType() == MouseNotifyEvent::LOSEFOCUS) - { - // special treatment for empty texts - if (GetText().isEmpty()) - { - if (!IsEmptyFieldEnabled()) - { - if (TreatingAsNumber()) - { - ImplSetValue(m_dCurrentValue, true); - Modify(); - m_ValueState = valueDouble; - } - else - { - OUString sNew = GetTextValue(); - if (!sNew.isEmpty()) - SetTextFormatted(sNew); - else - SetTextFormatted(m_sDefaultText); - m_ValueState = valueString; - } - } - } - else - { - Commit(); - } - } - - return SpinField::EventNotify( rNEvt ); -} - -void FormattedField::SetMinValue(double dMin) +void Formatter::SetMinValue(double dMin) { DBG_ASSERT(m_bTreatAsNumber, "FormattedField::SetMinValue : only to be used in numeric mode !"); @@ -821,7 +754,7 @@ void FormattedField::SetMinValue(double dMin) ReFormat(); } -void FormattedField::SetMaxValue(double dMax) +void Formatter::SetMaxValue(double dMax) { DBG_ASSERT(m_bTreatAsNumber, "FormattedField::SetMaxValue : only to be used in numeric mode !"); @@ -831,46 +764,23 @@ void FormattedField::SetMaxValue(double dMax) ReFormat(); } -void FormattedField::SetTextValue(const OUString& rText) +void Formatter::SetTextValue(const OUString& rText) { - SetText(rText); + SetFieldText(rText, Selection(0, 0)); ReFormat(); } -// currently used by online -void FormattedField::SetValueFromString(const OUString& rStr) -{ - sal_Int32 nEnd; - rtl_math_ConversionStatus eStatus; - double fValue = ::rtl::math::stringToDouble(rStr, '.', GetDecimalDigits(), &eStatus, &nEnd ); - - if (eStatus == rtl_math_ConversionStatus_Ok && - nEnd == rStr.getLength()) - { - SetValue(fValue); - SetModifyFlag(); - Modify(); - - // Notify the value has changed - SpinField::Up(); - } - else - { - SAL_WARN("vcl", "fail to convert the value: " << rStr); - } -} - -void FormattedField::EnableEmptyField(bool bEnable) +void Formatter::EnableEmptyField(bool bEnable) { if (bEnable == m_bEnableEmptyField) return; m_bEnableEmptyField = bEnable; - if (!m_bEnableEmptyField && GetText().isEmpty()) + if (!m_bEnableEmptyField && GetEntryText().isEmpty()) ImplSetValue(m_dCurrentValue, true); } -void FormattedField::ImplSetValue(double dVal, bool bForce) +void Formatter::ImplSetValue(double dVal, bool bForce) { if (m_bHasMin && (dVal<m_dMinValue)) { @@ -890,7 +800,7 @@ void FormattedField::ImplSetValue(double dVal, bool bForce) m_ValueState = valueDouble; m_dCurrentValue = dVal; - if (!m_aOutputHdl.IsSet() || !m_aOutputHdl.Call(*this)) + if (!m_aOutputHdl.IsSet() || !m_aOutputHdl.Call(nullptr)) { OUString sNewText; if (ImplGetFormatter()->IsTextFormat(m_nFormatKey)) @@ -919,14 +829,14 @@ void FormattedField::ImplSetValue(double dVal, bool bForce) m_ValueState = valueDouble; } -bool FormattedField::ImplGetValue(double& dNewVal) +bool Formatter::ImplGetValue(double& dNewVal) { dNewVal = m_dCurrentValue; if (m_ValueState == valueDouble) return true; dNewVal = m_dDefaultValue; - OUString sText(GetText()); + OUString sText(GetEntryText()); if (sText.isEmpty()) return true; @@ -987,12 +897,12 @@ bool FormattedField::ImplGetValue(double& dNewVal) return true; } -void FormattedField::SetValue(double dVal) +void Formatter::SetValue(double dVal) { ImplSetValue(dVal, m_ValueState != valueDouble); } -double FormattedField::GetValue() +double Formatter::GetValue() { if ( !ImplGetValue( m_dCurrentValue ) ) @@ -1007,104 +917,17 @@ double FormattedField::GetValue() return m_dCurrentValue; } -void FormattedField::DisableRemainderFactor() +void Formatter::DisableRemainderFactor() { m_bDisableRemainderFactor = true; } -bool FormattedField::set_property(const OString &rKey, const OUString &rValue) -{ - if (rKey == "digits") - SetDecimalDigits(rValue.toInt32()); - else if (rKey == "wrap") - m_bWrapOnLimits = toBool(rValue); - else - return SpinField::set_property(rKey, rValue); - return true; -} -void FormattedField::Up() -{ - auto nScale = weld::SpinButton::Power10(GetDecimalDigits()); - - sal_Int64 nValue = std::round(GetValue() * nScale); - sal_Int64 nSpinSize = std::round(m_dSpinSize * nScale); - sal_Int64 nRemainder = m_bDisableRemainderFactor ? 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); - SetModifyFlag(); - Modify(); - - SpinField::Up(); -} - -void FormattedField::Down() -{ - auto nScale = weld::SpinButton::Power10(GetDecimalDigits()); - - sal_Int64 nValue = std::round(GetValue() * nScale); - sal_Int64 nSpinSize = std::round(m_dSpinSize * nScale); - sal_Int64 nRemainder = m_bDisableRemainderFactor ? 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); - SetModifyFlag(); - Modify(); - - SpinField::Down(); -} - -void FormattedField::First() -{ - if (m_bHasMin) - { - SetValue(m_dMinValue); - SetModifyFlag(); - Modify(); - } - - SpinField::First(); -} - -void FormattedField::Last() -{ - if (m_bHasMax) - { - SetValue(m_dMaxValue); - SetModifyFlag(); - Modify(); - } - - SpinField::Last(); -} - -void FormattedField::UseInputStringForFormatting() +void Formatter::UseInputStringForFormatting() { m_bUseInputStringForFormatting = true; } -void FormattedField::DumpAsPropertyTree(tools::JsonWriter& rJsonWriter) -{ - SpinField::DumpAsPropertyTree(rJsonWriter); - rJsonWriter.put("min", GetMinValue()); - rJsonWriter.put("max", GetMaxValue()); - rJsonWriter.put("value", GetValue()); -} - -FactoryFunction FormattedField::GetUITestFactory() const -{ - return FormattedFieldUIObject::create; -} - DoubleNumericField::DoubleNumericField(vcl::Window* pParent, WinBits nStyle) : FormattedField(pParent, nStyle) { @@ -1284,4 +1107,220 @@ void DoubleCurrencyField::UpdateCurrencyFormat() m_bChangingFormat = false; } +FormattedField::FormattedField(vcl::Window* pParent, WinBits nStyle) + : SpinField(pParent, nStyle, WindowType::FORMATTEDFIELD) +{ +} + +void FormattedField::SetText(const OUString& rStr) +{ + SetFieldText(rStr, Selection(0, 0)); +} + +void FormattedField::SetText(const OUString& rStr, const Selection& rNewSelection) +{ + SetFieldText(rStr, rNewSelection); + SetSelection(rNewSelection); +} + +bool FormattedField::set_property(const OString &rKey, const OUString &rValue) +{ + if (rKey == "digits") + SetDecimalDigits(rValue.toInt32()); + else if (rKey == "wrap") + m_bWrapOnLimits = toBool(rValue); + else + return SpinField::set_property(rKey, rValue); + return true; +} + +void FormattedField::Up() +{ + auto nScale = weld::SpinButton::Power10(GetDecimalDigits()); + + sal_Int64 nValue = std::round(GetValue() * nScale); + sal_Int64 nSpinSize = std::round(m_dSpinSize * nScale); + sal_Int64 nRemainder = m_bDisableRemainderFactor ? 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); + SetModifyFlag(); + Modify(); + + SpinField::Up(); +} + +void FormattedField::Down() +{ + auto nScale = weld::SpinButton::Power10(GetDecimalDigits()); + + sal_Int64 nValue = std::round(GetValue() * nScale); + sal_Int64 nSpinSize = std::round(m_dSpinSize * nScale); + sal_Int64 nRemainder = m_bDisableRemainderFactor ? 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); + SetModifyFlag(); + Modify(); + + SpinField::Down(); +} + +void FormattedField::First() +{ + if (m_bHasMin) + { + SetValue(m_dMinValue); + SetModifyFlag(); + Modify(); + } + + SpinField::First(); +} + +void FormattedField::Last() +{ + if (m_bHasMax) + { + SetValue(m_dMaxValue); + SetModifyFlag(); + Modify(); + } + + SpinField::Last(); +} + +void FormattedField::Modify() +{ + impl_Modify(); +} + +bool FormattedField::PreNotify(NotifyEvent& rNEvt) +{ + if (rNEvt.GetType() == MouseNotifyEvent::KEYINPUT) + m_aLastSelection = GetSelection(); + return SpinField::PreNotify(rNEvt); +} + +bool FormattedField::EventNotify(NotifyEvent& rNEvt) +{ + + if ((rNEvt.GetType() == MouseNotifyEvent::KEYINPUT) && !IsReadOnly()) + { + const KeyEvent& rKEvt = *rNEvt.GetKeyEvent(); + sal_uInt16 nMod = rKEvt.GetKeyCode().GetModifier(); + switch ( rKEvt.GetKeyCode().GetCode() ) + { + case KEY_UP: + case KEY_DOWN: + case KEY_PAGEUP: + case KEY_PAGEDOWN: + if (!nMod && ImplGetFormatter()->IsTextFormat(m_nFormatKey)) + { + // 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; + } + } + } + + if ((rNEvt.GetType() == MouseNotifyEvent::COMMAND) && !IsReadOnly()) + { + const CommandEvent* pCommand = rNEvt.GetCommandEvent(); + if (pCommand->GetCommand() == CommandEventId::Wheel) + { + const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData(); + if ((pData->GetMode() == CommandWheelMode::SCROLL) && ImplGetFormatter()->IsTextFormat(m_nFormatKey)) + { + // 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 ?) + // FS - 71553 - 19.01.00 + return true; + } + } + } + + if (rNEvt.GetType() == MouseNotifyEvent::LOSEFOCUS) + 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() +{ + SpinField::Modify(); +} + +// currently used by online +void FormattedField::SetValueFromString(const OUString& rStr) +{ + sal_Int32 nEnd; + rtl_math_ConversionStatus eStatus; + double fValue = ::rtl::math::stringToDouble(rStr, '.', GetDecimalDigits(), &eStatus, &nEnd ); + + if (eStatus == rtl_math_ConversionStatus_Ok && + nEnd == rStr.getLength()) + { + SetValue(fValue); + SetModifyFlag(); + Modify(); + + // Notify the value has changed + SpinField::Up(); + } + else + { + SAL_WARN("vcl", "fail to convert the value: " << rStr); + } +} + +void FormattedField::DumpAsPropertyTree(tools::JsonWriter& rJsonWriter) +{ + SpinField::DumpAsPropertyTree(rJsonWriter); + rJsonWriter.put("min", GetMinValue()); + rJsonWriter.put("max", GetMaxValue()); + rJsonWriter.put("value", GetValue()); +} + +FactoryFunction FormattedField::GetUITestFactory() const +{ + return FormattedFieldUIObject::create; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits