1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef _FMTFIELD_HXX_
21 #define _FMTFIELD_HXX_
23 #include "svtools/svtdllapi.h"
24 #include <vcl/spinfld.hxx>
25 #include <svl/zforlist.hxx>
27 namespace validation
{ class NumberValidator
; }
29 typedef sal_uInt16 FORMAT_CHANGE_TYPE
;
30 #define FCT_KEYONLY 0x00 // only a new key was set
31 #define FCT_FORMATTER 0x01 // a new formatter weas set, usually implies a change of the key, too
32 #define FCT_PRECISION 0x02 // a new precision was set
33 #define FCT_THOUSANDSSEP 0x03 // the thousands separator setting changed
35 //------------------------------------------------------------------------------
36 class SVT_DLLPUBLIC FormattedField
: public SpinField
39 // Da ein SvNumberFormatter eine ziemlich teure (sowohl zeit- als auch platz-maessig) Angelegenheit ist,
40 // haelt sich nicht jedes Field, an dem kein Formatter gesetzt wurde, eine eigenen Instanz, sondern es gibt nur eine
44 static SvNumberFormatter
* s_cFormatter
;
45 static sal_uLong s_nReferences
;
50 operator SvNumberFormatter
* () { return GetFormatter(); }
51 SVT_DLLPUBLIC SvNumberFormatter
* GetFormatter();
55 String m_sLastValidText
;
56 // hat nichts mit dem current value zu tun, ist der letzte Text, der waehrend einer Eingabe als gueltig erkannt
57 // wurde (also durch CheckText geprueft, nicht durch den Formatter gejagt)
58 Selection m_aLastSelection
;
62 sal_Bool m_bHasMin
: 1;
63 sal_Bool m_bHasMax
: 1;
65 sal_Bool m_bStrictFormat
: 1;
67 sal_Bool m_bValueDirty
: 1;
68 sal_Bool m_bEnableEmptyField
: 1;
69 sal_Bool m_bAutoColor
: 1;
70 sal_Bool m_bEnableNaN
: 1;
71 double m_dCurrentValue
;
72 double m_dDefaultValue
;
74 sal_uLong m_nFormatKey
;
75 SvNumberFormatter
* m_pFormatter
;
76 StaticFormatter m_aStaticFormatter
;
82 // es macht einen Unterschied, ob man bei eingestellter Textformatierung beim LostFocus den aktuellen String durch
83 // den Formatter jagt und das Ergebnis anzeigt oder erst aus dem String ein double macht, das formatiert und dann
85 sal_Bool m_bTreatAsNumber
;
86 // und mit den folgenden Members koennen wir das Ganze hier auch zur formatierten Text-Ausgabe benutzen ...
87 String m_sCurrentTextValue
;
88 String m_sDefaultText
;
90 // die bei der letzten Ausgabe-Operation vom Formatter gelieferte Farbe (nicht dass wir sie beachten wuerden, aber
91 // man kann sie von aussen abfragen)
92 Color
* m_pLastOutputColor
;
94 bool m_bUseInputStringForFormatting
;
97 FormattedField(Window
* pParent
, WinBits nStyle
= 0, SvNumberFormatter
* pInitialFormatter
= NULL
, sal_Int32 nFormatKey
= 0);
98 FormattedField(Window
* pParent
, const ResId
& rResId
, SvNumberFormatter
* pInitialFormatter
= NULL
, sal_Int32 nFormatKey
= 0);
99 virtual ~FormattedField();
101 // Min-/Max-Verwaltung
102 sal_Bool
HasMinValue() const { return m_bHasMin
; }
103 void ClearMinValue() { m_bHasMin
= sal_False
; }
104 void SetMinValue(double dMin
);
105 double GetMinValue() const { return m_dMinValue
; }
107 sal_Bool
HasMaxValue() const { return m_bHasMax
; }
108 void ClearMaxValue() { m_bHasMax
= sal_False
; }
109 void SetMaxValue(double dMax
);
110 double GetMaxValue() const { return m_dMaxValue
; }
113 virtual void SetValue(double dVal
);
114 virtual double GetValue();
115 // die Standard-Implementierung jagt die Eingabe jeweils durch den Formatter, so einer vorhanden ist
117 void GetColor() const;
119 void SetTextValue(const OUString
& rText
);
120 // der String wird in ein double umgewandelt (durch den Formatter) und anschliessen in SetValue gesteckt
122 sal_Bool
IsEmptyFieldEnabled() const { return m_bEnableEmptyField
; }
123 void EnableEmptyField(sal_Bool bEnable
);
124 // wenn nicht enabled, wird beim Verlassen des Feldes der Text auf den letzten gueltigen zurueckgesetzt
126 void SetDefaultValue(double dDefault
) { m_dDefaultValue
= dDefault
; m_bValueDirty
= sal_True
; }
127 // wenn der aktuelle String ungueltig ist, liefert GetValue() diesen Default-Wert
128 double GetDefaultValue() const { return m_dDefaultValue
; }
130 // Einstellungen fuer das Format
131 sal_uLong
GetFormatKey() const { return m_nFormatKey
; }
132 void SetFormatKey(sal_uLong nFormatKey
);
134 SvNumberFormatter
* GetFormatter() const { return m_pFormatter
; }
135 void SetFormatter(SvNumberFormatter
* pFormatter
, sal_Bool bResetFormat
= sal_True
);
136 // wenn bResetFormat sal_False ist, wird versucht, das alte eingestellte Format mit 'hinueberzuretten' (teuer, wenn es sich nicht
137 // um eines der Standard-Formate handelt, die in allen Formattern gleich sind)
138 // wenn sal_True, wird als neuer FormatKey 0 gesetzt
140 sal_Bool
GetThousandsSep() const;
141 void SetThousandsSep(sal_Bool _bUseSeparator
);
142 // the is no check if the current format is numeric, so be cautious when calling these functions
144 sal_uInt16
GetDecimalDigits() const;
145 void SetDecimalDigits(sal_uInt16 _nPrecision
);
146 // the is no check if the current format is numeric, so be cautious when calling these functions
148 SvNumberFormatter
* StandardFormatter() { return m_aStaticFormatter
; }
149 // Wenn man keinen eigenen Formatter explizit anlegen will, kann man diesen hier in SetFormatter stecken ...
150 // Das hier gelieferte Objekt wird allerdings zwischen allen Instanzen der Klasse geteilt (aus Zeit- und Platzgruenden),
151 // also ist etwas Vorsicht angebracht ...
153 OUString
GetFormat(LanguageType
& eLang
) const;
154 sal_Bool
SetFormat(const OUString
& rFormatString
, LanguageType eLang
);
155 // sal_False, wenn der FormatString nicht gesetzt werden konnte (also wahrscheinlich ungueltig ist)
157 sal_Bool
IsStrictFormat() const { return m_bStrictFormat
; }
158 void SetStrictFormat(sal_Bool bEnable
) { m_bStrictFormat
= bEnable
; }
159 // Formatueberpruefung waehrend der Eingabe ?
164 // Standard-Implementierung : hoch- oder runterzaehlen des aktuellen double einfach um die gesetzte SpinSize
165 virtual void First();
167 // Standard-Implementierung : aktuelles double setzen auf eingestellten first respektive last value
169 void SetSpinSize(double dStep
) { m_dSpinSize
= dStep
; }
170 double GetSpinSize() const { return m_dSpinSize
; }
172 void SetSpinFirst(double dFirst
) { m_dSpinFirst
= dFirst
; }
173 double GetSpinFirst() const { return m_dSpinFirst
; }
175 void SetSpinLast(double dLast
) { m_dSpinLast
= dLast
; }
176 double GetSpinLast() const { return m_dSpinLast
; }
178 sal_Bool
TreatingAsNumber() const { return m_bTreatAsNumber
; }
179 void TreatAsNumber(sal_Bool bDoSo
) { m_bTreatAsNumber
= bDoSo
; }
182 virtual void SetText( const OUString
& rStr
);
183 virtual void SetText( const OUString
& rStr
, const Selection
& rNewSelection
);
185 // die folgenden Methoden sind interesant, wenn m_bTreatAsNumber auf sal_False sitzt
186 /** nehmen wir mal an, irgendjemand will das ganze schoene double-Handling gar nicht haben, sondern
187 einfach den Text formatiert ausgeben ...
188 (der Text wird einfach nur durch den Formatter gejagt und dann gesetzt)
190 void SetTextFormatted(const OUString
& rText
);
191 String
GetTextValue() const;
193 void SetDefaultText(const OUString
& rDefault
) { m_sDefaultText
= rDefault
; }
194 String
GetDefaultText() const { return m_sDefaultText
; }
196 // die bei der letzten Ausgabe-Operation vom Formatter gelieferte Farbe (Ausgabe-Operationen werden getriggert durch
197 // SetValue, SetTextValue, SetTextFormatted, also indirekt eventuell auch durch SetMin-/-MaxValue)
198 Color
* GetLastOutputColor() const { return m_pLastOutputColor
; }
200 /** reformats the current text. Interesting if the user entered some text in an "input format", and
201 this should be formatted in the "output format" (which may differ, e.g. by additional numeric
206 // enable automatic coloring. if set to sal_True, and the format the field is working with for any current value
207 // says that it has to be painted in a special color (e.g. a format where negative numbers should be printed
208 // red), the text is painted with that color automatically.
209 // The color used is the same as returned by GetLastOutputColor()
210 void SetAutoColor(sal_Bool _bAutomatic
);
211 sal_Bool
GetAutoColor() const { return m_bAutoColor
; }
213 /** enables handling of not-a-number value.
215 When this is set to <FALSE/> (the default), then invalid inputs (i.e. text which cannot be
216 intepreted, according to the current formatting) will be handled as if the default value
217 has been entered. GetValue the will return this default value.
219 When set to <TRUE/>, then GetValue will return NaN (not a number, see <method scope="rtl::math">isNan</method>)
220 when the current input is invalid.
222 Note that setting this to <TRUE/> implies that upon leaving the control, the input
223 will *not* be corrected to a valid value. For example, if the user enters "foo" in the
224 control, and then tabs out of it, the text "foo" will persist, and GetValue will
225 return NaN in subsequent calls.
227 void EnableNotANumber( sal_Bool _bEnable
);
228 sal_Bool
IsNotANumberEnabled( ) const { return m_bEnableNaN
; }
230 /** When being set to true, the strings in the field are formatted using the
231 InputLine format. That's also what you get in Calc when you edit a cell
234 void UseInputStringForFormatting( bool bUseInputStr
= true );
235 bool IsUsingInputStringForFormatting() const;
238 virtual long Notify(NotifyEvent
& rNEvt
);
239 void impl_Modify(bool makeValueDirty
= true);
240 virtual void Modify();
242 // CheckText ueberschreiben fuer Ueberpruefung zur Eingabezeit
243 virtual sal_Bool
CheckText(const OUString
&) const { return sal_True
; }
245 // any aspect of the current format has changed
246 virtual void FormatChanged(FORMAT_CHANGE_TYPE nWhat
);
248 void ImplSetTextImpl(const OUString
& rNew
, Selection
* pNewSel
);
249 void ImplSetValue(double dValue
, sal_Bool bForce
);
250 sal_Bool
ImplGetValue(double& dNewVal
);
252 void ImplSetFormatKey(sal_uLong nFormatKey
);
253 // SetFormatKey without FormatChanged notification
255 virtual SvNumberFormatter
* CreateFormatter() { SetFormatter(StandardFormatter()); return m_pFormatter
; }
256 SvNumberFormatter
* ImplGetFormatter() const { return m_pFormatter
? m_pFormatter
: ((FormattedField
*)this)->CreateFormatter(); }
258 long PreNotify(NotifyEvent
& rNEvt
);
260 virtual void ReFormat();
263 //------------------------------------------------------------------------------
264 class SVT_DLLPUBLIC DoubleNumericField
: public FormattedField
267 validation::NumberValidator
* m_pNumberValidator
;
270 DoubleNumericField(Window
* pParent
, WinBits nStyle
= 0)
271 :FormattedField(pParent
, nStyle
)
272 ,m_pNumberValidator( NULL
)
274 ResetConformanceTester();
277 DoubleNumericField(Window
* pParent
, const ResId
& rResId
)
278 :FormattedField(pParent
, rResId
)
279 ,m_pNumberValidator( NULL
)
281 ResetConformanceTester();
283 virtual ~DoubleNumericField();
286 virtual sal_Bool
CheckText(const OUString
& sText
) const;
288 virtual void FormatChanged(FORMAT_CHANGE_TYPE nWhat
);
289 void ResetConformanceTester();
292 //==============================================================================
293 #define FCT_CURRENCY_SYMBOL 0x10
294 #define FCT_CURRSYM_POSITION 0x20
296 //------------------------------------------------------------------------------
297 class DoubleCurrencyField
: public FormattedField
299 OUString m_sCurrencySymbol
;
300 sal_Bool m_bPrependCurrSym
;
301 sal_Bool m_bChangingFormat
;
304 DoubleCurrencyField(Window
* pParent
, WinBits nStyle
= 0);
306 OUString
getCurrencySymbol() const { return m_sCurrencySymbol
; }
307 void setCurrencySymbol(const OUString
& rSymbol
);
309 sal_Bool
getPrependCurrSym() const { return m_bPrependCurrSym
; }
310 void setPrependCurrSym(sal_Bool _bPrepend
);
313 virtual void FormatChanged(FORMAT_CHANGE_TYPE nWhat
);
315 void UpdateCurrencyFormat();
318 #endif // _FMTFIELD_HXX_
320 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */