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