Difference between revisions of "Framework/Article/OpenOffice.org 2.0 User Interface Controller Internals"

From Apache OpenOffice Wiki
Jump to: navigation, search
(Undo revision 200517 by Ldb (Talk))
 
(18 intermediate revisions by 4 users not shown)
Line 2: Line 2:
  
 
A typical OOo 2.0 document contains different user interface elements. They have to provide their functions to the user and display the current state of the document view.
 
A typical OOo 2.0 document contains different user interface elements. They have to provide their functions to the user and display the current state of the document view.
 +
 +
If you want to know about the different controller type then you should read the controller tutorials available in the [[Framework#Articles_.26_Tutorials|articles&tutorials chapter]].
  
 
'''How and in which infrastructure do they work?'''
 
'''How and in which infrastructure do they work?'''
Line 28: Line 30:
  
 
A generic menu item controller supports the following interfaces:
 
A generic menu item controller supports the following interfaces:
<code>[cpp]
+
<source lang="idl">
 
module com { module sun { module star { module frame {
 
module com { module sun { module star { module frame {
 
published interface XStatusListener: com::sun::star::lang::XEventListener
 
published interface XStatusListener: com::sun::star::lang::XEventListener
Line 38: Line 40:
 
};
 
};
 
}; }; }; };
 
}; }; }; };
 +
</source>
  
 +
<source lang="idl">
 
module com { module sun { module star { module frame {
 
module com { module sun { module star { module frame {
 
published struct FeatureStateEvent: com::sun::star::lang::EventObject
 
published struct FeatureStateEvent: com::sun::star::lang::EventObject
Line 55: Line 59:
  
 
   //-------------------------------------------------------------------------
 
   //-------------------------------------------------------------------------
   /** specifies whether the &lt;type&gt;XDispatch&lt;/type&gt; has to be requeried. */
+
   /** specifies whether the <type>XDispatch</type> has to be requeried. */
 
   boolean Requery;
 
   boolean Requery;
  
Line 63: Line 67:
 
};
 
};
 
}; }; }; };
 
}; }; }; };
</code>
+
</source>
  
 
It supports the following generic functions by listing to status updates provided by function statusChanged.<br/>
 
It supports the following generic functions by listing to status updates provided by function statusChanged.<br/>
Line 115: Line 119:
 
An abstract from the org.openoffice.Office.UI.Controller/Registered/PopupMenu:
 
An abstract from the org.openoffice.Office.UI.Controller/Registered/PopupMenu:
  
<code>[xml]
+
<source lang="xml">
 
<!DOCTYPE oor:component-data SYSTEM "../../../../../component-update.dtd">
 
<!DOCTYPE oor:component-data SYSTEM "../../../../../component-update.dtd">
 
<oor:component-data oor:name="Controller" oor:package="org.openoffice.Office.UI" xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 
<oor:component-data oor:name="Controller" oor:package="org.openoffice.Office.UI" xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
Line 132: Line 136:
 
   </node>
 
   </node>
 
   ...
 
   ...
</code>
+
</source>
 
A popup menu controller must support the following services / interfaces:<br />
 
A popup menu controller must support the following services / interfaces:<br />
  
<code>[cpp]
+
<source lang="idl">
 
module com { module sun { module star { module frame {
 
module com { module sun { module star { module frame {
  
 
service PopupMenuController
 
service PopupMenuController
 +
{
 
//-------------------------------------------------------------------------
 
//-------------------------------------------------------------------------
 
/** supports functions to initialize and update a popup menu controller
 
/** supports functions to initialize and update a popup menu controller
Line 176: Line 181:
 
     send this data to a controller implementation.
 
     send this data to a controller implementation.
 
*/
 
*/
interface com::sun::star::frame::XStatusListener;<br/>
+
interface com::sun::star::frame::XStatusListener;
 
};
 
};
 
}; }; }; };
 
}; }; }; };
</code>
+
</source>
  
<code>[cpp]
+
<source lang="idl">
 
module com { module sun { module star { module frame {
 
module com { module sun { module star { module frame {
  
 
interface XPopupMenuController : com::sun::star::uno::XInterface
 
interface XPopupMenuController : com::sun::star::uno::XInterface
 
+
{
 
     /** provides a com::sun::star::awt::XPopupMenu to a popup menu  
 
     /** provides a com::sun::star::awt::XPopupMenu to a popup menu  
 
         controller implementation. The controller must fill this popup  
 
         controller implementation. The controller must fill this popup  
Line 205: Line 210:
 
     */
 
     */
 
     void updatePopupMenu();
 
     void updatePopupMenu();
 +
};
  
 
}; }; }; };
 
}; }; }; };
</code>
+
</source>
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">module com { module sun { module star { module lang { <br /><br />published interface XInitialization: com::sun::star::uno::XInterface<br />{ <br /> // DocMerge from xml: method com::sun::star::lang::XInitialization::initialize<br /> /** initializes the object. <br /><br /> &lt;p&gt;It should be called directly after the object is created.<br /> */<br /> void initialize( [in] sequence&lt;any&gt; aArguments ) <br /> raises( com::sun::star::uno::Exception );<br />}; <br /><br />//============================================================================= <br /><br />}; }; }; };</font></font>
+
<source lang="idl">
 +
module com { module sun { module star { module lang {
  
<br />
+
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 has been created.
 +
    */
 +
    void initialize( [in] sequence< any > aArguments ) raises( com::sun::star::uno::Exception );
 +
};
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">module com { module sun { module star { module frame { </font></font>
+
}; }; }; };
 +
</source>
  
<br />
+
<source lang="idl">
 +
module com { module sun { module star { module frame {
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">published interface XStatusListener: com::sun::star::lang::XEventListener</font></font>
+
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 );
 +
};
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">{</font></font>
+
}; }; }; };
 +
</source>
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> /** is called when the status of the feature changes.<br /><br /> @param State<br /> provides information about changes of the requested feature<br /> */</font></font>
+
<source lang="idl">
 +
module com { module sun { module star { module frame {
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> [oneway] void statusChanged( [in] FeatureStateEvent State );</font></font>
+
published struct FeatureStateEvent: com::sun::star::lang::EventObject
 +
{
 +
    //-------------------------------------------------------------------------
 +
    /** contains the URL of the feature.                                    */
 +
    com::sun::star::util::URL FeatureURL;
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">};</font></font>
+
    //-------------------------------------------------------------------------
 +
    /** contains a descriptor of the feature for the user interface.        */
 +
    string FeatureDescriptor;
  
<br />
+
    //-------------------------------------------------------------------------
 +
    /** specifies whether the feature is currently enabled or disabled.      */
 +
    boolean IsEnabled;
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">}; }; }; };</font></font>
+
    //-------------------------------------------------------------------------
 +
    /** specifies whether the XDispatch object has to be re-queried.        */
 +
    boolean Requery;
  
<br />
+
    //-------------------------------------------------------------------------
 +
    /** contains the state of the feature in this dispatch.                  */
 +
    any State;
 +
};
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">module com { module sun { module star { module frame { </font></font>
+
}; }; }; };
 
+
</source>
<br />
+
 
