OpenOffice Add-On Project Type

From Apache OpenOffice Wiki
Jump to: navigation, search

Back to OpenOffice.org NetBeans Integration

Overview

The Add-On wizard will enable users to create an OpenOffice.org component that including support of UI extensions. The component is based on a on a J2SE class library project and supports additional targets to create and deploy the package into the office installation. All interface methods are default implemented and do nothing. In a second step you can insert your implementation in the generated skeleton, rebuild the extension and deploy it again to see the effect in your office.

Project Wizard

The project wizard is quite simple to use, you simply choose

  • File -> New Project -> OpenOffice.org -> OpenOffice.org Add-On

and follow the wizard.

  • Step 1: Select the project type

    AddOn1.png


  • Step 2: Define the project name, Add-On name, an optional package and the project location

    AddOn2.png


    The necessary xcu files are generated and become part of the final oxt package. These xcu files can be easily adapted later to extend the initial project to a more complex Add-On example. The generated Add-On skeleton implements a simple com.sun.star.frame.ProtocolHandler Add-On.
  • Step 3: Defining the new commands, including icons.

    AddOn3-1.png


  • Step 4: Defining the top level menu

    AddOn3.png


    On this panel you can define the top level menus with sub-menus on a higher abstraction level. You will not have to deal with xcu files directly. You can modify the default menu, add new menus and commands, and you can define the context in which the command should appear. When you have deployed the package, the newly defined menus are visible in the specified context. For example, if you choose the context Writer, the menu is visible when you open or create a text document. Not selecting a context means all contexts, even the back-end window. For more detailed descriptions of the different fields simply press the help button or read the appropriate chapter in the Protocol Handler

    AddOn4.png


  • Step 5: Defining the toolbar is similar to the menu. There is no top level toolbar, of course.

    AddOn5.png


  • Step 6: Deploying the extension package

    Calc AddIn4.png


    You can simply create or deploy the oxt extension package by choosing:
    Project View -> Project Node -> Context Menu -> Deploy and Run Extension in OpenOffice.org


The AddOn deployed in OpenOffice.org is visible in the back-end window.

AddOn6.png
HINT: in order to make icons for the toolbar that have a transparent background, you must use the key color magenta for the transparency layer. Please refer to the Star Office Icon Design Guide for more information on designing your Add-On's icons.

Generated Code

Two (.xcu) files for the Add-On are created that describe the Add-On commands with descriptions, displaynames etc., (Addons.xcu) and the protocol that is used to access these commands (ProtocolHandler.xcu). For the example shown above, the following files are generated:

  • Addons.xcu
    xcu file defining the new menus with submenus and commands. This file can be easily extended to support toolbars as well (toolbar support will be added later to the wizard).
