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