Framework/Tutorial/Statusbar Controller

From Apache OpenOffice Wiki
Jump to: navigation, search

This tutorial will give you a detailed overview of the OpenOffice.org status bar and how to create a status bar controller. Everybody is invited to participate. Maybe someone wants to translate the extension to a different language (e.g. Java or Python) or wants to have more information about a specific topic. You can set a link to this page, if you think that this page adds valuable information. The outcome of this tutorial will be a status bar controller that will show the current position of the cursor (e.g. line, column).

The reader of this tutorial should have the following programming skills


The OpenOffice.org status bar

The OpenOffice.org status bar is controlled by the frame based layout manager. Every frame contains a layout manager that controls the user interfaces elements (e.g. menu bar, status bar, toolbars). The layout manager identifies every user interface element via a unique url. The status bar can be addressed by the following url: private:resource/statusbar/statusbar. The status bar is always located at the bottom side of a frame. It's also responsible to show the progress bar during loading of a document.

OpenOffice2UserInterfaceElements.png

The status bar consists of several status bar controller which each controls a different aspect. For example the default OpenOffice.org Writer status bar contains nine different controllers you can see on the following illustration.

Write statusbar.JPG

Statusbar Configuration

The structure of a status bar is defined by a XML file located in the OpenOffice.org installation folder. The default location is here:

<OpenOffice.org installation>/share/config/soffice.cfg/modules/<application module identifier>/statusbar/statusbar.xml

The following snippet shows the content of the OpenOffice.org Writer status bar XML file.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE statusbar:statusbar PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "statusbar.dtd">
<statusbar:statusbar xmlns:statusbar="http://openoffice.org/2001/statusbar" xmlns:xlink="http://www.w3.org/1999/xlink">
 <statusbar:statusbaritem xlink:href=".uno:StatePageNumber" statusbar:align="left" statusbar:autosize="true" statusbar:width="54"/>
 <statusbar:statusbaritem xlink:href=".uno:PageStyleName" statusbar:align="left" statusbar:autosize="true" statusbar:width="79"/>
 <statusbar:statusbaritem xlink:href=".uno:Zoom" statusbar:align="center" statusbar:width="35" />
 <statusbar:statusbaritem xlink:href=".uno:InsertMode" statusbar:align="center" statusbar:width="37" />
 <statusbar:statusbaritem xlink:href=".uno:SelectionMode" statusbar:align="center" statusbar:width="30" />
 <statusbar:statusbaritem xlink:href=".uno:ExecHyperlinks" statusbar:align="center" statusbar:width="22" />
 <statusbar:statusbaritem xlink:href=".uno:ModifiedStatus" statusbar:align="center" statusbar:width="9" />
 <statusbar:statusbaritem xlink:href=".uno:Signature" statusbar:align="center" statusbar:ownerdraw="true" statusbar:width="16" />
 <statusbar:statusbaritem xlink:href=".uno:Size" statusbar:align="left" statusbar:autosize="true" statusbar:ownerdraw="true" statusbar:width="129"/>
</statusbar:statusbar>

The xml configuration file supports the following elements, attributes and rules.

  • You must locate a <statusbar:statusbaritem> element inside a <statusbar:statusbar> element.
  • You cannot nest <statusbar:statusbar> elements.

Status Bar

The <statusbar:statusbar> element is a container element for status bar items.
 
XML Code : <statusbar:statusbar>
Rules    : You must include all status bar items in a this element.
DTD      : <!ELEMENT statusbar:statusbar (statusbar:statusbaritem*)>
           <!ATTLIST statusbar:statusbar
                     xmlns:statusbar CDATA #FIXED "http://openoffice.org/2001/statusbar"
                     xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">

Status Bar Item

XML Code : <statusbar:statusbaritem>
Rules    : You must specify a valid value for the xlink:href attribute
DTD      : <!ELEMENT statusbar:statusbaritem EMPTY>
           <!ATTLIST statusbar:statusbaritem
                     xlink:href CDATA #REQUIRED
                     statusbar:align %alignment; #IMPLIED
                     statusbar:style %style; #IMPLIED
                     statusbar:autosize %boolean; #IMPLIED
                     statusbar:ownerdraw %boolean; #IMPLIED
                     statusbar:width %numeric; #IMPLIED
                     statusbar:offset %numeric; #IMPLIED>

xlink:href

The xlink:href attribute specifies the status bar control that is instantiated for this status bar item

XML Code : <xlink:href>
Rules    : The value of this attribute must be a valid status URL. If the URL don't
           have a status bar controller associated it will be ignored.
DTD      : <!ATTLIST statusbar:statusbaritem xlink:href CDATA #REQUIRED>

The association between xlink:href value and a status bar controller is maintained by the Controller.xcu file which is described in the chapter Configuration

statusbar:align

The statusbar:align attribute specifies how the information is aligned in the bounding box of the status bar control window.