+
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">published struct FeatureStateEvent: com::sun::star::lang::EventObject</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">{</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> //-------------------------------------------------------------------------</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> /** contains the URL of the feature. */</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> com::sun::star::util::URL FeatureURL;</font></font>
+
 
+
<br />
+
 
+
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> //-------------------------------------------------------------------------</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> /** contains a descriptor of the feature for the user interface.*/</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> string FeatureDescriptor;</font></font>
+
 
+
<br />
+
 
+
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> //-------------------------------------------------------------------------</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> /** specifies whether the feature is currently enabled or disabled. */</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> boolean IsEnabled;</font></font>
+
 
+
<br />
+
 
+
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> //-------------------------------------------------------------------------</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> /** specifies whether the &lt;type&gt;XDispatch&lt;/type&gt; has to be requeried. */</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> boolean Requery;</font></font>
+
 
+
<br />
+
 
+
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> //-------------------------------------------------------------------------</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> /** contains the state of the feature in this dispatch.*/</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> any State;</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">}; </font></font>
+
 
+
<br />
+
 
+
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">}; }; }; };</font></font>
+
 
+
<br />
+
 
+
The framework project provides a base class to implement popup menu controller easier. It can be found in ''framework/inc/helper/popupmenucontrollerbase.hxx''. There are several implementations for popup menu controller in ''framework/source/uielement'' which uses the base class and can be used as templates.
+
 
+
<br />
+
  
 +
The framework project provides a base class to implement popup menu controller easier. It can be found in ''framework/inc/helper/popupmenucontrollerbase.hxx''. There are several implementations for popup menu controller in ''framework/source/uielement'' which uses the base class and can be used as templates.<br/>
 +
<br/>
 
Currently OOo 2.0 provides the following popup menu controllers:
 
Currently OOo 2.0 provides the following popup menu controllers:
 
+
<br/>
<br />
+
  
 
{| width="100%" border="1" cellpadding="4"
 
{| width="100%" border="1" cellpadding="4"
Line 405: Line 390:
 
<font size="2">Provides a popup menu with all available wizards.</font>
 
<font size="2">Provides a popup menu with all available wizards.</font>
 
|}
 
|}
 
<br />
 
  
 
The menu bar is completely controlled by an UNO implementations and is not based on any old sfx2 code. Therefor old sfx2 based and new non-sfx2 application modules are equally supported.
 
The menu bar is completely controlled by an UNO implementations and is not based on any old sfx2 code. Therefor old sfx2 based and new non-sfx2 application modules are equally supported.
 
<br />
 
 
<br />
 
  
 
== Toolbar ==
 
== Toolbar ==
Line 422: Line 401:
 
<br /><br />
 
<br /><br />
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">module com { module sun { module star { module frame {<br /><br />service ToolbarController<br />{<br /> //-------------------------------------------------------------------------<br /> /** with this interface a component can receive events if a feature has <br /> changed.<br /><br /> &lt;p&gt;<br /> The toolbar controller implementation should register itself as a <br /> listener when its &lt;member scope="com::sun::star::util"&gt;XUpdatable&lt;/member&gt; <br /> interface has been called.<br /> &lt;/p&gt;<br /> */<br /> interface com::sun::star::frame::XStatusListener;<br /><br /> /** used to initialize a component with required arguments.<br /><br /> A toolbar controller needs at least three additional arguments <br /> provided as &lt;type scope="com::sun::star::beans"&gt;PropertyValue&lt;/type&gt;:<br /> &lt;ul&gt;<br /> &lt;li&gt;&lt;b&gt;Frame&lt;/b&gt;&lt;br&gt;a &lt;type scope="com::sun::star::frame"&gt;XFrame&lt;/type&gt; <br /> instance to which the toolbar controller belongs.&lt;/li&gt;<br /> &lt;li&gt;&lt;b&gt;CommandURL&lt;/b&gt;&lt;br&gt;a string which specifies the command a <br /> toolbar controller is bound.&lt;/li&gt;<br /> &lt;li&gt;&lt;b&gt;ServiceManager&lt;/b&gt;&lt;br&gt;a <br /> &lt;type scope="com::sun::star::lang"&gt;XMultiServiceFactory&lt;/type&gt;<br /> instance which can be used to create additional UNO services.&lt;/li&gt;<br /> &lt;/ul&gt;<br /> */<br /> interface com::sun::star::lang::XInitialization;<br /><br /> /** used to notify an implementation that it needs to add its listener or remove <br /> and add them again.<br /><br /> &lt;p&gt;<br /> A toolbar controller instance is ready for use after this call has been made <br /> the first time. The toolbar implementation guarantees that the controller's <br /> item window has been added to the toolbar and its reference is held by it.<br /> &lt;/p&gt;<br /> */<br /> interface com::sun::star::util::XUpdatable;<br /><br /> //-------------------------------------------------------------------------<br /> /** used to notify changed features and requests for additional user interface <br /> items.<br /><br /> &lt;p&gt;<br /> Mostly used by a toolbar implementation to forward information to and request<br /> services from a toolbar controller component. This interface must be useable <br /> after &lt;member scope="com::sun::star::lang"&gt;XInitialitation::initialize&lt;/member&gt; <br /> has been called. The behavior of the interface is undefined if the controller <br /> component hasn't been initialized.<br /> &lt;/p&gt;<br /> */<br /> interface com::sun::star::frame::XToolbarController;<br /><br /> //-------------------------------------------------------------------------<br /> /** used to notify and retrieve information that are specific for sub-toolbar <br /> controllers.<br /><br /> &lt;p&gt;<br /> Used by implementations that want to provide the toolbar button/sub-<br /> toolbar function feature. A controller supporting this interface exchanges <br /> the function of its own toolbar button, that opened the sub-toolbar, with <br /> the one that has been selected on the sub-toolbar.<br /> &lt;/p&gt;<br /> */<br /> [optional] interface ::com::sun::star::frame::XSubToolbarController;<br />};<br /><br />}; }; }; };</font></font>
+
<source lang="idl">
 +
module com { module sun { module star { module frame {
  
<br />
+
service ToolbarController
 +
{
 +
    //-------------------------------------------------------------------------
 +
    /** 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;
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">module com { module sun { module star { module frame { </font></font>
+
    //-------------------------------------------------------------------------
 +
    /** used to initialize a component with required arguments.
 +
       
 +
        A toolbar controller needs at least three additional arguments provided as
 +
        com::sun::star::beans::PropertyValue
  
<br />
+
        Frame
 +
        a com::sun::star::frame::XFrame instance to which the toolbar controller belongs.
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">published interface XStatusListener: com::sun::star::lang::XEventListener</font></font>
+
        CommandURL
 +
        a string which specifies the command a toolbar controller is bound.
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">{</font></font>
+
        ServiceManager
 +
        a com::sun::star::lang::XMultiServiceFactory instance which can be used to
 +
        create additional UNO services.
 +
    */
 +
    interface com::sun::star::lang::XInitialization;
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> /** is called when the status of the feature changes.<br /><br /> @param State<br /> provides information about changes of the requested feature<br /> */</font></font>
+
    //-------------------------------------------------------------------------
 +
    /** used to notify an implementation that it needs to add its listener or remove
 +
        and add them again.
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> [oneway] void statusChanged( [in] FeatureStateEvent State );</font></font>
+
        A toolbar controller instance is ready for use after this call has been made
 +
        the first time. The toolbar implementation guarantees that the controller's
 +
        item window has been added to the toolbar and its reference is held by it.
 +
    */
 +
    interface com::sun::star::util::XUpdatable;
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">};</font></font>
+
    //-------------------------------------------------------------------------
 +
    /** used to notify changed features and requests for additional user interface
 +
        items.
  
<br />
+
        Mostly used by a toolbar implementation to forward information to and request
 +
        services from a toolbar 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::XToolbarController;
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">}; }; }; };</font></font>
+
    //-------------------------------------------------------------------------
 +
    /** used to notify and retrieve information that are specific for sub-toolbar
 +
        controllers.
  
<br />
+
        Used by implementations that want to provide the toolbar button sub-toolbar
 +
        function feature. A controller supporting this interface exchanges the
 +
        function of its own toolbar button, that opened the sub-toolbar, with the
 +
        one that has been selected on the sub-toolbar.
 +
    */
 +
    [optional] interface ::com::sun::star::frame::XSubToolbarController;
 +
};
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">module com { module sun { module star { module frame { </font></font>
+
}; }; }; };
 +
</source>
  
<br />
+
<source lang="idl">
 +
module com { module sun { module star { module frame {
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">published struct FeatureStateEvent: com::sun::star::lang::EventObject</font></font>
+
published interface XStatusListener: com::sun::star::lang::XEventListener
 +
{
 +
/** is called when the status of the feature changes.
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">{</font></font>
+
@param State
 +
provides information about changes of the requested feature
 +
*/
 +
[oneway] void statusChanged( [in] FeatureStateEvent State );
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> //-------------------------------------------------------------------------</font></font>
+
};
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> /** contains the URL of the feature. */</font></font>
+
}; }; }; };
 +
</source>
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> com::sun::star::util::URL FeatureURL;</font></font>
+
<source lang="idl">
 +
module com { module sun { module star { module frame {
  
<br />
+
published struct FeatureStateEvent: com::sun::star::lang::EventObject
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> //-------------------------------------------------------------------------</font></font>
+
{
 +
//-------------------------------------------------------------------------
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> /** contains a descriptor of the feature for the user interface.*/</font></font>
+
/** contains the URL of the feature. */
 +
com::sun::star::util::URL FeatureURL;
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> string FeatureDescriptor;</font></font>
+
//-------------------------------------------------------------------------
  
<br />
+
/** contains a descriptor of the feature for the user interface.*/
 +
string FeatureDescriptor;
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> //-------------------------------------------------------------------------</font></font>
+
//-------------------------------------------------------------------------
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> /** specifies whether the feature is currently enabled or disabled. */</font></font>
+
/** specifies whether the feature is currently enabled or disabled. */
 +
boolean IsEnabled;
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> boolean IsEnabled;</font></font>
+
//-------------------------------------------------------------------------
  
<br />
+
/** specifies whether the <type>XDispatch</type> has to be requeried. */
 +
boolean Requery;
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> //-------------------------------------------------------------------------</font></font>
+
//-------------------------------------------------------------------------
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> /** specifies whether the &lt;type&gt;XDispatch&lt;/type&gt; has to be requeried. */</font></font>
+
/** contains the state of the feature in this dispatch.*/
 +
any State;
 +
};
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> boolean Requery;</font></font>
+
}; }; }; };
 +
</source>
  
<br />
+
<source lang="idl">
 +
module com { module sun { module star { module lang {
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> //-------------------------------------------------------------------------</font></font>
+
published interface XInitialization: com::sun::star::uno::XInterface
 +
{
 +
// DocMerge from xml: method com::sun::star::lang::XInitialization::initialize
 +
/** initializes the object.
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> /** contains the state of the feature in this dispatch.*/</font></font>
+
<p>It should be called directly after the object is created.
 +
*/
 +
void initialize( [in] sequence<any> aArguments )
 +
raises( com::sun::star::uno::Exception );
 +
};
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> any State;</font></font>
+
//=============================================================================  
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">}; </font></font>
+
}; }; }; };
 +
</source>
  
<br />
+
<source lang="idl">
 +
module com { module sun { module star { module util {
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">}; }; }; };</font></font>
+
published interface XUpdatable: com::sun::star::uno::XInterface
 +
{
 +
//-------------------------------------------------------------------------
 +
/** refreshes the data of the object from the connected data source. */
 +
void update();
 +
};
  
<br />
+
//=============================================================================
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">module com { module sun { module star { module lang { <br /><br />published interface XInitialization: com::sun::star::uno::XInterface<br />{ <br /> // DocMerge from xml: method com::sun::star::lang::XInitialization::initialize<br /> /** initializes the object. <br /><br /> &lt;p&gt;It should be called directly after the object is created.<br /> */<br /> void initialize( [in] sequence&lt;any&gt; aArguments ) <br /> raises( com::sun::star::uno::Exception );<br />}; <br /><br />//============================================================================= <br /><br />}; }; }; };</font></font>
+
}; }; }; };
 +
</source>
  
<br />
+
<source lang="idl">
 +
module com { module sun { module star { module frame {
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">module com { module sun { module star { module util {<br /><br />published interface XUpdatable: com::sun::star::uno::XInterface<br />{<br /> //-------------------------------------------------------------------------<br /> /** refreshes the data of the object from the connected data source. */<br /> void update();<br />};<br /><br />//=============================================================================<br /><br />}; }; }; };</font></font>
+
interface XToolbarController : com::sun::star::uno::XInterface
 +
{
 +
//=============================================================================
 +
/** provides a function to execute the command which is bound to the toolbar controller.
  
<br />
+
@param
 +
a combination of <type scope="com::sun::star::awt">KeyModifier</type> value that represent the current state of the modifier keys.
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">module com { module sun { module star { module frame {<br /><br />interface XToolbarController : com::sun::star::uno::XInterface<br />{<br /> //=============================================================================<br /> /** provides a function to execute the command which is bound to the toolbar controller.<br /><br /> @param <br /> a combination of &lt;type scope="com::sun::star::awt"&gt;KeyModifier&lt;/type&gt; value that represent the current state of the modifier keys.<br /><br /> &lt;p&gt;<br /> This function is usally called by a toolbar implementation when a user clicked on a toolbar button or pressed enter on the keyboard when the item has the input focus.<br /> &lt;/p&gt;<br /> */<br /> void execute( [in] short KeyModifier );<br /><br /> //=============================================================================<br /> /** notifies a component that a single click has been made on the toolbar item.<br /> */<br /> void click();<br /><br /> //=============================================================================<br /> /** notifies a component that a double click has been made on the toolbar item.<br /> */<br /> void doubleClick();<br /><br /> //=============================================================================<br /> /** requests to create a popup window for additional functions.<br /><br /> @return<br /> a &lt;type scope="com::sun::star::awt"&gt;XWindow&lt;/type&gt; which provides additional functions to the user. The reference must be empty if component does not want to provide a separate window.<br /> */<br /> com::sun::star::awt::XWindow createPopupWindow();<br /><br /> //=============================================================================<br /> /** requests to create an item window which can be added to the toolbar.<br /><br /> @param Parent<br /> a &lt;type scope="com::sun::star::awt"&gt;XWindow&lt;/type&gt; which must be used as a parent for the requested item window.<br /><br /> @return<br /> a &lt;type scope="com::sun::star::awt"&gt;XWindow&lt;/type&gt; which can be added to a toolbar. The reference must be empty if a component does not want to provide an item window.<br /> */<br /> com::sun::star::awt::XWindow createItemWindow( [in] com::sun::star::awt::XWindow Parent );<br />};<br /><br />}; }; }; };</font></font>
+
<p>
 +
This function is usally called by a toolbar implementation when a user clicked on a toolbar button or pressed enter on the keyboard when the item has the input focus.
 +
</p>
 +
*/
 +
void execute( [in] short KeyModifier );
  
<br />
+
//=============================================================================
 +
/** notifies a component that a single click has been made on the toolbar item.
 +
*/
 +
void click();
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">module com { module sun { module star { module frame {<br /><br />interface XSubToolbarController : com::sun::star::uno::XInterface<br />{<br /> //=============================================================================<br /> /** if the controller features a sub-toolbar. <br /><br /> @return<br /> &lt;TRUE/&gt; if the controller offers a sub toolbar, otherwise &lt;FALSE/&gt;.<br /><br /> &lt;p&gt;<br /> Enables implementations to dynamically decide to support sub-toolbars<br /> or not.<br /> &lt;/p&gt;<br /> */<br /> boolean opensSubToolbar();<br /><br /> //=============================================================================<br /> /** provides the resource URL of the sub-toolbar this controller opens.<br /><br /> @return<br /> name of the sub-toolbar this controller offers. A empty string <br /> will be interpreted as if this controller offers no sub-toolbar.<br /> */<br /> string getSubToolbarName();<br /><br /> //=============================================================================<br /> /** gets called to notify a controller that a sub-toolbar function has been <br /> selected.<br /><br /> @param aCommand<br /> a string which identifies the function that has been selected by<br /> a user.<br /> */<br /> void functionSelected( [in] string aCommand );<br /><br /> //=============================================================================<br /> /** gets called to notify a controller that it should set an image which<br /> represents the current selected function.<br /><br /> &lt;p&gt;<br /> Only the controller instance is able to set the correct image for the<br /> current function. A toolbar implementation will ask sub-toolbar <br /> controllers to update their image whenever it has to update the images<br /> of all its buttons.<br /> &lt;/p&gt;<br /> */<br /> void updateImage();<br />};<br /><br />}; }; }; }; </font></font>
+
//=============================================================================
 +
/** notifies a component that a double click has been made on the toolbar item.
 +
*/
 +
void doubleClick();
  
<br />
+
//=============================================================================
 +
/** requests to create a popup window for additional functions.
 +
 
 +
@return
 +
a <type scope="com::sun::star::awt">XWindow</type> which provides additional functions to the user. The reference must be empty if component does not want to provide a separate window.
 +
*/
 +
com::sun::star::awt::XWindow createPopupWindow();
 +
 
 +
//=============================================================================
 +
/** requests to create an item window which can be added to the toolbar.
 +
 
 +
@param Parent
 +
a <type scope="com::sun::star::awt">XWindow</type> which must be used as a parent for the requested item window.
 +
 
 +
@return
 +
a <type scope="com::sun::star::awt">XWindow</type> which can be added to a toolbar. The reference must be empty if a component does not want to provide an item window.
 +
*/
 +
com::sun::star::awt::XWindow createItemWindow( [in] com::sun::star::awt::XWindow Parent );
 +
};
 +
 
 +
}; }; }; };
 +
</source>
 +
 
 +
<source lang="idl">
 +
module com { module sun { module star { module frame {
 +
 
 +
interface XSubToolbarController : com::sun::star::uno::XInterface
 +
{
 +
//=============================================================================
 +
/** if the controller features a sub-toolbar.
 +
 
 +
@return
 +
<TRUE/> if the controller offers a sub toolbar, otherwise <FALSE/>.
 +
 
 +
<p>
 +
Enables implementations to dynamically decide to support sub-toolbars
 +
or not.
 +
</p>
 +
*/
 +
boolean opensSubToolbar();
 +
 
 +
//=============================================================================
 +
/** provides the resource URL of the sub-toolbar this controller opens.
 +
 
 +
@return
 +
name of the sub-toolbar this controller offers. A empty string
 +
will be interpreted as if this controller offers no sub-toolbar.
 +
*/
 +
string getSubToolbarName();
 +
 
 +
//=============================================================================
 +
/** gets called to notify a controller that a sub-toolbar function has been
 +
selected.
 +
 
 +
@param aCommand
 +
a string which identifies the function that has been selected by
 +
a user.
 +
*/
 +
void functionSelected( [in] string aCommand );
 +
 
 +
//=============================================================================
 +
/** gets called to notify a controller that it should set an image which
 +
represents the current selected function.
 +
 
 +
<p>
 +
Only the controller instance is able to set the correct image for the
 +
current function. A toolbar implementation will ask sub-toolbar
 +
controllers to update their image whenever it has to update the images
 +
of all its buttons.
 +
</p>
 +
*/
 +
void updateImage();
 +
};
 +
 
 +
}; }; }; };
 +
</source>
  
 
=== <font color="#000000"><font face="Albany, serif"><font size="5">Generic toolbar item controller</font></font></font> ===
 
=== <font color="#000000"><font face="Albany, serif"><font size="5">Generic toolbar item controller</font></font></font> ===
Line 621: Line 765:
 
An abstract from the Controller.xcu with registered specific toolbar item controllers:
 
An abstract from the Controller.xcu with registered specific toolbar item controllers:
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> ...</font></font>
+
<source lang="xml">
 +
...
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">&lt;node oor:name="ToolBar"&gt;<br /> &lt;node oor:name="c1" oor:op="replace"&gt;<br /> &lt;prop oor:name="Command"&gt;<br /> &lt;value&gt;.uno:DBNewForm&lt;/value&gt;<br /> &lt;/prop&gt;<br /> &lt;prop oor:name="Module"&gt;<br /> &lt;value&gt;com.sun.star.sdb.OfficeDatabaseDocument&lt;/value&gt;<br /> &lt;/prop&gt;<br /> &lt;prop oor:name="Controller"&gt;<br /> &lt;value&gt;com.sun.star.sdb.ApplicationToolboxController&lt;/value&gt;<br /> &lt;/prop&gt;<br /> &lt;/node&gt;<br /> &lt;node oor:name="c2" oor:op="replace"&gt;<br /> &lt;prop oor:name="Command"&gt;<br /> &lt;value&gt;.uno:Refresh&lt;/value&gt;<br /> &lt;/prop&gt;<br /> &lt;prop oor:name="Module"&gt;<br /> &lt;value&gt;com.sun.star.sdb.OfficeDatabaseDocument&lt;/value&gt;<br /> &lt;/prop&gt;<br /> &lt;prop oor:name="Controller"&gt;<br /> &lt;value&gt;com.sun.star.sdb.ApplicationToolboxController&lt;/value&gt;<br /> &lt;/prop&gt;<br /> &lt;/node&gt;<br /> &lt;/node&gt;</font></font>
+
<node oor:name="ToolBar">
 +
<node oor:name="c1" oor:op="replace">
 +
  <prop oor:name="Command">
 +
  <value>.uno:DBNewForm</value>
 +
  </prop>
 +
  <prop oor:name="Module">
 +
  <value>com.sun.star.sdb.OfficeDatabaseDocument</value>
 +
  </prop>
 +
  <prop oor:name="Controller">
 +
  <value>com.sun.star.sdb.ApplicationToolboxController</value>
 +
  </prop>
 +
</node>
 +
<node oor:name="c2" oor:op="replace">
 +
  <prop oor:name="Command">
 +
  <value>.uno:Refresh</value>
 +
  </prop>
 +
  <prop oor:name="Module">
 +
  <value>com.sun.star.sdb.OfficeDatabaseDocument</value>
 +
  </prop>
 +
  <prop oor:name="Controller">
 +
  <value>com.sun.star.sdb.ApplicationToolboxController</value>
 +
  </prop>
 +
</node>
 +
</node>
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> ...</font></font>
+
...
 
+
</source>
<br /><br />
+
  
 
The framework provides a base class which makes it much easier to implement UNO based specific toolbar item controllers. It can be found in svtools/inc/toolboxcontroller.hxx.
 
The framework provides a base class which makes it much easier to implement UNO based specific toolbar item controllers. It can be found in svtools/inc/toolboxcontroller.hxx.
Line 633: Line 800:
 
The sfx2 based specific toolbar item controllers are registered by calling ''ToolbarControllerClass''<nowiki>::RegisterControl(SlotID, SfxModule* ). The framework implementation uses a special toolbar controller factory to create instances of sfx2 based specific toolbar item controllers. Sfx2 based specific toolbar controllers can use the known base class sfx2/inc/tbxctrl.hxx. It's a special wrapper which converts calls to the its UNO interfaces to the needs of sfx2 based toolbar controllers.</nowiki>
 
The sfx2 based specific toolbar item controllers are registered by calling ''ToolbarControllerClass''<nowiki>::RegisterControl(SlotID, SfxModule* ). The framework implementation uses a special toolbar controller factory to create instances of sfx2 based specific toolbar item controllers. Sfx2 based specific toolbar controllers can use the known base class sfx2/inc/tbxctrl.hxx. It's a special wrapper which converts calls to the its UNO interfaces to the needs of sfx2 based toolbar controllers.</nowiki>
  
<br /><br />
+
<source lang="cpp">
 +
class SFX2_DLLPUBLIC SfxToolBoxControl:
 +
    public ::com::sun::star::awt::XDockableWindowListener,
 +
    public ::com::sun::star::frame::XSubToolbarController,
 +
    public svt::ToolboxController
 +
{
 +
    friend class SfxToolbox;
 +
    friend class SfxToolBox_Impl;
 +
    friend class SfxToolboxCustomizer;
 +
    friend class SfxPopupWindow;
 +
    friend struct SfxTbxCtrlFactory;
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">class SFX2_DLLPUBLIC SfxToolBoxControl:<br /> public ::com::sun::star::awt::XDockableWindowListener,<br /> public ::com::sun::star::frame::XSubToolbarController,<br /> public svt::ToolboxController <br />{<br />friend class SfxToolbox;<br />friend class SfxToolBox_Impl;<br />friend class SfxToolboxCustomizer;<br />friend class SfxPopupWindow;<br />friend struct SfxTbxCtrlFactory;<br /><br /> SfxToolBoxControl_Impl* pImpl;<br /><br />protected:<br /> DECL_LINK( PopupModeEndHdl, void * );<br /> DECL_LINK( ClosePopupWindow, SfxPopupWindow * );<br /><br /> // old SfxToolBoxControl methods<br /> virtual void StateChanged( USHORT nSID, SfxItemState eState, const SfxPoolItem* pState );<br /> virtual void Select( BOOL bMod1 = FALSE );<br /> virtual void Select( USHORT nModifier );<br /><br /> virtual void DoubleClick();<br /> virtual void Click();<br /> virtual SfxPopupWindowType GetPopupWindowType() const;<br /> virtual SfxPopupWindow* CreatePopupWindow();<br /> virtual SfxPopupWindow* CreatePopupWindowCascading();<br /> virtual Window* CreateItemWindow( Window *pParent );<br /><br /> // Must be called by subclass to set a new popup window instance<br /> void SetPopupWindow( SfxPopupWindow* pWindow );<br /><br /> // XInterface<br /> virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type &amp; rType ) throw(::com::sun::star::uno::RuntimeException);<br /> virtual void SAL_CALL acquire() throw();<br /> virtual void SAL_CALL release() throw();<br /><br /> // XEventListener<br /> virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject&amp; aEvent ) throw( ::com::sun::star::uno::RuntimeException );<br /><br /> // XComponent<br /> virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException);<br /><br /> // new controller API<br /> // XStatusListener<br /> virtual void SAL_CALL statusChanged( const ::com::sun::star::frame::FeatureStateEvent&amp; Event ) throw ( ::com::sun::star::uno::RuntimeException );<br /><br /> // XToolbarController<br /> virtual void SAL_CALL execute( sal_Int16 KeyModifier ) <br /> throw (::com::sun::star::uno::RuntimeException);<br /> virtual void SAL_CALL click() <br /> throw (::com::sun::star::uno::RuntimeException);<br /> virtual void SAL_CALL doubleClick() <br /> throw (::com::sun::star::uno::RuntimeException);<br /> virtual ::com::sun::star::uno::Reference&lt; ::com::sun::star::awt::XWindow &gt; SAL_CALL createPopupWindow() <br /> throw (::com::sun::star::uno::RuntimeException);<br /> virtual ::com::sun::star::uno::Reference&lt; ::com::sun::star::awt::XWindow &gt; SAL_CALL createItemWindow( const ::com::sun::star::uno::Reference&lt; ::com::sun::star::awt::XWindow &gt;&amp; rParent ) <br /> throw (::com::sun::star::uno::RuntimeException);<br /><br /> // XSubToolbarController<br /> virtual ::sal_Bool SAL_CALL opensSubToolbar( ) throw (::com::sun::star::uno::RuntimeException);<br /> virtual ::rtl::OUString SAL_CALL getSubToolbarName( ) throw (::com::sun::star::uno::RuntimeException);<br /> virtual void SAL_CALL functionSelected( const ::rtl::OUString&amp; aCommand ) throw (::com::sun::star::uno::RuntimeException);<br /> virtual void SAL_CALL updateImage( ) throw (::com::sun::star::uno::RuntimeException);<br /><br /> // XDockableWindowListener<br /> virtual void SAL_CALL startDocking( const ::com::sun::star::awt::DockingEvent&amp; e ) throw (::com::sun::star::uno::RuntimeException);<br /> virtual ::com::sun::star::awt::DockingData SAL_CALL docking( const ::com::sun::star::awt::DockingEvent&amp; e ) throw (::com::sun::star::uno::RuntimeException);<br /> virtual void SAL_CALL endDocking( const ::com::sun::star::awt::EndDockingEvent&amp; e ) throw (::com::sun::star::uno::RuntimeException);<br /> virtual sal_Bool SAL_CALL prepareToggleFloatingMode( const ::com::sun::star::lang::EventObject&amp; e ) throw (::com::sun::star::uno::RuntimeException);<br /> virtual void SAL_CALL toggleFloatingMode( const ::com::sun::star::lang::EventObject&amp; e ) throw (::com::sun::star::uno::RuntimeException); <br /> virtual void SAL_CALL closed( const ::com::sun::star::lang::EventObject&amp; e ) throw (::com::sun::star::uno::RuntimeException);<br /> virtual void SAL_CALL endPopupMode( const ::com::sun::star::awt::EndPopupModeEvent&amp; e ) throw (::com::sun::star::uno::RuntimeException);<br /><br /> // helper methods<br /> void createAndPositionSubToolBar( const ::rtl::OUString&amp; rSubToolBarResName );<br /> ::Size getPersistentFloatingSize( const ::com::sun::star::uno::Reference&lt; ::com::sun::star::frame::XFrame &gt;&amp; xFrame, const ::rtl::OUString&amp; rSubToolBarResName );<br /><br />public:<br /> SFX_DECL_TOOLBOX_CONTROL();<br /><br /> SfxToolBoxControl( USHORT nSlotID, USHORT nId, ToolBox&amp; rBox, BOOL bShowStrings = FALSE );<br /> virtual ~SfxToolBoxControl();<br /><br /> ToolBox&amp; GetToolBox() const;<br /> unsigned short GetId() const;<br /> unsigned short GetSlotId() const;<br /><br /> void Dispatch( </font></font>
+
    SfxToolBoxControl_Impl* pImpl;
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> const ::rtl::OUString&amp; aCommand, <br /> ::com::sun::star::uno::Sequence&lt; ::com::sun::star::beans::PropertyValue &gt;&amp; aArgs );<br /> static void Dispatch( </font></font>
+
protected:
 +
    DECL_LINK( PopupModeEndHdl, void * );
 +
    DECL_LINK( ClosePopupWindow, SfxPopupWindow * );
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">const ::com::sun::star::uno::Reference&lt; ::com::sun::star::frame::XDispatchProvider &gt;&amp; rDispatchProvider, const rtl::OUString&amp; rCommand, ::com::sun::star::uno::Sequence&lt; ::com::sun::star::beans::PropertyValue &gt;&amp; aArgs );<br /><br /> static SfxItemState GetItemState( const SfxPoolItem* pState );<br /> static SfxToolBoxControl* CreateControl( USHORT nSlotId, USHORT nTbxId, ToolBox *pBox, SfxModule *pMod );<br />};</font></font>
+
    // old SfxToolBoxControl methods
 +
    virtual void StateChanged( USHORT nSID, SfxItemState eState, const SfxPoolItem* pState );
 +
    virtual void Select( BOOL bMod1 = FALSE );
 +
    virtual void Select( USHORT nModifier );
  
<br />
+
    virtual void DoubleClick();
 +
    virtual void Click();
 +
    virtual SfxPopupWindowType GetPopupWindowType() const;
 +
    virtual SfxPopupWindow* CreatePopupWindow();
 +
    virtual SfxPopupWindow* CreatePopupWindowCascading();
 +
    virtual Window* CreateItemWindow( Window *pParent );
  
<br />
+
    // Must be called by subclass to set a new popup window instance
 +
    void SetPopupWindow( SfxPopupWindow* pWindow );
 +
 
 +
    // XInterface
 +
    virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
 +
    virtual void SAL_CALL acquire() throw();
 +
    virtual void SAL_CALL release() throw();
 +
 
 +
    // XEventListener
 +
    virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& aEvent ) throw( ::com::sun::star::uno::RuntimeException );
 +
 
 +
    // XComponent
 +
    virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException);
 +
 
 +
    // new controller API
 +
    // XStatusListener
 +
    virtual void SAL_CALL statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw ( ::com::sun::star::uno::RuntimeException );
 +
 
 +
    // XToolbarController
 +
    virtual void SAL_CALL execute( sal_Int16 KeyModifier )
 +
    throw (::com::sun::star::uno::RuntimeException);
 +
    virtual void SAL_CALL click()
 +
    throw (::com::sun::star::uno::RuntimeException);
 +
    virtual void SAL_CALL doubleClick()
 +
    throw (::com::sun::star::uno::RuntimeException);
 +
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > SAL_CALL createPopupWindow()
 +
    throw (::com::sun::star::uno::RuntimeException);
 +
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > SAL_CALL createItemWindow( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& rParent )
 +
    throw (::com::sun::star::uno::RuntimeException);
 +
 
 +
    // XSubToolbarController
 +
    virtual ::sal_Bool SAL_CALL opensSubToolbar( ) throw (::com::sun::star::uno::RuntimeException);
 +
    virtual ::rtl::OUString SAL_CALL getSubToolbarName( ) throw (::com::sun::star::uno::RuntimeException);
 +
    virtual void SAL_CALL functionSelected( const ::rtl::OUString& aCommand ) throw (::com::sun::star::uno::RuntimeException);
 +
    virtual void SAL_CALL updateImage( ) throw (::com::sun::star::uno::RuntimeException);
 +
 
 +
    // XDockableWindowListener
 +
    virtual void SAL_CALL startDocking( const ::com::sun::star::awt::DockingEvent& e ) throw (::com::sun::star::uno::RuntimeException);
 +
    virtual ::com::sun::star::awt::DockingData SAL_CALL docking( const ::com::sun::star::awt::DockingEvent& e ) throw (::com::sun::star::uno::RuntimeException);
 +
    virtual void SAL_CALL endDocking( const ::com::sun::star::awt::EndDockingEvent& e ) throw (::com::sun::star::uno::RuntimeException);
 +
    virtual sal_Bool SAL_CALL prepareToggleFloatingMode( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException);
 +
    virtual void SAL_CALL toggleFloatingMode( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException);
 +
    virtual void SAL_CALL closed( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException);
 +
    virtual void SAL_CALL endPopupMode( const ::com::sun::star::awt::EndPopupModeEvent& e ) throw (::com::sun::star::uno::RuntimeException);
 +
 
 +
    // helper methods
 +
    void createAndPositionSubToolBar( const ::rtl::OUString& rSubToolBarResName );
 +
    ::Size getPersistentFloatingSize( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame, const ::rtl::OUString& rSubToolBarResName );
 +
 
 +
