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_ZFORLIST_HXX
20 #define INCLUDED_SVL_ZFORLIST_HXX
22 #include <svl/svldllapi.h>
23 #include <rtl/ustrbuf.hxx>
24 #include <rtl/ustring.hxx>
25 #include <i18nlangtag/lang.h>
26 #include <com/sun/star/uno/Reference.hxx>
27 #include <com/sun/star/lang/Locale.hpp>
28 #include <com/sun/star/i18n/NumberFormatCode.hpp>
29 #include <com/sun/star/util/NumberFormat.hpp>
30 #include <unotools/localedatawrapper.hxx>
31 #include <unotools/numberformatcodewrapper.hxx>
32 #include <tools/link.hxx>
33 #include <svl/ondemand.hxx>
34 #include <svl/nfkeytab.hxx>
42 class CalendarWrapper
;
44 class ImpSvNumberformatScan
;
45 class ImpSvNumberInputScan
;
48 namespace com
{ namespace sun
{ namespace star
{
50 class XComponentContext
;
54 #define SV_COUNTRY_LANGUAGE_OFFSET 10000 // Max count of formats per country/language
55 #define SV_MAX_ANZ_STANDARD_FORMATE 100 // Max count of builtin default formats per CL
57 #define NUMBERFORMAT_ENTRY_NOT_FOUND (sal_uInt32)(0xffffffff) /// MAX_ULONG
60 /** enum values for <method>SvNumberFormatter::GetFormatIndex</method>
63 Builtin standard formats, order should be also the arrangement in the
64 dialog list box representation.</p>
68 <li>SYSTEM: As set in System Regional Settings.
69 <li>SYS: short/long defined, order and separators from System Regional Settings.
70 <li>DEF: short/long and order defined, separators from System Regional Settings.
71 <li>DIN: all settings hard coded as DIN (Deutsche Industrie Norm) and EN (European Norm) require.
72 <li>all other: hard coded
75 Do NOT insert any new values!
76 The values here correspond with those in offapi/com/sun/star/i18n/NumberFormatIndex.idl
77 You may append values though.
79 enum NfIndexTableOffset
83 NF_NUMBER_START
= NF_NUMERIC_START
,
84 NF_NUMBER_STANDARD
= NF_NUMBER_START
, // Standard/General
86 NF_NUMBER_DEC2
, // 0.00
87 NF_NUMBER_1000INT
, // #,##0
88 NF_NUMBER_1000DEC2
, // #,##0.00
89 NF_NUMBER_SYSTEM
, // #,##0.00 or whatever is set in System Regional Settings
90 NF_NUMBER_END
= NF_NUMBER_SYSTEM
,
93 NF_SCIENTIFIC_000E000
= NF_SCIENTIFIC_START
, // 0.00E+000
94 NF_SCIENTIFIC_000E00
, // 0.00E+00
95 NF_SCIENTIFIC_END
= NF_SCIENTIFIC_000E00
,
98 NF_PERCENT_INT
= NF_PERCENT_START
, // 0%
99 NF_PERCENT_DEC2
, // 0.00%
100 NF_PERCENT_END
= NF_PERCENT_DEC2
,
103 NF_FRACTION_1
= NF_FRACTION_START
, // # ?/?
104 NF_FRACTION_2
, // # ??/??
105 NF_FRACTION_END
= NF_FRACTION_2
,
107 NF_NUMERIC_END
= NF_FRACTION_END
,
110 NF_CURRENCY_1000INT
= NF_CURRENCY_START
,// #,##0 DM
111 NF_CURRENCY_1000DEC2
, // #,##0.00 DM
112 NF_CURRENCY_1000INT_RED
, // #,##0 DM negative in red
113 NF_CURRENCY_1000DEC2_RED
, // #,##0.00 DM negative in red
114 NF_CURRENCY_1000DEC2_CCC
, // #,##0.00 DEM currency abbreviation
115 NF_CURRENCY_1000DEC2_DASHED
, // #,##0.-- DM
116 NF_CURRENCY_END
= NF_CURRENCY_1000DEC2_DASHED
,
119 NF_DATE_SYSTEM_SHORT
= NF_DATE_START
, // 08.10.97
120 NF_DATE_SYSTEM_LONG
, // Wednesday, 8. October 1997
121 NF_DATE_SYS_DDMMYY
, // 08.10.97
122 NF_DATE_SYS_DDMMYYYY
, // 08.10.1997
123 NF_DATE_SYS_DMMMYY
, // 8. Oct 97
124 NF_DATE_SYS_DMMMYYYY
, // 8. Oct 1997
125 NF_DATE_DIN_DMMMYYYY
, // 8. Oct. 1997 DIN
126 NF_DATE_SYS_DMMMMYYYY
, // 8. October 1997
127 NF_DATE_DIN_DMMMMYYYY
, // 8. October 1997 DIN
128 NF_DATE_SYS_NNDMMMYY
, // Wed, 8. Okt 97
129 NF_DATE_DEF_NNDDMMMYY
, // Wed 08.Okt 97
130 NF_DATE_SYS_NNDMMMMYYYY
, // Wed, 8. Oktober 1997
131 NF_DATE_SYS_NNNNDMMMMYYYY
, // Wednesday, 8. Oktober 1997
132 NF_DATE_DIN_MMDD
, // 10-08 DIN
133 NF_DATE_DIN_YYMMDD
, // 97-10-08 DIN
134 NF_DATE_DIN_YYYYMMDD
, // 1997-10-08 DIN
135 NF_DATE_ISO_YYYYMMDD
= NF_DATE_DIN_YYYYMMDD
, // 1997-10-08 ISO clarify with name
136 NF_DATE_SYS_MMYY
, // 10.97
137 NF_DATE_SYS_DDMMM
, // 08.Oct
138 NF_DATE_MMMM
, // October
139 NF_DATE_QQJJ
, // 4. Quarter 97
140 NF_DATE_WW
, // week of year
141 NF_DATE_END
= NF_DATE_WW
,
144 NF_TIME_HHMM
= NF_TIME_START
, // HH:MM
145 NF_TIME_HHMMSS
, // HH:MM:SS
146 NF_TIME_HHMMAMPM
, // HH:MM AM/PM
147 NF_TIME_HHMMSSAMPM
, // HH:MM:SS AM/PM
148 NF_TIME_HH_MMSS
, // [HH]:MM:SS
149 NF_TIME_MMSS00
, // MM:SS,00
150 NF_TIME_HH_MMSS00
, // [HH]:MM:SS,00
151 NF_TIME_END
= NF_TIME_HH_MMSS00
,
154 NF_DATETIME_SYSTEM_SHORT_HHMM
= NF_DATETIME_START
, // 08.10.97 01:23
155 NF_DATETIME_SYS_DDMMYYYY_HHMMSS
, // 08.10.1997 01:23:45
156 NF_DATETIME_END
= NF_DATETIME_SYS_DDMMYYYY_HHMMSS
,
158 NF_BOOLEAN
, // BOOLEAN
161 NF_INDEX_TABLE_LOCALE_DATA_DEFAULTS
, // == 50, old number of predefined entries, i18npool locale data additions start after this
163 // From here on are values of new built-in formats that are not in the
164 // original NumberFormatIndex.idl
166 // XXX Values appended here must also get a corresponding entry in
167 // svl/source/numbers/zforlist.cxx indexTable[] in the same order.
169 // XXX The dialog's number format shell assumes start/end spans
170 // (NF_..._START and NF_..._END above) to fill its categories with builtin
171 // formats, make new formats known to svx/source/items/numfmtsh.cxx
172 // SvxNumberFormatShell::FillEListWithStd_Impl(), otherwise they will not
173 // be be listed at all. Yes that is ugly.
175 NF_FRACTION_3
= NF_INDEX_TABLE_LOCALE_DATA_DEFAULTS
, // # ?/4
176 NF_FRACTION_4
, // # ?/100
178 NF_DATETIME_ISO_YYYYMMDD_HHMMSS
, // 1997-10-08 01:23:45 ISO (with blank instead of T)
180 NF_INDEX_TABLE_ENTRIES
// == 53, reserved up to 59 to not use in i18npool locale data.
184 // #45717# IsNumberFormat( "98-10-24", 30, x ), YMD Format set with DMY
185 // International settings doesn't recognize the string as a date.
186 /** enum values for <method>SvNumberFormatter::SetEvalDateFormat</method>
188 <p>How <method>ImpSvNumberInputScan::GetDateRef</method> shall take the
189 DateFormat order (YMD,DMY,MDY) into account, if called from IsNumberFormat
190 with a date format to match against.
192 enum NfEvalDateFormat
194 /** DateFormat only from International, default. */
195 NF_EVALDATEFORMAT_INTL
,
197 /** DateFormat only from date format passed to function (if any).
198 If no date format is passed then the DateFormat is taken from International. */
199 NF_EVALDATEFORMAT_FORMAT
,
201 /** First try the DateFormat from International. If it doesn't match a
202 valid date try the DateFormat from the date format passed. */
203 NF_EVALDATEFORMAT_INTL_FORMAT
,
205 /** First try the DateFormat from the date format passed. If it doesn't
206 match a valid date try the DateFormat from International. */
207 NF_EVALDATEFORMAT_FORMAT_INTL
211 typedef std::map
<sal_uInt32
, SvNumberformat
*> SvNumberFormatTable
;
212 typedef std::map
<sal_uInt16
, sal_uInt32
> SvNumberFormatterIndexTable
;
214 typedef ::std::map
< sal_uInt32
, sal_uInt32
> SvNumberFormatterMergeMap
;
216 typedef ::std::set
< LanguageType
> NfInstalledLocales
;
219 /** Language/country dependent currency entries
221 class SVL_DLLPUBLIC NfCurrencyEntry
223 OUString aSymbol
; /// currency symbol
224 OUString aBankSymbol
; /// currency abbreviation
225 LanguageType eLanguage
; /// language/country value
226 sal_uInt16 nPositiveFormat
; /// position of symbol
227 sal_uInt16 nNegativeFormat
; /// position of symbol and type and position of negative sign
228 sal_uInt16 nDigits
; /// count of decimal digits
229 sal_Unicode cZeroChar
; /// which character is used for zeros as last decimal digits
231 NfCurrencyEntry( const NfCurrencyEntry
& ) = delete;
232 NfCurrencyEntry
& operator=( const NfCurrencyEntry
& ) = delete;
236 // nDecimalFormat := 0, 1, 2
237 // #,##0 or #,##0.00 or #,##0.-- is returned
238 SVL_DLLPRIVATE OUString
Impl_BuildFormatStringNumChars( const LocaleDataWrapper
&, sal_uInt16 nDecimalFormat
) const;
242 NfCurrencyEntry( const LocaleDataWrapper
& rLocaleData
,
243 LanguageType eLang
);
244 NfCurrencyEntry( const css::i18n::Currency
& rCurr
,
245 const LocaleDataWrapper
& rLocaleData
,
246 LanguageType eLang
);
247 inline NfCurrencyEntry(const OUString
& rSymbol
, const OUString
& rBankSymbol
,
248 LanguageType eLang
, sal_uInt16 nPositiveFmt
,
249 sal_uInt16 nNegativeFmt
, sal_uInt16 nDig
, sal_Unicode cZero
);
250 ~NfCurrencyEntry() {}
252 /// Symbols and language identical
253 bool operator==( const NfCurrencyEntry
& r
) const;
255 const OUString
& GetSymbol() const { return aSymbol
; }
256 const OUString
& GetBankSymbol() const { return aBankSymbol
; }
257 LanguageType
GetLanguage() const { return eLanguage
; }
258 sal_uInt16
GetPositiveFormat() const { return nPositiveFormat
; }
259 sal_uInt16
GetNegativeFormat() const { return nNegativeFormat
; }
260 sal_uInt16
GetDigits() const { return nDigits
; }
262 /** [$DM-407] (bBank==false) or [$DEM] (bBank==true)
263 is returned. If bBank==false and
264 bWithoutExtension==true only [$DM] */
265 OUString
BuildSymbolString(bool bBank
, bool bWithoutExtension
= false) const;
267 /** #,##0.00 [$DM-407] is returned, separators
268 from rLoc, incl. minus sign but without [RED] */
269 OUString
BuildPositiveFormatString(bool bBank
, const LocaleDataWrapper
&,
270 sal_uInt16 nDecimalFormat
= 1) const;
271 OUString
BuildNegativeFormatString(bool bBank
, const LocaleDataWrapper
&,
272 sal_uInt16 nDecimalFormat
= 1) const;
274 /** [$DM-407] (or [$DEM] if bBank==true)
275 is appended/prepended to rStr, incl. minus sign */
276 void CompletePositiveFormatString(OUStringBuffer
& rStr
, bool bBank
,
277 sal_uInt16 nPosiFormat
) const;
278 void CompleteNegativeFormatString(OUStringBuffer
& rStr
, bool bBank
,
279 sal_uInt16 nNegaFormat
) const;
281 /// rSymStr is appended/prepended to rStr, incl. minus sign
282 static void CompletePositiveFormatString(OUStringBuffer
& rStr
,
283 const OUString
& rSymStr
, sal_uInt16 nPosiFormat
);
284 static void CompleteNegativeFormatString(OUStringBuffer
& rStr
,
285 const OUString
& rSymStr
, sal_uInt16 nNegaFormat
);
287 /** Representation of a currency (symbol position and
288 negative sign) in other language settings */
289 static sal_uInt16
GetEffectivePositiveFormat( sal_uInt16 nIntlFormat
,
290 sal_uInt16 nCurrFormat
, bool bBank
);
291 static sal_uInt16
GetEffectiveNegativeFormat( sal_uInt16 nIntlFormat
,
292 sal_uInt16 nCurrFormat
, bool bBank
);
294 /// General Unicode Euro symbol
295 static inline sal_Unicode
GetEuroSymbol() { return sal_Unicode(0x20AC); }
299 * Necessary for ptr_vector on Windows. Please don't remove these, or at
300 * least check it on Windows before attempting to remove them.
302 NfCurrencyEntry::NfCurrencyEntry(const OUString
& rSymbol
, const OUString
& rBankSymbol
,
303 LanguageType eLang
, sal_uInt16 nPositiveFmt
,
304 sal_uInt16 nNegativeFmt
, sal_uInt16 nDig
, sal_Unicode cZero
)
305 : aSymbol(rSymbol
), aBankSymbol(rBankSymbol
), eLanguage(eLang
)
306 , nPositiveFormat(nPositiveFmt
), nNegativeFormat(nNegativeFmt
)
307 , nDigits(nDig
), cZeroChar(cZero
)
311 typedef std::vector
< OUString
> NfWSStringsDtor
;
313 class SvNumberFormatterRegistry_Impl
;
314 class NfCurrencyTable
;
316 class SVL_DLLPUBLIC SvNumberFormatter
320 * We can't technically have an "infinite" value, so we use an arbitrary
321 * upper precision threshold to represent the "unlimited" precision.
323 static const sal_uInt16 UNLIMITED_PRECISION
;
326 * Precision suitable for numbers displayed in input bar, for instance
327 * Calc's formula input bar.
329 static const sal_uInt16 INPUTSTRING_PRECISION
;
331 /// Preferred ctor with service manager and language/country enum
333 const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
,
337 ~SvNumberFormatter();
339 /// Set CallBack to ColorTable
340 void SetColorLink( const Link
<sal_uInt16
,Color
*>& rColorTableCallBack
);
341 /// Do the CallBack to ColorTable
342 Color
* GetUserDefColor(sal_uInt16 nIndex
);
344 /// Change language/country, also input and format scanner
345 void ChangeIntl( LanguageType eLnge
);
346 /// Change the reference null date
347 void ChangeNullDate(sal_uInt16 nDay
, sal_uInt16 nMonth
, sal_uInt16 nYear
);
348 /// Change standard precision
349 void ChangeStandardPrec(short nPrec
);
350 /// Set zero value suppression
351 void SetNoZero(bool bNZ
);
353 /** The language with which the formatter was initialized (system setting),
354 NOT the current language after a ChangeIntl() */
355 LanguageType
GetLanguage() const;
357 // Determine whether two format types are input compatible or not
358 bool IsCompatible(short eOldType
, short eNewType
);
360 /** Get table of formats of a specific type of a locale. A format FIndex is
361 tested whether it has the type and locale requested, if it doesn't
362 match FIndex returns the default format for the type/locale. If no
363 specific format is to be selected FIndex may be initialized to 0. */
364 SvNumberFormatTable
& GetEntryTable(short eType
,
368 /** Get table of formats of a specific type of a language/country.
369 FIndex returns the default format of that type.
370 If the language/country was never touched before new entries are generated */
371 SvNumberFormatTable
& ChangeCL(short eType
,
375 /** Get table of formats of the same type as FIndex; eType and rLnge are
376 set accordingly. An unknown format is set to Standard/General */
377 SvNumberFormatTable
& GetFirstEntryTable(short& eType
,
379 LanguageType
& rLnge
);
381 /// Delete an entry including the format it is referring to
382 void DeleteEntry(sal_uInt32 nKey
);
384 /** Create new entry of a format code string for language/country.
386 <TRUE/> if string new and ok and inserted.
387 <FALSE/> if string already exists or an unresolvable parse error
388 occurred, in which case nCheckPos is the error position within rString.
389 If the error occurs at position 0 or rString is empty nCheckPos
390 will be 1, so an error in the string is always indicated by
391 nCheckPos not being zero.
392 The content of the rString variable can be changed and corrected
394 nType contains the type of the format.
395 nKey contains the index key of the format.
397 bool PutEntry( OUString
& rString
, sal_Int32
& nCheckPos
, short& nType
, sal_uInt32
& nKey
,
398 LanguageType eLnge
= LANGUAGE_DONTKNOW
);
400 /** Same as <method>PutEntry</method> but the format code string is
401 considered to be of language/country eLnge and is converted to
402 language/country eNewLnge */
403 bool PutandConvertEntry( OUString
& rString
, sal_Int32
& nCheckPos
,
404 short& nType
, sal_uInt32
& nKey
,
405 LanguageType eLnge
, LanguageType eNewLnge
);
407 /** Same as <method>PutandConvertEntry</method> but the format code string
408 is considered to be of the System language/country eLnge and is
409 converted to another System language/country eNewLnge. In this case
410 the automatic currency is converted too. */
411 bool PutandConvertEntrySystem( OUString
& rString
, sal_Int32
& nCheckPos
,
412 short& nType
, sal_uInt32
& nKey
,
413 LanguageType eLnge
, LanguageType eNewLnge
);
415 /** Similar to <method>PutEntry</method> and
416 <method>PutandConvertEntry</method> or
417 <method>PutandConvertEntrySystem</method>, the format code string
418 passed is considered to be of language/country eLnge. If
419 eLnge==LANGUAGE_SYSTEM the format code has to match eSysLnge, and if
420 eSysLnge is not the current application locale the format code is
421 converted to the current locale. Additionally, if the format code
422 represents an old "automatic" currency format, it is converted to the
423 new default currency format of the eLnge locale. The rString format
424 code passed as an argument may get adapted in case eLnge was used (or
425 is LANGUAGE_SYSTEM and eSysLnge is identical); in case it wasn't the
426 method works on a copy instead, otherwise the resulting string would
427 not match eSysLnge anymore.
429 <p> This method was introduced to handle the legacy currency formats of
430 the "autotbl.fmt" file used by Calc and Writer and convert them to
431 fixed currency codes of the actual currency. Note that in the case of
432 legacy currency formats no special attribution is converted, only the
433 default currency format of the locale is chosen, and that new fixed
434 currency codes are of course not converted to other currencies. The
435 method may also be used as a general method taking, converting and
436 inserting almost arbitrary format codes. To insert or use, for example,
437 the default currency format code matching the current locale, the
438 method could be called with<br/>
441 GetIndexPuttingAndConverting( "0 $", LANGUAGE_SYSTEM, LANGUAGE_ENGLISH_US, ...);
445 The index key of the resulting number format. If the format code
446 was empty, could not be converted or has errors, the eLnge locale's
447 standard number format is chosen instead. The index key is
448 guaranteed to represent some valid number format. If
449 rNewInserted==false and rCheckPos>0 the format code has errors
450 and/or could not be converted.
452 sal_uInt32
GetIndexPuttingAndConverting( OUString
& rString
, LanguageType eLnge
,
453 LanguageType eSysLnge
, short & rType
,
454 bool & rNewInserted
, sal_Int32
& rCheckPos
);
456 /** Create a format code string using format nIndex as a template and
457 applying other settings (passed from the dialog) */
458 OUString
GenerateFormat(sal_uInt32 nIndex
,
459 LanguageType eLnge
= LANGUAGE_DONTKNOW
,
460 bool bThousand
= false, bool IsRed
= false,
461 sal_uInt16 nPrecision
= 0, sal_uInt16 nAnzLeading
= 1);
463 /** Analyze an input string
465 <TRUE/> if input is a number or is matching a format F_Index
466 F_Index is set to a matching format if number, the value is
467 returned in fOutNumber
468 <FALSE/> if input is not a number
470 bool IsNumberFormat( const OUString
& sString
, sal_uInt32
& F_Index
, double& fOutNumber
);
472 /// Format a number according to a format index, return string and color
473 void GetOutputString( const double& fOutNumber
, sal_uInt32 nFIndex
,
474 OUString
& sOutString
, Color
** ppColor
, bool bUseStarFormat
= false );
476 /** Format a string according to a format index, return string and color.
477 Formats only if the format code is of type text or the 4th subcode
478 of a format code is specified, otherwise sOutString will be == "" */
479 void GetOutputString( const OUString
& sString
, sal_uInt32 nFIndex
,
480 OUString
& sOutString
, Color
** ppColor
, bool bUseStarFormat
= false );
482 /** Format a number according to the standard default format matching
483 the given format index */
484 void GetInputLineString( const double& fOutNumber
,
485 sal_uInt32 nFIndex
, OUString
& rOutString
);
487 /** Format a number according to a format code string to be scanned.
489 <FALSE/> if format code contains an error
490 <TRUE/> else, in which case the string and color are returned.
492 bool GetPreviewString(const OUString
& sFormatString
,
493 double fPreviewNumber
,
494 OUString
& sOutString
,
497 bool bUseStarFormat
= false );
499 /** Same as <method>GetPreviewString</method> but the format code string
500 may be either language/country eLnge or en_US english US */
501 bool GetPreviewStringGuess( const OUString
& sFormatString
, double fPreviewNumber
,
502 OUString
& sOutString
, Color
** ppColor
,
503 LanguageType eLnge
= LANGUAGE_DONTKNOW
);
505 /** Format a string according to a format code string to be scanned.
507 <FALSE/> if format code contains an error
508 <TRUE/> else, in which case the string and color are returned.
510 bool GetPreviewString( const OUString
& sFormatString
, const OUString
& sPreviewString
,
511 OUString
& sOutString
, Color
** ppColor
,
512 LanguageType eLnge
= LANGUAGE_DONTKNOW
);
514 /** Test whether the format code string is already present in container
516 NUMBERFORMAT_ENTRY_NOT_FOUND if not found, else the format index.
518 sal_uInt32
TestNewString( const OUString
& sFormatString
,
519 LanguageType eLnge
= LANGUAGE_DONTKNOW
);
521 /// Whether format index nFIndex is of type text or not
522 bool IsTextFormat(sal_uInt32 nFIndex
) const;
524 /// Get additional info of a format index, e.g. for dialog box
525 void GetFormatSpecialInfo(sal_uInt32 nFormat
, bool& bThousand
, bool& IsRed
,
526 sal_uInt16
& nPrecision
, sal_uInt16
& nAnzLeading
);
528 /// Count of decimals
529 sal_uInt16
GetFormatPrecision( sal_uInt32 nFormat
) const;
531 /// Count of integer digits
532 sal_uInt16
GetFormatIntegerDigits( sal_uInt32 nFormat
) const;
534 /** Get additional info of a format code string, e.g. for dialog box.
535 Uses a temporary parse, if possible use only if format code is not
536 present in container yet, otherwise ineffective.
538 0 if format code string parsed without errors, otherwise error
539 position (like nCheckPos on <method>PutEntry</method>)
541 sal_uInt32
GetFormatSpecialInfo( const OUString
&, bool& bThousand
, bool& IsRed
,
542 sal_uInt16
& nPrecision
, sal_uInt16
& nAnzLeading
,
543 LanguageType eLnge
= LANGUAGE_DONTKNOW
);
545 /// Check if format code string may be deleted by user
546 bool IsUserDefined( const OUString
& sStr
, LanguageType eLnge
= LANGUAGE_DONTKNOW
);
548 /** Return the format index of the format code string for language/country,
549 or NUMBERFORMAT_ENTRY_NOT_FOUND */
550 sal_uInt32
GetEntryKey( const OUString
& sStr
, LanguageType eLnge
= LANGUAGE_DONTKNOW
);
552 /// Return the format for a format index
553 const SvNumberformat
* GetEntry( sal_uInt32 nKey
) const;
555 /// Return the format index of the standard default number format for language/country
556 sal_uInt32
GetStandardIndex(LanguageType eLnge
= LANGUAGE_DONTKNOW
);
558 /// Return the format index of the default format of a type for language/country
559 sal_uInt32
GetStandardFormat(short eType
, LanguageType eLnge
= LANGUAGE_DONTKNOW
);
561 /** Return the format index of the default format of a type for language/country.
562 Maybe not the default format but a special builtin format, e.g. for
563 NF_TIME_HH_MMSS00, if that format is passed in nFIndex. */
564 sal_uInt32
GetStandardFormat( sal_uInt32 nFIndex
, short eType
, LanguageType eLnge
);
566 /** Return the format index of the default format of a type for language/country.
567 Maybe not the default format but a special builtin format, e.g. for
568 NF_TIME_HH_MMSS00, or NF_TIME_HH_MMSS if fNumber >= 1.0 */
569 sal_uInt32
GetStandardFormat( double fNumber
, sal_uInt32 nFIndex
, short eType
,
570 LanguageType eLnge
);
572 /// Whether nFIndex is a special builtin format
573 bool IsSpecialStandardFormat( sal_uInt32 nFIndex
, LanguageType eLnge
);
575 /** Return a time format that best matches fNumber. */
576 sal_uInt32
GetTimeFormat( double fNumber
, LanguageType eLnge
);
578 /** Return a format and type that best matches the value of fNumber if
579 fNumber is assumed to be a date, time or datetime value, but unknown
580 which. Originally introduced for Chart databrowser editor, probably
581 should not be used otherwise. */
582 sal_uInt32
GuessDateTimeFormat( short& rType
, double fNumber
, LanguageType eLnge
);
584 /** Return the corresponding edit format of a format. */
585 sal_uInt32
GetEditFormat( double fNumber
, sal_uInt32 nFIndex
, short eType
,
586 LanguageType eLnge
, SvNumberformat
* pFormat
);
588 /// Return the reference date
590 /// Return the standard decimal precision
591 sal_uInt16
GetStandardPrec();
592 /// Return whether zero suppression is switched on
594 /** Get the type of a format (or css::util::NumberFormat::UNDEFINED if no entry),
595 but with css::util::NumberFormat::DEFINED masked out */
596 short GetType(sal_uInt32 nFIndex
);
599 void ClearMergeTable();
600 /// Merge in all new entries from rNewTable and return a table of resulting new format indices
601 SvNumberFormatterIndexTable
* MergeFormatter(SvNumberFormatter
& rNewTable
);
603 /// Whether a merge table is present or not
604 bool HasMergeFormatTable() const;
605 /// Return the new format index for an old format index, if a merge table exists
606 sal_uInt32
GetMergeFormatIndex( sal_uInt32 nOldFmt
) const;
608 /** Convert the ugly old tools' Table type bloated with new'ed sal_uInt32
609 entries merge table to ::std::map with old index key and new index key.
610 @ATTENTION! Also clears the old table using ClearMergeTable() */
611 SvNumberFormatterMergeMap
ConvertMergeTableToMap();
613 /** Return the format index of a builtin format for a specific language/country.
614 If nFormat is not a builtin format nFormat is returned. */
615 sal_uInt32
GetFormatForLanguageIfBuiltIn( sal_uInt32 nFormat
,
616 LanguageType eLnge
= LANGUAGE_DONTKNOW
);
618 /** Return the format index for a builtin format of a specific language
619 @see NfIndexTableOffset
621 sal_uInt32
GetFormatIndex( NfIndexTableOffset
, LanguageType eLnge
= LANGUAGE_DONTKNOW
);
623 /** Return enum index of a format index of a builtin format,
624 NF_INDEX_TABLE_ENTRIES if it's not a builtin format.
625 @see NfIndexTableOffset
627 NfIndexTableOffset
GetIndexTableOffset( sal_uInt32 nFormat
) const;
629 /** Set evaluation type and order of input date strings
630 @see NfEvalDateFormat
632 void SetEvalDateFormat( NfEvalDateFormat eEDF
);
633 NfEvalDateFormat
GetEvalDateFormat() const;
635 /** Set TwoDigitYearStart, how the input string scanner handles a two digit year.
636 Default from VCL: 1930, 30-99 19xx, 00-29 20xx
638 <p> Historically (prior to src513e) it was a two digit number determining
639 until which number the string scanner recognizes a year to be 20xx,
640 default <= 29 is used by SFX/OfaMiscCfg.
641 The name Year2000 is kept although the actual functionality is now a
642 TwoDigitYearStart which might be in any century.
644 void SetYear2000( sal_uInt16 nVal
);
645 sal_uInt16
GetYear2000() const;
646 static sal_uInt16
GetYear2000Default();
648 sal_uInt16
ExpandTwoDigitYear( sal_uInt16 nYear
) const;
649 static sal_uInt16
ExpandTwoDigitYear( sal_uInt16 nYear
, sal_uInt16 nTwoDigitYearStart
);
651 /// DEPRECATED: Return first character of the decimal separator of the current language/country
652 sal_Unicode
GetDecSep() const;
654 /// Return the decimal separator matching the locale of the given format
655 OUString
GetFormatDecimalSep( sal_uInt32 nFormat
) const;
657 /// Return a NfCurrencyTable with pointers to <type>NfCurrencyEntry</type> entries
658 static const NfCurrencyTable
& GetTheCurrencyTable();
660 /** Searches, according to the default locale currency, an entry of the
661 CurrencyTable which is <bold>not</bold> the first (LANGUAGE_SYSTEM) entry.
664 else pointer to NfCurrencyEntry
666 static const NfCurrencyEntry
* MatchSystemCurrency();
668 /** Return a NfCurrencyEntry matching a language/country.
669 If language/country is LANGUAGE_SYSTEM a <method>MatchSystemCurrency</method>
670 call is tried to get an entry. If that fails or the corresponding
671 language/country is not present the entry for LANGUAGE_SYSTEM is returned.
673 static const NfCurrencyEntry
& GetCurrencyEntry( LanguageType
);
675 /** Return a NfCurrencyEntry pointer matching a language/country
676 and currency abbreviation (AKA banking symbol).
677 This method is meant for the configuration of the default currency.
680 else pointer to NfCurrencyEntry
682 static const NfCurrencyEntry
* GetCurrencyEntry( const OUString
& rAbbrev
,
683 LanguageType eLang
);
685 /** Return a NfCurrencyEntry pointer matching the symbol
686 combination of a LegacyOnly currency. Note that this means only that
687 the currency matching both symbols was once used in the Office, but is
688 not offered in dialogs anymore. It doesn't even mean that the currency
689 symbol combination is valid, since the reason for removing it may have
690 been just that. #i61657#
692 A matching entry, or else <NULL/>.
694 static const NfCurrencyEntry
* GetLegacyOnlyCurrencyEntry( const OUString
& rSymbol
, const OUString
& rAbbrev
);
696 /** Set the default system currency. The combination of abbreviation and
697 language must match an existent element of theCurrencyTable. If not,
698 the SYSTEM (current locale) entry becomes the default.
699 This method is meant for the configuration of the default currency.
701 static void SetDefaultSystemCurrency( const OUString
& rAbbrev
, LanguageType eLang
);
703 /** Get all standard formats for a specific currency, formats are
704 appended to the NfWSStringsDtor list.
706 <TRUE/>: generate only format strings with currency abbreviation
707 <FALSE/>: mixed format strings
709 position of default format
711 sal_uInt16
GetCurrencyFormatStrings( NfWSStringsDtor
&, const NfCurrencyEntry
&,
714 /** Whether nFormat is of type css::util::NumberFormat::CURRENCY and the format code
715 contains a new SYMBOLTYPE_CURRENCY and if so which one [$xxx-nnn].
716 If ppEntry is not NULL and exactly one entry is found, a [$xxx-nnn] is
717 returned, even if the format code only contains [$xxx] !
719 bool GetNewCurrencySymbolString( sal_uInt32 nFormat
, OUString
& rSymbol
,
720 const NfCurrencyEntry
** ppEntry
= nullptr,
721 bool* pBank
= nullptr ) const;
723 /** Look up the corresponding NfCurrencyEntry matching
724 rSymbol (may be CurrencySymbol or CurrencyAbbreviation) and possibly
725 a rExtension (being yyy of [$xxx-yyy]) or a given language/country
726 value. Tries to match a rSymbol with rExtension first, then with
727 eFormatLanguage, then rSymbol only. This is because a currency entry
728 might have been constructed using I18N locale data where a used locale
729 of a currency format code must not necessarily match the locale of
730 the locale data itself, e.g. [$HK$-40C] (being "zh_HK" locale) in
731 zh_CN locale data. Here the rExtension would have the value 0x40c but
732 eFormatLanguage of the number format would have the value of zh_CN
733 locale, the value with which the corresponding CurrencyEntry is
737 Only used for output.
738 If the return value is not <NULL/> this value is set to <TRUE/> if
739 the matching entry was found by comparing rSymbol against the
740 CurrencyAbbreviation (AKA BankSymbol).
741 If the return value is <NULL/> the value of bFoundBank is undefined.
743 Currency symbol, preferably obtained of a format by a call to
744 <method>SvNumberformat::GetNewCurrencySymbol()</method>
746 Currency extension, preferably obtained of a format by a call to
747 <method>SvNumberformat::GetNewCurrencySymbol()</method>
748 @param eFormatLanguage
749 The language/country value of the format of which rSymbol and
750 rExtension are obtained (<method>SvNumberformat::GetLanguage()</method>).
751 @param bOnlyStringLanguage
752 If <TRUE/> only entries with language/country of rExtension are
753 checked, no match on eFormatLanguage. If rExtension is empty all
756 The matching entry if unique (in which case bFoundBank is set),
759 static const NfCurrencyEntry
* GetCurrencyEntry( bool & bFoundBank
,
760 const OUString
& rSymbol
,
761 const OUString
& rExtension
,
762 LanguageType eFormatLanguage
,
763 bool bOnlyStringLanguage
= false );
765 /// Get compatibility ("automatic" old style) currency from I18N locale data
766 void GetCompatibilityCurrency( OUString
& rSymbol
, OUString
& rAbbrev
) const;
768 /// Fill rList with the language/country codes that have been allocated
769 void GetUsedLanguages( std::vector
<sal_uInt16
>& rList
);
771 /// Fill a NfKeywordIndex table with keywords of a language/country
772 void FillKeywordTable( NfKeywordTable
& rKeywords
, LanguageType eLang
);
774 /** Fill a NfKeywordIndex table with keywords usable in Excel export with
775 GetFormatStringForExcel() or SvNumberformat::GetMappedFormatstring() */
776 void FillKeywordTableForExcel( NfKeywordTable
& rKeywords
);
778 /** Return a format code string suitable for Excel export.
780 @param rTempFormatter
781 SvNumberFormatter to use if a non-en-US format code needs to be
782 converted and put, should not be the same formatter to not
783 pollute the entries of this one here.
785 OUString
GetFormatStringForExcel( sal_uInt32 nKey
, const NfKeywordTable
& rKeywords
,
786 SvNumberFormatter
& rTempFormatter
) const;
788 /** Return a keyword for a language/country and NfKeywordIndex
789 for XML import, to generate number format strings. */
790 OUString
GetKeyword( LanguageType eLnge
, sal_uInt16 nIndex
);
792 /** Return the GENERAL keyword in proper case ("General") for a
793 language/country, used in XML import */
794 OUString
GetStandardName( LanguageType eLnge
);
796 /** Check if a specific locale has supported locale data. */
797 static bool IsLocaleInstalled( LanguageType eLang
);
800 css::uno::Reference
< css::uno::XComponentContext
> m_xContext
;
801 LanguageTag maLanguageTag
;
802 SvNumberFormatTable aFTable
; // Table of format keys to format entries
803 typedef std::map
<sal_uInt32
, sal_uInt32
> DefaultFormatKeysMap
;
804 DefaultFormatKeysMap aDefaultFormatKeys
; // Table of default standard to format keys
805 SvNumberFormatTable
* pFormatTable
; // For the UI dialog
806 SvNumberFormatterIndexTable
* pMergeTable
; // List of indices for merging two formatters
807 CharClass
* pCharClass
; // CharacterClassification
808 OnDemandLocaleDataWrapper xLocaleData
; // LocaleData switched between SYSTEM, ENGLISH and other
809 OnDemandTransliterationWrapper xTransliteration
; // Transliteration loaded on demand
810 OnDemandCalendarWrapper xCalendar
; // Calendar loaded on demand
811 OnDemandNativeNumberWrapper xNatNum
; // Native number service loaded on demand
812 ImpSvNumberInputScan
* pStringScanner
; // Input string scanner
813 ImpSvNumberformatScan
* pFormatScanner
; // Format code string scanner
814 Link
<sal_uInt16
,Color
*> aColorLink
; // User defined color table CallBack
815 sal_uInt32 MaxCLOffset
; // Max language/country offset used
816 sal_uInt32 nDefaultSystemCurrencyFormat
; // NewCurrency matching SYSTEM locale
817 LanguageType IniLnge
; // Initialized setting language/country
818 LanguageType ActLnge
; // Current setting language/country
819 NfEvalDateFormat eEvalDateFormat
; // DateFormat evaluation
820 bool bNoZero
; // Zero value suppression
822 // cached locale data items needed almost any time
823 OUString aDecimalSep
;
824 OUString aThousandSep
;
827 SVL_DLLPRIVATE
static bool bCurrencyTableInitialized
;
828 SVL_DLLPRIVATE
static sal_uInt16 nSystemCurrencyPosition
;
829 SVL_DLLPRIVATE
static SvNumberFormatterRegistry_Impl
* pFormatterRegistry
;
831 // get the registry, create one if none exists
832 SVL_DLLPRIVATE
static SvNumberFormatterRegistry_Impl
& GetFormatterRegistry();
835 SVL_DLLPRIVATE
void ImpConstruct( LanguageType eLang
);
837 // Generate builtin formats provided by i18n behind CLOffset,
838 // if bNoAdditionalFormats==false also generate additional i18n formats.
839 SVL_DLLPRIVATE
void ImpGenerateFormats( sal_uInt32 CLOffset
, bool bNoAdditionalFormats
);
841 // Generate additional formats provided by i18n
842 SVL_DLLPRIVATE
void ImpGenerateAdditionalFormats( sal_uInt32 CLOffset
,
843 NumberFormatCodeWrapper
& rNumberFormatCode
,
844 bool bAfterChangingSystemCL
);
846 SVL_DLLPRIVATE SvNumberformat
* ImpInsertFormat( const css::i18n::NumberFormatCode
& rCode
,
848 bool bAfterChangingSystemCL
= false,
849 sal_Int16 nOrgIndex
= 0 );
851 // Return CLOffset or (MaxCLOffset + SV_COUNTRY_LANGUAGE_OFFSET) if new language/country
852 SVL_DLLPRIVATE sal_uInt32
ImpGetCLOffset(LanguageType eLnge
) const;
854 // Test whether format code already exists, then return index key,
855 // otherwise NUMBERFORMAT_ENTRY_NOT_FOUND
856 SVL_DLLPRIVATE sal_uInt32
ImpIsEntry( const OUString
& rString
,
858 LanguageType eLnge
);
860 // Create builtin formats for language/country if necessary, return CLOffset
861 SVL_DLLPRIVATE sal_uInt32
ImpGenerateCL( LanguageType eLnge
);
863 // Build negative currency format, old compatibility style
864 SVL_DLLPRIVATE
void ImpGetNegCurrFormat(OUStringBuffer
& sNegStr
, const OUString
& rCurrSymbol
);
865 // Build positive currency format, old compatibility style
866 SVL_DLLPRIVATE
void ImpGetPosCurrFormat(OUStringBuffer
& sPosStr
, const OUString
& rCurrSymbol
);
868 // Create theCurrencyTable with all <type>NfCurrencyEntry</type>
869 SVL_DLLPRIVATE
static void ImpInitCurrencyTable();
871 // Return the format index of the currency format of the system locale.
872 // Format is created if not already present.
873 SVL_DLLPRIVATE sal_uInt32
ImpGetDefaultSystemCurrencyFormat();
875 // Return the format index of the currency format of the current locale.
876 // Format is created if not already present.
877 SVL_DLLPRIVATE sal_uInt32
ImpGetDefaultCurrencyFormat();
879 // Return the default format for a given type and current locale.
880 // May ONLY be called from within GetStandardFormat().
881 SVL_DLLPRIVATE sal_uInt32
ImpGetDefaultFormat( short nType
);
883 // Return the index in a sequence of format codes matching an enum of
884 // NfIndexTableOffset. If not found 0 is returned. If the sequence doesn't
885 // contain any format code elements a default element is created and inserted.
886 SVL_DLLPRIVATE sal_Int32
ImpGetFormatCodeIndex( css::uno::Sequence
< css::i18n::NumberFormatCode
>& rSeq
,
887 const NfIndexTableOffset nTabOff
);
889 // Adjust a sequence of format codes to contain only one (THE) default
890 // instead of multiple defaults for short/medium/long types.
891 // If there is no medium but a short and a long default the long is taken.
892 // Non-PRODUCT version may check locale data for matching defaults in one
893 // FormatElement group.
894 SVL_DLLPRIVATE
void ImpAdjustFormatCodeDefault( css::i18n::NumberFormatCode
* pFormatArr
,
897 // Obtain the format entry for a given key index.
898 SVL_DLLPRIVATE SvNumberformat
* GetFormatEntry( sal_uInt32 nKey
);
899 SVL_DLLPRIVATE
const SvNumberformat
* GetFormatEntry( sal_uInt32 nKey
) const;
901 // used as a loop body inside of GetNewCurrencySymbolString() and GetCurrencyEntry()
902 static bool ImpLookupCurrencyEntryLoopBody(
903 const NfCurrencyEntry
*& pFoundEntry
, bool& bFoundBank
, const NfCurrencyEntry
* pData
,
904 sal_uInt16 nPos
, const OUString
& rSymbol
);
906 // link to be set at <method>SvtSysLocaleOptions::SetCurrencyChangeLink()</method>
907 DECL_DLLPRIVATE_STATIC_LINK_TYPED( SvNumberFormatter
, CurrencyChangeLink
, LinkParamNone
*, void );
909 // return position of a special character
910 sal_Int32
ImpPosToken ( const OUStringBuffer
& sFormat
, sal_Unicode token
, sal_Int32 nStartPos
= 0 );
914 // own static mutex, may also be used by internal class SvNumberFormatterRegistry_Impl
915 static ::osl::Mutex
& GetMutex();
917 // called by SvNumberFormatterRegistry_Impl::Notify if the default system currency changes
918 void ResetDefaultSystemCurrency();
920 // Called by SvNumberFormatterRegistry_Impl::Notify if the system locale's
921 // date acceptance patterns change.
922 void InvalidateDateAcceptancePatterns();
924 // Replace the SYSTEM language/country format codes. Called upon change of
925 // the user configurable locale.
926 // Old compatibility codes are replaced, user defined are converted, and
927 // new format codes are appended.
928 void ReplaceSystemCL( LanguageType eOldLanguage
);
930 const css::uno::Reference
<css::uno::XComponentContext
>& GetComponentContext() const;
932 //! The following method is not to be used from outside but must be
933 //! public for the InputScanner.
934 // return the current FormatScanner
935 const ImpSvNumberformatScan
* GetFormatScanner() const;
937 //! The following methods are not to be used from outside but must be
938 //! public for the InputScanner and FormatScanner.
940 // return current (!) Locale
941 const LanguageTag
& GetLanguageTag() const;
943 // return corresponding Transliteration wrapper
944 const ::utl::TransliterationWrapper
* GetTransliteration() const;
946 // return the corresponding CharacterClassification wrapper
947 const CharClass
* GetCharClass() const;
949 // return the corresponding LocaleData wrapper
950 const LocaleDataWrapper
* GetLocaleData() const;
952 // return the corresponding Calendar wrapper
953 CalendarWrapper
* GetCalendar() const;
955 // return the corresponding NativeNumberSupplier wrapper
956 const NativeNumberWrapper
* GetNatNum() const;
958 // cached locale data items
960 // return the corresponding decimal separator
961 const OUString
& GetNumDecimalSep() const;
963 // return the corresponding group (AKA thousand) separator
964 const OUString
& GetNumThousandSep() const;
966 // return the corresponding date separator
967 const OUString
& GetDateSep() const;
970 #endif // INCLUDED_SVL_ZFORLIST_HXX
972 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */