There are two primary methods for controlling OOo from a macro. The more versatile solution is to obtain the internal UNO objects and then directly manipulate them. Speaking technically, you obtain the data model and manipulate it directly. This method provides a lot of control, but you must understand a great deal about the different services and interfaces. The second solution, which requires very little understanding of the OOo internals, is to use a UNO dispatcher. The dispatcher accepts a command such as ".uno:Undo" and takes care of the rest of the details. The frame (remember that there is a desktop and there are frames ) provides the required dispatchers to perform the work. A dispatcher is basically a wrapper (in the sense of object-oriented programming techniques) for the internal functionality.
Warning | Although the macro recorder included with OOo uses a dispatcher for all tasks , the lead developers on OOo consistently say that the dispatch API can change without notification between OOo versions. Therefore, use the recorder when you must, and only when you must. |
Although direct control using UNO services provides the most control and versatility, some operations are much easier to perform using the dispatcher; sometimes a dispatcher is the only way to accomplish a task. For example, the dispatcher is the best solution for handling the clipboard. Even the macro recorder performs almost all tasks using a dispatcher.
Three things are required to accomplish tasks using a dispatcher: (1) the command to dispatch, (2) arguments that control the dispatch, and (3) an object capable of performing the dispatch (a dispatch provider, which is usually a frame). Each document has a controller that, loosely speaking, acts as the interface between the outside world and the document. For example, use the current controller to select text, find the current cursor location, or determine which sheet is active in a spreadsheet. The current controller can also return the frame of the document, which supports the dispatch command. OOo 1.1.0 introduces a dispatch helper service that greatly simplifies the use of dispatches (see Listing 2 ).
oDispHelper = createUnoService("com.sun.star.frame.DispatchHelper")
The dispatch helper implements the function executeDispatch, which implements most of the functionality required to perform a dispatch. Table 1 contains a list of the arguments supported by the executeDispatch method.
Argument | Description |
---|---|
XDispatchProvider | Dispatch provider that performs the dispatch. |
URL String | The command to dispatch, as a string. |
Target Frame String | Identifies the frame that will receive the dispatch. Use an empty string or "_self " to specify the current frame (any other value is invalid). |
long | Optional search flags that indicate how to find the target frame. Use zero or blank (see Listing 3 ), because it is not supported. |
PropertyValue() | Optional arguments that are dependent on the implementation. |
Sub NewUndo Dim oDispHelper as object Dim oProvider As Object oProvider = ThisComponent.CurrentController.Frame oDispHelper = createUnoService("com.sun.star.frame.DispatchHelper") oDispHelper.executeDispatch(oProvider,".uno:Undo", "", , Array()) End Sub
While executing a dispatch, as discussed here, you cannot dispatch a command to a frame based on its name -either leave the target frame empty or enter "_self". It is also, therefore, not important to use anything other than zero, or omit the argument completely, for the search flag. Attempting to specify another frame results in a run-time error (it seems silly to me that the arguments exist if they are not usable).
The dispatch commands have both a name and a number, called a "slot." A dispatch can be made based on this slot number (see Listing 4 ). The Tools library contains a subroutine called DispatchSlot, which performs a dispatch based on a slot number alone. The macro recorder included with OOo 1.1.0 produces macros that accomplish all tasks with a dispatcher that uses slots. One of the lead developers on OOo indicated that the slot numbers are more likely to change between OOo versions than the dispatch names .
'Include this library to use the DispatchSlot command. GlobalScope.BasicLibraries.LoadLibrary("Tools") DispatchSlot(5301) 'Load the About dialog, same as ".uno:About"
Tip | You cannot call a routine in a library unless the library is loaded. You can load a library manually from the Macro dialog and you can load it using the LoadLibrary command as shown in Listing 4. The Tools library included with OOo contains the DispatchSlot subroutine. |
Some dispatch commands require arguments. The examples in Listing 5 perform a dispatch with arguments. The GoToCell command needs to know which cell to go to. This macro moves the current cursor to the cell B3 in a spreadsheet document.
Dim args2(0) as new com.sun.star.beans.PropertyValue args2(0).Name = "ToPoint" args2(0).Value = "$B" ' position to B3 Dim oDispHelper as object Dim oProvider As Object oProvider = ThisComponent.CurrentController.Frame oDispHelper = createUnoService("com.sun.star.frame.DispatchHelper") oDispHelper.executeDispatch(oProvider, ".uno:GoToCell", "", 0, args2())
OOo supports numerous dispatch commands. To see the latest list, which includes the current slot numbers, start at http://frameworkopenoffice.org/servlets/ProjectDocumentList and follow the links under the section "Framework core " and then "Documentation." Although I intended to provide a link to the file that contains the list, the link changed three times while I was writing this book.
To obtain a list of the dispatch commands with a listing of the supported properties, start at http://api.openoffice.org/servlets/ProjectDownloadList and download the file "slots.sxc" or try http://api.openoffice.org/servlets/ProjectDownloadList?action=download&dlID=12 directly.
Tip | Macros that you expect to have a long life should access the UNO objects directly if possible, rather than using dispatch statements. This method will avoid problems if the dispatch commands or slots change; UNO objects have greater longevity as essentially fixed elements of the OOo implementation. For short- term macros, however, it makes little difference. |