public:
 +
    SFX_DECL_TOOLBOX_CONTROL();
 +
 
 +
    SfxToolBoxControl( USHORT nSlotID, USHORT nId, ToolBox& rBox, BOOL bShowStrings = FALSE );
 +
    virtual ~SfxToolBoxControl();
 +
 
 +
    ToolBox& GetToolBox() const;
 +
    unsigned short GetId() const;
 +
    unsigned short GetSlotId() const;
 +
 
 +
    void Dispatch(
 +
    const ::rtl::OUString& aCommand,
 +
    ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArgs );
 +
    static void Dispatch(
 +
    const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >& rDispatchProvider, const rtl::OUString& rCommand, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArgs );
 +
 
 +
    static SfxItemState GetItemState( const SfxPoolItem* pState );
 +
    static SfxToolBoxControl* CreateControl( USHORT nSlotId, USHORT nTbxId, ToolBox *pBox, SfxModule *pMod );
 +
};
 +
</source>
  
 
== Statusbar ==
 
== Statusbar ==
Line 653: Line 908:
 
A statusbar item controller must support the following services and interfaces.
 
A statusbar item controller must support the following services and interfaces.
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">module com { module sun { module star { module frame {<br /><br />service StatusbarController<br />{<br /> //-------------------------------------------------------------------------<br /> /** with this interface a component can receive events if a feature has <br /> changed.<br /><br /> &lt;p&gt;<br /> The statusbar controller implementation should register itself as a <br /> listener when its &lt;member scope="com::sun::star::util"&gt;XUpdatable&lt;/member&gt; <br /> interface has been called.<br /> &lt;/p&gt;<br /> */<br /> interface com::sun::star::frame::XStatusListener;<br /><br /> /** used to initialize a component with required arguments.<br /><br /> &lt;b&gt;A statusbar controller needs at least three additional arguments <br /> provided as &lt;type scope="com::sun::star::beans"&gt;PropertyValue&lt;/type&gt;:<br /> &lt;ul&gt;<br /> &lt;li&gt;&lt;b&gt;Frame&lt;/b&gt;&lt;br&gt;a <br /> &lt;type scope="com::sun::star::frame"&gt;XFrame&lt;/type&gt; instance<br /> to which the toolbar controller belongs.&lt;/li&gt;<br /> &lt;li&gt;&lt;b&gt;CommandURL&lt;/b&gt;&lt;br&gt;a string which specifies the command a <br /> statusbar controller is bound.&lt;/li&gt;<br /> &lt;li&gt;&lt;b&gt;ServiceManager&lt;/b&gt;&lt;br&gt;a &lt;type scope="com::sun::star::lang"&gt;<br /> XMultiServiceFactory&lt;/type&gt; instance which can be used to <br /> create additional UNO services.&lt;/li&gt;<br /> &lt;/ul&gt;<br /> */<br /> interface com::sun::star::lang::XInitialization;<br /><br /> /** used to notify an implementation that it needs to add its listener or <br /> remove and add them again.<br /><br /> &lt;p&gt;<br /> A status bar controller instance is ready for use after this call has <br /> been made the first time. The status bar implementation guarentees that <br /> the controller's item window has been added to the status bar and its <br /> reference is held by it.<br /> &lt;/p&gt;<br /> */<br /> interface com::sun::star::util::XUpdatable;<br /><br /> //-------------------------------------------------------------------------<br /> /** used to notify changed features and requests for additional user <br /> interface items.<br /><br /> &lt;p&gt;<br /> Mostly used by a status bar implementation to forward information to <br /> and request services from a status bar controller component. This <br /> interface must be useable after <br /> &lt;member scope="com::sun::star::lang"&gt;XInitialitation::initialize&lt;/member&gt; <br /> has been called. The behavior of the interface is undefined if the <br /> controller component hasn't been initialized.<br /> &lt;/p&gt;<br /> */<br /> interface com::sun::star::frame::XStatusbarController;<br />};<br /><br />}; }; }; }; </font></font>
+
<source lang="idl">
 +
module com { module sun { module star { module frame {
  
<br /><br />
+
service StatusbarController
 +
{
 +
//-------------------------------------------------------------------------
 +
/** with this interface a component can receive events if a feature has
 +
changed.
  
<code>[cpp]
+
<p>
module com { module sun { module star { module frame { </font></font>
+
The statusbar controller implementation should register itself as a
 +
listener when its <member scope="com::sun::star::util">XUpdatable</member>
 +
interface has been called.
 +
</p>
 +
*/
 +
interface com::sun::star::frame::XStatusListener;
 +
 
 +
/** used to initialize a component with required arguments.
 +
 
 +
<b>A statusbar controller needs at least three additional arguments
 +
provided as <type scope="com::sun::star::beans">PropertyValue</type>:
 +
<ul>
 +
<li><b>Frame</b><br>a
 +
<type scope="com::sun::star::frame">XFrame</type> instance
 +
to which the toolbar controller belongs.</li>
 +
<li><b>CommandURL</b><br>a string which specifies the command a
 +
statusbar controller is bound.</li>
 +
<li><b>ServiceManager</b><br>a <type scope="com::sun::star::lang">
 +
XMultiServiceFactory</type> instance which can be used to
 +
create additional UNO services.</li>
 +
</ul>
 +
*/
 +
interface com::sun::star::lang::XInitialization;
 +
 
 +
/** used to notify an implementation that it needs to add its listener or
 +
remove and add them again.
 +
 
 +
<p>
 +
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.
 +
</p>
 +
*/
 +
interface com::sun::star::util::XUpdatable;
 +
 
 +
//-------------------------------------------------------------------------
 +
/** used to notify changed features and requests for additional user
 +
interface items.
 +
 
 +
<p>
 +
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
 +
<member scope="com::sun::star::lang">XInitialitation::initialize</member>
 +
has been called. The behavior of the interface is undefined if the
 +
controller component hasn't been initialized.
 +
</p>
 +
*/
 +
interface com::sun::star::frame::XStatusbarController;
 +
};
 +
 
 +
}; }; }; };
 +
</source>
 +
 
 +
<source lang="idl">
 +
module com { module sun { module star { module frame {
  
 
published interface XStatusListener: com::sun::star::lang::XEventListener
 
published interface XStatusListener: com::sun::star::lang::XEventListener
Line 672: Line 988:
  
 
}; }; }; };
 
}; }; }; };
</code>
+
</source>
  
<code>[cpp]
+
<source lang="idl">
 
module com { module sun { module star { module frame {
 
module com { module sun { module star { module frame {
  
Line 706: Line 1,022:
 
};
 
};
 
}; }; }; };
 
}; }; }; };
</code>
+
</source>
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">module com { module sun { module star { module lang { <br /><br />published interface XInitialization: com::sun::star::uno::XInterface<br />{ <br /> // DocMerge from xml: method com::sun::star::lang::XInitialization::initialize<br /> /** initializes the object. <br /><br /> &lt;p&gt;It should be called directly after the object is created.<br /> */<br /> void initialize( [in] sequence&lt;any&gt; aArguments ) <br /> raises( com::sun::star::uno::Exception );<br />}; <br /><br />//============================================================================= <br /><br />}; }; }; };</font></font>
+
<source lang="idl">
 +
module com { module sun { module star { module lang {  
  
<br />
+
published interface XInitialization: com::sun::star::uno::XInterface
 +
{
 +
// DocMerge from xml: method com::sun::star::lang::XInitialization::initialize
 +
/** initializes the object.
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">module com { module sun { module star { module util {<br /><br />published interface XUpdatable: com::sun::star::uno::XInterface<br />{<br /> //-------------------------------------------------------------------------<br /> /** refreshes the data of the object from the connected data source. */<br /> void update();<br />};<br /><br />//=============================================================================<br /><br />}; }; }; };</font></font>
+
<p>It should be called directly after the object is created.
 +
*/
 +
void initialize( [in] sequence<any> aArguments )
 +
raises( com::sun::star::uno::Exception );
 +
};  
  
<br />
+
//=============================================================================
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">module com { module sun { module star { module frame {<br /><br />interface XStatusbarController : ::com::sun::star::uno::XInterface<br />{<br /> //=============================================================================<br /> /** is called by a status bar if the mouse position is within the controller <br /> and a mouse button has been pressed. If the controller has captured the <br /> mouse input this function is also called when the mouse position is not <br /> within the controller.<br /><br /> @param aMouseEvent<br /> current information about the mouse pointer.<br /><br /> @return<br /> return &lt;TRUE/&gt; if the event should not be processed and &lt;FALSE/&gt; <br /> if the event should be processed by the status bar.<br /> */<br /> boolean mouseButtonDown( [in] ::com::sun::star::awt::MouseEvent aMouseEvent );<br /><br /> //=============================================================================<br /> /** is called by a status bar if the mouse position is within the controller <br /> and a mouse has been moved. If the controller has captured the <br /> mouse input this function is also called when the mouse position is not <br /> within the controller.<br /><br /> @param aMouseEvent<br /> current information about the mouse pointer.<br /><br /> @return<br /> return &lt;TRUE/&gt; if the event should not be processed and &lt;FALSE/&gt; <br /> if the event should be processed by the status bar.<br /> */<br /> boolean mouseMove( [in] ::com::sun::star::awt::MouseEvent aMouseEvent );<br /><br /> //=============================================================================<br /> /** is called by a status bar if the mouse position is within the controller <br /> and a mouse button has been released. If the controller has captured the <br /> mouse input this function is also called when the mouse position is not <br /> within the controller.<br /><br /> @param aMouseEvent<br /> current information about the mouse pointer.<br /><br /> @return<br /> return &lt;TRUE/&gt; if the event should not be processed and &lt;FALSE/&gt; <br /> if the event should be processed by the status bar.<br /> */<br /> boolean mouseButtonUp( [in] ::com::sun::star::awt::MouseEvent aMouseEvent );<br /><br /> //=============================================================================<br /> /** is called by a status bar if a command event is available for a controller.<br /><br /> @param aPos<br /> the current mouse position in pixel.<br /><br /> @param nCommand<br /> describes which command has been invoked.<br /><br /> @param bMouseEvent<br /> &lt;TRUE/&gt; if the command is based on a mouse event, otherwise &lt;FALSE/&gt;.<br /><br /> @param aData<br /> for future use only.<br /> */<br /> void command( [in] ::com::sun::star::awt::Point aPos,<br /> [in] long nCommand,<br /> [in] boolean bMouseEvent,<br /> [in] any aData );<br /><br /> //=============================================================================<br /> /** is called by a status bar if a command event is available for a controller.<br /><br /> @param xGraphics<br /> the current graphics which should be used for painting.<br /><br /> @param rOutputRectangle<br /> the output rectangle for graphic operations.<br /><br /> @param nItemId<br /> the item id of the controller.<br /><br /> @param nStyle<br /> the style of the statusbar item. The controller should respect the provided</font></font>
+
}; }; }; };
 +
