139a19a47SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 339a19a47SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 439a19a47SAndrew Rist * or more contributor license agreements. See the NOTICE file 539a19a47SAndrew Rist * distributed with this work for additional information 639a19a47SAndrew Rist * regarding copyright ownership. The ASF licenses this file 739a19a47SAndrew Rist * to you under the Apache License, Version 2.0 (the 839a19a47SAndrew Rist * "License"); you may not use this file except in compliance 939a19a47SAndrew Rist * with the License. You may obtain a copy of the License at 1039a19a47SAndrew Rist * 1139a19a47SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 1239a19a47SAndrew Rist * 1339a19a47SAndrew Rist * Unless required by applicable law or agreed to in writing, 1439a19a47SAndrew Rist * software distributed under the License is distributed on an 1539a19a47SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 1639a19a47SAndrew Rist * KIND, either express or implied. See the License for the 1739a19a47SAndrew Rist * specific language governing permissions and limitations 1839a19a47SAndrew Rist * under the License. 1939a19a47SAndrew Rist * 2039a19a47SAndrew Rist *************************************************************/ 2139a19a47SAndrew Rist 2239a19a47SAndrew Rist 23cdf0e10cSrcweir #ifndef _ZFORMAT_HXX 24cdf0e10cSrcweir #define _ZFORMAT_HXX 25cdf0e10cSrcweir 26cdf0e10cSrcweir #include "svl/svldllapi.h" 27cdf0e10cSrcweir #include <tools/string.hxx> 28cdf0e10cSrcweir #include <i18npool/mslangid.hxx> 29cdf0e10cSrcweir #include <svl/zforlist.hxx> 30cdf0e10cSrcweir #include <svl/nfversi.hxx> 31cdf0e10cSrcweir #include <svl/nfkeytab.hxx> 32cdf0e10cSrcweir 33cdf0e10cSrcweir // We need ImpSvNumberformatScan for the private SvNumberformat definitions. 34cdf0e10cSrcweir #ifdef _ZFORMAT_CXX 35cdf0e10cSrcweir #include "zforscan.hxx" 36cdf0e10cSrcweir #endif 37cdf0e10cSrcweir 38cdf0e10cSrcweir // If comment field is also in format code string, was used for SUPD versions 371-372 39cdf0e10cSrcweir #define NF_COMMENT_IN_FORMATSTRING 0 40cdf0e10cSrcweir 41cdf0e10cSrcweir namespace utl { 42cdf0e10cSrcweir class DigitGroupingIterator; 43cdf0e10cSrcweir } 44cdf0e10cSrcweir 45cdf0e10cSrcweir class SvStream; 46cdf0e10cSrcweir class Color; 47cdf0e10cSrcweir 48cdf0e10cSrcweir class ImpSvNumberformatScan; // format code string scanner 49cdf0e10cSrcweir class ImpSvNumberInputScan; // input string scanner 50cdf0e10cSrcweir class ImpSvNumMultipleWriteHeader; // compatible file format 51cdf0e10cSrcweir class ImpSvNumMultipleReadHeader; // compatible file format 52cdf0e10cSrcweir class SvNumberFormatter; 53cdf0e10cSrcweir 54cdf0e10cSrcweir enum SvNumberformatLimitOps 55cdf0e10cSrcweir { 56cdf0e10cSrcweir NUMBERFORMAT_OP_NO = 0, // Undefined, no OP 57cdf0e10cSrcweir NUMBERFORMAT_OP_EQ = 1, // Operator = 58cdf0e10cSrcweir NUMBERFORMAT_OP_NE = 2, // Operator <> 59cdf0e10cSrcweir NUMBERFORMAT_OP_LT = 3, // Operator < 60cdf0e10cSrcweir NUMBERFORMAT_OP_LE = 4, // Operator <= 61cdf0e10cSrcweir NUMBERFORMAT_OP_GT = 5, // Operator > 62cdf0e10cSrcweir NUMBERFORMAT_OP_GE = 6 // Operator >= 63cdf0e10cSrcweir }; 64cdf0e10cSrcweir 65cdf0e10cSrcweir // SYSTEM-german to SYSTEM-xxx and vice versa conversion hack onLoad 66cdf0e10cSrcweir enum NfHackConversion 67cdf0e10cSrcweir { 68cdf0e10cSrcweir NF_CONVERT_NONE, 69cdf0e10cSrcweir NF_CONVERT_GERMAN_ENGLISH, 70cdf0e10cSrcweir NF_CONVERT_ENGLISH_GERMAN 71cdf0e10cSrcweir }; 72cdf0e10cSrcweir 73cdf0e10cSrcweir struct ImpSvNumberformatInfo // Struct for FormatInfo 74cdf0e10cSrcweir { 75cdf0e10cSrcweir String* sStrArray; // Array of symbols 76cdf0e10cSrcweir short* nTypeArray; // Array of infos 77cdf0e10cSrcweir sal_uInt16 nThousand; // Count of group separator sequences 78cdf0e10cSrcweir sal_uInt16 nCntPre; // Count of digits before decimal point 79cdf0e10cSrcweir sal_uInt16 nCntPost; // Count of digits after decimal point 80cdf0e10cSrcweir sal_uInt16 nCntExp; // Count of exponent digits, or AM/PM 81cdf0e10cSrcweir short eScannedType; // Type determined by scan 82cdf0e10cSrcweir sal_Bool bThousand; // Has group (AKA thousand) separator 83cdf0e10cSrcweir 84cdf0e10cSrcweir void Copy( const ImpSvNumberformatInfo& rNumFor, sal_uInt16 nAnz ); 85cdf0e10cSrcweir void Load(SvStream& rStream, sal_uInt16 nAnz); 86cdf0e10cSrcweir void Save(SvStream& rStream, sal_uInt16 nAnz) const; 87cdf0e10cSrcweir }; 88cdf0e10cSrcweir 89cdf0e10cSrcweir // NativeNumber, represent numbers using CJK or other digits if nNum>0, 90cdf0e10cSrcweir // eLang specifies the Locale to use. 91cdf0e10cSrcweir class SvNumberNatNum 92cdf0e10cSrcweir { 93cdf0e10cSrcweir LanguageType eLang; 94cdf0e10cSrcweir sal_uInt8 nNum; 95cdf0e10cSrcweir sal_Bool bDBNum :1; // DBNum, to be converted to NatNum 96cdf0e10cSrcweir sal_Bool bDate :1; // Used in date? (needed for DBNum/NatNum mapping) 97cdf0e10cSrcweir sal_Bool bSet :1; // If set, since NatNum0 is possible 98cdf0e10cSrcweir 99cdf0e10cSrcweir public: 100cdf0e10cSrcweir 101cdf0e10cSrcweir static sal_uInt8 MapDBNumToNatNum( sal_uInt8 nDBNum, LanguageType eLang, sal_Bool bDate ); 102cdf0e10cSrcweir static sal_uInt8 MapNatNumToDBNum( sal_uInt8 nNatNum, LanguageType eLang, sal_Bool bDate ); 103cdf0e10cSrcweir SvNumberNatNum()104cdf0e10cSrcweir SvNumberNatNum() : eLang( LANGUAGE_DONTKNOW ), nNum(0), 105cdf0e10cSrcweir bDBNum(0), bDate(0), bSet(0) {} IsComplete() const106cdf0e10cSrcweir sal_Bool IsComplete() const { return bSet && eLang != LANGUAGE_DONTKNOW; } GetRawNum() const107cdf0e10cSrcweir sal_uInt8 GetRawNum() const { return nNum; } GetNatNum() const108cdf0e10cSrcweir sal_uInt8 GetNatNum() const { return bDBNum ? MapDBNumToNatNum( nNum, eLang, bDate ) : nNum; } GetDBNum() const109cdf0e10cSrcweir sal_uInt8 GetDBNum() const { return bDBNum ? nNum : MapNatNumToDBNum( nNum, eLang, bDate ); } GetLang() const110cdf0e10cSrcweir LanguageType GetLang() const { return eLang; } SetLang(LanguageType e)111cdf0e10cSrcweir void SetLang( LanguageType e ) { eLang = e; } SetNum(sal_uInt8 nNumber,sal_Bool bDBNumber)112cdf0e10cSrcweir void SetNum( sal_uInt8 nNumber, sal_Bool bDBNumber ) 113cdf0e10cSrcweir { 114cdf0e10cSrcweir nNum = nNumber; 115cdf0e10cSrcweir bDBNum = bDBNumber; 116cdf0e10cSrcweir bSet = sal_True; 117cdf0e10cSrcweir } IsSet() const118cdf0e10cSrcweir sal_Bool IsSet() const { return bSet; } SetDate(sal_Bool bDateP)119cdf0e10cSrcweir void SetDate( sal_Bool bDateP ) { bDate = (bDateP != 0); } 120cdf0e10cSrcweir }; 121cdf0e10cSrcweir 122cdf0e10cSrcweir class CharClass; 123cdf0e10cSrcweir 124cdf0e10cSrcweir class ImpSvNumFor // One of four subformats of the format code string 125cdf0e10cSrcweir { 126cdf0e10cSrcweir public: 127cdf0e10cSrcweir ImpSvNumFor(); // Ctor without filling the Info 128cdf0e10cSrcweir ~ImpSvNumFor(); 129cdf0e10cSrcweir 130cdf0e10cSrcweir void Enlarge(sal_uInt16 nAnz); // Init of arrays to the right size 131cdf0e10cSrcweir void Load( SvStream& rStream, ImpSvNumberformatScan& rSc, 132cdf0e10cSrcweir String& rLoadedColorName); 133cdf0e10cSrcweir void Save( SvStream& rStream ) const; 134cdf0e10cSrcweir 135cdf0e10cSrcweir // if pSc is set, it is used to get the Color pointer 136cdf0e10cSrcweir void Copy( const ImpSvNumFor& rNumFor, ImpSvNumberformatScan* pSc ); 137cdf0e10cSrcweir 138cdf0e10cSrcweir // Access to Info; call Enlarge before! Info()139cdf0e10cSrcweir ImpSvNumberformatInfo& Info() { return aI;} Info() const140cdf0e10cSrcweir const ImpSvNumberformatInfo& Info() const { return aI; } 141cdf0e10cSrcweir 142cdf0e10cSrcweir // Get count of substrings (symbols) GetnAnz() const143cdf0e10cSrcweir sal_uInt16 GetnAnz() const { return nAnzStrings;} 144cdf0e10cSrcweir GetColor() const145cdf0e10cSrcweir Color* GetColor() const { return pColor; } SetColor(Color * pCol,String & rName)146cdf0e10cSrcweir void SetColor( Color* pCol, String& rName ) 147cdf0e10cSrcweir { pColor = pCol; sColorName = rName; } GetColorName() const148cdf0e10cSrcweir const String& GetColorName() const { return sColorName; } 149cdf0e10cSrcweir 150cdf0e10cSrcweir // new SYMBOLTYPE_CURRENCY in subformat? 151cdf0e10cSrcweir sal_Bool HasNewCurrency() const; 152cdf0e10cSrcweir sal_Bool GetNewCurrencySymbol( String& rSymbol, String& rExtension ) const; 153cdf0e10cSrcweir void SaveNewCurrencyMap( SvStream& rStream ) const; 154cdf0e10cSrcweir void LoadNewCurrencyMap( SvStream& rStream ); 155cdf0e10cSrcweir 156cdf0e10cSrcweir // [NatNum1], [NatNum2], ... SetNatNumNum(sal_uInt8 nNum,sal_Bool bDBNum)157cdf0e10cSrcweir void SetNatNumNum( sal_uInt8 nNum, sal_Bool bDBNum ) { aNatNum.SetNum( nNum, bDBNum ); } SetNatNumLang(LanguageType eLang)158cdf0e10cSrcweir void SetNatNumLang( LanguageType eLang ) { aNatNum.SetLang( eLang ); } SetNatNumDate(sal_Bool bDate)159cdf0e10cSrcweir void SetNatNumDate( sal_Bool bDate ) { aNatNum.SetDate( bDate ); } GetNatNum() const160cdf0e10cSrcweir const SvNumberNatNum& GetNatNum() const { return aNatNum; } 161cdf0e10cSrcweir 162fe481f06SOliver-Rainer Wittmann // check, if the format code contains a subformat for text 163*5ff14ef2SHerbert Dürr bool HasTextFormatCode() const; 164fe481f06SOliver-Rainer Wittmann 165cdf0e10cSrcweir private: 166cdf0e10cSrcweir ImpSvNumberformatInfo aI; // Hilfsstruct fuer die restlichen Infos 167cdf0e10cSrcweir String sColorName; // color name 168cdf0e10cSrcweir Color* pColor; // pointer to color of subformat 169cdf0e10cSrcweir sal_uInt16 nAnzStrings; // count of symbols 170cdf0e10cSrcweir SvNumberNatNum aNatNum; // DoubleByteNumber 171cdf0e10cSrcweir 172cdf0e10cSrcweir }; 173cdf0e10cSrcweir 174cdf0e10cSrcweir class SVL_DLLPUBLIC SvNumberformat 175cdf0e10cSrcweir { 176cdf0e10cSrcweir public: 177cdf0e10cSrcweir // Ctor for Load 178cdf0e10cSrcweir SvNumberformat( ImpSvNumberformatScan& rSc, LanguageType eLge ); 179cdf0e10cSrcweir 180cdf0e10cSrcweir // Normal ctor 181cdf0e10cSrcweir SvNumberformat( String& rString, 182cdf0e10cSrcweir ImpSvNumberformatScan* pSc, 183cdf0e10cSrcweir ImpSvNumberInputScan* pISc, 184cdf0e10cSrcweir xub_StrLen& nCheckPos, 185cdf0e10cSrcweir LanguageType& eLan, 186cdf0e10cSrcweir sal_Bool bStand = sal_False ); 187cdf0e10cSrcweir 188cdf0e10cSrcweir // Copy ctor 189cdf0e10cSrcweir SvNumberformat( SvNumberformat& rFormat ); 190cdf0e10cSrcweir 191cdf0e10cSrcweir // Copy ctor with exchange of format code string scanner (used in merge) 192cdf0e10cSrcweir SvNumberformat( SvNumberformat& rFormat, ImpSvNumberformatScan& rSc ); 193cdf0e10cSrcweir 194cdf0e10cSrcweir ~SvNumberformat(); 195cdf0e10cSrcweir 196cdf0e10cSrcweir /// Get type of format, may include NUMBERFORMAT_DEFINED bit GetType() const197cdf0e10cSrcweir short GetType() const 198cdf0e10cSrcweir { return (nNewStandardDefined && 199cdf0e10cSrcweir (nNewStandardDefined <= SV_NUMBERFORMATTER_VERSION)) ? 200cdf0e10cSrcweir (eType & ~NUMBERFORMAT_DEFINED) : eType; } 201cdf0e10cSrcweir SetType(const short eSetType)202cdf0e10cSrcweir void SetType(const short eSetType) { eType = eSetType; } 203cdf0e10cSrcweir // Standard means the I18N defined standard format of this type SetStandard()204cdf0e10cSrcweir void SetStandard() { bStandard = sal_True; } IsStandard() const205cdf0e10cSrcweir sal_Bool IsStandard() const { return bStandard; } 206cdf0e10cSrcweir 207cdf0e10cSrcweir // For versions before version nVer it is UserDefined, for newer versions 208cdf0e10cSrcweir // it is builtin. nVer of SV_NUMBERFORMATTER_VERSION_... SetNewStandardDefined(sal_uInt16 nVer)209cdf0e10cSrcweir void SetNewStandardDefined( sal_uInt16 nVer ) 210cdf0e10cSrcweir { nNewStandardDefined = nVer; eType |= NUMBERFORMAT_DEFINED; } 211cdf0e10cSrcweir GetNewStandardDefined() const212cdf0e10cSrcweir sal_uInt16 GetNewStandardDefined() const { return nNewStandardDefined; } IsAdditionalStandardDefined() const213cdf0e10cSrcweir sal_Bool IsAdditionalStandardDefined() const 214cdf0e10cSrcweir { return nNewStandardDefined == SV_NUMBERFORMATTER_VERSION_ADDITIONAL_I18N_FORMATS; } 215cdf0e10cSrcweir GetLanguage() const216cdf0e10cSrcweir LanguageType GetLanguage() const { return eLnge;} 217cdf0e10cSrcweir GetFormatstring() const218cdf0e10cSrcweir const String& GetFormatstring() const { return sFormatstring; } 219cdf0e10cSrcweir 220cdf0e10cSrcweir // Build a format string of application defined keywords 221cdf0e10cSrcweir String GetMappedFormatstring( const NfKeywordTable& rKeywords, 222cdf0e10cSrcweir const LocaleDataWrapper& rLoc, 223cdf0e10cSrcweir sal_Bool bDontQuote = sal_False ) const; 224cdf0e10cSrcweir SetUsed(const sal_Bool b)225cdf0e10cSrcweir void SetUsed(const sal_Bool b) { bIsUsed = b; } GetUsed() const226cdf0e10cSrcweir sal_Bool GetUsed() const { return bIsUsed; } IsStarFormatSupported() const227cdf0e10cSrcweir sal_Bool IsStarFormatSupported() const { return bStarFlag; } SetStarFormatSupport(sal_Bool b)228cdf0e10cSrcweir void SetStarFormatSupport( sal_Bool b ) { bStarFlag = b; } 229cdf0e10cSrcweir 230cdf0e10cSrcweir NfHackConversion Load( SvStream& rStream, ImpSvNumMultipleReadHeader& rHdr, 231cdf0e10cSrcweir SvNumberFormatter* pConverter, ImpSvNumberInputScan& rISc ); 232cdf0e10cSrcweir void Save( SvStream& rStream, ImpSvNumMultipleWriteHeader& rHdr ) const; 233cdf0e10cSrcweir 234cdf0e10cSrcweir // Load a string which might contain an Euro symbol, 235cdf0e10cSrcweir // in fact that could be any string used in number formats. 236cdf0e10cSrcweir static void LoadString( SvStream& rStream, String& rStr ); 237cdf0e10cSrcweir 238cdf0e10cSrcweir /** 239cdf0e10cSrcweir * Get output string from a numeric value that fits the number of 240cdf0e10cSrcweir * characters specified. 241cdf0e10cSrcweir */ 242cdf0e10cSrcweir bool GetOutputString( double fNumber, sal_uInt16 nCharCount, String& rOutString ) const; 243cdf0e10cSrcweir 244cdf0e10cSrcweir sal_Bool GetOutputString( double fNumber, String& OutString, Color** ppColor ); 245cdf0e10cSrcweir sal_Bool GetOutputString( String& sString, String& OutString, Color** ppColor ); 246cdf0e10cSrcweir 247cdf0e10cSrcweir // True if type text IsTextFormat() const248cdf0e10cSrcweir sal_Bool IsTextFormat() const { return (eType & NUMBERFORMAT_TEXT) != 0; } 249cdf0e10cSrcweir // True if 4th subformat present HasTextFormat() const250cdf0e10cSrcweir sal_Bool HasTextFormat() const 251cdf0e10cSrcweir { 252cdf0e10cSrcweir return (NumFor[3].GetnAnz() > 0) || 253cdf0e10cSrcweir (NumFor[3].Info().eScannedType == NUMBERFORMAT_TEXT); 254cdf0e10cSrcweir } 255cdf0e10cSrcweir 256cdf0e10cSrcweir void GetFormatSpecialInfo(sal_Bool& bThousand, 257cdf0e10cSrcweir sal_Bool& IsRed, 258cdf0e10cSrcweir sal_uInt16& nPrecision, 259cdf0e10cSrcweir sal_uInt16& nAnzLeading) const; 260cdf0e10cSrcweir 261cdf0e10cSrcweir /// Count of decimal precision GetFormatPrecision() const262cdf0e10cSrcweir sal_uInt16 GetFormatPrecision() const { return NumFor[0].Info().nCntPost; } 263cdf0e10cSrcweir 264cdf0e10cSrcweir //! Read/write access on a special sal_uInt16 component, may only be used on the 265cdf0e10cSrcweir //! standard format 0, 5000, ... and only by the number formatter! GetLastInsertKey() const266cdf0e10cSrcweir sal_uInt16 GetLastInsertKey() const 267cdf0e10cSrcweir { return NumFor[0].Info().nThousand; } SetLastInsertKey(sal_uInt16 nKey)268cdf0e10cSrcweir void SetLastInsertKey(sal_uInt16 nKey) 269cdf0e10cSrcweir { NumFor[0].Info().nThousand = nKey; } 270cdf0e10cSrcweir 271cdf0e10cSrcweir //! Only onLoad: convert from stored to current system language/country 272cdf0e10cSrcweir void ConvertLanguage( SvNumberFormatter& rConverter, 273cdf0e10cSrcweir LanguageType eConvertFrom, LanguageType eConvertTo, sal_Bool bSystem = sal_False ); 274cdf0e10cSrcweir 275cdf0e10cSrcweir // Substring of a subformat code nNumFor (0..3) 276cdf0e10cSrcweir // nPos == 0xFFFF => last substring 277cdf0e10cSrcweir // bString==sal_True: first/last SYMBOLTYPE_STRING or SYMBOLTYPE_CURRENCY 278cdf0e10cSrcweir const String* GetNumForString( sal_uInt16 nNumFor, sal_uInt16 nPos, 279cdf0e10cSrcweir sal_Bool bString = sal_False ) const; 280cdf0e10cSrcweir 281cdf0e10cSrcweir // Subtype of a subformat code nNumFor (0..3) 282cdf0e10cSrcweir // nPos == 0xFFFF => last substring 283cdf0e10cSrcweir // bString==sal_True: first/last SYMBOLTYPE_STRING or SYMBOLTYPE_CURRENCY 284cdf0e10cSrcweir short GetNumForType( sal_uInt16 nNumFor, sal_uInt16 nPos, sal_Bool bString = sal_False ) const; 285cdf0e10cSrcweir 286cdf0e10cSrcweir /** If the count of string elements (substrings, ignoring [modifiers] and 287cdf0e10cSrcweir so on) in a subformat code nNumFor (0..3) is equal to the given number. 288cdf0e10cSrcweir Used by ImpSvNumberInputScan::IsNumberFormatMain() to detect a matched 289cdf0e10cSrcweir format. */ IsNumForStringElementCountEqual(sal_uInt16 nNumFor,sal_uInt16 nAllCount,sal_uInt16 nNumCount) const290cdf0e10cSrcweir sal_Bool IsNumForStringElementCountEqual( sal_uInt16 nNumFor, sal_uInt16 nAllCount, 291cdf0e10cSrcweir sal_uInt16 nNumCount ) const 292cdf0e10cSrcweir { 293cdf0e10cSrcweir if ( nNumFor < 4 ) 294cdf0e10cSrcweir { 295cdf0e10cSrcweir // First try a simple approach. Note that this is called only 296cdf0e10cSrcweir // if all MidStrings did match so far, to verify that all 297cdf0e10cSrcweir // strings of the format were matched and not just the starting 298cdf0e10cSrcweir // sequence, so we don't have to check if GetnAnz() includes 299cdf0e10cSrcweir // [modifiers] or anything else if both counts are equal. 300cdf0e10cSrcweir sal_uInt16 nCnt = NumFor[nNumFor].GetnAnz(); 301cdf0e10cSrcweir if ( nAllCount == nCnt ) 302cdf0e10cSrcweir return sal_True; 303cdf0e10cSrcweir if ( nAllCount < nCnt ) // check ignoring [modifiers] and so on 304cdf0e10cSrcweir return ImpGetNumForStringElementCount( nNumFor ) == 305cdf0e10cSrcweir (nAllCount - nNumCount); 306cdf0e10cSrcweir } 307cdf0e10cSrcweir return sal_False; 308cdf0e10cSrcweir } 309cdf0e10cSrcweir 310cdf0e10cSrcweir // Whether the second subformat code is really for negative numbers 311cdf0e10cSrcweir // or another limit set. IsNegativeRealNegative() const312cdf0e10cSrcweir sal_Bool IsNegativeRealNegative() const 313cdf0e10cSrcweir { 314cdf0e10cSrcweir return fLimit1 == 0.0 && fLimit2 == 0.0 && 315cdf0e10cSrcweir ( (eOp1 == NUMBERFORMAT_OP_GE && eOp2 == NUMBERFORMAT_OP_NO) || 316cdf0e10cSrcweir (eOp1 == NUMBERFORMAT_OP_GT && eOp2 == NUMBERFORMAT_OP_LT) || 317cdf0e10cSrcweir (eOp1 == NUMBERFORMAT_OP_NO && eOp2 == NUMBERFORMAT_OP_NO) ); 318cdf0e10cSrcweir } 319f85760deSWang Lei // Whether the first subformat code is really for negative numbers 320f85760deSWang Lei // or another limit set. IsNegativeRealNegative2() const321f85760deSWang Lei sal_Bool IsNegativeRealNegative2() const 322f85760deSWang Lei { 323f85760deSWang Lei return fLimit1 == 0.0 && fLimit2 == 0.0 && 324f85760deSWang Lei ( (eOp2 == NUMBERFORMAT_OP_GT && eOp1 == NUMBERFORMAT_OP_LT) || 325f85760deSWang Lei (eOp2 == NUMBERFORMAT_OP_EQ && eOp1 == NUMBERFORMAT_OP_LT) || 326f85760deSWang Lei (eOp2 == NUMBERFORMAT_OP_GE && eOp1 == NUMBERFORMAT_OP_LT) || 327f85760deSWang Lei (eOp2 == NUMBERFORMAT_OP_NO && eOp1 == NUMBERFORMAT_OP_LT) || 328f85760deSWang Lei (eOp2 == NUMBERFORMAT_OP_NO && eOp1 == NUMBERFORMAT_OP_LE) || 329f85760deSWang Lei (eOp2 == NUMBERFORMAT_OP_GT && eOp1 == NUMBERFORMAT_OP_LE)); 330f85760deSWang Lei } 331cdf0e10cSrcweir 332cdf0e10cSrcweir // Whether the negative format is without a sign or not 333cdf0e10cSrcweir sal_Bool IsNegativeWithoutSign() const; 334cdf0e10cSrcweir 335cdf0e10cSrcweir // Whether a new SYMBOLTYPE_CURRENCY is contained in the format 336cdf0e10cSrcweir sal_Bool HasNewCurrency() const; 337cdf0e10cSrcweir 338fe481f06SOliver-Rainer Wittmann // check, if the format code contains a subformat for text 339*5ff14ef2SHerbert Dürr bool HasTextFormatCode() const; 340fe481f06SOliver-Rainer Wittmann 341cdf0e10cSrcweir // Build string from NewCurrency for saving it SO50 compatible 342cdf0e10cSrcweir void Build50Formatstring( String& rStr ) const; 343cdf0e10cSrcweir 344cdf0e10cSrcweir // strip [$-yyy] from all [$xxx-yyy] leaving only xxx's, 345cdf0e10cSrcweir // if bQuoteSymbol==sal_True the xxx will become "xxx" 346cdf0e10cSrcweir static String StripNewCurrencyDelimiters( const String& rStr, 347cdf0e10cSrcweir sal_Bool bQuoteSymbol ); 348cdf0e10cSrcweir 349cdf0e10cSrcweir // If a new SYMBOLTYPE_CURRENCY is contained if the format is of type 350cdf0e10cSrcweir // NUMBERFORMAT_CURRENCY, and if so the symbol xxx and the extension nnn 351cdf0e10cSrcweir // of [$xxx-nnn] are returned 352cdf0e10cSrcweir sal_Bool GetNewCurrencySymbol( String& rSymbol, String& rExtension ) const; 353cdf0e10cSrcweir 354cdf0e10cSrcweir static sal_Bool HasStringNegativeSign( const String& rStr ); 355cdf0e10cSrcweir 356cdf0e10cSrcweir /** 357cdf0e10cSrcweir Whether a character at position nPos is somewhere between two matching 358cdf0e10cSrcweir cQuote or not. 359cdf0e10cSrcweir If nPos points to a cQuote, a sal_True is returned on an opening cQuote, 360cdf0e10cSrcweir a sal_False is returned on a closing cQuote. 361cdf0e10cSrcweir A cQuote between quotes may be escaped by a cEscIn, a cQuote outside of 362cdf0e10cSrcweir quotes may be escaped by a cEscOut. 363cdf0e10cSrcweir The default '\0' results in no escapement possible. 364cdf0e10cSrcweir Defaults are set right according to the "unlogic" of the Numberformatter 365cdf0e10cSrcweir */ 366cdf0e10cSrcweir static sal_Bool IsInQuote( const String& rString, xub_StrLen nPos, 367cdf0e10cSrcweir sal_Unicode cQuote = '"', 368cdf0e10cSrcweir sal_Unicode cEscIn = '\0', sal_Unicode cEscOut = '\\' ); 369cdf0e10cSrcweir 370cdf0e10cSrcweir /** 371cdf0e10cSrcweir Return the position of a matching closing cQuote if the character at 372cdf0e10cSrcweir position nPos is between two matching cQuote, otherwise return 373cdf0e10cSrcweir STRING_NOTFOUND. 374cdf0e10cSrcweir If nPos points to an opening cQuote the position of the matching 375cdf0e10cSrcweir closing cQuote is returned. 376cdf0e10cSrcweir If nPos points to a closing cQuote nPos is returned. 377cdf0e10cSrcweir If nPos points into a part which starts with an opening cQuote but has 378cdf0e10cSrcweir no closing cQuote, rString.Len() is returned. 379cdf0e10cSrcweir Uses <method>IsInQuote</method> internally, so you don't have to call 380cdf0e10cSrcweir that prior to a call of this method. 381cdf0e10cSrcweir */ 382cdf0e10cSrcweir static xub_StrLen GetQuoteEnd( const String& rString, xub_StrLen nPos, 383cdf0e10cSrcweir sal_Unicode cQuote = '"', 384cdf0e10cSrcweir sal_Unicode cEscIn = '\0', sal_Unicode cEscOut = '\\' ); 385cdf0e10cSrcweir SetComment(const String & rStr)386cdf0e10cSrcweir void SetComment( const String& rStr ) 387cdf0e10cSrcweir #if NF_COMMENT_IN_FORMATSTRING 388cdf0e10cSrcweir { SetComment( rStr, sFormatstring, sComment ); } 389cdf0e10cSrcweir #else 390cdf0e10cSrcweir { sComment = rStr; } 391cdf0e10cSrcweir #endif GetComment() const392cdf0e10cSrcweir const String& GetComment() const { return sComment; } 393cdf0e10cSrcweir 394cdf0e10cSrcweir // Erase "{ "..." }" from format subcode string to get the pure comment (old version) 395cdf0e10cSrcweir static void EraseCommentBraces( String& rStr ); 396cdf0e10cSrcweir // Set comment rStr in format string rFormat and in rComment (old version) 397cdf0e10cSrcweir static void SetComment( const String& rStr, String& rFormat, String& rComment ); 398cdf0e10cSrcweir // Erase comment at end of rStr to get pure format code string (old version) 399cdf0e10cSrcweir static void EraseComment( String& rStr ); 400cdf0e10cSrcweir 401cdf0e10cSrcweir /** Insert the number of blanks into the string that is needed to simulate 402cdf0e10cSrcweir the width of character c for underscore formats */ 403cdf0e10cSrcweir static xub_StrLen InsertBlanks( String& r, xub_StrLen nPos, sal_Unicode c ); 404cdf0e10cSrcweir 405cdf0e10cSrcweir /// One of YMD,DMY,MDY if date format 406cdf0e10cSrcweir DateFormat GetDateOrder() const; 407cdf0e10cSrcweir 408cdf0e10cSrcweir /** A coded value of the exact YMD combination used, if date format. 409cdf0e10cSrcweir For example: YYYY-MM-DD => ('Y' << 16) | ('M' << 8) | 'D' 410cdf0e10cSrcweir or: MM/YY => ('M' << 8) | 'Y' */ 411cdf0e10cSrcweir sal_uInt32 GetExactDateOrder() const; 412cdf0e10cSrcweir ImpGetScan() const413cdf0e10cSrcweir ImpSvNumberformatScan& ImpGetScan() const { return rScan; } 414cdf0e10cSrcweir 415cdf0e10cSrcweir // used in XML export 416cdf0e10cSrcweir void GetConditions( SvNumberformatLimitOps& rOper1, double& rVal1, 417cdf0e10cSrcweir SvNumberformatLimitOps& rOper2, double& rVal2 ) const; 418cdf0e10cSrcweir Color* GetColor( sal_uInt16 nNumFor ) const; 419cdf0e10cSrcweir void GetNumForInfo( sal_uInt16 nNumFor, short& rScannedType, 420cdf0e10cSrcweir sal_Bool& bThousand, sal_uInt16& nPrecision, sal_uInt16& nAnzLeading ) const; 421cdf0e10cSrcweir 422cdf0e10cSrcweir // rAttr.Number not empty if NatNum attributes are to be stored 423cdf0e10cSrcweir void GetNatNumXml( 424cdf0e10cSrcweir ::com::sun::star::i18n::NativeNumberXmlAttributes& rAttr, 425cdf0e10cSrcweir sal_uInt16 nNumFor ) const; 426cdf0e10cSrcweir 427cdf0e10cSrcweir /** @returns <TRUE/> if E,EE,R,RR,AAA,AAAA in format code of subformat 428cdf0e10cSrcweir nNumFor (0..3) and <b>no</b> preceding calendar was specified and the 429cdf0e10cSrcweir currently loaded calendar is "gregorian". */ IsOtherCalendar(sal_uInt16 nNumFor) const430cdf0e10cSrcweir sal_Bool IsOtherCalendar( sal_uInt16 nNumFor ) const 431cdf0e10cSrcweir { 432cdf0e10cSrcweir if ( nNumFor < 4 ) 433cdf0e10cSrcweir return ImpIsOtherCalendar( NumFor[nNumFor] ); 434cdf0e10cSrcweir return sal_False; 435cdf0e10cSrcweir } 436cdf0e10cSrcweir 437cdf0e10cSrcweir /** Switches to the first non-"gregorian" calendar, but only if the current 438cdf0e10cSrcweir calendar is "gregorian"; original calendar name and date/time returned, 439cdf0e10cSrcweir but only if calendar switched and rOrgCalendar was empty. */ 440cdf0e10cSrcweir void SwitchToOtherCalendar( String& rOrgCalendar, double& fOrgDateTime ) const; 441cdf0e10cSrcweir 442cdf0e10cSrcweir /** Switches to the "gregorian" calendar, but only if the current calendar 443cdf0e10cSrcweir is non-"gregorian" and rOrgCalendar is not empty. Thus a preceding 444cdf0e10cSrcweir ImpSwitchToOtherCalendar() call should have been placed prior to 445cdf0e10cSrcweir calling this method. */ 446cdf0e10cSrcweir void SwitchToGregorianCalendar( const String& rOrgCalendar, double fOrgDateTime ) const; 447cdf0e10cSrcweir 448cdf0e10cSrcweir /** Switches to the first specified calendar, if any, in subformat nNumFor 449cdf0e10cSrcweir (0..3). Original calendar name and date/time returned, but only if 450cdf0e10cSrcweir calendar switched and rOrgCalendar was empty. 451cdf0e10cSrcweir 452cdf0e10cSrcweir @return 453cdf0e10cSrcweir <TRUE/> if a calendar was specified and switched to, 454cdf0e10cSrcweir <FALSE/> else. 455cdf0e10cSrcweir */ SwitchToSpecifiedCalendar(String & rOrgCalendar,double & fOrgDateTime,sal_uInt16 nNumFor) const456cdf0e10cSrcweir sal_Bool SwitchToSpecifiedCalendar( String& rOrgCalendar, double& fOrgDateTime, 457cdf0e10cSrcweir sal_uInt16 nNumFor ) const 458cdf0e10cSrcweir { 459cdf0e10cSrcweir if ( nNumFor < 4 ) 460cdf0e10cSrcweir return ImpSwitchToSpecifiedCalendar( rOrgCalendar, 461cdf0e10cSrcweir fOrgDateTime, NumFor[nNumFor] ); 462cdf0e10cSrcweir return sal_False; 463cdf0e10cSrcweir } 464cdf0e10cSrcweir 465cdf0e10cSrcweir private: 466cdf0e10cSrcweir ImpSvNumFor NumFor[4]; // Array for the 4 subformats 467cdf0e10cSrcweir String sFormatstring; // The format code string 468cdf0e10cSrcweir String sComment; // Comment, since number formatter version 6 469cdf0e10cSrcweir double fLimit1; // Value for first condition 470cdf0e10cSrcweir double fLimit2; // Value for second condition 471cdf0e10cSrcweir ImpSvNumberformatScan& rScan; // Format code scanner 472cdf0e10cSrcweir LanguageType eLnge; // Language/country of the format 473cdf0e10cSrcweir SvNumberformatLimitOps eOp1; // Operator for first condition 474cdf0e10cSrcweir SvNumberformatLimitOps eOp2; // Operator for second condition 475cdf0e10cSrcweir sal_uInt16 nNewStandardDefined; // new builtin formats as of version 6 476cdf0e10cSrcweir short eType; // Type of format 477cdf0e10cSrcweir sal_Bool bStarFlag; // Take *n format as ESC n 478cdf0e10cSrcweir sal_Bool bStandard; // If this is a default standard format 479cdf0e10cSrcweir sal_Bool bIsUsed; // Flag as used for storing 480cdf0e10cSrcweir 481cdf0e10cSrcweir SVL_DLLPRIVATE sal_uInt16 ImpGetNumForStringElementCount( sal_uInt16 nNumFor ) const; 482cdf0e10cSrcweir 483cdf0e10cSrcweir SVL_DLLPRIVATE sal_Bool ImpIsOtherCalendar( const ImpSvNumFor& rNumFor ) const; 484cdf0e10cSrcweir 485cdf0e10cSrcweir SVL_DLLPRIVATE sal_Bool ImpSwitchToSpecifiedCalendar( String& rOrgCalendar, 486cdf0e10cSrcweir double& fOrgDateTime, const ImpSvNumFor& rNumFor ) const; 487cdf0e10cSrcweir 488cdf0e10cSrcweir #ifdef _ZFORMAT_CXX // ----- private implementation methods ----- 489cdf0e10cSrcweir rChrCls() const490cdf0e10cSrcweir const CharClass& rChrCls() const { return rScan.GetChrCls(); } rLoc() const491cdf0e10cSrcweir const LocaleDataWrapper& rLoc() const { return rScan.GetLoc(); } GetCal() const492cdf0e10cSrcweir CalendarWrapper& GetCal() const { return rScan.GetCal(); } GetFormatter() const493cdf0e10cSrcweir const SvNumberFormatter& GetFormatter() const { return *rScan.GetNumberformatter(); } 494cdf0e10cSrcweir 495cdf0e10cSrcweir // divide in substrings and color conditions 496cdf0e10cSrcweir SVL_DLLPRIVATE short ImpNextSymbol( String& rString, 497cdf0e10cSrcweir xub_StrLen& nPos, 498cdf0e10cSrcweir String& sSymbol ); 499cdf0e10cSrcweir 500cdf0e10cSrcweir // read string until ']' and strip blanks (after condition) 501cdf0e10cSrcweir SVL_DLLPRIVATE static xub_StrLen ImpGetNumber( String& rString, 502cdf0e10cSrcweir xub_StrLen& nPos, 503cdf0e10cSrcweir String& sSymbol ); 504cdf0e10cSrcweir 505cdf0e10cSrcweir // get xxx of "[$-xxx]" as LanguageType, starting at and advancing position nPos 506cdf0e10cSrcweir SVL_DLLPRIVATE static LanguageType ImpGetLanguageType( const String& rString, xub_StrLen& nPos ); 507cdf0e10cSrcweir 508cdf0e10cSrcweir // standard number output 509cdf0e10cSrcweir SVL_DLLPRIVATE void ImpGetOutputStandard( double& fNumber, String& OutString ); 510cdf0e10cSrcweir SVL_DLLPRIVATE void ImpGetOutputStdToPrecision( double& rNumber, String& rOutString, sal_uInt16 nPrecision ) const; 511cdf0e10cSrcweir // numbers in input line 512cdf0e10cSrcweir SVL_DLLPRIVATE void ImpGetOutputInputLine( double fNumber, String& OutString ); 513cdf0e10cSrcweir 514cdf0e10cSrcweir // check subcondition 515cdf0e10cSrcweir // OP undefined => -1 516cdf0e10cSrcweir // else 0 or 1 517cdf0e10cSrcweir SVL_DLLPRIVATE short ImpCheckCondition(double& fNumber, 518cdf0e10cSrcweir double& fLimit, 519cdf0e10cSrcweir SvNumberformatLimitOps eOp); 520cdf0e10cSrcweir 521cdf0e10cSrcweir SVL_DLLPRIVATE sal_uLong ImpGGT(sal_uLong x, sal_uLong y); 522cdf0e10cSrcweir SVL_DLLPRIVATE sal_uLong ImpGGTRound(sal_uLong x, sal_uLong y); 523cdf0e10cSrcweir 524cdf0e10cSrcweir // Helper function for number strings 525cdf0e10cSrcweir // append string symbols, insert leading 0 or ' ', or ... 526cdf0e10cSrcweir SVL_DLLPRIVATE sal_Bool ImpNumberFill( String& sStr, 527cdf0e10cSrcweir double& rNumber, 528cdf0e10cSrcweir xub_StrLen& k, 529cdf0e10cSrcweir sal_uInt16& j, 530cdf0e10cSrcweir sal_uInt16 nIx, 531cdf0e10cSrcweir short eSymbolType ); 532cdf0e10cSrcweir 533cdf0e10cSrcweir // Helper function to fill in the integer part and the group (AKA thousand) separators 534cdf0e10cSrcweir SVL_DLLPRIVATE sal_Bool ImpNumberFillWithThousands( String& sStr, 535cdf0e10cSrcweir double& rNumber, 536cdf0e10cSrcweir xub_StrLen k, 537cdf0e10cSrcweir sal_uInt16 j, 538cdf0e10cSrcweir sal_uInt16 nIx, 539cdf0e10cSrcweir sal_uInt16 nDigCnt ); 540cdf0e10cSrcweir // Hilfsfunktion zum Auffuellen der Vor- 541cdf0e10cSrcweir // kommazahl auch mit Tausenderpunkt 542cdf0e10cSrcweir 543cdf0e10cSrcweir // Helper function to fill in the group (AKA thousand) separators 544cdf0e10cSrcweir // or to skip additional digits 545cdf0e10cSrcweir SVL_DLLPRIVATE void ImpDigitFill( String& sStr, 546cdf0e10cSrcweir xub_StrLen nStart, 547cdf0e10cSrcweir xub_StrLen& k, 548cdf0e10cSrcweir sal_uInt16 nIx, 549cdf0e10cSrcweir xub_StrLen & nDigitCount, 550cdf0e10cSrcweir utl::DigitGroupingIterator & ); 551cdf0e10cSrcweir 552cdf0e10cSrcweir SVL_DLLPRIVATE sal_Bool ImpGetDateOutput( double fNumber, 553cdf0e10cSrcweir sal_uInt16 nIx, 554cdf0e10cSrcweir String& OutString ); 555cdf0e10cSrcweir SVL_DLLPRIVATE sal_Bool ImpGetTimeOutput( double fNumber, 556cdf0e10cSrcweir sal_uInt16 nIx, 557cdf0e10cSrcweir String& OutString ); 558cdf0e10cSrcweir SVL_DLLPRIVATE sal_Bool ImpGetDateTimeOutput( double fNumber, 559cdf0e10cSrcweir sal_uInt16 nIx, 560cdf0e10cSrcweir String& OutString ); 561cdf0e10cSrcweir 562cdf0e10cSrcweir // Switches to the "gregorian" calendar if the current calendar is 563cdf0e10cSrcweir // non-"gregorian" and the era is a "Dummy" era of a calendar which doesn't 564cdf0e10cSrcweir // know a "before" era (like zh_TW ROC or ja_JP Gengou). If switched and 565cdf0e10cSrcweir // rOrgCalendar was "gregorian" the string is emptied. If rOrgCalendar was 566cdf0e10cSrcweir // empty the previous calendar name and date/time are returned. 567cdf0e10cSrcweir SVL_DLLPRIVATE sal_Bool ImpFallBackToGregorianCalendar( String& rOrgCalendar, double& fOrgDateTime ); 568cdf0e10cSrcweir 569cdf0e10cSrcweir // Append a "G" short era string of the given calendar. In the case of a 570cdf0e10cSrcweir // Gengou calendar this is a one character abbreviation, for other 571cdf0e10cSrcweir // calendars the XExtendedCalendar::getDisplayString() method is called. 572cdf0e10cSrcweir SVL_DLLPRIVATE static void ImpAppendEraG( String& OutString, const CalendarWrapper& rCal, 573cdf0e10cSrcweir sal_Int16 nNatNum ); 574cdf0e10cSrcweir 575cdf0e10cSrcweir SVL_DLLPRIVATE sal_Bool ImpGetNumberOutput( double fNumber, 576cdf0e10cSrcweir sal_uInt16 nIx, 577cdf0e10cSrcweir String& OutString ); 578cdf0e10cSrcweir 579cdf0e10cSrcweir SVL_DLLPRIVATE void ImpCopyNumberformat( const SvNumberformat& rFormat ); 580cdf0e10cSrcweir 581cdf0e10cSrcweir // normal digits or other digits, depending on ImpSvNumFor.aNatNum, 582cdf0e10cSrcweir // [NatNum1], [NatNum2], ... 583cdf0e10cSrcweir SVL_DLLPRIVATE String ImpGetNatNumString( const SvNumberNatNum& rNum, sal_Int32 nVal, 584cdf0e10cSrcweir sal_uInt16 nMinDigits = 0 ) const; 585cdf0e10cSrcweir ImpIntToString(sal_uInt16 nIx,sal_Int32 nVal,sal_uInt16 nMinDigits=0) const586cdf0e10cSrcweir String ImpIntToString( sal_uInt16 nIx, sal_Int32 nVal, sal_uInt16 nMinDigits = 0 ) const 587cdf0e10cSrcweir { 588cdf0e10cSrcweir const SvNumberNatNum& rNum = NumFor[nIx].GetNatNum(); 589cdf0e10cSrcweir if ( nMinDigits || rNum.IsComplete() ) 590cdf0e10cSrcweir return ImpGetNatNumString( rNum, nVal, nMinDigits ); 591cdf0e10cSrcweir return String::CreateFromInt32( nVal ); 592cdf0e10cSrcweir } 593cdf0e10cSrcweir 594cdf0e10cSrcweir // transliterate according to NativeNumber 595cdf0e10cSrcweir SVL_DLLPRIVATE void ImpTransliterateImpl( String& rStr, const SvNumberNatNum& rNum ) const; 596cdf0e10cSrcweir ImpTransliterate(String & rStr,const SvNumberNatNum & rNum) const597cdf0e10cSrcweir void ImpTransliterate( String& rStr, const SvNumberNatNum& rNum ) const 598cdf0e10cSrcweir { 599cdf0e10cSrcweir if ( rNum.IsComplete() ) 600cdf0e10cSrcweir ImpTransliterateImpl( rStr, rNum ); 601cdf0e10cSrcweir } 602cdf0e10cSrcweir 603cdf0e10cSrcweir #endif // _ZFORMAT_CXX 604cdf0e10cSrcweir 605cdf0e10cSrcweir }; 606cdf0e10cSrcweir 607cdf0e10cSrcweir #endif // _ZFORMAT_HXX 608