Framework/Tutorial/Statusbar Controller
TDF LibreOffice Document Liberation Project Community Blogs Weblate Nextcloud Redmine Ask LibreOffice Donate
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
- Programming with UNO
- C++ knowledge
- How to create an extension with the LibreOffice SDK
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.
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.
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.
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.
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.