Branch data Line data Source code
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 : :
20 : : #include <tools/debug.hxx>
21 : : #include <unotools/charclass.hxx>
22 : : #include <i18npool/mslangid.hxx>
23 : : #include <unotools/localedatawrapper.hxx>
24 : : #include <unotools/numberformatcodewrapper.hxx>
25 : : #include <unotools/calendarwrapper.hxx>
26 : : #include <com/sun/star/i18n/KNumberFormatUsage.hpp>
27 : : #include <com/sun/star/i18n/KNumberFormatType.hpp>
28 : : #include <comphelper/processfactory.hxx>
29 : : #include <unotools/misccfg.hxx>
30 : :
31 : :
32 : : #define _ZFORLIST_CXX
33 : : #include <osl/mutex.hxx>
34 : : #include <svl/zforlist.hxx>
35 : : #undef _ZFORLIST_CXX
36 : :
37 : : #include "zforscan.hxx"
38 : : #include "zforfind.hxx"
39 : : #include <svl/zformat.hxx>
40 : : #include "numhead.hxx"
41 : :
42 : : #include <unotools/syslocaleoptions.hxx>
43 : : #include <unotools/digitgroupingiterator.hxx>
44 : : #include <rtl/logfile.hxx>
45 : : #include <rtl/instance.hxx>
46 : : #include <rtl/strbuf.hxx>
47 : :
48 : : #include <math.h>
49 : : #include <limits>
50 : :
51 : : using namespace ::com::sun::star;
52 : : using namespace ::com::sun::star::uno;
53 : : using namespace ::com::sun::star::i18n;
54 : : using namespace ::com::sun::star::lang;
55 : : using namespace ::std;
56 : :
57 : : using ::rtl::OUString;
58 : :
59 : :
60 : : // Constants for type offsets per Country/Language (CL)
61 : : #define ZF_STANDARD 0
62 : : #define ZF_STANDARD_PERCENT 10
63 : : #define ZF_STANDARD_CURRENCY 20
64 : : #define ZF_STANDARD_DATE 30
65 : : #define ZF_STANDARD_TIME 40
66 : : #define ZF_STANDARD_DATETIME 50
67 : : #define ZF_STANDARD_SCIENTIFIC 60
68 : : #define ZF_STANDARD_FRACTION 70
69 : : #define ZF_STANDARD_NEWEXTENDED 75
70 : : #define ZF_STANDARD_NEWEXTENDEDMAX SV_MAX_ANZ_STANDARD_FORMATE-2 // 98
71 : : #define ZF_STANDARD_LOGICAL SV_MAX_ANZ_STANDARD_FORMATE-1 // 99
72 : : #define ZF_STANDARD_TEXT SV_MAX_ANZ_STANDARD_FORMATE // 100
73 : :
74 : : /* Locale that is set if an unknown locale (from another system) is loaded of
75 : : * legacy documents. Can not be SYSTEM because else, for example, a German "DM"
76 : : * (old currency) is recognized as a date (#53155#). */
77 : : #define UNKNOWN_SUBSTITUTE LANGUAGE_ENGLISH_US
78 : :
79 : : static bool bIndexTableInitialized = false;
80 : : static sal_uInt32 theIndexTable[NF_INDEX_TABLE_ENTRIES];
81 : :
82 : :
83 : : // ====================================================================
84 : :
85 : : /**
86 : : instead of every number formatter being a listener we have a registry which
87 : : also handles one instance of the SysLocale options
88 : : */
89 : :
90 : : typedef ::std::vector< SvNumberFormatter* > SvNumberFormatterList_impl;
91 : :
92 : : class SvNumberFormatterRegistry_Impl : public utl::ConfigurationListener
93 : : {
94 : : SvNumberFormatterList_impl aFormatters;
95 : : SvtSysLocaleOptions aSysLocaleOptions;
96 : : LanguageType eSysLanguage;
97 : :
98 : : public:
99 : : SvNumberFormatterRegistry_Impl();
100 : : virtual ~SvNumberFormatterRegistry_Impl();
101 : :
102 : 2191 : void Insert( SvNumberFormatter* pThis )
103 : 2191 : { aFormatters.push_back( pThis ); }
104 : :
105 : : SvNumberFormatter* Remove( SvNumberFormatter* pThis );
106 : :
107 : 1990 : size_t Count()
108 : 1990 : { return aFormatters.size(); }
109 : :
110 : : virtual void ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 );
111 : : };
112 : :
113 [ + - ][ + - ]: 998 : SvNumberFormatterRegistry_Impl::SvNumberFormatterRegistry_Impl()
114 : : {
115 [ + - ]: 998 : eSysLanguage = MsLangId::getRealLanguage( LANGUAGE_SYSTEM );
116 [ + - ]: 998 : aSysLocaleOptions.AddListener( this );
117 : 998 : }
118 : :
119 : :
120 [ + - ]: 980 : SvNumberFormatterRegistry_Impl::~SvNumberFormatterRegistry_Impl()
121 : : {
122 [ + - ]: 980 : aSysLocaleOptions.RemoveListener( this );
123 [ - + ]: 1960 : }
124 : :
125 : :
126 : 1990 : SvNumberFormatter* SvNumberFormatterRegistry_Impl::Remove( SvNumberFormatter* pThis )
127 : : {
128 [ + - + - ]: 9340 : for (SvNumberFormatterList_impl::iterator it = aFormatters.begin();
[ + - ]
129 : 4670 : it != aFormatters.end(); ++it)
130 : : {
131 [ + - ][ + + ]: 4670 : if ( *it == pThis )
132 : : {
133 [ + - ]: 1990 : aFormatters.erase( it );
134 : 1990 : break;
135 : : }
136 : : }
137 : 1990 : return pThis;
138 : : }
139 : :
140 : 0 : void SvNumberFormatterRegistry_Impl::ConfigurationChanged(
141 : : utl::ConfigurationBroadcaster*,
142 : : sal_uInt32 nHint)
143 : : {
144 [ # # ]: 0 : if ( nHint & SYSLOCALEOPTIONS_HINT_LOCALE )
145 : : {
146 [ # # ][ # # ]: 0 : ::osl::MutexGuard aGuard( SvNumberFormatter::GetMutex() );
147 [ # # ]: 0 : for( size_t i = 0, n = aFormatters.size(); i < n; ++i )
148 [ # # ][ # # ]: 0 : aFormatters[ i ]->ReplaceSystemCL( eSysLanguage );
149 [ # # ][ # # ]: 0 : eSysLanguage = MsLangId::getRealLanguage( LANGUAGE_SYSTEM );
150 : : }
151 [ # # ]: 0 : if ( nHint & SYSLOCALEOPTIONS_HINT_CURRENCY )
152 : : {
153 [ # # ][ # # ]: 0 : ::osl::MutexGuard aGuard( SvNumberFormatter::GetMutex() );
154 [ # # ]: 0 : for( size_t i = 0, n = aFormatters.size(); i < n; ++i )
155 [ # # ][ # # ]: 0 : aFormatters[ i ]->ResetDefaultSystemCurrency();
[ # # ]
156 : : }
157 : 0 : }
158 : :
159 : :
160 : : // ====================================================================
161 : :
162 : : SvNumberFormatterRegistry_Impl* SvNumberFormatter::pFormatterRegistry = NULL;
163 : : bool SvNumberFormatter::bCurrencyTableInitialized = false;
164 : : namespace
165 : : {
166 : : struct theCurrencyTable :
167 : : public rtl::Static< NfCurrencyTable, theCurrencyTable > {};
168 : :
169 : : struct theLegacyOnlyCurrencyTable :
170 : : public rtl::Static< NfCurrencyTable, theLegacyOnlyCurrencyTable > {};
171 : :
172 : : /** THE set of installed locales. */
173 : : struct theInstalledLocales :
174 : : public rtl::Static< NfInstalledLocales, theInstalledLocales> {};
175 : :
176 : : }
177 : : sal_uInt16 SvNumberFormatter::nSystemCurrencyPosition = 0;
178 : :
179 : : // Whether BankSymbol (not CurrencySymbol!) is always at the end (1 $;-1 $) or
180 : : // language dependent.
181 : : #define NF_BANKSYMBOL_FIX_POSITION 1
182 : :
183 : :
184 : : /***********************Funktionen SvNumberFormatter**************************/
185 : :
186 : : const sal_uInt16 SvNumberFormatter::UNLIMITED_PRECISION = ::std::numeric_limits<sal_uInt16>::max();
187 : : const sal_uInt16 SvNumberFormatter::INPUTSTRING_PRECISION = ::std::numeric_limits<sal_uInt16>::max()-1;
188 : :
189 : 2191 : SvNumberFormatter::SvNumberFormatter(
190 : : const Reference< XMultiServiceFactory >& xSMgr,
191 : : LanguageType eLang )
192 : : :
193 [ + - ][ + - ]: 2191 : xServiceManager( xSMgr )
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
194 : : {
195 [ + - ]: 2191 : ImpConstruct( eLang );
196 : 2191 : }
197 : :
198 : :
199 [ + - ][ + - ]: 1990 : SvNumberFormatter::~SvNumberFormatter()
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
200 : : {
201 : : {
202 [ + - ][ + - ]: 1990 : ::osl::MutexGuard aGuard( GetMutex() );
203 [ + - ]: 1990 : pFormatterRegistry->Remove( this );
204 [ + + ]: 1990 : if ( !pFormatterRegistry->Count() )
205 : : {
206 [ + - ][ + - ]: 980 : delete pFormatterRegistry;
207 : 980 : pFormatterRegistry = NULL;
208 [ + - ]: 1990 : }
209 : : }
210 : :
211 [ + - ][ + - ]: 153325 : for (SvNumberFormatTable::iterator it = aFTable.begin(); it != aFTable.end(); ++it)
[ + + ]
212 [ + - ][ + - ]: 151335 : delete it->second;
[ + - ]
213 [ + + ]: 1990 : delete pFormatTable;
214 [ + - ][ + - ]: 1990 : delete pCharClass;
215 [ + - ][ + - ]: 1990 : delete pStringScanner;
216 [ + - ][ + - ]: 1990 : delete pFormatScanner;
217 [ + - ]: 1990 : ClearMergeTable();
218 [ + + ]: 1990 : delete pMergeTable;
219 : 1990 : }
220 : :
221 : :
222 : 2191 : void SvNumberFormatter::ImpConstruct( LanguageType eLang )
223 : : {
224 : : RTL_LOGFILE_CONTEXT_AUTHOR( aTimeLog, "svl", "er93726", "SvNumberFormatter::ImpConstruct" );
225 : :
226 [ - + ]: 2191 : if ( eLang == LANGUAGE_DONTKNOW )
227 : 0 : eLang = UNKNOWN_SUBSTITUTE;
228 : 2191 : IniLnge = eLang;
229 : 2191 : ActLnge = eLang;
230 : 2191 : eEvalDateFormat = NF_EVALDATEFORMAT_INTL;
231 : 2191 : nDefaultSystemCurrencyFormat = NUMBERFORMAT_ENTRY_NOT_FOUND;
232 : :
233 [ + - ]: 2191 : aLocale = MsLangId::convertLanguageToLocale( eLang );
234 [ + - ][ + - ]: 2191 : pCharClass = new CharClass( xServiceManager, aLocale );
235 [ + - ]: 2191 : xLocaleData.init( xServiceManager, aLocale, eLang );
236 [ + - ]: 2191 : xCalendar.init( xServiceManager, aLocale );
237 : : xTransliteration.init( xServiceManager, eLang,
238 [ + - ]: 2191 : ::com::sun::star::i18n::TransliterationModules_IGNORE_CASE );
239 [ + - ]: 2191 : xNatNum.init( xServiceManager );
240 : :
241 : : // cached locale data items
242 : 2191 : const LocaleDataWrapper* pLoc = GetLocaleData();
243 [ + - ][ + - ]: 2191 : aDecimalSep = pLoc->getNumDecimalSep();
244 [ + - ][ + - ]: 2191 : aThousandSep = pLoc->getNumThousandSep();
245 [ + - ][ + - ]: 2191 : aDateSep = pLoc->getDateSep();
246 : :
247 [ + - ][ + - ]: 2191 : pStringScanner = new ImpSvNumberInputScan( this );
248 [ + - ][ + - ]: 2191 : pFormatScanner = new ImpSvNumberformatScan( this );
249 : 2191 : pFormatTable = NULL;
250 : 2191 : MaxCLOffset = 0;
251 [ + - ]: 2191 : ImpGenerateFormats( 0, false ); // 0 .. 999 for initialized language formats
252 : 2191 : pMergeTable = NULL;
253 : 2191 : bNoZero = false;
254 : :
255 [ + - ][ + - ]: 2191 : ::osl::MutexGuard aGuard( GetMutex() );
256 [ + - ][ + - ]: 2191 : GetFormatterRegistry().Insert( this );
[ + - ]
257 : 2191 : }
258 : :
259 : :
260 : 122950 : void SvNumberFormatter::ChangeIntl(LanguageType eLnge)
261 : : {
262 [ + + ]: 122950 : if (ActLnge != eLnge)
263 : : {
264 : 6677 : ActLnge = eLnge;
265 : :
266 : 6677 : aLocale = MsLangId::convertLanguageToLocale( eLnge );
267 : 6677 : pCharClass->setLocale( aLocale );
268 : 6677 : xLocaleData.changeLocale( aLocale, eLnge );
269 : 6677 : xCalendar.changeLocale( aLocale );
270 : 6677 : xTransliteration.changeLocale( eLnge );
271 : :
272 : : // cached locale data items, initialize BEFORE calling ChangeIntl below
273 : 6677 : const LocaleDataWrapper* pLoc = GetLocaleData();
274 : 6677 : aDecimalSep = pLoc->getNumDecimalSep();
275 : 6677 : aThousandSep = pLoc->getNumThousandSep();
276 : 6677 : aDateSep = pLoc->getDateSep();
277 : :
278 : 6677 : pFormatScanner->ChangeIntl();
279 : 6677 : pStringScanner->ChangeIntl();
280 : : }
281 : 122950 : }
282 : :
283 : :
284 : : // static
285 : 6711 : ::osl::Mutex& SvNumberFormatter::GetMutex()
286 : : {
287 : : static ::osl::Mutex* pMutex = NULL;
288 [ + + ]: 6711 : if( !pMutex )
289 : : {
290 [ + - ][ + - ]: 123 : ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
291 [ + - ]: 123 : if( !pMutex )
292 : : {
293 : : // #i77768# Due to a static reference in the toolkit lib
294 : : // we need a mutex that lives longer than the svl library.
295 : : // Otherwise the dtor would use a destructed mutex!!
296 [ + - ][ + - ]: 123 : pMutex = new ::osl::Mutex;
297 [ + - ]: 123 : }
298 : : }
299 : 6711 : return *pMutex;
300 : : }
301 : :
302 : :
303 : : // static
304 : 2191 : SvNumberFormatterRegistry_Impl& SvNumberFormatter::GetFormatterRegistry()
305 : : {
306 [ + - ][ + - ]: 2191 : ::osl::MutexGuard aGuard( GetMutex() );
307 [ + + ]: 2191 : if ( !pFormatterRegistry )
308 [ + - ][ + - ]: 998 : pFormatterRegistry = new SvNumberFormatterRegistry_Impl;
309 [ + - ]: 2191 : return *pFormatterRegistry;
310 : : }
311 : :
312 : :
313 : 0 : Color* SvNumberFormatter::GetUserDefColor(sal_uInt16 nIndex)
314 : : {
315 [ # # ]: 0 : if( aColorLink.IsSet() )
316 : 0 : return (Color*) ( aColorLink.Call( (void*) &nIndex ));
317 : : else
318 : 0 : return NULL;
319 : : }
320 : :
321 : 1617 : void SvNumberFormatter::ChangeNullDate(sal_uInt16 nDay,
322 : : sal_uInt16 nMonth,
323 : : sal_uInt16 nYear)
324 : : {
325 : 1617 : pFormatScanner->ChangeNullDate(nDay, nMonth, nYear);
326 : 1617 : pStringScanner->ChangeNullDate(nDay, nMonth, nYear);
327 : 1617 : }
328 : :
329 : 1636 : Date* SvNumberFormatter::GetNullDate()
330 : : {
331 : 1636 : return pFormatScanner->GetNullDate();
332 : : }
333 : :
334 : 2246 : void SvNumberFormatter::ChangeStandardPrec(short nPrec)
335 : : {
336 : 2246 : pFormatScanner->ChangeStandardPrec(nPrec);
337 : 2246 : }
338 : :
339 : 3 : sal_uInt16 SvNumberFormatter::GetStandardPrec()
340 : : {
341 : 3 : return pFormatScanner->GetStandardPrec();
342 : : }
343 : :
344 : 0 : void SvNumberFormatter::ImpChangeSysCL( LanguageType eLnge, bool bNoAdditionalFormats )
345 : : {
346 [ # # ]: 0 : if (eLnge == LANGUAGE_DONTKNOW)
347 : 0 : eLnge = UNKNOWN_SUBSTITUTE;
348 [ # # ]: 0 : if (eLnge != IniLnge)
349 : : {
350 : 0 : IniLnge = eLnge;
351 : 0 : ChangeIntl(eLnge);
352 : : // delete old formats
353 [ # # ][ # # ]: 0 : for (SvNumberFormatTable::iterator it = aFTable.begin(); it != aFTable.end(); ++it)
[ # # ]
354 [ # # ][ # # ]: 0 : delete it->second;
[ # # ]
355 : 0 : aFTable.clear();
356 : 0 : ImpGenerateFormats( 0, bNoAdditionalFormats ); // new standard formats
357 : : }
358 [ # # ]: 0 : else if ( bNoAdditionalFormats )
359 : : { // delete additional standard formats
360 : : sal_uInt32 nKey;
361 [ # # ]: 0 : SvNumberFormatTable::iterator it = aFTable.find( SV_MAX_ANZ_STANDARD_FORMATE + 1 );
362 [ # # ][ # # ]: 0 : while ( it != aFTable.end() && (nKey = it->first) > SV_MAX_ANZ_STANDARD_FORMATE &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
363 : : nKey < SV_COUNTRY_LANGUAGE_OFFSET )
364 : : {
365 [ # # ][ # # ]: 0 : delete it->second;
[ # # ]
366 [ # # ][ # # ]: 0 : aFTable.erase( it++ );
367 : : }
368 : : }
369 : 0 : }
370 : :
371 : :
372 : 0 : void SvNumberFormatter::ReplaceSystemCL( LanguageType eOldLanguage )
373 : : {
374 [ # # ]: 0 : sal_uInt32 nCLOffset = ImpGetCLOffset( LANGUAGE_SYSTEM );
375 [ # # ]: 0 : if ( nCLOffset > MaxCLOffset )
376 : 0 : return ; // no SYSTEM entries to replace
377 : :
378 : 0 : const sal_uInt32 nMaxBuiltin = nCLOffset + SV_MAX_ANZ_STANDARD_FORMATE;
379 : 0 : const sal_uInt32 nNextCL = nCLOffset + SV_COUNTRY_LANGUAGE_OFFSET;
380 : : sal_uInt32 nKey;
381 : :
382 : : // remove old builtin formats
383 [ # # ]: 0 : SvNumberFormatTable::iterator it = aFTable.find( nCLOffset );
384 [ # # ][ # # ]: 0 : while ( it != aFTable.end() && (nKey = it->first) >= nCLOffset && nKey <= nMaxBuiltin )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
385 : : {
386 [ # # ][ # # ]: 0 : delete it->second;
[ # # ]
387 [ # # ][ # # ]: 0 : aFTable.erase( it++ );
388 : : }
389 : :
390 : : // move additional and user defined to temporary table
391 [ # # ]: 0 : SvNumberFormatTable aOldTable;
392 [ # # ][ # # ]: 0 : while ( it != aFTable.end() && (nKey = it->first) >= nCLOffset && nKey < nNextCL )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
393 : : {
394 [ # # ][ # # ]: 0 : aOldTable[ nKey ] = it->second;
395 [ # # ][ # # ]: 0 : aFTable.erase( it++ );
396 : : }
397 : :
398 : : // generate new old builtin formats
399 : : // reset ActLnge otherwise ChangeIntl() wouldn't switch if already LANGUAGE_SYSTEM
400 : 0 : ActLnge = LANGUAGE_DONTKNOW;
401 [ # # ]: 0 : ChangeIntl( LANGUAGE_SYSTEM );
402 [ # # ]: 0 : ImpGenerateFormats( nCLOffset, true );
403 : :
404 : : // convert additional and user defined from old system to new system
405 [ # # ]: 0 : SvNumberformat* pStdFormat = GetFormatEntry( nCLOffset + ZF_STANDARD );
406 : 0 : sal_uInt32 nLastKey = nMaxBuiltin;
407 : 0 : pFormatScanner->SetConvertMode( eOldLanguage, LANGUAGE_SYSTEM, true );
408 [ # # ]: 0 : while ( !aOldTable.empty() )
409 : : {
410 [ # # ]: 0 : nKey = aOldTable.begin()->first;
411 [ # # ]: 0 : if ( nLastKey < nKey )
412 : 0 : nLastKey = nKey;
413 [ # # ]: 0 : SvNumberformat* pOldEntry = aOldTable.begin()->second;
414 [ # # ]: 0 : aOldTable.erase( nKey );
415 [ # # ]: 0 : String aString( pOldEntry->GetFormatstring() );
416 : 0 : xub_StrLen nCheckPos = STRING_NOTFOUND;
417 : :
418 : : // Same as PutEntry() but assures key position even if format code is
419 : : // a duplicate. Also won't mix up any LastInsertKey.
420 [ # # ]: 0 : ChangeIntl( eOldLanguage );
421 : 0 : LanguageType eLge = eOldLanguage; // ConvertMode changes this
422 : 0 : bool bCheck = false;
423 : : SvNumberformat* pNewEntry = new SvNumberformat( aString, pFormatScanner,
424 [ # # ][ # # ]: 0 : pStringScanner, nCheckPos, eLge );
425 [ # # ]: 0 : if ( nCheckPos != 0 )
426 [ # # ][ # # ]: 0 : delete pNewEntry;
427 : : else
428 : : {
429 : 0 : short eCheckType = pNewEntry->GetType();
430 [ # # ]: 0 : if ( eCheckType != NUMBERFORMAT_UNDEFINED )
431 : 0 : pNewEntry->SetType( eCheckType | NUMBERFORMAT_DEFINED );
432 : : else
433 : 0 : pNewEntry->SetType( NUMBERFORMAT_DEFINED );
434 : :
435 [ # # ][ # # ]: 0 : if ( !aFTable.insert( make_pair( nKey, pNewEntry) ).second )
[ # # ]
436 [ # # ][ # # ]: 0 : delete pNewEntry;
437 : : else
438 : 0 : bCheck = true;
439 : : }
440 : : DBG_ASSERT( bCheck, "SvNumberFormatter::ReplaceSystemCL: couldn't convert" );
441 : : (void)bCheck;
442 : :
443 [ # # ][ # # ]: 0 : delete pOldEntry;
444 [ # # ]: 0 : }
445 : 0 : pFormatScanner->SetConvertMode(false);
446 : 0 : pStdFormat->SetLastInsertKey( sal_uInt16(nLastKey - nCLOffset) );
447 : :
448 : : // append new system additional formats
449 [ # # ]: 0 : NumberFormatCodeWrapper aNumberFormatCode( xServiceManager, GetLocale() );
450 [ # # ][ # # ]: 0 : ImpGenerateAdditionalFormats( nCLOffset, aNumberFormatCode, true );
451 : : }
452 : :
453 : :
454 : 2584 : bool SvNumberFormatter::IsTextFormat(sal_uInt32 F_Index) const
455 : : {
456 : 2584 : const SvNumberformat* pFormat = GetFormatEntry(F_Index);
457 [ + + ]: 2584 : if (!pFormat)
458 : 820 : return false;
459 : : else
460 : 2584 : return pFormat->IsTextFormat();
461 : : }
462 : :
463 : 6282 : bool SvNumberFormatter::PutEntry(String& rString,
464 : : xub_StrLen& nCheckPos,
465 : : short& nType,
466 : : sal_uInt32& nKey, // format key
467 : : LanguageType eLnge)
468 : : {
469 : 6282 : nKey = 0;
470 [ + + ]: 6282 : if (rString.Len() == 0) // empty string
471 : : {
472 : 1815 : nCheckPos = 1; // -> Error
473 : 1815 : return false;
474 : : }
475 [ - + ]: 4467 : if (eLnge == LANGUAGE_DONTKNOW)
476 : 0 : eLnge = IniLnge;
477 : :
478 [ + - ]: 4467 : ChangeIntl(eLnge); // change locale if necessary
479 : 4467 : LanguageType eLge = eLnge; // non-const for ConvertMode
480 : 4467 : bool bCheck = false;
481 : : SvNumberformat* p_Entry = new SvNumberformat(rString,
482 : : pFormatScanner,
483 : : pStringScanner,
484 : : nCheckPos,
485 [ + - ][ + - ]: 4467 : eLge);
486 [ + - ]: 4467 : if (nCheckPos == 0) // Format ok
487 : : { // Type comparison:
488 : 4467 : short eCheckType = p_Entry->GetType();
489 [ + - ]: 4467 : if ( eCheckType != NUMBERFORMAT_UNDEFINED)
490 : : {
491 : 4467 : p_Entry->SetType(eCheckType | NUMBERFORMAT_DEFINED);
492 : 4467 : nType = eCheckType;
493 : : }
494 : : else
495 : : {
496 : 0 : p_Entry->SetType(NUMBERFORMAT_DEFINED);
497 : 0 : nType = NUMBERFORMAT_DEFINED;
498 : : }
499 [ + - ]: 4467 : sal_uInt32 CLOffset = ImpGenerateCL(eLge); // create new standard formats if necessary
500 : :
501 [ + - ]: 4467 : nKey = ImpIsEntry(p_Entry->GetFormatstring(),CLOffset, eLge);
502 [ + + ]: 4467 : if (nKey != NUMBERFORMAT_ENTRY_NOT_FOUND) // already present
503 [ + - ][ + - ]: 2012 : delete p_Entry;
504 : : else
505 : : {
506 : : SvNumberformat* pStdFormat =
507 [ + - ]: 2455 : GetFormatEntry(CLOffset + ZF_STANDARD);
508 : 2455 : sal_uInt32 nPos = CLOffset + pStdFormat->GetLastInsertKey();
509 [ - + ]: 2455 : if (nPos - CLOffset >= SV_COUNTRY_LANGUAGE_OFFSET)
510 : : {
511 : : OSL_FAIL("SvNumberFormatter:: Zu viele Formate pro CL");
512 [ # # ][ # # ]: 0 : delete p_Entry;
513 : : }
514 [ + - ][ + - ]: 2455 : else if (!aFTable.insert(make_pair( nPos+1,p_Entry)).second)
[ - + ]
515 [ # # ][ # # ]: 0 : delete p_Entry;
516 : : else
517 : : {
518 : 2455 : bCheck = true;
519 : 2455 : nKey = nPos+1;
520 : 2455 : pStdFormat->SetLastInsertKey((sal_uInt16) (nKey-CLOffset));
521 : : }
522 : : }
523 : : }
524 : : else
525 [ # # ][ # # ]: 0 : delete p_Entry;
526 : 6282 : return bCheck;
527 : : }
528 : :
529 : 97 : bool SvNumberFormatter::PutEntry(
530 : : OUString& rString, xub_StrLen& nCheckPos, short& nType, sal_uInt32& nKey,
531 : : LanguageType eLnge)
532 : : {
533 : : // Wrapper to allow rtl::OUString to be used.
534 [ + - ]: 97 : String aStr(rString);
535 [ + - ]: 97 : bool bRet = PutEntry(aStr, nCheckPos, nType, nKey, eLnge);
536 [ + - ]: 97 : rString = aStr;
537 [ + - ]: 97 : return bRet;
538 : : }
539 : :
540 : 5296 : bool SvNumberFormatter::PutandConvertEntry(String& rString,
541 : : xub_StrLen& nCheckPos,
542 : : short& nType,
543 : : sal_uInt32& nKey,
544 : : LanguageType eLnge,
545 : : LanguageType eNewLnge)
546 : : {
547 : : bool bRes;
548 [ - + ]: 5296 : if (eNewLnge == LANGUAGE_DONTKNOW)
549 : 0 : eNewLnge = IniLnge;
550 : :
551 : 5296 : pFormatScanner->SetConvertMode(eLnge, eNewLnge);
552 : 5296 : bRes = PutEntry(rString, nCheckPos, nType, nKey, eLnge);
553 : 5296 : pFormatScanner->SetConvertMode(false);
554 : 5296 : return bRes;
555 : : }
556 : :
557 : 1815 : bool SvNumberFormatter::PutandConvertEntry(rtl::OUString& rString,
558 : : xub_StrLen& nCheckPos,
559 : : short& nType,
560 : : sal_uInt32& nKey,
561 : : LanguageType eLnge,
562 : : LanguageType eNewLnge)
563 : : {
564 [ + - ]: 1815 : String aStr;
565 [ + - ]: 1815 : bool bRet = PutandConvertEntry(aStr, nCheckPos, nType, nKey, eLnge, eNewLnge);
566 [ + - ]: 1815 : rString = aStr;
567 [ + - ]: 1815 : return bRet;
568 : : }
569 : :
570 : 0 : bool SvNumberFormatter::PutandConvertEntrySystem(String& rString,
571 : : xub_StrLen& nCheckPos,
572 : : short& nType,
573 : : sal_uInt32& nKey,
574 : : LanguageType eLnge,
575 : : LanguageType eNewLnge)
576 : : {
577 : : bool bRes;
578 [ # # ]: 0 : if (eNewLnge == LANGUAGE_DONTKNOW)
579 : 0 : eNewLnge = IniLnge;
580 : :
581 : 0 : pFormatScanner->SetConvertMode(eLnge, eNewLnge, true);
582 : 0 : bRes = PutEntry(rString, nCheckPos, nType, nKey, eLnge);
583 : 0 : pFormatScanner->SetConvertMode(false);
584 : 0 : return bRes;
585 : : }
586 : :
587 : :
588 : 0 : sal_uInt32 SvNumberFormatter::GetIndexPuttingAndConverting( String & rString,
589 : : LanguageType eLnge, LanguageType eSysLnge, short & rType,
590 : : bool & rNewInserted, xub_StrLen & rCheckPos )
591 : : {
592 : 0 : sal_uInt32 nKey = NUMBERFORMAT_ENTRY_NOT_FOUND;
593 : 0 : rNewInserted = false;
594 : 0 : rCheckPos = 0;
595 : :
596 : : // #62389# empty format string (of Writer) => General standard format
597 [ # # ]: 0 : if (!rString.Len())
598 : : ; // nothing
599 [ # # ][ # # ]: 0 : else if (eLnge == LANGUAGE_SYSTEM && eSysLnge != SvtSysLocale().GetLanguage())
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
600 : : {
601 [ # # ]: 0 : sal_uInt32 nOrig = GetEntryKey( rString, eSysLnge );
602 [ # # ]: 0 : if (nOrig == NUMBERFORMAT_ENTRY_NOT_FOUND)
603 : 0 : nKey = nOrig; // none avaliable, maybe user-defined
604 : : else
605 [ # # ][ # # ]: 0 : nKey = GetFormatForLanguageIfBuiltIn( nOrig, SvtSysLocale().GetLanguage() );
[ # # ][ # # ]
606 : :
607 [ # # ]: 0 : if (nKey == nOrig)
608 : : {
609 : : // Not a builtin format, convert.
610 : : // The format code string may get modified and adapted to the real
611 : : // language and wouldn't match eSysLnge anymore, do that on a copy.
612 [ # # ]: 0 : String aTmp( rString);
613 : : rNewInserted = PutandConvertEntrySystem( aTmp, rCheckPos, rType,
614 [ # # ][ # # ]: 0 : nKey, eLnge, SvtSysLocale().GetLanguage());
[ # # ][ # # ]
615 [ # # ]: 0 : if (rCheckPos > 0)
616 : : {
617 : : SAL_WARN( "svl.numbers", "SvNumberFormatter::GetIndexPuttingAndConverting: bad format code string for current locale");
618 : 0 : nKey = NUMBERFORMAT_ENTRY_NOT_FOUND;
619 [ # # ]: 0 : }
620 : : }
621 : : }
622 : : else
623 : : {
624 [ # # ]: 0 : nKey = GetEntryKey( rString, eLnge);
625 [ # # ]: 0 : if (nKey == NUMBERFORMAT_ENTRY_NOT_FOUND)
626 : : {
627 [ # # ]: 0 : rNewInserted = PutEntry( rString, rCheckPos, rType, nKey, eLnge);
628 [ # # ]: 0 : if (rCheckPos > 0)
629 : : {
630 : : SAL_WARN( "svl.numbers", "SvNumberFormatter::GetIndexPuttingAndConverting: bad format code string for specified locale");
631 : 0 : nKey = NUMBERFORMAT_ENTRY_NOT_FOUND;
632 : : }
633 : : }
634 : : }
635 [ # # ]: 0 : if (nKey == NUMBERFORMAT_ENTRY_NOT_FOUND)
636 [ # # ]: 0 : nKey = GetStandardIndex( eLnge);
637 [ # # ]: 0 : rType = GetType( nKey);
638 : : // Convert any (!) old "automatic" currency format to new fixed currency
639 : : // default format.
640 [ # # ]: 0 : if ((rType & NUMBERFORMAT_CURRENCY) != 0)
641 : : {
642 [ # # ]: 0 : const SvNumberformat* pFormat = GetEntry( nKey);
643 [ # # ][ # # ]: 0 : if (!pFormat->HasNewCurrency())
644 : : {
645 [ # # ]: 0 : if (rNewInserted)
646 : : {
647 [ # # ]: 0 : DeleteEntry( nKey); // don't leave trails of rubbish
648 : 0 : rNewInserted = false;
649 : : }
650 [ # # ]: 0 : nKey = GetStandardFormat( NUMBERFORMAT_CURRENCY, eLnge);
651 : : }
652 : : }
653 : 0 : return nKey;
654 : : }
655 : :
656 : :
657 : 232 : void SvNumberFormatter::DeleteEntry(sal_uInt32 nKey)
658 : : {
659 [ + - ]: 232 : delete aFTable[nKey];
660 : 232 : aFTable.erase(nKey);
661 : 232 : }
662 : :
663 : 0 : bool SvNumberFormatter::Load( SvStream& rStream )
664 : : {
665 [ # # ][ # # ]: 0 : LanguageType eSysLang = SvtSysLocale().GetLanguage();
[ # # ]
666 : 0 : SvNumberFormatter* pConverter = NULL;
667 : :
668 [ # # ]: 0 : ImpSvNumMultipleReadHeader aHdr( rStream );
669 : : sal_uInt16 nVersion;
670 [ # # ]: 0 : rStream >> nVersion;
671 : : SvNumberformat* pEntry;
672 : : sal_uInt32 nPos;
673 : : sal_uInt16 nSysOnStore, eLge, eDummy; // Dummy for compatible format
674 [ # # ][ # # ]: 0 : rStream >> nSysOnStore >> eLge; // system language from document
675 : :
676 : : SAL_WARN_IF( nVersion < SV_NUMBERFORMATTER_VERSION_CALENDAR, "svl.numbers", "SvNumberFormatter::Load: where does this unsupported old data come from?!?");
677 : :
678 : 0 : LanguageType eSaveSysLang = (LanguageType) nSysOnStore;
679 : 0 : LanguageType eLnge = (LanguageType) eLge;
680 [ # # ]: 0 : ImpChangeSysCL( eLnge, true );
681 : :
682 [ # # ]: 0 : rStream >> nPos;
683 [ # # ]: 0 : while (nPos != NUMBERFORMAT_ENTRY_NOT_FOUND)
684 : : {
685 [ # # ][ # # ]: 0 : rStream >> eDummy >> eLge;
686 : 0 : eLnge = (LanguageType) eLge;
687 [ # # ]: 0 : ImpGenerateCL( eLnge, true ); // create new standard formats if necessary
688 : :
689 : 0 : sal_uInt32 nOffset = nPos % SV_COUNTRY_LANGUAGE_OFFSET; // relativIndex
690 : 0 : bool bUserDefined = (nOffset > SV_MAX_ANZ_STANDARD_FORMATE);
691 : :
692 [ # # ][ # # ]: 0 : pEntry = new SvNumberformat(*pFormatScanner, eLnge);
693 [ # # ]: 0 : pEntry->Load( rStream, aHdr, NULL, *pStringScanner );
694 [ # # ]: 0 : if ( !bUserDefined )
695 : 0 : bUserDefined = (pEntry->GetNewStandardDefined() > SV_NUMBERFORMATTER_VERSION);
696 [ # # ]: 0 : if ( bUserDefined )
697 : : {
698 [ # # ]: 0 : LanguageType eLoadSysLang = (eLnge == LANGUAGE_SYSTEM ? eSysLang : eSaveSysLang);
699 [ # # ]: 0 : if ( eSaveSysLang != eLoadSysLang )
700 : : { // different SYSTEM locale
701 [ # # ]: 0 : if ( !pConverter )
702 [ # # ][ # # ]: 0 : pConverter = new SvNumberFormatter( xServiceManager, eSysLang );
703 : : pEntry->ConvertLanguage( *pConverter,
704 [ # # ]: 0 : eSaveSysLang, eLoadSysLang, true );
705 : : }
706 : : }
707 [ # # ]: 0 : if ( nOffset == 0 ) // Standard/General format
708 : : {
709 [ # # ]: 0 : SvNumberformat* pEnt = GetFormatEntry(nPos);
710 [ # # ]: 0 : if (pEnt)
711 : 0 : pEnt->SetLastInsertKey(pEntry->GetLastInsertKey());
712 : : }
713 [ # # ][ # # ]: 0 : if (!aFTable.insert(make_pair( nPos, pEntry)).second)
[ # # ]
714 [ # # ][ # # ]: 0 : delete pEntry;
715 [ # # ]: 0 : rStream >> nPos;
716 : : }
717 : :
718 : : // as of SV_NUMBERFORMATTER_VERSION_YEAR2000
719 [ # # ]: 0 : if ( nVersion >= SV_NUMBERFORMATTER_VERSION_YEAR2000 )
720 : : {
721 [ # # ]: 0 : aHdr.StartEntry();
722 [ # # ][ # # ]: 0 : if ( aHdr.BytesLeft() >= sizeof(sal_uInt16) )
723 : : {
724 : : sal_uInt16 nY2k;
725 [ # # ]: 0 : rStream >> nY2k;
726 [ # # ][ # # ]: 0 : if ( nVersion < SV_NUMBERFORMATTER_VERSION_TWODIGITYEAR && nY2k < 100 )
727 : 0 : nY2k += 1901; // was before src513e: 29, now: 1930
728 [ # # ]: 0 : SetYear2000( nY2k );
729 : : }
730 [ # # ]: 0 : aHdr.EndEntry();
731 : : }
732 : :
733 [ # # ]: 0 : if ( pConverter )
734 [ # # ][ # # ]: 0 : delete pConverter;
735 : :
736 : : // generate additional i18n standard formats for all used locales
737 : 0 : LanguageType eOldLanguage = ActLnge;
738 [ # # ]: 0 : NumberFormatCodeWrapper aNumberFormatCode( xServiceManager, GetLocale() );
739 [ # # ]: 0 : std::vector<sal_uInt16> aList;
740 [ # # ]: 0 : GetUsedLanguages( aList );
741 [ # # ][ # # ]: 0 : for ( std::vector<sal_uInt16>::const_iterator it(aList.begin()); it != aList.end(); ++it )
[ # # ][ # # ]
742 : : {
743 [ # # ]: 0 : LanguageType eLang = *it;
744 [ # # ]: 0 : ChangeIntl( eLang );
745 [ # # ]: 0 : sal_uInt32 CLOffset = ImpGetCLOffset( eLang );
746 [ # # ]: 0 : ImpGenerateAdditionalFormats( CLOffset, aNumberFormatCode, true );
747 : : }
748 [ # # ]: 0 : ChangeIntl( eOldLanguage );
749 : :
750 [ # # ]: 0 : if (rStream.GetError())
751 : 0 : return false;
752 : : else
753 [ # # ][ # # ]: 0 : return true;
754 : : }
755 : :
756 : 0 : bool SvNumberFormatter::Save( SvStream& rStream ) const
757 : : {
758 [ # # ]: 0 : ImpSvNumMultipleWriteHeader aHdr( rStream );
759 : : // As of 364i we store what SYSTEM locale really was, before it was hard
760 : : // coded LANGUAGE_SYSTEM.
761 [ # # ]: 0 : rStream << (sal_uInt16) SV_NUMBERFORMATTER_VERSION;
762 [ # # ][ # # ]: 0 : rStream << (sal_uInt16) SvtSysLocale().GetLanguage() << (sal_uInt16) IniLnge;
[ # # ][ # # ]
[ # # ]
763 : 0 : const SvNumberFormatTable* pTable = &aFTable;
764 : 0 : SvNumberFormatTable::const_iterator it = pTable->begin();
765 [ # # ][ # # ]: 0 : while (it != pTable->end())
766 : : {
767 [ # # ]: 0 : SvNumberformat* pEntry = it->second;
768 : : // Stored are all marked user defined formats and for each active
769 : : // (selected) locale the Standard/General format and
770 : : // NewStandardDefined.
771 [ # # ]: 0 : if ( pEntry->GetUsed() || (pEntry->GetType() & NUMBERFORMAT_DEFINED) ||
[ # # # # ]
[ # # ][ # # ]
772 : 0 : pEntry->GetNewStandardDefined() ||
773 [ # # ]: 0 : (it->first % SV_COUNTRY_LANGUAGE_OFFSET == 0) )
774 : : {
775 [ # # ][ # # ]: 0 : rStream << it->first
776 [ # # ]: 0 : << (sal_uInt16) LANGUAGE_SYSTEM
777 [ # # ]: 0 : << (sal_uInt16) pEntry->GetLanguage();
778 [ # # ]: 0 : pEntry->Save(rStream, aHdr);
779 : : }
780 [ # # ]: 0 : ++it;
781 : : }
782 [ # # ]: 0 : rStream << NUMBERFORMAT_ENTRY_NOT_FOUND; // end marker
783 : :
784 : : // as of SV_NUMBERFORMATTER_VERSION_YEAR2000
785 [ # # ]: 0 : aHdr.StartEntry();
786 [ # # ][ # # ]: 0 : rStream << (sal_uInt16) GetYear2000();
787 [ # # ]: 0 : aHdr.EndEntry();
788 : :
789 [ # # ]: 0 : if (rStream.GetError())
790 : 0 : return false;
791 : : else
792 [ # # ]: 0 : return true;
793 : : }
794 : :
795 : 178 : void SvNumberFormatter::GetUsedLanguages( std::vector<sal_uInt16>& rList )
796 : : {
797 : 178 : rList.clear();
798 : :
799 : 178 : sal_uInt32 nOffset = 0;
800 [ + + ]: 356 : while (nOffset <= MaxCLOffset)
801 : : {
802 : 178 : SvNumberformat* pFormat = GetFormatEntry(nOffset);
803 [ + - ]: 178 : if (pFormat)
804 [ + - ]: 178 : rList.push_back( pFormat->GetLanguage() );
805 : 178 : nOffset += SV_COUNTRY_LANGUAGE_OFFSET;
806 : : }
807 : 178 : }
808 : :
809 : :
810 : 0 : void SvNumberFormatter::FillKeywordTable( NfKeywordTable& rKeywords,
811 : : LanguageType eLang )
812 : : {
813 : 0 : ChangeIntl( eLang );
814 : 0 : const NfKeywordTable & rTable = pFormatScanner->GetKeywords();
815 [ # # ]: 0 : for ( sal_uInt16 i = 0; i < NF_KEYWORD_ENTRIES_COUNT; ++i )
816 : : {
817 : 0 : rKeywords[i] = rTable[i];
818 : : }
819 : 0 : }
820 : :
821 : :
822 : 454 : String SvNumberFormatter::GetKeyword( LanguageType eLnge, sal_uInt16 nIndex )
823 : : {
824 : 454 : ChangeIntl(eLnge);
825 : 454 : const NfKeywordTable & rTable = pFormatScanner->GetKeywords();
826 [ + - ]: 454 : if ( nIndex < NF_KEYWORD_ENTRIES_COUNT )
827 : 454 : return rTable[nIndex];
828 : :
829 : : OSL_FAIL("GetKeyword: invalid index");
830 : 454 : return String();
831 : : }
832 : :
833 : :
834 : 99 : String SvNumberFormatter::GetStandardName( LanguageType eLnge )
835 : : {
836 : 99 : ChangeIntl( eLnge );
837 : 99 : return pFormatScanner->GetStandardName();
838 : : }
839 : :
840 : :
841 : 36630 : sal_uInt32 SvNumberFormatter::ImpGetCLOffset(LanguageType eLnge) const
842 : : {
843 : 36630 : sal_uInt32 nOffset = 0;
844 [ + + ]: 55368 : while (nOffset <= MaxCLOffset)
845 : : {
846 : 55119 : const SvNumberformat* pFormat = GetFormatEntry(nOffset);
847 [ + + ][ + + ]: 55119 : if (pFormat && pFormat->GetLanguage() == eLnge)
[ + - ]
848 : 36381 : return nOffset;
849 : 18738 : nOffset += SV_COUNTRY_LANGUAGE_OFFSET;
850 : : }
851 : 36630 : return nOffset;
852 : : }
853 : :
854 : 42431 : sal_uInt32 SvNumberFormatter::ImpIsEntry(const String& rString,
855 : : sal_uInt32 nCLOffset,
856 : : LanguageType eLnge)
857 : : {
858 : 42431 : sal_uInt32 res = NUMBERFORMAT_ENTRY_NOT_FOUND;
859 [ + - ]: 42431 : SvNumberFormatTable::iterator it = aFTable.find( nCLOffset);
860 [ + + ]: 10365311 : while ( res == NUMBERFORMAT_ENTRY_NOT_FOUND &&
[ + + + + ]
[ + + ]
861 [ + - ][ + - ]: 7762890 : it != aFTable.end() && it->second->GetLanguage() == eLnge )
[ + + ][ # # ]
862 : : {
863 [ + - ][ + - ]: 2559990 : if ( rString == it->second->GetFormatstring() )
[ + + ]
864 [ + - ]: 2792 : res = it->first;
865 : : else
866 [ + - ]: 2557198 : ++it;
867 : : }
868 : 42431 : return res;
869 : : }
870 : :
871 : :
872 : 0 : SvNumberFormatTable& SvNumberFormatter::GetFirstEntryTable(
873 : : short& eType,
874 : : sal_uInt32& FIndex,
875 : : LanguageType& rLnge)
876 : : {
877 : 0 : short eTypetmp = eType;
878 [ # # ]: 0 : if (eType == NUMBERFORMAT_ALL) // empty cell or don't care
879 : 0 : rLnge = IniLnge;
880 : : else
881 : : {
882 : 0 : SvNumberformat* pFormat = GetFormatEntry(FIndex);
883 [ # # ]: 0 : if (!pFormat)
884 : : {
885 : 0 : rLnge = IniLnge;
886 : 0 : eType = NUMBERFORMAT_ALL;
887 : 0 : eTypetmp = eType;
888 : : }
889 : : else
890 : : {
891 : 0 : rLnge = pFormat->GetLanguage();
892 : 0 : eType = pFormat->GetType()&~NUMBERFORMAT_DEFINED;
893 [ # # ]: 0 : if (eType == 0)
894 : : {
895 : 0 : eType = NUMBERFORMAT_DEFINED;
896 : 0 : eTypetmp = eType;
897 : : }
898 [ # # ]: 0 : else if (eType == NUMBERFORMAT_DATETIME)
899 : : {
900 : 0 : eTypetmp = eType;
901 : 0 : eType = NUMBERFORMAT_DATE;
902 : : }
903 : : else
904 : 0 : eTypetmp = eType;
905 : : }
906 : : }
907 : 0 : ChangeIntl(rLnge);
908 : 0 : return GetEntryTable(eTypetmp, FIndex, rLnge);
909 : : }
910 : :
911 : 31238 : sal_uInt32 SvNumberFormatter::ImpGenerateCL( LanguageType eLnge, bool bNoAdditionalFormats )
912 : : {
913 : 31238 : ChangeIntl(eLnge);
914 : 31238 : sal_uInt32 CLOffset = ImpGetCLOffset(ActLnge);
915 [ + + ]: 31238 : if (CLOffset > MaxCLOffset)
916 : : { // new CL combination
917 [ - + ]: 249 : if (LocaleDataWrapper::areChecksEnabled())
918 : : {
919 [ # # ]: 0 : Locale aLoadedLocale = xLocaleData->getLoadedLocale();
920 [ # # # # ]: 0 : if ( aLoadedLocale.Language != aLocale.Language ||
[ # # ]
921 : 0 : aLoadedLocale.Country != aLocale.Country )
922 : : {
923 : 0 : rtl::OUString aMsg("SvNumerFormatter::ImpGenerateCL: locales don't match:");
924 [ # # ][ # # ]: 0 : LocaleDataWrapper::outputCheckMessage( xLocaleData->appendLocaleInfo( aMsg ));
925 : : }
926 : : // test XML locale data FormatElement entries
927 : : {
928 [ # # ]: 0 : uno::Sequence< i18n::FormatElement > xSeq = xLocaleData->getAllFormats();
929 : : // A test for completeness of formatindex="0" ...
930 : : // formatindex="47" is not needed here since it is done in
931 : : // ImpGenerateFormats().
932 : :
933 : : // Test for dupes of formatindex="..."
934 [ # # ]: 0 : for ( sal_Int32 j = 0; j < xSeq.getLength(); j++ )
935 : : {
936 [ # # ]: 0 : sal_Int16 nIdx = xSeq[j].formatIndex;
937 : 0 : rtl::OUString aDupes;
938 [ # # ]: 0 : for ( sal_Int32 i = 0; i < xSeq.getLength(); i++ )
939 : : {
940 [ # # ][ # # ]: 0 : if ( i != j && xSeq[i].formatIndex == nIdx )
[ # # ][ # # ]
941 : : {
942 : 0 : aDupes += rtl::OUString::valueOf( i );
943 : 0 : aDupes += "(";
944 [ # # ]: 0 : aDupes += rtl::OUString( xSeq[i].formatKey );
945 : 0 : aDupes += ") ";
946 : : }
947 : : }
948 [ # # ]: 0 : if ( !aDupes.isEmpty() )
949 : : {
950 : 0 : rtl::OUString aMsg("XML locale data FormatElement formatindex dupe: ");
951 : 0 : aMsg += rtl::OUString::valueOf( sal_Int32(nIdx) );
952 : 0 : aMsg += "\nFormatElements: ";
953 : 0 : aMsg += rtl::OUString::valueOf( j );
954 : 0 : aMsg += "(";
955 [ # # ]: 0 : aMsg += rtl::OUString( xSeq[j].formatKey );
956 : 0 : aMsg += ") ";
957 : 0 : aMsg += aDupes;
958 : : LocaleDataWrapper::outputCheckMessage(
959 [ # # ][ # # ]: 0 : xLocaleData->appendLocaleInfo( aMsg ));
960 : : }
961 [ # # ]: 0 : }
962 : 0 : }
963 : : }
964 : :
965 : 249 : MaxCLOffset += SV_COUNTRY_LANGUAGE_OFFSET;
966 : 249 : ImpGenerateFormats( MaxCLOffset, bNoAdditionalFormats );
967 : 249 : CLOffset = MaxCLOffset;
968 : : }
969 : 31238 : return CLOffset;
970 : : }
971 : :
972 : 2557 : SvNumberFormatTable& SvNumberFormatter::ChangeCL(short eType,
973 : : sal_uInt32& FIndex,
974 : : LanguageType eLnge)
975 : : {
976 : 2557 : ImpGenerateCL(eLnge);
977 : 2557 : return GetEntryTable(eType, FIndex, ActLnge);
978 : : }
979 : :
980 : 2735 : SvNumberFormatTable& SvNumberFormatter::GetEntryTable(
981 : : short eType,
982 : : sal_uInt32& FIndex,
983 : : LanguageType eLnge)
984 : : {
985 [ + + ]: 2735 : if ( pFormatTable )
986 : 2519 : pFormatTable->clear();
987 : : else
988 [ + - ][ + - ]: 216 : pFormatTable = new SvNumberFormatTable;
989 [ + - ]: 2735 : ChangeIntl(eLnge);
990 [ + - ]: 2735 : sal_uInt32 CLOffset = ImpGetCLOffset(ActLnge);
991 : :
992 : : // Might generate and insert a default format for the given type
993 : : // (e.g. currency) => has to be done before collecting formats.
994 [ + - ]: 2735 : sal_uInt32 nDefaultIndex = GetStandardFormat( eType, ActLnge );
995 : :
996 [ + - ]: 2735 : SvNumberFormatTable::iterator it = aFTable.find( CLOffset);
997 : :
998 [ - + ]: 2735 : if (eType == NUMBERFORMAT_ALL)
999 : : {
1000 [ # # ][ # # ]: 0 : while (it != aFTable.end() && it->second->GetLanguage() == ActLnge)
[ # # ][ # # ]
[ # # ]
[ # # # # ]
1001 : : { // copy all entries to output table
1002 [ # # ][ # # ]: 0 : (*pFormatTable)[ it->first ] = it->second;
[ # # ]
1003 [ # # ]: 0 : ++it;
1004 : : }
1005 : : }
1006 : : else
1007 : : {
1008 [ + - ][ + + ]: 185980 : while (it != aFTable.end() && it->second->GetLanguage() == ActLnge)
[ + - ][ + - ]
[ + - ]
[ + + # # ]
1009 : : { // copy entries of queried type to output table
1010 [ + - ][ + + ]: 183245 : if ((it->second->GetType()) & eType)
1011 [ + - ][ + - ]: 76512 : (*pFormatTable)[ it->first ] = it->second;
[ + - ]
1012 [ + - ]: 183245 : ++it;
1013 : : }
1014 : : }
1015 [ + + ]: 2735 : if ( !pFormatTable->empty() )
1016 : : { // select default if queried format doesn't exist or queried type or
1017 : : // language differ from existing format
1018 [ + - ]: 2557 : SvNumberformat* pEntry = GetFormatEntry(FIndex);
1019 [ + - ][ - + ]: 2557 : if ( !pEntry || !(pEntry->GetType() & eType) || pEntry->GetLanguage() != ActLnge )
[ # # ][ + - ]
1020 : 2557 : FIndex = nDefaultIndex;
1021 : : }
1022 : 2735 : return *pFormatTable;
1023 : : }
1024 : :
1025 : 6781 : bool SvNumberFormatter::IsNumberFormat(const String& sString,
1026 : : sal_uInt32& F_Index,
1027 : : double& fOutNumber)
1028 : : {
1029 : : short FType;
1030 [ + - ]: 6781 : const SvNumberformat* pFormat = GetFormatEntry(F_Index);
1031 [ + + ]: 6781 : if (!pFormat)
1032 : : {
1033 [ + - ]: 40 : ChangeIntl(IniLnge);
1034 : 40 : FType = NUMBERFORMAT_NUMBER;
1035 : : }
1036 : : else
1037 : : {
1038 : 6741 : FType = pFormat->GetType() &~NUMBERFORMAT_DEFINED;
1039 [ - + ]: 6741 : if (FType == 0)
1040 : 0 : FType = NUMBERFORMAT_DEFINED;
1041 [ + - ]: 6741 : ChangeIntl(pFormat->GetLanguage());
1042 : : }
1043 : : bool res;
1044 : 6781 : short RType = FType;
1045 [ - + ]: 6781 : if (RType == NUMBERFORMAT_TEXT)
1046 : 0 : res = false; // type text preset => no conversion to number
1047 : : else
1048 [ + - ]: 6781 : res = pStringScanner->IsNumberFormat(sString, RType, fOutNumber, pFormat);
1049 : :
1050 [ + + ][ + - ]: 6781 : if (res && !IsCompatible(FType, RType)) // non-matching type
[ + + ][ + + ]
1051 : : {
1052 [ + - + ]: 156 : switch ( RType )
1053 : : {
1054 : : case NUMBERFORMAT_DATE :
1055 : : // Preserve ISO 8601 input.
1056 [ + - ][ + - ]: 132 : if (pStringScanner->CanForceToIso8601( DMY))
1057 [ + - ]: 132 : F_Index = GetFormatIndex( NF_DATE_DIN_YYYYMMDD, ActLnge );
1058 : : else
1059 [ # # ]: 0 : F_Index = GetStandardFormat( RType, ActLnge );
1060 : 132 : break;
1061 : : case NUMBERFORMAT_TIME :
1062 [ # # ]: 0 : if ( pStringScanner->GetDecPos() )
1063 : : { // 100th seconds
1064 [ # # ][ # # ]: 0 : if ( pStringScanner->GetAnzNums() > 3 || fOutNumber < 0.0 )
[ # # ]
1065 [ # # ]: 0 : F_Index = GetFormatIndex( NF_TIME_HH_MMSS00, ActLnge );
1066 : : else
1067 [ # # ]: 0 : F_Index = GetFormatIndex( NF_TIME_MMSS00, ActLnge );
1068 : : }
1069 [ # # ][ # # ]: 0 : else if ( fOutNumber >= 1.0 || fOutNumber < 0.0 )
1070 [ # # ]: 0 : F_Index = GetFormatIndex( NF_TIME_HH_MMSS, ActLnge );
1071 : : else
1072 [ # # ]: 0 : F_Index = GetStandardFormat( RType, ActLnge );
1073 : 0 : break;
1074 : : default:
1075 [ + - ]: 156 : F_Index = GetStandardFormat( RType, ActLnge );
1076 : : }
1077 : : }
1078 : 6781 : return res;
1079 : : }
1080 : :
1081 : 2993 : bool SvNumberFormatter::IsCompatible(short eOldType,
1082 : : short eNewType)
1083 : : {
1084 [ + + ]: 2993 : if (eOldType == eNewType)
1085 : 2827 : return true;
1086 [ - + ]: 166 : else if (eOldType == NUMBERFORMAT_DEFINED)
1087 : 0 : return true;
1088 : : else
1089 : : {
1090 [ + + - + : 166 : switch (eNewType)
- ]
1091 : : {
1092 : : case NUMBERFORMAT_NUMBER:
1093 : : {
1094 [ + - ]: 10 : switch (eOldType)
1095 : : {
1096 : : case NUMBERFORMAT_PERCENT:
1097 : : case NUMBERFORMAT_CURRENCY:
1098 : : case NUMBERFORMAT_SCIENTIFIC:
1099 : : case NUMBERFORMAT_FRACTION:
1100 : : // case NUMBERFORMAT_LOGICAL:
1101 : : case NUMBERFORMAT_DEFINED:
1102 : 10 : return true;
1103 : : default:
1104 : 0 : return false;
1105 : : }
1106 : : }
1107 : : break;
1108 : : case NUMBERFORMAT_DATE:
1109 : : {
1110 [ - + ]: 132 : switch (eOldType)
1111 : : {
1112 : : case NUMBERFORMAT_DATETIME:
1113 : 0 : return true;
1114 : : default:
1115 : 132 : return false;
1116 : : }
1117 : : }
1118 : : break;
1119 : : case NUMBERFORMAT_TIME:
1120 : : {
1121 [ # # ]: 0 : switch (eOldType)
1122 : : {
1123 : : case NUMBERFORMAT_DATETIME:
1124 : 0 : return true;
1125 : : default:
1126 : 0 : return false;
1127 : : }
1128 : : }
1129 : : break;
1130 : : case NUMBERFORMAT_DATETIME:
1131 : : {
1132 [ - + ]: 24 : switch (eOldType)
1133 : : {
1134 : : case NUMBERFORMAT_TIME:
1135 : : case NUMBERFORMAT_DATE:
1136 : 0 : return true;
1137 : : default:
1138 : 24 : return false;
1139 : : }
1140 : : }
1141 : : break;
1142 : : default:
1143 : 2993 : return false;
1144 : : }
1145 : : }
1146 : : }
1147 : :
1148 : :
1149 : 2657 : sal_uInt32 SvNumberFormatter::ImpGetDefaultFormat( short nType )
1150 : : {
1151 [ + - ]: 2657 : sal_uInt32 CLOffset = ImpGetCLOffset( ActLnge );
1152 : : sal_uInt32 nSearch;
1153 [ + - + + : 2657 : switch( nType )
- - ]
1154 : : {
1155 : : case NUMBERFORMAT_DATE :
1156 : 2532 : nSearch = CLOffset + ZF_STANDARD_DATE;
1157 : 2532 : break;
1158 : : case NUMBERFORMAT_TIME :
1159 : 0 : nSearch = CLOffset + ZF_STANDARD_TIME;
1160 : 0 : break;
1161 : : case NUMBERFORMAT_DATETIME :
1162 : 30 : nSearch = CLOffset + ZF_STANDARD_DATETIME;
1163 : 30 : break;
1164 : : case NUMBERFORMAT_PERCENT :
1165 : 95 : nSearch = CLOffset + ZF_STANDARD_PERCENT;
1166 : 95 : break;
1167 : : case NUMBERFORMAT_SCIENTIFIC:
1168 : 0 : nSearch = CLOffset + ZF_STANDARD_SCIENTIFIC;
1169 : 0 : break;
1170 : : default:
1171 : 0 : nSearch = CLOffset + ZF_STANDARD;
1172 : : }
1173 [ + - ]: 2657 : DefaultFormatKeysMap::iterator it = aDefaultFormatKeys.find( nSearch);
1174 [ + - ]: 2657 : sal_uInt32 nDefaultFormat = (it != aDefaultFormatKeys.end() ?
1175 [ + + ][ + - ]: 2657 : it->second : NUMBERFORMAT_ENTRY_NOT_FOUND);
1176 [ + + ]: 2657 : if ( nDefaultFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
1177 : : { // look for a defined standard
1178 : 69 : sal_uInt32 nStopKey = CLOffset + SV_COUNTRY_LANGUAGE_OFFSET;
1179 : : sal_uInt32 nKey;
1180 [ + - ]: 69 : SvNumberFormatTable::iterator it2 = aFTable.find( CLOffset );
1181 [ + - ][ + - ]: 1522 : while ( it2 != aFTable.end() && (nKey = it2->first ) >= CLOffset && nKey < nStopKey )
[ + - ][ + - ]
[ + - ][ + - ]
[ + - # # ]
1182 : : {
1183 [ + - ]: 1522 : const SvNumberformat* pEntry = it2->second;
1184 [ + + ][ + + ]: 1522 : if ( pEntry->IsStandard() && ((pEntry->GetType() &
[ + + ]
1185 : : ~NUMBERFORMAT_DEFINED) == nType) )
1186 : : {
1187 : 69 : nDefaultFormat = nKey;
1188 : 69 : break; // while
1189 : : }
1190 [ + - ]: 1453 : ++it2;
1191 : : }
1192 : :
1193 [ - + ]: 69 : if ( nDefaultFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
1194 : : { // none found, use old fixed standards
1195 [ # # # # : 0 : switch( nType )
# # ]
1196 : : {
1197 : : case NUMBERFORMAT_DATE :
1198 : 0 : nDefaultFormat = CLOffset + ZF_STANDARD_DATE;
1199 : 0 : break;
1200 : : case NUMBERFORMAT_TIME :
1201 : 0 : nDefaultFormat = CLOffset + ZF_STANDARD_TIME+1;
1202 : 0 : break;
1203 : : case NUMBERFORMAT_DATETIME :
1204 : 0 : nDefaultFormat = CLOffset + ZF_STANDARD_DATETIME;
1205 : 0 : break;
1206 : : case NUMBERFORMAT_PERCENT :
1207 : 0 : nDefaultFormat = CLOffset + ZF_STANDARD_PERCENT+1;
1208 : 0 : break;
1209 : : case NUMBERFORMAT_SCIENTIFIC:
1210 : 0 : nDefaultFormat = CLOffset + ZF_STANDARD_SCIENTIFIC;
1211 : 0 : break;
1212 : : default:
1213 : 0 : nDefaultFormat = CLOffset + ZF_STANDARD;
1214 : : }
1215 : : }
1216 [ + - ]: 69 : aDefaultFormatKeys[ nSearch ] = nDefaultFormat;
1217 : : }
1218 : 2657 : return nDefaultFormat;
1219 : : }
1220 : :
1221 : :
1222 : 9999 : sal_uInt32 SvNumberFormatter::GetStandardFormat( short eType, LanguageType eLnge )
1223 : : {
1224 [ + + ]: 9999 : if (eLnge == LANGUAGE_DONTKNOW)
1225 : 121 : eLnge = IniLnge;
1226 : :
1227 : 9999 : sal_uInt32 CLOffset = ImpGenerateCL(eLnge);
1228 [ + + - + : 9999 : switch(eType)
+ + ]
1229 : : {
1230 : : case NUMBERFORMAT_CURRENCY :
1231 : : {
1232 [ + - ]: 190 : if ( eLnge == LANGUAGE_SYSTEM )
1233 : 190 : return ImpGetDefaultSystemCurrencyFormat();
1234 : : else
1235 : 0 : return ImpGetDefaultCurrencyFormat();
1236 : : }
1237 : : case NUMBERFORMAT_DATE :
1238 : : case NUMBERFORMAT_TIME :
1239 : : case NUMBERFORMAT_DATETIME :
1240 : : case NUMBERFORMAT_PERCENT :
1241 : : case NUMBERFORMAT_SCIENTIFIC:
1242 : 2657 : return ImpGetDefaultFormat( eType );
1243 : :
1244 : 0 : case NUMBERFORMAT_FRACTION : return CLOffset + ZF_STANDARD_FRACTION;
1245 : 56 : case NUMBERFORMAT_LOGICAL : return CLOffset + ZF_STANDARD_LOGICAL;
1246 : 834 : case NUMBERFORMAT_TEXT : return CLOffset + ZF_STANDARD_TEXT;
1247 : : case NUMBERFORMAT_ALL :
1248 : : case NUMBERFORMAT_DEFINED :
1249 : : case NUMBERFORMAT_NUMBER :
1250 : : case NUMBERFORMAT_UNDEFINED :
1251 : 9999 : default : return CLOffset + ZF_STANDARD;
1252 : : }
1253 : : }
1254 : :
1255 : 2123 : bool SvNumberFormatter::IsSpecialStandardFormat( sal_uInt32 nFIndex,
1256 : : LanguageType eLnge )
1257 : : {
1258 : : return
1259 : 2123 : nFIndex == GetFormatIndex( NF_TIME_MMSS00, eLnge ) ||
1260 : 2123 : nFIndex == GetFormatIndex( NF_TIME_HH_MMSS00, eLnge ) ||
1261 [ - + ]: 4246 : nFIndex == GetFormatIndex( NF_TIME_HH_MMSS, eLnge )
[ + - + - ]
1262 : : ;
1263 : : }
1264 : :
1265 : 257 : sal_uInt32 SvNumberFormatter::GetStandardFormat( sal_uInt32 nFIndex, short eType,
1266 : : LanguageType eLnge )
1267 : : {
1268 [ - + ]: 257 : if ( IsSpecialStandardFormat( nFIndex, eLnge ) )
1269 : 0 : return nFIndex;
1270 : : else
1271 : 257 : return GetStandardFormat( eType, eLnge );
1272 : : }
1273 : :
1274 : 1866 : sal_uInt32 SvNumberFormatter::GetStandardFormat( double fNumber, sal_uInt32 nFIndex,
1275 : : short eType, LanguageType eLnge )
1276 : : {
1277 [ - + ]: 1866 : if ( IsSpecialStandardFormat( nFIndex, eLnge ) )
1278 : 0 : return nFIndex;
1279 : :
1280 [ - + ]: 1866 : switch( eType )
1281 : : {
1282 : : case NUMBERFORMAT_TIME :
1283 : : {
1284 : : bool bSign;
1285 [ # # ]: 0 : if ( fNumber < 0.0 )
1286 : : {
1287 : 0 : bSign = true;
1288 : 0 : fNumber = -fNumber;
1289 : : }
1290 : : else
1291 : 0 : bSign = false;
1292 : 0 : double fSeconds = fNumber * 86400;
1293 [ # # ]: 0 : if ( floor( fSeconds + 0.5 ) * 100 != floor( fSeconds * 100 + 0.5 ) )
1294 : : { // with 100th seconds
1295 [ # # ][ # # ]: 0 : if ( bSign || fSeconds >= 3600 )
1296 : 0 : return GetFormatIndex( NF_TIME_HH_MMSS00, eLnge );
1297 : : else
1298 : 0 : return GetFormatIndex( NF_TIME_MMSS00, eLnge );
1299 : : }
1300 : : else
1301 : : {
1302 [ # # ][ # # ]: 0 : if ( bSign || fNumber >= 1.0 )
1303 : 0 : return GetFormatIndex( NF_TIME_HH_MMSS, eLnge );
1304 : : else
1305 : 0 : return GetStandardFormat( eType, eLnge );
1306 : : }
1307 : : }
1308 : : default:
1309 : 1866 : return GetStandardFormat( eType, eLnge );
1310 : : }
1311 : : }
1312 : :
1313 : 360 : sal_uInt32 SvNumberFormatter::GetEditFormat( double fNumber, sal_uInt32 nFIndex,
1314 : : short eType, LanguageType eLang, SvNumberformat* pFormat )
1315 : : {
1316 : 360 : sal_uInt32 nKey = nFIndex;
1317 [ + - - + ]: 360 : switch ( eType )
1318 : : { // #61619# always edit using 4-digit year
1319 : : case NUMBERFORMAT_DATE :
1320 [ - + ]: 6 : if (::rtl::math::approxFloor( fNumber) != fNumber)
1321 : 0 : nKey = GetFormatIndex( NF_DATETIME_SYS_DDMMYYYY_HHMMSS, eLang );
1322 : : // fdo#34977 preserve time when editing even if only date was
1323 : : // displayed.
1324 : : /* FIXME: in case an ISO 8601 format was used, editing should
1325 : : * also use such. Unfortunately we have no builtin combined
1326 : : * date+time ISO format defined. Needs also locale data work.
1327 : : * */
1328 : : else
1329 : : {
1330 : : // Preserve ISO 8601 format.
1331 [ + - + - : 24 : if ( nFIndex == GetFormatIndex( NF_DATE_DIN_YYYYMMDD, eLang) ||
+ - ]
[ + - - + ]
[ - + ]
1332 : 6 : nFIndex == GetFormatIndex( NF_DATE_DIN_YYMMDD, eLang) ||
1333 : 6 : nFIndex == GetFormatIndex( NF_DATE_DIN_MMDD, eLang) ||
1334 : 6 : (pFormat && pFormat->IsIso8601( 0 )))
1335 : 0 : nKey = GetFormatIndex( NF_DATE_DIN_YYYYMMDD, eLang);
1336 : : else
1337 : 6 : nKey = GetFormatIndex( NF_DATE_SYS_DDMMYYYY, eLang );
1338 : : }
1339 : 6 : break;
1340 : : case NUMBERFORMAT_TIME :
1341 [ # # ][ # # ]: 0 : if (fNumber < 0.0 || fNumber >= 1.0)
1342 : : {
1343 : : /* XXX NOTE: this is a purely arbitrary value within the limits
1344 : : * of a signed 16-bit. 32k hours are 3.7 years ... or
1345 : : * 1903-09-26 if date. */
1346 [ # # ]: 0 : if (fabs( fNumber) * 24 < 0x7fff)
1347 : 0 : nKey = GetFormatIndex( NF_TIME_HH_MMSS, eLang );
1348 : : // Preserve duration, use [HH]:MM:SS instead of time.
1349 : : else
1350 : 0 : nKey = GetFormatIndex( NF_DATETIME_SYS_DDMMYYYY_HHMMSS, eLang );
1351 : : // Assume that a large value is a datetime with only time
1352 : : // displayed.
1353 : : }
1354 : : else
1355 : 0 : nKey = GetStandardFormat( fNumber, nFIndex, eType, eLang );
1356 : 0 : break;
1357 : : case NUMBERFORMAT_DATETIME :
1358 : 0 : nKey = GetFormatIndex( NF_DATETIME_SYS_DDMMYYYY_HHMMSS, eLang );
1359 : : /* FIXME: in case an ISO 8601 format was used, editing should
1360 : : * also use such. Unfortunately we have no builtin combined
1361 : : * date+time ISO format defined. Needs also locale data work. */
1362 : 0 : break;
1363 : : default:
1364 : 354 : nKey = GetStandardFormat( fNumber, nFIndex, eType, eLang );
1365 : : }
1366 : 360 : return nKey;
1367 : : }
1368 : :
1369 : 360 : void SvNumberFormatter::GetInputLineString(const double& fOutNumber,
1370 : : sal_uInt32 nFIndex,
1371 : : String& sOutString)
1372 : : {
1373 : : Color* pColor;
1374 [ + - ]: 360 : SvNumberformat* pFormat = GetFormatEntry( nFIndex );
1375 [ - + ]: 360 : if (!pFormat)
1376 [ # # ]: 0 : pFormat = GetFormatEntry(ZF_STANDARD);
1377 : 360 : LanguageType eLang = pFormat->GetLanguage();
1378 [ + - ]: 360 : ChangeIntl( eLang );
1379 : 360 : short eType = pFormat->GetType() & ~NUMBERFORMAT_DEFINED;
1380 [ - + ]: 360 : if (eType == 0)
1381 : 0 : eType = NUMBERFORMAT_DEFINED;
1382 : 360 : sal_uInt16 nOldPrec = pFormatScanner->GetStandardPrec();
1383 : 360 : bool bPrecChanged = false;
1384 [ + - ][ + - ]: 360 : if (eType == NUMBERFORMAT_NUMBER || eType == NUMBERFORMAT_PERCENT
[ + - ][ - + ]
[ + + ]
1385 : : || eType == NUMBERFORMAT_CURRENCY
1386 : : || eType == NUMBERFORMAT_SCIENTIFIC
1387 : : || eType == NUMBERFORMAT_FRACTION)
1388 : : {
1389 [ + - ]: 354 : if (eType != NUMBERFORMAT_PERCENT) // special treatment of % later
1390 : 354 : eType = NUMBERFORMAT_NUMBER;
1391 [ + - ]: 354 : ChangeStandardPrec(INPUTSTRING_PRECISION);
1392 : 354 : bPrecChanged = true;
1393 : : }
1394 [ + - ]: 360 : sal_uInt32 nKey = GetEditFormat( fOutNumber, nFIndex, eType, eLang, pFormat);
1395 [ + + ]: 360 : if ( nKey != nFIndex )
1396 [ + - ]: 6 : pFormat = GetFormatEntry( nKey );
1397 [ + - ]: 360 : if (pFormat)
1398 : : {
1399 [ - + ][ # # ]: 360 : if ( eType == NUMBERFORMAT_TIME && pFormat->GetFormatPrecision() )
[ - + ]
1400 : : {
1401 [ # # ]: 0 : ChangeStandardPrec(INPUTSTRING_PRECISION);
1402 : 0 : bPrecChanged = true;
1403 : : }
1404 [ + - ]: 360 : pFormat->GetOutputString(fOutNumber, sOutString, &pColor);
1405 : : }
1406 [ + + ]: 360 : if (bPrecChanged)
1407 [ + - ]: 354 : ChangeStandardPrec(nOldPrec);
1408 : 360 : }
1409 : :
1410 : 14 : void SvNumberFormatter::GetInputLineString(const double& fOutNumber,
1411 : : sal_uInt32 nFIndex,
1412 : : rtl::OUString& rOutString)
1413 : : {
1414 [ + - ]: 14 : String aTmp;
1415 [ + - ]: 14 : GetInputLineString(fOutNumber, nFIndex, aTmp);
1416 [ + - ][ + - ]: 14 : rOutString = aTmp;
1417 : 14 : }
1418 : :
1419 : 12054 : void SvNumberFormatter::GetOutputString(const double& fOutNumber,
1420 : : sal_uInt32 nFIndex,
1421 : : String& sOutString,
1422 : : Color** ppColor,
1423 : : bool bUseStarFormat )
1424 : : {
1425 [ - + ][ # # ]: 12054 : if (bNoZero && fOutNumber == 0.0)
1426 : : {
1427 : 0 : sOutString.Erase();
1428 : 12054 : return;
1429 : : }
1430 : 12054 : SvNumberformat* pFormat = GetFormatEntry( nFIndex );
1431 [ + + ]: 12054 : if (!pFormat)
1432 : 16 : pFormat = GetFormatEntry(ZF_STANDARD);
1433 : 12054 : ChangeIntl(pFormat->GetLanguage());
1434 [ - + ]: 12054 : if ( bUseStarFormat )
1435 : 0 : pFormat->SetStarFormatSupport( true );
1436 : 12054 : pFormat->GetOutputString(fOutNumber, sOutString, ppColor);
1437 [ - + ]: 12054 : if ( bUseStarFormat )
1438 : 0 : pFormat->SetStarFormatSupport( false );
1439 : : }
1440 : :
1441 : 128 : void SvNumberFormatter::GetOutputString(String& sString,
1442 : : sal_uInt32 nFIndex,
1443 : : String& sOutString,
1444 : : Color** ppColor )
1445 : : {
1446 : 128 : SvNumberformat* pFormat = GetFormatEntry( nFIndex );
1447 [ - + ]: 128 : if (!pFormat)
1448 : 0 : pFormat = GetFormatEntry(ZF_STANDARD_TEXT);
1449 [ - + ][ # # ]: 128 : if (!pFormat->IsTextFormat() && !pFormat->HasTextFormat())
[ - + ]
1450 : : {
1451 : 0 : *ppColor = NULL;
1452 : 0 : sOutString = sString;
1453 : : }
1454 : : else
1455 : : {
1456 : 128 : ChangeIntl(pFormat->GetLanguage());
1457 : 128 : pFormat->GetOutputString(sString, sOutString, ppColor);
1458 : : }
1459 : 128 : }
1460 : :
1461 : 52935 : void SvNumberFormatter::GetOutputString(const double& fOutNumber,
1462 : : sal_uInt32 nFIndex,
1463 : : rtl::OUString& sOutString,
1464 : : Color** ppColor,
1465 : : bool bUseStarFormat )
1466 : : {
1467 [ - + ][ # # ]: 52935 : if (bNoZero && fOutNumber == 0.0)
1468 : : {
1469 : 0 : sOutString = rtl::OUString();
1470 : 52935 : return;
1471 : : }
1472 [ + - ]: 52935 : SvNumberformat* pFormat = GetFormatEntry( nFIndex );
1473 [ + + ]: 52935 : if (!pFormat)
1474 [ + - ]: 960 : pFormat = GetFormatEntry(ZF_STANDARD);
1475 [ + - ]: 52935 : ChangeIntl(pFormat->GetLanguage());
1476 [ + - ]: 52935 : String aOutString;
1477 [ + + ]: 52935 : if ( bUseStarFormat )
1478 : 5786 : pFormat->SetStarFormatSupport( true );
1479 [ + - ]: 52935 : pFormat->GetOutputString(fOutNumber, aOutString, ppColor);
1480 [ + + ]: 52935 : if ( bUseStarFormat )
1481 : 5786 : pFormat->SetStarFormatSupport( false );
1482 [ + - ][ + - ]: 52935 : sOutString = aOutString;
1483 : : }
1484 : :
1485 : 18245 : void SvNumberFormatter::GetOutputString(rtl::OUString& sString,
1486 : : sal_uInt32 nFIndex,
1487 : : rtl::OUString& sOutString,
1488 : : Color** ppColor)
1489 : : {
1490 : 18245 : SvNumberformat* pFormat = GetFormatEntry( nFIndex );
1491 [ + + ]: 18245 : if (!pFormat)
1492 : 696 : pFormat = GetFormatEntry(ZF_STANDARD_TEXT);
1493 [ + + ][ + - ]: 18245 : if (!pFormat->IsTextFormat() && !pFormat->HasTextFormat())
[ + + ]
1494 : : {
1495 : 17315 : *ppColor = NULL;
1496 : 17315 : sOutString = sString;
1497 : : }
1498 : : else
1499 : : {
1500 [ + - ]: 930 : ChangeIntl(pFormat->GetLanguage());
1501 [ + - ]: 930 : String aString = sString;
1502 [ + - ]: 930 : String aOutString = sOutString;
1503 [ + - ]: 930 : pFormat->GetOutputString(aString, aOutString, ppColor);
1504 [ + - ]: 930 : sString = aString;
1505 [ + - ][ + - ]: 930 : sOutString = aOutString;
[ + - ]
1506 : : }
1507 : 18245 : }
1508 : :
1509 : 0 : bool SvNumberFormatter::GetPreviewString(const String& sFormatString,
1510 : : double fPreviewNumber,
1511 : : String& sOutString,
1512 : : Color** ppColor,
1513 : : LanguageType eLnge,
1514 : : bool bUseStarFormat )
1515 : : {
1516 [ # # ]: 0 : if (sFormatString.Len() == 0) // no empty string
1517 : 0 : return false;
1518 : :
1519 : 0 : xub_StrLen nCheckPos = STRING_NOTFOUND;
1520 : : sal_uInt32 nKey;
1521 [ # # ]: 0 : if (eLnge == LANGUAGE_DONTKNOW)
1522 : 0 : eLnge = IniLnge;
1523 [ # # ]: 0 : ChangeIntl(eLnge); // change locale if necessary
1524 : 0 : eLnge = ActLnge;
1525 [ # # ]: 0 : String sTmpString = sFormatString;
1526 : : SvNumberformat* p_Entry = new SvNumberformat(sTmpString,
1527 : : pFormatScanner,
1528 : : pStringScanner,
1529 : : nCheckPos,
1530 [ # # ][ # # ]: 0 : eLnge);
1531 [ # # ]: 0 : if (nCheckPos == 0) // String ok
1532 : : {
1533 [ # # ]: 0 : sal_uInt32 CLOffset = ImpGenerateCL(eLnge); // create new standard formats if necessary
1534 [ # # ]: 0 : nKey = ImpIsEntry(p_Entry->GetFormatstring(),CLOffset, eLnge);
1535 [ # # ]: 0 : if (nKey != NUMBERFORMAT_ENTRY_NOT_FOUND) // already present
1536 [ # # ]: 0 : GetOutputString(fPreviewNumber,nKey,sOutString,ppColor, bUseStarFormat);
1537 : : else
1538 : : {
1539 [ # # ]: 0 : if ( bUseStarFormat )
1540 : 0 : p_Entry->SetStarFormatSupport( true );
1541 [ # # ]: 0 : p_Entry->GetOutputString(fPreviewNumber,sOutString, ppColor);
1542 [ # # ]: 0 : if ( bUseStarFormat )
1543 : 0 : p_Entry->SetStarFormatSupport( false );
1544 : : }
1545 [ # # ][ # # ]: 0 : delete p_Entry;
1546 : 0 : return true;
1547 : : }
1548 : : else
1549 : : {
1550 [ # # ][ # # ]: 0 : delete p_Entry;
1551 : 0 : return false;
1552 [ # # ]: 0 : }
1553 : : }
1554 : :
1555 : 0 : bool SvNumberFormatter::GetPreviewStringGuess( const String& sFormatString,
1556 : : double fPreviewNumber,
1557 : : String& sOutString,
1558 : : Color** ppColor,
1559 : : LanguageType eLnge )
1560 : : {
1561 [ # # ]: 0 : if (sFormatString.Len() == 0) // no empty string
1562 : 0 : return false;
1563 : :
1564 [ # # ]: 0 : if (eLnge == LANGUAGE_DONTKNOW)
1565 : 0 : eLnge = IniLnge;
1566 : :
1567 [ # # ]: 0 : ChangeIntl( eLnge );
1568 : 0 : eLnge = ActLnge;
1569 : 0 : bool bEnglish = (eLnge == LANGUAGE_ENGLISH_US);
1570 : :
1571 [ # # ][ # # ]: 0 : String aFormatStringUpper( pCharClass->uppercase( sFormatString ) );
[ # # ]
1572 [ # # ]: 0 : sal_uInt32 nCLOffset = ImpGenerateCL( eLnge );
1573 [ # # ]: 0 : sal_uInt32 nKey = ImpIsEntry( aFormatStringUpper, nCLOffset, eLnge );
1574 [ # # ]: 0 : if ( nKey != NUMBERFORMAT_ENTRY_NOT_FOUND )
1575 : : { // Zielformat vorhanden
1576 [ # # ]: 0 : GetOutputString( fPreviewNumber, nKey, sOutString, ppColor );
1577 : 0 : return true;
1578 : : }
1579 : :
1580 : 0 : SvNumberformat *pEntry = NULL;
1581 : 0 : xub_StrLen nCheckPos = STRING_NOTFOUND;
1582 [ # # ]: 0 : String sTmpString;
1583 : :
1584 [ # # ]: 0 : if ( bEnglish )
1585 : : {
1586 [ # # ]: 0 : sTmpString = sFormatString;
1587 : : pEntry = new SvNumberformat( sTmpString, pFormatScanner,
1588 [ # # ][ # # ]: 0 : pStringScanner, nCheckPos, eLnge );
1589 : : }
1590 : : else
1591 : : {
1592 [ # # ]: 0 : nCLOffset = ImpGenerateCL( LANGUAGE_ENGLISH_US );
1593 [ # # ]: 0 : nKey = ImpIsEntry( aFormatStringUpper, nCLOffset, LANGUAGE_ENGLISH_US );
1594 : 0 : bool bEnglishFormat = (nKey != NUMBERFORMAT_ENTRY_NOT_FOUND);
1595 : :
1596 : : // try english --> other bzw. english nach other konvertieren
1597 : 0 : LanguageType eFormatLang = LANGUAGE_ENGLISH_US;
1598 : 0 : pFormatScanner->SetConvertMode( LANGUAGE_ENGLISH_US, eLnge );
1599 [ # # ]: 0 : sTmpString = sFormatString;
1600 : : pEntry = new SvNumberformat( sTmpString, pFormatScanner,
1601 [ # # ][ # # ]: 0 : pStringScanner, nCheckPos, eFormatLang );
1602 : 0 : pFormatScanner->SetConvertMode( false );
1603 [ # # ]: 0 : ChangeIntl( eLnge );
1604 : :
1605 [ # # ]: 0 : if ( !bEnglishFormat )
1606 : : {
1607 [ # # ][ # # ]: 0 : if ( nCheckPos > 0 || xTransliteration->isEqual( sFormatString,
[ # # ]
1608 [ # # ][ # # ]: 0 : pEntry->GetFormatstring() ) )
1609 : : { // other Format
1610 [ # # ][ # # ]: 0 : delete pEntry;
1611 [ # # ]: 0 : sTmpString = sFormatString;
1612 : : pEntry = new SvNumberformat( sTmpString, pFormatScanner,
1613 [ # # ][ # # ]: 0 : pStringScanner, nCheckPos, eLnge );
1614 : : }
1615 : : else
1616 : : { // verify english
1617 : 0 : xub_StrLen nCheckPos2 = STRING_NOTFOUND;
1618 : : // try other --> english
1619 : 0 : eFormatLang = eLnge;
1620 : 0 : pFormatScanner->SetConvertMode( eLnge, LANGUAGE_ENGLISH_US );
1621 [ # # ]: 0 : sTmpString = sFormatString;
1622 : : SvNumberformat* pEntry2 = new SvNumberformat( sTmpString, pFormatScanner,
1623 [ # # ][ # # ]: 0 : pStringScanner, nCheckPos2, eFormatLang );
1624 : 0 : pFormatScanner->SetConvertMode( false );
1625 [ # # ]: 0 : ChangeIntl( eLnge );
1626 [ # # ][ # # ]: 0 : if ( nCheckPos2 == 0 && !xTransliteration->isEqual( sFormatString,
[ # # ]
1627 [ # # ][ # # ]: 0 : pEntry2->GetFormatstring() ) )
1628 : : { // other Format
1629 [ # # ][ # # ]: 0 : delete pEntry;
1630 [ # # ]: 0 : sTmpString = sFormatString;
1631 : : pEntry = new SvNumberformat( sTmpString, pFormatScanner,
1632 [ # # ][ # # ]: 0 : pStringScanner, nCheckPos, eLnge );
1633 : : }
1634 [ # # ][ # # ]: 0 : delete pEntry2;
1635 : : }
1636 : : }
1637 : : }
1638 : :
1639 [ # # ]: 0 : if (nCheckPos == 0) // String ok
1640 : : {
1641 [ # # ]: 0 : ImpGenerateCL( eLnge ); // create new standard formats if necessary
1642 [ # # ]: 0 : pEntry->GetOutputString( fPreviewNumber, sOutString, ppColor );
1643 [ # # ][ # # ]: 0 : delete pEntry;
1644 : 0 : return true;
1645 : : }
1646 [ # # ][ # # ]: 0 : delete pEntry;
1647 [ # # ][ # # ]: 0 : return false;
1648 : : }
1649 : :
1650 : 0 : bool SvNumberFormatter::GetPreviewString( const String& sFormatString,
1651 : : const String& sPreviewString,
1652 : : String& sOutString,
1653 : : Color** ppColor,
1654 : : LanguageType eLnge )
1655 : : {
1656 [ # # ]: 0 : if (sFormatString.Len() == 0) // no empty string
1657 : 0 : return false;
1658 : :
1659 : 0 : xub_StrLen nCheckPos = STRING_NOTFOUND;
1660 : : sal_uInt32 nKey;
1661 [ # # ]: 0 : if (eLnge == LANGUAGE_DONTKNOW)
1662 : 0 : eLnge = IniLnge;
1663 [ # # ]: 0 : ChangeIntl(eLnge); // switch if needed
1664 : 0 : eLnge = ActLnge;
1665 [ # # ]: 0 : String sTmpString = sFormatString;
1666 : : SvNumberformat* p_Entry = new SvNumberformat( sTmpString,
1667 : : pFormatScanner,
1668 : : pStringScanner,
1669 : : nCheckPos,
1670 [ # # ][ # # ]: 0 : eLnge);
1671 [ # # ]: 0 : if (nCheckPos == 0) // String ok
1672 : : {
1673 [ # # ]: 0 : String aNonConstPreview( sPreviewString);
1674 : : // May have to create standard formats for this locale.
1675 [ # # ]: 0 : sal_uInt32 CLOffset = ImpGenerateCL(eLnge);
1676 [ # # ]: 0 : nKey = ImpIsEntry( p_Entry->GetFormatstring(), CLOffset, eLnge);
1677 [ # # ]: 0 : if (nKey != NUMBERFORMAT_ENTRY_NOT_FOUND) // already present
1678 [ # # ]: 0 : GetOutputString( aNonConstPreview, nKey, sOutString, ppColor);
1679 : : else
1680 : : {
1681 : : // If the format is valid but not a text format and does not
1682 : : // include a text subformat, an empty string would result. Same as
1683 : : // in SvNumberFormatter::GetOutputString()
1684 [ # # ][ # # ]: 0 : if (p_Entry->IsTextFormat() || p_Entry->HasTextFormat())
[ # # ]
1685 [ # # ]: 0 : p_Entry->GetOutputString( aNonConstPreview, sOutString, ppColor);
1686 : : else
1687 : : {
1688 : 0 : *ppColor = NULL;
1689 [ # # ]: 0 : sOutString = sPreviewString;
1690 : : }
1691 : : }
1692 [ # # ][ # # ]: 0 : delete p_Entry;
1693 [ # # ]: 0 : return true;
1694 : : }
1695 : : else
1696 : : {
1697 [ # # ][ # # ]: 0 : delete p_Entry;
1698 : 0 : return false;
1699 [ # # ]: 0 : }
1700 : : }
1701 : :
1702 : 224 : sal_uInt32 SvNumberFormatter::TestNewString(const String& sFormatString,
1703 : : LanguageType eLnge)
1704 : : {
1705 [ - + ]: 224 : if (sFormatString.Len() == 0) // no empty string
1706 : 0 : return NUMBERFORMAT_ENTRY_NOT_FOUND;
1707 : :
1708 : 224 : xub_StrLen nCheckPos = STRING_NOTFOUND;
1709 [ + + ]: 224 : if (eLnge == LANGUAGE_DONTKNOW)
1710 : 2 : eLnge = IniLnge;
1711 [ + - ]: 224 : ChangeIntl(eLnge); // change locale if necessary
1712 : 224 : eLnge = ActLnge;
1713 : : sal_uInt32 nRes;
1714 [ + - ]: 224 : String sTmpString = sFormatString;
1715 : : SvNumberformat* pEntry = new SvNumberformat(sTmpString,
1716 : : pFormatScanner,
1717 : : pStringScanner,
1718 : : nCheckPos,
1719 [ + - ][ + - ]: 224 : eLnge);
1720 [ + - ]: 224 : if (nCheckPos == 0) // String ok
1721 : : {
1722 [ + - ]: 224 : sal_uInt32 CLOffset = ImpGenerateCL(eLnge); // create new standard formats if necessary
1723 [ + - ]: 224 : nRes = ImpIsEntry(pEntry->GetFormatstring(),CLOffset, eLnge);
1724 : : // already present?
1725 : : }
1726 : : else
1727 : 0 : nRes = NUMBERFORMAT_ENTRY_NOT_FOUND;
1728 [ + - ][ + - ]: 224 : delete pEntry;
1729 [ + - ]: 224 : return nRes;
1730 : : }
1731 : :
1732 : 158450 : SvNumberformat* SvNumberFormatter::ImpInsertFormat(
1733 : : const ::com::sun::star::i18n::NumberFormatCode& rCode,
1734 : : sal_uInt32 nPos, bool bAfterChangingSystemCL, sal_Int16 nOrgIndex )
1735 : : {
1736 [ + - ]: 158450 : String aCodeStr( rCode.Code );
1737 [ + + ][ + + ]: 158450 : if ( rCode.Index < NF_INDEX_TABLE_ENTRIES &&
[ + + ]
1738 : : rCode.Usage == ::com::sun::star::i18n::KNumberFormatUsage::CURRENCY &&
1739 : : rCode.Index != NF_CURRENCY_1000DEC2_CCC )
1740 : : { // strip surrounding [$...] on automatic currency
1741 [ + - ][ + - ]: 12200 : if ( aCodeStr.SearchAscii( "[$" ) != STRING_NOTFOUND )
1742 [ + - ][ + - ]: 12200 : aCodeStr = SvNumberformat::StripNewCurrencyDelimiters( aCodeStr, false );
[ + - ]
1743 : : else
1744 : : {
1745 [ # # ][ # # ]: 0 : if (LocaleDataWrapper::areChecksEnabled() &&
[ # # ][ # # ]
1746 : : rCode.Index != NF_CURRENCY_1000DEC2_CCC )
1747 : : {
1748 : 0 : rtl::OUString aMsg("SvNumberFormatter::ImpInsertFormat: no [$...] on currency format code, index ");
1749 : 0 : aMsg += rtl::OUString::valueOf( sal_Int32(rCode.Index) );
1750 : 0 : aMsg += ":\n";
1751 : 0 : aMsg += rCode.Code;
1752 [ # # ][ # # ]: 0 : LocaleDataWrapper::outputCheckMessage( xLocaleData->appendLocaleInfo( aMsg));
1753 : : }
1754 : : }
1755 : : }
1756 : 158450 : xub_StrLen nCheckPos = 0;
1757 : : SvNumberformat* pFormat = new SvNumberformat(aCodeStr,
1758 : : pFormatScanner,
1759 : : pStringScanner,
1760 : : nCheckPos,
1761 [ + - ][ + - ]: 158450 : ActLnge);
1762 [ + - ][ - + ]: 158450 : if ( !pFormat || nCheckPos > 0 )
1763 : : {
1764 [ # # ][ # # ]: 0 : if (LocaleDataWrapper::areChecksEnabled())
1765 : : {
1766 : 0 : rtl::OUString aMsg( "SvNumberFormatter::ImpInsertFormat: bad format code, index " );
1767 : 0 : aMsg += rtl::OUString::valueOf( sal_Int32(rCode.Index) );
1768 : 0 : aMsg += "\n";
1769 : 0 : aMsg += rCode.Code;
1770 [ # # ][ # # ]: 0 : LocaleDataWrapper::outputCheckMessage( xLocaleData->appendLocaleInfo( aMsg));
1771 : : }
1772 [ # # ][ # # ]: 0 : delete pFormat;
1773 : 0 : return NULL;
1774 : : }
1775 [ + + ]: 158450 : if ( rCode.Index >= NF_INDEX_TABLE_ENTRIES )
1776 : : {
1777 : 36450 : sal_uInt32 nCLOffset = nPos - (nPos % SV_COUNTRY_LANGUAGE_OFFSET);
1778 [ + - ]: 36450 : sal_uInt32 nKey = ImpIsEntry( aCodeStr, nCLOffset, ActLnge );
1779 [ - + ]: 36450 : if ( nKey != NUMBERFORMAT_ENTRY_NOT_FOUND )
1780 : : {
1781 : : // If bAfterChangingSystemCL there will definitely be some dups,
1782 : : // don't cry then.
1783 [ # # ][ # # ]: 0 : if (LocaleDataWrapper::areChecksEnabled() && !bAfterChangingSystemCL)
[ # # ][ # # ]
1784 : : {
1785 : : // Test for duplicate indexes in locale data.
1786 [ # # ]: 0 : switch ( nOrgIndex )
1787 : : {
1788 : : // These may be dups of integer versions for locales where
1789 : : // currencies have no decimals like Italian Lira.
1790 : : case NF_CURRENCY_1000DEC2 : // NF_CURRENCY_1000INT
1791 : : case NF_CURRENCY_1000DEC2_RED : // NF_CURRENCY_1000INT_RED
1792 : : case NF_CURRENCY_1000DEC2_DASHED : // NF_CURRENCY_1000INT_RED
1793 : 0 : break;
1794 : : default:
1795 : : {
1796 : 0 : rtl::OUString aMsg("SvNumberFormatter::ImpInsertFormat: dup format code, index ");
1797 : 0 : aMsg += rtl::OUString::valueOf( sal_Int32(rCode.Index) );
1798 : 0 : aMsg += "\n";
1799 : 0 : aMsg += rCode.Code;
1800 [ # # ][ # # ]: 0 : LocaleDataWrapper::outputCheckMessage( xLocaleData->appendLocaleInfo( aMsg));
1801 : : }
1802 : : }
1803 : : }
1804 [ # # ][ # # ]: 0 : delete pFormat;
1805 : 0 : return NULL;
1806 : : }
1807 [ - + ]: 36450 : else if ( nPos - nCLOffset >= SV_COUNTRY_LANGUAGE_OFFSET )
1808 : : {
1809 [ # # ][ # # ]: 0 : if (LocaleDataWrapper::areChecksEnabled())
1810 : : {
1811 : 0 : rtl::OUString aMsg( "SvNumberFormatter::ImpInsertFormat: too many format codes, index ");
1812 : 0 : aMsg += rtl::OUString::valueOf( sal_Int32(rCode.Index) );
1813 : 0 : aMsg += "\n";
1814 : 0 : aMsg += rCode.Code;
1815 [ # # ][ # # ]: 0 : LocaleDataWrapper::outputCheckMessage( xLocaleData->appendLocaleInfo( aMsg));
1816 : : }
1817 [ # # ][ # # ]: 0 : delete pFormat;
1818 : 0 : return NULL;
1819 : : }
1820 : : }
1821 [ + - ][ + - ]: 158450 : if ( !aFTable.insert( make_pair( nPos, pFormat) ).second )
[ - + ]
1822 : : {
1823 [ # # ][ # # ]: 0 : if (LocaleDataWrapper::areChecksEnabled())
1824 : : {
1825 : 0 : rtl::OUString aMsg( "ImpInsertFormat: can't insert number format key pos: ");
1826 : 0 : aMsg += rtl::OUString::valueOf( sal_Int32( nPos ) );
1827 : 0 : aMsg += ", code index ";
1828 : 0 : aMsg += rtl::OUString::valueOf( sal_Int32(rCode.Index) );
1829 : 0 : aMsg += "\n";
1830 : 0 : aMsg += rCode.Code;
1831 [ # # ][ # # ]: 0 : LocaleDataWrapper::outputCheckMessage( xLocaleData->appendLocaleInfo( aMsg));
1832 : : }
1833 [ # # ][ # # ]: 0 : delete pFormat;
1834 : 0 : return NULL;
1835 : : }
1836 [ + + ]: 158450 : if ( rCode.Default )
1837 : 14640 : pFormat->SetStandard();
1838 [ + + ]: 158450 : if ( !rCode.DefaultName.isEmpty() )
1839 [ + - ][ + - ]: 2440 : pFormat->SetComment( rCode.DefaultName );
[ + - ]
1840 [ + - ]: 158450 : return pFormat;
1841 : : }
1842 : :
1843 : 85250 : SvNumberformat* SvNumberFormatter::ImpInsertNewStandardFormat(
1844 : : const ::com::sun::star::i18n::NumberFormatCode& rCode,
1845 : : sal_uInt32 nPos, sal_uInt16 nVersion, bool bAfterChangingSystemCL,
1846 : : sal_Int16 nOrgIndex )
1847 : : {
1848 : : SvNumberformat* pNewFormat = ImpInsertFormat( rCode, nPos,
1849 : 85250 : bAfterChangingSystemCL, nOrgIndex );
1850 [ + - ]: 85250 : if (pNewFormat)
1851 : 85250 : pNewFormat->SetNewStandardDefined( nVersion );
1852 : : // so that it gets saved, displayed properly, and converted by old versions
1853 : 85250 : return pNewFormat;
1854 : : }
1855 : :
1856 : 652 : void SvNumberFormatter::GetFormatSpecialInfo(sal_uInt32 nFormat,
1857 : : bool& bThousand,
1858 : : bool& IsRed,
1859 : : sal_uInt16& nPrecision,
1860 : : sal_uInt16& nAnzLeading)
1861 : :
1862 : : {
1863 : 652 : SvNumberformat* pFormat = GetFormatEntry( nFormat );
1864 [ + - ]: 652 : if (pFormat)
1865 : : pFormat->GetFormatSpecialInfo(bThousand, IsRed,
1866 : 652 : nPrecision, nAnzLeading);
1867 : : else
1868 : : {
1869 : 0 : bThousand = false;
1870 : 0 : IsRed = false;
1871 : 0 : nPrecision = pFormatScanner->GetStandardPrec();
1872 : 0 : nAnzLeading = 0;
1873 : : }
1874 : 652 : }
1875 : :
1876 : 0 : sal_uInt16 SvNumberFormatter::GetFormatPrecision( sal_uInt32 nFormat ) const
1877 : : {
1878 : 0 : const SvNumberformat* pFormat = GetFormatEntry( nFormat );
1879 [ # # ]: 0 : if ( pFormat )
1880 : 0 : return pFormat->GetFormatPrecision();
1881 : : else
1882 : 0 : return pFormatScanner->GetStandardPrec();
1883 : : }
1884 : :
1885 : :
1886 : 0 : String SvNumberFormatter::GetFormatDecimalSep( sal_uInt32 nFormat ) const
1887 : : {
1888 [ # # ]: 0 : const SvNumberformat* pFormat = GetFormatEntry(nFormat);
1889 [ # # ][ # # ]: 0 : if ( !pFormat || pFormat->GetLanguage() == ActLnge )
[ # # ]
1890 [ # # ]: 0 : return GetNumDecimalSep();
1891 : :
1892 [ # # ]: 0 : String aRet;
1893 : 0 : LanguageType eSaveLang = xLocaleData.getCurrentLanguage();
1894 [ # # ]: 0 : if ( pFormat->GetLanguage() == eSaveLang )
1895 [ # # ][ # # ]: 0 : aRet = xLocaleData->getNumDecimalSep();
1896 : : else
1897 : : {
1898 [ # # ]: 0 : ::com::sun::star::lang::Locale aSaveLocale( xLocaleData->getLocale() );
1899 [ # # ]: 0 : ::com::sun::star::lang::Locale aTmpLocale(MsLangId::convertLanguageToLocale(pFormat->GetLanguage()));
1900 [ # # ]: 0 : ((SvNumberFormatter*)this)->xLocaleData.changeLocale(aTmpLocale, pFormat->GetLanguage() );
1901 [ # # ][ # # ]: 0 : aRet = xLocaleData->getNumDecimalSep();
1902 [ # # ]: 0 : ((SvNumberFormatter*)this)->xLocaleData.changeLocale( aSaveLocale, eSaveLang );
1903 : : }
1904 [ # # ][ # # ]: 0 : return aRet;
1905 : : }
1906 : :
1907 : :
1908 : 0 : sal_uInt32 SvNumberFormatter::GetFormatSpecialInfo( const String& rFormatString,
1909 : : bool& bThousand, bool& IsRed, sal_uInt16& nPrecision,
1910 : : sal_uInt16& nAnzLeading, LanguageType eLnge )
1911 : :
1912 : : {
1913 : 0 : xub_StrLen nCheckPos = 0;
1914 [ # # ]: 0 : if (eLnge == LANGUAGE_DONTKNOW)
1915 : 0 : eLnge = IniLnge;
1916 [ # # ]: 0 : ChangeIntl(eLnge); // change locale if necessary
1917 : 0 : eLnge = ActLnge;
1918 [ # # ]: 0 : String aTmpStr( rFormatString );
1919 : : SvNumberformat* pFormat = new SvNumberformat( aTmpStr,
1920 [ # # ][ # # ]: 0 : pFormatScanner, pStringScanner, nCheckPos, eLnge );
1921 [ # # ]: 0 : if ( nCheckPos == 0 )
1922 [ # # ]: 0 : pFormat->GetFormatSpecialInfo( bThousand, IsRed, nPrecision, nAnzLeading );
1923 : : else
1924 : : {
1925 : 0 : bThousand = false;
1926 : 0 : IsRed = false;
1927 : 0 : nPrecision = pFormatScanner->GetStandardPrec();
1928 : 0 : nAnzLeading = 0;
1929 : : }
1930 [ # # ][ # # ]: 0 : delete pFormat;
1931 [ # # ]: 0 : return nCheckPos;
1932 : : }
1933 : :
1934 : :
1935 : 126880 : inline sal_uInt32 SetIndexTable( NfIndexTableOffset nTabOff, sal_uInt32 nIndOff )
1936 : : {
1937 [ + + ]: 126880 : if ( !bIndexTableInitialized )
1938 : : {
1939 : : DBG_ASSERT( theIndexTable[nTabOff] == NUMBERFORMAT_ENTRY_NOT_FOUND,
1940 : : "SetIndexTable: theIndexTable[nTabOff] already occupied" );
1941 : 6396 : theIndexTable[nTabOff] = nIndOff;
1942 : : }
1943 : 126880 : return nIndOff;
1944 : : }
1945 : :
1946 : :
1947 : 109800 : sal_Int32 SvNumberFormatter::ImpGetFormatCodeIndex(
1948 : : ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::NumberFormatCode >& rSeq,
1949 : : const NfIndexTableOffset nTabOff )
1950 : : {
1951 : 109800 : const sal_Int32 nLen = rSeq.getLength();
1952 [ + - ]: 705160 : for ( sal_Int32 j=0; j<nLen; j++ )
1953 : : {
1954 [ + + ]: 705160 : if ( rSeq[j].Index == nTabOff )
1955 : 109800 : return j;
1956 : : }
1957 [ # # ][ # # ]: 0 : if (LocaleDataWrapper::areChecksEnabled() && (nTabOff < NF_CURRENCY_START
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1958 : : || NF_CURRENCY_END < nTabOff || nTabOff == NF_CURRENCY_1000INT
1959 : : || nTabOff == NF_CURRENCY_1000INT_RED
1960 : : || nTabOff == NF_CURRENCY_1000DEC2_CCC))
1961 : : { // currency entries with decimals might not exist, e.g. Italian Lira
1962 : 0 : rtl::OUString aMsg( "SvNumberFormatter::ImpGetFormatCodeIndex: not found: " );
1963 : 0 : aMsg += rtl::OUString::valueOf( sal_Int32( nTabOff ) );
1964 [ # # ][ # # ]: 0 : LocaleDataWrapper::outputCheckMessage( xLocaleData->appendLocaleInfo(aMsg));
1965 : : }
1966 [ # # ]: 0 : if ( nLen )
1967 : : {
1968 : : sal_Int32 j;
1969 : : // look for a preset default
1970 [ # # ]: 0 : for ( j=0; j<nLen; j++ )
1971 : : {
1972 [ # # ]: 0 : if ( rSeq[j].Default )
1973 : 0 : return j;
1974 : : }
1975 : : // currencies are special, not all format codes must exist, but all
1976 : : // builtin number format key index positions must have a format assigned
1977 [ # # ][ # # ]: 0 : if ( NF_CURRENCY_START <= nTabOff && nTabOff <= NF_CURRENCY_END )
1978 : : {
1979 : : // look for a format with decimals
1980 [ # # ]: 0 : for ( j=0; j<nLen; j++ )
1981 : : {
1982 [ # # ]: 0 : if ( rSeq[j].Index == NF_CURRENCY_1000DEC2 )
1983 : 0 : return j;
1984 : : }
1985 : : // last resort: look for a format without decimals
1986 [ # # ]: 0 : for ( j=0; j<nLen; j++ )
1987 : : {
1988 [ # # ]: 0 : if ( rSeq[j].Index == NF_CURRENCY_1000INT )
1989 : 0 : return j;
1990 : : }
1991 : : }
1992 : : }
1993 : : else
1994 : : { // we need at least _some_ format
1995 : 0 : rSeq.realloc(1);
1996 [ # # ]: 0 : rSeq[0] = ::com::sun::star::i18n::NumberFormatCode();
1997 [ # # ]: 0 : rSeq[0].Code = rtl::OUStringBuffer().
1998 [ # # ]: 0 : append('0').
1999 [ # # ]: 0 : append(GetNumDecimalSep()).
2000 [ # # ]: 0 : appendAscii(RTL_CONSTASCII_STRINGPARAM("############")).
2001 [ # # ]: 0 : makeStringAndClear();
2002 : : }
2003 : 109800 : return 0;
2004 : : }
2005 : :
2006 : :
2007 : 19520 : sal_Int32 SvNumberFormatter::ImpAdjustFormatCodeDefault(
2008 : : ::com::sun::star::i18n::NumberFormatCode * pFormatArr,
2009 : : sal_Int32 nCnt, bool bCheckCorrectness )
2010 : : {
2011 : : using namespace ::com::sun::star;
2012 : :
2013 [ - + ]: 19520 : if ( !nCnt )
2014 : 0 : return -1;
2015 [ + + ][ - + ]: 19520 : if (bCheckCorrectness && LocaleDataWrapper::areChecksEnabled())
[ - + ]
2016 : : {
2017 : : // check the locale data for correctness
2018 : 0 : rtl::OStringBuffer aMsg;
2019 : : sal_Int32 nElem, nShort, nMedium, nLong, nShortDef, nMediumDef, nLongDef;
2020 : 0 : nShort = nMedium = nLong = nShortDef = nMediumDef = nLongDef = -1;
2021 [ # # ]: 0 : for ( nElem = 0; nElem < nCnt; nElem++ )
2022 : : {
2023 [ # # # # ]: 0 : switch ( pFormatArr[nElem].Type )
2024 : : {
2025 : : case i18n::KNumberFormatType::SHORT :
2026 : 0 : nShort = nElem;
2027 : 0 : break;
2028 : : case i18n::KNumberFormatType::MEDIUM :
2029 : 0 : nMedium = nElem;
2030 : 0 : break;
2031 : : case i18n::KNumberFormatType::LONG :
2032 : 0 : nLong = nElem;
2033 : 0 : break;
2034 : : default:
2035 [ # # ]: 0 : aMsg.append(RTL_CONSTASCII_STRINGPARAM("unknown type"));
2036 : : }
2037 [ # # ]: 0 : if ( pFormatArr[nElem].Default )
2038 : : {
2039 [ # # # # ]: 0 : switch ( pFormatArr[nElem].Type )
2040 : : {
2041 : : case i18n::KNumberFormatType::SHORT :
2042 [ # # ]: 0 : if ( nShortDef != -1 )
2043 [ # # ]: 0 : aMsg.append(RTL_CONSTASCII_STRINGPARAM("dupe short type default"));
2044 : 0 : nShortDef = nElem;
2045 : 0 : break;
2046 : : case i18n::KNumberFormatType::MEDIUM :
2047 [ # # ]: 0 : if ( nMediumDef != -1 )
2048 [ # # ]: 0 : aMsg.append(RTL_CONSTASCII_STRINGPARAM("dupe medium type default"));
2049 : 0 : nMediumDef = nElem;
2050 : 0 : break;
2051 : : case i18n::KNumberFormatType::LONG :
2052 [ # # ]: 0 : if ( nLongDef != -1 )
2053 [ # # ]: 0 : aMsg.append(RTL_CONSTASCII_STRINGPARAM("dupe long type default"));
2054 : 0 : nLongDef = nElem;
2055 : 0 : break;
2056 : : }
2057 : : }
2058 [ # # ]: 0 : if (aMsg.getLength())
2059 : : {
2060 [ # # ]: 0 : aMsg.insert(0, RTL_CONSTASCII_STRINGPARAM("SvNumberFormatter::ImpAdjustFormatCodeDefault: "));
2061 [ # # ]: 0 : aMsg.append(RTL_CONSTASCII_STRINGPARAM("\nXML locale data FormatElement formatindex: "));
2062 [ # # ]: 0 : aMsg.append(static_cast<sal_Int32>(pFormatArr[nElem].Index));
2063 : : rtl::OUString aUMsg(rtl::OStringToOUString(aMsg.makeStringAndClear(),
2064 [ # # ]: 0 : RTL_TEXTENCODING_ASCII_US));
2065 [ # # ][ # # ]: 0 : LocaleDataWrapper::outputCheckMessage(xLocaleData->appendLocaleInfo(aUMsg));
2066 : : }
2067 : : }
2068 [ # # ][ # # ]: 0 : if ( nShort != -1 && nShortDef == -1 )
2069 [ # # ]: 0 : aMsg.append(RTL_CONSTASCII_STRINGPARAM("no short type default "));
2070 [ # # ][ # # ]: 0 : if ( nMedium != -1 && nMediumDef == -1 )
2071 [ # # ]: 0 : aMsg.append(RTL_CONSTASCII_STRINGPARAM("no medium type default "));
2072 [ # # ][ # # ]: 0 : if ( nLong != -1 && nLongDef == -1 )
2073 [ # # ]: 0 : aMsg.append(RTL_CONSTASCII_STRINGPARAM("no long type default "));
2074 [ # # ]: 0 : if (aMsg.getLength())
2075 : : {
2076 [ # # ]: 0 : aMsg.insert(0, RTL_CONSTASCII_STRINGPARAM("SvNumberFormatter::ImpAdjustFormatCodeDefault: "));
2077 [ # # ]: 0 : aMsg.append(RTL_CONSTASCII_STRINGPARAM("\nXML locale data FormatElement group of: "));
2078 [ # # ]: 0 : rtl::OUString aUMsg(rtl::OStringToOUString(aMsg.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US));
2079 : : LocaleDataWrapper::outputCheckMessage(
2080 [ # # ][ # # ]: 0 : xLocaleData->appendLocaleInfo(aUMsg + pFormatArr[0].NameID));
2081 : 0 : }
2082 : : }
2083 : : // find the default (medium preferred, then long) and reset all other defaults
2084 : : sal_Int32 nElem, nDef, nMedium;
2085 : 19520 : nDef = nMedium = -1;
2086 [ + + ]: 302200 : for ( nElem = 0; nElem < nCnt; nElem++ )
2087 : : {
2088 [ + + ]: 282680 : if ( pFormatArr[nElem].Default )
2089 : : {
2090 [ + + + ]: 63440 : switch ( pFormatArr[nElem].Type )
2091 : : {
2092 : : case i18n::KNumberFormatType::MEDIUM :
2093 : 29280 : nDef = nMedium = nElem;
2094 : 29280 : break;
2095 : : case i18n::KNumberFormatType::LONG :
2096 [ + + ]: 9760 : if ( nMedium == -1 )
2097 : 4880 : nDef = nElem;
2098 : : // fallthru
2099 : : default:
2100 [ + + ]: 34160 : if ( nDef == -1 )
2101 : 9760 : nDef = nElem;
2102 : 63440 : pFormatArr[nElem].Default = false;
2103 : : }
2104 : : }
2105 : : }
2106 [ - + ]: 19520 : if ( nDef == -1 )
2107 : 0 : nDef = 0;
2108 : 19520 : pFormatArr[nDef].Default = true;
2109 : 19520 : return nDef;
2110 : : }
2111 : :
2112 : 110418 : SvNumberformat* SvNumberFormatter::GetFormatEntry( sal_uInt32 nKey )
2113 : : {
2114 [ + - ]: 110418 : SvNumberFormatTable::iterator it = aFTable.find( nKey);
2115 [ + - ][ + + ]: 110418 : if (it != aFTable.end())
2116 [ + - ]: 108706 : return it->second;
2117 : 110418 : return 0;
2118 : : }
2119 : :
2120 : 72699 : const SvNumberformat* SvNumberFormatter::GetEntry( sal_uInt32 nKey ) const
2121 : : {
2122 [ + - ]: 72699 : SvNumberFormatTable::const_iterator it = aFTable.find( nKey);
2123 [ + - ][ + + ]: 72699 : if (it != aFTable.end())
2124 [ + - ]: 71849 : return it->second;
2125 : 72699 : return 0;
2126 : : }
2127 : :
2128 : 2440 : void SvNumberFormatter::ImpGenerateFormats( sal_uInt32 CLOffset, bool bNoAdditionalFormats )
2129 : : {
2130 : : using namespace ::com::sun::star;
2131 : :
2132 [ + + ]: 2440 : if ( !bIndexTableInitialized )
2133 : : {
2134 [ + + ]: 6519 : for ( sal_uInt16 j=0; j<NF_INDEX_TABLE_ENTRIES; j++ )
2135 : : {
2136 : 6396 : theIndexTable[j] = NUMBERFORMAT_ENTRY_NOT_FOUND;
2137 : : }
2138 : : }
2139 : 2440 : bool bOldConvertMode = pFormatScanner->GetConvertMode();
2140 [ + + ]: 2440 : if (bOldConvertMode)
2141 : 55 : pFormatScanner->SetConvertMode(false); // switch off for this function
2142 : :
2143 [ + - ]: 2440 : NumberFormatCodeWrapper aNumberFormatCode( xServiceManager, GetLocale() );
2144 : :
2145 : 2440 : xub_StrLen nCheckPos = 0;
2146 : 2440 : SvNumberformat* pNewFormat = NULL;
2147 [ + - ]: 2440 : String aFormatCode;
2148 : : sal_Int32 nIdx;
2149 : : bool bDefault;
2150 : :
2151 : : // Counter for additional builtin formats not fitting into the first 10
2152 : : // of a category (TLOT:=The Legacy Of Templin), altogether about 20 formats.
2153 : : // Has to be incremented on each ImpInsertNewStandardformat, new formats
2154 : : // must be appended, not inserted!
2155 : 2440 : sal_uInt16 nNewExtended = ZF_STANDARD_NEWEXTENDED;
2156 : :
2157 : : // Number
2158 : : uno::Sequence< i18n::NumberFormatCode > aFormatSeq
2159 [ + - ]: 2440 : = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::FIXED_NUMBER );
2160 [ + - ][ + - ]: 2440 : ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() );
2161 : :
2162 : : // General
2163 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_NUMBER_STANDARD );
2164 [ + - ]: 2440 : SvNumberformat* pStdFormat = ImpInsertFormat( aFormatSeq[nIdx],
2165 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_NUMBER_STANDARD, ZF_STANDARD ));
2166 [ + - ]: 2440 : if (pStdFormat)
2167 : : {
2168 : : // This is _the_ standard format.
2169 [ + - ][ - + ]: 2440 : if (LocaleDataWrapper::areChecksEnabled() && pStdFormat->GetType() != NUMBERFORMAT_NUMBER)
[ # # ][ - + ]
2170 : : LocaleDataWrapper::outputCheckMessage( xLocaleData->
2171 [ # # ][ # # ]: 0 : appendLocaleInfo( "SvNumberFormatter::ImpGenerateFormats: General format not NUMBER"));
2172 : :
2173 : 2440 : pStdFormat->SetType( NUMBERFORMAT_NUMBER );
2174 : 2440 : pStdFormat->SetStandard();
2175 : 2440 : pStdFormat->SetLastInsertKey( SV_MAX_ANZ_STANDARD_FORMATE );
2176 : : }
2177 : : else
2178 : : {
2179 [ # # ][ # # ]: 0 : if (LocaleDataWrapper::areChecksEnabled())
2180 : : LocaleDataWrapper::outputCheckMessage( xLocaleData->
2181 [ # # ][ # # ]: 0 : appendLocaleInfo( "SvNumberFormatter::ImpGenerateFormats: General format not insertable, nothing will work"));
2182 : : }
2183 : :
2184 : : // Boolean
2185 [ + - ][ + - ]: 2440 : aFormatCode = pFormatScanner->GetBooleanString();
2186 : : pNewFormat = new SvNumberformat( aFormatCode,
2187 [ + - ][ + - ]: 2440 : pFormatScanner, pStringScanner, nCheckPos, ActLnge );
2188 : 2440 : pNewFormat->SetType(NUMBERFORMAT_LOGICAL);
2189 : 2440 : pNewFormat->SetStandard();
2190 [ - + ]: 2440 : if ( !aFTable.insert(make_pair(
2191 : 2440 : CLOffset + SetIndexTable( NF_BOOLEAN, ZF_STANDARD_LOGICAL ),
2192 [ + - ][ + - ]: 2440 : pNewFormat)).second)
2193 [ # # ][ # # ]: 0 : delete pNewFormat;
2194 : :
2195 : : // Text
2196 [ + - ]: 2440 : aFormatCode = '@';
2197 : : pNewFormat = new SvNumberformat( aFormatCode,
2198 [ + - ][ + - ]: 2440 : pFormatScanner, pStringScanner, nCheckPos, ActLnge );
2199 : 2440 : pNewFormat->SetType(NUMBERFORMAT_TEXT);
2200 : 2440 : pNewFormat->SetStandard();
2201 [ - + ]: 2440 : if ( !aFTable.insert(make_pair(
2202 : 2440 : CLOffset + SetIndexTable( NF_TEXT, ZF_STANDARD_TEXT ),
2203 [ + - ][ + - ]: 2440 : pNewFormat)).second)
2204 [ # # ][ # # ]: 0 : delete pNewFormat;
2205 : :
2206 : :
2207 : :
2208 : : // 0
2209 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_NUMBER_INT );
2210 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2211 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_NUMBER_INT, ZF_STANDARD+1 ));
2212 : :
2213 : : // 0.00
2214 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_NUMBER_DEC2 );
2215 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2216 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_NUMBER_DEC2, ZF_STANDARD+2 ));
2217 : :
2218 : : // #,##0
2219 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_NUMBER_1000INT );
2220 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2221 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_NUMBER_1000INT, ZF_STANDARD+3 ));
2222 : :
2223 : : // #,##0.00
2224 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_NUMBER_1000DEC2 );
2225 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2226 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_NUMBER_1000DEC2, ZF_STANDARD+4 ));
2227 : :
2228 : : // #.##0,00 System country/language dependent since number formatter version 6
2229 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_NUMBER_SYSTEM );
2230 [ + - ]: 2440 : ImpInsertNewStandardFormat( aFormatSeq[nIdx],
2231 : 2440 : CLOffset + SetIndexTable( NF_NUMBER_SYSTEM, ZF_STANDARD+5 ),
2232 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_NEWSTANDARD );
2233 : :
2234 : :
2235 : : // Percent number
2236 [ + - ][ + - ]: 2440 : aFormatSeq = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::PERCENT_NUMBER );
[ + - ]
2237 [ + - ][ + - ]: 2440 : ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() );
2238 : :
2239 : : // 0%
2240 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_PERCENT_INT );
2241 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2242 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_PERCENT_INT, ZF_STANDARD_PERCENT ));
2243 : :
2244 : : // 0.00%
2245 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_PERCENT_DEC2 );
2246 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2247 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_PERCENT_DEC2, ZF_STANDARD_PERCENT+1 ));
2248 : :
2249 : :
2250 : :
2251 : : // Currency. NO default standard option! Default is determined of locale
2252 : : // data default currency and format is generated if needed.
2253 [ + - ][ + - ]: 2440 : aFormatSeq = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::CURRENCY );
[ + - ]
2254 [ + - ][ - + ]: 2440 : if (LocaleDataWrapper::areChecksEnabled())
2255 : : {
2256 : : // though no default desired here, test for correctness of locale data
2257 [ # # ][ # # ]: 0 : ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() );
2258 : : }
2259 : :
2260 : : // #,##0
2261 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_CURRENCY_1000INT );
2262 [ + - ]: 2440 : bDefault = aFormatSeq[nIdx].Default;
2263 [ + - ]: 2440 : aFormatSeq[nIdx].Default = false;
2264 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2265 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_CURRENCY_1000INT, ZF_STANDARD_CURRENCY ));
2266 [ + - ]: 2440 : aFormatSeq[nIdx].Default = bDefault;
2267 : :
2268 : : // #,##0.00
2269 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_CURRENCY_1000DEC2 );
2270 [ + - ]: 2440 : bDefault = aFormatSeq[nIdx].Default;
2271 [ + - ]: 2440 : aFormatSeq[nIdx].Default = false;
2272 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2273 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_CURRENCY_1000DEC2, ZF_STANDARD_CURRENCY+1 ));
2274 [ + - ]: 2440 : aFormatSeq[nIdx].Default = bDefault;
2275 : :
2276 : : // #,##0 negative red
2277 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_CURRENCY_1000INT_RED );
2278 [ + - ]: 2440 : bDefault = aFormatSeq[nIdx].Default;
2279 [ + - ]: 2440 : aFormatSeq[nIdx].Default = false;
2280 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2281 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_CURRENCY_1000INT_RED, ZF_STANDARD_CURRENCY+2 ));
2282 [ + - ]: 2440 : aFormatSeq[nIdx].Default = bDefault;
2283 : :
2284 : : // #,##0.00 negative red
2285 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_CURRENCY_1000DEC2_RED );
2286 [ + - ]: 2440 : bDefault = aFormatSeq[nIdx].Default;
2287 [ + - ]: 2440 : aFormatSeq[nIdx].Default = false;
2288 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2289 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_CURRENCY_1000DEC2_RED, ZF_STANDARD_CURRENCY+3 ));
2290 [ + - ]: 2440 : aFormatSeq[nIdx].Default = bDefault;
2291 : :
2292 : : // #,##0.00 USD since number formatter version 3
2293 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_CURRENCY_1000DEC2_CCC );
2294 [ + - ]: 2440 : bDefault = aFormatSeq[nIdx].Default;
2295 [ + - ]: 2440 : aFormatSeq[nIdx].Default = false;
2296 [ + - ]: 2440 : pNewFormat = ImpInsertFormat( aFormatSeq[nIdx],
2297 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_CURRENCY_1000DEC2_CCC, ZF_STANDARD_CURRENCY+4 ));
2298 [ + - ]: 2440 : if ( pNewFormat )
2299 : 2440 : pNewFormat->SetUsed(true); // must be saved for older versions
2300 [ + - ]: 2440 : aFormatSeq[nIdx].Default = bDefault;
2301 : :
2302 : : // #.##0,-- since number formatter version 6
2303 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_CURRENCY_1000DEC2_DASHED );
2304 [ + - ]: 2440 : bDefault = aFormatSeq[nIdx].Default;
2305 [ + - ]: 2440 : aFormatSeq[nIdx].Default = false;
2306 [ + - ]: 2440 : ImpInsertNewStandardFormat( aFormatSeq[nIdx],
2307 : 2440 : CLOffset + SetIndexTable( NF_CURRENCY_1000DEC2_DASHED, ZF_STANDARD_CURRENCY+5 ),
2308 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_NEWSTANDARD );
2309 [ + - ]: 2440 : aFormatSeq[nIdx].Default = bDefault;
2310 : :
2311 : :
2312 : :
2313 : : // Date
2314 [ + - ][ + - ]: 2440 : aFormatSeq = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::DATE );
[ + - ]
2315 [ + - ][ + - ]: 2440 : ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() );
2316 : :
2317 : : // DD.MM.YY System
2318 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYSTEM_SHORT );
2319 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2320 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_DATE_SYSTEM_SHORT, ZF_STANDARD_DATE ));
2321 : :
2322 : : // NN DD.MMM YY
2323 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_DEF_NNDDMMMYY );
2324 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2325 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_DATE_DEF_NNDDMMMYY, ZF_STANDARD_DATE+1 ));
2326 : :
2327 : : // DD.MM.YY def/System
2328 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_MMYY );
2329 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2330 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_DATE_SYS_MMYY, ZF_STANDARD_DATE+2 ));
2331 : :
2332 : : // DD MMM
2333 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_DDMMM );
2334 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2335 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_DATE_SYS_DDMMM, ZF_STANDARD_DATE+3 ));
2336 : :
2337 : : // MMMM
2338 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_MMMM );
2339 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2340 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_DATE_MMMM, ZF_STANDARD_DATE+4 ));
2341 : :
2342 : : // QQ YY
2343 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_QQJJ );
2344 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2345 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_DATE_QQJJ, ZF_STANDARD_DATE+5 ));
2346 : :
2347 : : // DD.MM.YYYY since number formatter version 2, was DD.MM.[YY]YY
2348 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_DDMMYYYY );
2349 [ + - ]: 2440 : pNewFormat = ImpInsertFormat( aFormatSeq[nIdx],
2350 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_DATE_SYS_DDMMYYYY, ZF_STANDARD_DATE+6 ));
2351 [ + - ]: 2440 : if ( pNewFormat )
2352 : 2440 : pNewFormat->SetUsed(true); // must be saved for older versions
2353 : :
2354 : : // DD.MM.YY def/System, since number formatter version 6
2355 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_DDMMYY );
2356 [ + - ]: 2440 : ImpInsertNewStandardFormat( aFormatSeq[nIdx],
2357 : 2440 : CLOffset + SetIndexTable( NF_DATE_SYS_DDMMYY, ZF_STANDARD_DATE+7 ),
2358 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_NEWSTANDARD );
2359 : :
2360 : : // NNN, D. MMMM YYYY System
2361 : : // Long day of week: "NNNN" instead of "NNN," because of compatibility
2362 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYSTEM_LONG );
2363 [ + - ]: 2440 : ImpInsertNewStandardFormat( aFormatSeq[nIdx],
2364 : 2440 : CLOffset + SetIndexTable( NF_DATE_SYSTEM_LONG, ZF_STANDARD_DATE+8 ),
2365 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_NEWSTANDARD );
2366 : :
2367 : : // Hard coded but system (regional settings) delimiters dependent long date formats
2368 : : // since numberformatter version 6
2369 : :
2370 : : // D. MMM YY def/System
2371 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_DMMMYY );
2372 [ + - ]: 2440 : ImpInsertNewStandardFormat( aFormatSeq[nIdx],
2373 : 2440 : CLOffset + SetIndexTable( NF_DATE_SYS_DMMMYY, ZF_STANDARD_DATE+9 ),
2374 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_NEWSTANDARD );
2375 : :
2376 : : //! Unfortunally TLOT intended only 10 builtin formats per category, more
2377 : : //! would overwrite the next category (ZF_STANDARD_TIME) :-((
2378 : : //! Therefore they are inserted with nNewExtended++ (which is also limited)
2379 : :
2380 : : // D. MMM YYYY def/System
2381 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_DMMMYYYY );
2382 [ + - ]: 2440 : ImpInsertNewStandardFormat( aFormatSeq[nIdx],
2383 : 2440 : CLOffset + SetIndexTable( NF_DATE_SYS_DMMMYYYY, nNewExtended++ ),
2384 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_NEWSTANDARD );
2385 : :
2386 : : // D. MMMM YYYY def/System
2387 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_DMMMMYYYY );
2388 [ + - ]: 2440 : ImpInsertNewStandardFormat( aFormatSeq[nIdx],
2389 : 2440 : CLOffset + SetIndexTable( NF_DATE_SYS_DMMMMYYYY, nNewExtended++ ),
2390 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_NEWSTANDARD );
2391 : :
2392 : : // NN, D. MMM YY def/System
2393 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_NNDMMMYY );
2394 [ + - ]: 2440 : ImpInsertNewStandardFormat( aFormatSeq[nIdx],
2395 : 2440 : CLOffset + SetIndexTable( NF_DATE_SYS_NNDMMMYY, nNewExtended++ ),
2396 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_NEWSTANDARD );
2397 : :
2398 : : // NN, D. MMMM YYYY def/System
2399 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_NNDMMMMYYYY );
2400 [ + - ]: 2440 : ImpInsertNewStandardFormat( aFormatSeq[nIdx],
2401 : 2440 : CLOffset + SetIndexTable( NF_DATE_SYS_NNDMMMMYYYY, nNewExtended++ ),
2402 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_NEWSTANDARD );
2403 : :
2404 : : // NNN, D. MMMM YYYY def/System
2405 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_NNNNDMMMMYYYY );
2406 [ + - ]: 2440 : ImpInsertNewStandardFormat( aFormatSeq[nIdx],
2407 : 2440 : CLOffset + SetIndexTable( NF_DATE_SYS_NNNNDMMMMYYYY, nNewExtended++ ),
2408 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_NEWSTANDARD );
2409 : :
2410 : : // Hard coded DIN (Deutsche Industrie Norm) and EN (European Norm) date formats
2411 : :
2412 : : // D. MMM. YYYY DIN/EN
2413 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_DIN_DMMMYYYY );
2414 [ + - ]: 2440 : ImpInsertNewStandardFormat( aFormatSeq[nIdx],
2415 : 2440 : CLOffset + SetIndexTable( NF_DATE_DIN_DMMMYYYY, nNewExtended++ ),
2416 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_NEWSTANDARD );
2417 : :
2418 : : // D. MMMM YYYY DIN/EN
2419 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_DIN_DMMMMYYYY );
2420 [ + - ]: 2440 : ImpInsertNewStandardFormat( aFormatSeq[nIdx],
2421 : 2440 : CLOffset + SetIndexTable( NF_DATE_DIN_DMMMMYYYY, nNewExtended++ ),
2422 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_NEWSTANDARD );
2423 : :
2424 : : // MM-DD DIN/EN
2425 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_DIN_MMDD );
2426 [ + - ]: 2440 : ImpInsertNewStandardFormat( aFormatSeq[nIdx],
2427 : 2440 : CLOffset + SetIndexTable( NF_DATE_DIN_MMDD, nNewExtended++ ),
2428 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_NEWSTANDARD );
2429 : :
2430 : : // YY-MM-DD DIN/EN
2431 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_DIN_YYMMDD );
2432 [ + - ]: 2440 : ImpInsertNewStandardFormat( aFormatSeq[nIdx],
2433 : 2440 : CLOffset + SetIndexTable( NF_DATE_DIN_YYMMDD, nNewExtended++ ),
2434 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_NEWSTANDARD );
2435 : :
2436 : : // YYYY-MM-DD DIN/EN
2437 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_DIN_YYYYMMDD );
2438 [ + - ]: 2440 : ImpInsertNewStandardFormat( aFormatSeq[nIdx],
2439 : 2440 : CLOffset + SetIndexTable( NF_DATE_DIN_YYYYMMDD, nNewExtended++ ),
2440 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_NEWSTANDARD );
2441 : :
2442 : :
2443 : :
2444 : : // Time
2445 [ + - ][ + - ]: 2440 : aFormatSeq = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::TIME );
[ + - ]
2446 [ + - ][ + - ]: 2440 : ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() );
2447 : :
2448 : : // HH:MM
2449 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_TIME_HHMM );
2450 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2451 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_TIME_HHMM, ZF_STANDARD_TIME ));
2452 : :
2453 : : // HH:MM:SS
2454 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_TIME_HHMMSS );
2455 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2456 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_TIME_HHMMSS, ZF_STANDARD_TIME+1 ));
2457 : :
2458 : : // HH:MM AM/PM
2459 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_TIME_HHMMAMPM );
2460 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2461 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_TIME_HHMMAMPM, ZF_STANDARD_TIME+2 ));
2462 : :
2463 : : // HH:MM:SS AM/PM
2464 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_TIME_HHMMSSAMPM );
2465 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2466 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_TIME_HHMMSSAMPM, ZF_STANDARD_TIME+3 ));
2467 : :
2468 : : // [HH]:MM:SS
2469 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_TIME_HH_MMSS );
2470 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2471 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_TIME_HH_MMSS, ZF_STANDARD_TIME+4 ));
2472 : :
2473 : : // MM:SS,00
2474 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_TIME_MMSS00 );
2475 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2476 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_TIME_MMSS00, ZF_STANDARD_TIME+5 ));
2477 : :
2478 : : // [HH]:MM:SS,00
2479 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_TIME_HH_MMSS00 );
2480 [ + - ]: 2440 : ImpInsertNewStandardFormat( aFormatSeq[nIdx],
2481 : 2440 : CLOffset + SetIndexTable( NF_TIME_HH_MMSS00, ZF_STANDARD_TIME+6 ),
2482 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_NF_TIME_HH_MMSS00 );
2483 : :
2484 : :
2485 : :
2486 : : // DateTime
2487 [ + - ][ + - ]: 2440 : aFormatSeq = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::DATE_TIME );
[ + - ]
2488 [ + - ][ + - ]: 2440 : ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() );
2489 : :
2490 : : // DD.MM.YY HH:MM System
2491 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATETIME_SYSTEM_SHORT_HHMM );
2492 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2493 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_DATETIME_SYSTEM_SHORT_HHMM, ZF_STANDARD_DATETIME ));
2494 : :
2495 : : // DD.MM.YYYY HH:MM:SS System
2496 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATETIME_SYS_DDMMYYYY_HHMMSS );
2497 [ + - ]: 2440 : ImpInsertNewStandardFormat( aFormatSeq[nIdx],
2498 : 2440 : CLOffset + SetIndexTable( NF_DATETIME_SYS_DDMMYYYY_HHMMSS, ZF_STANDARD_DATETIME+1 ),
2499 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_NF_DATETIME_SYS_DDMMYYYY_HHMMSS );
2500 : :
2501 : :
2502 : :
2503 : : // Scientific number
2504 [ + - ][ + - ]: 2440 : aFormatSeq = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::SCIENTIFIC_NUMBER );
[ + - ]
2505 [ + - ][ + - ]: 2440 : ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() );
2506 : :
2507 : : // 0.00E+000
2508 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_SCIENTIFIC_000E000 );
2509 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2510 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_SCIENTIFIC_000E000, ZF_STANDARD_SCIENTIFIC ));
2511 : :
2512 : : // 0.00E+00
2513 [ + - ]: 2440 : nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_SCIENTIFIC_000E00 );
2514 [ + - ]: 2440 : ImpInsertFormat( aFormatSeq[nIdx],
2515 [ + - ]: 4880 : CLOffset + SetIndexTable( NF_SCIENTIFIC_000E00, ZF_STANDARD_SCIENTIFIC+1 ));
2516 : :
2517 : :
2518 : :
2519 : : // Fraction number (no default option)
2520 : 2440 : i18n::NumberFormatCode aSingleFormatCode;
2521 : 2440 : aSingleFormatCode.Usage = i18n::KNumberFormatUsage::FRACTION_NUMBER;
2522 : :
2523 : : // # ?/?
2524 : 2440 : aSingleFormatCode.Code = "# ?/?";
2525 : : ImpInsertFormat( aSingleFormatCode,
2526 [ + - ]: 2440 : CLOffset + SetIndexTable( NF_FRACTION_1, ZF_STANDARD_FRACTION ));
2527 : :
2528 : : // # ??/??
2529 : : //! "??/" would be interpreted by the compiler as a trigraph for '\'
2530 : 2440 : aSingleFormatCode.Code = "# ?\?/?\?";
2531 : : ImpInsertFormat( aSingleFormatCode,
2532 [ + - ]: 2440 : CLOffset + SetIndexTable( NF_FRACTION_2, ZF_STANDARD_FRACTION+1 ));
2533 : :
2534 : : // # ?/4
2535 : 2440 : aSingleFormatCode.Code = "# ?/4";
2536 : : ImpInsertNewStandardFormat( aSingleFormatCode,
2537 : 2440 : CLOffset + SetIndexTable( NF_FRACTION_3, ZF_STANDARD_FRACTION+2 ),
2538 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_FIXED_FRACTION );
2539 : :
2540 : : // # ??/100
2541 : 2440 : aSingleFormatCode.Code = "# ?\?/100";
2542 : : ImpInsertNewStandardFormat( aSingleFormatCode,
2543 : 2440 : CLOffset + SetIndexTable( NF_FRACTION_4, ZF_STANDARD_FRACTION+3 ),
2544 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_FIXED_FRACTION );
2545 : :
2546 : :
2547 : :
2548 : : // Week of year must be appended here because of nNewExtended
2549 [ + - ]: 2440 : const NfKeywordTable & rKeyword = pFormatScanner->GetKeywords();
2550 [ + - ][ + - ]: 2440 : aSingleFormatCode.Code = rKeyword[NF_KEY_WW];
2551 : : ImpInsertNewStandardFormat( aSingleFormatCode,
2552 : 2440 : CLOffset + SetIndexTable( NF_DATE_WW, nNewExtended++ ),
2553 [ + - ]: 2440 : SV_NUMBERFORMATTER_VERSION_NF_DATE_WW );
2554 : :
2555 : :
2556 : 2440 : bIndexTableInitialized = true;
2557 : : DBG_ASSERT( nNewExtended <= ZF_STANDARD_NEWEXTENDEDMAX,
2558 : : "ImpGenerateFormats: overflow of nNewExtended standard formats" );
2559 : :
2560 : : // Now all additional format codes provided by I18N, but only if not
2561 : : // changing SystemCL, then they are appended last after user defined.
2562 [ + - ]: 2440 : if ( !bNoAdditionalFormats )
2563 [ + - ]: 2440 : ImpGenerateAdditionalFormats( CLOffset, aNumberFormatCode, false );
2564 : :
2565 [ + + ]: 2440 : if (bOldConvertMode)
2566 [ + - ][ + - ]: 2440 : pFormatScanner->SetConvertMode(true);
[ + - ]
2567 : 2440 : }
2568 : :
2569 : :
2570 : 2440 : void SvNumberFormatter::ImpGenerateAdditionalFormats( sal_uInt32 CLOffset,
2571 : : NumberFormatCodeWrapper& rNumberFormatCode, bool bAfterChangingSystemCL )
2572 : : {
2573 : : using namespace ::com::sun::star;
2574 : :
2575 [ + - ]: 2440 : SvNumberformat* pStdFormat = GetFormatEntry( CLOffset + ZF_STANDARD );
2576 [ + - ]: 2440 : if ( !pStdFormat )
2577 : : {
2578 : : SAL_WARN( "svl.numbers", "ImpGenerateAdditionalFormats: no GENERAL format" );
2579 : 2440 : return ;
2580 : : }
2581 : 2440 : sal_uInt32 nPos = CLOffset + pStdFormat->GetLastInsertKey();
2582 [ + - ]: 2440 : rNumberFormatCode.setLocale( GetLocale() );
2583 : : sal_Int32 j;
2584 : :
2585 : : // All currencies, this time with [$...] which was stripped in
2586 : : // ImpGenerateFormats for old "automatic" currency formats.
2587 : : uno::Sequence< i18n::NumberFormatCode > aFormatSeq =
2588 [ + - ]: 2440 : rNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::CURRENCY );
2589 [ + - ]: 2440 : i18n::NumberFormatCode * pFormatArr = aFormatSeq.getArray();
2590 : 2440 : sal_Int32 nCodes = aFormatSeq.getLength();
2591 [ + - ][ + - ]: 2440 : ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), nCodes );
2592 [ + + ]: 17080 : for ( j = 0; j < nCodes; j++ )
2593 : : {
2594 [ - + ]: 14640 : if ( nPos - CLOffset >= SV_COUNTRY_LANGUAGE_OFFSET )
2595 : : {
2596 : : SAL_WARN( "svl.numbers", "ImpGenerateAdditionalFormats: too many formats" );
2597 : 0 : break; // for
2598 : : }
2599 [ + - ][ + + ]: 14640 : if ( pFormatArr[j].Index < NF_INDEX_TABLE_ENTRIES &&
2600 : 14640 : pFormatArr[j].Index != NF_CURRENCY_1000DEC2_CCC )
2601 : : { // Insert only if not already inserted, but internal index must be
2602 : : // above so ImpInsertFormat can distinguish it.
2603 : 12200 : sal_Int16 nOrgIndex = pFormatArr[j].Index;
2604 : 12200 : pFormatArr[j].Index = sal::static_int_cast< sal_Int16 >(
2605 : 12200 : pFormatArr[j].Index + nCodes + NF_INDEX_TABLE_ENTRIES);
2606 : : //! no default on currency
2607 [ + - ]: 12200 : bool bDefault = aFormatSeq[j].Default;
2608 [ + - ]: 12200 : aFormatSeq[j].Default = false;
2609 [ + - ]: 12200 : if ( ImpInsertNewStandardFormat( pFormatArr[j], nPos+1,
2610 : : SV_NUMBERFORMATTER_VERSION_ADDITIONAL_I18N_FORMATS,
2611 [ + - ]: 12200 : bAfterChangingSystemCL, nOrgIndex ) )
2612 : 12200 : nPos++;
2613 : 12200 : pFormatArr[j].Index = nOrgIndex;
2614 [ + - ]: 12200 : aFormatSeq[j].Default = bDefault;
2615 : : }
2616 : : }
2617 : :
2618 : : // all additional format codes provided by I18N that are not old standard index
2619 [ + - ][ + - ]: 2440 : aFormatSeq = rNumberFormatCode.getAllFormatCodes();
[ + - ]
2620 : 2440 : nCodes = aFormatSeq.getLength();
2621 [ + - ]: 2440 : if ( nCodes )
2622 : : {
2623 [ + - ]: 2440 : pFormatArr = aFormatSeq.getArray();
2624 : : // don't check ALL
2625 [ + - ]: 2440 : sal_Int32 nDef = ImpAdjustFormatCodeDefault( pFormatArr, nCodes, false);
2626 : : // don't have any defaults here
2627 : 2440 : pFormatArr[nDef].Default = false;
2628 [ + + ]: 143780 : for ( j = 0; j < nCodes; j++ )
2629 : : {
2630 [ - + ]: 141340 : if ( nPos - CLOffset >= SV_COUNTRY_LANGUAGE_OFFSET )
2631 : : {
2632 : : SAL_WARN( "svl.numbers", "ImpGenerateAdditionalFormats: too many formats" );
2633 : 0 : break; // for
2634 : : }
2635 [ + + ]: 141340 : if ( pFormatArr[j].Index >= NF_INDEX_TABLE_ENTRIES )
2636 [ + - ]: 24250 : if ( ImpInsertNewStandardFormat( pFormatArr[j], nPos+1,
2637 : : SV_NUMBERFORMATTER_VERSION_ADDITIONAL_I18N_FORMATS,
2638 [ + - ]: 24250 : bAfterChangingSystemCL ) )
2639 : 24250 : nPos++;
2640 : : }
2641 : : }
2642 : :
2643 [ + - ]: 2440 : pStdFormat->SetLastInsertKey( (sal_uInt16)(nPos - CLOffset) );
2644 : : }
2645 : :
2646 : :
2647 : 0 : void SvNumberFormatter::ImpGetPosCurrFormat( String& sPosStr, const String& rCurrSymbol )
2648 : : {
2649 : : NfCurrencyEntry::CompletePositiveFormatString( sPosStr,
2650 : 0 : rCurrSymbol, xLocaleData->getCurrPositiveFormat() );
2651 : 0 : }
2652 : :
2653 : 0 : void SvNumberFormatter::ImpGetNegCurrFormat( String& sNegStr, const String& rCurrSymbol )
2654 : : {
2655 : : NfCurrencyEntry::CompleteNegativeFormatString( sNegStr,
2656 : 0 : rCurrSymbol, xLocaleData->getCurrNegativeFormat() );
2657 : 0 : }
2658 : :
2659 : 798 : void SvNumberFormatter::GenerateFormat(String& sString,
2660 : : sal_uInt32 nIndex,
2661 : : LanguageType eLnge,
2662 : : bool bThousand,
2663 : : bool IsRed,
2664 : : sal_uInt16 nPrecision,
2665 : : sal_uInt16 nAnzLeading)
2666 : : {
2667 [ - + ]: 798 : if (eLnge == LANGUAGE_DONTKNOW)
2668 : 0 : eLnge = IniLnge;
2669 [ + - ]: 798 : short eType = GetType(nIndex);
2670 : : sal_uInt16 i;
2671 [ + - ]: 798 : ImpGenerateCL(eLnge); // create new standard formats if necessary
2672 [ + - ]: 798 : sString.Erase();
2673 : :
2674 [ + - ][ + - ]: 798 : utl::DigitGroupingIterator aGrouping( xLocaleData->getDigitGrouping());
[ + - ]
2675 : 798 : const xub_StrLen nDigitsInFirstGroup = static_cast<xub_StrLen>(aGrouping.get());
2676 : 798 : const String& rThSep = GetNumThousandSep();
2677 : :
2678 [ + - ]: 798 : SvNumberformat* pFormat = GetFormatEntry( nIndex );
2679 : :
2680 [ + + ]: 798 : if (nAnzLeading == 0)
2681 : : {
2682 [ + - ]: 18 : if (!bThousand)
2683 [ + - ]: 18 : sString += '#';
2684 : : else
2685 : : {
2686 [ # # ]: 0 : sString += '#';
2687 [ # # ]: 0 : sString += rThSep;
2688 [ # # ]: 0 : sString.Expand( sString.Len() + nDigitsInFirstGroup, '#' );
2689 : : }
2690 : : }
2691 : : else
2692 : : {
2693 [ + + ]: 1576 : for (i = 0; i < nAnzLeading; i++)
2694 : : {
2695 [ + + ][ - + ]: 796 : if (bThousand && i > 0 && i == aGrouping.getPos())
[ # # ][ - + ]
2696 : : {
2697 [ # # ]: 0 : sString.Insert( rThSep, 0 );
2698 [ # # ]: 0 : aGrouping.advance();
2699 : : }
2700 [ + - ]: 796 : sString.Insert('0',0);
2701 : : }
2702 [ + + ][ + - ]: 780 : if (bThousand && nAnzLeading < nDigitsInFirstGroup + 1)
2703 : : {
2704 [ + + ]: 1932 : for (i = nAnzLeading; i < nDigitsInFirstGroup + 1; i++)
2705 : : {
2706 [ + - ][ + + ]: 1449 : if (bThousand && i % nDigitsInFirstGroup == 0)
2707 [ + - ]: 483 : sString.Insert( rThSep, 0 );
2708 [ + - ]: 1449 : sString.Insert('#',0);
2709 : : }
2710 : : }
2711 : : }
2712 [ + + ]: 798 : if (nPrecision > 0)
2713 : : {
2714 [ + - ]: 669 : sString += GetNumDecimalSep();
2715 [ + - ]: 669 : sString.Expand( sString.Len() + nPrecision, '0' );
2716 : : }
2717 [ - + ]: 798 : if (eType == NUMBERFORMAT_PERCENT)
2718 [ # # ]: 0 : sString += '%';
2719 [ + + ]: 798 : else if (eType == NUMBERFORMAT_CURRENCY)
2720 : : {
2721 [ + - ]: 80 : String sNegStr = sString;
2722 [ + - ]: 80 : String aCurr;
2723 : : const NfCurrencyEntry* pEntry;
2724 : : bool bBank;
2725 [ + - ][ + - ]: 80 : if ( GetNewCurrencySymbolString( nIndex, aCurr, &pEntry, &bBank ) )
2726 : : {
2727 [ + + ]: 80 : if ( pEntry )
2728 : : {
2729 : : sal_uInt16 nPosiForm = NfCurrencyEntry::GetEffectivePositiveFormat(
2730 [ + - ]: 20 : xLocaleData->getCurrPositiveFormat(),
2731 [ + - ]: 40 : pEntry->GetPositiveFormat(), bBank );
2732 : : sal_uInt16 nNegaForm = NfCurrencyEntry::GetEffectiveNegativeFormat(
2733 [ + - ]: 20 : xLocaleData->getCurrNegativeFormat(),
2734 [ + - ]: 40 : pEntry->GetNegativeFormat(), bBank );
2735 : : pEntry->CompletePositiveFormatString( sString, bBank,
2736 [ + - ]: 20 : nPosiForm );
2737 : : pEntry->CompleteNegativeFormatString( sNegStr, bBank,
2738 [ + - ]: 20 : nNegaForm );
2739 : : }
2740 : : else
2741 : : { // assume currency abbreviation (AKA banking symbol), not symbol
2742 : : sal_uInt16 nPosiForm = NfCurrencyEntry::GetEffectivePositiveFormat(
2743 [ + - ]: 60 : xLocaleData->getCurrPositiveFormat(),
2744 [ + - ][ + - ]: 120 : xLocaleData->getCurrPositiveFormat(), true );
2745 : : sal_uInt16 nNegaForm = NfCurrencyEntry::GetEffectiveNegativeFormat(
2746 [ + - ]: 60 : xLocaleData->getCurrNegativeFormat(),
2747 [ + - ][ + - ]: 120 : xLocaleData->getCurrNegativeFormat(), true );
2748 : : NfCurrencyEntry::CompletePositiveFormatString( sString, aCurr,
2749 [ + - ]: 60 : nPosiForm );
2750 : : NfCurrencyEntry::CompleteNegativeFormatString( sNegStr, aCurr,
2751 [ + - ]: 60 : nNegaForm );
2752 : : }
2753 : : }
2754 : : else
2755 : : { // "automatic" old style
2756 [ # # ][ # # ]: 0 : String aSymbol, aAbbrev;
2757 [ # # ]: 0 : GetCompatibilityCurrency( aSymbol, aAbbrev );
2758 [ # # ]: 0 : ImpGetPosCurrFormat( sString, aSymbol );
2759 [ # # ][ # # ]: 0 : ImpGetNegCurrFormat( sNegStr, aSymbol );
[ # # ]
2760 : : }
2761 [ - + ]: 80 : if (IsRed)
2762 : : {
2763 [ # # ]: 0 : sString += ';';
2764 [ # # ]: 0 : sString += '[';
2765 [ # # ][ # # ]: 0 : sString += pFormatScanner->GetRedString();
2766 [ # # ]: 0 : sString += ']';
2767 : : }
2768 : : else
2769 [ + - ]: 80 : sString += ';';
2770 [ + - ][ + - ]: 80 : sString += sNegStr;
[ + - ]
2771 : : }
2772 [ + + ]: 798 : if (eType != NUMBERFORMAT_CURRENCY)
2773 : : {
2774 : 718 : bool insertBrackets = false;
2775 [ + - ]: 718 : if ( eType != NUMBERFORMAT_UNDEFINED)
2776 [ + - ]: 718 : insertBrackets = pFormat->IsNegativeInBracket();
2777 [ + - ][ - + ]: 718 : if (IsRed || insertBrackets)
2778 : : {
2779 [ # # ]: 0 : String sTmpStr = sString;
2780 : :
2781 [ # # ][ # # ]: 0 : if ( pFormat->HasPositiveBracketPlaceholder() )
2782 : : {
2783 [ # # ]: 0 : sTmpStr += '_';
2784 [ # # ]: 0 : sTmpStr += ')';
2785 : : }
2786 [ # # ]: 0 : sTmpStr += ';';
2787 : :
2788 [ # # ]: 0 : if (IsRed)
2789 : : {
2790 [ # # ]: 0 : sTmpStr += '[';
2791 [ # # ][ # # ]: 0 : sTmpStr += pFormatScanner->GetRedString();
2792 [ # # ]: 0 : sTmpStr += ']';
2793 : : }
2794 : :
2795 [ # # ]: 0 : if (insertBrackets)
2796 : : {
2797 [ # # ]: 0 : sTmpStr += '(';
2798 [ # # ]: 0 : sTmpStr += sString;
2799 [ # # ]: 0 : sTmpStr += ')';
2800 : : }
2801 : : else
2802 : : {
2803 [ # # ]: 0 : sTmpStr += '-';
2804 [ # # ]: 0 : sTmpStr +=sString;
2805 : : }
2806 [ # # ][ # # ]: 0 : sString = sTmpStr;
2807 : : }
2808 [ + - ]: 798 : }
2809 : 798 : }
2810 : :
2811 : 0 : bool SvNumberFormatter::IsUserDefined(const String& sStr,
2812 : : LanguageType eLnge)
2813 : : {
2814 [ # # ]: 0 : if (eLnge == LANGUAGE_DONTKNOW)
2815 : 0 : eLnge = IniLnge;
2816 : 0 : sal_uInt32 CLOffset = ImpGenerateCL(eLnge); // create new standard formats if necessary
2817 : 0 : eLnge = ActLnge;
2818 : 0 : sal_uInt32 nKey = ImpIsEntry(sStr, CLOffset, eLnge);
2819 [ # # ]: 0 : if (nKey == NUMBERFORMAT_ENTRY_NOT_FOUND)
2820 : 0 : return true;
2821 : 0 : SvNumberformat* pEntry = GetFormatEntry( nKey );
2822 [ # # ][ # # ]: 0 : if ( pEntry && ((pEntry->GetType() & NUMBERFORMAT_DEFINED) != 0) )
[ # # ]
2823 : 0 : return true;
2824 : 0 : return false;
2825 : : }
2826 : :
2827 : 953 : sal_uInt32 SvNumberFormatter::GetEntryKey(const String& sStr,
2828 : : LanguageType eLnge)
2829 : : {
2830 [ - + ]: 953 : if (eLnge == LANGUAGE_DONTKNOW)
2831 : 0 : eLnge = IniLnge;
2832 : 953 : sal_uInt32 CLOffset = ImpGenerateCL(eLnge); // create new standard formats if necessary
2833 : 953 : return ImpIsEntry(sStr, CLOffset, eLnge);
2834 : : }
2835 : :
2836 : 3650 : sal_uInt32 SvNumberFormatter::GetStandardIndex(LanguageType eLnge)
2837 : : {
2838 [ + + ]: 3650 : if (eLnge == LANGUAGE_DONTKNOW)
2839 : 768 : eLnge = IniLnge;
2840 : 3650 : return GetStandardFormat(NUMBERFORMAT_NUMBER, eLnge);
2841 : : }
2842 : :
2843 : 9152 : short SvNumberFormatter::GetType(sal_uInt32 nFIndex)
2844 : : {
2845 : : short eType;
2846 : 9152 : SvNumberformat* pFormat = GetFormatEntry( nFIndex );
2847 [ - + ]: 9152 : if (!pFormat)
2848 : 0 : eType = NUMBERFORMAT_UNDEFINED;
2849 : : else
2850 : : {
2851 : 9152 : eType = pFormat->GetType() &~NUMBERFORMAT_DEFINED;
2852 [ - + ]: 9152 : if (eType == 0)
2853 : 0 : eType = NUMBERFORMAT_DEFINED;
2854 : : }
2855 : 9152 : return eType;
2856 : : }
2857 : :
2858 : 1992 : void SvNumberFormatter::ClearMergeTable()
2859 : : {
2860 [ + + ]: 1992 : if ( pMergeTable )
2861 : : {
2862 : 9 : pMergeTable->clear();
2863 : : }
2864 : 1992 : }
2865 : :
2866 : 18 : SvNumberFormatterIndexTable* SvNumberFormatter::MergeFormatter(SvNumberFormatter& rTable)
2867 : : {
2868 [ - + ]: 18 : if ( pMergeTable )
2869 [ # # ]: 0 : ClearMergeTable();
2870 : : else
2871 [ + - ][ + - ]: 18 : pMergeTable = new SvNumberFormatterIndexTable;
2872 : 18 : sal_uInt32 nCLOffset = 0;
2873 : : sal_uInt32 nOldKey, nOffset, nNewKey;
2874 : : SvNumberformat* pNewEntry;
2875 : 18 : SvNumberFormatTable::iterator it = rTable.aFTable.begin();
2876 [ + - ][ + + ]: 1499 : while (it != rTable.aFTable.end())
2877 : : {
2878 [ + - ]: 1481 : SvNumberformat* pFormat = it->second;
2879 [ + - ]: 1481 : nOldKey = it->first;
2880 : 1481 : nOffset = nOldKey % SV_COUNTRY_LANGUAGE_OFFSET; // relative index
2881 [ + + ]: 1481 : if (nOffset == 0) // 1st format of CL
2882 [ + - ]: 22 : nCLOffset = ImpGenerateCL(pFormat->GetLanguage());
2883 : :
2884 [ + + ]: 1481 : if (nOffset <= SV_MAX_ANZ_STANDARD_FORMATE) // Std.form.
2885 : : {
2886 : 1144 : nNewKey = nCLOffset + nOffset;
2887 [ + - ][ + - ]: 1144 : if (aFTable.find( nNewKey) == aFTable.end()) // not already present
[ - + ]
2888 : : {
2889 : : // pNewEntry = new SvNumberformat(*pFormat); // Copy is not sufficient!
2890 [ # # ][ # # ]: 0 : pNewEntry = new SvNumberformat( *pFormat, *pFormatScanner );
2891 [ # # ][ # # ]: 0 : if (!aFTable.insert(make_pair( nNewKey, pNewEntry)).second)
[ # # ]
2892 [ # # ][ # # ]: 0 : delete pNewEntry;
2893 : : }
2894 [ - + ]: 1144 : if (nNewKey != nOldKey) // new index
2895 : : {
2896 [ # # ]: 0 : (*pMergeTable)[nOldKey] = nNewKey;
2897 : : }
2898 : : }
2899 : : else // user defined
2900 : : {
2901 : : // pNewEntry = new SvNumberformat(*pFormat); // Copy is not sufficient!
2902 [ + - ][ + - ]: 337 : pNewEntry = new SvNumberformat( *pFormat, *pFormatScanner );
2903 : 337 : nNewKey = ImpIsEntry(pNewEntry->GetFormatstring(),
2904 : : nCLOffset,
2905 [ + - ]: 674 : pFormat->GetLanguage());
2906 [ + + ]: 337 : if (nNewKey != NUMBERFORMAT_ENTRY_NOT_FOUND) // already present
2907 [ + - ][ + - ]: 332 : delete pNewEntry;
2908 : : else
2909 : : {
2910 : : SvNumberformat* pStdFormat =
2911 [ + - ]: 5 : GetFormatEntry(nCLOffset + ZF_STANDARD);
2912 : 5 : sal_uInt32 nPos = nCLOffset + pStdFormat->GetLastInsertKey();
2913 : 5 : nNewKey = nPos+1;
2914 [ - + ]: 5 : if (nPos - nCLOffset >= SV_COUNTRY_LANGUAGE_OFFSET)
2915 : : {
2916 : : OSL_FAIL(
2917 : : "SvNumberFormatter:: Zu viele Formate pro CL");
2918 [ # # ][ # # ]: 0 : delete pNewEntry;
2919 : : }
2920 [ + - ][ + - ]: 5 : else if (!aFTable.insert(make_pair( nNewKey, pNewEntry)).second)
[ - + ]
2921 [ # # ][ # # ]: 0 : delete pNewEntry;
2922 : : else
2923 : 5 : pStdFormat->SetLastInsertKey((sal_uInt16) (nNewKey - nCLOffset));
2924 : : }
2925 [ + + ]: 337 : if (nNewKey != nOldKey) // new index
2926 : : {
2927 [ + - ]: 5 : (*pMergeTable)[nOldKey] = nNewKey;
2928 : : }
2929 : : }
2930 [ + - ]: 1481 : ++it;
2931 : : }
2932 : 18 : return pMergeTable;
2933 : : }
2934 : :
2935 : :
2936 : 6 : SvNumberFormatterMergeMap SvNumberFormatter::ConvertMergeTableToMap()
2937 : : {
2938 [ + - ]: 6 : if (!HasMergeFmtTbl())
2939 [ + - ]: 6 : return SvNumberFormatterMergeMap();
2940 : :
2941 [ # # ]: 0 : SvNumberFormatterMergeMap aMap;
2942 [ # # ][ # # ]: 0 : for (SvNumberFormatterIndexTable::iterator it = pMergeTable->begin(); it != pMergeTable->end(); ++it)
[ # # ]
2943 : : {
2944 [ # # ]: 0 : sal_uInt32 nOldKey = it->first;
2945 [ # # ][ # # ]: 0 : aMap[ nOldKey ] = it->second;
2946 : : }
2947 [ # # ]: 0 : ClearMergeTable();
2948 : 6 : return aMap;
2949 : : }
2950 : :
2951 : :
2952 : 55607 : sal_uInt32 SvNumberFormatter::GetFormatForLanguageIfBuiltIn( sal_uInt32 nFormat,
2953 : : LanguageType eLnge )
2954 : : {
2955 [ - + ]: 55607 : if ( eLnge == LANGUAGE_DONTKNOW )
2956 : 0 : eLnge = IniLnge;
2957 [ + + ][ + + ]: 55607 : if ( nFormat < SV_COUNTRY_LANGUAGE_OFFSET && eLnge == IniLnge )
2958 : 55224 : return nFormat; // it stays as it is
2959 : 383 : sal_uInt32 nOffset = nFormat % SV_COUNTRY_LANGUAGE_OFFSET; // relative index
2960 [ - + ]: 383 : if ( nOffset > SV_MAX_ANZ_STANDARD_FORMATE )
2961 : 0 : return nFormat; // not a built-in format
2962 : 383 : sal_uInt32 nCLOffset = ImpGenerateCL(eLnge); // create new standard formats if necessary
2963 : 55607 : return nCLOffset + nOffset;
2964 : : }
2965 : :
2966 : :
2967 : 11835 : sal_uInt32 SvNumberFormatter::GetFormatIndex( NfIndexTableOffset nTabOff,
2968 : : LanguageType eLnge )
2969 : : {
2970 [ + - ][ - + ]: 11835 : if ( nTabOff >= NF_INDEX_TABLE_ENTRIES
2971 : 11835 : || theIndexTable[nTabOff] == NUMBERFORMAT_ENTRY_NOT_FOUND )
2972 : 0 : return NUMBERFORMAT_ENTRY_NOT_FOUND;
2973 [ - + ]: 11835 : if ( eLnge == LANGUAGE_DONTKNOW )
2974 : 0 : eLnge = IniLnge;
2975 : 11835 : sal_uInt32 nCLOffset = ImpGenerateCL(eLnge); // create new standard formats if necessary
2976 : 11835 : return nCLOffset + theIndexTable[nTabOff];
2977 : : }
2978 : :
2979 : :
2980 : 770 : NfIndexTableOffset SvNumberFormatter::GetIndexTableOffset( sal_uInt32 nFormat ) const
2981 : : {
2982 : 770 : sal_uInt32 nOffset = nFormat % SV_COUNTRY_LANGUAGE_OFFSET; // relative index
2983 [ + + ]: 770 : if ( nOffset > SV_MAX_ANZ_STANDARD_FORMATE )
2984 : 584 : return NF_INDEX_TABLE_ENTRIES; // not a built-in format
2985 [ + - ]: 1566 : for ( sal_uInt16 j = 0; j < NF_INDEX_TABLE_ENTRIES; j++ )
2986 : : {
2987 [ + + ]: 1566 : if ( theIndexTable[j] == nOffset )
2988 : 186 : return (NfIndexTableOffset) j;
2989 : : }
2990 : 770 : return NF_INDEX_TABLE_ENTRIES; // bad luck
2991 : : }
2992 : :
2993 : :
2994 : 2868 : void SvNumberFormatter::SetYear2000( sal_uInt16 nVal )
2995 : : {
2996 : 2868 : pStringScanner->SetYear2000( nVal );
2997 : 2868 : }
2998 : :
2999 : :
3000 : 48 : sal_uInt16 SvNumberFormatter::GetYear2000() const
3001 : : {
3002 : 48 : return pStringScanner->GetYear2000();
3003 : : }
3004 : :
3005 : :
3006 : 0 : sal_uInt16 SvNumberFormatter::ExpandTwoDigitYear( sal_uInt16 nYear ) const
3007 : : {
3008 [ # # ]: 0 : if ( nYear < 100 )
3009 : : return SvNumberFormatter::ExpandTwoDigitYear( nYear,
3010 : 0 : pStringScanner->GetYear2000() );
3011 : 0 : return nYear;
3012 : : }
3013 : :
3014 : :
3015 : : // static
3016 : 4869 : sal_uInt16 SvNumberFormatter::GetYear2000Default()
3017 : : {
3018 [ + - ]: 4869 : return (sal_uInt16) ::utl::MiscCfg().GetYear2000();
3019 : : }
3020 : :
3021 : :
3022 : : // static
3023 : 339 : const NfCurrencyTable& SvNumberFormatter::GetTheCurrencyTable()
3024 : : {
3025 [ + - ][ + - ]: 339 : ::osl::MutexGuard aGuard( GetMutex() );
3026 [ + + ]: 375 : while ( !bCurrencyTableInitialized )
3027 [ + - ]: 36 : ImpInitCurrencyTable();
3028 [ + - ][ + - ]: 339 : return theCurrencyTable::get();
3029 : : }
3030 : :
3031 : :
3032 : : // static
3033 : 198 : const NfCurrencyEntry* SvNumberFormatter::MatchSystemCurrency()
3034 : : {
3035 : : // MUST call GetTheCurrencyTable() before accessing nSystemCurrencyPosition
3036 : 198 : const NfCurrencyTable& rTable = GetTheCurrencyTable();
3037 [ + - ]: 198 : return nSystemCurrencyPosition ? &rTable[nSystemCurrencyPosition] : NULL;
3038 : : }
3039 : :
3040 : :
3041 : : // static
3042 : 221 : const NfCurrencyEntry& SvNumberFormatter::GetCurrencyEntry( LanguageType eLang )
3043 : : {
3044 [ + + ]: 221 : if ( eLang == LANGUAGE_SYSTEM )
3045 : : {
3046 : 178 : const NfCurrencyEntry* pCurr = MatchSystemCurrency();
3047 [ - + ]: 178 : return pCurr ? *pCurr : GetTheCurrencyTable()[0];
3048 : : }
3049 : : else
3050 : : {
3051 : 43 : eLang = MsLangId::getRealLanguage( eLang );
3052 : 43 : const NfCurrencyTable& rTable = GetTheCurrencyTable();
3053 : 43 : sal_uInt16 nCount = rTable.size();
3054 [ + - ]: 86 : for ( sal_uInt16 j = 0; j < nCount; j++ )
3055 : : {
3056 [ + + ]: 86 : if ( rTable[j].GetLanguage() == eLang )
3057 : 43 : return rTable[j];
3058 : : }
3059 : 221 : return rTable[0];
3060 : : }
3061 : : }
3062 : :
3063 : :
3064 : : // static
3065 : 0 : const NfCurrencyEntry* SvNumberFormatter::GetCurrencyEntry(
3066 : : const String& rAbbrev, LanguageType eLang )
3067 : : {
3068 : 0 : eLang = MsLangId::getRealLanguage( eLang );
3069 : 0 : const NfCurrencyTable& rTable = GetTheCurrencyTable();
3070 : 0 : sal_uInt16 nCount = rTable.size();
3071 [ # # ]: 0 : for ( sal_uInt16 j = 0; j < nCount; j++ )
3072 : : {
3073 [ # # # # ]: 0 : if ( rTable[j].GetLanguage() == eLang &&
[ # # ]
3074 : 0 : rTable[j].GetBankSymbol() == rAbbrev )
3075 : 0 : return &rTable[j];
3076 : : }
3077 : 0 : return NULL;
3078 : : }
3079 : :
3080 : :
3081 : : // static
3082 : 0 : const NfCurrencyEntry* SvNumberFormatter::GetLegacyOnlyCurrencyEntry(
3083 : : const String& rSymbol, const String& rAbbrev )
3084 : : {
3085 [ # # ]: 0 : if (!bCurrencyTableInitialized)
3086 : 0 : GetTheCurrencyTable(); // just for initialization
3087 : 0 : const NfCurrencyTable& rTable = theLegacyOnlyCurrencyTable::get();
3088 : 0 : sal_uInt16 nCount = rTable.size();
3089 [ # # ]: 0 : for ( sal_uInt16 j = 0; j < nCount; j++ )
3090 : : {
3091 [ # # # # ]: 0 : if ( rTable[j].GetSymbol() == rSymbol &&
[ # # ]
3092 : 0 : rTable[j].GetBankSymbol() == rAbbrev )
3093 : 0 : return &rTable[j];
3094 : : }
3095 : 0 : return NULL;
3096 : : }
3097 : :
3098 : :
3099 : : // static
3100 : 0 : IMPL_STATIC_LINK_NOINSTANCE( SvNumberFormatter, CurrencyChangeLink, SAL_UNUSED_PARAMETER void*, EMPTYARG )
3101 : : {
3102 [ # # ][ # # ]: 0 : ::osl::MutexGuard aGuard( GetMutex() );
3103 [ # # ]: 0 : String aAbbrev;
3104 : 0 : LanguageType eLang = LANGUAGE_SYSTEM;
3105 [ # # ][ # # ]: 0 : SvtSysLocaleOptions().GetCurrencyAbbrevAndLanguage( aAbbrev, eLang );
[ # # ]
3106 [ # # ]: 0 : SetDefaultSystemCurrency( aAbbrev, eLang );
3107 [ # # ][ # # ]: 0 : return 0;
3108 : : }
3109 : :
3110 : :
3111 : : // static
3112 : 0 : void SvNumberFormatter::SetDefaultSystemCurrency( const String& rAbbrev, LanguageType eLang )
3113 : : {
3114 [ # # ][ # # ]: 0 : ::osl::MutexGuard aGuard( GetMutex() );
3115 [ # # ]: 0 : if ( eLang == LANGUAGE_SYSTEM )
3116 [ # # ][ # # ]: 0 : eLang = SvtSysLocale().GetLanguage();
[ # # ]
3117 [ # # ]: 0 : const NfCurrencyTable& rTable = GetTheCurrencyTable();
3118 : 0 : sal_uInt16 nCount = rTable.size();
3119 [ # # ]: 0 : if ( rAbbrev.Len() )
3120 : : {
3121 [ # # ]: 0 : for ( sal_uInt16 j = 0; j < nCount; j++ )
3122 : : {
3123 [ # # ][ # # ]: 0 : if ( rTable[j].GetLanguage() == eLang && rTable[j].GetBankSymbol() == rAbbrev )
[ # # ][ # # ]
[ # # ][ # # ]
3124 : : {
3125 : 0 : nSystemCurrencyPosition = j;
3126 : : return ;
3127 : : }
3128 : : }
3129 : : }
3130 : : else
3131 : : {
3132 [ # # ]: 0 : for ( sal_uInt16 j = 0; j < nCount; j++ )
3133 : : {
3134 [ # # ][ # # ]: 0 : if ( rTable[j].GetLanguage() == eLang )
3135 : : {
3136 : 0 : nSystemCurrencyPosition = j;
3137 : : return ;
3138 : : }
3139 : : }
3140 : : }
3141 [ # # ][ # # ]: 0 : nSystemCurrencyPosition = 0; // not found => simple SYSTEM
3142 : : }
3143 : :
3144 : :
3145 : 0 : void SvNumberFormatter::ResetDefaultSystemCurrency()
3146 : : {
3147 : 0 : nDefaultSystemCurrencyFormat = NUMBERFORMAT_ENTRY_NOT_FOUND;
3148 : 0 : }
3149 : :
3150 : :
3151 : 190 : sal_uInt32 SvNumberFormatter::ImpGetDefaultSystemCurrencyFormat()
3152 : : {
3153 [ + + ]: 190 : if ( nDefaultSystemCurrencyFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
3154 : : {
3155 : : xub_StrLen nCheck;
3156 : : short nType;
3157 [ + - ]: 97 : NfWSStringsDtor aCurrList;
3158 : : sal_uInt16 nDefault = GetCurrencyFormatStrings( aCurrList,
3159 [ + - ][ + - ]: 97 : GetCurrencyEntry( LANGUAGE_SYSTEM ), false );
3160 : : DBG_ASSERT( aCurrList.size(), "where is the NewCurrency System standard format?!?" );
3161 : : // if already loaded or user defined nDefaultSystemCurrencyFormat
3162 : : // will be set to the right value
3163 : 97 : PutEntry( aCurrList[ nDefault ], nCheck, nType,
3164 [ + - ]: 97 : nDefaultSystemCurrencyFormat, LANGUAGE_SYSTEM );
3165 : : DBG_ASSERT( nCheck == 0, "NewCurrency CheckError" );
3166 : : DBG_ASSERT( nDefaultSystemCurrencyFormat != NUMBERFORMAT_ENTRY_NOT_FOUND,
3167 : 97 : "nDefaultSystemCurrencyFormat == NUMBERFORMAT_ENTRY_NOT_FOUND" );
3168 : : }
3169 : 190 : return nDefaultSystemCurrencyFormat;
3170 : : }
3171 : :
3172 : :
3173 : 0 : sal_uInt32 SvNumberFormatter::ImpGetDefaultCurrencyFormat()
3174 : : {
3175 [ # # ]: 0 : sal_uInt32 CLOffset = ImpGetCLOffset( ActLnge );
3176 [ # # ]: 0 : DefaultFormatKeysMap::iterator it = aDefaultFormatKeys.find( CLOffset + ZF_STANDARD_CURRENCY );
3177 [ # # ]: 0 : sal_uInt32 nDefaultCurrencyFormat = (it != aDefaultFormatKeys.end() ?
3178 [ # # ][ # # ]: 0 : it->second : NUMBERFORMAT_ENTRY_NOT_FOUND);
3179 [ # # ]: 0 : if ( nDefaultCurrencyFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
3180 : : {
3181 : : // look for a defined standard
3182 : 0 : sal_uInt32 nStopKey = CLOffset + SV_COUNTRY_LANGUAGE_OFFSET;
3183 : : sal_uInt32 nKey;
3184 [ # # ]: 0 : SvNumberFormatTable::iterator it2 = aFTable.lower_bound( CLOffset );
3185 [ # # ][ # # ]: 0 : while ( it2 != aFTable.end() && (nKey = it2->first) >= CLOffset && nKey < nStopKey )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
3186 : : {
3187 [ # # ]: 0 : const SvNumberformat* pEntry = it2->second;
3188 [ # # ][ # # ]: 0 : if ( pEntry->IsStandard() && (pEntry->GetType() & NUMBERFORMAT_CURRENCY) )
[ # # ]
3189 : : {
3190 : 0 : nDefaultCurrencyFormat = nKey;
3191 : 0 : break; // while
3192 : : }
3193 [ # # ]: 0 : ++it2;
3194 : : }
3195 : :
3196 [ # # ]: 0 : if ( nDefaultCurrencyFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
3197 : : { // none found, create one
3198 : : xub_StrLen nCheck;
3199 [ # # ]: 0 : NfWSStringsDtor aCurrList;
3200 : : sal_uInt16 nDefault = GetCurrencyFormatStrings( aCurrList,
3201 [ # # ][ # # ]: 0 : GetCurrencyEntry( ActLnge ), false );
3202 : : DBG_ASSERT( aCurrList.size(), "where is the NewCurrency standard format?" );
3203 [ # # ]: 0 : if ( !aCurrList.empty() )
3204 : : {
3205 : : // if already loaded or user defined nDefaultSystemCurrencyFormat
3206 : : // will be set to the right value
3207 : : short nType;
3208 : 0 : PutEntry( aCurrList[ nDefault ], nCheck, nType,
3209 [ # # ]: 0 : nDefaultCurrencyFormat, ActLnge );
3210 : : DBG_ASSERT( nCheck == 0, "NewCurrency CheckError" );
3211 : : DBG_ASSERT( nDefaultCurrencyFormat != NUMBERFORMAT_ENTRY_NOT_FOUND,
3212 : : "nDefaultCurrencyFormat == NUMBERFORMAT_ENTRY_NOT_FOUND" );
3213 : : }
3214 : : // old automatic currency format as a last resort
3215 [ # # ]: 0 : if ( nDefaultCurrencyFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
3216 : 0 : nDefaultCurrencyFormat = CLOffset + ZF_STANDARD_CURRENCY+3;
3217 : : else
3218 : : { // mark as standard so that it is found next time
3219 [ # # ]: 0 : SvNumberformat* pEntry = GetFormatEntry( nDefaultCurrencyFormat );
3220 [ # # ]: 0 : if ( pEntry )
3221 : 0 : pEntry->SetStandard();
3222 : 0 : }
3223 : : }
3224 [ # # ]: 0 : aDefaultFormatKeys[ CLOffset + ZF_STANDARD_CURRENCY ] = nDefaultCurrencyFormat;
3225 : : }
3226 : 0 : return nDefaultCurrencyFormat;
3227 : : }
3228 : :
3229 : :
3230 : : // static
3231 : : // try to make it inline if possible since this a loop body
3232 : : // true: continue; false: break loop, if pFoundEntry==NULL dupe found
3233 : : #ifndef DBG_UTIL
3234 : : inline
3235 : : #endif
3236 : 15143 : bool SvNumberFormatter::ImpLookupCurrencyEntryLoopBody(
3237 : : const NfCurrencyEntry*& pFoundEntry, bool& bFoundBank,
3238 : : const NfCurrencyEntry* pData, sal_uInt16 nPos, const String& rSymbol )
3239 : : {
3240 : : bool bFound;
3241 [ + + ]: 15143 : if ( pData->GetSymbol() == rSymbol )
3242 : : {
3243 : 23 : bFound = true;
3244 : 23 : bFoundBank = false;
3245 : : }
3246 [ - + ]: 15120 : else if ( pData->GetBankSymbol() == rSymbol )
3247 : : {
3248 : 0 : bFound = true;
3249 : 0 : bFoundBank = true;
3250 : : }
3251 : : else
3252 : 15120 : bFound = false;
3253 [ + + ]: 15143 : if ( bFound )
3254 : : {
3255 [ - + ][ # # ]: 23 : if ( pFoundEntry && pFoundEntry != pData )
3256 : : {
3257 : 0 : pFoundEntry = NULL;
3258 : 0 : return false; // break loop, not unique
3259 : : }
3260 [ + + ]: 23 : if ( nPos == 0 )
3261 : : { // first entry is SYSTEM
3262 : 20 : pFoundEntry = MatchSystemCurrency();
3263 [ + - ]: 20 : if ( pFoundEntry )
3264 : 20 : return false; // break loop
3265 : : // even if there are more matching entries
3266 : : // this one is propably the one we are looking for
3267 : : else
3268 : 0 : pFoundEntry = pData;
3269 : : }
3270 : : else
3271 : 3 : pFoundEntry = pData;
3272 : : }
3273 : 15143 : return true;
3274 : : }
3275 : :
3276 : :
3277 : 80 : bool SvNumberFormatter::GetNewCurrencySymbolString( sal_uInt32 nFormat,
3278 : : String& rStr, const NfCurrencyEntry** ppEntry /* = NULL */,
3279 : : bool* pBank /* = NULL */ ) const
3280 : : {
3281 : 80 : rStr.Erase();
3282 [ + - ]: 80 : if ( ppEntry )
3283 : 80 : *ppEntry = NULL;
3284 [ + - ]: 80 : if ( pBank )
3285 : 80 : *pBank = false;
3286 : 80 : const SvNumberformat* pFormat = GetFormatEntry(nFormat);
3287 [ + - ]: 80 : if ( pFormat )
3288 : : {
3289 [ + - ][ + - ]: 80 : String aSymbol, aExtension;
3290 [ + - ][ + - ]: 80 : if ( pFormat->GetNewCurrencySymbol( aSymbol, aExtension ) )
3291 : : {
3292 [ + - ]: 80 : if ( ppEntry )
3293 : : {
3294 : 80 : bool bFoundBank = false;
3295 : : // we definiteley need an entry matching the format code string
3296 : : const NfCurrencyEntry* pFoundEntry = GetCurrencyEntry(
3297 : 80 : bFoundBank, aSymbol, aExtension, pFormat->GetLanguage(),
3298 [ + - ]: 80 : true );
3299 [ + + ]: 80 : if ( pFoundEntry )
3300 : : {
3301 : 20 : *ppEntry = pFoundEntry;
3302 [ + - ]: 20 : if ( pBank )
3303 : 20 : *pBank = bFoundBank;
3304 [ + - ]: 80 : pFoundEntry->BuildSymbolString( rStr, bFoundBank );
3305 : : }
3306 : : }
3307 [ + + ]: 80 : if ( !rStr.Len() )
3308 : : { // analog to BuildSymbolString
3309 [ + - ]: 60 : rStr = '[';
3310 [ + - ]: 60 : rStr += '$';
3311 [ + - ][ + - ]: 120 : if ( aSymbol.Search( '-' ) != STRING_NOTFOUND ||
[ - + ][ - + ]
3312 [ + - ]: 60 : aSymbol.Search( ']' ) != STRING_NOTFOUND )
3313 : : {
3314 [ # # ]: 0 : rStr += '"';
3315 [ # # ]: 0 : rStr += aSymbol;
3316 [ # # ]: 0 : rStr += '"';
3317 : : }
3318 : : else
3319 [ + - ]: 60 : rStr += aSymbol;
3320 [ - + ]: 60 : if ( aExtension.Len() )
3321 [ # # ]: 0 : rStr += aExtension;
3322 [ + - ]: 60 : rStr += ']';
3323 : : }
3324 : 80 : return true;
3325 [ + - ][ + - ]: 80 : }
[ + - ][ - + ]
3326 : : }
3327 : 80 : return false;
3328 : : }
3329 : :
3330 : :
3331 : : // static
3332 : 83 : const NfCurrencyEntry* SvNumberFormatter::GetCurrencyEntry( bool & bFoundBank,
3333 : : const String& rSymbol, const String& rExtension,
3334 : : LanguageType eFormatLanguage, bool bOnlyStringLanguage )
3335 : : {
3336 : 83 : xub_StrLen nExtLen = rExtension.Len();
3337 : : LanguageType eExtLang;
3338 [ + + ]: 83 : if ( nExtLen )
3339 : : {
3340 [ + - ]: 3 : sal_Int32 nExtLang = ::rtl::OUString( rExtension ).toInt32( 16 );
3341 [ - + ]: 3 : if ( !nExtLang )
3342 : 0 : eExtLang = LANGUAGE_DONTKNOW;
3343 : : else
3344 : : eExtLang = (LanguageType) ((nExtLang < 0) ?
3345 : 3 : -nExtLang : nExtLang);
3346 : : }
3347 : : else
3348 : 80 : eExtLang = LANGUAGE_DONTKNOW;
3349 : 83 : const NfCurrencyEntry* pFoundEntry = NULL;
3350 [ + - ]: 83 : const NfCurrencyTable& rTable = GetTheCurrencyTable();
3351 : 83 : sal_uInt16 nCount = rTable.size();
3352 : 83 : bool bCont = true;
3353 : :
3354 : : // first try with given extension language/country
3355 [ + + ]: 83 : if ( nExtLen )
3356 : : {
3357 [ + + ][ + - ]: 759 : for ( sal_uInt16 j = 0; j < nCount && bCont; j++ )
[ + + ]
3358 : : {
3359 [ + - ]: 756 : LanguageType eLang = rTable[j].GetLanguage();
3360 [ - + ][ # # ]: 756 : if ( eLang == eExtLang ||
[ + + ]
3361 : : ((eExtLang == LANGUAGE_DONTKNOW) &&
3362 : : (eLang == LANGUAGE_SYSTEM))
3363 : : )
3364 : : {
3365 : : bCont = ImpLookupCurrencyEntryLoopBody( pFoundEntry, bFoundBank,
3366 [ + - ][ + - ]: 3 : &rTable[j], j, rSymbol );
3367 : : }
3368 : : }
3369 : : }
3370 : :
3371 : : // ok?
3372 [ + + ][ + - ]: 83 : if ( pFoundEntry || !bCont || (bOnlyStringLanguage && nExtLen) )
[ + - ][ - + ]
3373 : 3 : return pFoundEntry;
3374 : :
3375 [ - + ]: 80 : if ( !bOnlyStringLanguage )
3376 : : {
3377 : : // now try the language/country of the number format
3378 [ # # ][ # # ]: 0 : for ( sal_uInt16 j = 0; j < nCount && bCont; j++ )
[ # # ]
3379 : : {
3380 [ # # ]: 0 : LanguageType eLang = rTable[j].GetLanguage();
3381 [ # # ][ # # ]: 0 : if ( eLang == eFormatLanguage ||
[ # # ]
3382 : : ((eFormatLanguage == LANGUAGE_DONTKNOW) &&
3383 : : (eLang == LANGUAGE_SYSTEM))
3384 : : )
3385 : : {
3386 : : bCont = ImpLookupCurrencyEntryLoopBody( pFoundEntry, bFoundBank,
3387 [ # # ][ # # ]: 0 : &rTable[j], j, rSymbol );
3388 : : }
3389 : : }
3390 : :
3391 : : // ok?
3392 [ # # ][ # # ]: 0 : if ( pFoundEntry || !bCont )
3393 : 0 : return pFoundEntry;
3394 : : }
3395 : :
3396 : : // then try without language/country if no extension specified
3397 [ + - ]: 80 : if ( !nExtLen )
3398 : : {
3399 [ + + ][ + + ]: 15220 : for ( sal_uInt16 j = 0; j < nCount && bCont; j++ )
[ + + ]
3400 : : {
3401 : : bCont = ImpLookupCurrencyEntryLoopBody( pFoundEntry, bFoundBank,
3402 [ + - ][ + - ]: 15140 : &rTable[j], j, rSymbol );
3403 : : }
3404 : : }
3405 : :
3406 : 83 : return pFoundEntry;
3407 : : }
3408 : :
3409 : :
3410 : 7267 : void SvNumberFormatter::GetCompatibilityCurrency( String& rSymbol, String& rAbbrev ) const
3411 : : {
3412 : : ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::Currency2 >
3413 [ + - ]: 7267 : xCurrencies( xLocaleData->getAllCurrencies() );
3414 : :
3415 : 7267 : const ::com::sun::star::i18n::Currency2 *pCurrencies = xCurrencies.getConstArray();
3416 : 7267 : sal_Int32 nCurrencies = xCurrencies.getLength();
3417 : :
3418 : : sal_Int32 j;
3419 [ + - ]: 7281 : for ( j=0; j < nCurrencies; ++j )
3420 : : {
3421 [ + + ]: 7281 : if ( pCurrencies[j].UsedInCompatibleFormatCodes )
3422 : : {
3423 [ + - ]: 7267 : rSymbol = pCurrencies[j].Symbol;
3424 [ + - ]: 7267 : rAbbrev = pCurrencies[j].BankSymbol;
3425 : 7267 : break;
3426 : : }
3427 : : }
3428 [ - + ]: 7267 : if ( j >= nCurrencies )
3429 : : {
3430 [ # # ][ # # ]: 0 : if (LocaleDataWrapper::areChecksEnabled())
3431 : : LocaleDataWrapper::outputCheckMessage( xLocaleData->
3432 [ # # ][ # # ]: 0 : appendLocaleInfo( "GetCompatibilityCurrency: none?"));
3433 : :
3434 [ # # ][ # # ]: 0 : rSymbol = xLocaleData->getCurrSymbol();
3435 [ # # ][ # # ]: 0 : rAbbrev = xLocaleData->getCurrBankSymbol();
3436 [ + - ]: 7267 : }
3437 : 7267 : }
3438 : :
3439 : :
3440 : 0 : void lcl_CheckCurrencySymbolPosition( const NfCurrencyEntry& rCurr )
3441 : : {
3442 [ # # ]: 0 : switch ( rCurr.GetPositiveFormat() )
3443 : : {
3444 : : case 0: // $1
3445 : : case 1: // 1$
3446 : : case 2: // $ 1
3447 : : case 3: // 1 $
3448 : 0 : break;
3449 : : default:
3450 : : LocaleDataWrapper::outputCheckMessage(
3451 : 0 : "lcl_CheckCurrencySymbolPosition: unknown PositiveFormat");
3452 : 0 : break;
3453 : : }
3454 [ # # ]: 0 : switch ( rCurr.GetNegativeFormat() )
3455 : : {
3456 : : case 0: // ($1)
3457 : : case 1: // -$1
3458 : : case 2: // $-1
3459 : : case 3: // $1-
3460 : : case 4: // (1$)
3461 : : case 5: // -1$
3462 : : case 6: // 1-$
3463 : : case 7: // 1$-
3464 : : case 8: // -1 $
3465 : : case 9: // -$ 1
3466 : : case 10: // 1 $-
3467 : : case 11: // $ -1
3468 : : case 12 : // $ 1-
3469 : : case 13 : // 1- $
3470 : : case 14 : // ($ 1)
3471 : : case 15 : // (1 $)
3472 : 0 : break;
3473 : : default:
3474 : : LocaleDataWrapper::outputCheckMessage(
3475 : 0 : "lcl_CheckCurrencySymbolPosition: unknown NegativeFormat");
3476 : 0 : break;
3477 : : }
3478 : 0 : }
3479 : :
3480 : : // static
3481 : 15 : bool SvNumberFormatter::IsLocaleInstalled( LanguageType eLang )
3482 : : {
3483 : : // The set is initialized as a side effect of the currency table
3484 : : // created, make sure that exists, which usually is the case unless a
3485 : : // SvNumberFormatter was never instanciated.
3486 : 15 : GetTheCurrencyTable();
3487 : 15 : const NfInstalledLocales &rInstalledLocales = theInstalledLocales::get();
3488 [ + - ][ + - ]: 15 : return rInstalledLocales.find( eLang) != rInstalledLocales.end();
3489 : : }
3490 : :
3491 : : // static
3492 : 36 : void SvNumberFormatter::ImpInitCurrencyTable()
3493 : : {
3494 : : // racing condition possible:
3495 : : // ::osl::MutexGuard aGuard( GetMutex() );
3496 : : // while ( !bCurrencyTableInitialized )
3497 : : // ImpInitCurrencyTable();
3498 : : static bool bInitializing = false;
3499 [ + - ][ + - ]: 36 : if ( bCurrencyTableInitialized || bInitializing )
3500 : 36 : return ;
3501 : 36 : bInitializing = true;
3502 : :
3503 : : RTL_LOGFILE_CONTEXT_AUTHOR( aTimeLog, "svl", "er93726", "SvNumberFormatter::ImpInitCurrencyTable" );
3504 : :
3505 [ + - ][ + - ]: 36 : LanguageType eSysLang = SvtSysLocale().GetLanguage();
[ + - ]
3506 : : LocaleDataWrapper* pLocaleData = new LocaleDataWrapper(
3507 : : ::comphelper::getProcessServiceFactory(),
3508 [ + - ][ + - ]: 36 : MsLangId::convertLanguageToLocale( eSysLang ) );
[ + - ][ + - ]
3509 : : // get user configured currency
3510 [ + - ]: 36 : String aConfiguredCurrencyAbbrev;
3511 : 36 : LanguageType eConfiguredCurrencyLanguage = LANGUAGE_SYSTEM;
3512 : : SvtSysLocaleOptions().GetCurrencyAbbrevAndLanguage(
3513 [ + - ][ + - ]: 36 : aConfiguredCurrencyAbbrev, eConfiguredCurrencyLanguage );
[ + - ]
3514 : 36 : sal_uInt16 nSecondarySystemCurrencyPosition = 0;
3515 : 36 : sal_uInt16 nMatchingSystemCurrencyPosition = 0;
3516 : : NfCurrencyEntry* pEntry;
3517 : :
3518 : : // first entry is SYSTEM
3519 [ + - ][ + - ]: 36 : pEntry = new NfCurrencyEntry( *pLocaleData, LANGUAGE_SYSTEM );
3520 [ + - ][ + - ]: 36 : theCurrencyTable::get().insert( theCurrencyTable::get().begin(), pEntry );
[ + - ][ + - ]
3521 : 36 : sal_uInt16 nCurrencyPos = 1;
3522 : :
3523 : : ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > xLoc =
3524 [ + - ]: 36 : LocaleDataWrapper::getInstalledLocaleNames();
3525 : 36 : sal_Int32 nLocaleCount = xLoc.getLength();
3526 : : RTL_LOGFILE_CONTEXT_TRACE1( aTimeLog, "number of locales: %ld", nLocaleCount );
3527 : 36 : Locale const * const pLocales = xLoc.getConstArray();
3528 [ + - ]: 36 : NfCurrencyTable &rCurrencyTable = theCurrencyTable::get();
3529 [ + - ]: 36 : NfCurrencyTable &rLegacyOnlyCurrencyTable = theLegacyOnlyCurrencyTable::get();
3530 [ + - ]: 36 : NfInstalledLocales &rInstalledLocales = theInstalledLocales::get();
3531 : 36 : sal_uInt16 nLegacyOnlyCurrencyPos = 0;
3532 [ + + ]: 7128 : for ( sal_Int32 nLocale = 0; nLocale < nLocaleCount; nLocale++ )
3533 : : {
3534 : : LanguageType eLang = MsLangId::convertLocaleToLanguage(
3535 [ + - ]: 7092 : pLocales[nLocale]);
3536 [ + - ]: 7092 : rInstalledLocales.insert( eLang);
3537 [ + - ]: 7092 : pLocaleData->setLocale( pLocales[nLocale] );
3538 [ + - ]: 7092 : Sequence< Currency2 > aCurrSeq = pLocaleData->getAllCurrencies();
3539 : 7092 : sal_Int32 nCurrencyCount = aCurrSeq.getLength();
3540 : 7092 : Currency2 const * const pCurrencies = aCurrSeq.getConstArray();
3541 : :
3542 : : // one default currency for each locale, insert first so it is found first
3543 : : sal_Int32 nDefault;
3544 [ + - ]: 7488 : for ( nDefault = 0; nDefault < nCurrencyCount; nDefault++ )
3545 : : {
3546 [ + + ]: 7488 : if ( pCurrencies[nDefault].Default )
3547 : 7092 : break;
3548 : : }
3549 [ + - ]: 7092 : if ( nDefault < nCurrencyCount )
3550 [ + - ][ + - ]: 7092 : pEntry = new NfCurrencyEntry( pCurrencies[nDefault], *pLocaleData, eLang );
3551 : : else
3552 [ # # ][ # # ]: 0 : pEntry = new NfCurrencyEntry( *pLocaleData, eLang ); // first or ShellsAndPebbles
3553 : :
3554 [ + - ][ - + ]: 7092 : if (LocaleDataWrapper::areChecksEnabled())
3555 [ # # ]: 0 : lcl_CheckCurrencySymbolPosition( *pEntry );
3556 : :
3557 [ + - ][ + - ]: 7092 : rCurrencyTable.insert( rCurrencyTable.begin() + nCurrencyPos++, pEntry );
[ + - ]
3558 [ + - ][ - + ]: 7092 : if ( !nSystemCurrencyPosition && (aConfiguredCurrencyAbbrev.Len() ?
[ # # # # ]
[ - + ]
3559 [ # # ]: 0 : pEntry->GetBankSymbol() == aConfiguredCurrencyAbbrev &&
3560 : 0 : pEntry->GetLanguage() == eConfiguredCurrencyLanguage : false) )
3561 : 0 : nSystemCurrencyPosition = nCurrencyPos-1;
3562 [ + + + - ]: 7128 : if ( !nMatchingSystemCurrencyPosition &&
[ + + ]
3563 : 36 : pEntry->GetLanguage() == eSysLang )
3564 : 36 : nMatchingSystemCurrencyPosition = nCurrencyPos-1;
3565 : :
3566 : : // all remaining currencies for each locale
3567 [ + + ]: 7092 : if ( nCurrencyCount > 1 )
3568 : : {
3569 : : sal_Int32 nCurrency;
3570 [ + + ]: 8388 : for ( nCurrency = 0; nCurrency < nCurrencyCount; nCurrency++ )
3571 : : {
3572 [ + + ]: 5832 : if (pCurrencies[nCurrency].LegacyOnly)
3573 : : {
3574 [ + - ][ + - ]: 1332 : pEntry = new NfCurrencyEntry( pCurrencies[nCurrency], *pLocaleData, eLang );
3575 [ + - ][ + - ]: 1332 : rLegacyOnlyCurrencyTable.insert( rLegacyOnlyCurrencyTable.begin() + nLegacyOnlyCurrencyPos++, pEntry );
[ + - ]
3576 : : }
3577 [ + + ]: 4500 : else if ( nCurrency != nDefault )
3578 : : {
3579 [ + - ][ + - ]: 1944 : pEntry = new NfCurrencyEntry( pCurrencies[nCurrency], *pLocaleData, eLang );
3580 : : // no dupes
3581 : 1944 : bool bInsert = true;
3582 : 1944 : sal_uInt16 n = rCurrencyTable.size();
3583 : 1944 : sal_uInt16 aCurrencyIndex = 1; // skip first SYSTEM entry
3584 [ + + ]: 190548 : for ( sal_uInt16 j=1; j<n; j++ )
3585 : : {
3586 [ + - ][ + - ]: 188604 : if ( rCurrencyTable[aCurrencyIndex++] == *pEntry )
[ - + ]
3587 : : {
3588 : 0 : bInsert = false;
3589 : 0 : break; // for
3590 : : }
3591 : : }
3592 [ - + ]: 1944 : if ( !bInsert )
3593 [ # # ][ # # ]: 0 : delete pEntry;
3594 : : else
3595 : : {
3596 [ + - ][ + - ]: 1944 : rCurrencyTable.insert( rCurrencyTable.begin() + nCurrencyPos++, pEntry );
[ + - ]
3597 [ + - - + ]: 5832 : if ( !nSecondarySystemCurrencyPosition &&
[ # # ][ - + ]
3598 : 1944 : (aConfiguredCurrencyAbbrev.Len() ?
3599 [ # # ]: 0 : pEntry->GetBankSymbol() == aConfiguredCurrencyAbbrev :
3600 [ - + ]: 1944 : pEntry->GetLanguage() == eConfiguredCurrencyLanguage) )
3601 : 0 : nSecondarySystemCurrencyPosition = nCurrencyPos-1;
3602 [ - + # # ]: 1944 : if ( !nMatchingSystemCurrencyPosition &&
[ - + ]
3603 : 0 : pEntry->GetLanguage() == eSysLang )
3604 : 0 : nMatchingSystemCurrencyPosition = nCurrencyPos-1;
3605 : : }
3606 : : }
3607 : : }
3608 : : }
3609 [ + - ]: 7092 : }
3610 [ + - ]: 36 : if ( !nSystemCurrencyPosition )
3611 : 36 : nSystemCurrencyPosition = nSecondarySystemCurrencyPosition;
3612 [ - + ][ # # ]: 36 : if ((aConfiguredCurrencyAbbrev.Len() && !nSystemCurrencyPosition) &&
[ # # ][ - + ]
3613 [ # # ]: 0 : LocaleDataWrapper::areChecksEnabled())
3614 : : LocaleDataWrapper::outputCheckMessage(
3615 [ # # ]: 0 : "SvNumberFormatter::ImpInitCurrencyTable: configured currency not in I18N locale data.");
3616 : : // match SYSTEM if no configured currency found
3617 [ + - ]: 36 : if ( !nSystemCurrencyPosition )
3618 : 36 : nSystemCurrencyPosition = nMatchingSystemCurrencyPosition;
3619 [ + - ][ - + ]: 36 : if ((!aConfiguredCurrencyAbbrev.Len() && !nSystemCurrencyPosition) &&
[ # # ][ - + ]
3620 [ # # ]: 0 : LocaleDataWrapper::areChecksEnabled())
3621 : : LocaleDataWrapper::outputCheckMessage(
3622 [ # # ]: 0 : "SvNumberFormatter::ImpInitCurrencyTable: system currency not in I18N locale data.");
3623 [ + - ][ + - ]: 36 : delete pLocaleData;
3624 : : SvtSysLocaleOptions::SetCurrencyChangeLink(
3625 [ + - ][ + - ]: 36 : STATIC_LINK( NULL, SvNumberFormatter, CurrencyChangeLink ) );
3626 : 36 : bInitializing = false;
3627 [ + - ][ + - ]: 36 : bCurrencyTableInitialized = true;
3628 : : }
3629 : :
3630 : :
3631 : 97 : sal_uInt16 SvNumberFormatter::GetCurrencyFormatStrings( NfWSStringsDtor& rStrArr,
3632 : : const NfCurrencyEntry& rCurr, bool bBank ) const
3633 : : {
3634 : : rtl::OUString aRed = rtl::OUStringBuffer().
3635 [ + - ]: 194 : append('[').
3636 [ + - ][ + - ]: 291 : append(pFormatScanner->GetRedString()).
[ + - ]
3637 [ + - ][ + - ]: 97 : append(']').makeStringAndClear();
3638 : :
3639 : 97 : sal_uInt16 nDefault = 0;
3640 [ - + ]: 97 : if ( bBank )
3641 : : {
3642 : : // Only bank symbols.
3643 [ # # ][ # # ]: 0 : String aPositiveBank, aNegativeBank;
3644 [ # # ]: 0 : rCurr.BuildPositiveFormatString( aPositiveBank, true, *xLocaleData, 1 );
3645 [ # # ]: 0 : rCurr.BuildNegativeFormatString( aNegativeBank, true, *xLocaleData, 1 );
3646 : :
3647 [ # # ][ # # ]: 0 : ::rtl::OUStringBuffer format1(aPositiveBank);
3648 [ # # ]: 0 : format1.append(';');
3649 [ # # ][ # # ]: 0 : format1.append(aNegativeBank);
3650 [ # # ][ # # ]: 0 : rStrArr.push_back(format1.makeStringAndClear());
3651 : :
3652 [ # # ][ # # ]: 0 : ::rtl::OUStringBuffer format2(aPositiveBank);
3653 [ # # ]: 0 : format2.append(';');
3654 : :
3655 [ # # ]: 0 : format2.append(aRed);
3656 : :
3657 [ # # ][ # # ]: 0 : format2.append(aNegativeBank);
3658 [ # # ][ # # ]: 0 : rStrArr.push_back(format2.makeStringAndClear());
3659 : :
3660 [ # # ][ # # ]: 0 : nDefault = rStrArr.size() - 1;
3661 : : }
3662 : : else
3663 : : {
3664 : : // Mixed formats like in SvNumberFormatter::ImpGenerateFormats() but no
3665 : : // duplicates if no decimals in currency.
3666 [ + - ][ + - ]: 97 : String aPositive, aNegative, aPositiveNoDec, aNegativeNoDec,
[ + - ][ + - ]
3667 [ + - ][ + - ]: 97 : aPositiveDashed, aNegativeDashed;
3668 : :
3669 [ + - ]: 97 : rCurr.BuildPositiveFormatString( aPositive, false, *xLocaleData, 1 );
3670 [ + - ]: 97 : rCurr.BuildNegativeFormatString( aNegative, false, *xLocaleData, 1 );
3671 : 97 : ::rtl::OUStringBuffer format1;
3672 : 97 : ::rtl::OUStringBuffer format2;
3673 : 97 : ::rtl::OUStringBuffer format3;
3674 : 97 : ::rtl::OUStringBuffer format4;
3675 : 97 : ::rtl::OUStringBuffer format5;
3676 [ + - ]: 97 : if ( rCurr.GetDigits() )
3677 : : {
3678 [ + - ]: 97 : rCurr.BuildPositiveFormatString( aPositiveNoDec, false, *xLocaleData, 0 );
3679 [ + - ]: 97 : rCurr.BuildNegativeFormatString( aNegativeNoDec, false, *xLocaleData, 0 );
3680 [ + - ]: 97 : rCurr.BuildPositiveFormatString( aPositiveDashed, false, *xLocaleData, 2 );
3681 [ + - ]: 97 : rCurr.BuildNegativeFormatString( aNegativeDashed, false, *xLocaleData, 2 );
3682 : :
3683 [ + - ][ + - ]: 97 : format1.append(aPositiveNoDec);
3684 [ + - ]: 97 : format1.append(';');
3685 [ + - ][ + - ]: 97 : format1.append(aNegativeNoDec);
3686 : :
3687 [ + - ][ + - ]: 97 : format3.append(aPositiveNoDec);
3688 [ + - ]: 97 : format3.append(';');
3689 [ + - ]: 97 : format3.append(aRed);
3690 [ + - ][ + - ]: 97 : format3.append(aNegativeNoDec);
3691 : :
3692 [ + - ][ + - ]: 97 : format5.append(aPositiveDashed);
3693 [ + - ]: 97 : format5.append(';');
3694 [ + - ]: 97 : format5.append(aRed);
3695 [ + - ][ + - ]: 97 : format5.append(aNegativeDashed);
3696 : : }
3697 : :
3698 [ + - ][ + - ]: 97 : format2.append(aPositive);
3699 [ + - ]: 97 : format2.append(';');
3700 [ + - ][ + - ]: 97 : format2.append(aNegative);
3701 : :
3702 [ + - ][ + - ]: 97 : format4.append(aPositive);
3703 [ + - ]: 97 : format4.append(';');
3704 [ + - ]: 97 : format4.append(aRed);
3705 [ + - ][ + - ]: 97 : format4.append(aNegative);
3706 : :
3707 [ + - ]: 97 : if (rCurr.GetDigits()) {
3708 [ + - ][ + - ]: 97 : rStrArr.push_back(format1.makeStringAndClear());
3709 : : }
3710 [ + - ][ + - ]: 97 : rStrArr.push_back(format2.makeStringAndClear());
3711 [ + - ]: 97 : if (rCurr.GetDigits()) {
3712 [ + - ][ + - ]: 97 : rStrArr.push_back(format3.makeStringAndClear());
3713 : : }
3714 [ + - ][ + - ]: 97 : rStrArr.push_back(format4.makeStringAndClear());
3715 : 97 : nDefault = rStrArr.size() - 1;
3716 [ + - ]: 97 : if (rCurr.GetDigits()) {
3717 [ + - ][ + - ]: 97 : rStrArr.push_back(format5.makeStringAndClear());
3718 [ + - ][ + - ]: 97 : }
[ + - ][ + - ]
[ + - ][ + - ]
3719 : : }
3720 : 97 : return nDefault;
3721 : : }
3722 : :
3723 : :
3724 : : //--- NfCurrencyEntry ----------------------------------------------------
3725 : :
3726 : :
3727 [ + - ]: 36 : NfCurrencyEntry::NfCurrencyEntry( const LocaleDataWrapper& rLocaleData, LanguageType eLang )
3728 : : {
3729 [ + - ][ + - ]: 36 : aSymbol = rLocaleData.getCurrSymbol();
3730 [ + - ][ + - ]: 36 : aBankSymbol = rLocaleData.getCurrBankSymbol();
3731 : 36 : eLanguage = eLang;
3732 [ + - ]: 36 : nPositiveFormat = rLocaleData.getCurrPositiveFormat();
3733 [ + - ]: 36 : nNegativeFormat = rLocaleData.getCurrNegativeFormat();
3734 [ + - ]: 36 : nDigits = rLocaleData.getCurrDigits();
3735 : 36 : cZeroChar = rLocaleData.getCurrZeroChar();
3736 : 36 : }
3737 : :
3738 : :
3739 : 10368 : NfCurrencyEntry::NfCurrencyEntry( const ::com::sun::star::i18n::Currency & rCurr,
3740 [ + - ]: 10368 : const LocaleDataWrapper& rLocaleData, LanguageType eLang )
3741 : : {
3742 [ + - ]: 10368 : aSymbol = rCurr.Symbol;
3743 [ + - ]: 10368 : aBankSymbol = rCurr.BankSymbol;
3744 : 10368 : eLanguage = eLang;
3745 [ + - ]: 10368 : nPositiveFormat = rLocaleData.getCurrPositiveFormat();
3746 [ + - ]: 10368 : nNegativeFormat = rLocaleData.getCurrNegativeFormat();
3747 : 10368 : nDigits = rCurr.DecimalPlaces;
3748 : 10368 : cZeroChar = rLocaleData.getCurrZeroChar();
3749 : 10368 : }
3750 : :
3751 : :
3752 : 188604 : bool NfCurrencyEntry::operator==( const NfCurrencyEntry& r ) const
3753 : : {
3754 : 188604 : return aSymbol == r.aSymbol
3755 : 4824 : && aBankSymbol == r.aBankSymbol
3756 [ - + ]: 193428 : && eLanguage == r.eLanguage
[ + + + + ]
3757 : : ;
3758 : : }
3759 : :
3760 : 642 : void NfCurrencyEntry::BuildSymbolString( String& rStr, bool bBank,
3761 : : bool bWithoutExtension ) const
3762 : : {
3763 : 642 : rStr = '[';
3764 : 642 : rStr += '$';
3765 [ - + ]: 642 : if ( bBank )
3766 : 0 : rStr += aBankSymbol;
3767 : : else
3768 : : {
3769 [ + - ][ - + ]: 642 : if ( aSymbol.Search( '-' ) != STRING_NOTFOUND || aSymbol.Search( ']' ) != STRING_NOTFOUND )
[ - + ]
3770 : : {
3771 : 0 : rStr += '"';
3772 : 0 : rStr += aSymbol;
3773 : 0 : rStr += '"';
3774 : : }
3775 : : else
3776 : 642 : rStr += aSymbol;
3777 [ + - ][ + - ]: 642 : if ( !bWithoutExtension && eLanguage != LANGUAGE_DONTKNOW && eLanguage != LANGUAGE_SYSTEM )
[ + - ]
3778 : : {
3779 : 642 : rStr += '-';
3780 [ + - ][ + - ]: 642 : rStr += String::CreateFromInt32( sal_Int32( eLanguage ), 16 ).ToUpperAscii();
3781 : : }
3782 : : }
3783 : 642 : rStr += ']';
3784 : 642 : }
3785 : :
3786 : :
3787 : 582 : void NfCurrencyEntry::Impl_BuildFormatStringNumChars( String& rStr,
3788 : : const LocaleDataWrapper& rLoc, sal_uInt16 nDecimalFormat ) const
3789 : : {
3790 : 582 : rStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "###0" ) );
3791 [ + - ]: 582 : rStr.Insert( rLoc.getNumThousandSep(), 1 );
3792 [ + - ][ + + ]: 582 : if ( nDecimalFormat && nDigits )
3793 : : {
3794 : 388 : rStr += rLoc.getNumDecimalSep();
3795 [ + + ]: 388 : rStr.Expand( rStr.Len() + nDigits, (nDecimalFormat == 2 ? '-' : cZeroChar) );
3796 : : }
3797 : 582 : }
3798 : :
3799 : :
3800 : 291 : void NfCurrencyEntry::BuildPositiveFormatString( String& rStr, bool bBank,
3801 : : const LocaleDataWrapper& rLoc, sal_uInt16 nDecimalFormat ) const
3802 : : {
3803 : 291 : Impl_BuildFormatStringNumChars( rStr, rLoc, nDecimalFormat );
3804 : : sal_uInt16 nPosiForm = NfCurrencyEntry::GetEffectivePositiveFormat(
3805 : 291 : rLoc.getCurrPositiveFormat(), nPositiveFormat, bBank );
3806 : 291 : CompletePositiveFormatString( rStr, bBank, nPosiForm );
3807 : 291 : }
3808 : :
3809 : :
3810 : 291 : void NfCurrencyEntry::BuildNegativeFormatString( String& rStr, bool bBank,
3811 : : const LocaleDataWrapper& rLoc, sal_uInt16 nDecimalFormat ) const
3812 : : {
3813 : 291 : Impl_BuildFormatStringNumChars( rStr, rLoc, nDecimalFormat );
3814 : : sal_uInt16 nNegaForm = NfCurrencyEntry::GetEffectiveNegativeFormat(
3815 : 291 : rLoc.getCurrNegativeFormat(), nNegativeFormat, bBank );
3816 : 291 : CompleteNegativeFormatString( rStr, bBank, nNegaForm );
3817 : 291 : }
3818 : :
3819 : :
3820 : 311 : void NfCurrencyEntry::CompletePositiveFormatString( String& rStr, bool bBank,
3821 : : sal_uInt16 nPosiForm ) const
3822 : : {
3823 [ + - ]: 311 : String aSymStr;
3824 [ + - ]: 311 : BuildSymbolString( aSymStr, bBank );
3825 [ + - ][ + - ]: 311 : NfCurrencyEntry::CompletePositiveFormatString( rStr, aSymStr, nPosiForm );
3826 : 311 : }
3827 : :
3828 : :
3829 : 311 : void NfCurrencyEntry::CompleteNegativeFormatString( String& rStr, bool bBank,
3830 : : sal_uInt16 nNegaForm ) const
3831 : : {
3832 [ + - ]: 311 : String aSymStr;
3833 [ + - ]: 311 : BuildSymbolString( aSymStr, bBank );
3834 [ + - ][ + - ]: 311 : NfCurrencyEntry::CompleteNegativeFormatString( rStr, aSymStr, nNegaForm );
3835 : 311 : }
3836 : :
3837 : :
3838 : : // static
3839 : 371 : void NfCurrencyEntry::CompletePositiveFormatString( String& rStr,
3840 : : const String& rSymStr, sal_uInt16 nPositiveFormat )
3841 : : {
3842 [ + - - + : 371 : switch( nPositiveFormat )
- ]
3843 : : {
3844 : : case 0: // $1
3845 : 311 : rStr.Insert( rSymStr , 0 );
3846 : 311 : break;
3847 : : case 1: // 1$
3848 : 0 : rStr += rSymStr;
3849 : 0 : break;
3850 : : case 2: // $ 1
3851 : : {
3852 : 0 : rStr.Insert( ' ', 0 );
3853 : 0 : rStr.Insert( rSymStr, 0 );
3854 : : }
3855 : 0 : break;
3856 : : case 3: // 1 $
3857 : : {
3858 : 60 : rStr += ' ';
3859 : 60 : rStr += rSymStr;
3860 : : }
3861 : 60 : break;
3862 : : default:
3863 : : OSL_FAIL("NfCurrencyEntry::CompletePositiveFormatString: unknown option");
3864 : 0 : break;
3865 : : }
3866 : 371 : }
3867 : :
3868 : :
3869 : : // static
3870 : 371 : void NfCurrencyEntry::CompleteNegativeFormatString( String& rStr,
3871 : : const String& rSymStr, sal_uInt16 nNegativeFormat )
3872 : : {
3873 [ - + - - : 371 : switch( nNegativeFormat )
- - - - +
- - - - -
- - - ]
3874 : : {
3875 : : case 0: // ($1)
3876 : : {
3877 : 0 : rStr.Insert( rSymStr, 0);
3878 : 0 : rStr.Insert('(',0);
3879 : 0 : rStr += ')';
3880 : : }
3881 : 0 : break;
3882 : : case 1: // -$1
3883 : : {
3884 : 311 : rStr.Insert( rSymStr, 0);
3885 : 311 : rStr.Insert('-',0);
3886 : : }
3887 : 311 : break;
3888 : : case 2: // $-1
3889 : : {
3890 : 0 : rStr.Insert('-',0);
3891 : 0 : rStr.Insert( rSymStr, 0);
3892 : : }
3893 : 0 : break;
3894 : : case 3: // $1-
3895 : : {
3896 : 0 : rStr.Insert( rSymStr, 0);
3897 : 0 : rStr += '-';
3898 : : }
3899 : 0 : break;
3900 : : case 4: // (1$)
3901 : : {
3902 : 0 : rStr.Insert('(',0);
3903 : 0 : rStr += rSymStr;
3904 : 0 : rStr += ')';
3905 : : }
3906 : 0 : break;
3907 : : case 5: // -1$
3908 : : {
3909 : 0 : rStr += rSymStr;
3910 : 0 : rStr.Insert('-',0);
3911 : : }
3912 : 0 : break;
3913 : : case 6: // 1-$
3914 : : {
3915 : 0 : rStr += '-';
3916 : 0 : rStr += rSymStr;
3917 : : }
3918 : 0 : break;
3919 : : case 7: // 1$-
3920 : : {
3921 : 0 : rStr += rSymStr;
3922 : 0 : rStr += '-';
3923 : : }
3924 : 0 : break;
3925 : : case 8: // -1 $
3926 : : {
3927 : 60 : rStr += ' ';
3928 : 60 : rStr += rSymStr;
3929 : 60 : rStr.Insert('-',0);
3930 : : }
3931 : 60 : break;
3932 : : case 9: // -$ 1
3933 : : {
3934 : 0 : rStr.Insert(' ',0);
3935 : 0 : rStr.Insert( rSymStr, 0);
3936 : 0 : rStr.Insert('-',0);
3937 : : }
3938 : 0 : break;
3939 : : case 10: // 1 $-
3940 : : {
3941 : 0 : rStr += ' ';
3942 : 0 : rStr += rSymStr;
3943 : 0 : rStr += '-';
3944 : : }
3945 : 0 : break;
3946 : : case 11: // $ -1
3947 : : {
3948 [ # # ]: 0 : String aTmp( rSymStr );
3949 [ # # ]: 0 : aTmp += ' ';
3950 [ # # ]: 0 : aTmp += '-';
3951 [ # # ][ # # ]: 0 : rStr.Insert( aTmp, 0 );
3952 : : }
3953 : 0 : break;
3954 : : case 12 : // $ 1-
3955 : : {
3956 : 0 : rStr.Insert(' ', 0);
3957 : 0 : rStr.Insert( rSymStr, 0);
3958 : 0 : rStr += '-';
3959 : : }
3960 : 0 : break;
3961 : : case 13 : // 1- $
3962 : : {
3963 : 0 : rStr += '-';
3964 : 0 : rStr += ' ';
3965 : 0 : rStr += rSymStr;
3966 : : }
3967 : 0 : break;
3968 : : case 14 : // ($ 1)
3969 : : {
3970 : 0 : rStr.Insert(' ',0);
3971 : 0 : rStr.Insert( rSymStr, 0);
3972 : 0 : rStr.Insert('(',0);
3973 : 0 : rStr += ')';
3974 : : }
3975 : 0 : break;
3976 : : case 15 : // (1 $)
3977 : : {
3978 : 0 : rStr.Insert('(',0);
3979 : 0 : rStr += ' ';
3980 : 0 : rStr += rSymStr;
3981 : 0 : rStr += ')';
3982 : : }
3983 : 0 : break;
3984 : : default:
3985 : : OSL_FAIL("NfCurrencyEntry::CompleteNegativeFormatString: unknown option");
3986 : 0 : break;
3987 : : }
3988 : 371 : }
3989 : :
3990 : :
3991 : : // static
3992 : 371 : sal_uInt16 NfCurrencyEntry::GetEffectivePositiveFormat(
3993 : : sal_uInt16 nIntlFormat, sal_uInt16 nCurrFormat, bool bBank )
3994 : : {
3995 [ + + ]: 371 : if ( bBank )
3996 : : {
3997 : : #if NF_BANKSYMBOL_FIX_POSITION
3998 : : (void) nIntlFormat; // avoid warnings
3999 : 60 : return 3;
4000 : : #else
4001 : : switch ( nIntlFormat )
4002 : : {
4003 : : case 0: // $1
4004 : : nIntlFormat = 2; // $ 1
4005 : : break;
4006 : : case 1: // 1$
4007 : : nIntlFormat = 3; // 1 $
4008 : : break;
4009 : : case 2: // $ 1
4010 : : break;
4011 : : case 3: // 1 $
4012 : : break;
4013 : : default:
4014 : : OSL_FAIL("NfCurrencyEntry::GetEffectivePositiveFormat: unknown option");
4015 : : break;
4016 : : }
4017 : : return nIntlFormat;
4018 : : #endif
4019 : : }
4020 : : else
4021 : 371 : return nCurrFormat;
4022 : : }
4023 : :
4024 : :
4025 : : //! Call this only if nCurrFormat is really with parentheses!
4026 : 0 : sal_uInt16 lcl_MergeNegativeParenthesisFormat( sal_uInt16 nIntlFormat, sal_uInt16 nCurrFormat )
4027 : : {
4028 : 0 : short nSign = 0; // -1:=Klammer 0:=links, 1:=mitte, 2:=rechts
4029 [ # # # # : 0 : switch ( nIntlFormat )
# ]
4030 : : {
4031 : : case 0: // ($1)
4032 : : case 4: // (1$)
4033 : : case 14 : // ($ 1)
4034 : : case 15 : // (1 $)
4035 : 0 : return nCurrFormat;
4036 : : case 1: // -$1
4037 : : case 5: // -1$
4038 : : case 8: // -1 $
4039 : : case 9: // -$ 1
4040 : 0 : nSign = 0;
4041 : 0 : break;
4042 : : case 2: // $-1
4043 : : case 6: // 1-$
4044 : : case 11 : // $ -1
4045 : : case 13 : // 1- $
4046 : 0 : nSign = 1;
4047 : 0 : break;
4048 : : case 3: // $1-
4049 : : case 7: // 1$-
4050 : : case 10: // 1 $-
4051 : : case 12 : // $ 1-
4052 : 0 : nSign = 2;
4053 : 0 : break;
4054 : : default:
4055 : : OSL_FAIL("lcl_MergeNegativeParenthesisFormat: unknown option");
4056 : 0 : break;
4057 : : }
4058 : :
4059 [ # # # # : 0 : switch ( nCurrFormat )
# ]
4060 : : {
4061 : : case 0: // ($1)
4062 [ # # # # ]: 0 : switch ( nSign )
4063 : : {
4064 : : case 0:
4065 : 0 : return 1; // -$1
4066 : : case 1:
4067 : 0 : return 2; // $-1
4068 : : case 2:
4069 : 0 : return 3; // $1-
4070 : : }
4071 : 0 : break;
4072 : : case 4: // (1$)
4073 [ # # # # ]: 0 : switch ( nSign )
4074 : : {
4075 : : case 0:
4076 : 0 : return 5; // -1$
4077 : : case 1:
4078 : 0 : return 6; // 1-$
4079 : : case 2:
4080 : 0 : return 7; // 1$-
4081 : : }
4082 : 0 : break;
4083 : : case 14 : // ($ 1)
4084 [ # # # # ]: 0 : switch ( nSign )
4085 : : {
4086 : : case 0:
4087 : 0 : return 9; // -$ 1
4088 : : case 1:
4089 : 0 : return 11; // $ -1
4090 : : case 2:
4091 : 0 : return 12; // $ 1-
4092 : : }
4093 : 0 : break;
4094 : : case 15 : // (1 $)
4095 [ # # # # ]: 0 : switch ( nSign )
4096 : : {
4097 : : case 0:
4098 : 0 : return 8; // -1 $
4099 : : case 1:
4100 : 0 : return 13; // 1- $
4101 : : case 2:
4102 : 0 : return 10; // 1 $-
4103 : : }
4104 : 0 : break;
4105 : : }
4106 : 0 : return nCurrFormat;
4107 : : }
4108 : :
4109 : :
4110 : : // static
4111 : 371 : sal_uInt16 NfCurrencyEntry::GetEffectiveNegativeFormat( sal_uInt16 nIntlFormat,
4112 : : sal_uInt16 nCurrFormat, bool bBank )
4113 : : {
4114 [ + + ]: 371 : if ( bBank )
4115 : : {
4116 : : #if NF_BANKSYMBOL_FIX_POSITION
4117 : 60 : return 8;
4118 : : #else
4119 : : switch ( nIntlFormat )
4120 : : {
4121 : : case 0: // ($1)
4122 : : // nIntlFormat = 14; // ($ 1)
4123 : : nIntlFormat = 9; // -$ 1
4124 : : break;
4125 : : case 1: // -$1
4126 : : nIntlFormat = 9; // -$ 1
4127 : : break;
4128 : : case 2: // $-1
4129 : : nIntlFormat = 11; // $ -1
4130 : : break;
4131 : : case 3: // $1-
4132 : : nIntlFormat = 12; // $ 1-
4133 : : break;
4134 : : case 4: // (1$)
4135 : : // nIntlFormat = 15; // (1 $)
4136 : : nIntlFormat = 8; // -1 $
4137 : : break;
4138 : : case 5: // -1$
4139 : : nIntlFormat = 8; // -1 $
4140 : : break;
4141 : : case 6: // 1-$
4142 : : nIntlFormat = 13; // 1- $
4143 : : break;
4144 : : case 7: // 1$-
4145 : : nIntlFormat = 10; // 1 $-
4146 : : break;
4147 : : case 8: // -1 $
4148 : : break;
4149 : : case 9: // -$ 1
4150 : : break;
4151 : : case 10: // 1 $-
4152 : : break;
4153 : : case 11: // $ -1
4154 : : break;
4155 : : case 12 : // $ 1-
4156 : : break;
4157 : : case 13 : // 1- $
4158 : : break;
4159 : : case 14 : // ($ 1)
4160 : : // nIntlFormat = 14; // ($ 1)
4161 : : nIntlFormat = 9; // -$ 1
4162 : : break;
4163 : : case 15 : // (1 $)
4164 : : // nIntlFormat = 15; // (1 $)
4165 : : nIntlFormat = 8; // -1 $
4166 : : break;
4167 : : default:
4168 : : OSL_FAIL("NfCurrencyEntry::GetEffectiveNegativeFormat: unknown option");
4169 : : break;
4170 : : }
4171 : : #endif
4172 : : }
4173 [ - + ]: 311 : else if ( nIntlFormat != nCurrFormat )
4174 : : {
4175 [ # # # # : 0 : switch ( nCurrFormat )
# # # # #
# # # # #
# # # ]
4176 : : {
4177 : : case 0: // ($1)
4178 : : nIntlFormat = lcl_MergeNegativeParenthesisFormat(
4179 : 0 : nIntlFormat, nCurrFormat );
4180 : 0 : break;
4181 : : case 1: // -$1
4182 : 0 : nIntlFormat = nCurrFormat;
4183 : 0 : break;
4184 : : case 2: // $-1
4185 : 0 : nIntlFormat = nCurrFormat;
4186 : 0 : break;
4187 : : case 3: // $1-
4188 : 0 : nIntlFormat = nCurrFormat;
4189 : 0 : break;
4190 : : case 4: // (1$)
4191 : : nIntlFormat = lcl_MergeNegativeParenthesisFormat(
4192 : 0 : nIntlFormat, nCurrFormat );
4193 : 0 : break;
4194 : : case 5: // -1$
4195 : 0 : nIntlFormat = nCurrFormat;
4196 : 0 : break;
4197 : : case 6: // 1-$
4198 : 0 : nIntlFormat = nCurrFormat;
4199 : 0 : break;
4200 : : case 7: // 1$-
4201 : 0 : nIntlFormat = nCurrFormat;
4202 : 0 : break;
4203 : : case 8: // -1 $
4204 : 0 : nIntlFormat = nCurrFormat;
4205 : 0 : break;
4206 : : case 9: // -$ 1
4207 : 0 : nIntlFormat = nCurrFormat;
4208 : 0 : break;
4209 : : case 10: // 1 $-
4210 : 0 : nIntlFormat = nCurrFormat;
4211 : 0 : break;
4212 : : case 11: // $ -1
4213 : 0 : nIntlFormat = nCurrFormat;
4214 : 0 : break;
4215 : : case 12 : // $ 1-
4216 : 0 : nIntlFormat = nCurrFormat;
4217 : 0 : break;
4218 : : case 13 : // 1- $
4219 : 0 : nIntlFormat = nCurrFormat;
4220 : 0 : break;
4221 : : case 14 : // ($ 1)
4222 : : nIntlFormat = lcl_MergeNegativeParenthesisFormat(
4223 : 0 : nIntlFormat, nCurrFormat );
4224 : 0 : break;
4225 : : case 15 : // (1 $)
4226 : : nIntlFormat = lcl_MergeNegativeParenthesisFormat(
4227 : 0 : nIntlFormat, nCurrFormat );
4228 : 0 : break;
4229 : : default:
4230 : : OSL_FAIL("NfCurrencyEntry::GetEffectiveNegativeFormat: unknown option");
4231 : 0 : break;
4232 : : }
4233 : : }
4234 : 371 : return nIntlFormat;
4235 : : }
4236 : :
4237 : :
4238 : : // we only support default encodings here
4239 : : // static
4240 : 0 : sal_Char NfCurrencyEntry::GetEuroSymbol( rtl_TextEncoding eTextEncoding )
4241 : : {
4242 [ # # # # : 0 : switch ( eTextEncoding )
# ]
4243 : : {
4244 : : case RTL_TEXTENCODING_MS_1252 : // WNT Ansi
4245 : : case RTL_TEXTENCODING_ISO_8859_1 : // UNX for use with TrueType fonts
4246 : 0 : return '\x80';
4247 : : case RTL_TEXTENCODING_ISO_8859_15 : // UNX real
4248 : 0 : return '\xA4';
4249 : : case RTL_TEXTENCODING_IBM_850 : // OS2
4250 : 0 : return '\xD5';
4251 : : case RTL_TEXTENCODING_APPLE_ROMAN : // MAC
4252 : 0 : return '\xDB';
4253 : : default: // default system
4254 : : #if WNT
4255 : : return '\x80';
4256 : : #elif UNX
4257 : : // return '\xA4'; // #56121# 0xA4 would be correct for iso-8859-15
4258 : 0 : return '\x80'; // but Windows code for the converted TrueType fonts
4259 : : #else
4260 : : #error EuroSymbol is what?
4261 : : return '\x80';
4262 : : #endif
4263 : : }
4264 : : }
4265 : :
4266 : :
4267 : :
4268 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|