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
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)
' Needed when _NewDialog called from _EventManager
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
259 If Not ScriptForge.SF_Utils._Validate(vContainer,
"Container
", Array(V_STRING, ScriptForge.V_OBJECT)) Then GoTo Finally
260 If Not ScriptForge.SF_Utils._Validate(vLibrary,
"Library
", V_STRING) Then GoTo Finally
261 If Not ScriptForge.SF_Utils._Validate(vDialogName,
"DialogName
", V_STRING) Then GoTo Finally
262 If UBound(pvArgs)
>=
3 Then vContext = pvArgs(
3) Else vContext = Nothing
263 If Not ScriptForge.SF_Utils._Validate(vContext,
"DialogName
", V_OBJECT) Then GoTo Finally
264 Set oDialog = Nothing
267 ' Determine the library container hosting the dialog
268 Set oUi = ScriptForge.SF_Register.CreateScriptService(
"UI
")
270 If VarType(vContainer) = V_STRING Then
271 bFound = ( UCase(vContainer) = UCase(cstGlobal) )
274 Select Case VarType(vContainer)
276 If Len(vContainer)
> 0 Then
278 Set oEnum = StarDesktop.Components().createEnumeration
279 Do While oEnum.hasMoreElements
280 Set oComp = oEnum.nextElement
281 vWindow = oUi._IdentifyWindow(oComp)
283 ' Does the current window match the argument ?
284 If (Len(.WindowFileName)
> 0 And .WindowFileName = ScriptForge.SF_FileSystem._ConvertToUrl(vContainer)) _
285 Or (Len(.WindowName)
> 0 And .WindowName = vContainer) _
286 Or (Len(.WindowTitle)
> 0 And .WindowTitle = vContainer) Then
294 Set oComp = StarDesktop.CurrentComponent
295 vWindow = oUi._IdentifyWindow(oComp)
297 Case V_OBJECT
' com.sun.star.lang.XComponent
299 vWindow = oUi._IdentifyWindow(vContainer)
300 Set oComp = vContainer
302 If Not bFound Then GoTo CatchNotFound
303 If Len(vWindow.DocumentType) =
0 Then GoTo CatchNotFound
306 ' Determine the dialog provider
308 Case IsNull(vContext) And IsNull(oComp)
' Basic and GlobalScope
309 Set oDialogProvider = GetProcessServiceManager.createInstance(
"com.sun.star.awt.DialogProvider
")
310 Case IsNull(vContext) And Not IsNull(oComp)
' Basic and Document
311 Set oDialogProvider = GetProcessServiceManager.createInstanceWithArguments(
"com.sun.star.awt.DialogProvider
", Array(oComp))
312 Case Not IsNull(vContext) And IsNull(oComp)
' Python and GlobalScope
313 Set oDialogProvider = vContext.getServiceManager().createInstanceWithContext(
"com.sun.star.awt.DialogProvider
", vContext)
314 Case Not IsNull(vContext) And Not IsNull(oComp)
' Python and Document
315 Set oDialogProvider = vContext.getServiceManager().createInstanceWithArguments(
"com.sun.star.awt.DialogProvider
", Array(oComp))
318 ' Create the graphical interface
319 sScope = Iif(IsNull(oComp),
"application
",
"document
")
320 sURI =
"vnd.sun.star.script:
" & vLibrary
& ".
" & vDialogName
& "?location=
" & sScope
321 On Local Error GoTo CatchNotFound
322 Set oDialogControl = oDialogProvider.createDialog(sURI)
324 ' Initialize the basic SF_Dialog instance to return to the user script
325 Set oDialog = New SF_Dialog
328 If VarType(vContainer) = V_STRING Then ._Container = vContainer Else ._Container = vWindow.WindowName
331 Set ._DialogProvider = oDialogProvider
332 Set ._DialogControl = oDialogControl
337 Set _NewDialog = oDialog
342 ScriptForge.SF_Exception.RaiseFatal(DIALOGNOTFOUNDERROR,
"Service
", cstService _
343 ,
"Container
", vContainer,
"Library
", vLibrary,
"DialogName
", vDialogName)
345 End Function
' SFDialogs.SF_Register._NewDialog
347 REM ============================================== END OF SFDIALOGS.SF_REGISTER