1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 INCLUDED_SVL_ZFORMAT_HXX
20 #define INCLUDED_SVL_ZFORMAT_HXX
22 #include <svl/svldllapi.h>
23 #include <svl/zforlist.hxx>
24 #include <svl/nfkeytab.hxx>
28 class DigitGroupingIterator
;
31 namespace com::sun::star::i18n
{ struct NativeNumberXmlAttributes2
; }
35 class ImpSvNumberformatScan
; // format code string scanner
36 class ImpSvNumberInputScan
; // input string scanner
38 enum SvNumberformatLimitOps
40 NUMBERFORMAT_OP_NO
= 0, // Undefined, no OP
41 NUMBERFORMAT_OP_EQ
= 1, // Operator =
42 NUMBERFORMAT_OP_NE
= 2, // Operator <>
43 NUMBERFORMAT_OP_LT
= 3, // Operator <
44 NUMBERFORMAT_OP_LE
= 4, // Operator <=
45 NUMBERFORMAT_OP_GT
= 5, // Operator >
46 NUMBERFORMAT_OP_GE
= 6 // Operator >=
49 struct ImpSvNumberformatInfo
// Struct for FormatInfo
51 std::vector
<OUString
> sStrArray
; // Array of symbols
52 std::vector
<short> nTypeArray
; // Array of infos
53 sal_uInt16 nThousand
; // Count of group separator sequences
54 sal_uInt16 nCntPre
; // Count of digits before decimal point
55 sal_uInt16 nCntPost
; // Count of digits after decimal point
56 sal_uInt16 nCntExp
; // Count of exponent digits, or AM/PM
57 SvNumFormatType eScannedType
; // Type determined by scan
58 bool bThousand
; // Has group (AKA thousand) separator
60 void Copy( const ImpSvNumberformatInfo
& rNumFor
, sal_uInt16 nCount
);
63 // NativeNumber, represent numbers using CJK or other digits if nNum>0,
64 // eLang specifies the Locale to use.
67 OUString sParams
; // For [NatNum12 ordinal-number]-like syntax
70 bool bDBNum
:1; // DBNum, to be converted to NatNum
71 bool bDate
:1; // Used in date? (needed for DBNum/NatNum mapping)
72 bool bSet
:1; // If set, since NatNum0 is possible
76 static sal_uInt8
MapDBNumToNatNum( sal_uInt8 nDBNum
, LanguageType eLang
, bool bDate
);
77 static sal_uInt8
MapNatNumToDBNum( sal_uInt8 nNatNum
, LanguageType eLang
, bool bDate
);
79 SvNumberNatNum() : eLang( LANGUAGE_DONTKNOW
), nNum(0),
80 bDBNum(false), bDate(false), bSet(false) {}
81 bool IsComplete() const { return bSet
&& eLang
!= LANGUAGE_DONTKNOW
; }
82 sal_uInt8
GetNatNum() const { return bDBNum
? MapDBNumToNatNum( nNum
, eLang
, bDate
) : nNum
; }
83 sal_uInt8
GetDBNum() const { return bDBNum
? nNum
: MapNatNumToDBNum( nNum
, eLang
, bDate
); }
84 LanguageType
GetLang() const { return eLang
; }
85 void SetLang( LanguageType e
) { eLang
= e
; }
86 void SetNum( sal_uInt8 nNumber
, bool bDBNumber
)
92 bool IsSet() const { return bSet
; }
93 void SetDate( bool bDateP
) { bDate
= bDateP
; }
94 void SetParams(const OUString
& s
) { sParams
= s
; }
95 OUString
const & GetParams() const { return sParams
; }
100 class ImpSvNumFor
// One of four subformats of the format code string
103 ImpSvNumFor(); // Ctor without filling the Info
106 void Enlarge(sal_uInt16 nCount
); // Init of arrays to the right size
108 // if pSc is set, it is used to get the Color pointer
109 void Copy( const ImpSvNumFor
& rNumFor
, const ImpSvNumberformatScan
* pSc
);
111 // Access to Info; call Enlarge before!
112 ImpSvNumberformatInfo
& Info() { return aI
;}
113 const ImpSvNumberformatInfo
& Info() const { return aI
; }
115 // Get count of substrings (symbols)
116 sal_uInt16
GetCount() const { return nStringsCnt
;}
118 const Color
* GetColor() const { return pColor
; }
119 void SetColor(const Color
* pCol
, OUString
const& rName
)
120 { pColor
= pCol
; sColorName
= rName
; }
121 const OUString
& GetColorName() const { return sColorName
; }
123 // new SYMBOLTYPE_CURRENCY in subformat?
124 bool HasNewCurrency() const;
125 bool GetNewCurrencySymbol( OUString
& rSymbol
, OUString
& rExtension
) const;
127 // [NatNum1], [NatNum2], ...
128 void SetNatNumNum( sal_uInt8 nNum
, bool bDBNum
) { aNatNum
.SetNum( nNum
, bDBNum
); }
129 void SetNatNumLang( LanguageType eLang
) { aNatNum
.SetLang( eLang
); }
130 void SetNatNumDate( bool bDate
) { aNatNum
.SetDate( bDate
); }
131 void SetNatNumParams(const OUString
& sParams
) { aNatNum
.SetParams(sParams
); }
132 const SvNumberNatNum
& GetNatNum() const { return aNatNum
; }
135 ImpSvNumberformatInfo aI
; // helper struct for remaining information
136 OUString sColorName
; // color name
137 const Color
* pColor
; // pointer to color of subformat
138 sal_uInt16 nStringsCnt
; // count of symbols
139 SvNumberNatNum aNatNum
; // DoubleByteNumber
143 class SVL_DLLPUBLIC SvNumberformat
145 struct SAL_DLLPRIVATE LocaleType
147 enum class Substitute
: sal_uInt8
154 LanguageType meLanguage
;
155 LanguageType meLanguageWithoutLocaleData
;
156 Substitute meSubstitute
;
157 sal_uInt8 mnNumeralShape
;
158 sal_uInt8 mnCalendarType
;
160 OUString
generateCode() const;
163 LocaleType(sal_uInt32 nRawCode
);
165 bool isPlainLocale() const;
170 SvNumberformat( OUString
& rString
,
171 ImpSvNumberformatScan
* pSc
,
172 ImpSvNumberInputScan
* pISc
,
173 sal_Int32
& nCheckPos
,
174 LanguageType
& eLan
);
177 SvNumberformat( SvNumberformat
const & rFormat
);
179 // Copy ctor with exchange of format code string scanner (used in merge)
180 SvNumberformat( SvNumberformat
const & rFormat
, ImpSvNumberformatScan
& rSc
);
184 /// Get type of format, may include css::util::NumberFormat::DEFINED bit
185 SvNumFormatType
GetType() const { return eType
; }
187 /// Get type of format, does not include css::util::NumberFormat::DEFINED
188 SvNumFormatType
GetMaskedType() const { return eType
& ~SvNumFormatType::DEFINED
; }
190 void SetType(SvNumFormatType eSetType
) { eType
= eSetType
; }
191 // Standard means the I18N defined standard format of this type
192 void SetStandard() { bStandard
= true; }
193 bool IsStandard() const { return bStandard
; }
195 // If this format is an additional built-in format defined by i18n.
196 void SetAdditionalBuiltin() { bAdditionalBuiltin
= true; }
197 bool IsAdditionalBuiltin() const { return bAdditionalBuiltin
; }
199 LanguageType
GetLanguage() const { return maLocale
.meLanguage
;}
201 /** If the format is a placeholder and needs to be substituted. */
202 bool IsSubstituted() const
204 return maLocale
.meSubstitute
!= LocaleType::Substitute::NONE
;
207 /** If the format is a placeholder for the system time format and needs to
208 be substituted during formatting time.
210 bool IsSystemTimeFormat() const
212 return maLocale
.meSubstitute
== LocaleType::Substitute::TIME
&& maLocale
.meLanguage
== LANGUAGE_SYSTEM
;
215 /** If the format is a placeholder for the system long date format and needs
216 to be substituted during formatting time.
218 bool IsSystemLongDateFormat() const
220 return maLocale
.meSubstitute
== LocaleType::Substitute::LONGDATE
&& maLocale
.meLanguage
== LANGUAGE_SYSTEM
;
223 /** If the format is a MM:SS or [MM]:SS format, or MM:[SS] (sic!) or even
224 MM:SS.00 or [MM]:SS.00 or MM:[SS].00
226 bool IsMinuteSecondFormat() const;
228 const OUString
& GetFormatstring() const { return sFormatstring
; }
230 // Build a format string of application defined keywords
231 OUString
GetMappedFormatstring( const NfKeywordTable
& rKeywords
,
232 const LocaleDataWrapper
& rLoc
,
233 LanguageType nOriginalLang
= LANGUAGE_DONTKNOW
,
234 bool bSystemLanguage
= false ) const;
236 void SetStarFormatSupport( bool b
) { bStarFlag
= b
; }
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
, const Color
** ppColor
);
245 void GetOutputString( const OUString
& sString
, OUString
& OutString
, const Color
** ppColor
);
248 bool IsTextFormat() const { return bool(eType
& SvNumFormatType::TEXT
); }
249 // True if 4th subformat present
250 bool HasTextFormat() const
252 return (NumFor
[3].GetCount() > 0) ||
253 (NumFor
[3].Info().eScannedType
== SvNumFormatType::TEXT
);
256 void GetFormatSpecialInfo(bool& bThousand
,
258 sal_uInt16
& nPrecision
,
259 sal_uInt16
& nLeadingCnt
) const;
261 /// Get index of subformat (0..3) according to conditions and fNumber value
262 sal_uInt16
GetSubformatIndex( double fNumber
) const;
264 /// Count of decimal precision
265 sal_uInt16
GetFormatPrecision( sal_uInt16 nIx
= 0 ) const
266 { return NumFor
[nIx
].Info().nCntPost
; }
268 /// Count of integer digits
269 sal_uInt16
GetFormatIntegerDigits( sal_uInt16 nIx
= 0 ) const
270 { return NumFor
[nIx
].Info().nCntPre
; }
272 /** Count of hidden integer digits with thousands divisor:
273 * formats like "0," to show only thousands
275 sal_uInt16
GetThousandDivisorPrecision( sal_uInt16 nIx
= 0 ) const
276 { return NumFor
[nIx
].Info().nThousand
* 3; }
278 //! Read/write access on a special sal_uInt16 component, may only be used on the
279 //! standard format 0, 10000, ... and only by the number formatter!
280 struct FormatterPrivateAccess
{ friend SvNumberFormatter
; private: FormatterPrivateAccess() {} };
281 sal_uInt16
GetLastInsertKey( const FormatterPrivateAccess
& ) const
282 { return NumFor
[0].Info().nThousand
; }
283 void SetLastInsertKey( sal_uInt16 nKey
, const FormatterPrivateAccess
& )
284 { NumFor
[0].Info().nThousand
= nKey
; }
286 //! Only onLoad: convert from stored to current system language/country
287 void ConvertLanguage( SvNumberFormatter
& rConverter
,
288 LanguageType eConvertFrom
, LanguageType eConvertTo
);
290 // Substring of a subformat code nNumFor (0..3)
291 // nPos == 0xFFFF => last substring
292 // bString==true: first/last SYMBOLTYPE_STRING or SYMBOLTYPE_CURRENCY
293 const OUString
* GetNumForString( sal_uInt16 nNumFor
, sal_uInt16 nPos
,
294 bool bString
= false ) const;
296 // Subtype of a subformat code nNumFor (0..3)
297 // nPos == 0xFFFF => last substring
298 short GetNumForType( sal_uInt16 nNumFor
, sal_uInt16 nPos
) const;
300 OUString
GetPercentString( sal_uInt16 nNumFor
= 0 ) const;
302 OUString
GetDenominatorString( sal_uInt16 nNumFor
) const;
303 OUString
GetNumeratorString( sal_uInt16 nNumFor
) const;
304 OUString
GetIntegerFractionDelimiterString( sal_uInt16 nNumFor
) const;
305 /// Round fNumber to its fraction representation
306 double GetRoundFractionValue ( double fNumber
) const;
308 /// Create a format string for time with a new precision
309 OUString
GetFormatStringForTimePrecision( int nPrecision
) const;
312 /** If the count of string elements (substrings, ignoring [modifiers] and
313 so on) in a subformat code nNumFor (0..3) is equal to the given number.
314 Used by ImpSvNumberInputScan::IsNumberFormatMain() to detect a matched
316 bool IsNumForStringElementCountEqual( sal_uInt16 nNumFor
, sal_uInt16 nAllCount
,
317 sal_uInt16 nNumCount
) const
321 // First try a simple approach. Note that this is called only
322 // if all MidStrings did match so far, to verify that all
323 // strings of the format were matched and not just the starting
324 // sequence, so we don't have to check if GetCount() includes
325 // [modifiers] or anything else if both counts are equal.
326 sal_uInt16 nCnt
= NumFor
[nNumFor
].GetCount();
327 if ( nAllCount
== nCnt
)
329 if ( nAllCount
< nCnt
) // check ignoring [modifiers] and so on
330 return ImpGetNumForStringElementCount( nNumFor
) ==
331 (nAllCount
- nNumCount
);
335 /** Get the count of numbers among string elements **/
336 sal_uInt16
GetNumForNumberElementCount( sal_uInt16 nNumFor
) const;
338 /** Get the scanned type of the specified subformat. */
339 SvNumFormatType
GetNumForInfoScannedType( sal_uInt16 nNumFor
) const
341 return (nNumFor
< 4) ? NumFor
[nNumFor
].Info().eScannedType
: SvNumFormatType::UNDEFINED
;
344 // Whether the second subformat code is really for negative numbers
345 // or another limit set.
346 bool IsSecondSubformatRealNegative() const
348 return fLimit1
== 0.0 && fLimit2
== 0.0 &&
349 ( (eOp1
== NUMBERFORMAT_OP_GE
&& eOp2
== NUMBERFORMAT_OP_NO
) ||
350 (eOp1
== NUMBERFORMAT_OP_GT
&& eOp2
== NUMBERFORMAT_OP_LT
) ||
351 (eOp1
== NUMBERFORMAT_OP_NO
&& eOp2
== NUMBERFORMAT_OP_NO
) );
354 // Whether the first subformat code is really for negative numbers
355 // or another limit set.
356 bool IsFirstSubformatRealNegative() const
358 return fLimit1
== 0.0 && fLimit2
== 0.0 &&
359 ((eOp1
== NUMBERFORMAT_OP_LT
&&
360 (eOp2
== NUMBERFORMAT_OP_GT
|| eOp2
== NUMBERFORMAT_OP_EQ
||
361 eOp2
== NUMBERFORMAT_OP_GE
|| eOp2
== NUMBERFORMAT_OP_NO
)) ||
362 (eOp1
== NUMBERFORMAT_OP_LE
&&
363 (eOp2
== NUMBERFORMAT_OP_NO
|| eOp2
== NUMBERFORMAT_OP_GT
)));
366 // Whether the negative format is without a sign or not
367 bool IsNegativeWithoutSign() const;
369 bool IsNegativeInBracket() const;
371 bool HasPositiveBracketPlaceholder() const;
373 // Whether a new SYMBOLTYPE_CURRENCY is contained in the format
374 bool HasNewCurrency() const;
376 // strip [$-yyy] from all [$xxx-yyy] leaving only xxx's,
377 static OUString
StripNewCurrencyDelimiters( const OUString
& rStr
);
379 // If a new SYMBOLTYPE_CURRENCY is contained if the format is of type
380 // css::util::NumberFormat::CURRENCY, and if so the symbol xxx and the extension nnn
381 // of [$xxx-nnn] are returned
382 bool GetNewCurrencySymbol( OUString
& rSymbol
, OUString
& rExtension
) const;
384 static bool HasStringNegativeSign( const OUString
& rStr
);
387 Whether a character at position nPos is somewhere between two matching
389 If nPos points to a cQuote, a true is returned on an opening cQuote,
390 a false is returned on a closing cQuote.
391 A cQuote between quotes may be escaped by a cEscIn, a cQuote outside of
392 quotes may be escaped by a cEscOut.
393 The default '\0' results in no escapement possible.
394 Defaults are set right according to the "unlogic" of the Numberformatter
396 static bool IsInQuote( const OUString
& rString
, sal_Int32 nPos
,
397 sal_Unicode cQuote
= '"',
398 sal_Unicode cEscIn
= '\0', sal_Unicode cEscOut
= '\\' );
401 Return the position of a matching closing cQuote if the character at
402 position nPos is between two matching cQuote, otherwise return -1.
403 If nPos points to an opening cQuote the position of the matching
404 closing cQuote is returned.
405 If nPos points to a closing cQuote nPos is returned.
406 If nPos points into a part which starts with an opening cQuote but has
407 no closing cQuote, rString.Len() is returned.
408 Uses <method>IsInQuote</method> internally, so you don't have to call
409 that prior to a call of this method.
411 static sal_Int32
GetQuoteEnd( const OUString
& rString
, sal_Int32 nPos
,
412 sal_Unicode cQuote
= '"',
413 sal_Unicode cEscIn
= '\0' );
415 void SetComment( const OUString
& rStr
)
417 const OUString
& GetComment() const { return sComment
; }
419 /** Insert the number of blanks into the string that is needed to simulate
420 the width of character c for underscore formats */
421 static sal_Int32
InsertBlanks( OUString
& r
, sal_Int32 nPos
, sal_Unicode c
)
424 OUStringBuffer
sBuff(r
);
426 result
= InsertBlanks(sBuff
, nPos
, c
);
427 r
= sBuff
.makeStringAndClear();
432 /** Insert the number of blanks into the string that is needed to simulate
433 the width of character c for underscore formats */
434 static sal_Int32
InsertBlanks( OUStringBuffer
& r
, sal_Int32 nPos
, sal_Unicode c
);
436 /// One of YMD,DMY,MDY if date format
437 DateOrder
GetDateOrder() const;
439 /** A coded value of the exact YMD combination used, if date format.
440 For example: YYYY-MM-DD => ('Y' << 16) | ('M' << 8) | 'D'
441 or: MM/YY => ('M' << 8) | 'Y' */
442 sal_uInt32
GetExactDateOrder() const;
444 // used in XML export
445 void GetConditions( SvNumberformatLimitOps
& rOper1
, double& rVal1
,
446 SvNumberformatLimitOps
& rOper2
, double& rVal2
) const;
447 const Color
* GetColor( sal_uInt16 nNumFor
) const;
448 void GetNumForInfo( sal_uInt16 nNumFor
, SvNumFormatType
& rScannedType
,
449 bool& bThousand
, sal_uInt16
& nPrecision
, sal_uInt16
& nLeadingCnt
) const;
451 // rAttr.Number not empty if NatNum attributes are to be stored
453 css::i18n::NativeNumberXmlAttributes2
& rAttr
,
454 sal_uInt16 nNumFor
) const;
456 /** Switches to the first non-"gregorian" calendar, but only if the current
457 calendar is "gregorian"; original calendar name and date/time returned,
458 but only if calendar switched and rOrgCalendar was empty. */
459 void SwitchToOtherCalendar( OUString
& rOrgCalendar
, double& fOrgDateTime
) const;
461 /** Switches to the "gregorian" calendar, but only if the current calendar
462 is non-"gregorian" and rOrgCalendar is not empty. Thus a preceding
463 ImpSwitchToOtherCalendar() call should have been placed prior to
464 calling this method. */
465 void SwitchToGregorianCalendar( const OUString
& rOrgCalendar
, double fOrgDateTime
) const;
468 /** Switches to the first specified calendar, if any, in subformat nNumFor
469 (0..3). Original calendar name and date/time returned, but only if
470 calendar switched and rOrgCalendar was empty.
473 <TRUE/> if a calendar was specified and switched to,
476 bool SwitchToSpecifiedCalendar( OUString
& rOrgCalendar
, double& fOrgDateTime
,
477 sal_uInt16 nNumFor
) const
480 return ImpSwitchToSpecifiedCalendar( rOrgCalendar
,
481 fOrgDateTime
, NumFor
[nNumFor
] );
486 /// Whether it's a (YY)YY-M(M)-D(D) format.
487 bool IsIso8601( sal_uInt16 nNumFor
) const
490 return ImpIsIso8601( NumFor
[nNumFor
]);
495 ImpSvNumFor NumFor
[4]; // Array for the 4 subformats
496 OUString sFormatstring
; // The format code string
497 OUString sComment
; // Comment, since number formatter version 6
498 double fLimit1
; // Value for first condition
499 double fLimit2
; // Value for second condition
500 ImpSvNumberformatScan
& rScan
; // Format code scanner
501 LocaleType maLocale
; // Language/country of the format, numeral shape and calendar type from Excel.
502 SvNumberformatLimitOps eOp1
; // Operator for first condition
503 SvNumberformatLimitOps eOp2
; // Operator for second condition
504 SvNumFormatType eType
; // Type of format
505 bool bAdditionalBuiltin
; // If this is an additional built-in format defined by i18n
506 bool bStarFlag
; // Take *n format as ESC n
507 bool bStandard
; // If this is a default standard format
508 bool bIsUsed
; // Flag as used for storing
510 SVL_DLLPRIVATE sal_uInt16
ImpGetNumForStringElementCount( sal_uInt16 nNumFor
) const;
512 SVL_DLLPRIVATE
bool ImpIsOtherCalendar( const ImpSvNumFor
& rNumFor
) const;
515 SVL_DLLPRIVATE
bool ImpSwitchToSpecifiedCalendar( OUString
& rOrgCalendar
,
516 double& fOrgDateTime
,
517 const ImpSvNumFor
& rNumFor
) const;
520 /** Whether to use possessive genitive case month name, or partitive case
521 month name, instead of nominative name (noun).
524 0: execute check <br>
525 set to 1 if nominative case is returned, <br>
526 set to 2 if genitive case is returned, <br>
527 set to 3 if partitive case is returned <br>
528 1: don't execute check, return nominative case <br>
529 2: don't execute check, return genitive case <br>
530 3: don't execute check, return partitive case <br>
533 a NfKeywordIndex, must designate a month type code
535 @returns one of css::i18n::CalendarDisplayCode values
536 according to eCodeType and the check executed (or passed).
538 SVL_DLLPRIVATE
static sal_Int32
ImpUseMonthCase( int & io_nState
, const ImpSvNumFor
& rNumFor
, NfKeywordIndex eCodeType
);
540 /// Whether it's a (YY)YY-M(M)-D(D) format.
541 SVL_DLLPRIVATE
bool ImpIsIso8601( const ImpSvNumFor
& rNumFor
) const;
543 const CharClass
& rChrCls() const;
544 const LocaleDataWrapper
& rLoc() const;
545 CalendarWrapper
& GetCal() const;
546 const SvNumberFormatter
& GetFormatter() const;
548 // divide in substrings and color conditions
549 SVL_DLLPRIVATE
short ImpNextSymbol( OUStringBuffer
& rString
,
551 OUString
& sSymbol
) const;
553 // read string until ']' and strip blanks (after condition)
554 SVL_DLLPRIVATE
static sal_Int32
ImpGetNumber( OUStringBuffer
& rString
,
559 * Parse the content of '[$-xxx] or '[$-xxxxxxxx]' and extract the locale
560 * type from it. Given the string, start parsing at position specified by
561 * nPos, and store the end position with nPos when the parsing is
562 * complete. The nPos should point to the '$' before the parsing, and to
563 * the closing bracket after the parsing. When the content is [$-xxx],
564 * the xxx part represents the language type (aka LCID) in hex numerals.
565 * When the content is [$-xxxxxxxx] the last 4 digits represent the LCID
566 * (again in hex), the next 2 digits represent the calendar type, and the
567 * 2 highest digits (if exists) is the numeral shape.
570 * http://office.microsoft.com/en-us/excel-help/creating-international-number-formats-HA001034635.aspx
572 * @param rString input string
573 * @param nPos position (see above).
575 * @return struct containing numeral shape, calendar type, and LCID that
576 * specifies language type. See i18nlangtag/lang.h for a complete
577 * list of language types. These numbers also correspond with the
578 * numbers used by Microsoft Office.
580 SVL_DLLPRIVATE
static LocaleType
ImpGetLocaleType( const OUString
& rString
, sal_Int32
& nPos
);
582 /** Obtain calendar and numerals from a LocaleType that was parsed from a
583 LCID with ImpGetLocaleType().
585 Inserts a NatNum modifier to rString at nPos if needed as determined
586 from the numeral code.
588 @ATTENTION: may modify <member>maLocale</member> to make it follow
589 aTmpLocale, in which case also nLang is adapted.
591 @returns a string with the calendar if one was determined from the
592 calendar code, else an empty string. The calendar string needs to be
593 inserted at a proper position to rString after all bracketed prefixes.
595 SVL_DLLPRIVATE OUString
ImpObtainCalendarAndNumerals( OUStringBuffer
& rString
,
597 LanguageType
& nLang
,
598 const LocaleType
& aTmpLocale
);
600 // standard number output
601 SVL_DLLPRIVATE
void ImpGetOutputStandard( double& fNumber
, OUString
& OutString
) const;
602 SVL_DLLPRIVATE
void ImpGetOutputStandard( double& fNumber
, OUStringBuffer
& OutString
) const;
603 SVL_DLLPRIVATE
void ImpGetOutputStdToPrecision( double& rNumber
, OUString
& rOutString
, sal_uInt16 nPrecision
) const;
604 // numbers in input line
605 SVL_DLLPRIVATE
void ImpGetOutputInputLine( double fNumber
, OUString
& OutString
) const;
607 // check subcondition
608 // OP undefined => -1
610 SVL_DLLPRIVATE
static short ImpCheckCondition(double fNumber
,
612 SvNumberformatLimitOps eOp
);
614 // Helper function for number strings
615 // append string symbols, insert leading 0 or ' ', or ...
616 SVL_DLLPRIVATE
bool ImpNumberFill( OUStringBuffer
& sStr
,
622 bool bInsertRightBlank
= false );
624 // Helper function to fill in the integer part and the group (AKA thousand) separators
625 SVL_DLLPRIVATE
bool ImpNumberFillWithThousands( OUStringBuffer
& sStr
,
631 bool bAddDecSep
= true );
633 // Helper function to fill in the group (AKA thousand) separators
634 // or to skip additional digits
635 SVL_DLLPRIVATE
void ImpDigitFill( OUStringBuffer
& sStr
,
639 sal_Int32
& nDigitCount
,
640 utl::DigitGroupingIterator
& );
642 SVL_DLLPRIVATE
bool ImpDecimalFill( OUStringBuffer
& sStr
,
649 /** Calculate each element of fraction:
650 * integer part, numerator part, denominator part
651 * @param fNumber value to be represented as fraction. Will contain absolute fractional part
652 * @param nIx subformat number 0..3
653 * @param fIntPart integral part of fraction
654 * @param nFrac numerator of fraction
655 * @param nDic denominator of fraction
657 SVL_DLLPRIVATE
void ImpGetFractionElements( double& fNumber
,
661 sal_Int64
& nDiv
) const;
662 SVL_DLLPRIVATE
bool ImpGetFractionOutput(double fNumber
,
664 OUStringBuffer
& OutString
);
665 SVL_DLLPRIVATE
bool ImpGetScientificOutput(double fNumber
,
667 OUStringBuffer
& OutString
);
669 SVL_DLLPRIVATE
bool ImpGetDateOutput( double fNumber
,
671 OUStringBuffer
& OutString
);
672 SVL_DLLPRIVATE
bool ImpGetTimeOutput( double fNumber
,
674 OUStringBuffer
& OutString
);
675 SVL_DLLPRIVATE
bool ImpGetDateTimeOutput( double fNumber
,
677 OUStringBuffer
& OutString
);
679 // Switches to the "gregorian" calendar if the current calendar is
680 // non-"gregorian" and the era is a "Dummy" era of a calendar which doesn't
681 // know a "before" era (like zh_TW ROC or ja_JP Gengou). If switched and
682 // rOrgCalendar was "gregorian" the string is emptied. If rOrgCalendar was
683 // empty the previous calendar name and date/time are returned.
684 SVL_DLLPRIVATE
bool ImpFallBackToGregorianCalendar( OUString
& rOrgCalendar
, double& fOrgDateTime
);
686 // Append a "G" short era string of the given calendar. In the case of a
687 // Gengou calendar this is a one character abbreviation, for other
688 // calendars the XExtendedCalendar::getDisplayString() method is called.
689 SVL_DLLPRIVATE
static void ImpAppendEraG( OUStringBuffer
& OutStringBuffer
, const CalendarWrapper
& rCal
,
692 SVL_DLLPRIVATE
bool ImpGetNumberOutput( double fNumber
,
694 OUStringBuffer
& OutString
);
696 SVL_DLLPRIVATE
void ImpCopyNumberformat( const SvNumberformat
& rFormat
);
698 // normal digits or other digits, depending on ImpSvNumFor.aNatNum,
699 // [NatNum1], [NatNum2], ...
700 SVL_DLLPRIVATE OUString
ImpGetNatNumString( const SvNumberNatNum
& rNum
, sal_Int64 nVal
,
701 sal_uInt16 nMinDigits
) const;
703 OUString
ImpIntToString( sal_uInt16 nIx
, sal_Int64 nVal
, sal_uInt16 nMinDigits
= 0 ) const
705 const SvNumberNatNum
& rNum
= NumFor
[nIx
].GetNatNum();
706 if ( nMinDigits
|| rNum
.IsComplete() )
708 return ImpGetNatNumString( rNum
, nVal
, nMinDigits
);
710 return OUString::number(nVal
);
713 // Obtain the string of the fraction of second, without leading "0.",
714 // rounded to nFractionDecimals (or nFractionDecimals+1 if
715 // bAddOneRoundingDecimal==true but then truncated at nFractionDecimals,
716 // for use with the result of tools::Time::GetClock()) with the length of
717 // nFractionDecimals, unless nMinimumInputLineDecimals>0 is given for input
718 // line string where extra trailing "0" are discarded.
719 SVL_DLLPRIVATE sal_uInt16
ImpGetFractionOfSecondString( OUStringBuffer
& rBuf
, double fFractionOfSecond
,
720 int nFractionDecimals
, bool bAddOneRoundingDecimal
, sal_uInt16 nIx
, sal_uInt16 nMinimumInputLineDecimals
);
722 // transliterate according to NativeNumber
723 SVL_DLLPRIVATE OUString
impTransliterateImpl(const OUString
& rStr
, const SvNumberNatNum
& rNum
) const;
724 SVL_DLLPRIVATE
void impTransliterateImpl(OUStringBuffer
& rStr
, const SvNumberNatNum
& rNum
) const;
725 SVL_DLLPRIVATE OUString
impTransliterateImpl(const OUString
& rStr
, const SvNumberNatNum
& rNum
, sal_uInt16 nDateKey
) const;
727 OUString
impTransliterate(const OUString
& rStr
, const SvNumberNatNum
& rNum
) const
729 return rNum
.IsComplete() ? impTransliterateImpl(rStr
, rNum
) : rStr
;
732 SVL_DLLPRIVATE
void impTransliterate(OUStringBuffer
& rStr
, const SvNumberNatNum
& rNum
) const
734 if(rNum
.IsComplete())
736 impTransliterateImpl(rStr
, rNum
);
740 OUString
impTransliterate(const OUString
& rStr
, const SvNumberNatNum
& rNum
, sal_uInt16 nDateKey
) const
742 return rNum
.IsComplete() ? impTransliterateImpl(rStr
, rNum
, nDateKey
) : rStr
;
747 #endif // INCLUDED_SVL_ZFORMAT_HXX
749 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */