ScriptForge Extend Python-Basic gateway for objects
A Python ScriptForge object may be passed to Basic functions, so far only when it is positioned as the first argument in the method signature. Like in: dialogB.Center(dialogA) The actual commit extends the protocol between Python and Basic to allow passing Python objects from another position in the method signature. However this possibility is limited to maximum 1 such argument. (Note that removing this limitation, if ever needed, would not require a big change.) No impact on user existing scripts. No documentation update. Change-Id: I191b7bb7c32b158b7274815577349ddfa1406b93 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190931 Tested-by: Jenkins Reviewed-by: Jean-Pierre Ledure <jp@ledure.be>
This commit is contained in:
@@ -603,6 +603,9 @@ Public Function _PythonDispatcher(ByRef BasicObject As Variant _
|
||||
''' 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
|
||||
''' When CallType is an array (applicable when CallType includes cstObject)
|
||||
''' CallType[0] = CallType scalar
|
||||
''' CallType[1] = argument index on which to apply the scalar value
|
||||
''' 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:
|
||||
@@ -621,6 +624,8 @@ Public Function _PythonDispatcher(ByRef BasicObject As Variant _
|
||||
|
||||
Dim vReturn As Variant ' The value returned by the invoked property or method
|
||||
Dim vReturnArray As Variant ' Return value
|
||||
Dim iCallType As Integer ' Alias of CallType
|
||||
Dim iArgIndex As Integer ' Index companion when CallType is an array
|
||||
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
|
||||
@@ -653,7 +658,8 @@ 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 cstObject = 2048 ' n-th argument is a Basic object when numeric
|
||||
' n (default = 0) can be passed as companion in an array
|
||||
Const cstHardCode = 4096 ' Method must not be executed with CallByName()
|
||||
' Returned object nature
|
||||
Const objMODULE = 1, objCLASS = 2, objDICT = 3, objUNO = 4
|
||||
@@ -665,6 +671,15 @@ Check:
|
||||
' Ignore Null basic objects (Null = Null or Nothing)
|
||||
If IsNull(BasicObject) Or IsEmpty(BasicObject) Then GoTo Catch
|
||||
|
||||
' Intercept CallType when the targeted argument should be identified
|
||||
If IsArray(CallType) Then
|
||||
iCallType = CallType(0)
|
||||
iArgIndex = CallType(1)
|
||||
Else
|
||||
iCallType = CallType
|
||||
iArgIndex = 0
|
||||
End If
|
||||
|
||||
' Reinterpret arguments one by one into vArgs
|
||||
' - convert UNO dates/times
|
||||
' - identify conventional NoArgs/Empty/Null/Missing constants
|
||||
@@ -680,7 +695,7 @@ Check:
|
||||
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 i = iArgIndex And (( iCallType 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)
|
||||
@@ -695,8 +710,8 @@ Check:
|
||||
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 ( iCallType And cstDateArg ) = cstDateArg Then vArg = CDateFromUnoDateTime(vArg)
|
||||
ElseIf ( iCallType And cstDictArg ) = cstDictArg Then
|
||||
If IsArray(vArg) Then
|
||||
If UBound(vArg) >= 0 Then
|
||||
If sess.UnoObjectType(vArg(0)) = "com.sun.star.beans.PropertyValue" Then
|
||||
@@ -776,7 +791,7 @@ Try:
|
||||
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
|
||||
If Not bBasicClass And (iCallType And vbMethod) = vbMethod And (iCallType And cstRetArray) = cstRetArray Then
|
||||
sScript = sLibrary & "." & sObjectType & "." & Script
|
||||
' Force validation in targeted function, not in ExecuteBasicScript()
|
||||
_SF_.StackLevel = -1
|
||||
@@ -794,14 +809,14 @@ Try:
|
||||
_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
|
||||
ElseIf (iCallType 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
|
||||
ElseIf (iCallType 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
|
||||
ElseIf ((iCallType And vbMethod) + (iCallType And cstArgArray)) = vbMethod + cstArgArray Or _
|
||||
((iCallType And vbMethod) + (iCallType And cstRetArray)) = vbMethod + cstRetArray Then
|
||||
If Script = "Methods" Then
|
||||
vReturn = vBasicObject.Methods()
|
||||
ElseIf Script = "Properties" Then
|
||||
@@ -875,7 +890,7 @@ Try:
|
||||
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
|
||||
ElseIf bBasicClass And ((iCallType And vbMethod) + (iCallType And cstHardCode)) = vbMethod + cstHardCode Then
|
||||
Select Case sServiceName
|
||||
Case "SFDialogs.Dialog"
|
||||
Select Case Script
|
||||
@@ -884,7 +899,7 @@ Try:
|
||||
End Select
|
||||
|
||||
' Methods in all modules are invoked with CallByName
|
||||
ElseIf ((CallType And vbMethod) = vbMethod) Then
|
||||
ElseIf ((iCallType And vbMethod) = vbMethod) Then
|
||||
Select Case UBound(vArgs)
|
||||
' Dirty alternatives to process usual and ParamArray cases
|
||||
' But, up to ... how many ?
|
||||
@@ -934,7 +949,7 @@ Try:
|
||||
End If
|
||||
|
||||
' Post processing
|
||||
If (CallType And cstPost) = cstPost Then
|
||||
If (iCallType 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
|
||||
@@ -971,7 +986,7 @@ Try:
|
||||
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
|
||||
If (iCallType 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
|
||||
|
||||
@@ -348,9 +348,10 @@ class ScriptForge(object, metaclass = _Singleton):
|
||||
argslist[i] = argdict.ConvertToPropertyValues()
|
||||
return tuple(argslist)
|
||||
|
||||
#
|
||||
# Intercept flags is a tuple
|
||||
flag = (flags[0] if isinstance(flags, tuple) else flags)
|
||||
# Intercept dictionary arguments
|
||||
if flags & SFServices.flgDictArg == SFServices.flgDictArg: # Bits comparison
|
||||
if flag & SFServices.flgDictArg == SFServices.flgDictArg: # Bits comparison
|
||||
args = ConvertDictArgs()
|
||||
#
|
||||
# Run the basic script
|
||||
@@ -395,7 +396,7 @@ class ScriptForge(object, metaclass = _Singleton):
|
||||
# Intercept empty array
|
||||
if isinstance(returnvalue, uno.ByteSequence):
|
||||
return ()
|
||||
if flags & SFServices.flgDateRet == SFServices.flgDateRet: # Bits comparison
|
||||
if flag & SFServices.flgDateRet == SFServices.flgDateRet: # Bits comparison
|
||||
# Intercept all UNO dates in the 1D or 2D array
|
||||
if isinstance(returnvalue[0], tuple): # tuple of tuples
|
||||
arr = []
|
||||
@@ -555,7 +556,8 @@ class SFServices(object):
|
||||
flgArrayArg = 512 # 1st argument can be a 2D array
|
||||
flgArrayRet = 1024 # Invoked service method can return a 2D array (standard modules) or any array (class modules)
|
||||
flgUno = 256 # Invoked service method/property can return a UNO object
|
||||
flgObject = 2048 # 1st argument may be a Basic object
|
||||
flgObject = 2048 # N-th argument may be a Basic object
|
||||
# N (default = 0) can be passed as companion in a tuple
|
||||
flgHardCode = 4096 # Force hardcoded call to method, avoid CallByName()
|
||||
# Basic class type
|
||||
moduleClass, moduleStandard = 2, 1
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE library:library PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "library.dtd">
|
||||
<library:library xmlns:library="http://openoffice.org/2000/library" library:name="ScriptForge" library:readonly="false" library:passwordprotected="false">
|
||||
<library:element library:name="SF_Timer"/>
|
||||
<library:element library:name="SF_FileSystem"/>
|
||||
<library:element library:name="__License"/>
|
||||
<library:element library:name="SF_Root"/>
|
||||
<library:element library:name="SF_Region"/>
|
||||
<library:element library:name="SF_L10N"/>
|
||||
<library:element library:name="SF_SharedMemory"/>
|
||||
<library:element library:name="_CodingConventions"/>
|
||||
<library:element library:name="SF_Session"/>
|
||||
<library:element library:name="SF_Dictionary"/>
|
||||
<library:element library:name="SF_Exception"/>
|
||||
<library:element library:name="SF_UI"/>
|
||||
<library:element library:name="SF_Services"/>
|
||||
<library:element library:name="SF_PythonHelper"/>
|
||||
<library:element library:name="SF_Platform"/>
|
||||
<library:element library:name="SF_Array"/>
|
||||
@@ -8,17 +21,4 @@
|
||||
<library:element library:name="SF_Utils"/>
|
||||
<library:element library:name="SF_String"/>
|
||||
<library:element library:name="_ModuleModel"/>
|
||||
<library:element library:name="SF_SharedMemory"/>
|
||||
<library:element library:name="SF_L10N"/>
|
||||
<library:element library:name="SF_Region"/>
|
||||
<library:element library:name="__License"/>
|
||||
<library:element library:name="SF_Root"/>
|
||||
<library:element library:name="SF_Timer"/>
|
||||
<library:element library:name="SF_FileSystem"/>
|
||||
<library:element library:name="SF_Services"/>
|
||||
<library:element library:name="SF_UI"/>
|
||||
<library:element library:name="SF_Exception"/>
|
||||
<library:element library:name="SF_Dictionary"/>
|
||||
<library:element library:name="SF_Session"/>
|
||||
<library:element library:name="_CodingConventions"/>
|
||||
</library:library>
|
||||
Reference in New Issue
Block a user