| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_basic.hxx" |
| |
| #include <stdlib.h> // getenv |
| #include <vcl/svapp.hxx> |
| #include <vcl/mapmod.hxx> |
| #include <vcl/wrkwin.hxx> |
| #include <vcl/timer.hxx> |
| #include <basic/sbxvar.hxx> |
| #ifndef _SBX_HXX |
| #include <basic/sbx.hxx> |
| #endif |
| #include <svl/zforlist.hxx> |
| #include <tools/fsys.hxx> |
| #include <tools/urlobj.hxx> |
| #include <osl/file.hxx> |
| |
| #ifdef OS2 |
| #define INCL_DOS |
| #define INCL_DOSPROCESS |
| #include <svpm.h> |
| #endif |
| |
| #ifndef CLK_TCK |
| #define CLK_TCK CLOCKS_PER_SEC |
| #endif |
| |
| #include <vcl/jobset.hxx> |
| #include <basic/sbobjmod.hxx> |
| |
| #include "sbintern.hxx" |
| #include "runtime.hxx" |
| #include "stdobj.hxx" |
| #include "rtlproto.hxx" |
| #include "dllmgr.hxx" |
| #include <iosys.hxx> |
| #include "sbunoobj.hxx" |
| #include "propacc.hxx" |
| |
| |
| #include <comphelper/processfactory.hxx> |
| |
| #include <com/sun/star/uno/Sequence.hxx> |
| #include <com/sun/star/lang/XMultiServiceFactory.hpp> |
| #include <com/sun/star/i18n/XCalendar.hpp> |
| |
| using namespace comphelper; |
| using namespace com::sun::star::uno; |
| using namespace com::sun::star::i18n; |
| |
| |
| static Reference< XCalendar > getLocaleCalendar( void ) |
| { |
| static Reference< XCalendar > xCalendar; |
| if( !xCalendar.is() ) |
| { |
| Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory(); |
| if( xSMgr.is() ) |
| { |
| xCalendar = Reference< XCalendar >( xSMgr->createInstance |
| ( ::rtl::OUString::createFromAscii( "com.sun.star.i18n.LocaleCalendar" ) ), UNO_QUERY ); |
| } |
| } |
| |
| static com::sun::star::lang::Locale aLastLocale; |
| static bool bNeedsInit = true; |
| |
| com::sun::star::lang::Locale aLocale = Application::GetSettings().GetLocale(); |
| bool bNeedsReload = false; |
| if( bNeedsInit ) |
| { |
| bNeedsInit = false; |
| bNeedsReload = true; |
| } |
| else if( aLocale.Language != aLastLocale.Language || |
| aLocale.Country != aLastLocale.Country ) |
| { |
| bNeedsReload = true; |
| } |
| if( bNeedsReload ) |
| { |
| aLastLocale = aLocale; |
| xCalendar->loadDefaultCalendar( aLocale ); |
| } |
| return xCalendar; |
| } |
| |
| RTLFUNC(CallByName) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| const sal_Int16 vbGet = 2; |
| const sal_Int16 vbLet = 4; |
| const sal_Int16 vbMethod = 1; |
| const sal_Int16 vbSet = 8; |
| |
| // At least 3 parameter needed plus function itself -> 4 |
| sal_uInt16 nParCount = rPar.Count(); |
| if ( nParCount < 4 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| // 1. parameter is object |
| SbxBase* pObjVar = (SbxObject*)rPar.Get(1)->GetObject(); |
| SbxObject* pObj = NULL; |
| if( pObjVar ) |
| pObj = PTR_CAST(SbxObject,pObjVar); |
| if( !pObj && pObjVar && pObjVar->ISA(SbxVariable) ) |
| { |
| SbxBase* pObjVarObj = ((SbxVariable*)pObjVar)->GetObject(); |
| pObj = PTR_CAST(SbxObject,pObjVarObj); |
| } |
| if( !pObj ) |
| { |
| StarBASIC::Error( SbERR_BAD_PARAMETER ); |
| return; |
| } |
| |
| // 2. parameter is ProcedureName |
| String aNameStr = rPar.Get(2)->GetString(); |
| |
| // 3. parameter is CallType |
| sal_Int16 nCallType = rPar.Get(3)->GetInteger(); |
| |
| //SbxObject* pFindObj = NULL; |
| SbxVariable* pFindVar = pObj->Find( aNameStr, SbxCLASS_DONTCARE ); |
| if( pFindVar == NULL ) |
| { |
| StarBASIC::Error( SbERR_PROC_UNDEFINED ); |
| return; |
| } |
| |
| switch( nCallType ) |
| { |
| case vbGet: |
| { |
| SbxValues aVals; |
| aVals.eType = SbxVARIANT; |
| pFindVar->Get( aVals ); |
| |
| SbxVariableRef refVar = rPar.Get(0); |
| refVar->Put( aVals ); |
| } |
| break; |
| case vbLet: |
| case vbSet: |
| { |
| if ( nParCount != 5 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| SbxVariableRef pValVar = rPar.Get(4); |
| if( nCallType == vbLet ) |
| { |
| SbxValues aVals; |
| aVals.eType = SbxVARIANT; |
| pValVar->Get( aVals ); |
| pFindVar->Put( aVals ); |
| } |
| else |
| { |
| SbxVariableRef rFindVar = pFindVar; |
| SbiInstance* pInst = pINST; |
| SbiRuntime* pRT = pInst ? pInst->pRun : NULL; |
| if( pRT != NULL ) |
| pRT->StepSET_Impl( pValVar, rFindVar, false ); |
| } |
| } |
| break; |
| case vbMethod: |
| { |
| SbMethod* pMeth = PTR_CAST(SbMethod,pFindVar); |
| if( pMeth == NULL ) |
| { |
| StarBASIC::Error( SbERR_PROC_UNDEFINED ); |
| return; |
| } |
| |
| // Setup parameters |
| SbxArrayRef xArray; |
| sal_uInt16 nMethParamCount = nParCount - 4; |
| if( nMethParamCount > 0 ) |
| { |
| xArray = new SbxArray; |
| for( sal_uInt16 i = 0 ; i < nMethParamCount ; i++ ) |
| { |
| SbxVariable* pPar = rPar.Get( i + 4 ); |
| xArray->Put( pPar, i + 1 ); |
| } |
| } |
| |
| // Call method |
| SbxVariableRef refVar = rPar.Get(0); |
| if( xArray.Is() ) |
| pMeth->SetParameters( xArray ); |
| pMeth->Call( refVar ); |
| pMeth->SetParameters( NULL ); |
| } |
| break; |
| default: |
| StarBASIC::Error( SbERR_PROC_UNDEFINED ); |
| } |
| } |
| |
| RTLFUNC(CBool) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_Bool bVal = sal_False; |
| if ( rPar.Count() == 2 ) |
| { |
| SbxVariable *pSbxVariable = rPar.Get(1); |
| bVal = pSbxVariable->GetBool(); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| |
| rPar.Get(0)->PutBool(bVal); |
| } |
| |
| RTLFUNC(CByte) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_uInt8 nByte = 0; |
| if ( rPar.Count() == 2 ) |
| { |
| SbxVariable *pSbxVariable = rPar.Get(1); |
| nByte = pSbxVariable->GetByte(); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| |
| rPar.Get(0)->PutByte(nByte); |
| } |
| |
| RTLFUNC(CCur) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| SbxINT64 nCur; |
| if ( rPar.Count() == 2 ) |
| { |
| SbxVariable *pSbxVariable = rPar.Get(1); |
| nCur = pSbxVariable->GetCurrency(); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| |
| rPar.Get(0)->PutCurrency( nCur ); |
| } |
| |
| RTLFUNC(CDec) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| #ifdef WNT |
| SbxDecimal* pDec = NULL; |
| if ( rPar.Count() == 2 ) |
| { |
| SbxVariable *pSbxVariable = rPar.Get(1); |
| pDec = pSbxVariable->GetDecimal(); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| |
| rPar.Get(0)->PutDecimal( pDec ); |
| #else |
| rPar.Get(0)->PutEmpty(); |
| StarBASIC::Error(SbERR_NOT_IMPLEMENTED); |
| #endif |
| } |
| |
| RTLFUNC(CDate) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| double nVal = 0.0; |
| if ( rPar.Count() == 2 ) |
| { |
| SbxVariable *pSbxVariable = rPar.Get(1); |
| nVal = pSbxVariable->GetDate(); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| |
| rPar.Get(0)->PutDate(nVal); |
| } |
| |
| RTLFUNC(CDbl) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| double nVal = 0.0; |
| if ( rPar.Count() == 2 ) |
| { |
| SbxVariable *pSbxVariable = rPar.Get(1); |
| if( pSbxVariable->GetType() == SbxSTRING ) |
| { |
| // AB #41690 , String holen |
| String aScanStr = pSbxVariable->GetString(); |
| SbError Error = SbxValue::ScanNumIntnl( aScanStr, nVal ); |
| if( Error != SbxERR_OK ) |
| StarBASIC::Error( Error ); |
| } |
| else |
| { |
| nVal = pSbxVariable->GetDouble(); |
| } |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| |
| rPar.Get(0)->PutDouble(nVal); |
| } |
| |
| RTLFUNC(CInt) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_Int16 nVal = 0; |
| if ( rPar.Count() == 2 ) |
| { |
| SbxVariable *pSbxVariable = rPar.Get(1); |
| nVal = pSbxVariable->GetInteger(); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| |
| rPar.Get(0)->PutInteger(nVal); |
| } |
| |
| RTLFUNC(CLng) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_Int32 nVal = 0; |
| if ( rPar.Count() == 2 ) |
| { |
| SbxVariable *pSbxVariable = rPar.Get(1); |
| nVal = pSbxVariable->GetLong(); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| |
| rPar.Get(0)->PutLong(nVal); |
| } |
| |
| RTLFUNC(CSng) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| float nVal = (float)0.0; |
| if ( rPar.Count() == 2 ) |
| { |
| SbxVariable *pSbxVariable = rPar.Get(1); |
| if( pSbxVariable->GetType() == SbxSTRING ) |
| { |
| // AB #41690 , String holen |
| double dVal = 0.0; |
| String aScanStr = pSbxVariable->GetString(); |
| SbError Error = SbxValue::ScanNumIntnl( aScanStr, dVal, /*bSingle=*/sal_True ); |
| if( SbxBase::GetError() == SbxERR_OK && Error != SbxERR_OK ) |
| StarBASIC::Error( Error ); |
| nVal = (float)dVal; |
| } |
| else |
| { |
| nVal = pSbxVariable->GetSingle(); |
| } |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| |
| rPar.Get(0)->PutSingle(nVal); |
| } |
| |
| RTLFUNC(CStr) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| String aString; |
| if ( rPar.Count() == 2 ) |
| { |
| SbxVariable *pSbxVariable = rPar.Get(1); |
| aString = pSbxVariable->GetString(); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| |
| rPar.Get(0)->PutString(aString); |
| } |
| |
| RTLFUNC(CVar) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| SbxValues aVals( SbxVARIANT ); |
| if ( rPar.Count() == 2 ) |
| { |
| SbxVariable *pSbxVariable = rPar.Get(1); |
| pSbxVariable->Get( aVals ); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| |
| rPar.Get(0)->Put( aVals ); |
| } |
| |
| RTLFUNC(CVErr) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_Int16 nErrCode = 0; |
| if ( rPar.Count() == 2 ) |
| { |
| SbxVariable *pSbxVariable = rPar.Get(1); |
| nErrCode = pSbxVariable->GetInteger(); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| |
| rPar.Get(0)->PutErr( nErrCode ); |
| } |
| |
| RTLFUNC(Iif) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() == 4 ) |
| { |
| if (rPar.Get(1)->GetBool()) |
| *rPar.Get(0) = *rPar.Get(2); |
| else |
| *rPar.Get(0) = *rPar.Get(3); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| |
| RTLFUNC(GetSystemType) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 1 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| // Removed for SRC595 |
| rPar.Get(0)->PutInteger( -1 ); |
| } |
| |
| RTLFUNC(GetGUIType) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 1 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| // 17.7.2000 Make simple solution for testtool / fat office |
| #if defined (WNT) |
| rPar.Get(0)->PutInteger( 1 ); |
| #elif defined OS2 |
| rPar.Get(0)->PutInteger( 2 ); |
| #elif defined UNX |
| rPar.Get(0)->PutInteger( 4 ); |
| #else |
| rPar.Get(0)->PutInteger( -1 ); |
| #endif |
| } |
| } |
| |
| RTLFUNC(Red) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| sal_uIntPtr nRGB = (sal_uIntPtr)rPar.Get(1)->GetLong(); |
| nRGB &= 0x00FF0000; |
| nRGB >>= 16; |
| rPar.Get(0)->PutInteger( (sal_Int16)nRGB ); |
| } |
| } |
| |
| RTLFUNC(Green) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| sal_uIntPtr nRGB = (sal_uIntPtr)rPar.Get(1)->GetLong(); |
| nRGB &= 0x0000FF00; |
| nRGB >>= 8; |
| rPar.Get(0)->PutInteger( (sal_Int16)nRGB ); |
| } |
| } |
| |
| RTLFUNC(Blue) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| sal_uIntPtr nRGB = (sal_uIntPtr)rPar.Get(1)->GetLong(); |
| nRGB &= 0x000000FF; |
| rPar.Get(0)->PutInteger( (sal_Int16)nRGB ); |
| } |
| } |
| |
| |
| RTLFUNC(Switch) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_uInt16 nCount = rPar.Count(); |
| if( !(nCount & 0x0001 )) |
| // Anzahl der Argumente muss ungerade sein |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| sal_uInt16 nCurExpr = 1; |
| while( nCurExpr < (nCount-1) ) |
| { |
| if( rPar.Get( nCurExpr )->GetBool()) |
| { |
| (*rPar.Get(0)) = *(rPar.Get(nCurExpr+1)); |
| return; |
| } |
| nCurExpr += 2; |
| } |
| rPar.Get(0)->PutNull(); |
| } |
| |
| //i#64882# Common wait impl for existing Wait and new WaitUntil |
| // rtl functions |
| void Wait_Impl( bool bDurationBased, SbxArray& rPar ) |
| { |
| if( rPar.Count() != 2 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| long nWait = 0; |
| if ( bDurationBased ) |
| { |
| double dWait = rPar.Get(1)->GetDouble(); |
| double dNow = Now_Impl(); |
| double dSecs = (double)( ( dWait - dNow ) * (double)( 24.0*3600.0) ); |
| nWait = (long)( dSecs * 1000 ); // wait in thousands of sec |
| } |
| else |
| nWait = rPar.Get(1)->GetLong(); |
| if( nWait < 0 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| Timer aTimer; |
| aTimer.SetTimeout( nWait ); |
| aTimer.Start(); |
| while ( aTimer.IsActive() ) |
| Application::Yield(); |
| } |
| |
| //i#64882# |
| RTLFUNC(Wait) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| Wait_Impl( false, rPar ); |
| } |
| |
| //i#64882# add new WaitUntil ( for application.wait ) |
| // share wait_impl with 'normal' oobasic wait |
| RTLFUNC(WaitUntil) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| Wait_Impl( true, rPar ); |
| } |
| |
| RTLFUNC(DoEvents) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| (void)rPar; |
| // Dummy implementation as the following code leads |
| // to performance problems for unknown reasons |
| //Timer aTimer; |
| //aTimer.SetTimeout( 1 ); |
| //aTimer.Start(); |
| //while ( aTimer.IsActive() ) |
| // Application::Reschedule(); |
| Application::Reschedule( true ); |
| } |
| |
| RTLFUNC(GetGUIVersion) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 1 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| // Removed for SRC595 |
| rPar.Get(0)->PutLong( -1 ); |
| } |
| } |
| |
| RTLFUNC(Choose) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| sal_Int16 nIndex = rPar.Get(1)->GetInteger(); |
| sal_uInt16 nCount = rPar.Count(); |
| nCount--; |
| if( nCount == 1 || nIndex > (nCount-1) || nIndex < 1 ) |
| { |
| rPar.Get(0)->PutNull(); |
| return; |
| } |
| (*rPar.Get(0)) = *(rPar.Get(nIndex+1)); |
| } |
| |
| |
| RTLFUNC(Trim) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| String aStr( rPar.Get(1)->GetString() ); |
| aStr.EraseLeadingChars(); |
| aStr.EraseTrailingChars(); |
| rPar.Get(0)->PutString( aStr ); |
| } |
| } |
| |
| RTLFUNC(GetSolarVersion) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| rPar.Get(0)->PutLong( (sal_Int32)SUPD ); |
| } |
| |
| RTLFUNC(TwipsPerPixelX) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_Int32 nResult = 0; |
| Size aSize( 100,0 ); |
| MapMode aMap( MAP_TWIP ); |
| OutputDevice* pDevice = Application::GetDefaultDevice(); |
| if( pDevice ) |
| { |
| aSize = pDevice->PixelToLogic( aSize, aMap ); |
| nResult = aSize.Width() / 100; |
| } |
| rPar.Get(0)->PutLong( nResult ); |
| } |
| |
| RTLFUNC(TwipsPerPixelY) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_Int32 nResult = 0; |
| Size aSize( 0,100 ); |
| MapMode aMap( MAP_TWIP ); |
| OutputDevice* pDevice = Application::GetDefaultDevice(); |
| if( pDevice ) |
| { |
| aSize = pDevice->PixelToLogic( aSize, aMap ); |
| nResult = aSize.Height() / 100; |
| } |
| rPar.Get(0)->PutLong( nResult ); |
| } |
| |
| |
| RTLFUNC(FreeLibrary) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| pINST->GetDllMgr()->FreeDll( rPar.Get(1)->GetString() ); |
| } |
| bool IsBaseIndexOne() |
| { |
| bool result = false; |
| if ( pINST && pINST->pRun ) |
| { |
| sal_uInt16 res = pINST->pRun->GetBase(); |
| if ( res ) |
| result = true; |
| } |
| return result; |
| } |
| |
| RTLFUNC(Array) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| SbxDimArray* pArray = new SbxDimArray( SbxVARIANT ); |
| sal_uInt16 nArraySize = rPar.Count() - 1; |
| |
| // Option Base zunaechst ignorieren (kennt leider nur der Compiler) |
| bool bIncIndex = (IsBaseIndexOne() && SbiRuntime::isVBAEnabled() ); |
| if( nArraySize ) |
| { |
| if ( bIncIndex ) |
| pArray->AddDim( 1, nArraySize ); |
| else |
| pArray->AddDim( 0, nArraySize-1 ); |
| } |
| else |
| { |
| pArray->unoAddDim( 0, -1 ); |
| } |
| |
| // Parameter ins Array uebernehmen |
| // ATTENTION: Using type sal_uInt16 for loop variable is |
| // mandatory to workaround a problem with the |
| // Solaris Intel compiler optimizer! See i104354 |
| for( sal_uInt16 i = 0 ; i < nArraySize ; i++ ) |
| { |
| SbxVariable* pVar = rPar.Get(i+1); |
| SbxVariable* pNew = new SbxVariable( *pVar ); |
| pNew->SetFlag( SBX_WRITE ); |
| short index = static_cast< short >(i); |
| if ( bIncIndex ) |
| ++index; |
| pArray->Put( pNew, &index ); |
| } |
| |
| // Array zurueckliefern |
| SbxVariableRef refVar = rPar.Get(0); |
| sal_uInt16 nFlags = refVar->GetFlags(); |
| refVar->ResetFlag( SBX_FIXED ); |
| refVar->PutObject( pArray ); |
| refVar->SetFlags( nFlags ); |
| refVar->SetParameters( NULL ); |
| } |
| |
| |
| // Featurewunsch #57868 |
| // Die Funktion liefert ein Variant-Array, wenn keine Parameter angegeben |
| // werden, wird ein leeres Array erzeugt (entsprechend dim a(), entspricht |
| // einer Sequence der Laenge 0 in Uno). |
| // Wenn Parameter angegeben sind, wird fuer jeden eine Dimension erzeugt |
| // DimArray( 2, 2, 4 ) entspricht DIM a( 2, 2, 4 ) |
| // Das Array ist immer vom Typ Variant |
| RTLFUNC(DimArray) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| SbxDimArray * pArray = new SbxDimArray( SbxVARIANT ); |
| sal_uInt16 nArrayDims = rPar.Count() - 1; |
| if( nArrayDims > 0 ) |
| { |
| for( sal_uInt16 i = 0; i < nArrayDims ; i++ ) |
| { |
| sal_Int32 ub = rPar.Get(i+1)->GetLong(); |
| if( ub < 0 ) |
| { |
| StarBASIC::Error( SbERR_OUT_OF_RANGE ); |
| ub = 0; |
| } |
| pArray->AddDim32( 0, ub ); |
| } |
| } |
| else |
| pArray->unoAddDim( 0, -1 ); |
| |
| // Array zurueckliefern |
| SbxVariableRef refVar = rPar.Get(0); |
| sal_uInt16 nFlags = refVar->GetFlags(); |
| refVar->ResetFlag( SBX_FIXED ); |
| refVar->PutObject( pArray ); |
| refVar->SetFlags( nFlags ); |
| refVar->SetParameters( NULL ); |
| } |
| |
| /* |
| * FindObject und FindPropertyObject ermoeglichen es, |
| * Objekte und Properties vom Typ Objekt zur Laufzeit |
| * ueber ihren Namen als String-Parameter anzusprechen. |
| * |
| * Bsp.: |
| * MyObj.Prop1.Bla = 5 |
| * |
| * entspricht: |
| * dim ObjVar as Object |
| * dim ObjProp as Object |
| * ObjName$ = "MyObj" |
| * ObjVar = FindObject( ObjName$ ) |
| * PropName$ = "Prop1" |
| * ObjProp = FindPropertyObject( ObjVar, PropName$ ) |
| * ObjProp.Bla = 5 |
| * |
| * Dabei koennen die Namen zur Laufzeit dynamisch |
| * erzeugt werden und, so dass z.B. ueber Controls |
| * "TextEdit1" bis "TextEdit5" in einem Dialog in |
| * einer Schleife iteriert werden kann. |
| */ |
| |
| // Objekt ueber den Namen ansprechen |
| // 1. Parameter = Name des Objekts als String |
| RTLFUNC(FindObject) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| // Wir brauchen einen Parameter |
| if ( rPar.Count() < 2 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| // 1. Parameter ist der Name |
| String aNameStr = rPar.Get(1)->GetString(); |
| |
| // Basic-Suchfunktion benutzen |
| SbxBase* pFind = StarBASIC::FindSBXInCurrentScope( aNameStr ); |
| SbxObject* pFindObj = NULL; |
| if( pFind ) |
| pFindObj = PTR_CAST(SbxObject,pFind); |
| /* |
| if( !pFindObj ) |
| { |
| StarBASIC::Error( SbERR_VAR_UNDEFINED ); |
| return; |
| } |
| */ |
| |
| // Objekt zurueckliefern |
| SbxVariableRef refVar = rPar.Get(0); |
| refVar->PutObject( pFindObj ); |
| } |
| |
| // Objekt-Property in einem Objekt ansprechen |
| // 1. Parameter = Objekt |
| // 2. Parameter = Name der Property als String |
| RTLFUNC(FindPropertyObject) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| // Wir brauchen 2 Parameter |
| if ( rPar.Count() < 3 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| // 1. Parameter holen, muss Objekt sein |
| SbxBase* pObjVar = (SbxObject*)rPar.Get(1)->GetObject(); |
| SbxObject* pObj = NULL; |
| if( pObjVar ) |
| pObj = PTR_CAST(SbxObject,pObjVar); |
| if( !pObj && pObjVar && pObjVar->ISA(SbxVariable) ) |
| { |
| SbxBase* pObjVarObj = ((SbxVariable*)pObjVar)->GetObject(); |
| pObj = PTR_CAST(SbxObject,pObjVarObj); |
| } |
| /* |
| if( !pObj ) |
| { |
| StarBASIC::Error( SbERR_VAR_UNDEFINED ); |
| return; |
| } |
| */ |
| |
| // 2. Parameter ist der Name |
| String aNameStr = rPar.Get(2)->GetString(); |
| |
| // Jetzt muss ein Objekt da sein, sonst Error |
| SbxObject* pFindObj = NULL; |
| if( pObj ) |
| { |
| // Im Objekt nach Objekt suchen |
| SbxVariable* pFindVar = pObj->Find( aNameStr, SbxCLASS_OBJECT ); |
| pFindObj = PTR_CAST(SbxObject,pFindVar); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_PARAMETER ); |
| |
| // Objekt zurueckliefern |
| SbxVariableRef refVar = rPar.Get(0); |
| refVar->PutObject( pFindObj ); |
| } |
| |
| |
| |
| sal_Bool lcl_WriteSbxVariable( const SbxVariable& rVar, SvStream* pStrm, |
| sal_Bool bBinary, short nBlockLen, sal_Bool bIsArray ) |
| { |
| sal_uIntPtr nFPos = pStrm->Tell(); |
| |
| sal_Bool bIsVariant = !rVar.IsFixed(); |
| SbxDataType eType = rVar.GetType(); |
| |
| switch( eType ) |
| { |
| case SbxBOOL: |
| case SbxCHAR: |
| case SbxBYTE: |
| if( bIsVariant ) |
| *pStrm << (sal_uInt16)SbxBYTE; // VarType Id |
| *pStrm << rVar.GetByte(); |
| break; |
| |
| case SbxEMPTY: |
| case SbxNULL: |
| case SbxVOID: |
| case SbxINTEGER: |
| case SbxUSHORT: |
| case SbxINT: |
| case SbxUINT: |
| if( bIsVariant ) |
| *pStrm << (sal_uInt16)SbxINTEGER; // VarType Id |
| *pStrm << rVar.GetInteger(); |
| break; |
| |
| case SbxLONG: |
| case SbxULONG: |
| case SbxLONG64: |
| case SbxULONG64: |
| if( bIsVariant ) |
| *pStrm << (sal_uInt16)SbxLONG; // VarType Id |
| *pStrm << rVar.GetLong(); |
| break; |
| |
| case SbxSINGLE: |
| if( bIsVariant ) |
| *pStrm << (sal_uInt16)eType; // VarType Id |
| *pStrm << rVar.GetSingle(); |
| break; |
| |
| case SbxDOUBLE: |
| case SbxCURRENCY: |
| case SbxDATE: |
| if( bIsVariant ) |
| *pStrm << (sal_uInt16)eType; // VarType Id |
| *pStrm << rVar.GetDouble(); |
| break; |
| |
| case SbxSTRING: |
| case SbxLPSTR: |
| { |
| const String& rStr = rVar.GetString(); |
| if( !bBinary || bIsArray ) |
| { |
| if( bIsVariant ) |
| *pStrm << (sal_uInt16)SbxSTRING; |
| pStrm->WriteByteString( rStr, gsl_getSystemTextEncoding() ); |
| //*pStrm << rStr; |
| } |
| else |
| { |
| // ohne Laengenangabe! ohne Endekennung! |
| // What does that mean for Unicode?! Choosing conversion to ByteString... |
| ByteString aByteStr( rStr, gsl_getSystemTextEncoding() ); |
| *pStrm << (const char*)aByteStr.GetBuffer(); |
| //*pStrm << (const char*)rStr.GetStr(); |
| } |
| } |
| break; |
| |
| default: |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return sal_False; |
| } |
| |
| if( nBlockLen ) |
| pStrm->Seek( nFPos + nBlockLen ); |
| return pStrm->GetErrorCode() ? sal_False : sal_True; |
| } |
| |
| sal_Bool lcl_ReadSbxVariable( SbxVariable& rVar, SvStream* pStrm, |
| sal_Bool bBinary, short nBlockLen, sal_Bool bIsArray ) |
| { |
| (void)bBinary; |
| (void)bIsArray; |
| |
| double aDouble; |
| |
| sal_uIntPtr nFPos = pStrm->Tell(); |
| |
| sal_Bool bIsVariant = !rVar.IsFixed(); |
| SbxDataType eVarType = rVar.GetType(); |
| |
| SbxDataType eSrcType = eVarType; |
| if( bIsVariant ) |
| { |
| sal_uInt16 nTemp; |
| *pStrm >> nTemp; |
| eSrcType = (SbxDataType)nTemp; |
| } |
| |
| switch( eSrcType ) |
| { |
| case SbxBOOL: |
| case SbxCHAR: |
| case SbxBYTE: |
| { |
| sal_uInt8 aByte; |
| *pStrm >> aByte; |
| |
| if( bBinary && SbiRuntime::isVBAEnabled() && aByte == 1 && pStrm->IsEof() ) |
| aByte = 0; |
| |
| rVar.PutByte( aByte ); |
| } |
| break; |
| |
| case SbxEMPTY: |
| case SbxNULL: |
| case SbxVOID: |
| case SbxINTEGER: |
| case SbxUSHORT: |
| case SbxINT: |
| case SbxUINT: |
| { |
| sal_Int16 aInt; |
| *pStrm >> aInt; |
| rVar.PutInteger( aInt ); |
| } |
| break; |
| |
| case SbxLONG: |
| case SbxULONG: |
| case SbxLONG64: |
| case SbxULONG64: |
| { |
| sal_Int32 aInt; |
| *pStrm >> aInt; |
| rVar.PutLong( aInt ); |
| } |
| break; |
| |
| case SbxSINGLE: |
| { |
| float nS; |
| *pStrm >> nS; |
| rVar.PutSingle( nS ); |
| } |
| break; |
| |
| case SbxDOUBLE: |
| case SbxCURRENCY: |
| { |
| *pStrm >> aDouble; |
| rVar.PutDouble( aDouble ); |
| } |
| break; |
| |
| case SbxDATE: |
| { |
| *pStrm >> aDouble; |
| rVar.PutDate( aDouble ); |
| } |
| break; |
| |
| case SbxSTRING: |
| case SbxLPSTR: |
| { |
| String aStr; |
| pStrm->ReadByteString( aStr, gsl_getSystemTextEncoding() ); |
| rVar.PutString( aStr ); |
| } |
| break; |
| |
| default: |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return sal_False; |
| } |
| |
| if( nBlockLen ) |
| pStrm->Seek( nFPos + nBlockLen ); |
| return pStrm->GetErrorCode() ? sal_False : sal_True; |
| } |
| |
| |
| // nCurDim = 1...n |
| sal_Bool lcl_WriteReadSbxArray( SbxDimArray& rArr, SvStream* pStrm, |
| sal_Bool bBinary, short nCurDim, short* pOtherDims, sal_Bool bWrite ) |
| { |
| DBG_ASSERT( nCurDim > 0,"Bad Dim"); |
| short nLower, nUpper; |
| if( !rArr.GetDim( nCurDim, nLower, nUpper ) ) |
| return sal_False; |
| for( short nCur = nLower; nCur <= nUpper; nCur++ ) |
| { |
| pOtherDims[ nCurDim-1 ] = nCur; |
| if( nCurDim != 1 ) |
| lcl_WriteReadSbxArray(rArr, pStrm, bBinary, nCurDim-1, pOtherDims, bWrite); |
| else |
| { |
| SbxVariable* pVar = rArr.Get( (const short*)pOtherDims ); |
| sal_Bool bRet; |
| if( bWrite ) |
| bRet = lcl_WriteSbxVariable(*pVar, pStrm, bBinary, 0, sal_True ); |
| else |
| bRet = lcl_ReadSbxVariable(*pVar, pStrm, bBinary, 0, sal_True ); |
| if( !bRet ) |
| return sal_False; |
| } |
| } |
| return sal_True; |
| } |
| |
| void PutGet( SbxArray& rPar, sal_Bool bPut ) |
| { |
| // Wir brauchen 3 Parameter |
| if ( rPar.Count() != 4 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| sal_Int16 nFileNo = rPar.Get(1)->GetInteger(); |
| SbxVariable* pVar2 = rPar.Get(2); |
| SbxDataType eType2 = pVar2->GetType(); |
| sal_Bool bHasRecordNo = (sal_Bool)(eType2 != SbxEMPTY && eType2 != SbxERROR); |
| long nRecordNo = pVar2->GetLong(); |
| if ( nFileNo < 1 || ( bHasRecordNo && nRecordNo < 1 ) ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| nRecordNo--; // wir moegen's ab 0! |
| SbiIoSystem* pIO = pINST->GetIoSystem(); |
| SbiStream* pSbStrm = pIO->GetStream( nFileNo ); |
| // das File muss Random (feste Record-Laenge) oder Binary sein |
| if ( !pSbStrm || !(pSbStrm->GetMode() & (SBSTRM_BINARY | SBSTRM_RANDOM)) ) |
| { |
| StarBASIC::Error( SbERR_BAD_CHANNEL ); |
| return; |
| } |
| |
| SvStream* pStrm = pSbStrm->GetStrm(); |
| sal_Bool bRandom = pSbStrm->IsRandom(); |
| short nBlockLen = bRandom ? pSbStrm->GetBlockLen() : 0; |
| |
| if( bPut ) |
| { |
| // Datei aufplustern, falls jemand uebers Dateiende hinaus geseekt hat |
| pSbStrm->ExpandFile(); |
| } |
| |
| // auf die Startposition seeken |
| if( bHasRecordNo ) |
| { |
| sal_uIntPtr nFilePos = bRandom ? (sal_uIntPtr)(nBlockLen*nRecordNo) : (sal_uIntPtr)nRecordNo; |
| pStrm->Seek( nFilePos ); |
| } |
| |
| SbxDimArray* pArr = 0; |
| SbxVariable* pVar = rPar.Get(3); |
| if( pVar->GetType() & SbxARRAY ) |
| { |
| SbxBase* pParObj = pVar->GetObject(); |
| pArr = PTR_CAST(SbxDimArray,pParObj); |
| } |
| |
| sal_Bool bRet; |
| |
| if( pArr ) |
| { |
| sal_uIntPtr nFPos = pStrm->Tell(); |
| short nDims = pArr->GetDims(); |
| short* pDims = new short[ nDims ]; |
| bRet = lcl_WriteReadSbxArray(*pArr,pStrm,!bRandom,nDims,pDims,bPut); |
| delete [] pDims; |
| if( nBlockLen ) |
| pStrm->Seek( nFPos + nBlockLen ); |
| } |
| else |
| { |
| if( bPut ) |
| bRet = lcl_WriteSbxVariable(*pVar, pStrm, !bRandom, nBlockLen, sal_False); |
| else |
| bRet = lcl_ReadSbxVariable(*pVar, pStrm, !bRandom, nBlockLen, sal_False); |
| } |
| if( !bRet || pStrm->GetErrorCode() ) |
| StarBASIC::Error( SbERR_IO_ERROR ); |
| } |
| |
| RTLFUNC(Put) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| PutGet( rPar, sal_True ); |
| } |
| |
| RTLFUNC(Get) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| PutGet( rPar, sal_False ); |
| } |
| |
| RTLFUNC(Environ) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 2 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| String aResult; |
| // sollte ANSI sein, aber unter Win16 in DLL nicht moeglich |
| ByteString aByteStr( rPar.Get(1)->GetString(), gsl_getSystemTextEncoding() ); |
| const char* pEnvStr = getenv( aByteStr.GetBuffer() ); |
| if ( pEnvStr ) |
| aResult = String::CreateFromAscii( pEnvStr ); |
| rPar.Get(0)->PutString( aResult ); |
| } |
| |
| static double GetDialogZoomFactor( sal_Bool bX, long nValue ) |
| { |
| OutputDevice* pDevice = Application::GetDefaultDevice(); |
| double nResult = 0; |
| if( pDevice ) |
| { |
| Size aRefSize( nValue, nValue ); |
| Fraction aFracX( 1, 26 ); |
| Fraction aFracY( 1, 24 ); |
| MapMode aMap( MAP_APPFONT, Point(), aFracX, aFracY ); |
| Size aScaledSize = pDevice->LogicToPixel( aRefSize, aMap ); |
| aRefSize = pDevice->LogicToPixel( aRefSize, MapMode(MAP_TWIP) ); |
| |
| double nRef, nScaled; |
| if( bX ) |
| { |
| nRef = aRefSize.Width(); |
| nScaled = aScaledSize.Width(); |
| } |
| else |
| { |
| nRef = aRefSize.Height(); |
| nScaled = aScaledSize.Height(); |
| } |
| nResult = nScaled / nRef; |
| } |
| return nResult; |
| } |
| |
| |
| RTLFUNC(GetDialogZoomFactorX) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 2 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| rPar.Get(0)->PutDouble( GetDialogZoomFactor( sal_True, rPar.Get(1)->GetLong() )); |
| } |
| |
| RTLFUNC(GetDialogZoomFactorY) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 2 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| rPar.Get(0)->PutDouble( GetDialogZoomFactor( sal_False, rPar.Get(1)->GetLong())); |
| } |
| |
| |
| RTLFUNC(EnableReschedule) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| rPar.Get(0)->PutEmpty(); |
| if ( rPar.Count() != 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| if( pINST ) |
| pINST->EnableReschedule( rPar.Get(1)->GetBool() ); |
| } |
| |
| RTLFUNC(GetSystemTicks) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 1 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| rPar.Get(0)->PutLong( Time::GetSystemTicks() ); |
| } |
| |
| RTLFUNC(GetPathSeparator) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 1 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| rPar.Get(0)->PutString( DirEntry::GetAccessDelimiter() ); |
| } |
| |
| RTLFUNC(ResolvePath) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() == 2 ) |
| { |
| String aStr = rPar.Get(1)->GetString(); |
| DirEntry aEntry( aStr ); |
| //if( aEntry.IsVirtual() ) |
| //aStr = aEntry.GetRealPathFromVirtualURL(); |
| rPar.Get(0)->PutString( aStr ); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| |
| RTLFUNC(TypeLen) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| SbxDataType eType = rPar.Get(1)->GetType(); |
| sal_Int16 nLen = 0; |
| switch( eType ) |
| { |
| case SbxEMPTY: |
| case SbxNULL: |
| case SbxVECTOR: |
| case SbxARRAY: |
| case SbxBYREF: |
| case SbxVOID: |
| case SbxHRESULT: |
| case SbxPOINTER: |
| case SbxDIMARRAY: |
| case SbxCARRAY: |
| case SbxUSERDEF: |
| nLen = 0; |
| break; |
| |
| case SbxINTEGER: |
| case SbxERROR: |
| case SbxUSHORT: |
| case SbxINT: |
| case SbxUINT: |
| nLen = 2; |
| break; |
| |
| case SbxLONG: |
| case SbxSINGLE: |
| case SbxULONG: |
| nLen = 4; |
| break; |
| |
| case SbxDOUBLE: |
| case SbxCURRENCY: |
| case SbxDATE: |
| case SbxLONG64: |
| case SbxULONG64: |
| nLen = 8; |
| break; |
| |
| case SbxOBJECT: |
| case SbxVARIANT: |
| case SbxDATAOBJECT: |
| nLen = 0; |
| break; |
| |
| case SbxCHAR: |
| case SbxBYTE: |
| case SbxBOOL: |
| nLen = 1; |
| break; |
| |
| case SbxLPSTR: |
| case SbxLPWSTR: |
| case SbxCoreSTRING: |
| case SbxSTRING: |
| nLen = (sal_Int16)rPar.Get(1)->GetString().Len(); |
| break; |
| |
| default: |
| nLen = 0; |
| } |
| rPar.Get(0)->PutInteger( nLen ); |
| } |
| } |
| |
| |
| // Uno-Struct eines beliebigen Typs erzeugen |
| // 1. Parameter == Klassename, weitere Parameter zur Initialisierung |
| RTLFUNC(CreateUnoStruct) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| RTL_Impl_CreateUnoStruct( pBasic, rPar, bWrite ); |
| } |
| |
| // Uno-Service erzeugen |
| // 1. Parameter == Service-Name |
| RTLFUNC(CreateUnoService) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| RTL_Impl_CreateUnoService( pBasic, rPar, bWrite ); |
| } |
| |
| RTLFUNC(CreateUnoServiceWithArguments) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| RTL_Impl_CreateUnoServiceWithArguments( pBasic, rPar, bWrite ); |
| } |
| |
| |
| RTLFUNC(CreateUnoValue) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| RTL_Impl_CreateUnoValue( pBasic, rPar, bWrite ); |
| } |
| |
| |
| // ServiceManager liefern (keine Parameter) |
| RTLFUNC(GetProcessServiceManager) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| RTL_Impl_GetProcessServiceManager( pBasic, rPar, bWrite ); |
| } |
| |
| // PropertySet erzeugen |
| // 1. Parameter == Sequence<PropertyValue> |
| RTLFUNC(CreatePropertySet) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| RTL_Impl_CreatePropertySet( pBasic, rPar, bWrite ); |
| } |
| |
| // Abfragen, ob ein Interface unterstuetzt wird |
| // Mehrere Interface-Namen als Parameter |
| RTLFUNC(HasUnoInterfaces) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| RTL_Impl_HasInterfaces( pBasic, rPar, bWrite ); |
| } |
| |
| // Abfragen, ob ein Basic-Objekt ein Uno-Struct repraesentiert |
| RTLFUNC(IsUnoStruct) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| RTL_Impl_IsUnoStruct( pBasic, rPar, bWrite ); |
| } |
| |
| // Abfragen, ob zwei Uno-Objekte identisch sind |
| RTLFUNC(EqualUnoObjects) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| RTL_Impl_EqualUnoObjects( pBasic, rPar, bWrite ); |
| } |
| |
| // Instanciate "com.sun.star.awt.UnoControlDialog" on basis |
| // of a DialogLibrary entry: Convert from XML-ByteSequence |
| // and attach events. Implemented in classes\eventatt.cxx |
| void RTL_Impl_CreateUnoDialog( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite ); |
| |
| RTLFUNC(CreateUnoDialog) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| RTL_Impl_CreateUnoDialog( pBasic, rPar, bWrite ); |
| } |
| |
| // Return the application standard lib as root scope |
| RTLFUNC(GlobalScope) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| SbxObject* p = pBasic; |
| while( p->GetParent() ) |
| p = p->GetParent(); |
| |
| SbxVariableRef refVar = rPar.Get(0); |
| refVar->PutObject( p ); |
| } |
| |
| // Helper functions to convert Url from/to system paths |
| RTLFUNC(ConvertToUrl) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() == 2 ) |
| { |
| String aStr = rPar.Get(1)->GetString(); |
| INetURLObject aURLObj( aStr, INET_PROT_FILE ); |
| ::rtl::OUString aFileURL = aURLObj.GetMainURL( INetURLObject::NO_DECODE ); |
| if( aFileURL.isEmpty() ) |
| ::osl::File::getFileURLFromSystemPath( aFileURL, aFileURL ); |
| if( aFileURL.isEmpty() ) |
| aFileURL = aStr; |
| rPar.Get(0)->PutString( String(aFileURL) ); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| |
| RTLFUNC(ConvertFromUrl) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() == 2 ) |
| { |
| String aStr = rPar.Get(1)->GetString(); |
| ::rtl::OUString aSysPath; |
| ::osl::File::getSystemPathFromFileURL( aStr, aSysPath ); |
| if( aSysPath.isEmpty() ) |
| aSysPath = aStr; |
| rPar.Get(0)->PutString( String(aSysPath) ); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| |
| |
| // Provide DefaultContext |
| RTLFUNC(GetDefaultContext) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| RTL_Impl_GetDefaultContext( pBasic, rPar, bWrite ); |
| } |
| |
| #ifdef DBG_TRACE_BASIC |
| RTLFUNC(TraceCommand) |
| { |
| RTL_Impl_TraceCommand( pBasic, rPar, bWrite ); |
| } |
| #endif |
| |
| RTLFUNC(Join) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_uInt16 nParCount = rPar.Count(); |
| if ( nParCount != 3 && nParCount != 2 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| SbxBase* pParObj = rPar.Get(1)->GetObject(); |
| SbxDimArray* pArr = PTR_CAST(SbxDimArray,pParObj); |
| if( pArr ) |
| { |
| if( pArr->GetDims() != 1 ) |
| StarBASIC::Error( SbERR_WRONG_DIMS ); // Syntax Error?! |
| |
| String aDelim; |
| if( nParCount == 3 ) |
| aDelim = rPar.Get(2)->GetString(); |
| else |
| aDelim = String::CreateFromAscii( " " ); |
| |
| String aRetStr; |
| short nLower, nUpper; |
| pArr->GetDim( 1, nLower, nUpper ); |
| for( short i = nLower ; i <= nUpper ; ++i ) |
| { |
| String aStr = pArr->Get( &i )->GetString(); |
| aRetStr += aStr; |
| if( i != nUpper ) |
| aRetStr += aDelim; |
| } |
| rPar.Get(0)->PutString( aRetStr ); |
| } |
| else |
| StarBASIC::Error( SbERR_MUST_HAVE_DIMS ); |
| } |
| |
| |
| RTLFUNC(Split) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_uInt16 nParCount = rPar.Count(); |
| if ( nParCount < 2 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| String aExpression = rPar.Get(1)->GetString(); |
| short nArraySize = 0; |
| StringVector vRet; |
| if( aExpression.Len() ) |
| { |
| String aDelim; |
| if( nParCount >= 3 ) |
| aDelim = rPar.Get(2)->GetString(); |
| else |
| aDelim = String::CreateFromAscii( " " ); |
| |
| sal_Int32 nCount = -1; |
| if( nParCount == 4 ) |
| nCount = rPar.Get(3)->GetLong(); |
| |
| xub_StrLen nDelimLen = aDelim.Len(); |
| if( nDelimLen ) |
| { |
| xub_StrLen iSearch = STRING_NOTFOUND; |
| xub_StrLen iStart = 0; |
| do |
| { |
| bool bBreak = false; |
| if( nCount >= 0 && nArraySize == nCount - 1 ) |
| bBreak = true; |
| |
| iSearch = aExpression.Search( aDelim, iStart ); |
| String aSubStr; |
| if( iSearch != STRING_NOTFOUND && !bBreak ) |
| { |
| aSubStr = aExpression.Copy( iStart, iSearch - iStart ); |
| iStart = iSearch + nDelimLen; |
| } |
| else |
| { |
| aSubStr = aExpression.Copy( iStart ); |
| } |
| vRet.push_back( aSubStr ); |
| nArraySize++; |
| |
| if( bBreak ) |
| break; |
| } |
| while( iSearch != STRING_NOTFOUND ); |
| } |
| else |
| { |
| vRet.push_back( aExpression ); |
| nArraySize = 1; |
| } |
| } |
| |
| SbxDimArray* pArray = new SbxDimArray( SbxVARIANT ); |
| pArray->unoAddDim( 0, nArraySize-1 ); |
| |
| // Parameter ins Array uebernehmen |
| for( short i = 0 ; i < nArraySize ; i++ ) |
| { |
| SbxVariableRef xVar = new SbxVariable( SbxVARIANT ); |
| xVar->PutString( vRet[i] ); |
| pArray->Put( (SbxVariable*)xVar, &i ); |
| } |
| |
| // Array zurueckliefern |
| SbxVariableRef refVar = rPar.Get(0); |
| sal_uInt16 nFlags = refVar->GetFlags(); |
| refVar->ResetFlag( SBX_FIXED ); |
| refVar->PutObject( pArray ); |
| refVar->SetFlags( nFlags ); |
| refVar->SetParameters( NULL ); |
| } |
| |
| // MonthName(month[, abbreviate]) |
| RTLFUNC(MonthName) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_uInt16 nParCount = rPar.Count(); |
| if( nParCount != 2 && nParCount != 3 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| Reference< XCalendar > xCalendar = getLocaleCalendar(); |
| if( !xCalendar.is() ) |
| { |
| StarBASIC::Error( SbERR_INTERNAL_ERROR ); |
| return; |
| } |
| Sequence< CalendarItem > aMonthSeq = xCalendar->getMonths(); |
| sal_Int32 nMonthCount = aMonthSeq.getLength(); |
| |
| sal_Int16 nVal = rPar.Get(1)->GetInteger(); |
| if( nVal < 1 || nVal > nMonthCount ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| sal_Bool bAbbreviate = false; |
| if( nParCount == 3 ) |
| bAbbreviate = rPar.Get(2)->GetBool(); |
| |
| const CalendarItem* pCalendarItems = aMonthSeq.getConstArray(); |
| const CalendarItem& rItem = pCalendarItems[nVal - 1]; |
| |
| ::rtl::OUString aRetStr = ( bAbbreviate ? rItem.AbbrevName : rItem.FullName ); |
| rPar.Get(0)->PutString( String(aRetStr) ); |
| } |
| |
| // WeekdayName(weekday, abbreviate, firstdayofweek) |
| RTLFUNC(WeekdayName) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_uInt16 nParCount = rPar.Count(); |
| if( nParCount < 2 || nParCount > 4 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| Reference< XCalendar > xCalendar = getLocaleCalendar(); |
| if( !xCalendar.is() ) |
| { |
| StarBASIC::Error( SbERR_INTERNAL_ERROR ); |
| return; |
| } |
| |
| Sequence< CalendarItem > aDaySeq = xCalendar->getDays(); |
| sal_Int16 nDayCount = (sal_Int16)aDaySeq.getLength(); |
| sal_Int16 nDay = rPar.Get(1)->GetInteger(); |
| sal_Int16 nFirstDay = 0; |
| if( nParCount == 4 ) |
| { |
| nFirstDay = rPar.Get(3)->GetInteger(); |
| if( nFirstDay < 0 || nFirstDay > 7 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| } |
| if( nFirstDay == 0 ) |
| nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 ); |
| |
| nDay = 1 + (nDay + nDayCount + nFirstDay - 2) % nDayCount; |
| if( nDay < 1 || nDay > nDayCount ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| sal_Bool bAbbreviate = false; |
| if( nParCount >= 3 ) |
| { |
| SbxVariable* pPar2 = rPar.Get(2); |
| if( !pPar2->IsErr() ) |
| bAbbreviate = pPar2->GetBool(); |
| } |
| |
| const CalendarItem* pCalendarItems = aDaySeq.getConstArray(); |
| const CalendarItem& rItem = pCalendarItems[nDay - 1]; |
| |
| ::rtl::OUString aRetStr = ( bAbbreviate ? rItem.AbbrevName : rItem.FullName ); |
| rPar.Get(0)->PutString( String(aRetStr) ); |
| } |
| |
| sal_Int16 implGetWeekDay( double aDate, bool bFirstDayParam = false, sal_Int16 nFirstDay = 0 ) |
| { |
| Date aRefDate( 1,1,1900 ); |
| long nDays = (long) aDate; |
| nDays -= 2; // normieren: 1.1.1900 => 0 |
| aRefDate += nDays; |
| DayOfWeek aDay = aRefDate.GetDayOfWeek(); |
| sal_Int16 nDay; |
| if ( aDay != SUNDAY ) |
| nDay = (sal_Int16)aDay + 2; |
| else |
| nDay = 1; // 1==Sonntag |
| |
| // #117253 Optional 2. parameter "firstdayofweek" |
| if( bFirstDayParam ) |
| { |
| if( nFirstDay < 0 || nFirstDay > 7 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return 0; |
| } |
| if( nFirstDay == 0 ) |
| { |
| Reference< XCalendar > xCalendar = getLocaleCalendar(); |
| if( !xCalendar.is() ) |
| { |
| StarBASIC::Error( SbERR_INTERNAL_ERROR ); |
| return 0; |
| } |
| nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 ); |
| } |
| nDay = 1 + (nDay + 7 - nFirstDay) % 7; |
| } |
| return nDay; |
| } |
| |
| RTLFUNC(Weekday) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_uInt16 nParCount = rPar.Count(); |
| if ( nParCount < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| double aDate = rPar.Get(1)->GetDate(); |
| |
| bool bFirstDay = false; |
| sal_Int16 nFirstDay = 0; |
| if ( nParCount > 2 ) |
| { |
| nFirstDay = rPar.Get(2)->GetInteger(); |
| bFirstDay = true; |
| } |
| sal_Int16 nDay = implGetWeekDay( aDate, bFirstDay, nFirstDay ); |
| rPar.Get(0)->PutInteger( nDay ); |
| } |
| } |
| |
| |
| enum Interval |
| { |
| INTERVAL_NONE, |
| INTERVAL_YYYY, |
| INTERVAL_Q, |
| INTERVAL_M, |
| INTERVAL_Y, |
| INTERVAL_D, |
| INTERVAL_W, |
| INTERVAL_WW, |
| INTERVAL_H, |
| INTERVAL_N, |
| INTERVAL_S |
| }; |
| |
| struct IntervalInfo |
| { |
| Interval meInterval; |
| const char* mpStringCode; |
| double mdValue; |
| bool mbSimple; |
| |
| IntervalInfo( Interval eInterval, const char* pStringCode, double dValue, bool bSimple ) |
| : meInterval( eInterval ) |
| , mpStringCode( pStringCode ) |
| , mdValue( dValue ) |
| , mbSimple( bSimple ) |
| {} |
| }; |
| |
| static IntervalInfo pIntervalTable[] = |
| { |
| IntervalInfo( INTERVAL_YYYY, "yyyy", 0.0, false ), // Year |
| IntervalInfo( INTERVAL_Q, "q", 0.0, false ), // Quarter |
| IntervalInfo( INTERVAL_M, "m", 0.0, false ), // Month |
| IntervalInfo( INTERVAL_Y, "y", 1.0, true ), // Day of year |
| IntervalInfo( INTERVAL_D, "d", 1.0, true ), // Day |
| IntervalInfo( INTERVAL_W, "w", 1.0, true ), // Weekday |
| IntervalInfo( INTERVAL_WW, "ww", 7.0, true ), // Week |
| IntervalInfo( INTERVAL_H, "h", (1.0 / 24.0), true ), // Hour |
| IntervalInfo( INTERVAL_N, "n", (1.0 / 1440.0), true), // Minute |
| IntervalInfo( INTERVAL_S, "s", (1.0 / 86400.0), true ), // Second |
| IntervalInfo( INTERVAL_NONE, NULL, 0.0, false ) |
| }; |
| |
| IntervalInfo* getIntervalInfo( const String& rStringCode ) |
| { |
| IntervalInfo* pInfo = NULL; |
| sal_Int16 i = 0; |
| while( (pInfo = pIntervalTable + i)->mpStringCode != NULL ) |
| { |
| if( rStringCode.EqualsIgnoreCaseAscii( pInfo->mpStringCode ) ) |
| break; |
| i++; |
| } |
| return pInfo; |
| } |
| |
| // From methods.cxx |
| sal_Bool implDateSerial( sal_Int16 nYear, sal_Int16 nMonth, sal_Int16 nDay, double& rdRet ); |
| sal_Int16 implGetDateDay( double aDate ); |
| sal_Int16 implGetDateMonth( double aDate ); |
| sal_Int16 implGetDateYear( double aDate ); |
| |
| sal_Int16 implGetHour( double dDate ); |
| sal_Int16 implGetMinute( double dDate ); |
| sal_Int16 implGetSecond( double dDate ); |
| |
| |
| inline void implGetDayMonthYear( sal_Int16& rnYear, sal_Int16& rnMonth, sal_Int16& rnDay, double dDate ) |
| { |
| rnDay = implGetDateDay( dDate ); |
| rnMonth = implGetDateMonth( dDate ); |
| rnYear = implGetDateYear( dDate ); |
| } |
| |
| inline sal_Int16 limitToINT16( sal_Int32 n32 ) |
| { |
| if( n32 > 32767 ) |
| n32 = 32767; |
| else if( n32 < -32768 ) |
| n32 = -32768; |
| return (sal_Int16)n32; |
| } |
| |
| RTLFUNC(DateAdd) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_uInt16 nParCount = rPar.Count(); |
| if( nParCount != 4 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| String aStringCode = rPar.Get(1)->GetString(); |
| IntervalInfo* pInfo = getIntervalInfo( aStringCode ); |
| if( !pInfo ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| sal_Int32 lNumber = rPar.Get(2)->GetLong(); |
| double dDate = rPar.Get(3)->GetDate(); |
| double dNewDate = 0; |
| if( pInfo->mbSimple ) |
| { |
| double dAdd = pInfo->mdValue * lNumber; |
| dNewDate = dDate + dAdd; |
| } |
| else |
| { |
| // Keep hours, minutes, seconds |
| double dHoursMinutesSeconds = dDate - floor( dDate ); |
| |
| sal_Bool bOk = sal_True; |
| sal_Int16 nYear, nMonth, nDay; |
| sal_Int16 nTargetYear16 = 0, nTargetMonth = 0; |
| implGetDayMonthYear( nYear, nMonth, nDay, dDate ); |
| switch( pInfo->meInterval ) |
| { |
| case INTERVAL_YYYY: |
| { |
| sal_Int32 nTargetYear = lNumber + nYear; |
| nTargetYear16 = limitToINT16( nTargetYear ); |
| nTargetMonth = nMonth; |
| bOk = implDateSerial( nTargetYear16, nTargetMonth, nDay, dNewDate ); |
| break; |
| } |
| case INTERVAL_Q: |
| case INTERVAL_M: |
| { |
| bool bNeg = (lNumber < 0); |
| if( bNeg ) |
| lNumber = -lNumber; |
| sal_Int32 nYearsAdd; |
| sal_Int16 nMonthAdd; |
| if( pInfo->meInterval == INTERVAL_Q ) |
| { |
| nYearsAdd = lNumber / 4; |
| nMonthAdd = (sal_Int16)( 3 * (lNumber % 4) ); |
| } |
| else |
| { |
| nYearsAdd = lNumber / 12; |
| nMonthAdd = (sal_Int16)( lNumber % 12 ); |
| } |
| |
| sal_Int32 nTargetYear; |
| if( bNeg ) |
| { |
| nTargetMonth = nMonth - nMonthAdd; |
| if( nTargetMonth <= 0 ) |
| { |
| nTargetMonth += 12; |
| nYearsAdd++; |
| } |
| nTargetYear = (sal_Int32)nYear - nYearsAdd; |
| } |
| else |
| { |
| nTargetMonth = nMonth + nMonthAdd; |
| if( nTargetMonth > 12 ) |
| { |
| nTargetMonth -= 12; |
| nYearsAdd++; |
| } |
| nTargetYear = (sal_Int32)nYear + nYearsAdd; |
| } |
| nTargetYear16 = limitToINT16( nTargetYear ); |
| bOk = implDateSerial( nTargetYear16, nTargetMonth, nDay, dNewDate ); |
| break; |
| } |
| default: break; |
| } |
| |
| if( bOk ) |
| { |
| // Overflow? |
| sal_Int16 nNewYear, nNewMonth, nNewDay; |
| implGetDayMonthYear( nNewYear, nNewMonth, nNewDay, dNewDate ); |
| if( nNewYear > 9999 || nNewYear < 100 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| sal_Int16 nCorrectionDay = nDay; |
| while( nNewMonth > nTargetMonth ) |
| { |
| nCorrectionDay--; |
| implDateSerial( nTargetYear16, nTargetMonth, nCorrectionDay, dNewDate ); |
| implGetDayMonthYear( nNewYear, nNewMonth, nNewDay, dNewDate ); |
| } |
| dNewDate += dHoursMinutesSeconds; |
| } |
| } |
| |
| rPar.Get(0)->PutDate( dNewDate ); |
| } |
| |
| inline double RoundImpl( double d ) |
| { |
| return ( d >= 0 ) ? floor( d + 0.5 ) : -floor( -d + 0.5 ); |
| } |
| |
| RTLFUNC(DateDiff) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| // DateDiff(interval, date1, date2[, firstdayofweek[, firstweekofyear]]) |
| |
| sal_uInt16 nParCount = rPar.Count(); |
| if( nParCount < 4 || nParCount > 6 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| String aStringCode = rPar.Get(1)->GetString(); |
| IntervalInfo* pInfo = getIntervalInfo( aStringCode ); |
| if( !pInfo ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| double dDate1 = rPar.Get(2)->GetDate(); |
| double dDate2 = rPar.Get(3)->GetDate(); |
| |
| double dRet = 0.0; |
| switch( pInfo->meInterval ) |
| { |
| case INTERVAL_YYYY: |
| { |
| sal_Int16 nYear1 = implGetDateYear( dDate1 ); |
| sal_Int16 nYear2 = implGetDateYear( dDate2 ); |
| dRet = nYear2 - nYear1; |
| break; |
| } |
| case INTERVAL_Q: |
| { |
| sal_Int16 nYear1 = implGetDateYear( dDate1 ); |
| sal_Int16 nYear2 = implGetDateYear( dDate2 ); |
| sal_Int16 nQ1 = 1 + (implGetDateMonth( dDate1 ) - 1) / 3; |
| sal_Int16 nQ2 = 1 + (implGetDateMonth( dDate2 ) - 1) / 3; |
| sal_Int16 nQGes1 = 4 * nYear1 + nQ1; |
| sal_Int16 nQGes2 = 4 * nYear2 + nQ2; |
| dRet = nQGes2 - nQGes1; |
| break; |
| } |
| case INTERVAL_M: |
| { |
| sal_Int16 nYear1 = implGetDateYear( dDate1 ); |
| sal_Int16 nYear2 = implGetDateYear( dDate2 ); |
| sal_Int16 nMonth1 = implGetDateMonth( dDate1 ); |
| sal_Int16 nMonth2 = implGetDateMonth( dDate2 ); |
| sal_Int16 nMonthGes1 = 12 * nYear1 + nMonth1; |
| sal_Int16 nMonthGes2 = 12 * nYear2 + nMonth2; |
| dRet = nMonthGes2 - nMonthGes1; |
| break; |
| } |
| case INTERVAL_Y: |
| case INTERVAL_D: |
| { |
| double dDays1 = floor( dDate1 ); |
| double dDays2 = floor( dDate2 ); |
| dRet = dDays2 - dDays1; |
| break; |
| } |
| case INTERVAL_W: |
| case INTERVAL_WW: |
| { |
| double dDays1 = floor( dDate1 ); |
| double dDays2 = floor( dDate2 ); |
| if( pInfo->meInterval == INTERVAL_WW ) |
| { |
| sal_Int16 nFirstDay = 1; // Default |
| if( nParCount >= 5 ) |
| { |
| nFirstDay = rPar.Get(4)->GetInteger(); |
| if( nFirstDay < 0 || nFirstDay > 7 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| if( nFirstDay == 0 ) |
| { |
| Reference< XCalendar > xCalendar = getLocaleCalendar(); |
| if( !xCalendar.is() ) |
| { |
| StarBASIC::Error( SbERR_INTERNAL_ERROR ); |
| return; |
| } |
| nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 ); |
| } |
| } |
| sal_Int16 nDay1 = implGetWeekDay( dDate1 ); |
| sal_Int16 nDay1_Diff = nDay1 - nFirstDay; |
| if( nDay1_Diff < 0 ) |
| nDay1_Diff += 7; |
| dDays1 -= nDay1_Diff; |
| |
| sal_Int16 nDay2 = implGetWeekDay( dDate2 ); |
| sal_Int16 nDay2_Diff = nDay2 - nFirstDay; |
| if( nDay2_Diff < 0 ) |
| nDay2_Diff += 7; |
| dDays2 -= nDay2_Diff; |
| } |
| |
| double dDiff = dDays2 - dDays1; |
| dRet = ( dDiff >= 0 ) ? floor( dDiff / 7.0 ) : -floor( -dDiff / 7.0 ); |
| break; |
| } |
| case INTERVAL_H: |
| { |
| double dFactor = 24.0; |
| dRet = RoundImpl( dFactor * (dDate2 - dDate1) ); |
| break; |
| } |
| case INTERVAL_N: |
| { |
| double dFactor =1440.0; |
| dRet = RoundImpl( dFactor * (dDate2 - dDate1) ); |
| break; |
| } |
| case INTERVAL_S: |
| { |
| double dFactor = 86400.0; |
| dRet = RoundImpl( dFactor * (dDate2 - dDate1) ); |
| break; |
| } |
| case INTERVAL_NONE: |
| break; |
| } |
| rPar.Get(0)->PutDouble( dRet ); |
| } |
| |
| double implGetDateOfFirstDayInFirstWeek |
| ( sal_Int16 nYear, sal_Int16& nFirstDay, sal_Int16& nFirstWeek, bool* pbError = NULL ) |
| { |
| SbError nError = 0; |
| if( nFirstDay < 0 || nFirstDay > 7 ) |
| nError = SbERR_BAD_ARGUMENT; |
| |
| if( nFirstWeek < 0 || nFirstWeek > 3 ) |
| nError = SbERR_BAD_ARGUMENT; |
| |
| Reference< XCalendar > xCalendar; |
| if( nFirstDay == 0 || nFirstWeek == 0 ) |
| { |
| xCalendar = getLocaleCalendar(); |
| if( !xCalendar.is() ) |
| nError = SbERR_BAD_ARGUMENT; |
| } |
| |
| if( nError != 0 ) |
| { |
| StarBASIC::Error( nError ); |
| if( pbError ) |
| *pbError = true; |
| return 0.0; |
| } |
| |
| if( nFirstDay == 0 ) |
| nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 ); |
| |
| sal_Int16 nFirstWeekMinDays = 0; // Not used for vbFirstJan1 = default |
| if( nFirstWeek == 0 ) |
| { |
| nFirstWeekMinDays = xCalendar->getMinimumNumberOfDaysForFirstWeek(); |
| if( nFirstWeekMinDays == 1 ) |
| { |
| nFirstWeekMinDays = 0; |
| nFirstWeek = 1; |
| } |
| else if( nFirstWeekMinDays == 4 ) |
| nFirstWeek = 2; |
| else if( nFirstWeekMinDays == 7 ) |
| nFirstWeek = 3; |
| } |
| else if( nFirstWeek == 2 ) |
| nFirstWeekMinDays = 4; // vbFirstFourDays |
| else if( nFirstWeek == 3 ) |
| nFirstWeekMinDays = 7; // vbFirstFourDays |
| |
| double dBaseDate; |
| implDateSerial( nYear, 1, 1, dBaseDate ); |
| double dRetDate = dBaseDate; |
| |
| sal_Int16 nWeekDay0101 = implGetWeekDay( dBaseDate ); |
| sal_Int16 nDayDiff = nWeekDay0101 - nFirstDay; |
| if( nDayDiff < 0 ) |
| nDayDiff += 7; |
| |
| if( nFirstWeekMinDays ) |
| { |
| sal_Int16 nThisWeeksDaysInYearCount = 7 - nDayDiff; |
| if( nThisWeeksDaysInYearCount < nFirstWeekMinDays ) |
| nDayDiff -= 7; |
| } |
| dRetDate = dBaseDate - nDayDiff; |
| return dRetDate; |
| } |
| |
| RTLFUNC(DatePart) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| // DatePart(interval, date[,firstdayofweek[, firstweekofyear]]) |
| |
| sal_uInt16 nParCount = rPar.Count(); |
| if( nParCount < 3 || nParCount > 5 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| String aStringCode = rPar.Get(1)->GetString(); |
| IntervalInfo* pInfo = getIntervalInfo( aStringCode ); |
| if( !pInfo ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| double dDate = rPar.Get(2)->GetDate(); |
| |
| sal_Int32 nRet = 0; |
| switch( pInfo->meInterval ) |
| { |
| case INTERVAL_YYYY: |
| { |
| nRet = implGetDateYear( dDate ); |
| break; |
| } |
| case INTERVAL_Q: |
| { |
| nRet = 1 + (implGetDateMonth( dDate ) - 1) / 3; |
| break; |
| } |
| case INTERVAL_M: |
| { |
| nRet = implGetDateMonth( dDate ); |
| break; |
| } |
| case INTERVAL_Y: |
| { |
| sal_Int16 nYear = implGetDateYear( dDate ); |
| double dBaseDate; |
| implDateSerial( nYear, 1, 1, dBaseDate ); |
| nRet = 1 + sal_Int32( dDate - dBaseDate ); |
| break; |
| } |
| case INTERVAL_D: |
| { |
| nRet = implGetDateDay( dDate ); |
| break; |
| } |
| case INTERVAL_W: |
| { |
| bool bFirstDay = false; |
| sal_Int16 nFirstDay = 1; // Default |
| if( nParCount >= 4 ) |
| { |
| nFirstDay = rPar.Get(3)->GetInteger(); |
| bFirstDay = true; |
| } |
| nRet = implGetWeekDay( dDate, bFirstDay, nFirstDay ); |
| break; |
| } |
| case INTERVAL_WW: |
| { |
| sal_Int16 nFirstDay = 1; // Default |
| if( nParCount >= 4 ) |
| nFirstDay = rPar.Get(3)->GetInteger(); |
| |
| sal_Int16 nFirstWeek = 1; // Default |
| if( nParCount == 5 ) |
| nFirstWeek = rPar.Get(4)->GetInteger(); |
| |
| sal_Int16 nYear = implGetDateYear( dDate ); |
| bool bError = false; |
| double dYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear, nFirstDay, nFirstWeek, &bError ); |
| if( !bError ) |
| { |
| if( dYearFirstDay > dDate ) |
| { |
| // Date belongs to last year's week |
| dYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear - 1, nFirstDay, nFirstWeek ); |
| } |
| else if( nFirstWeek != 1 ) |
| { |
| // Check if date belongs to next year |
| double dNextYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear + 1, nFirstDay, nFirstWeek ); |
| if( dDate >= dNextYearFirstDay ) |
| dYearFirstDay = dNextYearFirstDay; |
| } |
| |
| // Calculate week |
| double dDiff = dDate - dYearFirstDay; |
| nRet = 1 + sal_Int32( dDiff / 7 ); |
| } |
| break; |
| } |
| case INTERVAL_H: |
| { |
| nRet = implGetHour( dDate ); |
| break; |
| } |
| case INTERVAL_N: |
| { |
| nRet = implGetMinute( dDate ); |
| break; |
| } |
| case INTERVAL_S: |
| { |
| nRet = implGetSecond( dDate ); |
| break; |
| } |
| case INTERVAL_NONE: |
| break; |
| } |
| rPar.Get(0)->PutLong( nRet ); |
| } |
| |
| // FormatDateTime(Date[,NamedFormat]) |
| RTLFUNC(FormatDateTime) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_uInt16 nParCount = rPar.Count(); |
| if( nParCount < 2 || nParCount > 3 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| double dDate = rPar.Get(1)->GetDate(); |
| sal_Int16 nNamedFormat = 0; |
| if( nParCount > 2 ) |
| { |
| nNamedFormat = rPar.Get(2)->GetInteger(); |
| if( nNamedFormat < 0 || nNamedFormat > 4 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| } |
| |
| Reference< XCalendar > xCalendar = getLocaleCalendar(); |
| if( !xCalendar.is() ) |
| { |
| StarBASIC::Error( SbERR_INTERNAL_ERROR ); |
| return; |
| } |
| |
| String aRetStr; |
| SbxVariableRef pSbxVar = new SbxVariable( SbxSTRING ); |
| switch( nNamedFormat ) |
| { |
| // GeneralDate: |
| // Display a date and/or time. If there is a date part, |
| // display it as a short date. If there is a time part, |
| // display it as a long time. If present, both parts are displayed. |
| |
| // 12/21/2004 11:24:50 AM |
| // 21.12.2004 12:13:51 |
| case 0: |
| pSbxVar->PutDate( dDate ); |
| aRetStr = pSbxVar->GetString(); |
| break; |
| |
| // LongDate: Display a date using the long date format specified |
| // in your computer's regional settings. |
| // Tuesday, December 21, 2004 |
| // Dienstag, 21. December 2004 |
| case 1: |
| { |
| SvNumberFormatter* pFormatter = NULL; |
| if( pINST ) |
| pFormatter = pINST->GetNumberFormatter(); |
| else |
| { |
| sal_uInt32 n; // Dummy |
| SbiInstance::PrepareNumberFormatter( pFormatter, n, n, n ); |
| } |
| |
| LanguageType eLangType = GetpApp()->GetSettings().GetLanguage(); |
| sal_uIntPtr nIndex = pFormatter->GetFormatIndex( NF_DATE_SYSTEM_LONG, eLangType ); |
| Color* pCol; |
| pFormatter->GetOutputString( dDate, nIndex, aRetStr, &pCol ); |
| |
| if( !pINST ) |
| delete pFormatter; |
| |
| break; |
| } |
| |
| // ShortDate: Display a date using the short date format specified |
| // in your computer's regional settings. |
| // 12/21/2004 |
| // 21.12.2004 |
| case 2: |
| pSbxVar->PutDate( floor(dDate) ); |
| aRetStr = pSbxVar->GetString(); |
| break; |
| |
| // LongTime: Display a time using the time format specified |
| // in your computer's regional settings. |
| // 11:24:50 AM |
| // 12:13:51 |
| case 3: |
| // ShortTime: Display a time using the 24-hour format (hh:mm). |
| // 11:24 |
| case 4: |
| double n; |
| double dTime = modf( dDate, &n ); |
| pSbxVar->PutDate( dTime ); |
| if( nNamedFormat == 3 ) |
| aRetStr = pSbxVar->GetString(); |
| else |
| aRetStr = pSbxVar->GetString().Copy( 0, 5 ); |
| break; |
| } |
| |
| rPar.Get(0)->PutString( aRetStr ); |
| } |
| |
| RTLFUNC(Round) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_uInt16 nParCount = rPar.Count(); |
| if( nParCount != 2 && nParCount != 3 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| SbxVariable *pSbxVariable = rPar.Get(1); |
| double dVal = pSbxVariable->GetDouble(); |
| double dRes = 0.0; |
| if( dVal != 0.0 ) |
| { |
| bool bNeg = false; |
| if( dVal < 0.0 ) |
| { |
| bNeg = true; |
| dVal = -dVal; |
| } |
| |
| sal_Int16 numdecimalplaces = 0; |
| if( nParCount == 3 ) |
| { |
| numdecimalplaces = rPar.Get(2)->GetInteger(); |
| if( numdecimalplaces < 0 || numdecimalplaces > 22 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| } |
| |
| if( numdecimalplaces == 0 ) |
| { |
| dRes = floor( dVal + 0.5 ); |
| } |
| else |
| { |
| double dFactor = pow( 10.0, numdecimalplaces ); |
| dVal *= dFactor; |
| dRes = floor( dVal + 0.5 ); |
| dRes /= dFactor; |
| } |
| |
| if( bNeg ) |
| dRes = -dRes; |
| } |
| rPar.Get(0)->PutDouble( dRes ); |
| } |
| |
| RTLFUNC(StrReverse) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 2 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| SbxVariable *pSbxVariable = rPar.Get(1); |
| if( pSbxVariable->IsNull() ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| String aStr = pSbxVariable->GetString(); |
| aStr.Reverse(); |
| rPar.Get(0)->PutString( aStr ); |
| } |
| |
| RTLFUNC(CompatibilityMode) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| bool bEnabled = false; |
| sal_uInt16 nCount = rPar.Count(); |
| if ( nCount != 1 && nCount != 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| |
| SbiInstance* pInst = pINST; |
| if( pInst ) |
| { |
| if ( nCount == 2 ) |
| pInst->EnableCompatibility( rPar.Get(1)->GetBool() ); |
| |
| bEnabled = pInst->IsCompatibility(); |
| } |
| rPar.Get(0)->PutBool( bEnabled ); |
| } |
| |
| RTLFUNC(Input) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| // 2 parameters needed |
| if ( rPar.Count() < 3 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| sal_uInt16 nByteCount = rPar.Get(1)->GetUShort(); |
| sal_Int16 nFileNumber = rPar.Get(2)->GetInteger(); |
| |
| SbiIoSystem* pIosys = pINST->GetIoSystem(); |
| SbiStream* pSbStrm = pIosys->GetStream( nFileNumber ); |
| if ( !pSbStrm || !(pSbStrm->GetMode() & (SBSTRM_BINARY | SBSTRM_INPUT)) ) |
| { |
| StarBASIC::Error( SbERR_BAD_CHANNEL ); |
| return; |
| } |
| |
| ByteString aByteBuffer; |
| SbError err = pSbStrm->Read( aByteBuffer, nByteCount, true ); |
| if( !err ) |
| err = pIosys->GetError(); |
| |
| if( err ) |
| { |
| StarBASIC::Error( err ); |
| return; |
| } |
| rPar.Get(0)->PutString( String( aByteBuffer, gsl_getSystemTextEncoding() ) ); |
| } |
| |
| // #115824 |
| RTLFUNC(Me) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| SbModule* pActiveModule = pINST->GetActiveModule(); |
| SbClassModuleObject* pClassModuleObject = PTR_CAST(SbClassModuleObject,pActiveModule); |
| SbxVariableRef refVar = rPar.Get(0); |
| if( pClassModuleObject == NULL ) |
| { |
| SbObjModule* pMod = PTR_CAST(SbObjModule,pActiveModule); |
| if ( pMod ) |
| refVar->PutObject( pMod ); |
| else |
| StarBASIC::Error( SbERR_INVALID_USAGE_OBJECT ); |
| } |
| else |
| refVar->PutObject( pClassModuleObject ); |
| } |
| |