Branch data Line data Source code
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 : : #ifndef _ZFORMAT_HXX
20 : : #define _ZFORMAT_HXX
21 : :
22 : : #include "svl/svldllapi.h"
23 : : #include <tools/string.hxx>
24 : : #include <i18npool/mslangid.hxx>
25 : : #include <svl/zforlist.hxx>
26 : : #include <svl/nfversi.hxx>
27 : : #include <svl/nfkeytab.hxx>
28 : :
29 : : // We need ImpSvNumberformatScan for the private SvNumberformat definitions.
30 : : #ifdef _ZFORMAT_CXX
31 : : #include "zforscan.hxx"
32 : : #endif
33 : :
34 : : namespace utl {
35 : : class DigitGroupingIterator;
36 : : }
37 : :
38 : : class SvStream;
39 : : class Color;
40 : :
41 : : class ImpSvNumberformatScan; // format code string scanner
42 : : class ImpSvNumberInputScan; // input string scanner
43 : : class ImpSvNumMultipleWriteHeader; // compatible file format
44 : : class ImpSvNumMultipleReadHeader; // compatible file format
45 : : class SvNumberFormatter;
46 : :
47 : : enum SvNumberformatLimitOps
48 : : {
49 : : NUMBERFORMAT_OP_NO = 0, // Undefined, no OP
50 : : NUMBERFORMAT_OP_EQ = 1, // Operator =
51 : : NUMBERFORMAT_OP_NE = 2, // Operator <>
52 : : NUMBERFORMAT_OP_LT = 3, // Operator <
53 : : NUMBERFORMAT_OP_LE = 4, // Operator <=
54 : : NUMBERFORMAT_OP_GT = 5, // Operator >
55 : : NUMBERFORMAT_OP_GE = 6 // Operator >=
56 : : };
57 : :
58 : : // SYSTEM-german to SYSTEM-xxx and vice versa conversion hack onLoad
59 : : enum NfHackConversion
60 : : {
61 : : NF_CONVERT_NONE,
62 : : NF_CONVERT_GERMAN_ENGLISH,
63 : : NF_CONVERT_ENGLISH_GERMAN
64 : : };
65 : :
66 : : struct ImpSvNumberformatInfo // Struct for FormatInfo
67 : : {
68 : : String* sStrArray; // Array of symbols
69 : : short* nTypeArray; // Array of infos
70 : : sal_uInt16 nThousand; // Count of group separator sequences
71 : : sal_uInt16 nCntPre; // Count of digits before decimal point
72 : : sal_uInt16 nCntPost; // Count of digits after decimal point
73 : : sal_uInt16 nCntExp; // Count of exponent digits, or AM/PM
74 : : short eScannedType; // Type determined by scan
75 : : bool bThousand; // Has group (AKA thousand) separator
76 : :
77 : : void Copy( const ImpSvNumberformatInfo& rNumFor, sal_uInt16 nAnz );
78 : : void Load(SvStream& rStream, sal_uInt16 nAnz);
79 : : void Save(SvStream& rStream, sal_uInt16 nAnz) const;
80 : : };
81 : :
82 : : // NativeNumber, represent numbers using CJK or other digits if nNum>0,
83 : : // eLang specifies the Locale to use.
84 : : class SvNumberNatNum
85 : : {
86 : : LanguageType eLang;
87 : : sal_uInt8 nNum;
88 : : bool bDBNum :1; // DBNum, to be converted to NatNum
89 : : bool bDate :1; // Used in date? (needed for DBNum/NatNum mapping)
90 : : bool bSet :1; // If set, since NatNum0 is possible
91 : :
92 : : public:
93 : :
94 : : static sal_uInt8 MapDBNumToNatNum( sal_uInt8 nDBNum, LanguageType eLang, bool bDate );
95 : : #ifdef THE_FUTURE
96 : : static sal_uInt8 MapNatNumToDBNum( sal_uInt8 nNatNum, LanguageType eLang, bool bDate );
97 : : #endif
98 : :
99 : 673432 : SvNumberNatNum() : eLang( LANGUAGE_DONTKNOW ), nNum(0),
100 : 673432 : bDBNum(0), bDate(0), bSet(0) {}
101 [ - + ][ # # ]: 65005 : bool IsComplete() const { return bSet && eLang != LANGUAGE_DONTKNOW; }
102 : : sal_uInt8 GetRawNum() const { return nNum; }
103 [ - + ]: 199390 : sal_uInt8 GetNatNum() const { return bDBNum ? MapDBNumToNatNum( nNum, eLang, bDate ) : nNum; }
104 : : #ifdef THE_FUTURE
105 : : sal_uInt8 GetDBNum() const { return bDBNum ? nNum : MapNatNumToDBNum( nNum, eLang, bDate ); }
106 : : #endif
107 : 15 : LanguageType GetLang() const { return eLang; }
108 : 15 : void SetLang( LanguageType e ) { eLang = e; }
109 : 0 : void SetNum( sal_uInt8 nNumber, bool bDBNumber )
110 : : {
111 : 0 : nNum = nNumber;
112 : 0 : bDBNum = bDBNumber;
113 : 0 : bSet = true;
114 : 0 : }
115 : 398371 : bool IsSet() const { return bSet; }
116 : 0 : void SetDate( bool bDateP ) { bDate = (bDateP != 0); }
117 : : };
118 : :
119 : : class CharClass;
120 : :
121 : : class ImpSvNumFor // One of four subformats of the format code string
122 : : {
123 : : public:
124 : : ImpSvNumFor(); // Ctor without filling the Info
125 : : ~ImpSvNumFor();
126 : :
127 : : void Enlarge(sal_uInt16 nAnz); // Init of arrays to the right size
128 : : void Load( SvStream& rStream, ImpSvNumberformatScan& rSc,
129 : : String& rLoadedColorName);
130 : : void Save( SvStream& rStream ) const;
131 : :
132 : : // if pSc is set, it is used to get the Color pointer
133 : : void Copy( const ImpSvNumFor& rNumFor, ImpSvNumberformatScan* pSc );
134 : :
135 : : // Access to Info; call Enlarge before!
136 : 415032 : ImpSvNumberformatInfo& Info() { return aI;}
137 : 26047 : const ImpSvNumberformatInfo& Info() const { return aI; }
138 : :
139 : : // Get count of substrings (symbols)
140 : 200870 : sal_uInt16 GetCount() const { return nAnzStrings;}
141 : :
142 : 19296 : Color* GetColor() const { return pColor; }
143 : 15173 : void SetColor( Color* pCol, String& rName )
144 : 15173 : { pColor = pCol; sColorName = rName; }
145 : 0 : const String& GetColorName() const { return sColorName; }
146 : :
147 : : // new SYMBOLTYPE_CURRENCY in subformat?
148 : : bool HasNewCurrency() const;
149 : : bool GetNewCurrencySymbol( String& rSymbol, String& rExtension ) const;
150 : : void SaveNewCurrencyMap( SvStream& rStream ) const;
151 : : void LoadNewCurrencyMap( SvStream& rStream );
152 : :
153 : : // [NatNum1], [NatNum2], ...
154 : 0 : void SetNatNumNum( sal_uInt8 nNum, bool bDBNum ) { aNatNum.SetNum( nNum, bDBNum ); }
155 : 15 : void SetNatNumLang( LanguageType eLang ) { aNatNum.SetLang( eLang ); }
156 : 0 : void SetNatNumDate( bool bDate ) { aNatNum.SetDate( bDate ); }
157 : 662781 : const SvNumberNatNum& GetNatNum() const { return aNatNum; }
158 : :
159 : : private:
160 : : ImpSvNumberformatInfo aI; // Hilfsstruct fuer die restlichen Infos
161 : : String sColorName; // color name
162 : : Color* pColor; // pointer to color of subformat
163 : : sal_uInt16 nAnzStrings; // count of symbols
164 : : SvNumberNatNum aNatNum; // DoubleByteNumber
165 : :
166 : : };
167 : :
168 : : class SVL_DLLPUBLIC SvNumberformat
169 : : {
170 : : struct LocaleType
171 : : {
172 : : sal_uInt8 mnNumeralShape;
173 : : sal_uInt8 mnCalendarType;
174 : : LanguageType meLanguage;
175 : :
176 : : ::rtl::OUString generateCode() const;
177 : :
178 : : LocaleType();
179 : : LocaleType(sal_uInt32 nRawCode);
180 : : };
181 : :
182 : : public:
183 : : // Ctor for Load
184 : : SvNumberformat( ImpSvNumberformatScan& rSc, LanguageType eLge );
185 : :
186 : : // Normal ctor
187 : : SvNumberformat( String& rString,
188 : : ImpSvNumberformatScan* pSc,
189 : : ImpSvNumberInputScan* pISc,
190 : : xub_StrLen& nCheckPos,
191 : : LanguageType& eLan,
192 : : bool bStand = false );
193 : :
194 : : // Copy ctor
195 : : SvNumberformat( SvNumberformat& rFormat );
196 : :
197 : : // Copy ctor with exchange of format code string scanner (used in merge)
198 : : SvNumberformat( SvNumberformat& rFormat, ImpSvNumberformatScan& rSc );
199 : :
200 : : ~SvNumberformat();
201 : :
202 : : /// Get type of format, may include NUMBERFORMAT_DEFINED bit
203 : 210794 : short GetType() const
204 : : { return (nNewStandardDefined &&
205 : : (nNewStandardDefined <= SV_NUMBERFORMATTER_VERSION)) ?
206 [ + + ][ + - ]: 210794 : (eType & ~NUMBERFORMAT_DEFINED) : eType; }
207 : :
208 : 11787 : void SetType(const short eSetType) { eType = eSetType; }
209 : : // Standard means the I18N defined standard format of this type
210 : 21960 : void SetStandard() { bStandard = true; }
211 : 1615 : bool IsStandard() const { return bStandard; }
212 : :
213 : : // For versions before version nVer it is UserDefined, for newer versions
214 : : // it is builtin. nVer of SV_NUMBERFORMATTER_VERSION_...
215 : 85250 : void SetNewStandardDefined( sal_uInt16 nVer )
216 : 85250 : { nNewStandardDefined = nVer; eType |= NUMBERFORMAT_DEFINED; }
217 : :
218 : 0 : sal_uInt16 GetNewStandardDefined() const { return nNewStandardDefined; }
219 : 0 : bool IsAdditionalStandardDefined() const
220 : 0 : { return nNewStandardDefined == SV_NUMBERFORMATTER_VERSION_ADDITIONAL_I18N_FORMATS; }
221 : :
222 : 2880785 : LanguageType GetLanguage() const { return maLocale.meLanguage;}
223 : :
224 : 2565675 : const String& GetFormatstring() const { return sFormatstring; }
225 : :
226 : : // Build a format string of application defined keywords
227 : : String GetMappedFormatstring( const NfKeywordTable& rKeywords,
228 : : const LocaleDataWrapper& rLoc,
229 : : bool bDontQuote = false ) const;
230 : :
231 : 4880 : void SetUsed(const bool b) { bIsUsed = b; }
232 : 0 : bool GetUsed() const { return bIsUsed; }
233 : : bool IsStarFormatSupported() const { return bStarFlag; }
234 : 11572 : void SetStarFormatSupport( bool b ) { bStarFlag = b; }
235 : :
236 : : NfHackConversion Load( SvStream& rStream, ImpSvNumMultipleReadHeader& rHdr,
237 : : SvNumberFormatter* pConverter, ImpSvNumberInputScan& rISc );
238 : : void Save( SvStream& rStream, ImpSvNumMultipleWriteHeader& rHdr ) const;
239 : :
240 : : // Load a string which might contain an Euro symbol,
241 : : // in fact that could be any string used in number formats.
242 : : static rtl::OUString LoadString( SvStream& rStream );
243 : :
244 : : /**
245 : : * Get output string from a numeric value that fits the number of
246 : : * characters specified.
247 : : */
248 : : bool GetOutputString( double fNumber, sal_uInt16 nCharCount, String& rOutString ) const;
249 : :
250 : : bool GetOutputString( double fNumber, String& OutString, Color** ppColor );
251 : : bool GetOutputString( String& sString, String& OutString, Color** ppColor );
252 : :
253 : : // True if type text
254 : 20137 : bool IsTextFormat() const { return (eType & NUMBERFORMAT_TEXT) != 0; }
255 : : // True if 4th subformat present
256 : 17373 : bool HasTextFormat() const
257 : : {
258 : 17373 : return (NumFor[3].GetCount() > 0) ||
259 [ - + ][ + - ]: 17373 : (NumFor[3].Info().eScannedType == NUMBERFORMAT_TEXT);
260 : : }
261 : :
262 : : void GetFormatSpecialInfo(bool& bThousand,
263 : : bool& IsRed,
264 : : sal_uInt16& nPrecision,
265 : : sal_uInt16& nAnzLeading) const;
266 : :
267 : : /// Count of decimal precision
268 : 0 : sal_uInt16 GetFormatPrecision() const { return NumFor[0].Info().nCntPost; }
269 : :
270 : : //! Read/write access on a special sal_uInt16 component, may only be used on the
271 : : //! standard format 0, 5000, ... and only by the number formatter!
272 : 4900 : sal_uInt16 GetLastInsertKey() const
273 : 4900 : { return NumFor[0].Info().nThousand; }
274 : 7340 : void SetLastInsertKey(sal_uInt16 nKey)
275 : 7340 : { NumFor[0].Info().nThousand = nKey; }
276 : :
277 : : //! Only onLoad: convert from stored to current system language/country
278 : : void ConvertLanguage( SvNumberFormatter& rConverter,
279 : : LanguageType eConvertFrom, LanguageType eConvertTo, bool bSystem = false );
280 : :
281 : : // Substring of a subformat code nNumFor (0..3)
282 : : // nPos == 0xFFFF => last substring
283 : : // bString==true: first/last SYMBOLTYPE_STRING or SYMBOLTYPE_CURRENCY
284 : : const String* GetNumForString( sal_uInt16 nNumFor, sal_uInt16 nPos,
285 : : bool bString = false ) const;
286 : :
287 : : // Subtype of a subformat code nNumFor (0..3)
288 : : // nPos == 0xFFFF => last substring
289 : : // bString==true: first/last SYMBOLTYPE_STRING or SYMBOLTYPE_CURRENCY
290 : : short GetNumForType( sal_uInt16 nNumFor, sal_uInt16 nPos, bool bString = false ) const;
291 : :
292 : : /** If the count of string elements (substrings, ignoring [modifiers] and
293 : : so on) in a subformat code nNumFor (0..3) is equal to the given number.
294 : : Used by ImpSvNumberInputScan::IsNumberFormatMain() to detect a matched
295 : : format. */
296 : 0 : bool IsNumForStringElementCountEqual( sal_uInt16 nNumFor, sal_uInt16 nAllCount,
297 : : sal_uInt16 nNumCount ) const
298 : : {
299 [ # # ]: 0 : if ( nNumFor < 4 )
300 : : {
301 : : // First try a simple approach. Note that this is called only
302 : : // if all MidStrings did match so far, to verify that all
303 : : // strings of the format were matched and not just the starting
304 : : // sequence, so we don't have to check if GetnAnz() includes
305 : : // [modifiers] or anything else if both counts are equal.
306 : 0 : sal_uInt16 nCnt = NumFor[nNumFor].GetCount();
307 [ # # ]: 0 : if ( nAllCount == nCnt )
308 : 0 : return true;
309 [ # # ]: 0 : if ( nAllCount < nCnt ) // check ignoring [modifiers] and so on
310 : 0 : return ImpGetNumForStringElementCount( nNumFor ) ==
311 : 0 : (nAllCount - nNumCount);
312 : : }
313 : 0 : return false;
314 : : }
315 : :
316 : : // Whether the second subformat code is really for negative numbers
317 : : // or another limit set.
318 : 16 : bool IsNegativeRealNegative() const
319 : : {
320 : : return fLimit1 == 0.0 && fLimit2 == 0.0 &&
321 : : ( (eOp1 == NUMBERFORMAT_OP_GE && eOp2 == NUMBERFORMAT_OP_NO) ||
322 : : (eOp1 == NUMBERFORMAT_OP_GT && eOp2 == NUMBERFORMAT_OP_LT) ||
323 [ + - ][ + - ]: 16 : (eOp1 == NUMBERFORMAT_OP_NO && eOp2 == NUMBERFORMAT_OP_NO) );
[ + - ][ - + ]
[ # # ][ # # ]
[ # # ][ # # ]
324 : : }
325 : :
326 : : // Whether the negative format is without a sign or not
327 : : bool IsNegativeWithoutSign() const;
328 : :
329 : : bool IsNegativeInBracket() const;
330 : :
331 : : bool HasPositiveBracketPlaceholder() const;
332 : :
333 : : // Whether a new SYMBOLTYPE_CURRENCY is contained in the format
334 : : bool HasNewCurrency() const;
335 : :
336 : : // Build string from NewCurrency for saving it SO50 compatible
337 : : void Build50Formatstring( String& rStr ) const;
338 : :
339 : : // strip [$-yyy] from all [$xxx-yyy] leaving only xxx's,
340 : : // if bQuoteSymbol==true the xxx will become "xxx"
341 : : static String StripNewCurrencyDelimiters( const String& rStr,
342 : : bool bQuoteSymbol );
343 : :
344 : : // If a new SYMBOLTYPE_CURRENCY is contained if the format is of type
345 : : // NUMBERFORMAT_CURRENCY, and if so the symbol xxx and the extension nnn
346 : : // of [$xxx-nnn] are returned
347 : : bool GetNewCurrencySymbol( String& rSymbol, String& rExtension ) const;
348 : :
349 : : static bool HasStringNegativeSign( const String& rStr );
350 : :
351 : : /**
352 : : Whether a character at position nPos is somewhere between two matching
353 : : cQuote or not.
354 : : If nPos points to a cQuote, a true is returned on an opening cQuote,
355 : : a false is returned on a closing cQuote.
356 : : A cQuote between quotes may be escaped by a cEscIn, a cQuote outside of
357 : : quotes may be escaped by a cEscOut.
358 : : The default '\0' results in no escapement possible.
359 : : Defaults are set right according to the "unlogic" of the Numberformatter
360 : : */
361 : : static bool IsInQuote( const String& rString, xub_StrLen nPos,
362 : : sal_Unicode cQuote = '"',
363 : : sal_Unicode cEscIn = '\0', sal_Unicode cEscOut = '\\' );
364 : :
365 : : /**
366 : : Return the position of a matching closing cQuote if the character at
367 : : position nPos is between two matching cQuote, otherwise return
368 : : STRING_NOTFOUND.
369 : : If nPos points to an opening cQuote the position of the matching
370 : : closing cQuote is returned.
371 : : If nPos points to a closing cQuote nPos is returned.
372 : : If nPos points into a part which starts with an opening cQuote but has
373 : : no closing cQuote, rString.Len() is returned.
374 : : Uses <method>IsInQuote</method> internally, so you don't have to call
375 : : that prior to a call of this method.
376 : : */
377 : : static xub_StrLen GetQuoteEnd( const String& rString, xub_StrLen nPos,
378 : : sal_Unicode cQuote = '"',
379 : : sal_Unicode cEscIn = '\0', sal_Unicode cEscOut = '\\' );
380 : :
381 : 2440 : void SetComment( const String& rStr )
382 : 2440 : { sComment = rStr; }
383 : 33 : const String& GetComment() const { return sComment; }
384 : :
385 : : /** Insert the number of blanks into the string that is needed to simulate
386 : : the width of character c for underscore formats */
387 : : static xub_StrLen InsertBlanks( String& r, xub_StrLen nPos, sal_Unicode c );
388 : :
389 : : /// One of YMD,DMY,MDY if date format
390 : : DateFormat GetDateOrder() const;
391 : :
392 : : /** A coded value of the exact YMD combination used, if date format.
393 : : For example: YYYY-MM-DD => ('Y' << 16) | ('M' << 8) | 'D'
394 : : or: MM/YY => ('M' << 8) | 'Y' */
395 : : sal_uInt32 GetExactDateOrder() const;
396 : :
397 : : ImpSvNumberformatScan& ImpGetScan() const { return rScan; }
398 : :
399 : : // used in XML export
400 : : void GetConditions( SvNumberformatLimitOps& rOper1, double& rVal1,
401 : : SvNumberformatLimitOps& rOper2, double& rVal2 ) const;
402 : : Color* GetColor( sal_uInt16 nNumFor ) const;
403 : : void GetNumForInfo( sal_uInt16 nNumFor, short& rScannedType,
404 : : bool& bThousand, sal_uInt16& nPrecision, sal_uInt16& nAnzLeading ) const;
405 : :
406 : : // rAttr.Number not empty if NatNum attributes are to be stored
407 : : void GetNatNumXml(
408 : : ::com::sun::star::i18n::NativeNumberXmlAttributes& rAttr,
409 : : sal_uInt16 nNumFor ) const;
410 : :
411 : : /** @returns <TRUE/> if E,EE,R,RR,AAA,AAAA in format code of subformat
412 : : nNumFor (0..3) and <b>no</b> preceding calendar was specified and the
413 : : currently loaded calendar is "gregorian". */
414 : : bool IsOtherCalendar( sal_uInt16 nNumFor ) const
415 : : {
416 : : if ( nNumFor < 4 )
417 : : return ImpIsOtherCalendar( NumFor[nNumFor] );
418 : : return false;
419 : : }
420 : :
421 : : /** Switches to the first non-"gregorian" calendar, but only if the current
422 : : calendar is "gregorian"; original calendar name and date/time returned,
423 : : but only if calendar switched and rOrgCalendar was empty. */
424 : : void SwitchToOtherCalendar( String& rOrgCalendar, double& fOrgDateTime ) const;
425 : :
426 : : /** Switches to the "gregorian" calendar, but only if the current calendar
427 : : is non-"gregorian" and rOrgCalendar is not empty. Thus a preceding
428 : : ImpSwitchToOtherCalendar() call should have been placed prior to
429 : : calling this method. */
430 : : void SwitchToGregorianCalendar( const String& rOrgCalendar, double fOrgDateTime ) const;
431 : :
432 : : #ifdef THE_FUTURE
433 : : /** Switches to the first specified calendar, if any, in subformat nNumFor
434 : : (0..3). Original calendar name and date/time returned, but only if
435 : : calendar switched and rOrgCalendar was empty.
436 : :
437 : : @return
438 : : <TRUE/> if a calendar was specified and switched to,
439 : : <FALSE/> else.
440 : : */
441 : : bool SwitchToSpecifiedCalendar( String& rOrgCalendar, double& fOrgDateTime,
442 : : sal_uInt16 nNumFor ) const
443 : : {
444 : : if ( nNumFor < 4 )
445 : : return ImpSwitchToSpecifiedCalendar( rOrgCalendar,
446 : : fOrgDateTime, NumFor[nNumFor] );
447 : : return false;
448 : : }
449 : : #endif
450 : :
451 : : /// Whether it's a (YY)YY-M(M)-D(D) format.
452 : 6 : bool IsIso8601( sal_uInt16 nNumFor )
453 : : {
454 [ + - ]: 6 : if ( nNumFor < 4 )
455 : 6 : return ImpIsIso8601( NumFor[nNumFor]);
456 : 6 : return false;
457 : : }
458 : :
459 : : private:
460 : : ImpSvNumFor NumFor[4]; // Array for the 4 subformats
461 : : String sFormatstring; // The format code string
462 : : String sComment; // Comment, since number formatter version 6
463 : : double fLimit1; // Value for first condition
464 : : double fLimit2; // Value for second condition
465 : : ImpSvNumberformatScan& rScan; // Format code scanner
466 : : LocaleType maLocale; // Language/country of the format, numeral shape and calendar type from Excel.
467 : : SvNumberformatLimitOps eOp1; // Operator for first condition
468 : : SvNumberformatLimitOps eOp2; // Operator for second condition
469 : : sal_uInt16 nNewStandardDefined; // new builtin formats as of version 6
470 : : short eType; // Type of format
471 : : bool bStarFlag; // Take *n format as ESC n
472 : : bool bStandard; // If this is a default standard format
473 : : bool bIsUsed; // Flag as used for storing
474 : :
475 : : SVL_DLLPRIVATE sal_uInt16 ImpGetNumForStringElementCount( sal_uInt16 nNumFor ) const;
476 : :
477 : : SVL_DLLPRIVATE bool ImpIsOtherCalendar( const ImpSvNumFor& rNumFor ) const;
478 : :
479 : : #ifdef THE_FUTURE
480 : : SVL_DLLPRIVATE bool ImpSwitchToSpecifiedCalendar( String& rOrgCalendar,
481 : : double& fOrgDateTime, const ImpSvNumFor& rNumFor ) const;
482 : : #endif
483 : :
484 : : /** Whether to use possessive genitive case month name, or partitive case
485 : : month name, instead of nominative name (noun).
486 : :
487 : : @param io_nState
488 : : 0: execute check <br>
489 : : set to 1 if nominative case is returned, <br>
490 : : set to 2 if genitive case is returned, <br>
491 : : set to 3 if partitive case is returned <br>
492 : : 1: don't execute check, return nominative case <br>
493 : : 2: don't execute check, return genitive case <br>
494 : : 3: don't execute check, return partitive case <br>
495 : :
496 : : @param eCodeType
497 : : a NfKeywordIndex, must designate a month type code
498 : :
499 : : @returns one of com::sun::star::i18n::CalendarDisplayCode values
500 : : according to eCodeType and the check executed (or passed).
501 : : */
502 : : SVL_DLLPRIVATE sal_Int32 ImpUseMonthCase( int & io_nState, const ImpSvNumFor& rNumFor, NfKeywordIndex eCodeType ) const;
503 : :
504 : : /// Whether it's a (YY)YY-M(M)-D(D) format.
505 : : SVL_DLLPRIVATE bool ImpIsIso8601( const ImpSvNumFor& rNumFor );
506 : :
507 : : #ifdef _ZFORMAT_CXX // ----- private implementation methods -----
508 : :
509 : 45306 : const CharClass& rChrCls() const { return rScan.GetChrCls(); }
510 : 0 : const LocaleDataWrapper& rLoc() const { return rScan.GetLoc(); }
511 : 690 : CalendarWrapper& GetCal() const { return rScan.GetCal(); }
512 : 233961 : const SvNumberFormatter& GetFormatter() const { return *rScan.GetNumberformatter(); }
513 : :
514 : : // divide in substrings and color conditions
515 : : SVL_DLLPRIVATE short ImpNextSymbol( String& rString,
516 : : xub_StrLen& nPos,
517 : : String& sSymbol );
518 : :
519 : : // read string until ']' and strip blanks (after condition)
520 : : SVL_DLLPRIVATE static xub_StrLen ImpGetNumber( String& rString,
521 : : xub_StrLen& nPos,
522 : : String& sSymbol );
523 : :
524 : : /**
525 : : * Parse the content of '[$-xxx] or '[$-xxxxxxxx]' and extract the locale
526 : : * type from it. Given the string, start parsing at position specified by
527 : : * nPos, and store the end position with nPos when the parsing is
528 : : * complete. The nPos should point to the '$' before the parsing, and to
529 : : * the closing bracket after the parsing. When the content is [$-xxx],
530 : : * the xxx part represents the language type (aka LCID) in hex numerals.
531 : : * When the content is [$-xxxxxxxx] the last 4 digits represent the LCID
532 : : * (again in hex), the next 2 digits represent the calendar type, and the
533 : : * 2 highest digits (if exists) is the numeral shape.
534 : : *
535 : : * @reference
536 : : * http://office.microsoft.com/en-us/excel-help/creating-international-number-formats-HA001034635.aspx
537 : : *
538 : : * @param rString input string
539 : : * @param nPos position (see above).
540 : : *
541 : : * @return struct containing numeral shape, calendar type, and LCID that
542 : : * specifies language type. See i18npool/lang.h for a complete
543 : : * list of language types. These numbers also correspond with the
544 : : * numbers used by Microsoft Office.
545 : : */
546 : : SVL_DLLPRIVATE static LocaleType ImpGetLocaleType( const String& rString, xub_StrLen& nPos );
547 : :
548 : : /** Obtain calendar and numerals from a LocaleType that was parsed from a
549 : : LCID with ImpGetLocaleType().
550 : :
551 : : Inserts a NatNum modifier to rString at nPos if needed as determined
552 : : from the numeral code.
553 : :
554 : : @ATTENTION: may modify <member>maLocale</member> to make it follow
555 : : aTmpLocale, in which case also nLang is adapted.
556 : :
557 : : @returns a string with the calendar if one was determined from the
558 : : calendar code, else an empty string. The calendar string needs to be
559 : : inserted at a proper positon to rString after all bracketed prefixes.
560 : : */
561 : : SVL_DLLPRIVATE String ImpObtainCalendarAndNumerals( String & rString,
562 : : xub_StrLen & nPos, LanguageType & nLang, const LocaleType & aTmpLocale );
563 : :
564 : : // standard number output
565 : : SVL_DLLPRIVATE void ImpGetOutputStandard( double& fNumber, String& OutString );
566 : : SVL_DLLPRIVATE void ImpGetOutputStdToPrecision( double& rNumber, String& rOutString, sal_uInt16 nPrecision ) const;
567 : : // numbers in input line
568 : : SVL_DLLPRIVATE void ImpGetOutputInputLine( double fNumber, String& OutString );
569 : :
570 : : // check subcondition
571 : : // OP undefined => -1
572 : : // else 0 or 1
573 : : SVL_DLLPRIVATE short ImpCheckCondition(double& fNumber,
574 : : double& fLimit,
575 : : SvNumberformatLimitOps eOp);
576 : :
577 : : SVL_DLLPRIVATE sal_uLong ImpGGT(sal_uLong x, sal_uLong y);
578 : : SVL_DLLPRIVATE sal_uLong ImpGGTRound(sal_uLong x, sal_uLong y);
579 : :
580 : : // Helper function for number strings
581 : : // append string symbols, insert leading 0 or ' ', or ...
582 : : SVL_DLLPRIVATE bool ImpNumberFill( String& sStr,
583 : : double& rNumber,
584 : : xub_StrLen& k,
585 : : sal_uInt16& j,
586 : : sal_uInt16 nIx,
587 : : short eSymbolType );
588 : :
589 : : // Helper function to fill in the integer part and the group (AKA thousand) separators
590 : : SVL_DLLPRIVATE bool ImpNumberFillWithThousands( String& sStr,
591 : : double& rNumber,
592 : : xub_StrLen k,
593 : : sal_uInt16 j,
594 : : sal_uInt16 nIx,
595 : : sal_uInt16 nDigCnt );
596 : : // Hilfsfunktion zum Auffuellen der Vor-
597 : : // kommazahl auch mit Tausenderpunkt
598 : :
599 : : // Helper function to fill in the group (AKA thousand) separators
600 : : // or to skip additional digits
601 : : SVL_DLLPRIVATE void ImpDigitFill( String& sStr,
602 : : xub_StrLen nStart,
603 : : xub_StrLen& k,
604 : : sal_uInt16 nIx,
605 : : xub_StrLen & nDigitCount,
606 : : utl::DigitGroupingIterator & );
607 : :
608 : : SVL_DLLPRIVATE bool ImpGetDateOutput( double fNumber,
609 : : sal_uInt16 nIx,
610 : : String& OutString );
611 : : SVL_DLLPRIVATE bool ImpGetTimeOutput( double fNumber,
612 : : sal_uInt16 nIx,
613 : : String& OutString );
614 : : SVL_DLLPRIVATE bool ImpGetDateTimeOutput( double fNumber,
615 : : sal_uInt16 nIx,
616 : : String& OutString );
617 : :
618 : : // Switches to the "gregorian" calendar if the current calendar is
619 : : // non-"gregorian" and the era is a "Dummy" era of a calendar which doesn't
620 : : // know a "before" era (like zh_TW ROC or ja_JP Gengou). If switched and
621 : : // rOrgCalendar was "gregorian" the string is emptied. If rOrgCalendar was
622 : : // empty the previous calendar name and date/time are returned.
623 : : SVL_DLLPRIVATE bool ImpFallBackToGregorianCalendar( String& rOrgCalendar, double& fOrgDateTime );
624 : :
625 : : // Append a "G" short era string of the given calendar. In the case of a
626 : : // Gengou calendar this is a one character abbreviation, for other
627 : : // calendars the XExtendedCalendar::getDisplayString() method is called.
628 : : SVL_DLLPRIVATE static void ImpAppendEraG( String& OutString, const CalendarWrapper& rCal,
629 : : sal_Int16 nNatNum );
630 : :
631 : : SVL_DLLPRIVATE bool ImpGetNumberOutput( double fNumber,
632 : : sal_uInt16 nIx,
633 : : String& OutString );
634 : :
635 : : SVL_DLLPRIVATE void ImpCopyNumberformat( const SvNumberformat& rFormat );
636 : :
637 : : // normal digits or other digits, depending on ImpSvNumFor.aNatNum,
638 : : // [NatNum1], [NatNum2], ...
639 : : SVL_DLLPRIVATE String ImpGetNatNumString( const SvNumberNatNum& rNum, sal_Int32 nVal,
640 : : sal_uInt16 nMinDigits = 0 ) const;
641 : :
642 : 72 : String ImpIntToString( sal_uInt16 nIx, sal_Int32 nVal, sal_uInt16 nMinDigits = 0 ) const
643 : : {
644 : 72 : const SvNumberNatNum& rNum = NumFor[nIx].GetNatNum();
645 [ - + ][ + + ]: 72 : if ( nMinDigits || rNum.IsComplete() )
[ + + ]
646 : 48 : return ImpGetNatNumString( rNum, nVal, nMinDigits );
647 [ + - ]: 72 : return rtl::OUString::valueOf(nVal);
648 : : }
649 : :
650 : : // transliterate according to NativeNumber
651 : : SVL_DLLPRIVATE void ImpTransliterateImpl( String& rStr, const SvNumberNatNum& rNum ) const;
652 : :
653 : 64981 : void ImpTransliterate( String& rStr, const SvNumberNatNum& rNum ) const
654 : : {
655 [ - + ]: 64981 : if ( rNum.IsComplete() )
656 : 0 : ImpTransliterateImpl( rStr, rNum );
657 : 64981 : }
658 : :
659 : : #endif // _ZFORMAT_CXX
660 : :
661 : : };
662 : :
663 : : #endif // _ZFORMAT_HXX
664 : :
665 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|