Framework/Article/Tool Panels

From Apache OpenOffice Wiki
Jump to: navigation, search

Tool Panels

Starting with OpenOffice.org 3.3, the application framework supports so-called tool panels, grouped into a task pane. From previous OpenOffice.org versions, you already know the task pane from Impress, where there are 5 standard tool panels (called "Master Pages", "Layouts", "Table Design", "Custom Animation", and "Slide Transition"). With OpenOffice.org 3.3, you can write your own extension, which adds one or more tool panel/s to one or more of OpenOffice.org's applications.

The UI Element

Conceptually, a tool panel is an UI element, just like tool bars, menu bars, and status bars (to name the most prominent ones). This implies that a toolpanel is identified by a resource URL, starting with private:resource/, followed by a keyword describing the class of the UI element - toolpanel, in our case.

Everything following the mandatory private:resource/toolpanel/ part of the URL is at your own discretion. However, remember that your URL must be globally unique, so you should, for example, use your company's name, or something like this. For instance, an example tool panel provided by OOo itself could have an URL like private:resource/toolpanel/org.openoffice.example/ToolPanel, which makes name collisions with other tool panels quite unlikely.

The Window State

To make your new tool panel UI element known to the application framework, you need to add meta data about it to the org.openoffice.Office.UI.<Module>WindowState configuration, where <Module> denotes the short name of the application where your panel should appear. The following configuration fragment registers a tool panel for Writer's task pane:

<?xml version='1.0' encoding='UTF-8'?>
<oor:component-data
    oor:name="WriterWindowState"
    oor:package="org.openoffice.Office.UI"
    xmlns:install="http://openoffice.org/2004/installation"
    xmlns:oor="http://openoffice.org/2001/registry"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <node oor:name="UIElements">
    <node oor:name="States">
      <node oor:name="private:resource/toolpanel/org.openoffice.example/SoylentGreen" oor:op="replace">
        <prop oor:name="UIName" oor:type="xs:string">
          <value xml:lang="en-US">Soylent Green</value>
        </prop>
        <prop oor:name="ImageURL" oor:type="xs:string">
          <value>vnd.sun.star.extension://extension-identifier/green.png</value>
        </prop>
      </node>
    </node>
  </node>
</oor:component-data>

Note that the node describing your UI element is a WindowStateType, as defined by the org.openoffice.Office.UI.WindowState configuration scheme. Most of its properties are not used for tool panels, but one of them is mandatory: UIName defines the name of the tool panel, and must not be empty.

Additionally, ImageURL describes an image to associate with the panel. If you deploy an image with your extension, you can use the extension-UCP, which allows you to refer to a file within your extension package, without knowing the actual location to which the package is deployed later on.

The Factory

To allow the application framework to create your tool panel when needed, you need to implement an XUIElementFactory for it, and provide information about this factory in the org.openoffice.Office.UI.Factories configuration.

The Configuration

<?xml version='1.0' encoding='UTF-8'?>
<oor:component-data
    oor:name="Factories"
    oor:package="org.openoffice.Office.UI"
    xmlns:oor="http://openoffice.org/2001/registry"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <node oor:name="Registered">
    <node oor:name="UIElementFactories">
      <node oor:name="org.openoffice.example.CustomToolPanel" oor:op="replace">
        <prop oor:name="Type">
          <value>toolpanel</value>
        </prop>
        <prop oor:name="Name">
          <value>org.openoffice.example</value>
        </prop>
        <prop oor:name="Module">
          <value/>
        </prop>
        <prop oor:name="FactoryImplementation">
          <value>org.openoffice.example.colorpanel.ToolPanelFactory</value>
        </prop>
      </node>
    </node>
  </node>
</oor:component-data>

Again, the node name for your factory's configuration data should be unique, so apply some common sense when defining it ("MyFactory" is no good name for sure).

The Type property is mandatory and fixed, and must have the value "toolpanel". The Name property effectively is the pattern which is matched against a actual UI element resource URL: The above configuration registers the factory for all UI elements whose resource URL starts with private:resource/toolpanel/org.openoffice.example.

Module can be used to restrict the factory to UI elements in the given module - if your extension registers one or more panels for multiple applications, leave this property empty.

Finally, the FactoryImplementation property specifies the service or implementation name of your UIElementFactory.

The Implementation

Your factory's implementation must be a UNO component as usual, which implements the XUIElementFactory interface. In the createUIElement method, the framework will pass two arguments:

  • Frame specifies the frame which the UI element lives in. Thus, it provides you access to the document and its view, so can for instance add listeners which react on document/view states, and update your panel state accordingly.
  • ParentWindow specifies the window which you must use as parent for your tool panel main window.

Both arguments are guaranteed to be passed to the factory.

The Tool Panel

As with all UI elements, on the API level there is a separation between the abstract UI element (implementing XUIElement) and the concrete object - the latter being provided by XUIElement::getRealInterface

In the case of tool panels, the concrete object must support the XToolPanel interface, which is defined as follows:

/** describes the basic interface to be implemented by a tool panel
 */
interface XToolPanel
{
    /** provides access to the tool panel's main window.
    
    It is allowed for an implementation to return <NULL/> here, but in this case some functionality, for instance
    automatic positioning of the tool panel, might not be available, and must be implemented by the tool panel itself.
    */
    [attribute, readonly] ::com::sun::star::awt::XWindow    Window;

    /** creates the root of the Accessibility object tree for the tool panel
        @param ParentAccessible
            the parent object in the Accessibility object tree
    */
    ::com::sun::star::accessibility::XAccessible
        createAccessible( [in] ::com::sun::star::accessibility::XAccessible ParentAccessible );
};

You're strongly recommended to implement your tool panel in a way that it has a main/root window, i.e. returns non-NULL as its Window attribute. In this case, the application framework will care for automatic positioning of the panel, otherwise, you need to implement this yourself.

If your tool panel should be accessible to people with disabilities, you should implement an XAccessible for it, and return it in the createAccessible method.

Example Implementation

An example implementation, which adds simple single-colored tool panels without any own intelligence to multiple of OpenOffice.org's applications, can be found in the source code repository, in the folder sfx2/workben/custompanel, as soon as the CWS slidecopy has been integrated.

Installing this extension results in a Writer document view like the following:

Example of a simple, single-colored tool panel, added via an extension to OpenOffice.org Writer
Personal tools