Difference between revisions of "UNO component packaging"
(→See also: link to the Extensions chapter of the Developers Guide) |
m (code prettied; rewrote and corrected note about importing classes) |
||
Line 5: | Line 5: | ||
=Python loader= | =Python loader= | ||
− | Python loader is not able load classes | + | The Python loader is not able load classes that are not it its own path. Thus it's necessary to copy any classes or modules you will use into the OPenOffice Python lib directory, and it may be necessary to restart OOo before they are picked up. |
=Sample Python component= | =Sample Python component= | ||
Line 12: | Line 12: | ||
We will use my sample ''Wavelet'' class which replaces space with non breaking space before the Czech prepositions. Put the following code in the ''Wavelet.py'' file. | We will use my sample ''Wavelet'' class which replaces space with non breaking space before the Czech prepositions. Put the following code in the ''Wavelet.py'' file. | ||
− | < | + | <source lang=python> |
+ | |||
import uno | import uno | ||
import unohelper | import unohelper | ||
import string | import string | ||
− | |||
from com.sun.star.task import XJobExecutor | from com.sun.star.task import XJobExecutor | ||
− | + | ||
class Wavelet( unohelper.Base, XJobExecutor ): | class Wavelet( unohelper.Base, XJobExecutor ): | ||
def __init__( self, ctx ): | def __init__( self, ctx ): | ||
Line 41: | Line 41: | ||
except: | except: | ||
pass | pass | ||
− | </ | + | </source> |
Line 48: | Line 48: | ||
You have to tell the OpenOffice.org what is the main class of your component. Put the following code at the end of your ''Wavelet.py'' file. | You have to tell the OpenOffice.org what is the main class of your component. Put the following code at the end of your ''Wavelet.py'' file. | ||
− | < | + | <source lang=python> |
g_ImplementationHelper = unohelper.ImplementationHelper() | g_ImplementationHelper = unohelper.ImplementationHelper() | ||
g_ImplementationHelper.addImplementation( | g_ImplementationHelper.addImplementation( | ||
Line 54: | Line 54: | ||
"name.vojta.openoffice.Wavelet", | "name.vojta.openoffice.Wavelet", | ||
("com.sun.star.task.Job",),) | ("com.sun.star.task.Job",),) | ||
− | </ | + | </source> |
Line 73: | Line 73: | ||
The header of this file should contain: | The header of this file should contain: | ||
− | < | + | <source lang=xml> |
<?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||
<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" | <oor:component-data xmlns:oor="http://openoffice.org/2001/registry" | ||
Line 80: | Line 80: | ||
<node oor:name="AddonUI"> | <node oor:name="AddonUI"> | ||
− | </ | + | </source> |
Line 91: | Line 91: | ||
This menu will be visible in the OpenOffice.org Writer only. | This menu will be visible in the OpenOffice.org Writer only. | ||
− | < | + | <source lang=xml> |
<node oor:name="OfficeMenuBar"> | <node oor:name="OfficeMenuBar"> | ||
<node oor:name="name.vojta.openoffice.Wavelet" oor:op="replace"> | <node oor:name="name.vojta.openoffice.Wavelet" oor:op="replace"> | ||
Line 124: | Line 124: | ||
</node> | </node> | ||
</node> | </node> | ||
− | + | </node> | |
− | </ | + | </source> |
Line 134: | Line 134: | ||
'''Note:''' You can't rename the toolbar. It's due to the backwards compatibility with the 1.1.x version. | '''Note:''' You can't rename the toolbar. It's due to the backwards compatibility with the 1.1.x version. | ||
− | < | + | <source lang=xml> |
<node oor:name="OfficeToolBar"> | <node oor:name="OfficeToolBar"> | ||
<node oor:name="name.vojta.openoffice.Wavelet" oor:op="replace"> | <node oor:name="name.vojta.openoffice.Wavelet" oor:op="replace"> | ||
Line 157: | Line 157: | ||
</node> | </node> | ||
</node> | </node> | ||
− | + | </node> | |
− | </ | + | </source> |
Line 167: | Line 167: | ||
'''Note:''' %origin% is the UNO component package. We will explain it later. | '''Note:''' %origin% is the UNO component package. We will explain it later. | ||
− | < | + | <source lang=xml> |
<node oor:name="Images"> | <node oor:name="Images"> | ||
<node oor:name="name.vojta.openoffice.Wavelet.image1" oor:op="replace"> | <node oor:name="name.vojta.openoffice.Wavelet.image1" oor:op="replace"> | ||
Line 182: | Line 182: | ||
</node> | </node> | ||
</node> | </node> | ||
− | + | </node> | |
− | </ | + | </source> |
Line 190: | Line 190: | ||
Close all opened sections. | Close all opened sections. | ||
− | < | + | <source lang=xml> |
</node> | </node> | ||
− | + | </oor:component-data> | |
− | </oor:component-data> | + | </source> |
− | </ | + | |
=UNO component package= | =UNO component package= | ||
Line 202: | Line 201: | ||
You can pack our sample package with the following command: | You can pack our sample package with the following command: | ||
− | < | + | <source lang=bash> |
zip -r Wavelet.uno.zip Addons.xcu Wavelet.py images | zip -r Wavelet.uno.zip Addons.xcu Wavelet.py images | ||
− | </ | + | </source> |
The final ''Wavelet.uno.zip'' package should contain these files: | The final ''Wavelet.uno.zip'' package should contain these files: | ||
− | < | + | <source lang=bash> |
Wavelet.uno.zip | Wavelet.uno.zip | ||
Addons.xcu | Addons.xcu | ||
Line 213: | Line 212: | ||
images/WaveletBig.bmp | images/WaveletBig.bmp | ||
images/WaveletSmall.bmp | images/WaveletSmall.bmp | ||
− | </ | + | </source> |
'''Note:''' The ''%origin%'' is ''Wavelet.uno.zip'', thus the ''%origin%/images/WaveletBig.bmp'' points to the ''WaveletBig.bmp'' file in your ''Wavelet.uno.zip'' file. | '''Note:''' The ''%origin%'' is ''Wavelet.uno.zip'', thus the ''%origin%/images/WaveletBig.bmp'' points to the ''WaveletBig.bmp'' file in your ''Wavelet.uno.zip'' file. | ||
==Installation== | ==Installation== | ||
− | You can install your UNO component with the | + | You can install your UNO component with the Extension manager (somewhere in the ''Tools'' menu) or with the ''unopkg'' tool. |
− | < | + | <source lang=bash> |
/opt/openoffice.org1.9.103/program/unopkg add Wavelet.uno.zip | /opt/openoffice.org1.9.103/program/unopkg add Wavelet.uno.zip | ||
− | </ | + | </source> |
==Uninstallation== | ==Uninstallation== | ||
− | You can uninstall your UNO component with the | + | You can uninstall your UNO component with the Extension manager (somewhere in the ''Tools'' menu) or with the ''unopkg'' tool. |
− | < | + | <source lang=bash> |
/opt/openoffice.org1.9.103/program/unopkg remove Wavelet.uno.zip | /opt/openoffice.org1.9.103/program/unopkg remove Wavelet.uno.zip | ||
− | </ | + | </source> |
=Python component testing= | =Python component testing= | ||
Line 236: | Line 235: | ||
Append the following code at the end of the ''Wavelet.py'' file. | Append the following code at the end of the ''Wavelet.py'' file. | ||
− | < | + | <source lang=python> |
if __name__ == "__main__": | if __name__ == "__main__": | ||
import os | import os | ||
Line 261: | Line 260: | ||
wavelet = Wavelet( ctx ) | wavelet = Wavelet( ctx ) | ||
wavelet.trigger( () ) | wavelet.trigger( () ) | ||
− | </ | + | </source> |
Line 268: | Line 267: | ||
To test your UNO component, just run your ''Wavelet.py'' in the Python interpreter. | To test your UNO component, just run your ''Wavelet.py'' in the Python interpreter. | ||
− | < | + | <source lang=bash> |
/opt/openoffice.org1.9.103/program/python ./Wavelet.py | /opt/openoffice.org1.9.103/program/python ./Wavelet.py | ||
− | </ | + | </source> |
==Resume== | ==Resume== |
Revision as of 18:30, 8 March 2008
Contents
Python UNO component
This page shows you how to pack and deploy already written UNO component. I'm using my Wavelet class as an example of a very simple component.
More detailed info is in the [Developers Guide].
Python loader
The Python loader is not able load classes that are not it its own path. Thus it's necessary to copy any classes or modules you will use into the OPenOffice Python lib directory, and it may be necessary to restart OOo before they are picked up.
Sample Python component
Wavelet class
We will use my sample Wavelet class which replaces space with non breaking space before the Czech prepositions. Put the following code in the Wavelet.py file.
import uno import unohelper import string from com.sun.star.task import XJobExecutor class Wavelet( unohelper.Base, XJobExecutor ): def __init__( self, ctx ): self.ctx = ctx def trigger( self, args ): desktop = self.ctx.ServiceManager.createInstanceWithContext( "com.sun.star.frame.Desktop", self.ctx ) doc = desktop.getCurrentComponent() try: search = doc.createSearchDescriptor() search.SearchRegularExpression = True search.SearchString = "\\<(k|s|v|z|o|u|i|a) " found = doc.findFirst( search ) while found: found.String = string.replace( found.String, " ", u"\xa0" ) found = doc.findNext( found.End, search) except: pass
Wavelet class registration
You have to tell the OpenOffice.org what is the main class of your component. Put the following code at the end of your Wavelet.py file.
g_ImplementationHelper = unohelper.ImplementationHelper() g_ImplementationHelper.addImplementation( Wavelet, "name.vojta.openoffice.Wavelet", ("com.sun.star.task.Job",),)
Component integration
Icons
You can create your own icons for the Menu item or the Toolbar button. The easiest way is to create two true color BMP files - the first one should be 26×26 and the second one should be 16×16.
If you want to use alpha (transparent color), use #FF00FF (RGB) color.
This possibility is optional and you're not forced to create icons.
Addons.xcu
Component integration configuration is in the Addons.xcu file.
Header
The header of this file should contain:
<?xml version="1.0" encoding="UTF-8"?> <oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:name="Addons" oor:package="org.openoffice.Office"> <node oor:name="AddonUI">
Office Menu Bar
Following part creates new menu item Czech (or Cestina, depends on the UI language) and the Wavelet menu item.
This menu item is associated with the name.vojta.openoffice.Wavelet?execute URL. It means, that when you click on the menuitem, Wavelet.trigger method will be executed with the execute as an argument.
This menu will be visible in the OpenOffice.org Writer only.
<node oor:name="OfficeMenuBar"> <node oor:name="name.vojta.openoffice.Wavelet" oor:op="replace"> <prop oor:name="Title" oor:type="xs:string"> <value/> <value xml:lang="en-US">Czech</value> <value xml:lang="cs">Cestina</value> </prop> <prop oor:name="Target" oor:type="xs:string"> <value>_self</value> </prop> <prop oor:name="ImageIdentifier" oor:type="xs:string"> <value/> </prop> <node oor:name="Submenu"> <node oor:name="m1" oor:op="replace"> <prop oor:name="URL" oor:type="xs:string"> <value>service:name.vojta.openoffice.Wavelet?execute</value> </prop> <prop oor:name="Title" oor:type="xs:string"> <value/> <value xml:lang="en-US">Wavelet</value> <value xml:lang="cs">Vlnka</value> </prop> <prop oor:name="Target" oor:type="xs:string"> <value>_self</value> </prop> <prop oor:name="Context" oor:type="xs:string"> <value>com.sun.star.text.TextDocument</value> </prop> </node> </node> </node> </node>
Office Toolbar
Following part creates new toolbar (with name Add-on 1, Add-on 2, …) and one button. This button is associated with the name.vojta.openoffice.Wavelet?execute URL. It means that the Wavelet.trigger method will be executed when you click on the button on the toolbar. execute will be passed as an argument.
Note: You can't rename the toolbar. It's due to the backwards compatibility with the 1.1.x version.
<node oor:name="OfficeToolBar"> <node oor:name="name.vojta.openoffice.Wavelet" oor:op="replace"> <node oor:name="m1" oor:op="replace"> <prop oor:name="URL" oor:type="xs:string"> <value>service:name.vojta.openoffice.Wavelet?execute</value> </prop> <prop oor:name="ImageIdentifier" oor:type="xs:string"> <value/> </prop> <prop oor:name="Title" oor:type="xs:string"> <value/> <value xml:lang="en-US">Wavelet</value> <value xml:lang="cs">Vlnka</value> </prop> <prop oor:name="Target" oor:type="xs:string"> <value>_self</value> </prop> <prop oor:name="Context" oor:type="xs:string"> <value>com.sun.star.text.TextDocument</value> </prop> </node> </node> </node>
Icons
You can associate your icons with any URL. We will associate our icons with name.vojta.openoffice.Wavelet?execute URL. It means that all controls (menu item, button, …) associated with the same URL will use these icons.
Note: %origin% is the UNO component package. We will explain it later.
<node oor:name="Images"> <node oor:name="name.vojta.openoffice.Wavelet.image1" oor:op="replace"> <prop oor:name="URL"> <value>service:name.vojta.openoffice.Wavelet?execute</value> </prop> <node oor:name="UserDefinedImages"> <prop oor:name="ImageSmallURL" oor:type="xs:string"> <value>%origin%/images/WaveletSmall.bmp</value> </prop> <prop oor:name="ImageBigURL" oor:type="xs:string"> <value>%origin%/images/WaveletBig.bmp</value> </prop> </node> </node> </node>
Close all opened sections.
</node> </oor:component-data>
UNO component package
UNO component package is a simple ZIP file. Obviously it contains the Addons.xcu file, images directory with icons and the Python component implementation.
Packing
You can pack our sample package with the following command:
zip -r Wavelet.uno.zip Addons.xcu Wavelet.py images
The final Wavelet.uno.zip package should contain these files:
Wavelet.uno.zip Addons.xcu Wavelet.py images/WaveletBig.bmp images/WaveletSmall.bmp
Note: The %origin% is Wavelet.uno.zip, thus the %origin%/images/WaveletBig.bmp points to the WaveletBig.bmp file in your Wavelet.uno.zip file.
Installation
You can install your UNO component with the Extension manager (somewhere in the Tools menu) or with the unopkg tool.
/opt/openoffice.org1.9.103/program/unopkg add Wavelet.uno.zip
Uninstallation
You can uninstall your UNO component with the Extension manager (somewhere in the Tools menu) or with the unopkg tool.
/opt/openoffice.org1.9.103/program/unopkg remove Wavelet.uno.zip
Python component testing
It's not necessary to install the Python UNO component to test it. You can connect to the running OpenOffice.org instance and test your UNO component directly.
Code
Append the following code at the end of the Wavelet.py file.
if __name__ == "__main__": import os # Start OpenOffice.org, listen for connections and open testing document os.system( "/etc/openoffice.org-1.9/program/soffice '-accept=socket,host=localhost,port=2002;urp;' -writer ./WaveletTest.odt &" ) # Get local context info localContext = uno.getComponentContext() resolver = localContext.ServiceManager.createInstanceWithContext( "com.sun.star.bridge.UnoUrlResolver", localContext ) ctx = None # Wait until the OO.o starts and connection is established while ctx == None: try: ctx = resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" ) except: pass # Trigger our job wavelet = Wavelet( ctx ) wavelet.trigger( () )
Testing
To test your UNO component, just run your Wavelet.py in the Python interpreter.
/opt/openoffice.org1.9.103/program/python ./Wavelet.py
Resume
This part does this:
starts OpenOffice.org and opens the WaveletTest.odt file
loop until the connection will be established
start your component in the running OpenOffice.org context
Note: Do not forget to remove this part before real UNO component packaging. Or comment it out.
See also
- Extensions chapter of the Developers Guide
- Using C++ with OOo SDK : Constructing Component in C++
- UNO tutorial
- UNO IDL
- Uno/Article/Types&Reflection
- Daniel Bölzle's tutorial : Writing a simple UNO component.
- Component with Python