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 <sal/config.h>
21 :
22 : #include <cstddef>
23 :
24 : #include <stdlib.h>
25 : #include <vcl/svapp.hxx>
26 : #include <vcl/mapmod.hxx>
27 : #include <vcl/wrkwin.hxx>
28 : #include <vcl/timer.hxx>
29 : #include <vcl/settings.hxx>
30 : #include <basic/sbxvar.hxx>
31 : #include <basic/sbx.hxx>
32 : #include <svl/zforlist.hxx>
33 : #include <tools/urlobj.hxx>
34 : #include <osl/file.hxx>
35 : #include <vcl/jobset.hxx>
36 : #include "sbobjmod.hxx"
37 : #include <basic/sbuno.hxx>
38 :
39 : #include "date.hxx"
40 : #include "sbintern.hxx"
41 : #include "runtime.hxx"
42 : #include "stdobj.hxx"
43 : #include "rtlproto.hxx"
44 : #include "dllmgr.hxx"
45 : #include <iosys.hxx>
46 : #include "sbunoobj.hxx"
47 : #include "propacc.hxx"
48 : #include <sal/log.hxx>
49 : #include <eventatt.hxx>
50 :
51 : #include <comphelper/processfactory.hxx>
52 : #include <comphelper/string.hxx>
53 :
54 : #include <com/sun/star/uno/Sequence.hxx>
55 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
56 : #include <com/sun/star/i18n/LocaleCalendar.hpp>
57 : #include <com/sun/star/sheet/XFunctionAccess.hpp>
58 : #include <boost/scoped_array.hpp>
59 :
60 : using namespace comphelper;
61 : using namespace com::sun::star::i18n;
62 : using namespace com::sun::star::lang;
63 : using namespace com::sun::star::sheet;
64 : using namespace com::sun::star::uno;
65 :
66 0 : static Reference< XCalendar3 > getLocaleCalendar( void )
67 : {
68 0 : static Reference< XCalendar3 > xCalendar;
69 0 : if( !xCalendar.is() )
70 : {
71 0 : Reference< XComponentContext > xContext = getProcessComponentContext();
72 0 : xCalendar = LocaleCalendar::create(xContext);
73 : }
74 :
75 0 : static com::sun::star::lang::Locale aLastLocale;
76 : static bool bNeedsInit = true;
77 :
78 0 : com::sun::star::lang::Locale aLocale = Application::GetSettings().GetLanguageTag().getLocale();
79 0 : bool bNeedsReload = false;
80 0 : if( bNeedsInit )
81 : {
82 0 : bNeedsInit = false;
83 0 : bNeedsReload = true;
84 : }
85 0 : else if( aLocale.Language != aLastLocale.Language ||
86 0 : aLocale.Country != aLastLocale.Country ||
87 0 : aLocale.Variant != aLastLocale.Variant )
88 : {
89 0 : bNeedsReload = true;
90 : }
91 0 : if( bNeedsReload )
92 : {
93 0 : aLastLocale = aLocale;
94 0 : xCalendar->loadDefaultCalendar( aLocale );
95 : }
96 0 : return xCalendar;
97 : }
98 :
99 : #ifndef DISABLE_SCRIPTING
100 :
101 0 : RTLFUNC(CallByName)
102 : {
103 : (void)pBasic;
104 : (void)bWrite;
105 :
106 0 : const sal_Int16 vbGet = 2;
107 0 : const sal_Int16 vbLet = 4;
108 0 : const sal_Int16 vbMethod = 1;
109 0 : const sal_Int16 vbSet = 8;
110 :
111 : // At least 3 parameter needed plus function itself -> 4
112 0 : sal_uInt16 nParCount = rPar.Count();
113 0 : if ( nParCount < 4 )
114 : {
115 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
116 0 : return;
117 : }
118 :
119 : // 1. parameter is object
120 0 : SbxBase* pObjVar = (SbxObject*)rPar.Get(1)->GetObject();
121 0 : SbxObject* pObj = NULL;
122 0 : if( pObjVar )
123 0 : pObj = PTR_CAST(SbxObject,pObjVar);
124 0 : if( !pObj && pObjVar && pObjVar->ISA(SbxVariable) )
125 : {
126 0 : SbxBase* pObjVarObj = ((SbxVariable*)pObjVar)->GetObject();
127 0 : pObj = PTR_CAST(SbxObject,pObjVarObj);
128 : }
129 0 : if( !pObj )
130 : {
131 0 : StarBASIC::Error( SbERR_BAD_PARAMETER );
132 0 : return;
133 : }
134 :
135 : // 2. parameter is ProcedureName
136 0 : OUString aNameStr = rPar.Get(2)->GetOUString();
137 :
138 : // 3. parameter is CallType
139 0 : sal_Int16 nCallType = rPar.Get(3)->GetInteger();
140 :
141 : //SbxObject* pFindObj = NULL;
142 0 : SbxVariable* pFindVar = pObj->Find( aNameStr, SbxCLASS_DONTCARE );
143 0 : if( pFindVar == NULL )
144 : {
145 0 : StarBASIC::Error( SbERR_PROC_UNDEFINED );
146 0 : return;
147 : }
148 :
149 0 : switch( nCallType )
150 : {
151 : case vbGet:
152 : {
153 0 : SbxValues aVals;
154 0 : aVals.eType = SbxVARIANT;
155 0 : pFindVar->Get( aVals );
156 :
157 0 : SbxVariableRef refVar = rPar.Get(0);
158 0 : refVar->Put( aVals );
159 : }
160 0 : break;
161 : case vbLet:
162 : case vbSet:
163 : {
164 0 : if ( nParCount != 5 )
165 : {
166 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
167 0 : return;
168 : }
169 0 : SbxVariableRef pValVar = rPar.Get(4);
170 0 : if( nCallType == vbLet )
171 : {
172 0 : SbxValues aVals;
173 0 : aVals.eType = SbxVARIANT;
174 0 : pValVar->Get( aVals );
175 0 : pFindVar->Put( aVals );
176 : }
177 : else
178 : {
179 0 : SbxVariableRef rFindVar = pFindVar;
180 0 : SbiInstance* pInst = GetSbData()->pInst;
181 0 : SbiRuntime* pRT = pInst ? pInst->pRun : NULL;
182 0 : if( pRT != NULL )
183 : {
184 0 : pRT->StepSET_Impl( pValVar, rFindVar, false );
185 0 : }
186 0 : }
187 : }
188 0 : break;
189 : case vbMethod:
190 : {
191 0 : SbMethod* pMeth = PTR_CAST(SbMethod,pFindVar);
192 0 : if( pMeth == NULL )
193 : {
194 0 : StarBASIC::Error( SbERR_PROC_UNDEFINED );
195 0 : return;
196 : }
197 :
198 : // Setup parameters
199 0 : SbxArrayRef xArray;
200 0 : sal_uInt16 nMethParamCount = nParCount - 4;
201 0 : if( nMethParamCount > 0 )
202 : {
203 0 : xArray = new SbxArray;
204 0 : for( sal_uInt16 i = 0 ; i < nMethParamCount ; i++ )
205 : {
206 0 : SbxVariable* pPar = rPar.Get( i + 4 );
207 0 : xArray->Put( pPar, i + 1 );
208 : }
209 : }
210 :
211 : // Call method
212 0 : SbxVariableRef refVar = rPar.Get(0);
213 0 : if( xArray.Is() )
214 0 : pMeth->SetParameters( xArray );
215 0 : pMeth->Call( refVar );
216 0 : pMeth->SetParameters( NULL );
217 : }
218 0 : break;
219 : default:
220 0 : StarBASIC::Error( SbERR_PROC_UNDEFINED );
221 0 : }
222 : }
223 :
224 0 : RTLFUNC(CBool) // JSM
225 : {
226 : (void)pBasic;
227 : (void)bWrite;
228 :
229 0 : bool bVal = false;
230 0 : if ( rPar.Count() == 2 )
231 : {
232 0 : SbxVariable *pSbxVariable = rPar.Get(1);
233 0 : bVal = pSbxVariable->GetBool();
234 : }
235 : else
236 : {
237 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
238 : }
239 0 : rPar.Get(0)->PutBool(bVal);
240 0 : }
241 :
242 0 : RTLFUNC(CByte) // JSM
243 : {
244 : (void)pBasic;
245 : (void)bWrite;
246 :
247 0 : sal_uInt8 nByte = 0;
248 0 : if ( rPar.Count() == 2 )
249 : {
250 0 : SbxVariable *pSbxVariable = rPar.Get(1);
251 0 : nByte = pSbxVariable->GetByte();
252 : }
253 : else
254 : {
255 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
256 : }
257 0 : rPar.Get(0)->PutByte(nByte);
258 0 : }
259 :
260 0 : RTLFUNC(CCur)
261 : {
262 : (void)pBasic;
263 : (void)bWrite;
264 :
265 0 : sal_Int64 nCur = 0;
266 0 : if ( rPar.Count() == 2 )
267 : {
268 0 : SbxVariable *pSbxVariable = rPar.Get(1);
269 0 : nCur = pSbxVariable->GetCurrency();
270 : }
271 : else
272 : {
273 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
274 : }
275 0 : rPar.Get(0)->PutCurrency( nCur );
276 0 : }
277 :
278 0 : RTLFUNC(CDec)
279 : {
280 : (void)pBasic;
281 : (void)bWrite;
282 :
283 : #ifdef WNT
284 : SbxDecimal* pDec = NULL;
285 : if ( rPar.Count() == 2 )
286 : {
287 : SbxVariable *pSbxVariable = rPar.Get(1);
288 : pDec = pSbxVariable->GetDecimal();
289 : }
290 : else
291 : {
292 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
293 : }
294 : rPar.Get(0)->PutDecimal( pDec );
295 : #else
296 0 : rPar.Get(0)->PutEmpty();
297 0 : StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
298 : #endif
299 0 : }
300 :
301 0 : RTLFUNC(CDate) // JSM
302 : {
303 : (void)pBasic;
304 : (void)bWrite;
305 :
306 0 : double nVal = 0.0;
307 0 : if ( rPar.Count() == 2 )
308 : {
309 0 : SbxVariable *pSbxVariable = rPar.Get(1);
310 0 : nVal = pSbxVariable->GetDate();
311 : }
312 : else
313 : {
314 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
315 : }
316 0 : rPar.Get(0)->PutDate(nVal);
317 0 : }
318 :
319 0 : RTLFUNC(CDbl) // JSM
320 : {
321 : (void)pBasic;
322 : (void)bWrite;
323 :
324 0 : double nVal = 0.0;
325 0 : if ( rPar.Count() == 2 )
326 : {
327 0 : SbxVariable *pSbxVariable = rPar.Get(1);
328 0 : if( pSbxVariable->GetType() == SbxSTRING )
329 : {
330 : // #41690
331 0 : OUString aScanStr = pSbxVariable->GetOUString();
332 0 : SbError Error = SbxValue::ScanNumIntnl( aScanStr, nVal );
333 0 : if( Error != SbxERR_OK )
334 : {
335 0 : StarBASIC::Error( Error );
336 0 : }
337 : }
338 : else
339 : {
340 0 : nVal = pSbxVariable->GetDouble();
341 : }
342 : }
343 : else
344 : {
345 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
346 : }
347 :
348 0 : rPar.Get(0)->PutDouble(nVal);
349 0 : }
350 :
351 0 : RTLFUNC(CInt) // JSM
352 : {
353 : (void)pBasic;
354 : (void)bWrite;
355 :
356 0 : sal_Int16 nVal = 0;
357 0 : if ( rPar.Count() == 2 )
358 : {
359 0 : SbxVariable *pSbxVariable = rPar.Get(1);
360 0 : nVal = pSbxVariable->GetInteger();
361 : }
362 : else
363 : {
364 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
365 : }
366 0 : rPar.Get(0)->PutInteger(nVal);
367 0 : }
368 :
369 0 : RTLFUNC(CLng) // JSM
370 : {
371 : (void)pBasic;
372 : (void)bWrite;
373 :
374 0 : sal_Int32 nVal = 0;
375 0 : if ( rPar.Count() == 2 )
376 : {
377 0 : SbxVariable *pSbxVariable = rPar.Get(1);
378 0 : nVal = pSbxVariable->GetLong();
379 : }
380 : else
381 : {
382 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
383 : }
384 0 : rPar.Get(0)->PutLong(nVal);
385 0 : }
386 :
387 0 : RTLFUNC(CSng) // JSM
388 : {
389 : (void)pBasic;
390 : (void)bWrite;
391 :
392 0 : float nVal = (float)0.0;
393 0 : if ( rPar.Count() == 2 )
394 : {
395 0 : SbxVariable *pSbxVariable = rPar.Get(1);
396 0 : if( pSbxVariable->GetType() == SbxSTRING )
397 : {
398 : // #41690
399 0 : double dVal = 0.0;
400 0 : OUString aScanStr = pSbxVariable->GetOUString();
401 0 : SbError Error = SbxValue::ScanNumIntnl( aScanStr, dVal, /*bSingle=*/true );
402 0 : if( SbxBase::GetError() == SbxERR_OK && Error != SbxERR_OK )
403 : {
404 0 : StarBASIC::Error( Error );
405 : }
406 0 : nVal = (float)dVal;
407 : }
408 : else
409 : {
410 0 : nVal = pSbxVariable->GetSingle();
411 : }
412 : }
413 : else
414 : {
415 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
416 : }
417 0 : rPar.Get(0)->PutSingle(nVal);
418 0 : }
419 :
420 0 : RTLFUNC(CStr) // JSM
421 : {
422 : (void)pBasic;
423 : (void)bWrite;
424 :
425 0 : OUString aString;
426 0 : if ( rPar.Count() == 2 )
427 : {
428 0 : SbxVariable *pSbxVariable = rPar.Get(1);
429 0 : aString = pSbxVariable->GetOUString();
430 : }
431 : else
432 : {
433 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
434 : }
435 0 : rPar.Get(0)->PutString(aString);
436 0 : }
437 :
438 0 : RTLFUNC(CVar) // JSM
439 : {
440 : (void)pBasic;
441 : (void)bWrite;
442 :
443 0 : SbxValues aVals( SbxVARIANT );
444 0 : if ( rPar.Count() == 2 )
445 : {
446 0 : SbxVariable *pSbxVariable = rPar.Get(1);
447 0 : pSbxVariable->Get( aVals );
448 : }
449 : else
450 : {
451 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
452 : }
453 0 : rPar.Get(0)->Put( aVals );
454 0 : }
455 :
456 0 : RTLFUNC(CVErr)
457 : {
458 : (void)pBasic;
459 : (void)bWrite;
460 :
461 0 : sal_Int16 nErrCode = 0;
462 0 : if ( rPar.Count() == 2 )
463 : {
464 0 : SbxVariable *pSbxVariable = rPar.Get(1);
465 0 : nErrCode = pSbxVariable->GetInteger();
466 : }
467 : else
468 : {
469 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
470 : }
471 0 : rPar.Get(0)->PutErr( nErrCode );
472 0 : }
473 :
474 0 : RTLFUNC(Iif) // JSM
475 : {
476 : (void)pBasic;
477 : (void)bWrite;
478 :
479 0 : if ( rPar.Count() == 4 )
480 : {
481 0 : if (rPar.Get(1)->GetBool())
482 : {
483 0 : *rPar.Get(0) = *rPar.Get(2);
484 : }
485 : else
486 : {
487 0 : *rPar.Get(0) = *rPar.Get(3);
488 : }
489 : }
490 : else
491 : {
492 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
493 : }
494 0 : }
495 :
496 0 : RTLFUNC(GetSystemType)
497 : {
498 : (void)pBasic;
499 : (void)bWrite;
500 :
501 0 : if ( rPar.Count() != 1 )
502 : {
503 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
504 : }
505 : else
506 : {
507 : // Removed for SRC595
508 0 : rPar.Get(0)->PutInteger( -1 );
509 : }
510 0 : }
511 :
512 0 : RTLFUNC(GetGUIType)
513 : {
514 : (void)pBasic;
515 : (void)bWrite;
516 :
517 0 : if ( rPar.Count() != 1 )
518 : {
519 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
520 : }
521 : else
522 : {
523 : // 17.7.2000 Make simple solution for testtool / fat office
524 : #if defined (WNT)
525 : rPar.Get(0)->PutInteger( 1 );
526 : #elif defined UNX
527 0 : rPar.Get(0)->PutInteger( 4 );
528 : #else
529 : rPar.Get(0)->PutInteger( -1 );
530 : #endif
531 : }
532 0 : }
533 :
534 0 : RTLFUNC(Red)
535 : {
536 : (void)pBasic;
537 : (void)bWrite;
538 :
539 0 : if ( rPar.Count() != 2 )
540 : {
541 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
542 : }
543 : else
544 : {
545 0 : sal_Int32 nRGB = rPar.Get(1)->GetLong();
546 0 : nRGB &= 0x00FF0000;
547 0 : nRGB >>= 16;
548 0 : rPar.Get(0)->PutInteger( (sal_Int16)nRGB );
549 : }
550 0 : }
551 :
552 0 : RTLFUNC(Green)
553 : {
554 : (void)pBasic;
555 : (void)bWrite;
556 :
557 0 : if ( rPar.Count() != 2 )
558 : {
559 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
560 : }
561 : else
562 : {
563 0 : sal_Int32 nRGB = rPar.Get(1)->GetLong();
564 0 : nRGB &= 0x0000FF00;
565 0 : nRGB >>= 8;
566 0 : rPar.Get(0)->PutInteger( (sal_Int16)nRGB );
567 : }
568 0 : }
569 :
570 0 : RTLFUNC(Blue)
571 : {
572 : (void)pBasic;
573 : (void)bWrite;
574 :
575 0 : if ( rPar.Count() != 2 )
576 : {
577 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
578 : }
579 : else
580 : {
581 0 : sal_Int32 nRGB = rPar.Get(1)->GetLong();
582 0 : nRGB &= 0x000000FF;
583 0 : rPar.Get(0)->PutInteger( (sal_Int16)nRGB );
584 : }
585 0 : }
586 :
587 :
588 0 : RTLFUNC(Switch)
589 : {
590 : (void)pBasic;
591 : (void)bWrite;
592 :
593 0 : sal_uInt16 nCount = rPar.Count();
594 0 : if( !(nCount & 0x0001 ))
595 : {
596 : // number of arguments must be odd
597 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
598 : }
599 0 : sal_uInt16 nCurExpr = 1;
600 0 : while( nCurExpr < (nCount-1) )
601 : {
602 0 : if( rPar.Get( nCurExpr )->GetBool())
603 : {
604 0 : (*rPar.Get(0)) = *(rPar.Get(nCurExpr+1));
605 0 : return;
606 : }
607 0 : nCurExpr += 2;
608 : }
609 0 : rPar.Get(0)->PutNull();
610 : }
611 :
612 : //i#64882# Common wait impl for existing Wait and new WaitUntil
613 : // rtl functions
614 0 : void Wait_Impl( bool bDurationBased, SbxArray& rPar )
615 : {
616 0 : if( rPar.Count() != 2 )
617 : {
618 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
619 0 : return;
620 : }
621 0 : long nWait = 0;
622 0 : if ( bDurationBased )
623 : {
624 0 : double dWait = rPar.Get(1)->GetDouble();
625 0 : double dNow = Now_Impl();
626 0 : double dSecs = (double)( ( dWait - dNow ) * (double)( 24.0*3600.0) );
627 0 : nWait = (long)( dSecs * 1000 ); // wait in thousands of sec
628 : }
629 : else
630 : {
631 0 : nWait = rPar.Get(1)->GetLong();
632 : }
633 0 : if( nWait < 0 )
634 : {
635 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
636 0 : return;
637 : }
638 :
639 0 : Timer aTimer;
640 0 : aTimer.SetTimeout( nWait );
641 0 : aTimer.Start();
642 0 : while ( aTimer.IsActive() )
643 : {
644 0 : Application::Yield();
645 0 : }
646 : }
647 :
648 : //i#64882#
649 0 : RTLFUNC(Wait)
650 : {
651 : (void)pBasic;
652 : (void)bWrite;
653 0 : Wait_Impl( false, rPar );
654 0 : }
655 :
656 : //i#64882# add new WaitUntil ( for application.wait )
657 : // share wait_impl with 'normal' oobasic wait
658 0 : RTLFUNC(WaitUntil)
659 : {
660 : (void)pBasic;
661 : (void)bWrite;
662 0 : Wait_Impl( true, rPar );
663 0 : }
664 :
665 0 : RTLFUNC(DoEvents)
666 : {
667 : (void)pBasic;
668 : (void)bWrite;
669 : (void)rPar;
670 : // don't undstand what upstream are up to
671 : // we already process application events etc. in between
672 : // basic runtime pcode ( on a timed basis )
673 : // always return 0
674 0 : rPar.Get(0)->PutInteger( 0 );
675 0 : Application::Reschedule( true );
676 0 : }
677 :
678 0 : RTLFUNC(GetGUIVersion)
679 : {
680 : (void)pBasic;
681 : (void)bWrite;
682 :
683 0 : if ( rPar.Count() != 1 )
684 : {
685 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
686 : }
687 : else
688 : {
689 : // Removed for SRC595
690 0 : rPar.Get(0)->PutLong( -1 );
691 : }
692 0 : }
693 :
694 0 : RTLFUNC(Choose)
695 : {
696 : (void)pBasic;
697 : (void)bWrite;
698 :
699 0 : if ( rPar.Count() < 2 )
700 : {
701 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
702 : }
703 0 : sal_Int16 nIndex = rPar.Get(1)->GetInteger();
704 0 : sal_uInt16 nCount = rPar.Count();
705 0 : nCount--;
706 0 : if( nCount == 1 || nIndex > (nCount-1) || nIndex < 1 )
707 : {
708 0 : rPar.Get(0)->PutNull();
709 0 : return;
710 : }
711 0 : (*rPar.Get(0)) = *(rPar.Get(nIndex+1));
712 : }
713 :
714 :
715 0 : RTLFUNC(Trim)
716 : {
717 : (void)pBasic;
718 : (void)bWrite;
719 :
720 0 : if ( rPar.Count() < 2 )
721 : {
722 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
723 : }
724 : else
725 : {
726 0 : OUString aStr(comphelper::string::strip(rPar.Get(1)->GetOUString(), ' '));
727 0 : rPar.Get(0)->PutString(aStr);
728 : }
729 0 : }
730 :
731 0 : RTLFUNC(GetSolarVersion)
732 : {
733 : (void)pBasic;
734 : (void)bWrite;
735 :
736 0 : rPar.Get(0)->PutLong( (sal_Int32)SUPD );
737 0 : }
738 :
739 0 : RTLFUNC(TwipsPerPixelX)
740 : {
741 : (void)pBasic;
742 : (void)bWrite;
743 :
744 0 : sal_Int32 nResult = 0;
745 0 : Size aSize( 100,0 );
746 0 : MapMode aMap( MAP_TWIP );
747 0 : OutputDevice* pDevice = Application::GetDefaultDevice();
748 0 : if( pDevice )
749 : {
750 0 : aSize = pDevice->PixelToLogic( aSize, aMap );
751 0 : nResult = aSize.Width() / 100;
752 : }
753 0 : rPar.Get(0)->PutLong( nResult );
754 0 : }
755 :
756 0 : RTLFUNC(TwipsPerPixelY)
757 : {
758 : (void)pBasic;
759 : (void)bWrite;
760 :
761 0 : sal_Int32 nResult = 0;
762 0 : Size aSize( 0,100 );
763 0 : MapMode aMap( MAP_TWIP );
764 0 : OutputDevice* pDevice = Application::GetDefaultDevice();
765 0 : if( pDevice )
766 : {
767 0 : aSize = pDevice->PixelToLogic( aSize, aMap );
768 0 : nResult = aSize.Height() / 100;
769 : }
770 0 : rPar.Get(0)->PutLong( nResult );
771 0 : }
772 :
773 :
774 0 : RTLFUNC(FreeLibrary)
775 : {
776 : (void)pBasic;
777 : (void)bWrite;
778 :
779 0 : if ( rPar.Count() != 2 )
780 : {
781 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
782 : }
783 0 : GetSbData()->pInst->GetDllMgr()->FreeDll( rPar.Get(1)->GetOUString() );
784 0 : }
785 0 : bool IsBaseIndexOne()
786 : {
787 0 : bool result = false;
788 0 : if ( GetSbData()->pInst && GetSbData()->pInst->pRun )
789 : {
790 0 : sal_uInt16 res = GetSbData()->pInst->pRun->GetBase();
791 0 : if ( res )
792 : {
793 0 : result = true;
794 : }
795 : }
796 0 : return result;
797 : }
798 :
799 0 : RTLFUNC(Array)
800 : {
801 : (void)pBasic;
802 : (void)bWrite;
803 :
804 0 : SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
805 0 : sal_uInt16 nArraySize = rPar.Count() - 1;
806 :
807 : // ignore Option Base so far (unfortunately only known by the compiler)
808 0 : bool bIncIndex = (IsBaseIndexOne() && SbiRuntime::isVBAEnabled() );
809 0 : if( nArraySize )
810 : {
811 0 : if ( bIncIndex )
812 : {
813 0 : pArray->AddDim( 1, nArraySize );
814 : }
815 : else
816 : {
817 0 : pArray->AddDim( 0, nArraySize-1 );
818 : }
819 : }
820 : else
821 : {
822 0 : pArray->unoAddDim( 0, -1 );
823 : }
824 :
825 : // insert parameters into the array
826 : // ATTENTION: Using type sal_uInt16 for loop variable is
827 : // mandatory to workaround a problem with the
828 : // Solaris Intel compiler optimizer! See i104354
829 0 : for( sal_uInt16 i = 0 ; i < nArraySize ; i++ )
830 : {
831 0 : SbxVariable* pVar = rPar.Get(i+1);
832 0 : SbxVariable* pNew = new SbxVariable( *pVar );
833 0 : pNew->SetFlag( SBX_WRITE );
834 0 : short index = static_cast< short >(i);
835 0 : if ( bIncIndex )
836 : {
837 0 : ++index;
838 : }
839 0 : pArray->Put( pNew, &index );
840 : }
841 :
842 : // return array
843 0 : SbxVariableRef refVar = rPar.Get(0);
844 0 : sal_uInt16 nFlags = refVar->GetFlags();
845 0 : refVar->ResetFlag( SBX_FIXED );
846 0 : refVar->PutObject( pArray );
847 0 : refVar->SetFlags( nFlags );
848 0 : refVar->SetParameters( NULL );
849 0 : }
850 :
851 :
852 : // Featurewish #57868
853 : // The function returns a variant-array; if there are no parameters passed,
854 : // an empty array is created (according to dim a(); equal to a sequence of
855 : // the length 0 in Uno).
856 : // If there are parameters passed, there's a dimension created for each of
857 : // them; DimArray( 2, 2, 4 ) is equal to DIM a( 2, 2, 4 )
858 : // the array is always of the type variant
859 0 : RTLFUNC(DimArray)
860 : {
861 : (void)pBasic;
862 : (void)bWrite;
863 :
864 0 : SbxDimArray * pArray = new SbxDimArray( SbxVARIANT );
865 0 : sal_uInt16 nArrayDims = rPar.Count() - 1;
866 0 : if( nArrayDims > 0 )
867 : {
868 0 : for( sal_uInt16 i = 0; i < nArrayDims ; i++ )
869 : {
870 0 : sal_Int32 ub = rPar.Get(i+1)->GetLong();
871 0 : if( ub < 0 )
872 : {
873 0 : StarBASIC::Error( SbERR_OUT_OF_RANGE );
874 0 : ub = 0;
875 : }
876 0 : pArray->AddDim32( 0, ub );
877 : }
878 : }
879 : else
880 : {
881 0 : pArray->unoAddDim( 0, -1 );
882 : }
883 0 : SbxVariableRef refVar = rPar.Get(0);
884 0 : sal_uInt16 nFlags = refVar->GetFlags();
885 0 : refVar->ResetFlag( SBX_FIXED );
886 0 : refVar->PutObject( pArray );
887 0 : refVar->SetFlags( nFlags );
888 0 : refVar->SetParameters( NULL );
889 0 : }
890 :
891 : /*
892 : * FindObject and FindPropertyObject make it possible to
893 : * address objects and properties of the type Object with
894 : * their name as string-pararmeters at the runtime.
895 : *
896 : * Example:
897 : * MyObj.Prop1.Bla = 5
898 : *
899 : * is equal to:
900 : * dim ObjVar as Object
901 : * dim ObjProp as Object
902 : * ObjName$ = "MyObj"
903 : * ObjVar = FindObject( ObjName$ )
904 : * PropName$ = "Prop1"
905 : * ObjProp = FindPropertyObject( ObjVar, PropName$ )
906 : * ObjProp.Bla = 5
907 : *
908 : * The names can be created dynamically at the runtime
909 : * so that e. g. via controls "TextEdit1" to "TextEdit5"
910 : * can be iterated in a dialog in a loop.
911 : */
912 :
913 :
914 : // 1st parameter = the object's name as string
915 0 : RTLFUNC(FindObject)
916 : {
917 : (void)pBasic;
918 : (void)bWrite;
919 :
920 0 : if ( rPar.Count() < 2 )
921 : {
922 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
923 0 : return;
924 : }
925 :
926 0 : OUString aNameStr = rPar.Get(1)->GetOUString();
927 :
928 0 : SbxBase* pFind = StarBASIC::FindSBXInCurrentScope( aNameStr );
929 0 : SbxObject* pFindObj = NULL;
930 0 : if( pFind )
931 : {
932 0 : pFindObj = PTR_CAST(SbxObject,pFind);
933 : }
934 0 : SbxVariableRef refVar = rPar.Get(0);
935 0 : refVar->PutObject( pFindObj );
936 : }
937 :
938 : // address object-property in an object
939 : // 1st parameter = object
940 : // 2nd parameter = the property's name as string
941 0 : RTLFUNC(FindPropertyObject)
942 : {
943 : (void)pBasic;
944 : (void)bWrite;
945 :
946 0 : if ( rPar.Count() < 3 )
947 : {
948 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
949 0 : return;
950 : }
951 :
952 0 : SbxBase* pObjVar = (SbxObject*)rPar.Get(1)->GetObject();
953 0 : SbxObject* pObj = NULL;
954 0 : if( pObjVar )
955 : {
956 0 : pObj = PTR_CAST(SbxObject,pObjVar);
957 : }
958 0 : if( !pObj && pObjVar && pObjVar->ISA(SbxVariable) )
959 : {
960 0 : SbxBase* pObjVarObj = ((SbxVariable*)pObjVar)->GetObject();
961 0 : pObj = PTR_CAST(SbxObject,pObjVarObj);
962 : }
963 :
964 0 : OUString aNameStr = rPar.Get(2)->GetOUString();
965 :
966 0 : SbxObject* pFindObj = NULL;
967 0 : if( pObj )
968 : {
969 0 : SbxVariable* pFindVar = pObj->Find( aNameStr, SbxCLASS_OBJECT );
970 0 : pFindObj = PTR_CAST(SbxObject,pFindVar);
971 : }
972 : else
973 : {
974 0 : StarBASIC::Error( SbERR_BAD_PARAMETER );
975 : }
976 :
977 0 : SbxVariableRef refVar = rPar.Get(0);
978 0 : refVar->PutObject( pFindObj );
979 : }
980 :
981 :
982 :
983 0 : static bool lcl_WriteSbxVariable( const SbxVariable& rVar, SvStream* pStrm,
984 : bool bBinary, short nBlockLen, bool bIsArray )
985 : {
986 0 : sal_Size nFPos = pStrm->Tell();
987 :
988 0 : bool bIsVariant = !rVar.IsFixed();
989 0 : SbxDataType eType = rVar.GetType();
990 :
991 0 : switch( eType )
992 : {
993 : case SbxBOOL:
994 : case SbxCHAR:
995 : case SbxBYTE:
996 0 : if( bIsVariant )
997 : {
998 0 : pStrm->WriteUInt16( (sal_uInt16)SbxBYTE ); // VarType Id
999 : }
1000 0 : pStrm->WriteUChar( rVar.GetByte() );
1001 0 : break;
1002 :
1003 : case SbxEMPTY:
1004 : case SbxNULL:
1005 : case SbxVOID:
1006 : case SbxINTEGER:
1007 : case SbxUSHORT:
1008 : case SbxINT:
1009 : case SbxUINT:
1010 0 : if( bIsVariant )
1011 : {
1012 0 : pStrm->WriteUInt16( (sal_uInt16)SbxINTEGER ); // VarType Id
1013 : }
1014 0 : pStrm->WriteInt16( rVar.GetInteger() );
1015 0 : break;
1016 :
1017 : case SbxLONG:
1018 : case SbxULONG:
1019 0 : if( bIsVariant )
1020 : {
1021 0 : pStrm->WriteUInt16( (sal_uInt16)SbxLONG ); // VarType Id
1022 : }
1023 0 : pStrm->WriteInt32( rVar.GetLong() );
1024 0 : break;
1025 : case SbxSALINT64:
1026 : case SbxSALUINT64:
1027 0 : if( bIsVariant )
1028 : {
1029 0 : pStrm->WriteUInt16( (sal_uInt16)SbxSALINT64 ); // VarType Id
1030 : }
1031 0 : pStrm->WriteUInt64( (sal_uInt64)rVar.GetInt64() );
1032 0 : break;
1033 : case SbxSINGLE:
1034 0 : if( bIsVariant )
1035 : {
1036 0 : pStrm->WriteUInt16( (sal_uInt16)eType ); // VarType Id
1037 : }
1038 0 : pStrm->WriteFloat( rVar.GetSingle() );
1039 0 : break;
1040 :
1041 : case SbxDOUBLE:
1042 : case SbxCURRENCY:
1043 : case SbxDATE:
1044 0 : if( bIsVariant )
1045 : {
1046 0 : pStrm->WriteUInt16( (sal_uInt16)eType ); // VarType Id
1047 : }
1048 0 : pStrm->WriteDouble( rVar.GetDouble() );
1049 0 : break;
1050 :
1051 : case SbxSTRING:
1052 : case SbxLPSTR:
1053 : {
1054 0 : const OUString& rStr = rVar.GetOUString();
1055 0 : if( !bBinary || bIsArray )
1056 : {
1057 0 : if( bIsVariant )
1058 : {
1059 0 : pStrm->WriteUInt16( (sal_uInt16)SbxSTRING );
1060 : }
1061 0 : pStrm->WriteUniOrByteString( rStr, osl_getThreadTextEncoding() );
1062 : }
1063 : else
1064 : {
1065 : // without any length information! without end-identifier!
1066 : // What does that mean for Unicode?! Choosing conversion to ByteString...
1067 0 : OString aByteStr(OUStringToOString(rStr, osl_getThreadTextEncoding()));
1068 0 : pStrm->WriteCharPtr( (const char*)aByteStr.getStr() );
1069 0 : }
1070 : }
1071 0 : break;
1072 :
1073 : default:
1074 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1075 0 : return false;
1076 : }
1077 :
1078 0 : if( nBlockLen )
1079 : {
1080 0 : pStrm->Seek( nFPos + nBlockLen );
1081 : }
1082 0 : return pStrm->GetErrorCode() ? sal_False : sal_True;
1083 : }
1084 :
1085 0 : static bool lcl_ReadSbxVariable( SbxVariable& rVar, SvStream* pStrm,
1086 : bool bBinary, short nBlockLen, bool bIsArray )
1087 : {
1088 : (void)bBinary;
1089 : (void)bIsArray;
1090 :
1091 : double aDouble;
1092 :
1093 0 : sal_Size nFPos = pStrm->Tell();
1094 :
1095 0 : bool bIsVariant = !rVar.IsFixed();
1096 0 : SbxDataType eVarType = rVar.GetType();
1097 :
1098 0 : SbxDataType eSrcType = eVarType;
1099 0 : if( bIsVariant )
1100 : {
1101 : sal_uInt16 nTemp;
1102 0 : pStrm->ReadUInt16( nTemp );
1103 0 : eSrcType = (SbxDataType)nTemp;
1104 : }
1105 :
1106 0 : switch( eSrcType )
1107 : {
1108 : case SbxBOOL:
1109 : case SbxCHAR:
1110 : case SbxBYTE:
1111 : {
1112 : sal_uInt8 aByte;
1113 0 : pStrm->ReadUChar( aByte );
1114 :
1115 0 : if( bBinary && SbiRuntime::isVBAEnabled() && aByte == 1 && pStrm->IsEof() )
1116 : {
1117 0 : aByte = 0;
1118 : }
1119 0 : rVar.PutByte( aByte );
1120 : }
1121 0 : break;
1122 :
1123 : case SbxEMPTY:
1124 : case SbxNULL:
1125 : case SbxVOID:
1126 : case SbxINTEGER:
1127 : case SbxUSHORT:
1128 : case SbxINT:
1129 : case SbxUINT:
1130 : {
1131 : sal_Int16 aInt;
1132 0 : pStrm->ReadInt16( aInt );
1133 0 : rVar.PutInteger( aInt );
1134 : }
1135 0 : break;
1136 :
1137 : case SbxLONG:
1138 : case SbxULONG:
1139 : {
1140 : sal_Int32 aInt;
1141 0 : pStrm->ReadInt32( aInt );
1142 0 : rVar.PutLong( aInt );
1143 : }
1144 0 : break;
1145 : case SbxSALINT64:
1146 : case SbxSALUINT64:
1147 : {
1148 : sal_uInt32 aInt;
1149 0 : pStrm->ReadUInt32( aInt );
1150 0 : rVar.PutInt64( (sal_Int64)aInt );
1151 : }
1152 0 : break;
1153 : case SbxSINGLE:
1154 : {
1155 : float nS;
1156 0 : pStrm->ReadFloat( nS );
1157 0 : rVar.PutSingle( nS );
1158 : }
1159 0 : break;
1160 :
1161 : case SbxDOUBLE:
1162 : case SbxCURRENCY:
1163 : {
1164 0 : pStrm->ReadDouble( aDouble );
1165 0 : rVar.PutDouble( aDouble );
1166 : }
1167 0 : break;
1168 :
1169 : case SbxDATE:
1170 : {
1171 0 : pStrm->ReadDouble( aDouble );
1172 0 : rVar.PutDate( aDouble );
1173 : }
1174 0 : break;
1175 :
1176 : case SbxSTRING:
1177 : case SbxLPSTR:
1178 : {
1179 0 : OUString aStr = pStrm->ReadUniOrByteString(osl_getThreadTextEncoding());
1180 0 : rVar.PutString( aStr );
1181 : }
1182 0 : break;
1183 :
1184 : default:
1185 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1186 0 : return false;
1187 : }
1188 :
1189 0 : if( nBlockLen )
1190 : {
1191 0 : pStrm->Seek( nFPos + nBlockLen );
1192 : }
1193 0 : return pStrm->GetErrorCode() ? sal_False : sal_True;
1194 : }
1195 :
1196 :
1197 : // nCurDim = 1...n
1198 0 : static bool lcl_WriteReadSbxArray( SbxDimArray& rArr, SvStream* pStrm,
1199 : bool bBinary, short nCurDim, short* pOtherDims, bool bWrite )
1200 : {
1201 : SAL_WARN_IF( nCurDim <= 0,"basic", "Bad Dim");
1202 : short nLower, nUpper;
1203 0 : if( !rArr.GetDim( nCurDim, nLower, nUpper ) )
1204 0 : return false;
1205 0 : for( short nCur = nLower; nCur <= nUpper; nCur++ )
1206 : {
1207 0 : pOtherDims[ nCurDim-1 ] = nCur;
1208 0 : if( nCurDim != 1 )
1209 0 : lcl_WriteReadSbxArray(rArr, pStrm, bBinary, nCurDim-1, pOtherDims, bWrite);
1210 : else
1211 : {
1212 0 : SbxVariable* pVar = rArr.Get( (const short*)pOtherDims );
1213 : bool bRet;
1214 0 : if( bWrite )
1215 0 : bRet = lcl_WriteSbxVariable(*pVar, pStrm, bBinary, 0, true );
1216 : else
1217 0 : bRet = lcl_ReadSbxVariable(*pVar, pStrm, bBinary, 0, true );
1218 0 : if( !bRet )
1219 0 : return false;
1220 : }
1221 : }
1222 0 : return true;
1223 : }
1224 :
1225 0 : void PutGet( SbxArray& rPar, bool bPut )
1226 : {
1227 0 : if ( rPar.Count() != 4 )
1228 : {
1229 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1230 0 : return;
1231 : }
1232 0 : sal_Int16 nFileNo = rPar.Get(1)->GetInteger();
1233 0 : SbxVariable* pVar2 = rPar.Get(2);
1234 0 : SbxDataType eType2 = pVar2->GetType();
1235 0 : bool bHasRecordNo = (eType2 != SbxEMPTY && eType2 != SbxERROR);
1236 0 : long nRecordNo = pVar2->GetLong();
1237 0 : if ( nFileNo < 1 || ( bHasRecordNo && nRecordNo < 1 ) )
1238 : {
1239 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1240 0 : return;
1241 : }
1242 0 : nRecordNo--;
1243 0 : SbiIoSystem* pIO = GetSbData()->pInst->GetIoSystem();
1244 0 : SbiStream* pSbStrm = pIO->GetStream( nFileNo );
1245 :
1246 0 : if ( !pSbStrm || !(pSbStrm->GetMode() & (SBSTRM_BINARY | SBSTRM_RANDOM)) )
1247 : {
1248 0 : StarBASIC::Error( SbERR_BAD_CHANNEL );
1249 0 : return;
1250 : }
1251 :
1252 0 : SvStream* pStrm = pSbStrm->GetStrm();
1253 0 : bool bRandom = pSbStrm->IsRandom();
1254 0 : short nBlockLen = bRandom ? pSbStrm->GetBlockLen() : 0;
1255 :
1256 0 : if( bPut )
1257 : {
1258 0 : pSbStrm->ExpandFile();
1259 : }
1260 :
1261 0 : if( bHasRecordNo )
1262 : {
1263 0 : sal_Size nFilePos = bRandom ? (sal_Size)(nBlockLen * nRecordNo) : (sal_Size)nRecordNo;
1264 0 : pStrm->Seek( nFilePos );
1265 : }
1266 :
1267 0 : SbxDimArray* pArr = 0;
1268 0 : SbxVariable* pVar = rPar.Get(3);
1269 0 : if( pVar->GetType() & SbxARRAY )
1270 : {
1271 0 : SbxBase* pParObj = pVar->GetObject();
1272 0 : pArr = PTR_CAST(SbxDimArray,pParObj);
1273 : }
1274 :
1275 : bool bRet;
1276 :
1277 0 : if( pArr )
1278 : {
1279 0 : sal_Size nFPos = pStrm->Tell();
1280 0 : short nDims = pArr->GetDims();
1281 0 : boost::scoped_array<short> pDims(new short[ nDims ]);
1282 0 : bRet = lcl_WriteReadSbxArray(*pArr,pStrm,!bRandom,nDims,pDims.get(),bPut);
1283 0 : pDims.reset();
1284 0 : if( nBlockLen )
1285 0 : pStrm->Seek( nFPos + nBlockLen );
1286 : }
1287 : else
1288 : {
1289 0 : if( bPut )
1290 0 : bRet = lcl_WriteSbxVariable(*pVar, pStrm, !bRandom, nBlockLen, false);
1291 : else
1292 0 : bRet = lcl_ReadSbxVariable(*pVar, pStrm, !bRandom, nBlockLen, false);
1293 : }
1294 0 : if( !bRet || pStrm->GetErrorCode() )
1295 0 : StarBASIC::Error( SbERR_IO_ERROR );
1296 : }
1297 :
1298 0 : RTLFUNC(Put)
1299 : {
1300 : (void)pBasic;
1301 : (void)bWrite;
1302 :
1303 0 : PutGet( rPar, true );
1304 0 : }
1305 :
1306 0 : RTLFUNC(Get)
1307 : {
1308 : (void)pBasic;
1309 : (void)bWrite;
1310 :
1311 0 : PutGet( rPar, false );
1312 0 : }
1313 :
1314 0 : RTLFUNC(Environ)
1315 : {
1316 : (void)pBasic;
1317 : (void)bWrite;
1318 :
1319 0 : if ( rPar.Count() != 2 )
1320 : {
1321 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1322 0 : return;
1323 : }
1324 0 : OUString aResult;
1325 : // should be ANSI but that's not possible under Win16 in the DLL
1326 0 : OString aByteStr(OUStringToOString(rPar.Get(1)->GetOUString(),
1327 0 : osl_getThreadTextEncoding()));
1328 0 : const char* pEnvStr = getenv(aByteStr.getStr());
1329 0 : if ( pEnvStr )
1330 : {
1331 0 : aResult = OUString(pEnvStr, strlen(pEnvStr), osl_getThreadTextEncoding());
1332 : }
1333 0 : rPar.Get(0)->PutString( aResult );
1334 : }
1335 :
1336 0 : static double GetDialogZoomFactor( bool bX, long nValue )
1337 : {
1338 0 : OutputDevice* pDevice = Application::GetDefaultDevice();
1339 0 : double nResult = 0;
1340 0 : if( pDevice )
1341 : {
1342 0 : Size aRefSize( nValue, nValue );
1343 0 : Fraction aFracX( 1, 26 );
1344 0 : Fraction aFracY( 1, 24 );
1345 0 : MapMode aMap( MAP_APPFONT, Point(), aFracX, aFracY );
1346 0 : Size aScaledSize = pDevice->LogicToPixel( aRefSize, aMap );
1347 0 : aRefSize = pDevice->LogicToPixel( aRefSize, MapMode(MAP_TWIP) );
1348 :
1349 : double nRef, nScaled;
1350 0 : if( bX )
1351 : {
1352 0 : nRef = aRefSize.Width();
1353 0 : nScaled = aScaledSize.Width();
1354 : }
1355 : else
1356 : {
1357 0 : nRef = aRefSize.Height();
1358 0 : nScaled = aScaledSize.Height();
1359 : }
1360 0 : nResult = nScaled / nRef;
1361 : }
1362 0 : return nResult;
1363 : }
1364 :
1365 :
1366 0 : RTLFUNC(GetDialogZoomFactorX)
1367 : {
1368 : (void)pBasic;
1369 : (void)bWrite;
1370 :
1371 0 : if ( rPar.Count() != 2 )
1372 : {
1373 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1374 0 : return;
1375 : }
1376 0 : rPar.Get(0)->PutDouble( GetDialogZoomFactor( true, rPar.Get(1)->GetLong() ));
1377 : }
1378 :
1379 0 : RTLFUNC(GetDialogZoomFactorY)
1380 : {
1381 : (void)pBasic;
1382 : (void)bWrite;
1383 :
1384 0 : if ( rPar.Count() != 2 )
1385 : {
1386 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1387 0 : return;
1388 : }
1389 0 : rPar.Get(0)->PutDouble( GetDialogZoomFactor( false, rPar.Get(1)->GetLong()));
1390 : }
1391 :
1392 :
1393 0 : RTLFUNC(EnableReschedule)
1394 : {
1395 : (void)pBasic;
1396 : (void)bWrite;
1397 :
1398 0 : rPar.Get(0)->PutEmpty();
1399 0 : if ( rPar.Count() != 2 )
1400 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1401 0 : if( GetSbData()->pInst )
1402 0 : GetSbData()->pInst->EnableReschedule( rPar.Get(1)->GetBool() );
1403 0 : }
1404 :
1405 0 : RTLFUNC(GetSystemTicks)
1406 : {
1407 : (void)pBasic;
1408 : (void)bWrite;
1409 :
1410 0 : if ( rPar.Count() != 1 )
1411 : {
1412 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1413 0 : return;
1414 : }
1415 0 : rPar.Get(0)->PutLong( Time::GetSystemTicks() );
1416 : }
1417 :
1418 0 : RTLFUNC(GetPathSeparator)
1419 : {
1420 : (void)pBasic;
1421 : (void)bWrite;
1422 :
1423 0 : if ( rPar.Count() != 1 )
1424 : {
1425 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1426 0 : return;
1427 : }
1428 0 : rPar.Get(0)->PutString( OUString( SAL_PATHDELIMITER ) );
1429 : }
1430 :
1431 0 : RTLFUNC(ResolvePath)
1432 : {
1433 : (void)pBasic;
1434 : (void)bWrite;
1435 :
1436 0 : if ( rPar.Count() == 2 )
1437 : {
1438 0 : OUString aStr = rPar.Get(1)->GetOUString();
1439 0 : rPar.Get(0)->PutString( aStr );
1440 : }
1441 : else
1442 : {
1443 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1444 : }
1445 0 : }
1446 :
1447 0 : RTLFUNC(TypeLen)
1448 : {
1449 : (void)pBasic;
1450 : (void)bWrite;
1451 :
1452 0 : if ( rPar.Count() != 2 )
1453 : {
1454 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1455 : }
1456 : else
1457 : {
1458 0 : SbxDataType eType = rPar.Get(1)->GetType();
1459 0 : sal_Int16 nLen = 0;
1460 0 : switch( eType )
1461 : {
1462 : case SbxEMPTY:
1463 : case SbxNULL:
1464 : case SbxVECTOR:
1465 : case SbxARRAY:
1466 : case SbxBYREF:
1467 : case SbxVOID:
1468 : case SbxHRESULT:
1469 : case SbxPOINTER:
1470 : case SbxDIMARRAY:
1471 : case SbxCARRAY:
1472 : case SbxUSERDEF:
1473 0 : nLen = 0;
1474 0 : break;
1475 :
1476 : case SbxINTEGER:
1477 : case SbxERROR:
1478 : case SbxUSHORT:
1479 : case SbxINT:
1480 : case SbxUINT:
1481 0 : nLen = 2;
1482 0 : break;
1483 :
1484 : case SbxLONG:
1485 : case SbxSINGLE:
1486 : case SbxULONG:
1487 0 : nLen = 4;
1488 0 : break;
1489 :
1490 : case SbxDOUBLE:
1491 : case SbxCURRENCY:
1492 : case SbxDATE:
1493 : case SbxSALINT64:
1494 : case SbxSALUINT64:
1495 0 : nLen = 8;
1496 0 : break;
1497 :
1498 : case SbxOBJECT:
1499 : case SbxVARIANT:
1500 : case SbxDATAOBJECT:
1501 0 : nLen = 0;
1502 0 : break;
1503 :
1504 : case SbxCHAR:
1505 : case SbxBYTE:
1506 : case SbxBOOL:
1507 0 : nLen = 1;
1508 0 : break;
1509 :
1510 : case SbxLPSTR:
1511 : case SbxLPWSTR:
1512 : case SbxCoreSTRING:
1513 : case SbxSTRING:
1514 0 : nLen = (sal_Int16)rPar.Get(1)->GetOUString().getLength();
1515 0 : break;
1516 :
1517 : default:
1518 0 : nLen = 0;
1519 0 : break;
1520 : }
1521 0 : rPar.Get(0)->PutInteger( nLen );
1522 : }
1523 0 : }
1524 :
1525 :
1526 : // 1st parameter == class name, other parameters for initialisation
1527 0 : RTLFUNC(CreateUnoStruct)
1528 : {
1529 : (void)pBasic;
1530 : (void)bWrite;
1531 :
1532 0 : RTL_Impl_CreateUnoStruct( pBasic, rPar, bWrite );
1533 0 : }
1534 :
1535 :
1536 : // 1st parameter == service-name
1537 0 : RTLFUNC(CreateUnoService)
1538 : {
1539 : (void)pBasic;
1540 : (void)bWrite;
1541 :
1542 0 : RTL_Impl_CreateUnoService( pBasic, rPar, bWrite );
1543 0 : }
1544 :
1545 0 : RTLFUNC(CreateUnoServiceWithArguments)
1546 : {
1547 : (void)pBasic;
1548 : (void)bWrite;
1549 :
1550 0 : RTL_Impl_CreateUnoServiceWithArguments( pBasic, rPar, bWrite );
1551 0 : }
1552 :
1553 :
1554 0 : RTLFUNC(CreateUnoValue)
1555 : {
1556 : (void)pBasic;
1557 : (void)bWrite;
1558 :
1559 0 : RTL_Impl_CreateUnoValue( pBasic, rPar, bWrite );
1560 0 : }
1561 :
1562 :
1563 : // no parameters
1564 0 : RTLFUNC(GetProcessServiceManager)
1565 : {
1566 : (void)pBasic;
1567 : (void)bWrite;
1568 :
1569 0 : RTL_Impl_GetProcessServiceManager( pBasic, rPar, bWrite );
1570 0 : }
1571 :
1572 :
1573 : // 1st parameter == Sequence<PropertyValue>
1574 0 : RTLFUNC(CreatePropertySet)
1575 : {
1576 : (void)pBasic;
1577 : (void)bWrite;
1578 :
1579 0 : RTL_Impl_CreatePropertySet( pBasic, rPar, bWrite );
1580 0 : }
1581 :
1582 :
1583 : // multiple interface-names as parameters
1584 0 : RTLFUNC(HasUnoInterfaces)
1585 : {
1586 : (void)pBasic;
1587 : (void)bWrite;
1588 :
1589 0 : RTL_Impl_HasInterfaces( pBasic, rPar, bWrite );
1590 0 : }
1591 :
1592 :
1593 0 : RTLFUNC(IsUnoStruct)
1594 : {
1595 : (void)pBasic;
1596 : (void)bWrite;
1597 :
1598 0 : RTL_Impl_IsUnoStruct( pBasic, rPar, bWrite );
1599 0 : }
1600 :
1601 :
1602 0 : RTLFUNC(EqualUnoObjects)
1603 : {
1604 : (void)pBasic;
1605 : (void)bWrite;
1606 :
1607 0 : RTL_Impl_EqualUnoObjects( pBasic, rPar, bWrite );
1608 0 : }
1609 :
1610 0 : RTLFUNC(CreateUnoDialog)
1611 : {
1612 : (void)pBasic;
1613 : (void)bWrite;
1614 :
1615 0 : RTL_Impl_CreateUnoDialog( pBasic, rPar, bWrite );
1616 0 : }
1617 :
1618 : // Return the application standard lib as root scope
1619 0 : RTLFUNC(GlobalScope)
1620 : {
1621 : (void)pBasic;
1622 : (void)bWrite;
1623 :
1624 0 : SbxObject* p = pBasic;
1625 0 : while( p->GetParent() )
1626 : {
1627 0 : p = p->GetParent();
1628 : }
1629 0 : SbxVariableRef refVar = rPar.Get(0);
1630 0 : refVar->PutObject( p );
1631 0 : }
1632 :
1633 : // Helper functions to convert Url from/to system paths
1634 0 : RTLFUNC(ConvertToUrl)
1635 : {
1636 : (void)pBasic;
1637 : (void)bWrite;
1638 :
1639 0 : if ( rPar.Count() == 2 )
1640 : {
1641 0 : OUString aStr = rPar.Get(1)->GetOUString();
1642 0 : INetURLObject aURLObj( aStr, INET_PROT_FILE );
1643 0 : OUString aFileURL = aURLObj.GetMainURL( INetURLObject::NO_DECODE );
1644 0 : if( aFileURL.isEmpty() )
1645 : {
1646 0 : ::osl::File::getFileURLFromSystemPath( aFileURL, aFileURL );
1647 : }
1648 0 : if( aFileURL.isEmpty() )
1649 : {
1650 0 : aFileURL = aStr;
1651 : }
1652 0 : rPar.Get(0)->PutString(aFileURL);
1653 : }
1654 : else
1655 : {
1656 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1657 : }
1658 0 : }
1659 :
1660 0 : RTLFUNC(ConvertFromUrl)
1661 : {
1662 : (void)pBasic;
1663 : (void)bWrite;
1664 :
1665 0 : if ( rPar.Count() == 2 )
1666 : {
1667 0 : OUString aStr = rPar.Get(1)->GetOUString();
1668 0 : OUString aSysPath;
1669 0 : ::osl::File::getSystemPathFromFileURL( aStr, aSysPath );
1670 0 : if( aSysPath.isEmpty() )
1671 : {
1672 0 : aSysPath = aStr;
1673 : }
1674 0 : rPar.Get(0)->PutString(aSysPath);
1675 : }
1676 : else
1677 : {
1678 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1679 : }
1680 0 : }
1681 :
1682 :
1683 : // Provide DefaultContext
1684 0 : RTLFUNC(GetDefaultContext)
1685 : {
1686 : (void)pBasic;
1687 : (void)bWrite;
1688 :
1689 0 : RTL_Impl_GetDefaultContext( pBasic, rPar, bWrite );
1690 0 : }
1691 :
1692 : #ifdef DBG_TRACE_BASIC
1693 : RTLFUNC(TraceCommand)
1694 : {
1695 : RTL_Impl_TraceCommand( pBasic, rPar, bWrite );
1696 : }
1697 : #endif
1698 :
1699 0 : RTLFUNC(Join)
1700 : {
1701 : (void)pBasic;
1702 : (void)bWrite;
1703 :
1704 0 : sal_uInt16 nParCount = rPar.Count();
1705 0 : if ( nParCount != 3 && nParCount != 2 )
1706 : {
1707 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1708 0 : return;
1709 : }
1710 0 : SbxBase* pParObj = rPar.Get(1)->GetObject();
1711 0 : SbxDimArray* pArr = PTR_CAST(SbxDimArray,pParObj);
1712 0 : if( pArr )
1713 : {
1714 0 : if( pArr->GetDims() != 1 )
1715 : {
1716 0 : StarBASIC::Error( SbERR_WRONG_DIMS ); // Syntax Error?!
1717 : }
1718 0 : OUString aDelim;
1719 0 : if( nParCount == 3 )
1720 : {
1721 0 : aDelim = rPar.Get(2)->GetOUString();
1722 : }
1723 : else
1724 : {
1725 0 : aDelim = " ";
1726 : }
1727 0 : OUString aRetStr;
1728 : short nLower, nUpper;
1729 0 : pArr->GetDim( 1, nLower, nUpper );
1730 0 : for( short i = nLower ; i <= nUpper ; ++i )
1731 : {
1732 0 : OUString aStr = pArr->Get( &i )->GetOUString();
1733 0 : aRetStr += aStr;
1734 0 : if( i != nUpper )
1735 : {
1736 0 : aRetStr += aDelim;
1737 : }
1738 0 : }
1739 0 : rPar.Get(0)->PutString( aRetStr );
1740 : }
1741 : else
1742 : {
1743 0 : StarBASIC::Error( SbERR_MUST_HAVE_DIMS );
1744 : }
1745 : }
1746 :
1747 :
1748 0 : RTLFUNC(Split)
1749 : {
1750 : (void)pBasic;
1751 : (void)bWrite;
1752 :
1753 0 : sal_uInt16 nParCount = rPar.Count();
1754 0 : if ( nParCount < 2 )
1755 : {
1756 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1757 0 : return;
1758 : }
1759 :
1760 0 : OUString aExpression = rPar.Get(1)->GetOUString();
1761 0 : short nArraySize = 0;
1762 0 : StringVector vRet;
1763 0 : if( !aExpression.isEmpty() )
1764 : {
1765 0 : OUString aDelim;
1766 0 : if( nParCount >= 3 )
1767 : {
1768 0 : aDelim = rPar.Get(2)->GetOUString();
1769 : }
1770 : else
1771 : {
1772 0 : aDelim = " ";
1773 : }
1774 :
1775 0 : sal_Int32 nCount = -1;
1776 0 : if( nParCount == 4 )
1777 : {
1778 0 : nCount = rPar.Get(3)->GetLong();
1779 : }
1780 0 : sal_Int32 nDelimLen = aDelim.getLength();
1781 0 : if( nDelimLen )
1782 : {
1783 0 : sal_Int32 iSearch = -1;
1784 0 : sal_Int32 iStart = 0;
1785 0 : do
1786 : {
1787 0 : bool bBreak = false;
1788 0 : if( nCount >= 0 && nArraySize == nCount - 1 )
1789 : {
1790 0 : bBreak = true;
1791 : }
1792 0 : iSearch = aExpression.indexOf( aDelim, iStart );
1793 0 : OUString aSubStr;
1794 0 : if( iSearch >= 0 && !bBreak )
1795 : {
1796 0 : aSubStr = aExpression.copy( iStart, iSearch - iStart );
1797 0 : iStart = iSearch + nDelimLen;
1798 : }
1799 : else
1800 : {
1801 0 : aSubStr = aExpression.copy( iStart );
1802 : }
1803 0 : vRet.push_back( aSubStr );
1804 0 : nArraySize++;
1805 :
1806 0 : if( bBreak )
1807 : {
1808 0 : break;
1809 0 : }
1810 : }
1811 : while( iSearch >= 0 );
1812 : }
1813 : else
1814 : {
1815 0 : vRet.push_back( aExpression );
1816 0 : nArraySize = 1;
1817 0 : }
1818 : }
1819 :
1820 0 : SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
1821 0 : pArray->unoAddDim( 0, nArraySize-1 );
1822 :
1823 : // insert parameter(s) into the array
1824 0 : for( short i = 0 ; i < nArraySize ; i++ )
1825 : {
1826 0 : SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
1827 0 : xVar->PutString( vRet[i] );
1828 0 : pArray->Put( (SbxVariable*)xVar, &i );
1829 0 : }
1830 :
1831 : // return array
1832 0 : SbxVariableRef refVar = rPar.Get(0);
1833 0 : sal_uInt16 nFlags = refVar->GetFlags();
1834 0 : refVar->ResetFlag( SBX_FIXED );
1835 0 : refVar->PutObject( pArray );
1836 0 : refVar->SetFlags( nFlags );
1837 0 : refVar->SetParameters( NULL );
1838 : }
1839 :
1840 : // MonthName(month[, abbreviate])
1841 0 : RTLFUNC(MonthName)
1842 : {
1843 : (void)pBasic;
1844 : (void)bWrite;
1845 :
1846 0 : sal_uInt16 nParCount = rPar.Count();
1847 0 : if( nParCount != 2 && nParCount != 3 )
1848 : {
1849 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1850 0 : return;
1851 : }
1852 :
1853 0 : Reference< XCalendar3 > xCalendar = getLocaleCalendar();
1854 0 : if( !xCalendar.is() )
1855 : {
1856 0 : StarBASIC::Error( SbERR_INTERNAL_ERROR );
1857 0 : return;
1858 : }
1859 0 : Sequence< CalendarItem2 > aMonthSeq = xCalendar->getMonths2();
1860 0 : sal_Int32 nMonthCount = aMonthSeq.getLength();
1861 :
1862 0 : sal_Int16 nVal = rPar.Get(1)->GetInteger();
1863 0 : if( nVal < 1 || nVal > nMonthCount )
1864 : {
1865 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1866 0 : return;
1867 : }
1868 :
1869 0 : bool bAbbreviate = false;
1870 0 : if( nParCount == 3 )
1871 0 : bAbbreviate = rPar.Get(2)->GetBool();
1872 :
1873 0 : const CalendarItem2* pCalendarItems = aMonthSeq.getConstArray();
1874 0 : const CalendarItem2& rItem = pCalendarItems[nVal - 1];
1875 :
1876 0 : OUString aRetStr = ( bAbbreviate ? rItem.AbbrevName : rItem.FullName );
1877 0 : rPar.Get(0)->PutString(aRetStr);
1878 : }
1879 :
1880 : // WeekdayName(weekday, abbreviate, firstdayofweek)
1881 0 : RTLFUNC(WeekdayName)
1882 : {
1883 : (void)pBasic;
1884 : (void)bWrite;
1885 :
1886 0 : sal_uInt16 nParCount = rPar.Count();
1887 0 : if( nParCount < 2 || nParCount > 4 )
1888 : {
1889 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1890 0 : return;
1891 : }
1892 :
1893 0 : Reference< XCalendar3 > xCalendar = getLocaleCalendar();
1894 0 : if( !xCalendar.is() )
1895 : {
1896 0 : StarBASIC::Error( SbERR_INTERNAL_ERROR );
1897 0 : return;
1898 : }
1899 :
1900 0 : Sequence< CalendarItem2 > aDaySeq = xCalendar->getDays2();
1901 0 : sal_Int16 nDayCount = (sal_Int16)aDaySeq.getLength();
1902 0 : sal_Int16 nDay = rPar.Get(1)->GetInteger();
1903 0 : sal_Int16 nFirstDay = 0;
1904 0 : if( nParCount == 4 )
1905 : {
1906 0 : nFirstDay = rPar.Get(3)->GetInteger();
1907 0 : if( nFirstDay < 0 || nFirstDay > 7 )
1908 : {
1909 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1910 0 : return;
1911 : }
1912 : }
1913 0 : if( nFirstDay == 0 )
1914 : {
1915 0 : nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 );
1916 : }
1917 0 : nDay = 1 + (nDay + nDayCount + nFirstDay - 2) % nDayCount;
1918 0 : if( nDay < 1 || nDay > nDayCount )
1919 : {
1920 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1921 0 : return;
1922 : }
1923 :
1924 0 : bool bAbbreviate = false;
1925 0 : if( nParCount >= 3 )
1926 : {
1927 0 : SbxVariable* pPar2 = rPar.Get(2);
1928 0 : if( !pPar2->IsErr() )
1929 : {
1930 0 : bAbbreviate = pPar2->GetBool();
1931 : }
1932 : }
1933 :
1934 0 : const CalendarItem2* pCalendarItems = aDaySeq.getConstArray();
1935 0 : const CalendarItem2& rItem = pCalendarItems[nDay - 1];
1936 :
1937 0 : OUString aRetStr = ( bAbbreviate ? rItem.AbbrevName : rItem.FullName );
1938 0 : rPar.Get(0)->PutString( aRetStr );
1939 : }
1940 :
1941 0 : RTLFUNC(Weekday)
1942 : {
1943 : (void)pBasic;
1944 : (void)bWrite;
1945 :
1946 0 : sal_uInt16 nParCount = rPar.Count();
1947 0 : if ( nParCount < 2 )
1948 : {
1949 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1950 : }
1951 : else
1952 : {
1953 0 : double aDate = rPar.Get(1)->GetDate();
1954 :
1955 0 : bool bFirstDay = false;
1956 0 : sal_Int16 nFirstDay = 0;
1957 0 : if ( nParCount > 2 )
1958 : {
1959 0 : nFirstDay = rPar.Get(2)->GetInteger();
1960 0 : bFirstDay = true;
1961 : }
1962 0 : sal_Int16 nDay = implGetWeekDay( aDate, bFirstDay, nFirstDay );
1963 0 : rPar.Get(0)->PutInteger( nDay );
1964 : }
1965 0 : }
1966 :
1967 :
1968 : enum Interval
1969 : {
1970 : INTERVAL_YYYY,
1971 : INTERVAL_Q,
1972 : INTERVAL_M,
1973 : INTERVAL_Y,
1974 : INTERVAL_D,
1975 : INTERVAL_W,
1976 : INTERVAL_WW,
1977 : INTERVAL_H,
1978 : INTERVAL_N,
1979 : INTERVAL_S
1980 : };
1981 :
1982 : struct IntervalInfo
1983 : {
1984 : Interval meInterval;
1985 : char const * mStringCode;
1986 : double mdValue;
1987 : bool mbSimple;
1988 : };
1989 :
1990 0 : IntervalInfo const * getIntervalInfo( const OUString& rStringCode )
1991 : {
1992 : static IntervalInfo const aIntervalTable[] =
1993 : {
1994 : { INTERVAL_YYYY, "yyyy", 0.0, false }, // Year
1995 : { INTERVAL_Q, "q", 0.0, false }, // Quarter
1996 : { INTERVAL_M, "m", 0.0, false }, // Month
1997 : { INTERVAL_Y, "y", 1.0, true }, // Day of year
1998 : { INTERVAL_D, "d", 1.0, true }, // Day
1999 : { INTERVAL_W, "w", 1.0, true }, // Weekday
2000 : { INTERVAL_WW, "ww", 7.0, true }, // Week
2001 : { INTERVAL_H, "h", 1.0 / 24.0, true }, // Hour
2002 : { INTERVAL_N, "n", 1.0 / 1440.0, true }, // Minute
2003 : { INTERVAL_S, "s", 1.0 / 86400.0, true } // Second
2004 : };
2005 0 : for( std::size_t i = 0; i != SAL_N_ELEMENTS(aIntervalTable); ++i )
2006 : {
2007 0 : if( rStringCode.equalsIgnoreAsciiCaseAscii(
2008 0 : aIntervalTable[i].mStringCode ) )
2009 : {
2010 0 : return &aIntervalTable[i];
2011 : }
2012 : }
2013 0 : return NULL;
2014 : }
2015 :
2016 0 : inline void implGetDayMonthYear( sal_Int16& rnYear, sal_Int16& rnMonth, sal_Int16& rnDay, double dDate )
2017 : {
2018 0 : rnDay = implGetDateDay( dDate );
2019 0 : rnMonth = implGetDateMonth( dDate );
2020 0 : rnYear = implGetDateYear( dDate );
2021 0 : }
2022 :
2023 0 : inline sal_Int16 limitToINT16( sal_Int32 n32 )
2024 : {
2025 0 : if( n32 > 32767 )
2026 : {
2027 0 : n32 = 32767;
2028 : }
2029 0 : else if( n32 < -32768 )
2030 : {
2031 0 : n32 = -32768;
2032 : }
2033 0 : return (sal_Int16)n32;
2034 : }
2035 :
2036 0 : RTLFUNC(DateAdd)
2037 : {
2038 : (void)pBasic;
2039 : (void)bWrite;
2040 :
2041 0 : sal_uInt16 nParCount = rPar.Count();
2042 0 : if( nParCount != 4 )
2043 : {
2044 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2045 0 : return;
2046 : }
2047 :
2048 0 : OUString aStringCode = rPar.Get(1)->GetOUString();
2049 0 : IntervalInfo const * pInfo = getIntervalInfo( aStringCode );
2050 0 : if( !pInfo )
2051 : {
2052 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2053 0 : return;
2054 : }
2055 :
2056 0 : sal_Int32 lNumber = rPar.Get(2)->GetLong();
2057 0 : double dDate = rPar.Get(3)->GetDate();
2058 0 : double dNewDate = 0;
2059 0 : if( pInfo->mbSimple )
2060 : {
2061 0 : double dAdd = pInfo->mdValue * lNumber;
2062 0 : dNewDate = dDate + dAdd;
2063 : }
2064 : else
2065 : {
2066 : // Keep hours, minutes, seconds
2067 0 : double dHoursMinutesSeconds = dDate - floor( dDate );
2068 :
2069 0 : bool bOk = true;
2070 : sal_Int16 nYear, nMonth, nDay;
2071 0 : sal_Int16 nTargetYear16 = 0, nTargetMonth = 0;
2072 0 : implGetDayMonthYear( nYear, nMonth, nDay, dDate );
2073 0 : switch( pInfo->meInterval )
2074 : {
2075 : case INTERVAL_YYYY:
2076 : {
2077 0 : sal_Int32 nTargetYear = lNumber + nYear;
2078 0 : nTargetYear16 = limitToINT16( nTargetYear );
2079 0 : nTargetMonth = nMonth;
2080 0 : bOk = implDateSerial( nTargetYear16, nTargetMonth, nDay, dNewDate );
2081 0 : break;
2082 : }
2083 : case INTERVAL_Q:
2084 : case INTERVAL_M:
2085 : {
2086 0 : bool bNeg = (lNumber < 0);
2087 0 : if( bNeg )
2088 0 : lNumber = -lNumber;
2089 : sal_Int32 nYearsAdd;
2090 : sal_Int16 nMonthAdd;
2091 0 : if( pInfo->meInterval == INTERVAL_Q )
2092 : {
2093 0 : nYearsAdd = lNumber / 4;
2094 0 : nMonthAdd = (sal_Int16)( 3 * (lNumber % 4) );
2095 : }
2096 : else
2097 : {
2098 0 : nYearsAdd = lNumber / 12;
2099 0 : nMonthAdd = (sal_Int16)( lNumber % 12 );
2100 : }
2101 :
2102 : sal_Int32 nTargetYear;
2103 0 : if( bNeg )
2104 : {
2105 0 : nTargetMonth = nMonth - nMonthAdd;
2106 0 : if( nTargetMonth <= 0 )
2107 : {
2108 0 : nTargetMonth += 12;
2109 0 : nYearsAdd++;
2110 : }
2111 0 : nTargetYear = (sal_Int32)nYear - nYearsAdd;
2112 : }
2113 : else
2114 : {
2115 0 : nTargetMonth = nMonth + nMonthAdd;
2116 0 : if( nTargetMonth > 12 )
2117 : {
2118 0 : nTargetMonth -= 12;
2119 0 : nYearsAdd++;
2120 : }
2121 0 : nTargetYear = (sal_Int32)nYear + nYearsAdd;
2122 : }
2123 0 : nTargetYear16 = limitToINT16( nTargetYear );
2124 0 : bOk = implDateSerial( nTargetYear16, nTargetMonth, nDay, dNewDate );
2125 0 : break;
2126 : }
2127 0 : default: break;
2128 : }
2129 :
2130 0 : if( bOk )
2131 : {
2132 : // Overflow?
2133 : sal_Int16 nNewYear, nNewMonth, nNewDay;
2134 0 : implGetDayMonthYear( nNewYear, nNewMonth, nNewDay, dNewDate );
2135 0 : if( nNewYear > 9999 || nNewYear < 100 )
2136 : {
2137 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2138 0 : return;
2139 : }
2140 0 : sal_Int16 nCorrectionDay = nDay;
2141 0 : while( nNewMonth > nTargetMonth )
2142 : {
2143 0 : nCorrectionDay--;
2144 0 : implDateSerial( nTargetYear16, nTargetMonth, nCorrectionDay, dNewDate );
2145 0 : implGetDayMonthYear( nNewYear, nNewMonth, nNewDay, dNewDate );
2146 : }
2147 0 : dNewDate += dHoursMinutesSeconds;
2148 : }
2149 : }
2150 :
2151 0 : rPar.Get(0)->PutDate( dNewDate );
2152 : }
2153 :
2154 0 : inline double RoundImpl( double d )
2155 : {
2156 0 : return ( d >= 0 ) ? floor( d + 0.5 ) : -floor( -d + 0.5 );
2157 : }
2158 :
2159 0 : RTLFUNC(DateDiff)
2160 : {
2161 : (void)pBasic;
2162 : (void)bWrite;
2163 :
2164 : // DateDiff(interval, date1, date2[, firstdayofweek[, firstweekofyear]])
2165 :
2166 0 : sal_uInt16 nParCount = rPar.Count();
2167 0 : if( nParCount < 4 || nParCount > 6 )
2168 : {
2169 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2170 0 : return;
2171 : }
2172 :
2173 0 : OUString aStringCode = rPar.Get(1)->GetOUString();
2174 0 : IntervalInfo const * pInfo = getIntervalInfo( aStringCode );
2175 0 : if( !pInfo )
2176 : {
2177 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2178 0 : return;
2179 : }
2180 :
2181 0 : double dDate1 = rPar.Get(2)->GetDate();
2182 0 : double dDate2 = rPar.Get(3)->GetDate();
2183 :
2184 0 : double dRet = 0.0;
2185 0 : switch( pInfo->meInterval )
2186 : {
2187 : case INTERVAL_YYYY:
2188 : {
2189 0 : sal_Int16 nYear1 = implGetDateYear( dDate1 );
2190 0 : sal_Int16 nYear2 = implGetDateYear( dDate2 );
2191 0 : dRet = nYear2 - nYear1;
2192 0 : break;
2193 : }
2194 : case INTERVAL_Q:
2195 : {
2196 0 : sal_Int16 nYear1 = implGetDateYear( dDate1 );
2197 0 : sal_Int16 nYear2 = implGetDateYear( dDate2 );
2198 0 : sal_Int16 nQ1 = 1 + (implGetDateMonth( dDate1 ) - 1) / 3;
2199 0 : sal_Int16 nQ2 = 1 + (implGetDateMonth( dDate2 ) - 1) / 3;
2200 0 : sal_Int16 nQGes1 = 4 * nYear1 + nQ1;
2201 0 : sal_Int16 nQGes2 = 4 * nYear2 + nQ2;
2202 0 : dRet = nQGes2 - nQGes1;
2203 0 : break;
2204 : }
2205 : case INTERVAL_M:
2206 : {
2207 0 : sal_Int16 nYear1 = implGetDateYear( dDate1 );
2208 0 : sal_Int16 nYear2 = implGetDateYear( dDate2 );
2209 0 : sal_Int16 nMonth1 = implGetDateMonth( dDate1 );
2210 0 : sal_Int16 nMonth2 = implGetDateMonth( dDate2 );
2211 0 : sal_Int16 nMonthGes1 = 12 * nYear1 + nMonth1;
2212 0 : sal_Int16 nMonthGes2 = 12 * nYear2 + nMonth2;
2213 0 : dRet = nMonthGes2 - nMonthGes1;
2214 0 : break;
2215 : }
2216 : case INTERVAL_Y:
2217 : case INTERVAL_D:
2218 : {
2219 0 : double dDays1 = floor( dDate1 );
2220 0 : double dDays2 = floor( dDate2 );
2221 0 : dRet = dDays2 - dDays1;
2222 0 : break;
2223 : }
2224 : case INTERVAL_W:
2225 : case INTERVAL_WW:
2226 : {
2227 0 : double dDays1 = floor( dDate1 );
2228 0 : double dDays2 = floor( dDate2 );
2229 0 : if( pInfo->meInterval == INTERVAL_WW )
2230 : {
2231 0 : sal_Int16 nFirstDay = 1; // Default
2232 0 : if( nParCount >= 5 )
2233 : {
2234 0 : nFirstDay = rPar.Get(4)->GetInteger();
2235 0 : if( nFirstDay < 0 || nFirstDay > 7 )
2236 : {
2237 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2238 0 : return;
2239 : }
2240 0 : if( nFirstDay == 0 )
2241 : {
2242 0 : Reference< XCalendar3 > xCalendar = getLocaleCalendar();
2243 0 : if( !xCalendar.is() )
2244 : {
2245 0 : StarBASIC::Error( SbERR_INTERNAL_ERROR );
2246 0 : return;
2247 : }
2248 0 : nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 );
2249 : }
2250 : }
2251 0 : sal_Int16 nDay1 = implGetWeekDay( dDate1 );
2252 0 : sal_Int16 nDay1_Diff = nDay1 - nFirstDay;
2253 0 : if( nDay1_Diff < 0 )
2254 0 : nDay1_Diff += 7;
2255 0 : dDays1 -= nDay1_Diff;
2256 :
2257 0 : sal_Int16 nDay2 = implGetWeekDay( dDate2 );
2258 0 : sal_Int16 nDay2_Diff = nDay2 - nFirstDay;
2259 0 : if( nDay2_Diff < 0 )
2260 0 : nDay2_Diff += 7;
2261 0 : dDays2 -= nDay2_Diff;
2262 : }
2263 :
2264 0 : double dDiff = dDays2 - dDays1;
2265 0 : dRet = ( dDiff >= 0 ) ? floor( dDiff / 7.0 ) : -floor( -dDiff / 7.0 );
2266 0 : break;
2267 : }
2268 : case INTERVAL_H:
2269 : {
2270 0 : double dFactor = 24.0;
2271 0 : dRet = RoundImpl( dFactor * (dDate2 - dDate1) );
2272 0 : break;
2273 : }
2274 : case INTERVAL_N:
2275 : {
2276 0 : double dFactor =1440.0;
2277 0 : dRet = RoundImpl( dFactor * (dDate2 - dDate1) );
2278 0 : break;
2279 : }
2280 : case INTERVAL_S:
2281 : {
2282 0 : double dFactor = 86400.0;
2283 0 : dRet = RoundImpl( dFactor * (dDate2 - dDate1) );
2284 0 : break;
2285 : }
2286 : }
2287 0 : rPar.Get(0)->PutDouble( dRet );
2288 : }
2289 :
2290 0 : double implGetDateOfFirstDayInFirstWeek
2291 : ( sal_Int16 nYear, sal_Int16& nFirstDay, sal_Int16& nFirstWeek, bool* pbError = NULL )
2292 : {
2293 0 : SbError nError = 0;
2294 0 : if( nFirstDay < 0 || nFirstDay > 7 )
2295 0 : nError = SbERR_BAD_ARGUMENT;
2296 :
2297 0 : if( nFirstWeek < 0 || nFirstWeek > 3 )
2298 0 : nError = SbERR_BAD_ARGUMENT;
2299 :
2300 0 : Reference< XCalendar3 > xCalendar;
2301 0 : if( nFirstDay == 0 || nFirstWeek == 0 )
2302 : {
2303 0 : xCalendar = getLocaleCalendar();
2304 0 : if( !xCalendar.is() )
2305 0 : nError = SbERR_BAD_ARGUMENT;
2306 : }
2307 :
2308 0 : if( nError != 0 )
2309 : {
2310 0 : StarBASIC::Error( nError );
2311 0 : if( pbError )
2312 0 : *pbError = true;
2313 0 : return 0.0;
2314 : }
2315 :
2316 0 : if( nFirstDay == 0 )
2317 0 : nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 );
2318 :
2319 0 : sal_Int16 nFirstWeekMinDays = 0; // Not used for vbFirstJan1 = default
2320 0 : if( nFirstWeek == 0 )
2321 : {
2322 0 : nFirstWeekMinDays = xCalendar->getMinimumNumberOfDaysForFirstWeek();
2323 0 : if( nFirstWeekMinDays == 1 )
2324 : {
2325 0 : nFirstWeekMinDays = 0;
2326 0 : nFirstWeek = 1;
2327 : }
2328 0 : else if( nFirstWeekMinDays == 4 )
2329 0 : nFirstWeek = 2;
2330 0 : else if( nFirstWeekMinDays == 7 )
2331 0 : nFirstWeek = 3;
2332 : }
2333 0 : else if( nFirstWeek == 2 )
2334 0 : nFirstWeekMinDays = 4; // vbFirstFourDays
2335 0 : else if( nFirstWeek == 3 )
2336 0 : nFirstWeekMinDays = 7; // vbFirstFourDays
2337 :
2338 : double dBaseDate;
2339 0 : implDateSerial( nYear, 1, 1, dBaseDate );
2340 0 : double dRetDate = dBaseDate;
2341 :
2342 0 : sal_Int16 nWeekDay0101 = implGetWeekDay( dBaseDate );
2343 0 : sal_Int16 nDayDiff = nWeekDay0101 - nFirstDay;
2344 0 : if( nDayDiff < 0 )
2345 0 : nDayDiff += 7;
2346 :
2347 0 : if( nFirstWeekMinDays )
2348 : {
2349 0 : sal_Int16 nThisWeeksDaysInYearCount = 7 - nDayDiff;
2350 0 : if( nThisWeeksDaysInYearCount < nFirstWeekMinDays )
2351 0 : nDayDiff -= 7;
2352 : }
2353 0 : dRetDate = dBaseDate - nDayDiff;
2354 0 : return dRetDate;
2355 : }
2356 :
2357 0 : RTLFUNC(DatePart)
2358 : {
2359 : (void)pBasic;
2360 : (void)bWrite;
2361 :
2362 : // DatePart(interval, date[,firstdayofweek[, firstweekofyear]])
2363 :
2364 0 : sal_uInt16 nParCount = rPar.Count();
2365 0 : if( nParCount < 3 || nParCount > 5 )
2366 : {
2367 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2368 0 : return;
2369 : }
2370 :
2371 0 : OUString aStringCode = rPar.Get(1)->GetOUString();
2372 0 : IntervalInfo const * pInfo = getIntervalInfo( aStringCode );
2373 0 : if( !pInfo )
2374 : {
2375 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2376 0 : return;
2377 : }
2378 :
2379 0 : double dDate = rPar.Get(2)->GetDate();
2380 :
2381 0 : sal_Int32 nRet = 0;
2382 0 : switch( pInfo->meInterval )
2383 : {
2384 : case INTERVAL_YYYY:
2385 : {
2386 0 : nRet = implGetDateYear( dDate );
2387 0 : break;
2388 : }
2389 : case INTERVAL_Q:
2390 : {
2391 0 : nRet = 1 + (implGetDateMonth( dDate ) - 1) / 3;
2392 0 : break;
2393 : }
2394 : case INTERVAL_M:
2395 : {
2396 0 : nRet = implGetDateMonth( dDate );
2397 0 : break;
2398 : }
2399 : case INTERVAL_Y:
2400 : {
2401 0 : sal_Int16 nYear = implGetDateYear( dDate );
2402 : double dBaseDate;
2403 0 : implDateSerial( nYear, 1, 1, dBaseDate );
2404 0 : nRet = 1 + sal_Int32( dDate - dBaseDate );
2405 0 : break;
2406 : }
2407 : case INTERVAL_D:
2408 : {
2409 0 : nRet = implGetDateDay( dDate );
2410 0 : break;
2411 : }
2412 : case INTERVAL_W:
2413 : {
2414 0 : bool bFirstDay = false;
2415 0 : sal_Int16 nFirstDay = 1; // Default
2416 0 : if( nParCount >= 4 )
2417 : {
2418 0 : nFirstDay = rPar.Get(3)->GetInteger();
2419 0 : bFirstDay = true;
2420 : }
2421 0 : nRet = implGetWeekDay( dDate, bFirstDay, nFirstDay );
2422 0 : break;
2423 : }
2424 : case INTERVAL_WW:
2425 : {
2426 0 : sal_Int16 nFirstDay = 1; // Default
2427 0 : if( nParCount >= 4 )
2428 0 : nFirstDay = rPar.Get(3)->GetInteger();
2429 :
2430 0 : sal_Int16 nFirstWeek = 1; // Default
2431 0 : if( nParCount == 5 )
2432 0 : nFirstWeek = rPar.Get(4)->GetInteger();
2433 :
2434 0 : sal_Int16 nYear = implGetDateYear( dDate );
2435 0 : bool bError = false;
2436 0 : double dYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear, nFirstDay, nFirstWeek, &bError );
2437 0 : if( !bError )
2438 : {
2439 0 : if( dYearFirstDay > dDate )
2440 : {
2441 : // Date belongs to last year's week
2442 0 : dYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear - 1, nFirstDay, nFirstWeek );
2443 : }
2444 0 : else if( nFirstWeek != 1 )
2445 : {
2446 : // Check if date belongs to next year
2447 0 : double dNextYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear + 1, nFirstDay, nFirstWeek );
2448 0 : if( dDate >= dNextYearFirstDay )
2449 0 : dYearFirstDay = dNextYearFirstDay;
2450 : }
2451 :
2452 : // Calculate week
2453 0 : double dDiff = dDate - dYearFirstDay;
2454 0 : nRet = 1 + sal_Int32( dDiff / 7 );
2455 : }
2456 0 : break;
2457 : }
2458 : case INTERVAL_H:
2459 : {
2460 0 : nRet = implGetHour( dDate );
2461 0 : break;
2462 : }
2463 : case INTERVAL_N:
2464 : {
2465 0 : nRet = implGetMinute( dDate );
2466 0 : break;
2467 : }
2468 : case INTERVAL_S:
2469 : {
2470 0 : nRet = implGetSecond( dDate );
2471 0 : break;
2472 : }
2473 : }
2474 0 : rPar.Get(0)->PutLong( nRet );
2475 : }
2476 :
2477 : // FormatDateTime(Date[,NamedFormat])
2478 0 : RTLFUNC(FormatDateTime)
2479 : {
2480 : (void)pBasic;
2481 : (void)bWrite;
2482 :
2483 0 : sal_uInt16 nParCount = rPar.Count();
2484 0 : if( nParCount < 2 || nParCount > 3 )
2485 : {
2486 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2487 0 : return;
2488 : }
2489 :
2490 0 : double dDate = rPar.Get(1)->GetDate();
2491 0 : sal_Int16 nNamedFormat = 0;
2492 0 : if( nParCount > 2 )
2493 : {
2494 0 : nNamedFormat = rPar.Get(2)->GetInteger();
2495 0 : if( nNamedFormat < 0 || nNamedFormat > 4 )
2496 : {
2497 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2498 0 : return;
2499 : }
2500 : }
2501 :
2502 0 : Reference< XCalendar3 > xCalendar = getLocaleCalendar();
2503 0 : if( !xCalendar.is() )
2504 : {
2505 0 : StarBASIC::Error( SbERR_INTERNAL_ERROR );
2506 0 : return;
2507 : }
2508 :
2509 0 : OUString aRetStr;
2510 0 : SbxVariableRef pSbxVar = new SbxVariable( SbxSTRING );
2511 0 : switch( nNamedFormat )
2512 : {
2513 : // GeneralDate:
2514 : // Display a date and/or time. If there is a date part,
2515 : // display it as a short date. If there is a time part,
2516 : // display it as a long time. If present, both parts are displayed.
2517 :
2518 : // 12/21/2004 11:24:50 AM
2519 : // 21.12.2004 12:13:51
2520 : case 0:
2521 0 : pSbxVar->PutDate( dDate );
2522 0 : aRetStr = pSbxVar->GetOUString();
2523 0 : break;
2524 :
2525 : // LongDate: Display a date using the long date format specified
2526 : // in your computer's regional settings.
2527 : // Tuesday, December 21, 2004
2528 : // Dienstag, 21. December 2004
2529 : case 1:
2530 : {
2531 0 : SvNumberFormatter* pFormatter = NULL;
2532 0 : if( GetSbData()->pInst )
2533 : {
2534 0 : pFormatter = GetSbData()->pInst->GetNumberFormatter();
2535 : }
2536 : else
2537 : {
2538 : sal_uInt32 n; // Dummy
2539 0 : SbiInstance::PrepareNumberFormatter( pFormatter, n, n, n );
2540 : }
2541 :
2542 0 : LanguageType eLangType = GetpApp()->GetSettings().GetLanguageTag().getLanguageType();
2543 0 : sal_uIntPtr nIndex = pFormatter->GetFormatIndex( NF_DATE_SYSTEM_LONG, eLangType );
2544 : Color* pCol;
2545 0 : pFormatter->GetOutputString( dDate, nIndex, aRetStr, &pCol );
2546 :
2547 0 : if( !GetSbData()->pInst )
2548 : {
2549 0 : delete pFormatter;
2550 : }
2551 0 : break;
2552 : }
2553 :
2554 : // ShortDate: Display a date using the short date format specified
2555 : // in your computer's regional settings.
2556 : // 21.12.2004
2557 : case 2:
2558 0 : pSbxVar->PutDate( floor(dDate) );
2559 0 : aRetStr = pSbxVar->GetOUString();
2560 0 : break;
2561 :
2562 : // LongTime: Display a time using the time format specified
2563 : // in your computer's regional settings.
2564 : // 11:24:50 AM
2565 : // 12:13:51
2566 : case 3:
2567 : // ShortTime: Display a time using the 24-hour format (hh:mm).
2568 : // 11:24
2569 : case 4:
2570 : double n;
2571 0 : double dTime = modf( dDate, &n );
2572 0 : pSbxVar->PutDate( dTime );
2573 0 : if( nNamedFormat == 3 )
2574 : {
2575 0 : aRetStr = pSbxVar->GetOUString();
2576 : }
2577 : else
2578 : {
2579 0 : aRetStr = pSbxVar->GetOUString().copy( 0, 5 );
2580 : }
2581 0 : break;
2582 : }
2583 :
2584 0 : rPar.Get(0)->PutString( aRetStr );
2585 : }
2586 :
2587 0 : RTLFUNC(Frac)
2588 : {
2589 : (void)pBasic;
2590 : (void)bWrite;
2591 :
2592 0 : sal_uInt16 nParCount = rPar.Count();
2593 0 : if( nParCount != 2)
2594 : {
2595 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2596 0 : return;
2597 : }
2598 :
2599 0 : SbxVariable *pSbxVariable = rPar.Get(1);
2600 0 : double dVal = pSbxVariable->GetDouble();
2601 0 : if(dVal >= 0)
2602 0 : rPar.Get(0)->PutDouble(dVal - ::rtl::math::approxFloor(dVal));
2603 : else
2604 0 : rPar.Get(0)->PutDouble(dVal - ::rtl::math::approxCeil(dVal));
2605 : }
2606 :
2607 0 : RTLFUNC(Round)
2608 : {
2609 : (void)pBasic;
2610 : (void)bWrite;
2611 :
2612 0 : sal_uInt16 nParCount = rPar.Count();
2613 0 : if( nParCount != 2 && nParCount != 3 )
2614 : {
2615 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2616 0 : return;
2617 : }
2618 :
2619 0 : SbxVariable *pSbxVariable = rPar.Get(1);
2620 0 : double dVal = pSbxVariable->GetDouble();
2621 0 : double dRes = 0.0;
2622 0 : if( dVal != 0.0 )
2623 : {
2624 0 : bool bNeg = false;
2625 0 : if( dVal < 0.0 )
2626 : {
2627 0 : bNeg = true;
2628 0 : dVal = -dVal;
2629 : }
2630 :
2631 0 : sal_Int16 numdecimalplaces = 0;
2632 0 : if( nParCount == 3 )
2633 : {
2634 0 : numdecimalplaces = rPar.Get(2)->GetInteger();
2635 0 : if( numdecimalplaces < 0 || numdecimalplaces > 22 )
2636 : {
2637 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2638 0 : return;
2639 : }
2640 : }
2641 :
2642 0 : if( numdecimalplaces == 0 )
2643 : {
2644 0 : dRes = floor( dVal + 0.5 );
2645 : }
2646 : else
2647 : {
2648 0 : double dFactor = pow( 10.0, numdecimalplaces );
2649 0 : dVal *= dFactor;
2650 0 : dRes = floor( dVal + 0.5 );
2651 0 : dRes /= dFactor;
2652 : }
2653 :
2654 0 : if( bNeg )
2655 0 : dRes = -dRes;
2656 : }
2657 0 : rPar.Get(0)->PutDouble( dRes );
2658 : }
2659 :
2660 0 : void CallFunctionAccessFunction( const Sequence< Any >& aArgs, const OUString& sFuncName, SbxVariable* pRet )
2661 : {
2662 0 : static Reference< XFunctionAccess > xFunc;
2663 : try
2664 : {
2665 0 : if ( !xFunc.is() )
2666 : {
2667 0 : Reference< XMultiServiceFactory > xFactory( getProcessServiceFactory() );
2668 0 : if( xFactory.is() )
2669 : {
2670 0 : xFunc.set( xFactory->createInstance("com.sun.star.sheet.FunctionAccess"), UNO_QUERY_THROW);
2671 0 : }
2672 : }
2673 0 : Any aRet = xFunc->callFunction( sFuncName, aArgs );
2674 :
2675 0 : unoToSbxValue( pRet, aRet );
2676 :
2677 : }
2678 0 : catch(const Exception& )
2679 : {
2680 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2681 : }
2682 0 : }
2683 :
2684 0 : RTLFUNC(SYD)
2685 : {
2686 : (void)pBasic;
2687 : (void)bWrite;
2688 :
2689 0 : sal_uLong nArgCount = rPar.Count()-1;
2690 :
2691 0 : if ( nArgCount < 4 )
2692 : {
2693 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2694 0 : return;
2695 : }
2696 :
2697 : // retrieve non-optional params
2698 :
2699 0 : Sequence< Any > aParams( 4 );
2700 0 : aParams[ 0 ] <<= makeAny( rPar.Get(1)->GetDouble() );
2701 0 : aParams[ 1 ] <<= makeAny( rPar.Get(2)->GetDouble() );
2702 0 : aParams[ 2 ] <<= makeAny( rPar.Get(3)->GetDouble() );
2703 0 : aParams[ 3 ] <<= makeAny( rPar.Get(4)->GetDouble() );
2704 :
2705 0 : CallFunctionAccessFunction( aParams, "SYD", rPar.Get( 0 ) );
2706 : }
2707 :
2708 0 : RTLFUNC(SLN)
2709 : {
2710 : (void)pBasic;
2711 : (void)bWrite;
2712 :
2713 0 : sal_uLong nArgCount = rPar.Count()-1;
2714 :
2715 0 : if ( nArgCount < 3 )
2716 : {
2717 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2718 0 : return;
2719 : }
2720 :
2721 : // retrieve non-optional params
2722 :
2723 0 : Sequence< Any > aParams( 3 );
2724 0 : aParams[ 0 ] <<= makeAny( rPar.Get(1)->GetDouble() );
2725 0 : aParams[ 1 ] <<= makeAny( rPar.Get(2)->GetDouble() );
2726 0 : aParams[ 2 ] <<= makeAny( rPar.Get(3)->GetDouble() );
2727 :
2728 0 : CallFunctionAccessFunction( aParams, "SLN", rPar.Get( 0 ) );
2729 : }
2730 :
2731 0 : RTLFUNC(Pmt)
2732 : {
2733 : (void)pBasic;
2734 : (void)bWrite;
2735 :
2736 0 : sal_uLong nArgCount = rPar.Count()-1;
2737 :
2738 0 : if ( nArgCount < 3 || nArgCount > 5 )
2739 : {
2740 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2741 0 : return;
2742 : }
2743 : // retrieve non-optional params
2744 :
2745 0 : double rate = rPar.Get(1)->GetDouble();
2746 0 : double nper = rPar.Get(2)->GetDouble();
2747 0 : double pmt = rPar.Get(3)->GetDouble();
2748 :
2749 : // set default values for Optional args
2750 0 : double fv = 0;
2751 0 : double type = 0;
2752 :
2753 : // fv
2754 0 : if ( nArgCount >= 4 )
2755 : {
2756 0 : if( rPar.Get(4)->GetType() != SbxEMPTY )
2757 0 : fv = rPar.Get(4)->GetDouble();
2758 : }
2759 : // type
2760 0 : if ( nArgCount >= 5 )
2761 : {
2762 0 : if( rPar.Get(5)->GetType() != SbxEMPTY )
2763 0 : type = rPar.Get(5)->GetDouble();
2764 : }
2765 :
2766 0 : Sequence< Any > aParams( 5 );
2767 0 : aParams[ 0 ] <<= rate;
2768 0 : aParams[ 1 ] <<= nper;
2769 0 : aParams[ 2 ] <<= pmt;
2770 0 : aParams[ 3 ] <<= fv;
2771 0 : aParams[ 4 ] <<= type;
2772 :
2773 0 : CallFunctionAccessFunction( aParams, "Pmt", rPar.Get( 0 ) );
2774 : }
2775 :
2776 0 : RTLFUNC(PPmt)
2777 : {
2778 : (void)pBasic;
2779 : (void)bWrite;
2780 :
2781 0 : sal_uLong nArgCount = rPar.Count()-1;
2782 :
2783 0 : if ( nArgCount < 4 || nArgCount > 6 )
2784 : {
2785 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2786 0 : return;
2787 : }
2788 : // retrieve non-optional params
2789 :
2790 0 : double rate = rPar.Get(1)->GetDouble();
2791 0 : double per = rPar.Get(2)->GetDouble();
2792 0 : double nper = rPar.Get(3)->GetDouble();
2793 0 : double pv = rPar.Get(4)->GetDouble();
2794 :
2795 : // set default values for Optional args
2796 0 : double fv = 0;
2797 0 : double type = 0;
2798 :
2799 : // fv
2800 0 : if ( nArgCount >= 5 )
2801 : {
2802 0 : if( rPar.Get(5)->GetType() != SbxEMPTY )
2803 0 : fv = rPar.Get(5)->GetDouble();
2804 : }
2805 : // type
2806 0 : if ( nArgCount >= 6 )
2807 : {
2808 0 : if( rPar.Get(6)->GetType() != SbxEMPTY )
2809 0 : type = rPar.Get(6)->GetDouble();
2810 : }
2811 :
2812 0 : Sequence< Any > aParams( 6 );
2813 0 : aParams[ 0 ] <<= rate;
2814 0 : aParams[ 1 ] <<= per;
2815 0 : aParams[ 2 ] <<= nper;
2816 0 : aParams[ 3 ] <<= pv;
2817 0 : aParams[ 4 ] <<= fv;
2818 0 : aParams[ 5 ] <<= type;
2819 :
2820 0 : CallFunctionAccessFunction( aParams, "PPmt", rPar.Get( 0 ) );
2821 : }
2822 :
2823 0 : RTLFUNC(PV)
2824 : {
2825 : (void)pBasic;
2826 : (void)bWrite;
2827 :
2828 0 : sal_uLong nArgCount = rPar.Count()-1;
2829 :
2830 0 : if ( nArgCount < 3 || nArgCount > 5 )
2831 : {
2832 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2833 0 : return;
2834 : }
2835 : // retrieve non-optional params
2836 :
2837 0 : double rate = rPar.Get(1)->GetDouble();
2838 0 : double nper = rPar.Get(2)->GetDouble();
2839 0 : double pmt = rPar.Get(3)->GetDouble();
2840 :
2841 : // set default values for Optional args
2842 0 : double fv = 0;
2843 0 : double type = 0;
2844 :
2845 : // fv
2846 0 : if ( nArgCount >= 4 )
2847 : {
2848 0 : if( rPar.Get(4)->GetType() != SbxEMPTY )
2849 0 : fv = rPar.Get(4)->GetDouble();
2850 : }
2851 : // type
2852 0 : if ( nArgCount >= 5 )
2853 : {
2854 0 : if( rPar.Get(5)->GetType() != SbxEMPTY )
2855 0 : type = rPar.Get(5)->GetDouble();
2856 : }
2857 :
2858 0 : Sequence< Any > aParams( 5 );
2859 0 : aParams[ 0 ] <<= rate;
2860 0 : aParams[ 1 ] <<= nper;
2861 0 : aParams[ 2 ] <<= pmt;
2862 0 : aParams[ 3 ] <<= fv;
2863 0 : aParams[ 4 ] <<= type;
2864 :
2865 0 : CallFunctionAccessFunction( aParams, "PV", rPar.Get( 0 ) );
2866 : }
2867 :
2868 0 : RTLFUNC(NPV)
2869 : {
2870 : (void)pBasic;
2871 : (void)bWrite;
2872 :
2873 0 : sal_uLong nArgCount = rPar.Count()-1;
2874 :
2875 0 : if ( nArgCount < 1 || nArgCount > 2 )
2876 : {
2877 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2878 0 : return;
2879 : }
2880 :
2881 0 : Sequence< Any > aParams( 2 );
2882 0 : aParams[ 0 ] <<= makeAny( rPar.Get(1)->GetDouble() );
2883 0 : Any aValues = sbxToUnoValue( rPar.Get(2),
2884 0 : getCppuType( (Sequence<double>*)0 ) );
2885 :
2886 : // convert for calc functions
2887 0 : Sequence< Sequence< double > > sValues(1);
2888 0 : aValues >>= sValues[ 0 ];
2889 0 : aValues <<= sValues;
2890 :
2891 0 : aParams[ 1 ] <<= aValues;
2892 :
2893 0 : CallFunctionAccessFunction( aParams, "NPV", rPar.Get( 0 ) );
2894 : }
2895 :
2896 0 : RTLFUNC(NPer)
2897 : {
2898 : (void)pBasic;
2899 : (void)bWrite;
2900 :
2901 0 : sal_uLong nArgCount = rPar.Count()-1;
2902 :
2903 0 : if ( nArgCount < 3 || nArgCount > 5 )
2904 : {
2905 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2906 0 : return;
2907 : }
2908 : // retrieve non-optional params
2909 :
2910 0 : double rate = rPar.Get(1)->GetDouble();
2911 0 : double pmt = rPar.Get(2)->GetDouble();
2912 0 : double pv = rPar.Get(3)->GetDouble();
2913 :
2914 : // set default values for Optional args
2915 0 : double fv = 0;
2916 0 : double type = 0;
2917 :
2918 : // fv
2919 0 : if ( nArgCount >= 4 )
2920 : {
2921 0 : if( rPar.Get(4)->GetType() != SbxEMPTY )
2922 0 : fv = rPar.Get(4)->GetDouble();
2923 : }
2924 : // type
2925 0 : if ( nArgCount >= 5 )
2926 : {
2927 0 : if( rPar.Get(5)->GetType() != SbxEMPTY )
2928 0 : type = rPar.Get(5)->GetDouble();
2929 : }
2930 :
2931 0 : Sequence< Any > aParams( 5 );
2932 0 : aParams[ 0 ] <<= rate;
2933 0 : aParams[ 1 ] <<= pmt;
2934 0 : aParams[ 2 ] <<= pv;
2935 0 : aParams[ 3 ] <<= fv;
2936 0 : aParams[ 4 ] <<= type;
2937 :
2938 0 : CallFunctionAccessFunction( aParams, "NPer", rPar.Get( 0 ) );
2939 : }
2940 :
2941 0 : RTLFUNC(MIRR)
2942 : {
2943 : (void)pBasic;
2944 : (void)bWrite;
2945 :
2946 0 : sal_uLong nArgCount = rPar.Count()-1;
2947 :
2948 0 : if ( nArgCount < 3 )
2949 : {
2950 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2951 0 : return;
2952 : }
2953 :
2954 : // retrieve non-optional params
2955 :
2956 0 : Sequence< Any > aParams( 3 );
2957 0 : Any aValues = sbxToUnoValue( rPar.Get(1),
2958 0 : getCppuType( (Sequence<double>*)0 ) );
2959 :
2960 : // convert for calc functions
2961 0 : Sequence< Sequence< double > > sValues(1);
2962 0 : aValues >>= sValues[ 0 ];
2963 0 : aValues <<= sValues;
2964 :
2965 0 : aParams[ 0 ] <<= aValues;
2966 0 : aParams[ 1 ] <<= makeAny( rPar.Get(2)->GetDouble() );
2967 0 : aParams[ 2 ] <<= makeAny( rPar.Get(3)->GetDouble() );
2968 :
2969 0 : CallFunctionAccessFunction( aParams, "MIRR", rPar.Get( 0 ) );
2970 : }
2971 :
2972 0 : RTLFUNC(IRR)
2973 : {
2974 : (void)pBasic;
2975 : (void)bWrite;
2976 :
2977 0 : sal_uLong nArgCount = rPar.Count()-1;
2978 :
2979 0 : if ( nArgCount < 1 || nArgCount > 2 )
2980 : {
2981 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2982 0 : return;
2983 : }
2984 : // retrieve non-optional params
2985 0 : Any aValues = sbxToUnoValue( rPar.Get(1),
2986 0 : getCppuType( (Sequence<double>*)0 ) );
2987 :
2988 : // convert for calc functions
2989 0 : Sequence< Sequence< double > > sValues(1);
2990 0 : aValues >>= sValues[ 0 ];
2991 0 : aValues <<= sValues;
2992 :
2993 : // set default values for Optional args
2994 0 : double guess = 0.1;
2995 : // guess
2996 0 : if ( nArgCount >= 2 )
2997 : {
2998 0 : if( rPar.Get(2)->GetType() != SbxEMPTY )
2999 0 : guess = rPar.Get(2)->GetDouble();
3000 : }
3001 :
3002 0 : Sequence< Any > aParams( 2 );
3003 0 : aParams[ 0 ] <<= aValues;
3004 0 : aParams[ 1 ] <<= guess;
3005 :
3006 0 : CallFunctionAccessFunction( aParams, "IRR", rPar.Get( 0 ) );
3007 : }
3008 :
3009 0 : RTLFUNC(IPmt)
3010 : {
3011 : (void)pBasic;
3012 : (void)bWrite;
3013 :
3014 0 : sal_uLong nArgCount = rPar.Count()-1;
3015 :
3016 0 : if ( nArgCount < 4 || nArgCount > 6 )
3017 : {
3018 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3019 0 : return;
3020 : }
3021 : // retrieve non-optional params
3022 :
3023 0 : double rate = rPar.Get(1)->GetDouble();
3024 0 : double per = rPar.Get(2)->GetInteger();
3025 0 : double nper = rPar.Get(3)->GetDouble();
3026 0 : double pv = rPar.Get(4)->GetDouble();
3027 :
3028 : // set default values for Optional args
3029 0 : double fv = 0;
3030 0 : double type = 0;
3031 :
3032 : // fv
3033 0 : if ( nArgCount >= 5 )
3034 : {
3035 0 : if( rPar.Get(5)->GetType() != SbxEMPTY )
3036 0 : fv = rPar.Get(5)->GetDouble();
3037 : }
3038 : // type
3039 0 : if ( nArgCount >= 6 )
3040 : {
3041 0 : if( rPar.Get(6)->GetType() != SbxEMPTY )
3042 0 : type = rPar.Get(6)->GetDouble();
3043 : }
3044 :
3045 0 : Sequence< Any > aParams( 6 );
3046 0 : aParams[ 0 ] <<= rate;
3047 0 : aParams[ 1 ] <<= per;
3048 0 : aParams[ 2 ] <<= nper;
3049 0 : aParams[ 3 ] <<= pv;
3050 0 : aParams[ 4 ] <<= fv;
3051 0 : aParams[ 5 ] <<= type;
3052 :
3053 0 : CallFunctionAccessFunction( aParams, "IPmt", rPar.Get( 0 ) );
3054 : }
3055 :
3056 0 : RTLFUNC(FV)
3057 : {
3058 : (void)pBasic;
3059 : (void)bWrite;
3060 :
3061 0 : sal_uLong nArgCount = rPar.Count()-1;
3062 :
3063 0 : if ( nArgCount < 3 || nArgCount > 5 )
3064 : {
3065 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3066 0 : return;
3067 : }
3068 : // retrieve non-optional params
3069 :
3070 0 : double rate = rPar.Get(1)->GetDouble();
3071 0 : double nper = rPar.Get(2)->GetDouble();
3072 0 : double pmt = rPar.Get(3)->GetDouble();
3073 :
3074 : // set default values for Optional args
3075 0 : double pv = 0;
3076 0 : double type = 0;
3077 :
3078 : // pv
3079 0 : if ( nArgCount >= 4 )
3080 : {
3081 0 : if( rPar.Get(4)->GetType() != SbxEMPTY )
3082 0 : pv = rPar.Get(4)->GetDouble();
3083 : }
3084 : // type
3085 0 : if ( nArgCount >= 5 )
3086 : {
3087 0 : if( rPar.Get(5)->GetType() != SbxEMPTY )
3088 0 : type = rPar.Get(5)->GetDouble();
3089 : }
3090 :
3091 0 : Sequence< Any > aParams( 5 );
3092 0 : aParams[ 0 ] <<= rate;
3093 0 : aParams[ 1 ] <<= nper;
3094 0 : aParams[ 2 ] <<= pmt;
3095 0 : aParams[ 3 ] <<= pv;
3096 0 : aParams[ 4 ] <<= type;
3097 :
3098 0 : CallFunctionAccessFunction( aParams, "FV", rPar.Get( 0 ) );
3099 : }
3100 :
3101 0 : RTLFUNC(DDB)
3102 : {
3103 : (void)pBasic;
3104 : (void)bWrite;
3105 :
3106 0 : sal_uLong nArgCount = rPar.Count()-1;
3107 :
3108 0 : if ( nArgCount < 4 || nArgCount > 5 )
3109 : {
3110 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3111 0 : return;
3112 : }
3113 : // retrieve non-optional params
3114 :
3115 0 : double cost = rPar.Get(1)->GetDouble();
3116 0 : double salvage = rPar.Get(2)->GetDouble();
3117 0 : double life = rPar.Get(3)->GetDouble();
3118 0 : double period = rPar.Get(4)->GetDouble();
3119 :
3120 : // set default values for Optional args
3121 0 : double factor = 2;
3122 :
3123 : // factor
3124 0 : if ( nArgCount >= 5 )
3125 : {
3126 0 : if( rPar.Get(5)->GetType() != SbxEMPTY )
3127 0 : factor = rPar.Get(5)->GetDouble();
3128 : }
3129 :
3130 0 : Sequence< Any > aParams( 5 );
3131 0 : aParams[ 0 ] <<= cost;
3132 0 : aParams[ 1 ] <<= salvage;
3133 0 : aParams[ 2 ] <<= life;
3134 0 : aParams[ 3 ] <<= period;
3135 0 : aParams[ 4 ] <<= factor;
3136 :
3137 0 : CallFunctionAccessFunction( aParams, "DDB", rPar.Get( 0 ) );
3138 : }
3139 :
3140 0 : RTLFUNC(Rate)
3141 : {
3142 : (void)pBasic;
3143 : (void)bWrite;
3144 :
3145 0 : sal_uLong nArgCount = rPar.Count()-1;
3146 :
3147 0 : if ( nArgCount < 3 || nArgCount > 6 )
3148 : {
3149 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3150 0 : return;
3151 : }
3152 : // retrieve non-optional params
3153 :
3154 0 : double nper = 0;
3155 0 : double pmt = 0;
3156 0 : double pv = 0;
3157 :
3158 0 : nper = rPar.Get(1)->GetDouble();
3159 0 : pmt = rPar.Get(2)->GetDouble();
3160 0 : pv = rPar.Get(3)->GetDouble();
3161 :
3162 : // set default values for Optional args
3163 0 : double fv = 0;
3164 0 : double type = 0;
3165 0 : double guess = 0.1;
3166 :
3167 : // fv
3168 0 : if ( nArgCount >= 4 )
3169 : {
3170 0 : if( rPar.Get(4)->GetType() != SbxEMPTY )
3171 0 : fv = rPar.Get(4)->GetDouble();
3172 : }
3173 :
3174 : // type
3175 0 : if ( nArgCount >= 5 )
3176 : {
3177 0 : if( rPar.Get(5)->GetType() != SbxEMPTY )
3178 0 : type = rPar.Get(5)->GetDouble();
3179 : }
3180 :
3181 : // guess
3182 0 : if ( nArgCount >= 6 )
3183 : {
3184 0 : if( rPar.Get(6)->GetType() != SbxEMPTY )
3185 0 : type = rPar.Get(6)->GetDouble();
3186 : }
3187 :
3188 0 : Sequence< Any > aParams( 6 );
3189 0 : aParams[ 0 ] <<= nper;
3190 0 : aParams[ 1 ] <<= pmt;
3191 0 : aParams[ 2 ] <<= pv;
3192 0 : aParams[ 3 ] <<= fv;
3193 0 : aParams[ 4 ] <<= type;
3194 0 : aParams[ 5 ] <<= guess;
3195 :
3196 0 : CallFunctionAccessFunction( aParams, "Rate", rPar.Get( 0 ) );
3197 : }
3198 :
3199 0 : RTLFUNC(StrReverse)
3200 : {
3201 : (void)pBasic;
3202 : (void)bWrite;
3203 :
3204 0 : if ( rPar.Count() != 2 )
3205 : {
3206 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3207 0 : return;
3208 : }
3209 :
3210 0 : SbxVariable *pSbxVariable = rPar.Get(1);
3211 0 : if( pSbxVariable->IsNull() )
3212 : {
3213 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3214 0 : return;
3215 : }
3216 :
3217 0 : OUString aStr = comphelper::string::reverseString(pSbxVariable->GetOUString());
3218 0 : rPar.Get(0)->PutString( aStr );
3219 : }
3220 :
3221 0 : RTLFUNC(CompatibilityMode)
3222 : {
3223 : (void)pBasic;
3224 : (void)bWrite;
3225 :
3226 0 : bool bEnabled = false;
3227 0 : sal_uInt16 nCount = rPar.Count();
3228 0 : if ( nCount != 1 && nCount != 2 )
3229 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3230 :
3231 0 : SbiInstance* pInst = GetSbData()->pInst;
3232 0 : if( pInst )
3233 : {
3234 0 : if ( nCount == 2 )
3235 : {
3236 0 : pInst->EnableCompatibility( rPar.Get(1)->GetBool() );
3237 : }
3238 0 : bEnabled = pInst->IsCompatibility();
3239 : }
3240 0 : rPar.Get(0)->PutBool( bEnabled );
3241 0 : }
3242 :
3243 0 : RTLFUNC(Input)
3244 : {
3245 : (void)pBasic;
3246 : (void)bWrite;
3247 :
3248 : // 2 parameters needed
3249 0 : if ( rPar.Count() < 3 )
3250 : {
3251 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3252 0 : return;
3253 : }
3254 :
3255 0 : sal_uInt16 nByteCount = rPar.Get(1)->GetUShort();
3256 0 : sal_Int16 nFileNumber = rPar.Get(2)->GetInteger();
3257 :
3258 0 : SbiIoSystem* pIosys = GetSbData()->pInst->GetIoSystem();
3259 0 : SbiStream* pSbStrm = pIosys->GetStream( nFileNumber );
3260 0 : if ( !pSbStrm || !(pSbStrm->GetMode() & (SBSTRM_BINARY | SBSTRM_INPUT)) )
3261 : {
3262 0 : StarBASIC::Error( SbERR_BAD_CHANNEL );
3263 0 : return;
3264 : }
3265 :
3266 0 : OString aByteBuffer;
3267 0 : SbError err = pSbStrm->Read( aByteBuffer, nByteCount, true );
3268 0 : if( !err )
3269 0 : err = pIosys->GetError();
3270 :
3271 0 : if( err )
3272 : {
3273 0 : StarBASIC::Error( err );
3274 0 : return;
3275 : }
3276 0 : rPar.Get(0)->PutString(OStringToOUString(aByteBuffer, osl_getThreadTextEncoding()));
3277 : }
3278 :
3279 0 : RTLFUNC(Me)
3280 : {
3281 : (void)pBasic;
3282 : (void)bWrite;
3283 :
3284 0 : SbModule* pActiveModule = GetSbData()->pInst->GetActiveModule();
3285 0 : SbClassModuleObject* pClassModuleObject = PTR_CAST(SbClassModuleObject,pActiveModule);
3286 0 : SbxVariableRef refVar = rPar.Get(0);
3287 0 : if( pClassModuleObject == NULL )
3288 : {
3289 0 : SbObjModule* pMod = PTR_CAST(SbObjModule,pActiveModule);
3290 0 : if ( pMod )
3291 0 : refVar->PutObject( pMod );
3292 : else
3293 0 : StarBASIC::Error( SbERR_INVALID_USAGE_OBJECT );
3294 : }
3295 : else
3296 0 : refVar->PutObject( pClassModuleObject );
3297 0 : }
3298 :
3299 : #endif
3300 :
3301 0 : sal_Int16 implGetWeekDay( double aDate, bool bFirstDayParam, sal_Int16 nFirstDay )
3302 : {
3303 0 : Date aRefDate( 1,1,1900 );
3304 0 : long nDays = (long) aDate;
3305 0 : nDays -= 2; // normalize: 1.1.1900 => 0
3306 0 : aRefDate += nDays;
3307 0 : DayOfWeek aDay = aRefDate.GetDayOfWeek();
3308 : sal_Int16 nDay;
3309 0 : if ( aDay != SUNDAY )
3310 0 : nDay = (sal_Int16)aDay + 2;
3311 : else
3312 0 : nDay = 1; // 1 == Sunday
3313 :
3314 : // #117253 optional 2nd parameter "firstdayofweek"
3315 0 : if( bFirstDayParam )
3316 : {
3317 0 : if( nFirstDay < 0 || nFirstDay > 7 )
3318 : {
3319 : #ifndef DISABLE_SCRIPTING
3320 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3321 : #endif
3322 0 : return 0;
3323 : }
3324 0 : if( nFirstDay == 0 )
3325 : {
3326 0 : Reference< XCalendar3 > xCalendar = getLocaleCalendar();
3327 0 : if( !xCalendar.is() )
3328 : {
3329 : #ifndef DISABLE_SCRIPTING
3330 0 : StarBASIC::Error( SbERR_INTERNAL_ERROR );
3331 : #endif
3332 0 : return 0;
3333 : }
3334 0 : nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 );
3335 : }
3336 0 : nDay = 1 + (nDay + 7 - nFirstDay) % 7;
3337 : }
3338 0 : return nDay;
3339 : }
3340 :
3341 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|