1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: zforscan.cxx,v $
10 * $Revision: 1.49.140.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
37 #include <tools/debug.hxx>
38 #include <i18npool/mslangid.hxx>
39 #include <unotools/charclass.hxx>
40 #include <unotools/localedatawrapper.hxx>
41 #include <unotools/numberformatcodewrapper.hxx>
42 #include <rtl/instance.hxx>
44 #include <svtools/zforlist.hxx>
45 #include <svtools/zformat.hxx>
46 #include <unotools/digitgroupingiterator.hxx>
49 #include "zforscan.hxx"
51 #include "nfsymbol.hxx"
54 const sal_Unicode cNonBreakingSpace
= 0xA0;
58 struct ImplEnglishColors
60 const String
* operator()()
62 static const String aEnglishColors
[NF_MAX_DEFAULT_COLORS
] =
64 String( RTL_CONSTASCII_USTRINGPARAM( "BLACK" ) ),
65 String( RTL_CONSTASCII_USTRINGPARAM( "BLUE" ) ),
66 String( RTL_CONSTASCII_USTRINGPARAM( "GREEN" ) ),
67 String( RTL_CONSTASCII_USTRINGPARAM( "CYAN" ) ),
68 String( RTL_CONSTASCII_USTRINGPARAM( "RED" ) ),
69 String( RTL_CONSTASCII_USTRINGPARAM( "MAGENTA" ) ),
70 String( RTL_CONSTASCII_USTRINGPARAM( "BROWN" ) ),
71 String( RTL_CONSTASCII_USTRINGPARAM( "GREY" ) ),
72 String( RTL_CONSTASCII_USTRINGPARAM( "YELLOW" ) ),
73 String( RTL_CONSTASCII_USTRINGPARAM( "WHITE" ) )
75 return &aEnglishColors
[0];
79 struct theEnglishColors
80 : public rtl::StaticAggregate
< const String
, ImplEnglishColors
> {};
84 ImpSvNumberformatScan::ImpSvNumberformatScan( SvNumberFormatter
* pFormatterP
)
86 pFormatter
= pFormatterP
;
88 //! All keywords MUST be UPPERCASE!
89 sKeyword
[NF_KEY_E
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "E" ) ); // Exponent
90 sKeyword
[NF_KEY_AMPM
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "AM/PM" ) ); // AM/PM
91 sKeyword
[NF_KEY_AP
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "A/P" ) ); // AM/PM short
92 sKeyword
[NF_KEY_MI
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "M" ) ); // Minute
93 sKeyword
[NF_KEY_MMI
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MM" ) ); // Minute 02
94 sKeyword
[NF_KEY_S
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "S" ) ); // Second
95 sKeyword
[NF_KEY_SS
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "SS" ) ); // Second 02
96 sKeyword
[NF_KEY_Q
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Q" ) ); // Quarter short 'Q'
97 sKeyword
[NF_KEY_QQ
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "QQ" ) ); // Quarter long
98 sKeyword
[NF_KEY_NN
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NN" ) ); // Day of week short
99 sKeyword
[NF_KEY_NNN
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NNN" ) ); // Day of week long
100 sKeyword
[NF_KEY_NNNN
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NNNN" ) ); // Day of week long incl. separator
101 sKeyword
[NF_KEY_WW
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "WW" ) ); // Week of year
102 sKeyword
[NF_KEY_CCC
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "CCC" ) ); // Currency abbreviation
103 bKeywordsNeedInit
= TRUE
; // locale dependent keywords
104 bCompatCurNeedInit
= TRUE
; // locale dependent compatibility currency strings
106 StandardColor
[0] = Color(COL_BLACK
);
107 StandardColor
[1] = Color(COL_LIGHTBLUE
);
108 StandardColor
[2] = Color(COL_LIGHTGREEN
);
109 StandardColor
[3] = Color(COL_LIGHTCYAN
);
110 StandardColor
[4] = Color(COL_LIGHTRED
);
111 StandardColor
[5] = Color(COL_LIGHTMAGENTA
);
112 StandardColor
[6] = Color(COL_BROWN
);
113 StandardColor
[7] = Color(COL_GRAY
);
114 StandardColor
[8] = Color(COL_YELLOW
);
115 StandardColor
[9] = Color(COL_WHITE
);
117 pNullDate
= new Date(30,12,1899);
120 sErrStr
.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "###" ) );
124 ImpSvNumberformatScan::~ImpSvNumberformatScan()
131 void ImpSvNumberformatScan::ChangeIntl()
133 bKeywordsNeedInit
= TRUE
;
134 bCompatCurNeedInit
= TRUE
;
135 // may be initialized by InitSpecialKeyword()
136 sKeyword
[NF_KEY_TRUE
].Erase();
137 sKeyword
[NF_KEY_FALSE
].Erase();
141 void ImpSvNumberformatScan::InitSpecialKeyword( NfKeywordIndex eIdx
) const
146 ((ImpSvNumberformatScan
*)this)->sKeyword
[NF_KEY_TRUE
] =
147 pFormatter
->GetCharClass()->upper(
148 pFormatter
->GetLocaleData()->getTrueWord() );
149 if ( !sKeyword
[NF_KEY_TRUE
].Len() )
151 DBG_ERRORFILE( "InitSpecialKeyword: TRUE_WORD?" );
152 ((ImpSvNumberformatScan
*)this)->sKeyword
[NF_KEY_TRUE
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "TRUE" ) );
156 ((ImpSvNumberformatScan
*)this)->sKeyword
[NF_KEY_FALSE
] =
157 pFormatter
->GetCharClass()->upper(
158 pFormatter
->GetLocaleData()->getFalseWord() );
159 if ( !sKeyword
[NF_KEY_FALSE
].Len() )
161 DBG_ERRORFILE( "InitSpecialKeyword: FALSE_WORD?" );
162 ((ImpSvNumberformatScan
*)this)->sKeyword
[NF_KEY_FALSE
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "FALSE" ) );
166 DBG_ERRORFILE( "InitSpecialKeyword: unknown request" );
171 void ImpSvNumberformatScan::InitCompatCur() const
173 ImpSvNumberformatScan
* pThis
= (ImpSvNumberformatScan
*)this;
174 // currency symbol for old style ("automatic") compatibility format codes
175 pFormatter
->GetCompatibilityCurrency( pThis
->sCurSymbol
, pThis
->sCurAbbrev
);
176 // currency symbol upper case
177 pThis
->sCurString
= pFormatter
->GetCharClass()->upper( sCurSymbol
);
178 bCompatCurNeedInit
= FALSE
;
182 void ImpSvNumberformatScan::InitKeywords() const
184 if ( !bKeywordsNeedInit
)
186 ((ImpSvNumberformatScan
*)this)->SetDependentKeywords();
187 bKeywordsNeedInit
= FALSE
;
191 /** Extract the name of General, Standard, Whatever, ignoring leading modifiers
192 such as [NatNum1]. */
193 static String
lcl_extractStandardGeneralName( const ::rtl::OUString
& rCode
)
196 const sal_Unicode
* p
= rCode
.getStr();
197 const sal_Unicode
* const pStop
= p
+ rCode
.getLength();
198 const sal_Unicode
* pBeg
= p
; // name begins here
201 while (p
< pStop
&& !bDone
)
214 // else: would be a locale data error, easily to be spotted in
221 --p
; // put back, increment by one follows
230 aStr
= rCode
.copy( pBeg
- rCode
.getStr(), p
- pBeg
);
235 void ImpSvNumberformatScan::SetDependentKeywords()
237 using namespace ::com::sun::star
;
238 using namespace ::com::sun::star::uno
;
240 const CharClass
* pCharClass
= pFormatter
->GetCharClass();
241 const LocaleDataWrapper
* pLocaleData
= pFormatter
->GetLocaleData();
242 // #80023# be sure to generate keywords for the loaded Locale, not for the
243 // requested Locale, otherwise number format codes might not match
244 lang::Locale aLoadedLocale
= pLocaleData
->getLoadedLocale();
245 LanguageType eLang
= MsLangId::convertLocaleToLanguage( aLoadedLocale
);
246 NumberFormatCodeWrapper
aNumberFormatCode( pFormatter
->GetServiceManager(), aLoadedLocale
);
248 i18n::NumberFormatCode aFormat
= aNumberFormatCode
.getFormatCode( NF_NUMBER_STANDARD
);
249 sNameStandardFormat
= lcl_extractStandardGeneralName( aFormat
.Code
);
250 sKeyword
[NF_KEY_GENERAL
] = pCharClass
->upper( sNameStandardFormat
);
252 // preset new calendar keywords
253 sKeyword
[NF_KEY_AAA
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "AAA" ) );
254 sKeyword
[NF_KEY_AAAA
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "AAAA" ) );
255 sKeyword
[NF_KEY_EC
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "E" ) );
256 sKeyword
[NF_KEY_EEC
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "EE" ) );
257 sKeyword
[NF_KEY_G
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "G" ) );
258 sKeyword
[NF_KEY_GG
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GG" ) );
259 sKeyword
[NF_KEY_GGG
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GGG" ) );
260 sKeyword
[NF_KEY_R
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "R" ) );
261 sKeyword
[NF_KEY_RR
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "RR" ) );
263 // Thai T NatNum special. Other locale's small letter 't' results in upper
264 // case comparison not matching but length does in conversion mode. Ugly.
265 if (eLang
== LANGUAGE_THAI
)
266 sKeyword
[NF_KEY_THAI_T
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "T"));
268 sKeyword
[NF_KEY_THAI_T
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "t"));
272 case LANGUAGE_GERMAN
:
273 case LANGUAGE_GERMAN_SWISS
:
274 case LANGUAGE_GERMAN_AUSTRIAN
:
275 case LANGUAGE_GERMAN_LUXEMBOURG
:
276 case LANGUAGE_GERMAN_LIECHTENSTEIN
:
278 //! all capital letters
279 sKeyword
[NF_KEY_M
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "M" ) ); // month 1
280 sKeyword
[NF_KEY_MM
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MM" ) ); // month 01
281 sKeyword
[NF_KEY_MMM
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMM" ) ); // month Jan
282 sKeyword
[NF_KEY_MMMM
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMMM" ) ); // month Januar
283 sKeyword
[NF_KEY_MMMMM
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMMMM" ) );// month J
284 sKeyword
[NF_KEY_H
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "H" ) ); // hour 2
285 sKeyword
[NF_KEY_HH
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "HH" ) ); // hour 02
286 sKeyword
[NF_KEY_D
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "T" ) );
287 sKeyword
[NF_KEY_DD
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "TT" ) );
288 sKeyword
[NF_KEY_DDD
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "TTT" ) );
289 sKeyword
[NF_KEY_DDDD
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "TTTT" ) );
290 sKeyword
[NF_KEY_YY
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJ" ) );
291 sKeyword
[NF_KEY_YYYY
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJJJ" ) );
292 sKeyword
[NF_KEY_BOOLEAN
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "LOGISCH" ) );
293 sKeyword
[NF_KEY_COLOR
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "FARBE" ) );
294 sKeyword
[NF_KEY_BLACK
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "SCHWARZ" ) );
295 sKeyword
[NF_KEY_BLUE
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "BLAU" ) );
296 sKeyword
[NF_KEY_GREEN
] = UniString( "GR" "\xDC" "N", RTL_TEXTENCODING_ISO_8859_1
);
297 sKeyword
[NF_KEY_CYAN
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "CYAN" ) );
298 sKeyword
[NF_KEY_RED
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "ROT" ) );
299 sKeyword
[NF_KEY_MAGENTA
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MAGENTA" ) );
300 sKeyword
[NF_KEY_BROWN
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "BRAUN" ) );
301 sKeyword
[NF_KEY_GREY
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GRAU" ) );
302 sKeyword
[NF_KEY_YELLOW
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GELB" ) );
303 sKeyword
[NF_KEY_WHITE
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "WEISS" ) );
311 case LANGUAGE_ITALIAN
:
312 case LANGUAGE_ITALIAN_SWISS
:
313 sKeyword
[NF_KEY_D
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "G" ) );
314 sKeyword
[NF_KEY_DD
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GG" ) );
315 sKeyword
[NF_KEY_DDD
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GGG" ) );
316 sKeyword
[NF_KEY_DDDD
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GGGG" ) );
317 // must exchange the era code, same as Xcl
318 sKeyword
[NF_KEY_G
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "X" ) );
319 sKeyword
[NF_KEY_GG
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "XX" ) );
320 sKeyword
[NF_KEY_GGG
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "XXX" ) );
322 case LANGUAGE_FRENCH
:
323 case LANGUAGE_FRENCH_BELGIAN
:
324 case LANGUAGE_FRENCH_CANADIAN
:
325 case LANGUAGE_FRENCH_SWISS
:
326 case LANGUAGE_FRENCH_LUXEMBOURG
:
327 case LANGUAGE_FRENCH_MONACO
:
328 sKeyword
[NF_KEY_D
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "J" ) );
329 sKeyword
[NF_KEY_DD
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJ" ) );
330 sKeyword
[NF_KEY_DDD
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJJ" ) );
331 sKeyword
[NF_KEY_DDDD
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJJJ" ) );
333 case LANGUAGE_FINNISH
:
334 sKeyword
[NF_KEY_D
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "P" ) );
335 sKeyword
[NF_KEY_DD
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "PP" ) );
336 sKeyword
[NF_KEY_DDD
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "PPP" ) );
337 sKeyword
[NF_KEY_DDDD
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "PPPP" ) );
340 sKeyword
[NF_KEY_D
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D" ) );
341 sKeyword
[NF_KEY_DD
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DD" ) );
342 sKeyword
[NF_KEY_DDD
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDD" ) );
343 sKeyword
[NF_KEY_DDDD
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDDD" ) );
348 case LANGUAGE_FINNISH
:
349 sKeyword
[NF_KEY_M
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "K" ) );
350 sKeyword
[NF_KEY_MM
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "KK" ) );
351 sKeyword
[NF_KEY_MMM
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "KKK" ) );
352 sKeyword
[NF_KEY_MMMM
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "KKKK" ) );
353 sKeyword
[NF_KEY_MMMMM
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "KKKKK" ) );
356 sKeyword
[NF_KEY_M
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "M" ) );
357 sKeyword
[NF_KEY_MM
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MM" ) );
358 sKeyword
[NF_KEY_MMM
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMM" ) );
359 sKeyword
[NF_KEY_MMMM
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMMM" ) );
360 sKeyword
[NF_KEY_MMMMM
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMMMM" ) );
365 case LANGUAGE_ITALIAN
:
366 case LANGUAGE_ITALIAN_SWISS
:
367 case LANGUAGE_FRENCH
:
368 case LANGUAGE_FRENCH_BELGIAN
:
369 case LANGUAGE_FRENCH_CANADIAN
:
370 case LANGUAGE_FRENCH_SWISS
:
371 case LANGUAGE_FRENCH_LUXEMBOURG
:
372 case LANGUAGE_FRENCH_MONACO
:
373 case LANGUAGE_PORTUGUESE
:
374 case LANGUAGE_PORTUGUESE_BRAZILIAN
:
375 case LANGUAGE_SPANISH_MODERN
:
376 case LANGUAGE_SPANISH_DATED
:
377 case LANGUAGE_SPANISH_MEXICAN
:
378 case LANGUAGE_SPANISH_GUATEMALA
:
379 case LANGUAGE_SPANISH_COSTARICA
:
380 case LANGUAGE_SPANISH_PANAMA
:
381 case LANGUAGE_SPANISH_DOMINICAN_REPUBLIC
:
382 case LANGUAGE_SPANISH_VENEZUELA
:
383 case LANGUAGE_SPANISH_COLOMBIA
:
384 case LANGUAGE_SPANISH_PERU
:
385 case LANGUAGE_SPANISH_ARGENTINA
:
386 case LANGUAGE_SPANISH_ECUADOR
:
387 case LANGUAGE_SPANISH_CHILE
:
388 case LANGUAGE_SPANISH_URUGUAY
:
389 case LANGUAGE_SPANISH_PARAGUAY
:
390 case LANGUAGE_SPANISH_BOLIVIA
:
391 case LANGUAGE_SPANISH_EL_SALVADOR
:
392 case LANGUAGE_SPANISH_HONDURAS
:
393 case LANGUAGE_SPANISH_NICARAGUA
:
394 case LANGUAGE_SPANISH_PUERTO_RICO
:
395 sKeyword
[NF_KEY_YY
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "AA" ) );
396 sKeyword
[NF_KEY_YYYY
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "AAAA" ) );
397 // must exchange the day of week name code, same as Xcl
398 sKeyword
[NF_KEY_AAA
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "OOO" ) );
399 sKeyword
[NF_KEY_AAAA
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "OOOO" ) );
401 case LANGUAGE_DUTCH
:
402 case LANGUAGE_DUTCH_BELGIAN
:
403 sKeyword
[NF_KEY_YY
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJ" ) );
404 sKeyword
[NF_KEY_YYYY
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJJJ" ) );
406 case LANGUAGE_FINNISH
:
407 sKeyword
[NF_KEY_YY
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "VV" ) );
408 sKeyword
[NF_KEY_YYYY
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "VVVV" ) );
411 sKeyword
[NF_KEY_YY
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "YY" ) );
412 sKeyword
[NF_KEY_YYYY
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "YYYY" ) );
417 case LANGUAGE_DUTCH
:
418 case LANGUAGE_DUTCH_BELGIAN
:
419 sKeyword
[NF_KEY_H
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "U" ) );
420 sKeyword
[NF_KEY_HH
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "UU" ) );
422 case LANGUAGE_FINNISH
:
423 case LANGUAGE_SWEDISH
:
424 case LANGUAGE_SWEDISH_FINLAND
:
425 case LANGUAGE_DANISH
:
426 case LANGUAGE_NORWEGIAN
:
427 case LANGUAGE_NORWEGIAN_BOKMAL
:
428 case LANGUAGE_NORWEGIAN_NYNORSK
:
429 sKeyword
[NF_KEY_H
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "T" ) );
430 sKeyword
[NF_KEY_HH
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "TT" ) );
433 sKeyword
[NF_KEY_H
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "H" ) );
434 sKeyword
[NF_KEY_HH
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "HH" ) );
437 sKeyword
[NF_KEY_BOOLEAN
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "BOOLEAN" ) );
439 sKeyword
[NF_KEY_COLOR
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "COLOR" ) );
440 sKeyword
[NF_KEY_BLACK
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "BLACK" ) );
441 sKeyword
[NF_KEY_BLUE
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "BLUE" ) );
442 sKeyword
[NF_KEY_GREEN
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GREEN" ) );
443 sKeyword
[NF_KEY_CYAN
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "CYAN" ) );
444 sKeyword
[NF_KEY_RED
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "RED" ) );
445 sKeyword
[NF_KEY_MAGENTA
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MAGENTA" ) );
446 sKeyword
[NF_KEY_BROWN
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "BROWN" ) );
447 sKeyword
[NF_KEY_GREY
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GREY" ) );
448 sKeyword
[NF_KEY_YELLOW
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "YELLOW" ) );
449 sKeyword
[NF_KEY_WHITE
].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "WHITE" ) );
455 InitSpecialKeyword( NF_KEY_TRUE
);
456 InitSpecialKeyword( NF_KEY_FALSE
);
458 // compatibility currency strings
463 void ImpSvNumberformatScan::ChangeNullDate(USHORT nDay
, USHORT nMonth
, USHORT nYear
)
466 *pNullDate
= Date(nDay
, nMonth
, nYear
);
468 pNullDate
= new Date(nDay
, nMonth
, nYear
);
471 void ImpSvNumberformatScan::ChangeStandardPrec(short nPrec
)
473 nStandardPrec
= nPrec
;
476 Color
* ImpSvNumberformatScan::GetColor(String
& sStr
)
478 String sString
= pFormatter
->GetCharClass()->upper(sStr
);
479 const String
* pKeyword
= GetKeywords();
481 while (i
< NF_MAX_DEFAULT_COLORS
&&
482 sString
!= pKeyword
[NF_KEY_FIRSTCOLOR
+i
] )
484 if ( i
>= NF_MAX_DEFAULT_COLORS
)
486 const String
* pEnglishColors
= theEnglishColors::get();
488 while ( j
< NF_MAX_DEFAULT_COLORS
&&
489 sString
!= pEnglishColors
[j
] )
491 if ( j
< NF_MAX_DEFAULT_COLORS
)
495 Color
* pResult
= NULL
;
496 if (i
>= NF_MAX_DEFAULT_COLORS
)
498 const String
& rColorWord
= pKeyword
[NF_KEY_COLOR
];
499 xub_StrLen nPos
= sString
.Match(rColorWord
);
503 sStr
.EraseLeadingChars();
504 sStr
.EraseTrailingChars();
507 pFormatter
->ChangeIntl(eNewLnge
);
508 sStr
.Insert( GetKeywords()[NF_KEY_COLOR
], 0 ); // Color -> FARBE
509 pFormatter
->ChangeIntl(eTmpLnge
);
512 sStr
.Insert(rColorWord
,0);
513 sString
.Erase(0, nPos
);
514 sString
.EraseLeadingChars();
515 sString
.EraseTrailingChars();
517 if ( CharClass::isAsciiNumeric( sString
) )
519 long nIndex
= sString
.ToInt32();
520 if (nIndex
> 0 && nIndex
<= 64)
521 pResult
= pFormatter
->GetUserDefColor((USHORT
)nIndex
-1);
530 pFormatter
->ChangeIntl(eNewLnge
);
531 sStr
= GetKeywords()[NF_KEY_FIRSTCOLOR
+i
]; // red -> rot
532 pFormatter
->ChangeIntl(eTmpLnge
);
535 sStr
= pKeyword
[NF_KEY_FIRSTCOLOR
+i
];
537 pResult
= &(StandardColor
[i
]);
543 short ImpSvNumberformatScan::GetKeyWord( const String
& sSymbol
, xub_StrLen nPos
)
545 String sString
= pFormatter
->GetCharClass()->toUpper( sSymbol
, nPos
, sSymbol
.Len() - nPos
);
546 const String
* pKeyword
= GetKeywords();
547 // #77026# for the Xcl perverts: the GENERAL keyword is recognized anywhere
548 if ( sString
.Search( pKeyword
[NF_KEY_GENERAL
] ) == 0 )
549 return NF_KEY_GENERAL
;
550 //! MUST be a reverse search to find longer strings first
551 short i
= NF_KEYWORD_ENTRIES_COUNT
-1;
553 for ( ; i
> NF_KEY_LASTKEYWORD_SO5
; --i
)
555 bFound
= sString
.Search(pKeyword
[i
]) == 0;
561 // new keywords take precedence over old keywords
563 { // skip the gap of colors et al between new and old keywords and search on
564 i
= NF_KEY_LASTKEYWORD
;
565 while ( i
> 0 && sString
.Search(pKeyword
[i
]) != 0 )
567 if ( i
> NF_KEY_LASTOLDKEYWORD
&& sString
!= pKeyword
[i
] )
568 { // found something, but maybe it's something else?
569 // e.g. new NNN is found in NNNN, for NNNN we must search on
571 while ( j
> 0 && sString
.Search(pKeyword
[j
]) != 0 )
573 if ( j
&& pKeyword
[j
].Len() > pKeyword
[i
].Len() )
577 // The Thai T NatNum modifier during Xcl import.
578 if (i
== 0 && bConvertMode
&& sString
.GetChar(0) == 'T' && eTmpLnge
==
579 LANGUAGE_ENGLISH_US
&& MsLangId::getRealLanguage( eNewLnge
) ==
582 return i
; // 0 => not found
585 //---------------------------------------------------------------------------
587 //---------------------------------------------------------------------------
588 // Zerlegt die Eingabe in Symbole fuer die weitere
589 // Verarbeitung (Turing-Maschine).
590 //---------------------------------------------------------------------------
591 // Ausgangs Zustand = SsStart
592 //---------------+-------------------+-----------------------+---------------
593 // Alter Zustand | gelesenes Zeichen | Aktion | Neuer Zustand
594 //---------------+-------------------+-----------------------+---------------
595 // SsStart | Buchstabe | Symbol=Zeichen | SsGetWord
596 // | " | Typ = String | SsGetString
597 // | \ | Typ = String | SsGetChar
598 // | * | Typ = Star | SsGetStar
599 // | _ | Typ = Blank | SsGetBlank
600 // | @ # 0 ? / . , % [ | Symbol = Zeichen; |
601 // | ] ' Blank | Typ = Steuerzeichen | SsStop
602 // | $ - + ( ) : | Typ = String; |
603 // | | | Typ = Comment | SsStop
604 // | Sonst | Symbol = Zeichen | SsStop
605 //---------------|-------------------+-----------------------+---------------
606 // SsGetChar | Sonst | Symbol=Zeichen | SsStop
607 //---------------+-------------------+-----------------------+---------------
608 // GetString | " | | SsStop
609 // | Sonst | Symbol+=Zeichen | GetString
610 //---------------+-------------------+-----------------------+---------------
611 // SsGetWord | Buchstabe | Symbol += Zeichen |
612 // | + - (E+ E-)| Symbol += Zeichen | SsStop
613 // | / (AM/PM)| Symbol += Zeichen |
614 // | Sonst | Pos--, if Key Typ=Word| SsStop
615 //---------------+-------------------+-----------------------+---------------
616 // SsGetStar | Sonst | Symbol+=Zeichen | SsStop
617 // | | markiere Sonderfall * |
618 //---------------+-------------------+-----------------------+---------------
619 // SsGetBlank | Sonst | Symbol+=Zeichen | SsStop
620 // | | markiere Sonderfall _ |
621 //---------------+-------------------+-----------------------+---------------
622 // Wurde im State SsGetWord ein Schluesselwort erkannt (auch als
623 // Anfangsteilwort des Symbols)
624 // so werden die restlichen Buchstaben zurueckgeschrieben !!
637 short ImpSvNumberformatScan::Next_Symbol( const String
& rStr
,
638 xub_StrLen
& nPos
, String
& sSymbol
)
640 if ( bKeywordsNeedInit
)
642 const CharClass
* pChrCls
= pFormatter
->GetCharClass();
643 const LocaleDataWrapper
* pLoc
= pFormatter
->GetLocaleData();
644 const xub_StrLen nStart
= nPos
;
646 ScanState eState
= SsStart
;
648 while ( nPos
< rStr
.Len() && eState
!= SsStop
)
650 sal_Unicode cToken
= rStr
.GetChar( nPos
++ );
655 // Fetch any currency longer than one character and don't get
656 // confused later on by "E/" or other combinations of letters
657 // and meaningful symbols. Necessary for old automatic currency.
658 // #96158# But don't do it if we're starting a "[...]" section,
659 // for example a "[$...]" new currency symbol to not parse away
660 // "$U" (symbol) of "[$UYU]" (abbreviation).
661 if ( nCurrPos
!= STRING_NOTFOUND
&& sCurString
.Len() > 1 &&
662 nPos
-1 + sCurString
.Len() <= rStr
.Len() &&
663 !(nPos
> 1 && rStr
.GetChar( nPos
-2 ) == '[') )
665 String
aTest( rStr
.Copy( nPos
-1, sCurString
.Len() ) );
666 pChrCls
->toUpper( aTest
);
667 if ( aTest
== sCurString
)
669 sSymbol
= rStr
.Copy( --nPos
, sCurString
.Len() );
670 nPos
= nPos
+ sSymbol
.Len();
672 eType
= NF_SYMBOLTYPE_STRING
;
693 eType
= NF_SYMBOLTYPE_DEL
;
700 eType
= NF_SYMBOLTYPE_STAR
;
707 eType
= NF_SYMBOLTYPE_BLANK
;
712 #if NF_COMMENT_IN_FORMATSTRING
714 eType
= NF_SYMBOLTYPE_COMMENT
;
716 sSymbol
.Append( rStr
.GetBuffer() + (nPos
-1), rStr
.Len() - (nPos
-1) );
721 eType
= NF_SYMBOLTYPE_STRING
;
722 eState
= SsGetString
;
726 eType
= NF_SYMBOLTYPE_STRING
;
734 eType
= NF_SYMBOLTYPE_STRING
;
740 if (StringEqualsChar( pFormatter
->GetNumDecimalSep(), cToken
) ||
741 StringEqualsChar( pFormatter
->GetNumThousandSep(), cToken
) ||
742 StringEqualsChar( pFormatter
->GetDateSep(), cToken
) ||
743 StringEqualsChar( pLoc
->getTimeSep(), cToken
) ||
744 StringEqualsChar( pLoc
->getTime100SecSep(), cToken
))
746 // Another separator than pre-known ASCII
747 eType
= NF_SYMBOLTYPE_DEL
;
751 else if ( pChrCls
->isLetter( rStr
, nPos
-1 ) )
753 short nTmpType
= GetKeyWord( rStr
, nPos
-1 );
756 BOOL bCurrency
= FALSE
;
757 // "Automatic" currency may start with keyword,
758 // like "R" (Rand) and 'R' (era)
759 if ( nCurrPos
!= STRING_NOTFOUND
&&
760 nPos
-1 + sCurString
.Len() <= rStr
.Len() &&
761 sCurString
.Search( sKeyword
[nTmpType
] ) == 0 )
763 String
aTest( rStr
.Copy( nPos
-1, sCurString
.Len() ) );
764 pChrCls
->toUpper( aTest
);
765 if ( aTest
== sCurString
)
776 xub_StrLen nLen
= sKeyword
[eType
].Len();
777 sSymbol
= rStr
.Copy( nPos
-1, nLen
);
778 if ( eType
== NF_KEY_E
|| IsAmbiguousE( eType
) )
780 sal_Unicode cNext
= rStr
.GetChar(nPos
);
784 case '-' : // E+ E- combine to one symbol
790 case '#' : // scientific E without sign
808 eType
= NF_SYMBOLTYPE_STRING
;
832 if ( pChrCls
->isLetter( rStr
, nPos
-1 ) )
834 short nTmpType
= GetKeyWord( rStr
, nPos
-1 );
836 { // beginning of keyword, stop scan and put back
837 eType
= NF_SYMBOLTYPE_STRING
;
846 BOOL bDontStop
= FALSE
;
849 case '/': // AM/PM, A/P
851 sal_Unicode cNext
= rStr
.GetChar(nPos
);
852 if ( cNext
== 'P' || cNext
== 'p' )
854 xub_StrLen nLen
= sSymbol
.Len();
856 && (sSymbol
.GetChar(0) == 'A' || sSymbol
.GetChar(0) == 'a')
857 && (nLen
== 1 || (nLen
== 2
858 && (sSymbol
.GetChar(1) == 'M' || sSymbol
.GetChar(1) == 'm')
859 && (rStr
.GetChar(nPos
+1) == 'M' || rStr
.GetChar(nPos
+1) == 'm'))) )
868 // anything not recognized will stop the scan
869 if ( eState
!= SsStop
&& !bDontStop
)
873 eType
= NF_SYMBOLTYPE_STRING
;
882 nRepPos
= (nPos
- nStart
) - 1; // everytime > 0!!
895 if (eState
== SsGetWord
)
896 eType
= NF_SYMBOLTYPE_STRING
;
900 xub_StrLen
ImpSvNumberformatScan::Symbol_Division(const String
& rString
)
902 nCurrPos
= STRING_NOTFOUND
;
903 // Ist Waehrung im Spiel?
904 String sString
= pFormatter
->GetCharClass()->upper(rString
);
905 xub_StrLen nCPos
= 0;
906 while (nCPos
!= STRING_NOTFOUND
)
908 nCPos
= sString
.Search(GetCurString(),nCPos
);
909 if (nCPos
!= STRING_NOTFOUND
)
912 xub_StrLen nQ
= SvNumberformat::GetQuoteEnd( sString
, nCPos
);
913 if ( nQ
== STRING_NOTFOUND
)
917 ((c
= sString
.GetChar(xub_StrLen(nCPos
-1))) != '"'
918 && c
!= '\\') ) // dm kann durch "dm
919 { // \d geschuetzt werden
921 nCPos
= STRING_NOTFOUND
; // Abbruch
924 nCPos
++; // weitersuchen
927 nCPos
= nQ
+ 1; // weitersuchen
931 BOOL bStar
= FALSE
; // wird bei '*'Detektion gesetzt
935 const xub_StrLen nLen
= rString
.Len();
936 while (nPos
< nLen
&& nAnzStrings
< NF_MAX_FORMAT_SYMBOLS
)
938 nTypeArray
[nAnzStrings
] = Next_Symbol(rString
, nPos
, sStrArray
[nAnzStrings
]);
939 if (nTypeArray
[nAnzStrings
] == NF_SYMBOLTYPE_STAR
)
940 { // Ueberwachung des '*'
942 return nPos
; // Fehler: doppelter '*'
952 void ImpSvNumberformatScan::SkipStrings(USHORT
& i
, xub_StrLen
& nPos
)
954 while (i
< nAnzStrings
&& ( nTypeArray
[i
] == NF_SYMBOLTYPE_STRING
955 || nTypeArray
[i
] == NF_SYMBOLTYPE_BLANK
956 || nTypeArray
[i
] == NF_SYMBOLTYPE_STAR
) )
958 nPos
= nPos
+ sStrArray
[i
].Len();
964 USHORT
ImpSvNumberformatScan::PreviousKeyword(USHORT i
)
967 if (i
> 0 && i
< nAnzStrings
)
970 while (i
> 0 && nTypeArray
[i
] <= 0)
972 if (nTypeArray
[i
] > 0)
978 USHORT
ImpSvNumberformatScan::NextKeyword(USHORT i
)
981 if (i
< nAnzStrings
-1)
984 while (i
< nAnzStrings
-1 && nTypeArray
[i
] <= 0)
986 if (nTypeArray
[i
] > 0)
992 short ImpSvNumberformatScan::PreviousType( USHORT i
)
994 if ( i
> 0 && i
< nAnzStrings
)
999 } while ( i
> 0 && nTypeArray
[i
] == NF_SYMBOLTYPE_EMPTY
);
1000 return nTypeArray
[i
];
1005 sal_Unicode
ImpSvNumberformatScan::PreviousChar(USHORT i
)
1007 sal_Unicode res
= ' ';
1008 if (i
> 0 && i
< nAnzStrings
)
1011 while (i
> 0 && ( nTypeArray
[i
] == NF_SYMBOLTYPE_EMPTY
1012 || nTypeArray
[i
] == NF_SYMBOLTYPE_STRING
1013 || nTypeArray
[i
] == NF_SYMBOLTYPE_STAR
1014 || nTypeArray
[i
] == NF_SYMBOLTYPE_BLANK
) )
1016 if (sStrArray
[i
].Len() > 0)
1017 res
= sStrArray
[i
].GetChar(xub_StrLen(sStrArray
[i
].Len()-1));
1022 sal_Unicode
ImpSvNumberformatScan::NextChar(USHORT i
)
1024 sal_Unicode res
= ' ';
1025 if (i
< nAnzStrings
-1)
1028 while (i
< nAnzStrings
-1 &&
1029 ( nTypeArray
[i
] == NF_SYMBOLTYPE_EMPTY
1030 || nTypeArray
[i
] == NF_SYMBOLTYPE_STRING
1031 || nTypeArray
[i
] == NF_SYMBOLTYPE_STAR
1032 || nTypeArray
[i
] == NF_SYMBOLTYPE_BLANK
))
1034 if (sStrArray
[i
].Len() > 0)
1035 res
= sStrArray
[i
].GetChar(0);
1040 BOOL
ImpSvNumberformatScan::IsLastBlankBeforeFrac(USHORT i
)
1043 if (i
< nAnzStrings
-1)
1047 while (i
< nAnzStrings
-1 && !bStop
)
1050 if ( nTypeArray
[i
] == NF_SYMBOLTYPE_DEL
&&
1051 sStrArray
[i
].GetChar(0) == '/')
1053 else if ( nTypeArray
[i
] == NF_SYMBOLTYPE_DEL
&&
1054 sStrArray
[i
].GetChar(0) == ' ')
1057 if (!bStop
) // kein '/'
1061 res
= FALSE
; // kein '/' mehr
1066 void ImpSvNumberformatScan::Reset()
1071 // ER 20.06.97 14:05 nicht noetig, wenn nAnzStrings beachtet wird
1072 for (size_t i
= 0; i
< NF_MAX_FORMAT_SYMBOLS
; i
++)
1074 sStrArray
[i
].Erase();
1078 eScannedType
= NUMBERFORMAT_UNDEFINED
;
1085 nExpPos
= (USHORT
) -1;
1086 nBlankPos
= (USHORT
) -1;
1092 nNatNumModifier
= 0;
1096 BOOL
ImpSvNumberformatScan::Is100SecZero( USHORT i
, BOOL bHadDecSep
)
1098 USHORT nIndexPre
= PreviousKeyword( i
);
1099 return (nIndexPre
== NF_KEY_S
|| nIndexPre
== NF_KEY_SS
)
1100 && (bHadDecSep
// S, SS ','
1101 || (i
>0 && nTypeArray
[i
-1] == NF_SYMBOLTYPE_STRING
));
1102 // SS"any"00 take "any" as a valid decimal separator
1106 xub_StrLen
ImpSvNumberformatScan::ScanType(const String
&)
1108 const LocaleDataWrapper
* pLoc
= pFormatter
->GetLocaleData();
1110 xub_StrLen nPos
= 0;
1113 BOOL bMatchBracket
= FALSE
;
1114 bool bHaveGeneral
= false; // if General/Standard encountered
1116 SkipStrings(i
, nPos
);
1117 while (i
< nAnzStrings
)
1119 if (nTypeArray
[i
] > 0)
1121 switch (nTypeArray
[i
])
1124 eNewType
= NUMBERFORMAT_SCIENTIFIC
;
1126 case NF_KEY_AMPM
: // AM,A,PM,P
1129 case NF_KEY_HH
: // HH
1131 case NF_KEY_SS
: // SS
1132 eNewType
= NUMBERFORMAT_TIME
;
1135 case NF_KEY_MM
: // MM
1136 { // minute or month
1137 USHORT nIndexPre
= PreviousKeyword(i
);
1138 USHORT nIndexNex
= NextKeyword(i
);
1139 sal_Unicode cChar
= PreviousChar(i
);
1140 if (nIndexPre
== NF_KEY_H
|| // H
1141 nIndexPre
== NF_KEY_HH
|| // HH
1142 nIndexNex
== NF_KEY_S
|| // S
1143 nIndexNex
== NF_KEY_SS
|| // SS
1144 cChar
== '[' ) // [M
1146 eNewType
= NUMBERFORMAT_TIME
;
1147 nTypeArray
[i
] -= 2; // 6 -> 4, 7 -> 5
1150 eNewType
= NUMBERFORMAT_DATE
;
1153 case NF_KEY_MMM
: // MMM
1154 case NF_KEY_MMMM
: // MMMM
1155 case NF_KEY_MMMMM
: // MMMMM
1157 case NF_KEY_QQ
: // QQ
1159 case NF_KEY_DD
: // DD
1160 case NF_KEY_DDD
: // DDD
1161 case NF_KEY_DDDD
: // DDDD
1162 case NF_KEY_YY
: // YY
1163 case NF_KEY_YYYY
: // YYYY
1164 case NF_KEY_NN
: // NN
1165 case NF_KEY_NNN
: // NNN
1166 case NF_KEY_NNNN
: // NNNN
1167 case NF_KEY_WW
: // WW
1168 case NF_KEY_AAA
: // AAA
1169 case NF_KEY_AAAA
: // AAAA
1170 case NF_KEY_EC
: // E
1171 case NF_KEY_EEC
: // EE
1172 case NF_KEY_G
: // G
1173 case NF_KEY_GG
: // GG
1174 case NF_KEY_GGG
: // GGG
1175 case NF_KEY_R
: // R
1176 case NF_KEY_RR
: // RR
1177 eNewType
= NUMBERFORMAT_DATE
;
1179 case NF_KEY_CCC
: // CCC
1180 eNewType
= NUMBERFORMAT_CURRENCY
;
1182 case NF_KEY_GENERAL
: // Standard
1183 eNewType
= NUMBERFORMAT_NUMBER
;
1184 bHaveGeneral
= true;
1187 eNewType
= NUMBERFORMAT_UNDEFINED
;
1192 { // control character
1193 switch ( sStrArray
[i
].GetChar(0) )
1197 eNewType
= NUMBERFORMAT_NUMBER
;
1201 if ( (eScannedType
& NUMBERFORMAT_TIME
) == NUMBERFORMAT_TIME
)
1203 if ( Is100SecZero( i
, bDecSep
) )
1205 bDecSep
= TRUE
; // subsequent 0's
1206 eNewType
= NUMBERFORMAT_TIME
;
1209 return nPos
; // Error
1212 eNewType
= NUMBERFORMAT_NUMBER
;
1216 eNewType
= NUMBERFORMAT_PERCENT
;
1219 eNewType
= NUMBERFORMAT_FRACTION
;
1223 if ( i
< nAnzStrings
-1 &&
1224 nTypeArray
[i
+1] == NF_SYMBOLTYPE_STRING
&&
1225 sStrArray
[i
+1].GetChar(0) == '$' )
1226 { // as of SV_NUMBERFORMATTER_VERSION_NEW_CURR
1227 eNewType
= NUMBERFORMAT_CURRENCY
;
1228 bMatchBracket
= TRUE
;
1230 else if ( i
< nAnzStrings
-1 &&
1231 nTypeArray
[i
+1] == NF_SYMBOLTYPE_STRING
&&
1232 sStrArray
[i
+1].GetChar(0) == '~' )
1233 { // as of SV_NUMBERFORMATTER_VERSION_CALENDAR
1234 eNewType
= NUMBERFORMAT_DATE
;
1235 bMatchBracket
= TRUE
;
1239 USHORT nIndexNex
= NextKeyword(i
);
1240 if (nIndexNex
== NF_KEY_H
|| // H
1241 nIndexNex
== NF_KEY_HH
|| // HH
1242 nIndexNex
== NF_KEY_M
|| // M
1243 nIndexNex
== NF_KEY_MM
|| // MM
1244 nIndexNex
== NF_KEY_S
|| // S
1245 nIndexNex
== NF_KEY_SS
) // SS
1246 eNewType
= NUMBERFORMAT_TIME
;
1248 return nPos
; // Error
1253 eNewType
= NUMBERFORMAT_TEXT
;
1256 if ( sStrArray
[i
] == pLoc
->getTime100SecSep() )
1257 bDecSep
= TRUE
; // for SS,0
1258 eNewType
= NUMBERFORMAT_UNDEFINED
;
1262 if (eScannedType
== NUMBERFORMAT_UNDEFINED
)
1263 eScannedType
= eNewType
;
1264 else if (eScannedType
== NUMBERFORMAT_TEXT
|| eNewType
== NUMBERFORMAT_TEXT
)
1265 eScannedType
= NUMBERFORMAT_TEXT
; // Text bleibt immer Text
1266 else if (eNewType
== NUMBERFORMAT_UNDEFINED
)
1267 { // bleibt wie bisher
1269 else if (eScannedType
!= eNewType
)
1271 switch (eScannedType
)
1273 case NUMBERFORMAT_DATE
:
1277 case NUMBERFORMAT_TIME
:
1278 eScannedType
= NUMBERFORMAT_DATETIME
;
1280 case NUMBERFORMAT_FRACTION
: // DD/MM
1284 if (nCurrPos
!= STRING_NOTFOUND
)
1285 eScannedType
= NUMBERFORMAT_UNDEFINED
;
1286 else if ( sStrArray
[i
] != pFormatter
->GetDateSep() )
1292 case NUMBERFORMAT_TIME
:
1296 case NUMBERFORMAT_DATE
:
1297 eScannedType
= NUMBERFORMAT_DATETIME
;
1299 case NUMBERFORMAT_FRACTION
: // MM/SS
1303 if (nCurrPos
!= STRING_NOTFOUND
)
1304 eScannedType
= NUMBERFORMAT_UNDEFINED
;
1305 else if ( sStrArray
[i
] != pLoc
->getTimeSep() )
1311 case NUMBERFORMAT_DATETIME
:
1315 case NUMBERFORMAT_TIME
:
1316 case NUMBERFORMAT_DATE
:
1318 case NUMBERFORMAT_FRACTION
: // DD/MM
1322 if (nCurrPos
!= STRING_NOTFOUND
)
1323 eScannedType
= NUMBERFORMAT_UNDEFINED
;
1324 else if ( sStrArray
[i
] != pFormatter
->GetDateSep()
1325 && sStrArray
[i
] != pLoc
->getTimeSep() )
1331 case NUMBERFORMAT_PERCENT
:
1335 case NUMBERFORMAT_NUMBER
: // nur Zahl nach Prozent
1342 case NUMBERFORMAT_SCIENTIFIC
:
1346 case NUMBERFORMAT_NUMBER
: // nur Zahl nach E
1353 case NUMBERFORMAT_NUMBER
:
1357 case NUMBERFORMAT_SCIENTIFIC
:
1358 case NUMBERFORMAT_PERCENT
:
1359 case NUMBERFORMAT_FRACTION
:
1360 case NUMBERFORMAT_CURRENCY
:
1361 eScannedType
= eNewType
;
1364 if (nCurrPos
!= STRING_NOTFOUND
)
1365 eScannedType
= NUMBERFORMAT_UNDEFINED
;
1371 case NUMBERFORMAT_FRACTION
:
1375 case NUMBERFORMAT_NUMBER
: // nur Zahl nach Bruch
1386 nPos
= nPos
+ sStrArray
[i
].Len(); // Korrekturposition
1388 if ( bMatchBracket
)
1389 { // no type detection inside of matching brackets if [$...], [~...]
1390 while ( bMatchBracket
&& i
< nAnzStrings
)
1392 if ( nTypeArray
[i
] == NF_SYMBOLTYPE_DEL
1393 && sStrArray
[i
].GetChar(0) == ']' )
1394 bMatchBracket
= FALSE
;
1396 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
1397 nPos
= nPos
+ sStrArray
[i
].Len();
1400 if ( bMatchBracket
)
1401 return nPos
; // missing closing bracket at end of code
1403 SkipStrings(i
, nPos
);
1406 if ((eScannedType
== NUMBERFORMAT_NUMBER
|| eScannedType
== NUMBERFORMAT_UNDEFINED
)
1407 && nCurrPos
!= STRING_NOTFOUND
&& !bHaveGeneral
)
1408 eScannedType
= NUMBERFORMAT_CURRENCY
; // old "automatic" currency
1409 if (eScannedType
== NUMBERFORMAT_UNDEFINED
)
1410 eScannedType
= NUMBERFORMAT_DEFINED
;
1411 return 0; // Alles ok
1415 bool ImpSvNumberformatScan::InsertSymbol( USHORT
& nPos
, svt::NfSymbolType eType
, const String
& rStr
)
1417 if (nAnzStrings
>= NF_MAX_FORMAT_SYMBOLS
|| nPos
> nAnzStrings
)
1420 if (nPos
> 0 && nTypeArray
[nPos
-1] == NF_SYMBOLTYPE_EMPTY
)
1421 --nPos
; // reuse position
1425 for (size_t i
= nAnzStrings
; i
> nPos
; --i
)
1427 nTypeArray
[i
] = nTypeArray
[i
-1];
1428 sStrArray
[i
] = sStrArray
[i
-1];
1431 nTypeArray
[nPos
] = static_cast<short>(eType
);
1432 sStrArray
[nPos
] = rStr
;
1437 int ImpSvNumberformatScan::FinalScanGetCalendar( xub_StrLen
& nPos
, USHORT
& i
,
1438 USHORT
& rAnzResStrings
)
1440 if ( sStrArray
[i
].GetChar(0) == '[' &&
1441 i
< nAnzStrings
-1 &&
1442 nTypeArray
[i
+1] == NF_SYMBOLTYPE_STRING
&&
1443 sStrArray
[i
+1].GetChar(0) == '~' )
1445 // as of SV_NUMBERFORMATTER_VERSION_CALENDAR
1446 nPos
= nPos
+ sStrArray
[i
].Len(); // [
1447 nTypeArray
[i
] = NF_SYMBOLTYPE_CALDEL
;
1448 nPos
= nPos
+ sStrArray
[++i
].Len(); // ~
1449 sStrArray
[i
-1] += sStrArray
[i
]; // [~
1450 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
1452 if ( ++i
>= nAnzStrings
)
1454 nPos
= nPos
+ sStrArray
[i
].Len(); // calendarID
1455 String
& rStr
= sStrArray
[i
];
1456 nTypeArray
[i
] = NF_SYMBOLTYPE_CALENDAR
; // convert
1458 while ( i
< nAnzStrings
&&
1459 sStrArray
[i
].GetChar(0) != ']' )
1461 nPos
= nPos
+ sStrArray
[i
].Len();
1462 rStr
+= sStrArray
[i
];
1463 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
1467 if ( rStr
.Len() && i
< nAnzStrings
&&
1468 sStrArray
[i
].GetChar(0) == ']' )
1470 nTypeArray
[i
] = NF_SYMBOLTYPE_CALDEL
;
1471 nPos
= nPos
+ sStrArray
[i
].Len();
1481 xub_StrLen
ImpSvNumberformatScan::FinalScan( String
& rString
, String
& rComment
)
1483 const LocaleDataWrapper
* pLoc
= pFormatter
->GetLocaleData();
1485 // save values for convert mode
1486 String sOldDecSep
= pFormatter
->GetNumDecimalSep();
1487 String sOldThousandSep
= pFormatter
->GetNumThousandSep();
1488 String sOldDateSep
= pFormatter
->GetDateSep();
1489 String sOldTimeSep
= pLoc
->getTimeSep();
1490 String sOldTime100SecSep
= pLoc
->getTime100SecSep();
1491 String sOldCurSymbol
= GetCurSymbol();
1492 String sOldCurString
= GetCurString();
1493 sal_Unicode cOldKeyH
= sKeyword
[NF_KEY_H
].GetChar(0);
1494 sal_Unicode cOldKeyMI
= sKeyword
[NF_KEY_MI
].GetChar(0);
1495 sal_Unicode cOldKeyS
= sKeyword
[NF_KEY_S
].GetChar(0);
1497 // If the group separator is a Non-Breaking Space (French) continue with a
1498 // normal space instead so queries on space work correctly.
1499 // The format string is adjusted to allow both.
1500 // For output of the format code string the LocaleData characters are used.
1501 if ( sOldThousandSep
.GetChar(0) == cNonBreakingSpace
&& sOldThousandSep
.Len() == 1 )
1502 sOldThousandSep
= ' ';
1504 // change locale data et al
1507 pFormatter
->ChangeIntl(eNewLnge
);
1508 //! pointer may have changed
1509 pLoc
= pFormatter
->GetLocaleData();
1510 //! init new keywords
1513 const CharClass
* pChrCls
= pFormatter
->GetCharClass();
1515 xub_StrLen nPos
= 0; // error correction position
1516 USHORT i
= 0; // symbol loop counter
1517 USHORT nCounter
= 0; // counts digits
1518 nAnzResStrings
= nAnzStrings
; // counts remaining symbols
1519 bDecSep
= FALSE
; // reset in case already used in TypeCheck
1520 bool bThaiT
= false; // Thai T NatNum modifier present
1522 switch (eScannedType
)
1524 case NUMBERFORMAT_TEXT
:
1525 case NUMBERFORMAT_DEFINED
:
1527 while (i
< nAnzStrings
)
1529 switch (nTypeArray
[i
])
1531 case NF_SYMBOLTYPE_BLANK
:
1532 case NF_SYMBOLTYPE_STAR
:
1534 case NF_SYMBOLTYPE_COMMENT
:
1536 String
& rStr
= sStrArray
[i
];
1537 nPos
= nPos
+ rStr
.Len();
1538 SvNumberformat::EraseCommentBraces( rStr
);
1540 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
1544 case NF_KEY_GENERAL
: // #77026# "General" is the same as "@"
1548 if ( nTypeArray
[i
] != NF_SYMBOLTYPE_DEL
||
1549 sStrArray
[i
].GetChar(0) != '@' )
1550 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
1554 nPos
= nPos
+ sStrArray
[i
].Len();
1559 case NUMBERFORMAT_NUMBER
:
1560 case NUMBERFORMAT_PERCENT
:
1561 case NUMBERFORMAT_CURRENCY
:
1562 case NUMBERFORMAT_SCIENTIFIC
:
1563 case NUMBERFORMAT_FRACTION
:
1565 sal_Unicode cThousandFill
= ' ';
1566 while (i
< nAnzStrings
)
1568 if (eScannedType
== NUMBERFORMAT_FRACTION
&& // special case
1569 nTypeArray
[i
] == NF_SYMBOLTYPE_DEL
&& // # ### #/#
1570 StringEqualsChar( sOldThousandSep
, ' ' ) && // e.g. France or Sweden
1571 StringEqualsChar( sStrArray
[i
], ' ' ) &&
1573 IsLastBlankBeforeFrac(i
) )
1575 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
; // del->string
1579 if (nTypeArray
[i
] == NF_SYMBOLTYPE_BLANK
||
1580 nTypeArray
[i
] == NF_SYMBOLTYPE_STAR
||
1581 nTypeArray
[i
] == NF_KEY_CCC
|| // CCC
1582 nTypeArray
[i
] == NF_KEY_GENERAL
) // Standard
1584 if (nTypeArray
[i
] == NF_KEY_GENERAL
)
1586 nThousand
= FLAG_STANDARD_IN_FORMAT
;
1588 sStrArray
[i
] = sNameStandardFormat
;
1590 nPos
= nPos
+ sStrArray
[i
].Len();
1593 else if (nTypeArray
[i
] == NF_SYMBOLTYPE_STRING
|| // Strings oder
1594 nTypeArray
[i
] > 0) // Keywords
1596 if (eScannedType
== NUMBERFORMAT_SCIENTIFIC
&&
1597 nTypeArray
[i
] == NF_KEY_E
) // E+
1599 if (bExp
) // doppelt
1604 nCntPost
= nCounter
;
1608 nTypeArray
[i
] = NF_SYMBOLTYPE_EXP
;
1610 else if (eScannedType
== NUMBERFORMAT_FRACTION
&&
1611 sStrArray
[i
].GetChar(0) == ' ')
1613 if (!bBlank
&& !bFrac
) // nicht doppelt oder hinter /
1615 if (bDecSep
&& nCounter
> 0) // Nachkommastellen
1616 return nPos
; // Fehler
1622 nTypeArray
[i
] = NF_SYMBOLTYPE_FRACBLANK
;
1624 else if (nTypeArray
[i
] == NF_KEY_THAI_T
)
1627 sStrArray
[i
] = sKeyword
[nTypeArray
[i
]];
1630 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
1631 nPos
= nPos
+ sStrArray
[i
].Len();
1634 else if (nTypeArray
[i
] == NF_SYMBOLTYPE_DEL
)
1636 sal_Unicode cHere
= sStrArray
[i
].GetChar(0);
1637 // Handle not pre-known separators in switch.
1638 sal_Unicode cSimplified
;
1639 if (StringEqualsChar( pFormatter
->GetNumThousandSep(), cHere
))
1641 else if (StringEqualsChar( pFormatter
->GetNumDecimalSep(), cHere
))
1644 cSimplified
= cHere
;
1645 switch ( cSimplified
)
1651 if (nThousand
> 0) // #... #
1652 return nPos
; // Fehler
1653 else if (bFrac
&& cHere
== '0')
1654 return nPos
; // 0 im Nenner
1655 nTypeArray
[i
] = NF_SYMBOLTYPE_DIGIT
;
1656 String
& rStr
= sStrArray
[i
];
1657 nPos
= nPos
+ rStr
.Len();
1660 while (i
< nAnzStrings
&&
1661 (sStrArray
[i
].GetChar(0) == '#' ||
1662 sStrArray
[i
].GetChar(0) == '0' ||
1663 sStrArray
[i
].GetChar(0) == '?')
1666 nTypeArray
[i
] = NF_SYMBOLTYPE_DIGIT
;
1667 nPos
= nPos
+ sStrArray
[i
].Len();
1675 if ( bDecSep
&& nDecPos
+1 == i
&&
1676 nTypeArray
[nDecPos
] == NF_SYMBOLTYPE_DECSEP
)
1678 nTypeArray
[i
] = NF_SYMBOLTYPE_DIGIT
;
1679 String
& rStr
= sStrArray
[i
];
1680 nPos
= nPos
+ rStr
.Len();
1683 while (i
< nAnzStrings
&&
1684 (sStrArray
[i
].GetChar(0) == '-') )
1686 // If more than two dashes are present in
1687 // currency formats the last dash will be
1688 // interpreted literally as a minus sign.
1689 // Has to be this ugly. Period.
1690 if ( eScannedType
== NUMBERFORMAT_CURRENCY
1691 && rStr
.Len() >= 2 &&
1692 (i
== nAnzStrings
-1 ||
1693 sStrArray
[i
+1].GetChar(0) != '-') )
1695 rStr
+= sStrArray
[i
];
1696 nPos
= nPos
+ sStrArray
[i
].Len();
1697 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
1705 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
1706 nPos
= nPos
+ sStrArray
[i
].Len();
1716 sal_Unicode cSep
= cHere
; // remember
1717 if ( StringEqualsChar( sOldThousandSep
, cSep
) )
1719 // previous char with skip empty
1720 sal_Unicode cPre
= PreviousChar(i
);
1722 if (bExp
|| bBlank
|| bFrac
)
1723 { // after E, / or ' '
1724 if ( !StringEqualsChar( sOldThousandSep
, ' ' ) )
1726 nPos
= nPos
+ sStrArray
[i
].Len();
1727 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
1732 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
1734 else if (i
> 0 && i
< nAnzStrings
-1 &&
1735 (cPre
== '#' || cPre
== '0') &&
1736 ((cNext
= NextChar(i
)) == '#' || cNext
== '0')
1739 nPos
= nPos
+ sStrArray
[i
].Len();
1740 if (!bThousand
) // only once
1743 cThousandFill
= sStrArray
[i
+1].GetChar(0);
1745 // Eat it, will be reinserted at proper
1746 // grouping positions further down.
1747 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
1751 else if (i
> 0 && (cPre
== '#' || cPre
== '0')
1752 && PreviousType(i
) == NF_SYMBOLTYPE_DIGIT
1753 && nThousand
< FLAG_STANDARD_IN_FORMAT
)
1755 if ( StringEqualsChar( sOldThousandSep
, ' ' ) )
1756 { // strange, those French..
1758 String
& rStr
= sStrArray
[i
];
1759 // set a hard Non-Breaking Space or ConvertMode
1760 const String
& rSepF
= pFormatter
->GetNumThousandSep();
1761 while ( i
< nAnzStrings
1762 && sStrArray
[i
] == sOldThousandSep
1763 && StringEqualsChar( sOldThousandSep
, NextChar(i
) ) )
1764 { // last was a space or another space
1765 // is following => separator
1766 nPos
= nPos
+ sStrArray
[i
].Len();
1771 nTypeArray
[i
] = NF_SYMBOLTYPE_THSEP
;
1776 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
1782 if ( i
< nAnzStrings
-1
1783 && sStrArray
[i
] == sOldThousandSep
)
1784 { // something following last space
1785 // => space if currency contained,
1787 nPos
= nPos
+ sStrArray
[i
].Len();
1788 if ( (nPos
<= nCurrPos
&&
1789 nCurrPos
< nPos
+ sStrArray
[i
+1].Len())
1790 || nTypeArray
[i
+1] == NF_KEY_CCC
1791 || (i
< nAnzStrings
-2 &&
1792 sStrArray
[i
+1].GetChar(0) == '[' &&
1793 sStrArray
[i
+2].GetChar(0) == '$') )
1795 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
1803 nTypeArray
[i
] = NF_SYMBOLTYPE_THSEP
;
1808 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
1821 nTypeArray
[i
] = NF_SYMBOLTYPE_THSEP
;
1822 nPos
= nPos
+ sStrArray
[i
].Len();
1823 sStrArray
[i
] = pFormatter
->GetNumThousandSep();
1825 } while (i
< nAnzStrings
&&
1826 sStrArray
[i
] == sOldThousandSep
);
1831 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
1832 String
& rStr
= sStrArray
[i
];
1833 nPos
= nPos
+ rStr
.Len();
1835 while ( i
< nAnzStrings
&&
1836 sStrArray
[i
] == sOldThousandSep
)
1838 rStr
+= sStrArray
[i
];
1839 nPos
= nPos
+ sStrArray
[i
].Len();
1840 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
1846 else if ( StringEqualsChar( sOldDecSep
, cSep
) )
1848 if (bBlank
|| bFrac
) // . behind / or ' '
1849 return nPos
; // error
1850 else if (bExp
) // behind E
1852 nPos
= nPos
+ sStrArray
[i
].Len();
1853 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
1857 else if (bDecSep
) // any .
1859 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
1860 String
& rStr
= sStrArray
[i
];
1861 nPos
= nPos
+ rStr
.Len();
1863 while ( i
< nAnzStrings
&&
1864 sStrArray
[i
] == sOldDecSep
)
1866 rStr
+= sStrArray
[i
];
1867 nPos
= nPos
+ sStrArray
[i
].Len();
1868 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
1875 nPos
= nPos
+ sStrArray
[i
].Len();
1876 nTypeArray
[i
] = NF_SYMBOLTYPE_DECSEP
;
1877 sStrArray
[i
] = pFormatter
->GetNumDecimalSep();
1885 } // of else = DecSep
1886 else // . without meaning
1889 eScannedType
== NUMBERFORMAT_FRACTION
&&
1890 StringEqualsChar( sStrArray
[i
], ' ' ) )
1892 if (!bBlank
&& !bFrac
) // no dups
1894 if (bDecSep
&& nCounter
> 0)// dec.
1895 return nPos
; // error
1901 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
1902 nPos
= nPos
+ sStrArray
[i
].Len();
1906 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
1907 String
& rStr
= sStrArray
[i
];
1908 nPos
= nPos
+ rStr
.Len();
1910 while (i
< nAnzStrings
&&
1911 StringEqualsChar( sStrArray
[i
], cSep
) )
1913 rStr
+= sStrArray
[i
];
1914 nPos
= nPos
+ sStrArray
[i
].Len();
1915 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
1925 if (eScannedType
== NUMBERFORMAT_FRACTION
)
1928 (nTypeArray
[i
-1] != NF_SYMBOLTYPE_DIGIT
&&
1929 nTypeArray
[i
-1] != NF_SYMBOLTYPE_EMPTY
) )
1930 return nPos
? nPos
: 1; // /? not allowed
1931 else if (!bFrac
|| (bDecSep
&& nCounter
> 0))
1934 nCntPost
= nCounter
;
1936 nTypeArray
[i
] = NF_SYMBOLTYPE_FRAC
;
1937 nPos
= nPos
+ sStrArray
[i
].Len();
1940 else // / doppelt od. , imZaehl
1941 return nPos
; // Fehler
1945 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
1946 nPos
= nPos
+ sStrArray
[i
].Len();
1953 if ( eScannedType
== NUMBERFORMAT_CURRENCY
&&
1954 i
< nAnzStrings
-1 &&
1955 nTypeArray
[i
+1] == NF_SYMBOLTYPE_STRING
&&
1956 sStrArray
[i
+1].GetChar(0) == '$' )
1958 // ab SV_NUMBERFORMATTER_VERSION_NEW_CURR
1959 nPos
= nPos
+ sStrArray
[i
].Len(); // [
1960 nTypeArray
[i
] = NF_SYMBOLTYPE_CURRDEL
;
1961 nPos
= nPos
+ sStrArray
[++i
].Len(); // $
1962 sStrArray
[i
-1] += sStrArray
[i
]; // [$
1963 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
1965 if ( ++i
>= nAnzStrings
)
1966 return nPos
; // Fehler
1967 nPos
= nPos
+ sStrArray
[i
].Len(); // DM
1968 String
& rStr
= sStrArray
[i
];
1969 String
* pStr
= &sStrArray
[i
];
1970 nTypeArray
[i
] = NF_SYMBOLTYPE_CURRENCY
; // wandeln
1971 BOOL bHadDash
= FALSE
;
1973 while ( i
< nAnzStrings
&&
1974 sStrArray
[i
].GetChar(0) != ']' )
1976 nPos
= nPos
+ sStrArray
[i
].Len();
1979 *pStr
+= sStrArray
[i
];
1980 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
1985 if ( sStrArray
[i
].GetChar(0) == '-' )
1988 pStr
= &sStrArray
[i
];
1989 nTypeArray
[i
] = NF_SYMBOLTYPE_CURREXT
;
1993 *pStr
+= sStrArray
[i
];
1994 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
2000 if ( rStr
.Len() && i
< nAnzStrings
&&
2001 sStrArray
[i
].GetChar(0) == ']' )
2003 nTypeArray
[i
] = NF_SYMBOLTYPE_CURRDEL
;
2004 nPos
= nPos
+ sStrArray
[i
].Len();
2008 return nPos
; // Fehler
2012 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
2013 nPos
= nPos
+ sStrArray
[i
].Len();
2018 default: // andere Dels
2020 if (eScannedType
== NUMBERFORMAT_PERCENT
&&
2022 nTypeArray
[i
] = NF_SYMBOLTYPE_PERCENT
;
2024 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
2025 nPos
= nPos
+ sStrArray
[i
].Len();
2029 } // of switch (Del)
2031 else if ( nTypeArray
[i
] == NF_SYMBOLTYPE_COMMENT
)
2033 String
& rStr
= sStrArray
[i
];
2034 nPos
= nPos
+ rStr
.Len();
2035 SvNumberformat::EraseCommentBraces( rStr
);
2037 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
2043 DBG_ERRORFILE( "unknown NF_SYMBOLTYPE_..." );
2044 nPos
= nPos
+ sStrArray
[i
].Len();
2048 if (eScannedType
== NUMBERFORMAT_FRACTION
)
2053 nCntPost
= nCounter
;
2062 nCntPost
= nCounter
;
2066 if (bThousand
) // Expansion of grouping separators
2072 nMaxPos
= nBlankPos
;
2074 nMaxPos
= 0; // no grouping
2076 else if (bDecSep
) // decimal separator present
2078 else if (bExp
) // 'E' exponent present
2082 // Insert separators at proper positions.
2083 xub_StrLen nCount
= 0;
2084 utl::DigitGroupingIterator
aGrouping( pLoc
->getDigitGrouping());
2085 size_t nFirstDigitSymbol
= nMaxPos
;
2086 size_t nFirstGroupingSymbol
= nMaxPos
;
2090 if (nTypeArray
[i
] == NF_SYMBOLTYPE_DIGIT
)
2092 nFirstDigitSymbol
= i
;
2093 nCount
= nCount
+ sStrArray
[i
].Len(); // MSC converts += to int and then warns, so ...
2094 // Insert separator only if not leftmost symbol.
2095 if (i
> 0 && nCount
>= aGrouping
.getPos())
2097 DBG_ASSERT( sStrArray
[i
].Len() == 1,
2098 "ImpSvNumberformatScan::FinalScan: combined digits in group separator insertion");
2099 if (!InsertSymbol( i
, NF_SYMBOLTYPE_THSEP
,
2100 pFormatter
->GetNumThousandSep()))
2101 // nPos isn't correct here, but signals error
2103 // i may have been decremented by 1
2104 nFirstDigitSymbol
= i
+ 1;
2105 nFirstGroupingSymbol
= i
;
2106 aGrouping
.advance();
2110 // Generated something like "string",000; remove separator again.
2111 if (nFirstGroupingSymbol
< nFirstDigitSymbol
)
2113 nTypeArray
[nFirstGroupingSymbol
] = NF_SYMBOLTYPE_EMPTY
;
2117 // Combine digits into groups to save memory (Info will be copied
2118 // later, taking only non-empty symbols).
2119 for (i
= 0; i
< nAnzStrings
; ++i
)
2121 if (nTypeArray
[i
] == NF_SYMBOLTYPE_DIGIT
)
2123 String
& rStr
= sStrArray
[i
];
2124 while (++i
< nAnzStrings
&&
2125 nTypeArray
[i
] == NF_SYMBOLTYPE_DIGIT
)
2127 rStr
+= sStrArray
[i
];
2128 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
2134 break; // of NUMBERFORMAT_NUMBER
2135 case NUMBERFORMAT_DATE
:
2137 while (i
< nAnzStrings
)
2139 switch (nTypeArray
[i
])
2141 case NF_SYMBOLTYPE_BLANK
:
2142 case NF_SYMBOLTYPE_STAR
:
2143 case NF_SYMBOLTYPE_STRING
:
2144 nPos
= nPos
+ sStrArray
[i
].Len();
2147 case NF_SYMBOLTYPE_COMMENT
:
2149 String
& rStr
= sStrArray
[i
];
2150 nPos
= nPos
+ rStr
.Len();
2151 SvNumberformat::EraseCommentBraces( rStr
);
2153 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
2158 case NF_SYMBOLTYPE_DEL
:
2161 if (sStrArray
[i
] == sOldDateSep
)
2163 nTypeArray
[i
] = NF_SYMBOLTYPE_DATESEP
;
2164 nPos
= nPos
+ sStrArray
[i
].Len();
2166 sStrArray
[i
] = pFormatter
->GetDateSep();
2169 else if ( (nCalRet
= FinalScanGetCalendar( nPos
, i
, nAnzResStrings
)) != 0 )
2172 return nPos
; // error
2176 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
2177 nPos
= nPos
+ sStrArray
[i
].Len();
2182 case NF_KEY_THAI_T
:
2186 case NF_KEY_MM
: // MM
2187 case NF_KEY_MMM
: // MMM
2188 case NF_KEY_MMMM
: // MMMM
2189 case NF_KEY_MMMMM
: // MMMMM
2191 case NF_KEY_QQ
: // QQ
2193 case NF_KEY_DD
: // DD
2194 case NF_KEY_DDD
: // DDD
2195 case NF_KEY_DDDD
: // DDDD
2196 case NF_KEY_YY
: // YY
2197 case NF_KEY_YYYY
: // YYYY
2198 case NF_KEY_NN
: // NN
2199 case NF_KEY_NNN
: // NNN
2200 case NF_KEY_NNNN
: // NNNN
2201 case NF_KEY_WW
: // WW
2202 case NF_KEY_AAA
: // AAA
2203 case NF_KEY_AAAA
: // AAAA
2204 case NF_KEY_EC
: // E
2205 case NF_KEY_EEC
: // EE
2206 case NF_KEY_G
: // G
2207 case NF_KEY_GG
: // GG
2208 case NF_KEY_GGG
: // GGG
2209 case NF_KEY_R
: // R
2210 case NF_KEY_RR
: // RR
2211 sStrArray
[i
] = sKeyword
[nTypeArray
[i
]]; // tTtT -> TTTT
2212 nPos
= nPos
+ sStrArray
[i
].Len();
2215 default: // andere Keywords
2216 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
2217 nPos
= nPos
+ sStrArray
[i
].Len();
2223 break; // of NUMBERFORMAT_DATE
2224 case NUMBERFORMAT_TIME
:
2226 while (i
< nAnzStrings
)
2228 switch (nTypeArray
[i
])
2230 case NF_SYMBOLTYPE_BLANK
:
2231 case NF_SYMBOLTYPE_STAR
:
2233 nPos
= nPos
+ sStrArray
[i
].Len();
2237 case NF_SYMBOLTYPE_DEL
:
2239 switch( sStrArray
[i
].GetChar(0) )
2243 if ( Is100SecZero( i
, bDecSep
) )
2246 nTypeArray
[i
] = NF_SYMBOLTYPE_DIGIT
;
2247 String
& rStr
= sStrArray
[i
];
2249 nPos
= nPos
+ sStrArray
[i
].Len();
2251 while (i
< nAnzStrings
&&
2252 sStrArray
[i
].GetChar(0) == '0')
2254 rStr
+= sStrArray
[i
];
2255 nPos
= nPos
+ sStrArray
[i
].Len();
2256 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
2271 if (bThousand
) // doppelt
2273 bThousand
= TRUE
; // bei Time frei
2274 sal_Unicode cChar
= pChrCls
->upper( NextChar(i
) ).GetChar(0);
2275 if ( cChar
== cOldKeyH
)
2277 else if ( cChar
== cOldKeyMI
)
2279 else if ( cChar
== cOldKeyS
)
2283 nPos
= nPos
+ sStrArray
[i
].Len();
2289 if (!bThousand
) // kein [ vorher
2291 nPos
= nPos
+ sStrArray
[i
].Len();
2297 nPos
= nPos
+ sStrArray
[i
].Len();
2298 if ( sStrArray
[i
] == sOldTimeSep
)
2300 nTypeArray
[i
] = NF_SYMBOLTYPE_TIMESEP
;
2302 sStrArray
[i
] = pLoc
->getTimeSep();
2304 else if ( sStrArray
[i
] == sOldTime100SecSep
)
2307 nTypeArray
[i
] = NF_SYMBOLTYPE_TIME100SECSEP
;
2309 sStrArray
[i
] = pLoc
->getTime100SecSep();
2312 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
2319 case NF_SYMBOLTYPE_STRING
:
2321 nPos
= nPos
+ sStrArray
[i
].Len();
2325 case NF_SYMBOLTYPE_COMMENT
:
2327 String
& rStr
= sStrArray
[i
];
2328 nPos
= nPos
+ rStr
.Len();
2329 SvNumberformat::EraseCommentBraces( rStr
);
2331 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
2336 case NF_KEY_AMPM
: // AM/PM
2337 case NF_KEY_AP
: // A/P
2339 bExp
= TRUE
; // missbraucht fuer A/P
2340 sStrArray
[i
] = sKeyword
[nTypeArray
[i
]]; // tTtT -> TTTT
2341 nPos
= nPos
+ sStrArray
[i
].Len();
2345 case NF_KEY_THAI_T
:
2348 case NF_KEY_MI
: // M
2349 case NF_KEY_MMI
: // MM
2351 case NF_KEY_HH
: // HH
2353 case NF_KEY_SS
: // SS
2355 sStrArray
[i
] = sKeyword
[nTypeArray
[i
]]; // tTtT -> TTTT
2356 nPos
= nPos
+ sStrArray
[i
].Len();
2360 default: // andere Keywords
2362 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
2363 nPos
= nPos
+ sStrArray
[i
].Len();
2369 nCntPost
= nCounter
; // Zaehler der Nullen
2371 nCntExp
= 1; // merkt AM/PM
2373 break; // of NUMBERFORMAT_TIME
2374 case NUMBERFORMAT_DATETIME
:
2376 BOOL bTimePart
= FALSE
;
2377 while (i
< nAnzStrings
)
2379 switch (nTypeArray
[i
])
2381 case NF_SYMBOLTYPE_BLANK
:
2382 case NF_SYMBOLTYPE_STAR
:
2383 case NF_SYMBOLTYPE_STRING
:
2384 nPos
= nPos
+ sStrArray
[i
].Len();
2387 case NF_SYMBOLTYPE_COMMENT
:
2389 String
& rStr
= sStrArray
[i
];
2390 nPos
= nPos
+ rStr
.Len();
2391 SvNumberformat::EraseCommentBraces( rStr
);
2393 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
2398 case NF_SYMBOLTYPE_DEL
:
2401 if ( (nCalRet
= FinalScanGetCalendar( nPos
, i
, nAnzResStrings
)) != 0 )
2404 return nPos
; // error
2408 switch( sStrArray
[i
].GetChar(0) )
2412 if ( bTimePart
&& Is100SecZero( i
, bDecSep
) )
2415 nTypeArray
[i
] = NF_SYMBOLTYPE_DIGIT
;
2416 String
& rStr
= sStrArray
[i
];
2418 nPos
= nPos
+ sStrArray
[i
].Len();
2420 while (i
< nAnzStrings
&&
2421 sStrArray
[i
].GetChar(0) == '0')
2423 rStr
+= sStrArray
[i
];
2424 nPos
= nPos
+ sStrArray
[i
].Len();
2425 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
2440 nPos
= nPos
+ sStrArray
[i
].Len();
2443 if ( sStrArray
[i
] == sOldTimeSep
)
2445 nTypeArray
[i
] = NF_SYMBOLTYPE_TIMESEP
;
2447 sStrArray
[i
] = pLoc
->getTimeSep();
2449 else if ( sStrArray
[i
] == sOldTime100SecSep
)
2452 nTypeArray
[i
] = NF_SYMBOLTYPE_TIME100SECSEP
;
2454 sStrArray
[i
] = pLoc
->getTime100SecSep();
2457 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
2461 if ( sStrArray
[i
] == sOldDateSep
)
2463 nTypeArray
[i
] = NF_SYMBOLTYPE_DATESEP
;
2465 sStrArray
[i
] = pFormatter
->GetDateSep();
2468 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
2476 case NF_KEY_AMPM
: // AM/PM
2477 case NF_KEY_AP
: // A/P
2480 bExp
= TRUE
; // missbraucht fuer A/P
2481 sStrArray
[i
] = sKeyword
[nTypeArray
[i
]]; // tTtT -> TTTT
2482 nPos
= nPos
+ sStrArray
[i
].Len();
2486 case NF_KEY_MI
: // M
2487 case NF_KEY_MMI
: // MM
2489 case NF_KEY_HH
: // HH
2491 case NF_KEY_SS
: // SS
2493 sStrArray
[i
] = sKeyword
[nTypeArray
[i
]]; // tTtT -> TTTT
2494 nPos
= nPos
+ sStrArray
[i
].Len();
2498 case NF_KEY_MM
: // MM
2499 case NF_KEY_MMM
: // MMM
2500 case NF_KEY_MMMM
: // MMMM
2501 case NF_KEY_MMMMM
: // MMMMM
2503 case NF_KEY_QQ
: // QQ
2505 case NF_KEY_DD
: // DD
2506 case NF_KEY_DDD
: // DDD
2507 case NF_KEY_DDDD
: // DDDD
2508 case NF_KEY_YY
: // YY
2509 case NF_KEY_YYYY
: // YYYY
2510 case NF_KEY_NN
: // NN
2511 case NF_KEY_NNN
: // NNN
2512 case NF_KEY_NNNN
: // NNNN
2513 case NF_KEY_WW
: // WW
2514 case NF_KEY_AAA
: // AAA
2515 case NF_KEY_AAAA
: // AAAA
2516 case NF_KEY_EC
: // E
2517 case NF_KEY_EEC
: // EE
2518 case NF_KEY_G
: // G
2519 case NF_KEY_GG
: // GG
2520 case NF_KEY_GGG
: // GGG
2521 case NF_KEY_R
: // R
2522 case NF_KEY_RR
: // RR
2524 sStrArray
[i
] = sKeyword
[nTypeArray
[i
]]; // tTtT -> TTTT
2525 nPos
= nPos
+ sStrArray
[i
].Len();
2528 case NF_KEY_THAI_T
:
2530 sStrArray
[i
] = sKeyword
[nTypeArray
[i
]];
2531 nPos
= nPos
+ sStrArray
[i
].Len();
2534 default: // andere Keywords
2535 nTypeArray
[i
] = NF_SYMBOLTYPE_STRING
;
2536 nPos
= nPos
+ sStrArray
[i
].Len();
2541 nCntPost
= nCounter
; // decimals (100th seconds)
2543 nCntExp
= 1; // merkt AM/PM
2545 break; // of NUMBERFORMAT_DATETIME
2549 if (eScannedType
== NUMBERFORMAT_SCIENTIFIC
&&
2550 (nCntPre
+ nCntPost
== 0 || nCntExp
== 0))
2552 else if (eScannedType
== NUMBERFORMAT_FRACTION
&& (nCntExp
> 8 || nCntExp
== 0))
2555 if (bThaiT
&& !GetNatNumModifier())
2556 SetNatNumModifier(1);
2559 { // strings containing keywords of the target locale must be quoted, so
2560 // the user sees the difference and is able to edit the format string
2561 for ( i
=0; i
< nAnzStrings
; i
++ )
2563 if ( nTypeArray
[i
] == NF_SYMBOLTYPE_STRING
&&
2564 sStrArray
[i
].GetChar(0) != '\"' )
2566 if ( bConvertSystemToSystem
&& eScannedType
== NUMBERFORMAT_CURRENCY
)
2567 { // don't stringize automatic currency, will be converted
2568 if ( sStrArray
[i
] == sOldCurSymbol
)
2570 // DM might be splitted into D and M
2571 if ( sStrArray
[i
].Len() < sOldCurSymbol
.Len() &&
2572 pChrCls
->toUpper( sStrArray
[i
], 0, 1 ).GetChar(0) ==
2573 sOldCurString
.GetChar(0) )
2575 String
aTmp( sStrArray
[i
] );
2577 while ( aTmp
.Len() < sOldCurSymbol
.Len() &&
2579 nTypeArray
[j
] == NF_SYMBOLTYPE_STRING
)
2581 aTmp
+= sStrArray
[j
++];
2583 if ( pChrCls
->upper( aTmp
) == sOldCurString
)
2585 sStrArray
[i
++] = aTmp
;
2588 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
2596 String
& rStr
= sStrArray
[i
];
2597 xub_StrLen nLen
= rStr
.Len();
2598 for ( xub_StrLen j
=0; j
<nLen
; j
++ )
2600 if ( (j
== 0 || rStr
.GetChar(j
-1) != '\\') && GetKeyWord( rStr
, j
) )
2602 rStr
.Insert( '\"', 0 );
2610 // concatenate strings, remove quotes for output, and rebuild the format string
2613 while (i
< nAnzStrings
)
2615 switch ( nTypeArray
[i
] )
2617 case NF_SYMBOLTYPE_STRING
:
2619 xub_StrLen nStringPos
= rString
.Len();
2620 xub_StrLen nArrPos
= 0;
2624 if (sStrArray
[i
].Len() == 2 &&
2625 sStrArray
[i
].GetChar(0) == '\\')
2627 // Unescape some simple forms of symbols even in the UI
2628 // visible string to prevent duplicates that differ
2629 // only in notation, originating from import.
2630 // e.g. YYYY-MM-DD and YYYY\-MM\-DD are identical,
2631 // but 0\ 000 0 and 0 000 0 in a French locale are not.
2632 sal_Unicode c
= sStrArray
[i
].GetChar(1);
2642 if (((eScannedType
& NUMBERFORMAT_DATE
) == 0)
2643 && (StringEqualsChar(
2644 pFormatter
->GetNumThousandSep(),
2645 c
) || StringEqualsChar(
2646 pFormatter
->GetNumDecimalSep(),
2649 pFormatter
->GetNumThousandSep(),
2650 cNonBreakingSpace
))))
2651 rString
+= sStrArray
[i
];
2652 else if ((eScannedType
& NUMBERFORMAT_DATE
) &&
2654 pFormatter
->GetDateSep(), c
))
2655 rString
+= sStrArray
[i
];
2656 else if ((eScannedType
& NUMBERFORMAT_TIME
) &&
2657 (StringEqualsChar( pLoc
->getTimeSep(),
2660 pLoc
->getTime100SecSep(), c
)))
2661 rString
+= sStrArray
[i
];
2662 else if (eScannedType
& NUMBERFORMAT_FRACTION
)
2663 rString
+= sStrArray
[i
];
2668 rString
+= sStrArray
[i
];
2672 rString
+= sStrArray
[i
];
2673 if ( RemoveQuotes( sStrArray
[i
] ) > 0 )
2674 { // update currency up to quoted string
2675 if ( eScannedType
== NUMBERFORMAT_CURRENCY
)
2676 { // dM -> DM or DM -> $ in old automatic
2677 // currency formats, oh my ..., why did we ever
2679 String
aTmp( pChrCls
->toUpper(
2680 sStrArray
[iPos
], nArrPos
,
2681 sStrArray
[iPos
].Len()-nArrPos
) );
2682 xub_StrLen nCPos
= aTmp
.Search( sOldCurString
);
2683 if ( nCPos
!= STRING_NOTFOUND
)
2685 const String
& rCur
=
2686 bConvertMode
&& bConvertSystemToSystem
?
2687 GetCurSymbol() : sOldCurSymbol
;
2688 sStrArray
[iPos
].Replace( nArrPos
+nCPos
,
2689 sOldCurString
.Len(), rCur
);
2690 rString
.Replace( nStringPos
+nCPos
,
2691 sOldCurString
.Len(), rCur
);
2693 nStringPos
= rString
.Len();
2695 nArrPos
= sStrArray
[iPos
].Len();
2697 nArrPos
= sStrArray
[iPos
].Len() + sStrArray
[i
].Len();
2702 sStrArray
[iPos
] += sStrArray
[i
];
2703 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
2707 } while ( i
< nAnzStrings
&& nTypeArray
[i
] == NF_SYMBOLTYPE_STRING
);
2708 if ( i
< nAnzStrings
)
2709 i
--; // enter switch on next symbol again
2710 if ( eScannedType
== NUMBERFORMAT_CURRENCY
&& nStringPos
< rString
.Len() )
2711 { // same as above, since last RemoveQuotes
2712 String
aTmp( pChrCls
->toUpper(
2713 sStrArray
[iPos
], nArrPos
,
2714 sStrArray
[iPos
].Len()-nArrPos
) );
2715 xub_StrLen nCPos
= aTmp
.Search( sOldCurString
);
2716 if ( nCPos
!= STRING_NOTFOUND
)
2718 const String
& rCur
=
2719 bConvertMode
&& bConvertSystemToSystem
?
2720 GetCurSymbol() : sOldCurSymbol
;
2721 sStrArray
[iPos
].Replace( nArrPos
+nCPos
,
2722 sOldCurString
.Len(), rCur
);
2723 rString
.Replace( nStringPos
+nCPos
,
2724 sOldCurString
.Len(), rCur
);
2729 case NF_SYMBOLTYPE_CURRENCY
:
2731 rString
+= sStrArray
[i
];
2732 RemoveQuotes( sStrArray
[i
] );
2736 if (bThaiT
&& GetNatNumModifier() == 1)
2737 { // Remove T from format code, will be replaced with a [NatNum1] prefix.
2738 nTypeArray
[i
] = NF_SYMBOLTYPE_EMPTY
;
2742 rString
+= sStrArray
[i
];
2744 case NF_SYMBOLTYPE_EMPTY
:
2748 rString
+= sStrArray
[i
];
2756 xub_StrLen
ImpSvNumberformatScan::RemoveQuotes( String
& rStr
)
2758 if ( rStr
.Len() > 1 )
2760 sal_Unicode c
= rStr
.GetChar(0);
2762 if ( c
== '"' && rStr
.GetChar( (n
= xub_StrLen(rStr
.Len()-1)) ) == '"' )
2768 else if ( c
== '\\' )
2778 xub_StrLen
ImpSvNumberformatScan::ScanFormat( String
& rString
, String
& rComment
)
2780 xub_StrLen res
= Symbol_Division(rString
); //lexikalische Analyse
2782 res
= ScanType(rString
); // Erkennung des Formattyps
2784 res
= FinalScan( rString
, rComment
); // Typabhaengige Endanalyse
2785 return res
; // res = Kontrollposition
2786 // res = 0 => Format ok
2789 void ImpSvNumberformatScan::CopyInfo(ImpSvNumberformatInfo
* pInfo
, USHORT nAnz
)
2794 while (i
< nAnz
&& j
< NF_MAX_FORMAT_SYMBOLS
)
2796 if (nTypeArray
[j
] != NF_SYMBOLTYPE_EMPTY
)
2798 pInfo
->sStrArray
[i
] = sStrArray
[j
];
2799 pInfo
->nTypeArray
[i
] = nTypeArray
[j
];
2804 pInfo
->eScannedType
= eScannedType
;
2805 pInfo
->bThousand
= bThousand
;
2806 pInfo
->nThousand
= nThousand
;
2807 pInfo
->nCntPre
= nCntPre
;
2808 pInfo
->nCntPost
= nCntPost
;
2809 pInfo
->nCntExp
= nCntExp
;