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