</source>
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">style when paints.<br /> */<br /> void paint( [in] ::com::sun::star::awt::XGraphics xGraphics,<br /> [in] ::com::sun::star::awt::Rectangle rOutputRectangle,<br /> [in] long nItemId,<br /> [in] long nStyle );<br /><br /> //=============================================================================<br /> /** is called by a status bar if the user clicked with mouse into the <br /> field of the corresponding control.<br /> */<br /> void click();<br /><br /> //=============================================================================<br /> /** is called by a status bar if the user double-clicked with mouse <br /> into the field of the corresponding control.<br /> */<br /> void doubleClick();<br />}; <br /><br />}; }; }; };</font></font>
+
<source lang="idl">
 +
module com { module sun { module star { module util {
  
OOo 2.0 supports two kind of specific statusbar item controllers. UNO based specific statusbar item controllers must be registered in the configuration set org.openoffice.Office.UI.Controller/Registered/Statusbar.
+
published interface XUpdatable: com::sun::star::uno::XInterface
 +
{
 +
//-------------------------------------------------------------------------
 +
/** refreshes the data of the object from the connected data source. */
 +
void update();
 +
};
  
An abstract from the Controller.xcu with registered specific statusbar item controllers:
+
//=============================================================================
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> ...</font></font>
+
}; }; }; };
 +
</source>
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">&lt;node oor:name="StatusBar"&gt;<br /> &lt;node oor:name="c1" oor:op="replace"&gt;<br /> &lt;prop oor:name="Command"&gt;<br /> &lt;value&gt;.uno:DBStatusType&lt;/value&gt;<br /> &lt;/prop&gt;<br /> &lt;prop oor:name="Module"&gt;<br /> &lt;value&gt;com.sun.star.sdb.OfficeDatabaseDocument&lt;/value&gt;<br /> &lt;/prop&gt;<br /> &lt;prop oor:name="Controller"&gt;<br /> &lt;value&gt;com.sun.star.sdb.ApplicationStatusbarController&lt;/value&gt;<br /> &lt;/prop&gt;<br /> &lt;/node&gt;<br /> &lt;node oor:name="c2" oor:op="replace"&gt;<br /> &lt;prop oor:name="Command"&gt;<br /> &lt;value&gt;.uno:DBStatusDBName&lt;/value&gt;<br /> &lt;/prop&gt;<br /> &lt;prop oor:name="Module"&gt;<br /> &lt;value&gt;com.sun.star.sdb.OfficeDatabaseDocument&lt;/value&gt;<br /> &lt;/prop&gt;<br /> &lt;prop oor:name="Controller"&gt;<br /> &lt;value&gt;com.sun.star.sdb.ApplicationStatusbarController&lt;/value&gt;<br /> &lt;/prop&gt;<br /> &lt;/node&gt;</font></font>
+
<source lang="idl">
 +
module com { module sun { module star { module frame {
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> ...<br /> &lt;node oor:name="c5" oor:op="replace"&gt;<br /> &lt;prop oor:name="Command"&gt;<br /> &lt;value&gt;.uno:StatusbarLogo&lt;/value&gt;</font></font>
+
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.
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">&lt;/prop&gt;<br /> &lt;prop oor:name="Module"&gt;</font></font>
+
@param aMouseEvent
 +
current information about the mouse pointer.
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">&lt;value/&gt;<br /> &lt;/prop&gt;<br /> &lt;prop oor:name="Controller"&gt;<br /> &lt;value&gt;com.sun.star.comp.framework.LogoImageStatusbarController&lt;/value&gt;<br /> &lt;/prop&gt;<br /> &lt;/node&gt;</font></font>
+
@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 );
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"> ...<br /> &lt;/node&gt;</font></font>
+
//=============================================================================
 +
/** 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.
  
<br /><br />
+
@param aMouseEvent
 +
current information about the mouse pointer.
  
The framework library provides a base class in svtools/inc/statusbarcontroller.hxx which makes it simpler to implement a UNO based specific status bar controller.
+
@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 );
  
The sfx2 based specific statusbar item controllers are registered by calling ''StatusbarControllerClass''<nowiki>::RegisterControl(SlotID, SfxModule* ). The framework implementation uses a special statusbar controller factory to create instances of sfx2 based specific statusbar item controllers. Sfx2 based specific statusbar controllers can use the known base class sfx2/inc/stbitem.hxx. It's a special wrapper which converts calls to the its UNO interfaces to the needs of sfx2 based statusbar controllers.</nowiki>
+
//=============================================================================
 +
/** 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.
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">class SFX2_DLLPUBLIC SfxStatusBarControl: public svt::StatusbarController<br />{<br /> USHORT nSlotId;<br /> USHORT nId;<br /> StatusBar* pBar;<br /><br />protected:<br /> // new controller API<br /> // XInterface<br /> virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type &amp; rType ) throw(::com::sun::star::uno::RuntimeException);<br /> virtual void SAL_CALL acquire() throw();<br /> virtual void SAL_CALL release() throw();<br /><br /> // XEventListener<br /> virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject&amp; aEvent ) throw( ::com::sun::star::uno::RuntimeException );<br /><br /> // XComponent<br /> virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException);<br /><br /> // XStatusListener<br /> virtual void SAL_CALL statusChanged( const ::com::sun::star::frame::FeatureStateEvent&amp; Event ) throw ( ::com::sun::star::uno::RuntimeException );<br /><br /> // XStatusbarController<br /> virtual ::sal_Bool SAL_CALL mouseButtonDown( const ::com::sun::star::awt::MouseEvent&amp; aMouseEvent ) throw (::com::sun::star::uno::RuntimeException);<br /> virtual ::sal_Bool SAL_CALL mouseMove( const ::com::sun::star::awt::MouseEvent&amp; aMouseEvent ) throw (::com::sun::star::uno::RuntimeException);<br /> virtual ::sal_Bool SAL_CALL mouseButtonUp( const ::com::sun::star::awt::MouseEvent&amp; aMouseEvent ) throw (::com::sun::star::uno::RuntimeException);<br /> virtual void SAL_CALL command( const ::com::sun::star::awt::Point&amp; aPos, <br /> ::sal_Int32 nCommand, <br /> ::sal_Bool bMouseEvent, <br /> const ::com::sun::star::uno::Any&amp; aData ) </font></font>
+
@param aMouseEvent
 +
current information about the mouse pointer.
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">throw (::com::sun::star::uno::RuntimeException);<br /> virtual void SAL_CALL paint( const ::com::sun::star::uno::Reference&lt; ::com::sun::star::awt::XGraphics &gt;&amp; xGraphics, <br /> const ::com::sun::star::awt::Rectangle&amp; rOutputRectangle, <br /> ::sal_Int32 nItemId, </font></font>
+
@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 );
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2"><nowiki>::sal_Int32 nStyle )</nowiki></font></font>
+
//=============================================================================
 +
/** is called by a status bar if a command event is available for a controller.
  
<font face="Courier New, monospace"><font style="font-size: 9pt" size="2">throw (::com::sun::star::uno::RuntimeException);<br /> virtual void SAL_CALL click() throw (::com::sun::star::uno::RuntimeException);<br /> virtual void SAL_CALL doubleClick() throw (::com::sun::star::uno::RuntimeException);<br /><br /> // Old sfx2 interface<br /> virtual void StateChanged( USHORT nSID, SfxItemState eState,<br /> const SfxPoolItem* pState );<br /> virtual void Click();<br /> virtual void DoubleClick();<br /> virtual void Command( const CommandEvent&amp; rCEvt );<br /> virtual BOOL MouseButtonDown( const MouseEvent &amp; );<br /> virtual BOOL MouseMove( const MouseEvent &amp; );<br /> virtual BOOL MouseButtonUp( const MouseEvent &amp; );<br /> virtual void Paint( const UserDrawEvent &amp;rUDEvt );<br /><br /> static USHORT convertAwtToVCLMouseButtons( sal_Int16 nAwtMouseButtons ); <br /><br />public:<br /> SfxStatusBarControl( USHORT nSlotID, USHORT nId, StatusBar&amp; rBar );<br /> virtual ~SfxStatusBarControl();<br /><br /> USHORT GetSlotId() const { return nSlotId; }<br /> USHORT GetId() const { return nId; }<br /> StatusBar&amp; GetStatusBar() const { return *pBar; }<br /> void CaptureMouse();<br /> void ReleaseMouse();<br /><br /> static SfxStatusBarControl* CreateControl( USHORT nSlotID, USHORT nId, StatusBar *pBar, SfxModule* );<br />};</font></font>
+
@param aPos
 +
the current mouse position in pixel.
  
<br /><br />
+
@param nCommand
 +
describes which command has been invoked.
  
<br /><br />
+
@param bMouseEvent
 +
<TRUE/> if the command is based on a mouse event, otherwise <FALSE/>.
  
=User interface controllers in the mixed sfx2/uno environment=
+
@param aData
 +
for future use only.
 +
*/
 +
void command( [in] ::com::sun::star::awt::Point aPos,
 +
[in] long nCommand,
 +
[in] boolean bMouseEvent,
 +
[in] any aData );
  
==How user interface controllers work in a pure UNO based environment?==
+
//=============================================================================
 +
/** is called by a status bar if a command event is available for a controller.
  
[[Image:EnvironmentPureUnoUserInterfaceController.png]]
+
@param xGraphics
 +
the current graphics which should be used for painting.
  
==How user interface controllers work in our mixed sfx2/UNO based environment?==
+
@param rOutputRectangle
 +
the output rectangle for graphic operations.
  
[[Image:EnvironmentUserInterfaceController.png]]
+
@param nItemId
 +
the item id of the controller.
  
 +
@param nStyle
 +
the style of the statusbar item. The controller should respect the provided
  
Let's see what happens in more detail, especially when we switch from one layer to another one.
+
style when paints.
 +
*/
 +
void paint( [in] ::com::sun::star::awt::XGraphics xGraphics,
 +
[in] ::com::sun::star::awt::Rectangle rOutputRectangle,
 +
[in] long nItemId,
 +
[in] long nStyle );
  
# A shell wants to invalidate a slot and calls SfxShell::Invalidate( SlotID ).
+
//=============================================================================
# The bindings updates the SfxStateCache for the provided slot ID normally through a update timer or directly.
+
/** is called by a status bar if the user clicked with mouse into the  
# The SfxStateCache calls StateChanged with the new state on a SfxDispatchController_Impl object.
+
field of the corresponding control.
# The SfxDispatchController_Impl now maps the sfx2 state information based on SfxPoolItem to UNO information and sends them to UNO based toolbar controller.
+
*/
 +
void click();
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">...</font></font>
+
//=============================================================================
 +
/** is called by a status bar if the user double-clicked with mouse
 +
into the field of the corresponding control.
 +
*/
 +
void doubleClick();
 +
};
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><nowiki>::cppu::OInterfaceContainerHelper* pContnr = pDispatch-&gt;GetListeners().getContainer( aDispatchURL.Complete );</nowiki></font></font>
+
}; }; }; };
 +
</source>
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">if</font><font color="#000000"> ( bNotify &amp;&amp; pContnr )</font></font></font>
+
OOo 2.0 supports two kind of specific statusbar item controllers. UNO based specific statusbar item controllers must be registered in the configuration set org.openoffice.Office.UI.Controller/Registered/Statusbar.
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">{</font></font>
+
An abstract from the Controller.xcu with registered specific statusbar item controllers:
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><nowiki>::com::sun::star::uno::Any aState;</nowiki></font></font>
+
<source lang="xml">
 +
...
  
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">if</font><font color="#000000"> ( ( eState &gt;= SFX_ITEM_AVAILABLE ) &amp;&amp; pState &amp;&amp; !IsInvalidItem( pState ) &amp;&amp; !pState-&gt;ISA(SfxVoidItem) )</font></font></font>
+
<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>
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">{</font></font>
+
...
 +
<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>
  
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#008000">// Retrieve metric from pool to have correct sub ID when calling QueryValue</font></font></font>
+
...
 +
</node>
 +
</source>
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">USHORT nSubId( 0 );</font></font>
+
The framework library provides a base class in svtools/inc/statusbarcontroller.hxx which makes it simpler to implement a UNO based specific status bar controller.
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">SfxMapUnit eMapUnit( SFX_MAPUNIT_100TH_MM );</font></font>
+
The sfx2 based specific statusbar item controllers are registered by calling ''StatusbarControllerClass''<nowiki>::RegisterControl(SlotID, SfxModule* ). The framework implementation uses a special statusbar controller factory to create instances of sfx2 based specific statusbar item controllers. Sfx2 based specific statusbar controllers can use the known base class sfx2/inc/stbitem.hxx. It's a special wrapper which converts calls to the its UNO interfaces to the needs of sfx2 based statusbar controllers.</nowiki>
  
<br />
+
<source lang="cpp">
 +
class SFX2_DLLPUBLIC SfxStatusBarControl: public svt::StatusbarController
 +
{
 +
USHORT nSlotId;
 +
USHORT nId;
 +
StatusBar* pBar;
  
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#008000">// retrieve the core metric</font></font></font>
+
protected:
 +
// new controller API
 +
// XInterface
 +
virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
 +
virtual void SAL_CALL acquire() throw();
 +
virtual void SAL_CALL release() throw();
  
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#008000">// it's enough to check the objectshell, the only shell that does not </font></font></font>
+
// XEventListener
 +
virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& aEvent ) throw( ::com::sun::star::uno::RuntimeException );
  
<font color="#008000"> <font face="Courier New, monospace"><font style="font-size: 8pt" size="1">// use the pool of the document is SfxViewFrame, but it hasn't any metric parameters</font></font></font>
+
// XComponent
 +
virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException);
  
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">if</font><font color="#000000"> ( pSlotServ &amp;&amp; pDispatcher )</font></font></font>
+
// XStatusListener
 +
virtual void SAL_CALL statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw ( ::com::sun::star::uno::RuntimeException );
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">{</font></font>
+
// XStatusbarController
 +
virtual ::sal_Bool SAL_CALL mouseButtonDown( const ::com::sun::star::awt::MouseEvent& aMouseEvent ) throw (::com::sun::star::uno::RuntimeException);
 +
virtual ::sal_Bool SAL_CALL mouseMove( const ::com::sun::star::awt::MouseEvent& aMouseEvent ) throw (::com::sun::star::uno::RuntimeException);
 +
virtual ::sal_Bool SAL_CALL mouseButtonUp( const ::com::sun::star::awt::MouseEvent& aMouseEvent ) throw (::com::sun::star::uno::RuntimeException);
 +
virtual void SAL_CALL command( const ::com::sun::star::awt::Point& aPos,
 +
::sal_Int32 nCommand,
 +
::sal_Bool bMouseEvent,
 +
const ::com::sun::star::uno::Any& aData )
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">SfxShell* pShell = pDispatcher-&gt;GetShell( pSlotServ-&gt;GetShellLevel() );</font></font>
+
throw (::com::sun::star::uno::RuntimeException);
 +
virtual void SAL_CALL paint( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics >& xGraphics,
 +
const ::com::sun::star::awt::Rectangle& rOutputRectangle,
 +
::sal_Int32 nItemId,
 +
::sal_Int32 nStyle )
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">DBG_ASSERT( pShell, "Can't get core metric without shell!" );</font></font>
+
throw (::com::sun::star::uno::RuntimeException);
 +
virtual void SAL_CALL click() throw (::com::sun::star::uno::RuntimeException);
 +
virtual void SAL_CALL doubleClick() throw (::com::sun::star::uno::RuntimeException);
  
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">if</font><font color="#000000"> ( pShell )</font></font></font>
+
// Old sfx2 interface
 +
virtual void StateChanged( USHORT nSID, SfxItemState eState,
 +
const SfxPoolItem* pState );
 +
virtual void Click();
 +
virtual void DoubleClick();
 +
virtual void Command( const CommandEvent& rCEvt );
 +
virtual BOOL MouseButtonDown( const MouseEvent & );
 +
virtual BOOL MouseMove( const MouseEvent & );
 +
virtual BOOL MouseButtonUp( const MouseEvent & );
 +
virtual void Paint( const UserDrawEvent &rUDEvt );
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">eMapUnit = GetCoreMetric( pShell-&gt;GetPool(), nSID );</font></font>
+
static USHORT convertAwtToVCLMouseButtons( sal_Int16 nAwtMouseButtons );  
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">}</font></font>
+
public:
 +
SfxStatusBarControl( USHORT nSlotID, USHORT nId, StatusBar& rBar );
 +
virtual ~SfxStatusBarControl();
  
<br />
+
USHORT GetSlotId() const { return nSlotId; }
 +
USHORT GetId() const { return nId; }
 +
StatusBar& GetStatusBar() const { return *pBar; }
 +
void CaptureMouse();
 +
void ReleaseMouse();
  
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">if</font><font color="#000000"> ( eMapUnit == SFX_MAPUNIT_TWIP )</font></font></font>
+
static SfxStatusBarControl* CreateControl( USHORT nSlotID, USHORT nId, StatusBar *pBar, SfxModule* );
 +
};
 +
</source>
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">nSubId |= CONVERT_TWIPS;</font></font>
+
=User interface controllers in the mixed sfx2/uno environment=
  
<br />
+
==How user interface controllers work in a pure UNO based environment?==
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">'''pState-&gt;QueryValue( aState, (BYTE)nSubId );'''</font></font>
+
[[Image:EnvironmentPureUnoUserInterfaceController.png]]
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">}</font></font>
+
==How user interface controllers work in our mixed sfx2/UNO based environment?==
  
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">else</font><font color="#000000"> </font><font color="#0000ff">if</font><font color="#000000"> ( eState == SFX_ITEM_DONTCARE )</font></font></font>
+
[[Image:EnvironmentUserInterfaceController.png]]
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">{</font></font>
 
  
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#008000">// Use special uno struct to transport don't care state</font></font></font>
+
Let's see what happens in more detail, especially when we switch from one layer to another one.
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><nowiki>::com::sun::star::frame::status::ItemStatus aItemStatus;</nowiki></font></font>
+
# A shell wants to invalidate a slot and calls SfxShell::Invalidate( SlotID ).
 +
# The bindings updates the SfxStateCache for the provided slot ID normally through a update timer or directly.
 +
# The SfxStateCache calls StateChanged with the new state on a SfxDispatchController_Impl object.
 +
# The SfxDispatchController_Impl now maps the sfx2 state information based on SfxPoolItem to UNO information and sends them to UNO based toolbar controller.
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">aItemStatus.State = ::com::sun::star::frame::status::ItemState::dont_care;</font></font>
+
<source lang="cpp">
 +
...
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">aState = makeAny( aItemStatus );</font></font>
+
::cppu::OInterfaceContainerHelper* pContnr = pDispatch->GetListeners().getContainer( aDispatchURL.Complete );
 +
if ( bNotify && pContnr )
 +
{
 +
  ::com::sun::star::uno::Any aState;
 +
  if ( ( eState >= SFX_ITEM_AVAILABLE ) && pState && !IsInvalidItem( pState ) && !pState->ISA(SfxVoidItem) )
 +
  {
 +
    // Retrieve metric from pool to have correct sub ID when calling QueryValue
 +
    USHORT nSubId( 0 );
 +
    SfxMapUnit eMapUnit( SFX_MAPUNIT_100TH_MM );
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">}</font></font>
+
    // retrieve the core metric
 +
    // it's enough to check the objectshell, the only shell that does not
 +
    // use the pool of the document is SfxViewFrame, but it hasn't any metric parameters
 +
    if ( pSlotServ && pDispatcher )
 +
    {
 +
      SfxShell* pShell = pDispatcher->GetShell( pSlotServ->GetShellLevel() );
 +
      DBG_ASSERT( pShell, "Can't get core metric without shell!" );
 +
      if ( pShell )
 +
        eMapUnit = GetCoreMetric( pShell->GetPool(), nSID );
 +
    }
  
<br />
+
    if ( eMapUnit == SFX_MAPUNIT_TWIP )
 +
      nSubId |= CONVERT_TWIPS;
 +
    pState->QueryValue( aState, (BYTE)nSubId );
 +
  }
 +
  else if ( eState == SFX_ITEM_DONTCARE )
 +
  {
 +
    // Use special uno struct to transport don't care state
 +
    ::com::sun::star::frame::status::ItemStatus aItemStatus;
 +
    aItemStatus.State = ::com::sun::star::frame::status::ItemState::dont_care;
 +
    aState = makeAny( aItemStatus );
 +
  }
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><nowiki>::com::sun::star::frame::FeatureStateEvent aEvent;</nowiki></font></font>
+
  ::com::sun::star::frame::FeatureStateEvent aEvent;
 +
  aEvent.FeatureURL = aDispatchURL;
 +
  aEvent.Source = (::com::sun::star::frame::XDispatch*) pDispatch;
 +
  aEvent.IsEnabled = eState != SFX_ITEM_DISABLED;
 +
  aEvent.Requery = sal_False;
 +
  aEvent.State = aState;
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">aEvent.FeatureURL = aDispatchURL;</font></font>
+
  ::cppu::OInterfaceIteratorHelper aIt( *pContnr );
 +
  while( aIt.hasMoreElements() )
 +
  {
 +
    try
 +
    {
 +
      ((::com::sun::star::frame::XStatusListener *)aIt.next())->statusChanged( aEvent );
 +
    }
 +
    catch( ::com::sun::star::uno::RuntimeException& )
 +
    {
 +
      aIt.remove();
 +
    }
 +
  }
 +
}
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">aEvent.Source = (::com::sun::star::frame::XDispatch*) pDispatch;</font></font>
+
...
 
+
</source>
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">aEvent.IsEnabled = eState != SFX_ITEM_DISABLED;</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">aEvent.Requery = sal_False;</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">aEvent.State = aState;</font></font>
+
 
+
<br />
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><nowiki>::cppu::OInterfaceIteratorHelper aIt( *pContnr );</nowiki></font></font>
+
 
+
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">while</font><font color="#000000">( aIt.hasMoreElements() )</font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">{</font></font>
+
 
+
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">try</font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">{</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">'''((::com::sun::star::frame::XStatusListener *)aIt.next())-&gt;statusChanged( aEvent );'''</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">}</font></font>
+
 
+
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">catch</font><font color="#000000">( ::com::sun::star::uno::RuntimeException&amp; )</font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">{</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">aIt.remove();</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">}</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">}</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">}</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">...</font></font>
+
 
+
<br />
+
 
+
<br />
+
  
 
How does QueryValue work and convert an item to UNO com::sun::star::uno::any?
 
How does QueryValue work and convert an item to UNO com::sun::star::uno::any?
Line 894: Line 1,371:
 
You can find the base class of any pool item in ''svtools/inc/poolitem.hxx''
 
You can find the base class of any pool item in ''svtools/inc/poolitem.hxx''
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">class</font><font color="#000000"> SVL_DLLPUBLIC SfxPoolItem</font></font></font>
+
<source lang="cpp">
 +
class SVL_DLLPUBLIC SfxPoolItem
 +
{
 +
friend class SfxItemPool;
 +
friend class SfxItemDesruptor_Impl;
 +
friend class SfxItemPoolCache;
 +
friend class SfxItemSet;
 +
friend class SfxVoidItem;
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">{</font></font>
+
ULONG nRefCount; // Referenzzaehler
 +
USHORT nWhich;
 +
USHORT nKind;
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">friend</font><font color="#000000"> </font><font color="#0000ff">class</font><font color="#000000"> SfxItemPool;</font></font></font>
+
private:
 +
inline void SetRefCount( ULONG n );
 +
inline void SetKind( USHORT n );
 +
public:
 +
inline ULONG AddRef( ULONG n = 1 ) const;
 +
private:
 +
inline ULONG ReleaseRef( ULONG n = 1 ) const;
 +
SVL_DLLPRIVATE long Delete_Impl(void*);
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">friend</font><font color="#000000"> </font><font color="#0000ff">class</font><font color="#000000"> SfxItemDesruptor_Impl;</font></font></font>
+
protected:
 +
SfxPoolItem( USHORT nWhich = 0 );
 +
SfxPoolItem( const SfxPoolItem& );
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">friend</font><font color="#000000"> </font><font color="#0000ff">class</font><font color="#000000"> SfxItemPoolCache;</font></font></font>
+
public:
 +
TYPEINFO();
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">friend</font><font color="#000000"> </font><font color="#0000ff">class</font><font color="#000000"> SfxItemSet;</font></font></font>
+
virtual ~SfxPoolItem();
 +
void SetWhich( USHORT nId )
 +
{ DBG_CHKTHIS(SfxPoolItem, 0); nWhich = nId; }
 +
USHORT Which() const { DBG_CHKTHIS(SfxPoolItem, 0); return nWhich; }
 +
virtual int operator==( const SfxPoolItem& ) const = 0;
 +
int operator!=( const SfxPoolItem& rItem ) const
 +
{ return !(*this == rItem); }
 +
virtual int Compare( const SfxPoolItem &rWith ) const;
 +
virtual int Compare( const SfxPoolItem &rWith, const IntlWrapper& rIntlWrapper ) const;
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">friend</font><font color="#000000"> </font><font color="#0000ff">class</font><font color="#000000"> SfxVoidItem;</font></font></font>
+
virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePresentation,
 +
SfxMapUnit eCoreMetric,
 +
SfxMapUnit ePresentationMetric,
 +
XubString &rText,
 +
const IntlWrapper * pIntlWrapper = 0 ) const;
  
<br />
+
virtual USHORT GetVersion( USHORT nFileFormatVersion ) const;
 +
virtual int ScaleMetrics( long lMult, long lDiv );
 +
virtual int HasMetrics() const;
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> ULONG nRefCount; </font><font color="#008000">// Referenzzaehler</font></font></font>
+
virtual BOOL QueryValue( com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 ) const;
 +
virtual BOOL PutValue( const com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 );
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"> USHORT nWhich;</font></font>
+
virtual SfxPoolItem* Create( SvStream &, USHORT nItemVersion ) const;
 +
virtual SvStream& Store( SvStream &, USHORT nItemVersion ) const;
 +
virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const = 0;
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"> USHORT nKind;</font></font>
+
ULONG GetRefCount() const { return nRefCount; }
 +
inline USHORT GetKind() const { return nKind; }
  
<br />
+
static bool readByteString(SvStream & rStream, UniString & rString);
 +
static void writeByteString(SvStream & rStream,UniString const & rString);
 +
static bool readUnicodeString(SvStream & rStream, UniString & rString, bool bUnicode);
 +
static void writeUnicodeString(SvStream & rStream, UniString const & rString);
  
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">private</font><font color="#000000"><nowiki>:</nowiki></font></font></font>
+
private:
 
+
SfxPoolItem& operator=( const SfxPoolItem& ); // n.i.!!
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">inline</font><font color="#000000"> </font><font color="#0000ff">void </font><font color="#000000">SetRefCount( ULONG n );</font></font></font>
+
};
 
+
</source>
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">inline</font><font color="#000000"> </font><font color="#0000ff">void</font><font color="#000000"> SetKind( USHORT n );</font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">public</font><font color="#000000"><nowiki>:</nowiki></font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">inline</font><font color="#000000"> ULONG AddRef( ULONG n = 1 ) </font><font color="#0000ff">const</font><font color="#000000"><nowiki>;</nowiki></font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">private</font><font color="#000000"><nowiki>:</nowiki></font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">inline</font><font color="#000000"> ULONG ReleaseRef( ULONG n = 1 ) </font><font color="#0000ff">const</font><font color="#000000"><nowiki>;</nowiki></font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> SVL_DLLPRIVATE </font><font color="#0000ff">long </font><font color="#000000">Delete_Impl(</font><font color="#0000ff">void</font><font color="#000000"><nowiki>*);</nowiki></font></font></font>
+
 
+
<br />
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">protected</font><font color="#000000"><nowiki>:</nowiki></font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"> SfxPoolItem( USHORT nWhich = 0 );</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> SfxPoolItem( </font><font color="#0000ff">const</font><font color="#000000"> SfxPoolItem&amp; );</font></font></font>
+
 
+
<br />
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">public</font><font color="#000000"><nowiki>:</nowiki></font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">''' TYPEINFO();'''</font></font>
+
 
+
<font color="#000000"><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"> </font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">virtual</font><font color="#000000"> ~SfxPoolItem();</font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">void</font><font color="#000000"> SetWhich( USHORT nId ) </font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> { </font>DBG_CHKTHIS(SfxPoolItem, 0); nWhich = nId; }</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> USHORT Which() </font><font color="#0000ff">const</font><font color="#000000"> { </font>DBG_CHKTHIS(SfxPoolItem, 0);<font color="#000000"> </font><font color="#0000ff">return</font><font color="#000000"> nWhich; }</font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">virtual</font><font color="#000000"> </font><font color="#0000ff">int</font><font color="#000000"> </font><font color="#0000ff">operator</font><font color="#000000"><nowiki>==( </nowiki></font><font color="#0000ff">const</font><font color="#000000"> SfxPoolItem&amp; ) </font><font color="#0000ff">const</font><font color="#000000"> = 0;</font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">int</font><font color="#000000"> </font><font color="#0000ff">operator</font><font color="#000000"><nowiki>!=( </nowiki></font><font color="#0000ff">const</font><font color="#000000"> SfxPoolItem&amp; rItem ) </font><font color="#0000ff">const</font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> { </font><font color="#0000ff">return</font><font color="#000000"> !(*</font><font color="#0000ff">this</font><font color="#000000"> == rItem); }</font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">virtual</font><font color="#000000"> </font><font color="#0000ff">int </font><font color="#000000">Compare( </font><font color="#0000ff">const</font><font color="#000000"> SfxPoolItem &amp;rWith ) </font><font color="#0000ff">const</font><font color="#000000"><nowiki>;</nowiki></font></font></font>
+
 
+
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">virtual</font><font color="#000000"> </font><font color="#0000ff">int </font><font color="#000000">Compare( </font><font color="#0000ff">const</font><font color="#000000"> SfxPoolItem &amp;rWith, </font><font color="#0000ff">const</font><font color="#000000"> IntlWrapper&amp; rIntlWrapper ) </font><font color="#0000ff">const</font><font color="#000000"><nowiki>;</nowiki></font></font></font>
+
 
+
<br />
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">virtual</font><font color="#000000"> SfxItemPresentation GetPresentation( SfxItemPresentation ePresentation,</font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"> SfxMapUnit eCoreMetric,</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"> SfxMapUnit ePresentationMetric,</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"> XubString &amp;rText,</font></font>
+
 
+
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">const</font><font color="#000000"> IntlWrapper * pIntlWrapper = 0 ) </font><font color="#0000ff">const</font><font color="#000000"><nowiki>;</nowiki></font></font></font>
+
 
+
<br />
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">virtual</font><font color="#000000"> USHORT GetVersion( USHORT nFileFormatVersion ) </font><font color="#0000ff">const</font><font color="#000000"><nowiki>;</nowiki></font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">virtual</font><font color="#000000"> </font><font color="#0000ff">int </font><font color="#000000">ScaleMetrics( </font><font color="#0000ff">long</font><font color="#000000"> lMult, </font><font color="#0000ff">long</font><font color="#000000"> lDiv );</font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">virtual</font><font color="#000000"> </font><font color="#0000ff">int </font><font color="#000000">HasMetrics() </font><font color="#0000ff">const</font><font color="#000000"><nowiki>;</nowiki></font></font></font>
+
 
+
<br />
+
 
+
<br />
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font>'''<font color="#0000ff">virtual</font><font color="#000000"> BOOL QueryValue( com::sun::star::uno::Any&amp; rVal, BYTE nMemberId = 0 ) </font><font color="#0000ff">const</font><font color="#000000"><nowiki>;</nowiki></font>'''</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">'''<font color="#000000"> </font><font color="#0000ff">virtual</font><font color="#000000"> BOOL PutValue( </font><font color="#0000ff">const</font><font color="#000000"> com::sun::star::uno::Any&amp; rVal, BYTE nMemberId = 0 );</font>'''</font></font>
+
 
+
<br />
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">virtual</font><font color="#000000"> SfxPoolItem* Create( SvStream &amp;, USHORT nItemVersion ) </font><font color="#0000ff">const</font><font color="#000000"><nowiki>;</nowiki></font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">virtual</font><font color="#000000"> SvStream&amp; Store( SvStream &amp;, USHORT nItemVersion ) </font><font color="#0000ff">const</font><font color="#000000"><nowiki>;</nowiki></font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">virtual</font><font color="#000000"> SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) </font><font color="#0000ff">const</font><font color="#000000"> = 0;</font></font></font>
+
 
+
<br />
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> ULONG GetRefCount() </font><font color="#0000ff">const</font><font color="#000000"> { </font><font color="#0000ff">return</font><font color="#000000"> nRefCount; }</font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">inline</font><font color="#000000"> USHORT GetKind() </font><font color="#0000ff">const</font><font color="#000000"> { </font><font color="#0000ff">return</font><font color="#000000"> nKind; }</font></font></font>
+
 
+
<br />
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">static</font><font color="#000000"> </font><font color="#0000ff">bool</font><font color="#000000"> readByteString(SvStream &amp; rStream, UniString &amp; rString);</font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">static</font><font color="#000000"> </font><font color="#0000ff">void</font><font color="#000000"> writeByteString(SvStream &amp; rStream,UniString </font><font color="#0000ff">const</font><font color="#000000"> &amp; rString);</font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">static</font><font color="#000000"> </font><font color="#0000ff">bool</font><font color="#000000"> readUnicodeString(SvStream &amp; rStream, UniString &amp; rString,</font> <font color="#0000ff">bool</font><font color="#000000"> bUnicode);</font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> </font><font color="#0000ff">static</font><font color="#000000"> </font><font color="#0000ff">void</font><font color="#000000"> writeUnicodeString(SvStream &amp; rStream, UniString </font><font color="#0000ff">const</font><font color="#000000"> &amp; rString);</font></font></font>
+
 
+
<br />
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">private</font><font color="#000000"><nowiki>:</nowiki></font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#000000"> SfxPoolItem&amp; </font><font color="#0000ff">operator</font><font color="#000000"><nowiki>=( </nowiki></font><font color="#0000ff">const</font><font color="#000000"> SfxPoolItem&amp; ); </font><font color="#008000">// n.i.!!</font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">};</font></font>
+
 
+
<br />
+
  
 
A example how to implement QueryValue can be found in the implementation of the SvxULSpaceItem (located in svx/source/items/frmitems.cxx).
 
A example how to implement QueryValue can be found in the implementation of the SvxULSpaceItem (located in svx/source/items/frmitems.cxx).
  
<br />
+
<source lang="cpp">
 
+
sal_Bool SvxULSpaceItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">sal_Bool SvxULSpaceItem::QueryValue( uno::Any&amp; rVal, BYTE nMemberId ) <font color="#0000ff">const</font></font></font>
+
{
 
+
  sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">{</font></font>
+
  nMemberId &= ~CONVERT_TWIPS;
 
+
  switch( nMemberId )
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">sal_Bool bConvert = 0!=(nMemberId&amp;CONVERT_TWIPS);</font></font>
+
  {
 
+
    // jetzt alles signed
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">nMemberId &amp;= ~CONVERT_TWIPS;</font></font>
+
    case 0:
 
+
    {
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">switch</font><font color="#000000">( nMemberId )</font></font></font>
+
      ::com::sun::star::frame::status::UpperLowerMarginScale aUpperLowerMarginScale;
 
+
      aUpperLowerMarginScale.Upper = (sal_Int32)(bConvert ? TWIP_TO_MM100(nUpper) : nUpper);
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">{</font></font>
+
      aUpperLowerMarginScale.Lower = (sal_Int32)(bConvert ? TWIP_TO_MM100(nLower) : nPropUpper);
 
+
      aUpperLowerMarginScale.ScaleUpper = (sal_Int16)nPropUpper;
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#008000">// jetzt alles signed</font></font></font>
+
      aUpperLowerMarginScale.ScaleLower = (sal_Int16)nPropLower;
 
+
      rVal <<= aUpperLowerMarginScale;
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">case</font><font color="#000000"> 0:</font></font></font>
+
      break;
 
+
    }
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">{</font></font>
+
    case MID_UP_MARGIN: rVal <<= (sal_Int32)(bConvert ? TWIP_TO_MM100(nUpper) : nUpper); break;
 
+
    case MID_LO_MARGIN: rVal <<= (sal_Int32)(bConvert ? TWIP_TO_MM100(nLower) : nLower); break;
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><nowiki>::com::sun::star::frame::status::UpperLowerMarginScale aUpperLowerMarginScale;</nowiki></font></font>
+
    case MID_UP_REL_MARGIN: rVal <<= (sal_Int16) nPropUpper; break;
 
+
    case MID_LO_REL_MARGIN: rVal <<= (sal_Int16) nPropLower; break;
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">aUpperLowerMarginScale.Upper = (sal_Int32)(bConvert ? TWIP_TO_MM100(nUpper) : nUpper);</font></font>
+
  }
 
+
  return sal_True;
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">aUpperLowerMarginScale.Lower = (sal_Int32)(bConvert ? TWIP_TO_MM100(nLower) : nPropUpper);</font></font>
+
}
 
+
</source>
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">aUpperLowerMarginScale.ScaleUpper = (sal_Int16)nPropUpper;</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">aUpperLowerMarginScale.ScaleLower = (sal_Int16)nPropLower;</font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">rVal &lt;&lt;= aUpperLowerMarginScale;</font></font>
+
 
+
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">break</font><font color="#000000"><nowiki>;</nowiki></font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">}</font></font>
+
 
+
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">case</font><font color="#000000"> MID_UP_MARGIN: rVal &lt;&lt;= (sal_Int32)(bConvert ? TWIP_TO_MM100(nUpper) : nUpper); </font><font color="#0000ff">break</font><font color="#000000"><nowiki>;</nowiki></font></font></font>
+
 
+
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">case</font><font color="#000000"> MID_LO_MARGIN: rVal &lt;&lt;= (sal_Int32)(bConvert ? TWIP_TO_MM100(nLower) : nLower); </font><font color="#0000ff">break</font><font color="#000000"><nowiki>;</nowiki></font></font></font>
+
 
+
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">case</font><font color="#000000"> MID_UP_REL_MARGIN: rVal &lt;&lt;= (sal_Int16) nPropUpper; </font><font color="#0000ff">break</font><font color="#000000"><nowiki>;</nowiki></font></font></font>
+
 
+
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">case</font><font color="#000000"> MID_LO_REL_MARGIN: rVal &lt;&lt;= (sal_Int16) nPropLower; </font><font color="#0000ff">break</font><font color="#000000"><nowiki>;</nowiki></font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">}</font></font>
+
 
+
<font color="#000000"> </font><font face="Courier New, monospace"><font style="font-size: 8pt" size="1"><font color="#0000ff">return</font><font color="#000000"> sal_True;</font></font></font>
+
 
+
<font face="Courier New, monospace"><font style="font-size: 8pt" size="1">}</font></font>
+
 
+
<br />
+
  
 
# The UNO based toolbar controller now has to convert the state information (com::sun::star::uno::Any) again to provide it in a format that the sfx2 based toolbar controller implementation knows (SfxPoolItem).
 
# The UNO based toolbar controller now has to convert the state information (com::sun::star::uno::Any) again to provide it in a format that the sfx2 based toolbar controller implementation knows (SfxPoolItem).
  
<code>[cpp]
+
<source lang="cpp">
 
// XStatusListener  
 
// XStatusListener  
  
Line 1,203: Line 1,588:
 
     }  
 
     }  
 
}  
 
}  
</code>
+
</source>
  
 
As you can see the implementation retrieves the type of the slot and creates an empty item of that type. Now it has to use PutValue to convert the UNO com::sun::star::uno::Any back to an item. Let's see how the SvxULSpaceItem implements PutValue:
 
As you can see the implementation retrieves the type of the slot and creates an empty item of that type. Now it has to use PutValue to convert the UNO com::sun::star::uno::Any back to an item. Let's see how the SvxULSpaceItem implements PutValue:
  
<code>[cpp]
+
<source lang="cpp">
 
sal_Bool SvxULSpaceItem::PutValue( const uno::Any& rVal, BYTE nMemberId )  
 
sal_Bool SvxULSpaceItem::PutValue( const uno::Any& rVal, BYTE nMemberId )  
 
{  
 
{  
Line 1,269: Line 1,654:
 
   return sal_True;  
 
   return sal_True;  
 
}  
 
}  
</code>
+
</source>
  
 
'''''We should now see some very important rules that this conversion can work correctly.'''''
 
'''''We should now see some very important rules that this conversion can work correctly.'''''
Line 1,279: Line 1,664:
 
* Never use other arguments to call a slot than the ones that are declared in your SDI file. The conversion methods in sfx2 use the type description of the slot to map UNO types to items and cannot do this for unknown arguments.
 
* Never use other arguments to call a slot than the ones that are declared in your SDI file. The conversion methods in sfx2 use the type description of the slot to map UNO types to items and cannot do this for unknown arguments.
  
[[Category:Development]]
 
 
[[Category:Framework:Article]]
 
[[Category:Framework:Article]]

Latest revision as of 07:11, 2 May 2012

OpenOffice.org 2.0 User Interface Controller Internals

A typical OOo 2.0 document contains different user interface elements. They have to provide their functions to the user and display the current state of the document view.

If you want to know about the different controller type then you should read the controller tutorials available in the articles&tutorials chapter.

How and in which infrastructure do they work?

OpenOffice2UserInterfaceElements.png

The user interface elements are using controllers for each of their elements to bind them to the dynamic state of the application module. It's the responsibility of every user interface controller to call and to display the current state of its bound function.

OOo 2.0 uses the following user interface controllers:

  • Menubar
    • Popup menu controller
    • Generic menu item controller
    • Internal menu controller
  • Toolbar
    • Generic toolbar item controller
    • Specific toolbar item controller
  • Statusbar
    • Specific statusbar item controller

Menubar

Generic menu item controller

A normal menu item is controlled by a generic menu item controller. A menu bar of an application module uses for about 90% of its menu items generic item controllers. For example the Edit - Undo, Redo and Edit - Cut, Copy and Paste menu items are implemented using generic menu item controllers.

A generic menu item controller supports the following interfaces:

module com { module sun { module star { module frame {
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 );
};
}; }; }; };
module com { module sun { module star { module frame {
published struct FeatureStateEvent: com::sun::star::lang::EventObject
{
  //-------------------------------------------------------------------------
  /** contains the URL of the feature. */
  com::sun::star::util::URL FeatureURL;
 
  //-------------------------------------------------------------------------
  /** contains a descriptor of the feature for the user interface.*/
  string FeatureDescriptor;
 
  //-------------------------------------------------------------------------
  /** specifies whether the feature is currently enabled or disabled. */
  boolean IsEnabled;
 
  //-------------------------------------------------------------------------
  /** specifies whether the <type>XDispatch</type> has to be requeried. */
  boolean Requery;
 
  //-------------------------------------------------------------------------
  /** contains the state of the feature in this dispatch.*/
  any State;
};
}; }; }; };

It supports the following generic functions by listing to status updates provided by function statusChanged.

Variable

UNO Type/Poolitem

Action

State

String / SfxStringItem

Menu item changes its label to the content of the provided string.

State

Boolean / SfxBoolItem

Menu item checks or unchecks its menu item, according to the boolean value.

State

com.sun.star.frame.status.VisibilityItem / SfxVisibilityItem

Menu item will be made visible or invisible, according to the provided state.

IsEnabled

Boolean

Menu item is enabled or disabled according to the value of IsEnabled.


Internal menu controller

An Internal menu controllers is used for special menu items, like the window list (accessible via the Window popup menu). Internal menu controllers are completely responsible for their menu items. Currently there is no special menu controller which is implemented outside the framework library. There exists no UNO API to implement internal menu controllers.

Popup menu controller

A popup menu controller is a special menu controller which is responsible for a whole popup menu inside a menu bar. A popup menu controller must be a UNO service and registered in the configuration controller set, which can be found at org.openoffice.Office.UI.Controller/Registered/PopupMenu. The configuration set associates UNO service names implementing a popup menu controller with a command URL. The command URL is used by our XML based menu bar description. A popup menu controller is created by a popup menu controller factory which uses the configuration set to retrieve the correct service name and to initialize it.
An abstract from the org.openoffice.Office.UI.Controller/Registered/PopupMenu:

<!DOCTYPE oor:component-data SYSTEM "../../../../../component-update.dtd">
<oor:component-data oor:name="Controller" oor:package="org.openoffice.Office.UI" xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <node oor:name="Registered">
  <node oor:name="PopupMenu">
   <node oor:name="c1" oor:op="replace">
    <prop oor:name="Command">
     <value>.uno:CharFontName</value>
    </prop>
    <prop oor:name="Module">
     <value/>
    </prop>
    <prop oor:name="Controller">
     <value>com.sun.star.comp.framework.FontMenuController</value>
    </prop>
   </node>
   ...

A popup menu controller must support the following services / interfaces:

module com { module sun { module star { module frame {
 
service PopupMenuController
{
//-------------------------------------------------------------------------
/** supports functions to initialize and update a popup menu controller
    implementation.
 
    A popup menu controller implementation gets initialized with a
    com::sun::star::awt::XPopupMenu object. This assures
    that a popup menu controller can be implemented with any UNO based
    language.
*/
interface com::sun::star::frame::XPopupMenuController;
 
//-------------------------------------------------------------------------
/** provides functions to initialize a popup menu controller with
    specific data which are needed.
 
    This interface should not directly used. A factory service is responsible to
    initialize every controller correctly.
    popup menu controller needs at least two additional arguments
    provided as com::sun::star::beans::PropertyValue.
 
    Frame
    specifies the com::sun::star::frame::XFrame instance to which the 
    popup menu controller belongs to.
 
    CommandURL
    specifies which popup menu controller should be created.
 
    @see PopupMenuControllerFactory
*/
interface com::sun::star::lang::XInitialization;
 
//-------------------------------------------------------------------------
/** used to brief the popup menu controller with new status information.
    A popup menu controller makes special functions available to users which 
    normally depend on the state of other data. This interface is used to 
    send this data to a controller implementation.
*/
interface com::sun::star::frame::XStatusListener;
};
}; }; }; };
module com { module sun { module star { module frame {
 
interface XPopupMenuController : com::sun::star::uno::XInterface
{
    /** provides a com::sun::star::awt::XPopupMenu to a popup menu 
        controller implementation. The controller must fill this popup 
        menu with its functions.
 
        @param PopupMenu
        An empty popup menu that must be filled by the popup menu controller.
    */
    void setPopupMenu( [in] com::sun::star::awt::XPopupMenu PopupMenu );
 
    /** briefs the popup menu controller to update the contents of 
        the provided popup menu to reflect the current state. A 
        controller should never update the popup menu structure 
        on its own to prevent performance problems. A better way 
        would be that a controller registers itself as status listener 
        for a command URL and immediately deregister after that. 
        Therefore status updates will not be send regularly for a 
        non visible popup menu.
    */
    void updatePopupMenu();
};
 
}; }; }; };
module com { module sun { module star { module lang {
 
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 has been created. 
     */
    void initialize( [in] sequence< any > aArguments ) raises( com::sun::star::uno::Exception );
};
 
}; }; }; };
module com { module sun { module star { module frame {
 
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 );
};
 
}; }; }; };
module com { module sun { module star { module frame {
 
published struct FeatureStateEvent: com::sun::star::lang::EventObject
{
    //-------------------------------------------------------------------------
    /** contains the URL of the feature.                                     */
    com::sun::star::util::URL FeatureURL;
 
    //-------------------------------------------------------------------------
    /** contains a descriptor of the feature for the user interface.         */
    string FeatureDescriptor;
 
    //-------------------------------------------------------------------------
    /** specifies whether the feature is currently enabled or disabled.      */
    boolean IsEnabled;
 
    //-------------------------------------------------------------------------
    /** specifies whether the XDispatch object has to be re-queried.         */
    boolean Requery;
 
    //-------------------------------------------------------------------------
    /** contains the state of the feature in this dispatch.                  */
    any State;
};
 
}; }; }; };

The framework project provides a base class to implement popup menu controller easier. It can be found in framework/inc/helper/popupmenucontrollerbase.hxx. There are several implementations for popup menu controller in framework/source/uielement which uses the base class and can be used as templates.

Currently OOo 2.0 provides the following popup menu controllers:

Command

Modules

Service

Purpose

.uno:CharFontName

all

com.sun.star.comp.framework.FontMenuController

Provides a popup menu with all supported fonts.

.uno:FontHeight

all

com.sun.star.comp.framework.FontSizeMenuController

Provides a popup menu with all supported font sizes.

.uno:ObjectMenue

all

com.sun.star.comp.framework.ObjectMenuController

Provides a popup menu with all supported commands of an embedded object.

.uno:InsertPageHeader

all

com.sun.star.comp.framework.HeaderMenuController

Provides a popup menu to insert pages headers.

.uno:InsertPageFooter

all

com.sun.star.comp.framework.FooterMenuController

Provides a popup menu to insert page footers.

.uno:ChangeControlType

all

com.sun.star.comp.framework.ControlMenuController

Provides a popup menu to change the control type of a selected form control.

.uno:AvailableToolbars

all

com.sun.star.comp.framework.ToolBarsMenuController

Provides a popup menu to show/hide toolbars.

.uno:ScriptOrganizer

all

com.sun.star.comp.framework.MacrosMenuController

Provides a popup menu with all available scripting languages.

.uno:RecentFileList

all

com.sun.star.comp.framework.RecentFilesMenuController

Provides a popup menu with recently opened files.

.uno:AddDirect

all

com.sun.star.comp.framework.NewMenuController

Provides a popup menu to create document for all available application modules.

.uno:AutoPilotMenu

all

com.sun.star.comp.framework.NewMenuController

Provides a popup menu with all available wizards.

The menu bar is completely controlled by an UNO implementations and is not based on any old sfx2 code. Therefor old sfx2 based and new non-sfx2 application modules are equally supported.

Toolbar

Toolbar item controller

Toolbar item controllers are responsible for a single toolbar button or toolbar item window (like a combobox, dropdown-box or an edit field). A toolbar item controller must support the following services and interfaces.



module com { module sun { module star { module frame {
 
service ToolbarController
{
    //-------------------------------------------------------------------------
    /** 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 
        a com::sun::star::frame::XFrame instance to which the toolbar controller belongs.
 
        CommandURL
        a string which specifies the command a toolbar 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 toolbar controller instance is ready for use after this call has been made 
        the first time. The toolbar implementation guarantees that the controller's 
        item window has been added to the toolbar 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 toolbar implementation to forward information to and request
        services from a toolbar 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::XToolbarController;
 
    //-------------------------------------------------------------------------
    /** used to notify and retrieve information that are specific for sub-toolbar 
        controllers.
 
        Used by implementations that want to provide the toolbar button sub-toolbar 
        function feature. A controller supporting this interface exchanges the 
        function of its own toolbar button, that opened the sub-toolbar, with the 
        one that has been selected on the sub-toolbar.
    */
    [optional] interface ::com::sun::star::frame::XSubToolbarController;
};
 
}; }; }; };
module com { module sun { module star { module frame { 
 
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 );
 
};
 
}; }; }; };
module com { module sun { module star { module frame { 
 
published struct FeatureStateEvent: com::sun::star::lang::EventObject
 
{
 //-------------------------------------------------------------------------
 
 /** contains the URL of the feature. */
 com::sun::star::util::URL FeatureURL;
 
 //-------------------------------------------------------------------------
 
 /** contains a descriptor of the feature for the user interface.*/
 string FeatureDescriptor;
 
 //-------------------------------------------------------------------------
 
 /** specifies whether the feature is currently enabled or disabled. */
 boolean IsEnabled;
 
 //-------------------------------------------------------------------------
 
 /** specifies whether the <type>XDispatch</type> has to be requeried. */
 boolean Requery;
 
 //-------------------------------------------------------------------------
 
 /** contains the state of the feature in this dispatch.*/
 any State;
}; 
 
}; }; }; };
module com { module sun { module star { module lang { 
 
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 );
}; 
 
//============================================================================= 
 
}; }; }; };
module com { module sun { module star { module util {
 
published interface XUpdatable: com::sun::star::uno::XInterface
{
 //-------------------------------------------------------------------------
 /** refreshes the data of the object from the connected data source. */
 void update();
};
 
//=============================================================================
 
}; }; }; };
module com { module sun { module star { module frame {
 
interface XToolbarController : com::sun::star::uno::XInterface
{
 //=============================================================================
 /** provides a function to execute the command which is bound to the toolbar controller.
 
 @param 
 a combination of <type scope="com::sun::star::awt">KeyModifier</type> value that represent the current state of the modifier keys.
 
 <p>
 This function is usally called by a toolbar implementation when a user clicked on a toolbar button or pressed enter on the keyboard when the item has the input focus.
 </p>
 */
 void execute( [in] short KeyModifier );
 
 //=============================================================================
 /** notifies a component that a single click has been made on the toolbar item.
 */
 void click();
 
 //=============================================================================
 /** notifies a component that a double click has been made on the toolbar item.
 */
 void doubleClick();
 
 //=============================================================================
 /** requests to create a popup window for additional functions.
 
 @return
 a <type scope="com::sun::star::awt">XWindow</type> which provides additional functions to the user. The reference must be empty if component does not want to provide a separate window.
 */
 com::sun::star::awt::XWindow createPopupWindow();
 
 //=============================================================================
 /** requests to create an item window which can be added to the toolbar.
 
 @param Parent
 a <type scope="com::sun::star::awt">XWindow</type> which must be used as a parent for the requested item window.
 
 @return
 a <type scope="com::sun::star::awt">XWindow</type> which can be added to a toolbar. The reference must be empty if a component does not want to provide an item window.
 */
 com::sun::star::awt::XWindow createItemWindow( [in] com::sun::star::awt::XWindow Parent );
};
 
}; }; }; };
module com { module sun { module star { module frame {
 
interface XSubToolbarController : com::sun::star::uno::XInterface
{
 //=============================================================================
 /** if the controller features a sub-toolbar. 
 
 @return
 <TRUE/> if the controller offers a sub toolbar, otherwise <FALSE/>.
 
 <p>
 Enables implementations to dynamically decide to support sub-toolbars
 or not.
 </p>
 */
 boolean opensSubToolbar();
 
 //=============================================================================
 /** provides the resource URL of the sub-toolbar this controller opens.
 
 @return
 name of the sub-toolbar this controller offers. A empty string 
 will be interpreted as if this controller offers no sub-toolbar.
 */
 string getSubToolbarName();
 
 //=============================================================================
 /** gets called to notify a controller that a sub-toolbar function has been 
 selected.
 
 @param aCommand
 a string which identifies the function that has been selected by
 a user.
 */
 void functionSelected( [in] string aCommand );
 
 //=============================================================================
 /** gets called to notify a controller that it should set an image which
 represents the current selected function.
 
 <p>
 Only the controller instance is able to set the correct image for the
 current function. A toolbar implementation will ask sub-toolbar 
 controllers to update their image whenever it has to update the images
 of all its buttons.
 </p>
 */
 void updateImage();
};
 
}; }; }; };

Generic toolbar item controller

A generic toolbar item controller is used by toolbar implementation for simple toolbar buttons. Normally most items of a toolbar consists of generic toolbar item controllers. They support the following generic functions by listening to status updates provided by the application module controller.


Variable

UNO Type/Poolitem

Action

State

String / SfxStringItem

Toolbar item changes its quick help and its label to the content of the provided string.

State

Boolean / SfxBoolItem

Toolbar item checks or unchecks its item, according to the boolean value.

State

com.sun.star.frame.status.VisibilityItem / SfxVisibilityItem

Toolbar item will be made visible or invisible according to the provided state.

State

com.sun.star.frame.status.ItemStatus ( Will be directly retrieved with Dispatcher->QueryState(...) or transported by SfxItemState ).

Toolbar item is set to normal or tri-state according to the provided member ItemStatus.State (see dont_care value in com.sun.star.frame.status.ItemState)

IsEnabled

Boolean

Toolbar item is enabled or disabled according to the value of IsEnabled.


Generic toolbar item controllers are not able to support the creation of sub-toolbars or floating windows.


Specific toolbar item controllers

Specific toolbar item controllers are much more flexible and can support the creation of sub-toolbars or floating windows. As they are much more powerful they have sole responsibility to react correctly on status updates received by the application module controller.

Variable

UNO Type/Poolitem

Action required

State

Boolean / SfxBoolItem

Toolbar item checks or unchecks its item according to the boolean value, if this makes sense in the context.

State

com.sun.star.frame.status.VisibilityItem / SfxVisibilityItem

Toolbar item should make itself visible or invisible according to the provided state.

State

com.sun.star.frame.status.ItemStatus ( Will be directly retrieved with Dispatcher->QueryState(...) or transported by SfxItemState ).

Toolbar item should set itself to normal or tri-state according to the provided member ItemStatus.State. It depends on the specific toolbar item if this makes sense.

IsEnabled

Boolean

Toolbar item must enabled or disabled itself according to the value of IsEnabled.



Specific toolbar item controllers must be registered in the configuration set org.openoffice.Office.UI.Controller/Registered/Toolbar when they are implemented via an UNO service.

An abstract from the Controller.xcu with registered specific toolbar item controllers:

 ...
 
<node oor:name="ToolBar">
 <node oor:name="c1" oor:op="replace">
  <prop oor:name="Command">
   <value>.uno:DBNewForm</value>
  </prop>
  <prop oor:name="Module">
   <value>com.sun.star.sdb.OfficeDatabaseDocument</value>
  </prop>
  <prop oor:name="Controller">
   <value>com.sun.star.sdb.ApplicationToolboxController</value>
  </prop>
 </node>
 <node oor:name="c2" oor:op="replace">
  <prop oor:name="Command">
   <value>.uno:Refresh</value>
  </prop>
  <prop oor:name="Module">
   <value>com.sun.star.sdb.OfficeDatabaseDocument</value>
  </prop>
  <prop oor:name="Controller">
   <value>com.sun.star.sdb.ApplicationToolboxController</value>
  </prop>
 </node>
</node>
 
 ...

The framework provides a base class which makes it much easier to implement UNO based specific toolbar item controllers. It can be found in svtools/inc/toolboxcontroller.hxx.

The sfx2 based specific toolbar item controllers are registered by calling ToolbarControllerClass::RegisterControl(SlotID, SfxModule* ). The framework implementation uses a special toolbar controller factory to create instances of sfx2 based specific toolbar item controllers. Sfx2 based specific toolbar controllers can use the known base class sfx2/inc/tbxctrl.hxx. It's a special wrapper which converts calls to the its UNO interfaces to the needs of sfx2 based toolbar controllers.

class SFX2_DLLPUBLIC SfxToolBoxControl:
    public ::com::sun::star::awt::XDockableWindowListener,
    public ::com::sun::star::frame::XSubToolbarController,
    public svt::ToolboxController 
{
    friend class SfxToolbox;
    friend class SfxToolBox_Impl;
    friend class SfxToolboxCustomizer;
    friend class SfxPopupWindow;
    friend struct SfxTbxCtrlFactory;
 
    SfxToolBoxControl_Impl* pImpl;
 
protected:
    DECL_LINK( PopupModeEndHdl, void * );
    DECL_LINK( ClosePopupWindow, SfxPopupWindow * );
 
    // old SfxToolBoxControl methods
    virtual void StateChanged( USHORT nSID, SfxItemState eState, const SfxPoolItem* pState );
    virtual void Select( BOOL bMod1 = FALSE );
    virtual void Select( USHORT nModifier );
 
    virtual void DoubleClick();
    virtual void Click();
    virtual SfxPopupWindowType GetPopupWindowType() const;
    virtual SfxPopupWindow* CreatePopupWindow();
    virtual SfxPopupWindow* CreatePopupWindowCascading();
    virtual Window* CreateItemWindow( Window *pParent );
 
    // Must be called by subclass to set a new popup window instance
    void SetPopupWindow( SfxPopupWindow* pWindow );
 
    // XInterface
    virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL acquire() throw();
    virtual void SAL_CALL release() throw();
 
    // XEventListener
    virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& aEvent ) throw( ::com::sun::star::uno::RuntimeException );
 
    // XComponent
    virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException);
 
    // new controller API
    // XStatusListener
    virtual void SAL_CALL statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw ( ::com::sun::star::uno::RuntimeException );
 
    // XToolbarController
    virtual void SAL_CALL execute( sal_Int16 KeyModifier ) 
    throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL click() 
    throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL doubleClick() 
    throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > SAL_CALL createPopupWindow() 
    throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > SAL_CALL createItemWindow( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& rParent ) 
    throw (::com::sun::star::uno::RuntimeException);
 
    // XSubToolbarController
    virtual ::sal_Bool SAL_CALL opensSubToolbar( ) throw (::com::sun::star::uno::RuntimeException);
    virtual ::rtl::OUString SAL_CALL getSubToolbarName( ) throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL functionSelected( const ::rtl::OUString& aCommand ) throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL updateImage( ) throw (::com::sun::star::uno::RuntimeException);
 
    // XDockableWindowListener
    virtual void SAL_CALL startDocking( const ::com::sun::star::awt::DockingEvent& e ) throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::awt::DockingData SAL_CALL docking( const ::com::sun::star::awt::DockingEvent& e ) throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL endDocking( const ::com::sun::star::awt::EndDockingEvent& e ) throw (::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL prepareToggleFloatingMode( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL toggleFloatingMode( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException); 
    virtual void SAL_CALL closed( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL endPopupMode( const ::com::sun::star::awt::EndPopupModeEvent& e ) throw (::com::sun::star::uno::RuntimeException);
 
    // helper methods
    void createAndPositionSubToolBar( const ::rtl::OUString& rSubToolBarResName );
    ::Size getPersistentFloatingSize( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame, const ::rtl::OUString& rSubToolBarResName );
 
public:
    SFX_DECL_TOOLBOX_CONTROL();
 
    SfxToolBoxControl( USHORT nSlotID, USHORT nId, ToolBox& rBox, BOOL bShowStrings = FALSE );
    virtual ~SfxToolBoxControl();
 
    ToolBox& GetToolBox() const;
    unsigned short GetId() const;
    unsigned short GetSlotId() const;
 
    void Dispatch( 
    const ::rtl::OUString& aCommand, 
    ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArgs );
    static void Dispatch( 
    const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >& rDispatchProvider, const rtl::OUString& rCommand, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArgs );
 
    static SfxItemState GetItemState( const SfxPoolItem* pState );
    static SfxToolBoxControl* CreateControl( USHORT nSlotId, USHORT nTbxId, ToolBox *pBox, SfxModule *pMod );
};

Statusbar

Specific statusbar item controller

The statusbar implementation only supports specific statusbar item controllers. There are no generic statusbar item controllers which could provide generic functions.

A statusbar item controller must support the following services and interfaces.

module com { module sun { module star { module frame {
 
service StatusbarController
{
 //-------------------------------------------------------------------------
 /** with this interface a component can receive events if a feature has 
 changed.
 
 <p>
 The statusbar controller implementation should register itself as a 
 listener when its <member scope="com::sun::star::util">XUpdatable</member> 
 interface has been called.
 </p>
 */
 interface com::sun::star::frame::XStatusListener;
 
 /** used to initialize a component with required arguments.
 
 <b>A statusbar controller needs at least three additional arguments 
 provided as <type scope="com::sun::star::beans">PropertyValue</type>:
 <ul>
 <li><b>Frame</b><br>a 
 <type scope="com::sun::star::frame">XFrame</type> instance
 to which the toolbar controller belongs.</li>
 <li><b>CommandURL</b><br>a string which specifies the command a 
 statusbar controller is bound.</li>
 <li><b>ServiceManager</b><br>a <type scope="com::sun::star::lang">
 XMultiServiceFactory</type> instance which can be used to 
 create additional UNO services.</li>
 </ul>
 */
 interface com::sun::star::lang::XInitialization;
 
 /** used to notify an implementation that it needs to add its listener or 
 remove and add them again.
 
 <p>
 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.
 </p>
 */
 interface com::sun::star::util::XUpdatable;
 
 //-------------------------------------------------------------------------
 /** used to notify changed features and requests for additional user 
 interface items.
 
 <p>
 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 
 <member scope="com::sun::star::lang">XInitialitation::initialize</member> 
 has been called. The behavior of the interface is undefined if the 
 controller component hasn't been initialized.
 </p>
 */
 interface com::sun::star::frame::XStatusbarController;
};
 
}; }; }; };
module com { module sun { module star { module frame {
 
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 );
 
};
 
}; }; }; };
module com { module sun { module star { module frame {
 
published struct FeatureStateEvent: com::sun::star::lang::EventObject
{
    //-------------------------------------------------------------------------
    /** contains the URL of the feature. 
     */
    com::sun::star::util::URL FeatureURL;
 
    //-------------------------------------------------------------------------
    /** contains a descriptor of the feature for the user interface.
     */
    string FeatureDescriptor;
 
    //-------------------------------------------------------------------------
    /** specifies whether the feature is currently enabled or disabled.
    */
    boolean IsEnabled;
 
    //-------------------------------------------------------------------------
    /** specifies whether the XDispatch object has to be requeried.
     */
    boolean Requery;
 
    //-------------------------------------------------------------------------
    /** contains the state of the feature in this dispatch.
     */
    any State;
 
};
}; }; }; };
module com { module sun { module star { module lang { 
 
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 );
}; 
 
//============================================================================= 
 
}; }; }; };
module com { module sun { module star { module util {
 
published interface XUpdatable: com::sun::star::uno::XInterface
{
 //-------------------------------------------------------------------------
 /** refreshes the data of the object from the connected data source. */
 void update();
};
 
//=============================================================================
 
}; }; }; };
module com { module sun { module star { module frame {
 
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 xGraphics
 the current graphics which should be used for painting.
 
 @param rOutputRectangle
 the output rectangle for graphic operations.
 
 @param nItemId
 the item id of the controller.
 
 @param nStyle
 the style of the statusbar item. The controller should respect the provided
 
style when paints.
 */
 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();
}; 
 
}; }; }; };

OOo 2.0 supports two kind of specific statusbar item controllers. UNO based specific statusbar item controllers must be registered in the configuration set org.openoffice.Office.UI.Controller/Registered/Statusbar.

An abstract from the Controller.xcu with registered specific statusbar item controllers:

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

The framework library provides a base class in svtools/inc/statusbarcontroller.hxx which makes it simpler to implement a UNO based specific status bar controller.

The sfx2 based specific statusbar item controllers are registered by calling StatusbarControllerClass::RegisterControl(SlotID, SfxModule* ). The framework implementation uses a special statusbar controller factory to create instances of sfx2 based specific statusbar item controllers. Sfx2 based specific statusbar controllers can use the known base class sfx2/inc/stbitem.hxx. It's a special wrapper which converts calls to the its UNO interfaces to the needs of sfx2 based statusbar controllers.

class SFX2_DLLPUBLIC SfxStatusBarControl: public svt::StatusbarController
{
 USHORT nSlotId;
 USHORT nId;
 StatusBar* pBar;
 
protected:
 // new controller API
 // XInterface
 virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
 virtual void SAL_CALL acquire() throw();
 virtual void SAL_CALL release() throw();
 
