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