PageRenderTime 63ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/binfilter/bf_svtools/source/numbers/svt_zforscan.cxx

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