From d06cb471ecab814c29c3b8948933fc17b63ec21e Mon Sep 17 00:00:00 2001 From: Jean-Pierre Ledure Date: Tue, 29 Dec 2020 18:31:09 +0100 Subject: ScriptForge - (SFDocuments) create a SF_Form instance with Subforms() Subforms are controls in UNO They are considered as form objects in ScriptForge Additional error message in po files SF_Form._IsStillAlive() has been simplified SF_Form._GetParents() has been reviewed to incorporate subforms Change-Id: I89306d5c65e34ae1596f84b674ed338e070957f5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/108475 Tested-by: Jean-Pierre Ledure Reviewed-by: Jean-Pierre Ledure --- wizards/source/scriptforge/SF_Exception.xba | 4 + wizards/source/scriptforge/SF_Root.xba | 15 ++- wizards/source/scriptforge/po/ScriptForge.pot | 20 +++- wizards/source/scriptforge/po/en.po | 20 +++- wizards/source/sfdocuments/SF_Base.xba | 2 +- wizards/source/sfdocuments/SF_Calc.xba | 2 +- wizards/source/sfdocuments/SF_Document.xba | 4 +- wizards/source/sfdocuments/SF_Form.xba | 141 ++++++++++++++++++++------ wizards/source/sfdocuments/SF_Register.xba | 3 +- 9 files changed, 165 insertions(+), 46 deletions(-) (limited to 'wizards') diff --git a/wizards/source/scriptforge/SF_Exception.xba b/wizards/source/scriptforge/SF_Exception.xba index c4a0f6c85370..fa0db91d06af 100644 --- a/wizards/source/scriptforge/SF_Exception.xba +++ b/wizards/source/scriptforge/SF_Exception.xba @@ -109,6 +109,7 @@ Const FORMDEADERROR = "FORMDEADERROR" Const CALCFORMNOTFOUNDERROR = "CALCFORMNOTFOUNDERROR" Const WRITERFORMNOTFOUNDERROR = "WRITERFORMNOTFOUNDERROR" Const BASEFORMNOTFOUNDERROR = "BASEFORMNOTFOUNDERROR" +Const SUBFORMNOTFOUNDERROR = "SUBFORMNOTFOUNDERROR" ' SF_Dialog Const DIALOGNOTFOUNDERROR = "DIALOGNOTFOUNDERROR" @@ -842,6 +843,9 @@ Try: Case BASEFORMNOTFOUNDERROR ' SF_Base.Forms(Index, FormDocument, BaseDocument) sMessage = sLocation _ & "\n" & "\n" & .GetText("BASEFORMNOTFOUND", pvArgs(0), pvArgs(1), pvArgs(2)) + Case SUBFORMNOTFOUNDERROR ' SF_Form.Subforms(Subform, Mainform) + sMessage = sLocation _ + & "\n" & "\n" & .GetText("SUBFORMNOTFOUND", pvArgs(0), pvArgs(1)) Case DIALOGNOTFOUNDERROR ' SF_Dialog._NewDialog(Service, DialogName, WindowName) sMessage = sLocation _ & "\n" & "\n" & .GetText("DIALOGNOTFOUND", pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3), pvArgs(4) _ diff --git a/wizards/source/scriptforge/SF_Root.xba b/wizards/source/scriptforge/SF_Root.xba index 22a4a8aba2b2..3d643acdd121 100644 --- a/wizards/source/scriptforge/SF_Root.xba +++ b/wizards/source/scriptforge/SF_Root.xba @@ -740,7 +740,7 @@ Try: , MsgId := "The requested form could not be found in the Calc sheet. The given index is off-limits.\n\n" _ & "The concerned Calc document is '%3'.\n\n" _ & "The name of the sheet = '%2'\n" _ - & "The index = %1" _ + & "The index = %1." _ , Comment := "SF_Form determination\n" _ & "%1: A number\n" _ & "%2: A sheet name\n" _ @@ -750,7 +750,7 @@ Try: .AddText( Context := "WRITERFORMNOTFOUND" _ , MsgId := "The requested form could not be found in the Writer document. The given index is off-limits.\n\n" _ & "The concerned Writer document is '%2'.\n\n" _ - & "The index = %1" _ + & "The index = %1." _ , Comment := "SF_Form determination\n" _ & "%1: A number\n" _ & "%2: A file name" _ @@ -759,12 +759,21 @@ Try: .AddText( Context := "BASEFORMNOTFOUND" _ , MsgId := "The requested form could not be found in the form document '%2'. The given index is off-limits.\n\n" _ & "The concerned Base document is '%3'.\n\n" _ - & "The index = %1" _ + & "The index = %1." _ , Comment := "SF_Form determination\n" _ & "%1: A number\n" _ & "%2: A string\n" _ & "%3: A file name" _ ) + ' SF_Form.Subforms + .AddText( Context := "SUBFORMNOTFOUND" _ + , MsgId := "The requested subform could not be found below the given main form.\n\n" _ + & "The main form = '%2'.\n" _ + & "The subform = '%1'." _ + , Comment := "SF_Form determination\n" _ + & "%1: A form name\n" _ + & "%2: A form name" _ + ) ' SF_Dialog._NewDialog .AddText( Context := "DIALOGNOTFOUND" _ , MsgId := "The requested dialog could not be located in the given container or library.\n" _ diff --git a/wizards/source/scriptforge/po/ScriptForge.pot b/wizards/source/scriptforge/po/ScriptForge.pot index 9e39b5da6896..d75dbab0a991 100644 --- a/wizards/source/scriptforge/po/ScriptForge.pot +++ b/wizards/source/scriptforge/po/ScriptForge.pot @@ -14,7 +14,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://bugs.libreoffice.org/enter_bug.cgi?product=LibreOffice&bug_status=UNCONFIRMED&component=UI\n" -"POT-Creation-Date: 2020-12-15 15:57:29\n" +"POT-Creation-Date: 2020-12-29 18:05:28\n" "PO-Revision-Date: YYYY-MM-DD HH:MM:SS\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -750,7 +750,7 @@ msgid "" "The concerned Calc document is '%3'.\n" "\n" "The name of the sheet = '%2'\n" -"The index = %1" +"The index = %1." msgstr "" #. SF_Form determination @@ -764,7 +764,7 @@ msgid "" "\n" "The concerned Writer document is '%2'.\n" "\n" -"The index = %1" +"The index = %1." msgstr "" #. SF_Form determination @@ -779,7 +779,19 @@ msgid "" "\n" "The concerned Base document is '%3'.\n" "\n" -"The index = %1" +"The index = %1." +msgstr "" + +#. SF_Form determination +#. %1: A form name +#. %2: A form name +#, kde-format +msgctxt "SUBFORMNOTFOUND" +msgid "" +"The requested subform could not be found below the given main form.\n" +"\n" +"The main form = '%2'.\n" +"The subform = '%1'." msgstr "" #. SF_Dialog creation diff --git a/wizards/source/scriptforge/po/en.po b/wizards/source/scriptforge/po/en.po index 9e39b5da6896..d75dbab0a991 100644 --- a/wizards/source/scriptforge/po/en.po +++ b/wizards/source/scriptforge/po/en.po @@ -14,7 +14,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://bugs.libreoffice.org/enter_bug.cgi?product=LibreOffice&bug_status=UNCONFIRMED&component=UI\n" -"POT-Creation-Date: 2020-12-15 15:57:29\n" +"POT-Creation-Date: 2020-12-29 18:05:28\n" "PO-Revision-Date: YYYY-MM-DD HH:MM:SS\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -750,7 +750,7 @@ msgid "" "The concerned Calc document is '%3'.\n" "\n" "The name of the sheet = '%2'\n" -"The index = %1" +"The index = %1." msgstr "" #. SF_Form determination @@ -764,7 +764,7 @@ msgid "" "\n" "The concerned Writer document is '%2'.\n" "\n" -"The index = %1" +"The index = %1." msgstr "" #. SF_Form determination @@ -779,7 +779,19 @@ msgid "" "\n" "The concerned Base document is '%3'.\n" "\n" -"The index = %1" +"The index = %1." +msgstr "" + +#. SF_Form determination +#. %1: A form name +#. %2: A form name +#, kde-format +msgctxt "SUBFORMNOTFOUND" +msgid "" +"The requested subform could not be found below the given main form.\n" +"\n" +"The main form = '%2'.\n" +"The subform = '%1'." msgstr "" #. SF_Dialog creation diff --git a/wizards/source/sfdocuments/SF_Base.xba b/wizards/source/sfdocuments/SF_Base.xba index dec3b2eccad9..f60886e574c9 100644 --- a/wizards/source/sfdocuments/SF_Base.xba +++ b/wizards/source/sfdocuments/SF_Base.xba @@ -180,7 +180,7 @@ Public Function Forms(Optional ByVal FormDocument As Variant _ ''' When absent, the list of available forms is returned ''' To get the first (unique ?) form stored in the form document, set Form = 0 ''' Returns: -''' A zero-base array of strings if Form is absent +''' A zero-based array of strings if Form is absent ''' An instance of the SF_Form class if Form exists ''' Exceptions: ''' FORMDEADERROR The form is not open diff --git a/wizards/source/sfdocuments/SF_Calc.xba b/wizards/source/sfdocuments/SF_Calc.xba index 8f542af3aa58..852cd0ad138d 100644 --- a/wizards/source/sfdocuments/SF_Calc.xba +++ b/wizards/source/sfdocuments/SF_Calc.xba @@ -865,7 +865,7 @@ Public Function Forms(Optional ByVal SheetName As Variant _ ''' Exceptions: ''' CALCFORMNOTFOUNDERROR Form not found ''' Returns: -''' A zero-base array of strings if Form is absent +''' A zero-based array of strings if Form is absent ''' An instance of the SF_Form class if Form exists ''' Example: ''' Dim myForm As Object, myList As Variant diff --git a/wizards/source/sfdocuments/SF_Document.xba b/wizards/source/sfdocuments/SF_Document.xba index a77e0ad9223b..7b66600794a9 100644 --- a/wizards/source/sfdocuments/SF_Document.xba +++ b/wizards/source/sfdocuments/SF_Document.xba @@ -469,7 +469,7 @@ Public Function Forms(Optional ByVal Form As Variant) As Variant ''' Exceptions: ''' WRITERFORMNOTFOUNDERROR Form not found ''' Returns: -''' A zero-base array of strings if Form is absent +''' A zero-based array of strings if Form is absent ''' An instance of the SF_Form class if Form exists ''' Example: ''' Dim myForm As Object, myList As Variant @@ -504,7 +504,7 @@ Try: Forms = vFormNames Else If VarType(Form) = V_STRING Then ' Find the form by name - If Not ScriptForge.SF_Utils._Validate(Form, "Form", V_STRING, vFormNames) Then GoTo Finally + If Not ScriptForge.SF_Array.Contains(vFormNames, Form, CaseSensitive := True) Then GoTo CatchNotFound Set oXForm = oForms.getByName(Form) Else ' Find the form by index If Form < 0 Or Form >= oForms.Count Then GoTo CatchNotFound diff --git a/wizards/source/sfdocuments/SF_Form.xba b/wizards/source/sfdocuments/SF_Form.xba index 1ed94d51faf3..1c6b14770055 100644 --- a/wizards/source/sfdocuments/SF_Form.xba +++ b/wizards/source/sfdocuments/SF_Form.xba @@ -64,7 +64,8 @@ Option Explicit REM ================================================================== EXCEPTIONS -Private Const FORMDEADERROR = "FORMDEADERROR" +Private Const FORMDEADERROR = "FORMDEADERROR" +Private Const SUBFORMNOTFOUNDERROR = "SUBFORMNOTFOUNDERROR" REM ============================================================= PRIVATE MEMBERS @@ -84,7 +85,6 @@ Private _Component As Object ' com.sun.star.lang.XComponent or com.sun.s ' EVents management Private _CacheIndex As Long ' Index in central cache storage -Private _IssuedFromEvent As Boolean ' When True instance is always presumed alive ' Form UNO references ' The entry to the interactions with the form. Validity checked by the _IsStillAlive() method @@ -119,7 +119,6 @@ Private Sub Class_Initialize() Set _FormDocument = Nothing _FormType = ISUNDEFINED _CacheIndex = -1 - _IssuedFromEvent = False Set _Form = Nothing Set _Database = Nothing _ControlCache = Array() @@ -172,6 +171,12 @@ Property Get Name() As String Name = _PropertyGet("Name") End Property ' SFDocuments.SF_Form.Name +REM ----------------------------------------------------------------------------- +Property Get Parent() As Object +''' Return the Parent of the actual Form + Parent = _PropertyGet("Parent") +End Property ' SFDocuments.SF_Form.Parent + REM ----------------------------------------------------------------------------- Property Get Visible() As Variant ''' The Visible property is False before the Execute() statement @@ -349,7 +354,7 @@ Public Function GetDatabase(Optional ByVal User As Variant _ ''' Returns a Database instance (service = SFDatabases.Database) giving access ''' to the execution of SQL commands on the database defined and/or stored in ''' the actual Base document -''' Each form has its own database connection, except within Base documents where +''' Each main form has its own database connection, except within Base documents where ''' they all share the same connection ''' Args: ''' User, Password: the login parameters as strings. Defaults = "" @@ -393,7 +398,9 @@ Try: If _FormType = ISBASEFORM Then ' Fetch the shared connection Set _Database = [_Parent].GetDatabase(User, Password) - ElseIf Len(_Form.DataSOurceName) = 0 Then ' There is no database linked with the form + ElseIf _FormType = ISSUBFORM Then + ' Return Nothing : method is not applicable to subforms + ElseIf Len(_Form.DataSourceName) = 0 Then ' There is no database linked with the form ' Return Nothing Else ' Check if DataSourceName is a file or a registered name and create database instance accordingly @@ -553,6 +560,87 @@ Catch: GoTo Finally End Function ' SFDocuments.SF_Form.SetProperty +REM ----------------------------------------------------------------------------- +Public Function Subforms(Optional ByVal Subform As Variant) As Variant +''' Return either +''' - the list of the subforms contained in the actual form or subform instance +''' - a SFDocuments.Form object based on its name or its index in the alphabetic list of subforms +''' Args: +''' Subform: a subform stored in the parent form given by its name or its index +''' When absent, the list of available subforms is returned +''' To get the first (unique ?) subform stored in the parent form, set Subform = 0 +''' Exceptions: +''' SUBFORMNOTFOUNDERROR Subform not found +''' Returns: +''' A zero-based array of strings if Subform is absent +''' An instance of the SF_Form class if Subform exists +''' Example: +''' Dim myForm As Object, myList As Variant, mySubform As Object +''' myList = oForm.Subforms() +''' Set mySubform = myForm.Subforms("mySubform") + +Dim oSubform As Object ' The new Form class instance +Dim oXSubform As Object ' com.sun.star.form.XForm +Dim vSubformNames As Variant ' Array of subform names +Dim i As Long +Const cstDrawPage = 0 ' Only 1 drawpage in a Writer document + +Const cstThisSub = "SFDocuments.Form.Subforms" +Const cstSubArgs = "[Subform=""""]" + + If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch + +Check: + If IsMissing(Subform) Or IsEmpty(Subform) Then Subform = "" + If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then + If Not _IsStillAlive() Then GoTo Finally + If Not ScriptForge.SF_Utils._Validate(Subform, "Subform", Array(V_STRING, ScriptForge.V_NUMERIC)) Then GoTo Finally + End If + +Try: + ' Collect all control names and retain only the subforms + vSubformNames = _Form.getElementNames() + For i = 0 To UBound(vSubformNames) + Set oSubform = _Form.getByName(vSubformNames(i)) + ' Subforms are the only control types having no ClassId property + If ScriptForge.SF_Session.HasUnoProperty(oSubform, "ClassId") Then vSubformNames(i) = "" + Next i + vSubformNames = ScriptForge.SF_Array.TrimArray(vSubformNames) + + If Len(Subform) = 0 Then ' Return the list of valid subform names + Subforms = vSubformNames + Else + If VarType(Subform) = V_STRING Then ' Find the form by name + If Not ScriptForge.SF_Array.Contains(vSubformNames, Subform, CaseSensitive := True) Then GoTo CatchNotFound + Set oXSubform = _Form.getByName(Subform) + Else ' Find the form by index + If Subform < 0 Or Subform > UBound(vSubformNames) Then GoTo CatchNotFound + Set oXSubform = _Form.getByName(vSubformNames(Subform)) + End If + ' Create the new Form class instance + Set oSubform = SF_Register._NewForm(oXSubform) + With oSubform + Set .[_Parent] = [Me] + ._FormType = ISSUBFORM + Set ._Component = _Component + Set ._FormDocument = _FormDocument + ._SheetName = _SheetName + ._FormDocumentName = _FormDocumentName + ._Initialize() + End With + Set Subforms = oSubform + End If + +Finally: + ScriptForge.SF_Utils._ExitFunction(cstThisSub) + Exit Function +Catch: + GoTo Finally +CatchNotFound: + ScriptForge.SF_Exception.RaiseFatal(SUBFORMNOTFOUNDERROR, Subform, _Name) + GoTo Finally +End Function ' SFDocuments.SF_Form.Subforms + REM =========================================================== PRIVATE FUNCTIONS REM ----------------------------------------------------------------------------- @@ -625,9 +713,14 @@ Try: If iLevel = 1 Then _FormType = ISSUBFORM Set [_Parent] = SF_Register._NewForm(oParent) - ' The parent form could be a main form - [_Parent]._Initialize() - ' Everything is in the parent, stop scan + ' Everything is in the parent, copy items and stop scan + [_Parent]._Initialize() ' Current method is called recursively here + With [_Parent] + _SheetName = ._SheetName + _FormDocumentName = ._FormDocumentName + Set _FormDocument = ._FormDocument + Set _Component = ._Component + End With Exit Sub End If Case "com.sun.star.form.OFormsCollection" ' The collection of forms inside a drawpage @@ -667,7 +760,6 @@ Public Sub _Initialize() ''' - complete the missing private members ''' - store the new instance in the cache - _GetParents() _CacheIndex = SF_Register._AddFormToCache(_Form, [Me]) @@ -690,22 +782,10 @@ Check: If IsMissing(pbError) Then pbError = True Try: - If _IssuedFromEvent Then ' Instance is presumed alive when issued from an event - bAlive = True - Else - ' For usual documents, check that the parent document is still open - ' For Base forms and subforms, check the openness of the main form - Select Case _FormType - Case ISDOCFORM, ISCALCFORM - bAlive = [_Parent]._IsStillAlive(pbError) - Case ISBASEFORM, ISSUBFORM - ' A form that has never been opened has no component - ' If ever opened and closed afterwards, it keeps the Component but loses its Controller - bAlive = Not IsNull(_FormDocument.Component) - If bAlive Then bAlive = Not IsNull(_FormDocument.Component.CurrentController) - End Select - If Not bAlive Then GoTo Catch - End If + ' At main form termination, all database connections are lost + bAlive = Not IsNull(_Form) + If bAlive Then bAlive = Not IsNull(_Form.ActiveConnection) + If Not bAlive Then GoTo Catch Finally: _IsStillAlive = bAlive @@ -716,7 +796,7 @@ Catch: ' Keep error message elements before disposing the instance sName = _SheetName & _FormDocumentName ' At least one of them is a zero-length string sName = Iif(Len(sName) > 0, "[" & sName & "].", "") & _Name - sId = [_Parent]._FileIdent() + If Not IsNull(_Component) Then sId = _Component.Location Else sId = "" ' Dispose the actual forms instance Dispose() ' Display error message @@ -742,13 +822,14 @@ Const cstSubArgs = "" If IsNull(oSession) Then Set oSession = ScriptForge.SF_Services.CreateScriptService("Session") Select Case UCase(psProperty) - Case UCase("Caption") - Case UCase("Height") +' Case UCase("Caption") +' Case UCase("Height") Case UCase("Name") + _PropertyGet = _Name Case UCase("Parent") _PropertyGet = [_Parent] - Case UCase("Visible") - Case UCase("Width") +' Case UCase("Visible") +' Case UCase("Width") Case UCase("XForm") Set _PropertyGet = _Form Case Else diff --git a/wizards/source/sfdocuments/SF_Register.xba b/wizards/source/sfdocuments/SF_Register.xba index 55224b0d53d4..d530d5b84181 100644 --- a/wizards/source/sfdocuments/SF_Register.xba +++ b/wizards/source/sfdocuments/SF_Register.xba @@ -246,7 +246,8 @@ Try: If oSession.UnoObjectType(vEvent) = "com.sun.star.lang.EventObject" Then If oSession.UnoObjectType(vEvent.Source) = "com.sun.star.comp.forms.ODatabaseForm" Then Set oSource = SF_Register._NewForm(vEvent.Source) - Else ' Add for controls + If oSource._CacheIndex < 0 Then oSource._Initialize() + Else ' TODO for controls End If End If -- cgit