This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch python-editing-embedding
in repository https://gitbox.apache.org/repos/asf/openoffice.git

commit 083057a93135e6f76e77d0b5cb3ddfc5554975a4
Author: Damjan Jovanovic <[email protected]>
AuthorDate: Fri Apr 24 06:00:43 2026 +0200

    Preliminary changes to PythonScriptProvider to allow
    creating, renaming, and deleting libraries and macros.
    
    Patch by: me
---
 main/scripting/source/pyprov/pythonscript.py | 213 +++++++++++++++++++++++++--
 1 file changed, 203 insertions(+), 10 deletions(-)

diff --git a/main/scripting/source/pyprov/pythonscript.py 
b/main/scripting/source/pyprov/pythonscript.py
index 1e9b3266a6..6bc3fadc8e 100644
--- a/main/scripting/source/pyprov/pythonscript.py
+++ b/main/scripting/source/pyprov/pythonscript.py
@@ -128,7 +128,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
@@ -173,6 +173,26 @@ def toIniName( str ):
         return str + ".ini"
     return str + "rc"
 
+class EmptyInputStream( unohelper.Base, XInputStream ):
+      def __init__( self ):
+          self.alive = 1
+
+      def closeInput(self):
+          pass
+
+      def readBytes( self, seq, n ):
+          return 0, ""
+
+      def readSomeBytes( self, seq, n ):
+          log.debug("readSomeBytes(" + str(seq) + "," + str(n) + ")")
+          return 0, ""
+
+      def skipBytes( self, n ):
+          pass
+
+      def available( self ):
+          return 0
+
 
 """ definition: storageURI is the system dependent, absolute file url, where 
the script is stored on disk
                 scriptURI is the system independent uri
@@ -582,7 +602,7 @@ class ScriptBrowseNode( unohelper.Base, XBrowseNode , 
XPropertySet, XInvocation,
 
 
 #-------------------------------------------------------
-class FileBrowseNode( unohelper.Base, XBrowseNode ):
+class FileBrowseNode( unohelper.Base, XBrowseNode, XPropertySet, XInvocation ):
     def __init__( self, provCtx, uri , name ):
         self.provCtx = provCtx
         self.uri = uri
@@ -619,13 +639,74 @@ 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 )
 
-class DirBrowseNode( unohelper.Base, XBrowseNode ):
-    def __init__( self, provCtx, name, rootUrl ):
+            log.debug("uri is " + 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
+
+    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))
+        if name == "Editable":
+            log.debug("Editable not implemented")
+        elif name == "Deletable":
+            self.provCtx.sfa.kill( self.uri )
+            return True
+        elif name == "Renamable":
+            newUrl = self.rootUrl[0:self.uri.rfind("/")+1] + params[0]
+            self.provCtx.sfa.move( self.uri, newUrl )
+            childNode = FileBrowseNode( self.provCtx, newUrl, params[0] )
+            return childNode
+        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
+
+
+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
@@ -642,7 +723,8 @@ class DirBrowseNode( unohelper.Base, XBrowseNode ):
                         FileBrowseNode( self.provCtx, i, 
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()
@@ -656,10 +738,91 @@ 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 = not self.provCtx.sfa.isReadOnly( self.rootUrl )
+            elif name == "Deletable":
+                ret = not self.provCtx.sfa.isReadOnly( self.rootUrl )
+            elif name == "Renamable":
+                ret = not self.provCtx.sfa.isReadOnly( self.rootUrl )
+
+            log.debug("rootUrl is " + 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))
+        if name == "Creatable":
+            if self.depth == 0:
+                log.debug( "depth is 0" )
+                subFolderUrl = self.rootUrl + "/" + params[0]
+                self.provCtx.sfa.createFolder( subFolderUrl )
+                log.debug( "created folder!" )
+                childNode = DirBrowseNode( self.provCtx, 
subFolderUrl[subFolderUrl.rfind("/")+1:len(subFolderUrl)], subFolderUrl, 
self.depth + 1 )
+                log.debug( "created childNode" )
+                return childNode
+            else:
+                log.debug( "depth is " + str(self.depth) )
+                scriptUrl = self.rootUrl + "/" + params[0] + ".py"
+                log.debug( "scriptUrl=" + scriptUrl )
+                try:
+                    self.provCtx.sfa.writeFile( scriptUrl, EmptyInputStream() )
+                except Exception as e:
+                    log.error( "Creatable error: " + lastException2String())
+                    raise
+                childNode = FileBrowseNode( self.provCtx, scriptUrl, params[0] 
+ ".py" )
+                log.debug( "returning" )
+                return childNode
+        elif name == "Deletable":
+            self.provCtx.sfa.kill( self.rootUrl )
+            return True
+        elif name == "Renamable":
+            newUrl = self.rootUrl[0:self.rootUrl.rfind("/")+1] + params[0]
+            self.provCtx.sfa.move( self.rootUrl, newUrl )
+            childNode = FileBrowseNode( self.provCtx, newUrl, params[0] )
+            return childNode
+        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 ):
@@ -842,11 +1005,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 ):
@@ -904,7 +1067,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 = ""
@@ -912,7 +1075,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
@@ -958,7 +1121,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()
@@ -1004,6 +1167,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 ):

Reply via email to