XML Code : <statusbar:align>
Rules    : The value of this attribute can be one of the following:
           - left  : The status bar control output should be aligned to the left border
                     the bounding box.
           - center: The status bar control output should be aligned to the center of
                     the bounding box.
           - right : The status bar control output should be aligned to the right border
                     of the bounding box.
DTD      : <!ENTITY % alignment "(left|center|right)">
           <!ATTLIST statusbar:statusbaritem statusbar:align %alignment; "center">

statusbar:style

The statusbar:style attribute specifies how the bounding box of a status bar item is displayed.

XML Code : <statusbar:style>
Rules    : The value of this attribute can be one of the following:
           - in   : The bounding box of the status bar control is painted engraved.
           - out  : The bounding box of the status bar control is painted embossed.
           - flat : The bounding box of the status bar control is painted normally, no 3D effect.
DTD      : <!ENTITY % style "(in|out|flat)">
           <!ATTLIST statusbar:statusbaritem statusbar:style %style; "in">

statusbar:autosize

The statusbar:autosize attribute specifies whether or not the size of the bounding box for the status bar item is controlled automatically by the status bar.

XML Code : <statusbar:autosize>
Rules    : The value of this attribute can be true or false. If the value if true the size of the bounding box is set
           automatically by the status bar. If the value is false the statusbar:width attribute determines the size of the bounding
           box. The default value is false.
DTD      : <!ATTLIST statusbar:statusbaritem statusbar:autosize %boolean; "false">

statusbar:ownerdraw

The statusbar:ownerdraw attribute specifies whether or not the status bar item uses an external function to display its content.

XML Code : <statusbar:ownerdraw>
Rules    : The value of this attribute can be true or false. The value must be true to use an external function to display the 
           content.
DTD      : <!ATTLIST statusbar:statusbaritem statusbar:ownerdraw %boolean; "false">

statusbar:width

The statusbar:width attribute specifies the width of the bounding box for a status bar item in pixel.

XML Code : <statusbar:width>
Rules    : This attribute is only processed if the value of the statusbar:autosize attribute is set to false.
DTD      : <!ENTITY % numeric "CDATA">
           <!ATTLIST statusbar:statusbaritem statusbar:width %numeric; "0">

statusbar:offset

The statusbar:offset attribute specifies the distance by which text of a status bar item is offset on the x-axis.

XML Code : <statusbar:offset>
Rules    : The value of this attribute is a numerical value in pixel. The default value is 5 pixel.
DTD      : <!ENTITY % numeric "CDATA">
           <!ATTLIST statusbar:statusbaritem statusbar:offset %numeric; "5">

General abstract of the status bar controller concept

Status bar controller architecture

A status bar controller is responsible for a single aspect that should be accessible via status bar. It must be implemented via UNO using the status bar controller service. The following illustration shows how the different status bar implementation parts work together to create/associate a status bar controller for the status bar.

Statusbar-Controller-Architecture.png


Status bar controller service

This service is called com.sun.star.frame.StatusbarController. The OpenOffice.org status bar implementation uses the different interfaces of the service for creation, initialization, destruction and communication. The following snippet shows the UNO IDL description of the central com.sun.star.frame.StatusbarController service.

Documentation caution.png

ATTENTION: The service description of OpenOffice.org 2.2 and previous versions don't describe com::sun::star::lang::XComponent although the status bar implementation needs this interface! This issue will be corrected in the upcoming OpenOffice.org 2.3 service description. All internal OpenOffice.org status bar controller support this interface, so this is only a documentation error.


//=============================================================================
 
 module com {  module sun {  module star {  module frame {
 
//=============================================================================
/** is an abstract service for a component which offers a more complex user 
    interface to users within a status bar.
 
    A generic status bar function is represented as a text field which has 
    provides status information to the user. A status bar controller can be 
    added to a status bar and provide information or functions with a more 
    sophisticated user interface.
    A typical example for a status bar controller is the zoom level chooser 
    within the statusbar. It provides an option to change the zoom level of 
    an application.
 
    see com::sun::star::frame::XDispatchProvider
    see com::sun::star::frame::XStatusbarController
 
    since OOo 2.0.0
 */
 
service StatusbarController
{
    //-------------------------------------------------------------------------
    /** with this interface a component can receive events if a feature has 
        changed.
 
        The status bar controller implementation should register itself as a 
        listener when its com::sun::star::util::XUpdatable interface has 
        been called.
     */
    interface com::sun::star::frame::XStatusListener;
 
    /** used to initialize a component with required arguments.
 
        A status bar controller needs at least five additional arguments 
        provided as com::sun::star::beans::PropertyValue:
 
        Frame
        a com::sun::star::frame::XFrame instance to which the status bar 
        controller belongs.
 
        CommandURL
        a string which specifies the command associated with the 
        statusbar controller. The command is used to identify the status
        bar controller implementation.
 
        ServiceManager
        a com::sun::star::lang::XMultiServiceFactory instance which can 
        be used to create additional UNO services.
 
        Parent
        a com::sun::star::awt::XWindow instance which represents the parent
        window (status bar window).
 
        Identifier
        an integer value which is the unique id used by the status bar
        implementation to identify a status bar entry. This value is 
        currently only used by internal OpenOffice.org status bar controller
        implementations.
    */
    interface com::sun::star::lang::XInitialization;
 
    /** used to notify an implementation that it needs to add its listener or 
        remove and add them again.
 
        A status bar controller instance is ready for use after this call has 
        been made the first time. The status bar implementation guarentees that 
        the controller's item window has been added to the status bar and its 
        reference is held by it.
    */
    interface com::sun::star::util::XUpdatable;
 
    //-------------------------------------------------------------------------
    /** used to notify changed features and requests for additional user 
        interface items.
 
        Mostly used by a status bar implementation to forward information to 
        and request services from a status bar controller component. This 
        interface must be useable after 
        com::sun::star::lang::XInitialitation::initialize has been called.  
        The behavior of the interface is undefined if the controller component 
        hasn't been initialized.
     */
    interface com::sun::star::frame::XStatusbarController;
 
    //-------------------------------------------------------------------------
    /** used to control the life-time of the component
 
        Used by a status bar implementation to control the life-time of
        a status bar controller. The status bar is the only instance which
        is allowed to dispose the component.
     */
    interface com::sun::star::lang::XComponent;
};
 
}; }; }; };

Each interface has a clear task to work together with parts of the OpenOffice.org status bar implementation. The following illustration shows how the different interfaces are used within OpenOffice.org.

Statusbar-Controller-Interfaces.png


com::sun::star::frame::XStatusListener

module com {  module sun {  module star {  module frame {
 
//=============================================================================
/** makes it possible to receive events when the state of a feature changes.
 
    <p>
    Nobody guarantee any notification. Use combination of <type>XNotifyingDispatch</type>
    and <type>XDispatchResultListener</type> for that.
    </p>
 
    @see XDispatch
    @see XNotifyingDispatch
    @see XDispatchResultListener
 */
published interface XStatusListener: com::sun::star::lang::XEventListener
{
	//-------------------------------------------------------------------------
	/** is called when the status of the feature changes.
 
        @param State
            provides information about changes of the requested feature
	 */
    [oneway] void statusChanged( [in] FeatureStateEvent State );
};
 
//=============================================================================
 
}; }; }; };

com::sun::star::lang::XInitialization

module com {  module sun {  module star {  module lang {  
 
//============================================================================= 
 
// DocMerge from xml: interface com::sun::star::lang::XInitialization
/** initializes an object directly after its creation.
 
	<p>This interface works together with factories. If you want to 
	initialize the object after creation, you should
	support this interface and you may support other interfaces 
	which offer type-safe initialization methods.  </p>
 
    <p>Instead of calling <member>XSingleComponentFactory::createInstanceWithContext</member>
    and later initialize(), you should call 
    <member>XSingleComponentFactory::createInstanceWithArgumentsAndContext</member>
    to pass the arguments to the instance. The reason is, that a component may want to
    return the same instance for the same set of parameters, and it can do so by implementing
    the factory itself.
    </p>
 
 */
published interface XInitialization: com::sun::star::uno::XInterface
{ 
	//------------------------------------------------------------------------- 
 
	// DocMerge from xml: method com::sun::star::lang::XInitialization::initialize
	/** initializes the object. 
 
		<p>It should be called directly after the object is created.
	 */
	void initialize( [in] sequence<any> aArguments ) 
			raises( com::sun::star::uno::Exception ); 
 
}; 
 
//============================================================================= 
 
}; }; }; };

com::sun::star::util::XUpdatable

module com {  module sun {  module star {  module util {
 
//=============================================================================
/** is supported by objects with data that can be updated from a data source.
 */
published interface XUpdatable: com::sun::star::uno::XInterface
{
	//-------------------------------------------------------------------------
	/** refreshes the data of the object from the connected data source.
	 */
    void update();
};
 
//=============================================================================

com::sun::star::frame::XStatusbarController

module com {  module sun {  module star {  module frame {
 
//=============================================================================
/** is an abstract service for a component which offers a more complex user interface
    to users within a status bar.
 
    <p>
    A generic status bar field is represented as a simple text field. A status 
    bar controller can be added to a Statusbar and provide information or 
    functions with a more sophisticated user interface.<br/>
    A typical example for status bar controller is a zoom chooser. It shows 
    the current zoom and provides general zoom levels on a popup menu 
    that can be activated by a mouse action for context menus.
    <p>
 
    @see com::sun::star::frame::XDispatchProvider
 
    @since OOo 2.0.0
 */
interface XStatusbarController : ::com::sun::star::uno::XInterface
{
    //=============================================================================
    /** is called by a status bar if the mouse position is within the controller 
        and a mouse button has been pressed. If the controller has captured the 
        mouse input this function is also called when the mouse position is not 
        within the controller.
 
        @param aMouseEvent
            current information about the mouse pointer.
 
        @return
            return <TRUE/> if the event should not be processed and <FALSE/> 
            if the event should be processed by the status bar.
    */
    boolean mouseButtonDown( [in] ::com::sun::star::awt::MouseEvent aMouseEvent );
 
