| /************************************************************** |
| * |
| * 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 <tools/date.hxx> |
| #include <basic/sbxvar.hxx> |
| #include <vos/process.hxx> |
| #include <vcl/svapp.hxx> |
| #include <vcl/settings.hxx> |
| #include <vcl/sound.hxx> |
| #include <tools/wintypes.hxx> |
| #include <vcl/msgbox.hxx> |
| #include <basic/sbx.hxx> |
| #include <svl/zforlist.hxx> |
| #include <rtl/math.hxx> |
| #include <tools/urlobj.hxx> |
| #include <osl/time.h> |
| #include <unotools/charclass.hxx> |
| #include <unotools/ucbstreamhelper.hxx> |
| #include <tools/wldcrd.hxx> |
| #include <i18npool/lang.h> |
| #include <vcl/dibtools.hxx> |
| |
| #include "runtime.hxx" |
| #include "sbunoobj.hxx" |
| #ifdef WNT |
| #include <tools/prewin.h> |
| #include "winbase.h" |
| #include <tools/postwin.h> |
| #ifndef _FSYS_HXX //autogen |
| #include <tools/fsys.hxx> |
| #endif |
| #else |
| #include <osl/file.hxx> |
| #endif |
| #include "errobject.hxx" |
| |
| #ifdef _USE_UNO |
| #include <comphelper/processfactory.hxx> |
| |
| #include <com/sun/star/uno/Sequence.hxx> |
| #include <com/sun/star/util/DateTime.hpp> |
| #include <com/sun/star/lang/XMultiServiceFactory.hpp> |
| #include <com/sun/star/lang/Locale.hpp> |
| #include <com/sun/star/ucb/XSimpleFileAccess3.hpp> |
| #include <com/sun/star/io/XInputStream.hpp> |
| #include <com/sun/star/io/XOutputStream.hpp> |
| #include <com/sun/star/io/XStream.hpp> |
| #include <com/sun/star/io/XSeekable.hpp> |
| |
| using namespace comphelper; |
| using namespace osl; |
| using namespace com::sun::star::uno; |
| using namespace com::sun::star::lang; |
| using namespace com::sun::star::ucb; |
| using namespace com::sun::star::io; |
| using namespace com::sun::star::frame; |
| |
| #endif /* _USE_UNO */ |
| |
| //#define _ENABLE_CUR_DIR |
| |
| #include "stdobj.hxx" |
| #include <basic/sbstdobj.hxx> |
| #include "rtlproto.hxx" |
| #include "basrid.hxx" |
| #include "image.hxx" |
| #include "sb.hrc" |
| #include "iosys.hxx" |
| #include "ddectrl.hxx" |
| #include <sbintern.hxx> |
| #include <basic/vbahelper.hxx> |
| |
| #include <list> |
| #include <math.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <ctype.h> |
| |
| #if defined (WNT) || defined (OS2) |
| #include <direct.h> // _getdcwd get current work directory, _chdrive |
| #endif |
| |
| #ifdef UNX |
| #include <errno.h> |
| #include <unistd.h> |
| #endif |
| |
| #ifdef WNT |
| #include <io.h> |
| #endif |
| |
| #include <basic/sbobjmod.hxx> |
| |
| // from source/classes/sbxmod.cxx |
| Reference< XModel > getDocumentModel( StarBASIC* ); |
| |
| static void FilterWhiteSpace( String& rStr ) |
| { |
| rStr.EraseAllChars( ' ' ); |
| rStr.EraseAllChars( '\t' ); |
| rStr.EraseAllChars( '\n' ); |
| rStr.EraseAllChars( '\r' ); |
| } |
| |
| static long GetDayDiff( const Date& rDate ) |
| { |
| Date aRefDate( 1,1,1900 ); |
| long nDiffDays; |
| if ( aRefDate > rDate ) |
| { |
| nDiffDays = (long)(aRefDate - rDate); |
| nDiffDays *= -1; |
| } |
| else |
| nDiffDays = (long)(rDate - aRefDate); |
| nDiffDays += 2; // Anpassung VisualBasic: 1.Jan.1900 == 2 |
| return nDiffDays; |
| } |
| |
| static CharClass& GetCharClass( void ) |
| { |
| static sal_Bool bNeedsInit = sal_True; |
| static ::com::sun::star::lang::Locale aLocale; |
| if( bNeedsInit ) |
| { |
| bNeedsInit = sal_False; |
| aLocale = Application::GetSettings().GetLocale(); |
| } |
| static CharClass aCharClass( aLocale ); |
| return aCharClass; |
| } |
| |
| static inline sal_Bool isFolder( FileStatus::Type aType ) |
| { |
| return ( aType == FileStatus::Directory || aType == FileStatus::Volume ); |
| } |
| |
| |
| //*** UCB file access *** |
| |
| // Converts possibly relative paths to absolute paths |
| // according to the setting done by ChDir/ChDrive |
| String getFullPath( const String& aRelPath ) |
| { |
| ::rtl::OUString aFileURL; |
| |
| // #80204 Try first if it already is a valid URL |
| INetURLObject aURLObj( aRelPath ); |
| aFileURL = aURLObj.GetMainURL( INetURLObject::NO_DECODE ); |
| |
| if( aFileURL.isEmpty() ) |
| { |
| File::getFileURLFromSystemPath( aRelPath, aFileURL ); |
| } |
| |
| return aFileURL; |
| } |
| |
| // Sets (virtual) current path for UCB file access |
| void implChDir( const String& aDir ) |
| { |
| (void)aDir; |
| // TODO |
| } |
| |
| // Sets (virtual) current drive for UCB file access |
| void implChDrive( const String& aDrive ) |
| { |
| (void)aDrive; |
| // TODO |
| } |
| |
| // Returns (virtual) current path for UCB file access |
| String implGetCurDir( void ) |
| { |
| String aRetStr; |
| |
| return aRetStr; |
| } |
| |
| // TODO: -> SbiGlobals |
| static com::sun::star::uno::Reference< XSimpleFileAccess3 > getFileAccess( void ) |
| { |
| static com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI; |
| if( !xSFI.is() ) |
| { |
| com::sun::star::uno::Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory(); |
| if( xSMgr.is() ) |
| { |
| xSFI = com::sun::star::uno::Reference< XSimpleFileAccess3 >( xSMgr->createInstance |
| ( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY ); |
| } |
| } |
| return xSFI; |
| } |
| |
| |
| |
| // Properties und Methoden legen beim Get (bPut = sal_False) den Returnwert |
| // im Element 0 des Argv ab; beim Put (bPut = sal_True) wird der Wert aus |
| // Element 0 gespeichert. |
| |
| // CreateObject( class ) |
| |
| RTLFUNC(CreateObject) |
| { |
| (void)bWrite; |
| |
| String aClass( rPar.Get( 1 )->GetString() ); |
| SbxObjectRef p = SbxBase::CreateObject( aClass ); |
| if( !p ) |
| StarBASIC::Error( SbERR_CANNOT_LOAD ); |
| else |
| { |
| // Convenience: BASIC als Parent eintragen |
| p->SetParent( pBasic ); |
| rPar.Get( 0 )->PutObject( p ); |
| } |
| } |
| |
| // Error( n ) |
| |
| RTLFUNC(Error) |
| { |
| (void)bWrite; |
| |
| if( !pBasic ) |
| StarBASIC::Error( SbERR_INTERNAL_ERROR ); |
| else |
| { |
| String aErrorMsg; |
| SbError nErr = 0L; |
| sal_Int32 nCode = 0; |
| if( rPar.Count() == 1 ) |
| { |
| nErr = StarBASIC::GetErrBasic(); |
| aErrorMsg = StarBASIC::GetErrorMsg(); |
| } |
| else |
| { |
| nCode = rPar.Get( 1 )->GetLong(); |
| if( nCode > 65535L ) |
| StarBASIC::Error( SbERR_CONVERSION ); |
| else |
| nErr = StarBASIC::GetSfxFromVBError( (sal_uInt16)nCode ); |
| } |
| |
| bool bVBA = SbiRuntime::isVBAEnabled(); |
| String tmpErrMsg; |
| if( bVBA && aErrorMsg.Len() > 0 ) |
| { |
| tmpErrMsg = aErrorMsg; |
| } |
| else |
| { |
| pBasic->MakeErrorText( nErr, aErrorMsg ); |
| tmpErrMsg = pBasic->GetErrorText(); |
| } |
| // If this rtlfunc 'Error' passed a errcode the same as the active Err Objects's |
| // current err then return the description for the error message if it is set |
| // ( complicated isn't it ? ) |
| if ( bVBA && rPar.Count() > 1 ) |
| { |
| com::sun::star::uno::Reference< ooo::vba::XErrObject > xErrObj( SbxErrObject::getUnoErrObject() ); |
| if ( xErrObj.is() && xErrObj->getNumber() == nCode && !xErrObj->getDescription().isEmpty() ) |
| tmpErrMsg = xErrObj->getDescription(); |
| } |
| rPar.Get( 0 )->PutString( tmpErrMsg ); |
| } |
| } |
| |
| // Sinus |
| |
| RTLFUNC(Sin) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| SbxVariableRef pArg = rPar.Get( 1 ); |
| rPar.Get( 0 )->PutDouble( sin( pArg->GetDouble() ) ); |
| } |
| } |
| |
| // Cosinus |
| |
| RTLFUNC(Cos) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| SbxVariableRef pArg = rPar.Get( 1 ); |
| rPar.Get( 0 )->PutDouble( cos( pArg->GetDouble() ) ); |
| } |
| } |
| |
| // Atn |
| |
| RTLFUNC(Atn) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| SbxVariableRef pArg = rPar.Get( 1 ); |
| rPar.Get( 0 )->PutDouble( atan( pArg->GetDouble() ) ); |
| } |
| } |
| |
| |
| |
| RTLFUNC(Abs) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| SbxVariableRef pArg = rPar.Get( 1 ); |
| rPar.Get( 0 )->PutDouble( fabs( pArg->GetDouble() ) ); |
| } |
| } |
| |
| |
| RTLFUNC(Asc) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| SbxVariableRef pArg = rPar.Get( 1 ); |
| String aStr( pArg->GetString() ); |
| if ( aStr.Len() == 0 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| rPar.Get(0)->PutEmpty(); |
| } |
| else |
| { |
| sal_Unicode aCh = aStr.GetBuffer()[0]; |
| rPar.Get(0)->PutLong( aCh ); |
| } |
| } |
| } |
| |
| void implChr( SbxArray& rPar, bool bChrW ) |
| { |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| SbxVariableRef pArg = rPar.Get( 1 ); |
| |
| String aStr; |
| if( !bChrW && SbiRuntime::isVBAEnabled() ) |
| { |
| sal_Char c = (sal_Char)pArg->GetByte(); |
| ByteString s( c ); |
| aStr = String( s, gsl_getSystemTextEncoding() ); |
| } |
| else |
| { |
| sal_Unicode aCh = (sal_Unicode)pArg->GetUShort(); |
| aStr = String( aCh ); |
| } |
| rPar.Get(0)->PutString( aStr ); |
| } |
| } |
| |
| RTLFUNC(Chr) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| bool bChrW = false; |
| implChr( rPar, bChrW ); |
| } |
| |
| RTLFUNC(ChrW) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| bool bChrW = true; |
| implChr( rPar, bChrW ); |
| } |
| |
| |
| #ifdef UNX |
| #define _MAX_PATH 260 |
| #define _PATH_INCR 250 |
| #endif |
| |
| RTLFUNC(CurDir) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| // #57064 Obwohl diese Funktion nicht mit DirEntry arbeitet, ist sie von |
| // der Anpassung an virtuelle URLs nich betroffen, da bei Nutzung der |
| // DirEntry-Funktionalitaet keine Moeglichkeit besteht, das aktuelle so |
| // zu ermitteln, dass eine virtuelle URL geliefert werden koennte. |
| |
| // rPar.Get(0)->PutEmpty(); |
| #if defined (WNT) || defined (OS2) |
| int nCurDir = 0; // Current dir // JSM |
| if ( rPar.Count() == 2 ) |
| { |
| String aDrive = rPar.Get(1)->GetString(); |
| if ( aDrive.Len() != 1 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| else |
| { |
| nCurDir = (int)aDrive.GetBuffer()[0]; |
| if ( !isalpha( nCurDir ) ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| else |
| nCurDir -= ( 'A' - 1 ); |
| } |
| } |
| char* pBuffer = new char[ _MAX_PATH ]; |
| #ifdef OS2 |
| if( !nCurDir ) |
| nCurDir = _getdrive(); |
| #endif |
| if ( _getdcwd( nCurDir, pBuffer, _MAX_PATH ) != 0 ) |
| rPar.Get(0)->PutString( String::CreateFromAscii( pBuffer ) ); |
| else |
| StarBASIC::Error( SbERR_NO_DEVICE ); |
| delete [] pBuffer; |
| |
| #elif defined( UNX ) |
| |
| int nSize = _PATH_INCR; |
| char* pMem; |
| while( sal_True ) |
| { |
| pMem = new char[nSize]; |
| if( !pMem ) |
| { |
| StarBASIC::Error( SbERR_NO_MEMORY ); |
| return; |
| } |
| if( getcwd( pMem, nSize-1 ) != NULL ) |
| { |
| rPar.Get(0)->PutString( String::CreateFromAscii(pMem) ); |
| delete [] pMem; |
| return; |
| } |
| if( errno != ERANGE ) |
| { |
| StarBASIC::Error( SbERR_INTERNAL_ERROR ); |
| delete [] pMem; |
| return; |
| } |
| delete [] pMem; |
| nSize += _PATH_INCR; |
| }; |
| |
| #endif |
| } |
| |
| RTLFUNC(ChDir) // JSM |
| { |
| (void)bWrite; |
| |
| rPar.Get(0)->PutEmpty(); |
| if (rPar.Count() == 2) |
| { |
| #ifdef _ENABLE_CUR_DIR |
| String aPath = rPar.Get(1)->GetString(); |
| sal_Bool bError = sal_False; |
| #ifdef WNT |
| // #55997 Laut MI hilft es bei File-URLs einen DirEntry zwischenzuschalten |
| // #40996 Harmoniert bei Verwendung der WIN32-Funktion nicht mit getdir |
| DirEntry aEntry( aPath ); |
| ByteString aFullPath( aEntry.GetFull(), gsl_getSystemTextEncoding() ); |
| if( chdir( aFullPath.GetBuffer()) ) |
| bError = sal_True; |
| #else |
| if (!DirEntry(aPath).SetCWD()) |
| bError = sal_True; |
| #endif |
| if( bError ) |
| StarBASIC::Error( SbERR_PATH_NOT_FOUND ); |
| #endif |
| // VBA: track current directory per document type (separately for Writer, Calc, Impress, etc.) |
| if( SbiRuntime::isVBAEnabled() ) |
| ::basic::vba::registerCurrentDirectory( getDocumentModel( pBasic ), rPar.Get(1)->GetString() ); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| |
| RTLFUNC(ChDrive) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| rPar.Get(0)->PutEmpty(); |
| if (rPar.Count() == 2) |
| { |
| #ifdef _ENABLE_CUR_DIR |
| // Keine Laufwerke in Unix |
| #ifndef UNX |
| String aPar1 = rPar.Get(1)->GetString(); |
| |
| #if defined (WNT) || defined (OS2) |
| if (aPar1.Len() > 0) |
| { |
| int nCurDrive = (int)aPar1.GetBuffer()[0]; ; |
| if ( !isalpha( nCurDrive ) ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| else |
| nCurDrive -= ( 'A' - 1 ); |
| if (_chdrive(nCurDrive)) |
| StarBASIC::Error( SbERR_NO_DEVICE ); |
| } |
| #endif |
| |
| #endif |
| // #ifndef UNX |
| #endif |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| |
| |
| // Implementation of StepRENAME with UCB |
| void implStepRenameUCB( const String& aSource, const String& aDest ) |
| { |
| com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); |
| if( xSFI.is() ) |
| { |
| try |
| { |
| String aSourceFullPath = getFullPath( aSource ); |
| if( !xSFI->exists( aSourceFullPath ) ) |
| { |
| StarBASIC::Error( SbERR_FILE_NOT_FOUND ); |
| return; |
| } |
| |
| String aDestFullPath = getFullPath( aDest ); |
| if( xSFI->exists( aDestFullPath ) ) |
| StarBASIC::Error( SbERR_FILE_EXISTS ); |
| else |
| xSFI->move( aSourceFullPath, aDestFullPath ); |
| } |
| catch( Exception & ) |
| { |
| StarBASIC::Error( SbERR_FILE_NOT_FOUND ); |
| } |
| } |
| } |
| |
| // Implementation of StepRENAME with OSL |
| void implStepRenameOSL( const String& aSource, const String& aDest ) |
| { |
| FileBase::RC nRet = File::move( getFullPathUNC( aSource ), getFullPathUNC( aDest ) ); |
| if( nRet != FileBase::E_None ) |
| { |
| StarBASIC::Error( SbERR_PATH_NOT_FOUND ); |
| } |
| } |
| |
| RTLFUNC(FileCopy) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| rPar.Get(0)->PutEmpty(); |
| if (rPar.Count() == 3) |
| { |
| String aSource = rPar.Get(1)->GetString(); |
| String aDest = rPar.Get(2)->GetString(); |
| // <-- UCB |
| if( hasUno() ) |
| { |
| com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); |
| if( xSFI.is() ) |
| { |
| try |
| { |
| xSFI->copy( getFullPath( aSource ), getFullPath( aDest ) ); |
| } |
| catch( Exception & ) |
| { |
| StarBASIC::Error( SbERR_PATH_NOT_FOUND ); |
| } |
| } |
| } |
| else |
| // --> UCB |
| { |
| #ifdef _OLD_FILE_IMPL |
| DirEntry aSourceDirEntry(aSource); |
| if (aSourceDirEntry.Exists()) |
| { |
| if (aSourceDirEntry.CopyTo(DirEntry(aDest),FSYS_ACTION_COPYFILE) != FSYS_ERR_OK) |
| StarBASIC::Error( SbERR_PATH_NOT_FOUND ); |
| } |
| else |
| StarBASIC::Error( SbERR_PATH_NOT_FOUND ); |
| #else |
| FileBase::RC nRet = File::copy( getFullPathUNC( aSource ), getFullPathUNC( aDest ) ); |
| if( nRet != FileBase::E_None ) |
| { |
| StarBASIC::Error( SbERR_PATH_NOT_FOUND ); |
| } |
| #endif |
| } |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| |
| RTLFUNC(Kill) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| rPar.Get(0)->PutEmpty(); |
| if (rPar.Count() == 2) |
| { |
| String aFileSpec = rPar.Get(1)->GetString(); |
| |
| // <-- UCB |
| if( hasUno() ) |
| { |
| com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); |
| if( xSFI.is() ) |
| { |
| String aFullPath = getFullPath( aFileSpec ); |
| if( !xSFI->exists( aFullPath ) || xSFI->isFolder( aFullPath ) ) |
| { |
| StarBASIC::Error( SbERR_FILE_NOT_FOUND ); |
| return; |
| } |
| try |
| { |
| xSFI->kill( aFullPath ); |
| } |
| catch( Exception & ) |
| { |
| StarBASIC::Error( ERRCODE_IO_GENERAL ); |
| } |
| } |
| } |
| else |
| // --> UCB |
| { |
| #ifdef _OLD_FILE_IMPL |
| if(DirEntry(aFileSpec).Kill() != FSYS_ERR_OK) |
| StarBASIC::Error( SbERR_PATH_NOT_FOUND ); |
| #else |
| File::remove( getFullPathUNC( aFileSpec ) ); |
| #endif |
| } |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| |
| RTLFUNC(MkDir) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| rPar.Get(0)->PutEmpty(); |
| if (rPar.Count() == 2) |
| { |
| String aPath = rPar.Get(1)->GetString(); |
| |
| // <-- UCB |
| if( hasUno() ) |
| { |
| com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); |
| if( xSFI.is() ) |
| { |
| try |
| { |
| xSFI->createFolder( getFullPath( aPath ) ); |
| } |
| catch( Exception & ) |
| { |
| StarBASIC::Error( ERRCODE_IO_GENERAL ); |
| } |
| } |
| } |
| else |
| // --> UCB |
| { |
| #ifdef _OLD_FILE_IMPL |
| if (!DirEntry(aPath).MakeDir()) |
| StarBASIC::Error( SbERR_PATH_NOT_FOUND ); |
| #else |
| Directory::create( getFullPathUNC( aPath ) ); |
| #endif |
| } |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| |
| |
| #ifndef _OLD_FILE_IMPL |
| |
| // In OSL only empty directories can be deleted |
| // so we have to delete all files recursively |
| void implRemoveDirRecursive( const String& aDirPath ) |
| { |
| DirectoryItem aItem; |
| FileBase::RC nRet = DirectoryItem::get( aDirPath, aItem ); |
| sal_Bool bExists = (nRet == FileBase::E_None); |
| |
| FileStatus aFileStatus( FileStatusMask_Type ); |
| nRet = aItem.getFileStatus( aFileStatus ); |
| FileStatus::Type aType = aFileStatus.getFileType(); |
| sal_Bool bFolder = isFolder( aType ); |
| |
| if( !bExists || !bFolder ) |
| { |
| StarBASIC::Error( SbERR_PATH_NOT_FOUND ); |
| return; |
| } |
| |
| Directory aDir( aDirPath ); |
| nRet = aDir.open(); |
| if( nRet != FileBase::E_None ) |
| { |
| StarBASIC::Error( SbERR_PATH_NOT_FOUND ); |
| return; |
| } |
| |
| for( ;; ) |
| { |
| DirectoryItem aItem2; |
| nRet = aDir.getNextItem( aItem2 ); |
| if( nRet != FileBase::E_None ) |
| break; |
| |
| // Handle flags |
| FileStatus aFileStatus2( FileStatusMask_Type | FileStatusMask_FileURL ); |
| nRet = aItem2.getFileStatus( aFileStatus2 ); |
| ::rtl::OUString aPath = aFileStatus2.getFileURL(); |
| |
| // Directory? |
| FileStatus::Type aType2 = aFileStatus2.getFileType(); |
| sal_Bool bFolder2 = isFolder( aType2 ); |
| if( bFolder2 ) |
| { |
| implRemoveDirRecursive( aPath ); |
| } |
| else |
| { |
| File::remove( aPath ); |
| } |
| } |
| nRet = aDir.close(); |
| |
| nRet = Directory::remove( aDirPath ); |
| } |
| #endif |
| |
| |
| RTLFUNC(RmDir) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| rPar.Get(0)->PutEmpty(); |
| if (rPar.Count() == 2) |
| { |
| String aPath = rPar.Get(1)->GetString(); |
| // <-- UCB |
| if( hasUno() ) |
| { |
| com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); |
| if( xSFI.is() ) |
| { |
| try |
| { |
| if( !xSFI->isFolder( aPath ) ) |
| { |
| StarBASIC::Error( SbERR_PATH_NOT_FOUND ); |
| return; |
| } |
| SbiInstance* pInst = pINST; |
| bool bCompatibility = ( pInst && pInst->IsCompatibility() ); |
| if( bCompatibility ) |
| { |
| Sequence< ::rtl::OUString > aContent = xSFI->getFolderContents( aPath, true ); |
| sal_Int32 nCount = aContent.getLength(); |
| if( nCount > 0 ) |
| { |
| StarBASIC::Error( SbERR_ACCESS_ERROR ); |
| return; |
| } |
| } |
| |
| xSFI->kill( getFullPath( aPath ) ); |
| } |
| catch( Exception & ) |
| { |
| StarBASIC::Error( ERRCODE_IO_GENERAL ); |
| } |
| } |
| } |
| else |
| // --> UCB |
| { |
| #ifdef _OLD_FILE_IMPL |
| DirEntry aDirEntry(aPath); |
| if (aDirEntry.Kill() != FSYS_ERR_OK) |
| StarBASIC::Error( SbERR_PATH_NOT_FOUND ); |
| #else |
| implRemoveDirRecursive( getFullPathUNC( aPath ) ); |
| #endif |
| } |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| |
| RTLFUNC(SendKeys) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| rPar.Get(0)->PutEmpty(); |
| StarBASIC::Error(SbERR_NOT_IMPLEMENTED); |
| } |
| |
| RTLFUNC(Exp) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| double aDouble = rPar.Get( 1 )->GetDouble(); |
| aDouble = exp( aDouble ); |
| checkArithmeticOverflow( aDouble ); |
| rPar.Get( 0 )->PutDouble( aDouble ); |
| } |
| } |
| |
| RTLFUNC(FileLen) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| SbxVariableRef pArg = rPar.Get( 1 ); |
| String aStr( pArg->GetString() ); |
| sal_Int32 nLen = 0; |
| // <-- UCB |
| if( hasUno() ) |
| { |
| com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); |
| if( xSFI.is() ) |
| { |
| try |
| { |
| nLen = xSFI->getSize( getFullPath( aStr ) ); |
| } |
| catch( Exception & ) |
| { |
| StarBASIC::Error( ERRCODE_IO_GENERAL ); |
| } |
| } |
| } |
| else |
| // --> UCB |
| { |
| #ifdef _OLD_FILE_IMPL |
| FileStat aStat = DirEntry( aStr ); |
| nLen = aStat.GetSize(); |
| #else |
| DirectoryItem aItem; |
| FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( aStr ), aItem ); |
| FileStatus aFileStatus( FileStatusMask_FileSize ); |
| nRet = aItem.getFileStatus( aFileStatus ); |
| nLen = (sal_Int32)aFileStatus.getFileSize(); |
| #endif |
| } |
| rPar.Get(0)->PutLong( (long)nLen ); |
| } |
| } |
| |
| |
| RTLFUNC(Hex) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| char aBuffer[16]; |
| SbxVariableRef pArg = rPar.Get( 1 ); |
| if ( pArg->IsInteger() ) |
| snprintf( aBuffer, sizeof(aBuffer), "%X", pArg->GetInteger() ); |
| else |
| snprintf( aBuffer, sizeof(aBuffer), "%lX", static_cast<long unsigned int>(pArg->GetLong()) ); |
| rPar.Get(0)->PutString( String::CreateFromAscii( aBuffer ) ); |
| } |
| } |
| |
| // InStr( [start],string,string,[compare] ) |
| |
| RTLFUNC(InStr) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_uIntPtr nArgCount = rPar.Count()-1; |
| if ( nArgCount < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| sal_uInt16 nStartPos = 1; |
| |
| sal_uInt16 nFirstStringPos = 1; |
| if ( nArgCount >= 3 ) |
| { |
| sal_Int32 lStartPos = rPar.Get(1)->GetLong(); |
| if( lStartPos <= 0 || lStartPos > 0xffff ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| lStartPos = 1; |
| } |
| nStartPos = (sal_uInt16)lStartPos; |
| nFirstStringPos++; |
| } |
| |
| SbiInstance* pInst = pINST; |
| int bTextMode; |
| bool bCompatibility = ( pInst && pInst->IsCompatibility() ); |
| if( bCompatibility ) |
| { |
| SbiRuntime* pRT = pInst ? pInst->pRun : NULL; |
| bTextMode = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : sal_False; |
| } |
| else |
| { |
| bTextMode = 1;; |
| } |
| if ( nArgCount == 4 ) |
| bTextMode = rPar.Get(4)->GetInteger(); |
| |
| sal_uInt16 nPos; |
| const String& rToken = rPar.Get(nFirstStringPos+1)->GetString(); |
| |
| // #97545 Always find empty string |
| if( !rToken.Len() ) |
| { |
| nPos = nStartPos; |
| } |
| else |
| { |
| if( !bTextMode ) |
| { |
| const String& rStr1 = rPar.Get(nFirstStringPos)->GetString(); |
| |
| nPos = rStr1.Search( rToken, nStartPos-1 ); |
| if ( nPos == STRING_NOTFOUND ) |
| nPos = 0; |
| else |
| nPos++; |
| } |
| else |
| { |
| String aStr1 = rPar.Get(nFirstStringPos)->GetString(); |
| String aToken = rToken; |
| |
| aStr1.ToUpperAscii(); |
| aToken.ToUpperAscii(); |
| |
| nPos = aStr1.Search( aToken, nStartPos-1 ); |
| if ( nPos == STRING_NOTFOUND ) |
| nPos = 0; |
| else |
| nPos++; |
| } |
| } |
| rPar.Get(0)->PutLong( nPos ); |
| } |
| } |
| |
| |
| // InstrRev(string1, string2[, start[, compare]]) |
| |
| RTLFUNC(InStrRev) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_uIntPtr nArgCount = rPar.Count()-1; |
| if ( nArgCount < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| String aStr1 = rPar.Get(1)->GetString(); |
| String aToken = rPar.Get(2)->GetString(); |
| |
| sal_Int32 lStartPos = -1; |
| if ( nArgCount >= 3 ) |
| { |
| lStartPos = rPar.Get(3)->GetLong(); |
| if( (lStartPos <= 0 && lStartPos != -1) || lStartPos > 0xffff ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| lStartPos = -1; |
| } |
| } |
| |
| SbiInstance* pInst = pINST; |
| int bTextMode; |
| bool bCompatibility = ( pInst && pInst->IsCompatibility() ); |
| if( bCompatibility ) |
| { |
| SbiRuntime* pRT = pInst ? pInst->pRun : NULL; |
| bTextMode = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : sal_False; |
| } |
| else |
| { |
| bTextMode = 1;; |
| } |
| if ( nArgCount == 4 ) |
| bTextMode = rPar.Get(4)->GetInteger(); |
| |
| sal_uInt16 nStrLen = aStr1.Len(); |
| sal_uInt16 nStartPos = lStartPos == -1 ? nStrLen : (sal_uInt16)lStartPos; |
| |
| sal_uInt16 nPos = 0; |
| if( nStartPos <= nStrLen ) |
| { |
| sal_uInt16 nTokenLen = aToken.Len(); |
| if( !nTokenLen ) |
| { |
| // Always find empty string |
| nPos = nStartPos; |
| } |
| else if( nStrLen > 0 ) |
| { |
| if( !bTextMode ) |
| { |
| ::rtl::OUString aOUStr1 ( aStr1 ); |
| ::rtl::OUString aOUToken( aToken ); |
| sal_Int32 nRet = aOUStr1.lastIndexOf( aOUToken, nStartPos ); |
| if( nRet == -1 ) |
| nPos = 0; |
| else |
| nPos = (sal_uInt16)nRet + 1; |
| } |
| else |
| { |
| aStr1.ToUpperAscii(); |
| aToken.ToUpperAscii(); |
| |
| ::rtl::OUString aOUStr1 ( aStr1 ); |
| ::rtl::OUString aOUToken( aToken ); |
| sal_Int32 nRet = aOUStr1.lastIndexOf( aOUToken, nStartPos ); |
| |
| if( nRet == -1 ) |
| nPos = 0; |
| else |
| nPos = (sal_uInt16)nRet + 1; |
| } |
| } |
| } |
| rPar.Get(0)->PutLong( nPos ); |
| } |
| } |
| |
| |
| /* |
| Int( 2.8 ) = 2.0 |
| Int( -2.8 ) = -3.0 |
| Fix( 2.8 ) = 2.0 |
| Fix( -2.8 ) = -2.0 <- !! |
| */ |
| |
| RTLFUNC(Int) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| SbxVariableRef pArg = rPar.Get( 1 ); |
| double aDouble= pArg->GetDouble(); |
| /* |
| floor( 2.8 ) = 2.0 |
| floor( -2.8 ) = -3.0 |
| */ |
| aDouble = floor( aDouble ); |
| rPar.Get(0)->PutDouble( aDouble ); |
| } |
| } |
| |
| |
| |
| RTLFUNC(Fix) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| SbxVariableRef pArg = rPar.Get( 1 ); |
| double aDouble = pArg->GetDouble(); |
| if ( aDouble >= 0.0 ) |
| aDouble = floor( aDouble ); |
| else |
| aDouble = ceil( aDouble ); |
| rPar.Get(0)->PutDouble( aDouble ); |
| } |
| } |
| |
| |
| RTLFUNC(LCase) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| CharClass& rCharClass = GetCharClass(); |
| String aStr( rPar.Get(1)->GetString() ); |
| rCharClass.toLower( aStr ); |
| rPar.Get(0)->PutString( aStr ); |
| } |
| } |
| |
| RTLFUNC(Left) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 3 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| String aStr( rPar.Get(1)->GetString() ); |
| sal_Int32 lResultLen = rPar.Get(2)->GetLong(); |
| if( lResultLen > 0xffff ) |
| { |
| lResultLen = 0xffff; |
| } |
| else if( lResultLen < 0 ) |
| { |
| lResultLen = 0; |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| aStr.Erase( (sal_uInt16)lResultLen ); |
| rPar.Get(0)->PutString( aStr ); |
| } |
| } |
| |
| RTLFUNC(Log) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| double aArg = rPar.Get(1)->GetDouble(); |
| if ( aArg > 0 ) |
| { |
| double d = log( aArg ); |
| checkArithmeticOverflow( d ); |
| rPar.Get( 0 )->PutDouble( d ); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| } |
| |
| RTLFUNC(LTrim) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| String aStr( rPar.Get(1)->GetString() ); |
| aStr.EraseLeadingChars(); |
| rPar.Get(0)->PutString( aStr ); |
| } |
| } |
| |
| |
| // Mid( String, nStart, nLength ) |
| |
| RTLFUNC(Mid) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_uIntPtr nArgCount = rPar.Count()-1; |
| if ( nArgCount < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| // #23178: Funktionalitaet von Mid$ als Anweisung nachbilden, indem |
| // als weiterer (4.) Parameter ein Ersetzungsstring aufgenommen wird. |
| // Anders als im Original kann in dieser Variante der 3. Parameter |
| // nLength nicht weggelassen werden. Ist ueber bWrite schon vorgesehen. |
| if( nArgCount == 4 ) |
| bWrite = sal_True; |
| |
| String aArgStr = rPar.Get(1)->GetString(); |
| sal_uInt16 nStartPos = (sal_uInt16)(rPar.Get(2)->GetLong() ); |
| if ( nStartPos == 0 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| nStartPos--; |
| sal_uInt16 nLen = 0xffff; |
| bool bWriteNoLenParam = false; |
| if ( nArgCount == 3 || bWrite ) |
| { |
| sal_Int32 n = rPar.Get(3)->GetLong(); |
| if( bWrite && n == -1 ) |
| bWriteNoLenParam = true; |
| nLen = (sal_uInt16)n; |
| } |
| String aResultStr; |
| if ( bWrite ) |
| { |
| SbiInstance* pInst = pINST; |
| bool bCompatibility = ( pInst && pInst->IsCompatibility() ); |
| if( bCompatibility ) |
| { |
| sal_uInt16 nArgLen = aArgStr.Len(); |
| if( nStartPos + 1 > nArgLen ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| String aReplaceStr = rPar.Get(4)->GetString(); |
| sal_uInt16 nReplaceStrLen = aReplaceStr.Len(); |
| sal_uInt16 nReplaceLen; |
| if( bWriteNoLenParam ) |
| { |
| nReplaceLen = nReplaceStrLen; |
| } |
| else |
| { |
| nReplaceLen = nLen; |
| if( nReplaceLen > nReplaceStrLen ) |
| nReplaceLen = nReplaceStrLen; |
| } |
| |
| sal_uInt16 nReplaceEndPos = nStartPos + nReplaceLen; |
| if( nReplaceEndPos > nArgLen ) |
| nReplaceLen -= (nReplaceEndPos - nArgLen); |
| |
| aResultStr = aArgStr; |
| sal_uInt16 nErase = nReplaceLen; |
| aResultStr.Erase( nStartPos, nErase ); |
| aResultStr.Insert( aReplaceStr, 0, nReplaceLen, nStartPos ); |
| } |
| else |
| { |
| aResultStr = aArgStr; |
| aResultStr.Erase( nStartPos, nLen ); |
| aResultStr.Insert(rPar.Get(4)->GetString(),0,nLen,nStartPos); |
| } |
| |
| rPar.Get(1)->PutString( aResultStr ); |
| } |
| else |
| { |
| aResultStr = aArgStr.Copy( nStartPos, nLen ); |
| rPar.Get(0)->PutString( aResultStr ); |
| } |
| } |
| } |
| } |
| |
| RTLFUNC(Oct) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| char aBuffer[16]; |
| SbxVariableRef pArg = rPar.Get( 1 ); |
| if ( pArg->IsInteger() ) |
| snprintf( aBuffer, sizeof(aBuffer), "%o", pArg->GetInteger() ); |
| else |
| snprintf( aBuffer, sizeof(aBuffer), "%lo", static_cast<long unsigned int>(pArg->GetLong()) ); |
| rPar.Get(0)->PutString( String::CreateFromAscii( aBuffer ) ); |
| } |
| } |
| |
| // Replace(expression, find, replace[, start[, count[, compare]]]) |
| |
| RTLFUNC(Replace) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_uIntPtr nArgCount = rPar.Count()-1; |
| if ( nArgCount < 3 || nArgCount > 6 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| String aExpStr = rPar.Get(1)->GetString(); |
| String aFindStr = rPar.Get(2)->GetString(); |
| String aReplaceStr = rPar.Get(3)->GetString(); |
| |
| sal_Int32 lStartPos = 1; |
| if ( nArgCount >= 4 ) |
| { |
| if( rPar.Get(4)->GetType() != SbxEMPTY ) |
| lStartPos = rPar.Get(4)->GetLong(); |
| if( lStartPos < 1 || lStartPos > 0xffff ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| lStartPos = 1; |
| } |
| } |
| |
| sal_Int32 lCount = -1; |
| if( nArgCount >=5 ) |
| { |
| if( rPar.Get(5)->GetType() != SbxEMPTY ) |
| lCount = rPar.Get(5)->GetLong(); |
| if( lCount < -1 || lCount > 0xffff ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| lCount = -1; |
| } |
| } |
| |
| SbiInstance* pInst = pINST; |
| int bTextMode; |
| bool bCompatibility = ( pInst && pInst->IsCompatibility() ); |
| if( bCompatibility ) |
| { |
| SbiRuntime* pRT = pInst ? pInst->pRun : NULL; |
| bTextMode = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : sal_False; |
| } |
| else |
| { |
| bTextMode = 1; |
| } |
| if ( nArgCount == 6 ) |
| bTextMode = rPar.Get(6)->GetInteger(); |
| |
| sal_uInt16 nExpStrLen = aExpStr.Len(); |
| sal_uInt16 nFindStrLen = aFindStr.Len(); |
| sal_uInt16 nReplaceStrLen = aReplaceStr.Len(); |
| |
| if( lStartPos <= nExpStrLen ) |
| { |
| sal_uInt16 nPos = static_cast<sal_uInt16>( lStartPos - 1 ); |
| sal_uInt16 nCounts = 0; |
| while( lCount == -1 || lCount > nCounts ) |
| { |
| String aSrcStr( aExpStr ); |
| if( bTextMode ) |
| { |
| aSrcStr.ToUpperAscii(); |
| aFindStr.ToUpperAscii(); |
| } |
| nPos = aSrcStr.Search( aFindStr, nPos ); |
| if( nPos != STRING_NOTFOUND ) |
| { |
| aExpStr.Replace( nPos, nFindStrLen, aReplaceStr ); |
| nPos = nPos - nFindStrLen + nReplaceStrLen + 1; |
| nCounts++; |
| } |
| else |
| { |
| break; |
| } |
| } |
| } |
| rPar.Get(0)->PutString( aExpStr.Copy( static_cast<sal_uInt16>(lStartPos - 1) ) ); |
| } |
| } |
| |
| RTLFUNC(Right) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 3 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| const String& rStr = rPar.Get(1)->GetString(); |
| sal_Int32 lResultLen = rPar.Get(2)->GetLong(); |
| if( lResultLen > 0xffff ) |
| { |
| lResultLen = 0xffff; |
| } |
| else if( lResultLen < 0 ) |
| { |
| lResultLen = 0; |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| sal_uInt16 nResultLen = (sal_uInt16)lResultLen; |
| sal_uInt16 nStrLen = rStr.Len(); |
| if ( nResultLen > nStrLen ) |
| nResultLen = nStrLen; |
| String aResultStr = rStr.Copy( nStrLen-nResultLen ); |
| rPar.Get(0)->PutString( aResultStr ); |
| } |
| } |
| |
| RTLFUNC(RTL) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| rPar.Get( 0 )->PutObject( pBasic->getRTL() ); |
| } |
| |
| RTLFUNC(RTrim) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| String aStr( rPar.Get(1)->GetString() ); |
| aStr.EraseTrailingChars(); |
| rPar.Get(0)->PutString( aStr ); |
| } |
| } |
| |
| RTLFUNC(Sgn) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| double aDouble = rPar.Get(1)->GetDouble(); |
| sal_Int16 nResult = 0; |
| if ( aDouble > 0 ) |
| nResult = 1; |
| else if ( aDouble < 0 ) |
| nResult = -1; |
| rPar.Get(0)->PutInteger( nResult ); |
| } |
| } |
| |
| RTLFUNC(Space) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| String aStr; |
| aStr.Fill( (sal_uInt16)(rPar.Get(1)->GetLong() )); |
| rPar.Get(0)->PutString( aStr ); |
| } |
| } |
| |
| RTLFUNC(Spc) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| String aStr; |
| aStr.Fill( (sal_uInt16)(rPar.Get(1)->GetLong() )); |
| rPar.Get(0)->PutString( aStr ); |
| } |
| } |
| |
| RTLFUNC(Sqr) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| double aDouble = rPar.Get(1)->GetDouble(); |
| if ( aDouble >= 0 ) |
| rPar.Get(0)->PutDouble( sqrt( aDouble )); |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| } |
| |
| RTLFUNC(Str) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| String aStr; |
| SbxVariableRef pArg = rPar.Get( 1 ); |
| pArg->Format( aStr ); |
| |
| // Numbers start with a space |
| if( pArg->IsNumericRTL() ) |
| { |
| // Kommas durch Punkte ersetzen, damit es symmetrisch zu Val ist! |
| aStr.SearchAndReplace( ',', '.' ); |
| |
| SbiInstance* pInst = pINST; |
| bool bCompatibility = ( pInst && pInst->IsCompatibility() ); |
| if( bCompatibility ) |
| { |
| xub_StrLen nLen = aStr.Len(); |
| |
| const sal_Unicode* pBuf = aStr.GetBuffer(); |
| |
| bool bNeg = ( pBuf[0] == '-' ); |
| sal_uInt16 iZeroSearch = 0; |
| if( bNeg ) |
| iZeroSearch++; |
| |
| sal_uInt16 iNext = iZeroSearch + 1; |
| if( pBuf[iZeroSearch] == '0' && nLen > iNext && pBuf[iNext] == '.' ) |
| { |
| aStr.Erase( iZeroSearch, 1 ); |
| pBuf = aStr.GetBuffer(); |
| } |
| if( !bNeg ) |
| aStr.Insert( ' ', 0 ); |
| } |
| else |
| aStr.Insert( ' ', 0 ); |
| } |
| rPar.Get(0)->PutString( aStr ); |
| } |
| } |
| |
| RTLFUNC(StrComp) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 3 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| rPar.Get(0)->PutEmpty(); |
| return; |
| } |
| const String& rStr1 = rPar.Get(1)->GetString(); |
| const String& rStr2 = rPar.Get(2)->GetString(); |
| |
| SbiInstance* pInst = pINST; |
| sal_Int16 nTextCompare; |
| bool bCompatibility = ( pInst && pInst->IsCompatibility() ); |
| if( bCompatibility ) |
| { |
| SbiRuntime* pRT = pInst ? pInst->pRun : NULL; |
| nTextCompare = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : sal_False; |
| } |
| else |
| { |
| nTextCompare = sal_True; |
| } |
| if ( rPar.Count() == 4 ) |
| nTextCompare = rPar.Get(3)->GetInteger(); |
| |
| if( !bCompatibility ) |
| nTextCompare = !nTextCompare; |
| |
| StringCompare aResult; |
| sal_Int32 nRetValue = 0; |
| if( nTextCompare ) |
| { |
| ::utl::TransliterationWrapper* pTransliterationWrapper = GetSbData()->pTransliterationWrapper; |
| if( !pTransliterationWrapper ) |
| { |
| com::sun::star::uno::Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory(); |
| pTransliterationWrapper = GetSbData()->pTransliterationWrapper = |
| new ::utl::TransliterationWrapper( xSMgr, |
| ::com::sun::star::i18n::TransliterationModules_IGNORE_CASE | |
| ::com::sun::star::i18n::TransliterationModules_IGNORE_KANA | |
| ::com::sun::star::i18n::TransliterationModules_IGNORE_WIDTH ); |
| } |
| |
| LanguageType eLangType = GetpApp()->GetSettings().GetLanguage(); |
| pTransliterationWrapper->loadModuleIfNeeded( eLangType ); |
| nRetValue = pTransliterationWrapper->compareString( rStr1, rStr2 ); |
| } |
| else |
| { |
| aResult = rStr1.CompareTo( rStr2 ); |
| if ( aResult == COMPARE_LESS ) |
| nRetValue = -1; |
| else if ( aResult == COMPARE_GREATER ) |
| nRetValue = 1; |
| } |
| |
| rPar.Get(0)->PutInteger( sal::static_int_cast< sal_Int16 >( nRetValue ) ); |
| } |
| |
| RTLFUNC(String) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| String aStr; |
| sal_Unicode aFiller; |
| sal_Int32 lCount = rPar.Get(1)->GetLong(); |
| if( lCount < 0 || lCount > 0xffff ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| sal_uInt16 nCount = (sal_uInt16)lCount; |
| if( rPar.Get(2)->GetType() == SbxINTEGER ) |
| aFiller = (sal_Unicode)rPar.Get(2)->GetInteger(); |
| else |
| { |
| const String& rStr = rPar.Get(2)->GetString(); |
| aFiller = rStr.GetBuffer()[0]; |
| } |
| aStr.Fill( nCount, aFiller ); |
| rPar.Get(0)->PutString( aStr ); |
| } |
| } |
| |
| RTLFUNC(Tan) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| SbxVariableRef pArg = rPar.Get( 1 ); |
| rPar.Get( 0 )->PutDouble( tan( pArg->GetDouble() ) ); |
| } |
| } |
| |
| RTLFUNC(UCase) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| CharClass& rCharClass = GetCharClass(); |
| String aStr( rPar.Get(1)->GetString() ); |
| rCharClass.toUpper( aStr ); |
| rPar.Get(0)->PutString( aStr ); |
| } |
| } |
| |
| |
| RTLFUNC(Val) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| double nResult = 0.0; |
| char* pEndPtr; |
| |
| String aStr( rPar.Get(1)->GetString() ); |
| // lt. Mikkysoft bei Kommas abbrechen! |
| // for( sal_uInt16 n=0; n < aStr.Len(); n++ ) |
| // if( aStr[n] == ',' ) aStr[n] = '.'; |
| |
| FilterWhiteSpace( aStr ); |
| if ( aStr.GetBuffer()[0] == '&' && aStr.Len() > 1 ) |
| { |
| int nRadix = 10; |
| char aChar = (char)aStr.GetBuffer()[1]; |
| if ( aChar == 'h' || aChar == 'H' ) |
| nRadix = 16; |
| else if ( aChar == 'o' || aChar == 'O' ) |
| nRadix = 8; |
| if ( nRadix != 10 ) |
| { |
| ByteString aByteStr( aStr, gsl_getSystemTextEncoding() ); |
| sal_Int16 nlResult = (sal_Int16)strtol( aByteStr.GetBuffer()+2, &pEndPtr, nRadix); |
| nResult = (double)nlResult; |
| } |
| } |
| else |
| { |
| // #57844 Lokalisierte Funktion benutzen |
| nResult = ::rtl::math::stringToDouble( aStr, '.', ',', NULL, NULL ); |
| checkArithmeticOverflow( nResult ); |
| // ATL: nResult = strtod( aStr.GetStr(), &pEndPtr ); |
| } |
| |
| rPar.Get(0)->PutDouble( nResult ); |
| } |
| } |
| |
| |
| // Helper functions for date conversion |
| sal_Int16 implGetDateDay( double aDate ) |
| { |
| aDate -= 2.0; // normieren: 1.1.1900 => 0.0 |
| Date aRefDate( 1, 1, 1900 ); |
| if ( aDate >= 0.0 ) |
| { |
| aDate = floor( aDate ); |
| aRefDate += (sal_uIntPtr)aDate; |
| } |
| else |
| { |
| aDate = ceil( aDate ); |
| aRefDate -= (sal_uIntPtr)(-1.0 * aDate); |
| } |
| |
| sal_Int16 nRet = (sal_Int16)( aRefDate.GetDay() ); |
| return nRet; |
| } |
| |
| sal_Int16 implGetDateMonth( double aDate ) |
| { |
| Date aRefDate( 1,1,1900 ); |
| long nDays = (long)aDate; |
| nDays -= 2; // normieren: 1.1.1900 => 0.0 |
| aRefDate += nDays; |
| sal_Int16 nRet = (sal_Int16)( aRefDate.GetMonth() ); |
| return nRet; |
| } |
| |
| sal_Int16 implGetDateYear( double aDate ) |
| { |
| Date aRefDate( 1,1,1900 ); |
| long nDays = (long) aDate; |
| nDays -= 2; // normieren: 1.1.1900 => 0.0 |
| aRefDate += nDays; |
| sal_Int16 nRet = (sal_Int16)( aRefDate.GetYear() ); |
| return nRet; |
| } |
| |
| sal_Bool implDateSerial( sal_Int16 nYear, sal_Int16 nMonth, sal_Int16 nDay, double& rdRet ) |
| { |
| if ( nYear < 30 && SbiRuntime::isVBAEnabled() ) |
| nYear += 2000; |
| else if ( nYear < 100 ) |
| nYear += 1900; |
| Date aCurDate( nDay, nMonth, nYear ); |
| if ((nYear < 100 || nYear > 9999) ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return sal_False; |
| } |
| if ( !SbiRuntime::isVBAEnabled() ) |
| { |
| if ( (nMonth < 1 || nMonth > 12 )|| |
| (nDay < 1 || nDay > 31 ) ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return sal_False; |
| } |
| } |
| else |
| { |
| // grab the year & month |
| aCurDate = Date( 1, (( nMonth % 12 ) > 0 ) ? ( nMonth % 12 ) : 12 + ( nMonth % 12 ), nYear ); |
| |
| // adjust year based on month value |
| // e.g. 2000, 0, xx = 1999, 12, xx ( or December of the previous year ) |
| // 2000, 13, xx = 2001, 1, xx ( or January of the following year ) |
| if( ( nMonth < 1 ) || ( nMonth > 12 ) ) |
| { |
| // inacurrate around leap year, don't use days to calculate, |
| // just modify the months directory |
| sal_Int16 nYearAdj = ( nMonth /12 ); // default to positive months inputed |
| if ( nMonth <=0 ) |
| nYearAdj = ( ( nMonth -12 ) / 12 ); |
| aCurDate.SetYear( aCurDate.GetYear() + nYearAdj ); |
| } |
| |
| // adjust day value, |
| // e.g. 2000, 2, 0 = 2000, 1, 31 or the last day of the previous month |
| // 2000, 1, 32 = 2000, 2, 1 or the first day of the following month |
| if( ( nDay < 1 ) || ( nDay > aCurDate.GetDaysInMonth() ) ) |
| aCurDate += nDay - 1; |
| else |
| aCurDate.SetDay( nDay ); |
| } |
| |
| long nDiffDays = GetDayDiff( aCurDate ); |
| rdRet = (double)nDiffDays; |
| return sal_True; |
| } |
| |
| // Function to convert date to ISO 8601 date format |
| RTLFUNC(CDateToIso) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() == 2 ) |
| { |
| double aDate = rPar.Get(1)->GetDate(); |
| |
| char Buffer[9]; |
| snprintf( Buffer, sizeof( Buffer ), "%04d%02d%02d", |
| implGetDateYear( aDate ), |
| implGetDateMonth( aDate ), |
| implGetDateDay( aDate ) ); |
| String aRetStr = String::CreateFromAscii( Buffer ); |
| rPar.Get(0)->PutString( aRetStr ); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| |
| // Function to convert date from ISO 8601 date format |
| RTLFUNC(CDateFromIso) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() == 2 ) |
| { |
| String aStr = rPar.Get(1)->GetString(); |
| sal_Int16 iMonthStart = aStr.Len() - 4; |
| String aYearStr = aStr.Copy( 0, iMonthStart ); |
| String aMonthStr = aStr.Copy( iMonthStart, 2 ); |
| String aDayStr = aStr.Copy( iMonthStart+2, 2 ); |
| |
| double dDate; |
| if( implDateSerial( (sal_Int16)aYearStr.ToInt32(), |
| (sal_Int16)aMonthStr.ToInt32(), (sal_Int16)aDayStr.ToInt32(), dDate ) ) |
| { |
| rPar.Get(0)->PutDate( dDate ); |
| } |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| |
| RTLFUNC(DateSerial) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 4 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| sal_Int16 nYear = rPar.Get(1)->GetInteger(); |
| sal_Int16 nMonth = rPar.Get(2)->GetInteger(); |
| sal_Int16 nDay = rPar.Get(3)->GetInteger(); |
| |
| double dDate; |
| if( implDateSerial( nYear, nMonth, nDay, dDate ) ) |
| rPar.Get(0)->PutDate( dDate ); |
| } |
| |
| RTLFUNC(TimeSerial) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 4 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| sal_Int16 nHour = rPar.Get(1)->GetInteger(); |
| if ( nHour == 24 ) |
| nHour = 0; // Wegen UNO DateTimes, die bis 24 Uhr gehen |
| sal_Int16 nMinute = rPar.Get(2)->GetInteger(); |
| sal_Int16 nSecond = rPar.Get(3)->GetInteger(); |
| if ((nHour < 0 || nHour > 23) || |
| (nMinute < 0 || nMinute > 59 ) || |
| (nSecond < 0 || nSecond > 59 )) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| sal_Int32 nSeconds = nHour; |
| nSeconds *= 3600; |
| nSeconds += nMinute * 60; |
| nSeconds += nSecond; |
| double nDays = ((double)nSeconds) / (double)(86400.0); |
| rPar.Get(0)->PutDate( nDays ); // JSM |
| } |
| |
| RTLFUNC(DateValue) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden |
| SvNumberFormatter* pFormatter = NULL; |
| if( pINST ) |
| pFormatter = pINST->GetNumberFormatter(); |
| else |
| { |
| sal_uInt32 n; // Dummy |
| SbiInstance::PrepareNumberFormatter( pFormatter, n, n, n ); |
| } |
| |
| sal_uInt32 nIndex; |
| double fResult; |
| String aStr( rPar.Get(1)->GetString() ); |
| sal_Bool bSuccess = pFormatter->IsNumberFormat( aStr, nIndex, fResult ); |
| short nType = pFormatter->GetType( nIndex ); |
| |
| // DateValue("February 12, 1969") raises error if the system locale is not en_US |
| // by using SbiInstance::GetNumberFormatter. |
| // It seems that both locale number formatter and English number formatter |
| // are supported in Visual Basic. |
| LanguageType eLangType = GetpApp()->GetSettings().GetLanguage(); |
| if( !bSuccess && ( eLangType != LANGUAGE_ENGLISH_US ) ) |
| { |
| // Create a new SvNumberFormatter by using LANGUAGE_ENGLISH to get the date value; |
| com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > |
| xFactory = comphelper::getProcessServiceFactory(); |
| SvNumberFormatter aFormatter( xFactory, LANGUAGE_ENGLISH_US ); |
| bSuccess = aFormatter.IsNumberFormat( aStr, nIndex, fResult ); |
| nType = aFormatter.GetType( nIndex ); |
| } |
| |
| if(bSuccess && (nType==NUMBERFORMAT_DATE || nType==NUMBERFORMAT_DATETIME)) |
| { |
| if ( nType == NUMBERFORMAT_DATETIME ) |
| { |
| // Zeit abschneiden |
| if ( fResult > 0.0 ) |
| fResult = floor( fResult ); |
| else |
| fResult = ceil( fResult ); |
| } |
| // fResult += 2.0; // Anpassung StarCalcFormatter |
| rPar.Get(0)->PutDate( fResult ); // JSM |
| } |
| else |
| StarBASIC::Error( SbERR_CONVERSION ); |
| |
| // #39629 pFormatter kann selbst angefordert sein |
| if( !pINST ) |
| delete pFormatter; |
| } |
| } |
| |
| RTLFUNC(TimeValue) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden |
| SvNumberFormatter* pFormatter = NULL; |
| if( pINST ) |
| pFormatter = pINST->GetNumberFormatter(); |
| else |
| { |
| sal_uInt32 n; // Dummy |
| SbiInstance::PrepareNumberFormatter( pFormatter, n, n, n ); |
| } |
| |
| sal_uInt32 nIndex; |
| double fResult; |
| sal_Bool bSuccess = pFormatter->IsNumberFormat( rPar.Get(1)->GetString(), |
| nIndex, fResult ); |
| short nType = pFormatter->GetType(nIndex); |
| if(bSuccess && (nType==NUMBERFORMAT_TIME||nType==NUMBERFORMAT_DATETIME)) |
| { |
| if ( nType == NUMBERFORMAT_DATETIME ) |
| // Tage abschneiden |
| fResult = fmod( fResult, 1 ); |
| rPar.Get(0)->PutDate( fResult ); // JSM |
| } |
| else |
| StarBASIC::Error( SbERR_CONVERSION ); |
| |
| // #39629 pFormatter kann selbst angefordert sein |
| if( !pINST ) |
| delete pFormatter; |
| } |
| } |
| |
| RTLFUNC(Day) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| SbxVariableRef pArg = rPar.Get( 1 ); |
| double aDate = pArg->GetDate(); |
| |
| sal_Int16 nDay = implGetDateDay( aDate ); |
| rPar.Get(0)->PutInteger( nDay ); |
| } |
| } |
| |
| RTLFUNC(Year) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| sal_Int16 nYear = implGetDateYear( rPar.Get(1)->GetDate() ); |
| rPar.Get(0)->PutInteger( nYear ); |
| } |
| } |
| |
| sal_Int16 implGetHour( double dDate ) |
| { |
| if( dDate < 0.0 ) |
| dDate *= -1.0; |
| double nFrac = dDate - floor( dDate ); |
| nFrac *= 86400.0; |
| sal_Int32 nSeconds = (sal_Int32)(nFrac + 0.5); |
| sal_Int16 nHour = (sal_Int16)(nSeconds / 3600); |
| return nHour; |
| } |
| |
| RTLFUNC(Hour) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| double nArg = rPar.Get(1)->GetDate(); |
| sal_Int16 nHour = implGetHour( nArg ); |
| rPar.Get(0)->PutInteger( nHour ); |
| } |
| } |
| |
| sal_Int16 implGetMinute( double dDate ) |
| { |
| if( dDate < 0.0 ) |
| dDate *= -1.0; |
| double nFrac = dDate - floor( dDate ); |
| nFrac *= 86400.0; |
| sal_Int32 nSeconds = (sal_Int32)(nFrac + 0.5); |
| sal_Int16 nTemp = (sal_Int16)(nSeconds % 3600); |
| sal_Int16 nMin = nTemp / 60; |
| return nMin; |
| } |
| |
| RTLFUNC(Minute) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| double nArg = rPar.Get(1)->GetDate(); |
| sal_Int16 nMin = implGetMinute( nArg ); |
| rPar.Get(0)->PutInteger( nMin ); |
| } |
| } |
| |
| RTLFUNC(Month) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| sal_Int16 nMonth = implGetDateMonth( rPar.Get(1)->GetDate() ); |
| rPar.Get(0)->PutInteger( nMonth ); |
| } |
| } |
| |
| sal_Int16 implGetSecond( double dDate ) |
| { |
| if( dDate < 0.0 ) |
| dDate *= -1.0; |
| double nFrac = dDate - floor( dDate ); |
| nFrac *= 86400.0; |
| sal_Int32 nSeconds = (sal_Int32)(nFrac + 0.5); |
| sal_Int16 nTemp = (sal_Int16)(nSeconds / 3600); |
| nSeconds -= nTemp * 3600; |
| nTemp = (sal_Int16)(nSeconds / 60); |
| nSeconds -= nTemp * 60; |
| |
| sal_Int16 nRet = (sal_Int16)nSeconds; |
| return nRet; |
| } |
| |
| RTLFUNC(Second) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| double nArg = rPar.Get(1)->GetDate(); |
| sal_Int16 nSecond = implGetSecond( nArg ); |
| rPar.Get(0)->PutInteger( nSecond ); |
| } |
| } |
| |
| double Now_Impl() |
| { |
| Date aDate; |
| Time aTime; |
| double aSerial = (double)GetDayDiff( aDate ); |
| long nSeconds = aTime.GetHour(); |
| nSeconds *= 3600; |
| nSeconds += aTime.GetMin() * 60; |
| nSeconds += aTime.GetSec(); |
| double nDays = ((double)nSeconds) / (double)(24.0*3600.0); |
| aSerial += nDays; |
| return aSerial; |
| } |
| |
| // Date Now(void) |
| |
| RTLFUNC(Now) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| rPar.Get(0)->PutDate( Now_Impl() ); |
| } |
| |
| // Date Time(void) |
| |
| RTLFUNC(Time) |
| { |
| (void)pBasic; |
| |
| if ( !bWrite ) |
| { |
| Time aTime; |
| SbxVariable* pMeth = rPar.Get( 0 ); |
| String aRes; |
| if( pMeth->IsFixed() ) |
| { |
| // Time$: hh:mm:ss |
| char buf[ 20 ]; |
| snprintf( buf, sizeof(buf), "%02d:%02d:%02d", |
| aTime.GetHour(), aTime.GetMin(), aTime.GetSec() ); |
| aRes = String::CreateFromAscii( buf ); |
| } |
| else |
| { |
| // Time: system dependent |
| long nSeconds=aTime.GetHour(); |
| nSeconds *= 3600; |
| nSeconds += aTime.GetMin() * 60; |
| nSeconds += aTime.GetSec(); |
| double nDays = (double)nSeconds * ( 1.0 / (24.0*3600.0) ); |
| Color* pCol; |
| |
| // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden |
| SvNumberFormatter* pFormatter = NULL; |
| sal_uInt32 nIndex; |
| if( pINST ) |
| { |
| pFormatter = pINST->GetNumberFormatter(); |
| nIndex = pINST->GetStdTimeIdx(); |
| } |
| else |
| { |
| sal_uInt32 n; // Dummy |
| SbiInstance::PrepareNumberFormatter( pFormatter, n, nIndex, n ); |
| } |
| |
| pFormatter->GetOutputString( nDays, nIndex, aRes, &pCol ); |
| |
| // #39629 pFormatter kann selbst angefordert sein |
| if( !pINST ) |
| delete pFormatter; |
| } |
| pMeth->PutString( aRes ); |
| } |
| else |
| { |
| StarBASIC::Error( SbERR_NOT_IMPLEMENTED ); |
| } |
| } |
| |
| RTLFUNC(Timer) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| Time aTime; |
| long nSeconds = aTime.GetHour(); |
| nSeconds *= 3600; |
| nSeconds += aTime.GetMin() * 60; |
| nSeconds += aTime.GetSec(); |
| rPar.Get(0)->PutDate( (double)nSeconds ); |
| } |
| |
| |
| RTLFUNC(Date) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( !bWrite ) |
| { |
| Date aToday; |
| double nDays = (double)GetDayDiff( aToday ); |
| SbxVariable* pMeth = rPar.Get( 0 ); |
| if( pMeth->IsString() ) |
| { |
| String aRes; |
| Color* pCol; |
| |
| // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden |
| SvNumberFormatter* pFormatter = NULL; |
| sal_uInt32 nIndex; |
| if( pINST ) |
| { |
| pFormatter = pINST->GetNumberFormatter(); |
| nIndex = pINST->GetStdDateIdx(); |
| } |
| else |
| { |
| sal_uInt32 n; // Dummy |
| SbiInstance::PrepareNumberFormatter( pFormatter, nIndex, n, n ); |
| } |
| |
| pFormatter->GetOutputString( nDays, nIndex, aRes, &pCol ); |
| pMeth->PutString( aRes ); |
| |
| // #39629 pFormatter kann selbst angefordert sein |
| if( !pINST ) |
| delete pFormatter; |
| } |
| else |
| pMeth->PutDate( nDays ); |
| } |
| else |
| { |
| StarBASIC::Error( SbERR_NOT_IMPLEMENTED ); |
| } |
| } |
| |
| RTLFUNC(IsArray) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| rPar.Get(0)->PutBool((rPar.Get(1)->GetType() & SbxARRAY) ? sal_True : sal_False ); |
| } |
| |
| RTLFUNC(IsObject) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| SbxVariable* pVar = rPar.Get(1); |
| SbxBase* pObj = (SbxBase*)pVar->GetObject(); |
| |
| // #100385: GetObject can result in an error, so reset it |
| SbxBase::ResetError(); |
| |
| SbUnoClass* pUnoClass; |
| sal_Bool bObject; |
| if( pObj && NULL != ( pUnoClass=PTR_CAST(SbUnoClass,pObj) ) ) |
| { |
| bObject = pUnoClass->getUnoClass().is(); |
| } |
| else |
| { |
| bObject = pVar->IsObject(); |
| } |
| rPar.Get( 0 )->PutBool( bObject ); |
| } |
| } |
| |
| RTLFUNC(IsDate) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| // #46134 Nur String wird konvertiert, andere Typen ergeben sal_False |
| SbxVariableRef xArg = rPar.Get( 1 ); |
| SbxDataType eType = xArg->GetType(); |
| sal_Bool bDate = sal_False; |
| |
| if( eType == SbxDATE ) |
| { |
| bDate = sal_True; |
| } |
| else if( eType == SbxSTRING ) |
| { |
| // Error loeschen |
| SbxError nPrevError = SbxBase::GetError(); |
| SbxBase::ResetError(); |
| |
| // Konvertierung des Parameters nach SbxDATE erzwingen |
| xArg->SbxValue::GetDate(); |
| |
| // Bei Fehler ist es kein Date |
| bDate = !SbxBase::IsError(); |
| |
| // Error-Situation wiederherstellen |
| SbxBase::ResetError(); |
| SbxBase::SetError( nPrevError ); |
| } |
| rPar.Get( 0 )->PutBool( bDate ); |
| } |
| } |
| |
| RTLFUNC(IsEmpty) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| rPar.Get( 0 )->PutBool( rPar.Get(1)->IsEmpty() ); |
| } |
| |
| RTLFUNC(IsError) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() ); |
| } |
| |
| RTLFUNC(IsNull) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| // #51475 Wegen Uno-Objekten auch true liefern, |
| // wenn der pObj-Wert NULL ist |
| SbxVariableRef pArg = rPar.Get( 1 ); |
| sal_Bool bNull = rPar.Get(1)->IsNull(); |
| if( !bNull && pArg->GetType() == SbxOBJECT ) |
| { |
| SbxBase* pObj = pArg->GetObject(); |
| if( !pObj ) |
| bNull = sal_True; |
| } |
| rPar.Get( 0 )->PutBool( bNull ); |
| } |
| } |
| |
| RTLFUNC(IsNumeric) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| rPar.Get( 0 )->PutBool( rPar.Get( 1 )->IsNumericRTL() ); |
| } |
| |
| // Das machen wir auf die billige Tour |
| |
| RTLFUNC(IsMissing) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() < 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| // #57915 Missing wird durch Error angezeigt |
| rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() ); |
| } |
| |
| // Dir( [Maske] [,Attrs] ) |
| // ToDo: Library-globaler Datenbereich fuer Dir-Objekt und Flags |
| |
| |
| String getDirectoryPath( String aPathStr ) |
| { |
| String aRetStr; |
| |
| DirectoryItem aItem; |
| FileBase::RC nRet = DirectoryItem::get( aPathStr, aItem ); |
| if( nRet == FileBase::E_None ) |
| { |
| FileStatus aFileStatus( FileStatusMask_Type ); |
| nRet = aItem.getFileStatus( aFileStatus ); |
| if( nRet == FileBase::E_None ) |
| { |
| FileStatus::Type aType = aFileStatus.getFileType(); |
| if( isFolder( aType ) ) |
| { |
| aRetStr = aPathStr; |
| } |
| else if( aType == FileStatus::Link ) |
| { |
| FileStatus aFileStatus2( FileStatusMask_LinkTargetURL ); |
| nRet = aItem.getFileStatus( aFileStatus2 ); |
| if( nRet == FileBase::E_None ) |
| aRetStr = getDirectoryPath( aFileStatus2.getLinkTargetURL() ); |
| } |
| } |
| } |
| return aRetStr; |
| } |
| |
| // Function looks for wildcards, removes them and always returns the pure path |
| String implSetupWildcard( const String& rFileParam, SbiRTLData* pRTLData ) |
| { |
| static String aAsterisk = String::CreateFromAscii( "*" ); |
| static sal_Char cDelim1 = (sal_Char)'/'; |
| static sal_Char cDelim2 = (sal_Char)'\\'; |
| static sal_Char cWild1 = '*'; |
| static sal_Char cWild2 = '?'; |
| |
| delete pRTLData->pWildCard; |
| pRTLData->pWildCard = NULL; |
| pRTLData->sFullNameToBeChecked = String(); |
| |
| String aFileParam = rFileParam; |
| xub_StrLen nLastWild = aFileParam.SearchBackward( cWild1 ); |
| if( nLastWild == STRING_NOTFOUND ) |
| nLastWild = aFileParam.SearchBackward( cWild2 ); |
| sal_Bool bHasWildcards = ( nLastWild != STRING_NOTFOUND ); |
| |
| |
| xub_StrLen nLastDelim = aFileParam.SearchBackward( cDelim1 ); |
| if( nLastDelim == STRING_NOTFOUND ) |
| nLastDelim = aFileParam.SearchBackward( cDelim2 ); |
| |
| if( bHasWildcards ) |
| { |
| // Wildcards in path? |
| if( nLastDelim != STRING_NOTFOUND && nLastDelim > nLastWild ) |
| return aFileParam; |
| } |
| else |
| { |
| String aPathStr = getFullPath( aFileParam ); |
| if( nLastDelim != aFileParam.Len() - 1 ) |
| pRTLData->sFullNameToBeChecked = aPathStr; |
| return aPathStr; |
| } |
| |
| String aPureFileName; |
| if( nLastDelim == STRING_NOTFOUND ) |
| { |
| aPureFileName = aFileParam; |
| aFileParam = String(); |
| } |
| else |
| { |
| aPureFileName = aFileParam.Copy( nLastDelim + 1 ); |
| aFileParam = aFileParam.Copy( 0, nLastDelim ); |
| } |
| |
| // Try again to get a valid URL/UNC-path with only the path |
| String aPathStr = getFullPath( aFileParam ); |
| xub_StrLen nPureLen = aPureFileName.Len(); |
| |
| // Is there a pure file name left? Otherwise the path is |
| // invalid anyway because it was not accepted by OSL before |
| if( nPureLen && aPureFileName != aAsterisk ) |
| { |
| pRTLData->pWildCard = new WildCard( aPureFileName ); |
| } |
| return aPathStr; |
| } |
| |
| inline sal_Bool implCheckWildcard( const String& rName, SbiRTLData* pRTLData ) |
| { |
| sal_Bool bMatch = sal_True; |
| |
| if( pRTLData->pWildCard ) |
| bMatch = pRTLData->pWildCard->Matches( rName ); |
| return bMatch; |
| } |
| |
| |
| bool isRootDir( String aDirURLStr ) |
| { |
| INetURLObject aDirURLObj( aDirURLStr ); |
| sal_Bool bRoot = sal_False; |
| |
| // Check if it's a root directory |
| sal_Int32 nCount = aDirURLObj.getSegmentCount(); |
| |
| // No segment means Unix root directory "file:///" |
| if( nCount == 0 ) |
| { |
| bRoot = sal_True; |
| } |
| // Exactly one segment needs further checking, because it |
| // can be Unix "file:///foo/" -> no root |
| // or Windows "file:///c:/" -> root |
| else if( nCount == 1 ) |
| { |
| ::rtl::OUString aSeg1 = aDirURLObj.getName( 0, sal_True, |
| INetURLObject::DECODE_WITH_CHARSET ); |
| if( aSeg1.getStr()[1] == (sal_Unicode)':' ) |
| { |
| bRoot = sal_True; |
| } |
| } |
| // More than one segments can never be root |
| // so bRoot remains sal_False |
| |
| return bRoot; |
| } |
| |
| RTLFUNC(Dir) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| String aPath; |
| |
| sal_uInt16 nParCount = rPar.Count(); |
| if( nParCount > 3 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| SbiRTLData* pRTLData = pINST->GetRTLData(); |
| |
| // #34645: Kann auch von der URL-Zeile ueber 'macro: Dir' aufgerufen werden |
| // dann existiert kein pRTLData und die Methode muss verlassen werden |
| if( !pRTLData ) |
| return; |
| |
| // <-- UCB |
| if( hasUno() ) |
| { |
| com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); |
| if( xSFI.is() ) |
| { |
| if ( nParCount >= 2 ) |
| { |
| String aFileParam = rPar.Get(1)->GetString(); |
| |
| String aFileURLStr = implSetupWildcard( aFileParam, pRTLData ); |
| if( pRTLData->sFullNameToBeChecked.Len() > 0 ) |
| { |
| sal_Bool bExists = sal_False; |
| try { bExists = xSFI->exists( aFileURLStr ); } |
| catch( Exception & ) {} |
| |
| String aNameOnlyStr; |
| if( bExists ) |
| { |
| INetURLObject aFileURL( aFileURLStr ); |
| aNameOnlyStr = aFileURL.getName( INetURLObject::LAST_SEGMENT, |
| true, INetURLObject::DECODE_WITH_CHARSET ); |
| } |
| rPar.Get(0)->PutString( aNameOnlyStr ); |
| return; |
| } |
| |
| try |
| { |
| String aDirURLStr; |
| sal_Bool bFolder = xSFI->isFolder( aFileURLStr ); |
| |
| if( bFolder ) |
| { |
| aDirURLStr = aFileURLStr; |
| } |
| else |
| { |
| String aEmptyStr; |
| rPar.Get(0)->PutString( aEmptyStr ); |
| } |
| |
| sal_uInt16 nFlags = 0; |
| if ( nParCount > 2 ) |
| pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger(); |
| else |
| pRTLData->nDirFlags = 0; |
| |
| // Read directory |
| sal_Bool bIncludeFolders = ((nFlags & Sb_ATTR_DIRECTORY) != 0); |
| pRTLData->aDirSeq = xSFI->getFolderContents( aDirURLStr, bIncludeFolders ); |
| pRTLData->nCurDirPos = 0; |
| |
| // #78651 Add "." and ".." directories for VB compatibility |
| if( bIncludeFolders ) |
| { |
| sal_Bool bRoot = isRootDir( aDirURLStr ); |
| |
| // If it's no root directory we flag the need for |
| // the "." and ".." directories by the value -2 |
| // for the actual position. Later for -2 will be |
| // returned "." and for -1 ".." |
| if( !bRoot ) |
| { |
| pRTLData->nCurDirPos = -2; |
| } |
| } |
| } |
| catch( Exception & ) |
| { |
| //StarBASIC::Error( ERRCODE_IO_GENERAL ); |
| } |
| } |
| |
| |
| if( pRTLData->aDirSeq.getLength() > 0 ) |
| { |
| sal_Bool bFolderFlag = ((pRTLData->nDirFlags & Sb_ATTR_DIRECTORY) != 0); |
| |
| SbiInstance* pInst = pINST; |
| bool bCompatibility = ( pInst && pInst->IsCompatibility() ); |
| for( ;; ) |
| { |
| if( pRTLData->nCurDirPos < 0 ) |
| { |
| if( pRTLData->nCurDirPos == -2 ) |
| { |
| aPath = ::rtl::OUString::createFromAscii( "." ); |
| } |
| else if( pRTLData->nCurDirPos == -1 ) |
| { |
| aPath = ::rtl::OUString::createFromAscii( ".." ); |
| } |
| pRTLData->nCurDirPos++; |
| } |
| else if( pRTLData->nCurDirPos >= pRTLData->aDirSeq.getLength() ) |
| { |
| pRTLData->aDirSeq.realloc( 0 ); |
| aPath.Erase(); |
| break; |
| } |
| else |
| { |
| ::rtl::OUString aFile = pRTLData->aDirSeq.getConstArray()[pRTLData->nCurDirPos++]; |
| |
| if( bCompatibility ) |
| { |
| if( !bFolderFlag ) |
| { |
| sal_Bool bFolder = xSFI->isFolder( aFile ); |
| if( bFolder ) |
| continue; |
| } |
| } |
| else |
| { |
| // Only directories |
| if( bFolderFlag ) |
| { |
| sal_Bool bFolder = xSFI->isFolder( aFile ); |
| if( !bFolder ) |
| continue; |
| } |
| } |
| |
| INetURLObject aURL( aFile ); |
| aPath = aURL.getName( INetURLObject::LAST_SEGMENT, sal_True, |
| INetURLObject::DECODE_WITH_CHARSET ); |
| } |
| |
| sal_Bool bMatch = implCheckWildcard( aPath, pRTLData ); |
| if( !bMatch ) |
| continue; |
| |
| break; |
| } |
| } |
| rPar.Get(0)->PutString( aPath ); |
| } |
| } |
| else |
| // --> UCB |
| { |
| #ifdef _OLD_FILE_IMPL |
| if ( nParCount >= 2 ) |
| { |
| delete pRTLData->pDir; |
| pRTLData->pDir = 0; // wg. Sonderbehandlung Sb_ATTR_VOLUME |
| DirEntry aEntry( rPar.Get(1)->GetString() ); |
| FileStat aStat( aEntry ); |
| if(!aStat.GetError() && (aStat.GetKind() & FSYS_KIND_FILE)) |
| { |
| // ah ja, ist nur ein dateiname |
| // Pfad abschneiden (wg. VB4) |
| rPar.Get(0)->PutString( aEntry.GetName() ); |
| return; |
| } |
| sal_uInt16 nFlags = 0; |
| if ( nParCount > 2 ) |
| pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger(); |
| else |
| pRTLData->nDirFlags = 0; |
| |
| // Sb_ATTR_VOLUME wird getrennt gehandelt |
| if( pRTLData->nDirFlags & Sb_ATTR_VOLUME ) |
| aPath = aEntry.GetVolume(); |
| else |
| { |
| // Die richtige Auswahl treffen |
| sal_uInt16 nMode = FSYS_KIND_FILE; |
| if( nFlags & Sb_ATTR_DIRECTORY ) |
| nMode |= FSYS_KIND_DIR; |
| if( nFlags == Sb_ATTR_DIRECTORY ) |
| nMode = FSYS_KIND_DIR; |
| pRTLData->pDir = new Dir( aEntry, (DirEntryKind) nMode ); |
| pRTLData->nCurDirPos = 0; |
| } |
| } |
| |
| if( pRTLData->pDir ) |
| { |
| for( ;; ) |
| { |
| if( pRTLData->nCurDirPos >= pRTLData->pDir->Count() ) |
| { |
| delete pRTLData->pDir; |
| pRTLData->pDir = 0; |
| aPath.Erase(); |
| break; |
| } |
| DirEntry aNextEntry=(*(pRTLData->pDir))[pRTLData->nCurDirPos++]; |
| aPath = aNextEntry.GetName(); //Full(); |
| break; |
| } |
| } |
| rPar.Get(0)->PutString( aPath ); |
| #else |
| // TODO: OSL |
| if ( nParCount >= 2 ) |
| { |
| String aFileParam = rPar.Get(1)->GetString(); |
| |
| String aDirURL = implSetupWildcard( aFileParam, pRTLData ); |
| |
| sal_uInt16 nFlags = 0; |
| if ( nParCount > 2 ) |
| pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger(); |
| else |
| pRTLData->nDirFlags = 0; |
| |
| // Read directory |
| sal_Bool bIncludeFolders = ((nFlags & Sb_ATTR_DIRECTORY) != 0); |
| pRTLData->pDir = new Directory( aDirURL ); |
| FileBase::RC nRet = pRTLData->pDir->open(); |
| if( nRet != FileBase::E_None ) |
| { |
| delete pRTLData->pDir; |
| pRTLData->pDir = NULL; |
| rPar.Get(0)->PutString( String() ); |
| return; |
| } |
| |
| // #86950 Add "." and ".." directories for VB compatibility |
| pRTLData->nCurDirPos = 0; |
| if( bIncludeFolders ) |
| { |
| sal_Bool bRoot = isRootDir( aDirURL ); |
| |
| // If it's no root directory we flag the need for |
| // the "." and ".." directories by the value -2 |
| // for the actual position. Later for -2 will be |
| // returned "." and for -1 ".." |
| if( !bRoot ) |
| { |
| pRTLData->nCurDirPos = -2; |
| } |
| } |
| |
| } |
| |
| if( pRTLData->pDir ) |
| { |
| sal_Bool bFolderFlag = ((pRTLData->nDirFlags & Sb_ATTR_DIRECTORY) != 0); |
| for( ;; ) |
| { |
| if( pRTLData->nCurDirPos < 0 ) |
| { |
| if( pRTLData->nCurDirPos == -2 ) |
| { |
| aPath = ::rtl::OUString::createFromAscii( "." ); |
| } |
| else if( pRTLData->nCurDirPos == -1 ) |
| { |
| aPath = ::rtl::OUString::createFromAscii( ".." ); |
| } |
| pRTLData->nCurDirPos++; |
| } |
| else |
| { |
| DirectoryItem aItem; |
| FileBase::RC nRet = pRTLData->pDir->getNextItem( aItem ); |
| if( nRet != FileBase::E_None ) |
| { |
| delete pRTLData->pDir; |
| pRTLData->pDir = NULL; |
| aPath.Erase(); |
| break; |
| } |
| |
| // Handle flags |
| FileStatus aFileStatus( FileStatusMask_Type | FileStatusMask_FileName ); |
| nRet = aItem.getFileStatus( aFileStatus ); |
| |
| // Only directories? |
| if( bFolderFlag ) |
| { |
| FileStatus::Type aType = aFileStatus.getFileType(); |
| sal_Bool bFolder = isFolder( aType ); |
| if( !bFolder ) |
| continue; |
| } |
| |
| aPath = aFileStatus.getFileName(); |
| } |
| |
| sal_Bool bMatch = implCheckWildcard( aPath, pRTLData ); |
| if( !bMatch ) |
| continue; |
| |
| break; |
| } |
| } |
| rPar.Get(0)->PutString( aPath ); |
| #endif |
| } |
| } |
| } |
| |
| |
| RTLFUNC(GetAttr) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() == 2 ) |
| { |
| sal_Int16 nFlags = 0; |
| |
| // In Windows, We want to use Windows API to get the file attributes |
| // for VBA interoperability. |
| #if defined( WNT ) |
| if( SbiRuntime::isVBAEnabled() ) |
| { |
| DirEntry aEntry( rPar.Get(1)->GetString() ); |
| aEntry.ToAbs(); |
| |
| // #57064 Bei virtuellen URLs den Real-Path extrahieren |
| ByteString aByteStrFullPath( aEntry.GetFull(), gsl_getSystemTextEncoding() ); |
| DWORD nRealFlags = GetFileAttributes (aByteStrFullPath.GetBuffer()); |
| if (nRealFlags != 0xffffffff) |
| { |
| if (nRealFlags == FILE_ATTRIBUTE_NORMAL) |
| nRealFlags = 0; |
| nFlags = (sal_Int16) (nRealFlags); |
| } |
| else |
| StarBASIC::Error( SbERR_FILE_NOT_FOUND ); |
| |
| rPar.Get(0)->PutInteger( nFlags ); |
| |
| return; |
| } |
| #endif |
| |
| // <-- UCB |
| if( hasUno() ) |
| { |
| com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); |
| if( xSFI.is() ) |
| { |
| try |
| { |
| String aPath = getFullPath( rPar.Get(1)->GetString() ); |
| sal_Bool bExists = sal_False; |
| try { bExists = xSFI->exists( aPath ); } |
| catch( Exception & ) {} |
| if( !bExists ) |
| { |
| StarBASIC::Error( SbERR_FILE_NOT_FOUND ); |
| return; |
| } |
| |
| sal_Bool bReadOnly = xSFI->isReadOnly( aPath ); |
| sal_Bool bHidden = xSFI->isHidden( aPath ); |
| sal_Bool bDirectory = xSFI->isFolder( aPath ); |
| if( bReadOnly ) |
| nFlags |= 0x0001; // ATTR_READONLY |
| if( bHidden ) |
| nFlags |= 0x0002; // ATTR_HIDDEN |
| if( bDirectory ) |
| nFlags |= 0x0010; // ATTR_DIRECTORY |
| } |
| catch( Exception & ) |
| { |
| StarBASIC::Error( ERRCODE_IO_GENERAL ); |
| } |
| } |
| } |
| else |
| // --> UCB |
| { |
| DirectoryItem aItem; |
| FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( rPar.Get(1)->GetString() ), aItem ); |
| FileStatus aFileStatus( FileStatusMask_Attributes | FileStatusMask_Type ); |
| nRet = aItem.getFileStatus( aFileStatus ); |
| sal_uInt64 nAttributes = aFileStatus.getAttributes(); |
| sal_Bool bReadOnly = (nAttributes & Attribute_ReadOnly) != 0; |
| |
| FileStatus::Type aType = aFileStatus.getFileType(); |
| sal_Bool bDirectory = isFolder( aType ); |
| if( bReadOnly ) |
| nFlags |= 0x0001; // ATTR_READONLY |
| if( bDirectory ) |
| nFlags |= 0x0010; // ATTR_DIRECTORY |
| } |
| rPar.Get(0)->PutInteger( nFlags ); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| |
| |
| RTLFUNC(FileDateTime) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| // <-- UCB |
| String aPath = rPar.Get(1)->GetString(); |
| Time aTime; |
| Date aDate; |
| if( hasUno() ) |
| { |
| com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); |
| if( xSFI.is() ) |
| { |
| try |
| { |
| com::sun::star::util::DateTime aUnoDT = xSFI->getDateTimeModified( aPath ); |
| aTime = Time( aUnoDT.Hours, aUnoDT.Minutes, aUnoDT.Seconds, aUnoDT.HundredthSeconds ); |
| aDate = Date( aUnoDT.Day, aUnoDT.Month, aUnoDT.Year ); |
| } |
| catch( Exception & ) |
| { |
| StarBASIC::Error( ERRCODE_IO_GENERAL ); |
| } |
| } |
| } |
| else |
| // --> UCB |
| { |
| #ifdef _OLD_FILE_IMPL |
| DirEntry aEntry( aPath ); |
| FileStat aStat( aEntry ); |
| aTime = Time( aStat.TimeModified() ); |
| aDate = Date( aStat.DateModified() ); |
| #else |
| DirectoryItem aItem; |
| FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( aPath ), aItem ); |
| FileStatus aFileStatus( FileStatusMask_ModifyTime ); |
| nRet = aItem.getFileStatus( aFileStatus ); |
| TimeValue aTimeVal = aFileStatus.getModifyTime(); |
| oslDateTime aDT; |
| osl_getDateTimeFromTimeValue( &aTimeVal, &aDT ); |
| |
| aTime = Time( aDT.Hours, aDT.Minutes, aDT.Seconds, 10000000*aDT.NanoSeconds ); |
| aDate = Date( aDT.Day, aDT.Month, aDT.Year ); |
| #endif |
| } |
| |
| double fSerial = (double)GetDayDiff( aDate ); |
| long nSeconds = aTime.GetHour(); |
| nSeconds *= 3600; |
| nSeconds += aTime.GetMin() * 60; |
| nSeconds += aTime.GetSec(); |
| double nDays = ((double)nSeconds) / (double)(24.0*3600.0); |
| fSerial += nDays; |
| |
| Color* pCol; |
| |
| // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden |
| SvNumberFormatter* pFormatter = NULL; |
| sal_uInt32 nIndex; |
| if( pINST ) |
| { |
| pFormatter = pINST->GetNumberFormatter(); |
| nIndex = pINST->GetStdDateTimeIdx(); |
| } |
| else |
| { |
| sal_uInt32 n; // Dummy |
| SbiInstance::PrepareNumberFormatter( pFormatter, n, n, nIndex ); |
| } |
| |
| String aRes; |
| pFormatter->GetOutputString( fSerial, nIndex, aRes, &pCol ); |
| rPar.Get(0)->PutString( aRes ); |
| |
| // #39629 pFormatter kann selbst angefordert sein |
| if( !pINST ) |
| delete pFormatter; |
| } |
| } |
| |
| |
| RTLFUNC(EOF) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| // AB 08/16/2000: No changes for UCB |
| if ( rPar.Count() != 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| sal_Int16 nChannel = rPar.Get(1)->GetInteger(); |
| // nChannel--; // macht MD beim Oeffnen auch nicht |
| SbiIoSystem* pIO = pINST->GetIoSystem(); |
| SbiStream* pSbStrm = pIO->GetStream( nChannel ); |
| if ( !pSbStrm ) |
| { |
| StarBASIC::Error( SbERR_BAD_CHANNEL ); |
| return; |
| } |
| sal_Bool bIsEof; |
| SvStream* pSvStrm = pSbStrm->GetStrm(); |
| if ( pSbStrm->IsText() ) |
| { |
| char cBla; |
| (*pSvStrm) >> cBla; // koennen wir noch ein Zeichen lesen |
| bIsEof = pSvStrm->IsEof(); |
| if ( !bIsEof ) |
| pSvStrm->SeekRel( -1 ); |
| } |
| else |
| bIsEof = pSvStrm->IsEof(); // fuer binaerdateien! |
| rPar.Get(0)->PutBool( bIsEof ); |
| } |
| } |
| |
| RTLFUNC(FileAttr) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| // AB 08/16/2000: No changes for UCB |
| |
| // #57064 Obwohl diese Funktion nicht mit DirEntry arbeitet, ist sie von |
| // der Anpassung an virtuelle URLs nich betroffen, da sie nur auf bereits |
| // geoeffneten Dateien arbeitet und der Name hier keine Rolle spielt. |
| |
| if ( rPar.Count() != 3 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| sal_Int16 nChannel = rPar.Get(1)->GetInteger(); |
| // nChannel--; |
| SbiIoSystem* pIO = pINST->GetIoSystem(); |
| SbiStream* pSbStrm = pIO->GetStream( nChannel ); |
| if ( !pSbStrm ) |
| { |
| StarBASIC::Error( SbERR_BAD_CHANNEL ); |
| return; |
| } |
| sal_Int16 nRet; |
| if ( rPar.Get(2)->GetInteger() == 1 ) |
| nRet = (sal_Int16)(pSbStrm->GetMode()); |
| else |
| nRet = 0; // System file handle not supported |
| |
| rPar.Get(0)->PutInteger( nRet ); |
| } |
| } |
| RTLFUNC(Loc) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| // AB 08/16/2000: No changes for UCB |
| if ( rPar.Count() != 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| sal_Int16 nChannel = rPar.Get(1)->GetInteger(); |
| SbiIoSystem* pIO = pINST->GetIoSystem(); |
| SbiStream* pSbStrm = pIO->GetStream( nChannel ); |
| if ( !pSbStrm ) |
| { |
| StarBASIC::Error( SbERR_BAD_CHANNEL ); |
| return; |
| } |
| SvStream* pSvStrm = pSbStrm->GetStrm(); |
| sal_uIntPtr nPos; |
| if( pSbStrm->IsRandom()) |
| { |
| short nBlockLen = pSbStrm->GetBlockLen(); |
| nPos = nBlockLen ? (pSvStrm->Tell() / nBlockLen) : 0; |
| nPos++; // Blockpositionen beginnen bei 1 |
| } |
| else if ( pSbStrm->IsText() ) |
| nPos = pSbStrm->GetLine(); |
| else if( pSbStrm->IsBinary() ) |
| nPos = pSvStrm->Tell(); |
| else if ( pSbStrm->IsSeq() ) |
| nPos = ( pSvStrm->Tell()+1 ) / 128; |
| else |
| nPos = pSvStrm->Tell(); |
| rPar.Get(0)->PutLong( (sal_Int32)nPos ); |
| } |
| } |
| |
| RTLFUNC(Lof) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| // AB 08/16/2000: No changes for UCB |
| if ( rPar.Count() != 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| sal_Int16 nChannel = rPar.Get(1)->GetInteger(); |
| SbiIoSystem* pIO = pINST->GetIoSystem(); |
| SbiStream* pSbStrm = pIO->GetStream( nChannel ); |
| if ( !pSbStrm ) |
| { |
| StarBASIC::Error( SbERR_BAD_CHANNEL ); |
| return; |
| } |
| SvStream* pSvStrm = pSbStrm->GetStrm(); |
| sal_uIntPtr nOldPos = pSvStrm->Tell(); |
| sal_uIntPtr nLen = pSvStrm->Seek( STREAM_SEEK_TO_END ); |
| pSvStrm->Seek( nOldPos ); |
| rPar.Get(0)->PutLong( (sal_Int32)nLen ); |
| } |
| } |
| |
| |
| RTLFUNC(Seek) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| // AB 08/16/2000: No changes for UCB |
| int nArgs = (int)rPar.Count(); |
| if ( nArgs < 2 || nArgs > 3 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| sal_Int16 nChannel = rPar.Get(1)->GetInteger(); |
| // nChannel--; |
| SbiIoSystem* pIO = pINST->GetIoSystem(); |
| SbiStream* pSbStrm = pIO->GetStream( nChannel ); |
| if ( !pSbStrm ) |
| { |
| StarBASIC::Error( SbERR_BAD_CHANNEL ); |
| return; |
| } |
| SvStream* pStrm = pSbStrm->GetStrm(); |
| |
| if ( nArgs == 2 ) // Seek-Function |
| { |
| sal_uIntPtr nPos = pStrm->Tell(); |
| if( pSbStrm->IsRandom() ) |
| nPos = nPos / pSbStrm->GetBlockLen(); |
| nPos++; // Basic zaehlt ab 1 |
| rPar.Get(0)->PutLong( (sal_Int32)nPos ); |
| } |
| else // Seek-Statement |
| { |
| sal_Int32 nPos = rPar.Get(2)->GetLong(); |
| if ( nPos < 1 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| nPos--; // Basic zaehlt ab 1, SvStreams zaehlen ab 0 |
| pSbStrm->SetExpandOnWriteTo( 0 ); |
| if ( pSbStrm->IsRandom() ) |
| nPos *= pSbStrm->GetBlockLen(); |
| pStrm->Seek( (sal_uIntPtr)nPos ); |
| pSbStrm->SetExpandOnWriteTo( nPos ); |
| } |
| } |
| |
| RTLFUNC(Format) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_uInt16 nArgCount = (sal_uInt16)rPar.Count(); |
| if ( nArgCount < 2 || nArgCount > 3 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| String aResult; |
| if( nArgCount == 2 ) |
| rPar.Get(1)->Format( aResult ); |
| else |
| { |
| String aFmt( rPar.Get(2)->GetString() ); |
| rPar.Get(1)->Format( aResult, &aFmt ); |
| } |
| rPar.Get(0)->PutString( aResult ); |
| } |
| } |
| |
| RTLFUNC(Randomize) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() > 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| sal_Int16 nSeed; |
| if( rPar.Count() == 2 ) |
| nSeed = (sal_Int16)rPar.Get(1)->GetInteger(); |
| else |
| nSeed = (sal_Int16)rand(); |
| srand( nSeed ); |
| } |
| |
| RTLFUNC(Rnd) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() > 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| double nRand = (double)rand(); |
| nRand = ( nRand / (double)RAND_MAX ); |
| rPar.Get(0)->PutDouble( nRand ); |
| } |
| } |
| |
| |
| // |
| // Syntax: Shell("Path",[ Window-Style,[ "Params", [ bSync = sal_False ]]]) |
| // |
| // WindowStyles (VBA-kompatibel): |
| // 2 == Minimized |
| // 3 == Maximized |
| // 10 == Full-Screen (Textmodus-Anwendungen OS/2, WIN95, WNT) |
| // |
| // !!!HACK der WindowStyle wird im Creator an Application::StartApp |
| // uebergeben. Format: "xxxx2" |
| // |
| |
| |
| RTLFUNC(Shell) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| // No shell command for "virtual" portal users |
| if( needSecurityRestrictions() ) |
| { |
| StarBASIC::Error(SbERR_NOT_IMPLEMENTED); |
| return; |
| } |
| |
| sal_uIntPtr nArgCount = rPar.Count(); |
| if ( nArgCount < 2 || nArgCount > 5 ) |
| { |
| rPar.Get(0)->PutLong(0); |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| else |
| { |
| sal_uInt16 nOptions = vos::OProcess::TOption_SearchPath| |
| vos::OProcess::TOption_Detached; |
| String aCmdLine = rPar.Get(1)->GetString(); |
| // Zusaetzliche Parameter anhaengen, es muss eh alles geparsed werden |
| if( nArgCount >= 4 ) |
| { |
| aCmdLine.AppendAscii( " " ); |
| aCmdLine += rPar.Get(3)->GetString(); |
| } |
| else if( !aCmdLine.Len() ) |
| { |
| // Spezial-Behandlung (leere Liste) vermeiden |
| aCmdLine.AppendAscii( " " ); |
| } |
| sal_uInt16 nLen = aCmdLine.Len(); |
| |
| // #55735 Wenn Parameter dabei sind, muessen die abgetrennt werden |
| // #72471 Auch die einzelnen Parameter trennen |
| std::list<String> aTokenList; |
| String aToken; |
| sal_uInt16 i = 0; |
| sal_Unicode c; |
| while( i < nLen ) |
| { |
| // Spaces weg |
| for ( ;; ++i ) |
| { |
| c = aCmdLine.GetBuffer()[ i ]; |
| if ( c != ' ' && c != '\t' ) |
| break; |
| } |
| |
| if( c == '\"' || c == '\'' ) |
| { |
| sal_uInt16 iFoundPos = aCmdLine.Search( c, i + 1 ); |
| |
| // Wenn nichts gefunden wurde, Rest kopieren |
| if( iFoundPos == STRING_NOTFOUND ) |
| { |
| aToken = aCmdLine.Copy( i, STRING_LEN ); |
| i = nLen; |
| } |
| else |
| { |
| aToken = aCmdLine.Copy( i + 1, (iFoundPos - i - 1) ); |
| i = iFoundPos + 1; |
| } |
| } |
| else |
| { |
| sal_uInt16 iFoundSpacePos = aCmdLine.Search( ' ', i ); |
| sal_uInt16 iFoundTabPos = aCmdLine.Search( '\t', i ); |
| sal_uInt16 iFoundPos = Min( iFoundSpacePos, iFoundTabPos ); |
| |
| // Wenn nichts gefunden wurde, Rest kopieren |
| if( iFoundPos == STRING_NOTFOUND ) |
| { |
| aToken = aCmdLine.Copy( i, STRING_LEN ); |
| i = nLen; |
| } |
| else |
| { |
| aToken = aCmdLine.Copy( i, (iFoundPos - i) ); |
| i = iFoundPos; |
| } |
| } |
| |
| // In die Liste uebernehmen |
| aTokenList.push_back( aToken ); |
| } |
| // #55735 / #72471 Ende |
| |
| sal_Int16 nWinStyle = 0; |
| if( nArgCount >= 3 ) |
| { |
| nWinStyle = rPar.Get(2)->GetInteger(); |
| switch( nWinStyle ) |
| { |
| case 2: |
| nOptions |= vos::OProcess::TOption_Minimized; |
| break; |
| case 3: |
| nOptions |= vos::OProcess::TOption_Maximized; |
| break; |
| case 10: |
| nOptions |= vos::OProcess::TOption_FullScreen; |
| break; |
| } |
| |
| sal_Bool bSync = sal_False; |
| if( nArgCount >= 5 ) |
| bSync = rPar.Get(4)->GetBool(); |
| if( bSync ) |
| nOptions |= vos::OProcess::TOption_Wait; |
| } |
| vos::OProcess::TProcessOption eOptions = |
| (vos::OProcess::TProcessOption)nOptions; |
| |
| |
| // #72471 Parameter aufbereiten |
| std::list<String>::const_iterator iter = aTokenList.begin(); |
| const String& rStr = *iter; |
| ::rtl::OUString aOUStrProg( rStr.GetBuffer(), rStr.Len() ); |
| String aOUStrProgUNC = getFullPathUNC( aOUStrProg ); |
| |
| iter++; |
| |
| sal_uInt16 nParamCount = sal::static_int_cast< sal_uInt16 >( |
| aTokenList.size() - 1 ); |
| ::rtl::OUString* pArgumentList = NULL; |
| //const char** pParamList = NULL; |
| if( nParamCount ) |
| { |
| pArgumentList = new ::rtl::OUString[ nParamCount ]; |
| //pParamList = new const char*[ nParamCount ]; |
| sal_uInt16 iList = 0; |
| while( iter != aTokenList.end() ) |
| { |
| const String& rParamStr = (*iter); |
| pArgumentList[iList++] = ::rtl::OUString( rParamStr.GetBuffer(), rParamStr.Len() ); |
| //pParamList[iList++] = (*iter).GetStr(); |
| iter++; |
| } |
| } |
| |
| //const char* pParams = aParams.Len() ? aParams.GetStr() : 0; |
| vos::OProcess* pApp; |
| pApp = new vos::OProcess( aOUStrProgUNC ); |
| sal_Bool bSucc; |
| if( nParamCount == 0 ) |
| { |
| bSucc = pApp->execute( eOptions ) == vos::OProcess::E_None; |
| } |
| else |
| { |
| vos::OArgumentList aArgList( pArgumentList, nParamCount ); |
| bSucc = pApp->execute( eOptions, aArgList ) == vos::OProcess::E_None; |
| } |
| |
| /* |
| if( nParamCount == 0 ) |
| pApp = new vos::OProcess( pProg ); |
| else |
| pApp = new vos::OProcess( pProg, pParamList, nParamCount ); |
| sal_Bool bSucc = pApp->execute( eOptions ) == vos::OProcess::E_None; |
| */ |
| |
| delete pApp; |
| delete[] pArgumentList; |
| if( !bSucc ) |
| StarBASIC::Error( SbERR_FILE_NOT_FOUND ); |
| else |
| rPar.Get(0)->PutLong( 0 ); |
| } |
| } |
| |
| RTLFUNC(VarType) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| SbxDataType eType = rPar.Get(1)->GetType(); |
| rPar.Get(0)->PutInteger( (sal_Int16)eType ); |
| } |
| } |
| |
| // Exported function |
| String getBasicTypeName( SbxDataType eType ) |
| { |
| static const char* pTypeNames[] = |
| { |
| "Empty", // SbxEMPTY |
| "Null", // SbxNULL |
| "Integer", // SbxINTEGER |
| "Long", // SbxLONG |
| "Single", // SbxSINGLE |
| "Double", // SbxDOUBLE |
| "Currency", // SbxCURRENCY |
| "Date", // SbxDATE |
| "String", // SbxSTRING |
| "Object", // SbxOBJECT |
| "Error", // SbxERROR |
| "Boolean", // SbxBOOL |
| "Variant", // SbxVARIANT |
| "DataObject", // SbxDATAOBJECT |
| "Unknown Type", // |
| "Unknown Type", // |
| "Char", // SbxCHAR |
| "Byte", // SbxBYTE |
| "UShort", // SbxUSHORT |
| "ULong", // SbxULONG |
| "Long64", // SbxLONG64 |
| "ULong64", // SbxULONG64 |
| "Int", // SbxINT |
| "UInt", // SbxUINT |
| "Void", // SbxVOID |
| "HResult", // SbxHRESULT |
| "Pointer", // SbxPOINTER |
| "DimArray", // SbxDIMARRAY |
| "CArray", // SbxCARRAY |
| "Userdef", // SbxUSERDEF |
| "Lpstr", // SbxLPSTR |
| "Lpwstr", // SbxLPWSTR |
| "Unknown Type", // SbxCoreSTRING |
| "WString", // SbxWSTRING |
| "WChar", // SbxWCHAR |
| "Int64", // SbxSALINT64 |
| "UInt64", // SbxSALUINT64 |
| "Decimal", // SbxDECIMAL |
| }; |
| |
| int nPos = ((int)eType) & 0x0FFF; |
| sal_uInt16 nTypeNameCount = sizeof( pTypeNames ) / sizeof( char* ); |
| if ( nPos < 0 || nPos >= nTypeNameCount ) |
| nPos = nTypeNameCount - 1; |
| String aRetStr = String::CreateFromAscii( pTypeNames[nPos] ); |
| return aRetStr; |
| } |
| |
| RTLFUNC(TypeName) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| SbxDataType eType = rPar.Get(1)->GetType(); |
| sal_Bool bIsArray = ( ( eType & SbxARRAY ) != 0 ); |
| String aRetStr = getBasicTypeName( eType ); |
| if( bIsArray ) |
| aRetStr.AppendAscii( "()" ); |
| rPar.Get(0)->PutString( aRetStr ); |
| } |
| } |
| |
| RTLFUNC(Len) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 2 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else |
| { |
| const String& rStr = rPar.Get(1)->GetString(); |
| rPar.Get(0)->PutLong( (sal_Int32)rStr.Len() ); |
| } |
| } |
| |
| RTLFUNC(DDEInitiate) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| // No DDE for "virtual" portal users |
| if( needSecurityRestrictions() ) |
| { |
| StarBASIC::Error(SbERR_NOT_IMPLEMENTED); |
| return; |
| } |
| |
| int nArgs = (int)rPar.Count(); |
| if ( nArgs != 3 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| const String& rApp = rPar.Get(1)->GetString(); |
| const String& rTopic = rPar.Get(2)->GetString(); |
| |
| SbiDdeControl* pDDE = pINST->GetDdeControl(); |
| sal_Int16 nChannel; |
| SbError nDdeErr = pDDE->Initiate( rApp, rTopic, nChannel ); |
| if( nDdeErr ) |
| StarBASIC::Error( nDdeErr ); |
| else |
| rPar.Get(0)->PutInteger( nChannel ); |
| } |
| |
| RTLFUNC(DDETerminate) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| // No DDE for "virtual" portal users |
| if( needSecurityRestrictions() ) |
| { |
| StarBASIC::Error(SbERR_NOT_IMPLEMENTED); |
| return; |
| } |
| |
| rPar.Get(0)->PutEmpty(); |
| int nArgs = (int)rPar.Count(); |
| if ( nArgs != 2 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| sal_Int16 nChannel = rPar.Get(1)->GetInteger(); |
| SbiDdeControl* pDDE = pINST->GetDdeControl(); |
| SbError nDdeErr = pDDE->Terminate( nChannel ); |
| if( nDdeErr ) |
| StarBASIC::Error( nDdeErr ); |
| } |
| |
| RTLFUNC(DDETerminateAll) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| // No DDE for "virtual" portal users |
| if( needSecurityRestrictions() ) |
| { |
| StarBASIC::Error(SbERR_NOT_IMPLEMENTED); |
| return; |
| } |
| |
| rPar.Get(0)->PutEmpty(); |
| int nArgs = (int)rPar.Count(); |
| if ( nArgs != 1 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| SbiDdeControl* pDDE = pINST->GetDdeControl(); |
| SbError nDdeErr = pDDE->TerminateAll(); |
| if( nDdeErr ) |
| StarBASIC::Error( nDdeErr ); |
| |
| } |
| |
| RTLFUNC(DDERequest) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| // No DDE for "virtual" portal users |
| if( needSecurityRestrictions() ) |
| { |
| StarBASIC::Error(SbERR_NOT_IMPLEMENTED); |
| return; |
| } |
| |
| int nArgs = (int)rPar.Count(); |
| if ( nArgs != 3 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| sal_Int16 nChannel = rPar.Get(1)->GetInteger(); |
| const String& rItem = rPar.Get(2)->GetString(); |
| SbiDdeControl* pDDE = pINST->GetDdeControl(); |
| String aResult; |
| SbError nDdeErr = pDDE->Request( nChannel, rItem, aResult ); |
| if( nDdeErr ) |
| StarBASIC::Error( nDdeErr ); |
| else |
| rPar.Get(0)->PutString( aResult ); |
| } |
| |
| RTLFUNC(DDEExecute) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| // No DDE for "virtual" portal users |
| if( needSecurityRestrictions() ) |
| { |
| StarBASIC::Error(SbERR_NOT_IMPLEMENTED); |
| return; |
| } |
| |
| rPar.Get(0)->PutEmpty(); |
| int nArgs = (int)rPar.Count(); |
| if ( nArgs != 3 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| sal_Int16 nChannel = rPar.Get(1)->GetInteger(); |
| const String& rCommand = rPar.Get(2)->GetString(); |
| SbiDdeControl* pDDE = pINST->GetDdeControl(); |
| SbError nDdeErr = pDDE->Execute( nChannel, rCommand ); |
| if( nDdeErr ) |
| StarBASIC::Error( nDdeErr ); |
| } |
| |
| RTLFUNC(DDEPoke) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| // No DDE for "virtual" portal users |
| if( needSecurityRestrictions() ) |
| { |
| StarBASIC::Error(SbERR_NOT_IMPLEMENTED); |
| return; |
| } |
| |
| rPar.Get(0)->PutEmpty(); |
| int nArgs = (int)rPar.Count(); |
| if ( nArgs != 4 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| sal_Int16 nChannel = rPar.Get(1)->GetInteger(); |
| const String& rItem = rPar.Get(2)->GetString(); |
| const String& rData = rPar.Get(3)->GetString(); |
| SbiDdeControl* pDDE = pINST->GetDdeControl(); |
| SbError nDdeErr = pDDE->Poke( nChannel, rItem, rData ); |
| if( nDdeErr ) |
| StarBASIC::Error( nDdeErr ); |
| } |
| |
| |
| RTLFUNC(FreeFile) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 1 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| SbiIoSystem* pIO = pINST->GetIoSystem(); |
| short nChannel = 1; |
| while( nChannel < CHANNELS ) |
| { |
| SbiStream* pStrm = pIO->GetStream( nChannel ); |
| if( !pStrm ) |
| { |
| rPar.Get(0)->PutInteger( nChannel ); |
| return; |
| } |
| nChannel++; |
| } |
| StarBASIC::Error( SbERR_TOO_MANY_FILES ); |
| } |
| |
| RTLFUNC(LBound) |
| { |
| (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 ) |
| { |
| sal_Int32 nLower, nUpper; |
| short nDim = (nParCount == 3) ? (short)rPar.Get(2)->GetInteger() : 1; |
| if( !pArr->GetDim32( nDim, nLower, nUpper ) ) |
| StarBASIC::Error( SbERR_OUT_OF_RANGE ); |
| else |
| rPar.Get(0)->PutLong( nLower ); |
| } |
| else |
| StarBASIC::Error( SbERR_MUST_HAVE_DIMS ); |
| } |
| |
| RTLFUNC(UBound) |
| { |
| (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 ) |
| { |
| sal_Int32 nLower, nUpper; |
| short nDim = (nParCount == 3) ? (short)rPar.Get(2)->GetInteger() : 1; |
| if( !pArr->GetDim32( nDim, nLower, nUpper ) ) |
| StarBASIC::Error( SbERR_OUT_OF_RANGE ); |
| else |
| rPar.Get(0)->PutLong( nUpper ); |
| } |
| else |
| StarBASIC::Error( SbERR_MUST_HAVE_DIMS ); |
| } |
| |
| RTLFUNC(RGB) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 4 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| sal_uIntPtr nRed = rPar.Get(1)->GetInteger() & 0xFF; |
| sal_uIntPtr nGreen = rPar.Get(2)->GetInteger() & 0xFF; |
| sal_uIntPtr nBlue = rPar.Get(3)->GetInteger() & 0xFF; |
| sal_uIntPtr nRGB; |
| |
| SbiInstance* pInst = pINST; |
| bool bCompatibility = ( pInst && pInst->IsCompatibility() ); |
| if( bCompatibility ) |
| { |
| nRGB = (nBlue << 16) | (nGreen << 8) | nRed; |
| } |
| else |
| { |
| nRGB = (nRed << 16) | (nGreen << 8) | nBlue; |
| } |
| rPar.Get(0)->PutLong( nRGB ); |
| } |
| |
| RTLFUNC(QBColor) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| static const sal_Int32 pRGB[] = |
| { |
| 0x000000, |
| 0x800000, |
| 0x008000, |
| 0x808000, |
| 0x000080, |
| 0x800080, |
| 0x008080, |
| 0xC0C0C0, |
| 0x808080, |
| 0xFF0000, |
| 0x00FF00, |
| 0xFFFF00, |
| 0x0000FF, |
| 0xFF00FF, |
| 0x00FFFF, |
| 0xFFFFFF, |
| }; |
| |
| if ( rPar.Count() != 2 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| sal_Int16 nCol = rPar.Get(1)->GetInteger(); |
| if( nCol < 0 || nCol > 15 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| sal_Int32 nRGB = pRGB[ nCol ]; |
| rPar.Get(0)->PutLong( nRGB ); |
| } |
| |
| // StrConv(string, conversion, LCID) |
| RTLFUNC(StrConv) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_uIntPtr nArgCount = rPar.Count()-1; |
| if( nArgCount < 2 || nArgCount > 3 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| String aOldStr = rPar.Get(1)->GetString(); |
| sal_Int32 nConversion = rPar.Get(2)->GetLong(); |
| |
| sal_uInt16 nLanguage = LANGUAGE_SYSTEM; |
| if( nArgCount == 3 ) |
| { |
| // LCID not supported now |
| //nLanguage = rPar.Get(3)->GetInteger(); |
| } |
| |
| sal_uInt16 nOldLen = aOldStr.Len(); |
| if( nOldLen == 0 ) |
| { |
| // null string,return |
| rPar.Get(0)->PutString(aOldStr); |
| return; |
| } |
| |
| sal_Int32 nType = 0; |
| if ( (nConversion & 0x03) == 3 ) // vbProperCase |
| { |
| CharClass& rCharClass = GetCharClass(); |
| aOldStr = rCharClass.toTitle( aOldStr.ToLowerAscii(), 0, nOldLen ); |
| } |
| else if ( (nConversion & 0x01) == 1 ) // vbUpperCase |
| nType |= ::com::sun::star::i18n::TransliterationModules_LOWERCASE_UPPERCASE; |
| else if ( (nConversion & 0x02) == 2 ) // vbLowerCase |
| nType |= ::com::sun::star::i18n::TransliterationModules_UPPERCASE_LOWERCASE; |
| |
| if ( (nConversion & 0x04) == 4 ) // vbWide |
| nType |= ::com::sun::star::i18n::TransliterationModules_HALFWIDTH_FULLWIDTH; |
| else if ( (nConversion & 0x08) == 8 ) // vbNarrow |
| nType |= ::com::sun::star::i18n::TransliterationModules_FULLWIDTH_HALFWIDTH; |
| |
| if ( (nConversion & 0x10) == 16) // vbKatakana |
| nType |= ::com::sun::star::i18n::TransliterationModules_HIRAGANA_KATAKANA; |
| else if ( (nConversion & 0x20) == 32 ) // vbHiragana |
| nType |= ::com::sun::star::i18n::TransliterationModules_KATAKANA_HIRAGANA; |
| |
| String aNewStr( aOldStr ); |
| if( nType != 0 ) |
| { |
| com::sun::star::uno::Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory(); |
| ::utl::TransliterationWrapper aTransliterationWrapper( xSMgr,nType ); |
| com::sun::star::uno::Sequence<sal_Int32> aOffsets; |
| aTransliterationWrapper.loadModuleIfNeeded( nLanguage ); |
| aNewStr = aTransliterationWrapper.transliterate( aOldStr, nLanguage, 0, nOldLen, &aOffsets ); |
| } |
| |
| if ( (nConversion & 0x40) == 64 ) // vbUnicode |
| { |
| // convert the string to byte string, preserving unicode (2 bytes per character) |
| sal_uInt16 nSize = aNewStr.Len()*2; |
| const sal_Unicode* pSrc = aNewStr.GetBuffer(); |
| sal_Char* pChar = new sal_Char[nSize+1]; |
| for( sal_uInt16 i=0; i < nSize; i++ ) |
| { |
| pChar[i] = static_cast< sal_Char >( i%2 ? ((*pSrc) >> 8) & 0xff : (*pSrc) & 0xff ); |
| if( i%2 ) |
| pSrc++; |
| } |
| pChar[nSize] = '\0'; |
| ::rtl::OString aOStr(pChar); |
| |
| // there is no concept about default codepage in unix. so it is incorrectly in unix |
| ::rtl::OUString aOUStr = ::rtl::OStringToOUString(aOStr, osl_getThreadTextEncoding()); |
| aNewStr = String(aOUStr); |
| rPar.Get(0)->PutString( aNewStr ); |
| return; |
| } |
| else if ( (nConversion & 0x80) == 128 ) // vbFromUnicode |
| { |
| ::rtl::OUString aOUStr(aNewStr); |
| // there is no concept about default codepage in unix. so it is incorrectly in unix |
| ::rtl::OString aOStr = ::rtl::OUStringToOString(aNewStr,osl_getThreadTextEncoding()); |
| const sal_Char* pChar = aOStr.getStr(); |
| sal_uInt16 nArraySize = static_cast< sal_uInt16 >( aOStr.getLength() ); |
| SbxDimArray* pArray = new SbxDimArray(SbxBYTE); |
| bool bIncIndex = (IsBaseIndexOne() && SbiRuntime::isVBAEnabled() ); |
| if(nArraySize) |
| { |
| if( bIncIndex ) |
| pArray->AddDim( 1, nArraySize ); |
| else |
| pArray->AddDim( 0, nArraySize-1 ); |
| } |
| else |
| { |
| pArray->unoAddDim( 0, -1 ); |
| } |
| |
| for( sal_uInt16 i=0; i< nArraySize; i++) |
| { |
| SbxVariable* pNew = new SbxVariable( SbxBYTE ); |
| pNew->PutByte(*pChar); |
| pChar++; |
| pNew->SetFlag( SBX_WRITE ); |
| short index = i; |
| if( bIncIndex ) |
| ++index; |
| pArray->Put( pNew, &index ); |
| } |
| |
| SbxVariableRef refVar = rPar.Get(0); |
| sal_uInt16 nFlags = refVar->GetFlags(); |
| refVar->ResetFlag( SBX_FIXED ); |
| refVar->PutObject( pArray ); |
| refVar->SetFlags( nFlags ); |
| refVar->SetParameters( NULL ); |
| return; |
| } |
| |
| rPar.Get(0)->PutString(aNewStr); |
| } |
| |
| |
| RTLFUNC(Beep) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 1 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| Sound::Beep(); |
| } |
| |
| RTLFUNC(Load) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if( rPar.Count() != 2 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| // Diesen Call einfach an das Object weiterreichen |
| SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject(); |
| if ( pObj ) |
| { |
| if( pObj->IsA( TYPE( SbUserFormModule ) ) ) |
| { |
| ((SbUserFormModule*)pObj)->Load(); |
| } |
| else if( pObj->IsA( TYPE( SbxObject ) ) ) |
| { |
| SbxVariable* pVar = ((SbxObject*)pObj)-> |
| Find( String( RTL_CONSTASCII_USTRINGPARAM("Load") ), SbxCLASS_METHOD ); |
| if( pVar ) |
| pVar->GetInteger(); |
| } |
| } |
| } |
| |
| RTLFUNC(Unload) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| rPar.Get(0)->PutEmpty(); |
| if( rPar.Count() != 2 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| // Diesen Call einfach an das Object weitereichen |
| SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject(); |
| if ( pObj ) |
| { |
| if( pObj->IsA( TYPE( SbUserFormModule ) ) ) |
| { |
| SbUserFormModule* pFormModule = ( SbUserFormModule* )pObj; |
| pFormModule->Unload(); |
| } |
| else if( pObj->IsA( TYPE( SbxObject ) ) ) |
| { |
| SbxVariable* pVar = ((SbxObject*)pObj)-> |
| Find( String( RTL_CONSTASCII_USTRINGPARAM("Unload") ), SbxCLASS_METHOD ); |
| if( pVar ) |
| pVar->GetInteger(); |
| } |
| } |
| } |
| |
| RTLFUNC(LoadPicture) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if( rPar.Count() != 2 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| String aFileURL = getFullPath( rPar.Get(1)->GetString() ); |
| SvStream* pStream = utl::UcbStreamHelper::CreateStream( aFileURL, STREAM_READ ); |
| if( pStream != NULL ) |
| { |
| Bitmap aBmp; |
| ReadDIB(aBmp, *pStream, true); |
| Graphic aGraphic(aBmp); |
| |
| SbxObjectRef xRef = new SbStdPicture; |
| ((SbStdPicture*)(SbxObject*)xRef)->SetGraphic( aGraphic ); |
| rPar.Get(0)->PutObject( xRef ); |
| } |
| delete pStream; |
| } |
| |
| RTLFUNC(SavePicture) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| rPar.Get(0)->PutEmpty(); |
| if( rPar.Count() != 3 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject(); |
| if( pObj->IsA( TYPE( SbStdPicture ) ) ) |
| { |
| SvFileStream aOStream( rPar.Get(2)->GetString(), STREAM_WRITE | STREAM_TRUNC ); |
| Graphic aGraphic = ((SbStdPicture*)pObj)->GetGraphic(); |
| aOStream << aGraphic; |
| } |
| } |
| |
| |
| //----------------------------------------------------------------------------------------- |
| |
| RTLFUNC(AboutStarBasic) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| (void)rPar; |
| } |
| |
| RTLFUNC(MsgBox) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| static const WinBits nStyleMap[] = |
| { |
| WB_OK, // MB_OK |
| WB_OK_CANCEL, // MB_OKCANCEL |
| WB_ABORT_RETRY_IGNORE, // MB_ABORTRETRYIGNORE |
| WB_YES_NO_CANCEL, // MB_YESNOCANCEL |
| WB_YES_NO, // MB_YESNO |
| WB_RETRY_CANCEL // MB_RETRYCANCEL |
| }; |
| static const sal_Int16 nButtonMap[] = |
| { |
| 2, // #define RET_CANCEL sal_False |
| 1, // #define RET_OK sal_True |
| 6, // #define RET_YES 2 |
| 7, // #define RET_NO 3 |
| 4 // #define RET_RETRY 4 |
| }; |
| |
| |
| sal_uInt16 nArgCount = (sal_uInt16)rPar.Count(); |
| if( nArgCount < 2 || nArgCount > 6 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| WinBits nWinBits; |
| WinBits nType = 0; // MB_OK |
| if( nArgCount >= 3 ) |
| nType = (WinBits)rPar.Get(2)->GetInteger(); |
| WinBits nStyle = nType; |
| nStyle &= 15; // Bits 4-16 loeschen |
| if( nStyle > 5 ) |
| nStyle = 0; |
| |
| nWinBits = nStyleMap[ nStyle ]; |
| |
| WinBits nWinDefBits; |
| nWinDefBits = (WB_DEF_OK | WB_DEF_RETRY | WB_DEF_YES); |
| if( nType & 256 ) |
| { |
| if( nStyle == 5 ) |
| nWinDefBits = WB_DEF_CANCEL; |
| else if( nStyle == 2 ) |
| nWinDefBits = WB_DEF_RETRY; |
| else |
| nWinDefBits = (WB_DEF_CANCEL | WB_DEF_RETRY | WB_DEF_NO); |
| } |
| else if( nType & 512 ) |
| { |
| if( nStyle == 2) |
| nWinDefBits = WB_DEF_IGNORE; |
| else |
| nWinDefBits = WB_DEF_CANCEL; |
| } |
| else if( nStyle == 2) |
| nWinDefBits = WB_DEF_CANCEL; |
| nWinBits |= nWinDefBits; |
| |
| String aMsg = rPar.Get(1)->GetString(); |
| String aTitle; |
| if( nArgCount >= 4 ) |
| aTitle = rPar.Get(3)->GetString(); |
| else |
| aTitle = GetpApp()->GetAppName(); |
| |
| nType &= (16+32+64); |
| MessBox* pBox = 0; |
| Window* pParent = GetpApp()->GetDefDialogParent(); |
| switch( nType ) |
| { |
| case 16: |
| pBox = new ErrorBox( pParent, nWinBits, aMsg ); |
| break; |
| case 32: |
| pBox = new QueryBox( pParent, nWinBits, aMsg ); |
| break; |
| case 48: |
| pBox = new WarningBox( pParent, nWinBits, aMsg ); |
| break; |
| case 64: |
| pBox = new InfoBox( pParent, nWinBits, aMsg ); |
| break; |
| default: |
| pBox = new MessBox( pParent, nWinBits, aTitle, aMsg ); |
| } |
| pBox->SetText( aTitle ); |
| sal_uInt16 nRet = (sal_uInt16)pBox->Execute(); |
| if( nRet == sal_True ) |
| nRet = 1; |
| |
| sal_Int16 nMappedRet; |
| if( nStyle == 2 ) |
| { |
| nMappedRet = nRet; |
| if( nMappedRet == 0 ) |
| nMappedRet = 3; // Abort |
| } |
| else |
| nMappedRet = nButtonMap[ nRet ]; |
| |
| rPar.Get(0)->PutInteger( nMappedRet ); |
| delete pBox; |
| } |
| |
| RTLFUNC(SetAttr) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| rPar.Get(0)->PutEmpty(); |
| if ( rPar.Count() == 3 ) |
| { |
| String aStr = rPar.Get(1)->GetString(); |
| sal_Int16 nFlags = rPar.Get(2)->GetInteger(); |
| |
| // <-- UCB |
| if( hasUno() ) |
| { |
| com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); |
| if( xSFI.is() ) |
| { |
| try |
| { |
| sal_Bool bReadOnly = (nFlags & 0x0001) != 0; // ATTR_READONLY |
| xSFI->setReadOnly( aStr, bReadOnly ); |
| sal_Bool bHidden = (nFlags & 0x0002) != 0; // ATTR_HIDDEN |
| xSFI->setHidden( aStr, bHidden ); |
| } |
| catch( Exception & ) |
| { |
| StarBASIC::Error( ERRCODE_IO_GENERAL ); |
| } |
| } |
| } |
| else |
| // --> UCB |
| { |
| #ifdef _OLD_FILE_IMPL |
| // #57064 Bei virtuellen URLs den Real-Path extrahieren |
| DirEntry aEntry( aStr ); |
| String aFile = aEntry.GetFull(); |
| ByteString aByteFile( aFile, gsl_getSystemTextEncoding() ); |
| #ifdef WNT |
| if (!SetFileAttributes (aByteFile.GetBuffer(),(DWORD)nFlags)) |
| StarBASIC::Error(SbERR_FILE_NOT_FOUND); |
| #endif |
| #ifdef OS2 |
| FILESTATUS3 aFileStatus; |
| APIRET rc = DosQueryPathInfo(aByteFile.GetBuffer(),1, |
| &aFileStatus,sizeof(FILESTATUS3)); |
| if (!rc) |
| { |
| if (aFileStatus.attrFile != nFlags) |
| { |
| aFileStatus.attrFile = nFlags; |
| rc = DosSetPathInfo(aFile.GetStr(),1, |
| &aFileStatus,sizeof(FILESTATUS3),0); |
| if (rc) |
| StarBASIC::Error( SbERR_FILE_NOT_FOUND ); |
| } |
| } |
| else |
| StarBASIC::Error( SbERR_FILE_NOT_FOUND ); |
| #endif |
| #else |
| // Not implemented |
| #endif |
| } |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| |
| RTLFUNC(Reset) // JSM |
| { |
| (void)pBasic; |
| (void)bWrite; |
| (void)rPar; |
| |
| SbiIoSystem* pIO = pINST->GetIoSystem(); |
| if (pIO) |
| pIO->CloseAll(); |
| } |
| |
| RTLFUNC(DumpAllObjects) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| sal_uInt16 nArgCount = (sal_uInt16)rPar.Count(); |
| if( nArgCount < 2 || nArgCount > 3 ) |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| else if( !pBasic ) |
| StarBASIC::Error( SbERR_INTERNAL_ERROR ); |
| else |
| { |
| SbxObject* p = pBasic; |
| while( p->GetParent() ) |
| p = p->GetParent(); |
| SvFileStream aStrm( rPar.Get( 1 )->GetString(), |
| STREAM_WRITE | STREAM_TRUNC ); |
| p->Dump( aStrm, rPar.Get( 2 )->GetBool() ); |
| aStrm.Close(); |
| if( aStrm.GetError() != SVSTREAM_OK ) |
| StarBASIC::Error( SbERR_IO_ERROR ); |
| } |
| } |
| |
| |
| RTLFUNC(FileExists) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() == 2 ) |
| { |
| String aStr = rPar.Get(1)->GetString(); |
| sal_Bool bExists = sal_False; |
| |
| // <-- UCB |
| if( hasUno() ) |
| { |
| com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); |
| if( xSFI.is() ) |
| { |
| try |
| { |
| bExists = xSFI->exists( aStr ); |
| } |
| catch( Exception & ) |
| { |
| StarBASIC::Error( ERRCODE_IO_GENERAL ); |
| } |
| } |
| } |
| else |
| // --> UCB |
| { |
| #ifdef _OLD_FILE_IMPL |
| DirEntry aEntry( aStr ); |
| bExists = aEntry.Exists(); |
| #else |
| DirectoryItem aItem; |
| FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( aStr ), aItem ); |
| bExists = (nRet == FileBase::E_None); |
| #endif |
| } |
| rPar.Get(0)->PutBool( bExists ); |
| } |
| else |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| } |
| |
| RTLFUNC(Partition) |
| { |
| (void)pBasic; |
| (void)bWrite; |
| |
| if ( rPar.Count() != 5 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| sal_Int32 nNumber = rPar.Get(1)->GetLong(); |
| sal_Int32 nStart = rPar.Get(2)->GetLong(); |
| sal_Int32 nStop = rPar.Get(3)->GetLong(); |
| sal_Int32 nInterval = rPar.Get(4)->GetLong(); |
| |
| if( nStart < 0 || nStop <= nStart || nInterval < 1 ) |
| { |
| StarBASIC::Error( SbERR_BAD_ARGUMENT ); |
| return; |
| } |
| |
| // the Partition function inserts leading spaces before lowervalue and uppervalue |
| // so that they both have the same number of characters as the string |
| // representation of the value (Stop + 1). This ensures that if you use the output |
| // of the Partition function with several values of Number, the resulting text |
| // will be handled properly during any subsequent sort operation. |
| |
| // calculate the maximun number of characters before lowervalue and uppervalue |
| ::rtl::OUString aBeforeStart = ::rtl::OUString::valueOf( nStart - 1 ); |
| ::rtl::OUString aAfterStop = ::rtl::OUString::valueOf( nStop + 1 ); |
| sal_Int32 nLen1 = aBeforeStart.getLength(); |
| sal_Int32 nLen2 = aAfterStop.getLength(); |
| sal_Int32 nLen = nLen1 >= nLen2 ? nLen1:nLen2; |
| |
| ::rtl::OUStringBuffer aRetStr( nLen * 2 + 1); |
| ::rtl::OUString aLowerValue; |
| ::rtl::OUString aUpperValue; |
| if( nNumber < nStart ) |
| { |
| aUpperValue = aBeforeStart; |
| } |
| else if( nNumber > nStop ) |
| { |
| aLowerValue = aAfterStop; |
| } |
| else |
| { |
| sal_Int32 nLowerValue = nNumber; |
| sal_Int32 nUpperValue = nLowerValue; |
| if( nInterval > 1 ) |
| { |
| nLowerValue = ((( nNumber - nStart ) / nInterval ) * nInterval ) + nStart; |
| nUpperValue = nLowerValue + nInterval - 1; |
| } |
| |
| aLowerValue = ::rtl::OUString::valueOf( nLowerValue ); |
| aUpperValue = ::rtl::OUString::valueOf( nUpperValue ); |
| } |
| |
| nLen1 = aLowerValue.getLength(); |
| nLen2 = aUpperValue.getLength(); |
| |
| if( nLen > nLen1 ) |
| { |
| // appending the leading spaces for the lowervalue |
| for ( sal_Int32 i= (nLen - nLen1) ; i > 0; --i ) |
| aRetStr.appendAscii(" "); |
| } |
| aRetStr.append( aLowerValue ).appendAscii(":"); |
| if( nLen > nLen2 ) |
| { |
| // appending the leading spaces for the uppervalue |
| for ( sal_Int32 i= (nLen - nLen2) ; i > 0; --i ) |
| aRetStr.appendAscii(" "); |
| } |
| aRetStr.append( aUpperValue ); |
| rPar.Get(0)->PutString( String(aRetStr.makeStringAndClear()) ); |
| } |