De Basic a Python

From Apache OpenOffice Wiki
< ES‎ | Manuales‎ | GuiaAOO‎ | TemasAvanzados‎ | Macros‎ | Python
Jump to: navigation, search


Si te sientes incomodo usando StarBasic/OpenOffice Basic entonces estas en el lugar indicado para crear componentes personalizados de UNO, y cambiar los requisitos de Basic a Python.

En StarBasic, hay algunas funciones en el runtime provistas por atajos para hacer algo. Pero usando el puente Python-UNO, tendras que hacer estos procesos via el API.

Vamos a comenzar con los tutoriales de Python y regresar a aquí cuando hayas parendido más sobre el lenguaje de Python.

Ubicación de las macros

El editor de Macros

No existe un editor embedido para escribir o procesar tu código en Python. Pero puedes usar el editor de tu preferencia. Si no conoces alguno, Python incluye uno llamado IDLE.

Para más información checar la sección de Introducción a Python.

Pequeños ejemplos

Modulos de UNO

 import uno
 import unohelper

Script Context

El motor (runtime) de StarBasic esta integrado y vive dentro de la instancia de la suite. Asi que el contexto siempre sera el mismo que el de la suite. Pero el puente de Python-UNO actua como un cliente remoto tipo RPC. En ese momento, una instancia remota de Python tiene un contexto diferente que el de la instancia de la suite. Así que debes usar el componente en el contexto correcto para decirle a la fabrica multi componente que instancie el servicio.

En StarBasic, no tienes objetos coincidentes provistos.

En Python, las macros deben usar el modulo variable XSCRIPTCONTEXT que prove la interfaz com.sun.star.script.provider.XScriptContext.

Retorna el objeto actual del documento.
Retorna objetos invocados.
Retorna la instancia del servicio com.sun.star.frame.Desktop.
Retorna el contexto actual del componente que se este usando para decirle el contexto en que se encuentra.

Recuerda que, la variable XSCRIPTCONTEXT esta definida dentro del módulo y que no se incluye al momento de importar tus códigos.

Contexto del componente (Component Context)

En StarBasic, puedes obtener el contexto del componente de esta manera:

 ctx = GetDefaultContext()

Pero no es necesario que accedas a esta hasta que sea necesario, como el caso de obtener un singletons.

En Python, accedes al contexto del componente a traves del siguiente script de contexto.

 ctx = XSCRIPTCONTEXT.getComponentContext()

Necestas este valor para instanciar los servicios.

Gestor de servicios (Service Manager)

En StarBasic, puedes obtener el gestor de servicios (service manager) de esta manera:

 smgr = GetProcessServiceManger()

But not so many people having to access to it.

In Python, esta instancia obtiene mucho mayor valor ya que es la manera más directa y lograr que al instanciar servicios estos trabajen con el API.

 ctx = XSCRIPTCONTEXT.getComponentContext()
 smgr = ctx.getServiceManager()

Para instanciar los servicios necesitarás tanto el component context como el service manager.

Instanciando servicios

En StarBasic, puedes instanciar servicios usar las funciones pre-fabricadas, CreateUnoService:

 sfa = CreateUnoService("com.sun.star.ucb.SimpleFileAccess")

o con los argumentos inicializados:

 arg = com.sun.star.ui.dialogs.TemplateDescription.FILESAVE_SIMPLE
 file_picker = CreateUnoServiceWithArguments("com.sun.star.ui.dialogs.FilePicker", Array(arg))

En Python, debes trabajar con la interfaz com.sun.star.lang.XMultiComponentFactory así:

 ctx = XSCRIPTCONTEXT.getComponentContext()
 smgr = ctx.getServiceManager()
 sfa = smgr.createInstanceWithContext("com.sun.star.ucb.SimpleFileAccess", ctx)

Si necesitas inicializar la instancia, entonces usa el método createInstanceWithArgumentsAndContext:

 from com.sun.star.ui.dialogs.TemplateDescription import FILESAVE_SIMPLE
 file_picker = smgr.createInstanceWithArgumentsAndContext("com.sun.star.ui.dialogs.FilePicker", (FILESAVE_SIMPLE,) ctx)

o inicializalo despues de la instanciacion:

 file_picker = smgr.createInstanceWithContext("com.sun.star.ui.dialogs.FilePicker", ctx)
 file_picker.initialize((FILESAVE_SIMPLE,))

Servicios y constructores

En StarBasic, se puede llamar el constructor de esrvicios desde el módulo:

 shell_execute = com.sun.star.system.SystemShellExecute.create()

En Python, se debe instanciar con el método XMultiComponentFactory::createInstanceWithArgumentsAndContext con argumentos iniciales o intanciar despues de la creación de instancias. El constructor verifica los tipos antes de pasar los argumentos al método createInstanceWithArgumentsAndContext.

Documento actual

En StarBasic, la función ThisComponent provee el acceso al documento actual:

 doc = ThisComponent

El valor retornado depende de la ubicación del macro. Si el macro se encuentra dentro del documento, el resultado de la función ThisComponent es el documento mismo. Y si el macro esta almacenado dentro de Mis macros o Macros de OpenOffice el valor retornado es el modelo del documento activo en el frame (El documento que desde donde se llama el macro; o si se esta editando en el IDE, el último documento seleccionado), este da el mismo resultado que StarDesktop.getCurrentComponent().

En Python, se puede acceder al documento actual con el scrip de contexto:

 doc = XSCRIPTCONTEXT.getDocument()

Si el macro esta dentro del documento, el modelo es el mismo que el documento donde esta almacenado. Si el macro esta almacenado en Mis macros o Macros de OpenOffice, el modelo es el documento activo en el frame.

Función: StarDesktop

In StarBasic, StarDesktop runtime function is provided:

 desktop = StarDesktop()

In Python, you can get access to the desktop through the script context:

 desktop = XSCRIPTCONTEXT.getDesktop()

Instanciar Struct

In Basic, instance of struct can be instantiated in two ways:

 Dim a As New com.sun.star.awt.Point
 a = CreateUnoStruct("com.sun.star.awt.Point")

With Dim statement and New keyword, you can instantiate a struct or array of structs. Or CreateUnoStruct method provides the way to instantiate a struct at runtime. You can not initialize the instance at the creation, you have to set its value of members.

In Python, you can use the following ways to instantiate a struct. Import struct class and call it.

 from com.sun.star.awt import Point
 
 a = Point()         # instantiate with default values, X=0, Y=0
 b = Point(100, 200) # initialize with initial values, X=100, Y=200

Calling the class to create new instance of the struct, you can empty its arguments or you have to pass values for all fields. In other words, you can not pass insufficient number of arguments to initialize. And its order should be match with definition of the struct in its IDL. For example, instance of struct b having X=100 and Y=200 in the above piece of code.

You can initialize without to import the class of your target struct with uno.createUnoStruct function as follows:

 import uno
 
 a = uno.createUnoStruct("com.sun.star.awt.Point")
 b = uno.createUnoStruct("com.sun.star.awt.Point", 100, 200)

This makes the same result with the above example. The first parameter of the createUnoStruct method is the name of the struct to initialize. The following arguments are initial values for new instance.

Enum

In Basic, you can access to the module of the enum as follows:

 ITALIC = com.sun.star.awt.FontSlant.ITALIC

In Python, the following ways can be used:

 import uno
 from com.sun.star.awt.FontSlant import ITALIC
 ITALIC = uno.getConstantByName("com.sun.star.awt.FontSlant.ITALIC")
 ITALIC = uno.Enum("com.sun.star.awt.FontSlant", "ITALIC")

All of the way results the instance of uno.Enum class.

Constantes

En StarBasic, accedes a las constantes de esta manera:

 BOLD = com.sun.star.awt.FontWeight.BOLD

En Python, se hace de esta forma:

 import uno
 
 from com.sun.star.awt.FontWeight import BOLD
 Negrillas = uno.getConstantsByName("com.sun.star.awt.FontWeight.BOLD")

Sequence

The sequence is sequential value of the same type. In StarBasic, array is used. In Python, tuple is chosen to represent UNO's sequence. Note, list is not allowed to pass as sequence value.

Boolean

In Python, True or False.

Cadenas (String)

Las cadenas (string) en Python pueden obtener hasta 64K bytes. Si tienes que escribir caracteres no Ascii de 7 bit en tu código, inserta magic comment en el encabezado de tu código. Esta es una instrucción estandar del lenguaje Python.

 # -*- coding: utf_8 -*-

Consulta la documentación de Python para mas información sobre esto.

Char

There is no dedicated value for char type in StarBasic.

In Python, uno.Char class is defined for char type.

 import uno
 c = uno.Char("a")

Secuencia de Byte

The byte sequence is sequence of byte type.

In Basic, array of byte is used to represent it.

In Python, it is represented by str wrapped by uno.ByteSequence class. If you takes some byte sequences from UNO, they are the instance of uno.ByteSequence. If you need to get real value of them, refer its value instance variable.

Excepciones

