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 SFDialogs library is one of the associated libraries. ===
6 REM === Full documentation is available on https://help.libreoffice.org/ ===
7 REM =======================================================================================================================
12 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
13 ''' SF_Register
14 ''' ===========
15 ''' The ScriptForge framework includes
16 ''' the master ScriptForge library
17 ''' a number of
"associated
" libraries SF*
18 ''' any user/contributor extension wanting to fit into the framework
20 ''' The main methods in this module allow the current library to cling to ScriptForge
21 ''' - RegisterScriptServices
22 ''' Register the list of services implemented by the current library
23 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
25 REM ================================================================= DEFINITIONS
27 ''' Event management of dialogs requires to being able to rebuild a Dialog object
28 ''' from its com.sun.star.awt.XControl - stardiv.Toolkit.UnoDialogControl UNO instance
29 ''' For that purpose, the started dialogs are buffered in a global array of _DialogCache types
37 REM ================================================================== EXCEPTIONS
39 Private Const DIALOGNOTFOUNDERROR =
"DIALOGNOTFOUNDERROR
"
41 REM ============================================================== PUBLIC METHODS
43 REM -----------------------------------------------------------------------------
44 Public Sub RegisterScriptServices() As Variant
45 ''' Register into ScriptForge the list of the services implemented by the current library
46 ''' Each library pertaining to the framework must implement its own version of this method
48 ''' It consists in successive calls to the RegisterService() and RegisterEventManager() methods
49 ''' with
2 arguments:
50 ''' ServiceName: the name of the service as a case-insensitive string
51 ''' ServiceReference: the reference as an object
52 ''' If the reference refers to a module, then return the module as an object:
53 ''' GlobalScope.Library.Module
54 ''' If the reference is a class instance, then return a string referring to the method
55 ''' containing the New statement creating the instance
56 ''' "libraryname.modulename.function
"
58 With GlobalScope.ScriptForge.SF_Services
59 .RegisterService(
"Dialog
",
"SFDialogs.SF_Register._NewDialog
")
' Reference to the function initializing the service
60 .RegisterEventManager(
"DialogEvent
",
"SFDialogs.SF_Register._EventManager
")
' Reference to the events manager
61 .RegisterEventManager(
"NewDialog
",
"SFDialogs.SF_Register._NewDialogFromScratch
")
' Reference to the function initializing the service
64 End Sub
' SFDialogs.SF_Register.RegisterScriptServices
66 REM =========================================================== PRIVATE FUNCTIONS
68 REM -----------------------------------------------------------------------------
69 Private Function _AddDialogToCache(ByRef pvUnoDialog As Object _
70 , ByRef pvBasicDialog As Object _
72 ''' Add a new entry in the cache array with the references of the actual dialog
73 ''' If relevant, the last entry of the cache is reused.
74 ''' The cache is located in the global _SF_ variable
75 ''' Args:
76 ''' pvUnoDialog: the com.sun.star.awt.XControl - stardiv.Toolkit.UnoDialogControl of the dialog box
77 ''' pvBasicDialog: its corresponding Basic object
78 ''' Returns:
79 ''' The index of the new or modified entry
81 Dim vCache As New _DialogCache
' Entry to be added
82 Dim lIndex As Long
' UBound of _SF_.SFDialogs
83 Dim vCacheArray As Variant
' Alias of _SF_.SFDialogs
86 vCacheArray = _SF_.SFDialogs
88 If IsEmpty(vCacheArray) Then vCacheArray = Array()
89 lIndex = UBound(vCacheArray)
90 If lIndex
< LBound(vCacheArray) Then
91 ReDim vCacheArray(
0 To
0)
93 ElseIf Not vCacheArray(lIndex).Terminated Then
' Often last entry can be reused
95 ReDim Preserve vCacheArray(
0 To lIndex)
100 Set .XUnoDialog = pvUnoDialog
101 Set .BasicDialog = pvBasicDialog
103 vCacheArray(lIndex) = vCache
105 _SF_.SFDialogs = vCacheArray
108 _AddDialogToCache = lIndex
110 End Function
' SFDialogs.SF_Register._AddDialogToCache
112 REM -----------------------------------------------------------------------------
113 Private Sub _CleanCacheEntry(ByVal plIndex As Long)
114 ''' Clean the plIndex-th entry in the dialogs cache
115 ''' Args:
116 ''' plIndex: must fit within the actual boundaries of the cache, otherwise the request is ignored
118 Dim vCache As New _DialogCache
' Cleaned entry
121 If Not IsArray(.SFDialogs) Then Exit Sub
122 If plIndex
< LBound(.SFDialogs) Or plIndex
> UBound(.SFDialogs) Then Exit Sub
126 Set .XUnoDialog = Nothing
127 Set .BasicDialog = Nothing
129 .SFDialogs(plIndex) = vCache
134 End Sub
' SFDialogs.SF_Register._CleanCacheEntry
136 REM -----------------------------------------------------------------------------
137 Public Function _EventManager(Optional ByRef pvArgs As Variant) As Object
138 ''' Returns a Dialog or DialogControl object corresponding with the Basic dialog
139 ''' which triggered the event in argument
140 ''' This method should be triggered only thru the invocation of CreateScriptService
141 ''' Args:
142 ''' pvEvent: com.sun.star.xxx
143 ''' Returns:
144 ''' the output of a Dialog or DialogControl service or Nothing
145 ''' Example:
146 ''' Sub TriggeredByEvent(ByRef poEvent As Object)
147 ''' Dim oDlg As Object
148 ''' Set oDlg = CreateScriptService(
"SFDialogs.DialogEvent
", poEvent)
149 ''' If Not IsNull(oDlg) Then
150 ''' ' ... (a valid dialog or one of its controls has been identified)
151 ''' End Sub
153 Dim oSource As Object
' Return value
154 Dim oEventSource As Object
' Event UNO source
155 Dim vEvent As Variant
' Alias of pvArgs(
0)
156 Dim sSourceType As String
' Implementation name of event source
157 Dim oDialog As Object
' com.sun.star.awt.XControl - stardiv.Toolkit.UnoDialogControl
158 Dim bControl As Boolean
' True when control event
160 ' Never abort while an event is processed
161 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Finally
162 Set oSource = Nothing
165 If IsMissing(pvArgs) Or IsEmpty(pvArgs) Then pvArgs = Array()
166 If UBound(pvArgs)
>=
0 Then vEvent = pvArgs(
0) Else vEvent = Empty
167 If VarType(vEvent)
<> ScriptForge.V_OBJECT Then GoTo Finally
168 If Not ScriptForge.SF_Session.HasUnoProperty(vEvent,
"Source
") Then GoTo Finally
171 Set oEventSource = vEvent.Source
172 sSourceType = ScriptForge.SF_Session.UnoObjectType(oEventSource)
174 Set oDialog = Nothing
176 Case sSourceType =
"stardiv.Toolkit.UnoDialogControl
" ' A dialog
177 ' Search the dialog in the cache
178 Set oDialog = _FindDialogInCache(oEventSource)
180 Case Left(sSourceType,
16) =
"stardiv.Toolkit.
" ' A dialog control
181 Set oDialog = _FindDialogInCache(oEventSource.Context)
186 If Not IsNull(oDialog) Then
187 If bControl Then Set oSource = oDialog.Controls(oEventSource.Model.Name) Else Set oSource = oDialog
191 Set _EventManager = oSource
193 End Function
' SFDialogs.SF_Register._EventManager
195 REM -----------------------------------------------------------------------------
196 Private Function _FindDialogInCache(ByRef poDialog As Object) As Object
197 ''' Find the dialog based on its XUnoDialog
198 ''' The dialog must not be terminated
199 ''' Returns:
200 ''' The corresponding Basic dialog part or Nothing
202 Dim oBasicDialog As Object
' Return value
203 Dim oCache As _DialogCache
' Entry in the cache
205 Set oBasicDialog = Nothing
208 For Each oCache In _SF_.SFDialogs
209 If EqualUnoObjects(poDialog, oCache.XUnoDialog) And Not oCache.Terminated Then
210 Set oBasicDialog = oCache.BasicDialog
216 Set _FindDialogInCache = oBasicDialog
218 End Function
' SFDialogs.SF_Register._FindDialogInCache
220 REM -----------------------------------------------------------------------------
221 Public Function _NewDialog(Optional ByVal pvArgs As Variant) As Object
222 ''' Create a new instance of the SF_Dialog class
223 ''' Args:
224 ''' Container: either
"GlobalScope
" or a WindowName. Default = the active window
225 ''' see the definition of WindowName in the description of the UI service
226 ''' Library: the name of the library hosting the dialog. Default =
"Standard
"
227 ''' DialogName: The name of the dialog
228 ''' Library and dialog names are case-sensitive
229 ''' Context: When called from Python, the context must be provided : XSCRIPTCONTEXT
230 ''' Returns: the instance or Nothing
232 Dim oDialog As Object
' Return value
233 Dim vContainer As Variant
' Alias of pvArgs(
0)
234 Dim vLibrary As Variant
' Alias of pvArgs(
1)
235 Dim vDialogName As Variant
' Alias of pvArgs(
2)
236 Dim oLibraries As Object
' com.sun.star.comp.sfx2.DialogLibraryContainer
237 Dim vContext As Variant
' com.sun.star.uno.XComponentContext
238 Dim oDialogProvider As Object
' com.sun.star.io.XInputStreamProvider
239 Dim oEnum As Object
' com.sun.star.container.XEnumeration
240 Dim oComp As Object
' com.sun.star.lang.XComponent
241 Dim oDialogControl As Object
' com.sun.star.awt.XControl - stardiv.Toolkit.UnoDialogControl
242 Dim vWindow As Window
' A single component
243 Dim sScope As String
' "application
" or
"document
"
244 Dim sURI As String
' URI of the targeted dialog
245 Dim oUi As Object
' "UI
" service
246 Dim bFound As Boolean
' True if WindowName is found on the desktop
247 Const cstService =
"SFDialogs.Dialog
"
248 Const cstGlobal =
"GlobalScope
"
250 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
253 If IsMissing(pvArgs) Or IsEmpty(pvArgs) Then pvArgs = Array()
254 If Not IsArray(pvArgs) Then pvArgs = Array(pvArgs)
255 If UBound(pvArgs)
>=
0 Then vContainer = pvArgs(
0) Else vContainer =
""
256 If UBound(pvArgs)
>=
1 Then vLibrary = pvArgs(
1)
257 If IsEmpty(vLibrary) Then vLibrary =
"Standard
"
258 If UBound(pvArgs)
>=
2 Then vDialogName = pvArgs(
2) Else vDialogName = Empty
' Use Empty to force mandatory status
260 If Not ScriptForge.SF_Utils._Validate(vContainer,
"Container
", Array(V_STRING, ScriptForge.V_OBJECT)) Then GoTo Finally
261 If Not ScriptForge.SF_Utils._Validate(vLibrary,
"Library
", V_STRING) Then GoTo Finally
262 If Not ScriptForge.SF_Utils._Validate(vDialogName,
"DialogName
", V_STRING) Then GoTo Finally
263 If UBound(pvArgs)
>=
3 Then vContext = pvArgs(
3) Else Set vContext = Nothing
264 If Not ScriptForge.SF_Utils._Validate(vContext,
"Context
", ScriptForge.V_OBJECT) Then GoTo Finally
266 Set oDialog = Nothing
269 ' Determine the library container hosting the dialog
270 Set oUi = ScriptForge.SF_Register.CreateScriptService(
"UI
")
272 If VarType(vContainer) = V_STRING Then
273 bFound = ( UCase(vContainer) = UCase(cstGlobal) )
276 Select Case VarType(vContainer)
278 If Len(vContainer)
> 0 Then
280 Set oEnum = StarDesktop.Components().createEnumeration
281 Do While oEnum.hasMoreElements
282 Set oComp = oEnum.nextElement
283 vWindow = oUi._IdentifyWindow(oComp)
285 ' Does the current window match the argument ?
286 If (Len(.WindowFileName)
> 0 And .WindowFileName = ScriptForge.SF_FileSystem._ConvertToUrl(vContainer)) _
287 Or (Len(.WindowName)
> 0 And .WindowName = vContainer) _
288 Or (Len(.WindowTitle)
> 0 And .WindowTitle = vContainer) Then
296 Set oComp = StarDesktop.CurrentComponent
297 vWindow = oUi._IdentifyWindow(oComp)
299 Case V_OBJECT
' com.sun.star.lang.XComponent
301 vWindow = oUi._IdentifyWindow(vContainer)
302 Set oComp = vContainer
304 If Not bFound Then GoTo CatchNotFound
305 If Len(vWindow.DocumentType) =
0 Then GoTo CatchNotFound
308 ' Determine the dialog provider
310 Case IsNull(vContext) And IsNull(oComp)
' Basic and GlobalScope
311 Set oDialogProvider = GetProcessServiceManager.createInstance(
"com.sun.star.awt.DialogProvider
")
312 Case IsNull(vContext) And Not IsNull(oComp)
' Basic and Document
313 Set oDialogProvider = GetProcessServiceManager.createInstanceWithArguments(
"com.sun.star.awt.DialogProvider
", Array(oComp))
314 Case Not IsNull(vContext) And IsNull(oComp)
' Python and GlobalScope
315 Set oDialogProvider = vContext.getServiceManager().createInstanceWithContext(
"com.sun.star.awt.DialogProvider
", vContext)
316 Case Not IsNull(vContext) And Not IsNull(oComp)
' Python and Document
317 Set oDialogProvider = vContext.getServiceManager().createInstanceWithArguments(
"com.sun.star.awt.DialogProvider
", Array(oComp))
320 ' Create the graphical interface
321 sScope = Iif(IsNull(oComp),
"application
",
"document
")
322 sURI =
"vnd.sun.star.script:
" & vLibrary
& ".
" & vDialogName
& "?location=
" & sScope
323 On Local Error GoTo CatchNotFound
324 Set oDialogControl = oDialogProvider.createDialog(sURI)
326 ' Initialize the basic SF_Dialog instance to return to the user script
327 Set oDialog = New SF_Dialog
330 If VarType(vContainer) = V_STRING Then ._Container = vContainer Else ._Container = vWindow.WindowName
333 Set ._DialogProvider = oDialogProvider
334 Set ._DialogControl = oDialogControl
339 Set _NewDialog = oDialog
344 ScriptForge.SF_Exception.RaiseFatal(DIALOGNOTFOUNDERROR,
"Service
", cstService _
345 ,
"Container
", vContainer,
"Library
", vLibrary,
"DialogName
", vDialogName)
347 End Function
' SFDialogs.SF_Register._NewDialog
349 REM -----------------------------------------------------------------------------
350 Private Function _NewDialogFromScratch(Optional ByVal pvArgs As Variant) As Object
351 ''' Create a new instance of the SF_Dialog class describing a dynamically defined dialog box
352 ''' Args:
353 ''' DialogName: a symbolic name of the dialog to create, for information only. Not checked for unicity.
354 ''' Place: either
355 ''' - an array with
4 elements: (X, Y, Width, Height)
356 ''' - a com.sun.star.awt.Rectangle [X, Y, Width, Height]
357 ''' All elements are expressed in
"Map AppFont
" units.
358 ''' Context: When called from Python, the context must be provided : XSCRIPTCONTEXT
359 ''' Returns: the instance or Nothing
361 Dim oDialog As Object
' Return value
362 Dim vDialogName As Variant
' The name is for information only
363 Dim vPlace As variant
' com.sun.star.awt.rectangle or array(X, Y, Width, Height)
364 Dim oPlace As Object
' com.sun.star.awt.rectangle
365 Dim oProcessManager As Object
' com.sun.star.lang.XMultiServiceFactory
366 Dim bBuiltInPython As Boolean
' True when context is present
367 Dim oModel As Object
' com.sun.star.awt.UnoControlDialogModel
368 Dim oView As Object
' com.sun.star.awt.UnoControlDialog
369 Dim vContext As Variant
' com.sun.star.uno.XComponentContext
371 Const cstDialogModel =
"com.sun.star.awt.UnoControlDialogModel
"
372 Const cstDialogView =
"com.sun.star.awt.UnoControlDialog
"
374 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
377 If IsMissing(pvArgs) Or IsEmpty(pvArgs) Then pvArgs = Array()
378 If Not IsArray(pvArgs) Then pvArgs = Array(pvArgs)
379 If UBound(pvArgs)
>=
0 Then vDialogName = pvArgs(
0) Else vDialogName = Empty
380 If UBound(pvArgs)
>=
1 Then vPlace = pvArgs(
1) Else vPlace = Empty
' Use Empty to force the mandatory status
381 If IsMissing(vDialogName) Or IsEmpty(vDialogName) Then vDialogName =
"DYNDIALOG
"
382 If UBound(pvArgs)
>=
2 Then vContext = pvArgs(
2) Else Set vContext = Nothing
384 If Not ScriptForge.SF_Utils._Validate(vDialogName,
"DialogName
", V_STRING) Then GoTo Finally
385 If IsArray(vPlace) Then
386 If Not ScriptForge.SF_Utils._ValidateArray(vPlace,
"Place
",
1, ScriptForge.V_NUMERIC, True) Then GoTo Finally
388 If Not ScriptForge.SF_Utils._Validate(vPlace,
"Place
", ScriptForge.V_OBJECT) Then GoTo Finally
390 If Not ScriptForge.SF_Utils._Validate(vContext,
"Context
", ScriptForge.V_OBJECT) Then GoTo Finally
392 Set oDialog = Nothing
395 ' Determine the process service manager and create the dialog model
396 If IsNull(vContext) Then
' Basic
397 Set oprocessManager = GetProcessServiceManager()
398 Set oModel = oProcessManager.createInstance(cstDialogModel)
399 bBuiltInPython = False
401 Set oprocessManager = vContext.getServiceManager()
402 Set oModel = oProcessManager.createInstanceWithContext(cstDialogModel, vContext)
403 bBuiltInPython = True
406 oModel.Name = vDialogName
408 ' Set dimension and position
410 If IsArray(vPlace) Then
411 If UBound(vPlace) =
3 Then
412 .PositionX = vPlace(
0)
413 .PositionY = vPlace(
1)
417 ElseIf ScriptForge.SF_Session.UnoObjectType(vPlace) =
"com.sun.star.awt.Rectangle
" Then
419 .PositionX = oPlace.X
420 .PositionY = oPlace.Y
421 .Width = oPlace.Width
422 .Height = oPlace.Height
424 'Leave everything to zero
428 ' Create the view and associate model and view
429 Set oView = oProcessManager.createInstance(cstDialogView)
430 oView.setModel(oModel)
432 ' Initialize the basic SF_Dialog instance to return to the user script
433 Set oDialog = New SF_Dialog
436 ._Container =
""
437 ._Library =
""
438 ._BuiltFromScratch = True
439 ._BuiltInPython = bBuiltInPython
441 Set ._DialogProvider = Nothing
442 Set ._DialogControl = oView
447 Set _NewDialogFromScratch = oDialog
451 End Function
' SFDialogs.SF_Register._NewDialogFromScratch
453 REM ============================================== END OF SFDIALOGS.SF_REGISTER