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