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