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/numformat.hxx>
24 #include <svl/zforlist.hxx>
25 #include <tools/color.hxx>
26 #include <i18nlangtag/lang.h>
27 #include <basic/sberrors.hxx>
28 #include "sbxconv.hxx"
29 #include <runtime.hxx>
30 #include <sbintern.hxx>
33 #include <config_features.h>
36 double ImpGetDate( const SbxValues
* p
)
44 SbxBase::SetError( ERRCODE_BASIC_CONVERSION
);
64 nRes
= static_cast<double>(p
->nLong
);
67 nRes
= static_cast<double>(p
->nULong
);
77 nRes
= ImpCurrencyToDouble( p
->nInt64
);
80 nRes
= static_cast< double >(p
->nInt64
);
83 nRes
= ImpSalUInt64ToDouble( p
->uInt64
);
86 case SbxBYREF
| SbxDECIMAL
:
87 if (!p
->pDecimal
|| !p
->pDecimal
->getDouble(nRes
))
90 case SbxBYREF
| SbxSTRING
:
93 #if HAVE_FEATURE_SCRIPTING
100 LanguageType eLangType
= Application::GetSettings().GetLanguageTag().getLanguageType();
101 std::shared_ptr
<SvNumberFormatter
> pFormatter
;
102 if (GetSbData()->pInst
)
104 pFormatter
= GetSbData()->pInst
->GetNumberFormatter();
109 pFormatter
= SbiInstance::PrepareNumberFormatter( nDummy
, nDummy
, nDummy
);
113 sal_Int32 nCheckPos
= 0;
114 SvNumFormatType nType
= SvNumFormatType::DEFINED
| SvNumFormatType::DATE
| SvNumFormatType::TIME
| SvNumFormatType::CURRENCY
115 | SvNumFormatType::NUMBER
| SvNumFormatType::SCIENTIFIC
| SvNumFormatType::FRACTION
;
117 // Default templates of the formatter have only two-digit
118 // date. Therefore register an own format.
120 // HACK, because the number formatter in PutandConvertEntry replace the wildcard
121 // for month, day, year not according to the configuration.
122 // Problem: Print Year(Date) under Engl. OS
123 // quod vide basic/source/runtime/runtime.cxx
125 SvtSysLocale aSysLocale
;
126 DateOrder eDate
= aSysLocale
.GetLocaleData().getDateOrder();
131 case DateOrder::MDY
: aDateStr
= "MM/DD/YYYY"; break;
132 case DateOrder::DMY
: aDateStr
= "DD/MM/YYYY"; break;
133 case DateOrder::YMD
: aDateStr
= "YYYY/MM/DD"; break;
136 OUString aStr
= aDateStr
+ " HH:MM:SS";
138 pFormatter
->PutandConvertEntry( aStr
, nCheckPos
, nType
,
139 nIndex
, LANGUAGE_ENGLISH_US
, eLangType
, true);
140 bool bSuccess
= pFormatter
->IsNumberFormat( *p
->pOUString
, nIndex
, nRes
);
143 SvNumFormatType nType_
= pFormatter
->GetType( nIndex
);
144 if(!(nType_
& ( SvNumFormatType::DATETIME
| SvNumFormatType::DATE
|
145 SvNumFormatType::TIME
| SvNumFormatType::DEFINED
)))
153 SbxBase::SetError( ERRCODE_BASIC_CONVERSION
); nRes
= 0;
161 pVal
= dynamic_cast<SbxValue
*>( p
->pObj
);
164 nRes
= pVal
->GetDate();
168 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT
); nRes
= 0;
171 case SbxBYREF
| SbxCHAR
:
174 case SbxBYREF
| SbxBYTE
:
177 case SbxBYREF
| SbxINTEGER
:
178 case SbxBYREF
| SbxBOOL
:
181 case SbxBYREF
| SbxLONG
:
184 case SbxBYREF
| SbxULONG
:
187 case SbxBYREF
| SbxERROR
:
188 case SbxBYREF
| SbxUSHORT
:
191 case SbxBYREF
| SbxSINGLE
:
194 case SbxBYREF
| SbxDATE
:
195 case SbxBYREF
| SbxDOUBLE
:
198 case SbxBYREF
| SbxCURRENCY
:
199 nRes
= ImpCurrencyToDouble( *p
->pnInt64
);
201 case SbxBYREF
| SbxSALINT64
:
202 nRes
= static_cast< double >(*p
->pnInt64
);
204 case SbxBYREF
| SbxSALUINT64
:
205 nRes
= ImpSalUInt64ToDouble( *p
->puInt64
);
208 SbxBase::SetError( ERRCODE_BASIC_CONVERSION
); nRes
= 0;
214 void ImpPutDate( SbxValues
* p
, double n
)
227 // from here will be tested
229 aTmp
.pChar
= &p
->nChar
;
232 aTmp
.pByte
= &p
->nByte
;
236 aTmp
.pInteger
= &p
->nInteger
;
239 aTmp
.pLong
= &p
->nLong
;
242 aTmp
.pULong
= &p
->nULong
;
246 aTmp
.pUShort
= &p
->nUShort
;
249 aTmp
.pSingle
= &p
->nSingle
;
253 aTmp
.pnInt64
= &p
->nInt64
;
256 aTmp
.puInt64
= &p
->uInt64
;
259 case SbxBYREF
| SbxDECIMAL
:
260 pDec
= ImpCreateDecimal( p
);
261 if( !pDec
->setDouble( n
) )
263 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
);
267 aTmp
.eType
= SbxDataType( p
->eType
| SbxBYREF
);
268 p
= &aTmp
; goto start
;
270 case SbxBYREF
| SbxSTRING
:
274 #if HAVE_FEATURE_SCRIPTING
277 p
->pOUString
= new OUString
;
281 LanguageType eLangType
= Application::GetSettings().GetLanguageTag().getLanguageType();
282 std::shared_ptr
<SvNumberFormatter
> pFormatter
;
283 if (GetSbData()->pInst
)
285 pFormatter
= GetSbData()->pInst
->GetNumberFormatter();
290 pFormatter
= SbiInstance::PrepareNumberFormatter( nDummy
, nDummy
, nDummy
);
294 sal_Int32 nCheckPos
= 0;
295 SvNumFormatType nType
;
297 SvtSysLocale aSysLocale
;
298 DateOrder eDate
= aSysLocale
.GetLocaleData().getDateOrder();
300 // if the whole-number part is 0, we want no year!
301 if( n
<= -1.0 || n
>= 1.0 )
303 // Time only if != 00:00:00
304 if( rtl::math::approxEqual(floor( n
), n
) )
309 case DateOrder::MDY
: aStr
= "MM/DD/YYYY"; break;
310 case DateOrder::DMY
: aStr
= "DD/MM/YYYY"; break;
311 case DateOrder::YMD
: aStr
= "YYYY/MM/DD"; break;
319 case DateOrder::MDY
: aStr
= "MM/DD/YYYY HH:MM:SS"; break;
320 case DateOrder::DMY
: aStr
= "DD/MM/YYYY HH:MM:SS"; break;
321 case DateOrder::YMD
: aStr
= "YYYY/MM/DD HH:MM:SS"; break;
329 pFormatter
->PutandConvertEntry( aStr
,
335 pFormatter
->GetOutputString( n
, nIndex
, *p
->pOUString
, &pColor
);
340 pVal
= dynamic_cast<SbxValue
*>( p
->pObj
);
347 SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT
);
350 case SbxBYREF
| SbxCHAR
:
351 *p
->pChar
= ImpDoubleToChar(n
);
353 case SbxBYREF
| SbxBYTE
:
354 *p
->pByte
= ImpDoubleToByte(n
);
356 case SbxBYREF
| SbxINTEGER
:
357 case SbxBYREF
| SbxBOOL
:
358 *p
->pInteger
= ImpDoubleToInteger(n
);
360 case SbxBYREF
| SbxERROR
:
361 case SbxBYREF
| SbxUSHORT
:
362 *p
->pUShort
= ImpDoubleToUShort(n
);
364 case SbxBYREF
| SbxLONG
:
365 *p
->pLong
= ImpDoubleToLong(n
);
367 case SbxBYREF
| SbxULONG
:
368 *p
->pULong
= ImpDoubleToULong(n
);
370 case SbxBYREF
| SbxSINGLE
:
373 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMAXSNG
;
375 else if( n
< SbxMINSNG
)
377 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMINSNG
;
379 *p
->pSingle
= static_cast<float>(n
);
381 case SbxBYREF
| SbxSALINT64
:
382 *p
->pnInt64
= ImpDoubleToSalInt64( n
);
384 case SbxBYREF
| SbxSALUINT64
:
385 *p
->puInt64
= ImpDoubleToSalUInt64( n
);
387 case SbxBYREF
| SbxDATE
:
388 case SbxBYREF
| SbxDOUBLE
:
391 case SbxBYREF
| SbxCURRENCY
:
394 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMAXCURR
;
396 else if( n
< SbxMINCURR
)
398 SbxBase::SetError( ERRCODE_BASIC_MATH_OVERFLOW
); n
= SbxMINCURR
;
400 *p
->pnInt64
= ImpDoubleToCurrency( n
);
403 SbxBase::SetError( ERRCODE_BASIC_CONVERSION
);
408 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */