summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2020-07-03 09:57:44 +0100
committerCaolán McNamara <caolanm@redhat.com>2020-07-05 16:44:58 +0200
commit697f635fb8316d2c325ccdf9040cd0e371cdd6e5 (patch)
treec8b2c0b7b83337efa53ee3b5eaafa1a86ff3c2b7
parentef371319fa5f6b076d6d2edc8f252bbb94fd77f0 (diff)
add a DoubleNumericEntry
Change-Id: I866f078531779cbffb22035848dc88e0039c5ba0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97889 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--include/vcl/weldutils.hxx17
-rw-r--r--vcl/source/app/weldutils.cxx53
2 files changed, 70 insertions, 0 deletions
diff --git a/include/vcl/weldutils.hxx b/include/vcl/weldutils.hxx
index 757303fdcabf..84e647835863 100644
--- a/include/vcl/weldutils.hxx
+++ b/include/vcl/weldutils.hxx
@@ -202,6 +202,23 @@ private:
virtual void UpdateCurrentValue(double dCurrentValue) override;
};
+class VCL_DLLPUBLIC DoubleNumericEntry final : public EntryFormatter
+{
+public:
+ DoubleNumericEntry(weld::Entry& rEntry);
+ DoubleNumericEntry(weld::FormattedSpinButton& rSpinButton);
+
+ virtual ~DoubleNumericEntry() override;
+
+private:
+ virtual bool CheckText(const OUString& sText) const override;
+
+ virtual void FormatChanged(FORMAT_CHANGE_TYPE nWhat) override;
+ void ResetConformanceTester();
+
+ std::unique_ptr<validation::NumberValidator> m_pNumberValidator;
+};
+
// get the row the iterator is on
VCL_DLLPUBLIC size_t GetAbsPos(const weld::TreeView& rTreeView, const weld::TreeIter& rIter);
diff --git a/vcl/source/app/weldutils.cxx b/vcl/source/app/weldutils.cxx
index f560923e5609..329d15827b70 100644
--- a/vcl/source/app/weldutils.cxx
+++ b/vcl/source/app/weldutils.cxx
@@ -7,6 +7,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
#include <vcl/builderpage.hxx>
#include <vcl/commandinfoprovider.hxx>
#include <vcl/settings.hxx>
@@ -234,6 +236,57 @@ IMPL_LINK_NOARG(EntryFormatter, FocusOutHdl, weld::Widget&, void)
m_aFocusOutHdl.Call(m_rEntry);
}
+DoubleNumericEntry::DoubleNumericEntry(weld::Entry& rEntry)
+ : EntryFormatter(rEntry)
+{
+ ResetConformanceTester();
+}
+
+DoubleNumericEntry::DoubleNumericEntry(weld::FormattedSpinButton& rSpinButton)
+ : EntryFormatter(rSpinButton)
+{
+ ResetConformanceTester();
+}
+
+DoubleNumericEntry::~DoubleNumericEntry() = default;
+
+void DoubleNumericEntry::FormatChanged(FORMAT_CHANGE_TYPE nWhat)
+{
+ ResetConformanceTester();
+ EntryFormatter::FormatChanged(nWhat);
+}
+
+bool DoubleNumericEntry::CheckText(const OUString& sText) const
+{
+ // We'd like to implement this using the NumberFormatter::IsNumberFormat, but unfortunately, this doesn't
+ // recognize fragments of numbers (like, for instance "1e", which happens during entering e.g. "1e10")
+ // Thus, the roundabout way via a regular expression
+ return m_pNumberValidator->isValidNumericFragment(sText);
+}
+
+void DoubleNumericEntry::ResetConformanceTester()
+{
+ // the thousands and the decimal separator are language dependent
+ const SvNumberformat* pFormatEntry = GetOrCreateFormatter()->GetEntry(m_nFormatKey);
+
+ sal_Unicode cSeparatorThousand = ',';
+ sal_Unicode cSeparatorDecimal = '.';
+ if (pFormatEntry)
+ {
+ LocaleDataWrapper aLocaleInfo(LanguageTag(pFormatEntry->GetLanguage()));
+
+ OUString sSeparator = aLocaleInfo.getNumThousandSep();
+ if (!sSeparator.isEmpty())
+ cSeparatorThousand = sSeparator[0];
+
+ sSeparator = aLocaleInfo.getNumDecimalSep();
+ if (!sSeparator.isEmpty())
+ cSeparatorDecimal = sSeparator[0];
+ }
+
+ m_pNumberValidator.reset(
+ new validation::NumberValidator(cSeparatorThousand, cSeparatorDecimal));
+}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */