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