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 <config_features.h>
21 :
22 : #include <sal/config.h>
23 : #include <config_version.h>
24 :
25 : #include <cstddef>
26 :
27 : #include <stdlib.h>
28 : #include <vcl/svapp.hxx>
29 : #include <vcl/mapmod.hxx>
30 : #include <vcl/wrkwin.hxx>
31 : #include <vcl/timer.hxx>
32 : #include <vcl/settings.hxx>
33 : #include <basic/sbxvar.hxx>
34 : #include <basic/sbx.hxx>
35 : #include <svl/zforlist.hxx>
36 : #include <tools/urlobj.hxx>
37 : #include <tools/fract.hxx>
38 : #include <osl/file.hxx>
39 : #include <vcl/jobset.hxx>
40 : #include "sbobjmod.hxx"
41 : #include <basic/sbuno.hxx>
42 :
43 : #include "date.hxx"
44 : #include "sbintern.hxx"
45 : #include "runtime.hxx"
46 : #include "stdobj.hxx"
47 : #include "rtlproto.hxx"
48 : #include "dllmgr.hxx"
49 : #include <iosys.hxx>
50 : #include "sbunoobj.hxx"
51 : #include "propacc.hxx"
52 : #include <sal/log.hxx>
53 : #include <eventatt.hxx>
54 :
55 : #include <comphelper/processfactory.hxx>
56 : #include <comphelper/string.hxx>
57 :
58 : #include <com/sun/star/uno/Sequence.hxx>
59 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
60 : #include <com/sun/star/i18n/LocaleCalendar2.hpp>
61 : #include <com/sun/star/sheet/XFunctionAccess.hpp>
62 : #include <boost/scoped_array.hpp>
63 :
64 : using namespace comphelper;
65 : using namespace com::sun::star::i18n;
66 : using namespace com::sun::star::lang;
67 : using namespace com::sun::star::sheet;
68 : using namespace com::sun::star::uno;
69 :
70 0 : static Reference< XCalendar4 > getLocaleCalendar()
71 : {
72 0 : static Reference< XCalendar4 > xCalendar;
73 0 : if( !xCalendar.is() )
74 : {
75 0 : Reference< XComponentContext > xContext = getProcessComponentContext();
76 0 : xCalendar = LocaleCalendar2::create(xContext);
77 : }
78 :
79 0 : static com::sun::star::lang::Locale aLastLocale;
80 : static bool bNeedsInit = true;
81 :
82 0 : com::sun::star::lang::Locale aLocale = Application::GetSettings().GetLanguageTag().getLocale();
83 0 : bool bNeedsReload = false;
84 0 : if( bNeedsInit )
85 : {
86 0 : bNeedsInit = false;
87 0 : bNeedsReload = true;
88 : }
89 0 : else if( aLocale.Language != aLastLocale.Language ||
90 0 : aLocale.Country != aLastLocale.Country ||
91 0 : aLocale.Variant != aLastLocale.Variant )
92 : {
93 0 : bNeedsReload = true;
94 : }
95 0 : if( bNeedsReload )
96 : {
97 0 : aLastLocale = aLocale;
98 0 : xCalendar->loadDefaultCalendar( aLocale );
99 : }
100 0 : return xCalendar;
101 : }
102 :
103 : #if HAVE_FEATURE_SCRIPTING
104 :
105 0 : RTLFUNC(CallByName)
106 : {
107 : (void)pBasic;
108 : (void)bWrite;
109 :
110 0 : const sal_Int16 vbGet = 2;
111 0 : const sal_Int16 vbLet = 4;
112 0 : const sal_Int16 vbMethod = 1;
113 0 : const sal_Int16 vbSet = 8;
114 :
115 : // At least 3 parameter needed plus function itself -> 4
116 0 : sal_uInt16 nParCount = rPar.Count();
117 0 : if ( nParCount < 4 )
118 : {
119 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
120 0 : return;
121 : }
122 :
123 : // 1. parameter is object
124 0 : SbxBase* pObjVar = static_cast<SbxObject*>(rPar.Get(1)->GetObject());
125 0 : SbxObject* pObj = NULL;
126 0 : if( pObjVar )
127 0 : pObj = PTR_CAST(SbxObject,pObjVar);
128 0 : if( !pObj && pObjVar && pObjVar->ISA(SbxVariable) )
129 : {
130 0 : SbxBase* pObjVarObj = static_cast<SbxVariable*>(pObjVar)->GetObject();
131 0 : pObj = PTR_CAST(SbxObject,pObjVarObj);
132 : }
133 0 : if( !pObj )
134 : {
135 0 : StarBASIC::Error( SbERR_BAD_PARAMETER );
136 0 : return;
137 : }
138 :
139 : // 2. parameter is ProcedureName
140 0 : OUString aNameStr = rPar.Get(2)->GetOUString();
141 :
142 : // 3. parameter is CallType
143 0 : sal_Int16 nCallType = rPar.Get(3)->GetInteger();
144 :
145 : //SbxObject* pFindObj = NULL;
146 0 : SbxVariable* pFindVar = pObj->Find( aNameStr, SbxCLASS_DONTCARE );
147 0 : if( pFindVar == NULL )
148 : {
149 0 : StarBASIC::Error( SbERR_PROC_UNDEFINED );
150 0 : return;
151 : }
152 :
153 0 : switch( nCallType )
154 : {
155 : case vbGet:
156 : {
157 0 : SbxValues aVals;
158 0 : aVals.eType = SbxVARIANT;
159 0 : pFindVar->Get( aVals );
160 :
161 0 : SbxVariableRef refVar = rPar.Get(0);
162 0 : refVar->Put( aVals );
163 : }
164 0 : break;
165 : case vbLet:
166 : case vbSet:
167 : {
168 0 : if ( nParCount != 5 )
169 : {
170 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
171 0 : return;
172 : }
173 0 : SbxVariableRef pValVar = rPar.Get(4);
174 0 : if( nCallType == vbLet )
175 : {
176 0 : SbxValues aVals;
177 0 : aVals.eType = SbxVARIANT;
178 0 : pValVar->Get( aVals );
179 0 : pFindVar->Put( aVals );
180 : }
181 : else
182 : {
183 0 : SbxVariableRef rFindVar = pFindVar;
184 0 : SbiInstance* pInst = GetSbData()->pInst;
185 0 : SbiRuntime* pRT = pInst ? pInst->pRun : NULL;
186 0 : if( pRT != NULL )
187 : {
188 0 : pRT->StepSET_Impl( pValVar, rFindVar, false );
189 0 : }
190 0 : }
191 : }
192 0 : break;
193 : case vbMethod:
194 : {
195 0 : SbMethod* pMeth = PTR_CAST(SbMethod,pFindVar);
196 0 : if( pMeth == NULL )
197 : {
198 0 : StarBASIC::Error( SbERR_PROC_UNDEFINED );
199 0 : return;
200 : }
201 :
202 : // Setup parameters
203 0 : SbxArrayRef xArray;
204 0 : sal_uInt16 nMethParamCount = nParCount - 4;
205 0 : if( nMethParamCount > 0 )
206 : {
207 0 : xArray = new SbxArray;
208 0 : for( sal_uInt16 i = 0 ; i < nMethParamCount ; i++ )
209 : {
210 0 : SbxVariable* pPar = rPar.Get( i + 4 );
211 0 : xArray->Put( pPar, i + 1 );
212 : }
213 : }
214 :
215 : // Call method
216 0 : SbxVariableRef refVar = rPar.Get(0);
217 0 : if( xArray.Is() )
218 0 : pMeth->SetParameters( xArray );
219 0 : pMeth->Call( refVar );
220 0 : pMeth->SetParameters( NULL );
221 : }
222 0 : break;
223 : default:
224 0 : StarBASIC::Error( SbERR_PROC_UNDEFINED );
225 0 : }
226 : }
227 :
228 0 : RTLFUNC(CBool) // JSM
229 : {
230 : (void)pBasic;
231 : (void)bWrite;
232 :
233 0 : bool bVal = false;
234 0 : if ( rPar.Count() == 2 )
235 : {
236 0 : SbxVariable *pSbxVariable = rPar.Get(1);
237 0 : bVal = pSbxVariable->GetBool();
238 : }
239 : else
240 : {
241 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
242 : }
243 0 : rPar.Get(0)->PutBool(bVal);
244 0 : }
245 :
246 0 : RTLFUNC(CByte) // JSM
247 : {
248 : (void)pBasic;
249 : (void)bWrite;
250 :
251 0 : sal_uInt8 nByte = 0;
252 0 : if ( rPar.Count() == 2 )
253 : {
254 0 : SbxVariable *pSbxVariable = rPar.Get(1);
255 0 : nByte = pSbxVariable->GetByte();
256 : }
257 : else
258 : {
259 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
260 : }
261 0 : rPar.Get(0)->PutByte(nByte);
262 0 : }
263 :
264 0 : RTLFUNC(CCur)
265 : {
266 : (void)pBasic;
267 : (void)bWrite;
268 :
269 0 : sal_Int64 nCur = 0;
270 0 : if ( rPar.Count() == 2 )
271 : {
272 0 : SbxVariable *pSbxVariable = rPar.Get(1);
273 0 : nCur = pSbxVariable->GetCurrency();
274 : }
275 : else
276 : {
277 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
278 : }
279 0 : rPar.Get(0)->PutCurrency( nCur );
280 0 : }
281 :
282 1 : RTLFUNC(CDec)
283 : {
284 : (void)pBasic;
285 : (void)bWrite;
286 :
287 : #ifdef WNT
288 : SbxDecimal* pDec = NULL;
289 : if ( rPar.Count() == 2 )
290 : {
291 : SbxVariable *pSbxVariable = rPar.Get(1);
292 : pDec = pSbxVariable->GetDecimal();
293 : }
294 : else
295 : {
296 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
297 : }
298 : rPar.Get(0)->PutDecimal( pDec );
299 : #else
300 1 : rPar.Get(0)->PutEmpty();
301 1 : StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
302 : #endif
303 1 : }
304 :
305 0 : RTLFUNC(CDate) // JSM
306 : {
307 : (void)pBasic;
308 : (void)bWrite;
309 :
310 0 : double nVal = 0.0;
311 0 : if ( rPar.Count() == 2 )
312 : {
313 0 : SbxVariable *pSbxVariable = rPar.Get(1);
314 0 : nVal = pSbxVariable->GetDate();
315 : }
316 : else
317 : {
318 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
319 : }
320 0 : rPar.Get(0)->PutDate(nVal);
321 0 : }
322 :
323 2 : RTLFUNC(CDbl) // JSM
324 : {
325 : (void)pBasic;
326 : (void)bWrite;
327 :
328 2 : double nVal = 0.0;
329 2 : if ( rPar.Count() == 2 )
330 : {
331 2 : SbxVariable *pSbxVariable = rPar.Get(1);
332 2 : if( pSbxVariable->GetType() == SbxSTRING )
333 : {
334 : // #41690
335 2 : OUString aScanStr = pSbxVariable->GetOUString();
336 2 : SbError Error = SbxValue::ScanNumIntnl( aScanStr, nVal );
337 2 : if( Error != SbxERR_OK )
338 : {
339 0 : StarBASIC::Error( Error );
340 2 : }
341 : }
342 : else
343 : {
344 0 : nVal = pSbxVariable->GetDouble();
345 : }
346 : }
347 : else
348 : {
349 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
350 : }
351 :
352 2 : rPar.Get(0)->PutDouble(nVal);
353 2 : }
354 :
355 0 : RTLFUNC(CInt) // JSM
356 : {
357 : (void)pBasic;
358 : (void)bWrite;
359 :
360 0 : sal_Int16 nVal = 0;
361 0 : if ( rPar.Count() == 2 )
362 : {
363 0 : SbxVariable *pSbxVariable = rPar.Get(1);
364 0 : nVal = pSbxVariable->GetInteger();
365 : }
366 : else
367 : {
368 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
369 : }
370 0 : rPar.Get(0)->PutInteger(nVal);
371 0 : }
372 :
373 4 : RTLFUNC(CLng) // JSM
374 : {
375 : (void)pBasic;
376 : (void)bWrite;
377 :
378 4 : sal_Int32 nVal = 0;
379 4 : if ( rPar.Count() == 2 )
380 : {
381 4 : SbxVariable *pSbxVariable = rPar.Get(1);
382 4 : nVal = pSbxVariable->GetLong();
383 : }
384 : else
385 : {
386 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
387 : }
388 4 : rPar.Get(0)->PutLong(nVal);
389 4 : }
390 :
391 0 : RTLFUNC(CSng) // JSM
392 : {
393 : (void)pBasic;
394 : (void)bWrite;
395 :
396 0 : float nVal = (float)0.0;
397 0 : if ( rPar.Count() == 2 )
398 : {
399 0 : SbxVariable *pSbxVariable = rPar.Get(1);
400 0 : if( pSbxVariable->GetType() == SbxSTRING )
401 : {
402 : // #41690
403 0 : double dVal = 0.0;
404 0 : OUString aScanStr = pSbxVariable->GetOUString();
405 0 : SbError Error = SbxValue::ScanNumIntnl( aScanStr, dVal, /*bSingle=*/true );
406 0 : if( SbxBase::GetError() == SbxERR_OK && Error != SbxERR_OK )
407 : {
408 0 : StarBASIC::Error( Error );
409 : }
410 0 : nVal = (float)dVal;
411 : }
412 : else
413 : {
414 0 : nVal = pSbxVariable->GetSingle();
415 : }
416 : }
417 : else
418 : {
419 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
420 : }
421 0 : rPar.Get(0)->PutSingle(nVal);
422 0 : }
423 :
424 0 : RTLFUNC(CStr) // JSM
425 : {
426 : (void)pBasic;
427 : (void)bWrite;
428 :
429 0 : OUString aString;
430 0 : if ( rPar.Count() == 2 )
431 : {
432 0 : SbxVariable *pSbxVariable = rPar.Get(1);
433 0 : aString = pSbxVariable->GetOUString();
434 : }
435 : else
436 : {
437 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
438 : }
439 0 : rPar.Get(0)->PutString(aString);
440 0 : }
441 :
442 0 : RTLFUNC(CVar) // JSM
443 : {
444 : (void)pBasic;
445 : (void)bWrite;
446 :
447 0 : SbxValues aVals( SbxVARIANT );
448 0 : if ( rPar.Count() == 2 )
449 : {
450 0 : SbxVariable *pSbxVariable = rPar.Get(1);
451 0 : pSbxVariable->Get( aVals );
452 : }
453 : else
454 : {
455 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
456 : }
457 0 : rPar.Get(0)->Put( aVals );
458 0 : }
459 :
460 0 : RTLFUNC(CVErr)
461 : {
462 : (void)pBasic;
463 : (void)bWrite;
464 :
465 0 : sal_Int16 nErrCode = 0;
466 0 : if ( rPar.Count() == 2 )
467 : {
468 0 : SbxVariable *pSbxVariable = rPar.Get(1);
469 0 : nErrCode = pSbxVariable->GetInteger();
470 : }
471 : else
472 : {
473 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
474 : }
475 0 : rPar.Get(0)->PutErr( nErrCode );
476 0 : }
477 :
478 0 : RTLFUNC(Iif) // JSM
479 : {
480 : (void)pBasic;
481 : (void)bWrite;
482 :
483 0 : if ( rPar.Count() == 4 )
484 : {
485 0 : if (rPar.Get(1)->GetBool())
486 : {
487 0 : *rPar.Get(0) = *rPar.Get(2);
488 : }
489 : else
490 : {
491 0 : *rPar.Get(0) = *rPar.Get(3);
492 : }
493 : }
494 : else
495 : {
496 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
497 : }
498 0 : }
499 :
500 0 : RTLFUNC(GetSystemType)
501 : {
502 : (void)pBasic;
503 : (void)bWrite;
504 :
505 0 : if ( rPar.Count() != 1 )
506 : {
507 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
508 : }
509 : else
510 : {
511 : // Removed for SRC595
512 0 : rPar.Get(0)->PutInteger( -1 );
513 : }
514 0 : }
515 :
516 0 : RTLFUNC(GetGUIType)
517 : {
518 : (void)pBasic;
519 : (void)bWrite;
520 :
521 0 : if ( rPar.Count() != 1 )
522 : {
523 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
524 : }
525 : else
526 : {
527 : // 17.7.2000 Make simple solution for testtool / fat office
528 : #if defined (WNT)
529 : rPar.Get(0)->PutInteger( 1 );
530 : #elif defined UNX
531 0 : rPar.Get(0)->PutInteger( 4 );
532 : #else
533 : rPar.Get(0)->PutInteger( -1 );
534 : #endif
535 : }
536 0 : }
537 :
538 0 : RTLFUNC(Red)
539 : {
540 : (void)pBasic;
541 : (void)bWrite;
542 :
543 0 : if ( rPar.Count() != 2 )
544 : {
545 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
546 : }
547 : else
548 : {
549 0 : sal_Int32 nRGB = rPar.Get(1)->GetLong();
550 0 : nRGB &= 0x00FF0000;
551 0 : nRGB >>= 16;
552 0 : rPar.Get(0)->PutInteger( (sal_Int16)nRGB );
553 : }
554 0 : }
555 :
556 0 : RTLFUNC(Green)
557 : {
558 : (void)pBasic;
559 : (void)bWrite;
560 :
561 0 : if ( rPar.Count() != 2 )
562 : {
563 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
564 : }
565 : else
566 : {
567 0 : sal_Int32 nRGB = rPar.Get(1)->GetLong();
568 0 : nRGB &= 0x0000FF00;
569 0 : nRGB >>= 8;
570 0 : rPar.Get(0)->PutInteger( (sal_Int16)nRGB );
571 : }
572 0 : }
573 :
574 0 : RTLFUNC(Blue)
575 : {
576 : (void)pBasic;
577 : (void)bWrite;
578 :
579 0 : if ( rPar.Count() != 2 )
580 : {
581 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
582 : }
583 : else
584 : {
585 0 : sal_Int32 nRGB = rPar.Get(1)->GetLong();
586 0 : nRGB &= 0x000000FF;
587 0 : rPar.Get(0)->PutInteger( (sal_Int16)nRGB );
588 : }
589 0 : }
590 :
591 :
592 0 : RTLFUNC(Switch)
593 : {
594 : (void)pBasic;
595 : (void)bWrite;
596 :
597 0 : sal_uInt16 nCount = rPar.Count();
598 0 : if( !(nCount & 0x0001 ))
599 : {
600 : // number of arguments must be odd
601 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
602 : }
603 0 : sal_uInt16 nCurExpr = 1;
604 0 : while( nCurExpr < (nCount-1) )
605 : {
606 0 : if( rPar.Get( nCurExpr )->GetBool())
607 : {
608 0 : (*rPar.Get(0)) = *(rPar.Get(nCurExpr+1));
609 0 : return;
610 : }
611 0 : nCurExpr += 2;
612 : }
613 0 : rPar.Get(0)->PutNull();
614 : }
615 :
616 : //i#64882# Common wait impl for existing Wait and new WaitUntil
617 : // rtl functions
618 0 : void Wait_Impl( bool bDurationBased, SbxArray& rPar )
619 : {
620 0 : if( rPar.Count() != 2 )
621 : {
622 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
623 0 : return;
624 : }
625 0 : long nWait = 0;
626 0 : if ( bDurationBased )
627 : {
628 0 : double dWait = rPar.Get(1)->GetDouble();
629 0 : double dNow = Now_Impl();
630 0 : double dSecs = (double)( ( dWait - dNow ) * (double)( 24.0*3600.0) );
631 0 : nWait = (long)( dSecs * 1000 ); // wait in thousands of sec
632 : }
633 : else
634 : {
635 0 : nWait = rPar.Get(1)->GetLong();
636 : }
637 0 : if( nWait < 0 )
638 : {
639 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
640 0 : return;
641 : }
642 :
643 0 : Timer aTimer;
644 0 : aTimer.SetTimeout( nWait );
645 0 : aTimer.Start();
646 0 : while ( aTimer.IsActive() )
647 : {
648 0 : Application::Yield();
649 0 : }
650 : }
651 :
652 : //i#64882#
653 0 : RTLFUNC(Wait)
654 : {
655 : (void)pBasic;
656 : (void)bWrite;
657 0 : Wait_Impl( false, rPar );
658 0 : }
659 :
660 : //i#64882# add new WaitUntil ( for application.wait )
661 : // share wait_impl with 'normal' oobasic wait
662 0 : RTLFUNC(WaitUntil)
663 : {
664 : (void)pBasic;
665 : (void)bWrite;
666 0 : Wait_Impl( true, rPar );
667 0 : }
668 :
669 0 : RTLFUNC(DoEvents)
670 : {
671 : (void)pBasic;
672 : (void)bWrite;
673 : (void)rPar;
674 : // don't undstand what upstream are up to
675 : // we already process application events etc. in between
676 : // basic runtime pcode ( on a timed basis )
677 : // always return 0
678 0 : rPar.Get(0)->PutInteger( 0 );
679 0 : Application::Reschedule( true );
680 0 : }
681 :
682 0 : RTLFUNC(GetGUIVersion)
683 : {
684 : (void)pBasic;
685 : (void)bWrite;
686 :
687 0 : if ( rPar.Count() != 1 )
688 : {
689 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
690 : }
691 : else
692 : {
693 : // Removed for SRC595
694 0 : rPar.Get(0)->PutLong( -1 );
695 : }
696 0 : }
697 :
698 0 : RTLFUNC(Choose)
699 : {
700 : (void)pBasic;
701 : (void)bWrite;
702 :
703 0 : if ( rPar.Count() < 2 )
704 : {
705 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
706 : }
707 0 : sal_Int16 nIndex = rPar.Get(1)->GetInteger();
708 0 : sal_uInt16 nCount = rPar.Count();
709 0 : nCount--;
710 0 : if( nCount == 1 || nIndex > (nCount-1) || nIndex < 1 )
711 : {
712 0 : rPar.Get(0)->PutNull();
713 0 : return;
714 : }
715 0 : (*rPar.Get(0)) = *(rPar.Get(nIndex+1));
716 : }
717 :
718 :
719 0 : RTLFUNC(Trim)
720 : {
721 : (void)pBasic;
722 : (void)bWrite;
723 :
724 0 : if ( rPar.Count() < 2 )
725 : {
726 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
727 : }
728 : else
729 : {
730 0 : OUString aStr(comphelper::string::strip(rPar.Get(1)->GetOUString(), ' '));
731 0 : rPar.Get(0)->PutString(aStr);
732 : }
733 0 : }
734 :
735 0 : RTLFUNC(GetSolarVersion)
736 : {
737 : (void)pBasic;
738 : (void)bWrite;
739 :
740 0 : rPar.Get(0)->PutLong( LIBO_VERSION_MAJOR * 10000 + LIBO_VERSION_MINOR * 100 + LIBO_VERSION_MICRO * 1);
741 0 : }
742 :
743 0 : RTLFUNC(TwipsPerPixelX)
744 : {
745 : (void)pBasic;
746 : (void)bWrite;
747 :
748 0 : sal_Int32 nResult = 0;
749 0 : Size aSize( 100,0 );
750 0 : MapMode aMap( MAP_TWIP );
751 0 : OutputDevice* pDevice = Application::GetDefaultDevice();
752 0 : if( pDevice )
753 : {
754 0 : aSize = pDevice->PixelToLogic( aSize, aMap );
755 0 : nResult = aSize.Width() / 100;
756 : }
757 0 : rPar.Get(0)->PutLong( nResult );
758 0 : }
759 :
760 0 : RTLFUNC(TwipsPerPixelY)
761 : {
762 : (void)pBasic;
763 : (void)bWrite;
764 :
765 0 : sal_Int32 nResult = 0;
766 0 : Size aSize( 0,100 );
767 0 : MapMode aMap( MAP_TWIP );
768 0 : OutputDevice* pDevice = Application::GetDefaultDevice();
769 0 : if( pDevice )
770 : {
771 0 : aSize = pDevice->PixelToLogic( aSize, aMap );
772 0 : nResult = aSize.Height() / 100;
773 : }
774 0 : rPar.Get(0)->PutLong( nResult );
775 0 : }
776 :
777 :
778 0 : RTLFUNC(FreeLibrary)
779 : {
780 : (void)pBasic;
781 : (void)bWrite;
782 :
783 0 : if ( rPar.Count() != 2 )
784 : {
785 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
786 : }
787 0 : GetSbData()->pInst->GetDllMgr()->FreeDll( rPar.Get(1)->GetOUString() );
788 0 : }
789 26 : bool IsBaseIndexOne()
790 : {
791 26 : bool result = false;
792 26 : if ( GetSbData()->pInst && GetSbData()->pInst->pRun )
793 : {
794 26 : sal_uInt16 res = GetSbData()->pInst->pRun->GetBase();
795 26 : if ( res )
796 : {
797 21 : result = true;
798 : }
799 : }
800 26 : return result;
801 : }
802 :
803 24 : RTLFUNC(Array)
804 : {
805 : (void)pBasic;
806 : (void)bWrite;
807 :
808 24 : SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
809 24 : sal_uInt16 nArraySize = rPar.Count() - 1;
810 :
811 : // ignore Option Base so far (unfortunately only known by the compiler)
812 24 : bool bIncIndex = (IsBaseIndexOne() && SbiRuntime::isVBAEnabled() );
813 24 : if( nArraySize )
814 : {
815 24 : if ( bIncIndex )
816 : {
817 21 : pArray->AddDim( 1, nArraySize );
818 : }
819 : else
820 : {
821 3 : pArray->AddDim( 0, nArraySize-1 );
822 : }
823 : }
824 : else
825 : {
826 0 : pArray->unoAddDim( 0, -1 );
827 : }
828 :
829 : // insert parameters into the array
830 : // ATTENTION: Using type sal_uInt16 for loop variable is
831 : // mandatory to workaround a problem with the
832 : // Solaris Intel compiler optimizer! See i104354
833 102 : for( sal_uInt16 i = 0 ; i < nArraySize ; i++ )
834 : {
835 78 : SbxVariable* pVar = rPar.Get(i+1);
836 78 : SbxVariable* pNew = new SbxVariable( *pVar );
837 78 : pNew->SetFlag( SBX_WRITE );
838 78 : short index = static_cast< short >(i);
839 78 : if ( bIncIndex )
840 : {
841 71 : ++index;
842 : }
843 : // coverity[callee_ptr_arith]
844 78 : pArray->Put( pNew, &index );
845 : }
846 :
847 : // return array
848 24 : SbxVariableRef refVar = rPar.Get(0);
849 24 : SbxFlagBits nFlags = refVar->GetFlags();
850 24 : refVar->ResetFlag( SBX_FIXED );
851 24 : refVar->PutObject( pArray );
852 24 : refVar->SetFlags( nFlags );
853 24 : refVar->SetParameters( NULL );
854 24 : }
855 :
856 :
857 : // Featurewish #57868
858 : // The function returns a variant-array; if there are no parameters passed,
859 : // an empty array is created (according to dim a(); equal to a sequence of
860 : // the length 0 in Uno).
861 : // If there are parameters passed, there's a dimension created for each of
862 : // them; DimArray( 2, 2, 4 ) is equal to DIM a( 2, 2, 4 )
863 : // the array is always of the type variant
864 0 : RTLFUNC(DimArray)
865 : {
866 : (void)pBasic;
867 : (void)bWrite;
868 :
869 0 : SbxDimArray * pArray = new SbxDimArray( SbxVARIANT );
870 0 : sal_uInt16 nArrayDims = rPar.Count() - 1;
871 0 : if( nArrayDims > 0 )
872 : {
873 0 : for( sal_uInt16 i = 0; i < nArrayDims ; i++ )
874 : {
875 0 : sal_Int32 ub = rPar.Get(i+1)->GetLong();
876 0 : if( ub < 0 )
877 : {
878 0 : StarBASIC::Error( SbERR_OUT_OF_RANGE );
879 0 : ub = 0;
880 : }
881 0 : pArray->AddDim32( 0, ub );
882 : }
883 : }
884 : else
885 : {
886 0 : pArray->unoAddDim( 0, -1 );
887 : }
888 0 : SbxVariableRef refVar = rPar.Get(0);
889 0 : SbxFlagBits nFlags = refVar->GetFlags();
890 0 : refVar->ResetFlag( SBX_FIXED );
891 0 : refVar->PutObject( pArray );
892 0 : refVar->SetFlags( nFlags );
893 0 : refVar->SetParameters( NULL );
894 0 : }
895 :
896 : /*
897 : * FindObject and FindPropertyObject make it possible to
898 : * address objects and properties of the type Object with
899 : * their name as string-pararmeters at the runtime.
900 : *
901 : * Example:
902 : * MyObj.Prop1.Bla = 5
903 : *
904 : * is equal to:
905 : * dim ObjVar as Object
906 : * dim ObjProp as Object
907 : * ObjName$ = "MyObj"
908 : * ObjVar = FindObject( ObjName$ )
909 : * PropName$ = "Prop1"
910 : * ObjProp = FindPropertyObject( ObjVar, PropName$ )
911 : * ObjProp.Bla = 5
912 : *
913 : * The names can be created dynamically at the runtime
914 : * so that e. g. via controls "TextEdit1" to "TextEdit5"
915 : * can be iterated in a dialog in a loop.
916 : */
917 :
918 :
919 : // 1st parameter = the object's name as string
920 0 : RTLFUNC(FindObject)
921 : {
922 : (void)pBasic;
923 : (void)bWrite;
924 :
925 0 : if ( rPar.Count() < 2 )
926 : {
927 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
928 0 : return;
929 : }
930 :
931 0 : OUString aNameStr = rPar.Get(1)->GetOUString();
932 :
933 0 : SbxBase* pFind = StarBASIC::FindSBXInCurrentScope( aNameStr );
934 0 : SbxObject* pFindObj = NULL;
935 0 : if( pFind )
936 : {
937 0 : pFindObj = PTR_CAST(SbxObject,pFind);
938 : }
939 0 : SbxVariableRef refVar = rPar.Get(0);
940 0 : refVar->PutObject( pFindObj );
941 : }
942 :
943 : // address object-property in an object
944 : // 1st parameter = object
945 : // 2nd parameter = the property's name as string
946 0 : RTLFUNC(FindPropertyObject)
947 : {
948 : (void)pBasic;
949 : (void)bWrite;
950 :
951 0 : if ( rPar.Count() < 3 )
952 : {
953 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
954 0 : return;
955 : }
956 :
957 0 : SbxBase* pObjVar = static_cast<SbxObject*>(rPar.Get(1)->GetObject());
958 0 : SbxObject* pObj = NULL;
959 0 : if( pObjVar )
960 : {
961 0 : pObj = PTR_CAST(SbxObject,pObjVar);
962 : }
963 0 : if( !pObj && pObjVar && pObjVar->ISA(SbxVariable) )
964 : {
965 0 : SbxBase* pObjVarObj = static_cast<SbxVariable*>(pObjVar)->GetObject();
966 0 : pObj = PTR_CAST(SbxObject,pObjVarObj);
967 : }
968 :
969 0 : OUString aNameStr = rPar.Get(2)->GetOUString();
970 :
971 0 : SbxObject* pFindObj = NULL;
972 0 : if( pObj )
973 : {
974 0 : SbxVariable* pFindVar = pObj->Find( aNameStr, SbxCLASS_OBJECT );
975 0 : pFindObj = PTR_CAST(SbxObject,pFindVar);
976 : }
977 : else
978 : {
979 0 : StarBASIC::Error( SbERR_BAD_PARAMETER );
980 : }
981 :
982 0 : SbxVariableRef refVar = rPar.Get(0);
983 0 : refVar->PutObject( pFindObj );
984 : }
985 :
986 :
987 :
988 0 : static bool lcl_WriteSbxVariable( const SbxVariable& rVar, SvStream* pStrm,
989 : bool bBinary, short nBlockLen, bool bIsArray )
990 : {
991 0 : sal_Size nFPos = pStrm->Tell();
992 :
993 0 : bool bIsVariant = !rVar.IsFixed();
994 0 : SbxDataType eType = rVar.GetType();
995 :
996 0 : switch( eType )
997 : {
998 : case SbxBOOL:
999 : case SbxCHAR:
1000 : case SbxBYTE:
1001 0 : if( bIsVariant )
1002 : {
1003 0 : pStrm->WriteUInt16( SbxBYTE ); // VarType Id
1004 : }
1005 0 : pStrm->WriteUChar( rVar.GetByte() );
1006 0 : break;
1007 :
1008 : case SbxEMPTY:
1009 : case SbxNULL:
1010 : case SbxVOID:
1011 : case SbxINTEGER:
1012 : case SbxUSHORT:
1013 : case SbxINT:
1014 : case SbxUINT:
1015 0 : if( bIsVariant )
1016 : {
1017 0 : pStrm->WriteUInt16( SbxINTEGER ); // VarType Id
1018 : }
1019 0 : pStrm->WriteInt16( rVar.GetInteger() );
1020 0 : break;
1021 :
1022 : case SbxLONG:
1023 : case SbxULONG:
1024 0 : if( bIsVariant )
1025 : {
1026 0 : pStrm->WriteUInt16( SbxLONG ); // VarType Id
1027 : }
1028 0 : pStrm->WriteInt32( rVar.GetLong() );
1029 0 : break;
1030 : case SbxSALINT64:
1031 : case SbxSALUINT64:
1032 0 : if( bIsVariant )
1033 : {
1034 0 : pStrm->WriteUInt16( SbxSALINT64 ); // VarType Id
1035 : }
1036 0 : pStrm->WriteUInt64( rVar.GetInt64() );
1037 0 : break;
1038 : case SbxSINGLE:
1039 0 : if( bIsVariant )
1040 : {
1041 0 : pStrm->WriteUInt16( eType ); // VarType Id
1042 : }
1043 0 : pStrm->WriteFloat( rVar.GetSingle() );
1044 0 : break;
1045 :
1046 : case SbxDOUBLE:
1047 : case SbxCURRENCY:
1048 : case SbxDATE:
1049 0 : if( bIsVariant )
1050 : {
1051 0 : pStrm->WriteUInt16( eType ); // VarType Id
1052 : }
1053 0 : pStrm->WriteDouble( rVar.GetDouble() );
1054 0 : break;
1055 :
1056 : case SbxSTRING:
1057 : case SbxLPSTR:
1058 : {
1059 0 : const OUString& rStr = rVar.GetOUString();
1060 0 : if( !bBinary || bIsArray )
1061 : {
1062 0 : if( bIsVariant )
1063 : {
1064 0 : pStrm->WriteUInt16( SbxSTRING );
1065 : }
1066 0 : pStrm->WriteUniOrByteString( rStr, osl_getThreadTextEncoding() );
1067 : }
1068 : else
1069 : {
1070 : // without any length information! without end-identifier!
1071 : // What does that mean for Unicode?! Choosing conversion to ByteString...
1072 0 : OString aByteStr(OUStringToOString(rStr, osl_getThreadTextEncoding()));
1073 0 : pStrm->WriteCharPtr( aByteStr.getStr() );
1074 0 : }
1075 : }
1076 0 : break;
1077 :
1078 : default:
1079 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1080 0 : return false;
1081 : }
1082 :
1083 0 : if( nBlockLen )
1084 : {
1085 0 : pStrm->Seek( nFPos + nBlockLen );
1086 : }
1087 0 : return pStrm->GetErrorCode() == 0;
1088 : }
1089 :
1090 0 : static bool lcl_ReadSbxVariable( SbxVariable& rVar, SvStream* pStrm,
1091 : bool bBinary, short nBlockLen, bool bIsArray )
1092 : {
1093 : (void)bBinary;
1094 : (void)bIsArray;
1095 :
1096 : double aDouble;
1097 :
1098 0 : sal_Size nFPos = pStrm->Tell();
1099 :
1100 0 : bool bIsVariant = !rVar.IsFixed();
1101 0 : SbxDataType eVarType = rVar.GetType();
1102 :
1103 0 : SbxDataType eSrcType = eVarType;
1104 0 : if( bIsVariant )
1105 : {
1106 : sal_uInt16 nTemp;
1107 0 : pStrm->ReadUInt16( nTemp );
1108 0 : eSrcType = (SbxDataType)nTemp;
1109 : }
1110 :
1111 0 : switch( eSrcType )
1112 : {
1113 : case SbxBOOL:
1114 : case SbxCHAR:
1115 : case SbxBYTE:
1116 : {
1117 : sal_uInt8 aByte;
1118 0 : pStrm->ReadUChar( aByte );
1119 :
1120 0 : if( bBinary && SbiRuntime::isVBAEnabled() && aByte == 1 && pStrm->IsEof() )
1121 : {
1122 0 : aByte = 0;
1123 : }
1124 0 : rVar.PutByte( aByte );
1125 : }
1126 0 : break;
1127 :
1128 : case SbxEMPTY:
1129 : case SbxNULL:
1130 : case SbxVOID:
1131 : case SbxINTEGER:
1132 : case SbxUSHORT:
1133 : case SbxINT:
1134 : case SbxUINT:
1135 : {
1136 : sal_Int16 aInt;
1137 0 : pStrm->ReadInt16( aInt );
1138 0 : rVar.PutInteger( aInt );
1139 : }
1140 0 : break;
1141 :
1142 : case SbxLONG:
1143 : case SbxULONG:
1144 : {
1145 : sal_Int32 aInt;
1146 0 : pStrm->ReadInt32( aInt );
1147 0 : rVar.PutLong( aInt );
1148 : }
1149 0 : break;
1150 : case SbxSALINT64:
1151 : case SbxSALUINT64:
1152 : {
1153 : sal_uInt32 aInt;
1154 0 : pStrm->ReadUInt32( aInt );
1155 0 : rVar.PutInt64( (sal_Int64)aInt );
1156 : }
1157 0 : break;
1158 : case SbxSINGLE:
1159 : {
1160 : float nS;
1161 0 : pStrm->ReadFloat( nS );
1162 0 : rVar.PutSingle( nS );
1163 : }
1164 0 : break;
1165 :
1166 : case SbxDOUBLE:
1167 : case SbxCURRENCY:
1168 : {
1169 0 : pStrm->ReadDouble( aDouble );
1170 0 : rVar.PutDouble( aDouble );
1171 : }
1172 0 : break;
1173 :
1174 : case SbxDATE:
1175 : {
1176 0 : pStrm->ReadDouble( aDouble );
1177 0 : rVar.PutDate( aDouble );
1178 : }
1179 0 : break;
1180 :
1181 : case SbxSTRING:
1182 : case SbxLPSTR:
1183 : {
1184 0 : OUString aStr = pStrm->ReadUniOrByteString(osl_getThreadTextEncoding());
1185 0 : rVar.PutString( aStr );
1186 : }
1187 0 : break;
1188 :
1189 : default:
1190 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1191 0 : return false;
1192 : }
1193 :
1194 0 : if( nBlockLen )
1195 : {
1196 0 : pStrm->Seek( nFPos + nBlockLen );
1197 : }
1198 0 : return pStrm->GetErrorCode() == 0;
1199 : }
1200 :
1201 :
1202 : // nCurDim = 1...n
1203 0 : static bool lcl_WriteReadSbxArray( SbxDimArray& rArr, SvStream* pStrm,
1204 : bool bBinary, short nCurDim, short* pOtherDims, bool bWrite )
1205 : {
1206 : SAL_WARN_IF( nCurDim <= 0,"basic", "Bad Dim");
1207 : short nLower, nUpper;
1208 0 : if( !rArr.GetDim( nCurDim, nLower, nUpper ) )
1209 0 : return false;
1210 0 : for( short nCur = nLower; nCur <= nUpper; nCur++ )
1211 : {
1212 0 : pOtherDims[ nCurDim-1 ] = nCur;
1213 0 : if( nCurDim != 1 )
1214 0 : lcl_WriteReadSbxArray(rArr, pStrm, bBinary, nCurDim-1, pOtherDims, bWrite);
1215 : else
1216 : {
1217 0 : SbxVariable* pVar = rArr.Get( const_cast<const short*>(pOtherDims) );
1218 : bool bRet;
1219 0 : if( bWrite )
1220 0 : bRet = lcl_WriteSbxVariable(*pVar, pStrm, bBinary, 0, true );
1221 : else
1222 0 : bRet = lcl_ReadSbxVariable(*pVar, pStrm, bBinary, 0, true );
1223 0 : if( !bRet )
1224 0 : return false;
1225 : }
1226 : }
1227 0 : return true;
1228 : }
1229 :
1230 0 : void PutGet( SbxArray& rPar, bool bPut )
1231 : {
1232 0 : if ( rPar.Count() != 4 )
1233 : {
1234 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1235 0 : return;
1236 : }
1237 0 : sal_Int16 nFileNo = rPar.Get(1)->GetInteger();
1238 0 : SbxVariable* pVar2 = rPar.Get(2);
1239 0 : SbxDataType eType2 = pVar2->GetType();
1240 0 : bool bHasRecordNo = (eType2 != SbxEMPTY && eType2 != SbxERROR);
1241 0 : long nRecordNo = pVar2->GetLong();
1242 0 : if ( nFileNo < 1 || ( bHasRecordNo && nRecordNo < 1 ) )
1243 : {
1244 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1245 0 : return;
1246 : }
1247 0 : nRecordNo--;
1248 0 : SbiIoSystem* pIO = GetSbData()->pInst->GetIoSystem();
1249 0 : SbiStream* pSbStrm = pIO->GetStream( nFileNo );
1250 :
1251 0 : if ( !pSbStrm || !(pSbStrm->GetMode() & (SBSTRM_BINARY | SBSTRM_RANDOM)) )
1252 : {
1253 0 : StarBASIC::Error( SbERR_BAD_CHANNEL );
1254 0 : return;
1255 : }
1256 :
1257 0 : SvStream* pStrm = pSbStrm->GetStrm();
1258 0 : bool bRandom = pSbStrm->IsRandom();
1259 0 : short nBlockLen = bRandom ? pSbStrm->GetBlockLen() : 0;
1260 :
1261 0 : if( bPut )
1262 : {
1263 0 : pSbStrm->ExpandFile();
1264 : }
1265 :
1266 0 : if( bHasRecordNo )
1267 : {
1268 0 : sal_Size nFilePos = bRandom ? (sal_Size)(nBlockLen * nRecordNo) : (sal_Size)nRecordNo;
1269 0 : pStrm->Seek( nFilePos );
1270 : }
1271 :
1272 0 : SbxDimArray* pArr = 0;
1273 0 : SbxVariable* pVar = rPar.Get(3);
1274 0 : if( pVar->GetType() & SbxARRAY )
1275 : {
1276 0 : SbxBase* pParObj = pVar->GetObject();
1277 0 : pArr = PTR_CAST(SbxDimArray,pParObj);
1278 : }
1279 :
1280 : bool bRet;
1281 :
1282 0 : if( pArr )
1283 : {
1284 0 : sal_Size nFPos = pStrm->Tell();
1285 0 : short nDims = pArr->GetDims();
1286 0 : boost::scoped_array<short> pDims(new short[ nDims ]);
1287 0 : bRet = lcl_WriteReadSbxArray(*pArr,pStrm,!bRandom,nDims,pDims.get(),bPut);
1288 0 : pDims.reset();
1289 0 : if( nBlockLen )
1290 0 : pStrm->Seek( nFPos + nBlockLen );
1291 : }
1292 : else
1293 : {
1294 0 : if( bPut )
1295 0 : bRet = lcl_WriteSbxVariable(*pVar, pStrm, !bRandom, nBlockLen, false);
1296 : else
1297 0 : bRet = lcl_ReadSbxVariable(*pVar, pStrm, !bRandom, nBlockLen, false);
1298 : }
1299 0 : if( !bRet || pStrm->GetErrorCode() )
1300 0 : StarBASIC::Error( SbERR_IO_ERROR );
1301 : }
1302 :
1303 0 : RTLFUNC(Put)
1304 : {
1305 : (void)pBasic;
1306 : (void)bWrite;
1307 :
1308 0 : PutGet( rPar, true );
1309 0 : }
1310 :
1311 0 : RTLFUNC(Get)
1312 : {
1313 : (void)pBasic;
1314 : (void)bWrite;
1315 :
1316 0 : PutGet( rPar, false );
1317 0 : }
1318 :
1319 1 : RTLFUNC(Environ)
1320 : {
1321 : (void)pBasic;
1322 : (void)bWrite;
1323 :
1324 1 : if ( rPar.Count() != 2 )
1325 : {
1326 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1327 1 : return;
1328 : }
1329 1 : OUString aResult;
1330 : // should be ANSI but that's not possible under Win16 in the DLL
1331 1 : OString aByteStr(OUStringToOString(rPar.Get(1)->GetOUString(),
1332 3 : osl_getThreadTextEncoding()));
1333 1 : const char* pEnvStr = getenv(aByteStr.getStr());
1334 1 : if ( pEnvStr )
1335 : {
1336 1 : aResult = OUString(pEnvStr, strlen(pEnvStr), osl_getThreadTextEncoding());
1337 : }
1338 2 : rPar.Get(0)->PutString( aResult );
1339 : }
1340 :
1341 0 : static double GetDialogZoomFactor( bool bX, long nValue )
1342 : {
1343 0 : OutputDevice* pDevice = Application::GetDefaultDevice();
1344 0 : double nResult = 0;
1345 0 : if( pDevice )
1346 : {
1347 0 : Size aRefSize( nValue, nValue );
1348 0 : Fraction aFracX( 1, 26 );
1349 0 : Fraction aFracY( 1, 24 );
1350 0 : MapMode aMap( MAP_APPFONT, Point(), aFracX, aFracY );
1351 0 : Size aScaledSize = pDevice->LogicToPixel( aRefSize, aMap );
1352 0 : aRefSize = pDevice->LogicToPixel( aRefSize, MapMode(MAP_TWIP) );
1353 :
1354 : double nRef, nScaled;
1355 0 : if( bX )
1356 : {
1357 0 : nRef = aRefSize.Width();
1358 0 : nScaled = aScaledSize.Width();
1359 : }
1360 : else
1361 : {
1362 0 : nRef = aRefSize.Height();
1363 0 : nScaled = aScaledSize.Height();
1364 : }
1365 0 : nResult = nScaled / nRef;
1366 : }
1367 0 : return nResult;
1368 : }
1369 :
1370 :
1371 0 : RTLFUNC(GetDialogZoomFactorX)
1372 : {
1373 : (void)pBasic;
1374 : (void)bWrite;
1375 :
1376 0 : if ( rPar.Count() != 2 )
1377 : {
1378 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1379 0 : return;
1380 : }
1381 0 : rPar.Get(0)->PutDouble( GetDialogZoomFactor( true, rPar.Get(1)->GetLong() ));
1382 : }
1383 :
1384 0 : RTLFUNC(GetDialogZoomFactorY)
1385 : {
1386 : (void)pBasic;
1387 : (void)bWrite;
1388 :
1389 0 : if ( rPar.Count() != 2 )
1390 : {
1391 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1392 0 : return;
1393 : }
1394 0 : rPar.Get(0)->PutDouble( GetDialogZoomFactor( false, rPar.Get(1)->GetLong()));
1395 : }
1396 :
1397 :
1398 0 : RTLFUNC(EnableReschedule)
1399 : {
1400 : (void)pBasic;
1401 : (void)bWrite;
1402 :
1403 0 : rPar.Get(0)->PutEmpty();
1404 0 : if ( rPar.Count() != 2 )
1405 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1406 0 : if( GetSbData()->pInst )
1407 0 : GetSbData()->pInst->EnableReschedule( rPar.Get(1)->GetBool() );
1408 0 : }
1409 :
1410 0 : RTLFUNC(GetSystemTicks)
1411 : {
1412 : (void)pBasic;
1413 : (void)bWrite;
1414 :
1415 0 : if ( rPar.Count() != 1 )
1416 : {
1417 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1418 0 : return;
1419 : }
1420 0 : rPar.Get(0)->PutLong( tools::Time::GetSystemTicks() );
1421 : }
1422 :
1423 0 : RTLFUNC(GetPathSeparator)
1424 : {
1425 : (void)pBasic;
1426 : (void)bWrite;
1427 :
1428 0 : if ( rPar.Count() != 1 )
1429 : {
1430 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1431 0 : return;
1432 : }
1433 0 : rPar.Get(0)->PutString( OUString( SAL_PATHDELIMITER ) );
1434 : }
1435 :
1436 0 : RTLFUNC(ResolvePath)
1437 : {
1438 : (void)pBasic;
1439 : (void)bWrite;
1440 :
1441 0 : if ( rPar.Count() == 2 )
1442 : {
1443 0 : OUString aStr = rPar.Get(1)->GetOUString();
1444 0 : rPar.Get(0)->PutString( aStr );
1445 : }
1446 : else
1447 : {
1448 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1449 : }
1450 0 : }
1451 :
1452 0 : RTLFUNC(TypeLen)
1453 : {
1454 : (void)pBasic;
1455 : (void)bWrite;
1456 :
1457 0 : if ( rPar.Count() != 2 )
1458 : {
1459 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1460 : }
1461 : else
1462 : {
1463 0 : SbxDataType eType = rPar.Get(1)->GetType();
1464 0 : sal_Int16 nLen = 0;
1465 0 : switch( eType )
1466 : {
1467 : case SbxEMPTY:
1468 : case SbxNULL:
1469 : case SbxVECTOR:
1470 : case SbxARRAY:
1471 : case SbxBYREF:
1472 : case SbxVOID:
1473 : case SbxHRESULT:
1474 : case SbxPOINTER:
1475 : case SbxDIMARRAY:
1476 : case SbxCARRAY:
1477 : case SbxUSERDEF:
1478 0 : nLen = 0;
1479 0 : break;
1480 :
1481 : case SbxINTEGER:
1482 : case SbxERROR:
1483 : case SbxUSHORT:
1484 : case SbxINT:
1485 : case SbxUINT:
1486 0 : nLen = 2;
1487 0 : break;
1488 :
1489 : case SbxLONG:
1490 : case SbxSINGLE:
1491 : case SbxULONG:
1492 0 : nLen = 4;
1493 0 : break;
1494 :
1495 : case SbxDOUBLE:
1496 : case SbxCURRENCY:
1497 : case SbxDATE:
1498 : case SbxSALINT64:
1499 : case SbxSALUINT64:
1500 0 : nLen = 8;
1501 0 : break;
1502 :
1503 : case SbxOBJECT:
1504 : case SbxVARIANT:
1505 : case SbxDATAOBJECT:
1506 0 : nLen = 0;
1507 0 : break;
1508 :
1509 : case SbxCHAR:
1510 : case SbxBYTE:
1511 : case SbxBOOL:
1512 0 : nLen = 1;
1513 0 : break;
1514 :
1515 : case SbxLPSTR:
1516 : case SbxLPWSTR:
1517 : case SbxCoreSTRING:
1518 : case SbxSTRING:
1519 0 : nLen = (sal_Int16)rPar.Get(1)->GetOUString().getLength();
1520 0 : break;
1521 :
1522 : default:
1523 0 : nLen = 0;
1524 0 : break;
1525 : }
1526 0 : rPar.Get(0)->PutInteger( nLen );
1527 : }
1528 0 : }
1529 :
1530 :
1531 : // 1st parameter == class name, other parameters for initialisation
1532 37 : RTLFUNC(CreateUnoStruct)
1533 : {
1534 : (void)pBasic;
1535 : (void)bWrite;
1536 :
1537 37 : RTL_Impl_CreateUnoStruct( pBasic, rPar, bWrite );
1538 37 : }
1539 :
1540 :
1541 : // 1st parameter == service-name
1542 31 : RTLFUNC(CreateUnoService)
1543 : {
1544 : (void)pBasic;
1545 : (void)bWrite;
1546 :
1547 31 : RTL_Impl_CreateUnoService( pBasic, rPar, bWrite );
1548 31 : }
1549 :
1550 0 : RTLFUNC(CreateUnoServiceWithArguments)
1551 : {
1552 : (void)pBasic;
1553 : (void)bWrite;
1554 :
1555 0 : RTL_Impl_CreateUnoServiceWithArguments( pBasic, rPar, bWrite );
1556 0 : }
1557 :
1558 :
1559 0 : RTLFUNC(CreateUnoValue)
1560 : {
1561 : (void)pBasic;
1562 : (void)bWrite;
1563 :
1564 0 : RTL_Impl_CreateUnoValue( pBasic, rPar, bWrite );
1565 0 : }
1566 :
1567 :
1568 : // no parameters
1569 0 : RTLFUNC(GetProcessServiceManager)
1570 : {
1571 : (void)pBasic;
1572 : (void)bWrite;
1573 :
1574 0 : RTL_Impl_GetProcessServiceManager( pBasic, rPar, bWrite );
1575 0 : }
1576 :
1577 :
1578 : // 1st parameter == Sequence<PropertyValue>
1579 0 : RTLFUNC(CreatePropertySet)
1580 : {
1581 : (void)pBasic;
1582 : (void)bWrite;
1583 :
1584 0 : RTL_Impl_CreatePropertySet( pBasic, rPar, bWrite );
1585 0 : }
1586 :
1587 :
1588 : // multiple interface-names as parameters
1589 0 : RTLFUNC(HasUnoInterfaces)
1590 : {
1591 : (void)pBasic;
1592 : (void)bWrite;
1593 :
1594 0 : RTL_Impl_HasInterfaces( pBasic, rPar, bWrite );
1595 0 : }
1596 :
1597 :
1598 0 : RTLFUNC(IsUnoStruct)
1599 : {
1600 : (void)pBasic;
1601 : (void)bWrite;
1602 :
1603 0 : RTL_Impl_IsUnoStruct( pBasic, rPar, bWrite );
1604 0 : }
1605 :
1606 :
1607 0 : RTLFUNC(EqualUnoObjects)
1608 : {
1609 : (void)pBasic;
1610 : (void)bWrite;
1611 :
1612 0 : RTL_Impl_EqualUnoObjects( pBasic, rPar, bWrite );
1613 0 : }
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, INetProtocol::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 0 : return;
1723 : }
1724 0 : OUString aDelim;
1725 0 : if( nParCount == 3 )
1726 : {
1727 0 : aDelim = rPar.Get(2)->GetOUString();
1728 : }
1729 : else
1730 : {
1731 0 : aDelim = " ";
1732 : }
1733 0 : OUString aRetStr;
1734 : short nLower, nUpper;
1735 0 : pArr->GetDim( 1, nLower, nUpper );
1736 0 : for (short i = nLower; i <= nUpper; ++i)
1737 : {
1738 : // coverity[callee_ptr_arith]
1739 0 : OUString aStr = pArr->Get( &i )->GetOUString();
1740 0 : aRetStr += aStr;
1741 0 : if( i != nUpper )
1742 : {
1743 0 : aRetStr += aDelim;
1744 : }
1745 0 : }
1746 0 : rPar.Get(0)->PutString( aRetStr );
1747 : }
1748 : else
1749 : {
1750 0 : StarBASIC::Error( SbERR_MUST_HAVE_DIMS );
1751 : }
1752 : }
1753 :
1754 :
1755 0 : RTLFUNC(Split)
1756 : {
1757 : (void)pBasic;
1758 : (void)bWrite;
1759 :
1760 0 : sal_uInt16 nParCount = rPar.Count();
1761 0 : if ( nParCount < 2 )
1762 : {
1763 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1764 0 : return;
1765 : }
1766 :
1767 0 : OUString aExpression = rPar.Get(1)->GetOUString();
1768 0 : short nArraySize = 0;
1769 0 : StringVector vRet;
1770 0 : if( !aExpression.isEmpty() )
1771 : {
1772 0 : OUString aDelim;
1773 0 : if( nParCount >= 3 )
1774 : {
1775 0 : aDelim = rPar.Get(2)->GetOUString();
1776 : }
1777 : else
1778 : {
1779 0 : aDelim = " ";
1780 : }
1781 :
1782 0 : sal_Int32 nCount = -1;
1783 0 : if( nParCount == 4 )
1784 : {
1785 0 : nCount = rPar.Get(3)->GetLong();
1786 : }
1787 0 : sal_Int32 nDelimLen = aDelim.getLength();
1788 0 : if( nDelimLen )
1789 : {
1790 0 : sal_Int32 iSearch = -1;
1791 0 : sal_Int32 iStart = 0;
1792 0 : do
1793 : {
1794 0 : bool bBreak = false;
1795 0 : if( nCount >= 0 && nArraySize == nCount - 1 )
1796 : {
1797 0 : bBreak = true;
1798 : }
1799 0 : iSearch = aExpression.indexOf( aDelim, iStart );
1800 0 : OUString aSubStr;
1801 0 : if( iSearch >= 0 && !bBreak )
1802 : {
1803 0 : aSubStr = aExpression.copy( iStart, iSearch - iStart );
1804 0 : iStart = iSearch + nDelimLen;
1805 : }
1806 : else
1807 : {
1808 0 : aSubStr = aExpression.copy( iStart );
1809 : }
1810 0 : vRet.push_back( aSubStr );
1811 0 : nArraySize++;
1812 :
1813 0 : if( bBreak )
1814 : {
1815 0 : break;
1816 0 : }
1817 : }
1818 : while( iSearch >= 0 );
1819 : }
1820 : else
1821 : {
1822 0 : vRet.push_back( aExpression );
1823 0 : nArraySize = 1;
1824 0 : }
1825 : }
1826 :
1827 0 : SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
1828 0 : pArray->unoAddDim( 0, nArraySize-1 );
1829 :
1830 : // insert parameter(s) into the array
1831 0 : for( short i = 0 ; i < nArraySize ; i++ )
1832 : {
1833 0 : SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
1834 0 : xVar->PutString( vRet[i] );
1835 0 : pArray->Put( xVar.get(), &i );
1836 0 : }
1837 :
1838 : // return array
1839 0 : SbxVariableRef refVar = rPar.Get(0);
1840 0 : SbxFlagBits nFlags = refVar->GetFlags();
1841 0 : refVar->ResetFlag( SBX_FIXED );
1842 0 : refVar->PutObject( pArray );
1843 0 : refVar->SetFlags( nFlags );
1844 0 : refVar->SetParameters( NULL );
1845 : }
1846 :
1847 : // MonthName(month[, abbreviate])
1848 0 : RTLFUNC(MonthName)
1849 : {
1850 : (void)pBasic;
1851 : (void)bWrite;
1852 :
1853 0 : sal_uInt16 nParCount = rPar.Count();
1854 0 : if( nParCount != 2 && nParCount != 3 )
1855 : {
1856 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1857 0 : return;
1858 : }
1859 :
1860 0 : Reference< XCalendar4 > xCalendar = getLocaleCalendar();
1861 0 : if( !xCalendar.is() )
1862 : {
1863 0 : StarBASIC::Error( SbERR_INTERNAL_ERROR );
1864 0 : return;
1865 : }
1866 0 : Sequence< CalendarItem2 > aMonthSeq = xCalendar->getMonths2();
1867 0 : sal_Int32 nMonthCount = aMonthSeq.getLength();
1868 :
1869 0 : sal_Int16 nVal = rPar.Get(1)->GetInteger();
1870 0 : if( nVal < 1 || nVal > nMonthCount )
1871 : {
1872 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1873 0 : return;
1874 : }
1875 :
1876 0 : bool bAbbreviate = false;
1877 0 : if( nParCount == 3 )
1878 0 : bAbbreviate = rPar.Get(2)->GetBool();
1879 :
1880 0 : const CalendarItem2* pCalendarItems = aMonthSeq.getConstArray();
1881 0 : const CalendarItem2& rItem = pCalendarItems[nVal - 1];
1882 :
1883 0 : OUString aRetStr = ( bAbbreviate ? rItem.AbbrevName : rItem.FullName );
1884 0 : rPar.Get(0)->PutString(aRetStr);
1885 : }
1886 :
1887 : // WeekdayName(weekday, abbreviate, firstdayofweek)
1888 0 : RTLFUNC(WeekdayName)
1889 : {
1890 : (void)pBasic;
1891 : (void)bWrite;
1892 :
1893 0 : sal_uInt16 nParCount = rPar.Count();
1894 0 : if( nParCount < 2 || nParCount > 4 )
1895 : {
1896 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1897 0 : return;
1898 : }
1899 :
1900 0 : Reference< XCalendar4 > xCalendar = getLocaleCalendar();
1901 0 : if( !xCalendar.is() )
1902 : {
1903 0 : StarBASIC::Error( SbERR_INTERNAL_ERROR );
1904 0 : return;
1905 : }
1906 :
1907 0 : Sequence< CalendarItem2 > aDaySeq = xCalendar->getDays2();
1908 0 : sal_Int16 nDayCount = (sal_Int16)aDaySeq.getLength();
1909 0 : sal_Int16 nDay = rPar.Get(1)->GetInteger();
1910 0 : sal_Int16 nFirstDay = 0;
1911 0 : if( nParCount == 4 )
1912 : {
1913 0 : nFirstDay = rPar.Get(3)->GetInteger();
1914 0 : if( nFirstDay < 0 || nFirstDay > 7 )
1915 : {
1916 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1917 0 : return;
1918 : }
1919 : }
1920 0 : if( nFirstDay == 0 )
1921 : {
1922 0 : nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 );
1923 : }
1924 0 : nDay = 1 + (nDay + nDayCount + nFirstDay - 2) % nDayCount;
1925 0 : if( nDay < 1 || nDay > nDayCount )
1926 : {
1927 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1928 0 : return;
1929 : }
1930 :
1931 0 : bool bAbbreviate = false;
1932 0 : if( nParCount >= 3 )
1933 : {
1934 0 : SbxVariable* pPar2 = rPar.Get(2);
1935 0 : if( !pPar2->IsErr() )
1936 : {
1937 0 : bAbbreviate = pPar2->GetBool();
1938 : }
1939 : }
1940 :
1941 0 : const CalendarItem2* pCalendarItems = aDaySeq.getConstArray();
1942 0 : const CalendarItem2& rItem = pCalendarItems[nDay - 1];
1943 :
1944 0 : OUString aRetStr = ( bAbbreviate ? rItem.AbbrevName : rItem.FullName );
1945 0 : rPar.Get(0)->PutString( aRetStr );
1946 : }
1947 :
1948 0 : RTLFUNC(Weekday)
1949 : {
1950 : (void)pBasic;
1951 : (void)bWrite;
1952 :
1953 0 : sal_uInt16 nParCount = rPar.Count();
1954 0 : if ( nParCount < 2 )
1955 : {
1956 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1957 : }
1958 : else
1959 : {
1960 0 : double aDate = rPar.Get(1)->GetDate();
1961 :
1962 0 : bool bFirstDay = false;
1963 0 : sal_Int16 nFirstDay = 0;
1964 0 : if ( nParCount > 2 )
1965 : {
1966 0 : nFirstDay = rPar.Get(2)->GetInteger();
1967 0 : bFirstDay = true;
1968 : }
1969 0 : sal_Int16 nDay = implGetWeekDay( aDate, bFirstDay, nFirstDay );
1970 0 : rPar.Get(0)->PutInteger( nDay );
1971 : }
1972 0 : }
1973 :
1974 :
1975 : enum Interval
1976 : {
1977 : INTERVAL_YYYY,
1978 : INTERVAL_Q,
1979 : INTERVAL_M,
1980 : INTERVAL_Y,
1981 : INTERVAL_D,
1982 : INTERVAL_W,
1983 : INTERVAL_WW,
1984 : INTERVAL_H,
1985 : INTERVAL_N,
1986 : INTERVAL_S
1987 : };
1988 :
1989 : struct IntervalInfo
1990 : {
1991 : Interval meInterval;
1992 : char const * mStringCode;
1993 : double mdValue;
1994 : bool mbSimple;
1995 : };
1996 :
1997 0 : IntervalInfo const * getIntervalInfo( const OUString& rStringCode )
1998 : {
1999 : static IntervalInfo const aIntervalTable[] =
2000 : {
2001 : { INTERVAL_YYYY, "yyyy", 0.0, false }, // Year
2002 : { INTERVAL_Q, "q", 0.0, false }, // Quarter
2003 : { INTERVAL_M, "m", 0.0, false }, // Month
2004 : { INTERVAL_Y, "y", 1.0, true }, // Day of year
2005 : { INTERVAL_D, "d", 1.0, true }, // Day
2006 : { INTERVAL_W, "w", 1.0, true }, // Weekday
2007 : { INTERVAL_WW, "ww", 7.0, true }, // Week
2008 : { INTERVAL_H, "h", 1.0 / 24.0, true }, // Hour
2009 : { INTERVAL_N, "n", 1.0 / 1440.0, true }, // Minute
2010 : { INTERVAL_S, "s", 1.0 / 86400.0, true } // Second
2011 : };
2012 0 : for( std::size_t i = 0; i != SAL_N_ELEMENTS(aIntervalTable); ++i )
2013 : {
2014 0 : if( rStringCode.equalsIgnoreAsciiCaseAscii(
2015 0 : aIntervalTable[i].mStringCode ) )
2016 : {
2017 0 : return &aIntervalTable[i];
2018 : }
2019 : }
2020 0 : return NULL;
2021 : }
2022 :
2023 0 : inline void implGetDayMonthYear( sal_Int16& rnYear, sal_Int16& rnMonth, sal_Int16& rnDay, double dDate )
2024 : {
2025 0 : rnDay = implGetDateDay( dDate );
2026 0 : rnMonth = implGetDateMonth( dDate );
2027 0 : rnYear = implGetDateYear( dDate );
2028 0 : }
2029 :
2030 0 : inline sal_Int16 limitToINT16( sal_Int32 n32 )
2031 : {
2032 0 : if( n32 > 32767 )
2033 : {
2034 0 : n32 = 32767;
2035 : }
2036 0 : else if( n32 < -32768 )
2037 : {
2038 0 : n32 = -32768;
2039 : }
2040 0 : return (sal_Int16)n32;
2041 : }
2042 :
2043 0 : RTLFUNC(DateAdd)
2044 : {
2045 : (void)pBasic;
2046 : (void)bWrite;
2047 :
2048 0 : sal_uInt16 nParCount = rPar.Count();
2049 0 : if( nParCount != 4 )
2050 : {
2051 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2052 0 : return;
2053 : }
2054 :
2055 0 : OUString aStringCode = rPar.Get(1)->GetOUString();
2056 0 : IntervalInfo const * pInfo = getIntervalInfo( aStringCode );
2057 0 : if( !pInfo )
2058 : {
2059 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2060 0 : return;
2061 : }
2062 :
2063 0 : sal_Int32 lNumber = rPar.Get(2)->GetLong();
2064 0 : double dDate = rPar.Get(3)->GetDate();
2065 0 : double dNewDate = 0;
2066 0 : if( pInfo->mbSimple )
2067 : {
2068 0 : double dAdd = pInfo->mdValue * lNumber;
2069 0 : dNewDate = dDate + dAdd;
2070 : }
2071 : else
2072 : {
2073 : // Keep hours, minutes, seconds
2074 0 : double dHoursMinutesSeconds = dDate - floor( dDate );
2075 :
2076 0 : bool bOk = true;
2077 : sal_Int16 nYear, nMonth, nDay;
2078 0 : sal_Int16 nTargetYear16 = 0, nTargetMonth = 0;
2079 0 : implGetDayMonthYear( nYear, nMonth, nDay, dDate );
2080 0 : switch( pInfo->meInterval )
2081 : {
2082 : case INTERVAL_YYYY:
2083 : {
2084 0 : sal_Int32 nTargetYear = lNumber + nYear;
2085 0 : nTargetYear16 = limitToINT16( nTargetYear );
2086 0 : nTargetMonth = nMonth;
2087 0 : bOk = implDateSerial( nTargetYear16, nTargetMonth, nDay, dNewDate );
2088 0 : break;
2089 : }
2090 : case INTERVAL_Q:
2091 : case INTERVAL_M:
2092 : {
2093 0 : bool bNeg = (lNumber < 0);
2094 0 : if( bNeg )
2095 0 : lNumber = -lNumber;
2096 : sal_Int32 nYearsAdd;
2097 : sal_Int16 nMonthAdd;
2098 0 : if( pInfo->meInterval == INTERVAL_Q )
2099 : {
2100 0 : nYearsAdd = lNumber / 4;
2101 0 : nMonthAdd = (sal_Int16)( 3 * (lNumber % 4) );
2102 : }
2103 : else
2104 : {
2105 0 : nYearsAdd = lNumber / 12;
2106 0 : nMonthAdd = (sal_Int16)( lNumber % 12 );
2107 : }
2108 :
2109 : sal_Int32 nTargetYear;
2110 0 : if( bNeg )
2111 : {
2112 0 : nTargetMonth = nMonth - nMonthAdd;
2113 0 : if( nTargetMonth <= 0 )
2114 : {
2115 0 : nTargetMonth += 12;
2116 0 : nYearsAdd++;
2117 : }
2118 0 : nTargetYear = (sal_Int32)nYear - nYearsAdd;
2119 : }
2120 : else
2121 : {
2122 0 : nTargetMonth = nMonth + nMonthAdd;
2123 0 : if( nTargetMonth > 12 )
2124 : {
2125 0 : nTargetMonth -= 12;
2126 0 : nYearsAdd++;
2127 : }
2128 0 : nTargetYear = (sal_Int32)nYear + nYearsAdd;
2129 : }
2130 0 : nTargetYear16 = limitToINT16( nTargetYear );
2131 0 : bOk = implDateSerial( nTargetYear16, nTargetMonth, nDay, dNewDate );
2132 0 : break;
2133 : }
2134 0 : default: break;
2135 : }
2136 :
2137 0 : if( bOk )
2138 : {
2139 : // Overflow?
2140 : sal_Int16 nNewYear, nNewMonth, nNewDay;
2141 0 : implGetDayMonthYear( nNewYear, nNewMonth, nNewDay, dNewDate );
2142 0 : if( nNewYear > 9999 || nNewYear < 100 )
2143 : {
2144 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2145 0 : return;
2146 : }
2147 0 : sal_Int16 nCorrectionDay = nDay;
2148 0 : while( nNewMonth > nTargetMonth )
2149 : {
2150 0 : nCorrectionDay--;
2151 0 : implDateSerial( nTargetYear16, nTargetMonth, nCorrectionDay, dNewDate );
2152 0 : implGetDayMonthYear( nNewYear, nNewMonth, nNewDay, dNewDate );
2153 : }
2154 0 : dNewDate += dHoursMinutesSeconds;
2155 : }
2156 : }
2157 :
2158 0 : rPar.Get(0)->PutDate( dNewDate );
2159 : }
2160 :
2161 0 : inline double RoundImpl( double d )
2162 : {
2163 0 : return ( d >= 0 ) ? floor( d + 0.5 ) : -floor( -d + 0.5 );
2164 : }
2165 :
2166 0 : RTLFUNC(DateDiff)
2167 : {
2168 : (void)pBasic;
2169 : (void)bWrite;
2170 :
2171 : // DateDiff(interval, date1, date2[, firstdayofweek[, firstweekofyear]])
2172 :
2173 0 : sal_uInt16 nParCount = rPar.Count();
2174 0 : if( nParCount < 4 || nParCount > 6 )
2175 : {
2176 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2177 0 : return;
2178 : }
2179 :
2180 0 : OUString aStringCode = rPar.Get(1)->GetOUString();
2181 0 : IntervalInfo const * pInfo = getIntervalInfo( aStringCode );
2182 0 : if( !pInfo )
2183 : {
2184 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2185 0 : return;
2186 : }
2187 :
2188 0 : double dDate1 = rPar.Get(2)->GetDate();
2189 0 : double dDate2 = rPar.Get(3)->GetDate();
2190 :
2191 0 : double dRet = 0.0;
2192 0 : switch( pInfo->meInterval )
2193 : {
2194 : case INTERVAL_YYYY:
2195 : {
2196 0 : sal_Int16 nYear1 = implGetDateYear( dDate1 );
2197 0 : sal_Int16 nYear2 = implGetDateYear( dDate2 );
2198 0 : dRet = nYear2 - nYear1;
2199 0 : break;
2200 : }
2201 : case INTERVAL_Q:
2202 : {
2203 0 : sal_Int16 nYear1 = implGetDateYear( dDate1 );
2204 0 : sal_Int16 nYear2 = implGetDateYear( dDate2 );
2205 0 : sal_Int16 nQ1 = 1 + (implGetDateMonth( dDate1 ) - 1) / 3;
2206 0 : sal_Int16 nQ2 = 1 + (implGetDateMonth( dDate2 ) - 1) / 3;
2207 0 : sal_Int16 nQGes1 = 4 * nYear1 + nQ1;
2208 0 : sal_Int16 nQGes2 = 4 * nYear2 + nQ2;
2209 0 : dRet = nQGes2 - nQGes1;
2210 0 : break;
2211 : }
2212 : case INTERVAL_M:
2213 : {
2214 0 : sal_Int16 nYear1 = implGetDateYear( dDate1 );
2215 0 : sal_Int16 nYear2 = implGetDateYear( dDate2 );
2216 0 : sal_Int16 nMonth1 = implGetDateMonth( dDate1 );
2217 0 : sal_Int16 nMonth2 = implGetDateMonth( dDate2 );
2218 0 : sal_Int16 nMonthGes1 = 12 * nYear1 + nMonth1;
2219 0 : sal_Int16 nMonthGes2 = 12 * nYear2 + nMonth2;
2220 0 : dRet = nMonthGes2 - nMonthGes1;
2221 0 : break;
2222 : }
2223 : case INTERVAL_Y:
2224 : case INTERVAL_D:
2225 : {
2226 0 : double dDays1 = floor( dDate1 );
2227 0 : double dDays2 = floor( dDate2 );
2228 0 : dRet = dDays2 - dDays1;
2229 0 : break;
2230 : }
2231 : case INTERVAL_W:
2232 : case INTERVAL_WW:
2233 : {
2234 0 : double dDays1 = floor( dDate1 );
2235 0 : double dDays2 = floor( dDate2 );
2236 0 : if( pInfo->meInterval == INTERVAL_WW )
2237 : {
2238 0 : sal_Int16 nFirstDay = 1; // Default
2239 0 : if( nParCount >= 5 )
2240 : {
2241 0 : nFirstDay = rPar.Get(4)->GetInteger();
2242 0 : if( nFirstDay < 0 || nFirstDay > 7 )
2243 : {
2244 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2245 0 : return;
2246 : }
2247 0 : if( nFirstDay == 0 )
2248 : {
2249 0 : Reference< XCalendar4 > xCalendar = getLocaleCalendar();
2250 0 : if( !xCalendar.is() )
2251 : {
2252 0 : StarBASIC::Error( SbERR_INTERNAL_ERROR );
2253 0 : return;
2254 : }
2255 0 : nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 );
2256 : }
2257 : }
2258 0 : sal_Int16 nDay1 = implGetWeekDay( dDate1 );
2259 0 : sal_Int16 nDay1_Diff = nDay1 - nFirstDay;
2260 0 : if( nDay1_Diff < 0 )
2261 0 : nDay1_Diff += 7;
2262 0 : dDays1 -= nDay1_Diff;
2263 :
2264 0 : sal_Int16 nDay2 = implGetWeekDay( dDate2 );
2265 0 : sal_Int16 nDay2_Diff = nDay2 - nFirstDay;
2266 0 : if( nDay2_Diff < 0 )
2267 0 : nDay2_Diff += 7;
2268 0 : dDays2 -= nDay2_Diff;
2269 : }
2270 :
2271 0 : double dDiff = dDays2 - dDays1;
2272 0 : dRet = ( dDiff >= 0 ) ? floor( dDiff / 7.0 ) : -floor( -dDiff / 7.0 );
2273 0 : break;
2274 : }
2275 : case INTERVAL_H:
2276 : {
2277 0 : double dFactor = 24.0;
2278 0 : dRet = RoundImpl( dFactor * (dDate2 - dDate1) );
2279 0 : break;
2280 : }
2281 : case INTERVAL_N:
2282 : {
2283 0 : double dFactor =1440.0;
2284 0 : dRet = RoundImpl( dFactor * (dDate2 - dDate1) );
2285 0 : break;
2286 : }
2287 : case INTERVAL_S:
2288 : {
2289 0 : double dFactor = 86400.0;
2290 0 : dRet = RoundImpl( dFactor * (dDate2 - dDate1) );
2291 0 : break;
2292 : }
2293 : }
2294 0 : rPar.Get(0)->PutDouble( dRet );
2295 : }
2296 :
2297 0 : double implGetDateOfFirstDayInFirstWeek
2298 : ( sal_Int16 nYear, sal_Int16& nFirstDay, sal_Int16& nFirstWeek, bool* pbError = NULL )
2299 : {
2300 0 : SbError nError = 0;
2301 0 : if( nFirstDay < 0 || nFirstDay > 7 )
2302 0 : nError = SbERR_BAD_ARGUMENT;
2303 :
2304 0 : if( nFirstWeek < 0 || nFirstWeek > 3 )
2305 0 : nError = SbERR_BAD_ARGUMENT;
2306 :
2307 0 : Reference< XCalendar4 > xCalendar;
2308 0 : if( nFirstDay == 0 || nFirstWeek == 0 )
2309 : {
2310 0 : xCalendar = getLocaleCalendar();
2311 0 : if( !xCalendar.is() )
2312 0 : nError = SbERR_BAD_ARGUMENT;
2313 : }
2314 :
2315 0 : if( nError != 0 )
2316 : {
2317 0 : StarBASIC::Error( nError );
2318 0 : if( pbError )
2319 0 : *pbError = true;
2320 0 : return 0.0;
2321 : }
2322 :
2323 0 : if( nFirstDay == 0 )
2324 0 : nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 );
2325 :
2326 0 : sal_Int16 nFirstWeekMinDays = 0; // Not used for vbFirstJan1 = default
2327 0 : if( nFirstWeek == 0 )
2328 : {
2329 0 : nFirstWeekMinDays = xCalendar->getMinimumNumberOfDaysForFirstWeek();
2330 0 : if( nFirstWeekMinDays == 1 )
2331 : {
2332 0 : nFirstWeekMinDays = 0;
2333 0 : nFirstWeek = 1;
2334 : }
2335 0 : else if( nFirstWeekMinDays == 4 )
2336 0 : nFirstWeek = 2;
2337 0 : else if( nFirstWeekMinDays == 7 )
2338 0 : nFirstWeek = 3;
2339 : }
2340 0 : else if( nFirstWeek == 2 )
2341 0 : nFirstWeekMinDays = 4; // vbFirstFourDays
2342 0 : else if( nFirstWeek == 3 )
2343 0 : nFirstWeekMinDays = 7; // vbFirstFourDays
2344 :
2345 : double dBaseDate;
2346 0 : implDateSerial( nYear, 1, 1, dBaseDate );
2347 :
2348 0 : sal_Int16 nWeekDay0101 = implGetWeekDay( dBaseDate );
2349 0 : sal_Int16 nDayDiff = nWeekDay0101 - nFirstDay;
2350 0 : if( nDayDiff < 0 )
2351 0 : nDayDiff += 7;
2352 :
2353 0 : if( nFirstWeekMinDays )
2354 : {
2355 0 : sal_Int16 nThisWeeksDaysInYearCount = 7 - nDayDiff;
2356 0 : if( nThisWeeksDaysInYearCount < nFirstWeekMinDays )
2357 0 : nDayDiff -= 7;
2358 : }
2359 0 : double dRetDate = dBaseDate - nDayDiff;
2360 0 : return dRetDate;
2361 : }
2362 :
2363 0 : RTLFUNC(DatePart)
2364 : {
2365 : (void)pBasic;
2366 : (void)bWrite;
2367 :
2368 : // DatePart(interval, date[,firstdayofweek[, firstweekofyear]])
2369 :
2370 0 : sal_uInt16 nParCount = rPar.Count();
2371 0 : if( nParCount < 3 || nParCount > 5 )
2372 : {
2373 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2374 0 : return;
2375 : }
2376 :
2377 0 : OUString aStringCode = rPar.Get(1)->GetOUString();
2378 0 : IntervalInfo const * pInfo = getIntervalInfo( aStringCode );
2379 0 : if( !pInfo )
2380 : {
2381 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2382 0 : return;
2383 : }
2384 :
2385 0 : double dDate = rPar.Get(2)->GetDate();
2386 :
2387 0 : sal_Int32 nRet = 0;
2388 0 : switch( pInfo->meInterval )
2389 : {
2390 : case INTERVAL_YYYY:
2391 : {
2392 0 : nRet = implGetDateYear( dDate );
2393 0 : break;
2394 : }
2395 : case INTERVAL_Q:
2396 : {
2397 0 : nRet = 1 + (implGetDateMonth( dDate ) - 1) / 3;
2398 0 : break;
2399 : }
2400 : case INTERVAL_M:
2401 : {
2402 0 : nRet = implGetDateMonth( dDate );
2403 0 : break;
2404 : }
2405 : case INTERVAL_Y:
2406 : {
2407 0 : sal_Int16 nYear = implGetDateYear( dDate );
2408 : double dBaseDate;
2409 0 : implDateSerial( nYear, 1, 1, dBaseDate );
2410 0 : nRet = 1 + sal_Int32( dDate - dBaseDate );
2411 0 : break;
2412 : }
2413 : case INTERVAL_D:
2414 : {
2415 0 : nRet = implGetDateDay( dDate );
2416 0 : break;
2417 : }
2418 : case INTERVAL_W:
2419 : {
2420 0 : bool bFirstDay = false;
2421 0 : sal_Int16 nFirstDay = 1; // Default
2422 0 : if( nParCount >= 4 )
2423 : {
2424 0 : nFirstDay = rPar.Get(3)->GetInteger();
2425 0 : bFirstDay = true;
2426 : }
2427 0 : nRet = implGetWeekDay( dDate, bFirstDay, nFirstDay );
2428 0 : break;
2429 : }
2430 : case INTERVAL_WW:
2431 : {
2432 0 : sal_Int16 nFirstDay = 1; // Default
2433 0 : if( nParCount >= 4 )
2434 0 : nFirstDay = rPar.Get(3)->GetInteger();
2435 :
2436 0 : sal_Int16 nFirstWeek = 1; // Default
2437 0 : if( nParCount == 5 )
2438 0 : nFirstWeek = rPar.Get(4)->GetInteger();
2439 :
2440 0 : sal_Int16 nYear = implGetDateYear( dDate );
2441 0 : bool bError = false;
2442 0 : double dYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear, nFirstDay, nFirstWeek, &bError );
2443 0 : if( !bError )
2444 : {
2445 0 : if( dYearFirstDay > dDate )
2446 : {
2447 : // Date belongs to last year's week
2448 0 : dYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear - 1, nFirstDay, nFirstWeek );
2449 : }
2450 0 : else if( nFirstWeek != 1 )
2451 : {
2452 : // Check if date belongs to next year
2453 0 : double dNextYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear + 1, nFirstDay, nFirstWeek );
2454 0 : if( dDate >= dNextYearFirstDay )
2455 0 : dYearFirstDay = dNextYearFirstDay;
2456 : }
2457 :
2458 : // Calculate week
2459 0 : double dDiff = dDate - dYearFirstDay;
2460 0 : nRet = 1 + sal_Int32( dDiff / 7 );
2461 : }
2462 0 : break;
2463 : }
2464 : case INTERVAL_H:
2465 : {
2466 0 : nRet = implGetHour( dDate );
2467 0 : break;
2468 : }
2469 : case INTERVAL_N:
2470 : {
2471 0 : nRet = implGetMinute( dDate );
2472 0 : break;
2473 : }
2474 : case INTERVAL_S:
2475 : {
2476 0 : nRet = implGetSecond( dDate );
2477 0 : break;
2478 : }
2479 : }
2480 0 : rPar.Get(0)->PutLong( nRet );
2481 : }
2482 :
2483 : // FormatDateTime(Date[,NamedFormat])
2484 0 : RTLFUNC(FormatDateTime)
2485 : {
2486 : (void)pBasic;
2487 : (void)bWrite;
2488 :
2489 0 : sal_uInt16 nParCount = rPar.Count();
2490 0 : if( nParCount < 2 || nParCount > 3 )
2491 : {
2492 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2493 0 : return;
2494 : }
2495 :
2496 0 : double dDate = rPar.Get(1)->GetDate();
2497 0 : sal_Int16 nNamedFormat = 0;
2498 0 : if( nParCount > 2 )
2499 : {
2500 0 : nNamedFormat = rPar.Get(2)->GetInteger();
2501 0 : if( nNamedFormat < 0 || nNamedFormat > 4 )
2502 : {
2503 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2504 0 : return;
2505 : }
2506 : }
2507 :
2508 0 : Reference< XCalendar4 > xCalendar = getLocaleCalendar();
2509 0 : if( !xCalendar.is() )
2510 : {
2511 0 : StarBASIC::Error( SbERR_INTERNAL_ERROR );
2512 0 : return;
2513 : }
2514 :
2515 0 : OUString aRetStr;
2516 0 : SbxVariableRef pSbxVar = new SbxVariable( SbxSTRING );
2517 0 : switch( nNamedFormat )
2518 : {
2519 : // GeneralDate:
2520 : // Display a date and/or time. If there is a date part,
2521 : // display it as a short date. If there is a time part,
2522 : // display it as a long time. If present, both parts are displayed.
2523 :
2524 : // 12/21/2004 11:24:50 AM
2525 : // 21.12.2004 12:13:51
2526 : case 0:
2527 0 : pSbxVar->PutDate( dDate );
2528 0 : aRetStr = pSbxVar->GetOUString();
2529 0 : break;
2530 :
2531 : // LongDate: Display a date using the long date format specified
2532 : // in your computer's regional settings.
2533 : // Tuesday, December 21, 2004
2534 : // Dienstag, 21. December 2004
2535 : case 1:
2536 : {
2537 0 : SvNumberFormatter* pFormatter = NULL;
2538 0 : if( GetSbData()->pInst )
2539 : {
2540 0 : pFormatter = GetSbData()->pInst->GetNumberFormatter();
2541 : }
2542 : else
2543 : {
2544 : sal_uInt32 n; // Dummy
2545 0 : pFormatter = SbiInstance::PrepareNumberFormatter( n, n, n );
2546 : }
2547 :
2548 0 : LanguageType eLangType = Application::GetSettings().GetLanguageTag().getLanguageType();
2549 0 : sal_uIntPtr nIndex = pFormatter->GetFormatIndex( NF_DATE_SYSTEM_LONG, eLangType );
2550 : Color* pCol;
2551 0 : pFormatter->GetOutputString( dDate, nIndex, aRetStr, &pCol );
2552 :
2553 0 : if( !GetSbData()->pInst )
2554 : {
2555 0 : delete pFormatter;
2556 : }
2557 0 : break;
2558 : }
2559 :
2560 : // ShortDate: Display a date using the short date format specified
2561 : // in your computer's regional settings.
2562 : // 21.12.2004
2563 : case 2:
2564 0 : pSbxVar->PutDate( floor(dDate) );
2565 0 : aRetStr = pSbxVar->GetOUString();
2566 0 : break;
2567 :
2568 : // LongTime: Display a time using the time format specified
2569 : // in your computer's regional settings.
2570 : // 11:24:50 AM
2571 : // 12:13:51
2572 : case 3:
2573 : // ShortTime: Display a time using the 24-hour format (hh:mm).
2574 : // 11:24
2575 : case 4:
2576 : double n;
2577 0 : double dTime = modf( dDate, &n );
2578 0 : pSbxVar->PutDate( dTime );
2579 0 : if( nNamedFormat == 3 )
2580 : {
2581 0 : aRetStr = pSbxVar->GetOUString();
2582 : }
2583 : else
2584 : {
2585 0 : aRetStr = pSbxVar->GetOUString().copy( 0, 5 );
2586 : }
2587 0 : break;
2588 : }
2589 :
2590 0 : rPar.Get(0)->PutString( aRetStr );
2591 : }
2592 :
2593 0 : RTLFUNC(Frac)
2594 : {
2595 : (void)pBasic;
2596 : (void)bWrite;
2597 :
2598 0 : sal_uInt16 nParCount = rPar.Count();
2599 0 : if( nParCount != 2)
2600 : {
2601 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2602 0 : return;
2603 : }
2604 :
2605 0 : SbxVariable *pSbxVariable = rPar.Get(1);
2606 0 : double dVal = pSbxVariable->GetDouble();
2607 0 : if(dVal >= 0)
2608 0 : rPar.Get(0)->PutDouble(dVal - ::rtl::math::approxFloor(dVal));
2609 : else
2610 0 : rPar.Get(0)->PutDouble(dVal - ::rtl::math::approxCeil(dVal));
2611 : }
2612 :
2613 0 : RTLFUNC(Round)
2614 : {
2615 : (void)pBasic;
2616 : (void)bWrite;
2617 :
2618 0 : sal_uInt16 nParCount = rPar.Count();
2619 0 : if( nParCount != 2 && nParCount != 3 )
2620 : {
2621 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2622 0 : return;
2623 : }
2624 :
2625 0 : SbxVariable *pSbxVariable = rPar.Get(1);
2626 0 : double dVal = pSbxVariable->GetDouble();
2627 0 : double dRes = 0.0;
2628 0 : if( dVal != 0.0 )
2629 : {
2630 0 : bool bNeg = false;
2631 0 : if( dVal < 0.0 )
2632 : {
2633 0 : bNeg = true;
2634 0 : dVal = -dVal;
2635 : }
2636 :
2637 0 : sal_Int16 numdecimalplaces = 0;
2638 0 : if( nParCount == 3 )
2639 : {
2640 0 : numdecimalplaces = rPar.Get(2)->GetInteger();
2641 0 : if( numdecimalplaces < 0 || numdecimalplaces > 22 )
2642 : {
2643 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
2644 0 : return;
2645 : }
2646 : }
2647 :
2648 0 : if( numdecimalplaces == 0 )
2649 : {
2650 0 : dRes = floor( dVal + 0.5 );
2651 : }
2652 : else
2653 : {
2654 0 : double dFactor = pow( 10.0, numdecimalplaces );
2655 0 : dVal *= dFactor;
2656 0 : dRes = floor( dVal + 0.5 );
2657 0 : dRes /= dFactor;
2658 : }
2659 :
2660 0 : if( bNeg )
2661 0 : dRes = -dRes;
2662 : }
2663 0 : rPar.Get(0)->PutDouble( dRes );
2664 : }
2665 :
2666 0 : void CallFunctionAccessFunction( const Sequence< Any >& aArgs, const OUString& sFuncName, SbxVariable* pRet )
2667 : {
2668 0 : static Reference< XFunctionAccess > xFunc;
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 : }
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 0 : Any aValues = sbxToUnoValue( rPar.Get(2),
2890 0 : cppu::UnoType<Sequence<double>>::get() );
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 0 : Any aValues = sbxToUnoValue( rPar.Get(1),
2964 0 : cppu::UnoType<Sequence<double>>::get() );
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 0 : Any aValues = sbxToUnoValue( rPar.Get(1),
2992 0 : cppu::UnoType<Sequence<double>>::get() );
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 : #if HAVE_FEATURE_SCRIPTING
3326 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3327 : #endif
3328 0 : return 0;
3329 : }
3330 0 : if( nFirstDay == 0 )
3331 : {
3332 0 : Reference< XCalendar4 > xCalendar = getLocaleCalendar();
3333 0 : if( !xCalendar.is() )
3334 : {
3335 : #if HAVE_FEATURE_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 : }
3346 :
3347 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|