Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <vcl/svapp.hxx>
21 : #include <vcl/settings.hxx>
22 : #include <svl/zforlist.hxx>
23 : #include <tools/errcode.hxx>
24 : #include <tools/color.hxx>
25 : #include <i18nlangtag/lang.h>
26 : #include <basic/sbx.hxx>
27 : #include "sbxconv.hxx"
28 : #include "math.h"
29 : #include <comphelper/processfactory.hxx>
30 : #include <boost/scoped_ptr.hpp>
31 :
32 :
33 3 : double ImpGetDate( const SbxValues* p )
34 : {
35 : double nRes;
36 : SbxValue* pVal;
37 :
38 3 : switch( +p->eType )
39 : {
40 : case SbxNULL:
41 0 : SbxBase::SetError( SbxERR_CONVERSION );
42 : case SbxEMPTY:
43 0 : nRes = 0;
44 0 : break;
45 : case SbxCHAR:
46 0 : nRes = p->nChar;
47 0 : break;
48 : case SbxBYTE:
49 0 : nRes = p->nByte;
50 0 : break;
51 : case SbxINTEGER:
52 : case SbxBOOL:
53 1 : nRes = p->nInteger;
54 1 : break;
55 : case SbxERROR:
56 : case SbxUSHORT:
57 0 : nRes = p->nUShort;
58 0 : break;
59 : case SbxLONG:
60 0 : nRes = (double) p->nLong;
61 0 : break;
62 : case SbxULONG:
63 0 : nRes = (double) p->nULong;
64 0 : break;
65 : case SbxSINGLE:
66 0 : nRes = p->nSingle;
67 0 : break;
68 : case SbxDATE:
69 : case SbxDOUBLE:
70 2 : nRes = p->nDouble;
71 2 : break;
72 : case SbxCURRENCY:
73 0 : nRes = ImpCurrencyToDouble( p->nInt64 );
74 0 : break;
75 : case SbxSALINT64:
76 0 : nRes = static_cast< double >(p->nInt64);
77 0 : break;
78 : case SbxSALUINT64:
79 0 : nRes = ImpSalUInt64ToDouble( p->uInt64 );
80 0 : break;
81 : case SbxDECIMAL:
82 : case SbxBYREF | SbxDECIMAL:
83 0 : if( p->pDecimal )
84 : {
85 0 : p->pDecimal->getDouble( nRes );
86 : }
87 : else
88 : {
89 0 : nRes = 0.0;
90 : }
91 0 : break;
92 : case SbxBYREF | SbxSTRING:
93 : case SbxSTRING:
94 : case SbxLPSTR:
95 0 : if( !p->pOUString )
96 : {
97 0 : nRes = 0;
98 : }
99 : else
100 : {
101 0 : LanguageType eLangType = Application::GetSettings().GetLanguageTag().getLanguageType();
102 :
103 0 : boost::scoped_ptr<SvNumberFormatter> pFormatter(new SvNumberFormatter( comphelper::getProcessComponentContext(), eLangType ));
104 :
105 : sal_uInt32 nIndex;
106 0 : sal_Int32 nCheckPos = 0;
107 0 : short nType = 127;
108 :
109 : // Default templates of the formatter have only two-digit
110 : // date. Therefore register an own format.
111 :
112 : // HACK, because the number formatter in PutandConvertEntry replace the wildcard
113 : // for month, day, year not according to the configuration.
114 : // Problem: Print Year(Date) under Engl. OS
115 : // quod vide basic/source/runtime/runtime.cxx
116 :
117 0 : SvtSysLocale aSysLocale;
118 0 : DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
119 0 : OUString aDateStr;
120 0 : switch( eDate )
121 : {
122 : default:
123 0 : case MDY: aDateStr = "MM/DD/YYYY"; break;
124 0 : case DMY: aDateStr = "DD/MM/YYYY"; break;
125 0 : case YMD: aDateStr = "YYYY/MM/DD"; break;
126 : }
127 :
128 0 : OUString aStr( aDateStr );
129 0 : aStr += " HH:MM:SS";
130 :
131 : pFormatter->PutandConvertEntry( aStr, nCheckPos, nType,
132 0 : nIndex, LANGUAGE_ENGLISH_US, eLangType );
133 0 : bool bSuccess = pFormatter->IsNumberFormat( *p->pOUString, nIndex, nRes );
134 0 : if ( bSuccess )
135 : {
136 0 : short nType_ = pFormatter->GetType( nIndex );
137 0 : if(!(nType_ & ( css::util::NumberFormat::DATETIME | css::util::NumberFormat::DATE |
138 : css::util::NumberFormat::TIME | css::util::NumberFormat::DEFINED )))
139 : {
140 0 : bSuccess = false;
141 : }
142 : }
143 :
144 0 : if ( !bSuccess )
145 : {
146 0 : SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
147 0 : }
148 : }
149 0 : break;
150 : case SbxOBJECT:
151 0 : pVal = PTR_CAST(SbxValue,p->pObj);
152 0 : if( pVal )
153 : {
154 0 : nRes = pVal->GetDate();
155 : }
156 : else
157 : {
158 0 : SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
159 : }
160 0 : break;
161 : case SbxBYREF | SbxCHAR:
162 0 : nRes = *p->pChar;
163 0 : break;
164 : case SbxBYREF | SbxBYTE:
165 0 : nRes = *p->pByte;
166 0 : break;
167 : case SbxBYREF | SbxINTEGER:
168 : case SbxBYREF | SbxBOOL:
169 0 : nRes = *p->pInteger;
170 0 : break;
171 : case SbxBYREF | SbxLONG:
172 0 : nRes = *p->pLong;
173 0 : break;
174 : case SbxBYREF | SbxULONG:
175 0 : nRes = *p->pULong;
176 0 : break;
177 : case SbxBYREF | SbxERROR:
178 : case SbxBYREF | SbxUSHORT:
179 0 : nRes = *p->pUShort;
180 0 : break;
181 : case SbxBYREF | SbxSINGLE:
182 0 : nRes = *p->pSingle;
183 0 : break;
184 : case SbxBYREF | SbxDATE:
185 : case SbxBYREF | SbxDOUBLE:
186 0 : nRes = *p->pDouble;
187 0 : break;
188 : case SbxBYREF | SbxCURRENCY:
189 0 : nRes = ImpCurrencyToDouble( *p->pnInt64 );
190 0 : break;
191 : case SbxBYREF | SbxSALINT64:
192 0 : nRes = static_cast< double >(*p->pnInt64);
193 0 : break;
194 : case SbxBYREF | SbxSALUINT64:
195 0 : nRes = ImpSalUInt64ToDouble( *p->puInt64 );
196 0 : break;
197 : default:
198 0 : SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
199 0 : break;
200 : }
201 3 : return nRes;
202 : }
203 :
204 36 : void ImpPutDate( SbxValues* p, double n )
205 : {
206 36 : SbxValues aTmp;
207 : SbxDecimal* pDec;
208 : SbxValue* pVal;
209 :
210 : start:
211 36 : switch( +p->eType )
212 : {
213 : case SbxDATE:
214 : case SbxDOUBLE:
215 31 : p->nDouble = n;
216 31 : break;
217 : // from here will be tested
218 : case SbxCHAR:
219 0 : aTmp.pChar = &p->nChar;
220 0 : goto direct;
221 : case SbxBYTE:
222 0 : aTmp.pByte = &p->nByte;
223 0 : goto direct;
224 : case SbxINTEGER:
225 : case SbxBOOL:
226 0 : aTmp.pInteger = &p->nInteger;
227 0 : goto direct;
228 : case SbxLONG:
229 0 : aTmp.pLong = &p->nLong;
230 0 : goto direct;
231 : case SbxULONG:
232 0 : aTmp.pULong = &p->nULong;
233 0 : goto direct;
234 : case SbxERROR:
235 : case SbxUSHORT:
236 0 : aTmp.pUShort = &p->nUShort;
237 0 : goto direct;
238 : case SbxSINGLE:
239 0 : aTmp.pSingle = &p->nSingle;
240 0 : goto direct;
241 : case SbxCURRENCY:
242 : case SbxSALINT64:
243 0 : aTmp.pnInt64 = &p->nInt64;
244 0 : goto direct;
245 : case SbxSALUINT64:
246 0 : aTmp.puInt64 = &p->uInt64;
247 0 : goto direct;
248 : case SbxDECIMAL:
249 : case SbxBYREF | SbxDECIMAL:
250 0 : pDec = ImpCreateDecimal( p );
251 0 : if( !pDec->setDouble( n ) )
252 : {
253 0 : SbxBase::SetError( SbxERR_OVERFLOW );
254 : }
255 0 : break;
256 : direct:
257 0 : aTmp.eType = SbxDataType( p->eType | SbxBYREF );
258 0 : p = &aTmp; goto start;
259 :
260 : case SbxBYREF | SbxSTRING:
261 : case SbxSTRING:
262 : case SbxLPSTR:
263 : {
264 5 : if( !p->pOUString )
265 : {
266 0 : p->pOUString = new OUString;
267 : }
268 : Color* pColor;
269 :
270 5 : LanguageType eLangType = Application::GetSettings().GetLanguageTag().getLanguageType();
271 5 : boost::scoped_ptr<SvNumberFormatter> pFormatter(new SvNumberFormatter( comphelper::getProcessComponentContext(), eLangType ));
272 :
273 : sal_uInt32 nIndex;
274 5 : sal_Int32 nCheckPos = 0;
275 : short nType;
276 :
277 10 : SvtSysLocale aSysLocale;
278 5 : DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
279 10 : OUString aStr;
280 : // if the whole-number part is 0, we want no year!
281 5 : if( n <= -1.0 || n >= 1.0 )
282 : {
283 : // Time only if != 00:00:00
284 10 : if( floor( n ) == n )
285 : {
286 5 : switch( eDate )
287 : {
288 5 : case MDY: aStr = "MM.TT.JJJJ"; break;
289 0 : case DMY: aStr = "TT.MM.JJJJ"; break;
290 0 : case YMD: aStr = "JJJJ.MM.TT"; break;
291 0 : default: aStr = "MM.TT.JJJJ";
292 : }
293 : }
294 : else
295 : {
296 0 : switch( eDate )
297 : {
298 0 : case MDY: aStr = "MM.TT.JJJJ HH:MM:SS"; break;
299 0 : case DMY: aStr = "TT.MM.JJJJ HH:MM:SS"; break;
300 0 : case YMD: aStr = "JJJJ.MM.TT HH:MM:SS"; break;
301 0 : default: aStr = "MM.TT.JJJJ HH:MM:SS";
302 : }
303 : }
304 : }
305 : else
306 : {
307 0 : aStr = "HH:MM:SS";
308 : }
309 : pFormatter->PutandConvertEntry( aStr,
310 : nCheckPos,
311 : nType,
312 : nIndex,
313 : LANGUAGE_GERMAN,
314 5 : eLangType );
315 5 : pFormatter->GetOutputString( n, nIndex, *p->pOUString, &pColor );
316 10 : break;
317 : }
318 : case SbxOBJECT:
319 0 : pVal = PTR_CAST(SbxValue,p->pObj);
320 0 : if( pVal )
321 : {
322 0 : pVal->PutDate( n );
323 : }
324 : else
325 : {
326 0 : SbxBase::SetError( SbxERR_NO_OBJECT );
327 : }
328 0 : break;
329 : case SbxBYREF | SbxCHAR:
330 0 : if( n > SbxMAXCHAR )
331 : {
332 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
333 : }
334 0 : else if( n < SbxMINCHAR )
335 : {
336 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
337 : }
338 0 : *p->pChar = (sal_Unicode) n;
339 0 : break;
340 : case SbxBYREF | SbxBYTE:
341 0 : if( n > SbxMAXBYTE )
342 : {
343 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
344 : }
345 0 : else if( n < 0 )
346 : {
347 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
348 : }
349 0 : *p->pByte = (sal_uInt8) n;
350 0 : break;
351 : case SbxBYREF | SbxINTEGER:
352 : case SbxBYREF | SbxBOOL:
353 0 : if( n > SbxMAXINT )
354 : {
355 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
356 : }
357 0 : else if( n < SbxMININT )
358 : {
359 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
360 : }
361 0 : *p->pInteger = (sal_Int16) n;
362 0 : break;
363 : case SbxBYREF | SbxERROR:
364 : case SbxBYREF | SbxUSHORT:
365 0 : if( n > SbxMAXUINT )
366 : {
367 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
368 : }
369 0 : else if( n < 0 )
370 : {
371 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
372 : }
373 0 : *p->pUShort = (sal_uInt16) n;
374 0 : break;
375 : case SbxBYREF | SbxLONG:
376 0 : if( n > SbxMAXLNG )
377 : {
378 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
379 : }
380 0 : else if( n < SbxMINLNG )
381 : {
382 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINLNG;
383 : }
384 0 : *p->pLong = (sal_Int32) n;
385 0 : break;
386 : case SbxBYREF | SbxULONG:
387 0 : if( n > SbxMAXULNG )
388 : {
389 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
390 : }
391 0 : else if( n < 0 )
392 : {
393 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
394 : }
395 0 : *p->pULong = (sal_uInt32) n;
396 0 : break;
397 : case SbxBYREF | SbxSINGLE:
398 0 : if( n > SbxMAXSNG )
399 : {
400 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXSNG;
401 : }
402 0 : else if( n < SbxMINSNG )
403 : {
404 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINSNG;
405 : }
406 0 : *p->pSingle = (float) n;
407 0 : break;
408 : case SbxBYREF | SbxSALINT64:
409 0 : *p->pnInt64 = ImpDoubleToSalInt64( n );
410 0 : break;
411 : case SbxBYREF | SbxSALUINT64:
412 0 : *p->puInt64 = ImpDoubleToSalUInt64( n );
413 0 : break;
414 : case SbxBYREF | SbxDATE:
415 : case SbxBYREF | SbxDOUBLE:
416 0 : *p->pDouble = (double) n;
417 0 : break;
418 : case SbxBYREF | SbxCURRENCY:
419 0 : if( n > SbxMAXCURR )
420 : {
421 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCURR;
422 : }
423 0 : else if( n < SbxMINCURR )
424 : {
425 0 : SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCURR;
426 : }
427 0 : *p->pnInt64 = ImpDoubleToCurrency( n );
428 0 : break;
429 : default:
430 0 : SbxBase::SetError( SbxERR_CONVERSION );
431 0 : break;
432 : }
433 36 : }
434 :
435 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|