<?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">
    <node oor:name="OfficeMenuBar">
      <node oor:name="org.openoffice.testaddon.testaddon" oor:op="replace">
        <prop oor:name="Title" oor:type="xs:string">
          <value/>
          <value xml:lang="en">My Menu</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>org.openoffice.testaddon.testaddon:HelloWorld</value>
            </prop>
            <prop oor:name="ImageIdentifier" oor:type="xs:string">
              <value/>
            </prop>
            <prop oor:name="Target" oor:type="xs:string">
              <value>_self</value>
            </prop>
            <prop oor:name="Context" oor:type="xs:string">
              <value/>
            </prop>
            <prop oor:name="Title" oor:type="xs:string">
              <value/>
              <value xml:lang="en">Hello World</value>
            </prop>
          </node>
        </node>
      </node>
    </node>
    <node oor:name="OfficeToolBar">
      <node oor:name="org.openoffice.testaddon.testaddon" oor:op="replace">
      <node oor:name="m1" oor:op="replace">
        <prop oor:name="URL" oor:type="xs:string">
          <value>org.openoffice.testaddon.testaddon:HelloWorld</value>
        </prop>
        <prop oor:name="ImageIdentifier" oor:type="xs:string">
          <value/>
        </prop>
        <prop oor:name="Target" oor:type="xs:string">
          <value>_self</value>
        </prop>
        <prop oor:name="Context" oor:type="xs:string">
          <value/>
        </prop>
        <prop oor:name="Title" oor:type="xs:string">
          <value/>
          <value xml:lang="en">Hello World</value>
        </prop>
      </node>
      </node>
    </node>
    <node oor:name="Images">
      <node oor:name="org.openoffice.testaddon.testaddon.helloworld.images" oor:op="replace">
        <prop oor:name="URL" oor:type="xs:string">
          <value>org.openoffice.testaddon.testaddon:HelloWorld</value>
        </prop>
        <node oor:name="UserDefinedImages">
          <prop oor:name="ImageSmallURL">
            <value>%origin%/idlfile.png</value>
          </prop>
          <prop oor:name="ImageBigURL">
            <value>%origin%/idlfile.png</value>
          </prop>
          <prop oor:name="ImageSmallHCURL">
            <value>%origin%/idlfile.png</value>
          </prop>
          <prop oor:name="ImageBigHCURL">
            <value>%origin%/idlfile.png</value>
          </prop>
        </node>
      </node>
    </node>
  </node>
</oor:component-data>
  • uno-extension-manifest.xml
    the package descriptor, will be packed as "META-INF/manifest.xml"
<?xml version="1.0" encoding="UTF-8"?>
<manifest:manifest xmlns:manifest="http://openoffice.org/2001/manifest">
  <manifest:file-entry manifest:media-type="application/vnd.sun.star.uno-component;type=Java"
                       manifest:full-path="TestAddOn.jar"/>
  <manifest:file-entry manifest:media-type="application/vnd.sun.star.configuration-data"
                       manifest:full-path="registry/data/org/openoffice/Office/Addons.xcu"/>
  <manifest:file-entry manifest:media-type="application/vnd.sun.star.configuration-data"
                       manifest:full-path="registry/data/org/openoffice/Office/ProtocolHandler.xcu"/>
</manifest:manifest>
  • org/openoffice/testaddon/TestAddOn.java
    the generated Add-On code skeleton where the generated class acts itself as the dispatch object (can be easily changed to support more complex Add-Ons). Most of the methods are already implemented and you simply have to add your own code in the dispatch method in the right place for each specified command.
