Files
Jean-Pierre Ledure 1b3d801b14 ScriptForge ui.EnterValue() enhance password input
Addition of a button that makes the
password field readable and back.

A "password" input field is set by the
  EchoChar
property in the field model.
It cannot be changed dynamically during
the dialog's life.

To circumvene this limitation, a new readable
'= EchoChar = 0) usual text field is added
with the same dimensions and position
as the password field.
Only 1 of them is visible at the same time.

The button implements
- a swap between readable and non-readable fields
- a copy of the actual content of the last used field
- the repositioning of the caret
This maximizes the illusion of the use
of a single field while, in fact, 2 alternate
fields are used.

No effect on existing user scripts.
The functionality is valid for both Basic and
Python user scripts.

Change-Id: I8e84b2b0a8e25087f203a2efa58ff208526e2591
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/211228
Reviewed-by: Jean-Pierre Ledure <jp@ledure.be>
Tested-by: Jenkins
2026-09-20 09:27:03 +02:00

1928 lines
86 KiB
XML

<?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
&apos; Password management
Const cstPASSWORD = &quot;*&quot;
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
Else
ActiveWindow = &quot;&quot;
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
Dim bMaximized As Boolean &apos; True when window is maximized
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)
bMaximized = .IsMaximized
.IsMinimized = False
.setFocus()
.toFront() &apos; Force window change in Linux
If bMaximized Then .IsMaximized = True &apos; Re-maximized only when True
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 EnterValue(Optional ByRef Prompt As Variant _
, Optional ByVal ValueType As Variant _
, Optional ByVal Default As Variant _
, Optional ByVal Title As Variant _
, Optional ByRef Choices As Variant _
, Optional ByVal Format As Variant _
) As Variant
&apos;&apos;&apos; Displays a typed input box and returns the value entered by the user
&apos;&apos;&apos; Args: Irrelevant arguments are ignored
&apos;&apos;&apos; Prompt: the message appearing above the input field. Default = the zero-length string
&apos;&apos;&apos; Use of \n and \t escape characters is allowed.
&apos;&apos;&apos; ValueType: one of next values:
&apos;&apos;&apos; BOOL: to display a checkbox
&apos;&apos;&apos; STRING: (default) the dialog will look like an InputBox
&apos;&apos;&apos; PASSWORD: idem STRING but the input string is not readable
&apos;&apos;&apos; LIST, COMBO, RADIO: to display a list- of alternative potential choices
&apos;&apos;&apos; INTEGER, FLOAT: to get a numeric value
&apos;&apos;&apos; DATE, TIME, DATETIME: to let the user choose a date, an hour or both
&apos;&apos;&apos; Default: the value displayed at box appearance and having the expected type.
&apos;&apos;&apos; Title: the text appearing at the top of the box
&apos;&apos;&apos; Choices: the list of possible values (LIST, COMBO and RADIO only), as an array/tuple
&apos;&apos;&apos; Format: the format in which to display dates, times or numeric values
&apos;&apos;&apos; Depends on the platform.FormatLocale
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; A scalar of the given type, as entered by the user.
&apos;&apos;&apos; Returns Empty when the user cancelled the input box.
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; bool = ui.EnterValue(&quot;Do you prefer to leave ?&quot;, &quot;BOOL&quot;, True)
&apos;&apos;&apos; destination = ui.EnterValue(&quot;What is your next destination ?&quot;, &quot;LIST&quot;, _
&apos;&apos;&apos; Choices := Array(&quot;Belgium, &quot;Brazil&quot;, &quot;France&quot;, &quot;Mexico&quot;), _
&apos;&apos;&apos; Default := &quot;France&quot;, _
&apos;&apos;&apos; Title := &quot;This is in the titlebar&quot;)
Dim vEnterValue As Variant &apos; Return value
Dim oDialog As Object &apos; A SFDialogs.SF_Dialog class instance
Dim oControl As Object &apos; The input field as a SFDialogs.SF_DialogControl class instance
Dim oPasswordButton As Object &apos; The password button as a SFDialogs.SF_DialogControl class instance
Dim oPasswordField As Object &apos; The readable password as a SFDialogs.SF_DialogControl class instance
Dim oTime As Object &apos; An alternative SFDialogs.SF_DialogControl class instance to represent a TimeField
Dim oButton As Object &apos; A button SFDialogs.SF_DialogControl class instance
Dim iExecute As Integer &apos; dialog.Execute() return value
Dim vPrompt As Variant &apos; Array of prompt rows
Dim sPrompt As String &apos; A single prompt row
Dim lPromptHeight As Long &apos; Height of prompt (all lengths in MAP APPFONT units)
Dim lPromptWidth As Long &apos; Width of prompt
Dim lControlY As Long &apos; Vertical ordinate of control
Dim lControlHeight As Long &apos; Height of control
Dim lControlWidth As Long &apos; Width of control
Dim sItem As String &apos; A single item in Default()
Dim lItemLength As Long &apos; Length of an item in Default()
Dim lDialogWidth As Long &apos; Width of dialog
Dim lDialogHeight As Long &apos; Height of dialog
Dim oStr As Object : Set oStr = CreateScriptService(&quot;String&quot;)
Dim i As Long
Const LEFTMARGIN = 10 _
, TOPMARGIN = 10 _
, RIGHTMARGIN = 10 _
, BOTTOMMARGIN = 10
Const INTERVAL = 3
&apos; One Map AppFont unit is equal to one eighth of the average character (Systemfont) height and one quarter of the average character width.
Const TEXTHEIGHT = 8, TEXTWIDTH = 4, TEXTOFFSET = 2, MAXTEXTLENGTH = 70
Const MAXPASSWORDLENGTH = 30, PASSWORDWIDTH = 20
Const NUMERICWIDTH = 150, CHECKBOXWIDTH = 8, DATEWIDTH = 50, TIMEWIDTH = 50
Const TABSIZE = 4
Const LISTWIDTH = 20, MAXLISTCOUNT = 8
Const GROUPBOXMARGIN = 2
Const BUTTONWIDTH = 40, BUTTONHEIGHT = 10
Const cstThisSub = &quot;UI.EnterValue&quot;
Const cstSubArgs = &quot;Prompt, ValueType=&quot;&quot;BOOL&quot;&quot;|&quot;&quot;STRING&quot;&quot;|&quot;&quot;LIST&quot;&quot;|&quot;&quot;COMBO&quot;&quot;|&quot;&quot;RADIO&quot;&quot;&quot; _
&amp; &quot;|&quot;&quot;INTEGER&quot;&quot;|&quot;&quot;FLOAT&quot;&quot;|&quot;&quot;PASSWORD&quot;&quot;|&quot;&quot;DATE&quot;&quot;|&quot;&quot;TIME&quot;&quot;|&quot;&quot;DATETIME&quot;&quot;&quot; _
&amp; &quot;, [Default], [Title], [Choices], [Format]&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
vEnterValue = Empty
Check:
If IsMissing(Prompt) Or IsEmpty(Prompt) Then Prompt = &quot;&quot;
If IsMissing(ValueType) Or IsEmpty(ValueType) Then ValueType = &quot;STRING&quot;
If IsMissing(Default) Or IsEmpty(Default) Then Default = &quot;&quot;
If IsMissing(Choices) Or IsEmpty(Choices) Then Choices = Array()
If IsMissing(Title) Or IsEmpty(Title) Then Title = &quot;&quot;
If IsMissing(Format) Or IsEmpty(Format) Then Format = &quot;&quot;
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not SF_Utils._Validate(Prompt, &quot;Prompt&quot;, V_STRING) Then GoTo Finally
If Not SF_Utils._Validate(ValueType, &quot;ValueType&quot;, V_STRING, _
Split(&quot;BOOL,STRING,LIST,COMBO,RADIO,INTEGER,FLOAT,PASSWORD,DATE,TIME,DATETIME,&quot;, &quot;,&quot;) _
) Then GoTo Finally
If Len(ValueType) = 0 Then ValueType = &quot;STRING&quot;
If Not SF_Utils._Validate(Default, &quot;Default&quot;, Array(V_STRING, V_NUMERIC, V_DATE, V_BOOLEAN)) Then GoTo Finally
If Not SF_Utils._ValidateArray(Choices, &quot;Choices&quot;, 1, V_STRING, True) Then GoTo Finally
If Not SF_Utils._Validate(Title, &quot;Title&quot;, V_STRING) Then GoTo Finally
If Not SF_Utils._Validate(Format, &quot;Format&quot;, V_STRING) Then GoTo Finally
End If
Try:
lDialogWidth = 0
lDialogHeight = 0
&apos; Compute prompt size
vPrompt = oStr.Wrap(Prompt, MAXTEXTLENGTH, TabSize := TABSIZE)
lPromptWidth = 0
For Each sPrompt in vPrompt
If lPromptWidth &lt; Len(sPrompt) Then lPromptWidth = Len(sPrompt)
Next sPrompt
lPromptWidth = lPromptWidth * TEXTWIDTH
If lPromptWidth &gt; lDialogWidth Then lDialogWidth = lPromptWidth
lPromptHeight = ((UBound(vPrompt) + 1) * (TEXTHEIGHT + TEXTOFFSET))
&apos; Compute dialog control size
lControlHeight = TEXTHEIGHT
Select Case UCase(ValueType)
Case &quot;STRING&quot;&apos;, &quot;PASSWORD&quot;
lControlWidth = TEXTWIDTH * MAXTEXTLENGTH
Case &quot;PASSWORD&quot;
lControlWidth = TEXTWIDTH * MAXPASSWORDLENGTH + TEXTOFFSET + PASSWORDWIDTH
Case &quot;BOOL&quot;
lControlHeight = lPromptHeight
Case &quot;INTEGER&quot;, &quot;FLOAT&quot;
lControlWidth = NUMERICWIDTH
Case &quot;DATE&quot;
lControlWidth = DATEWIDTH
Case &quot;TIME&quot;
lControlWidth = TIMEWIDTH
Case &quot;DATETIME&quot;
lControlWidth = DATEWIDTH + TEXTOFFSET + TIMEWIDTH
Case &quot;COMBO&quot;, &quot;LIST&quot;, &quot;RADIO&quot;
lControlWidth = LISTWIDTH
lItemLength = 0
For Each sItem in Choices()
If Len(sItem) &gt; lItemLength Then lItemLength = Len(sItem)
Next sItem
lControlWidth = lControlWidth + lItemLength * TEXTWIDTH
If UCase(ValueType) = &quot;LIST&quot; Then
lControlHeight = ((TEXTHEIGHT + TEXTOFFSET) _
* Iif(UBound(Choices) &gt; MAXLISTCOUNT - 1, MAXLISTCOUNT, UBound(Choices) + 1)) _
- TEXTOFFSET
ElseIf UCase(ValueType) = &quot;RADIO&quot; Then
lControlHeight = (TEXTHEIGHT + TEXTOFFSET) * (UBound(Choices) + 1) - TEXTOFFSET
End If
End Select
If lControlWidth &gt; lDialogWidth Then lDialogWidth = lControlWidth
&apos; Setup of dialog
lDialogHeight = TOPMARGIN + Iif(UCase(ValueType) = &quot;BOOL&quot;, 0, lPromptHeight + INTERVAL) + lControlHeight
Set oDialog = CreateScriptService(&quot;SFDialogs.NewDialog&quot;, &quot;EnterValue&quot; _
, Array(0, 0, LEFTMARGIN + lDialogWidth + RIGHTMARGIN, TOPMARGIN + lDialogHeight + BUTTONHEIGHT + BOTTOMMARGIN) _
)
With oDialog
If Len(Title) &gt; 0 Then .Caption = Title
Select Case UCase(ValueType)
Case &quot;BOOL&quot;
&apos; Prompt is set at input control level
Case Else
Set oControl = .CreateFixedText(&quot;Prompt&quot; _
, Place := Array(LEFTMARGIN, TOPMARGIN, lPromptWidth, lPromptHeight) _
, MultiLine := ( UBound(vPrompt) &gt; 0 ) _
)
oControl.Caption = Join(vPrompt, &quot;&quot;)
End Select
End With
&apos; Setup of enabled control(s)
lControlY = TOPMARGIN + lPromptHeight + INTERVAL
Select Case UCase(ValueType)
Case &quot;STRING&quot;
Set oControl = oDialog.CreateTextField(&quot;InputField&quot; _
, Place := Array(LEFTMARGIN, lControlY, lControlWidth, TEXTHEIGHT) _
, MultiLine := False _
, PasswordCharacter := &quot;&quot;)
If VarType(Default) = V_STRING Then oControl.Value = Default
Case &quot;PASSWORD&quot;
Set oControl = oDialog.CreateTextField(&quot;InputField&quot; _
, Place := Array(LEFTMARGIN, lControlY, lControlWidth - TEXTOFFSET - PASSWORDWIDTH, TEXTHEIGHT) _
, MultiLine := False _
, PasswordCharacter := cstPASSWORD)
Set oPasswordField = oDialog.CreateTextField(&quot;HiddenField&quot; _
, Place := Array(LEFTMARGIN, lControlY, lControlWidth - TEXTOFFSET - PASSWORDWIDTH, TEXTHEIGHT) _
, MultiLine := False _
, PasswordCharacter := &quot;&quot;)
oPasswordField.Visible = False
Set oPasswordButton = oDialog.CreateButton(&quot;PasswordButton&quot; _
, Place := Array(oControl.X + oControl.Width + TEXTOFFSET, lControlY, PASSWORDWIDTH, BUTTONHEIGHT))
If VarType(Default) = V_STRING Then oControl.Value = Default
oPasswordButton.Caption = Chr(8644) &apos; ⇄ Unicode rightwards arrow over leftwards arrow
oPasswordButton.OnActionPerformed = &quot;vnd.sun.star.script:ScriptForge.SF_UI._RunPasswordButton?language=Basic&amp;location=application&quot;
Case &quot;INTEGER&quot;, &quot;FLOAT&quot;
Set oControl = oDialog.CreateFormattedField(&quot;InputField&quot; _
, Place := Array(LEFTMARGIN, lControlY, lControlWidth, TEXTHEIGHT) _
, SpinButton := ( UCase(ValueType) = &quot;INTEGER&quot; ))
If Len(Format) &gt; 0 Then oControl.Format = Format
If SF_Utils._VarTypeExt(Default) = V_NUMERIC Then oControl.Value = Default
Case &quot;BOOL&quot;
Set oControl = oDialog.CreateCheckBox(&quot;InputField&quot; _
, Place := Array(LEFTMARGIN, TOPMARGIN, lPROMPTWidth + CHECKBOXWIDTH, lPromptHeight) _
, MultiLine := ( UBound(vPrompt) &gt; 0 ) _
)
oControl.Caption = Join(vPrompt, &quot;&quot;)
oControl.TripleState = False
If VarType(Default) = V_BOOLEAN Then oControl.Value = Default
Case &quot;DATE&quot;
Set oControl = oDialog.CreateDateField(&quot;InputField&quot; _
, Place := Array(LEFTMARGIN, lControlY, lControlWidth, TEXTHEIGHT) _
, DropDown := True _
)
If VarType(Default) = V_DATE Then oControl.Value = Default
Case &quot;TIME&quot;
Set oControl = oDialog.CreateTimeField(&quot;InputField&quot; _
, Place := Array(LEFTMARGIN, lControlY, lControlWidth, TEXTHEIGHT) _
)
oControl.Format = &quot;24h long&quot; &apos; Include seconds
If VarType(Default) = V_DATE Then oControl.Value = Default
Case &quot;DATETIME&quot;
Set oControl = oDialog.CreateDateField(&quot;InputField&quot; _
, Place := Array(LEFTMARGIN, lControlY, DATEWIDTH, TEXTHEIGHT) _
, DropDown := True _
)
If VarType(Default) = V_DATE Then oControl.Value = DateSerial(Year(Default), Month(Default), Day(Default))
Set oTime = oDialog.CreateTimeField(&quot;TimeField&quot; _
, Place := Array(LEFTMARGIN + DATEWIDTH + TEXTOFFSET, lControlY, TIMEWIDTH, TEXTHEIGHT) _
)
oTime.Format = &quot;24h long&quot; &apos; Include seconds
If VarType(Default) = V_DATE Then oTime.Value = TimeSerial(Hour(Default), Minute(Default), Second(Default))
Case &quot;COMBO&quot;
Set oControl = oDialog.CreateComboBox(&quot;InputField&quot; _
, Place := Array(LEFTMARGIN, lControlY, lControlWidth, TEXTHEIGHT) _
, DropDown := True _
, LineCount := Iif(UBound(Choices) &gt; MAXLISTCOUNT - 1, MAXLISTCOUNT, UBound(Choices) + 1) _
)
oControl.RowSource = Choices
If Len(Default) &gt; 0 Then
oControl.Value = Default
ElseIf UBound(Choices) &gt;= 0 Then
oControl.Value = Choices(0)
End If
Case &quot;LIST&quot;
Set oControl = oDialog.CreateListBox(&quot;InputField&quot; _
, Place := Array(LEFTMARGIN, lControlY, lControlWidth, lControlHeight) _
, DropDown := False _
, LineCount := Iif(UBound(Choices) &gt; MAXLISTCOUNT - 1, MAXLISTCOUNT, UBound(Choices) + 1) _
, MultiSelect := False _
)
oControl.RowSource = Choices
If Len(Default) &gt; 0 Then
oControl.Value = Default
ElseIf UBound(Choices) &gt;= 0 Then
oControl.Value = Choices(0)
End If
Case &quot;RADIO&quot;
For i = 0 To UBound(Choices)
Set oControl = oDialog.CreateRadioButton(&quot;InputField&quot; &amp; Right(&quot;0&quot; &amp; i, 2) _
, Place := Array(LEFTMARGIN, lControlY + i * (TEXTHEIGHT + TEXTOFFSET), lControlWidth, TEXTHEIGHT) _
, MultiLine := False _
)
oControl.Caption = Choices(i)
If Len(Default) &gt; 0 Then oControl.Value = ( Default = Choices(i) ) Else oControl.Value = ( i = 0 )
Next i
oDialog.CreateGroupBox(&quot;GroupBox&quot; _
, Place := Array(LEFTMARGIN - GROUPBOXMARGIN, lControlY - GROUPBOXMARGIN _
, lControlWidth + (2 * GROUPBOXMARGIN), oControl.Y + TEXTHEIGHT + (2 * GROUPBOXMARGIN) - lControlY) _
)
Case Else
End Select
&apos; Define the Cancel and OK buttons
With oDialog
Set oButton = .CreateButton(&quot;CancelButton&quot; _
, Place := Array(.Width - RIGHTMARGIN - BUTTONWIDTH, .Height - BOTTOMMARGIN - BUTTONHEIGHT _
, BUTTONWIDTH, BUTTONHEIGHT) _
, Push := &quot;CANCEL&quot; _
)
Set oButton = .CreateButton(&quot;OKButton&quot; _
, Place := Array(oButton.X - BUTTONWIDTH - INTERVAL, oButton.Y, BUTTONWIDTH, BUTTONHEIGHT) _
, Push := &quot;OK&quot; _
)
oButton.Default = True
End With
&apos; Run the dialog
oControl.SetFocus()
oDialog.Center()
iExecute = oDialog.Execute(Modal := True)
If iExecute = oDialog.OKBUTTON Then
Select Case UCase(ValueType)
Case &quot;STRING&quot;, &quot;DATE&quot;, &quot;TIME&quot;, &quot;COMBO&quot;, &quot;LIST&quot;
vEnterValue = oControl.Value
Case &quot;PASSWORD&quot;
If oControl.Visible Then vEnterValue = oControl.Value Else vEnterValue = oPasswordField.Value
Case &quot;INTEGER&quot;
vEnterValue = CLng(oControl.Value)
Case &quot;FLOAT&quot;
vEnterValue = CDbl(oControl.Value)
Case &quot;BOOL&quot;
vEnterValue = CBool(oControl.Value)
Case &quot;DATETIME&quot;
vEnterValue = CDate(oControl.Value + oTime.Value)
Case &quot;RADIO&quot;
For i = 0 To UBound(Choices)
Set oControl = oDialog.Controls(&quot;InputField&quot; &amp; Right(&quot;0&quot; &amp; i, 2))
If oControl.Value = True Then
vEnterValue = Choices(i)
Exit For
End If
Next i
Case Else
End Select
End If
oControl.Dispose()
oDialog.Terminate()
Finally:
EnterValue = vEnterValue
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; ScriptForge.SF_UI.EnterValue
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 = Not IsNull(vWindow.Frame)
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 = Not IsNull(vWindow.Frame)
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;EnterValue&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
If Not IsNull (StarDesktop.ActiveFrame) Then 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 -----------------------------------------------------------------------------
Private Sub _RunPasswordButton(ByRef Optional poEvent As Object)
&apos;&apos;&apos; Activated by clicking on the password button defined in the EnterValue dialog box
&apos;&apos;&apos; Enable/Disable the echo character of the password control
&apos;&apos;&apos; Changing dynamically the EchoChar property in the model, view or peer has no effect,
&apos;&apos;&apos; hence - swap the readable and the not readable fields alternatively
&apos;&apos;&apos; - set the focus on the newly visible control
&apos;&apos;&apos; - put the caret at the current position
Dim oDialog As Object &apos; The EnterValue dialog as a SFDialogs.Dialog class instance
Dim oPasswordControl As Object &apos; The password control as a SFDialogs.DialogControl class instance
Dim oHiddenControl As Object &apos; The readable control as a SFDialogs.DialogControl class instance (initially hidden)
On Local Error GoTo Finally &apos; Never interrupt
If Not IsNull(poEvent) Then
Set oDialog = CreateScriptService(&quot;SFDialogs.DialogEvent&quot;, poEvent).Parent
Set oPasswordControl = oDialog.Controls(&quot;InputField&quot;)
Set oHiddenControl = oDialog.Controls(&quot;HiddenField&quot;)
&apos; Alternate swap
If oPasswordControl.Visible Then
With oHiddenControl
.Value = oPasswordControl.Value
oPasswordControl.Visible = False
.Visible = True
.SetFocus()
.XControlView.AccessibleContext.setCaretPosition(oPasswordControl.XControlView.AccessibleContext.CaretPosition)
End With
Else
With oPasswordControl
.Value = oHiddenControl.Value
oHiddenControl.Visible = False
.Visible = True
.SetFocus()
.XControlView.AccessibleContext.setCaretPosition(oHiddenControl.XControlView.AccessibleContext.CaretPosition)
End With
End If
End If
Finally:
On Error GoTo 0
Exit Sub
End Sub &apos; ScriptForge.SF_UI._RunPasswordButton
REM ============================================ END OF SCRIPTFORGE.SF_UI
</script:module>