tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / wizards / source / scriptforge / SF_Services.xba
blobffada4653d2cdab4e830399ce1a176bcbf2afa8d
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_Services" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
4 REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
5 REM === Full documentation is available on https://help.libreoffice.org/ ===
6 REM =======================================================================================================================
8 Option Compatible
9 Option Explicit
11 &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;
12 &apos;&apos;&apos; SF_Services
13 &apos;&apos;&apos; ===========
14 &apos;&apos;&apos; Singleton class implementing the &quot;ScriptForge.Services&quot; service
15 &apos;&apos;&apos; Implemented as a usual Basic module
16 &apos;&apos;&apos; The ScriptForge framework includes
17 &apos;&apos;&apos; the current ScriptForge library
18 &apos;&apos;&apos; a number of &quot;associated&quot; libraries
19 &apos;&apos;&apos; any user/contributor extension wanting to fit into the framework
20 &apos;&apos;&apos; The methods in this module constitute the kernel of the ScriptForge framework
21 &apos;&apos;&apos; - RegisterScriptServices
22 &apos;&apos;&apos; Register for a library the list of services it implements
23 &apos;&apos;&apos; Each library in the framework must implement its own RegisterScriptServices method
24 &apos;&apos;&apos; This method consists in a series of invocations of next 2 methods
25 &apos;&apos;&apos; - RegisterService
26 &apos;&apos;&apos; Register a single service
27 &apos;&apos;&apos; - RegisterEventManager
28 &apos;&apos;&apos; Register a single event manager
29 &apos;&apos;&apos; - CreateScriptService
30 &apos;&apos;&apos; Called by user scripts to get an object giving access to a service or to the event manager
31 &apos;&apos;&apos;
32 &apos;&apos;&apos; Detailed user documentation:
33 &apos;&apos;&apos; https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_services.html?DbPAR=BASIC
34 &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;
36 REM ================================================================== EXCEPTIONS
38 Const UNKNOWNSERVICEERROR = &quot;UNKNOWNSERVICEERROR&quot; &apos; Service not found within the registered services of the given library
39 Const SERVICESNOTLOADEDERROR = &quot;SERVICESNOTLOADEDERROR&quot; &apos; Failure during the registering of the services of the given library
40 Const UNKNOWNFILEERROR = &quot;UNKNOWNFILEERROR&quot; &apos; Source file does not exist
42 REM ============================================================== PUBLIC MEMBERS
44 &apos; Defines an entry in the services dictionary
45 Type _Service
46 ServiceName As String
47 ServiceType As Integer
48 &apos; 0 Undefined
49 &apos; 1 Basic module
50 &apos; 2 Method reference as a string
51 ServiceReference As Object
52 ServiceMethod As String
53 EventManager As Boolean &apos; True if registered item is an event manager
54 End Type
56 Private vServicesArray As Variant &apos; List of services registered by a library
58 REM ============================================================== PUBLIC METHODS
60 REM -----------------------------------------------------------------------------
61 Public Function CreateScriptService(Optional ByRef Service As Variant _
62 , ParamArray pvArgs As Variant _
63 ) As Variant
64 &apos;&apos;&apos; Create access to the services of a library for the benefit of a user script
65 &apos;&apos;&apos; A service is to understand either:
66 &apos;&apos;&apos; as a set of methods gathered in a Basic standard module
67 &apos;&apos;&apos; or a set of methods and properties gathered in a Basic class module
68 &apos;&apos;&apos; Args:
69 &apos;&apos;&apos; Service: the name of the service in 2 parts &quot;library.service&quot;
70 &apos;&apos;&apos; The library is a Basic library that must exist in the GlobalScope
71 &apos;&apos;&apos; (default = &quot;ScriptForge&quot;)
72 &apos;&apos;&apos; The service is one of the services registered by the library
73 &apos;&apos;&apos; thru the RegisterScriptServices() routine
74 &apos;&apos;&apos; pvArgs: a set of arguments passed to the constructor of the service
75 &apos;&apos;&apos; This is only possible if the service refers to a Basic class module
76 &apos;&apos;&apos; Returns
77 &apos;&apos;&apos; The object containing either the reference of the Basic module
78 &apos;&apos;&apos; or of the Basic class instance
79 &apos;&apos;&apos; Both are Basic objects
80 &apos;&apos;&apos; Returns Nothing if an error occurred.
81 &apos;&apos;&apos; ==&gt;&gt; NOTE: The error can be within the user script creating the new class instance
82 &apos;&apos;&apos; Exceptions:
83 &apos;&apos;&apos; SERVICESNOTLOADEDERROR RegisterScriptService probable failure
84 &apos;&apos;&apos; UNKNOWNSERVICEERROR Service not found
85 &apos;&apos;&apos; Examples
86 &apos;&apos;&apos; CreateScriptService(&quot;Array&quot;)
87 &apos;&apos;&apos; =&gt; Refers to ScriptForge.Array or SF_Array
88 &apos;&apos;&apos; CreateScriptService(&quot;ScriptForge.Dictionary&quot;)
89 &apos;&apos;&apos; =&gt; Returns a new empty dictionary; &quot;ScriptForge.&quot; is optional
90 &apos;&apos;&apos; CreateScriptService(&quot;SFDocuments.Calc&quot;)
91 &apos;&apos;&apos; =&gt; Refers to the Calc service, implemented in the SFDocuments library
92 &apos;&apos;&apos; CreateScriptService(&quot;Dialog&quot;, dlgName)
93 &apos;&apos;&apos; =&gt; Returns a Dialog instance referring to the dlgName dialog
94 &apos;&apos;&apos; CreateScriptService(&quot;SFDocuments.Event&quot;, oEvent)
95 &apos;&apos;&apos; =&gt; Refers to the Document service instance, implemented in the SFDocuments library, having triggered the event
97 Dim vScriptService As Variant &apos; Return value
98 Dim vServiceItem As Variant &apos; A single service (see _Service type definition)
99 Dim vServicesList As Variant &apos; Output of RegisterScriptServices
100 Dim vSplit As Variant &apos; Array to split argument in
101 Dim sLibrary As String &apos; Library part of the argument
102 Dim sService As String &apos; Service part of the argument
103 Dim vLibrary As Variant &apos; Dictionary of libraries
104 Dim vService As Variant &apos; An individual service object
105 Const cstThisSub = &quot;SF_Services.CreateScriptService&quot;
106 Const cstSubArgs = &quot;Service, arg0[, arg1] ...&quot;
108 &apos; Save Err, Erl, .. values before any On Error ... statement
109 SF_Exception._CaptureSystemError()
110 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
111 Set vScriptService = Nothing
113 Check:
114 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
115 If Not SF_Utils._Validate(Service, &quot;Service&quot;, V_STRING) Then GoTo Catch
116 If Len(Service) = 0 Then GoTo CatchNotFound
117 End If
119 Try:
120 &apos; Initialize the list of services when CreateScriptService called for the very 1st time
121 If IsEmpty(_SF_.ServicesList) Then _SF_.ServicesList = SF_Services._NewDictionary()
123 &apos; Simple parsing of argument
124 vSplit = Split(Service, &quot;.&quot;)
125 If UBound(vSplit) &gt; 1 Then GoTo CatchNotFound
126 If UBound(vSplit) = 0 Then
127 sLibrary = &quot;ScriptForge&quot; &apos; Yes, the default value !
128 sService = vSplit(0)
129 &apos; Accept other default values for associated libraries
130 Select Case LCase(sService)
131 Case &quot;document&quot;, &quot;calc&quot;, &quot;writer&quot;, &quot;base&quot;, &quot;formdocument&quot;, &quot;documentevent&quot;, &quot;formevent&quot;
132 sLibrary = &quot;SFDocuments&quot;
133 Case &quot;dialog&quot;, &quot;dialogevent&quot;, &quot;newdialog&quot;
134 sLibrary = &quot;SFDialogs&quot;
135 Case &quot;database&quot;, &quot;datasheet&quot; : sLibrary = &quot;SFDatabases&quot;
136 Case &quot;unittest&quot; : sLibrary = &quot;SFUnitTests&quot;
137 Case &quot;contextmenu&quot;, &quot;menu&quot;, &quot;popupmenu&quot;, &quot;toolbar&quot;, &quot;toolbarbutton&quot;
138 sLibrary = &quot;SFWidgets&quot;
139 Case Else
140 End Select
141 Else
142 sLibrary = vSplit(0)
143 sService = vSplit(1)
144 End If
146 With _SF_.ServicesList
148 &apos; Load the set of services from the library, if not yet done
149 If Not .Exists(sLibrary) Then
150 If Not SF_Services._LoadLibraryServices(sLibrary) Then GoTo CatchNotLoaded
151 End If
153 &apos; Find and return the requested service
154 vServicesList = .Item(sLibrary)
155 If Not vServicesList.Exists(sService) Then GoTo CatchNotFound
156 vServiceItem = vServicesList.Item(sService)
157 Select Case vServiceItem.ServiceType
158 Case 1 &apos; Basic module
159 vScriptService = vServiceItem.ServiceReference
160 Case 2 &apos; Method to call
161 If sLibrary = &quot;ScriptForge&quot; Then &apos; Direct call
162 Select Case UCase(sService)
163 Case &quot;DICTIONARY&quot; : vScriptService = SF_Services._NewDictionary()
164 Case &quot;L10N&quot; : vScriptService = SF_Services._NewL10N(pvArgs)
165 Case &quot;TIMER&quot; : vScriptService = SF_Services._NewTimer(pvArgs)
166 Case Else
167 End Select
168 Else &apos; Call via script provider
169 Set vService = SF_Session._GetScript(&quot;Basic&quot;, SF_Session.SCRIPTISAPPLICATION, vServiceItem.ServiceMethod)
170 vScriptService = vService.Invoke(Array(pvArgs()), Array(), Array())
171 End If
172 Case Else
173 End Select
175 End With
177 Finally:
178 CreateScriptService = vScriptService
179 SF_Utils._ExitFunction(cstThisSub)
180 Exit Function
181 Catch:
182 GoTo Finally
183 CatchNotFound:
184 SF_Exception.RaiseFatal(UNKNOWNSERVICEERROR, &quot;Service&quot;, Service, sLibrary, sService)
185 GoTo Finally
186 CatchNotLoaded:
187 SF_Exception.RaiseFatal(SERVICESNOTLOADEDERROR, &quot;Service&quot;, Service, sLibrary)
188 GoTo Finally
189 End Function &apos; ScriptForge.SF_Services.CreateScriptService
191 REM -----------------------------------------------------------------------------
192 Public Function RegisterEventManager(Optional ByVal ServiceName As Variant _
193 , Optional ByRef ServiceReference As Variant _
194 ) As Boolean
195 &apos;&apos;&apos; Register into ScriptForge a new event entry for the library
196 &apos;&apos;&apos; from which this method is called
197 &apos;&apos;&apos; MUST BE CALLED ONLY from a specific RegisterScriptServices() method
198 &apos;&apos;&apos; Usually the method should be called only once by library
199 &apos;&apos;&apos; Args:
200 &apos;&apos;&apos; ServiceName: the name of the service as a string. It the service exists
201 &apos;&apos;&apos; already for the library the method overwrites the existing entry
202 &apos;&apos;&apos; ServiceReference: the function which will identify the source of the triggered event
203 &apos;&apos;&apos; something like: &quot;libraryname.modulename.function&quot;
204 &apos;&apos;&apos; Returns:
205 &apos;&apos;&apos; True if successful
206 &apos;&apos;&apos; Example:
207 &apos;&apos;&apos; &apos; Code snippet stored in a module contained in the SFDocuments library
208 &apos;&apos;&apos; Sub RegisterScriptServices()
209 &apos;&apos;&apos; &apos; Register the events manager of the library
210 &apos;&apos;&apos; RegisterEventManager(&quot;DocumentEvent&quot;, &quot;SFDocuments.SF_Register._EventManager&quot;)
211 &apos;&apos;&apos; End Sub
212 &apos;&apos;&apos; &apos; Code snippet stored in a user script
213 &apos;&apos;&apos; Sub Trigger(poEvent As Object) &apos; Triggered by a DOCUMENTEVENT event
214 &apos;&apos;&apos; Dim myDoc As Object
215 &apos;&apos;&apos; &apos; To get the document concerned by the event:
216 &apos;&apos;&apos; Set myDoc = CreateScriptService(&quot;SFDocuments.DocumentEvent&quot;, poEvent)
217 &apos;&apos;&apos; End Sub
219 Dim bRegister As Boolean &apos; Return value
220 Const cstThisSub = &quot;SF_Services.RegisterEventManager&quot;
221 Const cstSubArgs = &quot;ServiceName, ServiceReference&quot;
223 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
224 bRegister = False
226 Check:
227 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
228 If Not SF_Utils._Validate(ServiceName, &quot;ServiceName&quot;, V_STRING) Then GoTo Finally
229 If Not SF_Utils._Validate(ServiceReference, &quot;ServiceReference&quot;,V_STRING) Then GoTo Finally
230 End If
232 Try:
233 bRegister = _AddToServicesArray(ServiceName, ServiceReference, True)
235 Finally:
236 RegisterEventManager = bRegister
237 SF_Utils._ExitFunction(cstThisSub)
238 Exit Function
239 Catch:
240 GoTo Finally
241 End Function &apos; ScriptForge.SF_Services.RegisterEventManager
243 REM -----------------------------------------------------------------------------
244 Public Function RegisterService(Optional ByVal ServiceName As Variant _
245 , Optional ByRef ServiceReference As Variant _
246 ) As Boolean
247 &apos;&apos;&apos; Register into ScriptForge a new service entry for the library
248 &apos;&apos;&apos; from which this method is called
249 &apos;&apos;&apos; MUST BE CALLED ONLY from a specific RegisterScriptServices() method
250 &apos;&apos;&apos; Args:
251 &apos;&apos;&apos; ServiceName: the name of the service as a string. It the service exists
252 &apos;&apos;&apos; already for the library the method overwrites the existing entry
253 &apos;&apos;&apos; ServiceReference: either
254 &apos;&apos;&apos; - the Basic module that implements the methods of the service
255 &apos;&apos;&apos; something like: GlobalScope.Library.Module
256 &apos;&apos;&apos; - an instance of the class implementing the methods and properties of the service
257 &apos;&apos;&apos; something like: &quot;libraryname.modulename.function&quot;
258 &apos;&apos;&apos; Returns:
259 &apos;&apos;&apos; True if successful
261 Dim bRegister As Boolean &apos; Return value
262 Const cstThisSub = &quot;SF_Services.RegisterService&quot;
263 Const cstSubArgs = &quot;ServiceName, ServiceReference&quot;
265 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
266 bRegister = False
268 Check:
269 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
270 If Not SF_Utils._Validate(ServiceName, &quot;ServiceName&quot;, V_STRING) Then GoTo Finally
271 If Not SF_Utils._Validate(ServiceReference, &quot;ServiceReference&quot;, Array(V_STRING, V_OBJECT)) Then GoTo Finally
272 End If
274 Try:
275 bRegister = _AddToServicesArray(ServiceName, ServiceReference, False)
277 Finally:
278 RegisterService = bRegister
279 SF_Utils._ExitFunction(cstThisSub)
280 Exit Function
281 Catch:
282 GoTo Finally
283 End Function &apos; ScriptForge.SF_Services.RegisterService
285 REM -----------------------------------------------------------------------------
286 Public Sub RegisterScriptServices() As Variant
287 &apos;&apos;&apos; Register into ScriptForge the list of the services implemented by the current library
288 &apos;&apos;&apos; Each library pertaining to the framework must implement its own version of this method
289 &apos;&apos;&apos; This method may be stored in any standard (i.e. not class-) module
290 &apos;&apos;&apos;
291 &apos;&apos;&apos; Each individual service is registered by calling the RegisterService() method
292 &apos;&apos;&apos;
293 &apos;&apos;&apos; The current version is given as an example
294 &apos;&apos;&apos;
295 With GlobalScope.ScriptForge.SF_Services
296 .RegisterService(&quot;Array&quot;, GlobalScope.ScriptForge.SF_Array) &apos; Reference to the Basic module
297 .RegisterService(&quot;Dictionary&quot;, &quot;ScriptForge.SF_Services._NewDictionary&quot;) &apos; Reference to the function initializing the service
298 .RegisterService(&quot;Exception&quot;, GlobalScope.ScriptForge.SF_Exception)
299 .RegisterService(&quot;FileSystem&quot;, GlobalScope.ScriptForge.SF_FileSystem)
300 .RegisterService(&quot;L10N&quot;, &quot;ScriptForge.SF_Services._NewL10N&quot;)
301 .RegisterService(&quot;Platform&quot;, GlobalScope.ScriptForge.SF_Platform)
302 .RegisterService(&quot;Region&quot;, GlobalScope.ScriptForge.SF_Region)
303 .RegisterService(&quot;Session&quot;, GlobalScope.ScriptForge.SF_Session)
304 .RegisterService(&quot;String&quot;, GlobalScope.ScriptForge.SF_String)
305 .RegisterService(&quot;Timer&quot;, &quot;ScriptForge.SF_Services._NewTimer&quot;)
306 .RegisterService(&quot;UI&quot;, GlobalScope.ScriptForge.SF_UI)
307 &apos;TODO
308 End With
310 End Sub &apos; ScriptForge.SF_Services.RegisterScriptServices
312 REM =========================================================== PRIVATE FUNCTIONS
314 REM -----------------------------------------------------------------------------
315 Private Function _AddToServicesArray(ByVal psServiceName As String _
316 , ByRef pvServiceReference As Variant _
317 , ByVal pbEvent As Boolean _
318 ) As Boolean
319 &apos;&apos;&apos; Add the arguments as an additional row in vServicesArray (Public variable)
320 &apos;&apos;&apos; Called from RegisterService and RegisterEvent methods
322 Dim bRegister As Boolean &apos; Return value
323 Dim lMax As Long &apos; Number of rows in vServicesArray
325 bRegister = False
327 Check:
328 &apos; Ignore when method is not called from RegisterScriptServices()
329 If IsEmpty(vServicesArray) Or IsNull(vServicesArray) Or Not IsArray(vServicesArray) Then GoTo Finally
331 Try:
332 lMax = UBound(vServicesArray, 1) + 1
333 If lMax &lt;= 0 Then
334 ReDim vServicesArray(0 To 0, 0 To 2)
335 Else
336 ReDim Preserve vServicesArray(0 To lMax, 0 To 2)
337 End If
338 vServicesArray(lMax, 0) = psServiceName
339 vServicesArray(lMax, 1) = pvServiceReference
340 vServicesArray(lMax, 2) = pbEvent
341 bRegister = True
343 Finally:
344 _AddToServicesArray = bRegister
345 Exit Function
346 End Function &apos; ScriptForge.SF_Services._AddToServicesArray
348 REM -----------------------------------------------------------------------------
349 Private Function _FindModuleFromMethod(ByVal psLibrary As String _
350 , ByVal psMethod As String _
351 ) As String
352 &apos;&apos;&apos; Find in the given library the name of the module containing
353 &apos;&apos;&apos; the method given as 2nd argument (usually RegisterScriptServices)
354 &apos;&apos;&apos; Args:
355 &apos;&apos;&apos; psLibrary: the name of the Basic library
356 &apos;&apos;&apos; psMethod: the method to locate
357 &apos;&apos;&apos; Returns:
358 &apos;&apos;&apos; The name of the module or a zero-length string if not found
360 Dim vCategories As Variant &apos; &quot;user&quot; or &quot;share&quot; library categories
361 Dim sCategory As String
362 Dim vLanguages As Variant &apos; &quot;Basic&quot;, &quot;Python&quot;, ... programming languages
363 Dim sLanguage As String
364 Dim vLibraries As Variant &apos; Library names
365 Dim sLibrary As String
366 Dim vModules As Variant &apos; Module names
367 Dim sModule As String &apos; Return value
368 Dim vMethods As Variant &apos; Method/properties/subs/functions
369 Dim sMethod As String
370 Dim oRoot As Object &apos; com.sun.star.script.browse.BrowseNodeFactory
371 Dim i As Integer, j As Integer, k As Integer, l As Integer, m As Integer
373 _FindModuleFromMethod = &quot;&quot;
374 Set oRoot = SF_Utils._GetUNOService(&quot;BrowseNodeFactory&quot;).createView(com.sun.star.script.browse.BrowseNodeFactoryViewTypes.MACROORGANIZER)
376 &apos; Exploration is done via tree nodes
377 If Not IsNull(oRoot) Then
378 If oRoot.hasChildNodes() Then
379 vCategories = oRoot.getChildNodes()
380 For i = 0 To UBound(vCategories)
381 sCategory = vCategories(i).getName()
382 &apos; Consider &quot;My macros &amp; Dialogs&quot; and &quot;LibreOffice Macros &amp; Dialogs&quot; only
383 If sCategory = &quot;user&quot; Or sCategory = &quot;share&quot; Then
384 If vCategories(i).hasChildNodes() Then
385 vLanguages = vCategories(i).getChildNodes()
386 For j = 0 To UBound(vLanguages)
387 sLanguage = vLanguages(j).getName()
388 &apos; Consider Basic libraries only
389 If sLanguage = &quot;Basic&quot; Then
390 If vLanguages(j).hasChildNodes() Then
391 vLibraries = vLanguages(j).getChildNodes()
392 For k = 0 To UBound(vLibraries)
393 sLibrary = vLibraries(k).getName()
394 &apos; Consider the given library only
395 If sLibrary = psLibrary Then
396 If vLibraries(k).hasChildNodes() Then
397 vModules = vLibraries(k).getChildNodes()
398 For l = 0 To UBound(vModules)
399 sModule = vModules(l).getName()
400 &apos; Check if the module contains the targeted method
401 If vModules(l).hasChildNodes() Then
402 vMethods = vModules(l).getChildNodes()
403 For m = 0 To UBound(vMethods)
404 sMethod = vMethods(m).getName()
405 If sMethod = psMethod Then
406 _FindModuleFromMethod = sModule
407 Exit Function
408 End If
409 Next m
410 End If
411 Next l
412 End If
413 End If
414 Next k
415 End If
416 End If
417 Next j
418 End If
419 End If
420 Next i
421 End If
422 End If
424 End Function &apos; ScriptForge.SF_Services._FindModuleFromMethod
426 REM -----------------------------------------------------------------------------
427 Private Function _LoadLibraryServices(ByVal psLibrary As String) As Boolean
428 &apos;&apos;&apos; Execute psLibrary.RegisterScriptServices() and load its services into the persistent storage
429 &apos;&apos;&apos; Args:
430 &apos;&apos;&apos; psLibrary: the name of the Basic library
431 &apos;&apos;&apos; Library will be loaded if not yet done
432 &apos;&apos;&apos; Returns:
433 &apos;&apos;&apos; True if success
434 &apos;&apos;&apos; The list of services is loaded directly into the persistent storage
437 Dim vServicesList As Variant &apos; Dictionary of services
438 Dim vService As Variant &apos; Single service entry in dictionary
439 Dim vServiceItem As Variant &apos; Single service in vServicesArray
440 Dim sModule As String &apos; Name of module containing the RegisterScriptServices method
441 Dim i As Long
442 Const cstRegister = &quot;RegisterScriptServices&quot;
444 Try:
445 _LoadLibraryServices = False
447 vServicesArray = Array()
449 If psLibrary = &quot;ScriptForge&quot; Then
450 &apos; Direct call
451 ScriptForge.SF_Services.RegisterScriptServices()
452 Else
453 &apos; Register services via script provider
454 If GlobalScope.BasicLibraries.hasByName(psLibrary) Then
455 If Not GlobalScope.BasicLibraries.isLibraryLoaded(psLibrary) Then
456 GlobalScope.BasicLibraries.LoadLibrary(psLibrary)
457 End If
458 Else
459 GoTo Finally
460 End If
461 sModule = SF_Services._FindModuleFromMethod(psLibrary, cstRegister)
462 If Len(sModule) = 0 Then GoTo Finally
463 SF_Session.ExecuteBasicScript(, psLibrary &amp; &quot;.&quot; &amp; sModule &amp; &quot;.&quot; &amp; cstRegister)
464 End If
466 &apos; Store in persistent storage
467 &apos; - Create list of services for the current library
468 Set vServicesList = SF_Services._NewDictionary()
469 For i = 0 To UBound(vServicesArray, 1)
470 Set vService = New _Service
471 With vService
472 .ServiceName = vServicesArray(i, 0)
473 vServiceItem = vServicesArray(i, 1)
474 If VarType(vServiceItem) = V_STRING Then
475 .ServiceType = 2
476 .ServiceMethod = vServiceItem
477 Set .ServiceReference = Nothing
478 Else &apos; OBJECT
479 .ServiceType = 1
480 .ServiceMethod = &quot;&quot;
481 Set .ServiceReference = vServiceItem
482 End If
483 .EventManager = vServicesArray(i, 2)
484 End With
485 vServicesList.Add(vServicesArray(i, 0), vService)
486 Next i
487 &apos; - Add the new dictionary to the persistent dictionary
488 _SF_.ServicesList.Add(psLibrary, vServicesList)
489 _LoadLibraryServices = True
490 vServicesArray = Empty
492 Finally:
493 Exit Function
494 End Function &apos; ScriptForge.SF_Services._LoadLibraryServices
496 REM -----------------------------------------------------------------------------
497 Public Function _NewDictionary(Optional ByVal pvArgs As Variant) As Variant
498 &apos;&apos;&apos; Create a new instance of the SF_Dictionary class
499 &apos;&apos;&apos; Args:
500 &apos;&apos;&apos; [0] : If True, the keys are compared case-sensitively. Default = False
501 &apos;&apos;&apos; Returns: the instance or Nothing
503 Dim oDict As Variant &apos; Return value
504 Dim bCaseSensitive As Boolean &apos; Keys comparison
506 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
508 Check:
509 If IsMissing(pvArgs) Then pvArgs = Array()
510 If Not IsArray(pvArgs) Then pvArgs = Array(pvArgs)
511 If UBound(pvArgs) &lt; 0 Then
512 bCaseSensitive = False
513 Else
514 If Not SF_Utils._Validate(pvArgs(0), &quot;CaseSensitive (Arg0)&quot;, V_BOOLEAN) Then GoTo Catch
515 bCaseSensitive = pvArgs(0)
516 End If
518 Try:
519 Set oDict = New SF_Dictionary
520 Set oDict.[Me] = oDict
521 oDict.CaseSensitive = bCaseSensitive
523 Finally:
524 Set _NewDictionary = oDict
525 Exit Function
526 Catch:
527 Set oDict = Nothing
528 GoTo Finally
529 End Function &apos; ScriptForge.SF_Services._NewDictionary
531 REM -----------------------------------------------------------------------------
532 Public Function _NewL10N(Optional ByVal pvArgs As Variant) As Variant
533 &apos;&apos;&apos; Create a new instance of the SF_L10N class
534 &apos; Args:
535 &apos;&apos;&apos; FolderName: the folder containing the PO files in SF_FileSystem.FileNaming notation
536 &apos;&apos;&apos; Locale: locale of user session (default) or any other valid la{nguage]-CO[UNTRY] combination
537 &apos;&apos;&apos; The country part is optional. Valid are f.i. &quot;fr&quot;, &quot;fr-CH&quot;, &quot;en-US&quot;
538 &apos;&apos;&apos; Encoding: The character set that should be used
539 &apos;&apos;&apos; Use one of the Names listed in https://www.iana.org/assignments/character-sets/character-sets.xhtml
540 &apos;&apos;&apos; Note that LibreOffice probably does not implement all existing sets
541 &apos;&apos;&apos; Default = UTF-8
542 &apos;&apos;&apos; Locale2: fallback Locale to select if Locale po file does not exist (typically &quot;en-US&quot;)
543 &apos;&apos;&apos; Encoding2: Encoding of the 2nd Locale file
544 &apos;&apos;&apos; Returns: the instance or Nothing
545 &apos;&apos;&apos; Exceptions:
546 &apos;&apos;&apos; UNKNOWNFILEERROR The PO file does not exist
548 Dim oL10N As Variant &apos; Return value
549 Dim sFolderName As String &apos; Folder containing the PO files
550 Dim sLocale As String &apos; Passed argument or that of the user session
551 Dim sLocale2 As String &apos; Alias for Locale2
552 Dim oLocale As Variant &apos; com.sun.star.lang.Locale
553 Dim sPOFile As String &apos; PO file must exist
554 Dim sEncoding As String &apos; Alias for Encoding
555 Dim sEncoding2 As String &apos; Alias for Encoding2
557 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
559 Check:
560 If IsMissing(pvArgs) Then pvArgs = Array()
561 sPOFile = &quot;&quot;
562 sEncoding = &quot;&quot;
563 If UBound(pvArgs) &gt;= 0 Then
564 If Not SF_Utils._ValidateFile(pvArgs(0), &quot;Folder (Arg0)&quot;, , True) Then GoTo Catch
565 sFolderName = pvArgs(0)
566 sLocale = &quot;&quot;
567 If UBound(pvArgs) &gt;= 1 Then
568 If Not SF_Utils._Validate(pvArgs(1), &quot;Locale (Arg1)&quot;, V_STRING) Then GoTo Catch
569 sLocale = pvArgs(1)
570 End If
571 If Len(sLocale) = 0 Then &apos; Called from Python, the Locale argument may be the zero-length string
572 Set oLocale = SF_Utils._GetUNOService(&quot;OfficeLocale&quot;)
573 sLocale = oLocale.Language &amp; &quot;-&quot; &amp; oLocale.Country
574 End If
575 If UBound(pvArgs) &gt;= 2 Then
576 If IsMissing(pvArgs(2)) Or IsEmpty(pvArgs(2)) Then pvArgs(2) = &quot;UTF-8&quot;
577 If Not SF_Utils._Validate(pvArgs(2), &quot;Encoding (Arg2)&quot;, V_STRING) Then GoTo Catch
578 sEncoding = pvArgs(2)
579 Else
580 sEncoding = &quot;UTF-8&quot;
581 End If
582 sLocale2 = &quot;&quot;
583 If UBound(pvArgs) &gt;= 3 Then
584 If Not SF_Utils._Validate(pvArgs(3), &quot;Locale2 (Arg3)&quot;, V_STRING) Then GoTo Catch
585 sLocale2 = pvArgs(3)
586 End If
587 If UBound(pvArgs) &gt;= 4 Then
588 If Not SF_Utils._Validate(pvArgs(4), &quot;Encoding2 (Arg4)&quot;, V_STRING) Then GoTo Catch
589 sEncoding2 = pvArgs(4)
590 Else
591 sEncoding2 = &quot;UTF-8&quot;
592 End If
593 If Len(sFolderName) &gt; 0 Then
594 sPOFile = SF_FileSystem.BuildPath(sFolderName, sLocale &amp; &quot;.po&quot;)
595 If Not SF_FileSystem.FileExists(sPOFile) Then
596 If Len(sLocale2) = 0 Then GoTo CatchNotExists &apos; No fallback =&gt; error
597 &apos; Try the fallback
598 sPOFile = SF_FileSystem.BuildPath(sFolderName, sLocale2 &amp; &quot;.po&quot;)
599 If Not SF_FileSystem.FileExists(sPOFile) Then GoTo CatchNotExists
600 sEncoding = sEncoding2
601 End If
602 End If
603 End If
605 Try:
606 Set oL10N = New SF_L10N
607 Set oL10N.[Me] = oL10N
608 oL10N._Initialize(sPOFile, sEncoding)
610 Finally:
611 Set _NewL10N = oL10N
612 Exit Function
613 Catch:
614 Set oL10N = Nothing
615 GoTo Finally
616 CatchNotExists:
617 SF_Exception.RaiseFatal(UNKNOWNFILEERROR, &quot;FileName&quot;, sPOFile)
618 GoTo Finally
619 End Function &apos; ScriptForge.SF_Services._NewL10N
621 REM -----------------------------------------------------------------------------
622 Public Function _NewTimer(Optional ByVal pvArgs As Variant) As Variant
623 &apos;&apos;&apos; Create a new instance of the SF_Timer class
624 &apos;&apos;&apos; Args:
625 &apos;&apos;&apos; [0] : If True, start the timer immediately
626 &apos;&apos;&apos; Returns: the instance or Nothing
628 Dim oTimer As Variant &apos; Return value
629 Dim bStart As Boolean &apos; Automatic start ?
631 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
633 Check:
634 If IsMissing(pvArgs) Then pvArgs = Array()
635 If UBound(pvArgs) &lt; 0 Then
636 bStart = False
637 Else
638 If Not SF_Utils._Validate(pvArgs(0), &quot;Start (Arg0)&quot;, V_BOOLEAN) Then GoTo Catch
639 bStart = pvArgs(0)
640 End If
641 Try:
642 Set oTimer = New SF_Timer
643 Set oTimer.[Me] = oTimer
644 If bStart Then oTimer.Start()
646 Finally:
647 Set _NewTimer = oTimer
648 Exit Function
649 Catch:
650 Set oTimer = Nothing
651 GoTo Finally
652 End Function &apos; ScriptForge.SF_Services._NewTimer
654 REM ============================================== END OF SCRIPTFORGE.SF_SERVICES
655 </script:module>