Using the Desktop

From Apache OpenOffice Wiki
Jump to: navigation, search



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:

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.

Tip.png If a specific document component is required, but you 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()) {
              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 ? "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 ? "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 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 is selected.

The desktop broadcasts these events for all loaded documents.

The current version of Apache OpenOffice does not have a GUI element as a desktop. The redesign of the Apache OpenOffice 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 Apache OpenOffice 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 Apache OpenOffice. The desktop has to be a frame because its com.sun.star.frame.XFramesSupplier interface must be passed to 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 Apache OpenOffice 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 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 Apache OpenOffice (OpenOffice.org_3.x_Commands). Through the com.sun.star.frame.XDispatchProviderInterception, client code intercepts the command dispatches at the desktop. The dispatching process is described in section Using the Dispatch Framework.

Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages