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