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 <rtl/math.hxx>
21 #include <vcl/svapp.hxx>
22 #include <vcl/settings.hxx>
23 #include <svl/zforlist.hxx>
24 #include <tools/color.hxx>
25 #include <i18nlangtag/lang.h>
26 #include <basic/sberrors.hxx>
27 #include "sbxconv.hxx"
28 #include <runtime.hxx>
29 #include <sbintern.hxx>
32 #include <config_features.h>
35 double ImpGetDate( const SbxValues
* p
)
43 SbxBase::SetError( ERRCODE_BASIC_CONVERSION
);
63 nRes
= static_cast<double>(p
->nLong
);
66 nRes
= static_cast<double>(p
->nULong
);
76 nRes
= ImpCurrencyToDouble( p
->nInt64
);
79 nRes
= static_cast< double >(p
->nInt64
);
82 nRes
= ImpSalUInt64ToDouble( p
->uInt64
);
85 case SbxBYREF
| SbxDECIMAL
:
88 p
->pDecimal
->getDouble( nRes
);
95 case SbxBYREF
| SbxSTRING
:
98 #if HAVE_FEATURE_SCRIPTING
105 LanguageType eLangType
= Application::GetSettings().GetLanguageTag().getLanguageType();
106 std::shared_ptr
<SvNumberFormatter
> pFormatter
;
107 if (GetSbData()->pInst
)
109 pFormatter
= GetSbData()->pInst
->GetNumberFormatter();
114 pFormatter
= SbiInstance::PrepareNumberFormatter( nDummy
, nDummy
, nDummy
);
118 sal_Int32 nCheckPos
= 0;
119 SvNumFormatType nType
= SvNumFormatType::DEFINED
| SvNumFormatType::DATE
| SvNumFormatType::TIME
| SvNumFormatType::CURRENCY
120 | SvNumFormatType::NUMBER
| SvNumFormatType::SCIENTIFIC
| SvNumFormatType::FRACTION
;
122 // Default templates of the formatter have only two-digit
123 // date. Therefore register an own format.
125 // HACK, because the number formatter in PutandConvertEntry replace the wildcard
126 // for month, day, year not according to the configuration.
127 // Problem: Print Year(Date) under Engl. OS
128 // quod vide basic/source/runtime/runtime.cxx
130 SvtSysLocale aSysLocale
;
131 DateOrder eDate
= aSysLocale
.GetLocaleData().getDateOrder();
136 case DateOrder::MDY
: aDateStr
= "MM/DD/YYYY"; break;
137 case DateOrder::DMY
: aDateStr
= "DD/MM/YYYY"; break;
138 case DateOrder::YMD
: aDateStr
= "YYYY/MM/DD"; break;
141 OUString aStr
= aDateStr
+ " HH:MM:SS";
143 pFormatter
->PutandConvertEntry( aStr
, nCheckPos
, nType
,
144 nIndex
, LANGUAGE_ENGLISH_US
, eLangType
, true);
145 bool bSuccess
= pFormatter
->IsNumberFormat( *p
->pOUString
, nIndex
, nRes
);
148 SvNumFormatType nType_
= pFormatter
->GetType( nIndex
);
149 if(!(nType_
& ( SvNumFormatType::DATETIME
| SvNumFormatType::DATE
|
150 SvNumFormatType::TIME
| SvNumFormatType::DEFINED
)))
158 SbxBase::SetError( ERRCODE_BASIC_CONVERSION
); nRes
= 0;
166 pVal
= dynamic_cast<SbxValue
*>( p
->pObj
);
169 nRes
= pVal
->GetDate();
173 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT
); nRes
= 0;
176 case SbxBYREF
| SbxCHAR
:
179 case SbxBYREF
| SbxBYTE
:
182 case SbxBYREF
| SbxINTEGER
:
183 case SbxBYREF
| SbxBOOL
:
186 case SbxBYREF
| SbxLONG
:
189 case SbxBYREF
| SbxULONG
:
192 case SbxBYREF
| SbxERROR
:
193 case SbxBYREF
| SbxUSHORT
:
196 case SbxBYREF
| SbxSINGLE
:
199 case SbxBYREF
| SbxDATE
:
200 case SbxBYREF
| SbxDOUBLE
:
203 case SbxBYREF
| SbxCURRENCY
:
204 nRes
= ImpCurrencyToDouble( *p
->pnInt64
);
206 case SbxBYREF
| SbxSALINT64
:
207 nRes
= static_cast< double >(*p
->pnInt64
);
209 case SbxBYREF
| SbxSALUINT64
:
210 nRes
= ImpSalUInt64ToDouble( *p
->puInt64
);
213 SbxBase::SetError( ERRCODE_BASIC_CONVERSION
); nRes
= 0;
219 void ImpPutDate( SbxValues
* p
, double n
)
232 // from here will be tested
234 aTmp
.pChar
= &p
->nChar
;
237 aTmp
.pByte
= &p
->nByte
;
241 aTmp
.pInteger
= &p
->nInteger
;
244 aTmp
.pLong
= &p
->nLong
;
247 aTmp
.pULong
= &p
->nULong
;
251 aTmp
.pUShort
= &p
->nUShort
;
254 aTmp
.pSingle
= &p
->nSingle
;
258 aTmp
.pnInt64
= &p
->nInt64
;
261 aTmp
.puInt64
= &p
->uInt64
;
264 case SbxBYREF
| SbxDECIMAL
:
265 pDec
= ImpCreateDecimal( p
);
266 if( !pDec
->setDouble( n
) )
268 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
);
272 aTmp
.eType
= SbxDataType( p
->eType
| SbxBYREF
);
273 p
= &aTmp
; goto start
;
275 case SbxBYREF
| SbxSTRING
:
279 #if HAVE_FEATURE_SCRIPTING
282 p
->pOUString
= new OUString
;
286 LanguageType eLangType
= Application::GetSettings().GetLanguageTag().getLanguageType();
287 std::shared_ptr
<SvNumberFormatter
> pFormatter
;
288 if (GetSbData()->pInst
)
290 pFormatter
= GetSbData()->pInst
->GetNumberFormatter();
295 pFormatter
= SbiInstance::PrepareNumberFormatter( nDummy
, nDummy
, nDummy
);
299 sal_Int32 nCheckPos
= 0;
300 SvNumFormatType nType
;
302 SvtSysLocale aSysLocale
;
303 DateOrder eDate
= aSysLocale
.GetLocaleData().getDateOrder();
305 // if the whole-number part is 0, we want no year!
306 if( n
<= -1.0 || n
>= 1.0 )
308 // Time only if != 00:00:00
309 if( rtl::math::approxEqual(floor( n
), n
) )
314 case DateOrder::MDY
: aStr
= "MM/DD/YYYY"; break;
315 case DateOrder::DMY
: aStr
= "DD/MM/YYYY"; break;
316 case DateOrder::YMD
: aStr
= "YYYY/MM/DD"; break;
324 case DateOrder::MDY
: aStr
= "MM/DD/YYYY HH:MM:SS"; break;
325 case DateOrder::DMY
: aStr
= "DD/MM/YYYY HH:MM:SS"; break;
326 case DateOrder::YMD
: aStr
= "YYYY/MM/DD HH:MM:SS"; break;
334 pFormatter
->PutandConvertEntry( aStr
,
340 pFormatter
->GetOutputString( n
, nIndex
, *p
->pOUString
, &pColor
);
345 pVal
= dynamic_cast<SbxValue
*>( p
->pObj
);
352 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT
);
355 case SbxBYREF
| SbxCHAR
:
358 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMAXCHAR
;
360 else if( n
< SbxMINCHAR
)
362 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMINCHAR
;
364 *p
->pChar
= static_cast<sal_Unicode
>(n
);
366 case SbxBYREF
| SbxBYTE
:
369 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMAXBYTE
;
373 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= 0;
375 *p
->pByte
= static_cast<sal_uInt8
>(n
);
377 case SbxBYREF
| SbxINTEGER
:
378 case SbxBYREF
| SbxBOOL
:
381 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMAXINT
;
383 else if( n
< SbxMININT
)
385 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMININT
;
387 *p
->pInteger
= static_cast<sal_Int16
>(n
);
389 case SbxBYREF
| SbxERROR
:
390 case SbxBYREF
| SbxUSHORT
:
393 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMAXUINT
;
397 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= 0;
399 *p
->pUShort
= static_cast<sal_uInt16
>(n
);
401 case SbxBYREF
| SbxLONG
:
404 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMAXLNG
;
406 else if( n
< SbxMINLNG
)
408 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMINLNG
;
410 *p
->pLong
= static_cast<sal_Int32
>(n
);
412 case SbxBYREF
| SbxULONG
:
415 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMAXULNG
;
419 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= 0;
421 *p
->pULong
= static_cast<sal_uInt32
>(n
);
423 case SbxBYREF
| SbxSINGLE
:
426 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMAXSNG
;
428 else if( n
< SbxMINSNG
)
430 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMINSNG
;
432 *p
->pSingle
= static_cast<float>(n
);
434 case SbxBYREF
| SbxSALINT64
:
435 *p
->pnInt64
= ImpDoubleToSalInt64( n
);
437 case SbxBYREF
| SbxSALUINT64
:
438 *p
->puInt64
= ImpDoubleToSalUInt64( n
);
440 case SbxBYREF
| SbxDATE
:
441 case SbxBYREF
| SbxDOUBLE
:
444 case SbxBYREF
| SbxCURRENCY
:
447 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMAXCURR
;
449 else if( n
< SbxMINCURR
)
451 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMINCURR
;
453 *p
->pnInt64
= ImpDoubleToCurrency( n
);
456 SbxBase::SetError( ERRCODE_BASIC_CONVERSION
);
461 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */