I wanted to write a modified version of the envelope creation macro described here, thinking that I would use Python to learn the OpenOffice.org API. OpenOffice.org developer documentation is horrible. Written by and for architecture astronauts, it is also not very complete for Python.
Background Reading
These are some useful places to start your education:
- Good, quick & practical overview
- Writing Macros
- Python as a macro language
- Python UNO Bridge
- Python overview and other links
- OpenOffice and Python
- Playing with the window toolkit
Debugging
The talk page tells you where to edit the file to get debugging on Linux. You have to restart OpenOffice to see the logging in the file, which is found by:
find ~/.openoffice* -name log.txt
So far I have found this log file to be utterly useless, even when on DEBUG
level. It seems that output does not go there, but if you do not catch exceptions then they come up in OpenOffice dialogues anyway, which is more useful.
So the first task was to be able to do simple error handling and debugging. Initially printf
into the document may be useful:
model = XSCRIPTCONTEXT.getDocument() text = model.Text cursor = text.createTextCursor() text.insertString(cursor, "START", 0) # do stuff text.insertString(cursor, "END", 0)
Message Boxes
After reading for hours and pasting together from various documentation sources, this seems like a reasonable, modern message box function:
import uno import traceback from com.sun.star.awt.MessageBoxButtons import (BUTTONS_OK, BUTTONS_OK_CANCEL, BUTTONS_YES_NO, BUTTONS_YES_NO_CANCEL, BUTTONS_RETRY_CANCEL, BUTTONS_ABORT_IGNORE_RETRY, DEFAULT_BUTTON_OK, DEFAULT_BUTTON_CANCEL, DEFAULT_BUTTON_RETRY, DEFAULT_BUTTON_YES, DEFAULT_BUTTON_NO, DEFAULT_BUTTON_IGNORE) def messageBox(message="", title="", msgtype="messbox", buttons=BUTTONS_OK, parentWin=None, rect=None): model = XSCRIPTCONTEXT.getDocument() context = XSCRIPTCONTEXT.getComponentContext() toolkit = context.ServiceManager.createInstanceWithContext("com.sun.star.awt.Toolkit", context) if not parentWin: parentWin = model.CurrentController.Frame.ContainerWindow if not rect: rect = uno.createUnoStruct('com.sun.star.awt.Rectangle') msgtypes = ("messbox", "infobox", "errorbox", "warningbox", "querybox") msgtype = msgtype.lower() if msgtype not in msgtypes: msgtype = "messbox" msgbox = toolkit.createMessageBox(parentWin, rect, msgtype, buttons, title, message) if msgbox: result = msgbox.execute() return result else: raise Exception("Unable to create message box")
Phew. Another option is to make a class, although I don’t like the constant-hacking done in that example. Some key gotchas are that import uno
must come first, you cannot import constants directly (or using *
), and you must supply a valid parent window.
So now on to getting the address(es) from the document…