bump product version to 7.6.3.2-android
[LibreOffice.git] / include / svl / numformat.hxx
blob0a374f3c3301991e4c64534861019ed4ac0fa712
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 #pragma once
21 #include <svl/svldllapi.h>
22 #include <com/sun/star/i18n/XNumberFormatCode.hpp>
23 #include <com/sun/star/uno/XComponentContext.hpp>
24 #include <i18nlangtag/lang.h>
25 #include <tools/link.hxx>
26 #include <svl/nfkeytab.hxx>
27 #include <svl/ondemand.hxx>
28 #include <svl/zforlist.hxx>
29 #include <unotools/charclass.hxx>
31 #include <map>
33 class Color;
34 class ImpSvNumberformatScan;
35 class ImpSvNumberInputScan;
36 class SvNumberFormatterRegistry_Impl;
37 class NfCurrencyTable;
39 class SVL_DLLPUBLIC SvNumberFormatter
41 friend class SvNumberFormatterRegistry_Impl;
43 public:
44 /**
45 * We can't technically have an "infinite" value, so we use an arbitrary
46 * upper precision threshold to represent the "unlimited" precision.
48 static const sal_uInt16 UNLIMITED_PRECISION;
50 /**
51 * Precision suitable for numbers displayed in input bar, for instance
52 * Calc's formula input bar.
54 static const sal_uInt16 INPUTSTRING_PRECISION;
56 /// Preferred ctor with service manager and language/country enum
57 SvNumberFormatter(const css::uno::Reference<css::uno::XComponentContext>& rxContext,
58 LanguageType eLang);
60 ~SvNumberFormatter();
62 /// Set CallBack to ColorTable
63 void SetColorLink(const Link<sal_uInt16, Color*>& rColorTableCallBack);
64 /// Do the CallBack to ColorTable
65 Color* GetUserDefColor(sal_uInt16 nIndex);
67 /// Change language/country, also input and format scanner
68 void ChangeIntl(LanguageType eLnge);
69 /// Change the reference null date
70 void ChangeNullDate(sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear);
71 /// Change standard precision
72 void ChangeStandardPrec(short nPrec);
73 /// Set zero value suppression
74 void SetNoZero(bool bNZ);
76 /** The language with which the formatter was initialized (system setting),
77 NOT the current language after a ChangeIntl() */
78 LanguageType GetLanguage() const;
80 // Determine whether two format types are input compatible or not
81 static bool IsCompatible(SvNumFormatType eOldType, SvNumFormatType eNewType);
83 /** Get table of formats of a specific type of a locale. A format FIndex is
84 tested whether it has the type and locale requested, if it doesn't
85 match FIndex returns the default format for the type/locale. If no
86 specific format is to be selected FIndex may be initialized to 0. */
87 SvNumberFormatTable& GetEntryTable(SvNumFormatType eType, sal_uInt32& FIndex,
88 LanguageType eLnge);
90 /** Get table of formats of a specific type of a language/country.
91 FIndex returns the default format of that type.
92 If the language/country was never touched before new entries are generated */
93 SvNumberFormatTable& ChangeCL(SvNumFormatType eType, sal_uInt32& FIndex, LanguageType eLnge);
95 /** Get table of formats of the same type as FIndex; eType and rLnge are
96 set accordingly. An unknown format is set to Standard/General */
97 SvNumberFormatTable& GetFirstEntryTable(SvNumFormatType& eType, sal_uInt32& FIndex,
98 LanguageType& rLnge);
100 /// Delete an entry including the format it is referring to
101 void DeleteEntry(sal_uInt32 nKey);
103 /** Create new entry of a format code string for language/country.
104 @return
105 <TRUE/> if string new and ok and inserted.
106 <FALSE/> if string already exists or an unresolvable parse error
107 occurred, in which case nCheckPos is the error position within rString.
108 If the error occurs at position 0 or rString is empty nCheckPos
109 will be 1, so an error in the string is always indicated by
110 nCheckPos not being zero.
111 The content of the rString variable can be changed and corrected
112 by the method.
113 nType contains the type of the format.
114 nKey contains the index key of the format.
116 bool PutEntry(OUString& rString, sal_Int32& nCheckPos, SvNumFormatType& nType, sal_uInt32& nKey,
117 LanguageType eLnge = LANGUAGE_DONTKNOW, bool bReplaceBooleanEquivalent = true);
119 /** Same as <method>PutEntry</method> but the format code string is
120 considered to be of language/country eLnge and is converted to
121 language/country eNewLnge */
122 bool PutandConvertEntry(OUString& rString, sal_Int32& nCheckPos, SvNumFormatType& nType,
123 sal_uInt32& nKey, LanguageType eLnge, LanguageType eNewLnge,
124 bool bConvertDateOrder, bool bReplaceBooleanEquivalent = true);
126 /** Same as <method>PutandConvertEntry</method> but the format code string
127 is considered to be of the System language/country eLnge and is
128 converted to another System language/country eNewLnge. In this case
129 the automatic currency is converted too. */
130 bool PutandConvertEntrySystem(OUString& rString, sal_Int32& nCheckPos, SvNumFormatType& nType,
131 sal_uInt32& nKey, LanguageType eLnge, LanguageType eNewLnge);
133 /** Similar to <method>PutEntry</method> and
134 <method>PutandConvertEntry</method> or
135 <method>PutandConvertEntrySystem</method>, the format code string
136 passed is considered to be of language/country eLnge. If
137 eLnge==LANGUAGE_SYSTEM the format code has to match eSysLnge, and if
138 eSysLnge is not the current application locale the format code is
139 converted to the current locale. Additionally, if the format code
140 represents an old "automatic" currency format, it is converted to the
141 new default currency format of the eLnge locale. The rString format
142 code passed as an argument may get adapted in case eLnge was used (or
143 is LANGUAGE_SYSTEM and eSysLnge is identical); in case it wasn't the
144 method works on a copy instead, otherwise the resulting string would
145 not match eSysLnge anymore.
147 <p> This method was introduced to handle the legacy currency formats of
148 the "autotbl.fmt" file used by Calc and Writer and convert them to
149 fixed currency codes of the actual currency. Note that in the case of
150 legacy currency formats no special attribution is converted, only the
151 default currency format of the locale is chosen, and that new fixed
152 currency codes are of course not converted to other currencies. The
153 method may also be used as a general method taking, converting and
154 inserting almost arbitrary format codes. To insert or use, for example,
155 the default currency format code matching the current locale, the
156 method could be called with<br/>
158 <code>
159 GetIndexPuttingAndConverting( "0 $", LANGUAGE_SYSTEM, LANGUAGE_ENGLISH_US, ...);
160 </code>
162 @return
163 The index key of the resulting number format. If the format code
164 was empty, could not be converted or has errors, the eLnge locale's
165 standard number format is chosen instead. The index key is
166 guaranteed to represent some valid number format. If
167 rNewInserted==false and rCheckPos>0 the format code has errors
168 and/or could not be converted.
170 sal_uInt32 GetIndexPuttingAndConverting(OUString& rString, LanguageType eLnge,
171 LanguageType eSysLnge, SvNumFormatType& rType,
172 bool& rNewInserted, sal_Int32& rCheckPos);
174 /** Create a format code string using format nIndex as a template and
175 applying other settings (passed from the dialog) */
176 OUString GenerateFormat(sal_uInt32 nIndex, LanguageType eLnge = LANGUAGE_DONTKNOW,
177 bool bThousand = false, bool IsRed = false, sal_uInt16 nPrecision = 0,
178 sal_uInt16 nLeadingCnt = 1);
180 /** Analyze an input string
181 @return
182 <TRUE/> if input is a number or is matching a format F_Index
183 F_Index is set to a matching format if number, the value is
184 returned in fOutNumber
185 <FALSE/> if input is not a number
187 bool IsNumberFormat(const OUString& sString, sal_uInt32& F_Index, double& fOutNumber,
188 SvNumInputOptions eInputOptions = SvNumInputOptions::NONE);
190 /// Format a number according to a format index, return string and color
191 void GetOutputString(const double& fOutNumber, sal_uInt32 nFIndex, OUString& sOutString,
192 const Color** ppColor, bool bUseStarFormat = false);
194 /** Format a string according to a format index, return string and color.
195 Formats only if the format code is of type text or the 4th subcode
196 of a format code is specified, otherwise sOutString will be == "" */
197 void GetOutputString(const OUString& sString, sal_uInt32 nFIndex, OUString& sOutString,
198 const Color** ppColor, bool bUseStarFormat = false);
200 /** Format a number according to the standard default format matching
201 the given format index. rOutString will be the real cell string (e.g.
202 a number rounded by the cell format, which rounded value is used
203 in the filtering condition now), instead of the EditFormat string
204 (e.g a not rounded value, which is visible during editing).*/
205 void GetInputLineString(const double& fOutNumber, sal_uInt32 nFIndex, OUString& rOutString,
206 bool bFiltering = false, bool bForceSystemLocale = false);
208 /** Format a number according to a format code string to be scanned.
209 @return
210 <FALSE/> if format code contains an error
211 <TRUE/> else, in which case the string and color are returned.
213 bool GetPreviewString(const OUString& sFormatString, double fPreviewNumber,
214 OUString& sOutString, const Color** ppColor, LanguageType eLnge,
215 bool bUseStarFormat = false);
217 /** Same as <method>GetPreviewString</method> but the format code string
218 may be either language/country eLnge or en_US english US */
219 bool GetPreviewStringGuess(const OUString& sFormatString, double fPreviewNumber,
220 OUString& sOutString, const Color** ppColor,
221 LanguageType eLnge = LANGUAGE_DONTKNOW);
223 /** Format a string according to a format code string to be scanned.
224 @return
225 <FALSE/> if format code contains an error
226 <TRUE/> else, in which case the string and color are returned.
228 bool GetPreviewString(const OUString& sFormatString, const OUString& sPreviewString,
229 OUString& sOutString, const Color** ppColor,
230 LanguageType eLnge = LANGUAGE_DONTKNOW);
232 /** Test whether the format code string is already present in container
233 @return
234 NUMBERFORMAT_ENTRY_NOT_FOUND if not found, else the format index.
236 sal_uInt32 TestNewString(const OUString& sFormatString, LanguageType eLnge = LANGUAGE_DONTKNOW);
238 /// Whether format index nFIndex is of type text or not
239 bool IsTextFormat(sal_uInt32 nFIndex) const;
241 /// Whether format index nFIndex has NatNum12 modifier
242 bool IsNatNum12(sal_uInt32 nFIndex) const;
244 /// Get additional info of a format index, e.g. for dialog box
245 void GetFormatSpecialInfo(sal_uInt32 nFormat, bool& bThousand, bool& IsRed,
246 sal_uInt16& nPrecision, sal_uInt16& nLeadingCnt);
248 /// Count of decimals
249 sal_uInt16 GetFormatPrecision(sal_uInt32 nFormat) const;
251 /// Count of integer digits
252 sal_uInt16 GetFormatIntegerDigits(sal_uInt32 nFormat) const;
254 /** Get additional info of a format code string, e.g. for dialog box.
255 Uses a temporary parse, if possible use only if format code is not
256 present in container yet, otherwise ineffective.
257 @return
258 0 if format code string parsed without errors, otherwise error
259 position (like nCheckPos on <method>PutEntry</method>)
261 sal_uInt32 GetFormatSpecialInfo(const OUString&, bool& bThousand, bool& IsRed,
262 sal_uInt16& nPrecision, sal_uInt16& nLeadingCnt,
263 LanguageType eLnge = LANGUAGE_DONTKNOW);
265 /// Get return string for Calc CELL() function, "G", "D1", ...
266 OUString GetCalcCellReturn(sal_uInt32 nFormat) const;
268 bool IsUserDefined(sal_uInt32 F_Index) const;
270 /// Check if format code string may be deleted by user
271 bool IsUserDefined(std::u16string_view sStr, LanguageType eLnge = LANGUAGE_DONTKNOW);
273 /** Return the format index of the format code string for language/country,
274 or NUMBERFORMAT_ENTRY_NOT_FOUND */
275 sal_uInt32 GetEntryKey(std::u16string_view sStr, LanguageType eLnge = LANGUAGE_DONTKNOW);
277 /// Return the format for a format index
278 const SvNumberformat* GetEntry(sal_uInt32 nKey) const;
280 /// Obtain substituted GetFormatEntry(), i.e. system formats.
281 const SvNumberformat* GetSubstitutedEntry(sal_uInt32 nKey, sal_uInt32& o_rNewKey) const;
283 /// Return the format index of the standard default number format for language/country
284 sal_uInt32 GetStandardIndex(LanguageType eLnge = LANGUAGE_DONTKNOW);
286 /// Return the format index of the default format of a type for language/country
287 sal_uInt32 GetStandardFormat(SvNumFormatType eType, LanguageType eLnge = LANGUAGE_DONTKNOW);
289 /** Return the format index of the default format of a type for language/country.
290 Maybe not the default format but a special builtin format, e.g. for
291 NF_TIME_HH_MMSS00, if that format is passed in nFIndex. */
292 sal_uInt32 GetStandardFormat(sal_uInt32 nFIndex, SvNumFormatType eType, LanguageType eLnge);
294 /** Return the format index of the default format of a type for language/country.
295 Maybe not the default format but a special builtin format, e.g. for
296 NF_TIME_HH_MMSS00, or NF_TIME_HH_MMSS if fNumber >= 1.0 */
297 sal_uInt32 GetStandardFormat(double fNumber, sal_uInt32 nFIndex, SvNumFormatType eType,
298 LanguageType eLnge);
300 /// Whether nFIndex is a special builtin format
301 bool IsSpecialStandardFormat(sal_uInt32 nFIndex, LanguageType eLnge);
303 /** Return a time format that best matches fNumber. */
304 sal_uInt32 GetTimeFormat(double fNumber, LanguageType eLnge, bool bForceDuration);
306 /** Return a format and type that best matches the value of fNumber if
307 fNumber is assumed to be a date, time or datetime value, but unknown
308 which. Originally introduced for Chart databrowser editor, probably
309 should not be used otherwise. */
310 sal_uInt32 GuessDateTimeFormat(SvNumFormatType& rType, double fNumber, LanguageType eLnge);
312 /** Return the corresponding edit format of a format.
314 nFIndex, eType and pFormat (if not nullptr) are assumed to match each
315 other / be of one format. The locale to use is obtained from pFormat,
316 if nullptr then LANGUAGE_SYSTEM is used. This can be overridden by
317 specifying eForLocale other than LANGUAGE_DONTKNOW.
319 sal_uInt32 GetEditFormat(double fNumber, sal_uInt32 nFIndex, SvNumFormatType eType,
320 SvNumberformat const* pFormat,
321 LanguageType eForLocale = LANGUAGE_DONTKNOW);
323 /// Return the reference date
324 const Date& GetNullDate() const;
325 /// Return the standard decimal precision
326 sal_uInt16 GetStandardPrec() const;
327 /// Return whether zero suppression is switched on
328 bool GetNoZero() const;
329 /** Get the type of a format (or css::util::NumberFormat::UNDEFINED if no entry),
330 but with css::util::NumberFormat::DEFINED masked out */
331 SvNumFormatType GetType(sal_uInt32 nFIndex) const;
333 /// As the name says
334 void ClearMergeTable();
335 /// Merge in all new entries from rNewTable and return a table of resulting new format indices
336 SvNumberFormatterIndexTable* MergeFormatter(SvNumberFormatter& rNewTable);
338 /// Whether a merge table is present or not
339 bool HasMergeFormatTable() const;
340 /// Return the new format index for an old format index, if a merge table exists
341 sal_uInt32 GetMergeFormatIndex(sal_uInt32 nOldFmt) const;
343 /** Convert the ugly old tools' Table type bloated with new'ed sal_uInt32
344 entries merge table to ::std::map with old index key and new index key.
345 @ATTENTION! Also clears the old table using ClearMergeTable() */
346 SvNumberFormatterMergeMap ConvertMergeTableToMap();
348 /** Return the format index of a builtin format for a specific language/country.
349 If nFormat is not a builtin format nFormat is returned. */
350 sal_uInt32 GetFormatForLanguageIfBuiltIn(sal_uInt32 nFormat,
351 LanguageType eLnge = LANGUAGE_DONTKNOW);
353 /** Return the format index for a builtin format of a specific language
354 @see NfIndexTableOffset
356 sal_uInt32 GetFormatIndex(NfIndexTableOffset, LanguageType eLnge = LANGUAGE_DONTKNOW);
358 /** Return enum index of a format index of a builtin format,
359 NF_INDEX_TABLE_ENTRIES if it's not a builtin format.
360 @see NfIndexTableOffset
362 NfIndexTableOffset GetIndexTableOffset(sal_uInt32 nFormat) const;
364 /** Set evaluation type and order of input date strings
365 @see NfEvalDateFormat
367 void SetEvalDateFormat(NfEvalDateFormat eEDF);
368 NfEvalDateFormat GetEvalDateFormat() const;
370 /** Set TwoDigitYearStart, how the input string scanner handles a two digit year.
371 Default from VCL: 1930, 30-99 19xx, 00-29 20xx
373 <p> Historically (prior to src513e) it was a two digit number determining
374 until which number the string scanner recognizes a year to be 20xx,
375 default <= 29 is used by SFX/OfaMiscCfg.
376 The name Year2000 is kept although the actual functionality is now a
377 TwoDigitYearStart which might be in any century.
379 void SetYear2000(sal_uInt16 nVal);
380 sal_uInt16 GetYear2000() const;
381 static sal_uInt16 GetYear2000Default();
383 sal_uInt16 ExpandTwoDigitYear(sal_uInt16 nYear) const;
384 static sal_uInt16 ExpandTwoDigitYear(sal_uInt16 nYear, sal_uInt16 nTwoDigitYearStart);
386 /// Return the decimal separator matching the locale of the given format
387 OUString GetFormatDecimalSep(sal_uInt32 nFormat) const;
389 /// Return the decimal separator matching the given locale / LanguageType.
390 OUString GetLangDecimalSep(LanguageType nLang) const;
392 static void resetTheCurrencyTable();
394 /// Return a NfCurrencyTable with pointers to <type>NfCurrencyEntry</type> entries
395 static const NfCurrencyTable& GetTheCurrencyTable();
397 /** Searches, according to the default locale currency, an entry of the
398 CurrencyTable which is <bold>not</bold> the first (LANGUAGE_SYSTEM) entry.
399 @return
400 <NULL/> if not found
401 else pointer to NfCurrencyEntry
403 static const NfCurrencyEntry* MatchSystemCurrency();
405 /** Return a NfCurrencyEntry matching a language/country.
406 If language/country is LANGUAGE_SYSTEM a <method>MatchSystemCurrency</method>
407 call is tried to get an entry. If that fails or the corresponding
408 language/country is not present the entry for LANGUAGE_SYSTEM is returned.
410 static const NfCurrencyEntry& GetCurrencyEntry(LanguageType);
412 /** Return a NfCurrencyEntry pointer matching a language/country
413 and currency abbreviation (AKA banking symbol).
414 This method is meant for the configuration of the default currency.
415 @return
416 <NULL/> if not found
417 else pointer to NfCurrencyEntry
419 static const NfCurrencyEntry* GetCurrencyEntry(std::u16string_view rAbbrev, LanguageType eLang);
421 /** Return a NfCurrencyEntry pointer matching the symbol
422 combination of a LegacyOnly currency. Note that this means only that
423 the currency matching both symbols was once used in the Office, but is
424 not offered in dialogs anymore. It doesn't even mean that the currency
425 symbol combination is valid, since the reason for removing it may have
426 been just that. #i61657#
427 @return
428 A matching entry, or else <NULL/>.
430 static const NfCurrencyEntry* GetLegacyOnlyCurrencyEntry(std::u16string_view rSymbol,
431 std::u16string_view rAbbrev);
433 /** Set the default system currency. The combination of abbreviation and
434 language must match an existent element of theCurrencyTable. If not,
435 the SYSTEM (current locale) entry becomes the default.
436 This method is meant for the configuration of the default currency.
438 static void SetDefaultSystemCurrency(std::u16string_view rAbbrev, LanguageType eLang);
440 /** Get all standard formats for a specific currency, formats are
441 appended to the NfWSStringsDtor list.
442 @param bBank
443 <TRUE/>: generate only format strings with currency abbreviation
444 <FALSE/>: mixed format strings
445 @return
446 position of default format
448 sal_uInt16 GetCurrencyFormatStrings(NfWSStringsDtor&, const NfCurrencyEntry&, bool bBank) const;
450 /** Whether nFormat is of type css::util::NumberFormat::CURRENCY and the format code
451 contains a new SYMBOLTYPE_CURRENCY and if so which one [$xxx-nnn].
452 If ppEntry is not NULL and exactly one entry is found, a [$xxx-nnn] is
453 returned, even if the format code only contains [$xxx] !
455 bool GetNewCurrencySymbolString(sal_uInt32 nFormat, OUString& rSymbol,
456 const NfCurrencyEntry** ppEntry, bool* pBank = nullptr) const;
458 /** Look up the corresponding NfCurrencyEntry matching
459 rSymbol (may be CurrencySymbol or CurrencyAbbreviation) and possibly
460 a rExtension (being yyy of [$xxx-yyy]) or a given language/country
461 value. Tries to match a rSymbol with rExtension first, then with
462 eFormatLanguage, then rSymbol only. This is because a currency entry
463 might have been constructed using I18N locale data where a used locale
464 of a currency format code must not necessarily match the locale of
465 the locale data itself, e.g. [$HK$-40C] (being "zh_HK" locale) in
466 zh_CN locale data. Here the rExtension would have the value 0x40c but
467 eFormatLanguage of the number format would have the value of zh_CN
468 locale, the value with which the corresponding CurrencyEntry is
469 constructed.
471 @param bFoundBank
472 Only used for output.
473 If the return value is not <NULL/> this value is set to <TRUE/> if
474 the matching entry was found by comparing rSymbol against the
475 CurrencyAbbreviation (AKA BankSymbol).
476 If the return value is <NULL/> the value of bFoundBank is undefined.
477 @param rSymbol
478 Currency symbol, preferably obtained of a format by a call to
479 <method>SvNumberformat::GetNewCurrencySymbol()</method>
480 @param rExtension
481 Currency extension, preferably obtained of a format by a call to
482 <method>SvNumberformat::GetNewCurrencySymbol()</method>
483 @param eFormatLanguage
484 The language/country value of the format of which rSymbol and
485 rExtension are obtained (<method>SvNumberformat::GetLanguage()</method>).
486 @param bOnlyStringLanguage
487 If <TRUE/> only entries with language/country of rExtension are
488 checked, no match on eFormatLanguage. If rExtension is empty all
489 entries are checked.
490 @return
491 The matching entry if unique (in which case bFoundBank is set),
492 else <NULL/>.
494 static const NfCurrencyEntry* GetCurrencyEntry(bool& bFoundBank, std::u16string_view rSymbol,
495 std::u16string_view rExtension,
496 LanguageType eFormatLanguage,
497 bool bOnlyStringLanguage = false);
499 /// Get compatibility ("automatic" old style) currency from I18N locale data
500 void GetCompatibilityCurrency(OUString& rSymbol, OUString& rAbbrev) const;
502 /// Fill rList with the language/country codes that have been allocated
503 void GetUsedLanguages(std::vector<LanguageType>& rList);
505 /// Fill a NfKeywordIndex table with keywords of a language/country
506 void FillKeywordTable(NfKeywordTable& rKeywords, LanguageType eLang);
508 /** Fill a NfKeywordIndex table with keywords usable in Excel export with
509 GetFormatStringForExcel() or SvNumberformat::GetMappedFormatstring() */
510 void FillKeywordTableForExcel(NfKeywordTable& rKeywords);
512 /** Return a format code string suitable for Excel export.
514 @param rTempFormatter
515 SvNumberFormatter to use if a non-en-US format code needs to be
516 converted and put, should not be the same formatter to not
517 pollute the entries of this one here.
519 OUString GetFormatStringForExcel(sal_uInt32 nKey, const NfKeywordTable& rKeywords,
520 SvNumberFormatter& rTempFormatter) const;
522 /** Return a keyword for a language/country and NfKeywordIndex
523 for XML import, to generate number format strings. */
524 OUString GetKeyword(LanguageType eLnge, sal_uInt16 nIndex);
526 /** Return the GENERAL keyword in proper case ("General") for a
527 language/country, used in XML import */
528 OUString GetStandardName(LanguageType eLnge);
530 /** Check if a specific locale has supported locale data. */
531 static bool IsLocaleInstalled(LanguageType eLang);
533 /** Obtain NfKeywordTable used with a format, possibly localized.
535 XXX NOTE: the content (actual keywords) is only valid as long as the
536 locale context of the associated ImpSvNumberformatScan instance does
537 not change to a locale with different keywords, which may happen
538 anytime with a call (implicit or explicit) to
539 SvNumberFormatter::ChangeIntl(). If needed longer, copy-create another
540 NfKeywordTable instance or copy individual elements.
542 If the format specified with nKey does not exist, the content of the
543 NfKeywordTable matches the locale with which the SvNumberFormatter
544 instance was created and initialized.
546 This function preliminary exists for unit tests and otherwise is
547 pretty much useless.
549 const NfKeywordTable& GetKeywords(sal_uInt32 nKey);
551 /** Access for unit tests. */
552 const NfKeywordTable& GetEnglishKeywords() const;
554 /** Access for unit tests. */
555 const std::vector<Color>& GetStandardColors() const;
557 /** Access for unit tests. */
558 size_t GetMaxDefaultColors() const;
560 struct InputScannerPrivateAccess
562 friend class ImpSvNumberInputScan;
564 private:
565 InputScannerPrivateAccess() {}
567 /** Access for input scanner to temporarily (!) switch locales. */
568 OnDemandLocaleDataWrapper& GetOnDemandLocaleDataWrapper(const InputScannerPrivateAccess&)
570 return xLocaleData;
573 private:
574 mutable ::osl::Mutex m_aMutex;
575 css::uno::Reference<css::uno::XComponentContext> m_xContext;
576 LanguageTag maLanguageTag;
577 std::map<sal_uInt32, std::unique_ptr<SvNumberformat>>
578 aFTable; // Table of format keys to format entries
579 typedef std::map<sal_uInt32, sal_uInt32> DefaultFormatKeysMap;
580 DefaultFormatKeysMap aDefaultFormatKeys; // Table of default standard to format keys
581 std::unique_ptr<SvNumberFormatTable> pFormatTable; // For the UI dialog
582 std::unique_ptr<SvNumberFormatterIndexTable>
583 pMergeTable; // List of indices for merging two formatters
584 OnDemandCharClass xCharClass; // CharacterClassification
585 OnDemandLocaleDataWrapper xLocaleData; // LocaleData switched between SYSTEM, ENGLISH and other
586 OnDemandTransliterationWrapper xTransliteration; // Transliteration loaded on demand
587 OnDemandCalendarWrapper xCalendar; // Calendar loaded on demand
588 OnDemandNativeNumberWrapper xNatNum; // Native number service loaded on demand
589 std::unique_ptr<ImpSvNumberInputScan> pStringScanner; // Input string scanner
590 std::unique_ptr<ImpSvNumberformatScan> pFormatScanner; // Format code string scanner
591 Link<sal_uInt16, Color*> aColorLink; // User defined color table CallBack
592 sal_uInt32 MaxCLOffset; // Max language/country offset used
593 sal_uInt32 nDefaultSystemCurrencyFormat; // NewCurrency matching SYSTEM locale
594 LanguageType IniLnge; // Initialized setting language/country
595 LanguageType ActLnge; // Current setting language/country
596 NfEvalDateFormat eEvalDateFormat; // DateFormat evaluation
597 bool bNoZero; // Zero value suppression
599 // cached locale data items needed almost any time
600 OUString aDecimalSep;
601 OUString aDecimalSepAlt;
602 OUString aThousandSep;
603 OUString aDateSep;
605 SVL_DLLPRIVATE static volatile bool bCurrencyTableInitialized;
606 SVL_DLLPRIVATE static sal_uInt16 nSystemCurrencyPosition;
607 SVL_DLLPRIVATE static SvNumberFormatterRegistry_Impl* pFormatterRegistry;
609 // get the registry, create one if none exists
610 SVL_DLLPRIVATE static SvNumberFormatterRegistry_Impl& GetFormatterRegistry();
612 // called by ctors
613 SVL_DLLPRIVATE void ImpConstruct(LanguageType eLang);
615 // Generate builtin formats provided by i18n behind CLOffset,
616 // if bNoAdditionalFormats==false also generate additional i18n formats.
617 SVL_DLLPRIVATE void ImpGenerateFormats(sal_uInt32 CLOffset, bool bNoAdditionalFormats);
619 // Generate additional formats provided by i18n
620 SVL_DLLPRIVATE void ImpGenerateAdditionalFormats(
621 sal_uInt32 CLOffset,
622 css::uno::Reference<css::i18n::XNumberFormatCode> const& rNumberFormatCode,
623 bool bAfterChangingSystemCL);
625 SVL_DLLPRIVATE SvNumberformat* ImpInsertFormat(const css::i18n::NumberFormatCode& rCode,
626 sal_uInt32 nPos,
627 bool bAfterChangingSystemCL = false,
628 sal_Int16 nOrgIndex = 0);
630 // Return CLOffset or (MaxCLOffset + SV_COUNTRY_LANGUAGE_OFFSET) if new language/country
631 SVL_DLLPRIVATE sal_uInt32 ImpGetCLOffset(LanguageType eLnge) const;
633 // Test whether format code already exists, then return index key,
634 // otherwise NUMBERFORMAT_ENTRY_NOT_FOUND
635 SVL_DLLPRIVATE sal_uInt32 ImpIsEntry(std::u16string_view rString, sal_uInt32 CLOffset,
636 LanguageType eLnge);
638 // Create builtin formats for language/country if necessary, return CLOffset
639 SVL_DLLPRIVATE sal_uInt32 ImpGenerateCL(LanguageType eLnge);
641 // Create theCurrencyTable with all <type>NfCurrencyEntry</type>
642 SVL_DLLPRIVATE static void ImpInitCurrencyTable();
644 // Return the format index of the currency format of the system locale.
645 // Format is created if not already present.
646 SVL_DLLPRIVATE sal_uInt32 ImpGetDefaultSystemCurrencyFormat();
648 // Return the format index of the currency format of the current locale.
649 // Format is created if not already present.
650 SVL_DLLPRIVATE sal_uInt32 ImpGetDefaultCurrencyFormat();
652 // Return the default format for a given type and current locale.
653 // May ONLY be called from within GetStandardFormat().
654 SVL_DLLPRIVATE sal_uInt32 ImpGetDefaultFormat(SvNumFormatType nType);
656 // Return the index in a sequence of format codes matching an enum of
657 // NfIndexTableOffset. If not found 0 is returned. If the sequence doesn't
658 // contain any format code elements a default element is created and inserted.
659 SVL_DLLPRIVATE sal_Int32 ImpGetFormatCodeIndex(
660 css::uno::Sequence<css::i18n::NumberFormatCode>& rSeq, const NfIndexTableOffset nTabOff);
662 // Adjust a sequence of format codes to contain only one (THE) default
663 // instead of multiple defaults for short/medium/long types.
664 // If there is no medium but a short and a long default the long is taken.
665 // Non-PRODUCT version may check locale data for matching defaults in one
666 // FormatElement group.
667 SVL_DLLPRIVATE void ImpAdjustFormatCodeDefault(css::i18n::NumberFormatCode* pFormatArr,
668 sal_Int32 nCount);
670 // Obtain the format entry for a given key index.
671 SVL_DLLPRIVATE SvNumberformat* GetFormatEntry(sal_uInt32 nKey);
672 SVL_DLLPRIVATE const SvNumberformat* GetFormatEntry(sal_uInt32 nKey) const;
674 // used as a loop body inside of GetNewCurrencySymbolString() and GetCurrencyEntry()
675 static bool ImpLookupCurrencyEntryLoopBody(const NfCurrencyEntry*& pFoundEntry,
676 bool& bFoundBank, const NfCurrencyEntry* pData,
677 sal_uInt16 nPos, std::u16string_view rSymbol);
679 // link to be set at <method>SvtSysLocaleOptions::SetCurrencyChangeLink()</method>
680 DECL_DLLPRIVATE_STATIC_LINK(SvNumberFormatter, CurrencyChangeLink, LinkParamNone*, void);
682 // return position of a special character
683 sal_Int32 ImpPosToken(const OUStringBuffer& sFormat, sal_Unicode token,
684 sal_Int32 nStartPos = 0) const;
686 // Substitute a format during GetFormatEntry(), i.e. system formats.
687 SvNumberformat* ImpSubstituteEntry(SvNumberformat* pFormat, sal_uInt32* o_pRealKey = nullptr);
689 // own mutex, may also be used by internal class SvNumberFormatterRegistry_Impl
690 static ::osl::Mutex& GetGlobalMutex();
691 ::osl::Mutex& GetInstanceMutex() const { return m_aMutex; }
693 public:
694 // called by SvNumberFormatterRegistry_Impl::Notify if the default system currency changes
695 void ResetDefaultSystemCurrency();
697 // Called by SvNumberFormatterRegistry_Impl::Notify if the system locale's
698 // date acceptance patterns change.
699 void InvalidateDateAcceptancePatterns();
701 // Replace the SYSTEM language/country format codes. Called upon change of
702 // the user configurable locale.
703 // Old compatibility codes are replaced, user defined are converted, and
704 // new format codes are appended.
705 void ReplaceSystemCL(LanguageType eOldLanguage);
707 const css::uno::Reference<css::uno::XComponentContext>& GetComponentContext() const;
709 //! The following method is not to be used from outside but must be
710 //! public for the InputScanner.
711 // return the current FormatScanner
712 const ImpSvNumberformatScan* GetFormatScanner() const;
714 //! The following methods are not to be used from outside but must be
715 //! public for the InputScanner and FormatScanner.
717 // return current (!) Locale
718 const LanguageTag& GetLanguageTag() const;
720 // return corresponding Transliteration wrapper
721 const ::utl::TransliterationWrapper* GetTransliteration() const;
723 // return the corresponding CharacterClassification wrapper
724 const CharClass* GetCharClass() const;
726 // return the corresponding LocaleData wrapper
727 const LocaleDataWrapper* GetLocaleData() const;
729 // return the corresponding Calendar wrapper
730 CalendarWrapper* GetCalendar() const;
732 // return the corresponding NativeNumberSupplier wrapper
733 const NativeNumberWrapper* GetNatNum() const;
735 // cached locale data items
737 // return the corresponding decimal separator
738 const OUString& GetNumDecimalSep() const;
740 // return the corresponding decimal separator alternative
741 const OUString& GetNumDecimalSepAlt() const;
743 // return the corresponding group (AKA thousand) separator
744 const OUString& GetNumThousandSep() const;
746 // return the corresponding date separator
747 const OUString& GetDateSep() const;
749 // checks for decimal separator and optional alternative
750 bool IsDecimalSep(std::u16string_view rStr) const;
753 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */