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