1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <vcl/svapp.hxx>
21 #include <vcl/settings.hxx>
22 #include <svl/zforlist.hxx>
23 #include <tools/color.hxx>
24 #include <i18nlangtag/lang.h>
25 #include <basic/sberrors.hxx>
26 #include "sbxconv.hxx"
27 #include <runtime.hxx>
28 #include <sbintern.hxx>
31 #include <config_features.h>
34 double ImpGetDate( const SbxValues
* p
)
42 SbxBase::SetError( ERRCODE_BASIC_CONVERSION
);
62 nRes
= static_cast<double>(p
->nLong
);
65 nRes
= static_cast<double>(p
->nULong
);
75 nRes
= ImpCurrencyToDouble( p
->nInt64
);
78 nRes
= static_cast< double >(p
->nInt64
);
81 nRes
= ImpSalUInt64ToDouble( p
->uInt64
);
84 case SbxBYREF
| SbxDECIMAL
:
87 p
->pDecimal
->getDouble( nRes
);
94 case SbxBYREF
| SbxSTRING
:
97 #if HAVE_FEATURE_SCRIPTING
104 LanguageType eLangType
= Application::GetSettings().GetLanguageTag().getLanguageType();
105 std::shared_ptr
<SvNumberFormatter
> pFormatter
;
106 if (GetSbData()->pInst
)
108 pFormatter
= GetSbData()->pInst
->GetNumberFormatter();
113 pFormatter
= SbiInstance::PrepareNumberFormatter( nDummy
, nDummy
, nDummy
);
117 sal_Int32 nCheckPos
= 0;
118 SvNumFormatType nType
= SvNumFormatType::DEFINED
| SvNumFormatType::DATE
| SvNumFormatType::TIME
| SvNumFormatType::CURRENCY
119 | SvNumFormatType::NUMBER
| SvNumFormatType::SCIENTIFIC
| SvNumFormatType::FRACTION
;
121 // Default templates of the formatter have only two-digit
122 // date. Therefore register an own format.
124 // HACK, because the number formatter in PutandConvertEntry replace the wildcard
125 // for month, day, year not according to the configuration.
126 // Problem: Print Year(Date) under Engl. OS
127 // quod vide basic/source/runtime/runtime.cxx
129 SvtSysLocale aSysLocale
;
130 DateOrder eDate
= aSysLocale
.GetLocaleData().getDateOrder();
135 case DateOrder::MDY
: aDateStr
= "MM/DD/YYYY"; break;
136 case DateOrder::DMY
: aDateStr
= "DD/MM/YYYY"; break;
137 case DateOrder::YMD
: aDateStr
= "YYYY/MM/DD"; break;
140 OUString aStr
= aDateStr
+ " HH:MM:SS";
142 pFormatter
->PutandConvertEntry( aStr
, nCheckPos
, nType
,
143 nIndex
, LANGUAGE_ENGLISH_US
, eLangType
, true);
144 bool bSuccess
= pFormatter
->IsNumberFormat( *p
->pOUString
, nIndex
, nRes
);
147 SvNumFormatType nType_
= pFormatter
->GetType( nIndex
);
148 if(!(nType_
& ( SvNumFormatType::DATETIME
| SvNumFormatType::DATE
|
149 SvNumFormatType::TIME
| SvNumFormatType::DEFINED
)))
157 SbxBase::SetError( ERRCODE_BASIC_CONVERSION
); nRes
= 0;
165 pVal
= dynamic_cast<SbxValue
*>( p
->pObj
);
168 nRes
= pVal
->GetDate();
172 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT
); nRes
= 0;
175 case SbxBYREF
| SbxCHAR
:
178 case SbxBYREF
| SbxBYTE
:
181 case SbxBYREF
| SbxINTEGER
:
182 case SbxBYREF
| SbxBOOL
:
185 case SbxBYREF
| SbxLONG
:
188 case SbxBYREF
| SbxULONG
:
191 case SbxBYREF
| SbxERROR
:
192 case SbxBYREF
| SbxUSHORT
:
195 case SbxBYREF
| SbxSINGLE
:
198 case SbxBYREF
| SbxDATE
:
199 case SbxBYREF
| SbxDOUBLE
:
202 case SbxBYREF
| SbxCURRENCY
:
203 nRes
= ImpCurrencyToDouble( *p
->pnInt64
);
205 case SbxBYREF
| SbxSALINT64
:
206 nRes
= static_cast< double >(*p
->pnInt64
);
208 case SbxBYREF
| SbxSALUINT64
:
209 nRes
= ImpSalUInt64ToDouble( *p
->puInt64
);
212 SbxBase::SetError( ERRCODE_BASIC_CONVERSION
); nRes
= 0;
218 void ImpPutDate( SbxValues
* p
, double n
)
231 // from here will be tested
233 aTmp
.pChar
= &p
->nChar
;
236 aTmp
.pByte
= &p
->nByte
;
240 aTmp
.pInteger
= &p
->nInteger
;
243 aTmp
.pLong
= &p
->nLong
;
246 aTmp
.pULong
= &p
->nULong
;
250 aTmp
.pUShort
= &p
->nUShort
;
253 aTmp
.pSingle
= &p
->nSingle
;
257 aTmp
.pnInt64
= &p
->nInt64
;
260 aTmp
.puInt64
= &p
->uInt64
;
263 case SbxBYREF
| SbxDECIMAL
:
264 pDec
= ImpCreateDecimal( p
);
265 if( !pDec
->setDouble( n
) )
267 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
);
271 aTmp
.eType
= SbxDataType( p
->eType
| SbxBYREF
);
272 p
= &aTmp
; goto start
;
274 case SbxBYREF
| SbxSTRING
:
278 #if HAVE_FEATURE_SCRIPTING
281 p
->pOUString
= new OUString
;
285 LanguageType eLangType
= Application::GetSettings().GetLanguageTag().getLanguageType();
286 std::shared_ptr
<SvNumberFormatter
> pFormatter
;
287 if (GetSbData()->pInst
)
289 pFormatter
= GetSbData()->pInst
->GetNumberFormatter();
294 pFormatter
= SbiInstance::PrepareNumberFormatter( nDummy
, nDummy
, nDummy
);
298 sal_Int32 nCheckPos
= 0;
299 SvNumFormatType nType
;
301 SvtSysLocale aSysLocale
;
302 DateOrder eDate
= aSysLocale
.GetLocaleData().getDateOrder();
304 // if the whole-number part is 0, we want no year!
305 if( n
<= -1.0 || n
>= 1.0 )
307 // Time only if != 00:00:00
308 if( rtl::math::approxEqual(floor( n
), n
) )
313 case DateOrder::MDY
: aStr
= "MM/DD/YYYY"; break;
314 case DateOrder::DMY
: aStr
= "DD/MM/YYYY"; break;
315 case DateOrder::YMD
: aStr
= "YYYY/MM/DD"; break;
323 case DateOrder::MDY
: aStr
= "MM/DD/YYYY HH:MM:SS"; break;
324 case DateOrder::DMY
: aStr
= "DD/MM/YYYY HH:MM:SS"; break;
325 case DateOrder::YMD
: aStr
= "YYYY/MM/DD HH:MM:SS"; break;
333 pFormatter
->PutandConvertEntry( aStr
,
339 pFormatter
->GetOutputString( n
, nIndex
, *p
->pOUString
, &pColor
);
344 pVal
= dynamic_cast<SbxValue
*>( p
->pObj
);
351 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT
);
354 case SbxBYREF
| SbxCHAR
:
357 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMAXCHAR
;
359 else if( n
< SbxMINCHAR
)
361 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMINCHAR
;
363 *p
->pChar
= static_cast<sal_Unicode
>(n
);
365 case SbxBYREF
| SbxBYTE
:
368 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMAXBYTE
;
372 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= 0;
374 *p
->pByte
= static_cast<sal_uInt8
>(n
);
376 case SbxBYREF
| SbxINTEGER
:
377 case SbxBYREF
| SbxBOOL
:
380 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMAXINT
;
382 else if( n
< SbxMININT
)
384 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMININT
;
386 *p
->pInteger
= static_cast<sal_Int16
>(n
);
388 case SbxBYREF
| SbxERROR
:
389 case SbxBYREF
| SbxUSHORT
:
392 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMAXUINT
;
396 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= 0;
398 *p
->pUShort
= static_cast<sal_uInt16
>(n
);
400 case SbxBYREF
| SbxLONG
:
403 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMAXLNG
;
405 else if( n
< SbxMINLNG
)
407 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMINLNG
;
409 *p
->pLong
= static_cast<sal_Int32
>(n
);
411 case SbxBYREF
| SbxULONG
:
414 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMAXULNG
;
418 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= 0;
420 *p
->pULong
= static_cast<sal_uInt32
>(n
);
422 case SbxBYREF
| SbxSINGLE
:
425 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMAXSNG
;
427 else if( n
< SbxMINSNG
)
429 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMINSNG
;
431 *p
->pSingle
= static_cast<float>(n
);
433 case SbxBYREF
| SbxSALINT64
:
434 *p
->pnInt64
= ImpDoubleToSalInt64( n
);
436 case SbxBYREF
| SbxSALUINT64
:
437 *p
->puInt64
= ImpDoubleToSalUInt64( n
);
439 case SbxBYREF
| SbxDATE
:
440 case SbxBYREF
| SbxDOUBLE
:
443 case SbxBYREF
| SbxCURRENCY
:
446 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMAXCURR
;
448 else if( n
< SbxMINCURR
)
450 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMINCURR
;
452 *p
->pnInt64
= ImpDoubleToCurrency( n
);
455 SbxBase::SetError( ERRCODE_BASIC_CONVERSION
);
460 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */