diff options
Diffstat (limited to 'include/svl/zforlist.hxx')
-rw-r--r-- | include/svl/zforlist.hxx | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/include/svl/zforlist.hxx b/include/svl/zforlist.hxx new file mode 100644 index 000000000..4159ce0fb --- /dev/null +++ b/include/svl/zforlist.hxx @@ -0,0 +1,381 @@ +/* -*- 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_ZFORLIST_HXX +#define INCLUDED_SVL_ZFORLIST_HXX + +#include <config_options.h> +#include <svl/svldllapi.h> +#include <rtl/ustrbuf.hxx> +#include <rtl/ustring.hxx> +#include <o3tl/typed_flags_set.hxx> +#include <i18nlangtag/lang.h> +#include <com/sun/star/util/NumberFormat.hpp> +#include <unotools/localedatawrapper.hxx> + +#include <map> +#include <unordered_map> + +namespace com::sun::star::i18n { struct Currency; } + +class SvNumberformat; + +#define SV_COUNTRY_LANGUAGE_OFFSET 10000 // Max count of formats per country/language +#define SV_MAX_COUNT_STANDARD_FORMATS 100 // Max count of builtin default formats per CL + +constexpr size_t NF_MAX_FORMAT_SYMBOLS = 100; + +/// The built-in @ Text format, offset within a locale, key in the locale the +/// number formatter was constructed with. +constexpr sal_uInt32 NF_STANDARD_FORMAT_TEXT = SV_MAX_COUNT_STANDARD_FORMATS; + +constexpr sal_uInt32 NUMBERFORMAT_ENTRY_NOT_FOUND = 0xffffffff; /// MAX_ULONG + +enum class SvNumFormatType : sal_Int16 +{ + /** selects all number formats. + */ + ALL = css::util::NumberFormat::ALL, // 0 + /** selects only user-defined number formats. + */ + DEFINED = css::util::NumberFormat::DEFINED, // 1 + /** selects date formats. + */ + DATE = css::util::NumberFormat::DATE, // 2 + /** selects time formats. + */ + TIME = css::util::NumberFormat::TIME, // 4 + /** selects currency formats. + */ + CURRENCY = css::util::NumberFormat::CURRENCY, // 8 + /** selects decimal number formats. + */ + NUMBER = css::util::NumberFormat::NUMBER, // 16 + /** selects scientific number formats. + */ + SCIENTIFIC = css::util::NumberFormat::SCIENTIFIC, // 32 + /** selects number formats for fractions. + */ + FRACTION = css::util::NumberFormat::FRACTION, // 64 + /** selects percentage number formats. + */ + PERCENT = css::util::NumberFormat::PERCENT, // 128 + /** selects text number formats. + */ + TEXT = css::util::NumberFormat::TEXT, // 256 + /** selects number formats which contain date and time. + */ + DATETIME = DATE | TIME, // 6 + /** selects boolean number formats. + */ + LOGICAL = css::util::NumberFormat::LOGICAL, // 1024 + /** is used as a return value if no format exists. + */ + UNDEFINED = css::util::NumberFormat::UNDEFINED, // 2048 + /** @internal is used to flag an empty sub format. + @since LibreOffice 5.1 + */ + EMPTY = css::util::NumberFormat::EMPTY, // 4096 + /** @internal selects a time duration format. + 8192 + TIME (4) + @since LibreOffice 6.2 + */ + DURATION = css::util::NumberFormat::DURATION, // 8196 +}; +namespace o3tl { + template<> struct typed_flags<SvNumFormatType> : is_typed_flags<SvNumFormatType, 0x3dff> {}; +} + +/** enum values for <method>SvNumberFormatter::GetFormatIndex</method> + + <p> + Builtin standard formats, order should be also the arrangement in the + dialog list box representation.</p> + + <p> + Date specials:<ul> + <li>SYSTEM: As set in System Regional Settings. + <li>SYS: short/long defined, order and separators from System Regional Settings. + <li>DEF: short/long and order defined, separators from System Regional Settings. + <li>DIN: all settings hard coded as DIN (Deutsche Industrie Norm) and EN (European Norm) require. + <li>all other: hard coded + </ul> + + Do NOT insert any new values! + The values here correspond with those in offapi/com/sun/star/i18n/NumberFormatIndex.idl + You may append values though after NF_INDEX_TABLE_LOCALE_DATA_DEFAULTS. + */ +enum NfIndexTableOffset +{ + NF_NUMERIC_START = 0, + + NF_NUMBER_START = NF_NUMERIC_START, + NF_NUMBER_STANDARD = NF_NUMBER_START, // Standard/General + NF_NUMBER_INT, // 0 + NF_NUMBER_DEC2, // 0.00 + NF_NUMBER_1000INT, // #,##0 + NF_NUMBER_1000DEC2, // #,##0.00 + NF_NUMBER_SYSTEM, // #,##0.00 or whatever is set in System Regional Settings + NF_NUMBER_END = NF_NUMBER_SYSTEM, + + NF_SCIENTIFIC_START, + NF_SCIENTIFIC_000E000 = NF_SCIENTIFIC_START, // 0.00E+000 + NF_SCIENTIFIC_000E00, // 0.00E+00 + NF_SCIENTIFIC_END = NF_SCIENTIFIC_000E00, + + NF_PERCENT_START, + NF_PERCENT_INT = NF_PERCENT_START, // 0% + NF_PERCENT_DEC2, // 0.00% + NF_PERCENT_END = NF_PERCENT_DEC2, + + NF_FRACTION_START, + NF_FRACTION_1D = NF_FRACTION_START, // # ?/? + NF_FRACTION_2D, // # ??/?? + NF_FRACTION_END = NF_FRACTION_2D, + + NF_NUMERIC_END = NF_FRACTION_END, + + NF_CURRENCY_START, + NF_CURRENCY_1000INT = NF_CURRENCY_START,// #,##0 DM + NF_CURRENCY_1000DEC2, // #,##0.00 DM + NF_CURRENCY_1000INT_RED, // #,##0 DM negative in red + NF_CURRENCY_1000DEC2_RED, // #,##0.00 DM negative in red + NF_CURRENCY_1000DEC2_CCC, // #,##0.00 DEM currency abbreviation + NF_CURRENCY_1000DEC2_DASHED, // #,##0.-- DM + NF_CURRENCY_END = NF_CURRENCY_1000DEC2_DASHED, + + NF_DATE_START, + NF_DATE_SYSTEM_SHORT = NF_DATE_START, // 08.10.97 + NF_DATE_SYSTEM_LONG, // Wednesday, 8. October 1997 + NF_DATE_SYS_DDMMYY, // 08.10.97 + NF_DATE_SYS_DDMMYYYY, // 08.10.1997 THE edit format, formatindex="21" + NF_DATE_SYS_DMMMYY, // 8. Oct 97 + NF_DATE_SYS_DMMMYYYY, // 8. Oct 1997 + NF_DATE_DIN_DMMMYYYY, // 8. Oct. 1997 DIN + NF_DATE_SYS_DMMMMYYYY, // 8. October 1997 + NF_DATE_DIN_DMMMMYYYY, // 8. October 1997 DIN + NF_DATE_SYS_NNDMMMYY, // Wed, 8. Okt 97 + NF_DATE_DEF_NNDDMMMYY, // Wed 08.Okt 97 + NF_DATE_SYS_NNDMMMMYYYY, // Wed, 8. Oktober 1997 + NF_DATE_SYS_NNNNDMMMMYYYY, // Wednesday, 8. Oktober 1997 + NF_DATE_DIN_MMDD, // 10-08 DIN + NF_DATE_DIN_YYMMDD, // 97-10-08 DIN + NF_DATE_DIN_YYYYMMDD, // 1997-10-08 DIN + NF_DATE_ISO_YYYYMMDD = NF_DATE_DIN_YYYYMMDD, // 1997-10-08 ISO clarify with name, formatindex="33" + NF_DATE_SYS_MMYY, // 10.97 + NF_DATE_SYS_DDMMM, // 08.Oct + NF_DATE_MMMM, // October + NF_DATE_QQJJ, // 4. Quarter 97 + NF_DATE_WW, // week of year + NF_DATE_END = NF_DATE_WW, + + NF_TIME_START, + NF_TIME_HHMM = NF_TIME_START, // HH:MM + NF_TIME_HHMMSS, // HH:MM:SS + NF_TIME_HHMMAMPM, // HH:MM AM/PM + NF_TIME_HHMMSSAMPM, // HH:MM:SS AM/PM + NF_TIME_HH_MMSS, // [HH]:MM:SS formatindex="43" + NF_TIME_MMSS00, // MM:SS,00 formatindex="44" + NF_TIME_HH_MMSS00, // [HH]:MM:SS,00 formatindex="45" + NF_TIME_END = NF_TIME_HH_MMSS00, + + NF_DATETIME_START, + NF_DATETIME_SYSTEM_SHORT_HHMM = NF_DATETIME_START, // 08.10.97 01:23 + NF_DATETIME_SYS_DDMMYYYY_HHMMSS, // 08.10.1997 01:23:45 THE edit format, formatindex="47" + NF_DATETIME_END = NF_DATETIME_SYS_DDMMYYYY_HHMMSS, + + NF_BOOLEAN, // BOOLEAN + NF_TEXT, // @ + + NF_INDEX_TABLE_LOCALE_DATA_DEFAULTS, // == 50, old number of predefined entries, i18npool locale data additions start after this + + // From here on are values of new predefined and built-in formats that are + // not in the original NumberFormatIndex.idl + + // XXX Values appended here must also get a corresponding entry in + // svl/source/numbers/zforlist.cxx indexTable[] in the same order. + + // XXX The dialog's number format shell assumes start/end spans + // (NF_..._START and NF_..._END above) to fill its categories with builtin + // formats, make new formats known to svx/source/items/numfmtsh.cxx + // SvxNumberFormatShell::FillEListWithStd_Impl(), otherwise they will not + // be listed at all. Yes that is ugly. + // DATETIME formats need to be added to + // SvxNumberFormatShell::FillEListWithDateTime_Impl(). + + // New predefined format added to i18npool locale data. + NF_DATETIME_SYS_DDMMYYYY_HHMM = NF_INDEX_TABLE_LOCALE_DATA_DEFAULTS, // 08.10.1997 01:23 formatindex="50" + + // No i18npool defined locale data between here and NF_INDEX_TABLE_ENTRIES. + NF_INDEX_TABLE_RESERVED_START, + + NF_FRACTION_3D = NF_INDEX_TABLE_RESERVED_START, // # ???/??? + NF_FRACTION_2, // # ?/2 + NF_FRACTION_4, // # ?/4 + NF_FRACTION_8, // # ?/8 + NF_FRACTION_16, // # ??/16 + NF_FRACTION_10, // # ??/10 + NF_FRACTION_100, // # ??/100 + + NF_DATETIME_ISO_YYYYMMDD_HHMMSS, // 1997-10-08 01:23:45 ISO (with blank instead of T) + NF_DATETIME_ISO_YYYYMMDD_HHMMSS000, // 1997-10-08 01:23:45.678 not quite ISO with locale's separator + NF_DATETIME_ISO_YYYYMMDDTHHMMSS, // 1997-10-08T01:23:45 ISO + NF_DATETIME_ISO_YYYYMMDDTHHMMSS000, // 1997-10-08T01:23:45,678 ISO with milliseconds and ',' or '.' + + // XXX When adding values here, follow the comment above about + // svx/source/items/numfmtsh.cxx + + NF_INDEX_TABLE_ENTRIES // == 62, reserved to not be used in i18npool locale data. + + // XXX Adding values above may increment the reserved area that can't be + // used by i18npool's locale data FormatCode definitions, see the + // description at i18npool/source/localedata/data/locale.dtd for ELEMENT + // FormatCode what the current convention's value is. In that case, the + // used formatIndex values in i18npool/source/localedata/data/*.xml will + // have to be adjusted. + // Overlapping the area will bail out with a check in + // SvNumberFormatter::ImpInsertFormat() in debug builds. +}; + + +// #45717# IsNumberFormat( "98-10-24", 30, x ), YMD Format set with DMY +// International settings doesn't recognize the string as a date. +/** enum values for <method>SvNumberFormatter::SetEvalDateFormat</method> + + <p>How <method>ImpSvNumberInputScan::GetDateRef</method> shall take the + DateFormat order (YMD,DMY,MDY) into account, if called from IsNumberFormat + with a date format to match against. + */ +enum NfEvalDateFormat +{ + /** DateFormat only from International, default. */ + NF_EVALDATEFORMAT_INTL, + + /** DateFormat only from date format passed to function (if any). + If no date format is passed then the DateFormat is taken from International. */ + NF_EVALDATEFORMAT_FORMAT, + + /** First try the DateFormat from International. If it doesn't match a + valid date try the DateFormat from the date format passed. */ + NF_EVALDATEFORMAT_INTL_FORMAT, + + /** First try the DateFormat from the date format passed. If it doesn't + match a valid date try the DateFormat from International. */ + NF_EVALDATEFORMAT_FORMAT_INTL +}; + + +/// This table is std::map because it needs to preserve insertion order, +/// because the formats are roughly ordered from most to least common, and some +/// parts of the UI want to show them in that order. +typedef std::map<sal_uInt32, SvNumberformat*> SvNumberFormatTable; +typedef std::unordered_map<sal_uInt16, sal_uInt32> SvNumberFormatterIndexTable; +typedef std::unordered_map< sal_uInt32, sal_uInt32> SvNumberFormatterMergeMap; + + +/** Language/country dependent currency entries + */ +class UNLESS_MERGELIBS(SVL_DLLPUBLIC) NfCurrencyEntry final +{ + OUString aSymbol; /// currency symbol + OUString aBankSymbol; /// currency abbreviation + LanguageType eLanguage; /// language/country value + sal_uInt16 nPositiveFormat; /// position of symbol + sal_uInt16 nNegativeFormat; /// position of symbol and type and position of negative sign + sal_uInt16 nDigits; /// count of decimal digits + sal_Unicode cZeroChar; /// which character is used for zeros as last decimal digits + +private: + + // nDecimalFormat := 0, 1, 2 + // #,##0 or #,##0.00 or #,##0.-- is returned + SVL_DLLPRIVATE OUString Impl_BuildFormatStringNumChars( const LocaleDataWrapper&, sal_uInt16 nDecimalFormat) const; + +public: + + NfCurrencyEntry( const LocaleDataWrapper& rLocaleData, + LanguageType eLang ); + NfCurrencyEntry( const css::i18n::Currency & rCurr, + const LocaleDataWrapper& rLocaleData, + LanguageType eLang ); + + /// Symbols and language identical + bool operator==( const NfCurrencyEntry& r ) const; + + const OUString& GetSymbol() const { return aSymbol; } + const OUString& GetBankSymbol() const { return aBankSymbol; } + LanguageType GetLanguage() const { return eLanguage; } + sal_uInt16 GetPositiveFormat() const { return nPositiveFormat; } + sal_uInt16 GetNegativeFormat() const { return nNegativeFormat; } + sal_uInt16 GetDigits() const { return nDigits; } + + /** Only to resolve system locale for currency list. */ + void SetLanguage( LanguageType nLang ) { eLanguage = nLang; } + + /** [$DM-407] (bBank==false) or [$DEM] (bBank==true) + is returned. If bBank==false and + bWithoutExtension==true only [$DM] */ + OUString BuildSymbolString(bool bBank, bool bWithoutExtension = false) const; + + /** #,##0.00 [$DM-407] is returned, separators + from rLoc, incl. minus sign but without [RED] */ + OUString BuildPositiveFormatString(bool bBank, const LocaleDataWrapper&, + sal_uInt16 nDecimalFormat = 1) const; + OUString BuildNegativeFormatString(bool bBank, const LocaleDataWrapper&, + sal_uInt16 nDecimalFormat = 1) const; + + /** [$DM-407] (or [$DEM] if bBank==true) + is appended/prepended to rStr, incl. minus sign */ + void CompletePositiveFormatString(OUStringBuffer& rStr, bool bBank, + sal_uInt16 nPosiFormat) const; + void CompleteNegativeFormatString(OUStringBuffer& rStr, bool bBank, + sal_uInt16 nNegaFormat) const; + + /// rSymStr is appended/prepended to rStr, incl. minus sign + static void CompletePositiveFormatString(OUStringBuffer& rStr, + std::u16string_view rSymStr, sal_uInt16 nPosiFormat); + static void CompleteNegativeFormatString(OUStringBuffer& rStr, + std::u16string_view rSymStr, sal_uInt16 nNegaFormat); + + /** Representation of a currency (symbol position and + negative sign) in other language settings */ + static sal_uInt16 GetEffectivePositiveFormat( sal_uInt16 nIntlFormat, + sal_uInt16 nCurrFormat, bool bBank ); + static sal_uInt16 GetEffectiveNegativeFormat( sal_uInt16 nIntlFormat, + sal_uInt16 nCurrFormat, bool bBank ); + + /// General Unicode Euro symbol + static sal_Unicode GetEuroSymbol() { return u'\x20AC'; } +}; + +typedef std::vector< OUString > NfWSStringsDtor; + +/** Input options to be used with IsNumberFormat() */ +enum class SvNumInputOptions : sal_uInt16 +{ + NONE = 0, + LAX_TIME = 1 ///< allow input of minutes or seconds >59 +}; +namespace o3tl { + template<> struct typed_flags<SvNumInputOptions> : is_typed_flags<SvNumInputOptions, 0x0001> {}; +} + + +#endif // INCLUDED_SVL_ZFORLIST_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |