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