140df464eSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 340df464eSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 440df464eSAndrew Rist * or more contributor license agreements. See the NOTICE file 540df464eSAndrew Rist * distributed with this work for additional information 640df464eSAndrew Rist * regarding copyright ownership. The ASF licenses this file 740df464eSAndrew Rist * to you under the Apache License, Version 2.0 (the 840df464eSAndrew Rist * "License"); you may not use this file except in compliance 940df464eSAndrew Rist * with the License. You may obtain a copy of the License at 1040df464eSAndrew Rist * 1140df464eSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 1240df464eSAndrew Rist * 1340df464eSAndrew Rist * Unless required by applicable law or agreed to in writing, 1440df464eSAndrew Rist * software distributed under the License is distributed on an 1540df464eSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 1640df464eSAndrew Rist * KIND, either express or implied. See the License for the 1740df464eSAndrew Rist * specific language governing permissions and limitations 1840df464eSAndrew Rist * under the License. 1940df464eSAndrew Rist * 2040df464eSAndrew Rist *************************************************************/ 2140df464eSAndrew Rist 2240df464eSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_svl.hxx" 26cdf0e10cSrcweir #include <stdio.h> 27cdf0e10cSrcweir #include <ctype.h> 28cdf0e10cSrcweir #include <float.h> 29cdf0e10cSrcweir // #include <math.h> 30cdf0e10cSrcweir #include <errno.h> 31cdf0e10cSrcweir #include <stdlib.h> 32cdf0e10cSrcweir #include <tools/debug.hxx> 33cdf0e10cSrcweir #include <i18npool/mslangid.hxx> 34cdf0e10cSrcweir #include <rtl/math.hxx> 35cdf0e10cSrcweir #include <rtl/instance.hxx> 36cdf0e10cSrcweir #include <unotools/charclass.hxx> 37cdf0e10cSrcweir #include <unotools/calendarwrapper.hxx> 38cdf0e10cSrcweir #include <unotools/nativenumberwrapper.hxx> 39cdf0e10cSrcweir #include <com/sun/star/i18n/CalendarFieldIndex.hpp> 40cdf0e10cSrcweir #include <com/sun/star/i18n/CalendarDisplayIndex.hpp> 41cdf0e10cSrcweir #include <com/sun/star/i18n/CalendarDisplayCode.hpp> 42cdf0e10cSrcweir #include <com/sun/star/i18n/AmPmValue.hpp> 43cdf0e10cSrcweir 44cdf0e10cSrcweir #define _ZFORMAT_CXX 45cdf0e10cSrcweir #include <svl/zformat.hxx> 46cdf0e10cSrcweir #include <zforscan.hxx> 47cdf0e10cSrcweir 48cdf0e10cSrcweir #include "zforfind.hxx" 49cdf0e10cSrcweir #include <svl/zforlist.hxx> 50cdf0e10cSrcweir #include "numhead.hxx" 51cdf0e10cSrcweir #include <unotools/digitgroupingiterator.hxx> 52cdf0e10cSrcweir #include <svl/nfsymbol.hxx> 53cdf0e10cSrcweir 54cdf0e10cSrcweir #include <cmath> 55cdf0e10cSrcweir 56cdf0e10cSrcweir using namespace svt; 57cdf0e10cSrcweir 58cdf0e10cSrcweir namespace { 59cdf0e10cSrcweir struct Gregorian 60cdf0e10cSrcweir : public rtl::StaticWithInit<const ::rtl::OUString, Gregorian> { 61cdf0e10cSrcweir const ::rtl::OUString operator () () { 62cdf0e10cSrcweir return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("gregorian")); 63cdf0e10cSrcweir } 64cdf0e10cSrcweir }; 65cdf0e10cSrcweir 66cdf0e10cSrcweir const sal_uInt16 UPPER_PRECISION = 300; // entirely arbitrary... 67cdf0e10cSrcweir const double EXP_LOWER_BOUND = 1.0E-4; // prefer scientific notation below this value. 68cdf0e10cSrcweir 69cdf0e10cSrcweir } 70cdf0e10cSrcweir 71cdf0e10cSrcweir const double _D_MAX_U_LONG_ = (double) 0xffffffff; // 4294967295.0 72cdf0e10cSrcweir const double _D_MAX_LONG_ = (double) 0x7fffffff; // 2147483647.0 73cdf0e10cSrcweir const sal_uInt16 _MAX_FRACTION_PREC = 3; 74cdf0e10cSrcweir const double D_EPS = 1.0E-2; 75cdf0e10cSrcweir 76cdf0e10cSrcweir const double _D_MAX_D_BY_100 = 1.7E306; 77cdf0e10cSrcweir const double _D_MIN_M_BY_1000 = 2.3E-305; 78cdf0e10cSrcweir 79cdf0e10cSrcweir static sal_uInt8 cCharWidths[ 128-32 ] = { 80cdf0e10cSrcweir 1,1,1,2,2,3,2,1,1,1,1,2,1,1,1,1, 81cdf0e10cSrcweir 2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2, 82cdf0e10cSrcweir 3,2,2,2,2,2,2,3,2,1,2,2,2,3,3,3, 83cdf0e10cSrcweir 2,3,2,2,2,2,2,3,2,2,2,1,1,1,2,2, 84cdf0e10cSrcweir 1,2,2,2,2,2,1,2,2,1,1,2,1,3,2,2, 85cdf0e10cSrcweir 2,2,1,2,1,2,2,2,2,2,2,1,1,1,2,1 86cdf0e10cSrcweir }; 87cdf0e10cSrcweir 88cdf0e10cSrcweir // static 89cdf0e10cSrcweir xub_StrLen SvNumberformat::InsertBlanks( String& r, xub_StrLen nPos, sal_Unicode c ) 90cdf0e10cSrcweir { 91cdf0e10cSrcweir if( c >= 32 ) 92cdf0e10cSrcweir { 93cdf0e10cSrcweir sal_uInt16 n = 2; // Default fuer Zeichen > 128 (HACK!) 94cdf0e10cSrcweir if( c <= 127 ) 95cdf0e10cSrcweir n = cCharWidths[ c - 32 ]; 96cdf0e10cSrcweir while( n-- ) 97cdf0e10cSrcweir r.Insert( ' ', nPos++ ); 98cdf0e10cSrcweir } 99cdf0e10cSrcweir return nPos; 100cdf0e10cSrcweir } 101cdf0e10cSrcweir 102cdf0e10cSrcweir static long GetPrecExp( double fAbsVal ) 103cdf0e10cSrcweir { 104cdf0e10cSrcweir DBG_ASSERT( fAbsVal > 0.0, "GetPrecExp: fAbsVal <= 0.0" ); 105cdf0e10cSrcweir if ( fAbsVal < 1e-7 || fAbsVal > 1e7 ) 106cdf0e10cSrcweir { // die Schere, ob's schneller ist oder nicht, liegt zwischen 1e6 und 1e7 107cdf0e10cSrcweir return (long) floor( log10( fAbsVal ) ) + 1; 108cdf0e10cSrcweir } 109cdf0e10cSrcweir else 110cdf0e10cSrcweir { 111cdf0e10cSrcweir long nPrecExp = 1; 112cdf0e10cSrcweir while( fAbsVal < 1 ) 113cdf0e10cSrcweir { 114cdf0e10cSrcweir fAbsVal *= 10; 115cdf0e10cSrcweir nPrecExp--; 116cdf0e10cSrcweir } 117cdf0e10cSrcweir while( fAbsVal >= 10 ) 118cdf0e10cSrcweir { 119cdf0e10cSrcweir fAbsVal /= 10; 120cdf0e10cSrcweir nPrecExp++; 121cdf0e10cSrcweir } 122cdf0e10cSrcweir return nPrecExp; 123cdf0e10cSrcweir } 124cdf0e10cSrcweir } 125cdf0e10cSrcweir 126cdf0e10cSrcweir const sal_uInt16 nNewCurrencyVersionId = 0x434E; // "NC" 127cdf0e10cSrcweir const sal_Unicode cNewCurrencyMagic = 0x01; // Magic for format code in comment 128cdf0e10cSrcweir const sal_uInt16 nNewStandardFlagVersionId = 0x4653; // "SF" 129cdf0e10cSrcweir 130cdf0e10cSrcweir /***********************Funktion SvNumberformatInfo******************************/ 131cdf0e10cSrcweir 132cdf0e10cSrcweir void ImpSvNumberformatInfo::Copy( const ImpSvNumberformatInfo& rNumFor, sal_uInt16 nAnz ) 133cdf0e10cSrcweir { 134cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nAnz; i++) 135cdf0e10cSrcweir { 136cdf0e10cSrcweir sStrArray[i] = rNumFor.sStrArray[i]; 137cdf0e10cSrcweir nTypeArray[i] = rNumFor.nTypeArray[i]; 138cdf0e10cSrcweir } 139cdf0e10cSrcweir eScannedType = rNumFor.eScannedType; 140cdf0e10cSrcweir bThousand = rNumFor.bThousand; 141cdf0e10cSrcweir nThousand = rNumFor.nThousand; 142cdf0e10cSrcweir nCntPre = rNumFor.nCntPre; 143cdf0e10cSrcweir nCntPost = rNumFor.nCntPost; 144cdf0e10cSrcweir nCntExp = rNumFor.nCntExp; 145cdf0e10cSrcweir } 146cdf0e10cSrcweir 147cdf0e10cSrcweir void ImpSvNumberformatInfo::Save(SvStream& rStream, sal_uInt16 nAnz) const 148cdf0e10cSrcweir { 149cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nAnz; i++) 150cdf0e10cSrcweir { 151cdf0e10cSrcweir rStream.WriteByteString( sStrArray[i], rStream.GetStreamCharSet() ); 152cdf0e10cSrcweir short nType = nTypeArray[i]; 153cdf0e10cSrcweir switch ( nType ) 154cdf0e10cSrcweir { // der Krampf fuer Versionen vor SV_NUMBERFORMATTER_VERSION_NEW_CURR 155cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRENCY : 156cdf0e10cSrcweir rStream << short( NF_SYMBOLTYPE_STRING ); 157cdf0e10cSrcweir break; 158cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRDEL : 159cdf0e10cSrcweir case NF_SYMBOLTYPE_CURREXT : 160cdf0e10cSrcweir rStream << short(0); // werden ignoriert (hoffentlich..) 161cdf0e10cSrcweir break; 162cdf0e10cSrcweir default: 163cdf0e10cSrcweir if ( nType > NF_KEY_LASTKEYWORD_SO5 ) 164cdf0e10cSrcweir rStream << short( NF_SYMBOLTYPE_STRING ); // all new keywords are string 165cdf0e10cSrcweir else 166cdf0e10cSrcweir rStream << nType; 167cdf0e10cSrcweir } 168cdf0e10cSrcweir 169cdf0e10cSrcweir } 170cdf0e10cSrcweir rStream << eScannedType << bThousand << nThousand 171cdf0e10cSrcweir << nCntPre << nCntPost << nCntExp; 172cdf0e10cSrcweir } 173cdf0e10cSrcweir 174cdf0e10cSrcweir void ImpSvNumberformatInfo::Load(SvStream& rStream, sal_uInt16 nAnz) 175cdf0e10cSrcweir { 176cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nAnz; i++) 177cdf0e10cSrcweir { 178cdf0e10cSrcweir SvNumberformat::LoadString( rStream, sStrArray[i] ); 179cdf0e10cSrcweir rStream >> nTypeArray[i]; 180cdf0e10cSrcweir } 181cdf0e10cSrcweir rStream >> eScannedType >> bThousand >> nThousand 182cdf0e10cSrcweir >> nCntPre >> nCntPost >> nCntExp; 183cdf0e10cSrcweir } 184cdf0e10cSrcweir 185cdf0e10cSrcweir 186cdf0e10cSrcweir //============================================================================ 187cdf0e10cSrcweir 188cdf0e10cSrcweir // static 189cdf0e10cSrcweir sal_uInt8 SvNumberNatNum::MapDBNumToNatNum( sal_uInt8 nDBNum, LanguageType eLang, sal_Bool bDate ) 190cdf0e10cSrcweir { 191cdf0e10cSrcweir sal_uInt8 nNatNum = 0; 192cdf0e10cSrcweir eLang = MsLangId::getRealLanguage( eLang ); // resolve SYSTEM etc. 193cdf0e10cSrcweir eLang &= 0x03FF; // 10 bit primary language 194cdf0e10cSrcweir if ( bDate ) 195cdf0e10cSrcweir { 196cdf0e10cSrcweir if ( nDBNum == 4 && eLang == LANGUAGE_KOREAN ) 197cdf0e10cSrcweir nNatNum = 9; 198cdf0e10cSrcweir else if ( nDBNum <= 3 ) 199cdf0e10cSrcweir nNatNum = nDBNum; // known to be good for: zh,ja,ko / 1,2,3 200cdf0e10cSrcweir } 201cdf0e10cSrcweir else 202cdf0e10cSrcweir { 203cdf0e10cSrcweir switch ( nDBNum ) 204cdf0e10cSrcweir { 205cdf0e10cSrcweir case 1: 206cdf0e10cSrcweir switch ( eLang ) 207cdf0e10cSrcweir { 208cdf0e10cSrcweir case (LANGUAGE_CHINESE & 0x03FF) : nNatNum = 4; break; 209cdf0e10cSrcweir case (LANGUAGE_JAPANESE & 0x03FF) : nNatNum = 1; break; 210cdf0e10cSrcweir case (LANGUAGE_KOREAN & 0x03FF) : nNatNum = 1; break; 211cdf0e10cSrcweir } 212cdf0e10cSrcweir break; 213cdf0e10cSrcweir case 2: 214cdf0e10cSrcweir switch ( eLang ) 215cdf0e10cSrcweir { 216cdf0e10cSrcweir case (LANGUAGE_CHINESE & 0x03FF) : nNatNum = 5; break; 217cdf0e10cSrcweir case (LANGUAGE_JAPANESE & 0x03FF) : nNatNum = 4; break; 218cdf0e10cSrcweir case (LANGUAGE_KOREAN & 0x03FF) : nNatNum = 2; break; 219cdf0e10cSrcweir } 220cdf0e10cSrcweir break; 221cdf0e10cSrcweir case 3: 222cdf0e10cSrcweir switch ( eLang ) 223cdf0e10cSrcweir { 224cdf0e10cSrcweir case (LANGUAGE_CHINESE & 0x03FF) : nNatNum = 6; break; 225cdf0e10cSrcweir case (LANGUAGE_JAPANESE & 0x03FF) : nNatNum = 5; break; 226cdf0e10cSrcweir case (LANGUAGE_KOREAN & 0x03FF) : nNatNum = 3; break; 227cdf0e10cSrcweir } 228cdf0e10cSrcweir break; 229cdf0e10cSrcweir case 4: 230cdf0e10cSrcweir switch ( eLang ) 231cdf0e10cSrcweir { 232cdf0e10cSrcweir case (LANGUAGE_JAPANESE & 0x03FF) : nNatNum = 7; break; 233cdf0e10cSrcweir case (LANGUAGE_KOREAN & 0x03FF) : nNatNum = 9; break; 234cdf0e10cSrcweir } 235cdf0e10cSrcweir break; 236cdf0e10cSrcweir } 237cdf0e10cSrcweir } 238cdf0e10cSrcweir return nNatNum; 239cdf0e10cSrcweir } 240cdf0e10cSrcweir 241cdf0e10cSrcweir 242cdf0e10cSrcweir // static 243cdf0e10cSrcweir sal_uInt8 SvNumberNatNum::MapNatNumToDBNum( sal_uInt8 nNatNum, LanguageType eLang, sal_Bool bDate ) 244cdf0e10cSrcweir { 245cdf0e10cSrcweir sal_uInt8 nDBNum = 0; 246cdf0e10cSrcweir eLang = MsLangId::getRealLanguage( eLang ); // resolve SYSTEM etc. 247cdf0e10cSrcweir eLang &= 0x03FF; // 10 bit primary language 248cdf0e10cSrcweir if ( bDate ) 249cdf0e10cSrcweir { 250cdf0e10cSrcweir if ( nNatNum == 9 && eLang == LANGUAGE_KOREAN ) 251cdf0e10cSrcweir nDBNum = 4; 252cdf0e10cSrcweir else if ( nNatNum <= 3 ) 253cdf0e10cSrcweir nDBNum = nNatNum; // known to be good for: zh,ja,ko / 1,2,3 254cdf0e10cSrcweir } 255cdf0e10cSrcweir else 256cdf0e10cSrcweir { 257cdf0e10cSrcweir switch ( nNatNum ) 258cdf0e10cSrcweir { 259cdf0e10cSrcweir case 1: 260cdf0e10cSrcweir switch ( eLang ) 261cdf0e10cSrcweir { 262cdf0e10cSrcweir case (LANGUAGE_JAPANESE & 0x03FF) : nDBNum = 1; break; 263cdf0e10cSrcweir case (LANGUAGE_KOREAN & 0x03FF) : nDBNum = 1; break; 264cdf0e10cSrcweir } 265cdf0e10cSrcweir break; 266cdf0e10cSrcweir case 2: 267cdf0e10cSrcweir switch ( eLang ) 268cdf0e10cSrcweir { 269cdf0e10cSrcweir case (LANGUAGE_KOREAN & 0x03FF) : nDBNum = 2; break; 270cdf0e10cSrcweir } 271cdf0e10cSrcweir break; 272cdf0e10cSrcweir case 3: 273cdf0e10cSrcweir switch ( eLang ) 274cdf0e10cSrcweir { 275cdf0e10cSrcweir case (LANGUAGE_KOREAN & 0x03FF) : nDBNum = 3; break; 276cdf0e10cSrcweir } 277cdf0e10cSrcweir break; 278cdf0e10cSrcweir case 4: 279cdf0e10cSrcweir switch ( eLang ) 280cdf0e10cSrcweir { 281cdf0e10cSrcweir case (LANGUAGE_CHINESE & 0x03FF) : nDBNum = 1; break; 282cdf0e10cSrcweir case (LANGUAGE_JAPANESE & 0x03FF) : nDBNum = 2; break; 283cdf0e10cSrcweir } 284cdf0e10cSrcweir break; 285cdf0e10cSrcweir case 5: 286cdf0e10cSrcweir switch ( eLang ) 287cdf0e10cSrcweir { 288cdf0e10cSrcweir case (LANGUAGE_CHINESE & 0x03FF) : nDBNum = 2; break; 289cdf0e10cSrcweir case (LANGUAGE_JAPANESE & 0x03FF) : nDBNum = 3; break; 290cdf0e10cSrcweir } 291cdf0e10cSrcweir break; 292cdf0e10cSrcweir case 6: 293cdf0e10cSrcweir switch ( eLang ) 294cdf0e10cSrcweir { 295cdf0e10cSrcweir case (LANGUAGE_CHINESE & 0x03FF) : nDBNum = 3; break; 296cdf0e10cSrcweir } 297cdf0e10cSrcweir break; 298cdf0e10cSrcweir case 7: 299cdf0e10cSrcweir switch ( eLang ) 300cdf0e10cSrcweir { 301cdf0e10cSrcweir case (LANGUAGE_JAPANESE & 0x03FF) : nDBNum = 4; break; 302cdf0e10cSrcweir } 303cdf0e10cSrcweir break; 304cdf0e10cSrcweir case 8: 305cdf0e10cSrcweir break; 306cdf0e10cSrcweir case 9: 307cdf0e10cSrcweir switch ( eLang ) 308cdf0e10cSrcweir { 309cdf0e10cSrcweir case (LANGUAGE_KOREAN & 0x03FF) : nDBNum = 4; break; 310cdf0e10cSrcweir } 311cdf0e10cSrcweir break; 312cdf0e10cSrcweir case 10: 313cdf0e10cSrcweir break; 314cdf0e10cSrcweir case 11: 315cdf0e10cSrcweir break; 316cdf0e10cSrcweir } 317cdf0e10cSrcweir } 318cdf0e10cSrcweir return nDBNum; 319cdf0e10cSrcweir } 320cdf0e10cSrcweir 321cdf0e10cSrcweir /***********************Funktionen SvNumFor******************************/ 322cdf0e10cSrcweir 323cdf0e10cSrcweir ImpSvNumFor::ImpSvNumFor() 324cdf0e10cSrcweir { 325cdf0e10cSrcweir nAnzStrings = 0; 326cdf0e10cSrcweir aI.nTypeArray = NULL; 327cdf0e10cSrcweir aI.sStrArray = NULL; 328cdf0e10cSrcweir aI.eScannedType = NUMBERFORMAT_UNDEFINED; 329cdf0e10cSrcweir aI.bThousand = sal_False; 330cdf0e10cSrcweir aI.nThousand = 0; 331cdf0e10cSrcweir aI.nCntPre = 0; 332cdf0e10cSrcweir aI.nCntPost = 0; 333cdf0e10cSrcweir aI.nCntExp = 0; 334cdf0e10cSrcweir pColor = NULL; 335cdf0e10cSrcweir } 336cdf0e10cSrcweir 337cdf0e10cSrcweir ImpSvNumFor::~ImpSvNumFor() 338cdf0e10cSrcweir { 339cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nAnzStrings; i++) 340cdf0e10cSrcweir aI.sStrArray[i].Erase(); 341cdf0e10cSrcweir delete [] aI.sStrArray; 342cdf0e10cSrcweir delete [] aI.nTypeArray; 343cdf0e10cSrcweir } 344cdf0e10cSrcweir 345cdf0e10cSrcweir void ImpSvNumFor::Enlarge(sal_uInt16 nAnz) 346cdf0e10cSrcweir { 347cdf0e10cSrcweir if ( nAnzStrings != nAnz ) 348cdf0e10cSrcweir { 349cdf0e10cSrcweir if ( aI.nTypeArray ) 350cdf0e10cSrcweir delete [] aI.nTypeArray; 351cdf0e10cSrcweir if ( aI.sStrArray ) 352cdf0e10cSrcweir delete [] aI.sStrArray; 353cdf0e10cSrcweir nAnzStrings = nAnz; 354cdf0e10cSrcweir if ( nAnz ) 355cdf0e10cSrcweir { 356cdf0e10cSrcweir aI.nTypeArray = new short[nAnz]; 357cdf0e10cSrcweir aI.sStrArray = new String[nAnz]; 358cdf0e10cSrcweir } 359cdf0e10cSrcweir else 360cdf0e10cSrcweir { 361cdf0e10cSrcweir aI.nTypeArray = NULL; 362cdf0e10cSrcweir aI.sStrArray = NULL; 363cdf0e10cSrcweir } 364cdf0e10cSrcweir } 365cdf0e10cSrcweir } 366cdf0e10cSrcweir 367cdf0e10cSrcweir void ImpSvNumFor::Copy( const ImpSvNumFor& rNumFor, ImpSvNumberformatScan* pSc ) 368cdf0e10cSrcweir { 369cdf0e10cSrcweir Enlarge( rNumFor.nAnzStrings ); 370cdf0e10cSrcweir aI.Copy( rNumFor.aI, nAnzStrings ); 371cdf0e10cSrcweir sColorName = rNumFor.sColorName; 372cdf0e10cSrcweir if ( pSc ) 373cdf0e10cSrcweir pColor = pSc->GetColor( sColorName ); // #121103# don't copy pointer between documents 374cdf0e10cSrcweir else 375cdf0e10cSrcweir pColor = rNumFor.pColor; 376cdf0e10cSrcweir aNatNum = rNumFor.aNatNum; 377cdf0e10cSrcweir } 378cdf0e10cSrcweir 379cdf0e10cSrcweir void ImpSvNumFor::Save(SvStream& rStream) const 380cdf0e10cSrcweir { 381cdf0e10cSrcweir rStream << nAnzStrings; 382cdf0e10cSrcweir aI.Save(rStream, nAnzStrings); 383cdf0e10cSrcweir rStream.WriteByteString( sColorName, rStream.GetStreamCharSet() ); 384cdf0e10cSrcweir } 385cdf0e10cSrcweir 386cdf0e10cSrcweir void ImpSvNumFor::Load(SvStream& rStream, ImpSvNumberformatScan& rSc, 387cdf0e10cSrcweir String& rLoadedColorName ) 388cdf0e10cSrcweir { 389cdf0e10cSrcweir sal_uInt16 nAnz; 390cdf0e10cSrcweir rStream >> nAnz; //! noch nicht direkt nAnzStrings wg. Enlarge 391cdf0e10cSrcweir Enlarge( nAnz ); 392cdf0e10cSrcweir aI.Load( rStream, nAnz ); 393cdf0e10cSrcweir rStream.ReadByteString( sColorName, rStream.GetStreamCharSet() ); 394cdf0e10cSrcweir rLoadedColorName = sColorName; 395cdf0e10cSrcweir pColor = rSc.GetColor(sColorName); 396cdf0e10cSrcweir } 397cdf0e10cSrcweir 398cdf0e10cSrcweir 399cdf0e10cSrcweir sal_Bool ImpSvNumFor::HasNewCurrency() const 400cdf0e10cSrcweir { 401cdf0e10cSrcweir for ( sal_uInt16 j=0; j<nAnzStrings; j++ ) 402cdf0e10cSrcweir { 403cdf0e10cSrcweir if ( aI.nTypeArray[j] == NF_SYMBOLTYPE_CURRENCY ) 404cdf0e10cSrcweir return sal_True; 405cdf0e10cSrcweir } 406cdf0e10cSrcweir return sal_False; 407cdf0e10cSrcweir } 408cdf0e10cSrcweir 409cdf0e10cSrcweir 410cdf0e10cSrcweir sal_Bool ImpSvNumFor::GetNewCurrencySymbol( String& rSymbol, 411cdf0e10cSrcweir String& rExtension ) const 412cdf0e10cSrcweir { 413cdf0e10cSrcweir for ( sal_uInt16 j=0; j<nAnzStrings; j++ ) 414cdf0e10cSrcweir { 415cdf0e10cSrcweir if ( aI.nTypeArray[j] == NF_SYMBOLTYPE_CURRENCY ) 416cdf0e10cSrcweir { 417cdf0e10cSrcweir rSymbol = aI.sStrArray[j]; 418cdf0e10cSrcweir if ( j < nAnzStrings-1 && aI.nTypeArray[j+1] == NF_SYMBOLTYPE_CURREXT ) 419cdf0e10cSrcweir rExtension = aI.sStrArray[j+1]; 420cdf0e10cSrcweir else 421cdf0e10cSrcweir rExtension.Erase(); 422cdf0e10cSrcweir return sal_True; 423cdf0e10cSrcweir } 424cdf0e10cSrcweir } 425cdf0e10cSrcweir //! kein Erase an rSymbol, rExtension 426cdf0e10cSrcweir return sal_False; 427cdf0e10cSrcweir } 428cdf0e10cSrcweir 429cdf0e10cSrcweir 430cdf0e10cSrcweir void ImpSvNumFor::SaveNewCurrencyMap( SvStream& rStream ) const 431cdf0e10cSrcweir { 432cdf0e10cSrcweir sal_uInt16 j; 433cdf0e10cSrcweir sal_uInt16 nCnt = 0; 434cdf0e10cSrcweir for ( j=0; j<nAnzStrings; j++ ) 435cdf0e10cSrcweir { 436cdf0e10cSrcweir switch ( aI.nTypeArray[j] ) 437cdf0e10cSrcweir { 438cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRENCY : 439cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRDEL : 440cdf0e10cSrcweir case NF_SYMBOLTYPE_CURREXT : 441cdf0e10cSrcweir nCnt++; 442cdf0e10cSrcweir break; 443cdf0e10cSrcweir } 444cdf0e10cSrcweir } 445cdf0e10cSrcweir rStream << nCnt; 446cdf0e10cSrcweir for ( j=0; j<nAnzStrings; j++ ) 447cdf0e10cSrcweir { 448cdf0e10cSrcweir switch ( aI.nTypeArray[j] ) 449cdf0e10cSrcweir { 450cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRENCY : 451cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRDEL : 452cdf0e10cSrcweir case NF_SYMBOLTYPE_CURREXT : 453cdf0e10cSrcweir rStream << j << aI.nTypeArray[j]; 454cdf0e10cSrcweir break; 455cdf0e10cSrcweir } 456cdf0e10cSrcweir } 457cdf0e10cSrcweir } 458cdf0e10cSrcweir 459cdf0e10cSrcweir 460cdf0e10cSrcweir void ImpSvNumFor::LoadNewCurrencyMap( SvStream& rStream ) 461cdf0e10cSrcweir { 462cdf0e10cSrcweir sal_uInt16 nCnt; 463cdf0e10cSrcweir rStream >> nCnt; 464cdf0e10cSrcweir for ( sal_uInt16 j=0; j<nCnt; j++ ) 465cdf0e10cSrcweir { 466cdf0e10cSrcweir sal_uInt16 nPos; 467cdf0e10cSrcweir short nType; 468cdf0e10cSrcweir rStream >> nPos >> nType; 469cdf0e10cSrcweir if ( nPos < nAnzStrings ) 470cdf0e10cSrcweir aI.nTypeArray[nPos] = nType; 471cdf0e10cSrcweir } 472cdf0e10cSrcweir } 473cdf0e10cSrcweir 474cdf0e10cSrcweir 475cdf0e10cSrcweir /***********************Funktionen SvNumberformat************************/ 476cdf0e10cSrcweir 477cdf0e10cSrcweir enum BracketFormatSymbolType 478cdf0e10cSrcweir { 479cdf0e10cSrcweir BRACKET_SYMBOLTYPE_FORMAT = -1, // subformat string 480cdf0e10cSrcweir BRACKET_SYMBOLTYPE_COLOR = -2, // color 481cdf0e10cSrcweir BRACKET_SYMBOLTYPE_ERROR = -3, // error 482cdf0e10cSrcweir BRACKET_SYMBOLTYPE_DBNUM1 = -4, // DoubleByteNumber, represent numbers 483cdf0e10cSrcweir BRACKET_SYMBOLTYPE_DBNUM2 = -5, // using CJK characters, Excel compatible. 484cdf0e10cSrcweir BRACKET_SYMBOLTYPE_DBNUM3 = -6, 485cdf0e10cSrcweir BRACKET_SYMBOLTYPE_DBNUM4 = -7, 486cdf0e10cSrcweir BRACKET_SYMBOLTYPE_DBNUM5 = -8, 487cdf0e10cSrcweir BRACKET_SYMBOLTYPE_DBNUM6 = -9, 488cdf0e10cSrcweir BRACKET_SYMBOLTYPE_DBNUM7 = -10, 489cdf0e10cSrcweir BRACKET_SYMBOLTYPE_DBNUM8 = -11, 490cdf0e10cSrcweir BRACKET_SYMBOLTYPE_DBNUM9 = -12, 491cdf0e10cSrcweir BRACKET_SYMBOLTYPE_LOCALE = -13, 492cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM0 = -14, // Our NativeNumber support, ASCII 493cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM1 = -15, // Our NativeNumber support, represent 494cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM2 = -16, // numbers using CJK, CTL, ... 495cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM3 = -17, 496cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM4 = -18, 497cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM5 = -19, 498cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM6 = -20, 499cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM7 = -21, 500cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM8 = -22, 501cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM9 = -23, 502cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM10 = -24, 503cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM11 = -25, 504cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM12 = -26, 505cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM13 = -27, 506cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM14 = -28, 507cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM15 = -29, 508cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM16 = -30, 509cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM17 = -31, 510cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM18 = -32, 511cdf0e10cSrcweir BRACKET_SYMBOLTYPE_NATNUM19 = -33 512cdf0e10cSrcweir }; 513cdf0e10cSrcweir 514cdf0e10cSrcweir SvNumberformat::SvNumberformat( ImpSvNumberformatScan& rSc, LanguageType eLge ) 515cdf0e10cSrcweir : 516cdf0e10cSrcweir rScan(rSc), 517cdf0e10cSrcweir eLnge(eLge), 518cdf0e10cSrcweir nNewStandardDefined(0), 519cdf0e10cSrcweir bStarFlag( sal_False ) 520cdf0e10cSrcweir { 521cdf0e10cSrcweir } 522cdf0e10cSrcweir 523cdf0e10cSrcweir void SvNumberformat::ImpCopyNumberformat( const SvNumberformat& rFormat ) 524cdf0e10cSrcweir { 525cdf0e10cSrcweir sFormatstring = rFormat.sFormatstring; 526cdf0e10cSrcweir eType = rFormat.eType; 527cdf0e10cSrcweir eLnge = rFormat.eLnge; 528cdf0e10cSrcweir fLimit1 = rFormat.fLimit1; 529cdf0e10cSrcweir fLimit2 = rFormat.fLimit2; 530cdf0e10cSrcweir eOp1 = rFormat.eOp1; 531cdf0e10cSrcweir eOp2 = rFormat.eOp2; 532cdf0e10cSrcweir bStandard = rFormat.bStandard; 533cdf0e10cSrcweir bIsUsed = rFormat.bIsUsed; 534cdf0e10cSrcweir sComment = rFormat.sComment; 535cdf0e10cSrcweir nNewStandardDefined = rFormat.nNewStandardDefined; 536cdf0e10cSrcweir 537cdf0e10cSrcweir // #121103# when copying between documents, get color pointers from own scanner 538cdf0e10cSrcweir ImpSvNumberformatScan* pColorSc = ( &rScan != &rFormat.rScan ) ? &rScan : NULL; 539cdf0e10cSrcweir 540cdf0e10cSrcweir for (sal_uInt16 i = 0; i < 4; i++) 541cdf0e10cSrcweir NumFor[i].Copy(rFormat.NumFor[i], pColorSc); 542cdf0e10cSrcweir } 543cdf0e10cSrcweir 544cdf0e10cSrcweir SvNumberformat::SvNumberformat( SvNumberformat& rFormat ) 545cdf0e10cSrcweir : rScan(rFormat.rScan), bStarFlag( rFormat.bStarFlag ) 546cdf0e10cSrcweir { 547cdf0e10cSrcweir ImpCopyNumberformat( rFormat ); 548cdf0e10cSrcweir } 549cdf0e10cSrcweir 550cdf0e10cSrcweir SvNumberformat::SvNumberformat( SvNumberformat& rFormat, ImpSvNumberformatScan& rSc ) 551cdf0e10cSrcweir : rScan(rSc), bStarFlag( rFormat.bStarFlag ) 552cdf0e10cSrcweir { 553cdf0e10cSrcweir ImpCopyNumberformat( rFormat ); 554cdf0e10cSrcweir } 555cdf0e10cSrcweir 556cdf0e10cSrcweir 557cdf0e10cSrcweir sal_Bool lcl_SvNumberformat_IsBracketedPrefix( short nSymbolType ) 558cdf0e10cSrcweir { 559cdf0e10cSrcweir if ( nSymbolType > 0 ) 560cdf0e10cSrcweir return sal_True; // conditions 561cdf0e10cSrcweir switch ( nSymbolType ) 562cdf0e10cSrcweir { 563cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_COLOR : 564cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_DBNUM1 : 565cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_DBNUM2 : 566cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_DBNUM3 : 567cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_DBNUM4 : 568cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_DBNUM5 : 569cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_DBNUM6 : 570cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_DBNUM7 : 571cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_DBNUM8 : 572cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_DBNUM9 : 573cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_LOCALE : 574cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM0 : 575cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM1 : 576cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM2 : 577cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM3 : 578cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM4 : 579cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM5 : 580cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM6 : 581cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM7 : 582cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM8 : 583cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM9 : 584cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM10 : 585cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM11 : 586cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM12 : 587cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM13 : 588cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM14 : 589cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM15 : 590cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM16 : 591cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM17 : 592cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM18 : 593cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM19 : 594cdf0e10cSrcweir return sal_True; 595cdf0e10cSrcweir } 596cdf0e10cSrcweir return sal_False; 597cdf0e10cSrcweir } 598cdf0e10cSrcweir 599cdf0e10cSrcweir 600cdf0e10cSrcweir SvNumberformat::SvNumberformat(String& rString, 601cdf0e10cSrcweir ImpSvNumberformatScan* pSc, 602cdf0e10cSrcweir ImpSvNumberInputScan* pISc, 603cdf0e10cSrcweir xub_StrLen& nCheckPos, 604cdf0e10cSrcweir LanguageType& eLan, 605cdf0e10cSrcweir sal_Bool bStan) 606cdf0e10cSrcweir : 607cdf0e10cSrcweir rScan(*pSc), 608cdf0e10cSrcweir nNewStandardDefined(0), 609cdf0e10cSrcweir bStarFlag( sal_False ) 610cdf0e10cSrcweir { 611cdf0e10cSrcweir // If the group (AKA thousand) separator is a Non-Breaking Space (French) 612cdf0e10cSrcweir // replace all occurences by a simple space. 613cdf0e10cSrcweir // The tokens will be changed to the LocaleData separator again later on. 614cdf0e10cSrcweir const sal_Unicode cNBSp = 0xA0; 615cdf0e10cSrcweir const String& rThSep = GetFormatter().GetNumThousandSep(); 616cdf0e10cSrcweir if ( rThSep.GetChar(0) == cNBSp && rThSep.Len() == 1 ) 617cdf0e10cSrcweir { 618cdf0e10cSrcweir xub_StrLen nIndex = 0; 619cdf0e10cSrcweir do 620cdf0e10cSrcweir nIndex = rString.SearchAndReplace( cNBSp, ' ', nIndex ); 621cdf0e10cSrcweir while ( nIndex != STRING_NOTFOUND ); 622cdf0e10cSrcweir } 623cdf0e10cSrcweir 624cdf0e10cSrcweir if (rScan.GetConvertMode()) 625cdf0e10cSrcweir { 626cdf0e10cSrcweir eLnge = rScan.GetNewLnge(); 627cdf0e10cSrcweir eLan = eLnge; // Wechsel auch zurueckgeben 628cdf0e10cSrcweir } 629cdf0e10cSrcweir else 630cdf0e10cSrcweir eLnge = eLan; 631cdf0e10cSrcweir bStandard = bStan; 632cdf0e10cSrcweir bIsUsed = sal_False; 633cdf0e10cSrcweir fLimit1 = 0.0; 634cdf0e10cSrcweir fLimit2 = 0.0; 635cdf0e10cSrcweir eOp1 = NUMBERFORMAT_OP_NO; 636cdf0e10cSrcweir eOp2 = NUMBERFORMAT_OP_NO; 637cdf0e10cSrcweir eType = NUMBERFORMAT_DEFINED; 638cdf0e10cSrcweir 639cdf0e10cSrcweir sal_Bool bCancel = sal_False; 640cdf0e10cSrcweir sal_Bool bCondition = sal_False; 641cdf0e10cSrcweir short eSymbolType; 642cdf0e10cSrcweir xub_StrLen nPos = 0; 643cdf0e10cSrcweir xub_StrLen nPosOld; 644cdf0e10cSrcweir nCheckPos = 0; 645cdf0e10cSrcweir String aComment; 646cdf0e10cSrcweir 647cdf0e10cSrcweir // Split into 4 sub formats 648cdf0e10cSrcweir sal_uInt16 nIndex; 649cdf0e10cSrcweir for ( nIndex = 0; nIndex < 4 && !bCancel; nIndex++ ) 650cdf0e10cSrcweir { 651cdf0e10cSrcweir // Original language/country may have to be reestablished 652cdf0e10cSrcweir if (rScan.GetConvertMode()) 653cdf0e10cSrcweir (rScan.GetNumberformatter())->ChangeIntl(rScan.GetTmpLnge()); 654cdf0e10cSrcweir 655cdf0e10cSrcweir String sStr; 656cdf0e10cSrcweir nPosOld = nPos; // Start position of substring 657cdf0e10cSrcweir // first get bracketed prefixes; e.g. conditions, color 658cdf0e10cSrcweir do 659cdf0e10cSrcweir { 660cdf0e10cSrcweir eSymbolType = ImpNextSymbol(rString, nPos, sStr); 661cdf0e10cSrcweir if (eSymbolType > 0) // condition 662cdf0e10cSrcweir { 663cdf0e10cSrcweir if ( nIndex == 0 && !bCondition ) 664cdf0e10cSrcweir { 665cdf0e10cSrcweir bCondition = sal_True; 666cdf0e10cSrcweir eOp1 = (SvNumberformatLimitOps) eSymbolType; 667cdf0e10cSrcweir } 668cdf0e10cSrcweir else if ( nIndex == 1 && bCondition ) 669cdf0e10cSrcweir eOp2 = (SvNumberformatLimitOps) eSymbolType; 670cdf0e10cSrcweir else // error 671cdf0e10cSrcweir { 672cdf0e10cSrcweir bCancel = sal_True; // break for 673cdf0e10cSrcweir nCheckPos = nPosOld; 674cdf0e10cSrcweir } 675cdf0e10cSrcweir if (!bCancel) 676cdf0e10cSrcweir { 677cdf0e10cSrcweir double fNumber; 678cdf0e10cSrcweir xub_StrLen nAnzChars = ImpGetNumber(rString, nPos, sStr); 679cdf0e10cSrcweir if (nAnzChars > 0) 680cdf0e10cSrcweir { 681cdf0e10cSrcweir short F_Type = NUMBERFORMAT_UNDEFINED; 682cdf0e10cSrcweir if (!pISc->IsNumberFormat(sStr,F_Type,fNumber) || 683cdf0e10cSrcweir ( F_Type != NUMBERFORMAT_NUMBER && 684cdf0e10cSrcweir F_Type != NUMBERFORMAT_SCIENTIFIC) ) 685cdf0e10cSrcweir { 686cdf0e10cSrcweir fNumber = 0.0; 687cdf0e10cSrcweir nPos = nPos - nAnzChars; 688cdf0e10cSrcweir rString.Erase(nPos, nAnzChars); 689cdf0e10cSrcweir rString.Insert('0',nPos); 690cdf0e10cSrcweir nPos++; 691cdf0e10cSrcweir } 692cdf0e10cSrcweir } 693cdf0e10cSrcweir else 694cdf0e10cSrcweir { 695cdf0e10cSrcweir fNumber = 0.0; 696cdf0e10cSrcweir rString.Insert('0',nPos++); 697cdf0e10cSrcweir } 698cdf0e10cSrcweir if (nIndex == 0) 699cdf0e10cSrcweir fLimit1 = fNumber; 700cdf0e10cSrcweir else 701cdf0e10cSrcweir fLimit2 = fNumber; 702cdf0e10cSrcweir if ( rString.GetChar(nPos) == ']' ) 703cdf0e10cSrcweir nPos++; 704cdf0e10cSrcweir else 705cdf0e10cSrcweir { 706cdf0e10cSrcweir bCancel = sal_True; // break for 707cdf0e10cSrcweir nCheckPos = nPos; 708cdf0e10cSrcweir } 709cdf0e10cSrcweir } 710cdf0e10cSrcweir nPosOld = nPos; // position before string 711cdf0e10cSrcweir } 712cdf0e10cSrcweir else if ( lcl_SvNumberformat_IsBracketedPrefix( eSymbolType ) ) 713cdf0e10cSrcweir { 714cdf0e10cSrcweir switch ( eSymbolType ) 715cdf0e10cSrcweir { 716cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_COLOR : 717cdf0e10cSrcweir { 718cdf0e10cSrcweir if ( NumFor[nIndex].GetColor() != NULL ) 719cdf0e10cSrcweir { // error, more than one color 720cdf0e10cSrcweir bCancel = sal_True; // break for 721cdf0e10cSrcweir nCheckPos = nPosOld; 722cdf0e10cSrcweir } 723cdf0e10cSrcweir else 724cdf0e10cSrcweir { 725cdf0e10cSrcweir Color* pColor = pSc->GetColor( sStr); 726cdf0e10cSrcweir NumFor[nIndex].SetColor( pColor, sStr); 727cdf0e10cSrcweir if (pColor == NULL) 728cdf0e10cSrcweir { // error 729cdf0e10cSrcweir bCancel = sal_True; // break for 730cdf0e10cSrcweir nCheckPos = nPosOld; 731cdf0e10cSrcweir } 732cdf0e10cSrcweir } 733cdf0e10cSrcweir } 734cdf0e10cSrcweir break; 735cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM0 : 736cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM1 : 737cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM2 : 738cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM3 : 739cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM4 : 740cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM5 : 741cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM6 : 742cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM7 : 743cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM8 : 744cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM9 : 745cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM10 : 746cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM11 : 747cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM12 : 748cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM13 : 749cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM14 : 750cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM15 : 751cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM16 : 752cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM17 : 753cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM18 : 754cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_NATNUM19 : 755cdf0e10cSrcweir { 756cdf0e10cSrcweir if ( NumFor[nIndex].GetNatNum().IsSet() ) 757cdf0e10cSrcweir { 758cdf0e10cSrcweir bCancel = sal_True; // break for 759cdf0e10cSrcweir nCheckPos = nPosOld; 760cdf0e10cSrcweir } 761cdf0e10cSrcweir else 762cdf0e10cSrcweir { 763cdf0e10cSrcweir sStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NatNum" ) ); 764cdf0e10cSrcweir //! eSymbolType is negative 765cdf0e10cSrcweir sal_uInt8 nNum = sal::static_int_cast< sal_uInt8 >(0 - (eSymbolType - BRACKET_SYMBOLTYPE_NATNUM0)); 766cdf0e10cSrcweir sStr += String::CreateFromInt32( nNum ); 767cdf0e10cSrcweir NumFor[nIndex].SetNatNumNum( nNum, sal_False ); 768cdf0e10cSrcweir } 769cdf0e10cSrcweir } 770cdf0e10cSrcweir break; 771cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_DBNUM1 : 772cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_DBNUM2 : 773cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_DBNUM3 : 774cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_DBNUM4 : 775cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_DBNUM5 : 776cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_DBNUM6 : 777cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_DBNUM7 : 778cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_DBNUM8 : 779cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_DBNUM9 : 780cdf0e10cSrcweir { 781cdf0e10cSrcweir if ( NumFor[nIndex].GetNatNum().IsSet() ) 782cdf0e10cSrcweir { 783cdf0e10cSrcweir bCancel = sal_True; // break for 784cdf0e10cSrcweir nCheckPos = nPosOld; 785cdf0e10cSrcweir } 786cdf0e10cSrcweir else 787cdf0e10cSrcweir { 788cdf0e10cSrcweir sStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DBNum" ) ); 789cdf0e10cSrcweir //! eSymbolType is negative 790cdf0e10cSrcweir sal_uInt8 nNum = sal::static_int_cast< sal_uInt8 >(1 - (eSymbolType - BRACKET_SYMBOLTYPE_DBNUM1)); 791cdf0e10cSrcweir sStr += static_cast< sal_Unicode >('0' + nNum); 792cdf0e10cSrcweir NumFor[nIndex].SetNatNumNum( nNum, sal_True ); 793cdf0e10cSrcweir } 794cdf0e10cSrcweir } 795cdf0e10cSrcweir break; 796cdf0e10cSrcweir case BRACKET_SYMBOLTYPE_LOCALE : 797cdf0e10cSrcweir { 798cdf0e10cSrcweir if ( NumFor[nIndex].GetNatNum().GetLang() != LANGUAGE_DONTKNOW ) 799cdf0e10cSrcweir { 800cdf0e10cSrcweir bCancel = sal_True; // break for 801cdf0e10cSrcweir nCheckPos = nPosOld; 802cdf0e10cSrcweir } 803cdf0e10cSrcweir else 804cdf0e10cSrcweir { 805cdf0e10cSrcweir xub_StrLen nTmp = 2; 806cdf0e10cSrcweir LanguageType eLang = ImpGetLanguageType( sStr, nTmp ); 807cdf0e10cSrcweir if ( eLang == LANGUAGE_DONTKNOW ) 808cdf0e10cSrcweir { 809cdf0e10cSrcweir bCancel = sal_True; // break for 810cdf0e10cSrcweir nCheckPos = nPosOld; 811cdf0e10cSrcweir } 812cdf0e10cSrcweir else 813cdf0e10cSrcweir { 814cdf0e10cSrcweir sStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "$-" ) ); 815cdf0e10cSrcweir sStr += String::CreateFromInt32( sal_Int32( eLang ), 16 ).ToUpperAscii(); 816cdf0e10cSrcweir NumFor[nIndex].SetNatNumLang( eLang ); 817cdf0e10cSrcweir } 818cdf0e10cSrcweir } 819cdf0e10cSrcweir } 820cdf0e10cSrcweir break; 821cdf0e10cSrcweir } 822cdf0e10cSrcweir if ( !bCancel ) 823cdf0e10cSrcweir { 824cdf0e10cSrcweir rString.Erase(nPosOld,nPos-nPosOld); 825cdf0e10cSrcweir rString.Insert(sStr,nPosOld); 826cdf0e10cSrcweir nPos = nPosOld + sStr.Len(); 827cdf0e10cSrcweir rString.Insert(']', nPos); 828cdf0e10cSrcweir rString.Insert('[', nPosOld); 829cdf0e10cSrcweir nPos += 2; 830cdf0e10cSrcweir nPosOld = nPos; // position before string 831cdf0e10cSrcweir } 832cdf0e10cSrcweir } 833cdf0e10cSrcweir } while ( !bCancel && lcl_SvNumberformat_IsBracketedPrefix( eSymbolType ) ); 834cdf0e10cSrcweir 835cdf0e10cSrcweir // The remaining format code string 836cdf0e10cSrcweir if ( !bCancel ) 837cdf0e10cSrcweir { 838cdf0e10cSrcweir if (eSymbolType == BRACKET_SYMBOLTYPE_FORMAT) 839cdf0e10cSrcweir { 840cdf0e10cSrcweir if (nIndex == 1 && eOp1 == NUMBERFORMAT_OP_NO) 841cdf0e10cSrcweir eOp1 = NUMBERFORMAT_OP_GT; // undefined condition, default: > 0 842cdf0e10cSrcweir else if (nIndex == 2 && eOp2 == NUMBERFORMAT_OP_NO) 843cdf0e10cSrcweir eOp2 = NUMBERFORMAT_OP_LT; // undefined condition, default: < 0 844cdf0e10cSrcweir if (sStr.Len() == 0) 845cdf0e10cSrcweir { // empty sub format 846cdf0e10cSrcweir } 847cdf0e10cSrcweir else 848cdf0e10cSrcweir { 849cdf0e10cSrcweir xub_StrLen nStrPos = pSc->ScanFormat( sStr, aComment ); 850cdf0e10cSrcweir sal_uInt16 nAnz = pSc->GetAnzResStrings(); 851cdf0e10cSrcweir if (nAnz == 0) // error 852cdf0e10cSrcweir nStrPos = 1; 853cdf0e10cSrcweir if (nStrPos == 0) // ok 854cdf0e10cSrcweir { 855cdf0e10cSrcweir // e.g. Thai T speciality 856cdf0e10cSrcweir if (pSc->GetNatNumModifier() && !NumFor[nIndex].GetNatNum().IsSet()) 857cdf0e10cSrcweir { 858cdf0e10cSrcweir String aNat( RTL_CONSTASCII_USTRINGPARAM( "[NatNum")); 859cdf0e10cSrcweir aNat += String::CreateFromInt32( pSc->GetNatNumModifier()); 860cdf0e10cSrcweir aNat += ']'; 861cdf0e10cSrcweir sStr.Insert( aNat, 0); 862cdf0e10cSrcweir NumFor[nIndex].SetNatNumNum( pSc->GetNatNumModifier(), sal_False ); 863cdf0e10cSrcweir } 864cdf0e10cSrcweir // #i53826# #i42727# For the Thai T speciality we need 865cdf0e10cSrcweir // to freeze the locale and immunize it against 866cdf0e10cSrcweir // conversions during exports, just in case we want to 867cdf0e10cSrcweir // save to Xcl. This disables the feature of being able 868cdf0e10cSrcweir // to convert a NatNum to another locale. You can't 869cdf0e10cSrcweir // have both. 870cdf0e10cSrcweir // FIXME: implement a specialized export conversion 871cdf0e10cSrcweir // that works on tokens (have to tokenize all first) 872cdf0e10cSrcweir // and doesn't use the format string and 873cdf0e10cSrcweir // PutandConvertEntry() to LANGUAGE_ENGLISH_US in 874cdf0e10cSrcweir // sc/source/filter/excel/xestyle.cxx 875cdf0e10cSrcweir // XclExpNumFmtBuffer::WriteFormatRecord(). 876cdf0e10cSrcweir LanguageType eLanguage; 877cdf0e10cSrcweir if (NumFor[nIndex].GetNatNum().GetNatNum() == 1 && 878cdf0e10cSrcweir ((eLanguage = 879cdf0e10cSrcweir MsLangId::getRealLanguage( eLan)) 880cdf0e10cSrcweir == LANGUAGE_THAI) && 881cdf0e10cSrcweir NumFor[nIndex].GetNatNum().GetLang() == 882cdf0e10cSrcweir LANGUAGE_DONTKNOW) 883cdf0e10cSrcweir { 884cdf0e10cSrcweir String aLID( RTL_CONSTASCII_USTRINGPARAM( "[$-")); 885cdf0e10cSrcweir aLID += String::CreateFromInt32( sal_Int32( 886cdf0e10cSrcweir eLanguage), 16 ).ToUpperAscii(); 887cdf0e10cSrcweir aLID += ']'; 888cdf0e10cSrcweir sStr.Insert( aLID, 0); 889cdf0e10cSrcweir NumFor[nIndex].SetNatNumLang( eLanguage); 890cdf0e10cSrcweir } 891cdf0e10cSrcweir rString.Erase(nPosOld,nPos-nPosOld); 892cdf0e10cSrcweir rString.Insert(sStr,nPosOld); 893cdf0e10cSrcweir nPos = nPosOld + sStr.Len(); 894cdf0e10cSrcweir if (nPos < rString.Len()) 895cdf0e10cSrcweir { 896cdf0e10cSrcweir rString.Insert(';',nPos); 897cdf0e10cSrcweir nPos++; 898cdf0e10cSrcweir } 899cdf0e10cSrcweir NumFor[nIndex].Enlarge(nAnz); 900cdf0e10cSrcweir pSc->CopyInfo(&(NumFor[nIndex].Info()), nAnz); 901cdf0e10cSrcweir // type check 902cdf0e10cSrcweir if (nIndex == 0) 903cdf0e10cSrcweir eType = (short) NumFor[nIndex].Info().eScannedType; 904cdf0e10cSrcweir else if (nIndex == 3) 905cdf0e10cSrcweir { // #77026# Everything recognized IS text 906cdf0e10cSrcweir NumFor[nIndex].Info().eScannedType = NUMBERFORMAT_TEXT; 907cdf0e10cSrcweir } 908cdf0e10cSrcweir else if ( (short) NumFor[nIndex].Info().eScannedType != 909cdf0e10cSrcweir eType) 910cdf0e10cSrcweir eType = NUMBERFORMAT_DEFINED; 911cdf0e10cSrcweir } 912cdf0e10cSrcweir else 913cdf0e10cSrcweir { 914cdf0e10cSrcweir nCheckPos = nPosOld + nStrPos; // error in string 915cdf0e10cSrcweir bCancel = sal_True; // break for 916cdf0e10cSrcweir } 917cdf0e10cSrcweir } 918cdf0e10cSrcweir } 919cdf0e10cSrcweir else if (eSymbolType == BRACKET_SYMBOLTYPE_ERROR) // error 920cdf0e10cSrcweir { 921cdf0e10cSrcweir nCheckPos = nPosOld; 922cdf0e10cSrcweir bCancel = sal_True; 923cdf0e10cSrcweir } 924cdf0e10cSrcweir else if ( lcl_SvNumberformat_IsBracketedPrefix( eSymbolType ) ) 925cdf0e10cSrcweir { 926cdf0e10cSrcweir nCheckPos = nPosOld+1; // error, prefix in string 927cdf0e10cSrcweir bCancel = sal_True; // break for 928cdf0e10cSrcweir } 929cdf0e10cSrcweir } 930cdf0e10cSrcweir if ( bCancel && !nCheckPos ) 931cdf0e10cSrcweir nCheckPos = 1; // nCheckPos is used as an error condition 932cdf0e10cSrcweir if ( !bCancel ) 933cdf0e10cSrcweir { 934cdf0e10cSrcweir if ( NumFor[nIndex].GetNatNum().IsSet() && 935cdf0e10cSrcweir NumFor[nIndex].GetNatNum().GetLang() == LANGUAGE_DONTKNOW ) 936cdf0e10cSrcweir NumFor[nIndex].SetNatNumLang( eLan ); 937cdf0e10cSrcweir } 938cdf0e10cSrcweir if (rString.Len() == nPos) 939cdf0e10cSrcweir { 940cdf0e10cSrcweir if ( nIndex == 2 && eSymbolType == BRACKET_SYMBOLTYPE_FORMAT && 941cdf0e10cSrcweir rString.GetChar(nPos-1) == ';' ) 942cdf0e10cSrcweir { // #83510# A 4th subformat explicitly specified to be empty 943cdf0e10cSrcweir // hides any text. Need the type here for HasTextFormat() 944cdf0e10cSrcweir NumFor[3].Info().eScannedType = NUMBERFORMAT_TEXT; 945cdf0e10cSrcweir } 946cdf0e10cSrcweir bCancel = sal_True; 947cdf0e10cSrcweir } 948cdf0e10cSrcweir if ( NumFor[nIndex].GetNatNum().IsSet() ) 949cdf0e10cSrcweir NumFor[nIndex].SetNatNumDate( 950cdf0e10cSrcweir (NumFor[nIndex].Info().eScannedType & NUMBERFORMAT_DATE) != 0 ); 951cdf0e10cSrcweir } 952cdf0e10cSrcweir 953cdf0e10cSrcweir if ( bCondition && !nCheckPos ) 954cdf0e10cSrcweir { 955cdf0e10cSrcweir if ( nIndex == 1 && NumFor[0].GetnAnz() == 0 && 956cdf0e10cSrcweir rString.GetChar(rString.Len()-1) != ';' ) 957cdf0e10cSrcweir { // No format code => GENERAL but not if specified empty 958cdf0e10cSrcweir String aAdd( pSc->GetStandardName() ); 959cdf0e10cSrcweir String aTmp; 960cdf0e10cSrcweir if ( !pSc->ScanFormat( aAdd, aTmp ) ) 961cdf0e10cSrcweir { 962cdf0e10cSrcweir sal_uInt16 nAnz = pSc->GetAnzResStrings(); 963cdf0e10cSrcweir if ( nAnz ) 964cdf0e10cSrcweir { 965cdf0e10cSrcweir NumFor[0].Enlarge(nAnz); 966cdf0e10cSrcweir pSc->CopyInfo( &(NumFor[0].Info()), nAnz ); 967cdf0e10cSrcweir rString += aAdd; 968cdf0e10cSrcweir } 969cdf0e10cSrcweir } 970cdf0e10cSrcweir } 971cdf0e10cSrcweir else if ( nIndex == 1 && NumFor[nIndex].GetnAnz() == 0 && 972cdf0e10cSrcweir rString.GetChar(rString.Len()-1) != ';' && 973cdf0e10cSrcweir (NumFor[0].GetnAnz() > 1 || (NumFor[0].GetnAnz() == 1 && 974cdf0e10cSrcweir NumFor[0].Info().nTypeArray[0] != NF_KEY_GENERAL)) ) 975cdf0e10cSrcweir { // No trailing second subformat => GENERAL but not if specified empty 976cdf0e10cSrcweir // and not if first subformat is GENERAL 977cdf0e10cSrcweir String aAdd( pSc->GetStandardName() ); 978cdf0e10cSrcweir String aTmp; 979cdf0e10cSrcweir if ( !pSc->ScanFormat( aAdd, aTmp ) ) 980cdf0e10cSrcweir { 981cdf0e10cSrcweir sal_uInt16 nAnz = pSc->GetAnzResStrings(); 982cdf0e10cSrcweir if ( nAnz ) 983cdf0e10cSrcweir { 984cdf0e10cSrcweir NumFor[nIndex].Enlarge(nAnz); 985cdf0e10cSrcweir pSc->CopyInfo( &(NumFor[nIndex].Info()), nAnz ); 986cdf0e10cSrcweir rString += ';'; 987cdf0e10cSrcweir rString += aAdd; 988cdf0e10cSrcweir } 989cdf0e10cSrcweir } 990cdf0e10cSrcweir } 991cdf0e10cSrcweir else if ( nIndex == 2 && NumFor[nIndex].GetnAnz() == 0 && 992cdf0e10cSrcweir rString.GetChar(rString.Len()-1) != ';' && 993cdf0e10cSrcweir eOp2 != NUMBERFORMAT_OP_NO ) 994cdf0e10cSrcweir { // No trailing third subformat => GENERAL but not if specified empty 995cdf0e10cSrcweir String aAdd( pSc->GetStandardName() ); 996cdf0e10cSrcweir String aTmp; 997cdf0e10cSrcweir if ( !pSc->ScanFormat( aAdd, aTmp ) ) 998cdf0e10cSrcweir { 999cdf0e10cSrcweir sal_uInt16 nAnz = pSc->GetAnzResStrings(); 1000cdf0e10cSrcweir if ( nAnz ) 1001cdf0e10cSrcweir { 1002cdf0e10cSrcweir NumFor[nIndex].Enlarge(nAnz); 1003cdf0e10cSrcweir pSc->CopyInfo( &(NumFor[nIndex].Info()), nAnz ); 1004cdf0e10cSrcweir rString += ';'; 1005cdf0e10cSrcweir rString += aAdd; 1006cdf0e10cSrcweir } 1007cdf0e10cSrcweir } 1008cdf0e10cSrcweir } 1009cdf0e10cSrcweir } 1010cdf0e10cSrcweir sFormatstring = rString; 1011cdf0e10cSrcweir if ( aComment.Len() ) 1012cdf0e10cSrcweir { 1013cdf0e10cSrcweir SetComment( aComment ); // setzt sComment und sFormatstring 1014cdf0e10cSrcweir rString = sFormatstring; // geaenderten sFormatstring uebernehmen 1015cdf0e10cSrcweir } 1016cdf0e10cSrcweir if (NumFor[2].GetnAnz() == 0 && // kein 3. Teilstring 1017cdf0e10cSrcweir eOp1 == NUMBERFORMAT_OP_GT && eOp2 == NUMBERFORMAT_OP_NO && 1018cdf0e10cSrcweir fLimit1 == 0.0 && fLimit2 == 0.0) 1019cdf0e10cSrcweir eOp1 = NUMBERFORMAT_OP_GE; // 0 zum ersten Format dazu 1020cdf0e10cSrcweir 1021cdf0e10cSrcweir } 1022cdf0e10cSrcweir 1023cdf0e10cSrcweir SvNumberformat::~SvNumberformat() 1024cdf0e10cSrcweir { 1025cdf0e10cSrcweir } 1026cdf0e10cSrcweir 1027cdf0e10cSrcweir //--------------------------------------------------------------------------- 1028cdf0e10cSrcweir // Next_Symbol 1029cdf0e10cSrcweir //--------------------------------------------------------------------------- 1030cdf0e10cSrcweir // Zerlegt die Eingabe in Symbole fuer die weitere 1031cdf0e10cSrcweir // Verarbeitung (Turing-Maschine). 1032cdf0e10cSrcweir //--------------------------------------------------------------------------- 1033cdf0e10cSrcweir // Ausgangs Zustand = SsStart 1034cdf0e10cSrcweir //---------------+-------------------+-----------------------+--------------- 1035cdf0e10cSrcweir // Alter Zustand | gelesenes Zeichen | Aktion | Neuer Zustand 1036cdf0e10cSrcweir //---------------+-------------------+-----------------------+--------------- 1037cdf0e10cSrcweir // SsStart | ; | Pos-- | SsGetString 1038cdf0e10cSrcweir // | [ | Symbol += Zeichen | SsGetBracketed 1039cdf0e10cSrcweir // | ] | Fehler | SsStop 1040cdf0e10cSrcweir // | BLANK | | 1041cdf0e10cSrcweir // | Sonst | Symbol += Zeichen | SsGetString 1042cdf0e10cSrcweir //---------------+-------------------+-----------------------+--------------- 1043cdf0e10cSrcweir // SsGetString | ; | | SsStop 1044cdf0e10cSrcweir // | Sonst | Symbol+=Zeichen | 1045cdf0e10cSrcweir //---------------+-------------------+-----------------------+--------------- 1046cdf0e10cSrcweir // SsGetBracketed| <, > = | del [ | 1047cdf0e10cSrcweir // | | Symbol += Zeichen | SsGetCon 1048cdf0e10cSrcweir // | BLANK | | 1049cdf0e10cSrcweir // | h, H, m, M, s, S | Symbol += Zeichen | SsGetTime 1050cdf0e10cSrcweir // | sonst | del [ | 1051cdf0e10cSrcweir // | | Symbol += Zeichen | SsGetPrefix 1052cdf0e10cSrcweir //---------------+-------------------+-----------------------+--------------- 1053cdf0e10cSrcweir // SsGetTime | ] | Symbol += Zeichen | SsGetString 1054cdf0e10cSrcweir // | h, H, m, M, s, S | Symbol += Zeichen, * | SsGetString 1055cdf0e10cSrcweir // | sonst | del [; Symbol+=Zeichen| SsGetPrefix 1056cdf0e10cSrcweir //---------------+-------------------+-----------------------+--------------- 1057cdf0e10cSrcweir // SsGetPrefix | ] | | SsStop 1058cdf0e10cSrcweir // | sonst | Symbol += Zeichen | 1059cdf0e10cSrcweir //---------------+-------------------+-----------------------+--------------- 1060cdf0e10cSrcweir // SsGetCon | >, = | Symbol+=Zeichen | 1061cdf0e10cSrcweir // | ] | | SsStop 1062cdf0e10cSrcweir // | sonst | Fehler | SsStop 1063cdf0e10cSrcweir //---------------+-------------------+-----------------------+--------------- 1064cdf0e10cSrcweir // * : Sonderbedingung 1065cdf0e10cSrcweir 1066cdf0e10cSrcweir enum ScanState 1067cdf0e10cSrcweir { 1068cdf0e10cSrcweir SsStop, 1069cdf0e10cSrcweir SsStart, 1070cdf0e10cSrcweir SsGetCon, // condition 1071cdf0e10cSrcweir SsGetString, // format string 1072cdf0e10cSrcweir SsGetPrefix, // color or NatNumN 1073cdf0e10cSrcweir SsGetTime, // [HH] for time 1074cdf0e10cSrcweir SsGetBracketed // any [...] not decided yet 1075cdf0e10cSrcweir }; 1076cdf0e10cSrcweir 1077cdf0e10cSrcweir 1078cdf0e10cSrcweir // read a string until ']' and delete spaces in input 1079cdf0e10cSrcweir // static 1080cdf0e10cSrcweir xub_StrLen SvNumberformat::ImpGetNumber(String& rString, 1081cdf0e10cSrcweir xub_StrLen& nPos, 1082cdf0e10cSrcweir String& sSymbol) 1083cdf0e10cSrcweir { 1084cdf0e10cSrcweir xub_StrLen nStartPos = nPos; 1085cdf0e10cSrcweir sal_Unicode cToken; 1086cdf0e10cSrcweir xub_StrLen nLen = rString.Len(); 1087cdf0e10cSrcweir sSymbol.Erase(); 1088cdf0e10cSrcweir while ( nPos < nLen && ((cToken = rString.GetChar(nPos)) != ']') ) 1089cdf0e10cSrcweir { 1090cdf0e10cSrcweir if (cToken == ' ') 1091cdf0e10cSrcweir { // delete spaces 1092cdf0e10cSrcweir rString.Erase(nPos,1); 1093cdf0e10cSrcweir nLen--; 1094cdf0e10cSrcweir } 1095cdf0e10cSrcweir else 1096cdf0e10cSrcweir { 1097cdf0e10cSrcweir nPos++; 1098cdf0e10cSrcweir sSymbol += cToken; 1099cdf0e10cSrcweir } 1100cdf0e10cSrcweir } 1101cdf0e10cSrcweir return nPos - nStartPos; 1102cdf0e10cSrcweir } 1103cdf0e10cSrcweir 1104cdf0e10cSrcweir 1105cdf0e10cSrcweir // static 1106cdf0e10cSrcweir LanguageType SvNumberformat::ImpGetLanguageType( const String& rString, 1107cdf0e10cSrcweir xub_StrLen& nPos ) 1108cdf0e10cSrcweir { 1109cdf0e10cSrcweir sal_Int32 nNum = 0; 1110cdf0e10cSrcweir sal_Unicode cToken = 0; 1111cdf0e10cSrcweir xub_StrLen nLen = rString.Len(); 1112cdf0e10cSrcweir while ( nPos < nLen && ((cToken = rString.GetChar(nPos)) != ']') ) 1113cdf0e10cSrcweir { 1114cdf0e10cSrcweir if ( '0' <= cToken && cToken <= '9' ) 1115cdf0e10cSrcweir { 1116cdf0e10cSrcweir nNum *= 16; 1117cdf0e10cSrcweir nNum += cToken - '0'; 1118cdf0e10cSrcweir } 1119cdf0e10cSrcweir else if ( 'a' <= cToken && cToken <= 'f' ) 1120cdf0e10cSrcweir { 1121cdf0e10cSrcweir nNum *= 16; 1122cdf0e10cSrcweir nNum += cToken - 'a' + 10; 1123cdf0e10cSrcweir } 1124cdf0e10cSrcweir else if ( 'A' <= cToken && cToken <= 'F' ) 1125cdf0e10cSrcweir { 1126cdf0e10cSrcweir nNum *= 16; 1127cdf0e10cSrcweir nNum += cToken - 'A' + 10; 1128cdf0e10cSrcweir } 1129cdf0e10cSrcweir else 1130cdf0e10cSrcweir return LANGUAGE_DONTKNOW; 1131cdf0e10cSrcweir ++nPos; 1132cdf0e10cSrcweir } 1133cdf0e10cSrcweir return (nNum && (cToken == ']' || nPos == nLen)) ? (LanguageType)nNum : 1134cdf0e10cSrcweir LANGUAGE_DONTKNOW; 1135cdf0e10cSrcweir } 1136cdf0e10cSrcweir 1137cdf0e10cSrcweir 1138cdf0e10cSrcweir short SvNumberformat::ImpNextSymbol(String& rString, 1139cdf0e10cSrcweir xub_StrLen& nPos, 1140cdf0e10cSrcweir String& sSymbol) 1141cdf0e10cSrcweir { 1142cdf0e10cSrcweir short eSymbolType = BRACKET_SYMBOLTYPE_FORMAT; 1143cdf0e10cSrcweir sal_Unicode cToken; 1144cdf0e10cSrcweir sal_Unicode cLetter = ' '; // Zwischenergebnis 1145cdf0e10cSrcweir xub_StrLen nLen = rString.Len(); 1146cdf0e10cSrcweir ScanState eState = SsStart; 1147cdf0e10cSrcweir sSymbol.Erase(); 1148cdf0e10cSrcweir const NfKeywordTable & rKeywords = rScan.GetKeywords(); 1149cdf0e10cSrcweir while (nPos < nLen && eState != SsStop) 1150cdf0e10cSrcweir { 1151cdf0e10cSrcweir cToken = rString.GetChar(nPos); 1152cdf0e10cSrcweir nPos++; 1153cdf0e10cSrcweir switch (eState) 1154cdf0e10cSrcweir { 1155cdf0e10cSrcweir case SsStart: 1156cdf0e10cSrcweir { 1157cdf0e10cSrcweir if (cToken == '[') 1158cdf0e10cSrcweir { 1159cdf0e10cSrcweir eState = SsGetBracketed; 1160cdf0e10cSrcweir sSymbol += cToken; 1161cdf0e10cSrcweir } 1162cdf0e10cSrcweir else if (cToken == ';') 1163cdf0e10cSrcweir { 1164cdf0e10cSrcweir eState = SsGetString; 1165cdf0e10cSrcweir nPos--; 1166cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_FORMAT; 1167cdf0e10cSrcweir } 1168cdf0e10cSrcweir else if (cToken == ']') 1169cdf0e10cSrcweir { 1170cdf0e10cSrcweir eState = SsStop; 1171cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_ERROR; 1172cdf0e10cSrcweir } 1173cdf0e10cSrcweir else if (cToken == ' ') // Skip Blanks 1174cdf0e10cSrcweir { 1175cdf0e10cSrcweir rString.Erase(nPos-1,1); 1176cdf0e10cSrcweir nPos--; 1177cdf0e10cSrcweir nLen--; 1178cdf0e10cSrcweir } 1179cdf0e10cSrcweir else 1180cdf0e10cSrcweir { 1181cdf0e10cSrcweir sSymbol += cToken; 1182cdf0e10cSrcweir eState = SsGetString; 1183cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_FORMAT; 1184cdf0e10cSrcweir } 1185cdf0e10cSrcweir } 1186cdf0e10cSrcweir break; 1187cdf0e10cSrcweir case SsGetBracketed: 1188cdf0e10cSrcweir { 1189cdf0e10cSrcweir switch (cToken) 1190cdf0e10cSrcweir { 1191cdf0e10cSrcweir case '<': 1192cdf0e10cSrcweir case '>': 1193cdf0e10cSrcweir case '=': 1194cdf0e10cSrcweir { 1195cdf0e10cSrcweir sSymbol.EraseAllChars('['); 1196cdf0e10cSrcweir sSymbol += cToken; 1197cdf0e10cSrcweir cLetter = cToken; 1198cdf0e10cSrcweir eState = SsGetCon; 1199cdf0e10cSrcweir switch (cToken) 1200cdf0e10cSrcweir { 1201cdf0e10cSrcweir case '<': eSymbolType = NUMBERFORMAT_OP_LT; break; 1202cdf0e10cSrcweir case '>': eSymbolType = NUMBERFORMAT_OP_GT; break; 1203cdf0e10cSrcweir case '=': eSymbolType = NUMBERFORMAT_OP_EQ; break; 1204cdf0e10cSrcweir default: break; 1205cdf0e10cSrcweir } 1206cdf0e10cSrcweir } 1207cdf0e10cSrcweir break; 1208cdf0e10cSrcweir case ' ': 1209cdf0e10cSrcweir { 1210cdf0e10cSrcweir rString.Erase(nPos-1,1); 1211cdf0e10cSrcweir nPos--; 1212cdf0e10cSrcweir nLen--; 1213cdf0e10cSrcweir } 1214cdf0e10cSrcweir break; 1215cdf0e10cSrcweir case '$' : 1216cdf0e10cSrcweir { 1217cdf0e10cSrcweir if ( rString.GetChar(nPos) == '-' ) 1218cdf0e10cSrcweir { // [$-xxx] locale 1219cdf0e10cSrcweir sSymbol.EraseAllChars('['); 1220cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_LOCALE; 1221cdf0e10cSrcweir eState = SsGetPrefix; 1222cdf0e10cSrcweir } 1223cdf0e10cSrcweir else 1224cdf0e10cSrcweir { // currency as of SV_NUMBERFORMATTER_VERSION_NEW_CURR 1225cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_FORMAT; 1226cdf0e10cSrcweir eState = SsGetString; 1227cdf0e10cSrcweir } 1228cdf0e10cSrcweir sSymbol += cToken; 1229cdf0e10cSrcweir } 1230cdf0e10cSrcweir break; 1231cdf0e10cSrcweir case '~' : 1232cdf0e10cSrcweir { // calendarID as of SV_NUMBERFORMATTER_VERSION_CALENDAR 1233cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_FORMAT; 1234cdf0e10cSrcweir sSymbol += cToken; 1235cdf0e10cSrcweir eState = SsGetString; 1236cdf0e10cSrcweir } 1237cdf0e10cSrcweir break; 1238cdf0e10cSrcweir default: 1239cdf0e10cSrcweir { 1240cdf0e10cSrcweir static const String aNatNum( RTL_CONSTASCII_USTRINGPARAM( "NATNUM" ) ); 1241cdf0e10cSrcweir static const String aDBNum( RTL_CONSTASCII_USTRINGPARAM( "DBNUM" ) ); 1242cdf0e10cSrcweir String aUpperNatNum( rChrCls().toUpper( rString, nPos-1, aNatNum.Len() ) ); 1243cdf0e10cSrcweir String aUpperDBNum( rChrCls().toUpper( rString, nPos-1, aDBNum.Len() ) ); 1244cdf0e10cSrcweir sal_Unicode cUpper = aUpperNatNum.GetChar(0); 1245cdf0e10cSrcweir sal_Int32 nNatNumNum = rString.Copy( nPos-1+aNatNum.Len() ).ToInt32(); 1246cdf0e10cSrcweir sal_Unicode cDBNum = rString.GetChar( nPos-1+aDBNum.Len() ); 1247cdf0e10cSrcweir if ( aUpperNatNum == aNatNum && 0 <= nNatNumNum && nNatNumNum <= 19 ) 1248cdf0e10cSrcweir { 1249cdf0e10cSrcweir sSymbol.EraseAllChars('['); 1250cdf0e10cSrcweir sSymbol += rString.Copy( --nPos, aNatNum.Len()+1 ); 1251cdf0e10cSrcweir nPos += aNatNum.Len()+1; 1252cdf0e10cSrcweir //! SymbolType is negative 1253cdf0e10cSrcweir eSymbolType = (short) (BRACKET_SYMBOLTYPE_NATNUM0 - nNatNumNum); 1254cdf0e10cSrcweir eState = SsGetPrefix; 1255cdf0e10cSrcweir } 1256cdf0e10cSrcweir else if ( aUpperDBNum == aDBNum && '1' <= cDBNum && cDBNum <= '9' ) 1257cdf0e10cSrcweir { 1258cdf0e10cSrcweir sSymbol.EraseAllChars('['); 1259cdf0e10cSrcweir sSymbol += rString.Copy( --nPos, aDBNum.Len()+1 ); 1260cdf0e10cSrcweir nPos += aDBNum.Len()+1; 1261cdf0e10cSrcweir //! SymbolType is negative 1262cdf0e10cSrcweir eSymbolType = sal::static_int_cast< short >( 1263cdf0e10cSrcweir BRACKET_SYMBOLTYPE_DBNUM1 - (cDBNum - '1')); 1264cdf0e10cSrcweir eState = SsGetPrefix; 1265cdf0e10cSrcweir } 1266cdf0e10cSrcweir else if (cUpper == rKeywords[NF_KEY_H].GetChar(0) || // H 1267cdf0e10cSrcweir cUpper == rKeywords[NF_KEY_MI].GetChar(0) || // M 1268cdf0e10cSrcweir cUpper == rKeywords[NF_KEY_S].GetChar(0) ) // S 1269cdf0e10cSrcweir { 1270cdf0e10cSrcweir sSymbol += cToken; 1271cdf0e10cSrcweir eState = SsGetTime; 1272cdf0e10cSrcweir cLetter = cToken; 1273cdf0e10cSrcweir } 1274cdf0e10cSrcweir else 1275cdf0e10cSrcweir { 1276cdf0e10cSrcweir sSymbol.EraseAllChars('['); 1277cdf0e10cSrcweir sSymbol += cToken; 1278cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_COLOR; 1279cdf0e10cSrcweir eState = SsGetPrefix; 1280cdf0e10cSrcweir } 1281cdf0e10cSrcweir } 1282cdf0e10cSrcweir break; 1283cdf0e10cSrcweir } 1284cdf0e10cSrcweir } 1285cdf0e10cSrcweir break; 1286cdf0e10cSrcweir case SsGetString: 1287cdf0e10cSrcweir { 1288cdf0e10cSrcweir if (cToken == ';') 1289cdf0e10cSrcweir eState = SsStop; 1290cdf0e10cSrcweir else 1291cdf0e10cSrcweir sSymbol += cToken; 1292cdf0e10cSrcweir } 1293cdf0e10cSrcweir break; 1294cdf0e10cSrcweir case SsGetTime: 1295cdf0e10cSrcweir { 1296cdf0e10cSrcweir if (cToken == ']') 1297cdf0e10cSrcweir { 1298cdf0e10cSrcweir sSymbol += cToken; 1299cdf0e10cSrcweir eState = SsGetString; 1300cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_FORMAT; 1301cdf0e10cSrcweir } 1302cdf0e10cSrcweir else 1303cdf0e10cSrcweir { 1304cdf0e10cSrcweir sal_Unicode cUpper = rChrCls().toUpper( rString, nPos-1, 1 ).GetChar(0); 1305cdf0e10cSrcweir if (cUpper == rKeywords[NF_KEY_H].GetChar(0) || // H 1306cdf0e10cSrcweir cUpper == rKeywords[NF_KEY_MI].GetChar(0) || // M 1307cdf0e10cSrcweir cUpper == rKeywords[NF_KEY_S].GetChar(0) ) // S 1308cdf0e10cSrcweir { 1309cdf0e10cSrcweir if (cLetter == cToken) 1310cdf0e10cSrcweir { 1311cdf0e10cSrcweir sSymbol += cToken; 1312cdf0e10cSrcweir cLetter = ' '; 1313cdf0e10cSrcweir } 1314cdf0e10cSrcweir else 1315cdf0e10cSrcweir { 1316cdf0e10cSrcweir sSymbol.EraseAllChars('['); 1317cdf0e10cSrcweir sSymbol += cToken; 1318cdf0e10cSrcweir eState = SsGetPrefix; 1319cdf0e10cSrcweir } 1320cdf0e10cSrcweir } 1321cdf0e10cSrcweir else 1322cdf0e10cSrcweir { 1323cdf0e10cSrcweir sSymbol.EraseAllChars('['); 1324cdf0e10cSrcweir sSymbol += cToken; 1325cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_COLOR; 1326cdf0e10cSrcweir eState = SsGetPrefix; 1327cdf0e10cSrcweir } 1328cdf0e10cSrcweir } 1329cdf0e10cSrcweir } 1330cdf0e10cSrcweir break; 1331cdf0e10cSrcweir case SsGetCon: 1332cdf0e10cSrcweir { 1333cdf0e10cSrcweir switch (cToken) 1334cdf0e10cSrcweir { 1335cdf0e10cSrcweir case '<': 1336cdf0e10cSrcweir { 1337cdf0e10cSrcweir eState = SsStop; 1338cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_ERROR; 1339cdf0e10cSrcweir } 1340cdf0e10cSrcweir break; 1341cdf0e10cSrcweir case '>': 1342cdf0e10cSrcweir { 1343cdf0e10cSrcweir if (cLetter == '<') 1344cdf0e10cSrcweir { 1345cdf0e10cSrcweir sSymbol += cToken; 1346cdf0e10cSrcweir cLetter = ' '; 1347cdf0e10cSrcweir eState = SsStop; 1348cdf0e10cSrcweir eSymbolType = NUMBERFORMAT_OP_NE; 1349cdf0e10cSrcweir } 1350cdf0e10cSrcweir else 1351cdf0e10cSrcweir { 1352cdf0e10cSrcweir eState = SsStop; 1353cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_ERROR; 1354cdf0e10cSrcweir } 1355cdf0e10cSrcweir } 1356cdf0e10cSrcweir break; 1357cdf0e10cSrcweir case '=': 1358cdf0e10cSrcweir { 1359cdf0e10cSrcweir if (cLetter == '<') 1360cdf0e10cSrcweir { 1361cdf0e10cSrcweir sSymbol += cToken; 1362cdf0e10cSrcweir cLetter = ' '; 1363cdf0e10cSrcweir eSymbolType = NUMBERFORMAT_OP_LE; 1364cdf0e10cSrcweir } 1365cdf0e10cSrcweir else if (cLetter == '>') 1366cdf0e10cSrcweir { 1367cdf0e10cSrcweir sSymbol += cToken; 1368cdf0e10cSrcweir cLetter = ' '; 1369cdf0e10cSrcweir eSymbolType = NUMBERFORMAT_OP_GE; 1370cdf0e10cSrcweir } 1371cdf0e10cSrcweir else 1372cdf0e10cSrcweir { 1373cdf0e10cSrcweir eState = SsStop; 1374cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_ERROR; 1375cdf0e10cSrcweir } 1376cdf0e10cSrcweir } 1377cdf0e10cSrcweir break; 1378cdf0e10cSrcweir case ' ': 1379cdf0e10cSrcweir { 1380cdf0e10cSrcweir rString.Erase(nPos-1,1); 1381cdf0e10cSrcweir nPos--; 1382cdf0e10cSrcweir nLen--; 1383cdf0e10cSrcweir } 1384cdf0e10cSrcweir break; 1385cdf0e10cSrcweir default: 1386cdf0e10cSrcweir { 1387cdf0e10cSrcweir eState = SsStop; 1388cdf0e10cSrcweir nPos--; 1389cdf0e10cSrcweir } 1390cdf0e10cSrcweir break; 1391cdf0e10cSrcweir } 1392cdf0e10cSrcweir } 1393cdf0e10cSrcweir break; 1394cdf0e10cSrcweir case SsGetPrefix: 1395cdf0e10cSrcweir { 1396cdf0e10cSrcweir if (cToken == ']') 1397cdf0e10cSrcweir eState = SsStop; 1398cdf0e10cSrcweir else 1399cdf0e10cSrcweir sSymbol += cToken; 1400cdf0e10cSrcweir } 1401cdf0e10cSrcweir break; 1402cdf0e10cSrcweir default: 1403cdf0e10cSrcweir break; 1404cdf0e10cSrcweir } // of switch 1405cdf0e10cSrcweir } // of while 1406cdf0e10cSrcweir 1407cdf0e10cSrcweir return eSymbolType; 1408cdf0e10cSrcweir } 1409cdf0e10cSrcweir 1410cdf0e10cSrcweir NfHackConversion SvNumberformat::Load( SvStream& rStream, 1411cdf0e10cSrcweir ImpSvNumMultipleReadHeader& rHdr, SvNumberFormatter* pHackConverter, 1412cdf0e10cSrcweir ImpSvNumberInputScan& rISc ) 1413cdf0e10cSrcweir { 1414cdf0e10cSrcweir rHdr.StartEntry(); 1415cdf0e10cSrcweir sal_uInt16 nOp1, nOp2; 1416cdf0e10cSrcweir SvNumberformat::LoadString( rStream, sFormatstring ); 1417cdf0e10cSrcweir rStream >> eType >> fLimit1 >> fLimit2 1418cdf0e10cSrcweir >> nOp1 >> nOp2 >> bStandard >> bIsUsed; 1419cdf0e10cSrcweir NfHackConversion eHackConversion = NF_CONVERT_NONE; 1420cdf0e10cSrcweir sal_Bool bOldConvert = sal_False; 1421cdf0e10cSrcweir LanguageType eOldTmpLang = 0; 1422cdf0e10cSrcweir LanguageType eOldNewLang = 0; 1423cdf0e10cSrcweir if ( pHackConverter ) 1424cdf0e10cSrcweir { // werden nur hierbei gebraucht 1425cdf0e10cSrcweir bOldConvert = rScan.GetConvertMode(); 1426cdf0e10cSrcweir eOldTmpLang = rScan.GetTmpLnge(); 1427cdf0e10cSrcweir eOldNewLang = rScan.GetNewLnge(); 1428cdf0e10cSrcweir } 1429cdf0e10cSrcweir String aLoadedColorName; 1430cdf0e10cSrcweir for (sal_uInt16 i = 0; i < 4; i++) 1431cdf0e10cSrcweir { 1432cdf0e10cSrcweir NumFor[i].Load( rStream, rScan, aLoadedColorName ); 1433cdf0e10cSrcweir if ( pHackConverter && eHackConversion == NF_CONVERT_NONE ) 1434cdf0e10cSrcweir { 1435cdf0e10cSrcweir //! HACK! ER 29.07.97 13:52 1436cdf0e10cSrcweir // leider wurde nicht gespeichert, was SYSTEM on Save wirklich war :-/ 1437cdf0e10cSrcweir // aber immerhin wird manchmal fuer einen Entry FARBE oder COLOR gespeichert.. 1438cdf0e10cSrcweir // System-German FARBE nach System-xxx COLOR umsetzen und vice versa, 1439cdf0e10cSrcweir //! geht davon aus, dass onSave nur GERMAN und ENGLISH KeyWords in 1440cdf0e10cSrcweir //! ImpSvNumberformatScan existierten 1441cdf0e10cSrcweir if ( aLoadedColorName.Len() && !NumFor[i].GetColor() 1442cdf0e10cSrcweir && aLoadedColorName != rScan.GetColorString() ) 1443cdf0e10cSrcweir { 1444cdf0e10cSrcweir if ( rScan.GetColorString().EqualsAscii( "FARBE" ) ) 1445cdf0e10cSrcweir { // English -> German 1446cdf0e10cSrcweir eHackConversion = NF_CONVERT_ENGLISH_GERMAN; 1447cdf0e10cSrcweir rScan.GetNumberformatter()->ChangeIntl( LANGUAGE_ENGLISH_US ); 1448cdf0e10cSrcweir rScan.SetConvertMode( LANGUAGE_ENGLISH_US, LANGUAGE_GERMAN ); 1449cdf0e10cSrcweir } 1450cdf0e10cSrcweir else 1451cdf0e10cSrcweir { // German -> English 1452cdf0e10cSrcweir eHackConversion = NF_CONVERT_GERMAN_ENGLISH; 1453cdf0e10cSrcweir rScan.GetNumberformatter()->ChangeIntl( LANGUAGE_GERMAN ); 1454cdf0e10cSrcweir rScan.SetConvertMode( LANGUAGE_GERMAN, LANGUAGE_ENGLISH_US ); 1455cdf0e10cSrcweir } 1456cdf0e10cSrcweir String aColorName = NumFor[i].GetColorName(); 1457cdf0e10cSrcweir const Color* pColor = rScan.GetColor( aColorName ); 1458cdf0e10cSrcweir if ( !pColor && aLoadedColorName == aColorName ) 1459cdf0e10cSrcweir eHackConversion = NF_CONVERT_NONE; 1460cdf0e10cSrcweir rScan.GetNumberformatter()->ChangeIntl( LANGUAGE_SYSTEM ); 1461cdf0e10cSrcweir rScan.SetConvertMode( eOldTmpLang, eOldNewLang ); 1462cdf0e10cSrcweir rScan.SetConvertMode( bOldConvert ); 1463cdf0e10cSrcweir } 1464cdf0e10cSrcweir } 1465cdf0e10cSrcweir } 1466cdf0e10cSrcweir eOp1 = (SvNumberformatLimitOps) nOp1; 1467cdf0e10cSrcweir eOp2 = (SvNumberformatLimitOps) nOp2; 1468cdf0e10cSrcweir String aComment; // wird nach dem NewCurrency-Geraffel richtig gesetzt 1469cdf0e10cSrcweir if ( rHdr.BytesLeft() ) 1470cdf0e10cSrcweir { // ab SV_NUMBERFORMATTER_VERSION_NEWSTANDARD 1471cdf0e10cSrcweir SvNumberformat::LoadString( rStream, aComment ); 1472cdf0e10cSrcweir rStream >> nNewStandardDefined; 1473cdf0e10cSrcweir } 1474cdf0e10cSrcweir 1475cdf0e10cSrcweir xub_StrLen nNewCurrencyEnd = STRING_NOTFOUND; 1476cdf0e10cSrcweir sal_Bool bNewCurrencyComment = ( aComment.GetChar(0) == cNewCurrencyMagic && 1477cdf0e10cSrcweir (nNewCurrencyEnd = aComment.Search( cNewCurrencyMagic, 1 )) != STRING_NOTFOUND ); 1478cdf0e10cSrcweir sal_Bool bNewCurrencyLoaded = sal_False; 1479cdf0e10cSrcweir sal_Bool bNewCurrency = sal_False; 1480cdf0e10cSrcweir 1481cdf0e10cSrcweir sal_Bool bGoOn = sal_True; 1482cdf0e10cSrcweir while ( rHdr.BytesLeft() && bGoOn ) 1483cdf0e10cSrcweir { // as of SV_NUMBERFORMATTER_VERSION_NEW_CURR 1484cdf0e10cSrcweir sal_uInt16 nId; 1485cdf0e10cSrcweir rStream >> nId; 1486cdf0e10cSrcweir switch ( nId ) 1487cdf0e10cSrcweir { 1488cdf0e10cSrcweir case nNewCurrencyVersionId : 1489cdf0e10cSrcweir { 1490cdf0e10cSrcweir bNewCurrencyLoaded = sal_True; 1491cdf0e10cSrcweir rStream >> bNewCurrency; 1492cdf0e10cSrcweir if ( bNewCurrency ) 1493cdf0e10cSrcweir { 1494cdf0e10cSrcweir for ( sal_uInt16 j=0; j<4; j++ ) 1495cdf0e10cSrcweir { 1496cdf0e10cSrcweir NumFor[j].LoadNewCurrencyMap( rStream ); 1497cdf0e10cSrcweir } 1498cdf0e10cSrcweir } 1499cdf0e10cSrcweir } 1500cdf0e10cSrcweir break; 1501cdf0e10cSrcweir case nNewStandardFlagVersionId : 1502cdf0e10cSrcweir rStream >> bStandard; // the real standard flag 1503cdf0e10cSrcweir break; 1504cdf0e10cSrcweir default: 1505cdf0e10cSrcweir DBG_ERRORFILE( "SvNumberformat::Load: unknown header bytes left nId" ); 1506cdf0e10cSrcweir bGoOn = sal_False; // stop reading unknown stream left over of newer versions 1507cdf0e10cSrcweir // Would be nice to have multiple read/write headers instead 1508cdf0e10cSrcweir // but old versions wouldn't know it, TLOT. 1509cdf0e10cSrcweir } 1510cdf0e10cSrcweir } 1511cdf0e10cSrcweir rHdr.EndEntry(); 1512cdf0e10cSrcweir 1513cdf0e10cSrcweir if ( bNewCurrencyLoaded ) 1514cdf0e10cSrcweir { 1515cdf0e10cSrcweir if ( bNewCurrency && bNewCurrencyComment ) 1516cdf0e10cSrcweir { // original Formatstring und Kommentar wiederherstellen 1517cdf0e10cSrcweir sFormatstring = aComment.Copy( 1, nNewCurrencyEnd-1 ); 1518cdf0e10cSrcweir aComment.Erase( 0, nNewCurrencyEnd+1 ); 1519cdf0e10cSrcweir } 1520cdf0e10cSrcweir } 1521cdf0e10cSrcweir else if ( bNewCurrencyComment ) 1522cdf0e10cSrcweir { // neu, aber mit Version vor SV_NUMBERFORMATTER_VERSION_NEW_CURR gespeichert 1523cdf0e10cSrcweir // original Formatstring und Kommentar wiederherstellen 1524cdf0e10cSrcweir sFormatstring = aComment.Copy( 1, nNewCurrencyEnd-1 ); 1525cdf0e10cSrcweir aComment.Erase( 0, nNewCurrencyEnd+1 ); 1526cdf0e10cSrcweir // Zustaende merken 1527cdf0e10cSrcweir short nDefined = ( eType & NUMBERFORMAT_DEFINED ); 1528cdf0e10cSrcweir sal_uInt16 nNewStandard = nNewStandardDefined; 1529cdf0e10cSrcweir // neu parsen etc. 1530cdf0e10cSrcweir String aStr( sFormatstring ); 1531cdf0e10cSrcweir xub_StrLen nCheckPos = 0; 1532cdf0e10cSrcweir SvNumberformat* pFormat = new SvNumberformat( aStr, &rScan, &rISc, 1533cdf0e10cSrcweir nCheckPos, eLnge, bStandard ); 1534cdf0e10cSrcweir DBG_ASSERT( !nCheckPos, "SvNumberformat::Load: NewCurrencyRescan nCheckPos" ); 1535cdf0e10cSrcweir ImpCopyNumberformat( *pFormat ); 1536cdf0e10cSrcweir delete pFormat; 1537cdf0e10cSrcweir // Zustaende wiederherstellen 1538cdf0e10cSrcweir eType |= nDefined; 1539cdf0e10cSrcweir if ( nNewStandard ) 1540cdf0e10cSrcweir SetNewStandardDefined( nNewStandard ); 1541cdf0e10cSrcweir } 1542cdf0e10cSrcweir SetComment( aComment ); 1543cdf0e10cSrcweir 1544cdf0e10cSrcweir if ( eHackConversion != NF_CONVERT_NONE ) 1545cdf0e10cSrcweir { //! und weiter mit dem HACK! 1546cdf0e10cSrcweir switch ( eHackConversion ) 1547cdf0e10cSrcweir { 1548cdf0e10cSrcweir case NF_CONVERT_ENGLISH_GERMAN : 1549cdf0e10cSrcweir ConvertLanguage( *pHackConverter, 1550cdf0e10cSrcweir LANGUAGE_ENGLISH_US, LANGUAGE_GERMAN, sal_True ); 1551cdf0e10cSrcweir break; 1552cdf0e10cSrcweir case NF_CONVERT_GERMAN_ENGLISH : 1553cdf0e10cSrcweir ConvertLanguage( *pHackConverter, 1554cdf0e10cSrcweir LANGUAGE_GERMAN, LANGUAGE_ENGLISH_US, sal_True ); 1555cdf0e10cSrcweir break; 1556cdf0e10cSrcweir default: 1557cdf0e10cSrcweir DBG_ERRORFILE( "SvNumberformat::Load: eHackConversion unknown" ); 1558cdf0e10cSrcweir } 1559cdf0e10cSrcweir } 1560cdf0e10cSrcweir return eHackConversion; 1561cdf0e10cSrcweir } 1562cdf0e10cSrcweir 1563cdf0e10cSrcweir void SvNumberformat::ConvertLanguage( SvNumberFormatter& rConverter, 1564cdf0e10cSrcweir LanguageType eConvertFrom, LanguageType eConvertTo, sal_Bool bSystem ) 1565cdf0e10cSrcweir { 1566cdf0e10cSrcweir xub_StrLen nCheckPos; 1567cdf0e10cSrcweir sal_uInt32 nKey; 1568cdf0e10cSrcweir short nType = eType; 1569cdf0e10cSrcweir String aFormatString( sFormatstring ); 1570cdf0e10cSrcweir if ( bSystem ) 1571cdf0e10cSrcweir rConverter.PutandConvertEntrySystem( aFormatString, nCheckPos, nType, 1572cdf0e10cSrcweir nKey, eConvertFrom, eConvertTo ); 1573cdf0e10cSrcweir else 1574cdf0e10cSrcweir rConverter.PutandConvertEntry( aFormatString, nCheckPos, nType, 1575cdf0e10cSrcweir nKey, eConvertFrom, eConvertTo ); 1576cdf0e10cSrcweir const SvNumberformat* pFormat = rConverter.GetEntry( nKey ); 1577cdf0e10cSrcweir DBG_ASSERT( pFormat, "SvNumberformat::ConvertLanguage: Conversion ohne Format" ); 1578cdf0e10cSrcweir if ( pFormat ) 1579cdf0e10cSrcweir { 1580cdf0e10cSrcweir ImpCopyNumberformat( *pFormat ); 1581cdf0e10cSrcweir // aus Formatter/Scanner uebernommene Werte zuruecksetzen 1582cdf0e10cSrcweir if ( bSystem ) 1583cdf0e10cSrcweir eLnge = LANGUAGE_SYSTEM; 1584cdf0e10cSrcweir // pColor zeigt noch auf Tabelle in temporaerem Formatter/Scanner 1585cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < 4; i++ ) 1586cdf0e10cSrcweir { 1587cdf0e10cSrcweir String aColorName = NumFor[i].GetColorName(); 1588cdf0e10cSrcweir Color* pColor = rScan.GetColor( aColorName ); 1589cdf0e10cSrcweir NumFor[i].SetColor( pColor, aColorName ); 1590cdf0e10cSrcweir } 1591cdf0e10cSrcweir } 1592cdf0e10cSrcweir } 1593cdf0e10cSrcweir 1594cdf0e10cSrcweir 1595cdf0e10cSrcweir // static 1596cdf0e10cSrcweir void SvNumberformat::LoadString( SvStream& rStream, String& rStr ) 1597cdf0e10cSrcweir { 1598cdf0e10cSrcweir CharSet eStream = rStream.GetStreamCharSet(); 1599cdf0e10cSrcweir ByteString aStr; 1600cdf0e10cSrcweir rStream.ReadByteString( aStr ); 1601cdf0e10cSrcweir sal_Char cStream = NfCurrencyEntry::GetEuroSymbol( eStream ); 1602cdf0e10cSrcweir if ( aStr.Search( cStream ) == STRING_NOTFOUND ) 1603cdf0e10cSrcweir { // simple conversion to unicode 1604cdf0e10cSrcweir rStr = UniString( aStr, eStream ); 1605cdf0e10cSrcweir } 1606cdf0e10cSrcweir else 1607cdf0e10cSrcweir { 1608cdf0e10cSrcweir sal_Unicode cTarget = NfCurrencyEntry::GetEuroSymbol(); 1609cdf0e10cSrcweir register const sal_Char* p = aStr.GetBuffer(); 1610cdf0e10cSrcweir register const sal_Char* const pEnd = p + aStr.Len(); 1611cdf0e10cSrcweir register sal_Unicode* pUni = rStr.AllocBuffer( aStr.Len() ); 1612cdf0e10cSrcweir while ( p < pEnd ) 1613cdf0e10cSrcweir { 1614cdf0e10cSrcweir if ( *p == cStream ) 1615cdf0e10cSrcweir *pUni = cTarget; 1616cdf0e10cSrcweir else 1617cdf0e10cSrcweir *pUni = ByteString::ConvertToUnicode( *p, eStream ); 1618cdf0e10cSrcweir p++; 1619cdf0e10cSrcweir pUni++; 1620cdf0e10cSrcweir } 1621cdf0e10cSrcweir *pUni = 0; 1622cdf0e10cSrcweir } 1623cdf0e10cSrcweir } 1624cdf0e10cSrcweir 1625cdf0e10cSrcweir 1626cdf0e10cSrcweir void SvNumberformat::Save( SvStream& rStream, ImpSvNumMultipleWriteHeader& rHdr ) const 1627cdf0e10cSrcweir { 1628cdf0e10cSrcweir String aFormatstring( sFormatstring ); 1629cdf0e10cSrcweir String aComment( sComment ); 1630cdf0e10cSrcweir #if NF_COMMENT_IN_FORMATSTRING 1631cdf0e10cSrcweir // der Kommentar im Formatstring wird nicht gespeichert, um in alten Versionen 1632cdf0e10cSrcweir // nicht ins schleudern zu kommen und spaeter getrennte Verarbeitung 1633cdf0e10cSrcweir // (z.B. im Dialog) zu ermoeglichen 1634cdf0e10cSrcweir SetComment( "", aFormatstring, aComment ); 1635cdf0e10cSrcweir #endif 1636cdf0e10cSrcweir 1637cdf0e10cSrcweir sal_Bool bNewCurrency = HasNewCurrency(); 1638cdf0e10cSrcweir if ( bNewCurrency ) 1639cdf0e10cSrcweir { // SV_NUMBERFORMATTER_VERSION_NEW_CURR im Kommentar speichern 1640cdf0e10cSrcweir aComment.Insert( cNewCurrencyMagic, 0 ); 1641cdf0e10cSrcweir aComment.Insert( cNewCurrencyMagic, 0 ); 1642cdf0e10cSrcweir aComment.Insert( aFormatstring, 1 ); 1643cdf0e10cSrcweir Build50Formatstring( aFormatstring ); // alten Formatstring generieren 1644cdf0e10cSrcweir } 1645cdf0e10cSrcweir 1646cdf0e10cSrcweir // old SO5 versions do behave strange (no output) if standard flag is set 1647cdf0e10cSrcweir // on formats not prepared for it (not having the following exact types) 1648cdf0e10cSrcweir sal_Bool bOldStandard = bStandard; 1649cdf0e10cSrcweir if ( bOldStandard ) 1650cdf0e10cSrcweir { 1651cdf0e10cSrcweir switch ( eType ) 1652cdf0e10cSrcweir { 1653cdf0e10cSrcweir case NUMBERFORMAT_NUMBER : 1654cdf0e10cSrcweir case NUMBERFORMAT_DATE : 1655cdf0e10cSrcweir case NUMBERFORMAT_TIME : 1656cdf0e10cSrcweir case NUMBERFORMAT_DATETIME : 1657cdf0e10cSrcweir case NUMBERFORMAT_PERCENT : 1658cdf0e10cSrcweir case NUMBERFORMAT_SCIENTIFIC : 1659cdf0e10cSrcweir // ok to save 1660cdf0e10cSrcweir break; 1661cdf0e10cSrcweir default: 1662cdf0e10cSrcweir bOldStandard = sal_False; 1663cdf0e10cSrcweir } 1664cdf0e10cSrcweir } 1665cdf0e10cSrcweir 1666cdf0e10cSrcweir rHdr.StartEntry(); 1667cdf0e10cSrcweir rStream.WriteByteString( aFormatstring, rStream.GetStreamCharSet() ); 1668cdf0e10cSrcweir rStream << eType << fLimit1 << fLimit2 << (sal_uInt16) eOp1 << (sal_uInt16) eOp2 1669cdf0e10cSrcweir << bOldStandard << bIsUsed; 1670cdf0e10cSrcweir for (sal_uInt16 i = 0; i < 4; i++) 1671cdf0e10cSrcweir NumFor[i].Save(rStream); 1672cdf0e10cSrcweir // ab SV_NUMBERFORMATTER_VERSION_NEWSTANDARD 1673cdf0e10cSrcweir rStream.WriteByteString( aComment, rStream.GetStreamCharSet() ); 1674cdf0e10cSrcweir rStream << nNewStandardDefined; 1675cdf0e10cSrcweir // ab SV_NUMBERFORMATTER_VERSION_NEW_CURR 1676cdf0e10cSrcweir rStream << nNewCurrencyVersionId; 1677cdf0e10cSrcweir rStream << bNewCurrency; 1678cdf0e10cSrcweir if ( bNewCurrency ) 1679cdf0e10cSrcweir { 1680cdf0e10cSrcweir for ( sal_uInt16 j=0; j<4; j++ ) 1681cdf0e10cSrcweir { 1682cdf0e10cSrcweir NumFor[j].SaveNewCurrencyMap( rStream ); 1683cdf0e10cSrcweir } 1684cdf0e10cSrcweir } 1685cdf0e10cSrcweir 1686cdf0e10cSrcweir // the real standard flag to load with versions >638 if different 1687cdf0e10cSrcweir if ( bStandard != bOldStandard ) 1688cdf0e10cSrcweir { 1689cdf0e10cSrcweir rStream << nNewStandardFlagVersionId; 1690cdf0e10cSrcweir rStream << bStandard; 1691cdf0e10cSrcweir } 1692cdf0e10cSrcweir 1693cdf0e10cSrcweir rHdr.EndEntry(); 1694cdf0e10cSrcweir } 1695cdf0e10cSrcweir 1696cdf0e10cSrcweir 1697cdf0e10cSrcweir sal_Bool SvNumberformat::HasNewCurrency() const 1698cdf0e10cSrcweir { 1699cdf0e10cSrcweir for ( sal_uInt16 j=0; j<4; j++ ) 1700cdf0e10cSrcweir { 1701cdf0e10cSrcweir if ( NumFor[j].HasNewCurrency() ) 1702cdf0e10cSrcweir return sal_True; 1703cdf0e10cSrcweir } 1704cdf0e10cSrcweir return sal_False; 1705cdf0e10cSrcweir } 1706cdf0e10cSrcweir 1707cdf0e10cSrcweir 1708cdf0e10cSrcweir sal_Bool SvNumberformat::GetNewCurrencySymbol( String& rSymbol, 1709cdf0e10cSrcweir String& rExtension ) const 1710cdf0e10cSrcweir { 1711cdf0e10cSrcweir for ( sal_uInt16 j=0; j<4; j++ ) 1712cdf0e10cSrcweir { 1713cdf0e10cSrcweir if ( NumFor[j].GetNewCurrencySymbol( rSymbol, rExtension ) ) 1714cdf0e10cSrcweir return sal_True; 1715cdf0e10cSrcweir } 1716cdf0e10cSrcweir rSymbol.Erase(); 1717cdf0e10cSrcweir rExtension.Erase(); 1718cdf0e10cSrcweir return sal_False; 1719cdf0e10cSrcweir } 1720cdf0e10cSrcweir 1721cdf0e10cSrcweir 1722cdf0e10cSrcweir // static 1723cdf0e10cSrcweir String SvNumberformat::StripNewCurrencyDelimiters( const String& rStr, 1724cdf0e10cSrcweir sal_Bool bQuoteSymbol ) 1725cdf0e10cSrcweir { 1726cdf0e10cSrcweir String aTmp; 1727cdf0e10cSrcweir xub_StrLen nStartPos, nPos, nLen; 1728cdf0e10cSrcweir nLen = rStr.Len(); 1729cdf0e10cSrcweir nStartPos = 0; 1730cdf0e10cSrcweir while ( (nPos = rStr.SearchAscii( "[$", nStartPos )) != STRING_NOTFOUND ) 1731cdf0e10cSrcweir { 1732cdf0e10cSrcweir xub_StrLen nEnd; 1733cdf0e10cSrcweir if ( (nEnd = GetQuoteEnd( rStr, nPos )) < nLen ) 1734cdf0e10cSrcweir { 1735cdf0e10cSrcweir aTmp += rStr.Copy( nStartPos, ++nEnd - nStartPos ); 1736cdf0e10cSrcweir nStartPos = nEnd; 1737cdf0e10cSrcweir } 1738cdf0e10cSrcweir else 1739cdf0e10cSrcweir { 1740cdf0e10cSrcweir aTmp += rStr.Copy( nStartPos, nPos - nStartPos ); 1741cdf0e10cSrcweir nStartPos = nPos + 2; 1742cdf0e10cSrcweir xub_StrLen nDash; 1743cdf0e10cSrcweir nEnd = nStartPos - 1; 1744cdf0e10cSrcweir do 1745cdf0e10cSrcweir { 1746cdf0e10cSrcweir nDash = rStr.Search( '-', ++nEnd ); 1747cdf0e10cSrcweir } while ( (nEnd = GetQuoteEnd( rStr, nDash )) < nLen ); 1748cdf0e10cSrcweir xub_StrLen nClose; 1749cdf0e10cSrcweir nEnd = nStartPos - 1; 1750cdf0e10cSrcweir do 1751cdf0e10cSrcweir { 1752cdf0e10cSrcweir nClose = rStr.Search( ']', ++nEnd ); 1753cdf0e10cSrcweir } while ( (nEnd = GetQuoteEnd( rStr, nClose )) < nLen ); 1754cdf0e10cSrcweir nPos = ( nDash < nClose ? nDash : nClose ); 1755cdf0e10cSrcweir if ( !bQuoteSymbol || rStr.GetChar( nStartPos ) == '"' ) 1756cdf0e10cSrcweir aTmp += rStr.Copy( nStartPos, nPos - nStartPos ); 1757cdf0e10cSrcweir else 1758cdf0e10cSrcweir { 1759cdf0e10cSrcweir aTmp += '"'; 1760cdf0e10cSrcweir aTmp += rStr.Copy( nStartPos, nPos - nStartPos ); 1761cdf0e10cSrcweir aTmp += '"'; 1762cdf0e10cSrcweir } 1763cdf0e10cSrcweir nStartPos = nClose + 1; 1764cdf0e10cSrcweir } 1765cdf0e10cSrcweir } 1766cdf0e10cSrcweir if ( nLen > nStartPos ) 1767cdf0e10cSrcweir aTmp += rStr.Copy( nStartPos, nLen - nStartPos ); 1768cdf0e10cSrcweir return aTmp; 1769cdf0e10cSrcweir } 1770cdf0e10cSrcweir 1771cdf0e10cSrcweir 1772cdf0e10cSrcweir void SvNumberformat::Build50Formatstring( String& rStr ) const 1773cdf0e10cSrcweir { 1774cdf0e10cSrcweir rStr = StripNewCurrencyDelimiters( sFormatstring, sal_True ); 1775cdf0e10cSrcweir } 1776cdf0e10cSrcweir 1777cdf0e10cSrcweir 1778cdf0e10cSrcweir void SvNumberformat::ImpGetOutputStandard(double& fNumber, String& OutString) 1779cdf0e10cSrcweir { 1780cdf0e10cSrcweir sal_uInt16 nStandardPrec = rScan.GetStandardPrec(); 1781cdf0e10cSrcweir 1782cdf0e10cSrcweir if ( fabs(fNumber) > 1.0E15 ) // #58531# war E16 1783cdf0e10cSrcweir { 1784cdf0e10cSrcweir nStandardPrec = ::std::min(nStandardPrec, static_cast<sal_uInt16>(14)); // limits to 14 decimals 1785cdf0e10cSrcweir OutString = ::rtl::math::doubleToUString( fNumber, 1786cdf0e10cSrcweir rtl_math_StringFormat_E, nStandardPrec /*2*/, 1787cdf0e10cSrcweir GetFormatter().GetNumDecimalSep().GetChar(0)); 1788cdf0e10cSrcweir } 1789cdf0e10cSrcweir else 1790cdf0e10cSrcweir ImpGetOutputStdToPrecision(fNumber, OutString, nStandardPrec); 1791cdf0e10cSrcweir } 1792cdf0e10cSrcweir 1793cdf0e10cSrcweir void SvNumberformat::ImpGetOutputStdToPrecision(double& rNumber, String& rOutString, sal_uInt16 nPrecision) const 1794cdf0e10cSrcweir { 1795cdf0e10cSrcweir // Make sure the precision doesn't go over the maximum allowable precision. 1796cdf0e10cSrcweir nPrecision = ::std::min(UPPER_PRECISION, nPrecision); 1797cdf0e10cSrcweir 1798cdf0e10cSrcweir #if 0 1799cdf0e10cSrcweir { 1800cdf0e10cSrcweir // debugger test case for ANSI standard correctness 1801cdf0e10cSrcweir ::rtl::OUString aTest; 1802cdf0e10cSrcweir // expect 0.00123 OK 1803cdf0e10cSrcweir aTest = ::rtl::math::doubleToUString( 0.001234567, 1804cdf0e10cSrcweir rtl_math_StringFormat_G, 3, '.', sal_True ); 1805cdf0e10cSrcweir // expect 123 OK 1806cdf0e10cSrcweir aTest = ::rtl::math::doubleToUString( 123.4567, 1807cdf0e10cSrcweir rtl_math_StringFormat_G, 3, '.', sal_True ); 1808cdf0e10cSrcweir // expect 123.5 OK 1809cdf0e10cSrcweir aTest = ::rtl::math::doubleToUString( 123.4567, 1810cdf0e10cSrcweir rtl_math_StringFormat_G, 4, '.', sal_True ); 1811cdf0e10cSrcweir // expect 1e+03 (as 999.6 rounded to 3 significant digits results in 1812cdf0e10cSrcweir // 1000 with an exponent equal to significant digits) 1813cdf0e10cSrcweir // Currently (24-Jan-2003) we do fail in this case and output 1000 1814cdf0e10cSrcweir // instead, negligible. 1815cdf0e10cSrcweir aTest = ::rtl::math::doubleToUString( 999.6, 1816cdf0e10cSrcweir rtl_math_StringFormat_G, 3, '.', sal_True ); 1817cdf0e10cSrcweir // expect what? result is 1.2e+004 1818cdf0e10cSrcweir aTest = ::rtl::math::doubleToUString( 12345.6789, 1819cdf0e10cSrcweir rtl_math_StringFormat_G, -3, '.', sal_True ); 1820cdf0e10cSrcweir } 1821cdf0e10cSrcweir #endif 1822cdf0e10cSrcweir 1823cdf0e10cSrcweir // We decided to strip trailing zeros unconditionally, since binary 1824cdf0e10cSrcweir // double-precision rounding error makes it impossible to determine e.g. 1825cdf0e10cSrcweir // whether 844.10000000000002273737 is what the user has typed, or the 1826cdf0e10cSrcweir // user has typed 844.1 but IEEE 754 represents it that way internally. 1827cdf0e10cSrcweir 1828cdf0e10cSrcweir rOutString = ::rtl::math::doubleToUString( rNumber, 1829cdf0e10cSrcweir rtl_math_StringFormat_F, nPrecision /*2*/, 1830cdf0e10cSrcweir GetFormatter().GetNumDecimalSep().GetChar(0), true ); 1831cdf0e10cSrcweir if (rOutString.GetChar(0) == '-' && 1832cdf0e10cSrcweir rOutString.GetTokenCount('0') == rOutString.Len()) 1833cdf0e10cSrcweir rOutString.EraseLeadingChars('-'); // nicht -0 1834cdf0e10cSrcweir 1835cdf0e10cSrcweir ImpTransliterate( rOutString, NumFor[0].GetNatNum() ); 1836cdf0e10cSrcweir } 1837cdf0e10cSrcweir 1838cdf0e10cSrcweir void SvNumberformat::ImpGetOutputInputLine(double fNumber, String& OutString) 1839cdf0e10cSrcweir { 1840cdf0e10cSrcweir sal_Bool bModified = sal_False; 1841cdf0e10cSrcweir if ( (eType & NUMBERFORMAT_PERCENT) && (fabs(fNumber) < _D_MAX_D_BY_100)) 1842cdf0e10cSrcweir { 1843cdf0e10cSrcweir if (fNumber == 0.0) 1844cdf0e10cSrcweir { 1845cdf0e10cSrcweir OutString.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "0%" ) ); 1846cdf0e10cSrcweir return; 1847cdf0e10cSrcweir } 1848cdf0e10cSrcweir fNumber *= 100; 1849cdf0e10cSrcweir bModified = sal_True; 1850cdf0e10cSrcweir } 1851cdf0e10cSrcweir 1852cdf0e10cSrcweir if (fNumber == 0.0) 1853cdf0e10cSrcweir { 1854cdf0e10cSrcweir OutString = '0'; 1855cdf0e10cSrcweir return; 1856cdf0e10cSrcweir } 1857cdf0e10cSrcweir 1858cdf0e10cSrcweir OutString = ::rtl::math::doubleToUString( fNumber, 1859cdf0e10cSrcweir rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, 1860cdf0e10cSrcweir GetFormatter().GetNumDecimalSep().GetChar(0), sal_True ); 1861cdf0e10cSrcweir 1862cdf0e10cSrcweir if ( eType & NUMBERFORMAT_PERCENT && bModified) 1863cdf0e10cSrcweir OutString += '%'; 1864cdf0e10cSrcweir return; 1865cdf0e10cSrcweir } 1866cdf0e10cSrcweir 1867cdf0e10cSrcweir short SvNumberformat::ImpCheckCondition(double& fNumber, 1868cdf0e10cSrcweir double& fLimit, 1869cdf0e10cSrcweir SvNumberformatLimitOps eOp) 1870cdf0e10cSrcweir { 1871cdf0e10cSrcweir switch(eOp) 1872cdf0e10cSrcweir { 1873cdf0e10cSrcweir case NUMBERFORMAT_OP_NO: return -1; 1874cdf0e10cSrcweir case NUMBERFORMAT_OP_EQ: return (short) (fNumber == fLimit); 1875cdf0e10cSrcweir case NUMBERFORMAT_OP_NE: return (short) (fNumber != fLimit); 1876cdf0e10cSrcweir case NUMBERFORMAT_OP_LT: return (short) (fNumber < fLimit); 1877cdf0e10cSrcweir case NUMBERFORMAT_OP_LE: return (short) (fNumber <= fLimit); 1878cdf0e10cSrcweir case NUMBERFORMAT_OP_GT: return (short) (fNumber > fLimit); 1879cdf0e10cSrcweir case NUMBERFORMAT_OP_GE: return (short) (fNumber >= fLimit); 1880cdf0e10cSrcweir default: return -1; 1881cdf0e10cSrcweir } 1882cdf0e10cSrcweir } 1883cdf0e10cSrcweir 1884cdf0e10cSrcweir sal_Bool SvNumberformat::GetOutputString(String& sString, 1885cdf0e10cSrcweir String& OutString, 1886cdf0e10cSrcweir Color** ppColor) 1887cdf0e10cSrcweir { 1888cdf0e10cSrcweir OutString.Erase(); 1889cdf0e10cSrcweir sal_uInt16 nIx; 1890cdf0e10cSrcweir if (eType & NUMBERFORMAT_TEXT) 1891cdf0e10cSrcweir nIx = 0; 1892cdf0e10cSrcweir else if (NumFor[3].GetnAnz() > 0) 1893cdf0e10cSrcweir nIx = 3; 1894cdf0e10cSrcweir else 1895cdf0e10cSrcweir { 1896cdf0e10cSrcweir *ppColor = NULL; // no change of color 1897cdf0e10cSrcweir return sal_False; 1898cdf0e10cSrcweir } 1899cdf0e10cSrcweir *ppColor = NumFor[nIx].GetColor(); 1900cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); 1901cdf0e10cSrcweir if (rInfo.eScannedType == NUMBERFORMAT_TEXT) 1902cdf0e10cSrcweir { 1903cdf0e10cSrcweir sal_Bool bRes = sal_False; 1904cdf0e10cSrcweir const sal_uInt16 nAnz = NumFor[nIx].GetnAnz(); 1905cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nAnz; i++) 1906cdf0e10cSrcweir { 1907cdf0e10cSrcweir switch (rInfo.nTypeArray[i]) 1908cdf0e10cSrcweir { 1909cdf0e10cSrcweir case NF_SYMBOLTYPE_STAR: 1910cdf0e10cSrcweir if( bStarFlag ) 1911cdf0e10cSrcweir { 1912cdf0e10cSrcweir OutString += (sal_Unicode) 0x1B; 1913cdf0e10cSrcweir OutString += rInfo.sStrArray[i].GetChar(1); 1914cdf0e10cSrcweir bRes = sal_True; 1915cdf0e10cSrcweir } 1916cdf0e10cSrcweir break; 1917cdf0e10cSrcweir case NF_SYMBOLTYPE_BLANK: 1918cdf0e10cSrcweir InsertBlanks( OutString, OutString.Len(), 1919cdf0e10cSrcweir rInfo.sStrArray[i].GetChar(1) ); 1920cdf0e10cSrcweir break; 1921cdf0e10cSrcweir case NF_KEY_GENERAL : // #77026# "General" is the same as "@" 1922cdf0e10cSrcweir case NF_SYMBOLTYPE_DEL : 1923cdf0e10cSrcweir OutString += sString; 1924cdf0e10cSrcweir break; 1925cdf0e10cSrcweir default: 1926cdf0e10cSrcweir OutString += rInfo.sStrArray[i]; 1927cdf0e10cSrcweir } 1928cdf0e10cSrcweir } 1929cdf0e10cSrcweir return bRes; 1930cdf0e10cSrcweir } 1931cdf0e10cSrcweir return sal_False; 1932cdf0e10cSrcweir } 1933cdf0e10cSrcweir /* 1934cdf0e10cSrcweir void SvNumberformat::GetNextFareyNumber(sal_uLong nPrec, sal_uLong x0, sal_uLong x1, 1935cdf0e10cSrcweir sal_uLong y0, sal_uLong y1, 1936cdf0e10cSrcweir sal_uLong& x2,sal_uLong& y2) 1937cdf0e10cSrcweir { 1938cdf0e10cSrcweir x2 = ((y0+nPrec)/y1)*x1 - x0; 1939cdf0e10cSrcweir y2 = ((y0+nPrec)/y1)*y1 - y0; 1940cdf0e10cSrcweir } 1941cdf0e10cSrcweir */ 1942cdf0e10cSrcweir sal_uLong SvNumberformat::ImpGGT(sal_uLong x, sal_uLong y) 1943cdf0e10cSrcweir { 1944cdf0e10cSrcweir if (y == 0) 1945cdf0e10cSrcweir return x; 1946cdf0e10cSrcweir else 1947cdf0e10cSrcweir { 1948cdf0e10cSrcweir sal_uLong z = x%y; 1949cdf0e10cSrcweir while (z) 1950cdf0e10cSrcweir { 1951cdf0e10cSrcweir x = y; 1952cdf0e10cSrcweir y = z; 1953cdf0e10cSrcweir z = x%y; 1954cdf0e10cSrcweir } 1955cdf0e10cSrcweir return y; 1956cdf0e10cSrcweir } 1957cdf0e10cSrcweir } 1958cdf0e10cSrcweir 1959cdf0e10cSrcweir sal_uLong SvNumberformat::ImpGGTRound(sal_uLong x, sal_uLong y) 1960cdf0e10cSrcweir { 1961cdf0e10cSrcweir if (y == 0) 1962cdf0e10cSrcweir return x; 1963cdf0e10cSrcweir else 1964cdf0e10cSrcweir { 1965cdf0e10cSrcweir sal_uLong z = x%y; 1966cdf0e10cSrcweir while ((double)z/(double)y > D_EPS) 1967cdf0e10cSrcweir { 1968cdf0e10cSrcweir x = y; 1969cdf0e10cSrcweir y = z; 1970cdf0e10cSrcweir z = x%y; 1971cdf0e10cSrcweir } 1972cdf0e10cSrcweir return y; 1973cdf0e10cSrcweir } 1974cdf0e10cSrcweir } 1975cdf0e10cSrcweir 1976cdf0e10cSrcweir namespace { 1977cdf0e10cSrcweir 1978cdf0e10cSrcweir void lcl_GetOutputStringScientific( 1979cdf0e10cSrcweir double fNumber, sal_uInt16 nCharCount, const SvNumberFormatter& rFormatter, String& rOutString) 1980cdf0e10cSrcweir { 1981cdf0e10cSrcweir bool bSign = ::rtl::math::isSignBitSet(fNumber); 1982cdf0e10cSrcweir 1983cdf0e10cSrcweir // 1.000E+015 (one digit and the decimal point, and the five chars for the exponential part, totalling 7). 1984cdf0e10cSrcweir sal_uInt16 nPrec = nCharCount > 7 ? nCharCount - 7 : 0; 1985cdf0e10cSrcweir if (nPrec && bSign) 1986cdf0e10cSrcweir // Make room for the negative sign. 1987cdf0e10cSrcweir --nPrec; 1988cdf0e10cSrcweir 1989cdf0e10cSrcweir nPrec = ::std::min(nPrec, static_cast<sal_uInt16>(14)); // limit to 14 decimals. 1990cdf0e10cSrcweir 1991cdf0e10cSrcweir rOutString = ::rtl::math::doubleToUString( 1992cdf0e10cSrcweir fNumber, rtl_math_StringFormat_E, nPrec, rFormatter.GetNumDecimalSep().GetChar(0)); 1993cdf0e10cSrcweir } 1994cdf0e10cSrcweir 1995cdf0e10cSrcweir } 1996cdf0e10cSrcweir 1997cdf0e10cSrcweir bool SvNumberformat::GetOutputString(double fNumber, sal_uInt16 nCharCount, String& rOutString) const 1998cdf0e10cSrcweir { 1999cdf0e10cSrcweir using namespace std; 2000cdf0e10cSrcweir 2001cdf0e10cSrcweir if (eType != NUMBERFORMAT_NUMBER) 2002cdf0e10cSrcweir return false; 2003cdf0e10cSrcweir 2004cdf0e10cSrcweir double fTestNum = fNumber; 2005cdf0e10cSrcweir bool bSign = ::rtl::math::isSignBitSet(fTestNum); 2006cdf0e10cSrcweir if (bSign) 2007cdf0e10cSrcweir fTestNum = -fTestNum; 2008cdf0e10cSrcweir 2009cdf0e10cSrcweir if (fTestNum < EXP_LOWER_BOUND) 2010cdf0e10cSrcweir { 2011cdf0e10cSrcweir lcl_GetOutputStringScientific(fNumber, nCharCount, GetFormatter(), rOutString); 2012cdf0e10cSrcweir return true; 2013cdf0e10cSrcweir } 2014cdf0e10cSrcweir 2015cdf0e10cSrcweir double fExp = log10(fTestNum); 2016cdf0e10cSrcweir // Values < 1.0 always have one digit before the decimal point. 2017cdf0e10cSrcweir sal_uInt16 nDigitPre = fExp >= 0.0 ? static_cast<sal_uInt16>(ceil(fExp)) : 1; 2018cdf0e10cSrcweir 2019cdf0e10cSrcweir if (nDigitPre > 15) 2020cdf0e10cSrcweir { 2021cdf0e10cSrcweir lcl_GetOutputStringScientific(fNumber, nCharCount, GetFormatter(), rOutString); 2022cdf0e10cSrcweir return true; 2023cdf0e10cSrcweir } 2024cdf0e10cSrcweir 2025cdf0e10cSrcweir sal_uInt16 nPrec = nCharCount >= nDigitPre ? nCharCount - nDigitPre : 0; 2026cdf0e10cSrcweir if (nPrec && bSign) 2027cdf0e10cSrcweir // Subtract the negative sign. 2028cdf0e10cSrcweir --nPrec; 2029cdf0e10cSrcweir if (nPrec) 2030cdf0e10cSrcweir // Subtract the decimal point. 2031cdf0e10cSrcweir --nPrec; 2032cdf0e10cSrcweir 2033cdf0e10cSrcweir ImpGetOutputStdToPrecision(fNumber, rOutString, nPrec); 2034cdf0e10cSrcweir if (rOutString.Len() > nCharCount) 2035cdf0e10cSrcweir // String still wider than desired. Switch to scientific notation. 2036cdf0e10cSrcweir lcl_GetOutputStringScientific(fNumber, nCharCount, GetFormatter(), rOutString); 2037cdf0e10cSrcweir 2038cdf0e10cSrcweir return true; 2039cdf0e10cSrcweir } 2040cdf0e10cSrcweir 2041cdf0e10cSrcweir sal_Bool SvNumberformat::GetOutputString(double fNumber, 2042cdf0e10cSrcweir String& OutString, 2043cdf0e10cSrcweir Color** ppColor) 2044cdf0e10cSrcweir { 2045cdf0e10cSrcweir sal_Bool bRes = sal_False; 2046cdf0e10cSrcweir OutString.Erase(); // alles loeschen 2047cdf0e10cSrcweir *ppColor = NULL; // keine Farbaenderung 2048cdf0e10cSrcweir if (eType & NUMBERFORMAT_LOGICAL) 2049cdf0e10cSrcweir { 2050cdf0e10cSrcweir if (fNumber) 2051cdf0e10cSrcweir OutString = rScan.GetTrueString(); 2052cdf0e10cSrcweir else 2053cdf0e10cSrcweir OutString = rScan.GetFalseString(); 2054cdf0e10cSrcweir return sal_False; 2055cdf0e10cSrcweir } 2056cdf0e10cSrcweir if (eType & NUMBERFORMAT_TEXT) 2057cdf0e10cSrcweir { 2058cdf0e10cSrcweir ImpGetOutputStandard(fNumber, OutString); 2059cdf0e10cSrcweir return sal_False; 2060cdf0e10cSrcweir } 2061cdf0e10cSrcweir sal_Bool bHadStandard = sal_False; 2062cdf0e10cSrcweir if (bStandard) // einzelne Standardformate 2063cdf0e10cSrcweir { 2064cdf0e10cSrcweir if (rScan.GetStandardPrec() == SvNumberFormatter::INPUTSTRING_PRECISION) // alle Zahlformate InputLine 2065cdf0e10cSrcweir { 2066cdf0e10cSrcweir ImpGetOutputInputLine(fNumber, OutString); 2067cdf0e10cSrcweir return false; 2068cdf0e10cSrcweir } 2069cdf0e10cSrcweir switch (eType) 2070cdf0e10cSrcweir { 2071cdf0e10cSrcweir case NUMBERFORMAT_NUMBER: // Standardzahlformat 2072cdf0e10cSrcweir { 2073cdf0e10cSrcweir if (rScan.GetStandardPrec() == SvNumberFormatter::UNLIMITED_PRECISION) 2074cdf0e10cSrcweir { 2075cdf0e10cSrcweir bool bSign = ::rtl::math::isSignBitSet(fNumber); 2076cdf0e10cSrcweir if (bSign) 2077cdf0e10cSrcweir fNumber = -fNumber; 2078cdf0e10cSrcweir ImpGetOutputStdToPrecision(fNumber, OutString, 10); // Use 10 decimals for general 'unlimited' format. 2079cdf0e10cSrcweir if (fNumber < EXP_LOWER_BOUND) 2080cdf0e10cSrcweir { 2081cdf0e10cSrcweir xub_StrLen nLen = OutString.Len(); 2082cdf0e10cSrcweir if (!nLen) 2083cdf0e10cSrcweir return false; 2084cdf0e10cSrcweir 2085cdf0e10cSrcweir // #i112250# With the 10-decimal limit, small numbers are formatted as "0". 2086cdf0e10cSrcweir // Switch to scientific in that case, too: 2087cdf0e10cSrcweir if (nLen > 11 || (OutString.EqualsAscii("0") && fNumber != 0.0)) 2088cdf0e10cSrcweir { 2089cdf0e10cSrcweir sal_uInt16 nStandardPrec = rScan.GetStandardPrec(); 2090cdf0e10cSrcweir nStandardPrec = ::std::min(nStandardPrec, static_cast<sal_uInt16>(14)); // limits to 14 decimals 2091cdf0e10cSrcweir OutString = ::rtl::math::doubleToUString( fNumber, 2092cdf0e10cSrcweir rtl_math_StringFormat_E, nStandardPrec /*2*/, 2093cdf0e10cSrcweir GetFormatter().GetNumDecimalSep().GetChar(0), true); 2094cdf0e10cSrcweir } 2095cdf0e10cSrcweir } 2096cdf0e10cSrcweir if (bSign) 2097cdf0e10cSrcweir OutString.Insert('-', 0); 2098cdf0e10cSrcweir return false; 2099cdf0e10cSrcweir } 2100cdf0e10cSrcweir ImpGetOutputStandard(fNumber, OutString); 2101cdf0e10cSrcweir bHadStandard = sal_True; 2102cdf0e10cSrcweir } 2103cdf0e10cSrcweir break; 2104cdf0e10cSrcweir case NUMBERFORMAT_DATE: 2105cdf0e10cSrcweir bRes |= ImpGetDateOutput(fNumber, 0, OutString); 2106cdf0e10cSrcweir bHadStandard = sal_True; 2107cdf0e10cSrcweir break; 2108cdf0e10cSrcweir case NUMBERFORMAT_TIME: 2109cdf0e10cSrcweir bRes |= ImpGetTimeOutput(fNumber, 0, OutString); 2110cdf0e10cSrcweir bHadStandard = sal_True; 2111cdf0e10cSrcweir break; 2112cdf0e10cSrcweir case NUMBERFORMAT_DATETIME: 2113cdf0e10cSrcweir bRes |= ImpGetDateTimeOutput(fNumber, 0, OutString); 2114cdf0e10cSrcweir bHadStandard = sal_True; 2115cdf0e10cSrcweir break; 2116cdf0e10cSrcweir } 2117cdf0e10cSrcweir } 2118cdf0e10cSrcweir if ( !bHadStandard ) 2119cdf0e10cSrcweir { 2120cdf0e10cSrcweir sal_uInt16 nIx; // Index des Teilformats 2121cdf0e10cSrcweir short nCheck = ImpCheckCondition(fNumber, fLimit1, eOp1); 2122cdf0e10cSrcweir if (nCheck == -1 || nCheck == 1) // nur 1 String oder True 2123cdf0e10cSrcweir nIx = 0; 2124cdf0e10cSrcweir else 2125cdf0e10cSrcweir { 2126cdf0e10cSrcweir nCheck = ImpCheckCondition(fNumber, fLimit2, eOp2); 2127cdf0e10cSrcweir if (nCheck == -1 || nCheck == 1) 2128cdf0e10cSrcweir nIx = 1; 2129cdf0e10cSrcweir else 2130cdf0e10cSrcweir nIx = 2; 2131cdf0e10cSrcweir } 2132*f85760deSWang Lei if (nIx == 1 && // negatives Format 2133*f85760deSWang Lei IsNegativeRealNegative() && fNumber < 0.0) // ohne Vorzeichen 2134cdf0e10cSrcweir fNumber = -fNumber; // Vorzeichen eliminieren 2135*f85760deSWang Lei if(nIx == 0 && 2136*f85760deSWang Lei IsNegativeRealNegative2() && fNumber < 0.0) 2137*f85760deSWang Lei fNumber = -fNumber; 2138cdf0e10cSrcweir *ppColor = NumFor[nIx].GetColor(); 2139cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); 2140cdf0e10cSrcweir const sal_uInt16 nAnz = NumFor[nIx].GetnAnz(); 2141cdf0e10cSrcweir if (nAnz == 0 && rInfo.eScannedType == NUMBERFORMAT_UNDEFINED) 2142cdf0e10cSrcweir return sal_False; // leer => nichts 2143cdf0e10cSrcweir else if (nAnz == 0) // sonst Standard-Format 2144cdf0e10cSrcweir { 2145cdf0e10cSrcweir ImpGetOutputStandard(fNumber, OutString); 2146cdf0e10cSrcweir return sal_False; 2147cdf0e10cSrcweir } 2148cdf0e10cSrcweir switch (rInfo.eScannedType) 2149cdf0e10cSrcweir { 2150cdf0e10cSrcweir case NUMBERFORMAT_TEXT: 2151cdf0e10cSrcweir case NUMBERFORMAT_DEFINED: 2152cdf0e10cSrcweir { 2153cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nAnz; i++) 2154cdf0e10cSrcweir { 2155cdf0e10cSrcweir switch (rInfo.nTypeArray[i]) 2156cdf0e10cSrcweir { 2157cdf0e10cSrcweir case NF_SYMBOLTYPE_STAR: 2158cdf0e10cSrcweir if( bStarFlag ) 2159cdf0e10cSrcweir { 2160cdf0e10cSrcweir OutString += (sal_Unicode) 0x1B; 2161cdf0e10cSrcweir OutString += rInfo.sStrArray[i].GetChar(1); 2162cdf0e10cSrcweir bRes = sal_True; 2163cdf0e10cSrcweir } 2164cdf0e10cSrcweir break; 2165cdf0e10cSrcweir case NF_SYMBOLTYPE_BLANK: 2166cdf0e10cSrcweir InsertBlanks( OutString, OutString.Len(), 2167cdf0e10cSrcweir rInfo.sStrArray[i].GetChar(1) ); 2168cdf0e10cSrcweir break; 2169cdf0e10cSrcweir case NF_SYMBOLTYPE_STRING: 2170cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRENCY: 2171cdf0e10cSrcweir OutString += rInfo.sStrArray[i]; 2172cdf0e10cSrcweir break; 2173cdf0e10cSrcweir case NF_SYMBOLTYPE_THSEP: 2174cdf0e10cSrcweir if (rInfo.nThousand == 0) 2175cdf0e10cSrcweir OutString += rInfo.sStrArray[i]; 2176cdf0e10cSrcweir break; 2177cdf0e10cSrcweir default: 2178cdf0e10cSrcweir break; 2179cdf0e10cSrcweir } 2180cdf0e10cSrcweir } 2181cdf0e10cSrcweir } 2182cdf0e10cSrcweir break; 2183cdf0e10cSrcweir case NUMBERFORMAT_DATE: 2184cdf0e10cSrcweir bRes |= ImpGetDateOutput(fNumber, nIx, OutString); 2185cdf0e10cSrcweir break; 2186cdf0e10cSrcweir case NUMBERFORMAT_TIME: 2187cdf0e10cSrcweir bRes |= ImpGetTimeOutput(fNumber, nIx, OutString); 2188cdf0e10cSrcweir break; 2189cdf0e10cSrcweir case NUMBERFORMAT_DATETIME: 2190cdf0e10cSrcweir bRes |= ImpGetDateTimeOutput(fNumber, nIx, OutString); 2191cdf0e10cSrcweir break; 2192cdf0e10cSrcweir case NUMBERFORMAT_NUMBER: 2193cdf0e10cSrcweir case NUMBERFORMAT_PERCENT: 2194cdf0e10cSrcweir case NUMBERFORMAT_CURRENCY: 2195cdf0e10cSrcweir bRes |= ImpGetNumberOutput(fNumber, nIx, OutString); 2196cdf0e10cSrcweir break; 2197cdf0e10cSrcweir case NUMBERFORMAT_FRACTION: 2198cdf0e10cSrcweir { 2199cdf0e10cSrcweir String sStr, sFrac, sDiv; // Strings, Wert fuer 2200cdf0e10cSrcweir sal_uLong nFrac, nDiv; // Vorkommaanteil 2201cdf0e10cSrcweir // Zaehler und Nenner 2202cdf0e10cSrcweir sal_Bool bSign = sal_False; 2203cdf0e10cSrcweir if (fNumber < 0) 2204cdf0e10cSrcweir { 2205cdf0e10cSrcweir if (nIx == 0) // nicht in hinteren 2206cdf0e10cSrcweir bSign = sal_True; // Formaten 2207cdf0e10cSrcweir fNumber = -fNumber; 2208cdf0e10cSrcweir } 2209cdf0e10cSrcweir double fNum = floor(fNumber); // Vorkommateil 2210cdf0e10cSrcweir fNumber -= fNum; // Nachkommateil 2211cdf0e10cSrcweir if (fNum > _D_MAX_U_LONG_ || rInfo.nCntExp > 9) 2212cdf0e10cSrcweir // zu gross 2213cdf0e10cSrcweir { 2214cdf0e10cSrcweir OutString = rScan.GetErrorString(); 2215cdf0e10cSrcweir return sal_False; 2216cdf0e10cSrcweir } 2217cdf0e10cSrcweir if (rInfo.nCntExp == 0) 2218cdf0e10cSrcweir { 2219cdf0e10cSrcweir DBG_ERROR("SvNumberformat:: Bruch, nCntExp == 0"); 2220cdf0e10cSrcweir return sal_False; 2221cdf0e10cSrcweir } 2222cdf0e10cSrcweir sal_uLong nBasis = ((sal_uLong)floor( // 9, 99, 999 ,... 2223cdf0e10cSrcweir pow(10.0,rInfo.nCntExp))) - 1; 2224cdf0e10cSrcweir sal_uLong x0, y0, x1, y1; 2225cdf0e10cSrcweir 2226cdf0e10cSrcweir if (rInfo.nCntExp <= _MAX_FRACTION_PREC) 2227cdf0e10cSrcweir { 2228cdf0e10cSrcweir sal_Bool bUpperHalf; 2229cdf0e10cSrcweir if (fNumber > 0.5) 2230cdf0e10cSrcweir { 2231cdf0e10cSrcweir bUpperHalf = sal_True; 2232cdf0e10cSrcweir fNumber -= (fNumber - 0.5) * 2.0; 2233cdf0e10cSrcweir } 2234cdf0e10cSrcweir else 2235cdf0e10cSrcweir bUpperHalf = sal_False; 2236cdf0e10cSrcweir // Einstieg in Farey-Serie 2237cdf0e10cSrcweir // finden: 2238cdf0e10cSrcweir x0 = (sal_uLong) floor(fNumber*nBasis); // z.B. 2/9 <= x < 3/9 2239cdf0e10cSrcweir if (x0 == 0) // => x0 = 2 2240cdf0e10cSrcweir { 2241cdf0e10cSrcweir y0 = 1; 2242cdf0e10cSrcweir x1 = 1; 2243cdf0e10cSrcweir y1 = nBasis; 2244cdf0e10cSrcweir } 2245cdf0e10cSrcweir else if (x0 == (nBasis-1)/2) // (b-1)/2, 1/2 2246cdf0e10cSrcweir { // geht (nBasis ungerade) 2247cdf0e10cSrcweir y0 = nBasis; 2248cdf0e10cSrcweir x1 = 1; 2249cdf0e10cSrcweir y1 = 2; 2250cdf0e10cSrcweir } 2251cdf0e10cSrcweir else if (x0 == 1) 2252cdf0e10cSrcweir { 2253cdf0e10cSrcweir y0 = nBasis; // 1/n; 1/(n-1) 2254cdf0e10cSrcweir x1 = 1; 2255cdf0e10cSrcweir y1 = nBasis - 1; 2256cdf0e10cSrcweir } 2257cdf0e10cSrcweir else 2258cdf0e10cSrcweir { 2259cdf0e10cSrcweir y0 = nBasis; // z.B. 2/9 2/8 2260cdf0e10cSrcweir x1 = x0; 2261cdf0e10cSrcweir y1 = nBasis - 1; 2262cdf0e10cSrcweir double fUg = (double) x0 / (double) y0; 2263cdf0e10cSrcweir double fOg = (double) x1 / (double) y1; 2264cdf0e10cSrcweir sal_uLong nGgt = ImpGGT(y0, x0); // x0/y0 kuerzen 2265cdf0e10cSrcweir x0 /= nGgt; 2266cdf0e10cSrcweir y0 /= nGgt; // Einschachteln: 2267cdf0e10cSrcweir sal_uLong x2 = 0; 2268cdf0e10cSrcweir sal_uLong y2 = 0; 2269cdf0e10cSrcweir sal_Bool bStop = sal_False; 2270cdf0e10cSrcweir while (!bStop) 2271cdf0e10cSrcweir { 2272cdf0e10cSrcweir #ifdef GCC 2273cdf0e10cSrcweir // #i21648# GCC over-optimizes something resulting 2274cdf0e10cSrcweir // in wrong fTest values throughout the loops. 2275cdf0e10cSrcweir volatile 2276cdf0e10cSrcweir #endif 2277cdf0e10cSrcweir double fTest = (double)x1/(double)y1; 2278cdf0e10cSrcweir while (!bStop) 2279cdf0e10cSrcweir { 2280cdf0e10cSrcweir while (fTest > fOg) 2281cdf0e10cSrcweir { 2282cdf0e10cSrcweir x1--; 2283cdf0e10cSrcweir fTest = (double)x1/(double)y1; 2284cdf0e10cSrcweir } 2285cdf0e10cSrcweir while (fTest < fUg && y1 > 1) 2286cdf0e10cSrcweir { 2287cdf0e10cSrcweir y1--; 2288cdf0e10cSrcweir fTest = (double)x1/(double)y1; 2289cdf0e10cSrcweir } 2290cdf0e10cSrcweir if (fTest <= fOg) 2291cdf0e10cSrcweir { 2292cdf0e10cSrcweir fOg = fTest; 2293cdf0e10cSrcweir bStop = sal_True; 2294cdf0e10cSrcweir } 2295cdf0e10cSrcweir else if (y1 == 1) 2296cdf0e10cSrcweir bStop = sal_True; 2297cdf0e10cSrcweir } // of while 2298cdf0e10cSrcweir nGgt = ImpGGT(y1, x1); // x1/y1 kuerzen 2299cdf0e10cSrcweir x2 = x1 / nGgt; 2300cdf0e10cSrcweir y2 = y1 / nGgt; 2301cdf0e10cSrcweir if (x2*y0 - x0*y2 == 1 || y1 <= 1) // Test, ob x2/y2 2302cdf0e10cSrcweir bStop = sal_True; // naechste Farey-Zahl 2303cdf0e10cSrcweir else 2304cdf0e10cSrcweir { 2305cdf0e10cSrcweir y1--; 2306cdf0e10cSrcweir bStop = sal_False; 2307cdf0e10cSrcweir } 2308cdf0e10cSrcweir } // of while 2309cdf0e10cSrcweir x1 = x2; 2310cdf0e10cSrcweir y1 = y2; 2311cdf0e10cSrcweir } // of else 2312cdf0e10cSrcweir double fup, flow; 2313cdf0e10cSrcweir flow = (double)x0/(double)y0; 2314cdf0e10cSrcweir fup = (double)x1/(double)y1; 2315cdf0e10cSrcweir while (fNumber > fup) 2316cdf0e10cSrcweir { 2317cdf0e10cSrcweir sal_uLong x2 = ((y0+nBasis)/y1)*x1 - x0; // naechste Farey-Zahl 2318cdf0e10cSrcweir sal_uLong y2 = ((y0+nBasis)/y1)*y1 - y0; 2319cdf0e10cSrcweir // GetNextFareyNumber(nBasis, x0, x1, y0, y1, x2, y2); 2320cdf0e10cSrcweir x0 = x1; 2321cdf0e10cSrcweir y0 = y1; 2322cdf0e10cSrcweir x1 = x2; 2323cdf0e10cSrcweir y1 = y2; 2324cdf0e10cSrcweir flow = fup; 2325cdf0e10cSrcweir fup = (double)x1/(double)y1; 2326cdf0e10cSrcweir } 2327cdf0e10cSrcweir if (fNumber - flow < fup - fNumber) 2328cdf0e10cSrcweir { 2329cdf0e10cSrcweir nFrac = x0; 2330cdf0e10cSrcweir nDiv = y0; 2331cdf0e10cSrcweir } 2332cdf0e10cSrcweir else 2333cdf0e10cSrcweir { 2334cdf0e10cSrcweir nFrac = x1; 2335cdf0e10cSrcweir nDiv = y1; 2336cdf0e10cSrcweir } 2337cdf0e10cSrcweir if (bUpperHalf) // Original restaur. 2338cdf0e10cSrcweir { 2339cdf0e10cSrcweir if (nFrac == 0 && nDiv == 1) // 1/1 2340cdf0e10cSrcweir fNum += 1.0; 2341cdf0e10cSrcweir else 2342cdf0e10cSrcweir nFrac = nDiv - nFrac; 2343cdf0e10cSrcweir } 2344cdf0e10cSrcweir } 2345cdf0e10cSrcweir else // grosse Nenner 2346cdf0e10cSrcweir { // 0,1234->123/1000 2347cdf0e10cSrcweir sal_uLong nGgt; 2348cdf0e10cSrcweir /* 2349cdf0e10cSrcweir nDiv = nBasis+1; 2350cdf0e10cSrcweir nFrac = ((sal_uLong)floor(0.5 + fNumber * 2351cdf0e10cSrcweir pow(10.0,rInfo.nCntExp))); 2352cdf0e10cSrcweir */ 2353cdf0e10cSrcweir nDiv = 10000000; 2354cdf0e10cSrcweir nFrac = ((sal_uLong)floor(0.5 + fNumber * 10000000.0)); 2355cdf0e10cSrcweir nGgt = ImpGGT(nDiv, nFrac); 2356cdf0e10cSrcweir if (nGgt > 1) 2357cdf0e10cSrcweir { 2358cdf0e10cSrcweir nDiv /= nGgt; 2359cdf0e10cSrcweir nFrac /= nGgt; 2360cdf0e10cSrcweir } 2361cdf0e10cSrcweir if (nDiv > nBasis) 2362cdf0e10cSrcweir { 2363cdf0e10cSrcweir nGgt = ImpGGTRound(nDiv, nFrac); 2364cdf0e10cSrcweir if (nGgt > 1) 2365cdf0e10cSrcweir { 2366cdf0e10cSrcweir nDiv /= nGgt; 2367cdf0e10cSrcweir nFrac /= nGgt; 2368cdf0e10cSrcweir } 2369cdf0e10cSrcweir } 2370cdf0e10cSrcweir if (nDiv > nBasis) 2371cdf0e10cSrcweir { 2372cdf0e10cSrcweir nDiv = nBasis; 2373cdf0e10cSrcweir nFrac = ((sal_uLong)floor(0.5 + fNumber * 2374cdf0e10cSrcweir pow(10.0,rInfo.nCntExp))); 2375cdf0e10cSrcweir nGgt = ImpGGTRound(nDiv, nFrac); 2376cdf0e10cSrcweir if (nGgt > 1) 2377cdf0e10cSrcweir { 2378cdf0e10cSrcweir nDiv /= nGgt; 2379cdf0e10cSrcweir nFrac /= nGgt; 2380cdf0e10cSrcweir } 2381cdf0e10cSrcweir } 2382cdf0e10cSrcweir } 2383cdf0e10cSrcweir 2384cdf0e10cSrcweir if (rInfo.nCntPre == 0) // unechter Bruch 2385cdf0e10cSrcweir { 2386cdf0e10cSrcweir double fNum1 = fNum * (double)nDiv + (double)nFrac; 2387cdf0e10cSrcweir if (fNum1 > _D_MAX_U_LONG_) 2388cdf0e10cSrcweir { 2389cdf0e10cSrcweir OutString = rScan.GetErrorString(); 2390cdf0e10cSrcweir return sal_False; 2391cdf0e10cSrcweir } 2392cdf0e10cSrcweir nFrac = (sal_uLong) floor(fNum1); 2393cdf0e10cSrcweir sStr.Erase(); 2394cdf0e10cSrcweir } 2395cdf0e10cSrcweir else if (fNum == 0.0 && nFrac != 0) 2396cdf0e10cSrcweir sStr.Erase(); 2397cdf0e10cSrcweir else 2398cdf0e10cSrcweir { 2399cdf0e10cSrcweir char aBuf[100]; 2400cdf0e10cSrcweir sprintf( aBuf, "%.f", fNum ); // simple rounded integer (#100211# - checked) 2401cdf0e10cSrcweir sStr.AssignAscii( aBuf ); 2402cdf0e10cSrcweir ImpTransliterate( sStr, NumFor[nIx].GetNatNum() ); 2403cdf0e10cSrcweir } 2404cdf0e10cSrcweir if (rInfo.nCntPre > 0 && nFrac == 0) 2405cdf0e10cSrcweir { 2406cdf0e10cSrcweir sFrac.Erase(); 2407cdf0e10cSrcweir sDiv.Erase(); 2408cdf0e10cSrcweir } 2409cdf0e10cSrcweir else 2410cdf0e10cSrcweir { 2411cdf0e10cSrcweir sFrac = ImpIntToString( nIx, nFrac ); 2412cdf0e10cSrcweir sDiv = ImpIntToString( nIx, nDiv ); 2413cdf0e10cSrcweir } 2414cdf0e10cSrcweir 2415cdf0e10cSrcweir sal_uInt16 j = nAnz-1; // letztes Symbol->rueckw. 2416cdf0e10cSrcweir xub_StrLen k; // Nenner: 2417cdf0e10cSrcweir bRes |= ImpNumberFill(sDiv, fNumber, k, j, nIx, NF_SYMBOLTYPE_FRAC); 2418cdf0e10cSrcweir sal_Bool bCont = sal_True; 2419cdf0e10cSrcweir if (rInfo.nTypeArray[j] == NF_SYMBOLTYPE_FRAC) 2420cdf0e10cSrcweir { 2421cdf0e10cSrcweir if (rInfo.nCntPre > 0 && nFrac == 0) 2422cdf0e10cSrcweir sDiv.Insert(' ',0); 2423cdf0e10cSrcweir else 2424cdf0e10cSrcweir sDiv.Insert( rInfo.sStrArray[j].GetChar(0), 0 ); 2425cdf0e10cSrcweir if ( j ) 2426cdf0e10cSrcweir j--; 2427cdf0e10cSrcweir else 2428cdf0e10cSrcweir bCont = sal_False; 2429cdf0e10cSrcweir } 2430cdf0e10cSrcweir // weiter Zaehler: 2431cdf0e10cSrcweir if ( !bCont ) 2432cdf0e10cSrcweir sFrac.Erase(); 2433cdf0e10cSrcweir else 2434cdf0e10cSrcweir { 2435cdf0e10cSrcweir bRes |= ImpNumberFill(sFrac, fNumber, k, j, nIx, NF_SYMBOLTYPE_FRACBLANK); 2436cdf0e10cSrcweir if (rInfo.nTypeArray[j] == NF_SYMBOLTYPE_FRACBLANK) 2437cdf0e10cSrcweir { 2438cdf0e10cSrcweir sFrac.Insert(rInfo.sStrArray[j],0); 2439cdf0e10cSrcweir if ( j ) 2440cdf0e10cSrcweir j--; 2441cdf0e10cSrcweir else 2442cdf0e10cSrcweir bCont = sal_False; 2443cdf0e10cSrcweir } 2444cdf0e10cSrcweir } 2445cdf0e10cSrcweir // weiter Hauptzahl 2446cdf0e10cSrcweir if ( !bCont ) 2447cdf0e10cSrcweir sStr.Erase(); 2448cdf0e10cSrcweir else 2449cdf0e10cSrcweir { 2450cdf0e10cSrcweir k = sStr.Len(); // hinter letzter Ziffer 2451cdf0e10cSrcweir bRes |= ImpNumberFillWithThousands(sStr, fNumber, k, j, nIx, 2452cdf0e10cSrcweir rInfo.nCntPre); 2453cdf0e10cSrcweir } 2454cdf0e10cSrcweir if (bSign && !(nFrac == 0 && fNum == 0.0)) 2455cdf0e10cSrcweir OutString.Insert('-',0); // nicht -0 2456cdf0e10cSrcweir OutString += sStr; 2457cdf0e10cSrcweir OutString += sFrac; 2458cdf0e10cSrcweir OutString += sDiv; 2459cdf0e10cSrcweir } 2460cdf0e10cSrcweir break; 2461cdf0e10cSrcweir case NUMBERFORMAT_SCIENTIFIC: 2462cdf0e10cSrcweir { 2463cdf0e10cSrcweir sal_Bool bSign = sal_False; 2464cdf0e10cSrcweir if (fNumber < 0) 2465cdf0e10cSrcweir { 2466cdf0e10cSrcweir if (nIx == 0) // nicht in hinteren 2467cdf0e10cSrcweir bSign = sal_True; // Formaten 2468cdf0e10cSrcweir fNumber = -fNumber; 2469cdf0e10cSrcweir } 2470cdf0e10cSrcweir String sStr( ::rtl::math::doubleToUString( fNumber, 2471cdf0e10cSrcweir rtl_math_StringFormat_E, 2472cdf0e10cSrcweir rInfo.nCntPre + rInfo.nCntPost - 1, '.' )); 2473cdf0e10cSrcweir 2474cdf0e10cSrcweir String ExpStr; 2475cdf0e10cSrcweir short nExpSign = 1; 2476cdf0e10cSrcweir xub_StrLen nExPos = sStr.Search('E'); 2477cdf0e10cSrcweir if ( nExPos != STRING_NOTFOUND ) 2478cdf0e10cSrcweir { 2479cdf0e10cSrcweir // split into mantisse and exponent and get rid of "E+" or "E-" 2480cdf0e10cSrcweir xub_StrLen nExpStart = nExPos + 1; 2481cdf0e10cSrcweir switch ( sStr.GetChar( nExpStart ) ) 2482cdf0e10cSrcweir { 2483cdf0e10cSrcweir case '-' : 2484cdf0e10cSrcweir nExpSign = -1; 2485cdf0e10cSrcweir // fallthru 2486cdf0e10cSrcweir case '+' : 2487cdf0e10cSrcweir ++nExpStart; 2488cdf0e10cSrcweir break; 2489cdf0e10cSrcweir } 2490cdf0e10cSrcweir ExpStr = sStr.Copy( nExpStart ); // part following the "E+" 2491cdf0e10cSrcweir sStr.Erase( nExPos ); 2492cdf0e10cSrcweir sStr.EraseAllChars('.'); // cut any decimal delimiter 2493cdf0e10cSrcweir if ( rInfo.nCntPre != 1 ) // rescale Exp 2494cdf0e10cSrcweir { 2495cdf0e10cSrcweir sal_Int32 nExp = ExpStr.ToInt32() * nExpSign; 2496cdf0e10cSrcweir nExp -= sal_Int32(rInfo.nCntPre)-1; 2497cdf0e10cSrcweir if ( nExp < 0 ) 2498cdf0e10cSrcweir { 2499cdf0e10cSrcweir nExpSign = -1; 2500cdf0e10cSrcweir nExp = -nExp; 2501cdf0e10cSrcweir } 2502cdf0e10cSrcweir else 2503cdf0e10cSrcweir nExpSign = 1; 2504cdf0e10cSrcweir ExpStr = String::CreateFromInt32( nExp ); 2505cdf0e10cSrcweir } 2506cdf0e10cSrcweir } 2507cdf0e10cSrcweir sal_uInt16 j = nAnz-1; // last symbol 2508cdf0e10cSrcweir xub_StrLen k; // position in ExpStr 2509cdf0e10cSrcweir bRes |= ImpNumberFill(ExpStr, fNumber, k, j, nIx, NF_SYMBOLTYPE_EXP); 2510cdf0e10cSrcweir 2511cdf0e10cSrcweir xub_StrLen nZeros = 0; // erase leading zeros 2512cdf0e10cSrcweir while (nZeros < k && ExpStr.GetChar(nZeros) == '0') 2513cdf0e10cSrcweir ++nZeros; 2514cdf0e10cSrcweir if (nZeros) 2515cdf0e10cSrcweir ExpStr.Erase( 0, nZeros); 2516cdf0e10cSrcweir 2517cdf0e10cSrcweir sal_Bool bCont = sal_True; 2518cdf0e10cSrcweir if (rInfo.nTypeArray[j] == NF_SYMBOLTYPE_EXP) 2519cdf0e10cSrcweir { 2520cdf0e10cSrcweir const String& rStr = rInfo.sStrArray[j]; 2521cdf0e10cSrcweir if (nExpSign == -1) 2522cdf0e10cSrcweir ExpStr.Insert('-',0); 2523cdf0e10cSrcweir else if (rStr.Len() > 1 && rStr.GetChar(1) == '+') 2524cdf0e10cSrcweir ExpStr.Insert('+',0); 2525cdf0e10cSrcweir ExpStr.Insert(rStr.GetChar(0),0); 2526cdf0e10cSrcweir if ( j ) 2527cdf0e10cSrcweir j--; 2528cdf0e10cSrcweir else 2529cdf0e10cSrcweir bCont = sal_False; 2530cdf0e10cSrcweir } 2531cdf0e10cSrcweir // weiter Hauptzahl: 2532cdf0e10cSrcweir if ( !bCont ) 2533cdf0e10cSrcweir sStr.Erase(); 2534cdf0e10cSrcweir else 2535cdf0e10cSrcweir { 2536cdf0e10cSrcweir k = sStr.Len(); // hinter letzter Ziffer 2537cdf0e10cSrcweir bRes |= ImpNumberFillWithThousands(sStr,fNumber, k,j,nIx, 2538cdf0e10cSrcweir rInfo.nCntPre + 2539cdf0e10cSrcweir rInfo.nCntPost); 2540cdf0e10cSrcweir } 2541cdf0e10cSrcweir if (bSign) 2542cdf0e10cSrcweir sStr.Insert('-',0); 2543cdf0e10cSrcweir OutString = sStr; 2544cdf0e10cSrcweir OutString += ExpStr; 2545cdf0e10cSrcweir } 2546cdf0e10cSrcweir break; 2547cdf0e10cSrcweir } 2548cdf0e10cSrcweir } 2549cdf0e10cSrcweir return bRes; 2550cdf0e10cSrcweir } 2551cdf0e10cSrcweir 2552cdf0e10cSrcweir sal_Bool SvNumberformat::ImpGetTimeOutput(double fNumber, 2553cdf0e10cSrcweir sal_uInt16 nIx, 2554cdf0e10cSrcweir String& OutString) 2555cdf0e10cSrcweir { 2556cdf0e10cSrcweir using namespace ::com::sun::star::i18n; 2557cdf0e10cSrcweir sal_Bool bCalendarSet = sal_False; 2558cdf0e10cSrcweir double fNumberOrig = fNumber; 2559cdf0e10cSrcweir sal_Bool bRes = sal_False; 2560cdf0e10cSrcweir sal_Bool bSign = sal_False; 2561cdf0e10cSrcweir if (fNumber < 0.0) 2562cdf0e10cSrcweir { 2563cdf0e10cSrcweir fNumber = -fNumber; 2564cdf0e10cSrcweir if (nIx == 0) 2565cdf0e10cSrcweir bSign = sal_True; 2566cdf0e10cSrcweir } 2567cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); 2568cdf0e10cSrcweir if (rInfo.bThousand) // []-Format 2569cdf0e10cSrcweir { 2570cdf0e10cSrcweir if (fNumber > 1.0E10) // zu gross 2571cdf0e10cSrcweir { 2572cdf0e10cSrcweir OutString = rScan.GetErrorString(); 2573cdf0e10cSrcweir return sal_False; 2574cdf0e10cSrcweir } 2575cdf0e10cSrcweir } 2576cdf0e10cSrcweir else 2577cdf0e10cSrcweir fNumber -= floor(fNumber); // sonst Datum abtrennen 2578cdf0e10cSrcweir sal_Bool bInputLine; 2579cdf0e10cSrcweir xub_StrLen nCntPost; 2580cdf0e10cSrcweir if ( rScan.GetStandardPrec() == 300 && 2581cdf0e10cSrcweir 0 < rInfo.nCntPost && rInfo.nCntPost < 7 ) 2582cdf0e10cSrcweir { // round at 7 decimals (+5 of 86400 == 12 significant digits) 2583cdf0e10cSrcweir bInputLine = sal_True; 2584cdf0e10cSrcweir nCntPost = 7; 2585cdf0e10cSrcweir } 2586cdf0e10cSrcweir else 2587cdf0e10cSrcweir { 2588cdf0e10cSrcweir bInputLine = sal_False; 2589cdf0e10cSrcweir nCntPost = xub_StrLen(rInfo.nCntPost); 2590cdf0e10cSrcweir } 2591cdf0e10cSrcweir if (bSign && !rInfo.bThousand) // kein []-Format 2592cdf0e10cSrcweir fNumber = 1.0 - fNumber; // "Kehrwert" 2593cdf0e10cSrcweir double fTime = fNumber * 86400.0; 2594cdf0e10cSrcweir fTime = ::rtl::math::round( fTime, int(nCntPost) ); 2595cdf0e10cSrcweir if (bSign && fTime == 0.0) 2596cdf0e10cSrcweir bSign = sal_False; // nicht -00:00:00 2597cdf0e10cSrcweir 2598cdf0e10cSrcweir if( floor( fTime ) > _D_MAX_U_LONG_ ) 2599cdf0e10cSrcweir { 2600cdf0e10cSrcweir OutString = rScan.GetErrorString(); 2601cdf0e10cSrcweir return sal_False; 2602cdf0e10cSrcweir } 2603cdf0e10cSrcweir sal_uLong nSeconds = (sal_uLong)floor( fTime ); 2604cdf0e10cSrcweir 2605cdf0e10cSrcweir String sSecStr( ::rtl::math::doubleToUString( fTime-nSeconds, 2606cdf0e10cSrcweir rtl_math_StringFormat_F, int(nCntPost), '.')); 2607cdf0e10cSrcweir sSecStr.EraseLeadingChars('0'); 2608cdf0e10cSrcweir sSecStr.EraseLeadingChars('.'); 2609cdf0e10cSrcweir if ( bInputLine ) 2610cdf0e10cSrcweir { 2611cdf0e10cSrcweir sSecStr.EraseTrailingChars('0'); 2612cdf0e10cSrcweir if ( sSecStr.Len() < xub_StrLen(rInfo.nCntPost) ) 2613cdf0e10cSrcweir sSecStr.Expand( xub_StrLen(rInfo.nCntPost), '0' ); 2614cdf0e10cSrcweir ImpTransliterate( sSecStr, NumFor[nIx].GetNatNum() ); 2615cdf0e10cSrcweir nCntPost = sSecStr.Len(); 2616cdf0e10cSrcweir } 2617cdf0e10cSrcweir else 2618cdf0e10cSrcweir ImpTransliterate( sSecStr, NumFor[nIx].GetNatNum() ); 2619cdf0e10cSrcweir 2620cdf0e10cSrcweir xub_StrLen nSecPos = 0; // Zum Ziffernweisen 2621cdf0e10cSrcweir // abarbeiten 2622cdf0e10cSrcweir sal_uLong nHour, nMin, nSec; 2623cdf0e10cSrcweir if (!rInfo.bThousand) // kein [] Format 2624cdf0e10cSrcweir { 2625cdf0e10cSrcweir nHour = (nSeconds/3600) % 24; 2626cdf0e10cSrcweir nMin = (nSeconds%3600) / 60; 2627cdf0e10cSrcweir nSec = nSeconds%60; 2628cdf0e10cSrcweir } 2629cdf0e10cSrcweir else if (rInfo.nThousand == 3) // [ss] 2630cdf0e10cSrcweir { 2631cdf0e10cSrcweir nHour = 0; 2632cdf0e10cSrcweir nMin = 0; 2633cdf0e10cSrcweir nSec = nSeconds; 2634cdf0e10cSrcweir } 2635cdf0e10cSrcweir else if (rInfo.nThousand == 2) // [mm]:ss 2636cdf0e10cSrcweir { 2637cdf0e10cSrcweir nHour = 0; 2638cdf0e10cSrcweir nMin = nSeconds / 60; 2639cdf0e10cSrcweir nSec = nSeconds % 60; 2640cdf0e10cSrcweir } 2641cdf0e10cSrcweir else if (rInfo.nThousand == 1) // [hh]:mm:ss 2642cdf0e10cSrcweir { 2643cdf0e10cSrcweir nHour = nSeconds / 3600; 2644cdf0e10cSrcweir nMin = (nSeconds%3600) / 60; 2645cdf0e10cSrcweir nSec = nSeconds%60; 2646cdf0e10cSrcweir } 2647cdf0e10cSrcweir else { 2648cdf0e10cSrcweir // TODO What should these be set to? 2649cdf0e10cSrcweir nHour = 0; 2650cdf0e10cSrcweir nMin = 0; 2651cdf0e10cSrcweir nSec = 0; 2652cdf0e10cSrcweir } 2653cdf0e10cSrcweir 2654cdf0e10cSrcweir sal_Unicode cAmPm = ' '; // a oder p 2655cdf0e10cSrcweir if (rInfo.nCntExp) // AM/PM 2656cdf0e10cSrcweir { 2657cdf0e10cSrcweir if (nHour == 0) 2658cdf0e10cSrcweir { 2659cdf0e10cSrcweir nHour = 12; 2660cdf0e10cSrcweir cAmPm = 'a'; 2661cdf0e10cSrcweir } 2662cdf0e10cSrcweir else if (nHour < 12) 2663cdf0e10cSrcweir cAmPm = 'a'; 2664cdf0e10cSrcweir else 2665cdf0e10cSrcweir { 2666cdf0e10cSrcweir cAmPm = 'p'; 2667cdf0e10cSrcweir if (nHour > 12) 2668cdf0e10cSrcweir nHour -= 12; 2669cdf0e10cSrcweir } 2670cdf0e10cSrcweir } 2671cdf0e10cSrcweir const sal_uInt16 nAnz = NumFor[nIx].GetnAnz(); 2672cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nAnz; i++) 2673cdf0e10cSrcweir { 2674cdf0e10cSrcweir switch (rInfo.nTypeArray[i]) 2675cdf0e10cSrcweir { 2676cdf0e10cSrcweir case NF_SYMBOLTYPE_STAR: 2677cdf0e10cSrcweir if( bStarFlag ) 2678cdf0e10cSrcweir { 2679cdf0e10cSrcweir OutString += (sal_Unicode) 0x1B; 2680cdf0e10cSrcweir OutString += rInfo.sStrArray[i].GetChar(1); 2681cdf0e10cSrcweir bRes = sal_True; 2682cdf0e10cSrcweir } 2683cdf0e10cSrcweir break; 2684cdf0e10cSrcweir case NF_SYMBOLTYPE_BLANK: 2685cdf0e10cSrcweir InsertBlanks( OutString, OutString.Len(), 2686cdf0e10cSrcweir rInfo.sStrArray[i].GetChar(1) ); 2687cdf0e10cSrcweir break; 2688cdf0e10cSrcweir case NF_SYMBOLTYPE_STRING: 2689cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRENCY: 2690cdf0e10cSrcweir case NF_SYMBOLTYPE_DATESEP: 2691cdf0e10cSrcweir case NF_SYMBOLTYPE_TIMESEP: 2692cdf0e10cSrcweir case NF_SYMBOLTYPE_TIME100SECSEP: 2693cdf0e10cSrcweir OutString += rInfo.sStrArray[i]; 2694cdf0e10cSrcweir break; 2695cdf0e10cSrcweir case NF_SYMBOLTYPE_DIGIT: 2696cdf0e10cSrcweir { 2697cdf0e10cSrcweir xub_StrLen nLen = ( bInputLine && i > 0 && 2698cdf0e10cSrcweir (rInfo.nTypeArray[i-1] == NF_SYMBOLTYPE_STRING || 2699cdf0e10cSrcweir rInfo.nTypeArray[i-1] == NF_SYMBOLTYPE_TIME100SECSEP) ? 2700cdf0e10cSrcweir nCntPost : rInfo.sStrArray[i].Len() ); 2701cdf0e10cSrcweir for (xub_StrLen j = 0; j < nLen && nSecPos < nCntPost; j++) 2702cdf0e10cSrcweir { 2703cdf0e10cSrcweir OutString += sSecStr.GetChar(nSecPos); 2704cdf0e10cSrcweir nSecPos++; 2705cdf0e10cSrcweir } 2706cdf0e10cSrcweir } 2707cdf0e10cSrcweir break; 2708cdf0e10cSrcweir case NF_KEY_AMPM: // AM/PM 2709cdf0e10cSrcweir { 2710cdf0e10cSrcweir if ( !bCalendarSet ) 2711cdf0e10cSrcweir { 2712cdf0e10cSrcweir double fDiff = DateTime(*(rScan.GetNullDate())) - GetCal().getEpochStart(); 2713cdf0e10cSrcweir fDiff += fNumberOrig; 2714cdf0e10cSrcweir GetCal().setLocalDateTime( fDiff ); 2715cdf0e10cSrcweir bCalendarSet = sal_True; 2716cdf0e10cSrcweir } 2717cdf0e10cSrcweir if (cAmPm == 'a') 2718cdf0e10cSrcweir OutString += GetCal().getDisplayName( 2719cdf0e10cSrcweir CalendarDisplayIndex::AM_PM, AmPmValue::AM, 0 ); 2720cdf0e10cSrcweir else 2721cdf0e10cSrcweir OutString += GetCal().getDisplayName( 2722cdf0e10cSrcweir CalendarDisplayIndex::AM_PM, AmPmValue::PM, 0 ); 2723cdf0e10cSrcweir } 2724cdf0e10cSrcweir break; 2725cdf0e10cSrcweir case NF_KEY_AP: // A/P 2726cdf0e10cSrcweir { 2727cdf0e10cSrcweir if (cAmPm == 'a') 2728cdf0e10cSrcweir OutString += 'a'; 2729cdf0e10cSrcweir else 2730cdf0e10cSrcweir OutString += 'p'; 2731cdf0e10cSrcweir } 2732cdf0e10cSrcweir break; 2733cdf0e10cSrcweir case NF_KEY_MI: // M 2734cdf0e10cSrcweir OutString += ImpIntToString( nIx, nMin ); 2735cdf0e10cSrcweir break; 2736cdf0e10cSrcweir case NF_KEY_MMI: // MM 2737cdf0e10cSrcweir OutString += ImpIntToString( nIx, nMin, 2 ); 2738cdf0e10cSrcweir break; 2739cdf0e10cSrcweir case NF_KEY_H: // H 2740cdf0e10cSrcweir OutString += ImpIntToString( nIx, nHour ); 2741cdf0e10cSrcweir break; 2742cdf0e10cSrcweir case NF_KEY_HH: // HH 2743cdf0e10cSrcweir OutString += ImpIntToString( nIx, nHour, 2 ); 2744cdf0e10cSrcweir break; 2745cdf0e10cSrcweir case NF_KEY_S: // S 2746cdf0e10cSrcweir OutString += ImpIntToString( nIx, nSec ); 2747cdf0e10cSrcweir break; 2748cdf0e10cSrcweir case NF_KEY_SS: // SS 2749cdf0e10cSrcweir OutString += ImpIntToString( nIx, nSec, 2 ); 2750cdf0e10cSrcweir break; 2751cdf0e10cSrcweir default: 2752cdf0e10cSrcweir break; 2753cdf0e10cSrcweir } 2754cdf0e10cSrcweir } 2755cdf0e10cSrcweir if (bSign && rInfo.bThousand) 2756cdf0e10cSrcweir OutString.Insert('-',0); 2757cdf0e10cSrcweir return bRes; 2758cdf0e10cSrcweir } 2759cdf0e10cSrcweir 2760cdf0e10cSrcweir 2761cdf0e10cSrcweir sal_Bool SvNumberformat::ImpIsOtherCalendar( const ImpSvNumFor& rNumFor ) const 2762cdf0e10cSrcweir { 2763cdf0e10cSrcweir if ( GetCal().getUniqueID() != Gregorian::get() ) 2764cdf0e10cSrcweir return sal_False; 2765cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = rNumFor.Info(); 2766cdf0e10cSrcweir const sal_uInt16 nAnz = rNumFor.GetnAnz(); 2767cdf0e10cSrcweir sal_uInt16 i; 2768cdf0e10cSrcweir for ( i = 0; i < nAnz; i++ ) 2769cdf0e10cSrcweir { 2770cdf0e10cSrcweir switch ( rInfo.nTypeArray[i] ) 2771cdf0e10cSrcweir { 2772cdf0e10cSrcweir case NF_SYMBOLTYPE_CALENDAR : 2773cdf0e10cSrcweir return sal_False; 2774cdf0e10cSrcweir case NF_KEY_EC : 2775cdf0e10cSrcweir case NF_KEY_EEC : 2776cdf0e10cSrcweir case NF_KEY_R : 2777cdf0e10cSrcweir case NF_KEY_RR : 2778cdf0e10cSrcweir case NF_KEY_AAA : 2779cdf0e10cSrcweir case NF_KEY_AAAA : 2780cdf0e10cSrcweir return sal_True; 2781cdf0e10cSrcweir } 2782cdf0e10cSrcweir } 2783cdf0e10cSrcweir return sal_False; 2784cdf0e10cSrcweir } 2785cdf0e10cSrcweir 2786cdf0e10cSrcweir 2787cdf0e10cSrcweir void SvNumberformat::SwitchToOtherCalendar( String& rOrgCalendar, 2788cdf0e10cSrcweir double& fOrgDateTime ) const 2789cdf0e10cSrcweir { 2790cdf0e10cSrcweir CalendarWrapper& rCal = GetCal(); 2791cdf0e10cSrcweir const rtl::OUString &rGregorian = Gregorian::get(); 2792cdf0e10cSrcweir if ( rCal.getUniqueID() == rGregorian ) 2793cdf0e10cSrcweir { 2794cdf0e10cSrcweir using namespace ::com::sun::star::i18n; 2795cdf0e10cSrcweir ::com::sun::star::uno::Sequence< ::rtl::OUString > xCals 2796cdf0e10cSrcweir = rCal.getAllCalendars( rLoc().getLocale() ); 2797cdf0e10cSrcweir sal_Int32 nCnt = xCals.getLength(); 2798cdf0e10cSrcweir if ( nCnt > 1 ) 2799cdf0e10cSrcweir { 2800cdf0e10cSrcweir for ( sal_Int32 j=0; j < nCnt; j++ ) 2801cdf0e10cSrcweir { 2802cdf0e10cSrcweir if ( xCals[j] != rGregorian ) 2803cdf0e10cSrcweir { 2804cdf0e10cSrcweir if ( !rOrgCalendar.Len() ) 2805cdf0e10cSrcweir { 2806cdf0e10cSrcweir rOrgCalendar = rCal.getUniqueID(); 2807cdf0e10cSrcweir fOrgDateTime = rCal.getDateTime(); 2808cdf0e10cSrcweir } 2809cdf0e10cSrcweir rCal.loadCalendar( xCals[j], rLoc().getLocale() ); 2810cdf0e10cSrcweir rCal.setDateTime( fOrgDateTime ); 2811cdf0e10cSrcweir break; // for 2812cdf0e10cSrcweir } 2813cdf0e10cSrcweir } 2814cdf0e10cSrcweir } 2815cdf0e10cSrcweir } 2816cdf0e10cSrcweir } 2817cdf0e10cSrcweir 2818cdf0e10cSrcweir 2819cdf0e10cSrcweir void SvNumberformat::SwitchToGregorianCalendar( const String& rOrgCalendar, 2820cdf0e10cSrcweir double fOrgDateTime ) const 2821cdf0e10cSrcweir { 2822cdf0e10cSrcweir CalendarWrapper& rCal = GetCal(); 2823cdf0e10cSrcweir const rtl::OUString &rGregorian = Gregorian::get(); 2824cdf0e10cSrcweir if ( rOrgCalendar.Len() && rCal.getUniqueID() != rGregorian ) 2825cdf0e10cSrcweir { 2826cdf0e10cSrcweir rCal.loadCalendar( rGregorian, rLoc().getLocale() ); 2827cdf0e10cSrcweir rCal.setDateTime( fOrgDateTime ); 2828cdf0e10cSrcweir } 2829cdf0e10cSrcweir } 2830cdf0e10cSrcweir 2831cdf0e10cSrcweir 2832cdf0e10cSrcweir sal_Bool SvNumberformat::ImpFallBackToGregorianCalendar( String& rOrgCalendar, double& fOrgDateTime ) 2833cdf0e10cSrcweir { 2834cdf0e10cSrcweir using namespace ::com::sun::star::i18n; 2835cdf0e10cSrcweir CalendarWrapper& rCal = GetCal(); 2836cdf0e10cSrcweir const rtl::OUString &rGregorian = Gregorian::get(); 2837cdf0e10cSrcweir if ( rCal.getUniqueID() != rGregorian ) 2838cdf0e10cSrcweir { 2839cdf0e10cSrcweir sal_Int16 nVal = rCal.getValue( CalendarFieldIndex::ERA ); 2840cdf0e10cSrcweir if ( nVal == 0 && rCal.getLoadedCalendar().Eras[0].ID.equalsAsciiL( 2841cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM( "Dummy" ) ) ) 2842cdf0e10cSrcweir { 2843cdf0e10cSrcweir if ( !rOrgCalendar.Len() ) 2844cdf0e10cSrcweir { 2845cdf0e10cSrcweir rOrgCalendar = rCal.getUniqueID(); 2846cdf0e10cSrcweir fOrgDateTime = rCal.getDateTime(); 2847cdf0e10cSrcweir } 2848cdf0e10cSrcweir else if ( rOrgCalendar == String(rGregorian) ) 2849cdf0e10cSrcweir rOrgCalendar.Erase(); 2850cdf0e10cSrcweir rCal.loadCalendar( rGregorian, rLoc().getLocale() ); 2851cdf0e10cSrcweir rCal.setDateTime( fOrgDateTime ); 2852cdf0e10cSrcweir return sal_True; 2853cdf0e10cSrcweir } 2854cdf0e10cSrcweir } 2855cdf0e10cSrcweir return sal_False; 2856cdf0e10cSrcweir } 2857cdf0e10cSrcweir 2858cdf0e10cSrcweir 2859cdf0e10cSrcweir sal_Bool SvNumberformat::ImpSwitchToSpecifiedCalendar( String& rOrgCalendar, 2860cdf0e10cSrcweir double& fOrgDateTime, const ImpSvNumFor& rNumFor ) const 2861cdf0e10cSrcweir { 2862cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = rNumFor.Info(); 2863cdf0e10cSrcweir const sal_uInt16 nAnz = rNumFor.GetnAnz(); 2864cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < nAnz; i++ ) 2865cdf0e10cSrcweir { 2866cdf0e10cSrcweir if ( rInfo.nTypeArray[i] == NF_SYMBOLTYPE_CALENDAR ) 2867cdf0e10cSrcweir { 2868cdf0e10cSrcweir CalendarWrapper& rCal = GetCal(); 2869cdf0e10cSrcweir if ( !rOrgCalendar.Len() ) 2870cdf0e10cSrcweir { 2871cdf0e10cSrcweir rOrgCalendar = rCal.getUniqueID(); 2872cdf0e10cSrcweir fOrgDateTime = rCal.getDateTime(); 2873cdf0e10cSrcweir } 2874cdf0e10cSrcweir rCal.loadCalendar( rInfo.sStrArray[i], rLoc().getLocale() ); 2875cdf0e10cSrcweir rCal.setDateTime( fOrgDateTime ); 2876cdf0e10cSrcweir return sal_True; 2877cdf0e10cSrcweir } 2878cdf0e10cSrcweir } 2879cdf0e10cSrcweir return sal_False; 2880cdf0e10cSrcweir } 2881cdf0e10cSrcweir 2882cdf0e10cSrcweir 2883cdf0e10cSrcweir // static 2884cdf0e10cSrcweir void SvNumberformat::ImpAppendEraG( String& OutString, 2885cdf0e10cSrcweir const CalendarWrapper& rCal, sal_Int16 nNatNum ) 2886cdf0e10cSrcweir { 2887cdf0e10cSrcweir using namespace ::com::sun::star::i18n; 2888cdf0e10cSrcweir if ( rCal.getUniqueID().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "gengou" ) ) ) 2889cdf0e10cSrcweir { 2890cdf0e10cSrcweir sal_Unicode cEra; 2891cdf0e10cSrcweir sal_Int16 nVal = rCal.getValue( CalendarFieldIndex::ERA ); 2892cdf0e10cSrcweir switch ( nVal ) 2893cdf0e10cSrcweir { 2894cdf0e10cSrcweir case 1 : cEra = 'M'; break; 2895cdf0e10cSrcweir case 2 : cEra = 'T'; break; 2896cdf0e10cSrcweir case 3 : cEra = 'S'; break; 2897cdf0e10cSrcweir case 4 : cEra = 'H'; break; 2898cdf0e10cSrcweir default: 2899cdf0e10cSrcweir cEra = '?'; 2900cdf0e10cSrcweir } 2901cdf0e10cSrcweir OutString += cEra; 2902cdf0e10cSrcweir } 2903cdf0e10cSrcweir else 2904cdf0e10cSrcweir OutString += rCal.getDisplayString( CalendarDisplayCode::SHORT_ERA, nNatNum ); 2905cdf0e10cSrcweir } 2906cdf0e10cSrcweir 2907cdf0e10cSrcweir 2908cdf0e10cSrcweir sal_Bool SvNumberformat::ImpGetDateOutput(double fNumber, 2909cdf0e10cSrcweir sal_uInt16 nIx, 2910cdf0e10cSrcweir String& OutString) 2911cdf0e10cSrcweir { 2912cdf0e10cSrcweir using namespace ::com::sun::star::i18n; 2913cdf0e10cSrcweir sal_Bool bRes = sal_False; 2914cdf0e10cSrcweir CalendarWrapper& rCal = GetCal(); 2915cdf0e10cSrcweir double fDiff = DateTime(*(rScan.GetNullDate())) - rCal.getEpochStart(); 2916cdf0e10cSrcweir fNumber += fDiff; 2917cdf0e10cSrcweir rCal.setLocalDateTime( fNumber ); 2918cdf0e10cSrcweir String aOrgCalendar; // empty => not changed yet 2919cdf0e10cSrcweir double fOrgDateTime; 2920cdf0e10cSrcweir sal_Bool bOtherCalendar = ImpIsOtherCalendar( NumFor[nIx] ); 2921cdf0e10cSrcweir if ( bOtherCalendar ) 2922cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 2923cdf0e10cSrcweir if ( ImpFallBackToGregorianCalendar( aOrgCalendar, fOrgDateTime ) ) 2924cdf0e10cSrcweir bOtherCalendar = sal_False; 2925cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); 2926cdf0e10cSrcweir const sal_uInt16 nAnz = NumFor[nIx].GetnAnz(); 2927cdf0e10cSrcweir sal_Int16 nNatNum = NumFor[nIx].GetNatNum().GetNatNum(); 2928cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nAnz; i++) 2929cdf0e10cSrcweir { 2930cdf0e10cSrcweir switch (rInfo.nTypeArray[i]) 2931cdf0e10cSrcweir { 2932cdf0e10cSrcweir case NF_SYMBOLTYPE_CALENDAR : 2933cdf0e10cSrcweir if ( !aOrgCalendar.Len() ) 2934cdf0e10cSrcweir { 2935cdf0e10cSrcweir aOrgCalendar = rCal.getUniqueID(); 2936cdf0e10cSrcweir fOrgDateTime = rCal.getDateTime(); 2937cdf0e10cSrcweir } 2938cdf0e10cSrcweir rCal.loadCalendar( rInfo.sStrArray[i], rLoc().getLocale() ); 2939cdf0e10cSrcweir rCal.setDateTime( fOrgDateTime ); 2940cdf0e10cSrcweir ImpFallBackToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 2941cdf0e10cSrcweir break; 2942cdf0e10cSrcweir case NF_SYMBOLTYPE_STAR: 2943cdf0e10cSrcweir if( bStarFlag ) 2944cdf0e10cSrcweir { 2945cdf0e10cSrcweir OutString += (sal_Unicode) 0x1B; 2946cdf0e10cSrcweir OutString += rInfo.sStrArray[i].GetChar(1); 2947cdf0e10cSrcweir bRes = sal_True; 2948cdf0e10cSrcweir } 2949cdf0e10cSrcweir break; 2950cdf0e10cSrcweir case NF_SYMBOLTYPE_BLANK: 2951cdf0e10cSrcweir InsertBlanks( OutString, OutString.Len(), 2952cdf0e10cSrcweir rInfo.sStrArray[i].GetChar(1) ); 2953cdf0e10cSrcweir break; 2954cdf0e10cSrcweir case NF_SYMBOLTYPE_STRING: 2955cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRENCY: 2956cdf0e10cSrcweir case NF_SYMBOLTYPE_DATESEP: 2957cdf0e10cSrcweir case NF_SYMBOLTYPE_TIMESEP: 2958cdf0e10cSrcweir case NF_SYMBOLTYPE_TIME100SECSEP: 2959cdf0e10cSrcweir OutString += rInfo.sStrArray[i]; 2960cdf0e10cSrcweir break; 2961cdf0e10cSrcweir case NF_KEY_M: // M 2962cdf0e10cSrcweir OutString += rCal.getDisplayString( 2963cdf0e10cSrcweir CalendarDisplayCode::SHORT_MONTH, nNatNum ); 2964cdf0e10cSrcweir break; 2965cdf0e10cSrcweir case NF_KEY_MM: // MM 2966cdf0e10cSrcweir OutString += rCal.getDisplayString( 2967cdf0e10cSrcweir CalendarDisplayCode::LONG_MONTH, nNatNum ); 2968cdf0e10cSrcweir break; 2969cdf0e10cSrcweir case NF_KEY_MMM: // MMM 2970cdf0e10cSrcweir OutString += rCal.getDisplayString( 2971cdf0e10cSrcweir CalendarDisplayCode::SHORT_MONTH_NAME, nNatNum ); 2972cdf0e10cSrcweir break; 2973cdf0e10cSrcweir case NF_KEY_MMMM: // MMMM 2974cdf0e10cSrcweir OutString += rCal.getDisplayString( 2975cdf0e10cSrcweir CalendarDisplayCode::LONG_MONTH_NAME, nNatNum ); 2976cdf0e10cSrcweir break; 2977cdf0e10cSrcweir case NF_KEY_MMMMM: // MMMMM 2978cdf0e10cSrcweir OutString += rCal.getDisplayString( 2979cdf0e10cSrcweir CalendarDisplayCode::LONG_MONTH_NAME, nNatNum ).GetChar(0); 2980cdf0e10cSrcweir break; 2981cdf0e10cSrcweir case NF_KEY_Q: // Q 2982cdf0e10cSrcweir OutString += rCal.getDisplayString( 2983cdf0e10cSrcweir CalendarDisplayCode::SHORT_QUARTER, nNatNum ); 2984cdf0e10cSrcweir break; 2985cdf0e10cSrcweir case NF_KEY_QQ: // QQ 2986cdf0e10cSrcweir OutString += rCal.getDisplayString( 2987cdf0e10cSrcweir CalendarDisplayCode::LONG_QUARTER, nNatNum ); 2988cdf0e10cSrcweir break; 2989cdf0e10cSrcweir case NF_KEY_D: // D 2990cdf0e10cSrcweir OutString += rCal.getDisplayString( 2991cdf0e10cSrcweir CalendarDisplayCode::SHORT_DAY, nNatNum ); 2992cdf0e10cSrcweir break; 2993cdf0e10cSrcweir case NF_KEY_DD: // DD 2994cdf0e10cSrcweir OutString += rCal.getDisplayString( 2995cdf0e10cSrcweir CalendarDisplayCode::LONG_DAY, nNatNum ); 2996cdf0e10cSrcweir break; 2997cdf0e10cSrcweir case NF_KEY_DDD: // DDD 2998cdf0e10cSrcweir { 2999cdf0e10cSrcweir if ( bOtherCalendar ) 3000cdf0e10cSrcweir SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 3001cdf0e10cSrcweir OutString += rCal.getDisplayString( 3002cdf0e10cSrcweir CalendarDisplayCode::SHORT_DAY_NAME, nNatNum ); 3003cdf0e10cSrcweir if ( bOtherCalendar ) 3004cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 3005cdf0e10cSrcweir } 3006cdf0e10cSrcweir break; 3007cdf0e10cSrcweir case NF_KEY_DDDD: // DDDD 3008cdf0e10cSrcweir { 3009cdf0e10cSrcweir if ( bOtherCalendar ) 3010cdf0e10cSrcweir SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 3011cdf0e10cSrcweir OutString += rCal.getDisplayString( 3012cdf0e10cSrcweir CalendarDisplayCode::LONG_DAY_NAME, nNatNum ); 3013cdf0e10cSrcweir if ( bOtherCalendar ) 3014cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 3015cdf0e10cSrcweir } 3016cdf0e10cSrcweir break; 3017cdf0e10cSrcweir case NF_KEY_YY: // YY 3018cdf0e10cSrcweir { 3019cdf0e10cSrcweir if ( bOtherCalendar ) 3020cdf0e10cSrcweir SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 3021cdf0e10cSrcweir OutString += rCal.getDisplayString( 3022cdf0e10cSrcweir CalendarDisplayCode::SHORT_YEAR, nNatNum ); 3023cdf0e10cSrcweir if ( bOtherCalendar ) 3024cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 3025cdf0e10cSrcweir } 3026cdf0e10cSrcweir break; 3027cdf0e10cSrcweir case NF_KEY_YYYY: // YYYY 3028cdf0e10cSrcweir { 3029cdf0e10cSrcweir if ( bOtherCalendar ) 3030cdf0e10cSrcweir SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 3031cdf0e10cSrcweir OutString += rCal.getDisplayString( 3032cdf0e10cSrcweir CalendarDisplayCode::LONG_YEAR, nNatNum ); 3033cdf0e10cSrcweir if ( bOtherCalendar ) 3034cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 3035cdf0e10cSrcweir } 3036cdf0e10cSrcweir break; 3037cdf0e10cSrcweir case NF_KEY_EC: // E 3038cdf0e10cSrcweir OutString += rCal.getDisplayString( 3039cdf0e10cSrcweir CalendarDisplayCode::SHORT_YEAR, nNatNum ); 3040cdf0e10cSrcweir break; 3041cdf0e10cSrcweir case NF_KEY_EEC: // EE 3042cdf0e10cSrcweir case NF_KEY_R: // R 3043cdf0e10cSrcweir OutString += rCal.getDisplayString( 3044cdf0e10cSrcweir CalendarDisplayCode::LONG_YEAR, nNatNum ); 3045cdf0e10cSrcweir break; 3046cdf0e10cSrcweir case NF_KEY_NN: // NN 3047cdf0e10cSrcweir case NF_KEY_AAA: // AAA 3048cdf0e10cSrcweir OutString += rCal.getDisplayString( 3049cdf0e10cSrcweir CalendarDisplayCode::SHORT_DAY_NAME, nNatNum ); 3050cdf0e10cSrcweir break; 3051cdf0e10cSrcweir case NF_KEY_NNN: // NNN 3052cdf0e10cSrcweir case NF_KEY_AAAA: // AAAA 3053cdf0e10cSrcweir OutString += rCal.getDisplayString( 3054cdf0e10cSrcweir CalendarDisplayCode::LONG_DAY_NAME, nNatNum ); 3055cdf0e10cSrcweir break; 3056cdf0e10cSrcweir case NF_KEY_NNNN: // NNNN 3057cdf0e10cSrcweir { 3058cdf0e10cSrcweir OutString += rCal.getDisplayString( 3059cdf0e10cSrcweir CalendarDisplayCode::LONG_DAY_NAME, nNatNum ); 3060cdf0e10cSrcweir OutString += rLoc().getLongDateDayOfWeekSep(); 3061cdf0e10cSrcweir } 3062cdf0e10cSrcweir break; 3063cdf0e10cSrcweir case NF_KEY_WW : // WW 3064cdf0e10cSrcweir { 3065cdf0e10cSrcweir sal_Int16 nVal = rCal.getValue( CalendarFieldIndex::WEEK_OF_YEAR ); 3066cdf0e10cSrcweir OutString += ImpIntToString( nIx, nVal ); 3067cdf0e10cSrcweir } 3068cdf0e10cSrcweir break; 3069cdf0e10cSrcweir case NF_KEY_G: // G 3070cdf0e10cSrcweir ImpAppendEraG( OutString, rCal, nNatNum ); 3071cdf0e10cSrcweir break; 3072cdf0e10cSrcweir case NF_KEY_GG: // GG 3073cdf0e10cSrcweir OutString += rCal.getDisplayString( 3074cdf0e10cSrcweir CalendarDisplayCode::SHORT_ERA, nNatNum ); 3075cdf0e10cSrcweir break; 3076cdf0e10cSrcweir case NF_KEY_GGG: // GGG 3077cdf0e10cSrcweir OutString += rCal.getDisplayString( 3078cdf0e10cSrcweir CalendarDisplayCode::LONG_ERA, nNatNum ); 3079cdf0e10cSrcweir break; 3080cdf0e10cSrcweir case NF_KEY_RR: // RR => GGGEE 3081cdf0e10cSrcweir OutString += rCal.getDisplayString( 3082cdf0e10cSrcweir CalendarDisplayCode::LONG_YEAR_AND_ERA, nNatNum ); 3083cdf0e10cSrcweir break; 3084cdf0e10cSrcweir } 3085cdf0e10cSrcweir } 3086cdf0e10cSrcweir if ( aOrgCalendar.Len() ) 3087cdf0e10cSrcweir rCal.loadCalendar( aOrgCalendar, rLoc().getLocale() ); // restore calendar 3088cdf0e10cSrcweir return bRes; 3089cdf0e10cSrcweir } 3090cdf0e10cSrcweir 3091cdf0e10cSrcweir sal_Bool SvNumberformat::ImpGetDateTimeOutput(double fNumber, 3092cdf0e10cSrcweir sal_uInt16 nIx, 3093cdf0e10cSrcweir String& OutString) 3094cdf0e10cSrcweir { 3095cdf0e10cSrcweir using namespace ::com::sun::star::i18n; 3096cdf0e10cSrcweir sal_Bool bRes = sal_False; 3097cdf0e10cSrcweir 3098cdf0e10cSrcweir CalendarWrapper& rCal = GetCal(); 3099cdf0e10cSrcweir double fDiff = DateTime(*(rScan.GetNullDate())) - rCal.getEpochStart(); 3100cdf0e10cSrcweir fNumber += fDiff; 3101cdf0e10cSrcweir 3102cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); 3103cdf0e10cSrcweir sal_Bool bInputLine; 3104cdf0e10cSrcweir xub_StrLen nCntPost; 3105cdf0e10cSrcweir if ( rScan.GetStandardPrec() == 300 && 3106cdf0e10cSrcweir 0 < rInfo.nCntPost && rInfo.nCntPost < 7 ) 3107cdf0e10cSrcweir { // round at 7 decimals (+5 of 86400 == 12 significant digits) 3108cdf0e10cSrcweir bInputLine = sal_True; 3109cdf0e10cSrcweir nCntPost = 7; 3110cdf0e10cSrcweir } 3111cdf0e10cSrcweir else 3112cdf0e10cSrcweir { 3113cdf0e10cSrcweir bInputLine = sal_False; 3114cdf0e10cSrcweir nCntPost = xub_StrLen(rInfo.nCntPost); 3115cdf0e10cSrcweir } 3116cdf0e10cSrcweir double fTime = (fNumber - floor( fNumber )) * 86400.0; 3117cdf0e10cSrcweir fTime = ::rtl::math::round( fTime, int(nCntPost) ); 3118cdf0e10cSrcweir if (fTime >= 86400.0) 3119cdf0e10cSrcweir { 3120cdf0e10cSrcweir // result of fNumber==x.999999999... rounded up, use correct date/time 3121cdf0e10cSrcweir fTime -= 86400.0; 3122cdf0e10cSrcweir fNumber = floor( fNumber + 0.5) + fTime; 3123cdf0e10cSrcweir } 3124cdf0e10cSrcweir rCal.setLocalDateTime( fNumber ); 3125cdf0e10cSrcweir 3126cdf0e10cSrcweir String aOrgCalendar; // empty => not changed yet 3127cdf0e10cSrcweir double fOrgDateTime; 3128cdf0e10cSrcweir sal_Bool bOtherCalendar = ImpIsOtherCalendar( NumFor[nIx] ); 3129cdf0e10cSrcweir if ( bOtherCalendar ) 3130cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 3131cdf0e10cSrcweir if ( ImpFallBackToGregorianCalendar( aOrgCalendar, fOrgDateTime ) ) 3132cdf0e10cSrcweir bOtherCalendar = sal_False; 3133cdf0e10cSrcweir sal_Int16 nNatNum = NumFor[nIx].GetNatNum().GetNatNum(); 3134cdf0e10cSrcweir 3135cdf0e10cSrcweir sal_uLong nSeconds = (sal_uLong)floor( fTime ); 3136cdf0e10cSrcweir String sSecStr( ::rtl::math::doubleToUString( fTime-nSeconds, 3137cdf0e10cSrcweir rtl_math_StringFormat_F, int(nCntPost), '.')); 3138cdf0e10cSrcweir sSecStr.EraseLeadingChars('0'); 3139cdf0e10cSrcweir sSecStr.EraseLeadingChars('.'); 3140cdf0e10cSrcweir if ( bInputLine ) 3141cdf0e10cSrcweir { 3142cdf0e10cSrcweir sSecStr.EraseTrailingChars('0'); 3143cdf0e10cSrcweir if ( sSecStr.Len() < xub_StrLen(rInfo.nCntPost) ) 3144cdf0e10cSrcweir sSecStr.Expand( xub_StrLen(rInfo.nCntPost), '0' ); 3145cdf0e10cSrcweir ImpTransliterate( sSecStr, NumFor[nIx].GetNatNum() ); 3146cdf0e10cSrcweir nCntPost = sSecStr.Len(); 3147cdf0e10cSrcweir } 3148cdf0e10cSrcweir else 3149cdf0e10cSrcweir ImpTransliterate( sSecStr, NumFor[nIx].GetNatNum() ); 3150cdf0e10cSrcweir 3151cdf0e10cSrcweir xub_StrLen nSecPos = 0; // Zum Ziffernweisen 3152cdf0e10cSrcweir // abarbeiten 3153cdf0e10cSrcweir sal_uLong nHour, nMin, nSec; 3154cdf0e10cSrcweir if (!rInfo.bThousand) // [] Format 3155cdf0e10cSrcweir { 3156cdf0e10cSrcweir nHour = (nSeconds/3600) % 24; 3157cdf0e10cSrcweir nMin = (nSeconds%3600) / 60; 3158cdf0e10cSrcweir nSec = nSeconds%60; 3159cdf0e10cSrcweir } 3160cdf0e10cSrcweir else if (rInfo.nThousand == 3) // [ss] 3161cdf0e10cSrcweir { 3162cdf0e10cSrcweir nHour = 0; 3163cdf0e10cSrcweir nMin = 0; 3164cdf0e10cSrcweir nSec = nSeconds; 3165cdf0e10cSrcweir } 3166cdf0e10cSrcweir else if (rInfo.nThousand == 2) // [mm]:ss 3167cdf0e10cSrcweir { 3168cdf0e10cSrcweir nHour = 0; 3169cdf0e10cSrcweir nMin = nSeconds / 60; 3170cdf0e10cSrcweir nSec = nSeconds % 60; 3171cdf0e10cSrcweir } 3172cdf0e10cSrcweir else if (rInfo.nThousand == 1) // [hh]:mm:ss 3173cdf0e10cSrcweir { 3174cdf0e10cSrcweir nHour = nSeconds / 3600; 3175cdf0e10cSrcweir nMin = (nSeconds%3600) / 60; 3176cdf0e10cSrcweir nSec = nSeconds%60; 3177cdf0e10cSrcweir } 3178cdf0e10cSrcweir else { 3179cdf0e10cSrcweir nHour = 0; // TODO What should these values be? 3180cdf0e10cSrcweir nMin = 0; 3181cdf0e10cSrcweir nSec = 0; 3182cdf0e10cSrcweir } 3183cdf0e10cSrcweir sal_Unicode cAmPm = ' '; // a oder p 3184cdf0e10cSrcweir if (rInfo.nCntExp) // AM/PM 3185cdf0e10cSrcweir { 3186cdf0e10cSrcweir if (nHour == 0) 3187cdf0e10cSrcweir { 3188cdf0e10cSrcweir nHour = 12; 3189cdf0e10cSrcweir cAmPm = 'a'; 3190cdf0e10cSrcweir } 3191cdf0e10cSrcweir else if (nHour < 12) 3192cdf0e10cSrcweir cAmPm = 'a'; 3193cdf0e10cSrcweir else 3194cdf0e10cSrcweir { 3195cdf0e10cSrcweir cAmPm = 'p'; 3196cdf0e10cSrcweir if (nHour > 12) 3197cdf0e10cSrcweir nHour -= 12; 3198cdf0e10cSrcweir } 3199cdf0e10cSrcweir } 3200cdf0e10cSrcweir const sal_uInt16 nAnz = NumFor[nIx].GetnAnz(); 3201cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nAnz; i++) 3202cdf0e10cSrcweir { 3203cdf0e10cSrcweir switch (rInfo.nTypeArray[i]) 3204cdf0e10cSrcweir { 3205cdf0e10cSrcweir case NF_SYMBOLTYPE_CALENDAR : 3206cdf0e10cSrcweir if ( !aOrgCalendar.Len() ) 3207cdf0e10cSrcweir { 3208cdf0e10cSrcweir aOrgCalendar = rCal.getUniqueID(); 3209cdf0e10cSrcweir fOrgDateTime = rCal.getDateTime(); 3210cdf0e10cSrcweir } 3211cdf0e10cSrcweir rCal.loadCalendar( rInfo.sStrArray[i], rLoc().getLocale() ); 3212cdf0e10cSrcweir rCal.setDateTime( fOrgDateTime ); 3213cdf0e10cSrcweir ImpFallBackToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 3214cdf0e10cSrcweir break; 3215cdf0e10cSrcweir case NF_SYMBOLTYPE_STAR: 3216cdf0e10cSrcweir if( bStarFlag ) 3217cdf0e10cSrcweir { 3218cdf0e10cSrcweir OutString += (sal_Unicode) 0x1B; 3219cdf0e10cSrcweir OutString += rInfo.sStrArray[i].GetChar(1); 3220cdf0e10cSrcweir bRes = sal_True; 3221cdf0e10cSrcweir } 3222cdf0e10cSrcweir break; 3223cdf0e10cSrcweir case NF_SYMBOLTYPE_BLANK: 3224cdf0e10cSrcweir InsertBlanks( OutString, OutString.Len(), 3225cdf0e10cSrcweir rInfo.sStrArray[i].GetChar(1) ); 3226cdf0e10cSrcweir break; 3227cdf0e10cSrcweir case NF_SYMBOLTYPE_STRING: 3228cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRENCY: 3229cdf0e10cSrcweir case NF_SYMBOLTYPE_DATESEP: 3230cdf0e10cSrcweir case NF_SYMBOLTYPE_TIMESEP: 3231cdf0e10cSrcweir case NF_SYMBOLTYPE_TIME100SECSEP: 3232cdf0e10cSrcweir OutString += rInfo.sStrArray[i]; 3233cdf0e10cSrcweir break; 3234cdf0e10cSrcweir case NF_SYMBOLTYPE_DIGIT: 3235cdf0e10cSrcweir { 3236cdf0e10cSrcweir xub_StrLen nLen = ( bInputLine && i > 0 && 3237cdf0e10cSrcweir (rInfo.nTypeArray[i-1] == NF_SYMBOLTYPE_STRING || 3238cdf0e10cSrcweir rInfo.nTypeArray[i-1] == NF_SYMBOLTYPE_TIME100SECSEP) ? 3239cdf0e10cSrcweir nCntPost : rInfo.sStrArray[i].Len() ); 3240cdf0e10cSrcweir for (xub_StrLen j = 0; j < nLen && nSecPos < nCntPost; j++) 3241cdf0e10cSrcweir { 3242cdf0e10cSrcweir OutString += sSecStr.GetChar(nSecPos); 3243cdf0e10cSrcweir nSecPos++; 3244cdf0e10cSrcweir } 3245cdf0e10cSrcweir } 3246cdf0e10cSrcweir break; 3247cdf0e10cSrcweir case NF_KEY_AMPM: // AM/PM 3248cdf0e10cSrcweir { 3249cdf0e10cSrcweir if (cAmPm == 'a') 3250cdf0e10cSrcweir OutString += rCal.getDisplayName( CalendarDisplayIndex::AM_PM, 3251cdf0e10cSrcweir AmPmValue::AM, 0 ); 3252cdf0e10cSrcweir else 3253cdf0e10cSrcweir OutString += rCal.getDisplayName( CalendarDisplayIndex::AM_PM, 3254cdf0e10cSrcweir AmPmValue::PM, 0 ); 3255cdf0e10cSrcweir } 3256cdf0e10cSrcweir break; 3257cdf0e10cSrcweir case NF_KEY_AP: // A/P 3258cdf0e10cSrcweir { 3259cdf0e10cSrcweir if (cAmPm == 'a') 3260cdf0e10cSrcweir OutString += 'a'; 3261cdf0e10cSrcweir else 3262cdf0e10cSrcweir OutString += 'p'; 3263cdf0e10cSrcweir } 3264cdf0e10cSrcweir break; 3265cdf0e10cSrcweir case NF_KEY_MI: // M 3266cdf0e10cSrcweir OutString += ImpIntToString( nIx, nMin ); 3267cdf0e10cSrcweir break; 3268cdf0e10cSrcweir case NF_KEY_MMI: // MM 3269cdf0e10cSrcweir OutString += ImpIntToString( nIx, nMin, 2 ); 3270cdf0e10cSrcweir break; 3271cdf0e10cSrcweir case NF_KEY_H: // H 3272cdf0e10cSrcweir OutString += ImpIntToString( nIx, nHour ); 3273cdf0e10cSrcweir break; 3274cdf0e10cSrcweir case NF_KEY_HH: // HH 3275cdf0e10cSrcweir OutString += ImpIntToString( nIx, nHour, 2 ); 3276cdf0e10cSrcweir break; 3277cdf0e10cSrcweir case NF_KEY_S: // S 3278cdf0e10cSrcweir OutString += ImpIntToString( nIx, nSec ); 3279cdf0e10cSrcweir break; 3280cdf0e10cSrcweir case NF_KEY_SS: // SS 3281cdf0e10cSrcweir OutString += ImpIntToString( nIx, nSec, 2 ); 3282cdf0e10cSrcweir break; 3283cdf0e10cSrcweir case NF_KEY_M: // M 3284cdf0e10cSrcweir OutString += rCal.getDisplayString( 3285cdf0e10cSrcweir CalendarDisplayCode::SHORT_MONTH, nNatNum ); 3286cdf0e10cSrcweir break; 3287cdf0e10cSrcweir case NF_KEY_MM: // MM 3288cdf0e10cSrcweir OutString += rCal.getDisplayString( 3289cdf0e10cSrcweir CalendarDisplayCode::LONG_MONTH, nNatNum ); 3290cdf0e10cSrcweir break; 3291cdf0e10cSrcweir case NF_KEY_MMM: // MMM 3292cdf0e10cSrcweir OutString += rCal.getDisplayString( 3293cdf0e10cSrcweir CalendarDisplayCode::SHORT_MONTH_NAME, nNatNum ); 3294cdf0e10cSrcweir break; 3295cdf0e10cSrcweir case NF_KEY_MMMM: // MMMM 3296cdf0e10cSrcweir OutString += rCal.getDisplayString( 3297cdf0e10cSrcweir CalendarDisplayCode::LONG_MONTH_NAME, nNatNum ); 3298cdf0e10cSrcweir break; 3299cdf0e10cSrcweir case NF_KEY_MMMMM: // MMMMM 3300cdf0e10cSrcweir OutString += rCal.getDisplayString( 3301cdf0e10cSrcweir CalendarDisplayCode::LONG_MONTH_NAME, nNatNum ).GetChar(0); 3302cdf0e10cSrcweir break; 3303cdf0e10cSrcweir case NF_KEY_Q: // Q 3304cdf0e10cSrcweir OutString += rCal.getDisplayString( 3305cdf0e10cSrcweir CalendarDisplayCode::SHORT_QUARTER, nNatNum ); 3306cdf0e10cSrcweir break; 3307cdf0e10cSrcweir case NF_KEY_QQ: // QQ 3308cdf0e10cSrcweir OutString += rCal.getDisplayString( 3309cdf0e10cSrcweir CalendarDisplayCode::LONG_QUARTER, nNatNum ); 3310cdf0e10cSrcweir break; 3311cdf0e10cSrcweir case NF_KEY_D: // D 3312cdf0e10cSrcweir OutString += rCal.getDisplayString( 3313cdf0e10cSrcweir CalendarDisplayCode::SHORT_DAY, nNatNum ); 3314cdf0e10cSrcweir break; 3315cdf0e10cSrcweir case NF_KEY_DD: // DD 3316cdf0e10cSrcweir OutString += rCal.getDisplayString( 3317cdf0e10cSrcweir CalendarDisplayCode::LONG_DAY, nNatNum ); 3318cdf0e10cSrcweir break; 3319cdf0e10cSrcweir case NF_KEY_DDD: // DDD 3320cdf0e10cSrcweir { 3321cdf0e10cSrcweir if ( bOtherCalendar ) 3322cdf0e10cSrcweir SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 3323cdf0e10cSrcweir OutString += rCal.getDisplayString( 3324cdf0e10cSrcweir CalendarDisplayCode::SHORT_DAY_NAME, nNatNum ); 3325cdf0e10cSrcweir if ( bOtherCalendar ) 3326cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 3327cdf0e10cSrcweir } 3328cdf0e10cSrcweir break; 3329cdf0e10cSrcweir case NF_KEY_DDDD: // DDDD 3330cdf0e10cSrcweir { 3331cdf0e10cSrcweir if ( bOtherCalendar ) 3332cdf0e10cSrcweir SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 3333cdf0e10cSrcweir OutString += rCal.getDisplayString( 3334cdf0e10cSrcweir CalendarDisplayCode::LONG_DAY_NAME, nNatNum ); 3335cdf0e10cSrcweir if ( bOtherCalendar ) 3336cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 3337cdf0e10cSrcweir } 3338cdf0e10cSrcweir break; 3339cdf0e10cSrcweir case NF_KEY_YY: // YY 3340cdf0e10cSrcweir { 3341cdf0e10cSrcweir if ( bOtherCalendar ) 3342cdf0e10cSrcweir SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 3343cdf0e10cSrcweir OutString += rCal.getDisplayString( 3344cdf0e10cSrcweir CalendarDisplayCode::SHORT_YEAR, nNatNum ); 3345cdf0e10cSrcweir if ( bOtherCalendar ) 3346cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 3347cdf0e10cSrcweir } 3348cdf0e10cSrcweir break; 3349cdf0e10cSrcweir case NF_KEY_YYYY: // YYYY 3350cdf0e10cSrcweir { 3351cdf0e10cSrcweir if ( bOtherCalendar ) 3352cdf0e10cSrcweir SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 3353cdf0e10cSrcweir OutString += rCal.getDisplayString( 3354cdf0e10cSrcweir CalendarDisplayCode::LONG_YEAR, nNatNum ); 3355cdf0e10cSrcweir if ( bOtherCalendar ) 3356cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 3357cdf0e10cSrcweir } 3358cdf0e10cSrcweir break; 3359cdf0e10cSrcweir case NF_KEY_EC: // E 3360cdf0e10cSrcweir OutString += rCal.getDisplayString( 3361cdf0e10cSrcweir CalendarDisplayCode::SHORT_YEAR, nNatNum ); 3362cdf0e10cSrcweir break; 3363cdf0e10cSrcweir case NF_KEY_EEC: // EE 3364cdf0e10cSrcweir case NF_KEY_R: // R 3365cdf0e10cSrcweir OutString += rCal.getDisplayString( 3366cdf0e10cSrcweir CalendarDisplayCode::LONG_YEAR, nNatNum ); 3367cdf0e10cSrcweir break; 3368cdf0e10cSrcweir case NF_KEY_NN: // NN 3369cdf0e10cSrcweir case NF_KEY_AAA: // AAA 3370cdf0e10cSrcweir OutString += rCal.getDisplayString( 3371cdf0e10cSrcweir CalendarDisplayCode::SHORT_DAY_NAME, nNatNum ); 3372cdf0e10cSrcweir break; 3373cdf0e10cSrcweir case NF_KEY_NNN: // NNN 3374cdf0e10cSrcweir case NF_KEY_AAAA: // AAAA 3375cdf0e10cSrcweir OutString += rCal.getDisplayString( 3376cdf0e10cSrcweir CalendarDisplayCode::LONG_DAY_NAME, nNatNum ); 3377cdf0e10cSrcweir break; 3378cdf0e10cSrcweir case NF_KEY_NNNN: // NNNN 3379cdf0e10cSrcweir { 3380cdf0e10cSrcweir OutString += rCal.getDisplayString( 3381cdf0e10cSrcweir CalendarDisplayCode::LONG_DAY_NAME, nNatNum ); 3382cdf0e10cSrcweir OutString += rLoc().getLongDateDayOfWeekSep(); 3383cdf0e10cSrcweir } 3384cdf0e10cSrcweir break; 3385cdf0e10cSrcweir case NF_KEY_WW : // WW 3386cdf0e10cSrcweir { 3387cdf0e10cSrcweir sal_Int16 nVal = rCal.getValue( CalendarFieldIndex::WEEK_OF_YEAR ); 3388cdf0e10cSrcweir OutString += ImpIntToString( nIx, nVal ); 3389cdf0e10cSrcweir } 3390cdf0e10cSrcweir break; 3391cdf0e10cSrcweir case NF_KEY_G: // G 3392cdf0e10cSrcweir ImpAppendEraG( OutString, rCal, nNatNum ); 3393cdf0e10cSrcweir break; 3394cdf0e10cSrcweir case NF_KEY_GG: // GG 3395cdf0e10cSrcweir OutString += rCal.getDisplayString( 3396cdf0e10cSrcweir CalendarDisplayCode::SHORT_ERA, nNatNum ); 3397cdf0e10cSrcweir break; 3398cdf0e10cSrcweir case NF_KEY_GGG: // GGG 3399cdf0e10cSrcweir OutString += rCal.getDisplayString( 3400cdf0e10cSrcweir CalendarDisplayCode::LONG_ERA, nNatNum ); 3401cdf0e10cSrcweir break; 3402cdf0e10cSrcweir case NF_KEY_RR: // RR => GGGEE 3403cdf0e10cSrcweir OutString += rCal.getDisplayString( 3404cdf0e10cSrcweir CalendarDisplayCode::LONG_YEAR_AND_ERA, nNatNum ); 3405cdf0e10cSrcweir break; 3406cdf0e10cSrcweir } 3407cdf0e10cSrcweir } 3408cdf0e10cSrcweir if ( aOrgCalendar.Len() ) 3409cdf0e10cSrcweir rCal.loadCalendar( aOrgCalendar, rLoc().getLocale() ); // restore calendar 3410cdf0e10cSrcweir return bRes; 3411cdf0e10cSrcweir } 3412cdf0e10cSrcweir 3413cdf0e10cSrcweir sal_Bool SvNumberformat::ImpGetNumberOutput(double fNumber, 3414cdf0e10cSrcweir sal_uInt16 nIx, 3415cdf0e10cSrcweir String& OutString) 3416cdf0e10cSrcweir { 3417cdf0e10cSrcweir sal_Bool bRes = sal_False; 3418cdf0e10cSrcweir sal_Bool bSign; 3419cdf0e10cSrcweir if (fNumber < 0.0) 3420cdf0e10cSrcweir { 3421cdf0e10cSrcweir if (nIx == 0) // nicht in hinteren 3422cdf0e10cSrcweir bSign = sal_True; // Formaten 3423cdf0e10cSrcweir else 3424cdf0e10cSrcweir bSign = sal_False; 3425cdf0e10cSrcweir fNumber = -fNumber; 3426cdf0e10cSrcweir } 3427cdf0e10cSrcweir else 3428cdf0e10cSrcweir { 3429cdf0e10cSrcweir bSign = sal_False; 3430cdf0e10cSrcweir if ( ::rtl::math::isSignBitSet( fNumber ) ) 3431cdf0e10cSrcweir fNumber = -fNumber; // yes, -0.0 is possible, eliminate '-' 3432cdf0e10cSrcweir } 3433cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); 3434cdf0e10cSrcweir if (rInfo.eScannedType == NUMBERFORMAT_PERCENT) 3435cdf0e10cSrcweir { 3436cdf0e10cSrcweir if (fNumber < _D_MAX_D_BY_100) 3437cdf0e10cSrcweir fNumber *= 100.0; 3438cdf0e10cSrcweir else 3439cdf0e10cSrcweir { 3440cdf0e10cSrcweir OutString = rScan.GetErrorString(); 3441cdf0e10cSrcweir return sal_False; 3442cdf0e10cSrcweir } 3443cdf0e10cSrcweir } 3444cdf0e10cSrcweir sal_uInt16 i, j; 3445cdf0e10cSrcweir xub_StrLen k; 3446cdf0e10cSrcweir String sStr; 3447cdf0e10cSrcweir long nPrecExp; 3448cdf0e10cSrcweir sal_Bool bInteger = sal_False; 3449cdf0e10cSrcweir if ( rInfo.nThousand != FLAG_STANDARD_IN_FORMAT ) 3450cdf0e10cSrcweir { // special formatting only if no GENERAL keyword in format code 3451cdf0e10cSrcweir const sal_uInt16 nThousand = rInfo.nThousand; 3452cdf0e10cSrcweir for (i = 0; i < nThousand; i++) 3453cdf0e10cSrcweir { 3454cdf0e10cSrcweir if (fNumber > _D_MIN_M_BY_1000) 3455cdf0e10cSrcweir fNumber /= 1000.0; 3456cdf0e10cSrcweir else 3457cdf0e10cSrcweir fNumber = 0.0; 3458cdf0e10cSrcweir } 3459cdf0e10cSrcweir if (fNumber > 0.0) 3460cdf0e10cSrcweir nPrecExp = GetPrecExp( fNumber ); 3461cdf0e10cSrcweir else 3462cdf0e10cSrcweir nPrecExp = 0; 3463cdf0e10cSrcweir if (rInfo.nCntPost) // NachkommaStellen 3464cdf0e10cSrcweir { 3465cdf0e10cSrcweir if (rInfo.nCntPost + nPrecExp > 15 && nPrecExp < 15) 3466cdf0e10cSrcweir { 3467cdf0e10cSrcweir sStr = ::rtl::math::doubleToUString( fNumber, 3468cdf0e10cSrcweir rtl_math_StringFormat_F, 15-nPrecExp, '.'); 3469cdf0e10cSrcweir for (long l = 15-nPrecExp; l < (long) rInfo.nCntPost; l++) 3470cdf0e10cSrcweir sStr += '0'; 3471cdf0e10cSrcweir } 3472cdf0e10cSrcweir else 3473cdf0e10cSrcweir sStr = ::rtl::math::doubleToUString( fNumber, 3474cdf0e10cSrcweir rtl_math_StringFormat_F, rInfo.nCntPost, '.' ); 3475cdf0e10cSrcweir sStr.EraseLeadingChars('0'); // fuehrende Nullen weg 3476cdf0e10cSrcweir } 3477cdf0e10cSrcweir else if (fNumber == 0.0) // Null 3478cdf0e10cSrcweir { 3479cdf0e10cSrcweir // nothing to be done here, keep empty string sStr, 3480cdf0e10cSrcweir // ImpNumberFillWithThousands does the rest 3481cdf0e10cSrcweir } 3482cdf0e10cSrcweir else // Integer 3483cdf0e10cSrcweir { 3484cdf0e10cSrcweir sStr = ::rtl::math::doubleToUString( fNumber, 3485cdf0e10cSrcweir rtl_math_StringFormat_F, 0, '.'); 3486cdf0e10cSrcweir sStr.EraseLeadingChars('0'); // fuehrende Nullen weg 3487cdf0e10cSrcweir } 3488cdf0e10cSrcweir xub_StrLen nPoint = sStr.Search( '.' ); 3489cdf0e10cSrcweir if ( nPoint != STRING_NOTFOUND ) 3490cdf0e10cSrcweir { 3491cdf0e10cSrcweir register const sal_Unicode* p = sStr.GetBuffer() + nPoint; 3492cdf0e10cSrcweir while ( *++p == '0' ) 3493cdf0e10cSrcweir ; 3494cdf0e10cSrcweir if ( !*p ) 3495cdf0e10cSrcweir bInteger = sal_True; 3496cdf0e10cSrcweir sStr.Erase( nPoint, 1 ); // . herausnehmen 3497cdf0e10cSrcweir } 3498cdf0e10cSrcweir if (bSign && 3499cdf0e10cSrcweir (sStr.Len() == 0 || sStr.GetTokenCount('0') == sStr.Len()+1)) // nur 00000 3500cdf0e10cSrcweir bSign = sal_False; // nicht -0.00 3501cdf0e10cSrcweir } // End of != FLAG_STANDARD_IN_FORMAT 3502cdf0e10cSrcweir 3503cdf0e10cSrcweir // von hinten nach vorn 3504cdf0e10cSrcweir // editieren: 3505cdf0e10cSrcweir k = sStr.Len(); // hinter letzter Ziffer 3506cdf0e10cSrcweir j = NumFor[nIx].GetnAnz()-1; // letztes Symbol 3507cdf0e10cSrcweir // Nachkommastellen: 3508cdf0e10cSrcweir if (rInfo.nCntPost > 0) 3509cdf0e10cSrcweir { 3510cdf0e10cSrcweir sal_Bool bTrailing = sal_True; // ob Endnullen? 3511cdf0e10cSrcweir sal_Bool bFilled = sal_False; // ob aufgefuellt wurde ? 3512cdf0e10cSrcweir short nType; 3513cdf0e10cSrcweir while (j > 0 && // rueckwaerts 3514cdf0e10cSrcweir (nType = rInfo.nTypeArray[j]) != NF_SYMBOLTYPE_DECSEP) 3515cdf0e10cSrcweir { 3516cdf0e10cSrcweir switch ( nType ) 3517cdf0e10cSrcweir { 3518cdf0e10cSrcweir case NF_SYMBOLTYPE_STAR: 3519cdf0e10cSrcweir if( bStarFlag ) 3520cdf0e10cSrcweir { 3521cdf0e10cSrcweir sStr.Insert( (sal_Unicode) 0x1B, k /*++*/ ); 3522cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j].GetChar(1),k); 3523cdf0e10cSrcweir bRes = sal_True; 3524cdf0e10cSrcweir } 3525cdf0e10cSrcweir break; 3526cdf0e10cSrcweir case NF_SYMBOLTYPE_BLANK: 3527cdf0e10cSrcweir /*k = */ InsertBlanks( sStr,k,rInfo.sStrArray[j].GetChar(1) ); 3528cdf0e10cSrcweir break; 3529cdf0e10cSrcweir case NF_SYMBOLTYPE_STRING: 3530cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRENCY: 3531cdf0e10cSrcweir case NF_SYMBOLTYPE_PERCENT: 3532cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j],k); 3533cdf0e10cSrcweir break; 3534cdf0e10cSrcweir case NF_SYMBOLTYPE_THSEP: 3535cdf0e10cSrcweir if (rInfo.nThousand == 0) 3536cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j],k); 3537cdf0e10cSrcweir break; 3538cdf0e10cSrcweir case NF_SYMBOLTYPE_DIGIT: 3539cdf0e10cSrcweir { 3540cdf0e10cSrcweir const String& rStr = rInfo.sStrArray[j]; 3541cdf0e10cSrcweir const sal_Unicode* p1 = rStr.GetBuffer(); 3542cdf0e10cSrcweir register const sal_Unicode* p = p1 + rStr.Len(); 3543cdf0e10cSrcweir while ( p1 < p-- ) 3544cdf0e10cSrcweir { 3545cdf0e10cSrcweir const sal_Unicode c = *p; 3546cdf0e10cSrcweir k--; 3547cdf0e10cSrcweir if ( sStr.GetChar(k) != '0' ) 3548cdf0e10cSrcweir bTrailing = sal_False; 3549cdf0e10cSrcweir if (bTrailing) 3550cdf0e10cSrcweir { 3551cdf0e10cSrcweir if ( c == '0' ) 3552cdf0e10cSrcweir bFilled = sal_True; 3553cdf0e10cSrcweir else if ( c == '-' ) 3554cdf0e10cSrcweir { 3555cdf0e10cSrcweir if ( bInteger ) 3556cdf0e10cSrcweir sStr.SetChar( k, '-' ); 3557cdf0e10cSrcweir bFilled = sal_True; 3558cdf0e10cSrcweir } 3559cdf0e10cSrcweir else if ( c == '?' ) 3560cdf0e10cSrcweir { 3561cdf0e10cSrcweir sStr.SetChar( k, ' ' ); 3562cdf0e10cSrcweir bFilled = sal_True; 3563cdf0e10cSrcweir } 3564cdf0e10cSrcweir else if ( !bFilled ) // # 3565cdf0e10cSrcweir sStr.Erase(k,1); 3566cdf0e10cSrcweir } 3567cdf0e10cSrcweir } // of for 3568cdf0e10cSrcweir } // of case digi 3569cdf0e10cSrcweir break; 3570cdf0e10cSrcweir case NF_KEY_CCC: // CCC-Waehrung 3571cdf0e10cSrcweir sStr.Insert(rScan.GetCurAbbrev(), k); 3572cdf0e10cSrcweir break; 3573cdf0e10cSrcweir case NF_KEY_GENERAL: // Standard im String 3574cdf0e10cSrcweir { 3575cdf0e10cSrcweir String sNum; 3576cdf0e10cSrcweir ImpGetOutputStandard(fNumber, sNum); 3577cdf0e10cSrcweir sNum.EraseLeadingChars('-'); 3578cdf0e10cSrcweir sStr.Insert(sNum, k); 3579cdf0e10cSrcweir } 3580cdf0e10cSrcweir break; 3581cdf0e10cSrcweir default: 3582cdf0e10cSrcweir break; 3583cdf0e10cSrcweir } // of switch 3584cdf0e10cSrcweir j--; 3585cdf0e10cSrcweir } // of while 3586cdf0e10cSrcweir } // of Nachkomma 3587cdf0e10cSrcweir 3588cdf0e10cSrcweir bRes |= ImpNumberFillWithThousands(sStr, fNumber, k, j, nIx, // ggfs Auffuellen mit . 3589cdf0e10cSrcweir rInfo.nCntPre); 3590cdf0e10cSrcweir if ( rInfo.nCntPost > 0 ) 3591cdf0e10cSrcweir { 3592cdf0e10cSrcweir const String& rDecSep = GetFormatter().GetNumDecimalSep(); 3593cdf0e10cSrcweir xub_StrLen nLen = rDecSep.Len(); 3594cdf0e10cSrcweir if ( sStr.Len() > nLen && sStr.Equals( rDecSep, sStr.Len() - nLen, nLen ) ) 3595cdf0e10cSrcweir sStr.Erase( sStr.Len() - nLen ); // no decimals => strip DecSep 3596cdf0e10cSrcweir } 3597cdf0e10cSrcweir if (bSign) 3598cdf0e10cSrcweir sStr.Insert('-',0); 3599cdf0e10cSrcweir ImpTransliterate( sStr, NumFor[nIx].GetNatNum() ); 3600cdf0e10cSrcweir OutString = sStr; 3601cdf0e10cSrcweir return bRes; 3602cdf0e10cSrcweir } 3603cdf0e10cSrcweir 3604cdf0e10cSrcweir sal_Bool SvNumberformat::ImpNumberFillWithThousands( 3605cdf0e10cSrcweir String& sStr, // number string 3606cdf0e10cSrcweir double& rNumber, // number 3607cdf0e10cSrcweir xub_StrLen k, // position within string 3608cdf0e10cSrcweir sal_uInt16 j, // symbol index within format code 3609cdf0e10cSrcweir sal_uInt16 nIx, // subformat index 3610cdf0e10cSrcweir sal_uInt16 nDigCnt) // count of integer digits in format 3611cdf0e10cSrcweir { 3612cdf0e10cSrcweir sal_Bool bRes = sal_False; 3613cdf0e10cSrcweir xub_StrLen nLeadingStringChars = 0; // inserted StringChars before number 3614cdf0e10cSrcweir xub_StrLen nDigitCount = 0; // count of integer digits from the right 3615cdf0e10cSrcweir sal_Bool bStop = sal_False; 3616cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); 3617cdf0e10cSrcweir // no normal thousands separators if number divided by thousands 3618cdf0e10cSrcweir sal_Bool bDoThousands = (rInfo.nThousand == 0); 3619cdf0e10cSrcweir utl::DigitGroupingIterator aGrouping( 3620cdf0e10cSrcweir GetFormatter().GetLocaleData()->getDigitGrouping()); 3621cdf0e10cSrcweir while (!bStop) // backwards 3622cdf0e10cSrcweir { 3623cdf0e10cSrcweir if (j == 0) 3624cdf0e10cSrcweir bStop = sal_True; 3625cdf0e10cSrcweir switch (rInfo.nTypeArray[j]) 3626cdf0e10cSrcweir { 3627cdf0e10cSrcweir case NF_SYMBOLTYPE_DECSEP: 3628cdf0e10cSrcweir aGrouping.reset(); 3629cdf0e10cSrcweir // fall thru 3630cdf0e10cSrcweir case NF_SYMBOLTYPE_STRING: 3631cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRENCY: 3632cdf0e10cSrcweir case NF_SYMBOLTYPE_PERCENT: 3633cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j],k); 3634cdf0e10cSrcweir if ( k == 0 ) 3635cdf0e10cSrcweir nLeadingStringChars = 3636cdf0e10cSrcweir nLeadingStringChars + rInfo.sStrArray[j].Len(); 3637cdf0e10cSrcweir break; 3638cdf0e10cSrcweir case NF_SYMBOLTYPE_STAR: 3639cdf0e10cSrcweir if( bStarFlag ) 3640cdf0e10cSrcweir { 3641cdf0e10cSrcweir sStr.Insert( (sal_Unicode) 0x1B, k/*++*/ ); 3642cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j].GetChar(1),k); 3643cdf0e10cSrcweir bRes = sal_True; 3644cdf0e10cSrcweir } 3645cdf0e10cSrcweir break; 3646cdf0e10cSrcweir case NF_SYMBOLTYPE_BLANK: 3647cdf0e10cSrcweir /*k = */ InsertBlanks( sStr,k,rInfo.sStrArray[j].GetChar(1) ); 3648cdf0e10cSrcweir break; 3649cdf0e10cSrcweir case NF_SYMBOLTYPE_THSEP: 3650cdf0e10cSrcweir { 3651cdf0e10cSrcweir // #i7284# #102685# Insert separator also if number is divided 3652cdf0e10cSrcweir // by thousands and the separator is specified somewhere in 3653cdf0e10cSrcweir // between and not only at the end. 3654cdf0e10cSrcweir // #i12596# But do not insert if it's a parenthesized negative 3655cdf0e10cSrcweir // format like (#,) 3656cdf0e10cSrcweir // In fact, do not insert if divided and regex [0#,],[^0#] and 3657cdf0e10cSrcweir // no other digit symbol follows (which was already detected 3658cdf0e10cSrcweir // during scan of format code, otherwise there would be no 3659cdf0e10cSrcweir // division), else do insert. Same in ImpNumberFill() below. 3660cdf0e10cSrcweir if ( !bDoThousands && j < NumFor[nIx].GetnAnz()-1 ) 3661cdf0e10cSrcweir bDoThousands = ((j == 0) || 3662cdf0e10cSrcweir (rInfo.nTypeArray[j-1] != NF_SYMBOLTYPE_DIGIT && 3663cdf0e10cSrcweir rInfo.nTypeArray[j-1] != NF_SYMBOLTYPE_THSEP) || 3664cdf0e10cSrcweir (rInfo.nTypeArray[j+1] == NF_SYMBOLTYPE_DIGIT)); 3665cdf0e10cSrcweir if ( bDoThousands ) 3666cdf0e10cSrcweir { 3667cdf0e10cSrcweir if (k > 0) 3668cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j],k); 3669cdf0e10cSrcweir else if (nDigitCount < nDigCnt) 3670cdf0e10cSrcweir { 3671cdf0e10cSrcweir // Leading '#' displays nothing (e.g. no leading 3672cdf0e10cSrcweir // separator for numbers <1000 with #,##0 format). 3673cdf0e10cSrcweir // Leading '?' displays blank. 3674cdf0e10cSrcweir // Everything else, including nothing, displays the 3675cdf0e10cSrcweir // separator. 3676cdf0e10cSrcweir sal_Unicode cLeader = 0; 3677cdf0e10cSrcweir if (j > 0 && rInfo.nTypeArray[j-1] == NF_SYMBOLTYPE_DIGIT) 3678cdf0e10cSrcweir { 3679cdf0e10cSrcweir const String& rStr = rInfo.sStrArray[j-1]; 3680cdf0e10cSrcweir xub_StrLen nLen = rStr.Len(); 3681cdf0e10cSrcweir if (nLen) 3682cdf0e10cSrcweir cLeader = rStr.GetChar(nLen-1); 3683cdf0e10cSrcweir } 3684cdf0e10cSrcweir switch (cLeader) 3685cdf0e10cSrcweir { 3686cdf0e10cSrcweir case '#': 3687cdf0e10cSrcweir ; // nothing 3688cdf0e10cSrcweir break; 3689cdf0e10cSrcweir case '?': 3690cdf0e10cSrcweir // erAck: 2008-04-03T16:24+0200 3691cdf0e10cSrcweir // Actually this currently isn't executed 3692cdf0e10cSrcweir // because the format scanner in the context of 3693cdf0e10cSrcweir // "?," doesn't generate a group separator but 3694cdf0e10cSrcweir // a literal ',' character instead that is 3695cdf0e10cSrcweir // inserted unconditionally. Should be changed 3696cdf0e10cSrcweir // on some occasion. 3697cdf0e10cSrcweir sStr.Insert(' ',k); 3698cdf0e10cSrcweir break; 3699cdf0e10cSrcweir default: 3700cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j],k); 3701cdf0e10cSrcweir } 3702cdf0e10cSrcweir } 3703cdf0e10cSrcweir aGrouping.advance(); 3704cdf0e10cSrcweir } 3705cdf0e10cSrcweir } 3706cdf0e10cSrcweir break; 3707cdf0e10cSrcweir case NF_SYMBOLTYPE_DIGIT: 3708cdf0e10cSrcweir { 3709cdf0e10cSrcweir const String& rStr = rInfo.sStrArray[j]; 3710cdf0e10cSrcweir const sal_Unicode* p1 = rStr.GetBuffer(); 3711cdf0e10cSrcweir register const sal_Unicode* p = p1 + rStr.Len(); 3712cdf0e10cSrcweir while ( p1 < p-- ) 3713cdf0e10cSrcweir { 3714cdf0e10cSrcweir nDigitCount++; 3715cdf0e10cSrcweir if (k > 0) 3716cdf0e10cSrcweir k--; 3717cdf0e10cSrcweir else 3718cdf0e10cSrcweir { 3719cdf0e10cSrcweir switch (*p) 3720cdf0e10cSrcweir { 3721cdf0e10cSrcweir case '0': 3722cdf0e10cSrcweir sStr.Insert('0',0); 3723cdf0e10cSrcweir break; 3724cdf0e10cSrcweir case '?': 3725cdf0e10cSrcweir sStr.Insert(' ',0); 3726cdf0e10cSrcweir break; 3727cdf0e10cSrcweir } 3728cdf0e10cSrcweir } 3729cdf0e10cSrcweir if (nDigitCount == nDigCnt && k > 0) 3730cdf0e10cSrcweir { // more digits than specified 3731cdf0e10cSrcweir ImpDigitFill(sStr, 0, k, nIx, nDigitCount, aGrouping); 3732cdf0e10cSrcweir } 3733cdf0e10cSrcweir } 3734cdf0e10cSrcweir } 3735cdf0e10cSrcweir break; 3736cdf0e10cSrcweir case NF_KEY_CCC: // CCC currency 3737cdf0e10cSrcweir sStr.Insert(rScan.GetCurAbbrev(), k); 3738cdf0e10cSrcweir break; 3739cdf0e10cSrcweir case NF_KEY_GENERAL: // "General" in string 3740cdf0e10cSrcweir { 3741cdf0e10cSrcweir String sNum; 3742cdf0e10cSrcweir ImpGetOutputStandard(rNumber, sNum); 3743cdf0e10cSrcweir sNum.EraseLeadingChars('-'); 3744cdf0e10cSrcweir sStr.Insert(sNum, k); 3745cdf0e10cSrcweir } 3746cdf0e10cSrcweir break; 3747cdf0e10cSrcweir 3748cdf0e10cSrcweir default: 3749cdf0e10cSrcweir break; 3750cdf0e10cSrcweir } // switch 3751cdf0e10cSrcweir j--; // next format code string 3752cdf0e10cSrcweir } // while 3753cdf0e10cSrcweir k = k + nLeadingStringChars; // MSC converts += to int and then warns, so ... 3754cdf0e10cSrcweir if (k > nLeadingStringChars) 3755cdf0e10cSrcweir ImpDigitFill(sStr, nLeadingStringChars, k, nIx, nDigitCount, aGrouping); 3756cdf0e10cSrcweir return bRes; 3757cdf0e10cSrcweir } 3758cdf0e10cSrcweir 3759cdf0e10cSrcweir void SvNumberformat::ImpDigitFill( 3760cdf0e10cSrcweir String& sStr, // number string 3761cdf0e10cSrcweir xub_StrLen nStart, // start of digits 3762cdf0e10cSrcweir xub_StrLen& k, // position within string 3763cdf0e10cSrcweir sal_uInt16 nIx, // subformat index 3764cdf0e10cSrcweir xub_StrLen & nDigitCount, // count of integer digits from the right so far 3765cdf0e10cSrcweir utl::DigitGroupingIterator & rGrouping ) // current grouping 3766cdf0e10cSrcweir { 3767cdf0e10cSrcweir if (NumFor[nIx].Info().bThousand) // only if grouping 3768cdf0e10cSrcweir { // fill in separators 3769cdf0e10cSrcweir const String& rThousandSep = GetFormatter().GetNumThousandSep(); 3770cdf0e10cSrcweir while (k > nStart) 3771cdf0e10cSrcweir { 3772cdf0e10cSrcweir if (nDigitCount == rGrouping.getPos()) 3773cdf0e10cSrcweir { 3774cdf0e10cSrcweir sStr.Insert( rThousandSep, k ); 3775cdf0e10cSrcweir rGrouping.advance(); 3776cdf0e10cSrcweir } 3777cdf0e10cSrcweir nDigitCount++; 3778cdf0e10cSrcweir k--; 3779cdf0e10cSrcweir } 3780cdf0e10cSrcweir } 3781cdf0e10cSrcweir else // simply skip 3782cdf0e10cSrcweir k = nStart; 3783cdf0e10cSrcweir } 3784cdf0e10cSrcweir 3785cdf0e10cSrcweir sal_Bool SvNumberformat::ImpNumberFill( String& sStr, // number string 3786cdf0e10cSrcweir double& rNumber, // number for "General" format 3787cdf0e10cSrcweir xub_StrLen& k, // position within string 3788cdf0e10cSrcweir sal_uInt16& j, // symbol index within format code 3789cdf0e10cSrcweir sal_uInt16 nIx, // subformat index 3790cdf0e10cSrcweir short eSymbolType ) // type of stop condition 3791cdf0e10cSrcweir { 3792cdf0e10cSrcweir sal_Bool bRes = sal_False; 3793cdf0e10cSrcweir k = sStr.Len(); // behind last digit 3794cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); 3795cdf0e10cSrcweir // no normal thousands separators if number divided by thousands 3796cdf0e10cSrcweir sal_Bool bDoThousands = (rInfo.nThousand == 0); 3797cdf0e10cSrcweir short nType; 3798cdf0e10cSrcweir while (j > 0 && (nType = rInfo.nTypeArray[j]) != eSymbolType ) 3799cdf0e10cSrcweir { // rueckwaerts: 3800cdf0e10cSrcweir switch ( nType ) 3801cdf0e10cSrcweir { 3802cdf0e10cSrcweir case NF_SYMBOLTYPE_STAR: 3803cdf0e10cSrcweir if( bStarFlag ) 3804cdf0e10cSrcweir { 3805cdf0e10cSrcweir sStr.Insert( sal_Unicode(0x1B), k++ ); 3806cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j].GetChar(1),k); 3807cdf0e10cSrcweir bRes = sal_True; 3808cdf0e10cSrcweir } 3809cdf0e10cSrcweir break; 3810cdf0e10cSrcweir case NF_SYMBOLTYPE_BLANK: 3811cdf0e10cSrcweir k = InsertBlanks( sStr,k,rInfo.sStrArray[j].GetChar(1) ); 3812cdf0e10cSrcweir break; 3813cdf0e10cSrcweir case NF_SYMBOLTYPE_THSEP: 3814cdf0e10cSrcweir { 3815cdf0e10cSrcweir // Same as in ImpNumberFillWithThousands() above, do not insert 3816cdf0e10cSrcweir // if divided and regex [0#,],[^0#] and no other digit symbol 3817cdf0e10cSrcweir // follows (which was already detected during scan of format 3818cdf0e10cSrcweir // code, otherwise there would be no division), else do insert. 3819cdf0e10cSrcweir if ( !bDoThousands && j < NumFor[nIx].GetnAnz()-1 ) 3820cdf0e10cSrcweir bDoThousands = ((j == 0) || 3821cdf0e10cSrcweir (rInfo.nTypeArray[j-1] != NF_SYMBOLTYPE_DIGIT && 3822cdf0e10cSrcweir rInfo.nTypeArray[j-1] != NF_SYMBOLTYPE_THSEP) || 3823cdf0e10cSrcweir (rInfo.nTypeArray[j+1] == NF_SYMBOLTYPE_DIGIT)); 3824cdf0e10cSrcweir if ( bDoThousands && k > 0 ) 3825cdf0e10cSrcweir { 3826cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j],k); 3827cdf0e10cSrcweir } 3828cdf0e10cSrcweir } 3829cdf0e10cSrcweir break; 3830cdf0e10cSrcweir case NF_SYMBOLTYPE_DIGIT: 3831cdf0e10cSrcweir { 3832cdf0e10cSrcweir const String& rStr = rInfo.sStrArray[j]; 3833cdf0e10cSrcweir const sal_Unicode* p1 = rStr.GetBuffer(); 3834cdf0e10cSrcweir register const sal_Unicode* p = p1 + rStr.Len(); 3835cdf0e10cSrcweir while ( p1 < p-- ) 3836cdf0e10cSrcweir { 3837cdf0e10cSrcweir if (k > 0) 3838cdf0e10cSrcweir k--; 3839cdf0e10cSrcweir else 3840cdf0e10cSrcweir { 3841cdf0e10cSrcweir switch (*p) 3842cdf0e10cSrcweir { 3843cdf0e10cSrcweir case '0': 3844cdf0e10cSrcweir sStr.Insert('0',0); 3845cdf0e10cSrcweir break; 3846cdf0e10cSrcweir case '?': 3847cdf0e10cSrcweir sStr.Insert(' ',0); 3848cdf0e10cSrcweir break; 3849cdf0e10cSrcweir } 3850cdf0e10cSrcweir } 3851cdf0e10cSrcweir } 3852cdf0e10cSrcweir } 3853cdf0e10cSrcweir break; 3854cdf0e10cSrcweir case NF_KEY_CCC: // CCC-Waehrung 3855cdf0e10cSrcweir sStr.Insert(rScan.GetCurAbbrev(), k); 3856cdf0e10cSrcweir break; 3857cdf0e10cSrcweir case NF_KEY_GENERAL: // Standard im String 3858cdf0e10cSrcweir { 3859cdf0e10cSrcweir String sNum; 3860cdf0e10cSrcweir ImpGetOutputStandard(rNumber, sNum); 3861cdf0e10cSrcweir sNum.EraseLeadingChars('-'); // Vorzeichen weg!! 3862cdf0e10cSrcweir sStr.Insert(sNum, k); 3863cdf0e10cSrcweir } 3864cdf0e10cSrcweir break; 3865cdf0e10cSrcweir 3866cdf0e10cSrcweir default: 3867cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j],k); 3868cdf0e10cSrcweir break; 3869cdf0e10cSrcweir } // of switch 3870cdf0e10cSrcweir j--; // naechster String 3871cdf0e10cSrcweir } // of while 3872cdf0e10cSrcweir return bRes; 3873cdf0e10cSrcweir } 3874cdf0e10cSrcweir 3875cdf0e10cSrcweir void SvNumberformat::GetFormatSpecialInfo(sal_Bool& bThousand, 3876cdf0e10cSrcweir sal_Bool& IsRed, 3877cdf0e10cSrcweir sal_uInt16& nPrecision, 3878cdf0e10cSrcweir sal_uInt16& nAnzLeading) const 3879cdf0e10cSrcweir { 3880cdf0e10cSrcweir // as before: take info from nNumFor=0 for whole format (for dialog etc.) 3881cdf0e10cSrcweir 3882cdf0e10cSrcweir short nDummyType; 3883cdf0e10cSrcweir GetNumForInfo( 0, nDummyType, bThousand, nPrecision, nAnzLeading ); 3884cdf0e10cSrcweir 3885cdf0e10cSrcweir // "negative in red" is only useful for the whole format 3886cdf0e10cSrcweir 3887cdf0e10cSrcweir const Color* pColor = NumFor[1].GetColor(); 3888cdf0e10cSrcweir if (fLimit1 == 0.0 && fLimit2 == 0.0 && pColor 3889cdf0e10cSrcweir && (*pColor == rScan.GetRedColor())) 3890cdf0e10cSrcweir IsRed = sal_True; 3891cdf0e10cSrcweir else 3892cdf0e10cSrcweir IsRed = sal_False; 3893cdf0e10cSrcweir } 3894cdf0e10cSrcweir 3895cdf0e10cSrcweir void SvNumberformat::GetNumForInfo( sal_uInt16 nNumFor, short& rScannedType, 3896cdf0e10cSrcweir sal_Bool& bThousand, sal_uInt16& nPrecision, sal_uInt16& nAnzLeading ) const 3897cdf0e10cSrcweir { 3898cdf0e10cSrcweir // take info from a specified sub-format (for XML export) 3899cdf0e10cSrcweir 3900cdf0e10cSrcweir if ( nNumFor > 3 ) 3901cdf0e10cSrcweir return; // invalid 3902cdf0e10cSrcweir 3903cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = NumFor[nNumFor].Info(); 3904cdf0e10cSrcweir rScannedType = rInfo.eScannedType; 3905cdf0e10cSrcweir bThousand = rInfo.bThousand; 3906cdf0e10cSrcweir nPrecision = rInfo.nCntPost; 3907cdf0e10cSrcweir if (bStandard && rInfo.eScannedType == NUMBERFORMAT_NUMBER) 3908cdf0e10cSrcweir // StandardFormat 3909cdf0e10cSrcweir nAnzLeading = 1; 3910cdf0e10cSrcweir else 3911cdf0e10cSrcweir { 3912cdf0e10cSrcweir nAnzLeading = 0; 3913cdf0e10cSrcweir sal_Bool bStop = sal_False; 3914cdf0e10cSrcweir sal_uInt16 i = 0; 3915cdf0e10cSrcweir const sal_uInt16 nAnz = NumFor[nNumFor].GetnAnz(); 3916cdf0e10cSrcweir while (!bStop && i < nAnz) 3917cdf0e10cSrcweir { 3918cdf0e10cSrcweir short nType = rInfo.nTypeArray[i]; 3919cdf0e10cSrcweir if ( nType == NF_SYMBOLTYPE_DIGIT) 3920cdf0e10cSrcweir { 3921cdf0e10cSrcweir register const sal_Unicode* p = rInfo.sStrArray[i].GetBuffer(); 3922cdf0e10cSrcweir while ( *p == '#' ) 3923cdf0e10cSrcweir p++; 3924cdf0e10cSrcweir while ( *p++ == '0' ) 3925cdf0e10cSrcweir nAnzLeading++; 3926cdf0e10cSrcweir } 3927cdf0e10cSrcweir else if (nType == NF_SYMBOLTYPE_DECSEP || nType == NF_SYMBOLTYPE_EXP) 3928cdf0e10cSrcweir bStop = sal_True; 3929cdf0e10cSrcweir i++; 3930cdf0e10cSrcweir } 3931cdf0e10cSrcweir } 3932cdf0e10cSrcweir } 3933cdf0e10cSrcweir 3934cdf0e10cSrcweir const String* SvNumberformat::GetNumForString( sal_uInt16 nNumFor, sal_uInt16 nPos, 3935cdf0e10cSrcweir sal_Bool bString /* = sal_False */ ) const 3936cdf0e10cSrcweir { 3937cdf0e10cSrcweir if ( nNumFor > 3 ) 3938cdf0e10cSrcweir return NULL; 3939cdf0e10cSrcweir sal_uInt16 nAnz = NumFor[nNumFor].GetnAnz(); 3940cdf0e10cSrcweir if ( !nAnz ) 3941cdf0e10cSrcweir return NULL; 3942cdf0e10cSrcweir if ( nPos == 0xFFFF ) 3943cdf0e10cSrcweir { 3944cdf0e10cSrcweir nPos = nAnz - 1; 3945cdf0e10cSrcweir if ( bString ) 3946cdf0e10cSrcweir { // rueckwaerts 3947cdf0e10cSrcweir short* pType = NumFor[nNumFor].Info().nTypeArray + nPos; 3948cdf0e10cSrcweir while ( nPos > 0 && (*pType != NF_SYMBOLTYPE_STRING) && 3949cdf0e10cSrcweir (*pType != NF_SYMBOLTYPE_CURRENCY) ) 3950cdf0e10cSrcweir { 3951cdf0e10cSrcweir pType--; 3952cdf0e10cSrcweir nPos--; 3953cdf0e10cSrcweir } 3954cdf0e10cSrcweir if ( (*pType != NF_SYMBOLTYPE_STRING) && (*pType != NF_SYMBOLTYPE_CURRENCY) ) 3955cdf0e10cSrcweir return NULL; 3956cdf0e10cSrcweir } 3957cdf0e10cSrcweir } 3958cdf0e10cSrcweir else if ( nPos > nAnz - 1 ) 3959cdf0e10cSrcweir return NULL; 3960cdf0e10cSrcweir else if ( bString ) 3961cdf0e10cSrcweir { // vorwaerts 3962cdf0e10cSrcweir short* pType = NumFor[nNumFor].Info().nTypeArray + nPos; 3963cdf0e10cSrcweir while ( nPos < nAnz && (*pType != NF_SYMBOLTYPE_STRING) && 3964cdf0e10cSrcweir (*pType != NF_SYMBOLTYPE_CURRENCY) ) 3965cdf0e10cSrcweir { 3966cdf0e10cSrcweir pType++; 3967cdf0e10cSrcweir nPos++; 3968cdf0e10cSrcweir } 3969cdf0e10cSrcweir if ( nPos >= nAnz || ((*pType != NF_SYMBOLTYPE_STRING) && 3970cdf0e10cSrcweir (*pType != NF_SYMBOLTYPE_CURRENCY)) ) 3971cdf0e10cSrcweir return NULL; 3972cdf0e10cSrcweir } 3973cdf0e10cSrcweir return &NumFor[nNumFor].Info().sStrArray[nPos]; 3974cdf0e10cSrcweir } 3975cdf0e10cSrcweir 3976cdf0e10cSrcweir 3977cdf0e10cSrcweir short SvNumberformat::GetNumForType( sal_uInt16 nNumFor, sal_uInt16 nPos, 3978cdf0e10cSrcweir sal_Bool bString /* = sal_False */ ) const 3979cdf0e10cSrcweir { 3980cdf0e10cSrcweir if ( nNumFor > 3 ) 3981cdf0e10cSrcweir return 0; 3982cdf0e10cSrcweir sal_uInt16 nAnz = NumFor[nNumFor].GetnAnz(); 3983cdf0e10cSrcweir if ( !nAnz ) 3984cdf0e10cSrcweir return 0; 3985cdf0e10cSrcweir if ( nPos == 0xFFFF ) 3986cdf0e10cSrcweir { 3987cdf0e10cSrcweir nPos = nAnz - 1; 3988cdf0e10cSrcweir if ( bString ) 3989cdf0e10cSrcweir { // rueckwaerts 3990cdf0e10cSrcweir short* pType = NumFor[nNumFor].Info().nTypeArray + nPos; 3991cdf0e10cSrcweir while ( nPos > 0 && (*pType != NF_SYMBOLTYPE_STRING) && 3992cdf0e10cSrcweir (*pType != NF_SYMBOLTYPE_CURRENCY) ) 3993cdf0e10cSrcweir { 3994cdf0e10cSrcweir pType--; 3995cdf0e10cSrcweir nPos--; 3996cdf0e10cSrcweir } 3997cdf0e10cSrcweir if ( (*pType != NF_SYMBOLTYPE_STRING) && (*pType != NF_SYMBOLTYPE_CURRENCY) ) 3998cdf0e10cSrcweir return 0; 3999cdf0e10cSrcweir } 4000cdf0e10cSrcweir } 4001cdf0e10cSrcweir else if ( nPos > nAnz - 1 ) 4002cdf0e10cSrcweir return 0; 4003cdf0e10cSrcweir else if ( bString ) 4004cdf0e10cSrcweir { // vorwaerts 4005cdf0e10cSrcweir short* pType = NumFor[nNumFor].Info().nTypeArray + nPos; 4006cdf0e10cSrcweir while ( nPos < nAnz && (*pType != NF_SYMBOLTYPE_STRING) && 4007cdf0e10cSrcweir (*pType != NF_SYMBOLTYPE_CURRENCY) ) 4008cdf0e10cSrcweir { 4009cdf0e10cSrcweir pType++; 4010cdf0e10cSrcweir nPos++; 4011cdf0e10cSrcweir } 4012cdf0e10cSrcweir if ( (*pType != NF_SYMBOLTYPE_STRING) && (*pType != NF_SYMBOLTYPE_CURRENCY) ) 4013cdf0e10cSrcweir return 0; 4014cdf0e10cSrcweir } 4015cdf0e10cSrcweir return NumFor[nNumFor].Info().nTypeArray[nPos]; 4016cdf0e10cSrcweir } 4017cdf0e10cSrcweir 4018cdf0e10cSrcweir 4019cdf0e10cSrcweir sal_Bool SvNumberformat::IsNegativeWithoutSign() const 4020cdf0e10cSrcweir { 4021cdf0e10cSrcweir if ( IsNegativeRealNegative() ) 4022cdf0e10cSrcweir { 4023cdf0e10cSrcweir const String* pStr = GetNumForString( 1, 0, sal_True ); 4024cdf0e10cSrcweir if ( pStr ) 4025cdf0e10cSrcweir return !HasStringNegativeSign( *pStr ); 4026cdf0e10cSrcweir } 4027cdf0e10cSrcweir return sal_False; 4028cdf0e10cSrcweir } 4029cdf0e10cSrcweir 4030cdf0e10cSrcweir 4031cdf0e10cSrcweir DateFormat SvNumberformat::GetDateOrder() const 4032cdf0e10cSrcweir { 4033cdf0e10cSrcweir if ( (eType & NUMBERFORMAT_DATE) == NUMBERFORMAT_DATE ) 4034cdf0e10cSrcweir { 4035cdf0e10cSrcweir short const * const pType = NumFor[0].Info().nTypeArray; 4036cdf0e10cSrcweir sal_uInt16 nAnz = NumFor[0].GetnAnz(); 4037cdf0e10cSrcweir for ( sal_uInt16 j=0; j<nAnz; j++ ) 4038cdf0e10cSrcweir { 4039cdf0e10cSrcweir switch ( pType[j] ) 4040cdf0e10cSrcweir { 4041cdf0e10cSrcweir case NF_KEY_D : 4042cdf0e10cSrcweir case NF_KEY_DD : 4043cdf0e10cSrcweir return DMY; 4044cdf0e10cSrcweir case NF_KEY_M : 4045cdf0e10cSrcweir case NF_KEY_MM : 4046cdf0e10cSrcweir case NF_KEY_MMM : 4047cdf0e10cSrcweir case NF_KEY_MMMM : 4048cdf0e10cSrcweir case NF_KEY_MMMMM : 4049cdf0e10cSrcweir return MDY; 4050cdf0e10cSrcweir case NF_KEY_YY : 4051cdf0e10cSrcweir case NF_KEY_YYYY : 4052cdf0e10cSrcweir case NF_KEY_EC : 4053cdf0e10cSrcweir case NF_KEY_EEC : 4054cdf0e10cSrcweir case NF_KEY_R : 4055cdf0e10cSrcweir case NF_KEY_RR : 4056cdf0e10cSrcweir return YMD; 4057cdf0e10cSrcweir } 4058cdf0e10cSrcweir } 4059cdf0e10cSrcweir } 4060cdf0e10cSrcweir else 4061cdf0e10cSrcweir { 4062cdf0e10cSrcweir DBG_ERROR( "SvNumberformat::GetDateOrder: no date" ); 4063cdf0e10cSrcweir } 4064cdf0e10cSrcweir return rLoc().getDateFormat(); 4065cdf0e10cSrcweir } 4066cdf0e10cSrcweir 4067cdf0e10cSrcweir 4068cdf0e10cSrcweir sal_uInt32 SvNumberformat::GetExactDateOrder() const 4069cdf0e10cSrcweir { 4070cdf0e10cSrcweir sal_uInt32 nRet = 0; 4071cdf0e10cSrcweir if ( (eType & NUMBERFORMAT_DATE) != NUMBERFORMAT_DATE ) 4072cdf0e10cSrcweir { 4073cdf0e10cSrcweir DBG_ERROR( "SvNumberformat::GetExactDateOrder: no date" ); 4074cdf0e10cSrcweir return nRet; 4075cdf0e10cSrcweir } 4076cdf0e10cSrcweir short const * const pType = NumFor[0].Info().nTypeArray; 4077cdf0e10cSrcweir sal_uInt16 nAnz = NumFor[0].GetnAnz(); 4078cdf0e10cSrcweir int nShift = 0; 4079cdf0e10cSrcweir for ( sal_uInt16 j=0; j<nAnz && nShift < 3; j++ ) 4080cdf0e10cSrcweir { 4081cdf0e10cSrcweir switch ( pType[j] ) 4082cdf0e10cSrcweir { 4083cdf0e10cSrcweir case NF_KEY_D : 4084cdf0e10cSrcweir case NF_KEY_DD : 4085cdf0e10cSrcweir nRet = (nRet << 8) | 'D'; 4086cdf0e10cSrcweir ++nShift; 4087cdf0e10cSrcweir break; 4088cdf0e10cSrcweir case NF_KEY_M : 4089cdf0e10cSrcweir case NF_KEY_MM : 4090cdf0e10cSrcweir case NF_KEY_MMM : 4091cdf0e10cSrcweir case NF_KEY_MMMM : 4092cdf0e10cSrcweir case NF_KEY_MMMMM : 4093cdf0e10cSrcweir nRet = (nRet << 8) | 'M'; 4094cdf0e10cSrcweir ++nShift; 4095cdf0e10cSrcweir break; 4096cdf0e10cSrcweir case NF_KEY_YY : 4097cdf0e10cSrcweir case NF_KEY_YYYY : 4098cdf0e10cSrcweir case NF_KEY_EC : 4099cdf0e10cSrcweir case NF_KEY_EEC : 4100cdf0e10cSrcweir case NF_KEY_R : 4101cdf0e10cSrcweir case NF_KEY_RR : 4102cdf0e10cSrcweir nRet = (nRet << 8) | 'Y'; 4103cdf0e10cSrcweir ++nShift; 4104cdf0e10cSrcweir break; 4105cdf0e10cSrcweir } 4106cdf0e10cSrcweir } 4107cdf0e10cSrcweir return nRet; 4108cdf0e10cSrcweir } 4109cdf0e10cSrcweir 4110cdf0e10cSrcweir 4111cdf0e10cSrcweir void SvNumberformat::GetConditions( SvNumberformatLimitOps& rOper1, double& rVal1, 4112cdf0e10cSrcweir SvNumberformatLimitOps& rOper2, double& rVal2 ) const 4113cdf0e10cSrcweir { 4114cdf0e10cSrcweir rOper1 = eOp1; 4115cdf0e10cSrcweir rOper2 = eOp2; 4116cdf0e10cSrcweir rVal1 = fLimit1; 4117cdf0e10cSrcweir rVal2 = fLimit2; 4118cdf0e10cSrcweir } 4119cdf0e10cSrcweir 4120cdf0e10cSrcweir 4121cdf0e10cSrcweir Color* SvNumberformat::GetColor( sal_uInt16 nNumFor ) const 4122cdf0e10cSrcweir { 4123cdf0e10cSrcweir if ( nNumFor > 3 ) 4124cdf0e10cSrcweir return NULL; 4125cdf0e10cSrcweir 4126cdf0e10cSrcweir return NumFor[nNumFor].GetColor(); 4127cdf0e10cSrcweir } 4128cdf0e10cSrcweir 4129cdf0e10cSrcweir 4130cdf0e10cSrcweir void lcl_SvNumberformat_AddLimitStringImpl( String& rStr, 4131cdf0e10cSrcweir SvNumberformatLimitOps eOp, double fLimit, const String& rDecSep ) 4132cdf0e10cSrcweir { 4133cdf0e10cSrcweir if ( eOp != NUMBERFORMAT_OP_NO ) 4134cdf0e10cSrcweir { 4135cdf0e10cSrcweir switch ( eOp ) 4136cdf0e10cSrcweir { 4137cdf0e10cSrcweir case NUMBERFORMAT_OP_EQ : 4138cdf0e10cSrcweir rStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "[=" ) ); 4139cdf0e10cSrcweir break; 4140cdf0e10cSrcweir case NUMBERFORMAT_OP_NE : 4141cdf0e10cSrcweir rStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "[<>" ) ); 4142cdf0e10cSrcweir break; 4143cdf0e10cSrcweir case NUMBERFORMAT_OP_LT : 4144cdf0e10cSrcweir rStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "[<" ) ); 4145cdf0e10cSrcweir break; 4146cdf0e10cSrcweir case NUMBERFORMAT_OP_LE : 4147cdf0e10cSrcweir rStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "[<=" ) ); 4148cdf0e10cSrcweir break; 4149cdf0e10cSrcweir case NUMBERFORMAT_OP_GT : 4150cdf0e10cSrcweir rStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "[>" ) ); 4151cdf0e10cSrcweir break; 4152cdf0e10cSrcweir case NUMBERFORMAT_OP_GE : 4153cdf0e10cSrcweir rStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "[>=" ) ); 4154cdf0e10cSrcweir break; 4155cdf0e10cSrcweir default: 4156cdf0e10cSrcweir OSL_ASSERT( "unsupported number format" ); 4157cdf0e10cSrcweir break; 4158cdf0e10cSrcweir } 4159cdf0e10cSrcweir rStr += String( ::rtl::math::doubleToUString( fLimit, 4160cdf0e10cSrcweir rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, 4161cdf0e10cSrcweir rDecSep.GetChar(0), sal_True)); 4162cdf0e10cSrcweir rStr += ']'; 4163cdf0e10cSrcweir } 4164cdf0e10cSrcweir } 4165cdf0e10cSrcweir 4166cdf0e10cSrcweir 4167cdf0e10cSrcweir String SvNumberformat::GetMappedFormatstring( 4168cdf0e10cSrcweir const NfKeywordTable& rKeywords, const LocaleDataWrapper& rLocWrp, 4169cdf0e10cSrcweir sal_Bool bDontQuote ) const 4170cdf0e10cSrcweir { 4171cdf0e10cSrcweir String aStr; 4172cdf0e10cSrcweir sal_Bool bDefault[4]; 4173cdf0e10cSrcweir // 1 subformat matches all if no condition specified, 4174cdf0e10cSrcweir bDefault[0] = ( NumFor[1].GetnAnz() == 0 && eOp1 == NUMBERFORMAT_OP_NO ); 4175cdf0e10cSrcweir // with 2 subformats [>=0];[<0] is implied if no condition specified 4176cdf0e10cSrcweir bDefault[1] = ( !bDefault[0] && NumFor[2].GetnAnz() == 0 && 4177cdf0e10cSrcweir eOp1 == NUMBERFORMAT_OP_GE && fLimit1 == 0.0 && 4178cdf0e10cSrcweir eOp2 == NUMBERFORMAT_OP_NO && fLimit2 == 0.0 ); 4179cdf0e10cSrcweir // with 3 or more subformats [>0];[<0];[=0] is implied if no condition specified, 4180cdf0e10cSrcweir // note that subformats may be empty (;;;) and NumFor[2].GetnAnz()>0 is not checked. 4181cdf0e10cSrcweir bDefault[2] = ( !bDefault[0] && !bDefault[1] && 4182cdf0e10cSrcweir eOp1 == NUMBERFORMAT_OP_GT && fLimit1 == 0.0 && 4183cdf0e10cSrcweir eOp2 == NUMBERFORMAT_OP_LT && fLimit2 == 0.0 ); 4184cdf0e10cSrcweir sal_Bool bDefaults = bDefault[0] || bDefault[1] || bDefault[2]; 4185cdf0e10cSrcweir // from now on bDefault[] values are used to append empty subformats at the end 4186cdf0e10cSrcweir bDefault[3] = sal_False; 4187cdf0e10cSrcweir if ( !bDefaults ) 4188cdf0e10cSrcweir { // conditions specified 4189cdf0e10cSrcweir if ( eOp1 != NUMBERFORMAT_OP_NO && eOp2 == NUMBERFORMAT_OP_NO ) 4190cdf0e10cSrcweir bDefault[0] = bDefault[1] = sal_True; // [];x 4191cdf0e10cSrcweir else if ( eOp1 != NUMBERFORMAT_OP_NO && eOp2 != NUMBERFORMAT_OP_NO && 4192cdf0e10cSrcweir NumFor[2].GetnAnz() == 0 ) 4193cdf0e10cSrcweir bDefault[0] = bDefault[1] = bDefault[2] = bDefault[3] = sal_True; // [];[];; 4194cdf0e10cSrcweir // nothing to do if conditions specified for every subformat 4195cdf0e10cSrcweir } 4196cdf0e10cSrcweir else if ( bDefault[0] ) 4197cdf0e10cSrcweir bDefault[0] = sal_False; // a single unconditional subformat is never delimited 4198cdf0e10cSrcweir else 4199cdf0e10cSrcweir { 4200cdf0e10cSrcweir if ( bDefault[2] && NumFor[2].GetnAnz() == 0 && NumFor[1].GetnAnz() > 0 ) 4201cdf0e10cSrcweir bDefault[3] = sal_True; // special cases x;x;; and ;x;; 4202cdf0e10cSrcweir for ( int i=0; i<3 && !bDefault[i]; ++i ) 4203cdf0e10cSrcweir bDefault[i] = sal_True; 4204cdf0e10cSrcweir } 4205cdf0e10cSrcweir int nSem = 0; // needed ';' delimiters 4206cdf0e10cSrcweir int nSub = 0; // subformats delimited so far 4207cdf0e10cSrcweir for ( int n=0; n<4; n++ ) 4208cdf0e10cSrcweir { 4209cdf0e10cSrcweir if ( n > 0 ) 4210cdf0e10cSrcweir nSem++; 4211cdf0e10cSrcweir 4212cdf0e10cSrcweir String aPrefix; 4213cdf0e10cSrcweir 4214cdf0e10cSrcweir if ( !bDefaults ) 4215cdf0e10cSrcweir { 4216cdf0e10cSrcweir switch ( n ) 4217cdf0e10cSrcweir { 4218cdf0e10cSrcweir case 0 : 4219cdf0e10cSrcweir lcl_SvNumberformat_AddLimitStringImpl( aPrefix, eOp1, 4220cdf0e10cSrcweir fLimit1, rLocWrp.getNumDecimalSep() ); 4221cdf0e10cSrcweir break; 4222cdf0e10cSrcweir case 1 : 4223cdf0e10cSrcweir lcl_SvNumberformat_AddLimitStringImpl( aPrefix, eOp2, 4224cdf0e10cSrcweir fLimit2, rLocWrp.getNumDecimalSep() ); 4225cdf0e10cSrcweir break; 4226cdf0e10cSrcweir } 4227cdf0e10cSrcweir } 4228cdf0e10cSrcweir 4229cdf0e10cSrcweir const String& rColorName = NumFor[n].GetColorName(); 4230cdf0e10cSrcweir if ( rColorName.Len() ) 4231cdf0e10cSrcweir { 4232cdf0e10cSrcweir const NfKeywordTable & rKey = rScan.GetKeywords(); 4233cdf0e10cSrcweir for ( int j=NF_KEY_FIRSTCOLOR; j<=NF_KEY_LASTCOLOR; j++ ) 4234cdf0e10cSrcweir { 4235cdf0e10cSrcweir if ( rKey[j] == rColorName ) 4236cdf0e10cSrcweir { 4237cdf0e10cSrcweir aPrefix += '['; 4238cdf0e10cSrcweir aPrefix += rKeywords[j]; 4239cdf0e10cSrcweir aPrefix += ']'; 4240cdf0e10cSrcweir break; // for 4241cdf0e10cSrcweir } 4242cdf0e10cSrcweir } 4243cdf0e10cSrcweir } 4244cdf0e10cSrcweir 4245cdf0e10cSrcweir const SvNumberNatNum& rNum = NumFor[n].GetNatNum(); 4246cdf0e10cSrcweir // The Thai T NatNum modifier during Xcl export. 4247cdf0e10cSrcweir if (rNum.IsSet() && rNum.GetNatNum() == 1 && 4248cdf0e10cSrcweir rKeywords[NF_KEY_THAI_T].EqualsAscii( "T") && 4249cdf0e10cSrcweir MsLangId::getRealLanguage( rNum.GetLang()) == 4250cdf0e10cSrcweir LANGUAGE_THAI) 4251cdf0e10cSrcweir { 4252cdf0e10cSrcweir aPrefix += 't'; // must be lowercase, otherwise taken as literal 4253cdf0e10cSrcweir } 4254cdf0e10cSrcweir 4255cdf0e10cSrcweir sal_uInt16 nAnz = NumFor[n].GetnAnz(); 4256cdf0e10cSrcweir if ( nSem && (nAnz || aPrefix.Len()) ) 4257cdf0e10cSrcweir { 4258cdf0e10cSrcweir for ( ; nSem; --nSem ) 4259cdf0e10cSrcweir aStr += ';'; 4260cdf0e10cSrcweir for ( ; nSub <= n; ++nSub ) 4261cdf0e10cSrcweir bDefault[nSub] = sal_False; 4262cdf0e10cSrcweir } 4263cdf0e10cSrcweir 4264cdf0e10cSrcweir if ( aPrefix.Len() ) 4265cdf0e10cSrcweir aStr += aPrefix; 4266cdf0e10cSrcweir 4267cdf0e10cSrcweir if ( nAnz ) 4268cdf0e10cSrcweir { 4269cdf0e10cSrcweir const short* pType = NumFor[n].Info().nTypeArray; 4270cdf0e10cSrcweir const String* pStr = NumFor[n].Info().sStrArray; 4271cdf0e10cSrcweir for ( sal_uInt16 j=0; j<nAnz; j++ ) 4272cdf0e10cSrcweir { 4273cdf0e10cSrcweir if ( 0 <= pType[j] && pType[j] < NF_KEYWORD_ENTRIES_COUNT ) 4274cdf0e10cSrcweir { 4275cdf0e10cSrcweir aStr += rKeywords[pType[j]]; 4276cdf0e10cSrcweir if( NF_KEY_NNNN == pType[j] ) 4277cdf0e10cSrcweir aStr += rLocWrp.getLongDateDayOfWeekSep(); 4278cdf0e10cSrcweir } 4279cdf0e10cSrcweir else 4280cdf0e10cSrcweir { 4281cdf0e10cSrcweir switch ( pType[j] ) 4282cdf0e10cSrcweir { 4283cdf0e10cSrcweir case NF_SYMBOLTYPE_DECSEP : 4284cdf0e10cSrcweir aStr += rLocWrp.getNumDecimalSep(); 4285cdf0e10cSrcweir break; 4286cdf0e10cSrcweir case NF_SYMBOLTYPE_THSEP : 4287cdf0e10cSrcweir aStr += rLocWrp.getNumThousandSep(); 4288cdf0e10cSrcweir break; 4289cdf0e10cSrcweir case NF_SYMBOLTYPE_DATESEP : 4290cdf0e10cSrcweir aStr += rLocWrp.getDateSep(); 4291cdf0e10cSrcweir break; 4292cdf0e10cSrcweir case NF_SYMBOLTYPE_TIMESEP : 4293cdf0e10cSrcweir aStr += rLocWrp.getTimeSep(); 4294cdf0e10cSrcweir break; 4295cdf0e10cSrcweir case NF_SYMBOLTYPE_TIME100SECSEP : 4296cdf0e10cSrcweir aStr += rLocWrp.getTime100SecSep(); 4297cdf0e10cSrcweir break; 4298cdf0e10cSrcweir case NF_SYMBOLTYPE_STRING : 4299cdf0e10cSrcweir if( bDontQuote ) 4300cdf0e10cSrcweir aStr += pStr[j]; 4301cdf0e10cSrcweir else if ( pStr[j].Len() == 1 ) 4302cdf0e10cSrcweir { 4303cdf0e10cSrcweir aStr += '\\'; 4304cdf0e10cSrcweir aStr += pStr[j]; 4305cdf0e10cSrcweir } 4306cdf0e10cSrcweir else 4307cdf0e10cSrcweir { 4308cdf0e10cSrcweir aStr += '"'; 4309cdf0e10cSrcweir aStr += pStr[j]; 4310cdf0e10cSrcweir aStr += '"'; 4311cdf0e10cSrcweir } 4312cdf0e10cSrcweir break; 4313cdf0e10cSrcweir default: 4314cdf0e10cSrcweir aStr += pStr[j]; 4315cdf0e10cSrcweir } 4316cdf0e10cSrcweir 4317cdf0e10cSrcweir } 4318cdf0e10cSrcweir } 4319cdf0e10cSrcweir } 4320cdf0e10cSrcweir } 4321cdf0e10cSrcweir for ( ; nSub<4 && bDefault[nSub]; ++nSub ) 4322cdf0e10cSrcweir { // append empty subformats 4323cdf0e10cSrcweir aStr += ';'; 4324cdf0e10cSrcweir } 4325cdf0e10cSrcweir return aStr; 4326cdf0e10cSrcweir } 4327cdf0e10cSrcweir 4328cdf0e10cSrcweir 4329cdf0e10cSrcweir String SvNumberformat::ImpGetNatNumString( const SvNumberNatNum& rNum, 4330cdf0e10cSrcweir sal_Int32 nVal, sal_uInt16 nMinDigits ) const 4331cdf0e10cSrcweir { 4332cdf0e10cSrcweir String aStr; 4333cdf0e10cSrcweir if ( nMinDigits ) 4334cdf0e10cSrcweir { 4335cdf0e10cSrcweir if ( nMinDigits == 2 ) 4336cdf0e10cSrcweir { // speed up the most common case 4337cdf0e10cSrcweir if ( 0 <= nVal && nVal < 10 ) 4338cdf0e10cSrcweir { 4339cdf0e10cSrcweir sal_Unicode* p = aStr.AllocBuffer( 2 ); 4340cdf0e10cSrcweir *p++ = '0'; 4341cdf0e10cSrcweir *p = sal_Unicode( '0' + nVal ); 4342cdf0e10cSrcweir } 4343cdf0e10cSrcweir else 4344cdf0e10cSrcweir aStr = String::CreateFromInt32( nVal ); 4345cdf0e10cSrcweir } 4346cdf0e10cSrcweir else 4347cdf0e10cSrcweir { 4348cdf0e10cSrcweir String aValStr( String::CreateFromInt32( nVal ) ); 4349cdf0e10cSrcweir if ( aValStr.Len() >= nMinDigits ) 4350cdf0e10cSrcweir aStr = aValStr; 4351cdf0e10cSrcweir else 4352cdf0e10cSrcweir { 4353cdf0e10cSrcweir aStr.Fill( nMinDigits - aValStr.Len(), '0' ); 4354cdf0e10cSrcweir aStr += aValStr; 4355cdf0e10cSrcweir } 4356cdf0e10cSrcweir } 4357cdf0e10cSrcweir } 4358cdf0e10cSrcweir else 4359cdf0e10cSrcweir aStr = String::CreateFromInt32( nVal ); 4360cdf0e10cSrcweir ImpTransliterate( aStr, rNum ); 4361cdf0e10cSrcweir return aStr; 4362cdf0e10cSrcweir } 4363cdf0e10cSrcweir 4364cdf0e10cSrcweir 4365cdf0e10cSrcweir void SvNumberformat::ImpTransliterateImpl( String& rStr, 4366cdf0e10cSrcweir const SvNumberNatNum& rNum ) const 4367cdf0e10cSrcweir { 4368cdf0e10cSrcweir com::sun::star::lang::Locale aLocale( 4369cdf0e10cSrcweir MsLangId::convertLanguageToLocale( rNum.GetLang() ) ); 4370cdf0e10cSrcweir rStr = GetFormatter().GetNatNum()->getNativeNumberString( rStr, 4371cdf0e10cSrcweir aLocale, rNum.GetNatNum() ); 4372cdf0e10cSrcweir } 4373cdf0e10cSrcweir 4374cdf0e10cSrcweir 4375cdf0e10cSrcweir void SvNumberformat::GetNatNumXml( 4376cdf0e10cSrcweir com::sun::star::i18n::NativeNumberXmlAttributes& rAttr, 4377cdf0e10cSrcweir sal_uInt16 nNumFor ) const 4378cdf0e10cSrcweir { 4379cdf0e10cSrcweir if ( nNumFor <= 3 ) 4380cdf0e10cSrcweir { 4381cdf0e10cSrcweir const SvNumberNatNum& rNum = NumFor[nNumFor].GetNatNum(); 4382cdf0e10cSrcweir if ( rNum.IsSet() ) 4383cdf0e10cSrcweir { 4384cdf0e10cSrcweir com::sun::star::lang::Locale aLocale( 4385cdf0e10cSrcweir MsLangId::convertLanguageToLocale( rNum.GetLang() ) ); 4386cdf0e10cSrcweir rAttr = GetFormatter().GetNatNum()->convertToXmlAttributes( 4387cdf0e10cSrcweir aLocale, rNum.GetNatNum() ); 4388cdf0e10cSrcweir } 4389cdf0e10cSrcweir else 4390cdf0e10cSrcweir rAttr = com::sun::star::i18n::NativeNumberXmlAttributes(); 4391cdf0e10cSrcweir } 4392cdf0e10cSrcweir else 4393cdf0e10cSrcweir rAttr = com::sun::star::i18n::NativeNumberXmlAttributes(); 4394cdf0e10cSrcweir } 4395cdf0e10cSrcweir 4396cdf0e10cSrcweir // static 4397cdf0e10cSrcweir sal_Bool SvNumberformat::HasStringNegativeSign( const String& rStr ) 4398cdf0e10cSrcweir { 4399cdf0e10cSrcweir // fuer Sign muss '-' am Anfang oder am Ende des TeilStrings sein (Blanks ignored) 4400cdf0e10cSrcweir xub_StrLen nLen = rStr.Len(); 4401cdf0e10cSrcweir if ( !nLen ) 4402cdf0e10cSrcweir return sal_False; 4403cdf0e10cSrcweir const sal_Unicode* const pBeg = rStr.GetBuffer(); 4404cdf0e10cSrcweir const sal_Unicode* const pEnd = pBeg + nLen; 4405cdf0e10cSrcweir register const sal_Unicode* p = pBeg; 4406cdf0e10cSrcweir do 4407cdf0e10cSrcweir { // Anfang 4408cdf0e10cSrcweir if ( *p == '-' ) 4409cdf0e10cSrcweir return sal_True; 4410cdf0e10cSrcweir } while ( *p == ' ' && ++p < pEnd ); 4411cdf0e10cSrcweir p = pEnd - 1; 4412cdf0e10cSrcweir do 4413cdf0e10cSrcweir { // Ende 4414cdf0e10cSrcweir if ( *p == '-' ) 4415cdf0e10cSrcweir return sal_True; 4416cdf0e10cSrcweir } while ( *p == ' ' && pBeg < --p ); 4417cdf0e10cSrcweir return sal_False; 4418cdf0e10cSrcweir } 4419cdf0e10cSrcweir 4420cdf0e10cSrcweir 4421cdf0e10cSrcweir // static 4422cdf0e10cSrcweir void SvNumberformat::SetComment( const String& rStr, String& rFormat, 4423cdf0e10cSrcweir String& rComment ) 4424cdf0e10cSrcweir { 4425cdf0e10cSrcweir if ( rComment.Len() ) 4426cdf0e10cSrcweir { // alten Kommentar aus Formatstring loeschen 4427cdf0e10cSrcweir //! nicht per EraseComment, der Kommentar muss matchen 4428cdf0e10cSrcweir String aTmp( '{' ); 4429cdf0e10cSrcweir aTmp += ' '; 4430cdf0e10cSrcweir aTmp += rComment; 4431cdf0e10cSrcweir aTmp += ' '; 4432cdf0e10cSrcweir aTmp += '}'; 4433cdf0e10cSrcweir xub_StrLen nCom = 0; 4434cdf0e10cSrcweir do 4435cdf0e10cSrcweir { 4436cdf0e10cSrcweir nCom = rFormat.Search( aTmp, nCom ); 4437cdf0e10cSrcweir } while ( (nCom != STRING_NOTFOUND) && (nCom + aTmp.Len() != rFormat.Len()) ); 4438cdf0e10cSrcweir if ( nCom != STRING_NOTFOUND ) 4439cdf0e10cSrcweir rFormat.Erase( nCom ); 4440cdf0e10cSrcweir } 4441cdf0e10cSrcweir if ( rStr.Len() ) 4442cdf0e10cSrcweir { // neuen Kommentar setzen 4443cdf0e10cSrcweir rFormat += '{'; 4444cdf0e10cSrcweir rFormat += ' '; 4445cdf0e10cSrcweir rFormat += rStr; 4446cdf0e10cSrcweir rFormat += ' '; 4447cdf0e10cSrcweir rFormat += '}'; 4448cdf0e10cSrcweir rComment = rStr; 4449cdf0e10cSrcweir } 4450cdf0e10cSrcweir } 4451cdf0e10cSrcweir 4452cdf0e10cSrcweir 4453cdf0e10cSrcweir // static 4454cdf0e10cSrcweir void SvNumberformat::EraseCommentBraces( String& rStr ) 4455cdf0e10cSrcweir { 4456cdf0e10cSrcweir xub_StrLen nLen = rStr.Len(); 4457cdf0e10cSrcweir if ( nLen && rStr.GetChar(0) == '{' ) 4458cdf0e10cSrcweir { 4459cdf0e10cSrcweir rStr.Erase( 0, 1 ); 4460cdf0e10cSrcweir --nLen; 4461cdf0e10cSrcweir } 4462cdf0e10cSrcweir if ( nLen && rStr.GetChar(0) == ' ' ) 4463cdf0e10cSrcweir { 4464cdf0e10cSrcweir rStr.Erase( 0, 1 ); 4465cdf0e10cSrcweir --nLen; 4466cdf0e10cSrcweir } 4467cdf0e10cSrcweir if ( nLen && rStr.GetChar( nLen-1 ) == '}' ) 4468cdf0e10cSrcweir rStr.Erase( --nLen, 1 ); 4469cdf0e10cSrcweir if ( nLen && rStr.GetChar( nLen-1 ) == ' ' ) 4470cdf0e10cSrcweir rStr.Erase( --nLen, 1 ); 4471cdf0e10cSrcweir } 4472cdf0e10cSrcweir 4473cdf0e10cSrcweir 4474cdf0e10cSrcweir // static 4475cdf0e10cSrcweir void SvNumberformat::EraseComment( String& rStr ) 4476cdf0e10cSrcweir { 4477cdf0e10cSrcweir register const sal_Unicode* p = rStr.GetBuffer(); 4478cdf0e10cSrcweir sal_Bool bInString = sal_False; 4479cdf0e10cSrcweir sal_Bool bEscaped = sal_False; 4480cdf0e10cSrcweir sal_Bool bFound = sal_False; 4481cdf0e10cSrcweir xub_StrLen nPos = 0; 4482cdf0e10cSrcweir while ( !bFound && *p ) 4483cdf0e10cSrcweir { 4484cdf0e10cSrcweir switch ( *p ) 4485cdf0e10cSrcweir { 4486cdf0e10cSrcweir case '\\' : 4487cdf0e10cSrcweir bEscaped = !bEscaped; 4488cdf0e10cSrcweir break; 4489cdf0e10cSrcweir case '\"' : 4490cdf0e10cSrcweir if ( !bEscaped ) 4491cdf0e10cSrcweir bInString = !bInString; 4492cdf0e10cSrcweir break; 4493cdf0e10cSrcweir case '{' : 4494cdf0e10cSrcweir if ( !bEscaped && !bInString ) 4495cdf0e10cSrcweir { 4496cdf0e10cSrcweir bFound = sal_True; 4497cdf0e10cSrcweir nPos = sal::static_int_cast< xub_StrLen >( 4498cdf0e10cSrcweir p - rStr.GetBuffer()); 4499cdf0e10cSrcweir } 4500cdf0e10cSrcweir break; 4501cdf0e10cSrcweir } 4502cdf0e10cSrcweir if ( bEscaped && *p != '\\' ) 4503cdf0e10cSrcweir bEscaped = sal_False; 4504cdf0e10cSrcweir ++p; 4505cdf0e10cSrcweir } 4506cdf0e10cSrcweir if ( bFound ) 4507cdf0e10cSrcweir rStr.Erase( nPos ); 4508cdf0e10cSrcweir } 4509cdf0e10cSrcweir 4510cdf0e10cSrcweir 4511cdf0e10cSrcweir // static 4512cdf0e10cSrcweir sal_Bool SvNumberformat::IsInQuote( const String& rStr, xub_StrLen nPos, 4513cdf0e10cSrcweir sal_Unicode cQuote, sal_Unicode cEscIn, sal_Unicode cEscOut ) 4514cdf0e10cSrcweir { 4515cdf0e10cSrcweir xub_StrLen nLen = rStr.Len(); 4516cdf0e10cSrcweir if ( nPos >= nLen ) 4517cdf0e10cSrcweir return sal_False; 4518cdf0e10cSrcweir register const sal_Unicode* p0 = rStr.GetBuffer(); 4519cdf0e10cSrcweir register const sal_Unicode* p = p0; 4520cdf0e10cSrcweir register const sal_Unicode* p1 = p0 + nPos; 4521cdf0e10cSrcweir sal_Bool bQuoted = sal_False; 4522cdf0e10cSrcweir while ( p <= p1 ) 4523cdf0e10cSrcweir { 4524cdf0e10cSrcweir if ( *p == cQuote ) 4525cdf0e10cSrcweir { 4526cdf0e10cSrcweir if ( p == p0 ) 4527cdf0e10cSrcweir bQuoted = sal_True; 4528cdf0e10cSrcweir else if ( bQuoted ) 4529cdf0e10cSrcweir { 4530cdf0e10cSrcweir if ( *(p-1) != cEscIn ) 4531cdf0e10cSrcweir bQuoted = sal_False; 4532cdf0e10cSrcweir } 4533cdf0e10cSrcweir else 4534cdf0e10cSrcweir { 4535cdf0e10cSrcweir if ( *(p-1) != cEscOut ) 4536cdf0e10cSrcweir bQuoted = sal_True; 4537cdf0e10cSrcweir } 4538cdf0e10cSrcweir } 4539cdf0e10cSrcweir p++; 4540cdf0e10cSrcweir } 4541cdf0e10cSrcweir return bQuoted; 4542cdf0e10cSrcweir } 4543cdf0e10cSrcweir 4544cdf0e10cSrcweir 4545cdf0e10cSrcweir // static 4546cdf0e10cSrcweir xub_StrLen SvNumberformat::GetQuoteEnd( const String& rStr, xub_StrLen nPos, 4547cdf0e10cSrcweir sal_Unicode cQuote, sal_Unicode cEscIn, sal_Unicode cEscOut ) 4548cdf0e10cSrcweir { 4549cdf0e10cSrcweir xub_StrLen nLen = rStr.Len(); 4550cdf0e10cSrcweir if ( nPos >= nLen ) 4551cdf0e10cSrcweir return STRING_NOTFOUND; 4552cdf0e10cSrcweir if ( !IsInQuote( rStr, nPos, cQuote, cEscIn, cEscOut ) ) 4553cdf0e10cSrcweir { 4554cdf0e10cSrcweir if ( rStr.GetChar( nPos ) == cQuote ) 4555cdf0e10cSrcweir return nPos; // schliessendes cQuote 4556cdf0e10cSrcweir return STRING_NOTFOUND; 4557cdf0e10cSrcweir } 4558cdf0e10cSrcweir register const sal_Unicode* p0 = rStr.GetBuffer(); 4559cdf0e10cSrcweir register const sal_Unicode* p = p0 + nPos; 4560cdf0e10cSrcweir register const sal_Unicode* p1 = p0 + nLen; 4561cdf0e10cSrcweir while ( p < p1 ) 4562cdf0e10cSrcweir { 4563cdf0e10cSrcweir if ( *p == cQuote && p > p0 && *(p-1) != cEscIn ) 4564cdf0e10cSrcweir return sal::static_int_cast< xub_StrLen >(p - p0); 4565cdf0e10cSrcweir p++; 4566cdf0e10cSrcweir } 4567cdf0e10cSrcweir return nLen; // String Ende 4568cdf0e10cSrcweir } 4569cdf0e10cSrcweir 4570cdf0e10cSrcweir 4571cdf0e10cSrcweir sal_uInt16 SvNumberformat::ImpGetNumForStringElementCount( sal_uInt16 nNumFor ) const 4572cdf0e10cSrcweir { 4573cdf0e10cSrcweir sal_uInt16 nCnt = 0; 4574cdf0e10cSrcweir sal_uInt16 nAnz = NumFor[nNumFor].GetnAnz(); 4575cdf0e10cSrcweir short const * const pType = NumFor[nNumFor].Info().nTypeArray; 4576cdf0e10cSrcweir for ( sal_uInt16 j=0; j<nAnz; ++j ) 4577cdf0e10cSrcweir { 4578cdf0e10cSrcweir switch ( pType[j] ) 4579cdf0e10cSrcweir { 4580cdf0e10cSrcweir case NF_SYMBOLTYPE_STRING: 4581cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRENCY: 4582cdf0e10cSrcweir case NF_SYMBOLTYPE_DATESEP: 4583cdf0e10cSrcweir case NF_SYMBOLTYPE_TIMESEP: 4584cdf0e10cSrcweir case NF_SYMBOLTYPE_TIME100SECSEP: 4585cdf0e10cSrcweir case NF_SYMBOLTYPE_PERCENT: 4586cdf0e10cSrcweir ++nCnt; 4587cdf0e10cSrcweir break; 4588cdf0e10cSrcweir } 4589cdf0e10cSrcweir } 4590cdf0e10cSrcweir return nCnt; 4591cdf0e10cSrcweir } 4592cdf0e10cSrcweir 4593