1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_features.h>
22 #include <sal/config.h>
23 #include <config_version.h>
28 #include <vcl/svapp.hxx>
29 #include <vcl/mapmod.hxx>
30 #include <vcl/wrkwin.hxx>
31 #include <vcl/timer.hxx>
32 #include <vcl/settings.hxx>
33 #include <basic/sbxvar.hxx>
34 #include <basic/sbx.hxx>
35 #include <svl/zforlist.hxx>
36 #include <tools/urlobj.hxx>
37 #include <tools/fract.hxx>
38 #include <osl/file.hxx>
39 #include <vcl/jobset.hxx>
40 #include "sbobjmod.hxx"
41 #include <basic/sbuno.hxx>
44 #include "sbintern.hxx"
45 #include "runtime.hxx"
47 #include "rtlproto.hxx"
50 #include "sbunoobj.hxx"
51 #include "propacc.hxx"
52 #include <sal/log.hxx>
53 #include <eventatt.hxx>
55 #include <comphelper/processfactory.hxx>
56 #include <comphelper/string.hxx>
58 #include <com/sun/star/uno/Sequence.hxx>
59 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
60 #include <com/sun/star/i18n/LocaleCalendar2.hpp>
61 #include <com/sun/star/sheet/XFunctionAccess.hpp>
62 #include <boost/scoped_array.hpp>
64 using namespace comphelper
;
65 using namespace com::sun::star::i18n
;
66 using namespace com::sun::star::lang
;
67 using namespace com::sun::star::sheet
;
68 using namespace com::sun::star::uno
;
70 static Reference
< XCalendar4
> getLocaleCalendar()
72 static Reference
< XCalendar4
> xCalendar
;
75 Reference
< XComponentContext
> xContext
= getProcessComponentContext();
76 xCalendar
= LocaleCalendar2::create(xContext
);
79 static com::sun::star::lang::Locale aLastLocale
;
80 static bool bNeedsInit
= true;
82 com::sun::star::lang::Locale aLocale
= Application::GetSettings().GetLanguageTag().getLocale();
83 bool bNeedsReload
= false;
89 else if( aLocale
.Language
!= aLastLocale
.Language
||
90 aLocale
.Country
!= aLastLocale
.Country
||
91 aLocale
.Variant
!= aLastLocale
.Variant
)
97 aLastLocale
= aLocale
;
98 xCalendar
->loadDefaultCalendar( aLocale
);
103 #if HAVE_FEATURE_SCRIPTING
110 const sal_Int16 vbGet
= 2;
111 const sal_Int16 vbLet
= 4;
112 const sal_Int16 vbMethod
= 1;
113 const sal_Int16 vbSet
= 8;
115 // At least 3 parameter needed plus function itself -> 4
116 sal_uInt16 nParCount
= rPar
.Count();
119 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
123 // 1. parameter is object
124 SbxBase
* pObjVar
= static_cast<SbxObject
*>(rPar
.Get(1)->GetObject());
125 SbxObject
* pObj
= NULL
;
127 pObj
= PTR_CAST(SbxObject
,pObjVar
);
128 if( !pObj
&& pObjVar
&& pObjVar
->ISA(SbxVariable
) )
130 SbxBase
* pObjVarObj
= static_cast<SbxVariable
*>(pObjVar
)->GetObject();
131 pObj
= PTR_CAST(SbxObject
,pObjVarObj
);
135 StarBASIC::Error( SbERR_BAD_PARAMETER
);
139 // 2. parameter is ProcedureName
140 OUString aNameStr
= rPar
.Get(2)->GetOUString();
142 // 3. parameter is CallType
143 sal_Int16 nCallType
= rPar
.Get(3)->GetInteger();
145 //SbxObject* pFindObj = NULL;
146 SbxVariable
* pFindVar
= pObj
->Find( aNameStr
, SbxCLASS_DONTCARE
);
147 if( pFindVar
== NULL
)
149 StarBASIC::Error( SbERR_PROC_UNDEFINED
);
158 aVals
.eType
= SbxVARIANT
;
159 pFindVar
->Get( aVals
);
161 SbxVariableRef refVar
= rPar
.Get(0);
162 refVar
->Put( aVals
);
168 if ( nParCount
!= 5 )
170 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
173 SbxVariableRef pValVar
= rPar
.Get(4);
174 if( nCallType
== vbLet
)
177 aVals
.eType
= SbxVARIANT
;
178 pValVar
->Get( aVals
);
179 pFindVar
->Put( aVals
);
183 SbxVariableRef rFindVar
= pFindVar
;
184 SbiInstance
* pInst
= GetSbData()->pInst
;
185 SbiRuntime
* pRT
= pInst
? pInst
->pRun
: NULL
;
188 pRT
->StepSET_Impl( pValVar
, rFindVar
, false );
195 SbMethod
* pMeth
= PTR_CAST(SbMethod
,pFindVar
);
198 StarBASIC::Error( SbERR_PROC_UNDEFINED
);
204 sal_uInt16 nMethParamCount
= nParCount
- 4;
205 if( nMethParamCount
> 0 )
207 xArray
= new SbxArray
;
208 for( sal_uInt16 i
= 0 ; i
< nMethParamCount
; i
++ )
210 SbxVariable
* pPar
= rPar
.Get( i
+ 4 );
211 xArray
->Put( pPar
, i
+ 1 );
216 SbxVariableRef refVar
= rPar
.Get(0);
218 pMeth
->SetParameters( xArray
);
219 pMeth
->Call( refVar
);
220 pMeth
->SetParameters( NULL
);
224 StarBASIC::Error( SbERR_PROC_UNDEFINED
);
228 RTLFUNC(CBool
) // JSM
234 if ( rPar
.Count() == 2 )
236 SbxVariable
*pSbxVariable
= rPar
.Get(1);
237 bVal
= pSbxVariable
->GetBool();
241 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
243 rPar
.Get(0)->PutBool(bVal
);
246 RTLFUNC(CByte
) // JSM
252 if ( rPar
.Count() == 2 )
254 SbxVariable
*pSbxVariable
= rPar
.Get(1);
255 nByte
= pSbxVariable
->GetByte();
259 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
261 rPar
.Get(0)->PutByte(nByte
);
270 if ( rPar
.Count() == 2 )
272 SbxVariable
*pSbxVariable
= rPar
.Get(1);
273 nCur
= pSbxVariable
->GetCurrency();
277 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
279 rPar
.Get(0)->PutCurrency( nCur
);
288 SbxDecimal
* pDec
= NULL
;
289 if ( rPar
.Count() == 2 )
291 SbxVariable
*pSbxVariable
= rPar
.Get(1);
292 pDec
= pSbxVariable
->GetDecimal();
296 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
298 rPar
.Get(0)->PutDecimal( pDec
);
300 rPar
.Get(0)->PutEmpty();
301 StarBASIC::Error(SbERR_NOT_IMPLEMENTED
);
305 RTLFUNC(CDate
) // JSM
311 if ( rPar
.Count() == 2 )
313 SbxVariable
*pSbxVariable
= rPar
.Get(1);
314 nVal
= pSbxVariable
->GetDate();
318 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
320 rPar
.Get(0)->PutDate(nVal
);
329 if ( rPar
.Count() == 2 )
331 SbxVariable
*pSbxVariable
= rPar
.Get(1);
332 if( pSbxVariable
->GetType() == SbxSTRING
)
335 OUString aScanStr
= pSbxVariable
->GetOUString();
336 SbError Error
= SbxValue::ScanNumIntnl( aScanStr
, nVal
);
337 if( Error
!= SbxERR_OK
)
339 StarBASIC::Error( Error
);
344 nVal
= pSbxVariable
->GetDouble();
349 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
352 rPar
.Get(0)->PutDouble(nVal
);
361 if ( rPar
.Count() == 2 )
363 SbxVariable
*pSbxVariable
= rPar
.Get(1);
364 nVal
= pSbxVariable
->GetInteger();
368 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
370 rPar
.Get(0)->PutInteger(nVal
);
379 if ( rPar
.Count() == 2 )
381 SbxVariable
*pSbxVariable
= rPar
.Get(1);
382 nVal
= pSbxVariable
->GetLong();
386 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
388 rPar
.Get(0)->PutLong(nVal
);
396 float nVal
= (float)0.0;
397 if ( rPar
.Count() == 2 )
399 SbxVariable
*pSbxVariable
= rPar
.Get(1);
400 if( pSbxVariable
->GetType() == SbxSTRING
)
404 OUString aScanStr
= pSbxVariable
->GetOUString();
405 SbError Error
= SbxValue::ScanNumIntnl( aScanStr
, dVal
, /*bSingle=*/true );
406 if( SbxBase::GetError() == SbxERR_OK
&& Error
!= SbxERR_OK
)
408 StarBASIC::Error( Error
);
414 nVal
= pSbxVariable
->GetSingle();
419 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
421 rPar
.Get(0)->PutSingle(nVal
);
430 if ( rPar
.Count() == 2 )
432 SbxVariable
*pSbxVariable
= rPar
.Get(1);
433 aString
= pSbxVariable
->GetOUString();
437 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
439 rPar
.Get(0)->PutString(aString
);
447 SbxValues
aVals( SbxVARIANT
);
448 if ( rPar
.Count() == 2 )
450 SbxVariable
*pSbxVariable
= rPar
.Get(1);
451 pSbxVariable
->Get( aVals
);
455 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
457 rPar
.Get(0)->Put( aVals
);
465 sal_Int16 nErrCode
= 0;
466 if ( rPar
.Count() == 2 )
468 SbxVariable
*pSbxVariable
= rPar
.Get(1);
469 nErrCode
= pSbxVariable
->GetInteger();
473 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
475 rPar
.Get(0)->PutErr( nErrCode
);
483 if ( rPar
.Count() == 4 )
485 if (rPar
.Get(1)->GetBool())
487 *rPar
.Get(0) = *rPar
.Get(2);
491 *rPar
.Get(0) = *rPar
.Get(3);
496 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
500 RTLFUNC(GetSystemType
)
505 if ( rPar
.Count() != 1 )
507 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
511 // Removed for SRC595
512 rPar
.Get(0)->PutInteger( -1 );
521 if ( rPar
.Count() != 1 )
523 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
527 // 17.7.2000 Make simple solution for testtool / fat office
529 rPar
.Get(0)->PutInteger( 1 );
531 rPar
.Get(0)->PutInteger( 4 );
533 rPar
.Get(0)->PutInteger( -1 );
543 if ( rPar
.Count() != 2 )
545 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
549 sal_Int32 nRGB
= rPar
.Get(1)->GetLong();
552 rPar
.Get(0)->PutInteger( (sal_Int16
)nRGB
);
561 if ( rPar
.Count() != 2 )
563 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
567 sal_Int32 nRGB
= rPar
.Get(1)->GetLong();
570 rPar
.Get(0)->PutInteger( (sal_Int16
)nRGB
);
579 if ( rPar
.Count() != 2 )
581 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
585 sal_Int32 nRGB
= rPar
.Get(1)->GetLong();
587 rPar
.Get(0)->PutInteger( (sal_Int16
)nRGB
);
597 sal_uInt16 nCount
= rPar
.Count();
598 if( !(nCount
& 0x0001 ))
600 // number of arguments must be odd
601 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
603 sal_uInt16 nCurExpr
= 1;
604 while( nCurExpr
< (nCount
-1) )
606 if( rPar
.Get( nCurExpr
)->GetBool())
608 (*rPar
.Get(0)) = *(rPar
.Get(nCurExpr
+1));
613 rPar
.Get(0)->PutNull();
616 //i#64882# Common wait impl for existing Wait and new WaitUntil
618 void Wait_Impl( bool bDurationBased
, SbxArray
& rPar
)
620 if( rPar
.Count() != 2 )
622 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
626 if ( bDurationBased
)
628 double dWait
= rPar
.Get(1)->GetDouble();
629 double dNow
= Now_Impl();
630 double dSecs
= (double)( ( dWait
- dNow
) * (double)( 24.0*3600.0) );
631 nWait
= (long)( dSecs
* 1000 ); // wait in thousands of sec
635 nWait
= rPar
.Get(1)->GetLong();
639 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
644 aTimer
.SetTimeout( nWait
);
646 while ( aTimer
.IsActive() )
648 Application::Yield();
657 Wait_Impl( false, rPar
);
660 //i#64882# add new WaitUntil ( for application.wait )
661 // share wait_impl with 'normal' oobasic wait
666 Wait_Impl( true, rPar
);
674 // don't undstand what upstream are up to
675 // we already process application events etc. in between
676 // basic runtime pcode ( on a timed basis )
678 rPar
.Get(0)->PutInteger( 0 );
679 Application::Reschedule( true );
682 RTLFUNC(GetGUIVersion
)
687 if ( rPar
.Count() != 1 )
689 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
693 // Removed for SRC595
694 rPar
.Get(0)->PutLong( -1 );
703 if ( rPar
.Count() < 2 )
705 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
707 sal_Int16 nIndex
= rPar
.Get(1)->GetInteger();
708 sal_uInt16 nCount
= rPar
.Count();
710 if( nCount
== 1 || nIndex
> (nCount
-1) || nIndex
< 1 )
712 rPar
.Get(0)->PutNull();
715 (*rPar
.Get(0)) = *(rPar
.Get(nIndex
+1));
724 if ( rPar
.Count() < 2 )
726 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
730 OUString
aStr(comphelper::string::strip(rPar
.Get(1)->GetOUString(), ' '));
731 rPar
.Get(0)->PutString(aStr
);
735 RTLFUNC(GetSolarVersion
)
740 rPar
.Get(0)->PutLong( LIBO_VERSION_MAJOR
* 10000 + LIBO_VERSION_MINOR
* 100 + LIBO_VERSION_MICRO
* 1);
743 RTLFUNC(TwipsPerPixelX
)
748 sal_Int32 nResult
= 0;
750 MapMode
aMap( MAP_TWIP
);
751 OutputDevice
* pDevice
= Application::GetDefaultDevice();
754 aSize
= pDevice
->PixelToLogic( aSize
, aMap
);
755 nResult
= aSize
.Width() / 100;
757 rPar
.Get(0)->PutLong( nResult
);
760 RTLFUNC(TwipsPerPixelY
)
765 sal_Int32 nResult
= 0;
767 MapMode
aMap( MAP_TWIP
);
768 OutputDevice
* pDevice
= Application::GetDefaultDevice();
771 aSize
= pDevice
->PixelToLogic( aSize
, aMap
);
772 nResult
= aSize
.Height() / 100;
774 rPar
.Get(0)->PutLong( nResult
);
783 if ( rPar
.Count() != 2 )
785 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
787 GetSbData()->pInst
->GetDllMgr()->FreeDll( rPar
.Get(1)->GetOUString() );
789 bool IsBaseIndexOne()
792 if ( GetSbData()->pInst
&& GetSbData()->pInst
->pRun
)
794 sal_uInt16 res
= GetSbData()->pInst
->pRun
->GetBase();
808 SbxDimArray
* pArray
= new SbxDimArray( SbxVARIANT
);
809 sal_uInt16 nArraySize
= rPar
.Count() - 1;
811 // ignore Option Base so far (unfortunately only known by the compiler)
812 bool bIncIndex
= (IsBaseIndexOne() && SbiRuntime::isVBAEnabled() );
817 pArray
->AddDim( 1, nArraySize
);
821 pArray
->AddDim( 0, nArraySize
-1 );
826 pArray
->unoAddDim( 0, -1 );
829 // insert parameters into the array
830 // ATTENTION: Using type sal_uInt16 for loop variable is
831 // mandatory to workaround a problem with the
832 // Solaris Intel compiler optimizer! See i104354
833 for( sal_uInt16 i
= 0 ; i
< nArraySize
; i
++ )
835 SbxVariable
* pVar
= rPar
.Get(i
+1);
836 SbxVariable
* pNew
= new SbxVariable( *pVar
);
837 pNew
->SetFlag( SBX_WRITE
);
838 short index
= static_cast< short >(i
);
843 // coverity[callee_ptr_arith]
844 pArray
->Put( pNew
, &index
);
848 SbxVariableRef refVar
= rPar
.Get(0);
849 SbxFlagBits nFlags
= refVar
->GetFlags();
850 refVar
->ResetFlag( SBX_FIXED
);
851 refVar
->PutObject( pArray
);
852 refVar
->SetFlags( nFlags
);
853 refVar
->SetParameters( NULL
);
857 // Featurewish #57868
858 // The function returns a variant-array; if there are no parameters passed,
859 // an empty array is created (according to dim a(); equal to a sequence of
860 // the length 0 in Uno).
861 // If there are parameters passed, there's a dimension created for each of
862 // them; DimArray( 2, 2, 4 ) is equal to DIM a( 2, 2, 4 )
863 // the array is always of the type variant
869 SbxDimArray
* pArray
= new SbxDimArray( SbxVARIANT
);
870 sal_uInt16 nArrayDims
= rPar
.Count() - 1;
873 for( sal_uInt16 i
= 0; i
< nArrayDims
; i
++ )
875 sal_Int32 ub
= rPar
.Get(i
+1)->GetLong();
878 StarBASIC::Error( SbERR_OUT_OF_RANGE
);
881 pArray
->AddDim32( 0, ub
);
886 pArray
->unoAddDim( 0, -1 );
888 SbxVariableRef refVar
= rPar
.Get(0);
889 SbxFlagBits nFlags
= refVar
->GetFlags();
890 refVar
->ResetFlag( SBX_FIXED
);
891 refVar
->PutObject( pArray
);
892 refVar
->SetFlags( nFlags
);
893 refVar
->SetParameters( NULL
);
897 * FindObject and FindPropertyObject make it possible to
898 * address objects and properties of the type Object with
899 * their name as string-pararmeters at the runtime.
902 * MyObj.Prop1.Bla = 5
905 * dim ObjVar as Object
906 * dim ObjProp as Object
908 * ObjVar = FindObject( ObjName$ )
909 * PropName$ = "Prop1"
910 * ObjProp = FindPropertyObject( ObjVar, PropName$ )
913 * The names can be created dynamically at the runtime
914 * so that e. g. via controls "TextEdit1" to "TextEdit5"
915 * can be iterated in a dialog in a loop.
919 // 1st parameter = the object's name as string
925 if ( rPar
.Count() < 2 )
927 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
931 OUString aNameStr
= rPar
.Get(1)->GetOUString();
933 SbxBase
* pFind
= StarBASIC::FindSBXInCurrentScope( aNameStr
);
934 SbxObject
* pFindObj
= NULL
;
937 pFindObj
= PTR_CAST(SbxObject
,pFind
);
939 SbxVariableRef refVar
= rPar
.Get(0);
940 refVar
->PutObject( pFindObj
);
943 // address object-property in an object
944 // 1st parameter = object
945 // 2nd parameter = the property's name as string
946 RTLFUNC(FindPropertyObject
)
951 if ( rPar
.Count() < 3 )
953 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
957 SbxBase
* pObjVar
= static_cast<SbxObject
*>(rPar
.Get(1)->GetObject());
958 SbxObject
* pObj
= NULL
;
961 pObj
= PTR_CAST(SbxObject
,pObjVar
);
963 if( !pObj
&& pObjVar
&& pObjVar
->ISA(SbxVariable
) )
965 SbxBase
* pObjVarObj
= static_cast<SbxVariable
*>(pObjVar
)->GetObject();
966 pObj
= PTR_CAST(SbxObject
,pObjVarObj
);
969 OUString aNameStr
= rPar
.Get(2)->GetOUString();
971 SbxObject
* pFindObj
= NULL
;
974 SbxVariable
* pFindVar
= pObj
->Find( aNameStr
, SbxCLASS_OBJECT
);
975 pFindObj
= PTR_CAST(SbxObject
,pFindVar
);
979 StarBASIC::Error( SbERR_BAD_PARAMETER
);
982 SbxVariableRef refVar
= rPar
.Get(0);
983 refVar
->PutObject( pFindObj
);
988 static bool lcl_WriteSbxVariable( const SbxVariable
& rVar
, SvStream
* pStrm
,
989 bool bBinary
, short nBlockLen
, bool bIsArray
)
991 sal_Size nFPos
= pStrm
->Tell();
993 bool bIsVariant
= !rVar
.IsFixed();
994 SbxDataType eType
= rVar
.GetType();
1003 pStrm
->WriteUInt16( SbxBYTE
); // VarType Id
1005 pStrm
->WriteUChar( rVar
.GetByte() );
1017 pStrm
->WriteUInt16( SbxINTEGER
); // VarType Id
1019 pStrm
->WriteInt16( rVar
.GetInteger() );
1026 pStrm
->WriteUInt16( SbxLONG
); // VarType Id
1028 pStrm
->WriteInt32( rVar
.GetLong() );
1034 pStrm
->WriteUInt16( SbxSALINT64
); // VarType Id
1036 pStrm
->WriteUInt64( rVar
.GetInt64() );
1041 pStrm
->WriteUInt16( eType
); // VarType Id
1043 pStrm
->WriteFloat( rVar
.GetSingle() );
1051 pStrm
->WriteUInt16( eType
); // VarType Id
1053 pStrm
->WriteDouble( rVar
.GetDouble() );
1059 const OUString
& rStr
= rVar
.GetOUString();
1060 if( !bBinary
|| bIsArray
)
1064 pStrm
->WriteUInt16( SbxSTRING
);
1066 pStrm
->WriteUniOrByteString( rStr
, osl_getThreadTextEncoding() );
1070 // without any length information! without end-identifier!
1071 // What does that mean for Unicode?! Choosing conversion to ByteString...
1072 OString
aByteStr(OUStringToOString(rStr
, osl_getThreadTextEncoding()));
1073 pStrm
->WriteCharPtr( (const char*)aByteStr
.getStr() );
1079 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1085 pStrm
->Seek( nFPos
+ nBlockLen
);
1087 return pStrm
->GetErrorCode() == 0;
1090 static bool lcl_ReadSbxVariable( SbxVariable
& rVar
, SvStream
* pStrm
,
1091 bool bBinary
, short nBlockLen
, bool bIsArray
)
1098 sal_Size nFPos
= pStrm
->Tell();
1100 bool bIsVariant
= !rVar
.IsFixed();
1101 SbxDataType eVarType
= rVar
.GetType();
1103 SbxDataType eSrcType
= eVarType
;
1107 pStrm
->ReadUInt16( nTemp
);
1108 eSrcType
= (SbxDataType
)nTemp
;
1118 pStrm
->ReadUChar( aByte
);
1120 if( bBinary
&& SbiRuntime::isVBAEnabled() && aByte
== 1 && pStrm
->IsEof() )
1124 rVar
.PutByte( aByte
);
1137 pStrm
->ReadInt16( aInt
);
1138 rVar
.PutInteger( aInt
);
1146 pStrm
->ReadInt32( aInt
);
1147 rVar
.PutLong( aInt
);
1154 pStrm
->ReadUInt32( aInt
);
1155 rVar
.PutInt64( (sal_Int64
)aInt
);
1161 pStrm
->ReadFloat( nS
);
1162 rVar
.PutSingle( nS
);
1169 pStrm
->ReadDouble( aDouble
);
1170 rVar
.PutDouble( aDouble
);
1176 pStrm
->ReadDouble( aDouble
);
1177 rVar
.PutDate( aDouble
);
1184 OUString aStr
= pStrm
->ReadUniOrByteString(osl_getThreadTextEncoding());
1185 rVar
.PutString( aStr
);
1190 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1196 pStrm
->Seek( nFPos
+ nBlockLen
);
1198 return pStrm
->GetErrorCode() == 0;
1203 static bool lcl_WriteReadSbxArray( SbxDimArray
& rArr
, SvStream
* pStrm
,
1204 bool bBinary
, short nCurDim
, short* pOtherDims
, bool bWrite
)
1206 SAL_WARN_IF( nCurDim
<= 0,"basic", "Bad Dim");
1207 short nLower
, nUpper
;
1208 if( !rArr
.GetDim( nCurDim
, nLower
, nUpper
) )
1210 for( short nCur
= nLower
; nCur
<= nUpper
; nCur
++ )
1212 pOtherDims
[ nCurDim
-1 ] = nCur
;
1214 lcl_WriteReadSbxArray(rArr
, pStrm
, bBinary
, nCurDim
-1, pOtherDims
, bWrite
);
1217 SbxVariable
* pVar
= rArr
.Get( (const short*)pOtherDims
);
1220 bRet
= lcl_WriteSbxVariable(*pVar
, pStrm
, bBinary
, 0, true );
1222 bRet
= lcl_ReadSbxVariable(*pVar
, pStrm
, bBinary
, 0, true );
1230 void PutGet( SbxArray
& rPar
, bool bPut
)
1232 if ( rPar
.Count() != 4 )
1234 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1237 sal_Int16 nFileNo
= rPar
.Get(1)->GetInteger();
1238 SbxVariable
* pVar2
= rPar
.Get(2);
1239 SbxDataType eType2
= pVar2
->GetType();
1240 bool bHasRecordNo
= (eType2
!= SbxEMPTY
&& eType2
!= SbxERROR
);
1241 long nRecordNo
= pVar2
->GetLong();
1242 if ( nFileNo
< 1 || ( bHasRecordNo
&& nRecordNo
< 1 ) )
1244 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1248 SbiIoSystem
* pIO
= GetSbData()->pInst
->GetIoSystem();
1249 SbiStream
* pSbStrm
= pIO
->GetStream( nFileNo
);
1251 if ( !pSbStrm
|| !(pSbStrm
->GetMode() & (SBSTRM_BINARY
| SBSTRM_RANDOM
)) )
1253 StarBASIC::Error( SbERR_BAD_CHANNEL
);
1257 SvStream
* pStrm
= pSbStrm
->GetStrm();
1258 bool bRandom
= pSbStrm
->IsRandom();
1259 short nBlockLen
= bRandom
? pSbStrm
->GetBlockLen() : 0;
1263 pSbStrm
->ExpandFile();
1268 sal_Size nFilePos
= bRandom
? (sal_Size
)(nBlockLen
* nRecordNo
) : (sal_Size
)nRecordNo
;
1269 pStrm
->Seek( nFilePos
);
1272 SbxDimArray
* pArr
= 0;
1273 SbxVariable
* pVar
= rPar
.Get(3);
1274 if( pVar
->GetType() & SbxARRAY
)
1276 SbxBase
* pParObj
= pVar
->GetObject();
1277 pArr
= PTR_CAST(SbxDimArray
,pParObj
);
1284 sal_Size nFPos
= pStrm
->Tell();
1285 short nDims
= pArr
->GetDims();
1286 boost::scoped_array
<short> pDims(new short[ nDims
]);
1287 bRet
= lcl_WriteReadSbxArray(*pArr
,pStrm
,!bRandom
,nDims
,pDims
.get(),bPut
);
1290 pStrm
->Seek( nFPos
+ nBlockLen
);
1295 bRet
= lcl_WriteSbxVariable(*pVar
, pStrm
, !bRandom
, nBlockLen
, false);
1297 bRet
= lcl_ReadSbxVariable(*pVar
, pStrm
, !bRandom
, nBlockLen
, false);
1299 if( !bRet
|| pStrm
->GetErrorCode() )
1300 StarBASIC::Error( SbERR_IO_ERROR
);
1308 PutGet( rPar
, true );
1316 PutGet( rPar
, false );
1324 if ( rPar
.Count() != 2 )
1326 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1330 // should be ANSI but that's not possible under Win16 in the DLL
1331 OString
aByteStr(OUStringToOString(rPar
.Get(1)->GetOUString(),
1332 osl_getThreadTextEncoding()));
1333 const char* pEnvStr
= getenv(aByteStr
.getStr());
1336 aResult
= OUString(pEnvStr
, strlen(pEnvStr
), osl_getThreadTextEncoding());
1338 rPar
.Get(0)->PutString( aResult
);
1341 static double GetDialogZoomFactor( bool bX
, long nValue
)
1343 OutputDevice
* pDevice
= Application::GetDefaultDevice();
1347 Size
aRefSize( nValue
, nValue
);
1348 Fraction
aFracX( 1, 26 );
1349 Fraction
aFracY( 1, 24 );
1350 MapMode
aMap( MAP_APPFONT
, Point(), aFracX
, aFracY
);
1351 Size aScaledSize
= pDevice
->LogicToPixel( aRefSize
, aMap
);
1352 aRefSize
= pDevice
->LogicToPixel( aRefSize
, MapMode(MAP_TWIP
) );
1354 double nRef
, nScaled
;
1357 nRef
= aRefSize
.Width();
1358 nScaled
= aScaledSize
.Width();
1362 nRef
= aRefSize
.Height();
1363 nScaled
= aScaledSize
.Height();
1365 nResult
= nScaled
/ nRef
;
1371 RTLFUNC(GetDialogZoomFactorX
)
1376 if ( rPar
.Count() != 2 )
1378 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1381 rPar
.Get(0)->PutDouble( GetDialogZoomFactor( true, rPar
.Get(1)->GetLong() ));
1384 RTLFUNC(GetDialogZoomFactorY
)
1389 if ( rPar
.Count() != 2 )
1391 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1394 rPar
.Get(0)->PutDouble( GetDialogZoomFactor( false, rPar
.Get(1)->GetLong()));
1398 RTLFUNC(EnableReschedule
)
1403 rPar
.Get(0)->PutEmpty();
1404 if ( rPar
.Count() != 2 )
1405 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1406 if( GetSbData()->pInst
)
1407 GetSbData()->pInst
->EnableReschedule( rPar
.Get(1)->GetBool() );
1410 RTLFUNC(GetSystemTicks
)
1415 if ( rPar
.Count() != 1 )
1417 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1420 rPar
.Get(0)->PutLong( tools::Time::GetSystemTicks() );
1423 RTLFUNC(GetPathSeparator
)
1428 if ( rPar
.Count() != 1 )
1430 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1433 rPar
.Get(0)->PutString( OUString( SAL_PATHDELIMITER
) );
1436 RTLFUNC(ResolvePath
)
1441 if ( rPar
.Count() == 2 )
1443 OUString aStr
= rPar
.Get(1)->GetOUString();
1444 rPar
.Get(0)->PutString( aStr
);
1448 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1457 if ( rPar
.Count() != 2 )
1459 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1463 SbxDataType eType
= rPar
.Get(1)->GetType();
1519 nLen
= (sal_Int16
)rPar
.Get(1)->GetOUString().getLength();
1526 rPar
.Get(0)->PutInteger( nLen
);
1531 // 1st parameter == class name, other parameters for initialisation
1532 RTLFUNC(CreateUnoStruct
)
1537 RTL_Impl_CreateUnoStruct( pBasic
, rPar
, bWrite
);
1541 // 1st parameter == service-name
1542 RTLFUNC(CreateUnoService
)
1547 RTL_Impl_CreateUnoService( pBasic
, rPar
, bWrite
);
1550 RTLFUNC(CreateUnoServiceWithArguments
)
1555 RTL_Impl_CreateUnoServiceWithArguments( pBasic
, rPar
, bWrite
);
1559 RTLFUNC(CreateUnoValue
)
1564 RTL_Impl_CreateUnoValue( pBasic
, rPar
, bWrite
);
1569 RTLFUNC(GetProcessServiceManager
)
1574 RTL_Impl_GetProcessServiceManager( pBasic
, rPar
, bWrite
);
1578 // 1st parameter == Sequence<PropertyValue>
1579 RTLFUNC(CreatePropertySet
)
1584 RTL_Impl_CreatePropertySet( pBasic
, rPar
, bWrite
);
1588 // multiple interface-names as parameters
1589 RTLFUNC(HasUnoInterfaces
)
1594 RTL_Impl_HasInterfaces( pBasic
, rPar
, bWrite
);
1598 RTLFUNC(IsUnoStruct
)
1603 RTL_Impl_IsUnoStruct( pBasic
, rPar
, bWrite
);
1607 RTLFUNC(EqualUnoObjects
)
1612 RTL_Impl_EqualUnoObjects( pBasic
, rPar
, bWrite
);
1615 RTLFUNC(CreateUnoDialog
)
1620 RTL_Impl_CreateUnoDialog( pBasic
, rPar
, bWrite
);
1623 // Return the application standard lib as root scope
1624 RTLFUNC(GlobalScope
)
1629 SbxObject
* p
= pBasic
;
1630 while( p
->GetParent() )
1634 SbxVariableRef refVar
= rPar
.Get(0);
1635 refVar
->PutObject( p
);
1638 // Helper functions to convert Url from/to system paths
1639 RTLFUNC(ConvertToUrl
)
1644 if ( rPar
.Count() == 2 )
1646 OUString aStr
= rPar
.Get(1)->GetOUString();
1647 INetURLObject
aURLObj( aStr
, INetProtocol::File
);
1648 OUString aFileURL
= aURLObj
.GetMainURL( INetURLObject::NO_DECODE
);
1649 if( aFileURL
.isEmpty() )
1651 ::osl::File::getFileURLFromSystemPath( aFileURL
, aFileURL
);
1653 if( aFileURL
.isEmpty() )
1657 rPar
.Get(0)->PutString(aFileURL
);
1661 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1665 RTLFUNC(ConvertFromUrl
)
1670 if ( rPar
.Count() == 2 )
1672 OUString aStr
= rPar
.Get(1)->GetOUString();
1674 ::osl::File::getSystemPathFromFileURL( aStr
, aSysPath
);
1675 if( aSysPath
.isEmpty() )
1679 rPar
.Get(0)->PutString(aSysPath
);
1683 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1688 // Provide DefaultContext
1689 RTLFUNC(GetDefaultContext
)
1694 RTL_Impl_GetDefaultContext( pBasic
, rPar
, bWrite
);
1697 #ifdef DBG_TRACE_BASIC
1698 RTLFUNC(TraceCommand
)
1700 RTL_Impl_TraceCommand( pBasic
, rPar
, bWrite
);
1709 sal_uInt16 nParCount
= rPar
.Count();
1710 if ( nParCount
!= 3 && nParCount
!= 2 )
1712 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1715 SbxBase
* pParObj
= rPar
.Get(1)->GetObject();
1716 SbxDimArray
* pArr
= PTR_CAST(SbxDimArray
,pParObj
);
1719 if( pArr
->GetDims() != 1 )
1721 StarBASIC::Error( SbERR_WRONG_DIMS
); // Syntax Error?!
1725 if( nParCount
== 3 )
1727 aDelim
= rPar
.Get(2)->GetOUString();
1734 short nLower
, nUpper
;
1735 pArr
->GetDim( 1, nLower
, nUpper
);
1736 for (short i
= nLower
; i
<= nUpper
; ++i
)
1738 // coverity[callee_ptr_arith]
1739 OUString aStr
= pArr
->Get( &i
)->GetOUString();
1746 rPar
.Get(0)->PutString( aRetStr
);
1750 StarBASIC::Error( SbERR_MUST_HAVE_DIMS
);
1760 sal_uInt16 nParCount
= rPar
.Count();
1761 if ( nParCount
< 2 )
1763 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1767 OUString aExpression
= rPar
.Get(1)->GetOUString();
1768 short nArraySize
= 0;
1770 if( !aExpression
.isEmpty() )
1773 if( nParCount
>= 3 )
1775 aDelim
= rPar
.Get(2)->GetOUString();
1782 sal_Int32 nCount
= -1;
1783 if( nParCount
== 4 )
1785 nCount
= rPar
.Get(3)->GetLong();
1787 sal_Int32 nDelimLen
= aDelim
.getLength();
1790 sal_Int32 iSearch
= -1;
1791 sal_Int32 iStart
= 0;
1794 bool bBreak
= false;
1795 if( nCount
>= 0 && nArraySize
== nCount
- 1 )
1799 iSearch
= aExpression
.indexOf( aDelim
, iStart
);
1801 if( iSearch
>= 0 && !bBreak
)
1803 aSubStr
= aExpression
.copy( iStart
, iSearch
- iStart
);
1804 iStart
= iSearch
+ nDelimLen
;
1808 aSubStr
= aExpression
.copy( iStart
);
1810 vRet
.push_back( aSubStr
);
1818 while( iSearch
>= 0 );
1822 vRet
.push_back( aExpression
);
1827 SbxDimArray
* pArray
= new SbxDimArray( SbxVARIANT
);
1828 pArray
->unoAddDim( 0, nArraySize
-1 );
1830 // insert parameter(s) into the array
1831 for( short i
= 0 ; i
< nArraySize
; i
++ )
1833 SbxVariableRef xVar
= new SbxVariable( SbxVARIANT
);
1834 xVar
->PutString( vRet
[i
] );
1835 pArray
->Put( xVar
.get(), &i
);
1839 SbxVariableRef refVar
= rPar
.Get(0);
1840 SbxFlagBits nFlags
= refVar
->GetFlags();
1841 refVar
->ResetFlag( SBX_FIXED
);
1842 refVar
->PutObject( pArray
);
1843 refVar
->SetFlags( nFlags
);
1844 refVar
->SetParameters( NULL
);
1847 // MonthName(month[, abbreviate])
1853 sal_uInt16 nParCount
= rPar
.Count();
1854 if( nParCount
!= 2 && nParCount
!= 3 )
1856 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1860 Reference
< XCalendar4
> xCalendar
= getLocaleCalendar();
1861 if( !xCalendar
.is() )
1863 StarBASIC::Error( SbERR_INTERNAL_ERROR
);
1866 Sequence
< CalendarItem2
> aMonthSeq
= xCalendar
->getMonths2();
1867 sal_Int32 nMonthCount
= aMonthSeq
.getLength();
1869 sal_Int16 nVal
= rPar
.Get(1)->GetInteger();
1870 if( nVal
< 1 || nVal
> nMonthCount
)
1872 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1876 bool bAbbreviate
= false;
1877 if( nParCount
== 3 )
1878 bAbbreviate
= rPar
.Get(2)->GetBool();
1880 const CalendarItem2
* pCalendarItems
= aMonthSeq
.getConstArray();
1881 const CalendarItem2
& rItem
= pCalendarItems
[nVal
- 1];
1883 OUString aRetStr
= ( bAbbreviate
? rItem
.AbbrevName
: rItem
.FullName
);
1884 rPar
.Get(0)->PutString(aRetStr
);
1887 // WeekdayName(weekday, abbreviate, firstdayofweek)
1888 RTLFUNC(WeekdayName
)
1893 sal_uInt16 nParCount
= rPar
.Count();
1894 if( nParCount
< 2 || nParCount
> 4 )
1896 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1900 Reference
< XCalendar4
> xCalendar
= getLocaleCalendar();
1901 if( !xCalendar
.is() )
1903 StarBASIC::Error( SbERR_INTERNAL_ERROR
);
1907 Sequence
< CalendarItem2
> aDaySeq
= xCalendar
->getDays2();
1908 sal_Int16 nDayCount
= (sal_Int16
)aDaySeq
.getLength();
1909 sal_Int16 nDay
= rPar
.Get(1)->GetInteger();
1910 sal_Int16 nFirstDay
= 0;
1911 if( nParCount
== 4 )
1913 nFirstDay
= rPar
.Get(3)->GetInteger();
1914 if( nFirstDay
< 0 || nFirstDay
> 7 )
1916 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1920 if( nFirstDay
== 0 )
1922 nFirstDay
= sal_Int16( xCalendar
->getFirstDayOfWeek() + 1 );
1924 nDay
= 1 + (nDay
+ nDayCount
+ nFirstDay
- 2) % nDayCount
;
1925 if( nDay
< 1 || nDay
> nDayCount
)
1927 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1931 bool bAbbreviate
= false;
1932 if( nParCount
>= 3 )
1934 SbxVariable
* pPar2
= rPar
.Get(2);
1935 if( !pPar2
->IsErr() )
1937 bAbbreviate
= pPar2
->GetBool();
1941 const CalendarItem2
* pCalendarItems
= aDaySeq
.getConstArray();
1942 const CalendarItem2
& rItem
= pCalendarItems
[nDay
- 1];
1944 OUString aRetStr
= ( bAbbreviate
? rItem
.AbbrevName
: rItem
.FullName
);
1945 rPar
.Get(0)->PutString( aRetStr
);
1953 sal_uInt16 nParCount
= rPar
.Count();
1954 if ( nParCount
< 2 )
1956 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
1960 double aDate
= rPar
.Get(1)->GetDate();
1962 bool bFirstDay
= false;
1963 sal_Int16 nFirstDay
= 0;
1964 if ( nParCount
> 2 )
1966 nFirstDay
= rPar
.Get(2)->GetInteger();
1969 sal_Int16 nDay
= implGetWeekDay( aDate
, bFirstDay
, nFirstDay
);
1970 rPar
.Get(0)->PutInteger( nDay
);
1991 Interval meInterval
;
1992 char const * mStringCode
;
1997 IntervalInfo
const * getIntervalInfo( const OUString
& rStringCode
)
1999 static IntervalInfo
const aIntervalTable
[] =
2001 { INTERVAL_YYYY
, "yyyy", 0.0, false }, // Year
2002 { INTERVAL_Q
, "q", 0.0, false }, // Quarter
2003 { INTERVAL_M
, "m", 0.0, false }, // Month
2004 { INTERVAL_Y
, "y", 1.0, true }, // Day of year
2005 { INTERVAL_D
, "d", 1.0, true }, // Day
2006 { INTERVAL_W
, "w", 1.0, true }, // Weekday
2007 { INTERVAL_WW
, "ww", 7.0, true }, // Week
2008 { INTERVAL_H
, "h", 1.0 / 24.0, true }, // Hour
2009 { INTERVAL_N
, "n", 1.0 / 1440.0, true }, // Minute
2010 { INTERVAL_S
, "s", 1.0 / 86400.0, true } // Second
2012 for( std::size_t i
= 0; i
!= SAL_N_ELEMENTS(aIntervalTable
); ++i
)
2014 if( rStringCode
.equalsIgnoreAsciiCaseAscii(
2015 aIntervalTable
[i
].mStringCode
) )
2017 return &aIntervalTable
[i
];
2023 inline void implGetDayMonthYear( sal_Int16
& rnYear
, sal_Int16
& rnMonth
, sal_Int16
& rnDay
, double dDate
)
2025 rnDay
= implGetDateDay( dDate
);
2026 rnMonth
= implGetDateMonth( dDate
);
2027 rnYear
= implGetDateYear( dDate
);
2030 inline sal_Int16
limitToINT16( sal_Int32 n32
)
2036 else if( n32
< -32768 )
2040 return (sal_Int16
)n32
;
2048 sal_uInt16 nParCount
= rPar
.Count();
2049 if( nParCount
!= 4 )
2051 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2055 OUString aStringCode
= rPar
.Get(1)->GetOUString();
2056 IntervalInfo
const * pInfo
= getIntervalInfo( aStringCode
);
2059 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2063 sal_Int32 lNumber
= rPar
.Get(2)->GetLong();
2064 double dDate
= rPar
.Get(3)->GetDate();
2065 double dNewDate
= 0;
2066 if( pInfo
->mbSimple
)
2068 double dAdd
= pInfo
->mdValue
* lNumber
;
2069 dNewDate
= dDate
+ dAdd
;
2073 // Keep hours, minutes, seconds
2074 double dHoursMinutesSeconds
= dDate
- floor( dDate
);
2077 sal_Int16 nYear
, nMonth
, nDay
;
2078 sal_Int16 nTargetYear16
= 0, nTargetMonth
= 0;
2079 implGetDayMonthYear( nYear
, nMonth
, nDay
, dDate
);
2080 switch( pInfo
->meInterval
)
2084 sal_Int32 nTargetYear
= lNumber
+ nYear
;
2085 nTargetYear16
= limitToINT16( nTargetYear
);
2086 nTargetMonth
= nMonth
;
2087 bOk
= implDateSerial( nTargetYear16
, nTargetMonth
, nDay
, dNewDate
);
2093 bool bNeg
= (lNumber
< 0);
2096 sal_Int32 nYearsAdd
;
2097 sal_Int16 nMonthAdd
;
2098 if( pInfo
->meInterval
== INTERVAL_Q
)
2100 nYearsAdd
= lNumber
/ 4;
2101 nMonthAdd
= (sal_Int16
)( 3 * (lNumber
% 4) );
2105 nYearsAdd
= lNumber
/ 12;
2106 nMonthAdd
= (sal_Int16
)( lNumber
% 12 );
2109 sal_Int32 nTargetYear
;
2112 nTargetMonth
= nMonth
- nMonthAdd
;
2113 if( nTargetMonth
<= 0 )
2118 nTargetYear
= (sal_Int32
)nYear
- nYearsAdd
;
2122 nTargetMonth
= nMonth
+ nMonthAdd
;
2123 if( nTargetMonth
> 12 )
2128 nTargetYear
= (sal_Int32
)nYear
+ nYearsAdd
;
2130 nTargetYear16
= limitToINT16( nTargetYear
);
2131 bOk
= implDateSerial( nTargetYear16
, nTargetMonth
, nDay
, dNewDate
);
2140 sal_Int16 nNewYear
, nNewMonth
, nNewDay
;
2141 implGetDayMonthYear( nNewYear
, nNewMonth
, nNewDay
, dNewDate
);
2142 if( nNewYear
> 9999 || nNewYear
< 100 )
2144 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2147 sal_Int16 nCorrectionDay
= nDay
;
2148 while( nNewMonth
> nTargetMonth
)
2151 implDateSerial( nTargetYear16
, nTargetMonth
, nCorrectionDay
, dNewDate
);
2152 implGetDayMonthYear( nNewYear
, nNewMonth
, nNewDay
, dNewDate
);
2154 dNewDate
+= dHoursMinutesSeconds
;
2158 rPar
.Get(0)->PutDate( dNewDate
);
2161 inline double RoundImpl( double d
)
2163 return ( d
>= 0 ) ? floor( d
+ 0.5 ) : -floor( -d
+ 0.5 );
2171 // DateDiff(interval, date1, date2[, firstdayofweek[, firstweekofyear]])
2173 sal_uInt16 nParCount
= rPar
.Count();
2174 if( nParCount
< 4 || nParCount
> 6 )
2176 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2180 OUString aStringCode
= rPar
.Get(1)->GetOUString();
2181 IntervalInfo
const * pInfo
= getIntervalInfo( aStringCode
);
2184 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2188 double dDate1
= rPar
.Get(2)->GetDate();
2189 double dDate2
= rPar
.Get(3)->GetDate();
2192 switch( pInfo
->meInterval
)
2196 sal_Int16 nYear1
= implGetDateYear( dDate1
);
2197 sal_Int16 nYear2
= implGetDateYear( dDate2
);
2198 dRet
= nYear2
- nYear1
;
2203 sal_Int16 nYear1
= implGetDateYear( dDate1
);
2204 sal_Int16 nYear2
= implGetDateYear( dDate2
);
2205 sal_Int16 nQ1
= 1 + (implGetDateMonth( dDate1
) - 1) / 3;
2206 sal_Int16 nQ2
= 1 + (implGetDateMonth( dDate2
) - 1) / 3;
2207 sal_Int16 nQGes1
= 4 * nYear1
+ nQ1
;
2208 sal_Int16 nQGes2
= 4 * nYear2
+ nQ2
;
2209 dRet
= nQGes2
- nQGes1
;
2214 sal_Int16 nYear1
= implGetDateYear( dDate1
);
2215 sal_Int16 nYear2
= implGetDateYear( dDate2
);
2216 sal_Int16 nMonth1
= implGetDateMonth( dDate1
);
2217 sal_Int16 nMonth2
= implGetDateMonth( dDate2
);
2218 sal_Int16 nMonthGes1
= 12 * nYear1
+ nMonth1
;
2219 sal_Int16 nMonthGes2
= 12 * nYear2
+ nMonth2
;
2220 dRet
= nMonthGes2
- nMonthGes1
;
2226 double dDays1
= floor( dDate1
);
2227 double dDays2
= floor( dDate2
);
2228 dRet
= dDays2
- dDays1
;
2234 double dDays1
= floor( dDate1
);
2235 double dDays2
= floor( dDate2
);
2236 if( pInfo
->meInterval
== INTERVAL_WW
)
2238 sal_Int16 nFirstDay
= 1; // Default
2239 if( nParCount
>= 5 )
2241 nFirstDay
= rPar
.Get(4)->GetInteger();
2242 if( nFirstDay
< 0 || nFirstDay
> 7 )
2244 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2247 if( nFirstDay
== 0 )
2249 Reference
< XCalendar4
> xCalendar
= getLocaleCalendar();
2250 if( !xCalendar
.is() )
2252 StarBASIC::Error( SbERR_INTERNAL_ERROR
);
2255 nFirstDay
= sal_Int16( xCalendar
->getFirstDayOfWeek() + 1 );
2258 sal_Int16 nDay1
= implGetWeekDay( dDate1
);
2259 sal_Int16 nDay1_Diff
= nDay1
- nFirstDay
;
2260 if( nDay1_Diff
< 0 )
2262 dDays1
-= nDay1_Diff
;
2264 sal_Int16 nDay2
= implGetWeekDay( dDate2
);
2265 sal_Int16 nDay2_Diff
= nDay2
- nFirstDay
;
2266 if( nDay2_Diff
< 0 )
2268 dDays2
-= nDay2_Diff
;
2271 double dDiff
= dDays2
- dDays1
;
2272 dRet
= ( dDiff
>= 0 ) ? floor( dDiff
/ 7.0 ) : -floor( -dDiff
/ 7.0 );
2277 double dFactor
= 24.0;
2278 dRet
= RoundImpl( dFactor
* (dDate2
- dDate1
) );
2283 double dFactor
=1440.0;
2284 dRet
= RoundImpl( dFactor
* (dDate2
- dDate1
) );
2289 double dFactor
= 86400.0;
2290 dRet
= RoundImpl( dFactor
* (dDate2
- dDate1
) );
2294 rPar
.Get(0)->PutDouble( dRet
);
2297 double implGetDateOfFirstDayInFirstWeek
2298 ( sal_Int16 nYear
, sal_Int16
& nFirstDay
, sal_Int16
& nFirstWeek
, bool* pbError
= NULL
)
2301 if( nFirstDay
< 0 || nFirstDay
> 7 )
2302 nError
= SbERR_BAD_ARGUMENT
;
2304 if( nFirstWeek
< 0 || nFirstWeek
> 3 )
2305 nError
= SbERR_BAD_ARGUMENT
;
2307 Reference
< XCalendar4
> xCalendar
;
2308 if( nFirstDay
== 0 || nFirstWeek
== 0 )
2310 xCalendar
= getLocaleCalendar();
2311 if( !xCalendar
.is() )
2312 nError
= SbERR_BAD_ARGUMENT
;
2317 StarBASIC::Error( nError
);
2323 if( nFirstDay
== 0 )
2324 nFirstDay
= sal_Int16( xCalendar
->getFirstDayOfWeek() + 1 );
2326 sal_Int16 nFirstWeekMinDays
= 0; // Not used for vbFirstJan1 = default
2327 if( nFirstWeek
== 0 )
2329 nFirstWeekMinDays
= xCalendar
->getMinimumNumberOfDaysForFirstWeek();
2330 if( nFirstWeekMinDays
== 1 )
2332 nFirstWeekMinDays
= 0;
2335 else if( nFirstWeekMinDays
== 4 )
2337 else if( nFirstWeekMinDays
== 7 )
2340 else if( nFirstWeek
== 2 )
2341 nFirstWeekMinDays
= 4; // vbFirstFourDays
2342 else if( nFirstWeek
== 3 )
2343 nFirstWeekMinDays
= 7; // vbFirstFourDays
2346 implDateSerial( nYear
, 1, 1, dBaseDate
);
2348 sal_Int16 nWeekDay0101
= implGetWeekDay( dBaseDate
);
2349 sal_Int16 nDayDiff
= nWeekDay0101
- nFirstDay
;
2353 if( nFirstWeekMinDays
)
2355 sal_Int16 nThisWeeksDaysInYearCount
= 7 - nDayDiff
;
2356 if( nThisWeeksDaysInYearCount
< nFirstWeekMinDays
)
2359 double dRetDate
= dBaseDate
- nDayDiff
;
2368 // DatePart(interval, date[,firstdayofweek[, firstweekofyear]])
2370 sal_uInt16 nParCount
= rPar
.Count();
2371 if( nParCount
< 3 || nParCount
> 5 )
2373 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2377 OUString aStringCode
= rPar
.Get(1)->GetOUString();
2378 IntervalInfo
const * pInfo
= getIntervalInfo( aStringCode
);
2381 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2385 double dDate
= rPar
.Get(2)->GetDate();
2388 switch( pInfo
->meInterval
)
2392 nRet
= implGetDateYear( dDate
);
2397 nRet
= 1 + (implGetDateMonth( dDate
) - 1) / 3;
2402 nRet
= implGetDateMonth( dDate
);
2407 sal_Int16 nYear
= implGetDateYear( dDate
);
2409 implDateSerial( nYear
, 1, 1, dBaseDate
);
2410 nRet
= 1 + sal_Int32( dDate
- dBaseDate
);
2415 nRet
= implGetDateDay( dDate
);
2420 bool bFirstDay
= false;
2421 sal_Int16 nFirstDay
= 1; // Default
2422 if( nParCount
>= 4 )
2424 nFirstDay
= rPar
.Get(3)->GetInteger();
2427 nRet
= implGetWeekDay( dDate
, bFirstDay
, nFirstDay
);
2432 sal_Int16 nFirstDay
= 1; // Default
2433 if( nParCount
>= 4 )
2434 nFirstDay
= rPar
.Get(3)->GetInteger();
2436 sal_Int16 nFirstWeek
= 1; // Default
2437 if( nParCount
== 5 )
2438 nFirstWeek
= rPar
.Get(4)->GetInteger();
2440 sal_Int16 nYear
= implGetDateYear( dDate
);
2441 bool bError
= false;
2442 double dYearFirstDay
= implGetDateOfFirstDayInFirstWeek( nYear
, nFirstDay
, nFirstWeek
, &bError
);
2445 if( dYearFirstDay
> dDate
)
2447 // Date belongs to last year's week
2448 dYearFirstDay
= implGetDateOfFirstDayInFirstWeek( nYear
- 1, nFirstDay
, nFirstWeek
);
2450 else if( nFirstWeek
!= 1 )
2452 // Check if date belongs to next year
2453 double dNextYearFirstDay
= implGetDateOfFirstDayInFirstWeek( nYear
+ 1, nFirstDay
, nFirstWeek
);
2454 if( dDate
>= dNextYearFirstDay
)
2455 dYearFirstDay
= dNextYearFirstDay
;
2459 double dDiff
= dDate
- dYearFirstDay
;
2460 nRet
= 1 + sal_Int32( dDiff
/ 7 );
2466 nRet
= implGetHour( dDate
);
2471 nRet
= implGetMinute( dDate
);
2476 nRet
= implGetSecond( dDate
);
2480 rPar
.Get(0)->PutLong( nRet
);
2483 // FormatDateTime(Date[,NamedFormat])
2484 RTLFUNC(FormatDateTime
)
2489 sal_uInt16 nParCount
= rPar
.Count();
2490 if( nParCount
< 2 || nParCount
> 3 )
2492 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2496 double dDate
= rPar
.Get(1)->GetDate();
2497 sal_Int16 nNamedFormat
= 0;
2500 nNamedFormat
= rPar
.Get(2)->GetInteger();
2501 if( nNamedFormat
< 0 || nNamedFormat
> 4 )
2503 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2508 Reference
< XCalendar4
> xCalendar
= getLocaleCalendar();
2509 if( !xCalendar
.is() )
2511 StarBASIC::Error( SbERR_INTERNAL_ERROR
);
2516 SbxVariableRef pSbxVar
= new SbxVariable( SbxSTRING
);
2517 switch( nNamedFormat
)
2520 // Display a date and/or time. If there is a date part,
2521 // display it as a short date. If there is a time part,
2522 // display it as a long time. If present, both parts are displayed.
2524 // 12/21/2004 11:24:50 AM
2525 // 21.12.2004 12:13:51
2527 pSbxVar
->PutDate( dDate
);
2528 aRetStr
= pSbxVar
->GetOUString();
2531 // LongDate: Display a date using the long date format specified
2532 // in your computer's regional settings.
2533 // Tuesday, December 21, 2004
2534 // Dienstag, 21. December 2004
2537 SvNumberFormatter
* pFormatter
= NULL
;
2538 if( GetSbData()->pInst
)
2540 pFormatter
= GetSbData()->pInst
->GetNumberFormatter();
2544 sal_uInt32 n
; // Dummy
2545 SbiInstance::PrepareNumberFormatter( pFormatter
, n
, n
, n
);
2548 LanguageType eLangType
= Application::GetSettings().GetLanguageTag().getLanguageType();
2549 sal_uIntPtr nIndex
= pFormatter
->GetFormatIndex( NF_DATE_SYSTEM_LONG
, eLangType
);
2551 pFormatter
->GetOutputString( dDate
, nIndex
, aRetStr
, &pCol
);
2553 if( !GetSbData()->pInst
)
2560 // ShortDate: Display a date using the short date format specified
2561 // in your computer's regional settings.
2564 pSbxVar
->PutDate( floor(dDate
) );
2565 aRetStr
= pSbxVar
->GetOUString();
2568 // LongTime: Display a time using the time format specified
2569 // in your computer's regional settings.
2573 // ShortTime: Display a time using the 24-hour format (hh:mm).
2577 double dTime
= modf( dDate
, &n
);
2578 pSbxVar
->PutDate( dTime
);
2579 if( nNamedFormat
== 3 )
2581 aRetStr
= pSbxVar
->GetOUString();
2585 aRetStr
= pSbxVar
->GetOUString().copy( 0, 5 );
2590 rPar
.Get(0)->PutString( aRetStr
);
2598 sal_uInt16 nParCount
= rPar
.Count();
2601 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2605 SbxVariable
*pSbxVariable
= rPar
.Get(1);
2606 double dVal
= pSbxVariable
->GetDouble();
2608 rPar
.Get(0)->PutDouble(dVal
- ::rtl::math::approxFloor(dVal
));
2610 rPar
.Get(0)->PutDouble(dVal
- ::rtl::math::approxCeil(dVal
));
2618 sal_uInt16 nParCount
= rPar
.Count();
2619 if( nParCount
!= 2 && nParCount
!= 3 )
2621 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2625 SbxVariable
*pSbxVariable
= rPar
.Get(1);
2626 double dVal
= pSbxVariable
->GetDouble();
2637 sal_Int16 numdecimalplaces
= 0;
2638 if( nParCount
== 3 )
2640 numdecimalplaces
= rPar
.Get(2)->GetInteger();
2641 if( numdecimalplaces
< 0 || numdecimalplaces
> 22 )
2643 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2648 if( numdecimalplaces
== 0 )
2650 dRes
= floor( dVal
+ 0.5 );
2654 double dFactor
= pow( 10.0, numdecimalplaces
);
2656 dRes
= floor( dVal
+ 0.5 );
2663 rPar
.Get(0)->PutDouble( dRes
);
2666 void CallFunctionAccessFunction( const Sequence
< Any
>& aArgs
, const OUString
& sFuncName
, SbxVariable
* pRet
)
2668 static Reference
< XFunctionAccess
> xFunc
;
2673 Reference
< XMultiServiceFactory
> xFactory( getProcessServiceFactory() );
2676 xFunc
.set( xFactory
->createInstance("com.sun.star.sheet.FunctionAccess"), UNO_QUERY_THROW
);
2679 Any aRet
= xFunc
->callFunction( sFuncName
, aArgs
);
2681 unoToSbxValue( pRet
, aRet
);
2684 catch(const Exception
& )
2686 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2695 sal_uLong nArgCount
= rPar
.Count()-1;
2697 if ( nArgCount
< 4 )
2699 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2703 // retrieve non-optional params
2705 Sequence
< Any
> aParams( 4 );
2706 aParams
[ 0 ] <<= makeAny( rPar
.Get(1)->GetDouble() );
2707 aParams
[ 1 ] <<= makeAny( rPar
.Get(2)->GetDouble() );
2708 aParams
[ 2 ] <<= makeAny( rPar
.Get(3)->GetDouble() );
2709 aParams
[ 3 ] <<= makeAny( rPar
.Get(4)->GetDouble() );
2711 CallFunctionAccessFunction( aParams
, "SYD", rPar
.Get( 0 ) );
2719 sal_uLong nArgCount
= rPar
.Count()-1;
2721 if ( nArgCount
< 3 )
2723 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2727 // retrieve non-optional params
2729 Sequence
< Any
> aParams( 3 );
2730 aParams
[ 0 ] <<= makeAny( rPar
.Get(1)->GetDouble() );
2731 aParams
[ 1 ] <<= makeAny( rPar
.Get(2)->GetDouble() );
2732 aParams
[ 2 ] <<= makeAny( rPar
.Get(3)->GetDouble() );
2734 CallFunctionAccessFunction( aParams
, "SLN", rPar
.Get( 0 ) );
2742 sal_uLong nArgCount
= rPar
.Count()-1;
2744 if ( nArgCount
< 3 || nArgCount
> 5 )
2746 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2749 // retrieve non-optional params
2751 double rate
= rPar
.Get(1)->GetDouble();
2752 double nper
= rPar
.Get(2)->GetDouble();
2753 double pmt
= rPar
.Get(3)->GetDouble();
2755 // set default values for Optional args
2760 if ( nArgCount
>= 4 )
2762 if( rPar
.Get(4)->GetType() != SbxEMPTY
)
2763 fv
= rPar
.Get(4)->GetDouble();
2766 if ( nArgCount
>= 5 )
2768 if( rPar
.Get(5)->GetType() != SbxEMPTY
)
2769 type
= rPar
.Get(5)->GetDouble();
2772 Sequence
< Any
> aParams( 5 );
2773 aParams
[ 0 ] <<= rate
;
2774 aParams
[ 1 ] <<= nper
;
2775 aParams
[ 2 ] <<= pmt
;
2776 aParams
[ 3 ] <<= fv
;
2777 aParams
[ 4 ] <<= type
;
2779 CallFunctionAccessFunction( aParams
, "Pmt", rPar
.Get( 0 ) );
2787 sal_uLong nArgCount
= rPar
.Count()-1;
2789 if ( nArgCount
< 4 || nArgCount
> 6 )
2791 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2794 // retrieve non-optional params
2796 double rate
= rPar
.Get(1)->GetDouble();
2797 double per
= rPar
.Get(2)->GetDouble();
2798 double nper
= rPar
.Get(3)->GetDouble();
2799 double pv
= rPar
.Get(4)->GetDouble();
2801 // set default values for Optional args
2806 if ( nArgCount
>= 5 )
2808 if( rPar
.Get(5)->GetType() != SbxEMPTY
)
2809 fv
= rPar
.Get(5)->GetDouble();
2812 if ( nArgCount
>= 6 )
2814 if( rPar
.Get(6)->GetType() != SbxEMPTY
)
2815 type
= rPar
.Get(6)->GetDouble();
2818 Sequence
< Any
> aParams( 6 );
2819 aParams
[ 0 ] <<= rate
;
2820 aParams
[ 1 ] <<= per
;
2821 aParams
[ 2 ] <<= nper
;
2822 aParams
[ 3 ] <<= pv
;
2823 aParams
[ 4 ] <<= fv
;
2824 aParams
[ 5 ] <<= type
;
2826 CallFunctionAccessFunction( aParams
, "PPmt", rPar
.Get( 0 ) );
2834 sal_uLong nArgCount
= rPar
.Count()-1;
2836 if ( nArgCount
< 3 || nArgCount
> 5 )
2838 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2841 // retrieve non-optional params
2843 double rate
= rPar
.Get(1)->GetDouble();
2844 double nper
= rPar
.Get(2)->GetDouble();
2845 double pmt
= rPar
.Get(3)->GetDouble();
2847 // set default values for Optional args
2852 if ( nArgCount
>= 4 )
2854 if( rPar
.Get(4)->GetType() != SbxEMPTY
)
2855 fv
= rPar
.Get(4)->GetDouble();
2858 if ( nArgCount
>= 5 )
2860 if( rPar
.Get(5)->GetType() != SbxEMPTY
)
2861 type
= rPar
.Get(5)->GetDouble();
2864 Sequence
< Any
> aParams( 5 );
2865 aParams
[ 0 ] <<= rate
;
2866 aParams
[ 1 ] <<= nper
;
2867 aParams
[ 2 ] <<= pmt
;
2868 aParams
[ 3 ] <<= fv
;
2869 aParams
[ 4 ] <<= type
;
2871 CallFunctionAccessFunction( aParams
, "PV", rPar
.Get( 0 ) );
2879 sal_uLong nArgCount
= rPar
.Count()-1;
2881 if ( nArgCount
< 1 || nArgCount
> 2 )
2883 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2887 Sequence
< Any
> aParams( 2 );
2888 aParams
[ 0 ] <<= makeAny( rPar
.Get(1)->GetDouble() );
2889 Any aValues
= sbxToUnoValue( rPar
.Get(2),
2890 cppu::UnoType
<Sequence
<double>>::get() );
2892 // convert for calc functions
2893 Sequence
< Sequence
< double > > sValues(1);
2894 aValues
>>= sValues
[ 0 ];
2895 aValues
<<= sValues
;
2897 aParams
[ 1 ] <<= aValues
;
2899 CallFunctionAccessFunction( aParams
, "NPV", rPar
.Get( 0 ) );
2907 sal_uLong nArgCount
= rPar
.Count()-1;
2909 if ( nArgCount
< 3 || nArgCount
> 5 )
2911 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2914 // retrieve non-optional params
2916 double rate
= rPar
.Get(1)->GetDouble();
2917 double pmt
= rPar
.Get(2)->GetDouble();
2918 double pv
= rPar
.Get(3)->GetDouble();
2920 // set default values for Optional args
2925 if ( nArgCount
>= 4 )
2927 if( rPar
.Get(4)->GetType() != SbxEMPTY
)
2928 fv
= rPar
.Get(4)->GetDouble();
2931 if ( nArgCount
>= 5 )
2933 if( rPar
.Get(5)->GetType() != SbxEMPTY
)
2934 type
= rPar
.Get(5)->GetDouble();
2937 Sequence
< Any
> aParams( 5 );
2938 aParams
[ 0 ] <<= rate
;
2939 aParams
[ 1 ] <<= pmt
;
2940 aParams
[ 2 ] <<= pv
;
2941 aParams
[ 3 ] <<= fv
;
2942 aParams
[ 4 ] <<= type
;
2944 CallFunctionAccessFunction( aParams
, "NPer", rPar
.Get( 0 ) );
2952 sal_uLong nArgCount
= rPar
.Count()-1;
2954 if ( nArgCount
< 3 )
2956 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2960 // retrieve non-optional params
2962 Sequence
< Any
> aParams( 3 );
2963 Any aValues
= sbxToUnoValue( rPar
.Get(1),
2964 cppu::UnoType
<Sequence
<double>>::get() );
2966 // convert for calc functions
2967 Sequence
< Sequence
< double > > sValues(1);
2968 aValues
>>= sValues
[ 0 ];
2969 aValues
<<= sValues
;
2971 aParams
[ 0 ] <<= aValues
;
2972 aParams
[ 1 ] <<= makeAny( rPar
.Get(2)->GetDouble() );
2973 aParams
[ 2 ] <<= makeAny( rPar
.Get(3)->GetDouble() );
2975 CallFunctionAccessFunction( aParams
, "MIRR", rPar
.Get( 0 ) );
2983 sal_uLong nArgCount
= rPar
.Count()-1;
2985 if ( nArgCount
< 1 || nArgCount
> 2 )
2987 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
2990 // retrieve non-optional params
2991 Any aValues
= sbxToUnoValue( rPar
.Get(1),
2992 cppu::UnoType
<Sequence
<double>>::get() );
2994 // convert for calc functions
2995 Sequence
< Sequence
< double > > sValues(1);
2996 aValues
>>= sValues
[ 0 ];
2997 aValues
<<= sValues
;
2999 // set default values for Optional args
3002 if ( nArgCount
>= 2 )
3004 if( rPar
.Get(2)->GetType() != SbxEMPTY
)
3005 guess
= rPar
.Get(2)->GetDouble();
3008 Sequence
< Any
> aParams( 2 );
3009 aParams
[ 0 ] <<= aValues
;
3010 aParams
[ 1 ] <<= guess
;
3012 CallFunctionAccessFunction( aParams
, "IRR", rPar
.Get( 0 ) );
3020 sal_uLong nArgCount
= rPar
.Count()-1;
3022 if ( nArgCount
< 4 || nArgCount
> 6 )
3024 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3027 // retrieve non-optional params
3029 double rate
= rPar
.Get(1)->GetDouble();
3030 double per
= rPar
.Get(2)->GetInteger();
3031 double nper
= rPar
.Get(3)->GetDouble();
3032 double pv
= rPar
.Get(4)->GetDouble();
3034 // set default values for Optional args
3039 if ( nArgCount
>= 5 )
3041 if( rPar
.Get(5)->GetType() != SbxEMPTY
)
3042 fv
= rPar
.Get(5)->GetDouble();
3045 if ( nArgCount
>= 6 )
3047 if( rPar
.Get(6)->GetType() != SbxEMPTY
)
3048 type
= rPar
.Get(6)->GetDouble();
3051 Sequence
< Any
> aParams( 6 );
3052 aParams
[ 0 ] <<= rate
;
3053 aParams
[ 1 ] <<= per
;
3054 aParams
[ 2 ] <<= nper
;
3055 aParams
[ 3 ] <<= pv
;
3056 aParams
[ 4 ] <<= fv
;
3057 aParams
[ 5 ] <<= type
;
3059 CallFunctionAccessFunction( aParams
, "IPmt", rPar
.Get( 0 ) );
3067 sal_uLong nArgCount
= rPar
.Count()-1;
3069 if ( nArgCount
< 3 || nArgCount
> 5 )
3071 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3074 // retrieve non-optional params
3076 double rate
= rPar
.Get(1)->GetDouble();
3077 double nper
= rPar
.Get(2)->GetDouble();
3078 double pmt
= rPar
.Get(3)->GetDouble();
3080 // set default values for Optional args
3085 if ( nArgCount
>= 4 )
3087 if( rPar
.Get(4)->GetType() != SbxEMPTY
)
3088 pv
= rPar
.Get(4)->GetDouble();
3091 if ( nArgCount
>= 5 )
3093 if( rPar
.Get(5)->GetType() != SbxEMPTY
)
3094 type
= rPar
.Get(5)->GetDouble();
3097 Sequence
< Any
> aParams( 5 );
3098 aParams
[ 0 ] <<= rate
;
3099 aParams
[ 1 ] <<= nper
;
3100 aParams
[ 2 ] <<= pmt
;
3101 aParams
[ 3 ] <<= pv
;
3102 aParams
[ 4 ] <<= type
;
3104 CallFunctionAccessFunction( aParams
, "FV", rPar
.Get( 0 ) );
3112 sal_uLong nArgCount
= rPar
.Count()-1;
3114 if ( nArgCount
< 4 || nArgCount
> 5 )
3116 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3119 // retrieve non-optional params
3121 double cost
= rPar
.Get(1)->GetDouble();
3122 double salvage
= rPar
.Get(2)->GetDouble();
3123 double life
= rPar
.Get(3)->GetDouble();
3124 double period
= rPar
.Get(4)->GetDouble();
3126 // set default values for Optional args
3130 if ( nArgCount
>= 5 )
3132 if( rPar
.Get(5)->GetType() != SbxEMPTY
)
3133 factor
= rPar
.Get(5)->GetDouble();
3136 Sequence
< Any
> aParams( 5 );
3137 aParams
[ 0 ] <<= cost
;
3138 aParams
[ 1 ] <<= salvage
;
3139 aParams
[ 2 ] <<= life
;
3140 aParams
[ 3 ] <<= period
;
3141 aParams
[ 4 ] <<= factor
;
3143 CallFunctionAccessFunction( aParams
, "DDB", rPar
.Get( 0 ) );
3151 sal_uLong nArgCount
= rPar
.Count()-1;
3153 if ( nArgCount
< 3 || nArgCount
> 6 )
3155 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3158 // retrieve non-optional params
3164 nper
= rPar
.Get(1)->GetDouble();
3165 pmt
= rPar
.Get(2)->GetDouble();
3166 pv
= rPar
.Get(3)->GetDouble();
3168 // set default values for Optional args
3174 if ( nArgCount
>= 4 )
3176 if( rPar
.Get(4)->GetType() != SbxEMPTY
)
3177 fv
= rPar
.Get(4)->GetDouble();
3181 if ( nArgCount
>= 5 )
3183 if( rPar
.Get(5)->GetType() != SbxEMPTY
)
3184 type
= rPar
.Get(5)->GetDouble();
3188 if ( nArgCount
>= 6 )
3190 if( rPar
.Get(6)->GetType() != SbxEMPTY
)
3191 type
= rPar
.Get(6)->GetDouble();
3194 Sequence
< Any
> aParams( 6 );
3195 aParams
[ 0 ] <<= nper
;
3196 aParams
[ 1 ] <<= pmt
;
3197 aParams
[ 2 ] <<= pv
;
3198 aParams
[ 3 ] <<= fv
;
3199 aParams
[ 4 ] <<= type
;
3200 aParams
[ 5 ] <<= guess
;
3202 CallFunctionAccessFunction( aParams
, "Rate", rPar
.Get( 0 ) );
3210 if ( rPar
.Count() != 2 )
3212 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3216 SbxVariable
*pSbxVariable
= rPar
.Get(1);
3217 if( pSbxVariable
->IsNull() )
3219 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3223 OUString aStr
= comphelper::string::reverseString(pSbxVariable
->GetOUString());
3224 rPar
.Get(0)->PutString( aStr
);
3227 RTLFUNC(CompatibilityMode
)
3232 bool bEnabled
= false;
3233 sal_uInt16 nCount
= rPar
.Count();
3234 if ( nCount
!= 1 && nCount
!= 2 )
3235 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3237 SbiInstance
* pInst
= GetSbData()->pInst
;
3242 pInst
->EnableCompatibility( rPar
.Get(1)->GetBool() );
3244 bEnabled
= pInst
->IsCompatibility();
3246 rPar
.Get(0)->PutBool( bEnabled
);
3254 // 2 parameters needed
3255 if ( rPar
.Count() < 3 )
3257 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3261 sal_uInt16 nByteCount
= rPar
.Get(1)->GetUShort();
3262 sal_Int16 nFileNumber
= rPar
.Get(2)->GetInteger();
3264 SbiIoSystem
* pIosys
= GetSbData()->pInst
->GetIoSystem();
3265 SbiStream
* pSbStrm
= pIosys
->GetStream( nFileNumber
);
3266 if ( !pSbStrm
|| !(pSbStrm
->GetMode() & (SBSTRM_BINARY
| SBSTRM_INPUT
)) )
3268 StarBASIC::Error( SbERR_BAD_CHANNEL
);
3272 OString aByteBuffer
;
3273 SbError err
= pSbStrm
->Read( aByteBuffer
, nByteCount
, true );
3275 err
= pIosys
->GetError();
3279 StarBASIC::Error( err
);
3282 rPar
.Get(0)->PutString(OStringToOUString(aByteBuffer
, osl_getThreadTextEncoding()));
3290 SbModule
* pActiveModule
= GetSbData()->pInst
->GetActiveModule();
3291 SbClassModuleObject
* pClassModuleObject
= PTR_CAST(SbClassModuleObject
,pActiveModule
);
3292 SbxVariableRef refVar
= rPar
.Get(0);
3293 if( pClassModuleObject
== NULL
)
3295 SbObjModule
* pMod
= PTR_CAST(SbObjModule
,pActiveModule
);
3297 refVar
->PutObject( pMod
);
3299 StarBASIC::Error( SbERR_INVALID_USAGE_OBJECT
);
3302 refVar
->PutObject( pClassModuleObject
);
3307 sal_Int16
implGetWeekDay( double aDate
, bool bFirstDayParam
, sal_Int16 nFirstDay
)
3309 Date
aRefDate( 1,1,1900 );
3310 long nDays
= (long) aDate
;
3311 nDays
-= 2; // normalize: 1.1.1900 => 0
3313 DayOfWeek aDay
= aRefDate
.GetDayOfWeek();
3315 if ( aDay
!= SUNDAY
)
3316 nDay
= (sal_Int16
)aDay
+ 2;
3318 nDay
= 1; // 1 == Sunday
3320 // #117253 optional 2nd parameter "firstdayofweek"
3321 if( bFirstDayParam
)
3323 if( nFirstDay
< 0 || nFirstDay
> 7 )
3325 #if HAVE_FEATURE_SCRIPTING
3326 StarBASIC::Error( SbERR_BAD_ARGUMENT
);
3330 if( nFirstDay
== 0 )
3332 Reference
< XCalendar4
> xCalendar
= getLocaleCalendar();
3333 if( !xCalendar
.is() )
3335 #if HAVE_FEATURE_SCRIPTING
3336 StarBASIC::Error( SbERR_INTERNAL_ERROR
);
3340 nFirstDay
= sal_Int16( xCalendar
->getFirstDayOfWeek() + 1 );
3342 nDay
= 1 + (nDay
+ 7 - nFirstDay
) % 7;
3347 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */