<?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_Dialog" 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 ClassModule

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_Dialog
&apos;&apos;&apos;	=========
&apos;&apos;&apos;		Management of dialogs defined with the Basic IDE
&apos;&apos;&apos;		Each instance of the current class represents a single dialog box displayed to the user
&apos;&apos;&apos;
&apos;&apos;&apos;		A dialog box can be displayed in modal or in non-modal modes
&apos;&apos;&apos;		In modal mode, the box is displayed and the execution of the macro process is suspended
&apos;&apos;&apos;		until one of the OK or Cancel buttons is pressed. In the meantime, other user actions
&apos;&apos;&apos;		executed on the box can trigger specific actions.
&apos;&apos;&apos;		In non-modal mode, the dialog box is &quot;floating&quot; on the user desktop and the execution
&apos;&apos;&apos;		of the macro process continues normally
&apos;&apos;&apos;		A dialog box disappears from memory after its explicit termination.
&apos;&apos;&apos;
&apos;&apos;&apos;		Service invocation and usage:
&apos;&apos;&apos;			Dim myDialog As Object, lButton As Long
&apos;&apos;&apos;				Set myDialog = CreateScriptService(&quot;SFDialogs.Dialog&quot;, Container, Library, DialogName)
&apos;&apos;&apos;					&apos;	Args:
&apos;&apos;&apos;					&apos;		Container:	&quot;GlobalScope&quot; for preinstalled libraries
&apos;&apos;&apos;					&apos;					A window name (see its definition in the ScriptForge.UI service)
&apos;&apos;&apos;					&apos;					&quot;&quot; (default) = the current document
&apos;&apos;&apos;					&apos;		Library:	The (case-sensitive) name of a library contained in the container
&apos;&apos;&apos;					&apos;					Default = &quot;Standard&quot;
&apos;&apos;&apos;					&apos;		DialogName:	a case-sensitive string designating the dialog where it is about
&apos;&apos;&apos;				&apos;	... Initialize controls ...
&apos;&apos;&apos;				lButton = myDialog.Execute()	&apos;	Default mode = Modal
&apos;&apos;&apos;				If lButton = myDialog.OKBUTTON Then
&apos;&apos;&apos;					&apos;	... Process controls and do what is needed
&apos;&apos;&apos;				End If
&apos;&apos;&apos;				myDialog.Terminate()
&apos;&apos;&apos;
&apos;&apos;&apos;		Detailed user documentation:
&apos;&apos;&apos;			https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_dialog.html?DbPAR=BASIC
&apos;&apos;&apos;
&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&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 ================================================================== EXCEPTIONS

Private Const DIALOGDEADERROR		=	&quot;DIALOGDEADERROR&quot;

REM ============================================================= PRIVATE MEMBERS

Private [Me]				As Object
Private [_Parent]			As Object
Private ObjectType			As String		&apos; Must be DIALOG
Private ServiceName			As String

&apos;	Dialog location
Private _Container			As String
Private _Library			As String
Private _Name				As String
Private _CacheIndex			As Long			&apos; Index in cache storage

&apos;	Dialog UNO references
Private _DialogProvider		As Object		&apos; com.sun.star.io.XInputStreamProvider
Private _DialogControl		As Object		&apos; com.sun.star.awt.XControl - stardiv.Toolkit.UnoDialogControl
Private _DialogModel		As Object		&apos; com.sun.star.awt.XControlModel - stardiv.Toolkit.UnoControlDialogModel

&apos;	Dialog attributes
Private _Displayed			As Boolean		&apos; True after Execute()
Private _Modal				As Boolean		&apos; Set by Execute()

&apos;	Persistent storage for controls
Private _ControlCache		As Variant		&apos; Array of control objects sorted like ElementNames of the Dialog model

REM ============================================================ MODULE CONSTANTS

Private Const OKBUTTON		= 1
Private Const CANCELBUTTON	= 0

REM ====================================================== CONSTRUCTOR/DESTRUCTOR

REM -----------------------------------------------------------------------------
Private Sub Class_Initialize()
	Set [Me] = Nothing
	Set [_Parent] = Nothing
	ObjectType = &quot;DIALOG&quot;
	ServiceName = &quot;SFDialogs.Dialog&quot;
	_Container = &quot;&quot;
	_Library = &quot;&quot;
	_Name = &quot;&quot;
	_CacheIndex = -1
	Set _DialogProvider = Nothing
	Set _DialogControl = Nothing
	Set _DialogModel = Nothing
	_Displayed = False
	_Modal = True
	_ControlCache = Array()
End Sub		&apos;	SFDialogs.SF_Dialog Constructor

REM -----------------------------------------------------------------------------
Private Sub Class_Terminate()
	Call Class_Initialize()
End Sub		&apos;	SFDialogs.SF_Dialog Destructor

REM -----------------------------------------------------------------------------
Public Function Dispose() As Variant
	If _CacheIndex &gt;= 0 Then Terminate()
	Call Class_Terminate()
	Set Dispose = Nothing
End Function	&apos;	SFDialogs.SF_Dialog Explicit Destructor

REM ================================================================== PROPERTIES

REM -----------------------------------------------------------------------------
Property Get Caption() As Variant
&apos;&apos;&apos;	The Caption property refers to the title of the dialog
	Caption = _PropertyGet(&quot;Caption&quot;)
End Property	&apos;	SFDialogs.SF_Dialog.Caption (get)

REM -----------------------------------------------------------------------------
Property Let Caption(Optional ByVal pvCaption As Variant)
&apos;&apos;&apos;	Set the updatable property Caption
	_PropertySet(&quot;Caption&quot;, pvCaption)
End Property	&apos;	SFDialogs.SF_Dialog.Caption (let)

REM -----------------------------------------------------------------------------
Property Get Height() As Variant
&apos;&apos;&apos;	The Height property refers to the height of the dialog box
	Height = _PropertyGet(&quot;Height&quot;)
End Property	&apos;	SFDialogs.SF_Dialog.Height (get)

REM -----------------------------------------------------------------------------
Property Let Height(Optional ByVal pvHeight As Variant)
&apos;&apos;&apos;	Set the updatable property Height
	_PropertySet(&quot;Height&quot;, pvHeight)
End Property	&apos;	SFDialogs.SF_Dialog.Height (let)

REM -----------------------------------------------------------------------------
Property Get Modal() As Boolean
&apos;&apos;&apos;	The Modal property specifies if the dialog box has been executed in modal mode
	Modal = _PropertyGet(&quot;Modal&quot;)
End Property	&apos;	SFDialogs.SF_Dialog.Modal (get)

REM -----------------------------------------------------------------------------
Property Get Name() As String
&apos;&apos;&apos;	Return the name of the actual dialog
	Name = _PropertyGet(&quot;Name&quot;)
End Property	&apos;	SFDialogs.SF_Dialog.Name

REM -----------------------------------------------------------------------------
Property Get OnFocusGained() As Variant
&apos;&apos;&apos;	Get the script associated with the OnFocusGained event
	OnFocusGained = _PropertyGet(&quot;OnFocusGained&quot;)
End Property	&apos;	SFDialogs.SF_Dialog.OnFocusGained (get)

REM -----------------------------------------------------------------------------
Property Get OnFocusLost() As Variant
&apos;&apos;&apos;	Get the script associated with the OnFocusLost event
	OnFocusLost = _PropertyGet(&quot;OnFocusLost&quot;)
End Property	&apos;	SFDialogs.SF_Dialog.OnFocusLost (get)

REM -----------------------------------------------------------------------------
Property Get OnKeyPressed() As Variant
&apos;&apos;&apos;	Get the script associated with the OnKeyPressed event
	OnKeyPressed = _PropertyGet(&quot;OnKeyPressed&quot;)
End Property	&apos;	SFDialogs.SF_Dialog.OnKeyPressed (get)

REM -----------------------------------------------------------------------------
Property Get OnKeyReleased() As Variant
&apos;&apos;&apos;	Get the script associated with the OnKeyReleased event
	OnKeyReleased = _PropertyGet(&quot;OnKeyReleased&quot;)
End Property	&apos;	SFDialogs.SF_Dialog.OnKeyReleased (get)

REM -----------------------------------------------------------------------------
Property Get OnMouseDragged() As Variant
&apos;&apos;&apos;	Get the script associated with the OnMouseDragged event
	OnMouseDragged = _PropertyGet(&quot;OnMouseDragged&quot;)
End Property	&apos;	SFDialogs.SF_Dialog.OnMouseDragged (get)

REM -----------------------------------------------------------------------------
Property Get OnMouseEntered() As Variant
&apos;&apos;&apos;	Get the script associated with the OnMouseEntered event
	OnMouseEntered = _PropertyGet(&quot;OnMouseEntered&quot;)
End Property	&apos;	SFDialogs.SF_Dialog.OnMouseEntered (get)

REM -----------------------------------------------------------------------------
Property Get OnMouseExited() As Variant
&apos;&apos;&apos;	Get the script associated with the OnMouseExited event
	OnMouseExited = _PropertyGet(&quot;OnMouseExited&quot;)
End Property	&apos;	SFDialogs.SF_Dialog.OnMouseExited (get)

REM -----------------------------------------------------------------------------
Property Get OnMouseMoved() As Variant
&apos;&apos;&apos;	Get the script associated with the OnMouseMoved event
	OnMouseMoved = _PropertyGet(&quot;OnMouseMoved&quot;)
End Property	&apos;	SFDialogs.SF_Dialog.OnMouseMoved (get)

REM -----------------------------------------------------------------------------
Property Get OnMousePressed() As Variant
&apos;&apos;&apos;	Get the script associated with the OnMousePressed event
	OnMousePressed = _PropertyGet(&quot;OnMousePressed&quot;)
End Property	&apos;	SFDialogs.SF_Dialog.OnMousePressed (get)

REM -----------------------------------------------------------------------------
Property Get OnMouseReleased() As Variant
&apos;&apos;&apos;	Get the script associated with the OnMouseReleased event
	OnMouseReleased = _PropertyGet(&quot;OnMouseReleased&quot;)
End Property	&apos;	SFDialogs.SF_Dialog.OnMouseReleased (get)

REM -----------------------------------------------------------------------------
Property Get Page() As Variant
&apos;&apos;&apos;	A dialog may have several pages that can be traversed by the user step by step. The Page property of the Dialog object defines which page of the dialog is active.
&apos;&apos;&apos;	The Page property of a control defines the page of the dialog on which the control is visible.
&apos;&apos;&apos;	For example, if a control has a page value of 1, it is only visible on page 1 of the dialog.
&apos;&apos;&apos;	If the page value of the dialog is increased from 1 to 2, then all controls with a page value of 1 disappear and all controls with a page value of 2 become visible.
	Page = _PropertyGet(&quot;Page&quot;)
End Property	&apos;	SFDialogs.SF_Dialog.Page (get)

REM -----------------------------------------------------------------------------
Property Let Page(Optional ByVal pvPage As Variant)
&apos;&apos;&apos;	Set the updatable property Page
	_PropertySet(&quot;Page&quot;, pvPage)
End Property	&apos;	SFDialogs.SF_Dialog.Page (let)

REM -----------------------------------------------------------------------------
Property Get Visible() As Variant
&apos;&apos;&apos;	The Visible property is False before the Execute() statement
	Visible = _PropertyGet(&quot;Visible&quot;)
End Property	&apos;	SFDialogs.SF_Dialog.Visible (get)

REM -----------------------------------------------------------------------------
Property Let Visible(Optional ByVal pvVisible As Variant)
&apos;&apos;&apos;	Set the updatable property Visible
	_PropertySet(&quot;Visible&quot;, pvVisible)
End Property	&apos;	SFDialogs.SF_Dialog.Visible (let)

REM -----------------------------------------------------------------------------
Property Get Width() As Variant
&apos;&apos;&apos;	The Width property refers to the Width of the dialog box
	Width = _PropertyGet(&quot;Width&quot;)
End Property	&apos;	SFDialogs.SF_Dialog.Width (get)

REM -----------------------------------------------------------------------------
Property Let Width(Optional ByVal pvWidth As Variant)
&apos;&apos;&apos;	Set the updatable property Width
	_PropertySet(&quot;Width&quot;, pvWidth)
End Property	&apos;	SFDialogs.SF_Dialog.Width (let)

REM -----------------------------------------------------------------------------
Property Get XDialogModel() As Object
&apos;&apos;&apos;	The XDialogModel property returns the model UNO object of the dialog
	XDialogModel = _PropertyGet(&quot;XDialogModel&quot;)
End Property	&apos;	SFDialogs.SF_Dialog.XDialogModel (get)

REM -----------------------------------------------------------------------------
Property Get XDialogView() As Object
&apos;&apos;&apos;	The XDialogView property returns the view UNO object of the dialog
	XDialogView = _PropertyGet(&quot;XDialogView&quot;)
End Property	&apos;	SFDialogs.SF_Dialog.XDialogView (get)

REM ===================================================================== METHODS

REM -----------------------------------------------------------------------------
Public Function Activate() As Boolean
&apos;&apos;&apos;	Set the focus on the current dialog instance
&apos;&apos;&apos;	Probably called from after an event occurrence or to focus on a non-modal dialog
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;	Returns:
&apos;&apos;&apos;		True if focusing is successful
&apos;&apos;&apos;	Example:
&apos;&apos;&apos;		Dim oDlg As Object
&apos;&apos;&apos;			Set oDlg = CreateScriptService(,, &quot;myDialog&quot;)	&apos;	Dialog stored in current document&apos;s standard library
&apos;&apos;&apos;			oDlg.Activate()

Dim bActivate As Boolean		&apos;	Return value
Const cstThisSub = &quot;SFDialogs.Dialog.Activate&quot;
Const cstSubArgs = &quot;&quot;

	If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
	bActivate = False

Check:
	If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
		If Not _IsStillAlive() Then GoTo Finally
	End If
Try:
	If Not IsNull(_DialogControl) Then
		_DialogControl.setFocus()
		bActivate = True
	End If

Finally:
	Activate = bActivate
	ScriptForge.SF_Utils._ExitFunction(cstThisSub)
	Exit Function
Catch:
	GoTo Finally
End Function	&apos;	SFDialogs.SF_Dialog.Activate

REM -----------------------------------------------------------------------------
Public Function Controls(Optional ByVal ControlName As Variant) As Variant
&apos;&apos;&apos;	Return either
&apos;&apos;&apos;		- the list of the controls contained in the dialog
&apos;&apos;&apos;		- a dialog control object based on its name
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		ControlName: a valid control name as a case-sensitive string. If absent the list is returned
&apos;&apos;&apos;	Returns:
&apos;&apos;&apos;		A zero-base array of strings if ControlName is absent
&apos;&apos;&apos;		An instance of the SF_DialogControl class if ControlName exists
&apos;&apos;&apos;	Exceptions:
&apos;&apos;&apos;		ControlName is invalid
&apos;&apos;&apos;	Example:
&apos;&apos;&apos;			Dim myDialog As Object, myList As Variant, myControl As Object
&apos;&apos;&apos;				Set myDialog = CreateScriptService(&quot;SFDialogs.Dialog&quot;, Container, Library, DialogName)
&apos;&apos;&apos;				myList = myDialog.Controls()
&apos;&apos;&apos;				Set myControl = myDialog.Controls(&quot;myTextBox&quot;)

