[Libreoffice-commits] core.git: include/vcl solenv/clang-format vcl/inc vcl/source
Caolán McNamara (via logerrit)
logerrit at kemper.freedesktop.org
Wed Jul 1 19:13:32 UTC 2020
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 <caolanm at redhat.com>
AuthorDate: Wed Jul 1 15:49:57 2020 +0100
Commit: Caolán McNamara <caolanm at 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 <caolanm at 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: */
More information about the Libreoffice-commits
mailing list