    //=============================================================================
    /** is called by a status bar if the mouse position is within the controller 
        and a mouse has been moved. If the controller has captured the 
        mouse input this function is also called when the mouse position is not 
        within the controller.
 
        @param aMouseEvent
            current information about the mouse pointer.
 
        @return
            return <TRUE/> if the event should not be processed and <FALSE/> 
            if the event should be processed by the status bar.
    */
    boolean mouseMove( [in] ::com::sun::star::awt::MouseEvent aMouseEvent );
 
    //=============================================================================
    /** is called by a status bar if the mouse position is within the controller 
        and a mouse button has been released. If the controller has captured the 
        mouse input this function is also called when the mouse position is not 
        within the controller.
 
        @param aMouseEvent
            current information about the mouse pointer.
 
        @return
            return <TRUE/> if the event should not be processed and <FALSE/> 
            if the event should be processed by the status bar.
    */
    boolean mouseButtonUp( [in] ::com::sun::star::awt::MouseEvent aMouseEvent );
 
    //=============================================================================
    /** is called by a status bar if a command event is available for a controller.
 
        @param aPos
            the current mouse position in pixel.
 
        @param nCommand
            describes which command has been invoked.
 
        @param bMouseEvent
            <TRUE/> if the command is based on a mouse event, otherwise <FALSE/>.
 
        @param aData
            for future use only.
    */
    void command( [in] ::com::sun::star::awt::Point aPos,
                  [in] long nCommand,
                  [in] boolean bMouseEvent,
                  [in] any aData );
 
    //=============================================================================
    /** is called by a status bar if a command event is available for a controller.
 
        @param aPos
            the current mouse position in pixel.
 
        @param nCommand
            describes which command has been invoked.
 
        @param bMouseEvent
            <TRUE/> if the command is based on a mouse event, otherwise <FALSE/>.
 
        @param aData
            for future use only.
    */
    void paint( [in] ::com::sun::star::awt::XGraphics xGraphics,
                [in] ::com::sun::star::awt::Rectangle rOutputRectangle,
                [in] long nItemId,
                [in] long nStyle );
 
    //=============================================================================
    /** is called by a status bar if the user clicked with mouse into the 
        field of the corresponding control.
    */
    void click();
 
    //=============================================================================
    /** is called by a status bar if the user double-clicked with mouse 
        into the field of the corresponding control.
    */
    void doubleClick();
};          
 
}; }; }; };

com::sun::star::lang::XComponent

//============================================================================= 
 
module com {  module sun {  module star {  module lang {  
 
