PageRenderTime 61ms 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

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

  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;

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