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 1137*158531faSWang Lei sal_Bool IsSingleSymbol(String& rString, xub_StrLen nPos){ 1138*158531faSWang Lei sal_Bool ret = sal_False; 1139*158531faSWang Lei while(nPos > 0){ 1140*158531faSWang Lei if(rString.GetChar(nPos) == '*' || rString.GetChar(nPos) == '\\' || rString.GetChar(nPos) == '_'){ 1141*158531faSWang Lei ret = !ret; 1142*158531faSWang Lei nPos--; 1143*158531faSWang Lei } 1144*158531faSWang Lei else 1145*158531faSWang Lei return ret; 1146*158531faSWang Lei } 1147*158531faSWang Lei return ret; 1148*158531faSWang Lei } 1149cdf0e10cSrcweir 1150cdf0e10cSrcweir short SvNumberformat::ImpNextSymbol(String& rString, 1151cdf0e10cSrcweir xub_StrLen& nPos, 1152cdf0e10cSrcweir String& sSymbol) 1153cdf0e10cSrcweir { 1154cdf0e10cSrcweir short eSymbolType = BRACKET_SYMBOLTYPE_FORMAT; 1155cdf0e10cSrcweir sal_Unicode cToken; 1156cdf0e10cSrcweir sal_Unicode cLetter = ' '; // Zwischenergebnis 1157cdf0e10cSrcweir xub_StrLen nLen = rString.Len(); 1158cdf0e10cSrcweir ScanState eState = SsStart; 1159cdf0e10cSrcweir sSymbol.Erase(); 1160cdf0e10cSrcweir const NfKeywordTable & rKeywords = rScan.GetKeywords(); 1161cdf0e10cSrcweir while (nPos < nLen && eState != SsStop) 1162cdf0e10cSrcweir { 1163cdf0e10cSrcweir cToken = rString.GetChar(nPos); 1164cdf0e10cSrcweir nPos++; 1165cdf0e10cSrcweir switch (eState) 1166cdf0e10cSrcweir { 1167cdf0e10cSrcweir case SsStart: 1168cdf0e10cSrcweir { 1169cdf0e10cSrcweir if (cToken == '[') 1170cdf0e10cSrcweir { 1171cdf0e10cSrcweir eState = SsGetBracketed; 1172cdf0e10cSrcweir sSymbol += cToken; 1173cdf0e10cSrcweir } 1174cdf0e10cSrcweir else if (cToken == ';') 1175cdf0e10cSrcweir { 1176cdf0e10cSrcweir eState = SsGetString; 1177cdf0e10cSrcweir nPos--; 1178cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_FORMAT; 1179cdf0e10cSrcweir } 1180cdf0e10cSrcweir else if (cToken == ']') 1181cdf0e10cSrcweir { 1182cdf0e10cSrcweir eState = SsStop; 1183cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_ERROR; 1184cdf0e10cSrcweir } 1185cdf0e10cSrcweir else if (cToken == ' ') // Skip Blanks 1186cdf0e10cSrcweir { 1187cdf0e10cSrcweir rString.Erase(nPos-1,1); 1188cdf0e10cSrcweir nPos--; 1189cdf0e10cSrcweir nLen--; 1190cdf0e10cSrcweir } 1191cdf0e10cSrcweir else 1192cdf0e10cSrcweir { 1193cdf0e10cSrcweir sSymbol += cToken; 1194cdf0e10cSrcweir eState = SsGetString; 1195cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_FORMAT; 1196cdf0e10cSrcweir } 1197cdf0e10cSrcweir } 1198cdf0e10cSrcweir break; 1199cdf0e10cSrcweir case SsGetBracketed: 1200cdf0e10cSrcweir { 1201cdf0e10cSrcweir switch (cToken) 1202cdf0e10cSrcweir { 1203cdf0e10cSrcweir case '<': 1204cdf0e10cSrcweir case '>': 1205cdf0e10cSrcweir case '=': 1206cdf0e10cSrcweir { 1207cdf0e10cSrcweir sSymbol.EraseAllChars('['); 1208cdf0e10cSrcweir sSymbol += cToken; 1209cdf0e10cSrcweir cLetter = cToken; 1210cdf0e10cSrcweir eState = SsGetCon; 1211cdf0e10cSrcweir switch (cToken) 1212cdf0e10cSrcweir { 1213cdf0e10cSrcweir case '<': eSymbolType = NUMBERFORMAT_OP_LT; break; 1214cdf0e10cSrcweir case '>': eSymbolType = NUMBERFORMAT_OP_GT; break; 1215cdf0e10cSrcweir case '=': eSymbolType = NUMBERFORMAT_OP_EQ; break; 1216cdf0e10cSrcweir default: break; 1217cdf0e10cSrcweir } 1218cdf0e10cSrcweir } 1219cdf0e10cSrcweir break; 1220cdf0e10cSrcweir case ' ': 1221cdf0e10cSrcweir { 1222cdf0e10cSrcweir rString.Erase(nPos-1,1); 1223cdf0e10cSrcweir nPos--; 1224cdf0e10cSrcweir nLen--; 1225cdf0e10cSrcweir } 1226cdf0e10cSrcweir break; 1227cdf0e10cSrcweir case '$' : 1228cdf0e10cSrcweir { 1229cdf0e10cSrcweir if ( rString.GetChar(nPos) == '-' ) 1230cdf0e10cSrcweir { // [$-xxx] locale 1231cdf0e10cSrcweir sSymbol.EraseAllChars('['); 1232cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_LOCALE; 1233cdf0e10cSrcweir eState = SsGetPrefix; 1234cdf0e10cSrcweir } 1235cdf0e10cSrcweir else 1236cdf0e10cSrcweir { // currency as of SV_NUMBERFORMATTER_VERSION_NEW_CURR 1237cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_FORMAT; 1238cdf0e10cSrcweir eState = SsGetString; 1239cdf0e10cSrcweir } 1240cdf0e10cSrcweir sSymbol += cToken; 1241cdf0e10cSrcweir } 1242cdf0e10cSrcweir break; 1243cdf0e10cSrcweir case '~' : 1244cdf0e10cSrcweir { // calendarID as of SV_NUMBERFORMATTER_VERSION_CALENDAR 1245cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_FORMAT; 1246cdf0e10cSrcweir sSymbol += cToken; 1247cdf0e10cSrcweir eState = SsGetString; 1248cdf0e10cSrcweir } 1249cdf0e10cSrcweir break; 1250cdf0e10cSrcweir default: 1251cdf0e10cSrcweir { 1252cdf0e10cSrcweir static const String aNatNum( RTL_CONSTASCII_USTRINGPARAM( "NATNUM" ) ); 1253cdf0e10cSrcweir static const String aDBNum( RTL_CONSTASCII_USTRINGPARAM( "DBNUM" ) ); 1254cdf0e10cSrcweir String aUpperNatNum( rChrCls().toUpper( rString, nPos-1, aNatNum.Len() ) ); 1255cdf0e10cSrcweir String aUpperDBNum( rChrCls().toUpper( rString, nPos-1, aDBNum.Len() ) ); 1256cdf0e10cSrcweir sal_Unicode cUpper = aUpperNatNum.GetChar(0); 1257cdf0e10cSrcweir sal_Int32 nNatNumNum = rString.Copy( nPos-1+aNatNum.Len() ).ToInt32(); 1258cdf0e10cSrcweir sal_Unicode cDBNum = rString.GetChar( nPos-1+aDBNum.Len() ); 1259cdf0e10cSrcweir if ( aUpperNatNum == aNatNum && 0 <= nNatNumNum && nNatNumNum <= 19 ) 1260cdf0e10cSrcweir { 1261cdf0e10cSrcweir sSymbol.EraseAllChars('['); 1262cdf0e10cSrcweir sSymbol += rString.Copy( --nPos, aNatNum.Len()+1 ); 1263cdf0e10cSrcweir nPos += aNatNum.Len()+1; 1264cdf0e10cSrcweir //! SymbolType is negative 1265cdf0e10cSrcweir eSymbolType = (short) (BRACKET_SYMBOLTYPE_NATNUM0 - nNatNumNum); 1266cdf0e10cSrcweir eState = SsGetPrefix; 1267cdf0e10cSrcweir } 1268cdf0e10cSrcweir else if ( aUpperDBNum == aDBNum && '1' <= cDBNum && cDBNum <= '9' ) 1269cdf0e10cSrcweir { 1270cdf0e10cSrcweir sSymbol.EraseAllChars('['); 1271cdf0e10cSrcweir sSymbol += rString.Copy( --nPos, aDBNum.Len()+1 ); 1272cdf0e10cSrcweir nPos += aDBNum.Len()+1; 1273cdf0e10cSrcweir //! SymbolType is negative 1274cdf0e10cSrcweir eSymbolType = sal::static_int_cast< short >( 1275cdf0e10cSrcweir BRACKET_SYMBOLTYPE_DBNUM1 - (cDBNum - '1')); 1276cdf0e10cSrcweir eState = SsGetPrefix; 1277cdf0e10cSrcweir } 1278cdf0e10cSrcweir else if (cUpper == rKeywords[NF_KEY_H].GetChar(0) || // H 1279cdf0e10cSrcweir cUpper == rKeywords[NF_KEY_MI].GetChar(0) || // M 1280cdf0e10cSrcweir cUpper == rKeywords[NF_KEY_S].GetChar(0) ) // S 1281cdf0e10cSrcweir { 1282cdf0e10cSrcweir sSymbol += cToken; 1283cdf0e10cSrcweir eState = SsGetTime; 1284cdf0e10cSrcweir cLetter = cToken; 1285cdf0e10cSrcweir } 1286cdf0e10cSrcweir else 1287cdf0e10cSrcweir { 1288cdf0e10cSrcweir sSymbol.EraseAllChars('['); 1289cdf0e10cSrcweir sSymbol += cToken; 1290cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_COLOR; 1291cdf0e10cSrcweir eState = SsGetPrefix; 1292cdf0e10cSrcweir } 1293cdf0e10cSrcweir } 1294cdf0e10cSrcweir break; 1295cdf0e10cSrcweir } 1296cdf0e10cSrcweir } 1297cdf0e10cSrcweir break; 1298cdf0e10cSrcweir case SsGetString: 1299cdf0e10cSrcweir { 1300*158531faSWang Lei if (cToken == ';' && !IsSingleSymbol(rString, nPos-2)) 1301*158531faSWang Lei { 1302cdf0e10cSrcweir eState = SsStop; 1303*158531faSWang Lei } 1304cdf0e10cSrcweir else 1305cdf0e10cSrcweir sSymbol += cToken; 1306cdf0e10cSrcweir } 1307cdf0e10cSrcweir break; 1308cdf0e10cSrcweir case SsGetTime: 1309cdf0e10cSrcweir { 1310cdf0e10cSrcweir if (cToken == ']') 1311cdf0e10cSrcweir { 1312cdf0e10cSrcweir sSymbol += cToken; 1313cdf0e10cSrcweir eState = SsGetString; 1314cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_FORMAT; 1315cdf0e10cSrcweir } 1316cdf0e10cSrcweir else 1317cdf0e10cSrcweir { 1318cdf0e10cSrcweir sal_Unicode cUpper = rChrCls().toUpper( rString, nPos-1, 1 ).GetChar(0); 1319cdf0e10cSrcweir if (cUpper == rKeywords[NF_KEY_H].GetChar(0) || // H 1320cdf0e10cSrcweir cUpper == rKeywords[NF_KEY_MI].GetChar(0) || // M 1321cdf0e10cSrcweir cUpper == rKeywords[NF_KEY_S].GetChar(0) ) // S 1322cdf0e10cSrcweir { 1323cdf0e10cSrcweir if (cLetter == cToken) 1324cdf0e10cSrcweir { 1325cdf0e10cSrcweir sSymbol += cToken; 1326cdf0e10cSrcweir cLetter = ' '; 1327cdf0e10cSrcweir } 1328cdf0e10cSrcweir else 1329cdf0e10cSrcweir { 1330cdf0e10cSrcweir sSymbol.EraseAllChars('['); 1331cdf0e10cSrcweir sSymbol += cToken; 1332cdf0e10cSrcweir eState = SsGetPrefix; 1333cdf0e10cSrcweir } 1334cdf0e10cSrcweir } 1335cdf0e10cSrcweir else 1336cdf0e10cSrcweir { 1337cdf0e10cSrcweir sSymbol.EraseAllChars('['); 1338cdf0e10cSrcweir sSymbol += cToken; 1339cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_COLOR; 1340cdf0e10cSrcweir eState = SsGetPrefix; 1341cdf0e10cSrcweir } 1342cdf0e10cSrcweir } 1343cdf0e10cSrcweir } 1344cdf0e10cSrcweir break; 1345cdf0e10cSrcweir case SsGetCon: 1346cdf0e10cSrcweir { 1347cdf0e10cSrcweir switch (cToken) 1348cdf0e10cSrcweir { 1349cdf0e10cSrcweir case '<': 1350cdf0e10cSrcweir { 1351cdf0e10cSrcweir eState = SsStop; 1352cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_ERROR; 1353cdf0e10cSrcweir } 1354cdf0e10cSrcweir break; 1355cdf0e10cSrcweir case '>': 1356cdf0e10cSrcweir { 1357cdf0e10cSrcweir if (cLetter == '<') 1358cdf0e10cSrcweir { 1359cdf0e10cSrcweir sSymbol += cToken; 1360cdf0e10cSrcweir cLetter = ' '; 1361cdf0e10cSrcweir eState = SsStop; 1362cdf0e10cSrcweir eSymbolType = NUMBERFORMAT_OP_NE; 1363cdf0e10cSrcweir } 1364cdf0e10cSrcweir else 1365cdf0e10cSrcweir { 1366cdf0e10cSrcweir eState = SsStop; 1367cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_ERROR; 1368cdf0e10cSrcweir } 1369cdf0e10cSrcweir } 1370cdf0e10cSrcweir break; 1371cdf0e10cSrcweir case '=': 1372cdf0e10cSrcweir { 1373cdf0e10cSrcweir if (cLetter == '<') 1374cdf0e10cSrcweir { 1375cdf0e10cSrcweir sSymbol += cToken; 1376cdf0e10cSrcweir cLetter = ' '; 1377cdf0e10cSrcweir eSymbolType = NUMBERFORMAT_OP_LE; 1378cdf0e10cSrcweir } 1379cdf0e10cSrcweir else if (cLetter == '>') 1380cdf0e10cSrcweir { 1381cdf0e10cSrcweir sSymbol += cToken; 1382cdf0e10cSrcweir cLetter = ' '; 1383cdf0e10cSrcweir eSymbolType = NUMBERFORMAT_OP_GE; 1384cdf0e10cSrcweir } 1385cdf0e10cSrcweir else 1386cdf0e10cSrcweir { 1387cdf0e10cSrcweir eState = SsStop; 1388cdf0e10cSrcweir eSymbolType = BRACKET_SYMBOLTYPE_ERROR; 1389cdf0e10cSrcweir } 1390cdf0e10cSrcweir } 1391cdf0e10cSrcweir break; 1392cdf0e10cSrcweir case ' ': 1393cdf0e10cSrcweir { 1394cdf0e10cSrcweir rString.Erase(nPos-1,1); 1395cdf0e10cSrcweir nPos--; 1396cdf0e10cSrcweir nLen--; 1397cdf0e10cSrcweir } 1398cdf0e10cSrcweir break; 1399cdf0e10cSrcweir default: 1400cdf0e10cSrcweir { 1401cdf0e10cSrcweir eState = SsStop; 1402cdf0e10cSrcweir nPos--; 1403cdf0e10cSrcweir } 1404cdf0e10cSrcweir break; 1405cdf0e10cSrcweir } 1406cdf0e10cSrcweir } 1407cdf0e10cSrcweir break; 1408cdf0e10cSrcweir case SsGetPrefix: 1409cdf0e10cSrcweir { 1410cdf0e10cSrcweir if (cToken == ']') 1411cdf0e10cSrcweir eState = SsStop; 1412cdf0e10cSrcweir else 1413cdf0e10cSrcweir sSymbol += cToken; 1414cdf0e10cSrcweir } 1415cdf0e10cSrcweir break; 1416cdf0e10cSrcweir default: 1417cdf0e10cSrcweir break; 1418cdf0e10cSrcweir } // of switch 1419cdf0e10cSrcweir } // of while 1420cdf0e10cSrcweir 1421cdf0e10cSrcweir return eSymbolType; 1422cdf0e10cSrcweir } 1423cdf0e10cSrcweir 1424cdf0e10cSrcweir NfHackConversion SvNumberformat::Load( SvStream& rStream, 1425cdf0e10cSrcweir ImpSvNumMultipleReadHeader& rHdr, SvNumberFormatter* pHackConverter, 1426cdf0e10cSrcweir ImpSvNumberInputScan& rISc ) 1427cdf0e10cSrcweir { 1428cdf0e10cSrcweir rHdr.StartEntry(); 1429cdf0e10cSrcweir sal_uInt16 nOp1, nOp2; 1430cdf0e10cSrcweir SvNumberformat::LoadString( rStream, sFormatstring ); 1431cdf0e10cSrcweir rStream >> eType >> fLimit1 >> fLimit2 1432cdf0e10cSrcweir >> nOp1 >> nOp2 >> bStandard >> bIsUsed; 1433cdf0e10cSrcweir NfHackConversion eHackConversion = NF_CONVERT_NONE; 1434cdf0e10cSrcweir sal_Bool bOldConvert = sal_False; 1435cdf0e10cSrcweir LanguageType eOldTmpLang = 0; 1436cdf0e10cSrcweir LanguageType eOldNewLang = 0; 1437cdf0e10cSrcweir if ( pHackConverter ) 1438cdf0e10cSrcweir { // werden nur hierbei gebraucht 1439cdf0e10cSrcweir bOldConvert = rScan.GetConvertMode(); 1440cdf0e10cSrcweir eOldTmpLang = rScan.GetTmpLnge(); 1441cdf0e10cSrcweir eOldNewLang = rScan.GetNewLnge(); 1442cdf0e10cSrcweir } 1443cdf0e10cSrcweir String aLoadedColorName; 1444cdf0e10cSrcweir for (sal_uInt16 i = 0; i < 4; i++) 1445cdf0e10cSrcweir { 1446cdf0e10cSrcweir NumFor[i].Load( rStream, rScan, aLoadedColorName ); 1447cdf0e10cSrcweir if ( pHackConverter && eHackConversion == NF_CONVERT_NONE ) 1448cdf0e10cSrcweir { 1449cdf0e10cSrcweir //! HACK! ER 29.07.97 13:52 1450cdf0e10cSrcweir // leider wurde nicht gespeichert, was SYSTEM on Save wirklich war :-/ 1451cdf0e10cSrcweir // aber immerhin wird manchmal fuer einen Entry FARBE oder COLOR gespeichert.. 1452cdf0e10cSrcweir // System-German FARBE nach System-xxx COLOR umsetzen und vice versa, 1453cdf0e10cSrcweir //! geht davon aus, dass onSave nur GERMAN und ENGLISH KeyWords in 1454cdf0e10cSrcweir //! ImpSvNumberformatScan existierten 1455cdf0e10cSrcweir if ( aLoadedColorName.Len() && !NumFor[i].GetColor() 1456cdf0e10cSrcweir && aLoadedColorName != rScan.GetColorString() ) 1457cdf0e10cSrcweir { 1458cdf0e10cSrcweir if ( rScan.GetColorString().EqualsAscii( "FARBE" ) ) 1459cdf0e10cSrcweir { // English -> German 1460cdf0e10cSrcweir eHackConversion = NF_CONVERT_ENGLISH_GERMAN; 1461cdf0e10cSrcweir rScan.GetNumberformatter()->ChangeIntl( LANGUAGE_ENGLISH_US ); 1462cdf0e10cSrcweir rScan.SetConvertMode( LANGUAGE_ENGLISH_US, LANGUAGE_GERMAN ); 1463cdf0e10cSrcweir } 1464cdf0e10cSrcweir else 1465cdf0e10cSrcweir { // German -> English 1466cdf0e10cSrcweir eHackConversion = NF_CONVERT_GERMAN_ENGLISH; 1467cdf0e10cSrcweir rScan.GetNumberformatter()->ChangeIntl( LANGUAGE_GERMAN ); 1468cdf0e10cSrcweir rScan.SetConvertMode( LANGUAGE_GERMAN, LANGUAGE_ENGLISH_US ); 1469cdf0e10cSrcweir } 1470cdf0e10cSrcweir String aColorName = NumFor[i].GetColorName(); 1471cdf0e10cSrcweir const Color* pColor = rScan.GetColor( aColorName ); 1472cdf0e10cSrcweir if ( !pColor && aLoadedColorName == aColorName ) 1473cdf0e10cSrcweir eHackConversion = NF_CONVERT_NONE; 1474cdf0e10cSrcweir rScan.GetNumberformatter()->ChangeIntl( LANGUAGE_SYSTEM ); 1475cdf0e10cSrcweir rScan.SetConvertMode( eOldTmpLang, eOldNewLang ); 1476cdf0e10cSrcweir rScan.SetConvertMode( bOldConvert ); 1477cdf0e10cSrcweir } 1478cdf0e10cSrcweir } 1479cdf0e10cSrcweir } 1480cdf0e10cSrcweir eOp1 = (SvNumberformatLimitOps) nOp1; 1481cdf0e10cSrcweir eOp2 = (SvNumberformatLimitOps) nOp2; 1482cdf0e10cSrcweir String aComment; // wird nach dem NewCurrency-Geraffel richtig gesetzt 1483cdf0e10cSrcweir if ( rHdr.BytesLeft() ) 1484cdf0e10cSrcweir { // ab SV_NUMBERFORMATTER_VERSION_NEWSTANDARD 1485cdf0e10cSrcweir SvNumberformat::LoadString( rStream, aComment ); 1486cdf0e10cSrcweir rStream >> nNewStandardDefined; 1487cdf0e10cSrcweir } 1488cdf0e10cSrcweir 1489cdf0e10cSrcweir xub_StrLen nNewCurrencyEnd = STRING_NOTFOUND; 1490cdf0e10cSrcweir sal_Bool bNewCurrencyComment = ( aComment.GetChar(0) == cNewCurrencyMagic && 1491cdf0e10cSrcweir (nNewCurrencyEnd = aComment.Search( cNewCurrencyMagic, 1 )) != STRING_NOTFOUND ); 1492cdf0e10cSrcweir sal_Bool bNewCurrencyLoaded = sal_False; 1493cdf0e10cSrcweir sal_Bool bNewCurrency = sal_False; 1494cdf0e10cSrcweir 1495cdf0e10cSrcweir sal_Bool bGoOn = sal_True; 1496cdf0e10cSrcweir while ( rHdr.BytesLeft() && bGoOn ) 1497cdf0e10cSrcweir { // as of SV_NUMBERFORMATTER_VERSION_NEW_CURR 1498cdf0e10cSrcweir sal_uInt16 nId; 1499cdf0e10cSrcweir rStream >> nId; 1500cdf0e10cSrcweir switch ( nId ) 1501cdf0e10cSrcweir { 1502cdf0e10cSrcweir case nNewCurrencyVersionId : 1503cdf0e10cSrcweir { 1504cdf0e10cSrcweir bNewCurrencyLoaded = sal_True; 1505cdf0e10cSrcweir rStream >> bNewCurrency; 1506cdf0e10cSrcweir if ( bNewCurrency ) 1507cdf0e10cSrcweir { 1508cdf0e10cSrcweir for ( sal_uInt16 j=0; j<4; j++ ) 1509cdf0e10cSrcweir { 1510cdf0e10cSrcweir NumFor[j].LoadNewCurrencyMap( rStream ); 1511cdf0e10cSrcweir } 1512cdf0e10cSrcweir } 1513cdf0e10cSrcweir } 1514cdf0e10cSrcweir break; 1515cdf0e10cSrcweir case nNewStandardFlagVersionId : 1516cdf0e10cSrcweir rStream >> bStandard; // the real standard flag 1517cdf0e10cSrcweir break; 1518cdf0e10cSrcweir default: 1519cdf0e10cSrcweir DBG_ERRORFILE( "SvNumberformat::Load: unknown header bytes left nId" ); 1520cdf0e10cSrcweir bGoOn = sal_False; // stop reading unknown stream left over of newer versions 1521cdf0e10cSrcweir // Would be nice to have multiple read/write headers instead 1522cdf0e10cSrcweir // but old versions wouldn't know it, TLOT. 1523cdf0e10cSrcweir } 1524cdf0e10cSrcweir } 1525cdf0e10cSrcweir rHdr.EndEntry(); 1526cdf0e10cSrcweir 1527cdf0e10cSrcweir if ( bNewCurrencyLoaded ) 1528cdf0e10cSrcweir { 1529cdf0e10cSrcweir if ( bNewCurrency && bNewCurrencyComment ) 1530cdf0e10cSrcweir { // original Formatstring und Kommentar wiederherstellen 1531cdf0e10cSrcweir sFormatstring = aComment.Copy( 1, nNewCurrencyEnd-1 ); 1532cdf0e10cSrcweir aComment.Erase( 0, nNewCurrencyEnd+1 ); 1533cdf0e10cSrcweir } 1534cdf0e10cSrcweir } 1535cdf0e10cSrcweir else if ( bNewCurrencyComment ) 1536cdf0e10cSrcweir { // neu, aber mit Version vor SV_NUMBERFORMATTER_VERSION_NEW_CURR gespeichert 1537cdf0e10cSrcweir // original Formatstring und Kommentar wiederherstellen 1538cdf0e10cSrcweir sFormatstring = aComment.Copy( 1, nNewCurrencyEnd-1 ); 1539cdf0e10cSrcweir aComment.Erase( 0, nNewCurrencyEnd+1 ); 1540cdf0e10cSrcweir // Zustaende merken 1541cdf0e10cSrcweir short nDefined = ( eType & NUMBERFORMAT_DEFINED ); 1542cdf0e10cSrcweir sal_uInt16 nNewStandard = nNewStandardDefined; 1543cdf0e10cSrcweir // neu parsen etc. 1544cdf0e10cSrcweir String aStr( sFormatstring ); 1545cdf0e10cSrcweir xub_StrLen nCheckPos = 0; 1546cdf0e10cSrcweir SvNumberformat* pFormat = new SvNumberformat( aStr, &rScan, &rISc, 1547cdf0e10cSrcweir nCheckPos, eLnge, bStandard ); 1548cdf0e10cSrcweir DBG_ASSERT( !nCheckPos, "SvNumberformat::Load: NewCurrencyRescan nCheckPos" ); 1549cdf0e10cSrcweir ImpCopyNumberformat( *pFormat ); 1550cdf0e10cSrcweir delete pFormat; 1551cdf0e10cSrcweir // Zustaende wiederherstellen 1552cdf0e10cSrcweir eType |= nDefined; 1553cdf0e10cSrcweir if ( nNewStandard ) 1554cdf0e10cSrcweir SetNewStandardDefined( nNewStandard ); 1555cdf0e10cSrcweir } 1556cdf0e10cSrcweir SetComment( aComment ); 1557cdf0e10cSrcweir 1558cdf0e10cSrcweir if ( eHackConversion != NF_CONVERT_NONE ) 1559cdf0e10cSrcweir { //! und weiter mit dem HACK! 1560cdf0e10cSrcweir switch ( eHackConversion ) 1561cdf0e10cSrcweir { 1562cdf0e10cSrcweir case NF_CONVERT_ENGLISH_GERMAN : 1563cdf0e10cSrcweir ConvertLanguage( *pHackConverter, 1564cdf0e10cSrcweir LANGUAGE_ENGLISH_US, LANGUAGE_GERMAN, sal_True ); 1565cdf0e10cSrcweir break; 1566cdf0e10cSrcweir case NF_CONVERT_GERMAN_ENGLISH : 1567cdf0e10cSrcweir ConvertLanguage( *pHackConverter, 1568cdf0e10cSrcweir LANGUAGE_GERMAN, LANGUAGE_ENGLISH_US, sal_True ); 1569cdf0e10cSrcweir break; 1570cdf0e10cSrcweir default: 1571cdf0e10cSrcweir DBG_ERRORFILE( "SvNumberformat::Load: eHackConversion unknown" ); 1572cdf0e10cSrcweir } 1573cdf0e10cSrcweir } 1574cdf0e10cSrcweir return eHackConversion; 1575cdf0e10cSrcweir } 1576cdf0e10cSrcweir 1577cdf0e10cSrcweir void SvNumberformat::ConvertLanguage( SvNumberFormatter& rConverter, 1578cdf0e10cSrcweir LanguageType eConvertFrom, LanguageType eConvertTo, sal_Bool bSystem ) 1579cdf0e10cSrcweir { 1580cdf0e10cSrcweir xub_StrLen nCheckPos; 1581cdf0e10cSrcweir sal_uInt32 nKey; 1582cdf0e10cSrcweir short nType = eType; 1583cdf0e10cSrcweir String aFormatString( sFormatstring ); 1584cdf0e10cSrcweir if ( bSystem ) 1585cdf0e10cSrcweir rConverter.PutandConvertEntrySystem( aFormatString, nCheckPos, nType, 1586cdf0e10cSrcweir nKey, eConvertFrom, eConvertTo ); 1587cdf0e10cSrcweir else 1588cdf0e10cSrcweir rConverter.PutandConvertEntry( aFormatString, nCheckPos, nType, 1589cdf0e10cSrcweir nKey, eConvertFrom, eConvertTo ); 1590cdf0e10cSrcweir const SvNumberformat* pFormat = rConverter.GetEntry( nKey ); 1591cdf0e10cSrcweir DBG_ASSERT( pFormat, "SvNumberformat::ConvertLanguage: Conversion ohne Format" ); 1592cdf0e10cSrcweir if ( pFormat ) 1593cdf0e10cSrcweir { 1594cdf0e10cSrcweir ImpCopyNumberformat( *pFormat ); 1595cdf0e10cSrcweir // aus Formatter/Scanner uebernommene Werte zuruecksetzen 1596cdf0e10cSrcweir if ( bSystem ) 1597cdf0e10cSrcweir eLnge = LANGUAGE_SYSTEM; 1598cdf0e10cSrcweir // pColor zeigt noch auf Tabelle in temporaerem Formatter/Scanner 1599cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < 4; i++ ) 1600cdf0e10cSrcweir { 1601cdf0e10cSrcweir String aColorName = NumFor[i].GetColorName(); 1602cdf0e10cSrcweir Color* pColor = rScan.GetColor( aColorName ); 1603cdf0e10cSrcweir NumFor[i].SetColor( pColor, aColorName ); 1604cdf0e10cSrcweir } 1605cdf0e10cSrcweir } 1606cdf0e10cSrcweir } 1607cdf0e10cSrcweir 1608cdf0e10cSrcweir 1609cdf0e10cSrcweir // static 1610cdf0e10cSrcweir void SvNumberformat::LoadString( SvStream& rStream, String& rStr ) 1611cdf0e10cSrcweir { 1612cdf0e10cSrcweir CharSet eStream = rStream.GetStreamCharSet(); 1613cdf0e10cSrcweir ByteString aStr; 1614cdf0e10cSrcweir rStream.ReadByteString( aStr ); 1615cdf0e10cSrcweir sal_Char cStream = NfCurrencyEntry::GetEuroSymbol( eStream ); 1616cdf0e10cSrcweir if ( aStr.Search( cStream ) == STRING_NOTFOUND ) 1617cdf0e10cSrcweir { // simple conversion to unicode 1618cdf0e10cSrcweir rStr = UniString( aStr, eStream ); 1619cdf0e10cSrcweir } 1620cdf0e10cSrcweir else 1621cdf0e10cSrcweir { 1622cdf0e10cSrcweir sal_Unicode cTarget = NfCurrencyEntry::GetEuroSymbol(); 1623cdf0e10cSrcweir register const sal_Char* p = aStr.GetBuffer(); 1624cdf0e10cSrcweir register const sal_Char* const pEnd = p + aStr.Len(); 1625cdf0e10cSrcweir register sal_Unicode* pUni = rStr.AllocBuffer( aStr.Len() ); 1626cdf0e10cSrcweir while ( p < pEnd ) 1627cdf0e10cSrcweir { 1628cdf0e10cSrcweir if ( *p == cStream ) 1629cdf0e10cSrcweir *pUni = cTarget; 1630cdf0e10cSrcweir else 1631cdf0e10cSrcweir *pUni = ByteString::ConvertToUnicode( *p, eStream ); 1632cdf0e10cSrcweir p++; 1633cdf0e10cSrcweir pUni++; 1634cdf0e10cSrcweir } 1635cdf0e10cSrcweir *pUni = 0; 1636cdf0e10cSrcweir } 1637cdf0e10cSrcweir } 1638cdf0e10cSrcweir 1639cdf0e10cSrcweir 1640cdf0e10cSrcweir void SvNumberformat::Save( SvStream& rStream, ImpSvNumMultipleWriteHeader& rHdr ) const 1641cdf0e10cSrcweir { 1642cdf0e10cSrcweir String aFormatstring( sFormatstring ); 1643cdf0e10cSrcweir String aComment( sComment ); 1644cdf0e10cSrcweir #if NF_COMMENT_IN_FORMATSTRING 1645cdf0e10cSrcweir // der Kommentar im Formatstring wird nicht gespeichert, um in alten Versionen 1646cdf0e10cSrcweir // nicht ins schleudern zu kommen und spaeter getrennte Verarbeitung 1647cdf0e10cSrcweir // (z.B. im Dialog) zu ermoeglichen 1648cdf0e10cSrcweir SetComment( "", aFormatstring, aComment ); 1649cdf0e10cSrcweir #endif 1650cdf0e10cSrcweir 1651cdf0e10cSrcweir sal_Bool bNewCurrency = HasNewCurrency(); 1652cdf0e10cSrcweir if ( bNewCurrency ) 1653cdf0e10cSrcweir { // SV_NUMBERFORMATTER_VERSION_NEW_CURR im Kommentar speichern 1654cdf0e10cSrcweir aComment.Insert( cNewCurrencyMagic, 0 ); 1655cdf0e10cSrcweir aComment.Insert( cNewCurrencyMagic, 0 ); 1656cdf0e10cSrcweir aComment.Insert( aFormatstring, 1 ); 1657cdf0e10cSrcweir Build50Formatstring( aFormatstring ); // alten Formatstring generieren 1658cdf0e10cSrcweir } 1659cdf0e10cSrcweir 1660cdf0e10cSrcweir // old SO5 versions do behave strange (no output) if standard flag is set 1661cdf0e10cSrcweir // on formats not prepared for it (not having the following exact types) 1662cdf0e10cSrcweir sal_Bool bOldStandard = bStandard; 1663cdf0e10cSrcweir if ( bOldStandard ) 1664cdf0e10cSrcweir { 1665cdf0e10cSrcweir switch ( eType ) 1666cdf0e10cSrcweir { 1667cdf0e10cSrcweir case NUMBERFORMAT_NUMBER : 1668cdf0e10cSrcweir case NUMBERFORMAT_DATE : 1669cdf0e10cSrcweir case NUMBERFORMAT_TIME : 1670cdf0e10cSrcweir case NUMBERFORMAT_DATETIME : 1671cdf0e10cSrcweir case NUMBERFORMAT_PERCENT : 1672cdf0e10cSrcweir case NUMBERFORMAT_SCIENTIFIC : 1673cdf0e10cSrcweir // ok to save 1674cdf0e10cSrcweir break; 1675cdf0e10cSrcweir default: 1676cdf0e10cSrcweir bOldStandard = sal_False; 1677cdf0e10cSrcweir } 1678cdf0e10cSrcweir } 1679cdf0e10cSrcweir 1680cdf0e10cSrcweir rHdr.StartEntry(); 1681cdf0e10cSrcweir rStream.WriteByteString( aFormatstring, rStream.GetStreamCharSet() ); 1682cdf0e10cSrcweir rStream << eType << fLimit1 << fLimit2 << (sal_uInt16) eOp1 << (sal_uInt16) eOp2 1683cdf0e10cSrcweir << bOldStandard << bIsUsed; 1684cdf0e10cSrcweir for (sal_uInt16 i = 0; i < 4; i++) 1685cdf0e10cSrcweir NumFor[i].Save(rStream); 1686cdf0e10cSrcweir // ab SV_NUMBERFORMATTER_VERSION_NEWSTANDARD 1687cdf0e10cSrcweir rStream.WriteByteString( aComment, rStream.GetStreamCharSet() ); 1688cdf0e10cSrcweir rStream << nNewStandardDefined; 1689cdf0e10cSrcweir // ab SV_NUMBERFORMATTER_VERSION_NEW_CURR 1690cdf0e10cSrcweir rStream << nNewCurrencyVersionId; 1691cdf0e10cSrcweir rStream << bNewCurrency; 1692cdf0e10cSrcweir if ( bNewCurrency ) 1693cdf0e10cSrcweir { 1694cdf0e10cSrcweir for ( sal_uInt16 j=0; j<4; j++ ) 1695cdf0e10cSrcweir { 1696cdf0e10cSrcweir NumFor[j].SaveNewCurrencyMap( rStream ); 1697cdf0e10cSrcweir } 1698cdf0e10cSrcweir } 1699cdf0e10cSrcweir 1700cdf0e10cSrcweir // the real standard flag to load with versions >638 if different 1701cdf0e10cSrcweir if ( bStandard != bOldStandard ) 1702cdf0e10cSrcweir { 1703cdf0e10cSrcweir rStream << nNewStandardFlagVersionId; 1704cdf0e10cSrcweir rStream << bStandard; 1705cdf0e10cSrcweir } 1706cdf0e10cSrcweir 1707cdf0e10cSrcweir rHdr.EndEntry(); 1708cdf0e10cSrcweir } 1709cdf0e10cSrcweir 1710cdf0e10cSrcweir 1711cdf0e10cSrcweir sal_Bool SvNumberformat::HasNewCurrency() const 1712cdf0e10cSrcweir { 1713cdf0e10cSrcweir for ( sal_uInt16 j=0; j<4; j++ ) 1714cdf0e10cSrcweir { 1715cdf0e10cSrcweir if ( NumFor[j].HasNewCurrency() ) 1716cdf0e10cSrcweir return sal_True; 1717cdf0e10cSrcweir } 1718cdf0e10cSrcweir return sal_False; 1719cdf0e10cSrcweir } 1720cdf0e10cSrcweir 1721cdf0e10cSrcweir 1722cdf0e10cSrcweir sal_Bool SvNumberformat::GetNewCurrencySymbol( String& rSymbol, 1723cdf0e10cSrcweir String& rExtension ) const 1724cdf0e10cSrcweir { 1725cdf0e10cSrcweir for ( sal_uInt16 j=0; j<4; j++ ) 1726cdf0e10cSrcweir { 1727cdf0e10cSrcweir if ( NumFor[j].GetNewCurrencySymbol( rSymbol, rExtension ) ) 1728cdf0e10cSrcweir return sal_True; 1729cdf0e10cSrcweir } 1730cdf0e10cSrcweir rSymbol.Erase(); 1731cdf0e10cSrcweir rExtension.Erase(); 1732cdf0e10cSrcweir return sal_False; 1733cdf0e10cSrcweir } 1734cdf0e10cSrcweir 1735cdf0e10cSrcweir 1736cdf0e10cSrcweir // static 1737cdf0e10cSrcweir String SvNumberformat::StripNewCurrencyDelimiters( const String& rStr, 1738cdf0e10cSrcweir sal_Bool bQuoteSymbol ) 1739cdf0e10cSrcweir { 1740cdf0e10cSrcweir String aTmp; 1741cdf0e10cSrcweir xub_StrLen nStartPos, nPos, nLen; 1742cdf0e10cSrcweir nLen = rStr.Len(); 1743cdf0e10cSrcweir nStartPos = 0; 1744cdf0e10cSrcweir while ( (nPos = rStr.SearchAscii( "[$", nStartPos )) != STRING_NOTFOUND ) 1745cdf0e10cSrcweir { 1746cdf0e10cSrcweir xub_StrLen nEnd; 1747cdf0e10cSrcweir if ( (nEnd = GetQuoteEnd( rStr, nPos )) < nLen ) 1748cdf0e10cSrcweir { 1749cdf0e10cSrcweir aTmp += rStr.Copy( nStartPos, ++nEnd - nStartPos ); 1750cdf0e10cSrcweir nStartPos = nEnd; 1751cdf0e10cSrcweir } 1752cdf0e10cSrcweir else 1753cdf0e10cSrcweir { 1754cdf0e10cSrcweir aTmp += rStr.Copy( nStartPos, nPos - nStartPos ); 1755cdf0e10cSrcweir nStartPos = nPos + 2; 1756cdf0e10cSrcweir xub_StrLen nDash; 1757cdf0e10cSrcweir nEnd = nStartPos - 1; 1758cdf0e10cSrcweir do 1759cdf0e10cSrcweir { 1760cdf0e10cSrcweir nDash = rStr.Search( '-', ++nEnd ); 1761cdf0e10cSrcweir } while ( (nEnd = GetQuoteEnd( rStr, nDash )) < nLen ); 1762cdf0e10cSrcweir xub_StrLen nClose; 1763cdf0e10cSrcweir nEnd = nStartPos - 1; 1764cdf0e10cSrcweir do 1765cdf0e10cSrcweir { 1766cdf0e10cSrcweir nClose = rStr.Search( ']', ++nEnd ); 1767cdf0e10cSrcweir } while ( (nEnd = GetQuoteEnd( rStr, nClose )) < nLen ); 1768cdf0e10cSrcweir nPos = ( nDash < nClose ? nDash : nClose ); 1769cdf0e10cSrcweir if ( !bQuoteSymbol || rStr.GetChar( nStartPos ) == '"' ) 1770cdf0e10cSrcweir aTmp += rStr.Copy( nStartPos, nPos - nStartPos ); 1771cdf0e10cSrcweir else 1772cdf0e10cSrcweir { 1773cdf0e10cSrcweir aTmp += '"'; 1774cdf0e10cSrcweir aTmp += rStr.Copy( nStartPos, nPos - nStartPos ); 1775cdf0e10cSrcweir aTmp += '"'; 1776cdf0e10cSrcweir } 1777cdf0e10cSrcweir nStartPos = nClose + 1; 1778cdf0e10cSrcweir } 1779cdf0e10cSrcweir } 1780cdf0e10cSrcweir if ( nLen > nStartPos ) 1781cdf0e10cSrcweir aTmp += rStr.Copy( nStartPos, nLen - nStartPos ); 1782cdf0e10cSrcweir return aTmp; 1783cdf0e10cSrcweir } 1784cdf0e10cSrcweir 1785cdf0e10cSrcweir 1786cdf0e10cSrcweir void SvNumberformat::Build50Formatstring( String& rStr ) const 1787cdf0e10cSrcweir { 1788cdf0e10cSrcweir rStr = StripNewCurrencyDelimiters( sFormatstring, sal_True ); 1789cdf0e10cSrcweir } 1790cdf0e10cSrcweir 1791cdf0e10cSrcweir 1792cdf0e10cSrcweir void SvNumberformat::ImpGetOutputStandard(double& fNumber, String& OutString) 1793cdf0e10cSrcweir { 1794cdf0e10cSrcweir sal_uInt16 nStandardPrec = rScan.GetStandardPrec(); 1795cdf0e10cSrcweir 1796cdf0e10cSrcweir if ( fabs(fNumber) > 1.0E15 ) // #58531# war E16 1797cdf0e10cSrcweir { 1798cdf0e10cSrcweir nStandardPrec = ::std::min(nStandardPrec, static_cast<sal_uInt16>(14)); // limits to 14 decimals 1799cdf0e10cSrcweir OutString = ::rtl::math::doubleToUString( fNumber, 1800cdf0e10cSrcweir rtl_math_StringFormat_E, nStandardPrec /*2*/, 1801cdf0e10cSrcweir GetFormatter().GetNumDecimalSep().GetChar(0)); 1802cdf0e10cSrcweir } 1803cdf0e10cSrcweir else 1804cdf0e10cSrcweir ImpGetOutputStdToPrecision(fNumber, OutString, nStandardPrec); 1805cdf0e10cSrcweir } 1806cdf0e10cSrcweir 1807cdf0e10cSrcweir void SvNumberformat::ImpGetOutputStdToPrecision(double& rNumber, String& rOutString, sal_uInt16 nPrecision) const 1808cdf0e10cSrcweir { 1809cdf0e10cSrcweir // Make sure the precision doesn't go over the maximum allowable precision. 1810cdf0e10cSrcweir nPrecision = ::std::min(UPPER_PRECISION, nPrecision); 1811cdf0e10cSrcweir 1812cdf0e10cSrcweir #if 0 1813cdf0e10cSrcweir { 1814cdf0e10cSrcweir // debugger test case for ANSI standard correctness 1815cdf0e10cSrcweir ::rtl::OUString aTest; 1816cdf0e10cSrcweir // expect 0.00123 OK 1817cdf0e10cSrcweir aTest = ::rtl::math::doubleToUString( 0.001234567, 1818cdf0e10cSrcweir rtl_math_StringFormat_G, 3, '.', sal_True ); 1819cdf0e10cSrcweir // expect 123 OK 1820cdf0e10cSrcweir aTest = ::rtl::math::doubleToUString( 123.4567, 1821cdf0e10cSrcweir rtl_math_StringFormat_G, 3, '.', sal_True ); 1822cdf0e10cSrcweir // expect 123.5 OK 1823cdf0e10cSrcweir aTest = ::rtl::math::doubleToUString( 123.4567, 1824cdf0e10cSrcweir rtl_math_StringFormat_G, 4, '.', sal_True ); 1825cdf0e10cSrcweir // expect 1e+03 (as 999.6 rounded to 3 significant digits results in 1826cdf0e10cSrcweir // 1000 with an exponent equal to significant digits) 1827cdf0e10cSrcweir // Currently (24-Jan-2003) we do fail in this case and output 1000 1828cdf0e10cSrcweir // instead, negligible. 1829cdf0e10cSrcweir aTest = ::rtl::math::doubleToUString( 999.6, 1830cdf0e10cSrcweir rtl_math_StringFormat_G, 3, '.', sal_True ); 1831cdf0e10cSrcweir // expect what? result is 1.2e+004 1832cdf0e10cSrcweir aTest = ::rtl::math::doubleToUString( 12345.6789, 1833cdf0e10cSrcweir rtl_math_StringFormat_G, -3, '.', sal_True ); 1834cdf0e10cSrcweir } 1835cdf0e10cSrcweir #endif 1836cdf0e10cSrcweir 1837cdf0e10cSrcweir // We decided to strip trailing zeros unconditionally, since binary 1838cdf0e10cSrcweir // double-precision rounding error makes it impossible to determine e.g. 1839cdf0e10cSrcweir // whether 844.10000000000002273737 is what the user has typed, or the 1840cdf0e10cSrcweir // user has typed 844.1 but IEEE 754 represents it that way internally. 1841cdf0e10cSrcweir 1842cdf0e10cSrcweir rOutString = ::rtl::math::doubleToUString( rNumber, 1843cdf0e10cSrcweir rtl_math_StringFormat_F, nPrecision /*2*/, 1844cdf0e10cSrcweir GetFormatter().GetNumDecimalSep().GetChar(0), true ); 1845cdf0e10cSrcweir if (rOutString.GetChar(0) == '-' && 1846cdf0e10cSrcweir rOutString.GetTokenCount('0') == rOutString.Len()) 1847cdf0e10cSrcweir rOutString.EraseLeadingChars('-'); // nicht -0 1848cdf0e10cSrcweir 1849cdf0e10cSrcweir ImpTransliterate( rOutString, NumFor[0].GetNatNum() ); 1850cdf0e10cSrcweir } 1851cdf0e10cSrcweir 1852cdf0e10cSrcweir void SvNumberformat::ImpGetOutputInputLine(double fNumber, String& OutString) 1853cdf0e10cSrcweir { 1854cdf0e10cSrcweir sal_Bool bModified = sal_False; 1855cdf0e10cSrcweir if ( (eType & NUMBERFORMAT_PERCENT) && (fabs(fNumber) < _D_MAX_D_BY_100)) 1856cdf0e10cSrcweir { 1857cdf0e10cSrcweir if (fNumber == 0.0) 1858cdf0e10cSrcweir { 1859cdf0e10cSrcweir OutString.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "0%" ) ); 1860cdf0e10cSrcweir return; 1861cdf0e10cSrcweir } 1862cdf0e10cSrcweir fNumber *= 100; 1863cdf0e10cSrcweir bModified = sal_True; 1864cdf0e10cSrcweir } 1865cdf0e10cSrcweir 1866cdf0e10cSrcweir if (fNumber == 0.0) 1867cdf0e10cSrcweir { 1868cdf0e10cSrcweir OutString = '0'; 1869cdf0e10cSrcweir return; 1870cdf0e10cSrcweir } 1871cdf0e10cSrcweir 1872cdf0e10cSrcweir OutString = ::rtl::math::doubleToUString( fNumber, 1873cdf0e10cSrcweir rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, 1874cdf0e10cSrcweir GetFormatter().GetNumDecimalSep().GetChar(0), sal_True ); 1875cdf0e10cSrcweir 1876cdf0e10cSrcweir if ( eType & NUMBERFORMAT_PERCENT && bModified) 1877cdf0e10cSrcweir OutString += '%'; 1878cdf0e10cSrcweir return; 1879cdf0e10cSrcweir } 1880cdf0e10cSrcweir 1881cdf0e10cSrcweir short SvNumberformat::ImpCheckCondition(double& fNumber, 1882cdf0e10cSrcweir double& fLimit, 1883cdf0e10cSrcweir SvNumberformatLimitOps eOp) 1884cdf0e10cSrcweir { 1885cdf0e10cSrcweir switch(eOp) 1886cdf0e10cSrcweir { 1887cdf0e10cSrcweir case NUMBERFORMAT_OP_NO: return -1; 1888cdf0e10cSrcweir case NUMBERFORMAT_OP_EQ: return (short) (fNumber == fLimit); 1889cdf0e10cSrcweir case NUMBERFORMAT_OP_NE: return (short) (fNumber != fLimit); 1890cdf0e10cSrcweir case NUMBERFORMAT_OP_LT: return (short) (fNumber < fLimit); 1891cdf0e10cSrcweir case NUMBERFORMAT_OP_LE: return (short) (fNumber <= fLimit); 1892cdf0e10cSrcweir case NUMBERFORMAT_OP_GT: return (short) (fNumber > fLimit); 1893cdf0e10cSrcweir case NUMBERFORMAT_OP_GE: return (short) (fNumber >= fLimit); 1894cdf0e10cSrcweir default: return -1; 1895cdf0e10cSrcweir } 1896cdf0e10cSrcweir } 1897cdf0e10cSrcweir 1898cdf0e10cSrcweir sal_Bool SvNumberformat::GetOutputString(String& sString, 1899cdf0e10cSrcweir String& OutString, 1900cdf0e10cSrcweir Color** ppColor) 1901cdf0e10cSrcweir { 1902cdf0e10cSrcweir OutString.Erase(); 1903cdf0e10cSrcweir sal_uInt16 nIx; 1904cdf0e10cSrcweir if (eType & NUMBERFORMAT_TEXT) 1905cdf0e10cSrcweir nIx = 0; 1906cdf0e10cSrcweir else if (NumFor[3].GetnAnz() > 0) 1907cdf0e10cSrcweir nIx = 3; 1908cdf0e10cSrcweir else 1909cdf0e10cSrcweir { 1910cdf0e10cSrcweir *ppColor = NULL; // no change of color 1911cdf0e10cSrcweir return sal_False; 1912cdf0e10cSrcweir } 1913cdf0e10cSrcweir *ppColor = NumFor[nIx].GetColor(); 1914cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); 1915cdf0e10cSrcweir if (rInfo.eScannedType == NUMBERFORMAT_TEXT) 1916cdf0e10cSrcweir { 1917cdf0e10cSrcweir sal_Bool bRes = sal_False; 1918cdf0e10cSrcweir const sal_uInt16 nAnz = NumFor[nIx].GetnAnz(); 1919cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nAnz; i++) 1920cdf0e10cSrcweir { 1921cdf0e10cSrcweir switch (rInfo.nTypeArray[i]) 1922cdf0e10cSrcweir { 1923cdf0e10cSrcweir case NF_SYMBOLTYPE_STAR: 1924cdf0e10cSrcweir if( bStarFlag ) 1925cdf0e10cSrcweir { 1926cdf0e10cSrcweir OutString += (sal_Unicode) 0x1B; 1927cdf0e10cSrcweir OutString += rInfo.sStrArray[i].GetChar(1); 1928cdf0e10cSrcweir bRes = sal_True; 1929cdf0e10cSrcweir } 1930cdf0e10cSrcweir break; 1931cdf0e10cSrcweir case NF_SYMBOLTYPE_BLANK: 1932cdf0e10cSrcweir InsertBlanks( OutString, OutString.Len(), 1933cdf0e10cSrcweir rInfo.sStrArray[i].GetChar(1) ); 1934cdf0e10cSrcweir break; 1935cdf0e10cSrcweir case NF_KEY_GENERAL : // #77026# "General" is the same as "@" 1936cdf0e10cSrcweir case NF_SYMBOLTYPE_DEL : 1937cdf0e10cSrcweir OutString += sString; 1938cdf0e10cSrcweir break; 1939cdf0e10cSrcweir default: 1940cdf0e10cSrcweir OutString += rInfo.sStrArray[i]; 1941cdf0e10cSrcweir } 1942cdf0e10cSrcweir } 1943cdf0e10cSrcweir return bRes; 1944cdf0e10cSrcweir } 1945cdf0e10cSrcweir return sal_False; 1946cdf0e10cSrcweir } 1947cdf0e10cSrcweir /* 1948cdf0e10cSrcweir void SvNumberformat::GetNextFareyNumber(sal_uLong nPrec, sal_uLong x0, sal_uLong x1, 1949cdf0e10cSrcweir sal_uLong y0, sal_uLong y1, 1950cdf0e10cSrcweir sal_uLong& x2,sal_uLong& y2) 1951cdf0e10cSrcweir { 1952cdf0e10cSrcweir x2 = ((y0+nPrec)/y1)*x1 - x0; 1953cdf0e10cSrcweir y2 = ((y0+nPrec)/y1)*y1 - y0; 1954cdf0e10cSrcweir } 1955cdf0e10cSrcweir */ 1956cdf0e10cSrcweir sal_uLong SvNumberformat::ImpGGT(sal_uLong x, sal_uLong y) 1957cdf0e10cSrcweir { 1958cdf0e10cSrcweir if (y == 0) 1959cdf0e10cSrcweir return x; 1960cdf0e10cSrcweir else 1961cdf0e10cSrcweir { 1962cdf0e10cSrcweir sal_uLong z = x%y; 1963cdf0e10cSrcweir while (z) 1964cdf0e10cSrcweir { 1965cdf0e10cSrcweir x = y; 1966cdf0e10cSrcweir y = z; 1967cdf0e10cSrcweir z = x%y; 1968cdf0e10cSrcweir } 1969cdf0e10cSrcweir return y; 1970cdf0e10cSrcweir } 1971cdf0e10cSrcweir } 1972cdf0e10cSrcweir 1973cdf0e10cSrcweir sal_uLong SvNumberformat::ImpGGTRound(sal_uLong x, sal_uLong y) 1974cdf0e10cSrcweir { 1975cdf0e10cSrcweir if (y == 0) 1976cdf0e10cSrcweir return x; 1977cdf0e10cSrcweir else 1978cdf0e10cSrcweir { 1979cdf0e10cSrcweir sal_uLong z = x%y; 1980cdf0e10cSrcweir while ((double)z/(double)y > D_EPS) 1981cdf0e10cSrcweir { 1982cdf0e10cSrcweir x = y; 1983cdf0e10cSrcweir y = z; 1984cdf0e10cSrcweir z = x%y; 1985cdf0e10cSrcweir } 1986cdf0e10cSrcweir return y; 1987cdf0e10cSrcweir } 1988cdf0e10cSrcweir } 1989cdf0e10cSrcweir 1990cdf0e10cSrcweir namespace { 1991cdf0e10cSrcweir 1992cdf0e10cSrcweir void lcl_GetOutputStringScientific( 1993cdf0e10cSrcweir double fNumber, sal_uInt16 nCharCount, const SvNumberFormatter& rFormatter, String& rOutString) 1994cdf0e10cSrcweir { 1995cdf0e10cSrcweir bool bSign = ::rtl::math::isSignBitSet(fNumber); 1996cdf0e10cSrcweir 1997cdf0e10cSrcweir // 1.000E+015 (one digit and the decimal point, and the five chars for the exponential part, totalling 7). 1998cdf0e10cSrcweir sal_uInt16 nPrec = nCharCount > 7 ? nCharCount - 7 : 0; 1999cdf0e10cSrcweir if (nPrec && bSign) 2000cdf0e10cSrcweir // Make room for the negative sign. 2001cdf0e10cSrcweir --nPrec; 2002cdf0e10cSrcweir 2003cdf0e10cSrcweir nPrec = ::std::min(nPrec, static_cast<sal_uInt16>(14)); // limit to 14 decimals. 2004cdf0e10cSrcweir 2005cdf0e10cSrcweir rOutString = ::rtl::math::doubleToUString( 2006cdf0e10cSrcweir fNumber, rtl_math_StringFormat_E, nPrec, rFormatter.GetNumDecimalSep().GetChar(0)); 2007cdf0e10cSrcweir } 2008cdf0e10cSrcweir 2009cdf0e10cSrcweir } 2010cdf0e10cSrcweir 2011cdf0e10cSrcweir bool SvNumberformat::GetOutputString(double fNumber, sal_uInt16 nCharCount, String& rOutString) const 2012cdf0e10cSrcweir { 2013cdf0e10cSrcweir using namespace std; 2014cdf0e10cSrcweir 2015cdf0e10cSrcweir if (eType != NUMBERFORMAT_NUMBER) 2016cdf0e10cSrcweir return false; 2017cdf0e10cSrcweir 2018cdf0e10cSrcweir double fTestNum = fNumber; 2019cdf0e10cSrcweir bool bSign = ::rtl::math::isSignBitSet(fTestNum); 2020cdf0e10cSrcweir if (bSign) 2021cdf0e10cSrcweir fTestNum = -fTestNum; 2022cdf0e10cSrcweir 2023cdf0e10cSrcweir if (fTestNum < EXP_LOWER_BOUND) 2024cdf0e10cSrcweir { 2025cdf0e10cSrcweir lcl_GetOutputStringScientific(fNumber, nCharCount, GetFormatter(), rOutString); 2026cdf0e10cSrcweir return true; 2027cdf0e10cSrcweir } 2028cdf0e10cSrcweir 2029cdf0e10cSrcweir double fExp = log10(fTestNum); 2030cdf0e10cSrcweir // Values < 1.0 always have one digit before the decimal point. 2031cdf0e10cSrcweir sal_uInt16 nDigitPre = fExp >= 0.0 ? static_cast<sal_uInt16>(ceil(fExp)) : 1; 2032cdf0e10cSrcweir 2033cdf0e10cSrcweir if (nDigitPre > 15) 2034cdf0e10cSrcweir { 2035cdf0e10cSrcweir lcl_GetOutputStringScientific(fNumber, nCharCount, GetFormatter(), rOutString); 2036cdf0e10cSrcweir return true; 2037cdf0e10cSrcweir } 2038cdf0e10cSrcweir 2039cdf0e10cSrcweir sal_uInt16 nPrec = nCharCount >= nDigitPre ? nCharCount - nDigitPre : 0; 2040cdf0e10cSrcweir if (nPrec && bSign) 2041cdf0e10cSrcweir // Subtract the negative sign. 2042cdf0e10cSrcweir --nPrec; 2043cdf0e10cSrcweir if (nPrec) 2044cdf0e10cSrcweir // Subtract the decimal point. 2045cdf0e10cSrcweir --nPrec; 2046cdf0e10cSrcweir 2047cdf0e10cSrcweir ImpGetOutputStdToPrecision(fNumber, rOutString, nPrec); 2048cdf0e10cSrcweir if (rOutString.Len() > nCharCount) 2049cdf0e10cSrcweir // String still wider than desired. Switch to scientific notation. 2050cdf0e10cSrcweir lcl_GetOutputStringScientific(fNumber, nCharCount, GetFormatter(), rOutString); 2051cdf0e10cSrcweir 2052cdf0e10cSrcweir return true; 2053cdf0e10cSrcweir } 2054cdf0e10cSrcweir 2055cdf0e10cSrcweir sal_Bool SvNumberformat::GetOutputString(double fNumber, 2056cdf0e10cSrcweir String& OutString, 2057cdf0e10cSrcweir Color** ppColor) 2058cdf0e10cSrcweir { 2059cdf0e10cSrcweir sal_Bool bRes = sal_False; 2060cdf0e10cSrcweir OutString.Erase(); // alles loeschen 2061cdf0e10cSrcweir *ppColor = NULL; // keine Farbaenderung 2062cdf0e10cSrcweir if (eType & NUMBERFORMAT_LOGICAL) 2063cdf0e10cSrcweir { 2064cdf0e10cSrcweir if (fNumber) 2065cdf0e10cSrcweir OutString = rScan.GetTrueString(); 2066cdf0e10cSrcweir else 2067cdf0e10cSrcweir OutString = rScan.GetFalseString(); 2068cdf0e10cSrcweir return sal_False; 2069cdf0e10cSrcweir } 2070cdf0e10cSrcweir if (eType & NUMBERFORMAT_TEXT) 2071cdf0e10cSrcweir { 2072cdf0e10cSrcweir ImpGetOutputStandard(fNumber, OutString); 2073cdf0e10cSrcweir return sal_False; 2074cdf0e10cSrcweir } 2075cdf0e10cSrcweir sal_Bool bHadStandard = sal_False; 2076cdf0e10cSrcweir if (bStandard) // einzelne Standardformate 2077cdf0e10cSrcweir { 2078cdf0e10cSrcweir if (rScan.GetStandardPrec() == SvNumberFormatter::INPUTSTRING_PRECISION) // alle Zahlformate InputLine 2079cdf0e10cSrcweir { 2080cdf0e10cSrcweir ImpGetOutputInputLine(fNumber, OutString); 2081cdf0e10cSrcweir return false; 2082cdf0e10cSrcweir } 2083cdf0e10cSrcweir switch (eType) 2084cdf0e10cSrcweir { 2085cdf0e10cSrcweir case NUMBERFORMAT_NUMBER: // Standardzahlformat 2086cdf0e10cSrcweir { 2087cdf0e10cSrcweir if (rScan.GetStandardPrec() == SvNumberFormatter::UNLIMITED_PRECISION) 2088cdf0e10cSrcweir { 2089cdf0e10cSrcweir bool bSign = ::rtl::math::isSignBitSet(fNumber); 2090cdf0e10cSrcweir if (bSign) 2091cdf0e10cSrcweir fNumber = -fNumber; 2092cdf0e10cSrcweir ImpGetOutputStdToPrecision(fNumber, OutString, 10); // Use 10 decimals for general 'unlimited' format. 2093cdf0e10cSrcweir if (fNumber < EXP_LOWER_BOUND) 2094cdf0e10cSrcweir { 2095cdf0e10cSrcweir xub_StrLen nLen = OutString.Len(); 2096cdf0e10cSrcweir if (!nLen) 2097cdf0e10cSrcweir return false; 2098cdf0e10cSrcweir 2099cdf0e10cSrcweir // #i112250# With the 10-decimal limit, small numbers are formatted as "0". 2100cdf0e10cSrcweir // Switch to scientific in that case, too: 2101cdf0e10cSrcweir if (nLen > 11 || (OutString.EqualsAscii("0") && fNumber != 0.0)) 2102cdf0e10cSrcweir { 2103cdf0e10cSrcweir sal_uInt16 nStandardPrec = rScan.GetStandardPrec(); 2104cdf0e10cSrcweir nStandardPrec = ::std::min(nStandardPrec, static_cast<sal_uInt16>(14)); // limits to 14 decimals 2105cdf0e10cSrcweir OutString = ::rtl::math::doubleToUString( fNumber, 2106cdf0e10cSrcweir rtl_math_StringFormat_E, nStandardPrec /*2*/, 2107cdf0e10cSrcweir GetFormatter().GetNumDecimalSep().GetChar(0), true); 2108cdf0e10cSrcweir } 2109cdf0e10cSrcweir } 2110cdf0e10cSrcweir if (bSign) 2111cdf0e10cSrcweir OutString.Insert('-', 0); 2112cdf0e10cSrcweir return false; 2113cdf0e10cSrcweir } 2114cdf0e10cSrcweir ImpGetOutputStandard(fNumber, OutString); 2115cdf0e10cSrcweir bHadStandard = sal_True; 2116cdf0e10cSrcweir } 2117cdf0e10cSrcweir break; 2118cdf0e10cSrcweir case NUMBERFORMAT_DATE: 2119cdf0e10cSrcweir bRes |= ImpGetDateOutput(fNumber, 0, OutString); 2120cdf0e10cSrcweir bHadStandard = sal_True; 2121cdf0e10cSrcweir break; 2122cdf0e10cSrcweir case NUMBERFORMAT_TIME: 2123cdf0e10cSrcweir bRes |= ImpGetTimeOutput(fNumber, 0, OutString); 2124cdf0e10cSrcweir bHadStandard = sal_True; 2125cdf0e10cSrcweir break; 2126cdf0e10cSrcweir case NUMBERFORMAT_DATETIME: 2127cdf0e10cSrcweir bRes |= ImpGetDateTimeOutput(fNumber, 0, OutString); 2128cdf0e10cSrcweir bHadStandard = sal_True; 2129cdf0e10cSrcweir break; 2130cdf0e10cSrcweir } 2131cdf0e10cSrcweir } 2132cdf0e10cSrcweir if ( !bHadStandard ) 2133cdf0e10cSrcweir { 2134cdf0e10cSrcweir sal_uInt16 nIx; // Index des Teilformats 2135cdf0e10cSrcweir short nCheck = ImpCheckCondition(fNumber, fLimit1, eOp1); 2136cdf0e10cSrcweir if (nCheck == -1 || nCheck == 1) // nur 1 String oder True 2137cdf0e10cSrcweir nIx = 0; 2138cdf0e10cSrcweir else 2139cdf0e10cSrcweir { 2140cdf0e10cSrcweir nCheck = ImpCheckCondition(fNumber, fLimit2, eOp2); 2141cdf0e10cSrcweir if (nCheck == -1 || nCheck == 1) 2142cdf0e10cSrcweir nIx = 1; 2143cdf0e10cSrcweir else 2144cdf0e10cSrcweir nIx = 2; 2145cdf0e10cSrcweir } 2146f85760deSWang Lei if (nIx == 1 && // negatives Format 2147f85760deSWang Lei IsNegativeRealNegative() && fNumber < 0.0) // ohne Vorzeichen 2148cdf0e10cSrcweir fNumber = -fNumber; // Vorzeichen eliminieren 2149f85760deSWang Lei if(nIx == 0 && 2150f85760deSWang Lei IsNegativeRealNegative2() && fNumber < 0.0) 2151f85760deSWang Lei fNumber = -fNumber; 2152cdf0e10cSrcweir *ppColor = NumFor[nIx].GetColor(); 2153cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); 2154cdf0e10cSrcweir const sal_uInt16 nAnz = NumFor[nIx].GetnAnz(); 2155cdf0e10cSrcweir if (nAnz == 0 && rInfo.eScannedType == NUMBERFORMAT_UNDEFINED) 2156cdf0e10cSrcweir return sal_False; // leer => nichts 2157cdf0e10cSrcweir else if (nAnz == 0) // sonst Standard-Format 2158cdf0e10cSrcweir { 2159cdf0e10cSrcweir ImpGetOutputStandard(fNumber, OutString); 2160cdf0e10cSrcweir return sal_False; 2161cdf0e10cSrcweir } 2162cdf0e10cSrcweir switch (rInfo.eScannedType) 2163cdf0e10cSrcweir { 2164cdf0e10cSrcweir case NUMBERFORMAT_TEXT: 2165cdf0e10cSrcweir case NUMBERFORMAT_DEFINED: 2166cdf0e10cSrcweir { 2167cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nAnz; i++) 2168cdf0e10cSrcweir { 2169cdf0e10cSrcweir switch (rInfo.nTypeArray[i]) 2170cdf0e10cSrcweir { 2171cdf0e10cSrcweir case NF_SYMBOLTYPE_STAR: 2172cdf0e10cSrcweir if( bStarFlag ) 2173cdf0e10cSrcweir { 2174cdf0e10cSrcweir OutString += (sal_Unicode) 0x1B; 2175cdf0e10cSrcweir OutString += rInfo.sStrArray[i].GetChar(1); 2176cdf0e10cSrcweir bRes = sal_True; 2177cdf0e10cSrcweir } 2178cdf0e10cSrcweir break; 2179cdf0e10cSrcweir case NF_SYMBOLTYPE_BLANK: 2180cdf0e10cSrcweir InsertBlanks( OutString, OutString.Len(), 2181cdf0e10cSrcweir rInfo.sStrArray[i].GetChar(1) ); 2182cdf0e10cSrcweir break; 2183cdf0e10cSrcweir case NF_SYMBOLTYPE_STRING: 2184cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRENCY: 2185cdf0e10cSrcweir OutString += rInfo.sStrArray[i]; 2186cdf0e10cSrcweir break; 2187cdf0e10cSrcweir case NF_SYMBOLTYPE_THSEP: 2188cdf0e10cSrcweir if (rInfo.nThousand == 0) 2189cdf0e10cSrcweir OutString += rInfo.sStrArray[i]; 2190cdf0e10cSrcweir break; 2191cdf0e10cSrcweir default: 2192cdf0e10cSrcweir break; 2193cdf0e10cSrcweir } 2194cdf0e10cSrcweir } 2195cdf0e10cSrcweir } 2196cdf0e10cSrcweir break; 2197cdf0e10cSrcweir case NUMBERFORMAT_DATE: 2198cdf0e10cSrcweir bRes |= ImpGetDateOutput(fNumber, nIx, OutString); 2199cdf0e10cSrcweir break; 2200cdf0e10cSrcweir case NUMBERFORMAT_TIME: 2201cdf0e10cSrcweir bRes |= ImpGetTimeOutput(fNumber, nIx, OutString); 2202cdf0e10cSrcweir break; 2203cdf0e10cSrcweir case NUMBERFORMAT_DATETIME: 2204cdf0e10cSrcweir bRes |= ImpGetDateTimeOutput(fNumber, nIx, OutString); 2205cdf0e10cSrcweir break; 2206cdf0e10cSrcweir case NUMBERFORMAT_NUMBER: 2207cdf0e10cSrcweir case NUMBERFORMAT_PERCENT: 2208cdf0e10cSrcweir case NUMBERFORMAT_CURRENCY: 2209cdf0e10cSrcweir bRes |= ImpGetNumberOutput(fNumber, nIx, OutString); 2210cdf0e10cSrcweir break; 2211cdf0e10cSrcweir case NUMBERFORMAT_FRACTION: 2212cdf0e10cSrcweir { 2213cdf0e10cSrcweir String sStr, sFrac, sDiv; // Strings, Wert fuer 2214cdf0e10cSrcweir sal_uLong nFrac, nDiv; // Vorkommaanteil 2215cdf0e10cSrcweir // Zaehler und Nenner 2216cdf0e10cSrcweir sal_Bool bSign = sal_False; 2217cdf0e10cSrcweir if (fNumber < 0) 2218cdf0e10cSrcweir { 2219cdf0e10cSrcweir if (nIx == 0) // nicht in hinteren 2220cdf0e10cSrcweir bSign = sal_True; // Formaten 2221cdf0e10cSrcweir fNumber = -fNumber; 2222cdf0e10cSrcweir } 2223cdf0e10cSrcweir double fNum = floor(fNumber); // Vorkommateil 2224cdf0e10cSrcweir fNumber -= fNum; // Nachkommateil 2225cdf0e10cSrcweir if (fNum > _D_MAX_U_LONG_ || rInfo.nCntExp > 9) 2226cdf0e10cSrcweir // zu gross 2227cdf0e10cSrcweir { 2228cdf0e10cSrcweir OutString = rScan.GetErrorString(); 2229cdf0e10cSrcweir return sal_False; 2230cdf0e10cSrcweir } 2231cdf0e10cSrcweir if (rInfo.nCntExp == 0) 2232cdf0e10cSrcweir { 2233cdf0e10cSrcweir DBG_ERROR("SvNumberformat:: Bruch, nCntExp == 0"); 2234cdf0e10cSrcweir return sal_False; 2235cdf0e10cSrcweir } 2236cdf0e10cSrcweir sal_uLong nBasis = ((sal_uLong)floor( // 9, 99, 999 ,... 2237cdf0e10cSrcweir pow(10.0,rInfo.nCntExp))) - 1; 2238cdf0e10cSrcweir sal_uLong x0, y0, x1, y1; 2239cdf0e10cSrcweir 2240cdf0e10cSrcweir if (rInfo.nCntExp <= _MAX_FRACTION_PREC) 2241cdf0e10cSrcweir { 2242cdf0e10cSrcweir sal_Bool bUpperHalf; 2243cdf0e10cSrcweir if (fNumber > 0.5) 2244cdf0e10cSrcweir { 2245cdf0e10cSrcweir bUpperHalf = sal_True; 2246cdf0e10cSrcweir fNumber -= (fNumber - 0.5) * 2.0; 2247cdf0e10cSrcweir } 2248cdf0e10cSrcweir else 2249cdf0e10cSrcweir bUpperHalf = sal_False; 2250cdf0e10cSrcweir // Einstieg in Farey-Serie 2251cdf0e10cSrcweir // finden: 2252cdf0e10cSrcweir x0 = (sal_uLong) floor(fNumber*nBasis); // z.B. 2/9 <= x < 3/9 2253cdf0e10cSrcweir if (x0 == 0) // => x0 = 2 2254cdf0e10cSrcweir { 2255cdf0e10cSrcweir y0 = 1; 2256cdf0e10cSrcweir x1 = 1; 2257cdf0e10cSrcweir y1 = nBasis; 2258cdf0e10cSrcweir } 2259cdf0e10cSrcweir else if (x0 == (nBasis-1)/2) // (b-1)/2, 1/2 2260cdf0e10cSrcweir { // geht (nBasis ungerade) 2261cdf0e10cSrcweir y0 = nBasis; 2262cdf0e10cSrcweir x1 = 1; 2263cdf0e10cSrcweir y1 = 2; 2264cdf0e10cSrcweir } 2265cdf0e10cSrcweir else if (x0 == 1) 2266cdf0e10cSrcweir { 2267cdf0e10cSrcweir y0 = nBasis; // 1/n; 1/(n-1) 2268cdf0e10cSrcweir x1 = 1; 2269cdf0e10cSrcweir y1 = nBasis - 1; 2270cdf0e10cSrcweir } 2271cdf0e10cSrcweir else 2272cdf0e10cSrcweir { 2273cdf0e10cSrcweir y0 = nBasis; // z.B. 2/9 2/8 2274cdf0e10cSrcweir x1 = x0; 2275cdf0e10cSrcweir y1 = nBasis - 1; 2276cdf0e10cSrcweir double fUg = (double) x0 / (double) y0; 2277cdf0e10cSrcweir double fOg = (double) x1 / (double) y1; 2278cdf0e10cSrcweir sal_uLong nGgt = ImpGGT(y0, x0); // x0/y0 kuerzen 2279cdf0e10cSrcweir x0 /= nGgt; 2280cdf0e10cSrcweir y0 /= nGgt; // Einschachteln: 2281cdf0e10cSrcweir sal_uLong x2 = 0; 2282cdf0e10cSrcweir sal_uLong y2 = 0; 2283cdf0e10cSrcweir sal_Bool bStop = sal_False; 2284cdf0e10cSrcweir while (!bStop) 2285cdf0e10cSrcweir { 2286cdf0e10cSrcweir #ifdef GCC 2287cdf0e10cSrcweir // #i21648# GCC over-optimizes something resulting 2288cdf0e10cSrcweir // in wrong fTest values throughout the loops. 2289cdf0e10cSrcweir volatile 2290cdf0e10cSrcweir #endif 2291cdf0e10cSrcweir double fTest = (double)x1/(double)y1; 2292cdf0e10cSrcweir while (!bStop) 2293cdf0e10cSrcweir { 2294cdf0e10cSrcweir while (fTest > fOg) 2295cdf0e10cSrcweir { 2296cdf0e10cSrcweir x1--; 2297cdf0e10cSrcweir fTest = (double)x1/(double)y1; 2298cdf0e10cSrcweir } 2299cdf0e10cSrcweir while (fTest < fUg && y1 > 1) 2300cdf0e10cSrcweir { 2301cdf0e10cSrcweir y1--; 2302cdf0e10cSrcweir fTest = (double)x1/(double)y1; 2303cdf0e10cSrcweir } 2304cdf0e10cSrcweir if (fTest <= fOg) 2305cdf0e10cSrcweir { 2306cdf0e10cSrcweir fOg = fTest; 2307cdf0e10cSrcweir bStop = sal_True; 2308cdf0e10cSrcweir } 2309cdf0e10cSrcweir else if (y1 == 1) 2310cdf0e10cSrcweir bStop = sal_True; 2311cdf0e10cSrcweir } // of while 2312cdf0e10cSrcweir nGgt = ImpGGT(y1, x1); // x1/y1 kuerzen 2313cdf0e10cSrcweir x2 = x1 / nGgt; 2314cdf0e10cSrcweir y2 = y1 / nGgt; 2315cdf0e10cSrcweir if (x2*y0 - x0*y2 == 1 || y1 <= 1) // Test, ob x2/y2 2316cdf0e10cSrcweir bStop = sal_True; // naechste Farey-Zahl 2317cdf0e10cSrcweir else 2318cdf0e10cSrcweir { 2319cdf0e10cSrcweir y1--; 2320cdf0e10cSrcweir bStop = sal_False; 2321cdf0e10cSrcweir } 2322cdf0e10cSrcweir } // of while 2323cdf0e10cSrcweir x1 = x2; 2324cdf0e10cSrcweir y1 = y2; 2325cdf0e10cSrcweir } // of else 2326cdf0e10cSrcweir double fup, flow; 2327cdf0e10cSrcweir flow = (double)x0/(double)y0; 2328cdf0e10cSrcweir fup = (double)x1/(double)y1; 2329cdf0e10cSrcweir while (fNumber > fup) 2330cdf0e10cSrcweir { 2331cdf0e10cSrcweir sal_uLong x2 = ((y0+nBasis)/y1)*x1 - x0; // naechste Farey-Zahl 2332cdf0e10cSrcweir sal_uLong y2 = ((y0+nBasis)/y1)*y1 - y0; 2333cdf0e10cSrcweir // GetNextFareyNumber(nBasis, x0, x1, y0, y1, x2, y2); 2334cdf0e10cSrcweir x0 = x1; 2335cdf0e10cSrcweir y0 = y1; 2336cdf0e10cSrcweir x1 = x2; 2337cdf0e10cSrcweir y1 = y2; 2338cdf0e10cSrcweir flow = fup; 2339cdf0e10cSrcweir fup = (double)x1/(double)y1; 2340cdf0e10cSrcweir } 2341cdf0e10cSrcweir if (fNumber - flow < fup - fNumber) 2342cdf0e10cSrcweir { 2343cdf0e10cSrcweir nFrac = x0; 2344cdf0e10cSrcweir nDiv = y0; 2345cdf0e10cSrcweir } 2346cdf0e10cSrcweir else 2347cdf0e10cSrcweir { 2348cdf0e10cSrcweir nFrac = x1; 2349cdf0e10cSrcweir nDiv = y1; 2350cdf0e10cSrcweir } 2351cdf0e10cSrcweir if (bUpperHalf) // Original restaur. 2352cdf0e10cSrcweir { 2353cdf0e10cSrcweir if (nFrac == 0 && nDiv == 1) // 1/1 2354cdf0e10cSrcweir fNum += 1.0; 2355cdf0e10cSrcweir else 2356cdf0e10cSrcweir nFrac = nDiv - nFrac; 2357cdf0e10cSrcweir } 2358cdf0e10cSrcweir } 2359cdf0e10cSrcweir else // grosse Nenner 2360cdf0e10cSrcweir { // 0,1234->123/1000 2361cdf0e10cSrcweir sal_uLong nGgt; 2362cdf0e10cSrcweir /* 2363cdf0e10cSrcweir nDiv = nBasis+1; 2364cdf0e10cSrcweir nFrac = ((sal_uLong)floor(0.5 + fNumber * 2365cdf0e10cSrcweir pow(10.0,rInfo.nCntExp))); 2366cdf0e10cSrcweir */ 2367cdf0e10cSrcweir nDiv = 10000000; 2368cdf0e10cSrcweir nFrac = ((sal_uLong)floor(0.5 + fNumber * 10000000.0)); 2369cdf0e10cSrcweir nGgt = ImpGGT(nDiv, nFrac); 2370cdf0e10cSrcweir if (nGgt > 1) 2371cdf0e10cSrcweir { 2372cdf0e10cSrcweir nDiv /= nGgt; 2373cdf0e10cSrcweir nFrac /= nGgt; 2374cdf0e10cSrcweir } 2375cdf0e10cSrcweir if (nDiv > nBasis) 2376cdf0e10cSrcweir { 2377cdf0e10cSrcweir nGgt = ImpGGTRound(nDiv, nFrac); 2378cdf0e10cSrcweir if (nGgt > 1) 2379cdf0e10cSrcweir { 2380cdf0e10cSrcweir nDiv /= nGgt; 2381cdf0e10cSrcweir nFrac /= nGgt; 2382cdf0e10cSrcweir } 2383cdf0e10cSrcweir } 2384cdf0e10cSrcweir if (nDiv > nBasis) 2385cdf0e10cSrcweir { 2386cdf0e10cSrcweir nDiv = nBasis; 2387cdf0e10cSrcweir nFrac = ((sal_uLong)floor(0.5 + fNumber * 2388cdf0e10cSrcweir pow(10.0,rInfo.nCntExp))); 2389cdf0e10cSrcweir nGgt = ImpGGTRound(nDiv, nFrac); 2390cdf0e10cSrcweir if (nGgt > 1) 2391cdf0e10cSrcweir { 2392cdf0e10cSrcweir nDiv /= nGgt; 2393cdf0e10cSrcweir nFrac /= nGgt; 2394cdf0e10cSrcweir } 2395cdf0e10cSrcweir } 2396cdf0e10cSrcweir } 2397cdf0e10cSrcweir 2398cdf0e10cSrcweir if (rInfo.nCntPre == 0) // unechter Bruch 2399cdf0e10cSrcweir { 2400cdf0e10cSrcweir double fNum1 = fNum * (double)nDiv + (double)nFrac; 2401cdf0e10cSrcweir if (fNum1 > _D_MAX_U_LONG_) 2402cdf0e10cSrcweir { 2403cdf0e10cSrcweir OutString = rScan.GetErrorString(); 2404cdf0e10cSrcweir return sal_False; 2405cdf0e10cSrcweir } 2406cdf0e10cSrcweir nFrac = (sal_uLong) floor(fNum1); 2407cdf0e10cSrcweir sStr.Erase(); 2408cdf0e10cSrcweir } 2409cdf0e10cSrcweir else if (fNum == 0.0 && nFrac != 0) 2410cdf0e10cSrcweir sStr.Erase(); 2411cdf0e10cSrcweir else 2412cdf0e10cSrcweir { 2413cdf0e10cSrcweir char aBuf[100]; 2414cdf0e10cSrcweir sprintf( aBuf, "%.f", fNum ); // simple rounded integer (#100211# - checked) 2415cdf0e10cSrcweir sStr.AssignAscii( aBuf ); 2416cdf0e10cSrcweir ImpTransliterate( sStr, NumFor[nIx].GetNatNum() ); 2417cdf0e10cSrcweir } 2418cdf0e10cSrcweir if (rInfo.nCntPre > 0 && nFrac == 0) 2419cdf0e10cSrcweir { 2420cdf0e10cSrcweir sFrac.Erase(); 2421cdf0e10cSrcweir sDiv.Erase(); 2422cdf0e10cSrcweir } 2423cdf0e10cSrcweir else 2424cdf0e10cSrcweir { 2425cdf0e10cSrcweir sFrac = ImpIntToString( nIx, nFrac ); 2426cdf0e10cSrcweir sDiv = ImpIntToString( nIx, nDiv ); 2427cdf0e10cSrcweir } 2428cdf0e10cSrcweir 2429cdf0e10cSrcweir sal_uInt16 j = nAnz-1; // letztes Symbol->rueckw. 2430cdf0e10cSrcweir xub_StrLen k; // Nenner: 2431cdf0e10cSrcweir bRes |= ImpNumberFill(sDiv, fNumber, k, j, nIx, NF_SYMBOLTYPE_FRAC); 2432cdf0e10cSrcweir sal_Bool bCont = sal_True; 2433cdf0e10cSrcweir if (rInfo.nTypeArray[j] == NF_SYMBOLTYPE_FRAC) 2434cdf0e10cSrcweir { 2435cdf0e10cSrcweir if (rInfo.nCntPre > 0 && nFrac == 0) 2436cdf0e10cSrcweir sDiv.Insert(' ',0); 2437cdf0e10cSrcweir else 2438cdf0e10cSrcweir sDiv.Insert( rInfo.sStrArray[j].GetChar(0), 0 ); 2439cdf0e10cSrcweir if ( j ) 2440cdf0e10cSrcweir j--; 2441cdf0e10cSrcweir else 2442cdf0e10cSrcweir bCont = sal_False; 2443cdf0e10cSrcweir } 2444cdf0e10cSrcweir // weiter Zaehler: 2445cdf0e10cSrcweir if ( !bCont ) 2446cdf0e10cSrcweir sFrac.Erase(); 2447cdf0e10cSrcweir else 2448cdf0e10cSrcweir { 2449cdf0e10cSrcweir bRes |= ImpNumberFill(sFrac, fNumber, k, j, nIx, NF_SYMBOLTYPE_FRACBLANK); 2450cdf0e10cSrcweir if (rInfo.nTypeArray[j] == NF_SYMBOLTYPE_FRACBLANK) 2451cdf0e10cSrcweir { 2452cdf0e10cSrcweir sFrac.Insert(rInfo.sStrArray[j],0); 2453cdf0e10cSrcweir if ( j ) 2454cdf0e10cSrcweir j--; 2455cdf0e10cSrcweir else 2456cdf0e10cSrcweir bCont = sal_False; 2457cdf0e10cSrcweir } 2458cdf0e10cSrcweir } 2459cdf0e10cSrcweir // weiter Hauptzahl 2460cdf0e10cSrcweir if ( !bCont ) 2461cdf0e10cSrcweir sStr.Erase(); 2462cdf0e10cSrcweir else 2463cdf0e10cSrcweir { 2464cdf0e10cSrcweir k = sStr.Len(); // hinter letzter Ziffer 2465cdf0e10cSrcweir bRes |= ImpNumberFillWithThousands(sStr, fNumber, k, j, nIx, 2466cdf0e10cSrcweir rInfo.nCntPre); 2467cdf0e10cSrcweir } 2468cdf0e10cSrcweir if (bSign && !(nFrac == 0 && fNum == 0.0)) 2469cdf0e10cSrcweir OutString.Insert('-',0); // nicht -0 2470cdf0e10cSrcweir OutString += sStr; 2471cdf0e10cSrcweir OutString += sFrac; 2472cdf0e10cSrcweir OutString += sDiv; 2473cdf0e10cSrcweir } 2474cdf0e10cSrcweir break; 2475cdf0e10cSrcweir case NUMBERFORMAT_SCIENTIFIC: 2476cdf0e10cSrcweir { 2477cdf0e10cSrcweir sal_Bool bSign = sal_False; 2478cdf0e10cSrcweir if (fNumber < 0) 2479cdf0e10cSrcweir { 2480cdf0e10cSrcweir if (nIx == 0) // nicht in hinteren 2481cdf0e10cSrcweir bSign = sal_True; // Formaten 2482cdf0e10cSrcweir fNumber = -fNumber; 2483cdf0e10cSrcweir } 2484cdf0e10cSrcweir String sStr( ::rtl::math::doubleToUString( fNumber, 2485cdf0e10cSrcweir rtl_math_StringFormat_E, 2486cdf0e10cSrcweir rInfo.nCntPre + rInfo.nCntPost - 1, '.' )); 2487cdf0e10cSrcweir 2488cdf0e10cSrcweir String ExpStr; 2489cdf0e10cSrcweir short nExpSign = 1; 2490cdf0e10cSrcweir xub_StrLen nExPos = sStr.Search('E'); 2491cdf0e10cSrcweir if ( nExPos != STRING_NOTFOUND ) 2492cdf0e10cSrcweir { 2493cdf0e10cSrcweir // split into mantisse and exponent and get rid of "E+" or "E-" 2494cdf0e10cSrcweir xub_StrLen nExpStart = nExPos + 1; 2495cdf0e10cSrcweir switch ( sStr.GetChar( nExpStart ) ) 2496cdf0e10cSrcweir { 2497cdf0e10cSrcweir case '-' : 2498cdf0e10cSrcweir nExpSign = -1; 2499cdf0e10cSrcweir // fallthru 2500cdf0e10cSrcweir case '+' : 2501cdf0e10cSrcweir ++nExpStart; 2502cdf0e10cSrcweir break; 2503cdf0e10cSrcweir } 2504cdf0e10cSrcweir ExpStr = sStr.Copy( nExpStart ); // part following the "E+" 2505cdf0e10cSrcweir sStr.Erase( nExPos ); 2506cdf0e10cSrcweir sStr.EraseAllChars('.'); // cut any decimal delimiter 2507cdf0e10cSrcweir if ( rInfo.nCntPre != 1 ) // rescale Exp 2508cdf0e10cSrcweir { 2509cdf0e10cSrcweir sal_Int32 nExp = ExpStr.ToInt32() * nExpSign; 2510cdf0e10cSrcweir nExp -= sal_Int32(rInfo.nCntPre)-1; 2511cdf0e10cSrcweir if ( nExp < 0 ) 2512cdf0e10cSrcweir { 2513cdf0e10cSrcweir nExpSign = -1; 2514cdf0e10cSrcweir nExp = -nExp; 2515cdf0e10cSrcweir } 2516cdf0e10cSrcweir else 2517cdf0e10cSrcweir nExpSign = 1; 2518cdf0e10cSrcweir ExpStr = String::CreateFromInt32( nExp ); 2519cdf0e10cSrcweir } 2520cdf0e10cSrcweir } 2521cdf0e10cSrcweir sal_uInt16 j = nAnz-1; // last symbol 2522cdf0e10cSrcweir xub_StrLen k; // position in ExpStr 2523cdf0e10cSrcweir bRes |= ImpNumberFill(ExpStr, fNumber, k, j, nIx, NF_SYMBOLTYPE_EXP); 2524cdf0e10cSrcweir 2525cdf0e10cSrcweir xub_StrLen nZeros = 0; // erase leading zeros 2526cdf0e10cSrcweir while (nZeros < k && ExpStr.GetChar(nZeros) == '0') 2527cdf0e10cSrcweir ++nZeros; 2528cdf0e10cSrcweir if (nZeros) 2529cdf0e10cSrcweir ExpStr.Erase( 0, nZeros); 2530cdf0e10cSrcweir 2531cdf0e10cSrcweir sal_Bool bCont = sal_True; 2532cdf0e10cSrcweir if (rInfo.nTypeArray[j] == NF_SYMBOLTYPE_EXP) 2533cdf0e10cSrcweir { 2534cdf0e10cSrcweir const String& rStr = rInfo.sStrArray[j]; 2535cdf0e10cSrcweir if (nExpSign == -1) 2536cdf0e10cSrcweir ExpStr.Insert('-',0); 2537cdf0e10cSrcweir else if (rStr.Len() > 1 && rStr.GetChar(1) == '+') 2538cdf0e10cSrcweir ExpStr.Insert('+',0); 2539cdf0e10cSrcweir ExpStr.Insert(rStr.GetChar(0),0); 2540cdf0e10cSrcweir if ( j ) 2541cdf0e10cSrcweir j--; 2542cdf0e10cSrcweir else 2543cdf0e10cSrcweir bCont = sal_False; 2544cdf0e10cSrcweir } 2545cdf0e10cSrcweir // weiter Hauptzahl: 2546cdf0e10cSrcweir if ( !bCont ) 2547cdf0e10cSrcweir sStr.Erase(); 2548cdf0e10cSrcweir else 2549cdf0e10cSrcweir { 2550cdf0e10cSrcweir k = sStr.Len(); // hinter letzter Ziffer 2551cdf0e10cSrcweir bRes |= ImpNumberFillWithThousands(sStr,fNumber, k,j,nIx, 2552cdf0e10cSrcweir rInfo.nCntPre + 2553cdf0e10cSrcweir rInfo.nCntPost); 2554cdf0e10cSrcweir } 2555cdf0e10cSrcweir if (bSign) 2556cdf0e10cSrcweir sStr.Insert('-',0); 2557cdf0e10cSrcweir OutString = sStr; 2558cdf0e10cSrcweir OutString += ExpStr; 2559cdf0e10cSrcweir } 2560cdf0e10cSrcweir break; 2561cdf0e10cSrcweir } 2562cdf0e10cSrcweir } 2563cdf0e10cSrcweir return bRes; 2564cdf0e10cSrcweir } 2565cdf0e10cSrcweir 2566cdf0e10cSrcweir sal_Bool SvNumberformat::ImpGetTimeOutput(double fNumber, 2567cdf0e10cSrcweir sal_uInt16 nIx, 2568cdf0e10cSrcweir String& OutString) 2569cdf0e10cSrcweir { 2570cdf0e10cSrcweir using namespace ::com::sun::star::i18n; 2571cdf0e10cSrcweir sal_Bool bCalendarSet = sal_False; 2572cdf0e10cSrcweir double fNumberOrig = fNumber; 2573cdf0e10cSrcweir sal_Bool bRes = sal_False; 2574cdf0e10cSrcweir sal_Bool bSign = sal_False; 2575cdf0e10cSrcweir if (fNumber < 0.0) 2576cdf0e10cSrcweir { 2577cdf0e10cSrcweir fNumber = -fNumber; 2578cdf0e10cSrcweir if (nIx == 0) 2579cdf0e10cSrcweir bSign = sal_True; 2580cdf0e10cSrcweir } 2581cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); 2582cdf0e10cSrcweir if (rInfo.bThousand) // []-Format 2583cdf0e10cSrcweir { 2584cdf0e10cSrcweir if (fNumber > 1.0E10) // zu gross 2585cdf0e10cSrcweir { 2586cdf0e10cSrcweir OutString = rScan.GetErrorString(); 2587cdf0e10cSrcweir return sal_False; 2588cdf0e10cSrcweir } 2589cdf0e10cSrcweir } 2590cdf0e10cSrcweir else 2591cdf0e10cSrcweir fNumber -= floor(fNumber); // sonst Datum abtrennen 2592cdf0e10cSrcweir sal_Bool bInputLine; 2593cdf0e10cSrcweir xub_StrLen nCntPost; 2594cdf0e10cSrcweir if ( rScan.GetStandardPrec() == 300 && 2595cdf0e10cSrcweir 0 < rInfo.nCntPost && rInfo.nCntPost < 7 ) 2596cdf0e10cSrcweir { // round at 7 decimals (+5 of 86400 == 12 significant digits) 2597cdf0e10cSrcweir bInputLine = sal_True; 2598cdf0e10cSrcweir nCntPost = 7; 2599cdf0e10cSrcweir } 2600cdf0e10cSrcweir else 2601cdf0e10cSrcweir { 2602cdf0e10cSrcweir bInputLine = sal_False; 2603cdf0e10cSrcweir nCntPost = xub_StrLen(rInfo.nCntPost); 2604cdf0e10cSrcweir } 2605cdf0e10cSrcweir if (bSign && !rInfo.bThousand) // kein []-Format 2606cdf0e10cSrcweir fNumber = 1.0 - fNumber; // "Kehrwert" 2607cdf0e10cSrcweir double fTime = fNumber * 86400.0; 2608cdf0e10cSrcweir fTime = ::rtl::math::round( fTime, int(nCntPost) ); 2609cdf0e10cSrcweir if (bSign && fTime == 0.0) 2610cdf0e10cSrcweir bSign = sal_False; // nicht -00:00:00 2611cdf0e10cSrcweir 2612cdf0e10cSrcweir if( floor( fTime ) > _D_MAX_U_LONG_ ) 2613cdf0e10cSrcweir { 2614cdf0e10cSrcweir OutString = rScan.GetErrorString(); 2615cdf0e10cSrcweir return sal_False; 2616cdf0e10cSrcweir } 2617cdf0e10cSrcweir sal_uLong nSeconds = (sal_uLong)floor( fTime ); 2618cdf0e10cSrcweir 2619cdf0e10cSrcweir String sSecStr( ::rtl::math::doubleToUString( fTime-nSeconds, 2620cdf0e10cSrcweir rtl_math_StringFormat_F, int(nCntPost), '.')); 2621cdf0e10cSrcweir sSecStr.EraseLeadingChars('0'); 2622cdf0e10cSrcweir sSecStr.EraseLeadingChars('.'); 2623cdf0e10cSrcweir if ( bInputLine ) 2624cdf0e10cSrcweir { 2625cdf0e10cSrcweir sSecStr.EraseTrailingChars('0'); 2626cdf0e10cSrcweir if ( sSecStr.Len() < xub_StrLen(rInfo.nCntPost) ) 2627cdf0e10cSrcweir sSecStr.Expand( xub_StrLen(rInfo.nCntPost), '0' ); 2628cdf0e10cSrcweir ImpTransliterate( sSecStr, NumFor[nIx].GetNatNum() ); 2629cdf0e10cSrcweir nCntPost = sSecStr.Len(); 2630cdf0e10cSrcweir } 2631cdf0e10cSrcweir else 2632cdf0e10cSrcweir ImpTransliterate( sSecStr, NumFor[nIx].GetNatNum() ); 2633cdf0e10cSrcweir 2634cdf0e10cSrcweir xub_StrLen nSecPos = 0; // Zum Ziffernweisen 2635cdf0e10cSrcweir // abarbeiten 2636cdf0e10cSrcweir sal_uLong nHour, nMin, nSec; 2637cdf0e10cSrcweir if (!rInfo.bThousand) // kein [] Format 2638cdf0e10cSrcweir { 2639cdf0e10cSrcweir nHour = (nSeconds/3600) % 24; 2640cdf0e10cSrcweir nMin = (nSeconds%3600) / 60; 2641cdf0e10cSrcweir nSec = nSeconds%60; 2642cdf0e10cSrcweir } 2643cdf0e10cSrcweir else if (rInfo.nThousand == 3) // [ss] 2644cdf0e10cSrcweir { 2645cdf0e10cSrcweir nHour = 0; 2646cdf0e10cSrcweir nMin = 0; 2647cdf0e10cSrcweir nSec = nSeconds; 2648cdf0e10cSrcweir } 2649cdf0e10cSrcweir else if (rInfo.nThousand == 2) // [mm]:ss 2650cdf0e10cSrcweir { 2651cdf0e10cSrcweir nHour = 0; 2652cdf0e10cSrcweir nMin = nSeconds / 60; 2653cdf0e10cSrcweir nSec = nSeconds % 60; 2654cdf0e10cSrcweir } 2655cdf0e10cSrcweir else if (rInfo.nThousand == 1) // [hh]:mm:ss 2656cdf0e10cSrcweir { 2657cdf0e10cSrcweir nHour = nSeconds / 3600; 2658cdf0e10cSrcweir nMin = (nSeconds%3600) / 60; 2659cdf0e10cSrcweir nSec = nSeconds%60; 2660cdf0e10cSrcweir } 2661cdf0e10cSrcweir else { 2662cdf0e10cSrcweir // TODO What should these be set to? 2663cdf0e10cSrcweir nHour = 0; 2664cdf0e10cSrcweir nMin = 0; 2665cdf0e10cSrcweir nSec = 0; 2666cdf0e10cSrcweir } 2667cdf0e10cSrcweir 2668cdf0e10cSrcweir sal_Unicode cAmPm = ' '; // a oder p 2669cdf0e10cSrcweir if (rInfo.nCntExp) // AM/PM 2670cdf0e10cSrcweir { 2671cdf0e10cSrcweir if (nHour == 0) 2672cdf0e10cSrcweir { 2673cdf0e10cSrcweir nHour = 12; 2674cdf0e10cSrcweir cAmPm = 'a'; 2675cdf0e10cSrcweir } 2676cdf0e10cSrcweir else if (nHour < 12) 2677cdf0e10cSrcweir cAmPm = 'a'; 2678cdf0e10cSrcweir else 2679cdf0e10cSrcweir { 2680cdf0e10cSrcweir cAmPm = 'p'; 2681cdf0e10cSrcweir if (nHour > 12) 2682cdf0e10cSrcweir nHour -= 12; 2683cdf0e10cSrcweir } 2684cdf0e10cSrcweir } 2685cdf0e10cSrcweir const sal_uInt16 nAnz = NumFor[nIx].GetnAnz(); 2686cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nAnz; i++) 2687cdf0e10cSrcweir { 2688cdf0e10cSrcweir switch (rInfo.nTypeArray[i]) 2689cdf0e10cSrcweir { 2690cdf0e10cSrcweir case NF_SYMBOLTYPE_STAR: 2691cdf0e10cSrcweir if( bStarFlag ) 2692cdf0e10cSrcweir { 2693cdf0e10cSrcweir OutString += (sal_Unicode) 0x1B; 2694cdf0e10cSrcweir OutString += rInfo.sStrArray[i].GetChar(1); 2695cdf0e10cSrcweir bRes = sal_True; 2696cdf0e10cSrcweir } 2697cdf0e10cSrcweir break; 2698cdf0e10cSrcweir case NF_SYMBOLTYPE_BLANK: 2699cdf0e10cSrcweir InsertBlanks( OutString, OutString.Len(), 2700cdf0e10cSrcweir rInfo.sStrArray[i].GetChar(1) ); 2701cdf0e10cSrcweir break; 2702cdf0e10cSrcweir case NF_SYMBOLTYPE_STRING: 2703cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRENCY: 2704cdf0e10cSrcweir case NF_SYMBOLTYPE_DATESEP: 2705cdf0e10cSrcweir case NF_SYMBOLTYPE_TIMESEP: 2706cdf0e10cSrcweir case NF_SYMBOLTYPE_TIME100SECSEP: 2707cdf0e10cSrcweir OutString += rInfo.sStrArray[i]; 2708cdf0e10cSrcweir break; 2709cdf0e10cSrcweir case NF_SYMBOLTYPE_DIGIT: 2710cdf0e10cSrcweir { 2711cdf0e10cSrcweir xub_StrLen nLen = ( bInputLine && i > 0 && 2712cdf0e10cSrcweir (rInfo.nTypeArray[i-1] == NF_SYMBOLTYPE_STRING || 2713cdf0e10cSrcweir rInfo.nTypeArray[i-1] == NF_SYMBOLTYPE_TIME100SECSEP) ? 2714cdf0e10cSrcweir nCntPost : rInfo.sStrArray[i].Len() ); 2715cdf0e10cSrcweir for (xub_StrLen j = 0; j < nLen && nSecPos < nCntPost; j++) 2716cdf0e10cSrcweir { 2717cdf0e10cSrcweir OutString += sSecStr.GetChar(nSecPos); 2718cdf0e10cSrcweir nSecPos++; 2719cdf0e10cSrcweir } 2720cdf0e10cSrcweir } 2721cdf0e10cSrcweir break; 2722cdf0e10cSrcweir case NF_KEY_AMPM: // AM/PM 2723cdf0e10cSrcweir { 2724cdf0e10cSrcweir if ( !bCalendarSet ) 2725cdf0e10cSrcweir { 2726cdf0e10cSrcweir double fDiff = DateTime(*(rScan.GetNullDate())) - GetCal().getEpochStart(); 2727cdf0e10cSrcweir fDiff += fNumberOrig; 2728cdf0e10cSrcweir GetCal().setLocalDateTime( fDiff ); 2729cdf0e10cSrcweir bCalendarSet = sal_True; 2730cdf0e10cSrcweir } 2731cdf0e10cSrcweir if (cAmPm == 'a') 2732cdf0e10cSrcweir OutString += GetCal().getDisplayName( 2733cdf0e10cSrcweir CalendarDisplayIndex::AM_PM, AmPmValue::AM, 0 ); 2734cdf0e10cSrcweir else 2735cdf0e10cSrcweir OutString += GetCal().getDisplayName( 2736cdf0e10cSrcweir CalendarDisplayIndex::AM_PM, AmPmValue::PM, 0 ); 2737cdf0e10cSrcweir } 2738cdf0e10cSrcweir break; 2739cdf0e10cSrcweir case NF_KEY_AP: // A/P 2740cdf0e10cSrcweir { 2741cdf0e10cSrcweir if (cAmPm == 'a') 2742cdf0e10cSrcweir OutString += 'a'; 2743cdf0e10cSrcweir else 2744cdf0e10cSrcweir OutString += 'p'; 2745cdf0e10cSrcweir } 2746cdf0e10cSrcweir break; 2747cdf0e10cSrcweir case NF_KEY_MI: // M 2748cdf0e10cSrcweir OutString += ImpIntToString( nIx, nMin ); 2749cdf0e10cSrcweir break; 2750cdf0e10cSrcweir case NF_KEY_MMI: // MM 2751cdf0e10cSrcweir OutString += ImpIntToString( nIx, nMin, 2 ); 2752cdf0e10cSrcweir break; 2753cdf0e10cSrcweir case NF_KEY_H: // H 2754cdf0e10cSrcweir OutString += ImpIntToString( nIx, nHour ); 2755cdf0e10cSrcweir break; 2756cdf0e10cSrcweir case NF_KEY_HH: // HH 2757cdf0e10cSrcweir OutString += ImpIntToString( nIx, nHour, 2 ); 2758cdf0e10cSrcweir break; 2759cdf0e10cSrcweir case NF_KEY_S: // S 2760cdf0e10cSrcweir OutString += ImpIntToString( nIx, nSec ); 2761cdf0e10cSrcweir break; 2762cdf0e10cSrcweir case NF_KEY_SS: // SS 2763cdf0e10cSrcweir OutString += ImpIntToString( nIx, nSec, 2 ); 2764cdf0e10cSrcweir break; 2765cdf0e10cSrcweir default: 2766cdf0e10cSrcweir break; 2767cdf0e10cSrcweir } 2768cdf0e10cSrcweir } 2769cdf0e10cSrcweir if (bSign && rInfo.bThousand) 2770cdf0e10cSrcweir OutString.Insert('-',0); 2771cdf0e10cSrcweir return bRes; 2772cdf0e10cSrcweir } 2773cdf0e10cSrcweir 2774cdf0e10cSrcweir 2775cdf0e10cSrcweir sal_Bool SvNumberformat::ImpIsOtherCalendar( const ImpSvNumFor& rNumFor ) const 2776cdf0e10cSrcweir { 2777cdf0e10cSrcweir if ( GetCal().getUniqueID() != Gregorian::get() ) 2778cdf0e10cSrcweir return sal_False; 2779cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = rNumFor.Info(); 2780cdf0e10cSrcweir const sal_uInt16 nAnz = rNumFor.GetnAnz(); 2781cdf0e10cSrcweir sal_uInt16 i; 2782cdf0e10cSrcweir for ( i = 0; i < nAnz; i++ ) 2783cdf0e10cSrcweir { 2784cdf0e10cSrcweir switch ( rInfo.nTypeArray[i] ) 2785cdf0e10cSrcweir { 2786cdf0e10cSrcweir case NF_SYMBOLTYPE_CALENDAR : 2787cdf0e10cSrcweir return sal_False; 2788cdf0e10cSrcweir case NF_KEY_EC : 2789cdf0e10cSrcweir case NF_KEY_EEC : 2790cdf0e10cSrcweir case NF_KEY_R : 2791cdf0e10cSrcweir case NF_KEY_RR : 2792cdf0e10cSrcweir case NF_KEY_AAA : 2793cdf0e10cSrcweir case NF_KEY_AAAA : 2794cdf0e10cSrcweir return sal_True; 2795cdf0e10cSrcweir } 2796cdf0e10cSrcweir } 2797cdf0e10cSrcweir return sal_False; 2798cdf0e10cSrcweir } 2799cdf0e10cSrcweir 2800cdf0e10cSrcweir 2801cdf0e10cSrcweir void SvNumberformat::SwitchToOtherCalendar( String& rOrgCalendar, 2802cdf0e10cSrcweir double& fOrgDateTime ) const 2803cdf0e10cSrcweir { 2804cdf0e10cSrcweir CalendarWrapper& rCal = GetCal(); 2805cdf0e10cSrcweir const rtl::OUString &rGregorian = Gregorian::get(); 2806cdf0e10cSrcweir if ( rCal.getUniqueID() == rGregorian ) 2807cdf0e10cSrcweir { 2808cdf0e10cSrcweir using namespace ::com::sun::star::i18n; 2809cdf0e10cSrcweir ::com::sun::star::uno::Sequence< ::rtl::OUString > xCals 2810cdf0e10cSrcweir = rCal.getAllCalendars( rLoc().getLocale() ); 2811cdf0e10cSrcweir sal_Int32 nCnt = xCals.getLength(); 2812cdf0e10cSrcweir if ( nCnt > 1 ) 2813cdf0e10cSrcweir { 2814cdf0e10cSrcweir for ( sal_Int32 j=0; j < nCnt; j++ ) 2815cdf0e10cSrcweir { 2816cdf0e10cSrcweir if ( xCals[j] != rGregorian ) 2817cdf0e10cSrcweir { 2818cdf0e10cSrcweir if ( !rOrgCalendar.Len() ) 2819cdf0e10cSrcweir { 2820cdf0e10cSrcweir rOrgCalendar = rCal.getUniqueID(); 2821cdf0e10cSrcweir fOrgDateTime = rCal.getDateTime(); 2822cdf0e10cSrcweir } 2823cdf0e10cSrcweir rCal.loadCalendar( xCals[j], rLoc().getLocale() ); 2824cdf0e10cSrcweir rCal.setDateTime( fOrgDateTime ); 2825cdf0e10cSrcweir break; // for 2826cdf0e10cSrcweir } 2827cdf0e10cSrcweir } 2828cdf0e10cSrcweir } 2829cdf0e10cSrcweir } 2830cdf0e10cSrcweir } 2831cdf0e10cSrcweir 2832cdf0e10cSrcweir 2833cdf0e10cSrcweir void SvNumberformat::SwitchToGregorianCalendar( const String& rOrgCalendar, 2834cdf0e10cSrcweir double fOrgDateTime ) const 2835cdf0e10cSrcweir { 2836cdf0e10cSrcweir CalendarWrapper& rCal = GetCal(); 2837cdf0e10cSrcweir const rtl::OUString &rGregorian = Gregorian::get(); 2838cdf0e10cSrcweir if ( rOrgCalendar.Len() && rCal.getUniqueID() != rGregorian ) 2839cdf0e10cSrcweir { 2840cdf0e10cSrcweir rCal.loadCalendar( rGregorian, rLoc().getLocale() ); 2841cdf0e10cSrcweir rCal.setDateTime( fOrgDateTime ); 2842cdf0e10cSrcweir } 2843cdf0e10cSrcweir } 2844cdf0e10cSrcweir 2845cdf0e10cSrcweir 2846cdf0e10cSrcweir sal_Bool SvNumberformat::ImpFallBackToGregorianCalendar( String& rOrgCalendar, double& fOrgDateTime ) 2847cdf0e10cSrcweir { 2848cdf0e10cSrcweir using namespace ::com::sun::star::i18n; 2849cdf0e10cSrcweir CalendarWrapper& rCal = GetCal(); 2850cdf0e10cSrcweir const rtl::OUString &rGregorian = Gregorian::get(); 2851cdf0e10cSrcweir if ( rCal.getUniqueID() != rGregorian ) 2852cdf0e10cSrcweir { 2853cdf0e10cSrcweir sal_Int16 nVal = rCal.getValue( CalendarFieldIndex::ERA ); 2854cdf0e10cSrcweir if ( nVal == 0 && rCal.getLoadedCalendar().Eras[0].ID.equalsAsciiL( 2855cdf0e10cSrcweir RTL_CONSTASCII_STRINGPARAM( "Dummy" ) ) ) 2856cdf0e10cSrcweir { 2857cdf0e10cSrcweir if ( !rOrgCalendar.Len() ) 2858cdf0e10cSrcweir { 2859cdf0e10cSrcweir rOrgCalendar = rCal.getUniqueID(); 2860cdf0e10cSrcweir fOrgDateTime = rCal.getDateTime(); 2861cdf0e10cSrcweir } 2862cdf0e10cSrcweir else if ( rOrgCalendar == String(rGregorian) ) 2863cdf0e10cSrcweir rOrgCalendar.Erase(); 2864cdf0e10cSrcweir rCal.loadCalendar( rGregorian, rLoc().getLocale() ); 2865cdf0e10cSrcweir rCal.setDateTime( fOrgDateTime ); 2866cdf0e10cSrcweir return sal_True; 2867cdf0e10cSrcweir } 2868cdf0e10cSrcweir } 2869cdf0e10cSrcweir return sal_False; 2870cdf0e10cSrcweir } 2871cdf0e10cSrcweir 2872cdf0e10cSrcweir 2873cdf0e10cSrcweir sal_Bool SvNumberformat::ImpSwitchToSpecifiedCalendar( String& rOrgCalendar, 2874cdf0e10cSrcweir double& fOrgDateTime, const ImpSvNumFor& rNumFor ) const 2875cdf0e10cSrcweir { 2876cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = rNumFor.Info(); 2877cdf0e10cSrcweir const sal_uInt16 nAnz = rNumFor.GetnAnz(); 2878cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < nAnz; i++ ) 2879cdf0e10cSrcweir { 2880cdf0e10cSrcweir if ( rInfo.nTypeArray[i] == NF_SYMBOLTYPE_CALENDAR ) 2881cdf0e10cSrcweir { 2882cdf0e10cSrcweir CalendarWrapper& rCal = GetCal(); 2883cdf0e10cSrcweir if ( !rOrgCalendar.Len() ) 2884cdf0e10cSrcweir { 2885cdf0e10cSrcweir rOrgCalendar = rCal.getUniqueID(); 2886cdf0e10cSrcweir fOrgDateTime = rCal.getDateTime(); 2887cdf0e10cSrcweir } 2888cdf0e10cSrcweir rCal.loadCalendar( rInfo.sStrArray[i], rLoc().getLocale() ); 2889cdf0e10cSrcweir rCal.setDateTime( fOrgDateTime ); 2890cdf0e10cSrcweir return sal_True; 2891cdf0e10cSrcweir } 2892cdf0e10cSrcweir } 2893cdf0e10cSrcweir return sal_False; 2894cdf0e10cSrcweir } 2895cdf0e10cSrcweir 2896cdf0e10cSrcweir 2897cdf0e10cSrcweir // static 2898cdf0e10cSrcweir void SvNumberformat::ImpAppendEraG( String& OutString, 2899cdf0e10cSrcweir const CalendarWrapper& rCal, sal_Int16 nNatNum ) 2900cdf0e10cSrcweir { 2901cdf0e10cSrcweir using namespace ::com::sun::star::i18n; 2902cdf0e10cSrcweir if ( rCal.getUniqueID().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "gengou" ) ) ) 2903cdf0e10cSrcweir { 2904cdf0e10cSrcweir sal_Unicode cEra; 2905cdf0e10cSrcweir sal_Int16 nVal = rCal.getValue( CalendarFieldIndex::ERA ); 2906cdf0e10cSrcweir switch ( nVal ) 2907cdf0e10cSrcweir { 2908cdf0e10cSrcweir case 1 : cEra = 'M'; break; 2909cdf0e10cSrcweir case 2 : cEra = 'T'; break; 2910cdf0e10cSrcweir case 3 : cEra = 'S'; break; 2911cdf0e10cSrcweir case 4 : cEra = 'H'; break; 2912cdf0e10cSrcweir default: 2913cdf0e10cSrcweir cEra = '?'; 2914cdf0e10cSrcweir } 2915cdf0e10cSrcweir OutString += cEra; 2916cdf0e10cSrcweir } 2917cdf0e10cSrcweir else 2918cdf0e10cSrcweir OutString += rCal.getDisplayString( CalendarDisplayCode::SHORT_ERA, nNatNum ); 2919cdf0e10cSrcweir } 2920cdf0e10cSrcweir 2921cdf0e10cSrcweir 2922cdf0e10cSrcweir sal_Bool SvNumberformat::ImpGetDateOutput(double fNumber, 2923cdf0e10cSrcweir sal_uInt16 nIx, 2924cdf0e10cSrcweir String& OutString) 2925cdf0e10cSrcweir { 2926cdf0e10cSrcweir using namespace ::com::sun::star::i18n; 2927cdf0e10cSrcweir sal_Bool bRes = sal_False; 2928cdf0e10cSrcweir CalendarWrapper& rCal = GetCal(); 2929cdf0e10cSrcweir double fDiff = DateTime(*(rScan.GetNullDate())) - rCal.getEpochStart(); 2930cdf0e10cSrcweir fNumber += fDiff; 2931cdf0e10cSrcweir rCal.setLocalDateTime( fNumber ); 2932cdf0e10cSrcweir String aOrgCalendar; // empty => not changed yet 2933cdf0e10cSrcweir double fOrgDateTime; 2934cdf0e10cSrcweir sal_Bool bOtherCalendar = ImpIsOtherCalendar( NumFor[nIx] ); 2935cdf0e10cSrcweir if ( bOtherCalendar ) 2936cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 2937cdf0e10cSrcweir if ( ImpFallBackToGregorianCalendar( aOrgCalendar, fOrgDateTime ) ) 2938cdf0e10cSrcweir bOtherCalendar = sal_False; 2939cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); 2940cdf0e10cSrcweir const sal_uInt16 nAnz = NumFor[nIx].GetnAnz(); 2941cdf0e10cSrcweir sal_Int16 nNatNum = NumFor[nIx].GetNatNum().GetNatNum(); 2942cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nAnz; i++) 2943cdf0e10cSrcweir { 2944cdf0e10cSrcweir switch (rInfo.nTypeArray[i]) 2945cdf0e10cSrcweir { 2946cdf0e10cSrcweir case NF_SYMBOLTYPE_CALENDAR : 2947cdf0e10cSrcweir if ( !aOrgCalendar.Len() ) 2948cdf0e10cSrcweir { 2949cdf0e10cSrcweir aOrgCalendar = rCal.getUniqueID(); 2950cdf0e10cSrcweir fOrgDateTime = rCal.getDateTime(); 2951cdf0e10cSrcweir } 2952cdf0e10cSrcweir rCal.loadCalendar( rInfo.sStrArray[i], rLoc().getLocale() ); 2953cdf0e10cSrcweir rCal.setDateTime( fOrgDateTime ); 2954cdf0e10cSrcweir ImpFallBackToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 2955cdf0e10cSrcweir break; 2956cdf0e10cSrcweir case NF_SYMBOLTYPE_STAR: 2957cdf0e10cSrcweir if( bStarFlag ) 2958cdf0e10cSrcweir { 2959cdf0e10cSrcweir OutString += (sal_Unicode) 0x1B; 2960cdf0e10cSrcweir OutString += rInfo.sStrArray[i].GetChar(1); 2961cdf0e10cSrcweir bRes = sal_True; 2962cdf0e10cSrcweir } 2963cdf0e10cSrcweir break; 2964cdf0e10cSrcweir case NF_SYMBOLTYPE_BLANK: 2965cdf0e10cSrcweir InsertBlanks( OutString, OutString.Len(), 2966cdf0e10cSrcweir rInfo.sStrArray[i].GetChar(1) ); 2967cdf0e10cSrcweir break; 2968cdf0e10cSrcweir case NF_SYMBOLTYPE_STRING: 2969cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRENCY: 2970cdf0e10cSrcweir case NF_SYMBOLTYPE_DATESEP: 2971cdf0e10cSrcweir case NF_SYMBOLTYPE_TIMESEP: 2972cdf0e10cSrcweir case NF_SYMBOLTYPE_TIME100SECSEP: 2973cdf0e10cSrcweir OutString += rInfo.sStrArray[i]; 2974cdf0e10cSrcweir break; 2975cdf0e10cSrcweir case NF_KEY_M: // M 2976cdf0e10cSrcweir OutString += rCal.getDisplayString( 2977cdf0e10cSrcweir CalendarDisplayCode::SHORT_MONTH, nNatNum ); 2978cdf0e10cSrcweir break; 2979cdf0e10cSrcweir case NF_KEY_MM: // MM 2980cdf0e10cSrcweir OutString += rCal.getDisplayString( 2981cdf0e10cSrcweir CalendarDisplayCode::LONG_MONTH, nNatNum ); 2982cdf0e10cSrcweir break; 2983cdf0e10cSrcweir case NF_KEY_MMM: // MMM 2984cdf0e10cSrcweir OutString += rCal.getDisplayString( 2985cdf0e10cSrcweir CalendarDisplayCode::SHORT_MONTH_NAME, nNatNum ); 2986cdf0e10cSrcweir break; 2987cdf0e10cSrcweir case NF_KEY_MMMM: // MMMM 2988cdf0e10cSrcweir OutString += rCal.getDisplayString( 2989cdf0e10cSrcweir CalendarDisplayCode::LONG_MONTH_NAME, nNatNum ); 2990cdf0e10cSrcweir break; 2991cdf0e10cSrcweir case NF_KEY_MMMMM: // MMMMM 2992cdf0e10cSrcweir OutString += rCal.getDisplayString( 2993cdf0e10cSrcweir CalendarDisplayCode::LONG_MONTH_NAME, nNatNum ).GetChar(0); 2994cdf0e10cSrcweir break; 2995cdf0e10cSrcweir case NF_KEY_Q: // Q 2996cdf0e10cSrcweir OutString += rCal.getDisplayString( 2997cdf0e10cSrcweir CalendarDisplayCode::SHORT_QUARTER, nNatNum ); 2998cdf0e10cSrcweir break; 2999cdf0e10cSrcweir case NF_KEY_QQ: // QQ 3000cdf0e10cSrcweir OutString += rCal.getDisplayString( 3001cdf0e10cSrcweir CalendarDisplayCode::LONG_QUARTER, nNatNum ); 3002cdf0e10cSrcweir break; 3003cdf0e10cSrcweir case NF_KEY_D: // D 3004cdf0e10cSrcweir OutString += rCal.getDisplayString( 3005cdf0e10cSrcweir CalendarDisplayCode::SHORT_DAY, nNatNum ); 3006cdf0e10cSrcweir break; 3007cdf0e10cSrcweir case NF_KEY_DD: // DD 3008cdf0e10cSrcweir OutString += rCal.getDisplayString( 3009cdf0e10cSrcweir CalendarDisplayCode::LONG_DAY, nNatNum ); 3010cdf0e10cSrcweir break; 3011cdf0e10cSrcweir case NF_KEY_DDD: // DDD 3012cdf0e10cSrcweir { 3013cdf0e10cSrcweir if ( bOtherCalendar ) 3014cdf0e10cSrcweir SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 3015cdf0e10cSrcweir OutString += rCal.getDisplayString( 3016cdf0e10cSrcweir CalendarDisplayCode::SHORT_DAY_NAME, nNatNum ); 3017cdf0e10cSrcweir if ( bOtherCalendar ) 3018cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 3019cdf0e10cSrcweir } 3020cdf0e10cSrcweir break; 3021cdf0e10cSrcweir case NF_KEY_DDDD: // DDDD 3022cdf0e10cSrcweir { 3023cdf0e10cSrcweir if ( bOtherCalendar ) 3024cdf0e10cSrcweir SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 3025cdf0e10cSrcweir OutString += rCal.getDisplayString( 3026cdf0e10cSrcweir CalendarDisplayCode::LONG_DAY_NAME, nNatNum ); 3027cdf0e10cSrcweir if ( bOtherCalendar ) 3028cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 3029cdf0e10cSrcweir } 3030cdf0e10cSrcweir break; 3031cdf0e10cSrcweir case NF_KEY_YY: // YY 3032cdf0e10cSrcweir { 3033cdf0e10cSrcweir if ( bOtherCalendar ) 3034cdf0e10cSrcweir SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 3035cdf0e10cSrcweir OutString += rCal.getDisplayString( 3036cdf0e10cSrcweir CalendarDisplayCode::SHORT_YEAR, nNatNum ); 3037cdf0e10cSrcweir if ( bOtherCalendar ) 3038cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 3039cdf0e10cSrcweir } 3040cdf0e10cSrcweir break; 3041cdf0e10cSrcweir case NF_KEY_YYYY: // YYYY 3042cdf0e10cSrcweir { 3043cdf0e10cSrcweir if ( bOtherCalendar ) 3044cdf0e10cSrcweir SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 3045cdf0e10cSrcweir OutString += rCal.getDisplayString( 3046cdf0e10cSrcweir CalendarDisplayCode::LONG_YEAR, nNatNum ); 3047cdf0e10cSrcweir if ( bOtherCalendar ) 3048cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 3049cdf0e10cSrcweir } 3050cdf0e10cSrcweir break; 3051cdf0e10cSrcweir case NF_KEY_EC: // E 3052cdf0e10cSrcweir OutString += rCal.getDisplayString( 3053cdf0e10cSrcweir CalendarDisplayCode::SHORT_YEAR, nNatNum ); 3054cdf0e10cSrcweir break; 3055cdf0e10cSrcweir case NF_KEY_EEC: // EE 3056cdf0e10cSrcweir case NF_KEY_R: // R 3057cdf0e10cSrcweir OutString += rCal.getDisplayString( 3058cdf0e10cSrcweir CalendarDisplayCode::LONG_YEAR, nNatNum ); 3059cdf0e10cSrcweir break; 3060cdf0e10cSrcweir case NF_KEY_NN: // NN 3061cdf0e10cSrcweir case NF_KEY_AAA: // AAA 3062cdf0e10cSrcweir OutString += rCal.getDisplayString( 3063cdf0e10cSrcweir CalendarDisplayCode::SHORT_DAY_NAME, nNatNum ); 3064cdf0e10cSrcweir break; 3065cdf0e10cSrcweir case NF_KEY_NNN: // NNN 3066cdf0e10cSrcweir case NF_KEY_AAAA: // AAAA 3067cdf0e10cSrcweir OutString += rCal.getDisplayString( 3068cdf0e10cSrcweir CalendarDisplayCode::LONG_DAY_NAME, nNatNum ); 3069cdf0e10cSrcweir break; 3070cdf0e10cSrcweir case NF_KEY_NNNN: // NNNN 3071cdf0e10cSrcweir { 3072cdf0e10cSrcweir OutString += rCal.getDisplayString( 3073cdf0e10cSrcweir CalendarDisplayCode::LONG_DAY_NAME, nNatNum ); 3074cdf0e10cSrcweir OutString += rLoc().getLongDateDayOfWeekSep(); 3075cdf0e10cSrcweir } 3076cdf0e10cSrcweir break; 3077cdf0e10cSrcweir case NF_KEY_WW : // WW 3078cdf0e10cSrcweir { 3079cdf0e10cSrcweir sal_Int16 nVal = rCal.getValue( CalendarFieldIndex::WEEK_OF_YEAR ); 3080cdf0e10cSrcweir OutString += ImpIntToString( nIx, nVal ); 3081cdf0e10cSrcweir } 3082cdf0e10cSrcweir break; 3083cdf0e10cSrcweir case NF_KEY_G: // G 3084cdf0e10cSrcweir ImpAppendEraG( OutString, rCal, nNatNum ); 3085cdf0e10cSrcweir break; 3086cdf0e10cSrcweir case NF_KEY_GG: // GG 3087cdf0e10cSrcweir OutString += rCal.getDisplayString( 3088cdf0e10cSrcweir CalendarDisplayCode::SHORT_ERA, nNatNum ); 3089cdf0e10cSrcweir break; 3090cdf0e10cSrcweir case NF_KEY_GGG: // GGG 3091cdf0e10cSrcweir OutString += rCal.getDisplayString( 3092cdf0e10cSrcweir CalendarDisplayCode::LONG_ERA, nNatNum ); 3093cdf0e10cSrcweir break; 3094cdf0e10cSrcweir case NF_KEY_RR: // RR => GGGEE 3095cdf0e10cSrcweir OutString += rCal.getDisplayString( 3096cdf0e10cSrcweir CalendarDisplayCode::LONG_YEAR_AND_ERA, nNatNum ); 3097cdf0e10cSrcweir break; 3098cdf0e10cSrcweir } 3099cdf0e10cSrcweir } 3100cdf0e10cSrcweir if ( aOrgCalendar.Len() ) 3101cdf0e10cSrcweir rCal.loadCalendar( aOrgCalendar, rLoc().getLocale() ); // restore calendar 3102cdf0e10cSrcweir return bRes; 3103cdf0e10cSrcweir } 3104cdf0e10cSrcweir 3105cdf0e10cSrcweir sal_Bool SvNumberformat::ImpGetDateTimeOutput(double fNumber, 3106cdf0e10cSrcweir sal_uInt16 nIx, 3107cdf0e10cSrcweir String& OutString) 3108cdf0e10cSrcweir { 3109cdf0e10cSrcweir using namespace ::com::sun::star::i18n; 3110cdf0e10cSrcweir sal_Bool bRes = sal_False; 3111cdf0e10cSrcweir 3112cdf0e10cSrcweir CalendarWrapper& rCal = GetCal(); 3113cdf0e10cSrcweir double fDiff = DateTime(*(rScan.GetNullDate())) - rCal.getEpochStart(); 3114cdf0e10cSrcweir fNumber += fDiff; 3115cdf0e10cSrcweir 3116cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); 3117cdf0e10cSrcweir sal_Bool bInputLine; 3118cdf0e10cSrcweir xub_StrLen nCntPost; 3119cdf0e10cSrcweir if ( rScan.GetStandardPrec() == 300 && 3120cdf0e10cSrcweir 0 < rInfo.nCntPost && rInfo.nCntPost < 7 ) 3121cdf0e10cSrcweir { // round at 7 decimals (+5 of 86400 == 12 significant digits) 3122cdf0e10cSrcweir bInputLine = sal_True; 3123cdf0e10cSrcweir nCntPost = 7; 3124cdf0e10cSrcweir } 3125cdf0e10cSrcweir else 3126cdf0e10cSrcweir { 3127cdf0e10cSrcweir bInputLine = sal_False; 3128cdf0e10cSrcweir nCntPost = xub_StrLen(rInfo.nCntPost); 3129cdf0e10cSrcweir } 3130cdf0e10cSrcweir double fTime = (fNumber - floor( fNumber )) * 86400.0; 3131cdf0e10cSrcweir fTime = ::rtl::math::round( fTime, int(nCntPost) ); 3132cdf0e10cSrcweir if (fTime >= 86400.0) 3133cdf0e10cSrcweir { 3134cdf0e10cSrcweir // result of fNumber==x.999999999... rounded up, use correct date/time 3135cdf0e10cSrcweir fTime -= 86400.0; 3136cdf0e10cSrcweir fNumber = floor( fNumber + 0.5) + fTime; 3137cdf0e10cSrcweir } 3138cdf0e10cSrcweir rCal.setLocalDateTime( fNumber ); 3139cdf0e10cSrcweir 3140cdf0e10cSrcweir String aOrgCalendar; // empty => not changed yet 3141cdf0e10cSrcweir double fOrgDateTime; 3142cdf0e10cSrcweir sal_Bool bOtherCalendar = ImpIsOtherCalendar( NumFor[nIx] ); 3143cdf0e10cSrcweir if ( bOtherCalendar ) 3144cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 3145cdf0e10cSrcweir if ( ImpFallBackToGregorianCalendar( aOrgCalendar, fOrgDateTime ) ) 3146cdf0e10cSrcweir bOtherCalendar = sal_False; 3147cdf0e10cSrcweir sal_Int16 nNatNum = NumFor[nIx].GetNatNum().GetNatNum(); 3148cdf0e10cSrcweir 3149cdf0e10cSrcweir sal_uLong nSeconds = (sal_uLong)floor( fTime ); 3150cdf0e10cSrcweir String sSecStr( ::rtl::math::doubleToUString( fTime-nSeconds, 3151cdf0e10cSrcweir rtl_math_StringFormat_F, int(nCntPost), '.')); 3152cdf0e10cSrcweir sSecStr.EraseLeadingChars('0'); 3153cdf0e10cSrcweir sSecStr.EraseLeadingChars('.'); 3154cdf0e10cSrcweir if ( bInputLine ) 3155cdf0e10cSrcweir { 3156cdf0e10cSrcweir sSecStr.EraseTrailingChars('0'); 3157cdf0e10cSrcweir if ( sSecStr.Len() < xub_StrLen(rInfo.nCntPost) ) 3158cdf0e10cSrcweir sSecStr.Expand( xub_StrLen(rInfo.nCntPost), '0' ); 3159cdf0e10cSrcweir ImpTransliterate( sSecStr, NumFor[nIx].GetNatNum() ); 3160cdf0e10cSrcweir nCntPost = sSecStr.Len(); 3161cdf0e10cSrcweir } 3162cdf0e10cSrcweir else 3163cdf0e10cSrcweir ImpTransliterate( sSecStr, NumFor[nIx].GetNatNum() ); 3164cdf0e10cSrcweir 3165cdf0e10cSrcweir xub_StrLen nSecPos = 0; // Zum Ziffernweisen 3166cdf0e10cSrcweir // abarbeiten 3167cdf0e10cSrcweir sal_uLong nHour, nMin, nSec; 3168cdf0e10cSrcweir if (!rInfo.bThousand) // [] Format 3169cdf0e10cSrcweir { 3170cdf0e10cSrcweir nHour = (nSeconds/3600) % 24; 3171cdf0e10cSrcweir nMin = (nSeconds%3600) / 60; 3172cdf0e10cSrcweir nSec = nSeconds%60; 3173cdf0e10cSrcweir } 3174cdf0e10cSrcweir else if (rInfo.nThousand == 3) // [ss] 3175cdf0e10cSrcweir { 3176cdf0e10cSrcweir nHour = 0; 3177cdf0e10cSrcweir nMin = 0; 3178cdf0e10cSrcweir nSec = nSeconds; 3179cdf0e10cSrcweir } 3180cdf0e10cSrcweir else if (rInfo.nThousand == 2) // [mm]:ss 3181cdf0e10cSrcweir { 3182cdf0e10cSrcweir nHour = 0; 3183cdf0e10cSrcweir nMin = nSeconds / 60; 3184cdf0e10cSrcweir nSec = nSeconds % 60; 3185cdf0e10cSrcweir } 3186cdf0e10cSrcweir else if (rInfo.nThousand == 1) // [hh]:mm:ss 3187cdf0e10cSrcweir { 3188cdf0e10cSrcweir nHour = nSeconds / 3600; 3189cdf0e10cSrcweir nMin = (nSeconds%3600) / 60; 3190cdf0e10cSrcweir nSec = nSeconds%60; 3191cdf0e10cSrcweir } 3192cdf0e10cSrcweir else { 3193cdf0e10cSrcweir nHour = 0; // TODO What should these values be? 3194cdf0e10cSrcweir nMin = 0; 3195cdf0e10cSrcweir nSec = 0; 3196cdf0e10cSrcweir } 3197cdf0e10cSrcweir sal_Unicode cAmPm = ' '; // a oder p 3198cdf0e10cSrcweir if (rInfo.nCntExp) // AM/PM 3199cdf0e10cSrcweir { 3200cdf0e10cSrcweir if (nHour == 0) 3201cdf0e10cSrcweir { 3202cdf0e10cSrcweir nHour = 12; 3203cdf0e10cSrcweir cAmPm = 'a'; 3204cdf0e10cSrcweir } 3205cdf0e10cSrcweir else if (nHour < 12) 3206cdf0e10cSrcweir cAmPm = 'a'; 3207cdf0e10cSrcweir else 3208cdf0e10cSrcweir { 3209cdf0e10cSrcweir cAmPm = 'p'; 3210cdf0e10cSrcweir if (nHour > 12) 3211cdf0e10cSrcweir nHour -= 12; 3212cdf0e10cSrcweir } 3213cdf0e10cSrcweir } 3214cdf0e10cSrcweir const sal_uInt16 nAnz = NumFor[nIx].GetnAnz(); 3215cdf0e10cSrcweir for (sal_uInt16 i = 0; i < nAnz; i++) 3216cdf0e10cSrcweir { 3217cdf0e10cSrcweir switch (rInfo.nTypeArray[i]) 3218cdf0e10cSrcweir { 3219cdf0e10cSrcweir case NF_SYMBOLTYPE_CALENDAR : 3220cdf0e10cSrcweir if ( !aOrgCalendar.Len() ) 3221cdf0e10cSrcweir { 3222cdf0e10cSrcweir aOrgCalendar = rCal.getUniqueID(); 3223cdf0e10cSrcweir fOrgDateTime = rCal.getDateTime(); 3224cdf0e10cSrcweir } 3225cdf0e10cSrcweir rCal.loadCalendar( rInfo.sStrArray[i], rLoc().getLocale() ); 3226cdf0e10cSrcweir rCal.setDateTime( fOrgDateTime ); 3227cdf0e10cSrcweir ImpFallBackToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 3228cdf0e10cSrcweir break; 3229cdf0e10cSrcweir case NF_SYMBOLTYPE_STAR: 3230cdf0e10cSrcweir if( bStarFlag ) 3231cdf0e10cSrcweir { 3232cdf0e10cSrcweir OutString += (sal_Unicode) 0x1B; 3233cdf0e10cSrcweir OutString += rInfo.sStrArray[i].GetChar(1); 3234cdf0e10cSrcweir bRes = sal_True; 3235cdf0e10cSrcweir } 3236cdf0e10cSrcweir break; 3237cdf0e10cSrcweir case NF_SYMBOLTYPE_BLANK: 3238cdf0e10cSrcweir InsertBlanks( OutString, OutString.Len(), 3239cdf0e10cSrcweir rInfo.sStrArray[i].GetChar(1) ); 3240cdf0e10cSrcweir break; 3241cdf0e10cSrcweir case NF_SYMBOLTYPE_STRING: 3242cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRENCY: 3243cdf0e10cSrcweir case NF_SYMBOLTYPE_DATESEP: 3244cdf0e10cSrcweir case NF_SYMBOLTYPE_TIMESEP: 3245cdf0e10cSrcweir case NF_SYMBOLTYPE_TIME100SECSEP: 3246cdf0e10cSrcweir OutString += rInfo.sStrArray[i]; 3247cdf0e10cSrcweir break; 3248cdf0e10cSrcweir case NF_SYMBOLTYPE_DIGIT: 3249cdf0e10cSrcweir { 3250cdf0e10cSrcweir xub_StrLen nLen = ( bInputLine && i > 0 && 3251cdf0e10cSrcweir (rInfo.nTypeArray[i-1] == NF_SYMBOLTYPE_STRING || 3252cdf0e10cSrcweir rInfo.nTypeArray[i-1] == NF_SYMBOLTYPE_TIME100SECSEP) ? 3253cdf0e10cSrcweir nCntPost : rInfo.sStrArray[i].Len() ); 3254cdf0e10cSrcweir for (xub_StrLen j = 0; j < nLen && nSecPos < nCntPost; j++) 3255cdf0e10cSrcweir { 3256cdf0e10cSrcweir OutString += sSecStr.GetChar(nSecPos); 3257cdf0e10cSrcweir nSecPos++; 3258cdf0e10cSrcweir } 3259cdf0e10cSrcweir } 3260cdf0e10cSrcweir break; 3261cdf0e10cSrcweir case NF_KEY_AMPM: // AM/PM 3262cdf0e10cSrcweir { 3263cdf0e10cSrcweir if (cAmPm == 'a') 3264cdf0e10cSrcweir OutString += rCal.getDisplayName( CalendarDisplayIndex::AM_PM, 3265cdf0e10cSrcweir AmPmValue::AM, 0 ); 3266cdf0e10cSrcweir else 3267cdf0e10cSrcweir OutString += rCal.getDisplayName( CalendarDisplayIndex::AM_PM, 3268cdf0e10cSrcweir AmPmValue::PM, 0 ); 3269cdf0e10cSrcweir } 3270cdf0e10cSrcweir break; 3271cdf0e10cSrcweir case NF_KEY_AP: // A/P 3272cdf0e10cSrcweir { 3273cdf0e10cSrcweir if (cAmPm == 'a') 3274cdf0e10cSrcweir OutString += 'a'; 3275cdf0e10cSrcweir else 3276cdf0e10cSrcweir OutString += 'p'; 3277cdf0e10cSrcweir } 3278cdf0e10cSrcweir break; 3279cdf0e10cSrcweir case NF_KEY_MI: // M 3280cdf0e10cSrcweir OutString += ImpIntToString( nIx, nMin ); 3281cdf0e10cSrcweir break; 3282cdf0e10cSrcweir case NF_KEY_MMI: // MM 3283cdf0e10cSrcweir OutString += ImpIntToString( nIx, nMin, 2 ); 3284cdf0e10cSrcweir break; 3285cdf0e10cSrcweir case NF_KEY_H: // H 3286cdf0e10cSrcweir OutString += ImpIntToString( nIx, nHour ); 3287cdf0e10cSrcweir break; 3288cdf0e10cSrcweir case NF_KEY_HH: // HH 3289cdf0e10cSrcweir OutString += ImpIntToString( nIx, nHour, 2 ); 3290cdf0e10cSrcweir break; 3291cdf0e10cSrcweir case NF_KEY_S: // S 3292cdf0e10cSrcweir OutString += ImpIntToString( nIx, nSec ); 3293cdf0e10cSrcweir break; 3294cdf0e10cSrcweir case NF_KEY_SS: // SS 3295cdf0e10cSrcweir OutString += ImpIntToString( nIx, nSec, 2 ); 3296cdf0e10cSrcweir break; 3297cdf0e10cSrcweir case NF_KEY_M: // M 3298cdf0e10cSrcweir OutString += rCal.getDisplayString( 3299cdf0e10cSrcweir CalendarDisplayCode::SHORT_MONTH, nNatNum ); 3300cdf0e10cSrcweir break; 3301cdf0e10cSrcweir case NF_KEY_MM: // MM 3302cdf0e10cSrcweir OutString += rCal.getDisplayString( 3303cdf0e10cSrcweir CalendarDisplayCode::LONG_MONTH, nNatNum ); 3304cdf0e10cSrcweir break; 3305cdf0e10cSrcweir case NF_KEY_MMM: // MMM 3306cdf0e10cSrcweir OutString += rCal.getDisplayString( 3307cdf0e10cSrcweir CalendarDisplayCode::SHORT_MONTH_NAME, nNatNum ); 3308cdf0e10cSrcweir break; 3309cdf0e10cSrcweir case NF_KEY_MMMM: // MMMM 3310cdf0e10cSrcweir OutString += rCal.getDisplayString( 3311cdf0e10cSrcweir CalendarDisplayCode::LONG_MONTH_NAME, nNatNum ); 3312cdf0e10cSrcweir break; 3313cdf0e10cSrcweir case NF_KEY_MMMMM: // MMMMM 3314cdf0e10cSrcweir OutString += rCal.getDisplayString( 3315cdf0e10cSrcweir CalendarDisplayCode::LONG_MONTH_NAME, nNatNum ).GetChar(0); 3316cdf0e10cSrcweir break; 3317cdf0e10cSrcweir case NF_KEY_Q: // Q 3318cdf0e10cSrcweir OutString += rCal.getDisplayString( 3319cdf0e10cSrcweir CalendarDisplayCode::SHORT_QUARTER, nNatNum ); 3320cdf0e10cSrcweir break; 3321cdf0e10cSrcweir case NF_KEY_QQ: // QQ 3322cdf0e10cSrcweir OutString += rCal.getDisplayString( 3323cdf0e10cSrcweir CalendarDisplayCode::LONG_QUARTER, nNatNum ); 3324cdf0e10cSrcweir break; 3325cdf0e10cSrcweir case NF_KEY_D: // D 3326cdf0e10cSrcweir OutString += rCal.getDisplayString( 3327cdf0e10cSrcweir CalendarDisplayCode::SHORT_DAY, nNatNum ); 3328cdf0e10cSrcweir break; 3329cdf0e10cSrcweir case NF_KEY_DD: // DD 3330cdf0e10cSrcweir OutString += rCal.getDisplayString( 3331cdf0e10cSrcweir CalendarDisplayCode::LONG_DAY, nNatNum ); 3332cdf0e10cSrcweir break; 3333cdf0e10cSrcweir case NF_KEY_DDD: // DDD 3334cdf0e10cSrcweir { 3335cdf0e10cSrcweir if ( bOtherCalendar ) 3336cdf0e10cSrcweir SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 3337cdf0e10cSrcweir OutString += rCal.getDisplayString( 3338cdf0e10cSrcweir CalendarDisplayCode::SHORT_DAY_NAME, nNatNum ); 3339cdf0e10cSrcweir if ( bOtherCalendar ) 3340cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 3341cdf0e10cSrcweir } 3342cdf0e10cSrcweir break; 3343cdf0e10cSrcweir case NF_KEY_DDDD: // DDDD 3344cdf0e10cSrcweir { 3345cdf0e10cSrcweir if ( bOtherCalendar ) 3346cdf0e10cSrcweir SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 3347cdf0e10cSrcweir OutString += rCal.getDisplayString( 3348cdf0e10cSrcweir CalendarDisplayCode::LONG_DAY_NAME, nNatNum ); 3349cdf0e10cSrcweir if ( bOtherCalendar ) 3350cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 3351cdf0e10cSrcweir } 3352cdf0e10cSrcweir break; 3353cdf0e10cSrcweir case NF_KEY_YY: // YY 3354cdf0e10cSrcweir { 3355cdf0e10cSrcweir if ( bOtherCalendar ) 3356cdf0e10cSrcweir SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 3357cdf0e10cSrcweir OutString += rCal.getDisplayString( 3358cdf0e10cSrcweir CalendarDisplayCode::SHORT_YEAR, nNatNum ); 3359cdf0e10cSrcweir if ( bOtherCalendar ) 3360cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 3361cdf0e10cSrcweir } 3362cdf0e10cSrcweir break; 3363cdf0e10cSrcweir case NF_KEY_YYYY: // YYYY 3364cdf0e10cSrcweir { 3365cdf0e10cSrcweir if ( bOtherCalendar ) 3366cdf0e10cSrcweir SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); 3367cdf0e10cSrcweir OutString += rCal.getDisplayString( 3368cdf0e10cSrcweir CalendarDisplayCode::LONG_YEAR, nNatNum ); 3369cdf0e10cSrcweir if ( bOtherCalendar ) 3370cdf0e10cSrcweir SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); 3371cdf0e10cSrcweir } 3372cdf0e10cSrcweir break; 3373cdf0e10cSrcweir case NF_KEY_EC: // E 3374cdf0e10cSrcweir OutString += rCal.getDisplayString( 3375cdf0e10cSrcweir CalendarDisplayCode::SHORT_YEAR, nNatNum ); 3376cdf0e10cSrcweir break; 3377cdf0e10cSrcweir case NF_KEY_EEC: // EE 3378cdf0e10cSrcweir case NF_KEY_R: // R 3379cdf0e10cSrcweir OutString += rCal.getDisplayString( 3380cdf0e10cSrcweir CalendarDisplayCode::LONG_YEAR, nNatNum ); 3381cdf0e10cSrcweir break; 3382cdf0e10cSrcweir case NF_KEY_NN: // NN 3383cdf0e10cSrcweir case NF_KEY_AAA: // AAA 3384cdf0e10cSrcweir OutString += rCal.getDisplayString( 3385cdf0e10cSrcweir CalendarDisplayCode::SHORT_DAY_NAME, nNatNum ); 3386cdf0e10cSrcweir break; 3387cdf0e10cSrcweir case NF_KEY_NNN: // NNN 3388cdf0e10cSrcweir case NF_KEY_AAAA: // AAAA 3389cdf0e10cSrcweir OutString += rCal.getDisplayString( 3390cdf0e10cSrcweir CalendarDisplayCode::LONG_DAY_NAME, nNatNum ); 3391cdf0e10cSrcweir break; 3392cdf0e10cSrcweir case NF_KEY_NNNN: // NNNN 3393cdf0e10cSrcweir { 3394cdf0e10cSrcweir OutString += rCal.getDisplayString( 3395cdf0e10cSrcweir CalendarDisplayCode::LONG_DAY_NAME, nNatNum ); 3396cdf0e10cSrcweir OutString += rLoc().getLongDateDayOfWeekSep(); 3397cdf0e10cSrcweir } 3398cdf0e10cSrcweir break; 3399cdf0e10cSrcweir case NF_KEY_WW : // WW 3400cdf0e10cSrcweir { 3401cdf0e10cSrcweir sal_Int16 nVal = rCal.getValue( CalendarFieldIndex::WEEK_OF_YEAR ); 3402cdf0e10cSrcweir OutString += ImpIntToString( nIx, nVal ); 3403cdf0e10cSrcweir } 3404cdf0e10cSrcweir break; 3405cdf0e10cSrcweir case NF_KEY_G: // G 3406cdf0e10cSrcweir ImpAppendEraG( OutString, rCal, nNatNum ); 3407cdf0e10cSrcweir break; 3408cdf0e10cSrcweir case NF_KEY_GG: // GG 3409cdf0e10cSrcweir OutString += rCal.getDisplayString( 3410cdf0e10cSrcweir CalendarDisplayCode::SHORT_ERA, nNatNum ); 3411cdf0e10cSrcweir break; 3412cdf0e10cSrcweir case NF_KEY_GGG: // GGG 3413cdf0e10cSrcweir OutString += rCal.getDisplayString( 3414cdf0e10cSrcweir CalendarDisplayCode::LONG_ERA, nNatNum ); 3415cdf0e10cSrcweir break; 3416cdf0e10cSrcweir case NF_KEY_RR: // RR => GGGEE 3417cdf0e10cSrcweir OutString += rCal.getDisplayString( 3418cdf0e10cSrcweir CalendarDisplayCode::LONG_YEAR_AND_ERA, nNatNum ); 3419cdf0e10cSrcweir break; 3420cdf0e10cSrcweir } 3421cdf0e10cSrcweir } 3422cdf0e10cSrcweir if ( aOrgCalendar.Len() ) 3423cdf0e10cSrcweir rCal.loadCalendar( aOrgCalendar, rLoc().getLocale() ); // restore calendar 3424cdf0e10cSrcweir return bRes; 3425cdf0e10cSrcweir } 3426cdf0e10cSrcweir 3427cdf0e10cSrcweir sal_Bool SvNumberformat::ImpGetNumberOutput(double fNumber, 3428cdf0e10cSrcweir sal_uInt16 nIx, 3429cdf0e10cSrcweir String& OutString) 3430cdf0e10cSrcweir { 3431cdf0e10cSrcweir sal_Bool bRes = sal_False; 3432cdf0e10cSrcweir sal_Bool bSign; 3433cdf0e10cSrcweir if (fNumber < 0.0) 3434cdf0e10cSrcweir { 3435cdf0e10cSrcweir if (nIx == 0) // nicht in hinteren 3436cdf0e10cSrcweir bSign = sal_True; // Formaten 3437cdf0e10cSrcweir else 3438cdf0e10cSrcweir bSign = sal_False; 3439cdf0e10cSrcweir fNumber = -fNumber; 3440cdf0e10cSrcweir } 3441cdf0e10cSrcweir else 3442cdf0e10cSrcweir { 3443cdf0e10cSrcweir bSign = sal_False; 3444cdf0e10cSrcweir if ( ::rtl::math::isSignBitSet( fNumber ) ) 3445cdf0e10cSrcweir fNumber = -fNumber; // yes, -0.0 is possible, eliminate '-' 3446cdf0e10cSrcweir } 3447cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); 3448cdf0e10cSrcweir if (rInfo.eScannedType == NUMBERFORMAT_PERCENT) 3449cdf0e10cSrcweir { 3450cdf0e10cSrcweir if (fNumber < _D_MAX_D_BY_100) 3451cdf0e10cSrcweir fNumber *= 100.0; 3452cdf0e10cSrcweir else 3453cdf0e10cSrcweir { 3454cdf0e10cSrcweir OutString = rScan.GetErrorString(); 3455cdf0e10cSrcweir return sal_False; 3456cdf0e10cSrcweir } 3457cdf0e10cSrcweir } 3458cdf0e10cSrcweir sal_uInt16 i, j; 3459cdf0e10cSrcweir xub_StrLen k; 3460cdf0e10cSrcweir String sStr; 3461cdf0e10cSrcweir long nPrecExp; 3462cdf0e10cSrcweir sal_Bool bInteger = sal_False; 3463cdf0e10cSrcweir if ( rInfo.nThousand != FLAG_STANDARD_IN_FORMAT ) 3464cdf0e10cSrcweir { // special formatting only if no GENERAL keyword in format code 3465cdf0e10cSrcweir const sal_uInt16 nThousand = rInfo.nThousand; 3466cdf0e10cSrcweir for (i = 0; i < nThousand; i++) 3467cdf0e10cSrcweir { 3468cdf0e10cSrcweir if (fNumber > _D_MIN_M_BY_1000) 3469cdf0e10cSrcweir fNumber /= 1000.0; 3470cdf0e10cSrcweir else 3471cdf0e10cSrcweir fNumber = 0.0; 3472cdf0e10cSrcweir } 3473cdf0e10cSrcweir if (fNumber > 0.0) 3474cdf0e10cSrcweir nPrecExp = GetPrecExp( fNumber ); 3475cdf0e10cSrcweir else 3476cdf0e10cSrcweir nPrecExp = 0; 3477cdf0e10cSrcweir if (rInfo.nCntPost) // NachkommaStellen 3478cdf0e10cSrcweir { 3479cdf0e10cSrcweir if (rInfo.nCntPost + nPrecExp > 15 && nPrecExp < 15) 3480cdf0e10cSrcweir { 3481cdf0e10cSrcweir sStr = ::rtl::math::doubleToUString( fNumber, 3482cdf0e10cSrcweir rtl_math_StringFormat_F, 15-nPrecExp, '.'); 3483cdf0e10cSrcweir for (long l = 15-nPrecExp; l < (long) rInfo.nCntPost; l++) 3484cdf0e10cSrcweir sStr += '0'; 3485cdf0e10cSrcweir } 3486cdf0e10cSrcweir else 3487cdf0e10cSrcweir sStr = ::rtl::math::doubleToUString( fNumber, 3488cdf0e10cSrcweir rtl_math_StringFormat_F, rInfo.nCntPost, '.' ); 3489cdf0e10cSrcweir sStr.EraseLeadingChars('0'); // fuehrende Nullen weg 3490cdf0e10cSrcweir } 3491cdf0e10cSrcweir else if (fNumber == 0.0) // Null 3492cdf0e10cSrcweir { 3493cdf0e10cSrcweir // nothing to be done here, keep empty string sStr, 3494cdf0e10cSrcweir // ImpNumberFillWithThousands does the rest 3495cdf0e10cSrcweir } 3496cdf0e10cSrcweir else // Integer 3497cdf0e10cSrcweir { 3498cdf0e10cSrcweir sStr = ::rtl::math::doubleToUString( fNumber, 3499cdf0e10cSrcweir rtl_math_StringFormat_F, 0, '.'); 3500cdf0e10cSrcweir sStr.EraseLeadingChars('0'); // fuehrende Nullen weg 3501cdf0e10cSrcweir } 3502cdf0e10cSrcweir xub_StrLen nPoint = sStr.Search( '.' ); 3503cdf0e10cSrcweir if ( nPoint != STRING_NOTFOUND ) 3504cdf0e10cSrcweir { 3505cdf0e10cSrcweir register const sal_Unicode* p = sStr.GetBuffer() + nPoint; 3506cdf0e10cSrcweir while ( *++p == '0' ) 3507cdf0e10cSrcweir ; 3508cdf0e10cSrcweir if ( !*p ) 3509cdf0e10cSrcweir bInteger = sal_True; 3510cdf0e10cSrcweir sStr.Erase( nPoint, 1 ); // . herausnehmen 3511cdf0e10cSrcweir } 3512cdf0e10cSrcweir if (bSign && 3513cdf0e10cSrcweir (sStr.Len() == 0 || sStr.GetTokenCount('0') == sStr.Len()+1)) // nur 00000 3514cdf0e10cSrcweir bSign = sal_False; // nicht -0.00 3515cdf0e10cSrcweir } // End of != FLAG_STANDARD_IN_FORMAT 3516cdf0e10cSrcweir 3517cdf0e10cSrcweir // von hinten nach vorn 3518cdf0e10cSrcweir // editieren: 3519cdf0e10cSrcweir k = sStr.Len(); // hinter letzter Ziffer 3520cdf0e10cSrcweir j = NumFor[nIx].GetnAnz()-1; // letztes Symbol 3521cdf0e10cSrcweir // Nachkommastellen: 3522cdf0e10cSrcweir if (rInfo.nCntPost > 0) 3523cdf0e10cSrcweir { 3524cdf0e10cSrcweir sal_Bool bTrailing = sal_True; // ob Endnullen? 3525cdf0e10cSrcweir sal_Bool bFilled = sal_False; // ob aufgefuellt wurde ? 3526cdf0e10cSrcweir short nType; 3527cdf0e10cSrcweir while (j > 0 && // rueckwaerts 3528cdf0e10cSrcweir (nType = rInfo.nTypeArray[j]) != NF_SYMBOLTYPE_DECSEP) 3529cdf0e10cSrcweir { 3530cdf0e10cSrcweir switch ( nType ) 3531cdf0e10cSrcweir { 3532cdf0e10cSrcweir case NF_SYMBOLTYPE_STAR: 3533cdf0e10cSrcweir if( bStarFlag ) 3534cdf0e10cSrcweir { 3535cdf0e10cSrcweir sStr.Insert( (sal_Unicode) 0x1B, k /*++*/ ); 3536cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j].GetChar(1),k); 3537cdf0e10cSrcweir bRes = sal_True; 3538cdf0e10cSrcweir } 3539cdf0e10cSrcweir break; 3540cdf0e10cSrcweir case NF_SYMBOLTYPE_BLANK: 3541cdf0e10cSrcweir /*k = */ InsertBlanks( sStr,k,rInfo.sStrArray[j].GetChar(1) ); 3542cdf0e10cSrcweir break; 3543cdf0e10cSrcweir case NF_SYMBOLTYPE_STRING: 3544cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRENCY: 3545cdf0e10cSrcweir case NF_SYMBOLTYPE_PERCENT: 3546cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j],k); 3547cdf0e10cSrcweir break; 3548cdf0e10cSrcweir case NF_SYMBOLTYPE_THSEP: 3549cdf0e10cSrcweir if (rInfo.nThousand == 0) 3550cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j],k); 3551cdf0e10cSrcweir break; 3552cdf0e10cSrcweir case NF_SYMBOLTYPE_DIGIT: 3553cdf0e10cSrcweir { 3554cdf0e10cSrcweir const String& rStr = rInfo.sStrArray[j]; 3555cdf0e10cSrcweir const sal_Unicode* p1 = rStr.GetBuffer(); 3556cdf0e10cSrcweir register const sal_Unicode* p = p1 + rStr.Len(); 3557cdf0e10cSrcweir while ( p1 < p-- ) 3558cdf0e10cSrcweir { 3559cdf0e10cSrcweir const sal_Unicode c = *p; 3560cdf0e10cSrcweir k--; 3561cdf0e10cSrcweir if ( sStr.GetChar(k) != '0' ) 3562cdf0e10cSrcweir bTrailing = sal_False; 3563cdf0e10cSrcweir if (bTrailing) 3564cdf0e10cSrcweir { 3565cdf0e10cSrcweir if ( c == '0' ) 3566cdf0e10cSrcweir bFilled = sal_True; 3567cdf0e10cSrcweir else if ( c == '-' ) 3568cdf0e10cSrcweir { 3569cdf0e10cSrcweir if ( bInteger ) 3570cdf0e10cSrcweir sStr.SetChar( k, '-' ); 3571cdf0e10cSrcweir bFilled = sal_True; 3572cdf0e10cSrcweir } 3573cdf0e10cSrcweir else if ( c == '?' ) 3574cdf0e10cSrcweir { 3575cdf0e10cSrcweir sStr.SetChar( k, ' ' ); 3576cdf0e10cSrcweir bFilled = sal_True; 3577cdf0e10cSrcweir } 3578cdf0e10cSrcweir else if ( !bFilled ) // # 3579cdf0e10cSrcweir sStr.Erase(k,1); 3580cdf0e10cSrcweir } 3581cdf0e10cSrcweir } // of for 3582cdf0e10cSrcweir } // of case digi 3583cdf0e10cSrcweir break; 3584cdf0e10cSrcweir case NF_KEY_CCC: // CCC-Waehrung 3585cdf0e10cSrcweir sStr.Insert(rScan.GetCurAbbrev(), k); 3586cdf0e10cSrcweir break; 3587cdf0e10cSrcweir case NF_KEY_GENERAL: // Standard im String 3588cdf0e10cSrcweir { 3589cdf0e10cSrcweir String sNum; 3590cdf0e10cSrcweir ImpGetOutputStandard(fNumber, sNum); 3591cdf0e10cSrcweir sNum.EraseLeadingChars('-'); 3592cdf0e10cSrcweir sStr.Insert(sNum, k); 3593cdf0e10cSrcweir } 3594cdf0e10cSrcweir break; 3595cdf0e10cSrcweir default: 3596cdf0e10cSrcweir break; 3597cdf0e10cSrcweir } // of switch 3598cdf0e10cSrcweir j--; 3599cdf0e10cSrcweir } // of while 3600cdf0e10cSrcweir } // of Nachkomma 3601cdf0e10cSrcweir 3602cdf0e10cSrcweir bRes |= ImpNumberFillWithThousands(sStr, fNumber, k, j, nIx, // ggfs Auffuellen mit . 3603cdf0e10cSrcweir rInfo.nCntPre); 3604cdf0e10cSrcweir if ( rInfo.nCntPost > 0 ) 3605cdf0e10cSrcweir { 3606cdf0e10cSrcweir const String& rDecSep = GetFormatter().GetNumDecimalSep(); 3607cdf0e10cSrcweir xub_StrLen nLen = rDecSep.Len(); 3608cdf0e10cSrcweir if ( sStr.Len() > nLen && sStr.Equals( rDecSep, sStr.Len() - nLen, nLen ) ) 3609cdf0e10cSrcweir sStr.Erase( sStr.Len() - nLen ); // no decimals => strip DecSep 3610cdf0e10cSrcweir } 3611cdf0e10cSrcweir if (bSign) 3612cdf0e10cSrcweir sStr.Insert('-',0); 3613cdf0e10cSrcweir ImpTransliterate( sStr, NumFor[nIx].GetNatNum() ); 3614cdf0e10cSrcweir OutString = sStr; 3615cdf0e10cSrcweir return bRes; 3616cdf0e10cSrcweir } 3617cdf0e10cSrcweir 3618cdf0e10cSrcweir sal_Bool SvNumberformat::ImpNumberFillWithThousands( 3619cdf0e10cSrcweir String& sStr, // number string 3620cdf0e10cSrcweir double& rNumber, // number 3621cdf0e10cSrcweir xub_StrLen k, // position within string 3622cdf0e10cSrcweir sal_uInt16 j, // symbol index within format code 3623cdf0e10cSrcweir sal_uInt16 nIx, // subformat index 3624cdf0e10cSrcweir sal_uInt16 nDigCnt) // count of integer digits in format 3625cdf0e10cSrcweir { 3626cdf0e10cSrcweir sal_Bool bRes = sal_False; 3627cdf0e10cSrcweir xub_StrLen nLeadingStringChars = 0; // inserted StringChars before number 3628cdf0e10cSrcweir xub_StrLen nDigitCount = 0; // count of integer digits from the right 3629cdf0e10cSrcweir sal_Bool bStop = sal_False; 3630cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); 3631cdf0e10cSrcweir // no normal thousands separators if number divided by thousands 3632cdf0e10cSrcweir sal_Bool bDoThousands = (rInfo.nThousand == 0); 3633cdf0e10cSrcweir utl::DigitGroupingIterator aGrouping( 3634cdf0e10cSrcweir GetFormatter().GetLocaleData()->getDigitGrouping()); 3635cdf0e10cSrcweir while (!bStop) // backwards 3636cdf0e10cSrcweir { 3637cdf0e10cSrcweir if (j == 0) 3638cdf0e10cSrcweir bStop = sal_True; 3639cdf0e10cSrcweir switch (rInfo.nTypeArray[j]) 3640cdf0e10cSrcweir { 3641cdf0e10cSrcweir case NF_SYMBOLTYPE_DECSEP: 3642cdf0e10cSrcweir aGrouping.reset(); 3643cdf0e10cSrcweir // fall thru 3644cdf0e10cSrcweir case NF_SYMBOLTYPE_STRING: 3645cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRENCY: 3646cdf0e10cSrcweir case NF_SYMBOLTYPE_PERCENT: 3647cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j],k); 3648cdf0e10cSrcweir if ( k == 0 ) 3649cdf0e10cSrcweir nLeadingStringChars = 3650cdf0e10cSrcweir nLeadingStringChars + rInfo.sStrArray[j].Len(); 3651cdf0e10cSrcweir break; 3652cdf0e10cSrcweir case NF_SYMBOLTYPE_STAR: 3653cdf0e10cSrcweir if( bStarFlag ) 3654cdf0e10cSrcweir { 3655cdf0e10cSrcweir sStr.Insert( (sal_Unicode) 0x1B, k/*++*/ ); 3656cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j].GetChar(1),k); 3657cdf0e10cSrcweir bRes = sal_True; 3658cdf0e10cSrcweir } 3659cdf0e10cSrcweir break; 3660cdf0e10cSrcweir case NF_SYMBOLTYPE_BLANK: 3661cdf0e10cSrcweir /*k = */ InsertBlanks( sStr,k,rInfo.sStrArray[j].GetChar(1) ); 3662cdf0e10cSrcweir break; 3663cdf0e10cSrcweir case NF_SYMBOLTYPE_THSEP: 3664cdf0e10cSrcweir { 3665cdf0e10cSrcweir // #i7284# #102685# Insert separator also if number is divided 3666cdf0e10cSrcweir // by thousands and the separator is specified somewhere in 3667cdf0e10cSrcweir // between and not only at the end. 3668cdf0e10cSrcweir // #i12596# But do not insert if it's a parenthesized negative 3669cdf0e10cSrcweir // format like (#,) 3670cdf0e10cSrcweir // In fact, do not insert if divided and regex [0#,],[^0#] and 3671cdf0e10cSrcweir // no other digit symbol follows (which was already detected 3672cdf0e10cSrcweir // during scan of format code, otherwise there would be no 3673cdf0e10cSrcweir // division), else do insert. Same in ImpNumberFill() below. 3674cdf0e10cSrcweir if ( !bDoThousands && j < NumFor[nIx].GetnAnz()-1 ) 3675cdf0e10cSrcweir bDoThousands = ((j == 0) || 3676cdf0e10cSrcweir (rInfo.nTypeArray[j-1] != NF_SYMBOLTYPE_DIGIT && 3677cdf0e10cSrcweir rInfo.nTypeArray[j-1] != NF_SYMBOLTYPE_THSEP) || 3678cdf0e10cSrcweir (rInfo.nTypeArray[j+1] == NF_SYMBOLTYPE_DIGIT)); 3679cdf0e10cSrcweir if ( bDoThousands ) 3680cdf0e10cSrcweir { 3681cdf0e10cSrcweir if (k > 0) 3682cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j],k); 3683cdf0e10cSrcweir else if (nDigitCount < nDigCnt) 3684cdf0e10cSrcweir { 3685cdf0e10cSrcweir // Leading '#' displays nothing (e.g. no leading 3686cdf0e10cSrcweir // separator for numbers <1000 with #,##0 format). 3687cdf0e10cSrcweir // Leading '?' displays blank. 3688cdf0e10cSrcweir // Everything else, including nothing, displays the 3689cdf0e10cSrcweir // separator. 3690cdf0e10cSrcweir sal_Unicode cLeader = 0; 3691cdf0e10cSrcweir if (j > 0 && rInfo.nTypeArray[j-1] == NF_SYMBOLTYPE_DIGIT) 3692cdf0e10cSrcweir { 3693cdf0e10cSrcweir const String& rStr = rInfo.sStrArray[j-1]; 3694cdf0e10cSrcweir xub_StrLen nLen = rStr.Len(); 3695cdf0e10cSrcweir if (nLen) 3696cdf0e10cSrcweir cLeader = rStr.GetChar(nLen-1); 3697cdf0e10cSrcweir } 3698cdf0e10cSrcweir switch (cLeader) 3699cdf0e10cSrcweir { 3700cdf0e10cSrcweir case '#': 3701cdf0e10cSrcweir ; // nothing 3702cdf0e10cSrcweir break; 3703cdf0e10cSrcweir case '?': 3704cdf0e10cSrcweir // erAck: 2008-04-03T16:24+0200 3705cdf0e10cSrcweir // Actually this currently isn't executed 3706cdf0e10cSrcweir // because the format scanner in the context of 3707cdf0e10cSrcweir // "?," doesn't generate a group separator but 3708cdf0e10cSrcweir // a literal ',' character instead that is 3709cdf0e10cSrcweir // inserted unconditionally. Should be changed 3710cdf0e10cSrcweir // on some occasion. 3711cdf0e10cSrcweir sStr.Insert(' ',k); 3712cdf0e10cSrcweir break; 3713cdf0e10cSrcweir default: 3714cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j],k); 3715cdf0e10cSrcweir } 3716cdf0e10cSrcweir } 3717cdf0e10cSrcweir aGrouping.advance(); 3718cdf0e10cSrcweir } 3719cdf0e10cSrcweir } 3720cdf0e10cSrcweir break; 3721cdf0e10cSrcweir case NF_SYMBOLTYPE_DIGIT: 3722cdf0e10cSrcweir { 3723cdf0e10cSrcweir const String& rStr = rInfo.sStrArray[j]; 3724cdf0e10cSrcweir const sal_Unicode* p1 = rStr.GetBuffer(); 3725cdf0e10cSrcweir register const sal_Unicode* p = p1 + rStr.Len(); 3726cdf0e10cSrcweir while ( p1 < p-- ) 3727cdf0e10cSrcweir { 3728cdf0e10cSrcweir nDigitCount++; 3729cdf0e10cSrcweir if (k > 0) 3730cdf0e10cSrcweir k--; 3731cdf0e10cSrcweir else 3732cdf0e10cSrcweir { 3733cdf0e10cSrcweir switch (*p) 3734cdf0e10cSrcweir { 3735cdf0e10cSrcweir case '0': 3736cdf0e10cSrcweir sStr.Insert('0',0); 3737cdf0e10cSrcweir break; 3738cdf0e10cSrcweir case '?': 3739cdf0e10cSrcweir sStr.Insert(' ',0); 3740cdf0e10cSrcweir break; 3741cdf0e10cSrcweir } 3742cdf0e10cSrcweir } 3743cdf0e10cSrcweir if (nDigitCount == nDigCnt && k > 0) 3744cdf0e10cSrcweir { // more digits than specified 3745cdf0e10cSrcweir ImpDigitFill(sStr, 0, k, nIx, nDigitCount, aGrouping); 3746cdf0e10cSrcweir } 3747cdf0e10cSrcweir } 3748cdf0e10cSrcweir } 3749cdf0e10cSrcweir break; 3750cdf0e10cSrcweir case NF_KEY_CCC: // CCC currency 3751cdf0e10cSrcweir sStr.Insert(rScan.GetCurAbbrev(), k); 3752cdf0e10cSrcweir break; 3753cdf0e10cSrcweir case NF_KEY_GENERAL: // "General" in string 3754cdf0e10cSrcweir { 3755cdf0e10cSrcweir String sNum; 3756cdf0e10cSrcweir ImpGetOutputStandard(rNumber, sNum); 3757cdf0e10cSrcweir sNum.EraseLeadingChars('-'); 3758cdf0e10cSrcweir sStr.Insert(sNum, k); 3759cdf0e10cSrcweir } 3760cdf0e10cSrcweir break; 3761cdf0e10cSrcweir 3762cdf0e10cSrcweir default: 3763cdf0e10cSrcweir break; 3764cdf0e10cSrcweir } // switch 3765cdf0e10cSrcweir j--; // next format code string 3766cdf0e10cSrcweir } // while 3767cdf0e10cSrcweir k = k + nLeadingStringChars; // MSC converts += to int and then warns, so ... 3768cdf0e10cSrcweir if (k > nLeadingStringChars) 3769cdf0e10cSrcweir ImpDigitFill(sStr, nLeadingStringChars, k, nIx, nDigitCount, aGrouping); 3770cdf0e10cSrcweir return bRes; 3771cdf0e10cSrcweir } 3772cdf0e10cSrcweir 3773cdf0e10cSrcweir void SvNumberformat::ImpDigitFill( 3774cdf0e10cSrcweir String& sStr, // number string 3775cdf0e10cSrcweir xub_StrLen nStart, // start of digits 3776cdf0e10cSrcweir xub_StrLen& k, // position within string 3777cdf0e10cSrcweir sal_uInt16 nIx, // subformat index 3778cdf0e10cSrcweir xub_StrLen & nDigitCount, // count of integer digits from the right so far 3779cdf0e10cSrcweir utl::DigitGroupingIterator & rGrouping ) // current grouping 3780cdf0e10cSrcweir { 3781cdf0e10cSrcweir if (NumFor[nIx].Info().bThousand) // only if grouping 3782cdf0e10cSrcweir { // fill in separators 3783cdf0e10cSrcweir const String& rThousandSep = GetFormatter().GetNumThousandSep(); 3784cdf0e10cSrcweir while (k > nStart) 3785cdf0e10cSrcweir { 3786cdf0e10cSrcweir if (nDigitCount == rGrouping.getPos()) 3787cdf0e10cSrcweir { 3788cdf0e10cSrcweir sStr.Insert( rThousandSep, k ); 3789cdf0e10cSrcweir rGrouping.advance(); 3790cdf0e10cSrcweir } 3791cdf0e10cSrcweir nDigitCount++; 3792cdf0e10cSrcweir k--; 3793cdf0e10cSrcweir } 3794cdf0e10cSrcweir } 3795cdf0e10cSrcweir else // simply skip 3796cdf0e10cSrcweir k = nStart; 3797cdf0e10cSrcweir } 3798cdf0e10cSrcweir 3799cdf0e10cSrcweir sal_Bool SvNumberformat::ImpNumberFill( String& sStr, // number string 3800cdf0e10cSrcweir double& rNumber, // number for "General" format 3801cdf0e10cSrcweir xub_StrLen& k, // position within string 3802cdf0e10cSrcweir sal_uInt16& j, // symbol index within format code 3803cdf0e10cSrcweir sal_uInt16 nIx, // subformat index 3804cdf0e10cSrcweir short eSymbolType ) // type of stop condition 3805cdf0e10cSrcweir { 3806cdf0e10cSrcweir sal_Bool bRes = sal_False; 3807cdf0e10cSrcweir k = sStr.Len(); // behind last digit 3808cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); 3809cdf0e10cSrcweir // no normal thousands separators if number divided by thousands 3810cdf0e10cSrcweir sal_Bool bDoThousands = (rInfo.nThousand == 0); 3811cdf0e10cSrcweir short nType; 3812cdf0e10cSrcweir while (j > 0 && (nType = rInfo.nTypeArray[j]) != eSymbolType ) 3813cdf0e10cSrcweir { // rueckwaerts: 3814cdf0e10cSrcweir switch ( nType ) 3815cdf0e10cSrcweir { 3816cdf0e10cSrcweir case NF_SYMBOLTYPE_STAR: 3817cdf0e10cSrcweir if( bStarFlag ) 3818cdf0e10cSrcweir { 3819cdf0e10cSrcweir sStr.Insert( sal_Unicode(0x1B), k++ ); 3820cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j].GetChar(1),k); 3821cdf0e10cSrcweir bRes = sal_True; 3822cdf0e10cSrcweir } 3823cdf0e10cSrcweir break; 3824cdf0e10cSrcweir case NF_SYMBOLTYPE_BLANK: 3825cdf0e10cSrcweir k = InsertBlanks( sStr,k,rInfo.sStrArray[j].GetChar(1) ); 3826cdf0e10cSrcweir break; 3827cdf0e10cSrcweir case NF_SYMBOLTYPE_THSEP: 3828cdf0e10cSrcweir { 3829cdf0e10cSrcweir // Same as in ImpNumberFillWithThousands() above, do not insert 3830cdf0e10cSrcweir // if divided and regex [0#,],[^0#] and no other digit symbol 3831cdf0e10cSrcweir // follows (which was already detected during scan of format 3832cdf0e10cSrcweir // code, otherwise there would be no division), else do insert. 3833cdf0e10cSrcweir if ( !bDoThousands && j < NumFor[nIx].GetnAnz()-1 ) 3834cdf0e10cSrcweir bDoThousands = ((j == 0) || 3835cdf0e10cSrcweir (rInfo.nTypeArray[j-1] != NF_SYMBOLTYPE_DIGIT && 3836cdf0e10cSrcweir rInfo.nTypeArray[j-1] != NF_SYMBOLTYPE_THSEP) || 3837cdf0e10cSrcweir (rInfo.nTypeArray[j+1] == NF_SYMBOLTYPE_DIGIT)); 3838cdf0e10cSrcweir if ( bDoThousands && k > 0 ) 3839cdf0e10cSrcweir { 3840cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j],k); 3841cdf0e10cSrcweir } 3842cdf0e10cSrcweir } 3843cdf0e10cSrcweir break; 3844cdf0e10cSrcweir case NF_SYMBOLTYPE_DIGIT: 3845cdf0e10cSrcweir { 3846cdf0e10cSrcweir const String& rStr = rInfo.sStrArray[j]; 3847cdf0e10cSrcweir const sal_Unicode* p1 = rStr.GetBuffer(); 3848cdf0e10cSrcweir register const sal_Unicode* p = p1 + rStr.Len(); 3849cdf0e10cSrcweir while ( p1 < p-- ) 3850cdf0e10cSrcweir { 3851cdf0e10cSrcweir if (k > 0) 3852cdf0e10cSrcweir k--; 3853cdf0e10cSrcweir else 3854cdf0e10cSrcweir { 3855cdf0e10cSrcweir switch (*p) 3856cdf0e10cSrcweir { 3857cdf0e10cSrcweir case '0': 3858cdf0e10cSrcweir sStr.Insert('0',0); 3859cdf0e10cSrcweir break; 3860cdf0e10cSrcweir case '?': 3861cdf0e10cSrcweir sStr.Insert(' ',0); 3862cdf0e10cSrcweir break; 3863cdf0e10cSrcweir } 3864cdf0e10cSrcweir } 3865cdf0e10cSrcweir } 3866cdf0e10cSrcweir } 3867cdf0e10cSrcweir break; 3868cdf0e10cSrcweir case NF_KEY_CCC: // CCC-Waehrung 3869cdf0e10cSrcweir sStr.Insert(rScan.GetCurAbbrev(), k); 3870cdf0e10cSrcweir break; 3871cdf0e10cSrcweir case NF_KEY_GENERAL: // Standard im String 3872cdf0e10cSrcweir { 3873cdf0e10cSrcweir String sNum; 3874cdf0e10cSrcweir ImpGetOutputStandard(rNumber, sNum); 3875cdf0e10cSrcweir sNum.EraseLeadingChars('-'); // Vorzeichen weg!! 3876cdf0e10cSrcweir sStr.Insert(sNum, k); 3877cdf0e10cSrcweir } 3878cdf0e10cSrcweir break; 3879cdf0e10cSrcweir 3880cdf0e10cSrcweir default: 3881cdf0e10cSrcweir sStr.Insert(rInfo.sStrArray[j],k); 3882cdf0e10cSrcweir break; 3883cdf0e10cSrcweir } // of switch 3884cdf0e10cSrcweir j--; // naechster String 3885cdf0e10cSrcweir } // of while 3886cdf0e10cSrcweir return bRes; 3887cdf0e10cSrcweir } 3888cdf0e10cSrcweir 3889cdf0e10cSrcweir void SvNumberformat::GetFormatSpecialInfo(sal_Bool& bThousand, 3890cdf0e10cSrcweir sal_Bool& IsRed, 3891cdf0e10cSrcweir sal_uInt16& nPrecision, 3892cdf0e10cSrcweir sal_uInt16& nAnzLeading) const 3893cdf0e10cSrcweir { 3894cdf0e10cSrcweir // as before: take info from nNumFor=0 for whole format (for dialog etc.) 3895cdf0e10cSrcweir 3896cdf0e10cSrcweir short nDummyType; 3897cdf0e10cSrcweir GetNumForInfo( 0, nDummyType, bThousand, nPrecision, nAnzLeading ); 3898cdf0e10cSrcweir 3899cdf0e10cSrcweir // "negative in red" is only useful for the whole format 3900cdf0e10cSrcweir 3901cdf0e10cSrcweir const Color* pColor = NumFor[1].GetColor(); 3902cdf0e10cSrcweir if (fLimit1 == 0.0 && fLimit2 == 0.0 && pColor 3903cdf0e10cSrcweir && (*pColor == rScan.GetRedColor())) 3904cdf0e10cSrcweir IsRed = sal_True; 3905cdf0e10cSrcweir else 3906cdf0e10cSrcweir IsRed = sal_False; 3907cdf0e10cSrcweir } 3908cdf0e10cSrcweir 3909cdf0e10cSrcweir void SvNumberformat::GetNumForInfo( sal_uInt16 nNumFor, short& rScannedType, 3910cdf0e10cSrcweir sal_Bool& bThousand, sal_uInt16& nPrecision, sal_uInt16& nAnzLeading ) const 3911cdf0e10cSrcweir { 3912cdf0e10cSrcweir // take info from a specified sub-format (for XML export) 3913cdf0e10cSrcweir 3914cdf0e10cSrcweir if ( nNumFor > 3 ) 3915cdf0e10cSrcweir return; // invalid 3916cdf0e10cSrcweir 3917cdf0e10cSrcweir const ImpSvNumberformatInfo& rInfo = NumFor[nNumFor].Info(); 3918cdf0e10cSrcweir rScannedType = rInfo.eScannedType; 3919cdf0e10cSrcweir bThousand = rInfo.bThousand; 3920cdf0e10cSrcweir nPrecision = rInfo.nCntPost; 3921cdf0e10cSrcweir if (bStandard && rInfo.eScannedType == NUMBERFORMAT_NUMBER) 3922cdf0e10cSrcweir // StandardFormat 3923cdf0e10cSrcweir nAnzLeading = 1; 3924cdf0e10cSrcweir else 3925cdf0e10cSrcweir { 3926cdf0e10cSrcweir nAnzLeading = 0; 3927cdf0e10cSrcweir sal_Bool bStop = sal_False; 3928cdf0e10cSrcweir sal_uInt16 i = 0; 3929cdf0e10cSrcweir const sal_uInt16 nAnz = NumFor[nNumFor].GetnAnz(); 3930cdf0e10cSrcweir while (!bStop && i < nAnz) 3931cdf0e10cSrcweir { 3932cdf0e10cSrcweir short nType = rInfo.nTypeArray[i]; 3933cdf0e10cSrcweir if ( nType == NF_SYMBOLTYPE_DIGIT) 3934cdf0e10cSrcweir { 3935cdf0e10cSrcweir register const sal_Unicode* p = rInfo.sStrArray[i].GetBuffer(); 3936cdf0e10cSrcweir while ( *p == '#' ) 3937cdf0e10cSrcweir p++; 3938cdf0e10cSrcweir while ( *p++ == '0' ) 3939cdf0e10cSrcweir nAnzLeading++; 3940cdf0e10cSrcweir } 3941cdf0e10cSrcweir else if (nType == NF_SYMBOLTYPE_DECSEP || nType == NF_SYMBOLTYPE_EXP) 3942cdf0e10cSrcweir bStop = sal_True; 3943cdf0e10cSrcweir i++; 3944cdf0e10cSrcweir } 3945cdf0e10cSrcweir } 3946cdf0e10cSrcweir } 3947cdf0e10cSrcweir 3948cdf0e10cSrcweir const String* SvNumberformat::GetNumForString( sal_uInt16 nNumFor, sal_uInt16 nPos, 3949cdf0e10cSrcweir sal_Bool bString /* = sal_False */ ) const 3950cdf0e10cSrcweir { 3951cdf0e10cSrcweir if ( nNumFor > 3 ) 3952cdf0e10cSrcweir return NULL; 3953cdf0e10cSrcweir sal_uInt16 nAnz = NumFor[nNumFor].GetnAnz(); 3954cdf0e10cSrcweir if ( !nAnz ) 3955cdf0e10cSrcweir return NULL; 3956cdf0e10cSrcweir if ( nPos == 0xFFFF ) 3957cdf0e10cSrcweir { 3958cdf0e10cSrcweir nPos = nAnz - 1; 3959cdf0e10cSrcweir if ( bString ) 3960cdf0e10cSrcweir { // rueckwaerts 3961cdf0e10cSrcweir short* pType = NumFor[nNumFor].Info().nTypeArray + nPos; 3962cdf0e10cSrcweir while ( nPos > 0 && (*pType != NF_SYMBOLTYPE_STRING) && 3963cdf0e10cSrcweir (*pType != NF_SYMBOLTYPE_CURRENCY) ) 3964cdf0e10cSrcweir { 3965cdf0e10cSrcweir pType--; 3966cdf0e10cSrcweir nPos--; 3967cdf0e10cSrcweir } 3968cdf0e10cSrcweir if ( (*pType != NF_SYMBOLTYPE_STRING) && (*pType != NF_SYMBOLTYPE_CURRENCY) ) 3969cdf0e10cSrcweir return NULL; 3970cdf0e10cSrcweir } 3971cdf0e10cSrcweir } 3972cdf0e10cSrcweir else if ( nPos > nAnz - 1 ) 3973cdf0e10cSrcweir return NULL; 3974cdf0e10cSrcweir else if ( bString ) 3975cdf0e10cSrcweir { // vorwaerts 3976cdf0e10cSrcweir short* pType = NumFor[nNumFor].Info().nTypeArray + nPos; 3977cdf0e10cSrcweir while ( nPos < nAnz && (*pType != NF_SYMBOLTYPE_STRING) && 3978cdf0e10cSrcweir (*pType != NF_SYMBOLTYPE_CURRENCY) ) 3979cdf0e10cSrcweir { 3980cdf0e10cSrcweir pType++; 3981cdf0e10cSrcweir nPos++; 3982cdf0e10cSrcweir } 3983cdf0e10cSrcweir if ( nPos >= nAnz || ((*pType != NF_SYMBOLTYPE_STRING) && 3984cdf0e10cSrcweir (*pType != NF_SYMBOLTYPE_CURRENCY)) ) 3985cdf0e10cSrcweir return NULL; 3986cdf0e10cSrcweir } 3987cdf0e10cSrcweir return &NumFor[nNumFor].Info().sStrArray[nPos]; 3988cdf0e10cSrcweir } 3989cdf0e10cSrcweir 3990cdf0e10cSrcweir 3991cdf0e10cSrcweir short SvNumberformat::GetNumForType( sal_uInt16 nNumFor, sal_uInt16 nPos, 3992cdf0e10cSrcweir sal_Bool bString /* = sal_False */ ) const 3993cdf0e10cSrcweir { 3994cdf0e10cSrcweir if ( nNumFor > 3 ) 3995cdf0e10cSrcweir return 0; 3996cdf0e10cSrcweir sal_uInt16 nAnz = NumFor[nNumFor].GetnAnz(); 3997cdf0e10cSrcweir if ( !nAnz ) 3998cdf0e10cSrcweir return 0; 3999cdf0e10cSrcweir if ( nPos == 0xFFFF ) 4000cdf0e10cSrcweir { 4001cdf0e10cSrcweir nPos = nAnz - 1; 4002cdf0e10cSrcweir if ( bString ) 4003cdf0e10cSrcweir { // rueckwaerts 4004cdf0e10cSrcweir short* pType = NumFor[nNumFor].Info().nTypeArray + nPos; 4005cdf0e10cSrcweir while ( nPos > 0 && (*pType != NF_SYMBOLTYPE_STRING) && 4006cdf0e10cSrcweir (*pType != NF_SYMBOLTYPE_CURRENCY) ) 4007cdf0e10cSrcweir { 4008cdf0e10cSrcweir pType--; 4009cdf0e10cSrcweir nPos--; 4010cdf0e10cSrcweir } 4011cdf0e10cSrcweir if ( (*pType != NF_SYMBOLTYPE_STRING) && (*pType != NF_SYMBOLTYPE_CURRENCY) ) 4012cdf0e10cSrcweir return 0; 4013cdf0e10cSrcweir } 4014cdf0e10cSrcweir } 4015cdf0e10cSrcweir else if ( nPos > nAnz - 1 ) 4016cdf0e10cSrcweir return 0; 4017cdf0e10cSrcweir else if ( bString ) 4018cdf0e10cSrcweir { // vorwaerts 4019cdf0e10cSrcweir short* pType = NumFor[nNumFor].Info().nTypeArray + nPos; 4020cdf0e10cSrcweir while ( nPos < nAnz && (*pType != NF_SYMBOLTYPE_STRING) && 4021cdf0e10cSrcweir (*pType != NF_SYMBOLTYPE_CURRENCY) ) 4022cdf0e10cSrcweir { 4023cdf0e10cSrcweir pType++; 4024cdf0e10cSrcweir nPos++; 4025cdf0e10cSrcweir } 4026cdf0e10cSrcweir if ( (*pType != NF_SYMBOLTYPE_STRING) && (*pType != NF_SYMBOLTYPE_CURRENCY) ) 4027cdf0e10cSrcweir return 0; 4028cdf0e10cSrcweir } 4029cdf0e10cSrcweir return NumFor[nNumFor].Info().nTypeArray[nPos]; 4030cdf0e10cSrcweir } 4031cdf0e10cSrcweir 4032cdf0e10cSrcweir 4033cdf0e10cSrcweir sal_Bool SvNumberformat::IsNegativeWithoutSign() const 4034cdf0e10cSrcweir { 4035cdf0e10cSrcweir if ( IsNegativeRealNegative() ) 4036cdf0e10cSrcweir { 4037cdf0e10cSrcweir const String* pStr = GetNumForString( 1, 0, sal_True ); 4038cdf0e10cSrcweir if ( pStr ) 4039cdf0e10cSrcweir return !HasStringNegativeSign( *pStr ); 4040cdf0e10cSrcweir } 4041cdf0e10cSrcweir return sal_False; 4042cdf0e10cSrcweir } 4043cdf0e10cSrcweir 4044cdf0e10cSrcweir 4045cdf0e10cSrcweir DateFormat SvNumberformat::GetDateOrder() const 4046cdf0e10cSrcweir { 4047cdf0e10cSrcweir if ( (eType & NUMBERFORMAT_DATE) == NUMBERFORMAT_DATE ) 4048cdf0e10cSrcweir { 4049cdf0e10cSrcweir short const * const pType = NumFor[0].Info().nTypeArray; 4050cdf0e10cSrcweir sal_uInt16 nAnz = NumFor[0].GetnAnz(); 4051cdf0e10cSrcweir for ( sal_uInt16 j=0; j<nAnz; j++ ) 4052cdf0e10cSrcweir { 4053cdf0e10cSrcweir switch ( pType[j] ) 4054cdf0e10cSrcweir { 4055cdf0e10cSrcweir case NF_KEY_D : 4056cdf0e10cSrcweir case NF_KEY_DD : 4057cdf0e10cSrcweir return DMY; 4058cdf0e10cSrcweir case NF_KEY_M : 4059cdf0e10cSrcweir case NF_KEY_MM : 4060cdf0e10cSrcweir case NF_KEY_MMM : 4061cdf0e10cSrcweir case NF_KEY_MMMM : 4062cdf0e10cSrcweir case NF_KEY_MMMMM : 4063cdf0e10cSrcweir return MDY; 4064cdf0e10cSrcweir case NF_KEY_YY : 4065cdf0e10cSrcweir case NF_KEY_YYYY : 4066cdf0e10cSrcweir case NF_KEY_EC : 4067cdf0e10cSrcweir case NF_KEY_EEC : 4068cdf0e10cSrcweir case NF_KEY_R : 4069cdf0e10cSrcweir case NF_KEY_RR : 4070cdf0e10cSrcweir return YMD; 4071cdf0e10cSrcweir } 4072cdf0e10cSrcweir } 4073cdf0e10cSrcweir } 4074cdf0e10cSrcweir else 4075cdf0e10cSrcweir { 4076cdf0e10cSrcweir DBG_ERROR( "SvNumberformat::GetDateOrder: no date" ); 4077cdf0e10cSrcweir } 4078cdf0e10cSrcweir return rLoc().getDateFormat(); 4079cdf0e10cSrcweir } 4080cdf0e10cSrcweir 4081cdf0e10cSrcweir 4082cdf0e10cSrcweir sal_uInt32 SvNumberformat::GetExactDateOrder() const 4083cdf0e10cSrcweir { 4084cdf0e10cSrcweir sal_uInt32 nRet = 0; 4085cdf0e10cSrcweir if ( (eType & NUMBERFORMAT_DATE) != NUMBERFORMAT_DATE ) 4086cdf0e10cSrcweir { 4087cdf0e10cSrcweir DBG_ERROR( "SvNumberformat::GetExactDateOrder: no date" ); 4088cdf0e10cSrcweir return nRet; 4089cdf0e10cSrcweir } 4090cdf0e10cSrcweir short const * const pType = NumFor[0].Info().nTypeArray; 4091cdf0e10cSrcweir sal_uInt16 nAnz = NumFor[0].GetnAnz(); 4092cdf0e10cSrcweir int nShift = 0; 4093cdf0e10cSrcweir for ( sal_uInt16 j=0; j<nAnz && nShift < 3; j++ ) 4094cdf0e10cSrcweir { 4095cdf0e10cSrcweir switch ( pType[j] ) 4096cdf0e10cSrcweir { 4097cdf0e10cSrcweir case NF_KEY_D : 4098cdf0e10cSrcweir case NF_KEY_DD : 4099cdf0e10cSrcweir nRet = (nRet << 8) | 'D'; 4100cdf0e10cSrcweir ++nShift; 4101cdf0e10cSrcweir break; 4102cdf0e10cSrcweir case NF_KEY_M : 4103cdf0e10cSrcweir case NF_KEY_MM : 4104cdf0e10cSrcweir case NF_KEY_MMM : 4105cdf0e10cSrcweir case NF_KEY_MMMM : 4106cdf0e10cSrcweir case NF_KEY_MMMMM : 4107cdf0e10cSrcweir nRet = (nRet << 8) | 'M'; 4108cdf0e10cSrcweir ++nShift; 4109cdf0e10cSrcweir break; 4110cdf0e10cSrcweir case NF_KEY_YY : 4111cdf0e10cSrcweir case NF_KEY_YYYY : 4112cdf0e10cSrcweir case NF_KEY_EC : 4113cdf0e10cSrcweir case NF_KEY_EEC : 4114cdf0e10cSrcweir case NF_KEY_R : 4115cdf0e10cSrcweir case NF_KEY_RR : 4116cdf0e10cSrcweir nRet = (nRet << 8) | 'Y'; 4117cdf0e10cSrcweir ++nShift; 4118cdf0e10cSrcweir break; 4119cdf0e10cSrcweir } 4120cdf0e10cSrcweir } 4121cdf0e10cSrcweir return nRet; 4122cdf0e10cSrcweir } 4123cdf0e10cSrcweir 4124cdf0e10cSrcweir 4125cdf0e10cSrcweir void SvNumberformat::GetConditions( SvNumberformatLimitOps& rOper1, double& rVal1, 4126cdf0e10cSrcweir SvNumberformatLimitOps& rOper2, double& rVal2 ) const 4127cdf0e10cSrcweir { 4128cdf0e10cSrcweir rOper1 = eOp1; 4129cdf0e10cSrcweir rOper2 = eOp2; 4130cdf0e10cSrcweir rVal1 = fLimit1; 4131cdf0e10cSrcweir rVal2 = fLimit2; 4132cdf0e10cSrcweir } 4133cdf0e10cSrcweir 4134cdf0e10cSrcweir 4135cdf0e10cSrcweir Color* SvNumberformat::GetColor( sal_uInt16 nNumFor ) const 4136cdf0e10cSrcweir { 4137cdf0e10cSrcweir if ( nNumFor > 3 ) 4138cdf0e10cSrcweir return NULL; 4139cdf0e10cSrcweir 4140cdf0e10cSrcweir return NumFor[nNumFor].GetColor(); 4141cdf0e10cSrcweir } 4142cdf0e10cSrcweir 4143cdf0e10cSrcweir 4144cdf0e10cSrcweir void lcl_SvNumberformat_AddLimitStringImpl( String& rStr, 4145cdf0e10cSrcweir SvNumberformatLimitOps eOp, double fLimit, const String& rDecSep ) 4146cdf0e10cSrcweir { 4147cdf0e10cSrcweir if ( eOp != NUMBERFORMAT_OP_NO ) 4148cdf0e10cSrcweir { 4149cdf0e10cSrcweir switch ( eOp ) 4150cdf0e10cSrcweir { 4151cdf0e10cSrcweir case NUMBERFORMAT_OP_EQ : 4152cdf0e10cSrcweir rStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "[=" ) ); 4153cdf0e10cSrcweir break; 4154cdf0e10cSrcweir case NUMBERFORMAT_OP_NE : 4155cdf0e10cSrcweir rStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "[<>" ) ); 4156cdf0e10cSrcweir break; 4157cdf0e10cSrcweir case NUMBERFORMAT_OP_LT : 4158cdf0e10cSrcweir rStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "[<" ) ); 4159cdf0e10cSrcweir break; 4160cdf0e10cSrcweir case NUMBERFORMAT_OP_LE : 4161cdf0e10cSrcweir rStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "[<=" ) ); 4162cdf0e10cSrcweir break; 4163cdf0e10cSrcweir case NUMBERFORMAT_OP_GT : 4164cdf0e10cSrcweir rStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "[>" ) ); 4165cdf0e10cSrcweir break; 4166cdf0e10cSrcweir case NUMBERFORMAT_OP_GE : 4167cdf0e10cSrcweir rStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "[>=" ) ); 4168cdf0e10cSrcweir break; 4169cdf0e10cSrcweir default: 4170cdf0e10cSrcweir OSL_ASSERT( "unsupported number format" ); 4171cdf0e10cSrcweir break; 4172cdf0e10cSrcweir } 4173cdf0e10cSrcweir rStr += String( ::rtl::math::doubleToUString( fLimit, 4174cdf0e10cSrcweir rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, 4175cdf0e10cSrcweir rDecSep.GetChar(0), sal_True)); 4176cdf0e10cSrcweir rStr += ']'; 4177cdf0e10cSrcweir } 4178cdf0e10cSrcweir } 4179cdf0e10cSrcweir 4180cdf0e10cSrcweir 4181cdf0e10cSrcweir String SvNumberformat::GetMappedFormatstring( 4182cdf0e10cSrcweir const NfKeywordTable& rKeywords, const LocaleDataWrapper& rLocWrp, 4183cdf0e10cSrcweir sal_Bool bDontQuote ) const 4184cdf0e10cSrcweir { 4185cdf0e10cSrcweir String aStr; 4186cdf0e10cSrcweir sal_Bool bDefault[4]; 4187cdf0e10cSrcweir // 1 subformat matches all if no condition specified, 4188cdf0e10cSrcweir bDefault[0] = ( NumFor[1].GetnAnz() == 0 && eOp1 == NUMBERFORMAT_OP_NO ); 4189cdf0e10cSrcweir // with 2 subformats [>=0];[<0] is implied if no condition specified 4190cdf0e10cSrcweir bDefault[1] = ( !bDefault[0] && NumFor[2].GetnAnz() == 0 && 4191cdf0e10cSrcweir eOp1 == NUMBERFORMAT_OP_GE && fLimit1 == 0.0 && 4192cdf0e10cSrcweir eOp2 == NUMBERFORMAT_OP_NO && fLimit2 == 0.0 ); 4193cdf0e10cSrcweir // with 3 or more subformats [>0];[<0];[=0] is implied if no condition specified, 4194cdf0e10cSrcweir // note that subformats may be empty (;;;) and NumFor[2].GetnAnz()>0 is not checked. 4195cdf0e10cSrcweir bDefault[2] = ( !bDefault[0] && !bDefault[1] && 4196cdf0e10cSrcweir eOp1 == NUMBERFORMAT_OP_GT && fLimit1 == 0.0 && 4197cdf0e10cSrcweir eOp2 == NUMBERFORMAT_OP_LT && fLimit2 == 0.0 ); 4198cdf0e10cSrcweir sal_Bool bDefaults = bDefault[0] || bDefault[1] || bDefault[2]; 4199cdf0e10cSrcweir // from now on bDefault[] values are used to append empty subformats at the end 4200cdf0e10cSrcweir bDefault[3] = sal_False; 4201cdf0e10cSrcweir if ( !bDefaults ) 4202cdf0e10cSrcweir { // conditions specified 4203cdf0e10cSrcweir if ( eOp1 != NUMBERFORMAT_OP_NO && eOp2 == NUMBERFORMAT_OP_NO ) 4204cdf0e10cSrcweir bDefault[0] = bDefault[1] = sal_True; // [];x 4205cdf0e10cSrcweir else if ( eOp1 != NUMBERFORMAT_OP_NO && eOp2 != NUMBERFORMAT_OP_NO && 4206cdf0e10cSrcweir NumFor[2].GetnAnz() == 0 ) 4207cdf0e10cSrcweir bDefault[0] = bDefault[1] = bDefault[2] = bDefault[3] = sal_True; // [];[];; 4208cdf0e10cSrcweir // nothing to do if conditions specified for every subformat 4209cdf0e10cSrcweir } 4210cdf0e10cSrcweir else if ( bDefault[0] ) 4211cdf0e10cSrcweir bDefault[0] = sal_False; // a single unconditional subformat is never delimited 4212cdf0e10cSrcweir else 4213cdf0e10cSrcweir { 4214cdf0e10cSrcweir if ( bDefault[2] && NumFor[2].GetnAnz() == 0 && NumFor[1].GetnAnz() > 0 ) 4215cdf0e10cSrcweir bDefault[3] = sal_True; // special cases x;x;; and ;x;; 4216cdf0e10cSrcweir for ( int i=0; i<3 && !bDefault[i]; ++i ) 4217cdf0e10cSrcweir bDefault[i] = sal_True; 4218cdf0e10cSrcweir } 4219cdf0e10cSrcweir int nSem = 0; // needed ';' delimiters 4220cdf0e10cSrcweir int nSub = 0; // subformats delimited so far 4221cdf0e10cSrcweir for ( int n=0; n<4; n++ ) 4222cdf0e10cSrcweir { 4223cdf0e10cSrcweir if ( n > 0 ) 4224cdf0e10cSrcweir nSem++; 4225cdf0e10cSrcweir 4226cdf0e10cSrcweir String aPrefix; 4227cdf0e10cSrcweir 4228cdf0e10cSrcweir if ( !bDefaults ) 4229cdf0e10cSrcweir { 4230cdf0e10cSrcweir switch ( n ) 4231cdf0e10cSrcweir { 4232cdf0e10cSrcweir case 0 : 4233cdf0e10cSrcweir lcl_SvNumberformat_AddLimitStringImpl( aPrefix, eOp1, 4234cdf0e10cSrcweir fLimit1, rLocWrp.getNumDecimalSep() ); 4235cdf0e10cSrcweir break; 4236cdf0e10cSrcweir case 1 : 4237cdf0e10cSrcweir lcl_SvNumberformat_AddLimitStringImpl( aPrefix, eOp2, 4238cdf0e10cSrcweir fLimit2, rLocWrp.getNumDecimalSep() ); 4239cdf0e10cSrcweir break; 4240cdf0e10cSrcweir } 4241cdf0e10cSrcweir } 4242cdf0e10cSrcweir 4243cdf0e10cSrcweir const String& rColorName = NumFor[n].GetColorName(); 4244cdf0e10cSrcweir if ( rColorName.Len() ) 4245cdf0e10cSrcweir { 4246cdf0e10cSrcweir const NfKeywordTable & rKey = rScan.GetKeywords(); 4247cdf0e10cSrcweir for ( int j=NF_KEY_FIRSTCOLOR; j<=NF_KEY_LASTCOLOR; j++ ) 4248cdf0e10cSrcweir { 4249cdf0e10cSrcweir if ( rKey[j] == rColorName ) 4250cdf0e10cSrcweir { 4251cdf0e10cSrcweir aPrefix += '['; 4252cdf0e10cSrcweir aPrefix += rKeywords[j]; 4253cdf0e10cSrcweir aPrefix += ']'; 4254cdf0e10cSrcweir break; // for 4255cdf0e10cSrcweir } 4256cdf0e10cSrcweir } 4257cdf0e10cSrcweir } 4258cdf0e10cSrcweir 4259cdf0e10cSrcweir const SvNumberNatNum& rNum = NumFor[n].GetNatNum(); 4260cdf0e10cSrcweir // The Thai T NatNum modifier during Xcl export. 4261cdf0e10cSrcweir if (rNum.IsSet() && rNum.GetNatNum() == 1 && 4262cdf0e10cSrcweir rKeywords[NF_KEY_THAI_T].EqualsAscii( "T") && 4263cdf0e10cSrcweir MsLangId::getRealLanguage( rNum.GetLang()) == 4264cdf0e10cSrcweir LANGUAGE_THAI) 4265cdf0e10cSrcweir { 4266cdf0e10cSrcweir aPrefix += 't'; // must be lowercase, otherwise taken as literal 4267cdf0e10cSrcweir } 4268cdf0e10cSrcweir 4269cdf0e10cSrcweir sal_uInt16 nAnz = NumFor[n].GetnAnz(); 4270cdf0e10cSrcweir if ( nSem && (nAnz || aPrefix.Len()) ) 4271cdf0e10cSrcweir { 4272cdf0e10cSrcweir for ( ; nSem; --nSem ) 4273cdf0e10cSrcweir aStr += ';'; 4274cdf0e10cSrcweir for ( ; nSub <= n; ++nSub ) 4275cdf0e10cSrcweir bDefault[nSub] = sal_False; 4276cdf0e10cSrcweir } 4277cdf0e10cSrcweir 4278cdf0e10cSrcweir if ( aPrefix.Len() ) 4279cdf0e10cSrcweir aStr += aPrefix; 4280cdf0e10cSrcweir 4281cdf0e10cSrcweir if ( nAnz ) 4282cdf0e10cSrcweir { 4283cdf0e10cSrcweir const short* pType = NumFor[n].Info().nTypeArray; 4284cdf0e10cSrcweir const String* pStr = NumFor[n].Info().sStrArray; 4285cdf0e10cSrcweir for ( sal_uInt16 j=0; j<nAnz; j++ ) 4286cdf0e10cSrcweir { 4287cdf0e10cSrcweir if ( 0 <= pType[j] && pType[j] < NF_KEYWORD_ENTRIES_COUNT ) 4288cdf0e10cSrcweir { 4289cdf0e10cSrcweir aStr += rKeywords[pType[j]]; 4290cdf0e10cSrcweir if( NF_KEY_NNNN == pType[j] ) 4291cdf0e10cSrcweir aStr += rLocWrp.getLongDateDayOfWeekSep(); 4292cdf0e10cSrcweir } 4293cdf0e10cSrcweir else 4294cdf0e10cSrcweir { 4295cdf0e10cSrcweir switch ( pType[j] ) 4296cdf0e10cSrcweir { 4297cdf0e10cSrcweir case NF_SYMBOLTYPE_DECSEP : 4298cdf0e10cSrcweir aStr += rLocWrp.getNumDecimalSep(); 4299cdf0e10cSrcweir break; 4300cdf0e10cSrcweir case NF_SYMBOLTYPE_THSEP : 4301cdf0e10cSrcweir aStr += rLocWrp.getNumThousandSep(); 4302cdf0e10cSrcweir break; 4303cdf0e10cSrcweir case NF_SYMBOLTYPE_DATESEP : 4304cdf0e10cSrcweir aStr += rLocWrp.getDateSep(); 4305cdf0e10cSrcweir break; 4306cdf0e10cSrcweir case NF_SYMBOLTYPE_TIMESEP : 4307cdf0e10cSrcweir aStr += rLocWrp.getTimeSep(); 4308cdf0e10cSrcweir break; 4309cdf0e10cSrcweir case NF_SYMBOLTYPE_TIME100SECSEP : 4310cdf0e10cSrcweir aStr += rLocWrp.getTime100SecSep(); 4311cdf0e10cSrcweir break; 4312cdf0e10cSrcweir case NF_SYMBOLTYPE_STRING : 4313cdf0e10cSrcweir if( bDontQuote ) 4314cdf0e10cSrcweir aStr += pStr[j]; 4315cdf0e10cSrcweir else if ( pStr[j].Len() == 1 ) 4316cdf0e10cSrcweir { 4317cdf0e10cSrcweir aStr += '\\'; 4318cdf0e10cSrcweir aStr += pStr[j]; 4319cdf0e10cSrcweir } 4320cdf0e10cSrcweir else 4321cdf0e10cSrcweir { 4322cdf0e10cSrcweir aStr += '"'; 4323cdf0e10cSrcweir aStr += pStr[j]; 4324cdf0e10cSrcweir aStr += '"'; 4325cdf0e10cSrcweir } 4326cdf0e10cSrcweir break; 4327cdf0e10cSrcweir default: 4328cdf0e10cSrcweir aStr += pStr[j]; 4329cdf0e10cSrcweir } 4330cdf0e10cSrcweir 4331cdf0e10cSrcweir } 4332cdf0e10cSrcweir } 4333cdf0e10cSrcweir } 4334cdf0e10cSrcweir } 4335cdf0e10cSrcweir for ( ; nSub<4 && bDefault[nSub]; ++nSub ) 4336cdf0e10cSrcweir { // append empty subformats 4337cdf0e10cSrcweir aStr += ';'; 4338cdf0e10cSrcweir } 4339cdf0e10cSrcweir return aStr; 4340cdf0e10cSrcweir } 4341cdf0e10cSrcweir 4342cdf0e10cSrcweir 4343cdf0e10cSrcweir String SvNumberformat::ImpGetNatNumString( const SvNumberNatNum& rNum, 4344cdf0e10cSrcweir sal_Int32 nVal, sal_uInt16 nMinDigits ) const 4345cdf0e10cSrcweir { 4346cdf0e10cSrcweir String aStr; 4347cdf0e10cSrcweir if ( nMinDigits ) 4348cdf0e10cSrcweir { 4349cdf0e10cSrcweir if ( nMinDigits == 2 ) 4350cdf0e10cSrcweir { // speed up the most common case 4351cdf0e10cSrcweir if ( 0 <= nVal && nVal < 10 ) 4352cdf0e10cSrcweir { 4353cdf0e10cSrcweir sal_Unicode* p = aStr.AllocBuffer( 2 ); 4354cdf0e10cSrcweir *p++ = '0'; 4355cdf0e10cSrcweir *p = sal_Unicode( '0' + nVal ); 4356cdf0e10cSrcweir } 4357cdf0e10cSrcweir else 4358cdf0e10cSrcweir aStr = String::CreateFromInt32( nVal ); 4359cdf0e10cSrcweir } 4360cdf0e10cSrcweir else 4361cdf0e10cSrcweir { 4362cdf0e10cSrcweir String aValStr( String::CreateFromInt32( nVal ) ); 4363cdf0e10cSrcweir if ( aValStr.Len() >= nMinDigits ) 4364cdf0e10cSrcweir aStr = aValStr; 4365cdf0e10cSrcweir else 4366cdf0e10cSrcweir { 4367cdf0e10cSrcweir aStr.Fill( nMinDigits - aValStr.Len(), '0' ); 4368cdf0e10cSrcweir aStr += aValStr; 4369cdf0e10cSrcweir } 4370cdf0e10cSrcweir } 4371cdf0e10cSrcweir } 4372cdf0e10cSrcweir else 4373cdf0e10cSrcweir aStr = String::CreateFromInt32( nVal ); 4374cdf0e10cSrcweir ImpTransliterate( aStr, rNum ); 4375cdf0e10cSrcweir return aStr; 4376cdf0e10cSrcweir } 4377cdf0e10cSrcweir 4378cdf0e10cSrcweir 4379cdf0e10cSrcweir void SvNumberformat::ImpTransliterateImpl( String& rStr, 4380cdf0e10cSrcweir const SvNumberNatNum& rNum ) const 4381cdf0e10cSrcweir { 4382cdf0e10cSrcweir com::sun::star::lang::Locale aLocale( 4383cdf0e10cSrcweir MsLangId::convertLanguageToLocale( rNum.GetLang() ) ); 4384cdf0e10cSrcweir rStr = GetFormatter().GetNatNum()->getNativeNumberString( rStr, 4385cdf0e10cSrcweir aLocale, rNum.GetNatNum() ); 4386cdf0e10cSrcweir } 4387cdf0e10cSrcweir 4388cdf0e10cSrcweir 4389cdf0e10cSrcweir void SvNumberformat::GetNatNumXml( 4390cdf0e10cSrcweir com::sun::star::i18n::NativeNumberXmlAttributes& rAttr, 4391cdf0e10cSrcweir sal_uInt16 nNumFor ) const 4392cdf0e10cSrcweir { 4393cdf0e10cSrcweir if ( nNumFor <= 3 ) 4394cdf0e10cSrcweir { 4395cdf0e10cSrcweir const SvNumberNatNum& rNum = NumFor[nNumFor].GetNatNum(); 4396cdf0e10cSrcweir if ( rNum.IsSet() ) 4397cdf0e10cSrcweir { 4398cdf0e10cSrcweir com::sun::star::lang::Locale aLocale( 4399cdf0e10cSrcweir MsLangId::convertLanguageToLocale( rNum.GetLang() ) ); 4400cdf0e10cSrcweir rAttr = GetFormatter().GetNatNum()->convertToXmlAttributes( 4401cdf0e10cSrcweir aLocale, rNum.GetNatNum() ); 4402cdf0e10cSrcweir } 4403cdf0e10cSrcweir else 4404cdf0e10cSrcweir rAttr = com::sun::star::i18n::NativeNumberXmlAttributes(); 4405cdf0e10cSrcweir } 4406cdf0e10cSrcweir else 4407cdf0e10cSrcweir rAttr = com::sun::star::i18n::NativeNumberXmlAttributes(); 4408cdf0e10cSrcweir } 4409cdf0e10cSrcweir 4410cdf0e10cSrcweir // static 4411cdf0e10cSrcweir sal_Bool SvNumberformat::HasStringNegativeSign( const String& rStr ) 4412cdf0e10cSrcweir { 4413cdf0e10cSrcweir // fuer Sign muss '-' am Anfang oder am Ende des TeilStrings sein (Blanks ignored) 4414cdf0e10cSrcweir xub_StrLen nLen = rStr.Len(); 4415cdf0e10cSrcweir if ( !nLen ) 4416cdf0e10cSrcweir return sal_False; 4417cdf0e10cSrcweir const sal_Unicode* const pBeg = rStr.GetBuffer(); 4418cdf0e10cSrcweir const sal_Unicode* const pEnd = pBeg + nLen; 4419cdf0e10cSrcweir register const sal_Unicode* p = pBeg; 4420cdf0e10cSrcweir do 4421cdf0e10cSrcweir { // Anfang 4422cdf0e10cSrcweir if ( *p == '-' ) 4423cdf0e10cSrcweir return sal_True; 4424cdf0e10cSrcweir } while ( *p == ' ' && ++p < pEnd ); 4425cdf0e10cSrcweir p = pEnd - 1; 4426cdf0e10cSrcweir do 4427cdf0e10cSrcweir { // Ende 4428cdf0e10cSrcweir if ( *p == '-' ) 4429cdf0e10cSrcweir return sal_True; 4430cdf0e10cSrcweir } while ( *p == ' ' && pBeg < --p ); 4431cdf0e10cSrcweir return sal_False; 4432cdf0e10cSrcweir } 4433cdf0e10cSrcweir 4434cdf0e10cSrcweir 4435cdf0e10cSrcweir // static 4436cdf0e10cSrcweir void SvNumberformat::SetComment( const String& rStr, String& rFormat, 4437cdf0e10cSrcweir String& rComment ) 4438cdf0e10cSrcweir { 4439cdf0e10cSrcweir if ( rComment.Len() ) 4440cdf0e10cSrcweir { // alten Kommentar aus Formatstring loeschen 4441cdf0e10cSrcweir //! nicht per EraseComment, der Kommentar muss matchen 4442cdf0e10cSrcweir String aTmp( '{' ); 4443cdf0e10cSrcweir aTmp += ' '; 4444cdf0e10cSrcweir aTmp += rComment; 4445cdf0e10cSrcweir aTmp += ' '; 4446cdf0e10cSrcweir aTmp += '}'; 4447cdf0e10cSrcweir xub_StrLen nCom = 0; 4448cdf0e10cSrcweir do 4449cdf0e10cSrcweir { 4450cdf0e10cSrcweir nCom = rFormat.Search( aTmp, nCom ); 4451cdf0e10cSrcweir } while ( (nCom != STRING_NOTFOUND) && (nCom + aTmp.Len() != rFormat.Len()) ); 4452cdf0e10cSrcweir if ( nCom != STRING_NOTFOUND ) 4453cdf0e10cSrcweir rFormat.Erase( nCom ); 4454cdf0e10cSrcweir } 4455cdf0e10cSrcweir if ( rStr.Len() ) 4456cdf0e10cSrcweir { // neuen Kommentar setzen 4457cdf0e10cSrcweir rFormat += '{'; 4458cdf0e10cSrcweir rFormat += ' '; 4459cdf0e10cSrcweir rFormat += rStr; 4460cdf0e10cSrcweir rFormat += ' '; 4461cdf0e10cSrcweir rFormat += '}'; 4462cdf0e10cSrcweir rComment = rStr; 4463cdf0e10cSrcweir } 4464cdf0e10cSrcweir } 4465cdf0e10cSrcweir 4466cdf0e10cSrcweir 4467cdf0e10cSrcweir // static 4468cdf0e10cSrcweir void SvNumberformat::EraseCommentBraces( String& rStr ) 4469cdf0e10cSrcweir { 4470cdf0e10cSrcweir xub_StrLen nLen = rStr.Len(); 4471cdf0e10cSrcweir if ( nLen && rStr.GetChar(0) == '{' ) 4472cdf0e10cSrcweir { 4473cdf0e10cSrcweir rStr.Erase( 0, 1 ); 4474cdf0e10cSrcweir --nLen; 4475cdf0e10cSrcweir } 4476cdf0e10cSrcweir if ( nLen && rStr.GetChar(0) == ' ' ) 4477cdf0e10cSrcweir { 4478cdf0e10cSrcweir rStr.Erase( 0, 1 ); 4479cdf0e10cSrcweir --nLen; 4480cdf0e10cSrcweir } 4481cdf0e10cSrcweir if ( nLen && rStr.GetChar( nLen-1 ) == '}' ) 4482cdf0e10cSrcweir rStr.Erase( --nLen, 1 ); 4483cdf0e10cSrcweir if ( nLen && rStr.GetChar( nLen-1 ) == ' ' ) 4484cdf0e10cSrcweir rStr.Erase( --nLen, 1 ); 4485cdf0e10cSrcweir } 4486cdf0e10cSrcweir 4487cdf0e10cSrcweir 4488cdf0e10cSrcweir // static 4489cdf0e10cSrcweir void SvNumberformat::EraseComment( String& rStr ) 4490cdf0e10cSrcweir { 4491cdf0e10cSrcweir register const sal_Unicode* p = rStr.GetBuffer(); 4492cdf0e10cSrcweir sal_Bool bInString = sal_False; 4493cdf0e10cSrcweir sal_Bool bEscaped = sal_False; 4494cdf0e10cSrcweir sal_Bool bFound = sal_False; 4495cdf0e10cSrcweir xub_StrLen nPos = 0; 4496cdf0e10cSrcweir while ( !bFound && *p ) 4497cdf0e10cSrcweir { 4498cdf0e10cSrcweir switch ( *p ) 4499cdf0e10cSrcweir { 4500cdf0e10cSrcweir case '\\' : 4501cdf0e10cSrcweir bEscaped = !bEscaped; 4502cdf0e10cSrcweir break; 4503cdf0e10cSrcweir case '\"' : 4504cdf0e10cSrcweir if ( !bEscaped ) 4505cdf0e10cSrcweir bInString = !bInString; 4506cdf0e10cSrcweir break; 4507cdf0e10cSrcweir case '{' : 4508cdf0e10cSrcweir if ( !bEscaped && !bInString ) 4509cdf0e10cSrcweir { 4510cdf0e10cSrcweir bFound = sal_True; 4511cdf0e10cSrcweir nPos = sal::static_int_cast< xub_StrLen >( 4512cdf0e10cSrcweir p - rStr.GetBuffer()); 4513cdf0e10cSrcweir } 4514cdf0e10cSrcweir break; 4515cdf0e10cSrcweir } 4516cdf0e10cSrcweir if ( bEscaped && *p != '\\' ) 4517cdf0e10cSrcweir bEscaped = sal_False; 4518cdf0e10cSrcweir ++p; 4519cdf0e10cSrcweir } 4520cdf0e10cSrcweir if ( bFound ) 4521cdf0e10cSrcweir rStr.Erase( nPos ); 4522cdf0e10cSrcweir } 4523cdf0e10cSrcweir 4524cdf0e10cSrcweir 4525cdf0e10cSrcweir // static 4526cdf0e10cSrcweir sal_Bool SvNumberformat::IsInQuote( const String& rStr, xub_StrLen nPos, 4527cdf0e10cSrcweir sal_Unicode cQuote, sal_Unicode cEscIn, sal_Unicode cEscOut ) 4528cdf0e10cSrcweir { 4529cdf0e10cSrcweir xub_StrLen nLen = rStr.Len(); 4530cdf0e10cSrcweir if ( nPos >= nLen ) 4531cdf0e10cSrcweir return sal_False; 4532cdf0e10cSrcweir register const sal_Unicode* p0 = rStr.GetBuffer(); 4533cdf0e10cSrcweir register const sal_Unicode* p = p0; 4534cdf0e10cSrcweir register const sal_Unicode* p1 = p0 + nPos; 4535cdf0e10cSrcweir sal_Bool bQuoted = sal_False; 4536cdf0e10cSrcweir while ( p <= p1 ) 4537cdf0e10cSrcweir { 4538cdf0e10cSrcweir if ( *p == cQuote ) 4539cdf0e10cSrcweir { 4540cdf0e10cSrcweir if ( p == p0 ) 4541cdf0e10cSrcweir bQuoted = sal_True; 4542cdf0e10cSrcweir else if ( bQuoted ) 4543cdf0e10cSrcweir { 4544cdf0e10cSrcweir if ( *(p-1) != cEscIn ) 4545cdf0e10cSrcweir bQuoted = sal_False; 4546cdf0e10cSrcweir } 4547cdf0e10cSrcweir else 4548cdf0e10cSrcweir { 4549cdf0e10cSrcweir if ( *(p-1) != cEscOut ) 4550cdf0e10cSrcweir bQuoted = sal_True; 4551cdf0e10cSrcweir } 4552cdf0e10cSrcweir } 4553cdf0e10cSrcweir p++; 4554cdf0e10cSrcweir } 4555cdf0e10cSrcweir return bQuoted; 4556cdf0e10cSrcweir } 4557cdf0e10cSrcweir 4558cdf0e10cSrcweir 4559cdf0e10cSrcweir // static 4560cdf0e10cSrcweir xub_StrLen SvNumberformat::GetQuoteEnd( const String& rStr, xub_StrLen nPos, 4561cdf0e10cSrcweir sal_Unicode cQuote, sal_Unicode cEscIn, sal_Unicode cEscOut ) 4562cdf0e10cSrcweir { 4563cdf0e10cSrcweir xub_StrLen nLen = rStr.Len(); 4564cdf0e10cSrcweir if ( nPos >= nLen ) 4565cdf0e10cSrcweir return STRING_NOTFOUND; 4566cdf0e10cSrcweir if ( !IsInQuote( rStr, nPos, cQuote, cEscIn, cEscOut ) ) 4567cdf0e10cSrcweir { 4568cdf0e10cSrcweir if ( rStr.GetChar( nPos ) == cQuote ) 4569cdf0e10cSrcweir return nPos; // schliessendes cQuote 4570cdf0e10cSrcweir return STRING_NOTFOUND; 4571cdf0e10cSrcweir } 4572cdf0e10cSrcweir register const sal_Unicode* p0 = rStr.GetBuffer(); 4573cdf0e10cSrcweir register const sal_Unicode* p = p0 + nPos; 4574cdf0e10cSrcweir register const sal_Unicode* p1 = p0 + nLen; 4575cdf0e10cSrcweir while ( p < p1 ) 4576cdf0e10cSrcweir { 4577cdf0e10cSrcweir if ( *p == cQuote && p > p0 && *(p-1) != cEscIn ) 4578cdf0e10cSrcweir return sal::static_int_cast< xub_StrLen >(p - p0); 4579cdf0e10cSrcweir p++; 4580cdf0e10cSrcweir } 4581cdf0e10cSrcweir return nLen; // String Ende 4582cdf0e10cSrcweir } 4583cdf0e10cSrcweir 4584cdf0e10cSrcweir 4585cdf0e10cSrcweir sal_uInt16 SvNumberformat::ImpGetNumForStringElementCount( sal_uInt16 nNumFor ) const 4586cdf0e10cSrcweir { 4587cdf0e10cSrcweir sal_uInt16 nCnt = 0; 4588cdf0e10cSrcweir sal_uInt16 nAnz = NumFor[nNumFor].GetnAnz(); 4589cdf0e10cSrcweir short const * const pType = NumFor[nNumFor].Info().nTypeArray; 4590cdf0e10cSrcweir for ( sal_uInt16 j=0; j<nAnz; ++j ) 4591cdf0e10cSrcweir { 4592cdf0e10cSrcweir switch ( pType[j] ) 4593cdf0e10cSrcweir { 4594cdf0e10cSrcweir case NF_SYMBOLTYPE_STRING: 4595cdf0e10cSrcweir case NF_SYMBOLTYPE_CURRENCY: 4596cdf0e10cSrcweir case NF_SYMBOLTYPE_DATESEP: 4597cdf0e10cSrcweir case NF_SYMBOLTYPE_TIMESEP: 4598cdf0e10cSrcweir case NF_SYMBOLTYPE_TIME100SECSEP: 4599cdf0e10cSrcweir case NF_SYMBOLTYPE_PERCENT: 4600cdf0e10cSrcweir ++nCnt; 4601cdf0e10cSrcweir break; 4602cdf0e10cSrcweir } 4603cdf0e10cSrcweir } 4604cdf0e10cSrcweir return nCnt; 4605cdf0e10cSrcweir } 4606cdf0e10cSrcweir 4607