wizards/source/scriptforge/SF_Session.xba        |    4 
 wizards/source/scriptforge/python/scriptforge.py |  136 ++++++++++++++++++++---
 2 files changed, 126 insertions(+), 14 deletions(-)

New commits:
commit c1f5d07f359a33bb45c27d3fb703c2ba841cebfc
Author:     Jean-Pierre Ledure <j...@ledure.be>
AuthorDate: Fri Mar 26 12:03:53 2021 +0100
Commit:     Jean-Pierre Ledure <j...@ledure.be>
CommitDate: Fri Mar 26 17:31:39 2021 +0100

    ScriptForge - (scriptforge.py) Session class
    
    Full support of the session class methods from Python
    
    The InvokeSimpleScript() python method has been
    extended to support broader scopes (extensions and user documents)
    and ParamArray arguments in Basic.
    
    Indeed the SF_Session.ExecuteBasicScript() and
    SF_Session.ExecuteCalcFunction() require a varying number
    of arguments.
    
    No regression found in unit tests
    
    Change-Id: I0899bc6535b00340ed82b46336d60a7bb23b2098
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113154
    Tested-by: Jean-Pierre Ledure <j...@ledure.be>
    Tested-by: Jenkins
    Reviewed-by: Jean-Pierre Ledure <j...@ledure.be>

diff --git a/wizards/source/scriptforge/SF_Session.xba 
b/wizards/source/scriptforge/SF_Session.xba
index 2a56e91f1a55..182fe1049f0b 100644
--- a/wizards/source/scriptforge/SF_Session.xba
+++ b/wizards/source/scriptforge/SF_Session.xba
@@ -216,6 +216,10 @@ Check:
 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
        On Local Error GoTo CatchCall
        vReturn = oCalc.callFunction(UCase(CalcFunction), pvArgs())
 
diff --git a/wizards/source/scriptforge/python/scriptforge.py 
b/wizards/source/scriptforge/python/scriptforge.py
index 92f214c34e52..c90264ad09bb 100644
--- a/wizards/source/scriptforge/python/scriptforge.py
+++ b/wizards/source/scriptforge/python/scriptforge.py
@@ -104,7 +104,7 @@ class ScriptForge(object, metaclass = _Singleton):
     Version = '7.2'  # Actual version number
     #
     # Basic dispatcher for Python scripts
-    basicdispatcher = 'ScriptForge.SF_PythonHelper._PythonDispatcher'
+    basicdispatcher = 
'@application:ScriptForge.SF_PythonHelper._PythonDispatcher'
     # Python helper functions module
     pythonhelpermodule = 'ScriptForgeHelper.py'
     #
@@ -187,27 +187,45 @@ class ScriptForge(object, metaclass = _Singleton):
         """
             Create a UNO object corresponding with the given Python or Basic 
script
             The execution is done with the invoke() method applied on the 
created object
-            Implicit scope: Extensions and documents are excluded. Either
+            Implicit scope: Either
                 "application"            a shared library                      
         (BASIC)
                 "share"                  a library of LibreOffice Macros       
         (PYTHON)
             :param script: Either
-                    [library.]module.method - Must not be a class module or 
method
-                    [directory/]module.py$method
-            :return: the script object as a 
com.sun.star.script.provider.XScript UNO object
+                    [@][scope:][library.]module.method - Must not be a class 
module or method
+                        [@] means that the targeted method accepts ParamArray 
arguments (Basic only)
+                    [scope:][directory/]module.py$method - Must be a method 
defined at module level
+            :return: the value returned by the invoked script, or an error if 
the script was not found
             """
-        #    Compute the URI specification described in
-        #    
https://wiki.openoffice.org/wiki/Documentation/DevGuide/Scripting/Scripting_Framework_URI_Specification
+
+        # The frequently called PythonDispatcher in the ScriptForge Basic 
library is buffered to privilege performance
         if cls.servicesdispatcher is not None and script == 
ScriptForge.basicdispatcher:
             xscript = cls.servicesdispatcher
+            fullscript = script
+            paramarray = True
+        #    Build the URI specification described in
+        #    
https://wiki.openoffice.org/wiki/Documentation/DevGuide/Scripting/Scripting_Framework_URI_Specification
         elif len(script) > 0:
+            # Check ParamArray arguments
+            paramarray = False
+            if script[0] == '@':
+                script = script[1:]
+                paramarray = True
+            scope = ''
+            if ':' in script:
+                scope, script = script.split(':')
             if '.py$' in script.lower():  # Python
-                uri = 'vnd.sun.star.script:' + script + 
'?language=Python&location=share'
+                if len(scope) == 0:
+                    scope = 'share'     # Default for Python
+                uri = 'vnd.sun.star.script:' + script + 
'?language=Python&location=' + scope
             else:  # Basic
+                if len(scope) == 0:
+                    scope = 'application'     # Default for Basic
                 lib = ''
                 if len(script.split('.')) < 3:
-                    lib = cls.library + '.'
-                uri = 'vnd.sun.star.script:' + lib + script + 
'?language=Basic&location=application'
+                    lib = cls.library + '.'     # Default library = ScriptForge
+                uri = 'vnd.sun.star.script:' + lib + script + 
'?language=Basic&location=' + scope
             # Get the script object
+            fullscript = ('@' if paramarray else '') + scope + ':' + script
             try:
                 xscript = cls.scriptprovider.getScript(uri)
             except Exception:
@@ -215,15 +233,18 @@ class ScriptForge(object, metaclass = _Singleton):
                                  + ' could not be located in your LibreOffice 
installation')
         else:  # Should not happen
             return None
