Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/eclipse/ui/application/WorkbenchAdvisor.java


1   /*******************************************************************************
2    * Copyright (c) 2003, 2004 IBM Corporation and others.
3    * All rights reserved. This program and the accompanying materials 
4    * are made available under the terms of the Common Public License v1.0
5    * which accompanies this distribution, and is available at
6    * http://www.eclipse.org/legal/cpl-v10.html
7    * 
8    * Contributors:
9    *     IBM Corporation - initial API and implementation
10   *******************************************************************************/
11  
12  package org.eclipse.ui.application;
13  
14  import org.eclipse.core.runtime.IAdaptable;
15  import org.eclipse.core.runtime.IStatus;
16  import org.eclipse.core.runtime.Status;
17  import org.eclipse.swt.SWTError;
18  import org.eclipse.swt.SWTException;
19  import org.eclipse.swt.widgets.Display;
20  import org.eclipse.swt.widgets.Shell;
21  import org.eclipse.ui.IWorkbenchPreferenceConstants;
22  import org.eclipse.ui.IWorkbenchWindow;
23  import org.eclipse.ui.PlatformUI;
24  import org.eclipse.ui.WorkbenchException;
25  import org.eclipse.ui.internal.WorkbenchPlugin;
26  import org.eclipse.ui.internal.WorkbenchWindowConfigurer;
27  import org.eclipse.ui.internal.util.PrefUtil;
28  
29  /**
30   * Public base class for configuring the workbench.
31   * <p>
32   * Note that the workbench advisor object is created in advance of creating the
33   * workbench. However, by the time the workbench starts calling methods on this
34   * class, <code>PlatformUI.getWorkbench</code> is guaranteed to have been
35   * properly initialized.
36   * </p>
37   * <p>
38   * Example of creating and running a workbench (in an
39   * <code>IPlatformRunnable</code>):
40   * <pre>
41   * <code>
42   * public class MyApplication implements IPlatformRunnable {
43   *   public Object run(Object args) {
44   *     WorkbenchAdvisor workbenchAdvisor = new MyWorkbenchAdvisor();
45   *     Display display = PlatformUI.createDisplay();
46   *     int returnCode = PlatformUI.createAndRunWorkbench(display, workbenchAdvisor);
47   *     if (returnCode == PlatformUI.RETURN_RESTART) {
48   *        return IPlatformRunnable.EXIT_RESTART;
49   *     } else {
50   *        return IPlatformRunnable.EXIT_OK;
51   *   }
52   * }
53   * </code>
54   * </pre>
55   * </p>
56   * <p>
57   * An application should declare a subclass of <code>WorkbenchAdvisor</code>
58   * and override methods to configure the workbench to suit the needs of the
59   * particular application.
60   * </p>
61   * <p>
62   * The following advisor methods are called at strategic points in the
63   * workbench's lifecycle (all occur within the dynamic scope of the call
64   * to {@link PlatformUI#createAndRunWorkbench PlatformUI.createAndRunWorkbench}):
65   * <ul>
66   * <li><code>initialize</code> - called first; before any windows; use to
67   * register things</li>
68   * <li><code>preStartup</code> - called second; after initialize but
69   * before first window is opened; use to temporarily disable things during
70   * startup or restore</li>
71   * <li><code>postStartup</code> - called third; after first window is
72   * opened; use to reenable things temporarily disabled in previous step</li>
73   * <li><code>postRestore</code> - called after the workbench and its windows
74   * has been recreated from a previously saved state; use to adjust the
75   * restored workbench</li>
76   * <li><code>preWindowOpen</code> - called as each window is being opened; 
77   *  use to configure aspects of the window other than actions bars </li>
78   * <li><code>fillActionBars</code> - called after <code>preWindowOpen</code> to
79   * configure a window's action bars</li>
80   * <li><code>postWindowRestore</code> - called after a window has been
81   * recreated from a previously saved state; use to adjust the restored
82   * window</li>
83   * <li><code>postWindowCreate</code> -  called after a window has been created,
84   * either from an initial state or from a restored state;  used to adjust the
85   * window</li>
86   * <li><code>openIntro</code> - called immediately before a window is opened in
87   * order to create the introduction component, if any.
88   * <li><code>postWindowOpen</code> - called after a window has been
89   * opened; use to hook window listeners, etc.</li>
90   * <li><code>preWindowShellClose</code> - called when a window's shell
91   * is closed by the user; use to pre-screen window closings</li>
92   * <li><code>eventLoopException</code> - called to handle the case where the
93   * event loop has crashed; use to inform the user that things are not well</li>
94   * <li><code>eventLoopIdle</code> - called when there are currently no more
95   * events to be processed; use to perform other work or to yield until new
96   * events enter the queue</li>
97   * <li><code>preShutdown</code> - called just after event loop has terminated
98   * but before any windows have been closed; use to deregister things registered
99   * during initialize</li>
100  * <li><code>postShutdown</code> - called last; after event loop has terminated
101  * and all windows have been closed; use to deregister things registered during
102  * initialize</li>
103  * </ul>
104  * </p>
105  * 
106  * @since 3.0
107  */
108 public abstract class WorkbenchAdvisor {
109   
110   /**
111    * Bit flag for {@link #fillActionBars fillActionBars} indicating that the
112    * operation is not filling the action bars of an actual workbench window,
113    * but rather a proxy (used for perspective customization).
114    */
115   public static final int FILL_PROXY = 0x01;
116 
117   /**
118    * Bit flag for {@link #fillActionBars fillActionBars} indicating that the
119    * operation is supposed to fill (or describe) the workbench window's menu
120    * bar.
121    */
122   public static final int FILL_MENU_BAR = 0x02;
123   
124   /**
125    * Bit flag for {@link #fillActionBars fillActionBars} indicating that the
126    * operation is supposed to fill (or describe) the workbench window's cool
127    * bar.
128    */
129   public static final int FILL_COOL_BAR = 0x04;
130 
131   /**
132    * Bit flag for {@link #fillActionBars fillActionBars} indicating that the
133    * operation is supposed to fill (or describe) the workbench window's status
134    * line.
135    */
136   public static final int FILL_STATUS_LINE = 0x08;
137 
138   /**
139    * The workbench configurer.
140    */
141   private IWorkbenchConfigurer workbenchConfigurer;
142 
143     private boolean introOpened;
144   
145   /**
146    * Creates and initializes a new workbench advisor instance.
147    */
148   protected WorkbenchAdvisor() {
149     // do nothing
150   }
151 
152   /**
153    * Remembers the configurer and calls <code>initialize</code>.
154    * <p>
155    * For internal use by the workbench only.
156    * </p>
157    * 
158    * @param configurer an object for configuring the workbench
159    */
160   public final void internalBasicInitialize(IWorkbenchConfigurer configurer) {
161       if (workbenchConfigurer != null) {
162           throw new IllegalStateException();
163       }
164     this.workbenchConfigurer = configurer;
165     initialize(configurer);
166   }
167   
168   /**
169    * Performs arbitrary initialization before the workbench starts running.
170    * <p>
171    * This method is called during workbench initialization prior to any
172    * windows being opened. 
173    * Clients must not call this method directly (although super calls are okay).
174    * The default implementation does nothing. Subclasses may override. 
175    * Typical clients will use the configurer passed in to tweak the
176    * workbench.  If further tweaking is required in the future,
177    * the configurer may be obtained using <code>getWorkbenchConfigurer</code>.
178    * </p>
179    * 
180    * @param configurer an object for configuring the workbench
181    */
182   public void initialize(IWorkbenchConfigurer configurer) {
183     // do nothing
184   }
185 
186   /**
187    * Returns the workbench configurer for the advisor. Can
188    * be <code>null</code> if the advisor is not initialized yet.
189    * 
190    * @return the workbench configurer, or <code>null</code>
191    *   if the advisor is not initialized yet
192    */
193   protected IWorkbenchConfigurer getWorkbenchConfigurer() {
194       return workbenchConfigurer;
195   }
196 
197   /**
198    * Performs arbitrary actions just before the first workbench window is
199    * opened (or restored).
200    * <p>
201    * This method is called after the workbench has been initialized and
202    * just before the first window is about to be opened.
203    * Clients must not call this method directly (although super calls are okay).
204    * The default implementation does nothing. Subclasses may override.
205    * </p>
206    */
207   public void preStartup() {
208     // do nothing
209   }
210 
211   /**
212    * Performs arbitrary actions after the workbench windows have been
213    * opened (or restored), but before the main event loop is run.
214    * <p>
215    * This method is called just after the windows have been opened.
216    * Clients must not call this method directly (although super calls are okay).
217    * The default implementation does nothing. Subclasses may override.
218    * It is okay to call <code>IWorkbench.close()</code> from this method.
219    * </p>
220    */
221   public void postStartup() {
222     // do nothing
223   }
224 
225   /**
226    * Performs arbitrary finalization before the workbench is about to
227    * shut down.
228    * <p>
229    * This method is called immediately prior to workbench shutdown before any
230    * windows have been closed.
231    * Clients must not call this method directly (although super calls are okay).
232    * The default implementation returns <code>true</code>. Subclasses may override.
233    * </p>
234    * <p>
235    * The advisor may veto a regular shutdown by returning <code>false</code>, 
236    * although this will be ignored if the workbench is being forced to shut down.
237    * </p>
238    * @return <code>true</code> to allow the workbench to proceed with shutdown,
239    *   <code>false</code> to veto a non-forced shutdown
240    */
241   public boolean preShutdown() {
242     return true;
243   }
244   
245   /**
246    * Performs arbitrary finalization after the workbench stops running.
247    * <p>
248    * This method is called during workbench shutdown after all windows
249    * have been closed.
250    * Clients must not call this method directly (although super calls are okay).
251    * The default implementation does nothing. Subclasses may override.
252    * </p>
253    */
254   public void postShutdown() {
255     // do nothing
256   }
257   
258   /**
259    * Performs arbitrary actions when the event loop crashes (the code that
260    * handles a UI event throws an exception that is not caught).
261    * <p>
262    * This method is called when the code handling a UI event throws an
263    * exception. In a perfectly functioning application, this method would
264    * never be called. In practice, it comes into play when there are bugs
265    * in the code that trigger unchecked runtime exceptions. It is also
266    * activated when the system runs short of memory, etc. 
267    * Fatal errors (ThreadDeath) are not passed on to this method, as there
268    * is nothing that could be done.
269    * </p>
270    * <p>
271    * Clients must not call this method directly (although super calls are okay).
272    * The default implementation logs the problem so that it does not go
273    * unnoticed. Subclasses may override or extend this method. It is generally
274    * a bad idea to override with an empty method, and you should be
275    * especially careful when handling Errors.
276    * </p>
277    * 
278    * @param exception the uncaught exception that was thrown inside the UI
279    * event loop
280    */
281   public void eventLoopException(Throwable exception) {
282     // Protection from client doing super(null) call
283     if (exception == null) {
284       return;
285     }
286     
287     try {
288       // Log the exception
289       String msg = exception.getMessage();
290       if (msg == null) {
291         msg = exception.toString();
292       }
293       WorkbenchPlugin.log(
294         "Unhandled event loop exception", //$NON-NLS-1$
295         new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, msg, exception));
296   
297       // Handle nested exception from SWT (see bug 6312)
298       Throwable nested = null;
299       if (exception instanceof SWTException) {
300         nested = ((SWTException)exception).throwable;
301       } else if (exception instanceof SWTError) {
302         nested = ((SWTError)exception).throwable;
303       }
304       if (nested != null) {
305         msg = nested.getMessage();
306         if (msg == null) {
307           msg = nested.toString();
308         }
309         WorkbenchPlugin.log(
310           "*** SWT nested exception", //$NON-NLS-1$
311           new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, msg, nested));
312       }
313       
314       // Print it onto the console if debugging
315       if (WorkbenchPlugin.DEBUG) {
316         exception.printStackTrace();
317       }
318     } catch (Throwable e) {
319       // One of the log listeners probably failed. Core should have logged the
320       // exception since its the first listener.
321       System.err.println("Error while logging event loop exception:"); //$NON-NLS-1$
322       exception.printStackTrace();
323       System.err.println("Logging exception:"); //$NON-NLS-1$
324       e.printStackTrace();
325     }
326   }
327 
328   /**
329    * Performs arbitrary work or yields when there are no events to be processed.
330    * <p>
331    * This method is called when there are currently no more events on the queue
332    * to be processed at the moment. 
333    * </p><p>
334    * Clients must not call this method directly (although super calls are okay).
335    * The default implementation yields until new events enter the queue.
336    * Subclasses may override or extend this method. It is generally
337    * a bad idea to override with an empty method. 
338    * It is okay to call <code>IWorkbench.close()</code> from this method.
339    * </p>
340    * @param display the main display of the workbench UI
341    */
342   public void eventLoopIdle(Display display) {
343     // default: yield cpu until new events enter the queue
344     display.sleep();
345   }
346   
347   /**
348    * Performs arbitrary actions before the given workbench window is
349    * opened.
350    * <p>
351    * This method is called before the window's controls have been created.
352    * Clients must not call this method directly (although super calls are okay).
353    * The default implementation does nothing. Subclasses may override.
354    * Typical clients will use the configurer passed in to tweak the
355    * workbench window in an application-specific way; however, filling the
356    * window's menu bar, tool bar, and status line must be done in 
357    * {@link #fillActionBars fillActionBars}, which is called immediately
358    * after this method is called.
359    * </p>
360    * 
361    * @param configurer an object for configuring the particular workbench
362    * window being opened
363    */
364   public void preWindowOpen(IWorkbenchWindowConfigurer configurer) {
365     // do nothing
366   }
367   
368   /**
369    * Configures the action bars using the given action bar configurer.
370    * Under normal circumstances, <code>flags</code> does not include
371    * <code>FILL_PROXY</code>, meaning this is a request to fill the actions\
372    * bars of the given workbench window; the
373    * remaining flags indicate which combination of
374    * the menu bar (<code>FILL_MENU_BAR</code>),
375    * the tool bar (<code>FILL_COOL_BAR</code>),
376    * and the status line (<code>FILL_STATUS_LINE</code>) are to be filled.
377    * <p>
378    * If <code>flags</code> does include <code>FILL_PROXY</code>, then this
379    * is a request to describe the actions bars of the given workbench window
380    * (which will already have been filled);
381    * again, the remaining flags indicate which combination of the menu bar,
382    * the tool bar, and the status line are to be described.
383    * The actions included in the proxy action bars can be the same instances
384    * as in the actual window's action bars. Calling <code>ActionFactory</code>
385    * to create new action instances is not recommended, because these
386    * actions internally register listeners with the window and there is no
387    * opportunity to dispose of these actions.
388    * </p>
389    * <p>
390    * This method is called just after {@link #preWindowOpen preWindowOpen}.
391    * Clients must not call this method directly (although super calls are okay).
392    * The default implementation does nothing. Subclasses may override.
393    * </p>
394    * 
395    * @param window the workbench window
396    * @param configurer the action bar configurer object
397    * @param flags bit mask composed from the constants
398    * {@link #FILL_MENU_BAR FILL_MENU_BAR},
399    * {@link #FILL_COOL_BAR FILL_COOL_BAR},
400    * {@link #FILL_STATUS_LINE FILL_STATUS_LINE},
401    * and {@link #FILL_PROXY FILL_PROXY}
402    * Note: should 1st param be IWorkbenchWindowConfigurer to be more consistent with other methods?
403    * Note: suggest adding ActionBuilder as API, to encapsulate the action building outside 
404    *   of the advisor, and to handle the common pattern of hanging onto the action builder
405    *   in order to properly handle FILL_PROXY 
406    */
407   public void fillActionBars(IWorkbenchWindow window, IActionBarConfigurer configurer, int flags) {
408       // do nothing by default
409   }
410 
411   /**
412    * Performs arbitrary actions after the given workbench window has been
413    * restored, but before it is opened.
414    * <p>
415    * This method is called after a previously-saved window have been
416    * recreated. This method is not called when a new window is created from
417    * scratch. This method is never called when a workbench is started for the
418    * very first time, or when workbench state is not saved or restored.
419    * Clients must not call this method directly (although super calls are okay).
420    * The default implementation does nothing. Subclasses may override.
421    * It is okay to call <code>IWorkbench.close()</code> from this method.
422    * </p>
423    * 
424    * @param configurer an object for configuring the particular workbench
425    *   window just restored
426      * Note: document checked exception
427    */
428   public void postWindowRestore(IWorkbenchWindowConfigurer configurer) throws WorkbenchException {
429     // do nothing
430   }
431   
432   /**
433    * Opens the introduction componenet.  
434    * <p>
435    * Clients must not call this method directly (although super calls are okay).
436    * The default implementation opens the intro in the first window provided
437    * the preference IWorkbenchPreferences.SHOW_INTRO is <code>true</code>.  If 
438    * an intro is shown then this preference will be set to <code>false</code>.  
439    * Subsequently, and intro will be shown only if 
440    * <code>WorkbenchConfigurer.getSaveAndRestore()</code> returns 
441    * <code>true</code> and the introduction was visible on last shutdown.  
442    * Subclasses may override.
443    * </p>
444    * 
445    * @param configurer configurer an object for configuring the particular workbench
446    * window just created
447    */
448   public void openIntro(IWorkbenchWindowConfigurer configurer) {
449         if (introOpened) 
450             return;
451 
452         introOpened = true;
453 
454       boolean showIntro = PrefUtil.getAPIPreferenceStore().getBoolean(
455                 IWorkbenchPreferenceConstants.SHOW_INTRO);
456       
457       if (!showIntro)
458           return;
459       
460     if (getWorkbenchConfigurer().getWorkbench().getIntroManager().hasIntro()) {
461         getWorkbenchConfigurer()
462           .getWorkbench()
463           .getIntroManager().showIntro(
464                   configurer.getWindow(), 
465                   false);
466         
467         PrefUtil.getAPIPreferenceStore().setValue(IWorkbenchPreferenceConstants.SHOW_INTRO, false);
468         PrefUtil.saveAPIPrefs();
469     }
470   }
471 
472   /**
473    * Performs arbitrary actions after the given workbench window has been
474    * created (possibly after being restored), but has not yet been opened.
475    * <p>
476    * This method is called after a new window has been created from scratch, 
477    * or when a previously-saved window has been restored.  In the latter case,
478    * this method is called after <code>postWindowRestore</code>.
479    * Clients must not call this method directly (although super calls are okay).
480    * The default implementation does nothing. Subclasses may override.
481    * </p>
482    * 
483    * @param configurer an object for configuring the particular workbench
484    *   window just created
485    */
486   public void postWindowCreate(IWorkbenchWindowConfigurer configurer) {
487     // do nothing
488   }
489   
490   /**
491    * Performs arbitrary actions after the given workbench window has been
492    * opened (possibly after being restored).
493    * <p>
494    * This method is called after a window has been opened. This method is 
495    * called after a new window has been created from scratch, or when
496    * a previously-saved window has been restored.
497    * Clients must not call this method directly (although super calls are okay).
498    * The default implementation does nothing. Subclasses may override.
499    * </p>
500    * 
501    * @param configurer an object for configuring the particular workbench
502    *   window just opened
503    */
504   public void postWindowOpen(IWorkbenchWindowConfigurer configurer) {
505     // do nothing
506   }
507   
508   /**
509    * Performs arbitrary actions as the given workbench window's shell is being
510    * closed directly, and possibly veto the close.
511    * <p>
512    * This method is called from a ShellListener associated with the workbench
513    * window. It is not called when the window is being closed for other reasons.
514    * Clients must not call this method directly (although super calls are okay).
515    * The default implementation does nothing. Subclasses may override.
516    * Typical clients may use the configurer passed in to access the
517    * workbench window being closed. If this method
518    * returns <code>false</code>, then the user's request to close the shell is
519    * ignored. This gives the workbench advisor an opportunity to query the user
520    * and/or veto the closing of a window under some circumstances.
521    * </p>
522    * 
523    * @param configurer an object for configuring the particular workbench
524    * window whose shell is being closed
525    * @return <code>true</code> to allow the window to close, 
526    * and <code>false</code> to prevent the window from closing
527    * @see org.eclipse.ui.IWorkbenchWindow#close
528    */
529   public boolean preWindowShellClose(IWorkbenchWindowConfigurer configurer) {
530     // do nothing, but allow the close() to proceed
531     return true;
532   }
533   
534   /**
535    * Performs arbitrary actions after the given workbench window is
536    * closed.
537    * <p>
538    * This method is called after the window's controls have been disposed.
539    * Clients must not call this method directly (although super calls are okay).
540    * The default implementation does nothing. Subclasses may override.
541    * Typical clients will use the configurer passed in to tweak the
542    * workbench window in an application-specific way.
543    * </p>
544    * 
545    * @param configurer an object for configuring the particular workbench
546    *   window being closed
547    */
548   public void postWindowClose(IWorkbenchWindowConfigurer configurer) {
549     // do nothing
550   }
551 
552   /**
553    * Returns whether the menu with the given id is an application menu of the
554    * given window. This is used during OLE "in place" editing.  Application
555    * menus should be preserved during menu merging. All other menus may be
556    * removed from the window.
557    * <p>
558    * The default implementation returns false. Subclasses may override.
559    * </p>
560    * 
561    * @param configurer an object for configuring the workbench window
562    * @param menuId the menu id
563    * @return <code>true</code> for application menus, and <code>false</code>
564    * for part-specific menus
565    */
566   public boolean isApplicationMenu(IWorkbenchWindowConfigurer configurer, String menuId) {
567     // default: not an application menu
568     return false;
569   }
570   
571   /**
572    * Returns the default input for newly created workbench pages.
573    * <p>
574    * The default implementation returns <code>null</code>.
575    * Subclasses may override.
576    * </p>
577    * 
578    * @return the default input for a new workbench window page, or
579    * <code>null</code> if none
580    */
581   public IAdaptable getDefaultPageInput() {
582     // default: no input
583     return null;
584   }
585   
586   /**
587    * Returns the id of the perspective to use for the initial workbench window.
588    * <p>
589    * This method is called during startup when the workbench is creating 
590    * the first new window. Subclasses must implement.
591    * </p>
592    * <p>
593    * If the {@link IWorkbenchPreferenceConstants#DEFAULT_PERSPECTIVE_ID} preference
594    * is specified, it supercedes the perspective specified here.
595    * </p>
596    * 
597    * @return the id of the perspective for the initial window
598    */
599   public abstract String getInitialWindowPerspectiveId();
600   
601   /**
602    * Returns the id of the preference page that should be presented most
603    * prominently.
604    * <p>
605    * The default implementation returns <code>null</code>. 
606    * Subclasses may override.
607    * </p>
608    * 
609    * @return the id of the preference page, or <code>null</code> if none
610    */
611   public String getMainPreferencePageId() {
612     // default: no opinion
613     return null;
614   }
615   
616   /**
617    * Creates the contents of the window.
618    * <p>
619    * The default implementation adds a menu bar, a cool bar, a status line, 
620    * a perspective bar, and a fast view bar.  The visibility of these controls
621    * can be configured using the <code>setShow*</code> methods on
622    * <code>IWorkbenchWindowConfigurer</code>.
623    * </p>
624    * <p>
625    * Subclasses may override to define custom window contents and layout,
626    * but must call <code>IWorkbenchWindowConfigurer.createPageComposite</code>.
627    * </p> 
628    * 
629    * @param configurer the window configurer
630    * @param shell the window's shell
631    * @see IWorkbenchWindowConfigurer#createMenuBar
632    * @see IWorkbenchWindowConfigurer#createCoolBarControl
633    * @see IWorkbenchWindowConfigurer#createStatusLineControl
634    * @see IWorkbenchWindowConfigurer#createPageComposite
635    */
636   public void createWindowContents(IWorkbenchWindowConfigurer configurer, Shell shell) {
637       ((WorkbenchWindowConfigurer) configurer).createDefaultContents(shell);
638   }
639 
640     /**
641      * Opens the workbench windows on startup.
642      * The default implementation tries to restore the previously saved
643      * workbench state using <code>IWorkbenchConfigurer.restoreWorkbenchState()</code>.
644      * If there was no previously saved state, or if the restore failed, 
645      * then a first-time window is opened using 
646      * <code>IWorkbenchConfigurer.openFirstTimeWindow</code>.
647      * 
648      * @return <code>true</code> to proceed with workbench startup,
649      *   or <code>false</code> to exit
650      */
651     public boolean openWindows() {
652         IStatus status = getWorkbenchConfigurer().restoreState();
653         if (!status.isOK()) {
654             if (status.getCode() == IWorkbenchConfigurer.RESTORE_CODE_EXIT) {
655           return false;
656             }
657         if (status.getCode() == IWorkbenchConfigurer.RESTORE_CODE_RESET) {
658             getWorkbenchConfigurer().openFirstTimeWindow();
659         }
660         }
661         return true;
662     }
663 }
664