Difference between revisions of "Documentation/DevGuide/Scripting/Writing Macros"
(→Using the {{PRODUCTNAME}} API from macros: Added Python) |
(→Handling arguments passed to macros: Added Python case) |
||
Line 205: | Line 205: | ||
The ButtonPressHandler macros in the Highlight library of a {{PRODUCTNAME}} installation show how a macro can handle arguments. | The ButtonPressHandler macros in the Highlight library of a {{PRODUCTNAME}} installation show how a macro can handle arguments. | ||
+ | |||
+ | * '''Python''': The arguments are passed as parameters of the called function | ||
=== Creating dialogs from macros === | === Creating dialogs from macros === |
Revision as of 09:38, 31 May 2010
The HelloWorld macro
When the user creates a new macro in BeanShell or JavaScript, the default content of the macro is the HelloWorld. Here is what the code looks like for BeanShell:
import com.sun.star.uno.UnoRuntime; import com.sun.star.text.XTextDocument; import com.sun.star.text.XText; import com.sun.star.text.XTextRange; oDoc = XSCRIPTCONTEXT.getDocument(); xTextDoc = (XTextDocument) UnoRuntime.queryInterface(XTextDocument.class,oDoc); xText = xTextDoc.getText(); xTextRange = xText.getEnd(); xTextRange.setString( "Hello World (in BeanShell)" ); // BeanShell OpenOffice.org scripts should always return 0 return 0;
As BeanShell accepts typeless variables, the queryInterface instructions can be simplified.
Like OpenOffice.org Basic, BeanShell interprets pairs of get and set methods at UNO objects as object properties if they follow this pattern:
SomeType getSomeProperty() void setSomeProperty(SomeType aValue)
Using these facilities the above example can be simplified:
import com.sun.star.uno.UnoRuntime; import com.sun.star.text.XTextDocument; import com.sun.star.text.XText; import com.sun.star.text.XTextRange; oDoc = XSCRIPTCONTEXT.Document; xTextDoc = UnoRuntime.queryInterface(XTextDocument.class,oDoc); xText = xTextDoc.Text; xTextRange = xText.End; xTextRange.String = "Hello World (in BeanShell)"; // BeanShell OpenOffice.org scripts should always return 0 return 0;
Here is the same code in JavaScript:
importClass(Packages.com.sun.star.uno.UnoRuntime); importClass(Packages.com.sun.star.text.XTextDocument); importClass(Packages.com.sun.star.text.XText); importClass(Packages.com.sun.star.text.XTextRange); oDoc = XSCRIPTCONTEXT.getDocument(); xTextDoc = UnoRuntime.queryInterface(XTextDocument,oDoc); xText = xTextDoc.getText(); xTextRange = xText.getEnd(); xTextRange.setString( "Hello World (in JavaScript)" );
Here is the code for HelloWorld in Java:
import com.sun.star.uno.UnoRuntime; import com.sun.star.frame.XModel; import com.sun.star.text.XTextDocument; import com.sun.star.text.XTextRange; import com.sun.star.text.XText; import com.sun.star.script.provider.XScriptContext; public class HelloWorld { public static void printHW(XScriptContext xScriptContext) { XModel xDocModel = xScriptContext.getDocument(); // getting the text document object XTextDocument xtextdocument = (XTextDocument) UnoRuntime.queryInterface( XTextDocument.class, xDocModel); XText xText = xtextdocument.getText(); XTextRange xTextRange = xText.getEnd(); xTextRange.setString( "Hello World (in Java)" ); } }
A Python module may contain several callable functions. Like OpenOffice.org Basic, Python scripts do not need to query the interface of an API method. Like Basic, it interprets pairs of get and set methods at UNO objects as object properties if they follow the pattern:
SomeType getSomeProperty() void setSomeProperty(SomeType aValue)
Taking advantage of these facilities, here is the code for HelloWorld in Python:
def HelloPython( ): oDoc = XSCRIPTCONTEXT.getDocument() oText = oDoc.Text oTextRange = oText.End oTextRange.String = "Hello World (in Python)" return None
For comparison purposes, here is the minimal code for HelloWorld in Basic:
Sub HelloBasic Dim oDoc, oText, oTextRange ' default type : Variant oDoc = ThisComponent oText = oDoc.Text oTextRange = oText.End oTextRange.String = "Hello World (in Basic)" End Sub
The table below outlines some of the features of macro development in the different languages:
Language | Interpreted | Typeless | Editor | Debugger |
---|---|---|---|---|
Basic | Yes | Yes : Variant | Yes, colored syntax | Yes |
BeanShell | Yes | Yes | Yes | No |
JavaScript | Yes | Yes | Yes | Yes |
Java | No | No | No | No |
Python | Yes | Yes | No | No |
Using the OpenOffice.org API from macros
All BeanShell, JavaScript and Java macros are supplied with a variable of type com.sun.star.script.provider.XScriptContext which can be used to access the OpenOffice.org API. This type has three methods:
- com.sun.star.frame.XModel
getDocument( )
- Returns the
XModel
interface of the document for which the macro was invoked (see Using the Component Framework)
- com.sun.star.frame.XDesktop
getDesktop( )
- Returns the
XDesktop
interface for the application which can be used to access open document, and load documents (see Using the Desktop)
- com.sun.star.uno.XComponentContext
getComponentContext( )
- Returns the
XComponentContext
interface which is used to create instances of services (see Service Manager and Component Context)
Depending on the language the macro accesses the XScriptContext
type in different ways:
- BeanShell: Using the global variable
XSCRIPTCONTEXT
oDoc = XSCRIPTCONTEXT.getDocument();
- JavaScript: Using the global variable
XSCRIPTCONTEXT
oDoc = XSCRIPTCONTEXT.getDocument();
- Java: The first parameter passed to the macro method is always of type
XScriptContext
Xmodel xDocModel = xScriptContext.getDocument();
- Python: Using the global variable
XSCRIPTCONTEXT
oDoc = XSCRIPTCONTEXT.getDocument()
Handling arguments passed to macros
In certain cases arguments may be passed to macros, for example, when a macro is assigned to a button in a document. In this case the arguments are passed to the macro as follows:
- BeanShell: In the global
Object[]
variableARGUMENTS
event = (ActionEvent) ARGUMENTS[0];
- JavaScript: In the global
Object[]
variableARGUMENTS
event = ARGUMENTS[0];
- Java: The arguments are passed as an
Object[]
in the second parameter to the macro method
public void handleButtonPress( XScriptContext xScriptContext, Object[] args)
Each of the arguments in the Object[]
are of the UNO type Any. For more information on how the Any type is used in Java see Type Mappings.
The ButtonPressHandler macros in the Highlight library of a OpenOffice.org installation show how a macro can handle arguments.
- Python: The arguments are passed as parameters of the called function
Creating dialogs from macros
Dialogs which have been built in the Dialog Editor can be loaded by macros using the com.sun.star.awt.XDialogProvider API. The XDialogProvider
interface has one method createDialog()
which takes a string as a parameter. This string is the URL to the dialog. The URL is formed as follows:
vnd.sun.star.script:DIALOGREF?location=[application|document]
where DIALOGREF
is the name of the dialog that you want to create, and location is either application or document depending on where the dialog is stored.
For example if you wanted to load dialog called MyDialog, which is in a Dialog Library called MyDialogLibrary in the OpenOffice.org dialogs area of your installation then the URL would be:
vnd.sun.star.script:MyDialogLibrary.MyDialog?location=application
If you wanted to load a dialog called MyDocumentDialog which in a library called MyDocumentLibrary which is located in a document then the URL would be:
vnd.sun.star.script:MyDocumentLibrary.MyDocumentDialog?location=document
The following code shows how to create a dialog from a Java macro:
public XDialog getDialog(XScriptContext context) { XDialog theDialog; // We must pass the XModel of the current document when creating a DialogProvider object Object[] args = { context.getDocument() }; Object obj; try { obj = xmcf.createInstanceWithArgumentsAndContext( "com.sun.star.awt.DialogProvider", args, context.getComponentContext()); } catch (com.sun.star.uno.Exception e) { System.err.println("Error getting DialogProvider object"); return null; } XDialogProvider xDialogProvider = (XDialogProvider) UnoRuntime.queryInterface(XDialogProvider.class, obj); // Got DialogProvider, now get dialog try { theDialog = xDialogProvider.createDialog( "vnd.sun.star.script:MyDialogLibrary.MyDialog?location=application"); } catch (java.lang.Exception e) { System.err.println("Got exception on first creating dialog: " + e.getMessage()); } return theDialog; }
Compiling and Deploying Java macros
Because Java is a compiled language it is not possible to execute Java source code as a macro directly from within OpenOffice.org. The code must first be compiled and then deployed within a OpenOffice.org installation or document. The following steps show how to create a Java macro using the HelloWorld example code:
- Create a HelloWorld directory for your macro
- Create a HelloWorld.java file using the HelloWorld source code
- Compile the HelloWorld.java file. The following jar files from the program/classes directory of a OpenOffice.org installation must be in the classpath: ridl.jar, unoil.jar, jurt.jar
- Create a HelloWorld.jar file containing the HelloWorld.class file
- Create a parcel-descriptor.xml file for your macro
<?xml version="1.0" encoding="UTF-8"?> <parcel language="Java" xmlns:parcel="scripting.dtd"> <script language="Java"> <locale lang="en"> <displayname value="HelloWorld"/> <description> Prints "Hello World". </description> </locale> <functionname value="HelloWorld.printHW"/> <logicalname value="HelloWorld.printHW"/> <languagedepprops> <prop name="classpath" value="HelloWorld.jar"/> </languagedepprops> </script> </parcel>
The parcel-descriptor.xml file is used by the Scripting Framework to find macros. The functionname element indicates the name of the Java method which should be executed as a macro. The classpath element can be used to indicate any jar or class files which are used by the macro. If the classpath element is not included, then the directory in which the parcel-desciptor.xml file is found and any jar files in that directory will be used as the classpath. The necessary Java UNO classes are available automatically.
- Copy the HelloWorld directory into the share/Scripts/java directory of a OpenOffice.org installation or into the user/Scripts/java directory of a user installation. If you want to deploy the macro to a document you need to place it in a Scripts/java directory within the document zip file.
- If OpenOffice.org is running, you will need to restart it in order for the macro to appear in the Macro Selector dialog.
Calling a macro with the Scripting Framework
The service com.sun.star.script.provider.ScriptProvider exports interface XScriptProvider which offers method getScript( )
. This method returns an interface XScript which offers the method invoke( )
which will call the script with parameters if necessary.
The identity and location of the called script is contained in an URI, which follows a particular syntax.
Here are links to some code examples written by the community
- Java calling a Java script
- Java calling a Basic macro
- Basic macro calling a Python script
- Python script calling a Basic macro
Content on this page is licensed under the Public Documentation License (PDL). |