ScriptForge - tdf#149983 dialog.EndExecute() failure
In SF_PythonHelper._PythonDispatcher():
Force a hardcoded call of the methods in the Dialog
service which may potentially be invoked while the
dialog is displayed, bypassing the generic CallByName()
Basic builtin function:
Activate
Center
EndExecute
Resize
(Controls is already hardcoded because returning an array)
Commit on master: https://gerrit.libreoffice.org/c/core/+/137084
Change-Id: I67649d86d2f0f2f76f3bdbbdbd0b22ae3e132b04
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137113
Tested-by: Jenkins
Tested-by: Jean-Pierre Ledure <jp@ledure.be>
Reviewed-by: Jean-Pierre Ledure <jp@ledure.be>
diff --git a/wizards/source/scriptforge/SF_PythonHelper.xba b/wizards/source/scriptforge/SF_PythonHelper.xba
index c3d67d8..178dfcc 100644
--- a/wizards/source/scriptforge/SF_PythonHelper.xba
+++ b/wizards/source/scriptforge/SF_PythonHelper.xba
@@ -611,10 +611,11 @@ Const vbGet = 2, vbLet = 4, vbMethod = 1, vbSet = 8
' Protocol flags
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 cstUno = 256 ' Return value can be a UNO object
Const cstObject = 2048 ' 1st argument is a Basic object when numeric
Const cstHardCode = 4096 ' Method must not be executed with CallByName()
' Object nature in returned array
Const objMODULE = 1, objCLASS = 2, objUNO = 3
@@ -625,7 +626,7 @@ Check:
' Ignore Null basic objects (Null = Null or Nothing)
If IsNull(BasicObject) Or IsEmpty(BasicObject) Then GoTo Catch
' Reinterpret arguments one by one into vArgs, examine iso-dates and conventional NoArgs/Empty/Null values
' Reinterpret arguments one by one into vArgs, convert UNO date/times and conventional NoArgs/Empty/Null/Missing values
iNbArgs = -1
vArgs = Array()
@@ -667,14 +668,14 @@ Try:
' 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
' 1. Methods in usual modules are called by ExecuteBasicScript() except if they use a ParamArray
' 2. Properties in any service are got and set with obj.GetProperty/SetProperty(...)
' 3. Methods in class modules are invoked with CallByName
' 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. Methods returning a 1D array when no arguments and a scalar otherwise (e.g. SF_Dialog.Controls())
' may be considered as properties when no argument
' Requires Python and Basic update in the concerned library but is transparent for this dispatcher
' 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
@@ -816,6 +817,19 @@ Try:
End Select
End If
' Methods in class modules may better not be executed with CallByName()
ElseIf bBasicClass And ((CallType And vbMethod) + (CallType And cstHardCode)) = vbMethod + cstHardCode Then
Select Case sServiceName
Case "SFDialogs.Dialog"
Select Case Script
Case "Activate" : vReturn = vBasicObject.Activate()
Case "Center"
If UBound(vArgs) < 0 Then vReturn = vBasicObject.Center() Else vReturn = vBasicObject.Center(vArgs(0))
Case "EndExecute" : vReturn = vBasicObject.EndExecute(vArgs(0))
Case "Resize" : vReturn = vBasicObject.Resize(vArgs(0), vArgs(1), vArgs(2), vArgs(3))
End Select
End Select
' Methods in class modules are invoked with CallByName
ElseIf bBasicClass And ((CallType And vbMethod) = vbMethod) Then
Select Case UBound(vArgs)
diff --git a/wizards/source/scriptforge/python/scriptforge.py b/wizards/source/scriptforge/python/scriptforge.py
index 86c70b2..003abfb 100644
--- a/wizards/source/scriptforge/python/scriptforge.py
+++ b/wizards/source/scriptforge/python/scriptforge.py
@@ -455,6 +455,7 @@ class SFServices(object):
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
flgHardCode = 4096 # Force hardcoded call to method, avoid CallByName()
# Basic class type
moduleClass, moduleStandard = 2, 1
#
@@ -1781,20 +1782,21 @@ class SFDialogs:
"""
return container, library, dialogname, ScriptForge.componentcontext
# Methods potentially executed while the dialog is in execution require the flgHardCode flag
def Activate(self):
return self.ExecMethod(self.vbMethod, 'Activate')
return self.ExecMethod(self.vbMethod + self.flgHardCode, 'Activate')
def Center(self, parent = ScriptForge.cstSymMissing):
parentclasses = (SFDocuments.SF_Document, SFDocuments.SF_Base, SFDocuments.SF_Calc, SFDocuments.SF_Writer,
SFDialogs.SF_Dialog)
parentobj = parent.objectreference if isinstance(parent, parentclasses) else parent
return self.ExecMethod(self.vbMethod + self.flgObject, 'Center', parentobj)
return self.ExecMethod(self.vbMethod + self.flgObject + self.flgHardCode, 'Center', parentobj)
def Controls(self, controlname = ''):
return self.ExecMethod(self.vbMethod + self.flgArrayRet, 'Controls', controlname)
return self.ExecMethod(self.vbMethod + self.flgArrayRet + self.flgHardCode, 'Controls', controlname)
def EndExecute(self, returnvalue):
return self.ExecMethod(self.vbMethod, 'EndExecute', returnvalue)
return self.ExecMethod(self.vbMethod + self.flgHardCode, 'EndExecute', returnvalue)
def Execute(self, modal = True):
return self.ExecMethod(self.vbMethod, 'Execute', modal)
@@ -1804,7 +1806,7 @@ class SFDialogs:
return self.ExecMethod(self.vbMethod + self.flgObject, 'GetTextsFromL10N', l10nobj)
def Resize(self, left = -1, top = -1, width = -1, height = -1):
return self.ExecMethod(self.vbMethod, 'Resize', left, top, width, height)
return self.ExecMethod(self.vbMethod + self.flgHardCode, 'Resize', left, top, width, height)
def Terminate(self):
return self.ExecMethod(self.vbMethod, 'Terminate')