xref: /AOO41X/main/svl/source/numbers/zforscan.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_svl.hxx"
30*cdf0e10cSrcweir #ifndef GCC
31*cdf0e10cSrcweir #endif
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include <stdlib.h>
34*cdf0e10cSrcweir #include <tools/debug.hxx>
35*cdf0e10cSrcweir #include <i18npool/mslangid.hxx>
36*cdf0e10cSrcweir #include <unotools/charclass.hxx>
37*cdf0e10cSrcweir #include <unotools/localedatawrapper.hxx>
38*cdf0e10cSrcweir #include <unotools/numberformatcodewrapper.hxx>
39*cdf0e10cSrcweir #include <rtl/instance.hxx>
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir #include <svl/zforlist.hxx>
42*cdf0e10cSrcweir #include <svl/zformat.hxx>
43*cdf0e10cSrcweir #include <unotools/digitgroupingiterator.hxx>
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir #define _ZFORSCAN_CXX
46*cdf0e10cSrcweir #include "zforscan.hxx"
47*cdf0e10cSrcweir #undef _ZFORSCAN_CXX
48*cdf0e10cSrcweir #include <svl/nfsymbol.hxx>
49*cdf0e10cSrcweir using namespace svt;
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir const sal_Unicode cNonBreakingSpace = 0xA0;
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir namespace
54*cdf0e10cSrcweir {
55*cdf0e10cSrcweir     struct ImplEnglishColors
56*cdf0e10cSrcweir     {
57*cdf0e10cSrcweir         const String* operator()()
58*cdf0e10cSrcweir         {
59*cdf0e10cSrcweir             static const String aEnglishColors[NF_MAX_DEFAULT_COLORS] =
60*cdf0e10cSrcweir             {
61*cdf0e10cSrcweir                 String( RTL_CONSTASCII_USTRINGPARAM( "BLACK" ) ),
62*cdf0e10cSrcweir                 String( RTL_CONSTASCII_USTRINGPARAM( "BLUE" ) ),
63*cdf0e10cSrcweir                 String( RTL_CONSTASCII_USTRINGPARAM( "GREEN" ) ),
64*cdf0e10cSrcweir                 String( RTL_CONSTASCII_USTRINGPARAM( "CYAN" ) ),
65*cdf0e10cSrcweir                 String( RTL_CONSTASCII_USTRINGPARAM( "RED" ) ),
66*cdf0e10cSrcweir                 String( RTL_CONSTASCII_USTRINGPARAM( "MAGENTA" ) ),
67*cdf0e10cSrcweir                 String( RTL_CONSTASCII_USTRINGPARAM( "BROWN" ) ),
68*cdf0e10cSrcweir                 String( RTL_CONSTASCII_USTRINGPARAM( "GREY" ) ),
69*cdf0e10cSrcweir                 String( RTL_CONSTASCII_USTRINGPARAM( "YELLOW" ) ),
70*cdf0e10cSrcweir                 String( RTL_CONSTASCII_USTRINGPARAM( "WHITE" ) )
71*cdf0e10cSrcweir             };
72*cdf0e10cSrcweir             return &aEnglishColors[0];
73*cdf0e10cSrcweir         }
74*cdf0e10cSrcweir     };
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir     struct theEnglishColors
77*cdf0e10cSrcweir             : public rtl::StaticAggregate< const String, ImplEnglishColors> {};
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir }
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir ImpSvNumberformatScan::ImpSvNumberformatScan( SvNumberFormatter* pFormatterP )
82*cdf0e10cSrcweir {
83*cdf0e10cSrcweir 	pFormatter = pFormatterP;
84*cdf0e10cSrcweir 	bConvertMode = sal_False;
85*cdf0e10cSrcweir 	//! All keywords MUST be UPPERCASE!
86*cdf0e10cSrcweir 	sKeyword[NF_KEY_E].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"E" ) );		// Exponent
87*cdf0e10cSrcweir 	sKeyword[NF_KEY_AMPM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"AM/PM" ) );	// AM/PM
88*cdf0e10cSrcweir 	sKeyword[NF_KEY_AP].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"A/P" ) );		// AM/PM short
89*cdf0e10cSrcweir 	sKeyword[NF_KEY_MI].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"M" ) );		// Minute
90*cdf0e10cSrcweir 	sKeyword[NF_KEY_MMI].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"MM" ) );		// Minute 02
91*cdf0e10cSrcweir 	sKeyword[NF_KEY_S].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"S" ) );		// Second
92*cdf0e10cSrcweir 	sKeyword[NF_KEY_SS].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"SS" ) );		// Second 02
93*cdf0e10cSrcweir 	sKeyword[NF_KEY_Q].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"Q" ) );		// Quarter short 'Q'
94*cdf0e10cSrcweir 	sKeyword[NF_KEY_QQ].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"QQ" ) );		// Quarter long
95*cdf0e10cSrcweir 	sKeyword[NF_KEY_NN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"NN" ) );		// Day of week short
96*cdf0e10cSrcweir 	sKeyword[NF_KEY_NNN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"NNN" ) );		// Day of week long
97*cdf0e10cSrcweir 	sKeyword[NF_KEY_NNNN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"NNNN" ) );		// Day of week long incl. separator
98*cdf0e10cSrcweir 	sKeyword[NF_KEY_WW].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"WW" ) );		// Week of year
99*cdf0e10cSrcweir 	sKeyword[NF_KEY_CCC].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"CCC" ) );		// Currency abbreviation
100*cdf0e10cSrcweir     bKeywordsNeedInit = sal_True;   // locale dependent keywords
101*cdf0e10cSrcweir     bCompatCurNeedInit = sal_True;  // locale dependent compatibility currency strings
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir 	StandardColor[0]  =  Color(COL_BLACK);
104*cdf0e10cSrcweir 	StandardColor[1]  =  Color(COL_LIGHTBLUE);
105*cdf0e10cSrcweir 	StandardColor[2]  =  Color(COL_LIGHTGREEN);
106*cdf0e10cSrcweir 	StandardColor[3]  =  Color(COL_LIGHTCYAN);
107*cdf0e10cSrcweir 	StandardColor[4]  =  Color(COL_LIGHTRED);
108*cdf0e10cSrcweir 	StandardColor[5]  =  Color(COL_LIGHTMAGENTA);
109*cdf0e10cSrcweir 	StandardColor[6]  =  Color(COL_BROWN);
110*cdf0e10cSrcweir 	StandardColor[7]  =  Color(COL_GRAY);
111*cdf0e10cSrcweir 	StandardColor[8]  =  Color(COL_YELLOW);
112*cdf0e10cSrcweir 	StandardColor[9]  =  Color(COL_WHITE);
113*cdf0e10cSrcweir 
114*cdf0e10cSrcweir 	pNullDate = new Date(30,12,1899);
115*cdf0e10cSrcweir 	nStandardPrec = 2;
116*cdf0e10cSrcweir 
117*cdf0e10cSrcweir 	sErrStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "###" ) );
118*cdf0e10cSrcweir 	Reset();
119*cdf0e10cSrcweir }
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir ImpSvNumberformatScan::~ImpSvNumberformatScan()
122*cdf0e10cSrcweir {
123*cdf0e10cSrcweir 	delete pNullDate;
124*cdf0e10cSrcweir 	Reset();
125*cdf0e10cSrcweir }
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir 
128*cdf0e10cSrcweir void ImpSvNumberformatScan::ChangeIntl()
129*cdf0e10cSrcweir {
130*cdf0e10cSrcweir     bKeywordsNeedInit = sal_True;
131*cdf0e10cSrcweir     bCompatCurNeedInit = sal_True;
132*cdf0e10cSrcweir     // may be initialized by InitSpecialKeyword()
133*cdf0e10cSrcweir     sKeyword[NF_KEY_TRUE].Erase();
134*cdf0e10cSrcweir     sKeyword[NF_KEY_FALSE].Erase();
135*cdf0e10cSrcweir }
136*cdf0e10cSrcweir 
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir void ImpSvNumberformatScan::InitSpecialKeyword( NfKeywordIndex eIdx ) const
139*cdf0e10cSrcweir {
140*cdf0e10cSrcweir     switch ( eIdx )
141*cdf0e10cSrcweir     {
142*cdf0e10cSrcweir         case NF_KEY_TRUE :
143*cdf0e10cSrcweir             ((ImpSvNumberformatScan*)this)->sKeyword[NF_KEY_TRUE] =
144*cdf0e10cSrcweir                 pFormatter->GetCharClass()->upper(
145*cdf0e10cSrcweir                 pFormatter->GetLocaleData()->getTrueWord() );
146*cdf0e10cSrcweir             if ( !sKeyword[NF_KEY_TRUE].Len() )
147*cdf0e10cSrcweir             {
148*cdf0e10cSrcweir                 DBG_ERRORFILE( "InitSpecialKeyword: TRUE_WORD?" );
149*cdf0e10cSrcweir                 ((ImpSvNumberformatScan*)this)->sKeyword[NF_KEY_TRUE].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "sal_True" ) );
150*cdf0e10cSrcweir             }
151*cdf0e10cSrcweir         break;
152*cdf0e10cSrcweir         case NF_KEY_FALSE :
153*cdf0e10cSrcweir             ((ImpSvNumberformatScan*)this)->sKeyword[NF_KEY_FALSE] =
154*cdf0e10cSrcweir                 pFormatter->GetCharClass()->upper(
155*cdf0e10cSrcweir                 pFormatter->GetLocaleData()->getFalseWord() );
156*cdf0e10cSrcweir             if ( !sKeyword[NF_KEY_FALSE].Len() )
157*cdf0e10cSrcweir             {
158*cdf0e10cSrcweir                 DBG_ERRORFILE( "InitSpecialKeyword: FALSE_WORD?" );
159*cdf0e10cSrcweir                 ((ImpSvNumberformatScan*)this)->sKeyword[NF_KEY_FALSE].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "sal_False" ) );
160*cdf0e10cSrcweir             }
161*cdf0e10cSrcweir         break;
162*cdf0e10cSrcweir         default:
163*cdf0e10cSrcweir             DBG_ERRORFILE( "InitSpecialKeyword: unknown request" );
164*cdf0e10cSrcweir     }
165*cdf0e10cSrcweir }
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir 
168*cdf0e10cSrcweir void ImpSvNumberformatScan::InitCompatCur() const
169*cdf0e10cSrcweir {
170*cdf0e10cSrcweir     ImpSvNumberformatScan* pThis = (ImpSvNumberformatScan*)this;
171*cdf0e10cSrcweir     // currency symbol for old style ("automatic") compatibility format codes
172*cdf0e10cSrcweir     pFormatter->GetCompatibilityCurrency( pThis->sCurSymbol, pThis->sCurAbbrev );
173*cdf0e10cSrcweir     // currency symbol upper case
174*cdf0e10cSrcweir     pThis->sCurString = pFormatter->GetCharClass()->upper( sCurSymbol );
175*cdf0e10cSrcweir     bCompatCurNeedInit = sal_False;
176*cdf0e10cSrcweir }
177*cdf0e10cSrcweir 
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir void ImpSvNumberformatScan::InitKeywords() const
180*cdf0e10cSrcweir {
181*cdf0e10cSrcweir     if ( !bKeywordsNeedInit )
182*cdf0e10cSrcweir         return ;
183*cdf0e10cSrcweir     ((ImpSvNumberformatScan*)this)->SetDependentKeywords();
184*cdf0e10cSrcweir     bKeywordsNeedInit = sal_False;
185*cdf0e10cSrcweir }
186*cdf0e10cSrcweir 
187*cdf0e10cSrcweir 
188*cdf0e10cSrcweir /** Extract the name of General, Standard, Whatever, ignoring leading modifiers
189*cdf0e10cSrcweir     such as [NatNum1]. */
190*cdf0e10cSrcweir static String lcl_extractStandardGeneralName( const ::rtl::OUString & rCode )
191*cdf0e10cSrcweir {
192*cdf0e10cSrcweir     String aStr;
193*cdf0e10cSrcweir     const sal_Unicode* p = rCode.getStr();
194*cdf0e10cSrcweir     const sal_Unicode* const pStop = p + rCode.getLength();
195*cdf0e10cSrcweir     const sal_Unicode* pBeg = p;    // name begins here
196*cdf0e10cSrcweir     bool bMod = false;
197*cdf0e10cSrcweir     bool bDone = false;
198*cdf0e10cSrcweir     while (p < pStop && !bDone)
199*cdf0e10cSrcweir     {
200*cdf0e10cSrcweir         switch (*p)
201*cdf0e10cSrcweir         {
202*cdf0e10cSrcweir             case '[':
203*cdf0e10cSrcweir                 bMod = true;
204*cdf0e10cSrcweir                 break;
205*cdf0e10cSrcweir             case ']':
206*cdf0e10cSrcweir                 if (bMod)
207*cdf0e10cSrcweir                 {
208*cdf0e10cSrcweir                     bMod = false;
209*cdf0e10cSrcweir                     pBeg = p+1;
210*cdf0e10cSrcweir                 }
211*cdf0e10cSrcweir                 // else: would be a locale data error, easily to be spotted in
212*cdf0e10cSrcweir                 // UI dialog
213*cdf0e10cSrcweir                 break;
214*cdf0e10cSrcweir             case ';':
215*cdf0e10cSrcweir                 if (!bMod)
216*cdf0e10cSrcweir                 {
217*cdf0e10cSrcweir                     bDone = true;
218*cdf0e10cSrcweir                     --p;    // put back, increment by one follows
219*cdf0e10cSrcweir                 }
220*cdf0e10cSrcweir                 break;
221*cdf0e10cSrcweir         }
222*cdf0e10cSrcweir         ++p;
223*cdf0e10cSrcweir         if (bMod)
224*cdf0e10cSrcweir             pBeg = p;
225*cdf0e10cSrcweir     }
226*cdf0e10cSrcweir     if (pBeg < p)
227*cdf0e10cSrcweir         aStr = rCode.copy( pBeg - rCode.getStr(), p - pBeg);
228*cdf0e10cSrcweir     return aStr;
229*cdf0e10cSrcweir }
230*cdf0e10cSrcweir 
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir void ImpSvNumberformatScan::SetDependentKeywords()
233*cdf0e10cSrcweir {
234*cdf0e10cSrcweir 	using namespace ::com::sun::star;
235*cdf0e10cSrcweir 	using namespace ::com::sun::star::uno;
236*cdf0e10cSrcweir 
237*cdf0e10cSrcweir 	const CharClass* pCharClass = pFormatter->GetCharClass();
238*cdf0e10cSrcweir 	const LocaleDataWrapper* pLocaleData = pFormatter->GetLocaleData();
239*cdf0e10cSrcweir 	// #80023# be sure to generate keywords for the loaded Locale, not for the
240*cdf0e10cSrcweir 	// requested Locale, otherwise number format codes might not match
241*cdf0e10cSrcweir 	lang::Locale aLoadedLocale = pLocaleData->getLoadedLocale();
242*cdf0e10cSrcweir 	LanguageType eLang = MsLangId::convertLocaleToLanguage( aLoadedLocale );
243*cdf0e10cSrcweir 	NumberFormatCodeWrapper aNumberFormatCode( pFormatter->GetServiceManager(), aLoadedLocale );
244*cdf0e10cSrcweir 
245*cdf0e10cSrcweir     i18n::NumberFormatCode aFormat = aNumberFormatCode.getFormatCode( NF_NUMBER_STANDARD );
246*cdf0e10cSrcweir 	sNameStandardFormat = lcl_extractStandardGeneralName( aFormat.Code);
247*cdf0e10cSrcweir 	sKeyword[NF_KEY_GENERAL] = pCharClass->upper( sNameStandardFormat );
248*cdf0e10cSrcweir 
249*cdf0e10cSrcweir 	// preset new calendar keywords
250*cdf0e10cSrcweir 	sKeyword[NF_KEY_AAA].AssignAscii( RTL_CONSTASCII_STRINGPARAM(	"AAA" ) );
251*cdf0e10cSrcweir 	sKeyword[NF_KEY_AAAA].AssignAscii( RTL_CONSTASCII_STRINGPARAM(	"AAAA" ) );
252*cdf0e10cSrcweir 	sKeyword[NF_KEY_EC].AssignAscii( RTL_CONSTASCII_STRINGPARAM(	"E" ) );
253*cdf0e10cSrcweir 	sKeyword[NF_KEY_EEC].AssignAscii( RTL_CONSTASCII_STRINGPARAM(	"EE" ) );
254*cdf0e10cSrcweir 	sKeyword[NF_KEY_G].AssignAscii( RTL_CONSTASCII_STRINGPARAM(		"G" ) );
255*cdf0e10cSrcweir 	sKeyword[NF_KEY_GG].AssignAscii( RTL_CONSTASCII_STRINGPARAM(	"GG" ) );
256*cdf0e10cSrcweir 	sKeyword[NF_KEY_GGG].AssignAscii( RTL_CONSTASCII_STRINGPARAM(	"GGG" ) );
257*cdf0e10cSrcweir 	sKeyword[NF_KEY_R].AssignAscii( RTL_CONSTASCII_STRINGPARAM(		"R" ) );
258*cdf0e10cSrcweir 	sKeyword[NF_KEY_RR].AssignAscii( RTL_CONSTASCII_STRINGPARAM(	"RR" ) );
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir     // Thai T NatNum special. Other locale's small letter 't' results in upper
261*cdf0e10cSrcweir     // case comparison not matching but length does in conversion mode. Ugly.
262*cdf0e10cSrcweir     if (eLang == LANGUAGE_THAI)
263*cdf0e10cSrcweir         sKeyword[NF_KEY_THAI_T].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "T"));
264*cdf0e10cSrcweir     else
265*cdf0e10cSrcweir         sKeyword[NF_KEY_THAI_T].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "t"));
266*cdf0e10cSrcweir 
267*cdf0e10cSrcweir 	switch ( eLang )
268*cdf0e10cSrcweir 	{
269*cdf0e10cSrcweir 		case LANGUAGE_GERMAN:
270*cdf0e10cSrcweir 		case LANGUAGE_GERMAN_SWISS:
271*cdf0e10cSrcweir 		case LANGUAGE_GERMAN_AUSTRIAN:
272*cdf0e10cSrcweir 		case LANGUAGE_GERMAN_LUXEMBOURG:
273*cdf0e10cSrcweir 		case LANGUAGE_GERMAN_LIECHTENSTEIN:
274*cdf0e10cSrcweir 		{
275*cdf0e10cSrcweir 			//! all capital letters
276*cdf0e10cSrcweir 			sKeyword[NF_KEY_M].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"M" ) ); 			// month 1
277*cdf0e10cSrcweir 			sKeyword[NF_KEY_MM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"MM" ) );			// month 01
278*cdf0e10cSrcweir 			sKeyword[NF_KEY_MMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"MMM" ) );		// month Jan
279*cdf0e10cSrcweir 			sKeyword[NF_KEY_MMMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"MMMM" ) );	// month Januar
280*cdf0e10cSrcweir 			sKeyword[NF_KEY_MMMMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"MMMMM" ) );// month J
281*cdf0e10cSrcweir 			sKeyword[NF_KEY_H].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"H" ) ); 			// hour 2
282*cdf0e10cSrcweir 			sKeyword[NF_KEY_HH].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"HH" ) );			// hour 02
283*cdf0e10cSrcweir 			sKeyword[NF_KEY_D].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"T" ) );
284*cdf0e10cSrcweir 			sKeyword[NF_KEY_DD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"TT" ) );
285*cdf0e10cSrcweir 			sKeyword[NF_KEY_DDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"TTT" ) );
286*cdf0e10cSrcweir 			sKeyword[NF_KEY_DDDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"TTTT" ) );
287*cdf0e10cSrcweir 			sKeyword[NF_KEY_YY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"JJ" ) );
288*cdf0e10cSrcweir 			sKeyword[NF_KEY_YYYY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"JJJJ" ) );
289*cdf0e10cSrcweir 			sKeyword[NF_KEY_BOOLEAN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"LOGISCH" ) );
290*cdf0e10cSrcweir 			sKeyword[NF_KEY_COLOR].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"FARBE" ) );
291*cdf0e10cSrcweir 			sKeyword[NF_KEY_BLACK].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"SCHWARZ" ) );
292*cdf0e10cSrcweir 			sKeyword[NF_KEY_BLUE].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"BLAU" ) );
293*cdf0e10cSrcweir 			sKeyword[NF_KEY_GREEN] = UniString( "GR" "\xDC" "N", RTL_TEXTENCODING_ISO_8859_1 );
294*cdf0e10cSrcweir 			sKeyword[NF_KEY_CYAN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"CYAN" ) );
295*cdf0e10cSrcweir 			sKeyword[NF_KEY_RED].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"ROT" ) );
296*cdf0e10cSrcweir 			sKeyword[NF_KEY_MAGENTA].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"MAGENTA" ) );
297*cdf0e10cSrcweir 			sKeyword[NF_KEY_BROWN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"BRAUN" ) );
298*cdf0e10cSrcweir 			sKeyword[NF_KEY_GREY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"GRAU" ) );
299*cdf0e10cSrcweir 			sKeyword[NF_KEY_YELLOW].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"GELB" ) );
300*cdf0e10cSrcweir 			sKeyword[NF_KEY_WHITE].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"WEISS" ) );
301*cdf0e10cSrcweir 		}
302*cdf0e10cSrcweir 		break;
303*cdf0e10cSrcweir 		default:
304*cdf0e10cSrcweir 		{
305*cdf0e10cSrcweir 			// day
306*cdf0e10cSrcweir 			switch ( eLang )
307*cdf0e10cSrcweir 			{
308*cdf0e10cSrcweir 				case LANGUAGE_ITALIAN       :
309*cdf0e10cSrcweir 				case LANGUAGE_ITALIAN_SWISS :
310*cdf0e10cSrcweir 					sKeyword[NF_KEY_D].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "G" ) );
311*cdf0e10cSrcweir 					sKeyword[NF_KEY_DD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GG" ) );
312*cdf0e10cSrcweir 					sKeyword[NF_KEY_DDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GGG" ) );
313*cdf0e10cSrcweir 					sKeyword[NF_KEY_DDDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GGGG" ) );
314*cdf0e10cSrcweir 					// must exchange the era code, same as Xcl
315*cdf0e10cSrcweir 					sKeyword[NF_KEY_G].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "X" ) );
316*cdf0e10cSrcweir 					sKeyword[NF_KEY_GG].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "XX" ) );
317*cdf0e10cSrcweir 					sKeyword[NF_KEY_GGG].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "XXX" ) );
318*cdf0e10cSrcweir 				break;
319*cdf0e10cSrcweir 				case LANGUAGE_FRENCH            :
320*cdf0e10cSrcweir 				case LANGUAGE_FRENCH_BELGIAN    :
321*cdf0e10cSrcweir 				case LANGUAGE_FRENCH_CANADIAN   :
322*cdf0e10cSrcweir 				case LANGUAGE_FRENCH_SWISS      :
323*cdf0e10cSrcweir 				case LANGUAGE_FRENCH_LUXEMBOURG :
324*cdf0e10cSrcweir 				case LANGUAGE_FRENCH_MONACO		:
325*cdf0e10cSrcweir 					sKeyword[NF_KEY_D].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "J" ) );
326*cdf0e10cSrcweir 					sKeyword[NF_KEY_DD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJ" ) );
327*cdf0e10cSrcweir 					sKeyword[NF_KEY_DDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJJ" ) );
328*cdf0e10cSrcweir 					sKeyword[NF_KEY_DDDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJJJ" ) );
329*cdf0e10cSrcweir 				break;
330*cdf0e10cSrcweir 				case LANGUAGE_FINNISH :
331*cdf0e10cSrcweir 					sKeyword[NF_KEY_D].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "P" ) );
332*cdf0e10cSrcweir 					sKeyword[NF_KEY_DD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "PP" ) );
333*cdf0e10cSrcweir 					sKeyword[NF_KEY_DDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "PPP" ) );
334*cdf0e10cSrcweir 					sKeyword[NF_KEY_DDDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "PPPP" ) );
335*cdf0e10cSrcweir 				break;
336*cdf0e10cSrcweir 				default:
337*cdf0e10cSrcweir 					sKeyword[NF_KEY_D].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D" ) );
338*cdf0e10cSrcweir 					sKeyword[NF_KEY_DD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DD" ) );
339*cdf0e10cSrcweir 					sKeyword[NF_KEY_DDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDD" ) );
340*cdf0e10cSrcweir 					sKeyword[NF_KEY_DDDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDDD" ) );
341*cdf0e10cSrcweir 			}
342*cdf0e10cSrcweir 			// month
343*cdf0e10cSrcweir 			switch ( eLang )
344*cdf0e10cSrcweir 			{
345*cdf0e10cSrcweir 				case LANGUAGE_FINNISH :
346*cdf0e10cSrcweir 					sKeyword[NF_KEY_M].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "K" ) );
347*cdf0e10cSrcweir 					sKeyword[NF_KEY_MM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "KK" ) );
348*cdf0e10cSrcweir 					sKeyword[NF_KEY_MMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "KKK" ) );
349*cdf0e10cSrcweir 					sKeyword[NF_KEY_MMMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "KKKK" ) );
350*cdf0e10cSrcweir 					sKeyword[NF_KEY_MMMMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "KKKKK" ) );
351*cdf0e10cSrcweir 				break;
352*cdf0e10cSrcweir 				default:
353*cdf0e10cSrcweir 					sKeyword[NF_KEY_M].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "M" ) );
354*cdf0e10cSrcweir 					sKeyword[NF_KEY_MM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MM" ) );
355*cdf0e10cSrcweir 					sKeyword[NF_KEY_MMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMM" ) );
356*cdf0e10cSrcweir 					sKeyword[NF_KEY_MMMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMMM" ) );
357*cdf0e10cSrcweir 					sKeyword[NF_KEY_MMMMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMMMM" ) );
358*cdf0e10cSrcweir 			}
359*cdf0e10cSrcweir 			// year
360*cdf0e10cSrcweir 			switch ( eLang )
361*cdf0e10cSrcweir 			{
362*cdf0e10cSrcweir 				case LANGUAGE_ITALIAN       :
363*cdf0e10cSrcweir 				case LANGUAGE_ITALIAN_SWISS :
364*cdf0e10cSrcweir 				case LANGUAGE_FRENCH            :
365*cdf0e10cSrcweir 				case LANGUAGE_FRENCH_BELGIAN    :
366*cdf0e10cSrcweir 				case LANGUAGE_FRENCH_CANADIAN   :
367*cdf0e10cSrcweir 				case LANGUAGE_FRENCH_SWISS      :
368*cdf0e10cSrcweir 				case LANGUAGE_FRENCH_LUXEMBOURG :
369*cdf0e10cSrcweir 				case LANGUAGE_FRENCH_MONACO		:
370*cdf0e10cSrcweir 				case LANGUAGE_PORTUGUESE           :
371*cdf0e10cSrcweir 				case LANGUAGE_PORTUGUESE_BRAZILIAN :
372*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_MODERN      :
373*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_DATED       :
374*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_MEXICAN     :
375*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_GUATEMALA   :
376*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_COSTARICA   :
377*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_PANAMA      :
378*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_DOMINICAN_REPUBLIC :
379*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_VENEZUELA   :
380*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_COLOMBIA    :
381*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_PERU        :
382*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_ARGENTINA   :
383*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_ECUADOR     :
384*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_CHILE       :
385*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_URUGUAY     :
386*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_PARAGUAY    :
387*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_BOLIVIA     :
388*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_EL_SALVADOR :
389*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_HONDURAS    :
390*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_NICARAGUA   :
391*cdf0e10cSrcweir 				case LANGUAGE_SPANISH_PUERTO_RICO :
392*cdf0e10cSrcweir 					sKeyword[NF_KEY_YY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "AA" ) );
393*cdf0e10cSrcweir 					sKeyword[NF_KEY_YYYY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "AAAA" ) );
394*cdf0e10cSrcweir 					// must exchange the day of week name code, same as Xcl
395*cdf0e10cSrcweir 					sKeyword[NF_KEY_AAA].AssignAscii( RTL_CONSTASCII_STRINGPARAM(	"OOO" ) );
396*cdf0e10cSrcweir 					sKeyword[NF_KEY_AAAA].AssignAscii( RTL_CONSTASCII_STRINGPARAM(	"OOOO" ) );
397*cdf0e10cSrcweir 				break;
398*cdf0e10cSrcweir 				case LANGUAGE_DUTCH         :
399*cdf0e10cSrcweir 				case LANGUAGE_DUTCH_BELGIAN :
400*cdf0e10cSrcweir 					sKeyword[NF_KEY_YY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJ" ) );
401*cdf0e10cSrcweir 					sKeyword[NF_KEY_YYYY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJJJ" ) );
402*cdf0e10cSrcweir 				break;
403*cdf0e10cSrcweir 				case LANGUAGE_FINNISH :
404*cdf0e10cSrcweir 					sKeyword[NF_KEY_YY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "VV" ) );
405*cdf0e10cSrcweir 					sKeyword[NF_KEY_YYYY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "VVVV" ) );
406*cdf0e10cSrcweir 				break;
407*cdf0e10cSrcweir 				default:
408*cdf0e10cSrcweir 					sKeyword[NF_KEY_YY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "YY" ) );
409*cdf0e10cSrcweir 					sKeyword[NF_KEY_YYYY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "YYYY" ) );
410*cdf0e10cSrcweir 			}
411*cdf0e10cSrcweir 			// hour
412*cdf0e10cSrcweir 			switch ( eLang )
413*cdf0e10cSrcweir 			{
414*cdf0e10cSrcweir 				case LANGUAGE_DUTCH         :
415*cdf0e10cSrcweir 				case LANGUAGE_DUTCH_BELGIAN :
416*cdf0e10cSrcweir 					sKeyword[NF_KEY_H].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "U" ) );
417*cdf0e10cSrcweir 					sKeyword[NF_KEY_HH].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "UU" ) );
418*cdf0e10cSrcweir 				break;
419*cdf0e10cSrcweir 				case LANGUAGE_FINNISH :
420*cdf0e10cSrcweir 				case LANGUAGE_SWEDISH         :
421*cdf0e10cSrcweir 				case LANGUAGE_SWEDISH_FINLAND :
422*cdf0e10cSrcweir 				case LANGUAGE_DANISH :
423*cdf0e10cSrcweir 				case LANGUAGE_NORWEGIAN         :
424*cdf0e10cSrcweir 				case LANGUAGE_NORWEGIAN_BOKMAL  :
425*cdf0e10cSrcweir 				case LANGUAGE_NORWEGIAN_NYNORSK :
426*cdf0e10cSrcweir 					sKeyword[NF_KEY_H].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "T" ) );
427*cdf0e10cSrcweir 					sKeyword[NF_KEY_HH].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "TT" ) );
428*cdf0e10cSrcweir 				break;
429*cdf0e10cSrcweir 				default:
430*cdf0e10cSrcweir 					sKeyword[NF_KEY_H].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "H" ) );
431*cdf0e10cSrcweir 					sKeyword[NF_KEY_HH].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "HH" ) );
432*cdf0e10cSrcweir 			}
433*cdf0e10cSrcweir 			// boolean
434*cdf0e10cSrcweir 			sKeyword[NF_KEY_BOOLEAN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "BOOLEAN" ) );
435*cdf0e10cSrcweir 			// colours
436*cdf0e10cSrcweir 			sKeyword[NF_KEY_COLOR].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"COLOR" ) );
437*cdf0e10cSrcweir 			sKeyword[NF_KEY_BLACK].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"BLACK" ) );
438*cdf0e10cSrcweir 			sKeyword[NF_KEY_BLUE].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"BLUE" ) );
439*cdf0e10cSrcweir 			sKeyword[NF_KEY_GREEN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"GREEN" ) );
440*cdf0e10cSrcweir 			sKeyword[NF_KEY_CYAN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"CYAN" ) );
441*cdf0e10cSrcweir 			sKeyword[NF_KEY_RED].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"RED" ) );
442*cdf0e10cSrcweir 			sKeyword[NF_KEY_MAGENTA].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"MAGENTA" ) );
443*cdf0e10cSrcweir 			sKeyword[NF_KEY_BROWN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"BROWN" ) );
444*cdf0e10cSrcweir 			sKeyword[NF_KEY_GREY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 		"GREY" ) );
445*cdf0e10cSrcweir 			sKeyword[NF_KEY_YELLOW].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"YELLOW" ) );
446*cdf0e10cSrcweir 			sKeyword[NF_KEY_WHITE].AssignAscii( RTL_CONSTASCII_STRINGPARAM( 	"WHITE" ) );
447*cdf0e10cSrcweir 		}
448*cdf0e10cSrcweir 		break;
449*cdf0e10cSrcweir 	}
450*cdf0e10cSrcweir 
451*cdf0e10cSrcweir 	// boolean keyords
452*cdf0e10cSrcweir     InitSpecialKeyword( NF_KEY_TRUE );
453*cdf0e10cSrcweir     InitSpecialKeyword( NF_KEY_FALSE );
454*cdf0e10cSrcweir 
455*cdf0e10cSrcweir     // compatibility currency strings
456*cdf0e10cSrcweir     InitCompatCur();
457*cdf0e10cSrcweir }
458*cdf0e10cSrcweir 
459*cdf0e10cSrcweir 
460*cdf0e10cSrcweir void ImpSvNumberformatScan::ChangeNullDate(sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear)
461*cdf0e10cSrcweir {
462*cdf0e10cSrcweir 	if ( pNullDate )
463*cdf0e10cSrcweir 		*pNullDate = Date(nDay, nMonth, nYear);
464*cdf0e10cSrcweir 	else
465*cdf0e10cSrcweir 		pNullDate = new Date(nDay, nMonth, nYear);
466*cdf0e10cSrcweir }
467*cdf0e10cSrcweir 
468*cdf0e10cSrcweir void ImpSvNumberformatScan::ChangeStandardPrec(sal_uInt16 nPrec)
469*cdf0e10cSrcweir {
470*cdf0e10cSrcweir 	nStandardPrec = nPrec;
471*cdf0e10cSrcweir }
472*cdf0e10cSrcweir 
473*cdf0e10cSrcweir Color* ImpSvNumberformatScan::GetColor(String& sStr)
474*cdf0e10cSrcweir {
475*cdf0e10cSrcweir 	String sString = pFormatter->GetCharClass()->upper(sStr);
476*cdf0e10cSrcweir     const NfKeywordTable & rKeyword = GetKeywords();
477*cdf0e10cSrcweir 	size_t i = 0;
478*cdf0e10cSrcweir 	while (i < NF_MAX_DEFAULT_COLORS &&
479*cdf0e10cSrcweir            sString != rKeyword[NF_KEY_FIRSTCOLOR+i] )
480*cdf0e10cSrcweir 		i++;
481*cdf0e10cSrcweir     if ( i >= NF_MAX_DEFAULT_COLORS )
482*cdf0e10cSrcweir     {
483*cdf0e10cSrcweir         const String* pEnglishColors = theEnglishColors::get();
484*cdf0e10cSrcweir         size_t j = 0;
485*cdf0e10cSrcweir         while ( j < NF_MAX_DEFAULT_COLORS &&
486*cdf0e10cSrcweir                 sString != pEnglishColors[j] )
487*cdf0e10cSrcweir             ++j;
488*cdf0e10cSrcweir         if ( j < NF_MAX_DEFAULT_COLORS )
489*cdf0e10cSrcweir             i = j;
490*cdf0e10cSrcweir     }
491*cdf0e10cSrcweir 
492*cdf0e10cSrcweir     Color* pResult = NULL;
493*cdf0e10cSrcweir 	if (i >= NF_MAX_DEFAULT_COLORS)
494*cdf0e10cSrcweir 	{
495*cdf0e10cSrcweir         const String& rColorWord = rKeyword[NF_KEY_COLOR];
496*cdf0e10cSrcweir 		xub_StrLen nPos = sString.Match(rColorWord);
497*cdf0e10cSrcweir 		if (nPos > 0)
498*cdf0e10cSrcweir 		{
499*cdf0e10cSrcweir 			sStr.Erase(0, nPos);
500*cdf0e10cSrcweir 			sStr.EraseLeadingChars();
501*cdf0e10cSrcweir 			sStr.EraseTrailingChars();
502*cdf0e10cSrcweir 			if (bConvertMode)
503*cdf0e10cSrcweir 			{
504*cdf0e10cSrcweir 				pFormatter->ChangeIntl(eNewLnge);
505*cdf0e10cSrcweir                 sStr.Insert( GetKeywords()[NF_KEY_COLOR], 0 );  // Color -> FARBE
506*cdf0e10cSrcweir 				pFormatter->ChangeIntl(eTmpLnge);
507*cdf0e10cSrcweir 			}
508*cdf0e10cSrcweir 			else
509*cdf0e10cSrcweir 				sStr.Insert(rColorWord,0);
510*cdf0e10cSrcweir 			sString.Erase(0, nPos);
511*cdf0e10cSrcweir 			sString.EraseLeadingChars();
512*cdf0e10cSrcweir 			sString.EraseTrailingChars();
513*cdf0e10cSrcweir 
514*cdf0e10cSrcweir 			if ( CharClass::isAsciiNumeric( sString ) )
515*cdf0e10cSrcweir 			{
516*cdf0e10cSrcweir 				long nIndex = sString.ToInt32();
517*cdf0e10cSrcweir 				if (nIndex > 0 && nIndex <= 64)
518*cdf0e10cSrcweir 					pResult = pFormatter->GetUserDefColor((sal_uInt16)nIndex-1);
519*cdf0e10cSrcweir 			}
520*cdf0e10cSrcweir 		}
521*cdf0e10cSrcweir 	}
522*cdf0e10cSrcweir 	else
523*cdf0e10cSrcweir 	{
524*cdf0e10cSrcweir 		sStr.Erase();
525*cdf0e10cSrcweir 		if (bConvertMode)
526*cdf0e10cSrcweir 		{
527*cdf0e10cSrcweir 			pFormatter->ChangeIntl(eNewLnge);
528*cdf0e10cSrcweir             sStr = GetKeywords()[NF_KEY_FIRSTCOLOR+i];           // red -> rot
529*cdf0e10cSrcweir 			pFormatter->ChangeIntl(eTmpLnge);
530*cdf0e10cSrcweir 		}
531*cdf0e10cSrcweir 		else
532*cdf0e10cSrcweir             sStr = rKeyword[NF_KEY_FIRSTCOLOR+i];
533*cdf0e10cSrcweir 
534*cdf0e10cSrcweir 		pResult = &(StandardColor[i]);
535*cdf0e10cSrcweir 	}
536*cdf0e10cSrcweir     return pResult;
537*cdf0e10cSrcweir }
538*cdf0e10cSrcweir 
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir short ImpSvNumberformatScan::GetKeyWord( const String& sSymbol, xub_StrLen nPos )
541*cdf0e10cSrcweir {
542*cdf0e10cSrcweir 	String sString = pFormatter->GetCharClass()->toUpper( sSymbol, nPos, sSymbol.Len() - nPos );
543*cdf0e10cSrcweir     const NfKeywordTable & rKeyword = GetKeywords();
544*cdf0e10cSrcweir 	// #77026# for the Xcl perverts: the GENERAL keyword is recognized anywhere
545*cdf0e10cSrcweir     if ( sString.Search( rKeyword[NF_KEY_GENERAL] ) == 0 )
546*cdf0e10cSrcweir 		return NF_KEY_GENERAL;
547*cdf0e10cSrcweir 	//! MUST be a reverse search to find longer strings first
548*cdf0e10cSrcweir 	short i = NF_KEYWORD_ENTRIES_COUNT-1;
549*cdf0e10cSrcweir 	sal_Bool bFound = sal_False;
550*cdf0e10cSrcweir     for ( ; i > NF_KEY_LASTKEYWORD_SO5; --i )
551*cdf0e10cSrcweir     {
552*cdf0e10cSrcweir         bFound = sString.Search(rKeyword[i]) == 0;
553*cdf0e10cSrcweir         if ( bFound )
554*cdf0e10cSrcweir         {
555*cdf0e10cSrcweir             break;
556*cdf0e10cSrcweir         }
557*cdf0e10cSrcweir     }
558*cdf0e10cSrcweir 	// new keywords take precedence over old keywords
559*cdf0e10cSrcweir 	if ( !bFound )
560*cdf0e10cSrcweir 	{	// skip the gap of colors et al between new and old keywords and search on
561*cdf0e10cSrcweir 		i = NF_KEY_LASTKEYWORD;
562*cdf0e10cSrcweir         while ( i > 0 && sString.Search(rKeyword[i]) != 0 )
563*cdf0e10cSrcweir 			i--;
564*cdf0e10cSrcweir         if ( i > NF_KEY_LASTOLDKEYWORD && sString != rKeyword[i] )
565*cdf0e10cSrcweir 		{	// found something, but maybe it's something else?
566*cdf0e10cSrcweir 			// e.g. new NNN is found in NNNN, for NNNN we must search on
567*cdf0e10cSrcweir 			short j = i - 1;
568*cdf0e10cSrcweir             while ( j > 0 && sString.Search(rKeyword[j]) != 0 )
569*cdf0e10cSrcweir 				j--;
570*cdf0e10cSrcweir             if ( j && rKeyword[j].Len() > rKeyword[i].Len() )
571*cdf0e10cSrcweir 				return j;
572*cdf0e10cSrcweir 		}
573*cdf0e10cSrcweir 	}
574*cdf0e10cSrcweir     // The Thai T NatNum modifier during Xcl import.
575*cdf0e10cSrcweir     if (i == 0 && bConvertMode && sString.GetChar(0) == 'T' && eTmpLnge ==
576*cdf0e10cSrcweir             LANGUAGE_ENGLISH_US && MsLangId::getRealLanguage( eNewLnge) ==
577*cdf0e10cSrcweir             LANGUAGE_THAI)
578*cdf0e10cSrcweir         i = NF_KEY_THAI_T;
579*cdf0e10cSrcweir 	return i;		// 0 => not found
580*cdf0e10cSrcweir }
581*cdf0e10cSrcweir 
582*cdf0e10cSrcweir //---------------------------------------------------------------------------
583*cdf0e10cSrcweir // Next_Symbol
584*cdf0e10cSrcweir //---------------------------------------------------------------------------
585*cdf0e10cSrcweir // Zerlegt die Eingabe in Symbole fuer die weitere
586*cdf0e10cSrcweir // Verarbeitung (Turing-Maschine).
587*cdf0e10cSrcweir //---------------------------------------------------------------------------
588*cdf0e10cSrcweir // Ausgangs Zustand = SsStart
589*cdf0e10cSrcweir //---------------+-------------------+-----------------------+---------------
590*cdf0e10cSrcweir // Alter Zustand | gelesenes Zeichen | Aktion                | Neuer Zustand
591*cdf0e10cSrcweir //---------------+-------------------+-----------------------+---------------
592*cdf0e10cSrcweir // SsStart       | Buchstabe         | Symbol=Zeichen        | SsGetWord
593*cdf0e10cSrcweir //               |    "              | Typ = String          | SsGetString
594*cdf0e10cSrcweir //               |    \              | Typ = String          | SsGetChar
595*cdf0e10cSrcweir //               |    *              | Typ = Star            | SsGetStar
596*cdf0e10cSrcweir //               |    _              | Typ = Blank           | SsGetBlank
597*cdf0e10cSrcweir //               | @ # 0 ? / . , % [ | Symbol = Zeichen;     |
598*cdf0e10cSrcweir //               | ] ' Blank         | Typ = Steuerzeichen   | SsStop
599*cdf0e10cSrcweir //               | $ - + ( ) :       | Typ    = String;      |
600*cdf0e10cSrcweir //               | |                 | Typ    = Comment      | SsStop
601*cdf0e10cSrcweir //               | Sonst             | Symbol = Zeichen      | SsStop
602*cdf0e10cSrcweir //---------------|-------------------+-----------------------+---------------
603*cdf0e10cSrcweir // SsGetChar     | Sonst             | Symbol=Zeichen        | SsStop
604*cdf0e10cSrcweir //---------------+-------------------+-----------------------+---------------
605*cdf0e10cSrcweir // GetString     | "                 |                       | SsStop
606*cdf0e10cSrcweir //               | Sonst             | Symbol+=Zeichen       | GetString
607*cdf0e10cSrcweir //---------------+-------------------+-----------------------+---------------
608*cdf0e10cSrcweir // SsGetWord     | Buchstabe         | Symbol += Zeichen     |
609*cdf0e10cSrcweir //               | + -        (E+ E-)| Symbol += Zeichen     | SsStop
610*cdf0e10cSrcweir //               | /          (AM/PM)| Symbol += Zeichen     |
611*cdf0e10cSrcweir //               | Sonst             | Pos--, if Key Typ=Word| SsStop
612*cdf0e10cSrcweir //---------------+-------------------+-----------------------+---------------
613*cdf0e10cSrcweir // SsGetStar     | Sonst             | Symbol+=Zeichen       | SsStop
614*cdf0e10cSrcweir //               |                   | markiere Sonderfall * |
615*cdf0e10cSrcweir //---------------+-------------------+-----------------------+---------------
616*cdf0e10cSrcweir // SsGetBlank    | Sonst             | Symbol+=Zeichen       | SsStop
617*cdf0e10cSrcweir //               |                   | markiere Sonderfall _ |
618*cdf0e10cSrcweir //---------------+-------------------+-----------------------+---------------
619*cdf0e10cSrcweir // Wurde im State SsGetWord ein Schluesselwort erkannt (auch als
620*cdf0e10cSrcweir // Anfangsteilwort des Symbols)
621*cdf0e10cSrcweir // so werden die restlichen Buchstaben zurueckgeschrieben !!
622*cdf0e10cSrcweir 
623*cdf0e10cSrcweir enum ScanState
624*cdf0e10cSrcweir {
625*cdf0e10cSrcweir 	SsStop      = 0,
626*cdf0e10cSrcweir 	SsStart     = 1,
627*cdf0e10cSrcweir 	SsGetChar   = 2,
628*cdf0e10cSrcweir 	SsGetString = 3,
629*cdf0e10cSrcweir 	SsGetWord   = 4,
630*cdf0e10cSrcweir 	SsGetStar   = 5,
631*cdf0e10cSrcweir 	SsGetBlank  = 6
632*cdf0e10cSrcweir };
633*cdf0e10cSrcweir 
634*cdf0e10cSrcweir short ImpSvNumberformatScan::Next_Symbol( const String& rStr,
635*cdf0e10cSrcweir 			xub_StrLen& nPos, String& sSymbol )
636*cdf0e10cSrcweir {
637*cdf0e10cSrcweir     if ( bKeywordsNeedInit )
638*cdf0e10cSrcweir         InitKeywords();
639*cdf0e10cSrcweir 	const CharClass* pChrCls = pFormatter->GetCharClass();
640*cdf0e10cSrcweir 	const LocaleDataWrapper* pLoc = pFormatter->GetLocaleData();
641*cdf0e10cSrcweir 	const xub_StrLen nStart = nPos;
642*cdf0e10cSrcweir 	short eType = 0;
643*cdf0e10cSrcweir 	ScanState eState = SsStart;
644*cdf0e10cSrcweir 	sSymbol.Erase();
645*cdf0e10cSrcweir 	while ( nPos < rStr.Len() && eState != SsStop )
646*cdf0e10cSrcweir 	{
647*cdf0e10cSrcweir 		sal_Unicode cToken = rStr.GetChar( nPos++ );
648*cdf0e10cSrcweir 		switch (eState)
649*cdf0e10cSrcweir 		{
650*cdf0e10cSrcweir 			case SsStart:
651*cdf0e10cSrcweir 			{
652*cdf0e10cSrcweir 				// Fetch any currency longer than one character and don't get
653*cdf0e10cSrcweir 				// confused later on by "E/" or other combinations of letters
654*cdf0e10cSrcweir                 // and meaningful symbols. Necessary for old automatic currency.
655*cdf0e10cSrcweir                 // #96158# But don't do it if we're starting a "[...]" section,
656*cdf0e10cSrcweir                 // for example a "[$...]" new currency symbol to not parse away
657*cdf0e10cSrcweir                 // "$U" (symbol) of "[$UYU]" (abbreviation).
658*cdf0e10cSrcweir                 if ( nCurrPos != STRING_NOTFOUND && sCurString.Len() > 1 &&
659*cdf0e10cSrcweir                         nPos-1 + sCurString.Len() <= rStr.Len() &&
660*cdf0e10cSrcweir                         !(nPos > 1 && rStr.GetChar( nPos-2 ) == '[') )
661*cdf0e10cSrcweir 				{
662*cdf0e10cSrcweir                     String aTest( rStr.Copy( nPos-1, sCurString.Len() ) );
663*cdf0e10cSrcweir 					pChrCls->toUpper( aTest );
664*cdf0e10cSrcweir                     if ( aTest == sCurString )
665*cdf0e10cSrcweir 					{
666*cdf0e10cSrcweir                         sSymbol = rStr.Copy( --nPos, sCurString.Len() );
667*cdf0e10cSrcweir 						nPos = nPos + sSymbol.Len();
668*cdf0e10cSrcweir 						eState = SsStop;
669*cdf0e10cSrcweir 						eType = NF_SYMBOLTYPE_STRING;
670*cdf0e10cSrcweir 						return eType;
671*cdf0e10cSrcweir 					}
672*cdf0e10cSrcweir 				}
673*cdf0e10cSrcweir 				switch (cToken)
674*cdf0e10cSrcweir 				{
675*cdf0e10cSrcweir 					case '#':
676*cdf0e10cSrcweir 					case '0':
677*cdf0e10cSrcweir 					case '?':
678*cdf0e10cSrcweir 					case '%':
679*cdf0e10cSrcweir 					case '@':
680*cdf0e10cSrcweir 					case '[':
681*cdf0e10cSrcweir 					case ']':
682*cdf0e10cSrcweir 					case ',':
683*cdf0e10cSrcweir 					case '.':
684*cdf0e10cSrcweir 					case '/':
685*cdf0e10cSrcweir 					case '\'':
686*cdf0e10cSrcweir 					case ' ':
687*cdf0e10cSrcweir 					case ':':
688*cdf0e10cSrcweir 					case '-':
689*cdf0e10cSrcweir 					{
690*cdf0e10cSrcweir 						eType = NF_SYMBOLTYPE_DEL;
691*cdf0e10cSrcweir 						sSymbol += cToken;
692*cdf0e10cSrcweir 						eState = SsStop;
693*cdf0e10cSrcweir 					}
694*cdf0e10cSrcweir 					break;
695*cdf0e10cSrcweir 					case '*':
696*cdf0e10cSrcweir 					{
697*cdf0e10cSrcweir 						eType = NF_SYMBOLTYPE_STAR;
698*cdf0e10cSrcweir 						sSymbol += cToken;
699*cdf0e10cSrcweir 						eState = SsGetStar;
700*cdf0e10cSrcweir 					}
701*cdf0e10cSrcweir 					break;
702*cdf0e10cSrcweir 					case '_':
703*cdf0e10cSrcweir 					{
704*cdf0e10cSrcweir 						eType = NF_SYMBOLTYPE_BLANK;
705*cdf0e10cSrcweir 						sSymbol += cToken;
706*cdf0e10cSrcweir 						eState = SsGetBlank;
707*cdf0e10cSrcweir 					}
708*cdf0e10cSrcweir 					break;
709*cdf0e10cSrcweir #if NF_COMMENT_IN_FORMATSTRING
710*cdf0e10cSrcweir 					case '{':
711*cdf0e10cSrcweir 						eType = NF_SYMBOLTYPE_COMMENT;
712*cdf0e10cSrcweir 						eState = SsStop;
713*cdf0e10cSrcweir 						sSymbol.Append( rStr.GetBuffer() + (nPos-1), rStr.Len() - (nPos-1) );
714*cdf0e10cSrcweir 						nPos = rStr.Len();
715*cdf0e10cSrcweir 					break;
716*cdf0e10cSrcweir #endif
717*cdf0e10cSrcweir 					case '"':
718*cdf0e10cSrcweir 						eType = NF_SYMBOLTYPE_STRING;
719*cdf0e10cSrcweir 						eState = SsGetString;
720*cdf0e10cSrcweir 						sSymbol += cToken;
721*cdf0e10cSrcweir 					break;
722*cdf0e10cSrcweir 					case '\\':
723*cdf0e10cSrcweir 						eType = NF_SYMBOLTYPE_STRING;
724*cdf0e10cSrcweir 						eState = SsGetChar;
725*cdf0e10cSrcweir 						sSymbol += cToken;
726*cdf0e10cSrcweir 					break;
727*cdf0e10cSrcweir 					case '$':
728*cdf0e10cSrcweir 					case '+':
729*cdf0e10cSrcweir 					case '(':
730*cdf0e10cSrcweir 					case ')':
731*cdf0e10cSrcweir 						eType = NF_SYMBOLTYPE_STRING;
732*cdf0e10cSrcweir 						eState = SsStop;
733*cdf0e10cSrcweir 						sSymbol += cToken;
734*cdf0e10cSrcweir 					break;
735*cdf0e10cSrcweir 					default :
736*cdf0e10cSrcweir 					{
737*cdf0e10cSrcweir                         if (StringEqualsChar( pFormatter->GetNumDecimalSep(), cToken) ||
738*cdf0e10cSrcweir                                 StringEqualsChar( pFormatter->GetNumThousandSep(), cToken) ||
739*cdf0e10cSrcweir                                 StringEqualsChar( pFormatter->GetDateSep(), cToken) ||
740*cdf0e10cSrcweir                                 StringEqualsChar( pLoc->getTimeSep(), cToken) ||
741*cdf0e10cSrcweir                                 StringEqualsChar( pLoc->getTime100SecSep(), cToken))
742*cdf0e10cSrcweir                         {
743*cdf0e10cSrcweir                             // Another separator than pre-known ASCII
744*cdf0e10cSrcweir                             eType = NF_SYMBOLTYPE_DEL;
745*cdf0e10cSrcweir                             sSymbol += cToken;
746*cdf0e10cSrcweir                             eState = SsStop;
747*cdf0e10cSrcweir                         }
748*cdf0e10cSrcweir                         else if ( pChrCls->isLetter( rStr, nPos-1 ) )
749*cdf0e10cSrcweir 						{
750*cdf0e10cSrcweir 							short nTmpType = GetKeyWord( rStr, nPos-1 );
751*cdf0e10cSrcweir 							if ( nTmpType )
752*cdf0e10cSrcweir 							{
753*cdf0e10cSrcweir 								sal_Bool bCurrency = sal_False;
754*cdf0e10cSrcweir 								// "Automatic" currency may start with keyword,
755*cdf0e10cSrcweir 								// like "R" (Rand) and 'R' (era)
756*cdf0e10cSrcweir 								if ( nCurrPos != STRING_NOTFOUND &&
757*cdf0e10cSrcweir                                     nPos-1 + sCurString.Len() <= rStr.Len() &&
758*cdf0e10cSrcweir                                     sCurString.Search( sKeyword[nTmpType] ) == 0 )
759*cdf0e10cSrcweir 								{
760*cdf0e10cSrcweir                                     String aTest( rStr.Copy( nPos-1, sCurString.Len() ) );
761*cdf0e10cSrcweir 									pChrCls->toUpper( aTest );
762*cdf0e10cSrcweir                                     if ( aTest == sCurString )
763*cdf0e10cSrcweir 										bCurrency = sal_True;
764*cdf0e10cSrcweir 								}
765*cdf0e10cSrcweir 								if ( bCurrency )
766*cdf0e10cSrcweir 								{
767*cdf0e10cSrcweir 									eState = SsGetWord;
768*cdf0e10cSrcweir 									sSymbol += cToken;
769*cdf0e10cSrcweir 								}
770*cdf0e10cSrcweir 								else
771*cdf0e10cSrcweir 								{
772*cdf0e10cSrcweir 									eType = nTmpType;
773*cdf0e10cSrcweir 									xub_StrLen nLen = sKeyword[eType].Len();
774*cdf0e10cSrcweir 									sSymbol = rStr.Copy( nPos-1, nLen );
775*cdf0e10cSrcweir 									if ( eType == NF_KEY_E || IsAmbiguousE( eType ) )
776*cdf0e10cSrcweir 									{
777*cdf0e10cSrcweir 										sal_Unicode cNext = rStr.GetChar(nPos);
778*cdf0e10cSrcweir 										switch ( cNext )
779*cdf0e10cSrcweir 										{
780*cdf0e10cSrcweir 											case '+' :
781*cdf0e10cSrcweir 											case '-' :	// E+ E- combine to one symbol
782*cdf0e10cSrcweir 												sSymbol += cNext;
783*cdf0e10cSrcweir 												eType = NF_KEY_E;
784*cdf0e10cSrcweir 												nPos++;
785*cdf0e10cSrcweir 											break;
786*cdf0e10cSrcweir 											case '0' :
787*cdf0e10cSrcweir 											case '#' :	// scientific E without sign
788*cdf0e10cSrcweir 												eType = NF_KEY_E;
789*cdf0e10cSrcweir 											break;
790*cdf0e10cSrcweir 										}
791*cdf0e10cSrcweir 									}
792*cdf0e10cSrcweir 									nPos--;
793*cdf0e10cSrcweir 									nPos = nPos + nLen;
794*cdf0e10cSrcweir 									eState = SsStop;
795*cdf0e10cSrcweir 								}
796*cdf0e10cSrcweir 							}
797*cdf0e10cSrcweir 							else
798*cdf0e10cSrcweir 							{
799*cdf0e10cSrcweir 								eState = SsGetWord;
800*cdf0e10cSrcweir 								sSymbol += cToken;
801*cdf0e10cSrcweir 							}
802*cdf0e10cSrcweir 						}
803*cdf0e10cSrcweir 						else
804*cdf0e10cSrcweir 						{
805*cdf0e10cSrcweir 							eType = NF_SYMBOLTYPE_STRING;
806*cdf0e10cSrcweir 							eState = SsStop;
807*cdf0e10cSrcweir 							sSymbol += cToken;
808*cdf0e10cSrcweir 						}
809*cdf0e10cSrcweir 					}
810*cdf0e10cSrcweir 					break;
811*cdf0e10cSrcweir 				}
812*cdf0e10cSrcweir 			}
813*cdf0e10cSrcweir 			break;
814*cdf0e10cSrcweir 			case SsGetChar:
815*cdf0e10cSrcweir 			{
816*cdf0e10cSrcweir 				sSymbol += cToken;
817*cdf0e10cSrcweir 				eState = SsStop;
818*cdf0e10cSrcweir 			}
819*cdf0e10cSrcweir 			break;
820*cdf0e10cSrcweir 			case SsGetString:
821*cdf0e10cSrcweir 			{
822*cdf0e10cSrcweir 				if (cToken == '"')
823*cdf0e10cSrcweir 					eState = SsStop;
824*cdf0e10cSrcweir 				sSymbol += cToken;
825*cdf0e10cSrcweir 			}
826*cdf0e10cSrcweir 			break;
827*cdf0e10cSrcweir 			case SsGetWord:
828*cdf0e10cSrcweir 			{
829*cdf0e10cSrcweir 				if ( pChrCls->isLetter( rStr, nPos-1 ) )
830*cdf0e10cSrcweir 				{
831*cdf0e10cSrcweir 					short nTmpType = GetKeyWord( rStr, nPos-1 );
832*cdf0e10cSrcweir 					if ( nTmpType )
833*cdf0e10cSrcweir 					{	// beginning of keyword, stop scan and put back
834*cdf0e10cSrcweir 						eType = NF_SYMBOLTYPE_STRING;
835*cdf0e10cSrcweir 						eState = SsStop;
836*cdf0e10cSrcweir 						nPos--;
837*cdf0e10cSrcweir 					}
838*cdf0e10cSrcweir 					else
839*cdf0e10cSrcweir 						sSymbol += cToken;
840*cdf0e10cSrcweir 				}
841*cdf0e10cSrcweir 				else
842*cdf0e10cSrcweir 				{
843*cdf0e10cSrcweir 					sal_Bool bDontStop = sal_False;
844*cdf0e10cSrcweir 					switch (cToken)
845*cdf0e10cSrcweir 					{
846*cdf0e10cSrcweir 						case '/':						// AM/PM, A/P
847*cdf0e10cSrcweir 						{
848*cdf0e10cSrcweir 							sal_Unicode cNext = rStr.GetChar(nPos);
849*cdf0e10cSrcweir 							if ( cNext == 'P' || cNext == 'p' )
850*cdf0e10cSrcweir 							{
851*cdf0e10cSrcweir 								xub_StrLen nLen = sSymbol.Len();
852*cdf0e10cSrcweir 								if ( 1 <= nLen
853*cdf0e10cSrcweir 										&& (sSymbol.GetChar(0) == 'A' || sSymbol.GetChar(0) == 'a')
854*cdf0e10cSrcweir 										&& (nLen == 1 || (nLen == 2
855*cdf0e10cSrcweir 											&& (sSymbol.GetChar(1) == 'M' || sSymbol.GetChar(1) == 'm')
856*cdf0e10cSrcweir 											&& (rStr.GetChar(nPos+1) == 'M' || rStr.GetChar(nPos+1) == 'm'))) )
857*cdf0e10cSrcweir 								{
858*cdf0e10cSrcweir 									sSymbol += cToken;
859*cdf0e10cSrcweir 									bDontStop = sal_True;
860*cdf0e10cSrcweir 								}
861*cdf0e10cSrcweir 							}
862*cdf0e10cSrcweir 						}
863*cdf0e10cSrcweir 						break;
864*cdf0e10cSrcweir 					}
865*cdf0e10cSrcweir 					// anything not recognized will stop the scan
866*cdf0e10cSrcweir 					if ( eState != SsStop && !bDontStop )
867*cdf0e10cSrcweir 					{
868*cdf0e10cSrcweir 						eState = SsStop;
869*cdf0e10cSrcweir 						nPos--;
870*cdf0e10cSrcweir 						eType = NF_SYMBOLTYPE_STRING;
871*cdf0e10cSrcweir 					}
872*cdf0e10cSrcweir 				}
873*cdf0e10cSrcweir 			}
874*cdf0e10cSrcweir 			break;
875*cdf0e10cSrcweir 			case SsGetStar:
876*cdf0e10cSrcweir 			{
877*cdf0e10cSrcweir 				eState = SsStop;
878*cdf0e10cSrcweir 				sSymbol += cToken;
879*cdf0e10cSrcweir 				nRepPos = (nPos - nStart) - 1;	// everytime > 0!!
880*cdf0e10cSrcweir 			}
881*cdf0e10cSrcweir 			break;
882*cdf0e10cSrcweir 			case SsGetBlank:
883*cdf0e10cSrcweir 			{
884*cdf0e10cSrcweir 				eState = SsStop;
885*cdf0e10cSrcweir 				sSymbol += cToken;
886*cdf0e10cSrcweir 			}
887*cdf0e10cSrcweir 			break;
888*cdf0e10cSrcweir 			default:
889*cdf0e10cSrcweir 			break;
890*cdf0e10cSrcweir 		}									// of switch
891*cdf0e10cSrcweir 	} 										// of while
892*cdf0e10cSrcweir 	if (eState == SsGetWord)
893*cdf0e10cSrcweir 		eType = NF_SYMBOLTYPE_STRING;
894*cdf0e10cSrcweir 	return eType;
895*cdf0e10cSrcweir }
896*cdf0e10cSrcweir 
897*cdf0e10cSrcweir xub_StrLen ImpSvNumberformatScan::Symbol_Division(const String& rString)
898*cdf0e10cSrcweir {
899*cdf0e10cSrcweir 	nCurrPos = STRING_NOTFOUND;
900*cdf0e10cSrcweir 													// Ist Waehrung im Spiel?
901*cdf0e10cSrcweir 	String sString = pFormatter->GetCharClass()->upper(rString);
902*cdf0e10cSrcweir 	xub_StrLen nCPos = 0;
903*cdf0e10cSrcweir 	while (nCPos != STRING_NOTFOUND)
904*cdf0e10cSrcweir 	{
905*cdf0e10cSrcweir         nCPos = sString.Search(GetCurString(),nCPos);
906*cdf0e10cSrcweir 		if (nCPos != STRING_NOTFOUND)
907*cdf0e10cSrcweir 		{
908*cdf0e10cSrcweir 			// in Quotes?
909*cdf0e10cSrcweir 			xub_StrLen nQ = SvNumberformat::GetQuoteEnd( sString, nCPos );
910*cdf0e10cSrcweir 			if ( nQ == STRING_NOTFOUND )
911*cdf0e10cSrcweir 			{
912*cdf0e10cSrcweir 				sal_Unicode c;
913*cdf0e10cSrcweir 				if ( nCPos == 0 ||
914*cdf0e10cSrcweir 					((c = sString.GetChar(xub_StrLen(nCPos-1))) != '"'
915*cdf0e10cSrcweir 							&& c != '\\') )			// dm kann durch "dm
916*cdf0e10cSrcweir 				{                   				// \d geschuetzt werden
917*cdf0e10cSrcweir 					nCurrPos = nCPos;
918*cdf0e10cSrcweir 					nCPos = STRING_NOTFOUND;		// Abbruch
919*cdf0e10cSrcweir 				}
920*cdf0e10cSrcweir 				else
921*cdf0e10cSrcweir 					nCPos++;						// weitersuchen
922*cdf0e10cSrcweir 			}
923*cdf0e10cSrcweir 			else
924*cdf0e10cSrcweir 				nCPos = nQ + 1;						// weitersuchen
925*cdf0e10cSrcweir 		}
926*cdf0e10cSrcweir 	}
927*cdf0e10cSrcweir 	nAnzStrings = 0;
928*cdf0e10cSrcweir 	sal_Bool bStar = sal_False;					// wird bei '*'Detektion gesetzt
929*cdf0e10cSrcweir 	Reset();
930*cdf0e10cSrcweir 
931*cdf0e10cSrcweir 	xub_StrLen nPos = 0;
932*cdf0e10cSrcweir 	const xub_StrLen nLen = rString.Len();
933*cdf0e10cSrcweir 	while (nPos < nLen && nAnzStrings < NF_MAX_FORMAT_SYMBOLS)
934*cdf0e10cSrcweir 	{
935*cdf0e10cSrcweir 		nTypeArray[nAnzStrings] = Next_Symbol(rString, nPos, sStrArray[nAnzStrings]);
936*cdf0e10cSrcweir 		if (nTypeArray[nAnzStrings] == NF_SYMBOLTYPE_STAR)
937*cdf0e10cSrcweir 		{								// Ueberwachung des '*'
938*cdf0e10cSrcweir 			if (bStar)
939*cdf0e10cSrcweir 				return nPos;		// Fehler: doppelter '*'
940*cdf0e10cSrcweir 			else
941*cdf0e10cSrcweir 				bStar = sal_True;
942*cdf0e10cSrcweir 		}
943*cdf0e10cSrcweir 		nAnzStrings++;
944*cdf0e10cSrcweir 	}
945*cdf0e10cSrcweir 
946*cdf0e10cSrcweir 	return 0;						// 0 => ok
947*cdf0e10cSrcweir }
948*cdf0e10cSrcweir 
949*cdf0e10cSrcweir void ImpSvNumberformatScan::SkipStrings(sal_uInt16& i, xub_StrLen& nPos)
950*cdf0e10cSrcweir {
951*cdf0e10cSrcweir 	while (i < nAnzStrings && (   nTypeArray[i] == NF_SYMBOLTYPE_STRING
952*cdf0e10cSrcweir 							   || nTypeArray[i] == NF_SYMBOLTYPE_BLANK
953*cdf0e10cSrcweir 							   || nTypeArray[i] == NF_SYMBOLTYPE_STAR) )
954*cdf0e10cSrcweir 	{
955*cdf0e10cSrcweir 		nPos = nPos + sStrArray[i].Len();
956*cdf0e10cSrcweir 		i++;
957*cdf0e10cSrcweir 	}
958*cdf0e10cSrcweir }
959*cdf0e10cSrcweir 
960*cdf0e10cSrcweir 
961*cdf0e10cSrcweir sal_uInt16 ImpSvNumberformatScan::PreviousKeyword(sal_uInt16 i)
962*cdf0e10cSrcweir {
963*cdf0e10cSrcweir 	short res = 0;
964*cdf0e10cSrcweir 	if (i > 0 && i < nAnzStrings)
965*cdf0e10cSrcweir 	{
966*cdf0e10cSrcweir 		i--;
967*cdf0e10cSrcweir 		while (i > 0 && nTypeArray[i] <= 0)
968*cdf0e10cSrcweir 			i--;
969*cdf0e10cSrcweir 		if (nTypeArray[i] > 0)
970*cdf0e10cSrcweir 			res = nTypeArray[i];
971*cdf0e10cSrcweir 	}
972*cdf0e10cSrcweir 	return res;
973*cdf0e10cSrcweir }
974*cdf0e10cSrcweir 
975*cdf0e10cSrcweir sal_uInt16 ImpSvNumberformatScan::NextKeyword(sal_uInt16 i)
976*cdf0e10cSrcweir {
977*cdf0e10cSrcweir 	short res = 0;
978*cdf0e10cSrcweir 	if (i < nAnzStrings-1)
979*cdf0e10cSrcweir 	{
980*cdf0e10cSrcweir 		i++;
981*cdf0e10cSrcweir 		while (i < nAnzStrings-1 && nTypeArray[i] <= 0)
982*cdf0e10cSrcweir 			i++;
983*cdf0e10cSrcweir 		if (nTypeArray[i] > 0)
984*cdf0e10cSrcweir 			res = nTypeArray[i];
985*cdf0e10cSrcweir 	}
986*cdf0e10cSrcweir 	return res;
987*cdf0e10cSrcweir }
988*cdf0e10cSrcweir 
989*cdf0e10cSrcweir short ImpSvNumberformatScan::PreviousType( sal_uInt16 i )
990*cdf0e10cSrcweir {
991*cdf0e10cSrcweir 	if ( i > 0 && i < nAnzStrings )
992*cdf0e10cSrcweir 	{
993*cdf0e10cSrcweir 		do
994*cdf0e10cSrcweir 		{
995*cdf0e10cSrcweir 			i--;
996*cdf0e10cSrcweir 		} while ( i > 0 && nTypeArray[i] == NF_SYMBOLTYPE_EMPTY );
997*cdf0e10cSrcweir 		return nTypeArray[i];
998*cdf0e10cSrcweir 	}
999*cdf0e10cSrcweir 	return 0;
1000*cdf0e10cSrcweir }
1001*cdf0e10cSrcweir 
1002*cdf0e10cSrcweir sal_Unicode ImpSvNumberformatScan::PreviousChar(sal_uInt16 i)
1003*cdf0e10cSrcweir {
1004*cdf0e10cSrcweir 	sal_Unicode res = ' ';
1005*cdf0e10cSrcweir 	if (i > 0 && i < nAnzStrings)
1006*cdf0e10cSrcweir 	{
1007*cdf0e10cSrcweir 		i--;
1008*cdf0e10cSrcweir 		while (i > 0 && ( 	nTypeArray[i] == NF_SYMBOLTYPE_EMPTY
1009*cdf0e10cSrcweir 						 || nTypeArray[i] == NF_SYMBOLTYPE_STRING
1010*cdf0e10cSrcweir 						 || nTypeArray[i] == NF_SYMBOLTYPE_STAR
1011*cdf0e10cSrcweir 						 || nTypeArray[i] == NF_SYMBOLTYPE_BLANK ) )
1012*cdf0e10cSrcweir 			i--;
1013*cdf0e10cSrcweir 		if (sStrArray[i].Len() > 0)
1014*cdf0e10cSrcweir 			res = sStrArray[i].GetChar(xub_StrLen(sStrArray[i].Len()-1));
1015*cdf0e10cSrcweir 	}
1016*cdf0e10cSrcweir 	return res;
1017*cdf0e10cSrcweir }
1018*cdf0e10cSrcweir 
1019*cdf0e10cSrcweir sal_Unicode ImpSvNumberformatScan::NextChar(sal_uInt16 i)
1020*cdf0e10cSrcweir {
1021*cdf0e10cSrcweir 	sal_Unicode res = ' ';
1022*cdf0e10cSrcweir 	if (i < nAnzStrings-1)
1023*cdf0e10cSrcweir 	{
1024*cdf0e10cSrcweir 		i++;
1025*cdf0e10cSrcweir 		while (i < nAnzStrings-1 &&
1026*cdf0e10cSrcweir 			   (   nTypeArray[i] == NF_SYMBOLTYPE_EMPTY
1027*cdf0e10cSrcweir 				|| nTypeArray[i] == NF_SYMBOLTYPE_STRING
1028*cdf0e10cSrcweir 				|| nTypeArray[i] == NF_SYMBOLTYPE_STAR
1029*cdf0e10cSrcweir 				|| nTypeArray[i] == NF_SYMBOLTYPE_BLANK))
1030*cdf0e10cSrcweir 			i++;
1031*cdf0e10cSrcweir 		if (sStrArray[i].Len() > 0)
1032*cdf0e10cSrcweir 			res = sStrArray[i].GetChar(0);
1033*cdf0e10cSrcweir 	}
1034*cdf0e10cSrcweir 	return res;
1035*cdf0e10cSrcweir }
1036*cdf0e10cSrcweir 
1037*cdf0e10cSrcweir sal_Bool ImpSvNumberformatScan::IsLastBlankBeforeFrac(sal_uInt16 i)
1038*cdf0e10cSrcweir {
1039*cdf0e10cSrcweir 	sal_Bool res = sal_True;
1040*cdf0e10cSrcweir 	if (i < nAnzStrings-1)
1041*cdf0e10cSrcweir 	{
1042*cdf0e10cSrcweir 		sal_Bool bStop = sal_False;
1043*cdf0e10cSrcweir 		i++;
1044*cdf0e10cSrcweir 		while (i < nAnzStrings-1 && !bStop)
1045*cdf0e10cSrcweir 		{
1046*cdf0e10cSrcweir 			i++;
1047*cdf0e10cSrcweir 			if ( nTypeArray[i] == NF_SYMBOLTYPE_DEL &&
1048*cdf0e10cSrcweir 					sStrArray[i].GetChar(0) == '/')
1049*cdf0e10cSrcweir 				bStop = sal_True;
1050*cdf0e10cSrcweir 			else if ( nTypeArray[i] == NF_SYMBOLTYPE_DEL &&
1051*cdf0e10cSrcweir 					sStrArray[i].GetChar(0) == ' ')
1052*cdf0e10cSrcweir 				res = sal_False;
1053*cdf0e10cSrcweir 		}
1054*cdf0e10cSrcweir 		if (!bStop)									// kein '/'
1055*cdf0e10cSrcweir 			res = sal_False;
1056*cdf0e10cSrcweir 	}
1057*cdf0e10cSrcweir 	else
1058*cdf0e10cSrcweir 		res = sal_False;								// kein '/' mehr
1059*cdf0e10cSrcweir 
1060*cdf0e10cSrcweir 	return res;
1061*cdf0e10cSrcweir }
1062*cdf0e10cSrcweir 
1063*cdf0e10cSrcweir void ImpSvNumberformatScan::Reset()
1064*cdf0e10cSrcweir {
1065*cdf0e10cSrcweir 	nAnzStrings = 0;
1066*cdf0e10cSrcweir 	nAnzResStrings = 0;
1067*cdf0e10cSrcweir #if 0
1068*cdf0e10cSrcweir // ER 20.06.97 14:05   nicht noetig, wenn nAnzStrings beachtet wird
1069*cdf0e10cSrcweir 	for (size_t i = 0; i < NF_MAX_FORMAT_SYMBOLS; i++)
1070*cdf0e10cSrcweir 	{
1071*cdf0e10cSrcweir 		sStrArray[i].Erase();
1072*cdf0e10cSrcweir 		nTypeArray[i] = 0;
1073*cdf0e10cSrcweir 	}
1074*cdf0e10cSrcweir #endif
1075*cdf0e10cSrcweir 	eScannedType = NUMBERFORMAT_UNDEFINED;
1076*cdf0e10cSrcweir 	nRepPos = 0;
1077*cdf0e10cSrcweir 	bExp = sal_False;
1078*cdf0e10cSrcweir 	bThousand = sal_False;
1079*cdf0e10cSrcweir 	nThousand = 0;
1080*cdf0e10cSrcweir 	bDecSep = sal_False;
1081*cdf0e10cSrcweir 	nDecPos =  -1;
1082*cdf0e10cSrcweir 	nExpPos = (sal_uInt16) -1;
1083*cdf0e10cSrcweir 	nBlankPos = (sal_uInt16) -1;
1084*cdf0e10cSrcweir 	nCntPre = 0;
1085*cdf0e10cSrcweir 	nCntPost = 0;
1086*cdf0e10cSrcweir 	nCntExp = 0;
1087*cdf0e10cSrcweir 	bFrac = sal_False;
1088*cdf0e10cSrcweir 	bBlank = sal_False;
1089*cdf0e10cSrcweir     nNatNumModifier = 0;
1090*cdf0e10cSrcweir }
1091*cdf0e10cSrcweir 
1092*cdf0e10cSrcweir 
1093*cdf0e10cSrcweir sal_Bool ImpSvNumberformatScan::Is100SecZero( sal_uInt16 i, sal_Bool bHadDecSep )
1094*cdf0e10cSrcweir {
1095*cdf0e10cSrcweir     sal_uInt16 nIndexPre = PreviousKeyword( i );
1096*cdf0e10cSrcweir     return (nIndexPre == NF_KEY_S || nIndexPre == NF_KEY_SS)
1097*cdf0e10cSrcweir             && (bHadDecSep                 // S, SS ','
1098*cdf0e10cSrcweir             || (i>0 && nTypeArray[i-1] == NF_SYMBOLTYPE_STRING));
1099*cdf0e10cSrcweir                 // SS"any"00  take "any" as a valid decimal separator
1100*cdf0e10cSrcweir }
1101*cdf0e10cSrcweir 
1102*cdf0e10cSrcweir 
1103*cdf0e10cSrcweir xub_StrLen ImpSvNumberformatScan::ScanType(const String&)
1104*cdf0e10cSrcweir {
1105*cdf0e10cSrcweir 	const LocaleDataWrapper* pLoc = pFormatter->GetLocaleData();
1106*cdf0e10cSrcweir 
1107*cdf0e10cSrcweir 	xub_StrLen nPos = 0;
1108*cdf0e10cSrcweir     sal_uInt16 i = 0;
1109*cdf0e10cSrcweir     short eNewType;
1110*cdf0e10cSrcweir     sal_Bool bMatchBracket = sal_False;
1111*cdf0e10cSrcweir     bool bHaveGeneral = false;      // if General/Standard encountered
1112*cdf0e10cSrcweir 
1113*cdf0e10cSrcweir     SkipStrings(i, nPos);
1114*cdf0e10cSrcweir 	while (i < nAnzStrings)
1115*cdf0e10cSrcweir 	{
1116*cdf0e10cSrcweir         if (nTypeArray[i] > 0)
1117*cdf0e10cSrcweir         {                                       // keyword
1118*cdf0e10cSrcweir 			switch (nTypeArray[i])
1119*cdf0e10cSrcweir 			{
1120*cdf0e10cSrcweir 				case NF_KEY_E:			 				// E
1121*cdf0e10cSrcweir 					eNewType = NUMBERFORMAT_SCIENTIFIC;
1122*cdf0e10cSrcweir 				break;
1123*cdf0e10cSrcweir 				case NF_KEY_AMPM:		 				// AM,A,PM,P
1124*cdf0e10cSrcweir 				case NF_KEY_AP:
1125*cdf0e10cSrcweir 				case NF_KEY_H:							// H
1126*cdf0e10cSrcweir 				case NF_KEY_HH:							// HH
1127*cdf0e10cSrcweir 				case NF_KEY_S:							// S
1128*cdf0e10cSrcweir 				case NF_KEY_SS:							// SS
1129*cdf0e10cSrcweir 					eNewType = NUMBERFORMAT_TIME;
1130*cdf0e10cSrcweir 				break;
1131*cdf0e10cSrcweir 				case NF_KEY_M:			 				// M
1132*cdf0e10cSrcweir 				case NF_KEY_MM:			 				// MM
1133*cdf0e10cSrcweir                 {                                       // minute or month
1134*cdf0e10cSrcweir 					sal_uInt16 nIndexPre = PreviousKeyword(i);
1135*cdf0e10cSrcweir 					sal_uInt16 nIndexNex = NextKeyword(i);
1136*cdf0e10cSrcweir 					sal_Unicode cChar = PreviousChar(i);
1137*cdf0e10cSrcweir 					if (nIndexPre == NF_KEY_H	|| 	// H
1138*cdf0e10cSrcweir 						nIndexPre == NF_KEY_HH	|| 	// HH
1139*cdf0e10cSrcweir 						nIndexNex == NF_KEY_S	|| 	// S
1140*cdf0e10cSrcweir 						nIndexNex == NF_KEY_SS	||  // SS
1141*cdf0e10cSrcweir 						cChar == '['  )     // [M
1142*cdf0e10cSrcweir 					{
1143*cdf0e10cSrcweir 						eNewType = NUMBERFORMAT_TIME;
1144*cdf0e10cSrcweir 						nTypeArray[i] -= 2;			// 6 -> 4, 7 -> 5
1145*cdf0e10cSrcweir 					}
1146*cdf0e10cSrcweir 					else
1147*cdf0e10cSrcweir 						eNewType = NUMBERFORMAT_DATE;
1148*cdf0e10cSrcweir 				}
1149*cdf0e10cSrcweir 				break;
1150*cdf0e10cSrcweir 				case NF_KEY_MMM:				// MMM
1151*cdf0e10cSrcweir 				case NF_KEY_MMMM:				// MMMM
1152*cdf0e10cSrcweir 				case NF_KEY_MMMMM:				// MMMMM
1153*cdf0e10cSrcweir 				case NF_KEY_Q:					// Q
1154*cdf0e10cSrcweir 				case NF_KEY_QQ:					// QQ
1155*cdf0e10cSrcweir 				case NF_KEY_D:					// D
1156*cdf0e10cSrcweir 				case NF_KEY_DD:					// DD
1157*cdf0e10cSrcweir 				case NF_KEY_DDD:				// DDD
1158*cdf0e10cSrcweir 				case NF_KEY_DDDD:				// DDDD
1159*cdf0e10cSrcweir 				case NF_KEY_YY:					// YY
1160*cdf0e10cSrcweir 				case NF_KEY_YYYY:				// YYYY
1161*cdf0e10cSrcweir 				case NF_KEY_NN:					// NN
1162*cdf0e10cSrcweir 				case NF_KEY_NNN:				// NNN
1163*cdf0e10cSrcweir 				case NF_KEY_NNNN:				// NNNN
1164*cdf0e10cSrcweir 				case NF_KEY_WW :				// WW
1165*cdf0e10cSrcweir 				case NF_KEY_AAA :				// AAA
1166*cdf0e10cSrcweir 				case NF_KEY_AAAA :				// AAAA
1167*cdf0e10cSrcweir 				case NF_KEY_EC :				// E
1168*cdf0e10cSrcweir 				case NF_KEY_EEC :				// EE
1169*cdf0e10cSrcweir 				case NF_KEY_G :					// G
1170*cdf0e10cSrcweir 				case NF_KEY_GG :				// GG
1171*cdf0e10cSrcweir 				case NF_KEY_GGG :				// GGG
1172*cdf0e10cSrcweir 				case NF_KEY_R :					// R
1173*cdf0e10cSrcweir 				case NF_KEY_RR :				// RR
1174*cdf0e10cSrcweir 					eNewType = NUMBERFORMAT_DATE;
1175*cdf0e10cSrcweir 				break;
1176*cdf0e10cSrcweir 				case NF_KEY_CCC:				// CCC
1177*cdf0e10cSrcweir 					eNewType = NUMBERFORMAT_CURRENCY;
1178*cdf0e10cSrcweir 				break;
1179*cdf0e10cSrcweir 				case NF_KEY_GENERAL:			// Standard
1180*cdf0e10cSrcweir 					eNewType = NUMBERFORMAT_NUMBER;
1181*cdf0e10cSrcweir                     bHaveGeneral = true;
1182*cdf0e10cSrcweir 				break;
1183*cdf0e10cSrcweir 				default:
1184*cdf0e10cSrcweir 					eNewType = NUMBERFORMAT_UNDEFINED;
1185*cdf0e10cSrcweir 				break;
1186*cdf0e10cSrcweir 			}
1187*cdf0e10cSrcweir 		}
1188*cdf0e10cSrcweir         else
1189*cdf0e10cSrcweir         {                                       // control character
1190*cdf0e10cSrcweir 			switch ( sStrArray[i].GetChar(0) )
1191*cdf0e10cSrcweir 			{
1192*cdf0e10cSrcweir 				case '#':
1193*cdf0e10cSrcweir 				case '?':
1194*cdf0e10cSrcweir 					eNewType = NUMBERFORMAT_NUMBER;
1195*cdf0e10cSrcweir 				break;
1196*cdf0e10cSrcweir 				case '0':
1197*cdf0e10cSrcweir 				{
1198*cdf0e10cSrcweir                     if ( (eScannedType & NUMBERFORMAT_TIME) == NUMBERFORMAT_TIME )
1199*cdf0e10cSrcweir 					{
1200*cdf0e10cSrcweir                         if ( Is100SecZero( i, bDecSep ) )
1201*cdf0e10cSrcweir                         {
1202*cdf0e10cSrcweir                             bDecSep = sal_True;                 // subsequent 0's
1203*cdf0e10cSrcweir 							eNewType = NUMBERFORMAT_TIME;
1204*cdf0e10cSrcweir                         }
1205*cdf0e10cSrcweir 						else
1206*cdf0e10cSrcweir                             return nPos;                    // Error
1207*cdf0e10cSrcweir 					}
1208*cdf0e10cSrcweir 					else
1209*cdf0e10cSrcweir 						eNewType = NUMBERFORMAT_NUMBER;
1210*cdf0e10cSrcweir 				}
1211*cdf0e10cSrcweir 				break;
1212*cdf0e10cSrcweir 				case '%':
1213*cdf0e10cSrcweir 					eNewType = NUMBERFORMAT_PERCENT;
1214*cdf0e10cSrcweir 				break;
1215*cdf0e10cSrcweir 				case '/':
1216*cdf0e10cSrcweir 					eNewType = NUMBERFORMAT_FRACTION;
1217*cdf0e10cSrcweir 				break;
1218*cdf0e10cSrcweir 				case '[':
1219*cdf0e10cSrcweir 				{
1220*cdf0e10cSrcweir 					if ( i < nAnzStrings-1 &&
1221*cdf0e10cSrcweir 							nTypeArray[i+1] == NF_SYMBOLTYPE_STRING &&
1222*cdf0e10cSrcweir 							sStrArray[i+1].GetChar(0) == '$' )
1223*cdf0e10cSrcweir 					{	// as of SV_NUMBERFORMATTER_VERSION_NEW_CURR
1224*cdf0e10cSrcweir 						eNewType = NUMBERFORMAT_CURRENCY;
1225*cdf0e10cSrcweir                         bMatchBracket = sal_True;
1226*cdf0e10cSrcweir 					}
1227*cdf0e10cSrcweir 					else if ( i < nAnzStrings-1 &&
1228*cdf0e10cSrcweir 							nTypeArray[i+1] == NF_SYMBOLTYPE_STRING &&
1229*cdf0e10cSrcweir 							sStrArray[i+1].GetChar(0) == '~' )
1230*cdf0e10cSrcweir 					{	// as of SV_NUMBERFORMATTER_VERSION_CALENDAR
1231*cdf0e10cSrcweir 						eNewType = NUMBERFORMAT_DATE;
1232*cdf0e10cSrcweir                         bMatchBracket = sal_True;
1233*cdf0e10cSrcweir 					}
1234*cdf0e10cSrcweir 					else
1235*cdf0e10cSrcweir 					{
1236*cdf0e10cSrcweir 						sal_uInt16 nIndexNex = NextKeyword(i);
1237*cdf0e10cSrcweir 						if (nIndexNex == NF_KEY_H	|| 	// H
1238*cdf0e10cSrcweir 							nIndexNex == NF_KEY_HH	|| 	// HH
1239*cdf0e10cSrcweir 							nIndexNex == NF_KEY_M	|| 	// M
1240*cdf0e10cSrcweir 							nIndexNex == NF_KEY_MM	|| 	// MM
1241*cdf0e10cSrcweir 							nIndexNex == NF_KEY_S	|| 	// S
1242*cdf0e10cSrcweir 							nIndexNex == NF_KEY_SS   )	// SS
1243*cdf0e10cSrcweir 							eNewType = NUMBERFORMAT_TIME;
1244*cdf0e10cSrcweir 						else
1245*cdf0e10cSrcweir                             return nPos;                // Error
1246*cdf0e10cSrcweir 					}
1247*cdf0e10cSrcweir 				}
1248*cdf0e10cSrcweir 				break;
1249*cdf0e10cSrcweir 				case '@':
1250*cdf0e10cSrcweir 					eNewType = NUMBERFORMAT_TEXT;
1251*cdf0e10cSrcweir 				break;
1252*cdf0e10cSrcweir 				default:
1253*cdf0e10cSrcweir                     if ( sStrArray[i] == pLoc->getTime100SecSep() )
1254*cdf0e10cSrcweir                         bDecSep = sal_True;                     // for SS,0
1255*cdf0e10cSrcweir                     eNewType = NUMBERFORMAT_UNDEFINED;
1256*cdf0e10cSrcweir 				break;
1257*cdf0e10cSrcweir 			}
1258*cdf0e10cSrcweir 		}
1259*cdf0e10cSrcweir 		if (eScannedType == NUMBERFORMAT_UNDEFINED)
1260*cdf0e10cSrcweir 			eScannedType = eNewType;
1261*cdf0e10cSrcweir 		else if (eScannedType == NUMBERFORMAT_TEXT || eNewType == NUMBERFORMAT_TEXT)
1262*cdf0e10cSrcweir 			eScannedType = NUMBERFORMAT_TEXT;				// Text bleibt immer Text
1263*cdf0e10cSrcweir 		else if (eNewType == NUMBERFORMAT_UNDEFINED)
1264*cdf0e10cSrcweir 		{											// bleibt wie bisher
1265*cdf0e10cSrcweir 		}
1266*cdf0e10cSrcweir 		else if (eScannedType != eNewType)
1267*cdf0e10cSrcweir 		{
1268*cdf0e10cSrcweir 			switch (eScannedType)
1269*cdf0e10cSrcweir 			{
1270*cdf0e10cSrcweir 				case NUMBERFORMAT_DATE:
1271*cdf0e10cSrcweir 				{
1272*cdf0e10cSrcweir 					switch (eNewType)
1273*cdf0e10cSrcweir 					{
1274*cdf0e10cSrcweir 						case NUMBERFORMAT_TIME:
1275*cdf0e10cSrcweir 							eScannedType = NUMBERFORMAT_DATETIME;
1276*cdf0e10cSrcweir 						break;
1277*cdf0e10cSrcweir 						case NUMBERFORMAT_FRACTION: 		// DD/MM
1278*cdf0e10cSrcweir 						break;
1279*cdf0e10cSrcweir 						default:
1280*cdf0e10cSrcweir 						{
1281*cdf0e10cSrcweir 							if (nCurrPos != STRING_NOTFOUND)
1282*cdf0e10cSrcweir 								eScannedType = NUMBERFORMAT_UNDEFINED;
1283*cdf0e10cSrcweir                             else if ( sStrArray[i] != pFormatter->GetDateSep() )
1284*cdf0e10cSrcweir 								return nPos;
1285*cdf0e10cSrcweir 						}
1286*cdf0e10cSrcweir 					}
1287*cdf0e10cSrcweir 				}
1288*cdf0e10cSrcweir 				break;
1289*cdf0e10cSrcweir 				case NUMBERFORMAT_TIME:
1290*cdf0e10cSrcweir 				{
1291*cdf0e10cSrcweir 					switch (eNewType)
1292*cdf0e10cSrcweir 					{
1293*cdf0e10cSrcweir 						case NUMBERFORMAT_DATE:
1294*cdf0e10cSrcweir 							eScannedType = NUMBERFORMAT_DATETIME;
1295*cdf0e10cSrcweir 						break;
1296*cdf0e10cSrcweir 						case NUMBERFORMAT_FRACTION: 		// MM/SS
1297*cdf0e10cSrcweir 						break;
1298*cdf0e10cSrcweir 						default:
1299*cdf0e10cSrcweir 						{
1300*cdf0e10cSrcweir 							if (nCurrPos != STRING_NOTFOUND)
1301*cdf0e10cSrcweir 								eScannedType = NUMBERFORMAT_UNDEFINED;
1302*cdf0e10cSrcweir 							else if ( sStrArray[i] != pLoc->getTimeSep() )
1303*cdf0e10cSrcweir 								return nPos;
1304*cdf0e10cSrcweir 						}
1305*cdf0e10cSrcweir 					}
1306*cdf0e10cSrcweir 				}
1307*cdf0e10cSrcweir 				break;
1308*cdf0e10cSrcweir 				case NUMBERFORMAT_DATETIME:
1309*cdf0e10cSrcweir 				{
1310*cdf0e10cSrcweir 					switch (eNewType)
1311*cdf0e10cSrcweir 					{
1312*cdf0e10cSrcweir 						case NUMBERFORMAT_TIME:
1313*cdf0e10cSrcweir 						case NUMBERFORMAT_DATE:
1314*cdf0e10cSrcweir 						break;
1315*cdf0e10cSrcweir 						case NUMBERFORMAT_FRACTION: 		// DD/MM
1316*cdf0e10cSrcweir 						break;
1317*cdf0e10cSrcweir 						default:
1318*cdf0e10cSrcweir 						{
1319*cdf0e10cSrcweir 							if (nCurrPos != STRING_NOTFOUND)
1320*cdf0e10cSrcweir 								eScannedType = NUMBERFORMAT_UNDEFINED;
1321*cdf0e10cSrcweir                             else if ( sStrArray[i] != pFormatter->GetDateSep()
1322*cdf0e10cSrcweir 								   && sStrArray[i] != pLoc->getTimeSep() )
1323*cdf0e10cSrcweir 								return nPos;
1324*cdf0e10cSrcweir 						}
1325*cdf0e10cSrcweir 					}
1326*cdf0e10cSrcweir 				}
1327*cdf0e10cSrcweir 				break;
1328*cdf0e10cSrcweir 				case NUMBERFORMAT_PERCENT:
1329*cdf0e10cSrcweir 				{
1330*cdf0e10cSrcweir 					switch (eNewType)
1331*cdf0e10cSrcweir 					{
1332*cdf0e10cSrcweir 						case NUMBERFORMAT_NUMBER:	// nur Zahl nach Prozent
1333*cdf0e10cSrcweir 						break;
1334*cdf0e10cSrcweir 						default:
1335*cdf0e10cSrcweir 							return nPos;
1336*cdf0e10cSrcweir 					}
1337*cdf0e10cSrcweir 				}
1338*cdf0e10cSrcweir 				break;
1339*cdf0e10cSrcweir 				case NUMBERFORMAT_SCIENTIFIC:
1340*cdf0e10cSrcweir 				{
1341*cdf0e10cSrcweir 					switch (eNewType)
1342*cdf0e10cSrcweir 					{
1343*cdf0e10cSrcweir 						case NUMBERFORMAT_NUMBER:	// nur Zahl nach E
1344*cdf0e10cSrcweir 						break;
1345*cdf0e10cSrcweir 						default:
1346*cdf0e10cSrcweir 							return nPos;
1347*cdf0e10cSrcweir 					}
1348*cdf0e10cSrcweir 				}
1349*cdf0e10cSrcweir 				break;
1350*cdf0e10cSrcweir 				case NUMBERFORMAT_NUMBER:
1351*cdf0e10cSrcweir 				{
1352*cdf0e10cSrcweir 					switch (eNewType)
1353*cdf0e10cSrcweir 					{
1354*cdf0e10cSrcweir 						case NUMBERFORMAT_SCIENTIFIC:
1355*cdf0e10cSrcweir 						case NUMBERFORMAT_PERCENT:
1356*cdf0e10cSrcweir 						case NUMBERFORMAT_FRACTION:
1357*cdf0e10cSrcweir 						case NUMBERFORMAT_CURRENCY:
1358*cdf0e10cSrcweir 							eScannedType = eNewType;
1359*cdf0e10cSrcweir 						break;
1360*cdf0e10cSrcweir 						default:
1361*cdf0e10cSrcweir 							if (nCurrPos != STRING_NOTFOUND)
1362*cdf0e10cSrcweir 								eScannedType = NUMBERFORMAT_UNDEFINED;
1363*cdf0e10cSrcweir 							else
1364*cdf0e10cSrcweir 								return nPos;
1365*cdf0e10cSrcweir 					}
1366*cdf0e10cSrcweir 				}
1367*cdf0e10cSrcweir 				break;
1368*cdf0e10cSrcweir 				case NUMBERFORMAT_FRACTION:
1369*cdf0e10cSrcweir 				{
1370*cdf0e10cSrcweir 					switch (eNewType)
1371*cdf0e10cSrcweir 					{
1372*cdf0e10cSrcweir 						case NUMBERFORMAT_NUMBER:			// nur Zahl nach Bruch
1373*cdf0e10cSrcweir 						break;
1374*cdf0e10cSrcweir 						default:
1375*cdf0e10cSrcweir 							return nPos;
1376*cdf0e10cSrcweir 					}
1377*cdf0e10cSrcweir 				}
1378*cdf0e10cSrcweir 				break;
1379*cdf0e10cSrcweir 				default:
1380*cdf0e10cSrcweir 				break;
1381*cdf0e10cSrcweir 			}
1382*cdf0e10cSrcweir 		}
1383*cdf0e10cSrcweir 		nPos = nPos + sStrArray[i].Len();			// Korrekturposition
1384*cdf0e10cSrcweir 		i++;
1385*cdf0e10cSrcweir         if ( bMatchBracket )
1386*cdf0e10cSrcweir         {   // no type detection inside of matching brackets if [$...], [~...]
1387*cdf0e10cSrcweir             while ( bMatchBracket && i < nAnzStrings )
1388*cdf0e10cSrcweir             {
1389*cdf0e10cSrcweir                 if ( nTypeArray[i] == NF_SYMBOLTYPE_DEL
1390*cdf0e10cSrcweir                         && sStrArray[i].GetChar(0) == ']' )
1391*cdf0e10cSrcweir                     bMatchBracket = sal_False;
1392*cdf0e10cSrcweir                 else
1393*cdf0e10cSrcweir                     nTypeArray[i] = NF_SYMBOLTYPE_STRING;
1394*cdf0e10cSrcweir                 nPos = nPos + sStrArray[i].Len();
1395*cdf0e10cSrcweir                 i++;
1396*cdf0e10cSrcweir             }
1397*cdf0e10cSrcweir             if ( bMatchBracket )
1398*cdf0e10cSrcweir                 return nPos;    // missing closing bracket at end of code
1399*cdf0e10cSrcweir         }
1400*cdf0e10cSrcweir 		SkipStrings(i, nPos);
1401*cdf0e10cSrcweir 	}
1402*cdf0e10cSrcweir 
1403*cdf0e10cSrcweir 	if ((eScannedType == NUMBERFORMAT_NUMBER || eScannedType == NUMBERFORMAT_UNDEFINED)
1404*cdf0e10cSrcweir 		 && nCurrPos != STRING_NOTFOUND && !bHaveGeneral)
1405*cdf0e10cSrcweir 		eScannedType = NUMBERFORMAT_CURRENCY;	// old "automatic" currency
1406*cdf0e10cSrcweir 	if (eScannedType == NUMBERFORMAT_UNDEFINED)
1407*cdf0e10cSrcweir 		eScannedType = NUMBERFORMAT_DEFINED;
1408*cdf0e10cSrcweir 	return 0;								// Alles ok
1409*cdf0e10cSrcweir }
1410*cdf0e10cSrcweir 
1411*cdf0e10cSrcweir 
1412*cdf0e10cSrcweir bool ImpSvNumberformatScan::InsertSymbol( sal_uInt16 & nPos, svt::NfSymbolType eType, const String& rStr )
1413*cdf0e10cSrcweir {
1414*cdf0e10cSrcweir     if (nAnzStrings >= NF_MAX_FORMAT_SYMBOLS || nPos > nAnzStrings)
1415*cdf0e10cSrcweir         return false;
1416*cdf0e10cSrcweir     ++nAnzResStrings;
1417*cdf0e10cSrcweir     if (nPos > 0 && nTypeArray[nPos-1] == NF_SYMBOLTYPE_EMPTY)
1418*cdf0e10cSrcweir         --nPos;     // reuse position
1419*cdf0e10cSrcweir     else
1420*cdf0e10cSrcweir     {
1421*cdf0e10cSrcweir         ++nAnzStrings;
1422*cdf0e10cSrcweir         for (size_t i = nAnzStrings; i > nPos; --i)
1423*cdf0e10cSrcweir         {
1424*cdf0e10cSrcweir             nTypeArray[i] = nTypeArray[i-1];
1425*cdf0e10cSrcweir             sStrArray[i] = sStrArray[i-1];
1426*cdf0e10cSrcweir         }
1427*cdf0e10cSrcweir     }
1428*cdf0e10cSrcweir     nTypeArray[nPos] = static_cast<short>(eType);
1429*cdf0e10cSrcweir     sStrArray[nPos] = rStr;
1430*cdf0e10cSrcweir     return true;
1431*cdf0e10cSrcweir }
1432*cdf0e10cSrcweir 
1433*cdf0e10cSrcweir 
1434*cdf0e10cSrcweir int ImpSvNumberformatScan::FinalScanGetCalendar( xub_StrLen& nPos, sal_uInt16& i,
1435*cdf0e10cSrcweir 			sal_uInt16& rAnzResStrings )
1436*cdf0e10cSrcweir {
1437*cdf0e10cSrcweir 	if ( sStrArray[i].GetChar(0) == '[' &&
1438*cdf0e10cSrcweir 			i < nAnzStrings-1 &&
1439*cdf0e10cSrcweir 			nTypeArray[i+1] == NF_SYMBOLTYPE_STRING &&
1440*cdf0e10cSrcweir 			sStrArray[i+1].GetChar(0) == '~' )
1441*cdf0e10cSrcweir 	{	// [~calendarID]
1442*cdf0e10cSrcweir 		// as of SV_NUMBERFORMATTER_VERSION_CALENDAR
1443*cdf0e10cSrcweir 		nPos = nPos + sStrArray[i].Len();			// [
1444*cdf0e10cSrcweir 		nTypeArray[i] = NF_SYMBOLTYPE_CALDEL;
1445*cdf0e10cSrcweir 		nPos = nPos + sStrArray[++i].Len();		// ~
1446*cdf0e10cSrcweir 		sStrArray[i-1] += sStrArray[i];		// [~
1447*cdf0e10cSrcweir 		nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
1448*cdf0e10cSrcweir 		rAnzResStrings--;
1449*cdf0e10cSrcweir 		if ( ++i >= nAnzStrings )
1450*cdf0e10cSrcweir 			return -1;		// error
1451*cdf0e10cSrcweir 		nPos = nPos + sStrArray[i].Len();			// calendarID
1452*cdf0e10cSrcweir 		String& rStr = sStrArray[i];
1453*cdf0e10cSrcweir 		nTypeArray[i] = NF_SYMBOLTYPE_CALENDAR;	// convert
1454*cdf0e10cSrcweir 		i++;
1455*cdf0e10cSrcweir 		while ( i < nAnzStrings &&
1456*cdf0e10cSrcweir 				sStrArray[i].GetChar(0) != ']' )
1457*cdf0e10cSrcweir 		{
1458*cdf0e10cSrcweir 			nPos = nPos + sStrArray[i].Len();
1459*cdf0e10cSrcweir 			rStr += sStrArray[i];
1460*cdf0e10cSrcweir 			nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
1461*cdf0e10cSrcweir 			rAnzResStrings--;
1462*cdf0e10cSrcweir 			i++;
1463*cdf0e10cSrcweir 		}
1464*cdf0e10cSrcweir 		if ( rStr.Len() && i < nAnzStrings &&
1465*cdf0e10cSrcweir 				sStrArray[i].GetChar(0) == ']' )
1466*cdf0e10cSrcweir 		{
1467*cdf0e10cSrcweir 			nTypeArray[i] = NF_SYMBOLTYPE_CALDEL;
1468*cdf0e10cSrcweir 			nPos = nPos + sStrArray[i].Len();
1469*cdf0e10cSrcweir 			i++;
1470*cdf0e10cSrcweir 		}
1471*cdf0e10cSrcweir 		else
1472*cdf0e10cSrcweir 			return -1;		// error
1473*cdf0e10cSrcweir 		return 1;
1474*cdf0e10cSrcweir 	}
1475*cdf0e10cSrcweir 	return 0;
1476*cdf0e10cSrcweir }
1477*cdf0e10cSrcweir 
1478*cdf0e10cSrcweir xub_StrLen ImpSvNumberformatScan::FinalScan( String& rString, String& rComment )
1479*cdf0e10cSrcweir {
1480*cdf0e10cSrcweir 	const LocaleDataWrapper* pLoc = pFormatter->GetLocaleData();
1481*cdf0e10cSrcweir 
1482*cdf0e10cSrcweir 	// save values for convert mode
1483*cdf0e10cSrcweir     String sOldDecSep       = pFormatter->GetNumDecimalSep();
1484*cdf0e10cSrcweir     String sOldThousandSep  = pFormatter->GetNumThousandSep();
1485*cdf0e10cSrcweir     String sOldDateSep      = pFormatter->GetDateSep();
1486*cdf0e10cSrcweir 	String sOldTimeSep		= pLoc->getTimeSep();
1487*cdf0e10cSrcweir     String sOldTime100SecSep= pLoc->getTime100SecSep();
1488*cdf0e10cSrcweir     String sOldCurSymbol    = GetCurSymbol();
1489*cdf0e10cSrcweir     String sOldCurString    = GetCurString();
1490*cdf0e10cSrcweir     sal_Unicode cOldKeyH    = sKeyword[NF_KEY_H].GetChar(0);
1491*cdf0e10cSrcweir     sal_Unicode cOldKeyMI   = sKeyword[NF_KEY_MI].GetChar(0);
1492*cdf0e10cSrcweir     sal_Unicode cOldKeyS    = sKeyword[NF_KEY_S].GetChar(0);
1493*cdf0e10cSrcweir 
1494*cdf0e10cSrcweir 	// If the group separator is a Non-Breaking Space (French) continue with a
1495*cdf0e10cSrcweir 	// normal space instead so queries on space work correctly.
1496*cdf0e10cSrcweir 	// The format string is adjusted to allow both.
1497*cdf0e10cSrcweir 	// For output of the format code string the LocaleData characters are used.
1498*cdf0e10cSrcweir 	if ( sOldThousandSep.GetChar(0) == cNonBreakingSpace && sOldThousandSep.Len() == 1 )
1499*cdf0e10cSrcweir 		sOldThousandSep = ' ';
1500*cdf0e10cSrcweir 
1501*cdf0e10cSrcweir 	// change locale data et al
1502*cdf0e10cSrcweir 	if (bConvertMode)
1503*cdf0e10cSrcweir     {
1504*cdf0e10cSrcweir 		pFormatter->ChangeIntl(eNewLnge);
1505*cdf0e10cSrcweir         //! pointer may have changed
1506*cdf0e10cSrcweir         pLoc = pFormatter->GetLocaleData();
1507*cdf0e10cSrcweir         //! init new keywords
1508*cdf0e10cSrcweir         InitKeywords();
1509*cdf0e10cSrcweir     }
1510*cdf0e10cSrcweir 	const CharClass* pChrCls = pFormatter->GetCharClass();
1511*cdf0e10cSrcweir 
1512*cdf0e10cSrcweir     xub_StrLen nPos = 0;                    // error correction position
1513*cdf0e10cSrcweir     sal_uInt16 i = 0;                           // symbol loop counter
1514*cdf0e10cSrcweir     sal_uInt16 nCounter = 0;                    // counts digits
1515*cdf0e10cSrcweir     nAnzResStrings = nAnzStrings;           // counts remaining symbols
1516*cdf0e10cSrcweir     bDecSep = sal_False;                        // reset in case already used in TypeCheck
1517*cdf0e10cSrcweir     bool bThaiT = false;                    // Thai T NatNum modifier present
1518*cdf0e10cSrcweir 
1519*cdf0e10cSrcweir 	switch (eScannedType)
1520*cdf0e10cSrcweir 	{
1521*cdf0e10cSrcweir 		case NUMBERFORMAT_TEXT:
1522*cdf0e10cSrcweir 		case NUMBERFORMAT_DEFINED:
1523*cdf0e10cSrcweir 		{
1524*cdf0e10cSrcweir 			while (i < nAnzStrings)
1525*cdf0e10cSrcweir 			{
1526*cdf0e10cSrcweir 				switch (nTypeArray[i])
1527*cdf0e10cSrcweir 				{
1528*cdf0e10cSrcweir 					case NF_SYMBOLTYPE_BLANK:
1529*cdf0e10cSrcweir 					case NF_SYMBOLTYPE_STAR:
1530*cdf0e10cSrcweir 					break;
1531*cdf0e10cSrcweir 					case NF_SYMBOLTYPE_COMMENT:
1532*cdf0e10cSrcweir 					{
1533*cdf0e10cSrcweir 						String& rStr = sStrArray[i];
1534*cdf0e10cSrcweir 						nPos = nPos + rStr.Len();
1535*cdf0e10cSrcweir 						SvNumberformat::EraseCommentBraces( rStr );
1536*cdf0e10cSrcweir 						rComment += rStr;
1537*cdf0e10cSrcweir 						nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
1538*cdf0e10cSrcweir 						nAnzResStrings--;
1539*cdf0e10cSrcweir 					}
1540*cdf0e10cSrcweir 					break;
1541*cdf0e10cSrcweir 					case NF_KEY_GENERAL :	// #77026# "General" is the same as "@"
1542*cdf0e10cSrcweir 					break;
1543*cdf0e10cSrcweir 					default:
1544*cdf0e10cSrcweir 					{
1545*cdf0e10cSrcweir 						if ( nTypeArray[i] != NF_SYMBOLTYPE_DEL ||
1546*cdf0e10cSrcweir 								sStrArray[i].GetChar(0) != '@' )
1547*cdf0e10cSrcweir 							nTypeArray[i] = NF_SYMBOLTYPE_STRING;
1548*cdf0e10cSrcweir 					}
1549*cdf0e10cSrcweir 					break;
1550*cdf0e10cSrcweir 				}
1551*cdf0e10cSrcweir 				nPos = nPos + sStrArray[i].Len();
1552*cdf0e10cSrcweir 				i++;
1553*cdf0e10cSrcweir 			}										// of while
1554*cdf0e10cSrcweir 		}
1555*cdf0e10cSrcweir 		break;
1556*cdf0e10cSrcweir 		case NUMBERFORMAT_NUMBER:
1557*cdf0e10cSrcweir 		case NUMBERFORMAT_PERCENT:
1558*cdf0e10cSrcweir 		case NUMBERFORMAT_CURRENCY:
1559*cdf0e10cSrcweir 		case NUMBERFORMAT_SCIENTIFIC:
1560*cdf0e10cSrcweir 		case NUMBERFORMAT_FRACTION:
1561*cdf0e10cSrcweir 		{
1562*cdf0e10cSrcweir 			sal_Unicode cThousandFill = ' ';
1563*cdf0e10cSrcweir 			while (i < nAnzStrings)
1564*cdf0e10cSrcweir 			{
1565*cdf0e10cSrcweir 				if (eScannedType == NUMBERFORMAT_FRACTION &&  	// special case
1566*cdf0e10cSrcweir 					nTypeArray[i] == NF_SYMBOLTYPE_DEL && 			// # ### #/#
1567*cdf0e10cSrcweir 					StringEqualsChar( sOldThousandSep, ' ' ) && // e.g. France or Sweden
1568*cdf0e10cSrcweir 					StringEqualsChar( sStrArray[i], ' ' ) &&
1569*cdf0e10cSrcweir 					!bFrac                          &&
1570*cdf0e10cSrcweir 					IsLastBlankBeforeFrac(i) )
1571*cdf0e10cSrcweir 				{
1572*cdf0e10cSrcweir 					nTypeArray[i] = NF_SYMBOLTYPE_STRING;			// del->string
1573*cdf0e10cSrcweir 				}                                               // kein Taus.p.
1574*cdf0e10cSrcweir 
1575*cdf0e10cSrcweir 
1576*cdf0e10cSrcweir 				if (nTypeArray[i] == NF_SYMBOLTYPE_BLANK	||
1577*cdf0e10cSrcweir 					nTypeArray[i] == NF_SYMBOLTYPE_STAR	||
1578*cdf0e10cSrcweir 					nTypeArray[i] == NF_KEY_CCC			||	// CCC
1579*cdf0e10cSrcweir 					nTypeArray[i] == NF_KEY_GENERAL )		// Standard
1580*cdf0e10cSrcweir 				{
1581*cdf0e10cSrcweir 					if (nTypeArray[i] == NF_KEY_GENERAL)
1582*cdf0e10cSrcweir 					{
1583*cdf0e10cSrcweir 						nThousand = FLAG_STANDARD_IN_FORMAT;
1584*cdf0e10cSrcweir 						if ( bConvertMode )
1585*cdf0e10cSrcweir 							sStrArray[i] = sNameStandardFormat;
1586*cdf0e10cSrcweir 					}
1587*cdf0e10cSrcweir 					nPos = nPos + sStrArray[i].Len();
1588*cdf0e10cSrcweir 					i++;
1589*cdf0e10cSrcweir 				}
1590*cdf0e10cSrcweir 				else if (nTypeArray[i] == NF_SYMBOLTYPE_STRING ||  // Strings oder
1591*cdf0e10cSrcweir 						 nTypeArray[i] > 0) 					// Keywords
1592*cdf0e10cSrcweir 				{
1593*cdf0e10cSrcweir 					if (eScannedType == NUMBERFORMAT_SCIENTIFIC &&
1594*cdf0e10cSrcweir 							 nTypeArray[i] == NF_KEY_E) 		// E+
1595*cdf0e10cSrcweir 					{
1596*cdf0e10cSrcweir 						if (bExp) 								// doppelt
1597*cdf0e10cSrcweir 							return nPos;
1598*cdf0e10cSrcweir 						bExp = sal_True;
1599*cdf0e10cSrcweir 						nExpPos = i;
1600*cdf0e10cSrcweir 						if (bDecSep)
1601*cdf0e10cSrcweir 							nCntPost = nCounter;
1602*cdf0e10cSrcweir 						else
1603*cdf0e10cSrcweir 							nCntPre = nCounter;
1604*cdf0e10cSrcweir 						nCounter = 0;
1605*cdf0e10cSrcweir 						nTypeArray[i] = NF_SYMBOLTYPE_EXP;
1606*cdf0e10cSrcweir 					}
1607*cdf0e10cSrcweir 					else if (eScannedType == NUMBERFORMAT_FRACTION &&
1608*cdf0e10cSrcweir 							 sStrArray[i].GetChar(0) == ' ')
1609*cdf0e10cSrcweir 					{
1610*cdf0e10cSrcweir 						if (!bBlank && !bFrac)	// nicht doppelt oder hinter /
1611*cdf0e10cSrcweir 						{
1612*cdf0e10cSrcweir 							if (bDecSep && nCounter > 0)	// Nachkommastellen
1613*cdf0e10cSrcweir 								return nPos;				// Fehler
1614*cdf0e10cSrcweir 							bBlank = sal_True;
1615*cdf0e10cSrcweir 							nBlankPos = i;
1616*cdf0e10cSrcweir 							nCntPre = nCounter;
1617*cdf0e10cSrcweir 							nCounter = 0;
1618*cdf0e10cSrcweir 						}
1619*cdf0e10cSrcweir 						nTypeArray[i] = NF_SYMBOLTYPE_FRACBLANK;
1620*cdf0e10cSrcweir 					}
1621*cdf0e10cSrcweir                     else if (nTypeArray[i] == NF_KEY_THAI_T)
1622*cdf0e10cSrcweir                     {
1623*cdf0e10cSrcweir                         bThaiT = true;
1624*cdf0e10cSrcweir                         sStrArray[i] = sKeyword[nTypeArray[i]];
1625*cdf0e10cSrcweir                     }
1626*cdf0e10cSrcweir 					else
1627*cdf0e10cSrcweir 						nTypeArray[i] = NF_SYMBOLTYPE_STRING;
1628*cdf0e10cSrcweir 					nPos = nPos + sStrArray[i].Len();
1629*cdf0e10cSrcweir 					i++;
1630*cdf0e10cSrcweir 				}
1631*cdf0e10cSrcweir 				else if (nTypeArray[i] == NF_SYMBOLTYPE_DEL)
1632*cdf0e10cSrcweir 				{
1633*cdf0e10cSrcweir 					sal_Unicode cHere = sStrArray[i].GetChar(0);
1634*cdf0e10cSrcweir                     // Handle not pre-known separators in switch.
1635*cdf0e10cSrcweir                     sal_Unicode cSimplified;
1636*cdf0e10cSrcweir                     if (StringEqualsChar( pFormatter->GetNumThousandSep(), cHere))
1637*cdf0e10cSrcweir                         cSimplified = ',';
1638*cdf0e10cSrcweir                     else if (StringEqualsChar( pFormatter->GetNumDecimalSep(), cHere))
1639*cdf0e10cSrcweir                         cSimplified = '.';
1640*cdf0e10cSrcweir                     else
1641*cdf0e10cSrcweir                         cSimplified = cHere;
1642*cdf0e10cSrcweir 					switch ( cSimplified )
1643*cdf0e10cSrcweir 					{
1644*cdf0e10cSrcweir 						case '#':
1645*cdf0e10cSrcweir 						case '0':
1646*cdf0e10cSrcweir 						case '?':
1647*cdf0e10cSrcweir 						{
1648*cdf0e10cSrcweir 							if (nThousand > 0)					// #... #
1649*cdf0e10cSrcweir 								return nPos;					// Fehler
1650*cdf0e10cSrcweir 							else if (bFrac && cHere == '0')
1651*cdf0e10cSrcweir 								return nPos;					// 0 im Nenner
1652*cdf0e10cSrcweir 							nTypeArray[i] = NF_SYMBOLTYPE_DIGIT;
1653*cdf0e10cSrcweir 							String& rStr = sStrArray[i];
1654*cdf0e10cSrcweir 							nPos = nPos + rStr.Len();
1655*cdf0e10cSrcweir 							i++;
1656*cdf0e10cSrcweir 							nCounter++;
1657*cdf0e10cSrcweir 							while (i < nAnzStrings &&
1658*cdf0e10cSrcweir 								(sStrArray[i].GetChar(0) == '#' ||
1659*cdf0e10cSrcweir 									sStrArray[i].GetChar(0) == '0' ||
1660*cdf0e10cSrcweir 									sStrArray[i].GetChar(0) == '?')
1661*cdf0e10cSrcweir 								)
1662*cdf0e10cSrcweir 							{
1663*cdf0e10cSrcweir 								nTypeArray[i] = NF_SYMBOLTYPE_DIGIT;
1664*cdf0e10cSrcweir 								nPos = nPos + sStrArray[i].Len();
1665*cdf0e10cSrcweir 								nCounter++;
1666*cdf0e10cSrcweir 								i++;
1667*cdf0e10cSrcweir 							}
1668*cdf0e10cSrcweir 						}
1669*cdf0e10cSrcweir 						break;
1670*cdf0e10cSrcweir 						case '-':
1671*cdf0e10cSrcweir 						{
1672*cdf0e10cSrcweir                             if ( bDecSep && nDecPos+1 == i &&
1673*cdf0e10cSrcweir 									nTypeArray[nDecPos] == NF_SYMBOLTYPE_DECSEP )
1674*cdf0e10cSrcweir                             {   // "0.--"
1675*cdf0e10cSrcweir 								nTypeArray[i] = NF_SYMBOLTYPE_DIGIT;
1676*cdf0e10cSrcweir 								String& rStr = sStrArray[i];
1677*cdf0e10cSrcweir 								nPos = nPos + rStr.Len();
1678*cdf0e10cSrcweir 								i++;
1679*cdf0e10cSrcweir 								nCounter++;
1680*cdf0e10cSrcweir 								while (i < nAnzStrings &&
1681*cdf0e10cSrcweir 										(sStrArray[i].GetChar(0) == '-') )
1682*cdf0e10cSrcweir 								{
1683*cdf0e10cSrcweir                                     // If more than two dashes are present in
1684*cdf0e10cSrcweir                                     // currency formats the last dash will be
1685*cdf0e10cSrcweir                                     // interpreted literally as a minus sign.
1686*cdf0e10cSrcweir                                     // Has to be this ugly. Period.
1687*cdf0e10cSrcweir                                     if ( eScannedType == NUMBERFORMAT_CURRENCY
1688*cdf0e10cSrcweir                                             && rStr.Len() >= 2 &&
1689*cdf0e10cSrcweir                                             (i == nAnzStrings-1 ||
1690*cdf0e10cSrcweir                                             sStrArray[i+1].GetChar(0) != '-') )
1691*cdf0e10cSrcweir                                         break;
1692*cdf0e10cSrcweir 									rStr += sStrArray[i];
1693*cdf0e10cSrcweir 									nPos = nPos + sStrArray[i].Len();
1694*cdf0e10cSrcweir 									nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
1695*cdf0e10cSrcweir 									nAnzResStrings--;
1696*cdf0e10cSrcweir 									nCounter++;
1697*cdf0e10cSrcweir 									i++;
1698*cdf0e10cSrcweir 								}
1699*cdf0e10cSrcweir 							}
1700*cdf0e10cSrcweir 							else
1701*cdf0e10cSrcweir 							{
1702*cdf0e10cSrcweir 								nTypeArray[i] = NF_SYMBOLTYPE_STRING;
1703*cdf0e10cSrcweir 								nPos = nPos + sStrArray[i].Len();
1704*cdf0e10cSrcweir 								i++;
1705*cdf0e10cSrcweir 							}
1706*cdf0e10cSrcweir 						}
1707*cdf0e10cSrcweir 						break;
1708*cdf0e10cSrcweir 						case '.':
1709*cdf0e10cSrcweir 						case ',':
1710*cdf0e10cSrcweir 						case '\'':
1711*cdf0e10cSrcweir 						case ' ':
1712*cdf0e10cSrcweir 						{
1713*cdf0e10cSrcweir 							sal_Unicode cSep = cHere;	// remember
1714*cdf0e10cSrcweir 							if ( StringEqualsChar( sOldThousandSep, cSep ) )
1715*cdf0e10cSrcweir 							{
1716*cdf0e10cSrcweir 								// previous char with skip empty
1717*cdf0e10cSrcweir 								sal_Unicode cPre = PreviousChar(i);
1718*cdf0e10cSrcweir 								sal_Unicode cNext;
1719*cdf0e10cSrcweir 								if (bExp || bBlank || bFrac)
1720*cdf0e10cSrcweir 								{	// after E, / or ' '
1721*cdf0e10cSrcweir 									if ( !StringEqualsChar( sOldThousandSep, ' ' ) )
1722*cdf0e10cSrcweir 									{
1723*cdf0e10cSrcweir 										nPos = nPos + sStrArray[i].Len();
1724*cdf0e10cSrcweir 										nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
1725*cdf0e10cSrcweir 										nAnzResStrings--;
1726*cdf0e10cSrcweir 										i++; 				// eat it
1727*cdf0e10cSrcweir 									}
1728*cdf0e10cSrcweir 									else
1729*cdf0e10cSrcweir 										nTypeArray[i] = NF_SYMBOLTYPE_STRING;
1730*cdf0e10cSrcweir 								}
1731*cdf0e10cSrcweir 								else if (i > 0 && i < nAnzStrings-1   &&
1732*cdf0e10cSrcweir 									(cPre == '#' || cPre == '0')      &&
1733*cdf0e10cSrcweir 									((cNext = NextChar(i)) == '#' || cNext == '0')
1734*cdf0e10cSrcweir 									)					// #,#
1735*cdf0e10cSrcweir 								{
1736*cdf0e10cSrcweir 									nPos = nPos + sStrArray[i].Len();
1737*cdf0e10cSrcweir 									if (!bThousand)					// only once
1738*cdf0e10cSrcweir                                     {
1739*cdf0e10cSrcweir 										bThousand = sal_True;
1740*cdf0e10cSrcweir 										cThousandFill = sStrArray[i+1].GetChar(0);
1741*cdf0e10cSrcweir 									}
1742*cdf0e10cSrcweir                                     // Eat it, will be reinserted at proper
1743*cdf0e10cSrcweir                                     // grouping positions further down.
1744*cdf0e10cSrcweir                                     nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
1745*cdf0e10cSrcweir                                     nAnzResStrings--;
1746*cdf0e10cSrcweir 									i++;
1747*cdf0e10cSrcweir 								}
1748*cdf0e10cSrcweir 								else if (i > 0 && (cPre == '#' || cPre == '0')
1749*cdf0e10cSrcweir 									&& PreviousType(i) == NF_SYMBOLTYPE_DIGIT
1750*cdf0e10cSrcweir 									&& nThousand < FLAG_STANDARD_IN_FORMAT )
1751*cdf0e10cSrcweir 								{									// #,,,,
1752*cdf0e10cSrcweir 									if ( StringEqualsChar( sOldThousandSep, ' ' ) )
1753*cdf0e10cSrcweir 									{	// strange, those French..
1754*cdf0e10cSrcweir 										sal_Bool bFirst = sal_True;
1755*cdf0e10cSrcweir 										String& rStr = sStrArray[i];
1756*cdf0e10cSrcweir                                         //  set a hard Non-Breaking Space or ConvertMode
1757*cdf0e10cSrcweir                                         const String& rSepF = pFormatter->GetNumThousandSep();
1758*cdf0e10cSrcweir 										while ( i < nAnzStrings
1759*cdf0e10cSrcweir 											&& sStrArray[i] == sOldThousandSep
1760*cdf0e10cSrcweir 											&& StringEqualsChar( sOldThousandSep, NextChar(i) ) )
1761*cdf0e10cSrcweir 										{	// last was a space or another space
1762*cdf0e10cSrcweir 											// is following => separator
1763*cdf0e10cSrcweir 											nPos = nPos + sStrArray[i].Len();
1764*cdf0e10cSrcweir 											if ( bFirst )
1765*cdf0e10cSrcweir 											{
1766*cdf0e10cSrcweir 												bFirst = sal_False;
1767*cdf0e10cSrcweir 												rStr = rSepF;
1768*cdf0e10cSrcweir 												nTypeArray[i] = NF_SYMBOLTYPE_THSEP;
1769*cdf0e10cSrcweir 											}
1770*cdf0e10cSrcweir 											else
1771*cdf0e10cSrcweir 											{
1772*cdf0e10cSrcweir 												rStr += rSepF;
1773*cdf0e10cSrcweir 												nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
1774*cdf0e10cSrcweir 												nAnzResStrings--;
1775*cdf0e10cSrcweir 											}
1776*cdf0e10cSrcweir 											nThousand++;
1777*cdf0e10cSrcweir 											i++;
1778*cdf0e10cSrcweir 										}
1779*cdf0e10cSrcweir 										if ( i < nAnzStrings-1
1780*cdf0e10cSrcweir 											&& sStrArray[i] == sOldThousandSep )
1781*cdf0e10cSrcweir 										{	// something following last space
1782*cdf0e10cSrcweir 											// => space if currency contained,
1783*cdf0e10cSrcweir 											// else separator
1784*cdf0e10cSrcweir 											nPos = nPos + sStrArray[i].Len();
1785*cdf0e10cSrcweir 											if ( (nPos <= nCurrPos &&
1786*cdf0e10cSrcweir 													nCurrPos < nPos + sStrArray[i+1].Len())
1787*cdf0e10cSrcweir 												|| nTypeArray[i+1] == NF_KEY_CCC
1788*cdf0e10cSrcweir 												|| (i < nAnzStrings-2 &&
1789*cdf0e10cSrcweir 												sStrArray[i+1].GetChar(0) == '[' &&
1790*cdf0e10cSrcweir 												sStrArray[i+2].GetChar(0) == '$') )
1791*cdf0e10cSrcweir 											{
1792*cdf0e10cSrcweir 												nTypeArray[i] = NF_SYMBOLTYPE_STRING;
1793*cdf0e10cSrcweir 											}
1794*cdf0e10cSrcweir 											else
1795*cdf0e10cSrcweir 											{
1796*cdf0e10cSrcweir 												if ( bFirst )
1797*cdf0e10cSrcweir 												{
1798*cdf0e10cSrcweir 													bFirst = sal_False;
1799*cdf0e10cSrcweir 													rStr = rSepF;
1800*cdf0e10cSrcweir 													nTypeArray[i] = NF_SYMBOLTYPE_THSEP;
1801*cdf0e10cSrcweir 												}
1802*cdf0e10cSrcweir 												else
1803*cdf0e10cSrcweir 												{
1804*cdf0e10cSrcweir 													rStr += rSepF;
1805*cdf0e10cSrcweir 													nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
1806*cdf0e10cSrcweir 													nAnzResStrings--;
1807*cdf0e10cSrcweir 												}
1808*cdf0e10cSrcweir 												nThousand++;
1809*cdf0e10cSrcweir 											}
1810*cdf0e10cSrcweir 											i++;
1811*cdf0e10cSrcweir 										}
1812*cdf0e10cSrcweir 									}
1813*cdf0e10cSrcweir 									else
1814*cdf0e10cSrcweir 									{
1815*cdf0e10cSrcweir                                         do
1816*cdf0e10cSrcweir                                         {
1817*cdf0e10cSrcweir                                             nThousand++;
1818*cdf0e10cSrcweir                                             nTypeArray[i] = NF_SYMBOLTYPE_THSEP;
1819*cdf0e10cSrcweir                                             nPos = nPos + sStrArray[i].Len();
1820*cdf0e10cSrcweir                                             sStrArray[i] = pFormatter->GetNumThousandSep();
1821*cdf0e10cSrcweir                                             i++;
1822*cdf0e10cSrcweir                                         } while (i < nAnzStrings &&
1823*cdf0e10cSrcweir                                                 sStrArray[i] == sOldThousandSep);
1824*cdf0e10cSrcweir 									}
1825*cdf0e10cSrcweir 								}
1826*cdf0e10cSrcweir 								else 					// any grsep
1827*cdf0e10cSrcweir 								{
1828*cdf0e10cSrcweir 									nTypeArray[i] = NF_SYMBOLTYPE_STRING;
1829*cdf0e10cSrcweir 									String& rStr = sStrArray[i];
1830*cdf0e10cSrcweir 									nPos = nPos + rStr.Len();
1831*cdf0e10cSrcweir 									i++;
1832*cdf0e10cSrcweir 									while ( i < nAnzStrings &&
1833*cdf0e10cSrcweir 										sStrArray[i] == sOldThousandSep )
1834*cdf0e10cSrcweir 									{
1835*cdf0e10cSrcweir 										rStr += sStrArray[i];
1836*cdf0e10cSrcweir 										nPos = nPos + sStrArray[i].Len();
1837*cdf0e10cSrcweir 										nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
1838*cdf0e10cSrcweir 										nAnzResStrings--;
1839*cdf0e10cSrcweir 										i++;
1840*cdf0e10cSrcweir 									}
1841*cdf0e10cSrcweir 								}
1842*cdf0e10cSrcweir 							}
1843*cdf0e10cSrcweir 							else if ( StringEqualsChar( sOldDecSep, cSep ) )
1844*cdf0e10cSrcweir 							{
1845*cdf0e10cSrcweir 								if (bBlank || bFrac)    // . behind / or ' '
1846*cdf0e10cSrcweir 									return nPos;		// error
1847*cdf0e10cSrcweir 								else if (bExp)			// behind E
1848*cdf0e10cSrcweir 								{
1849*cdf0e10cSrcweir 									nPos = nPos + sStrArray[i].Len();
1850*cdf0e10cSrcweir 									nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
1851*cdf0e10cSrcweir 									nAnzResStrings--;
1852*cdf0e10cSrcweir 									i++; 				// eat it
1853*cdf0e10cSrcweir 								}
1854*cdf0e10cSrcweir 								else if (bDecSep)		// any .
1855*cdf0e10cSrcweir 								{
1856*cdf0e10cSrcweir 									nTypeArray[i] = NF_SYMBOLTYPE_STRING;
1857*cdf0e10cSrcweir 									String& rStr = sStrArray[i];
1858*cdf0e10cSrcweir 									nPos = nPos + rStr.Len();
1859*cdf0e10cSrcweir 									i++;
1860*cdf0e10cSrcweir 									while ( i < nAnzStrings &&
1861*cdf0e10cSrcweir 										sStrArray[i] == sOldDecSep )
1862*cdf0e10cSrcweir 									{
1863*cdf0e10cSrcweir 										rStr += sStrArray[i];
1864*cdf0e10cSrcweir 										nPos = nPos + sStrArray[i].Len();
1865*cdf0e10cSrcweir 										nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
1866*cdf0e10cSrcweir 										nAnzResStrings--;
1867*cdf0e10cSrcweir 										i++;
1868*cdf0e10cSrcweir 									}
1869*cdf0e10cSrcweir 								}
1870*cdf0e10cSrcweir 								else
1871*cdf0e10cSrcweir 								{
1872*cdf0e10cSrcweir 									nPos = nPos + sStrArray[i].Len();
1873*cdf0e10cSrcweir 									nTypeArray[i] = NF_SYMBOLTYPE_DECSEP;
1874*cdf0e10cSrcweir                                     sStrArray[i] = pFormatter->GetNumDecimalSep();
1875*cdf0e10cSrcweir 									bDecSep = sal_True;
1876*cdf0e10cSrcweir 									nDecPos = i;
1877*cdf0e10cSrcweir 									nCntPre = nCounter;
1878*cdf0e10cSrcweir 									nCounter = 0;
1879*cdf0e10cSrcweir 
1880*cdf0e10cSrcweir 									i++;
1881*cdf0e10cSrcweir 								}
1882*cdf0e10cSrcweir 							} 							// of else = DecSep
1883*cdf0e10cSrcweir 							else						// . without meaning
1884*cdf0e10cSrcweir 							{
1885*cdf0e10cSrcweir 								if (cSep == ' ' &&
1886*cdf0e10cSrcweir 									eScannedType == NUMBERFORMAT_FRACTION &&
1887*cdf0e10cSrcweir 									StringEqualsChar( sStrArray[i], ' ' ) )
1888*cdf0e10cSrcweir 								{
1889*cdf0e10cSrcweir 									if (!bBlank && !bFrac)	// no dups
1890*cdf0e10cSrcweir 									{	                    // or behind /
1891*cdf0e10cSrcweir 										if (bDecSep && nCounter > 0)// dec.
1892*cdf0e10cSrcweir 											return nPos;			// error
1893*cdf0e10cSrcweir 										bBlank = sal_True;
1894*cdf0e10cSrcweir 										nBlankPos = i;
1895*cdf0e10cSrcweir 										nCntPre = nCounter;
1896*cdf0e10cSrcweir 										nCounter = 0;
1897*cdf0e10cSrcweir 									}
1898*cdf0e10cSrcweir 									nTypeArray[i] = NF_SYMBOLTYPE_STRING;
1899*cdf0e10cSrcweir 									nPos = nPos + sStrArray[i].Len();
1900*cdf0e10cSrcweir 								}
1901*cdf0e10cSrcweir 								else
1902*cdf0e10cSrcweir 								{
1903*cdf0e10cSrcweir 									nTypeArray[i] = NF_SYMBOLTYPE_STRING;
1904*cdf0e10cSrcweir 									String& rStr = sStrArray[i];
1905*cdf0e10cSrcweir 									nPos = nPos + rStr.Len();
1906*cdf0e10cSrcweir 									i++;
1907*cdf0e10cSrcweir 									while (i < nAnzStrings &&
1908*cdf0e10cSrcweir 										StringEqualsChar( sStrArray[i], cSep ) )
1909*cdf0e10cSrcweir 									{
1910*cdf0e10cSrcweir 										rStr += sStrArray[i];
1911*cdf0e10cSrcweir 										nPos = nPos + sStrArray[i].Len();
1912*cdf0e10cSrcweir 										nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
1913*cdf0e10cSrcweir 										nAnzResStrings--;
1914*cdf0e10cSrcweir 										i++;
1915*cdf0e10cSrcweir 									}
1916*cdf0e10cSrcweir 								}
1917*cdf0e10cSrcweir 							}
1918*cdf0e10cSrcweir 						}
1919*cdf0e10cSrcweir 						break;
1920*cdf0e10cSrcweir 						case '/':
1921*cdf0e10cSrcweir 						{
1922*cdf0e10cSrcweir 							if (eScannedType == NUMBERFORMAT_FRACTION)
1923*cdf0e10cSrcweir 							{
1924*cdf0e10cSrcweir 								if ( i == 0 ||
1925*cdf0e10cSrcweir 										(nTypeArray[i-1] != NF_SYMBOLTYPE_DIGIT &&
1926*cdf0e10cSrcweir 									 	nTypeArray[i-1] != NF_SYMBOLTYPE_EMPTY) )
1927*cdf0e10cSrcweir 									return nPos ? nPos : 1;	// /? not allowed
1928*cdf0e10cSrcweir 								else if (!bFrac || (bDecSep && nCounter > 0))
1929*cdf0e10cSrcweir 								{
1930*cdf0e10cSrcweir 									bFrac = sal_True;
1931*cdf0e10cSrcweir 									nCntPost = nCounter;
1932*cdf0e10cSrcweir 									nCounter = 0;
1933*cdf0e10cSrcweir 									nTypeArray[i] = NF_SYMBOLTYPE_FRAC;
1934*cdf0e10cSrcweir 									nPos = nPos + sStrArray[i].Len();
1935*cdf0e10cSrcweir 									i++;
1936*cdf0e10cSrcweir 								}
1937*cdf0e10cSrcweir 								else 				// / doppelt od. , imZaehl
1938*cdf0e10cSrcweir 									return nPos;	// Fehler
1939*cdf0e10cSrcweir 							}
1940*cdf0e10cSrcweir 							else
1941*cdf0e10cSrcweir 							{
1942*cdf0e10cSrcweir 								nTypeArray[i] = NF_SYMBOLTYPE_STRING;
1943*cdf0e10cSrcweir 								nPos = nPos + sStrArray[i].Len();
1944*cdf0e10cSrcweir 								i++;
1945*cdf0e10cSrcweir 							}
1946*cdf0e10cSrcweir 						}
1947*cdf0e10cSrcweir 						break;
1948*cdf0e10cSrcweir 						case '[' :
1949*cdf0e10cSrcweir 						{
1950*cdf0e10cSrcweir 							if ( eScannedType == NUMBERFORMAT_CURRENCY &&
1951*cdf0e10cSrcweir 									i < nAnzStrings-1 &&
1952*cdf0e10cSrcweir 									nTypeArray[i+1] == NF_SYMBOLTYPE_STRING &&
1953*cdf0e10cSrcweir 									sStrArray[i+1].GetChar(0) == '$' )
1954*cdf0e10cSrcweir 							{	// [$DM-xxx]
1955*cdf0e10cSrcweir 								// ab SV_NUMBERFORMATTER_VERSION_NEW_CURR
1956*cdf0e10cSrcweir 								nPos = nPos + sStrArray[i].Len();			// [
1957*cdf0e10cSrcweir 								nTypeArray[i] = NF_SYMBOLTYPE_CURRDEL;
1958*cdf0e10cSrcweir 								nPos = nPos + sStrArray[++i].Len();		// $
1959*cdf0e10cSrcweir 								sStrArray[i-1] += sStrArray[i];		// [$
1960*cdf0e10cSrcweir 								nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
1961*cdf0e10cSrcweir 								nAnzResStrings--;
1962*cdf0e10cSrcweir 								if ( ++i >= nAnzStrings )
1963*cdf0e10cSrcweir 									return nPos;		// Fehler
1964*cdf0e10cSrcweir 								nPos = nPos + sStrArray[i].Len();			// DM
1965*cdf0e10cSrcweir 								String& rStr = sStrArray[i];
1966*cdf0e10cSrcweir 								String* pStr = &sStrArray[i];
1967*cdf0e10cSrcweir 								nTypeArray[i] = NF_SYMBOLTYPE_CURRENCY;	// wandeln
1968*cdf0e10cSrcweir 								sal_Bool bHadDash = sal_False;
1969*cdf0e10cSrcweir 								i++;
1970*cdf0e10cSrcweir 								while ( i < nAnzStrings &&
1971*cdf0e10cSrcweir 										sStrArray[i].GetChar(0) != ']' )
1972*cdf0e10cSrcweir 								{
1973*cdf0e10cSrcweir 									nPos = nPos + sStrArray[i].Len();
1974*cdf0e10cSrcweir 									if ( bHadDash )
1975*cdf0e10cSrcweir 									{
1976*cdf0e10cSrcweir 										*pStr += sStrArray[i];
1977*cdf0e10cSrcweir 										nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
1978*cdf0e10cSrcweir 										nAnzResStrings--;
1979*cdf0e10cSrcweir 									}
1980*cdf0e10cSrcweir 									else
1981*cdf0e10cSrcweir 									{
1982*cdf0e10cSrcweir 										if ( sStrArray[i].GetChar(0) == '-' )
1983*cdf0e10cSrcweir 										{
1984*cdf0e10cSrcweir 											bHadDash = sal_True;
1985*cdf0e10cSrcweir 											pStr = &sStrArray[i];
1986*cdf0e10cSrcweir 											nTypeArray[i] = NF_SYMBOLTYPE_CURREXT;
1987*cdf0e10cSrcweir 										}
1988*cdf0e10cSrcweir 										else
1989*cdf0e10cSrcweir 										{
1990*cdf0e10cSrcweir 											*pStr += sStrArray[i];
1991*cdf0e10cSrcweir 											nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
1992*cdf0e10cSrcweir 											nAnzResStrings--;
1993*cdf0e10cSrcweir 										}
1994*cdf0e10cSrcweir 									}
1995*cdf0e10cSrcweir 									i++;
1996*cdf0e10cSrcweir 								}
1997*cdf0e10cSrcweir 								if ( rStr.Len() && i < nAnzStrings &&
1998*cdf0e10cSrcweir 										sStrArray[i].GetChar(0) == ']' )
1999*cdf0e10cSrcweir 								{
2000*cdf0e10cSrcweir 									nTypeArray[i] = NF_SYMBOLTYPE_CURRDEL;
2001*cdf0e10cSrcweir 									nPos = nPos + sStrArray[i].Len();
2002*cdf0e10cSrcweir 									i++;
2003*cdf0e10cSrcweir 								}
2004*cdf0e10cSrcweir 								else
2005*cdf0e10cSrcweir 									return nPos;		// Fehler
2006*cdf0e10cSrcweir 							}
2007*cdf0e10cSrcweir 							else
2008*cdf0e10cSrcweir 							{
2009*cdf0e10cSrcweir 								nTypeArray[i] = NF_SYMBOLTYPE_STRING;
2010*cdf0e10cSrcweir 								nPos = nPos + sStrArray[i].Len();
2011*cdf0e10cSrcweir 								i++;
2012*cdf0e10cSrcweir 							}
2013*cdf0e10cSrcweir 						}
2014*cdf0e10cSrcweir 						break;
2015*cdf0e10cSrcweir 						default:					// andere Dels
2016*cdf0e10cSrcweir 						{
2017*cdf0e10cSrcweir                             if (eScannedType == NUMBERFORMAT_PERCENT &&
2018*cdf0e10cSrcweir                                     cHere == '%')
2019*cdf0e10cSrcweir                                 nTypeArray[i] = NF_SYMBOLTYPE_PERCENT;
2020*cdf0e10cSrcweir                             else
2021*cdf0e10cSrcweir                                 nTypeArray[i] = NF_SYMBOLTYPE_STRING;
2022*cdf0e10cSrcweir 							nPos = nPos + sStrArray[i].Len();
2023*cdf0e10cSrcweir 							i++;
2024*cdf0e10cSrcweir 						}
2025*cdf0e10cSrcweir 						break;
2026*cdf0e10cSrcweir 					}								// of switch (Del)
2027*cdf0e10cSrcweir 				}									// of else Del
2028*cdf0e10cSrcweir 				else if ( nTypeArray[i] == NF_SYMBOLTYPE_COMMENT )
2029*cdf0e10cSrcweir 				{
2030*cdf0e10cSrcweir 					String& rStr = sStrArray[i];
2031*cdf0e10cSrcweir 					nPos = nPos + rStr.Len();
2032*cdf0e10cSrcweir 					SvNumberformat::EraseCommentBraces( rStr );
2033*cdf0e10cSrcweir 					rComment += rStr;
2034*cdf0e10cSrcweir 					nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
2035*cdf0e10cSrcweir 					nAnzResStrings--;
2036*cdf0e10cSrcweir 					i++;
2037*cdf0e10cSrcweir 				}
2038*cdf0e10cSrcweir 				else
2039*cdf0e10cSrcweir 				{
2040*cdf0e10cSrcweir 					DBG_ERRORFILE( "unknown NF_SYMBOLTYPE_..." );
2041*cdf0e10cSrcweir 					nPos = nPos + sStrArray[i].Len();
2042*cdf0e10cSrcweir 					i++;
2043*cdf0e10cSrcweir 				}
2044*cdf0e10cSrcweir 			}                                  		// of while
2045*cdf0e10cSrcweir 			if (eScannedType == NUMBERFORMAT_FRACTION)
2046*cdf0e10cSrcweir 			{
2047*cdf0e10cSrcweir 				if (bFrac)
2048*cdf0e10cSrcweir 					nCntExp = nCounter;
2049*cdf0e10cSrcweir 				else if (bBlank)
2050*cdf0e10cSrcweir 					nCntPost = nCounter;
2051*cdf0e10cSrcweir 				else
2052*cdf0e10cSrcweir 					nCntPre = nCounter;
2053*cdf0e10cSrcweir 			}
2054*cdf0e10cSrcweir 			else
2055*cdf0e10cSrcweir 			{
2056*cdf0e10cSrcweir 				if (bExp)
2057*cdf0e10cSrcweir 					nCntExp = nCounter;
2058*cdf0e10cSrcweir 				else if (bDecSep)
2059*cdf0e10cSrcweir 					nCntPost = nCounter;
2060*cdf0e10cSrcweir 				else
2061*cdf0e10cSrcweir 					nCntPre = nCounter;
2062*cdf0e10cSrcweir 			}
2063*cdf0e10cSrcweir 			if (bThousand)                          // Expansion of grouping separators
2064*cdf0e10cSrcweir 			{
2065*cdf0e10cSrcweir 				sal_uInt16 nMaxPos;
2066*cdf0e10cSrcweir 				if (bFrac)
2067*cdf0e10cSrcweir 				{
2068*cdf0e10cSrcweir 					if (bBlank)
2069*cdf0e10cSrcweir 						nMaxPos = nBlankPos;
2070*cdf0e10cSrcweir 					else
2071*cdf0e10cSrcweir 						nMaxPos = 0;				// no grouping
2072*cdf0e10cSrcweir 				}
2073*cdf0e10cSrcweir 				else if (bDecSep)					// decimal separator present
2074*cdf0e10cSrcweir 					nMaxPos = nDecPos;
2075*cdf0e10cSrcweir 				else if (bExp)						// 'E' exponent present
2076*cdf0e10cSrcweir 					nMaxPos = nExpPos;
2077*cdf0e10cSrcweir 				else								// up to end
2078*cdf0e10cSrcweir 					nMaxPos = i;
2079*cdf0e10cSrcweir                 // Insert separators at proper positions.
2080*cdf0e10cSrcweir                 xub_StrLen nCount = 0;
2081*cdf0e10cSrcweir                 utl::DigitGroupingIterator aGrouping( pLoc->getDigitGrouping());
2082*cdf0e10cSrcweir                 size_t nFirstDigitSymbol = nMaxPos;
2083*cdf0e10cSrcweir                 size_t nFirstGroupingSymbol = nMaxPos;
2084*cdf0e10cSrcweir                 i = nMaxPos;
2085*cdf0e10cSrcweir                 while (i-- > 0)
2086*cdf0e10cSrcweir                 {
2087*cdf0e10cSrcweir                     if (nTypeArray[i] == NF_SYMBOLTYPE_DIGIT)
2088*cdf0e10cSrcweir                     {
2089*cdf0e10cSrcweir                         nFirstDigitSymbol = i;
2090*cdf0e10cSrcweir                         nCount = nCount + sStrArray[i].Len();   // MSC converts += to int and then warns, so ...
2091*cdf0e10cSrcweir                         // Insert separator only if not leftmost symbol.
2092*cdf0e10cSrcweir                         if (i > 0 && nCount >= aGrouping.getPos())
2093*cdf0e10cSrcweir                         {
2094*cdf0e10cSrcweir                             DBG_ASSERT( sStrArray[i].Len() == 1,
2095*cdf0e10cSrcweir                                     "ImpSvNumberformatScan::FinalScan: combined digits in group separator insertion");
2096*cdf0e10cSrcweir                             if (!InsertSymbol( i, NF_SYMBOLTYPE_THSEP,
2097*cdf0e10cSrcweir                                         pFormatter->GetNumThousandSep()))
2098*cdf0e10cSrcweir                                 // nPos isn't correct here, but signals error
2099*cdf0e10cSrcweir                                 return nPos;
2100*cdf0e10cSrcweir                             // i may have been decremented by 1
2101*cdf0e10cSrcweir                             nFirstDigitSymbol = i + 1;
2102*cdf0e10cSrcweir                             nFirstGroupingSymbol = i;
2103*cdf0e10cSrcweir                             aGrouping.advance();
2104*cdf0e10cSrcweir                         }
2105*cdf0e10cSrcweir                     }
2106*cdf0e10cSrcweir                 }
2107*cdf0e10cSrcweir                 // Generated something like "string",000; remove separator again.
2108*cdf0e10cSrcweir                 if (nFirstGroupingSymbol < nFirstDigitSymbol)
2109*cdf0e10cSrcweir                 {
2110*cdf0e10cSrcweir                     nTypeArray[nFirstGroupingSymbol] = NF_SYMBOLTYPE_EMPTY;
2111*cdf0e10cSrcweir                     nAnzResStrings--;
2112*cdf0e10cSrcweir                 }
2113*cdf0e10cSrcweir             }
2114*cdf0e10cSrcweir             // Combine digits into groups to save memory (Info will be copied
2115*cdf0e10cSrcweir             // later, taking only non-empty symbols).
2116*cdf0e10cSrcweir             for (i = 0; i < nAnzStrings; ++i)
2117*cdf0e10cSrcweir             {
2118*cdf0e10cSrcweir                 if (nTypeArray[i] == NF_SYMBOLTYPE_DIGIT)
2119*cdf0e10cSrcweir                 {
2120*cdf0e10cSrcweir                     String& rStr = sStrArray[i];
2121*cdf0e10cSrcweir                     while (++i < nAnzStrings &&
2122*cdf0e10cSrcweir                             nTypeArray[i] == NF_SYMBOLTYPE_DIGIT)
2123*cdf0e10cSrcweir                     {
2124*cdf0e10cSrcweir                         rStr += sStrArray[i];
2125*cdf0e10cSrcweir                         nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
2126*cdf0e10cSrcweir                         nAnzResStrings--;
2127*cdf0e10cSrcweir                     }
2128*cdf0e10cSrcweir                 }
2129*cdf0e10cSrcweir             }
2130*cdf0e10cSrcweir 		}
2131*cdf0e10cSrcweir 		break;										// of NUMBERFORMAT_NUMBER
2132*cdf0e10cSrcweir 		case NUMBERFORMAT_DATE:
2133*cdf0e10cSrcweir 		{
2134*cdf0e10cSrcweir 			while (i < nAnzStrings)
2135*cdf0e10cSrcweir 			{
2136*cdf0e10cSrcweir 				switch (nTypeArray[i])
2137*cdf0e10cSrcweir 				{
2138*cdf0e10cSrcweir 					case NF_SYMBOLTYPE_BLANK:
2139*cdf0e10cSrcweir 					case NF_SYMBOLTYPE_STAR:
2140*cdf0e10cSrcweir 					case NF_SYMBOLTYPE_STRING:
2141*cdf0e10cSrcweir 						nPos = nPos + sStrArray[i].Len();
2142*cdf0e10cSrcweir 						i++;
2143*cdf0e10cSrcweir 					break;
2144*cdf0e10cSrcweir 					case NF_SYMBOLTYPE_COMMENT:
2145*cdf0e10cSrcweir 					{
2146*cdf0e10cSrcweir 						String& rStr = sStrArray[i];
2147*cdf0e10cSrcweir 						nPos = nPos + rStr.Len();
2148*cdf0e10cSrcweir 						SvNumberformat::EraseCommentBraces( rStr );
2149*cdf0e10cSrcweir 						rComment += rStr;
2150*cdf0e10cSrcweir 						nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
2151*cdf0e10cSrcweir 						nAnzResStrings--;
2152*cdf0e10cSrcweir 						i++;
2153*cdf0e10cSrcweir 					}
2154*cdf0e10cSrcweir 					break;
2155*cdf0e10cSrcweir 					case NF_SYMBOLTYPE_DEL:
2156*cdf0e10cSrcweir 					{
2157*cdf0e10cSrcweir 						int nCalRet;
2158*cdf0e10cSrcweir 						if (sStrArray[i] == sOldDateSep)
2159*cdf0e10cSrcweir 						{
2160*cdf0e10cSrcweir 							nTypeArray[i] = NF_SYMBOLTYPE_DATESEP;
2161*cdf0e10cSrcweir 							nPos = nPos + sStrArray[i].Len();
2162*cdf0e10cSrcweir                             if (bConvertMode)
2163*cdf0e10cSrcweir                                 sStrArray[i] = pFormatter->GetDateSep();
2164*cdf0e10cSrcweir 							i++;
2165*cdf0e10cSrcweir 						}
2166*cdf0e10cSrcweir 						else if ( (nCalRet = FinalScanGetCalendar( nPos, i, nAnzResStrings )) != 0 )
2167*cdf0e10cSrcweir 						{
2168*cdf0e10cSrcweir 							if ( nCalRet < 0  )
2169*cdf0e10cSrcweir 								return nPos;		// error
2170*cdf0e10cSrcweir 						}
2171*cdf0e10cSrcweir 						else
2172*cdf0e10cSrcweir 						{
2173*cdf0e10cSrcweir 							nTypeArray[i] = NF_SYMBOLTYPE_STRING;
2174*cdf0e10cSrcweir 							nPos = nPos + sStrArray[i].Len();
2175*cdf0e10cSrcweir 							i++;
2176*cdf0e10cSrcweir 						}
2177*cdf0e10cSrcweir 					}
2178*cdf0e10cSrcweir 					break;
2179*cdf0e10cSrcweir                     case NF_KEY_THAI_T :
2180*cdf0e10cSrcweir                         bThaiT = true;
2181*cdf0e10cSrcweir                         // fall thru
2182*cdf0e10cSrcweir 					case NF_KEY_M:							// M
2183*cdf0e10cSrcweir 					case NF_KEY_MM:							// MM
2184*cdf0e10cSrcweir 					case NF_KEY_MMM:						// MMM
2185*cdf0e10cSrcweir 					case NF_KEY_MMMM:						// MMMM
2186*cdf0e10cSrcweir 					case NF_KEY_MMMMM:						// MMMMM
2187*cdf0e10cSrcweir 					case NF_KEY_Q:							// Q
2188*cdf0e10cSrcweir 					case NF_KEY_QQ:							// QQ
2189*cdf0e10cSrcweir 					case NF_KEY_D:							// D
2190*cdf0e10cSrcweir 					case NF_KEY_DD:							// DD
2191*cdf0e10cSrcweir 					case NF_KEY_DDD:						// DDD
2192*cdf0e10cSrcweir 					case NF_KEY_DDDD:						// DDDD
2193*cdf0e10cSrcweir 					case NF_KEY_YY:							// YY
2194*cdf0e10cSrcweir 					case NF_KEY_YYYY:						// YYYY
2195*cdf0e10cSrcweir 					case NF_KEY_NN:							// NN
2196*cdf0e10cSrcweir 					case NF_KEY_NNN:						// NNN
2197*cdf0e10cSrcweir 					case NF_KEY_NNNN:						// NNNN
2198*cdf0e10cSrcweir 					case NF_KEY_WW :						// WW
2199*cdf0e10cSrcweir 					case NF_KEY_AAA :						// AAA
2200*cdf0e10cSrcweir 					case NF_KEY_AAAA :						// AAAA
2201*cdf0e10cSrcweir 					case NF_KEY_EC :						// E
2202*cdf0e10cSrcweir 					case NF_KEY_EEC :						// EE
2203*cdf0e10cSrcweir 					case NF_KEY_G :							// G
2204*cdf0e10cSrcweir 					case NF_KEY_GG :						// GG
2205*cdf0e10cSrcweir 					case NF_KEY_GGG :						// GGG
2206*cdf0e10cSrcweir 					case NF_KEY_R :							// R
2207*cdf0e10cSrcweir 					case NF_KEY_RR :						// RR
2208*cdf0e10cSrcweir 						sStrArray[i] = sKeyword[nTypeArray[i]];	// tTtT -> TTTT
2209*cdf0e10cSrcweir 						nPos = nPos + sStrArray[i].Len();
2210*cdf0e10cSrcweir 						i++;
2211*cdf0e10cSrcweir 					break;
2212*cdf0e10cSrcweir 					default:							// andere Keywords
2213*cdf0e10cSrcweir 						nTypeArray[i] = NF_SYMBOLTYPE_STRING;
2214*cdf0e10cSrcweir 						nPos = nPos + sStrArray[i].Len();
2215*cdf0e10cSrcweir 						i++;
2216*cdf0e10cSrcweir 					break;
2217*cdf0e10cSrcweir 				}
2218*cdf0e10cSrcweir 			}										// of while
2219*cdf0e10cSrcweir 		}
2220*cdf0e10cSrcweir 		break;										// of NUMBERFORMAT_DATE
2221*cdf0e10cSrcweir 		case NUMBERFORMAT_TIME:
2222*cdf0e10cSrcweir 		{
2223*cdf0e10cSrcweir 			while (i < nAnzStrings)
2224*cdf0e10cSrcweir 			{
2225*cdf0e10cSrcweir 				switch (nTypeArray[i])
2226*cdf0e10cSrcweir 				{
2227*cdf0e10cSrcweir 					case NF_SYMBOLTYPE_BLANK:
2228*cdf0e10cSrcweir 					case NF_SYMBOLTYPE_STAR:
2229*cdf0e10cSrcweir 					{
2230*cdf0e10cSrcweir 						nPos = nPos + sStrArray[i].Len();
2231*cdf0e10cSrcweir 						i++;
2232*cdf0e10cSrcweir 					}
2233*cdf0e10cSrcweir 					break;
2234*cdf0e10cSrcweir 					case NF_SYMBOLTYPE_DEL:
2235*cdf0e10cSrcweir 					{
2236*cdf0e10cSrcweir 						switch( sStrArray[i].GetChar(0) )
2237*cdf0e10cSrcweir 						{
2238*cdf0e10cSrcweir 							case '0':
2239*cdf0e10cSrcweir 							{
2240*cdf0e10cSrcweir                                 if ( Is100SecZero( i, bDecSep ) )
2241*cdf0e10cSrcweir 								{
2242*cdf0e10cSrcweir                                     bDecSep = sal_True;
2243*cdf0e10cSrcweir 									nTypeArray[i] = NF_SYMBOLTYPE_DIGIT;
2244*cdf0e10cSrcweir 									String& rStr = sStrArray[i];
2245*cdf0e10cSrcweir 									i++;
2246*cdf0e10cSrcweir 									nPos = nPos + sStrArray[i].Len();
2247*cdf0e10cSrcweir 									nCounter++;
2248*cdf0e10cSrcweir 									while (i < nAnzStrings &&
2249*cdf0e10cSrcweir 										   sStrArray[i].GetChar(0) == '0')
2250*cdf0e10cSrcweir 									{
2251*cdf0e10cSrcweir 										rStr += sStrArray[i];
2252*cdf0e10cSrcweir 										nPos = nPos + sStrArray[i].Len();
2253*cdf0e10cSrcweir 										nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
2254*cdf0e10cSrcweir 										nAnzResStrings--;
2255*cdf0e10cSrcweir 										nCounter++;
2256*cdf0e10cSrcweir 										i++;
2257*cdf0e10cSrcweir 									}
2258*cdf0e10cSrcweir 								}
2259*cdf0e10cSrcweir 								else
2260*cdf0e10cSrcweir 									return nPos;
2261*cdf0e10cSrcweir 							}
2262*cdf0e10cSrcweir 							break;
2263*cdf0e10cSrcweir 							case '#':
2264*cdf0e10cSrcweir 							case '?':
2265*cdf0e10cSrcweir 								return nPos;
2266*cdf0e10cSrcweir 							case '[':
2267*cdf0e10cSrcweir 							{
2268*cdf0e10cSrcweir 								if (bThousand)				// doppelt
2269*cdf0e10cSrcweir 									return nPos;
2270*cdf0e10cSrcweir 								bThousand = sal_True;			// bei Time frei
2271*cdf0e10cSrcweir 								sal_Unicode cChar = pChrCls->upper( NextChar(i) ).GetChar(0);
2272*cdf0e10cSrcweir 								if ( cChar == cOldKeyH )
2273*cdf0e10cSrcweir 									nThousand = 1;		// H
2274*cdf0e10cSrcweir 								else if ( cChar == cOldKeyMI )
2275*cdf0e10cSrcweir 									nThousand = 2;		// M
2276*cdf0e10cSrcweir 								else if ( cChar == cOldKeyS )
2277*cdf0e10cSrcweir 									nThousand = 3;		// S
2278*cdf0e10cSrcweir 								else
2279*cdf0e10cSrcweir 									return nPos;
2280*cdf0e10cSrcweir 								nPos = nPos + sStrArray[i].Len();
2281*cdf0e10cSrcweir 								i++;
2282*cdf0e10cSrcweir 							}
2283*cdf0e10cSrcweir                             break;
2284*cdf0e10cSrcweir 							case ']':
2285*cdf0e10cSrcweir 							{
2286*cdf0e10cSrcweir 								if (!bThousand)				// kein [ vorher
2287*cdf0e10cSrcweir 									return nPos;
2288*cdf0e10cSrcweir 								nPos = nPos + sStrArray[i].Len();
2289*cdf0e10cSrcweir 								i++;
2290*cdf0e10cSrcweir 							}
2291*cdf0e10cSrcweir 							break;
2292*cdf0e10cSrcweir 							default:
2293*cdf0e10cSrcweir 							{
2294*cdf0e10cSrcweir 								nPos = nPos + sStrArray[i].Len();
2295*cdf0e10cSrcweir                                 if ( sStrArray[i] == sOldTimeSep )
2296*cdf0e10cSrcweir                                 {
2297*cdf0e10cSrcweir                                     nTypeArray[i] = NF_SYMBOLTYPE_TIMESEP;
2298*cdf0e10cSrcweir                                     if ( bConvertMode )
2299*cdf0e10cSrcweir                                         sStrArray[i] = pLoc->getTimeSep();
2300*cdf0e10cSrcweir                                 }
2301*cdf0e10cSrcweir                                 else if ( sStrArray[i] == sOldTime100SecSep )
2302*cdf0e10cSrcweir                                 {
2303*cdf0e10cSrcweir                                     bDecSep = sal_True;
2304*cdf0e10cSrcweir                                     nTypeArray[i] = NF_SYMBOLTYPE_TIME100SECSEP;
2305*cdf0e10cSrcweir                                     if ( bConvertMode )
2306*cdf0e10cSrcweir                                         sStrArray[i] = pLoc->getTime100SecSep();
2307*cdf0e10cSrcweir                                 }
2308*cdf0e10cSrcweir                                 else
2309*cdf0e10cSrcweir                                     nTypeArray[i] = NF_SYMBOLTYPE_STRING;
2310*cdf0e10cSrcweir 								i++;
2311*cdf0e10cSrcweir 							}
2312*cdf0e10cSrcweir 							break;
2313*cdf0e10cSrcweir 						}
2314*cdf0e10cSrcweir 					}
2315*cdf0e10cSrcweir 					break;
2316*cdf0e10cSrcweir 					case NF_SYMBOLTYPE_STRING:
2317*cdf0e10cSrcweir 					{
2318*cdf0e10cSrcweir 						nPos = nPos + sStrArray[i].Len();
2319*cdf0e10cSrcweir 						i++;
2320*cdf0e10cSrcweir 					}
2321*cdf0e10cSrcweir 					break;
2322*cdf0e10cSrcweir 					case NF_SYMBOLTYPE_COMMENT:
2323*cdf0e10cSrcweir 					{
2324*cdf0e10cSrcweir 						String& rStr = sStrArray[i];
2325*cdf0e10cSrcweir 						nPos = nPos + rStr.Len();
2326*cdf0e10cSrcweir 						SvNumberformat::EraseCommentBraces( rStr );
2327*cdf0e10cSrcweir 						rComment += rStr;
2328*cdf0e10cSrcweir 						nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
2329*cdf0e10cSrcweir 						nAnzResStrings--;
2330*cdf0e10cSrcweir 						i++;
2331*cdf0e10cSrcweir 					}
2332*cdf0e10cSrcweir 					break;
2333*cdf0e10cSrcweir 					case NF_KEY_AMPM:						// AM/PM
2334*cdf0e10cSrcweir 					case NF_KEY_AP:							// A/P
2335*cdf0e10cSrcweir 					{
2336*cdf0e10cSrcweir 						bExp = sal_True;					// missbraucht fuer A/P
2337*cdf0e10cSrcweir 						sStrArray[i] = sKeyword[nTypeArray[i]];	// tTtT -> TTTT
2338*cdf0e10cSrcweir 						nPos = nPos + sStrArray[i].Len();
2339*cdf0e10cSrcweir 						i++;
2340*cdf0e10cSrcweir 					}
2341*cdf0e10cSrcweir 					break;
2342*cdf0e10cSrcweir                     case NF_KEY_THAI_T :
2343*cdf0e10cSrcweir                         bThaiT = true;
2344*cdf0e10cSrcweir                         // fall thru
2345*cdf0e10cSrcweir 					case NF_KEY_MI:							// M
2346*cdf0e10cSrcweir 					case NF_KEY_MMI:						// MM
2347*cdf0e10cSrcweir 					case NF_KEY_H:							// H
2348*cdf0e10cSrcweir 					case NF_KEY_HH:							// HH
2349*cdf0e10cSrcweir 					case NF_KEY_S:							// S
2350*cdf0e10cSrcweir 					case NF_KEY_SS:							// SS
2351*cdf0e10cSrcweir 					{
2352*cdf0e10cSrcweir 						sStrArray[i] = sKeyword[nTypeArray[i]];	// tTtT -> TTTT
2353*cdf0e10cSrcweir 						nPos = nPos + sStrArray[i].Len();
2354*cdf0e10cSrcweir 						i++;
2355*cdf0e10cSrcweir 					}
2356*cdf0e10cSrcweir 					break;
2357*cdf0e10cSrcweir 					default:							// andere Keywords
2358*cdf0e10cSrcweir 					{
2359*cdf0e10cSrcweir 						nTypeArray[i] = NF_SYMBOLTYPE_STRING;
2360*cdf0e10cSrcweir 						nPos = nPos + sStrArray[i].Len();
2361*cdf0e10cSrcweir 						i++;
2362*cdf0e10cSrcweir 					}
2363*cdf0e10cSrcweir 					break;
2364*cdf0e10cSrcweir 				}
2365*cdf0e10cSrcweir 			}                   					// of while
2366*cdf0e10cSrcweir 			nCntPost = nCounter;					// Zaehler der Nullen
2367*cdf0e10cSrcweir 			if (bExp)
2368*cdf0e10cSrcweir 				nCntExp = 1;						// merkt AM/PM
2369*cdf0e10cSrcweir 		}
2370*cdf0e10cSrcweir 		break;										// of NUMBERFORMAT_TIME
2371*cdf0e10cSrcweir 		case NUMBERFORMAT_DATETIME:
2372*cdf0e10cSrcweir 		{
2373*cdf0e10cSrcweir             sal_Bool bTimePart = sal_False;
2374*cdf0e10cSrcweir 			while (i < nAnzStrings)
2375*cdf0e10cSrcweir 			{
2376*cdf0e10cSrcweir 				switch (nTypeArray[i])
2377*cdf0e10cSrcweir 				{
2378*cdf0e10cSrcweir 					case NF_SYMBOLTYPE_BLANK:
2379*cdf0e10cSrcweir 					case NF_SYMBOLTYPE_STAR:
2380*cdf0e10cSrcweir 					case NF_SYMBOLTYPE_STRING:
2381*cdf0e10cSrcweir 						nPos = nPos + sStrArray[i].Len();
2382*cdf0e10cSrcweir 						i++;
2383*cdf0e10cSrcweir 					break;
2384*cdf0e10cSrcweir 					case NF_SYMBOLTYPE_COMMENT:
2385*cdf0e10cSrcweir 					{
2386*cdf0e10cSrcweir 						String& rStr = sStrArray[i];
2387*cdf0e10cSrcweir 						nPos = nPos + rStr.Len();
2388*cdf0e10cSrcweir 						SvNumberformat::EraseCommentBraces( rStr );
2389*cdf0e10cSrcweir 						rComment += rStr;
2390*cdf0e10cSrcweir 						nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
2391*cdf0e10cSrcweir 						nAnzResStrings--;
2392*cdf0e10cSrcweir 						i++;
2393*cdf0e10cSrcweir 					}
2394*cdf0e10cSrcweir 					break;
2395*cdf0e10cSrcweir 					case NF_SYMBOLTYPE_DEL:
2396*cdf0e10cSrcweir 					{
2397*cdf0e10cSrcweir 						int nCalRet;
2398*cdf0e10cSrcweir                         if ( (nCalRet = FinalScanGetCalendar( nPos, i, nAnzResStrings )) != 0 )
2399*cdf0e10cSrcweir 						{
2400*cdf0e10cSrcweir 							if ( nCalRet < 0  )
2401*cdf0e10cSrcweir 								return nPos;		// error
2402*cdf0e10cSrcweir 						}
2403*cdf0e10cSrcweir 						else
2404*cdf0e10cSrcweir 						{
2405*cdf0e10cSrcweir                             switch( sStrArray[i].GetChar(0) )
2406*cdf0e10cSrcweir                             {
2407*cdf0e10cSrcweir                                 case '0':
2408*cdf0e10cSrcweir                                 {
2409*cdf0e10cSrcweir                                     if ( bTimePart && Is100SecZero( i, bDecSep ) )
2410*cdf0e10cSrcweir                                     {
2411*cdf0e10cSrcweir                                         bDecSep = sal_True;
2412*cdf0e10cSrcweir                                         nTypeArray[i] = NF_SYMBOLTYPE_DIGIT;
2413*cdf0e10cSrcweir                                         String& rStr = sStrArray[i];
2414*cdf0e10cSrcweir                                         i++;
2415*cdf0e10cSrcweir                                         nPos = nPos + sStrArray[i].Len();
2416*cdf0e10cSrcweir                                         nCounter++;
2417*cdf0e10cSrcweir                                         while (i < nAnzStrings &&
2418*cdf0e10cSrcweir                                             sStrArray[i].GetChar(0) == '0')
2419*cdf0e10cSrcweir                                         {
2420*cdf0e10cSrcweir                                             rStr += sStrArray[i];
2421*cdf0e10cSrcweir                                             nPos = nPos + sStrArray[i].Len();
2422*cdf0e10cSrcweir                                             nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
2423*cdf0e10cSrcweir                                             nAnzResStrings--;
2424*cdf0e10cSrcweir                                             nCounter++;
2425*cdf0e10cSrcweir                                             i++;
2426*cdf0e10cSrcweir                                         }
2427*cdf0e10cSrcweir                                     }
2428*cdf0e10cSrcweir                                     else
2429*cdf0e10cSrcweir                                         return nPos;
2430*cdf0e10cSrcweir                                 }
2431*cdf0e10cSrcweir                                 break;
2432*cdf0e10cSrcweir                                 case '#':
2433*cdf0e10cSrcweir                                 case '?':
2434*cdf0e10cSrcweir                                     return nPos;
2435*cdf0e10cSrcweir                                 default:
2436*cdf0e10cSrcweir                                 {
2437*cdf0e10cSrcweir                                     nPos = nPos + sStrArray[i].Len();
2438*cdf0e10cSrcweir                                     if (bTimePart)
2439*cdf0e10cSrcweir                                     {
2440*cdf0e10cSrcweir                                         if ( sStrArray[i] == sOldTimeSep )
2441*cdf0e10cSrcweir                                         {
2442*cdf0e10cSrcweir                                             nTypeArray[i] = NF_SYMBOLTYPE_TIMESEP;
2443*cdf0e10cSrcweir                                             if ( bConvertMode )
2444*cdf0e10cSrcweir                                                 sStrArray[i] = pLoc->getTimeSep();
2445*cdf0e10cSrcweir                                         }
2446*cdf0e10cSrcweir                                         else if ( sStrArray[i] == sOldTime100SecSep )
2447*cdf0e10cSrcweir                                         {
2448*cdf0e10cSrcweir                                             bDecSep = sal_True;
2449*cdf0e10cSrcweir                                             nTypeArray[i] = NF_SYMBOLTYPE_TIME100SECSEP;
2450*cdf0e10cSrcweir                                             if ( bConvertMode )
2451*cdf0e10cSrcweir                                                 sStrArray[i] = pLoc->getTime100SecSep();
2452*cdf0e10cSrcweir                                         }
2453*cdf0e10cSrcweir                                         else
2454*cdf0e10cSrcweir                                             nTypeArray[i] = NF_SYMBOLTYPE_STRING;
2455*cdf0e10cSrcweir                                     }
2456*cdf0e10cSrcweir                                     else
2457*cdf0e10cSrcweir                                     {
2458*cdf0e10cSrcweir                                         if ( sStrArray[i] == sOldDateSep )
2459*cdf0e10cSrcweir                                         {
2460*cdf0e10cSrcweir                                             nTypeArray[i] = NF_SYMBOLTYPE_DATESEP;
2461*cdf0e10cSrcweir                                             if (bConvertMode)
2462*cdf0e10cSrcweir                                                 sStrArray[i] = pFormatter->GetDateSep();
2463*cdf0e10cSrcweir                                         }
2464*cdf0e10cSrcweir                                         else
2465*cdf0e10cSrcweir                                             nTypeArray[i] = NF_SYMBOLTYPE_STRING;
2466*cdf0e10cSrcweir                                     }
2467*cdf0e10cSrcweir                                     i++;
2468*cdf0e10cSrcweir                                 }
2469*cdf0e10cSrcweir                             }
2470*cdf0e10cSrcweir 						}
2471*cdf0e10cSrcweir 					}
2472*cdf0e10cSrcweir 					break;
2473*cdf0e10cSrcweir 					case NF_KEY_AMPM:						// AM/PM
2474*cdf0e10cSrcweir 					case NF_KEY_AP:							// A/P
2475*cdf0e10cSrcweir 					{
2476*cdf0e10cSrcweir                         bTimePart = sal_True;
2477*cdf0e10cSrcweir 						bExp = sal_True;					// missbraucht fuer A/P
2478*cdf0e10cSrcweir 						sStrArray[i] = sKeyword[nTypeArray[i]];	// tTtT -> TTTT
2479*cdf0e10cSrcweir 						nPos = nPos + sStrArray[i].Len();
2480*cdf0e10cSrcweir 						i++;
2481*cdf0e10cSrcweir 					}
2482*cdf0e10cSrcweir 					break;
2483*cdf0e10cSrcweir 					case NF_KEY_MI:							// M
2484*cdf0e10cSrcweir 					case NF_KEY_MMI:						// MM
2485*cdf0e10cSrcweir 					case NF_KEY_H:							// H
2486*cdf0e10cSrcweir 					case NF_KEY_HH:							// HH
2487*cdf0e10cSrcweir 					case NF_KEY_S:							// S
2488*cdf0e10cSrcweir 					case NF_KEY_SS:							// SS
2489*cdf0e10cSrcweir                         bTimePart = sal_True;
2490*cdf0e10cSrcweir 						sStrArray[i] = sKeyword[nTypeArray[i]];	// tTtT -> TTTT
2491*cdf0e10cSrcweir 						nPos = nPos + sStrArray[i].Len();
2492*cdf0e10cSrcweir 						i++;
2493*cdf0e10cSrcweir 					break;
2494*cdf0e10cSrcweir 					case NF_KEY_M:							// M
2495*cdf0e10cSrcweir 					case NF_KEY_MM:							// MM
2496*cdf0e10cSrcweir 					case NF_KEY_MMM:						// MMM
2497*cdf0e10cSrcweir 					case NF_KEY_MMMM:						// MMMM
2498*cdf0e10cSrcweir 					case NF_KEY_MMMMM:						// MMMMM
2499*cdf0e10cSrcweir 					case NF_KEY_Q:							// Q
2500*cdf0e10cSrcweir 					case NF_KEY_QQ:							// QQ
2501*cdf0e10cSrcweir 					case NF_KEY_D:							// D
2502*cdf0e10cSrcweir 					case NF_KEY_DD:							// DD
2503*cdf0e10cSrcweir 					case NF_KEY_DDD:						// DDD
2504*cdf0e10cSrcweir 					case NF_KEY_DDDD:						// DDDD
2505*cdf0e10cSrcweir 					case NF_KEY_YY:							// YY
2506*cdf0e10cSrcweir 					case NF_KEY_YYYY:						// YYYY
2507*cdf0e10cSrcweir 					case NF_KEY_NN:							// NN
2508*cdf0e10cSrcweir 					case NF_KEY_NNN:						// NNN
2509*cdf0e10cSrcweir 					case NF_KEY_NNNN:						// NNNN
2510*cdf0e10cSrcweir 					case NF_KEY_WW :						// WW
2511*cdf0e10cSrcweir 					case NF_KEY_AAA :						// AAA
2512*cdf0e10cSrcweir 					case NF_KEY_AAAA :						// AAAA
2513*cdf0e10cSrcweir 					case NF_KEY_EC :						// E
2514*cdf0e10cSrcweir 					case NF_KEY_EEC :						// EE
2515*cdf0e10cSrcweir 					case NF_KEY_G :							// G
2516*cdf0e10cSrcweir 					case NF_KEY_GG :						// GG
2517*cdf0e10cSrcweir 					case NF_KEY_GGG :						// GGG
2518*cdf0e10cSrcweir 					case NF_KEY_R :							// R
2519*cdf0e10cSrcweir 					case NF_KEY_RR :						// RR
2520*cdf0e10cSrcweir                         bTimePart = sal_False;
2521*cdf0e10cSrcweir 						sStrArray[i] = sKeyword[nTypeArray[i]];	// tTtT -> TTTT
2522*cdf0e10cSrcweir 						nPos = nPos + sStrArray[i].Len();
2523*cdf0e10cSrcweir 						i++;
2524*cdf0e10cSrcweir 					break;
2525*cdf0e10cSrcweir                     case NF_KEY_THAI_T :
2526*cdf0e10cSrcweir                         bThaiT = true;
2527*cdf0e10cSrcweir 						sStrArray[i] = sKeyword[nTypeArray[i]];
2528*cdf0e10cSrcweir 						nPos = nPos + sStrArray[i].Len();
2529*cdf0e10cSrcweir 						i++;
2530*cdf0e10cSrcweir 					break;
2531*cdf0e10cSrcweir 					default:							// andere Keywords
2532*cdf0e10cSrcweir 						nTypeArray[i] = NF_SYMBOLTYPE_STRING;
2533*cdf0e10cSrcweir 						nPos = nPos + sStrArray[i].Len();
2534*cdf0e10cSrcweir 						i++;
2535*cdf0e10cSrcweir 					break;
2536*cdf0e10cSrcweir 				}
2537*cdf0e10cSrcweir 			}										// of while
2538*cdf0e10cSrcweir             nCntPost = nCounter;                    // decimals (100th seconds)
2539*cdf0e10cSrcweir 			if (bExp)
2540*cdf0e10cSrcweir 				nCntExp = 1;						// merkt AM/PM
2541*cdf0e10cSrcweir 		}
2542*cdf0e10cSrcweir 		break;										// of NUMBERFORMAT_DATETIME
2543*cdf0e10cSrcweir 		default:
2544*cdf0e10cSrcweir 		break;
2545*cdf0e10cSrcweir 	}
2546*cdf0e10cSrcweir 	if (eScannedType == NUMBERFORMAT_SCIENTIFIC &&
2547*cdf0e10cSrcweir 		(nCntPre + nCntPost == 0 || nCntExp == 0))
2548*cdf0e10cSrcweir 		return nPos;
2549*cdf0e10cSrcweir 	else if (eScannedType == NUMBERFORMAT_FRACTION && (nCntExp > 8 || nCntExp == 0))
2550*cdf0e10cSrcweir 		return nPos;
2551*cdf0e10cSrcweir 
2552*cdf0e10cSrcweir     if (bThaiT && !GetNatNumModifier())
2553*cdf0e10cSrcweir         SetNatNumModifier(1);
2554*cdf0e10cSrcweir 
2555*cdf0e10cSrcweir 	if ( bConvertMode )
2556*cdf0e10cSrcweir 	{	// strings containing keywords of the target locale must be quoted, so
2557*cdf0e10cSrcweir 		// the user sees the difference and is able to edit the format string
2558*cdf0e10cSrcweir 		for ( i=0; i < nAnzStrings; i++ )
2559*cdf0e10cSrcweir 		{
2560*cdf0e10cSrcweir 			if ( nTypeArray[i] == NF_SYMBOLTYPE_STRING &&
2561*cdf0e10cSrcweir 					sStrArray[i].GetChar(0) != '\"' )
2562*cdf0e10cSrcweir 			{
2563*cdf0e10cSrcweir 				if ( bConvertSystemToSystem && eScannedType == NUMBERFORMAT_CURRENCY )
2564*cdf0e10cSrcweir 				{	// don't stringize automatic currency, will be converted
2565*cdf0e10cSrcweir                     if ( sStrArray[i] == sOldCurSymbol )
2566*cdf0e10cSrcweir 						continue;	// for
2567*cdf0e10cSrcweir 					// DM might be splitted into D and M
2568*cdf0e10cSrcweir                     if ( sStrArray[i].Len() < sOldCurSymbol.Len() &&
2569*cdf0e10cSrcweir 							pChrCls->toUpper( sStrArray[i], 0, 1 ).GetChar(0) ==
2570*cdf0e10cSrcweir 							sOldCurString.GetChar(0) )
2571*cdf0e10cSrcweir 					{
2572*cdf0e10cSrcweir 						String aTmp( sStrArray[i] );
2573*cdf0e10cSrcweir 						sal_uInt16 j = i + 1;
2574*cdf0e10cSrcweir                         while ( aTmp.Len() < sOldCurSymbol.Len() &&
2575*cdf0e10cSrcweir 								j < nAnzStrings &&
2576*cdf0e10cSrcweir 								nTypeArray[j] == NF_SYMBOLTYPE_STRING )
2577*cdf0e10cSrcweir 						{
2578*cdf0e10cSrcweir 							aTmp += sStrArray[j++];
2579*cdf0e10cSrcweir 						}
2580*cdf0e10cSrcweir 						if ( pChrCls->upper( aTmp ) == sOldCurString )
2581*cdf0e10cSrcweir 						{
2582*cdf0e10cSrcweir 							sStrArray[i++] = aTmp;
2583*cdf0e10cSrcweir 							for ( ; i<j; i++ )
2584*cdf0e10cSrcweir 							{
2585*cdf0e10cSrcweir 								nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
2586*cdf0e10cSrcweir 								nAnzResStrings--;
2587*cdf0e10cSrcweir 							}
2588*cdf0e10cSrcweir 							i = j - 1;
2589*cdf0e10cSrcweir 							continue;	// for
2590*cdf0e10cSrcweir 						}
2591*cdf0e10cSrcweir 					}
2592*cdf0e10cSrcweir 				}
2593*cdf0e10cSrcweir 				String& rStr = sStrArray[i];
2594*cdf0e10cSrcweir 				xub_StrLen nLen = rStr.Len();
2595*cdf0e10cSrcweir 				for ( xub_StrLen j=0; j<nLen; j++ )
2596*cdf0e10cSrcweir 				{
2597*cdf0e10cSrcweir 					if ( (j == 0 || rStr.GetChar(j-1) != '\\') && GetKeyWord( rStr, j ) )
2598*cdf0e10cSrcweir 					{
2599*cdf0e10cSrcweir 						rStr.Insert( '\"', 0 );
2600*cdf0e10cSrcweir 						rStr += '\"';
2601*cdf0e10cSrcweir 						break;	// for
2602*cdf0e10cSrcweir 					}
2603*cdf0e10cSrcweir 				}
2604*cdf0e10cSrcweir 			}
2605*cdf0e10cSrcweir 		}
2606*cdf0e10cSrcweir 	}
2607*cdf0e10cSrcweir 	// concatenate strings, remove quotes for output, and rebuild the format string
2608*cdf0e10cSrcweir 	rString.Erase();
2609*cdf0e10cSrcweir 	i = 0;
2610*cdf0e10cSrcweir 	while (i < nAnzStrings)
2611*cdf0e10cSrcweir 	{
2612*cdf0e10cSrcweir 		switch ( nTypeArray[i] )
2613*cdf0e10cSrcweir 		{
2614*cdf0e10cSrcweir 			case NF_SYMBOLTYPE_STRING :
2615*cdf0e10cSrcweir 			{
2616*cdf0e10cSrcweir 				xub_StrLen nStringPos = rString.Len();
2617*cdf0e10cSrcweir 				xub_StrLen nArrPos = 0;
2618*cdf0e10cSrcweir 				sal_uInt16 iPos = i;
2619*cdf0e10cSrcweir 				do
2620*cdf0e10cSrcweir 				{
2621*cdf0e10cSrcweir                     if (sStrArray[i].Len() == 2 &&
2622*cdf0e10cSrcweir                             sStrArray[i].GetChar(0) == '\\')
2623*cdf0e10cSrcweir                     {
2624*cdf0e10cSrcweir                         // Unescape some simple forms of symbols even in the UI
2625*cdf0e10cSrcweir                         // visible string to prevent duplicates that differ
2626*cdf0e10cSrcweir                         // only in notation, originating from import.
2627*cdf0e10cSrcweir                         // e.g. YYYY-MM-DD and YYYY\-MM\-DD are identical,
2628*cdf0e10cSrcweir                         // but 0\ 000 0 and 0 000 0 in a French locale are not.
2629*cdf0e10cSrcweir                         sal_Unicode c = sStrArray[i].GetChar(1);
2630*cdf0e10cSrcweir                         switch (c)
2631*cdf0e10cSrcweir                         {
2632*cdf0e10cSrcweir                             case '+':
2633*cdf0e10cSrcweir                             case '-':
2634*cdf0e10cSrcweir                                 rString += c;
2635*cdf0e10cSrcweir                                 break;
2636*cdf0e10cSrcweir                             case ' ':
2637*cdf0e10cSrcweir                             case '.':
2638*cdf0e10cSrcweir                             case '/':
2639*cdf0e10cSrcweir                                 if (((eScannedType & NUMBERFORMAT_DATE) == 0)
2640*cdf0e10cSrcweir                                         && (StringEqualsChar(
2641*cdf0e10cSrcweir                                                 pFormatter->GetNumThousandSep(),
2642*cdf0e10cSrcweir                                                 c) || StringEqualsChar(
2643*cdf0e10cSrcweir                                                     pFormatter->GetNumDecimalSep(),
2644*cdf0e10cSrcweir                                                     c) || (c == ' ' &&
2645*cdf0e10cSrcweir                                                         StringEqualsChar(
2646*cdf0e10cSrcweir                                                             pFormatter->GetNumThousandSep(),
2647*cdf0e10cSrcweir                                                             cNonBreakingSpace))))
2648*cdf0e10cSrcweir                                     rString += sStrArray[i];
2649*cdf0e10cSrcweir                                 else if ((eScannedType & NUMBERFORMAT_DATE) &&
2650*cdf0e10cSrcweir                                         StringEqualsChar(
2651*cdf0e10cSrcweir                                             pFormatter->GetDateSep(), c))
2652*cdf0e10cSrcweir                                     rString += sStrArray[i];
2653*cdf0e10cSrcweir                                 else if ((eScannedType & NUMBERFORMAT_TIME) &&
2654*cdf0e10cSrcweir                                         (StringEqualsChar( pLoc->getTimeSep(),
2655*cdf0e10cSrcweir                                                            c) ||
2656*cdf0e10cSrcweir                                          StringEqualsChar(
2657*cdf0e10cSrcweir                                              pLoc->getTime100SecSep(), c)))
2658*cdf0e10cSrcweir                                     rString += sStrArray[i];
2659*cdf0e10cSrcweir                                 else if (eScannedType & NUMBERFORMAT_FRACTION)
2660*cdf0e10cSrcweir                                     rString += sStrArray[i];
2661*cdf0e10cSrcweir                                 else
2662*cdf0e10cSrcweir                                     rString += c;
2663*cdf0e10cSrcweir                                 break;
2664*cdf0e10cSrcweir                             default:
2665*cdf0e10cSrcweir                                 rString += sStrArray[i];
2666*cdf0e10cSrcweir                         }
2667*cdf0e10cSrcweir                     }
2668*cdf0e10cSrcweir                     else
2669*cdf0e10cSrcweir                         rString += sStrArray[i];
2670*cdf0e10cSrcweir 					if ( RemoveQuotes( sStrArray[i] ) > 0 )
2671*cdf0e10cSrcweir 					{	// update currency up to quoted string
2672*cdf0e10cSrcweir 						if ( eScannedType == NUMBERFORMAT_CURRENCY )
2673*cdf0e10cSrcweir 						{	// dM -> DM  or  DM -> $  in old automatic
2674*cdf0e10cSrcweir 							// currency formats, oh my ..., why did we ever
2675*cdf0e10cSrcweir 							// introduce them?
2676*cdf0e10cSrcweir 							String aTmp( pChrCls->toUpper(
2677*cdf0e10cSrcweir 								sStrArray[iPos], nArrPos,
2678*cdf0e10cSrcweir 								sStrArray[iPos].Len()-nArrPos ) );
2679*cdf0e10cSrcweir 							xub_StrLen nCPos = aTmp.Search( sOldCurString );
2680*cdf0e10cSrcweir 							if ( nCPos != STRING_NOTFOUND )
2681*cdf0e10cSrcweir 							{
2682*cdf0e10cSrcweir 								const String& rCur =
2683*cdf0e10cSrcweir 									bConvertMode && bConvertSystemToSystem ?
2684*cdf0e10cSrcweir                                     GetCurSymbol() : sOldCurSymbol;
2685*cdf0e10cSrcweir 								sStrArray[iPos].Replace( nArrPos+nCPos,
2686*cdf0e10cSrcweir 									sOldCurString.Len(), rCur );
2687*cdf0e10cSrcweir 								rString.Replace( nStringPos+nCPos,
2688*cdf0e10cSrcweir 									sOldCurString.Len(), rCur );
2689*cdf0e10cSrcweir 							}
2690*cdf0e10cSrcweir 							nStringPos = rString.Len();
2691*cdf0e10cSrcweir 							if ( iPos == i )
2692*cdf0e10cSrcweir 								nArrPos = sStrArray[iPos].Len();
2693*cdf0e10cSrcweir 							else
2694*cdf0e10cSrcweir 								nArrPos = sStrArray[iPos].Len() + sStrArray[i].Len();
2695*cdf0e10cSrcweir 						}
2696*cdf0e10cSrcweir 					}
2697*cdf0e10cSrcweir 					if ( iPos != i )
2698*cdf0e10cSrcweir 					{
2699*cdf0e10cSrcweir 						sStrArray[iPos] += sStrArray[i];
2700*cdf0e10cSrcweir 						nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
2701*cdf0e10cSrcweir 						nAnzResStrings--;
2702*cdf0e10cSrcweir 					}
2703*cdf0e10cSrcweir 					i++;
2704*cdf0e10cSrcweir 				} while ( i < nAnzStrings && nTypeArray[i] == NF_SYMBOLTYPE_STRING );
2705*cdf0e10cSrcweir 				if ( i < nAnzStrings )
2706*cdf0e10cSrcweir 					i--;	// enter switch on next symbol again
2707*cdf0e10cSrcweir 				if ( eScannedType == NUMBERFORMAT_CURRENCY && nStringPos < rString.Len() )
2708*cdf0e10cSrcweir 				{	// same as above, since last RemoveQuotes
2709*cdf0e10cSrcweir 					String aTmp( pChrCls->toUpper(
2710*cdf0e10cSrcweir 						sStrArray[iPos], nArrPos,
2711*cdf0e10cSrcweir 						sStrArray[iPos].Len()-nArrPos ) );
2712*cdf0e10cSrcweir 					xub_StrLen nCPos = aTmp.Search( sOldCurString );
2713*cdf0e10cSrcweir 					if ( nCPos != STRING_NOTFOUND )
2714*cdf0e10cSrcweir 					{
2715*cdf0e10cSrcweir 						const String& rCur =
2716*cdf0e10cSrcweir 							bConvertMode && bConvertSystemToSystem ?
2717*cdf0e10cSrcweir                             GetCurSymbol() : sOldCurSymbol;
2718*cdf0e10cSrcweir 						sStrArray[iPos].Replace( nArrPos+nCPos,
2719*cdf0e10cSrcweir 							sOldCurString.Len(), rCur );
2720*cdf0e10cSrcweir 						rString.Replace( nStringPos+nCPos,
2721*cdf0e10cSrcweir 							sOldCurString.Len(), rCur );
2722*cdf0e10cSrcweir 					}
2723*cdf0e10cSrcweir 				}
2724*cdf0e10cSrcweir 			}
2725*cdf0e10cSrcweir 			break;
2726*cdf0e10cSrcweir 			case NF_SYMBOLTYPE_CURRENCY :
2727*cdf0e10cSrcweir 			{
2728*cdf0e10cSrcweir 				rString += sStrArray[i];
2729*cdf0e10cSrcweir 				RemoveQuotes( sStrArray[i] );
2730*cdf0e10cSrcweir 			}
2731*cdf0e10cSrcweir 			break;
2732*cdf0e10cSrcweir             case NF_KEY_THAI_T:
2733*cdf0e10cSrcweir                 if (bThaiT && GetNatNumModifier() == 1)
2734*cdf0e10cSrcweir                 {   // Remove T from format code, will be replaced with a [NatNum1] prefix.
2735*cdf0e10cSrcweir                     nTypeArray[i] = NF_SYMBOLTYPE_EMPTY;
2736*cdf0e10cSrcweir                     nAnzResStrings--;
2737*cdf0e10cSrcweir                 }
2738*cdf0e10cSrcweir                 else
2739*cdf0e10cSrcweir                     rString += sStrArray[i];
2740*cdf0e10cSrcweir             break;
2741*cdf0e10cSrcweir 			case NF_SYMBOLTYPE_EMPTY :
2742*cdf0e10cSrcweir 				// nothing
2743*cdf0e10cSrcweir 			break;
2744*cdf0e10cSrcweir 			default:
2745*cdf0e10cSrcweir 				rString += sStrArray[i];
2746*cdf0e10cSrcweir 		}
2747*cdf0e10cSrcweir 		i++;
2748*cdf0e10cSrcweir 	}
2749*cdf0e10cSrcweir 	return 0;
2750*cdf0e10cSrcweir }
2751*cdf0e10cSrcweir 
2752*cdf0e10cSrcweir 
2753*cdf0e10cSrcweir xub_StrLen ImpSvNumberformatScan::RemoveQuotes( String& rStr )
2754*cdf0e10cSrcweir {
2755*cdf0e10cSrcweir 	if ( rStr.Len() > 1 )
2756*cdf0e10cSrcweir 	{
2757*cdf0e10cSrcweir 		sal_Unicode c = rStr.GetChar(0);
2758*cdf0e10cSrcweir 		xub_StrLen n;
2759*cdf0e10cSrcweir 		if ( c == '"' && rStr.GetChar( (n = xub_StrLen(rStr.Len()-1)) ) == '"' )
2760*cdf0e10cSrcweir 		{
2761*cdf0e10cSrcweir 			rStr.Erase(n,1);
2762*cdf0e10cSrcweir 			rStr.Erase(0,1);
2763*cdf0e10cSrcweir 			return 2;
2764*cdf0e10cSrcweir 		}
2765*cdf0e10cSrcweir 		else if ( c == '\\' )
2766*cdf0e10cSrcweir 		{
2767*cdf0e10cSrcweir 			rStr.Erase(0,1);
2768*cdf0e10cSrcweir 			return 1;
2769*cdf0e10cSrcweir 		}
2770*cdf0e10cSrcweir 	}
2771*cdf0e10cSrcweir 	return 0;
2772*cdf0e10cSrcweir }
2773*cdf0e10cSrcweir 
2774*cdf0e10cSrcweir 
2775*cdf0e10cSrcweir xub_StrLen ImpSvNumberformatScan::ScanFormat( String& rString, String& rComment )
2776*cdf0e10cSrcweir {
2777*cdf0e10cSrcweir 	xub_StrLen res = Symbol_Division(rString);	//lexikalische Analyse
2778*cdf0e10cSrcweir 	if (!res)
2779*cdf0e10cSrcweir 		res = ScanType(rString);            // Erkennung des Formattyps
2780*cdf0e10cSrcweir 	if (!res)
2781*cdf0e10cSrcweir 		res = FinalScan( rString, rComment );	// Typabhaengige Endanalyse
2782*cdf0e10cSrcweir 	return res;								// res = Kontrollposition
2783*cdf0e10cSrcweir 											// res = 0 => Format ok
2784*cdf0e10cSrcweir }
2785*cdf0e10cSrcweir 
2786*cdf0e10cSrcweir void ImpSvNumberformatScan::CopyInfo(ImpSvNumberformatInfo* pInfo, sal_uInt16 nAnz)
2787*cdf0e10cSrcweir {
2788*cdf0e10cSrcweir 	size_t i,j;
2789*cdf0e10cSrcweir 	j = 0;
2790*cdf0e10cSrcweir 	i = 0;
2791*cdf0e10cSrcweir 	while (i < nAnz && j < NF_MAX_FORMAT_SYMBOLS)
2792*cdf0e10cSrcweir 	{
2793*cdf0e10cSrcweir 		if (nTypeArray[j] != NF_SYMBOLTYPE_EMPTY)
2794*cdf0e10cSrcweir 		{
2795*cdf0e10cSrcweir 			pInfo->sStrArray[i]  = sStrArray[j];
2796*cdf0e10cSrcweir 			pInfo->nTypeArray[i] = nTypeArray[j];
2797*cdf0e10cSrcweir 			i++;
2798*cdf0e10cSrcweir 		}
2799*cdf0e10cSrcweir 		j++;
2800*cdf0e10cSrcweir 	}
2801*cdf0e10cSrcweir 	pInfo->eScannedType = eScannedType;
2802*cdf0e10cSrcweir 	pInfo->bThousand    = bThousand;
2803*cdf0e10cSrcweir 	pInfo->nThousand    = nThousand;
2804*cdf0e10cSrcweir 	pInfo->nCntPre      = nCntPre;
2805*cdf0e10cSrcweir 	pInfo->nCntPost     = nCntPost;
2806*cdf0e10cSrcweir 	pInfo->nCntExp      = nCntExp;
2807*cdf0e10cSrcweir }
2808*cdf0e10cSrcweir 
2809*cdf0e10cSrcweir 
2810