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