summaryrefslogtreecommitdiff
path: root/wizards
diff options
context:
space:
mode:
authorJean-Pierre Ledure <jp@ledure.be>2021-04-04 15:56:44 +0200
committerJean-Pierre Ledure <jp@ledure.be>2021-04-04 17:04:15 +0200
commit88d3172f170fcb2e49d832b80444fd16b818deed (patch)
tree34d9cb0824c55c82bf6b6161d3f79d0b68c3b2b5 /wizards
parent33a7ff283a85dec1ff791a771753cc606dcd6bee (diff)
ScriptForge (scriptforge.py) UI, Document & Calc classes
Changes in the Basic-Python engine: - arguments of methods may be 2D arrays - 1st argument of method may be a Basic object - properties starting with 'X' may contain UNO objects - GetProperty may contain 1 argument Calc class is a subclass of the Document class in Python (in Basic it is simulated) A CalcReference class is also created to contain Range and Sheet objects Many comments have been reviewed for consistency in SF_Calc, SF_Form and SF_FormControl.xba Conversion to DataArrays is improved to process input arrays of arrays. Date conversions are supported. Change-Id: Id6254d668ec981b00555e7e277c4d31982c00092 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113568 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_PythonHelper.xba55
-rw-r--r--wizards/source/scriptforge/python/scriptforge.py396
-rw-r--r--wizards/source/sfdocuments/SF_Base.xba2
-rw-r--r--wizards/source/sfdocuments/SF_Calc.xba56
-rw-r--r--wizards/source/sfdocuments/SF_Form.xba6
-rw-r--r--wizards/source/sfdocuments/SF_FormControl.xba8
-rw-r--r--wizards/source/sfdocuments/SF_Register.xba4
7 files changed, 479 insertions, 48 deletions
diff --git a/wizards/source/scriptforge/SF_PythonHelper.xba b/wizards/source/scriptforge/SF_PythonHelper.xba
index 5acd2dfc9228..728cb7b52fcc 100644
--- a/wizards/source/scriptforge/SF_PythonHelper.xba
+++ b/wizards/source/scriptforge/SF_PythonHelper.xba
@@ -544,6 +544,7 @@ Dim vArgs() As Variant &apos; Alias for Args()
Dim sScript As String &apos; Argument of ExecuteBasicScript()
Dim vParams As Variant &apos; Array of arguments to pass to a ParamArray
Dim sObjectType As String &apos; Alias of object.ObjectType
+Dim sServiceName As String &apos; Alias of BasicObject.ServiceName
Dim bBasicClass As Boolean &apos; True when BasicObject is a class
Dim sLibrary As String &apos; Library where the object belongs to
Dim bUno As Boolean &apos; Return value is a UNO object
@@ -560,9 +561,10 @@ Const vbGet = 2, vbLet = 4, vbMethod = 1, vbSet = 8
&apos; Protocol flags
Const cstDateArg = 64 &apos; May contain a date argument
Const cstDateRet = 128 &apos; Return value can be a date
-Const cstArgArray = 512 &apos; 1st argument can be a 2D array
+Const cstArgArray = 512 &apos; Any argument can be a 2D array
Const cstRetArray = 1024 &apos; Return value can be an array
Const cstUno = 256 &apos; Return value can be a UNO object
+Const cstObject = 2048 &apos; 1st argument is a Basic object when numeric
&apos; Object nature in returned array
Const objMODULE = 1, objCLASS = 2, objUNO = 3
@@ -576,13 +578,21 @@ Check:
&apos; Reinterpret arguments one by one into vArgs, examine iso-dates and conventional NoArgs/Empty/Null values
iNbArgs = -1
vArgs = Array()
+
If UBound(Args) &gt;= 0 Then
For i = 0 To UBound(Args)
vArg = Args(i)
+ &apos; Are there arguments ?
If i = 0 And VarType(vArg) = V_STRING Then
If vArg = cstNoArgs Then Exit For
End If
- If VarType(vArg) = V_STRING Then
+ &apos; 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 &lt; 0 Or Not IsArray(_SF_.PythonStorage) Then GoTo Catch
+ If vArg &gt; UBound(_SF_.PythonStorage) Then GoTo Catch
+ vArg = _SF_.PythonStorage(vArg)
+ &apos; Is argument a symbolic constant for Null, Empty, ... , or a date?
+ ElseIf VarType(vArg) = V_STRING Then
If Len(vArg) = 0 Then
ElseIf vArg = cstSymEmpty Then
vArg = Empty
@@ -649,24 +659,25 @@ Try:
If BasicObject &gt; UBound(_SF_.PythonStorage) Then GoTo Catch
vBasicObject = _SF_.PythonStorage(BasicObject)
sObjectType = vBasicObject.ObjectType
+ sServiceName = vBasicObject.ServiceName
&apos; Basic modules have type = &quot;SF_*&quot;
bBasicClass = ( Left(sObjectType, 3) &lt;&gt; &quot;SF_&quot; )
- sLibrary = Split(vBasicObject.ServiceName, &quot;.&quot;)(0)
+ sLibrary = Split(sServiceName, &quot;.&quot;)(0)
&apos; Methods in standard modules returning a date are hardcoded as exceptions
If Not bBasicClass And ((CallType And vbMethod) = vbMethod) And ((CallType And cstDateRet) = cstDateRet) Then
- Select Case sLibrary
- Case &quot;ScriptForge&quot;
- If sObjectType = &quot;SF_FileSystem&quot; And Script = &quot;GetFileModified&quot; Then vReturn = SF_FileSystem.GetFileModified(vArgs(0))
+ Select Case sServiceName
+ Case &quot;ScriptForge.FileSystem&quot;
+ If Script = &quot;GetFileModified&quot; Then vReturn = SF_FileSystem.GetFileModified(vArgs(0))
End Select
&apos; Methods in usual modules using a 2D array or returning arrays are hardcoded as exceptions
ElseIf Not bBasicClass And _
(((CallType And vbMethod) + (CallType And cstArgArray)) = vbMethod + cstArgArray Or _
((CallType And vbMethod) + (CallType And cstRetArray)) = vbMethod + cstRetArray) Then
- Select Case sLibrary
- Case &quot;ScriptForge&quot;
- If sObjectType = &quot;SF_Array&quot; And Script = &quot;ImportFromCSVFile&quot; Then vReturn = SF_Array.ImportFromCSVFile(vArgs(0), vArgs(1), vArgs(2))
+ Select Case sServiceName
+ Case &quot;ScriptForge.Array&quot;
+ If Script = &quot;ImportFromCSVFile&quot; Then vReturn = SF_Array.ImportFromCSVFile(vArgs(0), vArgs(1), vArgs(2))
End Select
&apos; Methods in usual modules are called by ExecuteBasicScript() except if they use a ParamArray
@@ -688,17 +699,26 @@ Try:
_SF_.StackLevel = 0
&apos; Properties in any service are got and set with obj.GetProperty/SetProperty(...)
- ElseIf (CallType And vbGet) = vbGet Then
- &apos; vReturn = sess.ExecuteBasicScript(, sLibrary &amp; &quot;.&quot; &amp; sObjectType &amp; &quot;.GetProperty&quot;, Script)
- vReturn = vBasicObject.GetProperty(Script)
+ ElseIf (CallType And vbGet) = vbGet Then &apos; In some cases (Calc ...) GetProperty may have an argument
+ If UBound(vArgs) &lt; 0 Then vReturn = vBasicObject.GetProperty(Script) Else vReturn = vBasicObject.GetProperty(Script, vArgs(0))
ElseIf (CallType And vbLet) = vbLet Then
- &apos; vReturn = sess.ExecuteBasicScript(, sLibrary &amp; &quot;.&quot; &amp; sObjectType &amp; &quot;.SetProperty&quot;, Script, vArgs(0))
vReturn = vBasicObject.SetProperty(Script, vArgs(0))
&apos; Methods in class modules using a 2D array or returning arrays are hardcoded as exceptions
ElseIf ((CallType And vbMethod) + (CallType And cstArgArray)) = vbMethod + cstArgArray Or _
((CallType And vbMethod) + (CallType And cstRetArray)) = vbMethod + cstRetArray Then
- Select Case sLibrary
+ Select Case sServiceName
+ Case &quot;SFDocuments.Document&quot;
+ If Script = &quot;Forms&quot; Then vReturn = vBasicObject.Forms(vArgs(0))
+ Case &quot;SFDocuments.Calc&quot;
+ Select Case Script
+ Case &quot;Forms&quot; : vReturn = vBasicObject.Forms(vArgs(0), vArgs(1))
+ Case &quot;GetFormula&quot; : vReturn = vBasicObject.GetFormula(vArgs(0))
+ Case &quot;GetValue&quot; : vReturn = vBasicObject.GetValue(vArgs(0))
+ Case &quot;SetArray&quot; : vReturn = vBasicObject.SetArray(vArgs(0), vArgs(1))
+ Case &quot;SetFormula&quot; : vReturn = vBasicObject.SetFormula(vArgs(0), vArgs(1))
+ Case &quot;SetValue&quot; : vReturn = vBasicObject.SetValue(vArgs(0), vArgs(1))
+ End Select
End Select
&apos; Methods in class modules are invoked with CallByName
@@ -749,7 +769,7 @@ Try:
vReturnArray(1) = VarType(vReturn)
vReturnArray(2) = iDims
ElseIf VarType(vReturn) = V_OBJECT And Not IsNull(vReturn) Then
- &apos; Uno or not Uno ?BuildPath
+ &apos; Uno or not Uno ?
bUno = False
If (CallType And cstUno) = cstUno Then &apos; UNO considered only when pre-announced in CallType
If Len(sess.UnoObjectType(vReturn)) &gt; 0 Then bUno = True
@@ -766,7 +786,10 @@ Try:
If Not bUno Then
vReturnArray(3) = vReturn.ObjectType
vReturnArray(4) = vReturn.ServiceName
- If SF_Array.Contains(vReturn.Properties(), &quot;Name&quot;, SortOrder := &quot;ASC&quot;) Then vReturnArray(5) = vReturn.Name Else vReturnArray(5) = &quot;&quot;
+ vReturnArray(5) = &quot;&quot;
+ If vReturn.ObjectType &lt;&gt; &quot;SF_CalcReference&quot; Then &apos; Calc references are implemented as a Type ... End Type data structure
+ If SF_Array.Contains(vReturn.Properties(), &quot;Name&quot;, SortOrder := &quot;ASC&quot;) Then vReturnArray(5) = vReturn.Name
+ End If
End If
Else &apos; Scalar or Nothing
ReDim vReturnArray(0 To 1)
diff --git a/wizards/source/scriptforge/python/scriptforge.py b/wizards/source/scriptforge/python/scriptforge.py
index c90264ad09bb..b0c6c53077d5 100644
--- a/wizards/source/scriptforge/python/scriptforge.py
+++ b/wizards/source/scriptforge/python/scriptforge.py
@@ -299,12 +299,13 @@ class ScriptForge(object, metaclass = _Singleton):
else:
# Create the new class instance of the right subclass of SFServices()
servname = returntuple[cstService]
+ if servname not in cls.serviceslist:
+ # When service not found
+ raise RuntimeError("The service '" + servname + "' is not available in Python. Execution stops.")
subcls = cls.serviceslist[servname]
if subcls is not None:
return subcls(returntuple[cstValue], returntuple[cstType], returntuple[cstClass],
returntuple[cstName])
- # When service not found
- raise RuntimeError("The service '" + servname + "' is not available in Python. Execution stops.")
elif returntuple[cstVarType] >= ScriptForge.V_ARRAY:
pass
elif returntuple[cstVarType] == ScriptForge.V_DATE:
@@ -386,6 +387,7 @@ class SFServices(object):
flgArrayArg = 512 # 1st argument can be a 2D array
flgArrayRet = 1024 # Invoked service method can return a 2D array
flgUno = 256 # Invoked service method/property can return a UNO object
+ flgObject = 2048 # 1st argument may be a Basic object
# Basic class type
moduleClass, moduleStandard = 2, 1
#
@@ -501,12 +503,18 @@ class SFServices(object):
if len(methodname) > 0:
return self.EXEC(self.objectreference, flags, methodname, *args)
- def GetProperty(self, propertyname):
+ def GetProperty(self, propertyname, arg = None):
"""
Get the given property from the Basic world
"""
if self.serviceimplementation == 'basic':
- return self.EXEC(self.objectreference, self.vbGet, propertyname)
+ # Conventionally properties starting with X (and only them) may return a UNO object
+ calltype = self.vbGet + (self.flgUno if propertyname[0] == 'X' else 0)
+ if arg is None:
+ return self.EXEC(self.objectreference, calltype, propertyname)
+ else: # There are a few cases (Calc ...) where GetProperty accepts an argument
+ return self.EXEC(self.objectreference, calltype, propertyname, arg)
+ return None
getProperty, getproperty = GetProperty, GetProperty
def Properties(self):
@@ -526,6 +534,8 @@ class SFServices(object):
# SFScriptForge CLASS (alias of ScriptForge Basic library) ###
# #####################################################################################################################
class SFScriptForge:
+ pass
+
# #########################################################################
# SF_Array CLASS
# #########################################################################
@@ -1020,7 +1030,7 @@ class SFScriptForge:
# Mandatory class properties for service registration
serviceimplementation = 'basic'
servicename = 'ScriptForge.Platform'
- servicesynonyms = ()
+ servicesynonyms = ('platform', 'scriptforge.platform')
serviceproperties = dict(Architecture = False, ComputerName = False, CPUCount = False, CurrentUser = False,
Locale = False, Machine = False, OfficeVersion = False, OSName = False,
OSPlatform = False, OSRelease = False, OSVersion = False, Processor = False)
@@ -1312,8 +1322,382 @@ class SFScriptForge:
return self.Execute(self.vbMethod, 'Terminate')
terminate = Terminate
+ # #########################################################################
+ # SF_UI CLASS
+ # #########################################################################
+ class SF_UI(SFServices, metaclass = _Singleton):
+ """
+ Singleton class for the identification and the manipulation of the
+ different windows composing the whole LibreOffice application:
+ - Windows selection
+ - Windows moving and resizing
+ - Statusbar settings
+ - Creation of new windows
+ - Access to the underlying "documents"
+ """
+ # Mandatory class properties for service registration
+ serviceimplementation = 'basic'
+ servicename = 'ScriptForge.UI'
+ servicesynonyms = ('ui', 'scriptforge.ui')
+ serviceproperties = dict(ActiveWindow = False)
+ propertysynonyms = SFServices._getAttributeSynonyms(serviceproperties)
+
+ # Class constants
+ MACROEXECALWAYS, MAROEXECNEVER, MACROEXECNORMAL = 2, 1, 0
+ BASEDOCUMENT, CALCDOCUMENT, DRAWDOCUMENT, IMPRESSDOCUMENT, MATHDOCUMENT, WRITERDOCUMENT = \
+ 'Base', 'Calc', 'Draw', 'Impress', 'Math', 'Writer'
+
+ @property
+ def ActiveWindow(self):
+ return self.Execute(self.vbMethod, 'ActiveWindow')
+ activeWindow, activewindow = ActiveWindow, ActiveWindow
+
+ def Activate(self, windowname = ''):
+ return self.Execute(self.vbMethod, 'Activate', windowname)
+ activate = Activate
+
+ def CreateBaseDocument(self, filename, embeddeddatabase = 'HSQLDB', registrationname = ''):
+ return self.Execute(self.vbMethod, 'CreateBaseDocument', filename, embeddeddatabase, registrationname)
+ createBaseDocument, createbasedocument = CreateBaseDocument, CreateBaseDocument
+
+ def CreateDocument(self, documenttype = '', templatefile = '', hidden = False):
+ return self.Execute(self.vbMethod, 'CreateDocument', documenttype, templatefile, hidden)
+ createDocument, createdocument = CreateDocument, CreateDocument
+
+ def Documents(self):
+ return self.Execute(self.vbMethod, 'Documents')
+ documents = Documents
+
+ def GetDocument(self, windowname = ''):
+ return self.Execute(self.vbMethod, 'GetDocument', windowname)
+ getDocument, getdocument = GetDocument, GetDocument
+
+ def Maximize(self, windowname = ''):
+ return self.Execute(self.vbMethod, 'Maximize', windowname)
+ maximize = Maximize
+
+ def Minimize(self, windowname = ''):
+ return self.Execute(self.vbMethod, 'Minimize', windowname)
+ minimize = Minimize
+
+ def OpenBaseDocument(self, filename = '', registrationname = '', macroexecution = MACROEXECNORMAL):
+ return self.Execute(self.vbMethod, 'OpenBaseDocument', filename, registrationname, macroexecution)
+ openBaseDocument, openbasedocument = OpenBaseDocument, OpenBaseDocument
+
+ def OpenDocument(self, filename, password = '', readonly = False, hidden = False,
+ macroexecution = MACROEXECNORMAL, filtername = '', filteroptions = ''):
+ return self.Execute(self.vbMethod, 'OpenDocument', filename, password, readonly, hidden,
+ macroexecution, filtername, filteroptions)
+ openDocument, opendocument = OpenDocument, OpenDocument
+
+ def Resize(self, left = -1, top = -1, width = -1, height = -1):
+ return self.Execute(self.vbMethod, 'Resize', left, top, width, height)
+ resize = Resize
+
+ def SetStatusbar(self, text = '', percentage = -1):
+ return self.Execute(self.vbMethod, 'SetStatusbar', text, percentage)
+ setStatusbar, setstatusbar = SetStatusbar, SetStatusbar
+
+ # ShowProgressBar - not supported in Python
+
+ def WindowExists(self, windowname):
+ return self.Execute(self.vbMethod, 'WindowExists', windowname)
+ windowExists, windowexists = WindowExists, WindowExists
+
+
+# #####################################################################################################################
+# SFDocuments CLASS (alias of SFDocuments Basic library) ###
+# #####################################################################################################################
+class SFDocuments:
+ """
+ The SFDocuments class gathers a number of classes, methods and properties making easy
+ managing and manipulating LibreOffice documents
+ """
+ pass
+
+ # #########################################################################
+ # SF_Document CLASS
+ # #########################################################################
+ class SF_Document(SFServices):
+ """
+ The methods and properties are generic for all types of documents: they are combined in the
+ current SF_Document class
+ - saving, closing documents
+ - accessing their standard or custom properties
+ Specific properties and methods are implemented in the concerned subclass(es) SF_Calc, SF_Base, ...
+ """
+ # Mandatory class properties for service registration
+ serviceimplementation = 'basic'
+ servicename = 'SFDocuments.Document'
+ servicesynonyms = ('document', 'sfdocuments.document')
+ serviceproperties = dict(Description = True, DocumentType = False, IsBase = False, IsCalc = False,
+ IsDraw = False, IsImpress = False, IsMath = False, IsWriter = False,
+ Keywords = True, Readonly = False, Subject = True, Title = True,
+ XComponent = False)
+ propertysynonyms = SFServices._getAttributeSynonyms(serviceproperties)
+ # Force for each property to get its value from Basic - due to intense interactivity with user
+ forceGetProperty = True
+
+ @property
+ def XComponent(self):
+ return self.Execute(self.vbGet + self.flgUno, 'XComponent')
+ xComponent, xcomponent = XComponent, XComponent
+
+ def Activate(self):
+ return self.Execute(self.vbMethod, 'Activate')
+ activate = Activate
+
+ def CloseDocument(self, saveask = True):
+ return self.Execute(self.vbMethod, 'CloseDocument', saveask)
+ closeDocument, closedocument = CloseDocument, CloseDocument
+
+ def Forms(self, form = ''):
+ return self.Execute(self.vbMethod + self.flgArrayRet, 'Forms', form)
+ forms = Forms
+
+ def RunCommand(self, command):
+ return self.Execute(self.vbMethod, 'RunCommand', command)
+ runCommand, runcommand = RunCommand, RunCommand
+
+ def Save(self):
+ return self.Execute(self.vbMethod, 'Save')
+ save = Save
+
+ def SaveAs(self, filename, overwrite = False, password = '', filtername = '', filteroptions = ''):
+ return self.Execute(self.vbMethod, 'SaveAs', filename, overwrite, password, filtername, filteroptions)
+ saveAs, saveas = SaveAs, SaveAs
+
+ def SaveCopyAs(self, filename, overwrite = False, password = '', filtername = '', filteroptions = ''):
+ return self.Execute(self.vbMethod, 'SaveCopyAs', filename, overwrite, password, filtername, filteroptions)
+ saveCopyAs, savecopyas = SaveCopyAs, SaveCopyAs
+
+ # #########################################################################
+ # SF_Base CLASS
+ # #########################################################################
+ class SF_Base(SF_Document, SFServices):
+ """
+ The SF_Base module is provided mainly to block parent properties that are NOT applicable to Base documents
+ In addition, it provides methods to identify form documents and access their internal forms
+ (read more elsewhere (the "SFDocuments.Form" service) about this subject)
+ """
+ # Mandatory class properties for service registration
+ serviceimplementation = 'basic'
+ servicename = 'SFDocuments.Base'
+ servicesynonyms = ()
+ serviceproperties = dict(DocumentType = False, IsBase = False, IsCalc = False,
+ IsDraw = False, IsImpress = False, IsMath = False, IsWriter = False,
+ XComponent = False)
+ propertysynonyms = SFServices._getAttributeSynonyms(serviceproperties)
+
+ # #########################################################################
+ # SF_Calc CLASS
+ # #########################################################################
+ class SF_Calc(SF_Document, SFServices):
+ """
+ The SF_Calc module is focused on :
+ - management (copy, insert, move, ...) of sheets within a Calc document
+ - exchange of data between Basic data structures and Calc ranges of values
+ """
+ # Mandatory class properties for service registration
+ serviceimplementation = 'basic'
+ servicename = 'SFDocuments.Calc'
+ servicesynonyms = ('calc', 'sfdocuments.calc')
+ serviceproperties = dict(CurrentSelection = True, Sheets = False,
+ Description = True, DocumentType = False, IsBase = False, IsCalc = False,
+ IsDraw = False, IsImpress = False, IsMath = False, IsWriter = False,
+ Keywords = True, Readonly = False, Subject = True, Title = True,
+ XComponent = False)
+ propertysynonyms = SFServices._getAttributeSynonyms(serviceproperties)
+ # Force for each property to get its value from Basic - due to intense interactivity with user
+ forceGetProperty = True
+
+ # Next functions are implemented in Basic as read-only properties with 1 argument
+ def Height(self, rangename):
+ return self.GetProperty('Height', rangename)
+ height = Height
+
+ def LastCell(self, sheetname):
+ return self.GetProperty('LastCell', sheetname)
+ lastCell, lastcell = LastCell, LastCell
+
+ def LastColumn(self, sheetname):
+ return self.GetProperty('LastColumn', sheetname)
+ lastColumn, lastcolumn = LastColumn, LastColumn
+
+ def LastRow(self, sheetname):
+ return self.GetProperty('LastRow', sheetname)
+ lastRow, lastrow = LastRow, LastRow
+
+ def Range(self, rangename):
+ return self.GetProperty('Range', rangename)
+ range = Range
+
+ def Sheet(self, sheetname):
+ return self.GetProperty('Sheet', sheetname)
+ sheet = Sheet
+
+ def Width(self, rangename):
+ return self.GetProperty('Width', rangename)
+ width = Width
+
+ def XCellRange(self, rangename):
+ return self.Execute(self.vbGet + self.flgUno, 'XCellRange', rangename)
+ xCellRange, xcellrange = XCellRange, XCellRange
+
+ def XSpreadsheet(self, sheetname):
+ return self.Execute(self.vbGet + self.flgUno, 'XSpreadsheet', sheetname)
+ xSpreadsheet, xspreadsheet = XSpreadsheet, XSpreadsheet
+
+ # Usual methods
+ def Activate(self, sheetname = ''):
+ return self.Execute(self.vbMethod, 'Activate', sheetname)
+ activate = Activate
+
+ def ClearAll(self, range):
+ return self.Execute(self.vbMethod, 'ClearAll', range)
+ clearAll, clearall = ClearAll, ClearAll
+
+ def ClearFormats(self, range):
+ return self.Execute(self.vbMethod, 'ClearFormats', range)
+ clearFormats, clearformats = ClearFormats, ClearFormats
+
+ def ClearValues(self, range):
+ return self.Execute(self.vbMethod, 'ClearValues', range)
+ clearValues, clearvalues = ClearValues, ClearValues
+
+ def CopySheet(self, sheetname, newname, beforesheet = 32768):
+ sheet = (sheetname.objectreference if isinstance(sheetname, SFDocuments.SF_CalcReference) else sheetname)
+ return self.Execute(self.vbMethod + self.flgObject, 'CopySheet', sheet, newname, beforesheet)
+ copySheet, copysheet = CopySheet, CopySheet
+
+ def CopySheetFromFile(self, filename, sheetname, newname, beforesheet = 32768):
+ sheet = (sheetname.objectreference if isinstance(sheetname, SFDocuments.SF_CalcReference) else sheetname)
+ return self.Execute(self.vbMethod + self.flgObject, 'CopySheetFromFile',
+ filename, sheet, newname, beforesheet)
+ copySheetFromFile, copysheetfromfile = CopySheetFromFile, CopySheetFromFile
+
+ def CopyToCell(self, sourcerange, destinationcell):
+ range = (sourcerange.objectreference if isinstance(sourcerange, SFDocuments.SF_CalcReference)
+ else sourcerange)
+ return self.Execute(self.vbMethod + self.flgObject, 'CopyToCell', range, destinationcell)
+ copyToCell, copytocell = CopyToCell, CopyToCell
+
+ def CopyToRange(self, sourcerange, destinationrange):
+ range = (sourcerange.objectreference if isinstance(sourcerange, SFDocuments.SF_CalcReference)
+ else sourcerange)
+ return self.Execute(self.vbMethod + self.flgObject, 'CopyToRange', range, destinationrange)
+ copyToRange, copytorange = CopyToRange, CopyToRange
+
+ def DAvg(self, range):
+ return self.Execute(self.vbMethod, 'DAvg', range)
+ dAvg, davg = DAvg, DAvg
+
+ def DCount(self, range):
+ return self.Execute(self.vbMethod, 'DCount', range)
+ dCount, dcount = DCount, DCount
+
+ def DMax(self, range):
+ return self.Execute(self.vbMethod, 'DMax', range)
+ dMax, dmax = DMax, DMax
+
+ def DMin(self, range):
+ return self.Execute(self.vbMethod, 'DMin', range)
+ dMin, dmin = DMin, DMin
+
+ def DSum(self, range):
+ return self.Execute(self.vbMethod, 'DSum', range)
+ dSum, dsum = DSum, DSum
+
+ def Forms(self, sheetname, form = ''):
+ return self.Execute(self.vbMethod + self.flgArrayRet, 'Forms', sheetname, form)
+ forms = Forms
+
+ def GetColumnName(self, columnnumber):
+ return self.Execute(self.vbMethod, 'GetColumnName', columnnumber)
+ getColumnName, getcolumnname = GetColumnName, GetColumnName
+
+ def GetFormula(self, range):
+ return self.Execute(self.vbMethod + self.flgArrayRet, 'GetFormula', range)
+ getFormula, getformula = GetFormula, GetFormula
+
+ def GetValue(self, range):
+ return self.Execute(self.vbMethod + self.flgArrayRet, 'GetValue', range)
+ getValue, getvalue = GetValue, GetValue
+
+ def ImportFromCSVFile(self, filename, destinationcell, filteroptions = ScriptForge.cstSymEmpty):
+ return self.Execute(self.vbMethod, 'ImportFromCSVFile', filename, destinationcell, filteroptions)
+ importFromCSVFile, importfromcsvfile = ImportFromCSVFile, ImportFromCSVFile
+
+ def ImportFromDatabase(self, filename = '', registrationname = '', destinationcell = '', sqlcommand = '',
+ directsql = False):
+ return self.Execute(self.vbMethod, 'ImportFromDatabase', filename, registrationname,
+ destinationcell, sqlcommand, directsql)
+ importFromDatabase, importfromdatabase = ImportFromDatabase, ImportFromDatabase
+
+ def InsertSheet(self, sheetname, beforesheet = 32768):
+ return self.Execute(self.vbMethod, 'InsertSheet', sheetname, beforesheet)
+ insertSheet, insertsheet = InsertSheet, InsertSheet
+
+ def MoveRange(self, source, destination):
+ return self.Execute(self.vbMethod, 'MoveRange', source, destination)
+ moveRange, moverange = MoveRange, MoveRange
+
+ def MoveSheet(self, sheetname, beforesheet = 32768):
+ return self.Execute(self.vbMethod, 'MoveSheet', sheetname, beforesheet)
+ moveSheet, movesheet = MoveSheet, MoveSheet
+
+ def Offset(self, range, rows = 0, columns = 0, height = ScriptForge.cstSymEmpty,
+ width = ScriptForge.cstSymEmpty):
+ return self.Execute(self.vbMethod, 'Offset', range, rows, columns, height, width)
+ offset = Offset
+
+ def RemoveSheet(self, sheetname):
+ return self.Execute(self.vbMethod, 'RemoveSheet', sheetname)
+ removeSheet, removesheet = RemoveSheet, RemoveSheet
+
+ def RenameSheet(self, sheetname, newname):
+ return self.Execute(self.vbMethod, 'RenameSheet', sheetname, newname)
+ renameSheet, renamesheet = RenameSheet, RenameSheet
+
+ def SetArray(self, targetcell, value):
+ return self.Execute(self.vbMethod + self.flgArrayArg, 'SetArray', targetcell, value)
+ setArray, setarray = SetArray, SetArray
+
+ def SetCellStyle(self, targetrange, style):
+ return self.Execute(self.vbMethod, 'SetCellStyle', targetrange, style)
+ setCellStyle, setcellstyle = SetCellStyle, SetCellStyle
+
+ def SetFormula(self, targetrange, formula):
+ return self.Execute(self.vbMethod + self.flgArrayArg, 'SetFormula', targetrange, formula)
+ setFormula, setformula = SetFormula, SetFormula
+
+ def SetValue(self, targetrange, value):
+ return self.Execute(self.vbMethod + self.flgArrayArg, 'SetValue', targetrange, value)
+ setValue, setvalue = SetValue, SetValue
+
+ def SortRange(self, range, sortkeys, sortorder = 'ASC', destinationcell = ScriptForge.cstSymEmpty,
+ containsheader = False, casesensitive = False, sortcolumns = False):
+ return self.Execute(self.vbMethod, 'SortRange', range, sortkeys, sortorder, destinationcell,
+ containsheader, casesensitive, sortcolumns)
+ sortRange, sortrange = SortRange, SortRange
+
+ # #########################################################################
+ # SF_CalcReference CLASS
+ # #########################################################################
+ class SF_CalcReference(SFServices):
+ """
+ The SF_CalcReference class has as unique role to hold sheet and range references.
+ They are implemented in Basic as Type ... End Type data structures
+ """
+ # Mandatory class properties for service registration
+ serviceimplementation = 'basic'
+ servicename = 'SFDocuments.CalcReference'
+ servicesynonyms = ()
+ serviceproperties = dict()
+ propertysynonyms = SFServices._getAttributeSynonyms(serviceproperties)
+
-# ##############################################False#######################################################################
+# ##############################################False##################################################################
# CreateScriptService() ###
# #####################################################################################################################
def CreateScriptService(service, *args):
diff --git a/wizards/source/sfdocuments/SF_Base.xba b/wizards/source/sfdocuments/SF_Base.xba
index f60886e574c9..e9f9075f4fd7 100644
--- a/wizards/source/sfdocuments/SF_Base.xba
+++ b/wizards/source/sfdocuments/SF_Base.xba
@@ -399,6 +399,8 @@ Public Function Methods() As Variant
, &quot;FormDocuments&quot; _
, &quot;Forms&quot; _
, &quot;GetDatabase&quot; _
+ , &quot;IsLoaded&quot; _
+ , &quot;OpenFormDocument&quot; _
, &quot;RunCommand&quot; _
, &quot;Save&quot; _
, &quot;SaveAs&quot; _
diff --git a/wizards/source/sfdocuments/SF_Calc.xba b/wizards/source/sfdocuments/SF_Calc.xba
index c1e4c1c75549..e4bf084c8b83 100644
--- a/wizards/source/sfdocuments/SF_Calc.xba
+++ b/wizards/source/sfdocuments/SF_Calc.xba
@@ -95,6 +95,7 @@ Private _Component As Object &apos; com.sun.star.lang.XComponent
Type _Address
ObjectType As String &apos; Must be &quot;SF_CalcReference&quot;
+ ServiceName As String &apos; Must be &quot;SFDocuments.CalcReference&quot;
RawAddress As String
Component As Object &apos; com.sun.star.lang.XComponent
SheetName As String
@@ -115,6 +116,8 @@ Private Const MAXCOLS = 2^10 &apos; Max number of columns in a sheet
Private Const MAXROWS = 2^20 &apos; Max number of rows in a sheet
Private Const CALCREFERENCE = &quot;SF_CalcReference&quot; &apos; Object type of _Address
+Private Const SERVICEREFERENCE = &quot;SFDocuments.CalcReference&quot;
+ &apos; Service name of _Address (used in Python)
Private Const ISCALCFORM = 2 &apos; Form is stored in a Calc document
@@ -526,7 +529,7 @@ Public Function CopySheetFromFile(Optional ByVal FileName As Variant _
&apos;&apos;&apos; Args:
&apos;&apos;&apos; FileName: Identifies the file to open. It must follow the SF_FileSystem.FileNaming notation
&apos;&apos;&apos; The file must not be protected with a password
-&apos;&apos;&apos; SheetName: The name of the sheet to copy or its reference
+&apos;&apos;&apos; SheetName: The name of the sheet to copy
&apos;&apos;&apos; NewName: Must not exist
&apos;&apos;&apos; BeforeSheet: The name (string) or index (numeric, starting from 1) of the sheet before which to insert
&apos;&apos;&apos; Returns:
@@ -597,7 +600,7 @@ Public Function CopyToCell(Optional ByVal SourceRange As Variant _
&apos;&apos;&apos; SourceRange: the source range as a string if it belongs to the same document
&apos;&apos;&apos; or as a reference if it belongs to another open Calc document
&apos;&apos;&apos; DestinationCell: the destination of the copied range of cells, as a string
-&apos;&apos;&apos; If given as range, the destination will be reduced to its top-left cell
+&apos;&apos;&apos; If given as a range of cells, the destination will be reduced to its top-left cell
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; A string representing the modified range of cells
&apos;&apos;&apos; The modified area depends only on the size of the source area
@@ -789,7 +792,7 @@ Public Function DCount(Optional ByVal Range As Variant) As Long
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Range : the range as a string where to get the values from
&apos;&apos;&apos; Returns:
-&apos;&apos;&apos; The number of numeric values a Long
+&apos;&apos;&apos; The number of numeric values as a Long
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; Val = oDoc.DCount(&quot;~.A1:A1000&quot;)
@@ -859,6 +862,7 @@ Public Function Forms(Optional ByVal SheetName As Variant _
&apos;&apos;&apos; - the list of the Forms contained in the given sheet
&apos;&apos;&apos; - a SFDocuments.Form object based on its name or its index
&apos;&apos;&apos; Args:
+&apos;&apos;&apos; SheetName: the name of the sheet containing the requested form or forms
&apos;&apos;&apos; Form: a form stored in the document given by its name or its index
&apos;&apos;&apos; When absent, the list of available forms is returned
&apos;&apos;&apos; To get the first (unique ?) form stored in the form document, set Form = 0
@@ -1035,8 +1039,10 @@ Try:
&apos; Superclass or subclass property ?
If ScriptForge.SF_Array.Contains([_Super].Properties(), PropertyName) Then
GetProperty = [_Super].GetProperty(PropertyName)
- Else
+ ElseIf Len(ObjectName) = 0 Then
GetProperty = _PropertyGet(PropertyName)
+ Else
+ GetProperty = _PropertyGet(PropertyName, ObjectName)
End If
Finally:
@@ -1177,7 +1183,7 @@ Public Sub ImportFromDatabase(Optional ByVal FileName As Variant _
&apos;&apos;&apos; RegistrationName: the name of a registered database
&apos;&apos;&apos; It is ignored if FileName &lt;&gt; &quot;&quot;
&apos;&apos;&apos; DestinationCell: the destination of the copied range of cells, as a string
-&apos;&apos;&apos; If given as range, the destination will be reduced to its top-left cell
+&apos;&apos;&apos; If given as a range of cells, the destination will be reduced to its top-left cell
&apos;&apos;&apos; SQLCommand: either a table or query name (without square brackets)
&apos;&apos;&apos; or a full SQL commands where table and fieldnames are preferably surrounded with square brackets
&apos;&apos;&apos; Returns:
@@ -1375,6 +1381,7 @@ Public Function MoveRange(Optional ByVal Source As Variant _
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Source: the source range of cells as a string
&apos;&apos;&apos; Destination: the destination of the moved range of cells, as a string
+&apos;&apos;&apos; If given as a range of cells, the destination will be reduced to its top-left cell
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; A string representing the modified range of cells
&apos;&apos;&apos; The modified area depends only on the size of the source area
@@ -1556,7 +1563,7 @@ Public Function Properties() As Variant
, &quot;Height&quot; _
, &quot;IsBase&quot; _
, &quot;IsCalc&quot; _
- , &quot;IsDraw &quot; _
+ , &quot;IsDraw&quot; _
, &quot;IsImpress&quot; _
, &quot;IsMath&quot; _
, &quot;IsWriter&quot; _
@@ -1958,7 +1965,7 @@ Public Function SortRange(Optional ByVal Range As Variant _
&apos;&apos;&apos; DestinationCell: the destination of the sorted range of cells, as a string
&apos;&apos;&apos; If given as range, the destination will be reduced to its top-left cell
&apos;&apos;&apos; By default, Range is overwritten with its sorted content
-&apos;&apos;&apos; ContainsHeader: when True, the first row/column is not sorted
+&apos;&apos;&apos; ContainsHeader: when True, the first row/column is not sorted. Default = False
&apos;&apos;&apos; CaseSensitive: only for string comparisons, default = False
&apos;&apos;&apos; SortColumns: when True, the columns are sorted from left to right
&apos;&apos;&apos; Default = False: rows are sorted from top to bottom.
@@ -1979,7 +1986,7 @@ Dim vSortFields As Variant &apos; Array of com.sun.star.table.TableSortField
Dim sOrder As String &apos; Item in SortOrder
Dim i As Long
Const cstThisSub = &quot;SFDocuments.Calc.SortRange&quot;
-Const cstSubArgs = &quot;Range, SortKeys, [TargetRange=&quot;&quot;&quot;&quot;], [SortOrder=&quot;&quot;ASC&quot;&quot;], [ContainsHeader=False], [CaseSensitive=False], [SortColumns=False]&quot;
+Const cstSubArgs = &quot;Range, SortKeys, [TargetRange=&quot;&quot;&quot;&quot;], [SortOrder=&quot;&quot;ASC&quot;&quot;], [DestinationCell=&quot;&quot;&quot;&quot;], [ContainsHeader=False], [CaseSensitive=False], [SortColumns=False]&quot;
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
sSort = &quot;&quot;
@@ -2294,6 +2301,7 @@ Private Function _ConvertToDataArray(ByRef pvArray As Variant _
) As Variant
&apos;&apos;&apos; Create a 2-dimensions nested array (compatible with the ranges .DataArray property)
&apos;&apos;&apos; from a scalar, a 1D array or a 2D array
+&apos;&apos;&apos; Input may be a 1D array of arrays, typically when call issued by a Python script
&apos;&apos;&apos; Array items are converted to (possibly empty) strings or doubles
&apos;&apos;&apos; Args:
&apos;&apos;&apos; pvArray: the input scalar or array. If array, must be 1 or 2D otherwise it is ignored.
@@ -2313,13 +2321,14 @@ Dim vDataArray() As Variant &apos; Return value
Dim vVector() As Variant &apos; A temporary 1D array
Dim vItem As Variant &apos; A single input item
Dim iDims As Integer &apos; Number of dimensions of the input argument
-Dim lMin1 As Long &apos; Lower bound of input array
-Dim lMax1 As Long &apos; Upper bound
-Dim lMin2 As Long &apos; Lower bound
-Dim lMax2 As Long &apos; Upper bound
+Dim lMin1 As Long &apos; Lower bound (1) of input array
+Dim lMax1 As Long &apos; Upper bound (1)
+Dim lMin2 As Long &apos; Lower bound (2)
+Dim lMax2 As Long &apos; Upper bound (2)
Dim lRows As Long &apos; Upper bound of vDataArray
Dim lCols As Long &apos; Upper bound of vVector
Dim bHorizontal As Boolean &apos; Horizontal vector
+Dim bDataArray As Boolean &apos; Input array is already an array of arrays
Dim i As Long
Dim j As Long
@@ -2339,11 +2348,18 @@ Try:
Select Case iDims
Case -1 &apos; Scalar value
Case 1
- bHorizontal = ( plRows = 0 And plColumns &gt; 0)
- If Not bHorizontal Then
- lMin1 = LBound(pvArray) : lMax1 = UBound(pvArray)
+ bHorizontal = ( plRows = 0 And plColumns &gt; 0 )
+ bDataArray = IsArray(pvArray(0))
+ If Not bDataArray Then
+ If Not bHorizontal Then
+ lMin1 = LBound(pvArray) : lMax1 = UBound(pvArray)
+ Else
+ lMin2 = LBound(pvArray) : lMax2 = UBound(pvArray)
+ End If
Else
- lMin2 = LBound(pvArray) : lMax2 = UBound(pvArray)
+ iDims = 2
+ lMin1 = LBound(pvArray) : lMax1 = UBound(pvArray)
+ lMin2 = LBound(pvArray(0)) : lMax2 = UBound(pvArray(0))
End If
Case 2
lMin1 = LBound(pvArray, 1) : lMax1 = UBound(pvArray, 1)
@@ -2385,7 +2401,11 @@ Try:
vItem = _ConvertToCellValue(pvArray(i + lMin1))
End If
Case 2
- vItem = _ConvertToCellValue(pvArray(i + lMin1, j + lMin2))
+ If bDataArray Then
+ vItem = _ConvertToCellValue(pvArray(i + lMin1)(j + lMin2))
+ Else
+ vItem = _ConvertToCellValue(pvArray(i + lMin1, j + lMin2))
+ End If
End Select
vVector(j) = vItem
End If
@@ -2581,6 +2601,7 @@ Try:
Set oOffset = New _Address
With oOffset
.ObjectType = CALCREFERENCE
+ .ServiceName = SERVICEREFERENCE
.RawAddress = oNewRange.AbsoluteName
.Component = _Component
.XSpreadsheet = oNewRange.Spreadsheet
@@ -2631,6 +2652,7 @@ Dim oSelect As Object &apos; Current selection
.SheetName = &quot;&quot; : .RangeName = &quot;&quot;
.ObjectType = CALCREFERENCE
+ .ServiceName = SERVICEREFERENCE
.RawAddress = psAddress
Set .XSpreadSheet = Nothing : Set .XCellRange = Nothing
diff --git a/wizards/source/sfdocuments/SF_Form.xba b/wizards/source/sfdocuments/SF_Form.xba
index 5e1f011c8a1d..2fc8f6d60038 100644
--- a/wizards/source/sfdocuments/SF_Form.xba
+++ b/wizards/source/sfdocuments/SF_Form.xba
@@ -15,7 +15,7 @@ Option Explicit
&apos;&apos;&apos; SF_Form
&apos;&apos;&apos; =======
&apos;&apos;&apos; Management of forms defined in LibreOffice documents. Supported types are Base, Calc and Writer documents.
-&apos;&apos;&apos; For Base documents, it includes the management of subforms
+&apos;&apos;&apos; It includes the management of subforms
&apos;&apos;&apos; Each instance of the current class represents a single form or a single subform
&apos;&apos;&apos;
&apos;&apos;&apos; A form may optionally be (understand &quot;is often&quot;) linked to a data source manageable with the SFDatabases.Database service
@@ -916,7 +916,7 @@ REM ----------------------------------------------------------------------------
Public Function MovePrevious(Optional ByVal Offset As Variant) As Boolean
&apos;&apos;&apos; The cursor is (re)positioned on the previous row
&apos;&apos;&apos; Args:
-&apos;&apos;&apos; Offset: The number of records to go forward (default = 1)
+&apos;&apos;&apos; Offset: The number of records to go backward (default = 1)
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; True if cursor move is successful
&apos;&apos;&apos; Example:
@@ -1070,7 +1070,7 @@ Public Function Subforms(Optional ByVal Subform As Variant) As Variant
&apos;&apos;&apos; An instance of the SF_Form class if Subform exists
&apos;&apos;&apos; Example:
&apos;&apos;&apos; Dim myForm As Object, myList As Variant, mySubform As Object
-&apos;&apos;&apos; myList = oForm.Subforms()
+&apos;&apos;&apos; myList = myForm.Subforms()
&apos;&apos;&apos; Set mySubform = myForm.Subforms(&quot;mySubform&quot;)
Dim oSubform As Object &apos; The new Form class instance
diff --git a/wizards/source/sfdocuments/SF_FormControl.xba b/wizards/source/sfdocuments/SF_FormControl.xba
index 7fbd49bba965..a40b902e3425 100644
--- a/wizards/source/sfdocuments/SF_FormControl.xba
+++ b/wizards/source/sfdocuments/SF_FormControl.xba
@@ -547,7 +547,7 @@ End Property &apos; SFDocuments.SF_FormControl.OnUpdated (let)
REM -----------------------------------------------------------------------------
Property Get Parent() As Object
-&apos;&apos;&apos; Return the Parent dialog object of the actual control
+&apos;&apos;&apos; Return the Parent form or [table]control object of the actual control
Parent = _PropertyGet(&quot;Parent&quot;, Nothing)
End Property &apos; SFDocuments.SF_FormControl.Parent
@@ -860,9 +860,9 @@ Public Function SetFocus() As Boolean
&apos;&apos;&apos; True if focusing is successful
&apos;&apos;&apos; Example:
&apos;&apos;&apos; Dim oDoc As Object, oForm As Object, oControl As Object
-&apos;&apos;&apos; Set oDoc = Set oDoc = CreateScriptService(&quot;SFDocuments.Document&quot;, ThisComponent)
+&apos;&apos;&apos; Set oDoc = CreateScriptService(&quot;SFDocuments.Document&quot;, ThisComponent)
&apos;&apos;&apos; Set oForm = oDoc.Forms(0)
-&apos;&apos;&apos; Set oControl = oDlg.Controls(&quot;thisControl&quot;)
+&apos;&apos;&apos; Set oControl = oForm.Controls(&quot;thisControl&quot;)
&apos;&apos;&apos; oControl.SetFocus()
Dim bSetFocus As Boolean &apos; Return value
@@ -1846,4 +1846,4 @@ Private Function _Repr() As String
End Function &apos; SFDocuments.SF_FormControl._Repr
REM ============================================ END OF SFDOCUMENTS.SF_FORMCONTROL
-</script:module>
+</script:module> \ No newline at end of file
diff --git a/wizards/source/sfdocuments/SF_Register.xba b/wizards/source/sfdocuments/SF_Register.xba
index d2b0dafd341f..a8872e4115ed 100644
--- a/wizards/source/sfdocuments/SF_Register.xba
+++ b/wizards/source/sfdocuments/SF_Register.xba
@@ -66,8 +66,8 @@ Public Sub RegisterScriptServices() As Variant
With GlobalScope.ScriptForge.SF_Services
.RegisterService(&quot;Document&quot;, &quot;SFDocuments.SF_Register._NewDocument&quot;) &apos; Reference to the function initializing the service
- .RegisterService(&quot;Calc&quot;, &quot;SFDocuments.SF_Register._NewDocument&quot;) &apos; Same references, distinction is made inside the function
- .RegisterService(&quot;Base&quot;, &quot;SFDocuments.SF_Register._NewDocument&quot;) &apos; Same references, distinction is made inside the function
+ .RegisterService(&quot;Calc&quot;, &quot;SFDocuments.SF_Register._NewDocument&quot;) &apos; Same reference, distinction is made inside the function
+ .RegisterService(&quot;Base&quot;, &quot;SFDocuments.SF_Register._NewDocument&quot;) &apos; Same reference, distinction is made inside the function
.RegisterEventManager(&quot;DocumentEvent&quot;, &quot;SFDocuments.SF_Register._EventManager&quot;) &apos; Reference to the events manager
.RegisterEventManager(&quot;FormEvent&quot;, &quot;SFDocuments.SF_Register._FormEventManager&quot;)&apos; Reference to the form and controls events manager
End With