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