PageRenderTime 56ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/libreoffice-3.6.0.2/svl/source/numbers/zforscan.cxx

#
C++ | 2747 lines | 2525 code | 69 blank | 153 comment | 630 complexity | 55af38704f2ae0ab1cbc4f5fc13bc5fc MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, AGPL-1.0, BSD-3-Clause-No-Nuclear-License-2014, GPL-3.0, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /*************************************************************************
  3. *
  4. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5. *
  6. * Copyright 2000, 2010 Oracle and/or its affiliates.
  7. *
  8. * OpenOffice.org - a multi-platform office productivity suite
  9. *
  10. * This file is part of OpenOffice.org.
  11. *
  12. * OpenOffice.org is free software: you can redistribute it and/or modify
  13. * it under the terms of the GNU Lesser General Public License version 3
  14. * only, as published by the Free Software Foundation.
  15. *
  16. * OpenOffice.org is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU Lesser General Public License version 3 for more details
  20. * (a copy is included in the LICENSE file that accompanied this code).
  21. *
  22. * You should have received a copy of the GNU Lesser General Public License
  23. * version 3 along with OpenOffice.org. If not, see
  24. * <http://www.openoffice.org/license.html>
  25. * for a copy of the LGPLv3 License.
  26. *
  27. ************************************************************************/
  28. #include <stdlib.h>
  29. #include <tools/debug.hxx>
  30. #include <i18npool/mslangid.hxx>
  31. #include <unotools/charclass.hxx>
  32. #include <unotools/localedatawrapper.hxx>
  33. #include <unotools/numberformatcodewrapper.hxx>
  34. #include <rtl/instance.hxx>
  35. #include <svl/zforlist.hxx>
  36. #include <svl/zformat.hxx>
  37. #include <unotools/digitgroupingiterator.hxx>
  38. #define _ZFORSCAN_CXX
  39. #include "zforscan.hxx"
  40. #undef _ZFORSCAN_CXX
  41. #include <svl/nfsymbol.hxx>
  42. using namespace svt;
  43. const sal_Unicode cNonBreakingSpace = 0xA0;
  44. namespace
  45. {
  46. struct ImplEnglishColors
  47. {
  48. const String* operator()()
  49. {
  50. static const String aEnglishColors[NF_MAX_DEFAULT_COLORS] =
  51. {
  52. String( RTL_CONSTASCII_USTRINGPARAM( "BLACK" ) ),
  53. String( RTL_CONSTASCII_USTRINGPARAM( "BLUE" ) ),
  54. String( RTL_CONSTASCII_USTRINGPARAM( "GREEN" ) ),
  55. String( RTL_CONSTASCII_USTRINGPARAM( "CYAN" ) ),
  56. String( RTL_CONSTASCII_USTRINGPARAM( "RED" ) ),
  57. String( RTL_CONSTASCII_USTRINGPARAM( "MAGENTA" ) ),
  58. String( RTL_CONSTASCII_USTRINGPARAM( "BROWN" ) ),
  59. String( RTL_CONSTASCII_USTRINGPARAM( "GREY" ) ),
  60. String( RTL_CONSTASCII_USTRINGPARAM( "YELLOW" ) ),
  61. String( RTL_CONSTASCII_USTRINGPARAM( "WHITE" ) )
  62. };
  63. return &aEnglishColors[0];
  64. }
  65. };
  66. struct theEnglishColors
  67. : public rtl::StaticAggregate< const String, ImplEnglishColors> {};
  68. }
  69. ImpSvNumberformatScan::ImpSvNumberformatScan( SvNumberFormatter* pFormatterP )
  70. {
  71. pFormatter = pFormatterP;
  72. bConvertMode = false;
  73. //! All keywords MUST be UPPERCASE!
  74. sKeyword[NF_KEY_E].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "E" ) ); // Exponent
  75. sKeyword[NF_KEY_AMPM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "AM/PM" ) ); // AM/PM
  76. sKeyword[NF_KEY_AP].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "A/P" ) ); // AM/PM short
  77. sKeyword[NF_KEY_MI].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "M" ) ); // Minute
  78. sKeyword[NF_KEY_MMI].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MM" ) ); // Minute 02
  79. sKeyword[NF_KEY_S].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "S" ) ); // Second
  80. sKeyword[NF_KEY_SS].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "SS" ) ); // Second 02
  81. sKeyword[NF_KEY_Q].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Q" ) ); // Quarter short 'Q'
  82. sKeyword[NF_KEY_QQ].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "QQ" ) ); // Quarter long
  83. sKeyword[NF_KEY_NN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NN" ) ); // Day of week short
  84. sKeyword[NF_KEY_NNN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NNN" ) ); // Day of week long
  85. sKeyword[NF_KEY_NNNN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NNNN" ) ); // Day of week long incl. separator
  86. sKeyword[NF_KEY_WW].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "WW" ) ); // Week of year
  87. sKeyword[NF_KEY_CCC].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "CCC" ) ); // Currency abbreviation
  88. bKeywordsNeedInit = true; // locale dependent keywords
  89. bCompatCurNeedInit = true; // locale dependent compatibility currency strings
  90. StandardColor[0] = Color(COL_BLACK);
  91. StandardColor[1] = Color(COL_LIGHTBLUE);
  92. StandardColor[2] = Color(COL_LIGHTGREEN);
  93. StandardColor[3] = Color(COL_LIGHTCYAN);
  94. StandardColor[4] = Color(COL_LIGHTRED);
  95. StandardColor[5] = Color(COL_LIGHTMAGENTA);
  96. StandardColor[6] = Color(COL_BROWN);
  97. StandardColor[7] = Color(COL_GRAY);
  98. StandardColor[8] = Color(COL_YELLOW);
  99. StandardColor[9] = Color(COL_WHITE);
  100. pNullDate = new Date(30,12,1899);
  101. nStandardPrec = 2;
  102. sErrStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "###" ) );
  103. Reset();
  104. }
  105. ImpSvNumberformatScan::~ImpSvNumberformatScan()
  106. {
  107. delete pNullDate;
  108. Reset();
  109. }
  110. void ImpSvNumberformatScan::ChangeIntl()
  111. {
  112. bKeywordsNeedInit = true;
  113. bCompatCurNeedInit = true;
  114. // may be initialized by InitSpecialKeyword()
  115. sKeyword[NF_KEY_TRUE].Erase();
  116. sKeyword[NF_KEY_FALSE].Erase();
  117. }
  118. void ImpSvNumberformatScan::InitSpecialKeyword( NfKeywordIndex eIdx ) const
  119. {
  120. switch ( eIdx )
  121. {
  122. case NF_KEY_TRUE :
  123. ((ImpSvNumberformatScan*)this)->sKeyword[NF_KEY_TRUE] =
  124. pFormatter->GetCharClass()->uppercase(
  125. pFormatter->GetLocaleData()->getTrueWord() );
  126. if ( !sKeyword[NF_KEY_TRUE].Len() )
  127. {
  128. SAL_WARN( "svl.numbers", "InitSpecialKeyword: TRUE_WORD?" );
  129. ((ImpSvNumberformatScan*)this)->sKeyword[NF_KEY_TRUE].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "TRUE" ) );
  130. }
  131. break;
  132. case NF_KEY_FALSE :
  133. ((ImpSvNumberformatScan*)this)->sKeyword[NF_KEY_FALSE] =
  134. pFormatter->GetCharClass()->uppercase(
  135. pFormatter->GetLocaleData()->getFalseWord() );
  136. if ( !sKeyword[NF_KEY_FALSE].Len() )
  137. {
  138. SAL_WARN( "svl.numbers", "InitSpecialKeyword: FALSE_WORD?" );
  139. ((ImpSvNumberformatScan*)this)->sKeyword[NF_KEY_FALSE].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "FALSE" ) );
  140. }
  141. break;
  142. default:
  143. SAL_WARN( "svl.numbers", "InitSpecialKeyword: unknown request" );
  144. }
  145. }
  146. void ImpSvNumberformatScan::InitCompatCur() const
  147. {
  148. ImpSvNumberformatScan* pThis = (ImpSvNumberformatScan*)this;
  149. // currency symbol for old style ("automatic") compatibility format codes
  150. pFormatter->GetCompatibilityCurrency( pThis->sCurSymbol, pThis->sCurAbbrev );
  151. // currency symbol upper case
  152. pThis->sCurString = pFormatter->GetCharClass()->uppercase( sCurSymbol );
  153. bCompatCurNeedInit = false;
  154. }
  155. void ImpSvNumberformatScan::InitKeywords() const
  156. {
  157. if ( !bKeywordsNeedInit )
  158. return ;
  159. ((ImpSvNumberformatScan*)this)->SetDependentKeywords();
  160. bKeywordsNeedInit = false;
  161. }
  162. /** Extract the name of General, Standard, Whatever, ignoring leading modifiers
  163. such as [NatNum1]. */
  164. static String lcl_extractStandardGeneralName( const ::rtl::OUString & rCode )
  165. {
  166. String aStr;
  167. const sal_Unicode* p = rCode.getStr();
  168. const sal_Unicode* const pStop = p + rCode.getLength();
  169. const sal_Unicode* pBeg = p; // name begins here
  170. bool bMod = false;
  171. bool bDone = false;
  172. while (p < pStop && !bDone)
  173. {
  174. switch (*p)
  175. {
  176. case '[':
  177. bMod = true;
  178. break;
  179. case ']':
  180. if (bMod)
  181. {
  182. bMod = false;
  183. pBeg = p+1;
  184. }
  185. // else: would be a locale data error, easily to be spotted in
  186. // UI dialog
  187. break;
  188. case ';':
  189. if (!bMod)
  190. {
  191. bDone = true;
  192. --p; // put back, increment by one follows
  193. }
  194. break;
  195. }
  196. ++p;
  197. if (bMod)
  198. pBeg = p;
  199. }
  200. if (pBeg < p)
  201. aStr = rCode.copy( pBeg - rCode.getStr(), p - pBeg);
  202. return aStr;
  203. }
  204. void ImpSvNumberformatScan::SetDependentKeywords()
  205. {
  206. using namespace ::com::sun::star;
  207. using namespace ::com::sun::star::uno;
  208. const CharClass* pCharClass = pFormatter->GetCharClass();
  209. const LocaleDataWrapper* pLocaleData = pFormatter->GetLocaleData();
  210. // #80023# be sure to generate keywords for the loaded Locale, not for the
  211. // requested Locale, otherwise number format codes might not match
  212. lang::Locale aLoadedLocale = pLocaleData->getLoadedLocale();
  213. LanguageType eLang = MsLangId::convertLocaleToLanguage( aLoadedLocale );
  214. NumberFormatCodeWrapper aNumberFormatCode( pFormatter->GetServiceManager(), aLoadedLocale );
  215. i18n::NumberFormatCode aFormat = aNumberFormatCode.getFormatCode( NF_NUMBER_STANDARD );
  216. sNameStandardFormat = lcl_extractStandardGeneralName( aFormat.Code);
  217. sKeyword[NF_KEY_GENERAL] = pCharClass->uppercase( sNameStandardFormat );
  218. // preset new calendar keywords
  219. sKeyword[NF_KEY_AAA].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "AAA" ) );
  220. sKeyword[NF_KEY_AAAA].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "AAAA" ) );
  221. sKeyword[NF_KEY_EC].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "E" ) );
  222. sKeyword[NF_KEY_EEC].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "EE" ) );
  223. sKeyword[NF_KEY_G].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "G" ) );
  224. sKeyword[NF_KEY_GG].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GG" ) );
  225. sKeyword[NF_KEY_GGG].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GGG" ) );
  226. sKeyword[NF_KEY_R].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "R" ) );
  227. sKeyword[NF_KEY_RR].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "RR" ) );
  228. // Thai T NatNum special. Other locale's small letter 't' results in upper
  229. // case comparison not matching but length does in conversion mode. Ugly.
  230. if (eLang == LANGUAGE_THAI)
  231. sKeyword[NF_KEY_THAI_T].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "T"));
  232. else
  233. sKeyword[NF_KEY_THAI_T].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "t"));
  234. switch ( eLang )
  235. {
  236. case LANGUAGE_GERMAN:
  237. case LANGUAGE_GERMAN_SWISS:
  238. case LANGUAGE_GERMAN_AUSTRIAN:
  239. case LANGUAGE_GERMAN_LUXEMBOURG:
  240. case LANGUAGE_GERMAN_LIECHTENSTEIN:
  241. {
  242. //! all capital letters
  243. sKeyword[NF_KEY_M].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "M" ) ); // month 1
  244. sKeyword[NF_KEY_MM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MM" ) ); // month 01
  245. sKeyword[NF_KEY_MMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMM" ) ); // month Jan
  246. sKeyword[NF_KEY_MMMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMMM" ) ); // month Januar
  247. sKeyword[NF_KEY_MMMMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMMMM" ) );// month J
  248. sKeyword[NF_KEY_H].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "H" ) ); // hour 2
  249. sKeyword[NF_KEY_HH].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "HH" ) ); // hour 02
  250. sKeyword[NF_KEY_D].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "T" ) );
  251. sKeyword[NF_KEY_DD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "TT" ) );
  252. sKeyword[NF_KEY_DDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "TTT" ) );
  253. sKeyword[NF_KEY_DDDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "TTTT" ) );
  254. sKeyword[NF_KEY_YY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJ" ) );
  255. sKeyword[NF_KEY_YYYY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJJJ" ) );
  256. sKeyword[NF_KEY_BOOLEAN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "LOGISCH" ) );
  257. sKeyword[NF_KEY_COLOR].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "FARBE" ) );
  258. sKeyword[NF_KEY_BLACK].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "SCHWARZ" ) );
  259. sKeyword[NF_KEY_BLUE].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "BLAU" ) );
  260. sKeyword[NF_KEY_GREEN] = UniString( "GR" "\xDC" "N", RTL_TEXTENCODING_ISO_8859_1 );
  261. sKeyword[NF_KEY_CYAN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "CYAN" ) );
  262. sKeyword[NF_KEY_RED].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "ROT" ) );
  263. sKeyword[NF_KEY_MAGENTA].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MAGENTA" ) );
  264. sKeyword[NF_KEY_BROWN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "BRAUN" ) );
  265. sKeyword[NF_KEY_GREY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GRAU" ) );
  266. sKeyword[NF_KEY_YELLOW].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GELB" ) );
  267. sKeyword[NF_KEY_WHITE].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "WEISS" ) );
  268. }
  269. break;
  270. default:
  271. {
  272. // day
  273. switch ( eLang )
  274. {
  275. case LANGUAGE_ITALIAN :
  276. case LANGUAGE_ITALIAN_SWISS :
  277. sKeyword[NF_KEY_D].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "G" ) );
  278. sKeyword[NF_KEY_DD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GG" ) );
  279. sKeyword[NF_KEY_DDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GGG" ) );
  280. sKeyword[NF_KEY_DDDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GGGG" ) );
  281. // must exchange the era code, same as Xcl
  282. sKeyword[NF_KEY_G].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "X" ) );
  283. sKeyword[NF_KEY_GG].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "XX" ) );
  284. sKeyword[NF_KEY_GGG].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "XXX" ) );
  285. break;
  286. case LANGUAGE_FRENCH :
  287. case LANGUAGE_FRENCH_BELGIAN :
  288. case LANGUAGE_FRENCH_CANADIAN :
  289. case LANGUAGE_FRENCH_SWISS :
  290. case LANGUAGE_FRENCH_LUXEMBOURG :
  291. case LANGUAGE_FRENCH_MONACO :
  292. sKeyword[NF_KEY_D].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "J" ) );
  293. sKeyword[NF_KEY_DD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJ" ) );
  294. sKeyword[NF_KEY_DDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJJ" ) );
  295. sKeyword[NF_KEY_DDDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJJJ" ) );
  296. break;
  297. case LANGUAGE_FINNISH :
  298. sKeyword[NF_KEY_D].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "P" ) );
  299. sKeyword[NF_KEY_DD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "PP" ) );
  300. sKeyword[NF_KEY_DDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "PPP" ) );
  301. sKeyword[NF_KEY_DDDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "PPPP" ) );
  302. break;
  303. default:
  304. sKeyword[NF_KEY_D].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D" ) );
  305. sKeyword[NF_KEY_DD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DD" ) );
  306. sKeyword[NF_KEY_DDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDD" ) );
  307. sKeyword[NF_KEY_DDDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDDD" ) );
  308. }
  309. // month
  310. switch ( eLang )
  311. {
  312. case LANGUAGE_FINNISH :
  313. sKeyword[NF_KEY_M].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "K" ) );
  314. sKeyword[NF_KEY_MM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "KK" ) );
  315. sKeyword[NF_KEY_MMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "KKK" ) );
  316. sKeyword[NF_KEY_MMMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "KKKK" ) );
  317. sKeyword[NF_KEY_MMMMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "KKKKK" ) );
  318. break;
  319. default:
  320. sKeyword[NF_KEY_M].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "M" ) );
  321. sKeyword[NF_KEY_MM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MM" ) );
  322. sKeyword[NF_KEY_MMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMM" ) );
  323. sKeyword[NF_KEY_MMMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMMM" ) );
  324. sKeyword[NF_KEY_MMMMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMMMM" ) );
  325. }
  326. // year
  327. switch ( eLang )
  328. {
  329. case LANGUAGE_ITALIAN :
  330. case LANGUAGE_ITALIAN_SWISS :
  331. case LANGUAGE_FRENCH :
  332. case LANGUAGE_FRENCH_BELGIAN :
  333. case LANGUAGE_FRENCH_CANADIAN :
  334. case LANGUAGE_FRENCH_SWISS :
  335. case LANGUAGE_FRENCH_LUXEMBOURG :
  336. case LANGUAGE_FRENCH_MONACO :
  337. case LANGUAGE_PORTUGUESE :
  338. case LANGUAGE_PORTUGUESE_BRAZILIAN :
  339. case LANGUAGE_SPANISH_MODERN :
  340. case LANGUAGE_SPANISH_DATED :
  341. case LANGUAGE_SPANISH_MEXICAN :
  342. case LANGUAGE_SPANISH_GUATEMALA :
  343. case LANGUAGE_SPANISH_COSTARICA :
  344. case LANGUAGE_SPANISH_PANAMA :
  345. case LANGUAGE_SPANISH_DOMINICAN_REPUBLIC :
  346. case LANGUAGE_SPANISH_VENEZUELA :
  347. case LANGUAGE_SPANISH_COLOMBIA :
  348. case LANGUAGE_SPANISH_PERU :
  349. case LANGUAGE_SPANISH_ARGENTINA :
  350. case LANGUAGE_SPANISH_ECUADOR :
  351. case LANGUAGE_SPANISH_CHILE :
  352. case LANGUAGE_SPANISH_URUGUAY :
  353. case LANGUAGE_SPANISH_PARAGUAY :
  354. case LANGUAGE_SPANISH_BOLIVIA :
  355. case LANGUAGE_SPANISH_EL_SALVADOR :
  356. case LANGUAGE_SPANISH_HONDURAS :
  357. case LANGUAGE_SPANISH_NICARAGUA :
  358. case LANGUAGE_SPANISH_PUERTO_RICO :
  359. sKeyword[NF_KEY_YY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "AA" ) );
  360. sKeyword[NF_KEY_YYYY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "AAAA" ) );
  361. // must exchange the day of week name code, same as Xcl
  362. sKeyword[NF_KEY_AAA].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "OOO" ) );
  363. sKeyword[NF_KEY_AAAA].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "OOOO" ) );
  364. break;
  365. case LANGUAGE_DUTCH :
  366. case LANGUAGE_DUTCH_BELGIAN :
  367. sKeyword[NF_KEY_YY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJ" ) );
  368. sKeyword[NF_KEY_YYYY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJJJ" ) );
  369. break;
  370. case LANGUAGE_FINNISH :
  371. sKeyword[NF_KEY_YY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "VV" ) );
  372. sKeyword[NF_KEY_YYYY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "VVVV" ) );
  373. break;
  374. default:
  375. sKeyword[NF_KEY_YY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "YY" ) );
  376. sKeyword[NF_KEY_YYYY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "YYYY" ) );
  377. }
  378. // hour
  379. switch ( eLang )
  380. {
  381. case LANGUAGE_DUTCH :
  382. case LANGUAGE_DUTCH_BELGIAN :
  383. sKeyword[NF_KEY_H].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "U" ) );
  384. sKeyword[NF_KEY_HH].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "UU" ) );
  385. break;
  386. case LANGUAGE_FINNISH :
  387. case LANGUAGE_SWEDISH :
  388. case LANGUAGE_SWEDISH_FINLAND :
  389. case LANGUAGE_DANISH :
  390. case LANGUAGE_NORWEGIAN :
  391. case LANGUAGE_NORWEGIAN_BOKMAL :
  392. case LANGUAGE_NORWEGIAN_NYNORSK :
  393. sKeyword[NF_KEY_H].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "T" ) );
  394. sKeyword[NF_KEY_HH].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "TT" ) );
  395. break;
  396. default:
  397. sKeyword[NF_KEY_H].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "H" ) );
  398. sKeyword[NF_KEY_HH].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "HH" ) );
  399. }
  400. // boolean
  401. sKeyword[NF_KEY_BOOLEAN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "BOOLEAN" ) );
  402. // colours
  403. sKeyword[NF_KEY_COLOR].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "COLOR" ) );
  404. sKeyword[NF_KEY_BLACK].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "BLACK" ) );
  405. sKeyword[NF_KEY_BLUE].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "BLUE" ) );
  406. sKeyword[NF_KEY_GREEN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GREEN" ) );
  407. sKeyword[NF_KEY_CYAN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "CYAN" ) );
  408. sKeyword[NF_KEY_RED].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "RED" ) );
  409. sKeyword[NF_KEY_MAGENTA].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MAGENTA" ) );
  410. sKeyword[NF_KEY_BROWN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "BROWN" ) );
  411. sKeyword[NF_KEY_GREY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GREY" ) );
  412. sKeyword[NF_KEY_YELLOW].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "YELLOW" ) );
  413. sKeyword[NF_KEY_WHITE].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "WHITE" ) );
  414. }
  415. break;
  416. }
  417. // boolean keyords
  418. InitSpecialKeyword( NF_KEY_TRUE );
  419. InitSpecialKeyword( NF_KEY_FALSE );
  420. // compatibility currency strings
  421. InitCompatCur();
  422. }
  423. void ImpSvNumberformatScan::ChangeNullDate(sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear)
  424. {
  425. if ( pNullDate )
  426. *pNullDate = Date(nDay, nMonth, nYear);
  427. else
  428. pNullDate = new Date(nDay, nMonth, nYear);
  429. }
  430. void ImpSvNumberformatScan::ChangeStandardPrec(sal_uInt16 nPrec)
  431. {
  432. nStandardPrec = nPrec;
  433. }
  434. Color* ImpSvNumberformatScan::GetColor(String& sStr)
  435. {
  436. String sString = pFormatter->GetCharClass()->uppercase(sStr);
  437. const NfKeywordTable & rKeyword = GetKeywords();
  438. size_t i = 0;
  439. while (i < NF_MAX_DEFAULT_COLORS &&
  440. sString != rKeyword[NF_KEY_FIRSTCOLOR+i] )
  441. i++;
  442. if ( i >= NF_MAX_DEFAULT_COLORS )
  443. {
  444. const String* pEnglishColors = theEnglishColors::get();
  445. size_t j = 0;
  446. while ( j < NF_MAX_DEFAULT_COLORS &&
  447. sString != pEnglishColors[j] )
  448. ++j;
  449. if ( j < NF_MAX_DEFAULT_COLORS )
  450. i = j;
  451. }
  452. Color* pResult = NULL;
  453. if (i >= NF_MAX_DEFAULT_COLORS)
  454. {
  455. const String& rColorWord = rKeyword[NF_KEY_COLOR];
  456. xub_StrLen nPos = sString.Match(rColorWord);
  457. if (nPos > 0)
  458. {
  459. sStr.Erase(0, nPos);
  460. sStr.EraseLeadingChars();
  461. sStr.EraseTrailingChars();
  462. if (bConvertMode)
  463. {
  464. pFormatter->ChangeIntl(eNewLnge);
  465. sStr.Insert( GetKeywords()[NF_KEY_COLOR], 0 ); // Color -> FARBE
  466. pFormatter->ChangeIntl(eTmpLnge);
  467. }
  468. else
  469. sStr.Insert(rColorWord,0);
  470. sString.Erase(0, nPos);
  471. sString.EraseLeadingChars();
  472. sString.EraseTrailingChars();
  473. if ( CharClass::isAsciiNumeric( sString ) )
  474. {
  475. long nIndex = sString.ToInt32();
  476. if (nIndex > 0 && nIndex <= 64)
  477. pResult = pFormatter->GetUserDefColor((sal_uInt16)nIndex-1);
  478. }
  479. }
  480. }
  481. else
  482. {
  483. sStr.Erase();
  484. if (bConvertMode)
  485. {
  486. pFormatter->ChangeIntl(eNewLnge);
  487. sStr = GetKeywords()[NF_KEY_FIRSTCOLOR+i]; // red -> rot
  488. pFormatter->ChangeIntl(eTmpLnge);
  489. }
  490. else
  491. sStr = rKeyword[NF_KEY_FIRSTCOLOR+i];
  492. pResult = &(StandardColor[i]);
  493. }
  494. return pResult;
  495. }
  496. short ImpSvNumberformatScan::GetKeyWord( const String& sSymbol, xub_StrLen nPos )
  497. {
  498. String sString = pFormatter->GetCharClass()->uppercase( sSymbol, nPos, sSymbol.Len() - nPos );
  499. const NfKeywordTable & rKeyword = GetKeywords();
  500. // #77026# for the Xcl perverts: the GENERAL keyword is recognized anywhere
  501. if ( sString.Search( rKeyword[NF_KEY_GENERAL] ) == 0 )
  502. return NF_KEY_GENERAL;
  503. //! MUST be a reverse search to find longer strings first
  504. short i = NF_KEYWORD_ENTRIES_COUNT-1;
  505. bool bFound = false;
  506. for ( ; i > NF_KEY_LASTKEYWORD_SO5; --i )
  507. {
  508. bFound = sString.Search(rKeyword[i]) == 0;
  509. if ( bFound )
  510. {
  511. break;
  512. }
  513. }
  514. // new keywords take precedence over old keywords
  515. if ( !bFound )
  516. { // skip the gap of colors et al between new and old keywords and search on
  517. i = NF_KEY_LASTKEYWORD;
  518. while ( i > 0 && sString.Search(rKeyword[i]) != 0 )
  519. i--;
  520. if ( i > NF_KEY_LASTOLDKEYWORD && sString != rKeyword[i] )
  521. { // found something, but maybe it's something else?
  522. // e.g. new NNN is found in NNNN, for NNNN we must search on
  523. short j = i - 1;
  524. while ( j > 0 && sString.Search(rKeyword[j]) != 0 )
  525. j--;
  526. if ( j && rKeyword[j].Len() > rKeyword[i].Len() )
  527. return j;
  528. }
  529. }
  530. // The Thai T NatNum modifier during Xcl import.
  531. if (i == 0 && bConvertMode && sString.GetChar(0) == 'T' && eTmpLnge ==
  532. LANGUAGE_ENGLISH_US && MsLangId::getRealLanguage( eNewLnge) ==
  533. LANGUAGE_THAI)
  534. i = NF_KEY_THAI_T;
  535. return i; // 0 => not found
  536. }
  537. //---------------------------------------------------------------------------
  538. // Next_Symbol
  539. //---------------------------------------------------------------------------
  540. // Zerlegt die Eingabe in Symbole fuer die weitere
  541. // Verarbeitung (Turing-Maschine).
  542. //---------------------------------------------------------------------------
  543. // Ausgangs Zustand = SsStart
  544. //---------------+-------------------+-----------------------+---------------
  545. // Alter Zustand | gelesenes Zeichen | Aktion | Neuer Zustand
  546. //---------------+-------------------+-----------------------+---------------
  547. // SsStart | Buchstabe | Symbol=Zeichen | SsGetWord
  548. // | " | Typ = String | SsGetString
  549. // | \ | Typ = String | SsGetChar
  550. // | * | Typ = Star | SsGetStar
  551. // | _ | Typ = Blank | SsGetBlank
  552. // | @ # 0 ? / . , % [ | Symbol = Zeichen; |
  553. // | ] ' Blank | Typ = Steuerzeichen | SsStop
  554. // | $ - + ( ) : | Typ = String; |
  555. // | Sonst | Symbol = Zeichen | SsStop
  556. //---------------|-------------------+-----------------------+---------------
  557. // SsGetChar | Sonst | Symbol=Zeichen | SsStop
  558. //---------------+-------------------+-----------------------+---------------
  559. // GetString | " | | SsStop
  560. // | Sonst | Symbol+=Zeichen | GetString
  561. //---------------+-------------------+-----------------------+---------------
  562. // SsGetWord | Buchstabe | Symbol += Zeichen |
  563. // | + - (E+ E-)| Symbol += Zeichen | SsStop
  564. // | / (AM/PM)| Symbol += Zeichen |
  565. // | Sonst | Pos--, if Key Typ=Word| SsStop
  566. //---------------+-------------------+-----------------------+---------------
  567. // SsGetStar | Sonst | Symbol+=Zeichen | SsStop
  568. // | | markiere Sonderfall * |
  569. //---------------+-------------------+-----------------------+---------------
  570. // SsGetBlank | Sonst | Symbol+=Zeichen | SsStop
  571. // | | markiere Sonderfall _ |
  572. //---------------+-------------------+-----------------------+---------------
  573. // Wurde im State SsGetWord ein Schluesselwort erkannt (auch als
  574. // Anfangsteilwort des Symbols)
  575. // so werden die restlichen Buchstaben zurueckgeschrieben !!
  576. enum ScanState
  577. {
  578. SsStop = 0,
  579. SsStart = 1,
  580. SsGetChar = 2,
  581. SsGetString = 3,
  582. SsGetWord = 4,
  583. SsGetStar = 5,
  584. SsGetBlank = 6
  585. };
  586. short ImpSvNumberformatScan::Next_Symbol( const String& rStr,
  587. xub_StrLen& nPos, String& sSymbol )
  588. {
  589. if ( bKeywordsNeedInit )
  590. InitKeywords();
  591. const CharClass* pChrCls = pFormatter->GetCharClass();
  592. const LocaleDataWrapper* pLoc = pFormatter->GetLocaleData();
  593. const xub_StrLen nStart = nPos;
  594. short eType = 0;
  595. ScanState eState = SsStart;
  596. sSymbol.Erase();
  597. while ( nPos < rStr.Len() && eState != SsStop )
  598. {
  599. sal_Unicode cToken = rStr.GetChar( nPos++ );
  600. switch (eState)
  601. {
  602. case SsStart:
  603. {
  604. // Fetch any currency longer than one character and don't get
  605. // confused later on by "E/" or other combinations of letters
  606. // and meaningful symbols. Necessary for old automatic currency.
  607. // #96158# But don't do it if we're starting a "[...]" section,
  608. // for example a "[$...]" new currency symbol to not parse away
  609. // "$U" (symbol) of "[$UYU]" (abbreviation).
  610. if ( nCurrPos != STRING_NOTFOUND && sCurString.Len() > 1 &&
  611. nPos-1 + sCurString.Len() <= rStr.Len() &&
  612. !(nPos > 1 && rStr.GetChar( nPos-2 ) == '[') )
  613. {
  614. String aTest = pChrCls->uppercase( rStr.Copy( nPos-1, sCurString.Len() ) );
  615. if ( aTest == sCurString )
  616. {
  617. sSymbol = rStr.Copy( --nPos, sCurString.Len() );
  618. nPos = nPos + sSymbol.Len();
  619. eState = SsStop;
  620. eType = NF_SYMBOLTYPE_STRING;
  621. return eType;
  622. }
  623. }
  624. switch (cToken)
  625. {
  626. case '#':
  627. case '0':
  628. case '?':
  629. case '%':
  630. case '@':
  631. case '[':
  632. case ']':
  633. case ',':
  634. case '.':
  635. case '/':
  636. case '\'':
  637. case ' ':
  638. case ':':
  639. case '-':
  640. {
  641. eType = NF_SYMBOLTYPE_DEL;
  642. sSymbol += cToken;
  643. eState = SsStop;
  644. }
  645. break;
  646. case '*':
  647. {
  648. eType = NF_SYMBOLTYPE_STAR;
  649. sSymbol += cToken;
  650. eState = SsGetStar;
  651. }
  652. break;
  653. case '_':
  654. {
  655. eType = NF_SYMBOLTYPE_BLANK;
  656. sSymbol += cToken;
  657. eState = SsGetBlank;
  658. }
  659. break;
  660. case '"':
  661. eType = NF_SYMBOLTYPE_STRING;
  662. eState = SsGetString;
  663. sSymbol += cToken;
  664. break;
  665. case '\\':
  666. eType = NF_SYMBOLTYPE_STRING;
  667. eState = SsGetChar;
  668. sSymbol += cToken;
  669. break;
  670. case '$':
  671. case '+':
  672. case '(':
  673. case ')':
  674. eType = NF_SYMBOLTYPE_STRING;
  675. eState = SsStop;
  676. sSymbol += cToken;
  677. break;
  678. default :
  679. {
  680. if (StringEqualsChar( pFormatter->GetNumDecimalSep(), cToken) ||
  681. StringEqualsChar( pFormatter->GetNumThousandSep(), cToken) ||
  682. StringEqualsChar( pFormatter->GetDateSep(), cToken) ||
  683. StringEqualsChar( pLoc->getTimeSep(), cToken) ||
  684. StringEqualsChar( pLoc->getTime100SecSep(), cToken))
  685. {
  686. // Another separator than pre-known ASCII
  687. eType = NF_SYMBOLTYPE_DEL;
  688. sSymbol += cToken;
  689. eState = SsStop;
  690. }
  691. else if ( pChrCls->isLetter( rStr, nPos-1 ) )
  692. {
  693. short nTmpType = GetKeyWord( rStr, nPos-1 );
  694. if ( nTmpType )
  695. {
  696. bool bCurrency = false;
  697. // "Automatic" currency may start with keyword,
  698. // like "R" (Rand) and 'R' (era)
  699. if ( nCurrPos != STRING_NOTFOUND &&
  700. nPos-1 + sCurString.Len() <= rStr.Len() &&
  701. sCurString.Search( sKeyword[nTmpType] ) == 0 )
  702. {
  703. String aTest = pChrCls->uppercase( rStr.Copy( nPos-1, sCurString.Len() ) );
  704. if ( aTest == sCurString )
  705. bCurrency = true;
  706. }
  707. if ( bCurrency )
  708. {
  709. eState = SsGetWord;
  710. sSymbol += cToken;
  711. }
  712. else
  713. {
  714. eType = nTmpType;
  715. xub_StrLen nLen = sKeyword[eType].Len();
  716. sSymbol = rStr.Copy( nPos-1, nLen );
  717. if ( eType == NF_KEY_E || IsAmbiguousE( eType ) )
  718. {
  719. sal_Unicode cNext = rStr.GetChar(nPos);
  720. switch ( cNext )
  721. {
  722. case '+' :
  723. case '-' : // E+ E- combine to one symbol
  724. sSymbol += cNext;
  725. eType = NF_KEY_E;
  726. nPos++;
  727. break;
  728. case '0' :
  729. case '#' : // scientific E without sign
  730. eType = NF_KEY_E;
  731. break;
  732. }
  733. }
  734. nPos--;
  735. nPos = nPos + nLen;
  736. eState = SsStop;
  737. }
  738. }
  739. else
  740. {
  741. eState = SsGetWord;
  742. sSymbol += cToken;
  743. }
  744. }
  745. else
  746. {
  747. eType = NF_SYMBOLTYPE_STRING;
  748. eState = SsStop;
  749. sSymbol += cToken;
  750. }
  751. }
  752. break;
  753. }
  754. }
  755. break;
  756. case SsGetChar:
  757. {
  758. sSymbol += cToken;
  759. eState = SsStop;
  760. }
  761. break;
  762. case SsGetString:
  763. {
  764. if (cToken == '"')
  765. eState = SsStop;
  766. sSymbol += cToken;
  767. }
  768. break;
  769. case SsGetWord:
  770. {
  771. if ( pChrCls->isLetter( rStr, nPos-1 ) )
  772. {
  773. short nTmpType = GetKeyWord( rStr, nPos-1 );
  774. if ( nTmpType )
  775. { // beginning of keyword, stop scan and put back
  776. eType = NF_SYMBOLTYPE_STRING;
  777. eState = SsStop;
  778. nPos--;
  779. }
  780. else
  781. sSymbol += cToken;
  782. }
  783. else
  784. {
  785. bool bDontStop = false;
  786. switch (cToken)
  787. {
  788. case '/': // AM/PM, A/P
  789. {
  790. sal_Unicode cNext = rStr.GetChar(nPos);
  791. if ( cNext == 'P' || cNext == 'p' )
  792. {
  793. xub_StrLen nLen = sSymbol.Len();
  794. if ( 1 <= nLen
  795. && (sSymbol.GetChar(0) == 'A' || sSymbol.GetChar(0) == 'a')
  796. && (nLen == 1 || (nLen == 2
  797. && (sSymbol.GetChar(1) == 'M' || sSymbol.GetChar(1) == 'm')
  798. && (rStr.GetChar(nPos+1) == 'M' || rStr.GetChar(nPos+1) == 'm'))) )
  799. {
  800. sSymbol += cToken;
  801. bDontStop = true;
  802. }
  803. }
  804. }
  805. break;
  806. }
  807. // anything not recognized will stop the scan
  808. if ( eState != SsStop && !bDontStop )
  809. {
  810. eState = SsStop;
  811. nPos--;
  812. eType = NF_SYMBOLTYPE_STRING;
  813. }
  814. }
  815. }
  816. break;
  817. case SsGetStar:
  818. {
  819. eState = SsStop;
  820. sSymbol += cToken;
  821. nRepPos = (nPos - nStart) - 1; // everytime > 0!!
  822. }
  823. break;
  824. case SsGetBlank:
  825. {
  826. eState = SsStop;
  827. sSymbol += cToken;
  828. }
  829. break;
  830. default:
  831. break;
  832. } // of switch
  833. } // of while
  834. if (eState == SsGetWord)
  835. eType = NF_SYMBOLTYPE_STRING;
  836. return eType;
  837. }
  838. xub_StrLen ImpSvNumberformatScan::Symbol_Division(const String& rString)
  839. {
  840. nCurrPos = STRING_NOTFOUND;
  841. // Ist Waehrung im Spiel?
  842. String sString = pFormatter->GetCharClass()->uppercase(rString);
  843. xub_StrLen nCPos = 0;
  844. while (nCPos != STRING_NOTFOUND)
  845. {
  846. nCPos = sString.Search(GetCurString(),nCPos);
  847. if (nCPos != STRING_NOTFOUND)
  848. {
  849. // in Quotes?
  850. xub_StrLen nQ = SvNumberformat::GetQuoteEnd( sString, nCPos );
  851. if ( nQ == STRING_NOTFOUND )
  852. {
  853. sal_Unicode c;
  854. if ( nCPos == 0 ||
  855. ((c = sString.GetChar(xub_StrLen(nCPos-1))) != '"'
  856. && c != '\\') ) // dm kann durch "dm
  857. { // \d geschuetzt werden
  858. nCurrPos = nCPos;
  859. nCPos = STRING_NOTFOUND; // Abbruch
  860. }
  861. else
  862. nCPos++; // weitersuchen
  863. }
  864. else
  865. nCPos = nQ + 1; // weitersuchen
  866. }
  867. }
  868. nAnzStrings = 0;
  869. bool bStar = false; // wird bei '*'Detektion gesetzt
  870. Reset();
  871. xub_StrLen nPos = 0;
  872. const xub_StrLen nLen = rString.Len();
  873. while (nPos < nLen && nAnzStrings < NF_MAX_FORMAT_SYMBOLS)
  874. {
  875. nTypeArray[nAnzStrings] = Next_Symbol(rString, nPos, sStrArray[nAnzStrings]);
  876. if (nTypeArray[nAnzStrings] == NF_SYMBOLTYPE_STAR)
  877. { // Ueberwachung des '*'
  878. if (bStar)
  879. return nPos; // Fehler: doppelter '*'
  880. else
  881. bStar = true;
  882. }
  883. nAnzStrings++;
  884. }
  885. return 0; // 0 => ok
  886. }
  887. void ImpSvNumberformatScan::SkipStrings(sal_uInt16& i, xub_StrLen& nPos)
  888. {
  889. while (i < nAnzStrings && ( nTypeArray[i] == NF_SYMBOLTYPE_STRING
  890. || nTypeArray[i] == NF_SYMBOLTYPE_BLANK
  891. || nTypeArray[i] == NF_SYMBOLTYPE_STAR) )
  892. {
  893. nPos = nPos + sStrArray[i].Len();
  894. i++;
  895. }
  896. }
  897. sal_uInt16 ImpSvNumberformatScan::PreviousKeyword(sal_uInt16 i)
  898. {
  899. short res = 0;
  900. if (i > 0 && i < nAnzStrings)
  901. {
  902. i--;
  903. while (i > 0 && nTypeArray[i] <= 0)
  904. i--;
  905. if (nTypeArray[i] > 0)
  906. res = nTypeArray[i];
  907. }
  908. return res;
  909. }
  910. sal_uInt16 ImpSvNumberformatScan::NextKeyword(sal_uInt16 i)
  911. {
  912. short res = 0;
  913. if (i < nAnzStrings-1)
  914. {
  915. i++;
  916. while (i < nAnzStrings-1 && nTypeArray[i] <= 0)
  917. i++;
  918. if (nTypeArray[i] > 0)
  919. res = nTypeArray[i];
  920. }
  921. return res;
  922. }
  923. short ImpSvNumberformatScan::PreviousType( sal_uInt16 i )
  924. {
  925. if ( i > 0 && i < nAnzStrings )
  926. {
  927. do
  928. {
  929. i--;
  930. } while ( i > 0 && nTypeArray[i] == NF_SYMBOLTYPE_EMPTY );
  931. return nTypeArray[i];
  932. }
  933. return 0;
  934. }
  935. sal_Unicode ImpSvNumberformatScan::PreviousChar(sal_uInt16 i)
  936. {
  937. sal_Unicode res = ' ';
  938. if (i > 0 && i < nAnzStrings)
  939. {
  940. i--;
  941. while (i > 0 && ( nTypeArray[i] == NF_SYMBOLTYPE_EMPTY
  942. || nTypeArray[i] == NF_SYMBOLTYPE_STRING
  943. || nTypeArray[i] == NF_SYMBOLTYPE_STAR
  944. || nTypeArray[i] == NF_SYMBOLTYPE_BLANK ) )
  945. i--;
  946. if (sStrArray[i].Len() > 0)
  947. res = sStrArray[i].GetChar(xub_StrLen(sStrArray[i].Len()-1));
  948. }
  949. return res;
  950. }
  951. sal_Unicode ImpSvNumberformatScan::NextChar(sal_uInt16 i)
  952. {
  953. sal_Unicode res = ' ';
  954. if (i < nAnzStrings-1)
  955. {
  956. i++;
  957. while (i < nAnzStrings-1 &&
  958. ( nTypeArray[i] == NF_SYMBOLTYPE_EMPTY
  959. || nTypeArray[i] == NF_SYMBOLTYPE_STRING
  960. || nTypeArray[i] == NF_SYMBOLTYPE_STAR
  961. || nTypeArray[i] == NF_SYMBOLTYPE_BLANK))
  962. i++;
  963. if (sStrArray[i].Len() > 0)
  964. res = sStrArray[i].GetChar(0);
  965. }
  966. return res;
  967. }
  968. bool ImpSvNumberformatScan::IsLastBlankBeforeFrac(sal_uInt16 i)
  969. {
  970. bool res = true;
  971. if (i < nAnzStrings-1)
  972. {
  973. bool bStop = false;
  974. i++;
  975. while (i < nAnzStrings-1 && !bStop)
  976. {
  977. i++;
  978. if ( nTypeArray[i] == NF_SYMBOLTYPE_DEL &&
  979. sStrArray[i].GetChar(0) == '/')
  980. bStop = true;
  981. else if ( nTypeArray[i] == NF_SYMBOLTYPE_DEL &&
  982. sStrArray[i].GetChar(0) == ' ')
  983. res = false;
  984. }
  985. if (!bStop) // kein '/'
  986. res = false;
  987. }
  988. else
  989. res = false; // kein '/' mehr
  990. return res;
  991. }
  992. void ImpSvNumberformatScan::Reset()
  993. {
  994. nAnzStrings = 0;
  995. nAnzResStrings = 0;
  996. #if 0
  997. // ER 20.06.97 14:05 nicht noetig, wenn nAnzStrings beachtet wird
  998. for (size_t i = 0; i < NF_MAX_FORMAT_SYMBOLS; i++)
  999. {
  1000. sStrArray[i].Erase();
  1001. nTypeArray[i] = 0;
  1002. }
  1003. #endif
  1004. eScannedType = NUMBERFORMAT_UNDEFINED;
  1005. nRepPos = 0;
  1006. bExp = false;
  1007. bThousand = false;
  1008. nThousand = 0;
  1009. bDecSep = false;
  1010. nDecPos = -1;
  1011. nExpPos = (sal_uInt16) -1;
  1012. nBlankPos = (sal_uInt16) -1;
  1013. nCntPre = 0;
  1014. nCntPost = 0;
  1015. nCntExp = 0;
  1016. bFrac = false;
  1017. bBlank = false;
  1018. nNatNumModifier = 0;
  1019. }
  1020. bool ImpSvNumberformatScan::Is100SecZero( sal_uInt16 i, bool bHadDecSep )
  1021. {
  1022. sal_uInt16 nIndexPre = PreviousKeyword( i );
  1023. return (nIndexPre == NF_KEY_S || nIndexPre == NF_KEY_SS)
  1024. && (bHadDecSep // S, SS ','
  1025. || (i>0 && nTypeArray[i-1] == NF_SYMBOLTYPE_STRING));
  1026. // SS"any"00 take "any" as a valid decimal separator
  1027. }
  1028. xub_StrLen ImpSvNumberformatScan::ScanType()
  1029. {
  1030. const LocaleDataWrapper* pLoc = pFormatter->GetLocaleData();
  1031. xub_StrLen nPos = 0;
  1032. sal_uInt16 i = 0;
  1033. short eNewType;
  1034. bool bMatchBracket = false;
  1035. bool bHaveGeneral = false; // if General/Standard encountered
  1036. SkipStrings(i, nPos);
  1037. while (i < nAnzStrings)
  1038. {
  1039. if (nTypeArray[i] > 0)
  1040. { // keyword
  1041. switch (nTypeArray[i])
  1042. {
  1043. case NF_KEY_E: // E
  1044. eNewType = NUMBERFORMAT_SCIENTIFIC;
  1045. break;
  1046. case NF_KEY_AMPM: // AM,A,PM,P
  1047. case NF_KEY_AP:
  1048. case NF_KEY_H: // H
  1049. case NF_KEY_HH: // HH
  1050. case NF_KEY_S: // S
  1051. case NF_KEY_SS: // SS
  1052. eNewType = NUMBERFORMAT_TIME;
  1053. break;
  1054. case NF_KEY_M: // M
  1055. case NF_KEY_MM: // MM
  1056. { // minute or month
  1057. sal_uInt16 nIndexPre = PreviousKeyword(i);
  1058. sal_uInt16 nIndexNex = NextKeyword(i);
  1059. sal_Unicode cChar = PreviousChar(i);
  1060. if (nIndexPre == NF_KEY_H || // H
  1061. nIndexPre == NF_KEY_HH || // HH
  1062. nIndexNex == NF_KEY_S || // S
  1063. nIndexNex == NF_KEY_SS || // SS
  1064. cChar == '[' ) // [M
  1065. {
  1066. eNewType = NUMBERFORMAT_TIME;
  1067. nTypeArray[i] -= 2; // 6 -> 4, 7 -> 5
  1068. }
  1069. else
  1070. eNewType = NUMBERFORMAT_DATE;
  1071. }
  1072. break;
  1073. case NF_KEY_MMM: // MMM
  1074. case NF_KEY_MMMM: // MMMM
  1075. case NF_KEY_MMMMM: // MMMMM
  1076. case NF_KEY_Q: // Q
  1077. case NF_KEY_QQ: // QQ
  1078. case NF_KEY_D: // D
  1079. case NF_KEY_DD: // DD
  1080. case NF_KEY_DDD: // DDD
  1081. case NF_KEY_DDDD: // DDDD
  1082. case NF_KEY_YY: // YY
  1083. case NF_KEY_YYYY: // YYYY
  1084. case NF_KEY_NN: // NN
  1085. case NF_KEY_NNN: // NNN
  1086. case NF_KEY_NNNN: // NNNN
  1087. case NF_KEY_WW : // WW
  1088. case NF_KEY_AAA : // AAA
  1089. case NF_KEY_AAAA : // AAAA
  1090. case NF_KEY_EC : // E
  1091. case NF_KEY_EEC : // EE
  1092. case NF_KEY_G : // G
  1093. case NF_KEY_GG : // GG
  1094. case NF_KEY_GGG : // GGG
  1095. case NF_KEY_R : // R
  1096. case NF_KEY_RR : // RR
  1097. eNewType = NUMBERFORMAT_DATE;
  1098. break;
  1099. case NF_KEY_CCC: // CCC
  1100. eNewType = NUMBERFORMAT_CURRENCY;
  1101. break;
  1102. case NF_KEY_GENERAL: // Standard
  1103. eNewType = NUMBERFORMAT_NUMBER;
  1104. bHaveGeneral = true;
  1105. break;
  1106. default:
  1107. eNewType = NUMBERFORMAT_UNDEFINED;
  1108. break;
  1109. }
  1110. }
  1111. else
  1112. { // control character
  1113. switch ( sStrArray[i].GetChar(0) )
  1114. {
  1115. case '#':
  1116. case '?':
  1117. eNewType = NUMBERFORMAT_NUMBER;
  1118. break;
  1119. case '0':
  1120. {
  1121. if ( (eScannedType & NUMBERFORMAT_TIME) == NUMBERFORMAT_TIME )
  1122. {
  1123. if ( Is100SecZero( i, bDecSep ) )
  1124. {
  1125. bDecSep = true; // subsequent 0's
  1126. eNewType = NUMBERFORMAT_TIME;
  1127. }
  1128. else
  1129. return nPos; // Error
  1130. }
  1131. else
  1132. eNewType = NUMBERFORMAT_NUMBER;
  1133. }
  1134. break;
  1135. case '%':

Large files files are truncated, but you can click here to view the full file