| /************************************************************** |
| * |
| * 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 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #ifndef _FMTFIELD_HXX_ |
| #define _FMTFIELD_HXX_ |
| |
| #include "svtools/svtdllapi.h" |
| #include <vcl/spinfld.hxx> |
| #include <svl/zforlist.hxx> |
| |
| //#define REGEXP_SUPPORT |
| |
| #ifdef REGEXP_SUPPORT |
| #ifndef _UNOTOOLS_TEXTSEARCH_HXX |
| #include <unotools/textsearch.hxx> |
| #endif |
| #else |
| // use a hand-made regular expression parsing for the small expression we're interested in |
| // as soon as OOo does have regular expression support, we can switch on the REGEXP_SUPPORT define |
| namespace validation { class NumberValidator; } |
| #endif |
| |
| typedef sal_uInt16 FORMAT_CHANGE_TYPE; |
| #define FCT_KEYONLY 0x00 // only a new key was set |
| #define FCT_FORMATTER 0x01 // a new formatter was set, usually implies a change of the key, too |
| #define FCT_PRECISION 0x02 // a new precision was set |
| #define FCT_THOUSANDSSEP 0x03 // the thousands separator setting changed |
| |
| //------------------------------------------------------------------------------ |
| class SVT_DLLPUBLIC FormattedField : public SpinField |
| { |
| private: |
| // Da ein SvNumberFormatter eine ziemlich teure (sowohl zeit- als auch platz-maessig) Angelegenheit ist, |
| // haelt sich nicht jedes Field, an dem kein Formatter gesetzt wurde, eine eigenen Instanz, sondern es gibt nur eine |
| // einzige statische. |
| class StaticFormatter |
| { |
| static SvNumberFormatter* s_cFormatter; |
| static sal_uLong s_nReferences; |
| public: |
| StaticFormatter(); |
| ~StaticFormatter(); |
| |
| operator SvNumberFormatter* () { return GetFormatter(); } |
| SVT_DLLPUBLIC SvNumberFormatter* GetFormatter(); |
| }; |
| |
| protected: |
| String m_sLastValidText; |
| // hat nichts mit dem current value zu tun, ist der letzte Text, der waehrend einer Eingabe als gueltig erkannt |
| // wurde (also durch CheckText geprueft, nicht durch den Formatter gejagt) |
| Selection m_aLastSelection; |
| |
| double m_dMinValue; |
| double m_dMaxValue; |
| sal_Bool m_bHasMin : 1; |
| sal_Bool m_bHasMax : 1; |
| |
| sal_Bool m_bStrictFormat : 1; |
| |
| sal_Bool m_bValueDirty : 1; |
| sal_Bool m_bEnableEmptyField : 1; |
| sal_Bool m_bAutoColor : 1; |
| sal_Bool m_bEnableNaN : 1; |
| 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; |
| |
| // es macht einen Unterschied, ob man bei eingestellter Textformatierung beim LostFocus den aktuellen String durch |
| // den Formatter jagt und das Ergebnis anzeigt oder erst aus dem String ein double macht, das formatiert und dann |
| // ausgibt |
| sal_Bool m_bTreatAsNumber; |
| // und mit den folgenden Members koennen wir das Ganze hier auch zur formatierten Text-Ausgabe benutzen ... |
| String m_sCurrentTextValue; |
| String m_sDefaultText; |
| |
| // die bei der letzten Ausgabe-Operation vom Formatter gelieferte Farbe (nicht dass wir sie beachten wuerden, aber |
| // man kann sie von aussen abfragen) |
| Color* m_pLastOutputColor; |
| |
| bool m_bUseInputStringForFormatting; |
| |
| public: |
| FormattedField(Window* pParent, WinBits nStyle = 0, SvNumberFormatter* pInitialFormatter = NULL, sal_Int32 nFormatKey = 0); |
| FormattedField(Window* pParent, const ResId& rResId, SvNumberFormatter* pInitialFormatter = NULL, sal_Int32 nFormatKey = 0); |
| virtual ~FormattedField(); |
| |
| // Min-/Max-Verwaltung |
| sal_Bool HasMinValue() const { return m_bHasMin; } |
| void ClearMinValue() { m_bHasMin = sal_False; } |
| void SetMinValue(double dMin); |
| double GetMinValue() const { return m_dMinValue; } |
| |
| sal_Bool HasMaxValue() const { return m_bHasMax; } |
| void ClearMaxValue() { m_bHasMax = sal_False; } |
| void SetMaxValue(double dMax); |
| double GetMaxValue() const { return m_dMaxValue; } |
| |
| // aktueller Wert |
| virtual void SetValue(double dVal); |
| virtual double GetValue(); |
| // die Standard-Implementierung jagt die Eingabe jeweils durch den Formatter, so einer vorhanden ist |
| |
| void GetColor() const; |
| |
| void SetTextValue(const XubString& rText); |
| // der String wird in ein double umgewandelt (durch den Formatter) und anschliessen in SetValue gesteckt |
| |
| sal_Bool IsEmptyFieldEnabled() const { return m_bEnableEmptyField; } |
| void EnableEmptyField(sal_Bool bEnable); |
| // wenn nicht enabled, wird beim Verlassen des Feldes der Text auf den letzten gueltigen zurueckgesetzt |
| |
| void SetDefaultValue(double dDefault) { m_dDefaultValue = dDefault; m_bValueDirty = sal_True; } |
| // wenn der aktuelle String ungueltig ist, liefert GetValue() diesen Default-Wert |
| double GetDefaultValue() const { return m_dDefaultValue; } |
| |
| // Einstellungen fuer das Format |
| sal_uLong GetFormatKey() const { return m_nFormatKey; } |
| void SetFormatKey(sal_uLong nFormatKey); |
| |
| SvNumberFormatter* GetFormatter() const { return m_pFormatter; } |
| void SetFormatter(SvNumberFormatter* pFormatter, sal_Bool bResetFormat = sal_True); |
| // wenn bResetFormat sal_False ist, wird versucht, das alte eingestellte Format mit 'hinueberzuretten' (teuer, wenn es sich nicht |
| // um eines der Standard-Formate handelt, die in allen Formattern gleich sind) |
| // wenn sal_True, wird als neuer FormatKey 0 gesetzt |
| |
| sal_Bool GetThousandsSep() const; |
| void SetThousandsSep(sal_Bool _bUseSeparator); |
| // the is no check if the current format is numeric, so be cautious when calling these functions |
| |
| sal_uInt16 GetDecimalDigits() const; |
| void SetDecimalDigits(sal_uInt16 _nPrecision); |
| // the is no check if the current format is numeric, so be cautious when calling these functions |
| |
| SvNumberFormatter* StandardFormatter() { return m_aStaticFormatter; } |
| // Wenn man keinen eigenen Formatter explizit anlegen will, kann man diesen hier in SetFormatter stecken ... |
| // Das hier gelieferte Objekt wird allerdings zwischen allen Instanzen der Klasse geteilt (aus Zeit- und Platzgruenden), |
| // also ist etwas Vorsicht angebracht ... |
| |
| void GetFormat(XubString& rFormatString, LanguageType& eLang) const; |
| sal_Bool SetFormat(const XubString& rFormatString, LanguageType eLang); |
| // sal_False, wenn der FormatString nicht gesetzt werden konnte (also wahrscheinlich ungueltig ist) |
| |
| sal_Bool IsStrictFormat() const { return m_bStrictFormat; } |
| void SetStrictFormat(sal_Bool bEnable) { m_bStrictFormat = bEnable; } |
| // Formatueberpruefung waehrend der Eingabe ? |
| |
| // Spin-Handling |
| virtual void Up(); |
| virtual void Down(); |
| // Standard-Implementierung : hoch- oder runterzaehlen des aktuellen double einfach um die gesetzte SpinSize |
| virtual void First(); |
| virtual void Last(); |
| // Standard-Implementierung : aktuelles double setzen auf eingestellten first respektive last value |
| |
| 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; } |
| |
| sal_Bool TreatingAsNumber() const { return m_bTreatAsNumber; } |
| void TreatAsNumber(sal_Bool bDoSo) { m_bTreatAsNumber = bDoSo; } |
| |
| public: |
| virtual void SetText( const XubString& rStr ); |
| virtual void SetText( const XubString& rStr, const Selection& rNewSelection ); |
| void SetValidateText(const XubString& rText, const String* pErrorText = NULL); |
| |
| // die folgenden Methoden sind interesant, wenn m_bTreatAsNumber auf sal_False sitzt |
| /** nehmen wir mal an, irgendjemand will das ganze schoene double-Handling gar nicht haben, sondern |
| einfach den Text formatiert ausgeben ... |
| (der Text wird einfach nur durch den Formatter gejagt und dann gesetzt) |
| */ |
| void SetTextFormatted(const XubString& rText); |
| String GetTextValue() const; |
| |
| void SetDefaultText(const XubString& rDefault) { m_sDefaultText = rDefault; } |
| String GetDefaultText() const { return m_sDefaultText; } |
| |
| // die bei der letzten Ausgabe-Operation vom Formatter gelieferte Farbe (Ausgabe-Operationen werden getriggert durch |
| // SetValue, SetTextValue, SetTextFormatted, also indirekt eventuell auch durch 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(sal_Bool _bAutomatic); |
| sal_Bool GetAutoColor() const { return m_bAutoColor; } |
| |
| /** enables handling of not-a-number value. |
| |
| When this is set to <FALSE/> (the default), then invalid inputs (i.e. text which cannot be |
| intepreted, 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( sal_Bool _bEnable ); |
| sal_Bool IsNotANumberEnabled( ) const { return m_bEnableNaN; } |
| |
| /** 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 bUseInputStr = true ); |
| bool IsUsingInputStringForFormatting() const; |
| |
| protected: |
| virtual long Notify(NotifyEvent& rNEvt); |
| virtual void Modify(); |
| |
| // CheckText ueberschreiben fuer Ueberpruefung zur Eingabezeit |
| virtual sal_Bool CheckText(const XubString&) const { return sal_True; } |
| |
| // any aspect of the current format has changed |
| virtual void FormatChanged(FORMAT_CHANGE_TYPE nWhat); |
| |
| void ImplSetTextImpl(const XubString& rNew, Selection* pNewSel); |
| void ImplSetValue(double dValue, sal_Bool bForce); |
| sal_Bool ImplGetValue(double& dNewVal); |
| |
| void ImplSetFormatKey(sal_uLong nFormatKey); |
| // SetFormatKey without FormatChanged notification |
| |
| virtual SvNumberFormatter* CreateFormatter() { SetFormatter(StandardFormatter()); return m_pFormatter; } |
| SvNumberFormatter* ImplGetFormatter() const { return m_pFormatter ? m_pFormatter : ((FormattedField*)this)->CreateFormatter(); } |
| |
| long PreNotify(NotifyEvent& rNEvt); |
| |
| virtual void ReFormat(); |
| }; |
| |
| //------------------------------------------------------------------------------ |
| class SVT_DLLPUBLIC DoubleNumericField : public FormattedField |
| { |
| protected: |
| #ifdef REGEXP_SUPPORT |
| ::utl::TextSearch* m_pConformanceTester; |
| #else |
| validation::NumberValidator* m_pNumberValidator; |
| #endif |
| |
| public: |
| DoubleNumericField(Window* pParent, WinBits nStyle = 0) |
| :FormattedField(pParent, nStyle) |
| #ifdef REGEXP_SUPPORT |
| ,m_pConformanceTester( NULL ) |
| #else |
| ,m_pNumberValidator( NULL ) |
| #endif |
| { |
| ResetConformanceTester(); |
| } |
| |
| DoubleNumericField(Window* pParent, const ResId& rResId) |
| :FormattedField(pParent, rResId) |
| #ifdef REGEXP_SUPPORT |
| ,m_pConformanceTester( NULL ) |
| #else |
| ,m_pNumberValidator( NULL ) |
| #endif |
| { |
| ResetConformanceTester(); |
| } |
| virtual ~DoubleNumericField(); |
| |
| protected: |
| virtual sal_Bool CheckText(const XubString& sText) const; |
| |
| virtual void FormatChanged(FORMAT_CHANGE_TYPE nWhat); |
| void ResetConformanceTester(); |
| }; |
| |
| //============================================================================== |
| #define FCT_CURRENCY_SYMBOL 0x10 |
| #define FCT_CURRSYM_POSITION 0x20 |
| |
| //------------------------------------------------------------------------------ |
| class DoubleCurrencyField : public FormattedField |
| { |
| XubString m_sCurrencySymbol; |
| sal_Bool m_bPrependCurrSym; |
| sal_Bool m_bChangingFormat; |
| |
| public: |
| DoubleCurrencyField(Window* pParent, WinBits nStyle = 0); |
| DoubleCurrencyField(Window* pParent, const ResId& rResId); |
| |
| XubString getCurrencySymbol() const { return m_sCurrencySymbol; } |
| void setCurrencySymbol(const XubString& _sSymbol); |
| |
| sal_Bool getPrependCurrSym() const { return m_bPrependCurrSym; } |
| void setPrependCurrSym(sal_Bool _bPrepend); |
| |
| protected: |
| virtual void FormatChanged(FORMAT_CHANGE_TYPE nWhat); |
| |
| void UpdateCurrencyFormat(); |
| }; |
| |
| #endif // _FMTFIELD_HXX_ |
| |