[ Previous document | Content Table | Next document ]
This chapter describes the application environment of the OpenOffice.org application. It assumes that you have read the chapter 2 First Steps, and that you are able to connect to the office and load documents.
In most cases, developers use the functionality of OpenOffice.org by opening and modifying documents. The interfaces and services common to all document types and how documents are embedded in the surrounding application environment are discussed.
It is also possible to extend the functionality of OpenOffice.org by replacing the services mentioned here by intercepting the communication between objects or by creating your own document type and integrating it into the desktop environment. All these things are discussed in this chapter.
The OpenOffice.org application environment is made up of the desktop environment and the framework API.
Illustration 7.1: OpenOffice.org Application Environment |
The desktop environment consists of the desktop and auxiliary objects. It employs the framework API to carry out its functions. The framework API currently has two parts: the component framework and dispatch framework. The component framework follows a special Frame-Controller-Model paradigm to manage components viewable in OpenOffice.org. The dispatch framework handles command requests sent by the GUI.
The com.sun.star.frame.Desktop service is the central management instance for the OpenOffice.org application framework. All OpenOffice.org application windows are organized in a hierarchy of frames that contain viewable components. The desktop is the root frame for this hierarchy. From the desktop you can load viewable components, access frames and components, terminate the office, traverse the frame hierarchy and dispatch command requests.
The name of this service originates at StarOffice 5.x, where all document windows were embedded into a common application window that was occupied by the StarOffice desktop, mirroring the Windows desktop. The root frame of this hierarchy was called the desktop frame. The name of this service and the interface name com.sun.star.frame.XDesktop were kept for compatibility reasons.
The desktop object and frame objects use auxiliary services, such as the com.sun.star.document.TypeDetection service and other, opaque implementations that interact with the UNO-based office, but are not accessible through the OpenOffice.org API. Examples for the latter are the global document event handling and its user interface (Tools – Configure – Events), and the menu bars that use the dispatch API without being UNO services themselves. The desktop service, together with these surrounding objects, is called the desktop environment.
Illustration 7.2: The Desktop terminates the office and manages components and frames |
The viewable components managed by the desktop can be three different kinds of objects: full-blown office documents with a document model and controllers, components with a controller but no model, such as the bibliography and database browser, or simple windows without API-enabled controllers, for example, preview windows. The commonality between these types of components is the com.sun.star.lang.XComponent interface. Components with controllers are also called office components, whereas simple window components are called trivial components.
Frames in the OpenOffice.org API are the connecting link between windows, components and the desktop environment. The relationship between frames and components are discussed in the next section 7.1.1 Office Development - OpenOffice.org Application Environment - Overview - Framework API.
Like all other services, the com.sun.star.frame.Desktop service can be exchanged by another implementation that extends the functionality of OpenOffice.org. By exchanging the desktop service it is possible to use different kinds of windows or to make OpenOffice.org use MDI instead of SDI. This is not an easy thing to do, but it is possible without changing any code elsewhere in OpenOffice.org.
The framework API does not define an all-in-one framework with strongly coupled interfaces, but defines specialized frameworks that are grouped together by implementing the relevant interfaces at OpenOffice.org components. Each framework concentrates on a particular aspect, so that each component decides the frameworks it wants to participate in.
Currently, there are two of these frameworks: the component framework that implements the frame-controller-model paradigm and the dispatch framework that handles command requests from and to the application environment. The controller and frame implementations form the bridge between the two frameworks, because controllers and frames implement interfaces from the component framework and dispatch framework.
The framework API is an abstract specification. Its current implementation uses the Abstract Window Toolkit (AWT) specified in com.sun.star.awt, which is an abstract specification as well. The current implementation of the AWT is the Visual Component Library (VCL), a cross-platform toolkit for windows and controls written in C++ created before the specification of com.sun.star.awt and adapted to support com.sun.star.awt.
The well known Model-View-Controller (MVC) paradigm separates three application areas: document data (model), presentation (view) and interaction (controller). OpenOffice.org has a similar abstraction, called the Frame-Controller-Model (FCM) paradigm. The FCM paradigm shares certain aspects with MVC , but it has different purposes, therefore it is best to approach FCM independently from MVC. The model and controller in MVC and FCM are quite different things.
The FCM paradigm in OpenOffice.org separates three application areas: document object (model), screen interaction with the model (controller) and controller-window linkage (frame).
The model holds the document data and has methods to change these data without using a controller object. Text, drawings, and spreadsheet cells are accessed directly at the model.
The controller has knowledge about the current view status of the document and manipulates the screen presentation of the document, but not the document data. It observes changes made to the model, and can be duplicated to have multiple controllers for the same model.
The frame contains the controller for a model and knows the windows that are used with it, but does not have window functionality.
The purpose of FCM is to have three exchangeable parts that are used with an exchangeable window system:
It is possible to write a new controller that presents an existing model in a different manner without changing the model or the frame. A controller depends on the model it presents, therefore a new controller for a new model can be written.
Developers can introduce new models for new document types without taking care of the frame and underlying window management system. However, since there is no default controller, it is necessary to write a suitable controller also.
By keeping all window-related functionality separate from the frame, it is possible to use one single frame implementation for every possible window in the entire OpenOffice.org application. Thus, the presentation of all visible components is customized by exchanging the frame implementation. At runtime you can access a frame and replace the controller, together with the model it controls, by a different controller instance.
The main role of a frame in the Frame-Controller-Model paradigm is to act as a liaison between viewable components and the window system.
Frames can hold one component, or a component and one or more subframes. The following diagrams: Illustration 7.3: Frame containing a component and Illustration 7.4: Frame containing a component and a sub-frame depict both possibilities. The first illustration 7.3 shows a frame containing only a component. It is connected with two window instances: the container window and component window.
Illustration 7.3: Frame containing a component |
When a frame is constructed, the frame must be initialized with a container window using com.sun.star.frame.XFrame:initialize(). This method expects the com.sun.star.awt.XWindow interface of a surrounding window instance, which becomes the container window of the frame. The window instance passed to initialize() must also support com.sun.star.awt.XTopWindow to become a container window. The container window must broadcast window events, such as windowActivated(), and appear in front of other windows or be sent to the background. The fact that container windows support com.sun.star.awt.XTopWindow does not mean the container window is an independent window of the underlying window system with a title bar and a system menu. An XTopWindow acts as a window if necessary, but it can also be docked or depend on a surrounding application window.
After initializing the frame, a component is set into the frame by a frame loader implementation that loads a component into the frame. It calls com.sun.star.frame.XFrame:setComponent() that takes another com.sun.star.awt.XWindow instance and the com.sun.star.frame.XController interface of a controller.Usually the controller is holding a model, therefore the component gets a component window of its own, separate from the container window.
A frame with a component is associated with two windows: the container window which is an XTopWindow and the component window, which is the rectangular area that displays the component and receives GUI events for the component while it is active. When a frame is initialized with an instance of a window in a call to initialize(), this window becomes its container window. When a component is set into a frame using setComponent(), another com.sun.star.awt.XWindow instance is passed becoming the component window.
When a frame is added to the desktop frame hierarchy, the desktop becomes the parent frame of our frame. For this purpose, the com.sun.star.frame.XFramesSupplier interface of the desktop is passed to the method setCreator() at the XFrame interface. This happens internally when the method append() is called at the com.sun.star.frame.XFrames interface supplied by the desktop.
|
|
A component window can have sub-windows, and that is the case with all documents in OpenOffice.org. For instance, a text document has sub-windows for the toolbars and the editable text. Form controls are sub-windows, as well, however, these sub-windows depend on the component window and do not appear in the Frame-Controller-Model paradigm, as discussed above. |
The second diagram shows a frame with a component and a sub-frame with another component. Each frame has a container window and component window.
Illustration 7.4: Frame containing a component and a sub-frame |
In the OpenOffice.org GUI, sub-frames appear as dependent windows. The sub-frame in Illustration 7.4 could be a dockable window, such as the beamer showing the database browser or a floating frame in a document created with Insert – Frame.
Note that a frame with a component and sub-frame is associated with four windows. The frame and the sub-frame have a container window and a component window for the component.
When a sub-frame is added to a surrounding frame, the frame becomes the parent of the sub-frame by a call to setCreator() at the sub-frame. This happens internally when the method append() is called at the com.sun.star.frame.XFrames interface supplied by the surrounding frame.
The section 7.1.4 Office Development - OpenOffice.org Application Environment - Creating Frames Manually shows examples for the usage of the XFrame interface that creates frames in the desktop environment, constructs dockable and standalone windows, and inserts components into frames.
Besides the main role of frames as expressed in the com.sun.star.frame.XFrame interface, frames play another role by providing a communication context for the component they contain, that is, every communication from a controller to the desktop environment, and the user interface and conversely is done through the frame. This aspect of a frame is published through the com.sun.star.frame.XDispatchProvider interface, that uses special command requests to trigger actions.
The section 7.1.6 Office Development - OpenOffice.org Application Environment - Using the Dispatch Framework discusses the usage of the dispatch API.
The desktop environment section discussed the three kinds of viewable components that can be inserted into a frame. If the component has a controller and a model like a document, or if it has only a controller, such as the bibliography and database browser, it implements the com.sun.star.frame.Controller service represented by the interface com.sun.star.frame.XController. In the call to com.sun.star.frame.XFrame:setComponent(), the controller is passed with the component window instance. If the component has no controller, it directly implements com.sun.star.lang.XComponent and com.sun.star.awt.XWindow. In this case, the component is passed as XWindow parameter, and the XController parameter must be an XController reference set to null.
If the viewable component is a trivial component (implementing XWindow only), the frame holds a reference to the component window, controls the lifetime of the component and propagates certain events from the container window to the component window. If the viewable component is an office component (having a controller), the frame adds to these basic functions a set of features for integration of the component into the environment by supporting additional command URLs for the component at its com.sun.star.frame.XDispatchProvider interface.
Controllers in OpenOffice.org are between a frame and document model. This is their basic role as expressed in com.sun.star.frame.XController, which has methods getModel() and getFrame(). The method getFrame() provides the frame the controller is attached to. The method getModel() returns a document model, but it may return an empty reference if the component does not have a model.
Usually the controller objects support additional interfaces specific to the document type they control, such as com.sun.star.sheet.XSpreadsheetView for Calc document controllers or com.sun.star.text.XTextViewCursorSupplier for Writer document controllers.
Illustration 7.5: Controller with Model and Frame |
There can be more than one controller instance with frames of their own controlling the same document model simultaneously. Multiple controllers and frames are created by OpenOffice.org when the user clicks Window – New Window.
Windows in the OpenOffice.org API are rectangular areas that are positioned and resized, and inform listeners about UI events (com.sun.star.awt.XWindow). They have a platform-specific counterpart that is wrapped in the com.sun.star.awt.XWindowPeer interface, which is invalidated (redrawn), and sets the system pointer and hands out the toolkit for the window. The usage of the window interfaces is outlined in the section 7.1.3 Office Development - OpenOffice.org Application Environment - Using the Component Framework - Window Interfaces below.
The dispatch framework is designed to provide a uniform access to components for a GUI by using command URLs that mirror menu items, such as Edit – Select All with various document components. Only the component knows how to execute a command. Similarly, different document components trigger changes in the UI by common commands. For example, a controller might create UI elements like a menu bar, or open a hyperlink.
Command dispatching follows a chain of responsibility. Calls to the dispatch API are moderated by the frame, so all dispatch API calls from the UI to the component and conversely are handled by the frame. The frame passes on the command until an object is found that can handle it. It is possible to restrict, extend or redirect commands at the frame through a different frame implementation or through other components connecting to the frame.
It has already been discussed that frames and controllers have an interface com.sun.star.frame.XDispatchProvider. The interface is used to query a dispatch object for a command URL from a frame and have the dispatch object execute the command. This interface is one element of the dispatch framework.
By offering the interception of dispatches through the interface com.sun.star.frame.XDispatchProviderInterception, the Frame service offers a method to modify a component's handling of GUI event s while keeping its whole API available simultaneously.
|
|
Normally, command URL dispatches go to a target frame which decides what to do with it. A component can use globally accessible objects like the desktop service to bypass restrictions set by a frame, but this is not recommended. It is impossible to prevent a implemention of components against the design principles, because the framework API is made for components that adhere to its design. |
The usage of the Dispatch Framework is described in the section 7.1.6 Office Development - OpenOffice.org Application Environment - Using the Dispatch Framework.
Illustration 7.6: Desktop Service and Component Framework |
The com.sun.star.frame.Desktop service available at the global service manager includes the service com.sun.star.frame.Frame. The Desktop service specification provides three interfaces: com.sun.star.frame.XDesktop, com.sun.star.frame.XComponentLoader and com.sun.star.document.XEventBroadcaster, as shown in the following UML chart:
Illustration 7.7: UML description of the desktop service |
The interface com.sun.star.frame.XDesktop provides access to frames and components, and controls the termination of the office process. It defines the following methods:
com::sun::star::frame::XFrame getCurrentFrame ()
com::sun::star::container::XEnumerationAccess getComponents ()
com::sun::star::lang::XComponent getCurrentComponent ()
boolean terminate ()
void addTerminateListener ( [in] com::sun::star::frame::XTerminateListener xListener)
void removeTerminateListener ( [in] com::sun::star::frame::XTerminateListener xListener)
The methods getCurrentFrame() and getCurrentComponent() distribute the active frame and document model, whereas getComponents() returns a com.sun.star.container.XEnumerationAccess to all loaded documents. For documents loaded in the desktop environment the methods getComponents() and getCurrentComponent() always return the com.sun.star.lang.XComponent interface of the document model.
|
|
If a specific document component is required, but are not sure whether this component is the current component, use getComponents() to get an enumeration of all document components, check each for the existence of the com.sun.star.frame.XModel interface and use getURL() at XModel to identify your document. Since not all components have to support XModel, test for XModel before calling getURL(). |
The office process is usually terminated when the user selects File - Exit or after the last application window has been closed. Clients can terminate the office through a call to terminate()and add a terminate listener to veto the shutdown process.
As long as the Windows quickstarter is active, the soffice executable is not terminated.
The following sample shows an com.sun.star.frame.XTerminateListener implementation that prevents the office from being terminated when the class TerminationTest is still active:
import com.sun.star.frame.TerminationVetoException;
import com.sun.star.frame.XTerminateListener;
public class TerminateListener implements XTerminateListener {
public void notifyTermination (com.sun.star.lang.EventObject eventObject) {
System.out.println("about to terminate...");
}
public void queryTermination (com.sun.star.lang.EventObject eventObject)
throws TerminationVetoException {
// test if we can terminate now
if (TerminationTest.isAtWork() == true) {
System.out.println("Terminate while we are at work? No way!");
throw new TerminationVetoException() ; // this will veto the termination,
// a call to terminate() returns false
}
}
public void disposing (com.sun.star.lang.EventObject eventObject) {
}
}
The following class TerminationTest tests the TerminateListener above.
import com.sun.star.bridge.XUnoUrlResolver;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.beans.XPropertySet;
import com.sun.star.beans.PropertyValue;
import com.sun.star.frame.XDesktop;
import com.sun.star.frame.TerminationVetoException;
import com.sun.star.frame.XTerminateListener;
public class TerminationTest extends java.lang.Object {
private static boolean atWork = false;
public static void main(String[] args) {
XComponentContext xRemoteContext = null;
XMultiComponentFactory xRemoteServiceManager = null;
XDesktop xDesktop = null;
try {
// connect and retrieve a remote service manager and component context
XComponentContext xLocalContext =
com.sun.star.comp.helper.Bootstrap.createInitialComponentContext(null);
XMultiComponentFactory xLocalServiceManager = xLocalContext.getServiceManager();
Object urlResolver = xLocalServiceManager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver", xLocalContext );
XUnoUrlResolver xUnoUrlResolver = (XUnoUrlResolver) UnoRuntime.queryInterface(
XUnoUrlResolver.class, urlResolver );
Object initialObject = xUnoUrlResolver.resolve(
"uno:socket,host=localhost,port=2083;urp;StarOffice.ServiceManager" );
XPropertySet xPropertySet = (XPropertySet)UnoRuntime.queryInterface(
XPropertySet.class, initialObject);
Object context = xPropertySet.getPropertyValue("DefaultContext");
xRemoteContext = (XComponentContext)UnoRuntime.queryInterface(
XComponentContext.class, context);
xRemoteServiceManager = xRemoteContext.getServiceManager();
// get Desktop instance
Object desktop = xRemoteServiceManager.createInstanceWithContext (
"com.sun.star.frame.Desktop ", xRemoteContext);
xDesktop = (XDesktop)UnoRuntime.queryInterface(XDesktop.class, desktop);
TerminateListener terminateListener = new TerminateListener ();
xDesktop.addTerminateListener (terminateListener);
// try to terminate while we are at work
atWork = true;
boolean terminated = xDesktop.terminate ();
System.out.println("The Office " +
(terminated == true ? "has been terminated" : "is still running, we are at work"));
// no longer at work
atWork = false;
// once more: try to terminate
terminated = xDesktop.terminate ();
System.out.println("The Office " +
(terminated == true ? "has been terminated" :
"is still running. Someone else prevents termination, e.g. the quickstarter"));
}
catch (java.lang.Exception e){
e.printStackTrace();
}
finally {
System.exit(0);
}
}
public static boolean isAtWork() {
return atWork;
}
}
The office freezes when terminate() is called if there are unsaved changes. As a workaround set all documents into an unmodified state through their com.sun.star.util.XModifiable interface or store them using com.sun.star.frame.XStorable.
The Desktop offers a facility to load components through its interface com.sun.star.frame.XComponentLoader. It has one method:
com::sun::star::lang::XComponent loadComponentFromURL ( [in] string aURL,
[in] string aTargetFrameName,
[in] long nSearchFlags,
[in] sequence < com::sun::star::beans::PropertyValue aArgs > )
Refer to chapter 7.1.5 Office Development - OpenOffice.org Application Environment - Handling Documents for details about the loading process.
For versions beyond 641, the desktop also provides an interface that allows listeners to be notified about certain document events through its interface com.sun.star.document.XEventBroadcaster.
void addEventListener ( [in] com::sun::star::document::XEventListener xListener)
void removeEventListener ( [in] com::sun::star::document::XEventListener xListener)
The XEventListener must implement a single method (besides disposing()):
[oneway] void notifyEvent ( [in] com::sun::star::document::EventObject Event )
The struct com.sun.star.document.EventObject has a string member EventName that assumes one of the values specified in com.sun.star.document.Events. The corresponding events are found on the Events tab of the Tools – Configure dialog when the option OpenOffice.org is selected.
The desktop broadcasts these events for all loaded documents.
The current version of OpenOffice.org does not have a GUI element as a desktop. The redesign of the OpenOffice.org GUI in StarOffice 5.x and later resulted in the com.sun.star.frame.Frame service part of the desktop service is now non-functional. While the XFrame interface can still be queried from the desktop, almost all of its methods are dummy implementations. The default implementation of the desktop object in OpenOffice.org is not able to contain a component and refuses to be attached to it, because the desktop is still a frame that is the root for the common hierarchy of all frames in OpenOffice.org. The desktop has to be a frame because its com.sun.star.frame.XFramesSupplier interface must be passed to com.sun.star.frame.XFrame:setCreator() at the child frames, therefore the desktop becomes the parent frame. However, the following functionality of com.sun.star.frame.Frame is still in place:
The desktop interface com.sun.star.frame.XFramesSupplier offers methods to access frames. This interface inherits from com.sun.star.frame.XFrame, and introduces the following methods:
com::sun::star::frame::XFrames getFrames ()
com::sun::star::frame::XFrame getActiveFrame ()
void setActiveFrame ( [in] com::sun::star::frame::XFrame xFrame)
The method getFrames() returns a com.sun.star.frame.XFrames container, that is a com.sun.star.container.XIndexAccess, with additional methods to add and remove frames:
void append ( [in] com::sun::star::frame::XFrame xFrame )
sequence < com::sun::star::frame::XFrame > queryFrames ( [in] long nSearchFlags )
void remove ( [in] com::sun::star::frame::XFrame xFrame )
This XFrames collection is used when frames are added to the desktop to become application windows.
Through getActiveFrame(), you access the active sub-frame of the desktop frame, whereas setActiveFrame() is called by a sub-frame to inform the desktop about the active sub-frame.
The object returned by getFrames() does not support XTypeProvider, therefore it cannot be used with OpenOffice.org Basic.
The parent interface of XFramesSupplier, com.sun.star.frame.XFrame is functional by accessing the frame hierarchy below the desktop. These methods are discussed in the section 7.1.3 Office Development - OpenOffice.org Application Environment - Using the Component Framework - Frames below:
com::sun::star::frame::XFrame findFrame ( [in] string aTargetFrameName, [in] long nSearchFlags );
boolean isTop ();
The generic dispatch interface com.sun.star.frame.XDispatchProvider executes functions of the internal Desktop implementation that are not accessible through specialized interfaces. Dispatch functions are described by a command URL. The XDispatchProvider returns a dispatch object that dispatches a given command URL. A reference of command URLs supported by the desktop is available on OpenOffice (http://www.openoffice.org/files/documents/25/60/commands_11beta.html). Through the com.sun.star.frame.XDispatchProviderInterception, client code intercepts thecommand dispatches at the desktop. The dispatching process is described in section 7.1.6 Office Development - OpenOffice.org Application Environment - Using the Dispatch Framework.
The component framework comprises the interfaces of frames, controllers and models used to manage components in the OpenOffice.org desktop environment. In our context, everything that "dwells" in a frame of the desktop environment is called a component, because the interface com.sun.star.lang.XComponent is the common denominator for objects that are loaded into frames.
Frames, controllers and models hold references to each other. The frame is by definition the default owner of the controller and the model, that is,. it is responsible to call dispose() on the controller and model when it is destroyed itself. Other objects that are to hold references to the frame, controller, or model must register as listeners to be informed when these references become invalid. Therefore XModel,
XController and XFrame inherit from XComponent:
void dispose ()
void addEventListener ( [in] com::sun::star::lang::XEventListener xListener)
void removeEventListener ( [in] com::sun::star::lang::XEventListener aListener)
The process to resolve the circular dependencies of the component framework is a complex. For instance, the objects involved in the process may be in a condition where they may not be disposed of. Refer to the section 7.1.5 Office Development - OpenOffice.org Application Environment - Handling Documents - Closing Documents for additional details.
Theoretically every UNO object could exist in a frame, as long as it is willing to let the frame control its existence when it ends.
A trivial component (XWindow only) is enough for simple viewing purposes, where no activation of a component and related actions like cursor positioning or user interactions are necessary.
If the component participates in more complex interactions, it must implement the controller service.
Many features of the desktop environment are only available if the URL of a component is known. For example:
Presenting the URL or title of the document.
Inserting the document into the autosave queue.
Preventing the desktop environment from loading documents twice.
Allow for participation in the global document event handling.
In this case, com.sun.star.frame.XModel comes into operation, since it has methods to handle URLs, among others.
So a complete office component is made up of
a controller object that presents the model or shows a view to the model that implements the com.sun.star.frame.Controller service, but publishes additional document-specific interfaces. For almost all OpenOffice.org document types there are document specific controller object specifications,such as com.sun.star.sheet.SpreadsheetView, and com.sun.star.drawing.DrawingDocumentDrawView. For controllers, refer to the section 7.1.3 Office Development - OpenOffice.org Application Environment - Using the Component Framework - Controllers.
a model object implementing the com.sun.star.document.OfficeDocument service. Refer to the section 7.1.3 Office Development - OpenOffice.org Application Environment - Using the Component Framework - Models.
Usually developers require the controller and frame of an already loaded document model. The com.sun.star.frame.XModel interface of OpenOffice.org document models gets the controller that provides access to the frame through its com.sun.star.frame.XController interface. The following illustration shows the methods that get the controller and frame for a document model and conversely. From the frame , obtain the corresponding component and container window.
Illustration 7.8: Frame-Controller-Model Organization |
If the loaded component is a trivial component and implements com.sun.star.awt.XWindow only, the window and the window peer is reached by querying these interfaces from the com.sun.star.lang.XComponent returned by loadComponentFromURL().
Illustration 7.9: Frame Service |
The main role of a frame is to link components into a surrounding window system. This role is expressed by the following methods of the frame's main interface com.sun.star.frame.XFrame:
// methods for container window
void initialize ( [in] com::sun::star::awt::XWindow xWindow);
com::sun::star::awt::XWindow getContainerWindow ();
// methods for component window and controller
boolean setComponent ( [in] com::sun::star::awt::XWindow xComponentWindow,
[in] com::sun::star::frame::XController xController );
com::sun::star::awt::XWindow getComponentWindow ();
com::sun::star::frame::XController getController ();
The first two methods deal with the container window of a frame, the latter three are about linking the component and the component window with the frame. The method initialize() expects a top window that is created by the AWT toolkit that becomes the container window of the frame and is retrieved by getContainerWindow().
When frames link components into a surrounding window system, they build a frame hierarchy. This aspect is covered by the hierarchy-related XFrame methods:
[oneway] void setCreator ( [in] com::sun::star::frame::XFramesSupplier xCreator );
com::sun::star::frame::XFramesSupplier getCreator ();
string getName ();
[oneway] void setName ( [in] string aName );
com::sun::star::frame::XFrame findFrame ( [in] string aTargetFrameName, [in] long nSearchFlags );
boolean isTop ();
The XFrame method setCreator() informs a frame about its parent frame and must be called by a frames container (com.sun.star.frame.XFrames) when a frame is added to it by a call to com.sun.star.frame.XFrames:append(). A frames container is provided by frames supporting the interface com.sun.star.frame.XFramesSupplier. XFramesSupplier is currently supported by the desktop frame and by the default frame implementation used by OpenOffice.org documents. It is described below.
The frame has a custom name that is read through getName() and written through setName(). Frames in the desktop hierarchy created by GUI interaction usually do not have names. The getName() returns an empty string for them, whereas frames that are created for special purposes, such as the beamer frame or the online help, have names. Developers can set a name and use it to address a frame in findFrame() calls or when loading a component into the frame. Custom frame names must not start with an underscore.Leading underscores are reserved for special frame names.See below.
Every frame in the frame hierarchy is accessed through any other frame in this hierarchy by calling the findFrame() method. This method searches for a frame with a given name in five steps: self, children, siblings, parent, and create if not found. The findFrame() checks the called frame, then calls findFrame() at its children, then its siblings and at its parent frame. The fifth step in the search strategy is reached if the search makes it to the desktop without finding a frame with the given name. In this case, a new frame is created and assigned the name that was searched for. If the top frame is outside the desktop hierarchy, a new frame is not created.
The name used with findFrame() can be an arbitrary string without a leading underscore or one of the following reserved frame names. These names are for internal use for loading documents.Some of the reserved names are logical in a findFrame() call, also. A complete list of reserved frame names can be found in section 7.1.5 Office Development - OpenOffice.org Application Environment - Handling Documents - Loading Documents - Target Frame.
_top
Returns the top frame of the called frame, first frame where isTop() returns true when traveling up the hierarchy.
_parent
Returns the next frame above in the frame hierarchy.
_self
Returns the frame itself, same as an empty target frame name. This means you are searching for a frame you already have, but it is legal to do so.
_blank
Creates a new top-level frame whose parent is the desktop frame.
Calls with "_top" or "_parent" return the frame itself if the called frame is a top frame or has no parent. This is compatible to the targetting strategies of web browsers.
We have seen that findFrame() is called recursively. To control the recursion, the search flags parameter specified in the constants group com.sun.star.frame.FrameSearchFlag is used. For all of the five steps mentioned above, a suitable flag exists (SELF, CHILDREN, SIBLINGS, PARENT, CREATE ). Every search step can be prohibited by deleting the appropriate FrameSearchFlag. The search flag parameter can also be used to avoid ambiguities caused by multiple occurrences of a frame name in a hierarchy by excluding parts of the frame tree from the search. If findFrame() is called for a reserved frame name, the search flags are ignored.
|
|
An additional flag can be used to extend a bottom-up search to all OpenOffice.org application windows, no matter where the search starts. Based on the five flags for the five steps, the default frame search stops searching when it reaches a top frame and does not continue with other OpenOffice.org windows. Setting the TASKS flag overrides this. |
There are separate frame hierarchies that do not interact with each other. If a frame is created, but not inserted into any hierarchy, it becomes the top frame of its own hierarchy. This frame and its contents can not be accessed from other hierarchies by traversing the frame hierarchies through API calls. , Also, this frame and its content cannot reach frames and their contents in other hierarchies. It is the code that creates a frame and decides if the new frame becomes part of an existing hierarchy, thus enabling it to find other frames ,and making it and its viewable component visible to the other frames. Examples for frames that are not inserted into an existing hierarchy are preview frames in dialogs, such as the document preview in the File – New – Templates and Documents dialog.
|
|
This is the only way the current frame and desktop implementation handle this. If one exchanges either or both of them by another implementation, the treatment of the "_blank" target and the CREATE SearchFlag may differ. |
Several actions take place at a frame. The context of viewable components can change, a frame may be activated or the relationship between frame and component may be altered. For instance, when the current selection in a document has been changed, the controller informs the frame about it by calling contextChanged(). The frame then tells its frame action listeners that the context has changed. The frame action listeners are also informed about changes in the relationship between the frame and component, and about frame activation. The corresponding XFrame methods are:
void contextChanged ();
[oneway] void activate ();
[oneway] void deactivate ();
boolean isActive ();
[oneway] void addFrameActionListener ( [in] com::sun::star::frame::XFrameActionListener xListener );
[oneway] void removeFrameActionListener ( [in] com::sun::star::frame::XFrameActionListener xListener );
The method activate() makes the given frame the active frame in its parent container. If the parent is the desktop frame, this makes the associated component the current component. However, this is not reflected in the user interface by making the corresponding window the top window. If the container of the active frame is to be the top window, use setFocus() at the com.sun.star.awt.XWindow interface of the container window.
The interface com.sun.star.frame.XFrameActionListener used with addFrameActionListener() must implement the following method:
|
Method of com.sun.star.frame.XFrameActionListener | |
|
Takes a struct com.sun.star.frame.FrameActionEvent. The struct contains two members: the source com.sun.star.frame.XFrame Frame and an enum com.sun.star.frame.FrameActionEvent Action value with one of the following values: COMPONENT_ATTACHED: a component has been attached to a frame. This is almost the same as the instantiation of the component within that frame. The component is attached to the frame immediately before this event is broadcast. COMPONENT_DETACHING: a component is detaching from a frame. This is the same as the destruction of the component which was in that frame. The moment the event is broadcast the component is still attached to the frame, but in the next moment it will not be.. COMPONENT_REATTACHED: a component has been attached to a new model. In this case, the component remains the same, but operates on a new model component. FRAME_ACTIVATED: a component has been activated. Activations are broadcast from the top component which was not active, down to the innermost component. FRAME_DEACTIVATING: broadcast immediately before the component is deactivated. Deactivations are broadcast from the innermost component which does not stay active up to the outermost component which does not stay active. CONTEXT_CHANGED: a component has changed its internal context, for example, the selection. If the activation status within a frame changes, this is a context change, also. FRAME_UI_ACTIVATED: broadcast by an active frame when it is getting UI control (tool control). FRAME_UI_DEACTIVATING: broadcast by an active frame when it is losing UI control (tool control). | |
|
|
At this time, the XFrame methods used to build a frame-controller-model relationship can only be fully utilized by frame loader implementations or customized trivial components. Outside a frame loader you can create a frame, but the current implementations cannot create a standalone controller that could be used with setComponent(). Therefore, you can not remove components from one frame and add them to another or create additional controllers for a loaded model using the component framework. This is due to restrictions of the VCL and the C++ implementation of the current document components. Currently, the only way for clients to construct a frame and insert a OpenOffice.org document into it, is to use the com.sun.star.frame.XComponentLoader interface of the com.sun.star.frame.Desktop or the interfaces com.sun.star.frame.XSynchronousFrameLoader, the preferred frame loader interface, and the asynchronous com.sun.star.frame.XFrameLoader of the com.sun.star.frame.FrameLoader service that is available at the global service factory. The recommended method to get additional controllers for loaded models is to use the OpenNewView property with loadComponentFromURL() at the com.sun.star.frame.XComponentLoader interface of the desktop. There is also another possibility: dispatch a “.uno:NewWindow” command to a frame that contains that model. |
The Frame interface com.sun.star.frame.XFramesSupplier offers methods to access sub-frames of a frame. The frame implementation of OpenOffice.org supports this interface. This interface inherits from com.sun.star.frame.XFrame, and introduces the following methods:
com::sun::star::frame::XFrames getFrames ()
com::sun::star::frame::XFrame getActiveFrame ()
void setActiveFrame ( [in] com::sun::star::frame::XFrame xFrame)
The method getFrames() returns a com.sun.star.frame.XFrames container, that is a com.sun.star.container.XIndexAccess with additional methods to add and remove frames:
void append ( [in] com::sun::star::frame::XFrame xFrame )
sequence < com::sun::star::frame::XFrame > queryFrames ( [in] long nSearchFlags )
void remove ( [in] com::sun::star::frame::XFrame xFrame );
This XFrames collection is used when frames are appended to a frame to become sub-frames. The append() method implementation must extend the existing frame hierarchy by an internal call to setCreator() at the parent frame in the frame hierarchy. The parent frame is always the frame whose XFramesSupplier interface is used to append a new frame.
Through getActiveFrame() access the active sub-frame in a frame with subframes. If there are no sub-frames or a sub-frame is currently non active, the active frame is null. The setActiveFrame() is called by a sub-frame to inform the frame about the activation of the sub-frame. In setActiveFrame(), the method setActiveFrame() at the creator is called, then the registered frame action listeners are notified by an appropriate call to frameAction() with com.sun.star.frame.FrameActionEvent:Action set to FRAME_UI_ACTIVATED.
Frame services also support com.sun.star.frame.XDispatchProvider and com.sun.star.frame.XDispatchProviderInterception. The section 7.1.6 Office Development - OpenOffice.org Application Environment - Using the Dispatch Framework explains how these interfaces are used.
The frame implementation supplies a status indicator through its interface com.sun.star.task.XStatusIndicatorFactory. A status indicator can be used by a frame loader to show the loading process for a document. The factory has only one method that returns an object supporting com.sun.star.task.XStatusIndicator:
com::sun::star::task::XStatusIndicator createStatusIndicator ()
The status indicator is displayed by a call to com.sun.star.task.XStatusIndicator:start(). Pass a text and a numeric range, and use setValue() to let the status bar grow until the maximum range is reached. The method end() removes the status indicator.
Illustration 7.10: Controller Service |
A com.sun.star.frame.XController inherits from com.sun.star.lang.XComponent and introduces the following methods:
com::sun::star::frame::XFrame getFrame ()
void attachFrame (com::sun::star::frame::XFrame xFrame)
com::sun::star::frame::XModel getModel ()
boolean attachModel (com::sun::star::frame::XModel xModel)
boolean suspend (boolean bSuspend)
any getViewData ()
void restoreViewData (any Data)
The com.sun.star.frame.XController links model and frame through the methods get/attachModel() and get/attachFrame(). These methods and the corresponding methods in the com.sun.star.frame.XModel and com.sun.star.frame.XFrame interfaces act together. calling attachModel() at the controller must be accompanied by a corresponding call of connectController() at the model, and attachFrame() at the controller must have its counterpart setComponent() at the frame.
The controller is asked for permission to dispose of the entire associated component by using suspend(). The suspend() method shows dialogs, for example, to save changes. To avoid the dialog, close the corresponding frame without using suspend() before. The section 7.1.5 Office Development - OpenOffice.org Application Environment - Handling Documents - Closing Documents provides additional information.
Developers retrieve and restore data used to setup the view at the controller by calling get/restoreViewData(). These methods are usually called on loading and saving the document, but they also allow developers to manipulate the state of a view from the outside. The exact content of this data depends on the concrete controller/model pair.
Through com.sun.star.frame.XDispatchProvider, the controller participates in the dispatch framework. It is described in section 7.1.6 Office Development - OpenOffice.org Application Environment - Using the Dispatch Framework.
The optional Controller interface com.sun.star.view.XSelectionSupplier accesses the selected object and informs listeners when the selection changes:
boolean select ( [in] any aSelection)
any getSelection ()
void addSelectionChangeListener ( [in] com::sun::star::view::XSelectionChangeListener xListener)
void removeSelectionChangeListener ( [in] com::sun::star::view::XSelectionChangeListener xListener)
The type of selection depends on the type of the document and the selected object. It is also possible to get the current selection in the active or last controller of a model by calling the method getCurrentSelection() in the com.sun.star.frame.XModel interface.
The optional Controller interface com.sun.star.ui.XContextMenuInterception intercepts requests for context menus in the document's window. See chapter 4.7.5 Writing UNO Components - Integrating Components into OpenOffice.org - Intercepting Context Menus.
The com.sun.star.frame.Controller specification is generic and does not describe additional features required for a fully functional document controller specification, such as the controller specifications for Writer, Calc and Draw documents. The following table shows the controller services specified for OpenOffice.org document components.
Once the reference to a controller is retrieved, you can query for these interfaces. Use the com.sun.star.lang.XServiceInfo interface of the model to ask it for the supported service(s). The component implementations in OpenOffice.org support the following services. Refer to the related chapters for additional information about the interfaces you get from the controllers of OpenOffice.org documents.
|
Component and Chapter |
Specialized Controller Service |
General Description |
|
The text view supplies a text view cursor that has knowledge about the current page layout and page number. It can walk through document pages, screen pages and lines. The selected ruby text is also available, a special Asian text formatting, comparable to superscript. | ||
|
Calc 9.5 Spreadsheet Documents - Controlling Spreadsheet Documents |
The spreadsheet view is extremely powerful. It includes the services com.sun.star.sheet.SpreadsheetViewPane and com.sun.star.sheet.SpreadsheetViewSettings. The view pane handles the currently visible cell range and provides controllers for form controls in the spreadsheet. The view settings deal with the visibility of spreadsheet elements, such as the grid and current zoom mode. Furthermore, the spreadsheet view provides access to the active sheet in the view and the collection of all view panes, allowing to split and freeze the view, and control the interactive selection of a cell range. | |
|
Draw 10.7 Drawing - Drawing and Presentation Document Controller |
The drawing document view toggles master page mode and layer mode, controls the current page and supplies the currently visible rectangle. | |
|
Impress 10.7 Drawing - Drawing and Presentation Document Controller |
The presentation view does not introduce presentation specific features. Running presentations are controlled by the com.sun.star.presentation.XPresentationSupplier interface of the presentation document model. | |
|
DataBaseAccess |
This controller has no published functionality that would be useful for developers. | |
|
Bibliography |
(no special controller specified) |
- |
|
Writer (PagePreview) |
(no special controller specified) |
- |
|
Writer/Webdocument (SourceView) |
(no special controller specified) |
- |
|
Calc (PagePreview) |
(no special controller specified) |
- |
|
(no special controller specified) |
- | |
|
Math |
(no special controller specified) |
- |
There is not an independent specification for a model service. The interface com.sun.star.frame.XModel is currently supported by Writer, Calc, Draw and Impress document components. In our context, we call objects supporting com.sun.star.frame.XModel, model objects. All OpenOffice.org document components have the service com.sun.star.document.OfficeDocument in common. An OfficeDocument implements the following interfaces:
The interface com.sun.star.frame.XModel inherits from com.sun.star.lang.XComponent and introduces the following methods, which handle the model's resource description, manage its controllers and retrieves the current selection.
string getURL ()
sequence < com::sun::star::beans::PropertyValue > getArgs ()
boolean attachResource ( [in] string aURL,
[in] sequence < com::sun::star::beans::PropertyValue aArgs > )
com::sun::star::frame::XController getCurrentController ()
void setCurrentController (com::sun::star::frame::XController xController)
void connectController (com::sun::star::frame::XController xController)
void disconnectController (com::sun::star::frame::XController xController)
void lockControllers ()
void unlockControllers ()
boolean hasControllersLocked ()
com::sun::star::uno::XInterface getCurrentSelection ()
The method getURL() provides the URL where a document was loaded from or last stored using storeAsURL(). As long as a new document has not been saved, the URL is an empty string. The method getArgs() returns a sequence of property values that report the resource description according to com.sun.star.document.MediaDescriptor, specified on loading or saving with storeAsURL. The method attachResource() is used by the frame loader implementations to inform the model about its URL and MediaDescriptor.
The current or last active controller for a model isretrieved through getCurrentController(). The corresponding method setCurrentController() sets a different current controller at models where additional controllers are available. However, additional controllers can not be created at this time for OpenOffice.org components using the component API. The method connectController() is used by frame loader implementations and provides the model with a new controller that has been created for it, without making it the current controller. The disconnectController() tells the model that a controller may no longer be used. Finally, the model holds back screen updates using lockControllers() and unlockControllers(). For each call to lockControllers(), there must be a call to unlockControllers() to remove the lock. The method hasControllersLocked() tells if the controllers are locked.
The currently selected object is retrieved by a call to getCurrentSelection(). This method is an alternative to getSelection() at the com.sun.star.view.XSelectionSupplier interface supported by controller services.
The interface com.sun.star.util.XModifiable traces the modified status of a document:
void addModifyListener ( [in] com::sun::star::util::XModifyListener aListener)
void removeModifyListener ( [in] com::sun::star::util::XModifyListener aListener)
boolean isModified ()
void setModified ( [in] boolean bModified)
The interface com.sun.star.frame.XStorable stores a document under an arbitrary URL or its current location. Details about how to use this interface are discussed in the chapter 7.1.5 Office Development - OpenOffice.org Application Environment - Handling Documents
The interface com.sun.star.view.XPrintable is used to set and get the printer and its settings, and dispatch print jobs. These methods and special printing features for the various document types are described in the chapters 8.2.3 Text Documents - Handling Text Document Files - Printing Text Documents, 9.2.3 Spreadsheet Documents - Handling Spreadsheet Document Files - Printing Spreadsheet Documents, 10.2.3 Drawing - Handling Drawing Document Files - Printing Drawing Documents and 10.4.2 Drawing - Handling Presentation Document Files - Printing Presentation Documents.
sequence< com::sun::star::beans::PropertyValue > getPrinter ()
void setPrinter ( [in] sequence< com::sun::star::beans::PropertyValue > aPrinter )
void print ( [in] sequence< com::sun::star::beans::PropertyValue > xOptions )
For versions later than 641, the optional interface com.sun.star.document.XEventBroadcaster at office documents enables developers to add listeners for events related to office documents in general, or for events specific for the individual document type.See 7.2.8 Office Development - Common Application Features - Document Events).
void addEventListener ( [in] com::sun::star::document::XEventListener xListener)
void removeEventListener ( [in] com::sun::star::document::XEventListener xListener)
The XEventListener must implement a single method, besides disposing():
[oneway] void notifyEvent ( [in] com::sun::star::document::EventObject Event )
The struct com.sun.star.document.EventObject has a string member EventName, that assumes one of the values specified in com.sun.star.document.Events. These events are also on the Events tab of the Tools – Configure dialog.
The general events are the same events as those provided at the XEventBroadcaster interface of the desktop. While the model is only concerned about its own events, the desktop broadcasts the events for all the loaded documents.
The optional interface com.sun.star.document.XEventsSupplier binds the execution of dispatch URLs to document events, thus providing a configurable event listener as a simplification for the more general event broadcaster or listener mechanism of the com.sun.star.document.XEventBroadcaster interface. This is done programmatically versus manually in Tools – Configure – Events.
The optional interface com.sun.star.document.XDocumentInfoSupplier provides access to document information as described in section 7.2.7 Office Development - Common Application Features - Document Info.Document information is presented in the File – Properties dialog in the GUI.
The optional com.sun.star.document.XViewDataSupplier interface sets and restores view data.
com::sun::star::container::XIndexAccess getViewData ()
void setViewData ( [in] com::sun::star::container::XIndexAccess aData)
The view data are a com.sun.star.container.XIndexAccess to sequences of com.sun.star.beans.PropertyValue structs. Each sequence represents the settings of a view to the model that supplies the view data.
Every service specification for real model objects provides more interfaces that constitute the actual model functionality For example, a text document service com.sun.star.text.TextDocument provides text related interfaces. Having received a reference to a model, developers query for these interfaces. The com.sun.star.lang.XServiceInfo interface of a model can be used to ask for supported services. The OpenOffice.org document types support the following services:
|
Document |
Service |
Chapter |
|
Calc | ||
|
Draw |