class ImpSvNumberformatScan; // format code string scanner class ImpSvNumberInputScan; // input string scanner class NativeNumberWrapper; class SvNFFormatData; class SvNumberFormatter;
struct ImpSvNumberformatInfo // Struct for FormatInfo
{
std::vector<OUString> sStrArray; // Array of symbols
std::vector<short> nTypeArray; // Array of infos
sal_uInt16 nThousand; // Count of group separator sequences
sal_uInt16 nCntPre; // Count of digits before decimal point
sal_uInt16 nCntPost; // Count of digits after decimal point
sal_uInt16 nCntExp; // Count of exponent digits, or AM/PM
SvNumFormatType eScannedType; // Type determined by scan bool bThousand; // Has group (AKA thousand) separator
// NativeNumber, represent numbers using CJK or other digits if nNum>0, // eLang specifies the Locale to use. class SvNumberNatNum
{
OUString sParams; // For [NatNum12 ordinal-number]-like syntax
LanguageType eLang;
sal_uInt8 nNum; bool bDBNum :1; // DBNum, to be converted to NatNum bool bDate :1; // Used in date? (needed for DBNum/NatNum mapping) bool bSet :1; // If set, since NatNum0 is possible
private:
ImpSvNumberformatInfo aI; // helper struct for remaining information
OUString sColorName; // color name const Color* pColor; // pointer to color of subformat
sal_uInt16 nStringsCnt; // count of symbols
SvNumberNatNum aNatNum; // DoubleByteNumber
};
class SVL_DLLPUBLIC SvNumberformat
{ struct SAL_DLLPRIVATE LocaleType
{ enumclass Substitute : sal_uInt8
{
NONE,
TIME,
LONGDATE
};
// Copy ctor with exchange of format code string scanner (used in merge)
SvNumberformat( SvNumberformat const & rFormat, ImpSvNumberformatScan& rSc );
~SvNumberformat();
/// Get type of format, may include css::util::NumberFormat::DEFINED bit
SvNumFormatType GetType() const { return eType; }
/// Get type of format, does not include css::util::NumberFormat::DEFINED
SvNumFormatType GetMaskedType() const { return eType & ~SvNumFormatType::DEFINED; }
void SetType(SvNumFormatType eSetType) { eType = eSetType; } // Standard means the I18N defined standard format of this type void SetStandard() { bStandard = true; } bool IsStandard() const { return bStandard; }
// If this format is an additional built-in format defined by i18n. void SetAdditionalBuiltin() { bAdditionalBuiltin = true; } bool IsAdditionalBuiltin() const { return bAdditionalBuiltin; }
/** If the format is a placeholder and needs to be substituted. */ bool IsSubstituted() const
{ return maLocale.meSubstitute != LocaleType::Substitute::NONE;
}
/** If the format is a placeholder for the system time format and needs to besubstitutedduringformattingtime.
*/ bool IsSystemTimeFormat() const
{ return maLocale.meSubstitute == LocaleType::Substitute::TIME && maLocale.meLanguage == LANGUAGE_SYSTEM;
}
/** If the format is a placeholder for the system long date format and needs tobesubstitutedduringformattingtime.
*/ bool IsSystemLongDateFormat() const
{ return maLocale.meSubstitute == LocaleType::Substitute::LONGDATE && maLocale.meLanguage == LANGUAGE_SYSTEM;
}
/** If the format is a MM:SS or [MM]:SS format, or MM:[SS] (sic!) or even MM:SS.00or[MM]:SS.00orMM:[SS].00
*/ bool IsMinuteSecondFormat() const;
//! Read/write access on a special sal_uInt16 component, may only be used on the //! standard format 0, 10000, ... and only by the number formatter! struct FormatterPrivateAccess { friend SvNumberFormatter; friend SvNFFormatData; private: FormatterPrivateAccess() {} };
sal_uInt16 GetLastInsertKey( const FormatterPrivateAccess& ) const
{ return NumFor[0].Info().nThousand; } void SetLastInsertKey( sal_uInt16 nKey, const FormatterPrivateAccess& )
{ NumFor[0].Info().nThousand = nKey; }
//! Only onLoad: convert from stored to current system language/country void ConvertLanguage( SvNumberFormatter& rConverter,
LanguageType eConvertFrom, LanguageType eConvertTo );
// Substring of a subformat code nNumFor (0..3) // nPos == 0xFFFF => last substring // bString==true: first/last SYMBOLTYPE_STRING or SYMBOLTYPE_CURRENCY const OUString* GetNumForString( sal_uInt16 nNumFor, sal_uInt16 nPos, bool bString = false ) const;
// Subtype of a subformat code nNumFor (0..3) // nPos == 0xFFFF => last substring short GetNumForType( sal_uInt16 nNumFor, sal_uInt16 nPos ) const;
/// Create a format string for time with a new precision
OUString GetFormatStringForTimePrecision( int nPrecision ) const;
/** If the count of string elements (substrings, ignoring [modifiers] and soon)inasubformatcodenNumFor(0..3)isequaltothegivennumber. UsedbyImpSvNumberInputScan::IsNumberFormatMain()todetectamatched
format. */ bool IsNumForStringElementCountEqual( sal_uInt16 nNumFor, sal_uInt16 nAllCount,
sal_uInt16 nNumCount ) const
{ if ( nNumFor < 4 )
{ // First try a simple approach. Note that this is called only // if all MidStrings did match so far, to verify that all // strings of the format were matched and not just the starting // sequence, so we don't have to check if GetCount() includes // [modifiers] or anything else if both counts are equal.
sal_uInt16 nCnt = NumFor[nNumFor].GetCount(); if ( nAllCount == nCnt ) returntrue; if ( nAllCount < nCnt ) // check ignoring [modifiers] and so on return ImpGetNumForStringElementCount( nNumFor ) ==
(nAllCount - nNumCount);
} returnfalse;
} /** Get the count of numbers among string elements **/
sal_uInt16 GetNumForNumberElementCount( sal_uInt16 nNumFor ) const;
/** Get the scanned type of the specified subformat. */
SvNumFormatType GetNumForInfoScannedType( sal_uInt16 nNumFor ) const
{ return (nNumFor < 4) ? NumFor[nNumFor].Info().eScannedType : SvNumFormatType::UNDEFINED;
}
// Whether the second subformat code is really for negative numbers // or another limit set. bool IsSecondSubformatRealNegative() const
{ return fLimit1 == 0.0 && fLimit2 == 0.0 &&
( (eOp1 == NUMBERFORMAT_OP_GE && eOp2 == NUMBERFORMAT_OP_NO) ||
(eOp1 == NUMBERFORMAT_OP_GT && eOp2 == NUMBERFORMAT_OP_LT) ||
(eOp1 == NUMBERFORMAT_OP_NO && eOp2 == NUMBERFORMAT_OP_NO) );
}
// Whether the negative format is without a sign or not bool IsNegativeWithoutSign() const;
bool IsNegativeInBracket() const;
bool HasPositiveBracketPlaceholder() const;
// Whether a new SYMBOLTYPE_CURRENCY is contained in the format bool HasNewCurrency() const;
// strip [$-yyy] from all [$xxx-yyy] leaving only xxx's, static OUString StripNewCurrencyDelimiters( const OUString& rStr );
// If a new SYMBOLTYPE_CURRENCY is contained if the format is of type // css::util::NumberFormat::CURRENCY, and if so the symbol xxx and the extension nnn // of [$xxx-nnn] are returned bool GetNewCurrencySymbol( OUString& rSymbol, OUString& rExtension ) const;
/** Insert the number of blanks into the string that is needed to simulate
the width of character c for underscore formats */ static sal_Int32 InsertBlanks( OUString& r, sal_Int32 nPos, sal_Unicode c )
{
sal_Int32 result;
OUStringBuffer sBuff(r);
result = InsertBlanks(sBuff, nPos, c);
r = sBuff.makeStringAndClear();
return result;
}
/** Insert the number of blanks into the string that is needed to simulate
the width of character c for underscore formats */ static sal_Int32 InsertBlanks( OUStringBuffer& r, sal_Int32 nPos, sal_Unicode c );
/// One of YMD,DMY,MDY if date format
DateOrder GetDateOrder() const;
/** A coded value of the exact YMD combination used, if date format. Forexample:YYYY-MM-DD=>('Y'<<16)|('M'<<8)|'D'
or: MM/YY => ('M' << 8) | 'Y' */
sal_uInt32 GetExactDateOrder() const;
// rAttr.Number not empty if NatNum attributes are to be stored void GetNatNumXml(
css::i18n::NativeNumberXmlAttributes2& rAttr,
sal_uInt16 nNumFor, const NativeNumberWrapper& rNatNum ) const; /** Return empty string if no NatNum modifier or invalid nNumFor
otherwise return "[NatNum1]" or "[NatNum12 ...]" */
OUString GetNatNumModifierString( sal_uInt16 nNumFor = 0 ) const;
/** Switches to the first non-"gregorian" calendar, but only if the current calendaris"gregorian";originalcalendarnameanddate/timereturned,
but only if calendar switched and rOrgCalendar was empty. */ void SwitchToOtherCalendar( OUString& rOrgCalendar, double& fOrgDateTime, CalendarWrapper& rCal ) const;
/** Switches to the "gregorian" calendar, but only if the current calendar isnon-"gregorian"andrOrgCalendarisnotempty.Thusapreceding ImpSwitchToOtherCalendar()callshouldhavebeenplacedpriorto
calling this method. */ void SwitchToGregorianCalendar( std::u16string_view rOrgCalendar, double fOrgDateTime, CalendarWrapper& rCal ) const;
#ifdef THE_FUTURE /** Switches to the first specified calendar, if any, in subformat nNumFor (0..3).Originalcalendarnameanddate/timereturned,butonlyif calendarswitchedandrOrgCalendarwasempty.
private:
ImpSvNumFor NumFor[4]; // Array for the 4 subformats
OUString sFormatstring; // The format code string
OUString sComment; // Comment, since number formatter version 6 double fLimit1; // Value for first condition double fLimit2; // Value for second condition
ImpSvNumberformatScan& rScan; // Format code scanner
LocaleType maLocale; // Language/country of the format, numeral shape and calendar type from Excel.
SvNumberformatLimitOps eOp1; // Operator for first condition
SvNumberformatLimitOps eOp2; // Operator for second condition
SvNumFormatType eType; // Type of format bool bAdditionalBuiltin; // If this is an additional built-in format defined by i18n bool bStandard; // If this is a default standard format bool bIsUsed; // Flag as used for storing
// Helper function for number strings // append string symbols, insert leading 0 or ' ', or ...
SVL_DLLPRIVATE bool ImpNumberFill( const NativeNumberWrapper& rNatNum,
OUStringBuffer& sStr, double& rNumber,
sal_Int32& k,
sal_uInt16& j,
sal_uInt16 nIx, short eSymbolType, bool bStarFlag, bool bInsertRightBlank = false ) const;
// Helper function to fill in the integer part and the group (AKA thousand) separators
SVL_DLLPRIVATE bool ImpNumberFillWithThousands( const NativeNumberWrapper& rNatNum,
OUStringBuffer& sStr, double& rNumber,
sal_Int32 k,
sal_uInt16 j,
sal_uInt16 nIx,
sal_Int32 nDigCnt, bool bStarFlag, bool bAddDecSep = true ) const;
// Helper function to fill in the group (AKA thousand) separators // or to skip additional digits
SVL_DLLPRIVATE void ImpDigitFill( OUStringBuffer& sStr,
sal_Int32 nStart,
sal_Int32& k,
sal_uInt16 nIx,
sal_Int32 & nDigitCount,
utl::DigitGroupingIterator & ) const;
// Switches to the "gregorian" calendar if the current calendar is // non-"gregorian" and the era is a "Dummy" era of a calendar which doesn't // know a "before" era (like zh_TW ROC or ja_JP Gengou). If switched and // rOrgCalendar was "gregorian" the string is emptied. If rOrgCalendar was // empty the previous calendar name and date/time are returned.
SVL_DLLPRIVATE bool ImpFallBackToGregorianCalendar(OUString& rOrgCalendar, double& fOrgDateTime,
CalendarWrapper& rCal) const;
// Append a "G" short era string of the given calendar. In the case of a // Gengou calendar this is a one character abbreviation, for other // calendars the XExtendedCalendar::getDisplayString() method is called.
SVL_DLLPRIVATE staticvoid ImpAppendEraG( OUStringBuffer& OutStringBuffer, const CalendarWrapper& rCal,
sal_Int16 nNatNum );
// Obtain the string of the fraction of second, without leading "0.", // rounded to nFractionDecimals (or nFractionDecimals+1 if // bAddOneRoundingDecimal==true but then truncated at nFractionDecimals, // for use with the result of tools::Time::GetClock()) with the length of // nFractionDecimals, unless nMinimumInputLineDecimals>0 is given for input // line string where extra trailing "0" are discarded.
SVL_DLLPRIVATE sal_uInt16 ImpGetFractionOfSecondString( OUStringBuffer& rBuf, double fFractionOfSecond, int nFractionDecimals, bool bAddOneRoundingDecimal, sal_uInt16 nIx, sal_uInt16 nMinimumInputLineDecimals, const NativeNumberWrapper& rNatNum) const;
// transliterate according to NativeNumber
SVL_DLLPRIVATE OUString impTransliterateImpl(const OUString& rStr, const SvNumberNatNum& rNum, sal_uInt16 nDateKey, const NativeNumberWrapper& rNatNum) const;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.