office-gobmx/wizards/source/scriptforge/SF_Session.xba
Jean-Pierre Ledure fc36eed73e ScriptForge session.ExecuteCalcFunction error handling
1) Error handling in the ExecuteCalcFunction()
   function must be conditioned by the global
   error handling.
   True; display a user-friendly message
   False: abort on the erroneous line

   So far, an ambiguous error message was displayed
   in both cases.

2) Above ambiguous error message was corrupted
   by the detour to SF_Array.Prepend() method
   in exc.RaiseFatal() and exc.RaiseAbort().
   A simple workaround fixes the ambiguity
   about the name of the faulty routine.

Change-Id: Iab38b48e6291e1960fc288696a7ebd18ffe8ebae
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175020
Reviewed-by: Jean-Pierre Ledure <jp@ledure.be>
Tested-by: Jenkins
2024-10-16 17:47:14 +02:00

1098 lines
No EOL
47 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_Session" 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_Session
&apos;&apos;&apos; ==========
&apos;&apos;&apos; Singleton class implementing the &quot;ScriptForge.Session&quot; service
&apos;&apos;&apos; Implemented as a usual Basic module
&apos;&apos;&apos;
&apos;&apos;&apos; Gathers diverse general-purpose properties and methods about :
&apos;&apos;&apos; - installation/execution environment
&apos;&apos;&apos; - UNO introspection utilities
&apos;&apos;&apos; - clipboard management
&apos;&apos;&apos; - invocation of external scripts or programs
&apos;&apos;&apos;
&apos;&apos;&apos; Service invocation example:
&apos;&apos;&apos; Dim session As Variant
&apos;&apos;&apos; session = CreateScriptService(&quot;Session&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_session.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;
REM ================================================================== EXCEPTIONS
Const CALCFUNCERROR = &quot;CALCFUNCERROR&quot; &apos; Calc function execution failed
Const NOSCRIPTERROR = &quot;NOSCRIPTERROR&quot; &apos; Script could not be located
Const SCRIPTEXECERROR = &quot;SCRIPTEXECERROR&quot; &apos; Exception during script execution
Const WRONGEMAILERROR = &quot;WRONGEMAILERROR&quot; &apos; Wrong email address
Const SENDMAILERROR = &quot;SENDMAILERROR&quot; &apos; Mail could not be sent
Const UNKNOWNFILEERROR = &quot;UNKNOWNFILEERROR&quot; &apos; Source file does not exist
REM ============================================================ MODULE CONSTANTS
&apos;&apos;&apos; Script locations
&apos;&apos;&apos; ================
&apos;&apos;&apos; Use next constants as Scope argument when invoking next methods:
&apos;&apos;&apos; ExecuteBasicScript()
&apos;&apos;&apos; ExecutePythonScript()
&apos;&apos;&apos; Example:
&apos;&apos;&apos; session.ExecuteBasicScript(session.SCRIPTISEMBEDDED, &quot;Standard.myModule.myFunc&quot;, etc)
Const cstSCRIPTISEMBEDDED = &quot;document&quot; &apos; a library of the document (BASIC + PYTHON)
Const cstSCRIPTISAPPLICATION = &quot;application&quot; &apos; a shared library (BASIC)
Const cstSCRIPTISPERSONAL = &quot;user&quot; &apos; a library of My Macros (PYTHON)
Const cstSCRIPTISPERSOXT = &quot;user:uno_packages&quot; &apos; an extension for the current user (PYTHON)
Const cstSCRIPTISSHARED = &quot;share&quot; &apos; a library of LibreOffice Macros (PYTHON)
Const cstSCRIPTISSHAROXT = &quot;share:uno_packages&quot; &apos; an extension for all users (PYTHON)
Const cstSCRIPTISOXT = &quot;uno_packages&quot; &apos; an extension but install params are unknown (PYTHON)
&apos;&apos;&apos; To build or to parse scripting framework URI&apos;s
Const cstScript1 = &quot;vnd.sun.star.script:&quot;
Const cstScript2 = &quot;?language=&quot;
Const cstScript3 = &quot;&amp;location=&quot;
REM ===================================================== CONSTRUCTOR/DESTRUCTOR
REM -----------------------------------------------------------------------------
Public Function Dispose() As Variant
Set Dispose = Nothing
End Function &apos; ScriptForge.SF_Array Explicit destructor
REM ================================================================== PROPERTIES
REM -----------------------------------------------------------------------------
Property Get ObjectType As String
&apos;&apos;&apos; Only to enable object representation
ObjectType = &quot;SF_Session&quot;
End Property &apos; ScriptForge.SF_Session.ObjectType
REM -----------------------------------------------------------------------------
Property Get ServiceName As String
&apos;&apos;&apos; Internal use
ServiceName = &quot;ScriptForge.Session&quot;
End Property &apos; ScriptForge.SF_Array.ServiceName
REM -----------------------------------------------------------------------------
Property Get SCRIPTISAPPLICATION As String
&apos;&apos;&apos; Convenient constants
SCRIPTISAPPLICATION = cstSCRIPTISAPPLICATION
End Property &apos; ScriptForge.SF_Session.SCRIPTISAPPLICATION
REM -----------------------------------------------------------------------------
Property Get SCRIPTISEMBEDDED As String
&apos;&apos;&apos; Convenient constants
SCRIPTISEMBEDDED = cstSCRIPTISEMBEDDED
End Property &apos; ScriptForge.SF_Session.SCRIPTISEMBEDDED
REM -----------------------------------------------------------------------------
Property Get SCRIPTISOXT As String
&apos;&apos;&apos; Convenient constants
SCRIPTISOXT = cstSCRIPTISOXT
End Property &apos; ScriptForge.SF_Session.SCRIPTISOXT
REM -----------------------------------------------------------------------------
Property Get SCRIPTISPERSONAL As String
&apos;&apos;&apos; Convenient constants
SCRIPTISPERSONAL = cstSCRIPTISPERSONAL
End Property &apos; ScriptForge.SF_Session.SCRIPTISPERSONAL
REM -----------------------------------------------------------------------------
Property Get SCRIPTISPERSOXT As String
&apos;&apos;&apos; Convenient constants
SCRIPTISPERSOXT = cstSCRIPTISPERSOXT
End Property &apos; ScriptForge.SF_Session.SCRIPTISPERSOXT
REM -----------------------------------------------------------------------------
Property Get SCRIPTISSHARED As String
&apos;&apos;&apos; Convenient constants
SCRIPTISSHARED = cstSCRIPTISSHARED
End Property &apos; ScriptForge.SF_Session.SCRIPTISSHARED
REM -----------------------------------------------------------------------------
Property Get SCRIPTISSHAROXT As String
&apos;&apos;&apos; Convenient constants
SCRIPTISSHAROXT = cstSCRIPTISSHAROXT
End Property &apos; ScriptForge.SF_Session.SCRIPTISSHAROXT
REM ============================================================== PUBLIC METHODS
REM -----------------------------------------------------------------------------
Public Function ExecuteBasicScript(Optional ByVal Scope As Variant _
, Optional ByVal Script As Variant _
, ParamArray pvArgs As Variant _
) As Variant
&apos;&apos;&apos; Execute the Basic script given as a string and return the value returned by the script
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Scope: &quot;Application&quot; (default) or &quot;Document&quot; (NOT case-sensitive)
&apos;&apos;&apos; (or use one of the SCRIPTIS... public constants above)
&apos;&apos;&apos; Script: library.module.method (Case sensitive)
&apos;&apos;&apos; library =&gt; The library may be not loaded yet
&apos;&apos;&apos; module =&gt; Must not be a class module
&apos;&apos;&apos; method =&gt; Sub or Function
&apos;&apos;&apos; Read https://wiki.documentfoundation.org/Documentation/DevGuide/Scripting_Framework#Scripting_Framework_URI_Specification
&apos;&apos;&apos; pvArgs: the arguments of the called script
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; The value returned by the call to the script
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; NOSCRIPTERROR The script could not be found
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; session.ExecuteBasicScript(, &quot;XrayTool._Main.Xray&quot;, someuno) &apos; Sub: no return expected
Dim oScript As Object &apos; Script to be invoked
Dim vReturn As Variant &apos; Returned value
Const cstThisSub = &quot;Session.ExecuteBasicScript&quot;
Const cstSubArgs = &quot;[Scope], Script, arg0[, arg1] ...&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
vReturn = Empty
Check:
If IsMissing(Scope) Or IsEmpty(Scope) Then Scope = SCRIPTISAPPLICATION
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not SF_Utils._Validate(Scope, &quot;Scope&quot;, V_STRING _
, Array(SCRIPTISAPPLICATION, SCRIPTISEMBEDDED)) Then GoTo Finally
If Not SF_Utils._Validate(Script, &quot;Script&quot;, V_STRING) Then GoTo Finally
End If
Try:
&apos; Execute script
Set oScript = SF_Session._GetScript(&quot;Basic&quot;, Scope, Script)
On Local Error GoTo CatchExec
If Not IsNull(oScript) Then vReturn = oScript.Invoke(pvArgs, Array(), Array())
Finally:
ExecuteBasicScript = vReturn
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
CatchExec:
SF_Exception.RaiseFatal(SCRIPTEXECERROR, &quot;Script&quot;, Script, Error$)
GoTo Finally
End Function &apos; ScriptForge.SF_Session.ExecuteBasicScript
REM -----------------------------------------------------------------------------
Public Function ExecuteCalcFunction(Optional ByVal CalcFunction As Variant _
, ParamArray pvArgs As Variant _
) As Variant
&apos;&apos;&apos; Execute a Calc function by its (english) name and based on the given arguments
&apos;&apos;&apos; Args:
&apos;&apos;&apos; CalcFunction: the english name of the function to execute
&apos;&apos;&apos; pvArgs: the arguments of the called function
&apos;&apos;&apos; Each argument must be either a string, a numeric value
&apos;&apos;&apos; or an array of arrays combining those types
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; The (string or numeric) value or the array of arrays returned by the call to the function
&apos;&apos;&apos; When the arguments contain arrays, the function is executed as an array function
&apos;&apos;&apos; Wrong arguments generate an error
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; CALCFUNCERROR &apos; Execution error in calc function
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; session.ExecuteCalcFunction(&quot;AVERAGE&quot;, 1, 5, 3, 7) returns 4
&apos;&apos;&apos; session.ExecuteCalcFunction(&quot;ABS&quot;, Array(Array(-1,2,3),Array(4,-5,6),Array(7,8,-9)))(2)(2) returns 9
&apos;&apos;&apos; session.ExecuteCalcFunction(&quot;LN&quot;, -3) generates an error
Dim oCalc As Object &apos; Give access to the com.sun.star.sheet.FunctionAccess service
Dim vReturn As Variant &apos; Returned value
Const cstThisSub = &quot;Session.ExecuteCalcFunction&quot;
Const cstSubArgs = &quot;CalcFunction, arg0[, arg1] ...&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
vReturn = Empty
Check:
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not SF_Utils._Validate(CalcFunction, &quot;CalcFunction&quot;, V_STRING) Then GoTo Finally
End If
Try:
&apos; Execute function
Set oCalc = SF_Utils._GetUNOService(&quot;FunctionAccess&quot;)
&apos; Intercept calls from Python when no arguments. Example NOW()
If UBound(pvArgs) = 0 Then
If IsEmpty(pvArgs(0)) Then pvArgs = Array()
End If
If SF_Utils._ErrorHandling() Then On Local Error GoTo CatchCall
vReturn = oCalc.callFunction(UCase(CalcFunction), pvArgs())
Finally:
ExecuteCalcFunction = vReturn
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
CatchCall:
SF_Exception.RaiseFatal(CALCFUNCERROR, CalcFunction)
GoTo Finally
End Function &apos; ScriptForge.SF_Session.ExecuteCalcFunction
REM -----------------------------------------------------------------------------
Public Function ExecutePythonScript(Optional ByVal Scope As Variant _
, Optional ByVal Script As Variant _
, ParamArray pvArgs As Variant _
) As Variant
&apos;&apos;&apos; Execute the Python script given as a string and return the value returned by the script
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Scope: one of the SCRIPTIS... public constants above (default = &quot;share&quot;)
&apos;&apos;&apos; Script: (Case sensitive)
&apos;&apos;&apos; &quot;library/module.py$method&quot;
&apos;&apos;&apos; or &quot;module.py$method&quot;
&apos;&apos;&apos; or &quot;myExtension.oxt|myScript|module.py$method&quot;
&apos;&apos;&apos; library =&gt; The library may be not loaded yet
&apos;&apos;&apos; myScript =&gt; The directory containing the python module
&apos;&apos;&apos; module.py =&gt; The python module
&apos;&apos;&apos; method =&gt; The python function
&apos;&apos;&apos; Read https://wiki.documentfoundation.org/Documentation/DevGuide/Scripting_Framework#Scripting_Framework_URI_Specification
&apos;&apos;&apos; pvArgs: the arguments of the called script
&apos;&apos;&apos; Date arguments are converted to iso format. However dates in arrays are not converted
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; The value(s) returned by the call to the script. If &gt;1 values, enclosed in an array
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; NOSCRIPTERROR The script could not be found
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; session.ExecutePythonScript(session.SCRIPTISSHARED, &quot;Capitalise.py$getNewString&quot;, &quot;Abc&quot;) returns &quot;abc&quot;
Dim oScript As Object &apos; Script to be invoked
Dim vArg As Variant &apos; Individual argument
Dim vReturn As Variant &apos; Returned value
Dim i As Long
Const cstThisSub = &quot;Session.ExecutePythonScript&quot;
Const cstSubArgs = &quot;[Scope], Script, arg0[, arg1] ...&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
vReturn = Empty
Check:
If IsError(Scope) Or IsMissing(Scope) Then Scope = SCRIPTISSHARED
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not SF_Utils._Validate(Scope, &quot;Scope&quot;, V_STRING _
, Array(SCRIPTISSHARED, SCRIPTISEMBEDDED, SCRIPTISPERSONAL, SCRIPTISSHAROXT, SCRIPTISPERSOXT, SCRIPTISOXT) _
) Then GoTo Finally
If Not SF_Utils._Validate(Script, &quot;Script&quot;, V_STRING) Then GoTo Finally
End If
Try:
&apos; Filter date arguments - NB: dates in arrays are not filtered
For i = 0 To UBound(pvArgs) &apos; pvArgs always zero-based
vArg = pvArgs(i)
If VarType(vArg) = V_DATE Then pvArgs(i) = SF_Utils._CDateToIso(vArg)
Next i
&apos; Intercept alternate Python helpers file when relevant
With _SF_
If SF_String.StartsWith(Script, .PythonHelper) And Len(.PythonHelper2) &gt; 0 Then
Scope = SCRIPTISPERSONAL
Script = .PythonHelper2 &amp; Mid(Script, Len(.PythonHelper) + 1)
End If
End With
&apos; Find script
Set oScript = SF_Session._GetScript(&quot;Python&quot;, Scope, Script)
&apos; Execute script
If Not IsNull(oScript) Then
vReturn = oScript.Invoke(pvArgs(), Array(), Array())
&apos; Remove surrounding array when single returned value
If IsArray(vReturn) Then
If UBound(vReturn) = 0 Then vReturn = vReturn(0)
End If
End If
Finally:
ExecutePythonScript = vReturn
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; ScriptForge.SF_Session.ExecutePythonScript
REM -----------------------------------------------------------------------------
Public Function GetPDFExportOptions() As Variant
&apos;&apos;&apos; Return the actual values of the PDF export options
&apos;&apos;&apos; The PDF options are described on https://wiki.openoffice.org/wiki/API/Tutorials/PDF_export
&apos;&apos;&apos; PDF options are set at each use of the Export as ... PDF command by the user and kept
&apos;&apos;&apos; permanently until their reset by script or by a new export
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; A ScriptForge dictionary instance listing the 40+ properties and their value
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; Dim dict As Object
&apos;&apos;&apos; Set dict = session.GetPDFExportOptions()
&apos;&apos;&apos; MsgBox dict.Item(&quot;Quality&quot;)
Dim vDict As Variant &apos; Returned value
Dim oConfig As Object &apos; com.sun.star.configuration.ConfigurationProvider
Dim oNodePath As Object &apos; com.sun.star.beans.PropertyValue
Dim oOptions As Object &apos; configmgr.RootAccess
Dim vOptionNames As Variant &apos; Array of PDF options names
Dim vOptionValues As Variant &apos; Array of PDF options values
Dim i As Long
Const cstThisSub = &quot;Session.GetPDFExportOptions&quot;
Const cstSubArgs = &quot;&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
Set vDict = Nothing
Check:
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
Try:
&apos; Get the (read-only) internal PDF options
Set oConfig = SF_Utils._GetUNOService(&quot;ConfigurationProvider&quot;)
Set oNodePath = SF_Utils._MakePropertyValue(&quot;nodepath&quot;, &quot;/org.openoffice.Office.Common/Filter/PDF/Export/&quot;)
Set oOptions = oConfig.createInstanceWithArguments(&quot;com.sun.star.configuration.ConfigurationAccess&quot;, Array(oNodePath))
&apos; Copy the options into a ScriptForge dictionary with case-sensitive comparison of keys
Set vDict = CreateScriptService(&quot;Dictionary&quot;, True)
vOptionNames = oOptions.getElementNames()
vOptionValues = oOptions.getPropertyValues(vOptionNames)
&apos;
For i = 0 To UBound(vOptionNames)
vDict.Add(vOptionNames(i), vOptionValues(i))
Next i
Finally:
GetPDFExportOptions = vDict
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; ScriptForge.SF_Session.GetPDFExportOptions
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;Session.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 Else
End Select
Finally:
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; ScriptForge.SF_Session.GetProperty
REM -----------------------------------------------------------------------------
Public Function HasUnoMethod(Optional ByRef UnoObject As Variant _
, Optional ByVal MethodName As Variant _
) As Boolean
&apos;&apos;&apos; Returns True if a UNO object contains the given method
&apos;&apos;&apos; Code-snippet derived from XRAY
&apos;&apos;&apos; Args:
&apos;&apos;&apos; UnoObject: the object to identify
&apos;&apos;&apos; MethodName: the name of the method as a string. The search is case-sensitive
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; False when the method is not found or when an argument is invalid
Dim oIntrospect As Object &apos; com.sun.star.beans.Introspection
Dim oInspect As Object &apos; com.sun.star.beans.XIntrospectionAccess
Dim bMethod As Boolean &apos; Return value
Const cstThisSub = &quot;Session.HasUnoMethod&quot;
Const cstSubArgs = &quot;UnoObject, MethodName&quot;
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
Check:
bMethod = False
If VarType(UnoObject) &lt;&gt; V_OBJECT Then GoTo Finally
If IsNull(UnoObject) Then GoTo Finally
If VarType(MethodName) &lt;&gt; V_STRING Then GoTo Finally
If MethodName = Space(Len(MethodName)) Then GoTo Finally
Try:
On Local Error GoTo Catch
Set oIntrospect = SF_Utils._GetUNOService(&quot;Introspection&quot;)
Set oInspect = oIntrospect.inspect(UnoObject)
bMethod = oInspect.hasMethod(MethodName, com.sun.star.beans.MethodConcept.ALL)
Finally:
HasUnoMethod = bMethod
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
On Local Error GoTo 0
GoTo Finally
End Function &apos; ScriptForge.SF_Session.HasUnoMethod
REM -----------------------------------------------------------------------------
Public Function HasUnoProperty(Optional ByRef UnoObject As Variant _
, Optional ByVal PropertyName As Variant _
) As Boolean
&apos;&apos;&apos; Returns True if a UNO object contains the given property
&apos;&apos;&apos; Code-snippet derived from XRAY
&apos;&apos;&apos; Args:
&apos;&apos;&apos; UnoObject: the object to identify
&apos;&apos;&apos; PropertyName: the name of the property as a string. The search is case-sensitive
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; False when the property is not found or when an argument is invalid
Dim oIntrospect As Object &apos; com.sun.star.beans.Introspection
Dim oInspect As Object &apos; com.sun.star.beans.XIntrospectionAccess
Dim bProperty As Boolean &apos; Return value
Const cstThisSub = &quot;Session.HasUnoProperty&quot;
Const cstSubArgs = &quot;UnoObject, PropertyName&quot;
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
Check:
bProperty = False
If VarType(UnoObject) &lt;&gt; V_OBJECT Then GoTo Finally
If IsNull(UnoObject) Then GoTo Finally
If VarType(PropertyName) &lt;&gt; V_STRING Then GoTo Finally
If PropertyName = Space(Len(PropertyName)) Then GoTo Finally
Try:
On Local Error GoTo Catch
Set oIntrospect = SF_Utils._GetUNOService(&quot;Introspection&quot;)
Set oInspect = oIntrospect.inspect(UnoObject)
bProperty = oInspect.hasProperty(PropertyName, com.sun.star.beans.PropertyConcept.ALL)
Finally:
HasUnoProperty = bProperty
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
On Local Error GoTo 0
GoTo Finally
End Function &apos; ScriptForge.SF_Session.HasUnoProperty
REM -----------------------------------------------------------------------------
Public Function Methods() As Variant
&apos;&apos;&apos; Return the list of public methods of the Session service as an array
Methods = Array( _
&quot;ExecuteBasicScript&quot; _
, &quot;ExecuteCalcFunction&quot; _
, &quot;ExecutePythonScript&quot; _
, &quot;HasUnoMethod&quot; _
, &quot;HasUnoProperty&quot; _
, &quot;OpenURLInBrowser&quot; _
, &quot;RunApplication&quot; _
, &quot;SendMail&quot; _
, &quot;UnoMethods&quot; _
, &quot;UnoObjectType&quot; _
, &quot;UnoProperties&quot; _
, &quot;WebService&quot; _
)
End Function &apos; ScriptForge.SF_Session.Methods
REM -----------------------------------------------------------------------------
Public Sub OpenURLInBrowser(Optional ByVal URL As Variant)
&apos;&apos;&apos; Opens a URL in the default browser
&apos;&apos;&apos; Args:
&apos;&apos;&apos; URL: The URL to open in the browser
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; session.OpenURLInBrowser(&quot;https://docs.python.org/3/library/webbrowser.html&quot;)
Const cstPyHelper = &quot;$&quot; &amp; &quot;_SF_Session__OpenURLInBrowser&quot;
Const cstThisSub = &quot;Session.OpenURLInBrowser&quot;
Const cstSubArgs = &quot;URL&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
Check:
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not SF_Utils._Validate(URL, &quot;URL&quot;, V_STRING) Then GoTo Finally
End If
Try:
ExecutePythonScript(SCRIPTISSHARED, _SF_.PythonHelper &amp; cstPyHelper, URL)
Finally:
SF_Utils._ExitFunction(cstThisSub)
Exit Sub
Catch:
GoTo Finally
End Sub &apos; ScriptForge.SF_Session.OpenURLInBrowser
REM -----------------------------------------------------------------------------
Public Function Properties() As Variant
&apos;&apos;&apos; Return the list or properties as an array
Properties = Array( _
)
End Function &apos; ScriptForge.SF_Session.Properties
REM -----------------------------------------------------------------------------
Public Function RunApplication(Optional ByVal Command As Variant _
, Optional ByVal Parameters As Variant _
) As Boolean
&apos;&apos;&apos; Executes an arbitrary system command
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Command: The command to execute
&apos;&apos;&apos; This may be an executable file or a document which is registered with an application
&apos;&apos;&apos; so that the system knows what application to launch for that document
&apos;&apos;&apos; Parameters: a list of space separated parameters as a single string
&apos;&apos;&apos; The method does not validate the given parameters, but only passes them to the specified command
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; True if success
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; UNKNOWNFILEERROR Command could not be identified as a valid file
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; session.RunApplication(&quot;Notepad.exe&quot;)
&apos;&apos;&apos; session.RunApplication(&quot;C:\myFolder\myDocument.odt&quot;)
&apos;&apos;&apos; session.RunApplication(&quot;kate&quot;) &apos; (Linux)
&apos;&apos;&apos; session.RunApplication(&quot;kate&quot;, &quot;/home/me/install.txt&quot;) &apos; (Linux)
Dim bReturn As Boolean &apos; Returned value
Dim oShell As Object &apos; com.sun.star.system.SystemShellExecute
Dim sCommand As String &apos; Command as an URL
Const cstThisSub = &quot;Session.RunApplication&quot;
Const cstSubArgs = &quot;Command, [Parameters]&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
bReturn = False
Check:
If IsMissing(Parameters) Then Parameters = &quot;&quot;
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not SF_Utils._ValidateFile(Command, &quot;Command&quot;) Then GoTo Finally
If Not SF_Utils._Validate(Parameters, &quot;Parameters&quot;, V_STRING) Then GoTo Finally
End If
Try:
&apos; Cfr. discussion tdf#160222
&apos; 1) Try Shell(), always in not synchronized mode
&apos; 2) If failure - check command existence as a valid file
&apos; - try com.sun.star.system.SystemShellExecute
sCommand = SF_FileSystem._ConvertFromUrl(Command)
On Local Error GoTo Step2
Shell(sCommand, , Parameters, False)
Step2:
If Err &gt; 0 Then
On Error GoTo 0 &apos; Reset error status
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
If Not SF_FileSystem.FileExists(Command) Then GoTo CatchNotExists
Set oShell = SF_Utils._GetUNOService(&quot;SystemShellExecute&quot;)
sCommand = SF_FileSystem._ConvertToUrl(Command)
oShell.execute(sCommand, Parameters, com.sun.star.system.SystemShellExecuteFlags.DEFAULTS)
End If
bReturn = True
Finally:
RunApplication = bReturn
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
CatchNotExists:
SF_Exception.RaiseFatal(UNKNOWNFILEERROR, &quot;Command&quot;, Command)
GoTo Finally
End Function &apos; ScriptForge.SF_Session.RunApplication
REM -----------------------------------------------------------------------------
Public Sub SendMail(Optional ByVal Recipient As Variant _
, Optional ByRef Cc As Variant _
, Optional ByRef Bcc As Variant _
, Optional ByVal Subject As Variant _
, Optional ByRef Body As Variant _
, Optional ByVal FileNames As Variant _
, Optional ByVal EditMessage As Variant _
)
&apos;&apos;&apos; Send a message (with or without attachments) to recipients from the user&apos;s mail client
&apos;&apos;&apos; The message may be edited by the user before sending or, alternatively, be sent immediately
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Recipient: an email addresses (To recipient)
&apos;&apos;&apos; Cc: a comma-delimited list of email addresses (carbon copy)
&apos;&apos;&apos; Bcc: a comma-delimited list of email addresses (blind carbon copy)
&apos;&apos;&apos; Subject: the header of the message
&apos;&apos;&apos; FileNames: a comma-separated list of filenames to attach to the mail. SF_FileSystem naming conventions apply
&apos;&apos;&apos; Body: the unformatted text of the message
&apos;&apos;&apos; EditMessage: when True (default) the message is editable before being sent
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; UNKNOWNFILEERROR File does not exist
&apos;&apos;&apos; WRONGEMAILERROR String not recognized as an email address
&apos;&apos;&apos; SENDMAILERROR System error, probably no mail client
Dim sEmail As String &apos; An single email address
Dim sFile As String &apos; A single file name
Dim sArg As String &apos; Argument name
Dim vCc As Variant &apos; Array alias of Cc
Dim vBcc As Variant &apos; Array alias of Bcc
Dim vFileNames As Variant &apos; Array alias of FileNames
Dim oMailService As Object &apos; com.sun.star.system.SimpleCommandMail or com.sun.star.system.SimpleSystemMail
Dim oMail As Object &apos; com.sun.star.system.XSimpleMailClient
Dim oMessage As Object &apos; com.sun.star.system.XSimpleMailMessage
Dim lFlag As Long &apos; com.sun.star.system.SimpleMailClientFlags.XXX
Dim ARR As Object : ARR = ScriptForge.SF_Array
Dim i As Long
Const cstComma = &quot;,&quot;, cstSemiColon = &quot;;&quot;
Const cstThisSub = &quot;Session.SendMail&quot;
Const cstSubArgs = &quot;Recipient, [Cc=&quot;&quot;&quot;&quot;], [Bcc=&quot;&quot;&quot;&quot;], [Subject=&quot;&quot;&quot;&quot;], [FileNames=&quot;&quot;&quot;&quot;], [Body=&quot;&quot;&quot;&quot;], [EditMessage=True]&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
Check:
If IsMissing(Cc) Or IsEmpty(Cc) Then Cc = &quot;&quot;
If IsMissing(Bcc) Or IsEmpty(Bcc) Then Bcc = &quot;&quot;
If IsMissing(Subject) Or IsEmpty(Subject) Then Subject = &quot;&quot;
If IsMissing(FileNames) Or IsEmpty(FileNames) Then FileNames = &quot;&quot;
If IsMissing(Body) Or IsEmpty(Body) Then Body = &quot;&quot;
If IsMissing(EditMessage) Or IsEmpty(EditMessage) Then EditMessage = True
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not SF_Utils._Validate(Recipient, &quot;Recipient&quot;, V_STRING) Then GoTo Finally
If Not SF_Utils._Validate(Cc, &quot;Cc&quot;, V_STRING) Then GoTo Finally
If Not SF_Utils._Validate(Bcc, &quot;Bcc&quot;, V_STRING) Then GoTo Finally
If Not SF_Utils._Validate(Subject, &quot;Subject&quot;, V_STRING) Then GoTo Finally
If Not SF_Utils._Validate(FileNames, &quot;FileNames&quot;, V_STRING) Then GoTo Finally
If Not SF_Utils._Validate(Body, &quot;Body&quot;, V_STRING) Then GoTo Finally
If Not SF_Utils._Validate(EditMessage, &quot;EditMessage&quot;, V_BOOLEAN) Then GoTo Finally
End If
&apos; Check email addresses
sArg = &quot;Recipient&quot; : sEmail = Recipient
If Not SF_String.IsEmail(sEmail) Then GoTo CatchEmail
sArg = &quot;Cc&quot; : vCc = ARR.TrimArray(Split(Cc, cstComma))
For Each sEmail In vCc
If Not SF_String.IsEmail(sEmail) Then GoTo CatchEmail
Next sEmail
sArg = &quot;Bcc&quot; : vBcc = ARR.TrimArray(Split(Bcc, cstComma))
For Each sEmail In vBcc
If Not SF_String.IsEmail(sEmail) Then GoTo CatchEmail
Next sEmail
&apos; Check file existence
If Len(FileNames) &gt; 0 Then
vFileNames = ARR.TrimArray(Split(FileNames, cstComma))
For i = 0 To UBound(vFileNames)
sFile = vFileNames(i)
If Not SF_Utils._ValidateFile(sFile, &quot;FileNames&quot;) Then GoTo Finally
If Not SF_FileSystem.FileExists(sFile) Then GoTo CatchNotExists
vFileNames(i) = ConvertToUrl(sFile)
Next i
Else
vFileNames = Array()
End If
Try:
&apos; Initialize the mail service
Set oMailService = SF_Utils._GetUNOService(&quot;MailService&quot;)
If IsNull(oMailService) Then GoTo CatchMail
Set oMail = oMailService.querySimpleMailClient()
If IsNull(oMail) Then GoTo CatchMail
Set oMessage = oMail.createSimpleMailMessage()
If IsNull(oMessage) Then GoTo CatchMail
&apos; Feed the new mail message
With oMessage
.setRecipient(Recipient)
If Subject &lt;&gt; &quot;&quot; Then .setSubject(Subject)
If UBound(vCc) &gt;= 0 Then .setCcRecipient(vCc)
If UBound(vBcc) &gt;= 0 Then .setBccRecipient(vBcc)
.Body = Iif(Len(Body) = 0, &quot; &quot;, Body) &apos; Body must not be the empty string ??
.setAttachement(vFileNames)
End With
lFlag = Iif(EditMessage, com.sun.star.system.SimpleMailClientFlags.DEFAULTS, com.sun.star.system.SimpleMailClientFlags.NO_USER_INTERFACE)
&apos; Send using the mail service
oMail.sendSimpleMailMessage(oMessage, lFlag)
Finally:
SF_Utils._ExitFunction(cstThisSub)
Exit Sub
Catch:
GoTo Finally
CatchEmail:
SF_Exception.RaiseFatal(WRONGEMAILERROR, sArg, sEmail)
GoTo Finally
CatchNotExists:
SF_Exception.RaiseFatal(UNKNOWNFILEERROR, &quot;FileNames&quot;, sFile)
GoTo Finally
CatchMail:
SF_Exception.RaiseFatal(SENDMAILERROR)
GoTo Finally
End Sub &apos; ScriptForge.SF_Session.SendMail
REM -----------------------------------------------------------------------------
Public Function SetPDFExportOptions(Optional ByRef PDFOptions As Variant) As Boolean
&apos;&apos;&apos; Modify the actual values of the PDF export options from an options dictionary
&apos;&apos;&apos; The PDF options are described on https://wiki.openoffice.org/wiki/API/Tutorials/PDF_export
&apos;&apos;&apos; PDF options are set at each use of the Export as ... PDF command by the user and kept
&apos;&apos;&apos; permanently until their reset by script (like this one) or by a new export
&apos;&apos;&apos; The changed options are applicable on any subsequent ExportToPDF user command or to any SaveAsPDF script execution
&apos;&apos;&apos; Args:
&apos;&apos;&apos; PDFOptions: a ScriptForge dictionary object
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; True when successful
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; Dim dict As Object
&apos;&apos;&apos; Set dict = session.GetPDFExportOptions()
&apos;&apos;&apos; dict.ReplaceItem(&quot;Quality&quot;, 50)
&apos;&apos;&apos; session.SetPDFExportOptions(dict)
Dim bSetPDF As Boolean &apos; Returned value
Dim oConfig As Object &apos; com.sun.star.configuration.ConfigurationProvider
Dim oNodePath As Object &apos; com.sun.star.beans.PropertyValue
Dim oOptions As Object &apos; configmgr.RootAccess
Dim vOptionNames As Variant &apos; Array of PDF options names
Dim vOptionValues As Variant &apos; Array of PDF options values
Dim oDict As Object &apos; Alias of PDFOptions
Dim i As Long
Const cstThisSub = &quot;Session.SetPDFExportOptions&quot;
Const cstSubArgs = &quot;PDFOptions&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
bSetPDF = False
Check:
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not SF_Utils._Validate(PDFOptions, &quot;PDFOptions&quot;, V_OBJECT, , , &quot;DICTIONARY&quot;) Then GoTo Finally
End If
Try:
&apos; Get the (updatable) internal PDF options
Set oConfig = SF_Utils._GetUNOService(&quot;ConfigurationProvider&quot;)
Set oNodePath = SF_Utils._MakePropertyValue(&quot;nodepath&quot;, &quot;/org.openoffice.Office.Common/Filter/PDF/Export/&quot;)
Set oOptions = oConfig.createInstanceWithArguments(&quot;com.sun.star.configuration.ConfigurationUpdateAccess&quot;, Array(oNodePath))
&apos; Copy the options from the ScriptForge dictionary in argument to property values
Set oDict = PDFOptions
oOptions.setPropertyValues(oDict.Keys, oDict.Items)
oOptions.commitChanges()
bSetPDF = True
Finally:
SetPDFExportOptions = bSetPDF
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; ScriptForge.SF_Session.SetPDFExportOptions
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;Session.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_Session.SetProperty
REM -----------------------------------------------------------------------------
Public Function UnoMethods(Optional ByRef UnoObject As Variant) As Variant
&apos;&apos;&apos; Returns a list of the methods callable from an UNO object
&apos;&apos;&apos; Code-snippet derived from XRAY
&apos;&apos;&apos; Args:
&apos;&apos;&apos; UnoObject: the object to identify
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; A zero-based sorted array. May be empty
Dim oIntrospect As Object &apos; com.sun.star.beans.Introspection
Dim oInspect As Object &apos; com.sun.star.beans.XIntrospectionAccess
Dim vMethods As Variant &apos; Array of com.sun.star.reflection.XIdlMethod
Dim vMethod As Object &apos; com.sun.star.reflection.XIdlMethod
Dim lMax As Long &apos; UBounf of vMethods
Dim vMethodsList As Variant &apos; Return value
Dim i As Long
Const cstThisSub = &quot;Session.UnoMethods&quot;
Const cstSubArgs = &quot;UnoObject&quot;
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
Check:
vMethodsList = Array()
If VarType(UnoObject) &lt;&gt; V_OBJECT Then GoTo Finally
If IsNull(UnoObject) Then GoTo Finally
Try:
On Local Error GoTo Catch
Set oIntrospect = SF_Utils._GetUNOService(&quot;Introspection&quot;)
Set oInspect = oIntrospect.inspect(UnoObject)
vMethods = oInspect.getMethods(com.sun.star.beans.MethodConcept.ALL)
&apos; The names must be extracted from com.sun.star.reflection.XIdlMethod structures
lMax = UBound(vMethods)
If lMax &gt;= 0 Then
ReDim vMethodsList(0 To lMax)
For i = 0 To lMax
vMethodsList(i) = vMethods(i).Name
Next i
vMethodsList = SF_Array.Sort(vMethodsList, CaseSensitive := True)
End If
Finally:
UnoMethods = vMethodsList
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
On Local Error GoTo 0
GoTo Finally
End Function &apos; ScriptForge.SF_Session.UnoMethods
REM -----------------------------------------------------------------------------
Public Function UnoObjectType(Optional ByRef UnoObject As Variant) As String
&apos;&apos;&apos; Identify the UNO type of an UNO object
&apos;&apos;&apos; Code-snippet derived from XRAY
&apos;&apos;&apos; Args:
&apos;&apos;&apos; UnoObject: the object to identify
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; com.sun.star. ... as a string
&apos;&apos;&apos; a zero-length string if identification was not successful
Dim oObjDesc As Object &apos; _ObjectDescriptor type
Dim sObjectType As String &apos; Return value
Const cstThisSub = &quot;Session.UnoObjectType&quot;
Const cstSubArgs = &quot;UnoObject&quot;
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
Check:
sObjectType = &quot;&quot;
If VarType(UnoObject) &lt;&gt; V_OBJECT Then GoTo Finally
If IsNull(UnoObject) Then GoTo Finally
Try:
Set oObjDesc = SF_Utils._VarTypeObj(UnoObject)
If oObjDesc.iVarType = V_UNOOBJECT Then sObjectType = oObjDesc.sObjectType
Finally:
UnoObjectType = sObjectType
SF_Utils._ExitFunction(cstThisSub)
Exit Function
End Function &apos; ScriptForge.SF_Session.UnoObjectType
REM -----------------------------------------------------------------------------
Public Function UnoProperties(Optional ByRef UnoObject As Variant) As Variant
&apos;&apos;&apos; Returns a list of the properties of an UNO object
&apos;&apos;&apos; Code-snippet derived from XRAY
&apos;&apos;&apos; Args:
&apos;&apos;&apos; UnoObject: the object to identify
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; A zero-based sorted array. May be empty
Dim oIntrospect As Object &apos; com.sun.star.beans.Introspection
Dim oInspect As Object &apos; com.sun.star.beans.XIntrospectionAccess
Dim vProperties As Variant &apos; Array of com.sun.star.beans.Property
Dim vProperty As Object &apos; com.sun.star.beans.Property
Dim lMax As Long &apos; UBounf of vProperties
Dim vPropertiesList As Variant &apos; Return value
Dim i As Long
Const cstThisSub = &quot;Session.UnoProperties&quot;
Const cstSubArgs = &quot;UnoObject&quot;
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
Check:
vPropertiesList = Array()
If VarType(UnoObject) &lt;&gt; V_OBJECT Then GoTo Finally
If IsNull(UnoObject) Then GoTo Finally
Try:
On Local Error GoTo Catch
Set oIntrospect = SF_Utils._GetUNOService(&quot;Introspection&quot;)
Set oInspect = oIntrospect.inspect(UnoObject)
vProperties = oInspect.getProperties(com.sun.star.beans.PropertyConcept.ALL)
&apos; The names must be extracted from com.sun.star.beans.Property structures
lMax = UBound(vProperties)
If lMax &gt;= 0 Then
ReDim vPropertiesList(0 To lMax)
For i = 0 To lMax
vPropertiesList(i) = vProperties(i).Name
Next i
vPropertiesList = SF_Array.Sort(vPropertiesList, CaseSensitive := True)
End If
Finally:
UnoProperties = vPropertiesList
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
On Local Error GoTo 0
GoTo Finally
End Function &apos; ScriptForge.SF_Session.UnoProperties
REM -----------------------------------------------------------------------------
Public Function WebService(Optional ByVal URI As Variant) As String
&apos;&apos;&apos; Get some web content from a URI
&apos;&apos;&apos; Args:
&apos;&apos;&apos; URI: URI text of the web service
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; The web page content of the URI
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; CALCFUNCERROR
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; session.WebService(&quot;wiki.documentfoundation.org/api.php?&quot; _
&apos;&apos;&apos; &amp; &quot;hidebots=1&amp;days=7&amp;limit=50&amp;action=feedrecentchanges&amp;feedformat=rss&quot;)
Dim sReturn As String &apos; Returned value
Const cstThisSub = &quot;Session.WebService&quot;
Const cstSubArgs = &quot;URI&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
sReturn = &quot;&quot;
Check:
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not SF_Utils._Validate(URI, &quot;URI&quot;, V_STRING) Then GoTo Finally
End If
Try:
sReturn = SF_Session.ExecuteCalcFunction(&quot;WEBSERVICE&quot;, URI)
Finally:
WebService = sReturn
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; ScriptForge.SF_Session.WebService
REM =========================================================== PRIVATE FUNCTIONS
REM -----------------------------------------------------------------------------
Private Function _ExecuteScript(ByVal psScript As String _
, Optional ByRef pvArg As Variant _
) As Variant
&apos;&apos;&apos; Execute the script expressed in the scripting framework_URI notation
&apos;&apos;&apos; Args:
&apos;&apos;&apos; psScript: read https://wiki.documentfoundation.org/Documentation/DevGuide/Scripting_Framework#Scripting_Framework_URI_Specification
&apos;&apos;&apos; pvArg: the unique argument to pass to the called script.
&apos;&apos;&apos; It is often an event object that triggered the execution of the script.
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; The return value after the script execution. May be ignored for events
Dim sScope As String &apos; The scope part of the script URI
Dim sLanguage As String &apos; The language part of the script URI
Dim sScript As String &apos; The script part of the script URI
Dim vStrings As Variant &apos; Array of strings: (script, language, scope)
Const cstComma = &quot;,&quot;
Try:
If ScriptForge.SF_String.StartsWith(psScript, cstScript1) Then
&apos; Parse script
vStrings = Split( _
Replace( _
Replace(Mid(psScript, Len(cstScript1) + 1), cstScript2, cstComma) _
, cstScript3, cstComma) _
, cstComma)
sScript = vStrings(0) : sLanguage = vStrings(1) : sScope = vStrings(2)
&apos; Execute script
If UCase(sLanguage) = &quot;BASIC&quot; Then
_ExecuteScript = ExecuteBasicScript(sScope, sScript, pvArg)
Else &apos; Python
_ExecuteScript = ExecutePythonScript(sScope, sScript, pvArg)
End If
End If
End Function &apos; ScriptForge.SF_Session._ExecuteScript
REM -----------------------------------------------------------------------------
Private Function _GetScript(ByVal psLanguage As String _
, ByVal psScope As String _
, ByVal psScript As String _
) As Object
&apos;&apos;&apos; Get the adequate script provider and from there the requested script
&apos;&apos;&apos; Called by ExecuteBasicScript() and ExecutePythonScript()
&apos;&apos;&apos; The execution of the script is done by the caller
&apos;&apos;&apos; Args:
&apos;&apos;&apos; psLanguage: Basic or Python
&apos;&apos;&apos; psScope: one of the SCRIPTISxxx constants
&apos;&apos;&apos; The SCRIPTISOXT constant is an alias for 2 cases, extension either
&apos;&apos;&apos; installed for one user only, or for all users
&apos;&apos;&apos; Managed here by trial and error
&apos;&apos;&apos; psScript: Read https://wiki.documentfoundation.org/Documentation/DevGuide/Scripting_Framework#Scripting_Framework_URI_Specification
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; A com.sun.star.script.provider.XScript object
Dim sScript As String &apos; The complete script string
Dim oScriptProvider As Object &apos; Script provider singleton
Dim oScript As Object &apos; Return value
Try:
&apos; Build script string
sScript = cstScript1 &amp; psScript &amp; cstScript2 &amp; psLanguage &amp; cstScript3 &amp; LCase(psScope)
&apos; Find script
Set oScript = Nothing
&apos; Python only: installation of extension is determined by user =&gt; unknown to script author
If psScope = SCRIPTISOXT Then &apos; =&gt; Trial and error
On Local Error GoTo ForAllUsers
sScript = cstScript1 &amp; psScript &amp; cstScript2 &amp; psLanguage &amp; cstScript3 &amp; SCRIPTISPERSOXT
Set oScriptProvider = SF_Utils._GetUNOService(&quot;ScriptProvider&quot;, SCRIPTISPERSOXT)
Set oScript = oScriptProvider.getScript(sScript)
End If
ForAllUsers:
On Local Error GoTo CatchNotFound
If IsNull(oScript) Then
If psScope = SCRIPTISOXT Then psScope = SCRIPTISSHAROXT
Set oScriptProvider = SF_Utils._GetUNOService(&quot;ScriptProvider&quot;, psScope)
Set oScript = oScriptProvider.getScript(sScript)
End If
Finally:
_GetScript = oScript
Exit Function
CatchNotFound:
SF_Exception.RaiseFatal(NOSCRIPTERROR, psLanguage, &quot;Scope&quot;, psScope, &quot;Script&quot;, psScript)
GoTo Finally
End Function &apos; ScriptForge.SF_Session._GetScript
REM =============================================== END OF SCRIPTFORGE.SF_SESSION
</script:module>