In StarBasic, you get thrown exception as some error. And On Error statement is used to catch it.

 Sub ErrorExample
   On Error GoTo Handler
   ' ... error
   Exit Sub
   Handler: 
 End Sub

And you can not throw any exceptions from StarBasic.

In Python, the exception thrown in UNO world can be treated as normal Python's exception. Here is an example:

 from com.sun.star.container import IndexOutOfBoundsException
 try:
     obj.getByIndex(100) # raises IndexOutOfBoundsException
 except IndexOutOfBoundsException as e:
     print(e)

If getByIndex method raises IndexOutOfBoundsException, it can be caught in except statement because all exceptions inherit Python's Exception class.

And also you can throw UNO's exception from your Python code as follows:

 from com.sun.star.uno import RuntimeException
 raise RuntimeException("Some message", None)

Valores vacios

In Basic, there are some situations to meet variables that they do not contain any value (this is not correct). Null, empty, missing, nothing and so on.

In Python, None is used. If a method defined as void return value in its IDL, it results None if you call it. If you need to pass invalid interface as an argument for the method that takes some interface, pass None for it. The result of this behavior is fully dependent to the implementation of the method.

Receptores (Listeners) e Interfaces

In StarBasic, you can create new listener using CreateUnoListener runtime function with some subroutines or functions.

 Sub Add
 
   d = CreateUnoDialog(DialogLibraries.Standard.Dialog1)
   listener = CreateUnoListener("ActionListener", "com.sun.star.awt.XActionListener")
   d.getControl("CommandButton1").addActionListener(listener)
   d.execute()
   d.dispose()
 
 End Sub
 
 Sub ActionListener_actionPerformed(ev)
 
 End Sub
 
 Sub ActionListener_disposing(ev)
 
 End Sub

In Python, you have define your own class with desired interfaces. With helper class, you can define easily as follows:

 import unohelper
 
 from com.sun.star.awt import XActionListener
 
 class ActionListener(unohelper.Base, XActionListener):
 
     def __init__(self):
         pass
 
     def disposing(self, ev):
         pass
 
     def actionPerformed(self, ev):
         pass

unohelper.Base class provides required interface for UNO components.

Containers

In StarBasic, container object provides the way to access to its contents in sequentially.

In Python, there is no shortcut provided.

If you need to access to elements of indexed container, use range function to generate sequential indexes.

 for i in range(container.getCount()):
     obj = container.getByIndex(i)

URL y Rutas de sistema

If you work with a file stored in your local file system, you have to get its corresponding URL.

In StarBasic, ConvertToURL runtime function is prepared for this task. And there is ConvertFromURL runtime function for reverse conversion.

In Python, the following functions are defined in uno module for such task.

 import uno
 
 path = "/home/foo/Documents/file.odt"
 url = uno.sytemPathToFileUrl(path)
 path = uno.fileUrlToSystemPath(url)

Argumentos y valor de Retorno

In StarBasic, mode of the first argument of parseStrict method is "inout" in the following code:

 aURL = CreateUnoStruct("com.sun.star.util.URL")
 aURL.Complete = ".uno:Paste"
 CreateUnoService("com.sun.star.util.URLTransformer").parseStrict(aURL)

The content of aURL variable is updated after calling the method.

In Python, out mode parameter is returned as part of return value.

 from com.sun.star.util import URL
 
 aURL = URL()
 aURL.Complete = ".uno:Paste"
 dummy, aURL = smgr.createInstanceWithContext("com.sun.star.util.URLTransformer", ctx).parseStrict(aURL)
 # Definition of com.sun.star.util.XURLTransformer::parseStrict method: 
 # void parseStrict([inout] com.sun.star.util.URL aURL);

If a method has out mode in its parameters, its return is always tuple that contains original return value and values for out parameters.

Here is a potential example:

 # boolean getSomeValue([in] string aName, [out] short aNum, [inout] long aNum2);
 result, num, num2 = obj.getSomeValue("foo", 100, 200)

In the above example, result variable takes original return value, num takes output value for second parameter and num2 takes output value for third parameter. The method takes 100 as the second parameter but it is not used as input of value. No entry in returned tuple for in mode parameter.

Funciones para ser Ejecutadas

In Basic, you can not choose routines to be executed by users.

In Python, define g_exportedScripts variable that contains tuple of callable in your macro file.

 def func_a():
 pass
 
 def func_b():
 pass
 
 def func_hidden():
 pass # not shown in the UI
 
 g_exportedScripts = func_a, func_b

In the above code, func_hidden is not shown in execution dialog of macros.

Importando modulos

Dialogos

Message Box

Input Box

Personal tools