<?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_UI" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
REM ===			The ScriptForge library and its associated libraries are part of the LibreOffice project.				===
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_UI
&apos;&apos;&apos;	=====
&apos;&apos;&apos;		Singleton class module for the identification and the manipulation of the
&apos;&apos;&apos;		different windows composing the whole LibreOffice application:
&apos;&apos;&apos;			- Windows selection
&apos;&apos;&apos;			- Windows moving and resizing
&apos;&apos;&apos;			- Statusbar settings
&apos;&apos;&apos;			- Creation of new windows
&apos;&apos;&apos;			- Access to the underlying &quot;documents&quot;
&apos;&apos;&apos;
&apos;&apos;&apos;		WindowName: how to designate a window. It can be either
&apos;&apos;&apos;			a full FileName given in the notation indicated by the current value of SF_FileSystem.FileNaming
&apos;&apos;&apos;			or the last component of the full FileName or even only its BaseName
&apos;&apos;&apos;			or the title of the window
&apos;&apos;&apos;			or, for new documents, something like &quot;Untitled 1&quot;
&apos;&apos;&apos;			or one of the special windows &quot;BASICIDE&quot; and &quot;WELCOMESCREEN&quot;
&apos;&apos;&apos;			The window search is case-sensitive
&apos;&apos;&apos;
&apos;&apos;&apos;		Service invocation example:
&apos;&apos;&apos;			Dim ui As Variant
&apos;&apos;&apos;			ui = CreateScriptService(&quot;UI&quot;)
&apos;&apos;&apos;
&apos;&apos;&apos;		Detailed user documentation:
&apos;&apos;&apos;			https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_ui.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

Const DOCUMENTERROR				=	&quot;DOCUMENTERROR&quot;				&apos;	Requested document was not found
Const DOCUMENTCREATIONERROR		=	&quot;DOCUMENTCREATIONERROR&quot;		&apos;	Incoherent arguments, new document could not be created
Const DOCUMENTOPENERROR			=	&quot;DOCUMENTOPENERROR&quot;			&apos;	Document could not be opened, check the arguments
Const BASEDOCUMENTOPENERROR		=	&quot;BASEDOCUMENTOPENERROR&quot;		&apos;	Id. for Base document
Const UNKNOWNFILEERROR			=	&quot;UNKNOWNFILEERROR&quot;			&apos;	Calc datasource does not exist

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

Type Window
	Component				As Object		&apos;	com.sun.star.lang.XComponent
	Frame					As Object		&apos;	com.sun.star.comp.framework.Frame
	WindowName				As String		&apos;	Object Name
	WindowTitle				As String		&apos;	Only mean to identify new documents
	WindowFileName			As String		&apos;	URL of file name
	DocumentType			As String		&apos;	Writer, Calc, ...
	ParentName				As String		&apos;	Identifier of the parent Base file when Window is a subcomponent
End Type

Type _Toolbar				&apos;	Proto-toolbar object. Passed to the &quot;Toolbar&quot; service, a full ScriptForge Toolbar object will be returned
	Component				As Object		&apos;	com.sun.star.lang.XComponent
	ResourceURL				As String		&apos;	Toolbar internal name
	UIName					As String		&apos;	Toolbar external name, may be &quot;&quot;
	UIConfigurationManager	As Object		&apos;	com.sun.star.ui.XUIConfigurationManager
	ElementsInfoIndex		As Long			&apos;	Index of the toolbar in the getElementsInfo(0) array
	Storage					As Long			&apos;	One of the toolbar location constants
End Type

&apos;	The progress/status bar of the active window
&apos;Private oStatusBar			As Object		&apos;	com.sun.star.task.XStatusIndicator

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

&apos;	Special windows
Const BASICIDE					= &quot;BASICIDE&quot;
Const WELCOMESCREEN				= &quot;WELCOMESCREEN&quot;

&apos;	Document types (only if not 1 of the special windows)
Const BASEDOCUMENT				= &quot;Base&quot;
Const CALCDOCUMENT				= &quot;Calc&quot;
Const DRAWDOCUMENT				= &quot;Draw&quot;
Const FORMDOCUMENT				= &quot;FormDocument&quot;
Const IMPRESSDOCUMENT			= &quot;Impress&quot;
Const MATHDOCUMENT				= &quot;Math&quot;
Const WRITERDOCUMENT			= &quot;Writer&quot;

&apos;	Window subtypes
Const TABLEDATA					= &quot;TableData&quot;
Const QUERYDATA					= &quot;QueryData&quot;
Const SQLDATA					= &quot;SqlData&quot;
Const BASEREPORT				= &quot;BaseReport&quot;
Const BASEDIAGRAM				= &quot;BaseDiagram&quot;

&apos;	Macro execution modes
Const cstMACROEXECNORMAL		= 0		&apos;	Default, execution depends on user configuration and choice
Const cstMACROEXECNEVER			= 1		&apos;	Macros are not executed
Const cstMACROEXECALWAYS		= 2		&apos;	Macros are always executed

&apos;	Toolbar locations
Const cstBUILTINTOOLBAR			= 0		&apos;	Standard toolbar
Const cstCUSTOMTOOLBAR			= 1		&apos;	Toolbar added by user and stored in the LibreOffice application
Const cstCUSTOMDOCTOOLBAR		= 2		&apos;	Toolbar added by user solely for a single document

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

REM -----------------------------------------------------------------------------
Public Function Dispose() As Variant
	Set Dispose = Nothing
End Function	&apos;	ScriptForge.SF_UI Explicit destructor

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

REM -----------------------------------------------------------------------------
Public Function ActiveWindow() As String
&apos;&apos;&apos;	Returns a valid WindowName for the currently active window
&apos;&apos;&apos;	When &quot;&quot; is returned, the window could not be identified

Dim vWindow As Window			&apos;	A component
Dim oComp As Object				&apos;	com.sun.star.lang.XComponent

	Set oComp = StarDesktop.CurrentComponent
	If Not IsNull(oComp) Then
		vWindow = SF_UI._IdentifyWindow(oComp)
		With vWindow
			If Len(.WindowFileName) &gt; 0 Then
				ActiveWindow = SF_FileSystem._ConvertFromUrl(.WindowFileName)
			ElseIf Len(.WindowName) &gt; 0 Then
				ActiveWindow = .WindowName
			ElseIf Len(.WindowTitle) &gt; 0 Then
				ActiveWindow = .WindowTitle
			Else
				ActiveWindow = &quot;&quot;
			End If
		End With
	End If

End Function	&apos;	ScriptForge.SF_UI.ActiveWindow

REM -----------------------------------------------------------------------------
Property Get Height() As Long
&apos;&apos;&apos;	Returns the height of the active window
Dim oPosSize As Object			&apos;	com.sun.star.awt.Rectangle
	Set oPosSize = SF_UI._PosSize()
	If Not IsNull(oPosSize) Then Height = oPosSize.Height Else Height = -1
End Property	&apos;	ScriptForge.SF_UI.Height

REM -----------------------------------------------------------------------------
Property Get MACROEXECALWAYS As Integer
&apos;&apos;&apos;	Macros are always executed
	MACROEXECALWAYS = cstMACROEXECALWAYS
End Property	&apos;	ScriptForge.SF_UI.MACROEXECALWAYS

REM -----------------------------------------------------------------------------
Property Get MACROEXECNEVER As Integer
&apos;&apos;&apos;	Macros are not executed
	MACROEXECNEVER = cstMACROEXECNEVER
End Property	&apos;	ScriptForge.SF_UI.MACROEXECNEVER

REM -----------------------------------------------------------------------------
Property Get MACROEXECNORMAL As Integer
&apos;&apos;&apos;	Default, execution depends on user configuration and choice
	MACROEXECNORMAL = cstMACROEXECNORMAL
End Property	&apos;	ScriptForge.SF_UI.MACROEXECNORMAL

REM -----------------------------------------------------------------------------
Property Get ObjectType As String
&apos;&apos;&apos;	Only to enable object representation
	ObjectType = &quot;SF_UI&quot;
End Property	&apos;	ScriptForge.SF_UI.ObjectType

REM -----------------------------------------------------------------------------
Property Get ServiceName As String
&apos;&apos;&apos;	Internal use
	ServiceName = &quot;ScriptForge.UI&quot;
End Property	&apos;	ScriptForge.SF_UI.ServiceName

REM -----------------------------------------------------------------------------
Property Get Width() As Long
&apos;&apos;&apos;	Returns the width of the active window
Dim oPosSize As Object			&apos;	com.sun.star.awt.Rectangle
	Set oPosSize = SF_UI._PosSize()
	If Not IsNull(oPosSize) Then Width = oPosSize.Width Else Width = -1
End Property	&apos;	ScriptForge.SF_UI.Width

REM -----------------------------------------------------------------------------
Property Get X() As Long
&apos;&apos;&apos;	Returns the X coordinate of the active window
Dim oPosSize As Object			&apos;	com.sun.star.awt.Rectangle
	Set oPosSize = SF_UI._PosSize()
	If Not IsNull(oPosSize) Then X = oPosSize.X Else X = -1
End Property	&apos;	ScriptForge.SF_UI.X

REM -----------------------------------------------------------------------------
Property Get Y() As Long
&apos;&apos;&apos;	Returns the Y coordinate of the active window
Dim oPosSize As Object			&apos;	com.sun.star.awt.Rectangle
	Set oPosSize = SF_UI._PosSize()
	If Not IsNull(oPosSize) Then Y = oPosSize.Y Else Y = -1
End Property	&apos;	ScriptForge.SF_UI.Y

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

REM -----------------------------------------------------------------------------
Public Function Activate(Optional ByVal WindowName As Variant) As Boolean
&apos;&apos;&apos; Make the specified window active
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		WindowName: see definitions
&apos;&apos;&apos;	Returns:
&apos;&apos;&apos;		True if the given window is found and can be activated
&apos;&apos;&apos;		There is no change in the actual user interface if no window matches the selection
&apos;&apos;&apos;	Examples:
&apos;&apos;&apos;		ui.Activate(&quot;C:\Me\My file.odt&quot;)

Dim bActivate As Boolean			&apos;	Return value
Dim oEnum As Object					&apos;	com.sun.star.container.XEnumeration
Dim oComp As Object					&apos;	com.sun.star.lang.XComponent
Dim vWindow As Window				&apos;	A single component
Dim oContainer As Object			&apos;	com.sun.star.awt.XWindow
Const cstThisSub = &quot;UI.Activate&quot;
Const cstSubArgs = &quot;WindowName&quot;

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

Check:
	If IsMissing(WindowName) Or IsEmpty(WindowName) Then WindowName = &quot;&quot;
	If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
		If Not SF_Utils._ValidateFile(WindowName, &quot;WindowName&quot;) Then GoTo Finally
	End If

Try:
	Set oEnum = StarDesktop.Components().createEnumeration
	Do While oEnum.hasMoreElements
		Set oComp = oEnum.nextElement
		vWindow = SF_UI._IdentifyWindow(oComp)
		With vWindow
			&apos;	Does the current window match the arguments ?
			If	(Len(.WindowFileName) &gt; 0 And .WindowFileName = SF_FileSystem._ConvertToUrl(WindowName)) _
				Or (Len(.WindowName) &gt; 0 And .WindowName = WindowName) _
				Or (Len(.WindowTitle) &gt; 0 And .WindowTitle = WindowName) Then
					Set oContainer = vWindow.Frame.ContainerWindow
					With oContainer
						If .isVisible() = False Then .setVisible(True)
						.IsMinimized = False
						.setFocus()
						.toFront()				&apos;	Force window change in Linux
						Wait 1					&apos;	Bypass desynchro issue in Linux
					End With
					bActivate = True
					Exit Do
			End If
		End With
	Loop

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

REM -----------------------------------------------------------------------------
Public Function CreateBaseDocument(Optional ByVal FileName As Variant _
							, Optional ByVal EmbeddedDatabase As Variant _
							, Optional ByVal RegistrationName As Variant _
							, Optional ByVal DataFileName As Variant _
							, Optional ByVal CalcFileName As Variant _
							) As Object
&apos;&apos;&apos; Create a new LibreOffice Base document embedding an empty database of the given type
&apos;&apos;&apos;	or finding its datasource in an external database file (Calc or Firebird).
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		FileName: Identifies the file to create. It must follow the SF_FileSystem.FileNaming notation
&apos;&apos;&apos;			If the file already exists, it is overwritten without warning
&apos;&apos;&apos;		EmbeddedDatabase: either &quot;HSQLDB&quot; (default) or &quot;FIREBIRD&quot; or &quot;CALC&quot;
&apos;&apos;&apos;		RegistrationName: the name used to store the new database in the databases register
&apos;&apos;&apos;			If &quot;&quot; (default), no registration takes place
&apos;&apos;&apos;			If the name already exists it is overwritten without warning
&apos;&apos;&apos;		DataFileName: when EmbedddedDatabase = &quot;CALC&quot;, the name of the file containing the tables as Calc sheets,
&apos;&apos;&apos;			when EmbeddedDatabase = &quot;FIREBIRD_EXTERNAL&quot;, the Firebird external database file.
&apos;&apos;&apos;			The name of the file must be given in SF_FileSystem.FileNaming notation
&apos;&apos;&apos;			The file must exist
&apos;&apos;&apos;		CalcFileName: only when EmbedddedDatabase = &quot;CALC&quot;, the name of the file containing the tables as Calc sheets
&apos;&apos;&apos;			The argument is obsolete as from SF 25.8.
&apos;&apos;&apos;	Returns:
&apos;&apos;&apos;		 A SFDocuments.SF_Base object or Nothing
&apos;&apos;&apos;	Exceptions
&apos;&apos;&apos;		UNKNOWNFILEERROR				Calc datasource does not exist
&apos;&apos;&apos;	Examples:
&apos;&apos;&apos;		Dim myBase As Object, myCalcBase As Object
&apos;&apos;&apos;		Set myBase = ui.CreateBaseDocument(&quot;C:\Databases\MyBaseFile.odb&quot;, &quot;FIREBIRD&quot;)
&apos;&apos;&apos;		Set myCalcBase = ui.CreateBaseDocument(&quot;C:\Databases\MyCalcBaseFile.odb&quot;, &quot;CALC&quot;, , &quot;C:\Databases\MyCalcFile.ods&quot;)

Dim oCreate As Variant				&apos;	Return value
Dim oDBContext As Object			&apos;	com.sun.star.sdb.DatabaseContext
Dim oDatabase As Object				&apos;	com.sun.star.comp.dba.ODatabaseSource
Dim sTarget As String				&apos;	sdbc abbreviation
Dim sFileName As String				&apos;	Alias of FileName
Dim FSO As Object					&apos;	Alias for FileSystem service
Const cstDocType = &quot;private:factory/s&quot;
Const cstThisSub = &quot;UI.CreateBaseDocument&quot;
Const cstSubArgs = &quot;FileName, [EmbeddedDatabase=&quot;&quot;HSQLDB&quot;&quot;|&quot;&quot;FIREBIRD&quot;&quot;|&quot;&quot;FIREBIRD_EXTERNAL&quot;&quot;|&quot;&quot;CALC&quot;&quot;], &quot; _
					&amp; &quot;[RegistrationName=&quot;&quot;&quot;&quot;], [DataFileName]&quot;

	If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
	Set oCreate = Nothing
	Set FSO = CreateScriptService(&quot;FileSystem&quot;)

Check:
	If IsMissing(EmbeddedDatabase) Or IsEmpty(EmbeddedDatabase) Then EmbeddedDatabase = &quot;HSQLDB&quot;
	If IsMissing(RegistrationName) Or IsEmpty(RegistrationName) Then RegistrationName = &quot;&quot;
	If IsMissing(DataFileName) Or IsEmpty(DataFileName) Then DataFileName = &quot;&quot;
	If IsMissing(CalcFileName) Or IsEmpty(CalcFileName) Then CalcFileName = &quot;&quot;
	If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
		If Not SF_Utils._ValidateFile(FileName, &quot;FileName&quot;) Then GoTo Finally
		If Not SF_Utils._Validate(EmbeddedDatabase, &quot;EmbeddedDatabase&quot;, V_STRING, _
									Array(&quot;CALC&quot;, &quot;HSQLDB&quot;, &quot;FIREBIRD&quot;, &quot;FIREBIRD_EXTERNAL&quot;)) Then GoTo Finally
		If Not SF_Utils._Validate(RegistrationName, &quot;RegistrationName&quot;, V_STRING) Then GoTo Finally
		If InStr(UCase(EmbeddedDatabase), &quot;CALC,FIREBIRD_EXTERNAL&quot;) &gt; 0 Then
			If Len(CalcFileName) &gt; 0 And Len(DataFileName) = 0 Then DataFileName = CalcFileName
			If Not SF_Utils._ValidateFile(DataFileName, &quot;DataFileName&quot;) Then GoTo Finally
			If Not FSO.FileExists(DataFileName) Then GoTo CatchNotExists
		End If
	End If

Try:
	sFileName = FSO._ConvertToUrl(FileName)

	Set oDBContext = SF_Utils._GetUNOService(&quot;DatabaseContext&quot;)
	With oDBContext
		Set oDatabase = .createInstance()

		&apos;	Build the url links in the database descriptors
		oDatabase.URL = sFileName
		Select Case UCase(EmbeddedDatabase)
			Case &quot;HSQLDB&quot;, &quot;FIREBIRD&quot;
				oDatabase.DatabaseDocument.DataSource.URL = &quot;sdbc:embedded:&quot; &amp; LCase(EmbeddedDatabase)
			Case &quot;CALC&quot;, &quot;FIREBIRD_EXTERNAL&quot;
				If UCase(EmbeddedDatabase) = &quot;CALC&quot; Then sTarget = &quot;calc&quot; Else sTarget = &quot;firebird&quot;
				oDatabase.DatabaseDocument.DataSource.URL = &quot;sdbc:&quot; &amp; sTarget &amp; &quot;:&quot; &amp; FSO._ConvertToUrl(DataFileName)
		End Select

		&apos;	Create empty Base document
		&apos;	An existing file is overwritten without warning
		If FSO.FileExists(FileName) Then FSO.DeleteFile(FileName)
		If FSO.FileExists(FileName &amp; &quot;.lck&quot;) Then FSO.DeleteFile(FileName &amp; &quot;.lck&quot;)
		oDatabase.DatabaseDocument.storeAsURL(sFileName, Array(SF_Utils._MakePropertyValue(&quot;Overwrite&quot;, True)))

		&apos;	Register database if requested
		If Len(RegistrationName) &gt; 0 Then
			If .hasRegisteredDatabase(RegistrationName) Then
				.changeDatabaseLocation(RegistrationName, sFileName)
			Else
				.registerDatabaseLocation(RegistrationName, sFileName)
			End If
		End If
	End With

	Set oCreate = OpenBaseDocument(FileName)

Finally:
	Set CreateBaseDocument = oCreate
	SF_Utils._ExitFunction(cstThisSub)
	Exit Function
Catch:
	GoTo Finally
CatchNotExists:
	SF_Exception.RaiseFatal(UNKNOWNFILEERROR, &quot;DataFileName&quot;, DataFileName)
	GoTo Finally
End Function    &apos;   ScriptForge.SF_UI.CreateBaseDocument

REM -----------------------------------------------------------------------------
Public Function CreateDocument(Optional ByVal DocumentType As Variant _
							, Optional ByVal TemplateFile As Variant _
							, Optional ByVal Hidden As Variant _
							) As Object
&apos;&apos;&apos; Create a new LibreOffice document of a given type or based on a given template
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		DocumentType: &quot;Calc&quot;, &quot;Writer&quot;, etc. If absent, a TemplateFile must be given
&apos;&apos;&apos;		TemplateFile: the full FileName of the template to build the new document on
&apos;&apos;&apos;			If the file does not exist, the argument is ignored
&apos;&apos;&apos;			The &quot;FileSystem&quot; service provides the TemplatesFolder and UserTemplatesFolder
&apos;&apos;&apos;				properties to help to build the argument
&apos;&apos;&apos;		Hidden: if True, open in the background (default = False)
&apos;&apos;&apos;			To use with caution: activation or closure can only happen programmatically
&apos;&apos;&apos;	Returns:
&apos;&apos;&apos;		 A SFDocuments.SF_Document object or one of its subclasses
&apos;&apos;&apos;	Exceptions:
&apos;&apos;&apos;		DOCUMENTCREATIONERROR			Wrong arguments
&apos;&apos;&apos;	Examples:
&apos;&apos;&apos;		Dim myDoc1 As Object, myDoc2 As Object, FSO As Object
&apos;&apos;&apos;		Set myDoc1 = ui.CreateDocument(&quot;Calc&quot;)
&apos;&apos;&apos;		Set FSO = CreateScriptService(&quot;FileSystem&quot;)
&apos;&apos;&apos;		Set myDoc2 = ui.CreateDocument(, FSO.BuildPath(FSO.TemplatesFolder, &quot;personal/CV.ott&quot;))

Dim oCreate As Variant				&apos;	Return value
Dim vProperties As Variant			&apos;	Array of com.sun.star.beans.PropertyValue
Dim bTemplateExists As Boolean		&apos;	True if TemplateFile is valid
Dim sNew As String					&apos;	File url
Dim oComp As Object					&apos;	Loaded component com.sun.star.lang.XComponent
Const cstDocType = &quot;private:factory/s&quot;
Const cstThisSub = &quot;UI.CreateDocument&quot;
Const cstSubArgs = &quot;[DocumentType=&quot;&quot;&quot;&quot;], [TemplateFile=&quot;&quot;&quot;&quot;], [Hidden=False]&quot;

&apos;&gt;&gt;&gt;	If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
	Set oCreate = Nothing

Check:
	If IsMissing(DocumentType) Or IsEmpty(DocumentType) Then DocumentType = &quot;&quot;
	If IsMissing(TemplateFile) Or IsEmpty(TemplateFile) Then TemplateFile = &quot;&quot;
	If IsMissing(Hidden) Or IsEmpty(Hidden) Then Hidden = False

	If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
		If Not SF_Utils._Validate(DocumentType, &quot;DocumentType&quot;, V_STRING _
				, Array(&quot;&quot;, BASEDOCUMENT, CALCDOCUMENT, DRAWDOCUMENT _
				, IMPRESSDOCUMENT, MATHDOCUMENT, WRITERDOCUMENT)) Then GoTo Finally
		If Not SF_Utils._ValidateFile(TemplateFile, &quot;TemplateFile&quot;, , True) Then GoTo Finally
		If Not SF_Utils._Validate(Hidden, &quot;Hidden&quot;, V_BOOLEAN) Then GoTo Finally
	End If

	If Len(DocumentType) + Len(TemplateFile) = 0 Then GoTo CatchError
	If Len(TemplateFile) &gt; 0 Then bTemplateExists = SF_FileSystem.FileExists(TemplateFile) Else bTemplateExists = False
	If Len(DocumentType) = 0 Then
		If Not bTemplateExists Then GoTo CatchError
	End If

Try:
	If bTemplateExists Then sNew = SF_FileSystem._ConvertToUrl(TemplateFile) Else sNew = cstDocType &amp; LCase(DocumentType)
	vProperties = Array( _
					SF_Utils._MakePropertyValue(&quot;AsTemplate&quot;, bTemplateExists) _
					, SF_Utils._MakePropertyValue(&quot;Hidden&quot;, Hidden) _
					)
	Set oComp = StarDesktop.loadComponentFromURL(sNew, &quot;_blank&quot;, 0, vProperties)
	If Not IsNull(oComp) Then Set oCreate = CreateScriptService(&quot;SFDocuments.Document&quot;, oComp)

Finally:
	Set CreateDocument = oCreate
	SF_Utils._ExitFunction(cstThisSub)
	Exit Function
Catch:
	GoTo Finally
CatchError:
	SF_Exception.RaiseFatal(DOCUMENTCREATIONERROR, &quot;DocumentType&quot;, DocumentType, &quot;TemplateFile&quot;, TemplateFile)
	GoTo Finally
End Function    &apos;   ScriptForge.SF_UI.CreateDocument

REM -----------------------------------------------------------------------------
Public Function Documents() As Variant
&apos;&apos;&apos; Returns the list of the currently open documents. Special windows are ignored.
&apos;&apos;&apos;	Returns:
&apos;&apos;&apos;		A zero-based 1D array of filenames (in SF_FileSystem.FileNaming notation)
&apos;&apos;&apos;		or of window titles for unsaved documents
&apos;&apos;&apos;	Examples:
&apos;&apos;&apos;		Dim vDocs As Variant, sDoc As String
&apos;&apos;&apos;			vDocs = ui.Documents()
&apos;&apos;&apos;			For each sDoc In vDocs
&apos;&apos;&apos;				...

Dim vDocuments As Variant			&apos;	Return value
Dim oEnum As Object					&apos;	com.sun.star.container.XEnumeration
Dim oComp As Object					&apos;	com.sun.star.lang.XComponent
Dim vWindow As Window				&apos;	A single component
Const cstThisSub = &quot;UI.Documents&quot;
Const cstSubArgs = &quot;&quot;

	If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
	vDocuments = Array()

Check:
	SF_Utils._EnterFunction(cstThisSub, cstSubArgs)

Try:
	Set oEnum = StarDesktop.Components().createEnumeration
	Do While oEnum.hasMoreElements
		Set oComp = oEnum.nextElement
		vWindow = SF_UI._IdentifyWindow(oComp)
		With vWindow
			If Len(.WindowFileName) &gt; 0 Then
				vDocuments = SF_Array.Append(vDocuments, SF_FileSystem._ConvertFromUrl(.WindowFileName))
			ElseIf Len(.WindowTitle) &gt; 0 Then
				vDocuments = SF_Array.Append(vDocuments, .WindowTitle)
			End If	
		End With
	Loop

Finally:
	Documents = vDocuments
	SF_Utils._ExitFunction(cstThisSub)
	Exit Function
Catch:
	GoTo Finally
End Function    &apos;   ScriptForge.SF_UI.Documents

REM -----------------------------------------------------------------------------
Public Function GetDocument(Optional ByVal WindowName As Variant) As Variant
&apos;&apos;&apos; Returns a SFDocuments.Document object referring to the active window or the given window
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		WindowName:	when a string, see definitions. If absent the active window is considered.
&apos;&apos;&apos;					when an object, must be a UNO object of types
&apos;&apos;&apos;					   com.sun.star.lang.XComponent or com.sun.star.comp.dba.ODatabaseDocument
&apos;&apos;&apos;	Exceptions:
&apos;&apos;&apos;		DOCUMENTERROR		The targeted window could not be found
&apos;&apos;&apos;	Examples:
&apos;&apos;&apos;		Dim oDoc As Object
&apos;&apos;&apos;			Set oDoc = ui.GetDocument	&apos;	or Set oDoc = ui.GetDocument(ThisComponent)
&apos;&apos;&apos;			oDoc.Save()

Dim oDocument As Object			&apos;	Return value
Const cstThisSub = &quot;UI.GetDocument&quot;
Const cstSubArgs = &quot;[WindowName]&quot;

	If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
	Set oDocument = Nothing

Check:
	If IsMissing(WindowName) Or IsEmpty(WindowName) Then WindowName = &quot;&quot;
	If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
		If Not SF_Utils._Validate(WindowName, &quot;WindowName&quot;, Array(V_STRING, V_OBJECT)) Then GoTo Finally
		If VarType(WindowName) = V_STRING Then
			If Not SF_Utils._ValidateFile(WindowName, &quot;WindowName&quot;, , True) Then GoTo Finally
		End If
	End If

Try:
	Set oDocument = SF_Services.CreateScriptService(&quot;SFDocuments.Document&quot;, WindowName)
	If IsNull(oDocument) Then GoTo CatchDeliver

Finally:
	Set GetDocument = oDocument
	SF_Utils._ExitFunction(cstThisSub)
	Exit Function
Catch:
	GoTo Finally
CatchDeliver:
	SF_Exception.RaiseFatal(DOCUMENTERROR, &quot;WindowName&quot;, WindowName)
	GoTo Finally
End Function    &apos;   ScriptForge.SF_UI.GetDocument

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

Const cstThisSub = &quot;UI.GetProperty&quot;
Const cstSubArgs = &quot;PropertyName&quot;

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

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:
	Select Case UCase(PropertyName)
		Case &quot;ACTIVEWINDOW&quot;			:	GetProperty = ActiveWindow()
		Case &quot;HEIGHT&quot;				:	GetProperty = SF_UI.Height
		Case &quot;WIDTH&quot;				:	GetProperty = SF_UI.Width
		Case &quot;X&quot;					:	GetProperty = SF_UI.X
		Case &quot;Y&quot;					:	GetProperty = SF_UI.Y
		
		Case Else
	End Select

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

