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/fsys.hxx>
33 : #include <tools/urlobj.hxx>
34 : #include <osl/file.hxx>
35 : #include <vcl/jobset.hxx>
36 : #include <basic/sbobjmod.hxx>
37 :
38 : #include "date.hxx"
39 : #include "sbintern.hxx"
40 : #include "runtime.hxx"
41 : #include "stdobj.hxx"
42 : #include "rtlproto.hxx"
43 : #include "dllmgr.hxx"
44 : #include <iosys.hxx>
45 : #include "sbunoobj.hxx"
46 : #include "propacc.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::sheet;
59 : using namespace com::sun::star::uno;
60 : using namespace com::sun::star::i18n;
61 :
62 : void unoToSbxValue( SbxVariable* pVar, const Any& aValue );
63 : Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, com::sun::star::beans::Property* pUnoProperty = NULL );
64 :
65 0 : static Reference< XCalendar3 > getLocaleCalendar( void )
66 : {
67 0 : static Reference< XCalendar3 > xCalendar;
68 0 : if( !xCalendar.is() )
69 : {
70 0 : Reference< XComponentContext > xContext = getProcessComponentContext();
71 0 : xCalendar = LocaleCalendar::create(xContext);
72 : }
73 :
74 0 : static com::sun::star::lang::Locale aLastLocale;
75 : static bool bNeedsInit = true;
76 :
77 0 : com::sun::star::lang::Locale aLocale = Application::GetSettings().GetLanguageTag().getLocale();
78 0 : bool bNeedsReload = false;
79 0 : if( bNeedsInit )
80 : {
81 0 : bNeedsInit = false;
82 0 : bNeedsReload = true;
83 : }
84 0 : else if( aLocale.Language != aLastLocale.Language ||
85 0 : aLocale.Country != aLastLocale.Country ||
86 0 : aLocale.Variant != aLastLocale.Variant )
87 : {
88 0 : bNeedsReload = true;
89 : }
90 0 : if( bNeedsReload )
91 : {
92 0 : aLastLocale = aLocale;
93 0 : xCalendar->loadDefaultCalendar( aLocale );
94 : }
95 0 : return xCalendar;
96 : }
97 :
98 : #ifndef DISABLE_SCRIPTING
99 :
100 0 : RTLFUNC(CallByName)
101 : {
102 : (void)pBasic;
103 : (void)bWrite;
104 :
105 0 : const sal_Int16 vbGet = 2;
106 0 : const sal_Int16 vbLet = 4;
107 0 : const sal_Int16 vbMethod = 1;
108 0 : const sal_Int16 vbSet = 8;
109 :
110 : // At least 3 parameter needed plus function itself -> 4
111 0 : sal_uInt16 nParCount = rPar.Count();
112 0 : if ( nParCount < 4 )
113 : {
114 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
115 : return;
116 : }
117 :
118 : // 1. parameter is object
119 0 : SbxBase* pObjVar = (SbxObject*)rPar.Get(1)->GetObject();
120 0 : SbxObject* pObj = NULL;
121 0 : if( pObjVar )
122 0 : pObj = PTR_CAST(SbxObject,pObjVar);
123 0 : if( !pObj && pObjVar && pObjVar->ISA(SbxVariable) )
124 : {
125 0 : SbxBase* pObjVarObj = ((SbxVariable*)pObjVar)->GetObject();
126 0 : pObj = PTR_CAST(SbxObject,pObjVarObj);
127 : }
128 0 : if( !pObj )
129 : {
130 0 : StarBASIC::Error( SbERR_BAD_PARAMETER );
131 : return;
132 : }
133 :
134 : // 2. parameter is ProcedureName
135 0 : OUString aNameStr = rPar.Get(2)->GetOUString();
136 :
137 : // 3. parameter is CallType
138 0 : sal_Int16 nCallType = rPar.Get(3)->GetInteger();
139 :
140 : //SbxObject* pFindObj = NULL;
141 0 : SbxVariable* pFindVar = pObj->Find( aNameStr, SbxCLASS_DONTCARE );
142 0 : if( pFindVar == NULL )
143 : {
144 0 : StarBASIC::Error( SbERR_PROC_UNDEFINED );
145 : return;
146 : }
147 :
148 0 : switch( nCallType )
149 : {
150 : case vbGet:
151 : {
152 0 : SbxValues aVals;
153 0 : aVals.eType = SbxVARIANT;
154 0 : pFindVar->Get( aVals );
155 :
156 0 : SbxVariableRef refVar = rPar.Get(0);
157 0 : refVar->Put( aVals );
158 : }
159 0 : break;
160 : case vbLet:
161 : case vbSet:
162 : {
163 0 : if ( nParCount != 5 )
164 : {
165 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
166 : return;
167 : }
168 0 : SbxVariableRef pValVar = rPar.Get(4);
169 0 : if( nCallType == vbLet )
170 : {
171 0 : SbxValues aVals;
172 0 : aVals.eType = SbxVARIANT;
173 0 : pValVar->Get( aVals );
174 0 : pFindVar->Put( aVals );
175 : }
176 : else
177 : {
178 0 : SbxVariableRef rFindVar = pFindVar;
179 0 : SbiInstance* pInst = GetSbData()->pInst;
180 0 : SbiRuntime* pRT = pInst ? pInst->pRun : NULL;
181 0 : if( pRT != NULL )
182 : {
183 0 : pRT->StepSET_Impl( pValVar, rFindVar, false );
184 0 : }
185 0 : }
186 : }
187 0 : break;
188 : case vbMethod:
189 : {
190 0 : SbMethod* pMeth = PTR_CAST(SbMethod,pFindVar);
191 0 : if( pMeth == NULL )
192 : {
193 0 : StarBASIC::Error( SbERR_PROC_UNDEFINED );
194 : return;
195 : }
196 :
197 : // Setup parameters
198 0 : SbxArrayRef xArray;
199 0 : sal_uInt16 nMethParamCount = nParCount - 4;
200 0 : if( nMethParamCount > 0 )
201 : {
202 0 : xArray = new SbxArray;
203 0 : for( sal_uInt16 i = 0 ; i < nMethParamCount ; i++ )
204 : {
205 0 : SbxVariable* pPar = rPar.Get( i + 4 );
206 0 : xArray->Put( pPar, i + 1 );
207 : }
208 : }
209 :
210 : // Call method
211 0 : SbxVariableRef refVar = rPar.Get(0);
212 0 : if( xArray.Is() )
213 0 : pMeth->SetParameters( xArray );
214 0 : pMeth->Call( refVar );
215 0 : pMeth->SetParameters( NULL );
216 : }
217 0 : break;
218 : default:
219 0 : StarBASIC::Error( SbERR_PROC_UNDEFINED );
220 0 : }
221 : }
222 :
223 0 : RTLFUNC(CBool) // JSM
224 : {
225 : (void)pBasic;
226 : (void)bWrite;
227 :
228 0 : sal_Bool bVal = sal_False;
229 0 : if ( rPar.Count() == 2 )
230 : {
231 0 : SbxVariable *pSbxVariable = rPar.Get(1);
232 0 : bVal = pSbxVariable->GetBool();
233 : }
234 : else
235 : {
236 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
237 : }
238 0 : rPar.Get(0)->PutBool(bVal);
239 0 : }
240 :
241 0 : RTLFUNC(CByte) // JSM
242 : {
243 : (void)pBasic;
244 : (void)bWrite;
245 :
246 0 : sal_uInt8 nByte = 0;
247 0 : if ( rPar.Count() == 2 )
248 : {
249 0 : SbxVariable *pSbxVariable = rPar.Get(1);
250 0 : nByte = pSbxVariable->GetByte();
251 : }
252 : else
253 : {
254 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
255 : }
256 0 : rPar.Get(0)->PutByte(nByte);
257 0 : }
258 :
259 0 : RTLFUNC(CCur)
260 : {
261 : (void)pBasic;
262 : (void)bWrite;
263 :
264 0 : sal_Int64 nCur = 0;
265 0 : if ( rPar.Count() == 2 )
266 : {
267 0 : SbxVariable *pSbxVariable = rPar.Get(1);
268 0 : nCur = pSbxVariable->GetCurrency();
269 : }
270 : else
271 : {
272 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
273 : }
274 0 : rPar.Get(0)->PutCurrency( nCur );
275 0 : }
276 :
277 0 : RTLFUNC(CDec)
278 : {
279 : (void)pBasic;
280 : (void)bWrite;
281 :
282 : #ifdef WNT
283 : SbxDecimal* pDec = NULL;
284 : if ( rPar.Count() == 2 )
285 : {
286 : SbxVariable *pSbxVariable = rPar.Get(1);
287 : pDec = pSbxVariable->GetDecimal();
288 : }
289 : else
290 : {
291 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
292 : }
293 : rPar.Get(0)->PutDecimal( pDec );
294 : #else
295 0 : rPar.Get(0)->PutEmpty();
296 0 : StarBASIC::Error(SbERR_NOT_IMPLEMENTED);
297 : #endif
298 0 : }
299 :
300 0 : RTLFUNC(CDate) // JSM
301 : {
302 : (void)pBasic;
303 : (void)bWrite;
304 :
305 0 : double nVal = 0.0;
306 0 : if ( rPar.Count() == 2 )
307 : {
308 0 : SbxVariable *pSbxVariable = rPar.Get(1);
309 0 : nVal = pSbxVariable->GetDate();
310 : }
311 : else
312 : {
313 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
314 : }
315 0 : rPar.Get(0)->PutDate(nVal);
316 0 : }
317 :
318 0 : RTLFUNC(CDbl) // JSM
319 : {
320 : (void)pBasic;
321 : (void)bWrite;
322 :
323 0 : double nVal = 0.0;
324 0 : if ( rPar.Count() == 2 )
325 : {
326 0 : SbxVariable *pSbxVariable = rPar.Get(1);
327 0 : if( pSbxVariable->GetType() == SbxSTRING )
328 : {
329 : // #41690
330 0 : OUString aScanStr = pSbxVariable->GetOUString();
331 0 : SbError Error = SbxValue::ScanNumIntnl( aScanStr, nVal );
332 0 : if( Error != SbxERR_OK )
333 : {
334 0 : StarBASIC::Error( Error );
335 0 : }
336 : }
337 : else
338 : {
339 0 : nVal = pSbxVariable->GetDouble();
340 : }
341 : }
342 : else
343 : {
344 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
345 : }
346 :
347 0 : rPar.Get(0)->PutDouble(nVal);
348 0 : }
349 :
350 0 : RTLFUNC(CInt) // JSM
351 : {
352 : (void)pBasic;
353 : (void)bWrite;
354 :
355 0 : sal_Int16 nVal = 0;
356 0 : if ( rPar.Count() == 2 )
357 : {
358 0 : SbxVariable *pSbxVariable = rPar.Get(1);
359 0 : nVal = pSbxVariable->GetInteger();
360 : }
361 : else
362 : {
363 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
364 : }
365 0 : rPar.Get(0)->PutInteger(nVal);
366 0 : }
367 :
368 0 : RTLFUNC(CLng) // JSM
369 : {
370 : (void)pBasic;
371 : (void)bWrite;
372 :
373 0 : sal_Int32 nVal = 0;
374 0 : if ( rPar.Count() == 2 )
375 : {
376 0 : SbxVariable *pSbxVariable = rPar.Get(1);
377 0 : nVal = pSbxVariable->GetLong();
378 : }
379 : else
380 : {
381 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
382 : }
383 0 : rPar.Get(0)->PutLong(nVal);
384 0 : }
385 :
386 0 : RTLFUNC(CSng) // JSM
387 : {
388 : (void)pBasic;
389 : (void)bWrite;
390 :
391 0 : float nVal = (float)0.0;
392 0 : if ( rPar.Count() == 2 )
393 : {
394 0 : SbxVariable *pSbxVariable = rPar.Get(1);
395 0 : if( pSbxVariable->GetType() == SbxSTRING )
396 : {
397 : // #41690
398 0 : double dVal = 0.0;
399 0 : OUString aScanStr = pSbxVariable->GetOUString();
400 0 : SbError Error = SbxValue::ScanNumIntnl( aScanStr, dVal, /*bSingle=*/true );
401 0 : if( SbxBase::GetError() == SbxERR_OK && Error != SbxERR_OK )
402 : {
403 0 : StarBASIC::Error( Error );
404 : }
405 0 : nVal = (float)dVal;
406 : }
407 : else
408 : {
409 0 : nVal = pSbxVariable->GetSingle();
410 : }
411 : }
412 : else
413 : {
414 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
415 : }
416 0 : rPar.Get(0)->PutSingle(nVal);
417 0 : }
418 :
419 0 : RTLFUNC(CStr) // JSM
420 : {
421 : (void)pBasic;
422 : (void)bWrite;
423 :
424 0 : OUString aString;
425 0 : if ( rPar.Count() == 2 )
426 : {
427 0 : SbxVariable *pSbxVariable = rPar.Get(1);
428 0 : aString = pSbxVariable->GetOUString();
429 : }
430 : else
431 : {
432 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
433 : }
434 0 : rPar.Get(0)->PutString(aString);
435 0 : }
436 :
437 0 : RTLFUNC(CVar) // JSM
438 : {
439 : (void)pBasic;
440 : (void)bWrite;
441 :
442 0 : SbxValues aVals( SbxVARIANT );
443 0 : if ( rPar.Count() == 2 )
444 : {
445 0 : SbxVariable *pSbxVariable = rPar.Get(1);
446 0 : pSbxVariable->Get( aVals );
447 : }
448 : else
449 : {
450 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
451 : }
452 0 : rPar.Get(0)->Put( aVals );
453 0 : }
454 :
455 0 : RTLFUNC(CVErr)
456 : {
457 : (void)pBasic;
458 : (void)bWrite;
459 :
460 0 : sal_Int16 nErrCode = 0;
461 0 : if ( rPar.Count() == 2 )
462 : {
463 0 : SbxVariable *pSbxVariable = rPar.Get(1);
464 0 : nErrCode = pSbxVariable->GetInteger();
465 : }
466 : else
467 : {
468 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
469 : }
470 0 : rPar.Get(0)->PutErr( nErrCode );
471 0 : }
472 :
473 0 : RTLFUNC(Iif) // JSM
474 : {
475 : (void)pBasic;
476 : (void)bWrite;
477 :
478 0 : if ( rPar.Count() == 4 )
479 : {
480 0 : if (rPar.Get(1)->GetBool())
481 : {
482 0 : *rPar.Get(0) = *rPar.Get(2);
483 : }
484 : else
485 : {
486 0 : *rPar.Get(0) = *rPar.Get(3);
487 : }
488 : }
489 : else
490 : {
491 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
492 : }
493 0 : }
494 :
495 0 : RTLFUNC(GetSystemType)
496 : {
497 : (void)pBasic;
498 : (void)bWrite;
499 :
500 0 : if ( rPar.Count() != 1 )
501 : {
502 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
503 : }
504 : else
505 : {
506 : // Removed for SRC595
507 0 : rPar.Get(0)->PutInteger( -1 );
508 : }
509 0 : }
510 :
511 0 : RTLFUNC(GetGUIType)
512 : {
513 : (void)pBasic;
514 : (void)bWrite;
515 :
516 0 : if ( rPar.Count() != 1 )
517 : {
518 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
519 : }
520 : else
521 : {
522 : // 17.7.2000 Make simple solution for testtool / fat office
523 : #if defined (WNT)
524 : rPar.Get(0)->PutInteger( 1 );
525 : #elif defined UNX
526 0 : rPar.Get(0)->PutInteger( 4 );
527 : #else
528 : rPar.Get(0)->PutInteger( -1 );
529 : #endif
530 : }
531 0 : }
532 :
533 0 : RTLFUNC(Red)
534 : {
535 : (void)pBasic;
536 : (void)bWrite;
537 :
538 0 : if ( rPar.Count() != 2 )
539 : {
540 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
541 : }
542 : else
543 : {
544 0 : sal_uIntPtr nRGB = (sal_uIntPtr)rPar.Get(1)->GetLong();
545 0 : nRGB &= 0x00FF0000;
546 0 : nRGB >>= 16;
547 0 : rPar.Get(0)->PutInteger( (sal_Int16)nRGB );
548 : }
549 0 : }
550 :
551 0 : RTLFUNC(Green)
552 : {
553 : (void)pBasic;
554 : (void)bWrite;
555 :
556 0 : if ( rPar.Count() != 2 )
557 : {
558 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
559 : }
560 : else
561 : {
562 0 : sal_uIntPtr nRGB = (sal_uIntPtr)rPar.Get(1)->GetLong();
563 0 : nRGB &= 0x0000FF00;
564 0 : nRGB >>= 8;
565 0 : rPar.Get(0)->PutInteger( (sal_Int16)nRGB );
566 : }
567 0 : }
568 :
569 0 : RTLFUNC(Blue)
570 : {
571 : (void)pBasic;
572 : (void)bWrite;
573 :
574 0 : if ( rPar.Count() != 2 )
575 : {
576 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
577 : }
578 : else
579 : {
580 0 : sal_uIntPtr nRGB = (sal_uIntPtr)rPar.Get(1)->GetLong();
581 0 : nRGB &= 0x000000FF;
582 0 : rPar.Get(0)->PutInteger( (sal_Int16)nRGB );
583 : }
584 0 : }
585 :
586 :
587 0 : RTLFUNC(Switch)
588 : {
589 : (void)pBasic;
590 : (void)bWrite;
591 :
592 0 : sal_uInt16 nCount = rPar.Count();
593 0 : if( !(nCount & 0x0001 ))
594 : {
595 : // number of arguments must be odd
596 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
597 : }
598 0 : sal_uInt16 nCurExpr = 1;
599 0 : while( nCurExpr < (nCount-1) )
600 : {
601 0 : if( rPar.Get( nCurExpr )->GetBool())
602 : {
603 0 : (*rPar.Get(0)) = *(rPar.Get(nCurExpr+1));
604 0 : return;
605 : }
606 0 : nCurExpr += 2;
607 : }
608 0 : rPar.Get(0)->PutNull();
609 : }
610 :
611 : //i#64882# Common wait impl for existing Wait and new WaitUntil
612 : // rtl functions
613 0 : void Wait_Impl( bool bDurationBased, SbxArray& rPar )
614 : {
615 0 : if( rPar.Count() != 2 )
616 : {
617 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
618 : return;
619 : }
620 0 : long nWait = 0;
621 0 : if ( bDurationBased )
622 : {
623 0 : double dWait = rPar.Get(1)->GetDouble();
624 0 : double dNow = Now_Impl();
625 0 : double dSecs = (double)( ( dWait - dNow ) * (double)( 24.0*3600.0) );
626 0 : nWait = (long)( dSecs * 1000 ); // wait in thousands of sec
627 : }
628 : else
629 : {
630 0 : nWait = rPar.Get(1)->GetLong();
631 : }
632 0 : if( nWait < 0 )
633 : {
634 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
635 : return;
636 : }
637 :
638 0 : Timer aTimer;
639 0 : aTimer.SetTimeout( nWait );
640 0 : aTimer.Start();
641 0 : while ( aTimer.IsActive() )
642 : {
643 0 : Application::Yield();
644 0 : }
645 : }
646 :
647 : //i#64882#
648 0 : RTLFUNC(Wait)
649 : {
650 : (void)pBasic;
651 : (void)bWrite;
652 0 : Wait_Impl( false, rPar );
653 0 : }
654 :
655 : //i#64882# add new WaitUntil ( for application.wait )
656 : // share wait_impl with 'normal' oobasic wait
657 0 : RTLFUNC(WaitUntil)
658 : {
659 : (void)pBasic;
660 : (void)bWrite;
661 0 : Wait_Impl( true, rPar );
662 0 : }
663 :
664 0 : RTLFUNC(DoEvents)
665 : {
666 : (void)pBasic;
667 : (void)bWrite;
668 : (void)rPar;
669 : // don't undstand what upstream are up to
670 : // we already process application events etc. in between
671 : // basic runtime pcode ( on a timed basis )
672 : // always return 0
673 0 : rPar.Get(0)->PutInteger( 0 );
674 0 : Application::Reschedule( true );
675 0 : }
676 :
677 0 : RTLFUNC(GetGUIVersion)
678 : {
679 : (void)pBasic;
680 : (void)bWrite;
681 :
682 0 : if ( rPar.Count() != 1 )
683 : {
684 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
685 : }
686 : else
687 : {
688 : // Removed for SRC595
689 0 : rPar.Get(0)->PutLong( -1 );
690 : }
691 0 : }
692 :
693 0 : RTLFUNC(Choose)
694 : {
695 : (void)pBasic;
696 : (void)bWrite;
697 :
698 0 : if ( rPar.Count() < 2 )
699 : {
700 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
701 : }
702 0 : sal_Int16 nIndex = rPar.Get(1)->GetInteger();
703 0 : sal_uInt16 nCount = rPar.Count();
704 0 : nCount--;
705 0 : if( nCount == 1 || nIndex > (nCount-1) || nIndex < 1 )
706 : {
707 0 : rPar.Get(0)->PutNull();
708 0 : return;
709 : }
710 0 : (*rPar.Get(0)) = *(rPar.Get(nIndex+1));
711 : }
712 :
713 :
714 0 : RTLFUNC(Trim)
715 : {
716 : (void)pBasic;
717 : (void)bWrite;
718 :
719 0 : if ( rPar.Count() < 2 )
720 : {
721 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
722 : }
723 : else
724 : {
725 0 : rtl::OUString aStr(comphelper::string::strip(rPar.Get(1)->GetOUString(), ' '));
726 0 : rPar.Get(0)->PutString(aStr);
727 : }
728 0 : }
729 :
730 0 : RTLFUNC(GetSolarVersion)
731 : {
732 : (void)pBasic;
733 : (void)bWrite;
734 :
735 0 : rPar.Get(0)->PutLong( (sal_Int32)SUPD );
736 0 : }
737 :
738 0 : RTLFUNC(TwipsPerPixelX)
739 : {
740 : (void)pBasic;
741 : (void)bWrite;
742 :
743 0 : sal_Int32 nResult = 0;
744 0 : Size aSize( 100,0 );
745 0 : MapMode aMap( MAP_TWIP );
746 0 : OutputDevice* pDevice = Application::GetDefaultDevice();
747 0 : if( pDevice )
748 : {
749 0 : aSize = pDevice->PixelToLogic( aSize, aMap );
750 0 : nResult = aSize.Width() / 100;
751 : }
752 0 : rPar.Get(0)->PutLong( nResult );
753 0 : }
754 :
755 0 : RTLFUNC(TwipsPerPixelY)
756 : {
757 : (void)pBasic;
758 : (void)bWrite;
759 :
760 0 : sal_Int32 nResult = 0;
761 0 : Size aSize( 0,100 );
762 0 : MapMode aMap( MAP_TWIP );
763 0 : OutputDevice* pDevice = Application::GetDefaultDevice();
764 0 : if( pDevice )
765 : {
766 0 : aSize = pDevice->PixelToLogic( aSize, aMap );
767 0 : nResult = aSize.Height() / 100;
768 : }
769 0 : rPar.Get(0)->PutLong( nResult );
770 0 : }
771 :
772 :
773 0 : RTLFUNC(FreeLibrary)
774 : {
775 : (void)pBasic;
776 : (void)bWrite;
777 :
778 0 : if ( rPar.Count() != 2 )
779 : {
780 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
781 : }
782 0 : GetSbData()->pInst->GetDllMgr()->FreeDll( rPar.Get(1)->GetOUString() );
783 0 : }
784 0 : bool IsBaseIndexOne()
785 : {
786 0 : bool result = false;
787 0 : if ( GetSbData()->pInst && GetSbData()->pInst->pRun )
788 : {
789 0 : sal_uInt16 res = GetSbData()->pInst->pRun->GetBase();
790 0 : if ( res )
791 : {
792 0 : result = true;
793 : }
794 : }
795 0 : return result;
796 : }
797 :
798 0 : RTLFUNC(Array)
799 : {
800 : (void)pBasic;
801 : (void)bWrite;
802 :
803 0 : SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
804 0 : sal_uInt16 nArraySize = rPar.Count() - 1;
805 :
806 : // ignore Option Base so far (unfortunately only known by the compiler)
807 0 : bool bIncIndex = (IsBaseIndexOne() && SbiRuntime::isVBAEnabled() );
808 0 : if( nArraySize )
809 : {
810 0 : if ( bIncIndex )
811 : {
812 0 : pArray->AddDim( 1, nArraySize );
813 : }
814 : else
815 : {
816 0 : pArray->AddDim( 0, nArraySize-1 );
817 : }
818 : }
819 : else
820 : {
821 0 : pArray->unoAddDim( 0, -1 );
822 : }
823 :
824 : // insert parameters into the array
825 : // ATTENTION: Using type sal_uInt16 for loop variable is
826 : // mandatory to workaround a problem with the
827 : // Solaris Intel compiler optimizer! See i104354
828 0 : for( sal_uInt16 i = 0 ; i < nArraySize ; i++ )
829 : {
830 0 : SbxVariable* pVar = rPar.Get(i+1);
831 0 : SbxVariable* pNew = new SbxVariable( *pVar );
832 0 : pNew->SetFlag( SBX_WRITE );
833 0 : short index = static_cast< short >(i);
834 0 : if ( bIncIndex )
835 : {
836 0 : ++index;
837 : }
838 0 : pArray->Put( pNew, &index );
839 : }
840 :
841 : // return array
842 0 : SbxVariableRef refVar = rPar.Get(0);
843 0 : sal_uInt16 nFlags = refVar->GetFlags();
844 0 : refVar->ResetFlag( SBX_FIXED );
845 0 : refVar->PutObject( pArray );
846 0 : refVar->SetFlags( nFlags );
847 0 : refVar->SetParameters( NULL );
848 0 : }
849 :
850 :
851 : // Featurewish #57868
852 : // The function returns a variant-array; if there are no parameters passed,
853 : // an empty array is created (according to dim a(); equal to a sequence of
854 : // the length 0 in Uno).
855 : // If there are parameters passed, there's a dimension created for each of
856 : // them; DimArray( 2, 2, 4 ) is equal to DIM a( 2, 2, 4 )
857 : // the array is always of the type variant
858 0 : RTLFUNC(DimArray)
859 : {
860 : (void)pBasic;
861 : (void)bWrite;
862 :
863 0 : SbxDimArray * pArray = new SbxDimArray( SbxVARIANT );
864 0 : sal_uInt16 nArrayDims = rPar.Count() - 1;
865 0 : if( nArrayDims > 0 )
866 : {
867 0 : for( sal_uInt16 i = 0; i < nArrayDims ; i++ )
868 : {
869 0 : sal_Int32 ub = rPar.Get(i+1)->GetLong();
870 0 : if( ub < 0 )
871 : {
872 0 : StarBASIC::Error( SbERR_OUT_OF_RANGE );
873 0 : ub = 0;
874 : }
875 0 : pArray->AddDim32( 0, ub );
876 : }
877 : }
878 : else
879 : {
880 0 : pArray->unoAddDim( 0, -1 );
881 : }
882 0 : SbxVariableRef refVar = rPar.Get(0);
883 0 : sal_uInt16 nFlags = refVar->GetFlags();
884 0 : refVar->ResetFlag( SBX_FIXED );
885 0 : refVar->PutObject( pArray );
886 0 : refVar->SetFlags( nFlags );
887 0 : refVar->SetParameters( NULL );
888 0 : }
889 :
890 : /*
891 : * FindObject and FindPropertyObject make it possible to
892 : * address objects and properties of the type Object with
893 : * their name as string-pararmeters at the runtime.
894 : *
895 : * Example:
896 : * MyObj.Prop1.Bla = 5
897 : *
898 : * is equal to:
899 : * dim ObjVar as Object
900 : * dim ObjProp as Object
901 : * ObjName$ = "MyObj"
902 : * ObjVar = FindObject( ObjName$ )
903 : * PropName$ = "Prop1"
904 : * ObjProp = FindPropertyObject( ObjVar, PropName$ )
905 : * ObjProp.Bla = 5
906 : *
907 : * The names can be created dynamically at the runtime
908 : * so that e. g. via controls "TextEdit1" to "TextEdit5"
909 : * can be iterated in a dialog in a loop.
910 : */
911 :
912 :
913 : // 1st parameter = the object's name as string
914 0 : RTLFUNC(FindObject)
915 : {
916 : (void)pBasic;
917 : (void)bWrite;
918 :
919 0 : if ( rPar.Count() < 2 )
920 : {
921 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
922 0 : return;
923 : }
924 :
925 0 : OUString aNameStr = rPar.Get(1)->GetOUString();
926 :
927 0 : SbxBase* pFind = StarBASIC::FindSBXInCurrentScope( aNameStr );
928 0 : SbxObject* pFindObj = NULL;
929 0 : if( pFind )
930 : {
931 0 : pFindObj = PTR_CAST(SbxObject,pFind);
932 : }
933 0 : SbxVariableRef refVar = rPar.Get(0);
934 0 : refVar->PutObject( pFindObj );
935 : }
936 :
937 : // address object-property in an object
938 : // 1st parameter = object
939 : // 2nd parameter = the property's name as string
940 0 : RTLFUNC(FindPropertyObject)
941 : {
942 : (void)pBasic;
943 : (void)bWrite;
944 :
945 0 : if ( rPar.Count() < 3 )
946 : {
947 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
948 0 : return;
949 : }
950 :
951 0 : SbxBase* pObjVar = (SbxObject*)rPar.Get(1)->GetObject();
952 0 : SbxObject* pObj = NULL;
953 0 : if( pObjVar )
954 : {
955 0 : pObj = PTR_CAST(SbxObject,pObjVar);
956 : }
957 0 : if( !pObj && pObjVar && pObjVar->ISA(SbxVariable) )
958 : {
959 0 : SbxBase* pObjVarObj = ((SbxVariable*)pObjVar)->GetObject();
960 0 : pObj = PTR_CAST(SbxObject,pObjVarObj);
961 : }
962 :
963 0 : OUString aNameStr = rPar.Get(2)->GetOUString();
964 :
965 0 : SbxObject* pFindObj = NULL;
966 0 : if( pObj )
967 : {
968 0 : SbxVariable* pFindVar = pObj->Find( aNameStr, SbxCLASS_OBJECT );
969 0 : pFindObj = PTR_CAST(SbxObject,pFindVar);
970 : }
971 : else
972 : {
973 0 : StarBASIC::Error( SbERR_BAD_PARAMETER );
974 : }
975 :
976 0 : SbxVariableRef refVar = rPar.Get(0);
977 0 : refVar->PutObject( pFindObj );
978 : }
979 :
980 :
981 :
982 0 : static sal_Bool lcl_WriteSbxVariable( const SbxVariable& rVar, SvStream* pStrm,
983 : sal_Bool bBinary, short nBlockLen, sal_Bool bIsArray )
984 : {
985 0 : sal_uIntPtr nFPos = pStrm->Tell();
986 :
987 0 : sal_Bool bIsVariant = !rVar.IsFixed();
988 0 : SbxDataType eType = rVar.GetType();
989 :
990 0 : switch( eType )
991 : {
992 : case SbxBOOL:
993 : case SbxCHAR:
994 : case SbxBYTE:
995 0 : if( bIsVariant )
996 : {
997 0 : *pStrm << (sal_uInt16)SbxBYTE; // VarType Id
998 : }
999 0 : *pStrm << rVar.GetByte();
1000 0 : break;
1001 :
1002 : case SbxEMPTY:
1003 : case SbxNULL:
1004 : case SbxVOID:
1005 : case SbxINTEGER:
1006 : case SbxUSHORT:
1007 : case SbxINT:
1008 : case SbxUINT:
1009 0 : if( bIsVariant )
1010 : {
1011 0 : *pStrm << (sal_uInt16)SbxINTEGER; // VarType Id
1012 : }
1013 0 : *pStrm << rVar.GetInteger();
1014 0 : break;
1015 :
1016 : case SbxLONG:
1017 : case SbxULONG:
1018 0 : if( bIsVariant )
1019 : {
1020 0 : *pStrm << (sal_uInt16)SbxLONG; // VarType Id
1021 : }
1022 0 : *pStrm << rVar.GetLong();
1023 0 : break;
1024 : case SbxSALINT64:
1025 : case SbxSALUINT64:
1026 0 : if( bIsVariant )
1027 : {
1028 0 : *pStrm << (sal_uInt16)SbxSALINT64; // VarType Id
1029 : }
1030 0 : *pStrm << (sal_uInt64)rVar.GetInt64();
1031 0 : break;
1032 : case SbxSINGLE:
1033 0 : if( bIsVariant )
1034 : {
1035 0 : *pStrm << (sal_uInt16)eType; // VarType Id
1036 : }
1037 0 : *pStrm << rVar.GetSingle();
1038 0 : break;
1039 :
1040 : case SbxDOUBLE:
1041 : case SbxCURRENCY:
1042 : case SbxDATE:
1043 0 : if( bIsVariant )
1044 : {
1045 0 : *pStrm << (sal_uInt16)eType; // VarType Id
1046 : }
1047 0 : *pStrm << rVar.GetDouble();
1048 0 : break;
1049 :
1050 : case SbxSTRING:
1051 : case SbxLPSTR:
1052 : {
1053 0 : const OUString& rStr = rVar.GetOUString();
1054 0 : if( !bBinary || bIsArray )
1055 : {
1056 0 : if( bIsVariant )
1057 : {
1058 0 : *pStrm << (sal_uInt16)SbxSTRING;
1059 : }
1060 0 : pStrm->WriteUniOrByteString( rStr, osl_getThreadTextEncoding() );
1061 : }
1062 : else
1063 : {
1064 : // without any length information! without end-identifier!
1065 : // What does that mean for Unicode?! Choosing conversion to ByteString...
1066 0 : rtl::OString aByteStr(rtl::OUStringToOString(rStr, osl_getThreadTextEncoding()));
1067 0 : *pStrm << (const char*)aByteStr.getStr();
1068 0 : }
1069 : }
1070 0 : break;
1071 :
1072 : default:
1073 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1074 0 : return sal_False;
1075 : }
1076 :
1077 0 : if( nBlockLen )
1078 : {
1079 0 : pStrm->Seek( nFPos + nBlockLen );
1080 : }
1081 0 : return pStrm->GetErrorCode() ? sal_False : sal_True;
1082 : }
1083 :
1084 0 : static sal_Bool lcl_ReadSbxVariable( SbxVariable& rVar, SvStream* pStrm,
1085 : sal_Bool bBinary, short nBlockLen, sal_Bool bIsArray )
1086 : {
1087 : (void)bBinary;
1088 : (void)bIsArray;
1089 :
1090 : double aDouble;
1091 :
1092 0 : sal_uIntPtr nFPos = pStrm->Tell();
1093 :
1094 0 : sal_Bool bIsVariant = !rVar.IsFixed();
1095 0 : SbxDataType eVarType = rVar.GetType();
1096 :
1097 0 : SbxDataType eSrcType = eVarType;
1098 0 : if( bIsVariant )
1099 : {
1100 : sal_uInt16 nTemp;
1101 0 : *pStrm >> nTemp;
1102 0 : eSrcType = (SbxDataType)nTemp;
1103 : }
1104 :
1105 0 : switch( eSrcType )
1106 : {
1107 : case SbxBOOL:
1108 : case SbxCHAR:
1109 : case SbxBYTE:
1110 : {
1111 : sal_uInt8 aByte;
1112 0 : *pStrm >> aByte;
1113 :
1114 0 : if( bBinary && SbiRuntime::isVBAEnabled() && aByte == 1 && pStrm->IsEof() )
1115 : {
1116 0 : aByte = 0;
1117 : }
1118 0 : rVar.PutByte( aByte );
1119 : }
1120 0 : break;
1121 :
1122 : case SbxEMPTY:
1123 : case SbxNULL:
1124 : case SbxVOID:
1125 : case SbxINTEGER:
1126 : case SbxUSHORT:
1127 : case SbxINT:
1128 : case SbxUINT:
1129 : {
1130 : sal_Int16 aInt;
1131 0 : *pStrm >> aInt;
1132 0 : rVar.PutInteger( aInt );
1133 : }
1134 0 : break;
1135 :
1136 : case SbxLONG:
1137 : case SbxULONG:
1138 : {
1139 : sal_Int32 aInt;
1140 0 : *pStrm >> aInt;
1141 0 : rVar.PutLong( aInt );
1142 : }
1143 0 : break;
1144 : case SbxSALINT64:
1145 : case SbxSALUINT64:
1146 : {
1147 : sal_uInt32 aInt;
1148 0 : *pStrm >> aInt;
1149 0 : rVar.PutInt64( (sal_Int64)aInt );
1150 : }
1151 0 : break;
1152 : case SbxSINGLE:
1153 : {
1154 : float nS;
1155 0 : *pStrm >> nS;
1156 0 : rVar.PutSingle( nS );
1157 : }
1158 0 : break;
1159 :
1160 : case SbxDOUBLE:
1161 : case SbxCURRENCY:
1162 : {
1163 0 : *pStrm >> aDouble;
1164 0 : rVar.PutDouble( aDouble );
1165 : }
1166 0 : break;
1167 :
1168 : case SbxDATE:
1169 : {
1170 0 : *pStrm >> aDouble;
1171 0 : rVar.PutDate( aDouble );
1172 : }
1173 0 : break;
1174 :
1175 : case SbxSTRING:
1176 : case SbxLPSTR:
1177 : {
1178 0 : OUString aStr = pStrm->ReadUniOrByteString(osl_getThreadTextEncoding());
1179 0 : rVar.PutString( aStr );
1180 : }
1181 0 : break;
1182 :
1183 : default:
1184 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1185 0 : return sal_False;
1186 : }
1187 :
1188 0 : if( nBlockLen )
1189 : {
1190 0 : pStrm->Seek( nFPos + nBlockLen );
1191 : }
1192 0 : return pStrm->GetErrorCode() ? sal_False : sal_True;
1193 : }
1194 :
1195 :
1196 : // nCurDim = 1...n
1197 0 : static sal_Bool lcl_WriteReadSbxArray( SbxDimArray& rArr, SvStream* pStrm,
1198 : sal_Bool bBinary, short nCurDim, short* pOtherDims, sal_Bool bWrite )
1199 : {
1200 : DBG_ASSERT( nCurDim > 0,"Bad Dim");
1201 : short nLower, nUpper;
1202 0 : if( !rArr.GetDim( nCurDim, nLower, nUpper ) )
1203 0 : return sal_False;
1204 0 : for( short nCur = nLower; nCur <= nUpper; nCur++ )
1205 : {
1206 0 : pOtherDims[ nCurDim-1 ] = nCur;
1207 0 : if( nCurDim != 1 )
1208 0 : lcl_WriteReadSbxArray(rArr, pStrm, bBinary, nCurDim-1, pOtherDims, bWrite);
1209 : else
1210 : {
1211 0 : SbxVariable* pVar = rArr.Get( (const short*)pOtherDims );
1212 : sal_Bool bRet;
1213 0 : if( bWrite )
1214 0 : bRet = lcl_WriteSbxVariable(*pVar, pStrm, bBinary, 0, sal_True );
1215 : else
1216 0 : bRet = lcl_ReadSbxVariable(*pVar, pStrm, bBinary, 0, sal_True );
1217 0 : if( !bRet )
1218 0 : return sal_False;
1219 : }
1220 : }
1221 0 : return sal_True;
1222 : }
1223 :
1224 0 : void PutGet( SbxArray& rPar, sal_Bool bPut )
1225 : {
1226 0 : if ( rPar.Count() != 4 )
1227 : {
1228 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1229 0 : return;
1230 : }
1231 0 : sal_Int16 nFileNo = rPar.Get(1)->GetInteger();
1232 0 : SbxVariable* pVar2 = rPar.Get(2);
1233 0 : SbxDataType eType2 = pVar2->GetType();
1234 0 : bool bHasRecordNo = (eType2 != SbxEMPTY && eType2 != SbxERROR);
1235 0 : long nRecordNo = pVar2->GetLong();
1236 0 : if ( nFileNo < 1 || ( bHasRecordNo && nRecordNo < 1 ) )
1237 : {
1238 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1239 0 : return;
1240 : }
1241 0 : nRecordNo--;
1242 0 : SbiIoSystem* pIO = GetSbData()->pInst->GetIoSystem();
1243 0 : SbiStream* pSbStrm = pIO->GetStream( nFileNo );
1244 :
1245 0 : if ( !pSbStrm || !(pSbStrm->GetMode() & (SBSTRM_BINARY | SBSTRM_RANDOM)) )
1246 : {
1247 0 : StarBASIC::Error( SbERR_BAD_CHANNEL );
1248 0 : return;
1249 : }
1250 :
1251 0 : SvStream* pStrm = pSbStrm->GetStrm();
1252 0 : bool bRandom = pSbStrm->IsRandom();
1253 0 : short nBlockLen = bRandom ? pSbStrm->GetBlockLen() : 0;
1254 :
1255 0 : if( bPut )
1256 : {
1257 0 : pSbStrm->ExpandFile();
1258 : }
1259 :
1260 0 : if( bHasRecordNo )
1261 : {
1262 0 : sal_uIntPtr nFilePos = bRandom ? (sal_uIntPtr)(nBlockLen*nRecordNo) : (sal_uIntPtr)nRecordNo;
1263 0 : pStrm->Seek( nFilePos );
1264 : }
1265 :
1266 0 : SbxDimArray* pArr = 0;
1267 0 : SbxVariable* pVar = rPar.Get(3);
1268 0 : if( pVar->GetType() & SbxARRAY )
1269 : {
1270 0 : SbxBase* pParObj = pVar->GetObject();
1271 0 : pArr = PTR_CAST(SbxDimArray,pParObj);
1272 : }
1273 :
1274 : sal_Bool bRet;
1275 :
1276 0 : if( pArr )
1277 : {
1278 0 : sal_uIntPtr nFPos = pStrm->Tell();
1279 0 : short nDims = pArr->GetDims();
1280 0 : short* pDims = new short[ nDims ];
1281 0 : bRet = lcl_WriteReadSbxArray(*pArr,pStrm,!bRandom,nDims,pDims,bPut);
1282 0 : delete [] pDims;
1283 0 : if( nBlockLen )
1284 0 : pStrm->Seek( nFPos + nBlockLen );
1285 : }
1286 : else
1287 : {
1288 0 : if( bPut )
1289 0 : bRet = lcl_WriteSbxVariable(*pVar, pStrm, !bRandom, nBlockLen, sal_False);
1290 : else
1291 0 : bRet = lcl_ReadSbxVariable(*pVar, pStrm, !bRandom, nBlockLen, sal_False);
1292 : }
1293 0 : if( !bRet || pStrm->GetErrorCode() )
1294 0 : StarBASIC::Error( SbERR_IO_ERROR );
1295 : }
1296 :
1297 0 : RTLFUNC(Put)
1298 : {
1299 : (void)pBasic;
1300 : (void)bWrite;
1301 :
1302 0 : PutGet( rPar, sal_True );
1303 0 : }
1304 :
1305 0 : RTLFUNC(Get)
1306 : {
1307 : (void)pBasic;
1308 : (void)bWrite;
1309 :
1310 0 : PutGet( rPar, sal_False );
1311 0 : }
1312 :
1313 0 : RTLFUNC(Environ)
1314 : {
1315 : (void)pBasic;
1316 : (void)bWrite;
1317 :
1318 0 : if ( rPar.Count() != 2 )
1319 : {
1320 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1321 0 : return;
1322 : }
1323 0 : OUString aResult;
1324 : // should be ANSI but that's not possible under Win16 in the DLL
1325 0 : rtl::OString aByteStr(rtl::OUStringToOString(rPar.Get(1)->GetOUString(),
1326 0 : osl_getThreadTextEncoding()));
1327 0 : const char* pEnvStr = getenv(aByteStr.getStr());
1328 0 : if ( pEnvStr )
1329 : {
1330 0 : aResult = rtl::OUString::createFromAscii( pEnvStr );
1331 : }
1332 0 : rPar.Get(0)->PutString( aResult );
1333 : }
1334 :
1335 0 : static double GetDialogZoomFactor( bool bX, long nValue )
1336 : {
1337 0 : OutputDevice* pDevice = Application::GetDefaultDevice();
1338 0 : double nResult = 0;
1339 0 : if( pDevice )
1340 : {
1341 0 : Size aRefSize( nValue, nValue );
1342 0 : Fraction aFracX( 1, 26 );
1343 0 : Fraction aFracY( 1, 24 );
1344 0 : MapMode aMap( MAP_APPFONT, Point(), aFracX, aFracY );
1345 0 : Size aScaledSize = pDevice->LogicToPixel( aRefSize, aMap );
1346 0 : aRefSize = pDevice->LogicToPixel( aRefSize, MapMode(MAP_TWIP) );
1347 :
1348 : double nRef, nScaled;
1349 0 : if( bX )
1350 : {
1351 0 : nRef = aRefSize.Width();
1352 0 : nScaled = aScaledSize.Width();
1353 : }
1354 : else
1355 : {
1356 0 : nRef = aRefSize.Height();
1357 0 : nScaled = aScaledSize.Height();
1358 : }
1359 0 : nResult = nScaled / nRef;
1360 : }
1361 0 : return nResult;
1362 : }
1363 :
1364 :
1365 0 : RTLFUNC(GetDialogZoomFactorX)
1366 : {
1367 : (void)pBasic;
1368 : (void)bWrite;
1369 :
1370 0 : if ( rPar.Count() != 2 )
1371 : {
1372 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1373 0 : return;
1374 : }
1375 0 : rPar.Get(0)->PutDouble( GetDialogZoomFactor( true, rPar.Get(1)->GetLong() ));
1376 : }
1377 :
1378 0 : RTLFUNC(GetDialogZoomFactorY)
1379 : {
1380 : (void)pBasic;
1381 : (void)bWrite;
1382 :
1383 0 : if ( rPar.Count() != 2 )
1384 : {
1385 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1386 0 : return;
1387 : }
1388 0 : rPar.Get(0)->PutDouble( GetDialogZoomFactor( false, rPar.Get(1)->GetLong()));
1389 : }
1390 :
1391 :
1392 0 : RTLFUNC(EnableReschedule)
1393 : {
1394 : (void)pBasic;
1395 : (void)bWrite;
1396 :
1397 0 : rPar.Get(0)->PutEmpty();
1398 0 : if ( rPar.Count() != 2 )
1399 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1400 0 : if( GetSbData()->pInst )
1401 0 : GetSbData()->pInst->EnableReschedule( rPar.Get(1)->GetBool() );
1402 0 : }
1403 :
1404 0 : RTLFUNC(GetSystemTicks)
1405 : {
1406 : (void)pBasic;
1407 : (void)bWrite;
1408 :
1409 0 : if ( rPar.Count() != 1 )
1410 : {
1411 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1412 0 : return;
1413 : }
1414 0 : rPar.Get(0)->PutLong( Time::GetSystemTicks() );
1415 : }
1416 :
1417 0 : RTLFUNC(GetPathSeparator)
1418 : {
1419 : (void)pBasic;
1420 : (void)bWrite;
1421 :
1422 0 : if ( rPar.Count() != 1 )
1423 : {
1424 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1425 0 : return;
1426 : }
1427 0 : rPar.Get(0)->PutString( DirEntry::GetAccessDelimiter() );
1428 : }
1429 :
1430 0 : RTLFUNC(ResolvePath)
1431 : {
1432 : (void)pBasic;
1433 : (void)bWrite;
1434 :
1435 0 : if ( rPar.Count() == 2 )
1436 : {
1437 0 : OUString aStr = rPar.Get(1)->GetOUString();
1438 0 : DirEntry aEntry( aStr );
1439 0 : rPar.Get(0)->PutString( aStr );
1440 : }
1441 : else
1442 : {
1443 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1444 : }
1445 0 : }
1446 :
1447 0 : RTLFUNC(TypeLen)
1448 : {
1449 : (void)pBasic;
1450 : (void)bWrite;
1451 :
1452 0 : if ( rPar.Count() != 2 )
1453 : {
1454 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
1455 : }
1456 : else
1457 : {
1458 0 : SbxDataType eType = rPar.Get(1)->GetType();
1459 0 : sal_Int16 nLen = 0;
1460 0 : switch( eType )
1461 : {
1462 : case SbxEMPTY:
1463 : case SbxNULL:
1464 : case SbxVECTOR:
1465 : case SbxARRAY:
1466 : case SbxBYREF:
1467 : case SbxVOID:
1468 : case SbxHRESULT:
1469 : case SbxPOINTER:
1470 : case SbxDIMARRAY:
1471 : case SbxCARRAY:
1472 : case SbxUSERDEF:
1473 0 : nLen = 0;
1474 0 : break;
1475 :
1476 : case SbxINTEGER:
1477 : case SbxERROR:
1478 : case SbxUSHORT:
1479 : case SbxINT:
1480 : case SbxUINT:
1481 0 : nLen = 2;
1482 0 : break;
1483 :
1484 : case SbxLONG:
1485 : case SbxSINGLE:
1486 : case SbxULONG:
1487 0 : nLen = 4;
1488 0 : break;
1489 :
1490 : case SbxDOUBLE:
1491 : case SbxCURRENCY:
1492 : case SbxDATE:
1493 : case SbxSALINT64:
1494 : case SbxSALUINT64:
1495 0 : nLen = 8;
1496 0 : break;
1497 :
1498 : case SbxOBJECT:
1499 : case SbxVARIANT:
1500 : case SbxDATAOBJECT:
1501 0 : nLen = 0;
1502 0 : break;
1503 :
1504 : case SbxCHAR:
1505 : case SbxBYTE:
1506 : case SbxBOOL:
1507 0 : nLen = 1;
1508 0 : break;
1509 :
1510 : case SbxLPSTR:
1511 : case SbxLPWSTR:
1512 : case SbxCoreSTRING:
1513 : case SbxSTRING:
1514 0 : nLen = (sal_Int16)rPar.Get(1)->GetOUString().getLength();
1515 0 : break;
1516 :
1517 : default:
1518 0 : nLen = 0;
1519 0 : break;
1520 : }
1521 0 : rPar.Get(0)->PutInteger( nLen );
1522 : }
1523 0 : }
1524 :
1525 :
1526 : // 1st parameter == class name, other parameters for initialisation
1527 0 : RTLFUNC(CreateUnoStruct)
1528 : {
1529 : (void)pBasic;
1530 : (void)bWrite;
1531 :
1532 0 : RTL_Impl_CreateUnoStruct( pBasic, rPar, bWrite );
1533 0 : }
1534 :
1535 :
1536 : // 1st parameter == service-name
1537 0 : RTLFUNC(CreateUnoService)
1538 : {
1539 : (void)pBasic;
1540 : (void)bWrite;
1541 :
1542 0 : RTL_Impl_CreateUnoService( pBasic, rPar, bWrite );
1543 0 : }
1544 :
1545 0 : RTLFUNC(CreateUnoServiceWithArguments)
1546 : {
1547 : (void)pBasic;
1548 : (void)bWrite;
1549 :
1550 0 : RTL_Impl_CreateUnoServiceWithArguments( pBasic, rPar, bWrite );
1551 0 : }
1552 :
1553 :
1554 0 : RTLFUNC(CreateUnoValue)
1555 : {
1556 : (void)pBasic;
1557 : (void)bWrite;
1558 :
1559 0 : RTL_Impl_CreateUnoValue( pBasic, rPar, bWrite );
1560 0 : }
1561 :
1562 :
1563 : // no parameters
1564 0 : RTLFUNC(GetProcessServiceManager)
1565 : {
1566 : (void)pBasic;
1567 : (void)bWrite;
1568 :
1569 0 : RTL_Impl_GetProcessServiceManager( pBasic, rPar, bWrite );
1570 0 : }
1571 :
1572 :
1573 : // 1st parameter == Sequence<PropertyValue>
1574 0 : RTLFUNC(CreatePropertySet)
1575 : {
1576 : (void)pBasic;
1577 : (void)bWrite;
1578 :
1579 0 : RTL_Impl_CreatePropertySet( pBasic, rPar, bWrite );
1580 0 : }
1581 :
1582 :
1583 : // multiple interface-names as parameters
1584 0 : RTLFUNC(HasUnoInterfaces)
1585 : {
1586 : (void)pBasic;
1587 : (void)bWrite;
1588 :
1589 0 : RTL_Impl_HasInterfaces( pBasic, rPar, bWrite );
1590 0 : }
1591 :
1592 :
1593 0 : RTLFUNC(IsUnoStruct)
1594 : {
1595 : (void)pBasic;
1596 : (void)bWrite;
1597 :
1598 0 : RTL_Impl_IsUnoStruct( pBasic, rPar, bWrite );
1599 0 : }
1600 :
1601 :
1602 0 : RTLFUNC(EqualUnoObjects)
1603 : {
1604 : (void)pBasic;
1605 : (void)bWrite;
1606 :
1607 0 : RTL_Impl_EqualUnoObjects( pBasic, rPar, bWrite );
1608 0 : }
1609 :
1610 : // Instanciate "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 0 : RTLFUNC(GetDefaultContext)
1690 : {
1691 : (void)pBasic;
1692 : (void)bWrite;
1693 :
1694 0 : RTL_Impl_GetDefaultContext( pBasic, rPar, bWrite );
1695 0 : }
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 : 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 : return;
1856 : }
1857 :
1858 0 : Reference< XCalendar3 > xCalendar = getLocaleCalendar();
1859 0 : if( !xCalendar.is() )
1860 : {
1861 0 : StarBASIC::Error( SbERR_INTERNAL_ERROR );
1862 : 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 : 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 : return;
1896 : }
1897 :
1898 0 : Reference< XCalendar3 > xCalendar = getLocaleCalendar();
1899 0 : if( !xCalendar.is() )
1900 : {
1901 0 : StarBASIC::Error( SbERR_INTERNAL_ERROR );
1902 : 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 : 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 : 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 : 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 : 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 : 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 : 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 : 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 : 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 : 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 : 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 : 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 : 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 : 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 : 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 : return;
2504 : }
2505 : }
2506 :
2507 0 : Reference< XCalendar3 > xCalendar = getLocaleCalendar();
2508 0 : if( !xCalendar.is() )
2509 : {
2510 0 : StarBASIC::Error( SbERR_INTERNAL_ERROR );
2511 : 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 : 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 : 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 : 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 : 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 rtl::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(OUString("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, OUString( "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, OUString( "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, OUString( "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, OUString( "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, OUString( "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, OUString( "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, OUString( "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, OUString( "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, OUString( "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, OUString( "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, OUString( "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, OUString( "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, OUString( "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 : return;
3214 : }
3215 :
3216 0 : SbxVariable *pSbxVariable = rPar.Get(1);
3217 0 : if( pSbxVariable->IsNull() )
3218 : {
3219 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3220 : return;
3221 : }
3222 :
3223 0 : rtl::OUString aStr = comphelper::string::reverseString(pSbxVariable->GetOUString());
3224 0 : rPar.Get(0)->PutString( aStr );
3225 : }
3226 :
3227 0 : RTLFUNC(CompatibilityMode)
3228 : {
3229 : (void)pBasic;
3230 : (void)bWrite;
3231 :
3232 0 : bool bEnabled = false;
3233 0 : sal_uInt16 nCount = rPar.Count();
3234 0 : if ( nCount != 1 && nCount != 2 )
3235 0 : StarBASIC::Error( SbERR_BAD_ARGUMENT );
3236 :
3237 0 : SbiInstance* pInst = GetSbData()->pInst;
3238 0 : if( pInst )
3239 : {
3240 0 : if ( nCount == 2 )
3241 : {
3242 0 : pInst->EnableCompatibility( rPar.Get(1)->GetBool() );
3243 : }
3244 0 : bEnabled = pInst->IsCompatibility();
3245 : }
3246 0 : rPar.Get(0)->PutBool( bEnabled );
3247 0 : }
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 : 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 : return;
3270 : }
3271 :
3272 0 : rtl::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 : return;
3281 : }
3282 0 : rPar.Get(0)->PutString(rtl::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 : }
3346 :
3347 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|