tdf#154285 Check upper bound of arguments in SbRtl_Minute function
[LibreOffice.git] / wizards / source / scriptforge / SF_PythonHelper.xba
blobbeb0d16f1306eb16734af583f7351835fbfb4c6f
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
3 <script:module xmlns:script="http://openoffice.org/2000/script" script:name="SF_PythonHelper" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
4 REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
5 REM === Full documentation is available on https://help.libreoffice.org/ ===
6 REM =======================================================================================================================
8 Option Compatible
9 Option Explicit
11 &apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
12 &apos;&apos;&apos; SF_PythonHelper (aka Basic)
13 &apos;&apos;&apos; ===============
14 &apos;&apos;&apos; Singleton class implementing the &quot;ScriptForge.Basic&quot; service
15 &apos;&apos;&apos; Implemented as a usual Basic module
16 &apos;&apos;&apos;
17 &apos;&apos;&apos; The &quot;Basic&quot; service must be called ONLY from a PYTHON script
18 &apos;&apos;&apos; Service invocations: Next Python code lines are equivalent:
19 &apos;&apos;&apos; bas = CreateScriptService(&apos;ScriptForge.Basic&apos;)
20 &apos;&apos;&apos; bas = CreateScriptService(&apos;Basic&apos;)
21 &apos;&apos;&apos;
22 &apos;&apos;&apos; This service proposes a collection of methods to be executed in a Python context
23 &apos;&apos;&apos; to simulate the exact behaviour of the identical Basic builtin method.
24 &apos;&apos;&apos; Typical example:
25 &apos;&apos;&apos; bas.MsgBox(&apos;This has to be displayed in a message box&apos;)
26 &apos;&apos;&apos;
27 &apos;&apos;&apos; The service includes also an agnostic &quot;Python Dispatcher&quot; function.
28 &apos;&apos;&apos; It dispatches Python script requests to execute Basic services to the
29 &apos;&apos;&apos; appropriate properties and methods via dynamic call techniques
30 &apos;&apos;&apos;
31 &apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
33 REM ================================================================== EXCEPTIONS
35 REM ============================================================ MODULE CONSTANTS
37 REM ===================================================== CONSTRUCTOR/DESTRUCTOR
39 REM -----------------------------------------------------------------------------
40 Public Function Dispose() As Variant
41 Set Dispose = Nothing
42 End Function &apos; ScriptForge.SF_PythonHelper Explicit destructor
44 REM ================================================================== PROPERTIES
46 REM -----------------------------------------------------------------------------
47 Property Get ObjectType As String
48 &apos;&apos;&apos; Only to enable object representation
49 ObjectType = &quot;SF_PythonHelper&quot;
50 End Property &apos; ScriptForge.SF_PythonHelper.ObjectType
52 REM -----------------------------------------------------------------------------
53 Property Get ServiceName As String
54 &apos;&apos;&apos; Internal use
55 ServiceName = &quot;ScriptForge.Basic&quot;
56 End Property &apos; ScriptForge.SF_PythonHelper.ServiceName
58 REM ============================================================== PUBLIC METHODS
60 REM -----------------------------------------------------------------------------
61 Public Function PyCDate(ByVal DateArg As Variant) As Variant
62 &apos;&apos;&apos; Convenient function to replicate CDate() in Python scripts
63 &apos;&apos;&apos; Args:
64 &apos;&apos;&apos; DateArg: a date as a string or as a double
65 &apos;&apos;&apos; Returns:
66 &apos;&apos;&apos; The converted date as a UNO DateTime structure
67 &apos;&apos;&apos; If the input argument could not be recognized as a date, return the argument unchanged
68 &apos;&apos;&apos; Example: (Python code)
69 &apos;&apos;&apos; a = bas.CDate(&apos;2021-02-18&apos;)
71 Dim vDate As Variant &apos; Return value
72 Const cstThisSub = &quot;Basic.CDate&quot;
73 Const cstSubArgs = &quot;datearg&quot;
75 On Local Error GoTo Catch
76 vDate = Null
78 Check:
79 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
81 Try:
82 vDate = CDate(DateArg)
84 Finally:
85 If VarType(vDate) = V_DATE Then PyCDate = CDateToUnoDateTime(vDate) Else PyCDate = DateArg
86 SF_Utils._ExitFunction(cstThisSub)
87 Exit Function
88 Catch:
89 On Local Error GoTo 0
90 GoTo Finally
91 End Function &apos; ScriptForge.SF_PythonHelper.PyCDate
93 REM -----------------------------------------------------------------------------
94 Public Function PyConvertFromUrl(ByVal FileName As Variant) As String
95 &apos;&apos;&apos; Convenient function to replicate ConvertFromUrl() in Python scripts
96 &apos;&apos;&apos; Args:
97 &apos;&apos;&apos; FileName: a string representing a file in URL format
98 &apos;&apos;&apos; Returns:
99 &apos;&apos;&apos; The same file name in native operating system notation
100 &apos;&apos;&apos; Example: (Python code)
101 &apos;&apos;&apos; a = bas.ConvertFromUrl(&apos;file:////boot.sys&apos;)
103 Dim sFileName As String &apos; Return value
104 Const cstThisSub = &quot;Basic.ConvertFromUrl&quot;
105 Const cstSubArgs = &quot;filename&quot;
107 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
108 sFileName = &quot;&quot;
110 Check:
111 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
113 Try:
114 sFileName = ConvertFromUrl(FileName)
116 Finally:
117 PyConvertFromUrl = sFileName
118 SF_Utils._ExitFunction(cstThisSub)
119 Exit Function
120 Catch:
121 GoTo Finally
122 End Function &apos; ScriptForge.SF_PythonHelper.PyConvertFromUrl
124 REM -----------------------------------------------------------------------------
125 Public Function PyConvertToUrl(ByVal FileName As Variant) As String
126 &apos;&apos;&apos; Convenient function to replicate ConvertToUrl() in Python scripts
127 &apos;&apos;&apos; Args:
128 &apos;&apos;&apos; FileName: a string representing a file in native operating system notation
129 &apos;&apos;&apos; Returns:
130 &apos;&apos;&apos; The same file name in URL format
131 &apos;&apos;&apos; Example: (Python code)
132 &apos;&apos;&apos; a = bas.ConvertToUrl(&apos;C:\boot.sys&apos;)
134 Dim sFileName As String &apos; Return value
135 Const cstThisSub = &quot;Basic.ConvertToUrl&quot;
136 Const cstSubArgs = &quot;filename&quot;
138 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
139 sFileName = &quot;&quot;
141 Check:
142 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
144 Try:
145 sFileName = ConvertToUrl(FileName)
147 Finally:
148 PyConvertToUrl = sFileName
149 SF_Utils._ExitFunction(cstThisSub)
150 Exit Function
151 Catch:
152 GoTo Finally
153 End Function &apos; ScriptForge.SF_PythonHelper.PyConvertToUrl
155 REM -----------------------------------------------------------------------------
156 Public Function PyCreateUnoService(ByVal UnoService As Variant) As Variant
157 &apos;&apos;&apos; Convenient function to replicate CreateUnoService() in Python scripts
158 &apos;&apos;&apos; Args:
159 &apos;&apos;&apos; UnoService: a string representing the service to create
160 &apos;&apos;&apos; Returns:
161 &apos;&apos;&apos; A UNO object
162 &apos;&apos;&apos; Example: (Python code)
163 &apos;&apos;&apos; a = bas.CreateUnoService(&apos;com.sun.star.i18n.CharacterClassification&apos;)
165 Dim vUno As Variant &apos; Return value
166 Const cstThisSub = &quot;Basic.CreateUnoService&quot;
167 Const cstSubArgs = &quot;unoservice&quot;
169 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
170 Set vUno = Nothing
172 Check:
173 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
175 Try:
176 Set vUno = CreateUnoService(UnoService)
178 Finally:
179 Set PyCreateUnoService = vUno
180 SF_Utils._ExitFunction(cstThisSub)
181 Exit Function
182 Catch:
183 GoTo Finally
184 End Function &apos; ScriptForge.SF_PythonHelper.PyCreateUnoService
186 REM -----------------------------------------------------------------------------
187 Public Function PyDateAdd(ByVal Add As Variant _
188 , ByVal Count As Variant _
189 , ByVal DateArg As Variant _
190 ) As Variant
191 &apos;&apos;&apos; Convenient function to replicate DateAdd() in Python scripts
192 &apos;&apos;&apos; Args:
193 &apos;&apos;&apos; Add: The unit to add
194 &apos;&apos;&apos; Count: how many times to add (might be negative)
195 &apos;&apos;&apos; DateArg: a date as a com.sun.star.util.DateTime UNO structure
196 &apos;&apos;&apos; Returns:
197 &apos;&apos;&apos; The new date as a string in iso format
198 &apos;&apos;&apos; Example: (Python code)
199 &apos;&apos;&apos; a = bas.DateAdd(&apos;d&apos;, 1, bas.Now()) &apos; Tomorrow
201 Dim vNewDate As Variant &apos; Return value
202 Dim vDate As Date &apos; Alias of DateArg
203 Const cstThisSub = &quot;Basic.DateAdd&quot;
204 Const cstSubArgs = &quot;add, count, datearg&quot;
206 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
207 vNewDate = &quot;&quot;
209 Check:
210 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
212 Try:
213 If VarType(DateArg) = V_OBJECT Then
214 vDate = CDateFromUnoDateTime(DateArg)
215 Else
216 vDate = SF_Utils._CStrToDate(DateArg)
217 End If
218 vNewDate = DateAdd(Add, Count, vDate)
220 Finally:
221 If VarType(vNewDate) = V_DATE Then PyDateAdd = CDateToUnoDateTime(vNewDate) Else PyDateAdd = vNewDate
222 SF_Utils._ExitFunction(cstThisSub)
223 Exit Function
224 Catch:
225 GoTo Finally
226 End Function &apos; ScriptForge.SF_PythonHelper.PyDateAdd
228 REM -----------------------------------------------------------------------------
229 Public Function PyDateDiff(ByVal Add As Variant _
230 , ByVal Date1 As Variant _
231 , ByVal Date2 As Variant _
232 , ByVal WeekStart As Variant _
233 , ByVal YearStart As Variant _
234 ) As Long
235 &apos;&apos;&apos; Convenient function to replicate DateDiff() in Python scripts
236 &apos;&apos;&apos; Args:
237 &apos;&apos;&apos; Add: The unit of the date interval
238 &apos;&apos;&apos; Date1, Date2: the two dates to be compared
239 &apos;&apos;&apos; WeekStart: the starting day of a week
240 &apos;&apos;&apos; YearStart: the starting week of a year
241 &apos;&apos;&apos; Returns:
242 &apos;&apos;&apos; The number of intervals expressed in Adds
243 &apos;&apos;&apos; Example: (Python code)
244 &apos;&apos;&apos; a = bas.DateDiff(&apos;d&apos;, bas.DateAdd(&apos;d&apos;, 1, bas.Now()), bas.Now()) &apos; -1 day
246 Dim lDiff As Long &apos; Return value
247 Dim vDate1 As Date &apos; Alias of Date1
248 Dim vDate2 As Date &apos; Alias of Date2
249 Const cstThisSub = &quot;Basic.DateDiff&quot;
250 Const cstSubArgs = &quot;add, date1, date2, [weekstart=1], [yearstart=1]&quot;
252 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
253 lDiff = 0
255 Check:
256 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
258 Try:
259 If VarType(Date1) = V_OBJECT Then
260 vDate1 = CDateFromUnoDateTime(Date1)
261 Else
262 vDate1 = SF_Utils._CStrToDate(Date1)
263 End If
264 If VarType(Date2) = V_OBJECT Then
265 vDate2 = CDateFromUnoDateTime(Date2)
266 Else
267 vDate2 = SF_Utils._CStrToDate(Date2)
268 End If
269 lDiff = DateDiff(Add, vDate1, vDate2, WeekStart, YearStart)
272 Finally:
273 PyDateDiff = lDiff
274 SF_Utils._ExitFunction(cstThisSub)
275 Exit Function
276 Catch:
277 GoTo Finally
278 End Function &apos; ScriptForge.SF_PythonHelper.PyDateDiff
280 REM -----------------------------------------------------------------------------
281 Public Function PyDatePart(ByVal Add As Variant _
282 , ByVal DateArg As Variant _
283 , ByVal WeekStart As Variant _
284 , ByVal YearStart As Variant _
285 ) As Long
286 &apos;&apos;&apos; Convenient function to replicate DatePart() in Python scripts
287 &apos;&apos;&apos; Args:
288 &apos;&apos;&apos; Add: The unit of the date interval
289 &apos;&apos;&apos; DateArg: The date from which to extract a part
290 &apos;&apos;&apos; WeekStart: the starting day of a week
291 &apos;&apos;&apos; YearStart: the starting week of a year
292 &apos;&apos;&apos; Returns:
293 &apos;&apos;&apos; The specified part of the date
294 &apos;&apos;&apos; Example: (Python code)
295 &apos;&apos;&apos; a = bas.DatePart(&apos;y&apos;, bas.Now()) &apos; day of year
297 Dim lPart As Long &apos; Return value
298 Dim vDate As Date &apos; Alias of DateArg
299 Const cstThisSub = &quot;Basic.DatePart&quot;
300 Const cstSubArgs = &quot;add, datearg, [weekstart=1], [yearstart=1]&quot;
302 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
303 lPart = 0
305 Check:
306 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
308 Try:
309 If VarType(DateArg) = V_OBJECT Then
310 vDate = CDateFromUnoDateTime(DateArg)
311 Else
312 vDate = SF_Utils._CStrToDate(DateArg)
313 End If
314 lPart = DatePart(Add, vDate, WeekStart, YearStart)
317 Finally:
318 PyDatePart = lPart
319 SF_Utils._ExitFunction(cstThisSub)
320 Exit Function
321 Catch:
322 GoTo Finally
323 End Function &apos; ScriptForge.SF_PythonHelper.PyDatePart
325 REM -----------------------------------------------------------------------------
326 Public Function PyDateValue(ByVal DateArg As Variant) As Variant
327 &apos;&apos;&apos; Convenient function to replicate DateValue() in Python scripts
328 &apos;&apos;&apos; Args:
329 &apos;&apos;&apos; DateArg: a date as a string
330 &apos;&apos;&apos; Returns:
331 &apos;&apos;&apos; The converted date as a UNO DateTime structure
332 &apos;&apos;&apos; Example: (Python code)
333 &apos;&apos;&apos; a = bas.DateValue(&apos;2021-02-18&apos;)
335 Dim vDate As Variant &apos; Return value
336 Const cstThisSub = &quot;Basic.DateValue&quot;
337 Const cstSubArgs = &quot;datearg&quot;
339 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
340 vDate = &quot;&quot;
342 Check:
343 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
345 Try:
346 vDate = DateValue(DateArg)
348 Finally:
349 If VarType(vDate) = V_DATE Then PyDateValue = CDateToUnoDateTime(vDate) Else PyDateValue = vDate
350 SF_Utils._ExitFunction(cstThisSub)
351 Exit Function
352 Catch:
353 GoTo Finally
354 End Function &apos; ScriptForge.SF_PythonHelper.PyDateValue
356 REM -----------------------------------------------------------------------------
357 Public Function PyFormat(ByVal Value As Variant _
358 , ByVal Pattern As Variant _
359 ) As String
360 &apos;&apos;&apos; Convenient function to replicate Format() in Python scripts
361 &apos;&apos;&apos; Args:
362 &apos;&apos;&apos; Value: a date or a number
363 &apos;&apos;&apos; Pattern: the format to apply
364 &apos;&apos;&apos; Returns:
365 &apos;&apos;&apos; The formatted value
366 &apos;&apos;&apos; Example: (Python code)
367 &apos;&apos;&apos; MsgBox bas.Format(6328.2, &apos;##,##0.00&apos;)
369 Dim sFormat As String &apos; Return value
370 Dim vValue As Variant &apos; Alias of Value
371 Const cstThisSub = &quot;Basic.Format&quot;
372 Const cstSubArgs = &quot;value, pattern&quot;
374 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
375 sFormat = &quot;&quot;
377 Check:
378 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
380 Try:
381 If VarType(Value) = V_OBJECT Then vValue = CDateFromUnoDateTime(Value) ELse vValue = Value
382 If IsEmpty(Pattern) Or Len(Pattern) = 0 Then sFormat = Str(vValue) Else sFormat = Format(vValue, Pattern)
385 Finally:
386 PyFormat = sFormat
387 SF_Utils._ExitFunction(cstThisSub)
388 Exit Function
389 Catch:
390 GoTo Finally
391 End Function &apos; ScriptForge.SF_PythonHelper.PyFormat
393 REM -----------------------------------------------------------------------------
394 Public Function PyGetGuiType() As Integer
395 &apos;&apos;&apos; Convenient function to replicate GetGuiType() in Python scripts
396 &apos;&apos;&apos; Args:
397 &apos;&apos;&apos; Returns:
398 &apos;&apos;&apos; The GetGuiType value
399 &apos;&apos;&apos; Example: (Python code)
400 &apos;&apos;&apos; MsgBox bas.GetGuiType()
402 Const cstThisSub = &quot;Basic.GetGuiType&quot;
403 Const cstSubArgs = &quot;&quot;
405 Check:
406 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
408 Try:
409 PyGetGuiType = GetGuiType()
412 Finally:
413 SF_Utils._ExitFunction(cstThisSub)
414 Exit Function
415 End Function &apos; ScriptForge.SF_PythonHelper.PyGetGuiType
417 REM -----------------------------------------------------------------------------
418 Public Function PyGetSystemTicks() As Long
419 &apos;&apos;&apos; Convenient function to replicate GetSystemTicks() in Python scripts
420 &apos;&apos;&apos; Args:
421 &apos;&apos;&apos; Returns:
422 &apos;&apos;&apos; The GetSystemTicks value
423 &apos;&apos;&apos; Example: (Python code)
424 &apos;&apos;&apos; MsgBox bas.GetSystemTicks()
426 Const cstThisSub = &quot;Basic.GetSystemTicks&quot;
427 Const cstSubArgs = &quot;&quot;
429 Check:
430 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
432 Try:
433 PyGetSystemTicks = GetSystemTicks()
436 Finally:
437 SF_Utils._ExitFunction(cstThisSub)
438 Exit Function
439 End Function &apos; ScriptForge.SF_PythonHelper.PyGetSystemTicks
441 REM -----------------------------------------------------------------------------
442 Public Function PyGlobalScope(ByVal Library As Variant) As Object
443 &apos;&apos;&apos; Convenient function to replicate GlobalScope() in Python scripts
444 &apos;&apos;&apos; Args:
445 &apos;&apos;&apos; Library: &quot;Basic&quot; or &quot;Dialog&quot;
446 &apos;&apos;&apos; Returns:
447 &apos;&apos;&apos; The GlobalScope value
448 &apos;&apos;&apos; Example: (Python code)
449 &apos;&apos;&apos; MsgBox bas.GlobalScope.BasicLibraries()
451 Const cstThisSub = &quot;Basic.GlobalScope.BasicLibraries&quot; &apos; or DialogLibraries
452 Const cstSubArgs = &quot;&quot;
454 Check:
455 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
457 Try:
458 Select Case Library
459 Case &quot;Basic&quot;
460 PyGlobalScope = GlobalScope.BasicLibraries()
461 Case &quot;Dialog&quot;
462 PyGlobalScope = GlobalScope.DialogLibraries()
463 Case Else
464 End Select
466 Finally:
467 SF_Utils._ExitFunction(cstThisSub)
468 Exit Function
469 End Function &apos; ScriptForge.SF_PythonHelper.PyGlobalScope
471 REM -----------------------------------------------------------------------------
472 Public Function PyInputBox(ByVal Msg As Variant _
473 , ByVal Title As Variant _
474 , ByVal Default As Variant _
475 , Optional ByVal XPosTwips As Variant _
476 , Optional ByVal YPosTwips As Variant _
477 ) As String
478 &apos;&apos;&apos; Convenient function to replicate InputBox() in Python scripts
479 &apos;&apos;&apos; Args:
480 &apos;&apos;&apos; Msg: String expression displayed as the message in the dialog box
481 &apos;&apos;&apos; Title: String expression displayed in the title bar of the dialog box
482 &apos;&apos;&apos; Default: String expression displayed in the text box as default if no other input is given
483 &apos;&apos;&apos; XPosTwips: Integer expression that specifies the horizontal position of the dialog
484 &apos;&apos;&apos; YPosTwips: Integer expression that specifies the vertical position of the dialog
485 &apos;&apos;&apos; If XPosTwips and YPosTwips are omitted, the dialog is centered on the screen
486 &apos;&apos;&apos; The position is specified in twips.
487 &apos;&apos;&apos; Returns:
488 &apos;&apos;&apos; The entered value or &quot;&quot; if the user pressed the Cancel button
489 &apos;&apos;&apos; Example: (Python code)
490 &apos;&apos;&apos; a = bas.InputBox (&apos;Please enter a phrase:&apos;, &apos;Dear User&apos;)
492 Dim sInput As String &apos; Return value
493 Const cstThisSub = &quot;Basic.InputBox&quot;
494 Const cstSubArgs = &quot;msg, [title=&apos;&apos;], [default=&apos;&apos;], [xpostwips], [ypostwips]&quot;
496 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
497 sInput = &quot;&quot;
499 Check:
500 If IsMissing(YPosTwips) Then YPosTwips = 1
501 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
503 Try:
504 If IsMissing(XPosTwips) Then
505 sInput = InputBox(Msg, Title, Default)
506 Else
507 sInput = InputBox(Msg, Title, Default, XPosTwips, YPosTwips)
508 End If
510 Finally:
511 PyInputBox = sInput
512 SF_Utils._ExitFunction(cstThisSub)
513 Exit Function
514 Catch:
515 GoTo Finally
516 End Function &apos; ScriptForge.SF_PythonHelper.PyInputBox
518 REM -----------------------------------------------------------------------------
519 Public Function PyMsgBox(ByVal Text As Variant _
520 , ByVal DialogType As Variant _
521 , ByVal DialogTitle As Variant _
522 ) As Integer
523 &apos;&apos;&apos; Convenient function to replicate MsgBox() in Python scripts
524 &apos;&apos;&apos; Args:
525 &apos;&apos;&apos; Text: String expression displayed as a message in the dialog box
526 &apos;&apos;&apos; DialogType: Any integer expression that defines the number and type of buttons or icons displayed
527 &apos;&apos;&apos; DialogTitle: String expression displayed in the title bar of the dialog
528 &apos;&apos;&apos; Returns:
529 &apos;&apos;&apos; The pressed button
530 &apos;&apos;&apos; Example: (Python code)
531 &apos;&apos;&apos; a = bas.MsgBox (&apos;Please press a button:&apos;, bas.MB_EXCLAMATION, &apos;Dear User&apos;)
533 Dim iMsg As Integer &apos; Return value
534 Const cstThisSub = &quot;Basic.MsgBox&quot;
535 Const cstSubArgs = &quot;text, [dialogtype=0], [dialogtitle]&quot;
537 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
538 iMsg = -1
540 Check:
541 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
543 Try:
544 iMsg = MsgBox(Text, DialogType, DialogTitle)
546 Finally:
547 PyMsgBox = iMsg
548 SF_Utils._ExitFunction(cstThisSub)
549 Exit Function
550 Catch:
551 GoTo Finally
552 End Function &apos; ScriptForge.SF_PythonHelper.PyMsgBox
554 REM ============================================================= PRIVATE METHODS
556 REM -----------------------------------------------------------------------------
557 Public Function _PythonDispatcher(ByRef BasicObject As Variant _
558 , ByVal CallType As Variant _
559 , ByVal Script As Variant _
560 , ParamArray Args() As Variant _
561 ) As Variant
562 &apos;&apos;&apos; Called from Python only
563 &apos;&apos;&apos; The method calls the method Script associated with the BasicObject class or module
564 &apos;&apos;&apos; with the given arguments
565 &apos;&apos;&apos; The invocation of the method can be a Property Get, Property Let or a usual call
566 &apos;&apos;&apos; NB: arguments and return values must not be 2D arrays
567 &apos;&apos;&apos; The implementation intends to be as AGNOSTIC as possible in terms of objects nature and methods called
568 &apos;&apos;&apos; The method returns the value effectively returned by the called component,
569 &apos;&apos;&apos; completed with additional metadata. The whole is packaged in a 1D array.
570 &apos;&apos;&apos; Args:
571 &apos;&apos;&apos; BasicObject: a module or a class instance - May also be the reserved string: &quot;SF_Services&quot;
572 &apos;&apos;&apos; CallType: one of the constants applicable to a CallByName statement + optional protocol flags
573 &apos;&apos;&apos; Script: the name of the method or property
574 &apos;&apos;&apos; Args: the arguments to pass to the method. Input arguments can contain symbolic constants for Null, Missing, etc.
575 &apos;&apos;&apos; Returns:
576 &apos;&apos;&apos; A 1D array:
577 &apos;&apos;&apos; [0] The returned value - scalar, object or 1D array
578 &apos;&apos;&apos; [1] The VarType() of the returned value
579 &apos;&apos;&apos; Null, Empty and Nothing have different vartypes but return all None to Python
580 &apos;&apos;&apos; Additionally, when array:
581 &apos;&apos;&apos; [2] Number of dimensions in Basic
582 &apos;&apos;&apos; Additionally, when Basic object:
583 &apos;&apos;&apos; [2] Module (1), Class instance (2) or UNO (3)
584 &apos;&apos;&apos; [3] The object&apos;s ObjectType
585 &apos;&apos;&apos; [4] The object&apos;s service name
586 &apos;&apos;&apos; [5] The object&apos;s name
587 &apos;&apos;&apos; When an error occurs Python receives None as a scalar. This determines the occurrence of a failure
589 Dim vReturn As Variant &apos; The value returned by the invoked property or method
590 Dim vReturnArray As Variant &apos; Return value
591 Dim vBasicObject As Variant &apos; Alias of BasicObject to avoid &quot;Object reference not set&quot; error
592 Dim iNbArgs As Integer &apos; Number of valid input arguments
593 Dim vArg As Variant &apos; Alias for a single argument
594 Dim vArgs() As Variant &apos; Alias for Args()
595 Dim sScript As String &apos; Argument of ExecuteBasicScript()
596 Dim vParams As Variant &apos; Array of arguments to pass to a ParamArray
597 Dim sObjectType As String &apos; Alias of object.ObjectType
598 Dim sServiceName As String &apos; Alias of BasicObject.ServiceName
599 Dim bBasicClass As Boolean &apos; True when BasicObject is a class
600 Dim sLibrary As String &apos; Library where the object belongs to
601 Dim bUno As Boolean &apos; Return value is a UNO object
602 Dim bDict As Boolean &apos; Return value is a Basic SF_Dictionary class instance
603 Dim oDict As Object &apos; SF_Dictionary class instance
604 Dim oObjDesc As Object &apos; _ObjectDescriptor type
605 Dim iDims As Integer &apos; # of dims of vReturn when array
606 Dim sess As Object : Set sess = ScriptForge.SF_Session
607 Dim i As Long, j As Long
609 &apos; Conventional special input or output values
610 Const cstNoArgs = &quot;+++NOARGS+++&quot;, cstSymEmpty = &quot;+++EMPTY+++&quot;, cstSymNull = &quot;+++NULL+++&quot;, cstSymMissing = &quot;+++MISSING+++&quot;
612 &apos; https://support.office.com/en-us/article/CallByName-fonction-49ce9475-c315-4f13-8d35-e98cfe98729a
613 &apos; Determines the CallType
614 Const vbGet = 2, vbLet = 4, vbMethod = 1, vbSet = 8
615 &apos; Protocol flags
616 Const cstPost = 16 &apos; Requires a hardcoded post-processing
617 Const cstDictArg = 32 &apos; May contain a Dictionary argument
618 Const cstDateArg = 64 &apos; May contain a date argument
619 Const cstDateRet = 128 &apos; Return value can be a date
620 Const cstUno = 256 &apos; Return value can be a UNO object
621 Const cstArgArray = 512 &apos; Any argument can be a 2D array
622 Const cstRetArray = 1024 &apos; Return value can be an array
623 Const cstObject = 2048 &apos; 1st argument is a Basic object when numeric
624 Const cstHardCode = 4096 &apos; Method must not be executed with CallByName()
625 &apos; Returned object nature
626 Const objMODULE = 1, objCLASS = 2, objDICT = 3, objUNO = 4
628 Check:
629 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
630 _PythonDispatcher = Null
632 &apos; Ignore Null basic objects (Null = Null or Nothing)
633 If IsNull(BasicObject) Or IsEmpty(BasicObject) Then GoTo Catch
635 &apos; Reinterpret arguments one by one into vArgs
636 &apos; - convert UNO dates/times
637 &apos; - identify conventional NoArgs/Empty/Null/Missing constants
638 &apos; - convert arrays of property values into Dictionary
639 iNbArgs = -1
640 vArgs = Array()
642 If UBound(Args) &gt;= 0 Then
643 For i = 0 To UBound(Args)
644 vArg = Args(i)
645 &apos; Are there arguments ?
646 If i = 0 And VarType(vArg) = V_STRING Then
647 If vArg = cstNoArgs Then Exit For
648 End If
649 &apos; Is 1st argument a reference to a Basic object ?
650 If i = 0 And (( CallType And cstObject ) = cstObject) And SF_Utils._VarTypeExt(vArg) = V_NUMERIC Then
651 If vArg &lt; 0 Or Not IsArray(_SF_.PythonStorage) Then GoTo Catch
652 If vArg &gt; UBound(_SF_.PythonStorage) Then GoTo Catch
653 vArg = _SF_.PythonStorage(vArg)
654 &apos; Is argument a symbolic constant for Null, Empty, ... , or a date, or a dictionary ?
655 ElseIf VarType(vArg) = V_STRING Then
656 If Len(vArg) = 0 Then
657 ElseIf vArg = cstSymEmpty Then
658 vArg = Empty
659 ElseIf vArg = cstSymNull Then
660 vArg = Null
661 ElseIf vArg = cstSymMissing Then
662 Exit For &apos; Next arguments must be missing also
663 End If
664 ElseIf VarType(vArg) = V_OBJECT Then
665 If ( CallType And cstDateArg ) = cstDateArg Then vArg = CDateFromUnoDateTime(vArg)
666 ElseIf ( CallType And cstDictArg ) = cstDictArg Then
667 If IsArray(vArg) Then
668 If UBound(vArg) &gt;= 0 Then
669 If sess.UnoObjectType(vArg(0)) = &quot;com.sun.star.beans.PropertyValue&quot; Then
670 &apos; Create a dictionary - keys in Python dicts are case-sensitive
671 Set oDict = CreateScriptService(&quot;ScriptForge.Dictionary&quot;, True)
672 oDict.ImportFromPropertyValues(vArg, Overwrite := True)
673 vArg = oDict
674 End If
675 End If
676 End If
677 End If
678 iNbArgs = iNbArgs + 1
680 ReDim Preserve vArgs(iNbArgs)
681 vArgs(iNbArgs) = vArg
682 Next i
683 End If
685 Try:
686 &apos; Dispatching strategy: based on next constraints
687 &apos; (1) Bug https://bugs.documentfoundation.org/show_bug.cgi?id=138155
688 &apos; The CallByName function fails when returning an array
689 &apos; (2) Python has tuples and tuple of tuples, not 2D arrays
690 &apos; (3) Passing 2D arrays through a script provider always transform it into a sequence of sequences
691 &apos; (4) The CallByName function takes exclusive control on the targeted object up to its exit
692 &apos; (5) A script provider returns a Basic Date variable as Empty
693 &apos; RULES:
694 &apos; 1. All methods in any module are invoked with CallByName
695 &apos; 2. Properties in any service are got and set with obj.GetProperty/SetProperty(...)
696 &apos; EXCEPTIONS:
697 &apos; 3. Methods in usual modules are called by ExecuteBasicScript() when they manipulate arrays
698 &apos; 4. Methods in class modules using a 2D array or returning arrays, or methods using ParamArray,
699 &apos;&apos;&apos; are hardcoded as exceptions or are not implemented
700 &apos; 5. Due to constraint (4), a predefined list of method calls must be hardcoded to avoid blocking use of CallByName
701 &apos; The concerned methods are flagged with cstHardCode
703 With _SF_
704 &apos; Initialize Python persistent storage at 1st call
705 If IsEmpty(.PythonStorage) Then ._InitPythonStorage()
706 &apos; Reset any error
707 ._Stackreset()
708 &apos; Set Python trigger to manage signatures in error messages
709 .TriggeredByPython = True
710 End With
712 Select case VarType(BasicObject)
713 Case V_STRING
714 &apos; Special entry for CreateScriptService()
715 vBasicObject = BasicObject
716 If vBasicObject = &quot;SF_Services&quot; Then
717 If UBound(vArgs) = 0 Then vParams = Array() Else vParams = SF_Array.Slice(vArgs, 1)
718 Select Case UBound(vParams)
719 Case -1 : vReturn = SF_Services.CreateScriptService(vArgs(0))
720 Case 0 : vReturn = SF_Services.CreateScriptService(vArgs(0), vParams(0))
721 Case 1 : vReturn = SF_Services.CreateScriptService(vArgs(0), vParams(0), vParams(1))
722 Case 2 : vReturn = SF_Services.CreateScriptService(vArgs(0), vParams(0), vParams(1), vParams(2))
723 Case 3 : vReturn = SF_Services.CreateScriptService(vArgs(0), vParams(0), vParams(1), vParams(2), vParams(3))
724 Case 4 : vReturn = SF_Services.CreateScriptService(vArgs(0), vParams(0), vParams(1), vParams(2), vParams(3), vParams(4))
725 End Select
726 End If
727 If VarType(vReturn) = V_OBJECT And Not IsNull(vReturn) Then
728 vBasicObject = vReturn
729 sObjectType = vBasicObject.ObjectType
730 bBasicClass = ( Left(sObjectType, 3) &lt;&gt; &quot;SF_&quot; )
731 End If
733 &apos; Implement dispatching strategy
734 Case V_INTEGER
735 If BasicObject &lt; 0 Or Not IsArray(_SF_.PythonStorage) Then GoTo Catch
736 If BasicObject &gt; UBound(_SF_.PythonStorage) Then GoTo Catch
737 vBasicObject = _SF_.PythonStorage(BasicObject)
738 sObjectType = vBasicObject.ObjectType
739 sServiceName = vBasicObject.ServiceName
741 &apos; Basic modules have type = &quot;SF_*&quot;
742 bBasicClass = ( Left(sObjectType, 3) &lt;&gt; &quot;SF_&quot; )
743 sLibrary = Split(sServiceName, &quot;.&quot;)(0)
745 &apos; Methods in standard modules are called by ExecuteBasicScript() when arrays are returned
746 If Not bBasicClass And (CallType And vbMethod) = vbMethod And (CallType And cstRetArray) = cstRetArray Then
747 sScript = sLibrary &amp; &quot;.&quot; &amp; sObjectType &amp; &quot;.&quot; &amp; Script
748 &apos; Force validation in targeted function, not in ExecuteBasicScript()
749 _SF_.StackLevel = -1
750 Select Case UBound(vArgs)
751 Case -1 : vReturn = sess.ExecuteBasicScript(, sScript)
752 Case 0 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0))
753 Case 1 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1))
754 Case 2 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2))
755 Case 3 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2), vArgs(3))
756 Case 4 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4))
757 Case 5 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5))
758 Case 6 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6))
759 Case 7 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7))
760 End Select
761 _SF_.StackLevel = 0
763 &apos; Properties in any service are got and set with obj.GetProperty/SetProperty(...)
764 ElseIf (CallType And vbGet) = vbGet Then &apos; In some cases (Calc ...) GetProperty may have an argument
765 If UBound(vArgs) &lt; 0 Then vReturn = vBasicObject.GetProperty(Script) Else vReturn = vBasicObject.GetProperty(Script, vArgs(0))
766 ElseIf (CallType And vbLet) = vbLet Then
767 vReturn = vBasicObject.SetProperty(Script, vArgs(0))
769 &apos; Methods in class modules using a 2D array or returning arrays are hardcoded as exceptions. Bug #138155
770 ElseIf ((CallType And vbMethod) + (CallType And cstArgArray)) = vbMethod + cstArgArray Or _
771 ((CallType And vbMethod) + (CallType And cstRetArray)) = vbMethod + cstRetArray Then
772 If Script = &quot;Methods&quot; Then
773 vReturn = vBasicObject.Methods()
774 ElseIf Script = &quot;Properties&quot; Then
775 vReturn = vBasicObject.Properties()
776 Else
777 Select Case sServiceName
778 Case &quot;SFDatabases.Database&quot;
779 If Script = &quot;GetRows&quot; Then vReturn = vBasicObject.GetRows(vArgs(0), vArgs(1), vArgs(2), vArgs(3))
780 Case &quot;SFDatabases.Dataset&quot;
781 If Script = &quot;GetRows&quot; Then vReturn = vBasicObject.GetRows(vArgs(0), vArgs(1))
782 Case &quot;SFDialogs.Dialog&quot;
783 If Script = &quot;Controls&quot; Then vReturn = vBasicObject.Controls(vArgs(0))
784 Case &quot;SFDialogs.DialogControl&quot;
785 If Script = &quot;SetTableData&quot; Then vReturn = vBasicObject.SetTableData(vArgs(0), vArgs(1), vArgs(2))
786 Case &quot;SFDocuments.Document&quot;
787 Select Case Script
788 Case &quot;ContextMenus&quot; : vReturn = vBasicObject.ContextMenus(vArgs(0), vArgs(1))
789 Case &quot;Forms&quot; : vReturn = vBasicObject.Forms(vArgs(0))
790 Case &quot;Styles&quot; : vReturn = vBasicObject.Styles(vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5))
791 Case &quot;Toolbars&quot; : vReturn = vBasicObject.Toolbars(vArgs(0))
792 End Select
793 Case &quot;SFDocuments.Base&quot;
794 Select Case Script
795 Case &quot;ContextMenus&quot; : vReturn = vBasicObject.ContextMenus(vArgs(0), vArgs(1))
796 Case &quot;FormDocuments&quot; : vReturn = vBasicObject.FormDocuments()
797 Case &quot;Forms&quot; : vReturn = vBasicObject.Forms(vArgs(0), vArgs(1))
798 Case &quot;Toolbars&quot; : vReturn = vBasicObject.Toolbars(vArgs(0))
799 End Select
800 Case &quot;SFDocuments.Calc&quot;
801 Select Case Script
802 Case &quot;Charts&quot; : vReturn = vBasicObject.Charts(vArgs(0), vArgs(1))
803 Case &quot;ContextMenus&quot; : vReturn = vBasicObject.ContextMenus(vArgs(0), vArgs(1))
804 Case &quot;Forms&quot; : vReturn = vBasicObject.Forms(vArgs(0), vArgs(1))
805 Case &quot;GetFormula&quot; : vReturn = vBasicObject.GetFormula(vArgs(0))
806 Case &quot;GetValue&quot; : vReturn = vBasicObject.GetValue(vArgs(0))
807 Case &quot;SetArray&quot; : vReturn = vBasicObject.SetArray(vArgs(0), vArgs(1))
808 Case &quot;SetFormula&quot; : vReturn = vBasicObject.SetFormula(vArgs(0), vArgs(1))
809 Case &quot;SetValue&quot; : vReturn = vBasicObject.SetValue(vArgs(0), vArgs(1))
810 Case &quot;Styles&quot; : vReturn = vBasicObject.Styles(vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5))
811 Case &quot;Toolbars&quot; : vReturn = vBasicObject.Toolbars(vArgs(0))
812 End Select
813 Case &quot;SFDocuments.Form&quot;
814 Select Case Script
815 Case &quot;Controls&quot; : vReturn = vBasicObject.Controls(vArgs(0))
816 Case &quot;Subforms&quot; : vReturn = vBasicObject.Subforms(vArgs(0))
817 End Select
818 Case &quot;SFDocuments.FormControl&quot;
819 If Script = &quot;Controls&quot; Then vReturn = vBasicObject.Controls(vArgs(0))
820 Case &quot;SFDocuments.FormDocument&quot;
821 Select Case Script
822 Case &quot;ContextMenus&quot; : vReturn = vBasicObject.ContextMenus(vArgs(0), vArgs(1))
823 Case &quot;Forms&quot; : vReturn = vBasicObject.Forms(vArgs(0))
824 Case &quot;Toolbars&quot; : vReturn = vBasicObject.Toolbars(vArgs(0))
825 End Select
826 Case &quot;SFDocuments.Writer&quot;
827 Select Case Script
828 Case &quot;ContextMenus&quot; : vReturn = vBasicObject.ContextMenus(vArgs(0), vArgs(1))
829 Case &quot;Forms&quot; : vReturn = vBasicObject.Forms(vArgs(0))
830 Case &quot;Styles&quot; : vReturn = vBasicObject.Styles(vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5))
831 Case &quot;Toolbars&quot; : vReturn = vBasicObject.Toolbars(vArgs(0))
832 End Select
833 Case &quot;SFWidgets.Toolbar&quot;
834 Select Case Script
835 Case &quot;ToolbarButtons&quot; : vReturn = vBasicObject.ToolbarButtons(vArgs(0))
836 End Select
837 End Select
838 End If
840 &apos; Specific methods in class modules may better not be executed with CallByName() because they do not return immediately
841 ElseIf bBasicClass And ((CallType And vbMethod) + (CallType And cstHardCode)) = vbMethod + cstHardCode Then
842 Select Case sServiceName
843 Case &quot;SFDialogs.Dialog&quot;
844 Select Case Script
845 Case &quot;Execute&quot; : vReturn = vBasicObject.Execute(vArgs(0))
846 End Select
847 End Select
849 &apos; Methods in all modules are invoked with CallByName
850 ElseIf ((CallType And vbMethod) = vbMethod) Then
851 Select Case UBound(vArgs)
852 &apos; Dirty alternatives to process usual and ParamArray cases
853 &apos; But, up to ... how many ?
854 &apos; - The OFFSETADDRESSERROR has 12 arguments
855 &apos; - The &quot;.uno:DataSort&quot; command may have 14 property name-value pairs
856 Case -1 : vReturn = CallByName(vBasicObject, Script, vbMethod)
857 Case 0 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0))
858 Case 1 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1))
859 Case 2 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2))
860 Case 3 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3))
861 Case 4 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4))
862 Case 5 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5))
863 Case 6 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6))
864 Case 7 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7))
865 Case 8 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
866 , vArgs(8))
867 Case 9 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
868 , vArgs(8), vArgs(9))
869 Case 10 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
870 , vArgs(8), vArgs(9), vArgs(10))
871 Case 11 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
872 , vArgs(8), vArgs(9), vArgs(10), vArgs(11))
873 Case 12, 13 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
874 , vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12))
875 Case 14, 15 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
876 , vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14))
877 Case 16, 17 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
878 , vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16))
879 Case 18, 19 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
880 , vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16), vArgs(17), vArgs(18))
881 Case 20, 21 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
882 , vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16), vArgs(17), vArgs(18) _
883 , vArgs(19), vArgs(20))
884 Case 22, 23 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
885 , vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16), vArgs(17), vArgs(18) _
886 , vArgs(19), vArgs(20), vArgs(21), vArgs(22))
887 Case 24, 25 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
888 , vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16), vArgs(17), vArgs(18) _
889 , vArgs(19), vArgs(20), vArgs(21), vArgs(22), vArgs(23), vArgs(24))
890 Case 26, 27 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
891 , vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16), vArgs(17), vArgs(18) _
892 , vArgs(19), vArgs(20), vArgs(21), vArgs(22), vArgs(23), vArgs(24), vArgs(25), vArgs(26))
893 Case &gt;= 28 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
894 , vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16), vArgs(17), vArgs(18) _
895 , vArgs(19), vArgs(20), vArgs(21), vArgs(22), vArgs(23), vArgs(24), vArgs(25), vArgs(26), vArgs(27), vArgs(28))
896 End Select
897 End If
899 &apos; Post processing
900 If (CallType And cstPost) = cstPost Then
901 If Script = &quot;Dispose&quot; Then
902 &apos; Special case: Dispose() must update the cache for class objects created in Python scripts
903 Set _SF_.PythonStorage(BasicObject) = Nothing
904 End If
905 End If
906 Case Else
907 End Select
909 &apos; Format the returned array
910 vReturnArray = Array()
911 &apos; Distinguish: Basic object
912 &apos; UNO object
913 &apos; Dictionary
914 &apos; Array
915 &apos; Scalar
916 If IsArray(vReturn) Then
917 ReDim vReturnArray(0 To 2)
918 iDims = SF_Array.CountDims(vReturn)
919 &apos; Replace dates by UNO format
920 If iDims = 1 Then
921 For i = LBound(vReturn) To UBound(vReturn)
922 If VarType(vReturn(i)) = V_DATE Then vReturn(i) = CDateToUnoDateTime(vReturn(i))
923 Next i
924 ElseIf iDims = 2 Then
925 For i = LBound(vReturn, 1) To UBound(vReturn, 1)
926 For j = LBound(vReturn, 2) To UBound(vReturn, 2)
927 If VarType(vReturn(i, j)) = V_DATE Then vReturn(i, j) = CDateToUnoDateTime(vReturn(i, j))
928 Next j
929 Next i
930 End If
931 vReturnArray(0) = vReturn &apos; 2D arrays are flattened by the script provider when returning to Python
932 vReturnArray(1) = VarType(vReturn)
933 vReturnArray(2) = iDims
934 ElseIf VarType(vReturn) = V_OBJECT And Not IsNull(vReturn) Then
935 &apos; Uno or not Uno ?
936 bUno = False
937 If (CallType And cstUno) = cstUno Then &apos; UNO considered only when pre-announced in CallType
938 Set oObjDesc = SF_Utils._VarTypeObj(vReturn)
939 bUno = ( oObjDesc.iVarType = V_UNOOBJECT )
940 End If
941 If bUno Then
942 ReDim vReturnArray(0 To 2)
943 Set vReturnArray(0) = vReturn
944 Else
945 ReDim vReturnArray(0 To 5)
946 bDict = ( vReturn.ObjectType = &quot;DICTIONARY&quot; )
947 If bDict Then
948 vReturnArray(0) = vReturn.ConvertToPropertyValues()
949 Else
950 vReturnArray(0) = _SF_._AddToPythonSTorage(vReturn)
951 End If
952 End If
953 vReturnArray(1) = V_OBJECT
954 Select Case True
955 Case bUno : vReturnArray(2) = objUNO
956 Case bDict : vReturnArray(2) = objDICT
957 Case bBasicClass : vReturnArray(2) = objCLASS
958 Case Else : vReturnArray(2) = objMODULE
959 End Select
960 If Not bUno Then
961 vReturnArray(3) = vReturn.ObjectType
962 vReturnArray(4) = vReturn.ServiceName
963 vReturnArray(5) = &quot;&quot;
964 If vReturn.ObjectType &lt;&gt; &quot;SF_CalcReference&quot; And Not bDict Then &apos; Calc references are implemented as a Type ... End Type data structure
965 If SF_Array.Contains(vReturn.Properties(), &quot;Name&quot;, SortOrder := &quot;ASC&quot;) Then vReturnArray(5) = vReturn.Name
966 End If
967 End If
968 Else &apos; Scalar or Nothing
969 ReDim vReturnArray(0 To 1)
970 If VarType(vReturn) = V_DATE Then vReturnArray(0) = CDateToUnoDateTime(vReturn) Else vReturnArray(0) = vReturn
971 vReturnArray(1) = VarType(vReturn)
972 End If
974 &apos; Tests with non-modal dialogs and sleeping (time.sleep) Python processes show
975 &apos; a more fluid reactivity when next statement is present, at a minimal cost.
976 Wait 0
978 _PythonDispatcher = vReturnArray
980 Finally:
981 _SF_.TriggeredByPython = False &apos; Reset normal state
982 Exit Function
983 Catch:
984 GoTo Finally
985 End Function &apos; ScriptForge.SF_PythonHelper._PythonDispatcher
987 REM -----------------------------------------------------------------------------
988 Private Function _Repr() As String
989 &apos;&apos;&apos; Convert the Basic instance to a readable string, typically for debugging purposes (DebugPrint ...)
990 &apos;&apos;&apos; Args:
991 &apos;&apos;&apos; Return:
992 &apos;&apos;&apos; &quot;[PythonHelper]&quot;
994 _Repr = &quot;[PythonHelper]&quot;
996 End Function &apos; ScriptForge.SF_PythonHelper._Repr
998 REM ================================================= END OF SCRIPTFORGE.SF_PythonHelper
999 </script:module>