LibreOffice Module vcl (master)  1
formatter.hxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #pragma once
21 
22 #include <config_options.h>
23 #include <i18nlangtag/lang.h>
24 #include <tools/link.hxx>
25 #include <tools/solar.h>
26 #include <vcl/settings.hxx>
27 #include <map>
28 #include <memory>
29 #include <string_view>
30 
31 class SvNumberFormatter;
32 
33 namespace validation
34 {
35  // the states of our automat.
36  enum State
37  {
38  START, // at the very start of the string
39  NUM_START, // the very start of the number
40 
41  DIGIT_PRE_COMMA, // some pre-comma digits are read, perhaps including some thousand separators
42 
43  DIGIT_POST_COMMA, // reading digits after the comma
44  EXPONENT_START, // at the very start of the exponent value
45  // (means: not including the "e" which denotes the exponent)
46  EXPONENT_DIGIT, // currently reading the digits of the exponent
47 
48  END // reached the end of the string
49  };
50 
51  // a row in the transition table (means the set of states to be reached from a given state)
52  typedef ::std::map< sal_Unicode, State > StateTransitions;
53 
54  // a single transition
55  typedef StateTransitions::value_type Transition;
56 
57  // the complete transition table
58  typedef ::std::map< State, StateTransitions > TransitionTable;
59 
60  // the validator class
62  {
63  private:
64  TransitionTable m_aTransitions;
65 
66  public:
67  NumberValidator( const sal_Unicode _cThSep, const sal_Unicode _cDecSep );
68 
69  bool isValidNumericFragment( std::u16string_view _rText );
70 
71  private:
72  bool implValidateNormalized( const OUString& _rText );
73  };
74 }
75 
77 {
78  KEYONLY = 0x00, // only a new key was set
79  FORMATTER = 0x01, // a new formatter was set, usually implies a change of the key, too
80  PRECISION = 0x02, // a new precision was set
81  THOUSANDSSEP = 0x03, // the thousands separator setting changed
82  CURRENCY_SYMBOL = 0x10,
83  CURRSYM_POSITION = 0x20,
84 };
85 
87 {
88 public:
89  // A SvNumberFormatter is very expensive (regarding time and space), it is a Singleton
91  {
94  public:
96  ~StaticFormatter();
97 
98  operator SvNumberFormatter* () const { return GetFormatter(); }
99  UNLESS_MERGELIBS(VCL_DLLPUBLIC) static SvNumberFormatter* GetFormatter();
100  };
101 
102 protected:
103  OUString m_sLastValidText;
104  // Has nothing to do with the current value. It is the last text, which was valid at input (checked by CheckText,
105  // not yet through formatter)
106  Selection m_aLastSelection;
107 
108  double m_dMinValue;
109  double m_dMaxValue;
110  bool m_bHasMin : 1;
111  bool m_bHasMax : 1;
112 
113  bool m_bWrapOnLimits : 1;
114  bool m_bStrictFormat : 1;
115 
116  bool m_bEnableEmptyField : 1;
117  bool m_bAutoColor : 1;
118  bool m_bEnableNaN : 1;
119  bool m_bDisableRemainderFactor : 1;
120  enum valueState { valueDirty, valueString, valueDouble };
124 
128 
129  double m_dSpinSize;
130  double m_dSpinFirst;
131  double m_dSpinLast;
132 
133  // There is a difference, when text formatting is enabled, if LostFocus formats the current String and displays it,
134  // or if a double is created from the String and then
136  // And with the following members we can use it for formatted text output as well ...
138  OUString m_sDefaultText;
139 
140  // The last color from the Formatter at the last output operation (not we would use it, but you can get it)
142 
144 
147 
148 public:
149  Formatter();
150  virtual ~Formatter();
151 
152  void SetFieldText(const OUString& rText, const Selection& rNewSelection);
153 
154  virtual Selection GetEntrySelection() const = 0;
155  virtual OUString GetEntryText() const = 0;
156  virtual SelectionOptions GetEntrySelectionOptions() const = 0;
157  virtual void SetEntryText(const OUString& rText, const Selection& rSel) = 0;
158  virtual void SetEntryTextColor(const Color* pColor) = 0;
159  virtual void FieldModified() = 0;
160 
161  // Min-/Max-management
162  bool HasMinValue() const { return m_bHasMin; }
163  virtual void ClearMinValue() { m_bHasMin = false; }
164  virtual void SetMinValue(double dMin);
165  double GetMinValue() const { return m_dMinValue; }
166 
167  bool HasMaxValue() const { return m_bHasMax; }
168  virtual void ClearMaxValue() { m_bHasMax = false; }
169  virtual void SetMaxValue(double dMax);
170  double GetMaxValue() const { return m_dMaxValue; }
171 
172  // Current value
173  void SetValue(double dVal);
174  double GetValue();
175  // The default implementation uses a formatter, if available
176 
177  void SetTextValue(const OUString& rText);
178  // The String is transformed to a double (with a formatter) and SetValue is called afterwards
179 
180  bool IsEmptyFieldEnabled() const { return m_bEnableEmptyField; }
181  void EnableEmptyField(bool bEnable);
182  // If disabled, the value will be reset to the last valid value on leave
183 
184  void SetDefaultValue(double dDefault) { m_dDefaultValue = dDefault; m_ValueState = valueDirty; }
185  // If the current String is invalid, GetValue() returns this value
186  double GetDefaultValue() const { return m_dDefaultValue; }
187 
188  void SetLastSelection(const Selection& rSelection) { m_aLastSelection = rSelection; }
189 
190  // Settings for the format
191  sal_uLong GetFormatKey() const { return m_nFormatKey; }
192  void SetFormatKey(sal_uLong nFormatKey);
193 
194  SvNumberFormatter* GetOrCreateFormatter() const { return m_pFormatter ? m_pFormatter : const_cast<Formatter*>(this)->CreateFormatter(); }
195 
196  SvNumberFormatter* GetFormatter() const { return m_pFormatter; }
197  void SetFormatter(SvNumberFormatter* pFormatter, bool bResetFormat = true);
198  // If bResetFormat is sal_False, the old format is tried to be kept. (expensive, if it is no default format, available in all formatters)
199  // If sal_True, the new FormatKey is set to zero
200 
201  bool GetThousandsSep() const;
202  void SetThousandsSep(bool _bUseSeparator);
203  // the is no check if the current format is numeric, so be cautious when calling these functions
204 
205  void DisableRemainderFactor();
206  bool GetDisableRemainderFactor() const { return m_bDisableRemainderFactor; }
207 
208  void SetWrapOnLimits(bool bWrapOnLimits) { m_bWrapOnLimits = bWrapOnLimits; }
209 
210  sal_uInt16 GetDecimalDigits() const;
211  void SetDecimalDigits(sal_uInt16 _nPrecision);
212  // There is no check if the current format is numeric, so be cautious when calling these functions
213 
214  SvNumberFormatter* StandardFormatter() { return m_aStaticFormatter; }
215  // If no new Formatter is created explicitly, this can be used in SetFormatter...
216 
217  OUString GetFormat(LanguageType& eLang) const;
218  bool SetFormat(const OUString& rFormatString, LanguageType eLang);
219  // sal_False, if the FormatString could not be set (and very probably is invalid)
220  // This Object is shared via all instances, so be careful!
221 
222  bool IsStrictFormat() const { return m_bStrictFormat; }
223  void SetStrictFormat(bool bEnable) { m_bStrictFormat = bEnable; }
224  // Check format during input
225 
226  virtual void SetSpinSize(double dStep) { m_dSpinSize = dStep; }
227  double GetSpinSize() const { return m_dSpinSize; }
228 
229  void SetSpinFirst(double dFirst) { m_dSpinFirst = dFirst; }
230  double GetSpinFirst() const { return m_dSpinFirst; }
231 
232  void SetSpinLast(double dLast) { m_dSpinLast = dLast; }
233  double GetSpinLast() const { return m_dSpinLast; }
234 
235  bool TreatingAsNumber() const { return m_bTreatAsNumber; }
236  void TreatAsNumber(bool bDoSo) { m_bTreatAsNumber = bDoSo; }
237 
238  void SetInputHdl(const Link<sal_Int64*,TriState>& rLink) { m_aInputHdl = rLink; }
239  void SetOutputHdl(const Link<LinkParamNone*, bool>& rLink) { m_aOutputHdl = rLink; }
240 public:
241 
242  //The following methods are interesting, if m_bTreatAsNumber is set to sal_False
243  //If someone does not care about all the double handling and just wants to print the text formatted.
244  //(((The text will be formatted, using the Formatter, and then set)
245  void SetTextFormatted(const OUString& rText);
246  OUString const & GetTextValue() const;
247 
248  void SetDefaultText(const OUString& rDefault) { m_sDefaultText = rDefault; }
249  const OUString& GetDefaultText() const { return m_sDefaultText; }
250 
251  // The last colour from the Formatter's last output operation. Output operations get triggered by:
252  // SetValue, SetTextValue, SetTextFormatted, also indirectly via SetMin - / -MaxValue
253  const Color* GetLastOutputColor() const { return m_pLastOutputColor; }
254 
259  void Commit();
260 
261  // enable automatic coloring. if set to sal_True, and the format the field is working with for any current value
262  // says that it has to be painted in a special color (e.g. a format where negative numbers should be printed
263  // red), the text is painted with that color automatically.
264  // The color used is the same as returned by GetLastOutputColor()
265  void SetAutoColor(bool _bAutomatic);
266 
281  void EnableNotANumber( bool _bEnable );
282 
287  void UseInputStringForFormatting();
288  bool IsUsingInputStringForFormatting() const { return m_bUseInputStringForFormatting;}
289 
290  void Modify(bool makeValueDirty = true);
291 
292  void EntryLostFocus();
293 
294  void ReFormat();
295 
296  // any aspect of the current format has changed
297  virtual void FormatChanged(FORMAT_CHANGE_TYPE nWhat);
298 
299 protected:
300 
301  // Override CheckText for input-time checks
302  virtual bool CheckText(const OUString&) const { return true; }
303 
304  void ImplSetTextImpl(const OUString& rNew, Selection const * pNewSel);
305  void ImplSetValue(double dValue, bool bForce);
306  bool ImplGetValue(double& dNewVal);
307 
308  void ImplSetFormatKey(sal_uLong nFormatKey);
309  // SetFormatKey without FormatChanged notification
310 
311  SvNumberFormatter* CreateFormatter() { SetFormatter(StandardFormatter()); return m_pFormatter; }
312 
313  virtual void UpdateCurrentValue(double dCurrentValue) { m_dCurrentValue = dCurrentValue; }
314 };
315 
316 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool HasMaxValue() const
Definition: formatter.hxx:167
void SetSpinLast(double dLast)
Definition: formatter.hxx:232
static SvNumberFormatter * s_cFormatter
Definition: formatter.hxx:92
void SetInputHdl(const Link< sal_Int64 *, TriState > &rLink)
Definition: formatter.hxx:238
double m_dSpinSize
Definition: formatter.hxx:129
std::string GetValue
SelectionOptions
Definition: settings.hxx:178
#define VCL_DLLPUBLIC
Definition: dllapi.h:29
virtual void ClearMaxValue()
Definition: formatter.hxx:168
bool TreatingAsNumber() const
Definition: formatter.hxx:235
double m_dDefaultValue
Definition: formatter.hxx:123
sal_uIntPtr sal_uLong
SvNumberFormatter * StandardFormatter()
Definition: formatter.hxx:214
FORMAT_CHANGE_TYPE
Definition: formatter.hxx:76
::std::map< sal_Unicode, State > StateTransitions
Definition: formatter.hxx:52
double m_dSpinFirst
Definition: formatter.hxx:130
void SetDefaultValue(double dDefault)
Definition: formatter.hxx:184
bool IsUsingInputStringForFormatting() const
Definition: formatter.hxx:288
bool m_bUseInputStringForFormatting
Definition: formatter.hxx:143
TransitionTable m_aTransitions
Definition: formatter.hxx:64
void SetSpinFirst(double dFirst)
Definition: formatter.hxx:229
const Color * GetLastOutputColor() const
Definition: formatter.hxx:253
OUString m_sCurrentTextValue
Definition: formatter.hxx:137
bool IsEmptyFieldEnabled() const
Definition: formatter.hxx:180
sal_uInt16 sal_Unicode
StateTransitions::value_type Transition
Definition: formatter.hxx:55
virtual void UpdateCurrentValue(double dCurrentValue)
Definition: formatter.hxx:313
SvNumberFormatter * CreateFormatter()
Definition: formatter.hxx:311
void TreatAsNumber(bool bDoSo)
Definition: formatter.hxx:236
double GetSpinSize() const
Definition: formatter.hxx:227
void SetOutputHdl(const Link< LinkParamNone *, bool > &rLink)
Definition: formatter.hxx:239
StaticFormatter m_aStaticFormatter
Definition: formatter.hxx:127
const Color * m_pLastOutputColor
Definition: formatter.hxx:141
double GetMaxValue() const
Definition: formatter.hxx:170
virtual void ClearMinValue()
Definition: formatter.hxx:163
sal_uLong GetFormatKey() const
Definition: formatter.hxx:191
bool m_bTreatAsNumber
Definition: formatter.hxx:135
SvNumberFormatter * m_pFormatter
Definition: formatter.hxx:126
bool implValidateNormalized(const OUString &_rText)
Definition: fmtfield.cxx:175
double GetDefaultValue() const
Definition: formatter.hxx:186
SvNumberFormatter * GetFormatter() const
Definition: formatter.hxx:196
valueState m_ValueState
Definition: formatter.hxx:121
double GetSpinLast() const
Definition: formatter.hxx:233
void SetDefaultText(const OUString &rDefault)
Definition: formatter.hxx:248
bool GetDisableRemainderFactor() const
Definition: formatter.hxx:206
void SetStrictFormat(bool bEnable)
Definition: formatter.hxx:223
double m_dSpinLast
Definition: formatter.hxx:131
NumberValidator(const sal_Unicode _cThSep, const sal_Unicode _cDecSep)
Definition: fmtfield.cxx:87
double m_dCurrentValue
Definition: formatter.hxx:122
bool HasMinValue() const
Definition: formatter.hxx:162
void SetWrapOnLimits(bool bWrapOnLimits)
Definition: formatter.hxx:208
Link< sal_Int64 *, TriState > m_aInputHdl
Definition: formatter.hxx:145
virtual bool CheckText(const OUString &) const
Definition: formatter.hxx:302
void SetLastSelection(const Selection &rSelection)
Definition: formatter.hxx:188
class UNLESS_MERGELIBS(VCL_DLLPUBLIC) EventPoster
a client for the accessibility implementations which have been outsourced from the main vcl/svtools l...
Definition: evntpost.hxx:30
static sal_uLong s_nReferences
Definition: formatter.hxx:93
SvNumberFormatter * GetOrCreateFormatter() const
Definition: formatter.hxx:194
OUString m_sDefaultText
Definition: formatter.hxx:138
double GetMinValue() const
Definition: formatter.hxx:165
double GetSpinFirst() const
Definition: formatter.hxx:230
bool IsStrictFormat() const
Definition: formatter.hxx:222
bool isValidNumericFragment(std::u16string_view _rText)
Definition: fmtfield.cxx:214
const OUString & GetDefaultText() const
Definition: formatter.hxx:249
sal_uLong m_nFormatKey
Definition: formatter.hxx:125
::std::map< State, StateTransitions > TransitionTable
Definition: formatter.hxx:58
virtual void SetSpinSize(double dStep)
Definition: formatter.hxx:226
void SetFormat(LotusContext &rContext, SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt8 nFormat, sal_uInt8 nSt)
Link< LinkParamNone *, bool > m_aOutputHdl
Definition: formatter.hxx:146