Hi Our Python script/macro integration is the worst of all our scripting languages. While StarBasic, BeanShell and Javascript can be created, edited and debugged within OpenOffice, Python can only be run. Python scripts can only be embedded into documents manually, by unzipping the OpenDocument file, copying in the scripts, and then zipping it back up ( https://wiki.openoffice.org/wiki/Python_as_a_macro_language).
Also Python works as badly in LO as it does with us. On bugs 60849 and 75132 I started trying to improve that, so Python scripts can be embedded into documents, and created/deleted/renamed within OpenOffice, and have made considerable progress. The ScriptProvider implementations for Java, Javascript, and BeanShell are within main/scripting/java/org, while Python one is in main/scripting/source/pyprov/pythonscript.py. The fact that Java implementation had much more code, including UI dialogs, first led me to try adding a script provider for Python in there. But when I did, I realized that won't work well, as invoke() is called in Java but must reach Python, requiring a double UNO call: C++ -> Java -> Python, which would be bad for performance. Also further investigation led me to realize the UI dialogs in the Java code are unused, all the UI elements come from main/cui/source/dialogs/scriptdlg.cxx instead. What finally convinced me to go back to improving the Python ScriptProvider is that the scripting framework specifications ( https://www.openoffice.org/specs/scripting_framework/index.html) explained how each language ScriptProvider is supposed to operate independently, and can nest its XBrowseNodes in whatever way best represents that language's scripts. The Java/JavaScript/BeanShell ScriptProviders uses parcel-descriptor.xml files to define the scripts, using an entire file as a script, and have a nesting of root -> library -> macro. Python is completely different, with no parcel-descriptor.xml, instead of complete files it is the functions in the .py files that are scripts, and the nesting is root -> library -> macro -> function. Eventually by comparing Java's XBrowseNode implementations with Python's, I saw Java's XBrowseNode was implementing XPropertySet and XInvocation on some of its nodes, while Python wasn't. When I added those to Python, and handled the "Creatable", "Editable" and other properties, the macro dialog started enabling buttons that were previously greyed out, but only on existing libraries, I couldn't create new libraries from root sources like the document, and really struggled to understand why. I thought it was a lost cause and was about to give up, but then an idea came to me. I realized that PythonScriptProvider itself implement XBrowseNode, and forwards method calls to XBrowseNode methods to its DirBrowseNode field, and reasoned that just like XPropertySet and XInvocation had to be added to DirBrowseNode, they might have to be added to the PythonScriptProvider too, and also forwarded to that DirBrowseNode field. When I did that, top-level sources like the document started allowing creation of libraries within them :-). Implementing XPropertySet and XInvocation on FileBrowseNode even got macro creation to work, successfully embedding (admittedly empty) .py files into documents :-) :-). A number of issues however were discovered: - All macro operations (creating, renaming, deleting) give false errors saying they failed, but actually succeed, you need to close and re-open the macro dialog to see the changes. I suspect this is a bug in the Python UNO bridge. - Creating libraries inside documents is completely broken on Windows, the UI buttons stay greyed out. This is some kind of a permission issue when calling isReadOnly() on the SimpleFileAccess interface for the document. - The documentation for Python development leaves a lot to be desired. It took me forever to find how to create the UNO Any type. Handling "out" parameters is completely different to other languages. The best document is actually https://www.openoffice.org/udk/python/python-bridge.html which is also completely hidden and I only found it by accident. Apart from those issues, we now need to add Python editing in OpenOffice for it to be really useful. Still considering what to do there. The scripts embedded in documents especially, need to be accessed through a custom URL and our UCB system, and won't be easily accessible to external applications. There is some code in main/scripting/java that allows NetBeans to edit BeanShell files, but might require OpenOffice to be started with an UNO listening port (scripting/java/org/openoffice/idesupport/localoffice/LocalOfficeImpl.java), something that won't fly in production. Developing OpenOffice in Python is actually remarkably simple and pleasant, It is a first-class UNO language, capable of both consuming UNO components, and implementing them. Python is probably too slow for serious development, but given how Python components don't need compiling to redeploy changes, just OpenOffice restart, it is much faster to develop with. My preliminary changes have been pushed to the python-editing-embedding branch. There is no need to build, you can just copy main/scripting/source/pyprov/pythonscript.py over the one in an existing OpenOffice instance, it's in the same directory as the main soffice[.exe] executable. Then start OpenOffice, create or open a document, and compare Tools -> Macros -> Organize Macros -> Python before and after. Creating, renaming, and deleting Python libraries and macros should work (to some degree, on *nix at least), although with false errors afterwards (close and reopen the dialog to see the changes). You can also run OpenOffice with the environment variables PYSCRIPT_LOG_LEVEL=DEBUG PYSCRIPT_LOG_STDOUT=1 set, so that the Python ScriptProvider logs debugging info to standard output. (It would be best to change this to the XLogger logging framework eventually.) Regards Damjan