 // XEventListener
 virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& aEvent ) throw( ::com::sun::star::uno::RuntimeException );
 
 // XComponent
 virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException);
 
 // XStatusListener
 virtual void SAL_CALL statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw ( ::com::sun::star::uno::RuntimeException );
 
 // XStatusbarController
 virtual ::sal_Bool SAL_CALL mouseButtonDown( const ::com::sun::star::awt::MouseEvent& aMouseEvent ) throw (::com::sun::star::uno::RuntimeException);
 virtual ::sal_Bool SAL_CALL mouseMove( const ::com::sun::star::awt::MouseEvent& aMouseEvent ) throw (::com::sun::star::uno::RuntimeException);
 virtual ::sal_Bool SAL_CALL mouseButtonUp( const ::com::sun::star::awt::MouseEvent& aMouseEvent ) throw (::com::sun::star::uno::RuntimeException);
 virtual void SAL_CALL command( const ::com::sun::star::awt::Point& aPos, 
 ::sal_Int32 nCommand, 
 ::sal_Bool bMouseEvent, 
 const ::com::sun::star::uno::Any& aData ) 
 
throw (::com::sun::star::uno::RuntimeException);
 virtual void SAL_CALL paint( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics >& xGraphics, 
 const ::com::sun::star::awt::Rectangle& rOutputRectangle, 
 ::sal_Int32 nItemId, 
 ::sal_Int32 nStyle )
 
throw (::com::sun::star::uno::RuntimeException);
 virtual void SAL_CALL click() throw (::com::sun::star::uno::RuntimeException);
 virtual void SAL_CALL doubleClick() throw (::com::sun::star::uno::RuntimeException);
 
 // Old sfx2 interface
 virtual void StateChanged( USHORT nSID, SfxItemState eState,
 const SfxPoolItem* pState );
 virtual void Click();
 virtual void DoubleClick();
 virtual void Command( const CommandEvent& rCEvt );
 virtual BOOL MouseButtonDown( const MouseEvent & );
 virtual BOOL MouseMove( const MouseEvent & );
 virtual BOOL MouseButtonUp( const MouseEvent & );
 virtual void Paint( const UserDrawEvent &rUDEvt );
 
 static USHORT convertAwtToVCLMouseButtons( sal_Int16 nAwtMouseButtons ); 
 
public:
 SfxStatusBarControl( USHORT nSlotID, USHORT nId, StatusBar& rBar );
 virtual ~SfxStatusBarControl();
 
 USHORT GetSlotId() const { return nSlotId; }
 USHORT GetId() const { return nId; }
 StatusBar& GetStatusBar() const { return *pBar; }
 void CaptureMouse();
 void ReleaseMouse();
 
 static SfxStatusBarControl* CreateControl( USHORT nSlotID, USHORT nId, StatusBar *pBar, SfxModule* );
};

User interface controllers in the mixed sfx2/uno environment

How user interface controllers work in a pure UNO based environment?

EnvironmentPureUnoUserInterfaceController.png

How user interface controllers work in our mixed sfx2/UNO based environment?

EnvironmentUserInterfaceController.png


Let's see what happens in more detail, especially when we switch from one layer to another one.

  1. A shell wants to invalidate a slot and calls SfxShell::Invalidate( SlotID ).
  2. The bindings updates the SfxStateCache for the provided slot ID normally through a update timer or directly.
  3. The SfxStateCache calls StateChanged with the new state on a SfxDispatchController_Impl object.
  4. The SfxDispatchController_Impl now maps the sfx2 state information based on SfxPoolItem to UNO information and sends them to UNO based toolbar controller.
...
 
::cppu::OInterfaceContainerHelper* pContnr = pDispatch->GetListeners().getContainer( aDispatchURL.Complete );
if ( bNotify && pContnr )
{
  ::com::sun::star::uno::Any aState;
  if ( ( eState >= SFX_ITEM_AVAILABLE ) && pState && !IsInvalidItem( pState ) && !pState->ISA(SfxVoidItem) )
  {
    // Retrieve metric from pool to have correct sub ID when calling QueryValue
    USHORT nSubId( 0 );
    SfxMapUnit eMapUnit( SFX_MAPUNIT_100TH_MM );
 
    // retrieve the core metric
    // it's enough to check the objectshell, the only shell that does not 
    // use the pool of the document is SfxViewFrame, but it hasn't any metric parameters
    if ( pSlotServ && pDispatcher )
    {
      SfxShell* pShell = pDispatcher->GetShell( pSlotServ->GetShellLevel() );
      DBG_ASSERT( pShell, "Can't get core metric without shell!" );
      if ( pShell )
        eMapUnit = GetCoreMetric( pShell->GetPool(), nSID );
    }
 
    if ( eMapUnit == SFX_MAPUNIT_TWIP )
      nSubId |= CONVERT_TWIPS;
    pState->QueryValue( aState, (BYTE)nSubId );
  }
  else if ( eState == SFX_ITEM_DONTCARE )
  {
    // Use special uno struct to transport don't care state
    ::com::sun::star::frame::status::ItemStatus aItemStatus;
    aItemStatus.State = ::com::sun::star::frame::status::ItemState::dont_care;
    aState = makeAny( aItemStatus );
  }
 
  ::com::sun::star::frame::FeatureStateEvent aEvent;
  aEvent.FeatureURL = aDispatchURL;
  aEvent.Source = (::com::sun::star::frame::XDispatch*) pDispatch;
  aEvent.IsEnabled = eState != SFX_ITEM_DISABLED;
  aEvent.Requery = sal_False;
  aEvent.State = aState;
 
  ::cppu::OInterfaceIteratorHelper aIt( *pContnr );
  while( aIt.hasMoreElements() )
  {
    try
    {
      ((::com::sun::star::frame::XStatusListener *)aIt.next())->statusChanged( aEvent );
    }
    catch( ::com::sun::star::uno::RuntimeException& )
    {
      aIt.remove();
    }
  }
}
 
...

How does QueryValue work and convert an item to UNO com::sun::star::uno::any?


You can find the base class of any pool item in svtools/inc/poolitem.hxx

class SVL_DLLPUBLIC SfxPoolItem
{
friend class SfxItemPool;
friend class SfxItemDesruptor_Impl;
friend class SfxItemPoolCache;
friend class SfxItemSet;
friend class SfxVoidItem;
 
 ULONG nRefCount; // Referenzzaehler
 USHORT nWhich;
 USHORT nKind;
 
private:
 inline void SetRefCount( ULONG n );
 inline void SetKind( USHORT n );
public:
 inline ULONG AddRef( ULONG n = 1 ) const;
private:
 inline ULONG ReleaseRef( ULONG n = 1 ) const;
 SVL_DLLPRIVATE long Delete_Impl(void*);
 
protected:
 SfxPoolItem( USHORT nWhich = 0 );
 SfxPoolItem( const SfxPoolItem& );
 
public:
 TYPEINFO();
 
 virtual ~SfxPoolItem();
 void SetWhich( USHORT nId ) 
 { DBG_CHKTHIS(SfxPoolItem, 0); nWhich = nId; }
 USHORT Which() const { DBG_CHKTHIS(SfxPoolItem, 0); return nWhich; }
 virtual int operator==( const SfxPoolItem& ) const = 0;
 int operator!=( const SfxPoolItem& rItem ) const
 { return !(*this == rItem); }
 virtual int Compare( const SfxPoolItem &rWith ) const;
 virtual int Compare( const SfxPoolItem &rWith, const IntlWrapper& rIntlWrapper ) const;
 
 virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePresentation,
 SfxMapUnit eCoreMetric,
 SfxMapUnit ePresentationMetric,
 XubString &rText,
 const IntlWrapper * pIntlWrapper = 0 ) const;
 
 virtual USHORT GetVersion( USHORT nFileFormatVersion ) const;
 virtual int ScaleMetrics( long lMult, long lDiv );
 virtual int HasMetrics() const;
 
 virtual BOOL QueryValue( com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 ) const;
 virtual BOOL PutValue( const com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 );
 
 virtual SfxPoolItem* Create( SvStream &, USHORT nItemVersion ) const;
 virtual SvStream& Store( SvStream &, USHORT nItemVersion ) const;
 virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const = 0;
 
 ULONG GetRefCount() const { return nRefCount; }
 inline USHORT GetKind() const { return nKind; }
 
 static bool readByteString(SvStream & rStream, UniString & rString);
 static void writeByteString(SvStream & rStream,UniString const & rString);
 static bool readUnicodeString(SvStream & rStream, UniString & rString, bool bUnicode);
 static void writeUnicodeString(SvStream & rStream, UniString const & rString);
 
private:
 SfxPoolItem& operator=( const SfxPoolItem& ); // n.i.!!
};

A example how to implement QueryValue can be found in the implementation of the SvxULSpaceItem (located in svx/source/items/frmitems.cxx).

sal_Bool SvxULSpaceItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
{
  sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
  nMemberId &= ~CONVERT_TWIPS;
  switch( nMemberId )
  {
    // jetzt alles signed
    case 0:
    {
      ::com::sun::star::frame::status::UpperLowerMarginScale aUpperLowerMarginScale;
      aUpperLowerMarginScale.Upper = (sal_Int32)(bConvert ? TWIP_TO_MM100(nUpper) : nUpper);
      aUpperLowerMarginScale.Lower = (sal_Int32)(bConvert ? TWIP_TO_MM100(nLower) : nPropUpper);
      aUpperLowerMarginScale.ScaleUpper = (sal_Int16)nPropUpper;
      aUpperLowerMarginScale.ScaleLower = (sal_Int16)nPropLower;
      rVal <<= aUpperLowerMarginScale;
      break;
    }
    case MID_UP_MARGIN: rVal <<= (sal_Int32)(bConvert ? TWIP_TO_MM100(nUpper) : nUpper); break;
    case MID_LO_MARGIN: rVal <<= (sal_Int32)(bConvert ? TWIP_TO_MM100(nLower) : nLower); break;
    case MID_UP_REL_MARGIN: rVal <<= (sal_Int16) nPropUpper; break;
    case MID_LO_REL_MARGIN: rVal <<= (sal_Int16) nPropLower; break;
  }
  return sal_True;
}
  1. The UNO based toolbar controller now has to convert the state information (com::sun::star::uno::Any) again to provide it in a format that the sfx2 based toolbar controller implementation knows (SfxPoolItem).
// XStatusListener 
 
void SAL_CALL SfxToolBoxControl::statusChanged( const FeatureStateEvent& rEvent ) 
throw ( ::com::sun::star::uno::RuntimeException ) 
{ 
    SfxViewFrame* pViewFrame = NULL; 
    Reference < XController > xController; 
 
    ::vos::OGuard aGuard( Application::GetSolarMutex() ); 
    if ( getFrameInterface().is() ) 
        xController = getFrameInterface()->getController(); 
 
    Reference < XDispatchProvider > xProvider( xController, UNO_QUERY ); 
    if ( xProvider.is() ) 
    { 
        Reference < XDispatch > xDisp = xProvider->queryDispatch( 
            rEvent.FeatureURL, ::rtl::OUString(), 0 ); 
        if ( xDisp.is() ) 
        { 
            Reference< XUnoTunnel > xTunnel( xDisp, UNO_QUERY ); 
            SfxOfficeDispatch* pDisp = NULL; 
            if ( xTunnel.is() ) 
            { 
                sal_Int64 nImplementation = xTunnel>getSomething 
                SfxOfficeDispatch::impl_getStaticIdentifier() ); 
                pDisp = (SfxOfficeDispatch*)(nImplementation); 
            } 
 
            if ( pDisp ) 
                pViewFrame = pDisp->GetDispatcher_Impl()->GetFrame(); 
        } 
    } 
 
    USHORT nSlotId = 0; 
    SfxSlotPool& rPool = SFX_APP()->GetSlotPool( pViewFrame ); 
    const SfxSlot* pSlot = rPool.GetUnoSlot( rEvent.FeatureURL.Path ); 
    if ( pSlot ) 
        nSlotId = pSlot->GetSlotId(); 
 
    if ( nSlotId > 0 ) 
    { 
        if ( rEvent.Requery ) 
            svt::ToolboxController::statusChanged( rEvent ); 
        else 
        { 
            SfxItemState eState = SFX_ITEM_DISABLED; 
            SfxPoolItem* pItem = NULL; 
 
            if ( rEvent.IsEnabled ) 
            { 
                eState = SFX_ITEM_AVAILABLE; 
                ::com::sun::star::uno::Type pType = rEvent.State.getValueType(); 
 
                if ( pType == ::getVoidCppuType() ) 
                { 
                    pItem = new SfxVoidItem( nSlotId ); 
                    eState = SFX_ITEM_UNKNOWN; 
                } 
                else if ( pType == ::getBooleanCppuType() ) 
                { 
                    sal_Bool bTemp ; 
                    rEvent.State >>= bTemp ; 
                    pItem = new SfxBoolItem( nSlotId, bTemp ); 
                } 
                else if ( pType == ::getCppuType((const sal_uInt16*)0) ) 
                { 
                    sal_uInt16 nTemp ; 
                    rEvent.State >>= nTemp ; 
                    pItem = new SfxUInt16Item( nSlotId, nTemp ); 
                } 
                else if ( pType == ::getCppuType((const sal_uInt32*)0) ) 
                { 
                    sal_uInt32 nTemp ; 
                    rEvent.State >>= nTemp ; 
                    pItem = new SfxUInt32Item( nSlotId, nTemp ); 
                } 
                else if ( pType == ::getCppuType((const ::rtl::OUString*)0) ) 
                { 
                    ::rtl::OUString sTemp ; 
                    rEvent.State >>= sTemp ; 
                    pItem = new SfxStringItem( nSlotId, sTemp ); 
                } 
                else if ( pType == ::getCppuType(( const 
                    ::com::sun::star::frame::status::ItemStatus* )0) ) 
                { 
                    ItemStatus aItemStatus; 
                    rEvent.State >>= aItemStatus; 
                    eState = aItemStatus.State; 
                    pItem = new SfxVoidItem( nSlotId ); 
                } 
                else if ( pType == ::getCppuType(( const 
                    ::com::sun::star::frame::status::Visibility*)0) ) 
                { 
                    Visibility aVisibilityStatus; 
                    rEvent.State >>= aVisibilityStatus; 
                    pItem = new SfxVisibilityItem( nSlotId, aVisibilityStatus.bVisible ); 
                } 
                else 
                { 
                    if ( pSlot ) 
                        pItem = pSlot->GetType()->CreateItem(); 
                    if ( pItem ) 
                    { 
                        pItem->SetWhich( nSlotId ); 
                        pItem->PutValue( rEvent.State ); 
                    } 
                    else 
                        pItem = new SfxVoidItem( nSlotId ); 
                } 
           } 
 
           StateChanged( nSlotId, eState, pItem ); 
           delete pItem; 
        } 
    } 
}

As you can see the implementation retrieves the type of the slot and creates an empty item of that type. Now it has to use PutValue to convert the UNO com::sun::star::uno::Any back to an item. Let's see how the SvxULSpaceItem implements PutValue:

sal_Bool SvxULSpaceItem::PutValue( const uno::Any& rVal, BYTE nMemberId ) 
{ 
    sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); 
    nMemberId &= ~CONVERT_TWIPS; 
 
    sal_Int32 nVal; 
    switch( nMemberId ) 
    { 
        case 0: 
        { 
            ::com::sun::star::frame::status::UpperLowerMarginScale aUpperLowerMarginScale; 
            if ( !(rVal >>= aUpperLowerMarginScale )) 
                return sal_False; 
            else 
            { 
                SetUpper((sal_uInt16)(bConvert ? 
                    MM100_TO_TWIP( aUpperLowerMarginScale.Upper ) : aUpperLowerMarginScale.Upper)); 
                SetLower((sal_uInt16)(bConvert ? 
                    MM100_TO_TWIP( aUpperLowerMarginScale.Lower ) : aUpperLowerMarginScale.Lower)); 
                if( aUpperLowerMarginScale.ScaleUpper > 1 ) 
                    nPropUpper = aUpperLowerMarginScale.ScaleUpper; 
                if( aUpperLowerMarginScale.ScaleLower > 1 ) 
                    nPropUpper = aUpperLowerMarginScale.ScaleLower; 
            } 
        } 
 
        case MID_UP_MARGIN : 
            if(!(rVal >>= nVal) || nVal < 0) 
                return sal_False; 
            SetUpper((sal_uInt16)bConvert ? MM100_TO_TWIP(nVal) : nVal); 
            break; 
 
         case MID_LO_MARGIN : 
            if(!(rVal >>= nVal) || nVal < 0) 
                return sal_False; 
            SetLower((sal_uInt16)bConvert ? MM100_TO_TWIP(nVal) : nVal); 
            break; 
 
         case MID_UP_REL_MARGIN: 
         case MID_LO_REL_MARGIN: 
         { 
             sal_Int32 nRel; 
             if((rVal >>= nRel) && nRel > 1 ) 
             { 
                 if(MID_UP_REL_MARGIN == nMemberId) 
                     nPropUpper = nRel; 
                 else 
                     nPropLower = nRel; 
             } 
             else 
                 return FALSE; 
         } 
         break; 
 
         default: 
             DBG_ERROR("unknown MemberId"); 
             return sal_False; 
   } 
 
   return sal_True; 
}

We should now see some very important rules that this conversion can work correctly.


  • Never use the value 0 of the nMemberID to convert the default part of an item. This will immediately break our user interface updates.
  • If you want to add a new slot that can be used by the user interface, your MUST support Query- and PutValue. At least the default value 0 must be implemented.
  • Never use other arguments to call a slot than the ones that are declared in your SDI file. The conversion methods in sfx2 use the type description of the slot to map UNO types to items and cannot do this for unknown arguments.
Personal tools