1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_basic.hxx" 30 31 32 #include <tools/date.hxx> 33 #include <basic/sbxvar.hxx> 34 #ifndef _VOS_PROCESS_HXX 35 #include <vos/process.hxx> 36 #endif 37 #include <vcl/svapp.hxx> 38 #include <vcl/settings.hxx> 39 #include <vcl/sound.hxx> 40 #include <tools/wintypes.hxx> 41 #include <vcl/msgbox.hxx> 42 #include <basic/sbx.hxx> 43 #include <svl/zforlist.hxx> 44 #include <rtl/math.hxx> 45 #include <tools/urlobj.hxx> 46 #include <osl/time.h> 47 #include <unotools/charclass.hxx> 48 #include <unotools/ucbstreamhelper.hxx> 49 #include <tools/wldcrd.hxx> 50 #include <i18npool/lang.h> 51 52 #include "runtime.hxx" 53 #include "sbunoobj.hxx" 54 #ifdef WNT 55 #include <tools/prewin.h> 56 #include "winbase.h" 57 #include <tools/postwin.h> 58 #ifndef _FSYS_HXX //autogen 59 #include <tools/fsys.hxx> 60 #endif 61 #else 62 #include <osl/file.hxx> 63 #endif 64 #include "errobject.hxx" 65 66 #ifdef _USE_UNO 67 #include <comphelper/processfactory.hxx> 68 69 #include <com/sun/star/uno/Sequence.hxx> 70 #include <com/sun/star/util/DateTime.hpp> 71 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 72 #include <com/sun/star/lang/Locale.hpp> 73 #include <com/sun/star/ucb/XSimpleFileAccess3.hpp> 74 #include <com/sun/star/io/XInputStream.hpp> 75 #include <com/sun/star/io/XOutputStream.hpp> 76 #include <com/sun/star/io/XStream.hpp> 77 #include <com/sun/star/io/XSeekable.hpp> 78 79 using namespace comphelper; 80 using namespace osl; 81 using namespace com::sun::star::uno; 82 using namespace com::sun::star::lang; 83 using namespace com::sun::star::ucb; 84 using namespace com::sun::star::io; 85 using namespace com::sun::star::frame; 86 87 #endif /* _USE_UNO */ 88 89 //#define _ENABLE_CUR_DIR 90 91 #include "stdobj.hxx" 92 #include <basic/sbstdobj.hxx> 93 #include "rtlproto.hxx" 94 #include "basrid.hxx" 95 #include "image.hxx" 96 #include "sb.hrc" 97 #include "iosys.hxx" 98 #include "ddectrl.hxx" 99 #include <sbintern.hxx> 100 #include <basic/vbahelper.hxx> 101 102 #include <list> 103 #include <math.h> 104 #include <stdio.h> 105 #include <stdlib.h> 106 #include <ctype.h> 107 108 #if defined (WNT) || defined (OS2) 109 #include <direct.h> // _getdcwd get current work directory, _chdrive 110 #endif 111 112 #ifdef UNX 113 #include <errno.h> 114 #include <unistd.h> 115 #endif 116 117 #ifdef WNT 118 #include <io.h> 119 #endif 120 121 #include <basic/sbobjmod.hxx> 122 123 // from source/classes/sbxmod.cxx 124 Reference< XModel > getDocumentModel( StarBASIC* ); 125 126 static void FilterWhiteSpace( String& rStr ) 127 { 128 rStr.EraseAllChars( ' ' ); 129 rStr.EraseAllChars( '\t' ); 130 rStr.EraseAllChars( '\n' ); 131 rStr.EraseAllChars( '\r' ); 132 } 133 134 static long GetDayDiff( const Date& rDate ) 135 { 136 Date aRefDate( 1,1,1900 ); 137 long nDiffDays; 138 if ( aRefDate > rDate ) 139 { 140 nDiffDays = (long)(aRefDate - rDate); 141 nDiffDays *= -1; 142 } 143 else 144 nDiffDays = (long)(rDate - aRefDate); 145 nDiffDays += 2; // Anpassung VisualBasic: 1.Jan.1900 == 2 146 return nDiffDays; 147 } 148 149 static CharClass& GetCharClass( void ) 150 { 151 static sal_Bool bNeedsInit = sal_True; 152 static ::com::sun::star::lang::Locale aLocale; 153 if( bNeedsInit ) 154 { 155 bNeedsInit = sal_False; 156 aLocale = Application::GetSettings().GetLocale(); 157 } 158 static CharClass aCharClass( aLocale ); 159 return aCharClass; 160 } 161 162 static inline sal_Bool isFolder( FileStatus::Type aType ) 163 { 164 return ( aType == FileStatus::Directory || aType == FileStatus::Volume ); 165 } 166 167 168 //*** UCB file access *** 169 170 // Converts possibly relative paths to absolute paths 171 // according to the setting done by ChDir/ChDrive 172 String getFullPath( const String& aRelPath ) 173 { 174 ::rtl::OUString aFileURL; 175 176 // #80204 Try first if it already is a valid URL 177 INetURLObject aURLObj( aRelPath ); 178 aFileURL = aURLObj.GetMainURL( INetURLObject::NO_DECODE ); 179 180 if( !aFileURL.getLength() ) 181 { 182 File::getFileURLFromSystemPath( aRelPath, aFileURL ); 183 } 184 185 return aFileURL; 186 } 187 188 // Sets (virtual) current path for UCB file access 189 void implChDir( const String& aDir ) 190 { 191 (void)aDir; 192 // TODO 193 } 194 195 // Sets (virtual) current drive for UCB file access 196 void implChDrive( const String& aDrive ) 197 { 198 (void)aDrive; 199 // TODO 200 } 201 202 // Returns (virtual) current path for UCB file access 203 String implGetCurDir( void ) 204 { 205 String aRetStr; 206 207 return aRetStr; 208 } 209 210 // TODO: -> SbiGlobals 211 static com::sun::star::uno::Reference< XSimpleFileAccess3 > getFileAccess( void ) 212 { 213 static com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI; 214 if( !xSFI.is() ) 215 { 216 com::sun::star::uno::Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory(); 217 if( xSMgr.is() ) 218 { 219 xSFI = com::sun::star::uno::Reference< XSimpleFileAccess3 >( xSMgr->createInstance 220 ( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY ); 221 } 222 } 223 return xSFI; 224 } 225 226 227 228 // Properties und Methoden legen beim Get (bPut = sal_False) den Returnwert 229 // im Element 0 des Argv ab; beim Put (bPut = sal_True) wird der Wert aus 230 // Element 0 gespeichert. 231 232 // CreateObject( class ) 233 234 RTLFUNC(CreateObject) 235 { 236 (void)bWrite; 237 238 String aClass( rPar.Get( 1 )->GetString() ); 239 SbxObjectRef p = SbxBase::CreateObject( aClass ); 240 if( !p ) 241 StarBASIC::Error( SbERR_CANNOT_LOAD ); 242 else 243 { 244 // Convenience: BASIC als Parent eintragen 245 p->SetParent( pBasic ); 246 rPar.Get( 0 )->PutObject( p ); 247 } 248 } 249 250 // Error( n ) 251 252 RTLFUNC(Error) 253 { 254 (void)bWrite; 255 256 if( !pBasic ) 257 StarBASIC::Error( SbERR_INTERNAL_ERROR ); 258 else 259 { 260 String aErrorMsg; 261 SbError nErr = 0L; 262 sal_Int32 nCode = 0; 263 if( rPar.Count() == 1 ) 264 { 265 nErr = StarBASIC::GetErrBasic(); 266 aErrorMsg = StarBASIC::GetErrorMsg(); 267 } 268 else 269 { 270 nCode = rPar.Get( 1 )->GetLong(); 271 if( nCode > 65535L ) 272 StarBASIC::Error( SbERR_CONVERSION ); 273 else 274 nErr = StarBASIC::GetSfxFromVBError( (sal_uInt16)nCode ); 275 } 276 277 bool bVBA = SbiRuntime::isVBAEnabled(); 278 String tmpErrMsg; 279 if( bVBA && aErrorMsg.Len() > 0 ) 280 { 281 tmpErrMsg = aErrorMsg; 282 } 283 else 284 { 285 pBasic->MakeErrorText( nErr, aErrorMsg ); 286 tmpErrMsg = pBasic->GetErrorText(); 287 } 288 // If this rtlfunc 'Error' passed a errcode the same as the active Err Objects's 289 // current err then return the description for the error message if it is set 290 // ( complicated isn't it ? ) 291 if ( bVBA && rPar.Count() > 1 ) 292 { 293 com::sun::star::uno::Reference< ooo::vba::XErrObject > xErrObj( SbxErrObject::getUnoErrObject() ); 294 if ( xErrObj.is() && xErrObj->getNumber() == nCode && xErrObj->getDescription().getLength() ) 295 tmpErrMsg = xErrObj->getDescription(); 296 } 297 rPar.Get( 0 )->PutString( tmpErrMsg ); 298 } 299 } 300 301 // Sinus 302 303 RTLFUNC(Sin) 304 { 305 (void)pBasic; 306 (void)bWrite; 307 308 if ( rPar.Count() < 2 ) 309 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 310 else 311 { 312 SbxVariableRef pArg = rPar.Get( 1 ); 313 rPar.Get( 0 )->PutDouble( sin( pArg->GetDouble() ) ); 314 } 315 } 316 317 // Cosinus 318 319 RTLFUNC(Cos) 320 { 321 (void)pBasic; 322 (void)bWrite; 323 324 if ( rPar.Count() < 2 ) 325 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 326 else 327 { 328 SbxVariableRef pArg = rPar.Get( 1 ); 329 rPar.Get( 0 )->PutDouble( cos( pArg->GetDouble() ) ); 330 } 331 } 332 333 // Atn 334 335 RTLFUNC(Atn) 336 { 337 (void)pBasic; 338 (void)bWrite; 339 340 if ( rPar.Count() < 2 ) 341 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 342 else 343 { 344 SbxVariableRef pArg = rPar.Get( 1 ); 345 rPar.Get( 0 )->PutDouble( atan( pArg->GetDouble() ) ); 346 } 347 } 348 349 350 351 RTLFUNC(Abs) 352 { 353 (void)pBasic; 354 (void)bWrite; 355 356 if ( rPar.Count() < 2 ) 357 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 358 else 359 { 360 SbxVariableRef pArg = rPar.Get( 1 ); 361 rPar.Get( 0 )->PutDouble( fabs( pArg->GetDouble() ) ); 362 } 363 } 364 365 366 RTLFUNC(Asc) 367 { 368 (void)pBasic; 369 (void)bWrite; 370 371 if ( rPar.Count() < 2 ) 372 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 373 else 374 { 375 SbxVariableRef pArg = rPar.Get( 1 ); 376 String aStr( pArg->GetString() ); 377 if ( aStr.Len() == 0 ) 378 { 379 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 380 rPar.Get(0)->PutEmpty(); 381 } 382 else 383 { 384 sal_Unicode aCh = aStr.GetBuffer()[0]; 385 rPar.Get(0)->PutLong( aCh ); 386 } 387 } 388 } 389 390 void implChr( SbxArray& rPar, bool bChrW ) 391 { 392 if ( rPar.Count() < 2 ) 393 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 394 else 395 { 396 SbxVariableRef pArg = rPar.Get( 1 ); 397 398 String aStr; 399 if( !bChrW && SbiRuntime::isVBAEnabled() ) 400 { 401 sal_Char c = (sal_Char)pArg->GetByte(); 402 ByteString s( c ); 403 aStr = String( s, gsl_getSystemTextEncoding() ); 404 } 405 else 406 { 407 sal_Unicode aCh = (sal_Unicode)pArg->GetUShort(); 408 aStr = String( aCh ); 409 } 410 rPar.Get(0)->PutString( aStr ); 411 } 412 } 413 414 RTLFUNC(Chr) 415 { 416 (void)pBasic; 417 (void)bWrite; 418 419 bool bChrW = false; 420 implChr( rPar, bChrW ); 421 } 422 423 RTLFUNC(ChrW) 424 { 425 (void)pBasic; 426 (void)bWrite; 427 428 bool bChrW = true; 429 implChr( rPar, bChrW ); 430 } 431 432 433 #ifdef UNX 434 #define _MAX_PATH 260 435 #define _PATH_INCR 250 436 #endif 437 438 RTLFUNC(CurDir) 439 { 440 (void)pBasic; 441 (void)bWrite; 442 443 // #57064 Obwohl diese Funktion nicht mit DirEntry arbeitet, ist sie von 444 // der Anpassung an virtuelle URLs nich betroffen, da bei Nutzung der 445 // DirEntry-Funktionalitaet keine Moeglichkeit besteht, das aktuelle so 446 // zu ermitteln, dass eine virtuelle URL geliefert werden koennte. 447 448 // rPar.Get(0)->PutEmpty(); 449 #if defined (WNT) || defined (OS2) 450 int nCurDir = 0; // Current dir // JSM 451 if ( rPar.Count() == 2 ) 452 { 453 String aDrive = rPar.Get(1)->GetString(); 454 if ( aDrive.Len() != 1 ) 455 { 456 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 457 return; 458 } 459 else 460 { 461 nCurDir = (int)aDrive.GetBuffer()[0]; 462 if ( !isalpha( nCurDir ) ) 463 { 464 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 465 return; 466 } 467 else 468 nCurDir -= ( 'A' - 1 ); 469 } 470 } 471 char* pBuffer = new char[ _MAX_PATH ]; 472 #ifdef OS2 473 if( !nCurDir ) 474 nCurDir = _getdrive(); 475 #endif 476 if ( _getdcwd( nCurDir, pBuffer, _MAX_PATH ) != 0 ) 477 rPar.Get(0)->PutString( String::CreateFromAscii( pBuffer ) ); 478 else 479 StarBASIC::Error( SbERR_NO_DEVICE ); 480 delete [] pBuffer; 481 482 #elif defined( UNX ) 483 484 int nSize = _PATH_INCR; 485 char* pMem; 486 while( sal_True ) 487 { 488 pMem = new char[nSize]; 489 if( !pMem ) 490 { 491 StarBASIC::Error( SbERR_NO_MEMORY ); 492 return; 493 } 494 if( getcwd( pMem, nSize-1 ) != NULL ) 495 { 496 rPar.Get(0)->PutString( String::CreateFromAscii(pMem) ); 497 delete [] pMem; 498 return; 499 } 500 if( errno != ERANGE ) 501 { 502 StarBASIC::Error( SbERR_INTERNAL_ERROR ); 503 delete [] pMem; 504 return; 505 } 506 delete [] pMem; 507 nSize += _PATH_INCR; 508 }; 509 510 #endif 511 } 512 513 RTLFUNC(ChDir) // JSM 514 { 515 (void)bWrite; 516 517 rPar.Get(0)->PutEmpty(); 518 if (rPar.Count() == 2) 519 { 520 #ifdef _ENABLE_CUR_DIR 521 String aPath = rPar.Get(1)->GetString(); 522 sal_Bool bError = sal_False; 523 #ifdef WNT 524 // #55997 Laut MI hilft es bei File-URLs einen DirEntry zwischenzuschalten 525 // #40996 Harmoniert bei Verwendung der WIN32-Funktion nicht mit getdir 526 DirEntry aEntry( aPath ); 527 ByteString aFullPath( aEntry.GetFull(), gsl_getSystemTextEncoding() ); 528 if( chdir( aFullPath.GetBuffer()) ) 529 bError = sal_True; 530 #else 531 if (!DirEntry(aPath).SetCWD()) 532 bError = sal_True; 533 #endif 534 if( bError ) 535 StarBASIC::Error( SbERR_PATH_NOT_FOUND ); 536 #endif 537 // VBA: track current directory per document type (separately for Writer, Calc, Impress, etc.) 538 if( SbiRuntime::isVBAEnabled() ) 539 ::basic::vba::registerCurrentDirectory( getDocumentModel( pBasic ), rPar.Get(1)->GetString() ); 540 } 541 else 542 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 543 } 544 545 RTLFUNC(ChDrive) // JSM 546 { 547 (void)pBasic; 548 (void)bWrite; 549 550 rPar.Get(0)->PutEmpty(); 551 if (rPar.Count() == 2) 552 { 553 #ifdef _ENABLE_CUR_DIR 554 // Keine Laufwerke in Unix 555 #ifndef UNX 556 String aPar1 = rPar.Get(1)->GetString(); 557 558 #if defined (WNT) || defined (OS2) 559 if (aPar1.Len() > 0) 560 { 561 int nCurDrive = (int)aPar1.GetBuffer()[0]; ; 562 if ( !isalpha( nCurDrive ) ) 563 { 564 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 565 return; 566 } 567 else 568 nCurDrive -= ( 'A' - 1 ); 569 if (_chdrive(nCurDrive)) 570 StarBASIC::Error( SbERR_NO_DEVICE ); 571 } 572 #endif 573 574 #endif 575 // #ifndef UNX 576 #endif 577 } 578 else 579 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 580 } 581 582 583 // Implementation of StepRENAME with UCB 584 void implStepRenameUCB( const String& aSource, const String& aDest ) 585 { 586 com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); 587 if( xSFI.is() ) 588 { 589 try 590 { 591 String aSourceFullPath = getFullPath( aSource ); 592 if( !xSFI->exists( aSourceFullPath ) ) 593 { 594 StarBASIC::Error( SbERR_FILE_NOT_FOUND ); 595 return; 596 } 597 598 String aDestFullPath = getFullPath( aDest ); 599 if( xSFI->exists( aDestFullPath ) ) 600 StarBASIC::Error( SbERR_FILE_EXISTS ); 601 else 602 xSFI->move( aSourceFullPath, aDestFullPath ); 603 } 604 catch( Exception & ) 605 { 606 StarBASIC::Error( SbERR_FILE_NOT_FOUND ); 607 } 608 } 609 } 610 611 // Implementation of StepRENAME with OSL 612 void implStepRenameOSL( const String& aSource, const String& aDest ) 613 { 614 FileBase::RC nRet = File::move( getFullPathUNC( aSource ), getFullPathUNC( aDest ) ); 615 if( nRet != FileBase::E_None ) 616 { 617 StarBASIC::Error( SbERR_PATH_NOT_FOUND ); 618 } 619 } 620 621 RTLFUNC(FileCopy) // JSM 622 { 623 (void)pBasic; 624 (void)bWrite; 625 626 rPar.Get(0)->PutEmpty(); 627 if (rPar.Count() == 3) 628 { 629 String aSource = rPar.Get(1)->GetString(); 630 String aDest = rPar.Get(2)->GetString(); 631 // <-- UCB 632 if( hasUno() ) 633 { 634 com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); 635 if( xSFI.is() ) 636 { 637 try 638 { 639 xSFI->copy( getFullPath( aSource ), getFullPath( aDest ) ); 640 } 641 catch( Exception & ) 642 { 643 StarBASIC::Error( SbERR_PATH_NOT_FOUND ); 644 } 645 } 646 } 647 else 648 // --> UCB 649 { 650 #ifdef _OLD_FILE_IMPL 651 DirEntry aSourceDirEntry(aSource); 652 if (aSourceDirEntry.Exists()) 653 { 654 if (aSourceDirEntry.CopyTo(DirEntry(aDest),FSYS_ACTION_COPYFILE) != FSYS_ERR_OK) 655 StarBASIC::Error( SbERR_PATH_NOT_FOUND ); 656 } 657 else 658 StarBASIC::Error( SbERR_PATH_NOT_FOUND ); 659 #else 660 FileBase::RC nRet = File::copy( getFullPathUNC( aSource ), getFullPathUNC( aDest ) ); 661 if( nRet != FileBase::E_None ) 662 { 663 StarBASIC::Error( SbERR_PATH_NOT_FOUND ); 664 } 665 #endif 666 } 667 } 668 else 669 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 670 } 671 672 RTLFUNC(Kill) // JSM 673 { 674 (void)pBasic; 675 (void)bWrite; 676 677 rPar.Get(0)->PutEmpty(); 678 if (rPar.Count() == 2) 679 { 680 String aFileSpec = rPar.Get(1)->GetString(); 681 682 // <-- UCB 683 if( hasUno() ) 684 { 685 com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); 686 if( xSFI.is() ) 687 { 688 String aFullPath = getFullPath( aFileSpec ); 689 if( !xSFI->exists( aFullPath ) || xSFI->isFolder( aFullPath ) ) 690 { 691 StarBASIC::Error( SbERR_FILE_NOT_FOUND ); 692 return; 693 } 694 try 695 { 696 xSFI->kill( aFullPath ); 697 } 698 catch( Exception & ) 699 { 700 StarBASIC::Error( ERRCODE_IO_GENERAL ); 701 } 702 } 703 } 704 else 705 // --> UCB 706 { 707 #ifdef _OLD_FILE_IMPL 708 if(DirEntry(aFileSpec).Kill() != FSYS_ERR_OK) 709 StarBASIC::Error( SbERR_PATH_NOT_FOUND ); 710 #else 711 File::remove( getFullPathUNC( aFileSpec ) ); 712 #endif 713 } 714 } 715 else 716 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 717 } 718 719 RTLFUNC(MkDir) // JSM 720 { 721 (void)pBasic; 722 (void)bWrite; 723 724 rPar.Get(0)->PutEmpty(); 725 if (rPar.Count() == 2) 726 { 727 String aPath = rPar.Get(1)->GetString(); 728 729 // <-- UCB 730 if( hasUno() ) 731 { 732 com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); 733 if( xSFI.is() ) 734 { 735 try 736 { 737 xSFI->createFolder( getFullPath( aPath ) ); 738 } 739 catch( Exception & ) 740 { 741 StarBASIC::Error( ERRCODE_IO_GENERAL ); 742 } 743 } 744 } 745 else 746 // --> UCB 747 { 748 #ifdef _OLD_FILE_IMPL 749 if (!DirEntry(aPath).MakeDir()) 750 StarBASIC::Error( SbERR_PATH_NOT_FOUND ); 751 #else 752 Directory::create( getFullPathUNC( aPath ) ); 753 #endif 754 } 755 } 756 else 757 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 758 } 759 760 761 #ifndef _OLD_FILE_IMPL 762 763 // In OSL only empty directories can be deleted 764 // so we have to delete all files recursively 765 void implRemoveDirRecursive( const String& aDirPath ) 766 { 767 DirectoryItem aItem; 768 FileBase::RC nRet = DirectoryItem::get( aDirPath, aItem ); 769 sal_Bool bExists = (nRet == FileBase::E_None); 770 771 FileStatus aFileStatus( FileStatusMask_Type ); 772 nRet = aItem.getFileStatus( aFileStatus ); 773 FileStatus::Type aType = aFileStatus.getFileType(); 774 sal_Bool bFolder = isFolder( aType ); 775 776 if( !bExists || !bFolder ) 777 { 778 StarBASIC::Error( SbERR_PATH_NOT_FOUND ); 779 return; 780 } 781 782 Directory aDir( aDirPath ); 783 nRet = aDir.open(); 784 if( nRet != FileBase::E_None ) 785 { 786 StarBASIC::Error( SbERR_PATH_NOT_FOUND ); 787 return; 788 } 789 790 for( ;; ) 791 { 792 DirectoryItem aItem2; 793 nRet = aDir.getNextItem( aItem2 ); 794 if( nRet != FileBase::E_None ) 795 break; 796 797 // Handle flags 798 FileStatus aFileStatus2( FileStatusMask_Type | FileStatusMask_FileURL ); 799 nRet = aItem2.getFileStatus( aFileStatus2 ); 800 ::rtl::OUString aPath = aFileStatus2.getFileURL(); 801 802 // Directory? 803 FileStatus::Type aType2 = aFileStatus2.getFileType(); 804 sal_Bool bFolder2 = isFolder( aType2 ); 805 if( bFolder2 ) 806 { 807 implRemoveDirRecursive( aPath ); 808 } 809 else 810 { 811 File::remove( aPath ); 812 } 813 } 814 nRet = aDir.close(); 815 816 nRet = Directory::remove( aDirPath ); 817 } 818 #endif 819 820 821 RTLFUNC(RmDir) // JSM 822 { 823 (void)pBasic; 824 (void)bWrite; 825 826 rPar.Get(0)->PutEmpty(); 827 if (rPar.Count() == 2) 828 { 829 String aPath = rPar.Get(1)->GetString(); 830 // <-- UCB 831 if( hasUno() ) 832 { 833 com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); 834 if( xSFI.is() ) 835 { 836 try 837 { 838 if( !xSFI->isFolder( aPath ) ) 839 { 840 StarBASIC::Error( SbERR_PATH_NOT_FOUND ); 841 return; 842 } 843 SbiInstance* pInst = pINST; 844 bool bCompatibility = ( pInst && pInst->IsCompatibility() ); 845 if( bCompatibility ) 846 { 847 Sequence< ::rtl::OUString > aContent = xSFI->getFolderContents( aPath, true ); 848 sal_Int32 nCount = aContent.getLength(); 849 if( nCount > 0 ) 850 { 851 StarBASIC::Error( SbERR_ACCESS_ERROR ); 852 return; 853 } 854 } 855 856 xSFI->kill( getFullPath( aPath ) ); 857 } 858 catch( Exception & ) 859 { 860 StarBASIC::Error( ERRCODE_IO_GENERAL ); 861 } 862 } 863 } 864 else 865 // --> UCB 866 { 867 #ifdef _OLD_FILE_IMPL 868 DirEntry aDirEntry(aPath); 869 if (aDirEntry.Kill() != FSYS_ERR_OK) 870 StarBASIC::Error( SbERR_PATH_NOT_FOUND ); 871 #else 872 implRemoveDirRecursive( getFullPathUNC( aPath ) ); 873 #endif 874 } 875 } 876 else 877 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 878 } 879 880 RTLFUNC(SendKeys) // JSM 881 { 882 (void)pBasic; 883 (void)bWrite; 884 885 rPar.Get(0)->PutEmpty(); 886 StarBASIC::Error(SbERR_NOT_IMPLEMENTED); 887 } 888 889 RTLFUNC(Exp) 890 { 891 (void)pBasic; 892 (void)bWrite; 893 894 if( rPar.Count() < 2 ) 895 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 896 else 897 { 898 double aDouble = rPar.Get( 1 )->GetDouble(); 899 aDouble = exp( aDouble ); 900 checkArithmeticOverflow( aDouble ); 901 rPar.Get( 0 )->PutDouble( aDouble ); 902 } 903 } 904 905 RTLFUNC(FileLen) 906 { 907 (void)pBasic; 908 (void)bWrite; 909 910 if ( rPar.Count() < 2 ) 911 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 912 else 913 { 914 SbxVariableRef pArg = rPar.Get( 1 ); 915 String aStr( pArg->GetString() ); 916 sal_Int32 nLen = 0; 917 // <-- UCB 918 if( hasUno() ) 919 { 920 com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); 921 if( xSFI.is() ) 922 { 923 try 924 { 925 nLen = xSFI->getSize( getFullPath( aStr ) ); 926 } 927 catch( Exception & ) 928 { 929 StarBASIC::Error( ERRCODE_IO_GENERAL ); 930 } 931 } 932 } 933 else 934 // --> UCB 935 { 936 #ifdef _OLD_FILE_IMPL 937 FileStat aStat = DirEntry( aStr ); 938 nLen = aStat.GetSize(); 939 #else 940 DirectoryItem aItem; 941 FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( aStr ), aItem ); 942 FileStatus aFileStatus( FileStatusMask_FileSize ); 943 nRet = aItem.getFileStatus( aFileStatus ); 944 nLen = (sal_Int32)aFileStatus.getFileSize(); 945 #endif 946 } 947 rPar.Get(0)->PutLong( (long)nLen ); 948 } 949 } 950 951 952 RTLFUNC(Hex) 953 { 954 (void)pBasic; 955 (void)bWrite; 956 957 if ( rPar.Count() < 2 ) 958 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 959 else 960 { 961 char aBuffer[16]; 962 SbxVariableRef pArg = rPar.Get( 1 ); 963 if ( pArg->IsInteger() ) 964 snprintf( aBuffer, sizeof(aBuffer), "%X", pArg->GetInteger() ); 965 else 966 snprintf( aBuffer, sizeof(aBuffer), "%lX", static_cast<long unsigned int>(pArg->GetLong()) ); 967 rPar.Get(0)->PutString( String::CreateFromAscii( aBuffer ) ); 968 } 969 } 970 971 // InStr( [start],string,string,[compare] ) 972 973 RTLFUNC(InStr) 974 { 975 (void)pBasic; 976 (void)bWrite; 977 978 sal_uIntPtr nArgCount = rPar.Count()-1; 979 if ( nArgCount < 2 ) 980 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 981 else 982 { 983 sal_uInt16 nStartPos = 1; 984 985 sal_uInt16 nFirstStringPos = 1; 986 if ( nArgCount >= 3 ) 987 { 988 sal_Int32 lStartPos = rPar.Get(1)->GetLong(); 989 if( lStartPos <= 0 || lStartPos > 0xffff ) 990 { 991 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 992 lStartPos = 1; 993 } 994 nStartPos = (sal_uInt16)lStartPos; 995 nFirstStringPos++; 996 } 997 998 SbiInstance* pInst = pINST; 999 int bTextMode; 1000 bool bCompatibility = ( pInst && pInst->IsCompatibility() ); 1001 if( bCompatibility ) 1002 { 1003 SbiRuntime* pRT = pInst ? pInst->pRun : NULL; 1004 bTextMode = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : sal_False; 1005 } 1006 else 1007 { 1008 bTextMode = 1;; 1009 } 1010 if ( nArgCount == 4 ) 1011 bTextMode = rPar.Get(4)->GetInteger(); 1012 1013 sal_uInt16 nPos; 1014 const String& rToken = rPar.Get(nFirstStringPos+1)->GetString(); 1015 1016 // #97545 Always find empty string 1017 if( !rToken.Len() ) 1018 { 1019 nPos = nStartPos; 1020 } 1021 else 1022 { 1023 if( !bTextMode ) 1024 { 1025 const String& rStr1 = rPar.Get(nFirstStringPos)->GetString(); 1026 1027 nPos = rStr1.Search( rToken, nStartPos-1 ); 1028 if ( nPos == STRING_NOTFOUND ) 1029 nPos = 0; 1030 else 1031 nPos++; 1032 } 1033 else 1034 { 1035 String aStr1 = rPar.Get(nFirstStringPos)->GetString(); 1036 String aToken = rToken; 1037 1038 aStr1.ToUpperAscii(); 1039 aToken.ToUpperAscii(); 1040 1041 nPos = aStr1.Search( aToken, nStartPos-1 ); 1042 if ( nPos == STRING_NOTFOUND ) 1043 nPos = 0; 1044 else 1045 nPos++; 1046 } 1047 } 1048 rPar.Get(0)->PutLong( nPos ); 1049 } 1050 } 1051 1052 1053 // InstrRev(string1, string2[, start[, compare]]) 1054 1055 RTLFUNC(InStrRev) 1056 { 1057 (void)pBasic; 1058 (void)bWrite; 1059 1060 sal_uIntPtr nArgCount = rPar.Count()-1; 1061 if ( nArgCount < 2 ) 1062 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1063 else 1064 { 1065 String aStr1 = rPar.Get(1)->GetString(); 1066 String aToken = rPar.Get(2)->GetString(); 1067 1068 sal_Int32 lStartPos = -1; 1069 if ( nArgCount >= 3 ) 1070 { 1071 lStartPos = rPar.Get(3)->GetLong(); 1072 if( (lStartPos <= 0 && lStartPos != -1) || lStartPos > 0xffff ) 1073 { 1074 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1075 lStartPos = -1; 1076 } 1077 } 1078 1079 SbiInstance* pInst = pINST; 1080 int bTextMode; 1081 bool bCompatibility = ( pInst && pInst->IsCompatibility() ); 1082 if( bCompatibility ) 1083 { 1084 SbiRuntime* pRT = pInst ? pInst->pRun : NULL; 1085 bTextMode = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : sal_False; 1086 } 1087 else 1088 { 1089 bTextMode = 1;; 1090 } 1091 if ( nArgCount == 4 ) 1092 bTextMode = rPar.Get(4)->GetInteger(); 1093 1094 sal_uInt16 nStrLen = aStr1.Len(); 1095 sal_uInt16 nStartPos = lStartPos == -1 ? nStrLen : (sal_uInt16)lStartPos; 1096 1097 sal_uInt16 nPos = 0; 1098 if( nStartPos <= nStrLen ) 1099 { 1100 sal_uInt16 nTokenLen = aToken.Len(); 1101 if( !nTokenLen ) 1102 { 1103 // Always find empty string 1104 nPos = nStartPos; 1105 } 1106 else if( nStrLen > 0 ) 1107 { 1108 if( !bTextMode ) 1109 { 1110 ::rtl::OUString aOUStr1 ( aStr1 ); 1111 ::rtl::OUString aOUToken( aToken ); 1112 sal_Int32 nRet = aOUStr1.lastIndexOf( aOUToken, nStartPos ); 1113 if( nRet == -1 ) 1114 nPos = 0; 1115 else 1116 nPos = (sal_uInt16)nRet + 1; 1117 } 1118 else 1119 { 1120 aStr1.ToUpperAscii(); 1121 aToken.ToUpperAscii(); 1122 1123 ::rtl::OUString aOUStr1 ( aStr1 ); 1124 ::rtl::OUString aOUToken( aToken ); 1125 sal_Int32 nRet = aOUStr1.lastIndexOf( aOUToken, nStartPos ); 1126 1127 if( nRet == -1 ) 1128 nPos = 0; 1129 else 1130 nPos = (sal_uInt16)nRet + 1; 1131 } 1132 } 1133 } 1134 rPar.Get(0)->PutLong( nPos ); 1135 } 1136 } 1137 1138 1139 /* 1140 Int( 2.8 ) = 2.0 1141 Int( -2.8 ) = -3.0 1142 Fix( 2.8 ) = 2.0 1143 Fix( -2.8 ) = -2.0 <- !! 1144 */ 1145 1146 RTLFUNC(Int) 1147 { 1148 (void)pBasic; 1149 (void)bWrite; 1150 1151 if ( rPar.Count() < 2 ) 1152 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1153 else 1154 { 1155 SbxVariableRef pArg = rPar.Get( 1 ); 1156 double aDouble= pArg->GetDouble(); 1157 /* 1158 floor( 2.8 ) = 2.0 1159 floor( -2.8 ) = -3.0 1160 */ 1161 aDouble = floor( aDouble ); 1162 rPar.Get(0)->PutDouble( aDouble ); 1163 } 1164 } 1165 1166 1167 1168 RTLFUNC(Fix) 1169 { 1170 (void)pBasic; 1171 (void)bWrite; 1172 1173 if ( rPar.Count() < 2 ) 1174 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1175 else 1176 { 1177 SbxVariableRef pArg = rPar.Get( 1 ); 1178 double aDouble = pArg->GetDouble(); 1179 if ( aDouble >= 0.0 ) 1180 aDouble = floor( aDouble ); 1181 else 1182 aDouble = ceil( aDouble ); 1183 rPar.Get(0)->PutDouble( aDouble ); 1184 } 1185 } 1186 1187 1188 RTLFUNC(LCase) 1189 { 1190 (void)pBasic; 1191 (void)bWrite; 1192 1193 if ( rPar.Count() < 2 ) 1194 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1195 else 1196 { 1197 CharClass& rCharClass = GetCharClass(); 1198 String aStr( rPar.Get(1)->GetString() ); 1199 rCharClass.toLower( aStr ); 1200 rPar.Get(0)->PutString( aStr ); 1201 } 1202 } 1203 1204 RTLFUNC(Left) 1205 { 1206 (void)pBasic; 1207 (void)bWrite; 1208 1209 if ( rPar.Count() < 3 ) 1210 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1211 else 1212 { 1213 String aStr( rPar.Get(1)->GetString() ); 1214 sal_Int32 lResultLen = rPar.Get(2)->GetLong(); 1215 if( lResultLen > 0xffff ) 1216 { 1217 lResultLen = 0xffff; 1218 } 1219 else if( lResultLen < 0 ) 1220 { 1221 lResultLen = 0; 1222 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1223 } 1224 aStr.Erase( (sal_uInt16)lResultLen ); 1225 rPar.Get(0)->PutString( aStr ); 1226 } 1227 } 1228 1229 RTLFUNC(Log) 1230 { 1231 (void)pBasic; 1232 (void)bWrite; 1233 1234 if ( rPar.Count() < 2 ) 1235 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1236 else 1237 { 1238 double aArg = rPar.Get(1)->GetDouble(); 1239 if ( aArg > 0 ) 1240 { 1241 double d = log( aArg ); 1242 checkArithmeticOverflow( d ); 1243 rPar.Get( 0 )->PutDouble( d ); 1244 } 1245 else 1246 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1247 } 1248 } 1249 1250 RTLFUNC(LTrim) 1251 { 1252 (void)pBasic; 1253 (void)bWrite; 1254 1255 if ( rPar.Count() < 2 ) 1256 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1257 else 1258 { 1259 String aStr( rPar.Get(1)->GetString() ); 1260 aStr.EraseLeadingChars(); 1261 rPar.Get(0)->PutString( aStr ); 1262 } 1263 } 1264 1265 1266 // Mid( String, nStart, nLength ) 1267 1268 RTLFUNC(Mid) 1269 { 1270 (void)pBasic; 1271 (void)bWrite; 1272 1273 sal_uIntPtr nArgCount = rPar.Count()-1; 1274 if ( nArgCount < 2 ) 1275 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1276 else 1277 { 1278 // #23178: Funktionalitaet von Mid$ als Anweisung nachbilden, indem 1279 // als weiterer (4.) Parameter ein Ersetzungsstring aufgenommen wird. 1280 // Anders als im Original kann in dieser Variante der 3. Parameter 1281 // nLength nicht weggelassen werden. Ist ueber bWrite schon vorgesehen. 1282 if( nArgCount == 4 ) 1283 bWrite = sal_True; 1284 1285 String aArgStr = rPar.Get(1)->GetString(); 1286 sal_uInt16 nStartPos = (sal_uInt16)(rPar.Get(2)->GetLong() ); 1287 if ( nStartPos == 0 ) 1288 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1289 else 1290 { 1291 nStartPos--; 1292 sal_uInt16 nLen = 0xffff; 1293 bool bWriteNoLenParam = false; 1294 if ( nArgCount == 3 || bWrite ) 1295 { 1296 sal_Int32 n = rPar.Get(3)->GetLong(); 1297 if( bWrite && n == -1 ) 1298 bWriteNoLenParam = true; 1299 nLen = (sal_uInt16)n; 1300 } 1301 String aResultStr; 1302 if ( bWrite ) 1303 { 1304 SbiInstance* pInst = pINST; 1305 bool bCompatibility = ( pInst && pInst->IsCompatibility() ); 1306 if( bCompatibility ) 1307 { 1308 sal_uInt16 nArgLen = aArgStr.Len(); 1309 if( nStartPos + 1 > nArgLen ) 1310 { 1311 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1312 return; 1313 } 1314 1315 String aReplaceStr = rPar.Get(4)->GetString(); 1316 sal_uInt16 nReplaceStrLen = aReplaceStr.Len(); 1317 sal_uInt16 nReplaceLen; 1318 if( bWriteNoLenParam ) 1319 { 1320 nReplaceLen = nReplaceStrLen; 1321 } 1322 else 1323 { 1324 nReplaceLen = nLen; 1325 if( nReplaceLen > nReplaceStrLen ) 1326 nReplaceLen = nReplaceStrLen; 1327 } 1328 1329 sal_uInt16 nReplaceEndPos = nStartPos + nReplaceLen; 1330 if( nReplaceEndPos > nArgLen ) 1331 nReplaceLen -= (nReplaceEndPos - nArgLen); 1332 1333 aResultStr = aArgStr; 1334 sal_uInt16 nErase = nReplaceLen; 1335 aResultStr.Erase( nStartPos, nErase ); 1336 aResultStr.Insert( aReplaceStr, 0, nReplaceLen, nStartPos ); 1337 } 1338 else 1339 { 1340 aResultStr = aArgStr; 1341 aResultStr.Erase( nStartPos, nLen ); 1342 aResultStr.Insert(rPar.Get(4)->GetString(),0,nLen,nStartPos); 1343 } 1344 1345 rPar.Get(1)->PutString( aResultStr ); 1346 } 1347 else 1348 { 1349 aResultStr = aArgStr.Copy( nStartPos, nLen ); 1350 rPar.Get(0)->PutString( aResultStr ); 1351 } 1352 } 1353 } 1354 } 1355 1356 RTLFUNC(Oct) 1357 { 1358 (void)pBasic; 1359 (void)bWrite; 1360 1361 if ( rPar.Count() < 2 ) 1362 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1363 else 1364 { 1365 char aBuffer[16]; 1366 SbxVariableRef pArg = rPar.Get( 1 ); 1367 if ( pArg->IsInteger() ) 1368 snprintf( aBuffer, sizeof(aBuffer), "%o", pArg->GetInteger() ); 1369 else 1370 snprintf( aBuffer, sizeof(aBuffer), "%lo", static_cast<long unsigned int>(pArg->GetLong()) ); 1371 rPar.Get(0)->PutString( String::CreateFromAscii( aBuffer ) ); 1372 } 1373 } 1374 1375 // Replace(expression, find, replace[, start[, count[, compare]]]) 1376 1377 RTLFUNC(Replace) 1378 { 1379 (void)pBasic; 1380 (void)bWrite; 1381 1382 sal_uIntPtr nArgCount = rPar.Count()-1; 1383 if ( nArgCount < 3 || nArgCount > 6 ) 1384 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1385 else 1386 { 1387 String aExpStr = rPar.Get(1)->GetString(); 1388 String aFindStr = rPar.Get(2)->GetString(); 1389 String aReplaceStr = rPar.Get(3)->GetString(); 1390 1391 sal_Int32 lStartPos = 1; 1392 if ( nArgCount >= 4 ) 1393 { 1394 if( rPar.Get(4)->GetType() != SbxEMPTY ) 1395 lStartPos = rPar.Get(4)->GetLong(); 1396 if( lStartPos < 1 || lStartPos > 0xffff ) 1397 { 1398 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1399 lStartPos = 1; 1400 } 1401 } 1402 1403 sal_Int32 lCount = -1; 1404 if( nArgCount >=5 ) 1405 { 1406 if( rPar.Get(5)->GetType() != SbxEMPTY ) 1407 lCount = rPar.Get(5)->GetLong(); 1408 if( lCount < -1 || lCount > 0xffff ) 1409 { 1410 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1411 lCount = -1; 1412 } 1413 } 1414 1415 SbiInstance* pInst = pINST; 1416 int bTextMode; 1417 bool bCompatibility = ( pInst && pInst->IsCompatibility() ); 1418 if( bCompatibility ) 1419 { 1420 SbiRuntime* pRT = pInst ? pInst->pRun : NULL; 1421 bTextMode = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : sal_False; 1422 } 1423 else 1424 { 1425 bTextMode = 1; 1426 } 1427 if ( nArgCount == 6 ) 1428 bTextMode = rPar.Get(6)->GetInteger(); 1429 1430 sal_uInt16 nExpStrLen = aExpStr.Len(); 1431 sal_uInt16 nFindStrLen = aFindStr.Len(); 1432 sal_uInt16 nReplaceStrLen = aReplaceStr.Len(); 1433 1434 if( lStartPos <= nExpStrLen ) 1435 { 1436 sal_uInt16 nPos = static_cast<sal_uInt16>( lStartPos - 1 ); 1437 sal_uInt16 nCounts = 0; 1438 while( lCount == -1 || lCount > nCounts ) 1439 { 1440 String aSrcStr( aExpStr ); 1441 if( bTextMode ) 1442 { 1443 aSrcStr.ToUpperAscii(); 1444 aFindStr.ToUpperAscii(); 1445 } 1446 nPos = aSrcStr.Search( aFindStr, nPos ); 1447 if( nPos != STRING_NOTFOUND ) 1448 { 1449 aExpStr.Replace( nPos, nFindStrLen, aReplaceStr ); 1450 nPos = nPos - nFindStrLen + nReplaceStrLen + 1; 1451 nCounts++; 1452 } 1453 else 1454 { 1455 break; 1456 } 1457 } 1458 } 1459 rPar.Get(0)->PutString( aExpStr.Copy( static_cast<sal_uInt16>(lStartPos - 1) ) ); 1460 } 1461 } 1462 1463 RTLFUNC(Right) 1464 { 1465 (void)pBasic; 1466 (void)bWrite; 1467 1468 if ( rPar.Count() < 3 ) 1469 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1470 else 1471 { 1472 const String& rStr = rPar.Get(1)->GetString(); 1473 sal_Int32 lResultLen = rPar.Get(2)->GetLong(); 1474 if( lResultLen > 0xffff ) 1475 { 1476 lResultLen = 0xffff; 1477 } 1478 else if( lResultLen < 0 ) 1479 { 1480 lResultLen = 0; 1481 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1482 } 1483 sal_uInt16 nResultLen = (sal_uInt16)lResultLen; 1484 sal_uInt16 nStrLen = rStr.Len(); 1485 if ( nResultLen > nStrLen ) 1486 nResultLen = nStrLen; 1487 String aResultStr = rStr.Copy( nStrLen-nResultLen ); 1488 rPar.Get(0)->PutString( aResultStr ); 1489 } 1490 } 1491 1492 RTLFUNC(RTL) 1493 { 1494 (void)pBasic; 1495 (void)bWrite; 1496 1497 rPar.Get( 0 )->PutObject( pBasic->getRTL() ); 1498 } 1499 1500 RTLFUNC(RTrim) 1501 { 1502 (void)pBasic; 1503 (void)bWrite; 1504 1505 if ( rPar.Count() < 2 ) 1506 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1507 else 1508 { 1509 String aStr( rPar.Get(1)->GetString() ); 1510 aStr.EraseTrailingChars(); 1511 rPar.Get(0)->PutString( aStr ); 1512 } 1513 } 1514 1515 RTLFUNC(Sgn) 1516 { 1517 (void)pBasic; 1518 (void)bWrite; 1519 1520 if ( rPar.Count() < 2 ) 1521 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1522 else 1523 { 1524 double aDouble = rPar.Get(1)->GetDouble(); 1525 sal_Int16 nResult = 0; 1526 if ( aDouble > 0 ) 1527 nResult = 1; 1528 else if ( aDouble < 0 ) 1529 nResult = -1; 1530 rPar.Get(0)->PutInteger( nResult ); 1531 } 1532 } 1533 1534 RTLFUNC(Space) 1535 { 1536 (void)pBasic; 1537 (void)bWrite; 1538 1539 if ( rPar.Count() < 2 ) 1540 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1541 else 1542 { 1543 String aStr; 1544 aStr.Fill( (sal_uInt16)(rPar.Get(1)->GetLong() )); 1545 rPar.Get(0)->PutString( aStr ); 1546 } 1547 } 1548 1549 RTLFUNC(Spc) 1550 { 1551 (void)pBasic; 1552 (void)bWrite; 1553 1554 if ( rPar.Count() < 2 ) 1555 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1556 else 1557 { 1558 String aStr; 1559 aStr.Fill( (sal_uInt16)(rPar.Get(1)->GetLong() )); 1560 rPar.Get(0)->PutString( aStr ); 1561 } 1562 } 1563 1564 RTLFUNC(Sqr) 1565 { 1566 (void)pBasic; 1567 (void)bWrite; 1568 1569 if ( rPar.Count() < 2 ) 1570 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1571 else 1572 { 1573 double aDouble = rPar.Get(1)->GetDouble(); 1574 if ( aDouble >= 0 ) 1575 rPar.Get(0)->PutDouble( sqrt( aDouble )); 1576 else 1577 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1578 } 1579 } 1580 1581 RTLFUNC(Str) 1582 { 1583 (void)pBasic; 1584 (void)bWrite; 1585 1586 if ( rPar.Count() < 2 ) 1587 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1588 else 1589 { 1590 String aStr; 1591 SbxVariableRef pArg = rPar.Get( 1 ); 1592 pArg->Format( aStr ); 1593 1594 // Numbers start with a space 1595 if( pArg->IsNumericRTL() ) 1596 { 1597 // Kommas durch Punkte ersetzen, damit es symmetrisch zu Val ist! 1598 aStr.SearchAndReplace( ',', '.' ); 1599 1600 SbiInstance* pInst = pINST; 1601 bool bCompatibility = ( pInst && pInst->IsCompatibility() ); 1602 if( bCompatibility ) 1603 { 1604 xub_StrLen nLen = aStr.Len(); 1605 1606 const sal_Unicode* pBuf = aStr.GetBuffer(); 1607 1608 bool bNeg = ( pBuf[0] == '-' ); 1609 sal_uInt16 iZeroSearch = 0; 1610 if( bNeg ) 1611 iZeroSearch++; 1612 1613 sal_uInt16 iNext = iZeroSearch + 1; 1614 if( pBuf[iZeroSearch] == '0' && nLen > iNext && pBuf[iNext] == '.' ) 1615 { 1616 aStr.Erase( iZeroSearch, 1 ); 1617 pBuf = aStr.GetBuffer(); 1618 } 1619 if( !bNeg ) 1620 aStr.Insert( ' ', 0 ); 1621 } 1622 else 1623 aStr.Insert( ' ', 0 ); 1624 } 1625 rPar.Get(0)->PutString( aStr ); 1626 } 1627 } 1628 1629 RTLFUNC(StrComp) 1630 { 1631 (void)pBasic; 1632 (void)bWrite; 1633 1634 if ( rPar.Count() < 3 ) 1635 { 1636 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1637 rPar.Get(0)->PutEmpty(); 1638 return; 1639 } 1640 const String& rStr1 = rPar.Get(1)->GetString(); 1641 const String& rStr2 = rPar.Get(2)->GetString(); 1642 1643 SbiInstance* pInst = pINST; 1644 sal_Int16 nTextCompare; 1645 bool bCompatibility = ( pInst && pInst->IsCompatibility() ); 1646 if( bCompatibility ) 1647 { 1648 SbiRuntime* pRT = pInst ? pInst->pRun : NULL; 1649 nTextCompare = pRT ? pRT->GetImageFlag( SBIMG_COMPARETEXT ) : sal_False; 1650 } 1651 else 1652 { 1653 nTextCompare = sal_True; 1654 } 1655 if ( rPar.Count() == 4 ) 1656 nTextCompare = rPar.Get(3)->GetInteger(); 1657 1658 if( !bCompatibility ) 1659 nTextCompare = !nTextCompare; 1660 1661 StringCompare aResult; 1662 sal_Int32 nRetValue = 0; 1663 if( nTextCompare ) 1664 { 1665 ::utl::TransliterationWrapper* pTransliterationWrapper = GetSbData()->pTransliterationWrapper; 1666 if( !pTransliterationWrapper ) 1667 { 1668 com::sun::star::uno::Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory(); 1669 pTransliterationWrapper = GetSbData()->pTransliterationWrapper = 1670 new ::utl::TransliterationWrapper( xSMgr, 1671 ::com::sun::star::i18n::TransliterationModules_IGNORE_CASE | 1672 ::com::sun::star::i18n::TransliterationModules_IGNORE_KANA | 1673 ::com::sun::star::i18n::TransliterationModules_IGNORE_WIDTH ); 1674 } 1675 1676 LanguageType eLangType = GetpApp()->GetSettings().GetLanguage(); 1677 pTransliterationWrapper->loadModuleIfNeeded( eLangType ); 1678 nRetValue = pTransliterationWrapper->compareString( rStr1, rStr2 ); 1679 } 1680 else 1681 { 1682 aResult = rStr1.CompareTo( rStr2 ); 1683 if ( aResult == COMPARE_LESS ) 1684 nRetValue = -1; 1685 else if ( aResult == COMPARE_GREATER ) 1686 nRetValue = 1; 1687 } 1688 1689 rPar.Get(0)->PutInteger( sal::static_int_cast< sal_Int16 >( nRetValue ) ); 1690 } 1691 1692 RTLFUNC(String) 1693 { 1694 (void)pBasic; 1695 (void)bWrite; 1696 1697 if ( rPar.Count() < 2 ) 1698 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1699 else 1700 { 1701 String aStr; 1702 sal_Unicode aFiller; 1703 sal_Int32 lCount = rPar.Get(1)->GetLong(); 1704 if( lCount < 0 || lCount > 0xffff ) 1705 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1706 sal_uInt16 nCount = (sal_uInt16)lCount; 1707 if( rPar.Get(2)->GetType() == SbxINTEGER ) 1708 aFiller = (sal_Unicode)rPar.Get(2)->GetInteger(); 1709 else 1710 { 1711 const String& rStr = rPar.Get(2)->GetString(); 1712 aFiller = rStr.GetBuffer()[0]; 1713 } 1714 aStr.Fill( nCount, aFiller ); 1715 rPar.Get(0)->PutString( aStr ); 1716 } 1717 } 1718 1719 RTLFUNC(Tan) 1720 { 1721 (void)pBasic; 1722 (void)bWrite; 1723 1724 if ( rPar.Count() < 2 ) 1725 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1726 else 1727 { 1728 SbxVariableRef pArg = rPar.Get( 1 ); 1729 rPar.Get( 0 )->PutDouble( tan( pArg->GetDouble() ) ); 1730 } 1731 } 1732 1733 RTLFUNC(UCase) 1734 { 1735 (void)pBasic; 1736 (void)bWrite; 1737 1738 if ( rPar.Count() < 2 ) 1739 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1740 else 1741 { 1742 CharClass& rCharClass = GetCharClass(); 1743 String aStr( rPar.Get(1)->GetString() ); 1744 rCharClass.toUpper( aStr ); 1745 rPar.Get(0)->PutString( aStr ); 1746 } 1747 } 1748 1749 1750 RTLFUNC(Val) 1751 { 1752 (void)pBasic; 1753 (void)bWrite; 1754 1755 if ( rPar.Count() < 2 ) 1756 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1757 else 1758 { 1759 double nResult = 0.0; 1760 char* pEndPtr; 1761 1762 String aStr( rPar.Get(1)->GetString() ); 1763 // lt. Mikkysoft bei Kommas abbrechen! 1764 // for( sal_uInt16 n=0; n < aStr.Len(); n++ ) 1765 // if( aStr[n] == ',' ) aStr[n] = '.'; 1766 1767 FilterWhiteSpace( aStr ); 1768 if ( aStr.GetBuffer()[0] == '&' && aStr.Len() > 1 ) 1769 { 1770 int nRadix = 10; 1771 char aChar = (char)aStr.GetBuffer()[1]; 1772 if ( aChar == 'h' || aChar == 'H' ) 1773 nRadix = 16; 1774 else if ( aChar == 'o' || aChar == 'O' ) 1775 nRadix = 8; 1776 if ( nRadix != 10 ) 1777 { 1778 ByteString aByteStr( aStr, gsl_getSystemTextEncoding() ); 1779 sal_Int16 nlResult = (sal_Int16)strtol( aByteStr.GetBuffer()+2, &pEndPtr, nRadix); 1780 nResult = (double)nlResult; 1781 } 1782 } 1783 else 1784 { 1785 // #57844 Lokalisierte Funktion benutzen 1786 nResult = ::rtl::math::stringToDouble( aStr, '.', ',', NULL, NULL ); 1787 checkArithmeticOverflow( nResult ); 1788 // ATL: nResult = strtod( aStr.GetStr(), &pEndPtr ); 1789 } 1790 1791 rPar.Get(0)->PutDouble( nResult ); 1792 } 1793 } 1794 1795 1796 // Helper functions for date conversion 1797 sal_Int16 implGetDateDay( double aDate ) 1798 { 1799 aDate -= 2.0; // normieren: 1.1.1900 => 0.0 1800 Date aRefDate( 1, 1, 1900 ); 1801 if ( aDate >= 0.0 ) 1802 { 1803 aDate = floor( aDate ); 1804 aRefDate += (sal_uIntPtr)aDate; 1805 } 1806 else 1807 { 1808 aDate = ceil( aDate ); 1809 aRefDate -= (sal_uIntPtr)(-1.0 * aDate); 1810 } 1811 1812 sal_Int16 nRet = (sal_Int16)( aRefDate.GetDay() ); 1813 return nRet; 1814 } 1815 1816 sal_Int16 implGetDateMonth( double aDate ) 1817 { 1818 Date aRefDate( 1,1,1900 ); 1819 long nDays = (long)aDate; 1820 nDays -= 2; // normieren: 1.1.1900 => 0.0 1821 aRefDate += nDays; 1822 sal_Int16 nRet = (sal_Int16)( aRefDate.GetMonth() ); 1823 return nRet; 1824 } 1825 1826 sal_Int16 implGetDateYear( double aDate ) 1827 { 1828 Date aRefDate( 1,1,1900 ); 1829 long nDays = (long) aDate; 1830 nDays -= 2; // normieren: 1.1.1900 => 0.0 1831 aRefDate += nDays; 1832 sal_Int16 nRet = (sal_Int16)( aRefDate.GetYear() ); 1833 return nRet; 1834 } 1835 1836 sal_Bool implDateSerial( sal_Int16 nYear, sal_Int16 nMonth, sal_Int16 nDay, double& rdRet ) 1837 { 1838 if ( nYear < 30 && SbiRuntime::isVBAEnabled() ) 1839 nYear += 2000; 1840 else if ( nYear < 100 ) 1841 nYear += 1900; 1842 Date aCurDate( nDay, nMonth, nYear ); 1843 if ((nYear < 100 || nYear > 9999) ) 1844 { 1845 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1846 return sal_False; 1847 } 1848 if ( !SbiRuntime::isVBAEnabled() ) 1849 { 1850 if ( (nMonth < 1 || nMonth > 12 )|| 1851 (nDay < 1 || nDay > 31 ) ) 1852 { 1853 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1854 return sal_False; 1855 } 1856 } 1857 else 1858 { 1859 // grab the year & month 1860 aCurDate = Date( 1, (( nMonth % 12 ) > 0 ) ? ( nMonth % 12 ) : 12 + ( nMonth % 12 ), nYear ); 1861 1862 // adjust year based on month value 1863 // e.g. 2000, 0, xx = 1999, 12, xx ( or December of the previous year ) 1864 // 2000, 13, xx = 2001, 1, xx ( or January of the following year ) 1865 if( ( nMonth < 1 ) || ( nMonth > 12 ) ) 1866 { 1867 // inacurrate around leap year, don't use days to calculate, 1868 // just modify the months directory 1869 sal_Int16 nYearAdj = ( nMonth /12 ); // default to positive months inputed 1870 if ( nMonth <=0 ) 1871 nYearAdj = ( ( nMonth -12 ) / 12 ); 1872 aCurDate.SetYear( aCurDate.GetYear() + nYearAdj ); 1873 } 1874 1875 // adjust day value, 1876 // e.g. 2000, 2, 0 = 2000, 1, 31 or the last day of the previous month 1877 // 2000, 1, 32 = 2000, 2, 1 or the first day of the following month 1878 if( ( nDay < 1 ) || ( nDay > aCurDate.GetDaysInMonth() ) ) 1879 aCurDate += nDay - 1; 1880 else 1881 aCurDate.SetDay( nDay ); 1882 } 1883 1884 long nDiffDays = GetDayDiff( aCurDate ); 1885 rdRet = (double)nDiffDays; 1886 return sal_True; 1887 } 1888 1889 // Function to convert date to ISO 8601 date format 1890 RTLFUNC(CDateToIso) 1891 { 1892 (void)pBasic; 1893 (void)bWrite; 1894 1895 if ( rPar.Count() == 2 ) 1896 { 1897 double aDate = rPar.Get(1)->GetDate(); 1898 1899 char Buffer[9]; 1900 snprintf( Buffer, sizeof( Buffer ), "%04d%02d%02d", 1901 implGetDateYear( aDate ), 1902 implGetDateMonth( aDate ), 1903 implGetDateDay( aDate ) ); 1904 String aRetStr = String::CreateFromAscii( Buffer ); 1905 rPar.Get(0)->PutString( aRetStr ); 1906 } 1907 else 1908 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1909 } 1910 1911 // Function to convert date from ISO 8601 date format 1912 RTLFUNC(CDateFromIso) 1913 { 1914 (void)pBasic; 1915 (void)bWrite; 1916 1917 if ( rPar.Count() == 2 ) 1918 { 1919 String aStr = rPar.Get(1)->GetString(); 1920 sal_Int16 iMonthStart = aStr.Len() - 4; 1921 String aYearStr = aStr.Copy( 0, iMonthStart ); 1922 String aMonthStr = aStr.Copy( iMonthStart, 2 ); 1923 String aDayStr = aStr.Copy( iMonthStart+2, 2 ); 1924 1925 double dDate; 1926 if( implDateSerial( (sal_Int16)aYearStr.ToInt32(), 1927 (sal_Int16)aMonthStr.ToInt32(), (sal_Int16)aDayStr.ToInt32(), dDate ) ) 1928 { 1929 rPar.Get(0)->PutDate( dDate ); 1930 } 1931 } 1932 else 1933 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1934 } 1935 1936 RTLFUNC(DateSerial) 1937 { 1938 (void)pBasic; 1939 (void)bWrite; 1940 1941 if ( rPar.Count() < 4 ) 1942 { 1943 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1944 return; 1945 } 1946 sal_Int16 nYear = rPar.Get(1)->GetInteger(); 1947 sal_Int16 nMonth = rPar.Get(2)->GetInteger(); 1948 sal_Int16 nDay = rPar.Get(3)->GetInteger(); 1949 1950 double dDate; 1951 if( implDateSerial( nYear, nMonth, nDay, dDate ) ) 1952 rPar.Get(0)->PutDate( dDate ); 1953 } 1954 1955 RTLFUNC(TimeSerial) 1956 { 1957 (void)pBasic; 1958 (void)bWrite; 1959 1960 if ( rPar.Count() < 4 ) 1961 { 1962 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1963 return; 1964 } 1965 sal_Int16 nHour = rPar.Get(1)->GetInteger(); 1966 if ( nHour == 24 ) 1967 nHour = 0; // Wegen UNO DateTimes, die bis 24 Uhr gehen 1968 sal_Int16 nMinute = rPar.Get(2)->GetInteger(); 1969 sal_Int16 nSecond = rPar.Get(3)->GetInteger(); 1970 if ((nHour < 0 || nHour > 23) || 1971 (nMinute < 0 || nMinute > 59 ) || 1972 (nSecond < 0 || nSecond > 59 )) 1973 { 1974 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1975 return; 1976 } 1977 1978 sal_Int32 nSeconds = nHour; 1979 nSeconds *= 3600; 1980 nSeconds += nMinute * 60; 1981 nSeconds += nSecond; 1982 double nDays = ((double)nSeconds) / (double)(86400.0); 1983 rPar.Get(0)->PutDate( nDays ); // JSM 1984 } 1985 1986 RTLFUNC(DateValue) 1987 { 1988 (void)pBasic; 1989 (void)bWrite; 1990 1991 if ( rPar.Count() < 2 ) 1992 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1993 else 1994 { 1995 // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden 1996 SvNumberFormatter* pFormatter = NULL; 1997 if( pINST ) 1998 pFormatter = pINST->GetNumberFormatter(); 1999 else 2000 { 2001 sal_uInt32 n; // Dummy 2002 SbiInstance::PrepareNumberFormatter( pFormatter, n, n, n ); 2003 } 2004 2005 sal_uInt32 nIndex; 2006 double fResult; 2007 String aStr( rPar.Get(1)->GetString() ); 2008 sal_Bool bSuccess = pFormatter->IsNumberFormat( aStr, nIndex, fResult ); 2009 short nType = pFormatter->GetType( nIndex ); 2010 2011 // DateValue("February 12, 1969") raises error if the system locale is not en_US 2012 // by using SbiInstance::GetNumberFormatter. 2013 // It seems that both locale number formatter and English number formatter 2014 // are supported in Visual Basic. 2015 LanguageType eLangType = GetpApp()->GetSettings().GetLanguage(); 2016 if( !bSuccess && ( eLangType != LANGUAGE_ENGLISH_US ) ) 2017 { 2018 // Create a new SvNumberFormatter by using LANGUAGE_ENGLISH to get the date value; 2019 com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > 2020 xFactory = comphelper::getProcessServiceFactory(); 2021 SvNumberFormatter aFormatter( xFactory, LANGUAGE_ENGLISH_US ); 2022 bSuccess = aFormatter.IsNumberFormat( aStr, nIndex, fResult ); 2023 nType = aFormatter.GetType( nIndex ); 2024 } 2025 2026 if(bSuccess && (nType==NUMBERFORMAT_DATE || nType==NUMBERFORMAT_DATETIME)) 2027 { 2028 if ( nType == NUMBERFORMAT_DATETIME ) 2029 { 2030 // Zeit abschneiden 2031 if ( fResult > 0.0 ) 2032 fResult = floor( fResult ); 2033 else 2034 fResult = ceil( fResult ); 2035 } 2036 // fResult += 2.0; // Anpassung StarCalcFormatter 2037 rPar.Get(0)->PutDate( fResult ); // JSM 2038 } 2039 else 2040 StarBASIC::Error( SbERR_CONVERSION ); 2041 2042 // #39629 pFormatter kann selbst angefordert sein 2043 if( !pINST ) 2044 delete pFormatter; 2045 } 2046 } 2047 2048 RTLFUNC(TimeValue) 2049 { 2050 (void)pBasic; 2051 (void)bWrite; 2052 2053 if ( rPar.Count() < 2 ) 2054 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 2055 else 2056 { 2057 // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden 2058 SvNumberFormatter* pFormatter = NULL; 2059 if( pINST ) 2060 pFormatter = pINST->GetNumberFormatter(); 2061 else 2062 { 2063 sal_uInt32 n; // Dummy 2064 SbiInstance::PrepareNumberFormatter( pFormatter, n, n, n ); 2065 } 2066 2067 sal_uInt32 nIndex; 2068 double fResult; 2069 sal_Bool bSuccess = pFormatter->IsNumberFormat( rPar.Get(1)->GetString(), 2070 nIndex, fResult ); 2071 short nType = pFormatter->GetType(nIndex); 2072 if(bSuccess && (nType==NUMBERFORMAT_TIME||nType==NUMBERFORMAT_DATETIME)) 2073 { 2074 if ( nType == NUMBERFORMAT_DATETIME ) 2075 // Tage abschneiden 2076 fResult = fmod( fResult, 1 ); 2077 rPar.Get(0)->PutDate( fResult ); // JSM 2078 } 2079 else 2080 StarBASIC::Error( SbERR_CONVERSION ); 2081 2082 // #39629 pFormatter kann selbst angefordert sein 2083 if( !pINST ) 2084 delete pFormatter; 2085 } 2086 } 2087 2088 RTLFUNC(Day) 2089 { 2090 (void)pBasic; 2091 (void)bWrite; 2092 2093 if ( rPar.Count() < 2 ) 2094 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 2095 else 2096 { 2097 SbxVariableRef pArg = rPar.Get( 1 ); 2098 double aDate = pArg->GetDate(); 2099 2100 sal_Int16 nDay = implGetDateDay( aDate ); 2101 rPar.Get(0)->PutInteger( nDay ); 2102 } 2103 } 2104 2105 RTLFUNC(Year) 2106 { 2107 (void)pBasic; 2108 (void)bWrite; 2109 2110 if ( rPar.Count() < 2 ) 2111 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 2112 else 2113 { 2114 sal_Int16 nYear = implGetDateYear( rPar.Get(1)->GetDate() ); 2115 rPar.Get(0)->PutInteger( nYear ); 2116 } 2117 } 2118 2119 sal_Int16 implGetHour( double dDate ) 2120 { 2121 if( dDate < 0.0 ) 2122 dDate *= -1.0; 2123 double nFrac = dDate - floor( dDate ); 2124 nFrac *= 86400.0; 2125 sal_Int32 nSeconds = (sal_Int32)(nFrac + 0.5); 2126 sal_Int16 nHour = (sal_Int16)(nSeconds / 3600); 2127 return nHour; 2128 } 2129 2130 RTLFUNC(Hour) 2131 { 2132 (void)pBasic; 2133 (void)bWrite; 2134 2135 if ( rPar.Count() < 2 ) 2136 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 2137 else 2138 { 2139 double nArg = rPar.Get(1)->GetDate(); 2140 sal_Int16 nHour = implGetHour( nArg ); 2141 rPar.Get(0)->PutInteger( nHour ); 2142 } 2143 } 2144 2145 sal_Int16 implGetMinute( double dDate ) 2146 { 2147 if( dDate < 0.0 ) 2148 dDate *= -1.0; 2149 double nFrac = dDate - floor( dDate ); 2150 nFrac *= 86400.0; 2151 sal_Int32 nSeconds = (sal_Int32)(nFrac + 0.5); 2152 sal_Int16 nTemp = (sal_Int16)(nSeconds % 3600); 2153 sal_Int16 nMin = nTemp / 60; 2154 return nMin; 2155 } 2156 2157 RTLFUNC(Minute) 2158 { 2159 (void)pBasic; 2160 (void)bWrite; 2161 2162 if ( rPar.Count() < 2 ) 2163 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 2164 else 2165 { 2166 double nArg = rPar.Get(1)->GetDate(); 2167 sal_Int16 nMin = implGetMinute( nArg ); 2168 rPar.Get(0)->PutInteger( nMin ); 2169 } 2170 } 2171 2172 RTLFUNC(Month) 2173 { 2174 (void)pBasic; 2175 (void)bWrite; 2176 2177 if ( rPar.Count() < 2 ) 2178 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 2179 else 2180 { 2181 sal_Int16 nMonth = implGetDateMonth( rPar.Get(1)->GetDate() ); 2182 rPar.Get(0)->PutInteger( nMonth ); 2183 } 2184 } 2185 2186 sal_Int16 implGetSecond( double dDate ) 2187 { 2188 if( dDate < 0.0 ) 2189 dDate *= -1.0; 2190 double nFrac = dDate - floor( dDate ); 2191 nFrac *= 86400.0; 2192 sal_Int32 nSeconds = (sal_Int32)(nFrac + 0.5); 2193 sal_Int16 nTemp = (sal_Int16)(nSeconds / 3600); 2194 nSeconds -= nTemp * 3600; 2195 nTemp = (sal_Int16)(nSeconds / 60); 2196 nSeconds -= nTemp * 60; 2197 2198 sal_Int16 nRet = (sal_Int16)nSeconds; 2199 return nRet; 2200 } 2201 2202 RTLFUNC(Second) 2203 { 2204 (void)pBasic; 2205 (void)bWrite; 2206 2207 if ( rPar.Count() < 2 ) 2208 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 2209 else 2210 { 2211 double nArg = rPar.Get(1)->GetDate(); 2212 sal_Int16 nSecond = implGetSecond( nArg ); 2213 rPar.Get(0)->PutInteger( nSecond ); 2214 } 2215 } 2216 2217 double Now_Impl() 2218 { 2219 Date aDate; 2220 Time aTime; 2221 double aSerial = (double)GetDayDiff( aDate ); 2222 long nSeconds = aTime.GetHour(); 2223 nSeconds *= 3600; 2224 nSeconds += aTime.GetMin() * 60; 2225 nSeconds += aTime.GetSec(); 2226 double nDays = ((double)nSeconds) / (double)(24.0*3600.0); 2227 aSerial += nDays; 2228 return aSerial; 2229 } 2230 2231 // Date Now(void) 2232 2233 RTLFUNC(Now) 2234 { 2235 (void)pBasic; 2236 (void)bWrite; 2237 rPar.Get(0)->PutDate( Now_Impl() ); 2238 } 2239 2240 // Date Time(void) 2241 2242 RTLFUNC(Time) 2243 { 2244 (void)pBasic; 2245 2246 if ( !bWrite ) 2247 { 2248 Time aTime; 2249 SbxVariable* pMeth = rPar.Get( 0 ); 2250 String aRes; 2251 if( pMeth->IsFixed() ) 2252 { 2253 // Time$: hh:mm:ss 2254 char buf[ 20 ]; 2255 snprintf( buf, sizeof(buf), "%02d:%02d:%02d", 2256 aTime.GetHour(), aTime.GetMin(), aTime.GetSec() ); 2257 aRes = String::CreateFromAscii( buf ); 2258 } 2259 else 2260 { 2261 // Time: system dependent 2262 long nSeconds=aTime.GetHour(); 2263 nSeconds *= 3600; 2264 nSeconds += aTime.GetMin() * 60; 2265 nSeconds += aTime.GetSec(); 2266 double nDays = (double)nSeconds * ( 1.0 / (24.0*3600.0) ); 2267 Color* pCol; 2268 2269 // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden 2270 SvNumberFormatter* pFormatter = NULL; 2271 sal_uInt32 nIndex; 2272 if( pINST ) 2273 { 2274 pFormatter = pINST->GetNumberFormatter(); 2275 nIndex = pINST->GetStdTimeIdx(); 2276 } 2277 else 2278 { 2279 sal_uInt32 n; // Dummy 2280 SbiInstance::PrepareNumberFormatter( pFormatter, n, nIndex, n ); 2281 } 2282 2283 pFormatter->GetOutputString( nDays, nIndex, aRes, &pCol ); 2284 2285 // #39629 pFormatter kann selbst angefordert sein 2286 if( !pINST ) 2287 delete pFormatter; 2288 } 2289 pMeth->PutString( aRes ); 2290 } 2291 else 2292 { 2293 StarBASIC::Error( SbERR_NOT_IMPLEMENTED ); 2294 } 2295 } 2296 2297 RTLFUNC(Timer) 2298 { 2299 (void)pBasic; 2300 (void)bWrite; 2301 2302 Time aTime; 2303 long nSeconds = aTime.GetHour(); 2304 nSeconds *= 3600; 2305 nSeconds += aTime.GetMin() * 60; 2306 nSeconds += aTime.GetSec(); 2307 rPar.Get(0)->PutDate( (double)nSeconds ); 2308 } 2309 2310 2311 RTLFUNC(Date) 2312 { 2313 (void)pBasic; 2314 (void)bWrite; 2315 2316 if ( !bWrite ) 2317 { 2318 Date aToday; 2319 double nDays = (double)GetDayDiff( aToday ); 2320 SbxVariable* pMeth = rPar.Get( 0 ); 2321 if( pMeth->IsString() ) 2322 { 2323 String aRes; 2324 Color* pCol; 2325 2326 // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden 2327 SvNumberFormatter* pFormatter = NULL; 2328 sal_uInt32 nIndex; 2329 if( pINST ) 2330 { 2331 pFormatter = pINST->GetNumberFormatter(); 2332 nIndex = pINST->GetStdDateIdx(); 2333 } 2334 else 2335 { 2336 sal_uInt32 n; // Dummy 2337 SbiInstance::PrepareNumberFormatter( pFormatter, nIndex, n, n ); 2338 } 2339 2340 pFormatter->GetOutputString( nDays, nIndex, aRes, &pCol ); 2341 pMeth->PutString( aRes ); 2342 2343 // #39629 pFormatter kann selbst angefordert sein 2344 if( !pINST ) 2345 delete pFormatter; 2346 } 2347 else 2348 pMeth->PutDate( nDays ); 2349 } 2350 else 2351 { 2352 StarBASIC::Error( SbERR_NOT_IMPLEMENTED ); 2353 } 2354 } 2355 2356 RTLFUNC(IsArray) 2357 { 2358 (void)pBasic; 2359 (void)bWrite; 2360 2361 if ( rPar.Count() < 2 ) 2362 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 2363 else 2364 rPar.Get(0)->PutBool((rPar.Get(1)->GetType() & SbxARRAY) ? sal_True : sal_False ); 2365 } 2366 2367 RTLFUNC(IsObject) 2368 { 2369 (void)pBasic; 2370 (void)bWrite; 2371 2372 if ( rPar.Count() < 2 ) 2373 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 2374 else 2375 { 2376 SbxVariable* pVar = rPar.Get(1); 2377 SbxBase* pObj = (SbxBase*)pVar->GetObject(); 2378 2379 // #100385: GetObject can result in an error, so reset it 2380 SbxBase::ResetError(); 2381 2382 SbUnoClass* pUnoClass; 2383 sal_Bool bObject; 2384 if( pObj && NULL != ( pUnoClass=PTR_CAST(SbUnoClass,pObj) ) ) 2385 { 2386 bObject = pUnoClass->getUnoClass().is(); 2387 } 2388 else 2389 { 2390 bObject = pVar->IsObject(); 2391 } 2392 rPar.Get( 0 )->PutBool( bObject ); 2393 } 2394 } 2395 2396 RTLFUNC(IsDate) 2397 { 2398 (void)pBasic; 2399 (void)bWrite; 2400 2401 if ( rPar.Count() < 2 ) 2402 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 2403 else 2404 { 2405 // #46134 Nur String wird konvertiert, andere Typen ergeben sal_False 2406 SbxVariableRef xArg = rPar.Get( 1 ); 2407 SbxDataType eType = xArg->GetType(); 2408 sal_Bool bDate = sal_False; 2409 2410 if( eType == SbxDATE ) 2411 { 2412 bDate = sal_True; 2413 } 2414 else if( eType == SbxSTRING ) 2415 { 2416 // Error loeschen 2417 SbxError nPrevError = SbxBase::GetError(); 2418 SbxBase::ResetError(); 2419 2420 // Konvertierung des Parameters nach SbxDATE erzwingen 2421 xArg->SbxValue::GetDate(); 2422 2423 // Bei Fehler ist es kein Date 2424 bDate = !SbxBase::IsError(); 2425 2426 // Error-Situation wiederherstellen 2427 SbxBase::ResetError(); 2428 SbxBase::SetError( nPrevError ); 2429 } 2430 rPar.Get( 0 )->PutBool( bDate ); 2431 } 2432 } 2433 2434 RTLFUNC(IsEmpty) 2435 { 2436 (void)pBasic; 2437 (void)bWrite; 2438 2439 if ( rPar.Count() < 2 ) 2440 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 2441 else 2442 rPar.Get( 0 )->PutBool( rPar.Get(1)->IsEmpty() ); 2443 } 2444 2445 RTLFUNC(IsError) 2446 { 2447 (void)pBasic; 2448 (void)bWrite; 2449 2450 if ( rPar.Count() < 2 ) 2451 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 2452 else 2453 rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() ); 2454 } 2455 2456 RTLFUNC(IsNull) 2457 { 2458 (void)pBasic; 2459 (void)bWrite; 2460 2461 if ( rPar.Count() < 2 ) 2462 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 2463 else 2464 { 2465 // #51475 Wegen Uno-Objekten auch true liefern, 2466 // wenn der pObj-Wert NULL ist 2467 SbxVariableRef pArg = rPar.Get( 1 ); 2468 sal_Bool bNull = rPar.Get(1)->IsNull(); 2469 if( !bNull && pArg->GetType() == SbxOBJECT ) 2470 { 2471 SbxBase* pObj = pArg->GetObject(); 2472 if( !pObj ) 2473 bNull = sal_True; 2474 } 2475 rPar.Get( 0 )->PutBool( bNull ); 2476 } 2477 } 2478 2479 RTLFUNC(IsNumeric) 2480 { 2481 (void)pBasic; 2482 (void)bWrite; 2483 2484 if ( rPar.Count() < 2 ) 2485 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 2486 else 2487 rPar.Get( 0 )->PutBool( rPar.Get( 1 )->IsNumericRTL() ); 2488 } 2489 2490 // Das machen wir auf die billige Tour 2491 2492 RTLFUNC(IsMissing) 2493 { 2494 (void)pBasic; 2495 (void)bWrite; 2496 2497 if ( rPar.Count() < 2 ) 2498 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 2499 else 2500 // #57915 Missing wird durch Error angezeigt 2501 rPar.Get( 0 )->PutBool( rPar.Get(1)->IsErr() ); 2502 } 2503 2504 // Dir( [Maske] [,Attrs] ) 2505 // ToDo: Library-globaler Datenbereich fuer Dir-Objekt und Flags 2506 2507 2508 String getDirectoryPath( String aPathStr ) 2509 { 2510 String aRetStr; 2511 2512 DirectoryItem aItem; 2513 FileBase::RC nRet = DirectoryItem::get( aPathStr, aItem ); 2514 if( nRet == FileBase::E_None ) 2515 { 2516 FileStatus aFileStatus( FileStatusMask_Type ); 2517 nRet = aItem.getFileStatus( aFileStatus ); 2518 if( nRet == FileBase::E_None ) 2519 { 2520 FileStatus::Type aType = aFileStatus.getFileType(); 2521 if( isFolder( aType ) ) 2522 { 2523 aRetStr = aPathStr; 2524 } 2525 else if( aType == FileStatus::Link ) 2526 { 2527 FileStatus aFileStatus2( FileStatusMask_LinkTargetURL ); 2528 nRet = aItem.getFileStatus( aFileStatus2 ); 2529 if( nRet == FileBase::E_None ) 2530 aRetStr = getDirectoryPath( aFileStatus2.getLinkTargetURL() ); 2531 } 2532 } 2533 } 2534 return aRetStr; 2535 } 2536 2537 // Function looks for wildcards, removes them and always returns the pure path 2538 String implSetupWildcard( const String& rFileParam, SbiRTLData* pRTLData ) 2539 { 2540 static String aAsterisk = String::CreateFromAscii( "*" ); 2541 static sal_Char cDelim1 = (sal_Char)'/'; 2542 static sal_Char cDelim2 = (sal_Char)'\\'; 2543 static sal_Char cWild1 = '*'; 2544 static sal_Char cWild2 = '?'; 2545 2546 delete pRTLData->pWildCard; 2547 pRTLData->pWildCard = NULL; 2548 pRTLData->sFullNameToBeChecked = String(); 2549 2550 String aFileParam = rFileParam; 2551 xub_StrLen nLastWild = aFileParam.SearchBackward( cWild1 ); 2552 if( nLastWild == STRING_NOTFOUND ) 2553 nLastWild = aFileParam.SearchBackward( cWild2 ); 2554 sal_Bool bHasWildcards = ( nLastWild != STRING_NOTFOUND ); 2555 2556 2557 xub_StrLen nLastDelim = aFileParam.SearchBackward( cDelim1 ); 2558 if( nLastDelim == STRING_NOTFOUND ) 2559 nLastDelim = aFileParam.SearchBackward( cDelim2 ); 2560 2561 if( bHasWildcards ) 2562 { 2563 // Wildcards in path? 2564 if( nLastDelim != STRING_NOTFOUND && nLastDelim > nLastWild ) 2565 return aFileParam; 2566 } 2567 else 2568 { 2569 String aPathStr = getFullPath( aFileParam ); 2570 if( nLastDelim != aFileParam.Len() - 1 ) 2571 pRTLData->sFullNameToBeChecked = aPathStr; 2572 return aPathStr; 2573 } 2574 2575 String aPureFileName; 2576 if( nLastDelim == STRING_NOTFOUND ) 2577 { 2578 aPureFileName = aFileParam; 2579 aFileParam = String(); 2580 } 2581 else 2582 { 2583 aPureFileName = aFileParam.Copy( nLastDelim + 1 ); 2584 aFileParam = aFileParam.Copy( 0, nLastDelim ); 2585 } 2586 2587 // Try again to get a valid URL/UNC-path with only the path 2588 String aPathStr = getFullPath( aFileParam ); 2589 xub_StrLen nPureLen = aPureFileName.Len(); 2590 2591 // Is there a pure file name left? Otherwise the path is 2592 // invalid anyway because it was not accepted by OSL before 2593 if( nPureLen && aPureFileName != aAsterisk ) 2594 { 2595 pRTLData->pWildCard = new WildCard( aPureFileName ); 2596 } 2597 return aPathStr; 2598 } 2599 2600 inline sal_Bool implCheckWildcard( const String& rName, SbiRTLData* pRTLData ) 2601 { 2602 sal_Bool bMatch = sal_True; 2603 2604 if( pRTLData->pWildCard ) 2605 bMatch = pRTLData->pWildCard->Matches( rName ); 2606 return bMatch; 2607 } 2608 2609 2610 bool isRootDir( String aDirURLStr ) 2611 { 2612 INetURLObject aDirURLObj( aDirURLStr ); 2613 sal_Bool bRoot = sal_False; 2614 2615 // Check if it's a root directory 2616 sal_Int32 nCount = aDirURLObj.getSegmentCount(); 2617 2618 // No segment means Unix root directory "file:///" 2619 if( nCount == 0 ) 2620 { 2621 bRoot = sal_True; 2622 } 2623 // Exactly one segment needs further checking, because it 2624 // can be Unix "file:///foo/" -> no root 2625 // or Windows "file:///c:/" -> root 2626 else if( nCount == 1 ) 2627 { 2628 ::rtl::OUString aSeg1 = aDirURLObj.getName( 0, sal_True, 2629 INetURLObject::DECODE_WITH_CHARSET ); 2630 if( aSeg1.getStr()[1] == (sal_Unicode)':' ) 2631 { 2632 bRoot = sal_True; 2633 } 2634 } 2635 // More than one segments can never be root 2636 // so bRoot remains sal_False 2637 2638 return bRoot; 2639 } 2640 2641 RTLFUNC(Dir) 2642 { 2643 (void)pBasic; 2644 (void)bWrite; 2645 2646 String aPath; 2647 2648 sal_uInt16 nParCount = rPar.Count(); 2649 if( nParCount > 3 ) 2650 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 2651 else 2652 { 2653 SbiRTLData* pRTLData = pINST->GetRTLData(); 2654 2655 // #34645: Kann auch von der URL-Zeile ueber 'macro: Dir' aufgerufen werden 2656 // dann existiert kein pRTLData und die Methode muss verlassen werden 2657 if( !pRTLData ) 2658 return; 2659 2660 // <-- UCB 2661 if( hasUno() ) 2662 { 2663 com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); 2664 if( xSFI.is() ) 2665 { 2666 if ( nParCount >= 2 ) 2667 { 2668 String aFileParam = rPar.Get(1)->GetString(); 2669 2670 String aFileURLStr = implSetupWildcard( aFileParam, pRTLData ); 2671 if( pRTLData->sFullNameToBeChecked.Len() > 0 ) 2672 { 2673 sal_Bool bExists = sal_False; 2674 try { bExists = xSFI->exists( aFileURLStr ); } 2675 catch( Exception & ) {} 2676 2677 String aNameOnlyStr; 2678 if( bExists ) 2679 { 2680 INetURLObject aFileURL( aFileURLStr ); 2681 aNameOnlyStr = aFileURL.getName( INetURLObject::LAST_SEGMENT, 2682 true, INetURLObject::DECODE_WITH_CHARSET ); 2683 } 2684 rPar.Get(0)->PutString( aNameOnlyStr ); 2685 return; 2686 } 2687 2688 try 2689 { 2690 String aDirURLStr; 2691 sal_Bool bFolder = xSFI->isFolder( aFileURLStr ); 2692 2693 if( bFolder ) 2694 { 2695 aDirURLStr = aFileURLStr; 2696 } 2697 else 2698 { 2699 String aEmptyStr; 2700 rPar.Get(0)->PutString( aEmptyStr ); 2701 } 2702 2703 sal_uInt16 nFlags = 0; 2704 if ( nParCount > 2 ) 2705 pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger(); 2706 else 2707 pRTLData->nDirFlags = 0; 2708 2709 // Read directory 2710 sal_Bool bIncludeFolders = ((nFlags & Sb_ATTR_DIRECTORY) != 0); 2711 pRTLData->aDirSeq = xSFI->getFolderContents( aDirURLStr, bIncludeFolders ); 2712 pRTLData->nCurDirPos = 0; 2713 2714 // #78651 Add "." and ".." directories for VB compatibility 2715 if( bIncludeFolders ) 2716 { 2717 sal_Bool bRoot = isRootDir( aDirURLStr ); 2718 2719 // If it's no root directory we flag the need for 2720 // the "." and ".." directories by the value -2 2721 // for the actual position. Later for -2 will be 2722 // returned "." and for -1 ".." 2723 if( !bRoot ) 2724 { 2725 pRTLData->nCurDirPos = -2; 2726 } 2727 } 2728 } 2729 catch( Exception & ) 2730 { 2731 //StarBASIC::Error( ERRCODE_IO_GENERAL ); 2732 } 2733 } 2734 2735 2736 if( pRTLData->aDirSeq.getLength() > 0 ) 2737 { 2738 sal_Bool bFolderFlag = ((pRTLData->nDirFlags & Sb_ATTR_DIRECTORY) != 0); 2739 2740 SbiInstance* pInst = pINST; 2741 bool bCompatibility = ( pInst && pInst->IsCompatibility() ); 2742 for( ;; ) 2743 { 2744 if( pRTLData->nCurDirPos < 0 ) 2745 { 2746 if( pRTLData->nCurDirPos == -2 ) 2747 { 2748 aPath = ::rtl::OUString::createFromAscii( "." ); 2749 } 2750 else if( pRTLData->nCurDirPos == -1 ) 2751 { 2752 aPath = ::rtl::OUString::createFromAscii( ".." ); 2753 } 2754 pRTLData->nCurDirPos++; 2755 } 2756 else if( pRTLData->nCurDirPos >= pRTLData->aDirSeq.getLength() ) 2757 { 2758 pRTLData->aDirSeq.realloc( 0 ); 2759 aPath.Erase(); 2760 break; 2761 } 2762 else 2763 { 2764 ::rtl::OUString aFile = pRTLData->aDirSeq.getConstArray()[pRTLData->nCurDirPos++]; 2765 2766 if( bCompatibility ) 2767 { 2768 if( !bFolderFlag ) 2769 { 2770 sal_Bool bFolder = xSFI->isFolder( aFile ); 2771 if( bFolder ) 2772 continue; 2773 } 2774 } 2775 else 2776 { 2777 // Only directories 2778 if( bFolderFlag ) 2779 { 2780 sal_Bool bFolder = xSFI->isFolder( aFile ); 2781 if( !bFolder ) 2782 continue; 2783 } 2784 } 2785 2786 INetURLObject aURL( aFile ); 2787 aPath = aURL.getName( INetURLObject::LAST_SEGMENT, sal_True, 2788 INetURLObject::DECODE_WITH_CHARSET ); 2789 } 2790 2791 sal_Bool bMatch = implCheckWildcard( aPath, pRTLData ); 2792 if( !bMatch ) 2793 continue; 2794 2795 break; 2796 } 2797 } 2798 rPar.Get(0)->PutString( aPath ); 2799 } 2800 } 2801 else 2802 // --> UCB 2803 { 2804 #ifdef _OLD_FILE_IMPL 2805 if ( nParCount >= 2 ) 2806 { 2807 delete pRTLData->pDir; 2808 pRTLData->pDir = 0; // wg. Sonderbehandlung Sb_ATTR_VOLUME 2809 DirEntry aEntry( rPar.Get(1)->GetString() ); 2810 FileStat aStat( aEntry ); 2811 if(!aStat.GetError() && (aStat.GetKind() & FSYS_KIND_FILE)) 2812 { 2813 // ah ja, ist nur ein dateiname 2814 // Pfad abschneiden (wg. VB4) 2815 rPar.Get(0)->PutString( aEntry.GetName() ); 2816 return; 2817 } 2818 sal_uInt16 nFlags = 0; 2819 if ( nParCount > 2 ) 2820 pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger(); 2821 else 2822 pRTLData->nDirFlags = 0; 2823 2824 // Sb_ATTR_VOLUME wird getrennt gehandelt 2825 if( pRTLData->nDirFlags & Sb_ATTR_VOLUME ) 2826 aPath = aEntry.GetVolume(); 2827 else 2828 { 2829 // Die richtige Auswahl treffen 2830 sal_uInt16 nMode = FSYS_KIND_FILE; 2831 if( nFlags & Sb_ATTR_DIRECTORY ) 2832 nMode |= FSYS_KIND_DIR; 2833 if( nFlags == Sb_ATTR_DIRECTORY ) 2834 nMode = FSYS_KIND_DIR; 2835 pRTLData->pDir = new Dir( aEntry, (DirEntryKind) nMode ); 2836 pRTLData->nCurDirPos = 0; 2837 } 2838 } 2839 2840 if( pRTLData->pDir ) 2841 { 2842 for( ;; ) 2843 { 2844 if( pRTLData->nCurDirPos >= pRTLData->pDir->Count() ) 2845 { 2846 delete pRTLData->pDir; 2847 pRTLData->pDir = 0; 2848 aPath.Erase(); 2849 break; 2850 } 2851 DirEntry aNextEntry=(*(pRTLData->pDir))[pRTLData->nCurDirPos++]; 2852 aPath = aNextEntry.GetName(); //Full(); 2853 break; 2854 } 2855 } 2856 rPar.Get(0)->PutString( aPath ); 2857 #else 2858 // TODO: OSL 2859 if ( nParCount >= 2 ) 2860 { 2861 String aFileParam = rPar.Get(1)->GetString(); 2862 2863 String aDirURL = implSetupWildcard( aFileParam, pRTLData ); 2864 2865 sal_uInt16 nFlags = 0; 2866 if ( nParCount > 2 ) 2867 pRTLData->nDirFlags = nFlags = rPar.Get(2)->GetInteger(); 2868 else 2869 pRTLData->nDirFlags = 0; 2870 2871 // Read directory 2872 sal_Bool bIncludeFolders = ((nFlags & Sb_ATTR_DIRECTORY) != 0); 2873 pRTLData->pDir = new Directory( aDirURL ); 2874 FileBase::RC nRet = pRTLData->pDir->open(); 2875 if( nRet != FileBase::E_None ) 2876 { 2877 delete pRTLData->pDir; 2878 pRTLData->pDir = NULL; 2879 rPar.Get(0)->PutString( String() ); 2880 return; 2881 } 2882 2883 // #86950 Add "." and ".." directories for VB compatibility 2884 pRTLData->nCurDirPos = 0; 2885 if( bIncludeFolders ) 2886 { 2887 sal_Bool bRoot = isRootDir( aDirURL ); 2888 2889 // If it's no root directory we flag the need for 2890 // the "." and ".." directories by the value -2 2891 // for the actual position. Later for -2 will be 2892 // returned "." and for -1 ".." 2893 if( !bRoot ) 2894 { 2895 pRTLData->nCurDirPos = -2; 2896 } 2897 } 2898 2899 } 2900 2901 if( pRTLData->pDir ) 2902 { 2903 sal_Bool bFolderFlag = ((pRTLData->nDirFlags & Sb_ATTR_DIRECTORY) != 0); 2904 for( ;; ) 2905 { 2906 if( pRTLData->nCurDirPos < 0 ) 2907 { 2908 if( pRTLData->nCurDirPos == -2 ) 2909 { 2910 aPath = ::rtl::OUString::createFromAscii( "." ); 2911 } 2912 else if( pRTLData->nCurDirPos == -1 ) 2913 { 2914 aPath = ::rtl::OUString::createFromAscii( ".." ); 2915 } 2916 pRTLData->nCurDirPos++; 2917 } 2918 else 2919 { 2920 DirectoryItem aItem; 2921 FileBase::RC nRet = pRTLData->pDir->getNextItem( aItem ); 2922 if( nRet != FileBase::E_None ) 2923 { 2924 delete pRTLData->pDir; 2925 pRTLData->pDir = NULL; 2926 aPath.Erase(); 2927 break; 2928 } 2929 2930 // Handle flags 2931 FileStatus aFileStatus( FileStatusMask_Type | FileStatusMask_FileName ); 2932 nRet = aItem.getFileStatus( aFileStatus ); 2933 2934 // Only directories? 2935 if( bFolderFlag ) 2936 { 2937 FileStatus::Type aType = aFileStatus.getFileType(); 2938 sal_Bool bFolder = isFolder( aType ); 2939 if( !bFolder ) 2940 continue; 2941 } 2942 2943 aPath = aFileStatus.getFileName(); 2944 } 2945 2946 sal_Bool bMatch = implCheckWildcard( aPath, pRTLData ); 2947 if( !bMatch ) 2948 continue; 2949 2950 break; 2951 } 2952 } 2953 rPar.Get(0)->PutString( aPath ); 2954 #endif 2955 } 2956 } 2957 } 2958 2959 2960 RTLFUNC(GetAttr) 2961 { 2962 (void)pBasic; 2963 (void)bWrite; 2964 2965 if ( rPar.Count() == 2 ) 2966 { 2967 sal_Int16 nFlags = 0; 2968 2969 // In Windows, We want to use Windows API to get the file attributes 2970 // for VBA interoperability. 2971 #if defined( WNT ) 2972 if( SbiRuntime::isVBAEnabled() ) 2973 { 2974 DirEntry aEntry( rPar.Get(1)->GetString() ); 2975 aEntry.ToAbs(); 2976 2977 // #57064 Bei virtuellen URLs den Real-Path extrahieren 2978 ByteString aByteStrFullPath( aEntry.GetFull(), gsl_getSystemTextEncoding() ); 2979 DWORD nRealFlags = GetFileAttributes (aByteStrFullPath.GetBuffer()); 2980 if (nRealFlags != 0xffffffff) 2981 { 2982 if (nRealFlags == FILE_ATTRIBUTE_NORMAL) 2983 nRealFlags = 0; 2984 nFlags = (sal_Int16) (nRealFlags); 2985 } 2986 else 2987 StarBASIC::Error( SbERR_FILE_NOT_FOUND ); 2988 2989 rPar.Get(0)->PutInteger( nFlags ); 2990 2991 return; 2992 } 2993 #endif 2994 2995 // <-- UCB 2996 if( hasUno() ) 2997 { 2998 com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); 2999 if( xSFI.is() ) 3000 { 3001 try 3002 { 3003 String aPath = getFullPath( rPar.Get(1)->GetString() ); 3004 sal_Bool bExists = sal_False; 3005 try { bExists = xSFI->exists( aPath ); } 3006 catch( Exception & ) {} 3007 if( !bExists ) 3008 { 3009 StarBASIC::Error( SbERR_FILE_NOT_FOUND ); 3010 return; 3011 } 3012 3013 sal_Bool bReadOnly = xSFI->isReadOnly( aPath ); 3014 sal_Bool bHidden = xSFI->isHidden( aPath ); 3015 sal_Bool bDirectory = xSFI->isFolder( aPath ); 3016 if( bReadOnly ) 3017 nFlags |= 0x0001; // ATTR_READONLY 3018 if( bHidden ) 3019 nFlags |= 0x0002; // ATTR_HIDDEN 3020 if( bDirectory ) 3021 nFlags |= 0x0010; // ATTR_DIRECTORY 3022 } 3023 catch( Exception & ) 3024 { 3025 StarBASIC::Error( ERRCODE_IO_GENERAL ); 3026 } 3027 } 3028 } 3029 else 3030 // --> UCB 3031 { 3032 DirectoryItem aItem; 3033 FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( rPar.Get(1)->GetString() ), aItem ); 3034 FileStatus aFileStatus( FileStatusMask_Attributes | FileStatusMask_Type ); 3035 nRet = aItem.getFileStatus( aFileStatus ); 3036 sal_uInt64 nAttributes = aFileStatus.getAttributes(); 3037 sal_Bool bReadOnly = (nAttributes & Attribute_ReadOnly) != 0; 3038 3039 FileStatus::Type aType = aFileStatus.getFileType(); 3040 sal_Bool bDirectory = isFolder( aType ); 3041 if( bReadOnly ) 3042 nFlags |= 0x0001; // ATTR_READONLY 3043 if( bDirectory ) 3044 nFlags |= 0x0010; // ATTR_DIRECTORY 3045 } 3046 rPar.Get(0)->PutInteger( nFlags ); 3047 } 3048 else 3049 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3050 } 3051 3052 3053 RTLFUNC(FileDateTime) 3054 { 3055 (void)pBasic; 3056 (void)bWrite; 3057 3058 if ( rPar.Count() != 2 ) 3059 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3060 else 3061 { 3062 // <-- UCB 3063 String aPath = rPar.Get(1)->GetString(); 3064 Time aTime; 3065 Date aDate; 3066 if( hasUno() ) 3067 { 3068 com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); 3069 if( xSFI.is() ) 3070 { 3071 try 3072 { 3073 com::sun::star::util::DateTime aUnoDT = xSFI->getDateTimeModified( aPath ); 3074 aTime = Time( aUnoDT.Hours, aUnoDT.Minutes, aUnoDT.Seconds, aUnoDT.HundredthSeconds ); 3075 aDate = Date( aUnoDT.Day, aUnoDT.Month, aUnoDT.Year ); 3076 } 3077 catch( Exception & ) 3078 { 3079 StarBASIC::Error( ERRCODE_IO_GENERAL ); 3080 } 3081 } 3082 } 3083 else 3084 // --> UCB 3085 { 3086 #ifdef _OLD_FILE_IMPL 3087 DirEntry aEntry( aPath ); 3088 FileStat aStat( aEntry ); 3089 aTime = Time( aStat.TimeModified() ); 3090 aDate = Date( aStat.DateModified() ); 3091 #else 3092 DirectoryItem aItem; 3093 FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( aPath ), aItem ); 3094 FileStatus aFileStatus( FileStatusMask_ModifyTime ); 3095 nRet = aItem.getFileStatus( aFileStatus ); 3096 TimeValue aTimeVal = aFileStatus.getModifyTime(); 3097 oslDateTime aDT; 3098 osl_getDateTimeFromTimeValue( &aTimeVal, &aDT ); 3099 3100 aTime = Time( aDT.Hours, aDT.Minutes, aDT.Seconds, 10000000*aDT.NanoSeconds ); 3101 aDate = Date( aDT.Day, aDT.Month, aDT.Year ); 3102 #endif 3103 } 3104 3105 double fSerial = (double)GetDayDiff( aDate ); 3106 long nSeconds = aTime.GetHour(); 3107 nSeconds *= 3600; 3108 nSeconds += aTime.GetMin() * 60; 3109 nSeconds += aTime.GetSec(); 3110 double nDays = ((double)nSeconds) / (double)(24.0*3600.0); 3111 fSerial += nDays; 3112 3113 Color* pCol; 3114 3115 // #39629 pINST pruefen, kann aus URL-Zeile gerufen werden 3116 SvNumberFormatter* pFormatter = NULL; 3117 sal_uInt32 nIndex; 3118 if( pINST ) 3119 { 3120 pFormatter = pINST->GetNumberFormatter(); 3121 nIndex = pINST->GetStdDateTimeIdx(); 3122 } 3123 else 3124 { 3125 sal_uInt32 n; // Dummy 3126 SbiInstance::PrepareNumberFormatter( pFormatter, n, n, nIndex ); 3127 } 3128 3129 String aRes; 3130 pFormatter->GetOutputString( fSerial, nIndex, aRes, &pCol ); 3131 rPar.Get(0)->PutString( aRes ); 3132 3133 // #39629 pFormatter kann selbst angefordert sein 3134 if( !pINST ) 3135 delete pFormatter; 3136 } 3137 } 3138 3139 3140 RTLFUNC(EOF) 3141 { 3142 (void)pBasic; 3143 (void)bWrite; 3144 3145 // AB 08/16/2000: No changes for UCB 3146 if ( rPar.Count() != 2 ) 3147 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3148 else 3149 { 3150 sal_Int16 nChannel = rPar.Get(1)->GetInteger(); 3151 // nChannel--; // macht MD beim Oeffnen auch nicht 3152 SbiIoSystem* pIO = pINST->GetIoSystem(); 3153 SbiStream* pSbStrm = pIO->GetStream( nChannel ); 3154 if ( !pSbStrm ) 3155 { 3156 StarBASIC::Error( SbERR_BAD_CHANNEL ); 3157 return; 3158 } 3159 sal_Bool bIsEof; 3160 SvStream* pSvStrm = pSbStrm->GetStrm(); 3161 if ( pSbStrm->IsText() ) 3162 { 3163 char cBla; 3164 (*pSvStrm) >> cBla; // koennen wir noch ein Zeichen lesen 3165 bIsEof = pSvStrm->IsEof(); 3166 if ( !bIsEof ) 3167 pSvStrm->SeekRel( -1 ); 3168 } 3169 else 3170 bIsEof = pSvStrm->IsEof(); // fuer binaerdateien! 3171 rPar.Get(0)->PutBool( bIsEof ); 3172 } 3173 } 3174 3175 RTLFUNC(FileAttr) 3176 { 3177 (void)pBasic; 3178 (void)bWrite; 3179 3180 // AB 08/16/2000: No changes for UCB 3181 3182 // #57064 Obwohl diese Funktion nicht mit DirEntry arbeitet, ist sie von 3183 // der Anpassung an virtuelle URLs nich betroffen, da sie nur auf bereits 3184 // geoeffneten Dateien arbeitet und der Name hier keine Rolle spielt. 3185 3186 if ( rPar.Count() != 3 ) 3187 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3188 else 3189 { 3190 sal_Int16 nChannel = rPar.Get(1)->GetInteger(); 3191 // nChannel--; 3192 SbiIoSystem* pIO = pINST->GetIoSystem(); 3193 SbiStream* pSbStrm = pIO->GetStream( nChannel ); 3194 if ( !pSbStrm ) 3195 { 3196 StarBASIC::Error( SbERR_BAD_CHANNEL ); 3197 return; 3198 } 3199 sal_Int16 nRet; 3200 if ( rPar.Get(2)->GetInteger() == 1 ) 3201 nRet = (sal_Int16)(pSbStrm->GetMode()); 3202 else 3203 nRet = 0; // System file handle not supported 3204 3205 rPar.Get(0)->PutInteger( nRet ); 3206 } 3207 } 3208 RTLFUNC(Loc) 3209 { 3210 (void)pBasic; 3211 (void)bWrite; 3212 3213 // AB 08/16/2000: No changes for UCB 3214 if ( rPar.Count() != 2 ) 3215 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3216 else 3217 { 3218 sal_Int16 nChannel = rPar.Get(1)->GetInteger(); 3219 SbiIoSystem* pIO = pINST->GetIoSystem(); 3220 SbiStream* pSbStrm = pIO->GetStream( nChannel ); 3221 if ( !pSbStrm ) 3222 { 3223 StarBASIC::Error( SbERR_BAD_CHANNEL ); 3224 return; 3225 } 3226 SvStream* pSvStrm = pSbStrm->GetStrm(); 3227 sal_uIntPtr nPos; 3228 if( pSbStrm->IsRandom()) 3229 { 3230 short nBlockLen = pSbStrm->GetBlockLen(); 3231 nPos = nBlockLen ? (pSvStrm->Tell() / nBlockLen) : 0; 3232 nPos++; // Blockpositionen beginnen bei 1 3233 } 3234 else if ( pSbStrm->IsText() ) 3235 nPos = pSbStrm->GetLine(); 3236 else if( pSbStrm->IsBinary() ) 3237 nPos = pSvStrm->Tell(); 3238 else if ( pSbStrm->IsSeq() ) 3239 nPos = ( pSvStrm->Tell()+1 ) / 128; 3240 else 3241 nPos = pSvStrm->Tell(); 3242 rPar.Get(0)->PutLong( (sal_Int32)nPos ); 3243 } 3244 } 3245 3246 RTLFUNC(Lof) 3247 { 3248 (void)pBasic; 3249 (void)bWrite; 3250 3251 // AB 08/16/2000: No changes for UCB 3252 if ( rPar.Count() != 2 ) 3253 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3254 else 3255 { 3256 sal_Int16 nChannel = rPar.Get(1)->GetInteger(); 3257 SbiIoSystem* pIO = pINST->GetIoSystem(); 3258 SbiStream* pSbStrm = pIO->GetStream( nChannel ); 3259 if ( !pSbStrm ) 3260 { 3261 StarBASIC::Error( SbERR_BAD_CHANNEL ); 3262 return; 3263 } 3264 SvStream* pSvStrm = pSbStrm->GetStrm(); 3265 sal_uIntPtr nOldPos = pSvStrm->Tell(); 3266 sal_uIntPtr nLen = pSvStrm->Seek( STREAM_SEEK_TO_END ); 3267 pSvStrm->Seek( nOldPos ); 3268 rPar.Get(0)->PutLong( (sal_Int32)nLen ); 3269 } 3270 } 3271 3272 3273 RTLFUNC(Seek) 3274 { 3275 (void)pBasic; 3276 (void)bWrite; 3277 3278 // AB 08/16/2000: No changes for UCB 3279 int nArgs = (int)rPar.Count(); 3280 if ( nArgs < 2 || nArgs > 3 ) 3281 { 3282 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3283 return; 3284 } 3285 sal_Int16 nChannel = rPar.Get(1)->GetInteger(); 3286 // nChannel--; 3287 SbiIoSystem* pIO = pINST->GetIoSystem(); 3288 SbiStream* pSbStrm = pIO->GetStream( nChannel ); 3289 if ( !pSbStrm ) 3290 { 3291 StarBASIC::Error( SbERR_BAD_CHANNEL ); 3292 return; 3293 } 3294 SvStream* pStrm = pSbStrm->GetStrm(); 3295 3296 if ( nArgs == 2 ) // Seek-Function 3297 { 3298 sal_uIntPtr nPos = pStrm->Tell(); 3299 if( pSbStrm->IsRandom() ) 3300 nPos = nPos / pSbStrm->GetBlockLen(); 3301 nPos++; // Basic zaehlt ab 1 3302 rPar.Get(0)->PutLong( (sal_Int32)nPos ); 3303 } 3304 else // Seek-Statement 3305 { 3306 sal_Int32 nPos = rPar.Get(2)->GetLong(); 3307 if ( nPos < 1 ) 3308 { 3309 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3310 return; 3311 } 3312 nPos--; // Basic zaehlt ab 1, SvStreams zaehlen ab 0 3313 pSbStrm->SetExpandOnWriteTo( 0 ); 3314 if ( pSbStrm->IsRandom() ) 3315 nPos *= pSbStrm->GetBlockLen(); 3316 pStrm->Seek( (sal_uIntPtr)nPos ); 3317 pSbStrm->SetExpandOnWriteTo( nPos ); 3318 } 3319 } 3320 3321 RTLFUNC(Format) 3322 { 3323 (void)pBasic; 3324 (void)bWrite; 3325 3326 sal_uInt16 nArgCount = (sal_uInt16)rPar.Count(); 3327 if ( nArgCount < 2 || nArgCount > 3 ) 3328 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3329 else 3330 { 3331 String aResult; 3332 if( nArgCount == 2 ) 3333 rPar.Get(1)->Format( aResult ); 3334 else 3335 { 3336 String aFmt( rPar.Get(2)->GetString() ); 3337 rPar.Get(1)->Format( aResult, &aFmt ); 3338 } 3339 rPar.Get(0)->PutString( aResult ); 3340 } 3341 } 3342 3343 RTLFUNC(Randomize) 3344 { 3345 (void)pBasic; 3346 (void)bWrite; 3347 3348 if ( rPar.Count() > 2 ) 3349 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3350 sal_Int16 nSeed; 3351 if( rPar.Count() == 2 ) 3352 nSeed = (sal_Int16)rPar.Get(1)->GetInteger(); 3353 else 3354 nSeed = (sal_Int16)rand(); 3355 srand( nSeed ); 3356 } 3357 3358 RTLFUNC(Rnd) 3359 { 3360 (void)pBasic; 3361 (void)bWrite; 3362 3363 if ( rPar.Count() > 2 ) 3364 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3365 else 3366 { 3367 double nRand = (double)rand(); 3368 nRand = ( nRand / (double)RAND_MAX ); 3369 rPar.Get(0)->PutDouble( nRand ); 3370 } 3371 } 3372 3373 3374 // 3375 // Syntax: Shell("Path",[ Window-Style,[ "Params", [ bSync = sal_False ]]]) 3376 // 3377 // WindowStyles (VBA-kompatibel): 3378 // 2 == Minimized 3379 // 3 == Maximized 3380 // 10 == Full-Screen (Textmodus-Anwendungen OS/2, WIN95, WNT) 3381 // 3382 // !!!HACK der WindowStyle wird im Creator an Application::StartApp 3383 // uebergeben. Format: "xxxx2" 3384 // 3385 3386 3387 RTLFUNC(Shell) 3388 { 3389 (void)pBasic; 3390 (void)bWrite; 3391 3392 // No shell command for "virtual" portal users 3393 if( needSecurityRestrictions() ) 3394 { 3395 StarBASIC::Error(SbERR_NOT_IMPLEMENTED); 3396 return; 3397 } 3398 3399 sal_uIntPtr nArgCount = rPar.Count(); 3400 if ( nArgCount < 2 || nArgCount > 5 ) 3401 { 3402 rPar.Get(0)->PutLong(0); 3403 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3404 } 3405 else 3406 { 3407 sal_uInt16 nOptions = vos::OProcess::TOption_SearchPath| 3408 vos::OProcess::TOption_Detached; 3409 String aCmdLine = rPar.Get(1)->GetString(); 3410 // Zusaetzliche Parameter anhaengen, es muss eh alles geparsed werden 3411 if( nArgCount >= 4 ) 3412 { 3413 aCmdLine.AppendAscii( " " ); 3414 aCmdLine += rPar.Get(3)->GetString(); 3415 } 3416 else if( !aCmdLine.Len() ) 3417 { 3418 // Spezial-Behandlung (leere Liste) vermeiden 3419 aCmdLine.AppendAscii( " " ); 3420 } 3421 sal_uInt16 nLen = aCmdLine.Len(); 3422 3423 // #55735 Wenn Parameter dabei sind, muessen die abgetrennt werden 3424 // #72471 Auch die einzelnen Parameter trennen 3425 std::list<String> aTokenList; 3426 String aToken; 3427 sal_uInt16 i = 0; 3428 sal_Unicode c; 3429 while( i < nLen ) 3430 { 3431 // Spaces weg 3432 for ( ;; ++i ) 3433 { 3434 c = aCmdLine.GetBuffer()[ i ]; 3435 if ( c != ' ' && c != '\t' ) 3436 break; 3437 } 3438 3439 if( c == '\"' || c == '\'' ) 3440 { 3441 sal_uInt16 iFoundPos = aCmdLine.Search( c, i + 1 ); 3442 3443 // Wenn nichts gefunden wurde, Rest kopieren 3444 if( iFoundPos == STRING_NOTFOUND ) 3445 { 3446 aToken = aCmdLine.Copy( i, STRING_LEN ); 3447 i = nLen; 3448 } 3449 else 3450 { 3451 aToken = aCmdLine.Copy( i + 1, (iFoundPos - i - 1) ); 3452 i = iFoundPos + 1; 3453 } 3454 } 3455 else 3456 { 3457 sal_uInt16 iFoundSpacePos = aCmdLine.Search( ' ', i ); 3458 sal_uInt16 iFoundTabPos = aCmdLine.Search( '\t', i ); 3459 sal_uInt16 iFoundPos = Min( iFoundSpacePos, iFoundTabPos ); 3460 3461 // Wenn nichts gefunden wurde, Rest kopieren 3462 if( iFoundPos == STRING_NOTFOUND ) 3463 { 3464 aToken = aCmdLine.Copy( i, STRING_LEN ); 3465 i = nLen; 3466 } 3467 else 3468 { 3469 aToken = aCmdLine.Copy( i, (iFoundPos - i) ); 3470 i = iFoundPos; 3471 } 3472 } 3473 3474 // In die Liste uebernehmen 3475 aTokenList.push_back( aToken ); 3476 } 3477 // #55735 / #72471 Ende 3478 3479 sal_Int16 nWinStyle = 0; 3480 if( nArgCount >= 3 ) 3481 { 3482 nWinStyle = rPar.Get(2)->GetInteger(); 3483 switch( nWinStyle ) 3484 { 3485 case 2: 3486 nOptions |= vos::OProcess::TOption_Minimized; 3487 break; 3488 case 3: 3489 nOptions |= vos::OProcess::TOption_Maximized; 3490 break; 3491 case 10: 3492 nOptions |= vos::OProcess::TOption_FullScreen; 3493 break; 3494 } 3495 3496 sal_Bool bSync = sal_False; 3497 if( nArgCount >= 5 ) 3498 bSync = rPar.Get(4)->GetBool(); 3499 if( bSync ) 3500 nOptions |= vos::OProcess::TOption_Wait; 3501 } 3502 vos::OProcess::TProcessOption eOptions = 3503 (vos::OProcess::TProcessOption)nOptions; 3504 3505 3506 // #72471 Parameter aufbereiten 3507 std::list<String>::const_iterator iter = aTokenList.begin(); 3508 const String& rStr = *iter; 3509 ::rtl::OUString aOUStrProg( rStr.GetBuffer(), rStr.Len() ); 3510 String aOUStrProgUNC = getFullPathUNC( aOUStrProg ); 3511 3512 iter++; 3513 3514 sal_uInt16 nParamCount = sal::static_int_cast< sal_uInt16 >( 3515 aTokenList.size() - 1 ); 3516 ::rtl::OUString* pArgumentList = NULL; 3517 //const char** pParamList = NULL; 3518 if( nParamCount ) 3519 { 3520 pArgumentList = new ::rtl::OUString[ nParamCount ]; 3521 //pParamList = new const char*[ nParamCount ]; 3522 sal_uInt16 iList = 0; 3523 while( iter != aTokenList.end() ) 3524 { 3525 const String& rParamStr = (*iter); 3526 pArgumentList[iList++] = ::rtl::OUString( rParamStr.GetBuffer(), rParamStr.Len() ); 3527 //pParamList[iList++] = (*iter).GetStr(); 3528 iter++; 3529 } 3530 } 3531 3532 //const char* pParams = aParams.Len() ? aParams.GetStr() : 0; 3533 vos::OProcess* pApp; 3534 pApp = new vos::OProcess( aOUStrProgUNC ); 3535 sal_Bool bSucc; 3536 if( nParamCount == 0 ) 3537 { 3538 bSucc = pApp->execute( eOptions ) == vos::OProcess::E_None; 3539 } 3540 else 3541 { 3542 vos::OArgumentList aArgList( pArgumentList, nParamCount ); 3543 bSucc = pApp->execute( eOptions, aArgList ) == vos::OProcess::E_None; 3544 } 3545 3546 /* 3547 if( nParamCount == 0 ) 3548 pApp = new vos::OProcess( pProg ); 3549 else 3550 pApp = new vos::OProcess( pProg, pParamList, nParamCount ); 3551 sal_Bool bSucc = pApp->execute( eOptions ) == vos::OProcess::E_None; 3552 */ 3553 3554 delete pApp; 3555 delete[] pArgumentList; 3556 if( !bSucc ) 3557 StarBASIC::Error( SbERR_FILE_NOT_FOUND ); 3558 else 3559 rPar.Get(0)->PutLong( 0 ); 3560 } 3561 } 3562 3563 RTLFUNC(VarType) 3564 { 3565 (void)pBasic; 3566 (void)bWrite; 3567 3568 if ( rPar.Count() != 2 ) 3569 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3570 else 3571 { 3572 SbxDataType eType = rPar.Get(1)->GetType(); 3573 rPar.Get(0)->PutInteger( (sal_Int16)eType ); 3574 } 3575 } 3576 3577 // Exported function 3578 String getBasicTypeName( SbxDataType eType ) 3579 { 3580 static const char* pTypeNames[] = 3581 { 3582 "Empty", // SbxEMPTY 3583 "Null", // SbxNULL 3584 "Integer", // SbxINTEGER 3585 "Long", // SbxLONG 3586 "Single", // SbxSINGLE 3587 "Double", // SbxDOUBLE 3588 "Currency", // SbxCURRENCY 3589 "Date", // SbxDATE 3590 "String", // SbxSTRING 3591 "Object", // SbxOBJECT 3592 "Error", // SbxERROR 3593 "Boolean", // SbxBOOL 3594 "Variant", // SbxVARIANT 3595 "DataObject", // SbxDATAOBJECT 3596 "Unknown Type", // 3597 "Unknown Type", // 3598 "Char", // SbxCHAR 3599 "Byte", // SbxBYTE 3600 "UShort", // SbxUSHORT 3601 "ULong", // SbxULONG 3602 "Long64", // SbxLONG64 3603 "ULong64", // SbxULONG64 3604 "Int", // SbxINT 3605 "UInt", // SbxUINT 3606 "Void", // SbxVOID 3607 "HResult", // SbxHRESULT 3608 "Pointer", // SbxPOINTER 3609 "DimArray", // SbxDIMARRAY 3610 "CArray", // SbxCARRAY 3611 "Userdef", // SbxUSERDEF 3612 "Lpstr", // SbxLPSTR 3613 "Lpwstr", // SbxLPWSTR 3614 "Unknown Type", // SbxCoreSTRING 3615 "WString", // SbxWSTRING 3616 "WChar", // SbxWCHAR 3617 "Int64", // SbxSALINT64 3618 "UInt64", // SbxSALUINT64 3619 "Decimal", // SbxDECIMAL 3620 }; 3621 3622 int nPos = ((int)eType) & 0x0FFF; 3623 sal_uInt16 nTypeNameCount = sizeof( pTypeNames ) / sizeof( char* ); 3624 if ( nPos < 0 || nPos >= nTypeNameCount ) 3625 nPos = nTypeNameCount - 1; 3626 String aRetStr = String::CreateFromAscii( pTypeNames[nPos] ); 3627 return aRetStr; 3628 } 3629 3630 RTLFUNC(TypeName) 3631 { 3632 (void)pBasic; 3633 (void)bWrite; 3634 3635 if ( rPar.Count() != 2 ) 3636 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3637 else 3638 { 3639 SbxDataType eType = rPar.Get(1)->GetType(); 3640 sal_Bool bIsArray = ( ( eType & SbxARRAY ) != 0 ); 3641 String aRetStr = getBasicTypeName( eType ); 3642 if( bIsArray ) 3643 aRetStr.AppendAscii( "()" ); 3644 rPar.Get(0)->PutString( aRetStr ); 3645 } 3646 } 3647 3648 RTLFUNC(Len) 3649 { 3650 (void)pBasic; 3651 (void)bWrite; 3652 3653 if ( rPar.Count() != 2 ) 3654 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3655 else 3656 { 3657 const String& rStr = rPar.Get(1)->GetString(); 3658 rPar.Get(0)->PutLong( (sal_Int32)rStr.Len() ); 3659 } 3660 } 3661 3662 RTLFUNC(DDEInitiate) 3663 { 3664 (void)pBasic; 3665 (void)bWrite; 3666 3667 // No DDE for "virtual" portal users 3668 if( needSecurityRestrictions() ) 3669 { 3670 StarBASIC::Error(SbERR_NOT_IMPLEMENTED); 3671 return; 3672 } 3673 3674 int nArgs = (int)rPar.Count(); 3675 if ( nArgs != 3 ) 3676 { 3677 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3678 return; 3679 } 3680 const String& rApp = rPar.Get(1)->GetString(); 3681 const String& rTopic = rPar.Get(2)->GetString(); 3682 3683 SbiDdeControl* pDDE = pINST->GetDdeControl(); 3684 sal_Int16 nChannel; 3685 SbError nDdeErr = pDDE->Initiate( rApp, rTopic, nChannel ); 3686 if( nDdeErr ) 3687 StarBASIC::Error( nDdeErr ); 3688 else 3689 rPar.Get(0)->PutInteger( nChannel ); 3690 } 3691 3692 RTLFUNC(DDETerminate) 3693 { 3694 (void)pBasic; 3695 (void)bWrite; 3696 3697 // No DDE for "virtual" portal users 3698 if( needSecurityRestrictions() ) 3699 { 3700 StarBASIC::Error(SbERR_NOT_IMPLEMENTED); 3701 return; 3702 } 3703 3704 rPar.Get(0)->PutEmpty(); 3705 int nArgs = (int)rPar.Count(); 3706 if ( nArgs != 2 ) 3707 { 3708 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3709 return; 3710 } 3711 sal_Int16 nChannel = rPar.Get(1)->GetInteger(); 3712 SbiDdeControl* pDDE = pINST->GetDdeControl(); 3713 SbError nDdeErr = pDDE->Terminate( nChannel ); 3714 if( nDdeErr ) 3715 StarBASIC::Error( nDdeErr ); 3716 } 3717 3718 RTLFUNC(DDETerminateAll) 3719 { 3720 (void)pBasic; 3721 (void)bWrite; 3722 3723 // No DDE for "virtual" portal users 3724 if( needSecurityRestrictions() ) 3725 { 3726 StarBASIC::Error(SbERR_NOT_IMPLEMENTED); 3727 return; 3728 } 3729 3730 rPar.Get(0)->PutEmpty(); 3731 int nArgs = (int)rPar.Count(); 3732 if ( nArgs != 1 ) 3733 { 3734 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3735 return; 3736 } 3737 3738 SbiDdeControl* pDDE = pINST->GetDdeControl(); 3739 SbError nDdeErr = pDDE->TerminateAll(); 3740 if( nDdeErr ) 3741 StarBASIC::Error( nDdeErr ); 3742 3743 } 3744 3745 RTLFUNC(DDERequest) 3746 { 3747 (void)pBasic; 3748 (void)bWrite; 3749 3750 // No DDE for "virtual" portal users 3751 if( needSecurityRestrictions() ) 3752 { 3753 StarBASIC::Error(SbERR_NOT_IMPLEMENTED); 3754 return; 3755 } 3756 3757 int nArgs = (int)rPar.Count(); 3758 if ( nArgs != 3 ) 3759 { 3760 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3761 return; 3762 } 3763 sal_Int16 nChannel = rPar.Get(1)->GetInteger(); 3764 const String& rItem = rPar.Get(2)->GetString(); 3765 SbiDdeControl* pDDE = pINST->GetDdeControl(); 3766 String aResult; 3767 SbError nDdeErr = pDDE->Request( nChannel, rItem, aResult ); 3768 if( nDdeErr ) 3769 StarBASIC::Error( nDdeErr ); 3770 else 3771 rPar.Get(0)->PutString( aResult ); 3772 } 3773 3774 RTLFUNC(DDEExecute) 3775 { 3776 (void)pBasic; 3777 (void)bWrite; 3778 3779 // No DDE for "virtual" portal users 3780 if( needSecurityRestrictions() ) 3781 { 3782 StarBASIC::Error(SbERR_NOT_IMPLEMENTED); 3783 return; 3784 } 3785 3786 rPar.Get(0)->PutEmpty(); 3787 int nArgs = (int)rPar.Count(); 3788 if ( nArgs != 3 ) 3789 { 3790 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3791 return; 3792 } 3793 sal_Int16 nChannel = rPar.Get(1)->GetInteger(); 3794 const String& rCommand = rPar.Get(2)->GetString(); 3795 SbiDdeControl* pDDE = pINST->GetDdeControl(); 3796 SbError nDdeErr = pDDE->Execute( nChannel, rCommand ); 3797 if( nDdeErr ) 3798 StarBASIC::Error( nDdeErr ); 3799 } 3800 3801 RTLFUNC(DDEPoke) 3802 { 3803 (void)pBasic; 3804 (void)bWrite; 3805 3806 // No DDE for "virtual" portal users 3807 if( needSecurityRestrictions() ) 3808 { 3809 StarBASIC::Error(SbERR_NOT_IMPLEMENTED); 3810 return; 3811 } 3812 3813 rPar.Get(0)->PutEmpty(); 3814 int nArgs = (int)rPar.Count(); 3815 if ( nArgs != 4 ) 3816 { 3817 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3818 return; 3819 } 3820 sal_Int16 nChannel = rPar.Get(1)->GetInteger(); 3821 const String& rItem = rPar.Get(2)->GetString(); 3822 const String& rData = rPar.Get(3)->GetString(); 3823 SbiDdeControl* pDDE = pINST->GetDdeControl(); 3824 SbError nDdeErr = pDDE->Poke( nChannel, rItem, rData ); 3825 if( nDdeErr ) 3826 StarBASIC::Error( nDdeErr ); 3827 } 3828 3829 3830 RTLFUNC(FreeFile) 3831 { 3832 (void)pBasic; 3833 (void)bWrite; 3834 3835 if ( rPar.Count() != 1 ) 3836 { 3837 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3838 return; 3839 } 3840 SbiIoSystem* pIO = pINST->GetIoSystem(); 3841 short nChannel = 1; 3842 while( nChannel < CHANNELS ) 3843 { 3844 SbiStream* pStrm = pIO->GetStream( nChannel ); 3845 if( !pStrm ) 3846 { 3847 rPar.Get(0)->PutInteger( nChannel ); 3848 return; 3849 } 3850 nChannel++; 3851 } 3852 StarBASIC::Error( SbERR_TOO_MANY_FILES ); 3853 } 3854 3855 RTLFUNC(LBound) 3856 { 3857 (void)pBasic; 3858 (void)bWrite; 3859 3860 sal_uInt16 nParCount = rPar.Count(); 3861 if ( nParCount != 3 && nParCount != 2 ) 3862 { 3863 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3864 return; 3865 } 3866 SbxBase* pParObj = rPar.Get(1)->GetObject(); 3867 SbxDimArray* pArr = PTR_CAST(SbxDimArray,pParObj); 3868 if( pArr ) 3869 { 3870 sal_Int32 nLower, nUpper; 3871 short nDim = (nParCount == 3) ? (short)rPar.Get(2)->GetInteger() : 1; 3872 if( !pArr->GetDim32( nDim, nLower, nUpper ) ) 3873 StarBASIC::Error( SbERR_OUT_OF_RANGE ); 3874 else 3875 rPar.Get(0)->PutLong( nLower ); 3876 } 3877 else 3878 StarBASIC::Error( SbERR_MUST_HAVE_DIMS ); 3879 } 3880 3881 RTLFUNC(UBound) 3882 { 3883 (void)pBasic; 3884 (void)bWrite; 3885 3886 sal_uInt16 nParCount = rPar.Count(); 3887 if ( nParCount != 3 && nParCount != 2 ) 3888 { 3889 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3890 return; 3891 } 3892 3893 SbxBase* pParObj = rPar.Get(1)->GetObject(); 3894 SbxDimArray* pArr = PTR_CAST(SbxDimArray,pParObj); 3895 if( pArr ) 3896 { 3897 sal_Int32 nLower, nUpper; 3898 short nDim = (nParCount == 3) ? (short)rPar.Get(2)->GetInteger() : 1; 3899 if( !pArr->GetDim32( nDim, nLower, nUpper ) ) 3900 StarBASIC::Error( SbERR_OUT_OF_RANGE ); 3901 else 3902 rPar.Get(0)->PutLong( nUpper ); 3903 } 3904 else 3905 StarBASIC::Error( SbERR_MUST_HAVE_DIMS ); 3906 } 3907 3908 RTLFUNC(RGB) 3909 { 3910 (void)pBasic; 3911 (void)bWrite; 3912 3913 if ( rPar.Count() != 4 ) 3914 { 3915 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3916 return; 3917 } 3918 3919 sal_uIntPtr nRed = rPar.Get(1)->GetInteger() & 0xFF; 3920 sal_uIntPtr nGreen = rPar.Get(2)->GetInteger() & 0xFF; 3921 sal_uIntPtr nBlue = rPar.Get(3)->GetInteger() & 0xFF; 3922 sal_uIntPtr nRGB; 3923 3924 SbiInstance* pInst = pINST; 3925 bool bCompatibility = ( pInst && pInst->IsCompatibility() ); 3926 if( bCompatibility ) 3927 { 3928 nRGB = (nBlue << 16) | (nGreen << 8) | nRed; 3929 } 3930 else 3931 { 3932 nRGB = (nRed << 16) | (nGreen << 8) | nBlue; 3933 } 3934 rPar.Get(0)->PutLong( nRGB ); 3935 } 3936 3937 RTLFUNC(QBColor) 3938 { 3939 (void)pBasic; 3940 (void)bWrite; 3941 3942 static const sal_Int32 pRGB[] = 3943 { 3944 0x000000, 3945 0x800000, 3946 0x008000, 3947 0x808000, 3948 0x000080, 3949 0x800080, 3950 0x008080, 3951 0xC0C0C0, 3952 0x808080, 3953 0xFF0000, 3954 0x00FF00, 3955 0xFFFF00, 3956 0x0000FF, 3957 0xFF00FF, 3958 0x00FFFF, 3959 0xFFFFFF, 3960 }; 3961 3962 if ( rPar.Count() != 2 ) 3963 { 3964 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3965 return; 3966 } 3967 3968 sal_Int16 nCol = rPar.Get(1)->GetInteger(); 3969 if( nCol < 0 || nCol > 15 ) 3970 { 3971 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3972 return; 3973 } 3974 sal_Int32 nRGB = pRGB[ nCol ]; 3975 rPar.Get(0)->PutLong( nRGB ); 3976 } 3977 3978 // StrConv(string, conversion, LCID) 3979 RTLFUNC(StrConv) 3980 { 3981 (void)pBasic; 3982 (void)bWrite; 3983 3984 sal_uIntPtr nArgCount = rPar.Count()-1; 3985 if( nArgCount < 2 || nArgCount > 3 ) 3986 { 3987 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 3988 return; 3989 } 3990 3991 String aOldStr = rPar.Get(1)->GetString(); 3992 sal_Int32 nConversion = rPar.Get(2)->GetLong(); 3993 3994 sal_uInt16 nLanguage = LANGUAGE_SYSTEM; 3995 if( nArgCount == 3 ) 3996 { 3997 // LCID not supported now 3998 //nLanguage = rPar.Get(3)->GetInteger(); 3999 } 4000 4001 sal_uInt16 nOldLen = aOldStr.Len(); 4002 if( nOldLen == 0 ) 4003 { 4004 // null string,return 4005 rPar.Get(0)->PutString(aOldStr); 4006 return; 4007 } 4008 4009 sal_Int32 nType = 0; 4010 if ( (nConversion & 0x03) == 3 ) // vbProperCase 4011 { 4012 CharClass& rCharClass = GetCharClass(); 4013 aOldStr = rCharClass.toTitle( aOldStr.ToLowerAscii(), 0, nOldLen ); 4014 } 4015 else if ( (nConversion & 0x01) == 1 ) // vbUpperCase 4016 nType |= ::com::sun::star::i18n::TransliterationModules_LOWERCASE_UPPERCASE; 4017 else if ( (nConversion & 0x02) == 2 ) // vbLowerCase 4018 nType |= ::com::sun::star::i18n::TransliterationModules_UPPERCASE_LOWERCASE; 4019 4020 if ( (nConversion & 0x04) == 4 ) // vbWide 4021 nType |= ::com::sun::star::i18n::TransliterationModules_HALFWIDTH_FULLWIDTH; 4022 else if ( (nConversion & 0x08) == 8 ) // vbNarrow 4023 nType |= ::com::sun::star::i18n::TransliterationModules_FULLWIDTH_HALFWIDTH; 4024 4025 if ( (nConversion & 0x10) == 16) // vbKatakana 4026 nType |= ::com::sun::star::i18n::TransliterationModules_HIRAGANA_KATAKANA; 4027 else if ( (nConversion & 0x20) == 32 ) // vbHiragana 4028 nType |= ::com::sun::star::i18n::TransliterationModules_KATAKANA_HIRAGANA; 4029 4030 String aNewStr( aOldStr ); 4031 if( nType != 0 ) 4032 { 4033 com::sun::star::uno::Reference< XMultiServiceFactory > xSMgr = getProcessServiceFactory(); 4034 ::utl::TransliterationWrapper aTransliterationWrapper( xSMgr,nType ); 4035 com::sun::star::uno::Sequence<sal_Int32> aOffsets; 4036 aTransliterationWrapper.loadModuleIfNeeded( nLanguage ); 4037 aNewStr = aTransliterationWrapper.transliterate( aOldStr, nLanguage, 0, nOldLen, &aOffsets ); 4038 } 4039 4040 if ( (nConversion & 0x40) == 64 ) // vbUnicode 4041 { 4042 // convert the string to byte string, preserving unicode (2 bytes per character) 4043 sal_uInt16 nSize = aNewStr.Len()*2; 4044 const sal_Unicode* pSrc = aNewStr.GetBuffer(); 4045 sal_Char* pChar = new sal_Char[nSize+1]; 4046 for( sal_uInt16 i=0; i < nSize; i++ ) 4047 { 4048 pChar[i] = static_cast< sal_Char >( i%2 ? ((*pSrc) >> 8) & 0xff : (*pSrc) & 0xff ); 4049 if( i%2 ) 4050 pSrc++; 4051 } 4052 pChar[nSize] = '\0'; 4053 ::rtl::OString aOStr(pChar); 4054 4055 // there is no concept about default codepage in unix. so it is incorrectly in unix 4056 ::rtl::OUString aOUStr = ::rtl::OStringToOUString(aOStr, osl_getThreadTextEncoding()); 4057 aNewStr = String(aOUStr); 4058 rPar.Get(0)->PutString( aNewStr ); 4059 return; 4060 } 4061 else if ( (nConversion & 0x80) == 128 ) // vbFromUnicode 4062 { 4063 ::rtl::OUString aOUStr(aNewStr); 4064 // there is no concept about default codepage in unix. so it is incorrectly in unix 4065 ::rtl::OString aOStr = ::rtl::OUStringToOString(aNewStr,osl_getThreadTextEncoding()); 4066 const sal_Char* pChar = aOStr.getStr(); 4067 sal_uInt16 nArraySize = static_cast< sal_uInt16 >( aOStr.getLength() ); 4068 SbxDimArray* pArray = new SbxDimArray(SbxBYTE); 4069 bool bIncIndex = (IsBaseIndexOne() && SbiRuntime::isVBAEnabled() ); 4070 if(nArraySize) 4071 { 4072 if( bIncIndex ) 4073 pArray->AddDim( 1, nArraySize ); 4074 else 4075 pArray->AddDim( 0, nArraySize-1 ); 4076 } 4077 else 4078 { 4079 pArray->unoAddDim( 0, -1 ); 4080 } 4081 4082 for( sal_uInt16 i=0; i< nArraySize; i++) 4083 { 4084 SbxVariable* pNew = new SbxVariable( SbxBYTE ); 4085 pNew->PutByte(*pChar); 4086 pChar++; 4087 pNew->SetFlag( SBX_WRITE ); 4088 short index = i; 4089 if( bIncIndex ) 4090 ++index; 4091 pArray->Put( pNew, &index ); 4092 } 4093 4094 SbxVariableRef refVar = rPar.Get(0); 4095 sal_uInt16 nFlags = refVar->GetFlags(); 4096 refVar->ResetFlag( SBX_FIXED ); 4097 refVar->PutObject( pArray ); 4098 refVar->SetFlags( nFlags ); 4099 refVar->SetParameters( NULL ); 4100 return; 4101 } 4102 4103 rPar.Get(0)->PutString(aNewStr); 4104 } 4105 4106 4107 RTLFUNC(Beep) 4108 { 4109 (void)pBasic; 4110 (void)bWrite; 4111 4112 if ( rPar.Count() != 1 ) 4113 { 4114 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 4115 return; 4116 } 4117 Sound::Beep(); 4118 } 4119 4120 RTLFUNC(Load) 4121 { 4122 (void)pBasic; 4123 (void)bWrite; 4124 4125 if( rPar.Count() != 2 ) 4126 { 4127 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 4128 return; 4129 } 4130 4131 // Diesen Call einfach an das Object weiterreichen 4132 SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject(); 4133 if ( pObj ) 4134 { 4135 if( pObj->IsA( TYPE( SbUserFormModule ) ) ) 4136 { 4137 ((SbUserFormModule*)pObj)->Load(); 4138 } 4139 else if( pObj->IsA( TYPE( SbxObject ) ) ) 4140 { 4141 SbxVariable* pVar = ((SbxObject*)pObj)-> 4142 Find( String( RTL_CONSTASCII_USTRINGPARAM("Load") ), SbxCLASS_METHOD ); 4143 if( pVar ) 4144 pVar->GetInteger(); 4145 } 4146 } 4147 } 4148 4149 RTLFUNC(Unload) 4150 { 4151 (void)pBasic; 4152 (void)bWrite; 4153 4154 rPar.Get(0)->PutEmpty(); 4155 if( rPar.Count() != 2 ) 4156 { 4157 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 4158 return; 4159 } 4160 4161 // Diesen Call einfach an das Object weitereichen 4162 SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject(); 4163 if ( pObj ) 4164 { 4165 if( pObj->IsA( TYPE( SbUserFormModule ) ) ) 4166 { 4167 SbUserFormModule* pFormModule = ( SbUserFormModule* )pObj; 4168 pFormModule->Unload(); 4169 } 4170 else if( pObj->IsA( TYPE( SbxObject ) ) ) 4171 { 4172 SbxVariable* pVar = ((SbxObject*)pObj)-> 4173 Find( String( RTL_CONSTASCII_USTRINGPARAM("Unload") ), SbxCLASS_METHOD ); 4174 if( pVar ) 4175 pVar->GetInteger(); 4176 } 4177 } 4178 } 4179 4180 RTLFUNC(LoadPicture) 4181 { 4182 (void)pBasic; 4183 (void)bWrite; 4184 4185 if( rPar.Count() != 2 ) 4186 { 4187 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 4188 return; 4189 } 4190 4191 String aFileURL = getFullPath( rPar.Get(1)->GetString() ); 4192 SvStream* pStream = utl::UcbStreamHelper::CreateStream( aFileURL, STREAM_READ ); 4193 if( pStream != NULL ) 4194 { 4195 Bitmap aBmp; 4196 *pStream >> aBmp; 4197 Graphic aGraphic( aBmp ); 4198 4199 SbxObjectRef xRef = new SbStdPicture; 4200 ((SbStdPicture*)(SbxObject*)xRef)->SetGraphic( aGraphic ); 4201 rPar.Get(0)->PutObject( xRef ); 4202 } 4203 delete pStream; 4204 } 4205 4206 RTLFUNC(SavePicture) 4207 { 4208 (void)pBasic; 4209 (void)bWrite; 4210 4211 rPar.Get(0)->PutEmpty(); 4212 if( rPar.Count() != 3 ) 4213 { 4214 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 4215 return; 4216 } 4217 4218 SbxBase* pObj = (SbxObject*)rPar.Get(1)->GetObject(); 4219 if( pObj->IsA( TYPE( SbStdPicture ) ) ) 4220 { 4221 SvFileStream aOStream( rPar.Get(2)->GetString(), STREAM_WRITE | STREAM_TRUNC ); 4222 Graphic aGraphic = ((SbStdPicture*)pObj)->GetGraphic(); 4223 aOStream << aGraphic; 4224 } 4225 } 4226 4227 4228 //----------------------------------------------------------------------------------------- 4229 4230 RTLFUNC(AboutStarBasic) 4231 { 4232 (void)pBasic; 4233 (void)bWrite; 4234 (void)rPar; 4235 } 4236 4237 RTLFUNC(MsgBox) 4238 { 4239 (void)pBasic; 4240 (void)bWrite; 4241 4242 static const WinBits nStyleMap[] = 4243 { 4244 WB_OK, // MB_OK 4245 WB_OK_CANCEL, // MB_OKCANCEL 4246 WB_ABORT_RETRY_IGNORE, // MB_ABORTRETRYIGNORE 4247 WB_YES_NO_CANCEL, // MB_YESNOCANCEL 4248 WB_YES_NO, // MB_YESNO 4249 WB_RETRY_CANCEL // MB_RETRYCANCEL 4250 }; 4251 static const sal_Int16 nButtonMap[] = 4252 { 4253 2, // #define RET_CANCEL sal_False 4254 1, // #define RET_OK sal_True 4255 6, // #define RET_YES 2 4256 7, // #define RET_NO 3 4257 4 // #define RET_RETRY 4 4258 }; 4259 4260 4261 sal_uInt16 nArgCount = (sal_uInt16)rPar.Count(); 4262 if( nArgCount < 2 || nArgCount > 6 ) 4263 { 4264 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 4265 return; 4266 } 4267 WinBits nWinBits; 4268 WinBits nType = 0; // MB_OK 4269 if( nArgCount >= 3 ) 4270 nType = (WinBits)rPar.Get(2)->GetInteger(); 4271 WinBits nStyle = nType; 4272 nStyle &= 15; // Bits 4-16 loeschen 4273 if( nStyle > 5 ) 4274 nStyle = 0; 4275 4276 nWinBits = nStyleMap[ nStyle ]; 4277 4278 WinBits nWinDefBits; 4279 nWinDefBits = (WB_DEF_OK | WB_DEF_RETRY | WB_DEF_YES); 4280 if( nType & 256 ) 4281 { 4282 if( nStyle == 5 ) 4283 nWinDefBits = WB_DEF_CANCEL; 4284 else if( nStyle == 2 ) 4285 nWinDefBits = WB_DEF_RETRY; 4286 else 4287 nWinDefBits = (WB_DEF_CANCEL | WB_DEF_RETRY | WB_DEF_NO); 4288 } 4289 else if( nType & 512 ) 4290 { 4291 if( nStyle == 2) 4292 nWinDefBits = WB_DEF_IGNORE; 4293 else 4294 nWinDefBits = WB_DEF_CANCEL; 4295 } 4296 else if( nStyle == 2) 4297 nWinDefBits = WB_DEF_CANCEL; 4298 nWinBits |= nWinDefBits; 4299 4300 String aMsg = rPar.Get(1)->GetString(); 4301 String aTitle; 4302 if( nArgCount >= 4 ) 4303 aTitle = rPar.Get(3)->GetString(); 4304 else 4305 aTitle = GetpApp()->GetAppName(); 4306 4307 nType &= (16+32+64); 4308 MessBox* pBox = 0; 4309 Window* pParent = GetpApp()->GetDefDialogParent(); 4310 switch( nType ) 4311 { 4312 case 16: 4313 pBox = new ErrorBox( pParent, nWinBits, aMsg ); 4314 break; 4315 case 32: 4316 pBox = new QueryBox( pParent, nWinBits, aMsg ); 4317 break; 4318 case 48: 4319 pBox = new WarningBox( pParent, nWinBits, aMsg ); 4320 break; 4321 case 64: 4322 pBox = new InfoBox( pParent, aMsg ); 4323 break; 4324 default: 4325 pBox = new MessBox( pParent, nWinBits, aTitle, aMsg ); 4326 } 4327 pBox->SetText( aTitle ); 4328 sal_uInt16 nRet = (sal_uInt16)pBox->Execute(); 4329 if( nRet == sal_True ) 4330 nRet = 1; 4331 4332 sal_Int16 nMappedRet; 4333 if( nStyle == 2 ) 4334 { 4335 nMappedRet = nRet; 4336 if( nMappedRet == 0 ) 4337 nMappedRet = 3; // Abort 4338 } 4339 else 4340 nMappedRet = nButtonMap[ nRet ]; 4341 4342 rPar.Get(0)->PutInteger( nMappedRet ); 4343 delete pBox; 4344 } 4345 4346 RTLFUNC(SetAttr) // JSM 4347 { 4348 (void)pBasic; 4349 (void)bWrite; 4350 4351 rPar.Get(0)->PutEmpty(); 4352 if ( rPar.Count() == 3 ) 4353 { 4354 String aStr = rPar.Get(1)->GetString(); 4355 sal_Int16 nFlags = rPar.Get(2)->GetInteger(); 4356 4357 // <-- UCB 4358 if( hasUno() ) 4359 { 4360 com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); 4361 if( xSFI.is() ) 4362 { 4363 try 4364 { 4365 sal_Bool bReadOnly = (nFlags & 0x0001) != 0; // ATTR_READONLY 4366 xSFI->setReadOnly( aStr, bReadOnly ); 4367 sal_Bool bHidden = (nFlags & 0x0002) != 0; // ATTR_HIDDEN 4368 xSFI->setHidden( aStr, bHidden ); 4369 } 4370 catch( Exception & ) 4371 { 4372 StarBASIC::Error( ERRCODE_IO_GENERAL ); 4373 } 4374 } 4375 } 4376 else 4377 // --> UCB 4378 { 4379 #ifdef _OLD_FILE_IMPL 4380 // #57064 Bei virtuellen URLs den Real-Path extrahieren 4381 DirEntry aEntry( aStr ); 4382 String aFile = aEntry.GetFull(); 4383 ByteString aByteFile( aFile, gsl_getSystemTextEncoding() ); 4384 #ifdef WNT 4385 if (!SetFileAttributes (aByteFile.GetBuffer(),(DWORD)nFlags)) 4386 StarBASIC::Error(SbERR_FILE_NOT_FOUND); 4387 #endif 4388 #ifdef OS2 4389 FILESTATUS3 aFileStatus; 4390 APIRET rc = DosQueryPathInfo(aByteFile.GetBuffer(),1, 4391 &aFileStatus,sizeof(FILESTATUS3)); 4392 if (!rc) 4393 { 4394 if (aFileStatus.attrFile != nFlags) 4395 { 4396 aFileStatus.attrFile = nFlags; 4397 rc = DosSetPathInfo(aFile.GetStr(),1, 4398 &aFileStatus,sizeof(FILESTATUS3),0); 4399 if (rc) 4400 StarBASIC::Error( SbERR_FILE_NOT_FOUND ); 4401 } 4402 } 4403 else 4404 StarBASIC::Error( SbERR_FILE_NOT_FOUND ); 4405 #endif 4406 #else 4407 // Not implemented 4408 #endif 4409 } 4410 } 4411 else 4412 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 4413 } 4414 4415 RTLFUNC(Reset) // JSM 4416 { 4417 (void)pBasic; 4418 (void)bWrite; 4419 (void)rPar; 4420 4421 SbiIoSystem* pIO = pINST->GetIoSystem(); 4422 if (pIO) 4423 pIO->CloseAll(); 4424 } 4425 4426 RTLFUNC(DumpAllObjects) 4427 { 4428 (void)pBasic; 4429 (void)bWrite; 4430 4431 sal_uInt16 nArgCount = (sal_uInt16)rPar.Count(); 4432 if( nArgCount < 2 || nArgCount > 3 ) 4433 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 4434 else if( !pBasic ) 4435 StarBASIC::Error( SbERR_INTERNAL_ERROR ); 4436 else 4437 { 4438 SbxObject* p = pBasic; 4439 while( p->GetParent() ) 4440 p = p->GetParent(); 4441 SvFileStream aStrm( rPar.Get( 1 )->GetString(), 4442 STREAM_WRITE | STREAM_TRUNC ); 4443 p->Dump( aStrm, rPar.Get( 2 )->GetBool() ); 4444 aStrm.Close(); 4445 if( aStrm.GetError() != SVSTREAM_OK ) 4446 StarBASIC::Error( SbERR_IO_ERROR ); 4447 } 4448 } 4449 4450 4451 RTLFUNC(FileExists) 4452 { 4453 (void)pBasic; 4454 (void)bWrite; 4455 4456 if ( rPar.Count() == 2 ) 4457 { 4458 String aStr = rPar.Get(1)->GetString(); 4459 sal_Bool bExists = sal_False; 4460 4461 // <-- UCB 4462 if( hasUno() ) 4463 { 4464 com::sun::star::uno::Reference< XSimpleFileAccess3 > xSFI = getFileAccess(); 4465 if( xSFI.is() ) 4466 { 4467 try 4468 { 4469 bExists = xSFI->exists( aStr ); 4470 } 4471 catch( Exception & ) 4472 { 4473 StarBASIC::Error( ERRCODE_IO_GENERAL ); 4474 } 4475 } 4476 } 4477 else 4478 // --> UCB 4479 { 4480 #ifdef _OLD_FILE_IMPL 4481 DirEntry aEntry( aStr ); 4482 bExists = aEntry.Exists(); 4483 #else 4484 DirectoryItem aItem; 4485 FileBase::RC nRet = DirectoryItem::get( getFullPathUNC( aStr ), aItem ); 4486 bExists = (nRet == FileBase::E_None); 4487 #endif 4488 } 4489 rPar.Get(0)->PutBool( bExists ); 4490 } 4491 else 4492 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 4493 } 4494 4495 RTLFUNC(Partition) 4496 { 4497 (void)pBasic; 4498 (void)bWrite; 4499 4500 if ( rPar.Count() != 5 ) 4501 { 4502 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 4503 return; 4504 } 4505 4506 sal_Int32 nNumber = rPar.Get(1)->GetLong(); 4507 sal_Int32 nStart = rPar.Get(2)->GetLong(); 4508 sal_Int32 nStop = rPar.Get(3)->GetLong(); 4509 sal_Int32 nInterval = rPar.Get(4)->GetLong(); 4510 4511 if( nStart < 0 || nStop <= nStart || nInterval < 1 ) 4512 { 4513 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 4514 return; 4515 } 4516 4517 // the Partition function inserts leading spaces before lowervalue and uppervalue 4518 // so that they both have the same number of characters as the string 4519 // representation of the value (Stop + 1). This ensures that if you use the output 4520 // of the Partition function with several values of Number, the resulting text 4521 // will be handled properly during any subsequent sort operation. 4522 4523 // calculate the maximun number of characters before lowervalue and uppervalue 4524 ::rtl::OUString aBeforeStart = ::rtl::OUString::valueOf( nStart - 1 ); 4525 ::rtl::OUString aAfterStop = ::rtl::OUString::valueOf( nStop + 1 ); 4526 sal_Int32 nLen1 = aBeforeStart.getLength(); 4527 sal_Int32 nLen2 = aAfterStop.getLength(); 4528 sal_Int32 nLen = nLen1 >= nLen2 ? nLen1:nLen2; 4529 4530 ::rtl::OUStringBuffer aRetStr( nLen * 2 + 1); 4531 ::rtl::OUString aLowerValue; 4532 ::rtl::OUString aUpperValue; 4533 if( nNumber < nStart ) 4534 { 4535 aUpperValue = aBeforeStart; 4536 } 4537 else if( nNumber > nStop ) 4538 { 4539 aLowerValue = aAfterStop; 4540 } 4541 else 4542 { 4543 sal_Int32 nLowerValue = nNumber; 4544 sal_Int32 nUpperValue = nLowerValue; 4545 if( nInterval > 1 ) 4546 { 4547 nLowerValue = ((( nNumber - nStart ) / nInterval ) * nInterval ) + nStart; 4548 nUpperValue = nLowerValue + nInterval - 1; 4549 } 4550 4551 aLowerValue = ::rtl::OUString::valueOf( nLowerValue ); 4552 aUpperValue = ::rtl::OUString::valueOf( nUpperValue ); 4553 } 4554 4555 nLen1 = aLowerValue.getLength(); 4556 nLen2 = aUpperValue.getLength(); 4557 4558 if( nLen > nLen1 ) 4559 { 4560 // appending the leading spaces for the lowervalue 4561 for ( sal_Int32 i= (nLen - nLen1) ; i > 0; --i ) 4562 aRetStr.appendAscii(" "); 4563 } 4564 aRetStr.append( aLowerValue ).appendAscii(":"); 4565 if( nLen > nLen2 ) 4566 { 4567 // appending the leading spaces for the uppervalue 4568 for ( sal_Int32 i= (nLen - nLen2) ; i > 0; --i ) 4569 aRetStr.appendAscii(" "); 4570 } 4571 aRetStr.append( aUpperValue ); 4572 rPar.Get(0)->PutString( String(aRetStr.makeStringAndClear()) ); 4573 } 4574