The dispatch framework described in the last chapter establishes a communication between a user interface and an office component. Both can be Apache OpenOffice default components or custom components. Sometimes it is not necessary to replace a UI element by a new implementation. It can be sufficient to influence its visualized state or to redirect user interactions to external code. This is the typical use for dispatch interception.
The dispatch communication works in two directions: status information is transferred from the office component to the UI elements and user requests travel from the UI element to the office component. Both go through the same switching center, that is, an object implementing com.sun.star.frame.XDispatch. The UI element gets this object by calling
queryDispatch() at the frame containing the office component, and usually receives an object that connects to code inside the frame, the office component or global services in Apache OpenOffice. The frame offers an interface that is used to return third-party dispatch objects that provide the UI element with status updates. For example, it is possible to disable a UI element that would not be disabled otherwise. Another possibility is to write replacement code that is called by the UI element if the user performs a suitable action.
Dispatch objects are provided by objects implementing the com.sun.star.frame.XDispatchProvider interface, and that is the interface you are required to implement. There is an extra step where the dispatch provider must be attached to the frame to intercept the dispatching communication, therefore the dispatch provider becomes a part of the chain of responsibility described in the previous section. This is accomplished by implementing com.sun.star.frame.XDispatchProviderInterceptor.
This chain usually only consists of the frame and the controller of the office component it contains, but the frame offers the com.sun.star.frame.XDispatchProviderInterception interface where other providers are inserted. They are called before the frame tries to find a dispatch object for a command URL, so that it is possible to put the complete dispatch communication in a frame under external control. More than one interceptor can be registered, thus building a bigger chain.
Routing every dispatch through the whole chain becomes a performance problem, because there could be scores of possible clients asking for a dispatch object. For this reason, there is also an API that limits the routing procedure to particular commands or command groups. This is described below.
Once the connection is established, the dispatch interceptor decides how requests for a dispatch object are dealt with. When asked for a dispatch object for a Command URL, it can:
- Return an empty interface that disables the corresponding functionality. There's a bug in Ooo1.0/SO6.0 that this does not work, so disabling must be done explicitly (see below). It will be fixed in Ooo1.02/SO6.02.
- Pass the request to the next chain member, called slave dispatch provider described below if it is not interested in that functionality.
- Handle the request and return an object implementing com.sun.star.frame.XDispatch. As described in the previous chapter, client objects may register at this object as status event listeners. The dispatch object returns any possible status information as long as the type of the "State" member in the com.sun.star.frame.FeatureStateEvent struct has one of the expected types, otherwise the client requesting the status information can not handle it properly. The expected types must be documented together with the existing commands.For example, if a menu entry wants status information, it handles a
void, meaning nothing special should be done, or a
booleanstate by displaying a check mark, but nothing else. The status information could contain a
disabledirective. Note that a dispatch object returns status information immediately when a listener registers. Any change events can be broadcast at arbitrary points in time.
- The returned dispatch object is also used by client objects to dispatch the command that matches the command URL. The dispatch object receiving this request checks if the code it wants to execute is valid under the current conditions. It is not sufficient to rely on disable requests, because a client is not forced to register as a status listener if it wants to dispatch a request.
The slave dispatch provider and master dispatch provider in the com.sun.star.frame.XDispatchProviderInterceptor interface are a bit obscure at first. They are two pointers to chain members in both directions, next and previous, where the first and last member in the chain have special meanings and responsibilities.
The command dispatching passes through a chain of dispatch providers, starting at the frame. If the frame is answered to include an interceptor in this chain, the frame inserts the interceptor in the chain and passes the following chain member to the new chain member, so that calls are passed along the chain if it does not want to handle them.
If any interceptor is deregistered, the frame puts the loose ends together by adjusting the master and slave pointer of the chain successor and predecessor of the element that is going to be removed from the chain. All of them are interceptors, so only the last slave is a dispatch provider.
The frame takes care of the whole chain in the register or deregister of calls in the dispatch provider interceptor, so that the implementer of an interceptor does not have to be concerned with the chain construction.
|Content on this page is licensed under the Public Documentation License (PDL).|