calc: on editing invalidation of view with different zoom is wrong
[LibreOffice.git] / wizards / source / sfdocuments / SF_Register.xba
blob5baf37afb484df567334d0fc52ad137bc0d1381e
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
3 <script:module xmlns:script="http://openoffice.org/2000/script" script:name="SF_Register" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
4 REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
5 REM === The SFDocuments library is one of the associated libraries. ===
6 REM === Full documentation is available on https://help.libreoffice.org/ ===
7 REM =======================================================================================================================
9 Option Compatible
10 Option Explicit
12 &apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
13 &apos;&apos;&apos; SF_Register
14 &apos;&apos;&apos; ===========
15 &apos;&apos;&apos; The ScriptForge framework includes
16 &apos;&apos;&apos; the master ScriptForge library
17 &apos;&apos;&apos; a number of &quot;associated&quot; libraries SF*
18 &apos;&apos;&apos; any user/contributor extension wanting to fit into the framework
19 &apos;&apos;&apos;
20 &apos;&apos;&apos; The main methods in this module allow the current library to cling to ScriptForge
21 &apos;&apos;&apos; - RegisterScriptServices
22 &apos;&apos;&apos; Register the list of services implemented by the current library
23 &apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
25 REM ================================================================== EXCEPTIONS
27 REM ================================================================= DEFINITIONS
29 &apos;&apos;&apos; Strategy for management of Form and FormControl events:
30 &apos;&apos;&apos; ------------------------------------------------------
31 &apos;&apos;&apos; At the contrary of Dialogs and DialogControls, which are always started from some code,
32 &apos;&apos;&apos; Forms and FormControls will be initiated most often by the user, even if the SFDocuments library
33 &apos;&apos;&apos; allows to start forms programmatically
34 &apos;&apos;&apos;
35 &apos;&apos;&apos; For Forms started programmatically, the corresponding objects are built top-down
36 &apos;&apos;&apos; Event management of forms and their controls requires to being able to rebuild Form
37 &apos;&apos;&apos; and FormControl objects bottom-up
38 &apos;&apos;&apos;
39 &apos;&apos;&apos; To avoid multiple rebuilds requested by multiple events,
40 &apos;&apos;&apos; 1. The active form objects are cached in a global array of _FormCache types
41 &apos;&apos;&apos; 2. FormControl objects are cached in Form objects
42 &apos;&apos;&apos; 3. The bottom-up rebuild is executed only once, at instance creation
44 Type _FormCache
45 Terminated As Boolean
46 XUnoForm As Object
47 BasicForm As Object
48 End Type
50 REM ============================================================== PUBLIC METHODS
52 REM -----------------------------------------------------------------------------
53 Public Sub RegisterScriptServices() As Variant
54 &apos;&apos;&apos; Register into ScriptForge the list of the services implemented by the current library
55 &apos;&apos;&apos; Each library pertaining to the framework must implement its own version of this method
56 &apos;&apos;&apos;
57 &apos;&apos;&apos; It consists in successive calls to the RegisterService() and RegisterEventManager() methods
58 &apos;&apos;&apos; with 2 arguments:
59 &apos;&apos;&apos; ServiceName: the name of the service as a case-insensitive string
60 &apos;&apos;&apos; ServiceReference: the reference as an object
61 &apos;&apos;&apos; If the reference refers to a module, then return the module as an object:
62 &apos;&apos;&apos; GlobalScope.Library.Module
63 &apos;&apos;&apos; If the reference is a class instance, then return a string referring to the method
64 &apos;&apos;&apos; containing the New statement creating the instance
65 &apos;&apos;&apos; &quot;libraryname.modulename.function&quot;
67 With GlobalScope.ScriptForge.SF_Services
68 .RegisterService(&quot;Document&quot;, &quot;SFDocuments.SF_Register._NewDocument&quot;) &apos; Reference to the function initializing the service
69 .RegisterService(&quot;Base&quot;, &quot;SFDocuments.SF_Register._NewDocument&quot;) &apos; Same reference, distinction is made inside the function
70 .RegisterService(&quot;Calc&quot;, &quot;SFDocuments.SF_Register._NewDocument&quot;) &apos; Same reference, distinction is made inside the function
71 .RegisterService(&quot;Writer&quot;, &quot;SFDocuments.SF_Register._NewDocument&quot;) &apos; Same reference, distinction is made inside the function
72 .RegisterEventManager(&quot;DocumentEvent&quot;, &quot;SFDocuments.SF_Register._EventManager&quot;) &apos; Reference to the events manager
73 .RegisterEventManager(&quot;FormEvent&quot;, &quot;SFDocuments.SF_Register._FormEventManager&quot;)&apos; Reference to the form and controls events manager
74 End With
76 End Sub &apos; SFDocuments.SF_Register.RegisterScriptServices
78 REM =========================================================== PRIVATE FUNCTIONS
80 REM -----------------------------------------------------------------------------
81 Private Function _AddFormToCache(ByRef pvUnoForm As Object _
82 , ByRef pvBasicForm As Object _
83 ) As Long
84 &apos;&apos;&apos; Add a new entry in the cache array with the references of the actual Form
85 &apos;&apos;&apos; If relevant, the last entry of the cache is reused.
86 &apos;&apos;&apos; The cache is located in the global _SF_ variable
87 &apos;&apos;&apos; Args:
88 &apos;&apos;&apos; pvUnoForm: com.sun.star.form.XForm or com.sun.star.comp.forms.ODatabaseForm
89 &apos;&apos;&apos; pvBasicForm: its corresponding Basic object
90 &apos;&apos;&apos; Returns:
91 &apos;&apos;&apos; The index of the new or modified entry
93 Dim vCache As New _FormCache &apos; Entry to be added
94 Dim lIndex As Long &apos; UBound of _SF_.SFForms
95 Dim vCacheArray As Variant &apos; Alias of _SF_.SFForms
97 Try:
98 vCacheArray = _SF_.SFForms
100 If IsEmpty(vCacheArray) Then vCacheArray = Array()
101 lIndex = UBound(vCacheArray)
102 If lIndex &lt; LBound(vCacheArray) Then
103 ReDim vCacheArray(0 To 0)
104 lIndex = 0
105 ElseIf Not vCacheArray(lIndex).Terminated Then &apos; Often last entry can be reused
106 lIndex = lIndex + 1
107 ReDim Preserve vCacheArray(0 To lIndex)
108 End If
110 With vCache
111 .Terminated = False
112 Set .XUnoForm = pvUnoForm
113 Set .BasicForm = pvBasicForm
114 End With
115 Set vCacheArray(lIndex) = vCache
117 _SF_.SFForms = vCacheArray
119 Finally:
120 _AddFormToCache = lIndex
121 Exit Function
122 End Function &apos; SFDocuments.SF_Register._AddFormToCache
124 REM -----------------------------------------------------------------------------
125 Private Sub _CleanCacheEntry(ByVal plIndex As Long)
126 &apos;&apos;&apos; Clean the plIndex-th entry in the Forms cache
127 &apos;&apos;&apos; Args:
128 &apos;&apos;&apos; plIndex: must fit within the actual boundaries of the cache, otherwise the request is ignored
130 Dim vCache As New _FormCache &apos; Cleaned entry
132 With _SF_
133 If Not IsArray(.SFForms) Then Exit Sub
134 If plIndex &lt; LBound(.SFForms) Or plIndex &gt; UBound(.SFForms) Then Exit Sub
136 With vCache
137 .Terminated = True
138 Set .XUnoForm = Nothing
139 Set .BasicForm = Nothing
140 End With
141 .SFForms(plIndex) = vCache
142 End With
144 Finally:
145 Exit Sub
146 End Sub &apos; SFDocuments.SF_Register._CleanCacheEntry
148 REM -----------------------------------------------------------------------------
149 Public Function _EventManager(Optional ByRef pvArgs As Variant) As Object
150 &apos;&apos;&apos; Returns a Document, Calc or Base object corresponding with the active component
151 &apos;&apos;&apos; which triggered the event in argument
152 &apos;&apos;&apos; This method should be triggered only thru the invocation of CreateScriptService
153 &apos;&apos;&apos; Args:
154 &apos;&apos;&apos; pvEvent: com.sun.star.document.DocumentEvent
155 &apos;&apos;&apos; Returns:
156 &apos;&apos;&apos; the output of a Document, Calc, ... service or Nothing
157 &apos;&apos;&apos; Example:
158 &apos;&apos;&apos; Sub TriggeredByEvent(ByRef poEvent As Object)
159 &apos;&apos;&apos; Dim oDoc As Object
160 &apos;&apos;&apos; Set oDoc = CreateScriptService(&quot;SFDocuments.DocumentEvent&quot;, poEvent)
161 &apos;&apos;&apos; If Not IsNull(oDoc) Then
162 &apos;&apos;&apos; &apos; ... (a valid document has been identified)
163 &apos;&apos;&apos; End Sub
165 Dim oSource As Object &apos; Return value
166 Dim vEvent As Variant &apos; Alias of pvArgs(0)
168 &apos; Never abort while an event is processed
169 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Finally
170 Set oSource = Nothing
172 Check:
173 If IsMissing(pvArgs) Or IsEmpty(pvArgs) Then pvArgs = Array()
174 If UBound(pvArgs) &gt;= 0 Then vEvent = pvArgs(0) Else Set vEvent = Empty
175 If VarType(vEvent) &lt;&gt; ScriptForge.V_OBJECT Then GoTo Finally
177 Try:
178 If ScriptForge.SF_Session.UnoObjectType(vEvent) = &quot;com.sun.star.document.DocumentEvent&quot; Then
179 Set oSource = SF_Register._NewDocument(vEvent.Source)
180 End If
182 Finally:
183 Set _EventManager = oSource
184 Exit Function
185 End Function &apos; SFDocuments.SF_Register._EventManager
187 REM -----------------------------------------------------------------------------
188 Private Function _FindFormInCache(ByRef poForm As Object) As Object
189 &apos;&apos;&apos; Find the Form based on its XUnoForm
190 &apos;&apos;&apos; The Form must not be terminated
191 &apos;&apos;&apos; Returns:
192 &apos;&apos;&apos; The corresponding Basic Form part or Nothing
194 Dim oBasicForm As Object &apos; Return value
195 Dim oCache As _FormCache &apos; Entry in the cache
197 Set oBasicForm = Nothing
199 Try:
200 With _SF_
201 If Not IsEmpty(.SFForms) Then
202 For Each oCache In .SFForms
203 If EqualUnoObjects(poForm, oCache.XUnoForm) And Not oCache.Terminated Then
204 Set oBasicForm = oCache.BasicForm
205 Exit For
206 End If
207 Next oCache
208 End If
209 End With
211 Finally:
212 Set _FindFormInCache = oBasicForm
213 Exit Function
214 End Function &apos; SFDocuments.SF_Register._FindFormInCache
216 REM -----------------------------------------------------------------------------
217 Public Function _FormEventManager(Optional ByRef pvArgs As Variant) As Object
218 &apos;&apos;&apos; Returns a Form or FormControl object corresponding with the form or control
219 &apos;&apos;&apos; which triggered the event in argument
220 &apos;&apos;&apos; This method should be triggered only thru the invocation of CreateScriptService
221 &apos;&apos;&apos; Args:
222 &apos;&apos;&apos; pvEvent: com.sun.star.lang.EventObject
223 &apos;&apos;&apos; Returns:
224 &apos;&apos;&apos; the output of a Form, FormControl service or Nothing
225 &apos;&apos;&apos; Example:
226 &apos;&apos;&apos; Sub TriggeredByEvent(ByRef poEvent As Object)
227 &apos;&apos;&apos; Dim oForm As Object
228 &apos;&apos;&apos; Set oForm = CreateScriptService(&quot;SFDocuments.FormEvent&quot;, poEvent)
229 &apos;&apos;&apos; If Not IsNull(oForm) Then
230 &apos;&apos;&apos; &apos; ... (a valid form or subform has been identified)
231 &apos;&apos;&apos; End Sub
233 Dim oSource As Object &apos; Return value
234 Dim vEvent As Variant &apos; Alias of pvArgs(0)
235 Dim oControlModel As Object &apos; com.sun.star.awt.XControlModel
236 Dim oParent As Object &apos; com.sun.star.form.OGridControlModel or com.sun.star.comp.forms.ODatabaseForm
237 Dim sParentType As String &apos; &quot;com.sun.star.form.OGridControlModel&quot; or &quot;com.sun.star.comp.forms.ODatabaseForm&quot;
238 Dim oSFParent As Object &apos; The parent as a ScriptForge instance: SF_Form or SF_FormControl
239 Dim oSFForm As Object &apos; The grand-parent SF_Form instance
240 Dim oSession As Object : Set oSession = ScriptForge.SF_Session
242 &apos; Never abort while an event is processed
243 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Finally
244 Set oSource = Nothing
246 Check:
247 If IsMissing(pvArgs) Or IsEmpty(pvArgs) Then pvArgs = Array()
248 If UBound(pvArgs) &gt;= 0 Then vEvent = pvArgs(0) Else Set vEvent = Empty
249 If VarType(vEvent) &lt;&gt; ScriptForge.V_OBJECT Then GoTo Finally
251 Try:
252 If oSession.HasUnoProperty(vEvent, &quot;Source&quot;) Then
254 &apos; FORM EVENT
255 If oSession.UnoObjectType(vEvent.Source) = &quot;com.sun.star.comp.forms.ODatabaseForm&quot; Then
256 Set oSource = SF_Register._NewForm(vEvent.Source, pbForceInit := True)
258 &apos; CONTROL EVENT
259 Else
260 &apos; A SF_FormControl instance is always created from its parent, either a form, a subform or a table control
261 Set oControlModel = vEvent.Source.Model &apos; The event source is a control view com.sun.star.awt.XControl
262 Set oParent = oControlModel.Parent
263 sParentType = oSession.UnoObjectType(oParent)
264 Select Case sParentType
265 Case &quot;com.sun.star.form.OGridControlModel&quot;
266 Set oSFForm = SF_Register._NewForm(oParent.Parent, pbForceInit := True)
267 Set oSFParent = oSFForm.Controls(oParent.Name)
268 Case &quot;com.sun.star.comp.forms.ODatabaseForm&quot;
269 Set oSFParent = SF_Register._NewForm(oParent, pbForceInit := True)
270 End Select
271 &apos; The final instance is derived from its parent instance
272 Set oSource = oSFParent.Controls(oControlModel.Name)
274 End If
276 End If
278 Finally:
279 Set _FormEventManager = oSource
280 Exit Function
281 End Function &apos; SFDocuments.SF_Register._FormEventManager
283 REM -----------------------------------------------------------------------------
284 Public Function _GetEventScriptCode(poObject As Object _
285 , ByVal psEvent As String _
286 , ByVal psName As String _
287 ) As String
288 &apos;&apos;&apos; Extract from the parent of poObject the Basic script linked to psEvent.
289 &apos;&apos;&apos; Helper function common to forms and form controls
290 &apos;&apos;&apos; Args:
291 &apos;&apos;&apos; poObject: a com.sun.star.form.XForm or XControl object
292 &apos;&apos;&apos; psEvent: the &quot;On...&quot; name of the event
293 &apos;&apos;&apos; psName: the name of the object to be identified from the parent object
294 &apos;&apos;&apos; Returns:
295 &apos;&apos;&apos; The script to trigger when psEvent occurs
296 &apos;&apos;&apos; See Scripting Framework URI Specification : https://wiki.documentfoundation.org/Documentation/DevGuide/Scripting_Framework#Scripting_Framework_URI_Specification
298 Dim vEvents As Variant &apos; List of available events in the parent object
299 &apos; Array of com.sun.star.script.ScriptEventDescriptor
300 Dim sEvent As String &apos; The targeted event name
301 Dim oParent As Object &apos; The parent object
302 Dim lIndex As Long &apos; The index of the targeted event in the events list of the parent object
303 Dim sName As String &apos; The corrected UNO event name
304 Dim i As Long
306 _GetEventScriptCode = &quot;&quot;
307 On Local Error GoTo Catch
308 If Not ScriptForge.SF_Session.HasUnoMethod(poObject, &quot;getParent&quot;) Then GoTo Finally
310 Try:
311 &apos; Find form index i.e. find control via getByIndex()
312 &apos; The name is known (= psName) but getByIndex() is not in the same sequence as getElementNames()
313 Set oParent = poObject.getParent()
314 lIndex = -1
315 For i = 0 To oParent.getCount() - 1
316 sName = oParent.getByIndex(i).Name
317 If (sName = psName) Then
318 lIndex = i
319 Exit For
320 End If
321 Next i
322 If lIndex &lt; 0 Then GoTo Finally &apos; Not found, should not happen
324 &apos; Find script triggered by event
325 vEvents = oParent.getScriptEvents(lIndex) &apos; Returns an array
326 &apos; Fix historical typo error
327 sEvent = Replace(LCase(Mid(psEvent, 3, 1)) &amp; Mid(psEvent, 4), &quot;errorOccurred&quot;, &quot;errorOccured&quot;)
328 For i = 0 To UBound(vEvents)
329 If vEvents(i).EventMethod = sEvent Then
330 _GetEventScriptCode = vEvents(i).ScriptCode
331 Exit For
332 End If
333 Next i
335 Finally:
336 Exit Function
337 Catch:
338 GoTo Finally
339 End Function &apos; SFDocuments.SF_Register._GetEventScriptCode
341 REM -----------------------------------------------------------------------------
342 Public Function _NewDocument(Optional ByVal pvArgs As Variant) As Object
343 &apos;&apos;&apos; Create a new instance of the (super) SF_Document class or of one of its subclasses (SF_Calc, ...)
344 &apos; Args:
345 &apos;&apos;&apos; WindowName: see the definition of WindowName in the description of the UI service
346 &apos;&apos;&apos; If absent, the document is presumed to be in the active window
347 &apos;&apos;&apos; If WindowName is an object, it must be a component
348 &apos;&apos;&apos; (com.sun.star.lang.XComponent or com.sun.star.comp.dba.ODatabaseDocument)
349 &apos;&apos;&apos; Returns: the instance or Nothing
351 Dim oDocument As Object &apos; Return value
352 Dim oSuperDocument As Object &apos; Companion superclass document
353 Dim vWindowName As Variant &apos; Alias of pvArgs(0)
354 Dim oEnum As Object &apos; com.sun.star.container.XEnumeration
355 Dim oComp As Object &apos; com.sun.star.lang.XComponent
356 Dim vWindow As Window &apos; A single component
357 Dim oUi As Object &apos; &quot;UI&quot; service
358 Dim bFound As Boolean &apos; True if the document is found on the desktop
360 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
362 Check:
363 If IsMissing(pvArgs) Or IsEmpty(pvArgs) Then pvArgs = Array()
364 If Not IsArray(pvArgs) Then pvArgs = Array(pvArgs) &apos; Needed when _NewDocument called from _EventManager
365 If UBound(pvArgs) &gt;= 0 Then vWindowName = pvArgs(0) Else vWindowName = &quot;&quot;
366 If Not ScriptForge.SF_Utils._Validate(vWindowName, &quot;WindowName&quot;, Array(V_STRING, ScriptForge.V_OBJECT)) Then GoTo Finally
367 Set oDocument = Nothing
369 Try:
370 Set oUi = ScriptForge.SF_Services.CreateScriptService(&quot;UI&quot;)
371 Select Case VarType(vWindowName)
372 Case V_STRING
373 If Len(vWindowName) &gt; 0 Then
374 bFound = False
375 Set oEnum = StarDesktop.Components().createEnumeration
376 Do While oEnum.hasMoreElements
377 Set oComp = oEnum.nextElement
378 vWindow = oUi._IdentifyWindow(oComp)
379 With vWindow
380 &apos; Does the current window match the argument ?
381 If (Len(.WindowFileName) &gt; 0 And .WindowFileName = ScriptForge.SF_FileSystem._ConvertToUrl(vWindowName)) _
382 Or (Len(.WindowName) &gt; 0 And .WindowName = vWindowName) _
383 Or (Len(.WindowTitle) &gt; 0 And .WindowTitle = vWindowName) Then
384 bFound = True
385 Exit Do
386 End If
387 End With
388 Loop
389 Else
390 bFound = True
391 vWindow = oUi._IdentifyWindow(StarDesktop.CurrentComponent)
392 End If
393 Case ScriptForge.V_OBJECT &apos; com.sun.star.lang.XComponent
394 bFound = True
395 vWindow = oUi._IdentifyWindow(vWindowName)
396 End Select
398 If bFound And Not IsNull(vWindow.Frame) And Len(vWindow.DocumentType) &gt; 0 Then
399 &apos; Create the right subclass and associate to it a new instance of the superclass
400 Select Case vWindow.DocumentType
401 Case &quot;Base&quot;
402 Set oDocument = New SF_Base
403 Set oSuperDocument = New SF_Document
404 Set oDocument.[_Super] = oSuperDocument &apos; Now both super and subclass are twinned
405 Set oSuperDocument.[_SubClass] = oDocument
406 Case &quot;Calc&quot;
407 Set oDocument = New SF_Calc
408 Set oSuperDocument = New SF_Document
409 Set oDocument.[_Super] = oSuperDocument &apos; Now both super and subclass are twinned
410 Set oSuperDocument.[_SubClass] = oDocument
411 Case &quot;Writer&quot;
412 Set oDocument = New SF_Writer
413 Set oSuperDocument = New SF_Document
414 Set oDocument.[_Super] = oSuperDocument &apos; Now both super and subclass are twinned
415 Set oSuperDocument.[_SubClass] = oDocument
416 Case Else &apos; Only superclass
417 Set oDocument = New SF_Document
418 Set oSuperDocument = oDocument
419 End Select
420 With oDocument &apos; Initialize attributes of subclass
421 Set .[Me] = oDocument
422 Set ._Component = vWindow.Component
423 &apos; Initialize specific attributes
424 Select Case vWindow.DocumentType
425 Case &quot;Base&quot;
426 Set ._DataSource = ._Component.DataSource
427 Case Else
428 End Select
429 End With
430 With oSuperDocument &apos; Initialize attributes of superclass
431 Set .[Me] = oSuperDocument
432 Set ._Component = vWindow.Component
433 Set ._Frame = vWindow.Frame
434 ._WindowName = vWindow.WindowName
435 ._WindowTitle = vWindow.WindowTitle
436 ._WindowFileName = vWindow.WindowFileName
437 ._DocumentType = vWindow.DocumentType
438 End With
439 End If
441 Finally:
442 Set _NewDocument = oDocument
443 Exit Function
444 Catch:
445 GoTo Finally
446 End Function &apos; SFDocuments.SF_Register._NewDocument
448 REM -----------------------------------------------------------------------------
449 Public Function _NewForm(ByRef poForm As Object _
450 , Optional pbForceInit As Boolean _
451 ) As Object
452 &apos;&apos;&apos; Returns an existing or a new SF_Form instance based on the argument
453 &apos;&apos;&apos; If the instance is new (not found in cache), the minimal members are initialized
454 &apos;&apos;&apos; Args:
455 &apos;&apos;&apos; poForm: com.sun.star.form.XForm or com.sun.star.comp.forms.ODatabaseForm
456 &apos;&apos;&apos; pbForceInit: when True, initialize the form instance. Default = False
457 &apos;&apos;&apos; Returns:
458 &apos;&apos;&apos; A SF_Form instance
460 Dim oForm As Object &apos; Return value
462 Try:
463 Set oForm = SF_Register._FindFormInCache(poForm)
464 If IsNull(oForm) Then &apos; Not found
465 If IsMissing(pbForceInit) Or IsEmpty(pbForceInit) Then pbForceInit = False
466 Set oForm = New SF_Form
467 With oForm
468 ._Name = poForm.Name
469 Set .[Me] = oForm
470 Set ._Form = poForm
471 If pbForceInit Then ._Initialize()
472 End With
473 End If
475 Finally:
476 Set _NewForm = oForm
477 Exit Function
478 End Function &apos; SFDocuments.SF_Register._NewForm
480 REM -----------------------------------------------------------------------------
481 Public Function _RegisterEventScript(poObject As Object _
482 , ByVal psEvent As String _
483 , ByVal psListener As String _
484 , ByVal psScriptCode As String _
485 , ByVal psName As String _
486 ) As Boolean
487 &apos;&apos;&apos; Register a script event (psEvent) to poObject (Form, SubForm or Control)
488 &apos;&apos;&apos; Args:
489 &apos;&apos;&apos; poObject: a com.sun.star.form.XForm or XControl object
490 &apos;&apos;&apos; psEvent: the &quot;On...&quot; name of the event
491 &apos;&apos;&apos; psListener: the listener name corresponding with the event
492 &apos;&apos;&apos; psScriptCode: The script to trigger when psEvent occurs
493 &apos;&apos;&apos; See Scripting Framework URI Specification : https://wiki.documentfoundation.org/Documentation/DevGuide/Scripting_Framework#Scripting_Framework_URI_Specification
494 &apos;&apos;&apos; psName: the name of the object to associate with the event
495 &apos;&apos;&apos; Returns:
496 &apos;&apos;&apos; True when successful
498 Dim oEvent As Object &apos; com.sun.star.script.ScriptEventDescriptor
499 Dim sEvent As String &apos; The targeted event name
500 Dim oParent As Object &apos; The parent object
501 Dim lIndex As Long &apos; The index of the targeted event in the events list of the parent object
502 Dim sName As String &apos; The corrected UNO event name
503 Dim i As Long
505 _RegisterEventScript = False
506 On Local Error GoTo Catch
507 If Not ScriptForge.SF_Session.HasUnoMethod(poObject, &quot;getParent&quot;) Then GoTo Finally
509 Try:
510 &apos; Find object&apos;s internal index i.e. how to reach it via getByIndex()
511 Set oParent = poObject.getParent()
512 lIndex = -1
513 For i = 0 To oParent.getCount() - 1
514 sName = oParent.getByIndex(i).Name
515 If (sName = psName) Then
516 lIndex = i
517 Exit For
518 End If
519 Next i
520 If lIndex &lt; 0 Then GoTo Finally &apos; Not found, should not happen
522 &apos; Fix historical typo error
523 sEvent = Replace(LCase(Mid(psEvent, 3, 1)) &amp; Mid(psEvent, 4), &quot;errorOccurred&quot;, &quot;errorOccured&quot;)
524 &apos; Apply new script code. Erasing it is done with a specific UNO method
525 If psScriptCode = &quot;&quot; Then
526 oParent.revokeScriptEvent(lIndex, psListener, sEvent, &quot;&quot;)
527 Else
528 Set oEvent = CreateUnoStruct(&quot;com.sun.star.script.ScriptEventDescriptor&quot;)
529 With oEvent
530 .ListenerType = psListener
531 .EventMethod = sEvent
532 .ScriptType = &quot;Script&quot; &apos; Better than &quot;Basic&quot;
533 .ScriptCode = psScriptCode
534 End With
535 oParent.registerScriptEvent(lIndex, oEvent)
536 End If
537 _RegisterEventScript = True
539 Finally:
540 Exit Function
541 Catch:
542 GoTo Finally
543 End Function &apos; SFDocuments.SF_Register._RegisterEventScript
545 REM ============================================== END OF SFDOCUMENTS.SF_REGISTER
546 </script:module>