Package org.eclipse.ui.application

Source Code of org.eclipse.ui.application.WorkbenchAdvisor

/*******************************************************************************
* Copyright (c) 2003, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*******************************************************************************/

package org.eclipse.ui.application;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.internal.StartupThreading;
import org.eclipse.ui.internal.UISynchronizer;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.WorkbenchWindowConfigurer;
import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
import org.eclipse.ui.internal.application.CompatibilityWorkbenchWindowAdvisor;
import org.eclipse.ui.internal.util.PrefUtil;
import org.eclipse.ui.statushandlers.AbstractStatusHandler;
import org.eclipse.ui.statushandlers.StatusManager;
import org.eclipse.ui.statushandlers.WorkbenchErrorHandler;

/**
* Public base class for configuring the workbench.
* <p>
* Note that the workbench advisor object is created in advance of creating the
* workbench. However, by the time the workbench starts calling methods on this
* class, <code>PlatformUI.getWorkbench</code> is guaranteed to have been
* properly initialized.
* </p>
* <p>
* Example of creating and running a workbench (in an
* <code>IPlatformRunnable</code>):
*
* <pre>
* <code>
*           public class MyApplication implements IPlatformRunnable {
*             public Object run(Object args) {
*               WorkbenchAdvisor workbenchAdvisor = new MyWorkbenchAdvisor();
*               Display display = PlatformUI.createDisplay();
*               int returnCode = PlatformUI.createAndRunWorkbench(display, workbenchAdvisor);
*               if (returnCode == PlatformUI.RETURN_RESTART) {
*                  return IPlatformRunnable.EXIT_RESTART;
*               } else {
*                  return IPlatformRunnable.EXIT_OK;
*             }
*           }
* </code>
* </pre>
*
* </p>
* <p>
* An application should declare a subclass of <code>WorkbenchAdvisor</code>
* and override methods to configure the workbench to suit the needs of the
* particular application.
* </p>
* <p>
* The following advisor methods are called at strategic points in the
* workbench's lifecycle (all occur within the dynamic scope of the call to
* {@link PlatformUI#createAndRunWorkbench PlatformUI.createAndRunWorkbench}):
* <ul>
* <li><code>initialize</code> - called first; before any windows; use to
* register things</li>
* <li><code>preStartup</code> - called second; after initialize but before
* first window is opened; use to temporarily disable things during startup or
* restore</li>
* <li><code>postStartup</code> - called third; after first window is opened;
* use to reenable things temporarily disabled in previous step</li>
* <li><code>postRestore</code> - called after the workbench and its windows
* has been recreated from a previously saved state; use to adjust the restored
* workbench</li>
* <li><code>preWindowOpen</code> - called as each window is being opened;
* use to configure aspects of the window other than actions bars </li>
* <li><code>fillActionBars</code> - called after <code>preWindowOpen</code>
* to configure a window's action bars</li>
* <li><code>postWindowRestore</code> - called after a window has been
* recreated from a previously saved state; use to adjust the restored window</li>
* <li><code>postWindowCreate</code> - called after a window has been
* created, either from an initial state or from a restored state; used to
* adjust the window</li>
* <li><code>openIntro</code> - called immediately before a window is opened
* in order to create the introduction component, if any.</li>
* <li><code>postWindowOpen</code> - called after a window has been opened;
* use to hook window listeners, etc.</li>
* <li><code>preWindowShellClose</code> - called when a window's shell is
* closed by the user; use to pre-screen window closings</li>
* <li><code>eventLoopException</code> - called to handle the case where the
* event loop has crashed; use to inform the user that things are not well</li>
* <li><code>eventLoopIdle</code> - called when there are currently no more
* events to be processed; use to perform other work or to yield until new
* events enter the queue</li>
* <li><code>preShutdown</code> - called immediately prior to workbench
* shutdown before any windows have been closed; allows the advisor to veto the
* shutdown</li>
* <li><code>postShutdown</code> - called last; after event loop has
* terminated and all windows have been closed; use to deregister things
* registered during initialize</li>
* </ul>
* </p>
*
* @since 3.0
*/
public abstract class WorkbenchAdvisor {

  /**
   * Bit flag for {@link #fillActionBars fillActionBars} indicating that the
   * operation is not filling the action bars of an actual workbench window,
   * but rather a proxy (used for perspective customization).
   *
   * @deprecated use {@link ActionBarAdvisor#FILL_PROXY instead}
   */
  public static final int FILL_PROXY = ActionBarAdvisor.FILL_PROXY;

  /**
   * Bit flag for {@link #fillActionBars fillActionBars} indicating that the
   * operation is supposed to fill (or describe) the workbench window's menu
   * bar.
   *
   * @deprecated use {@link ActionBarAdvisor#FILL_MENU_BAR instead}
   */
  public static final int FILL_MENU_BAR = ActionBarAdvisor.FILL_MENU_BAR;

  /**
   * Bit flag for {@link #fillActionBars fillActionBars} indicating that the
   * operation is supposed to fill (or describe) the workbench window's cool
   * bar.
   *
   * @deprecated use {@link ActionBarAdvisor#FILL_COOL_BAR instead}
   */
  public static final int FILL_COOL_BAR = ActionBarAdvisor.FILL_COOL_BAR;

  /**
   * Bit flag for {@link #fillActionBars fillActionBars} indicating that the
   * operation is supposed to fill (or describe) the workbench window's status
   * line.
   *
   * @deprecated use {@link ActionBarAdvisor#FILL_STATUS_LINE instead}
   */
  public static final int FILL_STATUS_LINE = ActionBarAdvisor.FILL_STATUS_LINE;

  /**
   * The workbench configurer.
   */
  private IWorkbenchConfigurer workbenchConfigurer;

  /**
   * The workbench error handler.
   */
  private AbstractStatusHandler workbenchErrorHandler;

  private boolean introOpened;

  /**
   * Creates and initializes a new workbench advisor instance.
   */
  protected WorkbenchAdvisor() {
    // do nothing
  }

  /**
   * Remembers the configurer and calls <code>initialize</code>.
   * <p>
   * For internal use by the workbench only.
   * </p>
   *
   * @param configurer
   *            an object for configuring the workbench
   */
  public final void internalBasicInitialize(IWorkbenchConfigurer configurer) {
    if (workbenchConfigurer != null) {
      throw new IllegalStateException();
    }
    this.workbenchConfigurer = configurer;
    initialize(configurer);
  }

  /**
   * Performs arbitrary initialization before the workbench starts running.
   * <p>
   * This method is called during workbench initialization prior to any
   * windows being opened. Clients must not call this method directly
   * (although super calls are okay). The default implementation does nothing.
   * Subclasses may override. Typical clients will use the configurer passed
   * in to tweak the workbench. If further tweaking is required in the future,
   * the configurer may be obtained using <code>getWorkbenchConfigurer</code>.
   * </p>
   *
   * @param configurer
   *            an object for configuring the workbench
   */
  public void initialize(IWorkbenchConfigurer configurer) {
    // do nothing
  }

  /**
   * Returns the workbench configurer for the advisor. Can be
   * <code>null</code> if the advisor is not initialized yet.
   *
   * @return the workbench configurer, or <code>null</code> if the advisor
   *         is not initialized yet
   */
  protected IWorkbenchConfigurer getWorkbenchConfigurer() {
    return workbenchConfigurer;
  }

  /**
   * Returns the workbench error handler for the advisor.
   *
   * @return the workbench error handler
   * @since 3.3
   */
  public AbstractStatusHandler getWorkbenchErrorHandler() {
    if (workbenchErrorHandler == null) {
      workbenchErrorHandler = new WorkbenchErrorHandler();
    }
    return workbenchErrorHandler;
  }

  /**
   * Performs arbitrary actions just before the first workbench window is
   * opened (or restored).
   * <p>
   * This method is called after the workbench has been initialized and just
   * before the first window is about to be opened. Clients must not call this
   * method directly (although super calls are okay). The default
   * implementation does nothing. Subclasses may override.
   * </p>
   */
  public void preStartup() {
    // do nothing
  }

  /**
   * Performs arbitrary actions after the workbench windows have been opened
   * (or restored), but before the main event loop is run.
   * <p>
   * This method is called just after the windows have been opened. Clients
   * must not call this method directly (although super calls are okay). The
   * default implementation does nothing. Subclasses may override. It is okay
   * to call <code>IWorkbench.close()</code> from this method.
   * </p>
   */
  public void postStartup() {
    // do nothing
  }

  /**
   * Performs arbitrary finalization before the workbench is about to shut
   * down.
   * <p>
   * This method is called immediately prior to workbench shutdown before any
   * windows have been closed. Clients must not call this method directly
   * (although super calls are okay). The default implementation returns
   * <code>true</code>. Subclasses may override.
   * </p>
   * <p>
   * The advisor may veto a regular shutdown by returning <code>false</code>,
   * although this will be ignored if the workbench is being forced to shut
   * down.
   * </p>
   *
   * @return <code>true</code> to allow the workbench to proceed with
   *         shutdown, <code>false</code> to veto a non-forced shutdown
   */
  public boolean preShutdown() {
    return true;
  }

  /**
   * Performs arbitrary finalization after the workbench stops running.
   * <p>
   * This method is called during workbench shutdown after all windows have
   * been closed. Clients must not call this method directly (although super
   * calls are okay). The default implementation does nothing. Subclasses may
   * override.
   * </p>
   */
  public void postShutdown() {
    // do nothing
  }

  /**
   * Performs arbitrary actions when the event loop crashes (the code that
   * handles a UI event throws an exception that is not caught).
   * <p>
   * This method is called when the code handling a UI event throws an
   * exception. In a perfectly functioning application, this method would
   * never be called. In practice, it comes into play when there are bugs in
   * the code that trigger unchecked runtime exceptions. It is also activated
   * when the system runs short of memory, etc. Fatal errors (ThreadDeath) are
   * not passed on to this method, as there is nothing that could be done.
   * </p>
   * <p>
   * Clients must not call this method directly (although super calls are
   * okay). The default implementation logs the problem so that it does not go
   * unnoticed. Subclasses may override or extend this method. It is generally
   * a bad idea to override with an empty method, and you should be especially
   * careful when handling Errors.
   * </p>
   *
   * @param exception
   *            the uncaught exception that was thrown inside the UI event
   *            loop
   */
  public void eventLoopException(Throwable exception) {
    // Protection from client doing super(null) call
    if (exception == null) {
      return;
    }

    try {
      StatusManager.getManager().handle(
          new Status(IStatus.ERROR, WorkbenchPlugin.PI_WORKBENCH,
              "Unhandled event loop exception", exception)); //$NON-NLS-1$

      if (WorkbenchPlugin.DEBUG) {
        exception.printStackTrace();
      }
    } catch (Throwable e) {
      // One of the log listeners probably failed. Core should have logged
      // the
      // exception since its the first listener.
      System.err.println("Error while logging event loop exception:"); //$NON-NLS-1$
      exception.printStackTrace();
      System.err.println("Logging exception:"); //$NON-NLS-1$
      e.printStackTrace();
    }
  }

  /**
   * Performs arbitrary work or yields when there are no events to be
   * processed.
   * <p>
   * This method is called when there are currently no more events on the
   * queue to be processed at the moment.
   * </p>
   * <p>
   * Clients must not call this method directly (although super calls are
   * okay). The default implementation yields until new events enter the
   * queue. Subclasses may override or extend this method. It is generally a
   * bad idea to override with an empty method. It is okay to call
   * <code>IWorkbench.close()</code> from this method.
   * </p>
   *
   * @param display
   *            the main display of the workbench UI
   */
  public void eventLoopIdle(Display display) {
    // default: yield cpu until new events enter the queue
    display.sleep();
  }

  /**
   * Creates a new workbench window advisor for configuring a new workbench
   * window via the given workbench window configurer. Clients should override
   * to provide their own window configurer. This method replaces all the
   * other window and action bar lifecycle methods on the workbench advisor.
   * <p>
   * The default implementation creates a window advisor that calls back to
   * the legacy window and action bar lifecycle methods on the workbench
   * advisor, for backwards compatibility with 3.0.
   * </p>
   *
   * @param configurer
   *            the workbench window configurer
   * @return a new workbench window advisor
   * @since 3.1
   */
  public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
      IWorkbenchWindowConfigurer configurer) {
    return new CompatibilityWorkbenchWindowAdvisor(this, configurer);
  }

  /**
   * Performs arbitrary actions before the given workbench window is opened.
   * <p>
   * This method is called before the window's controls have been created.
   * Clients must not call this method directly (although super calls are
   * okay). The default implementation does nothing. Subclasses may override.
   * Typical clients will use the configurer passed in to tweak the workbench
   * window in an application-specific way; however, filling the window's menu
   * bar, tool bar, and status line must be done in
   * {@link #fillActionBars fillActionBars}, which is called immediately
   * after this method is called.
   * </p>
   *
   * @param configurer
   *            an object for configuring the particular workbench window
   *            being opened
   *
   * @deprecated since 3.1, override
   *             {@link WorkbenchWindowAdvisor#preWindowOpen()} instead
   * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
   */
  public void preWindowOpen(IWorkbenchWindowConfigurer configurer) {
    // do nothing
  }

  /**
   * Configures the action bars using the given action bar configurer. Under
   * normal circumstances, <code>flags</code> does not include
   * <code>FILL_PROXY</code>, meaning this is a request to fill the
   * actions\ bars of the given workbench window; the remaining flags indicate
   * which combination of the menu bar (<code>FILL_MENU_BAR</code>), the
   * tool bar (<code>FILL_COOL_BAR</code>), and the status line (<code>FILL_STATUS_LINE</code>)
   * are to be filled.
   * <p>
   * If <code>flags</code> does include <code>FILL_PROXY</code>, then
   * this is a request to describe the actions bars of the given workbench
   * window (which will already have been filled); again, the remaining flags
   * indicate which combination of the menu bar, the tool bar, and the status
   * line are to be described. The actions included in the proxy action bars
   * can be the same instances as in the actual window's action bars. Calling
   * <code>ActionFactory</code> to create new action instances is not
   * recommended, because these actions internally register listeners with the
   * window and there is no opportunity to dispose of these actions.
   * </p>
   * <p>
   * This method is called just after {@link #preWindowOpen preWindowOpen}.
   * Clients must not call this method directly (although super calls are
   * okay). The default implementation does nothing. Subclasses may override.
   * </p>
   *
   * @param window
   *            the workbench window
   * @param configurer
   *            the action bar configurer object
   * @param flags
   *            bit mask composed from the constants
   *            {@link #FILL_MENU_BAR FILL_MENU_BAR},
   *            {@link #FILL_COOL_BAR FILL_COOL_BAR},
   *            {@link #FILL_STATUS_LINE FILL_STATUS_LINE}, and
   *            {@link #FILL_PROXY FILL_PROXY} Note: should 1st param be
   *            IWorkbenchWindowConfigurer to be more consistent with other
   *            methods? Note: suggest adding ActionBuilder as API, to
   *            encapsulate the action building outside of the advisor, and to
   *            handle the common pattern of hanging onto the action builder
   *            in order to properly handle FILL_PROXY
   *
   * @deprecated since 3.1, override
   *             {@link ActionBarAdvisor#fillActionBars(int)} instead
   * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
   * @see WorkbenchWindowAdvisor#createActionBarAdvisor(IActionBarConfigurer)
   */
  public void fillActionBars(IWorkbenchWindow window,
      IActionBarConfigurer configurer, int flags) {
    // do nothing by default
  }

  /**
   * Performs arbitrary actions after the given workbench window has been
   * restored, but before it is opened.
   * <p>
   * This method is called after a previously-saved window have been
   * recreated. This method is not called when a new window is created from
   * scratch. This method is never called when a workbench is started for the
   * very first time, or when workbench state is not saved or restored.
   * Clients must not call this method directly (although super calls are
   * okay). The default implementation does nothing. Subclasses may override.
   * It is okay to call <code>IWorkbench.close()</code> from this method.
   * </p>
   *
   * @param configurer
   *            an object for configuring the particular workbench window just
   *            restored
   *
   * @deprecated since 3.1, override
   *             {@link WorkbenchWindowAdvisor#postWindowRestore()} instead
   * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
   */
  public void postWindowRestore(IWorkbenchWindowConfigurer configurer)
      throws WorkbenchException {
    // do nothing
  }

  /**
   * Opens the introduction componenet.
   * <p>
   * Clients must not call this method directly (although super calls are
   * okay). The default implementation opens the intro in the first window
   * provided the preference IWorkbenchPreferences.SHOW_INTRO is
   * <code>true</code>. If an intro is shown then this preference will be
   * set to <code>false</code>. Subsequently, and intro will be shown only
   * if <code>WorkbenchConfigurer.getSaveAndRestore()</code> returns
   * <code>true</code> and the introduction was visible on last shutdown.
   * Subclasses may override.
   * </p>
   *
   * @param configurer
   *            configurer an object for configuring the particular workbench
   *            window just created
   *
   * @deprecated since 3.1, override
   *             {@link WorkbenchWindowAdvisor#openIntro()} instead
   * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
   */
  public void openIntro(IWorkbenchWindowConfigurer configurer) {
    if (introOpened) {
      return;
    }

    introOpened = true;

    boolean showIntro = PrefUtil.getAPIPreferenceStore().getBoolean(
        IWorkbenchPreferenceConstants.SHOW_INTRO);

    if (!showIntro) {
      return;
    }

    if (getWorkbenchConfigurer().getWorkbench().getIntroManager()
        .hasIntro()) {
      getWorkbenchConfigurer().getWorkbench().getIntroManager()
          .showIntro(configurer.getWindow(), false);

      PrefUtil.getAPIPreferenceStore().setValue(
          IWorkbenchPreferenceConstants.SHOW_INTRO, false);
      PrefUtil.saveAPIPrefs();
    }
  }

  /**
   * Performs arbitrary actions after the given workbench window has been
   * created (possibly after being restored), but has not yet been opened.
   * <p>
   * This method is called after a new window has been created from scratch,
   * or when a previously-saved window has been restored. In the latter case,
   * this method is called after <code>postWindowRestore</code>. Clients
   * must not call this method directly (although super calls are okay). The
   * default implementation does nothing. Subclasses may override.
   * </p>
   *
   * @param configurer
   *            an object for configuring the particular workbench window just
   *            created
   *
   * @deprecated since 3.1, override
   *             {@link WorkbenchWindowAdvisor#postWindowCreate()} instead
   * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
   */
  public void postWindowCreate(IWorkbenchWindowConfigurer configurer) {
    // do nothing
  }

  /**
   * Performs arbitrary actions after the given workbench window has been
   * opened (possibly after being restored).
   * <p>
   * This method is called after a window has been opened. This method is
   * called after a new window has been created from scratch, or when a
   * previously-saved window has been restored. Clients must not call this
   * method directly (although super calls are okay). The default
   * implementation does nothing. Subclasses may override.
   * </p>
   *
   * @param configurer
   *            an object for configuring the particular workbench window just
   *            opened
   *
   * @deprecated since 3.1, override
   *             {@link WorkbenchWindowAdvisor#postWindowOpen()} instead
   * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
   */
  public void postWindowOpen(IWorkbenchWindowConfigurer configurer) {
    // do nothing
  }

  /**
   * Performs arbitrary actions as the given workbench window's shell is being
   * closed directly, and possibly veto the close.
   * <p>
   * This method is called from a ShellListener associated with the workbench
   * window. It is not called when the window is being closed for other
   * reasons. Clients must not call this method directly (although super calls
   * are okay). The default implementation does nothing. Subclasses may
   * override. Typical clients may use the configurer passed in to access the
   * workbench window being closed. If this method returns <code>false</code>,
   * then the user's request to close the shell is ignored. This gives the
   * workbench advisor an opportunity to query the user and/or veto the
   * closing of a window under some circumstances.
   * </p>
   *
   * @param configurer
   *            an object for configuring the particular workbench window
   *            whose shell is being closed
   * @return <code>true</code> to allow the window to close, and
   *         <code>false</code> to prevent the window from closing
   * @see org.eclipse.ui.IWorkbenchWindow#close
   *
   * @deprecated since 3.1, override
   *             {@link WorkbenchWindowAdvisor#preWindowShellClose()} instead
   * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
   */
  public boolean preWindowShellClose(IWorkbenchWindowConfigurer configurer) {
    // do nothing, but allow the close() to proceed
    return true;
  }

  /**
   * Performs arbitrary actions after the given workbench window is closed.
   * <p>
   * This method is called after the window's controls have been disposed.
   * Clients must not call this method directly (although super calls are
   * okay). The default implementation does nothing. Subclasses may override.
   * Typical clients will use the configurer passed in to tweak the workbench
   * window in an application-specific way.
   * </p>
   *
   * @param configurer
   *            an object for configuring the particular workbench window
   *            being closed
   *
   * @deprecated since 3.1, override
   *             {@link WorkbenchWindowAdvisor#postWindowClose()} instead
   * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
   */
  public void postWindowClose(IWorkbenchWindowConfigurer configurer) {
    // do nothing
  }

  /**
   * Returns whether the menu with the given id is an application menu of the
   * given window. This is used during OLE "in place" editing. Application
   * menus should be preserved during menu merging. All other menus may be
   * removed from the window.
   * <p>
   * The default implementation returns false. Subclasses may override.
   * </p>
   *
   * @param configurer
   *            an object for configuring the workbench window
   * @param menuId
   *            the menu id
   * @return <code>true</code> for application menus, and <code>false</code>
   *         for part-specific menus
   *
   * @deprecated since 3.1, override
   *             {@link ActionBarAdvisor#isApplicationMenu(String)} instead
   * @see WorkbenchWindowAdvisor#createActionBarAdvisor(IActionBarConfigurer)
   */
  public boolean isApplicationMenu(IWorkbenchWindowConfigurer configurer,
      String menuId) {
    // default: not an application menu
    return false;
  }

  /**
   * Returns the default input for newly created workbench pages when the
   * input is not explicitly specified.
   * <p>
   * The default implementation returns <code>null</code>. Subclasses may
   * override.
   * </p>
   *
   * @return the default input for a new workbench window page, or
   *         <code>null</code> if none
   *
   * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
   */
  public IAdaptable getDefaultPageInput() {
    // default: no input
    return null;
  }

  /**
   * Returns the id of the perspective to use for the initial workbench
   * window, or <code>null</code> if no initial perspective should be shown
   * in the initial workbench window.
   * <p>
   * This method is called during startup when the workbench is creating the
   * first new window. Subclasses must implement.
   * </p>
   * <p>
   * If the {@link IWorkbenchPreferenceConstants#DEFAULT_PERSPECTIVE_ID}
   * preference is specified, it supercedes the perspective specified here.
   * </p>
   *
   * @return the id of the perspective for the initial window, or
   *         <code>null</code> if no initial perspective should be shown
   */
  public abstract String getInitialWindowPerspectiveId();

  /**
   * Returns the id of the preference page that should be presented most
   * prominently.
   * <p>
   * The default implementation returns <code>null</code>. Subclasses may
   * override.
   * </p>
   *
   * @return the id of the preference page, or <code>null</code> if none
   */
  public String getMainPreferencePageId() {
    // default: no opinion
    return null;
  }

  /**
   * Creates the contents of the window.
   * <p>
   * The default implementation adds a menu bar, a cool bar, a status line, a
   * perspective bar, and a fast view bar. The visibility of these controls
   * can be configured using the <code>setShow*</code> methods on
   * <code>IWorkbenchWindowConfigurer</code>.
   * </p>
   * <p>
   * Subclasses may override to define custom window contents and layout, but
   * must call <code>IWorkbenchWindowConfigurer.createPageComposite</code>.
   * </p>
   *
   * @param configurer
   *            the window configurer
   * @param shell
   *            the window's shell
   * @see IWorkbenchWindowConfigurer#createMenuBar
   * @see IWorkbenchWindowConfigurer#createCoolBarControl
   * @see IWorkbenchWindowConfigurer#createStatusLineControl
   * @see IWorkbenchWindowConfigurer#createPageComposite
   *
   * @deprecated since 3.1, override
   *             {@link WorkbenchWindowAdvisor#createWindowContents(Shell)}
   *             instead
   * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
   */
  public void createWindowContents(IWorkbenchWindowConfigurer configurer,
      Shell shell) {
    ((WorkbenchWindowConfigurer) configurer).createDefaultContents(shell);
  }

  /**
   * Opens the workbench windows on startup. The default implementation tries
   * to restore the previously saved workbench state using
   * <code>IWorkbenchConfigurer.restoreWorkbenchState()</code>. If there
   * was no previously saved state, or if the restore failed, then a
   * first-time window is opened using
   * <code>IWorkbenchConfigurer.openFirstTimeWindow</code>.
   *
   * @return <code>true</code> to proceed with workbench startup, or
   *         <code>false</code> to exit
   */
  public boolean openWindows() {
    final Display display = PlatformUI.getWorkbench().getDisplay();
    final boolean result [] = new boolean[1];
   
    // spawn another init thread.  For API compatibility We guarantee this method is called from
    // the UI thread but it could take enough time to disrupt progress reporting.
    // spawn a new thread to do the grunt work of this initialization and spin the event loop
    // ourselves just like it's done in Workbench.
    final boolean[] initDone = new boolean[]{false};
    final Throwable [] error = new Throwable[1];
    Thread initThread = new Thread() {
      /* (non-Javadoc)
       * @see java.lang.Thread#run()
       */
      public void run() {
        try {
          //declare us to be a startup thread so that our syncs will be executed
          UISynchronizer.startupThread.set(Boolean.TRUE);
          final IWorkbenchConfigurer [] myConfigurer = new IWorkbenchConfigurer[1];
          StartupThreading.runWithoutExceptions(new StartupRunnable() {
 
            public void runWithException() throws Throwable {
              myConfigurer[0] = getWorkbenchConfigurer();
             
            }});
         
          IStatus status = myConfigurer[0].restoreState();
          if (!status.isOK()) {
            if (status.getCode() == IWorkbenchConfigurer.RESTORE_CODE_EXIT) {
              result[0] = false;
              return;
            }
            if (status.getCode() == IWorkbenchConfigurer.RESTORE_CODE_RESET) {
              myConfigurer[0].openFirstTimeWindow();
            }
          }
          result[0] = true;
        } catch (Throwable e) {
          error[0] = e;
        }
        finally {
          initDone[0] = true;
          display.wake();
        }
      }};
      initThread.start();

      while (true) {
        if (!display.readAndDispatch()) {
          if (initDone[0])
            break;
          display.sleep();
        }
       
      }
     
      // can only be a runtime or error
      if (error[0] instanceof Error)
        throw (Error)error[0];
      else if (error[0] instanceof RuntimeException)
        throw (RuntimeException)error[0];
   
      return result[0];
  }

  /**
   * Saves arbitrary application-specific state information for this workbench
   * advisor.
   * <p>
   * The default implementation simply returns an OK status. Subclasses may
   * extend or override.
   * </p>
   *
   * @param memento
   *            the memento in which to save the advisor's state
   * @return a status object indicating whether the save was successful
   * @since 3.1
   */
  public IStatus saveState(IMemento memento) {
    return Status.OK_STATUS;
  }

  /**
   * Restores arbitrary application-specific state information for this
   * workbench advisor.
   * <p>
   * The default implementation simply returns an OK status. Subclasses may
   * extend or override.
   * </p>
   *
   * @param memento
   *            the memento from which to restore the advisor's state
   * @return a status object indicating whether the restore was successful
   * @since 3.1
   */
  public IStatus restoreState(IMemento memento) {
    return Status.OK_STATUS;
  }
}
TOP

Related Classes of org.eclipse.ui.application.WorkbenchAdvisor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.