Framework/Tutorial/Statusbar Controller

    From The Document Foundation Wiki

    This tutorial will give you a detailed overview of the LibreOffice 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 LibreOffice status bar

    The LibreOffice 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 LibreOffice 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 LibreOffice installation folder. The default location is here:

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

    The following snippet shows the content of the OpenOffice 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 doesn'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 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 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 <idls>com.sun.star.frame.StatusbarController</idls>. The LibreOffice 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 <idls>com.sun.star.frame.StatusbarController</idls> service.

    //=============================================================================
    
     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 LibreOffice status bar implementation. The following illustration shows how the different interfaces are used within LibreOffice.

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

    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.  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.
    		
    		<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.
    
        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.
    
        @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.
            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 LibreOffice 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.

    <LibreOffice 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

    Apache Feather Logo.svg

    This work is licensed under the Apache License version 2.0