tdf#145248 don't start a drag if actively selecting
[LibreOffice.git] / include / svl / zformat.hxx
blobcd04f96ac8a1538081970e905e70e1fedaef353b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #ifndef 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>
25 #include <vector>
27 namespace utl {
28 class DigitGroupingIterator;
31 namespace com::sun::star::i18n { struct NativeNumberXmlAttributes2; }
33 class Color;
35 class ImpSvNumberformatScan; // format code string scanner
36 class ImpSvNumberInputScan; // input string scanner
37 class SvNumberFormatter;
39 enum SvNumberformatLimitOps
41 NUMBERFORMAT_OP_NO = 0, // Undefined, no OP
42 NUMBERFORMAT_OP_EQ = 1, // Operator =
43 NUMBERFORMAT_OP_NE = 2, // Operator <>
44 NUMBERFORMAT_OP_LT = 3, // Operator <
45 NUMBERFORMAT_OP_LE = 4, // Operator <=
46 NUMBERFORMAT_OP_GT = 5, // Operator >
47 NUMBERFORMAT_OP_GE = 6 // Operator >=
50 struct ImpSvNumberformatInfo // Struct for FormatInfo
52 std::vector<OUString> sStrArray; // Array of symbols
53 std::vector<short> nTypeArray; // Array of infos
54 sal_uInt16 nThousand; // Count of group separator sequences
55 sal_uInt16 nCntPre; // Count of digits before decimal point
56 sal_uInt16 nCntPost; // Count of digits after decimal point
57 sal_uInt16 nCntExp; // Count of exponent digits, or AM/PM
58 SvNumFormatType eScannedType; // Type determined by scan
59 bool bThousand; // Has group (AKA thousand) separator
61 void Copy( const ImpSvNumberformatInfo& rNumFor, sal_uInt16 nCount );
64 // NativeNumber, represent numbers using CJK or other digits if nNum>0,
65 // eLang specifies the Locale to use.
66 class SvNumberNatNum
68 OUString sParams; // For [NatNum12 ordinal-number]-like syntax
69 LanguageType eLang;
70 sal_uInt8 nNum;
71 bool bDBNum :1; // DBNum, to be converted to NatNum
72 bool bDate :1; // Used in date? (needed for DBNum/NatNum mapping)
73 bool bSet :1; // If set, since NatNum0 is possible
75 public:
77 static sal_uInt8 MapDBNumToNatNum( sal_uInt8 nDBNum, LanguageType eLang, bool bDate );
78 static sal_uInt8 MapNatNumToDBNum( sal_uInt8 nNatNum, LanguageType eLang, bool bDate );
80 SvNumberNatNum() : eLang( LANGUAGE_DONTKNOW ), nNum(0),
81 bDBNum(false), bDate(false), bSet(false) {}
82 bool IsComplete() const { return bSet && eLang != LANGUAGE_DONTKNOW; }
83 sal_uInt8 GetNatNum() const { return bDBNum ? MapDBNumToNatNum( nNum, eLang, bDate ) : nNum; }
84 sal_uInt8 GetDBNum() const { return bDBNum ? nNum : MapNatNumToDBNum( nNum, eLang, bDate ); }
85 LanguageType GetLang() const { return eLang; }
86 void SetLang( LanguageType e ) { eLang = e; }
87 void SetNum( sal_uInt8 nNumber, bool bDBNumber )
89 nNum = nNumber;
90 bDBNum = bDBNumber;
91 bSet = true;
93 bool IsSet() const { return bSet; }
94 void SetDate( bool bDateP ) { bDate = bDateP; }
95 void SetParams(const OUString& s) { sParams = s; }
96 OUString const & GetParams() const { return sParams; }
99 class CharClass;
101 class ImpSvNumFor // One of four subformats of the format code string
103 public:
104 ImpSvNumFor(); // Ctor without filling the Info
105 ~ImpSvNumFor();
107 void Enlarge(sal_uInt16 nCount); // Init of arrays to the right size
109 // if pSc is set, it is used to get the Color pointer
110 void Copy( const ImpSvNumFor& rNumFor, const ImpSvNumberformatScan* pSc );
112 // Access to Info; call Enlarge before!
113 ImpSvNumberformatInfo& Info() { return aI;}
114 const ImpSvNumberformatInfo& Info() const { return aI; }
116 // Get count of substrings (symbols)
117 sal_uInt16 GetCount() const { return nStringsCnt;}
119 const Color* GetColor() const { return pColor; }
120 void SetColor(const Color* pCol, OUString const& rName)
121 { pColor = pCol; sColorName = rName; }
122 const OUString& GetColorName() const { return sColorName; }
124 // new SYMBOLTYPE_CURRENCY in subformat?
125 bool HasNewCurrency() const;
126 bool GetNewCurrencySymbol( OUString& rSymbol, OUString& rExtension ) const;
128 // [NatNum1], [NatNum2], ...
129 void SetNatNumNum( sal_uInt8 nNum, bool bDBNum ) { aNatNum.SetNum( nNum, bDBNum ); }
130 void SetNatNumLang( LanguageType eLang ) { aNatNum.SetLang( eLang ); }
131 void SetNatNumDate( bool bDate ) { aNatNum.SetDate( bDate ); }
132 void SetNatNumParams(const OUString& sParams) { aNatNum.SetParams(sParams); }
133 const SvNumberNatNum& GetNatNum() const { return aNatNum; }
135 private:
136 ImpSvNumberformatInfo aI; // helper struct for remaining information
137 OUString sColorName; // color name
138 const Color* pColor; // pointer to color of subformat
139 sal_uInt16 nStringsCnt; // count of symbols
140 SvNumberNatNum aNatNum; // DoubleByteNumber
144 class SVL_DLLPUBLIC SvNumberformat
146 struct SAL_DLLPRIVATE LocaleType
148 enum class Substitute : sal_uInt8
150 NONE,
151 TIME,
152 LONGDATE
155 LanguageType meLanguage;
156 LanguageType meLanguageWithoutLocaleData;
157 Substitute meSubstitute;
158 sal_uInt8 mnNumeralShape;
159 sal_uInt8 mnCalendarType;
161 OUString generateCode() const;
163 LocaleType();
164 LocaleType(sal_uInt32 nRawCode);
166 bool isPlainLocale() const;
169 public:
170 // Normal ctor
171 SvNumberformat( OUString& rString,
172 ImpSvNumberformatScan* pSc,
173 ImpSvNumberInputScan* pISc,
174 sal_Int32& nCheckPos,
175 LanguageType& eLan,
176 bool bReplaceBooleanEquivalent = true );
178 // Copy ctor
179 SvNumberformat( SvNumberformat const & rFormat );
181 // Copy ctor with exchange of format code string scanner (used in merge)
182 SvNumberformat( SvNumberformat const & rFormat, ImpSvNumberformatScan& rSc );
184 ~SvNumberformat();
186 /// Get type of format, may include css::util::NumberFormat::DEFINED bit
187 SvNumFormatType GetType() const { return eType; }
189 /// Get type of format, does not include css::util::NumberFormat::DEFINED
190 SvNumFormatType GetMaskedType() const { return eType & ~SvNumFormatType::DEFINED; }
192 void SetType(SvNumFormatType eSetType) { eType = eSetType; }
193 // Standard means the I18N defined standard format of this type
194 void SetStandard() { bStandard = true; }
195 bool IsStandard() const { return bStandard; }
197 // If this format is an additional built-in format defined by i18n.
198 void SetAdditionalBuiltin() { bAdditionalBuiltin = true; }
199 bool IsAdditionalBuiltin() const { return bAdditionalBuiltin; }
201 LanguageType GetLanguage() const { return maLocale.meLanguage;}
203 /** If the format is a placeholder and needs to be substituted. */
204 bool IsSubstituted() const
206 return maLocale.meSubstitute != LocaleType::Substitute::NONE;
209 /** If the format is a placeholder for the system time format and needs to
210 be substituted during formatting time.
212 bool IsSystemTimeFormat() const
214 return maLocale.meSubstitute == LocaleType::Substitute::TIME && maLocale.meLanguage == LANGUAGE_SYSTEM;
217 /** If the format is a placeholder for the system long date format and needs
218 to be substituted during formatting time.
220 bool IsSystemLongDateFormat() const
222 return maLocale.meSubstitute == LocaleType::Substitute::LONGDATE && maLocale.meLanguage == LANGUAGE_SYSTEM;
225 /** If the format is a MM:SS or [MM]:SS format, or MM:[SS] (sic!) or even
226 MM:SS.00 or [MM]:SS.00 or MM:[SS].00
228 bool IsMinuteSecondFormat() const;
230 const OUString& GetFormatstring() const { return sFormatstring; }
232 // Build a format string of application defined keywords
233 OUString GetMappedFormatstring( const NfKeywordTable& rKeywords,
234 const LocaleDataWrapper& rLoc,
235 LanguageType nOriginalLang = LANGUAGE_DONTKNOW,
236 bool bSystemLanguage = false ) const;
238 void SetStarFormatSupport( bool b ) { bStarFlag = b; }
241 * Get output string from a numeric value that fits the number of
242 * characters specified.
244 bool GetOutputString( double fNumber, sal_uInt16 nCharCount, OUString& rOutString ) const;
246 bool GetOutputString( double fNumber, OUString& OutString, const Color** ppColor );
247 void GetOutputString( std::u16string_view sString, OUString& OutString, const Color** ppColor );
249 // True if type text
250 bool IsTextFormat() const { return bool(eType & SvNumFormatType::TEXT); }
251 // True if 4th subformat present
252 bool HasTextFormat() const
254 return (NumFor[3].GetCount() > 0) ||
255 (NumFor[3].Info().eScannedType == SvNumFormatType::TEXT);
258 void GetFormatSpecialInfo(bool& bThousand,
259 bool& IsRed,
260 sal_uInt16& nPrecision,
261 sal_uInt16& nLeadingCnt) const;
263 /// Get index of subformat (0..3) according to conditions and fNumber value
264 sal_uInt16 GetSubformatIndex( double fNumber ) const;
266 /// Count of decimal precision
267 sal_uInt16 GetFormatPrecision( sal_uInt16 nIx = 0 ) const
268 { return NumFor[nIx].Info().nCntPost; }
270 /// Count of integer digits
271 sal_uInt16 GetFormatIntegerDigits( sal_uInt16 nIx = 0 ) const
272 { return NumFor[nIx].Info().nCntPre; }
274 /** Count of hidden integer digits with thousands divisor:
275 formats like "0," to show only thousands.
277 Works only with SvNumFormatType::NUMBER and SvNumFormatType::CURRENCY,
278 returns 0 otherwise.
280 Returns SvNumberFormatter::UNLIMITED_PRECISION for formats that contain
281 the General keyword.
283 sal_uInt16 GetThousandDivisorPrecision( sal_uInt16 nIx = 0 ) const;
285 //! Read/write access on a special sal_uInt16 component, may only be used on the
286 //! standard format 0, 10000, ... and only by the number formatter!
287 struct FormatterPrivateAccess { friend SvNumberFormatter; private: FormatterPrivateAccess() {} };
288 sal_uInt16 GetLastInsertKey( const FormatterPrivateAccess& ) const
289 { return NumFor[0].Info().nThousand; }
290 void SetLastInsertKey( sal_uInt16 nKey, const FormatterPrivateAccess& )
291 { NumFor[0].Info().nThousand = nKey; }
293 //! Only onLoad: convert from stored to current system language/country
294 void ConvertLanguage( SvNumberFormatter& rConverter,
295 LanguageType eConvertFrom, LanguageType eConvertTo );
297 // Substring of a subformat code nNumFor (0..3)
298 // nPos == 0xFFFF => last substring
299 // bString==true: first/last SYMBOLTYPE_STRING or SYMBOLTYPE_CURRENCY
300 const OUString* GetNumForString( sal_uInt16 nNumFor, sal_uInt16 nPos,
301 bool bString = false ) const;
303 // Subtype of a subformat code nNumFor (0..3)
304 // nPos == 0xFFFF => last substring
305 short GetNumForType( sal_uInt16 nNumFor, sal_uInt16 nPos ) const;
307 OUString GetPercentString( sal_uInt16 nNumFor = 0 ) const;
309 OUString GetDenominatorString( sal_uInt16 nNumFor ) const;
310 OUString GetNumeratorString( sal_uInt16 nNumFor ) const;
311 OUString GetIntegerFractionDelimiterString( sal_uInt16 nNumFor ) const;
312 /// Round fNumber to its fraction representation
313 double GetRoundFractionValue ( double fNumber ) const;
315 /// Create a format string for time with a new precision
316 OUString GetFormatStringForTimePrecision( int nPrecision ) const;
319 /** If the count of string elements (substrings, ignoring [modifiers] and
320 so on) in a subformat code nNumFor (0..3) is equal to the given number.
321 Used by ImpSvNumberInputScan::IsNumberFormatMain() to detect a matched
322 format. */
323 bool IsNumForStringElementCountEqual( sal_uInt16 nNumFor, sal_uInt16 nAllCount,
324 sal_uInt16 nNumCount ) const
326 if ( nNumFor < 4 )
328 // First try a simple approach. Note that this is called only
329 // if all MidStrings did match so far, to verify that all
330 // strings of the format were matched and not just the starting
331 // sequence, so we don't have to check if GetCount() includes
332 // [modifiers] or anything else if both counts are equal.
333 sal_uInt16 nCnt = NumFor[nNumFor].GetCount();
334 if ( nAllCount == nCnt )
335 return true;
336 if ( nAllCount < nCnt ) // check ignoring [modifiers] and so on
337 return ImpGetNumForStringElementCount( nNumFor ) ==
338 (nAllCount - nNumCount);
340 return false;
342 /** Get the count of numbers among string elements **/
343 sal_uInt16 GetNumForNumberElementCount( sal_uInt16 nNumFor ) const;
345 /** Get the scanned type of the specified subformat. */
346 SvNumFormatType GetNumForInfoScannedType( sal_uInt16 nNumFor ) const
348 return (nNumFor < 4) ? NumFor[nNumFor].Info().eScannedType : SvNumFormatType::UNDEFINED;
351 // Whether the second subformat code is really for negative numbers
352 // or another limit set.
353 bool IsSecondSubformatRealNegative() const
355 return fLimit1 == 0.0 && fLimit2 == 0.0 &&
356 ( (eOp1 == NUMBERFORMAT_OP_GE && eOp2 == NUMBERFORMAT_OP_NO) ||
357 (eOp1 == NUMBERFORMAT_OP_GT && eOp2 == NUMBERFORMAT_OP_LT) ||
358 (eOp1 == NUMBERFORMAT_OP_NO && eOp2 == NUMBERFORMAT_OP_NO) );
361 // Whether the first subformat code is really for negative numbers
362 // or another limit set.
363 bool IsFirstSubformatRealNegative() const
365 return fLimit1 == 0.0 && fLimit2 == 0.0 &&
366 ((eOp1 == NUMBERFORMAT_OP_LT &&
367 (eOp2 == NUMBERFORMAT_OP_GT || eOp2 == NUMBERFORMAT_OP_EQ ||
368 eOp2 == NUMBERFORMAT_OP_GE || eOp2 == NUMBERFORMAT_OP_NO)) ||
369 (eOp1 == NUMBERFORMAT_OP_LE &&
370 (eOp2 == NUMBERFORMAT_OP_NO || eOp2 == NUMBERFORMAT_OP_GT)));
373 // Whether the negative format is without a sign or not
374 bool IsNegativeWithoutSign() const;
376 bool IsNegativeInBracket() const;
378 bool HasPositiveBracketPlaceholder() const;
380 // Whether a new SYMBOLTYPE_CURRENCY is contained in the format
381 bool HasNewCurrency() const;
383 // strip [$-yyy] from all [$xxx-yyy] leaving only xxx's,
384 static OUString StripNewCurrencyDelimiters( const OUString& rStr );
386 // If a new SYMBOLTYPE_CURRENCY is contained if the format is of type
387 // css::util::NumberFormat::CURRENCY, and if so the symbol xxx and the extension nnn
388 // of [$xxx-nnn] are returned
389 bool GetNewCurrencySymbol( OUString& rSymbol, OUString& rExtension ) const;
391 static bool HasStringNegativeSign( const OUString& rStr );
394 Whether a character at position nPos is somewhere between two matching
395 cQuote or not.
396 If nPos points to a cQuote, a true is returned on an opening cQuote,
397 a false is returned on a closing cQuote.
398 A cQuote between quotes may be escaped by a cEscIn, a cQuote outside of
399 quotes may be escaped by a cEscOut.
400 The default '\0' results in no escapement possible.
401 Defaults are set right according to the "unlogic" of the Numberformatter
403 static bool IsInQuote( const OUString& rString, sal_Int32 nPos,
404 sal_Unicode cQuote = '"',
405 sal_Unicode cEscIn = '\0', sal_Unicode cEscOut = '\\' );
408 Return the position of a matching closing cQuote if the character at
409 position nPos is between two matching cQuote, otherwise return -1.
410 If nPos points to an opening cQuote the position of the matching
411 closing cQuote is returned.
412 If nPos points to a closing cQuote nPos is returned.
413 If nPos points into a part which starts with an opening cQuote but has
414 no closing cQuote, rString.Len() is returned.
415 Uses <method>IsInQuote</method> internally, so you don't have to call
416 that prior to a call of this method.
418 static sal_Int32 GetQuoteEnd( const OUString& rString, sal_Int32 nPos,
419 sal_Unicode cQuote = '"',
420 sal_Unicode cEscIn = '\0' );
422 void SetComment( const OUString& rStr )
423 { sComment = rStr; }
424 const OUString& GetComment() const { return sComment; }
426 /** Insert the number of blanks into the string that is needed to simulate
427 the width of character c for underscore formats */
428 static sal_Int32 InsertBlanks( OUString& r, sal_Int32 nPos, sal_Unicode c )
430 sal_Int32 result;
431 OUStringBuffer sBuff(r);
433 result = InsertBlanks(sBuff, nPos, c);
434 r = sBuff.makeStringAndClear();
436 return result;
439 /** Insert the number of blanks into the string that is needed to simulate
440 the width of character c for underscore formats */
441 static sal_Int32 InsertBlanks( OUStringBuffer& r, sal_Int32 nPos, sal_Unicode c );
443 /// One of YMD,DMY,MDY if date format
444 DateOrder GetDateOrder() const;
446 /** A coded value of the exact YMD combination used, if date format.
447 For example: YYYY-MM-DD => ('Y' << 16) | ('M' << 8) | 'D'
448 or: MM/YY => ('M' << 8) | 'Y' */
449 sal_uInt32 GetExactDateOrder() const;
451 // used in XML export
452 void GetConditions( SvNumberformatLimitOps& rOper1, double& rVal1,
453 SvNumberformatLimitOps& rOper2, double& rVal2 ) const;
454 const Color* GetColor( sal_uInt16 nNumFor ) const;
455 void GetNumForInfo( sal_uInt16 nNumFor, SvNumFormatType& rScannedType,
456 bool& bThousand, sal_uInt16& nPrecision, sal_uInt16& nLeadingCnt ) const;
458 // rAttr.Number not empty if NatNum attributes are to be stored
459 void GetNatNumXml(
460 css::i18n::NativeNumberXmlAttributes2& rAttr,
461 sal_uInt16 nNumFor ) const;
463 /** Switches to the first non-"gregorian" calendar, but only if the current
464 calendar is "gregorian"; original calendar name and date/time returned,
465 but only if calendar switched and rOrgCalendar was empty. */
466 void SwitchToOtherCalendar( OUString& rOrgCalendar, double& fOrgDateTime ) const;
468 /** Switches to the "gregorian" calendar, but only if the current calendar
469 is non-"gregorian" and rOrgCalendar is not empty. Thus a preceding
470 ImpSwitchToOtherCalendar() call should have been placed prior to
471 calling this method. */
472 void SwitchToGregorianCalendar( const OUString& rOrgCalendar, double fOrgDateTime ) const;
474 #ifdef THE_FUTURE
475 /** Switches to the first specified calendar, if any, in subformat nNumFor
476 (0..3). Original calendar name and date/time returned, but only if
477 calendar switched and rOrgCalendar was empty.
479 @return
480 <TRUE/> if a calendar was specified and switched to,
481 <FALSE/> else.
483 bool SwitchToSpecifiedCalendar( OUString& rOrgCalendar, double& fOrgDateTime,
484 sal_uInt16 nNumFor ) const
486 if ( nNumFor < 4 )
487 return ImpSwitchToSpecifiedCalendar( rOrgCalendar,
488 fOrgDateTime, NumFor[nNumFor] );
489 return false;
491 #endif
493 /// Whether it's a (YY)YY-M(M)-D(D) format.
494 bool IsIso8601( sal_uInt16 nNumFor ) const
496 if ( nNumFor < 4 )
497 return ImpIsIso8601( NumFor[nNumFor]);
498 return false;
501 private:
502 ImpSvNumFor NumFor[4]; // Array for the 4 subformats
503 OUString sFormatstring; // The format code string
504 OUString sComment; // Comment, since number formatter version 6
505 double fLimit1; // Value for first condition
506 double fLimit2; // Value for second condition
507 ImpSvNumberformatScan& rScan; // Format code scanner
508 LocaleType maLocale; // Language/country of the format, numeral shape and calendar type from Excel.
509 SvNumberformatLimitOps eOp1; // Operator for first condition
510 SvNumberformatLimitOps eOp2; // Operator for second condition
511 SvNumFormatType eType; // Type of format
512 bool bAdditionalBuiltin; // If this is an additional built-in format defined by i18n
513 bool bStarFlag; // Take *n format as ESC n
514 bool bStandard; // If this is a default standard format
515 bool bIsUsed; // Flag as used for storing
517 SVL_DLLPRIVATE sal_uInt16 ImpGetNumForStringElementCount( sal_uInt16 nNumFor ) const;
519 SVL_DLLPRIVATE bool ImpIsOtherCalendar( const ImpSvNumFor& rNumFor ) const;
521 #ifdef THE_FUTURE
522 SVL_DLLPRIVATE bool ImpSwitchToSpecifiedCalendar( OUString& rOrgCalendar,
523 double& fOrgDateTime,
524 const ImpSvNumFor& rNumFor ) const;
525 #endif
527 /** Whether to use possessive genitive case month name, or partitive case
528 month name, instead of nominative name (noun).
530 @param io_nState
531 0: execute check <br>
532 set to 1 if nominative case is returned, <br>
533 set to 2 if genitive case is returned, <br>
534 set to 3 if partitive case is returned <br>
535 1: don't execute check, return nominative case <br>
536 2: don't execute check, return genitive case <br>
537 3: don't execute check, return partitive case <br>
539 @param eCodeType
540 a NfKeywordIndex, must designate a month type code
542 @returns one of css::i18n::CalendarDisplayCode values
543 according to eCodeType and the check executed (or passed).
545 SVL_DLLPRIVATE static sal_Int32 ImpUseMonthCase( int & io_nState, const ImpSvNumFor& rNumFor, NfKeywordIndex eCodeType );
547 /// Whether it's a (YY)YY-M(M)-D(D) format.
548 SVL_DLLPRIVATE bool ImpIsIso8601( const ImpSvNumFor& rNumFor ) const;
550 const CharClass& rChrCls() const;
551 const LocaleDataWrapper& rLoc() const;
552 CalendarWrapper& GetCal() const;
553 const SvNumberFormatter& GetFormatter() const;
555 // divide in substrings and color conditions
556 SVL_DLLPRIVATE short ImpNextSymbol( OUStringBuffer& rString,
557 sal_Int32& nPos,
558 OUString& sSymbol ) const;
560 // read string until ']' and strip blanks (after condition)
561 SVL_DLLPRIVATE static sal_Int32 ImpGetNumber( OUStringBuffer& rString,
562 sal_Int32& nPos,
563 OUString& sSymbol );
566 * Parse the content of '[$-xxx] or '[$-xxxxxxxx]' and extract the locale
567 * type from it. Given the string, start parsing at position specified by
568 * nPos, and store the end position with nPos when the parsing is
569 * complete. The nPos should point to the '$' before the parsing, and to
570 * the closing bracket after the parsing. When the content is [$-xxx],
571 * the xxx part represents the language type (aka LCID) in hex numerals.
572 * When the content is [$-xxxxxxxx] the last 4 digits represent the LCID
573 * (again in hex), the next 2 digits represent the calendar type, and the
574 * 2 highest digits (if exists) is the numeral shape.
576 * @reference
577 * http://office.microsoft.com/en-us/excel-help/creating-international-number-formats-HA001034635.aspx
579 * @param rString input string
580 * @param nPos position (see above).
582 * @return struct containing numeral shape, calendar type, and LCID that
583 * specifies language type. See i18nlangtag/lang.h for a complete
584 * list of language types. These numbers also correspond with the
585 * numbers used by Microsoft Office.
587 SVL_DLLPRIVATE static LocaleType ImpGetLocaleType( const OUString& rString, sal_Int32& nPos );
589 /** Obtain calendar and numerals from a LocaleType that was parsed from a
590 LCID with ImpGetLocaleType().
592 Inserts a NatNum modifier to rString at nPos if needed as determined
593 from the numeral code.
595 @ATTENTION: may modify <member>maLocale</member> to make it follow
596 aTmpLocale, in which case also nLang is adapted.
598 @returns a string with the calendar if one was determined from the
599 calendar code, else an empty string. The calendar string needs to be
600 inserted at a proper position to rString after all bracketed prefixes.
602 SVL_DLLPRIVATE OUString ImpObtainCalendarAndNumerals( OUStringBuffer & rString,
603 sal_Int32 nPos,
604 LanguageType & nLang,
605 const LocaleType & aTmpLocale );
607 // standard number output
608 SVL_DLLPRIVATE void ImpGetOutputStandard( double& fNumber, OUString& OutString ) const;
609 SVL_DLLPRIVATE void ImpGetOutputStandard( double& fNumber, OUStringBuffer& OutString ) const;
610 SVL_DLLPRIVATE void ImpGetOutputStdToPrecision( double& rNumber, OUString& rOutString, sal_uInt16 nPrecision ) const;
611 // numbers in input line
612 SVL_DLLPRIVATE void ImpGetOutputInputLine( double fNumber, OUString& OutString ) const;
614 // check subcondition
615 // OP undefined => -1
616 // else 0 or 1
617 SVL_DLLPRIVATE static short ImpCheckCondition(double fNumber,
618 double fLimit,
619 SvNumberformatLimitOps eOp);
621 // Helper function for number strings
622 // append string symbols, insert leading 0 or ' ', or ...
623 SVL_DLLPRIVATE bool ImpNumberFill( OUStringBuffer& sStr,
624 double& rNumber,
625 sal_Int32& k,
626 sal_uInt16& j,
627 sal_uInt16 nIx,
628 short eSymbolType,
629 bool bInsertRightBlank = false );
631 // Helper function to fill in the integer part and the group (AKA thousand) separators
632 SVL_DLLPRIVATE bool ImpNumberFillWithThousands( OUStringBuffer& sStr,
633 double& rNumber,
634 sal_Int32 k,
635 sal_uInt16 j,
636 sal_uInt16 nIx,
637 sal_Int32 nDigCnt,
638 bool bAddDecSep = true );
640 // Helper function to fill in the group (AKA thousand) separators
641 // or to skip additional digits
642 SVL_DLLPRIVATE void ImpDigitFill( OUStringBuffer& sStr,
643 sal_Int32 nStart,
644 sal_Int32& k,
645 sal_uInt16 nIx,
646 sal_Int32 & nDigitCount,
647 utl::DigitGroupingIterator & );
649 SVL_DLLPRIVATE bool ImpDecimalFill( OUStringBuffer& sStr,
650 double& rNumber,
651 sal_Int32 nDecPos,
652 sal_uInt16 j,
653 sal_uInt16 nIx,
654 bool bInteger );
656 /** Calculate each element of fraction:
657 * integer part, numerator part, denominator part
658 * @param fNumber value to be represented as fraction. Will contain absolute fractional part
659 * @param nIx subformat number 0..3
660 * @param fIntPart integral part of fraction
661 * @param nFrac numerator of fraction
662 * @param nDic denominator of fraction
664 SVL_DLLPRIVATE void ImpGetFractionElements( double& fNumber,
665 sal_uInt16 nIx,
666 double& fIntPart,
667 sal_Int64& nFrac,
668 sal_Int64& nDiv ) const;
669 SVL_DLLPRIVATE bool ImpGetFractionOutput(double fNumber,
670 sal_uInt16 nIx,
671 OUStringBuffer& OutString);
672 SVL_DLLPRIVATE bool ImpGetScientificOutput(double fNumber,
673 sal_uInt16 nIx,
674 OUStringBuffer& OutString);
676 SVL_DLLPRIVATE bool ImpGetDateOutput( double fNumber,
677 sal_uInt16 nIx,
678 OUStringBuffer& OutString );
679 SVL_DLLPRIVATE bool ImpGetTimeOutput( double fNumber,
680 sal_uInt16 nIx,
681 OUStringBuffer& OutString );
682 SVL_DLLPRIVATE bool ImpGetDateTimeOutput( double fNumber,
683 sal_uInt16 nIx,
684 OUStringBuffer& OutString );
686 // Switches to the "gregorian" calendar if the current calendar is
687 // non-"gregorian" and the era is a "Dummy" era of a calendar which doesn't
688 // know a "before" era (like zh_TW ROC or ja_JP Gengou). If switched and
689 // rOrgCalendar was "gregorian" the string is emptied. If rOrgCalendar was
690 // empty the previous calendar name and date/time are returned.
691 SVL_DLLPRIVATE bool ImpFallBackToGregorianCalendar( OUString& rOrgCalendar, double& fOrgDateTime );
693 // Append a "G" short era string of the given calendar. In the case of a
694 // Gengou calendar this is a one character abbreviation, for other
695 // calendars the XExtendedCalendar::getDisplayString() method is called.
696 SVL_DLLPRIVATE static void ImpAppendEraG( OUStringBuffer& OutStringBuffer, const CalendarWrapper& rCal,
697 sal_Int16 nNatNum );
699 SVL_DLLPRIVATE bool ImpGetNumberOutput( double fNumber,
700 sal_uInt16 nIx,
701 OUStringBuffer& OutString );
703 SVL_DLLPRIVATE void ImpCopyNumberformat( const SvNumberformat& rFormat );
705 // normal digits or other digits, depending on ImpSvNumFor.aNatNum,
706 // [NatNum1], [NatNum2], ...
707 SVL_DLLPRIVATE OUString ImpGetNatNumString( const SvNumberNatNum& rNum, sal_Int64 nVal,
708 sal_uInt16 nMinDigits ) const;
710 OUString ImpIntToString( sal_uInt16 nIx, sal_Int64 nVal, sal_uInt16 nMinDigits = 0 ) const
712 const SvNumberNatNum& rNum = NumFor[nIx].GetNatNum();
713 if ( nMinDigits || rNum.IsComplete() )
715 return ImpGetNatNumString( rNum, nVal, nMinDigits );
717 return OUString::number(nVal);
720 // Obtain the string of the fraction of second, without leading "0.",
721 // rounded to nFractionDecimals (or nFractionDecimals+1 if
722 // bAddOneRoundingDecimal==true but then truncated at nFractionDecimals,
723 // for use with the result of tools::Time::GetClock()) with the length of
724 // nFractionDecimals, unless nMinimumInputLineDecimals>0 is given for input
725 // line string where extra trailing "0" are discarded.
726 SVL_DLLPRIVATE sal_uInt16 ImpGetFractionOfSecondString( OUStringBuffer& rBuf, double fFractionOfSecond,
727 int nFractionDecimals, bool bAddOneRoundingDecimal, sal_uInt16 nIx, sal_uInt16 nMinimumInputLineDecimals );
729 // transliterate according to NativeNumber
730 SVL_DLLPRIVATE OUString impTransliterateImpl(const OUString& rStr, const SvNumberNatNum& rNum) const;
731 SVL_DLLPRIVATE void impTransliterateImpl(OUStringBuffer& rStr, const SvNumberNatNum& rNum) const;
732 SVL_DLLPRIVATE OUString impTransliterateImpl(const OUString& rStr, const SvNumberNatNum& rNum, sal_uInt16 nDateKey) const;
734 OUString impTransliterate(const OUString& rStr, const SvNumberNatNum& rNum) const
736 return rNum.IsComplete() ? impTransliterateImpl(rStr, rNum) : rStr;
739 SVL_DLLPRIVATE void impTransliterate(OUStringBuffer& rStr, const SvNumberNatNum& rNum) const
741 if(rNum.IsComplete())
743 impTransliterateImpl(rStr, rNum);
747 OUString impTransliterate(const OUString& rStr, const SvNumberNatNum& rNum, sal_uInt16 nDateKey) const
749 return rNum.IsComplete() ? impTransliterateImpl(rStr, rNum, nDateKey) : rStr;
754 #endif // INCLUDED_SVL_ZFORMAT_HXX
756 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */