/* -*- 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 #include #include #include #include #include #include #include #include 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 & 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 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( std::u16string_view rStr, sal_Unicode ch ) { return rStr.size() == 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: */