999 lines
No EOL
45 KiB
XML
999 lines
No EOL
45 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
|
|
<script:module xmlns:script="http://openoffice.org/2000/script" script:name="SF_PythonHelper" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
|
|
REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
|
|
REM === Full documentation is available on https://help.libreoffice.org/ ===
|
|
REM =======================================================================================================================
|
|
|
|
Option Compatible
|
|
Option Explicit
|
|
|
|
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
|
''' SF_PythonHelper (aka Basic)
|
|
''' ===============
|
|
''' Singleton class implementing the "ScriptForge.Basic" service
|
|
''' Implemented as a usual Basic module
|
|
'''
|
|
''' The "Basic" service must be called ONLY from a PYTHON script
|
|
''' Service invocations: Next Python code lines are equivalent:
|
|
''' bas = CreateScriptService('ScriptForge.Basic')
|
|
''' bas = CreateScriptService('Basic')
|
|
'''
|
|
''' This service proposes a collection of methods to be executed in a Python context
|
|
''' to simulate the exact behaviour of the identical Basic builtin method.
|
|
''' Typical example:
|
|
''' bas.MsgBox('This has to be displayed in a message box')
|
|
'''
|
|
''' The service includes also an agnostic "Python Dispatcher" function.
|
|
''' It dispatches Python script requests to execute Basic services to the
|
|
''' appropriate properties and methods via dynamic call techniques
|
|
'''
|
|
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
|
|
|
REM ================================================================== EXCEPTIONS
|
|
|
|
REM ============================================================ MODULE CONSTANTS
|
|
|
|
REM ===================================================== CONSTRUCTOR/DESTRUCTOR
|
|
|
|
REM -----------------------------------------------------------------------------
|
|
Public Function Dispose() As Variant
|
|
Set Dispose = Nothing
|
|
End Function ' ScriptForge.SF_PythonHelper Explicit destructor
|
|
|
|
REM ================================================================== PROPERTIES
|
|
|
|
REM -----------------------------------------------------------------------------
|
|
Property Get ObjectType As String
|
|
''' Only to enable object representation
|
|
ObjectType = "SF_PythonHelper"
|
|
End Property ' ScriptForge.SF_PythonHelper.ObjectType
|
|
|
|
REM -----------------------------------------------------------------------------
|
|
Property Get ServiceName As String
|
|
''' Internal use
|
|
ServiceName = "ScriptForge.Basic"
|
|
End Property ' ScriptForge.SF_PythonHelper.ServiceName
|
|
|
|
REM ============================================================== PUBLIC METHODS
|
|
|
|
REM -----------------------------------------------------------------------------
|
|
Public Function PyCDate(ByVal DateArg As Variant) As Variant
|
|
''' Convenient function to replicate CDate() in Python scripts
|
|
''' Args:
|
|
''' DateArg: a date as a string or as a double
|
|
''' Returns:
|
|
''' The converted date as a UNO DateTime structure
|
|
''' If the input argument could not be recognized as a date, return the argument unchanged
|
|
''' Example: (Python code)
|
|
''' a = bas.CDate('2021-02-18')
|
|
|
|
Dim vDate As Variant ' Return value
|
|
Const cstThisSub = "Basic.CDate"
|
|
Const cstSubArgs = "datearg"
|
|
|
|
On Local Error GoTo Catch
|
|
vDate = Null
|
|
|
|
Check:
|
|
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
|
|
|
Try:
|
|
vDate = CDate(DateArg)
|
|
|
|
Finally:
|
|
If VarType(vDate) = V_DATE Then PyCDate = CDateToUnoDateTime(vDate) Else PyCDate = DateArg
|
|
SF_Utils._ExitFunction(cstThisSub)
|
|
Exit Function
|
|
Catch:
|
|
On Local Error GoTo 0
|
|
GoTo Finally
|
|
End Function ' ScriptForge.SF_PythonHelper.PyCDate
|
|
|
|
REM -----------------------------------------------------------------------------
|
|
Public Function PyConvertFromUrl(ByVal FileName As Variant) As String
|
|
''' Convenient function to replicate ConvertFromUrl() in Python scripts
|
|
''' Args:
|
|
''' FileName: a string representing a file in URL format
|
|
''' Returns:
|
|
''' The same file name in native operating system notation
|
|
''' Example: (Python code)
|
|
''' a = bas.ConvertFromUrl('file:////boot.sys')
|
|
|
|
Dim sFileName As String ' Return value
|
|
Const cstThisSub = "Basic.ConvertFromUrl"
|
|
Const cstSubArgs = "filename"
|
|
|
|
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
|
sFileName = ""
|
|
|
|
Check:
|
|
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
|
|
|
Try:
|
|
sFileName = ConvertFromUrl(FileName)
|
|
|
|
Finally:
|
|
PyConvertFromUrl = sFileName
|
|
SF_Utils._ExitFunction(cstThisSub)
|
|
Exit Function
|
|
Catch:
|
|
GoTo Finally
|
|
End Function ' ScriptForge.SF_PythonHelper.PyConvertFromUrl
|
|
|
|
REM -----------------------------------------------------------------------------
|
|
Public Function PyConvertToUrl(ByVal FileName As Variant) As String
|
|
''' Convenient function to replicate ConvertToUrl() in Python scripts
|
|
''' Args:
|
|
''' FileName: a string representing a file in native operating system notation
|
|
''' Returns:
|
|
''' The same file name in URL format
|
|
''' Example: (Python code)
|
|
''' a = bas.ConvertToUrl('C:\boot.sys')
|
|
|
|
Dim sFileName As String ' Return value
|
|
Const cstThisSub = "Basic.ConvertToUrl"
|
|
Const cstSubArgs = "filename"
|
|
|
|
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
|
sFileName = ""
|
|
|
|
Check:
|
|
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
|
|
|
Try:
|
|
sFileName = ConvertToUrl(FileName)
|
|
|
|
Finally:
|
|
PyConvertToUrl = sFileName
|
|
SF_Utils._ExitFunction(cstThisSub)
|
|
Exit Function
|
|
Catch:
|
|
GoTo Finally
|
|
End Function ' ScriptForge.SF_PythonHelper.PyConvertToUrl
|
|
|
|
REM -----------------------------------------------------------------------------
|
|
Public Function PyCreateUnoService(ByVal UnoService As Variant) As Variant
|
|
''' Convenient function to replicate CreateUnoService() in Python scripts
|
|
''' Args:
|
|
''' UnoService: a string representing the service to create
|
|
''' Returns:
|
|
''' A UNO object
|
|
''' Example: (Python code)
|
|
''' a = bas.CreateUnoService('com.sun.star.i18n.CharacterClassification')
|
|
|
|
Dim vUno As Variant ' Return value
|
|
Const cstThisSub = "Basic.CreateUnoService"
|
|
Const cstSubArgs = "unoservice"
|
|
|
|
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
|
Set vUno = Nothing
|
|
|
|
Check:
|
|
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
|
|
|
Try:
|
|
Set vUno = CreateUnoService(UnoService)
|
|
|
|
Finally:
|
|
Set PyCreateUnoService = vUno
|
|
SF_Utils._ExitFunction(cstThisSub)
|
|
Exit Function
|
|
Catch:
|
|
GoTo Finally
|
|
End Function ' ScriptForge.SF_PythonHelper.PyCreateUnoService
|
|
|
|
REM -----------------------------------------------------------------------------
|
|
Public Function PyDateAdd(ByVal Add As Variant _
|
|
, ByVal Count As Variant _
|
|
, ByVal DateArg As Variant _
|
|
) As Variant
|
|
''' Convenient function to replicate DateAdd() in Python scripts
|
|
''' Args:
|
|
''' Add: The unit to add
|
|
''' Count: how many times to add (might be negative)
|
|
''' DateArg: a date as a com.sun.star.util.DateTime UNO structure
|
|
''' Returns:
|
|
''' The new date as a string in iso format
|
|
''' Example: (Python code)
|
|
''' a = bas.DateAdd('d', 1, bas.Now()) ' Tomorrow
|
|
|
|
Dim vNewDate As Variant ' Return value
|
|
Dim vDate As Date ' Alias of DateArg
|
|
Const cstThisSub = "Basic.DateAdd"
|
|
Const cstSubArgs = "add, count, datearg"
|
|
|
|
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
|
vNewDate = ""
|
|
|
|
Check:
|
|
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
|
|
|
Try:
|
|
If VarType(DateArg) = V_OBJECT Then
|
|
vDate = CDateFromUnoDateTime(DateArg)
|
|
Else
|
|
vDate = SF_Utils._CStrToDate(DateArg)
|
|
End If
|
|
vNewDate = DateAdd(Add, Count, vDate)
|
|
|
|
Finally:
|
|
If VarType(vNewDate) = V_DATE Then PyDateAdd = CDateToUnoDateTime(vNewDate) Else PyDateAdd = vNewDate
|
|
SF_Utils._ExitFunction(cstThisSub)
|
|
Exit Function
|
|
Catch:
|
|
GoTo Finally
|
|
End Function ' ScriptForge.SF_PythonHelper.PyDateAdd
|
|
|
|
REM -----------------------------------------------------------------------------
|
|
Public Function PyDateDiff(ByVal Add As Variant _
|
|
, ByVal Date1 As Variant _
|
|
, ByVal Date2 As Variant _
|
|
, ByVal WeekStart As Variant _
|
|
, ByVal YearStart As Variant _
|
|
) As Long
|
|
''' Convenient function to replicate DateDiff() in Python scripts
|
|
''' Args:
|
|
''' Add: The unit of the date interval
|
|
''' Date1, Date2: the two dates to be compared
|
|
''' WeekStart: the starting day of a week
|
|
''' YearStart: the starting week of a year
|
|
''' Returns:
|
|
''' The number of intervals expressed in Adds
|
|
''' Example: (Python code)
|
|
''' a = bas.DateDiff('d', bas.DateAdd('d', 1, bas.Now()), bas.Now()) ' -1 day
|
|
|
|
Dim lDiff As Long ' Return value
|
|
Dim vDate1 As Date ' Alias of Date1
|
|
Dim vDate2 As Date ' Alias of Date2
|
|
Const cstThisSub = "Basic.DateDiff"
|
|
Const cstSubArgs = "add, date1, date2, [weekstart=1], [yearstart=1]"
|
|
|
|
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
|
lDiff = 0
|
|
|
|
Check:
|
|
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
|
|
|
Try:
|
|
If VarType(Date1) = V_OBJECT Then
|
|
vDate1 = CDateFromUnoDateTime(Date1)
|
|
Else
|
|
vDate1 = SF_Utils._CStrToDate(Date1)
|
|
End If
|
|
If VarType(Date2) = V_OBJECT Then
|
|
vDate2 = CDateFromUnoDateTime(Date2)
|
|
Else
|
|
vDate2 = SF_Utils._CStrToDate(Date2)
|
|
End If
|
|
lDiff = DateDiff(Add, vDate1, vDate2, WeekStart, YearStart)
|
|
|
|
|
|
Finally:
|
|
PyDateDiff = lDiff
|
|
SF_Utils._ExitFunction(cstThisSub)
|
|
Exit Function
|
|
Catch:
|
|
GoTo Finally
|
|
End Function ' ScriptForge.SF_PythonHelper.PyDateDiff
|
|
|
|
REM -----------------------------------------------------------------------------
|
|
Public Function PyDatePart(ByVal Add As Variant _
|
|
, ByVal DateArg As Variant _
|
|
, ByVal WeekStart As Variant _
|
|
, ByVal YearStart As Variant _
|
|
) As Long
|
|
''' Convenient function to replicate DatePart() in Python scripts
|
|
''' Args:
|
|
''' Add: The unit of the date interval
|
|
''' DateArg: The date from which to extract a part
|
|
''' WeekStart: the starting day of a week
|
|
''' YearStart: the starting week of a year
|
|
''' Returns:
|
|
''' The specified part of the date
|
|
''' Example: (Python code)
|
|
''' a = bas.DatePart('y', bas.Now()) ' day of year
|
|
|
|
Dim lPart As Long ' Return value
|
|
Dim vDate As Date ' Alias of DateArg
|
|
Const cstThisSub = "Basic.DatePart"
|
|
Const cstSubArgs = "add, datearg, [weekstart=1], [yearstart=1]"
|
|
|
|
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
|
lPart = 0
|
|
|
|
Check:
|
|
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
|
|
|
Try:
|
|
If VarType(DateArg) = V_OBJECT Then
|
|
vDate = CDateFromUnoDateTime(DateArg)
|
|
Else
|
|
vDate = SF_Utils._CStrToDate(DateArg)
|
|
End If
|
|
lPart = DatePart(Add, vDate, WeekStart, YearStart)
|
|
|
|
|
|
Finally:
|
|
PyDatePart = lPart
|
|
SF_Utils._ExitFunction(cstThisSub)
|
|
Exit Function
|
|
Catch:
|
|
GoTo Finally
|
|
End Function ' ScriptForge.SF_PythonHelper.PyDatePart
|
|
|
|
REM -----------------------------------------------------------------------------
|
|
Public Function PyDateValue(ByVal DateArg As Variant) As Variant
|
|
''' Convenient function to replicate DateValue() in Python scripts
|
|
''' Args:
|
|
''' DateArg: a date as a string
|
|
''' Returns:
|
|
''' The converted date as a UNO DateTime structure
|
|
''' Example: (Python code)
|
|
''' a = bas.DateValue('2021-02-18')
|
|
|
|
Dim vDate As Variant ' Return value
|
|
Const cstThisSub = "Basic.DateValue"
|
|
Const cstSubArgs = "datearg"
|
|
|
|
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
|
vDate = ""
|
|
|
|
Check:
|
|
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
|
|
|
Try:
|
|
vDate = DateValue(DateArg)
|
|
|
|
Finally:
|
|
If VarType(vDate) = V_DATE Then PyDateValue = CDateToUnoDateTime(vDate) Else PyDateValue = vDate
|
|
SF_Utils._ExitFunction(cstThisSub)
|
|
Exit Function
|
|
Catch:
|
|
GoTo Finally
|
|
End Function ' ScriptForge.SF_PythonHelper.PyDateValue
|
|
|
|
REM -----------------------------------------------------------------------------
|
|
Public Function PyFormat(ByVal Value As Variant _
|
|
, ByVal Pattern As Variant _
|
|
) As String
|
|
''' Convenient function to replicate Format() in Python scripts
|
|
''' Args:
|
|
''' Value: a date or a number
|
|
''' Pattern: the format to apply
|
|
''' Returns:
|
|
''' The formatted value
|
|
''' Example: (Python code)
|
|
''' MsgBox bas.Format(6328.2, '##,##0.00')
|
|
|
|
Dim sFormat As String ' Return value
|
|
Dim vValue As Variant ' Alias of Value
|
|
Const cstThisSub = "Basic.Format"
|
|
Const cstSubArgs = "value, pattern"
|
|
|
|
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
|
sFormat = ""
|
|
|
|
Check:
|
|
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
|
|
|
Try:
|
|
If VarType(Value) = V_OBJECT Then vValue = CDateFromUnoDateTime(Value) ELse vValue = Value
|
|
If IsEmpty(Pattern) Or Len(Pattern) = 0 Then sFormat = Str(vValue) Else sFormat = Format(vValue, Pattern)
|
|
|
|
|
|
Finally:
|
|
PyFormat = sFormat
|
|
SF_Utils._ExitFunction(cstThisSub)
|
|
Exit Function
|
|
Catch:
|
|
GoTo Finally
|
|
End Function ' ScriptForge.SF_PythonHelper.PyFormat
|
|
|
|
REM -----------------------------------------------------------------------------
|
|
Public Function PyGetGuiType() As Integer
|
|
''' Convenient function to replicate GetGuiType() in Python scripts
|
|
''' Args:
|
|
''' Returns:
|
|
''' The GetGuiType value
|
|
''' Example: (Python code)
|
|
''' MsgBox bas.GetGuiType()
|
|
|
|
Const cstThisSub = "Basic.GetGuiType"
|
|
Const cstSubArgs = ""
|
|
|
|
Check:
|
|
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
|
|
|
Try:
|
|
PyGetGuiType = GetGuiType()
|
|
|
|
|
|
Finally:
|
|
SF_Utils._ExitFunction(cstThisSub)
|
|
Exit Function
|
|
End Function ' ScriptForge.SF_PythonHelper.PyGetGuiType
|
|
|
|
REM -----------------------------------------------------------------------------
|
|
Public Function PyGetSystemTicks() As Long
|
|
''' Convenient function to replicate GetSystemTicks() in Python scripts
|
|
''' Args:
|
|
''' Returns:
|
|
''' The GetSystemTicks value
|
|
''' Example: (Python code)
|
|
''' MsgBox bas.GetSystemTicks()
|
|
|
|
Const cstThisSub = "Basic.GetSystemTicks"
|
|
Const cstSubArgs = ""
|
|
|
|
Check:
|
|
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
|
|
|
Try:
|
|
PyGetSystemTicks = GetSystemTicks()
|
|
|
|
|
|
Finally:
|
|
SF_Utils._ExitFunction(cstThisSub)
|
|
Exit Function
|
|
End Function ' ScriptForge.SF_PythonHelper.PyGetSystemTicks
|
|
|
|
REM -----------------------------------------------------------------------------
|
|
Public Function PyGlobalScope(ByVal Library As Variant) As Object
|
|
''' Convenient function to replicate GlobalScope() in Python scripts
|
|
''' Args:
|
|
''' Library: "Basic" or "Dialog"
|
|
''' Returns:
|
|
''' The GlobalScope value
|
|
''' Example: (Python code)
|
|
''' MsgBox bas.GlobalScope.BasicLibraries()
|
|
|
|
Const cstThisSub = "Basic.GlobalScope.BasicLibraries" ' or DialogLibraries
|
|
Const cstSubArgs = ""
|
|
|
|
Check:
|
|
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
|
|
|
Try:
|
|
Select Case Library
|
|
Case "Basic"
|
|
PyGlobalScope = GlobalScope.BasicLibraries()
|
|
Case "Dialog"
|
|
PyGlobalScope = GlobalScope.DialogLibraries()
|
|
Case Else
|
|
End Select
|
|
|
|
Finally:
|
|
SF_Utils._ExitFunction(cstThisSub)
|
|
Exit Function
|
|
End Function ' ScriptForge.SF_PythonHelper.PyGlobalScope
|
|
|
|
REM -----------------------------------------------------------------------------
|
|
Public Function PyInputBox(ByVal Msg As Variant _
|
|
, ByVal Title As Variant _
|
|
, ByVal Default As Variant _
|
|
, Optional ByVal XPosTwips As Variant _
|
|
, Optional ByVal YPosTwips As Variant _
|
|
) As String
|
|
''' Convenient function to replicate InputBox() in Python scripts
|
|
''' Args:
|
|
''' Msg: String expression displayed as the message in the dialog box
|
|
''' Title: String expression displayed in the title bar of the dialog box
|
|
''' Default: String expression displayed in the text box as default if no other input is given
|
|
''' XPosTwips: Integer expression that specifies the horizontal position of the dialog
|
|
''' YPosTwips: Integer expression that specifies the vertical position of the dialog
|
|
''' If XPosTwips and YPosTwips are omitted, the dialog is centered on the screen
|
|
''' The position is specified in twips.
|
|
''' Returns:
|
|
''' The entered value or "" if the user pressed the Cancel button
|
|
''' Example: (Python code)
|
|
''' a = bas.InputBox ('Please enter a phrase:', 'Dear User')
|
|
|
|
Dim sInput As String ' Return value
|
|
Const cstThisSub = "Basic.InputBox"
|
|
Const cstSubArgs = "msg, [title=''], [default=''], [xpostwips], [ypostwips]"
|
|
|
|
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
|
sInput = ""
|
|
|
|
Check:
|
|
If IsMissing(YPosTwips) Then YPosTwips = 1
|
|
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
|
|
|
Try:
|
|
If IsMissing(XPosTwips) Then
|
|
sInput = InputBox(Msg, Title, Default)
|
|
Else
|
|
sInput = InputBox(Msg, Title, Default, XPosTwips, YPosTwips)
|
|
End If
|
|
|
|
Finally:
|
|
PyInputBox = sInput
|
|
SF_Utils._ExitFunction(cstThisSub)
|
|
Exit Function
|
|
Catch:
|
|
GoTo Finally
|
|
End Function ' ScriptForge.SF_PythonHelper.PyInputBox
|
|
|
|
REM -----------------------------------------------------------------------------
|
|
Public Function PyMsgBox(ByVal Text As Variant _
|
|
, ByVal DialogType As Variant _
|
|
, ByVal DialogTitle As Variant _
|
|
) As Integer
|
|
''' Convenient function to replicate MsgBox() in Python scripts
|
|
''' Args:
|
|
''' Text: String expression displayed as a message in the dialog box
|
|
''' DialogType: Any integer expression that defines the number and type of buttons or icons displayed
|
|
''' DialogTitle: String expression displayed in the title bar of the dialog
|
|
''' Returns:
|
|
''' The pressed button
|
|
''' Example: (Python code)
|
|
''' a = bas.MsgBox ('Please press a button:', bas.MB_EXCLAMATION, 'Dear User')
|
|
|
|
Dim iMsg As Integer ' Return value
|
|
Const cstThisSub = "Basic.MsgBox"
|
|
Const cstSubArgs = "text, [dialogtype=0], [dialogtitle]"
|
|
|
|
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
|
iMsg = -1
|
|
|
|
Check:
|
|
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
|
|
|
Try:
|
|
iMsg = MsgBox(Text, DialogType, DialogTitle)
|
|
|
|
Finally:
|
|
PyMsgBox = iMsg
|
|
SF_Utils._ExitFunction(cstThisSub)
|
|
Exit Function
|
|
Catch:
|
|
GoTo Finally
|
|
End Function ' ScriptForge.SF_PythonHelper.PyMsgBox
|
|
|
|
REM ============================================================= PRIVATE METHODS
|
|
|
|
REM -----------------------------------------------------------------------------
|
|
Public Function _PythonDispatcher(ByRef BasicObject As Variant _
|
|
, ByVal CallType As Variant _
|
|
, ByVal Script As Variant _
|
|
, ParamArray Args() As Variant _
|
|
) As Variant
|
|
''' Called from Python only
|
|
''' The method calls the method Script associated with the BasicObject class or module
|
|
''' with the given arguments
|
|
''' The invocation of the method can be a Property Get, Property Let or a usual call
|
|
''' NB: arguments and return values must not be 2D arrays
|
|
''' The implementation intends to be as AGNOSTIC as possible in terms of objects nature and methods called
|
|
''' The method returns the value effectively returned by the called component,
|
|
''' completed with additional metadata. The whole is packaged in a 1D array.
|
|
''' Args:
|
|
''' BasicObject: a module or a class instance - May also be the reserved string: "SF_Services"
|
|
''' CallType: one of the constants applicable to a CallByName statement + optional protocol flags
|
|
''' Script: the name of the method or property
|
|
''' Args: the arguments to pass to the method. Input arguments can contain symbolic constants for Null, Missing, etc.
|
|
''' Returns:
|
|
''' A 1D array:
|
|
''' [0] The returned value - scalar, object or 1D array
|
|
''' [1] The VarType() of the returned value
|
|
''' Null, Empty and Nothing have different vartypes but return all None to Python
|
|
''' Additionally, when array:
|
|
''' [2] Number of dimensions in Basic
|
|
''' Additionally, when Basic object:
|
|
''' [2] Module (1), Class instance (2) or UNO (3)
|
|
''' [3] The object's ObjectType
|
|
''' [4] The object's service name
|
|
''' [5] The object's name
|
|
''' When an error occurs Python receives None as a scalar. This determines the occurrence of a failure
|
|
|
|
Dim vReturn As Variant ' The value returned by the invoked property or method
|
|
Dim vReturnArray As Variant ' Return value
|
|
Dim vBasicObject As Variant ' Alias of BasicObject to avoid "Object reference not set" error
|
|
Dim iNbArgs As Integer ' Number of valid input arguments
|
|
Dim vArg As Variant ' Alias for a single argument
|
|
Dim vArgs() As Variant ' Alias for Args()
|
|
Dim sScript As String ' Argument of ExecuteBasicScript()
|
|
Dim vParams As Variant ' Array of arguments to pass to a ParamArray
|
|
Dim sObjectType As String ' Alias of object.ObjectType
|
|
Dim sServiceName As String ' Alias of BasicObject.ServiceName
|
|
Dim bBasicClass As Boolean ' True when BasicObject is a class
|
|
Dim sLibrary As String ' Library where the object belongs to
|
|
Dim bUno As Boolean ' Return value is a UNO object
|
|
Dim bDict As Boolean ' Return value is a Basic SF_Dictionary class instance
|
|
Dim oDict As Object ' SF_Dictionary class instance
|
|
Dim oObjDesc As Object ' _ObjectDescriptor type
|
|
Dim iDims As Integer ' # of dims of vReturn when array
|
|
Dim sess As Object : Set sess = ScriptForge.SF_Session
|
|
Dim i As Long, j As Long
|
|
|
|
' Conventional special input or output values
|
|
Const cstNoArgs = "+++NOARGS+++", cstSymEmpty = "+++EMPTY+++", cstSymNull = "+++NULL+++", cstSymMissing = "+++MISSING+++"
|
|
|
|
' https://support.office.com/en-us/article/CallByName-fonction-49ce9475-c315-4f13-8d35-e98cfe98729a
|
|
' Determines the CallType
|
|
Const vbGet = 2, vbLet = 4, vbMethod = 1, vbSet = 8
|
|
' Protocol flags
|
|
Const cstPost = 16 ' Requires a hardcoded post-processing
|
|
Const cstDictArg = 32 ' May contain a Dictionary argument
|
|
Const cstDateArg = 64 ' May contain a date argument
|
|
Const cstDateRet = 128 ' Return value can be a date
|
|
Const cstUno = 256 ' Return value can be a UNO object
|
|
Const cstArgArray = 512 ' Any argument can be a 2D array
|
|
Const cstRetArray = 1024 ' Return value can be an array
|
|
Const cstObject = 2048 ' 1st argument is a Basic object when numeric
|
|
Const cstHardCode = 4096 ' Method must not be executed with CallByName()
|
|
' Returned object nature
|
|
Const objMODULE = 1, objCLASS = 2, objDICT = 3, objUNO = 4
|
|
|
|
Check:
|
|
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
|
_PythonDispatcher = Null
|
|
|
|
' Ignore Null basic objects (Null = Null or Nothing)
|
|
If IsNull(BasicObject) Or IsEmpty(BasicObject) Then GoTo Catch
|
|
|
|
' Reinterpret arguments one by one into vArgs
|
|
' - convert UNO dates/times
|
|
' - identify conventional NoArgs/Empty/Null/Missing constants
|
|
' - convert arrays of property values into Dictionary
|
|
iNbArgs = -1
|
|
vArgs = Array()
|
|
|
|
If UBound(Args) >= 0 Then
|
|
For i = 0 To UBound(Args)
|
|
vArg = Args(i)
|
|
' Are there arguments ?
|
|
If i = 0 And VarType(vArg) = V_STRING Then
|
|
If vArg = cstNoArgs Then Exit For
|
|
End If
|
|
' Is 1st argument a reference to a Basic object ?
|
|
If i = 0 And (( CallType And cstObject ) = cstObject) And SF_Utils._VarTypeExt(vArg) = V_NUMERIC Then
|
|
If vArg < 0 Or Not IsArray(_SF_.PythonStorage) Then GoTo Catch
|
|
If vArg > UBound(_SF_.PythonStorage) Then GoTo Catch
|
|
vArg = _SF_.PythonStorage(vArg)
|
|
' Is argument a symbolic constant for Null, Empty, ... , or a date, or a dictionary ?
|
|
ElseIf VarType(vArg) = V_STRING Then
|
|
If Len(vArg) = 0 Then
|
|
ElseIf vArg = cstSymEmpty Then
|
|
vArg = Empty
|
|
ElseIf vArg = cstSymNull Then
|
|
vArg = Null
|
|
ElseIf vArg = cstSymMissing Then
|
|
Exit For ' Next arguments must be missing also
|
|
End If
|
|
ElseIf VarType(vArg) = V_OBJECT Then
|
|
If ( CallType And cstDateArg ) = cstDateArg Then vArg = CDateFromUnoDateTime(vArg)
|
|
ElseIf ( CallType And cstDictArg ) = cstDictArg Then
|
|
If IsArray(vArg) Then
|
|
If UBound(vArg) >= 0 Then
|
|
If sess.UnoObjectType(vArg(0)) = "com.sun.star.beans.PropertyValue" Then
|
|
' Create a dictionary - keys in Python dicts are case-sensitive
|
|
Set oDict = CreateScriptService("ScriptForge.Dictionary", True)
|
|
oDict.ImportFromPropertyValues(vArg, Overwrite := True)
|
|
vArg = oDict
|
|
End If
|
|
End If
|
|
End If
|
|
End If
|
|
iNbArgs = iNbArgs + 1
|
|
|
|
ReDim Preserve vArgs(iNbArgs)
|
|
vArgs(iNbArgs) = vArg
|
|
Next i
|
|
End If
|
|
|
|
Try:
|
|
' Dispatching strategy: based on next constraints
|
|
' (1) Bug https://bugs.documentfoundation.org/show_bug.cgi?id=138155
|
|
' The CallByName function fails when returning an array
|
|
' (2) Python has tuples and tuple of tuples, not 2D arrays
|
|
' (3) Passing 2D arrays through a script provider always transform it into a sequence of sequences
|
|
' (4) The CallByName function takes exclusive control on the targeted object up to its exit
|
|
' (5) A script provider returns a Basic Date variable as Empty
|
|
' RULES:
|
|
' 1. All methods in any module are invoked with CallByName
|
|
' 2. Properties in any service are got and set with obj.GetProperty/SetProperty(...)
|
|
' EXCEPTIONS:
|
|
' 3. Methods in usual modules are called by ExecuteBasicScript() when they manipulate arrays
|
|
' 4. Methods in class modules using a 2D array or returning arrays, or methods using ParamArray,
|
|
''' are hardcoded as exceptions or are not implemented
|
|
' 5. Due to constraint (4), a predefined list of method calls must be hardcoded to avoid blocking use of CallByName
|
|
' The concerned methods are flagged with cstHardCode
|
|
|
|
With _SF_
|
|
' Initialize Python persistent storage at 1st call
|
|
If IsEmpty(.PythonStorage) Then ._InitPythonStorage()
|
|
' Reset any error
|
|
._Stackreset()
|
|
' Set Python trigger to manage signatures in error messages
|
|
.TriggeredByPython = True
|
|
End With
|
|
|
|
Select case VarType(BasicObject)
|
|
Case V_STRING
|
|
' Special entry for CreateScriptService()
|
|
vBasicObject = BasicObject
|
|
If vBasicObject = "SF_Services" Then
|
|
If UBound(vArgs) = 0 Then vParams = Array() Else vParams = SF_Array.Slice(vArgs, 1)
|
|
Select Case UBound(vParams)
|
|
Case -1 : vReturn = SF_Services.CreateScriptService(vArgs(0))
|
|
Case 0 : vReturn = SF_Services.CreateScriptService(vArgs(0), vParams(0))
|
|
Case 1 : vReturn = SF_Services.CreateScriptService(vArgs(0), vParams(0), vParams(1))
|
|
Case 2 : vReturn = SF_Services.CreateScriptService(vArgs(0), vParams(0), vParams(1), vParams(2))
|
|
Case 3 : vReturn = SF_Services.CreateScriptService(vArgs(0), vParams(0), vParams(1), vParams(2), vParams(3))
|
|
Case 4 : vReturn = SF_Services.CreateScriptService(vArgs(0), vParams(0), vParams(1), vParams(2), vParams(3), vParams(4))
|
|
End Select
|
|
End If
|
|
If VarType(vReturn) = V_OBJECT And Not IsNull(vReturn) Then
|
|
vBasicObject = vReturn
|
|
sObjectType = vBasicObject.ObjectType
|
|
bBasicClass = ( Left(sObjectType, 3) <> "SF_" )
|
|
End If
|
|
|
|
' Implement dispatching strategy
|
|
Case V_INTEGER
|
|
If BasicObject < 0 Or Not IsArray(_SF_.PythonStorage) Then GoTo Catch
|
|
If BasicObject > UBound(_SF_.PythonStorage) Then GoTo Catch
|
|
vBasicObject = _SF_.PythonStorage(BasicObject)
|
|
sObjectType = vBasicObject.ObjectType
|
|
sServiceName = vBasicObject.ServiceName
|
|
|
|
' Basic modules have type = "SF_*"
|
|
bBasicClass = ( Left(sObjectType, 3) <> "SF_" )
|
|
sLibrary = Split(sServiceName, ".")(0)
|
|
|
|
' Methods in standard modules are called by ExecuteBasicScript() when arrays are returned
|
|
If Not bBasicClass And (CallType And vbMethod) = vbMethod And (CallType And cstRetArray) = cstRetArray Then
|
|
sScript = sLibrary & "." & sObjectType & "." & Script
|
|
' Force validation in targeted function, not in ExecuteBasicScript()
|
|
_SF_.StackLevel = -1
|
|
Select Case UBound(vArgs)
|
|
Case -1 : vReturn = sess.ExecuteBasicScript(, sScript)
|
|
Case 0 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0))
|
|
Case 1 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1))
|
|
Case 2 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2))
|
|
Case 3 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2), vArgs(3))
|
|
Case 4 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4))
|
|
Case 5 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5))
|
|
Case 6 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6))
|
|
Case 7 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7))
|
|
End Select
|
|
_SF_.StackLevel = 0
|
|
|
|
' Properties in any service are got and set with obj.GetProperty/SetProperty(...)
|
|
ElseIf (CallType And vbGet) = vbGet Then ' In some cases (Calc ...) GetProperty may have an argument
|
|
If UBound(vArgs) < 0 Then vReturn = vBasicObject.GetProperty(Script) Else vReturn = vBasicObject.GetProperty(Script, vArgs(0))
|
|
ElseIf (CallType And vbLet) = vbLet Then
|
|
vReturn = vBasicObject.SetProperty(Script, vArgs(0))
|
|
|
|
' Methods in class modules using a 2D array or returning arrays are hardcoded as exceptions. Bug #138155
|
|
ElseIf ((CallType And vbMethod) + (CallType And cstArgArray)) = vbMethod + cstArgArray Or _
|
|
((CallType And vbMethod) + (CallType And cstRetArray)) = vbMethod + cstRetArray Then
|
|
If Script = "Methods" Then
|
|
vReturn = vBasicObject.Methods()
|
|
ElseIf Script = "Properties" Then
|
|
vReturn = vBasicObject.Properties()
|
|
Else
|
|
Select Case sServiceName
|
|
Case "SFDatabases.Database"
|
|
If Script = "GetRows" Then vReturn = vBasicObject.GetRows(vArgs(0), vArgs(1), vArgs(2), vArgs(3))
|
|
Case "SFDatabases.Dataset"
|
|
If Script = "GetRows" Then vReturn = vBasicObject.GetRows(vArgs(0), vArgs(1))
|
|
Case "SFDialogs.Dialog"
|
|
If Script = "Controls" Then vReturn = vBasicObject.Controls(vArgs(0))
|
|
Case "SFDialogs.DialogControl"
|
|
If Script = "SetTableData" Then vReturn = vBasicObject.SetTableData(vArgs(0), vArgs(1), vArgs(2))
|
|
Case "SFDocuments.Document"
|
|
Select Case Script
|
|
Case "ContextMenus" : vReturn = vBasicObject.ContextMenus(vArgs(0), vArgs(1))
|
|
Case "Forms" : vReturn = vBasicObject.Forms(vArgs(0))
|
|
Case "Styles" : vReturn = vBasicObject.Styles(vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5))
|
|
Case "Toolbars" : vReturn = vBasicObject.Toolbars(vArgs(0))
|
|
End Select
|
|
Case "SFDocuments.Base"
|
|
Select Case Script
|
|
Case "ContextMenus" : vReturn = vBasicObject.ContextMenus(vArgs(0), vArgs(1))
|
|
Case "FormDocuments" : vReturn = vBasicObject.FormDocuments()
|
|
Case "Forms" : vReturn = vBasicObject.Forms(vArgs(0), vArgs(1))
|
|
Case "Toolbars" : vReturn = vBasicObject.Toolbars(vArgs(0))
|
|
End Select
|
|
Case "SFDocuments.Calc"
|
|
Select Case Script
|
|
Case "Charts" : vReturn = vBasicObject.Charts(vArgs(0), vArgs(1))
|
|
Case "ContextMenus" : vReturn = vBasicObject.ContextMenus(vArgs(0), vArgs(1))
|
|
Case "Forms" : vReturn = vBasicObject.Forms(vArgs(0), vArgs(1))
|
|
Case "GetFormula" : vReturn = vBasicObject.GetFormula(vArgs(0))
|
|
Case "GetValue" : vReturn = vBasicObject.GetValue(vArgs(0))
|
|
Case "SetArray" : vReturn = vBasicObject.SetArray(vArgs(0), vArgs(1))
|
|
Case "SetFormula" : vReturn = vBasicObject.SetFormula(vArgs(0), vArgs(1))
|
|
Case "SetValue" : vReturn = vBasicObject.SetValue(vArgs(0), vArgs(1))
|
|
Case "Styles" : vReturn = vBasicObject.Styles(vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5))
|
|
Case "Toolbars" : vReturn = vBasicObject.Toolbars(vArgs(0))
|
|
End Select
|
|
Case "SFDocuments.Form"
|
|
Select Case Script
|
|
Case "Controls" : vReturn = vBasicObject.Controls(vArgs(0))
|
|
Case "Subforms" : vReturn = vBasicObject.Subforms(vArgs(0))
|
|
End Select
|
|
Case "SFDocuments.FormControl"
|
|
If Script = "Controls" Then vReturn = vBasicObject.Controls(vArgs(0))
|
|
Case "SFDocuments.FormDocument"
|
|
Select Case Script
|
|
Case "ContextMenus" : vReturn = vBasicObject.ContextMenus(vArgs(0), vArgs(1))
|
|
Case "Forms" : vReturn = vBasicObject.Forms(vArgs(0))
|
|
Case "Toolbars" : vReturn = vBasicObject.Toolbars(vArgs(0))
|
|
End Select
|
|
Case "SFDocuments.Writer"
|
|
Select Case Script
|
|
Case "ContextMenus" : vReturn = vBasicObject.ContextMenus(vArgs(0), vArgs(1))
|
|
Case "Forms" : vReturn = vBasicObject.Forms(vArgs(0))
|
|
Case "Styles" : vReturn = vBasicObject.Styles(vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5))
|
|
Case "Toolbars" : vReturn = vBasicObject.Toolbars(vArgs(0))
|
|
End Select
|
|
Case "SFWidgets.Toolbar"
|
|
Select Case Script
|
|
Case "ToolbarButtons" : vReturn = vBasicObject.ToolbarButtons(vArgs(0))
|
|
End Select
|
|
End Select
|
|
End If
|
|
|
|
' Specific methods in class modules may better not be executed with CallByName() because they do not return immediately
|
|
ElseIf bBasicClass And ((CallType And vbMethod) + (CallType And cstHardCode)) = vbMethod + cstHardCode Then
|
|
Select Case sServiceName
|
|
Case "SFDialogs.Dialog"
|
|
Select Case Script
|
|
Case "Execute" : vReturn = vBasicObject.Execute(vArgs(0))
|
|
End Select
|
|
End Select
|
|
|
|
' Methods in all modules are invoked with CallByName
|
|
ElseIf ((CallType And vbMethod) = vbMethod) Then
|
|
Select Case UBound(vArgs)
|
|
' Dirty alternatives to process usual and ParamArray cases
|
|
' But, up to ... how many ?
|
|
' - The OFFSETADDRESSERROR has 12 arguments
|
|
' - The ".uno:DataSort" command may have 14 property name-value pairs
|
|
Case -1 : vReturn = CallByName(vBasicObject, Script, vbMethod)
|
|
Case 0 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0))
|
|
Case 1 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1))
|
|
Case 2 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2))
|
|
Case 3 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3))
|
|
Case 4 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4))
|
|
Case 5 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5))
|
|
Case 6 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6))
|
|
Case 7 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7))
|
|
Case 8 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
|
, vArgs(8))
|
|
Case 9 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
|
, vArgs(8), vArgs(9))
|
|
Case 10 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
|
, vArgs(8), vArgs(9), vArgs(10))
|
|
Case 11 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
|
, vArgs(8), vArgs(9), vArgs(10), vArgs(11))
|
|
Case 12, 13 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
|
, vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12))
|
|
Case 14, 15 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
|
, vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14))
|
|
Case 16, 17 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
|
, vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16))
|
|
Case 18, 19 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
|
, vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16), vArgs(17), vArgs(18))
|
|
Case 20, 21 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
|
, vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16), vArgs(17), vArgs(18) _
|
|
, vArgs(19), vArgs(20))
|
|
Case 22, 23 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
|
, vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16), vArgs(17), vArgs(18) _
|
|
, vArgs(19), vArgs(20), vArgs(21), vArgs(22))
|
|
Case 24, 25 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
|
, vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16), vArgs(17), vArgs(18) _
|
|
, vArgs(19), vArgs(20), vArgs(21), vArgs(22), vArgs(23), vArgs(24))
|
|
Case 26, 27 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
|
, vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16), vArgs(17), vArgs(18) _
|
|
, vArgs(19), vArgs(20), vArgs(21), vArgs(22), vArgs(23), vArgs(24), vArgs(25), vArgs(26))
|
|
Case >= 28 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
|
, vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16), vArgs(17), vArgs(18) _
|
|
, vArgs(19), vArgs(20), vArgs(21), vArgs(22), vArgs(23), vArgs(24), vArgs(25), vArgs(26), vArgs(27), vArgs(28))
|
|
End Select
|
|
End If
|
|
|
|
' Post processing
|
|
If (CallType And cstPost) = cstPost Then
|
|
If Script = "Dispose" Then
|
|
' Special case: Dispose() must update the cache for class objects created in Python scripts
|
|
Set _SF_.PythonStorage(BasicObject) = Nothing
|
|
End If
|
|
End If
|
|
Case Else
|
|
End Select
|
|
|
|
' Format the returned array
|
|
vReturnArray = Array()
|
|
' Distinguish: Basic object
|
|
' UNO object
|
|
' Dictionary
|
|
' Array
|
|
' Scalar
|
|
If IsArray(vReturn) Then
|
|
ReDim vReturnArray(0 To 2)
|
|
iDims = SF_Array.CountDims(vReturn)
|
|
' Replace dates by UNO format
|
|
If iDims = 1 Then
|
|
For i = LBound(vReturn) To UBound(vReturn)
|
|
If VarType(vReturn(i)) = V_DATE Then vReturn(i) = CDateToUnoDateTime(vReturn(i))
|
|
Next i
|
|
ElseIf iDims = 2 Then
|
|
For i = LBound(vReturn, 1) To UBound(vReturn, 1)
|
|
For j = LBound(vReturn, 2) To UBound(vReturn, 2)
|
|
If VarType(vReturn(i, j)) = V_DATE Then vReturn(i, j) = CDateToUnoDateTime(vReturn(i, j))
|
|
Next j
|
|
Next i
|
|
End If
|
|
vReturnArray(0) = vReturn ' 2D arrays are flattened by the script provider when returning to Python
|
|
vReturnArray(1) = VarType(vReturn)
|
|
vReturnArray(2) = iDims
|
|
ElseIf VarType(vReturn) = V_OBJECT And Not IsNull(vReturn) Then
|
|
' Uno or not Uno ?
|
|
bUno = False
|
|
If (CallType And cstUno) = cstUno Then ' UNO considered only when pre-announced in CallType
|
|
Set oObjDesc = SF_Utils._VarTypeObj(vReturn)
|
|
bUno = ( oObjDesc.iVarType = V_UNOOBJECT )
|
|
End If
|
|
If bUno Then
|
|
ReDim vReturnArray(0 To 2)
|
|
Set vReturnArray(0) = vReturn
|
|
Else
|
|
ReDim vReturnArray(0 To 5)
|
|
bDict = ( vReturn.ObjectType = "DICTIONARY" )
|
|
If bDict Then
|
|
vReturnArray(0) = vReturn.ConvertToPropertyValues()
|
|
Else
|
|
vReturnArray(0) = _SF_._AddToPythonSTorage(vReturn)
|
|
End If
|
|
End If
|
|
vReturnArray(1) = V_OBJECT
|
|
Select Case True
|
|
Case bUno : vReturnArray(2) = objUNO
|
|
Case bDict : vReturnArray(2) = objDICT
|
|
Case bBasicClass : vReturnArray(2) = objCLASS
|
|
Case Else : vReturnArray(2) = objMODULE
|
|
End Select
|
|
If Not bUno Then
|
|
vReturnArray(3) = vReturn.ObjectType
|
|
vReturnArray(4) = vReturn.ServiceName
|
|
vReturnArray(5) = ""
|
|
If vReturn.ObjectType <> "SF_CalcReference" And Not bDict Then ' Calc references are implemented as a Type ... End Type data structure
|
|
If SF_Array.Contains(vReturn.Properties(), "Name", SortOrder := "ASC") Then vReturnArray(5) = vReturn.Name
|
|
End If
|
|
End If
|
|
Else ' Scalar or Nothing
|
|
ReDim vReturnArray(0 To 1)
|
|
If VarType(vReturn) = V_DATE Then vReturnArray(0) = CDateToUnoDateTime(vReturn) Else vReturnArray(0) = vReturn
|
|
vReturnArray(1) = VarType(vReturn)
|
|
End If
|
|
|
|
' Tests with non-modal dialogs and sleeping (time.sleep) Python processes show
|
|
' a more fluid reactivity when next statement is present, at a minimal cost.
|
|
Wait 0
|
|
|
|
_PythonDispatcher = vReturnArray
|
|
|
|
Finally:
|
|
_SF_.TriggeredByPython = False ' Reset normal state
|
|
Exit Function
|
|
Catch:
|
|
GoTo Finally
|
|
End Function ' ScriptForge.SF_PythonHelper._PythonDispatcher
|
|
|
|
REM -----------------------------------------------------------------------------
|
|
Private Function _Repr() As String
|
|
''' Convert the Basic instance to a readable string, typically for debugging purposes (DebugPrint ...)
|
|
''' Args:
|
|
''' Return:
|
|
''' "[PythonHelper]"
|
|
|
|
_Repr = "[PythonHelper]"
|
|
|
|
End Function ' ScriptForge.SF_PythonHelper._Repr
|
|
|
|
REM ================================================= END OF SCRIPTFORGE.SF_PythonHelper
|
|
</script:module> |