0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2007 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.ui.internal;
0011:
0012: import java.lang.reflect.InvocationTargetException;
0013: import java.util.ArrayList;
0014: import java.util.HashMap;
0015: import java.util.Iterator;
0016: import java.util.List;
0017: import java.util.Map;
0018:
0019: import org.eclipse.core.commands.IHandler;
0020: import org.eclipse.core.expressions.Expression;
0021: import org.eclipse.core.runtime.Assert;
0022: import org.eclipse.core.runtime.IAdaptable;
0023: import org.eclipse.core.runtime.IExtension;
0024: import org.eclipse.core.runtime.IExtensionPoint;
0025: import org.eclipse.core.runtime.IStatus;
0026: import org.eclipse.core.runtime.ListenerList;
0027: import org.eclipse.core.runtime.MultiStatus;
0028: import org.eclipse.core.runtime.Platform;
0029: import org.eclipse.core.runtime.Status;
0030: import org.eclipse.core.runtime.dynamichelpers.ExtensionTracker;
0031: import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler;
0032: import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
0033: import org.eclipse.jface.action.ContributionManager;
0034: import org.eclipse.jface.action.CoolBarManager;
0035: import org.eclipse.jface.action.GroupMarker;
0036: import org.eclipse.jface.action.IAction;
0037: import org.eclipse.jface.action.IContributionItem;
0038: import org.eclipse.jface.action.IContributionManager;
0039: import org.eclipse.jface.action.ICoolBarManager;
0040: import org.eclipse.jface.action.IMenuManager;
0041: import org.eclipse.jface.action.IToolBarManager;
0042: import org.eclipse.jface.action.MenuManager;
0043: import org.eclipse.jface.action.Separator;
0044: import org.eclipse.jface.action.StatusLineManager;
0045: import org.eclipse.jface.commands.ActionHandler;
0046: import org.eclipse.jface.internal.provisional.action.ICoolBarManager2;
0047: import org.eclipse.jface.internal.provisional.action.IToolBarContributionItem;
0048: import org.eclipse.jface.operation.IRunnableWithProgress;
0049: import org.eclipse.jface.util.IPropertyChangeListener;
0050: import org.eclipse.jface.util.PropertyChangeEvent;
0051: import org.eclipse.jface.window.ApplicationWindow;
0052: import org.eclipse.jface.window.Window;
0053: import org.eclipse.osgi.util.NLS;
0054: import org.eclipse.osgi.util.TextProcessor;
0055: import org.eclipse.swt.SWT;
0056: import org.eclipse.swt.custom.BusyIndicator;
0057: import org.eclipse.swt.custom.CBanner;
0058: import org.eclipse.swt.custom.StackLayout;
0059: import org.eclipse.swt.events.ControlAdapter;
0060: import org.eclipse.swt.events.ControlEvent;
0061: import org.eclipse.swt.events.ShellAdapter;
0062: import org.eclipse.swt.events.ShellEvent;
0063: import org.eclipse.swt.graphics.Point;
0064: import org.eclipse.swt.graphics.Rectangle;
0065: import org.eclipse.swt.widgets.Composite;
0066: import org.eclipse.swt.widgets.Control;
0067: import org.eclipse.swt.widgets.CoolBar;
0068: import org.eclipse.swt.widgets.Display;
0069: import org.eclipse.swt.widgets.Event;
0070: import org.eclipse.swt.widgets.Layout;
0071: import org.eclipse.swt.widgets.Listener;
0072: import org.eclipse.swt.widgets.Menu;
0073: import org.eclipse.swt.widgets.Shell;
0074: import org.eclipse.ui.ActiveShellExpression;
0075: import org.eclipse.ui.IEditorPart;
0076: import org.eclipse.ui.IElementFactory;
0077: import org.eclipse.ui.IMemento;
0078: import org.eclipse.ui.IPageListener;
0079: import org.eclipse.ui.IPartService;
0080: import org.eclipse.ui.IPersistable;
0081: import org.eclipse.ui.IPersistableElement;
0082: import org.eclipse.ui.IPerspectiveDescriptor;
0083: import org.eclipse.ui.ISelectionService;
0084: import org.eclipse.ui.IWorkbench;
0085: import org.eclipse.ui.IWorkbenchActionConstants;
0086: import org.eclipse.ui.IWorkbenchPage;
0087: import org.eclipse.ui.IWorkbenchPart;
0088: import org.eclipse.ui.IWorkbenchPartReference;
0089: import org.eclipse.ui.IWorkbenchPreferenceConstants;
0090: import org.eclipse.ui.IWorkbenchWindow;
0091: import org.eclipse.ui.PlatformUI;
0092: import org.eclipse.ui.WorkbenchException;
0093: import org.eclipse.ui.application.ActionBarAdvisor;
0094: import org.eclipse.ui.application.WorkbenchAdvisor;
0095: import org.eclipse.ui.application.WorkbenchWindowAdvisor;
0096: import org.eclipse.ui.commands.ICommandService;
0097: import org.eclipse.ui.contexts.IContextService;
0098: import org.eclipse.ui.contexts.IWorkbenchContextSupport;
0099: import org.eclipse.ui.handlers.IHandlerActivation;
0100: import org.eclipse.ui.handlers.IHandlerService;
0101: import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
0102: import org.eclipse.ui.internal.actions.CommandAction;
0103: import org.eclipse.ui.internal.commands.SlaveCommandService;
0104: import org.eclipse.ui.internal.contexts.ContextAuthority;
0105: import org.eclipse.ui.internal.contexts.SlaveContextService;
0106: import org.eclipse.ui.internal.dialogs.CustomizePerspectiveDialog;
0107: import org.eclipse.ui.internal.dnd.DragUtil;
0108: import org.eclipse.ui.internal.dnd.SwtUtil;
0109: import org.eclipse.ui.internal.expressions.WorkbenchWindowExpression;
0110: import org.eclipse.ui.internal.handlers.ActionCommandMappingService;
0111: import org.eclipse.ui.internal.handlers.IActionCommandMappingService;
0112: import org.eclipse.ui.internal.handlers.SlaveHandlerService;
0113: import org.eclipse.ui.internal.intro.IIntroConstants;
0114: import org.eclipse.ui.internal.layout.CacheWrapper;
0115: import org.eclipse.ui.internal.layout.ITrimManager;
0116: import org.eclipse.ui.internal.layout.IWindowTrim;
0117: import org.eclipse.ui.internal.layout.LayoutUtil;
0118: import org.eclipse.ui.internal.layout.TrimLayout;
0119: import org.eclipse.ui.internal.menus.IActionSetsListener;
0120: import org.eclipse.ui.internal.menus.LegacyActionPersistence;
0121: import org.eclipse.ui.internal.menus.TrimBarManager2;
0122: import org.eclipse.ui.internal.menus.TrimContributionManager;
0123: import org.eclipse.ui.internal.menus.WindowMenuService;
0124: import org.eclipse.ui.internal.misc.Policy;
0125: import org.eclipse.ui.internal.misc.UIListenerLogging;
0126: import org.eclipse.ui.internal.misc.UIStats;
0127: import org.eclipse.ui.internal.presentations.DefaultActionBarPresentationFactory;
0128: import org.eclipse.ui.internal.progress.ProgressRegion;
0129: import org.eclipse.ui.internal.provisional.application.IActionBarConfigurer2;
0130: import org.eclipse.ui.internal.provisional.presentations.IActionBarPresentationFactory;
0131: import org.eclipse.ui.internal.registry.ActionSetRegistry;
0132: import org.eclipse.ui.internal.registry.IActionSetDescriptor;
0133: import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
0134: import org.eclipse.ui.internal.registry.UIExtensionTracker;
0135: import org.eclipse.ui.internal.services.ServiceLocator;
0136: import org.eclipse.ui.internal.util.PrefUtil;
0137: import org.eclipse.ui.internal.util.Util;
0138: import org.eclipse.ui.menus.IMenuService;
0139: import org.eclipse.ui.menus.MenuUtil;
0140: import org.eclipse.ui.presentations.AbstractPresentationFactory;
0141: import org.eclipse.ui.services.IServiceScopes;
0142:
0143: /**
0144: * A window within the workbench.
0145: */
0146: public class WorkbenchWindow extends ApplicationWindow implements
0147: IWorkbenchWindow {
0148:
0149: private WorkbenchWindowAdvisor windowAdvisor;
0150:
0151: private ActionBarAdvisor actionBarAdvisor;
0152:
0153: private int number;
0154:
0155: private PageList pageList = new PageList();
0156:
0157: private PageListenerList pageListeners = new PageListenerList();
0158:
0159: private PerspectiveListenerList perspectiveListeners = new PerspectiveListenerList();
0160:
0161: private WWinPartService partService = new WWinPartService(this );
0162:
0163: private ActionPresentation actionPresentation;
0164:
0165: private WWinActionBars actionBars;
0166:
0167: private boolean updateDisabled = true;
0168:
0169: private boolean closing = false;
0170:
0171: private boolean shellActivated = false;
0172:
0173: private FastViewBar fastViewBar;
0174:
0175: private PerspectiveSwitcher perspectiveSwitcher = null;
0176:
0177: private TrimLayout defaultLayout;
0178:
0179: ProgressRegion progressRegion = null;
0180:
0181: // Legacy (3.2) contribution handling
0182: private TrimBarManager2 trimMgr2 = null;
0183:
0184: // 3.3 Trim Contribution handling
0185: private TrimContributionManager trimContributionMgr = null;
0186:
0187: /**
0188: * The map of services maintained by the workbench window. These services
0189: * are initialized during workbench window during the
0190: * {@link #configureShell(Shell)}.
0191: */
0192: private final ServiceLocator serviceLocator;
0193:
0194: private HeapStatus heapStatus;
0195:
0196: private WindowTrimProxy heapStatusTrim = null;
0197:
0198: private boolean emptyWindowContentsCreated = false;
0199:
0200: private Control emptyWindowContents;
0201:
0202: private Rectangle normalBounds;
0203:
0204: private boolean asMaximizedState = false;
0205:
0206: private CBanner topBar;
0207:
0208: private IWindowTrim topBarTrim;
0209:
0210: // Previous shell size. Used to prevent the CBanner from triggering
0211: // redundant layouts
0212: private Point lastShellSize = new Point(0, 0);
0213:
0214: /**
0215: * The composite under which workbench pages create their controls.
0216: *
0217: * @since 3.0
0218: */
0219: private Composite pageComposite;
0220:
0221: /**
0222: * Bit flags indication which submenus (New, Show Views, ...) this window
0223: * contains. Initially none.
0224: *
0225: * @since 3.0
0226: */
0227: private int submenus = 0x00;
0228:
0229: /**
0230: * Object for configuring this workbench window. Lazily initialized to an
0231: * instance unique to this window.
0232: *
0233: * @since 3.0
0234: */
0235: private WorkbenchWindowConfigurer windowConfigurer = null;
0236:
0237: /**
0238: * List of generic property listeners.
0239: *
0240: * @since 3.3
0241: */
0242: private ListenerList genericPropertyListeners = new ListenerList();
0243:
0244: private ShellPool detachedWindowShells;
0245:
0246: static final String TEXT_DELIMITERS = TextProcessor
0247: .getDefaultDelimiters()
0248: + "-"; //$NON-NLS-1$
0249:
0250: // constants for shortcut bar group ids
0251: static final String GRP_PAGES = "pages"; //$NON-NLS-1$
0252:
0253: static final String GRP_PERSPECTIVES = "perspectives"; //$NON-NLS-1$
0254:
0255: static final String GRP_FAST_VIEWS = "fastViews"; //$NON-NLS-1$
0256:
0257: // static fields for inner classes.
0258: static final int VGAP = 0;
0259:
0260: static final int CLIENT_INSET = 3;
0261:
0262: static final int BAR_SIZE = 23;
0263:
0264: /**
0265: * Coolbar visibility change property.
0266: *
0267: * @since 3.3
0268: */
0269: public static final String PROP_COOLBAR_VISIBLE = "coolbarVisible"; //$NON-NLS-1$
0270:
0271: /**
0272: * Perspective bar visibility change property.
0273: *
0274: * @since 3.3
0275: */
0276: public static final String PROP_PERSPECTIVEBAR_VISIBLE = "perspectiveBarVisible"; //$NON-NLS-1$
0277:
0278: /**
0279: * Constant (bit mask) indicating which the Show View submenu is probably
0280: * present somewhere in this window.
0281: *
0282: * @see #addSubmenu
0283: * @since 3.0
0284: */
0285: public static final int SHOW_VIEW_SUBMENU = 0x01;
0286:
0287: /**
0288: * Constant (bit mask) indicating which the Open Perspective submenu is
0289: * probably present somewhere in this window.
0290: *
0291: * @see #addSubmenu
0292: * @since 3.0
0293: */
0294: public static final int OPEN_PERSPECTIVE_SUBMENU = 0x02;
0295:
0296: /**
0297: * Constant (bit mask) indicating which the New Wizard submenu is probably
0298: * present somewhere in this window.
0299: *
0300: * @see #addSubmenu
0301: * @since 3.0
0302: */
0303: public static final int NEW_WIZARD_SUBMENU = 0x04;
0304:
0305: /**
0306: * Remembers that this window contains the given submenu.
0307: *
0308: * @param type
0309: * the type of submenu, one of:
0310: * {@link #NEW_WIZARD_SUBMENU NEW_WIZARD_SUBMENU},
0311: * {@link #OPEN_PERSPECTIVE_SUBMENU OPEN_PERSPECTIVE_SUBMENU},
0312: * {@link #SHOW_VIEW_SUBMENU SHOW_VIEW_SUBMENU}
0313: * @see #containsSubmenu
0314: * @since 3.0
0315: */
0316: public void addSubmenu(int type) {
0317: submenus |= type;
0318: }
0319:
0320: /**
0321: * Checks to see if this window contains the given type of submenu.
0322: *
0323: * @param type
0324: * the type of submenu, one of:
0325: * {@link #NEW_WIZARD_SUBMENU NEW_WIZARD_SUBMENU},
0326: * {@link #OPEN_PERSPECTIVE_SUBMENU OPEN_PERSPECTIVE_SUBMENU},
0327: * {@link #SHOW_VIEW_SUBMENU SHOW_VIEW_SUBMENU}
0328: * @return <code>true</code> if window contains submenu,
0329: * <code>false</code> otherwise
0330: * @see #addSubmenu
0331: * @since 3.0
0332: */
0333: public boolean containsSubmenu(int type) {
0334: return ((submenus & type) != 0);
0335: }
0336:
0337: /**
0338: * Constant indicating that all the actions bars should be filled.
0339: *
0340: * @since 3.0
0341: */
0342: private static final int FILL_ALL_ACTION_BARS = ActionBarAdvisor.FILL_MENU_BAR
0343: | ActionBarAdvisor.FILL_COOL_BAR
0344: | ActionBarAdvisor.FILL_STATUS_LINE;
0345:
0346: /**
0347: * Creates and initializes a new workbench window.
0348: *
0349: * @param number
0350: * the number for the window
0351: */
0352: public WorkbenchWindow(int number) {
0353: super (null);
0354: this .number = number;
0355:
0356: // Make sure there is a workbench. This call will throw
0357: // an exception if workbench not created yet.
0358: final IWorkbench workbench = PlatformUI.getWorkbench();
0359: this .serviceLocator = new ServiceLocator(workbench);
0360: initializeDefaultServices();
0361:
0362: // Add contribution managers that are exposed to other plugins.
0363: addMenuBar();
0364: addCoolBar(SWT.NONE); // style is unused
0365: addStatusLine();
0366:
0367: // register with the tracker
0368: getExtensionTracker()
0369: .registerHandler(
0370: actionSetHandler,
0371: ExtensionTracker
0372: .createExtensionPointFilter(getActionSetExtensionPoint()));
0373:
0374: fireWindowOpening();
0375:
0376: // set the shell style
0377: setShellStyle(getWindowConfigurer().getShellStyle());
0378:
0379: // Fill the action bars
0380: fillActionBars(FILL_ALL_ACTION_BARS);
0381: }
0382:
0383: /**
0384: * Return the action set extension point.
0385: *
0386: * @return the action set extension point
0387: * @since 3.1
0388: */
0389: private IExtensionPoint getActionSetExtensionPoint() {
0390: return Platform.getExtensionRegistry().getExtensionPoint(
0391: PlatformUI.PLUGIN_ID,
0392: IWorkbenchRegistryConstants.PL_ACTION_SETS);
0393: }
0394:
0395: /**
0396: * Return the style bits for the shortcut bar.
0397: *
0398: * @return int
0399: */
0400: protected int perspectiveBarStyle() {
0401: return SWT.FLAT | SWT.WRAP | SWT.RIGHT | SWT.HORIZONTAL;
0402: }
0403:
0404: private TrimDropTarget trimDropTarget;
0405:
0406: private boolean coolBarVisible = true;
0407:
0408: private boolean perspectiveBarVisible = true;
0409:
0410: private boolean fastViewBarVisible = true;
0411:
0412: private boolean statusLineVisible = true;
0413:
0414: private IWindowTrim statusLineTrim = null;
0415:
0416: /**
0417: * The handlers for global actions that were last submitted to the workbench
0418: * command support. This is a map of command identifiers to
0419: * <code>ActionHandler</code>. This map is never <code>null</code>,
0420: * and is never empty as long as at least one global action has been
0421: * registered.
0422: */
0423: private Map globalActionHandlersByCommandId = new HashMap();
0424:
0425: /**
0426: * The list of handler submissions submitted to the workbench command
0427: * support. This list may be empty, but it is never <code>null</code>.
0428: */
0429: private List handlerActivations = new ArrayList();
0430:
0431: /**
0432: * The number of large updates that are currently going on. If this is
0433: * number is greater than zero, then UI updateActionBars is a no-op.
0434: *
0435: * @since 3.1
0436: */
0437: private int largeUpdates = 0;
0438:
0439: private IExtensionTracker tracker;
0440:
0441: private IExtensionChangeHandler actionSetHandler = new IExtensionChangeHandler() {
0442:
0443: /*
0444: * (non-Javadoc)
0445: *
0446: * @see org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler#addExtension(org.eclipse.core.runtime.dynamichelpers.IExtensionTracker,
0447: * org.eclipse.core.runtime.IExtension)
0448: */
0449: public void addExtension(IExtensionTracker tracker,
0450: IExtension extension) {
0451: // this assumes that the workbench-level tracker will have already
0452: // updated the registry
0453:
0454: ArrayList setsToActivate = new ArrayList();
0455: // look for all new sets that are on by default. Examine the tracker
0456: // at the workbench level to see what descriptors are registered
0457: // against this extension
0458: Object[] registeredObjects = getWorkbench()
0459: .getExtensionTracker().getObjects(extension);
0460: for (int i = 0; i < registeredObjects.length; i++) {
0461: if (registeredObjects[i] instanceof IActionSetDescriptor) {
0462: IActionSetDescriptor desc = (IActionSetDescriptor) registeredObjects[i];
0463: if (desc.isInitiallyVisible()) {
0464: setsToActivate.add(desc);
0465: }
0466: }
0467: }
0468:
0469: // if none of the new sets are marked as initially visible, abort.
0470: if (setsToActivate.isEmpty()) {
0471: return;
0472: }
0473:
0474: IActionSetDescriptor[] descriptors = (IActionSetDescriptor[]) setsToActivate
0475: .toArray(new IActionSetDescriptor[setsToActivate
0476: .size()]);
0477:
0478: WorkbenchPage page = getActiveWorkbenchPage();
0479: if (page != null) {
0480: Perspective[] perspectives = page
0481: .getOpenInternalPerspectives();
0482:
0483: for (int i = 0; i < perspectives.length; i++) {
0484: perspectives[i].turnOnActionSets(descriptors);
0485: }
0486: }
0487:
0488: updateActionSets();
0489: }
0490:
0491: /*
0492: * (non-Javadoc)
0493: *
0494: * @see org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler#removeExtension(org.eclipse.core.runtime.IExtension,
0495: * java.lang.Object[])
0496: */
0497: public void removeExtension(IExtension extension,
0498: Object[] objects) {
0499: // remove the contributions from the window bars and dispose of the
0500: // actions
0501: for (int i = 0; i < objects.length; i++) {
0502: if (objects[i] instanceof PluginActionSetBuilder.Binding) {
0503: PluginActionSetBuilder.Binding binding = (PluginActionSetBuilder.Binding) objects[i];
0504: binding.builder.removeActionExtensions(binding.set,
0505: binding.window);
0506: binding.set.dispose();
0507: }
0508: }
0509:
0510: // update all opened perspectives
0511: Perspective[] perspectives = getActiveWorkbenchPage()
0512: .getOpenInternalPerspectives();
0513: boolean updateNeeded = true;
0514: IContextService contextService = (IContextService) getService(IContextService.class);
0515: try {
0516: contextService
0517: .activateContext(ContextAuthority.DEFER_EVENTS);
0518:
0519: for (int i = 0; i < perspectives.length; i++) {
0520: for (int j = 0; j < objects.length; j++) {
0521: if (objects[j] instanceof IActionSetDescriptor) {
0522: perspectives[i]
0523: .removeActionSet((IActionSetDescriptor) objects[j]);
0524: getActionPresentation().removeActionSet(
0525: (IActionSetDescriptor) objects[j]);
0526: }
0527: }
0528: }
0529: } finally {
0530: contextService
0531: .activateContext(ContextAuthority.SEND_EVENTS);
0532: }
0533:
0534: if (updateNeeded) {
0535: // refresh the window
0536: updateActionSets();
0537: }
0538: }
0539: };
0540:
0541: void registerGlobalAction(IAction globalAction) {
0542: String commandId = globalAction.getActionDefinitionId();
0543:
0544: if (commandId != null) {
0545: final Object value = globalActionHandlersByCommandId
0546: .get(commandId);
0547: if (value instanceof ActionHandler) {
0548: // This handler is about to get clobbered, so dispose it.
0549: final ActionHandler handler = (ActionHandler) value;
0550: handler.dispose();
0551: }
0552:
0553: if (globalAction instanceof CommandAction) {
0554: final String actionId = globalAction.getId();
0555: if (actionId != null) {
0556: final IActionCommandMappingService mappingService = (IActionCommandMappingService) serviceLocator
0557: .getService(IActionCommandMappingService.class);
0558: mappingService.map(actionId, commandId);
0559: }
0560: } else {
0561: globalActionHandlersByCommandId.put(commandId,
0562: new ActionHandler(globalAction));
0563: }
0564: }
0565:
0566: submitGlobalActions();
0567: }
0568:
0569: /**
0570: * <p>
0571: * Submits the action handlers for action set actions and global actions.
0572: * Global actions are given priority, so that if a global action and an
0573: * action set action both handle the same command, the global action is
0574: * given priority.
0575: * </p>
0576: * <p>
0577: * These submissions are submitted as <code>Priority.LEGACY</code>, which
0578: * means that they are the lowest priority. This means that if a higher
0579: * priority submission handles the same command under the same conditions,
0580: * that that submission will become the handler.
0581: * </p>
0582: */
0583: void submitGlobalActions() {
0584: final IHandlerService handlerService = (IHandlerService) getWorkbench()
0585: .getService(IHandlerService.class);
0586:
0587: /*
0588: * Mash the action sets and global actions together, with global actions
0589: * taking priority.
0590: */
0591: Map handlersByCommandId = new HashMap();
0592: handlersByCommandId.putAll(globalActionHandlersByCommandId);
0593:
0594: List newHandlers = new ArrayList(handlersByCommandId.size());
0595:
0596: Iterator existingIter = handlerActivations.iterator();
0597: while (existingIter.hasNext()) {
0598: IHandlerActivation next = (IHandlerActivation) existingIter
0599: .next();
0600:
0601: String cmdId = next.getCommandId();
0602:
0603: Object handler = handlersByCommandId.get(cmdId);
0604: if (handler == next.getHandler()) {
0605: handlersByCommandId.remove(cmdId);
0606: newHandlers.add(next);
0607: } else {
0608: handlerService.deactivateHandler(next);
0609: }
0610: }
0611:
0612: final Shell shell = getShell();
0613: if (shell != null) {
0614: final Expression expression = new ActiveShellExpression(
0615: shell);
0616: for (Iterator iterator = handlersByCommandId.entrySet()
0617: .iterator(); iterator.hasNext();) {
0618: Map.Entry entry = (Map.Entry) iterator.next();
0619: String commandId = (String) entry.getKey();
0620: IHandler handler = (IHandler) entry.getValue();
0621: newHandlers.add(handlerService.activateHandler(
0622: commandId, handler, expression));
0623: }
0624: }
0625:
0626: handlerActivations = newHandlers;
0627: }
0628:
0629: /**
0630: * Add a generic property listener.
0631: *
0632: * @param listener the listener to add
0633: * @since 3.3
0634: */
0635: public void addPropertyChangeListener(
0636: IPropertyChangeListener listener) {
0637: genericPropertyListeners.add(listener);
0638: }
0639:
0640: /**
0641: * Removes a generic property listener.
0642: *
0643: * @param listener the listener to remove
0644: * @since 3.3
0645: */
0646: public void removePropertyChangeListener(
0647: IPropertyChangeListener listener) {
0648: genericPropertyListeners.remove(listener);
0649: }
0650:
0651: private void firePropertyChanged(final String property,
0652: final Object oldValue, final Object newValue) {
0653: PropertyChangeEvent event = new PropertyChangeEvent(this ,
0654: property, oldValue, newValue);
0655: Object[] listeners = genericPropertyListeners.getListeners();
0656: for (int i = 0; i < listeners.length; i++) {
0657: IPropertyChangeListener listener = (IPropertyChangeListener) listeners[i];
0658: listener.propertyChange(event);
0659: }
0660: }
0661:
0662: /*
0663: * Adds an listener to the part service.
0664: */
0665: public void addPageListener(IPageListener l) {
0666: pageListeners.addPageListener(l);
0667: }
0668:
0669: /**
0670: * @see org.eclipse.ui.IPageService
0671: */
0672: public void addPerspectiveListener(
0673: org.eclipse.ui.IPerspectiveListener l) {
0674: perspectiveListeners.addPerspectiveListener(l);
0675: }
0676:
0677: /**
0678: * Configures this window to have a perspecive bar. Does nothing if it
0679: * already has one.
0680: */
0681: protected void addPerspectiveBar(int style) {
0682: Assert.isTrue(perspectiveSwitcher == null);
0683: perspectiveSwitcher = new PerspectiveSwitcher(this , topBar,
0684: style);
0685: }
0686:
0687: /**
0688: * Close the window.
0689: *
0690: * Assumes that busy cursor is active.
0691: */
0692: private boolean busyClose() {
0693: // Whether the window was actually closed or not
0694: boolean windowClosed = false;
0695:
0696: // Setup internal flags to indicate window is in
0697: // progress of closing and no update should be done.
0698: closing = true;
0699: updateDisabled = true;
0700:
0701: try {
0702: // Only do the check if it is OK to close if we are not closing
0703: // via the workbench as the workbench will check this itself.
0704: Workbench workbench = getWorkbenchImpl();
0705: int count = workbench.getWorkbenchWindowCount();
0706: // also check for starting - if the first window dies on startup
0707: // then we'll need to open a default window.
0708: if (!workbench.isStarting()
0709: && !workbench.isClosing()
0710: && count <= 1
0711: && workbench.getWorkbenchConfigurer()
0712: .getExitOnLastWindowClose()) {
0713: windowClosed = workbench.close();
0714: } else {
0715: if (okToClose()) {
0716: windowClosed = hardClose();
0717: }
0718: }
0719: } finally {
0720: if (!windowClosed) {
0721: // Reset the internal flags if window was not closed.
0722: closing = false;
0723: updateDisabled = false;
0724: }
0725: }
0726:
0727: if (windowClosed && tracker != null) {
0728: tracker.close();
0729: }
0730:
0731: return windowClosed;
0732: }
0733:
0734: /**
0735: * Opens a new page. Assumes that busy cursor is active.
0736: * <p>
0737: * <b>Note:</b> Since release 2.0, a window is limited to contain at most
0738: * one page. If a page exist in the window when this method is used, then
0739: * another window is created for the new page. Callers are strongly
0740: * recommended to use the <code>IWorkbench.openPerspective</code> APIs to
0741: * programmatically show a perspective.
0742: * </p>
0743: */
0744: protected IWorkbenchPage busyOpenPage(String perspID,
0745: IAdaptable input) throws WorkbenchException {
0746: IWorkbenchPage newPage = null;
0747:
0748: if (pageList.isEmpty()) {
0749: newPage = new WorkbenchPage(this , perspID, input);
0750: pageList.add(newPage);
0751: firePageOpened(newPage);
0752: setActivePage(newPage);
0753: } else {
0754: IWorkbenchWindow window = getWorkbench()
0755: .openWorkbenchWindow(perspID, input);
0756: newPage = window.getActivePage();
0757: }
0758:
0759: return newPage;
0760: }
0761:
0762: /**
0763: * @see Window
0764: */
0765: public int open() {
0766: if (getPages().length == 0) {
0767: showEmptyWindowContents();
0768: }
0769: fireWindowCreated();
0770: getWindowAdvisor().openIntro();
0771: int result = super .open();
0772:
0773: // It's time for a layout ... to insure that if TrimLayout
0774: // is in play, it updates all of the trim it's responsible
0775: // for. We have to do this before updating in order to get
0776: // the PerspectiveBar management correct...see defect 137334
0777: getShell().layout();
0778:
0779: fireWindowOpened();
0780: if (perspectiveSwitcher != null) {
0781: perspectiveSwitcher.updatePerspectiveBar();
0782: perspectiveSwitcher.updateBarParent();
0783: }
0784:
0785: return result;
0786: }
0787:
0788: /*
0789: * (non-Javadoc) Method declared on Window.
0790: */
0791: protected boolean canHandleShellCloseEvent() {
0792: if (!super .canHandleShellCloseEvent()) {
0793: return false;
0794: }
0795: // let the advisor or other interested parties
0796: // veto the user's explicit request to close the window
0797: return fireWindowShellClosing();
0798: }
0799:
0800: /**
0801: * @see IWorkbenchWindow
0802: */
0803: public boolean close() {
0804: final boolean[] ret = new boolean[1];
0805: BusyIndicator.showWhile(null, new Runnable() {
0806: public void run() {
0807: ret[0] = busyClose();
0808: }
0809: });
0810: return ret[0];
0811: }
0812:
0813: protected boolean isClosing() {
0814: return closing || getWorkbenchImpl().isClosing();
0815: }
0816:
0817: /**
0818: * Return whether or not the coolbar layout is locked.
0819: */
0820: protected boolean isCoolBarLocked() {
0821: ICoolBarManager cbm = getCoolBarManager2();
0822: return cbm != null && cbm.getLockLayout();
0823: }
0824:
0825: /**
0826: * Close all of the pages.
0827: */
0828: private void closeAllPages() {
0829: // Deactivate active page.
0830: setActivePage(null);
0831:
0832: // Clone and deref all so that calls to getPages() returns
0833: // empty list (if call by pageClosed event handlers)
0834: PageList oldList = pageList;
0835: pageList = new PageList();
0836:
0837: // Close all.
0838: Iterator itr = oldList.iterator();
0839: while (itr.hasNext()) {
0840: WorkbenchPage page = (WorkbenchPage) itr.next();
0841: firePageClosed(page);
0842: page.dispose();
0843: }
0844: if (!closing) {
0845: showEmptyWindowContents();
0846: }
0847: }
0848:
0849: /**
0850: * Save and close all of the pages.
0851: */
0852: public void closeAllPages(boolean save) {
0853: if (save) {
0854: boolean ret = saveAllPages(true);
0855: if (!ret) {
0856: return;
0857: }
0858: }
0859: closeAllPages();
0860: }
0861:
0862: /**
0863: * closePerspective method comment.
0864: */
0865: protected boolean closePage(IWorkbenchPage in, boolean save) {
0866: // Validate the input.
0867: if (!pageList.contains(in)) {
0868: return false;
0869: }
0870: WorkbenchPage oldPage = (WorkbenchPage) in;
0871:
0872: // Save old perspective.
0873: if (save && oldPage.isSaveNeeded()) {
0874: if (!oldPage.saveAllEditors(true)) {
0875: return false;
0876: }
0877: }
0878:
0879: // If old page is activate deactivate.
0880: boolean oldIsActive = (oldPage == getActiveWorkbenchPage());
0881: if (oldIsActive) {
0882: setActivePage(null);
0883: }
0884:
0885: // Close old page.
0886: pageList.remove(oldPage);
0887: firePageClosed(oldPage);
0888: oldPage.dispose();
0889:
0890: // Activate new page.
0891: if (oldIsActive) {
0892: IWorkbenchPage newPage = pageList.getNextActive();
0893: if (newPage != null) {
0894: setActivePage(newPage);
0895: }
0896: }
0897: if (!closing && pageList.isEmpty()) {
0898: showEmptyWindowContents();
0899: }
0900: return true;
0901: }
0902:
0903: private void showEmptyWindowContents() {
0904: if (!emptyWindowContentsCreated) {
0905: Composite parent = getPageComposite();
0906: emptyWindowContents = getWindowAdvisor()
0907: .createEmptyWindowContents(parent);
0908: emptyWindowContentsCreated = true;
0909: // force the empty window composite to be layed out
0910: ((StackLayout) parent.getLayout()).topControl = emptyWindowContents;
0911: parent.layout();
0912: }
0913: }
0914:
0915: private void hideEmptyWindowContents() {
0916: if (emptyWindowContentsCreated) {
0917: if (emptyWindowContents != null) {
0918: emptyWindowContents.dispose();
0919: emptyWindowContents = null;
0920: getPageComposite().layout();
0921: }
0922: emptyWindowContentsCreated = false;
0923: }
0924: }
0925:
0926: /*
0927: * (non-Javadoc)
0928: *
0929: * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
0930: */
0931: protected void configureShell(Shell shell) {
0932: super .configureShell(shell);
0933:
0934: detachedWindowShells = new ShellPool(shell, SWT.TOOL
0935: | SWT.TITLE | SWT.MAX | SWT.RESIZE
0936: | getDefaultOrientation());
0937:
0938: String title = getWindowConfigurer().basicGetTitle();
0939: if (title != null) {
0940: shell
0941: .setText(TextProcessor.process(title,
0942: TEXT_DELIMITERS));
0943: }
0944:
0945: final IWorkbench workbench = getWorkbench();
0946: workbench.getHelpSystem().setHelp(shell,
0947: IWorkbenchHelpContextIds.WORKBENCH_WINDOW);
0948:
0949: // initializeDefaultServices();
0950: final IContextService contextService = (IContextService) getWorkbench()
0951: .getService(IContextService.class);
0952: contextService
0953: .registerShell(shell, IContextService.TYPE_WINDOW);
0954:
0955: trackShellActivation(shell);
0956: trackShellResize(shell);
0957: }
0958:
0959: /* package */ShellPool getDetachedWindowPool() {
0960: return detachedWindowShells;
0961: }
0962:
0963: /*
0964: * (non-Javadoc)
0965: *
0966: * @see org.eclipse.jface.window.ApplicationWindow#createTrimWidgets(org.eclipse.swt.widgets.Shell)
0967: */
0968: protected void createTrimWidgets(Shell shell) {
0969: // do nothing -- trim widgets are created in createDefaultContents
0970: }
0971:
0972: /**
0973: * Creates and remembers the client composite, under which workbench pages
0974: * create their controls.
0975: *
0976: * @since 3.0
0977: */
0978: protected Composite createPageComposite(Composite parent) {
0979: pageComposite = new Composite(parent, SWT.NONE);
0980: // use a StackLayout instead of a FillLayout (see bug 81460 [Workbench]
0981: // (regression) Close all perspectives, open Java perspective, layout
0982: // wrong)
0983: pageComposite.setLayout(new StackLayout());
0984: return pageComposite;
0985: }
0986:
0987: /**
0988: * Creates the contents of the workbench window, including trim controls and
0989: * the client composite. This MUST create the client composite via a call to
0990: * <code>createClientComposite</code>.
0991: *
0992: * @since 3.0
0993: */
0994: protected Control createContents(Composite parent) {
0995: // we know from Window.create that the parent is a Shell.
0996: getWindowAdvisor().createWindowContents((Shell) parent);
0997: // the page composite must be set by createWindowContents
0998: Assert
0999: .isNotNull(pageComposite,
1000: "createWindowContents must call configurer.createPageComposite"); //$NON-NLS-1$
1001: return pageComposite;
1002: }
1003:
1004: /**
1005: * If the perspective bar is drawn on the top right corner of the window,
1006: * then this method changes its appearance from curved to square. This
1007: * should have its own preference, but for now it piggy-backs on the
1008: * SHOW_TRADITIONAL_STYLE_TABS preference.
1009: *
1010: * @param square
1011: * true for a square banner and false otherwise
1012: */
1013: public void setBannerCurve(boolean square) {
1014: if (topBar != null) {
1015: topBar.setSimple(square);
1016: }
1017: }
1018:
1019: /**
1020: * Creates the default contents and layout of the shell.
1021: *
1022: * @param shell
1023: * the shell
1024: */
1025: protected void createDefaultContents(final Shell shell) {
1026: defaultLayout = new TrimLayout();
1027: defaultLayout.setSpacing(2, 2, 2, 2);
1028: defaultLayout.setMargins(2, 2);
1029: shell.setLayout(defaultLayout);
1030:
1031: Menu menuBar = getMenuBarManager().createMenuBar(shell);
1032: if (getWindowConfigurer().getShowMenuBar()) {
1033: shell.setMenuBar(menuBar);
1034: }
1035:
1036: // Create the CBanner widget which parents both the Coolbar
1037: // and the perspective switcher, and supports some configurations
1038: // on the left right and bottom
1039: topBar = new CBanner(shell, SWT.NONE);
1040: topBarTrim = new WindowTrimProxy(
1041: topBar,
1042: "org.eclipse.ui.internal.WorkbenchWindow.topBar", //$NON-NLS-1$
1043: WorkbenchMessages.TrimCommon_Main_TrimName, SWT.NONE,
1044: true);
1045:
1046: // the banner gets a curve along with the new tab style
1047: // TODO create a dedicated preference for this
1048: setBannerCurve(PrefUtil
1049: .getAPIPreferenceStore()
1050: .getBoolean(
1051: IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS));
1052:
1053: CacheWrapper coolbarCacheWrapper = new CacheWrapper(topBar);
1054:
1055: final Control coolBar = createCoolBarControl(coolbarCacheWrapper
1056: .getControl());
1057: // need to resize the shell, not just the coolbar's immediate
1058: // parent, if the coolbar wants to grow or shrink
1059:
1060: coolBar.addListener(SWT.Resize, new Listener() {
1061: public void handleEvent(Event event) {
1062: // If the user is dragging the sash then we will need to force
1063: // a resize. However, if the coolbar was resized programatically
1064: // then everything is already layed out correctly. There is no
1065: // direct way to tell the difference between these cases,
1066: // however
1067: // we take advantage of the fact that dragging the sash does not
1068: // change the size of the shell, and only force another layout
1069: // if the shell size is unchanged.
1070: Rectangle clientArea = shell.getClientArea();
1071:
1072: if (lastShellSize.x == clientArea.width
1073: && lastShellSize.y == clientArea.height) {
1074: LayoutUtil.resize(coolBar);
1075: }
1076:
1077: lastShellSize.x = clientArea.width;
1078: lastShellSize.y = clientArea.height;
1079: }
1080: });
1081:
1082: if (getWindowConfigurer().getShowCoolBar()) {
1083: topBar.setLeft(coolbarCacheWrapper.getControl());
1084: }
1085:
1086: createStatusLine(shell);
1087:
1088: fastViewBar = new FastViewBar(this );
1089: fastViewBar.createControl(shell);
1090:
1091: if (getWindowConfigurer().getShowPerspectiveBar()) {
1092: addPerspectiveBar(perspectiveBarStyle());
1093: perspectiveSwitcher.createControl(shell);
1094: }
1095:
1096: createProgressIndicator(shell);
1097:
1098: if (getShowHeapStatus()) {
1099: createHeapStatus(shell);
1100: }
1101:
1102: // Insert any contributed trim into the layout
1103: // Legacy (3.2) trim
1104: trimMgr2 = new TrimBarManager2(this );
1105:
1106: // 3.3 Trim contributions
1107: trimContributionMgr = new TrimContributionManager(this );
1108:
1109: trimDropTarget = new TrimDropTarget(shell, this );
1110: DragUtil.addDragTarget(shell, trimDropTarget);
1111: DragUtil.addDragTarget(null, trimDropTarget);
1112:
1113: // Create the client composite area (where page content goes).
1114: createPageComposite(shell);
1115:
1116: setLayoutDataForContents();
1117: // System.err.println(defaultLayout.displayTrim());
1118: }
1119:
1120: /**
1121: * Returns whether the heap status indicator should be shown.
1122: *
1123: * @return <code>true</code> to show the heap status indicator,
1124: * <code>false</code> otherwise
1125: */
1126: private boolean getShowHeapStatus() {
1127: return // Show if the preference is set or debug option is on
1128: PrefUtil.getAPIPreferenceStore().getBoolean(
1129: IWorkbenchPreferenceConstants.SHOW_MEMORY_MONITOR)
1130: || Boolean
1131: .valueOf(
1132: Platform
1133: .getDebugOption(PlatformUI.PLUGIN_ID
1134: + "/perf/showHeapStatus")).booleanValue(); //$NON-NLS-1$
1135: }
1136:
1137: /**
1138: * Creates the controls for the heap status indicator.
1139: *
1140: * @param parent
1141: * the parent composite
1142: */
1143: private void createHeapStatus(Composite parent) {
1144: heapStatus = new HeapStatus(parent, PrefUtil
1145: .getInternalPreferenceStore());
1146:
1147: // Subclass the trim to allow closing...
1148: heapStatusTrim = new WindowTrimProxy(
1149: heapStatus,
1150: "org.eclipse.ui.internal.HeapStatus", //$NON-NLS-1$
1151: WorkbenchMessages.TrimCommon_HeapStatus_TrimName,
1152: SWT.BOTTOM | SWT.TOP) {
1153:
1154: public void handleClose() {
1155: getControl().dispose();
1156: }
1157:
1158: public boolean isCloseable() {
1159: return true;
1160: }
1161: };
1162: }
1163:
1164: /**
1165: * <p>
1166: * Returns a new menu manager for this workbench window. This menu manager
1167: * will just be a proxy to the new command-based menu service.
1168: * </p>
1169: * <p>
1170: * Subclasses may override this method to customize the menu manager.
1171: * </p>
1172: *
1173: * @return a menu manager for this workbench window; never <code>null</code>.
1174: */
1175: protected MenuManager createMenuManager() {
1176: return super .createMenuManager();
1177: }
1178:
1179: /**
1180: * Set the perspective bar location
1181: *
1182: * @param location
1183: * the location to place the bar
1184: */
1185: public void setPerspectiveBarLocation(String location) {
1186: if (perspectiveSwitcher != null) {
1187: perspectiveSwitcher.setPerspectiveBarLocation(location);
1188: }
1189: }
1190:
1191: /**
1192: * Notifies interested parties (namely the advisor) that the window is about
1193: * to be opened.
1194: *
1195: * @since 3.1
1196: */
1197: private void fireWindowOpening() {
1198: // let the application do further configuration
1199: getWindowAdvisor().preWindowOpen();
1200: }
1201:
1202: /**
1203: * Notifies interested parties (namely the advisor) that the window has been
1204: * restored from a previously saved state.
1205: *
1206: * @throws WorkbenchException
1207: * passed through from the advisor
1208: * @since 3.1
1209: */
1210: void fireWindowRestored() throws WorkbenchException {
1211: getWindowAdvisor().postWindowRestore();
1212: }
1213:
1214: /**
1215: * Notifies interested parties (namely the advisor) that the window has been
1216: * created.
1217: *
1218: * @since 3.1
1219: */
1220: private void fireWindowCreated() {
1221: getWindowAdvisor().postWindowCreate();
1222: }
1223:
1224: /**
1225: * Notifies interested parties (namely the advisor and the window listeners)
1226: * that the window has been opened.
1227: *
1228: * @since 3.1
1229: */
1230: private void fireWindowOpened() {
1231: getWorkbenchImpl().fireWindowOpened(this );
1232: getWindowAdvisor().postWindowOpen();
1233: }
1234:
1235: /**
1236: * Notifies interested parties (namely the advisor) that the window's shell
1237: * is closing. Allows the close to be vetoed.
1238: *
1239: * @return <code>true</code> if the close should proceed,
1240: * <code>false</code> if it should be canceled
1241: * @since 3.1
1242: */
1243: private boolean fireWindowShellClosing() {
1244: return getWindowAdvisor().preWindowShellClose();
1245: }
1246:
1247: /**
1248: * Notifies interested parties (namely the advisor and the window listeners)
1249: * that the window has been closed.
1250: *
1251: * @since 3.1
1252: */
1253: private void fireWindowClosed() {
1254: // let the application do further deconfiguration
1255: getWindowAdvisor().postWindowClose();
1256: getWorkbenchImpl().fireWindowClosed(this );
1257: }
1258:
1259: /**
1260: * Fires page activated
1261: */
1262: private void firePageActivated(IWorkbenchPage page) {
1263: String label = null; // debugging only
1264: if (UIStats.isDebugging(UIStats.NOTIFY_PAGE_LISTENERS)) {
1265: label = "activated " + page.getLabel(); //$NON-NLS-1$
1266: }
1267: try {
1268: UIStats.start(UIStats.NOTIFY_PAGE_LISTENERS, label);
1269: UIListenerLogging.logPageEvent(this , page,
1270: UIListenerLogging.WPE_PAGE_ACTIVATED);
1271: pageListeners.firePageActivated(page);
1272: partService.pageActivated(page);
1273: } finally {
1274: UIStats.end(UIStats.NOTIFY_PAGE_LISTENERS, page.getLabel(),
1275: label);
1276: }
1277: }
1278:
1279: /**
1280: * Fires page closed
1281: */
1282: private void firePageClosed(IWorkbenchPage page) {
1283: String label = null; // debugging only
1284: if (UIStats.isDebugging(UIStats.NOTIFY_PAGE_LISTENERS)) {
1285: label = "closed " + page.getLabel(); //$NON-NLS-1$
1286: }
1287: try {
1288: UIStats.start(UIStats.NOTIFY_PAGE_LISTENERS, label);
1289: UIListenerLogging.logPageEvent(this , page,
1290: UIListenerLogging.WPE_PAGE_CLOSED);
1291: pageListeners.firePageClosed(page);
1292: partService.pageClosed(page);
1293: } finally {
1294: UIStats.end(UIStats.NOTIFY_PAGE_LISTENERS, page.getLabel(),
1295: label);
1296: }
1297:
1298: }
1299:
1300: /**
1301: * Fires page opened
1302: */
1303: private void firePageOpened(IWorkbenchPage page) {
1304: String label = null; // debugging only
1305: if (UIStats.isDebugging(UIStats.NOTIFY_PAGE_LISTENERS)) {
1306: label = "opened " + page.getLabel(); //$NON-NLS-1$
1307: }
1308: try {
1309: UIStats.start(UIStats.NOTIFY_PAGE_LISTENERS, label);
1310: UIListenerLogging.logPageEvent(this , page,
1311: UIListenerLogging.WPE_PAGE_OPENED);
1312: pageListeners.firePageOpened(page);
1313: partService.pageOpened(page);
1314: } finally {
1315: UIStats.end(UIStats.NOTIFY_PAGE_LISTENERS, page.getLabel(),
1316: label);
1317: }
1318: }
1319:
1320: /**
1321: * Fires perspective activated
1322: */
1323: void firePerspectiveActivated(IWorkbenchPage page,
1324: IPerspectiveDescriptor perspective) {
1325: UIListenerLogging.logPerspectiveEvent(this , page, perspective,
1326: UIListenerLogging.PLE_PERSP_ACTIVATED);
1327: perspectiveListeners
1328: .firePerspectiveActivated(page, perspective);
1329: }
1330:
1331: /**
1332: * Fires perspective deactivated.
1333: *
1334: * @since 3.2
1335: */
1336: void firePerspectivePreDeactivate(IWorkbenchPage page,
1337: IPerspectiveDescriptor perspective) {
1338: UIListenerLogging.logPerspectiveEvent(this , page, perspective,
1339: UIListenerLogging.PLE_PERSP_PRE_DEACTIVATE);
1340: perspectiveListeners.firePerspectivePreDeactivate(page,
1341: perspective);
1342: }
1343:
1344: /**
1345: * Fires perspective deactivated.
1346: *
1347: * @since 3.1
1348: */
1349: void firePerspectiveDeactivated(IWorkbenchPage page,
1350: IPerspectiveDescriptor perspective) {
1351: UIListenerLogging.logPerspectiveEvent(this , page, perspective,
1352: UIListenerLogging.PLE_PERSP_DEACTIVATED);
1353: perspectiveListeners.firePerspectiveDeactivated(page,
1354: perspective);
1355: }
1356:
1357: /**
1358: * Fires perspective changed
1359: */
1360: void firePerspectiveChanged(IWorkbenchPage page,
1361: IPerspectiveDescriptor perspective, String changeId) {
1362: // Some callers call this even when there is no active perspective.
1363: // Just ignore this case.
1364: if (perspective != null) {
1365: UIListenerLogging.logPerspectiveChangedEvent(this , page,
1366: perspective, null, changeId);
1367: perspectiveListeners.firePerspectiveChanged(page,
1368: perspective, changeId);
1369: }
1370: }
1371:
1372: /**
1373: * Fires perspective changed for an affected part
1374: */
1375: void firePerspectiveChanged(IWorkbenchPage page,
1376: IPerspectiveDescriptor perspective,
1377: IWorkbenchPartReference partRef, String changeId) {
1378: // Some callers call this even when there is no active perspective.
1379: // Just ignore this case.
1380: if (perspective != null) {
1381: UIListenerLogging.logPerspectiveChangedEvent(this , page,
1382: perspective, partRef, changeId);
1383: perspectiveListeners.firePerspectiveChanged(page,
1384: perspective, partRef, changeId);
1385: }
1386: }
1387:
1388: /**
1389: * Fires perspective closed
1390: */
1391: void firePerspectiveClosed(IWorkbenchPage page,
1392: IPerspectiveDescriptor perspective) {
1393: UIListenerLogging.logPerspectiveEvent(this , page, perspective,
1394: UIListenerLogging.PLE_PERSP_CLOSED);
1395: perspectiveListeners.firePerspectiveClosed(page, perspective);
1396: }
1397:
1398: /**
1399: * Fires perspective opened
1400: */
1401: void firePerspectiveOpened(IWorkbenchPage page,
1402: IPerspectiveDescriptor perspective) {
1403: UIListenerLogging.logPerspectiveEvent(this , page, perspective,
1404: UIListenerLogging.PLE_PERSP_OPENED);
1405: perspectiveListeners.firePerspectiveOpened(page, perspective);
1406: }
1407:
1408: /**
1409: * Fires perspective saved as.
1410: *
1411: * @since 3.1
1412: */
1413: void firePerspectiveSavedAs(IWorkbenchPage page,
1414: IPerspectiveDescriptor oldPerspective,
1415: IPerspectiveDescriptor newPerspective) {
1416: UIListenerLogging.logPerspectiveSavedAs(this , page,
1417: oldPerspective, newPerspective);
1418: perspectiveListeners.firePerspectiveSavedAs(page,
1419: oldPerspective, newPerspective);
1420: }
1421:
1422: /**
1423: * Returns the action bars for this window.
1424: */
1425: public WWinActionBars getActionBars() {
1426: if (actionBars == null) {
1427: actionBars = new WWinActionBars(this );
1428: }
1429: return actionBars;
1430: }
1431:
1432: /**
1433: * Returns the active page.
1434: *
1435: * @return the active page
1436: */
1437: public IWorkbenchPage getActivePage() {
1438: return pageList.getActive();
1439: }
1440:
1441: /**
1442: * Returns the active workbench page.
1443: *
1444: * @return the active workbench page
1445: */
1446: /* package */
1447: WorkbenchPage getActiveWorkbenchPage() {
1448: return pageList.getActive();
1449: }
1450:
1451: /**
1452: * Returns the page composite, under which the window's pages create their
1453: * controls.
1454: */
1455: protected Composite getPageComposite() {
1456: return pageComposite;
1457: }
1458:
1459: /**
1460: * Answer the menu manager for this window.
1461: */
1462: public MenuManager getMenuManager() {
1463: return getMenuBarManager();
1464: }
1465:
1466: /**
1467: * Returns the number. This corresponds to a page number in a window or a
1468: * window number in the workbench.
1469: */
1470: public int getNumber() {
1471: return number;
1472: }
1473:
1474: /**
1475: * Returns an array of the pages in the workbench window.
1476: *
1477: * @return an array of pages
1478: */
1479: public IWorkbenchPage[] getPages() {
1480: return pageList.getPages();
1481: }
1482:
1483: /**
1484: * @see IWorkbenchWindow
1485: */
1486: public IPartService getPartService() {
1487: return partService;
1488: }
1489:
1490: /**
1491: * Returns the layout for the shell.
1492: *
1493: * @return the layout for the shell
1494: */
1495: protected Layout getLayout() {
1496: return null;
1497: }
1498:
1499: /**
1500: * @see IWorkbenchWindow
1501: */
1502: public ISelectionService getSelectionService() {
1503: return partService.getSelectionService();
1504: }
1505:
1506: /**
1507: * Returns <code>true</code> when the window's shell is activated,
1508: * <code>false</code> when it's shell is deactivated
1509: *
1510: * @return boolean <code>true</code> when shell activated,
1511: * <code>false</code> when shell deactivated
1512: */
1513: public boolean getShellActivated() {
1514: return shellActivated;
1515: }
1516:
1517: /**
1518: * Returns the status line manager for this window (if it has one).
1519: *
1520: * @return the status line manager, or <code>null</code> if this window
1521: * does not have a status line
1522: * @see ApplicationWindow#addStatusLine
1523: */
1524: public StatusLineManager getStatusLineManager() {
1525: return super .getStatusLineManager();
1526: }
1527:
1528: private IWindowTrim getStatusLineTrim() {
1529: if (statusLineTrim == null) {
1530: statusLineTrim = new WindowTrimProxy(
1531: getStatusLineManager().getControl(),
1532: "org.eclipse.jface.action.StatusLineManager", //$NON-NLS-1$
1533: WorkbenchMessages.TrimCommon_StatusLine_TrimName,
1534: SWT.NONE, true);
1535: }
1536: return statusLineTrim;
1537: }
1538:
1539: /**
1540: * @see IWorkbenchWindow
1541: */
1542: public IWorkbench getWorkbench() {
1543: return PlatformUI.getWorkbench();
1544: }
1545:
1546: public String getToolbarLabel(String actionSetId) {
1547: ActionSetRegistry registry = WorkbenchPlugin.getDefault()
1548: .getActionSetRegistry();
1549: IActionSetDescriptor actionSet = registry
1550: .findActionSet(actionSetId);
1551: if (actionSet != null) {
1552: return actionSet.getLabel();
1553: }
1554:
1555: if (IWorkbenchActionConstants.TOOLBAR_FILE
1556: .equalsIgnoreCase(actionSetId)) {
1557: return WorkbenchMessages.WorkbenchWindow_FileToolbar;
1558: }
1559:
1560: if (IWorkbenchActionConstants.TOOLBAR_NAVIGATE
1561: .equalsIgnoreCase(actionSetId)) {
1562: return WorkbenchMessages.WorkbenchWindow_NavigateToolbar;
1563: }
1564:
1565: return null;
1566: }
1567:
1568: /**
1569: * Unconditionally close this window. Assumes the proper flags have been set
1570: * correctly (e.i. closing and updateDisabled)
1571: */
1572: private boolean hardClose() {
1573: boolean result;
1574: try {
1575: // Clear the action sets, fix for bug 27416.
1576: getActionPresentation().clearActionSets();
1577:
1578: // Remove the handler submissions. Bug 64024.
1579: final IWorkbench workbench = getWorkbench();
1580: final IHandlerService handlerService = (IHandlerService) workbench
1581: .getService(IHandlerService.class);
1582: handlerService.deactivateHandlers(handlerActivations);
1583: final Iterator activationItr = handlerActivations
1584: .iterator();
1585: while (activationItr.hasNext()) {
1586: final IHandlerActivation activation = (IHandlerActivation) activationItr
1587: .next();
1588: activation.getHandler().dispose();
1589: }
1590: handlerActivations.clear();
1591: globalActionHandlersByCommandId.clear();
1592:
1593: // Remove the enabled submissions. Bug 64024.
1594: final IContextService contextService = (IContextService) workbench
1595: .getService(IContextService.class);
1596: contextService.unregisterShell(getShell());
1597:
1598: closeAllPages();
1599:
1600: fireWindowClosed();
1601:
1602: // time to wipe our our populate
1603: IMenuService menuService = (IMenuService) workbench
1604: .getService(IMenuService.class);
1605: menuService
1606: .releaseContributions(((ContributionManager) getActionBars()
1607: .getMenuManager()));
1608: ICoolBarManager coolbar = getActionBars()
1609: .getCoolBarManager();
1610: if (coolbar != null) {
1611: menuService
1612: .releaseContributions(((ContributionManager) coolbar));
1613: }
1614:
1615: getActionBarAdvisor().dispose();
1616: getWindowAdvisor().dispose();
1617: detachedWindowShells.dispose();
1618:
1619: // Bring down all of the services.
1620: serviceLocator.dispose();
1621:
1622: // Null out the progress region. Bug 64024.
1623: progressRegion = null;
1624:
1625: // Remove drop targets
1626: DragUtil.removeDragTarget(null, trimDropTarget);
1627: DragUtil.removeDragTarget(getShell(), trimDropTarget);
1628: trimDropTarget = null;
1629:
1630: if (trimMgr2 != null) {
1631: trimMgr2.dispose();
1632: trimMgr2 = null;
1633: }
1634:
1635: if (trimContributionMgr != null) {
1636: trimContributionMgr.dispose();
1637: trimContributionMgr = null;
1638: }
1639: } finally {
1640: result = super .close();
1641: }
1642: return result;
1643: }
1644:
1645: /**
1646: * @see IWorkbenchWindow
1647: */
1648: public boolean isApplicationMenu(String menuID) {
1649: // delegate this question to the action bar advisor
1650: return getActionBarAdvisor().isApplicationMenu(menuID);
1651: }
1652:
1653: /**
1654: * Return whether or not the given id matches the id of the coolitems that
1655: * the application creates.
1656: */
1657: /* package */
1658: boolean isWorkbenchCoolItemId(String id) {
1659: return windowConfigurer.containsCoolItem(id);
1660: }
1661:
1662: /**
1663: * Locks/unlocks the CoolBar for the workbench.
1664: *
1665: * @param lock
1666: * whether the CoolBar should be locked or unlocked
1667: */
1668: /* package */
1669: void lockCoolBar(boolean lock) {
1670: getCoolBarManager2().setLockLayout(lock);
1671: }
1672:
1673: /**
1674: * Makes the window visible and frontmost.
1675: */
1676: void makeVisible() {
1677: Shell shell = getShell();
1678: if (shell != null && !shell.isDisposed()) {
1679: // see bug 96700 and bug 4414 for a discussion on the use of open()
1680: // here
1681: shell.open();
1682: }
1683: }
1684:
1685: /**
1686: * Called when this window is about to be closed.
1687: *
1688: * Subclasses may overide to add code that returns <code>false</code> to
1689: * prevent closing under certain conditions.
1690: */
1691: public boolean okToClose() {
1692: // Save all of the editors.
1693: if (!getWorkbenchImpl().isClosing()) {
1694: if (!saveAllPages(true)) {
1695: return false;
1696: }
1697: }
1698: return true;
1699: }
1700:
1701: /**
1702: * Opens a new page.
1703: * <p>
1704: * <b>Note:</b> Since release 2.0, a window is limited to contain at most
1705: * one page. If a page exist in the window when this method is used, then
1706: * another window is created for the new page. Callers are strongly
1707: * recommended to use the <code>IWorkbench.openPerspective</code> APIs to
1708: * programmatically show a perspective.
1709: * </p>
1710: */
1711: public IWorkbenchPage openPage(final String perspId,
1712: final IAdaptable input) throws WorkbenchException {
1713: Assert.isNotNull(perspId);
1714:
1715: // Run op in busy cursor.
1716: final Object[] result = new Object[1];
1717: BusyIndicator.showWhile(null, new Runnable() {
1718: public void run() {
1719: try {
1720: result[0] = busyOpenPage(perspId, input);
1721: } catch (WorkbenchException e) {
1722: result[0] = e;
1723: }
1724: }
1725: });
1726:
1727: if (result[0] instanceof IWorkbenchPage) {
1728: return (IWorkbenchPage) result[0];
1729: } else if (result[0] instanceof WorkbenchException) {
1730: throw (WorkbenchException) result[0];
1731: } else {
1732: throw new WorkbenchException(
1733: WorkbenchMessages.WorkbenchWindow_exceptionMessage);
1734: }
1735: }
1736:
1737: /**
1738: * Opens a new page.
1739: * <p>
1740: * <b>Note:</b> Since release 2.0, a window is limited to contain at most
1741: * one page. If a page exist in the window when this method is used, then
1742: * another window is created for the new page. Callers are strongly
1743: * recommended to use the <code>IWorkbench.openPerspective</code> APIs to
1744: * programmatically show a perspective.
1745: * </p>
1746: */
1747: public IWorkbenchPage openPage(IAdaptable input)
1748: throws WorkbenchException {
1749: String perspId = getWorkbenchImpl().getPerspectiveRegistry()
1750: .getDefaultPerspective();
1751: return openPage(perspId, input);
1752: }
1753:
1754: /*
1755: * Removes an listener from the part service.
1756: */
1757: public void removePageListener(IPageListener l) {
1758: pageListeners.removePageListener(l);
1759: }
1760:
1761: /**
1762: * @see org.eclipse.ui.IPageService
1763: */
1764: public void removePerspectiveListener(
1765: org.eclipse.ui.IPerspectiveListener l) {
1766: perspectiveListeners.removePerspectiveListener(l);
1767: }
1768:
1769: private IStatus unableToRestorePage(IMemento pageMem) {
1770: String pageName = pageMem
1771: .getString(IWorkbenchConstants.TAG_LABEL);
1772: if (pageName == null) {
1773: pageName = ""; //$NON-NLS-1$
1774: }
1775: return new Status(
1776: IStatus.ERROR,
1777: PlatformUI.PLUGIN_ID,
1778: 0,
1779: NLS
1780: .bind(
1781: WorkbenchMessages.WorkbenchWindow_unableToRestorePerspective,
1782: pageName), null);
1783: }
1784:
1785: public IStatus restoreState(IMemento memento,
1786: IPerspectiveDescriptor activeDescriptor) {
1787: Assert.isNotNull(getShell());
1788:
1789: final MultiStatus result = new MultiStatus(
1790: PlatformUI.PLUGIN_ID,
1791: IStatus.OK,
1792: WorkbenchMessages.WorkbenchWindow_problemsRestoringWindow,
1793: null);
1794:
1795: // Restore the window advisor state.
1796: IMemento windowAdvisorState = memento
1797: .getChild(IWorkbenchConstants.TAG_WORKBENCH_WINDOW_ADVISOR);
1798: if (windowAdvisorState != null) {
1799: result.add(getWindowAdvisor().restoreState(
1800: windowAdvisorState));
1801: }
1802:
1803: // Restore actionbar advisor state.
1804: IMemento actionBarAdvisorState = memento
1805: .getChild(IWorkbenchConstants.TAG_ACTION_BAR_ADVISOR);
1806: if (actionBarAdvisorState != null) {
1807: result.add(getActionBarAdvisor().restoreState(
1808: actionBarAdvisorState));
1809: }
1810:
1811: // Read window's bounds and state.
1812: final Rectangle[] displayBounds = new Rectangle[1];
1813: StartupThreading.runWithoutExceptions(new StartupRunnable() {
1814:
1815: public void runWithException() {
1816: displayBounds[0] = getShell().getDisplay().getBounds();
1817:
1818: }
1819: });
1820: final Rectangle shellBounds = new Rectangle(0, 0, 0, 0);
1821:
1822: final IMemento fastViewMem = memento
1823: .getChild(IWorkbenchConstants.TAG_FAST_VIEW_DATA);
1824: if (fastViewMem != null) {
1825: if (fastViewBar != null) {
1826: StartupThreading
1827: .runWithoutExceptions(new StartupRunnable() {
1828:
1829: public void runWithException() {
1830: fastViewBar.restoreState(fastViewMem);
1831: }
1832: });
1833:
1834: }
1835: }
1836: Integer bigInt = memento.getInteger(IWorkbenchConstants.TAG_X);
1837: shellBounds.x = bigInt == null ? 0 : bigInt.intValue();
1838: bigInt = memento.getInteger(IWorkbenchConstants.TAG_Y);
1839: shellBounds.y = bigInt == null ? 0 : bigInt.intValue();
1840: bigInt = memento.getInteger(IWorkbenchConstants.TAG_WIDTH);
1841: shellBounds.width = bigInt == null ? 0 : bigInt.intValue();
1842: bigInt = memento.getInteger(IWorkbenchConstants.TAG_HEIGHT);
1843: shellBounds.height = bigInt == null ? 0 : bigInt.intValue();
1844: if (!shellBounds.isEmpty()) {
1845: StartupThreading
1846: .runWithoutExceptions(new StartupRunnable() {
1847:
1848: public void runWithException() {
1849: if (!shellBounds
1850: .intersects(displayBounds[0])) {
1851: Rectangle clientArea = getShell()
1852: .getDisplay().getClientArea();
1853: shellBounds.x = clientArea.x;
1854: shellBounds.y = clientArea.y;
1855: }
1856: getShell().setBounds(shellBounds);
1857: }
1858: });
1859: }
1860: if ("true".equals(memento.getString(IWorkbenchConstants.TAG_MAXIMIZED))) { //$NON-NLS-1$
1861: StartupThreading
1862: .runWithoutExceptions(new StartupRunnable() {
1863:
1864: public void runWithException() {
1865: getShell().setMaximized(true);
1866: }
1867: });
1868:
1869: }
1870: if ("true".equals(memento.getString(IWorkbenchConstants.TAG_MINIMIZED))) { //$NON-NLS-1$
1871: // getShell().setMinimized(true);
1872: }
1873:
1874: // restore the width of the perspective bar
1875: if (perspectiveSwitcher != null) {
1876: perspectiveSwitcher.restoreState(memento);
1877: }
1878:
1879: // Restore the cool bar order by creating all the tool bar contribution
1880: // items
1881: // This needs to be done before pages are created to ensure proper
1882: // canonical creation
1883: // of cool items
1884: final ICoolBarManager2 coolBarMgr = (ICoolBarManager2) getCoolBarManager2();
1885: if (coolBarMgr != null) {
1886: IMemento coolBarMem = memento
1887: .getChild(IWorkbenchConstants.TAG_COOLBAR_LAYOUT);
1888: if (coolBarMem != null) {
1889: // Check if the layout is locked
1890: final Integer lockedInt = coolBarMem
1891: .getInteger(IWorkbenchConstants.TAG_LOCKED);
1892: StartupThreading
1893: .runWithoutExceptions(new StartupRunnable() {
1894:
1895: public void runWithException() {
1896: if ((lockedInt != null)
1897: && (lockedInt.intValue() == 1)) {
1898: coolBarMgr.setLockLayout(true);
1899: } else {
1900: coolBarMgr.setLockLayout(false);
1901: }
1902: }
1903: });
1904:
1905: // The new layout of the cool bar manager
1906: ArrayList coolBarLayout = new ArrayList();
1907: // Traverse through all the cool item in the memento
1908: IMemento contributionMems[] = coolBarMem
1909: .getChildren(IWorkbenchConstants.TAG_COOLITEM);
1910: for (int i = 0; i < contributionMems.length; i++) {
1911: IMemento contributionMem = contributionMems[i];
1912: String type = contributionMem
1913: .getString(IWorkbenchConstants.TAG_ITEM_TYPE);
1914: if (type == null) {
1915: // Do not recognize that type
1916: continue;
1917: }
1918: String id = contributionMem
1919: .getString(IWorkbenchConstants.TAG_ID);
1920:
1921: // Prevent duplicate items from being read back in.
1922: IContributionItem existingItem = coolBarMgr
1923: .find(id);
1924: if ((id != null) && (existingItem != null)) {
1925: if (Policy.DEBUG_TOOLBAR_DISPOSAL) {
1926: System.out
1927: .println("Not loading duplicate cool bar item: " + id); //$NON-NLS-1$
1928: }
1929: coolBarLayout.add(existingItem);
1930: continue;
1931: }
1932: IContributionItem newItem = null;
1933: if (type
1934: .equals(IWorkbenchConstants.TAG_TYPE_SEPARATOR)) {
1935: if (id != null) {
1936: newItem = new Separator(id);
1937: } else {
1938: newItem = new Separator();
1939: }
1940: } else if (id != null) {
1941: if (type
1942: .equals(IWorkbenchConstants.TAG_TYPE_GROUPMARKER)) {
1943: newItem = new GroupMarker(id);
1944:
1945: } else if (type
1946: .equals(IWorkbenchConstants.TAG_TYPE_TOOLBARCONTRIBUTION)
1947: || type
1948: .equals(IWorkbenchConstants.TAG_TYPE_PLACEHOLDER)) {
1949:
1950: // Get Width and height
1951: Integer width = contributionMem
1952: .getInteger(IWorkbenchConstants.TAG_ITEM_X);
1953: Integer height = contributionMem
1954: .getInteger(IWorkbenchConstants.TAG_ITEM_Y);
1955: // Look for the object in the current cool bar
1956: // manager
1957: IContributionItem oldItem = coolBarMgr
1958: .find(id);
1959: // If a tool bar contribution item already exists
1960: // for this id then use the old object
1961: if (oldItem != null) {
1962: newItem = oldItem;
1963: } else {
1964: IActionBarPresentationFactory actionBarPresentation = getActionBarPresentationFactory();
1965: newItem = actionBarPresentation
1966: .createToolBarContributionItem(
1967: actionBarPresentation
1968: .createToolBarManager(),
1969: id);
1970: if (type
1971: .equals(IWorkbenchConstants.TAG_TYPE_PLACEHOLDER)) {
1972: IToolBarContributionItem newToolBarItem = (IToolBarContributionItem) newItem;
1973: if (height != null) {
1974: newToolBarItem
1975: .setCurrentHeight(height
1976: .intValue());
1977: }
1978: if (width != null) {
1979: newToolBarItem
1980: .setCurrentWidth(width
1981: .intValue());
1982: }
1983: newItem = new PlaceholderContributionItem(
1984: newToolBarItem);
1985: }
1986: // make it invisible by default
1987: newItem.setVisible(false);
1988: // Need to add the item to the cool bar manager
1989: // so that its canonical order can be preserved
1990: IContributionItem refItem = findAlphabeticalOrder(
1991: IWorkbenchActionConstants.MB_ADDITIONS,
1992: id, coolBarMgr);
1993: if (refItem != null) {
1994: coolBarMgr.insertAfter(refItem
1995: .getId(), newItem);
1996: } else {
1997: coolBarMgr.add(newItem);
1998: }
1999: }
2000: // Set the current height and width
2001: if ((width != null)
2002: && (newItem instanceof IToolBarContributionItem)) {
2003: ((IToolBarContributionItem) newItem)
2004: .setCurrentWidth(width
2005: .intValue());
2006: }
2007: if ((height != null)
2008: && (newItem instanceof IToolBarContributionItem)) {
2009: ((IToolBarContributionItem) newItem)
2010: .setCurrentHeight(height
2011: .intValue());
2012: }
2013: }
2014: }
2015: // Add new item into cool bar manager
2016: if (newItem != null) {
2017: coolBarLayout.add(newItem);
2018: newItem.setParent(coolBarMgr);
2019: coolBarMgr.markDirty();
2020: }
2021: }
2022:
2023: // We need to check if we have everything we need in the layout.
2024: final ArrayList finalLayout = new ArrayList();
2025: IContributionItem[] existingItems = coolBarMgr
2026: .getItems();
2027: for (int i = 0; i < existingItems.length; i++) {
2028: IContributionItem existingItem = existingItems[i];
2029:
2030: /*
2031: * This line shouldn't be necessary, but is here for
2032: * robustness.
2033: */
2034: if (existingItem == null) {
2035: continue;
2036: }
2037:
2038: boolean found = false;
2039: Iterator layoutItemItr = coolBarLayout.iterator();
2040: while (layoutItemItr.hasNext()) {
2041: IContributionItem layoutItem = (IContributionItem) layoutItemItr
2042: .next();
2043: if ((layoutItem != null)
2044: && (layoutItem.equals(existingItem))) {
2045: found = true;
2046: break;
2047: }
2048: }
2049:
2050: if (!found) {
2051: if (existingItem != null) {
2052: finalLayout.add(existingItem);
2053: }
2054: }
2055: }
2056:
2057: // Set the cool bar layout to the given layout.
2058: finalLayout.addAll(coolBarLayout);
2059: final IContributionItem[] itemsToSet = new IContributionItem[finalLayout
2060: .size()];
2061: finalLayout.toArray(itemsToSet);
2062: StartupThreading
2063: .runWithoutExceptions(new StartupRunnable() {
2064:
2065: public void runWithException() {
2066: coolBarMgr.setItems(itemsToSet);
2067: }
2068: });
2069:
2070: } else {
2071: // For older workbenchs
2072: coolBarMem = memento
2073: .getChild(IWorkbenchConstants.TAG_TOOLBAR_LAYOUT);
2074: if (coolBarMem != null) {
2075: // Restore an older layout
2076: restoreOldCoolBar(coolBarMem);
2077: }
2078: }
2079: }
2080:
2081: // Recreate each page in the window.
2082: IWorkbenchPage newActivePage = null;
2083: IMemento[] pageArray = memento
2084: .getChildren(IWorkbenchConstants.TAG_PAGE);
2085: for (int i = 0; i < pageArray.length; i++) {
2086: final IMemento pageMem = pageArray[i];
2087: String strFocus = pageMem
2088: .getString(IWorkbenchConstants.TAG_FOCUS);
2089: if (strFocus == null || strFocus.length() == 0) {
2090: continue;
2091: }
2092:
2093: // Get the input factory.
2094: final IAdaptable[] input = new IAdaptable[1];
2095: final IMemento inputMem = pageMem
2096: .getChild(IWorkbenchConstants.TAG_INPUT);
2097: if (inputMem != null) {
2098: final String factoryID = inputMem
2099: .getString(IWorkbenchConstants.TAG_FACTORY_ID);
2100: if (factoryID == null) {
2101: WorkbenchPlugin
2102: .log("Unable to restore page - no input factory ID."); //$NON-NLS-1$
2103: result.add(unableToRestorePage(pageMem));
2104: continue;
2105: }
2106: try {
2107: UIStats.start(UIStats.RESTORE_WORKBENCH,
2108: "WorkbenchPageFactory"); //$NON-NLS-1$
2109: StartupThreading
2110: .runWithoutExceptions(new StartupRunnable() {
2111:
2112: public void runWithException()
2113: throws Throwable {
2114: IElementFactory factory = PlatformUI
2115: .getWorkbench()
2116: .getElementFactory(
2117: factoryID);
2118: if (factory == null) {
2119: WorkbenchPlugin
2120: .log("Unable to restore page - cannot instantiate input factory: " + factoryID); //$NON-NLS-1$
2121: result
2122: .add(unableToRestorePage(pageMem));
2123: return;
2124: }
2125:
2126: // Get the input element.
2127: input[0] = factory
2128: .createElement(inputMem);
2129: }
2130: });
2131:
2132: if (input[0] == null) {
2133: WorkbenchPlugin
2134: .log("Unable to restore page - cannot instantiate input element: " + factoryID); //$NON-NLS-1$
2135: result.add(unableToRestorePage(pageMem));
2136: continue;
2137: }
2138: } finally {
2139: UIStats.end(UIStats.RESTORE_WORKBENCH, factoryID,
2140: "WorkbenchPageFactory"); //$NON-NLS-1$
2141: }
2142: }
2143: // Open the perspective.
2144: final IAdaptable finalInput = input[0];
2145: final WorkbenchPage[] newPage = new WorkbenchPage[1];
2146: try {
2147: StartupThreading
2148: .runWithWorkbenchExceptions(new StartupRunnable() {
2149:
2150: public void runWithException()
2151: throws WorkbenchException {
2152: newPage[0] = new WorkbenchPage(
2153: WorkbenchWindow.this ,
2154: finalInput);
2155: }
2156: });
2157:
2158: result.add(newPage[0].restoreState(pageMem,
2159: activeDescriptor));
2160: pageList.add(newPage[0]);
2161: StartupThreading
2162: .runWithoutExceptions(new StartupRunnable() {
2163:
2164: public void runWithException()
2165: throws Throwable {
2166: firePageOpened(newPage[0]);
2167: }
2168: });
2169:
2170: } catch (WorkbenchException e) {
2171: WorkbenchPlugin
2172: .log(
2173: "Unable to restore perspective - constructor failed.", e); //$NON-NLS-1$
2174: result.add(e.getStatus());
2175: continue;
2176: }
2177:
2178: if (strFocus != null && strFocus.length() > 0) {
2179: newActivePage = newPage[0];
2180: }
2181: }
2182:
2183: // If there are no pages create a default.
2184: if (pageList.isEmpty()) {
2185: try {
2186: final String defPerspID = getWorkbenchImpl()
2187: .getPerspectiveRegistry()
2188: .getDefaultPerspective();
2189: if (defPerspID != null) {
2190: final WorkbenchPage[] newPage = new WorkbenchPage[1];
2191: StartupThreading
2192: .runWithWorkbenchExceptions(new StartupRunnable() {
2193:
2194: public void runWithException()
2195: throws Throwable {
2196: newPage[0] = new WorkbenchPage(
2197: WorkbenchWindow.this ,
2198: defPerspID,
2199: getDefaultPageInput());
2200: }
2201: });
2202:
2203: pageList.add(newPage[0]);
2204: StartupThreading
2205: .runWithoutExceptions(new StartupRunnable() {
2206:
2207: public void runWithException()
2208: throws Throwable {
2209: firePageOpened(newPage[0]);
2210: }
2211: });
2212: }
2213: } catch (WorkbenchException e) {
2214: WorkbenchPlugin
2215: .log(
2216: "Unable to create default perspective - constructor failed.", e); //$NON-NLS-1$
2217: result.add(e.getStatus());
2218: String productName = WorkbenchPlugin.getDefault()
2219: .getProductName();
2220: if (productName == null) {
2221: productName = ""; //$NON-NLS-1$
2222: }
2223: getShell().setText(productName);
2224: }
2225: }
2226:
2227: // Set active page.
2228: if (newActivePage == null) {
2229: newActivePage = pageList.getNextActive();
2230: }
2231: final IWorkbenchPage myPage = newActivePage;
2232: StartupThreading.runWithoutExceptions(new StartupRunnable() {
2233:
2234: public void runWithException() throws Throwable {
2235: setActivePage(myPage);
2236: }
2237: });
2238:
2239: final IMemento introMem = memento
2240: .getChild(IWorkbenchConstants.TAG_INTRO);
2241: if (introMem != null) {
2242: StartupThreading
2243: .runWithoutExceptions(new StartupRunnable() {
2244:
2245: public void runWithException() throws Throwable {
2246: getWorkbench()
2247: .getIntroManager()
2248: .showIntro(
2249: WorkbenchWindow.this ,
2250: Boolean
2251: .valueOf(
2252: introMem
2253: .getString(IWorkbenchConstants.TAG_STANDBY))
2254: .booleanValue());
2255: }
2256: });
2257:
2258: }
2259:
2260: // Only restore the trim state if we're using the default layout
2261: if (defaultLayout != null) {
2262: // Restore the trim state. We pass in the 'root'
2263: // memento since we have to check for pre-3.2
2264: // state.
2265: result.add(restoreTrimState(memento));
2266: }
2267:
2268: return result;
2269: }
2270:
2271: /**
2272: * Restores cool item order from an old workbench.
2273: */
2274: private boolean restoreOldCoolBar(IMemento coolbarMem) {
2275: // Make sure the tag exist
2276: if (coolbarMem == null) {
2277: return false;
2278: }
2279: ICoolBarManager2 coolBarMgr = (ICoolBarManager2) getCoolBarManager2();
2280: // Check to see if layout is locked
2281: Integer locked = coolbarMem
2282: .getInteger(IWorkbenchConstants.TAG_LOCKED);
2283: boolean state = (locked != null) && (locked.intValue() == 1);
2284: coolBarMgr.setLockLayout(state);
2285:
2286: // Get the visual layout
2287: IMemento visibleLayout = coolbarMem
2288: .getChild(IWorkbenchConstants.TAG_TOOLBAR_LAYOUT);
2289: ArrayList visibleWrapIndicies = new ArrayList();
2290: ArrayList visibleItems = new ArrayList();
2291: if (visibleLayout != null) {
2292: if (readLayout(visibleLayout, visibleItems,
2293: visibleWrapIndicies) == false) {
2294: return false;
2295: }
2296: }
2297: // Get the remembered layout
2298: IMemento rememberedLayout = coolbarMem
2299: .getChild(IWorkbenchConstants.TAG_LAYOUT);
2300: ArrayList rememberedWrapIndicies = new ArrayList();
2301: ArrayList rememberedItems = new ArrayList();
2302: if (rememberedLayout != null) {
2303: if (readLayout(rememberedLayout, rememberedItems,
2304: rememberedWrapIndicies) == false) {
2305: return false;
2306: }
2307: }
2308:
2309: // Create the objects
2310: if (visibleItems != null) {
2311: // Merge remembered layout into visible layout
2312: if (rememberedItems != null) {
2313: // Traverse through all the remembered items
2314: int currentIndex = 0;
2315: for (Iterator i = rememberedItems.iterator(); i
2316: .hasNext(); currentIndex++) {
2317: String id = (String) i.next();
2318: int index = -1;
2319: for (Iterator iter = visibleItems.iterator(); iter
2320: .hasNext();) {
2321: String visibleId = (String) iter.next();
2322: if (visibleId.equals(id)) {
2323: index = visibleItems.indexOf(visibleId);
2324: break;
2325: }
2326: }
2327: // The item is not in the visible list
2328: if (index == -1) {
2329: int insertAt = Math.max(0, Math.min(
2330: currentIndex, visibleItems.size()));
2331: boolean separateLine = false;
2332: // Check whether this item is on a separate line
2333: for (Iterator iter = rememberedWrapIndicies
2334: .iterator(); iter.hasNext();) {
2335: Integer wrapIndex = (Integer) iter.next();
2336: if (wrapIndex.intValue() <= insertAt) {
2337: insertAt = visibleItems.size();
2338: // Add new wrap index for this Item
2339: visibleWrapIndicies.add(new Integer(
2340: insertAt));
2341: separateLine = true;
2342: }
2343: }
2344: // Add item to array list
2345: visibleItems.add(insertAt, id);
2346: // If the item was not on a separate line then adjust
2347: // the visible wrap indicies
2348: if (!separateLine) {
2349: // Adjust visible wrap indicies
2350: for (int j = 0; j < visibleWrapIndicies
2351: .size(); j++) {
2352: Integer index2 = (Integer) visibleWrapIndicies
2353: .get(j);
2354: if (index2.intValue() >= insertAt) {
2355: visibleWrapIndicies.set(j,
2356: new Integer(index2
2357: .intValue() + 1));
2358: }
2359: }
2360: }
2361: }
2362: }
2363: }
2364: // The new layout of the cool bar manager
2365: ArrayList coolBarLayout = new ArrayList(visibleItems.size());
2366: // Add all visible items to the layout object
2367: for (Iterator i = visibleItems.iterator(); i.hasNext();) {
2368: String id = (String) i.next();
2369: // Look for the object in the current cool bar manager
2370: IContributionItem oldItem = null;
2371: IContributionItem newItem = null;
2372: if (id != null) {
2373: oldItem = coolBarMgr.find(id);
2374: }
2375: // If a tool bar contribution item already exists for this id
2376: // then use the old object
2377: if (oldItem instanceof IToolBarContributionItem) {
2378: newItem = oldItem;
2379: } else {
2380: IActionBarPresentationFactory actionBarPresentaiton = getActionBarPresentationFactory();
2381: newItem = actionBarPresentaiton
2382: .createToolBarContributionItem(
2383: actionBarPresentaiton
2384: .createToolBarManager(), id);
2385: // make it invisible by default
2386: newItem.setVisible(false);
2387: // Need to add the item to the cool bar manager so that its
2388: // canonical order can be preserved
2389: IContributionItem refItem = findAlphabeticalOrder(
2390: IWorkbenchActionConstants.MB_ADDITIONS, id,
2391: coolBarMgr);
2392: if (refItem != null) {
2393: coolBarMgr
2394: .insertAfter(refItem.getId(), newItem);
2395: } else {
2396: coolBarMgr.add(newItem);
2397: }
2398: }
2399: // Add new item into cool bar manager
2400: if (newItem != null) {
2401: coolBarLayout.add(newItem);
2402: newItem.setParent(coolBarMgr);
2403: coolBarMgr.markDirty();
2404: }
2405: }
2406:
2407: // Add separators to the displayed Items data structure
2408: int offset = 0;
2409: for (int i = 1; i < visibleWrapIndicies.size(); i++) {
2410: int insertAt = ((Integer) visibleWrapIndicies.get(i))
2411: .intValue()
2412: + offset;
2413: coolBarLayout.add(insertAt, new Separator(
2414: CoolBarManager.USER_SEPARATOR));
2415: offset++;
2416: }
2417:
2418: // Add any group markers in their appropriate places
2419: IContributionItem[] items = coolBarMgr.getItems();
2420: for (int i = 0; i < items.length; i++) {
2421: IContributionItem item = items[i];
2422: if (item.isGroupMarker()) {
2423: coolBarLayout.add(Math.max(Math.min(i,
2424: coolBarLayout.size()), 0), item);
2425: }
2426: }
2427: IContributionItem[] itemsToSet = new IContributionItem[coolBarLayout
2428: .size()];
2429: coolBarLayout.toArray(itemsToSet);
2430: coolBarMgr.setItems(itemsToSet);
2431: }
2432: return true;
2433: }
2434:
2435: /**
2436: * Helper method used for restoring an old cool bar layout. This method
2437: * reads the memento and populatates the item id's and wrap indicies.
2438: */
2439: private boolean readLayout(IMemento memento, ArrayList itemIds,
2440: ArrayList wrapIndicies) {
2441: // Get the Wrap indicies
2442: IMemento[] wraps = memento
2443: .getChildren(IWorkbenchConstants.TAG_ITEM_WRAP_INDEX);
2444: if (wraps == null) {
2445: return false;
2446: }
2447: for (int i = 0; i < wraps.length; i++) {
2448: IMemento wrapMem = wraps[i];
2449: Integer index = wrapMem
2450: .getInteger(IWorkbenchConstants.TAG_INDEX);
2451: if (index == null) {
2452: return false;
2453: }
2454: wrapIndicies.add(index);
2455: }
2456: // Get the Item ids
2457: IMemento[] savedItems = memento
2458: .getChildren(IWorkbenchConstants.TAG_ITEM);
2459: if (savedItems == null) {
2460: return false;
2461: }
2462: for (int i = 0; i < savedItems.length; i++) {
2463: IMemento savedMem = savedItems[i];
2464: String id = savedMem.getString(IWorkbenchConstants.TAG_ID);
2465: if (id == null) {
2466: return false;
2467: }
2468: itemIds.add(id);
2469: }
2470: return true;
2471: }
2472:
2473: /**
2474: * Returns the contribution item that the given contribution item should be
2475: * inserted after.
2476: *
2477: * @param startId
2478: * the location to start looking alphabetically.
2479: * @param itemId
2480: * the target item id.
2481: * @param mgr
2482: * the contribution manager.
2483: * @return the contribution item that the given items should be returned
2484: * after.
2485: */
2486: private IContributionItem findAlphabeticalOrder(String startId,
2487: String itemId, IContributionManager mgr) {
2488: IContributionItem[] items = mgr.getItems();
2489: int insertIndex = 0;
2490:
2491: // look for starting point
2492: while (insertIndex < items.length) {
2493: IContributionItem item = items[insertIndex];
2494: if (item.getId() != null && item.getId().equals(startId)) {
2495: break;
2496: }
2497: ++insertIndex;
2498: }
2499:
2500: // Find the index that this item should be inserted in
2501: for (int i = insertIndex + 1; i < items.length; i++) {
2502: IContributionItem item = items[i];
2503: String testId = item.getId();
2504:
2505: if (item.isGroupMarker()) {
2506: break;
2507: }
2508:
2509: if (itemId != null && testId != null) {
2510: if (itemId.compareTo(testId) < 1) {
2511: break;
2512: }
2513: }
2514: insertIndex = i;
2515: }
2516: if (insertIndex >= items.length) {
2517: return null;
2518: }
2519: return items[insertIndex];
2520: }
2521:
2522: /*
2523: * (non-Javadoc) Method declared on IRunnableContext.
2524: */
2525: public void run(boolean fork, boolean cancelable,
2526: IRunnableWithProgress runnable)
2527: throws InvocationTargetException, InterruptedException {
2528: IWorkbenchContextSupport contextSupport = getWorkbench()
2529: .getContextSupport();
2530: final boolean keyFilterEnabled = contextSupport
2531: .isKeyFilterEnabled();
2532:
2533: Control fastViewBarControl = getFastViewBar() == null ? null
2534: : getFastViewBar().getControl();
2535: boolean fastViewBarWasEnabled = fastViewBarControl == null ? false
2536: : fastViewBarControl.getEnabled();
2537:
2538: Control perspectiveBarControl = getPerspectiveBar() == null ? null
2539: : getPerspectiveBar().getControl();
2540: boolean perspectiveBarWasEnabled = perspectiveBarControl == null ? false
2541: : perspectiveBarControl.getEnabled();
2542:
2543: // Cache for any diabled trim controls
2544: List disabledControls = null;
2545:
2546: try {
2547: if (fastViewBarControl != null
2548: && !fastViewBarControl.isDisposed()) {
2549: fastViewBarControl.setEnabled(false);
2550: }
2551:
2552: if (perspectiveBarControl != null
2553: && !perspectiveBarControl.isDisposed()) {
2554: perspectiveBarControl.setEnabled(false);
2555: }
2556:
2557: if (keyFilterEnabled) {
2558: contextSupport.setKeyFilterEnabled(false);
2559: }
2560:
2561: // Disable all trim -except- the StatusLine
2562: if (defaultLayout != null)
2563: disabledControls = defaultLayout
2564: .disableTrim(getStatusLineTrim());
2565:
2566: super .run(fork, cancelable, runnable);
2567: } finally {
2568: if (fastViewBarControl != null
2569: && !fastViewBarControl.isDisposed()) {
2570: fastViewBarControl.setEnabled(fastViewBarWasEnabled);
2571: }
2572:
2573: if (perspectiveBarControl != null
2574: && !perspectiveBarControl.isDisposed()) {
2575: perspectiveBarControl
2576: .setEnabled(perspectiveBarWasEnabled);
2577: }
2578:
2579: if (keyFilterEnabled) {
2580: contextSupport.setKeyFilterEnabled(true);
2581: }
2582:
2583: // Re-enable any disabled trim
2584: if (defaultLayout != null && disabledControls != null)
2585: defaultLayout.enableTrim(disabledControls);
2586: }
2587: }
2588:
2589: /**
2590: * Save all of the pages. Returns true if the operation succeeded.
2591: */
2592: private boolean saveAllPages(boolean bConfirm) {
2593: boolean bRet = true;
2594: Iterator itr = pageList.iterator();
2595: while (bRet && itr.hasNext()) {
2596: WorkbenchPage page = (WorkbenchPage) itr.next();
2597: bRet = page.saveAllEditors(bConfirm);
2598: }
2599: return bRet;
2600: }
2601:
2602: /**
2603: * @see IPersistable
2604: */
2605: public IStatus saveState(IMemento memento) {
2606:
2607: MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID,
2608: IStatus.OK,
2609: WorkbenchMessages.WorkbenchWindow_problemsSavingWindow,
2610: null);
2611:
2612: // Save the window's state and bounds.
2613: if (getShell().getMaximized() || asMaximizedState) {
2614: memento
2615: .putString(IWorkbenchConstants.TAG_MAXIMIZED,
2616: "true"); //$NON-NLS-1$
2617: }
2618: if (getShell().getMinimized()) {
2619: memento
2620: .putString(IWorkbenchConstants.TAG_MINIMIZED,
2621: "true"); //$NON-NLS-1$
2622: }
2623: if (normalBounds == null) {
2624: normalBounds = getShell().getBounds();
2625: }
2626: IMemento fastViewBarMem = memento
2627: .createChild(IWorkbenchConstants.TAG_FAST_VIEW_DATA);
2628: if (fastViewBar != null) {
2629: fastViewBar.saveState(fastViewBarMem);
2630: }
2631:
2632: memento.putInteger(IWorkbenchConstants.TAG_X, normalBounds.x);
2633: memento.putInteger(IWorkbenchConstants.TAG_Y, normalBounds.y);
2634: memento.putInteger(IWorkbenchConstants.TAG_WIDTH,
2635: normalBounds.width);
2636: memento.putInteger(IWorkbenchConstants.TAG_HEIGHT,
2637: normalBounds.height);
2638:
2639: IWorkbenchPage activePage = getActivePage();
2640: if (activePage != null
2641: && activePage.findView(IIntroConstants.INTRO_VIEW_ID) != null) {
2642: IMemento introMem = memento
2643: .createChild(IWorkbenchConstants.TAG_INTRO);
2644: boolean isStandby = getWorkbench()
2645: .getIntroManager()
2646: .isIntroStandby(
2647: getWorkbench().getIntroManager().getIntro());
2648: introMem.putString(IWorkbenchConstants.TAG_STANDBY, String
2649: .valueOf(isStandby));
2650: }
2651:
2652: // save the width of the perspective bar
2653: IMemento persBarMem = memento
2654: .createChild(IWorkbenchConstants.TAG_PERSPECTIVE_BAR);
2655: if (perspectiveSwitcher != null) {
2656: perspectiveSwitcher.saveState(persBarMem);
2657: }
2658:
2659: // / Save the order of the cool bar contribution items
2660: ICoolBarManager2 coolBarMgr = (ICoolBarManager2) getCoolBarManager2();
2661: if (coolBarMgr != null) {
2662: coolBarMgr.refresh();
2663: IMemento coolBarMem = memento
2664: .createChild(IWorkbenchConstants.TAG_COOLBAR_LAYOUT);
2665: if (coolBarMgr.getLockLayout() == true) {
2666: coolBarMem
2667: .putInteger(IWorkbenchConstants.TAG_LOCKED, 1);
2668: } else {
2669: coolBarMem
2670: .putInteger(IWorkbenchConstants.TAG_LOCKED, 0);
2671: }
2672: IContributionItem[] items = coolBarMgr.getItems();
2673: for (int i = 0; i < items.length; i++) {
2674: IMemento coolItemMem = coolBarMem
2675: .createChild(IWorkbenchConstants.TAG_COOLITEM);
2676: IContributionItem item = items[i];
2677: // The id of the contribution item
2678: if (item.getId() != null) {
2679: coolItemMem.putString(IWorkbenchConstants.TAG_ID,
2680: item.getId());
2681: }
2682: // Write out type and size if applicable
2683: if (item.isSeparator()) {
2684: coolItemMem.putString(
2685: IWorkbenchConstants.TAG_ITEM_TYPE,
2686: IWorkbenchConstants.TAG_TYPE_SEPARATOR);
2687: } else if (item.isGroupMarker() && !item.isSeparator()) {
2688: coolItemMem.putString(
2689: IWorkbenchConstants.TAG_ITEM_TYPE,
2690: IWorkbenchConstants.TAG_TYPE_GROUPMARKER);
2691: } else {
2692: if (item instanceof PlaceholderContributionItem) {
2693: coolItemMem
2694: .putString(
2695: IWorkbenchConstants.TAG_ITEM_TYPE,
2696: IWorkbenchConstants.TAG_TYPE_PLACEHOLDER);
2697: } else {
2698: // Store the identifier.
2699: coolItemMem
2700: .putString(
2701: IWorkbenchConstants.TAG_ITEM_TYPE,
2702: IWorkbenchConstants.TAG_TYPE_TOOLBARCONTRIBUTION);
2703: }
2704:
2705: /*
2706: * Retrieve a reasonable approximation of the height and
2707: * width, if possible.
2708: */
2709: final int height;
2710: final int width;
2711: if (item instanceof IToolBarContributionItem) {
2712: IToolBarContributionItem toolBarItem = (IToolBarContributionItem) item;
2713: toolBarItem.saveWidgetState();
2714: height = toolBarItem.getCurrentHeight();
2715: width = toolBarItem.getCurrentWidth();
2716: } else if (item instanceof PlaceholderContributionItem) {
2717: PlaceholderContributionItem placeholder = (PlaceholderContributionItem) item;
2718: height = placeholder.getHeight();
2719: width = placeholder.getWidth();
2720: } else {
2721: height = -1;
2722: width = -1;
2723: }
2724:
2725: // Store the height and width.
2726: coolItemMem.putInteger(
2727: IWorkbenchConstants.TAG_ITEM_X, width);
2728: coolItemMem.putInteger(
2729: IWorkbenchConstants.TAG_ITEM_Y, height);
2730: }
2731: }
2732: }
2733:
2734: // Save each page.
2735: Iterator itr = pageList.iterator();
2736: while (itr.hasNext()) {
2737: WorkbenchPage page = (WorkbenchPage) itr.next();
2738:
2739: // Save perspective.
2740: IMemento pageMem = memento
2741: .createChild(IWorkbenchConstants.TAG_PAGE);
2742: pageMem.putString(IWorkbenchConstants.TAG_LABEL, page
2743: .getLabel());
2744: result.add(page.saveState(pageMem));
2745:
2746: if (page == getActiveWorkbenchPage()) {
2747: pageMem
2748: .putString(IWorkbenchConstants.TAG_FOCUS,
2749: "true"); //$NON-NLS-1$
2750: }
2751:
2752: // Get the input.
2753: IAdaptable input = page.getInput();
2754: if (input != null) {
2755: IPersistableElement persistable = (IPersistableElement) Util
2756: .getAdapter(input, IPersistableElement.class);
2757: if (persistable == null) {
2758: WorkbenchPlugin
2759: .log("Unable to save page input: " //$NON-NLS-1$
2760: + input
2761: + ", because it does not adapt to IPersistableElement"); //$NON-NLS-1$
2762: } else {
2763: // Save input.
2764: IMemento inputMem = pageMem
2765: .createChild(IWorkbenchConstants.TAG_INPUT);
2766: inputMem.putString(
2767: IWorkbenchConstants.TAG_FACTORY_ID,
2768: persistable.getFactoryId());
2769: persistable.saveState(inputMem);
2770: }
2771: }
2772: }
2773:
2774: // Save window advisor state.
2775: IMemento windowAdvisorState = memento
2776: .createChild(IWorkbenchConstants.TAG_WORKBENCH_WINDOW_ADVISOR);
2777: result.add(getWindowAdvisor().saveState(windowAdvisorState));
2778:
2779: // Save actionbar advisor state.
2780: IMemento actionBarAdvisorState = memento
2781: .createChild(IWorkbenchConstants.TAG_ACTION_BAR_ADVISOR);
2782: result.add(getActionBarAdvisor().saveState(
2783: actionBarAdvisorState));
2784:
2785: // Only save the trim state if we're using the default layout
2786: if (defaultLayout != null) {
2787: IMemento trimState = memento
2788: .createChild(IWorkbenchConstants.TAG_TRIM);
2789: result.add(saveTrimState(trimState));
2790: }
2791:
2792: return result;
2793: }
2794:
2795: /**
2796: * Save the trim layout trim area and trim ordering.
2797: *
2798: * @param memento
2799: * the memento to update
2800: * @return the status, OK or not..
2801: * @since 3.2
2802: */
2803: private IStatus saveTrimState(IMemento memento) {
2804: int[] ids = defaultLayout.getAreaIds();
2805: for (int i = 0; i < ids.length; i++) {
2806: int id = ids[i];
2807: List trim = defaultLayout.getAreaTrim(id);
2808: if (!trim.isEmpty()) {
2809: IMemento area = memento.createChild(
2810: IWorkbenchConstants.TAG_TRIM_AREA, Integer
2811: .toString(id));
2812: Iterator d = trim.iterator();
2813: while (d.hasNext()) {
2814: IWindowTrim item = (IWindowTrim) d.next();
2815: area.createChild(IWorkbenchConstants.TAG_TRIM_ITEM,
2816: item.getId());
2817: }
2818: }
2819: }
2820: return Status.OK_STATUS;
2821: }
2822:
2823: /**
2824: * Restore the trim layout state from the memento.
2825: *
2826: * @param memento
2827: * the 'root' Workbench memento to restore
2828: * @return the status, OK or not
2829: * @since 3.2
2830: */
2831: private IStatus restoreTrimState(IMemento memento) {
2832: // Determine if we have saved state. If we don't have any 3.2
2833: // type state we're not done because the FastViewBar maintained
2834: // its own 'side' state in 3.1 so we'll honor its value
2835: IMemento trimState = memento
2836: .getChild(IWorkbenchConstants.TAG_TRIM);
2837: if (trimState != null) {
2838: // first pass sets up ordering for all trim areas
2839: IMemento[] areas = trimState
2840: .getChildren(IWorkbenchConstants.TAG_TRIM_AREA);
2841:
2842: // We need to remember all the trim that was repositioned
2843: // here so we can re-site -newly contributed- trim after
2844: // we're done
2845: final List knownIds = new ArrayList();
2846:
2847: List[] trimOrder = new List[areas.length];
2848: for (int i = 0; i < areas.length; i++) {
2849: trimOrder[i] = new ArrayList();
2850: List preferredLocations = new ArrayList();
2851: IMemento area = areas[i];
2852: IMemento[] items = area
2853: .getChildren(IWorkbenchConstants.TAG_TRIM_ITEM);
2854: for (int j = 0; j < items.length; j++) {
2855: IMemento item = items[j];
2856: String id = item.getID();
2857: knownIds.add(id);
2858: preferredLocations.add(id);
2859:
2860: IWindowTrim t = defaultLayout.getTrim(id);
2861: if (t != null) {
2862: trimOrder[i].add(t);
2863: }
2864: }
2865:
2866: // Inform the TrimLayout of the preferred location for this area
2867: String areaIdString = areas[i].getID();
2868: int areaId = Integer.parseInt(areaIdString);
2869: defaultLayout.setPreferredLocations(areaId,
2870: preferredLocations);
2871: }
2872:
2873: // second pass applies all of the window trim
2874: for (int i = 0; i < areas.length; i++) {
2875: IMemento area = areas[i];
2876: final int id = Integer.parseInt(area.getID());
2877: final List myTrimOrderList = trimOrder[i];
2878: StartupThreading
2879: .runWithoutExceptions(new StartupRunnable() {
2880:
2881: public void runWithException()
2882: throws Throwable {
2883: defaultLayout.updateAreaTrim(id,
2884: myTrimOrderList, false);
2885: }
2886: });
2887:
2888: }
2889:
2890: // get the trim manager to re-locate any -newly contributed-
2891: // trim widgets
2892: // Legacy (3.2) trim
2893: if (trimMgr2 != null) {
2894: StartupThreading
2895: .runWithoutExceptions(new StartupRunnable() {
2896:
2897: public void runWithException()
2898: throws Throwable {
2899: trimMgr2.updateLocations(knownIds);
2900: }
2901: });
2902:
2903: }
2904:
2905: // 3.3 Trim Contributions
2906: if (trimContributionMgr != null) {
2907: StartupThreading
2908: .runWithoutExceptions(new StartupRunnable() {
2909: public void runWithException()
2910: throws Throwable {
2911: trimContributionMgr
2912: .updateLocations(knownIds);
2913:
2914: // Update the GUI with the new locations
2915: WorkbenchPage page = getActiveWorkbenchPage();
2916: if (page != null) {
2917: Perspective perspective = page
2918: .getActivePerspective();
2919: if (perspective != null) {
2920: // Ensure that only the upper/right editor stack has
2921: // min/max buttons
2922: page.getEditorPresentation()
2923: .updateStackButtons();
2924:
2925: // The perspective's onActivate manipulates the trim under the
2926: // new min/max story so cause it to refresh...
2927: perspective.onActivate();
2928: }
2929: }
2930: }
2931: });
2932: }
2933: } else {
2934: // No 3.2 state...check if the FVB has state
2935: IMemento fastViewMem = memento
2936: .getChild(IWorkbenchConstants.TAG_FAST_VIEW_DATA);
2937: if (fastViewMem != null) {
2938: if (fastViewBar != null) {
2939: final Integer bigInt = fastViewMem
2940: .getInteger(IWorkbenchConstants.TAG_FAST_VIEW_SIDE);
2941: if (bigInt != null) {
2942: StartupThreading
2943: .runWithoutExceptions(new StartupRunnable() {
2944:
2945: public void runWithException()
2946: throws Throwable {
2947: fastViewBar.dock(bigInt
2948: .intValue());
2949: getTrimManager().addTrim(
2950: bigInt.intValue(),
2951: fastViewBar);
2952: }
2953: });
2954:
2955: }
2956: }
2957: }
2958: }
2959:
2960: return Status.OK_STATUS;
2961: }
2962:
2963: /**
2964: * Sets the active page within the window.
2965: *
2966: * @param in
2967: * identifies the new active page, or <code>null</code> for no
2968: * active page
2969: */
2970: public void setActivePage(final IWorkbenchPage in) {
2971: if (getActiveWorkbenchPage() == in) {
2972: return;
2973: }
2974:
2975: // 1FVGTNR: ITPUI:WINNT - busy cursor for switching perspectives
2976: BusyIndicator.showWhile(getShell().getDisplay(),
2977: new Runnable() {
2978: public void run() {
2979: // Deactivate old persp.
2980: WorkbenchPage currentPage = getActiveWorkbenchPage();
2981: if (currentPage != null) {
2982: currentPage.onDeactivate();
2983: }
2984:
2985: // Activate new persp.
2986: if (in == null || pageList.contains(in)) {
2987: pageList.setActive(in);
2988: }
2989: WorkbenchPage newPage = pageList.getActive();
2990: Composite parent = getPageComposite();
2991: StackLayout layout = (StackLayout) parent
2992: .getLayout();
2993: if (newPage != null) {
2994: layout.topControl = newPage
2995: .getClientComposite();
2996: parent.layout();
2997: hideEmptyWindowContents();
2998: newPage.onActivate();
2999: firePageActivated(newPage);
3000: if (newPage.getPerspective() != null) {
3001: firePerspectiveActivated(newPage,
3002: newPage.getPerspective());
3003: }
3004: } else {
3005: layout.topControl = null;
3006: parent.layout();
3007: }
3008:
3009: updateFastViewBar();
3010:
3011: if (isClosing()) {
3012: return;
3013: }
3014:
3015: updateDisabled = false;
3016:
3017: // Update action bars ( implicitly calls updateActionBars() )
3018: updateActionSets();
3019: submitGlobalActions();
3020:
3021: if (perspectiveSwitcher != null) {
3022: perspectiveSwitcher.update(false);
3023: }
3024:
3025: getMenuManager().update(IAction.TEXT);
3026: }
3027: });
3028: }
3029:
3030: /**
3031: * Returns whether or not children exist for the Window's toolbar control.
3032: * Overridden for coolbar support.
3033: * <p>
3034: *
3035: * @return boolean true if children exist, false otherwise
3036: */
3037: protected boolean toolBarChildrenExist() {
3038: CoolBar coolBarControl = (CoolBar) getCoolBarControl();
3039: return coolBarControl.getItemCount() > 0;
3040: }
3041:
3042: /**
3043: * Hooks a listener to track the activation and deactivation of the window's
3044: * shell. Notifies the active part and editor of the change
3045: */
3046: private void trackShellActivation(Shell shell) {
3047: shell.addShellListener(new ShellAdapter() {
3048: public void shellActivated(ShellEvent event) {
3049: shellActivated = true;
3050: serviceLocator.activate();
3051: getWorkbenchImpl().setActivatedWindow(
3052: WorkbenchWindow.this );
3053: WorkbenchPage currentPage = getActiveWorkbenchPage();
3054: if (currentPage != null) {
3055: IWorkbenchPart part = currentPage.getActivePart();
3056: if (part != null) {
3057: PartSite site = (PartSite) part.getSite();
3058: site.getPane().shellActivated();
3059: }
3060: IEditorPart editor = currentPage.getActiveEditor();
3061: if (editor != null) {
3062: PartSite site = (PartSite) editor.getSite();
3063: site.getPane().shellActivated();
3064: }
3065: getWorkbenchImpl().fireWindowActivated(
3066: WorkbenchWindow.this );
3067: }
3068: }
3069:
3070: public void shellDeactivated(ShellEvent event) {
3071: shellActivated = false;
3072: serviceLocator.deactivate();
3073: WorkbenchPage currentPage = getActiveWorkbenchPage();
3074: if (currentPage != null) {
3075: IWorkbenchPart part = currentPage.getActivePart();
3076: if (part != null) {
3077: PartSite site = (PartSite) part.getSite();
3078: site.getPane().shellDeactivated();
3079: }
3080: IEditorPart editor = currentPage.getActiveEditor();
3081: if (editor != null) {
3082: PartSite site = (PartSite) editor.getSite();
3083: site.getPane().shellDeactivated();
3084: }
3085: getWorkbenchImpl().fireWindowDeactivated(
3086: WorkbenchWindow.this );
3087: }
3088: }
3089: });
3090: }
3091:
3092: /**
3093: * Hooks a listener to track the resize of the window's shell. Stores the
3094: * new bounds if in normal state - that is, not in minimized or maximized
3095: * state)
3096: */
3097: private void trackShellResize(Shell newShell) {
3098: newShell.addControlListener(new ControlAdapter() {
3099: public void controlMoved(ControlEvent e) {
3100: saveBounds();
3101: }
3102:
3103: public void controlResized(ControlEvent e) {
3104: saveBounds();
3105: }
3106:
3107: private void saveBounds() {
3108: Shell shell = getShell();
3109: if (shell == null) {
3110: return;
3111: }
3112: if (shell.isDisposed()) {
3113: return;
3114: }
3115: if (shell.getMinimized()) {
3116: return;
3117: }
3118: if (shell.getMaximized()) {
3119: asMaximizedState = true;
3120: return;
3121: }
3122: asMaximizedState = false;
3123: normalBounds = shell.getBounds();
3124: }
3125: });
3126: }
3127:
3128: /**
3129: * update the action bars.
3130: */
3131: public void updateActionBars() {
3132: if (updateDisabled || updatesDeferred()) {
3133: return;
3134: }
3135: // updateAll required in order to enable accelerators on pull-down menus
3136: getMenuBarManager().update(false);
3137:
3138: try {
3139: getShell().setLayoutDeferred(true);
3140: getCoolBarManager2().update(false);
3141: } finally {
3142: getShell().setLayoutDeferred(false);
3143: }
3144:
3145: getStatusLineManager().update(false);
3146: }
3147:
3148: /**
3149: * Returns true iff we are currently deferring UI processing due to a large
3150: * update
3151: *
3152: * @return true iff we are deferring UI updates.
3153: * @since 3.1
3154: */
3155: private boolean updatesDeferred() {
3156: return largeUpdates > 0;
3157: }
3158:
3159: /**
3160: * <p>
3161: * Indicates the start of a large update within this window. This is used to
3162: * disable CPU-intensive, change-sensitive services that were temporarily
3163: * disabled in the midst of large changes. This method should always be
3164: * called in tandem with <code>largeUpdateEnd</code>, and the event loop
3165: * should not be allowed to spin before that method is called.
3166: * </p>
3167: * <p>
3168: * Important: always use with <code>largeUpdateEnd</code>!
3169: * </p>
3170: *
3171: * @since 3.1
3172: */
3173: public final void largeUpdateStart() {
3174: largeUpdates++;
3175: }
3176:
3177: /**
3178: * <p>
3179: * Indicates the end of a large update within this window. This is used to
3180: * re-enable services that were temporarily disabled in the midst of large
3181: * changes. This method should always be called in tandem with
3182: * <code>largeUpdateStart</code>, and the event loop should not be
3183: * allowed to spin before this method is called.
3184: * </p>
3185: * <p>
3186: * Important: always protect this call by using <code>finally</code>!
3187: * </p>
3188: *
3189: * @since 3.1
3190: */
3191: public final void largeUpdateEnd() {
3192: if (--largeUpdates == 0) {
3193: updateActionBars();
3194: }
3195: }
3196:
3197: /**
3198: * Update the visible action sets. This method is typically called from a
3199: * page when the user changes the visible action sets within the
3200: * prespective.
3201: */
3202: public void updateActionSets() {
3203: if (updateDisabled) {
3204: return;
3205: }
3206:
3207: WorkbenchPage currentPage = getActiveWorkbenchPage();
3208: if (currentPage == null) {
3209: getActionPresentation().clearActionSets();
3210: } else {
3211: ICoolBarManager2 coolBarManager = (ICoolBarManager2) getCoolBarManager2();
3212: if (coolBarManager != null) {
3213: coolBarManager.refresh();
3214: }
3215: getActionPresentation().setActionSets(
3216: currentPage.getActionSets());
3217: }
3218: fireActionSetsChanged();
3219: updateActionBars();
3220:
3221: // hide the launch menu if it is empty
3222: String path = IWorkbenchActionConstants.M_WINDOW
3223: + IWorkbenchActionConstants.SEP
3224: + IWorkbenchActionConstants.M_LAUNCH;
3225: IMenuManager manager = getMenuBarManager().findMenuUsingPath(
3226: path);
3227: IContributionItem item = getMenuBarManager()
3228: .findUsingPath(path);
3229:
3230: if (manager == null || item == null) {
3231: return;
3232: }
3233: item.setVisible(manager.getItems().length >= 2);
3234: // there is a separator for the additions group thus >= 2
3235: }
3236:
3237: private ListenerList actionSetListeners = null;
3238:
3239: private ListenerList backgroundSaveListeners = new ListenerList(
3240: ListenerList.IDENTITY);
3241:
3242: private final void fireActionSetsChanged() {
3243: if (actionSetListeners != null) {
3244: final Object[] listeners = actionSetListeners
3245: .getListeners();
3246: for (int i = 0; i < listeners.length; i++) {
3247: final IActionSetsListener listener = (IActionSetsListener) listeners[i];
3248: final WorkbenchPage currentPage = getActiveWorkbenchPage();
3249: final IActionSetDescriptor[] newActionSets;
3250: if (currentPage == null) {
3251: newActionSets = null;
3252: } else {
3253: newActionSets = currentPage.getActionSets();
3254: }
3255: final ActionSetsEvent event = new ActionSetsEvent(
3256: newActionSets);
3257: listener.actionSetsChanged(event);
3258: }
3259: }
3260: }
3261:
3262: final void addActionSetsListener(final IActionSetsListener listener) {
3263: if (actionSetListeners == null) {
3264: actionSetListeners = new ListenerList();
3265: }
3266:
3267: actionSetListeners.add(listener);
3268: }
3269:
3270: final void removeActionSetsListener(
3271: final IActionSetsListener listener) {
3272: if (actionSetListeners != null) {
3273: actionSetListeners.remove(listener);
3274: if (actionSetListeners.isEmpty()) {
3275: actionSetListeners = null;
3276: }
3277: }
3278: }
3279:
3280: /**
3281: * Create the progress indicator for the receiver.
3282: *
3283: * @param shell
3284: * the parent shell
3285: */
3286: private void createProgressIndicator(Shell shell) {
3287: if (getWindowConfigurer().getShowProgressIndicator()) {
3288: progressRegion = new ProgressRegion();
3289: progressRegion.createContents(shell, this );
3290: }
3291:
3292: }
3293:
3294: class PageList {
3295: // List of pages in the order they were created;
3296: private List pagesInCreationOrder;
3297:
3298: // List of pages where the top is the last activated.
3299: private List pageInActivationOrder;
3300:
3301: // The page explicitly activated
3302: private Object active;
3303:
3304: public PageList() {
3305: pagesInCreationOrder = new ArrayList(4);
3306: pageInActivationOrder = new ArrayList(4);
3307: }
3308:
3309: public boolean add(Object object) {
3310: pagesInCreationOrder.add(object);
3311: pageInActivationOrder.add(0, object);
3312: // It will be moved to top only when activated.
3313: return true;
3314: }
3315:
3316: public Iterator iterator() {
3317: return pagesInCreationOrder.iterator();
3318: }
3319:
3320: public boolean contains(Object object) {
3321: return pagesInCreationOrder.contains(object);
3322: }
3323:
3324: public boolean remove(Object object) {
3325: if (active == object) {
3326: active = null;
3327: }
3328: pageInActivationOrder.remove(object);
3329: return pagesInCreationOrder.remove(object);
3330: }
3331:
3332: public boolean isEmpty() {
3333: return pagesInCreationOrder.isEmpty();
3334: }
3335:
3336: public IWorkbenchPage[] getPages() {
3337: int nSize = pagesInCreationOrder.size();
3338: IWorkbenchPage[] retArray = new IWorkbenchPage[nSize];
3339: pagesInCreationOrder.toArray(retArray);
3340: return retArray;
3341: }
3342:
3343: public void setActive(Object page) {
3344: if (active == page) {
3345: return;
3346: }
3347:
3348: active = page;
3349:
3350: if (page != null) {
3351: pageInActivationOrder.remove(page);
3352: pageInActivationOrder.add(page);
3353: }
3354: }
3355:
3356: public WorkbenchPage getActive() {
3357: return (WorkbenchPage) active;
3358: }
3359:
3360: public WorkbenchPage getNextActive() {
3361: if (active == null) {
3362: if (pageInActivationOrder.isEmpty()) {
3363: return null;
3364: }
3365:
3366: return (WorkbenchPage) pageInActivationOrder
3367: .get(pageInActivationOrder.size() - 1);
3368: }
3369:
3370: if (pageInActivationOrder.size() < 2) {
3371: return null;
3372: }
3373:
3374: return (WorkbenchPage) pageInActivationOrder
3375: .get(pageInActivationOrder.size() - 2);
3376: }
3377: }
3378:
3379: /**
3380: * Returns the unique object that applications use to configure this window.
3381: * <p>
3382: * IMPORTANT This method is declared package-private to prevent regular
3383: * plug-ins from downcasting IWorkbenchWindow to WorkbenchWindow and getting
3384: * hold of the workbench window configurer that would allow them to tamper
3385: * with the workbench window. The workbench window configurer is available
3386: * only to the application.
3387: * </p>
3388: */
3389: /* package - DO NOT CHANGE */
3390: WorkbenchWindowConfigurer getWindowConfigurer() {
3391: if (windowConfigurer == null) {
3392: // lazy initialize
3393: windowConfigurer = new WorkbenchWindowConfigurer(this );
3394: }
3395: return windowConfigurer;
3396: }
3397:
3398: /**
3399: * Returns the workbench advisor. Assumes the workbench has been created
3400: * already.
3401: * <p>
3402: * IMPORTANT This method is declared private to prevent regular plug-ins
3403: * from downcasting IWorkbenchWindow to WorkbenchWindow and getting hold of
3404: * the workbench advisor that would allow them to tamper with the workbench.
3405: * The workbench advisor is internal to the application.
3406: * </p>
3407: */
3408: private/* private - DO NOT CHANGE */
3409: WorkbenchAdvisor getAdvisor() {
3410: return getWorkbenchImpl().getAdvisor();
3411: }
3412:
3413: /**
3414: * Returns the window advisor, creating a new one for this window if needed.
3415: * <p>
3416: * IMPORTANT This method is declared private to prevent regular plug-ins
3417: * from downcasting IWorkbenchWindow to WorkbenchWindow and getting hold of
3418: * the window advisor that would allow them to tamper with the window. The
3419: * window advisor is internal to the application.
3420: * </p>
3421: */
3422: private/* private - DO NOT CHANGE */
3423: WorkbenchWindowAdvisor getWindowAdvisor() {
3424: if (windowAdvisor == null) {
3425: windowAdvisor = getAdvisor().createWorkbenchWindowAdvisor(
3426: getWindowConfigurer());
3427: Assert.isNotNull(windowAdvisor);
3428: }
3429: return windowAdvisor;
3430: }
3431:
3432: /**
3433: * Returns the action bar advisor, creating a new one for this window if
3434: * needed.
3435: * <p>
3436: * IMPORTANT This method is declared private to prevent regular plug-ins
3437: * from downcasting IWorkbenchWindow to WorkbenchWindow and getting hold of
3438: * the action bar advisor that would allow them to tamper with the window's
3439: * action bars. The action bar advisor is internal to the application.
3440: * </p>
3441: */
3442: private/* private - DO NOT CHANGE */
3443: ActionBarAdvisor getActionBarAdvisor() {
3444: if (actionBarAdvisor == null) {
3445: actionBarAdvisor = getWindowAdvisor()
3446: .createActionBarAdvisor(
3447: getWindowConfigurer()
3448: .getActionBarConfigurer());
3449: Assert.isNotNull(actionBarAdvisor);
3450: }
3451: return actionBarAdvisor;
3452: }
3453:
3454: /*
3455: * Returns the IWorkbench implementation.
3456: */
3457: private Workbench getWorkbenchImpl() {
3458: return Workbench.getInstance();
3459: }
3460:
3461: /**
3462: * Fills the window's real action bars.
3463: *
3464: * @param flags
3465: * indicate which bars to fill
3466: */
3467: public void fillActionBars(int flags) {
3468: Workbench workbench = getWorkbenchImpl();
3469: workbench.largeUpdateStart();
3470: try {
3471: getActionBarAdvisor().fillActionBars(flags);
3472: //
3473: // 3.3 start
3474: final IMenuService menuService = (IMenuService) serviceLocator
3475: .getService(IMenuService.class);
3476: menuService.populateContributionManager(
3477: (ContributionManager) getActionBars()
3478: .getMenuManager(), MenuUtil.MAIN_MENU);
3479: ICoolBarManager coolbar = getActionBars()
3480: .getCoolBarManager();
3481: if (coolbar != null) {
3482: menuService.populateContributionManager(
3483: (ContributionManager) coolbar,
3484: MenuUtil.MAIN_TOOLBAR);
3485: }
3486: // 3.3 end
3487: } finally {
3488: workbench.largeUpdateEnd();
3489: }
3490: }
3491:
3492: /**
3493: * Fills the window's proxy action bars.
3494: *
3495: * @param proxyBars
3496: * the proxy configurer
3497: * @param flags
3498: * indicate which bars to fill
3499: */
3500: public void fillActionBars(IActionBarConfigurer2 proxyBars,
3501: int flags) {
3502: Assert.isNotNull(proxyBars);
3503: WorkbenchWindowConfigurer.WindowActionBarConfigurer wab = (WorkbenchWindowConfigurer.WindowActionBarConfigurer) getWindowConfigurer()
3504: .getActionBarConfigurer();
3505: wab.setProxy(proxyBars);
3506: try {
3507: getActionBarAdvisor().fillActionBars(
3508: flags | ActionBarAdvisor.FILL_PROXY);
3509: } finally {
3510: wab.setProxy(null);
3511: }
3512: }
3513:
3514: /**
3515: * The <code>WorkbenchWindow</code> implementation of this method has the
3516: * same logic as <code>Window</code>'s implementation, but without the
3517: * resize check. We don't want to skip setting the bounds if the shell has
3518: * been resized since a free resize event occurs on Windows when the menubar
3519: * is set in configureShell.
3520: */
3521: protected void initializeBounds() {
3522: Point size = getInitialSize();
3523: Point location = getInitialLocation(size);
3524: getShell().setBounds(
3525: getConstrainedShellBounds(new Rectangle(location.x,
3526: location.y, size.x, size.y)));
3527: }
3528:
3529: /*
3530: * Unlike dialogs, the position of the workbench window is set by the user
3531: * and persisted across sessions. If the user wants to put the window
3532: * offscreen or spanning multiple monitors, let them (bug 74762)
3533: */
3534: protected void constrainShellSize() {
3535: // As long as the shell is visible on some monitor, don't change it.
3536: Rectangle bounds = getShell().getBounds();
3537: if (!SwtUtil.intersectsAnyMonitor(Display.getCurrent(), bounds)) {
3538: super .constrainShellSize();
3539: }
3540: }
3541:
3542: /*
3543: * Unlike dialogs, the position of the workbench window is set by the user
3544: * and persisted across sessions. If the user wants to put the window
3545: * offscreen or spanning multiple monitors, let them (bug 74762)
3546: */
3547: protected Point getInitialLocation(Point size) {
3548: Shell shell = getShell();
3549: if (shell != null) {
3550: return shell.getLocation();
3551: }
3552:
3553: return super .getInitialLocation(size);
3554: }
3555:
3556: /**
3557: * The <code>WorkbenchWindow</code> implementation of this method
3558: * delegates to the window configurer.
3559: *
3560: * @since 3.0
3561: */
3562: protected Point getInitialSize() {
3563: return getWindowConfigurer().getInitialSize();
3564: }
3565:
3566: /**
3567: * @param visible
3568: * whether the cool bar should be shown. This is only applicable
3569: * if the window configurer also wishes either the cool bar to be
3570: * visible.
3571: * @since 3.0
3572: */
3573: public void setCoolBarVisible(boolean visible) {
3574: boolean oldValue = coolBarVisible;
3575: coolBarVisible = visible;
3576: if (oldValue != coolBarVisible) {
3577: updateLayoutDataForContents();
3578: }
3579: }
3580:
3581: /**
3582: * @return whether the cool bar should be shown. This is only applicable if
3583: * the window configurer also wishes either the cool bar to be
3584: * visible.
3585: * @since 3.0
3586: */
3587: public boolean getCoolBarVisible() {
3588: return coolBarVisible;
3589: }
3590:
3591: /**
3592: * @param visible
3593: * whether the perspective bar should be shown. This is only
3594: * applicable if the window configurer also wishes either the
3595: * perspective bar to be visible.
3596: * @since 3.0
3597: */
3598: public void setPerspectiveBarVisible(boolean visible) {
3599: boolean oldValue = perspectiveBarVisible;
3600: perspectiveBarVisible = visible;
3601: if (oldValue != perspectiveBarVisible) {
3602: updateLayoutDataForContents();
3603: }
3604: }
3605:
3606: /**
3607: * @return whether the perspective bar should be shown. This is only
3608: * applicable if the window configurer also wishes either the
3609: * perspective bar to be visible.
3610: * @since 3.0
3611: */
3612: public boolean getPerspectiveBarVisible() {
3613: return perspectiveBarVisible;
3614: }
3615:
3616: /**
3617: * Tell the workbench window a visible state for the fastview bar. This is
3618: * only applicable if the window configurer also wishes the fast view bar to
3619: * be visible.
3620: *
3621: * @param visible
3622: * <code>true</code> or <code>false</code>
3623: * @since 3.2
3624: */
3625: public void setFastViewBarVisible(boolean visible) {
3626: boolean oldValue = fastViewBarVisible;
3627: fastViewBarVisible = visible;
3628: if (oldValue != fastViewBarVisible) {
3629: updateLayoutDataForContents();
3630: }
3631: }
3632:
3633: /**
3634: * The workbench window take on the fastview bar. This is only applicable if
3635: * the window configurer also wishes the fast view bar to be visible.
3636: *
3637: * @return <code>true</code> if the workbench window thinks the fastview
3638: * bar should be visible.
3639: * @since 3.2
3640: */
3641: public boolean getFastViewBarVisible() {
3642: return fastViewBarVisible;
3643: }
3644:
3645: /**
3646: * @param visible
3647: * whether the perspective bar should be shown. This is only
3648: * applicable if the window configurer also wishes either the
3649: * perspective bar to be visible.
3650: * @since 3.0
3651: */
3652: public void setStatusLineVisible(boolean visible) {
3653: boolean oldValue = statusLineVisible;
3654: statusLineVisible = visible;
3655: if (oldValue != statusLineVisible) {
3656: updateLayoutDataForContents();
3657: }
3658: }
3659:
3660: /**
3661: * @return whether the perspective bar should be shown. This is only
3662: * applicable if the window configurer also wishes either the
3663: * perspective bar to be visible.
3664: * @since 3.0
3665: */
3666: public boolean getStatusLineVisible() {
3667: return statusLineVisible;
3668: }
3669:
3670: /**
3671: * Note that this will only have an effect if the default implementation of
3672: * WorkbenchAdvisor.createWindowContents() has been invoked.
3673: *
3674: * called IWorkbench
3675: *
3676: * @since 3.0
3677: */
3678: private void updateLayoutDataForContents() {
3679: if (defaultLayout == null) {
3680: return;
3681: }
3682:
3683: // @issue this is not ideal; coolbar and perspective shortcuts should be
3684: // separately configurable
3685: if ((getCoolBarVisible() && getWindowConfigurer()
3686: .getShowCoolBar())
3687: || (getPerspectiveBarVisible() && getWindowConfigurer()
3688: .getShowPerspectiveBar())) {
3689: if (defaultLayout.getTrim(topBarTrim.getId()) == null) {
3690: defaultLayout.addTrim(SWT.TOP, topBarTrim);
3691: }
3692: topBar.setVisible(true);
3693: } else {
3694: defaultLayout.removeTrim(topBarTrim);
3695: topBar.setVisible(false);
3696: }
3697:
3698: if (fastViewBar != null) {
3699: if (getFastViewBarVisible()
3700: && getWindowConfigurer().getShowFastViewBars()) {
3701: int side = fastViewBar.getSide();
3702:
3703: if (defaultLayout.getTrim(fastViewBar.getId()) == null) {
3704: defaultLayout.addTrim(side, fastViewBar);
3705: }
3706: fastViewBar.getControl().setVisible(true);
3707: } else {
3708: defaultLayout.removeTrim(fastViewBar);
3709: fastViewBar.getControl().setVisible(false);
3710: }
3711: }
3712:
3713: if (getStatusLineVisible()
3714: && getWindowConfigurer().getShowStatusLine()) {
3715: if (defaultLayout.getTrim(getStatusLineTrim().getId()) == null) {
3716: defaultLayout.addTrim(SWT.BOTTOM, getStatusLineTrim());
3717: }
3718: getStatusLineManager().getControl().setVisible(true);
3719: } else {
3720: defaultLayout.removeTrim(getStatusLineTrim());
3721: getStatusLineManager().getControl().setVisible(false);
3722: }
3723:
3724: if (heapStatus != null) {
3725: if (getShowHeapStatus()) {
3726: if (heapStatus.getLayoutData() == null) {
3727: heapStatusTrim.setWidthHint(heapStatus.computeSize(
3728: SWT.DEFAULT, SWT.DEFAULT).x);
3729: heapStatusTrim.setHeightHint(getStatusLineManager()
3730: .getControl().computeSize(SWT.DEFAULT,
3731: SWT.DEFAULT).y);
3732: }
3733:
3734: if (defaultLayout.getTrim(heapStatusTrim.getId()) == null) {
3735: defaultLayout.addTrim(SWT.BOTTOM, heapStatusTrim);
3736: }
3737: heapStatus.setVisible(true);
3738: } else {
3739:
3740: defaultLayout.removeTrim(heapStatusTrim);
3741: heapStatus.setVisible(false);
3742: }
3743: }
3744:
3745: if (progressRegion != null) {
3746: if (getWindowConfigurer().getShowProgressIndicator()) {
3747: if (defaultLayout.getTrim(progressRegion.getId()) == null) {
3748: defaultLayout.addTrim(SWT.BOTTOM, progressRegion);
3749: }
3750: progressRegion.getControl().setVisible(true);
3751: } else {
3752: defaultLayout.removeTrim(progressRegion);
3753: progressRegion.getControl().setVisible(false);
3754: }
3755: }
3756:
3757: defaultLayout.setCenterControl(getPageComposite());
3758:
3759: // Re-populate the trim elements
3760: if (trimMgr2 != null)
3761: trimMgr2.update(true, false, !topBar.getVisible());
3762: if (trimContributionMgr != null)
3763: trimContributionMgr.update(true, !topBar.getVisible());
3764: }
3765:
3766: public boolean getShowFastViewBars() {
3767: return getWindowConfigurer().getShowFastViewBars();
3768: }
3769:
3770: /**
3771: * Set the layout data for the contents of the window.
3772: */
3773: private void setLayoutDataForContents() {
3774: updateLayoutDataForContents();
3775: }
3776:
3777: /**
3778: * Returns the fast view bar.
3779: */
3780: public FastViewBar getFastViewBar() {
3781: return fastViewBar;
3782: }
3783:
3784: /**
3785: * Returns the perspective bar.
3786: *
3787: * @return Returns the perspective bar, or <code>null</code> if it has not
3788: * been initialized.
3789: */
3790: public PerspectiveBarManager getPerspectiveBar() {
3791: return perspectiveSwitcher == null ? null : perspectiveSwitcher
3792: .getPerspectiveBar();
3793: }
3794:
3795: /**
3796: * Returns the action presentation for dynamic UI
3797: * @return action presentation
3798: */
3799: public ActionPresentation getActionPresentation() {
3800: if (actionPresentation == null) {
3801: actionPresentation = new ActionPresentation(this );
3802: }
3803: return actionPresentation;
3804: }
3805:
3806: /**
3807: * Return the action bar presentation used for creating toolbars. This
3808: * is for internal use only, used for consistency with the window.
3809: *
3810: * @return the presentation used.
3811: */
3812: public IActionBarPresentationFactory getActionBarPresentationFactory() {
3813: // allow replacement of the actionbar presentation
3814: IActionBarPresentationFactory actionBarPresentation;
3815: AbstractPresentationFactory presentationFactory = getWindowConfigurer()
3816: .getPresentationFactory();
3817: if (presentationFactory instanceof IActionBarPresentationFactory) {
3818: actionBarPresentation = ((IActionBarPresentationFactory) presentationFactory);
3819: } else {
3820: actionBarPresentation = new DefaultActionBarPresentationFactory();
3821: }
3822:
3823: return actionBarPresentation;
3824: }
3825:
3826: /*
3827: * (non-Javadoc)
3828: *
3829: * @see org.eclipse.jface.window.ApplicationWindow#showTopSeperator()
3830: */
3831: protected boolean showTopSeperator() {
3832: return false;
3833: }
3834:
3835: /**
3836: * Returns a new cool bar manager for the window.
3837: * <p>
3838: * Subclasses may override this method to customize the cool bar manager.
3839: * </p>
3840: *
3841: * @return a cool bar manager
3842: * @since 3.2
3843: */
3844: protected ICoolBarManager createCoolBarManager2(int style) {
3845: return getActionBarPresentationFactory().createCoolBarManager();
3846: }
3847:
3848: /**
3849: * Returns a new tool bar manager for the window.
3850: * <p>
3851: * Subclasses may override this method to customize the tool bar manager.
3852: * </p>
3853: * @return a tool bar manager
3854: * @since 3.2
3855: */
3856: protected IToolBarManager createToolBarManager2(int style) {
3857: return getActionBarPresentationFactory().createToolBarManager();
3858: }
3859:
3860: /**
3861: * Delegate to the presentation factory.
3862: *
3863: * @see org.eclipse.jface.window.ApplicationWindow#createStatusLineManager
3864: * @since 3.0
3865: */
3866: protected StatusLineManager createStatusLineManager() {
3867: // @issue ApplicationWindow and WorkbenchWindow should allow full
3868: // IStatusLineManager
3869: return (StatusLineManager) getWindowConfigurer()
3870: .getPresentationFactory().createStatusLineManager();
3871: }
3872:
3873: /**
3874: * Delegate to the presentation factory.
3875: *
3876: * @see org.eclipse.jface.window.ApplicationWindow#createStatusLine
3877: * @since 3.0
3878: */
3879: protected void createStatusLine(Shell shell) {
3880: getWindowConfigurer().getPresentationFactory()
3881: .createStatusLineControl(getStatusLineManager(), shell);
3882: }
3883:
3884: /**
3885: * Updates the fast view bar, if present. TODO: The fast view bar should
3886: * update itself as necessary. All calls to this should be cleaned up.
3887: *
3888: * @since 3.0
3889: */
3890: public void updateFastViewBar() {
3891: if (getFastViewBar() != null) {
3892: getFastViewBar().update(true);
3893: }
3894: }
3895:
3896: /**
3897: * @return Returns the progressRegion.
3898: */
3899: public ProgressRegion getProgressRegion() {
3900: return progressRegion;
3901: }
3902:
3903: /**
3904: * Adds the given control to the specified side of this window's trim.
3905: *
3906: * @param trim
3907: * the bar's IWindowTrim
3908: * @param side
3909: * one of <code>SWT.LEFT</code>,<code>SWT.BOTTOM</code>,
3910: * or <code>SWT.RIGHT</code> (only LEFT has been tested)
3911: * @since 3.0
3912: */
3913: public void addToTrim(IWindowTrim trim, int side) {
3914: IWindowTrim reference = null;
3915: defaultLayout.addTrim(side, trim, reference);
3916: }
3917:
3918: /*
3919: * (non-Javadoc)
3920: *
3921: * @see org.eclipse.ui.IWorkbenchWindow#getExtensionTracker()
3922: */
3923: public IExtensionTracker getExtensionTracker() {
3924: if (tracker == null) {
3925: tracker = new UIExtensionTracker(getWorkbench()
3926: .getDisplay());
3927: }
3928: return tracker;
3929: }
3930:
3931: /**
3932: * Creates the perspective customization dialog.
3933: *
3934: * @param persp
3935: * perspective to customize
3936: *
3937: * @return a new perspective customization dialog
3938: * @since 3.1
3939: */
3940: public CustomizePerspectiveDialog createCustomizePerspectiveDialog(
3941: Perspective persp) {
3942: return new CustomizePerspectiveDialog(getWindowConfigurer(),
3943: persp);
3944: }
3945:
3946: /**
3947: * Returns the default page input for workbench pages opened in this window.
3948: *
3949: * @return the default page input or <code>null</code> if none
3950: * @since 3.1
3951: */
3952: IAdaptable getDefaultPageInput() {
3953: return getWorkbenchImpl().getDefaultPageInput();
3954: }
3955:
3956: /**
3957: * Add a listener for perspective reordering.
3958: *
3959: * @param listener
3960: */
3961: public void addPerspectiveReorderListener(IReorderListener listener) {
3962: if (perspectiveSwitcher != null) {
3963: perspectiveSwitcher.addReorderListener(listener);
3964: }
3965: }
3966:
3967: /**
3968: * Show the heap status
3969: *
3970: * @param selection
3971: */
3972: public void showHeapStatus(boolean selection) {
3973: if (selection) {
3974: if (heapStatus == null) {
3975: createHeapStatus(getShell());
3976: updateLayoutDataForContents();
3977: getShell().layout();
3978: }
3979: } else {
3980: if (heapStatus != null) {
3981: heapStatus.dispose();
3982: heapStatus = null;
3983: }
3984: }
3985:
3986: }
3987:
3988: /*
3989: * (non-Javadoc)
3990: *
3991: * @see org.eclipse.ui.IWorkbenchWindow#getTrimManager()
3992: */
3993: public ITrimManager getTrimManager() {
3994: return defaultLayout;
3995: }
3996:
3997: /**
3998: * Initializes all of the default command-based services for the workbench
3999: * window.
4000: */
4001: private final void initializeDefaultServices() {
4002: serviceLocator.registerService(IWorkbenchWindow.class, this );
4003:
4004: final Expression defaultExpression = new WorkbenchWindowExpression(
4005: this );
4006:
4007: final IHandlerService parentHandlerService = (IHandlerService) serviceLocator
4008: .getService(IHandlerService.class);
4009: final IHandlerService handlerService = new SlaveHandlerService(
4010: parentHandlerService, defaultExpression);
4011: serviceLocator.registerService(IHandlerService.class,
4012: handlerService);
4013:
4014: final IContextService parentContextService = (IContextService) serviceLocator
4015: .getService(IContextService.class);
4016: final IContextService contextService = new SlaveContextService(
4017: parentContextService, defaultExpression);
4018: serviceLocator.registerService(IContextService.class,
4019: contextService);
4020:
4021: final ICommandService parentCommandService = (ICommandService) serviceLocator
4022: .getService(ICommandService.class);
4023: final ICommandService commandService = new SlaveCommandService(
4024: parentCommandService, IServiceScopes.WINDOW_SCOPE, this );
4025: serviceLocator.registerService(ICommandService.class,
4026: commandService);
4027:
4028: final IMenuService menuService = new WindowMenuService(
4029: serviceLocator);
4030: serviceLocator.registerService(IMenuService.class, menuService);
4031:
4032: // final ISourceProviderService sourceProviderService = (ISourceProviderService) serviceLocator
4033: // .getService(ISourceProviderService.class);
4034: // final ISourceProvider[] sourceProviders = sourceProviderService
4035: // .getSourceProviders();
4036: // for (int i = 0; i < sourceProviders.length; i++) {
4037: // final ISourceProvider provider = sourceProviders[i];
4038: // menuService.addSourceProvider(provider);
4039: // }
4040: // serviceLocator.registerService(IMenuService.class, menuService);
4041:
4042: final ActionCommandMappingService mappingService = new ActionCommandMappingService();
4043: serviceLocator.registerService(
4044: IActionCommandMappingService.class, mappingService);
4045:
4046: final LegacyActionPersistence actionPersistence = new LegacyActionPersistence(
4047: this );
4048: serviceLocator.registerService(LegacyActionPersistence.class,
4049: actionPersistence);
4050: actionPersistence.read();
4051:
4052: }
4053:
4054: public final Object getService(final Class key) {
4055: return serviceLocator.getService(key);
4056: }
4057:
4058: public final boolean hasService(final Class key) {
4059: return serviceLocator.hasService(key);
4060: }
4061:
4062: /**
4063: * Toggle the visibility of the coolbar/perspective bar. This method
4064: * respects the window configurer and will only toggle visibility if the
4065: * item in question was originally declared visible by the window advisor.
4066: *
4067: * @since 3.3
4068: */
4069: public void toggleToolbarVisibility() {
4070: boolean coolbarVisible = getCoolBarVisible();
4071: boolean perspectivebarVisible = getPerspectiveBarVisible();
4072: // only toggle the visibility of the components that
4073: // were on initially
4074: if (getWindowConfigurer().getShowCoolBar()) {
4075: setCoolBarVisible(!coolbarVisible);
4076: firePropertyChanged(PROP_COOLBAR_VISIBLE,
4077: coolbarVisible ? Boolean.TRUE : Boolean.FALSE,
4078: !coolbarVisible ? Boolean.TRUE : Boolean.FALSE);
4079: }
4080: if (getWindowConfigurer().getShowPerspectiveBar()) {
4081: setPerspectiveBarVisible(!perspectivebarVisible);
4082: firePropertyChanged(PROP_PERSPECTIVEBAR_VISIBLE,
4083: coolbarVisible ? Boolean.TRUE : Boolean.FALSE,
4084: !coolbarVisible ? Boolean.TRUE : Boolean.FALSE);
4085: }
4086: getShell().layout();
4087: }
4088:
4089: /*package*/void addBackgroundSaveListener(
4090: IBackgroundSaveListener listener) {
4091: backgroundSaveListeners.add(listener);
4092: }
4093:
4094: /*package*/void fireBackgroundSaveStarted() {
4095: Object[] listeners = backgroundSaveListeners.getListeners();
4096: for (int i = 0; i < listeners.length; i++) {
4097: IBackgroundSaveListener listener = (IBackgroundSaveListener) listeners[i];
4098: listener.handleBackgroundSaveStarted();
4099: }
4100: }
4101:
4102: /*package*/void removeBackgroundSaveListener(
4103: IBackgroundSaveListener listener) {
4104: backgroundSaveListeners.remove(listener);
4105: }
4106: }
|