summaryrefslogtreecommitdiffstats
path: root/wizards/source/sfdialogs/SF_Register.xba
diff options
context:
space:
mode:
Diffstat (limited to 'wizards/source/sfdialogs/SF_Register.xba')
-rw-r--r--wizards/source/sfdialogs/SF_Register.xba348
1 files changed, 348 insertions, 0 deletions
diff --git a/wizards/source/sfdialogs/SF_Register.xba b/wizards/source/sfdialogs/SF_Register.xba
new file mode 100644
index 000000000..e81dbb069
--- /dev/null
+++ b/wizards/source/sfdialogs/SF_Register.xba
@@ -0,0 +1,348 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
+<script:module xmlns:script="http://openoffice.org/2000/script" script:name="SF_Register" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
+REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
+REM === The SFDialogs library is one of the associated libraries. ===
+REM === Full documentation is available on https://help.libreoffice.org/ ===
+REM =======================================================================================================================
+
+Option Compatible
+Option Explicit
+
+&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;
+&apos;&apos;&apos; SF_Register
+&apos;&apos;&apos; ===========
+&apos;&apos;&apos; The ScriptForge framework includes
+&apos;&apos;&apos; the master ScriptForge library
+&apos;&apos;&apos; a number of &quot;associated&quot; libraries SF*
+&apos;&apos;&apos; any user/contributor extension wanting to fit into the framework
+&apos;&apos;&apos;
+&apos;&apos;&apos; The main methods in this module allow the current library to cling to ScriptForge
+&apos;&apos;&apos; - RegisterScriptServices
+&apos;&apos;&apos; Register the list of services implemented by the current library
+&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;
+
+REM ================================================================= DEFINITIONS
+
+&apos;&apos;&apos; Event management of dialogs requires to being able to rebuild a Dialog object
+&apos;&apos;&apos; from its com.sun.star.awt.XControl - stardiv.Toolkit.UnoDialogControl UNO instance
+&apos;&apos;&apos; For that purpose, the started dialogs are buffered in a global array of _DialogCache types
+
+Type _DialogCache
+ Terminated As Boolean
+ XUnoDialog As Object
+ BasicDialog As Object
+End Type
+
+REM ================================================================== EXCEPTIONS
+
+Private Const DIALOGNOTFOUNDERROR = &quot;DIALOGNOTFOUNDERROR&quot;
+
+REM ============================================================== PUBLIC METHODS
+
+REM -----------------------------------------------------------------------------
+Public Sub RegisterScriptServices() As Variant
+&apos;&apos;&apos; Register into ScriptForge the list of the services implemented by the current library
+&apos;&apos;&apos; Each library pertaining to the framework must implement its own version of this method
+&apos;&apos;&apos;
+&apos;&apos;&apos; It consists in successive calls to the RegisterService() and RegisterEventManager() methods
+&apos;&apos;&apos; with 2 arguments:
+&apos;&apos;&apos; ServiceName: the name of the service as a case-insensitive string
+&apos;&apos;&apos; ServiceReference: the reference as an object
+&apos;&apos;&apos; If the reference refers to a module, then return the module as an object:
+&apos;&apos;&apos; GlobalScope.Library.Module
+&apos;&apos;&apos; If the reference is a class instance, then return a string referring to the method
+&apos;&apos;&apos; containing the New statement creating the instance
+&apos;&apos;&apos; &quot;libraryname.modulename.function&quot;
+
+ With GlobalScope.ScriptForge.SF_Services
+ .RegisterService(&quot;Dialog&quot;, &quot;SFDialogs.SF_Register._NewDialog&quot;) &apos; Reference to the function initializing the service
+ .RegisterEventManager(&quot;DialogEvent&quot;, &quot;SFDialogs.SF_Register._EventManager&quot;) &apos; Reference to the events manager
+ &apos;TODO
+ End With
+
+End Sub &apos; SFDialogs.SF_Register.RegisterScriptServices
+
+REM =========================================================== PRIVATE FUNCTIONS
+
+REM -----------------------------------------------------------------------------
+Private Function _AddDialogToCache(ByRef pvUnoDialog As Object _
+ , ByRef pvBasicDialog As Object _
+ ) As Long
+&apos;&apos;&apos; Add a new entry in the cache array with the references of the actual dialog
+&apos;&apos;&apos; If relevant, the last entry of the cache is reused.
+&apos;&apos;&apos; The cache is located in the global _SF_ variable
+&apos;&apos;&apos; Args:
+&apos;&apos;&apos; pvUnoDialog: the com.sun.star.awt.XControl - stardiv.Toolkit.UnoDialogControl of the dialog box
+&apos;&apos;&apos; pvBasicDialog: its corresponding Basic object
+&apos;&apos;&apos; Returns:
+&apos;&apos;&apos; The index of the new or modified entry
+
+Dim vCache As New _DialogCache &apos; Entry to be added
+Dim lIndex As Long &apos; UBound of _SF_.SFDialogs
+Dim vCacheArray As Variant &apos; Alias of _SF_.SFDialogs
+
+Try:
+ vCacheArray = _SF_.SFDialogs
+
+ If IsEmpty(vCacheArray) Then vCacheArray = Array()
+ lIndex = UBound(vCacheArray)
+ If lIndex &lt; LBound(vCacheArray) Then
+ ReDim vCacheArray(0 To 0)
+ lIndex = 0
+ ElseIf Not vCacheArray(lIndex).Terminated Then &apos; Often last entry can be reused
+ lIndex = lIndex + 1
+ ReDim Preserve vCacheArray(0 To lIndex)
+ End If
+
+ With vCache
+ .Terminated = False
+ Set .XUnoDialog = pvUnoDialog
+ Set .BasicDialog = pvBasicDialog
+ End With
+ vCacheArray(lIndex) = vCache
+
+ _SF_.SFDialogs = vCacheArray
+
+Finally:
+ _AddDialogToCache = lIndex
+ Exit Function
+End Function &apos; SFDialogs.SF_Register._AddDialogToCache
+
+REM -----------------------------------------------------------------------------
+Private Sub _CleanCacheEntry(ByVal plIndex As Long)
+&apos;&apos;&apos; Clean the plIndex-th entry in the dialogs cache
+&apos;&apos;&apos; Args:
+&apos;&apos;&apos; plIndex: must fit within the actual boundaries of the cache, otherwise the request is ignored
+
+Dim vCache As New _DialogCache &apos; Cleaned entry
+
+ With _SF_
+ If Not IsArray(.SFDialogs) Then Exit Sub
+ If plIndex &lt; LBound(.SFDialogs) Or plIndex &gt; UBound(.SFDialogs) Then Exit Sub
+
+ With vCache
+ .Terminated = True
+ Set .XUnoDialog = Nothing
+ Set .BasicDialog = Nothing
+ End With
+ .SFDialogs(plIndex) = vCache
+ End With
+
+Finally:
+ Exit Sub
+End Sub &apos; SFDialogs.SF_Register._CleanCacheEntry
+
+REM -----------------------------------------------------------------------------
+Public Function _EventManager(Optional ByRef pvArgs As Variant) As Object
+&apos;&apos;&apos; Returns a Dialog or DialogControl object corresponding with the Basic dialog
+&apos;&apos;&apos; which triggered the event in argument
+&apos;&apos;&apos; This method should be triggered only thru the invocation of CreateScriptService
+&apos;&apos;&apos; Args:
+&apos;&apos;&apos; pvEvent: com.sun.star.xxx
+&apos;&apos;&apos; Returns:
+&apos;&apos;&apos; the output of a Dialog or DialogControl service or Nothing
+&apos;&apos;&apos; Example:
+&apos;&apos;&apos; Sub TriggeredByEvent(ByRef poEvent As Object)
+&apos;&apos;&apos; Dim oDlg As Object
+&apos;&apos;&apos; Set oDlg = CreateScriptService(&quot;SFDialogs.DialogEvent&quot;, poEvent)
+&apos;&apos;&apos; If Not IsNull(oDlg) Then
+&apos;&apos;&apos; &apos; ... (a valid dialog or one of its controls has been identified)
+&apos;&apos;&apos; End Sub
+
+Dim oSource As Object &apos; Return value
+Dim oEventSource As Object &apos; Event UNO source
+Dim vEvent As Variant &apos; Alias of pvArgs(0)
+Dim sSourceType As String &apos; Implementation name of event source
+Dim oDialog As Object &apos; com.sun.star.awt.XControl - stardiv.Toolkit.UnoDialogControl
+Dim bControl As Boolean &apos; True when control event
+
+ &apos; 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) &gt;= 0 Then vEvent = pvArgs(0) Else vEvent = Empty
+ If VarType(vEvent) &lt;&gt; ScriptForge.V_OBJECT Then GoTo Finally
+ If Not ScriptForge.SF_Session.HasUnoProperty(vEvent, &quot;Source&quot;) Then GoTo Finally
+
+Try:
+ Set oEventSource = vEvent.Source
+ sSourceType = ScriptForge.SF_Session.UnoObjectType(oEventSource)
+
+ Set oDialog = Nothing
+ Select Case True
+ Case sSourceType = &quot;stardiv.Toolkit.UnoDialogControl&quot; &apos; A dialog
+ &apos; Search the dialog in the cache
+ Set oDialog = _FindDialogInCache(oEventSource)
+ bControl = False
+ Case Left(sSourceType, 16) = &quot;stardiv.Toolkit.&quot; &apos; A dialog control
+ Set oDialog = _FindDialogInCache(oEventSource.Context)
+ bControl = True
+ Case Else
+ End Select
+
+ If Not IsNull(oDialog) Then
+ If bControl Then Set oSource = oDialog.Controls(oEventSource.Model.Name) Else Set oSource = oDialog
+ End If
+
+Finally:
+ Set _EventManager = oSource
+ Exit Function
+End Function &apos; SFDialogs.SF_Register._EventManager
+
+REM -----------------------------------------------------------------------------
+Private Function _FindDialogInCache(ByRef poDialog As Object) As Object
+&apos;&apos;&apos; Find the dialog based on its XUnoDialog
+&apos;&apos;&apos; The dialog must not be terminated
+&apos;&apos;&apos; Returns:
+&apos;&apos;&apos; The corresponding Basic dialog part or Nothing
+
+Dim oBasicDialog As Object &apos; Return value
+Dim oCache As _DialogCache &apos; Entry in the cache
+
+ Set oBasicDialog = Nothing
+
+Try:
+ For Each oCache In _SF_.SFDialogs
+ If EqualUnoObjects(poDialog, oCache.XUnoDialog) And Not oCache.Terminated Then
+ Set oBasicDialog = oCache.BasicDialog
+ Exit For
+ End If
+ Next oCache
+
+Finally:
+ Set _FindDialogInCache = oBasicDialog
+ Exit Function
+End Function &apos; SFDialogs.SF_Register._FindDialogInCache
+
+REM -----------------------------------------------------------------------------
+Public Function _NewDialog(Optional ByVal pvArgs As Variant) As Object
+&apos;&apos;&apos; Create a new instance of the SF_Dialog class
+&apos;&apos;&apos; Args:
+&apos;&apos;&apos; Container: either &quot;GlobalScope&quot; or a WindowName. Default = the active window
+&apos;&apos;&apos; see the definition of WindowName in the description of the UI service
+&apos;&apos;&apos; Library: the name of the library hosting the dialog. Default = &quot;Standard&quot;
+&apos;&apos;&apos; DialogName: The name of the dialog
+&apos;&apos;&apos; Library and dialog names are case-sensitive
+&apos;&apos;&apos; Context: When called from Python, the context must be provided : XSCRIPTCONTEXT
+&apos;&apos;&apos; Returns: the instance or Nothing
+
+Dim oDialog As Object &apos; Return value
+Dim vContainer As Variant &apos; Alias of pvArgs(0)
+Dim vLibrary As Variant &apos; Alias of pvArgs(1)
+Dim vDialogName As Variant &apos; Alias of pvArgs(2)
+Dim oLibraries As Object &apos; com.sun.star.comp.sfx2.DialogLibraryContainer
+Dim vContext As Variant &apos; com.sun.star.uno.XComponentContext
+Dim oDialogProvider As Object &apos; com.sun.star.io.XInputStreamProvider
+Dim oEnum As Object &apos; com.sun.star.container.XEnumeration
+Dim oComp As Object &apos; com.sun.star.lang.XComponent
+Dim oDialogControl As Object &apos; com.sun.star.awt.XControl - stardiv.Toolkit.UnoDialogControl
+Dim vWindow As Window &apos; A single component
+Dim sScope As String &apos; &quot;application&quot; or &quot;document&quot;
+Dim sURI As String &apos; URI of the targeted dialog
+Dim oUi As Object &apos; &quot;UI&quot; service
+Dim bFound As Boolean &apos; True if WindowName is found on the desktop
+Const cstService = &quot;SFDialogs.Dialog&quot;
+Const cstGlobal = &quot;GlobalScope&quot;
+
+ If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
+
+Check:
+ If IsMissing(pvArgs) Or IsEmpty(pvArgs) Then pvArgs = Array()
+ If Not IsArray(pvArgs) Then pvArgs = Array(pvArgs) &apos; Needed when _NewDialog called from _EventManager
+ If UBound(pvArgs) &gt;= 0 Then vContainer = pvArgs(0) Else vContainer = &quot;&quot;
+ If UBound(pvArgs) &gt;= 1 Then vLibrary = pvArgs(1)
+ If IsEmpty(vLibrary) Then vLibrary = &quot;Standard&quot;
+ If UBound(pvArgs) &gt;= 2 Then vDialogName = pvArgs(2) Else vDialogName = Empty &apos; Use Empty to force mandatory status
+ If Not ScriptForge.SF_Utils._Validate(vContainer, &quot;Container&quot;, Array(V_STRING, ScriptForge.V_OBJECT)) Then GoTo Finally
+ If Not ScriptForge.SF_Utils._Validate(vLibrary, &quot;Library&quot;, V_STRING) Then GoTo Finally
+ If Not ScriptForge.SF_Utils._Validate(vDialogName, &quot;DialogName&quot;, V_STRING) Then GoTo Finally
+ If UBound(pvArgs) &gt;= 3 Then vContext = pvArgs(3) Else vContext = Nothing
+ If Not ScriptForge.SF_Utils._Validate(vContext, &quot;DialogName&quot;, V_OBJECT) Then GoTo Finally
+ Set oDialog = Nothing
+
+Try:
+ &apos; Determine the library container hosting the dialog
+ Set oUi = ScriptForge.SF_Register.CreateScriptService(&quot;UI&quot;)
+ Set oComp = Nothing
+ If VarType(vContainer) = V_STRING Then
+ bFound = ( UCase(vContainer) = UCase(cstGlobal) )
+ End If
+ If Not bFound Then
+ Select Case VarType(vContainer)
+ Case V_STRING
+ If Len(vContainer) &gt; 0 Then
+ bFound = False
+ Set oEnum = StarDesktop.Components().createEnumeration
+ Do While oEnum.hasMoreElements
+ Set oComp = oEnum.nextElement
+ vWindow = oUi._IdentifyWindow(oComp)
+ With vWindow
+ &apos; Does the current window match the argument ?
+ If (Len(.WindowFileName) &gt; 0 And .WindowFileName = ScriptForge.SF_FileSystem._ConvertToUrl(vContainer)) _
+ Or (Len(.WindowName) &gt; 0 And .WindowName = vContainer) _
+ Or (Len(.WindowTitle) &gt; 0 And .WindowTitle = vContainer) Then
+ bFound = True
+ Exit Do
+ End If
+ End With
+ Loop
+ Else
+ bFound = True
+ Set oComp = StarDesktop.CurrentComponent
+ vWindow = oUi._IdentifyWindow(oComp)
+ End If
+ Case V_OBJECT &apos; com.sun.star.lang.XComponent
+ bFound = True
+ vWindow = oUi._IdentifyWindow(vContainer)
+ Set oComp = vContainer
+ End Select
+ If Not bFound Then GoTo CatchNotFound
+ If Len(vWindow.DocumentType) = 0 Then GoTo CatchNotFound
+ End If
+
+ &apos; Determine the dialog provider
+ Select Case True
+ Case IsNull(vContext) And IsNull(oComp) &apos; Basic and GlobalScope
+ Set oDialogProvider = GetProcessServiceManager.createInstance(&quot;com.sun.star.awt.DialogProvider&quot;)
+ Case IsNull(vContext) And Not IsNull(oComp) &apos; Basic and Document
+ Set oDialogProvider = GetProcessServiceManager.createInstanceWithArguments(&quot;com.sun.star.awt.DialogProvider&quot;, Array(oComp))
+ Case Not IsNull(vContext) And IsNull(oComp) &apos; Python and GlobalScope
+ Set oDialogProvider = vContext.getServiceManager().createInstanceWithContext(&quot;com.sun.star.awt.DialogProvider&quot;, vContext)
+ Case Not IsNull(vContext) And Not IsNull(oComp) &apos; Python and Document
+ Set oDialogProvider = vContext.getServiceManager().createInstanceWithArguments(&quot;com.sun.star.awt.DialogProvider&quot;, Array(oComp))
+ End Select
+
+ &apos; Create the graphical interface
+ sScope = Iif(IsNull(oComp), &quot;application&quot;, &quot;document&quot;)
+ sURI = &quot;vnd.sun.star.script:&quot; &amp; vLibrary &amp; &quot;.&quot; &amp; vDialogName &amp; &quot;?location=&quot; &amp; sScope
+ On Local Error GoTo CatchNotFound
+ Set oDialogControl = oDialogProvider.createDialog(sURI)
+
+ &apos; Initialize the basic SF_Dialog instance to return to the user script
+ Set oDialog = New SF_Dialog
+ With oDialog
+ Set .[Me] = oDialog
+ If VarType(vContainer) = V_STRING Then ._Container = vContainer Else ._Container = vWindow.WindowName
+ ._Library = vLibrary
+ ._Name = vDialogName
+ Set ._DialogProvider = oDialogProvider
+ Set ._DialogControl = oDialogControl
+ ._Initialize()
+ End With
+
+Finally:
+ Set _NewDialog = oDialog
+ Exit Function
+Catch:
+ GoTo Finally
+CatchNotFound:
+ ScriptForge.SF_Exception.RaiseFatal(DIALOGNOTFOUNDERROR, &quot;Service&quot;, cstService _
+ , &quot;Container&quot;, vContainer, &quot;Library&quot;, vLibrary, &quot;DialogName&quot;, vDialogName)
+ GoTo Finally
+End Function &apos; SFDialogs.SF_Register._NewDialog
+
+REM ============================================== END OF SFDIALOGS.SF_REGISTER
+</script:module> \ No newline at end of file