2009-09-10 10:13:43 +0200 jsk r276023 : Test Cases for #i103691, #i103697, #i103990 2009-09-03 15:42:36 +0200 ab r275754 : #i103990# Removed warning 2009-09-03 09:02:32 +0200 ab r275744 : CWS-TOOLING: rebase CWS ab74 to trunk@275331 (milestone: DEV300:m56) 2009-09-02 17:14:42 +0200 ab r275724 : #i103697# Applied patch 2009-08-27 15:11:50 +0200 ab r275488 : #i103354# Check Lucene index file to be named _0.cfs, fail otherwise 2009-08-26 08:57:21 +0200 ab r275393 : #i104354# Changed loop variable type to avoid Solaris Intel compiler optimizer bug 2009-08-17 14:17:32 +0200 ab r275053 : #i73263# Adapted breakpoint dialog to longer strings 2009-08-13 17:09:30 +0200 ab r274951 : #i103691# Fix empty comparison behaviour 2009-08-13 13:03:28 +0200 ab r274935 : #i103948# Applied patch 2009-08-13 12:31:15 +0200 ab r274931 : #i103134# Patch: Always set default property 2009-08-13 11:02:50 +0200 ab r274926 : #i103990# Support arrays in user types 2009-07-21 11:16:54 +0200 ab r274171 : #i102816# Make sure LocaleItem is loaded before copying from it 2009-07-20 14:56:35 +0200 ab r274139 : #i102816# Use default language as final fallback in service implementation
2611 lines
64 KiB
C++
2611 lines
64 KiB
C++
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2008 by Sun Microsystems, Inc.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* $RCSfile: methods1.cxx,v $
|
|
* $Revision: 1.38 $
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
#include "precompiled_basic.hxx"
|
|
|
|
#if defined(WIN)
|
|
#include <string.h>
|
|
#else
|
|
#include <stdlib.h> // getenv
|
|
#endif
|
|
#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 <svtools/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
|
|
|
|
#if defined(WIN)
|
|
#include <tools/svwin.h>
|
|
#endif
|
|
|
|
#ifndef CLK_TCK
|
|
#define CLK_TCK CLOCKS_PER_SEC
|
|
#endif
|
|
|
|
#include <vcl/jobset.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(CBool) // JSM
|
|
{
|
|
(void)pBasic;
|
|
(void)bWrite;
|
|
|
|
BOOL bVal = 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;
|
|
|
|
BYTE 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;
|
|
|
|
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;
|
|
|
|
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=*/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;
|
|
|
|
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
|
|
{
|
|
ULONG nRGB = (ULONG)rPar.Get(1)->GetLong();
|
|
nRGB &= 0x00FF0000;
|
|
nRGB >>= 16;
|
|
rPar.Get(0)->PutInteger( (INT16)nRGB );
|
|
}
|
|
}
|
|
|
|
RTLFUNC(Green)
|
|
{
|
|
(void)pBasic;
|
|
(void)bWrite;
|
|
|
|
if ( rPar.Count() != 2 )
|
|
StarBASIC::Error( SbERR_BAD_ARGUMENT );
|
|
else
|
|
{
|
|
ULONG nRGB = (ULONG)rPar.Get(1)->GetLong();
|
|
nRGB &= 0x0000FF00;
|
|
nRGB >>= 8;
|
|
rPar.Get(0)->PutInteger( (INT16)nRGB );
|
|
}
|
|
}
|
|
|
|
RTLFUNC(Blue)
|
|
{
|
|
(void)pBasic;
|
|
(void)bWrite;
|
|
|
|
if ( rPar.Count() != 2 )
|
|
StarBASIC::Error( SbERR_BAD_ARGUMENT );
|
|
else
|
|
{
|
|
ULONG nRGB = (ULONG)rPar.Get(1)->GetLong();
|
|
nRGB &= 0x000000FF;
|
|
rPar.Get(0)->PutInteger( (INT16)nRGB );
|
|
}
|
|
}
|
|
|
|
|
|
RTLFUNC(Switch)
|
|
{
|
|
(void)pBasic;
|
|
(void)bWrite;
|
|
|
|
USHORT nCount = rPar.Count();
|
|
if( !(nCount & 0x0001 ))
|
|
// Anzahl der Argumente muss ungerade sein
|
|
StarBASIC::Error( SbERR_BAD_ARGUMENT );
|
|
USHORT 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(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 );
|
|
INT16 nIndex = rPar.Get(1)->GetInteger();
|
|
USHORT 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( (INT32)SUPD );
|
|
}
|
|
|
|
RTLFUNC(TwipsPerPixelX)
|
|
{
|
|
(void)pBasic;
|
|
(void)bWrite;
|
|
|
|
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;
|
|
|
|
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 );
|
|
ByteString aByteDLLName( rPar.Get(1)->GetString(), gsl_getSystemTextEncoding() );
|
|
pINST->GetDllMgr()->FreeDll( aByteDLLName );
|
|
}
|
|
bool IsBaseIndexOne()
|
|
{
|
|
bool result = false;
|
|
if ( pINST && pINST->pRun )
|
|
{
|
|
USHORT res = pINST->pRun->GetBase();
|
|
if ( res )
|
|
result = true;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
RTLFUNC(Array)
|
|
{
|
|
(void)pBasic;
|
|
(void)bWrite;
|
|
|
|
SbxDimArray* pArray = new SbxDimArray( SbxVARIANT );
|
|
USHORT 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 USHORT for loop variable is
|
|
// mandatory to workaround a problem with the
|
|
// Solaris Intel compiler optimizer! See i104354
|
|
for( USHORT 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);
|
|
USHORT 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 );
|
|
USHORT nArrayDims = rPar.Count() - 1;
|
|
if( nArrayDims > 0 )
|
|
{
|
|
for( USHORT i = 0; i < nArrayDims ; i++ )
|
|
{
|
|
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);
|
|
USHORT 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 );
|
|
}
|
|
|
|
|
|
|
|
BOOL lcl_WriteSbxVariable( const SbxVariable& rVar, SvStream* pStrm,
|
|
BOOL bBinary, short nBlockLen, BOOL bIsArray )
|
|
{
|
|
ULONG nFPos = pStrm->Tell();
|
|
|
|
BOOL bIsVariant = !rVar.IsFixed();
|
|
SbxDataType eType = rVar.GetType();
|
|
|
|
switch( eType )
|
|
{
|
|
case SbxBOOL:
|
|
case SbxCHAR:
|
|
case SbxBYTE:
|
|
if( bIsVariant )
|
|
*pStrm << (USHORT)SbxBYTE; // VarType Id
|
|
*pStrm << rVar.GetByte();
|
|
break;
|
|
|
|
case SbxEMPTY:
|
|
case SbxNULL:
|
|
case SbxVOID:
|
|
case SbxINTEGER:
|
|
case SbxUSHORT:
|
|
case SbxINT:
|
|
case SbxUINT:
|
|
if( bIsVariant )
|
|
*pStrm << (USHORT)SbxINTEGER; // VarType Id
|
|
*pStrm << rVar.GetInteger();
|
|
break;
|
|
|
|
case SbxLONG:
|
|
case SbxULONG:
|
|
case SbxLONG64:
|
|
case SbxULONG64:
|
|
if( bIsVariant )
|
|
*pStrm << (USHORT)SbxLONG; // VarType Id
|
|
*pStrm << rVar.GetLong();
|
|
break;
|
|
|
|
case SbxSINGLE:
|
|
if( bIsVariant )
|
|
*pStrm << (USHORT)eType; // VarType Id
|
|
*pStrm << rVar.GetSingle();
|
|
break;
|
|
|
|
case SbxDOUBLE:
|
|
case SbxCURRENCY:
|
|
case SbxDATE:
|
|
if( bIsVariant )
|
|
*pStrm << (USHORT)eType; // VarType Id
|
|
*pStrm << rVar.GetDouble();
|
|
break;
|
|
|
|
case SbxSTRING:
|
|
case SbxLPSTR:
|
|
{
|
|
const String& rStr = rVar.GetString();
|
|
if( !bBinary || bIsArray )
|
|
{
|
|
if( bIsVariant )
|
|
*pStrm << (USHORT)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 FALSE;
|
|
}
|
|
|
|
if( nBlockLen )
|
|
pStrm->Seek( nFPos + nBlockLen );
|
|
return pStrm->GetErrorCode() ? FALSE : TRUE;
|
|
}
|
|
|
|
BOOL lcl_ReadSbxVariable( SbxVariable& rVar, SvStream* pStrm,
|
|
BOOL bBinary, short nBlockLen, BOOL bIsArray )
|
|
{
|
|
(void)bBinary;
|
|
(void)bIsArray;
|
|
|
|
double aDouble;
|
|
|
|
ULONG nFPos = pStrm->Tell();
|
|
|
|
BOOL bIsVariant = !rVar.IsFixed();
|
|
SbxDataType eVarType = rVar.GetType();
|
|
|
|
SbxDataType eSrcType = eVarType;
|
|
if( bIsVariant )
|
|
{
|
|
USHORT nTemp;
|
|
*pStrm >> nTemp;
|
|
eSrcType = (SbxDataType)nTemp;
|
|
}
|
|
|
|
switch( eSrcType )
|
|
{
|
|
case SbxBOOL:
|
|
case SbxCHAR:
|
|
case SbxBYTE:
|
|
{
|
|
BYTE aByte;
|
|
*pStrm >> aByte;
|
|
rVar.PutByte( aByte );
|
|
}
|
|
break;
|
|
|
|
case SbxEMPTY:
|
|
case SbxNULL:
|
|
case SbxVOID:
|
|
case SbxINTEGER:
|
|
case SbxUSHORT:
|
|
case SbxINT:
|
|
case SbxUINT:
|
|
{
|
|
INT16 aInt;
|
|
*pStrm >> aInt;
|
|
rVar.PutInteger( aInt );
|
|
}
|
|
break;
|
|
|
|
case SbxLONG:
|
|
case SbxULONG:
|
|
case SbxLONG64:
|
|
case SbxULONG64:
|
|
{
|
|
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 FALSE;
|
|
}
|
|
|
|
if( nBlockLen )
|
|
pStrm->Seek( nFPos + nBlockLen );
|
|
return pStrm->GetErrorCode() ? FALSE : TRUE;
|
|
}
|
|
|
|
|
|
// nCurDim = 1...n
|
|
BOOL lcl_WriteReadSbxArray( SbxDimArray& rArr, SvStream* pStrm,
|
|
BOOL bBinary, short nCurDim, short* pOtherDims, BOOL bWrite )
|
|
{
|
|
DBG_ASSERT( nCurDim > 0,"Bad Dim");
|
|
short nLower, nUpper;
|
|
if( !rArr.GetDim( nCurDim, nLower, nUpper ) )
|
|
return 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 );
|
|
BOOL bRet;
|
|
if( bWrite )
|
|
bRet = lcl_WriteSbxVariable(*pVar, pStrm, bBinary, 0, TRUE );
|
|
else
|
|
bRet = lcl_ReadSbxVariable(*pVar, pStrm, bBinary, 0, TRUE );
|
|
if( !bRet )
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void PutGet( SbxArray& rPar, BOOL bPut )
|
|
{
|
|
// Wir brauchen 3 Parameter
|
|
if ( rPar.Count() != 4 )
|
|
{
|
|
StarBASIC::Error( SbERR_BAD_ARGUMENT );
|
|
return;
|
|
}
|
|
INT16 nFileNo = rPar.Get(1)->GetInteger();
|
|
SbxVariable* pVar2 = rPar.Get(2);
|
|
BOOL bHasRecordNo = (BOOL)(pVar2->GetType() != SbxEMPTY);
|
|
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();
|
|
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 )
|
|
{
|
|
ULONG nFilePos = bRandom ? (ULONG)(nBlockLen*nRecordNo) : (ULONG)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);
|
|
}
|
|
|
|
BOOL bRet;
|
|
|
|
if( pArr )
|
|
{
|
|
ULONG 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, FALSE);
|
|
else
|
|
bRet = lcl_ReadSbxVariable(*pVar, pStrm, !bRandom, nBlockLen, FALSE);
|
|
}
|
|
if( !bRet || pStrm->GetErrorCode() )
|
|
StarBASIC::Error( SbERR_IO_ERROR );
|
|
}
|
|
|
|
RTLFUNC(Put)
|
|
{
|
|
(void)pBasic;
|
|
(void)bWrite;
|
|
|
|
PutGet( rPar, TRUE );
|
|
}
|
|
|
|
RTLFUNC(Get)
|
|
{
|
|
(void)pBasic;
|
|
(void)bWrite;
|
|
|
|
PutGet( rPar, 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
|
|
#if defined(WIN)
|
|
LPSTR lpszEnv = GetDOSEnvironment();
|
|
String aCompareStr( rPar.Get(1)->GetString() );
|
|
aCompareStr += '=';
|
|
const char* pCompare = aCompareStr.GetStr();
|
|
int nCompareLen = aCompareStr.Len();
|
|
while ( *lpszEnv )
|
|
{
|
|
// Es werden alle EnvString in der Form ENV=VAL 0-terminiert
|
|
// aneinander gehaengt.
|
|
|
|
if ( strnicmp( pCompare, lpszEnv, nCompareLen ) == 0 )
|
|
{
|
|
aResult = (const char*)(lpszEnv+nCompareLen);
|
|
rPar.Get(0)->PutString( aResult );
|
|
return;
|
|
}
|
|
lpszEnv += lstrlen( lpszEnv ) + 1; // Next Enviroment-String
|
|
}
|
|
#else
|
|
ByteString aByteStr( rPar.Get(1)->GetString(), gsl_getSystemTextEncoding() );
|
|
const char* pEnvStr = getenv( aByteStr.GetBuffer() );
|
|
if ( pEnvStr )
|
|
aResult = String::CreateFromAscii( pEnvStr );
|
|
#endif
|
|
rPar.Get(0)->PutString( aResult );
|
|
}
|
|
|
|
static double GetDialogZoomFactor( BOOL bX, long nValue )
|
|
{
|
|
OutputDevice* pDevice = Application::GetDefaultDevice();
|
|
double nResult = 0;
|
|
if( pDevice )
|
|
{
|
|
Size aRefSize( nValue, nValue );
|
|
#ifndef WIN
|
|
Fraction aFracX( 1, 26 );
|
|
#else
|
|
Fraction aFracX( 1, 23 );
|
|
#endif
|
|
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( 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( 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();
|
|
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 = (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, 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.getLength() )
|
|
::osl::File::getFileURLFromSystemPath( aFileURL, aFileURL );
|
|
if( !aFileURL.getLength() )
|
|
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.getLength() )
|
|
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 );
|
|
}
|
|
|
|
|
|
RTLFUNC(Join)
|
|
{
|
|
(void)pBasic;
|
|
(void)bWrite;
|
|
|
|
USHORT 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 );
|
|
}
|
|
|
|
|
|
typedef ::std::vector< String > StringVector;
|
|
|
|
RTLFUNC(Split)
|
|
{
|
|
(void)pBasic;
|
|
(void)bWrite;
|
|
|
|
USHORT 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( " " );
|
|
|
|
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);
|
|
USHORT 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;
|
|
|
|
USHORT 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();
|
|
|
|
INT16 nVal = rPar.Get(1)->GetInteger();
|
|
if( nVal < 1 || nVal > nMonthCount )
|
|
{
|
|
StarBASIC::Error( SbERR_BAD_ARGUMENT );
|
|
return;
|
|
}
|
|
|
|
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;
|
|
|
|
USHORT 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();
|
|
INT16 nDayCount = (INT16)aDaySeq.getLength();
|
|
INT16 nDay = rPar.Get(1)->GetInteger();
|
|
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 = INT16( xCalendar->getFirstDayOfWeek() + 1 );
|
|
|
|
nDay = 1 + (nDay + nDayCount + nFirstDay - 2) % nDayCount;
|
|
if( nDay < 1 || nDay > nDayCount )
|
|
{
|
|
StarBASIC::Error( SbERR_BAD_ARGUMENT );
|
|
return;
|
|
}
|
|
|
|
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) );
|
|
}
|
|
|
|
INT16 implGetWeekDay( double aDate, bool bFirstDayParam = false, 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();
|
|
INT16 nDay;
|
|
if ( aDay != SUNDAY )
|
|
nDay = (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 = INT16( xCalendar->getFirstDayOfWeek() + 1 );
|
|
}
|
|
nDay = 1 + (nDay + 7 - nFirstDay) % 7;
|
|
}
|
|
return nDay;
|
|
}
|
|
|
|
RTLFUNC(Weekday)
|
|
{
|
|
(void)pBasic;
|
|
(void)bWrite;
|
|
|
|
USHORT nParCount = rPar.Count();
|
|
if ( nParCount < 2 )
|
|
StarBASIC::Error( SbERR_BAD_ARGUMENT );
|
|
else
|
|
{
|
|
double aDate = rPar.Get(1)->GetDate();
|
|
|
|
bool bFirstDay = false;
|
|
INT16 nFirstDay = 0;
|
|
if ( nParCount > 2 )
|
|
{
|
|
nFirstDay = rPar.Get(2)->GetInteger();
|
|
bFirstDay = true;
|
|
}
|
|
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;
|
|
INT16 i = 0;
|
|
while( (pInfo = pIntervalTable + i)->mpStringCode != NULL )
|
|
{
|
|
if( rStringCode.EqualsIgnoreCaseAscii( pInfo->mpStringCode ) )
|
|
break;
|
|
i++;
|
|
}
|
|
return pInfo;
|
|
}
|
|
|
|
// From methods.cxx
|
|
BOOL implDateSerial( INT16 nYear, INT16 nMonth, INT16 nDay, double& rdRet );
|
|
INT16 implGetDateDay( double aDate );
|
|
INT16 implGetDateMonth( double aDate );
|
|
INT16 implGetDateYear( double aDate );
|
|
|
|
INT16 implGetHour( double dDate );
|
|
INT16 implGetMinute( double dDate );
|
|
INT16 implGetSecond( double dDate );
|
|
|
|
|
|
inline void implGetDayMonthYear( INT16& rnYear, INT16& rnMonth, INT16& rnDay, double dDate )
|
|
{
|
|
rnDay = implGetDateDay( dDate );
|
|
rnMonth = implGetDateMonth( dDate );
|
|
rnYear = implGetDateYear( dDate );
|
|
}
|
|
|
|
inline INT16 limitToINT16( INT32 n32 )
|
|
{
|
|
if( n32 > 32767 )
|
|
n32 = 32767;
|
|
else if( n32 < -32768 )
|
|
n32 = -32768;
|
|
return (INT16)n32;
|
|
}
|
|
|
|
RTLFUNC(DateAdd)
|
|
{
|
|
(void)pBasic;
|
|
(void)bWrite;
|
|
|
|
USHORT 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;
|
|
}
|
|
|
|
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 );
|
|
|
|
BOOL bOk = TRUE;
|
|
INT16 nYear, nMonth, nDay;
|
|
INT16 nTargetYear16 = 0, nTargetMonth = 0;
|
|
implGetDayMonthYear( nYear, nMonth, nDay, dDate );
|
|
switch( pInfo->meInterval )
|
|
{
|
|
case INTERVAL_YYYY:
|
|
{
|
|
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;
|
|
INT32 nYearsAdd;
|
|
INT16 nMonthAdd;
|
|
if( pInfo->meInterval == INTERVAL_Q )
|
|
{
|
|
nYearsAdd = lNumber / 4;
|
|
nMonthAdd = (INT16)( 3 * (lNumber % 4) );
|
|
}
|
|
else
|
|
{
|
|
nYearsAdd = lNumber / 12;
|
|
nMonthAdd = (INT16)( lNumber % 12 );
|
|
}
|
|
|
|
INT32 nTargetYear;
|
|
if( bNeg )
|
|
{
|
|
nTargetMonth = nMonth - nMonthAdd;
|
|
if( nTargetMonth <= 0 )
|
|
{
|
|
nTargetMonth += 12;
|
|
nYearsAdd++;
|
|
}
|
|
nTargetYear = (INT32)nYear - nYearsAdd;
|
|
}
|
|
else
|
|
{
|
|
nTargetMonth = nMonth + nMonthAdd;
|
|
if( nTargetMonth > 12 )
|
|
{
|
|
nTargetMonth -= 12;
|
|
nYearsAdd++;
|
|
}
|
|
nTargetYear = (INT32)nYear + nYearsAdd;
|
|
}
|
|
nTargetYear16 = limitToINT16( nTargetYear );
|
|
bOk = implDateSerial( nTargetYear16, nTargetMonth, nDay, dNewDate );
|
|
break;
|
|
}
|
|
default: break;
|
|
}
|
|
|
|
if( bOk )
|
|
{
|
|
// Overflow?
|
|
INT16 nNewYear, nNewMonth, nNewDay;
|
|
implGetDayMonthYear( nNewYear, nNewMonth, nNewDay, dNewDate );
|
|
if( nNewYear > 9999 || nNewYear < 100 )
|
|
{
|
|
StarBASIC::Error( SbERR_BAD_ARGUMENT );
|
|
return;
|
|
}
|
|
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]])
|
|
|
|
USHORT 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:
|
|
{
|
|
INT16 nYear1 = implGetDateYear( dDate1 );
|
|
INT16 nYear2 = implGetDateYear( dDate2 );
|
|
dRet = nYear2 - nYear1;
|
|
break;
|
|
}
|
|
case INTERVAL_Q:
|
|
{
|
|
INT16 nYear1 = implGetDateYear( dDate1 );
|
|
INT16 nYear2 = implGetDateYear( dDate2 );
|
|
INT16 nQ1 = 1 + (implGetDateMonth( dDate1 ) - 1) / 3;
|
|
INT16 nQ2 = 1 + (implGetDateMonth( dDate2 ) - 1) / 3;
|
|
INT16 nQGes1 = 4 * nYear1 + nQ1;
|
|
INT16 nQGes2 = 4 * nYear2 + nQ2;
|
|
dRet = nQGes2 - nQGes1;
|
|
break;
|
|
}
|
|
case INTERVAL_M:
|
|
{
|
|
INT16 nYear1 = implGetDateYear( dDate1 );
|
|
INT16 nYear2 = implGetDateYear( dDate2 );
|
|
INT16 nMonth1 = implGetDateMonth( dDate1 );
|
|
INT16 nMonth2 = implGetDateMonth( dDate2 );
|
|
INT16 nMonthGes1 = 12 * nYear1 + nMonth1;
|
|
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 )
|
|
{
|
|
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 = INT16( xCalendar->getFirstDayOfWeek() + 1 );
|
|
}
|
|
}
|
|
INT16 nDay1 = implGetWeekDay( dDate1 );
|
|
INT16 nDay1_Diff = nDay1 - nFirstDay;
|
|
if( nDay1_Diff < 0 )
|
|
nDay1_Diff += 7;
|
|
dDays1 -= nDay1_Diff;
|
|
|
|
INT16 nDay2 = implGetWeekDay( dDate2 );
|
|
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
|
|
( INT16 nYear, INT16& nFirstDay, 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 = INT16( xCalendar->getFirstDayOfWeek() + 1 );
|
|
|
|
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;
|
|
|
|
INT16 nWeekDay0101 = implGetWeekDay( dBaseDate );
|
|
INT16 nDayDiff = nWeekDay0101 - nFirstDay;
|
|
if( nDayDiff < 0 )
|
|
nDayDiff += 7;
|
|
|
|
if( nFirstWeekMinDays )
|
|
{
|
|
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]])
|
|
|
|
USHORT 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();
|
|
|
|
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:
|
|
{
|
|
INT16 nYear = implGetDateYear( dDate );
|
|
double dBaseDate;
|
|
implDateSerial( nYear, 1, 1, dBaseDate );
|
|
nRet = 1 + INT32( dDate - dBaseDate );
|
|
break;
|
|
}
|
|
case INTERVAL_D:
|
|
{
|
|
nRet = implGetDateDay( dDate );
|
|
break;
|
|
}
|
|
case INTERVAL_W:
|
|
{
|
|
bool bFirstDay = false;
|
|
INT16 nFirstDay = 1; // Default
|
|
if( nParCount >= 4 )
|
|
{
|
|
nFirstDay = rPar.Get(3)->GetInteger();
|
|
bFirstDay = true;
|
|
}
|
|
nRet = implGetWeekDay( dDate, bFirstDay, nFirstDay );
|
|
break;
|
|
}
|
|
case INTERVAL_WW:
|
|
{
|
|
INT16 nFirstDay = 1; // Default
|
|
if( nParCount >= 4 )
|
|
nFirstDay = rPar.Get(3)->GetInteger();
|
|
|
|
INT16 nFirstWeek = 1; // Default
|
|
if( nParCount == 5 )
|
|
nFirstWeek = rPar.Get(4)->GetInteger();
|
|
|
|
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 + 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;
|
|
|
|
USHORT nParCount = rPar.Count();
|
|
if( nParCount < 2 || nParCount > 3 )
|
|
{
|
|
StarBASIC::Error( SbERR_BAD_ARGUMENT );
|
|
return;
|
|
}
|
|
|
|
double dDate = rPar.Get(1)->GetDate();
|
|
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();
|
|
ULONG 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;
|
|
|
|
USHORT 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;
|
|
}
|
|
|
|
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;
|
|
USHORT 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;
|
|
}
|
|
|
|
USHORT nByteCount = rPar.Get(1)->GetUShort();
|
|
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);
|
|
if( pClassModuleObject == NULL )
|
|
{
|
|
StarBASIC::Error( SbERR_INVALID_USAGE_OBJECT );
|
|
}
|
|
else
|
|
{
|
|
SbxVariableRef refVar = rPar.Get(0);
|
|
refVar->PutObject( pClassModuleObject );
|
|
}
|
|
}
|
|
|