package org.openoffice.testaddon;
 
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.lib.uno.helper.Factory;
import com.sun.star.lang.XSingleComponentFactory;
import com.sun.star.registry.XRegistryKey;
import com.sun.star.lib.uno.helper.WeakBase;
 
 
public final class TestAddOn extends WeakBase
   implements com.sun.star.lang.XServiceInfo,
              com.sun.star.frame.XDispatchProvider,
              com.sun.star.lang.XInitialization,
              com.sun.star.frame.XDispatch
{
    private final XComponentContext m_xContext;
    private com.sun.star.frame.XFrame m_xFrame;
    private static final String m_implementationName = TestAddOn.class.getName();
    private static final String[] m_serviceNames = {
        "com.sun.star.frame.ProtocolHandler" };
 
 
    public TestAddOn( XComponentContext context )
    {
        m_xContext = context;
    };
 
    public static XSingleComponentFactory __getComponentFactory( String sImplementationName ) {
        XSingleComponentFactory xFactory = null;
 
        if ( sImplementationName.equals( m_implementationName ) )
            xFactory = Factory.createComponentFactory(TestAddOn.class, m_serviceNames);
        return xFactory;
    }
 
    public static boolean __writeRegistryServiceInfo( XRegistryKey xRegistryKey ) {
        return Factory.writeRegistryServiceInfo(m_implementationName,
                                                m_serviceNames,
                                                xRegistryKey);
    }
 
    // com.sun.star.lang.XServiceInfo:
    public String getImplementationName() {
         return m_implementationName;
    }
 
    public boolean supportsService( String sService ) {
        int len = m_serviceNames.length;
 
        for( int i=0; i < len; i++) {
            if (sService.equals(m_serviceNames[i]))
                return true;
        }
        return false;
    }
 
    public String[] getSupportedServiceNames() {
        return m_serviceNames;
    }
 
    // com.sun.star.frame.XDispatchProvider:
    public com.sun.star.frame.XDispatch queryDispatch( com.sun.star.util.URL aURL,
                                                       String sTargetFrameName,
                                                       int iSearchFlags )
    {
        if ( aURL.Protocol.equals("org.openoffice.testaddon.testaddon:") )
        {
            if ( aURL.Path.equals("mycommands") )
                return this;
        }
        return null;
    }
 
    // com.sun.star.frame.XDispatchProvider:
    public com.sun.star.frame.XDispatch[] queryDispatches(
         com.sun.star.frame.DispatchDescriptor[] seqDescriptors )
    {
        int nCount = seqDescriptors.length;
        com.sun.star.frame.XDispatch[] seqDispatcher =
            new com.sun.star.frame.XDispatch[seqDescriptors.length];
 
        for( int i=0; i < nCount; ++i )
        {
            seqDispatcher[i] = queryDispatch(seqDescriptors[i].FeatureURL,
                                             seqDescriptors[i].FrameName,
                                             seqDescriptors[i].SearchFlags );
        }
        return seqDispatcher;
    }
 
    // com.sun.star.lang.XInitialization:
    public void initialize( Object[] object )
        throws com.sun.star.uno.Exception
    {
        if ( object.length > 0 )
        {
            m_xFrame = (com.sun.star.frame.XFrame)UnoRuntime.queryInterface(
                com.sun.star.frame.XFrame.class, object[0]);
        }
    }
 
    // com.sun.star.frame.XDispatch:
     public void dispatch( com.sun.star.util.URL aURL,
                           com.sun.star.beans.PropertyValue[] aArguments )
    {
         if ( aURL.Protocol.equals("org.openoffice.testaddon.testaddon:") )
        {
            if ( aURL.Path.equals("mycommands") )
            {
                // add your own code here
                return;
            }
        }
    }
 
    public void addStatusListener( com.sun.star.frame.XStatusListener xControl,
                                    com.sun.star.util.URL aURL )
    {
        // add your own code here
    }
 
    public void removeStatusListener( com.sun.star.frame.XStatusListener xControl,
                                       com.sun.star.util.URL aURL )
    {
        // add your own code here
    }
 
}


Project Settings

Before deploying your project, you can define a few settings such as the Display Name, the Description, the License, the Default Icon... Right-click on the project and click on Settings. Under the Apache OpenOffice category there are two sections, Display and Version.

The settings in the Display section are presented to the end-user when installing the plugin or when viewing the plugin manager.



Openoffice project settings display.png
HINT: if you have internationalized your Add-On, you can also internationalize the Add-On name and description. For example, you can create a subfolder under the project OXT folder (say for example, a description folder), and add a text file with the translated description for each locale to this subfolder (e.g. "description_en.txt", "description_fr.txt", "description_zh.txt", etc.). Then set the Description property in the Display settings to the path of the translated description text file for each locale that the Add-On supports (e.g. "description/description_en.txt" will point to the description subfolder in the OXT folder; you can switch between properties for each locale at the top of the Apache OpenOffice -> Display settings using the Current locale dropdown). This way, when users install your Add-On, they will see the description of your Add-On in their own language.

The settings in the Version section are used by the plugin manager to determine the newest version and to detect when newer versions are available. Each time you release an update, you will want to increment the version number from here.


Openoffice project settings version.png
HINT: Leaving the Update URLs setting empty will allow the extensions website to automatically detect when a new version is deployed (update notifications are issued periodically).
Personal tools