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

Quick Search    Search Deep

Source code: org/eclipse/ui/internal/WorkbenchWindow.java


1   /*******************************************************************************
2    * Copyright (c) 2000, 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.internal;
13  
14  import java.lang.reflect.InvocationTargetException;
15  import java.util.ArrayList;
16  import java.util.HashMap;
17  import java.util.Iterator;
18  import java.util.List;
19  import java.util.Map;
20  
21  import org.eclipse.core.runtime.IAdaptable;
22  import org.eclipse.core.runtime.IStatus;
23  import org.eclipse.core.runtime.MultiStatus;
24  import org.eclipse.core.runtime.Status;
25  import org.eclipse.jface.action.CoolBarManager;
26  import org.eclipse.jface.action.GroupMarker;
27  import org.eclipse.jface.action.IAction;
28  import org.eclipse.jface.action.IContributionItem;
29  import org.eclipse.jface.action.IContributionManager;
30  import org.eclipse.jface.action.IMenuManager;
31  import org.eclipse.jface.action.MenuManager;
32  import org.eclipse.jface.action.Separator;
33  import org.eclipse.jface.action.StatusLineManager;
34  import org.eclipse.jface.action.ToolBarContributionItem;
35  import org.eclipse.jface.action.ToolBarManager;
36  import org.eclipse.jface.operation.IRunnableWithProgress;
37  import org.eclipse.jface.window.ApplicationWindow;
38  import org.eclipse.jface.window.Window;
39  import org.eclipse.swt.SWT;
40  import org.eclipse.swt.custom.BusyIndicator;
41  import org.eclipse.swt.custom.CBanner;
42  import org.eclipse.swt.events.ControlAdapter;
43  import org.eclipse.swt.events.ControlEvent;
44  import org.eclipse.swt.events.ShellAdapter;
45  import org.eclipse.swt.events.ShellEvent;
46  import org.eclipse.swt.graphics.Point;
47  import org.eclipse.swt.graphics.Rectangle;
48  import org.eclipse.swt.widgets.Composite;
49  import org.eclipse.swt.widgets.Control;
50  import org.eclipse.swt.widgets.CoolBar;
51  import org.eclipse.swt.widgets.Event;
52  import org.eclipse.swt.widgets.Label;
53  import org.eclipse.swt.widgets.Layout;
54  import org.eclipse.swt.widgets.Listener;
55  import org.eclipse.swt.widgets.Menu;
56  import org.eclipse.swt.widgets.Shell;
57  import org.eclipse.ui.IEditorPart;
58  import org.eclipse.ui.IElementFactory;
59  import org.eclipse.ui.IMemento;
60  import org.eclipse.ui.IPageListener;
61  import org.eclipse.ui.IPartService;
62  import org.eclipse.ui.IPersistableElement;
63  import org.eclipse.ui.IPerspectiveDescriptor;
64  import org.eclipse.ui.ISelectionService;
65  import org.eclipse.ui.IViewReference;
66  import org.eclipse.ui.IWorkbench;
67  import org.eclipse.ui.IWorkbenchActionConstants;
68  import org.eclipse.ui.IWorkbenchPage;
69  import org.eclipse.ui.IWorkbenchPart;
70  import org.eclipse.ui.IWorkbenchPartReference;
71  import org.eclipse.ui.IWorkbenchPreferenceConstants;
72  import org.eclipse.ui.IWorkbenchWindow;
73  import org.eclipse.ui.PlatformUI;
74  import org.eclipse.ui.WorkbenchException;
75  import org.eclipse.ui.application.IActionBarConfigurer;
76  import org.eclipse.ui.application.WorkbenchAdvisor;
77  import org.eclipse.ui.commands.ActionHandler;
78  import org.eclipse.ui.commands.HandlerSubmission;
79  import org.eclipse.ui.commands.IHandler;
80  import org.eclipse.ui.commands.IWorkbenchCommandSupport;
81  import org.eclipse.ui.commands.Priority;
82  import org.eclipse.ui.contexts.IWorkbenchContextSupport;
83  import org.eclipse.ui.help.WorkbenchHelp;
84  import org.eclipse.ui.internal.dnd.DragUtil;
85  import org.eclipse.ui.internal.intro.IIntroConstants;
86  import org.eclipse.ui.internal.layout.CacheWrapper;
87  import org.eclipse.ui.internal.layout.LayoutUtil;
88  import org.eclipse.ui.internal.layout.TrimLayout;
89  import org.eclipse.ui.internal.layout.TrimLayoutData;
90  import org.eclipse.ui.internal.misc.Assert;
91  import org.eclipse.ui.internal.misc.Policy;
92  import org.eclipse.ui.internal.misc.UIStats;
93  import org.eclipse.ui.internal.progress.ProgressRegion;
94  import org.eclipse.ui.internal.registry.ActionSetRegistry;
95  import org.eclipse.ui.internal.registry.IActionSet;
96  import org.eclipse.ui.internal.registry.IActionSetDescriptor;
97  import org.eclipse.ui.internal.util.PrefUtil;
98  
99  /**
100  * A window within the workbench.
101  */
102 public class WorkbenchWindow extends ApplicationWindow implements IWorkbenchWindow {
103 
104   private int number;
105   private PageList pageList = new PageList();
106   private PageListenerList pageListeners = new PageListenerList();
107   private PerspectiveListenerListOld perspectiveListeners = new PerspectiveListenerListOld();
108   private WWinPerspectiveService perspectiveService = new WWinPerspectiveService(this);
109   private WWinPartService partService = new WWinPartService(this);
110   private ActionPresentation actionPresentation;
111   private WWinActionBars actionBars;
112 
113   private boolean updateDisabled = true;
114   private boolean closing = false;
115   private boolean shellActivated = false;
116 
117   private FastViewBar fastViewBar;
118   private PerspectiveSwitcher perspectiveSwitcher;
119 
120   private TrimLayout defaultLayout; 
121   
122   ProgressRegion progressRegion;
123 
124   private Label noOpenPerspective;
125   private Rectangle normalBounds;
126   private boolean asMaximizedState = false;
127 
128   private CBanner topBar;
129 
130   // Previous shell size. Used to prevent the CBanner from triggering redundant layouts
131   private Point lastShellSize = new Point(0,0);
132   
133   /**
134    * The composite under which workbench pages create their controls.
135    * 
136    * @since 3.0
137    */
138   private Composite pageComposite;
139 
140   /**
141    * Bit flags indication which submenus (New, Show Views, ...) this
142    * window contains. Initially none.
143    * 
144    * @since 3.0
145    */
146   private int submenus = 0x00;
147 
148   /**
149    * Object for configuring this workbench window. Lazily initialized to
150    * an instance unique to this window.
151    *  
152    * @since 3.0
153    */
154   private WorkbenchWindowConfigurer windowConfigurer = null;
155 
156   // constants for shortcut bar group ids 
157   static final String GRP_PAGES = "pages"; //$NON-NLS-1$
158   static final String GRP_PERSPECTIVES = "perspectives"; //$NON-NLS-1$
159   static final String GRP_FAST_VIEWS = "fastViews"; //$NON-NLS-1$
160 
161   // static fields for inner classes.
162   static final int VGAP = 0;
163   static final int CLIENT_INSET = 3;
164   static final int BAR_SIZE = 23;
165 
166   /**
167    * Constant (bit mask) indicating which the Show View submenu is
168    * probably present somewhere in this window.
169    * 
170    * @see #addSubmenu
171    * @since 3.0
172    */
173   public static final int SHOW_VIEW_SUBMENU = 0x01;
174 
175   /**
176    * Constant (bit mask) indicating which the Open Perspective submenu is
177    * probably present somewhere in this window.
178    *
179    * @see #addSubmenu
180    * @since 3.0
181    */
182   public static final int OPEN_PERSPECTIVE_SUBMENU = 0x02;
183 
184   /**
185    * Constant (bit mask) indicating which the New Wizard submenu is
186    * probably present somewhere in this window.
187    * 
188    * @see #addSubmenu
189    * @since 3.0
190    */
191   public static final int NEW_WIZARD_SUBMENU = 0x04;
192 
193   /**
194    * Remembers that this window contains the given submenu.
195    * 
196    * @param type the type of submenu, one of: 
197    * {@link #NEW_WIZARD_SUBMENU NEW_WIZARD_SUBMENU},
198    * {@link #OPEN_PERSPECTIVE_SUBMENU OPEN_PERSPECTIVE_SUBMENU},
199    * {@link #SHOW_VIEW_SUBMENU SHOW_VIEW_SUBMENU}
200    * @see #containsSubmenu
201    * @since 3.0
202    */
203   public void addSubmenu(int type) {
204     submenus |= type;
205   }
206 
207   /**
208    * Checks to see if this window contains the given type of submenu.
209    * 
210    * @param type the type of submenu, one of: 
211    * {@link #NEW_WIZARD_SUBMENU NEW_WIZARD_SUBMENU},
212    * {@link #OPEN_PERSPECTIVE_SUBMENU OPEN_PERSPECTIVE_SUBMENU},
213    * {@link #SHOW_VIEW_SUBMENU SHOW_VIEW_SUBMENU}
214    * @return <code>true</code> if window contains submenu,
215    * <code>false</code> otherwise
216    * @see #addSubmenu
217    * @since 3.0
218    */
219   public boolean containsSubmenu(int type) {
220     return ((submenus & type) != 0);
221   }
222 
223   /**
224    * Constant indicating that all the actions bars should be
225    * filled.
226    * 
227    * @since 3.0
228    */
229   private static final int FILL_ALL_ACTION_BARS =
230     WorkbenchAdvisor.FILL_MENU_BAR
231       | WorkbenchAdvisor.FILL_COOL_BAR
232       | WorkbenchAdvisor.FILL_STATUS_LINE;
233 
234   /**
235    * Creates and initializes a new workbench window.
236    * 
237    * @param number the number for the window
238    */
239   public WorkbenchWindow(int number) {
240     super(null);
241     this.number = number;
242     
243     // Make sure there is a workbench. This call will throw
244     // an exception if workbench not created yet. 
245     PlatformUI.getWorkbench();
246     
247     // Add contribution managers that are exposed to other plugins.
248     addMenuBar();
249     addCoolBar(SWT.FLAT);
250     addStatusLine();
251 
252     actionPresentation = new ActionPresentation(this);
253 
254     // let the application do further configuration
255     getAdvisor().preWindowOpen(getWindowConfigurer());
256     
257     // set the shell style
258     setShellStyle(getWindowConfigurer().getShellStyle());
259     
260     // Fill the action bars
261     fillActionBars(getWindowConfigurer().getActionBarConfigurer(), FILL_ALL_ACTION_BARS);
262   }
263 
264   /**
265    * Return the style bits for the shortcut bar.
266    * @return int
267    */
268   protected int perspectiveBarStyle() {
269     return SWT.FLAT | SWT.WRAP | SWT.RIGHT | SWT.HORIZONTAL;
270   }  
271 
272   private TrimDropTarget trimDropTarget;
273   private boolean coolBarVisible = true;
274   private boolean perspectiveBarVisible = true;
275   private boolean statusLineVisible = true;
276     
277   /**
278      * The handlers for action set actions that were last submitted to the
279      * workbench command support. This is a map of command identifiers to
280      * <code>ActionHandler</code>. This map is never <code>null</code>,
281      * and is never empty as long as at least one action set has been
282      * registered. The items in this map may not all be submitted, as global
283      * actions take priority.
284      */
285     private Map actionSetHandlersByCommandId = new HashMap();
286 
287     /**
288      * The handlers for global actions that were last submitted to the workbench
289      * command support. This is a map of command identifiers to
290      * <code>ActionHandler</code>. This map is never <code>null</code>,
291      * and is never empty as long as at least one global action has been
292      * registered.
293      */
294     private Map globalActionHandlersByCommandId = new HashMap();
295 
296     /**
297      * The list of handler submissions submitted to the workbench command
298      * support. This list may be empty, but it is never <code>null</code>.
299      */
300     private List handlerSubmissions = new ArrayList();
301     
302   void registerActionSets(IActionSet[] actionSets) {
303         // Remove the old handlers, and dispose them.
304         final Iterator oldHandlerItr = actionSetHandlersByCommandId.values()
305                 .iterator();
306         while (oldHandlerItr.hasNext()) {
307             ((IHandler) oldHandlerItr.next()).dispose();
308         }
309         actionSetHandlersByCommandId.clear();
310 
311         /*
312          * For each action in each action, create a new action handler. If there
313          * are duplicates, then dispose of the earlier handler before clobbering
314          * it. This avoids memory leaks.
315          */
316         for (int i = 0; i < actionSets.length; i++) {
317             if (actionSets[i] instanceof PluginActionSet) {
318                 PluginActionSet pluginActionSet = (PluginActionSet) actionSets[i];
319                 IAction[] pluginActions = pluginActionSet.getPluginActions();
320 
321                 for (int j = 0; j < pluginActions.length; j++) {
322                     IAction pluginAction = pluginActions[j];
323                     String commandId = pluginAction.getActionDefinitionId();
324 
325                     if (commandId != null) {
326                         final Object value = actionSetHandlersByCommandId
327                                 .get(commandId);
328                         if (value instanceof IHandler) {
329                             /*
330                              * This handler is about to get clobbered, so
331                              * dispose it.
332                              */
333                             ((IHandler) value).dispose();
334                         }
335                         actionSetHandlersByCommandId.put(commandId,
336                                 new ActionHandler(pluginAction));
337 
338                     }
339                 }
340             }
341         }
342 
343         /* Submit the new amalgamated list of action set handlers and global
344          * handlers.
345          */
346         submitActionSetAndGlobalHandlers();
347     }
348 
349   void registerGlobalAction(IAction globalAction) {
350         String commandId = globalAction.getActionDefinitionId();
351 
352         if (commandId != null) {
353             final Object value = globalActionHandlersByCommandId.get(commandId);
354             if (value instanceof ActionHandler) {
355                 // This handler is about to get clobbered, so dispose it.
356                 final ActionHandler handler = (ActionHandler) value;
357                 handler.dispose();
358             }
359 
360             globalActionHandlersByCommandId.put(commandId, new ActionHandler(
361                     globalAction));
362         }
363 
364         submitActionSetAndGlobalHandlers();
365     }
366 
367   /**
368      * <p>
369      * Submits the action handlers for action set actions and global actions.
370      * Global actions are given priority, so that if a global action and an
371      * action set action both handle the same command, the global action is
372      * given priority.
373      * </p>
374      * <p>
375      * These submissions are submitted as <code>Priority.LEGACY</code>, which
376      * means that they are the lowest priority. This means that if a higher
377      * priority submission handles the same command under the same conditions,
378      * that that submission will become the handler.
379      * </p>
380      */
381   void submitActionSetAndGlobalHandlers() {
382       /* Mash the action sets and global actions together, with global actions
383        * taking priority.
384        */
385         Map handlersByCommandId = new HashMap();
386         handlersByCommandId.putAll(actionSetHandlersByCommandId);
387         handlersByCommandId.putAll(globalActionHandlersByCommandId);
388         
389         // Create a low priority submission for each handler.
390         final List newHandlerSubmissions = new ArrayList();
391         final Shell shell = getShell();
392         if (shell != null) {
393 
394             for (Iterator iterator = handlersByCommandId.entrySet().iterator(); iterator
395                     .hasNext();) {
396                 Map.Entry entry = (Map.Entry) iterator.next();
397                 String commandId = (String) entry.getKey();
398                 IHandler handler = (IHandler) entry.getValue();
399                 newHandlerSubmissions.add(new HandlerSubmission(null, shell,
400                         null, commandId, handler, Priority.LEGACY));
401             }
402         }
403         
404         // Remove the old submissions, and the add the new ones.
405         final IWorkbenchCommandSupport commandSupport = Workbench.getInstance().getCommandSupport();
406         commandSupport.removeHandlerSubmissions(handlerSubmissions);
407         handlerSubmissions = newHandlerSubmissions;
408         commandSupport.addHandlerSubmissions(newHandlerSubmissions);
409     }  
410   
411   /*
412    * Adds an listener to the part service.
413    */
414   public void addPageListener(IPageListener l) {
415     pageListeners.addPageListener(l);
416   }
417   /*
418    * Adds an listener to the perspective service.
419    *
420    * NOTE: Internally, please use getPerspectiveService instead.
421    */
422   public void addPerspectiveListener(org.eclipse.ui.IPerspectiveListener l) {
423     perspectiveListeners.addPerspectiveListener(l);
424   }
425   
426   /**
427    * add a shortcut for the page.
428    */
429   void addPerspectiveShortcut(IPerspectiveDescriptor perspective, WorkbenchPage workbenchPage) {
430       if (perspectiveSwitcher != null)
431           perspectiveSwitcher.addPerspectiveShortcut(perspective, workbenchPage);
432   }
433   
434   /**
435    * Configures this window to have a perspecive bar.
436    * Does nothing if it already has one.
437    */
438   protected void addPerspectiveBar(int style) {
439       Assert.isTrue(perspectiveSwitcher == null);
440       perspectiveSwitcher = new PerspectiveSwitcher(this, topBar, style);
441   }
442   
443   /**
444    * Close the window.
445    * 
446    * Assumes that busy cursor is active.
447    */
448   private boolean busyClose() {
449     // Whether the window was actually closed or not
450     boolean windowClosed = false;
451 
452     // Setup internal flags to indicate window is in
453     // progress of closing and no update should be done.
454     closing = true;
455     updateDisabled = true;
456 
457     try {
458       // Only do the check if it is OK to close if we are not closing
459       // via the workbench as the workbench will check this itself.
460       Workbench workbench = getWorkbenchImpl();
461       int count = workbench.getWorkbenchWindowCount();
462       //also check for starting - if the first window dies on startup then we'll need to open a default window.
463       if (!workbench.isStarting() && !workbench.isClosing() && count <= 1) {
464         windowClosed = workbench.close();
465       } else {
466         if (okToClose()) {
467           windowClosed = hardClose();
468         }
469       }
470     } finally {
471       if (!windowClosed) {
472         // Reset the internal flags if window was not closed.
473         closing = false;
474         updateDisabled = false;
475       }
476     }
477 
478     return windowClosed;
479   }
480   /**
481    * Opens a new page. Assumes that busy cursor is active.
482    * <p>
483    * <b>Note:</b> Since release 2.0, a window is limited to contain at most
484    * one page. If a page exist in the window when this method is used, then
485    * another window is created for the new page.  Callers are strongly
486    * recommended to use the <code>IWorkbench.openPerspective</code> APIs to
487    * programmatically show a perspective.
488    * </p>
489    */
490   protected IWorkbenchPage busyOpenPage(String perspID, IAdaptable input)
491     throws WorkbenchException {
492     IWorkbenchPage newPage = null;
493 
494     if (pageList.isEmpty()) {
495       newPage = new WorkbenchPage(this, perspID, input);
496       pageList.add(newPage);
497       firePageOpened(newPage);
498       setActivePage(newPage);
499     } else {
500       IWorkbenchWindow window = getWorkbench().openWorkbenchWindow(perspID, input);
501       newPage = window.getActivePage();
502     }
503 
504     return newPage;
505   }
506     
507   /**
508    * @see Window
509    */
510   public int open() {
511       getAdvisor().postWindowCreate(getWindowConfigurer());
512       getAdvisor().openIntro(getWindowConfigurer());
513     int result = super.open();
514     getWorkbenchImpl().fireWindowOpened(this);
515     getAdvisor().postWindowOpen(getWindowConfigurer());
516      if (perspectiveSwitcher != null)
517           perspectiveSwitcher.updatePerspectiveBar();
518     return result;
519   }
520 
521   /* (non-Javadoc)
522    * Method declared on Window.
523    */
524   protected boolean canHandleShellCloseEvent() {
525     if (!super.canHandleShellCloseEvent()) {
526       return false;
527     }
528     // let the advisor veto the user's explicit request to close the window
529     return getAdvisor().preWindowShellClose(getWindowConfigurer());
530   }
531 
532   /**
533    * @see IWorkbenchWindow
534    */
535   public boolean close() {
536     final boolean[] ret = new boolean[1];
537     BusyIndicator.showWhile(null, new Runnable() {
538       public void run() {
539         ret[0] = busyClose();
540       }
541     });
542     return ret[0];
543   }
544 
545   protected boolean isClosing() {
546     return closing || getWorkbenchImpl().isClosing();
547   }
548   /**
549    * Return whether or not the coolbar layout is locked.
550    */
551   protected boolean isCoolBarLocked() {
552     return getCoolBarManager().getLockLayout();
553   }
554 
555   /**
556    * Close all of the pages.
557    */
558   private void closeAllPages() {
559     // Deactivate active page.
560     setActivePage(null);
561 
562     // Clone and deref all so that calls to getPages() returns
563     // empty list (if call by pageClosed event handlers)
564     PageList oldList = pageList;
565     pageList = new PageList();
566 
567     // Close all.
568     Iterator enum = oldList.iterator();
569     while (enum.hasNext()) {
570       WorkbenchPage page = (WorkbenchPage) enum.next();
571       firePageClosed(page);
572       page.dispose();
573     }
574     if (!closing)
575       showEmptyWindowMessage();
576   }
577   /**
578    * Save and close all of the pages.
579    */
580   public void closeAllPages(boolean save) {
581     if (save) {
582       boolean ret = saveAllPages(true);
583       if (!ret)
584         return;
585     }
586     closeAllPages();
587   }
588   /**
589    * closePerspective method comment.
590    */
591   protected boolean closePage(IWorkbenchPage in, boolean save) {
592     // Validate the input.
593     if (!pageList.contains(in))
594       return false;
595     WorkbenchPage oldPage = (WorkbenchPage) in;
596 
597     // Save old perspective.
598     if (save && oldPage.isSaveNeeded()) {
599       if (!oldPage.saveAllEditors(true))
600         return false;
601     }
602 
603     // If old page is activate deactivate.
604     boolean oldIsActive = (oldPage == getActiveWorkbenchPage());
605     if (oldIsActive)
606       setActivePage(null);
607 
608     // Close old page. 
609     pageList.remove(oldPage);
610     firePageClosed(oldPage);
611     oldPage.dispose();
612 
613     // Activate new page.
614     if (oldIsActive) {
615       IWorkbenchPage newPage = pageList.getNextActive();
616       if (newPage != null)
617         setActivePage(newPage);
618     }
619     if (!closing && pageList.isEmpty())
620       showEmptyWindowMessage();
621     return true;
622   }
623   private void showEmptyWindowMessage() {
624     Composite parent = getPageComposite();
625     if (noOpenPerspective == null) {
626       noOpenPerspective = new Label(parent, SWT.NONE);
627       noOpenPerspective.setText(WorkbenchMessages.getString("WorkbenchWindow.noPerspective")); //$NON-NLS-1$
628       noOpenPerspective.setBounds(parent.getClientArea());
629     }
630   }
631 
632   /* (non-Javadoc)
633    * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
634    */
635   protected void configureShell(Shell shell) {
636     super.configureShell(shell);
637 
638     String title = getWindowConfigurer().basicGetTitle();
639     if (title != null) {
640       shell.setText(title);
641     }
642     
643     WorkbenchHelp.setHelp(shell, IHelpContextIds.WORKBENCH_WINDOW);
644         getWorkbench().getContextSupport().registerShell(shell,
645                 IWorkbenchContextSupport.TYPE_WINDOW);
646 
647     trackShellActivation(shell);
648     trackShellResize(shell);
649   }
650 
651   /* (non-Javadoc)
652    * @see org.eclipse.jface.window.ApplicationWindow#createTrimWidgets(org.eclipse.swt.widgets.Shell)
653    */
654   protected void createTrimWidgets(Shell shell) {
655       // do nothing -- trim widgets are created in createDefaultContents
656   }
657 
658   /**
659    * Creates and remembers the client composite, under which workbench
660    * pages create their controls.
661    * 
662    * @since 3.0
663    */
664   protected Composite createPageComposite(Composite parent) {
665       pageComposite = new Composite(parent, SWT.NONE);
666       return pageComposite;
667   }
668   
669   
670     /**
671      * Creates the contents of the workbench window, including
672      * trim controls and the client composite.
673      * This MUST create the client composite via a call to
674      * <code>createClientComposite</code>.
675      * 
676      * @since 3.0
677      */
678     protected Control createContents(Composite parent) {
679         // we know from Window.create that the parent is a Shell.
680         getAdvisor().createWindowContents(getWindowConfigurer(), (Shell) parent);
681         // the page composite must be set by createWindowContents
682         Assert.isNotNull(pageComposite, "createWindowContents must call configurer.createPageComposite"); //$NON-NLS-1$
683         return pageComposite;
684     }
685 
686     /**
687      * If the perspective bar is drawn on the top right corner of the window,
688      * then this method changes its appearance from curved to square. This
689      * should have its own preference, but for now it piggy-backs on the
690      * SHOW_TRADITIONAL_STYLE_TABS preference.
691      * 
692      * @param square
693      *            true for a square banner and false otherwise
694      */
695     public void setBannerCurve(boolean square) {
696         if (topBar != null)
697             topBar.setSimple(square);
698     }
699 
700     /**
701      * Creates the default contents and layout of the shell. 
702      * 
703      * @param shell the shell
704      */
705   protected void createDefaultContents(final Shell shell) {
706     defaultLayout = new TrimLayout();
707     defaultLayout.setSpacing(5, 5, 2, 2);
708     shell.setLayout(defaultLayout);
709       
710       Menu menuBar = getMenuBarManager().createMenuBar(shell);
711       if (getWindowConfigurer().getShowMenuBar()) {
712       shell.setMenuBar(menuBar);
713     }
714       
715       // Create the CBanner widget which parents both the Coolbar
716       // and the perspective switcher, and supports some configurations
717       // on the left right and bottom
718     topBar = new CBanner(shell, SWT.NONE);
719 
720     // the banner gets a curve along with the new tab style
721     // TODO create a dedicated preference for this
722     setBannerCurve(PrefUtil.getAPIPreferenceStore().getBoolean(
723                 IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS));
724 
725     CacheWrapper coolbarCacheWrapper = new CacheWrapper(topBar);
726     
727     final Control coolBar = createCoolBarControl(coolbarCacheWrapper.getControl());
728     // need to resize the shell, not just the coolbar's immediate
729     // parent, if the coolbar wants to grow or shrink
730     
731         coolBar.addListener(SWT.Resize, new Listener() {
732             public void handleEvent(Event event) {
733               // If the user is dragging the sash then we will need to force
734               // a resize. However, if the coolbar was resized programatically
735               // then everything is already layed out correctly. There is no
736               // direct way to tell the difference between these cases, however
737               // we take advantage of the fact that dragging the sash does not
738               // change the size of the shell, and only force another layout
739               // if the shell size is unchanged.
740                 Rectangle clientArea = shell.getClientArea();
741               
742               if (lastShellSize.x == clientArea.width && lastShellSize.y == clientArea.height) {
743                 LayoutUtil.resize(coolBar);
744               }
745               
746             lastShellSize.x = clientArea.width;
747             lastShellSize.y = clientArea.height;
748             }
749         });
750 
751     if (getWindowConfigurer().getShowCoolBar()) {
752       topBar.setLeft(coolbarCacheWrapper.getControl());
753     }
754     
755     createStatusLine(shell);
756     
757     fastViewBar = new FastViewBar(this);
758     fastViewBar.createControl(shell);
759 
760       if (getWindowConfigurer().getShowPerspectiveBar()) {
761       addPerspectiveBar(perspectiveBarStyle());
762       perspectiveSwitcher.createControl(shell);
763       }
764 
765     createProgressIndicator(shell);
766 
767     trimDropTarget = new TrimDropTarget(shell, this);    
768     DragUtil.addDragTarget(shell, trimDropTarget);
769     
770     // Create the client composite area (where page content goes).
771     createPageComposite(shell);
772     
773     setLayoutDataForContents();
774   }
775   
776   public void setPerspectiveBarLocation(String location) {
777       if (perspectiveSwitcher != null)
778           perspectiveSwitcher.setPerspectiveBarLocation(location);
779   }
780 
781   /**
782    * Returns the shortcut for a page.
783    */
784   /* protected */
785   IContributionItem findPerspectiveShortcut(
786     IPerspectiveDescriptor perspective,
787     WorkbenchPage page) {
788         return perspectiveSwitcher == null ? null : perspectiveSwitcher
789                 .findPerspectiveShortcut(perspective, page);
790   }
791   /**
792    * Fires page activated
793    */
794   private void firePageActivated(IWorkbenchPage page) {
795     pageListeners.firePageActivated(page);
796     partService.pageActivated(page);
797   }
798   /**
799    * Fires page closed
800    */
801   private void firePageClosed(IWorkbenchPage page) {
802     pageListeners.firePageClosed(page);
803     partService.pageClosed(page);
804   }
805   /**
806    * Fires page opened
807    */
808   private void firePageOpened(IWorkbenchPage page) {
809     pageListeners.firePageOpened(page);
810     partService.pageOpened(page);
811   }
812   /**
813    * Fires perspective activated
814    */
815   void firePerspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
816     perspectiveListeners.firePerspectiveActivated(page, perspective);
817     perspectiveService.firePerspectiveActivated(page, perspective);
818   }
819   /**
820    * Fires perspective changed
821    */
822   void firePerspectiveChanged(
823     IWorkbenchPage page,
824     IPerspectiveDescriptor perspective,
825     String changeId) {
826     perspectiveListeners.firePerspectiveChanged(page, perspective, changeId);
827     perspectiveService.firePerspectiveChanged(page, perspective, changeId);
828   }
829   /**
830    * Fires perspective changed for an affected part
831    */
832   void firePerspectiveChanged(
833     IWorkbenchPage page,
834     IPerspectiveDescriptor perspective,
835     IWorkbenchPartReference partRef,
836     String changeId) {
837     perspectiveListeners.firePerspectiveChanged(page, perspective, partRef, changeId);
838   }
839   /**
840    * Fires perspective closed
841    */
842   void firePerspectiveClosed(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
843     perspectiveService.firePerspectiveClosed(page, perspective);
844   }
845   /**
846    * Fires perspective opened
847    */
848   void firePerspectiveOpened(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
849     perspectiveService.firePerspectiveOpened(page, perspective);
850   }
851   /**
852    * Returns the action bars for this window.
853    */
854   public WWinActionBars getActionBars() {
855     if (actionBars == null) {
856       actionBars = new WWinActionBars(this);
857     }
858     return actionBars;
859   }
860 
861   /**
862    * Returns the active page.
863    *
864    * @return the active page
865    */
866   public IWorkbenchPage getActivePage() {
867     return pageList.getActive();
868   }
869   /**
870    * Returns the active workbench page.
871    *
872    * @return the active workbench page
873    */
874   /* package */
875   WorkbenchPage getActiveWorkbenchPage() {
876     return pageList.getActive();
877   }
878   /**
879    * Returns the page composite, under which the window's pages create
880    * their controls.
881    */
882   protected Composite getPageComposite() {
883     return pageComposite;
884   }
885   /**
886    * Answer the menu manager for this window.
887    */
888   public MenuManager getMenuManager() {
889     return getMenuBarManager();
890   }
891   /**
892    * Returns the number.  This corresponds to a page number in a window or a
893    * window number in the workbench.
894    */
895   public int getNumber() {
896     return number;
897   }
898   /**
899    * Returns an array of the pages in the workbench window.
900    *
901    * @return an array of pages
902    */
903   public IWorkbenchPage[] getPages() {
904     return pageList.getPages();
905   }
906   /**
907    * @see IWorkbenchWindow
908    */
909   public IPartService getPartService() {
910     return partService;
911   }
912 
913   /**
914    * Returns the layout for the shell.
915    * 
916    * @return the layout for the shell
917    */
918   protected Layout getLayout() {
919     return null;
920   }
921 
922   /**
923    * @see IWorkbenchWindow
924    */
925   public IPerspectiveService getPerspectiveService() {
926     return perspectiveService;
927   }
928 
929   /**
930    * @see IWorkbenchWindow
931    */
932   public ISelectionService getSelectionService() {
933     return partService.getSelectionService();
934   }
935   /**
936    * Returns <code>true</code> when the window's shell
937    * is activated, <code>false</code> when it's shell is
938    * deactivated
939    * 
940    * @return boolean <code>true</code> when shell activated,
941    *     <code>false</code> when shell deactivated
942    */
943   public boolean getShellActivated() {
944     return shellActivated;
945   }
946 
947   /**
948    * Returns the status line manager for this window (if it has one).
949    *
950    * @return the status line manager, or <code>null</code> if
951    *   this window does not have a status line
952    * @see #addStatusLine
953    */
954   public StatusLineManager getStatusLineManager() {
955     return super.getStatusLineManager();
956   }
957 
958   /**
959    * @see IWorkbenchWindow
960    */
961   public IWorkbench getWorkbench() {
962     return PlatformUI.getWorkbench();
963   }
964   public String getToolbarLabel(String actionSetId) {
965     ActionSetRegistry registry = WorkbenchPlugin.getDefault().getActionSetRegistry();
966     IActionSetDescriptor actionSet = registry.findActionSet(actionSetId);
967     if (actionSet != null) {
968       return actionSet.getLabel();
969     } else {
970       if (IWorkbenchActionConstants.TOOLBAR_FILE.equalsIgnoreCase(actionSetId))
971         return WorkbenchMessages.getString("WorkbenchWindow.FileToolbar"); //$NON-NLS-1$
972       if (IWorkbenchActionConstants.TOOLBAR_NAVIGATE.equalsIgnoreCase(actionSetId))
973         return WorkbenchMessages.getString("WorkbenchWindow.NavigateToolbar"); //$NON-NLS-1$
974     }
975     return null;
976   }
977   /**
978    * Unconditionally close this window. Assumes the proper
979    * flags have been set correctly (e.i. closing and updateDisabled)
980    */
981   private boolean hardClose() {
982     boolean result;
983     try {
984       // Clear the action sets, fix for bug 27416.
985       actionPresentation.clearActionSets();
986 
987             // Remove the handler submissions. Bug 64024.
988             final IWorkbench workbench = getWorkbench();
989             final IWorkbenchCommandSupport commandSupport = workbench
990                     .getCommandSupport();
991             commandSupport.removeHandlerSubmissions(handlerSubmissions);
992             final Iterator submissionItr = handlerSubmissions.iterator();
993             while (submissionItr.hasNext()) {
994                 final HandlerSubmission submission = (HandlerSubmission) submissionItr
995                         .next();
996                 submission.getHandler().dispose();
997             }
998             handlerSubmissions.clear();
999             actionSetHandlersByCommandId.clear();
1000            globalActionHandlersByCommandId.clear();
1001
1002            // Remove the enabled submissions. Bug 64024.
1003            final IWorkbenchContextSupport contextSupport = workbench
1004                    .getContextSupport();
1005            contextSupport.unregisterShell(getShell());
1006      
1007      closeAllPages();
1008      // let the application do further deconfiguration
1009      getAdvisor().postWindowClose(getWindowConfigurer());
1010      getWorkbenchImpl().fireWindowClosed(this);
1011            
1012            // Null out the progress region.  Bug 64024.
1013            progressRegion = null;
1014    } finally {
1015      result = super.close();
1016    }
1017    return result;
1018  }
1019  /**
1020   * @see IWorkbenchWindow
1021   */
1022  public boolean isApplicationMenu(String menuID) {
1023    // delegate this question to the workbench advisor
1024    return getAdvisor().isApplicationMenu(getWindowConfigurer(), menuID);
1025  }
1026
1027  /**
1028   * Return whether or not the given id matches the id of the coolitems that
1029   * the application creates.
1030   */
1031  /* package */
1032  boolean isWorkbenchCoolItemId(String id) {
1033    return windowConfigurer.containsCoolItem(id);
1034  }
1035  /**
1036   * Locks/unlocks the CoolBar for the workbench.
1037   * 
1038   * @param lock whether the CoolBar should be locked or unlocked
1039   */
1040  /* package */
1041  void lockCoolBar(boolean lock) {
1042    getCoolBarManager().setLockLayout(lock);
1043  }
1044  /**
1045   * Called when this window is about to be closed.
1046   *
1047   * Subclasses may overide to add code that returns <code>false</code> 
1048   * to prevent closing under certain conditions.
1049   */
1050  public boolean okToClose() {
1051    // Save all of the editors.
1052    if (!getWorkbenchImpl().isClosing())
1053      if (!saveAllPages(true))
1054        return false;
1055    return true;
1056  }
1057  /**
1058   * Opens a new page.
1059   * <p>
1060   * <b>Note:</b> Since release 2.0, a window is limited to contain at most
1061   * one page. If a page exist in the window when this method is used, then
1062   * another window is created for the new page.  Callers are strongly
1063   * recommended to use the <code>IWorkbench.openPerspective</code> APIs to
1064   * programmatically show a perspective.
1065   * </p>
1066   */
1067  public IWorkbenchPage openPage(final String perspId, final IAdaptable input)
1068    throws WorkbenchException {
1069    Assert.isNotNull(perspId);
1070
1071    // Run op in busy cursor.
1072    final Object[] result = new Object[1];
1073    BusyIndicator.showWhile(null, new Runnable() {
1074      public void run() {
1075        try {
1076          result[0] = busyOpenPage(perspId, input);
1077        } catch (WorkbenchException e) {
1078          result[0] = e;
1079        }
1080      }
1081    });
1082
1083    if (result[0] instanceof IWorkbenchPage)
1084      return (IWorkbenchPage) result[0];
1085    else if (result[0] instanceof WorkbenchException)
1086      throw (WorkbenchException) result[0];
1087    else
1088      throw new WorkbenchException(WorkbenchMessages.getString("WorkbenchWindow.exceptionMessage")); //$NON-NLS-1$
1089  }
1090  /**
1091   * Opens a new page. 
1092   * <p>
1093   * <b>Note:</b> Since release 2.0, a window is limited to contain at most
1094   * one page. If a page exist in the window when this method is used, then
1095   * another window is created for the new page.  Callers are strongly
1096   * recommended to use the <code>IWorkbench.openPerspective</code> APIs to
1097   * programmatically show a perspective.
1098   * </p>
1099   */
1100  public IWorkbenchPage openPage(IAdaptable input) throws WorkbenchException {
1101    String perspId = getWorkbenchImpl().getPerspectiveRegistry().getDefaultPerspective();
1102    return openPage(perspId, input);
1103  }
1104
1105  /*
1106   * Removes an listener from the part service.
1107   */
1108  public void removePageListener(IPageListener l) {
1109    pageListeners.removePageListener(l);
1110  }
1111  /*
1112   * Removes an listener from the perspective service.
1113   *
1114   * NOTE: Internally, please use getPerspectiveService instead.
1115   */
1116  public void removePerspectiveListener(org.eclipse.ui.IPerspectiveListener l) {
1117    perspectiveListeners.removePerspectiveListener(l);
1118  }
1119  /**
1120   * Remove the shortcut for a page.
1121   */
1122  /* package */
1123  void removePerspectiveShortcut(IPerspectiveDescriptor perspective, WorkbenchPage page) {
1124    if (perspectiveSwitcher != null)
1125        perspectiveSwitcher.removePerspectiveShortcut(perspective, page);
1126  }
1127  private IStatus unableToRestorePage(IMemento pageMem) {
1128    String pageName = pageMem.getString(IWorkbenchConstants.TAG_LABEL);
1129    if (pageName == null)
1130      pageName = ""; //$NON-NLS-1$
1131    return new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, WorkbenchMessages.format("WorkbenchWindow.unableToRestorePerspective", new String[] { pageName }), //$NON-NLS-1$
1132    null);
1133  }
1134  /**
1135   * @see IPersistable.
1136   */
1137  public IStatus restoreState(IMemento memento, IPerspectiveDescriptor activeDescriptor) {
1138    Assert.isNotNull(getShell());
1139
1140    MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, WorkbenchMessages.getString("WorkbenchWindow.problemsRestoringWindow"), null); //$NON-NLS-1$
1141
1142    // Read window's bounds and state.
1143    Rectangle displayBounds = getShell().getDisplay().getBounds();
1144    Rectangle shellBounds = new Rectangle(0, 0, 0, 0);
1145    
1146    IMemento fastViewMem = memento.getChild(IWorkbenchConstants.TAG_FAST_VIEW_DATA);
1147    if (fastViewMem != null) {
1148        if (fastViewBar != null) {
1149            fastViewBar.restoreState(fastViewMem);
1150        }
1151    }
1152    Integer bigInt = memento.getInteger(IWorkbenchConstants.TAG_X);
1153    shellBounds.x = bigInt == null ? 0 : bigInt.intValue();
1154    bigInt = memento.getInteger(IWorkbenchConstants.TAG_Y);
1155    shellBounds.y = bigInt == null ? 0 : bigInt.intValue();
1156    bigInt = memento.getInteger(IWorkbenchConstants.TAG_WIDTH);
1157    shellBounds.width = bigInt == null ? 0 : bigInt.intValue();
1158    bigInt = memento.getInteger(IWorkbenchConstants.TAG_HEIGHT);
1159    shellBounds.height = bigInt == null ? 0 : bigInt.intValue();
1160    if (!shellBounds.isEmpty()) {
1161      if (!shellBounds.intersects(displayBounds)) {
1162        Rectangle clientArea = getShell().getDisplay().getClientArea();
1163        shellBounds.x = clientArea.x;
1164        shellBounds.y = clientArea.y;
1165      }
1166      getShell().setBounds(shellBounds);
1167    }
1168    if ("true".equals(memento.getString(IWorkbenchConstants.TAG_MAXIMIZED))) { //$NON-NLS-1$
1169      getShell().setMaximized(true);
1170    }
1171    if ("true".equals(memento.getString(IWorkbenchConstants.TAG_MINIMIZED))) { //$NON-NLS-1$
1172      //    getShell().setMinimized(true);
1173    }
1174
1175    // restore the width of the perspective bar
1176    if (perspectiveSwitcher != null) 
1177      perspectiveSwitcher.restoreState(memento);
1178    
1179    // Restore the cool bar order by creating all the tool bar contribution items
1180    // This needs to be done before pages are created to ensure proper canonical creation
1181    // of cool items
1182    if (getCoolBarManager() != null) {
1183      CoolBarManager coolBarMgr = getCoolBarManager();
1184      IMemento coolBarMem = memento.getChild(IWorkbenchConstants.TAG_COOLBAR_LAYOUT);
1185      if (coolBarMem != null) {
1186        // Check if the layout is locked
1187        Integer lockedInt = coolBarMem.getInteger(IWorkbenchConstants.TAG_LOCKED);
1188        if ((lockedInt != null) && (lockedInt.intValue() == 1)) {
1189          coolBarMgr.setLockLayout(true);
1190        }else {
1191          coolBarMgr.setLockLayout(false);
1192        }
1193        // The new layout of the cool bar manager
1194        ArrayList coolBarLayout = new ArrayList();
1195        // Traverse through all the cool item in the memento
1196        IMemento contributionMems[] =
1197          coolBarMem.getChildren(IWorkbenchConstants.TAG_COOLITEM);
1198        for (int i = 0; i < contributionMems.length; i++) {
1199          IMemento contributionMem = contributionMems[i];
1200          String type = contributionMem.getString(IWorkbenchConstants.TAG_ITEM_TYPE);
1201          if (type == null) {
1202            // Do not recognize that type
1203            continue;
1204          }
1205          String id = contributionMem.getString(IWorkbenchConstants.TAG_ID);
1206          
1207          // Prevent duplicate items from being read back in.
1208          IContributionItem existingItem = coolBarMgr.find(id);
1209          if ((id != null) && (existingItem != null)) {
1210              if (Policy.DEBUG_TOOLBAR_DISPOSAL) {
1211                  System.out.println("Not loading duplicate cool bar item: " + id); //$NON-NLS-1$
1212              }
1213              coolBarLayout.add(existingItem);
1214              continue;
1215          }
1216          IContributionItem newItem = null;
1217          if (type.equals(IWorkbenchConstants.TAG_TYPE_SEPARATOR)) {
1218            if (id != null) {
1219              newItem = new Separator(id);
1220            } else {
1221              newItem = new Separator();
1222            }
1223          } else if (id != null) {
1224              if (type.equals(IWorkbenchConstants.TAG_TYPE_GROUPMARKER)) {
1225            newItem = new GroupMarker(id);
1226
1227              } else if (type.equals(IWorkbenchConstants.TAG_TYPE_TOOLBARCONTRIBUTION) 
1228                      || type.equals(IWorkbenchConstants.TAG_TYPE_PLACEHOLDER)) {
1229
1230            // Get Width and height
1231            Integer width = contributionMem.getInteger(IWorkbenchConstants.TAG_ITEM_X);
1232            Integer height = contributionMem.getInteger(IWorkbenchConstants.TAG_ITEM_Y);
1233            // Look for the object in the current cool bar manager
1234            IContributionItem oldItem = coolBarMgr.find(id);
1235            // If a tool bar contribution item already exists for this id then use the old object
1236                  if (oldItem != null) {
1237                      newItem = oldItem;
1238            } else {
1239              newItem =
1240                new ToolBarContributionItem(
1241                    new ToolBarManager(coolBarMgr.getStyle()),
1242                    id);
1243                      if (type.equals(IWorkbenchConstants.TAG_TYPE_PLACEHOLDER)) {
1244                          ToolBarContributionItem newToolBarItem = (ToolBarContributionItem) newItem;
1245                          if (height != null) {
1246                              newToolBarItem.setCurrentHeight(height.intValue());
1247                          }
1248                          if (width != null) {
1249                              newToolBarItem.setCurrentWidth(width.intValue());
1250                          }
1251                          newItem = new PlaceholderContributionItem(newToolBarItem);
1252                      }
1253              // make it invisible by default
1254              newItem.setVisible(false);
1255              // Need to add the item to the cool bar manager so that its canonical order can be preserved
1256              IContributionItem refItem =
1257                findAlphabeticalOrder(
1258                    IWorkbenchActionConstants.MB_ADDITIONS,
1259                    id,
1260                    coolBarMgr);
1261              if (refItem != null) {
1262                coolBarMgr.insertAfter(refItem.getId(), newItem);
1263              }else {
1264                coolBarMgr.add(newItem);
1265              }
1266            }
1267            // Set the current height and width
1268                  if ((width != null) && (newItem instanceof ToolBarContributionItem)) {
1269              ((ToolBarContributionItem) newItem).setCurrentWidth(width.intValue());
1270            }
1271                  if ((height != null) && (newItem instanceof ToolBarContributionItem)) {
1272              ((ToolBarContributionItem) newItem).setCurrentHeight(height.intValue());
1273            }
1274          }
1275          }
1276          // Add new item into cool bar manager
1277          if (newItem != null) {
1278            coolBarLayout.add(newItem);
1279            newItem.setParent(coolBarMgr);
1280            coolBarMgr.markDirty();
1281          }
1282        }
1283        
1284        // We need to check if we have everything we need in the layout.
1285        final ArrayList finalLayout = new ArrayList();
1286        IContributionItem[] existingItems = coolBarMgr.getItems();
1287        for (int i = 0; i < existingItems.length; i++) {
1288              IContributionItem existingItem = existingItems[i];
1289              
1290              /* This line shouldn't be necessary, but is here for
1291               * robustness.
1292               */
1293              if (existingItem == null) {
1294                  continue;
1295              }
1296              
1297            boolean found = false;
1298            Iterator layoutItemItr = coolBarLayout.iterator();
1299            while (layoutItemItr.hasNext()) {
1300                IContributionItem layoutItem = (IContributionItem) layoutItemItr.next();
1301                if ((layoutItem != null) && (layoutItem.equals(existingItem))) {
1302                    found = true;
1303                    break;
1304                }
1305            }
1306            
1307            if (!found) {
1308                if (existingItem != null) {
1309                    finalLayout.add(existingItem);
1310                }
1311            }
1312        }
1313        
1314        // Set the cool bar layout to the given layout.
1315        finalLayout.addAll(coolBarLayout);
1316            IContributionItem[] itemsToSet = new IContributionItem[finalLayout.size()];
1317            finalLayout.toArray(itemsToSet);
1318        coolBarMgr.setItems(itemsToSet);
1319      } else {
1320        // For older workbenchs
1321        coolBarMem = memento.getChild(IWorkbenchConstants.TAG_TOOLBAR_LAYOUT);
1322        if (coolBarMem != null) {
1323          // Restore an older layout
1324          restoreOldCoolBar(coolBarMem);
1325        }
1326      }
1327    }
1328
1329    // Recreate each page in the window. 
1330    IWorkbenchPage newActivePage = null;
1331    IMemento[] pageArray = memento.getChildren(IWorkbenchConstants.TAG_PAGE);
1332    for (int i = 0; i < pageArray.length; i++) {
1333      IMemento pageMem = pageArray[i];
1334      String strFocus = pageMem.getString(IWorkbenchConstants.TAG_FOCUS);
1335      if (strFocus == null || strFocus.length() == 0)
1336        continue;
1337
1338      // Get the input factory.
1339      IAdaptable input = null;
1340      IMemento inputMem = pageMem.getChild(IWorkbenchConstants.TAG_INPUT);
1341      if (inputMem != null) {
1342        String factoryID = inputMem.getString(IWorkbenchConstants.TAG_FACTORY_ID);
1343        if (factoryID == null) {
1344          WorkbenchPlugin.log("Unable to restore page - no input factory ID."); //$NON-NLS-1$
1345          result.add(unableToRestorePage(pageMem));
1346          continue;
1347        }
1348        try {
1349          UIStats.start(UIStats.RESTORE_WORKBENCH, "WorkbenchPageFactory"); //$NON-NLS-1$
1350          IElementFactory factory = PlatformUI.getWorkbench().getElementFactory(factoryID);
1351          if (factory == null) {
1352            WorkbenchPlugin.log("Unable to restore page - cannot instantiate input factory: " + factoryID); //$NON-NLS-1$
1353            result.add(unableToRestorePage(pageMem));
1354            continue;
1355          }
1356  
1357          // Get the input element.
1358          input = factory.createElement(inputMem);
1359          if (input == null) {
1360            WorkbenchPlugin.log("Unable to restore page - cannot instantiate input element: " + factoryID); //$NON-NLS-1$
1361            result.add(unableToRestorePage(pageMem));
1362            continue;
1363          }
1364        } finally {
1365          UIStats.end(UIStats.RESTORE_WORKBENCH, "WorkbenchPageFactory"); //$NON-NLS-1$
1366        }
1367      }
1368      // Open the perspective.
1369      WorkbenchPage newPage = null;
1370      try {
1371        newPage = new WorkbenchPage(this, input);
1372        result.add(newPage.restoreState(pageMem, activeDescriptor));
1373        pageList.add(newPage);
1374        firePageOpened(newPage);
1375      } catch (WorkbenchException e) {
1376        WorkbenchPlugin.log("Unable to restore perspective - constructor failed."); //$NON-NLS-1$
1377        result.add(e.getStatus());
1378        continue;
1379      }
1380
1381      if (strFocus != null && strFocus.length() > 0)
1382        newActivePage = newPage;
1383    }
1384
1385    // If there are no pages create a default.
1386    if (pageList.isEmpty()) {
1387      try {
1388        String defPerspID =
1389          getWorkbenchImpl().getPerspectiveRegistry().getDefaultPerspective();
1390        WorkbenchPage newPage =
1391          new WorkbenchPage(this, defPerspID, getAdvisor().getDefaultPageInput());
1392        pageList.add(newPage);
1393        firePageOpened(newPage);
1394      } catch (WorkbenchException e) {
1395        WorkbenchPlugin.log("Unable to create default perspective - constructor failed."); //$NON-NLS-1$
1396        result.add(e.getStatus());
1397        String productName = WorkbenchPlugin.getDefault().getProductName();
1398        if (productName == null) {
1399          productName = ""; //$NON-NLS-1$
1400        }
1401        getShell().setText(productName);
1402      }
1403    }
1404
1405    // Set active page.
1406    if (newActivePage == null)
1407      newActivePage = pageList.getNextActive();
1408
1409    setActivePage(newActivePage);
1410    
1411    IMemento introMem = memento.getChild(IWorkbenchConstants.TAG_INTRO);
1412    if (introMem != null) {
1413        getWorkbench().getIntroManager().showIntro(this, Boolean.valueOf(introMem.getString(IWorkbenchConstants.TAG_STANDBY)).booleanValue());
1414    }
1415    return result;
1416  }
1417  
1418  /**
1419   * Restores cool item order from an old workbench.
1420   */
1421  private boolean restoreOldCoolBar(IMemento coolbarMem) {
1422    // Make sure the tag exist
1423    if (coolbarMem == null) {
1424      return false;
1425    }
1426    CoolBarManager coolBarMgr = getCoolBarManager();
1427    // Check to see if layout is locked
1428    Integer locked = coolbarMem.getInteger(IWorkbenchConstants.TAG_LOCKED);
1429    boolean state = (locked != null) && (locked.intValue() == 1);
1430    coolBarMgr.setLockLayout(state);
1431    
1432    // Get the visual layout
1433    IMemento visibleLayout = coolbarMem.getChild(IWorkbenchConstants.TAG_TOOLBAR_LAYOUT);
1434    ArrayList visibleWrapIndicies = new ArrayList();
1435    ArrayList visibleItems = new ArrayList();
1436    if (visibleLayout != null) {
1437      if (readLayout(visibleLayout,visibleItems,visibleWrapIndicies) == false ) {
1438        return false;
1439      }  
1440    }
1441    // Get the remembered layout
1442    IMemento rememberedLayout = coolbarMem.getChild(IWorkbenchConstants.TAG_LAYOUT);
1443    ArrayList rememberedWrapIndicies = new ArrayList();
1444    ArrayList rememberedItems = new ArrayList();
1445    if (rememberedLayout != null) {
1446      if (readLayout(rememberedLayout,rememberedItems,rememberedWrapIndicies) == false ) {
1447        return false;
1448      }  
1449    }
1450
1451    // Create the objects
1452    if (visibleItems != null) {
1453      // Merge remembered layout into visible layout
1454      if (rememberedItems != null) {    
1455        // Traverse through all the remembered items
1456        int currentIndex = 0;
1457        for (Iterator i = rememberedItems.iterator(); i.hasNext();currentIndex++) {
1458          String id = (String)i.next();
1459          int index = -1;
1460          for(Iterator iter=visibleItems.iterator();iter.hasNext();) {
1461            String visibleId = (String)iter.next();
1462            if (visibleId.equals(id)) {
1463              index = visibleItems.indexOf(visibleId);
1464              break;
1465            }
1466          }
1467          // The item is not in the visible list
1468          if (index == -1) {
1469            int insertAt = Math.max(0,Math.min(currentIndex,visibleItems.size()));
1470            boolean separateLine = false;
1471            // Check whether this item is on a separate line
1472            for(Iterator iter=rememberedWrapIndicies.iterator();iter.hasNext();) {
1473              Integer wrapIndex = (Integer)iter.next();
1474              if (wrapIndex.intValue() <= insertAt) {
1475                insertAt = visibleItems.size();
1476                // Add new wrap index for this Item
1477                visibleWrapIndicies.add(new Integer(insertAt));
1478                separateLine = true;
1479              }
1480            }
1481            // Add item to array list
1482            visibleItems.add(insertAt,id);
1483            // If the item was not on a separate line then adjust the visible wrap indicies
1484            if (!separateLine) {
1485              // Adjust visible wrap indicies
1486              for(int j=0; j < visibleWrapIndicies.size();j++) {
1487                Integer index2 = (Integer)visibleWrapIndicies.get(j);
1488                if (index2.intValue() >= insertAt) {
1489                  visibleWrapIndicies.set(j, new Integer(index2.intValue() + 1));        
1490                }
1491              }
1492            }
1493          }
1494        }
1495      }
1496      // The new layout of the cool bar manager
1497      ArrayList coolBarLayout = new ArrayList(visibleItems.size());
1498      // Add all visible items to the layout object
1499      for (Iterator i = visibleItems.iterator(); i.hasNext();) {
1500        String id = (String)i.next();
1501        // Look for the object in the current cool bar manager
1502        IContributionItem oldItem = null;
1503        IContributionItem newItem = null;
1504        if (id != null) {
1505          oldItem = coolBarMgr.find(id);
1506        }
1507        // If a tool bar contribution item already exists for this id then use the old object
1508        if (oldItem instanceof ToolBarContributionItem) {
1509          newItem = (ToolBarContributionItem) oldItem;
1510        } else {
1511          newItem =
1512            new ToolBarContributionItem(
1513                new ToolBarManager(coolBarMgr.getStyle()),
1514                id);
1515          // make it invisible by default
1516          newItem.setVisible(false);
1517          // Need to add the item to the cool bar manager so that its canonical order can be preserved
1518          IContributionItem refItem =
1519            findAlphabeticalOrder(
1520                IWorkbenchActionConstants.MB_ADDITIONS,
1521                id,
1522                coolBarMgr);
1523          if (refItem != null) {
1524            coolBarMgr.insertAfter(refItem.getId(), newItem);
1525          }else {
1526            coolBarMgr.add(newItem);
1527          }
1528        }
1529        // Add new item into cool bar manager
1530        if (newItem != null) {
1531          coolBarLayout.add(newItem);
1532          newItem.setParent(coolBarMgr);
1533          coolBarMgr.markDirty();
1534        }
1535      }
1536      
1537      // Add separators to the displayed Items data structure
1538      int offset = 0;
1539      for(int i=1; i < visibleWrapIndicies.size(); i++) {
1540        int insertAt = ((Integer)visibleWrapIndicies.get(i)).intValue() + offset;
1541        coolBarLayout.add(insertAt,new Separator(CoolBarManager.USER_SEPARATOR));
1542        offset++;
1543      }
1544      
1545      // Add any group markers in their appropriate places
1546      IContributionItem[] items = coolBarMgr.getItems();
1547      for (int i=0; i < items.length; i++) {
1548        IContributionItem item = items[i];
1549        if (item.isGroupMarker()) {
1550          coolBarLayout.add(Math.max(Math.min(i,coolBarLayout.size()), 0),item);
1551        }
1552      }
1553          IContributionItem[] itemsToSet = new IContributionItem[coolBarLayout.size()];
1554          coolBarLayout.toArray(itemsToSet);
1555      coolBarMgr.setItems(itemsToSet);
1556    }
1557    return true;
1558  }
1559  
1560  /**
1561   * Helper method used for restoring an old cool bar layout. This method reads the memento
1562   * and populatates the item id's and wrap indicies.
1563   */
1564  private boolean readLayout(IMemento memento, ArrayList itemIds, ArrayList wrapIndicies) {
1565    // Get the Wrap indicies
1566    IMemento [] wraps = memento.getChildren(IWorkbenchConstants.TAG_ITEM_WRAP_INDEX);
1567    if (wraps == null) return false;
1568    for (int i = 0; i < wraps.length; i++) {
1569      IMemento wrapMem = wraps[i];
1570      Integer index = wrapMem.getInteger(IWorkbenchConstants.TAG_INDEX);
1571      if (index == null) return false;
1572      wrapIndicies.add(index);
1573    }
1574    // Get the Item ids
1575    IMemento [] savedItems = memento.getChildren(IWorkbenchConstants.TAG_ITEM);
1576    if (savedItems == null) return false;
1577    for (int i = 0; i < savedItems.length; i++) {
1578      IMemento savedMem = savedItems[i];
1579      String id = savedMem.getString(IWorkbenchConstants.TAG_ID);
1580      if (id == null) return false;
1581      itemIds.add(id);
1582    }
1583    return true;
1584  }
1585
1586  /**
1587   * Returns the contribution item that the given contribution item should be inserted after.
1588   * 
1589   * @param startId the location to start looking alphabetically.
1590   * @param itemId the target item id.
1591   * @param mgr the contribution manager.
1592   * @return the contribution item that the given items should be returned after.
1593   */
1594  private IContributionItem findAlphabeticalOrder(
1595    String startId,
1596    String itemId,
1597    IContributionManager mgr) {
1598    IContributionItem[] items = mgr.getItems();
1599    int insertIndex = 0;
1600
1601    // look for starting point
1602    while (insertIndex < items.length) {
1603      IContributionItem item = items[insertIndex];
1604      if (item.getId() != null && item.getId().equals(startId))
1605        break;
1606      ++insertIndex;
1607    }
1608
1609    // Find the index that this item should be inserted in
1610    for (int i = insertIndex + 1; i < items.length; i++) {
1611      IContributionItem item = items[i];
1612      String testId = item.getId();
1613
1614      if (item.isGroupMarker())
1615        break;
1616
1617      if (itemId != null && testId != null) {
1618        if (itemId.compareTo(testId) < 1)
1619          break;
1620      }
1621      insertIndex = i;
1622    }
1623    if ( insertIndex >= items.length) {
1624      return null;
1625    }
1626    return items[insertIndex];
1627  }
1628
1629  /* (non-Javadoc)
1630   * Method declared on IRunnableContext.
1631   */
1632  public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable)
1633    throws InvocationTargetException, InterruptedException {
1634    IWorkbenchContextSupport contextSupport = getWorkbench().getContextSupport();
1635    final boolean keyFilterEnabled = contextSupport.isKeyFilterEnabled();
1636
1637    Control fastViewBarControl = getFastViewBar() == null ? null : getFastViewBar().getControl();
1638    boolean fastViewBarWasEnabled = fastViewBarControl == null ? false : fastViewBarControl.getEnabled();
1639
1640    Control perspectiveBarControl = getPerspectiveBar() == null ? null : getPerspectiveBar().getControl();
1641    boolean perspectiveBarWasEnabled = perspectiveBarControl == null ? false : perspectiveBarControl.getEnabled();
1642
1643    try {
1644      if (fastViewBarControl != null && !fastViewBarControl.isDisposed())
1645          fastViewBarControl.setEnabled(false);
1646
1647      if (perspectiveBarControl != null && !perspectiveBarControl.isDisposed())
1648          perspectiveBarControl.setEnabled(false);
1649
1650      if (keyFilterEnabled)
1651        contextSupport.setKeyFilterEnabled(false);
1652
1653      super.run(fork, cancelable, runnable);
1654    } finally {
1655      if (fastViewBarControl != null && !fastViewBarControl.isDisposed())
1656          fastViewBarControl.setEnabled(fastViewBarWasEnabled);
1657
1658      if (perspectiveBarControl != null && !perspectiveBarControl.isDisposed())
1659          perspectiveBarControl.setEnabled(perspectiveBarWasEnabled);
1660
1661      if (keyFilterEnabled)
1662        contextSupport.setKeyFilterEnabled(true);
1663    }
1664  }
1665  /**
1666   * Save all of the pages.  Returns true if the operation succeeded.
1667   */
1668  private boolean saveAllPages(boolean bConfirm) {
1669    boolean bRet = true;
1670    Iterator enum = pageList.iterator();
1671    while (bRet && enum.hasNext()) {
1672      WorkbenchPage page = (WorkbenchPage) enum.next();
1673      bRet = page.saveAllEditors(bConfirm);
1674    }
1675    return bRet;
1676  }
1677  /**
1678   * @see IPersistable
1679   */
1680  public IStatus saveState(IMemento memento) {
1681
1682    MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, WorkbenchMessages.getString("WorkbenchWindow.problemsSavingWindow"), null); //$NON-NLS-1$
1683
1684    // Save the window's state and bounds.
1685    if (getShell().getMaximized() || asMaximizedState) {
1686      memento.putString(IWorkbenchConstants.TAG_MAXIMIZED, "true"); //$NON-NLS-1$
1687    }
1688    if (getShell().getMinimized()) {
1689      memento.putString(IWorkbenchConstants.TAG_MINIMIZED, "true"); //$NON-NLS-1$
1690    }
1691    if (normalBounds == null) {
1692      normalBounds = getShell().getBounds();
1693    }
1694    IMemento fastViewBarMem = memento.createChild(IWorkbenchConstants.TAG_FAST_VIEW_DATA);
1695    if (fastViewBar != null) {
1696        fastViewBar.saveState(fastViewBarMem);
1697    }
1698    
1699    memento.putInteger(IWorkbenchConstants.TAG_X, normalBounds.x);
1700    memento.putInteger(IWorkbenchConstants.TAG_Y, normalBounds.y);
1701    memento.putInteger(IWorkbenchConstants.TAG_WIDTH, normalBounds.width);
1702    memento.putInteger(IWorkbenchConstants.TAG_HEIGHT, normalBounds.height);
1703
1704    IWorkbenchPage activePage = getActivePage();
1705    if (activePage != null && activePage.findView(IIntroConstants.INTRO_VIEW_ID) != null) {
1706      IMemento introMem = memento.createChild(IWorkbenchConstants.TAG_INTRO);
1707      introMem.putString(
1708              IWorkbenchConstants.TAG_STANDBY, 
1709              Boolean.valueOf(
1710                      getWorkbench()
1711                      .getIntroManager()
1712                      .isIntroStandby(
1713                              getWorkbench()
1714                              .getIntroManager()
1715                              .getIntro())).toString());
1716    }        
1717    
1718    // save the width of the perspective bar
1719    IMemento persBarMem = memento.createChild(IWorkbenchConstants.TAG_PERSPECTIVE_BAR);
1720    if (perspectiveSwitcher != null) {
1721        perspectiveSwitcher.saveState(persBarMem);
1722    }
1723    
1724    /// Save the order of the cool bar contribution items
1725    if (getCoolBarManager() != null) {
1726      getCoolBarManager().refresh();
1727      IMemento coolBarMem = memento.createChild(IWorkbenchConstants.TAG_COOLBAR_LAYOUT);
1728      if (getCoolBarManager().getLockLayout() == true) {
1729        coolBarMem.putInteger(IWorkbenchConstants.TAG_LOCKED,1);
1730      }else {
1731        coolBarMem.putInteger(IWorkbenchConstants.TAG_LOCKED,0);
1732      }
1733      IContributionItem[] items = getCoolBarManager().getItems();
1734      for (int i = 0; i < items.length; i++) {
1735        IMemento coolItemMem = coolBarMem.createChild(IWorkbenchConstants.TAG_COOLITEM);
1736        IContributionItem item = items[i];
1737        // The id of the contribution item
1738        if (item.getId() != null) {
1739          coolItemMem.putString(IWorkbenchConstants.TAG_ID, item.getId());
1740        }
1741        // Write out type and size if applicable
1742        if (item.isSeparator()) {
1743          coolItemMem.putString(
1744              IWorkbenchConstants.TAG_ITEM_TYPE,
1745              IWorkbenchConstants.TAG_TYPE_SEPARATOR);
1746        } else if (item.isGroupMarker() && !item.isSeparator()) {
1747          coolItemMem.putString(
1748              IWorkbenchConstants.TAG_ITEM_TYPE,
1749              IWorkbenchConstants.TAG_TYPE_GROUPMARKER);
1750        } else {
1751            if (item instanceof PlaceholderContributionItem) {
1752          coolItemMem.putString(
1753              IWorkbenchConstants.TAG_ITEM_TYPE,
1754                        IWorkbenchConstants.TAG_TYPE_PLACEHOLDER);
1755            } else {
1756                // Store the identifier.
1757                coolItemMem.putString(
1758                        IWorkbenchConstants.TAG_ITEM_TYPE,
1759              IWorkbenchConstants.TAG_TYPE_TOOLBARCONTRIBUTION);
1760        }
1761          
1762          /* Retrieve a reasonable approximation of the height and
1763           * width, if possible.
1764           */
1765          final int height;
1766          final int width;
1767          if (item instanceof ToolBarContributionItem) {
1768              ToolBarContributionItem toolBarItem = (ToolBarContributionItem) item;
1769              toolBarItem.saveWidgetState();
1770              height = toolBarItem.getCurrentHeight();
1771              width = toolBarItem.getCurrentWidth();
1772          } else if (item instanceof PlaceholderContributionItem) {
1773              PlaceholderContributionItem placeholder = (PlaceholderContributionItem) item;
1774              height = placeholder.getHeight();
1775              width = placeholder.getWidth();
1776          } else {
1777              height = -1;
1778              width = -1;
1779      }
1780          
1781          // Store the height and width.
1782          coolItemMem.putInteger(IWorkbenchConstants.TAG_ITEM_X, width);
1783          coolItemMem.putInteger(IWorkbenchConstants.TAG_ITEM_Y, height); 
1784    }
1785      }
1786    }
1787    
1788
1789    // Save each page.
1790    Iterator enum = pageList.iterator();
1791    while (enum.hasNext()) {
1792      WorkbenchPage page = (WorkbenchPage) enum.next();
1793
1794      // Save perspective.
1795      IMemento pageMem = memento.createChild(IWorkbenchConstants.TAG_PAGE);
1796      pageMem.putString(IWorkbenchConstants.TAG_LABEL, page.getLabel());
1797      result.add(page.saveState(pageMem));
1798      
1799      if (page == getActiveWorkbenchPage()) {
1800        pageMem.putString(IWorkbenchConstants.TAG_FOCUS, "true"); //$NON-NLS-1$
1801      }
1802
1803      // Get the input.
1804      IAdaptable input = page.getInput();
1805      if (input != null) {
1806        IPersistableElement persistable =
1807          (IPersistableElement) input.getAdapter(IPersistableElement.class);
1808        if (persistable == null) {
1809          WorkbenchPlugin.log(
1810            "Unable to save page input: " //$NON-NLS-1$
1811              + input
1812              + ", because it does not adapt to IPersistableElement"); //$NON-NLS-1$
1813        }
1814        else {
1815          // Save input.  
1816          IMemento inputMem = pageMem.createChild(IWorkbenchConstants.TAG_INPUT);
1817          inputMem.putString(IWorkbenchConstants.TAG_FACTORY_ID, persistable.getFactoryId());
1818          persistable.saveState(inputMem);
1819        }
1820      }
1821    }
1822    return result;
1823  }
1824  /**
1825   * Select the shortcut for a perspective.
1826   */
1827  /* package */
1828  void selectPerspectiveShortcut(
1829    IPerspectiveDescriptor perspective,
1830    WorkbenchPage page,
1831    boolean selected) {
1832      if (perspectiveSwitcher != null)
1833          perspectiveSwitcher.selectPerspectiveShortcut(perspective, page, selected);
1834  }
1835  /**
1836   * Sets the active page within the window.
1837   *
1838   * @param page identifies the new active page.
1839   */
1840  public void setActivePage(final IWorkbenchPage in) {
1841    if (getActiveWorkbenchPage() == in)
1842      return;
1843
1844    // 1FVGTNR: ITPUI:WINNT - busy cursor for switching perspectives
1845    BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
1846      public void run() {
1847        // Deactivate old persp.
1848        WorkbenchPage currentPage = getActiveWorkbenchPage();
1849        if (currentPage != null) {
1850          currentPage.onDeactivate();
1851        }
1852
1853        // Activate new persp.
1854        if (in == null || pageList.contains(in))
1855          pageList.setActive(in);
1856        WorkbenchPage newPage = pageList.getActive();
1857        if (newPage != null) {
1858          newPage.onActivate();
1859          firePageActivated(newPage);
1860          if (newPage.getPerspective() != null)
1861            firePerspectiveActivated(newPage, newPage.getPerspective());
1862        }
1863
1864        if (isClosing())
1865          return;
1866
1867        updateDisabled = false;
1868
1869        // Update action bars ( implicitly calls updateActionBars() )
1870        updateActionSets();
1871
1872        if (perspectiveSwitcher != null)
1873            perspectiveSwitcher.update(false);
1874
1875        getMenuManager().update(IAction.TEXT);
1876
1877        if (noOpenPerspective != null && in != null) {
1878          noOpenPerspective.dispose();
1879          noOpenPerspective = null;
1880        }
1881      }
1882    });
1883  }
1884
1885  /**
1886   * Returns whether or not children exist for the Window's toolbar control.
1887   * Overridden for coolbar support.
1888   * <p>
1889   * @return boolean true if children exist, false otherwise
1890   */
1891  protected boolean toolBarChildrenExist() {
1892    CoolBar coolBarControl = (CoolBar) getCoolBarControl();
1893    return coolBarControl.getItemCount() > 0;
1894  }
1895  /**
1896   * Hooks a listener to track the activation and
1897   * deactivation of the window's shell. Notifies
1898   * the active part and editor of the change
1899   */
1900  private void trackShellActivation(Shell shell) {
1901    shell.addShellListener(new ShellAdapter() {
1902      public void shellActivated(ShellEvent event) {
1903        shellActivated = true;
1904        getWorkbenchImpl().setActivatedWindow(WorkbenchWindow.this);
1905        WorkbenchPage currentPage = getActiveWorkbenchPage();
1906        if (currentPage != null) {
1907          IWorkbenchPart part = currentPage.getActivePart();
1908          if (part != null) {
1909            PartSite site = (PartSite) part.getSite();
1910            site.getPane().shellActivated();
1911          }
1912          IEditorPart editor = currentPage.getActiveEditor();
1913          if (editor != null) {
1914            PartSite site = (PartSite) editor.getSite();
1915            site.getPane().shellActivated();
1916          }
1917          getWorkbenchImpl().fireWindowActivated(WorkbenchWindow.this);
1918        }
1919      }
1920      public void shellDeactivated(ShellEvent event) {
1921        shellActivated = false;
1922        WorkbenchPage currentPage = getActiveWorkbenchPage();
1923        if (currentPage != null) {
1924          IWorkbenchPart part = currentPage.getActivePart();
1925          if (part != null) {
1926            PartSite site = (PartSite) part.getSite();
1927            site.getPane().shellDeactivated();
1928          }
1929          IEditorPart editor = currentPage.getActiveEditor();
1930          if (editor != null) {
1931            PartSite site = (PartSite) editor.getSite();
1932            site.getPane().shellDeactivated();
1933          }
1934          getWorkbenchImpl().fireWindowDeactivated(WorkbenchWindow.this);
1935        }
1936      }
1937    });
1938  }
1939  /**
1940   * Hooks a listener to track the resize of the window's
1941   * shell. Stores the new bounds if in normal state - that
1942   * is, not in minimized or maximized state)
1943   */
1944  private void trackShellResize(Shell newShell) {
1945    newShell.addControlListener(new ControlAdapter() {
1946      public void controlMoved(ControlEvent e) {
1947        saveBounds();
1948      }
1949
1950      public void controlResized(ControlEvent e) {
1951        saveBounds();
1952      }
1953
1954      private void saveBounds() {
1955        Shell shell = getShell();
1956        if (shell == null)
1957          return;
1958        if (shell.isDisposed())
1959          return;
1960        if (shell.getMinimized())
1961          return;
1962        if (shell.getMaximized()) {
1963          asMaximizedState = true;
1964          return;
1965        }
1966        asMaximizedState = false;
1967        normalBounds = shell.getBounds();
1968      }
1969    });
1970  }
1971
1972  /**
1973   * update the action bars.
1974   */
1975  public void updateActionBars() {
1976    if (updateDisabled)
1977      return;
1978    // updateAll required in order to enable accelerators on pull-down menus
1979    getMenuBarManager().updateAll(false);
1980    getCoolBarManager().update(false);
1981    getStatusLineManager().update(false);
1982  }
1983  /**
1984   * Update the visible action sets. This method is typically called
1985   * from a page when the user changes the visible action sets
1986   * within the prespective.  
1987   */
1988  public void updateActionSets() {
1989    if (updateDisabled)
1990      return;
1991
1992    WorkbenchPage currentPage = getActiveWorkbenchPage();
1993    if (currentPage == null)
1994      actionPresentation.clearActionSets();
1995    else {
1996      if (getCoolBarManager() != null) {
1997        getCoolBarManager().refresh();
1998      }
1999      actionPresentation.setActionSets(currentPage.getActionSets());
2000    }
2001    updateActionBars();
2002
2003    // hide the launch menu if it is empty
2004    String path =
2005      IWorkbenchActionConstants.M_WINDOW
2006        + IWorkbenchActionConstants.SEP
2007        + IWorkbenchActionConstants.M_LAUNCH;
2008    IMenuManager manager = getMenuBarManager().findMenuUsingPath(path);
2009    IContributionItem item = getMenuBarManager().findUsingPath(path);
2010    
2011    // TODO remove: updateActiveActions();
2012    IActionSet actionSets[] = actionPresentation.getActionSets();
2013    registerActionSets(actionSets);
2014
2015    if (manager == null || item == null)
2016      return;
2017    item.setVisible(manager.getItems().length >= 2);
2018    // there is a separator for the additions group thus >= 2
2019  }
2020  /**
2021   * Updates the shorcut item
2022   */
2023  /* package */
2024  void updatePerspectiveShortcut(
2025    IPerspectiveDescriptor oldDesc,
2026    IPerspectiveDescriptor newDesc,
2027    WorkbenchPage page) {
2028    if (updateDisabled)
2029      return;
2030    
2031    if (perspectiveSwitcher != null)
2032        perspectiveSwitcher.updatePerspectiveShortcut(oldDesc, newDesc, page);
2033  }
2034
2035  /**
2036   * Create the progress indicator for the receiver.
2037   * @param shell  the parent shell
2038   */
2039  private void createProgressIndicator(Shell shell) {
2040    if (getWindowConfigurer().getShowProgressIndicator()) {
2041      progressRegion = new ProgressRegion();
2042      progressRegion.createContents(shell,this);
2043    }
2044
2045  }
2046  class PageList {
2047    //List of pages in the order they were created;
2048    private List pagesInCreationOrder;
2049    //List of pages where the top is the last activated.
2050    private List pageInActivationOrder;
2051    // The page explicitly activated
2052    private Object active;
2053
2054    public PageList() {
2055      pagesInCreationOrder = new ArrayList(4);
2056      pageInActivationOrder = new ArrayList(4);
2057    }
2058    public boolean add(Object object) {
2059      pagesInCreationOrder.add(object);
2060      pageInActivationOrder.add(0, object);
2061      //It will be moved to top only when activated.
2062      return true;
2063    }
2064    public Iterator iterator() {
2065      return pagesInCreationOrder.iterator();
2066    }
2067    public boolean contains(Object object) {
2068      return pagesInCreationOrder.contains(object);
2069    }
2070    public boolean remove(Object object) {
2071      if (active == object)
2072        active = null;
2073      pageInActivationOrder.remove(object);
2074      return pagesInCreationOrder.remove(object);
2075    }
2076    public boolean isEmpty() {
2077      return pagesInCreationOrder.isEmpty();
2078    }
2079    public IWorkbenchPage[] getPages() {
2080      int nSize = pagesInCreationOrder.size();
2081      IWorkbenchPage[] retArray = new IWorkbenchPage[nSize];
2082      pagesInCreationOrder.toArray(retArray);
2083      return retArray;
2084    }
2085    public void setActive(Object page) {
2086      if (active == page)
2087        return;
2088
2089      active = page;
2090
2091      if (page != null) {
2092        pageInActivationOrder.remove(page);
2093        pageInActivationOrder.add(page);
2094      }
2095    }
2096    public WorkbenchPage getActive() {
2097      return (WorkbenchPage) active;
2098    }
2099    public WorkbenchPage getNextActive() {
2100      if (active == null) {
2101        if (pageInActivationOrder.isEmpty())
2102          return null;
2103        else
2104          return (WorkbenchPage) pageInActivationOrder.get(pageInActivationOrder.size() - 1);
2105      } else {
2106        if (pageInActivationOrder.size() < 2)
2107          return null;
2108        else
2109          return (WorkbenchPage) pageInActivationOrder.get(pageInActivationOrder.size() - 2);
2110      }
2111    }
2112  }
2113
2114  /**
2115   * Returns the unique object that applications use to configure this window.
2116   * <p>
2117   * IMPORTANT This method is declared package-private to prevent regular
2118   * plug-ins from downcasting IWorkbenchWindow to WorkbenchWindow and getting
2119   * hold of the workbench window configurer that would allow them to tamper
2120   * with the workbench window. The workbench window configurer is available
2121   * only to the application.
2122   * </p>
2123   */
2124  /* package - DO NOT CHANGE */
2125  WorkbenchWindowConfigurer getWindowConfigurer() {
2126    if (windowConfigurer == null) {
2127      // lazy initialize
2128      windowConfigurer = new WorkbenchWindowConfigurer(this);
2129    }
2130    return windowConfigurer;
2131  }
2132
2133  /**
2134   * Returns the workbench advisor. Assumes the workbench
2135   * has been created already.
2136   * <p>
2137   * IMPORTANT This method is declared private to prevent regular
2138   * plug-ins from downcasting IWorkbenchWindow to WorkbenchWindow and getting
2139   * hold of the workbench advisor that would allow them to tamper with the
2140   * workbench. The workbench advisor is internal to the application.
2141   * </p>
2142   */
2143  private /* private - DO NOT CHANGE */
2144  WorkbenchAdvisor getAdvisor() {
2145    return getWorkbenchImpl().getAdvisor();
2146  }
2147
2148  /*
2149   * Returns the IWorkbench implementation.
2150   */
2151  private Workbench getWorkbenchImpl() {
2152    return Workbench.getInstance();
2153  }
2154
2155  /**
2156   * Creates a clone copy of the current action bars
2157   * @param configurer location of managers
2158   * @param flags indicate which actions to load and whether its a proxy fill
2159   */
2160  public void fillActionBars(IActionBarConfigurer configurer, int flags) {
2161      Workbench workbench = getWorkbenchImpl();
2162        workbench.largeUpdateStart();
2163      try {
2164
2165            getAdvisor().fillActionBars(this, configurer, flags);
2166
2167        } finally {
2168            workbench.largeUpdateEnd();
2169        }
2170  }
2171
2172
2173  /**
2174   * The <code>WorkbenchWindow</code> implementation of this method has the same
2175   * logic as <code>Window</code>'s implementation, but without the resize check.
2176   * We don't want to skip setting the bounds if the shell has been resized since a
2177   * free resize event occurs on Windows when the menubar is set in configureShell. 
2178   */
2179  protected void initializeBounds() {
2180    Point size = getInitialSize();
2181    Point location = getInitialLocation(size);
2182    getShell().setBounds(getConstrainedShellBounds(new Rectangle(location.x, location.y, size.x, size.y)));
2183  }
2184  
2185  /**
2186   * The <code>WorkbenchWindow</code> implementation of this method
2187   * delegates to the window configurer.
2188   *  
2189   * @since 3.0
2190   */
2191  protected Point getInitialSize() {
2192    return getWindowConfigurer().getInitialSize();
2193  }
2194  
2195  /**
2196   * @param visible whether the cool bar should be shown.  This is only 
2197   * applicable if the window configurer also wishes either the cool bar to be
2198   * visible.
2199   * @since 3.0 
2200   */  
2201  public void setCoolBarVisible(boolean visible) {
2202    boolean oldValue = coolBarVisible;
2203    coolBarVisible = visible;
2204    if (oldValue != coolBarVisible) {
2205      updateLayoutDataForContents();
2206    }
2207  }
2208  
2209  /** 
2210   * @return whether the cool bar should be shown.  This is only 
2211   * applicable if the window configurer also wishes either the cool bar to be
2212   * visible.
2213   * @since 3.0
2214   */
2215  public boolean getCoolBarVisible() {
2216    return coolBarVisible;
2217  }
2218  
2219  /**
2220   * @param visible whether the perspective bar should be shown.  This is only 
2221   * applicable if the window configurer also wishes either the perspective 
2222   * bar to be visible.
2223   * @since 3.0 
2224   */  
2225  public void setPerspectiveBarVisible(boolean visible) {
2226    boolean oldValue = perspectiveBarVisible;
2227    perspectiveBarVisible = visible;
2228    if (oldValue != perspectiveBarVisible) {
2229      updateLayoutDataForContents();
2230    }
2231  }
2232  
2233  /** 
2234   * @return whether the perspective bar should be shown.  This is only 
2235   * applicable if the window configurer also wishes either the perspective 
2236   * bar to be visible.
2237   * @since 3.0
2238   */
2239  public boolean getPerspectiveBarVisible() {
2240    return perspectiveBarVisible;
2241  }  
2242  
2243  /**
2244   * @param visible whether the perspective bar should be shown.  This is only 
2245   * applicable if the window configurer also wishes either the perspective 
2246   * bar to be visible.
2247   * @since 3.0 
2248   */  
2249  public void setStatusLineVisible(boolean visible) {
2250    boolean oldValue = statusLineVisible;
2251    statusLineVisible = visible;
2252    if (oldValue != statusLineVisible) {
2253      updateLayoutDataForContents();
2254    }
2255  }
2256  
2257  /** 
2258   * @return whether the perspective bar should be shown.  This is only 
2259   * applicable if the window configurer also wishes either the perspective 
2260   * bar to be visible.
2261   * @since 3.0
2262   */
2263  public boolean getStatusLineVisible() {
2264    return statusLineVisible;
2265  }  
2266
2267  /** 
2268   * Note that this will only have an effect if the default implementation of
2269   * WorkbenchAdvisor.createWindowContents() has been invoked.
2270   *  
2271   * called  IWorkbench
2272   * @since 3.0
2273   */
2274  private void updateLayoutDataForContents() {
2275      if (defaultLayout == null) 
2276          return;
2277      
2278    // @issue this is not ideal; coolbar and perspective shortcuts should be
2279    //   separately configurable
2280    if ((getCoolBarVisible() && getWindowConfigurer().getShowCoolBar()) || (getPerspectiveBarVisible() && getWindowConfigurer().getShowPerspectiveBar())) {
2281      defaultLayout.addTrim(topBar, SWT.TOP, null);
2282      topBar.setVisible(true);
2283    }
2284    else {
2285      defaultLayout.removeTrim(topBar);
2286      topBar.setVisible(false);
2287    }
2288
2289    if (getStatusLineVisible() && getWindowConfigurer().getShowStatusLine()) {
2290      defaultLayout.addTrim(getStatusLineManager().getControl(), SWT.BOTTOM, null);
2291      getStatusLineManager().getControl().setVisible(true);
2292    }
2293    else {
2294      defaultLayout.removeTrim(getStatusLineManager().getControl());
2295      getStatusLineManager().getControl().setVisible(false);
2296    }
2297    
2298    if (getWindowConfigurer().getShowProgressIndicator()) {
2299      if (progressRegion.getControl().getLayoutData() == null) {
2300        TrimLayoutData animationData = new TrimLayoutData(false, 
2301            progressRegion.getControl().computeSize(SWT.DEFAULT, SWT.DEFAULT).x, 
2302            getStatusLineManager().getControl().computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
2303  
2304        progressRegion.getControl().setLayoutData(animationData);
2305      }
2306      defaultLayout.addTrim(progressRegion.getControl(), SWT.BOTTOM, null);
2307      progressRegion.getControl().setVisible(true);
2308    }
2309    else {
2310      if (progressRegion != null) {
2311        defaultLayout.removeTrim(progressRegion.getControl());
2312        progressRegion.getControl().setVisible(false);
2313      }
2314    }
2315    defaultLayout.setCenterControl(getPageComposite());  
2316  }
2317  
2318  public boolean getShowFastViewBars() {
2319    return getWindowConfigurer().getShowFastViewBars();
2320  }
2321  
2322  /**
2323   * Set the layout data for the contents of the window.
2324   */
2325  private void setLayoutDataForContents() {
2326    updateLayoutDataForContents();
2327    
2328    if (getWindowConfigurer().getShowFastViewBars() && fastViewBar != null) {
2329      fastViewBar.addDockingListener(new IChangeListener() {
2330        public void update(boolean changed) {
2331          Control reference = null;
2332          int side = fastViewBar.getSide(); 
2333          
2334          fastViewBar.getControl().setLayoutData(new TrimLayoutData(side != SWT.BOTTOM, SWT.DEFAULT, SWT.DEFAULT));
2335          
2336          if (side == SWT.BOTTOM && getWindowConfigurer().getShowStatusLine()) {
2337            reference = getStatusLineManager().getControl();  
2338          }
2339          
2340          defaultLayout.addTrim(fastViewBar.getControl(), side, reference);
2341          WorkbenchPage page = getActiveWorkbenchPage(); 
2342          
2343          if (page != null) {
2344            Perspective persp = page.getActivePerspective();
2345            IViewReference activeFastView = persp.getActiveFastView(); 
2346            if (activeFastView != null) {
2347              persp.setActiveFastView(null);
2348              persp.setActiveFastView(activeFastView);
2349            }
2350          }
2351          
2352          LayoutUtil.resize(fastViewBar.getControl());
2353        }
2354      });
2355    }
2356  }
2357  
2358  /**
2359   * Returns the fast view bar.
2360   */
2361  public FastViewBar getFastViewBar() {
2362    return fastViewBar;
2363  }
2364  
2365  /**
2366   * Returns the perspective bar.
2367   */
2368  public PerspectiveBarManager getPerspectiveBar() {
2369    return perspectiveSwitcher == null ? null : perspectiveSwitcher.getPerspectiveBar();
2370  }
2371
2372//for dynamic UI
2373  protected ActionPresentation getActionPresentation() {
2374    return actionPresentation;
2375  }
2376
2377  /* (non-Javadoc)
2378   * @see org.eclipse.jface.window.ApplicationWindow#showTopSeperator()
2379   */
2380  protected boolean showTopSeperator() {
2381    return false;
2382  }
2383  
2384  
2385    /**
2386     * Delegate to the presentation factory.
2387     * 
2388     * @see org.eclipse.jface.window.ApplicationWindow#createStatusLineManager
2389     * @since 3.0
2390     */
2391    protected StatusLineManager createStatusLineManager() {
2392        // @issue ApplicationWindow and WorkbenchWindow should allow full IStatusLineManager
2393        return (StatusLineManager) getWindowConfigurer().getPresentationFactory().createStatusLineManager();
2394    }
2395    
2396    /**
2397     * Delegate to the presentation factory.
2398     * 
2399     * @see org.eclipse.jface.window.ApplicationWindow#createStatusLine
2400     * @since 3.0
2401     */
2402    protected void createStatusLine(Shell shell) {
2403        getWindowConfigurer().getPresentationFactory().createStatusLineControl(getStatusLineManager(), shell);
2404    }
2405
2406    /**
2407     * Updates the fast view bar, if present.
2408     * TODO: The fast view bar should update itself as necessary.
2409     * All calls to this should be cleaned up.
2410     * 
2411     * @since 3.0
2412     */
2413    public void updateFastViewBar() {
2414    if (getFastViewBar() != null) {
2415        getFastViewBar().update(true);
2416    }
2417    }
2418    /**
2419     * @return Returns the progressRegion.
2420     */
2421    public ProgressRegion getProgressRegion() {
2422        return progressRegion;
2423    }
2424
2425    /**
2426     * Add the argument perspective bar control to the argument side of this
2427     * window's trim.
2428     * 
2429     * @param control
2430     *            the perspective bar's control
2431     * @param side
2432     *            one of <code>SWT.LEFT</code>,<code>SWT.BOTTOM</code>,
2433     *            or <code>SWT.RIGHT</code> (only LEFT has been tested)
2434   * @since 3.0
2435     */
2436    public void addPerspectiveBarToTrim(Control control, int side) {
2437        Control reference = null;
2438
2439        // the perspective bar should go before the fast view bar they're on the
2440        // same side and before the status line if on the bottom
2441        if (side == fastViewBar.getSide())
2442            reference = fastViewBar.getControl();
2443        else if(side == SWT.BOTTOM && getWindowConfigurer().getShowStatusLine())
2444            reference = getStatusLineManager().getControl();  
2445
2446    control.setLayoutData(new TrimLayoutData(false, SWT.DEFAULT, SWT.DEFAULT));
2447    defaultLayout.addTrim(control, side, reference);
2448    }
2449}