xref: /trunk/main/svl/inc/svl/zformat.hxx (revision 5ff14ef2)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #ifndef _ZFORMAT_HXX
24 #define _ZFORMAT_HXX
25 
26 #include "svl/svldllapi.h"
27 #include <tools/string.hxx>
28 #include <i18npool/mslangid.hxx>
29 #include <svl/zforlist.hxx>
30 #include <svl/nfversi.hxx>
31 #include <svl/nfkeytab.hxx>
32 
33 // We need ImpSvNumberformatScan for the private SvNumberformat definitions.
34 #ifdef _ZFORMAT_CXX
35 #include "zforscan.hxx"
36 #endif
37 
38 // If comment field is also in format code string, was used for SUPD versions 371-372
39 #define NF_COMMENT_IN_FORMATSTRING 0
40 
41 namespace utl {
42     class DigitGroupingIterator;
43 }
44 
45 class SvStream;
46 class Color;
47 
48 class ImpSvNumberformatScan;            // format code string scanner
49 class ImpSvNumberInputScan;             // input string scanner
50 class ImpSvNumMultipleWriteHeader;      // compatible file format
51 class ImpSvNumMultipleReadHeader;       // compatible file format
52 class SvNumberFormatter;
53 
54 enum SvNumberformatLimitOps
55 {
56     NUMBERFORMAT_OP_NO  = 0,            // Undefined, no OP
57     NUMBERFORMAT_OP_EQ  = 1,            // Operator =
58     NUMBERFORMAT_OP_NE  = 2,            // Operator <>
59     NUMBERFORMAT_OP_LT  = 3,            // Operator <
60     NUMBERFORMAT_OP_LE  = 4,            // Operator <=
61     NUMBERFORMAT_OP_GT  = 5,            // Operator >
62     NUMBERFORMAT_OP_GE  = 6             // Operator >=
63 };
64 
65 // SYSTEM-german to SYSTEM-xxx and vice versa conversion hack onLoad
66 enum NfHackConversion
67 {
68     NF_CONVERT_NONE,
69     NF_CONVERT_GERMAN_ENGLISH,
70     NF_CONVERT_ENGLISH_GERMAN
71 };
72 
73 struct ImpSvNumberformatInfo            // Struct for FormatInfo
74 {
75     String* sStrArray;                  // Array of symbols
76     short* nTypeArray;                  // Array of infos
77     sal_uInt16 nThousand;                   // Count of group separator sequences
78     sal_uInt16 nCntPre;                     // Count of digits before decimal point
79     sal_uInt16 nCntPost;                    // Count of digits after decimal point
80     sal_uInt16 nCntExp;                     // Count of exponent digits, or AM/PM
81     short eScannedType;                 // Type determined by scan
82     sal_Bool bThousand;                     // Has group (AKA thousand) separator
83 
84     void Copy( const ImpSvNumberformatInfo& rNumFor, sal_uInt16 nAnz );
85     void Load(SvStream& rStream, sal_uInt16 nAnz);
86     void Save(SvStream& rStream, sal_uInt16 nAnz) const;
87 };
88 
89 // NativeNumber, represent numbers using CJK or other digits if nNum>0,
90 // eLang specifies the Locale to use.
91 class SvNumberNatNum
92 {
93     LanguageType    eLang;
94     sal_uInt8            nNum;
95     sal_Bool            bDBNum  :1;     // DBNum, to be converted to NatNum
96     sal_Bool            bDate   :1;     // Used in date? (needed for DBNum/NatNum mapping)
97     sal_Bool            bSet    :1;     // If set, since NatNum0 is possible
98 
99 public:
100 
101     static  sal_uInt8    MapDBNumToNatNum( sal_uInt8 nDBNum, LanguageType eLang, sal_Bool bDate );
102     static  sal_uInt8    MapNatNumToDBNum( sal_uInt8 nNatNum, LanguageType eLang, sal_Bool bDate );
103 
SvNumberNatNum()104                     SvNumberNatNum() : eLang( LANGUAGE_DONTKNOW ), nNum(0),
105                                         bDBNum(0), bDate(0), bSet(0) {}
IsComplete() const106     sal_Bool            IsComplete() const  { return bSet && eLang != LANGUAGE_DONTKNOW; }
GetRawNum() const107     sal_uInt8            GetRawNum() const   { return nNum; }
GetNatNum() const108     sal_uInt8            GetNatNum() const   { return bDBNum ? MapDBNumToNatNum( nNum, eLang, bDate ) : nNum; }
GetDBNum() const109     sal_uInt8            GetDBNum() const    { return bDBNum ? nNum : MapNatNumToDBNum( nNum, eLang, bDate ); }
GetLang() const110     LanguageType    GetLang() const     { return eLang; }
SetLang(LanguageType e)111     void            SetLang( LanguageType e ) { eLang = e; }
SetNum(sal_uInt8 nNumber,sal_Bool bDBNumber)112     void            SetNum( sal_uInt8 nNumber, sal_Bool bDBNumber )
113                         {
114                             nNum = nNumber;
115                             bDBNum = bDBNumber;
116                             bSet = sal_True;
117                         }
IsSet() const118     sal_Bool            IsSet() const       { return bSet; }
SetDate(sal_Bool bDateP)119     void            SetDate( sal_Bool bDateP )   { bDate = (bDateP != 0); }
120 };
121 
122 class CharClass;
123 
124 class ImpSvNumFor                       // One of four subformats of the format code string
125 {
126 public:
127     ImpSvNumFor();                      // Ctor without filling the Info
128     ~ImpSvNumFor();
129 
130     void Enlarge(sal_uInt16 nAnz);          // Init of arrays to the right size
131     void Load( SvStream& rStream, ImpSvNumberformatScan& rSc,
132                 String& rLoadedColorName);
133     void Save( SvStream& rStream ) const;
134 
135     // if pSc is set, it is used to get the Color pointer
136     void Copy( const ImpSvNumFor& rNumFor, ImpSvNumberformatScan* pSc );
137 
138     // Access to Info; call Enlarge before!
Info()139     ImpSvNumberformatInfo& Info() { return aI;}
Info() const140     const ImpSvNumberformatInfo& Info() const { return aI; }
141 
142     // Get count of substrings (symbols)
GetnAnz() const143     sal_uInt16 GetnAnz() const { return nAnzStrings;}
144 
GetColor() const145     Color* GetColor() const { return pColor; }
SetColor(Color * pCol,String & rName)146     void SetColor( Color* pCol, String& rName )
147      { pColor = pCol; sColorName = rName; }
GetColorName() const148     const String& GetColorName() const { return sColorName; }
149 
150     // new SYMBOLTYPE_CURRENCY in subformat?
151     sal_Bool HasNewCurrency() const;
152     sal_Bool GetNewCurrencySymbol( String& rSymbol, String& rExtension ) const;
153     void SaveNewCurrencyMap( SvStream& rStream ) const;
154     void LoadNewCurrencyMap( SvStream& rStream );
155 
156     // [NatNum1], [NatNum2], ...
SetNatNumNum(sal_uInt8 nNum,sal_Bool bDBNum)157     void SetNatNumNum( sal_uInt8 nNum, sal_Bool bDBNum ) { aNatNum.SetNum( nNum, bDBNum ); }
SetNatNumLang(LanguageType eLang)158     void SetNatNumLang( LanguageType eLang ) { aNatNum.SetLang( eLang ); }
SetNatNumDate(sal_Bool bDate)159     void SetNatNumDate( sal_Bool bDate ) { aNatNum.SetDate( bDate ); }
GetNatNum() const160     const SvNumberNatNum& GetNatNum() const { return aNatNum; }
161 
162     // check, if the format code contains a subformat for text
163     bool HasTextFormatCode() const;
164 
165 private:
166     ImpSvNumberformatInfo aI;           // Hilfsstruct fuer die restlichen Infos
167     String sColorName;                  // color name
168     Color* pColor;                      // pointer to color of subformat
169     sal_uInt16 nAnzStrings;                 // count of symbols
170     SvNumberNatNum aNatNum;             // DoubleByteNumber
171 
172 };
173 
174 class SVL_DLLPUBLIC SvNumberformat
175 {
176 public:
177     // Ctor for Load
178     SvNumberformat( ImpSvNumberformatScan& rSc, LanguageType eLge );
179 
180     // Normal ctor
181     SvNumberformat( String& rString,
182                    ImpSvNumberformatScan* pSc,
183                    ImpSvNumberInputScan* pISc,
184                    xub_StrLen& nCheckPos,
185                    LanguageType& eLan,
186                    sal_Bool bStand = sal_False );
187 
188     // Copy ctor
189     SvNumberformat( SvNumberformat& rFormat );
190 
191     // Copy ctor with exchange of format code string scanner (used in merge)
192     SvNumberformat( SvNumberformat& rFormat, ImpSvNumberformatScan& rSc );
193 
194     ~SvNumberformat();
195 
196     /// Get type of format, may include NUMBERFORMAT_DEFINED bit
GetType() const197     short GetType() const
198         { return (nNewStandardDefined &&
199             (nNewStandardDefined <= SV_NUMBERFORMATTER_VERSION)) ?
200             (eType & ~NUMBERFORMAT_DEFINED) : eType; }
201 
SetType(const short eSetType)202     void SetType(const short eSetType)          { eType = eSetType; }
203     // Standard means the I18N defined standard format of this type
SetStandard()204     void SetStandard()                          { bStandard = sal_True; }
IsStandard() const205     sal_Bool IsStandard() const                     { return bStandard; }
206 
207     // For versions before version nVer it is UserDefined, for newer versions
208     // it is builtin. nVer of SV_NUMBERFORMATTER_VERSION_...
SetNewStandardDefined(sal_uInt16 nVer)209     void SetNewStandardDefined( sal_uInt16 nVer )
210         { nNewStandardDefined = nVer; eType |= NUMBERFORMAT_DEFINED; }
211 
GetNewStandardDefined() const212     sal_uInt16 GetNewStandardDefined() const        { return nNewStandardDefined; }
IsAdditionalStandardDefined() const213     sal_Bool IsAdditionalStandardDefined() const
214         { return nNewStandardDefined == SV_NUMBERFORMATTER_VERSION_ADDITIONAL_I18N_FORMATS; }
215 
GetLanguage() const216     LanguageType GetLanguage() const            { return eLnge;}
217 
GetFormatstring() const218     const String& GetFormatstring() const   { return sFormatstring; }
219 
220     // Build a format string of application defined keywords
221     String GetMappedFormatstring( const NfKeywordTable& rKeywords,
222                                     const LocaleDataWrapper& rLoc,
223                                     sal_Bool bDontQuote = sal_False ) const;
224 
SetUsed(const sal_Bool b)225     void SetUsed(const sal_Bool b)                  { bIsUsed = b; }
GetUsed() const226     sal_Bool GetUsed() const                        { return bIsUsed; }
IsStarFormatSupported() const227     sal_Bool IsStarFormatSupported() const          { return bStarFlag; }
SetStarFormatSupport(sal_Bool b)228     void SetStarFormatSupport( sal_Bool b )         { bStarFlag = b; }
229 
230     NfHackConversion Load( SvStream& rStream, ImpSvNumMultipleReadHeader& rHdr,
231         SvNumberFormatter* pConverter, ImpSvNumberInputScan& rISc );
232     void Save( SvStream& rStream, ImpSvNumMultipleWriteHeader& rHdr  ) const;
233 
234     // Load a string which might contain an Euro symbol,
235     // in fact that could be any string used in number formats.
236     static void LoadString( SvStream& rStream, String& rStr );
237 
238     /**
239      * Get output string from a numeric value that fits the number of
240      * characters specified.
241      */
242     bool GetOutputString( double fNumber, sal_uInt16 nCharCount, String& rOutString ) const;
243 
244     sal_Bool GetOutputString( double fNumber, String& OutString, Color** ppColor );
245     sal_Bool GetOutputString( String& sString, String& OutString, Color** ppColor );
246 
247     // True if type text
IsTextFormat() const248     sal_Bool IsTextFormat() const { return (eType & NUMBERFORMAT_TEXT) != 0; }
249     // True if 4th subformat present
HasTextFormat() const250     sal_Bool HasTextFormat() const
251         {
252             return (NumFor[3].GetnAnz() > 0) ||
253                 (NumFor[3].Info().eScannedType == NUMBERFORMAT_TEXT);
254         }
255 
256     void GetFormatSpecialInfo(sal_Bool& bThousand,
257                               sal_Bool& IsRed,
258                               sal_uInt16& nPrecision,
259                               sal_uInt16& nAnzLeading) const;
260 
261     /// Count of decimal precision
GetFormatPrecision() const262     sal_uInt16 GetFormatPrecision() const   { return NumFor[0].Info().nCntPost; }
263 
264     //! Read/write access on a special sal_uInt16 component, may only be used on the
265     //! standard format 0, 5000, ... and only by the number formatter!
GetLastInsertKey() const266     sal_uInt16 GetLastInsertKey() const
267         { return NumFor[0].Info().nThousand; }
SetLastInsertKey(sal_uInt16 nKey)268     void SetLastInsertKey(sal_uInt16 nKey)
269         { NumFor[0].Info().nThousand = nKey; }
270 
271     //! Only onLoad: convert from stored to current system language/country
272     void ConvertLanguage( SvNumberFormatter& rConverter,
273         LanguageType eConvertFrom, LanguageType eConvertTo, sal_Bool bSystem = sal_False );
274 
275     // Substring of a subformat code nNumFor (0..3)
276     // nPos == 0xFFFF => last substring
277     // bString==sal_True: first/last SYMBOLTYPE_STRING or SYMBOLTYPE_CURRENCY
278     const String* GetNumForString( sal_uInt16 nNumFor, sal_uInt16 nPos,
279             sal_Bool bString = sal_False ) const;
280 
281     // Subtype of a subformat code nNumFor (0..3)
282     // nPos == 0xFFFF => last substring
283     // bString==sal_True: first/last SYMBOLTYPE_STRING or SYMBOLTYPE_CURRENCY
284     short GetNumForType( sal_uInt16 nNumFor, sal_uInt16 nPos, sal_Bool bString = sal_False ) const;
285 
286     /** If the count of string elements (substrings, ignoring [modifiers] and
287         so on) in a subformat code nNumFor (0..3) is equal to the given number.
288         Used by ImpSvNumberInputScan::IsNumberFormatMain() to detect a matched
289         format.  */
IsNumForStringElementCountEqual(sal_uInt16 nNumFor,sal_uInt16 nAllCount,sal_uInt16 nNumCount) const290     sal_Bool IsNumForStringElementCountEqual( sal_uInt16 nNumFor, sal_uInt16 nAllCount,
291             sal_uInt16 nNumCount ) const
292         {
293             if ( nNumFor < 4 )
294             {
295                 // First try a simple approach. Note that this is called only
296                 // if all MidStrings did match so far, to verify that all
297                 // strings of the format were matched and not just the starting
298                 // sequence, so we don't have to check if GetnAnz() includes
299                 // [modifiers] or anything else if both counts are equal.
300                 sal_uInt16 nCnt = NumFor[nNumFor].GetnAnz();
301                 if ( nAllCount == nCnt )
302                     return sal_True;
303                 if ( nAllCount < nCnt ) // check ignoring [modifiers] and so on
304                     return ImpGetNumForStringElementCount( nNumFor ) ==
305                         (nAllCount - nNumCount);
306             }
307             return sal_False;
308         }
309 
310     // Whether the second subformat code is really for negative numbers
311     // or another limit set.
IsNegativeRealNegative() const312     sal_Bool IsNegativeRealNegative() const
313         {
314             return fLimit1 == 0.0 && fLimit2 == 0.0 &&
315             ( (eOp1 == NUMBERFORMAT_OP_GE && eOp2 == NUMBERFORMAT_OP_NO) ||
316               (eOp1 == NUMBERFORMAT_OP_GT && eOp2 == NUMBERFORMAT_OP_LT) ||
317               (eOp1 == NUMBERFORMAT_OP_NO && eOp2 == NUMBERFORMAT_OP_NO) );
318         }
319 	// Whether the first subformat code is really for negative numbers
320     // or another limit set.
IsNegativeRealNegative2() const321     sal_Bool IsNegativeRealNegative2() const
322         {
323             return fLimit1 == 0.0 && fLimit2 == 0.0 &&
324             ( (eOp2 == NUMBERFORMAT_OP_GT && eOp1 == NUMBERFORMAT_OP_LT) ||
325 			  (eOp2 == NUMBERFORMAT_OP_EQ && eOp1 == NUMBERFORMAT_OP_LT) ||
326 			  (eOp2 == NUMBERFORMAT_OP_GE && eOp1 == NUMBERFORMAT_OP_LT) ||
327 			  (eOp2 == NUMBERFORMAT_OP_NO && eOp1 == NUMBERFORMAT_OP_LT) ||
328 			  (eOp2 == NUMBERFORMAT_OP_NO && eOp1 == NUMBERFORMAT_OP_LE) ||
329 			  (eOp2 == NUMBERFORMAT_OP_GT && eOp1 == NUMBERFORMAT_OP_LE));
330         }
331 
332     // Whether the negative format is without a sign or not
333     sal_Bool IsNegativeWithoutSign() const;
334 
335     // Whether a new SYMBOLTYPE_CURRENCY is contained in the format
336     sal_Bool HasNewCurrency() const;
337 
338     // check, if the format code contains a subformat for text
339     bool HasTextFormatCode() const;
340 
341     // Build string from NewCurrency for saving it SO50 compatible
342     void Build50Formatstring( String& rStr ) const;
343 
344     // strip [$-yyy] from all [$xxx-yyy] leaving only xxx's,
345     // if bQuoteSymbol==sal_True the xxx will become "xxx"
346     static String StripNewCurrencyDelimiters( const String& rStr,
347         sal_Bool bQuoteSymbol );
348 
349     // If a new SYMBOLTYPE_CURRENCY is contained if the format is of type
350     // NUMBERFORMAT_CURRENCY, and if so the symbol xxx and the extension nnn
351     // of [$xxx-nnn] are returned
352     sal_Bool GetNewCurrencySymbol( String& rSymbol, String& rExtension ) const;
353 
354     static sal_Bool HasStringNegativeSign( const String& rStr );
355 
356     /**
357         Whether a character at position nPos is somewhere between two matching
358         cQuote or not.
359         If nPos points to a cQuote, a sal_True is returned on an opening cQuote,
360         a sal_False is returned on a closing cQuote.
361         A cQuote between quotes may be escaped by a cEscIn, a cQuote outside of
362         quotes may be escaped by a cEscOut.
363         The default '\0' results in no escapement possible.
364         Defaults are set right according to the "unlogic" of the Numberformatter
365      */
366     static sal_Bool IsInQuote( const String& rString, xub_StrLen nPos,
367             sal_Unicode cQuote = '"',
368             sal_Unicode cEscIn = '\0', sal_Unicode cEscOut = '\\' );
369 
370     /**
371         Return the position of a matching closing cQuote if the character at
372         position nPos is between two matching cQuote, otherwise return
373         STRING_NOTFOUND.
374         If nPos points to an opening cQuote the position of the matching
375         closing cQuote is returned.
376         If nPos points to a closing cQuote nPos is returned.
377         If nPos points into a part which starts with an opening cQuote but has
378         no closing cQuote, rString.Len() is returned.
379         Uses <method>IsInQuote</method> internally, so you don't have to call
380         that prior to a call of this method.
381      */
382     static xub_StrLen GetQuoteEnd( const String& rString, xub_StrLen nPos,
383                 sal_Unicode cQuote = '"',
384                 sal_Unicode cEscIn = '\0', sal_Unicode cEscOut = '\\' );
385 
SetComment(const String & rStr)386     void SetComment( const String& rStr )
387 #if NF_COMMENT_IN_FORMATSTRING
388         { SetComment( rStr, sFormatstring, sComment ); }
389 #else
390         { sComment = rStr; }
391 #endif
GetComment() const392     const String& GetComment() const { return sComment; }
393 
394     // Erase "{ "..." }" from format subcode string to get the pure comment (old version)
395     static void EraseCommentBraces( String& rStr );
396     // Set comment rStr in format string rFormat and in rComment (old version)
397     static void SetComment( const String& rStr, String& rFormat, String& rComment );
398     // Erase comment at end of rStr to get pure format code string (old version)
399     static void EraseComment( String& rStr );
400 
401     /** Insert the number of blanks into the string that is needed to simulate
402         the width of character c for underscore formats */
403     static xub_StrLen InsertBlanks( String& r, xub_StrLen nPos, sal_Unicode c );
404 
405     /// One of YMD,DMY,MDY if date format
406     DateFormat GetDateOrder() const;
407 
408     /** A coded value of the exact YMD combination used, if date format.
409         For example: YYYY-MM-DD => ('Y' << 16) | ('M' << 8) | 'D'
410         or: MM/YY => ('M' << 8) | 'Y'  */
411     sal_uInt32 GetExactDateOrder() const;
412 
ImpGetScan() const413     ImpSvNumberformatScan& ImpGetScan() const { return rScan; }
414 
415     // used in XML export
416     void GetConditions( SvNumberformatLimitOps& rOper1, double& rVal1,
417                         SvNumberformatLimitOps& rOper2, double& rVal2 ) const;
418     Color* GetColor( sal_uInt16 nNumFor ) const;
419     void GetNumForInfo( sal_uInt16 nNumFor, short& rScannedType,
420                     sal_Bool& bThousand, sal_uInt16& nPrecision, sal_uInt16& nAnzLeading ) const;
421 
422     // rAttr.Number not empty if NatNum attributes are to be stored
423     void GetNatNumXml(
424             ::com::sun::star::i18n::NativeNumberXmlAttributes& rAttr,
425             sal_uInt16 nNumFor ) const;
426 
427     /** @returns <TRUE/> if E,EE,R,RR,AAA,AAAA in format code of subformat
428         nNumFor (0..3) and <b>no</b> preceding calendar was specified and the
429         currently loaded calendar is "gregorian". */
IsOtherCalendar(sal_uInt16 nNumFor) const430     sal_Bool IsOtherCalendar( sal_uInt16 nNumFor ) const
431         {
432             if ( nNumFor < 4 )
433                 return ImpIsOtherCalendar( NumFor[nNumFor] );
434             return sal_False;
435         }
436 
437     /** Switches to the first non-"gregorian" calendar, but only if the current
438         calendar is "gregorian"; original calendar name and date/time returned,
439         but only if calendar switched and rOrgCalendar was empty. */
440     void SwitchToOtherCalendar( String& rOrgCalendar, double& fOrgDateTime ) const;
441 
442     /** Switches to the "gregorian" calendar, but only if the current calendar
443         is non-"gregorian" and rOrgCalendar is not empty. Thus a preceding
444         ImpSwitchToOtherCalendar() call should have been placed prior to
445         calling this method. */
446     void SwitchToGregorianCalendar( const String& rOrgCalendar, double fOrgDateTime ) const;
447 
448     /** Switches to the first specified calendar, if any, in subformat nNumFor
449         (0..3). Original calendar name and date/time returned, but only if
450         calendar switched and rOrgCalendar was empty.
451 
452         @return
453             <TRUE/> if a calendar was specified and switched to,
454             <FALSE/> else.
455      */
SwitchToSpecifiedCalendar(String & rOrgCalendar,double & fOrgDateTime,sal_uInt16 nNumFor) const456     sal_Bool SwitchToSpecifiedCalendar( String& rOrgCalendar, double& fOrgDateTime,
457             sal_uInt16 nNumFor ) const
458         {
459             if ( nNumFor < 4 )
460                 return ImpSwitchToSpecifiedCalendar( rOrgCalendar,
461                         fOrgDateTime, NumFor[nNumFor] );
462             return sal_False;
463         }
464 
465 private:
466     ImpSvNumFor NumFor[4];          // Array for the 4 subformats
467     String sFormatstring;           // The format code string
468     String sComment;                // Comment, since number formatter version 6
469     double fLimit1;                 // Value for first condition
470     double fLimit2;                 // Value for second condition
471     ImpSvNumberformatScan& rScan;   // Format code scanner
472     LanguageType eLnge;             // Language/country of the format
473     SvNumberformatLimitOps eOp1;    // Operator for first condition
474     SvNumberformatLimitOps eOp2;    // Operator for second condition
475     sal_uInt16 nNewStandardDefined;     // new builtin formats as of version 6
476     short eType;                    // Type of format
477     sal_Bool bStarFlag;                 // Take *n format as ESC n
478     sal_Bool bStandard;                 // If this is a default standard format
479     sal_Bool bIsUsed;                   // Flag as used for storing
480 
481     SVL_DLLPRIVATE sal_uInt16 ImpGetNumForStringElementCount( sal_uInt16 nNumFor ) const;
482 
483     SVL_DLLPRIVATE sal_Bool ImpIsOtherCalendar( const ImpSvNumFor& rNumFor ) const;
484 
485     SVL_DLLPRIVATE sal_Bool ImpSwitchToSpecifiedCalendar( String& rOrgCalendar,
486             double& fOrgDateTime, const ImpSvNumFor& rNumFor ) const;
487 
488 #ifdef _ZFORMAT_CXX     // ----- private implementation methods -----
489 
rChrCls() const490     const CharClass& rChrCls() const        { return rScan.GetChrCls(); }
rLoc() const491     const LocaleDataWrapper& rLoc() const   { return rScan.GetLoc(); }
GetCal() const492     CalendarWrapper& GetCal() const         { return rScan.GetCal(); }
GetFormatter() const493     const SvNumberFormatter& GetFormatter() const   { return *rScan.GetNumberformatter(); }
494 
495     // divide in substrings and color conditions
496     SVL_DLLPRIVATE short ImpNextSymbol( String& rString,
497                      xub_StrLen& nPos,
498                      String& sSymbol );
499 
500     // read string until ']' and strip blanks (after condition)
501     SVL_DLLPRIVATE static xub_StrLen ImpGetNumber( String& rString,
502                    xub_StrLen& nPos,
503                    String& sSymbol );
504 
505     // get xxx of "[$-xxx]" as LanguageType, starting at and advancing position nPos
506     SVL_DLLPRIVATE static LanguageType ImpGetLanguageType( const String& rString, xub_StrLen& nPos );
507 
508     // standard number output
509     SVL_DLLPRIVATE void ImpGetOutputStandard( double& fNumber, String& OutString );
510     SVL_DLLPRIVATE void ImpGetOutputStdToPrecision( double& rNumber, String& rOutString, sal_uInt16 nPrecision ) const;
511     // numbers in input line
512     SVL_DLLPRIVATE void ImpGetOutputInputLine( double fNumber, String& OutString );
513 
514     // check subcondition
515     // OP undefined => -1
516     // else 0 or 1
517     SVL_DLLPRIVATE short ImpCheckCondition(double& fNumber,
518                          double& fLimit,
519                          SvNumberformatLimitOps eOp);
520 
521     SVL_DLLPRIVATE sal_uLong ImpGGT(sal_uLong x, sal_uLong y);
522     SVL_DLLPRIVATE sal_uLong ImpGGTRound(sal_uLong x, sal_uLong y);
523 
524     // Helper function for number strings
525     // append string symbols, insert leading 0 or ' ', or ...
526     SVL_DLLPRIVATE sal_Bool ImpNumberFill( String& sStr,
527                     double& rNumber,
528                     xub_StrLen& k,
529                     sal_uInt16& j,
530                     sal_uInt16 nIx,
531                     short eSymbolType );
532 
533     // Helper function to fill in the integer part and the group (AKA thousand) separators
534     SVL_DLLPRIVATE sal_Bool ImpNumberFillWithThousands( String& sStr,
535                                  double& rNumber,
536                                  xub_StrLen k,
537                                  sal_uInt16 j,
538                                  sal_uInt16 nIx,
539                                  sal_uInt16 nDigCnt );
540                                     // Hilfsfunktion zum Auffuellen der Vor-
541                                     // kommazahl auch mit Tausenderpunkt
542 
543     // Helper function to fill in the group (AKA thousand) separators
544     // or to skip additional digits
545     SVL_DLLPRIVATE void ImpDigitFill( String& sStr,
546                     xub_StrLen nStart,
547                     xub_StrLen& k,
548                     sal_uInt16 nIx,
549                     xub_StrLen & nDigitCount,
550                     utl::DigitGroupingIterator & );
551 
552     SVL_DLLPRIVATE sal_Bool ImpGetDateOutput( double fNumber,
553                        sal_uInt16 nIx,
554                        String& OutString );
555     SVL_DLLPRIVATE sal_Bool ImpGetTimeOutput( double fNumber,
556                        sal_uInt16 nIx,
557                        String& OutString );
558     SVL_DLLPRIVATE sal_Bool ImpGetDateTimeOutput( double fNumber,
559                            sal_uInt16 nIx,
560                            String& OutString );
561 
562     // Switches to the "gregorian" calendar if the current calendar is
563     // non-"gregorian" and the era is a "Dummy" era of a calendar which doesn't
564     // know a "before" era (like zh_TW ROC or ja_JP Gengou). If switched and
565     // rOrgCalendar was "gregorian" the string is emptied. If rOrgCalendar was
566     // empty the previous calendar name and date/time are returned.
567     SVL_DLLPRIVATE sal_Bool ImpFallBackToGregorianCalendar( String& rOrgCalendar, double& fOrgDateTime );
568 
569     // Append a "G" short era string of the given calendar. In the case of a
570     // Gengou calendar this is a one character abbreviation, for other
571     // calendars the XExtendedCalendar::getDisplayString() method is called.
572     SVL_DLLPRIVATE static void ImpAppendEraG( String& OutString, const CalendarWrapper& rCal,
573             sal_Int16 nNatNum );
574 
575     SVL_DLLPRIVATE sal_Bool ImpGetNumberOutput( double fNumber,
576                          sal_uInt16 nIx,
577                          String& OutString );
578 
579     SVL_DLLPRIVATE void ImpCopyNumberformat( const SvNumberformat& rFormat );
580 
581     // normal digits or other digits, depending on ImpSvNumFor.aNatNum,
582     // [NatNum1], [NatNum2], ...
583     SVL_DLLPRIVATE String ImpGetNatNumString( const SvNumberNatNum& rNum, sal_Int32 nVal,
584             sal_uInt16 nMinDigits = 0  ) const;
585 
ImpIntToString(sal_uInt16 nIx,sal_Int32 nVal,sal_uInt16 nMinDigits=0) const586     String ImpIntToString( sal_uInt16 nIx, sal_Int32 nVal, sal_uInt16 nMinDigits = 0 ) const
587         {
588             const SvNumberNatNum& rNum = NumFor[nIx].GetNatNum();
589             if ( nMinDigits || rNum.IsComplete() )
590                 return ImpGetNatNumString( rNum, nVal, nMinDigits );
591             return String::CreateFromInt32( nVal );
592         }
593 
594     // transliterate according to NativeNumber
595     SVL_DLLPRIVATE void ImpTransliterateImpl( String& rStr, const SvNumberNatNum& rNum ) const;
596 
ImpTransliterate(String & rStr,const SvNumberNatNum & rNum) const597     void ImpTransliterate( String& rStr, const SvNumberNatNum& rNum ) const
598         {
599             if ( rNum.IsComplete() )
600                 ImpTransliterateImpl( rStr, rNum );
601         }
602 
603 #endif // _ZFORMAT_CXX
604 
605 };
606 
607 #endif  // _ZFORMAT_HXX
608