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 =======================================================================================================================
11 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
12 ''' SF_PythonHelper (aka Basic)
13 ''' ===============
14 ''' Singleton class implementing the
"ScriptForge.Basic
" service
15 ''' Implemented as a usual Basic module
17 ''' The
"Basic
" service must be called ONLY from a PYTHON script
18 ''' Service invocations: Next Python code lines are equivalent:
19 ''' bas = CreateScriptService(
'ScriptForge.Basic
')
20 ''' bas = CreateScriptService(
'Basic
')
22 ''' This service proposes a collection of methods to be executed in a Python context
23 ''' to simulate the exact behaviour of the identical Basic builtin method.
24 ''' Typical example:
25 ''' bas.MsgBox(
'This has to be displayed in a message box
')
27 ''' The service includes also an agnostic
"Python Dispatcher
" function.
28 ''' It dispatches Python script requests to execute Basic services to the
29 ''' appropriate properties and methods via dynamic call techniques
31 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
33 REM ================================================================== EXCEPTIONS
35 REM ============================================================ MODULE CONSTANTS
37 REM ===================================================== CONSTRUCTOR/DESTRUCTOR
39 REM -----------------------------------------------------------------------------
40 Public Function Dispose() As Variant
42 End Function
' ScriptForge.SF_PythonHelper Explicit destructor
44 REM ================================================================== PROPERTIES
46 REM -----------------------------------------------------------------------------
47 Property Get ObjectType As String
48 ''' Only to enable object representation
49 ObjectType =
"SF_PythonHelper
"
50 End Property
' ScriptForge.SF_PythonHelper.ObjectType
52 REM -----------------------------------------------------------------------------
53 Property Get ServiceName As String
54 ''' Internal use
55 ServiceName =
"ScriptForge.Basic
"
56 End Property
' ScriptForge.SF_PythonHelper.ServiceName
58 REM ============================================================== PUBLIC METHODS
60 REM -----------------------------------------------------------------------------
61 Public Function PyCDate(ByVal DateArg As Variant) As Variant
62 ''' Convenient function to replicate CDate() in Python scripts
63 ''' Args:
64 ''' DateArg: a date as a string or as a double
65 ''' Returns:
66 ''' The converted date as a UNO DateTime structure
67 ''' If the input argument could not be recognized as a date, return the argument unchanged
68 ''' Example: (Python code)
69 ''' a = bas.CDate(
'2021-
02-
18')
71 Dim vDate As Variant
' Return value
72 Const cstThisSub =
"Basic.CDate
"
73 Const cstSubArgs =
"datearg
"
75 On Local Error GoTo Catch
79 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
82 vDate = CDate(DateArg)
85 If VarType(vDate) = V_DATE Then PyCDate = CDateToUnoDateTime(vDate) Else PyCDate = DateArg
86 SF_Utils._ExitFunction(cstThisSub)
91 End Function
' ScriptForge.SF_PythonHelper.PyCDate
93 REM -----------------------------------------------------------------------------
94 Public Function PyConvertFromUrl(ByVal FileName As Variant) As String
95 ''' Convenient function to replicate ConvertFromUrl() in Python scripts
96 ''' Args:
97 ''' FileName: a string representing a file in URL format
98 ''' Returns:
99 ''' The same file name in native operating system notation
100 ''' Example: (Python code)
101 ''' a = bas.ConvertFromUrl(
'file:////boot.sys
')
103 Dim sFileName As String
' Return value
104 Const cstThisSub =
"Basic.ConvertFromUrl
"
105 Const cstSubArgs =
"filename
"
107 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
108 sFileName =
""
111 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
114 sFileName = ConvertFromUrl(FileName)
117 PyConvertFromUrl = sFileName
118 SF_Utils._ExitFunction(cstThisSub)
122 End Function
' ScriptForge.SF_PythonHelper.PyConvertFromUrl
124 REM -----------------------------------------------------------------------------
125 Public Function PyConvertToUrl(ByVal FileName As Variant) As String
126 ''' Convenient function to replicate ConvertToUrl() in Python scripts
127 ''' Args:
128 ''' FileName: a string representing a file in native operating system notation
129 ''' Returns:
130 ''' The same file name in URL format
131 ''' Example: (Python code)
132 ''' a = bas.ConvertToUrl(
'C:\boot.sys
')
134 Dim sFileName As String
' Return value
135 Const cstThisSub =
"Basic.ConvertToUrl
"
136 Const cstSubArgs =
"filename
"
138 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
139 sFileName =
""
142 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
145 sFileName = ConvertToUrl(FileName)
148 PyConvertToUrl = sFileName
149 SF_Utils._ExitFunction(cstThisSub)
153 End Function
' ScriptForge.SF_PythonHelper.PyConvertToUrl
155 REM -----------------------------------------------------------------------------
156 Public Function PyCreateUnoService(ByVal UnoService As Variant) As Variant
157 ''' Convenient function to replicate CreateUnoService() in Python scripts
158 ''' Args:
159 ''' UnoService: a string representing the service to create
160 ''' Returns:
161 ''' A UNO object
162 ''' Example: (Python code)
163 ''' a = bas.CreateUnoService(
'com.sun.star.i18n.CharacterClassification
')
165 Dim vUno As Variant
' Return value
166 Const cstThisSub =
"Basic.CreateUnoService
"
167 Const cstSubArgs =
"unoservice
"
169 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
173 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
176 Set vUno = CreateUnoService(UnoService)
179 Set PyCreateUnoService = vUno
180 SF_Utils._ExitFunction(cstThisSub)
184 End Function
' ScriptForge.SF_PythonHelper.PyCreateUnoService
186 REM -----------------------------------------------------------------------------
187 Public Function PyDateAdd(ByVal Add As Variant _
188 , ByVal Count As Variant _
189 , ByVal DateArg As Variant _
191 ''' Convenient function to replicate DateAdd() in Python scripts
192 ''' Args:
193 ''' Add: The unit to add
194 ''' Count: how many times to add (might be negative)
195 ''' DateArg: a date as a com.sun.star.util.DateTime UNO structure
196 ''' Returns:
197 ''' The new date as a string in iso format
198 ''' Example: (Python code)
199 ''' a = bas.DateAdd(
'd
',
1, bas.Now())
' Tomorrow
201 Dim vNewDate As Variant
' Return value
202 Dim vDate As Date
' Alias of DateArg
203 Const cstThisSub =
"Basic.DateAdd
"
204 Const cstSubArgs =
"add, count, datearg
"
206 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
207 vNewDate =
""
210 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
213 If VarType(DateArg) = V_OBJECT Then
214 vDate = CDateFromUnoDateTime(DateArg)
216 vDate = SF_Utils._CStrToDate(DateArg)
218 vNewDate = DateAdd(Add, Count, vDate)
221 If VarType(vNewDate) = V_DATE Then PyDateAdd = CDateToUnoDateTime(vNewDate) Else PyDateAdd = vNewDate
222 SF_Utils._ExitFunction(cstThisSub)
226 End Function
' 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 _
235 ''' Convenient function to replicate DateDiff() in Python scripts
236 ''' Args:
237 ''' Add: The unit of the date interval
238 ''' Date1, Date2: the two dates to be compared
239 ''' WeekStart: the starting day of a week
240 ''' YearStart: the starting week of a year
241 ''' Returns:
242 ''' The number of intervals expressed in Adds
243 ''' Example: (Python code)
244 ''' a = bas.DateDiff(
'd
', bas.DateAdd(
'd
',
1, bas.Now()), bas.Now())
' -
1 day
246 Dim lDiff As Long
' Return value
247 Dim vDate1 As Date
' Alias of Date1
248 Dim vDate2 As Date
' Alias of Date2
249 Const cstThisSub =
"Basic.DateDiff
"
250 Const cstSubArgs =
"add, date1, date2, [weekstart=
1], [yearstart=
1]
"
252 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
256 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
259 If VarType(Date1) = V_OBJECT Then
260 vDate1 = CDateFromUnoDateTime(Date1)
262 vDate1 = SF_Utils._CStrToDate(Date1)
264 If VarType(Date2) = V_OBJECT Then
265 vDate2 = CDateFromUnoDateTime(Date2)
267 vDate2 = SF_Utils._CStrToDate(Date2)
269 lDiff = DateDiff(Add, vDate1, vDate2, WeekStart, YearStart)
274 SF_Utils._ExitFunction(cstThisSub)
278 End Function
' 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 _
286 ''' Convenient function to replicate DatePart() in Python scripts
287 ''' Args:
288 ''' Add: The unit of the date interval
289 ''' DateArg: The date from which to extract a part
290 ''' WeekStart: the starting day of a week
291 ''' YearStart: the starting week of a year
292 ''' Returns:
293 ''' The specified part of the date
294 ''' Example: (Python code)
295 ''' a = bas.DatePart(
'y
', bas.Now())
' day of year
297 Dim lPart As Long
' Return value
298 Dim vDate As Date
' Alias of DateArg
299 Const cstThisSub =
"Basic.DatePart
"
300 Const cstSubArgs =
"add, datearg, [weekstart=
1], [yearstart=
1]
"
302 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
306 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
309 If VarType(DateArg) = V_OBJECT Then
310 vDate = CDateFromUnoDateTime(DateArg)
312 vDate = SF_Utils._CStrToDate(DateArg)
314 lPart = DatePart(Add, vDate, WeekStart, YearStart)
319 SF_Utils._ExitFunction(cstThisSub)
323 End Function
' ScriptForge.SF_PythonHelper.PyDatePart
325 REM -----------------------------------------------------------------------------
326 Public Function PyDateValue(ByVal DateArg As Variant) As Variant
327 ''' Convenient function to replicate DateValue() in Python scripts
328 ''' Args:
329 ''' DateArg: a date as a string
330 ''' Returns:
331 ''' The converted date as a UNO DateTime structure
332 ''' Example: (Python code)
333 ''' a = bas.DateValue(
'2021-
02-
18')
335 Dim vDate As Variant
' Return value
336 Const cstThisSub =
"Basic.DateValue
"
337 Const cstSubArgs =
"datearg
"
339 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
343 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
346 vDate = DateValue(DateArg)
349 If VarType(vDate) = V_DATE Then PyDateValue = CDateToUnoDateTime(vDate) Else PyDateValue = vDate
350 SF_Utils._ExitFunction(cstThisSub)
354 End Function
' ScriptForge.SF_PythonHelper.PyDateValue
356 REM -----------------------------------------------------------------------------
357 Public Function PyFormat(ByVal Value As Variant _
358 , ByVal Pattern As Variant _
360 ''' Convenient function to replicate Format() in Python scripts
361 ''' Args:
362 ''' Value: a date or a number
363 ''' Pattern: the format to apply
364 ''' Returns:
365 ''' The formatted value
366 ''' Example: (Python code)
367 ''' MsgBox bas.Format(
6328.2,
'##,##
0.00')
369 Dim sFormat As String
' Return value
370 Dim vValue As Variant
' Alias of Value
371 Const cstThisSub =
"Basic.Format
"
372 Const cstSubArgs =
"value, pattern
"
374 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
375 sFormat =
""
378 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
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)
387 SF_Utils._ExitFunction(cstThisSub)
391 End Function
' ScriptForge.SF_PythonHelper.PyFormat
393 REM -----------------------------------------------------------------------------
394 Public Function PyGetGuiType() As Integer
395 ''' Convenient function to replicate GetGuiType() in Python scripts
396 ''' Args:
397 ''' Returns:
398 ''' The GetGuiType value
399 ''' Example: (Python code)
400 ''' MsgBox bas.GetGuiType()
402 Const cstThisSub =
"Basic.GetGuiType
"
403 Const cstSubArgs =
""
406 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
409 PyGetGuiType = GetGuiType()
413 SF_Utils._ExitFunction(cstThisSub)
415 End Function
' ScriptForge.SF_PythonHelper.PyGetGuiType
417 REM -----------------------------------------------------------------------------
418 Public Function PyGetSystemTicks() As Long
419 ''' Convenient function to replicate GetSystemTicks() in Python scripts
420 ''' Args:
421 ''' Returns:
422 ''' The GetSystemTicks value
423 ''' Example: (Python code)
424 ''' MsgBox bas.GetSystemTicks()
426 Const cstThisSub =
"Basic.GetSystemTicks
"
427 Const cstSubArgs =
""
430 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
433 PyGetSystemTicks = GetSystemTicks()
437 SF_Utils._ExitFunction(cstThisSub)
439 End Function
' ScriptForge.SF_PythonHelper.PyGetSystemTicks
441 REM -----------------------------------------------------------------------------
442 Public Function PyGlobalScope(ByVal Library As Variant) As Object
443 ''' Convenient function to replicate GlobalScope() in Python scripts
444 ''' Args:
445 ''' Library:
"Basic
" or
"Dialog
"
446 ''' Returns:
447 ''' The GlobalScope value
448 ''' Example: (Python code)
449 ''' MsgBox bas.GlobalScope.BasicLibraries()
451 Const cstThisSub =
"Basic.GlobalScope.BasicLibraries
" ' or DialogLibraries
452 Const cstSubArgs =
""
455 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
459 Case
"Basic
"
460 PyGlobalScope = GlobalScope.BasicLibraries()
461 Case
"Dialog
"
462 PyGlobalScope = GlobalScope.DialogLibraries()
467 SF_Utils._ExitFunction(cstThisSub)
469 End Function
' 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 _
478 ''' Convenient function to replicate InputBox() in Python scripts
479 ''' Args:
480 ''' Msg: String expression displayed as the message in the dialog box
481 ''' Title: String expression displayed in the title bar of the dialog box
482 ''' Default: String expression displayed in the text box as default if no other input is given
483 ''' XPosTwips: Integer expression that specifies the horizontal position of the dialog
484 ''' YPosTwips: Integer expression that specifies the vertical position of the dialog
485 ''' If XPosTwips and YPosTwips are omitted, the dialog is centered on the screen
486 ''' The position is specified in twips.
487 ''' Returns:
488 ''' The entered value or
"" if the user pressed the Cancel button
489 ''' Example: (Python code)
490 ''' a = bas.InputBox (
'Please enter a phrase:
',
'Dear User
')
492 Dim sInput As String
' Return value
493 Const cstThisSub =
"Basic.InputBox
"
494 Const cstSubArgs =
"msg, [title=
''], [default=
''], [xpostwips], [ypostwips]
"
496 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
497 sInput =
""
500 If IsMissing(YPosTwips) Then YPosTwips =
1
501 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
504 If IsMissing(XPosTwips) Then
505 sInput = InputBox(Msg, Title, Default)
507 sInput = InputBox(Msg, Title, Default, XPosTwips, YPosTwips)
512 SF_Utils._ExitFunction(cstThisSub)
516 End Function
' ScriptForge.SF_PythonHelper.PyInputBox
518 REM -----------------------------------------------------------------------------
519 Public Function PyMsgBox(ByVal Text As Variant _
520 , ByVal DialogType As Variant _
521 , ByVal DialogTitle As Variant _
523 ''' Convenient function to replicate MsgBox() in Python scripts
524 ''' Args:
525 ''' Text: String expression displayed as a message in the dialog box
526 ''' DialogType: Any integer expression that defines the number and type of buttons or icons displayed
527 ''' DialogTitle: String expression displayed in the title bar of the dialog
528 ''' Returns:
529 ''' The pressed button
530 ''' Example: (Python code)
531 ''' a = bas.MsgBox (
'Please press a button:
', bas.MB_EXCLAMATION,
'Dear User
')
533 Dim iMsg As Integer
' Return value
534 Const cstThisSub =
"Basic.MsgBox
"
535 Const cstSubArgs =
"text, [dialogtype=
0], [dialogtitle]
"
537 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
541 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
544 iMsg = MsgBox(Text, DialogType, DialogTitle)
548 SF_Utils._ExitFunction(cstThisSub)
552 End Function
' 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 _
562 ''' Called from Python only
563 ''' The method calls the method Script associated with the BasicObject class or module
564 ''' with the given arguments
565 ''' The invocation of the method can be a Property Get, Property Let or a usual call
566 ''' NB: arguments and return values must not be
2D arrays
567 ''' The implementation intends to be as AGNOSTIC as possible in terms of objects nature and methods called
568 ''' Args:
569 ''' BasicObject: a module or a class instance - May also be the reserved string:
"SF_Services
"
570 ''' CallType: one of the constants applicable to a CallByName statement + optional protocol flags
571 ''' Script: the name of the method or property
572 ''' Args: the arguments to pass to the method. Input arguments can contain symbolic constants for Null, Missing, etc.
573 ''' Returns:
574 ''' A
1D array:
575 ''' [
0] The returned value - scalar, object or
1D array
576 ''' [
1] The VarType() of the returned value
577 ''' Null, Empty and Nothing have different vartypes but return all None to Python
578 ''' Additionally, when array:
579 ''' [
2] Number of dimensions in Basic
580 ''' Additionally, when Basic object:
581 ''' [
2] Module (
1), Class instance (
2) or UNO (
3)
582 ''' [
3] The object
's ObjectType
583 ''' [
4] The object
's service name
584 ''' [
5] The object
's name
585 ''' When an error occurs Python receives None as a scalar. This determines the occurrence of a failure
587 Dim vReturn As Variant
' The value returned by the invoked property or method
588 Dim vReturnArray As Variant
' Return value
589 Dim vBasicObject As Variant
' Alias of BasicObject to avoid
"Object reference not set
" error
590 Dim iNbArgs As Integer
' Number of valid input arguments
591 Dim vArg As Variant
' Alias for a single argument
592 Dim vArgs() As Variant
' Alias for Args()
593 Dim sScript As String
' Argument of ExecuteBasicScript()
594 Dim vParams As Variant
' Array of arguments to pass to a ParamArray
595 Dim sObjectType As String
' Alias of object.ObjectType
596 Dim sServiceName As String
' Alias of BasicObject.ServiceName
597 Dim bBasicClass As Boolean
' True when BasicObject is a class
598 Dim sLibrary As String
' Library where the object belongs to
599 Dim bUno As Boolean
' Return value is a UNO object
600 Dim oObjDesc As Object
' _ObjectDescriptor type
601 Dim iDims As Integer
' # of dims of vReturn
602 Dim sess As Object : Set sess = ScriptForge.SF_Session
603 Dim i As Long, j As Long
605 ' Conventional special input or output values
606 Const cstNoArgs =
"+++NOARGS+++
", cstSymEmpty =
"+++EMPTY+++
", cstSymNull =
"+++NULL+++
", cstSymMissing =
"+++MISSING+++
"
608 ' https://support.office.com/en-us/article/CallByName-fonction-
49ce9475-c315-
4f13-
8d35-e98cfe98729a
609 ' Determines the CallType
610 Const vbGet =
2, vbLet =
4, vbMethod =
1, vbSet =
8
611 ' Protocol flags
612 Const cstDateArg =
64 ' May contain a date argument
613 Const cstDateRet =
128 ' Return value can be a date
614 Const cstUno =
256 ' Return value can be a UNO object
615 Const cstArgArray =
512 ' Any argument can be a
2D array
616 Const cstRetArray =
1024 ' Return value can be an array
617 Const cstObject =
2048 ' 1st argument is a Basic object when numeric
618 Const cstHardCode =
4096 ' Method must not be executed with CallByName()
619 ' Object nature in returned array
620 Const objMODULE =
1, objCLASS =
2, objUNO =
3
623 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
624 _PythonDispatcher = Null
626 ' Ignore Null basic objects (Null = Null or Nothing)
627 If IsNull(BasicObject) Or IsEmpty(BasicObject) Then GoTo Catch
629 ' Reinterpret arguments one by one into vArgs, convert UNO date/times and conventional NoArgs/Empty/Null/Missing values
633 If UBound(Args)
>=
0 Then
634 For i =
0 To UBound(Args)
636 ' Are there arguments ?
637 If i =
0 And VarType(vArg) = V_STRING Then
638 If vArg = cstNoArgs Then Exit For
640 ' Is
1st argument a reference to a Basic object ?
641 If i =
0 And (( CallType And cstObject ) = cstObject) And SF_Utils._VarTypeExt(vArg) = V_NUMERIC Then
642 If vArg
< 0 Or Not IsArray(_SF_.PythonStorage) Then GoTo Catch
643 If vArg
> UBound(_SF_.PythonStorage) Then GoTo Catch
644 vArg = _SF_.PythonStorage(vArg)
645 ' Is argument a symbolic constant for Null, Empty, ... , or a date?
646 ElseIf VarType(vArg) = V_STRING Then
647 If Len(vArg) =
0 Then
648 ElseIf vArg = cstSymEmpty Then
650 ElseIf vArg = cstSymNull Then
652 ElseIf vArg = cstSymMissing Then
653 Exit For
' Next arguments must be missing also
655 ElseIf VarType(vArg) = V_OBJECT Then
656 If ( CallType And cstDateArg ) = cstDateArg Then vArg = CDateFromUnoDateTime(vArg)
658 iNbArgs = iNbArgs +
1
660 ReDim Preserve vArgs(iNbArgs)
661 vArgs(iNbArgs) = vArg
666 ' Dispatching strategy: based on next constraints
667 ' (
1) Bug https://bugs.documentfoundation.org/show_bug.cgi?id=
138155
668 ' The CallByName function fails when returning an array
669 ' (
2) Python has tuples and tuple of tuples, not
2D arrays
670 ' (
3) Passing
2D arrays through a script provider always transform it into a sequence of sequences
671 ' (
4) The CallByName function takes exclusive control on the targeted object up to its exit
672 ' 1. Methods in usual modules are called by ExecuteBasicScript() except if they use a ParamArray
673 ' 2. Properties in any service are got and set with obj.GetProperty/SetProperty(...)
674 ' 3. Methods in class modules are invoked with CallByName
675 ' 4. Methods in class modules using a
2D array or returning arrays, or methods using ParamArray,
676 ''' are hardcoded as exceptions or are not implemented
677 ' 5. Due to constraint (
4), a predefined list of method calls must be hardcoded to avoid blocking use of CallByName
678 ' The concerned methods are flagged with cstHardCode
681 ' Initialize Python persistent storage at
1st call
682 If IsEmpty(.PythonStorage) Then ._InitPythonStorage()
683 ' Reset any error
685 ' Set Python trigger to manage signatures in error messages
686 .TriggeredByPython = True
689 Select case VarType(BasicObject)
691 ' Special entry for CreateScriptService()
692 vBasicObject = BasicObject
693 If vBasicObject =
"SF_Services
" Then
694 If UBound(vArgs) =
0 Then vParams = Array() Else vParams = SF_Array.Slice(vArgs,
1)
695 Select Case UBound(vParams)
696 Case -
1 : vReturn = SF_Services.CreateScriptService(vArgs(
0))
697 Case
0 : vReturn = SF_Services.CreateScriptService(vArgs(
0), vParams(
0))
698 Case
1 : vReturn = SF_Services.CreateScriptService(vArgs(
0), vParams(
0), vParams(
1))
699 Case
2 : vReturn = SF_Services.CreateScriptService(vArgs(
0), vParams(
0), vParams(
1), vParams(
2))
700 Case
3 : vReturn = SF_Services.CreateScriptService(vArgs(
0), vParams(
0), vParams(
1), vParams(
2), vParams(
3))
701 Case
4 : vReturn = SF_Services.CreateScriptService(vArgs(
0), vParams(
0), vParams(
1), vParams(
2), vParams(
3), vParams(
4))
704 If VarType(vReturn) = V_OBJECT And Not IsNull(vReturn) Then
705 vBasicObject = vReturn
706 sObjectType = vBasicObject.ObjectType
707 bBasicClass = ( Left(sObjectType,
3)
<> "SF_
" )
710 ' Implement dispatching strategy
712 If BasicObject
< 0 Or Not IsArray(_SF_.PythonStorage) Then GoTo Catch
713 If BasicObject
> UBound(_SF_.PythonStorage) Then GoTo Catch
714 vBasicObject = _SF_.PythonStorage(BasicObject)
715 sObjectType = vBasicObject.ObjectType
716 sServiceName = vBasicObject.ServiceName
718 ' Basic modules have type =
"SF_*
"
719 bBasicClass = ( Left(sObjectType,
3)
<> "SF_
" )
720 sLibrary = Split(sServiceName,
".
")(
0)
722 ' Methods in standard modules returning/passing a date are hardcoded as exceptions
723 If Not bBasicClass And ((CallType And vbMethod) = vbMethod) _
724 And (((CallType And cstDateRet) = cstDateRet) Or ((CallType And cstDateArg) = cstDateArg)) Then
725 Select Case sServiceName
726 Case
"ScriptForge.FileSystem
"
727 If Script =
"GetFileModified
" Then vReturn = SF_FileSystem.GetFileModified(vArgs(
0))
728 Case
"ScriptForge.Region
"
730 Case
"DSTOffset
" : vReturn = SF_Region.DSTOffset(vArgs(
0), vArgs(
1), vArgs(
2))
731 Case
"LocalDateTime
" : vReturn = SF_Region.LocalDateTime(vArgs(
0), vArgs(
1), vArgs(
2))
732 Case
"UTCDateTime
" : vReturn = SF_Region.UTCDateTime(vArgs(
0), vArgs(
1), vArgs(
2))
733 Case
"UTCNow
" : vReturn = SF_Region.UTCNow(vArgs(
0), vArgs(
1))
738 ' Methods in usual modules using a
2D array or returning arrays are hardcoded as exceptions
739 ElseIf Not bBasicClass And _
740 (((CallType And vbMethod) + (CallType And cstArgArray)) = vbMethod + cstArgArray Or _
741 ((CallType And vbMethod) + (CallType And cstRetArray)) = vbMethod + cstRetArray) Then
742 ' Not service related
743 If Script =
"Methods
" Then
744 vReturn = vBasicObject.Methods()
745 ElseIf Script =
"Properties
" Then
746 vReturn = vBasicObject.Properties()
748 Select Case sServiceName
749 Case
"ScriptForge.Array
"
750 If Script =
"ImportFromCSVFile
" Then vReturn = SF_Array.ImportFromCSVFile(vArgs(
0), vArgs(
1), vArgs(
2), True)
754 ' Methods in usual modules are called by ExecuteBasicScript() except if they use a ParamArray
755 ElseIf Not bBasicClass And (CallType And vbMethod) = vbMethod Then
756 sScript = sLibrary
& ".
" & sObjectType
& ".
" & Script
757 ' Force validation in targeted function, not in ExecuteBasicScript()
759 Select Case UBound(vArgs)
760 Case -
1 : vReturn = sess.ExecuteBasicScript(, sScript)
761 Case
0 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(
0))
762 Case
1 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(
0), vArgs(
1))
763 Case
2 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(
0), vArgs(
1), vArgs(
2))
764 Case
3 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3))
765 Case
4 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3), vArgs(
4))
766 Case
5 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3), vArgs(
4), vArgs(
5))
767 Case
6 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3), vArgs(
4), vArgs(
5), vArgs(
6))
768 Case
7 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3), vArgs(
4), vArgs(
5), vArgs(
6), vArgs(
7))
772 ' Properties in any service are got and set with obj.GetProperty/SetProperty(...)
773 ElseIf (CallType And vbGet) = vbGet Then
' In some cases (Calc ...) GetProperty may have an argument
774 If UBound(vArgs)
< 0 Then vReturn = vBasicObject.GetProperty(Script) Else vReturn = vBasicObject.GetProperty(Script, vArgs(
0))
775 ElseIf (CallType And vbLet) = vbLet Then
776 vReturn = vBasicObject.SetProperty(Script, vArgs(
0))
778 ' Methods in class modules using a
2D array or returning arrays are hardcoded as exceptions. Bug #
138155
779 ElseIf ((CallType And vbMethod) + (CallType And cstArgArray)) = vbMethod + cstArgArray Or _
780 ((CallType And vbMethod) + (CallType And cstRetArray)) = vbMethod + cstRetArray Then
781 If Script =
"Methods
" Then
782 vReturn = vBasicObject.Methods()
783 ElseIf Script =
"Properties
" Then
784 vReturn = vBasicObject.Properties()
786 Select Case sServiceName
787 Case
"SFDatabases.Database
"
788 If Script =
"GetRows
" Then vReturn = vBasicObject.GetRows(vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3))
789 Case
"SFDialogs.Dialog
"
790 If Script =
"Controls
" Then vReturn = vBasicObject.Controls(vArgs(
0))
791 Case
"SFDialogs.DialogControl
"
792 If Script =
"SetTableData
" Then vReturn = vBasicObject.SetTableData(vArgs(
0), vArgs(
1), vArgs(
2))
793 Case
"SFDocuments.Document
"
794 If Script =
"Forms
" Then vReturn = vBasicObject.Forms(vArgs(
0))
795 Case
"SFDocuments.Base
"
797 Case
"FormDocuments
" : vReturn = vBasicObject.FormDocuments()
798 Case
"Forms
" : vReturn = vBasicObject.Forms(vArgs(
0), vArgs(
1))
800 Case
"SFDocuments.Calc
"
802 Case
"Charts
" : vReturn = vBasicObject.Charts(vArgs(
0), vArgs(
1))
803 Case
"Forms
" : vReturn = vBasicObject.Forms(vArgs(
0), vArgs(
1))
804 Case
"GetFormula
" : vReturn = vBasicObject.GetFormula(vArgs(
0))
805 Case
"GetValue
" : vReturn = vBasicObject.GetValue(vArgs(
0))
806 Case
"SetArray
" : vReturn = vBasicObject.SetArray(vArgs(
0), vArgs(
1))
807 Case
"SetFormula
" : vReturn = vBasicObject.SetFormula(vArgs(
0), vArgs(
1))
808 Case
"SetValue
" : vReturn = vBasicObject.SetValue(vArgs(
0), vArgs(
1))
810 Case
"SFDocuments.Form
"
812 Case
"Controls
" : vReturn = vBasicObject.Controls(vArgs(
0))
813 Case
"Subforms
" : vReturn = vBasicObject.Subforms(vArgs(
0))
815 Case
"SFDocuments.FormControl
"
816 If Script =
"Controls
" Then vReturn = vBasicObject.Controls(vArgs(
0))
820 ' Methods in class modules may better not be executed with CallByName()
821 ElseIf bBasicClass And ((CallType And vbMethod) + (CallType And cstHardCode)) = vbMethod + cstHardCode Then
822 Select Case sServiceName
823 Case
"SFDialogs.Dialog
"
825 Case
"Activate
" : vReturn = vBasicObject.Activate()
826 Case
"Center
"
827 If UBound(vArgs)
< 0 Then vReturn = vBasicObject.Center() Else vReturn = vBasicObject.Center(vArgs(
0))
828 Case
"EndExecute
" : vReturn = vBasicObject.EndExecute(vArgs(
0))
829 Case
"Execute
" : vReturn = vBasicObject.Execute(vArgs(
0))
830 Case
"Resize
" : vReturn = vBasicObject.Resize(vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3))
834 ' Methods in class modules are invoked with CallByName
835 ElseIf bBasicClass And ((CallType And vbMethod) = vbMethod) Then
836 Select Case UBound(vArgs)
837 ' Dirty alternatives to process usual and ParamArray cases
838 ' But, up to ... how many ?
839 ' - The OFFSETADDRESSERROR has
12 arguments
840 ' - The
".uno:DataSort
" command may have
14 property name-value pairs
841 Case -
1 : vReturn = CallByName(vBasicObject, Script, vbMethod)
842 Case
0 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(
0))
843 Case
1 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(
0), vArgs(
1))
844 Case
2 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(
0), vArgs(
1), vArgs(
2))
845 Case
3 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3))
846 Case
4 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3), vArgs(
4))
847 Case
5 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3), vArgs(
4), vArgs(
5))
848 Case
6 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3), vArgs(
4), vArgs(
5), vArgs(
6))
849 Case
7 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3), vArgs(
4), vArgs(
5), vArgs(
6), vArgs(
7))
850 Case
8 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3), vArgs(
4), vArgs(
5), vArgs(
6), vArgs(
7) _
852 Case
9 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3), vArgs(
4), vArgs(
5), vArgs(
6), vArgs(
7) _
853 , vArgs(
8), vArgs(
9))
854 Case
10 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3), vArgs(
4), vArgs(
5), vArgs(
6), vArgs(
7) _
855 , vArgs(
8), vArgs(
9), vArgs(
10))
856 Case
11 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3), vArgs(
4), vArgs(
5), vArgs(
6), vArgs(
7) _
857 , vArgs(
8), vArgs(
9), vArgs(
10), vArgs(
11))
858 Case
12,
13 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3), vArgs(
4), vArgs(
5), vArgs(
6), vArgs(
7) _
859 , vArgs(
8), vArgs(
9), vArgs(
10), vArgs(
11), vArgs(
12))
860 Case
14,
15 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3), vArgs(
4), vArgs(
5), vArgs(
6), vArgs(
7) _
861 , vArgs(
8), vArgs(
9), vArgs(
10), vArgs(
11), vArgs(
12), vArgs(
13), vArgs(
14))
862 Case
16,
17 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3), vArgs(
4), vArgs(
5), vArgs(
6), vArgs(
7) _
863 , vArgs(
8), vArgs(
9), vArgs(
10), vArgs(
11), vArgs(
12), vArgs(
13), vArgs(
14), vArgs(
15), vArgs(
16))
864 Case
18,
19 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3), vArgs(
4), vArgs(
5), vArgs(
6), vArgs(
7) _
865 , vArgs(
8), vArgs(
9), vArgs(
10), vArgs(
11), vArgs(
12), vArgs(
13), vArgs(
14), vArgs(
15), vArgs(
16), vArgs(
17), vArgs(
18))
866 Case
20,
21 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3), vArgs(
4), vArgs(
5), vArgs(
6), vArgs(
7) _
867 , vArgs(
8), vArgs(
9), vArgs(
10), vArgs(
11), vArgs(
12), vArgs(
13), vArgs(
14), vArgs(
15), vArgs(
16), vArgs(
17), vArgs(
18) _
868 , vArgs(
19), vArgs(
20))
869 Case
22,
23 : 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), vArgs(
11), vArgs(
12), vArgs(
13), vArgs(
14), vArgs(
15), vArgs(
16), vArgs(
17), vArgs(
18) _
871 , vArgs(
19), vArgs(
20), vArgs(
21), vArgs(
22))
872 Case
24,
25 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3), vArgs(
4), vArgs(
5), vArgs(
6), vArgs(
7) _
873 , vArgs(
8), vArgs(
9), vArgs(
10), vArgs(
11), vArgs(
12), vArgs(
13), vArgs(
14), vArgs(
15), vArgs(
16), vArgs(
17), vArgs(
18) _
874 , vArgs(
19), vArgs(
20), vArgs(
21), vArgs(
22), vArgs(
23), vArgs(
24))
875 Case
26,
27 : 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), vArgs(
15), vArgs(
16), vArgs(
17), vArgs(
18) _
877 , vArgs(
19), vArgs(
20), vArgs(
21), vArgs(
22), vArgs(
23), vArgs(
24), vArgs(
25), vArgs(
26))
878 Case
>=
28 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(
0), vArgs(
1), vArgs(
2), vArgs(
3), vArgs(
4), vArgs(
5), vArgs(
6), vArgs(
7) _
879 , vArgs(
8), vArgs(
9), vArgs(
10), vArgs(
11), vArgs(
12), vArgs(
13), vArgs(
14), vArgs(
15), vArgs(
16), vArgs(
17), vArgs(
18) _
880 , vArgs(
19), vArgs(
20), vArgs(
21), vArgs(
22), vArgs(
23), vArgs(
24), vArgs(
25), vArgs(
26), vArgs(
27), vArgs(
28))
884 ' Post processing
885 If Script =
"Dispose
" Then
886 ' Special case: Dispose() must update the cache for class objects created in Python scripts
887 Set _SF_.PythonStorage(BasicObject) = Nothing
892 ' Format the returned array
893 vReturnArray = Array()
894 ' Distinguish: Basic object
898 If IsArray(vReturn) Then
899 ReDim vReturnArray(
0 To
2)
900 iDims = SF_Array.CountDims(vReturn)
901 ' Replace dates by UNO format
903 For i = LBound(vReturn) To UBound(vReturn)
904 If VarType(vReturn(i)) = V_DATE Then vReturn(i) = CDateToUnoDateTime(vReturn(i))
906 ElseIf iDims =
2 Then
907 For i = LBound(vReturn,
1) To UBound(vReturn,
1)
908 For j = LBound(vReturn,
2) To UBound(vReturn,
2)
909 If VarType(vReturn(i, j)) = V_DATE Then vReturn(i, j) = CDateToUnoDateTime(vReturn(i, j))
913 vReturnArray(
0) = vReturn
' 2D arrays are flattened by the script provider when returning to Python
914 vReturnArray(
1) = VarType(vReturn)
915 vReturnArray(
2) = iDims
916 ElseIf VarType(vReturn) = V_OBJECT And Not IsNull(vReturn) Then
917 ' Uno or not Uno ?
919 If (CallType And cstUno) = cstUno Then
' UNO considered only when pre-announced in CallType
920 Set oObjDesc = SF_Utils._VarTypeObj(vReturn)
921 bUno = ( oObjDesc.iVarType = V_UNOOBJECT )
924 ReDim vReturnArray(
0 To
2)
925 Set vReturnArray(
0) = vReturn
927 ReDim vReturnArray(
0 To
5)
928 vReturnArray(
0) = _SF_._AddToPythonSTorage(vReturn)
930 vReturnArray(
1) = V_OBJECT
931 vReturnArray(
2) = Iif(bUno, objUNO, Iif(bBasicClass, objCLASS, objMODULE))
933 vReturnArray(
3) = vReturn.ObjectType
934 vReturnArray(
4) = vReturn.ServiceName
935 vReturnArray(
5) =
""
936 If vReturn.ObjectType
<> "SF_CalcReference
" Then
' Calc references are implemented as a Type ... End Type data structure
937 If SF_Array.Contains(vReturn.Properties(),
"Name
", SortOrder :=
"ASC
") Then vReturnArray(
5) = vReturn.Name
940 Else
' Scalar or Nothing
941 ReDim vReturnArray(
0 To
1)
942 If VarType(vReturn) = V_DATE Then vReturnArray(
0) = CDateToUnoDateTime(vReturn) Else vReturnArray(
0) = vReturn
943 vReturnArray(
1) = VarType(vReturn)
946 _PythonDispatcher = vReturnArray
949 _SF_.TriggeredByPython = False
' Reset normal state
953 End Function
' ScriptForge.SF_PythonHelper._PythonDispatcher
955 REM -----------------------------------------------------------------------------
956 Private Function _Repr() As String
957 ''' Convert the Basic instance to a readable string, typically for debugging purposes (DebugPrint ...)
958 ''' Args:
959 ''' Return:
960 ''' "[PythonHelper]
"
962 _Repr =
"[PythonHelper]
"
964 End Function
' ScriptForge.SF_PythonHelper._Repr
966 REM ================================================= END OF SCRIPTFORGE.SF_PythonHelper