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