Dim oControl As Object				&apos;	The new control class instance
Dim lIndexOfNames As Long			&apos;	Index in ElementNames array. Used to access _ControlCache
Dim vControl As Variant				&apos;	Alias of _ControlCache entry
Const cstThisSub = &quot;SFDialogs.Dialog.Controls&quot;
Const cstSubArgs = &quot;[ControlName]&quot;

	If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch

Check:
	If IsMissing(ControlName) Or IsEmpty(ControlName) Then ControlName = &quot;&quot;
	If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
		If Not _IsStillAlive() Then GoTo Finally
		If Not ScriptForge.SF_Utils._Validate(ControlName, &quot;ControlName&quot;, V_STRING) Then GoTo Finally
	End If

Try:
	If Len(ControlName) = 0 Then
		Controls = _DialogModel.getElementNames()
	Else
		If Not _DialogModel.hasByName(ControlName) Then GoTo CatchNotFound
		lIndexOfNames = ScriptForge.IndexOf(_DialogModel.getElementNames(), ControlName, CaseSensitive := True)
		&apos;	Reuse cache when relevant
		vControl = _ControlCache(lIndexOfNames)
		If IsEmpty(vControl) Then
			&apos;	Create the new dialog control class instance
			Set oControl = New SF_DialogControl
			With oControl
				._Name = ControlName
				Set .[Me] = oControl
				Set .[_Parent] = [Me]
				._IndexOfNames = ScriptForge.IndexOf(_DialogModel.getElementNames(), ControlName, CaseSensitive := True)
				._DialogName = _Name
				Set ._ControlModel = _DialogModel.getByName(ControlName)
				Set ._ControlView = _DialogControl.getControl(ControlName)
				._Initialize()
			End With
		Else
			Set oControl = vControl
		End If
		Set Controls = oControl
	End If

Finally:
	ScriptForge.SF_Utils._ExitFunction(cstThisSub)
	Exit Function
Catch:
	GoTo Finally
CatchNotFound:
	ScriptForge.SF_Utils._Validate(ControlName, &quot;ControlName&quot;, V_STRING, _DialogModel.getElementNames())
	GoTo Finally
End Function	&apos;	SFDialogs.SF_Dialog.Controls

REM -----------------------------------------------------------------------------
Public Sub EndExecute(Optional ByVal ReturnValue As Variant)
&apos;&apos;&apos;	Ends the display of a modal dialog and gives back the argument
&apos;&apos;&apos;	as return value for the current Execute() action
&apos;&apos;&apos;	EndExecute is usually contained in the processing of a macro
&apos;&apos;&apos;	triggered by a dialog or control event
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		ReturnValue: must be numeric. The value passed to the running Execute() method
&apos;&apos;&apos;	Example:
&apos;&apos;&apos;		Sub OnEvent(poEvent As Variant)
&apos;&apos;&apos;		Dim oDlg As Object
&apos;&apos;&apos;			Set oDlg = CreateScriptService(&quot;SFDialogs.DialogEvent&quot;, poEvent)
&apos;&apos;&apos;			oDlg.EndExecute(25)
&apos;&apos;&apos;		End Sub

Dim lExecute As Long			&apos;	Alias of ReturnValue
Const cstThisSub = &quot;SFDialogs.Dialog.EndExecute&quot;
Const cstSubArgs = &quot;ReturnValue&quot;

	If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch

Check:
	If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
		If Not _IsStillAlive() Then GoTo Finally
		If Not ScriptForge.SF_Utils._Validate(ReturnValue, &quot;ReturnValue&quot;, V_NUMERIC) Then GoTo Finally
	End If

Try:
	lExecute = CLng(ReturnValue)
	Call _DialogControl.endDialog(lExecute)

Finally:
	ScriptForge.SF_Utils._ExitFunction(cstThisSub)
	Exit Sub
Catch:
	GoTo Finally
End Sub			&apos;	SFDialogs.SF_Dialog.EndExecute

REM -----------------------------------------------------------------------------
Public Function Execute(Optional ByVal Modal As Variant) As Long
&apos;&apos;&apos;	Display the dialog and wait for its termination by the user
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		Modal: False when non-modal dialog. Default = True
&apos;&apos;&apos;	Returns:
&apos;&apos;&apos;		0 = Cancel button pressed
&apos;&apos;&apos;		1 = OK button pressed
&apos;&apos;&apos;		Otherwise: the dialog stopped with an EndExecute statement executed from a dialog or control event
&apos;&apos;&apos;	Example:
&apos;&apos;&apos;		Dim oDlg As Object, lReturn As Long
&apos;&apos;&apos;			Set oDlg = CreateScriptService(,, &quot;myDialog&quot;)	&apos;	Dialog stored in current document&apos;s standard library
&apos;&apos;&apos;			lReturn = oDlg.Execute()
&apos;&apos;&apos;			Select Case lReturn

Dim lExecute As Long			&apos;	Return value
Const cstThisSub = &quot;SFDialogs.Dialog.Execute&quot;
Const cstSubArgs = &quot;[Modal=True]&quot;

	If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
	lExecute = -1

Check:
	If IsMissing(Modal) Or IsEmpty(Modal) Then Modal = True
	If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
		If Not _IsStillAlive() Then GoTo Finally
		If Not ScriptForge.SF_Utils._Validate(Modal, &quot;Modal&quot;, V_BOOLEAN) Then GoTo Finally
	End If

Try:
	If Modal Then
		_Modal = True
		_Displayed = True
		lExecute = _DialogControl.execute()
		Select Case lExecute
			Case 1		:	lExecute = OKBUTTON
			Case 0		:	lExecute = CANCELBUTTON
			Case Else
		End Select
		_Displayed = False
	Else
		_Modal = False
		_Displayed = True
		_DialogModel.DesktopAsParent = True
		_DialogControl.setVisible(True)
		lExecute = 0
	End If

Finally:
	Execute = lExecute
	ScriptForge.SF_Utils._ExitFunction(cstThisSub)
	Exit Function
Catch:
	GoTo Finally
End Function	&apos;	SFDialogs.SF_Dialog.Execute

REM -----------------------------------------------------------------------------
Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
&apos;&apos;&apos;	Return the actual value of the given property
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		PropertyName: the name of the property as a string
&apos;&apos;&apos;	Returns:
&apos;&apos;&apos;		The actual value of the property
&apos;&apos;&apos;	Exceptions:
&apos;&apos;&apos;		ARGUMENTERROR		The property does not exist
&apos;&apos;&apos;	Examples:
&apos;&apos;&apos;		oDlg.GetProperty(&quot;Caption&quot;)

Const cstThisSub = &quot;SFDialogs.Dialog.GetProperty&quot;
Const cstSubArgs = &quot;&quot;

	If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
	GetProperty = Null

Check:
	If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
		If Not ScriptForge.SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
	End If

Try:
	GetProperty = _PropertyGet(PropertyName)

Finally:
	SF_Utils._ExitFunction(cstThisSub)
	Exit Function
Catch:
	GoTo Finally
End Function	&apos;	SFDialogs.SF_Dialog.GetProperty

REM -----------------------------------------------------------------------------
Public Function GetTextsFromL10N(Optional ByRef L10N As Variant) As Boolean
&apos;&apos;&apos; Replace all fixed text strings of a dialog by their localized version
&apos;&apos;&apos;	Replaced texts are:
&apos;&apos;&apos;		- the title of the dialog
&apos;&apos;&apos;		- the caption associated with next control types: Button, CheckBox, FixedLine, FixedText, GroupBox and RadioButton
&apos;&apos;&apos;		- the content of list- and comboboxes
&apos;&apos;&apos;		- the tip- or helptext displayed when the mouse is hovering the control
&apos;&apos;&apos;	The current method has a twin method ScriptForge.SF_L10N.AddTextsFromDialog
&apos;&apos;&apos;	The current method is probably run before the Execute() method
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		L10N : a &quot;L10N&quot; service instance created with CreateScriptService(&quot;L10N&quot;)
&apos;&apos;&apos;	Returns:
&apos;&apos;&apos;		True when successful
&apos;&apos;&apos;	Examples:
&apos;&apos;&apos;		Dim myPO As Object, oDlg As Object
&apos;&apos;&apos;		Set oDlg = CreateScriptService(&quot;Dialog&quot;, &quot;GlobalScope&quot;, &quot;XrayTool&quot;, &quot;DlgXray&quot;)
&apos;&apos;&apos;		Set myPO = CreateScriptService(&quot;L10N&quot;, &quot;C:\myPOFiles\&quot;, &quot;fr-BE&quot;)
&apos;&apos;&apos;		oDlg.GetTextsFromL10N(myPO)

Dim bGet As Boolean					&apos;	Return value
Dim vControls As Variant			&apos;	Array of control names
Dim sControl As String				&apos;	A single control name
Dim oControl As Object				&apos;	SFDialogs.DialogControl
Dim sText As String					&apos;	The text found in the dialog
Dim sTranslation As String			&apos;	The translated text got from the dictionary
Dim vSource As Variant				&apos;	RowSource property of dialog control as an array
Dim bChanged As Boolean				&apos;	True when at least 1 item of a RowSource is modified
Dim i As Long

Const cstThisSub = &quot;SFDialogs.Dialog.GetTextsFromL10N&quot;
Const cstSubArgs = &quot;L10N&quot;

	If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
	bGet = False

Check:
	If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
		If Not SF_Utils._Validate(L10N, &quot;L10N&quot;, V_OBJECT, , , &quot;L10N&quot;) Then GoTo Finally
	End If

Try:
	&apos;	Get the dialog title
	sText = Caption
	If Len(sText) &gt; 0 Then
		sTranslation = L10N._(sText)
		If sText &lt;&gt; sTranslation Then Caption = sTranslation
	End If
	&apos;	Scan all controls
	vControls = Controls()
	For Each sControl In vControls
		Set oControl = Controls(sControl)
		With oControl
			&apos;	Extract fixed texts
			sText = .Caption
			If Len(sText) &gt; 0 Then
				sTranslation = L10N._(sText)
				If sText &lt;&gt; sTranslation Then .Caption = sTranslation
			End If
			vSource = .RowSource	&apos;	List and comboboxes only
			If IsArray(vSource) Then
				bChanged = False
				For i = 0 To UBound(vSource)
					If Len(vSource(i)) &gt; 0 Then
						sTranslation = L10N._(vSource(i))
						If sTranslation &lt;&gt; vSource(i) Then
							bChanged = True
							vSource(i) = sTranslation
						End If
					End If
				Next i
				&apos;	Rewrite if at least 1 item has been modified by the translation process
				If bChanged Then .RowSource = vSource
			End If
			sText = .TipText
			If Len(sText) &gt; 0 Then
				sTranslation = L10N._(sText)
				If sText &lt;&gt; sTranslation Then .TipText = sTranslation
			End If
		End With
	Next sControl

	bGet = True

