diff options
Diffstat (limited to 'svl/source/numbers/zforscan.hxx')
-rw-r--r-- | svl/source/numbers/zforscan.hxx | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/svl/source/numbers/zforscan.hxx b/svl/source/numbers/zforscan.hxx new file mode 100644 index 000000000..4e6f7d145 --- /dev/null +++ b/svl/source/numbers/zforscan.hxx @@ -0,0 +1,304 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_SVL_SOURCE_NUMBERS_ZFORSCAN_HXX +#define INCLUDED_SVL_SOURCE_NUMBERS_ZFORSCAN_HXX + +#include <i18nlangtag/lang.h> +#include <rtl/ustring.hxx> +#include <svl/nfkeytab.hxx> +#include <svl/nfsymbol.hxx> +#include <svl/numformat.hxx> +#include <svl/zforlist.hxx> +#include <tools/color.hxx> +#include <tools/date.hxx> +#include <unotools/localedatawrapper.hxx> + +class SvNumberFormatter; +struct ImpSvNumberformatInfo; + + +const size_t NF_MAX_DEFAULT_COLORS = 10; + +// Hack: nThousand==1000 => "Default" occurs in format string +const sal_uInt16 FLAG_STANDARD_IN_FORMAT = 1000; + +class ImpSvNumberformatScan +{ +public: + + /** Specify what keyword localization is allowed when scanning the format code. */ + enum class KeywordLocalization + { + LocaleLegacy, ///< unfortunately localized in few locales, otherwise English + EnglishOnly, ///< only English, no localized keywords + AllowEnglish ///< allow English keywords as well as localized keywords + }; + + explicit ImpSvNumberformatScan( SvNumberFormatter* pFormatter ); + ~ImpSvNumberformatScan(); + void ChangeIntl( KeywordLocalization eKeywordLocalization = KeywordLocalization::AllowEnglish ); // Replaces Keywords + + void ChangeNullDate(sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear); // Replaces reference date + void ChangeStandardPrec(sal_uInt16 nPrec); // Replaces standard precision + + sal_Int32 ScanFormat( OUString& rString ); // Call scan analysis + + void CopyInfo(ImpSvNumberformatInfo* pInfo, + sal_uInt16 nCnt); // Copies the FormatInfo + sal_uInt16 GetResultStringsCnt() const { return nResultStringsCnt; } + + const CharClass& GetChrCls() const { return *pFormatter->GetCharClass(); } + const LocaleDataWrapper& GetLoc() const { return *pFormatter->GetLocaleData(); } + CalendarWrapper& GetCal() const { return *pFormatter->GetCalendar(); } + + const NfKeywordTable & GetKeywords() const + { + if ( bKeywordsNeedInit ) + { + InitKeywords(); + } + return sKeyword; + } + + static const NfKeywordTable & GetEnglishKeywords() + { + return sEnglishKeyword; + } + + // Keywords used in output like true and false + const OUString& GetSpecialKeyword( NfKeywordIndex eIdx ) const + { + if ( sKeyword[eIdx].isEmpty() ) + { + InitSpecialKeyword( eIdx ); + } + return sKeyword[eIdx]; + } + const OUString& GetTrueString() const { return GetSpecialKeyword( NF_KEY_TRUE ); } + const OUString& GetFalseString() const { return GetSpecialKeyword( NF_KEY_FALSE ); } + const OUString& GetRedString() const { return GetKeywords()[NF_KEY_RED]; } + const OUString& GetBooleanString() const { return GetKeywords()[NF_KEY_BOOLEAN]; } + static const ::std::vector<Color> & GetStandardColors() + { + return StandardColor; + } + static size_t GetMaxDefaultColors() + { + return NF_MAX_DEFAULT_COLORS; + } + + const Date& GetNullDate() const { return maNullDate; } + const OUString& GetStandardName() const + { + if ( bKeywordsNeedInit ) + { + InitKeywords(); + } + return sNameStandardFormat; + } + sal_uInt16 GetStandardPrec() const { return nStandardPrec; } + static const Color& GetRedColor() { return StandardColor[4]; } + const Color* GetColor(OUString& sStr) const; // Set main colors or defines colors + + // the compatibility currency symbol for old automatic currency formats + const OUString& GetCurSymbol() const + { + if ( bCompatCurNeedInit ) + { + InitCompatCur(); + } + return sCurSymbol; + } + + // the compatibility currency abbreviation for CCC format code + const OUString& GetCurAbbrev() const + { + if ( bCompatCurNeedInit ) + { + InitCompatCur(); + } + return sCurAbbrev; + } + + // the compatibility currency symbol upper case for old automatic currency formats + const OUString& GetCurString() const + { + if ( bCompatCurNeedInit ) + { + InitCompatCur(); + } + return sCurString; + } + + /// Replace Boolean equivalent format codes with proper Boolean format. + bool ReplaceBooleanEquivalent( OUString& rString ); + + void SetConvertMode(LanguageType eTmpLge, LanguageType eNewLge, + bool bSystemToSystem, bool bConvertDateOrder) + { + bConvertMode = true; + eNewLnge = eNewLge; + eTmpLnge = eTmpLge; + bConvertSystemToSystem = bSystemToSystem; + mbConvertDateOrder = bConvertDateOrder; + } + // Only changes the bool variable, in order to temporarily pause the convert mode + void SetConvertMode(bool bMode) { bConvertMode = bMode; } + bool GetConvertMode() const { return bConvertMode; } + LanguageType GetNewLnge() const { return eNewLnge; } // Read access on ConvertMode and convert country/language + LanguageType GetTmpLnge() const { return eTmpLnge; } // Read access on StartCountry/Language + void SetNewLnge( LanguageType e ) { eNewLnge = e; } // Set new convert country/language + + /// get Thai T speciality + sal_uInt8 GetNatNumModifier() const { return nNatNumModifier; } + /// set Thai T speciality + void SetNatNumModifier( sal_uInt8 n ) { nNatNumModifier = n; } + + SvNumberFormatter* GetNumberformatter() { return pFormatter; } // Access to formatter (for zformat.cxx) + + /// Get type scanned (so far). + SvNumFormatType GetScannedType() const { return eScannedType; } + + static constexpr OUStringLiteral sErrStr = u"#FMT"; // String for error output + +private: // Private section + NfKeywordTable sKeyword; // Syntax keywords + static const NfKeywordTable sEnglishKeyword; // English Syntax keywords + static const ::std::vector<Color> StandardColor; // Standard color array + Date maNullDate; // 30Dec1899 + OUString sNameStandardFormat; // "Standard" + sal_uInt16 nStandardPrec; // Default Precision for Standardformat + SvNumberFormatter* pFormatter; // Pointer to the FormatList + css::uno::Reference< css::i18n::XNumberFormatCode > xNFC; + + OUString sStrArray[NF_MAX_FORMAT_SYMBOLS]; // Array of symbols + short nTypeArray[NF_MAX_FORMAT_SYMBOLS]; // Array of infos + // External Infos: + sal_uInt16 nResultStringsCnt; // Result symbol count + SvNumFormatType eScannedType; // Type according to scan + bool bThousand; // With thousands marker + sal_uInt16 nThousand; // Counts ... series + sal_uInt16 nCntPre; // Counts digits of integral part + sal_uInt16 nCntPost; // Counts digits of fractional part + sal_uInt16 nCntExp; // Counts exponent digits AM/PM + // Internal info: + sal_uInt16 nStringsCnt; // Symbol count + sal_uInt16 nExpPos; // Internal position of E + sal_uInt16 nBlankPos; // Internal position of the Blank + short nDecPos; // Internal position of the , + bool bExp; // Set when reading E + bool bFrac; // Set when reading / + bool bBlank; // Set when reading ' ' (Fraction) + bool bDecSep; // Set on first , + mutable bool bKeywordsNeedInit; // Locale dependent keywords need to be initialized + mutable bool bCompatCurNeedInit; // Locale dependent compatibility currency need to be initialized + OUString sCurSymbol; // Currency symbol for compatibility format codes + OUString sCurString; // Currency symbol in upper case + OUString sCurAbbrev; // Currency abbreviation + OUString sBooleanEquivalent1; // "TRUE";"TRUE";"FALSE" + OUString sBooleanEquivalent2; // [>0]"TRUE";[<0]"TRUE";"FALSE" + + bool bConvertMode; // Set in the convert mode + bool mbConvertDateOrder; // Set in the convert mode whether to convert date particles order + + LanguageType eNewLnge; // Language/country which the scanned string is converted to (for Excel filter) + LanguageType eTmpLnge; // Language/country which the scanned string is converted from (for Excel filter) + + bool bConvertSystemToSystem; // Whether the conversion is from one system locale to another system locale + // (in this case the automatic currency symbol is converted too). + + sal_Int32 nCurrPos; // Position of currency symbol + + sal_uInt8 nNatNumModifier; // Thai T speciality + + KeywordLocalization meKeywordLocalization; ///< which keywords localization to scan + + // Copy assignment is forbidden and not implemented. + ImpSvNumberformatScan (const ImpSvNumberformatScan &) = delete; + ImpSvNumberformatScan & operator= (const ImpSvNumberformatScan &) = delete; + + void InitKeywords() const; + void InitSpecialKeyword( NfKeywordIndex eIdx ) const; + void InitCompatCur() const; + + void SetDependentKeywords(); + // Sets the language dependent keywords + void SkipStrings(sal_uInt16& i, sal_Int32& nPos) const;// Skips StringSymbols + sal_uInt16 PreviousKeyword(sal_uInt16 i) const; // Returns index of the preceding one + // Keyword or 0 + sal_uInt16 NextKeyword(sal_uInt16 i) const; // Returns index of the next one + // Keyword or 0 + sal_Unicode PreviousChar(sal_uInt16 i) const; // Returns last char before index skips EMPTY, STRING, STAR, BLANK + sal_Unicode NextChar(sal_uInt16 i) const; // Returns first following char + short PreviousType( sal_uInt16 i ) const; // Returns type before position skips EMPTY + bool IsLastBlankBeforeFrac(sal_uInt16 i) const; // True <=> there won't be a ' ' until the '/' + void Reset(); // Reset all variables before starting the analysis + + /** Determine keyword at nPos. + @param rbFoundEnglish set if English instead of locale's keyword + found, never cleared, thus init with false. + @return 0 if not found, else keyword enumeration. + */ + short GetKeyWord( const OUString& sSymbol, + sal_Int32 nPos, + bool& rbFoundEnglish ) const; + + bool IsAmbiguousE( short nKey ) const // whether nKey is ambiguous E of NF_KEY_E/NF_KEY_EC + { + return (nKey == NF_KEY_EC || nKey == NF_KEY_E) && + (GetKeywords()[NF_KEY_EC] == GetKeywords()[NF_KEY_E]); + } + + // if 0 at strArray[i] is of S,00 or SS,00 or SS"any"00 in ScanType() or FinalScan() + bool Is100SecZero( sal_uInt16 i, bool bHadDecSep ) const; + + short Next_Symbol(const OUString& rStr, + sal_Int32& nPos, + OUString& sSymbol) const; // Next Symbol + sal_Int32 Symbol_Division(const OUString& rString);// Initial lexical scan + sal_Int32 ScanType(); // Analysis of the Format type + sal_Int32 FinalScan( OUString& rString ); // Final analysis with supplied type + + // -1:= error, return nPos in FinalScan; 0:= no calendar, 1:= calendar found + int FinalScanGetCalendar( sal_Int32& nPos, sal_uInt16& i, sal_uInt16& nResultStringsCnt ); + + /** Insert symbol into nTypeArray and sStrArray, e.g. grouping separator. + If at nPos-1 a symbol type NF_SYMBOLTYPE_EMPTY is present, that is + reused instead of shifting all one up and nPos is decremented! */ + bool InsertSymbol( sal_uInt16 & nPos, svt::NfSymbolType eType, const OUString& rStr ); + + /** Whether two key symbols are adjacent separated by date separator. + This can only be used at the end of FinalScan() after + NF_SYMBOLTYPE_DATESEP has already been set. + */ + bool IsDateFragment( size_t nPos1, size_t nPos2 ) const; + + /** Swap nTypeArray and sStrArray elements at positions. */ + void SwapArrayElements( size_t nPos1, size_t nPos2 ); + + static bool StringEqualsChar( const OUString& rStr, sal_Unicode ch ) + { return rStr.getLength() == 1 && rStr[0] == ch; } + + // remove "..." and \... quotes from rStr, return how many chars removed + static sal_Int32 RemoveQuotes( OUString& rStr ); +}; + +#endif // INCLUDED_SVL_SOURCE_NUMBERS_ZFORSCAN_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |