1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 #ifndef INCLUDED_SVL_SOURCE_NUMBERS_ZFORSCAN_HXX 20 #define INCLUDED_SVL_SOURCE_NUMBERS_ZFORSCAN_HXX 21 22 #include <i18nlangtag/lang.h> 23 #include <rtl/ustring.hxx> 24 #include <svl/nfkeytab.hxx> 25 #include <svl/nfsymbol.hxx> 26 #include <tools/color.hxx> 27 #include <tools/date.hxx> 28 29 class SvNumberFormatter; 30 struct ImpSvNumberformatInfo; 31 32 33 const size_t NF_MAX_DEFAULT_COLORS = 10; 34 35 // Hack: nThousand==1000 => "Default" occurs in format string 36 const sal_uInt16 FLAG_STANDARD_IN_FORMAT = 1000; 37 38 class ImpSvNumberformatScan 39 { 40 public: 41 42 /** Specify what keyword localization is allowed when scanning the format code. */ 43 enum class KeywordLocalization 44 { 45 LocaleLegacy, ///< unfortunately localized in few locales, otherwise English 46 EnglishOnly, ///< only English, no localized keywords 47 AllowEnglish ///< allow English keywords as well as localized keywords 48 }; 49 50 explicit ImpSvNumberformatScan( SvNumberFormatter* pFormatter ); 51 ~ImpSvNumberformatScan(); 52 void ChangeIntl( KeywordLocalization eKeywordLocalization = KeywordLocalization::AllowEnglish ); // Replaces Keywords 53 54 void ChangeNullDate(sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear); // Replaces reference date 55 void ChangeStandardPrec(sal_uInt16 nPrec); // Replaces standard precision 56 57 sal_Int32 ScanFormat( OUString& rString ); // Call scan analysis 58 59 void CopyInfo(ImpSvNumberformatInfo* pInfo, 60 sal_uInt16 nCnt); // Copies the FormatInfo GetResultStringsCnt() const61 sal_uInt16 GetResultStringsCnt() const { return nResultStringsCnt; } 62 GetChrCls() const63 const CharClass& GetChrCls() const { return *pFormatter->GetCharClass(); } GetLoc() const64 const LocaleDataWrapper& GetLoc() const { return *pFormatter->GetLocaleData(); } GetCal() const65 CalendarWrapper& GetCal() const { return *pFormatter->GetCalendar(); } 66 GetKeywords() const67 const NfKeywordTable & GetKeywords() const 68 { 69 if ( bKeywordsNeedInit ) 70 { 71 InitKeywords(); 72 } 73 return sKeyword; 74 } 75 GetEnglishKeywords()76 static const NfKeywordTable & GetEnglishKeywords() 77 { 78 return sEnglishKeyword; 79 } 80 81 // Keywords used in output like true and false GetSpecialKeyword(NfKeywordIndex eIdx) const82 const OUString& GetSpecialKeyword( NfKeywordIndex eIdx ) const 83 { 84 if ( sKeyword[eIdx].isEmpty() ) 85 { 86 InitSpecialKeyword( eIdx ); 87 } 88 return sKeyword[eIdx]; 89 } GetTrueString() const90 const OUString& GetTrueString() const { return GetSpecialKeyword( NF_KEY_TRUE ); } GetFalseString() const91 const OUString& GetFalseString() const { return GetSpecialKeyword( NF_KEY_FALSE ); } GetRedString() const92 const OUString& GetRedString() const { return GetKeywords()[NF_KEY_RED]; } GetBooleanString() const93 const OUString& GetBooleanString() const { return GetKeywords()[NF_KEY_BOOLEAN]; } GetErrorString()94 static const OUString& GetErrorString() { return sErrStr; } GetStandardColors()95 static const ::std::vector<Color> & GetStandardColors() 96 { 97 return StandardColor; 98 } GetMaxDefaultColors()99 static size_t GetMaxDefaultColors() 100 { 101 return NF_MAX_DEFAULT_COLORS; 102 } 103 GetNullDate() const104 const Date& GetNullDate() const { return maNullDate; } GetStandardName() const105 const OUString& GetStandardName() const 106 { 107 if ( bKeywordsNeedInit ) 108 { 109 InitKeywords(); 110 } 111 return sNameStandardFormat; 112 } GetStandardPrec() const113 sal_uInt16 GetStandardPrec() const { return nStandardPrec; } GetRedColor()114 static const Color& GetRedColor() { return StandardColor[4]; } 115 Color* GetColor(OUString& sStr); // Set main colors or defines colors 116 117 // the compatibility currency symbol for old automatic currency formats GetCurSymbol() const118 const OUString& GetCurSymbol() const 119 { 120 if ( bCompatCurNeedInit ) 121 { 122 InitCompatCur(); 123 } 124 return sCurSymbol; 125 } 126 127 // the compatibility currency abbreviation for CCC format code GetCurAbbrev() const128 const OUString& GetCurAbbrev() const 129 { 130 if ( bCompatCurNeedInit ) 131 { 132 InitCompatCur(); 133 } 134 return sCurAbbrev; 135 } 136 137 // the compatibility currency symbol upper case for old automatic currency formats GetCurString() const138 const OUString& GetCurString() const 139 { 140 if ( bCompatCurNeedInit ) 141 { 142 InitCompatCur(); 143 } 144 return sCurString; 145 } 146 147 /// Replace Boolean equivalent format codes with proper Boolean format. 148 void ReplaceBooleanEquivalent( OUString& rString ); 149 SetConvertMode(LanguageType eTmpLge,LanguageType eNewLge,bool bSystemToSystem,bool bConvertDateOrder)150 void SetConvertMode(LanguageType eTmpLge, LanguageType eNewLge, 151 bool bSystemToSystem, bool bConvertDateOrder) 152 { 153 bConvertMode = true; 154 eNewLnge = eNewLge; 155 eTmpLnge = eTmpLge; 156 bConvertSystemToSystem = bSystemToSystem; 157 mbConvertDateOrder = bConvertDateOrder; 158 } 159 // Only changes the bool variable, in order to temporarily pause the convert mode SetConvertMode(bool bMode)160 void SetConvertMode(bool bMode) { bConvertMode = bMode; } GetConvertMode() const161 bool GetConvertMode() const { return bConvertMode; } GetNewLnge() const162 LanguageType GetNewLnge() const { return eNewLnge; } // Read access on ConvertMode and convert country/language GetTmpLnge() const163 LanguageType GetTmpLnge() const { return eTmpLnge; } // Read access on StartCountry/Language SetNewLnge(LanguageType e)164 void SetNewLnge( LanguageType e ) { eNewLnge = e; } // Set new convert country/language 165 166 /// get Thai T speciality GetNatNumModifier() const167 sal_uInt8 GetNatNumModifier() const { return nNatNumModifier; } 168 /// set Thai T speciality SetNatNumModifier(sal_uInt8 n)169 void SetNatNumModifier( sal_uInt8 n ) { nNatNumModifier = n; } 170 GetNumberformatter()171 SvNumberFormatter* GetNumberformatter() { return pFormatter; } // Access to formatter (for zformat.cxx) 172 173 /// Get type scanned (so far). GetScannedType() const174 SvNumFormatType GetScannedType() const { return eScannedType; } 175 176 private: // Private section 177 NfKeywordTable sKeyword; // Syntax keywords 178 static const NfKeywordTable sEnglishKeyword; // English Syntax keywords 179 static ::std::vector<Color> StandardColor; // Standard color array 180 static bool bStandardColorNeedInitialization; // initialize Standard color array 181 static ::std::vector<OUString> sGermanColorNames; // German color names array 182 Date maNullDate; // 30Dec1899 183 OUString sNameStandardFormat; // "Standard" 184 sal_uInt16 nStandardPrec; // Default Precision for Standardformat 185 SvNumberFormatter* pFormatter; // Pointer to the FormatList 186 css::uno::Reference< css::i18n::XNumberFormatCode > xNFC; 187 188 OUString sStrArray[NF_MAX_FORMAT_SYMBOLS]; // Array of symbols 189 short nTypeArray[NF_MAX_FORMAT_SYMBOLS]; // Array of infos 190 // External Infos: 191 sal_uInt16 nResultStringsCnt; // Result symbol count 192 SvNumFormatType eScannedType; // Type according to scan 193 bool bThousand; // With thousands marker 194 sal_uInt16 nThousand; // Counts ... series 195 sal_uInt16 nCntPre; // Counts digits of integral part 196 sal_uInt16 nCntPost; // Counts digits of fractional part 197 sal_uInt16 nCntExp; // Counts exponent digits AM/PM 198 // Internal info: 199 sal_uInt16 nStringsCnt; // Symbol count 200 sal_uInt16 nExpPos; // Internal position of E 201 sal_uInt16 nBlankPos; // Internal position of the Blank 202 short nDecPos; // Internal position of the , 203 bool bExp; // Set when reading E 204 bool bFrac; // Set when reading / 205 bool bBlank; // Set when reading ' ' (Fraction) 206 bool bDecSep; // Set on first , 207 mutable bool bKeywordsNeedInit; // Locale dependent keywords need to be initialized 208 mutable bool bCompatCurNeedInit; // Locale dependent compatibility currency need to be initialized 209 OUString sCurSymbol; // Currency symbol for compatibility format codes 210 OUString sCurString; // Currency symbol in upper case 211 OUString sCurAbbrev; // Currency abbreviation 212 OUString sBooleanEquivalent1; // "TRUE";"TRUE";"FALSE" 213 OUString sBooleanEquivalent2; // [>0]"TRUE";[<0]"TRUE";"FALSE" 214 static const OUString sErrStr; // String for error output 215 216 bool bConvertMode; // Set in the convert mode 217 bool mbConvertDateOrder; // Set in the convert mode whether to convert date particles order 218 219 LanguageType eNewLnge; // Language/country which the scanned string is converted to (for Excel filter) 220 LanguageType eTmpLnge; // Language/country which the scanned string is converted from (for Excel filter) 221 222 bool bConvertSystemToSystem; // Whether the conversion is from one system locale to another system locale 223 // (in this case the automatic currency symbol is converted too). 224 225 sal_Int32 nCurrPos; // Position of currency symbol 226 227 sal_uInt8 nNatNumModifier; // Thai T speciality 228 229 KeywordLocalization meKeywordLocalization; ///< which keywords localization to scan 230 231 // Copy assignment is forbidden and not implemented. 232 ImpSvNumberformatScan (const ImpSvNumberformatScan &) = delete; 233 ImpSvNumberformatScan & operator= (const ImpSvNumberformatScan &) = delete; 234 235 void InitKeywords() const; 236 void InitSpecialKeyword( NfKeywordIndex eIdx ) const; 237 void InitCompatCur() const; 238 239 void SetDependentKeywords(); 240 // Sets the language dependent keywords 241 void SkipStrings(sal_uInt16& i, sal_Int32& nPos) const;// Skips StringSymbols 242 sal_uInt16 PreviousKeyword(sal_uInt16 i) const; // Returns index of the preceding one 243 // Keyword or 0 244 sal_uInt16 NextKeyword(sal_uInt16 i) const; // Returns index of the next one 245 // Keyword or 0 246 sal_Unicode PreviousChar(sal_uInt16 i) const; // Returns last char before index skips EMPTY, STRING, STAR, BLANK 247 sal_Unicode NextChar(sal_uInt16 i) const; // Returns first following char 248 short PreviousType( sal_uInt16 i ) const; // Returns type before position skips EMPTY 249 bool IsLastBlankBeforeFrac(sal_uInt16 i) const; // True <=> there won't be a ' ' until the '/' 250 void Reset(); // Reset all variables before starting the analysis 251 252 /** Determine keyword at nPos. 253 @param rbFoundEnglish set if English instead of locale's keyword 254 found, never cleared, thus init with false. 255 @return 0 if not found, else keyword enumeration. 256 */ 257 short GetKeyWord( const OUString& sSymbol, 258 sal_Int32 nPos, 259 bool& rbFoundEnglish ) const; 260 IsAmbiguousE(short nKey) const261 bool IsAmbiguousE( short nKey ) const // whether nKey is ambiguous E of NF_KEY_E/NF_KEY_EC 262 { 263 return (nKey == NF_KEY_EC || nKey == NF_KEY_E) && 264 (GetKeywords()[NF_KEY_EC] == GetKeywords()[NF_KEY_E]); 265 } 266 267 // if 0 at strArray[i] is of S,00 or SS,00 or SS"any"00 in ScanType() or FinalScan() 268 bool Is100SecZero( sal_uInt16 i, bool bHadDecSep ) const; 269 270 short Next_Symbol(const OUString& rStr, 271 sal_Int32& nPos, 272 OUString& sSymbol) const; // Next Symbol 273 sal_Int32 Symbol_Division(const OUString& rString);// Initial lexical scan 274 sal_Int32 ScanType(); // Analysis of the Format type 275 sal_Int32 FinalScan( OUString& rString ); // Final analysis with supplied type 276 277 // -1:= error, return nPos in FinalScan; 0:= no calendar, 1:= calendar found 278 int FinalScanGetCalendar( sal_Int32& nPos, sal_uInt16& i, sal_uInt16& nResultStringsCnt ); 279 280 /** Insert symbol into nTypeArray and sStrArray, e.g. grouping separator. 281 If at nPos-1 a symbol type NF_SYMBOLTYPE_EMPTY is present, that is 282 reused instead of shifting all one up and nPos is decremented! */ 283 bool InsertSymbol( sal_uInt16 & nPos, svt::NfSymbolType eType, const OUString& rStr ); 284 285 /** Whether two key symbols are adjacent separated by date separator. 286 This can only be used at the end of FinalScan() after 287 NF_SYMBOLTYPE_DATESEP has already been set. 288 */ 289 bool IsDateFragment( size_t nPos1, size_t nPos2 ) const; 290 291 /** Swap nTypeArray and sStrArray elements at positions. */ 292 void SwapArrayElements( size_t nPos1, size_t nPos2 ); 293 StringEqualsChar(const OUString & rStr,sal_Unicode ch)294 static bool StringEqualsChar( const OUString& rStr, sal_Unicode ch ) 295 { return rStr.getLength() == 1 && rStr[0] == ch; } 296 297 // remove "..." and \... quotes from rStr, return how many chars removed 298 static sal_Int32 RemoveQuotes( OUString& rStr ); 299 }; 300 301 #endif // INCLUDED_SVL_SOURCE_NUMBERS_ZFORSCAN_HXX 302 303 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 304