Finally:
	GetTextsFromL10N = bGet
	SF_Utils._ExitFunction(cstThisSub)
	Exit Function
Catch:
	GoTo Finally
End Function    &apos;   SFDialogs.SF_Dialog.GetTextsFromL10N

REM -----------------------------------------------------------------------------
Public Function Methods() As Variant
&apos;&apos;&apos;	Return the list of public methods of the Model service as an array

	Methods = Array( _
					&quot;Activate&quot; _
					, &quot;Controls&quot; _
					, &quot;EndExecute&quot; _
					, &quot;Execute&quot; _
					, &quot;GetTextsFromL10N&quot; _
					, &quot;Terminate&quot; _
					)

End Function	&apos;	SFDialogs.SF_Dialog.Methods

REM -----------------------------------------------------------------------------
Public Function Properties() As Variant
&apos;&apos;&apos;	Return the list or properties of the Dialog class as an array

	Properties = Array( _
					&quot;Caption&quot; _
					, &quot;Height&quot; _
					, &quot;Modal&quot; _
					, &quot;Name&quot; _
					, &quot;OnFocusGained&quot; _
					, &quot;OnFocusLost&quot; _
					, &quot;OnKeyPressed&quot; _
					, &quot;OnKeyReleased&quot; _
					, &quot;OnMouseDragged&quot; _
					, &quot;OnMouseEntered&quot; _
					, &quot;OnMouseExited&quot; _
					, &quot;OnMouseMoved&quot; _
					, &quot;OnMousePressed&quot; _
					, &quot;OnMouseReleased&quot; _
					, &quot;Page&quot; _
					, &quot;Visible&quot; _
					, &quot;Width&quot; _
					, &quot;XDialogModel&quot; _
					, &quot;XDialogView&quot; _
					)

End Function	&apos;	SFDialogs.SF_Dialog.Properties

REM -----------------------------------------------------------------------------
Public Function SetProperty(Optional ByVal PropertyName As Variant _
								, Optional ByRef Value As Variant _
								) As Boolean
&apos;&apos;&apos;	Set a new value to the given property
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		PropertyName: the name of the property as a string
&apos;&apos;&apos;		Value: its new value
&apos;&apos;&apos;	Exceptions
&apos;&apos;&apos;		ARGUMENTERROR		The property does not exist

Const cstThisSub = &quot;SFDialogs.Dialog.SetProperty&quot;
Const cstSubArgs = &quot;PropertyName, Value&quot;

	If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
	SetProperty = False

Check:
	If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
		If Not SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
	End If

Try:
	SetProperty = _PropertySet(PropertyName, Value)

Finally:
	SF_Utils._ExitFunction(cstThisSub)
	Exit Function
Catch:
	GoTo Finally
End Function	&apos;	SFDialogs.SF_Dialog.SetProperty

REM -----------------------------------------------------------------------------
Public Function Terminate() As Boolean
&apos;&apos;&apos;	Terminate the dialog service for the current dialog instance
&apos;&apos;&apos;	After termination any action on the current instance will be ignored
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;	Returns:
&apos;&apos;&apos;		True if termination is successful
&apos;&apos;&apos;	Example:
&apos;&apos;&apos;		Dim oDlg As Object, lReturn As Long
&apos;&apos;&apos;			Set oDlg = CreateScriptService(,, &quot;myDialog&quot;)	&apos;	Dialog stored in current document&apos;s standard library
&apos;&apos;&apos;			lreturn = oDlg.Execute()
&apos;&apos;&apos;			Select Case lReturn
&apos;&apos;&apos;					&apos;	...
&apos;&apos;&apos;			End Select
&apos;&apos;&apos;			oDlg.Terminate()

Dim bTerminate As Boolean		&apos;	Return value
Const cstThisSub = &quot;SFDialogs.Dialog.Terminate&quot;
Const cstSubArgs = &quot;&quot;

	If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
	bTerminate = False

Check:
	If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
		If Not _IsStillAlive() Then GoTo Finally
	End If
Try:
	_DialogControl.dispose()
	Set _DialogControl = Nothing
	SF_Register._CleanCacheEntry(_CacheIndex)
	_CacheIndex = -1
	Dispose()
	
	bTerminate = True

Finally:
	Terminate = bTerminate
	ScriptForge.SF_Utils._ExitFunction(cstThisSub)
	Exit Function
Catch:
	GoTo Finally
End Function	&apos;	SFDialogs.SF_Dialog.Terminate

REM =========================================================== PRIVATE FUNCTIONS

REM -----------------------------------------------------------------------------
Public Function _GetEventName(ByVal psProperty As String) As String
&apos;&apos;&apos;	Return the LO internal event name derived from the SF property name
&apos;&apos;&apos;	The SF property name is not case sensitive, while the LO name is case-sensitive
&apos;	Corrects the typo on ErrorOccur(r?)ed, if necessary

Dim vProperties As Variant			&apos;	Array of class properties
Dim sProperty As String				&apos;	Correctly cased property name

	vProperties = Properties()
	sProperty = vProperties(ScriptForge.SF_Array.IndexOf(vProperties, psProperty, SortOrder := &quot;ASC&quot;))

	_GetEventName = LCase(Mid(sProperty, 3, 1)) &amp; Right(sProperty, Len(sProperty) - 3)
	
End Function	&apos;	SFDialogs.SF_Dialog._GetEventName

REM -----------------------------------------------------------------------------
Private Function _GetListener(ByVal psEventName As String) As String
&apos;&apos;&apos;	Getting/Setting macros triggered by events requires a Listener-EventName pair
&apos;&apos;&apos;	Return the X...Listener corresponding with the event name in argument

	Select Case UCase(psEventName)
		Case UCase(&quot;OnFocusGained&quot;), UCase(&quot;OnFocusLost&quot;)
			_GetListener = &quot;XFocusListener&quot;
		Case UCase(&quot;OnKeyPressed&quot;), UCase(&quot;OnKeyReleased&quot;)
			_GetListener = &quot;XKeyListener&quot;
		Case UCase(&quot;OnMouseDragged&quot;), UCase(&quot;OnMouseMoved&quot;)
			_GetListener = &quot;XMouseMotionListener&quot;
		Case UCase(&quot;OnMouseEntered&quot;), UCase(&quot;OnMouseExited&quot;), UCase(&quot;OnMousePressed&quot;), UCase(&quot;OnMouseReleased&quot;)
			_GetListener = &quot;XMouseListener&quot;
		Case Else
			_GetListener = &quot;&quot;
	End Select
	
End Function	&apos;	SFDialogs.SF_Dialog._GetListener

REM -----------------------------------------------------------------------------
Public Sub _Initialize()
&apos;&apos;&apos;	Complete the object creation process:
&apos;&apos;&apos;		- Initialization of private members
&apos;&apos;&apos;		- Creation of the dialog graphical interface
&apos;&apos;&apos;		- Addition of the new object in the Dialogs buffer
&apos;&apos;&apos;		- Initialisation of persistent storage for controls

Try:
	&apos;	Keep reference to model
	Set _DialogModel = _DialogControl.Model

	&apos;	Add dialog reference to cache
	_CacheIndex = SF_Register._AddDialogToCache(_DialogControl, [Me])

	&apos;	Size the persistent storage
	_ControlCache = Array()
	ReDim _ControlCache(0 To UBound(_DialogModel.getElementNames()))

Finally:
	Exit Sub
End Sub			&apos;	SFDialogs.SF_Dialog._Initialize

REM -----------------------------------------------------------------------------
Private Function _IsStillAlive(Optional ByVal pbError As Boolean) As Boolean
&apos;&apos;&apos;	Return True if the dialog service is still active
&apos;&apos;&apos;	If dead the actual instance is disposed. The execution is cancelled when pbError = True (default)
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		pbError: if True (default), raise a fatal error

Dim bAlive As Boolean		&apos;	Return value
Dim sDialog As String		&apos;	Alias of DialogName

Check:
	On Local Error GoTo Catch		&apos;	Anticipate DisposedException errors or alike
	If IsMissing(pbError) Then pbError = True

Try:
	bAlive = ( Not IsNull(_DialogProvider) And Not IsNull(_DialogControl) )
	If Not bAlive Then GoTo Catch

Finally:
	_IsStillAlive = bAlive
	Exit Function
Catch:
	bAlive = False
	On Error GoTo 0
	sDialog = _Name
	Dispose()
	If pbError Then ScriptForge.SF_Exception.RaiseFatal(DIALOGDEADERROR, sDialog)
	GoTo Finally
End Function	&apos;	SFDialogs.SF_Dialog._IsStillAlive

REM -----------------------------------------------------------------------------
Private Function _PropertyGet(Optional ByVal psProperty As String) As Variant
&apos;&apos;&apos;	Return the value of the named property
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		psProperty: the name of the property