REM -----------------------------------------------------------------------------
Public Sub Maximize(Optional ByVal WindowName As Variant)
&apos;&apos;&apos; Maximizes the active window or the given window
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		WindowName: see definitions. If absent the active window is considered
&apos;&apos;&apos;	Examples:
&apos;&apos;&apos;		ui.Maximize
&apos;&apos;&apos;				...

Dim oEnum As Object					&apos;	com.sun.star.container.XEnumeration
Dim oComp As Object					&apos;	com.sun.star.lang.XComponent
Dim vWindow As Window				&apos;	A single component
Dim oContainer As Object			&apos;	com.sun.star.awt.XWindow
Dim bFound As Boolean				&apos;	True if window found
Const cstThisSub = &quot;UI.Maximize&quot;
Const cstSubArgs = &quot;[WindowName]&quot;

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

Check:
	If IsMissing(WindowName) Or IsEmpty(WindowName) Then WindowName = &quot;&quot;
	If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
			If Not SF_Utils._ValidateFile(WindowName, &quot;WindowName&quot;, , True) Then GoTo Finally
	End If

Try:
	bFound = False
	If Len(WindowName) &gt; 0 Then
		Set oEnum = StarDesktop.Components().createEnumeration
		Do While oEnum.hasMoreElements And Not bFound
			Set oComp = oEnum.nextElement
			vWindow = SF_UI._IdentifyWindow(oComp)
			With vWindow
				&apos;	Does the current window match the arguments ?
				If	(Len(.WindowFileName) &gt; 0 And .WindowFileName = SF_FileSystem.ConvertToUrl(WindowName)) _
					Or (Len(.WindowName) &gt; 0 And .WindowName = WindowName) _
					Or (Len(.WindowTitle) &gt; 0 And .WindowTitle = WindowName) Then bFound = True
			End With
		Loop
	Else
		vWindow = SF_UI._IdentifyWindow(StarDesktop.CurrentComponent)
		bFound = True
	End If

	If bFound Then
		Set oContainer = vWindow.Frame.ContainerWindow
		oContainer.IsMaximized = True
	End If

Finally:
	SF_Utils._ExitFunction(cstThisSub)
	Exit Sub
Catch:
	GoTo Finally
End Sub		    &apos;   ScriptForge.SF_UI.Maximize

REM -----------------------------------------------------------------------------
Public Sub Minimize(Optional ByVal WindowName As Variant)
&apos;&apos;&apos; Minimizes the current window or the given window
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		WindowName: see definitions. If absent the current window is considered
&apos;&apos;&apos;	Examples:
&apos;&apos;&apos;		ui.Minimize(&quot;myFile.ods&quot;)
&apos;&apos;&apos;				...

Dim oEnum As Object					&apos;	com.sun.star.container.XEnumeration
Dim oComp As Object					&apos;	com.sun.star.lang.XComponent
Dim vWindow As Window				&apos;	A single component
Dim oContainer As Object			&apos;	com.sun.star.awt.XWindow
Dim bFound As Boolean				&apos;	True if window found
Const cstThisSub = &quot;UI.Minimize&quot;
Const cstSubArgs = &quot;[WindowName]&quot;

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

Check:
	If IsMissing(WindowName) Or IsEmpty(WindowName) Then WindowName = &quot;&quot;
	If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
			If Not SF_Utils._ValidateFile(WindowName, &quot;WindowName&quot;, , True) Then GoTo Finally
	End If

Try:
	bFound = False
	If Len(WindowName) &gt; 0 Then
		Set oEnum = StarDesktop.Components().createEnumeration
		Do While oEnum.hasMoreElements And Not bFound
			Set oComp = oEnum.nextElement
			vWindow = SF_UI._IdentifyWindow(oComp)
			With vWindow
				&apos;	Does the current window match the arguments ?
				If	(Len(.WindowFileName) &gt; 0 And .WindowFileName = SF_FileSystem.ConvertToUrl(WindowName)) _
					Or (Len(.WindowName) &gt; 0 And .WindowName = WindowName) _
					Or (Len(.WindowTitle) &gt; 0 And .WindowTitle = WindowName) Then bFound = True
			End With
		Loop
	Else
		vWindow = SF_UI._IdentifyWindow(StarDesktop.CurrentComponent)
		bFound = True
	End If

	If bFound Then
		Set oContainer = vWindow.Frame.ContainerWindow
		oContainer.IsMinimized = True
	End If

Finally:
	SF_Utils._ExitFunction(cstThisSub)
	Exit Sub
Catch:
	GoTo Finally
End Sub		    &apos;   ScriptForge.SF_UI.Minimize

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

	Methods = Array(&quot;Activate&quot; _
					, &quot;CreateBaseDocument&quot; _
					, &quot;CreateDocument&quot; _
					, &quot;Documents&quot; _
					, &quot;GetDocument&quot; _
					, &quot;Maximize&quot; _
					, &quot;Minimize&quot; _
					, &quot;OpenBaseDocument&quot; _
					, &quot;OpenDocument&quot; _
					, &quot;Resize&quot; _
					, &quot;RunCommand&quot; _
					, &quot;SetStatusbar&quot; _
					, &quot;ShowProgressBar&quot; _
					, &quot;WindowExists&quot; _
					)

End Function	&apos;	ScriptForge.SF_UI.Methods

REM -----------------------------------------------------------------------------
Public Function OpenBaseDocument(Optional ByVal FileName As Variant _
									, Optional ByVal RegistrationName As Variant _
									, Optional ByVal MacroExecution As Variant _
									) As Object
&apos;&apos;&apos; Open an existing LibreOffice Base document and return a SFDocuments.Document object
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		FileName: Identifies the file to open. It must follow the SF_FileSystem.FileNaming notation
&apos;&apos;&apos;		RegistrationName: the name of a registered database
&apos;&apos;&apos;			It is ignored if FileName &lt;&gt; &quot;&quot;
&apos;&apos;&apos;		MacroExecution: one of the MACROEXECxxx constants
&apos;&apos;&apos;	Returns:
&apos;&apos;&apos;		A SFDocuments.SF_Base object
&apos;&apos;&apos;		Null if the opening failed, including when due to a user decision
&apos;&apos;&apos;	Exceptions:
&apos;&apos;&apos;		BASEDOCUMENTOPENERROR			Wrong arguments
&apos;&apos;&apos;	Examples:
&apos;&apos;&apos;		Dim mBasec As Object, FSO As Object
&apos;&apos;&apos;		Set myBase = ui.OpenBaseDocument(&quot;C:\Temp\myDB.odb&quot;, MacroExecution := ui.MACROEXECNEVER)

Dim oOpen As Variant				&apos;	Return value
Dim vProperties As Variant			&apos;	Array of com.sun.star.beans.PropertyValue
Dim oDBContext As Object			&apos;	com.sun.star.sdb.DatabaseContext
Dim oComp As Object					&apos;	Loaded component com.sun.star.lang.XComponent
Dim sFile As String					&apos;	Alias for FileName
Dim iMacro As Integer				&apos;	Alias for MacroExecution
Const cstThisSub = &quot;UI.OpenBaseDocument&quot;
Const cstSubArgs = &quot;[FileName=&quot;&quot;&quot;&quot;], [RegistrationName=&quot;&quot;&quot;&quot;], [MacroExecution=0|1|2]&quot;

	If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
	Set oOpen = Nothing

Check:
	If IsMissing(FileName) Or IsEmpty(FileName) Then FileName = &quot;&quot;
	If IsMissing(RegistrationName) Or IsEmpty(RegistrationName) Then RegistrationName = &quot;&quot;
	If IsMissing(MacroExecution) Or IsEmpty(MacroExecution) Then MacroExecution = MACROEXECNORMAL

	If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
		If Not SF_Utils._ValidateFile(FileName, &quot;FileName&quot;, , True) Then GoTo Finally
		If Not SF_Utils._Validate(RegistrationName, &quot;RegistrationName&quot;, V_STRING) Then GoTo Finally
		If Not SF_Utils._Validate(MacroExecution, &quot;MacroExecution&quot;, V_NUMERIC _
				, Array(MACROEXECNORMAL, MACROEXECNEVER, MACROEXECALWAYS)) Then GoTo Finally
	End If

	&apos;	Check the existence of FileName
	If Len(FileName) = 0 Then	&apos;	FileName has precedence over RegistrationName
		If Len(RegistrationName) = 0 Then GoTo CatchError
		Set oDBContext = SF_Utils._GetUNOService(&quot;DatabaseContext&quot;)
		If Not oDBContext.hasRegisteredDatabase(RegistrationName) Then GoTo CatchError
		FileName = SF_FileSystem._ConvertFromUrl(oDBContext.getDatabaseLocation(RegistrationName))
	End If	
	If Not SF_FileSystem.FileExists(FileName) Then GoTo CatchError

Try:
	With com.sun.star.document.MacroExecMode
		Select Case MacroExecution
			Case 0		: 	iMacro = .USE_CONFIG
			Case 1		:	iMacro = .NEVER_EXECUTE
			Case 2		:	iMacro = .ALWAYS_EXECUTE_NO_WARN
		End Select
	End With

	vProperties = Array(SF_Utils._MakePropertyValue(&quot;MacroExecutionMode&quot;, iMacro))

	sFile = SF_FileSystem._ConvertToUrl(FileName)
	Set oComp = StarDesktop.loadComponentFromURL(sFile, &quot;_blank&quot;, 0, vProperties)
	If Not IsNull(oComp) Then Set oOpen = CreateScriptService(&quot;SFDocuments.Document&quot;, oComp)

Finally:
	Set OpenBaseDocument = oOpen
	SF_Utils._ExitFunction(cstThisSub)
	Exit Function
Catch:
	GoTo Finally
CatchError:
	SF_Exception.RaiseFatal(BASEDOCUMENTOPENERROR, &quot;FileName&quot;, FileName, &quot;RegistrationName&quot;, RegistrationName)
	GoTo Finally
End Function    &apos;   ScriptForge.SF_UI.OpenBaseDocument

REM -----------------------------------------------------------------------------
Public Function OpenDocument(Optional ByVal FileName As Variant _
							, Optional ByVal Password As Variant _
							, Optional ByVal ReadOnly As Variant _
							, Optional ByVal Hidden As Variant _
							, Optional ByVal MacroExecution As Variant _
							, Optional ByVal FilterName As Variant _
							, Optional ByVal FilterOptions As Variant _
							) As Object
&apos;&apos;&apos; Open an existing LibreOffice document with the given options
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		FileName: Identifies the file to open. It must follow the SF_FileSystem.FileNaming notation
&apos;&apos;&apos;		Password: To use when the document is protected
&apos;&apos;&apos;			If wrong or absent while the document is protected, the user will be prompted to enter a password
&apos;&apos;&apos;		ReadOnly: Default = False
&apos;&apos;&apos;		Hidden: if True, open in the background (default = False)
&apos;&apos;&apos;			To use with caution: activation or closure can only happen programmatically
&apos;&apos;&apos;		MacroExecution: one of the MACROEXECxxx constants
&apos;&apos;&apos;		FilterName: the name of a filter that should be used for loading the document
&apos;&apos;&apos;			If present, the filter must exist
&apos;&apos;&apos;		FilterOptions: an optional string of options associated with the filter
&apos;&apos;&apos;	Returns:
&apos;&apos;&apos;		A SFDocuments.SF_Document object or one of its subclasses
&apos;&apos;&apos;		Null if the opening failed, including when due to a user decision
&apos;&apos;&apos;	Exceptions:
&apos;&apos;&apos;		DOCUMENTOPENERROR			Wrong arguments
&apos;&apos;&apos;	Examples:
&apos;&apos;&apos;		Dim myDoc As Object, FSO As Object
&apos;&apos;&apos;		Set myDoc = ui.OpenDocument(&quot;C:\Temp\myFile.odt&quot;, MacroExecution := ui.MACROEXECNEVER)

Dim oOpen As Variant				&apos;	Return value
Dim oFilterFactory As Object		&apos;	com.sun.star.document.FilterFactory
Dim vProperties As Variant			&apos;	Array of com.sun.star.beans.PropertyValue
Dim oComp As Object					&apos;	Loaded component com.sun.star.lang.XComponent
Dim sFile As String					&apos;	Alias for FileName
Dim iMacro As Integer				&apos;	Alias for MacroExecution
Const cstThisSub = &quot;UI.OpenDocument&quot;
Const cstSubArgs = &quot;FileName, [Password=&quot;&quot;&quot;&quot;], [ReadOnly=False], [Hidden=False], [MacroExecution=0|1|2], [FilterName=&quot;&quot;&quot;&quot;], [FilterOptions=&quot;&quot;&quot;&quot;]&quot;

	If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
	Set oOpen = Nothing

Check:
	If IsMissing(Password) Or IsEmpty(Password) Then Password = &quot;&quot;
	If IsMissing(ReadOnly) Or IsEmpty(ReadOnly) Then ReadOnly = False
	If IsMissing(Hidden) Or IsEmpty(Hidden) Then Hidden = False
	If IsMissing(MacroExecution) Or IsEmpty(MacroExecution) Then MacroExecution = MACROEXECNORMAL
	If IsMissing(FilterName) Or IsEmpty(FilterName) Then FilterName = &quot;&quot;
	If IsMissing(FilterOptions) Or IsEmpty(FilterOptions) Then FilterOptions = &quot;&quot;

	If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
		If Not SF_Utils._ValidateFile(FileName, &quot;FileName&quot;) Then GoTo Finally
		If Not SF_Utils._Validate(Password, &quot;Password&quot;, V_STRING) Then GoTo Finally
		If Not SF_Utils._Validate(ReadOnly, &quot;ReadOnly&quot;, V_BOOLEAN) Then GoTo Finally
		If Not SF_Utils._Validate(Hidden, &quot;Hidden&quot;, V_BOOLEAN) Then GoTo Finally
		If Not SF_Utils._Validate(MacroExecution, &quot;MacroExecution&quot;, V_NUMERIC _
				, Array(MACROEXECNORMAL, MACROEXECNEVER, MACROEXECALWAYS)) Then GoTo Finally
		If Not SF_Utils._Validate(FilterName, &quot;FilterName&quot;, V_STRING) Then GoTo Finally
		If Not SF_Utils._Validate(FilterOptions, &quot;FilterOptions&quot;, V_STRING) Then GoTo Finally
	End If

	&apos;	Check the existence of FileName and FilterName
	If Not SF_FileSystem.FileExists(FileName) Then GoTo CatchError
	If Len(FilterName) &gt; 0 Then
		Set oFilterFactory = SF_Utils._GetUNOService(&quot;FilterFactory&quot;)
		If Not oFilterFactory.hasByName(FilterName) Then GoTo CatchError
	End If

Try:
	With com.sun.star.document.MacroExecMode
		Select Case MacroExecution
			Case 0		: 	iMacro = .USE_CONFIG
			Case 1		:	iMacro = .NEVER_EXECUTE
			Case 2		:	iMacro = .ALWAYS_EXECUTE_NO_WARN
		End Select
	End With

	vProperties = Array( _
					SF_Utils._MakePropertyValue(&quot;ReadOnly&quot;, ReadOnly) _
					, SF_Utils._MakePropertyValue(&quot;Hidden&quot;, Hidden) _
					, SF_Utils._MakePropertyValue(&quot;MacroExecutionMode&quot;, iMacro) _
					, SF_Utils._MakePropertyValue(&quot;FilterName&quot;, FilterName) _
					, SF_Utils._MakePropertyValue(&quot;FilterOptions&quot;, FilterOptions) _
					)
	If Len(Password) &gt; 0 Then		&apos;	Password is to add only if &lt;&gt; &quot;&quot; !?
		vProperties = SF_Array.Append(vProperties, SF_Utils._MakePropertyValue(&quot;Password&quot;, Password))
	End If

	sFile = SF_FileSystem._ConvertToUrl(FileName)
	Set oComp = StarDesktop.loadComponentFromURL(sFile, &quot;_blank&quot;, 0, vProperties)
	If Not IsNull(oComp) Then Set oOpen = CreateScriptService(&quot;SFDocuments.Document&quot;, oComp)

Finally:
	Set OpenDocument = oOpen
	SF_Utils._ExitFunction(cstThisSub)
	Exit Function
Catch:
	GoTo Finally
CatchError:
	SF_Exception.RaiseFatal(DOCUMENTOPENERROR, &quot;FileName&quot;, FileName, &quot;Password&quot;, Password, &quot;FilterName&quot;, FilterName)
	GoTo Finally
End Function    &apos;   ScriptForge.SF_UI.OpenDocument

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

	Properties = Array( _
					&quot;ActiveWindow&quot; _
					, &quot;Height&quot; _
					, &quot;Width&quot; _
					, &quot;X&quot; _
					, &quot;Y&quot; _
					)

End Function	&apos;	ScriptForge.SF_UI.Properties

REM -----------------------------------------------------------------------------
Public Sub Resize(Optional ByVal Left As Variant _
					, Optional ByVal Top As Variant _
					, Optional ByVal Width As Variant _
					, Optional ByVal Height As Variant _
					)
&apos;&apos;&apos; Resizes and/or moves the active window. Negative arguments are ignored.
&apos;&apos;&apos;	If the window was minimized or without arguments, it is restored
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		Left, Top: Distances from top and left edges of the screen
&apos;&apos;&apos;		Width, Height: Dimensions of the window
&apos;&apos;&apos;	Examples:
&apos;&apos;&apos;		ui.Resize(10,,500)		&apos;	Top and Height are unchanged
&apos;&apos;&apos;				...

Dim vWindow As Window				&apos;	A single component
Dim oContainer As Object			&apos;	com.sun.star.awt.XWindow
Dim iPosSize As Integer				&apos;	Computes which of the 4 arguments should be considered
Const cstThisSub = &quot;UI.Resize&quot;
Const cstSubArgs = &quot;[Left], [Top], [Width], [Height]&quot;

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

Check:
	If IsMissing(Left) Or IsEmpty(Left) Then Left = -1
	If IsMissing(Top) Or IsEmpty(Top) Then Top = -1
	If IsMissing(Width) Or IsEmpty(Width) Then Width = -1
	If IsMissing(Height) Or IsEmpty(Height) Then Height = -1
	If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
		If Not SF_Utils._Validate(Left, &quot;Left&quot;, V_NUMERIC) Then GoTo Finally
		If Not SF_Utils._Validate(Top, &quot;Top&quot;, V_NUMERIC) Then GoTo Finally
		If Not SF_Utils._Validate(Width, &quot;Width&quot;, V_NUMERIC) Then GoTo Finally
		If Not SF_Utils._Validate(Height, &quot;Height&quot;, V_NUMERIC) Then GoTo Finally
	End If

Try:
	vWindow = SF_UI._IdentifyWindow(StarDesktop.CurrentComponent)
	If Not IsNull(vWindow.Frame) Then
		Set oContainer = vWindow.Frame.ContainerWindow
		iPosSize = 0
		If Left &gt;= 0		Then iPosSize = iPosSize + com.sun.star.awt.PosSize.X
		If Top &gt;= 0			Then iPosSize = iPosSize + com.sun.star.awt.PosSize.Y
		If Width &gt; 0		Then iPosSize = iPosSize + com.sun.star.awt.PosSize.WIDTH
		If Height &gt; 0		Then iPosSize = iPosSize + com.sun.star.awt.PosSize.HEIGHT
		With oContainer
			.IsMaximized = False
			.IsMinimized = False
			.setPosSize(Left, Top, Width, Height, iPosSize)
		End With
	End If

Finally:
	SF_Utils._ExitFunction(cstThisSub)
	Exit Sub
Catch:
	GoTo Finally
End Sub		    &apos;   ScriptForge.SF_UI.Resize

REM -----------------------------------------------------------------------------
Public Sub RunCommand(Optional ByVal Command As Variant _
									, ParamArray Args As Variant _
									)
&apos;&apos;&apos; Run on the current window the given menu command. The command is executed with or without arguments
&apos;&apos;&apos;	A few typical commands:
&apos;&apos;&apos;		About, Delete, Edit, Undo, Copy, Paste, ...
&apos;&apos;&apos;	Dozens can be found on next page: https://wiki.documentfoundation.org/Development/DispatchCommands
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		Command: Case-sensitive. The command itself is not checked.
&apos;&apos;&apos;			If the command does not contain the &quot;.uno:&quot; prefix, it is added.
&apos;&apos;&apos;			If nothing happens, then the command is probably wrong
&apos;&apos;&apos;		Args: Pairs of arguments name (string), value (any)	
&apos;&apos;&apos;	Returns:
&apos;&apos;&apos;	Examples:
&apos;&apos;&apos;		ui.RunCommand(&quot;BasicIDEAppear&quot;, _
&apos;&apos;&apos;					&quot;Document&quot;, &quot;LibreOffice Macros &amp; Dialogs&quot;, _
&apos;&apos;&apos;					&quot;LibName&quot;, &quot;ScriptForge&quot;, _
&apos;&apos;&apos;					&quot;Name&quot;, &quot;SF_Session&quot;, _
&apos;&apos;&apos;					&quot;Line&quot;, 600)

Dim oDispatch				&apos;	com.sun.star.frame.DispatchHelper
Dim vProps As Variant		&apos;	Array of PropertyValues
Dim vValue As Variant		&apos;	A single value argument
Dim sCommand As String		&apos;	Alias of Command
Dim i As Long
Const cstPrefix = &quot;.uno:&quot;

Const cstThisSub = &quot;UI.RunCommand&quot;
Const cstSubArgs = &quot;Command, [arg0Name, arg0Value], [arg1Name, arg1Value], ...&quot;

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

Check:
	If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
		If Not SF_Utils._Validate(Command, &quot;Command&quot;, V_STRING) Then GoTo Finally
		If Not SF_Utils._ValidateArray(Args, &quot;Args&quot;, 1) Then GoTo Finally
		For i = 0 To UBound(Args) - 1 Step 2
			If Not SF_Utils._Validate(Args(i), &quot;Arg&quot; &amp; CStr(i/2) &amp; &quot;Name&quot;, V_STRING) Then GoTo Finally
		Next i
	End If

Try:
	&apos;	Build array of property values
	vProps = Array()
	For i = 0 To UBound(Args) - 1 Step 2
		If IsEmpty(Args(i + 1)) Then vValue = Null Else vValue = Args(i + 1)
		vProps = SF_Array.Append(vProps, SF_Utils._MakePropertyValue(Args(i), vValue))
	Next i
	Set oDispatch = SF_Utils._GetUNOService(&quot;DispatchHelper&quot;)
	If SF_String.StartsWith(Command, cstPrefix) Then sCommand = Command Else sCommand = cstPrefix &amp; Command
	oDispatch.executeDispatch(StarDesktop.ActiveFrame, sCommand, &quot;&quot;, 0, vProps)

Finally:
	SF_Utils._ExitFunction(cstThisSub)
	Exit Sub
Catch:
	GoTo Finally
End Sub			&apos;	ScriptForge.SF_UI.RunCommand

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;UI.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:
	Select Case UCase(PropertyName)
		Case Else
	End Select

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

REM -----------------------------------------------------------------------------
Public Sub SetStatusbar(Optional ByVal Text As Variant _
					, Optional ByVal Percentage As Variant _
					)
&apos;&apos;&apos; Display a text and a progressbar in the status bar of the active window
&apos;&apos;&apos;	Any subsequent calls in the same macro run refer to the same status bar of the same window,
&apos;&apos;&apos;	even if the window is not active anymore
&apos;&apos;&apos;	A call without arguments resets the status bar to its normal state.
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		Text: the optional text to be displayed before the progress bar
&apos;&apos;&apos;		Percentage: the optional degree of progress between 0 and 100
&apos;&apos;&apos;	Examples:
&apos;&apos;&apos;		Dim i As Integer
&apos;&apos;&apos;			For i = 0 To 100
&apos;&apos;&apos;				ui.SetStatusbar(&quot;Progress ...&quot;, i)
&apos;&apos;&apos;				Wait 50
&apos;&apos;&apos;			Next i
&apos;&apos;&apos;			ui.SetStatusbar

Dim oComp As Object
Dim oControl As Object
Dim oStatusbar As Object
Const cstThisSub = &quot;UI.SetStatusbar&quot;
Const cstSubArgs = &quot;[Text], [Percentage]&quot;

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

Check:
	If IsMissing(Text) Or IsEmpty(Text) Then Text = &quot;&quot;
	If IsMissing(Percentage) Or IsEmpty(Percentage) Then Percentage = -1
	If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
		If Not SF_Utils._Validate(Text, &quot;Text&quot;, V_STRING) Then GoTo Finally
		If Not SF_Utils._Validate(Percentage, &quot;Percentage&quot;, V_NUMERIC) Then GoTo Finally
	End If

Try:
	Set oStatusbar = _SF_.Statusbar
	If IsNull(oStatusbar) Then		&apos;	Initial call
		Set oComp = StarDesktop.CurrentComponent
		If Not IsNull(oComp) Then
			Set oControl = Nothing
			If SF_Session.HasUnoProperty(oComp, &quot;CurrentController&quot;) Then Set oControl = oComp.CurrentController
			If Not IsNull(oControl) Then
				If SF_Session.HasUnoMethod(oControl, &quot;getStatusIndicator&quot;) Then oStatusbar = oControl.getStatusIndicator()
			End If
		End If
		If Not IsNull(oStatusbar) Then oStatusBar.start(&quot;&quot;, 100)
	End If
	If Not IsNull(oStatusbar) Then
		With oStatusbar
			If Len(Text) = 0 And Percentage = -1 Then
				.end()
				Set oStatusbar = Nothing
			Else
				If Len(Text) &gt; 0 Then .setText(Text)
				If Percentage &gt;= 0 And Percentage &lt;= 100 Then .setValue(Percentage)
			End If
		End With
	End If

Finally:
	Set _SF_.Statusbar = oStatusbar
	SF_Utils._ExitFunction(cstThisSub)
	Exit Sub
Catch:
	GoTo Finally
End Sub		    &apos;   ScriptForge.SF_UI.SetStatusbar

REM -----------------------------------------------------------------------------
Public Sub ShowProgressBar(Optional Title As Variant _
					, Optional ByVal Text As Variant _
					, Optional ByVal Percentage As Variant _
					, Optional ByRef _Context As Variant _
					)
&apos;&apos;&apos; Display a non-modal dialog box. Specify its title, an explicatory text and the progress on a progressbar
&apos;&apos;&apos;	A call without arguments erases the progress bar dialog.
&apos;&apos;&apos;	The box will anyway vanish at the end of the macro run.
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		Title: the title appearing on top of the dialog box (Default = &quot;ScriptForge&quot;)
&apos;&apos;&apos;		Text: the optional text to be displayed above the progress bar (default = zero-length string)
&apos;&apos;&apos;		Percentage: the degree of progress between 0 and 100. Default = 0
&apos;&apos;&apos;		_Context: from Python, the XComponentXontext (FOR INTERNAL USE ONLY)
&apos;&apos;&apos;	Examples:
&apos;&apos;&apos;		Dim i As Integer
&apos;&apos;&apos;			For i = 0 To 100
&apos;&apos;&apos;				ui.ShowProgressBar(, &quot;Progress ... &quot; &amp; i &amp; &quot;/100&quot;, i)
&apos;&apos;&apos;				Wait 50
&apos;&apos;&apos;			Next i
&apos;&apos;&apos;			ui.ShowProgressBar

Dim bFirstCall As Boolean				&apos;	True at first invocation of method
Dim oDialog As Object					&apos;	SFDialogs.Dialog object
Dim oFixedText As Object				&apos;	SFDialogs.DialogControl object
Dim oProgressBar As Object				&apos;	SFDialogs.DialogControl object
Dim sTitle As String					&apos;	Alias of Title
Const cstThisSub = &quot;UI.ShowProgressBar&quot;
Const cstSubArgs = &quot;[Title], [Text], [Percentage]&quot;

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

Check:
	If IsMissing(Title) Or IsEmpty(Title) Then Title = &quot;&quot;
	If IsMissing(Text) Or IsEmpty(Text) Then Text = &quot;&quot;
	If IsMissing(Percentage) Or IsEmpty(Percentage) Then Percentage = -1
	If IsMissing(_Context) Or IsEmpty(_Context) Then _Context = Nothing
	If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
		If Not SF_Utils._Validate(Title, &quot;Title&quot;, V_STRING) Then GoTo Finally
		If Not SF_Utils._Validate(Text, &quot;Text&quot;, V_STRING) Then GoTo Finally
		If Not SF_Utils._Validate(Percentage, &quot;Percentage&quot;, V_NUMERIC) Then GoTo Finally
	End If

Try:
	With _SF_
		Set oDialog = .ProgressBarDialog
		Set oFixedText = .ProgressBarText
		Set oProgressBar = .ProgressBarBar
	End With

	bFirstCall = ( IsNull(oDialog) )
	If Not bFirstCall Then bFirstCall = Not oDialog._IsStillAlive(False)	&apos;	False to not raise an error
	If bFirstCall Then Set oDialog = CreateScriptService(&quot;SFDialogs.Dialog&quot;, &quot;GlobalScope&quot;, &quot;ScriptForge&quot;, &quot;dlgProgress&quot;, _Context)
	With oDialog
		If Not IsNull(oDialog) Then
			If Len(Title) = 0 And Len(Text) = 0 And Percentage = -1 Then
				.Terminate()
				Set oDialog = Nothing
			Else
				.Caption = Iif(Len(Title) &gt; 0, Title, &quot;ScriptForge&quot;)
				If bFirstCall Then
					Set oFixedText = .Controls(&quot;ProgressText&quot;)
					Set oProgressBar = .Controls(&quot;ProgressBar&quot;)
					.Execute(Modal := False)
				End If
				If Len(Text) &gt; 0 Then oFixedText.Caption = Text
				oProgressBar.Value = Iif(Percentage &gt;= 0 And Percentage &lt;= 100, Percentage, 0)
			End If
		End If
	End With

Finally:
	With _SF_
		Set .ProgressBarDialog = oDialog
		Set .ProgressBarText = oFixedText
		Set .ProgressBarBar = oProgressBar
	End With
	SF_Utils._ExitFunction(cstThisSub)
	Exit Sub
Catch:
	GoTo Finally
End Sub		    &apos;   ScriptForge.SF_UI.ShowProgressBar

REM -----------------------------------------------------------------------------
Public Function WindowExists(Optional ByVal WindowName As Variant) As Boolean
&apos;&apos;&apos; Returns True if the specified window exists
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		WindowName: see definitions
&apos;&apos;&apos;	Returns:
&apos;&apos;&apos;		True if the given window is found
&apos;&apos;&apos;	Examples:
&apos;&apos;&apos;		ui.WindowExists(&quot;C:\Me\My file.odt&quot;)

Dim bWindowExists As Boolean		&apos;	Return value
Dim oEnum As Object					&apos;	com.sun.star.container.XEnumeration
Dim oComp As Object					&apos;	com.sun.star.lang.XComponent
Dim vWindow As Window				&apos;	A single component
Dim oContainer As Object			&apos;	com.sun.star.awt.XWindow
Const cstThisSub = &quot;UI.WindowExists&quot;
Const cstSubArgs = &quot;WindowName&quot;

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

Check:
	If IsMissing(WindowName) Or IsEmpty(WindowName) Then WindowName = &quot;&quot;
	If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
		If Not SF_Utils._ValidateFile(WindowName, &quot;WindowName&quot;) Then GoTo Finally
	End If

Try:
	Set oEnum = StarDesktop.Components().createEnumeration
	Do While oEnum.hasMoreElements
		Set oComp = oEnum.nextElement
		vWindow = SF_UI._IdentifyWindow(oComp)
		With vWindow
			&apos;	Does the current window match the arguments ?
			If	(Len(.WindowFileName) &gt; 0 And .WindowFileName = SF_FileSystem.ConvertToUrl(WindowName)) _
				Or (Len(.WindowName) &gt; 0 And .WindowName = WindowName) _
				Or (Len(.WindowTitle) &gt; 0 And .WindowTitle = WindowName) Then
					bWindowExists = True
					Exit Do
			End If
		End With
	Loop

Finally:
	WindowExists = bWindowExists
	SF_Utils._ExitFunction(cstThisSub)
	Exit Function
Catch:
	GoTo Finally
End Function    &apos;   ScriptForge.SF_UI.WindowExists

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

REM -----------------------------------------------------------------------------
Public Sub _CloseProgressBar(Optional ByRef poEvent As Object)
&apos;&apos;&apos;	Triggered by the Close button in the dlgProgress dialog
&apos;&apos;&apos;	to simply close the dialog

	ShowProgressBar()	&apos;	Without arguments =&gt; close the dialog

End Sub			&apos;	ScriptForge.SF_UI._CloseProgressBar

REM -----------------------------------------------------------------------------
Function _GetConfigurationManager(ByRef poComponent) As String
&apos;&apos;&apos;	Derives the argument to be passed to a configuration manager
&apos;&apos;&apos;	(managing the user interface elements like menus, toolbars, ...)
&apos;&apos;&apos;	from the nature of the component
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		poComponent: any component in desktop, typically a document but not only

Dim sConfigurationManager As String			&apos;	Return value
Dim oWindow As Object						&apos;	Window type

Check:
&apos;	On Local Error GoTo Catch
	If IsNull(poComponent) Then GoTo Catch

Try:
	Set oWindow = _IdentifyWindow(poComponent)

	&apos;		Derive the name of the UI configuration manager from the component type
	With oWindow
		Select Case .WindowName
			Case BASICIDE		:	sConfigurationManager = &quot;com.sun.star.script.BasicIDE&quot;
			Case WELCOMESCREEN	:	sConfigurationManager = &quot;com.sun.star.frame.StartModule&quot;
			Case Else
				Select Case .DocumentType
					Case BASEDOCUMENT		:	sConfigurationManager = &quot;com.sun.star.sdb.OfficeDatabaseDocument&quot;
					Case CALCDOCUMENT		:	sConfigurationManager = &quot;com.sun.star.sheet.SpreadsheetDocument&quot;
					Case DRAWDOCUMENT		:	sConfigurationManager = &quot;com.sun.star.drawing.DrawingDocument&quot;
					Case FORMDOCUMENT		:	sConfigurationManager = &quot;com.sun.star.sdb.FormDesign&quot;
					Case IMPRESSDOCUMENT	:	sConfigurationManager = &quot;com.sun.star.presentation.PresentationDocument&quot;
					Case MATHDOCUMENT		:	sConfigurationManager = &quot;com.sun.star.formula.FormulaProperties&quot;
					Case WRITERDOCUMENT		:	sConfigurationManager = &quot;com.sun.star.text.TextDocument&quot;
					Case TABLEDATA, QUERYDATA, SQLDATA
												sConfigurationManager = &quot;com.sun.star.sdb.DataSourceBrowser&quot;
					Case Else				:	sConfigurationManager = &quot;&quot;
				End Select
		End Select
	End With

Finally:
	_GetConfigurationManager = sConfigurationManager
	Exit Function
Catch:
	On Local Error GoTo 0
	GoTo Finally
End Function		&apos;	ScriptForge.SF_UI._GetConfigurationManager

REM -----------------------------------------------------------------------------
Public Function _IdentifyWindow(ByRef poComponent As Object) As Object
&apos;&apos;&apos;	Return a Window object (definition on top of module) based on component given as argument
&apos;&apos;&apos;	Is a shortcut to explore the most relevant properties or objects bound to a UNO component

Dim oWindow As Window				&apos;	Return value
Dim sImplementation As String		&apos;	Component&apos;s implementationname
Dim sIdentifier As String			&apos;	Component&apos;s identifier
Dim vSelection As Variant			&apos;	Array of poCOmponent.Selection property values
Dim iCommandType As Integer			&apos;	Datasheet type
Dim FSO As Object					&apos;	Alias for SF_FileSystem

	If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
	Set _IdentifyWindow = Nothing
	sImplementation = &quot;&quot;	:	sIdentifier = &quot;&quot;

	Set FSO = SF_FileSystem
	With oWindow
		Set .Frame = Nothing
		Set .Component = Nothing
		.WindowName = &quot;&quot;
		.WindowTitle = &quot;&quot;
		.WindowFileName = &quot;&quot;
		.DocumentType = &quot;&quot;
		.ParentName = &quot;&quot;
		If IsNull(poComponent) Then GoTo Finally
		If SF_Session.HasUnoProperty(poComponent, &quot;ImplementationName&quot;) Then sImplementation = poComponent.ImplementationName
		If SF_Session.HasUnoProperty(poComponent, &quot;Identifier&quot;) Then sIdentifier = poComponent.Identifier
		Set .Component = poComponent
		Select Case sImplementation
			Case &quot;com.sun.star.comp.basic.BasicIDE&quot;
				.WindowName = BASICIDE
			Case &quot;com.sun.star.comp.dba.ODatabaseDocument&quot;	&apos;	No identifier
				.WindowFileName = SF_Utils._GetPropertyValue(poComponent.Args, &quot;URL&quot;)
				If Len(.WindowFileName) &gt; 0 Then .WindowName = FSO.GetName(FSO._ConvertFromUrl(.WindowFileName))
				.DocumentType = BASEDOCUMENT
			Case &quot;org.openoffice.comp.dbu.ODatasourceBrowser&quot;		&apos;	Base datasheet (table, query or sql) in read mode
				Set .Frame = poComponent.Frame
				If Not IsEmpty(poComponent.Selection) Then		&apos;	Empty for (F4) DatasourceBrowser !!
					vSelection = poComponent.Selection
					.WindowName = SF_Utils._GetPropertyValue(vSelection, &quot;Command&quot;)
					iCommandType = SF_Utils._GetPropertyValue(vSelection, &quot;CommandType&quot;)
					Select Case iCommandType
						Case com.sun.star.sdb.CommandType.TABLE		:	.DocumentType = TABLEDATA
						Case com.sun.star.sdb.CommandType.QUERY		:	.DocumentType = QUERYDATA
						Case com.sun.star.sdb.CommandType.COMMAND	:	.DocumentType = SQLDATA
					End Select
					.ParentName = SF_Utils._GetPropertyValue(vSelection, &quot;DataSourceName&quot;)
					.WindowTitle = .WindowName
				End If
			Case &quot;org.openoffice.comp.dbu.OTableDesign&quot;, &quot;org.openoffice.comp.dbu.OQueryDesign&quot;			&apos;	Table or Query in Edit mode
			Case &quot;org.openoffice.comp.dbu.ORelationDesign&quot;
			Case &quot;com.sun.star.comp.sfx2.BackingComp&quot;				&apos;		Welcome screen
				Set .Frame = poComponent.Frame
				.WindowName = WELCOMESCREEN
			Case Else
				If Len(sIdentifier) &gt; 0 Then
						&apos;	Do not use URL : it contains the TemplateFile when new documents are created from a template
					.WindowFileName = poComponent.Location
					If Len(.WindowFileName) &gt; 0 Then .WindowName = FSO.GetName(FSO._ConvertFromUrl(.WindowFileName))
					If SF_Session.HasUnoProperty(poComponent, &quot;Title&quot;) Then .WindowTitle = poComponent.Title
					Select Case sIdentifier
						Case &quot;com.sun.star.sdb.FormDesign&quot;							&apos;	Form
							.DocumentType = FORMDOCUMENT
						Case &quot;com.sun.star.sdb.TextReportDesign&quot;					&apos;	Report
						Case &quot;com.sun.star.text.TextDocument&quot;						&apos;	Writer
							.DocumentType = WRITERDOCUMENT
						Case &quot;com.sun.star.sheet.SpreadsheetDocument&quot;				&apos;	Calc
							.DocumentType = CALCDOCUMENT
						Case &quot;com.sun.star.presentation.PresentationDocument&quot;		&apos;	Impress
							.DocumentType = IMPRESSDOCUMENT
						Case &quot;com.sun.star.drawing.DrawingDocument&quot;					&apos;	Draw
							.DocumentType = DRAWDOCUMENT
						Case &quot;com.sun.star.formula.FormulaProperties&quot;				&apos;	Math
							.DocumentType = MATHDOCUMENT
						Case Else
					End Select
				End If
		End Select
		If IsNull(.Frame) Then 
			If Not IsNull(poComponent.CurrentController) Then Set .Frame = poComponent.CurrentController.Frame
		End If
	End With
	
Finally:
	Set _IdentifyWindow = oWindow
	Exit Function
Catch:
	GoTo Finally
End Function		&apos;	ScriptForge.SF_UI._IdentifyWindow

REM -----------------------------------------------------------------------------
Public Function _ListToolbars(ByRef poComponent As Object) As Object
&apos;&apos;&apos;	Returns a SF_Dictionary object containing a list of all available
&apos;&apos;&apos;	toolbars in the given component
&apos;&apos;&apos;	A toolbar may be located:
&apos;&apos;&apos;		- builtin in the LibreOffice configuration, but dependent on the component type
&apos;&apos;&apos;		- added by the user and stored in the LibreOffice configuration of the user
&apos;&apos;&apos;		- added by the user and stored in the component/document itself
&apos;&apos;&apos;	The output dictionary has as
&apos;&apos;&apos;		key: the UIName of the toolbar when not blank, otherwise the last component of its ResourceURL
&apos;&apos;&apos;		item: a _Toolbar object (see top of module)
&apos;&apos;&apos;	Menubar, statusbar and popup menus are ignored.
&apos;&apos;&apos;	Args:
&apos;&apos;&apos;		poComponent: any component in desktop, typically a document but not only

Dim oToolbarsDict As Object					&apos;	Return value
Dim oConfigMgr As Object					&apos;	com.sun.star.ui.ModuleUIConfigurationManagerSupplier
Dim sConfigurationManager As String			&apos;	Derived from the component&apos;s type
Dim oUIConfigMgr As Object					&apos;	com.sun.star.comp.framework.ModuleUIConfigurationManager
Dim vCommandBars As Variant					&apos;	Array of  bars in component
Dim vCommandBar As Variant					&apos;	Array of PropertyValue about a single bar
Dim oToolbar As Object						&apos;	Toolbar description as a _Toolbar object
Dim sResourceURL As String					&apos;	Toolbar internal name as &quot;private:resource/toolbar/...&quot;
Dim sUIName As String						&apos;	Toolbar external name, may be zero-length string
Dim sBarName As String						&apos;	External bar name: either UIName or last component of resource URL
Dim i As Long

Const cstCUSTOM = &quot;custom_&quot;

Check:
&apos;	On Local Error GoTo Catch
	If IsNull(poComponent) Then GoTo Catch

Try:
	Set oToolbarsDict = CreateScriptService(&quot;Dictionary&quot;, True)	&apos;	with case-sensitive comparison of keys

	&apos;	1. Collect all builtin and custom toolbars stored in the LibreOffice configuration files

	&apos;		Derive the name of the UI configuration manager from the component type
	sConfigurationManager = _GetConfigurationManager(poComponent)

	Set oConfigMgr = SF_Utils._GetUNOService(&quot;ModuleUIConfigurationManagerSupplier&quot;)
	Set oUIConfigMgr = oConfigMgr.getUIConfigurationManager(sConfigurationManager)
	vCommandBars = oUIConfigMgr.getUIElementsInfo(com.sun.star.ui.UIElementType.TOOLBAR)

	&apos;		Ignore statusbar, menubar and popup menus. Store toolbars in dictionary
	For i = 0 To UBound(vCommandBars)
		vCommandBar = vCommandBars(i)
		sResourceURL = SF_Utils._GetPropertyValue(vCommandBar, &quot;ResourceURL&quot;)
		sUIName = SF_Utils._GetPropertyValue(vCommandBar, &quot;UIName&quot;)
		If Len(sUIName) &gt; 0 Then sBarName = sUIName Else sBarName = Split(sResourceURL, &quot;/&quot;)(2)
		&apos;	Store a new entry in the returned dictionary
		If Not oToolbarsDict.Exists(sBarName) Then
			Set oToolbar = New _Toolbar
			With oToolbar
				Set .Component = poComponent
				.ResourceURL = sResourceURL
				.UIName = sUIName
				Set .UIConfigurationManager = oUIConfigMgr
				.ElementsInfoIndex = i
				&apos;	Distinguish builtin and custom toolbars stored in the application
				If SF_String.StartsWith(sBarName, cstCUSTOM, CaseSensitive := True) Then
					.Storage = cstCUSTOMTOOLBAR
					sBarName = Mid(sBarName, Len(cstCUSTOM) + 1)
				Else
					.Storage = cstBUILTINTOOLBAR
				End If
			End With
			oToolbarsDict.Add(sBarName, oToolbar)
		End If
	Next i

	&apos;	2. Collect all toolbars stored in the current component/document

	&apos;	Some components (e.g. datasheets) cannot contain own toolbars
	If SF_Session.HasUnoMethod(poComponent, &quot;getUIConfigurationManager&quot;) Then
		Set oUIConfigMgr = poComponent.getUIConfigurationManager
		vCommandBars = oUIConfigMgr.getUIElementsInfo(com.sun.star.ui.UIElementType.TOOLBAR)
		For i = 0 To UBound(vCommandBars)
			vCommandBar = vCommandBars(i)
			sResourceURL = SF_Utils._GetPropertyValue(vCommandBar, &quot;ResourceURL&quot;)
			sUIName = SF_Utils._GetPropertyValue(vCommandBar, &quot;UIName&quot;)
			If Len(sUIName) &gt; 0 Then sBarName = sUIName Else sBarName = Split(sResourceURL, &quot;/&quot;)(2)
			&apos;	Store a new entry in the returned dictionary
			If Not oToolbarsDict.Exists(sBarName) Then
				Set oToolbar = New _Toolbar
				With oToolbar
					Set .Component = poComponent
					.ResourceURL = sResourceURL
					.UIName = sUIName
					Set .UIConfigurationManager = oUIConfigMgr
					.ElementsInfoIndex = i
					.Storage = cstCUSTOMDOCTOOLBAR
				End With
				oToolbarsDict.Add(sBarName, oToolbar)
			End If
		Next i
	End If

Finally:
	Set _ListToolbars = oToolbarsDict
	Exit Function
Catch:
	Set oToolbarsDict = Nothing
	GoTo Finally
End Function		&apos;	ScriptForge.SF_UI._ListToolbars

REM -----------------------------------------------------------------------------
Public Function _PosSize() As Object
&apos;&apos;&apos;	Returns the PosSize structure of the active window

Dim vWindow As Window				&apos;	A single component
Dim oContainer As Object			&apos;	com.sun.star.awt.XWindow
Dim oPosSize As Object				&apos;	com.sun.star.awt.Rectangle

	Set oPosSize = Nothing

Try:
	vWindow = SF_UI._IdentifyWindow(StarDesktop.CurrentComponent)
	If Not IsNull(vWindow.Frame) Then
		Set oContainer = vWindow.Frame.ContainerWindow
		Set oPosSize = oContainer.getPosSize()
	End If

Finally:
	Set _PosSize = oPosSize
	Exit Function
End Function	&apos;	ScriptForge.SF_UI._PosSize

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

	_Repr = &quot;[UI]&quot;

End Function	&apos;	ScriptForge.SF_UI._Repr

REM ============================================ END OF SCRIPTFORGE.SF_UI
</script:module>