/src/libreoffice/include/svl/numformat.hxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | #pragma once |
20 | | |
21 | | #include <svl/svldllapi.h> |
22 | | |
23 | | #include <svl/nfengine.hxx> |
24 | | #include <svl/nfkeytab.hxx> |
25 | | #include <tools/link.hxx> |
26 | | |
27 | | class SvNumberFormatterRegistry_Impl; |
28 | | class NfCurrencyTable; |
29 | | |
30 | | class SVL_DLLPUBLIC SvNumberFormatter |
31 | | { |
32 | | friend class SvNumberFormatterRegistry_Impl; |
33 | | |
34 | | public: |
35 | | /** |
36 | | * We can't technically have an "infinite" value, so we use an arbitrary |
37 | | * upper precision threshold to represent the "unlimited" precision. |
38 | | */ |
39 | | static const sal_uInt16 UNLIMITED_PRECISION; |
40 | | |
41 | | /** |
42 | | * Precision suitable for numbers displayed in input bar, for instance |
43 | | * Calc's formula input bar. |
44 | | */ |
45 | | static const sal_uInt16 INPUTSTRING_PRECISION; |
46 | | |
47 | | /// ctor with service manager and language/country enum |
48 | | SvNumberFormatter(const css::uno::Reference<css::uno::XComponentContext>& rxContext, |
49 | | LanguageType eLang); |
50 | | |
51 | | ~SvNumberFormatter(); |
52 | | |
53 | | /// Set CallBack to ColorTable |
54 | | void SetColorLink(const Link<sal_uInt16, Color*>& rColorTableCallBack); |
55 | | /// Do the CallBack to ColorTable |
56 | | Color* GetUserDefColor(sal_uInt16 nIndex) const; |
57 | | |
58 | | /// Change language/country, also input and format scanner |
59 | | void ChangeIntl(LanguageType eLnge); |
60 | | /// Change the reference null date |
61 | | void ChangeNullDate(sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear); |
62 | | /// Change standard precision |
63 | | void ChangeStandardPrec(short nPrec); |
64 | | /// Set zero value suppression |
65 | | void SetNoZero(bool bNZ); |
66 | | |
67 | | /** The language with which the formatter was initialized (system setting), |
68 | | NOT the current language after a ChangeIntl() */ |
69 | | LanguageType GetLanguage() const; |
70 | | |
71 | | // Determine whether two format types are input compatible or not |
72 | | static bool IsCompatible(SvNumFormatType eOldType, SvNumFormatType eNewType); |
73 | | |
74 | | /** Get table of formats of a specific type of a locale. A format FIndex is |
75 | | tested whether it has the type and locale requested, if it doesn't |
76 | | match FIndex returns the default format for the type/locale. If no |
77 | | specific format is to be selected FIndex may be initialized to 0. */ |
78 | | SvNumberFormatTable& GetEntryTable(SvNumFormatType eType, sal_uInt32& FIndex, |
79 | | LanguageType eLnge); |
80 | | |
81 | | /** Get table of formats of a specific type of a language/country. |
82 | | FIndex returns the default format of that type. |
83 | | If the language/country was never touched before new entries are generated */ |
84 | | SvNumberFormatTable& ChangeCL(SvNumFormatType eType, sal_uInt32& FIndex, LanguageType eLnge); |
85 | | |
86 | | /** Get table of formats of the same type as FIndex; eType and rLnge are |
87 | | set accordingly. An unknown format is set to Standard/General */ |
88 | | SvNumberFormatTable& GetFirstEntryTable(SvNumFormatType& eType, sal_uInt32& FIndex, |
89 | | LanguageType& rLnge); |
90 | | |
91 | | /// Delete an entry including the format it is referring to |
92 | | void DeleteEntry(sal_uInt32 nKey); |
93 | | |
94 | | /** Create new entry of a format code string for language/country. |
95 | | @return |
96 | | <TRUE/> if string new and ok and inserted. |
97 | | <FALSE/> if string already exists or an unresolvable parse error |
98 | | occurred, in which case nCheckPos is the error position within rString. |
99 | | If the error occurs at position 0 or rString is empty nCheckPos |
100 | | will be 1, so an error in the string is always indicated by |
101 | | nCheckPos not being zero. |
102 | | The content of the rString variable can be changed and corrected |
103 | | by the method. |
104 | | nType contains the type of the format. |
105 | | nKey contains the index key of the format. |
106 | | */ |
107 | | bool PutEntry(OUString& rString, sal_Int32& nCheckPos, SvNumFormatType& nType, sal_uInt32& nKey, |
108 | | LanguageType eLnge = LANGUAGE_DONTKNOW, bool bReplaceBooleanEquivalent = true); |
109 | | |
110 | | /** Same as <method>PutEntry</method> but the format code string is |
111 | | considered to be of language/country eLnge and is converted to |
112 | | language/country eNewLnge */ |
113 | | bool PutandConvertEntry(OUString& rString, sal_Int32& nCheckPos, SvNumFormatType& nType, |
114 | | sal_uInt32& nKey, LanguageType eLnge, LanguageType eNewLnge, |
115 | | bool bConvertDateOrder, bool bReplaceBooleanEquivalent = true); |
116 | | |
117 | | /** Same as <method>PutandConvertEntry</method> but the format code string |
118 | | is considered to be of the System language/country eLnge and is |
119 | | converted to another System language/country eNewLnge. In this case |
120 | | the automatic currency is converted too. */ |
121 | | bool PutandConvertEntrySystem(OUString& rString, sal_Int32& nCheckPos, SvNumFormatType& nType, |
122 | | sal_uInt32& nKey, LanguageType eLnge, LanguageType eNewLnge); |
123 | | |
124 | | /** Similar to <method>PutEntry</method> and |
125 | | <method>PutandConvertEntry</method> or |
126 | | <method>PutandConvertEntrySystem</method>, the format code string |
127 | | passed is considered to be of language/country eLnge. If |
128 | | eLnge==LANGUAGE_SYSTEM the format code has to match eSysLnge, and if |
129 | | eSysLnge is not the current application locale the format code is |
130 | | converted to the current locale. Additionally, if the format code |
131 | | represents an old "automatic" currency format, it is converted to the |
132 | | new default currency format of the eLnge locale. The rString format |
133 | | code passed as an argument may get adapted in case eLnge was used (or |
134 | | is LANGUAGE_SYSTEM and eSysLnge is identical); in case it wasn't the |
135 | | method works on a copy instead, otherwise the resulting string would |
136 | | not match eSysLnge anymore. |
137 | | |
138 | | <p> This method was introduced to handle the legacy currency formats of |
139 | | the "autotbl.fmt" file used by Calc and Writer and convert them to |
140 | | fixed currency codes of the actual currency. Note that in the case of |
141 | | legacy currency formats no special attribution is converted, only the |
142 | | default currency format of the locale is chosen, and that new fixed |
143 | | currency codes are of course not converted to other currencies. The |
144 | | method may also be used as a general method taking, converting and |
145 | | inserting almost arbitrary format codes. To insert or use, for example, |
146 | | the default currency format code matching the current locale, the |
147 | | method could be called with<br/> |
148 | | |
149 | | <code> |
150 | | GetIndexPuttingAndConverting( "0 $", LANGUAGE_SYSTEM, LANGUAGE_ENGLISH_US, ...); |
151 | | </code> |
152 | | |
153 | | @return |
154 | | The index key of the resulting number format. If the format code |
155 | | was empty, could not be converted or has errors, the eLnge locale's |
156 | | standard number format is chosen instead. The index key is |
157 | | guaranteed to represent some valid number format. If |
158 | | rNewInserted==false and rCheckPos>0 the format code has errors |
159 | | and/or could not be converted. |
160 | | */ |
161 | | sal_uInt32 GetIndexPuttingAndConverting(OUString& rString, LanguageType eLnge, |
162 | | LanguageType eSysLnge, SvNumFormatType& rType, |
163 | | bool& rNewInserted, sal_Int32& rCheckPos); |
164 | | |
165 | | /** Create a format code string using format nIndex as a template and |
166 | | applying other settings (passed from the dialog) */ |
167 | | OUString GenerateFormat(sal_uInt32 nIndex, LanguageType eLnge = LANGUAGE_DONTKNOW, |
168 | | bool bThousand = false, bool IsRed = false, sal_uInt16 nPrecision = 0, |
169 | | sal_uInt16 nLeadingCnt = 1); |
170 | | |
171 | | /** Analyze an input string |
172 | | @return |
173 | | <TRUE/> if input is a number or is matching a format F_Index |
174 | | F_Index is set to a matching format if number, the value is |
175 | | returned in fOutNumber |
176 | | <FALSE/> if input is not a number |
177 | | */ |
178 | | bool IsNumberFormat(const OUString& sString, sal_uInt32& F_Index, double& fOutNumber, |
179 | | SvNumInputOptions eInputOptions = SvNumInputOptions::NONE); |
180 | | |
181 | | /// Format a number according to a format index, return string and color |
182 | | void GetOutputString(const double& fOutNumber, sal_uInt32 nFIndex, OUString& sOutString, |
183 | | const Color** ppColor, bool bUseStarFormat = false); |
184 | | |
185 | | /** Format a string according to a format index, return string and color. |
186 | | Formats only if the format code is of type text or the 4th subcode |
187 | | of a format code is specified, otherwise sOutString will be == "" */ |
188 | | void GetOutputString(const OUString& sString, sal_uInt32 nFIndex, OUString& sOutString, |
189 | | const Color** ppColor, bool bUseStarFormat = false); |
190 | | |
191 | | /** Format a number according to the standard default format matching |
192 | | the given format index. rOutString will be the real cell string (e.g. |
193 | | a number rounded by the cell format, which rounded value is used |
194 | | in the filtering condition now), instead of the EditFormat string |
195 | | (e.g a not rounded value, which is visible during editing).*/ |
196 | | OUString GetInputLineString(const double& fOutNumber, sal_uInt32 nFIndex, |
197 | | bool bFiltering = false, bool bForceSystemLocale = false); |
198 | | |
199 | | /** Format a number according to a format code string to be scanned. |
200 | | @return |
201 | | <FALSE/> if format code contains an error |
202 | | <TRUE/> else, in which case the string and color are returned. |
203 | | */ |
204 | | bool GetPreviewString(const OUString& sFormatString, double fPreviewNumber, |
205 | | OUString& sOutString, const Color** ppColor, LanguageType eLnge, |
206 | | bool bUseStarFormat = false); |
207 | | |
208 | | /** Same as <method>GetPreviewString</method> but the format code string |
209 | | may be either language/country eLnge or en_US english US */ |
210 | | bool GetPreviewStringGuess(const OUString& sFormatString, double fPreviewNumber, |
211 | | OUString& sOutString, const Color** ppColor, |
212 | | LanguageType eLnge = LANGUAGE_DONTKNOW); |
213 | | |
214 | | /** Format a string according to a format code string to be scanned. |
215 | | @return |
216 | | <FALSE/> if format code contains an error |
217 | | <TRUE/> else, in which case the string and color are returned. |
218 | | */ |
219 | | bool GetPreviewString(const OUString& sFormatString, const OUString& sPreviewString, |
220 | | OUString& sOutString, const Color** ppColor, |
221 | | LanguageType eLnge = LANGUAGE_DONTKNOW); |
222 | | |
223 | | /** Test whether the format code string is already present in container |
224 | | @return |
225 | | NUMBERFORMAT_ENTRY_NOT_FOUND if not found, else the format index. |
226 | | */ |
227 | | sal_uInt32 TestNewString(const OUString& sFormatString, LanguageType eLnge = LANGUAGE_DONTKNOW); |
228 | | |
229 | | /// Whether format index nFIndex is of type text or not |
230 | | bool IsTextFormat(sal_uInt32 nFIndex) const; |
231 | | |
232 | | /// Whether format index nFIndex has NatNum12 modifier |
233 | | bool IsNatNum12(sal_uInt32 nFIndex) const; |
234 | | |
235 | | /// Get additional info of a format index, e.g. for dialog box |
236 | | void GetFormatSpecialInfo(sal_uInt32 nFormat, bool& bThousand, bool& IsRed, |
237 | | sal_uInt16& nPrecision, sal_uInt16& nLeadingCnt); |
238 | | |
239 | | /// Count of decimals |
240 | | sal_uInt16 GetFormatPrecision(sal_uInt32 nFormat); |
241 | | |
242 | | /// Count of integer digits |
243 | | sal_uInt16 GetFormatIntegerDigits(sal_uInt32 nFormat) const; |
244 | | |
245 | | /** Get additional info of a format code string, e.g. for dialog box. |
246 | | Uses a temporary parse, if possible use only if format code is not |
247 | | present in container yet, otherwise ineffective. |
248 | | @return |
249 | | 0 if format code string parsed without errors, otherwise error |
250 | | position (like nCheckPos on <method>PutEntry</method>) |
251 | | */ |
252 | | sal_uInt32 GetFormatSpecialInfo(const OUString&, bool& bThousand, bool& IsRed, |
253 | | sal_uInt16& nPrecision, sal_uInt16& nLeadingCnt, |
254 | | LanguageType eLnge = LANGUAGE_DONTKNOW); |
255 | | |
256 | | /// Get return string for Calc CELL() function, "G", "D1", ... |
257 | | OUString GetCalcCellReturn(sal_uInt32 nFormat) const; |
258 | | |
259 | | bool IsUserDefined(sal_uInt32 F_Index) const; |
260 | | |
261 | | /// Check if format code string may be deleted by user |
262 | | bool IsUserDefined(std::u16string_view sStr, LanguageType eLnge = LANGUAGE_DONTKNOW); |
263 | | |
264 | | /** Return the format index of the format code string for language/country, |
265 | | or NUMBERFORMAT_ENTRY_NOT_FOUND */ |
266 | | sal_uInt32 GetEntryKey(std::u16string_view sStr, LanguageType eLnge = LANGUAGE_DONTKNOW); |
267 | | |
268 | | /// Return the format for a format index |
269 | | const SvNumberformat* GetEntry(sal_uInt32 nKey) const; |
270 | | |
271 | | /// Obtain substituted GetFormatEntry(), i.e. system formats. |
272 | | const SvNumberformat* GetSubstitutedEntry(sal_uInt32 nKey, sal_uInt32& o_rNewKey); |
273 | | |
274 | | /// Return the format index of the standard default number format for language/country |
275 | | sal_uInt32 GetStandardIndex(LanguageType eLnge = LANGUAGE_DONTKNOW); |
276 | | |
277 | | /// Return the format index of the default format of a type for language/country |
278 | | sal_uInt32 GetStandardFormat(SvNumFormatType eType, LanguageType eLnge = LANGUAGE_DONTKNOW); |
279 | | |
280 | | /** Return the format index of the default format of a type for language/country. |
281 | | Maybe not the default format but a special builtin format, e.g. for |
282 | | NF_TIME_HH_MMSS00, if that format is passed in nFIndex. */ |
283 | | sal_uInt32 GetStandardFormat(sal_uInt32 nFIndex, SvNumFormatType eType, LanguageType eLnge); |
284 | | |
285 | | /** Return the format index of the default format of a type for language/country. |
286 | | Maybe not the default format but a special builtin format, e.g. for |
287 | | NF_TIME_HH_MMSS00, or NF_TIME_HH_MMSS if fNumber >= 1.0 */ |
288 | | sal_uInt32 GetStandardFormat(double fNumber, sal_uInt32 nFIndex, SvNumFormatType eType, |
289 | | LanguageType eLnge); |
290 | | |
291 | | /** Return a time format that best matches fNumber. */ |
292 | | sal_uInt32 GetTimeFormat(double fNumber, LanguageType eLnge, bool bForceDuration); |
293 | | |
294 | | /** Return a format and type that best matches the value of fNumber if |
295 | | fNumber is assumed to be a date, time or datetime value, but unknown |
296 | | which. Originally introduced for Chart databrowser editor, probably |
297 | | should not be used otherwise. */ |
298 | | sal_uInt32 GuessDateTimeFormat(SvNumFormatType& rType, double fNumber, LanguageType eLnge); |
299 | | |
300 | | /** Return the corresponding edit format of a format. |
301 | | |
302 | | nFIndex, eType and pFormat (if not nullptr) are assumed to match each |
303 | | other / be of one format. The locale to use is obtained from pFormat, |
304 | | if nullptr then LANGUAGE_SYSTEM is used. This can be overridden by |
305 | | specifying eForLocale other than LANGUAGE_DONTKNOW. |
306 | | */ |
307 | | sal_uInt32 GetEditFormat(double fNumber, sal_uInt32 nFIndex, SvNumFormatType eType, |
308 | | SvNumberformat const* pFormat, |
309 | | LanguageType eForLocale = LANGUAGE_DONTKNOW); |
310 | | |
311 | | /// Return the reference date |
312 | | const Date& GetNullDate() const; |
313 | | /// Return the standard decimal precision |
314 | | sal_uInt16 GetStandardPrec() const; |
315 | | /// Return whether zero suppression is switched on |
316 | | bool GetNoZero() const; |
317 | | /** Get the type of a format (or css::util::NumberFormat::UNDEFINED if no entry), |
318 | | but with css::util::NumberFormat::DEFINED masked out */ |
319 | | SvNumFormatType GetType(sal_uInt32 nFIndex) const; |
320 | | |
321 | | /// As the name says |
322 | | void ClearMergeTable(); |
323 | | /// Merge in all new entries from rNewTable and return a table of resulting new format indices |
324 | | SvNumberFormatterIndexTable* MergeFormatter(SvNumberFormatter& rNewTable); |
325 | | |
326 | | /// Whether a merge table is present or not |
327 | | bool HasMergeFormatTable() const; |
328 | | /// Return the new format index for an old format index, if a merge table exists |
329 | | sal_uInt32 GetMergeFormatIndex(sal_uInt32 nOldFmt) const; |
330 | | |
331 | | /** Convert the ugly old tools' Table type bloated with new'ed sal_uInt32 |
332 | | entries merge table to ::std::map with old index key and new index key. |
333 | | @ATTENTION! Also clears the old table using ClearMergeTable() */ |
334 | | SvNumberFormatterMergeMap ConvertMergeTableToMap(); |
335 | | |
336 | | /** Return the format index of a builtin format for a specific language/country. |
337 | | If nFormat is not a builtin format nFormat is returned. */ |
338 | | sal_uInt32 GetFormatForLanguageIfBuiltIn(sal_uInt32 nFormat, |
339 | | LanguageType eLnge = LANGUAGE_DONTKNOW); |
340 | | |
341 | | /** Return the format index for a builtin format of a specific language |
342 | | @see NfIndexTableOffset |
343 | | */ |
344 | | sal_uInt32 GetFormatIndex(NfIndexTableOffset, LanguageType eLnge = LANGUAGE_DONTKNOW); |
345 | | |
346 | | /** Return enum index of a format index of a builtin format, |
347 | | NF_INDEX_TABLE_ENTRIES if it's not a builtin format. |
348 | | @see NfIndexTableOffset |
349 | | */ |
350 | | static NfIndexTableOffset GetIndexTableOffset(sal_uInt32 nFormat); |
351 | | |
352 | | /** Set evaluation type and order of input date strings |
353 | | @see NfEvalDateFormat |
354 | | */ |
355 | | void SetEvalDateFormat(NfEvalDateFormat eEDF); |
356 | | NfEvalDateFormat GetEvalDateFormat() const; |
357 | | |
358 | | /** Set TwoDigitYearStart, how the input string scanner handles a two digit year. |
359 | | Default from VCL: 1930, 30-99 19xx, 00-29 20xx |
360 | | |
361 | | <p> Historically (prior to src513e) it was a two digit number determining |
362 | | until which number the string scanner recognizes a year to be 20xx, |
363 | | default <= 29 is used by SFX/OfaMiscCfg. |
364 | | The name Year2000 is kept although the actual functionality is now a |
365 | | TwoDigitYearStart which might be in any century. |
366 | | */ |
367 | | void SetYear2000(sal_uInt16 nVal); |
368 | | sal_uInt16 GetYear2000() const; |
369 | | static sal_uInt16 GetYear2000Default(); |
370 | | |
371 | | sal_uInt16 ExpandTwoDigitYear(sal_uInt16 nYear) const; |
372 | | static sal_uInt16 ExpandTwoDigitYear(sal_uInt16 nYear, sal_uInt16 nTwoDigitYearStart); |
373 | | |
374 | | /// Return the decimal separator matching the locale of the given format |
375 | | OUString GetFormatDecimalSep(sal_uInt32 nFormat); |
376 | | |
377 | | static void resetTheCurrencyTable(); |
378 | | |
379 | | /// Return a NfCurrencyTable with pointers to <type>NfCurrencyEntry</type> entries |
380 | | static const NfCurrencyTable& GetTheCurrencyTable(); |
381 | | |
382 | | /** Searches, according to the default locale currency, an entry of the |
383 | | CurrencyTable which is <bold>not</bold> the first (LANGUAGE_SYSTEM) entry. |
384 | | @return |
385 | | <NULL/> if not found |
386 | | else pointer to NfCurrencyEntry |
387 | | */ |
388 | | static const NfCurrencyEntry* MatchSystemCurrency(); |
389 | | |
390 | | /** Return a NfCurrencyEntry matching a language/country. |
391 | | If language/country is LANGUAGE_SYSTEM a <method>MatchSystemCurrency</method> |
392 | | call is tried to get an entry. If that fails or the corresponding |
393 | | language/country is not present the entry for LANGUAGE_SYSTEM is returned. |
394 | | */ |
395 | | static const NfCurrencyEntry& GetCurrencyEntry(LanguageType); |
396 | | |
397 | | /** Return a NfCurrencyEntry pointer matching a language/country |
398 | | and currency abbreviation (AKA banking symbol). |
399 | | This method is meant for the configuration of the default currency. |
400 | | @return |
401 | | <NULL/> if not found |
402 | | else pointer to NfCurrencyEntry |
403 | | */ |
404 | | static const NfCurrencyEntry* GetCurrencyEntry(std::u16string_view rAbbrev, LanguageType eLang); |
405 | | |
406 | | /** Return a NfCurrencyEntry pointer matching the symbol |
407 | | combination of a LegacyOnly currency. Note that this means only that |
408 | | the currency matching both symbols was once used in the Office, but is |
409 | | not offered in dialogs anymore. It doesn't even mean that the currency |
410 | | symbol combination is valid, since the reason for removing it may have |
411 | | been just that. #i61657# |
412 | | @return |
413 | | A matching entry, or else <NULL/>. |
414 | | */ |
415 | | static const NfCurrencyEntry* GetLegacyOnlyCurrencyEntry(std::u16string_view rSymbol, |
416 | | std::u16string_view rAbbrev); |
417 | | |
418 | | /** Set the default system currency. The combination of abbreviation and |
419 | | language must match an existent element of theCurrencyTable. If not, |
420 | | the SYSTEM (current locale) entry becomes the default. |
421 | | This method is meant for the configuration of the default currency. |
422 | | */ |
423 | | static void SetDefaultSystemCurrency(std::u16string_view rAbbrev, LanguageType eLang); |
424 | | |
425 | | /** Get all standard formats for a specific currency, formats are |
426 | | appended to the NfWSStringsDtor list. |
427 | | @param bBank |
428 | | <TRUE/>: generate only format strings with currency abbreviation |
429 | | <FALSE/>: mixed format strings |
430 | | @return |
431 | | position of default format |
432 | | */ |
433 | | sal_uInt16 GetCurrencyFormatStrings(NfWSStringsDtor&, const NfCurrencyEntry&, bool bBank) const; |
434 | | |
435 | | /** Whether nFormat is of type css::util::NumberFormat::CURRENCY and the format code |
436 | | contains a new SYMBOLTYPE_CURRENCY and if so which one [$xxx-nnn]. |
437 | | If ppEntry is not NULL and exactly one entry is found, a [$xxx-nnn] is |
438 | | returned, even if the format code only contains [$xxx] ! |
439 | | */ |
440 | | bool GetNewCurrencySymbolString(sal_uInt32 nFormat, OUString& rSymbol, |
441 | | const NfCurrencyEntry** ppEntry, bool* pBank = nullptr) const; |
442 | | |
443 | | /** Look up the corresponding NfCurrencyEntry matching |
444 | | rSymbol (may be CurrencySymbol or CurrencyAbbreviation) and possibly |
445 | | a rExtension (being yyy of [$xxx-yyy]) or a given language/country |
446 | | value. Tries to match a rSymbol with rExtension first, then with |
447 | | eFormatLanguage, then rSymbol only. This is because a currency entry |
448 | | might have been constructed using I18N locale data where a used locale |
449 | | of a currency format code must not necessarily match the locale of |
450 | | the locale data itself, e.g. [$HK$-40C] (being "zh_HK" locale) in |
451 | | zh_CN locale data. Here the rExtension would have the value 0x40c but |
452 | | eFormatLanguage of the number format would have the value of zh_CN |
453 | | locale, the value with which the corresponding CurrencyEntry is |
454 | | constructed. |
455 | | |
456 | | @param bFoundBank |
457 | | Only used for output. |
458 | | If the return value is not <NULL/> this value is set to <TRUE/> if |
459 | | the matching entry was found by comparing rSymbol against the |
460 | | CurrencyAbbreviation (AKA BankSymbol). |
461 | | If the return value is <NULL/> the value of bFoundBank is undefined. |
462 | | @param rSymbol |
463 | | Currency symbol, preferably obtained of a format by a call to |
464 | | <method>SvNumberformat::GetNewCurrencySymbol()</method> |
465 | | @param rExtension |
466 | | Currency extension, preferably obtained of a format by a call to |
467 | | <method>SvNumberformat::GetNewCurrencySymbol()</method> |
468 | | @param eFormatLanguage |
469 | | The language/country value of the format of which rSymbol and |
470 | | rExtension are obtained (<method>SvNumberformat::GetLanguage()</method>). |
471 | | @param bOnlyStringLanguage |
472 | | If <TRUE/> only entries with language/country of rExtension are |
473 | | checked, no match on eFormatLanguage. If rExtension is empty all |
474 | | entries are checked. |
475 | | @return |
476 | | The matching entry if unique (in which case bFoundBank is set), |
477 | | else <NULL/>. |
478 | | */ |
479 | | static const NfCurrencyEntry* GetCurrencyEntry(bool& bFoundBank, std::u16string_view rSymbol, |
480 | | std::u16string_view rExtension, |
481 | | LanguageType eFormatLanguage, |
482 | | bool bOnlyStringLanguage = false); |
483 | | |
484 | | /// Get compatibility ("automatic" old style) currency from I18N locale data |
485 | | void GetCompatibilityCurrency(OUString& rSymbol, OUString& rAbbrev) const; |
486 | | |
487 | | /// Fill rList with the language/country codes that have been allocated |
488 | | void GetUsedLanguages(std::vector<LanguageType>& rList); |
489 | | |
490 | | /// Fill a NfKeywordIndex table with keywords of a language/country |
491 | | void FillKeywordTable(NfKeywordTable& rKeywords, LanguageType eLang); |
492 | | |
493 | | /** Fill a NfKeywordIndex table with keywords usable in Excel export with |
494 | | GetFormatStringForExcel() or SvNumberformat::GetMappedFormatstring() */ |
495 | | void FillKeywordTableForExcel(NfKeywordTable& rKeywords); |
496 | | |
497 | | /** Return a format code string suitable for Excel export. |
498 | | |
499 | | @param rTempFormatter |
500 | | SvNumberFormatter to use if a non-en-US format code needs to be |
501 | | converted and put, should not be the same formatter to not |
502 | | pollute the entries of this one here. |
503 | | */ |
504 | | OUString GetFormatStringForExcel(sal_uInt32 nKey, const NfKeywordTable& rKeywords, |
505 | | SvNumberFormatter& rTempFormatter) const; |
506 | | |
507 | | /** Return a keyword for a language/country and NfKeywordIndex |
508 | | for XML import, to generate number format strings. */ |
509 | | OUString GetKeyword(LanguageType eLnge, sal_uInt16 nIndex); |
510 | | |
511 | | /** Return the GENERAL keyword in proper case ("General") for a |
512 | | language/country, used in XML import */ |
513 | | OUString GetStandardName(LanguageType eLnge); |
514 | | |
515 | | void MergeDefaultFormatKeys(const SvNFFormatData::DefaultFormatKeysMap& rDefaultFormatKeys); |
516 | | |
517 | | /** Check if a specific locale has supported locale data. */ |
518 | | static bool IsLocaleInstalled(LanguageType eLang); |
519 | | |
520 | | /** Obtain NfKeywordTable used with a format, possibly localized. |
521 | | |
522 | | XXX NOTE: the content (actual keywords) is only valid as long as the |
523 | | locale context of the associated ImpSvNumberformatScan instance does |
524 | | not change to a locale with different keywords, which may happen |
525 | | anytime with a call (implicit or explicit) to |
526 | | SvNumberFormatter::ChangeIntl(). If needed longer, copy-create another |
527 | | NfKeywordTable instance or copy individual elements. |
528 | | |
529 | | If the format specified with nKey does not exist, the content of the |
530 | | NfKeywordTable matches the locale with which the SvNumberFormatter |
531 | | instance was created and initialized. |
532 | | |
533 | | This function preliminary exists for unit tests and otherwise is |
534 | | pretty much useless. |
535 | | */ |
536 | | const NfKeywordTable& GetKeywords(sal_uInt32 nKey); |
537 | | |
538 | | /** Access for unit tests. */ |
539 | | static const NfKeywordTable& GetEnglishKeywords(); |
540 | | |
541 | | /** Access for unit tests. */ |
542 | | static const std::vector<Color>& GetStandardColors(); |
543 | | |
544 | | /** Access for unit tests. */ |
545 | | static size_t GetMaxDefaultColors(); |
546 | | |
547 | | private: |
548 | | mutable ::osl::Mutex m_aMutex; |
549 | | css::uno::Reference<css::uno::XComponentContext> m_xContext; |
550 | | const LanguageType IniLnge; // Initialized setting language/country |
551 | | SvNFFormatData m_aFormatData; |
552 | | SvNFEngine::Accessor m_aRWPolicy; |
553 | | std::unique_ptr<SvNumberFormatTable> pFormatTable; // For the UI dialog |
554 | | std::unique_ptr<SvNumberFormatterIndexTable> |
555 | | pMergeTable; // List of indices for merging two formatters |
556 | | SvNFLanguageData m_aCurrentLanguage; |
557 | | OnDemandNativeNumberWrapper m_xNatNum; // Native number service loaded on demand |
558 | | Link<sal_uInt16, Color*> aColorLink; // User defined color table CallBack |
559 | | |
560 | | SVL_DLLPRIVATE static sal_uInt16 nSystemCurrencyPosition; |
561 | | SVL_DLLPRIVATE static SvNumberFormatterRegistry_Impl* pFormatterRegistry; |
562 | | |
563 | | // get the registry, create one if none exists |
564 | | SVL_DLLPRIVATE static SvNumberFormatterRegistry_Impl& GetFormatterRegistry(); |
565 | | |
566 | | // Generate additional formats provided by i18n |
567 | | SVL_DLLPRIVATE void ImpGenerateAdditionalFormats( |
568 | | sal_uInt32 CLOffset, |
569 | | css::uno::Reference<css::i18n::XNumberFormatCode> const& rNumberFormatCode); |
570 | | |
571 | | // Test whether format code already exists, then return index key, |
572 | | // otherwise NUMBERFORMAT_ENTRY_NOT_FOUND |
573 | | SVL_DLLPRIVATE sal_uInt32 ImpIsEntry(std::u16string_view rString, sal_uInt32 CLOffset, |
574 | | LanguageType eLnge) const; |
575 | | |
576 | | // Create theCurrencyTable with all <type>NfCurrencyEntry</type> |
577 | | SVL_DLLPRIVATE static void ImpInitCurrencyTable(); |
578 | | |
579 | | // used as a loop body inside of GetNewCurrencySymbolString() and GetCurrencyEntry() |
580 | | static bool ImpLookupCurrencyEntryLoopBody(const NfCurrencyEntry*& pFoundEntry, |
581 | | bool& bFoundBank, const NfCurrencyEntry* pData, |
582 | | sal_uInt16 nPos, std::u16string_view rSymbol); |
583 | | |
584 | | // called by SvNumberFormatterRegistry_Impl::Notify if the default system currency changes |
585 | | SVL_DLLPRIVATE void ResetDefaultSystemCurrency(); |
586 | | |
587 | | // link to be set at <method>SvtSysLocaleOptions::SetCurrencyChangeLink()</method> |
588 | | DECL_DLLPRIVATE_STATIC_LINK(SvNumberFormatter, CurrencyChangeLink, LinkParamNone*, void); |
589 | | |
590 | | // Substitute a format during GetFormatEntry(), i.e. system formats. |
591 | | SVL_DLLPRIVATE const SvNumberformat* ImpSubstituteEntry(const SvNumberformat* pFormat, |
592 | | sal_uInt32* o_pRealKey = nullptr); |
593 | | |
594 | | // Whether nFIndex is a special builtin format |
595 | | SVL_DLLPRIVATE bool ImpIsSpecialStandardFormat(sal_uInt32 nFIndex, LanguageType eLnge); |
596 | | |
597 | | // Replace the SYSTEM language/country format codes. Called upon change of |
598 | | // the user configurable locale. |
599 | | // Old compatibility codes are replaced, user defined are converted, and |
600 | | // new format codes are appended. |
601 | | SVL_DLLPRIVATE void ReplaceSystemCL(LanguageType eOldLanguage); |
602 | | |
603 | | // own mutex, may also be used by internal class SvNumberFormatterRegistry_Impl |
604 | | static ::osl::Mutex& GetGlobalMutex(); |
605 | 112M | ::osl::Mutex& GetInstanceMutex() const { return m_aMutex; } |
606 | | |
607 | | public: |
608 | | // Called by SvNumberFormatterRegistry_Impl::Notify if the system locale's |
609 | | // date acceptance patterns change. |
610 | | void InvalidateDateAcceptancePatterns(); |
611 | | |
612 | | //! The following methods are not to be used from outside but must be |
613 | | //! public for the InputScanner and FormatScanner. |
614 | | |
615 | | // return current (!) Locale |
616 | 0 | const LanguageTag& GetLanguageTag() const { return m_aCurrentLanguage.GetLanguageTag(); } |
617 | | |
618 | | // return the corresponding CharacterClassification wrapper |
619 | 0 | const CharClass* GetCharClass() const { return m_aCurrentLanguage.GetCharClass(); } |
620 | | |
621 | | // return the corresponding LocaleData wrapper |
622 | 0 | const LocaleDataWrapper* GetLocaleData() const { return m_aCurrentLanguage.GetLocaleData(); } |
623 | | |
624 | | // return the corresponding Calendar wrapper |
625 | 0 | CalendarWrapper* GetCalendar() const { return m_aCurrentLanguage.GetCalendar(); } |
626 | | |
627 | | // return the corresponding NativeNumberSupplier wrapper |
628 | | const NativeNumberWrapper& GetNatNum() const; |
629 | | |
630 | | // cached locale data items |
631 | | |
632 | | // return the corresponding decimal separator |
633 | 168 | const OUString& GetNumDecimalSep() const { return m_aCurrentLanguage.GetNumDecimalSep(); } |
634 | | |
635 | | // return the corresponding date separator |
636 | 1.09k | const OUString& GetDateSep() const { return m_aCurrentLanguage.GetDateSep(); } |
637 | | |
638 | | void PrepForRoMode(); |
639 | 78.8k | const SvNFFormatData& GetROFormatData() const { return m_aFormatData; } |
640 | 78.8k | const SvNFLanguageData& GetROLanguageData() const { return m_aCurrentLanguage; } |
641 | | }; |
642 | | |
643 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |