[Libreoffice-commits] core.git: wizards/source

Jean-Pierre Ledure (via logerrit) logerrit at kemper.freedesktop.org
Sat Dec 26 15:54:05 UTC 2020


 wizards/source/scriptforge/SF_Services.xba |    3 
 wizards/source/sfdocuments/SF_Base.xba     |   58 +++++++++-
 wizards/source/sfdocuments/SF_Calc.xba     |    8 -
 wizards/source/sfdocuments/SF_Document.xba |   11 -
 wizards/source/sfdocuments/SF_Form.xba     |  162 ++++++++++++++++++++++-------
 wizards/source/sfdocuments/SF_Register.xba |  109 +++++++++++++++++--
 6 files changed, 280 insertions(+), 71 deletions(-)

New commits:
commit f6ba6fc1adde356a88f5e3f91a013aaf3015a55a
Author:     Jean-Pierre Ledure <jp at ledure.be>
AuthorDate: Sat Dec 26 13:21:21 2020 +0100
Commit:     Jean-Pierre Ledure <jp at ledure.be>
CommitDate: Sat Dec 26 16:53:18 2020 +0100

    ScriptForge - (SF_Form) event management and bottom-up tree scan
    
    Strategy for management of Form and FormControl events:
    
    At the contrary of Dialogs and DialogControls, which are always started from some code,
    Forms and FormControls will be initiated most often by the user, even if the SFDocuments library
    allows to start forms programmatically
    
    For Forms started programmatically, the corresponding objects are built top-down
    Event management of forms and their controls requires to being able to rebuild Form
    and FormControl objects bottom-up
    
    To avoid multiple rebuilds requested by multiple events,
    1. The active form objects are cached in a global array of _FormCache types
    2. FormControl objects are cached in Form objects
    3. The bottom-up rebuild is executed only once, at instance creation
    
    Change-Id: I76ebb8064a900397427554ca47464c99266e0e5e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/108325
    Tested-by: Jenkins
    Reviewed-by: Jean-Pierre Ledure <jp at ledure.be>

diff --git a/wizards/source/scriptforge/SF_Services.xba b/wizards/source/scriptforge/SF_Services.xba
index 10b8c53978e2..39429d67384e 100644
--- a/wizards/source/scriptforge/SF_Services.xba
+++ b/wizards/source/scriptforge/SF_Services.xba
@@ -123,7 +123,8 @@ Try:
 		sService = vSplit(0)
 		'	Accept other default values for associated libraries
 		Select Case sService
-			Case "Document", "Calc", "Base"			:	sLibrary = "SFDocuments"
+			Case "Document", "Calc", "Base", "DocumentEvent", "FormEvent"
+														sLibrary = "SFDocuments"
 			Case "Dialog", "DialogEvent"			:	sLibrary = "SFDialogs"
 			Case "Database"							:	sLibrary = "SFDatabases"
 			Case Else
