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 INCLUDED_SVL_ZFORMAT_HXX
20 : #define INCLUDED_SVL_ZFORMAT_HXX
21 :
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>
27 :
28 : namespace utl {
29 : class DigitGroupingIterator;
30 : }
31 :
32 : class SvStream;
33 : class Color;
34 :
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;
40 :
41 : enum SvNumberformatLimitOps
42 : {
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 >=
50 : };
51 :
52 : // SYSTEM-german to SYSTEM-xxx and vice versa conversion hack onLoad
53 : enum NfHackConversion
54 : {
55 : NF_CONVERT_NONE,
56 : NF_CONVERT_GERMAN_ENGLISH,
57 : NF_CONVERT_ENGLISH_GERMAN
58 : };
59 :
60 : struct ImpSvNumberformatInfo // Struct for FormatInfo
61 : {
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
70 :
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;
74 : };
75 :
76 : // NativeNumber, represent numbers using CJK or other digits if nNum>0,
77 : // eLang specifies the Locale to use.
78 : class SvNumberNatNum
79 : {
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
85 :
86 : public:
87 :
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
92 :
93 2295956 : SvNumberNatNum() : eLang( LANGUAGE_DONTKNOW ), nNum(0),
94 2295956 : bDBNum(false), bDate(false), bSet(false) {}
95 97151 : bool IsComplete() const { return bSet && eLang != LANGUAGE_DONTKNOW; }
96 : sal_uInt8 GetRawNum() const { return nNum; }
97 690907 : 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 426 : LanguageType GetLang() const { return eLang; }
102 234 : void SetLang( LanguageType e ) { eLang = e; }
103 210 : void SetNum( sal_uInt8 nNumber, bool bDBNumber )
104 : {
105 210 : nNum = nNumber;
106 210 : bDBNum = bDBNumber;
107 210 : bSet = true;
108 210 : }
109 1379682 : bool IsSet() const { return bSet; }
110 210 : void SetDate( bool bDateP ) { bDate = bDateP; }
111 : };
112 :
113 : class CharClass;
114 :
115 : class ImpSvNumFor // One of four subformats of the format code string
116 : {
117 : public:
118 : ImpSvNumFor(); // Ctor without filling the Info
119 : ~ImpSvNumFor();
120 :
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;
125 :
126 : // if pSc is set, it is used to get the Color pointer
127 : void Copy( const ImpSvNumFor& rNumFor, ImpSvNumberformatScan* pSc );
128 :
129 : // Access to Info; call Enlarge before!
130 1430375 : ImpSvNumberformatInfo& Info() { return aI;}
131 91071 : const ImpSvNumberformatInfo& Info() const { return aI; }
132 :
133 : // Get count of substrings (symbols)
134 697970 : sal_uInt16 GetCount() const { return nAnzStrings;}
135 :
136 61211 : Color* GetColor() const { return pColor; }
137 48928 : void SetColor( Color* pCol, OUString& rName )
138 48928 : { pColor = pCol; sColorName = rName; }
139 592 : const OUString& GetColorName() const { return sColorName; }
140 :
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 );
146 :
147 : // [NatNum1], [NatNum2], ...
148 210 : void SetNatNumNum( sal_uInt8 nNum, bool bDBNum ) { aNatNum.SetNum( nNum, bDBNum ); }
149 234 : void SetNatNumLang( LanguageType eLang ) { aNatNum.SetLang( eLang ); }
150 210 : void SetNatNumDate( bool bDate ) { aNatNum.SetDate( bDate ); }
151 2168162 : const SvNumberNatNum& GetNatNum() const { return aNatNum; }
152 :
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
159 :
160 : };
161 :
162 : class SVL_DLLPUBLIC SvNumberformat
163 : {
164 : struct LocaleType
165 : {
166 : sal_uInt8 mnNumeralShape;
167 : sal_uInt8 mnCalendarType;
168 : LanguageType meLanguage;
169 :
170 : OUString generateCode() const;
171 :
172 : LocaleType();
173 : LocaleType(sal_uInt32 nRawCode);
174 : };
175 :
176 : public:
177 : // Ctor for Load
178 : SvNumberformat( ImpSvNumberformatScan& rSc, LanguageType eLge );
179 :
180 : // Normal ctor
181 : SvNumberformat( OUString& rString,
182 : ImpSvNumberformatScan* pSc,
183 : ImpSvNumberInputScan* pISc,
184 : sal_Int32& nCheckPos,
185 : LanguageType& eLan,
186 : bool bStand = 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
197 227293 : short GetType() const
198 57831 : { return (nNewStandardDefined &&
199 57831 : (nNewStandardDefined <= SV_NUMBERFORMATTER_VERSION)) ?
200 285124 : (eType & ~NUMBERFORMAT_DEFINED) : eType; }
201 :
202 40433 : void SetType(const short eSetType) { eType = eSetType; }
203 : // Standard means the I18N defined standard format of this type
204 70416 : void SetStandard() { bStandard = true; }
205 9026 : 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_...
209 303922 : void SetNewStandardDefined( sal_uInt16 nVer )
210 303922 : { nNewStandardDefined = nVer; eType |= NUMBERFORMAT_DEFINED; }
211 :
212 0 : sal_uInt16 GetNewStandardDefined() const { return nNewStandardDefined; }
213 0 : bool IsAdditionalStandardDefined() const
214 0 : { return nNewStandardDefined == SV_NUMBERFORMATTER_VERSION_ADDITIONAL_I18N_FORMATS; }
215 :
216 11126301 : LanguageType GetLanguage() const { return maLocale.meLanguage;}
217 :
218 10796922 : const OUString& GetFormatstring() const { return sFormatstring; }
219 :
220 : // Build a format string of application defined keywords
221 : OUString GetMappedFormatstring( const NfKeywordTable& rKeywords,
222 : const LocaleDataWrapper& rLoc,
223 : bool bDontQuote = false ) const;
224 :
225 15648 : void SetUsed(const bool b) { bIsUsed = b; }
226 0 : bool GetUsed() const { return bIsUsed; }
227 : bool IsStarFormatSupported() const { return bStarFlag; }
228 20650 : void SetStarFormatSupport( 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 OUString LoadString( SvStream& rStream );
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, OUString& rOutString ) const;
243 :
244 : bool GetOutputString( double fNumber, OUString& OutString, Color** ppColor );
245 : bool GetOutputString( const OUString& sString, OUString& OutString, Color** ppColor );
246 :
247 : // True if type text
248 31810 : bool IsTextFormat() const { return (eType & NUMBERFORMAT_TEXT) != 0; }
249 : // True if 4th subformat present
250 30478 : bool HasTextFormat() const
251 : {
252 60896 : return (NumFor[3].GetCount() > 0) ||
253 60896 : (NumFor[3].Info().eScannedType == NUMBERFORMAT_TEXT);
254 : }
255 :
256 : void GetFormatSpecialInfo(bool& bThousand,
257 : bool& IsRed,
258 : sal_uInt16& nPrecision,
259 : sal_uInt16& nAnzLeading) const;
260 :
261 : /// Count of decimal precision
262 4 : 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!
266 16686 : sal_uInt16 GetLastInsertKey() const
267 16686 : { return NumFor[0].Info().nThousand; }
268 24510 : void SetLastInsertKey(sal_uInt16 nKey)
269 24510 : { 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, bool bSystem = false );
274 :
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;
280 :
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;
285 :
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 0 : bool IsNumForStringElementCountEqual( sal_uInt16 nNumFor, sal_uInt16 nAllCount,
292 : sal_uInt16 nNumCount ) const
293 : {
294 0 : if ( nNumFor < 4 )
295 : {
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 0 : sal_uInt16 nCnt = NumFor[nNumFor].GetCount();
302 0 : if ( nAllCount == nCnt )
303 0 : return true;
304 0 : if ( nAllCount < nCnt ) // check ignoring [modifiers] and so on
305 0 : return ImpGetNumForStringElementCount( nNumFor ) ==
306 0 : (nAllCount - nNumCount);
307 : }
308 0 : return false;
309 : }
310 :
311 : // Whether the second subformat code is really for negative numbers
312 : // or another limit set.
313 190 : bool IsSecondSubformatRealNegative() const
314 : {
315 570 : return fLimit1 == 0.0 && fLimit2 == 0.0 &&
316 380 : ( (eOp1 == NUMBERFORMAT_OP_GE && eOp2 == NUMBERFORMAT_OP_NO) ||
317 352 : (eOp1 == NUMBERFORMAT_OP_GT && eOp2 == NUMBERFORMAT_OP_LT) ||
318 542 : (eOp1 == NUMBERFORMAT_OP_NO && eOp2 == NUMBERFORMAT_OP_NO) );
319 : }
320 :
321 : // Whether the first subformat code is really for negative numbers
322 : // or another limit set.
323 1836 : bool IsFirstSubformatRealNegative() const
324 : {
325 3672 : return fLimit1 == 0.0 && fLimit2 == 0.0 &&
326 1836 : ((eOp1 == NUMBERFORMAT_OP_LT &&
327 0 : (eOp2 == NUMBERFORMAT_OP_GT || eOp2 == NUMBERFORMAT_OP_EQ ||
328 1836 : eOp2 == NUMBERFORMAT_OP_GE || eOp2 == NUMBERFORMAT_OP_NO)) ||
329 1836 : (eOp1 == NUMBERFORMAT_OP_LE &&
330 1836 : (eOp2 == NUMBERFORMAT_OP_NO || eOp2 == NUMBERFORMAT_OP_GT)));
331 : }
332 :
333 : // Whether the negative format is without a sign or not
334 : bool IsNegativeWithoutSign() const;
335 :
336 : bool IsNegativeInBracket() const;
337 :
338 : bool HasPositiveBracketPlaceholder() const;
339 :
340 : // Whether a new SYMBOLTYPE_CURRENCY is contained in the format
341 : bool HasNewCurrency() const;
342 :
343 : // Build string from NewCurrency for saving it SO50 compatible
344 : void Build50Formatstring( OUString& rStr ) const;
345 :
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 );
350 :
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;
355 :
356 : static bool HasStringNegativeSign( const OUString& rStr );
357 :
358 : /**
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
367 : */
368 : static bool IsInQuote( const OUString& rString, sal_Int32 nPos,
369 : sal_Unicode cQuote = '"',
370 : sal_Unicode cEscIn = '\0', sal_Unicode cEscOut = '\\' );
371 :
372 : /**
373 : Return the position of a matching closing cQuote if the character at
374 : position nPos is between two matching cQuote, otherwise return -1.
375 : If nPos points to an opening cQuote the position of the matching
376 : closing cQuote is returned.
377 : If nPos points to a closing cQuote nPos is returned.
378 : If nPos points into a part which starts with an opening cQuote but has
379 : no closing cQuote, rString.Len() is returned.
380 : Uses <method>IsInQuote</method> internally, so you don't have to call
381 : that prior to a call of this method.
382 : */
383 : static sal_Int32 GetQuoteEnd( const OUString& rString, sal_Int32 nPos,
384 : sal_Unicode cQuote = '"',
385 : sal_Unicode cEscIn = '\0',
386 : sal_Unicode cEscOut = '\\' );
387 :
388 7824 : void SetComment( const OUString& rStr )
389 7824 : { sComment = rStr; }
390 1536 : const OUString& GetComment() const { return sComment; }
391 :
392 : /** Insert the number of blanks into the string that is needed to simulate
393 : the width of character c for underscore formats */
394 194 : static sal_Int32 InsertBlanks( OUString& r, sal_Int32 nPos, sal_Unicode c )
395 : {
396 : sal_Int32 result;
397 194 : OUStringBuffer sBuff(r);
398 :
399 194 : result = InsertBlanks(sBuff, nPos, c);
400 194 : r = sBuff.makeStringAndClear();
401 :
402 194 : return result;
403 : }
404 :
405 : /** Insert the number of blanks into the string that is needed to simulate
406 : the width of character c for underscore formats */
407 : static sal_Int32 InsertBlanks( OUStringBuffer& r, sal_Int32 nPos, sal_Unicode c );
408 :
409 : /// One of YMD,DMY,MDY if date format
410 : DateFormat GetDateOrder() const;
411 :
412 : /** A coded value of the exact YMD combination used, if date format.
413 : For example: YYYY-MM-DD => ('Y' << 16) | ('M' << 8) | 'D'
414 : or: MM/YY => ('M' << 8) | 'Y' */
415 : sal_uInt32 GetExactDateOrder() const;
416 :
417 : ImpSvNumberformatScan& ImpGetScan() const { return rScan; }
418 :
419 : // used in XML export
420 : void GetConditions( SvNumberformatLimitOps& rOper1, double& rVal1,
421 : SvNumberformatLimitOps& rOper2, double& rVal2 ) const;
422 : Color* GetColor( sal_uInt16 nNumFor ) const;
423 : void GetNumForInfo( sal_uInt16 nNumFor, short& rScannedType,
424 : bool& bThousand, sal_uInt16& nPrecision, sal_uInt16& nAnzLeading ) const;
425 :
426 : // rAttr.Number not empty if NatNum attributes are to be stored
427 : void GetNatNumXml(
428 : ::com::sun::star::i18n::NativeNumberXmlAttributes& rAttr,
429 : sal_uInt16 nNumFor ) const;
430 :
431 : /** @returns <TRUE/> if E,EE,R,RR,AAA,AAAA in format code of subformat
432 : nNumFor (0..3) and <b>no</b> preceding calendar was specified and the
433 : currently loaded calendar is "gregorian". */
434 : bool IsOtherCalendar( sal_uInt16 nNumFor ) const
435 : {
436 : if ( nNumFor < 4 )
437 : return ImpIsOtherCalendar( NumFor[nNumFor] );
438 : return false;
439 : }
440 :
441 : /** Switches to the first non-"gregorian" calendar, but only if the current
442 : calendar is "gregorian"; original calendar name and date/time returned,
443 : but only if calendar switched and rOrgCalendar was empty. */
444 : void SwitchToOtherCalendar( OUString& rOrgCalendar, double& fOrgDateTime ) const;
445 :
446 : /** Switches to the "gregorian" calendar, but only if the current calendar
447 : is non-"gregorian" and rOrgCalendar is not empty. Thus a preceding
448 : ImpSwitchToOtherCalendar() call should have been placed prior to
449 : calling this method. */
450 : void SwitchToGregorianCalendar( const OUString& rOrgCalendar, double fOrgDateTime ) const;
451 :
452 : #ifdef THE_FUTURE
453 : /** Switches to the first specified calendar, if any, in subformat nNumFor
454 : (0..3). Original calendar name and date/time returned, but only if
455 : calendar switched and rOrgCalendar was empty.
456 :
457 : @return
458 : <TRUE/> if a calendar was specified and switched to,
459 : <FALSE/> else.
460 : */
461 : bool SwitchToSpecifiedCalendar( OUString& rOrgCalendar, double& fOrgDateTime,
462 : sal_uInt16 nNumFor ) const
463 : {
464 : if ( nNumFor < 4 )
465 : return ImpSwitchToSpecifiedCalendar( rOrgCalendar,
466 : fOrgDateTime, NumFor[nNumFor] );
467 : return false;
468 : }
469 : #endif
470 :
471 : /// Whether it's a (YY)YY-M(M)-D(D) format.
472 20 : bool IsIso8601( sal_uInt16 nNumFor )
473 : {
474 20 : if ( nNumFor < 4 )
475 20 : return ImpIsIso8601( NumFor[nNumFor]);
476 0 : return false;
477 : }
478 :
479 : private:
480 : ImpSvNumFor NumFor[4]; // Array for the 4 subformats
481 : OUString sFormatstring; // The format code string
482 : OUString sComment; // Comment, since number formatter version 6
483 : double fLimit1; // Value for first condition
484 : double fLimit2; // Value for second condition
485 : ImpSvNumberformatScan& rScan; // Format code scanner
486 : LocaleType maLocale; // Language/country of the format, numeral shape and calendar type from Excel.
487 : SvNumberformatLimitOps eOp1; // Operator for first condition
488 : SvNumberformatLimitOps eOp2; // Operator for second condition
489 : sal_uInt16 nNewStandardDefined; // new builtin formats as of version 6
490 : short eType; // Type of format
491 : bool bStarFlag; // Take *n format as ESC n
492 : bool bStandard; // If this is a default standard format
493 : bool bIsUsed; // Flag as used for storing
494 :
495 : SVL_DLLPRIVATE sal_uInt16 ImpGetNumForStringElementCount( sal_uInt16 nNumFor ) const;
496 :
497 : SVL_DLLPRIVATE bool ImpIsOtherCalendar( const ImpSvNumFor& rNumFor ) const;
498 :
499 : #ifdef THE_FUTURE
500 : SVL_DLLPRIVATE bool ImpSwitchToSpecifiedCalendar( OUString& rOrgCalendar,
501 : double& fOrgDateTime,
502 : const ImpSvNumFor& rNumFor ) const;
503 : #endif
504 :
505 : /** Whether to use possessive genitive case month name, or partitive case
506 : month name, instead of nominative name (noun).
507 :
508 : @param io_nState
509 : 0: execute check <br>
510 : set to 1 if nominative case is returned, <br>
511 : set to 2 if genitive case is returned, <br>
512 : set to 3 if partitive case is returned <br>
513 : 1: don't execute check, return nominative case <br>
514 : 2: don't execute check, return genitive case <br>
515 : 3: don't execute check, return partitive case <br>
516 :
517 : @param eCodeType
518 : a NfKeywordIndex, must designate a month type code
519 :
520 : @returns one of com::sun::star::i18n::CalendarDisplayCode values
521 : according to eCodeType and the check executed (or passed).
522 : */
523 : SVL_DLLPRIVATE sal_Int32 ImpUseMonthCase( int & io_nState, const ImpSvNumFor& rNumFor, NfKeywordIndex eCodeType ) const;
524 :
525 : /// Whether it's a (YY)YY-M(M)-D(D) format.
526 : SVL_DLLPRIVATE bool ImpIsIso8601( const ImpSvNumFor& rNumFor );
527 :
528 : const CharClass& rChrCls() const;
529 : const LocaleDataWrapper& rLoc() const;
530 : CalendarWrapper& GetCal() const;
531 : const SvNumberFormatter& GetFormatter() const;
532 :
533 : // divide in substrings and color conditions
534 : SVL_DLLPRIVATE short ImpNextSymbol( OUStringBuffer& rString,
535 : sal_Int32& nPos,
536 : OUString& sSymbol );
537 :
538 : // read string until ']' and strip blanks (after condition)
539 : SVL_DLLPRIVATE static sal_Int32 ImpGetNumber( OUStringBuffer& rString,
540 : sal_Int32& nPos,
541 : OUString& sSymbol );
542 :
543 : /**
544 : * Parse the content of '[$-xxx] or '[$-xxxxxxxx]' and extract the locale
545 : * type from it. Given the string, start parsing at position specified by
546 : * nPos, and store the end position with nPos when the parsing is
547 : * complete. The nPos should point to the '$' before the parsing, and to
548 : * the closing bracket after the parsing. When the content is [$-xxx],
549 : * the xxx part represents the language type (aka LCID) in hex numerals.
550 : * When the content is [$-xxxxxxxx] the last 4 digits represent the LCID
551 : * (again in hex), the next 2 digits represent the calendar type, and the
552 : * 2 highest digits (if exists) is the numeral shape.
553 : *
554 : * @reference
555 : * http://office.microsoft.com/en-us/excel-help/creating-international-number-formats-HA001034635.aspx
556 : *
557 : * @param rString input string
558 : * @param nPos position (see above).
559 : *
560 : * @return struct containing numeral shape, calendar type, and LCID that
561 : * specifies language type. See i18nlangtag/lang.h for a complete
562 : * list of language types. These numbers also correspond with the
563 : * numbers used by Microsoft Office.
564 : */
565 : SVL_DLLPRIVATE static LocaleType ImpGetLocaleType( const OUString& rString, sal_Int32& nPos );
566 :
567 : /** Obtain calendar and numerals from a LocaleType that was parsed from a
568 : LCID with ImpGetLocaleType().
569 :
570 : Inserts a NatNum modifier to rString at nPos if needed as determined
571 : from the numeral code.
572 :
573 : @ATTENTION: may modify <member>maLocale</member> to make it follow
574 : aTmpLocale, in which case also nLang is adapted.
575 :
576 : @returns a string with the calendar if one was determined from the
577 : calendar code, else an empty string. The calendar string needs to be
578 : inserted at a proper position to rString after all bracketed prefixes.
579 : */
580 : SVL_DLLPRIVATE OUString ImpObtainCalendarAndNumerals( OUStringBuffer & rString,
581 : sal_Int32 & nPos,
582 : LanguageType & nLang,
583 : const LocaleType & aTmpLocale );
584 :
585 : // standard number output
586 : SVL_DLLPRIVATE void ImpGetOutputStandard( double& fNumber, OUString& OutString );
587 : SVL_DLLPRIVATE void ImpGetOutputStandard( double& fNumber, OUStringBuffer& OutString );
588 : SVL_DLLPRIVATE void ImpGetOutputStdToPrecision( double& rNumber, OUString& rOutString, sal_uInt16 nPrecision ) const;
589 : // numbers in input line
590 : SVL_DLLPRIVATE void ImpGetOutputInputLine( double fNumber, OUString& OutString );
591 :
592 : // check subcondition
593 : // OP undefined => -1
594 : // else 0 or 1
595 : SVL_DLLPRIVATE short ImpCheckCondition(double& fNumber,
596 : double& fLimit,
597 : SvNumberformatLimitOps eOp);
598 :
599 : SVL_DLLPRIVATE sal_uLong ImpGGT(sal_uLong x, sal_uLong y);
600 : SVL_DLLPRIVATE sal_uLong ImpGGTRound(sal_uLong x, sal_uLong y);
601 :
602 : // Helper function for number strings
603 : // append string symbols, insert leading 0 or ' ', or ...
604 : SVL_DLLPRIVATE bool ImpNumberFill( OUStringBuffer& sStr,
605 : double& rNumber,
606 : sal_Int32& k,
607 : sal_uInt16& j,
608 : sal_uInt16 nIx,
609 : short eSymbolType );
610 :
611 : // Helper function to fill in the integer part and the group (AKA thousand) separators
612 : SVL_DLLPRIVATE bool ImpNumberFillWithThousands( OUStringBuffer& sStr,
613 : double& rNumber,
614 : sal_Int32 k,
615 : sal_uInt16 j,
616 : sal_uInt16 nIx,
617 : sal_Int32 nDigCnt );
618 : // Hilfsfunktion zum Auffuellen der Vor-
619 : // kommazahl auch mit Tausenderpunkt
620 :
621 : // Helper function to fill in the group (AKA thousand) separators
622 : // or to skip additional digits
623 : SVL_DLLPRIVATE void ImpDigitFill( OUStringBuffer& sStr,
624 : sal_Int32 nStart,
625 : sal_Int32& k,
626 : sal_uInt16 nIx,
627 : sal_Int32 & nDigitCount,
628 : utl::DigitGroupingIterator & );
629 :
630 : SVL_DLLPRIVATE bool ImpGetFractionOutput(double fNumber,
631 : sal_uInt16 nIx,
632 : OUStringBuffer& OutString);
633 : SVL_DLLPRIVATE bool ImpGetScientificOutput(double fNumber,
634 : sal_uInt16 nIx,
635 : OUStringBuffer& OutString);
636 :
637 : SVL_DLLPRIVATE bool ImpGetDateOutput( double fNumber,
638 : sal_uInt16 nIx,
639 : OUStringBuffer& OutString );
640 : SVL_DLLPRIVATE bool ImpGetTimeOutput( double fNumber,
641 : sal_uInt16 nIx,
642 : OUStringBuffer& OutString );
643 : SVL_DLLPRIVATE bool ImpGetDateTimeOutput( double fNumber,
644 : sal_uInt16 nIx,
645 : OUStringBuffer& OutString );
646 :
647 : // Switches to the "gregorian" calendar if the current calendar is
648 : // non-"gregorian" and the era is a "Dummy" era of a calendar which doesn't
649 : // know a "before" era (like zh_TW ROC or ja_JP Gengou). If switched and
650 : // rOrgCalendar was "gregorian" the string is emptied. If rOrgCalendar was
651 : // empty the previous calendar name and date/time are returned.
652 : SVL_DLLPRIVATE bool ImpFallBackToGregorianCalendar( OUString& rOrgCalendar, double& fOrgDateTime );
653 :
654 : // Append a "G" short era string of the given calendar. In the case of a
655 : // Gengou calendar this is a one character abbreviation, for other
656 : // calendars the XExtendedCalendar::getDisplayString() method is called.
657 : SVL_DLLPRIVATE static void ImpAppendEraG( OUStringBuffer& OutStringBuffer, const CalendarWrapper& rCal,
658 : sal_Int16 nNatNum );
659 :
660 : SVL_DLLPRIVATE bool ImpGetNumberOutput( double fNumber,
661 : sal_uInt16 nIx,
662 : OUStringBuffer& OutString );
663 :
664 : SVL_DLLPRIVATE void ImpCopyNumberformat( const SvNumberformat& rFormat );
665 :
666 : // normal digits or other digits, depending on ImpSvNumFor.aNatNum,
667 : // [NatNum1], [NatNum2], ...
668 : SVL_DLLPRIVATE OUString ImpGetNatNumString( const SvNumberNatNum& rNum, sal_Int32 nVal,
669 : sal_uInt16 nMinDigits = 0 ) const;
670 :
671 2132 : OUString ImpIntToString( sal_uInt16 nIx, sal_Int32 nVal, sal_uInt16 nMinDigits = 0 ) const
672 : {
673 2132 : const SvNumberNatNum& rNum = NumFor[nIx].GetNatNum();
674 2132 : if ( nMinDigits || rNum.IsComplete() )
675 : {
676 2078 : return ImpGetNatNumString( rNum, nVal, nMinDigits );
677 : }
678 54 : return OUString::number(nVal);
679 : }
680 :
681 : // transliterate according to NativeNumber
682 : SVL_DLLPRIVATE OUString impTransliterateImpl(const OUString& rStr, const SvNumberNatNum& rNum) const;
683 : SVL_DLLPRIVATE void impTransliterateImpl(OUStringBuffer& rStr, const SvNumberNatNum& rNum) const;
684 :
685 90139 : OUString impTransliterate(const OUString& rStr, const SvNumberNatNum& rNum) const
686 : {
687 90139 : return rNum.IsComplete() ? impTransliterateImpl(rStr, rNum) : rStr;
688 : }
689 :
690 6958 : SVL_DLLPRIVATE void impTransliterate(OUStringBuffer& rStr, const SvNumberNatNum& rNum) const
691 : {
692 6958 : if(rNum.IsComplete())
693 : {
694 2 : impTransliterateImpl(rStr, rNum);
695 : }
696 6958 : }
697 : };
698 :
699 : #endif // INCLUDED_SVL_ZFORMAT_HXX
700 :
701 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|