1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_basic.hxx" 30 #include <vcl/svapp.hxx> 31 #include <svl/zforlist.hxx> 32 #include <tools/errcode.hxx> 33 #include <tools/color.hxx> 34 #include <i18npool/lang.h> 35 #include <basic/sbx.hxx> 36 #include "sbxconv.hxx" 37 #include "math.h" 38 #include <comphelper/processfactory.hxx> 39 40 41 double ImpGetDate( const SbxValues* p ) 42 { 43 double nRes; 44 switch( +p->eType ) 45 { 46 case SbxNULL: 47 SbxBase::SetError( SbxERR_CONVERSION ); 48 case SbxEMPTY: 49 nRes = 0; break; 50 case SbxCHAR: 51 nRes = p->nChar; break; 52 case SbxBYTE: 53 nRes = p->nByte; break; 54 case SbxINTEGER: 55 case SbxBOOL: 56 nRes = p->nInteger; break; 57 case SbxERROR: 58 case SbxUSHORT: 59 nRes = p->nUShort; break; 60 case SbxLONG: 61 nRes = (double) p->nLong; break; 62 case SbxULONG: 63 nRes = (double) p->nULong; break; 64 case SbxSINGLE: 65 nRes = p->nSingle; break; 66 case SbxDATE: 67 case SbxDOUBLE: 68 nRes = p->nDouble; break; 69 case SbxULONG64: 70 nRes = ImpUINT64ToDouble( p->nULong64 ); break; 71 case SbxLONG64: 72 nRes = ImpINT64ToDouble( p->nLong64 ); break; 73 case SbxCURRENCY: 74 nRes = ImpCurrencyToDouble( p->nLong64 ); break; 75 case SbxSALINT64: 76 nRes = static_cast< double >(p->nInt64); break; 77 case SbxSALUINT64: 78 nRes = ImpSalUInt64ToDouble( p->uInt64 ); break; 79 case SbxDECIMAL: 80 case SbxBYREF | SbxDECIMAL: 81 if( p->pDecimal ) 82 p->pDecimal->getDouble( nRes ); 83 else 84 nRes = 0.0; 85 break; 86 case SbxBYREF | SbxSTRING: 87 case SbxSTRING: 88 case SbxLPSTR: 89 if( !p->pOUString ) 90 nRes = 0; 91 else 92 { 93 LanguageType eLangType = GetpApp()->GetSettings().GetLanguage(); 94 95 SvNumberFormatter* pFormatter; 96 com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > 97 xFactory = comphelper::getProcessServiceFactory(); 98 pFormatter = new SvNumberFormatter( xFactory, eLangType ); 99 100 sal_uInt32 nIndex; 101 xub_StrLen nCheckPos = 0; 102 short nType = 127; 103 104 // Standard-Vorlagen des Formatters haben nur zweistellige 105 // Jahreszahl. Deshalb eigenes Format registrieren 106 107 // HACK, da der Numberformatter in PutandConvertEntry die Platzhalter 108 // fuer Monat, Tag, Jahr nicht entsprechend der Systemeinstellung 109 // austauscht. Problem: Print Year(Date) unter engl. BS 110 // siehe auch basic\source\runtime\runtime.cxx 111 112 SvtSysLocale aSysLocale; 113 DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat(); 114 String aDateStr; 115 switch( eDate ) 116 { 117 case MDY: aDateStr.AssignAscii( "MM.TT.JJJJ" ); break; 118 case DMY: aDateStr.AssignAscii( "TT.MM.JJJJ" ); break; 119 case YMD: aDateStr.AssignAscii( "JJJJ.MM.TT" ); break; 120 default: aDateStr.AssignAscii( "MM.TT.JJJJ" ); 121 } 122 123 String aStr( aDateStr ); 124 aStr.AppendAscii( " HH:MM:SS" ); 125 126 pFormatter->PutandConvertEntry( aStr, nCheckPos, nType, 127 nIndex, LANGUAGE_GERMAN, eLangType ); 128 sal_Bool bSuccess = pFormatter->IsNumberFormat( *p->pOUString, nIndex, nRes ); 129 if ( bSuccess ) 130 { 131 short nType_ = pFormatter->GetType( nIndex ); 132 if(!(nType_ & ( NUMBERFORMAT_DATETIME | NUMBERFORMAT_DATE | 133 NUMBERFORMAT_TIME | NUMBERFORMAT_DEFINED ))) 134 bSuccess = sal_False; 135 } 136 137 if ( !bSuccess ) 138 { 139 SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0; 140 } 141 142 delete pFormatter; 143 } 144 break; 145 case SbxOBJECT: 146 { 147 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj); 148 if( pVal ) 149 nRes = pVal->GetDate(); 150 else 151 { 152 SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0; 153 } 154 break; 155 } 156 157 case SbxBYREF | SbxCHAR: 158 nRes = *p->pChar; break; 159 case SbxBYREF | SbxBYTE: 160 nRes = *p->pByte; break; 161 case SbxBYREF | SbxINTEGER: 162 case SbxBYREF | SbxBOOL: 163 nRes = *p->pInteger; break; 164 case SbxBYREF | SbxLONG: 165 nRes = *p->pLong; break; 166 case SbxBYREF | SbxULONG: 167 nRes = *p->pULong; break; 168 case SbxBYREF | SbxERROR: 169 case SbxBYREF | SbxUSHORT: 170 nRes = *p->pUShort; break; 171 case SbxBYREF | SbxSINGLE: 172 nRes = *p->pSingle; break; 173 case SbxBYREF | SbxDATE: 174 case SbxBYREF | SbxDOUBLE: 175 nRes = *p->pDouble; break; 176 case SbxBYREF | SbxULONG64: 177 nRes = ImpUINT64ToDouble( *p->pULong64 ); break; 178 case SbxBYREF | SbxLONG64: 179 nRes = ImpINT64ToDouble( *p->pLong64 ); break; 180 case SbxBYREF | SbxCURRENCY: 181 nRes = ImpCurrencyToDouble( *p->pLong64 ); break; 182 case SbxBYREF | SbxSALINT64: 183 nRes = static_cast< double >(*p->pnInt64); break; 184 case SbxBYREF | SbxSALUINT64: 185 nRes = ImpSalUInt64ToDouble( *p->puInt64 ); break; 186 187 default: 188 SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0; 189 } 190 return nRes; 191 } 192 193 void ImpPutDate( SbxValues* p, double n ) 194 { 195 SbxValues aTmp; 196 197 start: 198 switch( +p->eType ) 199 { 200 case SbxDATE: 201 case SbxDOUBLE: 202 p->nDouble = n; break; 203 204 // ab hier wird getestet 205 case SbxCHAR: 206 aTmp.pChar = &p->nChar; goto direct; 207 case SbxBYTE: 208 aTmp.pByte = &p->nByte; goto direct; 209 case SbxINTEGER: 210 case SbxBOOL: 211 aTmp.pInteger = &p->nInteger; goto direct; 212 case SbxLONG: 213 aTmp.pLong = &p->nLong; goto direct; 214 case SbxULONG: 215 aTmp.pULong = &p->nULong; goto direct; 216 case SbxERROR: 217 case SbxUSHORT: 218 aTmp.pUShort = &p->nUShort; goto direct; 219 case SbxSINGLE: 220 aTmp.pSingle = &p->nSingle; goto direct; 221 case SbxULONG64: 222 aTmp.pULong64 = &p->nULong64; goto direct; 223 case SbxLONG64: 224 case SbxCURRENCY: 225 aTmp.pLong64 = &p->nLong64; goto direct; 226 case SbxSALINT64: 227 aTmp.pnInt64 = &p->nInt64; goto direct; 228 case SbxSALUINT64: 229 aTmp.puInt64 = &p->uInt64; goto direct; 230 case SbxDECIMAL: 231 case SbxBYREF | SbxDECIMAL: 232 { 233 SbxDecimal* pDec = ImpCreateDecimal( p ); 234 if( !pDec->setDouble( n ) ) 235 SbxBase::SetError( SbxERR_OVERFLOW ); 236 break; 237 } 238 direct: 239 aTmp.eType = SbxDataType( p->eType | SbxBYREF ); 240 p = &aTmp; goto start; 241 242 case SbxBYREF | SbxSTRING: 243 case SbxSTRING: 244 case SbxLPSTR: 245 { 246 if( !p->pOUString ) 247 p->pOUString = new ::rtl::OUString; 248 Color* pColor; 249 250 LanguageType eLangType = GetpApp()->GetSettings().GetLanguage(); 251 SvNumberFormatter* pFormatter; 252 com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > 253 xFactory = comphelper::getProcessServiceFactory(); 254 pFormatter = new SvNumberFormatter( xFactory, eLangType ); 255 256 sal_uInt32 nIndex; 257 xub_StrLen nCheckPos = 0; 258 short nType; 259 260 SvtSysLocale aSysLocale; 261 DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat(); 262 String aStr; 263 // ist der ganzzahlige Teil 0, wollen wir kein Jahr! 264 if( n <= -1.0 || n >= 1.0 ) 265 { 266 // Time only if != 00:00:00 267 if( floor( n ) == n ) 268 { 269 switch( eDate ) 270 { 271 case MDY: aStr.AssignAscii( "MM.TT.JJJJ" ); break; 272 case DMY: aStr.AssignAscii( "TT.MM.JJJJ" ); break; 273 case YMD: aStr.AssignAscii( "JJJJ.MM.TT" ); break; 274 default: aStr.AssignAscii( "MM.TT.JJJJ" ); 275 } 276 } 277 else 278 { 279 switch( eDate ) 280 { 281 case MDY: aStr.AssignAscii( "MM.TT.JJJJ HH:MM:SS" ); break; 282 case DMY: aStr.AssignAscii( "TT.MM.JJJJ HH:MM:SS" ); break; 283 case YMD: aStr.AssignAscii( "JJJJ.MM.TT HH:MM:SS" ); break; 284 default: aStr.AssignAscii( "MM.TT.JJJJ HH:MM:SS" ); 285 } 286 } 287 } 288 else 289 aStr.AppendAscii( "HH:MM:SS" ); 290 291 pFormatter->PutandConvertEntry( aStr, 292 nCheckPos, 293 nType, 294 nIndex, 295 LANGUAGE_GERMAN, 296 eLangType ); 297 String aTmpString; 298 pFormatter->GetOutputString( n, nIndex, aTmpString, &pColor ); 299 *p->pOUString = aTmpString; 300 delete pFormatter; 301 break; 302 } 303 case SbxOBJECT: 304 { 305 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj); 306 if( pVal ) 307 pVal->PutDate( n ); 308 else 309 SbxBase::SetError( SbxERR_NO_OBJECT ); 310 break; 311 } 312 case SbxBYREF | SbxCHAR: 313 if( n > SbxMAXCHAR ) 314 { 315 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR; 316 } 317 else if( n < SbxMINCHAR ) 318 { 319 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR; 320 } 321 *p->pChar = (xub_Unicode) n; break; 322 case SbxBYREF | SbxBYTE: 323 if( n > SbxMAXBYTE ) 324 { 325 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE; 326 } 327 else if( n < 0 ) 328 { 329 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0; 330 } 331 *p->pByte = (sal_uInt8) n; break; 332 case SbxBYREF | SbxINTEGER: 333 case SbxBYREF | SbxBOOL: 334 if( n > SbxMAXINT ) 335 { 336 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT; 337 } 338 else if( n < SbxMININT ) 339 { 340 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT; 341 } 342 *p->pInteger = (sal_Int16) n; break; 343 case SbxBYREF | SbxERROR: 344 case SbxBYREF | SbxUSHORT: 345 if( n > SbxMAXUINT ) 346 { 347 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT; 348 } 349 else if( n < 0 ) 350 { 351 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0; 352 } 353 *p->pUShort = (sal_uInt16) n; break; 354 case SbxBYREF | SbxLONG: 355 if( n > SbxMAXLNG ) 356 { 357 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG; 358 } 359 else if( n < SbxMINLNG ) 360 { 361 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINLNG; 362 } 363 *p->pLong = (sal_Int32) n; break; 364 case SbxBYREF | SbxULONG: 365 if( n > SbxMAXULNG ) 366 { 367 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG; 368 } 369 else if( n < 0 ) 370 { 371 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0; 372 } 373 *p->pULong = (sal_uInt32) n; break; 374 case SbxBYREF | SbxSINGLE: 375 if( n > SbxMAXSNG ) 376 { 377 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXSNG; 378 } 379 else if( n < SbxMINSNG ) 380 { 381 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINSNG; 382 } 383 *p->pSingle = (float) n; break; 384 case SbxBYREF | SbxSALINT64: 385 *p->pnInt64 = ImpDoubleToSalInt64( n ); break; 386 case SbxBYREF | SbxSALUINT64: 387 *p->puInt64 = ImpDoubleToSalUInt64( n ); break; 388 case SbxBYREF | SbxDATE: 389 case SbxBYREF | SbxDOUBLE: 390 *p->pDouble = (double) n; break; 391 case SbxBYREF | SbxCURRENCY: 392 if( n > SbxMAXCURR ) 393 { 394 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCURR; 395 } 396 else if( n < SbxMINCURR ) 397 { 398 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCURR; 399 } 400 *p->pLong64 = ImpDoubleToCurrency( n ); break; 401 402 default: 403 SbxBase::SetError( SbxERR_CONVERSION ); 404 } 405 } 406 407