001: /*******************************************************************************
002: * Copyright (c) 2003, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.application;
011:
012: import org.eclipse.core.runtime.IAdaptable;
013: import org.eclipse.core.runtime.IStatus;
014: import org.eclipse.core.runtime.Status;
015: import org.eclipse.swt.widgets.Display;
016: import org.eclipse.swt.widgets.Shell;
017: import org.eclipse.ui.IMemento;
018: import org.eclipse.ui.IWorkbenchPreferenceConstants;
019: import org.eclipse.ui.IWorkbenchWindow;
020: import org.eclipse.ui.PlatformUI;
021: import org.eclipse.ui.WorkbenchException;
022: import org.eclipse.ui.internal.StartupThreading;
023: import org.eclipse.ui.internal.UISynchronizer;
024: import org.eclipse.ui.internal.WorkbenchPlugin;
025: import org.eclipse.ui.internal.WorkbenchWindowConfigurer;
026: import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
027: import org.eclipse.ui.internal.application.CompatibilityWorkbenchWindowAdvisor;
028: import org.eclipse.ui.internal.util.PrefUtil;
029: import org.eclipse.ui.statushandlers.AbstractStatusHandler;
030: import org.eclipse.ui.statushandlers.StatusManager;
031: import org.eclipse.ui.statushandlers.WorkbenchErrorHandler;
032:
033: /**
034: * Public base class for configuring the workbench.
035: * <p>
036: * Note that the workbench advisor object is created in advance of creating the
037: * workbench. However, by the time the workbench starts calling methods on this
038: * class, <code>PlatformUI.getWorkbench</code> is guaranteed to have been
039: * properly initialized.
040: * </p>
041: * <p>
042: * Example of creating and running a workbench (in an
043: * <code>IPlatformRunnable</code>):
044: *
045: * <pre>
046: * <code>
047: * public class MyApplication implements IPlatformRunnable {
048: * public Object run(Object args) {
049: * WorkbenchAdvisor workbenchAdvisor = new MyWorkbenchAdvisor();
050: * Display display = PlatformUI.createDisplay();
051: * int returnCode = PlatformUI.createAndRunWorkbench(display, workbenchAdvisor);
052: * if (returnCode == PlatformUI.RETURN_RESTART) {
053: * return IPlatformRunnable.EXIT_RESTART;
054: * } else {
055: * return IPlatformRunnable.EXIT_OK;
056: * }
057: * }
058: * </code>
059: * </pre>
060: *
061: * </p>
062: * <p>
063: * An application should declare a subclass of <code>WorkbenchAdvisor</code>
064: * and override methods to configure the workbench to suit the needs of the
065: * particular application.
066: * </p>
067: * <p>
068: * The following advisor methods are called at strategic points in the
069: * workbench's lifecycle (all occur within the dynamic scope of the call to
070: * {@link PlatformUI#createAndRunWorkbench PlatformUI.createAndRunWorkbench}):
071: * <ul>
072: * <li><code>initialize</code> - called first; before any windows; use to
073: * register things</li>
074: * <li><code>preStartup</code> - called second; after initialize but before
075: * first window is opened; use to temporarily disable things during startup or
076: * restore</li>
077: * <li><code>postStartup</code> - called third; after first window is opened;
078: * use to reenable things temporarily disabled in previous step</li>
079: * <li><code>postRestore</code> - called after the workbench and its windows
080: * has been recreated from a previously saved state; use to adjust the restored
081: * workbench</li>
082: * <li><code>preWindowOpen</code> - called as each window is being opened;
083: * use to configure aspects of the window other than actions bars </li>
084: * <li><code>fillActionBars</code> - called after <code>preWindowOpen</code>
085: * to configure a window's action bars</li>
086: * <li><code>postWindowRestore</code> - called after a window has been
087: * recreated from a previously saved state; use to adjust the restored window</li>
088: * <li><code>postWindowCreate</code> - called after a window has been
089: * created, either from an initial state or from a restored state; used to
090: * adjust the window</li>
091: * <li><code>openIntro</code> - called immediately before a window is opened
092: * in order to create the introduction component, if any.</li>
093: * <li><code>postWindowOpen</code> - called after a window has been opened;
094: * use to hook window listeners, etc.</li>
095: * <li><code>preWindowShellClose</code> - called when a window's shell is
096: * closed by the user; use to pre-screen window closings</li>
097: * <li><code>eventLoopException</code> - called to handle the case where the
098: * event loop has crashed; use to inform the user that things are not well</li>
099: * <li><code>eventLoopIdle</code> - called when there are currently no more
100: * events to be processed; use to perform other work or to yield until new
101: * events enter the queue</li>
102: * <li><code>preShutdown</code> - called immediately prior to workbench
103: * shutdown before any windows have been closed; allows the advisor to veto the
104: * shutdown</li>
105: * <li><code>postShutdown</code> - called last; after event loop has
106: * terminated and all windows have been closed; use to deregister things
107: * registered during initialize</li>
108: * </ul>
109: * </p>
110: *
111: * @since 3.0
112: */
113: public abstract class WorkbenchAdvisor {
114:
115: /**
116: * Bit flag for {@link #fillActionBars fillActionBars} indicating that the
117: * operation is not filling the action bars of an actual workbench window,
118: * but rather a proxy (used for perspective customization).
119: *
120: * @deprecated use {@link ActionBarAdvisor#FILL_PROXY instead}
121: */
122: public static final int FILL_PROXY = ActionBarAdvisor.FILL_PROXY;
123:
124: /**
125: * Bit flag for {@link #fillActionBars fillActionBars} indicating that the
126: * operation is supposed to fill (or describe) the workbench window's menu
127: * bar.
128: *
129: * @deprecated use {@link ActionBarAdvisor#FILL_MENU_BAR instead}
130: */
131: public static final int FILL_MENU_BAR = ActionBarAdvisor.FILL_MENU_BAR;
132:
133: /**
134: * Bit flag for {@link #fillActionBars fillActionBars} indicating that the
135: * operation is supposed to fill (or describe) the workbench window's cool
136: * bar.
137: *
138: * @deprecated use {@link ActionBarAdvisor#FILL_COOL_BAR instead}
139: */
140: public static final int FILL_COOL_BAR = ActionBarAdvisor.FILL_COOL_BAR;
141:
142: /**
143: * Bit flag for {@link #fillActionBars fillActionBars} indicating that the
144: * operation is supposed to fill (or describe) the workbench window's status
145: * line.
146: *
147: * @deprecated use {@link ActionBarAdvisor#FILL_STATUS_LINE instead}
148: */
149: public static final int FILL_STATUS_LINE = ActionBarAdvisor.FILL_STATUS_LINE;
150:
151: /**
152: * The workbench configurer.
153: */
154: private IWorkbenchConfigurer workbenchConfigurer;
155:
156: /**
157: * The workbench error handler.
158: */
159: private AbstractStatusHandler workbenchErrorHandler;
160:
161: private boolean introOpened;
162:
163: /**
164: * Creates and initializes a new workbench advisor instance.
165: */
166: protected WorkbenchAdvisor() {
167: // do nothing
168: }
169:
170: /**
171: * Remembers the configurer and calls <code>initialize</code>.
172: * <p>
173: * For internal use by the workbench only.
174: * </p>
175: *
176: * @param configurer
177: * an object for configuring the workbench
178: */
179: public final void internalBasicInitialize(
180: IWorkbenchConfigurer configurer) {
181: if (workbenchConfigurer != null) {
182: throw new IllegalStateException();
183: }
184: this .workbenchConfigurer = configurer;
185: initialize(configurer);
186: }
187:
188: /**
189: * Performs arbitrary initialization before the workbench starts running.
190: * <p>
191: * This method is called during workbench initialization prior to any
192: * windows being opened. Clients must not call this method directly
193: * (although super calls are okay). The default implementation does nothing.
194: * Subclasses may override. Typical clients will use the configurer passed
195: * in to tweak the workbench. If further tweaking is required in the future,
196: * the configurer may be obtained using <code>getWorkbenchConfigurer</code>.
197: * </p>
198: *
199: * @param configurer
200: * an object for configuring the workbench
201: */
202: public void initialize(IWorkbenchConfigurer configurer) {
203: // do nothing
204: }
205:
206: /**
207: * Returns the workbench configurer for the advisor. Can be
208: * <code>null</code> if the advisor is not initialized yet.
209: *
210: * @return the workbench configurer, or <code>null</code> if the advisor
211: * is not initialized yet
212: */
213: protected IWorkbenchConfigurer getWorkbenchConfigurer() {
214: return workbenchConfigurer;
215: }
216:
217: /**
218: * Returns the workbench error handler for the advisor.
219: *
220: * @return the workbench error handler
221: * @since 3.3
222: */
223: public AbstractStatusHandler getWorkbenchErrorHandler() {
224: if (workbenchErrorHandler == null) {
225: workbenchErrorHandler = new WorkbenchErrorHandler();
226: }
227: return workbenchErrorHandler;
228: }
229:
230: /**
231: * Performs arbitrary actions just before the first workbench window is
232: * opened (or restored).
233: * <p>
234: * This method is called after the workbench has been initialized and just
235: * before the first window is about to be opened. Clients must not call this
236: * method directly (although super calls are okay). The default
237: * implementation does nothing. Subclasses may override.
238: * </p>
239: */
240: public void preStartup() {
241: // do nothing
242: }
243:
244: /**
245: * Performs arbitrary actions after the workbench windows have been opened
246: * (or restored), but before the main event loop is run.
247: * <p>
248: * This method is called just after the windows have been opened. Clients
249: * must not call this method directly (although super calls are okay). The
250: * default implementation does nothing. Subclasses may override. It is okay
251: * to call <code>IWorkbench.close()</code> from this method.
252: * </p>
253: */
254: public void postStartup() {
255: // do nothing
256: }
257:
258: /**
259: * Performs arbitrary finalization before the workbench is about to shut
260: * down.
261: * <p>
262: * This method is called immediately prior to workbench shutdown before any
263: * windows have been closed. Clients must not call this method directly
264: * (although super calls are okay). The default implementation returns
265: * <code>true</code>. Subclasses may override.
266: * </p>
267: * <p>
268: * The advisor may veto a regular shutdown by returning <code>false</code>,
269: * although this will be ignored if the workbench is being forced to shut
270: * down.
271: * </p>
272: *
273: * @return <code>true</code> to allow the workbench to proceed with
274: * shutdown, <code>false</code> to veto a non-forced shutdown
275: */
276: public boolean preShutdown() {
277: return true;
278: }
279:
280: /**
281: * Performs arbitrary finalization after the workbench stops running.
282: * <p>
283: * This method is called during workbench shutdown after all windows have
284: * been closed. Clients must not call this method directly (although super
285: * calls are okay). The default implementation does nothing. Subclasses may
286: * override.
287: * </p>
288: */
289: public void postShutdown() {
290: // do nothing
291: }
292:
293: /**
294: * Performs arbitrary actions when the event loop crashes (the code that
295: * handles a UI event throws an exception that is not caught).
296: * <p>
297: * This method is called when the code handling a UI event throws an
298: * exception. In a perfectly functioning application, this method would
299: * never be called. In practice, it comes into play when there are bugs in
300: * the code that trigger unchecked runtime exceptions. It is also activated
301: * when the system runs short of memory, etc. Fatal errors (ThreadDeath) are
302: * not passed on to this method, as there is nothing that could be done.
303: * </p>
304: * <p>
305: * Clients must not call this method directly (although super calls are
306: * okay). The default implementation logs the problem so that it does not go
307: * unnoticed. Subclasses may override or extend this method. It is generally
308: * a bad idea to override with an empty method, and you should be especially
309: * careful when handling Errors.
310: * </p>
311: *
312: * @param exception
313: * the uncaught exception that was thrown inside the UI event
314: * loop
315: */
316: public void eventLoopException(Throwable exception) {
317: // Protection from client doing super(null) call
318: if (exception == null) {
319: return;
320: }
321:
322: try {
323: StatusManager
324: .getManager()
325: .handle(
326: new Status(
327: IStatus.ERROR,
328: WorkbenchPlugin.PI_WORKBENCH,
329: "Unhandled event loop exception", exception)); //$NON-NLS-1$
330:
331: if (WorkbenchPlugin.DEBUG) {
332: exception.printStackTrace();
333: }
334: } catch (Throwable e) {
335: // One of the log listeners probably failed. Core should have logged
336: // the
337: // exception since its the first listener.
338: System.err
339: .println("Error while logging event loop exception:"); //$NON-NLS-1$
340: exception.printStackTrace();
341: System.err.println("Logging exception:"); //$NON-NLS-1$
342: e.printStackTrace();
343: }
344: }
345:
346: /**
347: * Performs arbitrary work or yields when there are no events to be
348: * processed.
349: * <p>
350: * This method is called when there are currently no more events on the
351: * queue to be processed at the moment.
352: * </p>
353: * <p>
354: * Clients must not call this method directly (although super calls are
355: * okay). The default implementation yields until new events enter the
356: * queue. Subclasses may override or extend this method. It is generally a
357: * bad idea to override with an empty method. It is okay to call
358: * <code>IWorkbench.close()</code> from this method.
359: * </p>
360: *
361: * @param display
362: * the main display of the workbench UI
363: */
364: public void eventLoopIdle(Display display) {
365: // default: yield cpu until new events enter the queue
366: display.sleep();
367: }
368:
369: /**
370: * Creates a new workbench window advisor for configuring a new workbench
371: * window via the given workbench window configurer. Clients should override
372: * to provide their own window configurer. This method replaces all the
373: * other window and action bar lifecycle methods on the workbench advisor.
374: * <p>
375: * The default implementation creates a window advisor that calls back to
376: * the legacy window and action bar lifecycle methods on the workbench
377: * advisor, for backwards compatibility with 3.0.
378: * </p>
379: *
380: * @param configurer
381: * the workbench window configurer
382: * @return a new workbench window advisor
383: * @since 3.1
384: */
385: public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
386: IWorkbenchWindowConfigurer configurer) {
387: return new CompatibilityWorkbenchWindowAdvisor(this , configurer);
388: }
389:
390: /**
391: * Performs arbitrary actions before the given workbench window is opened.
392: * <p>
393: * This method is called before the window's controls have been created.
394: * Clients must not call this method directly (although super calls are
395: * okay). The default implementation does nothing. Subclasses may override.
396: * Typical clients will use the configurer passed in to tweak the workbench
397: * window in an application-specific way; however, filling the window's menu
398: * bar, tool bar, and status line must be done in
399: * {@link #fillActionBars fillActionBars}, which is called immediately
400: * after this method is called.
401: * </p>
402: *
403: * @param configurer
404: * an object for configuring the particular workbench window
405: * being opened
406: *
407: * @deprecated since 3.1, override
408: * {@link WorkbenchWindowAdvisor#preWindowOpen()} instead
409: * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
410: */
411: public void preWindowOpen(IWorkbenchWindowConfigurer configurer) {
412: // do nothing
413: }
414:
415: /**
416: * Configures the action bars using the given action bar configurer. Under
417: * normal circumstances, <code>flags</code> does not include
418: * <code>FILL_PROXY</code>, meaning this is a request to fill the
419: * actions\ bars of the given workbench window; the remaining flags indicate
420: * which combination of the menu bar (<code>FILL_MENU_BAR</code>), the
421: * tool bar (<code>FILL_COOL_BAR</code>), and the status line (<code>FILL_STATUS_LINE</code>)
422: * are to be filled.
423: * <p>
424: * If <code>flags</code> does include <code>FILL_PROXY</code>, then
425: * this is a request to describe the actions bars of the given workbench
426: * window (which will already have been filled); again, the remaining flags
427: * indicate which combination of the menu bar, the tool bar, and the status
428: * line are to be described. The actions included in the proxy action bars
429: * can be the same instances as in the actual window's action bars. Calling
430: * <code>ActionFactory</code> to create new action instances is not
431: * recommended, because these actions internally register listeners with the
432: * window and there is no opportunity to dispose of these actions.
433: * </p>
434: * <p>
435: * This method is called just after {@link #preWindowOpen preWindowOpen}.
436: * Clients must not call this method directly (although super calls are
437: * okay). The default implementation does nothing. Subclasses may override.
438: * </p>
439: *
440: * @param window
441: * the workbench window
442: * @param configurer
443: * the action bar configurer object
444: * @param flags
445: * bit mask composed from the constants
446: * {@link #FILL_MENU_BAR FILL_MENU_BAR},
447: * {@link #FILL_COOL_BAR FILL_COOL_BAR},
448: * {@link #FILL_STATUS_LINE FILL_STATUS_LINE}, and
449: * {@link #FILL_PROXY FILL_PROXY} Note: should 1st param be
450: * IWorkbenchWindowConfigurer to be more consistent with other
451: * methods? Note: suggest adding ActionBuilder as API, to
452: * encapsulate the action building outside of the advisor, and to
453: * handle the common pattern of hanging onto the action builder
454: * in order to properly handle FILL_PROXY
455: *
456: * @deprecated since 3.1, override
457: * {@link ActionBarAdvisor#fillActionBars(int)} instead
458: * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
459: * @see WorkbenchWindowAdvisor#createActionBarAdvisor(IActionBarConfigurer)
460: */
461: public void fillActionBars(IWorkbenchWindow window,
462: IActionBarConfigurer configurer, int flags) {
463: // do nothing by default
464: }
465:
466: /**
467: * Performs arbitrary actions after the given workbench window has been
468: * restored, but before it is opened.
469: * <p>
470: * This method is called after a previously-saved window have been
471: * recreated. This method is not called when a new window is created from
472: * scratch. This method is never called when a workbench is started for the
473: * very first time, or when workbench state is not saved or restored.
474: * Clients must not call this method directly (although super calls are
475: * okay). The default implementation does nothing. Subclasses may override.
476: * It is okay to call <code>IWorkbench.close()</code> from this method.
477: * </p>
478: *
479: * @param configurer
480: * an object for configuring the particular workbench window just
481: * restored
482: *
483: * @deprecated since 3.1, override
484: * {@link WorkbenchWindowAdvisor#postWindowRestore()} instead
485: * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
486: */
487: public void postWindowRestore(IWorkbenchWindowConfigurer configurer)
488: throws WorkbenchException {
489: // do nothing
490: }
491:
492: /**
493: * Opens the introduction componenet.
494: * <p>
495: * Clients must not call this method directly (although super calls are
496: * okay). The default implementation opens the intro in the first window
497: * provided the preference IWorkbenchPreferences.SHOW_INTRO is
498: * <code>true</code>. If an intro is shown then this preference will be
499: * set to <code>false</code>. Subsequently, and intro will be shown only
500: * if <code>WorkbenchConfigurer.getSaveAndRestore()</code> returns
501: * <code>true</code> and the introduction was visible on last shutdown.
502: * Subclasses may override.
503: * </p>
504: *
505: * @param configurer
506: * configurer an object for configuring the particular workbench
507: * window just created
508: *
509: * @deprecated since 3.1, override
510: * {@link WorkbenchWindowAdvisor#openIntro()} instead
511: * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
512: */
513: public void openIntro(IWorkbenchWindowConfigurer configurer) {
514: if (introOpened) {
515: return;
516: }
517:
518: introOpened = true;
519:
520: boolean showIntro = PrefUtil.getAPIPreferenceStore()
521: .getBoolean(IWorkbenchPreferenceConstants.SHOW_INTRO);
522:
523: if (!showIntro) {
524: return;
525: }
526:
527: if (getWorkbenchConfigurer().getWorkbench().getIntroManager()
528: .hasIntro()) {
529: getWorkbenchConfigurer().getWorkbench().getIntroManager()
530: .showIntro(configurer.getWindow(), false);
531:
532: PrefUtil.getAPIPreferenceStore().setValue(
533: IWorkbenchPreferenceConstants.SHOW_INTRO, false);
534: PrefUtil.saveAPIPrefs();
535: }
536: }
537:
538: /**
539: * Performs arbitrary actions after the given workbench window has been
540: * created (possibly after being restored), but has not yet been opened.
541: * <p>
542: * This method is called after a new window has been created from scratch,
543: * or when a previously-saved window has been restored. In the latter case,
544: * this method is called after <code>postWindowRestore</code>. Clients
545: * must not call this method directly (although super calls are okay). The
546: * default implementation does nothing. Subclasses may override.
547: * </p>
548: *
549: * @param configurer
550: * an object for configuring the particular workbench window just
551: * created
552: *
553: * @deprecated since 3.1, override
554: * {@link WorkbenchWindowAdvisor#postWindowCreate()} instead
555: * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
556: */
557: public void postWindowCreate(IWorkbenchWindowConfigurer configurer) {
558: // do nothing
559: }
560:
561: /**
562: * Performs arbitrary actions after the given workbench window has been
563: * opened (possibly after being restored).
564: * <p>
565: * This method is called after a window has been opened. This method is
566: * called after a new window has been created from scratch, or when a
567: * previously-saved window has been restored. Clients must not call this
568: * method directly (although super calls are okay). The default
569: * implementation does nothing. Subclasses may override.
570: * </p>
571: *
572: * @param configurer
573: * an object for configuring the particular workbench window just
574: * opened
575: *
576: * @deprecated since 3.1, override
577: * {@link WorkbenchWindowAdvisor#postWindowOpen()} instead
578: * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
579: */
580: public void postWindowOpen(IWorkbenchWindowConfigurer configurer) {
581: // do nothing
582: }
583:
584: /**
585: * Performs arbitrary actions as the given workbench window's shell is being
586: * closed directly, and possibly veto the close.
587: * <p>
588: * This method is called from a ShellListener associated with the workbench
589: * window. It is not called when the window is being closed for other
590: * reasons. Clients must not call this method directly (although super calls
591: * are okay). The default implementation does nothing. Subclasses may
592: * override. Typical clients may use the configurer passed in to access the
593: * workbench window being closed. If this method returns <code>false</code>,
594: * then the user's request to close the shell is ignored. This gives the
595: * workbench advisor an opportunity to query the user and/or veto the
596: * closing of a window under some circumstances.
597: * </p>
598: *
599: * @param configurer
600: * an object for configuring the particular workbench window
601: * whose shell is being closed
602: * @return <code>true</code> to allow the window to close, and
603: * <code>false</code> to prevent the window from closing
604: * @see org.eclipse.ui.IWorkbenchWindow#close
605: *
606: * @deprecated since 3.1, override
607: * {@link WorkbenchWindowAdvisor#preWindowShellClose()} instead
608: * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
609: */
610: public boolean preWindowShellClose(
611: IWorkbenchWindowConfigurer configurer) {
612: // do nothing, but allow the close() to proceed
613: return true;
614: }
615:
616: /**
617: * Performs arbitrary actions after the given workbench window is closed.
618: * <p>
619: * This method is called after the window's controls have been disposed.
620: * Clients must not call this method directly (although super calls are
621: * okay). The default implementation does nothing. Subclasses may override.
622: * Typical clients will use the configurer passed in to tweak the workbench
623: * window in an application-specific way.
624: * </p>
625: *
626: * @param configurer
627: * an object for configuring the particular workbench window
628: * being closed
629: *
630: * @deprecated since 3.1, override
631: * {@link WorkbenchWindowAdvisor#postWindowClose()} instead
632: * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
633: */
634: public void postWindowClose(IWorkbenchWindowConfigurer configurer) {
635: // do nothing
636: }
637:
638: /**
639: * Returns whether the menu with the given id is an application menu of the
640: * given window. This is used during OLE "in place" editing. Application
641: * menus should be preserved during menu merging. All other menus may be
642: * removed from the window.
643: * <p>
644: * The default implementation returns false. Subclasses may override.
645: * </p>
646: *
647: * @param configurer
648: * an object for configuring the workbench window
649: * @param menuId
650: * the menu id
651: * @return <code>true</code> for application menus, and <code>false</code>
652: * for part-specific menus
653: *
654: * @deprecated since 3.1, override
655: * {@link ActionBarAdvisor#isApplicationMenu(String)} instead
656: * @see WorkbenchWindowAdvisor#createActionBarAdvisor(IActionBarConfigurer)
657: */
658: public boolean isApplicationMenu(
659: IWorkbenchWindowConfigurer configurer, String menuId) {
660: // default: not an application menu
661: return false;
662: }
663:
664: /**
665: * Returns the default input for newly created workbench pages when the
666: * input is not explicitly specified.
667: * <p>
668: * The default implementation returns <code>null</code>. Subclasses may
669: * override.
670: * </p>
671: *
672: * @return the default input for a new workbench window page, or
673: * <code>null</code> if none
674: *
675: * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
676: */
677: public IAdaptable getDefaultPageInput() {
678: // default: no input
679: return null;
680: }
681:
682: /**
683: * Returns the id of the perspective to use for the initial workbench
684: * window, or <code>null</code> if no initial perspective should be shown
685: * in the initial workbench window.
686: * <p>
687: * This method is called during startup when the workbench is creating the
688: * first new window. Subclasses must implement.
689: * </p>
690: * <p>
691: * If the {@link IWorkbenchPreferenceConstants#DEFAULT_PERSPECTIVE_ID}
692: * preference is specified, it supercedes the perspective specified here.
693: * </p>
694: *
695: * @return the id of the perspective for the initial window, or
696: * <code>null</code> if no initial perspective should be shown
697: */
698: public abstract String getInitialWindowPerspectiveId();
699:
700: /**
701: * Returns the id of the preference page that should be presented most
702: * prominently.
703: * <p>
704: * The default implementation returns <code>null</code>. Subclasses may
705: * override.
706: * </p>
707: *
708: * @return the id of the preference page, or <code>null</code> if none
709: */
710: public String getMainPreferencePageId() {
711: // default: no opinion
712: return null;
713: }
714:
715: /**
716: * Creates the contents of the window.
717: * <p>
718: * The default implementation adds a menu bar, a cool bar, a status line, a
719: * perspective bar, and a fast view bar. The visibility of these controls
720: * can be configured using the <code>setShow*</code> methods on
721: * <code>IWorkbenchWindowConfigurer</code>.
722: * </p>
723: * <p>
724: * Subclasses may override to define custom window contents and layout, but
725: * must call <code>IWorkbenchWindowConfigurer.createPageComposite</code>.
726: * </p>
727: *
728: * @param configurer
729: * the window configurer
730: * @param shell
731: * the window's shell
732: * @see IWorkbenchWindowConfigurer#createMenuBar
733: * @see IWorkbenchWindowConfigurer#createCoolBarControl
734: * @see IWorkbenchWindowConfigurer#createStatusLineControl
735: * @see IWorkbenchWindowConfigurer#createPageComposite
736: *
737: * @deprecated since 3.1, override
738: * {@link WorkbenchWindowAdvisor#createWindowContents(Shell)}
739: * instead
740: * @see #createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer)
741: */
742: public void createWindowContents(
743: IWorkbenchWindowConfigurer configurer, Shell shell) {
744: ((WorkbenchWindowConfigurer) configurer)
745: .createDefaultContents(shell);
746: }
747:
748: /**
749: * Opens the workbench windows on startup. The default implementation tries
750: * to restore the previously saved workbench state using
751: * <code>IWorkbenchConfigurer.restoreWorkbenchState()</code>. If there
752: * was no previously saved state, or if the restore failed, then a
753: * first-time window is opened using
754: * <code>IWorkbenchConfigurer.openFirstTimeWindow</code>.
755: *
756: * @return <code>true</code> to proceed with workbench startup, or
757: * <code>false</code> to exit
758: */
759: public boolean openWindows() {
760: final Display display = PlatformUI.getWorkbench().getDisplay();
761: final boolean result[] = new boolean[1];
762:
763: // spawn another init thread. For API compatibility We guarantee this method is called from
764: // the UI thread but it could take enough time to disrupt progress reporting.
765: // spawn a new thread to do the grunt work of this initialization and spin the event loop
766: // ourselves just like it's done in Workbench.
767: final boolean[] initDone = new boolean[] { false };
768: final Throwable[] error = new Throwable[1];
769: Thread initThread = new Thread() {
770: /* (non-Javadoc)
771: * @see java.lang.Thread#run()
772: */
773: public void run() {
774: try {
775: //declare us to be a startup thread so that our syncs will be executed
776: UISynchronizer.startupThread.set(Boolean.TRUE);
777: final IWorkbenchConfigurer[] myConfigurer = new IWorkbenchConfigurer[1];
778: StartupThreading
779: .runWithoutExceptions(new StartupRunnable() {
780:
781: public void runWithException()
782: throws Throwable {
783: myConfigurer[0] = getWorkbenchConfigurer();
784:
785: }
786: });
787:
788: IStatus status = myConfigurer[0].restoreState();
789: if (!status.isOK()) {
790: if (status.getCode() == IWorkbenchConfigurer.RESTORE_CODE_EXIT) {
791: result[0] = false;
792: return;
793: }
794: if (status.getCode() == IWorkbenchConfigurer.RESTORE_CODE_RESET) {
795: myConfigurer[0].openFirstTimeWindow();
796: }
797: }
798: result[0] = true;
799: } catch (Throwable e) {
800: error[0] = e;
801: } finally {
802: initDone[0] = true;
803: display.wake();
804: }
805: }
806: };
807: initThread.start();
808:
809: while (true) {
810: if (!display.readAndDispatch()) {
811: if (initDone[0])
812: break;
813: display.sleep();
814: }
815:
816: }
817:
818: // can only be a runtime or error
819: if (error[0] instanceof Error)
820: throw (Error) error[0];
821: else if (error[0] instanceof RuntimeException)
822: throw (RuntimeException) error[0];
823:
824: return result[0];
825: }
826:
827: /**
828: * Saves arbitrary application-specific state information for this workbench
829: * advisor.
830: * <p>
831: * The default implementation simply returns an OK status. Subclasses may
832: * extend or override.
833: * </p>
834: *
835: * @param memento
836: * the memento in which to save the advisor's state
837: * @return a status object indicating whether the save was successful
838: * @since 3.1
839: */
840: public IStatus saveState(IMemento memento) {
841: return Status.OK_STATUS;
842: }
843:
844: /**
845: * Restores arbitrary application-specific state information for this
846: * workbench advisor.
847: * <p>
848: * The default implementation simply returns an OK status. Subclasses may
849: * extend or override.
850: * </p>
851: *
852: * @param memento
853: * the memento from which to restore the advisor's state
854: * @return a status object indicating whether the restore was successful
855: * @since 3.1
856: */
857: public IStatus restoreState(IMemento memento) {
858: return Status.OK_STATUS;
859: }
860: }
|