 published interface XEventListener; 
 
//============================================================================= 
 
/** allows to exclicitly free resources and break cyclic references.
 
    Actually the real lifetime of an UNO object is controlled by 
    references kept on interfaces of this object. But there are two
    distinct meanings in keeping a reference to an interface:
    1st to own the object and 2nd to know the object.
 
    You are only allowed to keep references of interfaces
    to UNO objects if you are by definition the owner of that object or
    your reference is very temporary or you have registered an
    EventListener at that object and release the reference when
    "disposing" is called.
 */
published interface XComponent: com::sun::star::uno::XInterface
{ 
    //------------------------------------------------------------------------- 
    /** The owner of an object calls this method to explicitly free all
        resources kept by this object and thus break cyclic references.
 
        Only the owner of this object is allowed to call this method.
        The object should release all resources and references in the
        easiest possible manner ( for instance no serialization should
        take place anymore ).
 
        The object must notify all registered listeners using the method
        XEventListener::disposing. All notfied objects should release 
        there references to this object without calling 
        XComponent::removeEventListener (the disposed object will release 
        the listeners eitherway).
 
        After this method has been called, the object should behave as 
        passive as possible, thus it should ignore all calls in case it 
        can comply with its specification (for instance addEventListener()).
        Often the object can't fulfill its specification anymore, in this 
        case it must throw the DisposedException (which is derived from 
        com::sun::star::uno::RuntimeException) when it gets called.
 
        For some objects no real owner can be identified, thus it can be
        disposed from multiple reference holders. In this case
        the object should be able to cope with multiple dispose()-calls (which
        are inevitable in a multithreaded environment).
    */
    void dispose(); 
 
    //------------------------------------------------------------------------- 	 
    /** adds an event listener to the object. 
 
        The broadcaster fires the disposing method of this listener if the 
        XComponent::dispose method is called.
 
        It is suggested to allow multiple registration of the same listener,
	thus for each time a listener is added, it has to be removed.</p>
 
        If this com::sun::star::lang::XComponent is already disposed when 
        com::sun::star::lang::XComponent::addEventListener is called, the 
        call will not fail with a com::sun::star::lang::DisposedException, 
        but the caller will be notified via the 
        com::sun::star::lang::XEventListener::disposing callback.  This 
        callback can occur synchronously within the 
        com::sun::star::lang::XComponent::addEventListener call.
 
        see XComponent::removeEventListener
    */
    void addEventListener( [in] XEventListener xListener ); 
 
    //------------------------------------------------------------------------- 
    /** removes an event listener from the listener list.
 
	It is a "noop" if the specified listener is not registered.
 
        It is suggested to allow multiple registration of the same listener,
	thus for each time a listener is added, it has to be removed.
 
        If this com::sun::star::lang::XComponent is already disposed when 
        com::sun::star::lang::XComponent::removeEventListener is called, the 
        call will not fail with a com::sun::star::lang::DisposedException,
        but will rather be ignored silently.
 
        see XComponent::addEventListener
    */
    void removeEventListener( [in] XEventListener aListener ); 
}; 
 
//============================================================================= 
}; }; }; };

Configuration

Every UNO based status bar controller must be registered in the OpenOffice.org configuration to be accessible by the status bar controller factory. The following snippet shows the schema of this controller configuration.

<?xml version='1.0' encoding='UTF-8'?>
 
<oor:component-schema oor:name="Controller" oor:package="org.openoffice.Office.UI" xml:lang="en-US" xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <info>
  <desc>Contains implementation of popup menu controllers.</desc>
 </info>
 <templates>
  <group oor:name="ControllerType">
   <info>
    <desc>Describes a controller implementation.</desc>
   </info>
   <prop oor:name="Command" oor:type="xs:string">
    <info>
     <desc>Specifies the command name which the controller is bound to.</desc>
    </info>
   </prop>
   <prop oor:name="Module" oor:type="xs:string">
    <info>
     <desc>Specifies the model that the controller is associated with. An empty string matches every module.</desc>
    </info>
   </prop>
   <prop oor:name="Controller" oor:type="xs:string">
    <info>
     <desc>Specifies the UNO service to use for the specified tuple Command and Module</desc>
    </info>
   </prop>
   <prop oor:name="Value" oor:type="xs:string">
    <info>
     <desc>Specifies a controller specific value which is provided to every controller instance during initialization.</desc>
    </info>
    <value/>
   </prop>
  </group>
 </templates>
 <component>
  <group oor:name="Registered">
   ...
   <set oor:name="StatusBar" oor:node-type="ControllerType">
    <info>
     <desc>Contains UNO component implementation names that implement status bar controller which are bound to a command and module name.</desc>
    </info>
   </set>
  </group>
 </component>
</oor:component-schema>

The important part of the schema is the group "ControllerType". The group defines an association between a single command URL and a controller implementation.

Property Type Description
Command String Contains the command URL for which the controller is registered. The UI element implementation uses the command URL to query for controllers.
Module String Specifies the module for which the association is active. This allows to use different controller implementations for different modules. An empty entry means active for all modules.
Controller String Specifies the implementation name of the controller. The name will be used by the ControllerFactory to create an instance of the controller.
Value String Contains controller specific data which will be provided at creation time. It interpretation of the data depends on the controller implementation.

The following snippet is extracted from a org/openoffice/Office/UI/Controller.xcu configuration file which is part of every OpenOffice.org 2.x installation.

<OpenOffice.org installation>/share/registry/data/org/openoffice/Office/UI/Controller.xcu

<?xml version='1.0' encoding='UTF-8'?>
 
<oor:component-data oor:name="Controller" 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="Registered">
  <node oor:name="StatusBar">
   <node oor:name="c1" oor:op="replace">
    <prop oor:name="Command">
     <value>.uno:DBStatusType</value>
    </prop>
    <prop oor:name="Module">
     <value>com.sun.star.sdb.OfficeDatabaseDocument</value>
    </prop>
    <prop oor:name="Controller">
     <value>com.sun.star.sdb.ApplicationStatusbarController</value>
    </prop>
   </node>
   <node oor:name="c2" oor:op="replace">
    <prop oor:name="Command">
     <value>.uno:DBStatusDBName</value>
    </prop>
    <prop oor:name="Module">
     <value>com.sun.star.sdb.OfficeDatabaseDocument</value>
    </prop>
    <prop oor:name="Controller">
     <value>com.sun.star.sdb.ApplicationStatusbarController</value>
    </prop>
   </node>
   <node oor:name="c3" oor:op="replace">
    <prop oor:name="Command">
     <value>.uno:DBStatusUserName</value>
    </prop>
    <prop oor:name="Module">
     <value>com.sun.star.sdb.OfficeDatabaseDocument</value>
    </prop>
    <prop oor:name="Controller">
     <value>com.sun.star.sdb.ApplicationStatusbarController</value>
    </prop>
   </node>
   <node oor:name="c4" oor:op="replace">
    <prop oor:name="Command">
     <value>.uno:DBStatusHostName</value>
    </prop>
    <prop oor:name="Module">
     <value>com.sun.star.sdb.OfficeDatabaseDocument</value>
    </prop>
    <prop oor:name="Controller">
     <value>com.sun.star.sdb.ApplicationStatusbarController</value>
    </prop>
   </node>
   <node oor:name="c5" oor:op="replace">
    <prop oor:name="Command">
     <value>.uno:StatusbarLogo</value>
    </prop>
    <prop oor:name="Module">
     <value/>
    </prop>
    <prop oor:name="Controller">
     <value>com.sun.star.comp.framework.LogoImageStatusbarController</value>
    </prop>
    </node>
    <node oor:name="c6" oor:op="replace">
     <prop oor:name="Command">
      <value>.uno:StatusbarLogoText</value>
     </prop>
     <prop oor:name="Module">
      <value/>
     </prop>
     <prop oor:name="Controller">
      <value>com.sun.star.comp.framework.LogoTextStatusbarController</value>
     </prop>
    </node>
   </node>
  </node>
</oor:component-data>

This file contains all UNO based status bar controller. There a couple of internal status bar controller which are sfx2 based. These controller are restricted to sfx2 based application modules (e.g. Writer, Calc, Draw, Impress and Math). In the future all controllers will be translated to support the described UNO service (com.sun.star.frame.StatusbarController). This would allow non-sfx2 based application modules to also use them.

A status bar controller skeleton

This chapter wants to present a status bar controller skeleton which can be used as a basis for own experiments.

The following source code provides a working skeleton that can be extended by developers. The skeleton was created using the uno-skeletonmaker provided by the OpenOffice.org SDK.

#include "sal/config.h"
#include "cppuhelper/factory.hxx"
#include "cppuhelper/implementationentry.hxx"
#include "cppuhelper/compbase5.hxx"
#include "cppuhelper/basemutex.hxx"
#include "com/sun/star/lang/XServiceInfo.hpp"
#include "com/sun/star/frame/XStatusbarController.hpp"
#include "com/sun/star/frame/XStatusListener.hpp"
#include "com/sun/star/lang/XInitialization.hpp"
#include "com/sun/star/util/XUpdatable.hpp"
#include <com/sun/star/beans/PropertyValue.hpp>
#include "com/sun/star/frame/XFrame.hpp"
#include <stdio.h>
 
// component helper namespace
namespace comp_CursorPos {
 
namespace css = ::com::sun::star;
 
// component and service helper functions:
::rtl::OUString SAL_CALL _getImplementationName();
css::uno::Sequence< ::rtl::OUString > SAL_CALL _getSupportedServiceNames();
css::uno::Reference< css::uno::XInterface > SAL_CALL _create( css::uno::Reference< css::uno::XComponentContext > const & context );
 
} // closing component helper namespace
 
 
 
/// anonymous implementation namespace
namespace {
 
namespace css = ::com::sun::star;
 
class CursorPos:
    private ::cppu::BaseMutex,
    public ::cppu::WeakComponentImplHelper5<
        css::lang::XServiceInfo,
        css::frame::XStatusbarController,
        css::frame::XStatusListener,
        css::lang::XInitialization,
        css::util::XUpdatable>
{
public:
    explicit CursorPos(css::uno::Reference< css::uno::XComponentContext > const & context);
 
    // ::com::sun::star::lang::XServiceInfo:
    virtual ::rtl::OUString SAL_CALL getImplementationName() throw (css::uno::RuntimeException);
    virtual ::sal_Bool SAL_CALL supportsService(const ::rtl::OUString & ServiceName) throw (css::uno::RuntimeException);
    virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw (css::uno::RuntimeException);
 
    // ::com::sun::star::frame::XStatusbarController:
    virtual ::sal_Bool SAL_CALL mouseButtonDown(const css::awt::MouseEvent & aMouseEvent) throw (css::uno::RuntimeException);
    virtual ::sal_Bool SAL_CALL mouseMove(const css::awt::MouseEvent & aMouseEvent) throw (css::uno::RuntimeException);
    virtual ::sal_Bool SAL_CALL mouseButtonUp(const css::awt::MouseEvent & aMouseEvent) throw (css::uno::RuntimeException);
    virtual void SAL_CALL command(const css::awt::Point & aPos, ::sal_Int32 nCommand, ::sal_Bool bMouseEvent, const ::com::sun::star::uno::Any & aData) throw (css::uno::RuntimeException);
    virtual void SAL_CALL paint(const css::uno::Reference< css::awt::XGraphics > & xGraphics, const css::awt::Rectangle & rOutputRectangle, ::sal_Int32 nItemId, ::sal_Int32 nStyle) throw (css::uno::RuntimeException);
    virtual void SAL_CALL click() throw (css::uno::RuntimeException);
    virtual void SAL_CALL doubleClick() throw (css::uno::RuntimeException);
 
    // ::com::sun::star::lang::XEventListener:
    virtual void SAL_CALL disposing(const css::lang::EventObject & Source) throw (css::uno::RuntimeException);
 
    // ::com::sun::star::frame::XStatusListener:
    virtual void SAL_CALL statusChanged(const css::frame::FeatureStateEvent & State) throw (css::uno::RuntimeException);
 
    // ::com::sun::star::lang::XInitialization:
    virtual void SAL_CALL initialize(const css::uno::Sequence< ::com::sun::star::uno::Any > & aArguments) throw (css::uno::RuntimeException, css::uno::Exception);
 
    // ::com::sun::star::util::XUpdatable:
    virtual void SAL_CALL update() throw (css::uno::RuntimeException);
 
private:
    CursorPos(CursorPos &); // not defined
    void operator =(CursorPos &); // not defined
 
    virtual ~CursorPos() {}
 
    // overload WeakComponentImplHelperBase::disposing()
    // This function is called upon disposing the component,
    // if your component needs special work when it becomes
    // disposed, do it here.
    virtual void SAL_CALL disposing();
 
    bool                                                   m_bInitialized;
    ::rtl::OUString                                        m_aCommandURL;
    css::uno::Reference< css::uno::XComponentContext >     m_xContext;
    css::uno::Reference< css::frame::XFrame >              m_xFrame;
    css::uno::Reference< css::lang::XMultiServiceFactory > m_xServiceManager;
    css::uno::Reference< css::awt::XWindow >               m_xParentWindow;
};
 
CursorPos::CursorPos(css::uno::Reference< css::uno::XComponentContext > const & context) :
    ::cppu::WeakComponentImplHelper5<
        css::lang::XServiceInfo,
        css::frame::XStatusbarController,
        css::frame::XStatusListener,
        css::lang::XInitialization,
        css::util::XUpdatable>(m_aMutex),
    m_bInitialized( false ),
    m_xContext(context)
{
}
 
// overload WeakComponentImplHelperBase::disposing()
// This function is called upon disposing the component,
// if your component needs special work when it becomes
// disposed, do it here.
void SAL_CALL CursorPos::disposing()
{
    ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
    m_xContext.clear();
    m_xServiceManager.clear();
    m_xParentWindow.clear();
    m_xFrame.clear();
}
 
// com.sun.star.uno.XServiceInfo:
::rtl::OUString SAL_CALL CursorPos::getImplementationName() throw (css::uno::RuntimeException)
{
    return comp_CursorPos::_getImplementationName();
}
 
::sal_Bool SAL_CALL CursorPos::supportsService(::rtl::OUString const & serviceName) throw (css::uno::RuntimeException)
{
    css::uno::Sequence< ::rtl::OUString > serviceNames = comp_CursorPos::_getSupportedServiceNames();
    for (::sal_Int32 i = 0; i < serviceNames.getLength(); ++i) {
        if (serviceNames[i] == serviceName)
            return sal_True;
    }
    return sal_False;
}
 
css::uno::Sequence< ::rtl::OUString > SAL_CALL CursorPos::getSupportedServiceNames() throw (css::uno::RuntimeException)
{
    return comp_CursorPos::_getSupportedServiceNames();
}
 
// ::com::sun::star::frame::XStatusbarController:
::sal_Bool SAL_CALL CursorPos::mouseButtonDown(const css::awt::MouseEvent & aMouseEvent) throw (css::uno::RuntimeException)
{
    // TODO !!!
    // Exchange the default return implementation.
    // NOTE: Default initialized polymorphic structs can cause problems because of
    // missing default initialization of primitive types of some C++ compilers or
    // different Any initialization in Java and C++ polymorphic structs.
    return sal_False;
}
 
::sal_Bool SAL_CALL CursorPos::mouseMove(const css::awt::MouseEvent & aMouseEvent) throw (css::uno::RuntimeException)
{
    // TODO !!!
    // Exchange the default return implementation.
    // NOTE: Default initialized polymorphic structs can cause problems because of
    // missing default initialization of primitive types of some C++ compilers or
    // different Any initialization in Java and C++ polymorphic structs.
    return sal_False;
}
 
::sal_Bool SAL_CALL CursorPos::mouseButtonUp(const css::awt::MouseEvent & aMouseEvent) throw (css::uno::RuntimeException)
{
    // TODO !!!
    // Exchange the default return implementation.
    // NOTE: Default initialized polymorphic structs can cause problems because of
    // missing default initialization of primitive types of some C++ compilers or
    // different Any initialization in Java and C++ polymorphic structs.
    return sal_False;
}
 
void SAL_CALL CursorPos::command(const css::awt::Point & aPos, ::sal_Int32 nCommand, ::sal_Bool bMouseEvent, const ::com::sun::star::uno::Any & aData) throw (css::uno::RuntimeException)
{
    // TODO !!!
    // Insert your implementation here.
}
 
void SAL_CALL CursorPos::paint(const css::uno::Reference< css::awt::XGraphics > & xGraphics, const css::awt::Rectangle & rOutputRectangle, ::sal_Int32 nItemId, ::sal_Int32 nStyle) throw (css::uno::RuntimeException)
{
    // TODO !!!
    // Insert your implementation here.
}
 
void SAL_CALL CursorPos::click() throw (css::uno::RuntimeException)
{
    // TODO !!!
    // Insert your implementation here.
}
 
void SAL_CALL CursorPos::doubleClick() throw (css::uno::RuntimeException)
{
    // TODO !!!
    // Insert your implementation here.
}
 
// ::com::sun::star::lang::XEventListener:
void SAL_CALL CursorPos::disposing(const css::lang::EventObject & Source) throw (css::uno::RuntimeException)
{
    // TODO !!!
    // Insert your implementation here.
}
 
// ::com::sun::star::frame::XStatusListener:
void SAL_CALL CursorPos::statusChanged(const css::frame::FeatureStateEvent & State) throw (css::uno::RuntimeException)
{
    // TODO !!!
    // Insert your implementation here.
}
 
// ::com::sun::star::lang::XInitialization:
void SAL_CALL CursorPos::initialize(const css::uno::Sequence< ::com::sun::star::uno::Any > & aArguments) throw (css::uno::RuntimeException, css::uno::Exception)
{
    const rtl::OUString aFrameName( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
    const rtl::OUString aCommandURLName( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" ));
    const rtl::OUString aServiceManagerName( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" ));
    const rtl::OUString aParentWindow( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ));
 
    // Retrieve the arguments from the sequence to initialize our status bar controller
    ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
    if ( !m_bInitialized )
    {
        m_bInitialized = sal_True;
 
        css::beans::PropertyValue aPropValue;
        for ( int i = 0; i < aArguments.getLength(); i++ )
        {
            if ( aArguments[i] >>= aPropValue )
            {
                if ( aPropValue.Name.equalsAscii( "Frame" ))
                    aPropValue.Value >>= m_xFrame;
                else if ( aPropValue.Name.equalsAscii( "CommandURL" ))
                    aPropValue.Value >>= m_aCommandURL;
                else if ( aPropValue.Name.equalsAscii( "ServiceManager" ))
                    aPropValue.Value >>= m_xServiceManager;
                else if ( aPropValue.Name.equalsAscii( "ParentWindow" ))
                    aPropValue.Value >>= m_xParentWindow;
            }
        }
    }
}
 
// ::com::sun::star::util::XUpdatable:
void SAL_CALL CursorPos::update() throw (css::uno::RuntimeException)
{
    // TODO !!!
    // Insert your implementation here.
}
 
} // closing anonymous implementation namespace
 
 
 
// component helper namespace
namespace comp_CursorPos {
 
::rtl::OUString SAL_CALL _getImplementationName() {
    return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
        "org.openoffice.Office.UI.StatusbarController.comp.CursorPos"));
}
 
css::uno::Sequence< ::rtl::OUString > SAL_CALL _getSupportedServiceNames()
{
    css::uno::Sequence< ::rtl::OUString > s(1);
    s[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
        "com.sun.star.frame.StatusbarController"));
    return s;
}
 
css::uno::Reference< css::uno::XInterface > SAL_CALL _create(
    const css::uno::Reference< css::uno::XComponentContext > & context)
        SAL_THROW((css::uno::Exception))
{
    return static_cast< ::cppu::OWeakObject * >(new CursorPos(context));
}
 
} // closing component helper namespace
 
static ::cppu::ImplementationEntry const entries[] = {
    { &comp_CursorPos::_create,
      &comp_CursorPos::_getImplementationName,
      &comp_CursorPos::_getSupportedServiceNames,
      &::cppu::createSingleComponentFactory, 0, 0 },
    { 0, 0, 0, 0, 0, 0 }
};
 
extern "C" void SAL_CALL component_getImplementationEnvironment(
    const char ** envTypeName, uno_Environment **)
{
    *envTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}
 
extern "C" void * SAL_CALL component_getFactory(
    const char * implName, void * serviceManager, void * registryKey)
{
    return ::cppu::component_getFactoryHelper(
        implName, serviceManager, registryKey, entries);
}
 
extern "C" sal_Bool SAL_CALL component_writeInfo(
    void * serviceManager, void * registryKey)
{
    return ::cppu::component_writeInfoHelper(serviceManager, registryKey, entries);
}

The cursor position status bar controller

This chapter describes how to create a cursor position status bar controller. It uses the previous described concepts and descriptions to implement it.

The cursor position part

Personal tools