Static oSession As Object					&apos;	Alias of SF_Session
Dim oDialogEvents As Object					&apos;	com.sun.star.container.XNameContainer
Dim sEventName As String					&apos;	Internal event name
Dim cstThisSub As String
Const cstSubArgs = &quot;&quot;

	cstThisSub = &quot;SFDialogs.Dialog.get&quot; &amp; psProperty
	If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch

	ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
	If Not _IsStillAlive() Then GoTo Finally

	If IsNull(oSession) Then Set oSession = ScriptForge.SF_Services.CreateScriptService(&quot;Session&quot;)
	Select Case UCase(psProperty)
		Case UCase(&quot;Caption&quot;)
			If oSession.HasUNOProperty(_DialogModel, &quot;Title&quot;) Then _PropertyGet = _DialogModel.Title
		Case UCase(&quot;Height&quot;)
			If oSession.HasUNOProperty(_DialogModel, &quot;Height&quot;) Then _PropertyGet = _DialogModel.Height
		Case UCase(&quot;Modal&quot;)
			_PropertyGet = _Modal
		Case UCase(&quot;Name&quot;)
			_PropertyGet = _Name
		Case UCase(&quot;OnFocusGained&quot;), UCase(&quot;OnFocusLost&quot;), UCase(&quot;OnKeyPressed&quot;), UCase(&quot;OnKeyReleased&quot;) _
				, UCase(&quot;OnMouseDragged&quot;), UCase(&quot;OnMouseEntered&quot;), UCase(&quot;OnMouseExited&quot;), UCase(&quot;OnMouseMoved&quot;) _
				, UCase(&quot;OnMousePressed&quot;), UCase(&quot;OnMouseReleased&quot;)
			Set oDialogEvents = _DialogModel.getEvents()
			sEventName = &quot;com.sun.star.awt.&quot; &amp; _GetListener(psProperty) &amp; &quot;::&quot; &amp; _GetEventName(psProperty)
			If oDialogEvents.hasByName(sEventName) Then
				_PropertyGet = oDialogEvents.getByName(sEventName).ScriptCode
			Else
				_PropertyGet = &quot;&quot;
			End If
		Case UCase(&quot;Page&quot;)
			If oSession.HasUNOProperty(_DialogModel, &quot;Step&quot;) Then _PropertyGet = _DialogModel.Step
		Case UCase(&quot;Visible&quot;)
			If oSession.HasUnoMethod(_DialogControl, &quot;isVisible&quot;) Then _PropertyGet = CBool(_DialogControl.isVisible())
		Case UCase(&quot;Width&quot;)
			If oSession.HasUNOProperty(_DialogModel, &quot;Width&quot;) Then _PropertyGet = _DialogModel.Width
		Case UCase(&quot;XDialogModel&quot;)
			Set _PropertyGet = _DialogModel
		Case UCase(&quot;XDialogView&quot;)
			Set _PropertyGet = _DialogControl
		Case Else
			_PropertyGet = Null
	End Select

Finally:
	ScriptForge.SF_Utils._ExitFunction(cstThisSub)
	Exit Function
Catch:
	GoTo Finally
End Function	&apos;	SFDialogs.SF_Dialog._PropertyGet

REM -----------------------------------------------------------------------------
Private Function _PropertySet(Optional ByVal psProperty As String _
								, Optional ByVal pvValue As Variant _
								) As Boolean
&apos;&apos;&apos;	Set the new value of the named property
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		psProperty: the name of the property
&apos;&apos;&apos;		pvValue: the new value of the given property
&apos;&apos;&apos;	Returns:
&apos;&apos;&apos;		True if successful

Dim bSet As Boolean							&apos;	Return value
Static oSession As Object					&apos;	Alias of SF_Session
Dim cstThisSub As String
Const cstSubArgs = &quot;Value&quot;

	If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
	bSet = False

	cstThisSub = &quot;SFDialogs.Dialog.set&quot; &amp; psProperty
	ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
	If Not _IsStillAlive() Then GoTo Finally

	If IsNull(oSession) Then Set oSession = ScriptForge.SF_Services.CreateScriptService(&quot;Session&quot;)
	bSet = True
	Select Case UCase(psProperty)
		Case UCase(&quot;Caption&quot;)
			If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Caption&quot;, V_STRING) Then GoTo Finally
			If oSession.HasUNOProperty(_DialogModel, &quot;Title&quot;) Then _DialogModel.Title = pvValue
		Case UCase(&quot;Height&quot;)
			If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Height&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
			If oSession.HasUNOProperty(_DialogModel, &quot;Height&quot;) Then _DialogModel.Height = pvValue
		Case UCase(&quot;Page&quot;)
			If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Page&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
			If oSession.HasUNOProperty(_DialogModel, &quot;Step&quot;) Then _DialogModel.Step = CLng(pvValue)
		Case UCase(&quot;Visible&quot;)
			If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Visible&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
			If oSession.HasUnoMethod(_DialogControl, &quot;setVisible&quot;) Then _DialogControl.setVisible(pvValue)
		Case UCase(&quot;Width&quot;)
			If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Width&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
			If oSession.HasUNOProperty(_DialogModel, &quot;Width&quot;) Then _DialogModel.Width = pvValue
		Case Else
			bSet = False
	End Select

Finally:
	_PropertySet = bSet
	ScriptForge.SF_Utils._ExitFunction(cstThisSub)
	Exit Function
Catch:
	GoTo Finally
End Function	&apos;	SFDialogs.SF_Dialog._PropertySet

REM -----------------------------------------------------------------------------
Private Function _Repr() As String
&apos;&apos;&apos;	Convert the Model instance to a readable string, typically for debugging purposes (DebugPrint ...)
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;	Return:
&apos;&apos;&apos;		&quot;[DIALOG]: Container.Library.Name&quot;

	_Repr = &quot;[DIALOG]: &quot; &amp; _Container &amp; &quot;.&quot; &amp; _Library &amp; &quot;.&quot; &amp; _Name

End Function	&apos;	SFDialogs.SF_Dialog._Repr

REM ============================================ END OF SFDIALOGS.SF_DIALOG
</script:module>