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> // getenv
25 : #include <vcl/svapp.hxx>
26 : #include <vcl/mapmod.hxx>
27 : #include <vcl/wrkwin.hxx>
28 : #include <vcl/timer.hxx>
29 : #include <basic/sbxvar.hxx>
30 : #include <basic/sbx.hxx>
31 : #include <svl/zforlist.hxx>
32 : #include <tools/urlobj.hxx>
33 : #include <osl/file.hxx>
34 : #include <vcl/jobset.hxx>
35 : #include <basic/sbobjmod.hxx>
36 :
37 : #include "date.hxx"
38 : #include "sbintern.hxx"
39 : #include "runtime.hxx"
40 : #include "stdobj.hxx"
41 : #include "rtlproto.hxx"
42 : #include "dllmgr.hxx"
43 : #include <iosys.hxx>
44 : #include "sbunoobj.hxx"
45 : #include "propacc.hxx"
46 : #include "sal/log.hxx"
47 :
48 :
49 : #include <comphelper/processfactory.hxx>
50 : #include <comphelper/string.hxx>
51 :
52 : #include <com/sun/star/uno/Sequence.hxx>
53 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
54 : #include <com/sun/star/i18n/LocaleCalendar.hpp>
55 : #include <com/sun/star/sheet/XFunctionAccess.hpp>
56 :
57 : using namespace comphelper;
58 : using namespace com::sun::star::i18n;
59 : using namespace com::sun::star::lang;
60 : using namespace com::sun::star::sheet;
61 : using namespace com::sun::star::uno;
62 :
63 : void unoToSbxValue( SbxVariable* pVar, const Any& aValue );
64 : Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, com::sun::star::beans::Property* pUnoProperty = NULL );
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 : sal_Bool bVal = sal_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 2 : RTLFUNC(CDbl) // JSM
320 : {
321 : (void)pBasic;
322 : (void)bWrite;
323 :
324 2 : double nVal = 0.0;
325 2 : if ( rPar.Count() == 2 )
326 : {
327 2 : SbxVariable *pSbxVariable = rPar.Get(1);
328 2 : if( pSbxVariable->GetType() == SbxSTRING )
329 : {
330 : // #41690
331 2 : OUString aScanStr = pSbxVariable->GetOUString();
332 2 : SbError Error = SbxValue::ScanNumIntnl( aScanStr, nVal );
333 2 : if( Error != SbxERR_OK )
334 : {
335 0 : StarBASIC::Error( Error );
336 2 : }
337 : }
338 : else
339 : {
340 0 : nVal = pSbxVariable->GetDouble();
341 : }
342 : }
343 : else
344 : {
345 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
346 : }
347 :
348 2 : rPar.Get(0)->PutDouble(nVal);
349 2 : }
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_uIntPtr nRGB = (sal_uIntPtr)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_uIntPtr nRGB = (sal_uIntPtr)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_uIntPtr nRGB = (sal_uIntPtr)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 26 : bool IsBaseIndexOne()
786 : {
787 26 : bool result = false;
788 26 : if ( GetSbData()->pInst && GetSbData()->pInst->pRun )
789 : {
790 26 : sal_uInt16 res = GetSbData()->pInst->pRun->GetBase();
791 26 : if ( res )
792 : {
793 21 : result = true;
794 : }
795 : }
796 26 : return result;
797 : }
798 :
799 24 : RTLFUNC(Array)
800 : {
801 : (void)pBasic;
802 : (void)bWrite;
803 :
804 24 : SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
805 24 : sal_uInt16 nArraySize = rPar.Count() - 1;
806 :
807 : // ignore Option Base so far (unfortunately only known by the compiler)
808 24 : bool bIncIndex = (IsBaseIndexOne() && SbiRuntime::isVBAEnabled() );
809 24 : if( nArraySize )
810 : {
811 24 : if ( bIncIndex )
812 : {
813 21 : pArray->AddDim( 1, nArraySize );
814 : }
815 : else
816 : {
817 3 : 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 102 : for( sal_uInt16 i = 0 ; i < nArraySize ; i++ )
830 : {
831 78 : SbxVariable* pVar = rPar.Get(i+1);
832 78 : SbxVariable* pNew = new SbxVariable( *pVar );
833 78 : pNew->SetFlag( SBX_WRITE );
834 78 : short index = static_cast< short >(i);
835 78 : if ( bIncIndex )
836 : {
837 71 : ++index;
838 : }
839 78 : pArray->Put( pNew, &index );
840 : }
841 :
842 : // return array
843 24 : SbxVariableRef refVar = rPar.Get(0);
844 24 : sal_uInt16 nFlags = refVar->GetFlags();
845 24 : refVar->ResetFlag( SBX_FIXED );
846 24 : refVar->PutObject( pArray );
847 24 : refVar->SetFlags( nFlags );
848 24 : refVar->SetParameters( NULL );
849 24 : }
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 sal_Bool lcl_WriteSbxVariable( const SbxVariable& rVar, SvStream* pStrm,
984 : sal_Bool bBinary, short nBlockLen, sal_Bool bIsArray )
985 : {
986 0 : sal_uIntPtr nFPos = pStrm->Tell();
987 :
988 0 : sal_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 << (sal_uInt16)SbxBYTE; // VarType Id
999 : }
1000 0 : *pStrm << 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 << (sal_uInt16)SbxINTEGER; // VarType Id
1013 : }
1014 0 : *pStrm << rVar.GetInteger();
1015 0 : break;
1016 :
1017 : case SbxLONG:
1018 : case SbxULONG:
1019 0 : if( bIsVariant )
1020 : {
1021 0 : *pStrm << (sal_uInt16)SbxLONG; // VarType Id
1022 : }
1023 0 : *pStrm << rVar.GetLong();
1024 0 : break;
1025 : case SbxSALINT64:
1026 : case SbxSALUINT64:
1027 0 : if( bIsVariant )
1028 : {
1029 0 : *pStrm << (sal_uInt16)SbxSALINT64; // VarType Id
1030 : }
1031 0 : *pStrm << (sal_uInt64)rVar.GetInt64();
1032 0 : break;
1033 : case SbxSINGLE:
1034 0 : if( bIsVariant )
1035 : {
1036 0 : *pStrm << (sal_uInt16)eType; // VarType Id
1037 : }
1038 0 : *pStrm << rVar.GetSingle();
1039 0 : break;
1040 :
1041 : case SbxDOUBLE:
1042 : case SbxCURRENCY:
1043 : case SbxDATE:
1044 0 : if( bIsVariant )
1045 : {
1046 0 : *pStrm << (sal_uInt16)eType; // VarType Id
1047 : }
1048 0 : *pStrm << 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 << (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 << (const char*)aByteStr.getStr();
1069 0 : }
1070 : }
1071 0 : break;
1072 :
1073 : default:
1074 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1075 0 : return sal_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 sal_Bool lcl_ReadSbxVariable( SbxVariable& rVar, SvStream* pStrm,
1086 : sal_Bool bBinary, short nBlockLen, sal_Bool bIsArray )
1087 : {
1088 : (void)bBinary;
1089 : (void)bIsArray;
1090 :
1091 : double aDouble;
1092 :
1093 0 : sal_uIntPtr nFPos = pStrm->Tell();
1094 :
1095 0 : sal_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 >> 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 >> 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 >> 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 >> aInt;
1142 0 : rVar.PutLong( aInt );
1143 : }
1144 0 : break;
1145 : case SbxSALINT64:
1146 : case SbxSALUINT64:
1147 : {
1148 : sal_uInt32 aInt;
1149 0 : *pStrm >> aInt;
1150 0 : rVar.PutInt64( (sal_Int64)aInt );
1151 : }
1152 0 : break;
1153 : case SbxSINGLE:
1154 : {
1155 : float nS;
1156 0 : *pStrm >> nS;
1157 0 : rVar.PutSingle( nS );
1158 : }
1159 0 : break;
1160 :
1161 : case SbxDOUBLE:
1162 : case SbxCURRENCY:
1163 : {
1164 0 : *pStrm >> aDouble;
1165 0 : rVar.PutDouble( aDouble );
1166 : }
1167 0 : break;
1168 :
1169 : case SbxDATE:
1170 : {
1171 0 : *pStrm >> 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 sal_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 sal_Bool lcl_WriteReadSbxArray( SbxDimArray& rArr, SvStream* pStrm,
1199 : sal_Bool bBinary, short nCurDim, short* pOtherDims, sal_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 sal_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 : sal_Bool bRet;
1214 0 : if( bWrite )
1215 0 : bRet = lcl_WriteSbxVariable(*pVar, pStrm, bBinary, 0, sal_True );
1216 : else
1217 0 : bRet = lcl_ReadSbxVariable(*pVar, pStrm, bBinary, 0, sal_True );
1218 0 : if( !bRet )
1219 0 : return sal_False;
1220 : }
1221 : }
1222 0 : return sal_True;
1223 : }
1224 :
1225 0 : void PutGet( SbxArray& rPar, sal_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_uIntPtr nFilePos = bRandom ? (sal_uIntPtr)(nBlockLen*nRecordNo) : (sal_uIntPtr)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 : sal_Bool bRet;
1276 :
1277 0 : if( pArr )
1278 : {
1279 0 : sal_uIntPtr nFPos = pStrm->Tell();
1280 0 : short nDims = pArr->GetDims();
1281 0 : short* pDims = new short[ nDims ];
1282 0 : bRet = lcl_WriteReadSbxArray(*pArr,pStrm,!bRandom,nDims,pDims,bPut);
1283 0 : delete [] pDims;
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, sal_False);
1291 : else
1292 0 : bRet = lcl_ReadSbxVariable(*pVar, pStrm, !bRandom, nBlockLen, sal_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, sal_True );
1304 0 : }
1305 :
1306 0 : RTLFUNC(Get)
1307 : {
1308 : (void)pBasic;
1309 : (void)bWrite;
1310 :
1311 0 : PutGet( rPar, sal_False );
1312 0 : }
1313 :
1314 1 : RTLFUNC(Environ)
1315 : {
1316 : (void)pBasic;
1317 : (void)bWrite;
1318 :
1319 1 : if ( rPar.Count() != 2 )
1320 : {
1321 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1322 1 : return;
1323 : }
1324 1 : OUString aResult;
1325 : // should be ANSI but that's not possible under Win16 in the DLL
1326 1 : OString aByteStr(OUStringToOString(rPar.Get(1)->GetOUString(),
1327 3 : osl_getThreadTextEncoding()));
1328 1 : const char* pEnvStr = getenv(aByteStr.getStr());
1329 1 : if ( pEnvStr )
1330 : {
1331 1 : aResult = OUString::createFromAscii( pEnvStr );
1332 : }
1333 2 : 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 53 : RTLFUNC(CreateUnoStruct)
1528 : {
1529 : (void)pBasic;
1530 : (void)bWrite;
1531 :
1532 53 : RTL_Impl_CreateUnoStruct( pBasic, rPar, bWrite );
1533 53 : }
1534 :
1535 :
1536 : // 1st parameter == service-name
1537 38 : RTLFUNC(CreateUnoService)
1538 : {
1539 : (void)pBasic;
1540 : (void)bWrite;
1541 :
1542 38 : RTL_Impl_CreateUnoService( pBasic, rPar, bWrite );
1543 38 : }
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 : // Instantiate "com.sun.star.awt.UnoControlDialog" on basis
1611 : // of a DialogLibrary entry: Convert from XML-ByteSequence
1612 : // and attach events. Implemented in classes\eventatt.cxx
1613 : void RTL_Impl_CreateUnoDialog( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite );
1614 :
1615 0 : RTLFUNC(CreateUnoDialog)
1616 : {
1617 : (void)pBasic;
1618 : (void)bWrite;
1619 :
1620 0 : RTL_Impl_CreateUnoDialog( pBasic, rPar, bWrite );
1621 0 : }
1622 :
1623 : // Return the application standard lib as root scope
1624 0 : RTLFUNC(GlobalScope)
1625 : {
1626 : (void)pBasic;
1627 : (void)bWrite;
1628 :
1629 0 : SbxObject* p = pBasic;
1630 0 : while( p->GetParent() )
1631 : {
1632 0 : p = p->GetParent();
1633 : }
1634 0 : SbxVariableRef refVar = rPar.Get(0);
1635 0 : refVar->PutObject( p );
1636 0 : }
1637 :
1638 : // Helper functions to convert Url from/to system paths
1639 0 : RTLFUNC(ConvertToUrl)
1640 : {
1641 : (void)pBasic;
1642 : (void)bWrite;
1643 :
1644 0 : if ( rPar.Count() == 2 )
1645 : {
1646 0 : OUString aStr = rPar.Get(1)->GetOUString();
1647 0 : INetURLObject aURLObj( aStr, INET_PROT_FILE );
1648 0 : OUString aFileURL = aURLObj.GetMainURL( INetURLObject::NO_DECODE );
1649 0 : if( aFileURL.isEmpty() )
1650 : {
1651 0 : ::osl::File::getFileURLFromSystemPath( aFileURL, aFileURL );
1652 : }
1653 0 : if( aFileURL.isEmpty() )
1654 : {
1655 0 : aFileURL = aStr;
1656 : }
1657 0 : rPar.Get(0)->PutString(aFileURL);
1658 : }
1659 : else
1660 : {
1661 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1662 : }
1663 0 : }
1664 :
1665 0 : RTLFUNC(ConvertFromUrl)
1666 : {
1667 : (void)pBasic;
1668 : (void)bWrite;
1669 :
1670 0 : if ( rPar.Count() == 2 )
1671 : {
1672 0 : OUString aStr = rPar.Get(1)->GetOUString();
1673 0 : OUString aSysPath;
1674 0 : ::osl::File::getSystemPathFromFileURL( aStr, aSysPath );
1675 0 : if( aSysPath.isEmpty() )
1676 : {
1677 0 : aSysPath = aStr;
1678 : }
1679 0 : rPar.Get(0)->PutString(aSysPath);
1680 : }
1681 : else
1682 : {
1683 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1684 : }
1685 0 : }
1686 :
1687 :
1688 : // Provide DefaultContext
1689 1 : RTLFUNC(GetDefaultContext)
1690 : {
1691 : (void)pBasic;
1692 : (void)bWrite;
1693 :
1694 1 : RTL_Impl_GetDefaultContext( pBasic, rPar, bWrite );
1695 1 : }
1696 :
1697 : #ifdef DBG_TRACE_BASIC
1698 : RTLFUNC(TraceCommand)
1699 : {
1700 : RTL_Impl_TraceCommand( pBasic, rPar, bWrite );
1701 : }
1702 : #endif
1703 :
1704 0 : RTLFUNC(Join)
1705 : {
1706 : (void)pBasic;
1707 : (void)bWrite;
1708 :
1709 0 : sal_uInt16 nParCount = rPar.Count();
1710 0 : if ( nParCount != 3 && nParCount != 2 )
1711 : {
1712 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1713 0 : return;
1714 : }
1715 0 : SbxBase* pParObj = rPar.Get(1)->GetObject();
1716 0 : SbxDimArray* pArr = PTR_CAST(SbxDimArray,pParObj);
1717 0 : if( pArr )
1718 : {
1719 0 : if( pArr->GetDims() != 1 )
1720 : {
1721 0 : StarBASIC::Error( SbERR_WRONG_DIMS ); // Syntax Error?!
1722 : }
1723 0 : OUString aDelim;
1724 0 : if( nParCount == 3 )
1725 : {
1726 0 : aDelim = rPar.Get(2)->GetOUString();
1727 : }
1728 : else
1729 : {
1730 0 : aDelim = " ";
1731 : }
1732 0 : OUString aRetStr;
1733 : short nLower, nUpper;
1734 0 : pArr->GetDim( 1, nLower, nUpper );
1735 0 : for( short i = nLower ; i <= nUpper ; ++i )
1736 : {
1737 0 : OUString aStr = pArr->Get( &i )->GetOUString();
1738 0 : aRetStr += aStr;
1739 0 : if( i != nUpper )
1740 : {
1741 0 : aRetStr += aDelim;
1742 : }
1743 0 : }
1744 0 : rPar.Get(0)->PutString( aRetStr );
1745 : }
1746 : else
1747 : {
1748 0 : StarBASIC::Error( SbERR_MUST_HAVE_DIMS );
1749 : }
1750 : }
1751 :
1752 :
1753 0 : RTLFUNC(Split)
1754 : {
1755 : (void)pBasic;
1756 : (void)bWrite;
1757 :
1758 0 : sal_uInt16 nParCount = rPar.Count();
1759 0 : if ( nParCount < 2 )
1760 : {
1761 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1762 0 : return;
1763 : }
1764 :
1765 0 : OUString aExpression = rPar.Get(1)->GetOUString();
1766 0 : short nArraySize = 0;
1767 0 : StringVector vRet;
1768 0 : if( !aExpression.isEmpty() )
1769 : {
1770 0 : OUString aDelim;
1771 0 : if( nParCount >= 3 )
1772 : {
1773 0 : aDelim = rPar.Get(2)->GetOUString();
1774 : }
1775 : else
1776 : {
1777 0 : aDelim = " ";
1778 : }
1779 :
1780 0 : sal_Int32 nCount = -1;
1781 0 : if( nParCount == 4 )
1782 : {
1783 0 : nCount = rPar.Get(3)->GetLong();
1784 : }
1785 0 : sal_Int32 nDelimLen = aDelim.getLength();
1786 0 : if( nDelimLen )
1787 : {
1788 0 : sal_Int32 iSearch = -1;
1789 0 : sal_Int32 iStart = 0;
1790 0 : do
1791 : {
1792 0 : bool bBreak = false;
1793 0 : if( nCount >= 0 && nArraySize == nCount - 1 )
1794 : {
1795 0 : bBreak = true;
1796 : }
1797 0 : iSearch = aExpression.indexOf( aDelim, iStart );
1798 0 : OUString aSubStr;
1799 0 : if( iSearch >= 0 && !bBreak )
1800 : {
1801 0 : aSubStr = aExpression.copy( iStart, iSearch - iStart );
1802 0 : iStart = iSearch + nDelimLen;
1803 : }
1804 : else
1805 : {
1806 0 : aSubStr = aExpression.copy( iStart );
1807 : }
1808 0 : vRet.push_back( aSubStr );
1809 0 : nArraySize++;
1810 :
1811 0 : if( bBreak )
1812 : {
1813 0 : break;
1814 0 : }
1815 : }
1816 : while( iSearch >= 0 );
1817 : }
1818 : else
1819 : {
1820 0 : vRet.push_back( aExpression );
1821 0 : nArraySize = 1;
1822 0 : }
1823 : }
1824 :
1825 0 : SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
1826 0 : pArray->unoAddDim( 0, nArraySize-1 );
1827 :
1828 : // insert parameter(s) into the array
1829 0 : for( short i = 0 ; i < nArraySize ; i++ )
1830 : {
1831 0 : SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
1832 0 : xVar->PutString( vRet[i] );
1833 0 : pArray->Put( (SbxVariable*)xVar, &i );
1834 0 : }
1835 :
1836 : // return array
1837 0 : SbxVariableRef refVar = rPar.Get(0);
1838 0 : sal_uInt16 nFlags = refVar->GetFlags();
1839 0 : refVar->ResetFlag( SBX_FIXED );
1840 0 : refVar->PutObject( pArray );
1841 0 : refVar->SetFlags( nFlags );
1842 0 : refVar->SetParameters( NULL );
1843 : }
1844 :
1845 : // MonthName(month[, abbreviate])
1846 0 : RTLFUNC(MonthName)
1847 : {
1848 : (void)pBasic;
1849 : (void)bWrite;
1850 :
1851 0 : sal_uInt16 nParCount = rPar.Count();
1852 0 : if( nParCount != 2 && nParCount != 3 )
1853 : {
1854 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1855 0 : return;
1856 : }
1857 :
1858 0 : Reference< XCalendar3 > xCalendar = getLocaleCalendar();
1859 0 : if( !xCalendar.is() )
1860 : {
1861 0 : StarBASIC::Error( SbERR_INTERNAL_ERROR );
1862 0 : return;
1863 : }
1864 0 : Sequence< CalendarItem2 > aMonthSeq = xCalendar->getMonths2();
1865 0 : sal_Int32 nMonthCount = aMonthSeq.getLength();
1866 :
1867 0 : sal_Int16 nVal = rPar.Get(1)->GetInteger();
1868 0 : if( nVal < 1 || nVal > nMonthCount )
1869 : {
1870 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1871 0 : return;
1872 : }
1873 :
1874 0 : sal_Bool bAbbreviate = false;
1875 0 : if( nParCount == 3 )
1876 0 : bAbbreviate = rPar.Get(2)->GetBool();
1877 :
1878 0 : const CalendarItem2* pCalendarItems = aMonthSeq.getConstArray();
1879 0 : const CalendarItem2& rItem = pCalendarItems[nVal - 1];
1880 :
1881 0 : OUString aRetStr = ( bAbbreviate ? rItem.AbbrevName : rItem.FullName );
1882 0 : rPar.Get(0)->PutString(aRetStr);
1883 : }
1884 :
1885 : // WeekdayName(weekday, abbreviate, firstdayofweek)
1886 0 : RTLFUNC(WeekdayName)
1887 : {
1888 : (void)pBasic;
1889 : (void)bWrite;
1890 :
1891 0 : sal_uInt16 nParCount = rPar.Count();
1892 0 : if( nParCount < 2 || nParCount > 4 )
1893 : {
1894 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1895 0 : return;
1896 : }
1897 :
1898 0 : Reference< XCalendar3 > xCalendar = getLocaleCalendar();
1899 0 : if( !xCalendar.is() )
1900 : {
1901 0 : StarBASIC::Error( SbERR_INTERNAL_ERROR );
1902 0 : return;
1903 : }
1904 :
1905 0 : Sequence< CalendarItem2 > aDaySeq = xCalendar->getDays2();
1906 0 : sal_Int16 nDayCount = (sal_Int16)aDaySeq.getLength();
1907 0 : sal_Int16 nDay = rPar.Get(1)->GetInteger();
1908 0 : sal_Int16 nFirstDay = 0;
1909 0 : if( nParCount == 4 )
1910 : {
1911 0 : nFirstDay = rPar.Get(3)->GetInteger();
1912 0 : if( nFirstDay < 0 || nFirstDay > 7 )
1913 : {
1914 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1915 0 : return;
1916 : }
1917 : }
1918 0 : if( nFirstDay == 0 )
1919 : {
1920 0 : nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 );
1921 : }
1922 0 : nDay = 1 + (nDay + nDayCount + nFirstDay - 2) % nDayCount;
1923 0 : if( nDay < 1 || nDay > nDayCount )
1924 : {
1925 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1926 0 : return;
1927 : }
1928 :
1929 0 : sal_Bool bAbbreviate = false;
1930 0 : if( nParCount >= 3 )
1931 : {
1932 0 : SbxVariable* pPar2 = rPar.Get(2);
1933 0 : if( !pPar2->IsErr() )
1934 : {
1935 0 : bAbbreviate = pPar2->GetBool();
1936 : }
1937 : }
1938 :
1939 0 : const CalendarItem2* pCalendarItems = aDaySeq.getConstArray();
1940 0 : const CalendarItem2& rItem = pCalendarItems[nDay - 1];
1941 :
1942 0 : OUString aRetStr = ( bAbbreviate ? rItem.AbbrevName : rItem.FullName );
1943 0 : rPar.Get(0)->PutString( aRetStr );
1944 : }
1945 :
1946 0 : RTLFUNC(Weekday)
1947 : {
1948 : (void)pBasic;
1949 : (void)bWrite;
1950 :
1951 0 : sal_uInt16 nParCount = rPar.Count();
1952 0 : if ( nParCount < 2 )
1953 : {
1954 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1955 : }
1956 : else
1957 : {
1958 0 : double aDate = rPar.Get(1)->GetDate();
1959 :
1960 0 : bool bFirstDay = false;
1961 0 : sal_Int16 nFirstDay = 0;
1962 0 : if ( nParCount > 2 )
1963 : {
1964 0 : nFirstDay = rPar.Get(2)->GetInteger();
1965 0 : bFirstDay = true;
1966 : }
1967 0 : sal_Int16 nDay = implGetWeekDay( aDate, bFirstDay, nFirstDay );
1968 0 : rPar.Get(0)->PutInteger( nDay );
1969 : }
1970 0 : }
1971 :
1972 :
1973 : enum Interval
1974 : {
1975 : INTERVAL_YYYY,
1976 : INTERVAL_Q,
1977 : INTERVAL_M,
1978 : INTERVAL_Y,
1979 : INTERVAL_D,
1980 : INTERVAL_W,
1981 : INTERVAL_WW,
1982 : INTERVAL_H,
1983 : INTERVAL_N,
1984 : INTERVAL_S
1985 : };
1986 :
1987 : struct IntervalInfo
1988 : {
1989 : Interval meInterval;
1990 : char const * mStringCode;
1991 : double mdValue;
1992 : bool mbSimple;
1993 : };
1994 :
1995 0 : IntervalInfo const * getIntervalInfo( const OUString& rStringCode )
1996 : {
1997 : static IntervalInfo const aIntervalTable[] =
1998 : {
1999 : { INTERVAL_YYYY, "yyyy", 0.0, false }, // Year
2000 : { INTERVAL_Q, "q", 0.0, false }, // Quarter
2001 : { INTERVAL_M, "m", 0.0, false }, // Month
2002 : { INTERVAL_Y, "y", 1.0, true }, // Day of year
2003 : { INTERVAL_D, "d", 1.0, true }, // Day
2004 : { INTERVAL_W, "w", 1.0, true }, // Weekday
2005 : { INTERVAL_WW, "ww", 7.0, true }, // Week
2006 : { INTERVAL_H, "h", 1.0 / 24.0, true }, // Hour
2007 : { INTERVAL_N, "n", 1.0 / 1440.0, true }, // Minute
2008 : { INTERVAL_S, "s", 1.0 / 86400.0, true } // Second
2009 : };
2010 0 : for( std::size_t i = 0; i != SAL_N_ELEMENTS(aIntervalTable); ++i )
2011 : {
2012 0 : if( rStringCode.equalsIgnoreAsciiCaseAscii(
2013 0 : aIntervalTable[i].mStringCode ) )
2014 : {
2015 0 : return &aIntervalTable[i];
2016 : }
2017 : }
2018 0 : return NULL;
2019 : }
2020 :
2021 0 : inline void implGetDayMonthYear( sal_Int16& rnYear, sal_Int16& rnMonth, sal_Int16& rnDay, double dDate )
2022 : {
2023 0 : rnDay = implGetDateDay( dDate );
2024 0 : rnMonth = implGetDateMonth( dDate );
2025 0 : rnYear = implGetDateYear( dDate );
2026 0 : }
2027 :
2028 0 : inline sal_Int16 limitToINT16( sal_Int32 n32 )
2029 : {
2030 0 : if( n32 > 32767 )
2031 : {
2032 0 : n32 = 32767;
2033 : }
2034 0 : else if( n32 < -32768 )
2035 : {
2036 0 : n32 = -32768;
2037 : }
2038 0 : return (sal_Int16)n32;
2039 : }
2040 :
2041 0 : RTLFUNC(DateAdd)
2042 : {
2043 : (void)pBasic;
2044 : (void)bWrite;
2045 :
2046 0 : sal_uInt16 nParCount = rPar.Count();
2047 0 : if( nParCount != 4 )
2048 : {
2049 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2050 0 : return;
2051 : }
2052 :
2053 0 : OUString aStringCode = rPar.Get(1)->GetOUString();
2054 0 : IntervalInfo const * pInfo = getIntervalInfo( aStringCode );
2055 0 : if( !pInfo )
2056 : {
2057 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2058 0 : return;
2059 : }
2060 :
2061 0 : sal_Int32 lNumber = rPar.Get(2)->GetLong();
2062 0 : double dDate = rPar.Get(3)->GetDate();
2063 0 : double dNewDate = 0;
2064 0 : if( pInfo->mbSimple )
2065 : {
2066 0 : double dAdd = pInfo->mdValue * lNumber;
2067 0 : dNewDate = dDate + dAdd;
2068 : }
2069 : else
2070 : {
2071 : // Keep hours, minutes, seconds
2072 0 : double dHoursMinutesSeconds = dDate - floor( dDate );
2073 :
2074 0 : bool bOk = true;
2075 : sal_Int16 nYear, nMonth, nDay;
2076 0 : sal_Int16 nTargetYear16 = 0, nTargetMonth = 0;
2077 0 : implGetDayMonthYear( nYear, nMonth, nDay, dDate );
2078 0 : switch( pInfo->meInterval )
2079 : {
2080 : case INTERVAL_YYYY:
2081 : {
2082 0 : sal_Int32 nTargetYear = lNumber + nYear;
2083 0 : nTargetYear16 = limitToINT16( nTargetYear );
2084 0 : nTargetMonth = nMonth;
2085 0 : bOk = implDateSerial( nTargetYear16, nTargetMonth, nDay, dNewDate );
2086 0 : break;
2087 : }
2088 : case INTERVAL_Q:
2089 : case INTERVAL_M:
2090 : {
2091 0 : bool bNeg = (lNumber < 0);
2092 0 : if( bNeg )
2093 0 : lNumber = -lNumber;
2094 : sal_Int32 nYearsAdd;
2095 : sal_Int16 nMonthAdd;
2096 0 : if( pInfo->meInterval == INTERVAL_Q )
2097 : {
2098 0 : nYearsAdd = lNumber / 4;
2099 0 : nMonthAdd = (sal_Int16)( 3 * (lNumber % 4) );
2100 : }
2101 : else
2102 : {
2103 0 : nYearsAdd = lNumber / 12;
2104 0 : nMonthAdd = (sal_Int16)( lNumber % 12 );
2105 : }
2106 :
2107 : sal_Int32 nTargetYear;
2108 0 : if( bNeg )
2109 : {
2110 0 : nTargetMonth = nMonth - nMonthAdd;
2111 0 : if( nTargetMonth <= 0 )
2112 : {
2113 0 : nTargetMonth += 12;
2114 0 : nYearsAdd++;
2115 : }
2116 0 : nTargetYear = (sal_Int32)nYear - nYearsAdd;
2117 : }
2118 : else
2119 : {
2120 0 : nTargetMonth = nMonth + nMonthAdd;
2121 0 : if( nTargetMonth > 12 )
2122 : {
2123 0 : nTargetMonth -= 12;
2124 0 : nYearsAdd++;
2125 : }
2126 0 : nTargetYear = (sal_Int32)nYear + nYearsAdd;
2127 : }
2128 0 : nTargetYear16 = limitToINT16( nTargetYear );
2129 0 : bOk = implDateSerial( nTargetYear16, nTargetMonth, nDay, dNewDate );
2130 0 : break;
2131 : }
2132 0 : default: break;
2133 : }
2134 :
2135 0 : if( bOk )
2136 : {
2137 : // Overflow?
2138 : sal_Int16 nNewYear, nNewMonth, nNewDay;
2139 0 : implGetDayMonthYear( nNewYear, nNewMonth, nNewDay, dNewDate );
2140 0 : if( nNewYear > 9999 || nNewYear < 100 )
2141 : {
2142 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2143 0 : return;
2144 : }
2145 0 : sal_Int16 nCorrectionDay = nDay;
2146 0 : while( nNewMonth > nTargetMonth )
2147 : {
2148 0 : nCorrectionDay--;
2149 0 : implDateSerial( nTargetYear16, nTargetMonth, nCorrectionDay, dNewDate );
2150 0 : implGetDayMonthYear( nNewYear, nNewMonth, nNewDay, dNewDate );
2151 : }
2152 0 : dNewDate += dHoursMinutesSeconds;
2153 : }
2154 : }
2155 :
2156 0 : rPar.Get(0)->PutDate( dNewDate );
2157 : }
2158 :
2159 0 : inline double RoundImpl( double d )
2160 : {
2161 0 : return ( d >= 0 ) ? floor( d + 0.5 ) : -floor( -d + 0.5 );
2162 : }
2163 :
2164 0 : RTLFUNC(DateDiff)
2165 : {
2166 : (void)pBasic;
2167 : (void)bWrite;
2168 :
2169 : // DateDiff(interval, date1, date2[, firstdayofweek[, firstweekofyear]])
2170 :
2171 0 : sal_uInt16 nParCount = rPar.Count();
2172 0 : if( nParCount < 4 || nParCount > 6 )
2173 : {
2174 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2175 0 : return;
2176 : }
2177 :
2178 0 : OUString aStringCode = rPar.Get(1)->GetOUString();
2179 0 : IntervalInfo const * pInfo = getIntervalInfo( aStringCode );
2180 0 : if( !pInfo )
2181 : {
2182 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2183 0 : return;
2184 : }
2185 :
2186 0 : double dDate1 = rPar.Get(2)->GetDate();
2187 0 : double dDate2 = rPar.Get(3)->GetDate();
2188 :
2189 0 : double dRet = 0.0;
2190 0 : switch( pInfo->meInterval )
2191 : {
2192 : case INTERVAL_YYYY:
2193 : {
2194 0 : sal_Int16 nYear1 = implGetDateYear( dDate1 );
2195 0 : sal_Int16 nYear2 = implGetDateYear( dDate2 );
2196 0 : dRet = nYear2 - nYear1;
2197 0 : break;
2198 : }
2199 : case INTERVAL_Q:
2200 : {
2201 0 : sal_Int16 nYear1 = implGetDateYear( dDate1 );
2202 0 : sal_Int16 nYear2 = implGetDateYear( dDate2 );
2203 0 : sal_Int16 nQ1 = 1 + (implGetDateMonth( dDate1 ) - 1) / 3;
2204 0 : sal_Int16 nQ2 = 1 + (implGetDateMonth( dDate2 ) - 1) / 3;
2205 0 : sal_Int16 nQGes1 = 4 * nYear1 + nQ1;
2206 0 : sal_Int16 nQGes2 = 4 * nYear2 + nQ2;
2207 0 : dRet = nQGes2 - nQGes1;
2208 0 : break;
2209 : }
2210 : case INTERVAL_M:
2211 : {
2212 0 : sal_Int16 nYear1 = implGetDateYear( dDate1 );
2213 0 : sal_Int16 nYear2 = implGetDateYear( dDate2 );
2214 0 : sal_Int16 nMonth1 = implGetDateMonth( dDate1 );
2215 0 : sal_Int16 nMonth2 = implGetDateMonth( dDate2 );
2216 0 : sal_Int16 nMonthGes1 = 12 * nYear1 + nMonth1;
2217 0 : sal_Int16 nMonthGes2 = 12 * nYear2 + nMonth2;
2218 0 : dRet = nMonthGes2 - nMonthGes1;
2219 0 : break;
2220 : }
2221 : case INTERVAL_Y:
2222 : case INTERVAL_D:
2223 : {
2224 0 : double dDays1 = floor( dDate1 );
2225 0 : double dDays2 = floor( dDate2 );
2226 0 : dRet = dDays2 - dDays1;
2227 0 : break;
2228 : }
2229 : case INTERVAL_W:
2230 : case INTERVAL_WW:
2231 : {
2232 0 : double dDays1 = floor( dDate1 );
2233 0 : double dDays2 = floor( dDate2 );
2234 0 : if( pInfo->meInterval == INTERVAL_WW )
2235 : {
2236 0 : sal_Int16 nFirstDay = 1; // Default
2237 0 : if( nParCount >= 5 )
2238 : {
2239 0 : nFirstDay = rPar.Get(4)->GetInteger();
2240 0 : if( nFirstDay < 0 || nFirstDay > 7 )
2241 : {
2242 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2243 0 : return;
2244 : }
2245 0 : if( nFirstDay == 0 )
2246 : {
2247 0 : Reference< XCalendar3 > xCalendar = getLocaleCalendar();
2248 0 : if( !xCalendar.is() )
2249 : {
2250 0 : StarBASIC::Error( SbERR_INTERNAL_ERROR );
2251 0 : return;
2252 : }
2253 0 : nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 );
2254 : }
2255 : }
2256 0 : sal_Int16 nDay1 = implGetWeekDay( dDate1 );
2257 0 : sal_Int16 nDay1_Diff = nDay1 - nFirstDay;
2258 0 : if( nDay1_Diff < 0 )
2259 0 : nDay1_Diff += 7;
2260 0 : dDays1 -= nDay1_Diff;
2261 :
2262 0 : sal_Int16 nDay2 = implGetWeekDay( dDate2 );
2263 0 : sal_Int16 nDay2_Diff = nDay2 - nFirstDay;
2264 0 : if( nDay2_Diff < 0 )
2265 0 : nDay2_Diff += 7;
2266 0 : dDays2 -= nDay2_Diff;
2267 : }
2268 :
2269 0 : double dDiff = dDays2 - dDays1;
2270 0 : dRet = ( dDiff >= 0 ) ? floor( dDiff / 7.0 ) : -floor( -dDiff / 7.0 );
2271 0 : break;
2272 : }
2273 : case INTERVAL_H:
2274 : {
2275 0 : double dFactor = 24.0;
2276 0 : dRet = RoundImpl( dFactor * (dDate2 - dDate1) );
2277 0 : break;
2278 : }
2279 : case INTERVAL_N:
2280 : {
2281 0 : double dFactor =1440.0;
2282 0 : dRet = RoundImpl( dFactor * (dDate2 - dDate1) );
2283 0 : break;
2284 : }
2285 : case INTERVAL_S:
2286 : {
2287 0 : double dFactor = 86400.0;
2288 0 : dRet = RoundImpl( dFactor * (dDate2 - dDate1) );
2289 0 : break;
2290 : }
2291 : }
2292 0 : rPar.Get(0)->PutDouble( dRet );
2293 : }
2294 :
2295 0 : double implGetDateOfFirstDayInFirstWeek
2296 : ( sal_Int16 nYear, sal_Int16& nFirstDay, sal_Int16& nFirstWeek, bool* pbError = NULL )
2297 : {
2298 0 : SbError nError = 0;
2299 0 : if( nFirstDay < 0 || nFirstDay > 7 )
2300 0 : nError = SbERR_BAD_ARGUMENT;
2301 :
2302 0 : if( nFirstWeek < 0 || nFirstWeek > 3 )
2303 0 : nError = SbERR_BAD_ARGUMENT;
2304 :
2305 0 : Reference< XCalendar3 > xCalendar;
2306 0 : if( nFirstDay == 0 || nFirstWeek == 0 )
2307 : {
2308 0 : xCalendar = getLocaleCalendar();
2309 0 : if( !xCalendar.is() )
2310 0 : nError = SbERR_BAD_ARGUMENT;
2311 : }
2312 :
2313 0 : if( nError != 0 )
2314 : {
2315 0 : StarBASIC::Error( nError );
2316 0 : if( pbError )
2317 0 : *pbError = true;
2318 0 : return 0.0;
2319 : }
2320 :
2321 0 : if( nFirstDay == 0 )
2322 0 : nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 );
2323 :
2324 0 : sal_Int16 nFirstWeekMinDays = 0; // Not used for vbFirstJan1 = default
2325 0 : if( nFirstWeek == 0 )
2326 : {
2327 0 : nFirstWeekMinDays = xCalendar->getMinimumNumberOfDaysForFirstWeek();
2328 0 : if( nFirstWeekMinDays == 1 )
2329 : {
2330 0 : nFirstWeekMinDays = 0;
2331 0 : nFirstWeek = 1;
2332 : }
2333 0 : else if( nFirstWeekMinDays == 4 )
2334 0 : nFirstWeek = 2;
2335 0 : else if( nFirstWeekMinDays == 7 )
2336 0 : nFirstWeek = 3;
2337 : }
2338 0 : else if( nFirstWeek == 2 )
2339 0 : nFirstWeekMinDays = 4; // vbFirstFourDays
2340 0 : else if( nFirstWeek == 3 )
2341 0 : nFirstWeekMinDays = 7; // vbFirstFourDays
2342 :
2343 : double dBaseDate;
2344 0 : implDateSerial( nYear, 1, 1, dBaseDate );
2345 0 : double dRetDate = dBaseDate;
2346 :
2347 0 : sal_Int16 nWeekDay0101 = implGetWeekDay( dBaseDate );
2348 0 : sal_Int16 nDayDiff = nWeekDay0101 - nFirstDay;
2349 0 : if( nDayDiff < 0 )
2350 0 : nDayDiff += 7;
2351 :
2352 0 : if( nFirstWeekMinDays )
2353 : {
2354 0 : sal_Int16 nThisWeeksDaysInYearCount = 7 - nDayDiff;
2355 0 : if( nThisWeeksDaysInYearCount < nFirstWeekMinDays )
2356 0 : nDayDiff -= 7;
2357 : }
2358 0 : dRetDate = dBaseDate - nDayDiff;
2359 0 : return dRetDate;
2360 : }
2361 :
2362 0 : RTLFUNC(DatePart)
2363 : {
2364 : (void)pBasic;
2365 : (void)bWrite;
2366 :
2367 : // DatePart(interval, date[,firstdayofweek[, firstweekofyear]])
2368 :
2369 0 : sal_uInt16 nParCount = rPar.Count();
2370 0 : if( nParCount < 3 || nParCount > 5 )
2371 : {
2372 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2373 0 : return;
2374 : }
2375 :
2376 0 : OUString aStringCode = rPar.Get(1)->GetOUString();
2377 0 : IntervalInfo const * pInfo = getIntervalInfo( aStringCode );
2378 0 : if( !pInfo )
2379 : {
2380 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2381 0 : return;
2382 : }
2383 :
2384 0 : double dDate = rPar.Get(2)->GetDate();
2385 :
2386 0 : sal_Int32 nRet = 0;
2387 0 : switch( pInfo->meInterval )
2388 : {
2389 : case INTERVAL_YYYY:
2390 : {
2391 0 : nRet = implGetDateYear( dDate );
2392 0 : break;
2393 : }
2394 : case INTERVAL_Q:
2395 : {
2396 0 : nRet = 1 + (implGetDateMonth( dDate ) - 1) / 3;
2397 0 : break;
2398 : }
2399 : case INTERVAL_M:
2400 : {
2401 0 : nRet = implGetDateMonth( dDate );
2402 0 : break;
2403 : }
2404 : case INTERVAL_Y:
2405 : {
2406 0 : sal_Int16 nYear = implGetDateYear( dDate );
2407 : double dBaseDate;
2408 0 : implDateSerial( nYear, 1, 1, dBaseDate );
2409 0 : nRet = 1 + sal_Int32( dDate - dBaseDate );
2410 0 : break;
2411 : }
2412 : case INTERVAL_D:
2413 : {
2414 0 : nRet = implGetDateDay( dDate );
2415 0 : break;
2416 : }
2417 : case INTERVAL_W:
2418 : {
2419 0 : bool bFirstDay = false;
2420 0 : sal_Int16 nFirstDay = 1; // Default
2421 0 : if( nParCount >= 4 )
2422 : {
2423 0 : nFirstDay = rPar.Get(3)->GetInteger();
2424 0 : bFirstDay = true;
2425 : }
2426 0 : nRet = implGetWeekDay( dDate, bFirstDay, nFirstDay );
2427 0 : break;
2428 : }
2429 : case INTERVAL_WW:
2430 : {
2431 0 : sal_Int16 nFirstDay = 1; // Default
2432 0 : if( nParCount >= 4 )
2433 0 : nFirstDay = rPar.Get(3)->GetInteger();
2434 :
2435 0 : sal_Int16 nFirstWeek = 1; // Default
2436 0 : if( nParCount == 5 )
2437 0 : nFirstWeek = rPar.Get(4)->GetInteger();
2438 :
2439 0 : sal_Int16 nYear = implGetDateYear( dDate );
2440 0 : bool bError = false;
2441 0 : double dYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear, nFirstDay, nFirstWeek, &bError );
2442 0 : if( !bError )
2443 : {
2444 0 : if( dYearFirstDay > dDate )
2445 : {
2446 : // Date belongs to last year's week
2447 0 : dYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear - 1, nFirstDay, nFirstWeek );
2448 : }
2449 0 : else if( nFirstWeek != 1 )
2450 : {
2451 : // Check if date belongs to next year
2452 0 : double dNextYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear + 1, nFirstDay, nFirstWeek );
2453 0 : if( dDate >= dNextYearFirstDay )
2454 0 : dYearFirstDay = dNextYearFirstDay;
2455 : }
2456 :
2457 : // Calculate week
2458 0 : double dDiff = dDate - dYearFirstDay;
2459 0 : nRet = 1 + sal_Int32( dDiff / 7 );
2460 : }
2461 0 : break;
2462 : }
2463 : case INTERVAL_H:
2464 : {
2465 0 : nRet = implGetHour( dDate );
2466 0 : break;
2467 : }
2468 : case INTERVAL_N:
2469 : {
2470 0 : nRet = implGetMinute( dDate );
2471 0 : break;
2472 : }
2473 : case INTERVAL_S:
2474 : {
2475 0 : nRet = implGetSecond( dDate );
2476 0 : break;
2477 : }
2478 : }
2479 0 : rPar.Get(0)->PutLong( nRet );
2480 : }
2481 :
2482 : // FormatDateTime(Date[,NamedFormat])
2483 0 : RTLFUNC(FormatDateTime)
2484 : {
2485 : (void)pBasic;
2486 : (void)bWrite;
2487 :
2488 0 : sal_uInt16 nParCount = rPar.Count();
2489 0 : if( nParCount < 2 || nParCount > 3 )
2490 : {
2491 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2492 0 : return;
2493 : }
2494 :
2495 0 : double dDate = rPar.Get(1)->GetDate();
2496 0 : sal_Int16 nNamedFormat = 0;
2497 0 : if( nParCount > 2 )
2498 : {
2499 0 : nNamedFormat = rPar.Get(2)->GetInteger();
2500 0 : if( nNamedFormat < 0 || nNamedFormat > 4 )
2501 : {
2502 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2503 0 : return;
2504 : }
2505 : }
2506 :
2507 0 : Reference< XCalendar3 > xCalendar = getLocaleCalendar();
2508 0 : if( !xCalendar.is() )
2509 : {
2510 0 : StarBASIC::Error( SbERR_INTERNAL_ERROR );
2511 0 : return;
2512 : }
2513 :
2514 0 : OUString aRetStr;
2515 0 : SbxVariableRef pSbxVar = new SbxVariable( SbxSTRING );
2516 0 : switch( nNamedFormat )
2517 : {
2518 : // GeneralDate:
2519 : // Display a date and/or time. If there is a date part,
2520 : // display it as a short date. If there is a time part,
2521 : // display it as a long time. If present, both parts are displayed.
2522 :
2523 : // 12/21/2004 11:24:50 AM
2524 : // 21.12.2004 12:13:51
2525 : case 0:
2526 0 : pSbxVar->PutDate( dDate );
2527 0 : aRetStr = pSbxVar->GetOUString();
2528 0 : break;
2529 :
2530 : // LongDate: Display a date using the long date format specified
2531 : // in your computer's regional settings.
2532 : // Tuesday, December 21, 2004
2533 : // Dienstag, 21. December 2004
2534 : case 1:
2535 : {
2536 0 : SvNumberFormatter* pFormatter = NULL;
2537 0 : if( GetSbData()->pInst )
2538 : {
2539 0 : pFormatter = GetSbData()->pInst->GetNumberFormatter();
2540 : }
2541 : else
2542 : {
2543 : sal_uInt32 n; // Dummy
2544 0 : SbiInstance::PrepareNumberFormatter( pFormatter, n, n, n );
2545 : }
2546 :
2547 0 : LanguageType eLangType = GetpApp()->GetSettings().GetLanguageTag().getLanguageType();
2548 0 : sal_uIntPtr nIndex = pFormatter->GetFormatIndex( NF_DATE_SYSTEM_LONG, eLangType );
2549 : Color* pCol;
2550 0 : pFormatter->GetOutputString( dDate, nIndex, aRetStr, &pCol );
2551 :
2552 0 : if( !GetSbData()->pInst )
2553 : {
2554 0 : delete pFormatter;
2555 : }
2556 0 : break;
2557 : }
2558 :
2559 : // ShortDate: Display a date using the short date format specified
2560 : // in your computer's regional settings.
2561 : // 21.12.2004
2562 : case 2:
2563 0 : pSbxVar->PutDate( floor(dDate) );
2564 0 : aRetStr = pSbxVar->GetOUString();
2565 0 : break;
2566 :
2567 : // LongTime: Display a time using the time format specified
2568 : // in your computer's regional settings.
2569 : // 11:24:50 AM
2570 : // 12:13:51
2571 : case 3:
2572 : // ShortTime: Display a time using the 24-hour format (hh:mm).
2573 : // 11:24
2574 : case 4:
2575 : double n;
2576 0 : double dTime = modf( dDate, &n );
2577 0 : pSbxVar->PutDate( dTime );
2578 0 : if( nNamedFormat == 3 )
2579 : {
2580 0 : aRetStr = pSbxVar->GetOUString();
2581 : }
2582 : else
2583 : {
2584 0 : aRetStr = pSbxVar->GetOUString().copy( 0, 5 );
2585 : }
2586 0 : break;
2587 : }
2588 :
2589 0 : rPar.Get(0)->PutString( aRetStr );
2590 : }
2591 :
2592 0 : RTLFUNC(Frac)
2593 : {
2594 : (void)pBasic;
2595 : (void)bWrite;
2596 :
2597 0 : sal_uInt16 nParCount = rPar.Count();
2598 0 : if( nParCount != 2)
2599 : {
2600 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2601 0 : return;
2602 : }
2603 :
2604 0 : SbxVariable *pSbxVariable = rPar.Get(1);
2605 0 : double dVal = pSbxVariable->GetDouble();
2606 0 : if(dVal >= 0)
2607 0 : rPar.Get(0)->PutDouble(dVal - ::rtl::math::approxFloor(dVal));
2608 : else
2609 0 : rPar.Get(0)->PutDouble(dVal - ::rtl::math::approxCeil(dVal));
2610 : }
2611 :
2612 0 : RTLFUNC(Round)
2613 : {
2614 : (void)pBasic;
2615 : (void)bWrite;
2616 :
2617 0 : sal_uInt16 nParCount = rPar.Count();
2618 0 : if( nParCount != 2 && nParCount != 3 )
2619 : {
2620 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2621 0 : return;
2622 : }
2623 :
2624 0 : SbxVariable *pSbxVariable = rPar.Get(1);
2625 0 : double dVal = pSbxVariable->GetDouble();
2626 0 : double dRes = 0.0;
2627 0 : if( dVal != 0.0 )
2628 : {
2629 0 : bool bNeg = false;
2630 0 : if( dVal < 0.0 )
2631 : {
2632 0 : bNeg = true;
2633 0 : dVal = -dVal;
2634 : }
2635 :
2636 0 : sal_Int16 numdecimalplaces = 0;
2637 0 : if( nParCount == 3 )
2638 : {
2639 0 : numdecimalplaces = rPar.Get(2)->GetInteger();
2640 0 : if( numdecimalplaces < 0 || numdecimalplaces > 22 )
2641 : {
2642 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2643 0 : return;
2644 : }
2645 : }
2646 :
2647 0 : if( numdecimalplaces == 0 )
2648 : {
2649 0 : dRes = floor( dVal + 0.5 );
2650 : }
2651 : else
2652 : {
2653 0 : double dFactor = pow( 10.0, numdecimalplaces );
2654 0 : dVal *= dFactor;
2655 0 : dRes = floor( dVal + 0.5 );
2656 0 : dRes /= dFactor;
2657 : }
2658 :
2659 0 : if( bNeg )
2660 0 : dRes = -dRes;
2661 : }
2662 0 : rPar.Get(0)->PutDouble( dRes );
2663 : }
2664 :
2665 0 : void CallFunctionAccessFunction( const Sequence< Any >& aArgs, const OUString& sFuncName, SbxVariable* pRet )
2666 : {
2667 0 : static Reference< XFunctionAccess > xFunc;
2668 0 : Any aRes;
2669 : try
2670 : {
2671 0 : if ( !xFunc.is() )
2672 : {
2673 0 : Reference< XMultiServiceFactory > xFactory( getProcessServiceFactory() );
2674 0 : if( xFactory.is() )
2675 : {
2676 0 : xFunc.set( xFactory->createInstance("com.sun.star.sheet.FunctionAccess"), UNO_QUERY_THROW);
2677 0 : }
2678 : }
2679 0 : Any aRet = xFunc->callFunction( sFuncName, aArgs );
2680 :
2681 0 : unoToSbxValue( pRet, aRet );
2682 :
2683 : }
2684 0 : catch(const Exception& )
2685 : {
2686 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2687 0 : }
2688 0 : }
2689 :
2690 0 : RTLFUNC(SYD)
2691 : {
2692 : (void)pBasic;
2693 : (void)bWrite;
2694 :
2695 0 : sal_uLong nArgCount = rPar.Count()-1;
2696 :
2697 0 : if ( nArgCount < 4 )
2698 : {
2699 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2700 0 : return;
2701 : }
2702 :
2703 : // retrieve non-optional params
2704 :
2705 0 : Sequence< Any > aParams( 4 );
2706 0 : aParams[ 0 ] <<= makeAny( rPar.Get(1)->GetDouble() );
2707 0 : aParams[ 1 ] <<= makeAny( rPar.Get(2)->GetDouble() );
2708 0 : aParams[ 2 ] <<= makeAny( rPar.Get(3)->GetDouble() );
2709 0 : aParams[ 3 ] <<= makeAny( rPar.Get(4)->GetDouble() );
2710 :
2711 0 : CallFunctionAccessFunction( aParams, "SYD", rPar.Get( 0 ) );
2712 : }
2713 :
2714 0 : RTLFUNC(SLN)
2715 : {
2716 : (void)pBasic;
2717 : (void)bWrite;
2718 :
2719 0 : sal_uLong nArgCount = rPar.Count()-1;
2720 :
2721 0 : if ( nArgCount < 3 )
2722 : {
2723 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2724 0 : return;
2725 : }
2726 :
2727 : // retrieve non-optional params
2728 :
2729 0 : Sequence< Any > aParams( 3 );
2730 0 : aParams[ 0 ] <<= makeAny( rPar.Get(1)->GetDouble() );
2731 0 : aParams[ 1 ] <<= makeAny( rPar.Get(2)->GetDouble() );
2732 0 : aParams[ 2 ] <<= makeAny( rPar.Get(3)->GetDouble() );
2733 :
2734 0 : CallFunctionAccessFunction( aParams, "SLN", rPar.Get( 0 ) );
2735 : }
2736 :
2737 0 : RTLFUNC(Pmt)
2738 : {
2739 : (void)pBasic;
2740 : (void)bWrite;
2741 :
2742 0 : sal_uLong nArgCount = rPar.Count()-1;
2743 :
2744 0 : if ( nArgCount < 3 || nArgCount > 5 )
2745 : {
2746 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2747 0 : return;
2748 : }
2749 : // retrieve non-optional params
2750 :
2751 0 : double rate = rPar.Get(1)->GetDouble();
2752 0 : double nper = rPar.Get(2)->GetDouble();
2753 0 : double pmt = rPar.Get(3)->GetDouble();
2754 :
2755 : // set default values for Optional args
2756 0 : double fv = 0;
2757 0 : double type = 0;
2758 :
2759 : // fv
2760 0 : if ( nArgCount >= 4 )
2761 : {
2762 0 : if( rPar.Get(4)->GetType() != SbxEMPTY )
2763 0 : fv = rPar.Get(4)->GetDouble();
2764 : }
2765 : // type
2766 0 : if ( nArgCount >= 5 )
2767 : {
2768 0 : if( rPar.Get(5)->GetType() != SbxEMPTY )
2769 0 : type = rPar.Get(5)->GetDouble();
2770 : }
2771 :
2772 0 : Sequence< Any > aParams( 5 );
2773 0 : aParams[ 0 ] <<= rate;
2774 0 : aParams[ 1 ] <<= nper;
2775 0 : aParams[ 2 ] <<= pmt;
2776 0 : aParams[ 3 ] <<= fv;
2777 0 : aParams[ 4 ] <<= type;
2778 :
2779 0 : CallFunctionAccessFunction( aParams, "Pmt", rPar.Get( 0 ) );
2780 : }
2781 :
2782 0 : RTLFUNC(PPmt)
2783 : {
2784 : (void)pBasic;
2785 : (void)bWrite;
2786 :
2787 0 : sal_uLong nArgCount = rPar.Count()-1;
2788 :
2789 0 : if ( nArgCount < 4 || nArgCount > 6 )
2790 : {
2791 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2792 0 : return;
2793 : }
2794 : // retrieve non-optional params
2795 :
2796 0 : double rate = rPar.Get(1)->GetDouble();
2797 0 : double per = rPar.Get(2)->GetDouble();
2798 0 : double nper = rPar.Get(3)->GetDouble();
2799 0 : double pv = rPar.Get(4)->GetDouble();
2800 :
2801 : // set default values for Optional args
2802 0 : double fv = 0;
2803 0 : double type = 0;
2804 :
2805 : // fv
2806 0 : if ( nArgCount >= 5 )
2807 : {
2808 0 : if( rPar.Get(5)->GetType() != SbxEMPTY )
2809 0 : fv = rPar.Get(5)->GetDouble();
2810 : }
2811 : // type
2812 0 : if ( nArgCount >= 6 )
2813 : {
2814 0 : if( rPar.Get(6)->GetType() != SbxEMPTY )
2815 0 : type = rPar.Get(6)->GetDouble();
2816 : }
2817 :
2818 0 : Sequence< Any > aParams( 6 );
2819 0 : aParams[ 0 ] <<= rate;
2820 0 : aParams[ 1 ] <<= per;
2821 0 : aParams[ 2 ] <<= nper;
2822 0 : aParams[ 3 ] <<= pv;
2823 0 : aParams[ 4 ] <<= fv;
2824 0 : aParams[ 5 ] <<= type;
2825 :
2826 0 : CallFunctionAccessFunction( aParams, "PPmt", rPar.Get( 0 ) );
2827 : }
2828 :
2829 0 : RTLFUNC(PV)
2830 : {
2831 : (void)pBasic;
2832 : (void)bWrite;
2833 :
2834 0 : sal_uLong nArgCount = rPar.Count()-1;
2835 :
2836 0 : if ( nArgCount < 3 || nArgCount > 5 )
2837 : {
2838 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2839 0 : return;
2840 : }
2841 : // retrieve non-optional params
2842 :
2843 0 : double rate = rPar.Get(1)->GetDouble();
2844 0 : double nper = rPar.Get(2)->GetDouble();
2845 0 : double pmt = rPar.Get(3)->GetDouble();
2846 :
2847 : // set default values for Optional args
2848 0 : double fv = 0;
2849 0 : double type = 0;
2850 :
2851 : // fv
2852 0 : if ( nArgCount >= 4 )
2853 : {
2854 0 : if( rPar.Get(4)->GetType() != SbxEMPTY )
2855 0 : fv = rPar.Get(4)->GetDouble();
2856 : }
2857 : // type
2858 0 : if ( nArgCount >= 5 )
2859 : {
2860 0 : if( rPar.Get(5)->GetType() != SbxEMPTY )
2861 0 : type = rPar.Get(5)->GetDouble();
2862 : }
2863 :
2864 0 : Sequence< Any > aParams( 5 );
2865 0 : aParams[ 0 ] <<= rate;
2866 0 : aParams[ 1 ] <<= nper;
2867 0 : aParams[ 2 ] <<= pmt;
2868 0 : aParams[ 3 ] <<= fv;
2869 0 : aParams[ 4 ] <<= type;
2870 :
2871 0 : CallFunctionAccessFunction( aParams, "PV", rPar.Get( 0 ) );
2872 : }
2873 :
2874 0 : RTLFUNC(NPV)
2875 : {
2876 : (void)pBasic;
2877 : (void)bWrite;
2878 :
2879 0 : sal_uLong nArgCount = rPar.Count()-1;
2880 :
2881 0 : if ( nArgCount < 1 || nArgCount > 2 )
2882 : {
2883 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2884 0 : return;
2885 : }
2886 :
2887 0 : Sequence< Any > aParams( 2 );
2888 0 : aParams[ 0 ] <<= makeAny( rPar.Get(1)->GetDouble() );
2889 : Any aValues = sbxToUnoValue( rPar.Get(2),
2890 0 : getCppuType( (Sequence<double>*)0 ) );
2891 :
2892 : // convert for calc functions
2893 0 : Sequence< Sequence< double > > sValues(1);
2894 0 : aValues >>= sValues[ 0 ];
2895 0 : aValues <<= sValues;
2896 :
2897 0 : aParams[ 1 ] <<= aValues;
2898 :
2899 0 : CallFunctionAccessFunction( aParams, "NPV", rPar.Get( 0 ) );
2900 : }
2901 :
2902 0 : RTLFUNC(NPer)
2903 : {
2904 : (void)pBasic;
2905 : (void)bWrite;
2906 :
2907 0 : sal_uLong nArgCount = rPar.Count()-1;
2908 :
2909 0 : if ( nArgCount < 3 || nArgCount > 5 )
2910 : {
2911 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2912 0 : return;
2913 : }
2914 : // retrieve non-optional params
2915 :
2916 0 : double rate = rPar.Get(1)->GetDouble();
2917 0 : double pmt = rPar.Get(2)->GetDouble();
2918 0 : double pv = rPar.Get(3)->GetDouble();
2919 :
2920 : // set default values for Optional args
2921 0 : double fv = 0;
2922 0 : double type = 0;
2923 :
2924 : // fv
2925 0 : if ( nArgCount >= 4 )
2926 : {
2927 0 : if( rPar.Get(4)->GetType() != SbxEMPTY )
2928 0 : fv = rPar.Get(4)->GetDouble();
2929 : }
2930 : // type
2931 0 : if ( nArgCount >= 5 )
2932 : {
2933 0 : if( rPar.Get(5)->GetType() != SbxEMPTY )
2934 0 : type = rPar.Get(5)->GetDouble();
2935 : }
2936 :
2937 0 : Sequence< Any > aParams( 5 );
2938 0 : aParams[ 0 ] <<= rate;
2939 0 : aParams[ 1 ] <<= pmt;
2940 0 : aParams[ 2 ] <<= pv;
2941 0 : aParams[ 3 ] <<= fv;
2942 0 : aParams[ 4 ] <<= type;
2943 :
2944 0 : CallFunctionAccessFunction( aParams, "NPer", rPar.Get( 0 ) );
2945 : }
2946 :
2947 0 : RTLFUNC(MIRR)
2948 : {
2949 : (void)pBasic;
2950 : (void)bWrite;
2951 :
2952 0 : sal_uLong nArgCount = rPar.Count()-1;
2953 :
2954 0 : if ( nArgCount < 3 )
2955 : {
2956 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2957 0 : return;
2958 : }
2959 :
2960 : // retrieve non-optional params
2961 :
2962 0 : Sequence< Any > aParams( 3 );
2963 : Any aValues = sbxToUnoValue( rPar.Get(1),
2964 0 : getCppuType( (Sequence<double>*)0 ) );
2965 :
2966 : // convert for calc functions
2967 0 : Sequence< Sequence< double > > sValues(1);
2968 0 : aValues >>= sValues[ 0 ];
2969 0 : aValues <<= sValues;
2970 :
2971 0 : aParams[ 0 ] <<= aValues;
2972 0 : aParams[ 1 ] <<= makeAny( rPar.Get(2)->GetDouble() );
2973 0 : aParams[ 2 ] <<= makeAny( rPar.Get(3)->GetDouble() );
2974 :
2975 0 : CallFunctionAccessFunction( aParams, "MIRR", rPar.Get( 0 ) );
2976 : }
2977 :
2978 0 : RTLFUNC(IRR)
2979 : {
2980 : (void)pBasic;
2981 : (void)bWrite;
2982 :
2983 0 : sal_uLong nArgCount = rPar.Count()-1;
2984 :
2985 0 : if ( nArgCount < 1 || nArgCount > 2 )
2986 : {
2987 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2988 0 : return;
2989 : }
2990 : // retrieve non-optional params
2991 : Any aValues = sbxToUnoValue( rPar.Get(1),
2992 0 : getCppuType( (Sequence<double>*)0 ) );
2993 :
2994 : // convert for calc functions
2995 0 : Sequence< Sequence< double > > sValues(1);
2996 0 : aValues >>= sValues[ 0 ];
2997 0 : aValues <<= sValues;
2998 :
2999 : // set default values for Optional args
3000 0 : double guess = 0.1;
3001 : // guess
3002 0 : if ( nArgCount >= 2 )
3003 : {
3004 0 : if( rPar.Get(2)->GetType() != SbxEMPTY )
3005 0 : guess = rPar.Get(2)->GetDouble();
3006 : }
3007 :
3008 0 : Sequence< Any > aParams( 2 );
3009 0 : aParams[ 0 ] <<= aValues;
3010 0 : aParams[ 1 ] <<= guess;
3011 :
3012 0 : CallFunctionAccessFunction( aParams, "IRR", rPar.Get( 0 ) );
3013 : }
3014 :
3015 0 : RTLFUNC(IPmt)
3016 : {
3017 : (void)pBasic;
3018 : (void)bWrite;
3019 :
3020 0 : sal_uLong nArgCount = rPar.Count()-1;
3021 :
3022 0 : if ( nArgCount < 4 || nArgCount > 6 )
3023 : {
3024 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3025 0 : return;
3026 : }
3027 : // retrieve non-optional params
3028 :
3029 0 : double rate = rPar.Get(1)->GetDouble();
3030 0 : double per = rPar.Get(2)->GetInteger();
3031 0 : double nper = rPar.Get(3)->GetDouble();
3032 0 : double pv = rPar.Get(4)->GetDouble();
3033 :
3034 : // set default values for Optional args
3035 0 : double fv = 0;
3036 0 : double type = 0;
3037 :
3038 : // fv
3039 0 : if ( nArgCount >= 5 )
3040 : {
3041 0 : if( rPar.Get(5)->GetType() != SbxEMPTY )
3042 0 : fv = rPar.Get(5)->GetDouble();
3043 : }
3044 : // type
3045 0 : if ( nArgCount >= 6 )
3046 : {
3047 0 : if( rPar.Get(6)->GetType() != SbxEMPTY )
3048 0 : type = rPar.Get(6)->GetDouble();
3049 : }
3050 :
3051 0 : Sequence< Any > aParams( 6 );
3052 0 : aParams[ 0 ] <<= rate;
3053 0 : aParams[ 1 ] <<= per;
3054 0 : aParams[ 2 ] <<= nper;
3055 0 : aParams[ 3 ] <<= pv;
3056 0 : aParams[ 4 ] <<= fv;
3057 0 : aParams[ 5 ] <<= type;
3058 :
3059 0 : CallFunctionAccessFunction( aParams, "IPmt", rPar.Get( 0 ) );
3060 : }
3061 :
3062 0 : RTLFUNC(FV)
3063 : {
3064 : (void)pBasic;
3065 : (void)bWrite;
3066 :
3067 0 : sal_uLong nArgCount = rPar.Count()-1;
3068 :
3069 0 : if ( nArgCount < 3 || nArgCount > 5 )
3070 : {
3071 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3072 0 : return;
3073 : }
3074 : // retrieve non-optional params
3075 :
3076 0 : double rate = rPar.Get(1)->GetDouble();
3077 0 : double nper = rPar.Get(2)->GetDouble();
3078 0 : double pmt = rPar.Get(3)->GetDouble();
3079 :
3080 : // set default values for Optional args
3081 0 : double pv = 0;
3082 0 : double type = 0;
3083 :
3084 : // pv
3085 0 : if ( nArgCount >= 4 )
3086 : {
3087 0 : if( rPar.Get(4)->GetType() != SbxEMPTY )
3088 0 : pv = rPar.Get(4)->GetDouble();
3089 : }
3090 : // type
3091 0 : if ( nArgCount >= 5 )
3092 : {
3093 0 : if( rPar.Get(5)->GetType() != SbxEMPTY )
3094 0 : type = rPar.Get(5)->GetDouble();
3095 : }
3096 :
3097 0 : Sequence< Any > aParams( 5 );
3098 0 : aParams[ 0 ] <<= rate;
3099 0 : aParams[ 1 ] <<= nper;
3100 0 : aParams[ 2 ] <<= pmt;
3101 0 : aParams[ 3 ] <<= pv;
3102 0 : aParams[ 4 ] <<= type;
3103 :
3104 0 : CallFunctionAccessFunction( aParams, "FV", rPar.Get( 0 ) );
3105 : }
3106 :
3107 0 : RTLFUNC(DDB)
3108 : {
3109 : (void)pBasic;
3110 : (void)bWrite;
3111 :
3112 0 : sal_uLong nArgCount = rPar.Count()-1;
3113 :
3114 0 : if ( nArgCount < 4 || nArgCount > 5 )
3115 : {
3116 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3117 0 : return;
3118 : }
3119 : // retrieve non-optional params
3120 :
3121 0 : double cost = rPar.Get(1)->GetDouble();
3122 0 : double salvage = rPar.Get(2)->GetDouble();
3123 0 : double life = rPar.Get(3)->GetDouble();
3124 0 : double period = rPar.Get(4)->GetDouble();
3125 :
3126 : // set default values for Optional args
3127 0 : double factor = 2;
3128 :
3129 : // factor
3130 0 : if ( nArgCount >= 5 )
3131 : {
3132 0 : if( rPar.Get(5)->GetType() != SbxEMPTY )
3133 0 : factor = rPar.Get(5)->GetDouble();
3134 : }
3135 :
3136 0 : Sequence< Any > aParams( 5 );
3137 0 : aParams[ 0 ] <<= cost;
3138 0 : aParams[ 1 ] <<= salvage;
3139 0 : aParams[ 2 ] <<= life;
3140 0 : aParams[ 3 ] <<= period;
3141 0 : aParams[ 4 ] <<= factor;
3142 :
3143 0 : CallFunctionAccessFunction( aParams, "DDB", rPar.Get( 0 ) );
3144 : }
3145 :
3146 0 : RTLFUNC(Rate)
3147 : {
3148 : (void)pBasic;
3149 : (void)bWrite;
3150 :
3151 0 : sal_uLong nArgCount = rPar.Count()-1;
3152 :
3153 0 : if ( nArgCount < 3 || nArgCount > 6 )
3154 : {
3155 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3156 0 : return;
3157 : }
3158 : // retrieve non-optional params
3159 :
3160 0 : double nper = 0;
3161 0 : double pmt = 0;
3162 0 : double pv = 0;
3163 :
3164 0 : nper = rPar.Get(1)->GetDouble();
3165 0 : pmt = rPar.Get(2)->GetDouble();
3166 0 : pv = rPar.Get(3)->GetDouble();
3167 :
3168 : // set default values for Optional args
3169 0 : double fv = 0;
3170 0 : double type = 0;
3171 0 : double guess = 0.1;
3172 :
3173 : // fv
3174 0 : if ( nArgCount >= 4 )
3175 : {
3176 0 : if( rPar.Get(4)->GetType() != SbxEMPTY )
3177 0 : fv = rPar.Get(4)->GetDouble();
3178 : }
3179 :
3180 : // type
3181 0 : if ( nArgCount >= 5 )
3182 : {
3183 0 : if( rPar.Get(5)->GetType() != SbxEMPTY )
3184 0 : type = rPar.Get(5)->GetDouble();
3185 : }
3186 :
3187 : // guess
3188 0 : if ( nArgCount >= 6 )
3189 : {
3190 0 : if( rPar.Get(6)->GetType() != SbxEMPTY )
3191 0 : type = rPar.Get(6)->GetDouble();
3192 : }
3193 :
3194 0 : Sequence< Any > aParams( 6 );
3195 0 : aParams[ 0 ] <<= nper;
3196 0 : aParams[ 1 ] <<= pmt;
3197 0 : aParams[ 2 ] <<= pv;
3198 0 : aParams[ 3 ] <<= fv;
3199 0 : aParams[ 4 ] <<= type;
3200 0 : aParams[ 5 ] <<= guess;
3201 :
3202 0 : CallFunctionAccessFunction( aParams, "Rate", rPar.Get( 0 ) );
3203 : }
3204 :
3205 0 : RTLFUNC(StrReverse)
3206 : {
3207 : (void)pBasic;
3208 : (void)bWrite;
3209 :
3210 0 : if ( rPar.Count() != 2 )
3211 : {
3212 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3213 0 : return;
3214 : }
3215 :
3216 0 : SbxVariable *pSbxVariable = rPar.Get(1);
3217 0 : if( pSbxVariable->IsNull() )
3218 : {
3219 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3220 0 : return;
3221 : }
3222 :
3223 0 : OUString aStr = comphelper::string::reverseString(pSbxVariable->GetOUString());
3224 0 : rPar.Get(0)->PutString( aStr );
3225 : }
3226 :
3227 2 : RTLFUNC(CompatibilityMode)
3228 : {
3229 : (void)pBasic;
3230 : (void)bWrite;
3231 :
3232 2 : bool bEnabled = false;
3233 2 : sal_uInt16 nCount = rPar.Count();
3234 2 : if ( nCount != 1 && nCount != 2 )
3235 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3236 :
3237 2 : SbiInstance* pInst = GetSbData()->pInst;
3238 2 : if( pInst )
3239 : {
3240 2 : if ( nCount == 2 )
3241 : {
3242 2 : pInst->EnableCompatibility( rPar.Get(1)->GetBool() );
3243 : }
3244 2 : bEnabled = pInst->IsCompatibility();
3245 : }
3246 2 : rPar.Get(0)->PutBool( bEnabled );
3247 2 : }
3248 :
3249 0 : RTLFUNC(Input)
3250 : {
3251 : (void)pBasic;
3252 : (void)bWrite;
3253 :
3254 : // 2 parameters needed
3255 0 : if ( rPar.Count() < 3 )
3256 : {
3257 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3258 0 : return;
3259 : }
3260 :
3261 0 : sal_uInt16 nByteCount = rPar.Get(1)->GetUShort();
3262 0 : sal_Int16 nFileNumber = rPar.Get(2)->GetInteger();
3263 :
3264 0 : SbiIoSystem* pIosys = GetSbData()->pInst->GetIoSystem();
3265 0 : SbiStream* pSbStrm = pIosys->GetStream( nFileNumber );
3266 0 : if ( !pSbStrm || !(pSbStrm->GetMode() & (SBSTRM_BINARY | SBSTRM_INPUT)) )
3267 : {
3268 0 : StarBASIC::Error( SbERR_BAD_CHANNEL );
3269 0 : return;
3270 : }
3271 :
3272 0 : OString aByteBuffer;
3273 0 : SbError err = pSbStrm->Read( aByteBuffer, nByteCount, true );
3274 0 : if( !err )
3275 0 : err = pIosys->GetError();
3276 :
3277 0 : if( err )
3278 : {
3279 0 : StarBASIC::Error( err );
3280 0 : return;
3281 : }
3282 0 : rPar.Get(0)->PutString(OStringToOUString(aByteBuffer, osl_getThreadTextEncoding()));
3283 : }
3284 :
3285 0 : RTLFUNC(Me)
3286 : {
3287 : (void)pBasic;
3288 : (void)bWrite;
3289 :
3290 0 : SbModule* pActiveModule = GetSbData()->pInst->GetActiveModule();
3291 0 : SbClassModuleObject* pClassModuleObject = PTR_CAST(SbClassModuleObject,pActiveModule);
3292 0 : SbxVariableRef refVar = rPar.Get(0);
3293 0 : if( pClassModuleObject == NULL )
3294 : {
3295 0 : SbObjModule* pMod = PTR_CAST(SbObjModule,pActiveModule);
3296 0 : if ( pMod )
3297 0 : refVar->PutObject( pMod );
3298 : else
3299 0 : StarBASIC::Error( SbERR_INVALID_USAGE_OBJECT );
3300 : }
3301 : else
3302 0 : refVar->PutObject( pClassModuleObject );
3303 0 : }
3304 :
3305 : #endif
3306 :
3307 0 : sal_Int16 implGetWeekDay( double aDate, bool bFirstDayParam, sal_Int16 nFirstDay )
3308 : {
3309 0 : Date aRefDate( 1,1,1900 );
3310 0 : long nDays = (long) aDate;
3311 0 : nDays -= 2; // normalize: 1.1.1900 => 0
3312 0 : aRefDate += nDays;
3313 0 : DayOfWeek aDay = aRefDate.GetDayOfWeek();
3314 : sal_Int16 nDay;
3315 0 : if ( aDay != SUNDAY )
3316 0 : nDay = (sal_Int16)aDay + 2;
3317 : else
3318 0 : nDay = 1; // 1 == Sunday
3319 :
3320 : // #117253 optional 2nd parameter "firstdayofweek"
3321 0 : if( bFirstDayParam )
3322 : {
3323 0 : if( nFirstDay < 0 || nFirstDay > 7 )
3324 : {
3325 : #ifndef DISABLE_SCRIPTING
3326 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3327 : #endif
3328 0 : return 0;
3329 : }
3330 0 : if( nFirstDay == 0 )
3331 : {
3332 0 : Reference< XCalendar3 > xCalendar = getLocaleCalendar();
3333 0 : if( !xCalendar.is() )
3334 : {
3335 : #ifndef DISABLE_SCRIPTING
3336 0 : StarBASIC::Error( SbERR_INTERNAL_ERROR );
3337 : #endif
3338 0 : return 0;
3339 : }
3340 0 : nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 );
3341 : }
3342 0 : nDay = 1 + (nDay + 7 - nFirstDay) % 7;
3343 : }
3344 0 : return nDay;
3345 429 : }
3346 :
3347 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|