Framework/Tutorial/Statusbar Controller

From Apache OpenOffice Wiki
< Framework
Revision as of 14:24, 2 October 2007 by Fpe (Talk | contribs)

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 conbtroller. Everybody is invited to participate. May be 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] <?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

[xml] 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] 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:autosive %boolean; #IMPLIED
                    statusbar:ownertraw %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] 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] 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] 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] 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] 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] 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] 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.

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.

[cpp] //=============================================================================

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 toolbar 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 toolbar controller needs at least three additional arguments 
       provided as com::sun::star::beans::PropertyValue:
       Frame
       com::sun::star::frame::XFrame instance to which the toolbar 
       controller belongs.
       
       CommandURL
       a string which specifies the command a statusbar controller is bound.
       ServiceManager
       a com::sun::star::lang::XMultiServiceFactory instance which can 
       be used to create additional UNO services.
   */
   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

[cpp] module com { module sun { module star { module frame {

//============================================================================= /** makes it possible to receive events when the state of a feature changes.

Nobody guarantee any notification. Use combination of <type>XNotifyingDispatch</type> and <type>XDispatchResultListener</type> for that.

   @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

[cpp] module com { module sun { module star { module lang {

//=============================================================================

// DocMerge from xml: interface com::sun::star::lang::XInitialization /** initializes an object directly after its creation.

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.

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.

*/

published interface XInitialization: com::sun::star::uno::XInterface { //-------------------------------------------------------------------------

// DocMerge from xml: method com::sun::star::lang::XInitialization::initialize /** initializes the object.

It should be called directly after the object is created. */ void initialize( [in] sequence<any> aArguments ) raises( com::sun::star::uno::Exception ); }; //============================================================================= }; }; }; }; </code>

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

<code>[cpp] 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();

};

//============================================================================= </code>

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

<code>[cpp] 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.
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();

};

}; }; }; }; </code>

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

<code>[cpp] //=============================================================================

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.

       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] <?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] <?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.

[cpp]

  1. include "sal/config.h"
  2. include "cppuhelper/factory.hxx"
  3. include "cppuhelper/implementationentry.hxx"
  4. include "cppuhelper/compbase5.hxx"
  5. include "cppuhelper/basemutex.hxx"
  6. include "com/sun/star/lang/XServiceInfo.hpp"
  7. include "com/sun/star/frame/XStatusbarController.hpp"
  8. include "com/sun/star/frame/XStatusListener.hpp"
  9. include "com/sun/star/lang/XInitialization.hpp"
  10. include "com/sun/star/util/XUpdatable.hpp"
  11. include <com/sun/star/beans/PropertyValue.hpp>
  12. include "com/sun/star/frame/XFrame.hpp"
  13. 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