+
+        # At 1st execution of the common Basic dispatcher, buffer xscript
+        if fullscript == ScriptForge.basicdispatcher and 
cls.servicesdispatcher is None:
+            cls.servicesdispatcher = xscript
+
         # Execute the script with the given arguments
         # Packaging for script provider depends on presence of ParamArray 
arguments in the called Basic script
-        if script == ScriptForge.basicdispatcher:
-            # At 1st execution, buffer xscript
-            if cls.servicesdispatcher is None:
-                cls.servicesdispatcher = xscript
+        if paramarray:
             scriptreturn = xscript.invoke(args[0], (), ())
         else:
             scriptreturn = xscript.invoke(args, (), ())
+
         #
         return scriptreturn[0]  # Updatable arguments passed by reference are 
ignored
 
@@ -1057,6 +1078,93 @@ class SFScriptForge:
             return self.SIMPLEEXEC(self.py, 'Processor')
         processor = Processor
 
+    # #########################################################################
+    # SF_Session CLASS
+    # #########################################################################
+    class SF_Session(SFServices, metaclass = _Singleton):
+        """
+            The Session service gathers various general-purpose methods about:
+            - UNO introspection
+            - the invocation of external scripts or programs
+            """
+        # Mandatory class properties for service registration
+        serviceimplementation = 'basic'
+        servicename = 'ScriptForge.Session'
+        servicesynonyms = ('session', 'scriptforge.session')
+        serviceproperties = dict()
+        propertysynonyms = SFServices._getAttributeSynonyms(serviceproperties)
+
+        # Class constants                       Where to find an invoked 
library ?
+        SCRIPTISEMBEDDED = 'document'           # in the document
+        SCRIPTISAPPLICATION = 'application'     # in any shared library (Basic)
+        SCRIPTISPERSONAL = 'user'               # in My Macros (Python)
+        SCRIPTISPERSOXT = 'user:uno_packages'   # in an extension installed 
for the current user (Python)
+        SCRIPTISSHARED = 'share'                # in LibreOffice macros 
(Python)
+        SCRIPTISSHAROXT = 'share:uno_packages'  # in an extension installed 
for all users (Python)
+        SCRIPTISOXT = 'uno_packages'            # in an extension but the 
installation parameters are unknown (Python)
+
+        def ExecuteBasicScript(self, scope = '', script = '', *args):
+            if scope is None or scope == '':
+                scope = self.SCRIPTISAPPLICATION
+            if len(args) == 0:
+                args = (scope,) + (script,) + (None,)
+            else:
+                args = (scope,) + (script,) + args
+            # ExecuteBasicScript method has a ParamArray parameter in Basic
+            return self.SIMPLEEXEC('@SF_Session.ExecuteBasicScript', args)
+        executeBasicScript, executebasicscript = ExecuteBasicScript, 
ExecuteBasicScript
+
+        def ExecuteCalcFunction(self, calcfunction, *args):
+            if len(args) == 0:
+                # Arguments of Calc functions are strings or numbers. None == 
Empty is a good alias for no argument
+                args = (calcfunction,) + (None,)
+            else:
+                args = (calcfunction,) + args
+            # ExecuteCalcFunction method has a ParamArray parameter in Basic
+            return self.SIMPLEEXEC('@SF_Session.ExecuteCalcFunction', args)
+        executeCalcFunction, executecalcfunction = ExecuteCalcFunction, 
ExecuteCalcFunction
+
+        def ExecutePythonScript(self, scope = '', script = '', *args):
+            return self.SIMPLEEXEC(scope + ':' + script, *args)
+        executePythonScript, executepythonscript = ExecutePythonScript, 
ExecutePythonScript
+
+        def HasUnoMethod(self, unoobject, methodname):
+            return self.Execute(self.vbMethod, 'HasUnoMethod', unoobject, 
methodname)
+        hasUnoMethod, hasunomethod = HasUnoMethod, HasUnoMethod
+
+        def HasUnoProperty(self, unoobject, propertyname):
+            return self.Execute(self.vbMethod, 'HasUnoProperty', unoobject, 
propertyname)
+        hasUnoProperty, hasunoproperty = HasUnoProperty, HasUnoProperty
+
+        def OpenURLInBrowser(self, url):
+            py = ScriptForge.pythonhelpermodule + '$' + 
'_SF_Session__OpenURLInBrowser'
+            return self.SIMPLEEXEC(py, url)
+        openURLInBrowser, openurlinbrowser = OpenURLInBrowser, OpenURLInBrowser
+
+        def RunApplication(self, command, parameters):
+            return self.Execute(self.vbMethod, 'RunApplication', command, 
parameters)
+        runApplication, runapplication = RunApplication, RunApplication
+
+        def SendMail(self, recipient, cc = '', bcc = '', subject = '', body = 
'', filenames = '', editmessage = True):
+            return self.Execute(self.vbMethod, 'SendMail', recipient, cc, bcc, 
subject, body, filenames, editmessage)
+        sendMail, sendmail = SendMail, SendMail
+
+        def UnoObjectType(self, unoobject):
+            return self.Execute(self.vbMethod, 'UnoObjectType', unoobject)
+        unoObjectType, unoobjecttype = UnoObjectType, UnoObjectType
+
+        def UnoMethods(self, unoobject):
+            return self.Execute(self.vbMethod, 'UnoMethods', unoobject)
+        unoMethods, unomethods = UnoMethods, UnoMethods
+
+        def UnoProperties(self, unoobject):
+            return self.Execute(self.vbMethod, 'UnoProperties', unoobject)
+        unoProperties, unoproperties = UnoProperties, UnoProperties
+
+        def WebService(self, uri):
+            return self.Execute(self.vbMethod, 'WebService', uri)
+        webService, webservice = WebService, WebService
+
     # #########################################################################
     # SF_String CLASS
     # #########################################################################
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to