KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > WorkbenchWindow


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-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 JavaDoc;
15 import java.util.ArrayList JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Map JavaDoc;
20
21 import org.eclipse.core.commands.IHandler;
22 import org.eclipse.core.expressions.Expression;
23 import org.eclipse.core.runtime.Assert;
24 import org.eclipse.core.runtime.IAdaptable;
25 import org.eclipse.core.runtime.IExtension;
26 import org.eclipse.core.runtime.IExtensionPoint;
27 import org.eclipse.core.runtime.IStatus;
28 import org.eclipse.core.runtime.ListenerList;
29 import org.eclipse.core.runtime.MultiStatus;
30 import org.eclipse.core.runtime.Platform;
31 import org.eclipse.core.runtime.Status;
32 import org.eclipse.core.runtime.dynamichelpers.ExtensionTracker;
33 import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler;
34 import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
35 import org.eclipse.jface.action.ContributionManager;
36 import org.eclipse.jface.action.CoolBarManager;
37 import org.eclipse.jface.action.GroupMarker;
38 import org.eclipse.jface.action.IAction;
39 import org.eclipse.jface.action.IContributionItem;
40 import org.eclipse.jface.action.IContributionManager;
41 import org.eclipse.jface.action.ICoolBarManager;
42 import org.eclipse.jface.action.IMenuManager;
43 import org.eclipse.jface.action.IToolBarManager;
44 import org.eclipse.jface.action.MenuManager;
45 import org.eclipse.jface.action.Separator;
46 import org.eclipse.jface.action.StatusLineManager;
47 import org.eclipse.jface.commands.ActionHandler;
48 import org.eclipse.jface.internal.provisional.action.ICoolBarManager2;
49 import org.eclipse.jface.internal.provisional.action.IToolBarContributionItem;
50 import org.eclipse.jface.operation.IRunnableWithProgress;
51 import org.eclipse.jface.util.IPropertyChangeListener;
52 import org.eclipse.jface.util.PropertyChangeEvent;
53 import org.eclipse.jface.window.ApplicationWindow;
54 import org.eclipse.jface.window.Window;
55 import org.eclipse.osgi.util.NLS;
56 import org.eclipse.osgi.util.TextProcessor;
57 import org.eclipse.swt.SWT;
58 import org.eclipse.swt.custom.BusyIndicator;
59 import org.eclipse.swt.custom.CBanner;
60 import org.eclipse.swt.custom.StackLayout;
61 import org.eclipse.swt.events.ControlAdapter;
62 import org.eclipse.swt.events.ControlEvent;
63 import org.eclipse.swt.events.ShellAdapter;
64 import org.eclipse.swt.events.ShellEvent;
65 import org.eclipse.swt.graphics.Point;
66 import org.eclipse.swt.graphics.Rectangle;
67 import org.eclipse.swt.widgets.Composite;
68 import org.eclipse.swt.widgets.Control;
69 import org.eclipse.swt.widgets.CoolBar;
70 import org.eclipse.swt.widgets.Display;
71 import org.eclipse.swt.widgets.Event;
72 import org.eclipse.swt.widgets.Layout;
73 import org.eclipse.swt.widgets.Listener;
74 import org.eclipse.swt.widgets.Menu;
75 import org.eclipse.swt.widgets.Shell;
76 import org.eclipse.ui.ActiveShellExpression;
77 import org.eclipse.ui.IEditorPart;
78 import org.eclipse.ui.IElementFactory;
79 import org.eclipse.ui.IMemento;
80 import org.eclipse.ui.IPageListener;
81 import org.eclipse.ui.IPartService;
82 import org.eclipse.ui.IPersistable;
83 import org.eclipse.ui.IPersistableElement;
84 import org.eclipse.ui.IPerspectiveDescriptor;
85 import org.eclipse.ui.ISelectionService;
86 import org.eclipse.ui.IWorkbench;
87 import org.eclipse.ui.IWorkbenchActionConstants;
88 import org.eclipse.ui.IWorkbenchPage;
89 import org.eclipse.ui.IWorkbenchPart;
90 import org.eclipse.ui.IWorkbenchPartReference;
91 import org.eclipse.ui.IWorkbenchPreferenceConstants;
92 import org.eclipse.ui.IWorkbenchWindow;
93 import org.eclipse.ui.PlatformUI;
94 import org.eclipse.ui.WorkbenchException;
95 import org.eclipse.ui.application.ActionBarAdvisor;
96 import org.eclipse.ui.application.WorkbenchAdvisor;
97 import org.eclipse.ui.application.WorkbenchWindowAdvisor;
98 import org.eclipse.ui.commands.ICommandService;
99 import org.eclipse.ui.contexts.IContextService;
100 import org.eclipse.ui.contexts.IWorkbenchContextSupport;
101 import org.eclipse.ui.handlers.IHandlerActivation;
102 import org.eclipse.ui.handlers.IHandlerService;
103 import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
104 import org.eclipse.ui.internal.actions.CommandAction;
105 import org.eclipse.ui.internal.commands.SlaveCommandService;
106 import org.eclipse.ui.internal.contexts.ContextAuthority;
107 import org.eclipse.ui.internal.contexts.SlaveContextService;
108 import org.eclipse.ui.internal.dialogs.CustomizePerspectiveDialog;
109 import org.eclipse.ui.internal.dnd.DragUtil;
110 import org.eclipse.ui.internal.dnd.SwtUtil;
111 import org.eclipse.ui.internal.expressions.WorkbenchWindowExpression;
112 import org.eclipse.ui.internal.handlers.ActionCommandMappingService;
113 import org.eclipse.ui.internal.handlers.IActionCommandMappingService;
114 import org.eclipse.ui.internal.handlers.SlaveHandlerService;
115 import org.eclipse.ui.internal.intro.IIntroConstants;
116 import org.eclipse.ui.internal.layout.CacheWrapper;
117 import org.eclipse.ui.internal.layout.ITrimManager;
118 import org.eclipse.ui.internal.layout.IWindowTrim;
119 import org.eclipse.ui.internal.layout.LayoutUtil;
120 import org.eclipse.ui.internal.layout.TrimLayout;
121 import org.eclipse.ui.internal.menus.IActionSetsListener;
122 import org.eclipse.ui.internal.menus.LegacyActionPersistence;
123 import org.eclipse.ui.internal.menus.TrimBarManager2;
124 import org.eclipse.ui.internal.menus.TrimContributionManager;
125 import org.eclipse.ui.internal.menus.WindowMenuService;
126 import org.eclipse.ui.internal.misc.Policy;
127 import org.eclipse.ui.internal.misc.UIListenerLogging;
128 import org.eclipse.ui.internal.misc.UIStats;
129 import org.eclipse.ui.internal.presentations.DefaultActionBarPresentationFactory;
130 import org.eclipse.ui.internal.progress.ProgressRegion;
131 import org.eclipse.ui.internal.provisional.application.IActionBarConfigurer2;
132 import org.eclipse.ui.internal.provisional.presentations.IActionBarPresentationFactory;
133 import org.eclipse.ui.internal.registry.ActionSetRegistry;
134 import org.eclipse.ui.internal.registry.IActionSetDescriptor;
135 import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
136 import org.eclipse.ui.internal.registry.UIExtensionTracker;
137 import org.eclipse.ui.internal.services.ServiceLocator;
138 import org.eclipse.ui.internal.util.PrefUtil;
139 import org.eclipse.ui.internal.util.Util;
140 import org.eclipse.ui.menus.IMenuService;
141 import org.eclipse.ui.menus.MenuUtil;
142 import org.eclipse.ui.presentations.AbstractPresentationFactory;
143 import org.eclipse.ui.services.IServiceScopes;
144
145 /**
146  * A window within the workbench.
147  */

148 public class WorkbenchWindow extends ApplicationWindow implements
149         IWorkbenchWindow {
150
151     private WorkbenchWindowAdvisor windowAdvisor;
152
153     private ActionBarAdvisor actionBarAdvisor;
154
155     private int number;
156
157     private PageList pageList = new PageList();
158
159     private PageListenerList pageListeners = new PageListenerList();
160
161     private PerspectiveListenerList perspectiveListeners = new PerspectiveListenerList();
162
163     private WWinPartService partService = new WWinPartService(this);
164
165     private ActionPresentation actionPresentation;
166
167     private WWinActionBars actionBars;
168
169     private boolean updateDisabled = true;
170
171     private boolean closing = false;
172
173     private boolean shellActivated = false;
174
175     private FastViewBar fastViewBar;
176
177     private PerspectiveSwitcher perspectiveSwitcher = null;
178
179     private TrimLayout defaultLayout;
180
181     ProgressRegion progressRegion = null;
182
183     // Legacy (3.2) contribution handling
184
private TrimBarManager2 trimMgr2 = null;
185     
186     // 3.3 Trim Contribution handling
187
private TrimContributionManager trimContributionMgr = null;
188     
189     /**
190      * The map of services maintained by the workbench window. These services
191      * are initialized during workbench window during the
192      * {@link #configureShell(Shell)}.
193      */

194     private final ServiceLocator serviceLocator;
195
196     private HeapStatus heapStatus;
197
198     private WindowTrimProxy heapStatusTrim = null;
199
200     private boolean emptyWindowContentsCreated = false;
201
202     private Control emptyWindowContents;
203
204     private Rectangle normalBounds;
205
206     private boolean asMaximizedState = false;
207
208     private CBanner topBar;
209
210     private IWindowTrim topBarTrim;
211
212     // Previous shell size. Used to prevent the CBanner from triggering
213
// redundant layouts
214
private Point lastShellSize = new Point(0, 0);
215
216     /**
217      * The composite under which workbench pages create their controls.
218      *
219      * @since 3.0
220      */

221     private Composite pageComposite;
222
223     /**
224      * Bit flags indication which submenus (New, Show Views, ...) this window
225      * contains. Initially none.
226      *
227      * @since 3.0
228      */

229     private int submenus = 0x00;
230
231     /**
232      * Object for configuring this workbench window. Lazily initialized to an
233      * instance unique to this window.
234      *
235      * @since 3.0
236      */

237     private WorkbenchWindowConfigurer windowConfigurer = null;
238     
239     /**
240      * List of generic property listeners.
241      *
242      * @since 3.3
243      */

244     private ListenerList genericPropertyListeners = new ListenerList();
245
246     private ShellPool detachedWindowShells;
247     
248     static final String JavaDoc TEXT_DELIMITERS = TextProcessor.getDefaultDelimiters() + "-"; //$NON-NLS-1$
249

250     // constants for shortcut bar group ids
251
static final String JavaDoc GRP_PAGES = "pages"; //$NON-NLS-1$
252

253     static final String JavaDoc GRP_PERSPECTIVES = "perspectives"; //$NON-NLS-1$
254

255     static final String JavaDoc GRP_FAST_VIEWS = "fastViews"; //$NON-NLS-1$
256

257     // static fields for inner classes.
258
static final int VGAP = 0;
259
260     static final int CLIENT_INSET = 3;
261
262     static final int BAR_SIZE = 23;
263
264     /**
265      * Coolbar visibility change property.
266      *
267      * @since 3.3
268      */

269     public static final String JavaDoc PROP_COOLBAR_VISIBLE = "coolbarVisible"; //$NON-NLS-1$
270

271     /**
272      * Perspective bar visibility change property.
273      *
274      * @since 3.3
275      */

276     public static final String JavaDoc PROP_PERSPECTIVEBAR_VISIBLE = "perspectiveBarVisible"; //$NON-NLS-1$
277

278     /**
279      * Constant (bit mask) indicating which the Show View submenu is probably
280      * present somewhere in this window.
281      *
282      * @see #addSubmenu
283      * @since 3.0
284      */

285     public static final int SHOW_VIEW_SUBMENU = 0x01;
286
287     /**
288      * Constant (bit mask) indicating which the Open Perspective submenu is
289      * probably present somewhere in this window.
290      *
291      * @see #addSubmenu
292      * @since 3.0
293      */

294     public static final int OPEN_PERSPECTIVE_SUBMENU = 0x02;
295
296     /**
297      * Constant (bit mask) indicating which the New Wizard submenu is probably
298      * present somewhere in this window.
299      *
300      * @see #addSubmenu
301      * @since 3.0
302      */

303     public static final int NEW_WIZARD_SUBMENU = 0x04;
304
305     /**
306      * Remembers that this window contains the given submenu.
307      *
308      * @param type
309      * the type of submenu, one of:
310      * {@link #NEW_WIZARD_SUBMENU NEW_WIZARD_SUBMENU},
311      * {@link #OPEN_PERSPECTIVE_SUBMENU OPEN_PERSPECTIVE_SUBMENU},
312      * {@link #SHOW_VIEW_SUBMENU SHOW_VIEW_SUBMENU}
313      * @see #containsSubmenu
314      * @since 3.0
315      */

316     public void addSubmenu(int type) {
317         submenus |= type;
318     }
319
320     /**
321      * Checks to see if this window contains the given type of submenu.
322      *
323      * @param type
324      * the type of submenu, one of:
325      * {@link #NEW_WIZARD_SUBMENU NEW_WIZARD_SUBMENU},
326      * {@link #OPEN_PERSPECTIVE_SUBMENU OPEN_PERSPECTIVE_SUBMENU},
327      * {@link #SHOW_VIEW_SUBMENU SHOW_VIEW_SUBMENU}
328      * @return <code>true</code> if window contains submenu,
329      * <code>false</code> otherwise
330      * @see #addSubmenu
331      * @since 3.0
332      */

333     public boolean containsSubmenu(int type) {
334         return ((submenus & type) != 0);
335     }
336
337     /**
338      * Constant indicating that all the actions bars should be filled.
339      *
340      * @since 3.0
341      */

342     private static final int FILL_ALL_ACTION_BARS = ActionBarAdvisor.FILL_MENU_BAR
343             | ActionBarAdvisor.FILL_COOL_BAR
344             | ActionBarAdvisor.FILL_STATUS_LINE;
345
346     /**
347      * Creates and initializes a new workbench window.
348      *
349      * @param number
350      * the number for the window
351      */

352     public WorkbenchWindow(int number) {
353         super(null);
354         this.number = number;
355
356         // Make sure there is a workbench. This call will throw
357
// an exception if workbench not created yet.
358
final IWorkbench workbench = PlatformUI.getWorkbench();
359         this.serviceLocator = new ServiceLocator(workbench);
360         initializeDefaultServices();
361
362         // Add contribution managers that are exposed to other plugins.
363
addMenuBar();
364         addCoolBar(SWT.NONE); // style is unused
365
addStatusLine();
366
367         // register with the tracker
368
getExtensionTracker()
369                 .registerHandler(
370                         actionSetHandler,
371                         ExtensionTracker
372                                 .createExtensionPointFilter(getActionSetExtensionPoint()));
373
374         fireWindowOpening();
375
376         // set the shell style
377
setShellStyle(getWindowConfigurer().getShellStyle());
378
379         // Fill the action bars
380
fillActionBars(FILL_ALL_ACTION_BARS);
381     }
382
383     /**
384      * Return the action set extension point.
385      *
386      * @return the action set extension point
387      * @since 3.1
388      */

389     private IExtensionPoint getActionSetExtensionPoint() {
390         return Platform.getExtensionRegistry().getExtensionPoint(
391                 PlatformUI.PLUGIN_ID, IWorkbenchRegistryConstants.PL_ACTION_SETS);
392     }
393
394     /**
395      * Return the style bits for the shortcut bar.
396      *
397      * @return int
398      */

399     protected int perspectiveBarStyle() {
400         return SWT.FLAT | SWT.WRAP | SWT.RIGHT | SWT.HORIZONTAL;
401     }
402
403     private TrimDropTarget trimDropTarget;
404
405     private boolean coolBarVisible = true;
406
407     private boolean perspectiveBarVisible = true;
408     
409     private boolean fastViewBarVisible = true;
410
411     private boolean statusLineVisible = true;
412
413     private IWindowTrim statusLineTrim = null;
414
415     /**
416      * The handlers for global actions that were last submitted to the workbench
417      * command support. This is a map of command identifiers to
418      * <code>ActionHandler</code>. This map is never <code>null</code>,
419      * and is never empty as long as at least one global action has been
420      * registered.
421      */

422     private Map JavaDoc globalActionHandlersByCommandId = new HashMap JavaDoc();
423
424     /**
425      * The list of handler submissions submitted to the workbench command
426      * support. This list may be empty, but it is never <code>null</code>.
427      */

428     private List JavaDoc handlerActivations = new ArrayList JavaDoc();
429
430     /**
431      * The number of large updates that are currently going on. If this is
432      * number is greater than zero, then UI updateActionBars is a no-op.
433      *
434      * @since 3.1
435      */

436     private int largeUpdates = 0;
437
438     private IExtensionTracker tracker;
439
440     private IExtensionChangeHandler actionSetHandler = new IExtensionChangeHandler() {
441
442         /*
443          * (non-Javadoc)
444          *
445          * @see org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler#addExtension(org.eclipse.core.runtime.dynamichelpers.IExtensionTracker,
446          * org.eclipse.core.runtime.IExtension)
447          */

448         public void addExtension(IExtensionTracker tracker, IExtension extension) {
449             // this assumes that the workbench-level tracker will have already
450
// updated the registry
451

452             ArrayList JavaDoc setsToActivate = new ArrayList JavaDoc();
453             // look for all new sets that are on by default. Examine the tracker
454
// at the workbench level to see what descriptors are registered
455
// against this extension
456
Object JavaDoc[] registeredObjects = getWorkbench().getExtensionTracker()
457                     .getObjects(extension);
458             for (int i = 0; i < registeredObjects.length; i++) {
459                 if (registeredObjects[i] instanceof IActionSetDescriptor) {
460                     IActionSetDescriptor desc = (IActionSetDescriptor) registeredObjects[i];
461                     if (desc.isInitiallyVisible()) {
462                         setsToActivate.add(desc);
463                     }
464                 }
465             }
466
467             // if none of the new sets are marked as initially visible, abort.
468
if (setsToActivate.isEmpty()) {
469                 return;
470             }
471
472             IActionSetDescriptor[] descriptors = (IActionSetDescriptor[]) setsToActivate
473                     .toArray(new IActionSetDescriptor[setsToActivate.size()]);
474
475             WorkbenchPage page = getActiveWorkbenchPage();
476             if (page != null) {
477                 Perspective[] perspectives = page.getOpenInternalPerspectives();
478
479                 for (int i = 0; i < perspectives.length; i++) {
480                     perspectives[i].turnOnActionSets(descriptors);
481                 }
482             }
483
484             updateActionSets();
485         }
486
487         /*
488          * (non-Javadoc)
489          *
490          * @see org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler#removeExtension(org.eclipse.core.runtime.IExtension,
491          * java.lang.Object[])
492          */

493         public void removeExtension(IExtension extension, Object JavaDoc[] objects) {
494             // remove the contributions from the window bars and dispose of the
495
// actions
496
for (int i = 0; i < objects.length; i++) {
497                 if (objects[i] instanceof PluginActionSetBuilder.Binding) {
498                     PluginActionSetBuilder.Binding binding = (PluginActionSetBuilder.Binding) objects[i];
499                     binding.builder.removeActionExtensions(binding.set,
500                             binding.window);
501                     binding.set.dispose();
502                 }
503             }
504
505             // update all opened perspectives
506
Perspective[] perspectives = getActiveWorkbenchPage()
507                     .getOpenInternalPerspectives();
508             boolean updateNeeded = true;
509             IContextService contextService = (IContextService) getService(IContextService.class);
510             try {
511                 contextService.activateContext(ContextAuthority.DEFER_EVENTS);
512                 
513                 for (int i = 0; i < perspectives.length; i++) {
514                     for (int j = 0; j < objects.length; j++) {
515                         if (objects[j] instanceof IActionSetDescriptor) {
516                             perspectives[i]
517                                     .removeActionSet((IActionSetDescriptor) objects[j]);
518                             getActionPresentation().removeActionSet(
519                                     (IActionSetDescriptor) objects[j]);
520                         }
521                     }
522                 }
523             } finally {
524                 contextService.activateContext(ContextAuthority.SEND_EVENTS);
525             }
526
527             if (updateNeeded) {
528                 // refresh the window
529
updateActionSets();
530             }
531         }
532     };
533
534     void registerGlobalAction(IAction globalAction) {
535         String JavaDoc commandId = globalAction.getActionDefinitionId();
536
537         if (commandId != null) {
538             final Object JavaDoc value = globalActionHandlersByCommandId.get(commandId);
539             if (value instanceof ActionHandler) {
540                 // This handler is about to get clobbered, so dispose it.
541
final ActionHandler handler = (ActionHandler) value;
542                 handler.dispose();
543             }
544
545             if (globalAction instanceof CommandAction) {
546                 final String JavaDoc actionId = globalAction.getId();
547                 if (actionId != null) {
548                     final IActionCommandMappingService mappingService = (IActionCommandMappingService) serviceLocator
549                             .getService(IActionCommandMappingService.class);
550                     mappingService.map(actionId, commandId);
551                 }
552             } else {
553                 globalActionHandlersByCommandId.put(commandId,
554                         new ActionHandler(globalAction));
555             }
556         }
557
558         submitGlobalActions();
559     }
560
561     /**
562      * <p>
563      * Submits the action handlers for action set actions and global actions.
564      * Global actions are given priority, so that if a global action and an
565      * action set action both handle the same command, the global action is
566      * given priority.
567      * </p>
568      * <p>
569      * These submissions are submitted as <code>Priority.LEGACY</code>, which
570      * means that they are the lowest priority. This means that if a higher
571      * priority submission handles the same command under the same conditions,
572      * that that submission will become the handler.
573      * </p>
574      */

575     void submitGlobalActions() {
576         final IHandlerService handlerService = (IHandlerService) getWorkbench().getService(IHandlerService.class);
577
578         /*
579          * Mash the action sets and global actions together, with global actions
580          * taking priority.
581          */

582         Map JavaDoc handlersByCommandId = new HashMap JavaDoc();
583         handlersByCommandId.putAll(globalActionHandlersByCommandId);
584
585         List JavaDoc newHandlers = new ArrayList JavaDoc(handlersByCommandId.size());
586
587         Iterator JavaDoc existingIter = handlerActivations.iterator();
588         while (existingIter.hasNext()) {
589             IHandlerActivation next = (IHandlerActivation) existingIter.next();
590
591             String JavaDoc cmdId = next.getCommandId();
592
593             Object JavaDoc handler = handlersByCommandId.get(cmdId);
594             if (handler == next.getHandler()) {
595                 handlersByCommandId.remove(cmdId);
596                 newHandlers.add(next);
597             } else {
598                 handlerService.deactivateHandler(next);
599             }
600         }
601
602         final Shell shell = getShell();
603         if (shell != null) {
604             final Expression expression = new ActiveShellExpression(shell);
605             for (Iterator JavaDoc iterator = handlersByCommandId.entrySet().iterator(); iterator
606                     .hasNext();) {
607                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iterator.next();
608                 String JavaDoc commandId = (String JavaDoc) entry.getKey();
609                 IHandler handler = (IHandler) entry.getValue();
610                 newHandlers.add(handlerService.activateHandler(commandId,
611                         handler, expression));
612             }
613         }
614
615         handlerActivations = newHandlers;
616     }
617     
618     /**
619      * Add a generic property listener.
620      *
621      * @param listener the listener to add
622      * @since 3.3
623      */

624     public void addPropertyChangeListener(IPropertyChangeListener listener) {
625         genericPropertyListeners.add(listener);
626     }
627     
628     /**
629      * Removes a generic property listener.
630      *
631      * @param listener the listener to remove
632      * @since 3.3
633      */

634     public void removePropertyChangeListener(IPropertyChangeListener listener) {
635         genericPropertyListeners.remove(listener);
636     }
637     
638     private void firePropertyChanged(final String JavaDoc property, final Object JavaDoc oldValue, final Object JavaDoc newValue) {
639         PropertyChangeEvent event = new PropertyChangeEvent(this, property, oldValue, newValue);
640         Object JavaDoc[] listeners = genericPropertyListeners.getListeners();
641         for (int i = 0; i < listeners.length; i++) {
642             IPropertyChangeListener listener = (IPropertyChangeListener) listeners[i];
643             listener.propertyChange(event);
644         }
645     }
646
647     /*
648      * Adds an listener to the part service.
649      */

650     public void addPageListener(IPageListener l) {
651         pageListeners.addPageListener(l);
652     }
653
654     /**
655      * @see org.eclipse.ui.IPageService
656      */

657     public void addPerspectiveListener(org.eclipse.ui.IPerspectiveListener l) {
658         perspectiveListeners.addPerspectiveListener(l);
659     }
660
661     /**
662      * Configures this window to have a perspecive bar. Does nothing if it
663      * already has one.
664      */

665     protected void addPerspectiveBar(int style) {
666         Assert.isTrue(perspectiveSwitcher == null);
667         perspectiveSwitcher = new PerspectiveSwitcher(this, topBar, style);
668     }
669
670     /**
671      * Close the window.
672      *
673      * Assumes that busy cursor is active.
674      */

675     private boolean busyClose() {
676         // Whether the window was actually closed or not
677
boolean windowClosed = false;
678
679         // Setup internal flags to indicate window is in
680
// progress of closing and no update should be done.
681
closing = true;
682         updateDisabled = true;
683
684         try {
685             // Only do the check if it is OK to close if we are not closing
686
// via the workbench as the workbench will check this itself.
687
Workbench workbench = getWorkbenchImpl();
688             int count = workbench.getWorkbenchWindowCount();
689             // also check for starting - if the first window dies on startup
690
// then we'll need to open a default window.
691
if (!workbench.isStarting()
692                     && !workbench.isClosing()
693                     && count <= 1
694                     && workbench.getWorkbenchConfigurer()
695                             .getExitOnLastWindowClose()) {
696                 windowClosed = workbench.close();
697             } else {
698                 if (okToClose()) {
699                     windowClosed = hardClose();
700                 }
701             }
702         } finally {
703             if (!windowClosed) {
704                 // Reset the internal flags if window was not closed.
705
closing = false;
706                 updateDisabled = false;
707             }
708         }
709
710         if (windowClosed && tracker != null) {
711             tracker.close();
712         }
713
714         return windowClosed;
715     }
716
717     /**
718      * Opens a new page. Assumes that busy cursor is active.
719      * <p>
720      * <b>Note:</b> Since release 2.0, a window is limited to contain at most
721      * one page. If a page exist in the window when this method is used, then
722      * another window is created for the new page. Callers are strongly
723      * recommended to use the <code>IWorkbench.openPerspective</code> APIs to
724      * programmatically show a perspective.
725      * </p>
726      */

727     protected IWorkbenchPage busyOpenPage(String JavaDoc perspID, IAdaptable input)
728             throws WorkbenchException {
729         IWorkbenchPage newPage = null;
730
731         if (pageList.isEmpty()) {
732             newPage = new WorkbenchPage(this, perspID, input);
733             pageList.add(newPage);
734             firePageOpened(newPage);
735             setActivePage(newPage);
736         } else {
737             IWorkbenchWindow window = getWorkbench().openWorkbenchWindow(
738                     perspID, input);
739             newPage = window.getActivePage();
740         }
741
742         return newPage;
743     }
744
745     /**
746      * @see Window
747      */

748     public int open() {
749         if (getPages().length == 0) {
750             showEmptyWindowContents();
751         }
752         fireWindowCreated();
753         getWindowAdvisor().openIntro();
754         int result = super.open();
755
756         // It's time for a layout ... to insure that if TrimLayout
757
// is in play, it updates all of the trim it's responsible
758
// for. We have to do this before updating in order to get
759
// the PerspectiveBar management correct...see defect 137334
760
getShell().layout();
761         
762         fireWindowOpened();
763         if (perspectiveSwitcher != null) {
764             perspectiveSwitcher.updatePerspectiveBar();
765             perspectiveSwitcher.updateBarParent();
766         }
767         
768         return result;
769     }
770
771     /*
772      * (non-Javadoc) Method declared on Window.
773      */

774     protected boolean canHandleShellCloseEvent() {
775         if (!super.canHandleShellCloseEvent()) {
776             return false;
777         }
778         // let the advisor or other interested parties
779
// veto the user's explicit request to close the window
780
return fireWindowShellClosing();
781     }
782
783     /**
784      * @see IWorkbenchWindow
785      */

786     public boolean close() {
787         final boolean[] ret = new boolean[1];
788         BusyIndicator.showWhile(null, new Runnable JavaDoc() {
789             public void run() {
790                 ret[0] = busyClose();
791             }
792         });
793         return ret[0];
794     }
795
796     protected boolean isClosing() {
797         return closing || getWorkbenchImpl().isClosing();
798     }
799
800     /**
801      * Return whether or not the coolbar layout is locked.
802      */

803     protected boolean isCoolBarLocked() {
804         ICoolBarManager cbm = getCoolBarManager2();
805         return cbm != null && cbm.getLockLayout();
806     }
807
808     /**
809      * Close all of the pages.
810      */

811     private void closeAllPages() {
812         // Deactivate active page.
813
setActivePage(null);
814
815         // Clone and deref all so that calls to getPages() returns
816
// empty list (if call by pageClosed event handlers)
817
PageList oldList = pageList;
818         pageList = new PageList();
819
820         // Close all.
821
Iterator JavaDoc itr = oldList.iterator();
822         while (itr.hasNext()) {
823             WorkbenchPage page = (WorkbenchPage) itr.next();
824             firePageClosed(page);
825             page.dispose();
826         }
827         if (!closing) {
828             showEmptyWindowContents();
829         }
830     }
831
832     /**
833      * Save and close all of the pages.
834      */

835     public void closeAllPages(boolean save) {
836         if (save) {
837             boolean ret = saveAllPages(true);
838             if (!ret) {
839                 return;
840             }
841         }
842         closeAllPages();
843     }
844
845     /**
846      * closePerspective method comment.
847      */

848     protected boolean closePage(IWorkbenchPage in, boolean save) {
849         // Validate the input.
850
if (!pageList.contains(in)) {
851             return false;
852         }
853         WorkbenchPage oldPage = (WorkbenchPage) in;
854
855         // Save old perspective.
856
if (save && oldPage.isSaveNeeded()) {
857             if (!oldPage.saveAllEditors(true)) {
858                 return false;
859             }
860         }
861
862         // If old page is activate deactivate.
863
boolean oldIsActive = (oldPage == getActiveWorkbenchPage());
864         if (oldIsActive) {
865             setActivePage(null);
866         }
867
868         // Close old page.
869
pageList.remove(oldPage);
870         firePageClosed(oldPage);
871         oldPage.dispose();
872
873         // Activate new page.
874
if (oldIsActive) {
875             IWorkbenchPage newPage = pageList.getNextActive();
876             if (newPage != null) {
877                 setActivePage(newPage);
878             }
879         }
880         if (!closing && pageList.isEmpty()) {
881             showEmptyWindowContents();
882         }
883         return true;
884     }
885
886     private void showEmptyWindowContents() {
887         if (!emptyWindowContentsCreated) {
888             Composite parent = getPageComposite();
889             emptyWindowContents = getWindowAdvisor().createEmptyWindowContents(
890                     parent);
891             emptyWindowContentsCreated = true;
892             // force the empty window composite to be layed out
893
((StackLayout) parent.getLayout()).topControl = emptyWindowContents;
894             parent.layout();
895         }
896     }
897
898     private void hideEmptyWindowContents() {
899         if (emptyWindowContentsCreated) {
900             if (emptyWindowContents != null) {
901                 emptyWindowContents.dispose();
902                 emptyWindowContents = null;
903                 getPageComposite().layout();
904             }
905             emptyWindowContentsCreated = false;
906         }
907     }
908
909     /*
910      * (non-Javadoc)
911      *
912      * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
913      */

914     protected void configureShell(Shell shell) {
915         super.configureShell(shell);
916
917         detachedWindowShells = new ShellPool(shell, SWT.TOOL | SWT.TITLE
918                 | SWT.MAX | SWT.RESIZE | getDefaultOrientation());
919
920         String JavaDoc title = getWindowConfigurer().basicGetTitle();
921         if (title != null) {
922             shell.setText(TextProcessor.process(title, TEXT_DELIMITERS));
923         }
924
925         final IWorkbench workbench = getWorkbench();
926         workbench.getHelpSystem().setHelp(shell,
927                 IWorkbenchHelpContextIds.WORKBENCH_WINDOW);
928
929 // initializeDefaultServices();
930
final IContextService contextService = (IContextService) getWorkbench().getService(IContextService.class);
931         contextService.registerShell(shell, IContextService.TYPE_WINDOW);
932
933         trackShellActivation(shell);
934         trackShellResize(shell);
935     }
936
937     /* package */ShellPool getDetachedWindowPool() {
938         return detachedWindowShells;
939     }
940
941     /*
942      * (non-Javadoc)
943      *
944      * @see org.eclipse.jface.window.ApplicationWindow#createTrimWidgets(org.eclipse.swt.widgets.Shell)
945      */

946     protected void createTrimWidgets(Shell shell) {
947         // do nothing -- trim widgets are created in createDefaultContents
948
}
949
950     /**
951      * Creates and remembers the client composite, under which workbench pages
952      * create their controls.
953      *
954      * @since 3.0
955      */

956     protected Composite createPageComposite(Composite parent) {
957         pageComposite = new Composite(parent, SWT.NONE);
958         // use a StackLayout instead of a FillLayout (see bug 81460 [Workbench]
959
// (regression) Close all perspectives, open Java perspective, layout
960
// wrong)
961
pageComposite.setLayout(new StackLayout());
962         return pageComposite;
963     }
964
965     /**
966      * Creates the contents of the workbench window, including trim controls and
967      * the client composite. This MUST create the client composite via a call to
968      * <code>createClientComposite</code>.
969      *
970      * @since 3.0
971      */

972     protected Control createContents(Composite parent) {
973         // we know from Window.create that the parent is a Shell.
974
getWindowAdvisor().createWindowContents((Shell) parent);
975         // the page composite must be set by createWindowContents
976
Assert
977                 .isNotNull(pageComposite,
978                         "createWindowContents must call configurer.createPageComposite"); //$NON-NLS-1$
979
return pageComposite;
980     }
981
982     /**
983      * If the perspective bar is drawn on the top right corner of the window,
984      * then this method changes its appearance from curved to square. This
985      * should have its own preference, but for now it piggy-backs on the
986      * SHOW_TRADITIONAL_STYLE_TABS preference.
987      *
988      * @param square
989      * true for a square banner and false otherwise
990      */

991     public void setBannerCurve(boolean square) {
992         if (topBar != null) {
993             topBar.setSimple(square);
994         }
995     }
996
997     /**
998      * Creates the default contents and layout of the shell.
999      *
1000     * @param shell
1001     * the shell
1002     */

1003    protected void createDefaultContents(final Shell shell) {
1004        defaultLayout = new TrimLayout();
1005        defaultLayout.setSpacing(2, 2, 2, 2);
1006        defaultLayout.setMargins(2, 2);
1007        shell.setLayout(defaultLayout);
1008
1009        Menu menuBar = getMenuBarManager().createMenuBar(shell);
1010        if (getWindowConfigurer().getShowMenuBar()) {
1011            shell.setMenuBar(menuBar);
1012        }
1013
1014        // Create the CBanner widget which parents both the Coolbar
1015
// and the perspective switcher, and supports some configurations
1016
// on the left right and bottom
1017
topBar = new CBanner(shell, SWT.NONE);
1018        topBarTrim = new WindowTrimProxy(topBar,
1019                "org.eclipse.ui.internal.WorkbenchWindow.topBar", //$NON-NLS-1$
1020
WorkbenchMessages.TrimCommon_Main_TrimName, SWT.NONE, true);
1021
1022        // the banner gets a curve along with the new tab style
1023
// TODO create a dedicated preference for this
1024
setBannerCurve(PrefUtil.getAPIPreferenceStore().getBoolean(
1025                IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS));
1026
1027        CacheWrapper coolbarCacheWrapper = new CacheWrapper(topBar);
1028
1029        final Control coolBar = createCoolBarControl(coolbarCacheWrapper
1030                .getControl());
1031        // need to resize the shell, not just the coolbar's immediate
1032
// parent, if the coolbar wants to grow or shrink
1033

1034        coolBar.addListener(SWT.Resize, new Listener() {
1035            public void handleEvent(Event event) {
1036                // If the user is dragging the sash then we will need to force
1037
// a resize. However, if the coolbar was resized programatically
1038
// then everything is already layed out correctly. There is no
1039
// direct way to tell the difference between these cases,
1040
// however
1041
// we take advantage of the fact that dragging the sash does not
1042
// change the size of the shell, and only force another layout
1043
// if the shell size is unchanged.
1044
Rectangle clientArea = shell.getClientArea();
1045
1046                if (lastShellSize.x == clientArea.width
1047                        && lastShellSize.y == clientArea.height) {
1048                    LayoutUtil.resize(coolBar);
1049                }
1050
1051                lastShellSize.x = clientArea.width;
1052                lastShellSize.y = clientArea.height;
1053            }
1054        });
1055
1056        if (getWindowConfigurer().getShowCoolBar()) {
1057            topBar.setLeft(coolbarCacheWrapper.getControl());
1058        }
1059
1060        createStatusLine(shell);
1061
1062        fastViewBar = new FastViewBar(this);
1063        fastViewBar.createControl(shell);
1064
1065        if (getWindowConfigurer().getShowPerspectiveBar()) {
1066            addPerspectiveBar(perspectiveBarStyle());
1067            perspectiveSwitcher.createControl(shell);
1068        }
1069
1070        createProgressIndicator(shell);
1071
1072        if (getShowHeapStatus()) {
1073            createHeapStatus(shell);
1074        }
1075        
1076        // Insert any contributed trim into the layout
1077
// Legacy (3.2) trim
1078
trimMgr2 = new TrimBarManager2(this);
1079        
1080        // 3.3 Trim contributions
1081
trimContributionMgr = new TrimContributionManager(this);
1082        
1083        trimDropTarget = new TrimDropTarget(shell, this);
1084        DragUtil.addDragTarget(shell, trimDropTarget);
1085        DragUtil.addDragTarget(null, trimDropTarget);
1086
1087        // Create the client composite area (where page content goes).
1088
createPageComposite(shell);
1089
1090        setLayoutDataForContents();
1091        // System.err.println(defaultLayout.displayTrim());
1092
}
1093
1094    /**
1095     * Returns whether the heap status indicator should be shown.
1096     *
1097     * @return <code>true</code> to show the heap status indicator,
1098     * <code>false</code> otherwise
1099     */

1100    private boolean getShowHeapStatus() {
1101        return // Show if the preference is set or debug option is on
1102
PrefUtil.getAPIPreferenceStore().getBoolean(
1103                IWorkbenchPreferenceConstants.SHOW_MEMORY_MONITOR)
1104                || Boolean.valueOf(
1105                        Platform.getDebugOption(PlatformUI.PLUGIN_ID
1106                                + "/perf/showHeapStatus")).booleanValue(); //$NON-NLS-1$
1107
}
1108
1109    /**
1110     * Creates the controls for the heap status indicator.
1111     *
1112     * @param parent
1113     * the parent composite
1114     */

1115    private void createHeapStatus(Composite parent) {
1116        heapStatus = new HeapStatus(parent, PrefUtil
1117                .getInternalPreferenceStore());
1118
1119        // Subclass the trim to allow closing...
1120
heapStatusTrim = new WindowTrimProxy(heapStatus,
1121                "org.eclipse.ui.internal.HeapStatus", //$NON-NLS-1$
1122
WorkbenchMessages.TrimCommon_HeapStatus_TrimName, SWT.BOTTOM
1123                        | SWT.TOP) {
1124
1125            public void handleClose() {
1126                getControl().dispose();
1127            }
1128
1129            public boolean isCloseable() {
1130                return true;
1131            }
1132        };
1133    }
1134
1135    /**
1136     * <p>
1137     * Returns a new menu manager for this workbench window. This menu manager
1138     * will just be a proxy to the new command-based menu service.
1139     * </p>
1140     * <p>
1141     * Subclasses may override this method to customize the menu manager.
1142     * </p>
1143     *
1144     * @return a menu manager for this workbench window; never <code>null</code>.
1145     */

1146    protected MenuManager createMenuManager() {
1147        return super.createMenuManager();
1148    }
1149
1150    /**
1151     * Set the perspective bar location
1152     *
1153     * @param location
1154     * the location to place the bar
1155     */

1156    public void setPerspectiveBarLocation(String JavaDoc location) {
1157        if (perspectiveSwitcher != null) {
1158            perspectiveSwitcher.setPerspectiveBarLocation(location);
1159        }
1160    }
1161
1162    /**
1163     * Notifies interested parties (namely the advisor) that the window is about
1164     * to be opened.
1165     *
1166     * @since 3.1
1167     */

1168    private void fireWindowOpening() {
1169        // let the application do further configuration
1170
getWindowAdvisor().preWindowOpen();
1171    }
1172
1173    /**
1174     * Notifies interested parties (namely the advisor) that the window has been
1175     * restored from a previously saved state.
1176     *
1177     * @throws WorkbenchException
1178     * passed through from the advisor
1179     * @since 3.1
1180     */

1181    void fireWindowRestored() throws WorkbenchException {
1182        getWindowAdvisor().postWindowRestore();
1183    }
1184
1185    /**
1186     * Notifies interested parties (namely the advisor) that the window has been
1187     * created.
1188     *
1189     * @since 3.1
1190     */

1191    private void fireWindowCreated() {
1192        getWindowAdvisor().postWindowCreate();
1193    }
1194
1195    /**
1196     * Notifies interested parties (namely the advisor and the window listeners)
1197     * that the window has been opened.
1198     *
1199     * @since 3.1
1200     */

1201    private void fireWindowOpened() {
1202        getWorkbenchImpl().fireWindowOpened(this);
1203        getWindowAdvisor().postWindowOpen();
1204    }
1205
1206    /**
1207     * Notifies interested parties (namely the advisor) that the window's shell
1208     * is closing. Allows the close to be vetoed.
1209     *
1210     * @return <code>true</code> if the close should proceed,
1211     * <code>false</code> if it should be canceled
1212     * @since 3.1
1213     */

1214    private boolean fireWindowShellClosing() {
1215        return getWindowAdvisor().preWindowShellClose();
1216    }
1217
1218    /**
1219     * Notifies interested parties (namely the advisor and the window listeners)
1220     * that the window has been closed.
1221     *
1222     * @since 3.1
1223     */

1224    private void fireWindowClosed() {
1225        // let the application do further deconfiguration
1226
getWindowAdvisor().postWindowClose();
1227        getWorkbenchImpl().fireWindowClosed(this);
1228    }
1229
1230    /**
1231     * Fires page activated
1232     */

1233    private void firePageActivated(IWorkbenchPage page) {
1234        String JavaDoc label = null; // debugging only
1235
if (UIStats.isDebugging(UIStats.NOTIFY_PAGE_LISTENERS)) {
1236            label = "activated " + page.getLabel(); //$NON-NLS-1$
1237
}
1238        try {
1239            UIStats.start(UIStats.NOTIFY_PAGE_LISTENERS, label);
1240            UIListenerLogging.logPageEvent(this, page,
1241                    UIListenerLogging.WPE_PAGE_ACTIVATED);
1242            pageListeners.firePageActivated(page);
1243            partService.pageActivated(page);
1244        } finally {
1245            UIStats.end(UIStats.NOTIFY_PAGE_LISTENERS, page.getLabel(), label);
1246        }
1247    }
1248
1249    /**
1250     * Fires page closed
1251     */

1252    private void firePageClosed(IWorkbenchPage page) {
1253        String JavaDoc label = null; // debugging only
1254
if (UIStats.isDebugging(UIStats.NOTIFY_PAGE_LISTENERS)) {
1255            label = "closed " + page.getLabel(); //$NON-NLS-1$
1256
}
1257        try {
1258            UIStats.start(UIStats.NOTIFY_PAGE_LISTENERS, label);
1259            UIListenerLogging.logPageEvent(this, page,
1260                    UIListenerLogging.WPE_PAGE_CLOSED);
1261            pageListeners.firePageClosed(page);
1262            partService.pageClosed(page);
1263        } finally {
1264            UIStats.end(UIStats.NOTIFY_PAGE_LISTENERS, page.getLabel(), label);
1265        }
1266
1267    }
1268
1269    /**
1270     * Fires page opened
1271     */

1272    private void firePageOpened(IWorkbenchPage page) {
1273        String JavaDoc label = null; // debugging only
1274
if (UIStats.isDebugging(UIStats.NOTIFY_PAGE_LISTENERS)) {
1275            label = "opened " + page.getLabel(); //$NON-NLS-1$
1276
}
1277        try {
1278            UIStats.start(UIStats.NOTIFY_PAGE_LISTENERS, label);
1279            UIListenerLogging.logPageEvent(this, page,
1280                    UIListenerLogging.WPE_PAGE_OPENED);
1281            pageListeners.firePageOpened(page);
1282            partService.pageOpened(page);
1283        } finally {
1284            UIStats.end(UIStats.NOTIFY_PAGE_LISTENERS, page.getLabel(), label);
1285        }
1286    }
1287
1288    /**
1289     * Fires perspective activated
1290     */

1291    void firePerspectiveActivated(IWorkbenchPage page,
1292            IPerspectiveDescriptor perspective) {
1293        UIListenerLogging.logPerspectiveEvent(this, page, perspective,
1294                UIListenerLogging.PLE_PERSP_ACTIVATED);
1295        perspectiveListeners.firePerspectiveActivated(page, perspective);
1296    }
1297
1298    /**
1299     * Fires perspective deactivated.
1300     *
1301     * @since 3.2
1302     */

1303    void firePerspectivePreDeactivate(IWorkbenchPage page,
1304            IPerspectiveDescriptor perspective) {
1305        UIListenerLogging.logPerspectiveEvent(this, page, perspective,
1306                UIListenerLogging.PLE_PERSP_PRE_DEACTIVATE);
1307        perspectiveListeners.firePerspectivePreDeactivate(page, perspective);
1308    }
1309    
1310    /**
1311     * Fires perspective deactivated.
1312     *
1313     * @since 3.1
1314     */

1315    void firePerspectiveDeactivated(IWorkbenchPage page,
1316            IPerspectiveDescriptor perspective) {
1317        UIListenerLogging.logPerspectiveEvent(this, page, perspective,
1318                UIListenerLogging.PLE_PERSP_DEACTIVATED);
1319        perspectiveListeners.firePerspectiveDeactivated(page, perspective);
1320    }
1321
1322    /**
1323     * Fires perspective changed
1324     */

1325    void firePerspectiveChanged(IWorkbenchPage page,
1326            IPerspectiveDescriptor perspective, String JavaDoc changeId) {
1327        // Some callers call this even when there is no active perspective.
1328
// Just ignore this case.
1329
if (perspective != null) {
1330            UIListenerLogging.logPerspectiveChangedEvent(this, page,
1331                    perspective, null, changeId);
1332            perspectiveListeners.firePerspectiveChanged(page, perspective,
1333                    changeId);
1334        }
1335    }
1336
1337    /**
1338     * Fires perspective changed for an affected part
1339     */

1340    void firePerspectiveChanged(IWorkbenchPage page,
1341            IPerspectiveDescriptor perspective,
1342            IWorkbenchPartReference partRef, String JavaDoc changeId) {
1343        // Some callers call this even when there is no active perspective.
1344
// Just ignore this case.
1345
if (perspective != null) {
1346            UIListenerLogging.logPerspectiveChangedEvent(this, page,
1347                    perspective, partRef, changeId);
1348            perspectiveListeners.firePerspectiveChanged(page, perspective,
1349                    partRef, changeId);
1350        }
1351    }
1352
1353    /**
1354     * Fires perspective closed
1355     */

1356    void firePerspectiveClosed(IWorkbenchPage page,
1357            IPerspectiveDescriptor perspective) {
1358        UIListenerLogging.logPerspectiveEvent(this, page, perspective,
1359                UIListenerLogging.PLE_PERSP_CLOSED);
1360        perspectiveListeners.firePerspectiveClosed(page, perspective);
1361    }
1362
1363    /**
1364     * Fires perspective opened
1365     */

1366    void firePerspectiveOpened(IWorkbenchPage page,
1367            IPerspectiveDescriptor perspective) {
1368        UIListenerLogging.logPerspectiveEvent(this, page, perspective,
1369                UIListenerLogging.PLE_PERSP_OPENED);
1370        perspectiveListeners.firePerspectiveOpened(page, perspective);
1371    }
1372
1373    /**
1374     * Fires perspective saved as.
1375     *
1376     * @since 3.1
1377     */

1378    void firePerspectiveSavedAs(IWorkbenchPage page,
1379            IPerspectiveDescriptor oldPerspective,
1380            IPerspectiveDescriptor newPerspective) {
1381        UIListenerLogging.logPerspectiveSavedAs(this, page, oldPerspective,
1382                newPerspective);
1383        perspectiveListeners.firePerspectiveSavedAs(page, oldPerspective,
1384                newPerspective);
1385    }
1386
1387    /**
1388     * Returns the action bars for this window.
1389     */

1390    public WWinActionBars getActionBars() {
1391        if (actionBars == null) {
1392            actionBars = new WWinActionBars(this);
1393        }
1394        return actionBars;
1395    }
1396
1397    /**
1398     * Returns the active page.
1399     *
1400     * @return the active page
1401     */

1402    public IWorkbenchPage getActivePage() {
1403        return pageList.getActive();
1404    }
1405
1406    /**
1407     * Returns the active workbench page.
1408     *
1409     * @return the active workbench page
1410     */

1411    /* package */
1412    WorkbenchPage getActiveWorkbenchPage() {
1413        return pageList.getActive();
1414    }
1415
1416    /**
1417     * Returns the page composite, under which the window's pages create their
1418     * controls.
1419     */

1420    protected Composite getPageComposite() {
1421        return pageComposite;
1422    }
1423
1424    /**
1425     * Answer the menu manager for this window.
1426     */

1427    public MenuManager getMenuManager() {
1428        return getMenuBarManager();
1429    }
1430
1431    /**
1432     * Returns the number. This corresponds to a page number in a window or a
1433     * window number in the workbench.
1434     */

1435    public int getNumber() {
1436        return number;
1437    }
1438
1439    /**
1440     * Returns an array of the pages in the workbench window.
1441     *
1442     * @return an array of pages
1443     */

1444    public IWorkbenchPage[] getPages() {
1445        return pageList.getPages();
1446    }
1447
1448    /**
1449     * @see IWorkbenchWindow
1450     */

1451    public IPartService getPartService() {
1452        return partService;
1453    }
1454
1455    /**
1456     * Returns the layout for the shell.
1457     *
1458     * @return the layout for the shell
1459     */

1460    protected Layout getLayout() {
1461        return null;
1462    }
1463
1464    /**
1465     * @see IWorkbenchWindow
1466     */

1467    public ISelectionService getSelectionService() {
1468        return partService.getSelectionService();
1469    }
1470
1471    /**
1472     * Returns <code>true</code> when the window's shell is activated,
1473     * <code>false</code> when it's shell is deactivated
1474     *
1475     * @return boolean <code>true</code> when shell activated,
1476     * <code>false</code> when shell deactivated
1477     */

1478    public boolean getShellActivated() {
1479        return shellActivated;
1480    }
1481
1482    /**
1483     * Returns the status line manager for this window (if it has one).
1484     *
1485     * @return the status line manager, or <code>null</code> if this window
1486     * does not have a status line
1487     * @see ApplicationWindow#addStatusLine
1488     */

1489    public StatusLineManager getStatusLineManager() {
1490        return super.getStatusLineManager();
1491    }
1492
1493    private IWindowTrim getStatusLineTrim() {
1494        if (statusLineTrim == null) {
1495            statusLineTrim = new WindowTrimProxy(
1496                    getStatusLineManager().getControl(),
1497                    "org.eclipse.jface.action.StatusLineManager", //$NON-NLS-1$
1498
WorkbenchMessages.TrimCommon_StatusLine_TrimName, SWT.NONE,
1499                    true);
1500        }
1501        return statusLineTrim;
1502    }
1503
1504    /**
1505     * @see IWorkbenchWindow
1506     */

1507    public IWorkbench getWorkbench() {
1508        return PlatformUI.getWorkbench();
1509    }
1510
1511    public String JavaDoc getToolbarLabel(String JavaDoc actionSetId) {
1512        ActionSetRegistry registry = WorkbenchPlugin.getDefault()
1513                .getActionSetRegistry();
1514        IActionSetDescriptor actionSet = registry.findActionSet(actionSetId);
1515        if (actionSet != null) {
1516            return actionSet.getLabel();
1517        }
1518
1519        if (IWorkbenchActionConstants.TOOLBAR_FILE
1520                .equalsIgnoreCase(actionSetId)) {
1521            return WorkbenchMessages.WorkbenchWindow_FileToolbar;
1522        }
1523
1524        if (IWorkbenchActionConstants.TOOLBAR_NAVIGATE
1525                .equalsIgnoreCase(actionSetId)) {
1526            return WorkbenchMessages.WorkbenchWindow_NavigateToolbar;
1527        }
1528
1529        return null;
1530    }
1531
1532    /**
1533     * Unconditionally close this window. Assumes the proper flags have been set
1534     * correctly (e.i. closing and updateDisabled)
1535     */

1536    private boolean hardClose() {
1537        boolean result;
1538        try {
1539            // Clear the action sets, fix for bug 27416.
1540
getActionPresentation().clearActionSets();
1541
1542            // Remove the handler submissions. Bug 64024.
1543
final IWorkbench workbench = getWorkbench();
1544            final IHandlerService handlerService = (IHandlerService) workbench.getService(IHandlerService.class);
1545            handlerService.deactivateHandlers(handlerActivations);
1546            final Iterator JavaDoc activationItr = handlerActivations.iterator();
1547            while (activationItr.hasNext()) {
1548                final IHandlerActivation activation = (IHandlerActivation) activationItr
1549                        .next();
1550                activation.getHandler().dispose();
1551            }
1552            handlerActivations.clear();
1553            globalActionHandlersByCommandId.clear();
1554
1555            // Remove the enabled submissions. Bug 64024.
1556
final IContextService contextService = (IContextService) workbench.getService(IContextService.class);
1557            contextService.unregisterShell(getShell());
1558
1559            closeAllPages();
1560
1561            fireWindowClosed();
1562            
1563            // time to wipe our our populate
1564
IMenuService menuService = (IMenuService) workbench
1565                    .getService(IMenuService.class);
1566            menuService
1567                    .releaseContributions(((ContributionManager) getActionBars()
1568                            .getMenuManager()));
1569            ICoolBarManager coolbar = getActionBars().getCoolBarManager();
1570            if (coolbar != null) {
1571                menuService
1572                        .releaseContributions(((ContributionManager) coolbar));
1573            }
1574
1575            getActionBarAdvisor().dispose();
1576            getWindowAdvisor().dispose();
1577            detachedWindowShells.dispose();
1578
1579            // Bring down all of the services.
1580
serviceLocator.dispose();
1581
1582            // Null out the progress region. Bug 64024.
1583
progressRegion = null;
1584            
1585            // Remove drop targets
1586
DragUtil.removeDragTarget(null, trimDropTarget);
1587            DragUtil.removeDragTarget(getShell(), trimDropTarget);
1588            trimDropTarget = null;
1589            
1590            if (trimMgr2 != null) {
1591                trimMgr2.dispose();
1592                trimMgr2 = null;
1593            }
1594            
1595            if (trimContributionMgr != null) {
1596                trimContributionMgr.dispose();
1597                trimContributionMgr = null;
1598            }
1599        } finally {
1600            result = super.close();
1601        }
1602        return result;
1603    }
1604
1605    /**
1606     * @see IWorkbenchWindow
1607     */

1608    public boolean isApplicationMenu(String JavaDoc menuID) {
1609        // delegate this question to the action bar advisor
1610
return getActionBarAdvisor().isApplicationMenu(menuID);
1611    }
1612
1613    /**
1614     * Return whether or not the given id matches the id of the coolitems that
1615     * the application creates.
1616     */

1617    /* package */
1618    boolean isWorkbenchCoolItemId(String JavaDoc id) {
1619        return windowConfigurer.containsCoolItem(id);
1620    }
1621
1622    /**
1623     * Locks/unlocks the CoolBar for the workbench.
1624     *
1625     * @param lock
1626     * whether the CoolBar should be locked or unlocked
1627     */

1628    /* package */
1629    void lockCoolBar(boolean lock) {
1630        getCoolBarManager2().setLockLayout(lock);
1631    }
1632
1633    /**
1634     * Makes the window visible and frontmost.
1635     */

1636    void makeVisible() {
1637        Shell shell = getShell();
1638        if (shell != null && !shell.isDisposed()) {
1639            // see bug 96700 and bug 4414 for a discussion on the use of open()
1640
// here
1641
shell.open();
1642        }
1643    }
1644
1645    /**
1646     * Called when this window is about to be closed.
1647     *
1648     * Subclasses may overide to add code that returns <code>false</code> to
1649     * prevent closing under certain conditions.
1650     */

1651    public boolean okToClose() {
1652        // Save all of the editors.
1653
if (!getWorkbenchImpl().isClosing()) {
1654            if (!saveAllPages(true)) {
1655                return false;
1656            }
1657        }
1658        return true;
1659    }
1660
1661    /**
1662     * Opens a new page.
1663     * <p>
1664     * <b>Note:</b> Since release 2.0, a window is limited to contain at most
1665     * one page. If a page exist in the window when this method is used, then
1666     * another window is created for the new page. Callers are strongly
1667     * recommended to use the <code>IWorkbench.openPerspective</code> APIs to
1668     * programmatically show a perspective.
1669     * </p>
1670     */

1671    public IWorkbenchPage openPage(final String JavaDoc perspId, final IAdaptable input)
1672            throws WorkbenchException {
1673        Assert.isNotNull(perspId);
1674
1675        // Run op in busy cursor.
1676
final Object JavaDoc[] result = new Object JavaDoc[1];
1677        BusyIndicator.showWhile(null, new Runnable JavaDoc() {
1678            public void run() {
1679                try {
1680                    result[0] = busyOpenPage(perspId, input);
1681                } catch (WorkbenchException e) {
1682                    result[0] = e;
1683                }
1684            }
1685        });
1686
1687        if (result[0] instanceof IWorkbenchPage) {
1688            return (IWorkbenchPage) result[0];
1689        } else if (result[0] instanceof WorkbenchException) {
1690            throw (WorkbenchException) result[0];
1691        } else {
1692            throw new WorkbenchException(
1693                    WorkbenchMessages.WorkbenchWindow_exceptionMessage);
1694        }
1695    }
1696
1697    /**
1698     * Opens a new page.
1699     * <p>
1700     * <b>Note:</b> Since release 2.0, a window is limited to contain at most
1701     * one page. If a page exist in the window when this method is used, then
1702     * another window is created for the new page. Callers are strongly
1703     * recommended to use the <code>IWorkbench.openPerspective</code> APIs to
1704     * programmatically show a perspective.
1705     * </p>
1706     */

1707    public IWorkbenchPage openPage(IAdaptable input) throws WorkbenchException {
1708        String JavaDoc perspId = getWorkbenchImpl().getPerspectiveRegistry()
1709                .getDefaultPerspective();
1710        return openPage(perspId, input);
1711    }
1712
1713    /*
1714     * Removes an listener from the part service.
1715     */

1716    public void removePageListener(IPageListener l) {
1717        pageListeners.removePageListener(l);
1718    }
1719
1720    /**
1721     * @see org.eclipse.ui.IPageService
1722     */

1723    public void removePerspectiveListener(org.eclipse.ui.IPerspectiveListener l) {
1724        perspectiveListeners.removePerspectiveListener(l);
1725    }
1726
1727    private IStatus unableToRestorePage(IMemento pageMem) {
1728        String JavaDoc pageName = pageMem.getString(IWorkbenchConstants.TAG_LABEL);
1729        if (pageName == null) {
1730            pageName = ""; //$NON-NLS-1$
1731
}
1732        return new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, NLS.bind(
1733                WorkbenchMessages.WorkbenchWindow_unableToRestorePerspective,
1734                pageName), null);
1735    }
1736
1737    public IStatus restoreState(IMemento memento,
1738            IPerspectiveDescriptor activeDescriptor) {
1739        Assert.isNotNull(getShell());
1740
1741        final MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK,
1742                WorkbenchMessages.WorkbenchWindow_problemsRestoringWindow, null);
1743
1744        // Restore the window advisor state.
1745
IMemento windowAdvisorState = memento
1746                .getChild(IWorkbenchConstants.TAG_WORKBENCH_WINDOW_ADVISOR);
1747        if (windowAdvisorState != null) {
1748            result.add(getWindowAdvisor().restoreState(windowAdvisorState));
1749        }
1750
1751        // Restore actionbar advisor state.
1752
IMemento actionBarAdvisorState = memento
1753                .getChild(IWorkbenchConstants.TAG_ACTION_BAR_ADVISOR);
1754        if (actionBarAdvisorState != null) {
1755            result.add(getActionBarAdvisor()
1756                    .restoreState(actionBarAdvisorState));
1757        }
1758
1759        // Read window's bounds and state.
1760
final Rectangle [] displayBounds = new Rectangle[1];
1761        StartupThreading.runWithoutExceptions(new StartupRunnable() {
1762
1763            public void runWithException() {
1764                displayBounds[0] = getShell().getDisplay().getBounds();
1765                
1766            }});
1767        final Rectangle shellBounds = new Rectangle(0, 0, 0, 0);
1768
1769        final IMemento fastViewMem = memento
1770                .getChild(IWorkbenchConstants.TAG_FAST_VIEW_DATA);
1771        if (fastViewMem != null) {
1772            if (fastViewBar != null) {
1773                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1774
1775                    public void runWithException() {
1776                        fastViewBar.restoreState(fastViewMem);
1777                    }});
1778                
1779            }
1780        }
1781        Integer JavaDoc bigInt = memento.getInteger(IWorkbenchConstants.TAG_X);
1782        shellBounds.x = bigInt == null ? 0 : bigInt.intValue();
1783        bigInt = memento.getInteger(IWorkbenchConstants.TAG_Y);
1784        shellBounds.y = bigInt == null ? 0 : bigInt.intValue();
1785        bigInt = memento.getInteger(IWorkbenchConstants.TAG_WIDTH);
1786        shellBounds.width = bigInt == null ? 0 : bigInt.intValue();
1787        bigInt = memento.getInteger(IWorkbenchConstants.TAG_HEIGHT);
1788        shellBounds.height = bigInt == null ? 0 : bigInt.intValue();
1789        if (!shellBounds.isEmpty()) {
1790            StartupThreading.runWithoutExceptions(new StartupRunnable() {
1791
1792                public void runWithException() {
1793                    if (!shellBounds.intersects(displayBounds[0])) {
1794                        Rectangle clientArea = getShell().getDisplay().getClientArea();
1795                        shellBounds.x = clientArea.x;
1796                        shellBounds.y = clientArea.y;
1797                    }
1798                    getShell().setBounds(shellBounds);
1799                }});
1800        }
1801        if ("true".equals(memento.getString(IWorkbenchConstants.TAG_MAXIMIZED))) { //$NON-NLS-1$
1802
StartupThreading.runWithoutExceptions(new StartupRunnable() {
1803
1804                public void runWithException() {
1805                    getShell().setMaximized(true);
1806                }});
1807            
1808        }
1809        if ("true".equals(memento.getString(IWorkbenchConstants.TAG_MINIMIZED))) { //$NON-NLS-1$
1810
// getShell().setMinimized(true);
1811
}
1812
1813        // restore the width of the perspective bar
1814
if (perspectiveSwitcher != null) {
1815            perspectiveSwitcher.restoreState(memento);
1816        }
1817
1818        // Restore the cool bar order by creating all the tool bar contribution
1819
// items
1820
// This needs to be done before pages are created to ensure proper
1821
// canonical creation
1822
// of cool items
1823
final ICoolBarManager2 coolBarMgr = (ICoolBarManager2) getCoolBarManager2();
1824        if (coolBarMgr != null) {
1825            IMemento coolBarMem = memento
1826                    .getChild(IWorkbenchConstants.TAG_COOLBAR_LAYOUT);
1827            if (coolBarMem != null) {
1828                // Check if the layout is locked
1829
final Integer JavaDoc lockedInt = coolBarMem
1830                        .getInteger(IWorkbenchConstants.TAG_LOCKED);
1831                StartupThreading.runWithoutExceptions(new StartupRunnable(){
1832
1833                    public void runWithException() {
1834                        if ((lockedInt != null) && (lockedInt.intValue() == 1)) {
1835                            coolBarMgr.setLockLayout(true);
1836                        } else {
1837                            coolBarMgr.setLockLayout(false);
1838                        }
1839                    }});
1840                
1841                // The new layout of the cool bar manager
1842
ArrayList JavaDoc coolBarLayout = new ArrayList JavaDoc();
1843                // Traverse through all the cool item in the memento
1844
IMemento contributionMems[] = coolBarMem
1845                        .getChildren(IWorkbenchConstants.TAG_COOLITEM);
1846                for (int i = 0; i < contributionMems.length; i++) {
1847                    IMemento contributionMem = contributionMems[i];
1848                    String JavaDoc type = contributionMem
1849                            .getString(IWorkbenchConstants.TAG_ITEM_TYPE);
1850                    if (type == null) {
1851                        // Do not recognize that type
1852
continue;
1853                    }
1854                    String JavaDoc id = contributionMem
1855                            .getString(IWorkbenchConstants.TAG_ID);
1856
1857                    // Prevent duplicate items from being read back in.
1858
IContributionItem existingItem = coolBarMgr.find(id);
1859                    if ((id != null) && (existingItem != null)) {
1860                        if (Policy.DEBUG_TOOLBAR_DISPOSAL) {
1861                            System.out
1862                                    .println("Not loading duplicate cool bar item: " + id); //$NON-NLS-1$
1863
}
1864                        coolBarLayout.add(existingItem);
1865                        continue;
1866                    }
1867                    IContributionItem newItem = null;
1868                    if (type.equals(IWorkbenchConstants.TAG_TYPE_SEPARATOR)) {
1869                        if (id != null) {
1870                            newItem = new Separator(id);
1871                        } else {
1872                            newItem = new Separator();
1873                        }
1874                    } else if (id != null) {
1875                        if (type
1876                                .equals(IWorkbenchConstants.TAG_TYPE_GROUPMARKER)) {
1877                            newItem = new GroupMarker(id);
1878
1879                        } else if (type
1880                                .equals(IWorkbenchConstants.TAG_TYPE_TOOLBARCONTRIBUTION)
1881                                || type
1882                                        .equals(IWorkbenchConstants.TAG_TYPE_PLACEHOLDER)) {
1883
1884                            // Get Width and height
1885
Integer JavaDoc width = contributionMem
1886                                    .getInteger(IWorkbenchConstants.TAG_ITEM_X);
1887                            Integer JavaDoc height = contributionMem
1888                                    .getInteger(IWorkbenchConstants.TAG_ITEM_Y);
1889                            // Look for the object in the current cool bar
1890
// manager
1891
IContributionItem oldItem = coolBarMgr.find(id);
1892                            // If a tool bar contribution item already exists
1893
// for this id then use the old object
1894
if (oldItem != null) {
1895                                newItem = oldItem;
1896                            } else {
1897                                IActionBarPresentationFactory actionBarPresentation = getActionBarPresentationFactory();
1898                                newItem = actionBarPresentation.createToolBarContributionItem(
1899                                        actionBarPresentation.createToolBarManager(), id);
1900                                if (type
1901                                        .equals(IWorkbenchConstants.TAG_TYPE_PLACEHOLDER)) {
1902                                    IToolBarContributionItem newToolBarItem = (IToolBarContributionItem) newItem;
1903                                    if (height != null) {
1904                                        newToolBarItem.setCurrentHeight(height
1905                                                .intValue());
1906                                    }
1907                                    if (width != null) {
1908                                        newToolBarItem.setCurrentWidth(width
1909                                                .intValue());
1910                                    }
1911                                    newItem = new PlaceholderContributionItem(
1912                                            newToolBarItem);
1913                                }
1914                                // make it invisible by default
1915
newItem.setVisible(false);
1916                                // Need to add the item to the cool bar manager
1917
// so that its canonical order can be preserved
1918
IContributionItem refItem = findAlphabeticalOrder(
1919                                        IWorkbenchActionConstants.MB_ADDITIONS,
1920                                        id, coolBarMgr);
1921                                if (refItem != null) {
1922                                    coolBarMgr.insertAfter(refItem.getId(),
1923                                            newItem);
1924                                } else {
1925                                    coolBarMgr.add(newItem);
1926                                }
1927                            }
1928                            // Set the current height and width
1929
if ((width != null)
1930                                    && (newItem instanceof IToolBarContributionItem)) {
1931                                ((IToolBarContributionItem) newItem)
1932                                        .setCurrentWidth(width.intValue());
1933                            }
1934                            if ((height != null)
1935                                    && (newItem instanceof IToolBarContributionItem)) {
1936                                ((IToolBarContributionItem) newItem)
1937                                        .setCurrentHeight(height.intValue());
1938                            }
1939                        }
1940                    }
1941                    // Add new item into cool bar manager
1942
if (newItem != null) {
1943                        coolBarLayout.add(newItem);
1944                        newItem.setParent(coolBarMgr);
1945                        coolBarMgr.markDirty();
1946                    }
1947                }
1948
1949                // We need to check if we have everything we need in the layout.
1950
final ArrayList JavaDoc finalLayout = new ArrayList JavaDoc();
1951                IContributionItem[] existingItems = coolBarMgr.getItems();
1952                for (int i = 0; i < existingItems.length; i++) {
1953                    IContributionItem existingItem = existingItems[i];
1954
1955                    /*
1956                     * This line shouldn't be necessary, but is here for
1957                     * robustness.
1958                     */

1959                    if (existingItem == null) {
1960                        continue;
1961                    }
1962
1963                    boolean found = false;
1964                    Iterator JavaDoc layoutItemItr = coolBarLayout.iterator();
1965                    while (layoutItemItr.hasNext()) {
1966                        IContributionItem layoutItem = (IContributionItem) layoutItemItr
1967                                .next();
1968                        if ((layoutItem != null)
1969                                && (layoutItem.equals(existingItem))) {
1970                            found = true;
1971                            break;
1972                        }
1973                    }
1974
1975                    if (!found) {
1976                        if (existingItem != null) {
1977                            finalLayout.add(existingItem);
1978                        }
1979                    }
1980                }
1981
1982                // Set the cool bar layout to the given layout.
1983
finalLayout.addAll(coolBarLayout);
1984                final IContributionItem[] itemsToSet = new IContributionItem[finalLayout
1985                        .size()];
1986                finalLayout.toArray(itemsToSet);
1987                StartupThreading.runWithoutExceptions(new StartupRunnable() {
1988
1989                    public void runWithException() {
1990                        coolBarMgr.setItems(itemsToSet);
1991                    }});
1992                
1993            } else {
1994                // For older workbenchs
1995
coolBarMem = memento
1996                        .getChild(IWorkbenchConstants.TAG_TOOLBAR_LAYOUT);
1997                if (coolBarMem != null) {
1998                    // Restore an older layout
1999
restoreOldCoolBar(coolBarMem);
2000                }
2001            }
2002        }
2003
2004        // Recreate each page in the window.
2005
IWorkbenchPage newActivePage = null;
2006        IMemento[] pageArray = memento
2007                .getChildren(IWorkbenchConstants.TAG_PAGE);
2008        for (int i = 0; i < pageArray.length; i++) {
2009            final IMemento pageMem = pageArray[i];
2010            String JavaDoc strFocus = pageMem.getString(IWorkbenchConstants.TAG_FOCUS);
2011            if (strFocus == null || strFocus.length() == 0) {
2012                continue;
2013            }
2014
2015            // Get the input factory.
2016
final IAdaptable [] input = new IAdaptable[1];
2017            final IMemento inputMem = pageMem.getChild(IWorkbenchConstants.TAG_INPUT);
2018            if (inputMem != null) {
2019                final String JavaDoc factoryID = inputMem
2020                        .getString(IWorkbenchConstants.TAG_FACTORY_ID);
2021                if (factoryID == null) {
2022                    WorkbenchPlugin
2023                            .log("Unable to restore page - no input factory ID."); //$NON-NLS-1$
2024
result.add(unableToRestorePage(pageMem));
2025                    continue;
2026                }
2027                try {
2028                    UIStats.start(UIStats.RESTORE_WORKBENCH,
2029                            "WorkbenchPageFactory"); //$NON-NLS-1$
2030
StartupThreading
2031                            .runWithoutExceptions(new StartupRunnable() {
2032
2033                                public void runWithException() throws Throwable JavaDoc {
2034                                    IElementFactory factory = PlatformUI
2035                                            .getWorkbench().getElementFactory(
2036                                                    factoryID);
2037                                    if (factory == null) {
2038                                        WorkbenchPlugin
2039                                                .log("Unable to restore page - cannot instantiate input factory: " + factoryID); //$NON-NLS-1$
2040
result
2041                                                .add(unableToRestorePage(pageMem));
2042                                        return;
2043                                    }
2044
2045                                    // Get the input element.
2046
input[0] = factory.createElement(inputMem);
2047                                }
2048                            });
2049                    
2050                    if (input[0] == null) {
2051                        WorkbenchPlugin
2052                                .log("Unable to restore page - cannot instantiate input element: " + factoryID); //$NON-NLS-1$
2053
result.add(unableToRestorePage(pageMem));
2054                        continue;
2055                    }
2056                } finally {
2057                    UIStats.end(UIStats.RESTORE_WORKBENCH, factoryID,
2058                            "WorkbenchPageFactory"); //$NON-NLS-1$
2059
}
2060            }
2061            // Open the perspective.
2062
final IAdaptable finalInput = input[0];
2063            final WorkbenchPage [] newPage = new WorkbenchPage[1];
2064            try {
2065                StartupThreading.runWithWorkbenchExceptions(new StartupRunnable(){
2066
2067                    public void runWithException() throws WorkbenchException {
2068                        newPage[0] = new WorkbenchPage(WorkbenchWindow.this, finalInput);
2069                    }});
2070                
2071                result.add(newPage[0].restoreState(pageMem, activeDescriptor));
2072                pageList.add(newPage[0]);
2073                StartupThreading.runWithoutExceptions(new StartupRunnable() {
2074
2075                    public void runWithException() throws Throwable JavaDoc {
2076                        firePageOpened(newPage[0]);
2077                    }});
2078                
2079            } catch (WorkbenchException e) {
2080                WorkbenchPlugin
2081                        .log(
2082                                "Unable to restore perspective - constructor failed.", e); //$NON-NLS-1$
2083
result.add(e.getStatus());
2084                continue;
2085            }
2086
2087            if (strFocus != null && strFocus.length() > 0) {
2088                newActivePage = newPage[0];
2089            }
2090        }
2091
2092        // If there are no pages create a default.
2093
if (pageList.isEmpty()) {
2094            try {
2095                final String JavaDoc defPerspID = getWorkbenchImpl().getPerspectiveRegistry()
2096                        .getDefaultPerspective();
2097                if (defPerspID != null) {
2098                    final WorkbenchPage [] newPage = new WorkbenchPage[1];
2099                    StartupThreading.runWithWorkbenchExceptions(new StartupRunnable() {
2100                        
2101                        public void runWithException() throws Throwable JavaDoc {
2102                            newPage[0] = new WorkbenchPage(WorkbenchWindow.this, defPerspID,
2103                                    getDefaultPageInput());
2104                        }});
2105                    
2106                    pageList.add(newPage[0]);
2107                    StartupThreading.runWithoutExceptions(new StartupRunnable() {
2108
2109                        public void runWithException() throws Throwable JavaDoc {
2110                            firePageOpened(newPage[0]);
2111                        }});
2112                }
2113            } catch (WorkbenchException e) {
2114                WorkbenchPlugin
2115                        .log(
2116                                "Unable to create default perspective - constructor failed.", e); //$NON-NLS-1$
2117
result.add(e.getStatus());
2118                String JavaDoc productName = WorkbenchPlugin.getDefault()
2119                        .getProductName();
2120                if (productName == null) {
2121                    productName = ""; //$NON-NLS-1$
2122
}
2123                getShell().setText(productName);
2124            }
2125        }
2126
2127        // Set active page.
2128
if (newActivePage == null) {
2129            newActivePage = pageList.getNextActive();
2130        }
2131        final IWorkbenchPage myPage = newActivePage;
2132        StartupThreading.runWithoutExceptions(new StartupRunnable() {
2133
2134            public void runWithException() throws Throwable JavaDoc {
2135                setActivePage(myPage);
2136            }});
2137        
2138
2139        final IMemento introMem = memento.getChild(IWorkbenchConstants.TAG_INTRO);
2140        if (introMem != null) {
2141            StartupThreading.runWithoutExceptions(new StartupRunnable() {
2142
2143                public void runWithException() throws Throwable JavaDoc {
2144                    getWorkbench()
2145                            .getIntroManager()
2146                            .showIntro(
2147                                    WorkbenchWindow.this,
2148                                    Boolean
2149                                            .valueOf(
2150                                                    introMem
2151                                                            .getString(IWorkbenchConstants.TAG_STANDBY))
2152                                            .booleanValue());
2153                }
2154            });
2155
2156        }
2157        
2158        // Only restore the trim state if we're using the default layout
2159
if (defaultLayout != null) {
2160            // Restore the trim state. We pass in the 'root'
2161
// memento since we have to check for pre-3.2
2162
// state.
2163
result.add(restoreTrimState(memento));
2164        }
2165        
2166        return result;
2167    }
2168
2169    /**
2170     * Restores cool item order from an old workbench.
2171     */

2172    private boolean restoreOldCoolBar(IMemento coolbarMem) {
2173        // Make sure the tag exist
2174
if (coolbarMem == null) {
2175            return false;
2176        }
2177        ICoolBarManager2 coolBarMgr = (ICoolBarManager2) getCoolBarManager2();
2178        // Check to see if layout is locked
2179
Integer JavaDoc locked = coolbarMem.getInteger(IWorkbenchConstants.TAG_LOCKED);
2180        boolean state = (locked != null) && (locked.intValue() == 1);
2181        coolBarMgr.setLockLayout(state);
2182
2183        // Get the visual layout
2184
IMemento visibleLayout = coolbarMem
2185                .getChild(IWorkbenchConstants.TAG_TOOLBAR_LAYOUT);
2186        ArrayList JavaDoc visibleWrapIndicies = new ArrayList JavaDoc();
2187        ArrayList JavaDoc visibleItems = new ArrayList JavaDoc();
2188        if (visibleLayout != null) {
2189            if (readLayout(visibleLayout, visibleItems, visibleWrapIndicies) == false) {
2190                return false;
2191            }
2192        }
2193        // Get the remembered layout
2194
IMemento rememberedLayout = coolbarMem
2195                .getChild(IWorkbenchConstants.TAG_LAYOUT);
2196        ArrayList JavaDoc rememberedWrapIndicies = new ArrayList JavaDoc();
2197        ArrayList JavaDoc rememberedItems = new ArrayList JavaDoc();
2198        if (rememberedLayout != null) {
2199            if (readLayout(rememberedLayout, rememberedItems,
2200                    rememberedWrapIndicies) == false) {
2201                return false;
2202            }
2203        }
2204
2205        // Create the objects
2206
if (visibleItems != null) {
2207            // Merge remembered layout into visible layout
2208
if (rememberedItems != null) {
2209                // Traverse through all the remembered items
2210
int currentIndex = 0;
2211                for (Iterator JavaDoc i = rememberedItems.iterator(); i.hasNext(); currentIndex++) {
2212                    String JavaDoc id = (String JavaDoc) i.next();
2213                    int index = -1;
2214                    for (Iterator JavaDoc iter = visibleItems.iterator(); iter
2215                            .hasNext();) {
2216                        String JavaDoc visibleId = (String JavaDoc) iter.next();
2217                        if (visibleId.equals(id)) {
2218                            index = visibleItems.indexOf(visibleId);
2219                            break;
2220                        }
2221                    }
2222                    // The item is not in the visible list
2223
if (index == -1) {
2224                        int insertAt = Math.max(0, Math.min(currentIndex,
2225                                visibleItems.size()));
2226                        boolean separateLine = false;
2227                        // Check whether this item is on a separate line
2228
for (Iterator JavaDoc iter = rememberedWrapIndicies.iterator(); iter
2229                                .hasNext();) {
2230                            Integer JavaDoc wrapIndex = (Integer JavaDoc) iter.next();
2231                            if (wrapIndex.intValue() <= insertAt) {
2232                                insertAt = visibleItems.size();
2233                                // Add new wrap index for this Item
2234
visibleWrapIndicies.add(new Integer JavaDoc(insertAt));
2235                                separateLine = true;
2236                            }
2237                        }
2238                        // Add item to array list
2239
visibleItems.add(insertAt, id);
2240                        // If the item was not on a separate line then adjust
2241
// the visible wrap indicies
2242
if (!separateLine) {
2243                            // Adjust visible wrap indicies
2244
for (int j = 0; j < visibleWrapIndicies.size(); j++) {
2245                                Integer JavaDoc index2 = (Integer JavaDoc) visibleWrapIndicies
2246                                        .get(j);
2247                                if (index2.intValue() >= insertAt) {
2248                                    visibleWrapIndicies.set(j, new Integer JavaDoc(
2249                                            index2.intValue() + 1));
2250                                }
2251                            }
2252                        }
2253                    }
2254                }
2255            }
2256            // The new layout of the cool bar manager
2257
ArrayList JavaDoc coolBarLayout = new ArrayList JavaDoc(visibleItems.size());
2258            // Add all visible items to the layout object
2259
for (Iterator JavaDoc i = visibleItems.iterator(); i.hasNext();) {
2260                String JavaDoc id = (String JavaDoc) i.next();
2261                // Look for the object in the current cool bar manager
2262
IContributionItem oldItem = null;
2263                IContributionItem newItem = null;
2264                if (id != null) {
2265                    oldItem = coolBarMgr.find(id);
2266                }
2267                // If a tool bar contribution item already exists for this id
2268
// then use the old object
2269
if (oldItem instanceof IToolBarContributionItem) {
2270                    newItem = oldItem;
2271                } else {
2272                    IActionBarPresentationFactory actionBarPresentaiton = getActionBarPresentationFactory();
2273                    newItem = actionBarPresentaiton.createToolBarContributionItem(
2274                                    actionBarPresentaiton.createToolBarManager(), id);
2275                    // make it invisible by default
2276
newItem.setVisible(false);
2277                    // Need to add the item to the cool bar manager so that its
2278
// canonical order can be preserved
2279
IContributionItem refItem = findAlphabeticalOrder(
2280                            IWorkbenchActionConstants.MB_ADDITIONS, id,
2281                            coolBarMgr);
2282                    if (refItem != null) {
2283                        coolBarMgr.insertAfter(refItem.getId(), newItem);
2284                    } else {
2285                        coolBarMgr.add(newItem);
2286                    }
2287                }
2288                // Add new item into cool bar manager
2289
if (newItem != null) {
2290                    coolBarLayout.add(newItem);
2291                    newItem.setParent(coolBarMgr);
2292                    coolBarMgr.markDirty();
2293                }
2294            }
2295
2296            // Add separators to the displayed Items data structure
2297
int offset = 0;
2298            for (int i = 1; i < visibleWrapIndicies.size(); i++) {
2299                int insertAt = ((Integer JavaDoc) visibleWrapIndicies.get(i))
2300                        .intValue()
2301                        + offset;
2302                coolBarLayout.add(insertAt, new Separator(
2303                        CoolBarManager.USER_SEPARATOR));
2304                offset++;
2305            }
2306
2307            // Add any group markers in their appropriate places
2308
IContributionItem[] items = coolBarMgr.getItems();
2309            for (int i = 0; i < items.length; i++) {
2310                IContributionItem item = items[i];
2311                if (item.isGroupMarker()) {
2312                    coolBarLayout.add(Math.max(Math
2313                            .min(i, coolBarLayout.size()), 0), item);
2314                }
2315            }
2316            IContributionItem[] itemsToSet = new IContributionItem[coolBarLayout
2317                    .size()];
2318            coolBarLayout.toArray(itemsToSet);
2319            coolBarMgr.setItems(itemsToSet);
2320        }
2321        return true;
2322    }
2323
2324    /**
2325     * Helper method used for restoring an old cool bar layout. This method
2326     * reads the memento and populatates the item id's and wrap indicies.
2327     */

2328    private boolean readLayout(IMemento memento, ArrayList JavaDoc itemIds,
2329            ArrayList JavaDoc wrapIndicies) {
2330        // Get the Wrap indicies
2331
IMemento[] wraps = memento
2332                .getChildren(IWorkbenchConstants.TAG_ITEM_WRAP_INDEX);
2333        if (wraps == null) {
2334            return false;
2335        }
2336        for (int i = 0; i < wraps.length; i++) {
2337            IMemento wrapMem = wraps[i];
2338            Integer JavaDoc index = wrapMem.getInteger(IWorkbenchConstants.TAG_INDEX);
2339            if (index == null) {
2340                return false;
2341            }
2342            wrapIndicies.add(index);
2343        }
2344        // Get the Item ids
2345
IMemento[] savedItems = memento
2346                .getChildren(IWorkbenchConstants.TAG_ITEM);
2347        if (savedItems == null) {
2348            return false;
2349        }
2350        for (int i = 0; i < savedItems.length; i++) {
2351            IMemento savedMem = savedItems[i];
2352            String JavaDoc id = savedMem.getString(IWorkbenchConstants.TAG_ID);
2353            if (id == null) {
2354                return false;
2355            }
2356            itemIds.add(id);
2357        }
2358        return true;
2359    }
2360
2361    /**
2362     * Returns the contribution item that the given contribution item should be
2363     * inserted after.
2364     *
2365     * @param startId
2366     * the location to start looking alphabetically.
2367     * @param itemId
2368     * the target item id.
2369     * @param mgr
2370     * the contribution manager.
2371     * @return the contribution item that the given items should be returned
2372     * after.
2373     */

