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