Ajout : Ajout d'une routine FileLen() retournant Currency plutôt que Long, le 30 Août 2018. |
Préambule
Les suites (Libre/Open)Office permettent le développement de macros en Basic, en Beanshell, en Javascript ou en Python. Leur exécution dans un document s’effectue sans considération du langage. Il est possible d’appeler une routine écrite en Basic depuis une fonction écrite en Python.
La routine Basic doit être soit personnelle, soit partagée, elle ne peut pas être stockée dans un document. La passerelle pyuno doit être présente.
Il est également possible d’appeler une routine écrite en Python depuis une fonction écrite en Basic.
La routine Python doit être soit personnelle, soit partagée, elle ne peut pas être stockée dans un document.
Appels Basic depuis Python
La manière d’appeler xRay, écrit en Basic, depuis Python fournit la base de nos exemples. Cet appel ne retourne aucune valeur :
Code : Tout sélectionner
import uno
from com.sun.star.uno import RuntimeException as _rtex
def xray(myObject):
try:
sm = uno.getComponentContext().ServiceManager
mspf = sm.createInstanceWithContext("com.sun.star.script.provider.MasterScriptProviderFactory", uno.getComponentContext())
scriptPro = mspf.createScriptProvider("")
xScript = scriptPro.getScript("vnd.sun.star.script:XrayTool._Main.Xray?language=Basic&location=application")
xScript.invoke((myObject,), (), ())
return
except:
raise _rtex("\nBasic library Xray is not installed", uno.getComponentContext())
Il est possible d’appeler les fonctions Basic comme
MsgBox,
InputBox ou
Print depuis Python, et d'exploiter leurs résultats. Des propriétés telles que
ComputerName, disponible seulement sous Windows, ou bien
UserName, disponible depuis LibreOffice 5.2, peuvent être étendues avec Python à toutes les plate-formes et généralisées aux produits OpenOffice et LibreOffice. La fonction Basic
FileLen(), limitée aux fichiers de 2 Gio max, peut retourner jusqu'à 856 484 Gio en recourant au langage Python. Les exemples qui suivent l’illustrent de manière volontairement simplifiée. Les macros en pièce jointe détaillent ces exemples plus précisement, en incluant par exemple une gestion des erreurs.
Deux bibliothèques _Python et _Basic contiennent chacune un module appelé devTools. Chaque module est organisé comme suit :
- _Python / devTools
- Computername(): str
- UserName(): str
- getScript ( .. ): ..script.provider.XScript
- MessageBox( .. ): int
- FileLen( .. ): int
- MsgBox( .. ): int
- InputBox( .. ): str
- Print( .. ):
- macros exemples
- _Basic /devTools
- ComputerName() As String
- UserName() As String
- getScript( .. ) As Object
- getURI( .. ) As String
- FileLen( .. ) As Currency
- MessageBox( .. ) As Integer
- _MsgBox( .. ) As Integer
- _InputBox(.. ) As String
- _Print ..
- macros exemples
Les macros en gras appellent leur homologues en Basic
ou en Python.
Il est nécessaire d’exporter la bibliothèque _Basic comme personnelle ou partagée pour lancer les macros exemples en Python.
Il faut exporter le module devTools de _Python comme personnel ou partagé pour lancer les macros exemples en Basic.
Les macros exemples Python et Basic s’exécutent depuis le menu
Outils – Macros… - Exécuter la Macro
Py2Bas.Figure.jpg
Si la bibliothèque _Python n’apparaît pas sous Unix, il convient d’installer la passerelle pyuno comme suit :
Appel de MsgBox, InputBox et Print depuis Python
Les programmes Basic ..
Code : Tout sélectionner
Private Function _MsgBox( msg As String, Optional options As Integer, Optional title As String ) As Integer
_MsgBox = MsgBox( msg, options, title )
End Function
Private Function _InputBox( prompt As String, Optional title As String, Optional defaultInput As String) As String
_InputBox = InputBox( prompt, title, defaultInput )
End Function
Private Sub _Print( msg As String )
Print msg
End Sub
.. sont appelés en Python comme suit :
Code : Tout sélectionner
def MsgBox(message: str, type_buttons_default=0, title='LibreOffice') -> int:
xScript = _getScript("_MsgBox")
res = xScript.invoke((message,type_buttons_default,title), (), ())
return res[0]
def InputBox(prompt: str, title='LibreOffice', defaultValue='') -> str:
xScript = _getScript("_InputBox")
res = xScript.invoke((prompt,title,defaultValue), (), ())
return res[0]
def Print(message: str):
xScript = getScript("_Print")
xScript.invoke((message), (), ())
L’attribut Private indique une fonction interne à ne pas utiliser en Basic, il n’a pas d’effet. Le caractère préfixe souligné (_) pratiqué en Python traduit la même convention de codage, il est également informatif. Les paramètres facultatifs en Basic sont gérés depuis Python à l’aide d’arguments nommés valorisés aux valeurs par défaut :
- types_buttons_default=0
- title='LibreOffice'
- defaultValue=''
Une fonction getScript() est responsable de la localisation et du chargement mémoire des scripts Basic :
Code : Tout sélectionner
from com.sun.star.script.provider import XScript
def getScript(script: str, library='_Basic', module='devTools') -> XScript:
sm = uno.getComponentContext().ServiceManager
mspf = sm.createInstanceWithContext("com.sun.star.script.provider.MasterScriptProviderFactory", uno.getComponentContext())
scriptPro = mspf.createScriptProvider("")
scriptName = "vnd.sun.star.script:"+library+"."+module+"."+script+"?language=Basic&location=application"
xScript = scriptPro.getScript(scriptName)
return xScript
Convention d’appel Python vers Basic
La documentation de l’interface
com.sun.star.script.provider.Xscript du
SDK nous fournit la description de trois
tuples paramètres d’appel de la méthode invoke() dans cet ordre :
- aParams (i.e. *args en Python) représente les paramètres passés positionnellement
- aOutParamIndex représente les indices des paramètres modifiés suite à l’appel
- aOutParam représente le(s) résultat(s) de l’appel
Les conventions d’appel du Python vers le Basic retournent un tuple résultat inversé qui se présente ainsi :
- (aOutParam, aOutParamIndex, aParams)
Le résultat des fonctions Basic MsgBox et InputBox est récupéré par :
Appels de MRI, ObjectInspector et X-Ray depuis Python
Le module _Python.devTools illustre par ailleurs comment appeler les extensions MRI, ObjectInspector et X-Ray respectivement écrites en Python, Basic et Java.
Appel de ComputerName, FileLen, MessageBox et UserName depuis Basic
Les programmes Python ..
Code : Tout sélectionner
def ComputerName():
import platform
return platform.node()
def FileLen(systemFilePath):
import os.path
return str(os.path.getsize(systemFilePath))
def UserName():
from getpass import getuser as userName
return userName()
def MessageBox( box_type: int, buttons: int, title: str, message: str) -> int :
desktop = uno.getDesktop()
frame = desktop.getCurrentFrame()
window = frame.getContainerWindow()
toolkit = window.getToolkit()
messagebox = toolkit.createMessageBox(window, box_type, buttons, title, message)
return messagebox.execute()
.. sont appelés en Basic comme suit :
Code : Tout sélectionner
Public Function ComputerName As String
Dim pyScript As Object
pyScript = getScript(getURI( "devTools.py$ComputerName", "Python", "user" ))
ComputerName = pyScript.invoke( Array(), Array(), Array() )
End Function ' ComputerName
Public Function FileLen(systemFilePath As String) As Currency
Dim pyScript As Object
pyScript = getScript(getURI( "devTools.py$FileLen", "Python", "user" ))
FileLen = pyScript.invoke( Array(systemFilePath), Array(), Array() )
End Function ' _Basic.devTools.FileLen()
Public Function UserName As String
Dim pyScript As Object
pyScript = getScript(getURI( "devTools.py$UserName", "Python", "user" ))
UserName = pyScript.invoke( Array(), Array(), Array() )
End Function ' UserName
Public Function MessageBox( box_type As Integer, _
buttons As integer, _
title As String, _
message As String _
) As Integer
Dim pyScript As Object ' com.sun.star.script.provider.XScript
pyScript = getScript(getURI( "devtools.py$MessageBox", "Python", "user" ))
MessageBox = pyScript.invoke( Array(Cint(box_type), Cint(buttons), Cstr(title), _
Cstr(message) ), Array(), Array() )
End Function
Les fonctions getScript() et getURI() sont responsables de la localisation et du chargement mémoire des scripts Python.
Sources
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.