summaryrefslogtreecommitdiff
path: root/wizards
diff options
context:
space:
mode:
authorJean-Pierre Ledure <jp@ledure.be>2021-04-10 15:10:02 +0200
committerJean-Pierre Ledure <jp@ledure.be>2021-04-10 16:44:27 +0200
commitde3b720f4066c9fcf1258bf6592263a7e476cc46 (patch)
tree3e8dc3173f0cbe2c6349d40dc3ddc7b7c725708e /wizards
parent32ad749a512b03e2d4588de667e397949cc51958 (diff)
ScriptForge - (scriptforge.py) FormControl class
New class to manage controls in forms and subforms from Python, essentially thru the use of Properties Required a review of SF_FormControl.Getproperty() Indeed, the IDE debugger computes all the properties of a Basic object when expanded in the watch window. This can cause errors. This class makes use of default values for properties when irrelevant for the actual control type Error were detected on date/time conversions of date/timefield controls and corrected. SF_String etc shortcuts have been removed (see previous commit) because not applicable in every scenario. The only entry point to the API from a user Python script is via CreateScriptService(). Change-Id: Ia87c7281c3fcf39ab0c3528f00114c9b1e067bcf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113920 Tested-by: Jean-Pierre Ledure <jp@ledure.be> Tested-by: Jenkins Reviewed-by: Jean-Pierre Ledure <jp@ledure.be>
Diffstat (limited to 'wizards')
-rw-r--r--wizards/source/scriptforge/SF_Exception.xba2
-rw-r--r--wizards/source/scriptforge/SF_PythonHelper.xba4
-rw-r--r--wizards/source/scriptforge/SF_String.xba2
-rw-r--r--wizards/source/scriptforge/python/scriptforge.py103
-rw-r--r--wizards/source/sfdocuments/SF_FormControl.xba75
5 files changed, 118 insertions, 68 deletions
diff --git a/wizards/source/scriptforge/SF_Exception.xba b/wizards/source/scriptforge/SF_Exception.xba
index d2ee476c6430..650f14164a02 100644
--- a/wizards/source/scriptforge/SF_Exception.xba
+++ b/wizards/source/scriptforge/SF_Exception.xba
@@ -1173,4 +1173,4 @@ Private Function _Repr() As String
End Function &apos; ScriptForge.SF_Exception._Repr
REM ============================================ END OF SCRIPTFORGE.SF_EXCEPTION
-</script:module>
+</script:module> \ No newline at end of file
diff --git a/wizards/source/scriptforge/SF_PythonHelper.xba b/wizards/source/scriptforge/SF_PythonHelper.xba
index e3d988c38aa9..328978033290 100644
--- a/wizards/source/scriptforge/SF_PythonHelper.xba
+++ b/wizards/source/scriptforge/SF_PythonHelper.xba
@@ -729,6 +729,10 @@ Try:
Case &quot;Controls&quot; : vReturn = vBasicObject.Controls(vArgs(0))
Case &quot;Subforms&quot; : vReturn = vBasicObject.Subforms(vArgs(0))
End Select
+ Case &quot;SFDocuments.FormControl&quot;
+ Select Case Script
+ Case &quot;Controls&quot; : vReturn = vBasicObject.Controls(vArgs(0))
+ End Select
End Select
&apos; Methods in class modules are invoked with CallByName
diff --git a/wizards/source/scriptforge/SF_String.xba b/wizards/source/scriptforge/SF_String.xba
index 6519ac2383d3..f7c645981c8b 100644
--- a/wizards/source/scriptforge/SF_String.xba
+++ b/wizards/source/scriptforge/SF_String.xba
@@ -2309,7 +2309,7 @@ Dim bSplit As Boolean &apos; New chunk found or not
Dim i As Long
Const cstDouble = &quot;&quot;&quot;&quot; : Const cstSingle = &quot;&apos;&quot;
Const cstThisSub = &quot;String.SplitNotQuoted&quot;
-Const cstSubArgs = &quot;InputStr, [Delimiter=&quot;&quot; &quot;&quot;], [Occurrences=0], [QuoteChar=&quot;&quot;&quot; &amp; cstDouble &amp; &quot;&quot;&quot;&quot;
+Const cstSubArgs = &quot;InputStr, [Delimiter=&quot;&quot; &quot;&quot;], [Occurrences=0], [QuoteChar=&quot;&quot;&quot; &amp; cstDouble &amp; &quot;&quot;&quot;]&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
vSplit = Array()
diff --git a/wizards/source/scriptforge/python/scriptforge.py b/wizards/source/scriptforge/python/scriptforge.py
index c143d196e3b7..e3d4bdfa63e6 100644
--- a/wizards/source/scriptforge/python/scriptforge.py
+++ b/wizards/source/scriptforge/python/scriptforge.py
@@ -183,7 +183,7 @@ class ScriptForge(object, metaclass = _Singleton):
"""
servicemanager = context.ServiceManager # com.sun.star.lang.XMultiComponentFactory
masterscript = servicemanager.createInstanceWithContext(
- "com.sun.star.script.provider.MasterScriptProviderFactory", context)
+ 'com.sun.star.script.provider.MasterScriptProviderFactory', context)
return masterscript.createScriptProvider("")
@classmethod
@@ -201,7 +201,7 @@ class ScriptForge(object, metaclass = _Singleton):
:return: the value returned by the invoked script, or an error if the script was not found
"""
- # The frequently called PythonDispatcher in the ScriptForge Basic library is buffered to privilege performance
+ # The frequently called PythonDispatcher in the ScriptForge Basic library is cached to privilege performance
if cls.servicesdispatcher is not None and script == ScriptForge.basicdispatcher:
xscript = cls.servicesdispatcher
fullscript = script
@@ -313,7 +313,11 @@ class ScriptForge(object, metaclass = _Singleton):
elif returntuple[cstVarType] >= ScriptForge.V_ARRAY:
pass
elif returntuple[cstVarType] == ScriptForge.V_DATE:
- return datetime.datetime.fromisoformat(returntuple[cstValue])
+ try: # Anticipate fromisoformat('00:00:00') and alike
+ dat = None
+ dat = datetime.datetime.fromisoformat(returntuple[cstValue])
+ finally:
+ return dat
else: # All other scalar values
pass
return returntuple[cstValue]
@@ -351,12 +355,11 @@ class ScriptForge(object, metaclass = _Singleton):
func = getattr(cls, method)
if callable(func):
# Assign to each synonym a reference to the original method
- m = method.lower()
- if hasattr(cls, m) is False:
- setattr(cls, m, func)
- m = camelCase(method)
- if hasattr(cls, m) is False:
- setattr(cls, m, func)
+ lc = method.lower()
+ setattr(cls, lc, func)
+ cc = camelCase(method)
+ if cc != lc:
+ setattr(cls, cc, func)
return
@@ -553,7 +556,7 @@ class SFServices(object):
Set the given property to a new value in the Basic world
"""
if self.serviceimplementation == 'basic':
- return self.EXEC(self.objectreference, self.vbLet, propertyname, value)
+ return self.EXEC(self.objectreference, self.vbLet + self.flgDateArg, propertyname, value)
# #####################################################################################################################
@@ -648,10 +651,9 @@ class SFScriptForge:
expression = expression.isoformat()
return self.SIMPLEEXEC(self.module + '.PyFormat', expression, format)
- @staticmethod
- def GetDefaultContext():
+ @classmethod
+ def GetDefaultContext(cls):
return ScriptForge.componentcontext
- getDefaultContext, getdefaultcontext = GetDefaultContext, GetDefaultContext
def GetGuiType(self):
return self.SIMPLEEXEC(self.module + '.PyGetGuiType')
@@ -659,10 +661,9 @@ class SFScriptForge:
def GetSystemTicks(self):
return self.SIMPLEEXEC(self.module + '.PyGetSystemTicks')
- @staticmethod
- def GetPathSeparator():
+ @classmethod
+ def GetPathSeparator(cls):
return os.sep
- getPathSeparator, getpathseparator = GetPathSeparator, GetPathSeparator
class GlobalScope(object, metaclass = _Singleton):
@classmethod # Mandatory because the GlobalScope class is normally not instantiated
@@ -681,18 +682,16 @@ class SFScriptForge:
def MsgBox(self, prompt, buttons = 0, title = ''):
return self.SIMPLEEXEC(self.module + '.PyMsgBox', prompt, buttons, title)
- @staticmethod
- def Now():
+ @classmethod
+ def Now(cls):
return datetime.datetime.now()
- now = Now
- @staticmethod
- def RGB(red, green, blue):
+ @classmethod
+ def RGB(cls, red, green, blue):
return int('%02x%02x%02x' % (red, green, blue), 16)
- rgb = RGB
- @staticmethod
- def StarDesktop():
+ @classmethod
+ def StarDesktop(cls):
ctx = ScriptForge.componentcontext
if ctx is None:
return None
@@ -700,7 +699,6 @@ class SFScriptForge:
DESK = 'com.sun.star.frame.Desktop'
desktop = smgr.createInstanceWithContext(DESK, ctx)
return desktop
- starDesktop, stardesktop = StarDesktop, StarDesktop
def Xray(self, unoobject = None):
return self.SIMPLEEXEC('XrayTool._main.xray', unoobject)
@@ -1653,6 +1651,40 @@ class SFDocuments:
def Subforms(self, subform = ''):
return self.Execute(self.vbMethod + self.flgArrayRet, 'Subforms', subform)
+ # #########################################################################
+ # SF_FormControl CLASS
+ # #########################################################################
+ class SF_FormControl(SFServices):
+ """
+ Manage the controls belonging to a form or subform stored in a document.
+ Each instance of the current class represents a single control within a form, a subform or a tablecontrol.
+ A prerequisite is that all controls within the same form, subform or tablecontrol must have
+ a unique name.
+ """
+ # Mandatory class properties for service registration
+ serviceimplementation = 'basic'
+ servicename = 'SFDocuments.FormControl'
+ servicesynonyms = ()
+ serviceproperties = dict(Action = True, Caption = True, ControlSource = False, ControlType = False,
+ Default = True, DefaultValue = True, Enabled = True, Format = True,
+ ListCount = False, ListIndex = True, ListSource = True, ListSourceType = True,
+ Locked = True, MultiSelect = True, Name = False,
+ OnActionPerformed = True, OnAdjustmentValueChanged = True,
+ OnApproveAction = True, OnApproveReset = True, OnApproveUpdate = True,
+ OnChanged = True, OnErrorOccurred = True, OnFocusGained = True, OnFocusLost = True,
+ OnItemStateChanged = True, OnKeyPressed = True, OnKeyReleased = True,
+ OnMouseDragged = True, OnMouseEntered = True, OnMouseExited = True,
+ OnMouseMoved = True, OnMousePressed = True, OnMouseReleased = True, OnResetted = True,
+ OnTextChanged = True, OnUpdated = True, Parent = False, Picture = True,
+ Required = True, Text = False, TipText = True, TripleState = True, Value = True,
+ Visible = True, XControlModel = False, XControlView = False)
+
+ def Controls(self, controlname = ''):
+ return self.Execute(self.vbMethod + self.flgArrayRet, 'Controls', controlname)
+
+ def SetFocus(self):
+ return self.Execute(self.vbMethod, 'SetFocus')
+
# ##############################################False##################################################################
# CreateScriptService() ###
@@ -1712,27 +1744,6 @@ def CreateScriptService(service, *args):
createScriptService, createscriptservice = CreateScriptService, CreateScriptService
-# #####################################################################################################################
-# Services shortcuts ###
-# #####################################################################################################################
-def _CreateScriptService(service):
- """
- Mini CreateScriptService() function to create singleton predefined Basic services
- The ScriptForge() initialization is SKIPPED.
- """
- if service in ScriptForge.servicesmodules:
- serv = ScriptForge.serviceslist[service]
- return serv(ScriptForge.servicesmodules[service], classmodule = SFServices.moduleStandard)
- return None
-
-
-# Shortcuts below are for compatibility with the Basic ScriptForge API
-SF_Basic = SFScriptForge.SF_Basic()
-SF_Array = _CreateScriptService('ScriptForge.SF_Array')
-SF_Exception = _CreateScriptService('ScriptForge.SF_Exception')
-SF_String = _CreateScriptService('ScriptForge.SF_String')
-
-
# ######################################################################
# Lists the scripts, that shall be visible inside the Basic/Python IDE
# ######################################################################
diff --git a/wizards/source/sfdocuments/SF_FormControl.xba b/wizards/source/sfdocuments/SF_FormControl.xba
index a40b902e3425..92055c5e25a4 100644
--- a/wizards/source/sfdocuments/SF_FormControl.xba
+++ b/wizards/source/sfdocuments/SF_FormControl.xba
@@ -758,9 +758,10 @@ Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; see the exceptions of the individual properties
&apos;&apos;&apos; Examples:
-&apos;&apos;&apos; myModel.GetProperty(&quot;MyProperty&quot;)
+&apos;&apos;&apos; myControl.GetProperty(&quot;MyProperty&quot;)
-Const cstThisSub = &quot;SFDocuments.DialogControl.GetProperty&quot;
+Dim vDefault As Variant &apos; Default value when property not applicable on control type
+Const cstThisSub = &quot;SFDocuments.FormControl.GetProperty&quot;
Const cstSubArgs = &quot;&quot;
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
@@ -772,7 +773,28 @@ Check:
End If
Try:
- GetProperty = _PropertyGet(PropertyName)
+ &apos; FormControl properties are far from applicable to all control types
+ &apos; Getting a property must never abort to not interfere with the Basic IDE watch function
+ &apos; Hence a default value must be provided
+ Select Case UCase(PropertyName)
+ Case UCase(&quot;Default&quot;) : vDefault = False
+ Case UCase(&quot;DefaultValue&quot;) : vDefault = Null
+ Case UCase(&quot;Enabled&quot;) : vDefault = False
+ Case UCase(&quot;ListCount&quot;) : vDefault = 0
+ Case UCase(&quot;ListIndex&quot;) : vDefault = -1
+ Case UCase(&quot;Locked&quot;) : vDefault = False
+ Case UCase(&quot;MultiSelect&quot;) : vDefault = False
+ Case UCase(&quot;Parent&quot;) : vDefault = Nothing
+ Case UCase(&quot;Required&quot;) : vDefault = False
+ Case UCase(&quot;TripleState&quot;) : vDefault = False
+ Case UCase(&quot;Value&quot;) : vDefault = Empty
+ Case UCase(&quot;Visible&quot;) : vDefault = True
+ Case UCase(&quot;XControlModel&quot;) : vDefault = Nothing
+ Case UCase(&quot;XControlView&quot;) : vDefault = Nothing
+ Case Else : vDefault = &quot;&quot;
+ End Select
+
+ GetProperty = _PropertyGet(PropertyName, vDefault)
Finally:
ScriptForge.SF_Utils._ExitFunction(cstThisSub)
@@ -783,7 +805,7 @@ End Function &apos; SFDocuments.SF_FormControl.GetProperty
REM -----------------------------------------------------------------------------
Public Function Methods() As Variant
-&apos;&apos;&apos; Return the list of public methods of the Model service as an array
+&apos;&apos;&apos; Return the list of public methods of the FormControl service as an array
Methods = Array( _
&quot;AddSubNode&quot; _
@@ -798,10 +820,11 @@ End Function &apos; SFDocuments.SF_FormControl.Methods
REM -----------------------------------------------------------------------------
Public Function Properties() As Variant
-&apos;&apos;&apos; Return the list or properties of the Timer class as an array
+&apos;&apos;&apos; Return the list or properties of the FormControl class as an array
Properties = Array( _
- &quot;Cancel&quot; _
+ &quot;Action&quot; _
+ , &quot;Cancel&quot; _
, &quot;Caption&quot; _
, &quot;ControlSource&quot; _
, &quot;ControlType&quot; _
@@ -926,7 +949,7 @@ Public Function SetProperty(Optional ByVal PropertyName As Variant _
&apos;&apos;&apos; Exceptions
&apos;&apos;&apos; ARGUMENTERROR The property does not exist
-Const cstThisSub = &quot;SFDocuments.DialogControl.SetProperty&quot;
+Const cstThisSub = &quot;SFDocuments.FormControl.SetProperty&quot;
Const cstSubArgs = &quot;PropertyName, Value&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
@@ -1173,7 +1196,7 @@ Dim vSelection As Variant &apos; Alias of Model.SelectedItems or Model.Selec
Dim vList As Variant &apos; Alias of Model.StringItemList
Dim lIndex As Long &apos; Index in StringItemList
Dim sItem As String &apos; A single item
-Dim vDate As Variant &apos; com.sun.star.util.Date or com.sun.star.util.Time
+Dim vDate As Variant &apos; Date after conversion from com.sun.star.util.Date or com.sun.star.util.Time
Dim vValues As Variant &apos; Array of listbox values
Dim oControlEvents As Object &apos; com.sun.star.container.XNameContainer
Dim sEventName As String &apos; Internal event name
@@ -1246,8 +1269,10 @@ Const cstSubArgs = &quot;&quot;
Case CTLDATEFIELD
If oSession.HasUNOProperty(_ControlModel, &quot;DefaultDate&quot;) Then
If Not IsEmpty(_ControlModel.DefaultDate) Then
- vDate = _ControlModel.DefaultDate
- _PropertyGet = DateSerial(vDate.Year, vDate.Month, vDate.Day)
+ With _ControlModel.DefaultDate
+ vDate = DateSerial(.Year, .Month, .Day)
+ End With
+ _PropertyGet = vDate
End If
End If
Case CTLFORMATTEDFIELD
@@ -1268,8 +1293,10 @@ Const cstSubArgs = &quot;&quot;
Case CTLTIMEFIELD
If oSession.HasUNOProperty(_ControlModel, &quot;DefaultTime&quot;) Then
If Not IsEmpty(_ControlModel.DefaultTime) Then
- vDate = _ControlModel.DefaultTime
- _PropertyGet = TimeSerial(vDate.Hours, vDate.Minutes, vDate.Seconds)
+ With _ControlModel.DefaultTime
+ vDate = TimeSerial(.Hours, .Minutes, .Seconds)
+ End With
+ _PropertyGet = vDate
End If
End If
Case Else : GoTo CatchType
@@ -1387,15 +1414,19 @@ Const cstSubArgs = &quot;&quot;
And oSession.HasUNOProperty(_ControlModel, &quot;FormatKey&quot;) _
And oSession.HasUNOProperty(_ControlModel, &quot;FormatsSupplier&quot;) Then
If Not IsEmpty(_ControlModel.Date) Then
- vDate = DateSerial(_ControlModel.Date.Year, _ControlModel.Date.Month, _ControlModel.Date.Day)
+ With _ControlModel.Date
+ vDate = DateSerial(.Year, .Month, .Day)
+ End With
_PropertyGet = Format(vDate, _ControlModel.FormatsSupplier.getNumberFormats.getByKey(_ControlModel.FormatKey).FormatString)
End If
End If
Case CTLTIMEFIELD
If oSession.HasUNOProperty(_ControlModel, &quot;Text&quot;) Then
If Not IsEmpty(_ControlModel.Time) Then
- Set vDate = _ControlModel.Time
- _PropertyGet = Format(TimeSerial(vDate.Hours, vDate.Minutes, vDate.Seconds), &quot;HH:MM:SS&quot;)
+ With _ControlModel.Time
+ vDate = TimeSerial(.Hours, .Minutes, .Seconds)
+ End With
+ _PropertyGet = Format(vDate, &quot;HH:MM:SS&quot;)
End If
End If
Case CTLCOMBOBOX, CTLFILECONTROL, CTLFORMATTEDFIELD, CTLPATTERNFIELD, CTLTEXTFIELD
@@ -1432,8 +1463,10 @@ Const cstSubArgs = &quot;&quot;
vGet = CDate(1)
If oSession.HasUnoProperty(_ControlModel, &quot;Date&quot;) Then
If VarType(_ControlModel.Date) = ScriptForge.V_OBJECT Then &apos; com.sun.star.util.Date
- Set vDate = _ControlModel.Date
- vGet = DateSerial(vDate.Year, vDate.Month, vDate.Day)
+ With _ControlModel.Date
+ vDate = DateSerial(.Year, .Month, .Day)
+ End With
+ vGet = vDate
Else &apos; .Date = Empty
End If
End If
@@ -1480,8 +1513,10 @@ Const cstSubArgs = &quot;&quot;
vGet = CDate(0)
If oSession.HasUnoProperty(_ControlModel, &quot;Time&quot;) Then
If VarType(_ControlModel.Time) = ScriptForge.V_OBJECT Then &apos; com.sun.star.Util.Time
- Set vDate = _ControlModel.Time
- vGet = TimeSerial(vDate.Hours, vDate.Minutes, vDate.Seconds)
+ With _ControlModel.Time
+ vDate = TimeSerial(.Hours, .Minutes, .Seconds)
+ End With
+ vGet = vDate
Else &apos; .Time = Empty
End If
End If
@@ -1625,7 +1660,7 @@ Const cstSubArgs = &quot;Value&quot;
If _ControlType = CTLCOMBOBOX Then _ControlModel.ListSource = pvValue Else _ControlModel.ListSource = Array(pvValue)
_ControlModel.refresh()
Case .SQL
- et oDatabase = _ParentForm.GetDatabase()
+ Set oDatabase = _ParentForm.GetDatabase()
If _ControlType = CTLCOMBOBOX Then _ControlModel.ListSource = oDatabase._ReplaceSquareBrackets(pvValue) Else _ControlModel.ListSource = Array(oDatabase._ReplaceSquareBrackets(pvValue))
_ControlModel.refresh()
Case .VALUELIST &apos; ListBox only !