This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch AOO41X
in repository https://gitbox.apache.org/repos/asf/openoffice.git
The following commit(s) were added to refs/heads/AOO41X by this push:
new 3492f04019 Merge branch 'python-editing-embedding' into trunk
3492f04019 is described below
commit 3492f040199cbf8c0c22e0df262dee73c8a0571a
Author: Damjan Jovanovic <[email protected]>
AuthorDate: Sun May 24 04:24:14 2026 +0200
Merge branch 'python-editing-embedding' into trunk
Fixes: #60849 - Python editing and embedding macros in documents
Patch by: me
(cherry picked from commit 4bb26738ff7ada5caefbfb03c42872fd9b2b6d18)
---
main/scripting/README | 8 +-
main/scripting/source/pyprov/pythonscript.py | 480 ++++++++++++++++++++++++---
2 files changed, 432 insertions(+), 56 deletions(-)
diff --git a/main/scripting/README b/main/scripting/README
index 686e4ad30f..2b6a7936e1 100644
--- a/main/scripting/README
+++ b/main/scripting/README
@@ -19,6 +19,10 @@ browsing and executing scripts.
C++ for a ProtocolHandler implementation that handles vnd.sun.star.script
URIs and dispatches them for execution to the Scripting Framework.
+- source/pyprov
+
+LanguageScriptProvider for Python
+
- source/basprov
C++ implementation of the LanguageScriptProvider UNO service for Basic
@@ -57,10 +61,6 @@ Deprecated Code
Support for developing scripts in IDEs such as NetBeans.
-- source/pyprov
-
-LanguageScriptProvider for Python
-
- source/storage
- source/runtimemgr
diff --git a/main/scripting/source/pyprov/pythonscript.py
b/main/scripting/source/pyprov/pythonscript.py
index 23e82b558d..40eba13efe 100644
--- a/main/scripting/source/pyprov/pythonscript.py
+++ b/main/scripting/source/pyprov/pythonscript.py
@@ -52,7 +52,6 @@ elif os.environ.get(PYSCRIPT_LOG_ENV) == "DEBUG":
# False, writes to user/Scripts/python/log.txt
LOG_STDOUT = os.environ.get(PYSCRIPT_LOG_STDOUT_ENV, "1") != "0"
-ENABLE_EDIT_DIALOG=False # offers a minimal editor for
editing.
#-------------------------------------------------------------------
def encfile(uni):
@@ -125,7 +124,7 @@ log.debug( "pythonscript loading" )
#from com.sun.star.lang import typeOfXServiceInfo, typeOfXTypeProvider
from com.sun.star.uno import RuntimeException
from com.sun.star.lang import XServiceInfo
-from com.sun.star.io import IOException
+from com.sun.star.io import IOException, XInputStream
from com.sun.star.ucb import CommandAbortedException, XCommandEnvironment,
XProgressHandler, Command
from com.sun.star.task import XInteractionHandler
from com.sun.star.beans import XPropertySet, Property
@@ -133,7 +132,8 @@ from com.sun.star.container import XNameContainer
from com.sun.star.xml.sax import XDocumentHandler, InputSource
from com.sun.star.uno import Exception as UnoException
from com.sun.star.script import XInvocation
-from com.sun.star.awt import XActionListener
+from com.sun.star.awt import XActionListener, FontDescriptor
+from com.sun.star.awt.FontPitch import FIXED
from com.sun.star.script.provider import XScriptProvider, XScript,
XScriptContext, ScriptFrameworkErrorException
from com.sun.star.script.browse import XBrowseNode
@@ -167,6 +167,52 @@ def toIniName( str ):
return str + ".ini"
return str + "rc"
+class EmptyInputStream( unohelper.Base, XInputStream ):
+ def __init__( self ):
+ pass
+
+ def closeInput(self):
+ pass
+
+ def readBytes( self, seq, n ):
+ return 0, ""
+
+ def readSomeBytes( self, seq, n ):
+ return 0, ""
+
+ def skipBytes( self, n ):
+ pass
+
+ def available( self ):
+ return 0
+
+class BytesInputStream( unohelper.Base, XInputStream ):
+ def __init__( self, bytes ):
+ self.bytes = bytes
+ self.position = 0
+
+ def closeInput(self):
+ pass
+
+ def readBytes( self, seq, n ):
+ size = self.available()
+ if n < size:
+ size = n
+ curr = self.position
+ self.position += size
+ return size, uno.ByteSequence( self.bytes[curr:curr+size] )
+
+ def readSomeBytes( self, seq, n ):
+ return self.readBytes( seq, n )
+
+ def skipBytes( self, n ):
+ size = self.available()
+ if n < size:
+ size = n
+ self.position += size
+
+ def available( self ):
+ return len( self.bytes ) - self.position
""" definition: storageURI is the system dependent, absolute file url, where
the script is stored on disk
scriptURI is the system independent uri
@@ -451,6 +497,91 @@ class ProviderContext:
log.debug( "mapped " + url + " to " + str( entry.module ) )
return entry.module
+ # Forgets a stale module so a fresh copy can be loaded in the future.
+ # This is necessary because getModuleByUrl()'s
self.sfa.getDateTimeModified()
+ # doesn't always work, eg. for embedded scripts it always returns
timestamps
+ # with all zeroes, and even if it worked, the smallest granularity for ZIP
file
+ # timestamps is 2 seconds, which isn't good enough.
+ def removeModuleByUrl( self, url ):
+ self.modules.pop( url, None )
+
+def createEditorDialog( ctx ):
+ smgr = ctx.ServiceManager
+
+ dialogModel = smgr.createInstanceWithContext(
+ "com.sun.star.awt.UnoControlDialogModel", ctx)
+ dialogModel.PositionX = 105
+ dialogModel.PositionY = 117
+ dialogModel.Width = 240
+ dialogModel.Height = 320
+ dialogModel.Closeable = True
+ dialogModel.Moveable = True
+ dialogModel.Title = "Python Macro Editor"
+
+ runButtonModel = dialogModel.createInstance(
+ "com.sun.star.awt.UnoControlButtonModel" )
+ runButtonModel.PositionX = 57
+ runButtonModel.PositionY = 300
+ runButtonModel.Width = 40
+ runButtonModel.Height = 14
+ runButtonModel.TabIndex = 0
+ runButtonModel.Label = "Run"
+
+ saveButtonModel = dialogModel.createInstance(
+ "com.sun.star.awt.UnoControlButtonModel" )
+ saveButtonModel.PositionX = 100
+ saveButtonModel.PositionY = 300
+ saveButtonModel.Width = 40
+ saveButtonModel.Height = 14
+ saveButtonModel.TabIndex = 1
+ saveButtonModel.Label = "Save"
+
+ closeButtonModel = dialogModel.createInstance(
+ "com.sun.star.awt.UnoControlButtonModel" )
+ closeButtonModel.PositionX = 143
+ closeButtonModel.PositionY = 300
+ closeButtonModel.Width = 40
+ closeButtonModel.Height = 14
+ closeButtonModel.TabIndex = 2
+ closeButtonModel.PushButtonType = 2 # CANCEL
+ closeButtonModel.Label = "Close"
+
+ fontDescriptor = FontDescriptor()
+ fontDescriptor.Name = "SomeFixedWidthFont"
+ fontDescriptor.Pitch = FIXED
+
+ textFieldModel = dialogModel.createInstance(
+ "com.sun.star.awt.UnoControlEditModel" )
+ textFieldModel.PositionX = 6
+ textFieldModel.PositionY = 6
+ textFieldModel.Width = 228
+ textFieldModel.Height = 288
+ textFieldModel.TabIndex = 3
+ textFieldModel.HScroll = True
+ textFieldModel.VScroll = True
+ textFieldModel.MultiLine = True
+ textFieldModel.FontDescriptor = fontDescriptor
+
+ dialogModel.insertByName( "RunButton", runButtonModel )
+ dialogModel.insertByName( "SaveButton", saveButtonModel )
+ dialogModel.insertByName( "CloseButton", closeButtonModel )
+ dialogModel.insertByName( "EditorTextField", textFieldModel )
+
+ # create the dialog control and set the model
+ controlContainer = smgr.createInstanceWithContext(
+ "com.sun.star.awt.UnoControlDialog", ctx);
+ controlContainer.setModel(dialogModel);
+
+ # create a peer
+ toolkit = smgr.createInstanceWithContext(
+ "com.sun.star.awt.ExtToolkit", ctx);
+
+ controlContainer.setVisible(False);
+ controlContainer.createPeer(toolkit, None);
+
+ return controlContainer
+
+
#--------------------------------------------------
def isScript( candidate ):
ret = False
@@ -459,12 +590,15 @@ def isScript( candidate ):
return ret
#-------------------------------------------------------
-class ScriptBrowseNode( unohelper.Base, XBrowseNode , XPropertySet,
XInvocation, XActionListener ):
- def __init__( self, provCtx, uri, fileName, funcName ):
+class ScriptBrowseNode( unohelper.Base, XBrowseNode, XPropertySet,
XInvocation, XActionListener ):
+ def __init__( self, provCtx, parent, fileName, funcName ):
+ self.parent = parent
self.fileName = fileName
self.funcName = funcName
self.provCtx = provCtx
- self.uri = uri
+
+ def uri( self ):
+ return self.parent.uri()
def getName( self ):
return self.funcName
@@ -483,9 +617,9 @@ class ScriptBrowseNode( unohelper.Base, XBrowseNode ,
XPropertySet, XInvocation,
try:
if name == "URI":
ret = self.provCtx.uriHelper.getScriptURI(
- self.provCtx.getPersistentUrlFromStorageUrl( self.uri +
"$" + self.funcName ) )
- elif name == "Editable" and ENABLE_EDIT_DIALOG:
- ret = not self.provCtx.sfa.isReadOnly( self.uri )
+ self.provCtx.getPersistentUrlFromStorageUrl( self.uri() +
"$" + self.funcName ) )
+ elif name == "Editable":
+ ret = not self.provCtx.sfa.isReadOnly( self.uri() )
log.debug( "ScriptBrowseNode.getPropertyValue called for " + name
+ ", returning " + str(ret) )
except Exception as e:
@@ -504,16 +638,11 @@ class ScriptBrowseNode( unohelper.Base, XBrowseNode ,
XPropertySet, XInvocation,
def invoke( self, name, params, outparamindex, outparams ):
if name == "Editable":
- servicename = "com.sun.star.awt.DialogProvider"
ctx = self.provCtx.scriptContext.getComponentContext()
- dlgprov = ctx.ServiceManager.createInstanceWithContext(
- servicename, ctx )
- self.editor = dlgprov.createDialog(
- "vnd.sun.star.script:" +
- "ScriptBindingLibrary.MacroEditor?location=application")
+ self.editor = createEditorDialog( ctx )
- code = readTextFromStream(self.provCtx.sfa.openFileRead(self.uri))
+ code =
readTextFromStream(self.provCtx.sfa.openFileRead(self.uri()))
code = ensureSourceState( code )
self.editor.getControl("EditorTextField").setText(code)
@@ -524,7 +653,7 @@ class ScriptBrowseNode( unohelper.Base, XBrowseNode ,
XPropertySet, XInvocation,
self.editor.execute()
- return None
+ return None, (), ()
def actionPerformed( self, event ):
try:
@@ -545,18 +674,10 @@ class ScriptBrowseNode( unohelper.Base, XBrowseNode ,
XPropertySet, XInvocation,
elif event.ActionCommand == "Save":
toWrite = uno.ByteSequence(
- str(
- self.editor.getControl("EditorTextField").getText().encode(
- sys.getdefaultencoding())) )
- copyUrl = self.uri + ".orig"
- self.provCtx.sfa.move( self.uri, copyUrl )
- out = self.provCtx.sfa.openFileWrite( self.uri )
- out.writeBytes( toWrite )
- out.close()
- self.provCtx.sfa.kill( copyUrl )
-# log.debug("Save is not implemented yet")
-# text = self.editor.getControl("EditorTextField").getText()
-# log.debug("Would save: " + text)
+
self.editor.getControl("EditorTextField").getText().encode("utf-8"))
+ log.debug( "Saving Python macro to URI " + self.uri() )
+ self.provCtx.sfa.writeFile( self.uri(), BytesInputStream(
toWrite.value ) )
+ self.provCtx.removeModuleByUrl( self.uri() )
except Exception as e:
# TODO: add an error box here !
log.error( lastException2String() )
@@ -576,31 +697,33 @@ class ScriptBrowseNode( unohelper.Base, XBrowseNode ,
XPropertySet, XInvocation,
#-------------------------------------------------------
-class FileBrowseNode( unohelper.Base, XBrowseNode ):
- def __init__( self, provCtx, uri , name ):
+class FileBrowseNode( unohelper.Base, XBrowseNode, XPropertySet, XInvocation,
XActionListener ):
+ def __init__( self, provCtx, parent, name ):
self.provCtx = provCtx
- self.uri = uri
+ self.parent = parent
self.name = name
self.funcnames = None
+ def uri( self ):
+ return self.parent.rootUrl + "/" + self.name + ".py"
+
def getName( self ):
return self.name
def getChildNodes(self):
ret = ()
try:
- self.funcnames = self.provCtx.getFuncsByUrl( self.uri )
+ self.funcnames = self.provCtx.getFuncsByUrl( self.uri() )
scriptNodeList = []
for i in self.funcnames:
scriptNodeList.append(
ScriptBrowseNode(
- self.provCtx, self.uri, self.name, i ))
+ self.provCtx, self, self.name, i ))
ret = tuple( scriptNodeList )
- log.debug( "returning " +str(len(ret)) + " ScriptChildNodes on " +
self.uri )
except Exception as e:
text = lastException2String()
- log.error( "Error while evaluating " + self.uri + ":" + text )
+ log.error( "FileBrowseNode.getChildNodes error while evaluating "
+ self.uri() + ":" + text )
raise
return ret
@@ -613,13 +736,121 @@ class FileBrowseNode( unohelper.Base, XBrowseNode ):
def getType( self):
return CONTAINER
+ # XPropertySet
+
+ def getPropertyValue( self, name ):
+ ret = None
+ try:
+ if name == "Editable":
+ ret = not self.provCtx.sfa.isReadOnly( self.uri() )
+ elif name == "Deletable":
+ ret = not self.provCtx.sfa.isReadOnly( self.uri() )
+ elif name == "Renamable":
+ ret = not self.provCtx.sfa.isReadOnly( self.uri() )
+
+ log.debug( "FileBrowseNode.getPropertyValue called for " + name +
", returning " + str(ret) )
+ except Exception as e:
+ log.error( "FileBrowseNode.getPropertyValue error " +
lastException2String())
+ raise
+ return ret
-class DirBrowseNode( unohelper.Base, XBrowseNode ):
- def __init__( self, provCtx, name, rootUrl ):
+ def setPropertyValue( self, name, value ):
+ log.debug( "FileBrowseNode.setPropertyValue called " + name + "="
+str(value ) )
+
+ def getPropertySetInfo( self ):
+ log.debug( "FileBrowseNode.getPropertySetInfo called " )
+ return None
+
+ # XInvocation
+
+ def getIntrospection( self ):
+ log.debug( "FileBrowseNode.getIntrospection() called" )
+ return None
+
+ def invoke( self, name, params, outparamindex, outparams ):
+ log.debug("FileBrowseNode.invoke called for " + name + "," +
str(params) + "," + str(outparamindex) + "," + str(outparams))
+ try:
+ if name == "Editable":
+ ctx = self.provCtx.scriptContext.getComponentContext()
+
+ self.editor = createEditorDialog( ctx )
+
+ code =
readTextFromStream(self.provCtx.sfa.openFileRead(self.uri()))
+ code = ensureSourceState( code )
+ self.editor.getControl("EditorTextField").setText(code)
+
+ self.editor.getControl("RunButton").setActionCommand("Run")
+ self.editor.getControl("RunButton").addActionListener(self)
+ self.editor.getControl("SaveButton").setActionCommand("Save")
+ self.editor.getControl("SaveButton").addActionListener(self)
+
+ self.editor.execute()
+ elif name == "Deletable":
+ self.provCtx.sfa.kill( self.uri() )
+ return True, (), ()
+ elif name == "Renamable":
+ if params is None or not params:
+ raise IllegalArgumentException( "invoke with Creatable
needs the name in params" )
+ newUri = self.parent.rootUrl + "/" + params[0] + ".py"
+ self.provCtx.sfa.move( self.uri(), newUri )
+ self.name = params[0]
+ return self, (), ()
+ except Exception as e:
+ log.error( "FileBrowseNode.invoke error " + lastException2String()
)
+ raise
+ return None, (), ()
+
+ def setValue( self, name, value ):
+ return None
+
+ def getValue( self, name ):
+ log.debug( "FileBrowseNode.getValue() called" )
+ return None
+
+ def hasMethod( self, name ):
+ return False
+
+ def hasProperty( self, name ):
+ return False
+
+ # XActionListener
+
+ def actionPerformed( self, event ):
+ try:
+ if event.ActionCommand == "Run":
+ code = self.editor.getControl("EditorTextField").getText()
+ code = ensureSourceState( code )
+ mod = imp.new_module("ooo_script_framework")
+ mod.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] =
self.provCtx.scriptContext
+ exec(code, mod.__dict__)
+ values = mod.__dict__.get( CALLABLE_CONTAINER_NAME , None )
+ if not values:
+ values = list(mod.__dict__.values())
+
+ for i in values:
+ if isScript( i ):
+ i()
+ break
+
+ elif event.ActionCommand == "Save":
+ toWrite = uno.ByteSequence(
+
self.editor.getControl("EditorTextField").getText().encode("utf-8"))
+ log.debug( "Saving Python macro to URI " + self.uri() )
+ self.provCtx.sfa.writeFile( self.uri(), BytesInputStream(
toWrite.value ) )
+ self.provCtx.removeModuleByUrl( self.uri() )
+ except Exception as e:
+ # TODO: add an error box here !
+ log.error( lastException2String() )
+
+
+class DirBrowseNode( unohelper.Base, XBrowseNode, XPropertySet, XInvocation ):
+ def __init__( self, provCtx, name, rootUrl, depth ):
self.provCtx = provCtx
self.name = name
self.rootUrl = rootUrl
+ self.depth = depth
+ log.debug( "DirBrowseNode constructor for " + name + "," + rootUrl )
def getName( self ):
return self.name
@@ -633,10 +864,11 @@ class DirBrowseNode( unohelper.Base, XBrowseNode ):
if i.endswith( ".py" ):
log.debug( "adding filenode " + i )
browseNodeList.append(
- FileBrowseNode( self.provCtx, i,
i[i.rfind("/")+1:len(i)-3] ) )
+ FileBrowseNode( self.provCtx, self,
i[i.rfind("/")+1:len(i)-3] ) )
elif self.provCtx.sfa.isFolder( i ) and not
i.endswith("/pythonpath"):
log.debug( "adding DirBrowseNode " + i )
- browseNodeList.append( DirBrowseNode( self.provCtx,
i[i.rfind("/")+1:len(i)],i))
+ browseNodeList.append(
+ DirBrowseNode( self.provCtx, i[i.rfind("/")+1:len(i)],
i, self.depth + 1 ) )
return tuple( browseNodeList )
except Exception as e:
text = lastException2String()
@@ -650,10 +882,90 @@ class DirBrowseNode( unohelper.Base, XBrowseNode ):
def getType( self ):
return CONTAINER
+ # XScriptProvider
+
def getScript( self, uri ):
log.debug( "DirBrowseNode getScript " + uri + " invoked" )
raise IllegalArgumentException( "DirBrowseNode couldn't instantiate
script " + uri , self , 0 )
+ # XPropertySet
+
+ def getPropertyValue( self, name ):
+ ret = None
+ try:
+ if name == "Creatable":
+ ret = True
+ elif name == "Deletable":
+ ret = self.depth > 0 and not self.provCtx.sfa.isReadOnly(
self.rootUrl )
+ elif name == "Renamable":
+ ret = self.depth > 0 and not self.provCtx.sfa.isReadOnly(
self.rootUrl )
+
+ log.debug( "DirBrowseNode.getPropertyValue called for " + name +
", returning " + str(ret) )
+ except Exception as e:
+ log.error( "DirBrowseNode.getPropertyValue error " +
lastException2String())
+ raise
+
+ return ret
+
+ def setPropertyValue( self, name, value ):
+ log.debug( "DirBrowseNode.setPropertyValue called " + name + "="
+str(value ) )
+
+ def getPropertySetInfo( self ):
+ log.debug( "DirBrowseNode.getPropertySetInfo called " )
+ return None
+
+ # XInvocation
+
+ def getIntrospection( self ):
+ log.debug( "DirBrowseNode.getIntrospection() called" )
+ return None
+
+ def invoke( self, name, params, outparamindex, outparams ):
+ log.debug("DirBrowseNode.invoke called for " + name + "," +
str(params) + "," + str(outparamindex) + "," + str(outparams))
+ try:
+ if name == "Creatable":
+ if params is None or not params:
+ raise IllegalArgumentException( "invoke with Creatable
needs the name in params" )
+ if self.depth == 0:
+ subFolderUrl = self.rootUrl + "/" + params[0]
+ self.provCtx.sfa.createFolder( subFolderUrl )
+ childNode = DirBrowseNode( self.provCtx,
subFolderUrl[subFolderUrl.rfind("/")+1:len(subFolderUrl)], subFolderUrl,
self.depth + 1 )
+ return childNode, (), ()
+ else:
+ scriptUrl = self.rootUrl + "/" + params[0] + ".py"
+ # Creates an empty file
+ self.provCtx.sfa.writeFile( scriptUrl, EmptyInputStream() )
+ childNode = FileBrowseNode( self.provCtx, self, params[0] )
+ return childNode, (), ()
+ elif name == "Deletable":
+ self.provCtx.sfa.kill( self.rootUrl )
+ return True, (), ()
+ elif name == "Renamable":
+ if params is None or not params:
+ raise IllegalArgumentException( "invoke with Renamable
needs the name in params" )
+ newUrl = self.rootUrl[0:self.rootUrl.rfind("/")+1] + params[0]
+ self.provCtx.sfa.move( self.rootUrl, newUrl )
+ self.rootUrl = newUrl
+ self.name = params[0]
+ return self, (), ()
+ except Exception as e:
+ log.error( "DirBrowseNode.invoke error: " + lastException2String())
+ raise
+ return None, (), ()
+
+ def setValue( self, name, value ):
+ return None
+
+ def getValue( self, name ):
+ log.debug( "DirBrowseNode.getValue() called" )
+ return None
+
+ def hasMethod( self, name ):
+ return False
+
+ def hasProperty( self, name ):
+ return False
+
class ManifestHandler( XDocumentHandler, unohelper.Base ):
def __init__( self, rootUrl ):
@@ -821,7 +1133,7 @@ def penultimateElement( aStr ):
def lastElement( aStr):
return aStr[ aStr.rfind( "/" )+1:len(aStr)]
-class PackageBrowseNode( unohelper.Base, XBrowseNode ):
+class PackageBrowseNode( unohelper.Base, XBrowseNode, XPropertySet,
XInvocation ):
def __init__( self, provCtx, name, rootUrl ):
self.provCtx = provCtx
self.name = name
@@ -836,11 +1148,11 @@ class PackageBrowseNode( unohelper.Base, XBrowseNode ):
for i in items:
if len( i[1].pathes ) == 1:
browseNodeList.append(
- DirBrowseNode( self.provCtx, i[0], i[1].pathes[0] ))
+ DirBrowseNode( self.provCtx, i[0], i[1].pathes[0], 0 ))
else:
for j in i[1].pathes:
browseNodeList.append(
- DirBrowseNode( self.provCtx, i[0]+"."+lastElement(j),
j ) )
+ DirBrowseNode( self.provCtx, i[0]+"."+lastElement(j),
j, 0 ) )
return tuple( browseNodeList )
def hasChildNodes( self ):
@@ -853,6 +1165,45 @@ class PackageBrowseNode( unohelper.Base, XBrowseNode ):
log.debug( "DirBrowseNode getScript " + uri + " invoked" )
raise IllegalArgumentException( "PackageBrowseNode couldn't
instantiate script " + uri , self , 0 )
+ # XPropertySet
+
+ def getPropertyValue( self, name ):
+ ret = None
+ log.debug( "PackageBrowseNode.getPropertyValue called for " + name +
", returning " + str(ret) )
+ return ret
+
+ def setPropertyValue( self, name, value ):
+ log.debug( "PackageBrowseNode.setPropertyValue " + name + "=" +str(
value ) )
+
+ def getPropertySetInfo( self ):
+ log.debug( "PackageBrowseNode.getPropertySetInfo called" )
+ return None
+
+ # XInvocation
+
+ def getIntrospection( self ):
+ log.debug( "PackageBrowseNode.getIntrospection() called" )
+ return None
+
+ def invoke( self, name, params, outparamindex, outparams ):
+ log.debug( "PackageBrowseNode.invoke called for " + name + "," + str(
params ) + "," + str( outparamindex ) + "," + str( outparams ) )
+ return None, (), ()
+
+ def setValue( self, name, value ):
+ log.debug( "PackageBrowseNode.setValue" )
+ return None
+
+ def getValue( self, name ):
+ log.debug( "PackageBrowseNode.getValue" )
+ return None
+
+ def hasMethod( self, name ):
+ log.debug( "PackageBrowseNode.hasMethod" )
+ return False
+
+ def hasProperty( self, name ):
+ log.debug( "PackageBrowseNode.hasProperty" )
+ return False
@@ -898,7 +1249,7 @@ def expandUri( uri ):
return uri
#--------------------------------------------------------------
-class PythonScriptProvider( unohelper.Base, XBrowseNode, XScriptProvider,
XNameContainer):
+class PythonScriptProvider( unohelper.Base, XBrowseNode, XScriptProvider,
XNameContainer, XPropertySet, XInvocation):
def __init__( self, ctx, *args ):
if log.isDebugLevel():
mystr = ""
@@ -906,7 +1257,7 @@ class PythonScriptProvider( unohelper.Base, XBrowseNode,
XScriptProvider, XNameC
if len(mystr) > 0:
mystr = mystr +","
mystr = mystr + str(i)
- log.debug( "Entering PythonScriptProvider.ctor" + mystr )
+ log.debug( "Entering PythonScriptProvider.ctor with args " + mystr
)
doc = None
inv = None
@@ -952,7 +1303,7 @@ class PythonScriptProvider( unohelper.Base, XBrowseNode,
XScriptProvider, XNameC
self.provCtx.setPackageAttributes( mapPackageName2Path ,
rootUrl )
self.dirBrowseNode = PackageBrowseNode( self.provCtx,
LANGUAGENAME, rootUrl )
else:
- self.dirBrowseNode = DirBrowseNode( self.provCtx,
LANGUAGENAME, rootUrl )
+ self.dirBrowseNode = DirBrowseNode( self.provCtx,
LANGUAGENAME, rootUrl, 0 )
except Exception as e:
text = lastException2String()
@@ -971,14 +1322,9 @@ class PythonScriptProvider( unohelper.Base, XBrowseNode,
XScriptProvider, XNameC
def getType( self ):
return self.dirBrowseNode.getType()
- def getScript( self, uri ):
- log.debug( "DirBrowseNode getScript " + uri + " invoked" )
-
- raise IllegalArgumentException( "DirBrowseNode couldn't instantiate
script " + uri , self , 0 )
-
def getScript( self, scriptUri ):
try:
- log.debug( "getScript " + scriptUri + " invoked")
+ log.debug( "DirBrowseNode getScript " + scriptUri + " invoked")
storageUri = self.provCtx.getStorageUrlFromPersistentUrl(
self.provCtx.uriHelper.getStorageURI(scriptUri) );
@@ -998,6 +1344,36 @@ class PythonScriptProvider( unohelper.Base, XBrowseNode,
XScriptProvider, XNameC
log.error( text )
raise ScriptFrameworkErrorException( text, self, scriptUri,
LANGUAGENAME, 0 )
+ # XPropertySet
+
+ def getPropertyValue( self, name ):
+ return self.dirBrowseNode.getPropertyValue( name )
+
+ def setPropertyValue( self, name, value ):
+ return self.dirBrowseNode.setPropertyValue( name, value )
+
+ def getPropertySetInfo( self ):
+ return self.dirBrowseNode.getPropertySetInfo()
+
+ # XInvocation
+
+ def getIntrospection( self ):
+ return self.dirBrowseNode.getIntrospection()
+
+ def invoke( self, name, params, outparamindex, outparams ):
+ return self.dirBrowseNode.invoke( name, params, outparamindex,
outparams)
+
+ def setValue( self, name, value ):
+ return self.dirBrowseNode.setValue( name, value )
+
+ def getValue( self, name ):
+ return self.dirBrowseNode.getValue( name )
+
+ def hasMethod( self, name ):
+ return self.dirBrowseNode.hasMethod( name )
+
+ def hasProperty( self, name ):
+ return self.dirBrowseNode.hasProperty( name )
# XServiceInfo
def getSupportedServices( self ):