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