File: | home/maarten/src/libreoffice/core/basic/source/runtime/methods1.cxx |
Warning: | line 2365, column 1 Potential leak of memory pointed to by 'pSbxVar.pObj' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | |||
2 | /* | |||
3 | * This file is part of the LibreOffice project. | |||
4 | * | |||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | |||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | |||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | |||
8 | * | |||
9 | * This file incorporates work covered by the following license notice: | |||
10 | * | |||
11 | * Licensed to the Apache Software Foundation (ASF) under one or more | |||
12 | * contributor license agreements. See the NOTICE file distributed | |||
13 | * with this work for additional information regarding copyright | |||
14 | * ownership. The ASF licenses this file to you under the Apache | |||
15 | * License, Version 2.0 (the "License"); you may not use this file | |||
16 | * except in compliance with the License. You may obtain a copy of | |||
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . | |||
18 | */ | |||
19 | ||||
20 | #include <config_features.h> | |||
21 | ||||
22 | #include <sal/config.h> | |||
23 | #include <config_version.h> | |||
24 | ||||
25 | #include <cstddef> | |||
26 | ||||
27 | #include <stdlib.h> | |||
28 | #include <vcl/svapp.hxx> | |||
29 | #include <vcl/mapmod.hxx> | |||
30 | #include <vcl/outdev.hxx> | |||
31 | #include <vcl/timer.hxx> | |||
32 | #include <vcl/settings.hxx> | |||
33 | #include <basic/sbxvar.hxx> | |||
34 | #include <basic/sbx.hxx> | |||
35 | #include <svl/zforlist.hxx> | |||
36 | #include <tools/urlobj.hxx> | |||
37 | #include <tools/fract.hxx> | |||
38 | #include <o3tl/temporary.hxx> | |||
39 | #include <osl/file.hxx> | |||
40 | #include <sbobjmod.hxx> | |||
41 | #include <basic/sbuno.hxx> | |||
42 | ||||
43 | #include <date.hxx> | |||
44 | #include <sbintern.hxx> | |||
45 | #include <runtime.hxx> | |||
46 | #include <rtlproto.hxx> | |||
47 | #include "dllmgr.hxx" | |||
48 | #include <iosys.hxx> | |||
49 | #include <sbunoobj.hxx> | |||
50 | #include <propacc.hxx> | |||
51 | #include <sal/log.hxx> | |||
52 | #include <eventatt.hxx> | |||
53 | ||||
54 | #include <comphelper/processfactory.hxx> | |||
55 | #include <comphelper/string.hxx> | |||
56 | ||||
57 | #include <com/sun/star/uno/Sequence.hxx> | |||
58 | #include <com/sun/star/lang/XMultiServiceFactory.hpp> | |||
59 | #include <com/sun/star/i18n/LocaleCalendar2.hpp> | |||
60 | #include <com/sun/star/sheet/XFunctionAccess.hpp> | |||
61 | #include <memory> | |||
62 | ||||
63 | using namespace comphelper; | |||
64 | using namespace com::sun::star::i18n; | |||
65 | using namespace com::sun::star::lang; | |||
66 | using namespace com::sun::star::sheet; | |||
67 | using namespace com::sun::star::uno; | |||
68 | ||||
69 | static Reference< XCalendar4 > const & getLocaleCalendar() | |||
70 | { | |||
71 | static Reference< XCalendar4 > xCalendar = LocaleCalendar2::create(getProcessComponentContext()); | |||
72 | static css::lang::Locale aLastLocale; | |||
73 | static bool bNeedsInit = true; | |||
74 | ||||
75 | css::lang::Locale aLocale = Application::GetSettings().GetLanguageTag().getLocale(); | |||
76 | bool bNeedsReload = false; | |||
77 | if( bNeedsInit ) | |||
78 | { | |||
79 | bNeedsInit = false; | |||
80 | bNeedsReload = true; | |||
81 | } | |||
82 | else if( aLocale.Language != aLastLocale.Language || | |||
83 | aLocale.Country != aLastLocale.Country || | |||
84 | aLocale.Variant != aLastLocale.Variant ) | |||
85 | { | |||
86 | bNeedsReload = true; | |||
87 | } | |||
88 | if( bNeedsReload ) | |||
89 | { | |||
90 | aLastLocale = aLocale; | |||
91 | xCalendar->loadDefaultCalendar( aLocale ); | |||
92 | } | |||
93 | return xCalendar; | |||
94 | } | |||
95 | ||||
96 | #if HAVE_FEATURE_SCRIPTING1 | |||
97 | ||||
98 | void SbRtl_CallByName(StarBASIC *, SbxArray & rPar, bool) | |||
99 | { | |||
100 | const sal_Int16 vbGet = 2; | |||
101 | const sal_Int16 vbLet = 4; | |||
102 | const sal_Int16 vbMethod = 1; | |||
103 | const sal_Int16 vbSet = 8; | |||
104 | ||||
105 | // At least 3 parameter needed plus function itself -> 4 | |||
106 | sal_uInt32 nParCount = rPar.Count32(); | |||
107 | if ( nParCount < 4 ) | |||
108 | { | |||
109 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
110 | return; | |||
111 | } | |||
112 | ||||
113 | // 1. parameter is object | |||
114 | SbxBase* pObjVar = rPar.Get32(1)->GetObject(); | |||
115 | SbxObject* pObj = nullptr; | |||
116 | if( pObjVar ) | |||
117 | pObj = dynamic_cast<SbxObject*>( pObjVar ); | |||
118 | if( !pObj && dynamic_cast<const SbxVariable*>( pObjVar) ) | |||
119 | { | |||
120 | SbxBase* pObjVarObj = static_cast<SbxVariable*>(pObjVar)->GetObject(); | |||
121 | pObj = dynamic_cast<SbxObject*>( pObjVarObj ); | |||
122 | } | |||
123 | if( !pObj ) | |||
124 | { | |||
125 | StarBASIC::Error( ERRCODE_BASIC_BAD_PARAMETERErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 7) ); | |||
126 | return; | |||
127 | } | |||
128 | ||||
129 | // 2. parameter is ProcedureName | |||
130 | OUString aNameStr = rPar.Get32(2)->GetOUString(); | |||
131 | ||||
132 | // 3. parameter is CallType | |||
133 | sal_Int16 nCallType = rPar.Get32(3)->GetInteger(); | |||
134 | ||||
135 | //SbxObject* pFindObj = NULL; | |||
136 | SbxVariable* pFindVar = pObj->Find( aNameStr, SbxClassType::DontCare ); | |||
137 | if( pFindVar == nullptr ) | |||
138 | { | |||
139 | StarBASIC::Error( ERRCODE_BASIC_PROC_UNDEFINEDErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 8) ); | |||
140 | return; | |||
141 | } | |||
142 | ||||
143 | switch( nCallType ) | |||
144 | { | |||
145 | case vbGet: | |||
146 | { | |||
147 | SbxValues aVals; | |||
148 | aVals.eType = SbxVARIANT; | |||
149 | pFindVar->Get( aVals ); | |||
150 | ||||
151 | SbxVariableRef refVar = rPar.Get32(0); | |||
152 | refVar->Put( aVals ); | |||
153 | } | |||
154 | break; | |||
155 | case vbLet: | |||
156 | case vbSet: | |||
157 | { | |||
158 | if ( nParCount != 5 ) | |||
159 | { | |||
160 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
161 | return; | |||
162 | } | |||
163 | SbxVariableRef pValVar = rPar.Get32(4); | |||
164 | if( nCallType == vbLet ) | |||
165 | { | |||
166 | SbxValues aVals; | |||
167 | aVals.eType = SbxVARIANT; | |||
168 | pValVar->Get( aVals ); | |||
169 | pFindVar->Put( aVals ); | |||
170 | } | |||
171 | else | |||
172 | { | |||
173 | SbxVariableRef rFindVar = pFindVar; | |||
174 | SbiInstance* pInst = GetSbData()->pInst; | |||
175 | SbiRuntime* pRT = pInst ? pInst->pRun : nullptr; | |||
176 | if( pRT != nullptr ) | |||
177 | { | |||
178 | pRT->StepSET_Impl( pValVar, rFindVar ); | |||
179 | } | |||
180 | } | |||
181 | } | |||
182 | break; | |||
183 | case vbMethod: | |||
184 | { | |||
185 | SbMethod* pMeth = dynamic_cast<SbMethod*>( pFindVar ); | |||
186 | if( pMeth == nullptr ) | |||
187 | { | |||
188 | StarBASIC::Error( ERRCODE_BASIC_PROC_UNDEFINEDErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 8) ); | |||
189 | return; | |||
190 | } | |||
191 | ||||
192 | // Setup parameters | |||
193 | SbxArrayRef xArray; | |||
194 | sal_uInt32 nMethParamCount = nParCount - 4; | |||
195 | if( nMethParamCount > 0 ) | |||
196 | { | |||
197 | xArray = new SbxArray; | |||
198 | for( sal_uInt32 i = 0 ; i < nMethParamCount ; i++ ) | |||
199 | { | |||
200 | SbxVariable* pPar = rPar.Get32( i + 4 ); | |||
201 | xArray->Put32( pPar, i + 1 ); | |||
202 | } | |||
203 | } | |||
204 | ||||
205 | // Call method | |||
206 | SbxVariableRef refVar = rPar.Get32(0); | |||
207 | if( xArray.is() ) | |||
208 | pMeth->SetParameters( xArray.get() ); | |||
209 | pMeth->Call( refVar.get() ); | |||
210 | pMeth->SetParameters( nullptr ); | |||
211 | } | |||
212 | break; | |||
213 | default: | |||
214 | StarBASIC::Error( ERRCODE_BASIC_PROC_UNDEFINEDErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 8) ); | |||
215 | } | |||
216 | } | |||
217 | ||||
218 | void SbRtl_CBool(StarBASIC *, SbxArray & rPar, bool) // JSM | |||
219 | { | |||
220 | bool bVal = false; | |||
221 | if ( rPar.Count32() == 2 ) | |||
222 | { | |||
223 | SbxVariable *pSbxVariable = rPar.Get32(1); | |||
224 | bVal = pSbxVariable->GetBool(); | |||
225 | } | |||
226 | else | |||
227 | { | |||
228 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
229 | } | |||
230 | rPar.Get32(0)->PutBool(bVal); | |||
231 | } | |||
232 | ||||
233 | void SbRtl_CByte(StarBASIC *, SbxArray & rPar, bool) // JSM | |||
234 | { | |||
235 | sal_uInt8 nByte = 0; | |||
236 | if ( rPar.Count32() == 2 ) | |||
237 | { | |||
238 | SbxVariable *pSbxVariable = rPar.Get32(1); | |||
239 | nByte = pSbxVariable->GetByte(); | |||
240 | } | |||
241 | else | |||
242 | { | |||
243 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
244 | } | |||
245 | rPar.Get32(0)->PutByte(nByte); | |||
246 | } | |||
247 | ||||
248 | void SbRtl_CCur(StarBASIC *, SbxArray & rPar, bool) | |||
249 | { | |||
250 | sal_Int64 nCur = 0; | |||
251 | if ( rPar.Count32() == 2 ) | |||
252 | { | |||
253 | SbxVariable *pSbxVariable = rPar.Get32(1); | |||
254 | nCur = pSbxVariable->GetCurrency(); | |||
255 | } | |||
256 | else | |||
257 | { | |||
258 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
259 | } | |||
260 | rPar.Get32(0)->PutCurrency( nCur ); | |||
261 | } | |||
262 | ||||
263 | void SbRtl_CDec(StarBASIC * pBasic, SbxArray & rPar, bool bWrite) | |||
264 | { | |||
265 | (void)pBasic; | |||
266 | (void)bWrite; | |||
267 | ||||
268 | #ifdef _WIN32 | |||
269 | SbxDecimal* pDec = nullptr; | |||
270 | if ( rPar.Count32() == 2 ) | |||
271 | { | |||
272 | SbxVariable *pSbxVariable = rPar.Get32(1); | |||
273 | pDec = pSbxVariable->GetDecimal(); | |||
274 | } | |||
275 | else | |||
276 | { | |||
277 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
278 | } | |||
279 | rPar.Get32(0)->PutDecimal( pDec ); | |||
280 | #else | |||
281 | rPar.Get32(0)->PutEmpty(); | |||
282 | StarBASIC::Error(ERRCODE_BASIC_NOT_IMPLEMENTEDErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 55 )); | |||
283 | #endif | |||
284 | } | |||
285 | ||||
286 | void SbRtl_CDate(StarBASIC *, SbxArray & rPar, bool) // JSM | |||
287 | { | |||
288 | double nVal = 0.0; | |||
289 | if ( rPar.Count32() == 2 ) | |||
290 | { | |||
291 | SbxVariable *pSbxVariable = rPar.Get32(1); | |||
292 | nVal = pSbxVariable->GetDate(); | |||
293 | } | |||
294 | else | |||
295 | { | |||
296 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
297 | } | |||
298 | rPar.Get32(0)->PutDate(nVal); | |||
299 | } | |||
300 | ||||
301 | void SbRtl_CDbl(StarBASIC *, SbxArray & rPar, bool) // JSM | |||
302 | { | |||
303 | double nVal = 0.0; | |||
304 | if ( rPar.Count32() == 2 ) | |||
305 | { | |||
306 | SbxVariable *pSbxVariable = rPar.Get32(1); | |||
307 | if( pSbxVariable->GetType() == SbxSTRING ) | |||
308 | { | |||
309 | // #41690 | |||
310 | OUString aScanStr = pSbxVariable->GetOUString(); | |||
311 | ErrCode Error = SbxValue::ScanNumIntnl( aScanStr, nVal ); | |||
312 | if( Error != ERRCODE_NONEErrCode(0) ) | |||
313 | { | |||
314 | StarBASIC::Error( Error ); | |||
315 | } | |||
316 | } | |||
317 | else | |||
318 | { | |||
319 | nVal = pSbxVariable->GetDouble(); | |||
320 | } | |||
321 | } | |||
322 | else | |||
323 | { | |||
324 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
325 | } | |||
326 | ||||
327 | rPar.Get32(0)->PutDouble(nVal); | |||
328 | } | |||
329 | ||||
330 | void SbRtl_CInt(StarBASIC *, SbxArray & rPar, bool) // JSM | |||
331 | { | |||
332 | sal_Int16 nVal = 0; | |||
333 | if ( rPar.Count32() == 2 ) | |||
334 | { | |||
335 | SbxVariable *pSbxVariable = rPar.Get32(1); | |||
336 | nVal = pSbxVariable->GetInteger(); | |||
337 | } | |||
338 | else | |||
339 | { | |||
340 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
341 | } | |||
342 | rPar.Get32(0)->PutInteger(nVal); | |||
343 | } | |||
344 | ||||
345 | void SbRtl_CLng(StarBASIC *, SbxArray & rPar, bool) // JSM | |||
346 | { | |||
347 | sal_Int32 nVal = 0; | |||
348 | if ( rPar.Count32() == 2 ) | |||
349 | { | |||
350 | SbxVariable *pSbxVariable = rPar.Get32(1); | |||
351 | nVal = pSbxVariable->GetLong(); | |||
352 | } | |||
353 | else | |||
354 | { | |||
355 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
356 | } | |||
357 | rPar.Get32(0)->PutLong(nVal); | |||
358 | } | |||
359 | ||||
360 | void SbRtl_CSng(StarBASIC *, SbxArray & rPar, bool) // JSM | |||
361 | { | |||
362 | float nVal = float(0.0); | |||
363 | if ( rPar.Count32() == 2 ) | |||
364 | { | |||
365 | SbxVariable *pSbxVariable = rPar.Get32(1); | |||
366 | if( pSbxVariable->GetType() == SbxSTRING ) | |||
367 | { | |||
368 | // #41690 | |||
369 | double dVal = 0.0; | |||
370 | OUString aScanStr = pSbxVariable->GetOUString(); | |||
371 | ErrCode Error = SbxValue::ScanNumIntnl( aScanStr, dVal, /*bSingle=*/true ); | |||
372 | if( SbxBase::GetError() == ERRCODE_NONEErrCode(0) && Error != ERRCODE_NONEErrCode(0) ) | |||
373 | { | |||
374 | StarBASIC::Error( Error ); | |||
375 | } | |||
376 | nVal = static_cast<float>(dVal); | |||
377 | } | |||
378 | else | |||
379 | { | |||
380 | nVal = pSbxVariable->GetSingle(); | |||
381 | } | |||
382 | } | |||
383 | else | |||
384 | { | |||
385 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
386 | } | |||
387 | rPar.Get32(0)->PutSingle(nVal); | |||
388 | } | |||
389 | ||||
390 | void SbRtl_CStr(StarBASIC *, SbxArray & rPar, bool) // JSM | |||
391 | { | |||
392 | OUString aString; | |||
393 | if ( rPar.Count32() == 2 ) | |||
394 | { | |||
395 | SbxVariable *pSbxVariable = rPar.Get32(1); | |||
396 | aString = pSbxVariable->GetOUString(); | |||
397 | } | |||
398 | else | |||
399 | { | |||
400 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
401 | } | |||
402 | rPar.Get32(0)->PutString(aString); | |||
403 | } | |||
404 | ||||
405 | void SbRtl_CVar(StarBASIC *, SbxArray & rPar, bool) // JSM | |||
406 | { | |||
407 | SbxValues aVals( SbxVARIANT ); | |||
408 | if ( rPar.Count32() == 2 ) | |||
409 | { | |||
410 | SbxVariable *pSbxVariable = rPar.Get32(1); | |||
411 | pSbxVariable->Get( aVals ); | |||
412 | } | |||
413 | else | |||
414 | { | |||
415 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
416 | } | |||
417 | rPar.Get32(0)->Put( aVals ); | |||
418 | } | |||
419 | ||||
420 | void SbRtl_CVErr(StarBASIC *, SbxArray & rPar, bool) | |||
421 | { | |||
422 | sal_Int16 nErrCode = 0; | |||
423 | if ( rPar.Count32() == 2 ) | |||
424 | { | |||
425 | SbxVariable *pSbxVariable = rPar.Get32(1); | |||
426 | nErrCode = pSbxVariable->GetInteger(); | |||
427 | } | |||
428 | else | |||
429 | { | |||
430 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
431 | } | |||
432 | rPar.Get32(0)->PutErr( nErrCode ); | |||
433 | } | |||
434 | ||||
435 | void SbRtl_Iif(StarBASIC *, SbxArray & rPar, bool) // JSM | |||
436 | { | |||
437 | if ( rPar.Count32() == 4 ) | |||
438 | { | |||
439 | if (rPar.Get32(1)->GetBool()) | |||
440 | { | |||
441 | *rPar.Get32(0) = *rPar.Get32(2); | |||
442 | } | |||
443 | else | |||
444 | { | |||
445 | *rPar.Get32(0) = *rPar.Get32(3); | |||
446 | } | |||
447 | } | |||
448 | else | |||
449 | { | |||
450 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
451 | } | |||
452 | } | |||
453 | ||||
454 | void SbRtl_GetSystemType(StarBASIC *, SbxArray & rPar, bool) | |||
455 | { | |||
456 | if ( rPar.Count32() != 1 ) | |||
457 | { | |||
458 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
459 | } | |||
460 | else | |||
461 | { | |||
462 | // Removed for SRC595 | |||
463 | rPar.Get32(0)->PutInteger( -1 ); | |||
464 | } | |||
465 | } | |||
466 | ||||
467 | void SbRtl_GetGUIType(StarBASIC * pBasic, SbxArray & rPar, bool bWrite) | |||
468 | { | |||
469 | (void)pBasic; | |||
470 | (void)bWrite; | |||
471 | ||||
472 | if ( rPar.Count32() != 1 ) | |||
473 | { | |||
474 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
475 | } | |||
476 | else | |||
477 | { | |||
478 | // 17.7.2000 Make simple solution for testtool / fat office | |||
479 | #if defined(_WIN32) | |||
480 | rPar.Get32(0)->PutInteger( 1 ); | |||
481 | #elif defined(UNX1) | |||
482 | rPar.Get32(0)->PutInteger( 4 ); | |||
483 | #else | |||
484 | rPar.Get32(0)->PutInteger( -1 ); | |||
485 | #endif | |||
486 | } | |||
487 | } | |||
488 | ||||
489 | void SbRtl_Red(StarBASIC *, SbxArray & rPar, bool) | |||
490 | { | |||
491 | if ( rPar.Count32() != 2 ) | |||
492 | { | |||
493 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
494 | } | |||
495 | else | |||
496 | { | |||
497 | sal_Int32 nRGB = rPar.Get32(1)->GetLong(); | |||
498 | nRGB &= 0x00FF0000; | |||
499 | nRGB >>= 16; | |||
500 | rPar.Get32(0)->PutInteger( static_cast<sal_Int16>(nRGB) ); | |||
501 | } | |||
502 | } | |||
503 | ||||
504 | void SbRtl_Green(StarBASIC *, SbxArray & rPar, bool) | |||
505 | { | |||
506 | if ( rPar.Count32() != 2 ) | |||
507 | { | |||
508 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
509 | } | |||
510 | else | |||
511 | { | |||
512 | sal_Int32 nRGB = rPar.Get32(1)->GetLong(); | |||
513 | nRGB &= 0x0000FF00; | |||
514 | nRGB >>= 8; | |||
515 | rPar.Get32(0)->PutInteger( static_cast<sal_Int16>(nRGB) ); | |||
516 | } | |||
517 | } | |||
518 | ||||
519 | void SbRtl_Blue(StarBASIC *, SbxArray & rPar, bool) | |||
520 | { | |||
521 | if ( rPar.Count32() != 2 ) | |||
522 | { | |||
523 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
524 | } | |||
525 | else | |||
526 | { | |||
527 | sal_Int32 nRGB = rPar.Get32(1)->GetLong(); | |||
528 | nRGB &= 0x000000FF; | |||
529 | rPar.Get32(0)->PutInteger( static_cast<sal_Int16>(nRGB) ); | |||
530 | } | |||
531 | } | |||
532 | ||||
533 | ||||
534 | void SbRtl_Switch(StarBASIC *, SbxArray & rPar, bool) | |||
535 | { | |||
536 | sal_uInt32 nCount = rPar.Count32(); | |||
537 | if( !(nCount & 0x0001 )) | |||
538 | { | |||
539 | // number of arguments must be odd | |||
540 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
541 | } | |||
542 | sal_uInt32 nCurExpr = 1; | |||
543 | while( nCurExpr < (nCount-1) ) | |||
544 | { | |||
545 | if( rPar.Get32( nCurExpr )->GetBool()) | |||
546 | { | |||
547 | (*rPar.Get32(0)) = *(rPar.Get32(nCurExpr+1)); | |||
548 | return; | |||
549 | } | |||
550 | nCurExpr += 2; | |||
551 | } | |||
552 | rPar.Get32(0)->PutNull(); | |||
553 | } | |||
554 | ||||
555 | //i#64882# Common wait impl for existing Wait and new WaitUntil | |||
556 | // rtl functions | |||
557 | void Wait_Impl( bool bDurationBased, SbxArray& rPar ) | |||
558 | { | |||
559 | if( rPar.Count32() != 2 ) | |||
560 | { | |||
561 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
562 | return; | |||
563 | } | |||
564 | long nWait = 0; | |||
565 | if ( bDurationBased ) | |||
566 | { | |||
567 | double dWait = rPar.Get32(1)->GetDouble(); | |||
568 | double dNow = Now_Impl(); | |||
569 | double dSecs = ( dWait - dNow ) * 24.0 * 3600.0; | |||
570 | nWait = static_cast<long>( dSecs * 1000 ); // wait in thousands of sec | |||
571 | } | |||
572 | else | |||
573 | { | |||
574 | nWait = rPar.Get32(1)->GetLong(); | |||
575 | } | |||
576 | if( nWait < 0 ) | |||
577 | { | |||
578 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
579 | return; | |||
580 | } | |||
581 | ||||
582 | Timer aTimer; | |||
583 | aTimer.SetTimeout( nWait ); | |||
584 | aTimer.Start(); | |||
585 | while ( aTimer.IsActive() ) | |||
586 | { | |||
587 | Application::Yield(); | |||
588 | } | |||
589 | } | |||
590 | ||||
591 | //i#64882# | |||
592 | void SbRtl_Wait(StarBASIC *, SbxArray & rPar, bool) | |||
593 | { | |||
594 | Wait_Impl( false, rPar ); | |||
595 | } | |||
596 | ||||
597 | //i#64882# add new WaitUntil ( for application.wait ) | |||
598 | // share wait_impl with 'normal' oobasic wait | |||
599 | void SbRtl_WaitUntil(StarBASIC *, SbxArray & rPar, bool) | |||
600 | { | |||
601 | Wait_Impl( true, rPar ); | |||
602 | } | |||
603 | ||||
604 | void SbRtl_DoEvents(StarBASIC *, SbxArray & rPar, bool) | |||
605 | { | |||
606 | // don't understand what upstream are up to | |||
607 | // we already process application events etc. in between | |||
608 | // basic runtime pcode ( on a timed basis ) | |||
609 | // always return 0 | |||
610 | rPar.Get32(0)->PutInteger( 0 ); | |||
611 | Application::Reschedule( true ); | |||
612 | } | |||
613 | ||||
614 | void SbRtl_GetGUIVersion(StarBASIC *, SbxArray & rPar, bool) | |||
615 | { | |||
616 | if ( rPar.Count32() != 1 ) | |||
617 | { | |||
618 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
619 | } | |||
620 | else | |||
621 | { | |||
622 | // Removed for SRC595 | |||
623 | rPar.Get32(0)->PutLong( -1 ); | |||
624 | } | |||
625 | } | |||
626 | ||||
627 | void SbRtl_Choose(StarBASIC *, SbxArray & rPar, bool) | |||
628 | { | |||
629 | if ( rPar.Count32() < 2 ) | |||
630 | { | |||
631 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
632 | } | |||
633 | sal_Int16 nIndex = rPar.Get32(1)->GetInteger(); | |||
634 | sal_uInt32 nCount = rPar.Count32(); | |||
635 | nCount--; | |||
636 | if( nCount == 1 || nIndex > sal::static_int_cast<sal_Int16>(nCount-1) || nIndex < 1 ) | |||
637 | { | |||
638 | rPar.Get32(0)->PutNull(); | |||
639 | return; | |||
640 | } | |||
641 | (*rPar.Get32(0)) = *(rPar.Get32(nIndex+1)); | |||
642 | } | |||
643 | ||||
644 | ||||
645 | void SbRtl_Trim(StarBASIC *, SbxArray & rPar, bool) | |||
646 | { | |||
647 | if ( rPar.Count32() < 2 ) | |||
648 | { | |||
649 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
650 | } | |||
651 | else | |||
652 | { | |||
653 | OUString aStr(comphelper::string::strip(rPar.Get32(1)->GetOUString(), ' ')); | |||
654 | rPar.Get32(0)->PutString(aStr); | |||
655 | } | |||
656 | } | |||
657 | ||||
658 | void SbRtl_GetSolarVersion(StarBASIC *, SbxArray & rPar, bool) | |||
659 | { | |||
660 | rPar.Get32(0)->PutLong( LIBO_VERSION_MAJOR7 * 10000 + LIBO_VERSION_MINOR1 * 100 + LIBO_VERSION_MICRO0 * 1); | |||
661 | } | |||
662 | ||||
663 | void SbRtl_TwipsPerPixelX(StarBASIC *, SbxArray & rPar, bool) | |||
664 | { | |||
665 | sal_Int32 nResult = 0; | |||
666 | Size aSize( 100,0 ); | |||
667 | MapMode aMap( MapUnit::MapTwip ); | |||
668 | OutputDevice* pDevice = Application::GetDefaultDevice(); | |||
669 | if( pDevice ) | |||
670 | { | |||
671 | aSize = pDevice->PixelToLogic( aSize, aMap ); | |||
672 | nResult = aSize.Width() / 100; | |||
673 | } | |||
674 | rPar.Get32(0)->PutLong( nResult ); | |||
675 | } | |||
676 | ||||
677 | void SbRtl_TwipsPerPixelY(StarBASIC *, SbxArray & rPar, bool) | |||
678 | { | |||
679 | sal_Int32 nResult = 0; | |||
680 | Size aSize( 0,100 ); | |||
681 | MapMode aMap( MapUnit::MapTwip ); | |||
682 | OutputDevice* pDevice = Application::GetDefaultDevice(); | |||
683 | if( pDevice ) | |||
684 | { | |||
685 | aSize = pDevice->PixelToLogic( aSize, aMap ); | |||
686 | nResult = aSize.Height() / 100; | |||
687 | } | |||
688 | rPar.Get32(0)->PutLong( nResult ); | |||
689 | } | |||
690 | ||||
691 | ||||
692 | void SbRtl_FreeLibrary(StarBASIC *, SbxArray & rPar, bool) | |||
693 | { | |||
694 | if ( rPar.Count32() != 2 ) | |||
695 | { | |||
696 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
697 | } | |||
698 | GetSbData()->pInst->GetDllMgr()->FreeDll( rPar.Get32(1)->GetOUString() ); | |||
699 | } | |||
700 | bool IsBaseIndexOne() | |||
701 | { | |||
702 | bool bResult = false; | |||
703 | if ( GetSbData()->pInst && GetSbData()->pInst->pRun ) | |||
704 | { | |||
705 | sal_uInt16 res = GetSbData()->pInst->pRun->GetBase(); | |||
706 | if ( res ) | |||
707 | { | |||
708 | bResult = true; | |||
709 | } | |||
710 | } | |||
711 | return bResult; | |||
712 | } | |||
713 | ||||
714 | void SbRtl_Array(StarBASIC *, SbxArray & rPar, bool) | |||
715 | { | |||
716 | SbxDimArray* pArray = new SbxDimArray( SbxVARIANT ); | |||
717 | sal_uInt32 nArraySize = rPar.Count32() - 1; | |||
718 | bool bIncIndex = IsBaseIndexOne(); | |||
719 | if( nArraySize ) | |||
720 | { | |||
721 | if ( bIncIndex ) | |||
722 | { | |||
723 | pArray->AddDim32( 1, sal::static_int_cast<sal_Int32>(nArraySize) ); | |||
724 | } | |||
725 | else | |||
726 | { | |||
727 | pArray->AddDim32( 0, sal::static_int_cast<sal_Int32>(nArraySize) - 1 ); | |||
728 | } | |||
729 | } | |||
730 | else | |||
731 | { | |||
732 | pArray->unoAddDim32( 0, -1 ); | |||
733 | } | |||
734 | ||||
735 | // insert parameters into the array | |||
736 | for( sal_uInt32 i = 0 ; i < nArraySize ; i++ ) | |||
737 | { | |||
738 | SbxVariable* pVar = rPar.Get32(i+1); | |||
739 | SbxVariable* pNew = new SbxEnsureParentVariable(*pVar); | |||
740 | pNew->SetFlag( SbxFlagBits::Write ); | |||
741 | sal_Int32 aIdx[1]; | |||
742 | aIdx[0] = static_cast<sal_Int32>(i); | |||
743 | if ( bIncIndex ) | |||
744 | { | |||
745 | ++aIdx[0]; | |||
746 | } | |||
747 | pArray->Put32(pNew, aIdx); | |||
748 | } | |||
749 | ||||
750 | // return array | |||
751 | SbxVariableRef refVar = rPar.Get32(0); | |||
752 | SbxFlagBits nFlags = refVar->GetFlags(); | |||
753 | refVar->ResetFlag( SbxFlagBits::Fixed ); | |||
754 | refVar->PutObject( pArray ); | |||
755 | refVar->SetFlags( nFlags ); | |||
756 | refVar->SetParameters( nullptr ); | |||
757 | } | |||
758 | ||||
759 | ||||
760 | // Featurewish #57868 | |||
761 | // The function returns a variant-array; if there are no parameters passed, | |||
762 | // an empty array is created (according to dim a(); equal to a sequence of | |||
763 | // the length 0 in Uno). | |||
764 | // If there are parameters passed, there's a dimension created for each of | |||
765 | // them; DimArray( 2, 2, 4 ) is equal to DIM a( 2, 2, 4 ) | |||
766 | // the array is always of the type variant | |||
767 | void SbRtl_DimArray(StarBASIC *, SbxArray & rPar, bool) | |||
768 | { | |||
769 | SbxDimArray * pArray = new SbxDimArray( SbxVARIANT ); | |||
770 | sal_uInt32 nArrayDims = rPar.Count32() - 1; | |||
771 | if( nArrayDims > 0 ) | |||
772 | { | |||
773 | for( sal_uInt32 i = 0; i < nArrayDims ; i++ ) | |||
774 | { | |||
775 | sal_Int32 ub = rPar.Get32(i+1)->GetLong(); | |||
776 | if( ub < 0 ) | |||
777 | { | |||
778 | StarBASIC::Error( ERRCODE_BASIC_OUT_OF_RANGEErrCode( ErrCodeArea::Sbx, ErrCodeClass::Sbx, 4) ); | |||
779 | ub = 0; | |||
780 | } | |||
781 | pArray->AddDim32( 0, ub ); | |||
782 | } | |||
783 | } | |||
784 | else | |||
785 | { | |||
786 | pArray->unoAddDim32( 0, -1 ); | |||
787 | } | |||
788 | SbxVariableRef refVar = rPar.Get32(0); | |||
789 | SbxFlagBits nFlags = refVar->GetFlags(); | |||
790 | refVar->ResetFlag( SbxFlagBits::Fixed ); | |||
791 | refVar->PutObject( pArray ); | |||
792 | refVar->SetFlags( nFlags ); | |||
793 | refVar->SetParameters( nullptr ); | |||
794 | } | |||
795 | ||||
796 | /* | |||
797 | * FindObject and FindPropertyObject make it possible to | |||
798 | * address objects and properties of the type Object with | |||
799 | * their name as string-parameters at the runtime. | |||
800 | * | |||
801 | * Example: | |||
802 | * MyObj.Prop1.Bla = 5 | |||
803 | * | |||
804 | * is equal to: | |||
805 | * dim ObjVar as Object | |||
806 | * dim ObjProp as Object | |||
807 | * ObjName$ = "MyObj" | |||
808 | * ObjVar = FindObject( ObjName$ ) | |||
809 | * PropName$ = "Prop1" | |||
810 | * ObjProp = FindPropertyObject( ObjVar, PropName$ ) | |||
811 | * ObjProp.Bla = 5 | |||
812 | * | |||
813 | * The names can be created dynamically at the runtime | |||
814 | * so that e. g. via controls "TextEdit1" to "TextEdit5" | |||
815 | * can be iterated in a dialog in a loop. | |||
816 | */ | |||
817 | ||||
818 | ||||
819 | // 1st parameter = the object's name as string | |||
820 | void SbRtl_FindObject(StarBASIC *, SbxArray & rPar, bool) | |||
821 | { | |||
822 | if ( rPar.Count32() < 2 ) | |||
823 | { | |||
824 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
825 | return; | |||
826 | } | |||
827 | ||||
828 | OUString aNameStr = rPar.Get32(1)->GetOUString(); | |||
829 | ||||
830 | SbxBase* pFind = StarBASIC::FindSBXInCurrentScope( aNameStr ); | |||
831 | SbxObject* pFindObj = nullptr; | |||
832 | if( pFind ) | |||
833 | { | |||
834 | pFindObj = dynamic_cast<SbxObject*>( pFind ); | |||
835 | } | |||
836 | SbxVariableRef refVar = rPar.Get32(0); | |||
837 | refVar->PutObject( pFindObj ); | |||
838 | } | |||
839 | ||||
840 | // address object-property in an object | |||
841 | // 1st parameter = object | |||
842 | // 2nd parameter = the property's name as string | |||
843 | void SbRtl_FindPropertyObject(StarBASIC *, SbxArray & rPar, bool) | |||
844 | { | |||
845 | if ( rPar.Count32() < 3 ) | |||
846 | { | |||
847 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
848 | return; | |||
849 | } | |||
850 | ||||
851 | SbxBase* pObjVar = rPar.Get32(1)->GetObject(); | |||
852 | SbxObject* pObj = nullptr; | |||
853 | if( pObjVar ) | |||
854 | { | |||
855 | pObj = dynamic_cast<SbxObject*>( pObjVar ); | |||
856 | } | |||
857 | if( !pObj && dynamic_cast<const SbxVariable*>( pObjVar) ) | |||
858 | { | |||
859 | SbxBase* pObjVarObj = static_cast<SbxVariable*>(pObjVar)->GetObject(); | |||
860 | pObj = dynamic_cast<SbxObject*>( pObjVarObj ); | |||
861 | } | |||
862 | ||||
863 | OUString aNameStr = rPar.Get32(2)->GetOUString(); | |||
864 | ||||
865 | SbxObject* pFindObj = nullptr; | |||
866 | if( pObj ) | |||
867 | { | |||
868 | SbxVariable* pFindVar = pObj->Find( aNameStr, SbxClassType::Object ); | |||
869 | pFindObj = dynamic_cast<SbxObject*>( pFindVar ); | |||
870 | } | |||
871 | else | |||
872 | { | |||
873 | StarBASIC::Error( ERRCODE_BASIC_BAD_PARAMETERErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 7) ); | |||
874 | } | |||
875 | ||||
876 | SbxVariableRef refVar = rPar.Get32(0); | |||
877 | refVar->PutObject( pFindObj ); | |||
878 | } | |||
879 | ||||
880 | ||||
881 | static bool lcl_WriteSbxVariable( const SbxVariable& rVar, SvStream* pStrm, | |||
882 | bool bBinary, short nBlockLen, bool bIsArray ) | |||
883 | { | |||
884 | sal_uInt64 const nFPos = pStrm->Tell(); | |||
885 | ||||
886 | bool bIsVariant = !rVar.IsFixed(); | |||
887 | SbxDataType eType = rVar.GetType(); | |||
888 | ||||
889 | switch( eType ) | |||
890 | { | |||
891 | case SbxBOOL: | |||
892 | case SbxCHAR: | |||
893 | case SbxBYTE: | |||
894 | if( bIsVariant ) | |||
895 | { | |||
896 | pStrm->WriteUInt16( SbxBYTE ); // VarType Id | |||
897 | } | |||
898 | pStrm->WriteUChar( rVar.GetByte() ); | |||
899 | break; | |||
900 | ||||
901 | case SbxEMPTY: | |||
902 | case SbxNULL: | |||
903 | case SbxVOID: | |||
904 | case SbxINTEGER: | |||
905 | case SbxUSHORT: | |||
906 | case SbxINT: | |||
907 | case SbxUINT: | |||
908 | if( bIsVariant ) | |||
909 | { | |||
910 | pStrm->WriteUInt16( SbxINTEGER ); // VarType Id | |||
911 | } | |||
912 | pStrm->WriteInt16( rVar.GetInteger() ); | |||
913 | break; | |||
914 | ||||
915 | case SbxLONG: | |||
916 | case SbxULONG: | |||
917 | if( bIsVariant ) | |||
918 | { | |||
919 | pStrm->WriteUInt16( SbxLONG ); // VarType Id | |||
920 | } | |||
921 | pStrm->WriteInt32( rVar.GetLong() ); | |||
922 | break; | |||
923 | case SbxSALINT64: | |||
924 | case SbxSALUINT64: | |||
925 | if( bIsVariant ) | |||
926 | { | |||
927 | pStrm->WriteUInt16( SbxSALINT64 ); // VarType Id | |||
928 | } | |||
929 | pStrm->WriteUInt64( rVar.GetInt64() ); | |||
930 | break; | |||
931 | case SbxSINGLE: | |||
932 | if( bIsVariant ) | |||
933 | { | |||
934 | pStrm->WriteUInt16( eType ); // VarType Id | |||
935 | } | |||
936 | pStrm->WriteFloat( rVar.GetSingle() ); | |||
937 | break; | |||
938 | ||||
939 | case SbxDOUBLE: | |||
940 | case SbxCURRENCY: | |||
941 | case SbxDATE: | |||
942 | if( bIsVariant ) | |||
943 | { | |||
944 | pStrm->WriteUInt16( eType ); // VarType Id | |||
945 | } | |||
946 | pStrm->WriteDouble( rVar.GetDouble() ); | |||
947 | break; | |||
948 | ||||
949 | case SbxSTRING: | |||
950 | case SbxLPSTR: | |||
951 | { | |||
952 | const OUString& rStr = rVar.GetOUString(); | |||
953 | if( !bBinary || bIsArray ) | |||
954 | { | |||
955 | if( bIsVariant ) | |||
956 | { | |||
957 | pStrm->WriteUInt16( SbxSTRING ); | |||
958 | } | |||
959 | pStrm->WriteUniOrByteString( rStr, osl_getThreadTextEncoding() ); | |||
960 | } | |||
961 | else | |||
962 | { | |||
963 | // without any length information! without end-identifier! | |||
964 | // What does that mean for Unicode?! Choosing conversion to ByteString... | |||
965 | OString aByteStr(OUStringToOString(rStr, osl_getThreadTextEncoding())); | |||
966 | pStrm->WriteOString( aByteStr ); | |||
967 | } | |||
968 | } | |||
969 | break; | |||
970 | ||||
971 | default: | |||
972 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
973 | return false; | |||
974 | } | |||
975 | ||||
976 | if( nBlockLen ) | |||
977 | { | |||
978 | pStrm->Seek( nFPos + nBlockLen ); | |||
979 | } | |||
980 | return pStrm->GetErrorCode() == ERRCODE_NONEErrCode(0); | |||
981 | } | |||
982 | ||||
983 | static bool lcl_ReadSbxVariable( SbxVariable& rVar, SvStream* pStrm, | |||
984 | bool bBinary, short nBlockLen ) | |||
985 | { | |||
986 | double aDouble; | |||
987 | ||||
988 | sal_uInt64 const nFPos = pStrm->Tell(); | |||
989 | ||||
990 | bool bIsVariant = !rVar.IsFixed(); | |||
991 | SbxDataType eVarType = rVar.GetType(); | |||
992 | ||||
993 | SbxDataType eSrcType = eVarType; | |||
994 | if( bIsVariant ) | |||
995 | { | |||
996 | sal_uInt16 nTemp; | |||
997 | pStrm->ReadUInt16( nTemp ); | |||
998 | eSrcType = static_cast<SbxDataType>(nTemp); | |||
999 | } | |||
1000 | ||||
1001 | switch( eSrcType ) | |||
1002 | { | |||
1003 | case SbxBOOL: | |||
1004 | case SbxCHAR: | |||
1005 | case SbxBYTE: | |||
1006 | { | |||
1007 | sal_uInt8 aByte; | |||
1008 | pStrm->ReadUChar( aByte ); | |||
1009 | ||||
1010 | if( bBinary && SbiRuntime::isVBAEnabled() && aByte == 1 && pStrm->eof() ) | |||
1011 | { | |||
1012 | aByte = 0; | |||
1013 | } | |||
1014 | rVar.PutByte( aByte ); | |||
1015 | } | |||
1016 | break; | |||
1017 | ||||
1018 | case SbxEMPTY: | |||
1019 | case SbxNULL: | |||
1020 | case SbxVOID: | |||
1021 | case SbxINTEGER: | |||
1022 | case SbxUSHORT: | |||
1023 | case SbxINT: | |||
1024 | case SbxUINT: | |||
1025 | { | |||
1026 | sal_Int16 aInt; | |||
1027 | pStrm->ReadInt16( aInt ); | |||
1028 | rVar.PutInteger( aInt ); | |||
1029 | } | |||
1030 | break; | |||
1031 | ||||
1032 | case SbxLONG: | |||
1033 | case SbxULONG: | |||
1034 | { | |||
1035 | sal_Int32 aInt; | |||
1036 | pStrm->ReadInt32( aInt ); | |||
1037 | rVar.PutLong( aInt ); | |||
1038 | } | |||
1039 | break; | |||
1040 | case SbxSALINT64: | |||
1041 | case SbxSALUINT64: | |||
1042 | { | |||
1043 | sal_uInt32 aInt; | |||
1044 | pStrm->ReadUInt32( aInt ); | |||
1045 | rVar.PutInt64( static_cast<sal_Int64>(aInt) ); | |||
1046 | } | |||
1047 | break; | |||
1048 | case SbxSINGLE: | |||
1049 | { | |||
1050 | float nS; | |||
1051 | pStrm->ReadFloat( nS ); | |||
1052 | rVar.PutSingle( nS ); | |||
1053 | } | |||
1054 | break; | |||
1055 | ||||
1056 | case SbxDOUBLE: | |||
1057 | case SbxCURRENCY: | |||
1058 | { | |||
1059 | pStrm->ReadDouble( aDouble ); | |||
1060 | rVar.PutDouble( aDouble ); | |||
1061 | } | |||
1062 | break; | |||
1063 | ||||
1064 | case SbxDATE: | |||
1065 | { | |||
1066 | pStrm->ReadDouble( aDouble ); | |||
1067 | rVar.PutDate( aDouble ); | |||
1068 | } | |||
1069 | break; | |||
1070 | ||||
1071 | case SbxSTRING: | |||
1072 | case SbxLPSTR: | |||
1073 | { | |||
1074 | OUString aStr = pStrm->ReadUniOrByteString(osl_getThreadTextEncoding()); | |||
1075 | rVar.PutString( aStr ); | |||
1076 | } | |||
1077 | break; | |||
1078 | ||||
1079 | default: | |||
1080 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1081 | return false; | |||
1082 | } | |||
1083 | ||||
1084 | if( nBlockLen ) | |||
1085 | { | |||
1086 | pStrm->Seek( nFPos + nBlockLen ); | |||
1087 | } | |||
1088 | return pStrm->GetErrorCode() == ERRCODE_NONEErrCode(0); | |||
1089 | } | |||
1090 | ||||
1091 | ||||
1092 | // nCurDim = 1...n | |||
1093 | static bool lcl_WriteReadSbxArray( SbxDimArray& rArr, SvStream* pStrm, | |||
1094 | bool bBinary, sal_Int32 nCurDim, sal_Int32* pOtherDims, bool bWrite ) | |||
1095 | { | |||
1096 | SAL_WARN_IF( nCurDim <= 0,"basic", "Bad Dim")do { if (true && (nCurDim <= 0)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "basic")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "Bad Dim") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic" ), ("/home/maarten/src/libreoffice/core/basic/source/runtime/methods1.cxx" ":" "1096" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Bad Dim"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Bad Dim"; ::sal ::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/runtime/methods1.cxx" ":" "1096" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Bad Dim") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/runtime/methods1.cxx" ":" "1096" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Bad Dim"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Bad Dim"; ::sal ::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/runtime/methods1.cxx" ":" "1096" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1097 | sal_Int32 nLower, nUpper; | |||
1098 | if( !rArr.GetDim32( nCurDim, nLower, nUpper ) ) | |||
1099 | return false; | |||
1100 | for(sal_Int32 nCur = nLower; nCur <= nUpper; nCur++ ) | |||
1101 | { | |||
1102 | pOtherDims[ nCurDim-1 ] = nCur; | |||
1103 | if( nCurDim != 1 ) | |||
1104 | lcl_WriteReadSbxArray(rArr, pStrm, bBinary, nCurDim-1, pOtherDims, bWrite); | |||
1105 | else | |||
1106 | { | |||
1107 | SbxVariable* pVar = rArr.Get32( pOtherDims ); | |||
1108 | bool bRet; | |||
1109 | if( bWrite ) | |||
1110 | bRet = lcl_WriteSbxVariable(*pVar, pStrm, bBinary, 0, true ); | |||
1111 | else | |||
1112 | bRet = lcl_ReadSbxVariable(*pVar, pStrm, bBinary, 0 ); | |||
1113 | if( !bRet ) | |||
1114 | return false; | |||
1115 | } | |||
1116 | } | |||
1117 | return true; | |||
1118 | } | |||
1119 | ||||
1120 | static void PutGet( SbxArray& rPar, bool bPut ) | |||
1121 | { | |||
1122 | if ( rPar.Count32() != 4 ) | |||
1123 | { | |||
1124 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1125 | return; | |||
1126 | } | |||
1127 | sal_Int16 nFileNo = rPar.Get32(1)->GetInteger(); | |||
1128 | SbxVariable* pVar2 = rPar.Get32(2); | |||
1129 | SbxDataType eType2 = pVar2->GetType(); | |||
1130 | bool bHasRecordNo = (eType2 != SbxEMPTY && eType2 != SbxERROR); | |||
1131 | long nRecordNo = pVar2->GetLong(); | |||
1132 | if ( nFileNo < 1 || ( bHasRecordNo && nRecordNo < 1 ) ) | |||
1133 | { | |||
1134 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1135 | return; | |||
1136 | } | |||
1137 | nRecordNo--; | |||
1138 | SbiIoSystem* pIO = GetSbData()->pInst->GetIoSystem(); | |||
1139 | SbiStream* pSbStrm = pIO->GetStream( nFileNo ); | |||
1140 | ||||
1141 | if ( !pSbStrm || !(pSbStrm->GetMode() & (SbiStreamFlags::Binary | SbiStreamFlags::Random)) ) | |||
1142 | { | |||
1143 | StarBASIC::Error( ERRCODE_BASIC_BAD_CHANNELErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 41 ) ); | |||
1144 | return; | |||
1145 | } | |||
1146 | ||||
1147 | SvStream* pStrm = pSbStrm->GetStrm(); | |||
1148 | bool bRandom = pSbStrm->IsRandom(); | |||
1149 | short nBlockLen = bRandom ? pSbStrm->GetBlockLen() : 0; | |||
1150 | ||||
1151 | if( bPut ) | |||
1152 | { | |||
1153 | pSbStrm->ExpandFile(); | |||
1154 | } | |||
1155 | ||||
1156 | if( bHasRecordNo ) | |||
1157 | { | |||
1158 | sal_uInt64 const nFilePos = bRandom | |||
1159 | ? static_cast<sal_uInt64>(nBlockLen * nRecordNo) | |||
1160 | : static_cast<sal_uInt64>(nRecordNo); | |||
1161 | pStrm->Seek( nFilePos ); | |||
1162 | } | |||
1163 | ||||
1164 | SbxDimArray* pArr = nullptr; | |||
1165 | SbxVariable* pVar = rPar.Get32(3); | |||
1166 | if( pVar->GetType() & SbxARRAY ) | |||
1167 | { | |||
1168 | SbxBase* pParObj = pVar->GetObject(); | |||
1169 | pArr = dynamic_cast<SbxDimArray*>( pParObj ); | |||
1170 | } | |||
1171 | ||||
1172 | bool bRet; | |||
1173 | ||||
1174 | if( pArr ) | |||
1175 | { | |||
1176 | sal_uInt64 const nFPos = pStrm->Tell(); | |||
1177 | sal_Int32 nDims = pArr->GetDims32(); | |||
1178 | std::unique_ptr<sal_Int32[]> pDims(new sal_Int32[ nDims ]); | |||
1179 | bRet = lcl_WriteReadSbxArray(*pArr,pStrm,!bRandom,nDims,pDims.get(),bPut); | |||
1180 | pDims.reset(); | |||
1181 | if( nBlockLen ) | |||
1182 | pStrm->Seek( nFPos + nBlockLen ); | |||
1183 | } | |||
1184 | else | |||
1185 | { | |||
1186 | if( bPut ) | |||
1187 | bRet = lcl_WriteSbxVariable(*pVar, pStrm, !bRandom, nBlockLen, false); | |||
1188 | else | |||
1189 | bRet = lcl_ReadSbxVariable(*pVar, pStrm, !bRandom, nBlockLen); | |||
1190 | } | |||
1191 | if( !bRet || pStrm->GetErrorCode() ) | |||
1192 | StarBASIC::Error( ERRCODE_BASIC_IO_ERRORErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 45 ) ); | |||
1193 | } | |||
1194 | ||||
1195 | void SbRtl_Put(StarBASIC *, SbxArray & rPar, bool) | |||
1196 | { | |||
1197 | PutGet( rPar, true ); | |||
1198 | } | |||
1199 | ||||
1200 | void SbRtl_Get(StarBASIC *, SbxArray & rPar, bool) | |||
1201 | { | |||
1202 | PutGet( rPar, false ); | |||
1203 | } | |||
1204 | ||||
1205 | void SbRtl_Environ(StarBASIC *, SbxArray & rPar, bool) | |||
1206 | { | |||
1207 | if ( rPar.Count32() != 2 ) | |||
1208 | { | |||
1209 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1210 | return; | |||
1211 | } | |||
1212 | OUString aResult; | |||
1213 | // should be ANSI but that's not possible under Win16 in the DLL | |||
1214 | OString aByteStr(OUStringToOString(rPar.Get32(1)->GetOUString(), | |||
1215 | osl_getThreadTextEncoding())); | |||
1216 | const char* pEnvStr = getenv(aByteStr.getStr()); | |||
1217 | if ( pEnvStr ) | |||
1218 | { | |||
1219 | aResult = OUString(pEnvStr, strlen(pEnvStr), osl_getThreadTextEncoding()); | |||
1220 | } | |||
1221 | rPar.Get32(0)->PutString( aResult ); | |||
1222 | } | |||
1223 | ||||
1224 | static double GetDialogZoomFactor( bool bX, long nValue ) | |||
1225 | { | |||
1226 | OutputDevice* pDevice = Application::GetDefaultDevice(); | |||
1227 | double nResult = 0; | |||
1228 | if( pDevice ) | |||
1229 | { | |||
1230 | Size aRefSize( nValue, nValue ); | |||
1231 | Fraction aFracX( 1, 26 ); | |||
1232 | Fraction aFracY( 1, 24 ); | |||
1233 | MapMode aMap( MapUnit::MapAppFont, Point(), aFracX, aFracY ); | |||
1234 | Size aScaledSize = pDevice->LogicToPixel( aRefSize, aMap ); | |||
1235 | aRefSize = pDevice->LogicToPixel( aRefSize, MapMode(MapUnit::MapTwip) ); | |||
1236 | ||||
1237 | double nRef, nScaled; | |||
1238 | if( bX ) | |||
1239 | { | |||
1240 | nRef = aRefSize.Width(); | |||
1241 | nScaled = aScaledSize.Width(); | |||
1242 | } | |||
1243 | else | |||
1244 | { | |||
1245 | nRef = aRefSize.Height(); | |||
1246 | nScaled = aScaledSize.Height(); | |||
1247 | } | |||
1248 | nResult = nScaled / nRef; | |||
1249 | } | |||
1250 | return nResult; | |||
1251 | } | |||
1252 | ||||
1253 | ||||
1254 | void SbRtl_GetDialogZoomFactorX(StarBASIC *, SbxArray & rPar, bool) | |||
1255 | { | |||
1256 | if ( rPar.Count32() != 2 ) | |||
1257 | { | |||
1258 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1259 | return; | |||
1260 | } | |||
1261 | rPar.Get32(0)->PutDouble( GetDialogZoomFactor( true, rPar.Get32(1)->GetLong() )); | |||
1262 | } | |||
1263 | ||||
1264 | void SbRtl_GetDialogZoomFactorY(StarBASIC *, SbxArray & rPar, bool) | |||
1265 | { | |||
1266 | if ( rPar.Count32() != 2 ) | |||
1267 | { | |||
1268 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1269 | return; | |||
1270 | } | |||
1271 | rPar.Get32(0)->PutDouble( GetDialogZoomFactor( false, rPar.Get32(1)->GetLong())); | |||
1272 | } | |||
1273 | ||||
1274 | ||||
1275 | void SbRtl_EnableReschedule(StarBASIC *, SbxArray & rPar, bool) | |||
1276 | { | |||
1277 | rPar.Get32(0)->PutEmpty(); | |||
1278 | if ( rPar.Count32() != 2 ) | |||
1279 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1280 | if( GetSbData()->pInst ) | |||
1281 | GetSbData()->pInst->EnableReschedule( rPar.Get32(1)->GetBool() ); | |||
1282 | } | |||
1283 | ||||
1284 | void SbRtl_GetSystemTicks(StarBASIC *, SbxArray & rPar, bool) | |||
1285 | { | |||
1286 | if ( rPar.Count32() != 1 ) | |||
1287 | { | |||
1288 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1289 | return; | |||
1290 | } | |||
1291 | rPar.Get32(0)->PutLong( tools::Time::GetSystemTicks() ); | |||
1292 | } | |||
1293 | ||||
1294 | void SbRtl_GetPathSeparator(StarBASIC *, SbxArray & rPar, bool) | |||
1295 | { | |||
1296 | if ( rPar.Count32() != 1 ) | |||
1297 | { | |||
1298 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1299 | return; | |||
1300 | } | |||
1301 | rPar.Get32(0)->PutString( OUString( SAL_PATHDELIMITER'/' ) ); | |||
1302 | } | |||
1303 | ||||
1304 | void SbRtl_ResolvePath(StarBASIC *, SbxArray & rPar, bool) | |||
1305 | { | |||
1306 | if ( rPar.Count32() == 2 ) | |||
1307 | { | |||
1308 | OUString aStr = rPar.Get32(1)->GetOUString(); | |||
1309 | rPar.Get32(0)->PutString( aStr ); | |||
1310 | } | |||
1311 | else | |||
1312 | { | |||
1313 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1314 | } | |||
1315 | } | |||
1316 | ||||
1317 | void SbRtl_TypeLen(StarBASIC *, SbxArray & rPar, bool) | |||
1318 | { | |||
1319 | if ( rPar.Count32() != 2 ) | |||
1320 | { | |||
1321 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1322 | } | |||
1323 | else | |||
1324 | { | |||
1325 | SbxDataType eType = rPar.Get32(1)->GetType(); | |||
1326 | sal_Int16 nLen = 0; | |||
1327 | switch( eType ) | |||
1328 | { | |||
1329 | case SbxEMPTY: | |||
1330 | case SbxNULL: | |||
1331 | case SbxVECTOR: | |||
1332 | case SbxARRAY: | |||
1333 | case SbxBYREF: | |||
1334 | case SbxVOID: | |||
1335 | case SbxHRESULT: | |||
1336 | case SbxPOINTER: | |||
1337 | case SbxDIMARRAY: | |||
1338 | case SbxCARRAY: | |||
1339 | case SbxUSERDEF: | |||
1340 | nLen = 0; | |||
1341 | break; | |||
1342 | ||||
1343 | case SbxINTEGER: | |||
1344 | case SbxERROR: | |||
1345 | case SbxUSHORT: | |||
1346 | case SbxINT: | |||
1347 | case SbxUINT: | |||
1348 | nLen = 2; | |||
1349 | break; | |||
1350 | ||||
1351 | case SbxLONG: | |||
1352 | case SbxSINGLE: | |||
1353 | case SbxULONG: | |||
1354 | nLen = 4; | |||
1355 | break; | |||
1356 | ||||
1357 | case SbxDOUBLE: | |||
1358 | case SbxCURRENCY: | |||
1359 | case SbxDATE: | |||
1360 | case SbxSALINT64: | |||
1361 | case SbxSALUINT64: | |||
1362 | nLen = 8; | |||
1363 | break; | |||
1364 | ||||
1365 | case SbxOBJECT: | |||
1366 | case SbxVARIANT: | |||
1367 | case SbxDATAOBJECT: | |||
1368 | nLen = 0; | |||
1369 | break; | |||
1370 | ||||
1371 | case SbxCHAR: | |||
1372 | case SbxBYTE: | |||
1373 | case SbxBOOL: | |||
1374 | nLen = 1; | |||
1375 | break; | |||
1376 | ||||
1377 | case SbxLPSTR: | |||
1378 | case SbxLPWSTR: | |||
1379 | case SbxCoreSTRING: | |||
1380 | case SbxSTRING: | |||
1381 | nLen = static_cast<sal_Int16>(rPar.Get32(1)->GetOUString().getLength()); | |||
1382 | break; | |||
1383 | ||||
1384 | default: | |||
1385 | nLen = 0; | |||
1386 | break; | |||
1387 | } | |||
1388 | rPar.Get32(0)->PutInteger( nLen ); | |||
1389 | } | |||
1390 | } | |||
1391 | ||||
1392 | ||||
1393 | // 1st parameter == class name, other parameters for initialisation | |||
1394 | void SbRtl_CreateUnoStruct(StarBASIC *, SbxArray & rPar, bool) | |||
1395 | { | |||
1396 | RTL_Impl_CreateUnoStruct( rPar ); | |||
1397 | } | |||
1398 | ||||
1399 | ||||
1400 | // 1st parameter == service-name | |||
1401 | void SbRtl_CreateUnoService(StarBASIC *, SbxArray & rPar, bool) | |||
1402 | { | |||
1403 | RTL_Impl_CreateUnoService( rPar ); | |||
1404 | } | |||
1405 | ||||
1406 | void SbRtl_CreateUnoServiceWithArguments(StarBASIC *, SbxArray & rPar, bool) | |||
1407 | { | |||
1408 | RTL_Impl_CreateUnoServiceWithArguments( rPar ); | |||
1409 | } | |||
1410 | ||||
1411 | ||||
1412 | void SbRtl_CreateUnoValue(StarBASIC *, SbxArray & rPar, bool) | |||
1413 | { | |||
1414 | RTL_Impl_CreateUnoValue( rPar ); | |||
1415 | } | |||
1416 | ||||
1417 | ||||
1418 | // no parameters | |||
1419 | void SbRtl_GetProcessServiceManager(StarBASIC *, SbxArray & rPar, bool) | |||
1420 | { | |||
1421 | RTL_Impl_GetProcessServiceManager( rPar ); | |||
1422 | } | |||
1423 | ||||
1424 | ||||
1425 | // 1st parameter == Sequence<PropertyValue> | |||
1426 | void SbRtl_CreatePropertySet(StarBASIC *, SbxArray & rPar, bool) | |||
1427 | { | |||
1428 | RTL_Impl_CreatePropertySet( rPar ); | |||
1429 | } | |||
1430 | ||||
1431 | ||||
1432 | // multiple interface-names as parameters | |||
1433 | void SbRtl_HasUnoInterfaces(StarBASIC *, SbxArray & rPar, bool) | |||
1434 | { | |||
1435 | RTL_Impl_HasInterfaces( rPar ); | |||
1436 | } | |||
1437 | ||||
1438 | ||||
1439 | void SbRtl_IsUnoStruct(StarBASIC *, SbxArray & rPar, bool) | |||
1440 | { | |||
1441 | RTL_Impl_IsUnoStruct( rPar ); | |||
1442 | } | |||
1443 | ||||
1444 | ||||
1445 | void SbRtl_EqualUnoObjects(StarBASIC *, SbxArray & rPar, bool) | |||
1446 | { | |||
1447 | RTL_Impl_EqualUnoObjects( rPar ); | |||
1448 | } | |||
1449 | ||||
1450 | void SbRtl_CreateUnoDialog(StarBASIC *, SbxArray & rPar, bool) | |||
1451 | { | |||
1452 | RTL_Impl_CreateUnoDialog( rPar ); | |||
1453 | } | |||
1454 | ||||
1455 | // Return the application standard lib as root scope | |||
1456 | void SbRtl_GlobalScope(StarBASIC * pBasic, SbxArray & rPar, bool) | |||
1457 | { | |||
1458 | SbxObject* p = pBasic; | |||
1459 | while( p->GetParent() ) | |||
1460 | { | |||
1461 | p = p->GetParent(); | |||
1462 | } | |||
1463 | SbxVariableRef refVar = rPar.Get32(0); | |||
1464 | refVar->PutObject( p ); | |||
1465 | } | |||
1466 | ||||
1467 | // Helper functions to convert Url from/to system paths | |||
1468 | void SbRtl_ConvertToUrl(StarBASIC *, SbxArray & rPar, bool) | |||
1469 | { | |||
1470 | if ( rPar.Count32() == 2 ) | |||
1471 | { | |||
1472 | OUString aStr = rPar.Get32(1)->GetOUString(); | |||
1473 | INetURLObject aURLObj( aStr, INetProtocol::File ); | |||
1474 | OUString aFileURL = aURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ); | |||
1475 | if( aFileURL.isEmpty() ) | |||
1476 | { | |||
1477 | osl::File::getFileURLFromSystemPath(aStr, aFileURL); | |||
1478 | } | |||
1479 | if( aFileURL.isEmpty() ) | |||
1480 | { | |||
1481 | aFileURL = aStr; | |||
1482 | } | |||
1483 | rPar.Get32(0)->PutString(aFileURL); | |||
1484 | } | |||
1485 | else | |||
1486 | { | |||
1487 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1488 | } | |||
1489 | } | |||
1490 | ||||
1491 | void SbRtl_ConvertFromUrl(StarBASIC *, SbxArray & rPar, bool) | |||
1492 | { | |||
1493 | if ( rPar.Count32() == 2 ) | |||
1494 | { | |||
1495 | OUString aStr = rPar.Get32(1)->GetOUString(); | |||
1496 | OUString aSysPath; | |||
1497 | ::osl::File::getSystemPathFromFileURL( aStr, aSysPath ); | |||
1498 | if( aSysPath.isEmpty() ) | |||
1499 | { | |||
1500 | aSysPath = aStr; | |||
1501 | } | |||
1502 | rPar.Get32(0)->PutString(aSysPath); | |||
1503 | } | |||
1504 | else | |||
1505 | { | |||
1506 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1507 | } | |||
1508 | } | |||
1509 | ||||
1510 | ||||
1511 | // Provide DefaultContext | |||
1512 | void SbRtl_GetDefaultContext(StarBASIC *, SbxArray & rPar, bool) | |||
1513 | { | |||
1514 | RTL_Impl_GetDefaultContext( rPar ); | |||
1515 | } | |||
1516 | ||||
1517 | void SbRtl_Join(StarBASIC *, SbxArray & rPar, bool) | |||
1518 | { | |||
1519 | sal_uInt32 nParCount = rPar.Count32(); | |||
1520 | if ( nParCount != 3 && nParCount != 2 ) | |||
1521 | { | |||
1522 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1523 | return; | |||
1524 | } | |||
1525 | SbxBase* pParObj = rPar.Get32(1)->GetObject(); | |||
1526 | SbxDimArray* pArr = dynamic_cast<SbxDimArray*>( pParObj ); | |||
1527 | if( pArr ) | |||
1528 | { | |||
1529 | if( pArr->GetDims32() != 1 ) | |||
1530 | { | |||
1531 | StarBASIC::Error( ERRCODE_BASIC_WRONG_DIMSErrCode( ErrCodeArea::Sbx, ErrCodeClass::Compiler, 116 ) ); // Syntax Error?! | |||
1532 | return; | |||
1533 | } | |||
1534 | OUString aDelim; | |||
1535 | if( nParCount == 3 ) | |||
1536 | { | |||
1537 | aDelim = rPar.Get32(2)->GetOUString(); | |||
1538 | } | |||
1539 | else | |||
1540 | { | |||
1541 | aDelim = " "; | |||
1542 | } | |||
1543 | OUStringBuffer aRetStr(32); | |||
1544 | sal_Int32 nLower, nUpper; | |||
1545 | pArr->GetDim32( 1, nLower, nUpper ); | |||
1546 | sal_Int32 aIdx[1]; | |||
1547 | for (aIdx[0] = nLower; aIdx[0] <= nUpper; ++aIdx[0]) | |||
1548 | { | |||
1549 | OUString aStr = pArr->Get32(aIdx)->GetOUString(); | |||
1550 | aRetStr.append(aStr); | |||
1551 | if (aIdx[0] != nUpper) | |||
1552 | { | |||
1553 | aRetStr.append(aDelim); | |||
1554 | } | |||
1555 | } | |||
1556 | rPar.Get32(0)->PutString( aRetStr.makeStringAndClear() ); | |||
1557 | } | |||
1558 | else | |||
1559 | { | |||
1560 | StarBASIC::Error( ERRCODE_BASIC_MUST_HAVE_DIMSErrCode( ErrCodeArea::Sbx, ErrCodeClass::Compiler, 112 ) ); | |||
1561 | } | |||
1562 | } | |||
1563 | ||||
1564 | ||||
1565 | void SbRtl_Split(StarBASIC *, SbxArray & rPar, bool) | |||
1566 | { | |||
1567 | sal_uInt32 nParCount = rPar.Count32(); | |||
1568 | if ( nParCount < 2 ) | |||
1569 | { | |||
1570 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1571 | return; | |||
1572 | } | |||
1573 | ||||
1574 | OUString aExpression = rPar.Get32(1)->GetOUString(); | |||
1575 | sal_Int32 nArraySize = 0; | |||
1576 | std::vector< OUString > vRet; | |||
1577 | if( !aExpression.isEmpty() ) | |||
1578 | { | |||
1579 | OUString aDelim; | |||
1580 | if( nParCount >= 3 ) | |||
1581 | { | |||
1582 | aDelim = rPar.Get32(2)->GetOUString(); | |||
1583 | } | |||
1584 | else | |||
1585 | { | |||
1586 | aDelim = " "; | |||
1587 | } | |||
1588 | ||||
1589 | sal_Int32 nCount = -1; | |||
1590 | if( nParCount == 4 ) | |||
1591 | { | |||
1592 | nCount = rPar.Get32(3)->GetLong(); | |||
1593 | } | |||
1594 | sal_Int32 nDelimLen = aDelim.getLength(); | |||
1595 | if( nDelimLen ) | |||
1596 | { | |||
1597 | sal_Int32 iSearch = -1; | |||
1598 | sal_Int32 iStart = 0; | |||
1599 | do | |||
1600 | { | |||
1601 | bool bBreak = false; | |||
1602 | if( nCount >= 0 && nArraySize == nCount - 1 ) | |||
1603 | { | |||
1604 | bBreak = true; | |||
1605 | } | |||
1606 | iSearch = aExpression.indexOf( aDelim, iStart ); | |||
1607 | OUString aSubStr; | |||
1608 | if( iSearch >= 0 && !bBreak ) | |||
1609 | { | |||
1610 | aSubStr = aExpression.copy( iStart, iSearch - iStart ); | |||
1611 | iStart = iSearch + nDelimLen; | |||
1612 | } | |||
1613 | else | |||
1614 | { | |||
1615 | aSubStr = aExpression.copy( iStart ); | |||
1616 | } | |||
1617 | vRet.push_back( aSubStr ); | |||
1618 | nArraySize++; | |||
1619 | ||||
1620 | if( bBreak ) | |||
1621 | { | |||
1622 | break; | |||
1623 | } | |||
1624 | } | |||
1625 | while( iSearch >= 0 ); | |||
1626 | } | |||
1627 | else | |||
1628 | { | |||
1629 | vRet.push_back( aExpression ); | |||
1630 | nArraySize = 1; | |||
1631 | } | |||
1632 | } | |||
1633 | ||||
1634 | SbxDimArray* pArray = new SbxDimArray( SbxVARIANT ); | |||
1635 | pArray->unoAddDim32( 0, nArraySize-1 ); | |||
1636 | ||||
1637 | // insert parameter(s) into the array | |||
1638 | for(sal_Int32 i = 0 ; i < nArraySize ; i++ ) | |||
1639 | { | |||
1640 | SbxVariableRef xVar = new SbxVariable( SbxVARIANT ); | |||
1641 | xVar->PutString( vRet[i] ); | |||
1642 | pArray->Put32( xVar.get(), &i ); | |||
1643 | } | |||
1644 | ||||
1645 | // return array | |||
1646 | SbxVariableRef refVar = rPar.Get32(0); | |||
1647 | SbxFlagBits nFlags = refVar->GetFlags(); | |||
1648 | refVar->ResetFlag( SbxFlagBits::Fixed ); | |||
1649 | refVar->PutObject( pArray ); | |||
1650 | refVar->SetFlags( nFlags ); | |||
1651 | refVar->SetParameters( nullptr ); | |||
1652 | } | |||
1653 | ||||
1654 | // MonthName(month[, abbreviate]) | |||
1655 | void SbRtl_MonthName(StarBASIC *, SbxArray & rPar, bool) | |||
1656 | { | |||
1657 | sal_uInt32 nParCount = rPar.Count32(); | |||
1658 | if( nParCount != 2 && nParCount != 3 ) | |||
1659 | { | |||
1660 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1661 | return; | |||
1662 | } | |||
1663 | ||||
1664 | const Reference< XCalendar4 >& xCalendar = getLocaleCalendar(); | |||
1665 | if( !xCalendar.is() ) | |||
1666 | { | |||
1667 | StarBASIC::Error( ERRCODE_BASIC_INTERNAL_ERRORErrCode( ErrCodeArea::Sbx, ErrCodeClass::Unknown, 9) ); | |||
1668 | return; | |||
1669 | } | |||
1670 | Sequence< CalendarItem2 > aMonthSeq = xCalendar->getMonths2(); | |||
1671 | sal_Int32 nMonthCount = aMonthSeq.getLength(); | |||
1672 | ||||
1673 | sal_Int16 nVal = rPar.Get32(1)->GetInteger(); | |||
1674 | if( nVal < 1 || nVal > nMonthCount ) | |||
1675 | { | |||
1676 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1677 | return; | |||
1678 | } | |||
1679 | ||||
1680 | bool bAbbreviate = false; | |||
1681 | if( nParCount == 3 ) | |||
1682 | bAbbreviate = rPar.Get32(2)->GetBool(); | |||
1683 | ||||
1684 | const CalendarItem2* pCalendarItems = aMonthSeq.getConstArray(); | |||
1685 | const CalendarItem2& rItem = pCalendarItems[nVal - 1]; | |||
1686 | ||||
1687 | OUString aRetStr = ( bAbbreviate ? rItem.AbbrevName : rItem.FullName ); | |||
1688 | rPar.Get32(0)->PutString(aRetStr); | |||
1689 | } | |||
1690 | ||||
1691 | // WeekdayName(weekday, abbreviate, firstdayofweek) | |||
1692 | void SbRtl_WeekdayName(StarBASIC *, SbxArray & rPar, bool) | |||
1693 | { | |||
1694 | sal_uInt32 nParCount = rPar.Count32(); | |||
1695 | if( nParCount < 2 || nParCount > 4 ) | |||
1696 | { | |||
1697 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1698 | return; | |||
1699 | } | |||
1700 | ||||
1701 | const Reference< XCalendar4 >& xCalendar = getLocaleCalendar(); | |||
1702 | if( !xCalendar.is() ) | |||
1703 | { | |||
1704 | StarBASIC::Error( ERRCODE_BASIC_INTERNAL_ERRORErrCode( ErrCodeArea::Sbx, ErrCodeClass::Unknown, 9) ); | |||
1705 | return; | |||
1706 | } | |||
1707 | ||||
1708 | Sequence< CalendarItem2 > aDaySeq = xCalendar->getDays2(); | |||
1709 | sal_Int16 nDayCount = static_cast<sal_Int16>(aDaySeq.getLength()); | |||
1710 | sal_Int16 nDay = rPar.Get32(1)->GetInteger(); | |||
1711 | sal_Int16 nFirstDay = 0; | |||
1712 | if( nParCount == 4 ) | |||
1713 | { | |||
1714 | nFirstDay = rPar.Get32(3)->GetInteger(); | |||
1715 | if( nFirstDay < 0 || nFirstDay > 7 ) | |||
1716 | { | |||
1717 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1718 | return; | |||
1719 | } | |||
1720 | } | |||
1721 | if( nFirstDay == 0 ) | |||
1722 | { | |||
1723 | nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 ); | |||
1724 | } | |||
1725 | nDay = 1 + (nDay + nDayCount + nFirstDay - 2) % nDayCount; | |||
1726 | if( nDay < 1 || nDay > nDayCount ) | |||
1727 | { | |||
1728 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1729 | return; | |||
1730 | } | |||
1731 | ||||
1732 | bool bAbbreviate = false; | |||
1733 | if( nParCount >= 3 ) | |||
1734 | { | |||
1735 | SbxVariable* pPar2 = rPar.Get32(2); | |||
1736 | if( !pPar2->IsErr() ) | |||
1737 | { | |||
1738 | bAbbreviate = pPar2->GetBool(); | |||
1739 | } | |||
1740 | } | |||
1741 | ||||
1742 | const CalendarItem2* pCalendarItems = aDaySeq.getConstArray(); | |||
1743 | const CalendarItem2& rItem = pCalendarItems[nDay - 1]; | |||
1744 | ||||
1745 | OUString aRetStr = ( bAbbreviate ? rItem.AbbrevName : rItem.FullName ); | |||
1746 | rPar.Get32(0)->PutString( aRetStr ); | |||
1747 | } | |||
1748 | ||||
1749 | void SbRtl_Weekday(StarBASIC *, SbxArray & rPar, bool) | |||
1750 | { | |||
1751 | sal_uInt32 nParCount = rPar.Count32(); | |||
1752 | if ( nParCount < 2 ) | |||
1753 | { | |||
1754 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1755 | } | |||
1756 | else | |||
1757 | { | |||
1758 | double aDate = rPar.Get32(1)->GetDate(); | |||
1759 | ||||
1760 | bool bFirstDay = false; | |||
1761 | sal_Int16 nFirstDay = 0; | |||
1762 | if ( nParCount > 2 ) | |||
1763 | { | |||
1764 | nFirstDay = rPar.Get32(2)->GetInteger(); | |||
1765 | bFirstDay = true; | |||
1766 | } | |||
1767 | sal_Int16 nDay = implGetWeekDay( aDate, bFirstDay, nFirstDay ); | |||
1768 | rPar.Get32(0)->PutInteger( nDay ); | |||
1769 | } | |||
1770 | } | |||
1771 | ||||
1772 | namespace { | |||
1773 | ||||
1774 | enum Interval | |||
1775 | { | |||
1776 | INTERVAL_YYYY, | |||
1777 | INTERVAL_Q, | |||
1778 | INTERVAL_M, | |||
1779 | INTERVAL_Y, | |||
1780 | INTERVAL_D, | |||
1781 | INTERVAL_W, | |||
1782 | INTERVAL_WW, | |||
1783 | INTERVAL_H, | |||
1784 | INTERVAL_N, | |||
1785 | INTERVAL_S | |||
1786 | }; | |||
1787 | ||||
1788 | struct IntervalInfo | |||
1789 | { | |||
1790 | Interval meInterval; | |||
1791 | char const * mStringCode; | |||
1792 | double mdValue; | |||
1793 | bool mbSimple; | |||
1794 | }; | |||
1795 | ||||
1796 | } | |||
1797 | ||||
1798 | static IntervalInfo const * getIntervalInfo( const OUString& rStringCode ) | |||
1799 | { | |||
1800 | static IntervalInfo const aIntervalTable[] = | |||
1801 | { | |||
1802 | { INTERVAL_YYYY, "yyyy", 0.0, false }, // Year | |||
1803 | { INTERVAL_Q, "q", 0.0, false }, // Quarter | |||
1804 | { INTERVAL_M, "m", 0.0, false }, // Month | |||
1805 | { INTERVAL_Y, "y", 1.0, true }, // Day of year | |||
1806 | { INTERVAL_D, "d", 1.0, true }, // Day | |||
1807 | { INTERVAL_W, "w", 1.0, true }, // Weekday | |||
1808 | { INTERVAL_WW, "ww", 7.0, true }, // Week | |||
1809 | { INTERVAL_H, "h", 1.0 / 24.0, true }, // Hour | |||
1810 | { INTERVAL_N, "n", 1.0 / 1440.0, true }, // Minute | |||
1811 | { INTERVAL_S, "s", 1.0 / 86400.0, true } // Second | |||
1812 | }; | |||
1813 | for( std::size_t i = 0; i != SAL_N_ELEMENTS(aIntervalTable)(sizeof(sal_n_array_size(aIntervalTable))); ++i ) | |||
1814 | { | |||
1815 | if( rStringCode.equalsIgnoreAsciiCaseAscii( | |||
1816 | aIntervalTable[i].mStringCode ) ) | |||
1817 | { | |||
1818 | return &aIntervalTable[i]; | |||
1819 | } | |||
1820 | } | |||
1821 | return nullptr; | |||
1822 | } | |||
1823 | ||||
1824 | static void implGetDayMonthYear( sal_Int16& rnYear, sal_Int16& rnMonth, sal_Int16& rnDay, double dDate ) | |||
1825 | { | |||
1826 | rnDay = implGetDateDay( dDate ); | |||
1827 | rnMonth = implGetDateMonth( dDate ); | |||
1828 | rnYear = implGetDateYear( dDate ); | |||
1829 | } | |||
1830 | ||||
1831 | /** Limits a date to valid dates within tools' class Date capabilities. | |||
1832 | ||||
1833 | @return the year number, truncated if necessary and in that case also | |||
1834 | rMonth and rDay adjusted. | |||
1835 | */ | |||
1836 | static sal_Int16 limitDate( sal_Int32 n32Year, sal_Int16& rMonth, sal_Int16& rDay ) | |||
1837 | { | |||
1838 | if( n32Year > SAL_MAX_INT16((sal_Int16) 0x7FFF) ) | |||
1839 | { | |||
1840 | n32Year = SAL_MAX_INT16((sal_Int16) 0x7FFF); | |||
1841 | rMonth = 12; | |||
1842 | rDay = 31; | |||
1843 | } | |||
1844 | else if( n32Year < SAL_MIN_INT16((sal_Int16) (-0x7FFF - 1)) ) | |||
1845 | { | |||
1846 | n32Year = SAL_MIN_INT16((sal_Int16) (-0x7FFF - 1)); | |||
1847 | rMonth = 1; | |||
1848 | rDay = 1; | |||
1849 | } | |||
1850 | return static_cast<sal_Int16>(n32Year); | |||
1851 | } | |||
1852 | ||||
1853 | void SbRtl_DateAdd(StarBASIC *, SbxArray & rPar, bool) | |||
1854 | { | |||
1855 | sal_uInt32 nParCount = rPar.Count32(); | |||
1856 | if( nParCount != 4 ) | |||
1857 | { | |||
1858 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1859 | return; | |||
1860 | } | |||
1861 | ||||
1862 | OUString aStringCode = rPar.Get32(1)->GetOUString(); | |||
1863 | IntervalInfo const * pInfo = getIntervalInfo( aStringCode ); | |||
1864 | if( !pInfo ) | |||
1865 | { | |||
1866 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1867 | return; | |||
1868 | } | |||
1869 | ||||
1870 | sal_Int32 lNumber = rPar.Get32(2)->GetLong(); | |||
1871 | double dDate = rPar.Get32(3)->GetDate(); | |||
1872 | double dNewDate = 0; | |||
1873 | if( pInfo->mbSimple ) | |||
1874 | { | |||
1875 | double dAdd = pInfo->mdValue * lNumber; | |||
1876 | dNewDate = dDate + dAdd; | |||
1877 | } | |||
1878 | else | |||
1879 | { | |||
1880 | // Keep hours, minutes, seconds | |||
1881 | double dHoursMinutesSeconds = dDate - floor( dDate ); | |||
1882 | ||||
1883 | bool bOk = true; | |||
1884 | sal_Int16 nYear, nMonth, nDay; | |||
1885 | sal_Int16 nTargetYear16 = 0, nTargetMonth = 0; | |||
1886 | implGetDayMonthYear( nYear, nMonth, nDay, dDate ); | |||
1887 | switch( pInfo->meInterval ) | |||
1888 | { | |||
1889 | case INTERVAL_YYYY: | |||
1890 | { | |||
1891 | sal_Int32 nTargetYear = lNumber + nYear; | |||
1892 | nTargetYear16 = limitDate( nTargetYear, nMonth, nDay ); | |||
1893 | /* TODO: should the result be error if the date was limited? It never was. */ | |||
1894 | nTargetMonth = nMonth; | |||
1895 | bOk = implDateSerial( nTargetYear16, nTargetMonth, nDay, false, SbDateCorrection::TruncateToMonth, dNewDate ); | |||
1896 | break; | |||
1897 | } | |||
1898 | case INTERVAL_Q: | |||
1899 | case INTERVAL_M: | |||
1900 | { | |||
1901 | bool bNeg = (lNumber < 0); | |||
1902 | if( bNeg ) | |||
1903 | lNumber = -lNumber; | |||
1904 | sal_Int32 nYearsAdd; | |||
1905 | sal_Int16 nMonthAdd; | |||
1906 | if( pInfo->meInterval == INTERVAL_Q ) | |||
1907 | { | |||
1908 | nYearsAdd = lNumber / 4; | |||
1909 | nMonthAdd = static_cast<sal_Int16>( 3 * (lNumber % 4) ); | |||
1910 | } | |||
1911 | else | |||
1912 | { | |||
1913 | nYearsAdd = lNumber / 12; | |||
1914 | nMonthAdd = static_cast<sal_Int16>( lNumber % 12 ); | |||
1915 | } | |||
1916 | ||||
1917 | sal_Int32 nTargetYear; | |||
1918 | if( bNeg ) | |||
1919 | { | |||
1920 | nTargetMonth = nMonth - nMonthAdd; | |||
1921 | if( nTargetMonth <= 0 ) | |||
1922 | { | |||
1923 | nTargetMonth += 12; | |||
1924 | nYearsAdd++; | |||
1925 | } | |||
1926 | nTargetYear = static_cast<sal_Int32>(nYear) - nYearsAdd; | |||
1927 | } | |||
1928 | else | |||
1929 | { | |||
1930 | nTargetMonth = nMonth + nMonthAdd; | |||
1931 | if( nTargetMonth > 12 ) | |||
1932 | { | |||
1933 | nTargetMonth -= 12; | |||
1934 | nYearsAdd++; | |||
1935 | } | |||
1936 | nTargetYear = static_cast<sal_Int32>(nYear) + nYearsAdd; | |||
1937 | } | |||
1938 | nTargetYear16 = limitDate( nTargetYear, nTargetMonth, nDay ); | |||
1939 | /* TODO: should the result be error if the date was limited? It never was. */ | |||
1940 | bOk = implDateSerial( nTargetYear16, nTargetMonth, nDay, false, SbDateCorrection::TruncateToMonth, dNewDate ); | |||
1941 | break; | |||
1942 | } | |||
1943 | default: break; | |||
1944 | } | |||
1945 | ||||
1946 | if( bOk ) | |||
1947 | dNewDate += dHoursMinutesSeconds; | |||
1948 | } | |||
1949 | ||||
1950 | rPar.Get32(0)->PutDate( dNewDate ); | |||
1951 | } | |||
1952 | ||||
1953 | static double RoundImpl( double d ) | |||
1954 | { | |||
1955 | return ( d >= 0 ) ? floor( d + 0.5 ) : -floor( -d + 0.5 ); | |||
1956 | } | |||
1957 | ||||
1958 | void SbRtl_DateDiff(StarBASIC *, SbxArray & rPar, bool) | |||
1959 | { | |||
1960 | // DateDiff(interval, date1, date2[, firstdayofweek[, firstweekofyear]]) | |||
1961 | ||||
1962 | sal_uInt32 nParCount = rPar.Count32(); | |||
1963 | if( nParCount < 4 || nParCount > 6 ) | |||
1964 | { | |||
1965 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1966 | return; | |||
1967 | } | |||
1968 | ||||
1969 | OUString aStringCode = rPar.Get32(1)->GetOUString(); | |||
1970 | IntervalInfo const * pInfo = getIntervalInfo( aStringCode ); | |||
1971 | if( !pInfo ) | |||
1972 | { | |||
1973 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
1974 | return; | |||
1975 | } | |||
1976 | ||||
1977 | double dDate1 = rPar.Get32(2)->GetDate(); | |||
1978 | double dDate2 = rPar.Get32(3)->GetDate(); | |||
1979 | ||||
1980 | double dRet = 0.0; | |||
1981 | switch( pInfo->meInterval ) | |||
1982 | { | |||
1983 | case INTERVAL_YYYY: | |||
1984 | { | |||
1985 | sal_Int16 nYear1 = implGetDateYear( dDate1 ); | |||
1986 | sal_Int16 nYear2 = implGetDateYear( dDate2 ); | |||
1987 | dRet = nYear2 - nYear1; | |||
1988 | break; | |||
1989 | } | |||
1990 | case INTERVAL_Q: | |||
1991 | { | |||
1992 | sal_Int16 nYear1 = implGetDateYear( dDate1 ); | |||
1993 | sal_Int16 nYear2 = implGetDateYear( dDate2 ); | |||
1994 | sal_Int16 nQ1 = 1 + (implGetDateMonth( dDate1 ) - 1) / 3; | |||
1995 | sal_Int16 nQ2 = 1 + (implGetDateMonth( dDate2 ) - 1) / 3; | |||
1996 | sal_Int16 nQGes1 = 4 * nYear1 + nQ1; | |||
1997 | sal_Int16 nQGes2 = 4 * nYear2 + nQ2; | |||
1998 | dRet = nQGes2 - nQGes1; | |||
1999 | break; | |||
2000 | } | |||
2001 | case INTERVAL_M: | |||
2002 | { | |||
2003 | sal_Int16 nYear1 = implGetDateYear( dDate1 ); | |||
2004 | sal_Int16 nYear2 = implGetDateYear( dDate2 ); | |||
2005 | sal_Int16 nMonth1 = implGetDateMonth( dDate1 ); | |||
2006 | sal_Int16 nMonth2 = implGetDateMonth( dDate2 ); | |||
2007 | sal_Int16 nMonthGes1 = 12 * nYear1 + nMonth1; | |||
2008 | sal_Int16 nMonthGes2 = 12 * nYear2 + nMonth2; | |||
2009 | dRet = nMonthGes2 - nMonthGes1; | |||
2010 | break; | |||
2011 | } | |||
2012 | case INTERVAL_Y: | |||
2013 | case INTERVAL_D: | |||
2014 | { | |||
2015 | double dDays1 = floor( dDate1 ); | |||
2016 | double dDays2 = floor( dDate2 ); | |||
2017 | dRet = dDays2 - dDays1; | |||
2018 | break; | |||
2019 | } | |||
2020 | case INTERVAL_W: | |||
2021 | case INTERVAL_WW: | |||
2022 | { | |||
2023 | double dDays1 = floor( dDate1 ); | |||
2024 | double dDays2 = floor( dDate2 ); | |||
2025 | if( pInfo->meInterval == INTERVAL_WW ) | |||
2026 | { | |||
2027 | sal_Int16 nFirstDay = 1; // Default | |||
2028 | if( nParCount >= 5 ) | |||
2029 | { | |||
2030 | nFirstDay = rPar.Get32(4)->GetInteger(); | |||
2031 | if( nFirstDay < 0 || nFirstDay > 7 ) | |||
2032 | { | |||
2033 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2034 | return; | |||
2035 | } | |||
2036 | if( nFirstDay == 0 ) | |||
2037 | { | |||
2038 | const Reference< XCalendar4 >& xCalendar = getLocaleCalendar(); | |||
2039 | if( !xCalendar.is() ) | |||
2040 | { | |||
2041 | StarBASIC::Error( ERRCODE_BASIC_INTERNAL_ERRORErrCode( ErrCodeArea::Sbx, ErrCodeClass::Unknown, 9) ); | |||
2042 | return; | |||
2043 | } | |||
2044 | nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 ); | |||
2045 | } | |||
2046 | } | |||
2047 | sal_Int16 nDay1 = implGetWeekDay( dDate1 ); | |||
2048 | sal_Int16 nDay1_Diff = nDay1 - nFirstDay; | |||
2049 | if( nDay1_Diff < 0 ) | |||
2050 | nDay1_Diff += 7; | |||
2051 | dDays1 -= nDay1_Diff; | |||
2052 | ||||
2053 | sal_Int16 nDay2 = implGetWeekDay( dDate2 ); | |||
2054 | sal_Int16 nDay2_Diff = nDay2 - nFirstDay; | |||
2055 | if( nDay2_Diff < 0 ) | |||
2056 | nDay2_Diff += 7; | |||
2057 | dDays2 -= nDay2_Diff; | |||
2058 | } | |||
2059 | ||||
2060 | double dDiff = dDays2 - dDays1; | |||
2061 | dRet = ( dDiff >= 0 ) ? floor( dDiff / 7.0 ) : -floor( -dDiff / 7.0 ); | |||
2062 | break; | |||
2063 | } | |||
2064 | case INTERVAL_H: | |||
2065 | { | |||
2066 | dRet = RoundImpl( 24.0 * (dDate2 - dDate1) ); | |||
2067 | break; | |||
2068 | } | |||
2069 | case INTERVAL_N: | |||
2070 | { | |||
2071 | dRet = RoundImpl( 1440.0 * (dDate2 - dDate1) ); | |||
2072 | break; | |||
2073 | } | |||
2074 | case INTERVAL_S: | |||
2075 | { | |||
2076 | dRet = RoundImpl( 86400.0 * (dDate2 - dDate1) ); | |||
2077 | break; | |||
2078 | } | |||
2079 | } | |||
2080 | rPar.Get32(0)->PutDouble( dRet ); | |||
2081 | } | |||
2082 | ||||
2083 | static double implGetDateOfFirstDayInFirstWeek | |||
2084 | ( sal_Int16 nYear, sal_Int16& nFirstDay, sal_Int16& nFirstWeek, bool* pbError = nullptr ) | |||
2085 | { | |||
2086 | ErrCode nError = ERRCODE_NONEErrCode(0); | |||
2087 | if( nFirstDay < 0 || nFirstDay > 7 ) | |||
2088 | nError = ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2); | |||
2089 | ||||
2090 | if( nFirstWeek < 0 || nFirstWeek > 3 ) | |||
2091 | nError = ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2); | |||
2092 | ||||
2093 | Reference< XCalendar4 > xCalendar; | |||
2094 | if( nFirstDay == 0 || nFirstWeek == 0 ) | |||
2095 | { | |||
2096 | xCalendar = getLocaleCalendar(); | |||
2097 | if( !xCalendar.is() ) | |||
2098 | nError = ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2); | |||
2099 | } | |||
2100 | ||||
2101 | if( nError != ERRCODE_NONEErrCode(0) ) | |||
2102 | { | |||
2103 | StarBASIC::Error( nError ); | |||
2104 | if( pbError ) | |||
2105 | *pbError = true; | |||
2106 | return 0.0; | |||
2107 | } | |||
2108 | ||||
2109 | if( nFirstDay == 0 ) | |||
2110 | nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 ); | |||
2111 | ||||
2112 | sal_Int16 nFirstWeekMinDays = 0; // Not used for vbFirstJan1 = default | |||
2113 | if( nFirstWeek == 0 ) | |||
2114 | { | |||
2115 | nFirstWeekMinDays = xCalendar->getMinimumNumberOfDaysForFirstWeek(); | |||
2116 | if( nFirstWeekMinDays == 1 ) | |||
2117 | { | |||
2118 | nFirstWeekMinDays = 0; | |||
2119 | nFirstWeek = 1; | |||
2120 | } | |||
2121 | else if( nFirstWeekMinDays == 4 ) | |||
2122 | nFirstWeek = 2; | |||
2123 | else if( nFirstWeekMinDays == 7 ) | |||
2124 | nFirstWeek = 3; | |||
2125 | } | |||
2126 | else if( nFirstWeek == 2 ) | |||
2127 | nFirstWeekMinDays = 4; // vbFirstFourDays | |||
2128 | else if( nFirstWeek == 3 ) | |||
2129 | nFirstWeekMinDays = 7; // vbFirstFourDays | |||
2130 | ||||
2131 | double dBaseDate; | |||
2132 | implDateSerial( nYear, 1, 1, false, SbDateCorrection::None, dBaseDate ); | |||
2133 | ||||
2134 | sal_Int16 nWeekDay0101 = implGetWeekDay( dBaseDate ); | |||
2135 | sal_Int16 nDayDiff = nWeekDay0101 - nFirstDay; | |||
2136 | if( nDayDiff < 0 ) | |||
2137 | nDayDiff += 7; | |||
2138 | ||||
2139 | if( nFirstWeekMinDays ) | |||
2140 | { | |||
2141 | sal_Int16 nThisWeeksDaysInYearCount = 7 - nDayDiff; | |||
2142 | if( nThisWeeksDaysInYearCount < nFirstWeekMinDays ) | |||
2143 | nDayDiff -= 7; | |||
2144 | } | |||
2145 | double dRetDate = dBaseDate - nDayDiff; | |||
2146 | return dRetDate; | |||
2147 | } | |||
2148 | ||||
2149 | void SbRtl_DatePart(StarBASIC *, SbxArray & rPar, bool) | |||
2150 | { | |||
2151 | // DatePart(interval, date[,firstdayofweek[, firstweekofyear]]) | |||
2152 | ||||
2153 | sal_uInt32 nParCount = rPar.Count32(); | |||
2154 | if( nParCount < 3 || nParCount > 5 ) | |||
2155 | { | |||
2156 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2157 | return; | |||
2158 | } | |||
2159 | ||||
2160 | OUString aStringCode = rPar.Get32(1)->GetOUString(); | |||
2161 | IntervalInfo const * pInfo = getIntervalInfo( aStringCode ); | |||
2162 | if( !pInfo ) | |||
2163 | { | |||
2164 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2165 | return; | |||
2166 | } | |||
2167 | ||||
2168 | double dDate = rPar.Get32(2)->GetDate(); | |||
2169 | ||||
2170 | sal_Int32 nRet = 0; | |||
2171 | switch( pInfo->meInterval ) | |||
2172 | { | |||
2173 | case INTERVAL_YYYY: | |||
2174 | { | |||
2175 | nRet = implGetDateYear( dDate ); | |||
2176 | break; | |||
2177 | } | |||
2178 | case INTERVAL_Q: | |||
2179 | { | |||
2180 | nRet = 1 + (implGetDateMonth( dDate ) - 1) / 3; | |||
2181 | break; | |||
2182 | } | |||
2183 | case INTERVAL_M: | |||
2184 | { | |||
2185 | nRet = implGetDateMonth( dDate ); | |||
2186 | break; | |||
2187 | } | |||
2188 | case INTERVAL_Y: | |||
2189 | { | |||
2190 | sal_Int16 nYear = implGetDateYear( dDate ); | |||
2191 | double dBaseDate; | |||
2192 | implDateSerial( nYear, 1, 1, false, SbDateCorrection::None, dBaseDate ); | |||
2193 | nRet = 1 + sal_Int32( dDate - dBaseDate ); | |||
2194 | break; | |||
2195 | } | |||
2196 | case INTERVAL_D: | |||
2197 | { | |||
2198 | nRet = implGetDateDay( dDate ); | |||
2199 | break; | |||
2200 | } | |||
2201 | case INTERVAL_W: | |||
2202 | { | |||
2203 | bool bFirstDay = false; | |||
2204 | sal_Int16 nFirstDay = 1; // Default | |||
2205 | if( nParCount >= 4 ) | |||
2206 | { | |||
2207 | nFirstDay = rPar.Get32(3)->GetInteger(); | |||
2208 | bFirstDay = true; | |||
2209 | } | |||
2210 | nRet = implGetWeekDay( dDate, bFirstDay, nFirstDay ); | |||
2211 | break; | |||
2212 | } | |||
2213 | case INTERVAL_WW: | |||
2214 | { | |||
2215 | sal_Int16 nFirstDay = 1; // Default | |||
2216 | if( nParCount >= 4 ) | |||
2217 | nFirstDay = rPar.Get32(3)->GetInteger(); | |||
2218 | ||||
2219 | sal_Int16 nFirstWeek = 1; // Default | |||
2220 | if( nParCount == 5 ) | |||
2221 | nFirstWeek = rPar.Get32(4)->GetInteger(); | |||
2222 | ||||
2223 | sal_Int16 nYear = implGetDateYear( dDate ); | |||
2224 | bool bError = false; | |||
2225 | double dYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear, nFirstDay, nFirstWeek, &bError ); | |||
2226 | if( !bError ) | |||
2227 | { | |||
2228 | if( dYearFirstDay > dDate ) | |||
2229 | { | |||
2230 | // Date belongs to last year's week | |||
2231 | dYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear - 1, nFirstDay, nFirstWeek ); | |||
2232 | } | |||
2233 | else if( nFirstWeek != 1 ) | |||
2234 | { | |||
2235 | // Check if date belongs to next year | |||
2236 | double dNextYearFirstDay = implGetDateOfFirstDayInFirstWeek( nYear + 1, nFirstDay, nFirstWeek ); | |||
2237 | if( dDate >= dNextYearFirstDay ) | |||
2238 | dYearFirstDay = dNextYearFirstDay; | |||
2239 | } | |||
2240 | ||||
2241 | // Calculate week | |||
2242 | double dDiff = dDate - dYearFirstDay; | |||
2243 | nRet = 1 + sal_Int32( dDiff / 7 ); | |||
2244 | } | |||
2245 | break; | |||
2246 | } | |||
2247 | case INTERVAL_H: | |||
2248 | { | |||
2249 | nRet = implGetHour( dDate ); | |||
2250 | break; | |||
2251 | } | |||
2252 | case INTERVAL_N: | |||
2253 | { | |||
2254 | nRet = implGetMinute( dDate ); | |||
2255 | break; | |||
2256 | } | |||
2257 | case INTERVAL_S: | |||
2258 | { | |||
2259 | nRet = implGetSecond( dDate ); | |||
2260 | break; | |||
2261 | } | |||
2262 | } | |||
2263 | rPar.Get32(0)->PutLong( nRet ); | |||
2264 | } | |||
2265 | ||||
2266 | // FormatDateTime(Date[,NamedFormat]) | |||
2267 | void SbRtl_FormatDateTime(StarBASIC *, SbxArray & rPar, bool) | |||
2268 | { | |||
2269 | sal_uInt32 nParCount = rPar.Count32(); | |||
2270 | if( nParCount < 2 || nParCount > 3 ) | |||
| ||||
2271 | { | |||
2272 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2273 | return; | |||
2274 | } | |||
2275 | ||||
2276 | double dDate = rPar.Get32(1)->GetDate(); | |||
2277 | sal_Int16 nNamedFormat = 0; | |||
2278 | if( nParCount > 2 ) | |||
2279 | { | |||
2280 | nNamedFormat = rPar.Get32(2)->GetInteger(); | |||
2281 | if( nNamedFormat < 0 || nNamedFormat > 4 ) | |||
2282 | { | |||
2283 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2284 | return; | |||
2285 | } | |||
2286 | } | |||
2287 | ||||
2288 | const Reference< XCalendar4 >& xCalendar = getLocaleCalendar(); | |||
2289 | if( !xCalendar.is() ) | |||
2290 | { | |||
2291 | StarBASIC::Error( ERRCODE_BASIC_INTERNAL_ERRORErrCode( ErrCodeArea::Sbx, ErrCodeClass::Unknown, 9) ); | |||
2292 | return; | |||
2293 | } | |||
2294 | ||||
2295 | OUString aRetStr; | |||
2296 | SbxVariableRef pSbxVar = new SbxVariable( SbxSTRING ); | |||
2297 | switch( nNamedFormat ) | |||
2298 | { | |||
2299 | // GeneralDate: | |||
2300 | // Display a date and/or time. If there is a date part, | |||
2301 | // display it as a short date. If there is a time part, | |||
2302 | // display it as a long time. If present, both parts are displayed. | |||
2303 | ||||
2304 | // 12/21/2004 11:24:50 AM | |||
2305 | // 21.12.2004 12:13:51 | |||
2306 | case 0: | |||
2307 | pSbxVar->PutDate( dDate ); | |||
2308 | aRetStr = pSbxVar->GetOUString(); | |||
2309 | break; | |||
2310 | ||||
2311 | // LongDate: Display a date using the long date format specified | |||
2312 | // in your computer's regional settings. | |||
2313 | // Tuesday, December 21, 2004 | |||
2314 | // Dienstag, 21. December 2004 | |||
2315 | case 1: | |||
2316 | { | |||
2317 | std::shared_ptr<SvNumberFormatter> pFormatter; | |||
2318 | if( GetSbData()->pInst ) | |||
2319 | { | |||
2320 | pFormatter = GetSbData()->pInst->GetNumberFormatter(); | |||
2321 | } | |||
2322 | else | |||
2323 | { | |||
2324 | sal_uInt32 n; // Dummy | |||
2325 | pFormatter = SbiInstance::PrepareNumberFormatter( n, n, n ); | |||
2326 | } | |||
2327 | ||||
2328 | LanguageType eLangType = Application::GetSettings().GetLanguageTag().getLanguageType(); | |||
2329 | const sal_uInt32 nIndex = pFormatter->GetFormatIndex( NF_DATE_SYSTEM_LONG, eLangType ); | |||
2330 | const Color* pCol; | |||
2331 | pFormatter->GetOutputString( dDate, nIndex, aRetStr, &pCol ); | |||
2332 | break; | |||
2333 | } | |||
2334 | ||||
2335 | // ShortDate: Display a date using the short date format specified | |||
2336 | // in your computer's regional settings. | |||
2337 | // 21.12.2004 | |||
2338 | case 2: | |||
2339 | pSbxVar->PutDate( floor(dDate) ); | |||
2340 | aRetStr = pSbxVar->GetOUString(); | |||
2341 | break; | |||
2342 | ||||
2343 | // LongTime: Display a time using the time format specified | |||
2344 | // in your computer's regional settings. | |||
2345 | // 11:24:50 AM | |||
2346 | // 12:13:51 | |||
2347 | case 3: | |||
2348 | // ShortTime: Display a time using the 24-hour format (hh:mm). | |||
2349 | // 11:24 | |||
2350 | case 4: | |||
2351 | double dTime = modf( dDate, &o3tl::temporary(double()) ); | |||
2352 | pSbxVar->PutDate( dTime ); | |||
2353 | if( nNamedFormat == 3 ) | |||
2354 | { | |||
2355 | aRetStr = pSbxVar->GetOUString(); | |||
2356 | } | |||
2357 | else | |||
2358 | { | |||
2359 | aRetStr = pSbxVar->GetOUString().copy( 0, 5 ); | |||
2360 | } | |||
2361 | break; | |||
2362 | } | |||
2363 | ||||
2364 | rPar.Get32(0)->PutString( aRetStr ); | |||
2365 | } | |||
| ||||
2366 | ||||
2367 | void SbRtl_Frac(StarBASIC *, SbxArray & rPar, bool) | |||
2368 | { | |||
2369 | sal_uInt32 nParCount = rPar.Count32(); | |||
2370 | if( nParCount != 2) | |||
2371 | { | |||
2372 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2373 | return; | |||
2374 | } | |||
2375 | ||||
2376 | SbxVariable *pSbxVariable = rPar.Get32(1); | |||
2377 | double dVal = pSbxVariable->GetDouble(); | |||
2378 | if(dVal >= 0) | |||
2379 | rPar.Get32(0)->PutDouble(dVal - ::rtl::math::approxFloor(dVal)); | |||
2380 | else | |||
2381 | rPar.Get32(0)->PutDouble(dVal - ::rtl::math::approxCeil(dVal)); | |||
2382 | } | |||
2383 | ||||
2384 | void SbRtl_Round(StarBASIC *, SbxArray & rPar, bool) | |||
2385 | { | |||
2386 | sal_uInt32 nParCount = rPar.Count32(); | |||
2387 | if( nParCount != 2 && nParCount != 3 ) | |||
2388 | { | |||
2389 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2390 | return; | |||
2391 | } | |||
2392 | ||||
2393 | SbxVariable *pSbxVariable = rPar.Get32(1); | |||
2394 | double dVal = pSbxVariable->GetDouble(); | |||
2395 | double dRes = 0.0; | |||
2396 | if( dVal != 0.0 ) | |||
2397 | { | |||
2398 | bool bNeg = false; | |||
2399 | if( dVal < 0.0 ) | |||
2400 | { | |||
2401 | bNeg = true; | |||
2402 | dVal = -dVal; | |||
2403 | } | |||
2404 | ||||
2405 | sal_Int16 numdecimalplaces = 0; | |||
2406 | if( nParCount == 3 ) | |||
2407 | { | |||
2408 | numdecimalplaces = rPar.Get32(2)->GetInteger(); | |||
2409 | if( numdecimalplaces < 0 || numdecimalplaces > 22 ) | |||
2410 | { | |||
2411 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2412 | return; | |||
2413 | } | |||
2414 | } | |||
2415 | ||||
2416 | if( numdecimalplaces == 0 ) | |||
2417 | { | |||
2418 | dRes = floor( dVal + 0.5 ); | |||
2419 | } | |||
2420 | else | |||
2421 | { | |||
2422 | double dFactor = pow( 10.0, numdecimalplaces ); | |||
2423 | dVal *= dFactor; | |||
2424 | dRes = floor( dVal + 0.5 ); | |||
2425 | dRes /= dFactor; | |||
2426 | } | |||
2427 | ||||
2428 | if( bNeg ) | |||
2429 | dRes = -dRes; | |||
2430 | } | |||
2431 | rPar.Get32(0)->PutDouble( dRes ); | |||
2432 | } | |||
2433 | ||||
2434 | static void CallFunctionAccessFunction( const Sequence< Any >& aArgs, const OUString& sFuncName, SbxVariable* pRet ) | |||
2435 | { | |||
2436 | static Reference< XFunctionAccess > xFunc; | |||
2437 | try | |||
2438 | { | |||
2439 | if ( !xFunc.is() ) | |||
2440 | { | |||
2441 | Reference< XMultiServiceFactory > xFactory( getProcessServiceFactory() ); | |||
2442 | if( xFactory.is() ) | |||
2443 | { | |||
2444 | xFunc.set( xFactory->createInstance("com.sun.star.sheet.FunctionAccess"), UNO_QUERY_THROW); | |||
2445 | } | |||
2446 | } | |||
2447 | Any aRet = xFunc->callFunction( sFuncName, aArgs ); | |||
2448 | ||||
2449 | unoToSbxValue( pRet, aRet ); | |||
2450 | ||||
2451 | } | |||
2452 | catch(const Exception& ) | |||
2453 | { | |||
2454 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2455 | } | |||
2456 | } | |||
2457 | ||||
2458 | void SbRtl_SYD(StarBASIC *, SbxArray & rPar, bool) | |||
2459 | { | |||
2460 | sal_uInt32 nArgCount = rPar.Count32()-1; | |||
2461 | ||||
2462 | if ( nArgCount < 4 ) | |||
2463 | { | |||
2464 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2465 | return; | |||
2466 | } | |||
2467 | ||||
2468 | // retrieve non-optional params | |||
2469 | ||||
2470 | Sequence< Any > aParams( 4 ); | |||
2471 | aParams[ 0 ] <<= rPar.Get32(1)->GetDouble(); | |||
2472 | aParams[ 1 ] <<= rPar.Get32(2)->GetDouble(); | |||
2473 | aParams[ 2 ] <<= rPar.Get32(3)->GetDouble(); | |||
2474 | aParams[ 3 ] <<= rPar.Get32(4)->GetDouble(); | |||
2475 | ||||
2476 | CallFunctionAccessFunction( aParams, "SYD", rPar.Get32( 0 ) ); | |||
2477 | } | |||
2478 | ||||
2479 | void SbRtl_SLN(StarBASIC *, SbxArray & rPar, bool) | |||
2480 | { | |||
2481 | sal_uInt32 nArgCount = rPar.Count32()-1; | |||
2482 | ||||
2483 | if ( nArgCount < 3 ) | |||
2484 | { | |||
2485 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2486 | return; | |||
2487 | } | |||
2488 | ||||
2489 | // retrieve non-optional params | |||
2490 | ||||
2491 | Sequence< Any > aParams( 3 ); | |||
2492 | aParams[ 0 ] <<= rPar.Get32(1)->GetDouble(); | |||
2493 | aParams[ 1 ] <<= rPar.Get32(2)->GetDouble(); | |||
2494 | aParams[ 2 ] <<= rPar.Get32(3)->GetDouble(); | |||
2495 | ||||
2496 | CallFunctionAccessFunction( aParams, "SLN", rPar.Get32( 0 ) ); | |||
2497 | } | |||
2498 | ||||
2499 | void SbRtl_Pmt(StarBASIC *, SbxArray & rPar, bool) | |||
2500 | { | |||
2501 | sal_uInt32 nArgCount = rPar.Count32()-1; | |||
2502 | ||||
2503 | if ( nArgCount < 3 || nArgCount > 5 ) | |||
2504 | { | |||
2505 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2506 | return; | |||
2507 | } | |||
2508 | // retrieve non-optional params | |||
2509 | ||||
2510 | double rate = rPar.Get32(1)->GetDouble(); | |||
2511 | double nper = rPar.Get32(2)->GetDouble(); | |||
2512 | double pmt = rPar.Get32(3)->GetDouble(); | |||
2513 | ||||
2514 | // set default values for Optional args | |||
2515 | double fv = 0; | |||
2516 | double type = 0; | |||
2517 | ||||
2518 | // fv | |||
2519 | if ( nArgCount >= 4 ) | |||
2520 | { | |||
2521 | if( rPar.Get32(4)->GetType() != SbxEMPTY ) | |||
2522 | fv = rPar.Get32(4)->GetDouble(); | |||
2523 | } | |||
2524 | // type | |||
2525 | if ( nArgCount >= 5 ) | |||
2526 | { | |||
2527 | if( rPar.Get32(5)->GetType() != SbxEMPTY ) | |||
2528 | type = rPar.Get32(5)->GetDouble(); | |||
2529 | } | |||
2530 | ||||
2531 | Sequence< Any > aParams( 5 ); | |||
2532 | aParams[ 0 ] <<= rate; | |||
2533 | aParams[ 1 ] <<= nper; | |||
2534 | aParams[ 2 ] <<= pmt; | |||
2535 | aParams[ 3 ] <<= fv; | |||
2536 | aParams[ 4 ] <<= type; | |||
2537 | ||||
2538 | CallFunctionAccessFunction( aParams, "Pmt", rPar.Get32( 0 ) ); | |||
2539 | } | |||
2540 | ||||
2541 | void SbRtl_PPmt(StarBASIC *, SbxArray & rPar, bool) | |||
2542 | { | |||
2543 | sal_uInt32 nArgCount = rPar.Count32()-1; | |||
2544 | ||||
2545 | if ( nArgCount < 4 || nArgCount > 6 ) | |||
2546 | { | |||
2547 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2548 | return; | |||
2549 | } | |||
2550 | // retrieve non-optional params | |||
2551 | ||||
2552 | double rate = rPar.Get32(1)->GetDouble(); | |||
2553 | double per = rPar.Get32(2)->GetDouble(); | |||
2554 | double nper = rPar.Get32(3)->GetDouble(); | |||
2555 | double pv = rPar.Get32(4)->GetDouble(); | |||
2556 | ||||
2557 | // set default values for Optional args | |||
2558 | double fv = 0; | |||
2559 | double type = 0; | |||
2560 | ||||
2561 | // fv | |||
2562 | if ( nArgCount >= 5 ) | |||
2563 | { | |||
2564 | if( rPar.Get32(5)->GetType() != SbxEMPTY ) | |||
2565 | fv = rPar.Get32(5)->GetDouble(); | |||
2566 | } | |||
2567 | // type | |||
2568 | if ( nArgCount >= 6 ) | |||
2569 | { | |||
2570 | if( rPar.Get32(6)->GetType() != SbxEMPTY ) | |||
2571 | type = rPar.Get32(6)->GetDouble(); | |||
2572 | } | |||
2573 | ||||
2574 | Sequence< Any > aParams( 6 ); | |||
2575 | aParams[ 0 ] <<= rate; | |||
2576 | aParams[ 1 ] <<= per; | |||
2577 | aParams[ 2 ] <<= nper; | |||
2578 | aParams[ 3 ] <<= pv; | |||
2579 | aParams[ 4 ] <<= fv; | |||
2580 | aParams[ 5 ] <<= type; | |||
2581 | ||||
2582 | CallFunctionAccessFunction( aParams, "PPmt", rPar.Get32( 0 ) ); | |||
2583 | } | |||
2584 | ||||
2585 | void SbRtl_PV(StarBASIC *, SbxArray & rPar, bool) | |||
2586 | { | |||
2587 | sal_uInt32 nArgCount = rPar.Count32()-1; | |||
2588 | ||||
2589 | if ( nArgCount < 3 || nArgCount > 5 ) | |||
2590 | { | |||
2591 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2592 | return; | |||
2593 | } | |||
2594 | // retrieve non-optional params | |||
2595 | ||||
2596 | double rate = rPar.Get32(1)->GetDouble(); | |||
2597 | double nper = rPar.Get32(2)->GetDouble(); | |||
2598 | double pmt = rPar.Get32(3)->GetDouble(); | |||
2599 | ||||
2600 | // set default values for Optional args | |||
2601 | double fv = 0; | |||
2602 | double type = 0; | |||
2603 | ||||
2604 | // fv | |||
2605 | if ( nArgCount >= 4 ) | |||
2606 | { | |||
2607 | if( rPar.Get32(4)->GetType() != SbxEMPTY ) | |||
2608 | fv = rPar.Get32(4)->GetDouble(); | |||
2609 | } | |||
2610 | // type | |||
2611 | if ( nArgCount >= 5 ) | |||
2612 | { | |||
2613 | if( rPar.Get32(5)->GetType() != SbxEMPTY ) | |||
2614 | type = rPar.Get32(5)->GetDouble(); | |||
2615 | } | |||
2616 | ||||
2617 | Sequence< Any > aParams( 5 ); | |||
2618 | aParams[ 0 ] <<= rate; | |||
2619 | aParams[ 1 ] <<= nper; | |||
2620 | aParams[ 2 ] <<= pmt; | |||
2621 | aParams[ 3 ] <<= fv; | |||
2622 | aParams[ 4 ] <<= type; | |||
2623 | ||||
2624 | CallFunctionAccessFunction( aParams, "PV", rPar.Get32( 0 ) ); | |||
2625 | } | |||
2626 | ||||
2627 | void SbRtl_NPV(StarBASIC *, SbxArray & rPar, bool) | |||
2628 | { | |||
2629 | sal_uInt32 nArgCount = rPar.Count32()-1; | |||
2630 | ||||
2631 | if ( nArgCount < 1 || nArgCount > 2 ) | |||
2632 | { | |||
2633 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2634 | return; | |||
2635 | } | |||
2636 | ||||
2637 | Sequence< Any > aParams( 2 ); | |||
2638 | aParams[ 0 ] <<= rPar.Get32(1)->GetDouble(); | |||
2639 | Any aValues = sbxToUnoValue( rPar.Get32(2), | |||
2640 | cppu::UnoType<Sequence<double>>::get() ); | |||
2641 | ||||
2642 | // convert for calc functions | |||
2643 | Sequence< Sequence< double > > sValues(1); | |||
2644 | aValues >>= sValues[ 0 ]; | |||
2645 | aValues <<= sValues; | |||
2646 | ||||
2647 | aParams[ 1 ] = aValues; | |||
2648 | ||||
2649 | CallFunctionAccessFunction( aParams, "NPV", rPar.Get32( 0 ) ); | |||
2650 | } | |||
2651 | ||||
2652 | void SbRtl_NPer(StarBASIC *, SbxArray & rPar, bool) | |||
2653 | { | |||
2654 | sal_uInt32 nArgCount = rPar.Count32()-1; | |||
2655 | ||||
2656 | if ( nArgCount < 3 || nArgCount > 5 ) | |||
2657 | { | |||
2658 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2659 | return; | |||
2660 | } | |||
2661 | // retrieve non-optional params | |||
2662 | ||||
2663 | double rate = rPar.Get32(1)->GetDouble(); | |||
2664 | double pmt = rPar.Get32(2)->GetDouble(); | |||
2665 | double pv = rPar.Get32(3)->GetDouble(); | |||
2666 | ||||
2667 | // set default values for Optional args | |||
2668 | double fv = 0; | |||
2669 | double type = 0; | |||
2670 | ||||
2671 | // fv | |||
2672 | if ( nArgCount >= 4 ) | |||
2673 | { | |||
2674 | if( rPar.Get32(4)->GetType() != SbxEMPTY ) | |||
2675 | fv = rPar.Get32(4)->GetDouble(); | |||
2676 | } | |||
2677 | // type | |||
2678 | if ( nArgCount >= 5 ) | |||
2679 | { | |||
2680 | if( rPar.Get32(5)->GetType() != SbxEMPTY ) | |||
2681 | type = rPar.Get32(5)->GetDouble(); | |||
2682 | } | |||
2683 | ||||
2684 | Sequence< Any > aParams( 5 ); | |||
2685 | aParams[ 0 ] <<= rate; | |||
2686 | aParams[ 1 ] <<= pmt; | |||
2687 | aParams[ 2 ] <<= pv; | |||
2688 | aParams[ 3 ] <<= fv; | |||
2689 | aParams[ 4 ] <<= type; | |||
2690 | ||||
2691 | CallFunctionAccessFunction( aParams, "NPer", rPar.Get32( 0 ) ); | |||
2692 | } | |||
2693 | ||||
2694 | void SbRtl_MIRR(StarBASIC *, SbxArray & rPar, bool) | |||
2695 | { | |||
2696 | sal_uInt32 nArgCount = rPar.Count32()-1; | |||
2697 | ||||
2698 | if ( nArgCount < 3 ) | |||
2699 | { | |||
2700 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2701 | return; | |||
2702 | } | |||
2703 | ||||
2704 | // retrieve non-optional params | |||
2705 | ||||
2706 | Sequence< Any > aParams( 3 ); | |||
2707 | Any aValues = sbxToUnoValue( rPar.Get32(1), | |||
2708 | cppu::UnoType<Sequence<double>>::get() ); | |||
2709 | ||||
2710 | // convert for calc functions | |||
2711 | Sequence< Sequence< double > > sValues(1); | |||
2712 | aValues >>= sValues[ 0 ]; | |||
2713 | aValues <<= sValues; | |||
2714 | ||||
2715 | aParams[ 0 ] = aValues; | |||
2716 | aParams[ 1 ] <<= rPar.Get32(2)->GetDouble(); | |||
2717 | aParams[ 2 ] <<= rPar.Get32(3)->GetDouble(); | |||
2718 | ||||
2719 | CallFunctionAccessFunction( aParams, "MIRR", rPar.Get32( 0 ) ); | |||
2720 | } | |||
2721 | ||||
2722 | void SbRtl_IRR(StarBASIC *, SbxArray & rPar, bool) | |||
2723 | { | |||
2724 | sal_uInt32 nArgCount = rPar.Count32()-1; | |||
2725 | ||||
2726 | if ( nArgCount < 1 || nArgCount > 2 ) | |||
2727 | { | |||
2728 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2729 | return; | |||
2730 | } | |||
2731 | // retrieve non-optional params | |||
2732 | Any aValues = sbxToUnoValue( rPar.Get32(1), | |||
2733 | cppu::UnoType<Sequence<double>>::get() ); | |||
2734 | ||||
2735 | // convert for calc functions | |||
2736 | Sequence< Sequence< double > > sValues(1); | |||
2737 | aValues >>= sValues[ 0 ]; | |||
2738 | aValues <<= sValues; | |||
2739 | ||||
2740 | // set default values for Optional args | |||
2741 | double guess = 0.1; | |||
2742 | // guess | |||
2743 | if ( nArgCount >= 2 ) | |||
2744 | { | |||
2745 | if( rPar.Get32(2)->GetType() != SbxEMPTY ) | |||
2746 | guess = rPar.Get32(2)->GetDouble(); | |||
2747 | } | |||
2748 | ||||
2749 | Sequence< Any > aParams( 2 ); | |||
2750 | aParams[ 0 ] = aValues; | |||
2751 | aParams[ 1 ] <<= guess; | |||
2752 | ||||
2753 | CallFunctionAccessFunction( aParams, "IRR", rPar.Get32( 0 ) ); | |||
2754 | } | |||
2755 | ||||
2756 | void SbRtl_IPmt(StarBASIC *, SbxArray & rPar, bool) | |||
2757 | { | |||
2758 | sal_uInt32 nArgCount = rPar.Count32()-1; | |||
2759 | ||||
2760 | if ( nArgCount < 4 || nArgCount > 6 ) | |||
2761 | { | |||
2762 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2763 | return; | |||
2764 | } | |||
2765 | // retrieve non-optional params | |||
2766 | ||||
2767 | double rate = rPar.Get32(1)->GetDouble(); | |||
2768 | double per = rPar.Get32(2)->GetInteger(); | |||
2769 | double nper = rPar.Get32(3)->GetDouble(); | |||
2770 | double pv = rPar.Get32(4)->GetDouble(); | |||
2771 | ||||
2772 | // set default values for Optional args | |||
2773 | double fv = 0; | |||
2774 | double type = 0; | |||
2775 | ||||
2776 | // fv | |||
2777 | if ( nArgCount >= 5 ) | |||
2778 | { | |||
2779 | if( rPar.Get32(5)->GetType() != SbxEMPTY ) | |||
2780 | fv = rPar.Get32(5)->GetDouble(); | |||
2781 | } | |||
2782 | // type | |||
2783 | if ( nArgCount >= 6 ) | |||
2784 | { | |||
2785 | if( rPar.Get32(6)->GetType() != SbxEMPTY ) | |||
2786 | type = rPar.Get32(6)->GetDouble(); | |||
2787 | } | |||
2788 | ||||
2789 | Sequence< Any > aParams( 6 ); | |||
2790 | aParams[ 0 ] <<= rate; | |||
2791 | aParams[ 1 ] <<= per; | |||
2792 | aParams[ 2 ] <<= nper; | |||
2793 | aParams[ 3 ] <<= pv; | |||
2794 | aParams[ 4 ] <<= fv; | |||
2795 | aParams[ 5 ] <<= type; | |||
2796 | ||||
2797 | CallFunctionAccessFunction( aParams, "IPmt", rPar.Get32( 0 ) ); | |||
2798 | } | |||
2799 | ||||
2800 | void SbRtl_FV(StarBASIC *, SbxArray & rPar, bool) | |||
2801 | { | |||
2802 | sal_uInt32 nArgCount = rPar.Count32()-1; | |||
2803 | ||||
2804 | if ( nArgCount < 3 || nArgCount > 5 ) | |||
2805 | { | |||
2806 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2807 | return; | |||
2808 | } | |||
2809 | // retrieve non-optional params | |||
2810 | ||||
2811 | double rate = rPar.Get32(1)->GetDouble(); | |||
2812 | double nper = rPar.Get32(2)->GetDouble(); | |||
2813 | double pmt = rPar.Get32(3)->GetDouble(); | |||
2814 | ||||
2815 | // set default values for Optional args | |||
2816 | double pv = 0; | |||
2817 | double type = 0; | |||
2818 | ||||
2819 | // pv | |||
2820 | if ( nArgCount >= 4 ) | |||
2821 | { | |||
2822 | if( rPar.Get32(4)->GetType() != SbxEMPTY ) | |||
2823 | pv = rPar.Get32(4)->GetDouble(); | |||
2824 | } | |||
2825 | // type | |||
2826 | if ( nArgCount >= 5 ) | |||
2827 | { | |||
2828 | if( rPar.Get32(5)->GetType() != SbxEMPTY ) | |||
2829 | type = rPar.Get32(5)->GetDouble(); | |||
2830 | } | |||
2831 | ||||
2832 | Sequence< Any > aParams( 5 ); | |||
2833 | aParams[ 0 ] <<= rate; | |||
2834 | aParams[ 1 ] <<= nper; | |||
2835 | aParams[ 2 ] <<= pmt; | |||
2836 | aParams[ 3 ] <<= pv; | |||
2837 | aParams[ 4 ] <<= type; | |||
2838 | ||||
2839 | CallFunctionAccessFunction( aParams, "FV", rPar.Get32( 0 ) ); | |||
2840 | } | |||
2841 | ||||
2842 | void SbRtl_DDB(StarBASIC *, SbxArray & rPar, bool) | |||
2843 | { | |||
2844 | sal_uInt32 nArgCount = rPar.Count32()-1; | |||
2845 | ||||
2846 | if ( nArgCount < 4 || nArgCount > 5 ) | |||
2847 | { | |||
2848 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2849 | return; | |||
2850 | } | |||
2851 | // retrieve non-optional params | |||
2852 | ||||
2853 | double cost = rPar.Get32(1)->GetDouble(); | |||
2854 | double salvage = rPar.Get32(2)->GetDouble(); | |||
2855 | double life = rPar.Get32(3)->GetDouble(); | |||
2856 | double period = rPar.Get32(4)->GetDouble(); | |||
2857 | ||||
2858 | // set default values for Optional args | |||
2859 | double factor = 2; | |||
2860 | ||||
2861 | // factor | |||
2862 | if ( nArgCount >= 5 ) | |||
2863 | { | |||
2864 | if( rPar.Get32(5)->GetType() != SbxEMPTY ) | |||
2865 | factor = rPar.Get32(5)->GetDouble(); | |||
2866 | } | |||
2867 | ||||
2868 | Sequence< Any > aParams( 5 ); | |||
2869 | aParams[ 0 ] <<= cost; | |||
2870 | aParams[ 1 ] <<= salvage; | |||
2871 | aParams[ 2 ] <<= life; | |||
2872 | aParams[ 3 ] <<= period; | |||
2873 | aParams[ 4 ] <<= factor; | |||
2874 | ||||
2875 | CallFunctionAccessFunction( aParams, "DDB", rPar.Get32( 0 ) ); | |||
2876 | } | |||
2877 | ||||
2878 | void SbRtl_Rate(StarBASIC *, SbxArray & rPar, bool) | |||
2879 | { | |||
2880 | sal_uInt32 nArgCount = rPar.Count32()-1; | |||
2881 | ||||
2882 | if ( nArgCount < 3 || nArgCount > 6 ) | |||
2883 | { | |||
2884 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2885 | return; | |||
2886 | } | |||
2887 | // retrieve non-optional params | |||
2888 | ||||
2889 | double nper = 0; | |||
2890 | double pmt = 0; | |||
2891 | double pv = 0; | |||
2892 | ||||
2893 | nper = rPar.Get32(1)->GetDouble(); | |||
2894 | pmt = rPar.Get32(2)->GetDouble(); | |||
2895 | pv = rPar.Get32(3)->GetDouble(); | |||
2896 | ||||
2897 | // set default values for Optional args | |||
2898 | double fv = 0; | |||
2899 | double type = 0; | |||
2900 | double guess = 0.1; | |||
2901 | ||||
2902 | // fv | |||
2903 | if ( nArgCount >= 4 ) | |||
2904 | { | |||
2905 | if( rPar.Get32(4)->GetType() != SbxEMPTY ) | |||
2906 | fv = rPar.Get32(4)->GetDouble(); | |||
2907 | } | |||
2908 | ||||
2909 | // type | |||
2910 | if ( nArgCount >= 5 ) | |||
2911 | { | |||
2912 | if( rPar.Get32(5)->GetType() != SbxEMPTY ) | |||
2913 | type = rPar.Get32(5)->GetDouble(); | |||
2914 | } | |||
2915 | ||||
2916 | // guess | |||
2917 | if ( nArgCount >= 6 ) | |||
2918 | { | |||
2919 | if( rPar.Get32(6)->GetType() != SbxEMPTY ) | |||
2920 | guess = rPar.Get32(6)->GetDouble(); | |||
2921 | } | |||
2922 | ||||
2923 | Sequence< Any > aParams( 6 ); | |||
2924 | aParams[ 0 ] <<= nper; | |||
2925 | aParams[ 1 ] <<= pmt; | |||
2926 | aParams[ 2 ] <<= pv; | |||
2927 | aParams[ 3 ] <<= fv; | |||
2928 | aParams[ 4 ] <<= type; | |||
2929 | aParams[ 5 ] <<= guess; | |||
2930 | ||||
2931 | CallFunctionAccessFunction( aParams, "Rate", rPar.Get32( 0 ) ); | |||
2932 | } | |||
2933 | ||||
2934 | void SbRtl_StrReverse(StarBASIC *, SbxArray & rPar, bool) | |||
2935 | { | |||
2936 | if ( rPar.Count32() != 2 ) | |||
2937 | { | |||
2938 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2939 | return; | |||
2940 | } | |||
2941 | ||||
2942 | SbxVariable *pSbxVariable = rPar.Get32(1); | |||
2943 | if( pSbxVariable->IsNull() ) | |||
2944 | { | |||
2945 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2946 | return; | |||
2947 | } | |||
2948 | ||||
2949 | OUString aStr = comphelper::string::reverseString(pSbxVariable->GetOUString()); | |||
2950 | rPar.Get32(0)->PutString( aStr ); | |||
2951 | } | |||
2952 | ||||
2953 | void SbRtl_CompatibilityMode(StarBASIC *, SbxArray & rPar, bool) | |||
2954 | { | |||
2955 | bool bEnabled = false; | |||
2956 | sal_uInt32 nCount = rPar.Count32(); | |||
2957 | if ( nCount != 1 && nCount != 2 ) | |||
2958 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2959 | ||||
2960 | SbiInstance* pInst = GetSbData()->pInst; | |||
2961 | if( pInst ) | |||
2962 | { | |||
2963 | if ( nCount == 2 ) | |||
2964 | { | |||
2965 | pInst->EnableCompatibility( rPar.Get32(1)->GetBool() ); | |||
2966 | } | |||
2967 | bEnabled = pInst->IsCompatibility(); | |||
2968 | } | |||
2969 | rPar.Get32(0)->PutBool( bEnabled ); | |||
2970 | } | |||
2971 | ||||
2972 | void SbRtl_Input(StarBASIC *, SbxArray & rPar, bool) | |||
2973 | { | |||
2974 | // 2 parameters needed | |||
2975 | if ( rPar.Count32() < 3 ) | |||
2976 | { | |||
2977 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
2978 | return; | |||
2979 | } | |||
2980 | ||||
2981 | sal_uInt16 nByteCount = rPar.Get32(1)->GetUShort(); | |||
2982 | sal_Int16 nFileNumber = rPar.Get32(2)->GetInteger(); | |||
2983 | ||||
2984 | SbiIoSystem* pIosys = GetSbData()->pInst->GetIoSystem(); | |||
2985 | SbiStream* pSbStrm = pIosys->GetStream( nFileNumber ); | |||
2986 | if ( !pSbStrm || !(pSbStrm->GetMode() & (SbiStreamFlags::Binary | SbiStreamFlags::Input)) ) | |||
2987 | { | |||
2988 | StarBASIC::Error( ERRCODE_BASIC_BAD_CHANNELErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 41 ) ); | |||
2989 | return; | |||
2990 | } | |||
2991 | ||||
2992 | OString aByteBuffer; | |||
2993 | ErrCode err = pSbStrm->Read( aByteBuffer, nByteCount, true ); | |||
2994 | if( !err ) | |||
2995 | err = pIosys->GetError(); | |||
2996 | ||||
2997 | if( err ) | |||
2998 | { | |||
2999 | StarBASIC::Error( err ); | |||
3000 | return; | |||
3001 | } | |||
3002 | rPar.Get32(0)->PutString(OStringToOUString(aByteBuffer, osl_getThreadTextEncoding())); | |||
3003 | } | |||
3004 | ||||
3005 | void SbRtl_Me(StarBASIC *, SbxArray & rPar, bool) | |||
3006 | { | |||
3007 | SbModule* pActiveModule = GetSbData()->pInst->GetActiveModule(); | |||
3008 | SbClassModuleObject* pClassModuleObject = dynamic_cast<SbClassModuleObject*>( pActiveModule ); | |||
3009 | SbxVariableRef refVar = rPar.Get32(0); | |||
3010 | if( pClassModuleObject == nullptr ) | |||
3011 | { | |||
3012 | SbObjModule* pMod = dynamic_cast<SbObjModule*>( pActiveModule ); | |||
3013 | if ( pMod ) | |||
3014 | refVar->PutObject( pMod ); | |||
3015 | else | |||
3016 | StarBASIC::Error( ERRCODE_BASIC_INVALID_USAGE_OBJECTErrCode( ErrCodeArea::Sbx, ErrCodeClass::Access, 19) ); | |||
3017 | } | |||
3018 | else | |||
3019 | refVar->PutObject( pClassModuleObject ); | |||
3020 | } | |||
3021 | ||||
3022 | #endif | |||
3023 | ||||
3024 | sal_Int16 implGetWeekDay( double aDate, bool bFirstDayParam, sal_Int16 nFirstDay ) | |||
3025 | { | |||
3026 | Date aRefDate( 1,1,1900 ); | |||
3027 | sal_Int32 nDays = static_cast<sal_Int32>(aDate); | |||
3028 | nDays -= 2; // normalize: 1.1.1900 => 0 | |||
3029 | aRefDate.AddDays( nDays); | |||
3030 | DayOfWeek aDay = aRefDate.GetDayOfWeek(); | |||
3031 | sal_Int16 nDay; | |||
3032 | if ( aDay != SUNDAY ) | |||
3033 | nDay = static_cast<sal_Int16>(aDay) + 2; | |||
3034 | else | |||
3035 | nDay = 1; // 1 == Sunday | |||
3036 | ||||
3037 | // #117253 optional 2nd parameter "firstdayofweek" | |||
3038 | if( bFirstDayParam ) | |||
3039 | { | |||
3040 | if( nFirstDay < 0 || nFirstDay > 7 ) | |||
3041 | { | |||
3042 | #if HAVE_FEATURE_SCRIPTING1 | |||
3043 | StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENTErrCode( ErrCodeArea::Sbx, ErrCodeClass::NotSupported, 2) ); | |||
3044 | #endif | |||
3045 | return 0; | |||
3046 | } | |||
3047 | if( nFirstDay == 0 ) | |||
3048 | { | |||
3049 | const Reference< XCalendar4 >& xCalendar = getLocaleCalendar(); | |||
3050 | if( !xCalendar.is() ) | |||
3051 | { | |||
3052 | #if HAVE_FEATURE_SCRIPTING1 | |||
3053 | StarBASIC::Error( ERRCODE_BASIC_INTERNAL_ERRORErrCode( ErrCodeArea::Sbx, ErrCodeClass::Unknown, 9) ); | |||
3054 | #endif | |||
3055 | return 0; | |||
3056 | } | |||
3057 | nFirstDay = sal_Int16( xCalendar->getFirstDayOfWeek() + 1 ); | |||
3058 | } | |||
3059 | nDay = 1 + (nDay + 7 - nFirstDay) % 7; | |||
3060 | } | |||
3061 | return nDay; | |||
3062 | } | |||
3063 | ||||
3064 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |