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