2374    private IContributionItem findAlphabeticalOrder(String JavaDoc startId,
2375            String JavaDoc itemId, IContributionManager mgr) {
2376        IContributionItem[] items = mgr.getItems();
2377        int insertIndex = 0;
2378
2379        // look for starting point
2380
while (insertIndex < items.length) {
2381            IContributionItem item = items[insertIndex];
2382            if (item.getId() != null && item.getId().equals(startId)) {
2383                break;
2384            }
2385            ++insertIndex;
2386        }
2387
2388        // Find the index that this item should be inserted in
2389
for (int i = insertIndex + 1; i < items.length; i++) {
2390            IContributionItem item = items[i];
2391            String JavaDoc testId = item.getId();
2392
2393            if (item.isGroupMarker()) {
2394                break;
2395            }
2396
2397            if (itemId != null && testId != null) {
2398                if (itemId.compareTo(testId) < 1) {
2399                    break;
2400                }
2401            }
2402            insertIndex = i;
2403        }
2404        if (insertIndex >= items.length) {
2405            return null;
2406        }
2407        return items[insertIndex];
2408    }
2409
2410    /*
2411     * (non-Javadoc) Method declared on IRunnableContext.
2412     */

2413    public void run(boolean fork, boolean cancelable,
2414            IRunnableWithProgress runnable) throws InvocationTargetException JavaDoc,
2415            InterruptedException JavaDoc {
2416        IWorkbenchContextSupport contextSupport = getWorkbench()
2417                .getContextSupport();
2418        final boolean keyFilterEnabled = contextSupport.isKeyFilterEnabled();
2419
2420        Control fastViewBarControl = getFastViewBar() == null ? null
2421                : getFastViewBar().getControl();
2422        boolean fastViewBarWasEnabled = fastViewBarControl == null ? false
2423                : fastViewBarControl.getEnabled();
2424
2425        Control perspectiveBarControl = getPerspectiveBar() == null ? null
2426                : getPerspectiveBar().getControl();
2427        boolean perspectiveBarWasEnabled = perspectiveBarControl == null ? false
2428                : perspectiveBarControl.getEnabled();
2429
2430        // Cache for any diabled trim controls
2431
List JavaDoc disabledControls = null;
2432        
2433        try {
2434            if (fastViewBarControl != null && !fastViewBarControl.isDisposed()) {
2435                fastViewBarControl.setEnabled(false);
2436            }
2437
2438            if (perspectiveBarControl != null
2439                    && !perspectiveBarControl.isDisposed()) {
2440                perspectiveBarControl.setEnabled(false);
2441            }
2442
2443            if (keyFilterEnabled) {
2444                contextSupport.setKeyFilterEnabled(false);
2445            }
2446
2447            // Disable all trim -except- the StatusLine
2448
if (defaultLayout != null)
2449                disabledControls = defaultLayout.disableTrim(getStatusLineTrim());
2450
2451            super.run(fork, cancelable, runnable);
2452        } finally {
2453            if (fastViewBarControl != null && !fastViewBarControl.isDisposed()) {
2454                fastViewBarControl.setEnabled(fastViewBarWasEnabled);
2455            }
2456
2457            if (perspectiveBarControl != null
2458                    && !perspectiveBarControl.isDisposed()) {
2459                perspectiveBarControl.setEnabled(perspectiveBarWasEnabled);
2460            }
2461
2462            if (keyFilterEnabled) {
2463                contextSupport.setKeyFilterEnabled(true);
2464            }
2465            
2466            // Re-enable any disabled trim
2467
if (defaultLayout != null && disabledControls != null)
2468                defaultLayout.enableTrim(disabledControls);
2469        }
2470    }
2471
2472    /**
2473     * Save all of the pages. Returns true if the operation succeeded.
2474     */

2475    private boolean saveAllPages(boolean bConfirm) {
2476        boolean bRet = true;
2477        Iterator JavaDoc itr = pageList.iterator();
2478        while (bRet && itr.hasNext()) {
2479            WorkbenchPage page = (WorkbenchPage) itr.next();
2480            bRet = page.saveAllEditors(bConfirm);
2481        }
2482        return bRet;
2483    }
2484
2485    /**
2486     * @see IPersistable
2487     */

2488    public IStatus saveState(IMemento memento) {
2489
2490        MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK,
2491                WorkbenchMessages.WorkbenchWindow_problemsSavingWindow, null);
2492
2493        // Save the window's state and bounds.
2494
if (getShell().getMaximized() || asMaximizedState) {
2495            memento.putString(IWorkbenchConstants.TAG_MAXIMIZED, "true"); //$NON-NLS-1$
2496
}
2497        if (getShell().getMinimized()) {
2498            memento.putString(IWorkbenchConstants.TAG_MINIMIZED, "true"); //$NON-NLS-1$
2499
}
2500        if (normalBounds == null) {
2501            normalBounds = getShell().getBounds();
2502        }
2503        IMemento fastViewBarMem = memento
2504                .createChild(IWorkbenchConstants.TAG_FAST_VIEW_DATA);
2505        if (fastViewBar != null) {
2506            fastViewBar.saveState(fastViewBarMem);
2507        }
2508
2509        memento.putInteger(IWorkbenchConstants.TAG_X, normalBounds.x);
2510        memento.putInteger(IWorkbenchConstants.TAG_Y, normalBounds.y);
2511        memento.putInteger(IWorkbenchConstants.TAG_WIDTH, normalBounds.width);
2512        memento.putInteger(IWorkbenchConstants.TAG_HEIGHT, normalBounds.height);
2513
2514        IWorkbenchPage activePage = getActivePage();
2515        if (activePage != null
2516                && activePage.findView(IIntroConstants.INTRO_VIEW_ID) != null) {
2517            IMemento introMem = memento
2518                    .createChild(IWorkbenchConstants.TAG_INTRO);
2519            boolean isStandby = getWorkbench()
2520                    .getIntroManager()
2521                    .isIntroStandby(getWorkbench().getIntroManager().getIntro());
2522            introMem.putString(IWorkbenchConstants.TAG_STANDBY, String
2523                    .valueOf(isStandby));
2524        }
2525
2526        // save the width of the perspective bar
2527
IMemento persBarMem = memento
2528                .createChild(IWorkbenchConstants.TAG_PERSPECTIVE_BAR);
2529        if (perspectiveSwitcher != null) {
2530            perspectiveSwitcher.saveState(persBarMem);
2531        }
2532
2533        // / Save the order of the cool bar contribution items
2534
ICoolBarManager2 coolBarMgr = (ICoolBarManager2) getCoolBarManager2();
2535        if (coolBarMgr != null) {
2536            coolBarMgr.refresh();
2537            IMemento coolBarMem = memento
2538                    .createChild(IWorkbenchConstants.TAG_COOLBAR_LAYOUT);
2539            if (coolBarMgr.getLockLayout() == true) {
2540                coolBarMem.putInteger(IWorkbenchConstants.TAG_LOCKED, 1);
2541            } else {
2542                coolBarMem.putInteger(IWorkbenchConstants.TAG_LOCKED, 0);
2543            }
2544            IContributionItem[] items = coolBarMgr.getItems();
2545            for (int i = 0; i < items.length; i++) {
2546                IMemento coolItemMem = coolBarMem
2547                        .createChild(IWorkbenchConstants.TAG_COOLITEM);
2548                IContributionItem item = items[i];
2549                // The id of the contribution item
2550
if (item.getId() != null) {
2551                    coolItemMem.putString(IWorkbenchConstants.TAG_ID, item
2552                            .getId());
2553                }
2554                // Write out type and size if applicable
2555
if (item.isSeparator()) {
2556                    coolItemMem.putString(IWorkbenchConstants.TAG_ITEM_TYPE,
2557                            IWorkbenchConstants.TAG_TYPE_SEPARATOR);
2558                } else if (item.isGroupMarker() && !item.isSeparator()) {
2559                    coolItemMem.putString(IWorkbenchConstants.TAG_ITEM_TYPE,
2560                            IWorkbenchConstants.TAG_TYPE_GROUPMARKER);
2561                } else {
2562                    if (item instanceof PlaceholderContributionItem) {
2563                        coolItemMem.putString(
2564                                IWorkbenchConstants.TAG_ITEM_TYPE,
2565                                IWorkbenchConstants.TAG_TYPE_PLACEHOLDER);
2566                    } else {
2567                        // Store the identifier.
2568
coolItemMem
2569                                .putString(
2570                                        IWorkbenchConstants.TAG_ITEM_TYPE,
2571                                        IWorkbenchConstants.TAG_TYPE_TOOLBARCONTRIBUTION);
2572                    }
2573
2574                    /*
2575                     * Retrieve a reasonable approximation of the height and
2576                     * width, if possible.
2577                     */

2578                    final int height;
2579                    final int width;
2580                    if (item instanceof IToolBarContributionItem) {
2581                        IToolBarContributionItem toolBarItem = (IToolBarContributionItem) item;
2582                        toolBarItem.saveWidgetState();
2583                        height = toolBarItem.getCurrentHeight();
2584                        width = toolBarItem.getCurrentWidth();
2585                    } else if (item instanceof PlaceholderContributionItem) {
2586                        PlaceholderContributionItem placeholder = (PlaceholderContributionItem) item;
2587                        height = placeholder.getHeight();
2588                        width = placeholder.getWidth();
2589                    } else {
2590                        height = -1;
2591                        width = -1;
2592                    }
2593
2594                    // Store the height and width.
2595
coolItemMem.putInteger(IWorkbenchConstants.TAG_ITEM_X,
2596                            width);
2597                    coolItemMem.putInteger(IWorkbenchConstants.TAG_ITEM_Y,
2598                            height);
2599                }
2600            }
2601        }
2602
2603        // Save each page.
2604
Iterator JavaDoc itr = pageList.iterator();
2605        while (itr.hasNext()) {
2606            WorkbenchPage page = (WorkbenchPage) itr.next();
2607
2608            // Save perspective.
2609
IMemento pageMem = memento
2610                    .createChild(IWorkbenchConstants.TAG_PAGE);
2611            pageMem.putString(IWorkbenchConstants.TAG_LABEL, page.getLabel());
2612            result.add(page.saveState(pageMem));
2613
2614            if (page == getActiveWorkbenchPage()) {
2615                pageMem.putString(IWorkbenchConstants.TAG_FOCUS, "true"); //$NON-NLS-1$
2616
}
2617
2618            // Get the input.
2619
IAdaptable input = page.getInput();
2620            if (input != null) {
2621                IPersistableElement persistable = (IPersistableElement) Util.getAdapter(input,
2622                        IPersistableElement.class);
2623                if (persistable == null) {
2624                    WorkbenchPlugin
2625                            .log("Unable to save page input: " //$NON-NLS-1$
2626
+ input
2627                                    + ", because it does not adapt to IPersistableElement"); //$NON-NLS-1$
2628
} else {
2629                    // Save input.
2630
IMemento inputMem = pageMem
2631                            .createChild(IWorkbenchConstants.TAG_INPUT);
2632                    inputMem.putString(IWorkbenchConstants.TAG_FACTORY_ID,
2633                            persistable.getFactoryId());
2634                    persistable.saveState(inputMem);
2635                }
2636            }
2637        }
2638
2639        // Save window advisor state.
2640
IMemento windowAdvisorState = memento
2641                .createChild(IWorkbenchConstants.TAG_WORKBENCH_WINDOW_ADVISOR);
2642        result.add(getWindowAdvisor().saveState(windowAdvisorState));
2643
2644        // Save actionbar advisor state.
2645
IMemento actionBarAdvisorState = memento
2646                .createChild(IWorkbenchConstants.TAG_ACTION_BAR_ADVISOR);
2647        result.add(getActionBarAdvisor().saveState(actionBarAdvisorState));
2648
2649        // Only save the trim state if we're using the default layout
2650
if (defaultLayout != null) {
2651            IMemento trimState = memento.createChild(IWorkbenchConstants.TAG_TRIM);
2652            result.add(saveTrimState(trimState));
2653        }
2654
2655        return result;
2656    }
2657
2658    /**
2659     * Save the trim layout trim area and trim ordering.
2660     *
2661     * @param memento
2662     * the memento to update
2663     * @return the status, OK or not..
2664     * @since 3.2
2665     */

2666    private IStatus saveTrimState(IMemento memento) {
2667        int[] ids = defaultLayout.getAreaIds();
2668        for (int i = 0; i < ids.length; i++) {
2669            int id = ids[i];
2670            List JavaDoc trim = defaultLayout.getAreaTrim(id);
2671            if (!trim.isEmpty()) {
2672                IMemento area = memento
2673                        .createChild(IWorkbenchConstants.TAG_TRIM_AREA, Integer
2674                                .toString(id));
2675                Iterator JavaDoc d = trim.iterator();
2676                while (d.hasNext()) {
2677                    IWindowTrim item = (IWindowTrim) d.next();
2678                    area.createChild(IWorkbenchConstants.TAG_TRIM_ITEM, item
2679                            .getId());
2680                }
2681            }
2682        }
2683        return Status.OK_STATUS;
2684    }
2685
2686    /**
2687     * Restore the trim layout state from the memento.
2688     *
2689     * @param memento
2690     * the 'root' Workbench memento to restore
2691     * @return the status, OK or not
2692     * @since 3.2
2693     */

2694    private IStatus restoreTrimState(IMemento memento) {
2695        // Determine if we have saved state. If we don't have any 3.2
2696
// type state we're not done because the FastViewBar maintained
2697
// its own 'side' state in 3.1 so we'll honor its value
2698
IMemento trimState = memento.getChild(IWorkbenchConstants.TAG_TRIM);
2699        if (trimState != null) {
2700            // first pass sets up ordering for all trim areas
2701
IMemento[] areas = trimState
2702                    .getChildren(IWorkbenchConstants.TAG_TRIM_AREA);
2703            
2704            // We need to remember all the trim that was repositioned
2705
// here so we can re-site -newly contributed- trim after
2706
// we're done
2707
final List JavaDoc knownIds = new ArrayList JavaDoc();
2708            
2709            List JavaDoc[] trimOrder = new List JavaDoc[areas.length];
2710            for (int i = 0; i < areas.length; i++) {
2711                trimOrder[i] = new ArrayList JavaDoc();
2712                List JavaDoc preferredLocations = new ArrayList JavaDoc();
2713                IMemento area = areas[i];
2714                IMemento[] items = area
2715                        .getChildren(IWorkbenchConstants.TAG_TRIM_ITEM);
2716                for (int j = 0; j < items.length; j++) {
2717                    IMemento item = items[j];
2718                    String JavaDoc id = item.getID();
2719                    knownIds.add(id);
2720                    preferredLocations.add(id);
2721                    
2722                    IWindowTrim t = defaultLayout.getTrim(id);
2723                    if (t != null) {
2724                        trimOrder[i].add(t);
2725                    }
2726                }
2727                
2728                // Inform the TrimLayout of the preferred location for this area
2729
String JavaDoc areaIdString = areas[i].getID();
2730                int areaId = Integer.parseInt(areaIdString);
2731                defaultLayout.setPreferredLocations(areaId, preferredLocations);
2732            }
2733    
2734            // second pass applies all of the window trim
2735
for (int i = 0; i < areas.length; i++) {
2736                IMemento area = areas[i];
2737                final int id = Integer.parseInt(area.getID());
2738                final List JavaDoc myTrimOrderList = trimOrder[i];
2739                StartupThreading.runWithoutExceptions(new StartupRunnable() {
2740
2741                    public void runWithException() throws Throwable JavaDoc {
2742                        defaultLayout.updateAreaTrim(id, myTrimOrderList, false);
2743                    }});
2744                
2745            }
2746
2747            // get the trim manager to re-locate any -newly contributed-
2748
// trim widgets
2749
// Legacy (3.2) trim
2750
if (trimMgr2 != null) {
2751                StartupThreading.runWithoutExceptions(new StartupRunnable() {
2752
2753                    public void runWithException() throws Throwable JavaDoc {
2754                        trimMgr2.updateLocations(knownIds);
2755                    }});
2756                
2757            }
2758            
2759            // 3.3 Trim Contributions
2760
if (trimContributionMgr != null) {
2761                StartupThreading.runWithoutExceptions(new StartupRunnable() {
2762                    public void runWithException() throws Throwable JavaDoc {
2763                        trimContributionMgr.updateLocations(knownIds);
2764
2765                        // Update the GUI with the new locations
2766
WorkbenchPage page = getActiveWorkbenchPage();
2767                        if (page != null) {
2768                            Perspective perspective = page.getActivePerspective();
2769                            if (perspective != null) {
2770                                // Ensure that only the upper/right editor stack has
2771
// min/max buttons
2772
page.getEditorPresentation().updateStackButtons();
2773                                
2774                                // The perspective's onActivate manipulates the trim under the
2775
// new min/max story so cause it to refresh...
2776
perspective.onActivate();
2777                            }
2778                        }
2779                    }});
2780            }
2781        }
2782        else {
2783            // No 3.2 state...check if the FVB has state
2784
IMemento fastViewMem = memento
2785                    .getChild(IWorkbenchConstants.TAG_FAST_VIEW_DATA);
2786            if (fastViewMem != null) {
2787                if (fastViewBar != null) {
2788                    final Integer JavaDoc bigInt = fastViewMem.getInteger(IWorkbenchConstants.TAG_FAST_VIEW_SIDE);
2789                    if (bigInt != null) {
2790                        StartupThreading.runWithoutExceptions(new StartupRunnable() {
2791
2792                            public void runWithException() throws Throwable JavaDoc {
2793                                fastViewBar.dock(bigInt.intValue());
2794                                getTrimManager().addTrim(bigInt.intValue(), fastViewBar);
2795                            }});
2796                        
2797                    }
2798                }
2799            }
2800        }
2801        
2802        return Status.OK_STATUS;
2803    }
2804
2805    /**
2806     * Sets the active page within the window.
2807     *
2808     * @param in
2809     * identifies the new active page, or <code>null</code> for no
2810     * active page
2811     */

2812    public void setActivePage(final IWorkbenchPage in) {
2813        if (getActiveWorkbenchPage() == in) {
2814            return;
2815        }
2816
2817        // 1FVGTNR: ITPUI:WINNT - busy cursor for switching perspectives
2818
BusyIndicator.showWhile(getShell().getDisplay(), new Runnable JavaDoc() {
2819            public void run() {
2820                // Deactivate old persp.
2821
WorkbenchPage currentPage = getActiveWorkbenchPage();
2822                if (currentPage != null) {
2823                    currentPage.onDeactivate();
2824                }
2825
2826                // Activate new persp.
2827
if (in == null || pageList.contains(in)) {
2828                    pageList.setActive(in);
2829                }
2830                WorkbenchPage newPage = pageList.getActive();
2831                Composite parent = getPageComposite();
2832                StackLayout layout = (StackLayout) parent.getLayout();
2833                if (newPage != null) {
2834                    layout.topControl = newPage.getClientComposite();
2835                    parent.layout();
2836                    hideEmptyWindowContents();
2837                    newPage.onActivate();
2838                    firePageActivated(newPage);
2839                    if (newPage.getPerspective() != null) {
2840                        firePerspectiveActivated(newPage, newPage
2841                                .getPerspective());
2842                    }
2843                } else {
2844                    layout.topControl = null;
2845                    parent.layout();
2846                }
2847
2848                updateFastViewBar();
2849
2850                if (isClosing()) {
2851                    return;
2852                }
2853
2854                updateDisabled = false;
2855
2856                // Update action bars ( implicitly calls updateActionBars() )
2857
updateActionSets();
2858                submitGlobalActions();
2859
2860                if (perspectiveSwitcher != null) {
2861                    perspectiveSwitcher.update(false);
2862                }
2863
2864                getMenuManager().update(IAction.TEXT);
2865            }
2866        });
2867    }
2868
2869    /**
2870     * Returns whether or not children exist for the Window's toolbar control.
2871     * Overridden for coolbar support.
2872     * <p>
2873     *
2874     * @return boolean true if children exist, false otherwise
2875     */

2876    protected boolean toolBarChildrenExist() {
2877        CoolBar coolBarControl = (CoolBar) getCoolBarControl();
2878        return coolBarControl.getItemCount() > 0;
2879    }
2880
2881    /**
2882     * Hooks a listener to track the activation and deactivation of the window's
2883     * shell. Notifies the active part and editor of the change
2884     */

2885    private void trackShellActivation(Shell shell) {
2886        shell.addShellListener(new ShellAdapter() {
2887            public void shellActivated(ShellEvent event) {
2888                shellActivated = true;
2889                serviceLocator.activate();
2890                getWorkbenchImpl().setActivatedWindow(WorkbenchWindow.this);
2891                WorkbenchPage currentPage = getActiveWorkbenchPage();
2892                if (currentPage != null) {
2893                    IWorkbenchPart part = currentPage.getActivePart();
2894                    if (part != null) {
2895                        PartSite site = (PartSite) part.getSite();
2896                        site.getPane().shellActivated();
2897                    }
2898                    IEditorPart editor = currentPage.getActiveEditor();
2899                    if (editor != null) {
2900                        PartSite site = (PartSite) editor.getSite();
2901                        site.getPane().shellActivated();
2902                    }
2903                    getWorkbenchImpl()
2904                            .fireWindowActivated(WorkbenchWindow.this);
2905                }
2906            }
2907
2908            public void shellDeactivated(ShellEvent event) {
2909                shellActivated = false;
2910                serviceLocator.deactivate();
2911                WorkbenchPage currentPage = getActiveWorkbenchPage();
2912                if (currentPage != null) {
2913                    IWorkbenchPart part = currentPage.getActivePart();
2914                    if (part != null) {
2915                        PartSite site = (PartSite) part.getSite();
2916                        site.getPane().shellDeactivated();
2917                    }
2918                    IEditorPart editor = currentPage.getActiveEditor();
2919                    if (editor != null) {
2920                        PartSite site = (PartSite) editor.getSite();
2921                        site.getPane().shellDeactivated();
2922                    }
2923                    getWorkbenchImpl().fireWindowDeactivated(
2924                            WorkbenchWindow.this);
2925                }
2926            }
2927        });
2928    }
2929
2930    /**
2931     * Hooks a listener to track the resize of the window's shell. Stores the
2932     * new bounds if in normal state - that is, not in minimized or maximized
2933     * state)
2934     */

2935    private void trackShellResize(Shell newShell) {
2936        newShell.addControlListener(new ControlAdapter() {
2937            public void controlMoved(ControlEvent e) {
2938                saveBounds();
2939            }
2940
2941            public void controlResized(ControlEvent e) {
2942                saveBounds();
2943            }
2944
2945            private void saveBounds() {
2946                Shell shell = getShell();
2947                if (shell == null) {
2948                    return;
2949                }
2950                if (shell.isDisposed()) {
2951                    return;
2952                }
2953                if (shell.getMinimized()) {
2954                    return;
2955                }
2956                if (shell.getMaximized()) {
2957                    asMaximizedState = true;
2958                    return;
2959                }
2960                asMaximizedState = false;
2961                normalBounds = shell.getBounds();
2962            }
2963        });
2964    }
2965
2966    /**
2967     * update the action bars.
2968     */

2969    public void updateActionBars() {
2970        if (updateDisabled || updatesDeferred()) {
2971            return;
2972        }
2973        // updateAll required in order to enable accelerators on pull-down menus
2974
getMenuBarManager().updateAll(false);
2975
2976        try {
2977            getShell().setLayoutDeferred(true);
2978            getCoolBarManager2().update(false);
2979        } finally {
2980            getShell().setLayoutDeferred(false);
2981        }
2982        
2983        getStatusLineManager().update(false);
2984    }
2985
2986    /**
2987     * Returns true iff we are currently deferring UI processing due to a large
2988     * update
2989     *
2990     * @return true iff we are deferring UI updates.
2991     * @since 3.1
2992     */

2993    private boolean updatesDeferred() {
2994        return largeUpdates > 0;
2995    }
2996
2997    /**
2998     * <p>
2999     * Indicates the start of a large update within this window. This is used to
3000     * disable CPU-intensive, change-sensitive services that were temporarily
3001     * disabled in the midst of large changes. This method should always be
3002     * called in tandem with <code>largeUpdateEnd</code>, and the event loop
3003     * should not be allowed to spin before that method is called.
3004     * </p>
3005     * <p>
3006     * Important: always use with <code>largeUpdateEnd</code>!
3007     * </p>
3008     *
3009     * @since 3.1
3010     */

3011    public final void largeUpdateStart() {
3012        largeUpdates++;
3013    }
3014
3015    /**
3016     * <p>
3017     * Indicates the end of a large update within this window. This is used to
3018     * re-enable services that were temporarily disabled in the midst of large
3019     * changes. This method should always be called in tandem with
3020     * <code>largeUpdateStart</code>, and the event loop should not be
3021     * allowed to spin before this method is called.
3022     * </p>
3023     * <p>
3024     * Important: always protect this call by using <code>finally</code>!
3025     * </p>
3026     *
3027     * @since 3.1
3028     */

3029    public final void largeUpdateEnd() {
3030        if (--largeUpdates == 0) {
3031            updateActionBars();
3032        }
3033    }
3034
3035    /**
3036     * Update the visible action sets. This method is typically called from a
3037     * page when the user changes the visible action sets within the
3038     * prespective.
3039     */

3040    public void updateActionSets() {
3041        if (updateDisabled) {
3042            return;
3043        }
3044
3045        WorkbenchPage currentPage = getActiveWorkbenchPage();
3046        if (currentPage == null) {
3047            getActionPresentation().clearActionSets();
3048        } else {
3049            ICoolBarManager2 coolBarManager = (ICoolBarManager2) getCoolBarManager2();
3050            if (coolBarManager != null) {
3051                coolBarManager.refresh();
3052            }
3053            getActionPresentation().setActionSets(
3054                    currentPage.getActionSets());
3055        }
3056        fireActionSetsChanged();
3057        updateActionBars();
3058
3059        // hide the launch menu if it is empty
3060
String JavaDoc path = IWorkbenchActionConstants.M_WINDOW
3061                + IWorkbenchActionConstants.SEP
3062                + IWorkbenchActionConstants.M_LAUNCH;
3063        IMenuManager manager = getMenuBarManager().findMenuUsingPath(path);
3064        IContributionItem item = getMenuBarManager().findUsingPath(path);
3065
3066        if (manager == null || item == null) {
3067            return;
3068        }
3069        item.setVisible(manager.getItems().length >= 2);
3070        // there is a separator for the additions group thus >= 2
3071
}
3072
3073    private ListenerList actionSetListeners = null;
3074
3075    private ListenerList backgroundSaveListeners = new ListenerList(ListenerList.IDENTITY);
3076
3077    private final void fireActionSetsChanged() {
3078        if (actionSetListeners != null) {
3079            final Object JavaDoc[] listeners = actionSetListeners.getListeners();
3080            for (int i = 0; i < listeners.length; i++) {
3081                final IActionSetsListener listener = (IActionSetsListener) listeners[i];
3082                final WorkbenchPage currentPage = getActiveWorkbenchPage();
3083                final IActionSetDescriptor[] newActionSets;
3084                if (currentPage == null) {
3085                    newActionSets = null;
3086                } else {
3087                    newActionSets = currentPage.getActionSets();
3088                }
3089                final ActionSetsEvent event = new ActionSetsEvent(newActionSets);
3090                listener.actionSetsChanged(event);
3091            }
3092        }
3093    }
3094
3095    final void addActionSetsListener(final IActionSetsListener listener) {
3096        if (actionSetListeners == null) {
3097            actionSetListeners = new ListenerList();
3098        }
3099
3100        actionSetListeners.add(listener);
3101    }
3102
3103    final void removeActionSetsListener(final IActionSetsListener listener) {
3104        if (actionSetListeners != null) {
3105            actionSetListeners.remove(listener);
3106            if (actionSetListeners.isEmpty()) {
3107                actionSetListeners = null;
3108            }
3109        }
3110    }
3111
3112    /**
3113     * Create the progress indicator for the receiver.
3114     *
3115     * @param shell
3116     * the parent shell
3117     */

3118    private void createProgressIndicator(Shell shell) {
3119        if (getWindowConfigurer().getShowProgressIndicator()) {
3120            progressRegion = new ProgressRegion();
3121            progressRegion.createContents(shell, this);
3122        }
3123
3124    }
3125
3126    class PageList {
3127        // List of pages in the order they were created;
3128
private List JavaDoc pagesInCreationOrder;
3129
3130        // List of pages where the top is the last activated.
3131
private List JavaDoc pageInActivationOrder;
3132
3133        // The page explicitly activated
3134
private Object JavaDoc active;
3135
3136        public PageList() {
3137            pagesInCreationOrder = new ArrayList JavaDoc(4);
3138            pageInActivationOrder = new ArrayList JavaDoc(4);
3139        }
3140
3141        public boolean add(Object JavaDoc object) {
3142            pagesInCreationOrder.add(object);
3143            pageInActivationOrder.add(0, object);
3144            // It will be moved to top only when activated.
3145
return true;
3146        }
3147
3148        public Iterator JavaDoc iterator() {
3149            return pagesInCreationOrder.iterator();
3150        }
3151
3152        public boolean contains(Object JavaDoc object) {
3153            return pagesInCreationOrder.contains(object);
3154        }
3155
3156        public boolean remove(Object JavaDoc object) {
3157            if (active == object) {
3158                active = null;
3159            }
3160            pageInActivationOrder.remove(object);
3161            return pagesInCreationOrder.remove(object);
3162        }
3163
3164        public boolean isEmpty() {
3165            return pagesInCreationOrder.isEmpty();
3166        }
3167
3168        public IWorkbenchPage[] getPages() {
3169            int nSize = pagesInCreationOrder.size();
3170            IWorkbenchPage[] retArray = new IWorkbenchPage[nSize];
3171            pagesInCreationOrder.toArray(retArray);
3172            return retArray;
3173        }
3174
3175        public void setActive(Object JavaDoc page) {
3176            if (active == page) {
3177                return;
3178            }
3179
3180            active = page;
3181
3182            if (page != null) {
3183                pageInActivationOrder.remove(page);
3184                pageInActivationOrder.add(page);
3185            }
3186        }
3187
3188        public WorkbenchPage getActive() {
3189            return (WorkbenchPage) active;
3190        }
3191
3192        public WorkbenchPage getNextActive() {
3193            if (active == null) {
3194                if (pageInActivationOrder.isEmpty()) {
3195                    return null;
3196                }
3197
3198                return (WorkbenchPage) pageInActivationOrder
3199                        .get(pageInActivationOrder.size() - 1);
3200            }
3201
3202            if (pageInActivationOrder.size() < 2) {
3203                return null;
3204            }
3205
3206            return (WorkbenchPage) pageInActivationOrder
3207                    .get(pageInActivationOrder.size() - 2);
3208        }
3209    }
3210
3211    /**
3212     * Returns the unique object that applications use to configure this window.
3213     * <p>
3214     * IMPORTANT This method is declared package-private to prevent regular
3215     * plug-ins from downcasting IWorkbenchWindow to WorkbenchWindow and getting
3216     * hold of the workbench window configurer that would allow them to tamper
3217     * with the workbench window. The workbench window configurer is available
3218     * only to the application.
3219     * </p>
3220     */

3221    /* package - DO NOT CHANGE */
3222    WorkbenchWindowConfigurer getWindowConfigurer() {
3223        if (windowConfigurer == null) {
3224            // lazy initialize
3225
windowConfigurer = new WorkbenchWindowConfigurer(this);
3226        }
3227        return windowConfigurer;
3228    }
3229
3230    /**
3231     * Returns the workbench advisor. Assumes the workbench has been created
3232     * already.
3233     * <p>
3234     * IMPORTANT This method is declared private to prevent regular plug-ins
3235     * from downcasting IWorkbenchWindow to WorkbenchWindow and getting hold of
3236     * the workbench advisor that would allow them to tamper with the workbench.
3237     * The workbench advisor is internal to the application.
3238     * </p>
3239     */

3240    private/* private - DO NOT CHANGE */
3241    WorkbenchAdvisor getAdvisor() {
3242        return getWorkbenchImpl().getAdvisor();
3243    }
3244
3245    /**
3246     * Returns the window advisor, creating a new one for this window if needed.
3247     * <p>
3248     * IMPORTANT This method is declared private to prevent regular plug-ins
3249     * from downcasting IWorkbenchWindow to WorkbenchWindow and getting hold of
3250     * the window advisor that would allow them to tamper with the window. The
3251     * window advisor is internal to the application.
3252     * </p>
3253     */

3254    private/* private - DO NOT CHANGE */
3255    WorkbenchWindowAdvisor getWindowAdvisor() {
3256        if (windowAdvisor == null) {
3257            windowAdvisor = getAdvisor().createWorkbenchWindowAdvisor(
3258                    getWindowConfigurer());
3259            Assert.isNotNull(windowAdvisor);
3260        }
3261        return windowAdvisor;
3262    }
3263
3264    /**
3265     * Returns the action bar advisor, creating a new one for this window if
3266     * needed.
3267     * <p>
3268     * IMPORTANT This method is declared private to prevent regular plug-ins
3269     * from downcasting IWorkbenchWindow to WorkbenchWindow and getting hold of
3270     * the action bar advisor that would allow them to tamper with the window's
3271     * action bars. The action bar advisor is internal to the application.
3272     * </p>
3273     */

3274    private/* private - DO NOT CHANGE */
3275    ActionBarAdvisor getActionBarAdvisor() {
3276        if (actionBarAdvisor == null) {
3277            actionBarAdvisor = getWindowAdvisor().createActionBarAdvisor(
3278                    getWindowConfigurer().getActionBarConfigurer());
3279            Assert.isNotNull(actionBarAdvisor);
3280        }
3281        return actionBarAdvisor;
3282    }
3283
3284    /*
3285     * Returns the IWorkbench implementation.
3286     */

3287    private Workbench getWorkbenchImpl() {
3288        return Workbench.getInstance();
3289    }
3290
3291    /**
3292     * Fills the window's real action bars.
3293     *
3294     * @param flags
3295     * indicate which bars to fill
3296     */

3297    public void fillActionBars(int flags) {
3298        Workbench workbench = getWorkbenchImpl();
3299        workbench.largeUpdateStart();
3300        try {
3301            getActionBarAdvisor().fillActionBars(flags);
3302            //
3303
// 3.3 start
3304
final IMenuService menuService = (IMenuService) serviceLocator
3305                    .getService(IMenuService.class);
3306            menuService.populateContributionManager(
3307                    (ContributionManager) getActionBars().getMenuManager(),
3308                    MenuUtil.MAIN_MENU);
3309            ICoolBarManager coolbar = getActionBars().getCoolBarManager();
3310            if (coolbar != null) {
3311                menuService.populateContributionManager(
3312                        (ContributionManager) coolbar,
3313                        MenuUtil.MAIN_TOOLBAR);
3314            }
3315            // 3.3 end
3316
} finally {
3317            workbench.largeUpdateEnd();
3318        }
3319    }
3320
3321    /**
3322     * Fills the window's proxy action bars.
3323     *
3324     * @param proxyBars
3325     * the proxy configurer
3326     * @param flags
3327     * indicate which bars to fill
3328     */

3329    public void fillActionBars(IActionBarConfigurer2 proxyBars, int flags) {
3330        Assert.isNotNull(proxyBars);
3331        WorkbenchWindowConfigurer.WindowActionBarConfigurer wab = (WorkbenchWindowConfigurer.WindowActionBarConfigurer) getWindowConfigurer()
3332                .getActionBarConfigurer();
3333        wab.setProxy(proxyBars);
3334        try {
3335            getActionBarAdvisor().fillActionBars(
3336                    flags | ActionBarAdvisor.FILL_PROXY);
3337        } finally {
3338            wab.setProxy(null);
3339        }
3340    }
3341
3342    /**
3343     * The <code>WorkbenchWindow</code> implementation of this method has the
3344     * same logic as <code>Window</code>'s implementation, but without the
3345     * resize check. We don't want to skip setting the bounds if the shell has
3346     * been resized since a free resize event occurs on Windows when the menubar
3347     * is set in configureShell.
3348     */

3349    protected void initializeBounds() {
3350        Point size = getInitialSize();
3351        Point location = getInitialLocation(size);
3352        getShell().setBounds(
3353                getConstrainedShellBounds(new Rectangle(location.x, location.y,
3354                        size.x, size.y)));
3355    }
3356
3357    /*
3358     * Unlike dialogs, the position of the workbench window is set by the user
3359     * and persisted across sessions. If the user wants to put the window
3360     * offscreen or spanning multiple monitors, let them (bug 74762)
3361     */

3362    protected void constrainShellSize() {
3363        // As long as the shell is visible on some monitor, don't change it.
3364
Rectangle bounds = getShell().getBounds();
3365        if (!SwtUtil.intersectsAnyMonitor(Display.getCurrent(), bounds)) {
3366            super.constrainShellSize();
3367        }
3368    }
3369
3370    /*
3371     * Unlike dialogs, the position of the workbench window is set by the user
3372     * and persisted across sessions. If the user wants to put the window
3373     * offscreen or spanning multiple monitors, let them (bug 74762)
3374     */

3375    protected Point getInitialLocation(Point size) {
3376        Shell shell = getShell();
3377        if (shell != null) {
3378            return shell.getLocation();
3379        }
3380
3381        return super.getInitialLocation(size);
3382    }
3383
3384    /**
3385     * The <code>WorkbenchWindow</code> implementation of this method
3386     * delegates to the window configurer.
3387     *
3388     * @since 3.0
3389     */

3390    protected Point getInitialSize() {
3391        return getWindowConfigurer().getInitialSize();
3392    }
3393
3394    /**
3395     * @param visible
3396     * whether the cool bar should be shown. This is only applicable
3397     * if the window configurer also wishes either the cool bar to be
3398     * visible.
3399     * @since 3.0
3400     */

3401    public void setCoolBarVisible(boolean visible) {
3402        boolean oldValue = coolBarVisible;
3403        coolBarVisible = visible;
3404        if (oldValue != coolBarVisible) {
3405            updateLayoutDataForContents();
3406        }
3407    }
3408
3409    /**
3410     * @return whether the cool bar should be shown. This is only applicable if
3411     * the window configurer also wishes either the cool bar to be
3412     * visible.
3413     * @since 3.0
3414     */

3415    public boolean getCoolBarVisible() {
3416        return coolBarVisible;
3417    }
3418
3419    /**
3420     * @param visible
3421     * whether the perspective bar should be shown. This is only
3422     * applicable if the window configurer also wishes either the
3423     * perspective bar to be visible.
3424     * @since 3.0
3425     */

3426    public void setPerspectiveBarVisible(boolean visible) {
3427        boolean oldValue = perspectiveBarVisible;
3428        perspectiveBarVisible = visible;
3429        if (oldValue != perspectiveBarVisible) {
3430            updateLayoutDataForContents();
3431        }
3432    }
3433
3434    /**
3435     * @return whether the perspective bar should be shown. This is only
3436     * applicable if the window configurer also wishes either the
3437     * perspective bar to be visible.
3438     * @since 3.0
3439     */

3440    public boolean getPerspectiveBarVisible() {
3441        return perspectiveBarVisible;
3442    }
3443    
3444    /**
3445     * Tell the workbench window a visible state for the fastview bar. This is
3446     * only applicable if the window configurer also wishes the fast view bar to
3447     * be visible.
3448     *
3449     * @param visible
3450     * <code>true</code> or <code>false</code>
3451     * @since 3.2
3452     */

3453    public void setFastViewBarVisible(boolean visible) {
3454        boolean oldValue = fastViewBarVisible;
3455        fastViewBarVisible = visible;
3456        if (oldValue != fastViewBarVisible) {
3457            updateLayoutDataForContents();
3458        }
3459    }
3460    
3461    /**
3462     * The workbench window take on the fastview bar. This is only applicable if
3463     * the window configurer also wishes the fast view bar to be visible.
3464     *
3465     * @return <code>true</code> if the workbench window thinks the fastview
3466     * bar should be visible.
3467     * @since 3.2
3468     */

3469    public boolean getFastViewBarVisible() {
3470        return fastViewBarVisible;
3471    }
3472
3473    /**
3474     * @param visible
3475     * whether the perspective bar should be shown. This is only
3476     * applicable if the window configurer also wishes either the
3477     * perspective bar to be visible.
3478     * @since 3.0
3479     */

3480    public void setStatusLineVisible(boolean visible) {
3481        boolean oldValue = statusLineVisible;
3482        statusLineVisible = visible;
3483        if (oldValue != statusLineVisible) {
3484            updateLayoutDataForContents();
3485        }
3486    }
3487
3488    /**
3489     * @return whether the perspective bar should be shown. This is only
3490     * applicable if the window configurer also wishes either the
3491     * perspective bar to be visible.
3492     * @since 3.0
3493     */

3494    public boolean getStatusLineVisible() {
3495        return statusLineVisible;
3496    }
3497
3498    /**
3499     * Note that this will only have an effect if the default implementation of
3500     * WorkbenchAdvisor.createWindowContents() has been invoked.
3501     *
3502     * called IWorkbench
3503     *
3504     * @since 3.0
3505     */

3506    private void updateLayoutDataForContents() {
3507        if (defaultLayout == null) {
3508            return;
3509        }
3510
3511        // @issue this is not ideal; coolbar and perspective shortcuts should be
3512
// separately configurable
3513
if ((getCoolBarVisible() && getWindowConfigurer().getShowCoolBar())
3514                || (getPerspectiveBarVisible() && getWindowConfigurer()
3515                        .getShowPerspectiveBar())) {
3516            if (defaultLayout.getTrim(topBarTrim.getId()) == null) {
3517                defaultLayout.addTrim(SWT.TOP, topBarTrim);
3518            }
3519            topBar.setVisible(true);
3520        } else {
3521            defaultLayout.removeTrim(topBarTrim);
3522            topBar.setVisible(false);
3523        }
3524
3525        if (fastViewBar != null) {
3526            if (getFastViewBarVisible()
3527                    && getWindowConfigurer().getShowFastViewBars()) {
3528                int side = fastViewBar.getSide();
3529
3530                if (defaultLayout.getTrim(fastViewBar.getId()) == null) {
3531                    defaultLayout.addTrim(side, fastViewBar);
3532                }
3533                fastViewBar.getControl().setVisible(true);
3534            } else {
3535                defaultLayout.removeTrim(fastViewBar);
3536                fastViewBar.getControl().setVisible(false);
3537            }
3538        }
3539
3540        if (getStatusLineVisible() && getWindowConfigurer().getShowStatusLine()) {
3541            if (defaultLayout.getTrim(getStatusLineTrim().getId()) == null) {
3542                defaultLayout.addTrim(SWT.BOTTOM, getStatusLineTrim());
3543            }
3544            getStatusLineManager().getControl().setVisible(true);
3545        } else {
3546            defaultLayout.removeTrim(getStatusLineTrim());
3547            getStatusLineManager().getControl().setVisible(false);
3548        }
3549
3550        if (heapStatus != null) {
3551            if (getShowHeapStatus()) {
3552                if (heapStatus.getLayoutData() == null) {
3553                    heapStatusTrim.setWidthHint(heapStatus.computeSize(
3554                            SWT.DEFAULT, SWT.DEFAULT).x);
3555                    heapStatusTrim
3556                            .setHeightHint(getStatusLineManager().getControl()
3557                                    .computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
3558                }
3559
3560                if (defaultLayout.getTrim(heapStatusTrim.getId()) == null) {
3561                    defaultLayout.addTrim(SWT.BOTTOM, heapStatusTrim);
3562                }
3563                heapStatus.setVisible(true);
3564            } else {
3565
3566                defaultLayout.removeTrim(heapStatusTrim);
3567                heapStatus.setVisible(false);
3568            }
3569        }
3570
3571        if (progressRegion != null) {
3572            if (getWindowConfigurer().getShowProgressIndicator()) {
3573                if (defaultLayout.getTrim(progressRegion.getId()) == null) {
3574                    defaultLayout.addTrim(SWT.BOTTOM, progressRegion);
3575                }
3576                progressRegion.getControl().setVisible(true);
3577            } else {
3578                defaultLayout.removeTrim(progressRegion);
3579                progressRegion.getControl().setVisible(false);
3580            }
3581        }
3582        
3583        defaultLayout.setCenterControl(getPageComposite());
3584
3585        // Re-populate the trim elements
3586
if (trimMgr2 != null)
3587            trimMgr2.update(true, false, !topBar.getVisible());
3588        if (trimContributionMgr != null)
3589            trimContributionMgr.update(true, !topBar.getVisible());
3590    }
3591
3592    public boolean getShowFastViewBars() {
3593        return getWindowConfigurer().getShowFastViewBars();
3594    }
3595
3596    /**
3597     * Set the layout data for the contents of the window.
3598     */

3599    private void setLayoutDataForContents() {
3600        updateLayoutDataForContents();
3601    }
3602
3603    /**
3604     * Returns the fast view bar.
3605     */

3606    public FastViewBar getFastViewBar() {
3607        return fastViewBar;
3608    }
3609
3610    /**
3611     * Returns the perspective bar.
3612     *
3613     * @return Returns the perspective bar, or <code>null</code> if it has not
3614     * been initialized.
3615     */

3616    public PerspectiveBarManager getPerspectiveBar() {
3617        return perspectiveSwitcher == null ? null : perspectiveSwitcher
3618                .getPerspectiveBar();
3619    }
3620
3621    /**
3622     * Returns the action presentation for dynamic UI
3623     * @return action presentation
3624     */

3625    public ActionPresentation getActionPresentation() {
3626        if (actionPresentation == null) {
3627            actionPresentation = new ActionPresentation(this);
3628        }
3629        return actionPresentation;
3630    }
3631    
3632    /**
3633     * Return the action bar presentation used for creating toolbars. This
3634     * is for internal use only, used for consistency with the window.
3635     *
3636     * @return the presentation used.
3637     */

3638    public IActionBarPresentationFactory getActionBarPresentationFactory() {
3639        // allow replacement of the actionbar presentation
3640
IActionBarPresentationFactory actionBarPresentation;
3641        AbstractPresentationFactory presentationFactory =
3642            getWindowConfigurer().getPresentationFactory();
3643        if (presentationFactory instanceof IActionBarPresentationFactory) {
3644            actionBarPresentation = ((IActionBarPresentationFactory) presentationFactory);
3645        } else {
3646            actionBarPresentation = new DefaultActionBarPresentationFactory();
3647        }
3648        
3649        return actionBarPresentation;
3650    }
3651    
3652    /*
3653     * (non-Javadoc)
3654     *
3655     * @see org.eclipse.jface.window.ApplicationWindow#showTopSeperator()
3656     */

3657    protected boolean showTopSeperator() {
3658        return false;
3659    }
3660
3661    /**
3662     * Returns a new cool bar manager for the window.
3663     * <p>
3664     * Subclasses may override this method to customize the cool bar manager.
3665     * </p>
3666     *
3667     * @return a cool bar manager
3668     * @since 3.2
3669     */

3670    protected ICoolBarManager createCoolBarManager2(int style) {
3671        return getActionBarPresentationFactory().createCoolBarManager();
3672    }
3673
3674    /**
3675     * Returns a new tool bar manager for the window.
3676     * <p>
3677     * Subclasses may override this method to customize the tool bar manager.
3678     * </p>
3679     * @return a tool bar manager
3680     * @since 3.2
3681     */

3682    protected IToolBarManager createToolBarManager2(int style) {
3683        return getActionBarPresentationFactory().createToolBarManager();
3684    }
3685    
3686    /**
3687     * Delegate to the presentation factory.
3688     *
3689     * @see org.eclipse.jface.window.ApplicationWindow#createStatusLineManager
3690     * @since 3.0
3691     */

3692    protected StatusLineManager createStatusLineManager() {
3693        // @issue ApplicationWindow and WorkbenchWindow should allow full
3694
// IStatusLineManager
3695
return (StatusLineManager) getWindowConfigurer()
3696                .getPresentationFactory().createStatusLineManager();
3697    }
3698
3699    /**
3700     * Delegate to the presentation factory.
3701     *
3702     * @see org.eclipse.jface.window.ApplicationWindow#createStatusLine
3703     * @since 3.0
3704     */

3705    protected void createStatusLine(Shell shell) {
3706        getWindowConfigurer().getPresentationFactory().createStatusLineControl(
3707                getStatusLineManager(), shell);
3708    }
3709
3710    /**
3711     * Updates the fast view bar, if present. TODO: The fast view bar should
3712     * update itself as necessary. All calls to this should be cleaned up.
3713     *
3714     * @since 3.0
3715     */

3716    public void updateFastViewBar() {
3717        if (getFastViewBar() != null) {
3718            getFastViewBar().update(true);
3719        }
3720    }
3721
3722    /**
3723     * @return Returns the progressRegion.
3724     */

3725    public ProgressRegion getProgressRegion() {
3726        return progressRegion;
3727    }
3728
3729    /**
3730     * Adds the given control to the specified side of this window's trim.
3731     *
3732     * @param trim
3733     * the bar's IWindowTrim
3734     * @param side
3735     * one of <code>SWT.LEFT</code>,<code>SWT.BOTTOM</code>,
3736     * or <code>SWT.RIGHT</code> (only LEFT has been tested)
3737     * @since 3.0
3738     */

3739    public void addToTrim(IWindowTrim trim, int side) {
3740        IWindowTrim reference = null;
3741        defaultLayout.addTrim(side, trim, reference);
3742    }
3743
3744    /*
3745     * (non-Javadoc)
3746     *
3747     * @see org.eclipse.ui.IWorkbenchWindow#getExtensionTracker()
3748     */

3749    public IExtensionTracker getExtensionTracker() {
3750        if (tracker == null) {
3751            tracker = new UIExtensionTracker(getWorkbench().getDisplay());
3752        }
3753        return tracker;
3754    }
3755
3756    /**
3757     * Creates the perspective customization dialog.
3758     *
3759     * @param persp
3760     * perspective to customize
3761     *
3762     * @return a new perspective customization dialog
3763     * @since 3.1
3764     */

3765    public CustomizePerspectiveDialog createCustomizePerspectiveDialog(
3766            Perspective persp) {
3767        return new CustomizePerspectiveDialog(getWindowConfigurer(), persp);
3768    }
3769
3770    /**
3771     * Returns the default page input for workbench pages opened in this window.
3772     *
3773     * @return the default page input or <code>null</code> if none
3774     * @since 3.1
3775     */

3776    IAdaptable getDefaultPageInput() {
3777        return getWorkbenchImpl().getDefaultPageInput();
3778    }
3779
3780    /**
3781     * Add a listener for perspective reordering.
3782     *
3783     * @param listener
3784     */

3785    public void addPerspectiveReorderListener(IReorderListener listener) {
3786        if (perspectiveSwitcher != null) {
3787            perspectiveSwitcher.addReorderListener(listener);
3788        }
3789    }
3790
3791    /**
3792     * Show the heap status
3793     *
3794     * @param selection
3795     */

3796    public void showHeapStatus(boolean selection) {
3797        if (selection) {
3798            if (heapStatus == null) {
3799                createHeapStatus(getShell());
3800                updateLayoutDataForContents();
3801                getShell().layout();
3802            }
3803        } else {
3804            if (heapStatus != null) {
3805                heapStatus.dispose();
3806                heapStatus = null;
3807            }
3808        }
3809
3810    }
3811
3812    /*
3813     * (non-Javadoc)
3814     *
3815     * @see org.eclipse.ui.IWorkbenchWindow#getTrimManager()
3816     */

3817    public ITrimManager getTrimManager() {
3818        return defaultLayout;
3819    }
3820
3821    /**
3822     * Initializes all of the default command-based services for the workbench
3823     * window.
3824     */

3825    private final void initializeDefaultServices() {
3826        serviceLocator.registerService(IWorkbenchWindow.class, this);
3827        
3828        final Expression defaultExpression = new WorkbenchWindowExpression(this);
3829
3830        final IHandlerService parentHandlerService = (IHandlerService) serviceLocator
3831                .getService(IHandlerService.class);
3832        final IHandlerService handlerService = new SlaveHandlerService(
3833                parentHandlerService, defaultExpression);
3834        serviceLocator.registerService(IHandlerService.class, handlerService);
3835
3836        final IContextService parentContextService = (IContextService) serviceLocator
3837                .getService(IContextService.class);
3838        final IContextService contextService = new SlaveContextService(
3839                parentContextService, defaultExpression);
3840        serviceLocator.registerService(IContextService.class, contextService);
3841
3842        final ICommandService parentCommandService = (ICommandService) serviceLocator
3843                .getService(ICommandService.class);
3844        final ICommandService commandService = new SlaveCommandService(
3845                parentCommandService, IServiceScopes.WINDOW_SCOPE,
3846                this);
3847        serviceLocator.registerService(ICommandService.class, commandService);
3848
3849        final IMenuService menuService = new WindowMenuService(serviceLocator);
3850        serviceLocator.registerService(IMenuService.class, menuService);
3851
3852// final ISourceProviderService sourceProviderService = (ISourceProviderService) serviceLocator
3853
// .getService(ISourceProviderService.class);
3854
// final ISourceProvider[] sourceProviders = sourceProviderService
3855
// .getSourceProviders();
3856
// for (int i = 0; i < sourceProviders.length; i++) {
3857
// final ISourceProvider provider = sourceProviders[i];
3858
// menuService.addSourceProvider(provider);
3859
// }
3860
// serviceLocator.registerService(IMenuService.class, menuService);
3861

3862        final ActionCommandMappingService mappingService = new ActionCommandMappingService();
3863        serviceLocator.registerService(IActionCommandMappingService.class,
3864                mappingService);
3865
3866        final LegacyActionPersistence actionPersistence = new LegacyActionPersistence(
3867                this);
3868        serviceLocator.registerService(LegacyActionPersistence.class,
3869                actionPersistence);
3870        actionPersistence.read();
3871
3872    }
3873
3874    public final Object JavaDoc getService(final Class JavaDoc key) {
3875        return serviceLocator.getService(key);
3876    }
3877
3878    public final boolean hasService(final Class JavaDoc key) {
3879        return serviceLocator.hasService(key);
3880    }
3881    
3882    /**
3883     * Toggle the visibility of the coolbar/perspective bar. This method
3884     * respects the window configurer and will only toggle visibility if the
3885     * item in question was originally declared visible by the window advisor.
3886     *
3887     * @since 3.3
3888     */

3889    public void toggleToolbarVisibility() {
3890        boolean coolbarVisible = getCoolBarVisible();
3891        boolean perspectivebarVisible = getPerspectiveBarVisible();
3892        // only toggle the visibility of the components that
3893
// were on initially
3894
if (getWindowConfigurer().getShowCoolBar()) {
3895            setCoolBarVisible(!coolbarVisible);
3896            firePropertyChanged(PROP_COOLBAR_VISIBLE,
3897                    coolbarVisible ? Boolean.TRUE : Boolean.FALSE,
3898                    !coolbarVisible ? Boolean.TRUE : Boolean.FALSE);
3899        }
3900        if (getWindowConfigurer().getShowPerspectiveBar()) {
3901            setPerspectiveBarVisible(!perspectivebarVisible);
3902            firePropertyChanged(PROP_PERSPECTIVEBAR_VISIBLE,
3903                    coolbarVisible ? Boolean.TRUE : Boolean.FALSE,
3904                    !coolbarVisible ? Boolean.TRUE : Boolean.FALSE);
3905        }
3906        getShell().layout();
3907    }
3908
3909    /*package*/ void addBackgroundSaveListener(IBackgroundSaveListener listener) {
3910        backgroundSaveListeners.add(listener);
3911    }
3912    
3913    /*package*/ void fireBackgroundSaveStarted() {
3914        Object JavaDoc[] listeners = backgroundSaveListeners.getListeners();
3915        for (int i = 0; i < listeners.length; i++) {
3916            IBackgroundSaveListener listener = (IBackgroundSaveListener) listeners[i];
3917            listener.handleBackgroundSaveStarted();
3918        }
3919    }
3920
3921    /*package*/ void removeBackgroundSaveListener(IBackgroundSaveListener listener) {
3922        backgroundSaveListeners.remove(listener);
3923    }
3924}
3925
Popular Tags