diff --git a/wizards/source/sfdocuments/SF_Base.xba b/wizards/source/sfdocuments/SF_Base.xba
index 31c12b016a50..dec3b2eccad9 100644
--- a/wizards/source/sfdocuments/SF_Base.xba
+++ b/wizards/source/sfdocuments/SF_Base.xba
@@ -191,7 +191,7 @@ Public Function Forms(Optional ByVal FormDocument As Variant _
 '''				Set myForm = oDoc.Forms("Folder1/myFormDocument", 0)
 
 Dim oForm As Object					'	The new Form class instance
-Dim oMainForm As Object				'	com.sun.star.comp.sdb.Content
+Dim oFormDocument As Object				'	com.sun.star.comp.sdb.Content
 Dim oXForm As Object				'	com.sun.star.form.XForm
 Dim vFormDocuments As Variant		'	Array of form documents
 Dim vFormNames As Variant			'	Array of form names
@@ -217,8 +217,8 @@ Check:
 
 Try:
 	'	Start from the form document and go down to forms
-	Set oMainForm = _FormDocuments.getByHierarchicalName(FormDocument)
-	Set oForms = oMainForm.Component.DrawPages(cstDrawPage).Forms
+	Set oFormDocument = _FormDocuments.getByHierarchicalName(FormDocument)
+	Set oForms = oFormDocument.Component.DrawPages(cstDrawPage).Forms
 	vFormNames = oForms.getElementNames()
 
 	If Len(Form) = 0 Then	'	Return the list of valid form names
@@ -237,9 +237,9 @@ Try:
 			._Name = oXForm.Name
 			Set .[Me] = oForm
 			Set .[_Parent] = [Me]
-			._DrawPage = cstDrawPage
+			Set ._Component = _Component
 			._FormDocumentName = FormDocument
-			Set ._MainForm = oMainForm
+			Set ._FormDocument = oFormDocument
 			._FormType = ISBASEFORM
 			Set ._Form = oXForm
 			._Initialize()
@@ -671,7 +671,6 @@ Private Function _CollectFormDocuments(ByRef poContainer As Object) As String
 
 Dim sCollectNames As String			'	Return value
 Dim oSubItem As Object				'	com.sun.star.container.XNameAccess (folder) or com.sun.star.ucb.XContent (form)
-Dim sFormName As String				'	Single form name
 Dim i As Long
 Const cstFormType = "application/vnd.oasis.opendocument.text"
 									'	Identifies forms. Folders have a zero-length content type
@@ -705,6 +704,53 @@ Private Function _FileIdent() As String
 
 End Function	'	SFDocuments.SF_Base._FileIdent
 
+REM -----------------------------------------------------------------------------
+Private Function _FindByPersistentName(ByRef poContainer As Object _
+										, psPersistent As String _
+										) As Object
+'''	The FormDocuments property of a Base component has strangely
+'''	a getByHierarchical() method but no access to the same com.sun.star.comp.sdb.Content
+'''	object via its persistent/ODF name
+'''	This method returns the object having the given persistent name
+'''	The function traverses recursively the whole tree below the container until found
+'''	The initial call starts from the container _Component.getFormDocuments
+'''	The list contains closed and open forms
+'''	Args:
+'''		poContainer: the actual top of the free, initially _FormDocuments
+'''		psPersistent: a name like "Obj..."
+'''	Returns:
+'''		A com.sun.star.comp.sdb.Content object (object found, the process stops)
+'''		or Nothing (object not found, the process continues)
+
+Dim oMainForm As Object				'	Return value
+Dim oSubItem As Object				'	com.sun.star.container.XNameAccess (folder) or com.sun.star.ucb.XContent (form)
+Dim i As Long
+Const cstFormType = "application/vnd.oasis.opendocument.text"
+									'	Identifies forms. Folders have a zero-length content type
+
+	On Local Error GoTo Finally
+
+Try:
+	Set oMainForm = Nothing
+	With poContainer
+		For i = 0 To .Count - 1
+			Set oSubItem = .getByIndex(i)
+			If oSubItem.ContentType = cstFormType Then		'	Examine its persistent name
+				If oSubItem.PersistentName = psPersistent Then
+					Set oMainForm = oSubItem
+					Exit For
+				End If
+			Else
+				Set oMainForm = _FindByPersistentName(oSubItem, psPersistent)
+			End If
+		Next i
+	End With
+
+Finally:
+	Set _FindByPersistentName = oMainForm
+	Exit Function
+End Function	'	SFDocuments.SF_Base.FindByPersistentName
+
 REM -----------------------------------------------------------------------------
 Private Function _IsStillAlive(Optional ByVal pbForUpdate As Boolean _
 									, Optional ByVal pbError As Boolean _
diff --git a/wizards/source/sfdocuments/SF_Calc.xba b/wizards/source/sfdocuments/SF_Calc.xba
index 8bbcf29019ac..8f542af3aa58 100644
--- a/wizards/source/sfdocuments/SF_Calc.xba
+++ b/wizards/source/sfdocuments/SF_Calc.xba
@@ -908,16 +908,12 @@ Try:
 			Set oXForm = oForms.getByIndex(Form)
 		End If
 		'	Create the new Form class instance
-		Set oForm = New SF_Form
+		Set oForm = SF_Register._NewForm(oXForm)
 		With oForm
-			._Name = oXForm.Name
-			Set .[Me] = oForm
 			Set .[_Parent] = [Me]
-			._DrawPage = cstDrawPage
 			._SheetName = SheetName
-			Set ._MainForm = Nothing
 			._FormType = ISCALCFORM
-			Set ._Form = oXForm
+			Set ._Component = _Component
 			._Initialize()
 		End With
 		Set Forms = oForm
diff --git a/wizards/source/sfdocuments/SF_Document.xba b/wizards/source/sfdocuments/SF_Document.xba
index b028d140c74f..a77e0ad9223b 100644
--- a/wizards/source/sfdocuments/SF_Document.xba
+++ b/wizards/source/sfdocuments/SF_Document.xba
@@ -79,7 +79,7 @@ Private _CustomProperties		As Object		'	Dictionary of custom properties
 
 REM ============================================================ MODULE CONSTANTS
 
-Const ISDOCFORM = 1				'	Form is stored in a Calc, Writer, ... document
+Const ISDOCFORM = 1				'	Form is stored in a Writer document
 
 REM ====================================================== CONSTRUCTOR/DESTRUCTOR
 
@@ -511,16 +511,11 @@ Try:
 			Set oXForm = oForms.getByIndex(Form)
 		End If
 		'	Create the new Form class instance
-		Set oForm = New SF_Form
+		Set oForm = SF_Register._NewForm(oXForm)
 		With oForm
-			._Name = oXForm.Name
-			Set .[Me] = oForm
 			Set .[_Parent] = [Me]
-			._DrawPage = cstDrawPage
-			._UsualName = ._Name
-			Set ._MainForm = Nothing
 			._FormType = ISDOCFORM
-			Set ._Form = oXForm
+			Set ._Component = _Component
 			._Initialize()
 		End With
 		Set Forms = oForm
diff --git a/wizards/source/sfdocuments/SF_Form.xba b/wizards/source/sfdocuments/SF_Form.xba
index 1962c54831fe..1ed94d51faf3 100644
--- a/wizards/source/sfdocuments/SF_Form.xba
+++ b/wizards/source/sfdocuments/SF_Form.xba
@@ -35,7 +35,7 @@ Option Explicit
 '''
 '''			Form: WHERE IT IS ABOUT IN THE CURRENT "Form" SERVICE
 '''				Is an abstract set of Controls in an OPEN FormDocument
-'''				Each form is (often) linked to a dataset (table, query or Select statement),
+'''				Each form is usually linked to one single dataset (table, query or Select statement),
 '''				located in any database (provided the user may access it)
 '''					A usual document may contain several forms. Each of which may have its own data source (database + dataset)
 '''					A Base form document may contain several forms. Each of which may address its own dataset. The database however is unique
@@ -75,16 +75,18 @@ Private ServiceName			As String
 
 '	Form location
 Private _Name				As String		' Internal name of the form
-Private _DrawPage			As Long			' Index in DrawPages collection
+Private _FormType			As Integer		' One of the ISxxxFORM constants
 Private _SheetName			As String		' Name as the sheet containing the form (Calc only)
 Private _FormDocumentName	As String		' The hierarchical name of the containing form document (Base only)
-Private _FormType			As Integer		' One of the ISxxxFORM constants
+Private _FormDocument		As Object		' com.sun.star.comp.sdb.Content - the containing form document
+	'	The form topmost container
+Private _Component			As Object		' com.sun.star.lang.XComponent or com.sun.star.comp.dba.ODatabaseDocument
+
+'	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 forms container found in a Base document
-'		Vital for Base forms and subforms
-Private _MainForm			As Object		' com.sun.star.comp.sdb.Content
 '		The entry to the interactions with the form. Validity checked by the _IsStillAlive() method
 '		Each method or property requiring that the form is opened should first invoke that method
 Private _Form				As Object		' com.sun.star.form.XForm or com.sun.star.comp.forms.ODatabaseForm
@@ -100,7 +102,8 @@ REM ============================================================ MODULE CONSTANT
 Const ISDOCFORM				=	1			' Form is stored in a Writer document
 Const ISCALCFORM			=	2			' Form is stored in a Calc document
 Const ISBASEFORM			=	3			' Form is stored in a Base document
-Const ISSUBFORM				=	4			' Form is a subform of a form stored in a Base document or of another subform
+Const ISSUBFORM				=	4			' Form is a subform of a form or of another subform
+Const ISUNDEFINED			=	-1			' Undefined form type
 
 REM ====================================================== CONSTRUCTOR/DESTRUCTOR
 
@@ -111,12 +114,12 @@ Private Sub Class_Initialize()
 	ObjectType = "Form"
 	ServiceName = "SFDocuments.Form"
 	_Name = ""
-	_DrawPage = -1
 	_SheetName = ""
 	_FormDocumentName = ""
-	_FormType = 0
+	Set _FormDocument = Nothing
+	_FormType = ISUNDEFINED
 	_CacheIndex = -1
-	Set _MainForm = Nothing
+	_IssuedFromEvent = False
 	Set _Form = Nothing
 	Set _Database = Nothing
 	_ControlCache = Array()
@@ -194,16 +197,10 @@ Property Let Width(Optional ByVal pvWidth As Variant)
 End Property	'	SFDocuments.SF_Form.Width (let)
 
 REM -----------------------------------------------------------------------------
-Property Get XFormModel() As Object
-'''	The XFormModel property returns the model UNO object of the Form
-	XFormModel = _PropertyGet("XFormModel")
-End Property	'	SFDocuments.SF_Form.XFormModel (get)
-
-REM -----------------------------------------------------------------------------
-Property Get XFormView() As Object
-'''	The XFormView property returns the view UNO object of the Form
-	XFormView = _PropertyGet("XFormView")
-End Property	'	SFDocuments.SF_Form.XFormView (get)
+Property Get XForm() As Object
+'''	The XForm property returns the XForm UNO object of the Form
+	XForm = _PropertyGet("XForm")
+End Property	'	SFDocuments.SF_Form.XForm (get)
 
 REM ===================================================================== METHODS
 
@@ -238,7 +235,7 @@ Try:
 		Case ISDOCFORM		:	bActivate = [_Parent].Activate()
 		Case ISCALCFORM		:	bActivate = [_Parent].Activate(_SheetName)
 		Case ISBASEFORM
-			Set oContainer = _MainForm.Component.CurrentController.Frame.ContainerWindow
+			Set oContainer = _FormDocument.Component.CurrentController.Frame.ContainerWindow
 			With oContainer
 				If .isVisible() = False Then .setVisible(True)
 				.IsMinimized = False
@@ -284,7 +281,7 @@ Try:
 	Select Case _FormType
 		Case ISDOCFORM, ISCALCFORM, ISSUBFORM
 		Case ISBASEFORM
-			_MainForm.close()
+			_FormDocument.close()
 			Dispose()
 			bClose = True
 	End Select
@@ -514,9 +511,11 @@ Public Function Properties() As Variant
 					, "OnUnloading" _
 					, "OrderBy" _
 					, "OrderByOn" _
+					, "Parent" _
 					, "RecordSource" _
 					, "Visible" _
 					, "Width" _
+					, "XForm" _
 					)
 
 End Function	'	SFDocuments.SF_Form.Properties
@@ -545,6 +544,7 @@ Check:
 
 Try:
 	SetProperty = _PropertySet(PropertyName, Value)
+				Set UI = ScriptForge.SF_Services.CreateScriptService("ScriptForge.UI")
 
 Finally:
 	SF_Utils._ExitFunction(cstThisSub)
@@ -583,11 +583,92 @@ Private Function _GetListener(ByVal psEventName As String) As String
 	
 End Function	'	SFDocuments.SF_Form._GetListener
 
+REM -----------------------------------------------------------------------------
+Private Sub _GetParents()
+'''	When the current instance is created top-down, the parents are completely defined
+'''	and nothing should be done in this method
+'''	When the a class instance is created in a (form/control) event, it is the opposite
+'''	The current method rebuilds the missing members in the instance from the bottom
+'''	Members potentially to collect are:
+'''		- _FormType
+'''		- [_Parent], the immediate parent: a form or a document instance
+'''		+ Only when the _FormType is a main form
+'''			- _SheetName (Calc only)
+'''			- _FormDocumentName (Base only)
+'''			- _FormDocument, the topmost form collection
+'''			- _Component, the containing document
+'''	They must be identified only starting from the _Form UNO object
+'''
+'''	The method is called from the _Initialize() method at instance creation
+
+Dim oParent As Object				'	Successive bottom-up parents
+Dim sType As String					'	UNO object type
+Dim sPersistentName As String		'	The Obj... name of a Base form
+Dim iLevel As Integer				'	When = 1 => first parent
+Dim oSession As Object				:	Set oSession = ScriptForge.SF_Session
+
+	On Local Error GoTo Finally		'	Being probably called from events, this method should avoid failures
+	'	When the form type is known, the upper part of the branch is not scanned
+	If _FormType <> ISUNDEFINED Then GoTo Finally
+
+Try:
+	'	The whole branch is scanned bottom-up
+	If oSession.HasUnoProperty(_Form, "Parent") Then Set oParent = _Form.Parent Else Set oParent = Nothing
+	_FormType = ISUNDEFINED
+	iLevel = 1
+
+	Do While Not IsNull(oParent)
+		sType = SF_Session.UnoObjectType(oParent)
+		Select Case sType
+			'	Collect at each level the needed info
+			Case "com.sun.star.comp.forms.ODatabaseForm"	'	The parent _Form of a subform
+				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
+					Exit Sub
+				End If
+			Case "com.sun.star.form.OFormsCollection"		'	The collection of forms inside a drawpage
+			Case "SwXTextDocument"							'	The parent document: a Writer document or a Base form document
+				If oParent.Identifier = "com.sun.star.sdb.FormDesign" Then
+					sPersistentName = ScriptForge._GetPropertyValue(oParent.Args, "HierarchicalDocumentName")
+				ElseIf oParent.Identifier = "com.sun.star.text.TextDocument" Then
+					_FormType = ISDOCFORM
+					Set [_Parent] = ScriptForge.SF_Services.CreateScriptService("SFDocuments.Document", oParent)
+					Set _Component = [_Parent]._Component
+				End If
+			Case "ScModelObj"								'	The parent document: a Calc document
+				_FormType = ISCALCFORM
+				Set [_Parent] = ScriptForge.SF_Services.CreateScriptService("SFDocuments.Document", oParent)
+				Set _Component = oParent
+				'	The triggered form event is presumed to be located in the (drawpage of the) active sheet
+				_SheetName = [_Parent].XSpreadsheet("~")
+			Case "com.sun.star.comp.dba.ODatabaseDocument"	'	The Base document
+				_FormType = ISBASEFORM
+				Set [_Parent] = ScriptForge.SF_Services.CreateScriptService("SFDocuments.Document", oParent)
+				Set _Component = oParent
+				If IsNull([_Parent]._FormDocuments) Then Set [_Parent]._FormDocuments = _Component.getFormDocuments()
+				Set _FormDocument = [_Parent]._FindByPersistentName([_Parent]._FormDocuments, sPersistentName)
+			Case Else
+		End Select
+		If oSession.HasUnoProperty(oParent, "Parent") Then Set oParent = oParent.Parent Else Set oParent = Nothing
+		iLevel = iLevel + 1
+	Loop
+
+Finally:
+	Exit Sub
+End Sub	'	SFDocuments.SF_Form._GetParents
+
 REM -----------------------------------------------------------------------------
 Public Sub _Initialize()
 '''	Achieve the creation of a SF_Form instance
+'''		- complete the missing private members
 '''		- store the new instance in the cache
 
+	
+	_GetParents()
 	_CacheIndex = SF_Register._AddFormToCache(_Form, [Me])
 
 End Sub			'	SFDocuments.SF_Form._Initialize
@@ -609,18 +690,22 @@ Check:
 	If IsMissing(pbError) Then pbError = True
 
 Try:
-	'	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(_MainForm.Component)
-			If bAlive Then bAlive = Not IsNull(_MainForm.Component.CurrentController)
-	End Select
-	If Not bAlive Then GoTo Catch
+	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
 
 Finally:
 	_IsStillAlive = bAlive
@@ -645,7 +730,7 @@ Private Function _PropertyGet(Optional ByVal psProperty As String) As Variant
 '''	Args:
 '''		psProperty: the name of the property
 
-Static oSession As Object					'	Alias of SF_Session
+Static oSession As Object		'	Alias of SF_Session
 Dim cstThisSub As String
 Const cstSubArgs = ""
 
@@ -653,7 +738,6 @@ Const cstSubArgs = ""
 	If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
 
 	ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
-	'	All the properties except one require an open form
 	If Not _IsStillAlive() Then GoTo Finally
 
 	If IsNull(oSession) Then Set oSession = ScriptForge.SF_Services.CreateScriptService("Session")
@@ -661,8 +745,12 @@ Const cstSubArgs = ""
 		Case UCase("Caption")
 		Case UCase("Height")
 		Case UCase("Name")
+		Case UCase("Parent")
+			_PropertyGet = [_Parent]
 		Case UCase("Visible")
 		Case UCase("Width")
+		Case UCase("XForm")
+			Set _PropertyGet = _Form
 		Case Else
 			_PropertyGet = Null
 	End Select
@@ -731,4 +819,4 @@ Dim sParent As String		'	To recognize the parent
 End Function	'	SFDocuments.SF_Form._Repr
 
 REM ============================================ END OF SFDOCUMENTS.SF_FORM
-</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 2dccc12c972d..55224b0d53d4 100644
--- a/wizards/source/sfdocuments/SF_Register.xba
+++ b/wizards/source/sfdocuments/SF_Register.xba
@@ -26,9 +26,20 @@ REM ================================================================== EXCEPTION
 
 REM ================================================================= DEFINITIONS
 
-'''	Event management of forms requires to being able to rebuild a Form object
-'''	from its com.sun.star.form.XForm or com.sun.star.comp.forms.ODatabaseForm UNO instance
-'''	For that purpose, the active forms are buffered in a global array of _FormCache types
+'''	Strategy for management of Form and FormControl events:
+'''	------------------------------------------------------
+'''	At the contrary of Dialogs and DialogControls, which are always started from some code,
+'''	Forms and FormControls will be initiated most often by the user, even if the SFDocuments library
+'''	allows to start forms programmatically
+'''
+'''	For Forms started programmatically, the corresponding objects are built top-down
+'''	Event management of forms and their controls requires to being able to rebuild Form
+'''	and FormControl objects bottom-up
+'''
+'''	To avoid multiple rebuilds requested by multiple events,
+'''		1. The active form objects are cached in a global array of _FormCache types
+'''		2. FormControl objects are cached in Form objects
+'''		3. The bottom-up rebuild is executed only once, at instance creation
 
 Type _FormCache
 	Terminated				As Boolean
@@ -58,7 +69,7 @@ Public Sub RegisterScriptServices() As Variant
 		.RegisterService("Calc",				"SFDocuments.SF_Register._NewDocument")		'	Same references, distinction is made inside the function
 		.RegisterService("Base",				"SFDocuments.SF_Register._NewDocument")		'	Same references, distinction is made inside the function
 		.RegisterEventManager("DocumentEvent",	"SFDocuments.SF_Register._EventManager")	'	Reference to the events manager
-		'TODO
+		.RegisterEventManager("FormEvent",		"SFDocuments.SF_Register._FormEventManager")'	Reference to the form and controls events manager
 	End With
 
 End Sub			'	SFDocuments.SF_Register.RegisterScriptServices
@@ -135,7 +146,7 @@ End Sub	'	SFDocuments.SF_Register._CleanCacheEntry
 
 REM -----------------------------------------------------------------------------
 Public Function _EventManager(Optional ByRef pvArgs As Variant) As Object
-'''	Returns a Document or Calc object corresponding with the active component
+'''	Returns a Document, Calc or Base object corresponding with the active component
 '''	which triggered the event in argument
 '''	This method should be triggered only thru the invocation of CreateScriptService
 '''	Args:
@@ -164,9 +175,7 @@ Check:
 
 Try:
 	If ScriptForge.SF_Session.UnoObjectType(vEvent) = "com.sun.star.document.DocumentEvent" Then
-		If ScriptForge.SF_Session.UnoObjectType(vEvent.Source) = "SwXTextDocument" Then
-			Set oSource = SF_Register._NewDocument(vEvent.Source)
-		End If
+		Set oSource = SF_Register._NewDocument(vEvent.Source)
 	End If
 
 Finally:
@@ -187,18 +196,65 @@ Dim oCache As _FormCache		'	Entry in the cache
 	Set oBasicForm = Nothing
 
 Try:
-	For Each oCache In _SF_.SFForms
-		If EqualUnoObjects(poForm, oCache.XUnoForm) And Not oCache.Terminated Then
-			Set oBasicForm = oCache.BasicForm
-			Exit For
+	With _SF_
+		If Not IsEmpty(.SFForms) Then
+			For Each oCache In .SFForms
+				If EqualUnoObjects(poForm, oCache.XUnoForm) And Not oCache.Terminated Then
+					Set oBasicForm = oCache.BasicForm
+					Exit For
+				End If
+			Next oCache
 		End If
-	Next oCache
+	End With
 
 Finally:
 	Set _FindFormInCache = oBasicForm
 	Exit Function
 End Function	'	SFDocuments.SF_Register._FindFormInCache
 
+REM -----------------------------------------------------------------------------
+Public Function _FormEventManager(Optional ByRef pvArgs As Variant) As Object
+'''	Returns a Form or FormControl object corresponding with the form or control
+'''	which triggered the event in argument
+'''	This method should be triggered only thru the invocation of CreateScriptService
+'''	Args:
+'''		pvEvent: com.sun.star.lang.EventObject
+'''	Returns:
+'''		the output of a Form, FormControl service or Nothing
+'''	Example:
+'''		Sub TriggeredByEvent(ByRef poEvent As Object)
+'''			Dim oForm As Object
+'''			Set oForm = CreateScriptService("SFDocuments.FormEvent", poEvent)
+'''			If Not IsNull(oForm) Then
+'''				' ... (a valid form or subform has been identified)
+'''		End Sub
+
+Dim oSource As Object			'	Return value
+Dim vEvent As Variant			'	Alias of pvArgs(0)
+Dim oSession As Object			:	Set oSession = ScriptForge.SF_Session
+
+	'	Never abort while an event is processed
+	If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Finally
+	Set oSource = Nothing
+
+Check:
+	If IsMissing(pvArgs) Or IsEmpty(pvArgs) Then pvArgs = Array()
+	If UBound(pvArgs) >= 0 Then vEvent = pvArgs(0) Else Set vEvent = Empty
+	If VarType(vEvent) <> ScriptForge.V_OBJECT Then GoTo Finally
+
+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
+		End If
+	End If
+
+Finally:
+	Set _FormEventManager = oSource
+	Exit Function
+End Function	'	SFDocuments.SF_Register._FormEventManager
+
 REM -----------------------------------------------------------------------------
 Public Function _NewDocument(Optional ByVal pvArgs As Variant) As Object
 '''	Create a new instance of the (super) SF_Document class or of one of its subclasses (SF_Calc, ...)
@@ -301,5 +357,32 @@ Catch:
 	GoTo Finally
 End Function	'	SFDocuments.SF_Register._NewDocument
 
+REM -----------------------------------------------------------------------------
+Public Function _NewForm(Optional ByRef poForm As Object) As Object
+'''	Returns an existing or a new SF_Form instance based on the argument
+'''	If the instance is new (not found in cache), the minimal members are initialized
+'''	Args:
+'''		poForm: com.sun.star.form.XForm or com.sun.star.comp.forms.ODatabaseForm
+'''	Returns:
+'''		A SF_Form instance
+
+Dim oForm As Object				'	Return value
+
+Try:
+	Set oForm = SF_Register._FindFormInCache(poForm)
+	If IsNull(oForm) Then		'	Not found
+		Set oForm = New SF_Form
+		With oForm
+			._Name = poForm.Name
+			Set .[Me] = oForm
+			Set ._Form = poForm
+		End With
+	End If
+
+Finally:
+	Set _NewForm = oForm
+	Exit Function
+End Function	'	SFDocuments.SF_Register._NewForm
+
 REM ============================================== END OF SFDOCUMENTS.SF_REGISTER
 </script:module>
\ No newline at end of file


More information about the Libreoffice-commits mailing list