1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_basic.hxx"
26 #include <vcl/svapp.hxx>
27 #include <svl/zforlist.hxx>
28 #include <tools/errcode.hxx>
29 #include <tools/color.hxx>
30 #include <i18npool/lang.h>
31 #include <basic/sbx.hxx>
32 #include "sbxconv.hxx"
33 #include "math.h"
34 #include <comphelper/processfactory.hxx>
35
36
ImpGetDate(const SbxValues * p)37 double ImpGetDate( const SbxValues* p )
38 {
39 double nRes;
40 switch( +p->eType )
41 {
42 case SbxNULL:
43 SbxBase::SetError( SbxERR_CONVERSION );
44 case SbxEMPTY:
45 nRes = 0; break;
46 case SbxCHAR:
47 nRes = p->nChar; break;
48 case SbxBYTE:
49 nRes = p->nByte; break;
50 case SbxINTEGER:
51 case SbxBOOL:
52 nRes = p->nInteger; break;
53 case SbxERROR:
54 case SbxUSHORT:
55 nRes = p->nUShort; break;
56 case SbxLONG:
57 nRes = (double) p->nLong; break;
58 case SbxULONG:
59 nRes = (double) p->nULong; break;
60 case SbxSINGLE:
61 nRes = p->nSingle; break;
62 case SbxDATE:
63 case SbxDOUBLE:
64 nRes = p->nDouble; break;
65 case SbxULONG64:
66 nRes = ImpUINT64ToDouble( p->nULong64 ); break;
67 case SbxLONG64:
68 nRes = ImpINT64ToDouble( p->nLong64 ); break;
69 case SbxCURRENCY:
70 nRes = ImpCurrencyToDouble( p->nLong64 ); break;
71 case SbxSALINT64:
72 nRes = static_cast< double >(p->nInt64); break;
73 case SbxSALUINT64:
74 nRes = ImpSalUInt64ToDouble( p->uInt64 ); break;
75 case SbxDECIMAL:
76 case SbxBYREF | SbxDECIMAL:
77 if( p->pDecimal )
78 p->pDecimal->getDouble( nRes );
79 else
80 nRes = 0.0;
81 break;
82 case SbxBYREF | SbxSTRING:
83 case SbxSTRING:
84 case SbxLPSTR:
85 if( !p->pOUString )
86 nRes = 0;
87 else
88 {
89 LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
90
91 SvNumberFormatter* pFormatter;
92 com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
93 xFactory = comphelper::getProcessServiceFactory();
94 pFormatter = new SvNumberFormatter( xFactory, eLangType );
95
96 sal_uInt32 nIndex;
97 xub_StrLen nCheckPos = 0;
98 short nType = 127;
99
100 // Standard-Vorlagen des Formatters haben nur zweistellige
101 // Jahreszahl. Deshalb eigenes Format registrieren
102
103 // HACK, da der Numberformatter in PutandConvertEntry die Platzhalter
104 // fuer Monat, Tag, Jahr nicht entsprechend der Systemeinstellung
105 // austauscht. Problem: Print Year(Date) unter engl. BS
106 // siehe auch basic\source\runtime\runtime.cxx
107
108 SvtSysLocale aSysLocale;
109 DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
110 String aDateStr;
111 switch( eDate )
112 {
113 case MDY: aDateStr.AssignAscii( "MM.TT.JJJJ" ); break;
114 case DMY: aDateStr.AssignAscii( "TT.MM.JJJJ" ); break;
115 case YMD: aDateStr.AssignAscii( "JJJJ.MM.TT" ); break;
116 default: aDateStr.AssignAscii( "MM.TT.JJJJ" );
117 }
118
119 String aStr( aDateStr );
120 aStr.AppendAscii( " HH:MM:SS" );
121
122 pFormatter->PutandConvertEntry( aStr, nCheckPos, nType,
123 nIndex, LANGUAGE_GERMAN, eLangType );
124 sal_Bool bSuccess = pFormatter->IsNumberFormat( *p->pOUString, nIndex, nRes );
125 if ( bSuccess )
126 {
127 short nType_ = pFormatter->GetType( nIndex );
128 if(!(nType_ & ( NUMBERFORMAT_DATETIME | NUMBERFORMAT_DATE |
129 NUMBERFORMAT_TIME | NUMBERFORMAT_DEFINED )))
130 bSuccess = sal_False;
131 }
132
133 if ( !bSuccess )
134 {
135 SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
136 }
137
138 delete pFormatter;
139 }
140 break;
141 case SbxOBJECT:
142 {
143 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
144 if( pVal )
145 nRes = pVal->GetDate();
146 else
147 {
148 SbxBase::SetError( SbxERR_NO_OBJECT ); nRes = 0;
149 }
150 break;
151 }
152
153 case SbxBYREF | SbxCHAR:
154 nRes = *p->pChar; break;
155 case SbxBYREF | SbxBYTE:
156 nRes = *p->pByte; break;
157 case SbxBYREF | SbxINTEGER:
158 case SbxBYREF | SbxBOOL:
159 nRes = *p->pInteger; break;
160 case SbxBYREF | SbxLONG:
161 nRes = *p->pLong; break;
162 case SbxBYREF | SbxULONG:
163 nRes = *p->pULong; break;
164 case SbxBYREF | SbxERROR:
165 case SbxBYREF | SbxUSHORT:
166 nRes = *p->pUShort; break;
167 case SbxBYREF | SbxSINGLE:
168 nRes = *p->pSingle; break;
169 case SbxBYREF | SbxDATE:
170 case SbxBYREF | SbxDOUBLE:
171 nRes = *p->pDouble; break;
172 case SbxBYREF | SbxULONG64:
173 nRes = ImpUINT64ToDouble( *p->pULong64 ); break;
174 case SbxBYREF | SbxLONG64:
175 nRes = ImpINT64ToDouble( *p->pLong64 ); break;
176 case SbxBYREF | SbxCURRENCY:
177 nRes = ImpCurrencyToDouble( *p->pLong64 ); break;
178 case SbxBYREF | SbxSALINT64:
179 nRes = static_cast< double >(*p->pnInt64); break;
180 case SbxBYREF | SbxSALUINT64:
181 nRes = ImpSalUInt64ToDouble( *p->puInt64 ); break;
182
183 default:
184 SbxBase::SetError( SbxERR_CONVERSION ); nRes = 0;
185 }
186 return nRes;
187 }
188
ImpPutDate(SbxValues * p,double n)189 void ImpPutDate( SbxValues* p, double n )
190 {
191 SbxValues aTmp;
192
193 start:
194 switch( +p->eType )
195 {
196 case SbxDATE:
197 case SbxDOUBLE:
198 p->nDouble = n; break;
199
200 // ab hier wird getestet
201 case SbxCHAR:
202 aTmp.pChar = &p->nChar; goto direct;
203 case SbxBYTE:
204 aTmp.pByte = &p->nByte; goto direct;
205 case SbxINTEGER:
206 case SbxBOOL:
207 aTmp.pInteger = &p->nInteger; goto direct;
208 case SbxLONG:
209 aTmp.pLong = &p->nLong; goto direct;
210 case SbxULONG:
211 aTmp.pULong = &p->nULong; goto direct;
212 case SbxERROR:
213 case SbxUSHORT:
214 aTmp.pUShort = &p->nUShort; goto direct;
215 case SbxSINGLE:
216 aTmp.pSingle = &p->nSingle; goto direct;
217 case SbxULONG64:
218 aTmp.pULong64 = &p->nULong64; goto direct;
219 case SbxLONG64:
220 case SbxCURRENCY:
221 aTmp.pLong64 = &p->nLong64; goto direct;
222 case SbxSALINT64:
223 aTmp.pnInt64 = &p->nInt64; goto direct;
224 case SbxSALUINT64:
225 aTmp.puInt64 = &p->uInt64; goto direct;
226 case SbxDECIMAL:
227 case SbxBYREF | SbxDECIMAL:
228 {
229 SbxDecimal* pDec = ImpCreateDecimal( p );
230 if( !pDec->setDouble( n ) )
231 SbxBase::SetError( SbxERR_OVERFLOW );
232 break;
233 }
234 direct:
235 aTmp.eType = SbxDataType( p->eType | SbxBYREF );
236 p = &aTmp; goto start;
237
238 case SbxBYREF | SbxSTRING:
239 case SbxSTRING:
240 case SbxLPSTR:
241 {
242 if( !p->pOUString )
243 p->pOUString = new ::rtl::OUString;
244 Color* pColor;
245
246 LanguageType eLangType = GetpApp()->GetSettings().GetLanguage();
247 SvNumberFormatter* pFormatter;
248 com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
249 xFactory = comphelper::getProcessServiceFactory();
250 pFormatter = new SvNumberFormatter( xFactory, eLangType );
251
252 sal_uInt32 nIndex;
253 xub_StrLen nCheckPos = 0;
254 short nType;
255
256 SvtSysLocale aSysLocale;
257 DateFormat eDate = aSysLocale.GetLocaleData().getDateFormat();
258 String aStr;
259 // ist der ganzzahlige Teil 0, wollen wir kein Jahr!
260 if( n <= -1.0 || n >= 1.0 )
261 {
262 // Time only if != 00:00:00
263 if( floor( n ) == n )
264 {
265 switch( eDate )
266 {
267 case MDY: aStr.AssignAscii( "MM.TT.JJJJ" ); break;
268 case DMY: aStr.AssignAscii( "TT.MM.JJJJ" ); break;
269 case YMD: aStr.AssignAscii( "JJJJ.MM.TT" ); break;
270 default: aStr.AssignAscii( "MM.TT.JJJJ" );
271 }
272 }
273 else
274 {
275 switch( eDate )
276 {
277 case MDY: aStr.AssignAscii( "MM.TT.JJJJ HH:MM:SS" ); break;
278 case DMY: aStr.AssignAscii( "TT.MM.JJJJ HH:MM:SS" ); break;
279 case YMD: aStr.AssignAscii( "JJJJ.MM.TT HH:MM:SS" ); break;
280 default: aStr.AssignAscii( "MM.TT.JJJJ HH:MM:SS" );
281 }
282 }
283 }
284 else
285 aStr.AppendAscii( "HH:MM:SS" );
286
287 pFormatter->PutandConvertEntry( aStr,
288 nCheckPos,
289 nType,
290 nIndex,
291 LANGUAGE_GERMAN,
292 eLangType );
293 String aTmpString;
294 pFormatter->GetOutputString( n, nIndex, aTmpString, &pColor );
295 *p->pOUString = aTmpString;
296 delete pFormatter;
297 break;
298 }
299 case SbxOBJECT:
300 {
301 SbxValue* pVal = PTR_CAST(SbxValue,p->pObj);
302 if( pVal )
303 pVal->PutDate( n );
304 else
305 SbxBase::SetError( SbxERR_NO_OBJECT );
306 break;
307 }
308 case SbxBYREF | SbxCHAR:
309 if( n > SbxMAXCHAR )
310 {
311 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCHAR;
312 }
313 else if( n < SbxMINCHAR )
314 {
315 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCHAR;
316 }
317 *p->pChar = (xub_Unicode) n; break;
318 case SbxBYREF | SbxBYTE:
319 if( n > SbxMAXBYTE )
320 {
321 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXBYTE;
322 }
323 else if( n < 0 )
324 {
325 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
326 }
327 *p->pByte = (sal_uInt8) n; break;
328 case SbxBYREF | SbxINTEGER:
329 case SbxBYREF | SbxBOOL:
330 if( n > SbxMAXINT )
331 {
332 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXINT;
333 }
334 else if( n < SbxMININT )
335 {
336 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMININT;
337 }
338 *p->pInteger = (sal_Int16) n; break;
339 case SbxBYREF | SbxERROR:
340 case SbxBYREF | SbxUSHORT:
341 if( n > SbxMAXUINT )
342 {
343 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXUINT;
344 }
345 else if( n < 0 )
346 {
347 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
348 }
349 *p->pUShort = (sal_uInt16) n; break;
350 case SbxBYREF | SbxLONG:
351 if( n > SbxMAXLNG )
352 {
353 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXLNG;
354 }
355 else if( n < SbxMINLNG )
356 {
357 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINLNG;
358 }
359 *p->pLong = (sal_Int32) n; break;
360 case SbxBYREF | SbxULONG:
361 if( n > SbxMAXULNG )
362 {
363 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXULNG;
364 }
365 else if( n < 0 )
366 {
367 SbxBase::SetError( SbxERR_OVERFLOW ); n = 0;
368 }
369 *p->pULong = (sal_uInt32) n; break;
370 case SbxBYREF | SbxSINGLE:
371 if( n > SbxMAXSNG )
372 {
373 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXSNG;
374 }
375 else if( n < SbxMINSNG )
376 {
377 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINSNG;
378 }
379 *p->pSingle = (float) n; break;
380 case SbxBYREF | SbxSALINT64:
381 *p->pnInt64 = ImpDoubleToSalInt64( n ); break;
382 case SbxBYREF | SbxSALUINT64:
383 *p->puInt64 = ImpDoubleToSalUInt64( n ); break;
384 case SbxBYREF | SbxDATE:
385 case SbxBYREF | SbxDOUBLE:
386 *p->pDouble = (double) n; break;
387 case SbxBYREF | SbxCURRENCY:
388 if( n > SbxMAXCURR )
389 {
390 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMAXCURR;
391 }
392 else if( n < SbxMINCURR )
393 {
394 SbxBase::SetError( SbxERR_OVERFLOW ); n = SbxMINCURR;
395 }
396 *p->pLong64 = ImpDoubleToCurrency( n ); break;
397
398 default:
399 SbxBase::SetError( SbxERR_CONVERSION );
400 }
401 }
402
403