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.io.IOException;
0013: import java.util.ArrayList;
0014: import java.util.HashMap;
0015: import java.util.HashSet;
0016: import java.util.Iterator;
0017: import java.util.List;
0018: import java.util.Map;
0019:
0020: import org.eclipse.core.runtime.CoreException;
0021: import org.eclipse.core.runtime.IStatus;
0022: import org.eclipse.core.runtime.MultiStatus;
0023: import org.eclipse.core.runtime.Status;
0024: import org.eclipse.jface.dialogs.ErrorDialog;
0025: import org.eclipse.jface.dialogs.MessageDialog;
0026: import org.eclipse.jface.preference.IPreferenceStore;
0027: import org.eclipse.jface.util.Geometry;
0028: import org.eclipse.osgi.util.NLS;
0029: import org.eclipse.swt.SWT;
0030: import org.eclipse.swt.graphics.Point;
0031: import org.eclipse.swt.graphics.Rectangle;
0032: import org.eclipse.swt.widgets.Composite;
0033: import org.eclipse.swt.widgets.Control;
0034: import org.eclipse.swt.widgets.Shell;
0035: import org.eclipse.ui.IMemento;
0036: import org.eclipse.ui.IPageLayout;
0037: import org.eclipse.ui.IPerspectiveDescriptor;
0038: import org.eclipse.ui.IPerspectiveFactory;
0039: import org.eclipse.ui.IPlaceholderFolderLayout;
0040: import org.eclipse.ui.IViewLayout;
0041: import org.eclipse.ui.IViewPart;
0042: import org.eclipse.ui.IViewReference;
0043: import org.eclipse.ui.IViewSite;
0044: import org.eclipse.ui.IWorkbenchPart;
0045: import org.eclipse.ui.IWorkbenchPartReference;
0046: import org.eclipse.ui.IWorkbenchPreferenceConstants;
0047: import org.eclipse.ui.IWorkbenchWindow;
0048: import org.eclipse.ui.PartInitException;
0049: import org.eclipse.ui.PlatformUI;
0050: import org.eclipse.ui.WorkbenchException;
0051: import org.eclipse.ui.XMLMemento;
0052: import org.eclipse.ui.contexts.IContextService;
0053: import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
0054: import org.eclipse.ui.internal.contexts.ContextAuthority;
0055: import org.eclipse.ui.internal.intro.IIntroConstants;
0056: import org.eclipse.ui.internal.layout.ITrimManager;
0057: import org.eclipse.ui.internal.layout.IWindowTrim;
0058: import org.eclipse.ui.internal.layout.TrimLayout;
0059: import org.eclipse.ui.internal.misc.StatusUtil;
0060: import org.eclipse.ui.internal.registry.ActionSetRegistry;
0061: import org.eclipse.ui.internal.registry.IActionSetDescriptor;
0062: import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
0063: import org.eclipse.ui.internal.registry.PerspectiveDescriptor;
0064: import org.eclipse.ui.internal.registry.PerspectiveExtensionReader;
0065: import org.eclipse.ui.internal.registry.PerspectiveRegistry;
0066: import org.eclipse.ui.internal.registry.StickyViewDescriptor;
0067: import org.eclipse.ui.internal.util.PrefUtil;
0068: import org.eclipse.ui.presentations.AbstractPresentationFactory;
0069: import org.eclipse.ui.presentations.IStackPresentationSite;
0070: import org.eclipse.ui.statushandlers.StatusManager;
0071: import org.eclipse.ui.views.IStickyViewDescriptor;
0072: import org.eclipse.ui.views.IViewDescriptor;
0073: import org.eclipse.ui.views.IViewRegistry;
0074:
0075: /**
0076: * The ViewManager is a factory for workbench views.
0077: */
0078: public class Perspective {
0079: private PerspectiveDescriptor descriptor;
0080:
0081: protected WorkbenchPage page;
0082:
0083: // Editor Area management
0084: protected LayoutPart editorArea;
0085: private PartPlaceholder editorHolder;
0086: private boolean editorHidden = false;
0087: private boolean editorAreaRestoreOnUnzoom = false;
0088: private int editorAreaState = IStackPresentationSite.STATE_RESTORED;
0089:
0090: private ViewFactory viewFactory;
0091:
0092: private ArrayList alwaysOnActionSets;
0093:
0094: private ArrayList alwaysOffActionSets;
0095:
0096: private ArrayList newWizardShortcuts;
0097:
0098: private ArrayList showViewShortcuts;
0099:
0100: private ArrayList perspectiveShortcuts;
0101:
0102: //private List fastViews;
0103: private FastViewManager fastViewManager = null;
0104:
0105: private Map mapIDtoViewLayoutRec;
0106:
0107: private boolean fixed;
0108:
0109: private ArrayList showInPartIds;
0110:
0111: private HashMap showInTimes = new HashMap();
0112:
0113: private IViewReference activeFastView;
0114:
0115: private IMemento memento;
0116:
0117: protected PerspectiveHelper presentation;
0118:
0119: final static private String VERSION_STRING = "0.016";//$NON-NLS-1$
0120:
0121: private FastViewPane fastViewPane = new FastViewPane();
0122:
0123: // fields used by fast view resizing via a sash
0124: private static final int FASTVIEW_HIDE_STEPS = 5;
0125:
0126: /**
0127: * Reference to the part that was previously active
0128: * when this perspective was deactivated.
0129: */
0130: private IWorkbenchPartReference oldPartRef = null;
0131:
0132: private boolean shouldHideEditorsOnActivate = false;
0133:
0134: private PageLayout layout;
0135:
0136: /**
0137: * ViewManager constructor comment.
0138: */
0139: public Perspective(PerspectiveDescriptor desc, WorkbenchPage page)
0140: throws WorkbenchException {
0141: this (page);
0142: descriptor = desc;
0143: if (desc != null) {
0144: createPresentation(desc);
0145: }
0146: }
0147:
0148: /**
0149: * ViewManager constructor comment.
0150: */
0151: protected Perspective(WorkbenchPage page) throws WorkbenchException {
0152: this .page = page;
0153: this .editorArea = page.getEditorPresentation().getLayoutPart();
0154: this .viewFactory = page.getViewFactory();
0155: alwaysOnActionSets = new ArrayList(2);
0156: alwaysOffActionSets = new ArrayList(2);
0157:
0158: // We'll only make a FastView Manager if there's a
0159: // Trim manager in the WorkbenchWindow
0160: IWorkbenchWindow wbw = page.getWorkbenchWindow();
0161: if (wbw instanceof WorkbenchWindow) {
0162: if (((WorkbenchWindow) wbw).getTrimManager() != null)
0163: fastViewManager = new FastViewManager(this , page);
0164: }
0165:
0166: mapIDtoViewLayoutRec = new HashMap();
0167: }
0168:
0169: /**
0170: * Sets the fast view attribute. Note: The page is expected to update action
0171: * bars.
0172: */
0173: public void makeFastView(IViewReference ref) {
0174: addFastView(ref, true);
0175: }
0176:
0177: /**
0178: * Sets the fast view attribute. Note: The page is expected to update action
0179: * bars.
0180: */
0181: public void addFastView(IViewReference ref, boolean handleLayout) {
0182: ViewPane pane = (ViewPane) ((WorkbenchPartReference) ref)
0183: .getPane();
0184: if (!isFastView(ref)) {
0185: if (handleLayout) {
0186: // Only remove the part from the presentation if it
0187: // is actually in the presentation.
0188: if (presentation.hasPlaceholder(ref.getId(), ref
0189: .getSecondaryId())
0190: || pane.getContainer() != null) {
0191: presentation.removePart(pane);
0192: }
0193: }
0194:
0195: // We are drag-enabling the pane because it has been disabled
0196: // when it was removed from the perspective presentation.
0197: pane.setFast(true);
0198: Control ctrl = pane.getControl();
0199: if (ctrl != null) {
0200: ctrl.setEnabled(false); // Remove focus support.
0201: }
0202: }
0203: }
0204:
0205: /**
0206: * Moves a part forward in the Z order of a perspective so it is visible.
0207: *
0208: * @param part the part to bring to move forward
0209: * @return true if the part was brought to top, false if not.
0210: */
0211: public boolean bringToTop(IViewReference ref) {
0212: if (isFastView(ref)) {
0213: setActiveFastView(ref);
0214: return true;
0215: } else {
0216: return presentation.bringPartToTop(getPane(ref));
0217: }
0218: }
0219:
0220: /**
0221: * Returns whether a view exists within the perspective.
0222: */
0223: public boolean containsView(IViewPart view) {
0224: IViewSite site = view.getViewSite();
0225: IViewReference ref = findView(site.getId(), site
0226: .getSecondaryId());
0227: if (ref == null) {
0228: return false;
0229: }
0230: return (view == ref.getPart(false));
0231: }
0232:
0233: /**
0234: * Create the initial list of action sets.
0235: */
0236: private void createInitialActionSets(List outputList,
0237: List stringList) {
0238: ActionSetRegistry reg = WorkbenchPlugin.getDefault()
0239: .getActionSetRegistry();
0240: Iterator iter = stringList.iterator();
0241: while (iter.hasNext()) {
0242: String id = (String) iter.next();
0243: IActionSetDescriptor desc = reg.findActionSet(id);
0244: if (desc != null) {
0245: outputList.add(desc);
0246: } else {
0247: WorkbenchPlugin.log("Unable to find Action Set: " + id);//$NON-NLS-1$
0248: }
0249: }
0250: }
0251:
0252: /**
0253: * Create a presentation for a perspective.
0254: */
0255: private void createPresentation(PerspectiveDescriptor persp)
0256: throws WorkbenchException {
0257: if (persp.hasCustomDefinition()) {
0258: loadCustomPersp(persp);
0259: } else {
0260: loadPredefinedPersp(persp);
0261: }
0262: }
0263:
0264: /**
0265: * Dispose the perspective and all views contained within.
0266: */
0267: public void dispose() {
0268: // Get rid of presentation.
0269: if (presentation == null) {
0270: return;
0271: }
0272:
0273: presentation.deactivate();
0274: presentation.dispose();
0275:
0276: fastViewPane.dispose();
0277:
0278: // Release each view.
0279: IViewReference refs[] = getViewReferences();
0280: for (int i = 0, length = refs.length; i < length; i++) {
0281: getViewFactory().releaseView(refs[i]);
0282: }
0283:
0284: mapIDtoViewLayoutRec.clear();
0285: }
0286:
0287: /**
0288: * Finds the view with the given ID that is open in this page, or <code>null</code>
0289: * if not found.
0290: *
0291: * @param viewId the view ID
0292: */
0293: public IViewReference findView(String viewId) {
0294: return findView(viewId, null);
0295: }
0296:
0297: /**
0298: * Finds the view with the given id and secondary id that is open in this page,
0299: * or <code>null</code> if not found.
0300: *
0301: * @param viewId the view ID
0302: * @param secondaryId the secondary ID
0303: */
0304: public IViewReference findView(String id, String secondaryId) {
0305: IViewReference refs[] = getViewReferences();
0306: for (int i = 0; i < refs.length; i++) {
0307: IViewReference ref = refs[i];
0308: if (id.equals(ref.getId())
0309: && (secondaryId == null ? ref.getSecondaryId() == null
0310: : secondaryId.equals(ref.getSecondaryId()))) {
0311: return ref;
0312: }
0313: }
0314: return null;
0315: }
0316:
0317: /**
0318: * Returns the window's client composite widget
0319: * which views and editor area will be parented.
0320: */
0321: public Composite getClientComposite() {
0322: return page.getClientComposite();
0323: }
0324:
0325: /**
0326: * Returns the perspective.
0327: */
0328: public IPerspectiveDescriptor getDesc() {
0329: return descriptor;
0330: }
0331:
0332: /**
0333: * Returns the bounds of the given fast view.
0334: */
0335: /*package*/Rectangle getFastViewBounds(IViewReference ref) {
0336: // Copy the bounds of the page composite
0337: Rectangle bounds = page.getClientComposite().getBounds();
0338: // get the width ratio of the fast view
0339: float ratio = getFastViewWidthRatio(ref);
0340: // Compute the actual width of the fast view.
0341: bounds.width = (int) (ratio * getClientComposite().getSize().x);
0342: return bounds;
0343: }
0344:
0345: /**
0346: * Returns the docked views.
0347: */
0348: public IViewReference[] getFastViews() {
0349: if (fastViewManager == null)
0350: return new IViewReference[0];
0351:
0352: List trueFVBRefs = fastViewManager
0353: .getFastViews(FastViewBar.FASTVIEWBAR_ID);
0354: IViewReference array[] = new IViewReference[trueFVBRefs.size()];
0355: trueFVBRefs.toArray(array);
0356: return array;
0357: }
0358:
0359: /**
0360: * Returns the new wizard shortcuts associated with this perspective.
0361: *
0362: * @return an array of new wizard identifiers
0363: */
0364: public String[] getNewWizardShortcuts() {
0365: return (String[]) newWizardShortcuts
0366: .toArray(new String[newWizardShortcuts.size()]);
0367: }
0368:
0369: /**
0370: * Returns the pane for a view reference.
0371: */
0372: private ViewPane getPane(IViewReference ref) {
0373: return (ViewPane) ((WorkbenchPartReference) ref).getPane();
0374: }
0375:
0376: /**
0377: * Returns the perspective shortcuts associated with this perspective.
0378: *
0379: * @return an array of perspective identifiers
0380: */
0381: public String[] getPerspectiveShortcuts() {
0382: return (String[]) perspectiveShortcuts
0383: .toArray(new String[perspectiveShortcuts.size()]);
0384: }
0385:
0386: /**
0387: * Returns the presentation.
0388: */
0389: public PerspectiveHelper getPresentation() {
0390: return presentation;
0391: }
0392:
0393: /**
0394: * Retrieves the fast view width ratio for the given view.
0395: * If the ratio is not known, the default ratio for the view is assigned and returned.
0396: */
0397: public float getFastViewWidthRatio(IViewReference ref) {
0398: ViewLayoutRec rec = getViewLayoutRec(ref, true);
0399: if (rec.fastViewWidthRatio == IPageLayout.INVALID_RATIO) {
0400: IViewRegistry reg = WorkbenchPlugin.getDefault()
0401: .getViewRegistry();
0402: IViewDescriptor desc = reg.find(ref.getId());
0403: rec.fastViewWidthRatio = (desc != null ? desc
0404: .getFastViewWidthRatio()
0405: : IPageLayout.DEFAULT_FASTVIEW_RATIO);
0406: }
0407: return rec.fastViewWidthRatio;
0408: }
0409:
0410: /**
0411: * Returns the ids of the parts to list in the Show In... dialog.
0412: * This is a List of Strings.
0413: */
0414: public ArrayList getShowInPartIds() {
0415: return showInPartIds;
0416: }
0417:
0418: /**
0419: * Returns the time at which the last Show In was performed
0420: * for the given target part, or 0 if unknown.
0421: */
0422: public long getShowInTime(String partId) {
0423: Long t = (Long) showInTimes.get(partId);
0424: return t == null ? 0L : t.longValue();
0425: }
0426:
0427: /**
0428: * Returns the show view shortcuts associated with this perspective.
0429: *
0430: * @return an array of view identifiers
0431: */
0432: public String[] getShowViewShortcuts() {
0433: return (String[]) showViewShortcuts
0434: .toArray(new String[showViewShortcuts.size()]);
0435: }
0436:
0437: /**
0438: * Returns the view factory.
0439: */
0440: public ViewFactory getViewFactory() {
0441: return viewFactory;
0442: }
0443:
0444: /**
0445: * See IWorkbenchPage.
0446: */
0447: public IViewReference[] getViewReferences() {
0448: // Get normal views.
0449: if (presentation == null) {
0450: return new IViewReference[0];
0451: }
0452:
0453: List panes = new ArrayList(5);
0454: presentation.collectViewPanes(panes);
0455:
0456: List fastViews = (fastViewManager != null) ? fastViewManager
0457: .getFastViews(null) : new ArrayList();
0458: IViewReference[] resultArray = new IViewReference[panes.size()
0459: + fastViews.size()];
0460:
0461: // Copy fast views.
0462: int nView = 0;
0463: for (int i = 0; i < fastViews.size(); i++) {
0464: resultArray[nView] = (IViewReference) fastViews.get(i);
0465: ++nView;
0466: }
0467:
0468: // Copy normal views.
0469: for (int i = 0; i < panes.size(); i++) {
0470: ViewPane pane = (ViewPane) panes.get(i);
0471: resultArray[nView] = pane.getViewReference();
0472: ++nView;
0473: }
0474:
0475: return resultArray;
0476: }
0477:
0478: /**
0479: * Hide the editor area if visible
0480: */
0481: protected void hideEditorArea() {
0482: if (!isEditorAreaVisible()) {
0483: return;
0484: }
0485:
0486: // Show the editor in the appropriate location
0487: if (useNewMinMax(this )) {
0488: // If it's the currently maximized part we have to restore first
0489: if (getPresentation().getMaximizedStack() instanceof EditorStack) {
0490: getPresentation().getMaximizedStack().setState(
0491: IStackPresentationSite.STATE_RESTORED);
0492: }
0493:
0494: boolean isMinimized = editorAreaState == IStackPresentationSite.STATE_MINIMIZED;
0495: if (!isMinimized)
0496: hideEditorAreaLocal();
0497: else
0498: setEditorAreaTrimVisibility(false);
0499: } else {
0500: hideEditorAreaLocal();
0501: }
0502:
0503: editorHidden = true;
0504: }
0505:
0506: /**
0507: * Hide the editor area if visible
0508: */
0509: protected void hideEditorAreaLocal() {
0510: if (editorHolder != null) {
0511: return;
0512: }
0513:
0514: // Replace the editor area with a placeholder so we
0515: // know where to put it back on show editor area request.
0516: editorHolder = new PartPlaceholder(editorArea.getID());
0517: presentation.getLayout().replace(editorArea, editorHolder);
0518: }
0519:
0520: /**
0521: * Hides a fast view. The view shrinks equally <code>steps</code> times
0522: * before disappearing completely.
0523: */
0524: private void hideFastView(IViewReference ref, int steps) {
0525: setFastViewIconSelection(ref, false);
0526:
0527: // Note: We always do at least one step of the animation.
0528: // Note: This doesn't take into account the overhead of doing
0529: if (ref == activeFastView) {
0530: saveFastViewWidthRatio();
0531: fastViewPane.hideView();
0532: }
0533: }
0534:
0535: /**
0536: * Hides the fast view sash for zooming in a fast view.
0537: */
0538: void hideFastViewSash() {
0539: fastViewPane.hideFastViewSash();
0540: }
0541:
0542: public boolean hideView(IViewReference ref) {
0543: // If the view is locked just return.
0544: ViewPane pane = getPane(ref);
0545:
0546: // Remove the view from the current presentation.
0547: if (isFastView(ref)) {
0548: if (pane != null) {
0549: pane.setFast(false); //force an update of the toolbar
0550: }
0551: if (activeFastView == ref) {
0552: setActiveFastView(null);
0553: }
0554: if (pane != null) {
0555: pane.getControl().setEnabled(true);
0556: }
0557: } else {
0558: presentation.removePart(pane);
0559: }
0560:
0561: // Dispose view if ref count == 0.
0562: getViewFactory().releaseView(ref);
0563: return true;
0564: }
0565:
0566: /*
0567: * Return whether the editor area is visible or not.
0568: */
0569: protected boolean isEditorAreaVisible() {
0570: return !editorHidden;
0571: }
0572:
0573: /**
0574: * Returns true if a view is fast.
0575: */
0576: public boolean isFastView(IViewReference ref) {
0577: if (fastViewManager == null)
0578: return false;
0579:
0580: return fastViewManager.isFastView(ref);
0581: }
0582:
0583: /**
0584: * Returns the view layout rec for the given view reference,
0585: * or null if not found. If create is true, it creates the record
0586: * if not already created.
0587: */
0588: public ViewLayoutRec getViewLayoutRec(IViewReference ref,
0589: boolean create) {
0590: ViewLayoutRec result = getViewLayoutRec(
0591: ViewFactory.getKey(ref), create);
0592: if (result == null && create == false) {
0593: result = getViewLayoutRec(ref.getId(), false);
0594: }
0595: return result;
0596: }
0597:
0598: /**
0599: * Returns the view layout record for the given view id
0600: * or null if not found. If create is true, it creates the record
0601: * if not already created.
0602: */
0603: private ViewLayoutRec getViewLayoutRec(String viewId, boolean create) {
0604: ViewLayoutRec rec = (ViewLayoutRec) mapIDtoViewLayoutRec
0605: .get(viewId);
0606: if (rec == null && create) {
0607: rec = new ViewLayoutRec();
0608: mapIDtoViewLayoutRec.put(viewId, rec);
0609: }
0610: return rec;
0611: }
0612:
0613: /**
0614: * Returns true if a layout or perspective is fixed.
0615: */
0616: public boolean isFixedLayout() {
0617: //@issue is there a difference between a fixed
0618: //layout and a fixed perspective?? If not the API
0619: //may need some polish, WorkbenchPage, PageLayout
0620: //and Perspective all have isFixed methods.
0621: //PageLayout and Perspective have their own fixed
0622: //attribute, we are assuming they are always in sync.
0623: //WorkbenchPage delegates to the perspective.
0624: return fixed;
0625: }
0626:
0627: /**
0628: * Returns true if a view is standalone.
0629: *
0630: * @since 3.0
0631: */
0632: public boolean isStandaloneView(IViewReference ref) {
0633: ViewLayoutRec rec = getViewLayoutRec(ref, false);
0634: return rec != null && rec.isStandalone;
0635: }
0636:
0637: /**
0638: * Returns whether the title for a view should
0639: * be shown. This applies only to standalone views.
0640: *
0641: * @since 3.0
0642: */
0643: public boolean getShowTitleView(IViewReference ref) {
0644: ViewLayoutRec rec = getViewLayoutRec(ref, false);
0645: return rec != null && rec.showTitle;
0646: }
0647:
0648: /**
0649: * Creates a new presentation from a persistence file.
0650: * Note: This method should not modify the current state of the perspective.
0651: */
0652: private void loadCustomPersp(PerspectiveDescriptor persp) {
0653: //get the layout from the registry
0654: PerspectiveRegistry perspRegistry = (PerspectiveRegistry) WorkbenchPlugin
0655: .getDefault().getPerspectiveRegistry();
0656: try {
0657: IMemento memento = perspRegistry.getCustomPersp(persp
0658: .getId());
0659: // Restore the layout state.
0660: MultiStatus status = new MultiStatus(
0661: PlatformUI.PLUGIN_ID,
0662: IStatus.OK,
0663: NLS
0664: .bind(
0665: WorkbenchMessages.Perspective_unableToRestorePerspective,
0666: persp.getLabel()), null);
0667: status.merge(restoreState(memento));
0668: status.merge(restoreState());
0669: if (status.getSeverity() != IStatus.OK) {
0670: unableToOpenPerspective(persp, status);
0671: }
0672: } catch (IOException e) {
0673: unableToOpenPerspective(persp, null);
0674: } catch (WorkbenchException e) {
0675: unableToOpenPerspective(persp, e.getStatus());
0676: }
0677: }
0678:
0679: private void unableToOpenPerspective(PerspectiveDescriptor persp,
0680: IStatus status) {
0681: PerspectiveRegistry perspRegistry = (PerspectiveRegistry) WorkbenchPlugin
0682: .getDefault().getPerspectiveRegistry();
0683: perspRegistry.deletePerspective(persp);
0684: // If this is a predefined perspective, we will not be able to delete
0685: // the perspective (we wouldn't want to). But make sure to delete the
0686: // customized portion.
0687: persp.deleteCustomDefinition();
0688: String title = WorkbenchMessages.Perspective_problemRestoringTitle;
0689: String msg = WorkbenchMessages.Perspective_errorReadingState;
0690: if (status == null) {
0691: MessageDialog.openError((Shell) null, title, msg);
0692: } else {
0693: ErrorDialog.openError((Shell) null, title, msg, status);
0694: }
0695: }
0696:
0697: /**
0698: * Create a presentation for a perspective.
0699: * Note: This method should not modify the current state of the perspective.
0700: */
0701: private void loadPredefinedPersp(PerspectiveDescriptor persp)
0702: throws WorkbenchException {
0703: // Create layout engine.
0704: IPerspectiveFactory factory = null;
0705: try {
0706: factory = persp.createFactory();
0707: } catch (CoreException e) {
0708: throw new WorkbenchException(NLS.bind(
0709: WorkbenchMessages.Perspective_unableToLoad, persp
0710: .getId()));
0711: }
0712:
0713: /*
0714: * IPerspectiveFactory#createFactory() can return null
0715: */
0716: if (factory == null) {
0717: throw new WorkbenchException(NLS.bind(
0718: WorkbenchMessages.Perspective_unableToLoad, persp
0719: .getId()));
0720: }
0721:
0722: // Create layout factory.
0723: ViewSashContainer container = new ViewSashContainer(page,
0724: getClientComposite());
0725: layout = new PageLayout(container, getViewFactory(),
0726: editorArea, descriptor);
0727: layout.setFixed(descriptor.getFixed());
0728:
0729: // add the placeholders for the sticky folders and their contents
0730: IPlaceholderFolderLayout stickyFolderRight = null, stickyFolderLeft = null, stickyFolderTop = null, stickyFolderBottom = null;
0731:
0732: IStickyViewDescriptor[] descs = WorkbenchPlugin.getDefault()
0733: .getViewRegistry().getStickyViews();
0734: for (int i = 0; i < descs.length; i++) {
0735: IStickyViewDescriptor stickyViewDescriptor = descs[i];
0736: String id = stickyViewDescriptor.getId();
0737: switch (stickyViewDescriptor.getLocation()) {
0738: case IPageLayout.RIGHT:
0739: if (stickyFolderRight == null) {
0740: stickyFolderRight = layout.createPlaceholderFolder(
0741: StickyViewDescriptor.STICKY_FOLDER_RIGHT,
0742: IPageLayout.RIGHT, .75f,
0743: IPageLayout.ID_EDITOR_AREA);
0744: }
0745: stickyFolderRight.addPlaceholder(id);
0746: break;
0747: case IPageLayout.LEFT:
0748: if (stickyFolderLeft == null) {
0749: stickyFolderLeft = layout.createPlaceholderFolder(
0750: StickyViewDescriptor.STICKY_FOLDER_LEFT,
0751: IPageLayout.LEFT, .25f,
0752: IPageLayout.ID_EDITOR_AREA);
0753: }
0754: stickyFolderLeft.addPlaceholder(id);
0755: break;
0756: case IPageLayout.TOP:
0757: if (stickyFolderTop == null) {
0758: stickyFolderTop = layout.createPlaceholderFolder(
0759: StickyViewDescriptor.STICKY_FOLDER_TOP,
0760: IPageLayout.TOP, .25f,
0761: IPageLayout.ID_EDITOR_AREA);
0762: }
0763: stickyFolderTop.addPlaceholder(id);
0764: break;
0765: case IPageLayout.BOTTOM:
0766: if (stickyFolderBottom == null) {
0767: stickyFolderBottom = layout
0768: .createPlaceholderFolder(
0769: StickyViewDescriptor.STICKY_FOLDER_BOTTOM,
0770: IPageLayout.BOTTOM, .75f,
0771: IPageLayout.ID_EDITOR_AREA);
0772: }
0773: stickyFolderBottom.addPlaceholder(id);
0774: break;
0775: }
0776:
0777: //should never be null as we've just added the view above
0778: IViewLayout viewLayout = layout.getViewLayout(id);
0779: viewLayout.setCloseable(stickyViewDescriptor.isCloseable());
0780: viewLayout.setMoveable(stickyViewDescriptor.isMoveable());
0781: }
0782:
0783: // Run layout engine.
0784: factory.createInitialLayout(layout);
0785: PerspectiveExtensionReader extender = new PerspectiveExtensionReader();
0786: extender.extendLayout(page.getExtensionTracker(), descriptor
0787: .getId(), layout);
0788:
0789: // Retrieve view layout info stored in the page layout.
0790: mapIDtoViewLayoutRec.putAll(layout.getIDtoViewLayoutRecMap());
0791:
0792: // Create action sets.
0793: List temp = new ArrayList();
0794: createInitialActionSets(temp, layout.getActionSets());
0795:
0796: IContextService service = null;
0797: if (page != null) {
0798: service = (IContextService) page.getWorkbenchWindow()
0799: .getService(IContextService.class);
0800: }
0801: try {
0802: if (service != null) {
0803: service.activateContext(ContextAuthority.DEFER_EVENTS);
0804: }
0805: for (Iterator iter = temp.iterator(); iter.hasNext();) {
0806: IActionSetDescriptor descriptor = (IActionSetDescriptor) iter
0807: .next();
0808: addAlwaysOn(descriptor);
0809: }
0810: } finally {
0811: if (service != null) {
0812: service.activateContext(ContextAuthority.SEND_EVENTS);
0813: }
0814: }
0815: newWizardShortcuts = layout.getNewWizardShortcuts();
0816: showViewShortcuts = layout.getShowViewShortcuts();
0817: perspectiveShortcuts = layout.getPerspectiveShortcuts();
0818: showInPartIds = layout.getShowInPartIds();
0819:
0820: // Retrieve fast views
0821: if (fastViewManager != null) {
0822: ArrayList fastViews = layout.getFastViews();
0823: for (Iterator fvIter = fastViews.iterator(); fvIter
0824: .hasNext();) {
0825: IViewReference ref = (IViewReference) fvIter.next();
0826: fastViewManager.addViewReference(
0827: FastViewBar.FASTVIEWBAR_ID, -1, ref, !fvIter
0828: .hasNext());
0829: }
0830: }
0831:
0832: // Is the layout fixed
0833: fixed = layout.isFixed();
0834:
0835: // Create presentation.
0836: presentation = new PerspectiveHelper(page, container, this );
0837:
0838: // Hide editor area if requested by factory
0839: if (!layout.isEditorAreaVisible()) {
0840: hideEditorArea();
0841: }
0842:
0843: }
0844:
0845: private void removeAlwaysOn(IActionSetDescriptor descriptor) {
0846: if (descriptor == null) {
0847: return;
0848: }
0849: if (!alwaysOnActionSets.contains(descriptor)) {
0850: return;
0851: }
0852:
0853: alwaysOnActionSets.remove(descriptor);
0854: if (page != null) {
0855: page.perspectiveActionSetChanged(this , descriptor,
0856: ActionSetManager.CHANGE_HIDE);
0857: }
0858: }
0859:
0860: private void addAlwaysOff(IActionSetDescriptor descriptor) {
0861: if (descriptor == null) {
0862: return;
0863: }
0864: if (alwaysOffActionSets.contains(descriptor)) {
0865: return;
0866: }
0867: alwaysOffActionSets.add(descriptor);
0868: if (page != null) {
0869: page.perspectiveActionSetChanged(this , descriptor,
0870: ActionSetManager.CHANGE_MASK);
0871: }
0872: removeAlwaysOn(descriptor);
0873: }
0874:
0875: private void addAlwaysOn(IActionSetDescriptor descriptor) {
0876: if (descriptor == null) {
0877: return;
0878: }
0879: if (alwaysOnActionSets.contains(descriptor)) {
0880: return;
0881: }
0882: alwaysOnActionSets.add(descriptor);
0883: if (page != null) {
0884: page.perspectiveActionSetChanged(this , descriptor,
0885: ActionSetManager.CHANGE_SHOW);
0886: }
0887: removeAlwaysOff(descriptor);
0888: }
0889:
0890: private void removeAlwaysOff(IActionSetDescriptor descriptor) {
0891: if (descriptor == null) {
0892: return;
0893: }
0894: if (!alwaysOffActionSets.contains(descriptor)) {
0895: return;
0896: }
0897: alwaysOffActionSets.remove(descriptor);
0898: if (page != null) {
0899: page.perspectiveActionSetChanged(this , descriptor,
0900: ActionSetManager.CHANGE_UNMASK);
0901: }
0902: }
0903:
0904: /**
0905: * activate.
0906: */
0907: protected void onActivate() {
0908: // Update editor area state.
0909: if (editorArea.getControl() != null) {
0910: boolean visible = isEditorAreaVisible();
0911: boolean inTrim = editorAreaState == IStackPresentationSite.STATE_MINIMIZED;
0912:
0913: // Funky check: Intro uses the old zoom behaviour when maximized. Make sure we don't show the
0914: // editor if it's supposed to be hidden because the intro is maximized. Note that
0915: // 'childObscuredByZoom' will only respond 'true' when using the old behaviour.
0916: boolean introMaxed = getPresentation().getLayout()
0917: .childObscuredByZoom(editorArea);
0918:
0919: editorArea.setVisible(visible && !inTrim && !introMaxed);
0920: }
0921:
0922: // Update fast views.
0923: // Make sure the control for the fastviews are created so they can
0924: // be activated.
0925: if (fastViewManager != null) {
0926: List fastViews = fastViewManager.getFastViews(null);
0927: for (int i = 0; i < fastViews.size(); i++) {
0928: ViewPane pane = getPane((IViewReference) fastViews
0929: .get(i));
0930: if (pane != null) {
0931: Control ctrl = pane.getControl();
0932: if (ctrl == null) {
0933: pane.createControl(getClientComposite());
0934: ctrl = pane.getControl();
0935: }
0936: ctrl.setEnabled(false); // Remove focus support.
0937: }
0938: }
0939: }
0940:
0941: // Set the visibility of all fast view pins
0942: setAllPinsVisible(true);
0943:
0944: // Trim Stack Support
0945: boolean useNewMinMax = Perspective.useNewMinMax(this );
0946: boolean hideEditorArea = shouldHideEditorsOnActivate
0947: || (editorHidden && editorHolder == null);
0948:
0949: // We have to set the editor area's stack state -before-
0950: // activating the presentation since it's used there to determine
0951: // size of the resulting stack
0952: if (useNewMinMax && !hideEditorArea) {
0953: refreshEditorAreaVisibility();
0954: }
0955:
0956: // Show the layout
0957: presentation.activate(getClientComposite());
0958:
0959: if (useNewMinMax) {
0960: fastViewManager.activate();
0961:
0962: // Move any minimized extension stacks to the trim
0963: if (layout != null) {
0964: // Turn aimations off
0965: IPreferenceStore preferenceStore = PrefUtil
0966: .getAPIPreferenceStore();
0967: boolean useAnimations = preferenceStore
0968: .getBoolean(IWorkbenchPreferenceConstants.ENABLE_ANIMATIONS);
0969: preferenceStore
0970: .setValue(
0971: IWorkbenchPreferenceConstants.ENABLE_ANIMATIONS,
0972: false);
0973:
0974: List minStacks = layout.getMinimizedStacks();
0975: for (Iterator msIter = minStacks.iterator(); msIter
0976: .hasNext();) {
0977: ViewStack vs = (ViewStack) msIter.next();
0978: vs.setMinimized(true);
0979: }
0980:
0981: // Restore the animation pref
0982: preferenceStore
0983: .setValue(
0984: IWorkbenchPreferenceConstants.ENABLE_ANIMATIONS,
0985: useAnimations);
0986:
0987: // this is a one-off deal...set during the extension reading
0988: minStacks.clear();
0989: layout = null;
0990: }
0991: } else {
0992: // Update the FVB only if not using the new min/max
0993: WorkbenchWindow wbw = (WorkbenchWindow) page
0994: .getWorkbenchWindow();
0995: if (wbw != null) {
0996: ITrimManager tbm = wbw.getTrimManager();
0997: if (tbm != null) {
0998: IWindowTrim fvb = tbm
0999: .getTrim(FastViewBar.FASTVIEWBAR_ID);
1000: if (fvb instanceof FastViewBar) {
1001: ((FastViewBar) fvb).update(true);
1002: }
1003: }
1004: }
1005: }
1006:
1007: // If we are -not- using the new min/max then ensure that there
1008: // are no stacks in the trim. This can happen when a user switches
1009: // back to the 3.0 presentation...
1010: if (!Perspective.useNewMinMax(this ) && fastViewManager != null) {
1011: boolean stacksWereRestored = fastViewManager
1012: .restoreAllTrimStacks();
1013: setEditorAreaTrimVisibility(false);
1014:
1015: // Restore any 'maximized' view stack since we've restored
1016: // the minimized stacks
1017: if (stacksWereRestored
1018: && presentation.getMaximizedStack() instanceof ViewStack) {
1019: ViewStack vs = (ViewStack) presentation
1020: .getMaximizedStack();
1021: vs
1022: .setPresentationState(IStackPresentationSite.STATE_RESTORED);
1023: presentation.setMaximizedStack(null);
1024: }
1025: }
1026:
1027: // We hide the editor area -after- the presentation activates
1028: if (hideEditorArea) {
1029: // We do this here to ensure that createPartControl is called on the
1030: // top editor
1031: // before it is hidden. See bug 20166.
1032: hideEditorArea();
1033: shouldHideEditorsOnActivate = false;
1034:
1035: // this is an override so it should handle both states
1036: if (useNewMinMax)
1037: setEditorAreaTrimVisibility(editorAreaState == IStackPresentationSite.STATE_MINIMIZED);
1038: }
1039: }
1040:
1041: /**
1042: * deactivate.
1043: */
1044: protected void onDeactivate() {
1045: presentation.deactivate();
1046: setActiveFastView(null);
1047: setAllPinsVisible(false);
1048:
1049: // Update fast views.
1050: if (fastViewManager != null) {
1051: List fastViews = fastViewManager.getFastViews(null);
1052: for (int i = 0; i < fastViews.size(); i++) {
1053: ViewPane pane = getPane((IViewReference) fastViews
1054: .get(i));
1055: if (pane != null) {
1056: Control ctrl = pane.getControl();
1057: if (ctrl != null) {
1058: ctrl.setEnabled(true); // Add focus support.
1059: }
1060: }
1061: }
1062:
1063: fastViewManager.deActivate();
1064: }
1065:
1066: // Ensure that the editor area trim is hidden as well
1067: setEditorAreaTrimVisibility(false);
1068: }
1069:
1070: /**
1071: * Notifies that a part has been activated.
1072: */
1073: public void partActivated(IWorkbenchPart activePart) {
1074: // If a fastview is open close it.
1075: if (activeFastView != null
1076: && activeFastView.getPart(false) != activePart) {
1077: setActiveFastView(null);
1078: }
1079: }
1080:
1081: /**
1082: * The user successfully performed a Show In... action on the specified part.
1083: * Update the history.
1084: */
1085: public void performedShowIn(String partId) {
1086: showInTimes.put(partId, new Long(System.currentTimeMillis()));
1087: }
1088:
1089: /**
1090: * Sets the fast view attribute. Note: The page is expected to update action
1091: * bars.
1092: */
1093: public void removeFastView(IViewReference ref) {
1094: removeFastView(ref, true);
1095: }
1096:
1097: /**
1098: * Sets the fast view attribute. Note: The page is expected to update action
1099: * bars.
1100: */
1101: public void removeFastView(IViewReference ref, boolean handleLayout) {
1102: ViewPane pane = getPane(ref);
1103:
1104: if (activeFastView == ref) {
1105: setActiveFastView(null);
1106: }
1107:
1108: pane.setFast(false);
1109: Control ctrl = pane.getControl();
1110: if (ctrl != null) {
1111: ctrl.setEnabled(true); // Modify focus support.
1112: }
1113:
1114: if (handleLayout) {
1115: // We are disabling the pane because it will be enabled when it
1116: // is added to the presentation. When a pane is enabled a drop
1117: // listener is added to it, and we do not want to have multiple
1118: // listeners for a pane
1119: presentation.addPart(pane);
1120: }
1121: }
1122:
1123: /**
1124: * Fills a presentation with layout data.
1125: * Note: This method should not modify the current state of the perspective.
1126: */
1127: public IStatus restoreState(IMemento memento) {
1128: MultiStatus result = new MultiStatus(
1129: PlatformUI.PLUGIN_ID,
1130: IStatus.OK,
1131: WorkbenchMessages.Perspective_problemsRestoringPerspective,
1132: null);
1133:
1134: // Create persp descriptor.
1135: descriptor = new PerspectiveDescriptor(null, null, null);
1136: result.add(descriptor.restoreState(memento));
1137: PerspectiveDescriptor desc = (PerspectiveDescriptor) WorkbenchPlugin
1138: .getDefault().getPerspectiveRegistry()
1139: .findPerspectiveWithId(descriptor.getId());
1140: if (desc != null) {
1141: descriptor = desc;
1142: }
1143:
1144: this .memento = memento;
1145: // Add the visible views.
1146: IMemento views[] = memento
1147: .getChildren(IWorkbenchConstants.TAG_VIEW);
1148: result.merge(createReferences(views));
1149:
1150: memento = memento.getChild(IWorkbenchConstants.TAG_FAST_VIEWS);
1151: if (memento != null) {
1152: views = memento.getChildren(IWorkbenchConstants.TAG_VIEW);
1153: result.merge(createReferences(views));
1154: }
1155: return result;
1156: }
1157:
1158: IStatus createReferences(IMemento views[]) {
1159: MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID,
1160: IStatus.OK,
1161: WorkbenchMessages.Perspective_problemsRestoringViews,
1162: null);
1163:
1164: for (int x = 0; x < views.length; x++) {
1165: // Get the view details.
1166: IMemento childMem = views[x];
1167: String id = childMem.getString(IWorkbenchConstants.TAG_ID);
1168: // skip creation of the intro reference - it's handled elsewhere.
1169: if (id.equals(IIntroConstants.INTRO_VIEW_ID)) {
1170: continue;
1171: }
1172:
1173: String secondaryId = ViewFactory.extractSecondaryId(id);
1174: if (secondaryId != null) {
1175: id = ViewFactory.extractPrimaryId(id);
1176: }
1177: // Create and open the view.
1178: try {
1179: if (!"true".equals(childMem.getString(IWorkbenchConstants.TAG_REMOVED))) { //$NON-NLS-1$
1180: viewFactory.createView(id, secondaryId);
1181: }
1182: } catch (PartInitException e) {
1183: childMem.putString(IWorkbenchConstants.TAG_REMOVED,
1184: "true"); //$NON-NLS-1$
1185: result.add(StatusUtil.newStatus(IStatus.ERROR, e
1186: .getMessage() == null ? "" : e.getMessage(), //$NON-NLS-1$
1187: e));
1188: }
1189: }
1190: return result;
1191: }
1192:
1193: /**
1194: * Fills a presentation with layout data.
1195: * Note: This method should not modify the current state of the perspective.
1196: */
1197: public IStatus restoreState() {
1198: if (this .memento == null) {
1199: return new Status(IStatus.OK, PlatformUI.PLUGIN_ID, 0,
1200: "", null); //$NON-NLS-1$
1201: }
1202:
1203: MultiStatus result = new MultiStatus(
1204: PlatformUI.PLUGIN_ID,
1205: IStatus.OK,
1206: WorkbenchMessages.Perspective_problemsRestoringPerspective,
1207: null);
1208:
1209: IMemento memento = this .memento;
1210: this .memento = null;
1211:
1212: final IMemento boundsMem = memento
1213: .getChild(IWorkbenchConstants.TAG_WINDOW);
1214: if (boundsMem != null) {
1215: final Rectangle r = new Rectangle(0, 0, 0, 0);
1216: r.x = boundsMem.getInteger(IWorkbenchConstants.TAG_X)
1217: .intValue();
1218: r.y = boundsMem.getInteger(IWorkbenchConstants.TAG_Y)
1219: .intValue();
1220: r.height = boundsMem.getInteger(
1221: IWorkbenchConstants.TAG_HEIGHT).intValue();
1222: r.width = boundsMem.getInteger(
1223: IWorkbenchConstants.TAG_WIDTH).intValue();
1224: StartupThreading
1225: .runWithoutExceptions(new StartupRunnable() {
1226:
1227: public void runWithException() throws Throwable {
1228: if (page.getWorkbenchWindow().getPages().length == 0) {
1229: page.getWorkbenchWindow().getShell()
1230: .setBounds(r);
1231: }
1232: }
1233: });
1234:
1235: }
1236:
1237: // Create an empty presentation..
1238: final PerspectiveHelper[] presArray = new PerspectiveHelper[1];
1239: StartupThreading.runWithoutExceptions(new StartupRunnable() {
1240:
1241: public void runWithException() throws Throwable {
1242: ViewSashContainer mainLayout = new ViewSashContainer(
1243: page, getClientComposite());
1244: presArray[0] = new PerspectiveHelper(page, mainLayout,
1245: Perspective.this );
1246: }
1247: });
1248: final PerspectiveHelper pres = presArray[0];
1249:
1250: // Read the layout.
1251: result.merge(pres.restoreState(memento
1252: .getChild(IWorkbenchConstants.TAG_LAYOUT)));
1253:
1254: StartupThreading.runWithoutExceptions(new StartupRunnable() {
1255:
1256: public void runWithException() throws Throwable {
1257: // Add the editor workbook. Do not hide it now.
1258: pres.replacePlaceholderWithPart(editorArea);
1259: }
1260: });
1261:
1262: // Add the visible views.
1263: IMemento[] views = memento
1264: .getChildren(IWorkbenchConstants.TAG_VIEW);
1265:
1266: for (int x = 0; x < views.length; x++) {
1267: // Get the view details.
1268: IMemento childMem = views[x];
1269: String id = childMem.getString(IWorkbenchConstants.TAG_ID);
1270: String secondaryId = ViewFactory.extractSecondaryId(id);
1271: if (secondaryId != null) {
1272: id = ViewFactory.extractPrimaryId(id);
1273: }
1274:
1275: // skip the intro as it is restored higher up in workbench.
1276: if (id.equals(IIntroConstants.INTRO_VIEW_ID)) {
1277: continue;
1278: }
1279:
1280: // Create and open the view.
1281: IViewReference viewRef = viewFactory.getView(id,
1282: secondaryId);
1283: WorkbenchPartReference ref = (WorkbenchPartReference) viewRef;
1284:
1285: // report error
1286: if (ref == null) {
1287: String key = ViewFactory.getKey(id, secondaryId);
1288: result
1289: .add(new Status(
1290: IStatus.ERROR,
1291: PlatformUI.PLUGIN_ID,
1292: 0,
1293: NLS
1294: .bind(
1295: WorkbenchMessages.Perspective_couldNotFind,
1296: key), null));
1297: continue;
1298: }
1299: boolean willPartBeVisible = pres.willPartBeVisible(ref
1300: .getId(), secondaryId);
1301: if (willPartBeVisible) {
1302: IViewPart view = (IViewPart) ref.getPart(true);
1303: if (view != null) {
1304: ViewSite site = (ViewSite) view.getSite();
1305: ViewPane pane = (ViewPane) site.getPane();
1306: pres.replacePlaceholderWithPart(pane);
1307: }
1308: } else {
1309: pres.replacePlaceholderWithPart(ref.getPane());
1310: }
1311: }
1312:
1313: // Load the fast views
1314: if (fastViewManager != null)
1315: fastViewManager.restoreState(memento, result);
1316:
1317: // Load the view layout recs
1318: IMemento[] recMementos = memento
1319: .getChildren(IWorkbenchConstants.TAG_VIEW_LAYOUT_REC);
1320: for (int i = 0; i < recMementos.length; i++) {
1321: IMemento recMemento = recMementos[i];
1322: String compoundId = recMemento
1323: .getString(IWorkbenchConstants.TAG_ID);
1324: if (compoundId != null) {
1325: ViewLayoutRec rec = getViewLayoutRec(compoundId, true);
1326: if (IWorkbenchConstants.FALSE.equals(recMemento
1327: .getString(IWorkbenchConstants.TAG_CLOSEABLE))) {
1328: rec.isCloseable = false;
1329: }
1330: if (IWorkbenchConstants.FALSE.equals(recMemento
1331: .getString(IWorkbenchConstants.TAG_MOVEABLE))) {
1332: rec.isMoveable = false;
1333: }
1334: if (IWorkbenchConstants.TRUE.equals(recMemento
1335: .getString(IWorkbenchConstants.TAG_STANDALONE))) {
1336: rec.isStandalone = true;
1337: rec.showTitle = !IWorkbenchConstants.FALSE
1338: .equals(recMemento
1339: .getString(IWorkbenchConstants.TAG_SHOW_TITLE));
1340: }
1341: }
1342: }
1343:
1344: final IContextService service = (IContextService) page
1345: .getWorkbenchWindow().getService(IContextService.class);
1346: try { // one big try block, don't kill me here
1347: // defer context events
1348: if (service != null) {
1349: service.activateContext(ContextAuthority.DEFER_EVENTS);
1350: }
1351:
1352: HashSet knownActionSetIds = new HashSet();
1353:
1354: // Load the always on action sets.
1355: IMemento[] actions = memento
1356: .getChildren(IWorkbenchConstants.TAG_ALWAYS_ON_ACTION_SET);
1357: for (int x = 0; x < actions.length; x++) {
1358: String actionSetID = actions[x]
1359: .getString(IWorkbenchConstants.TAG_ID);
1360: final IActionSetDescriptor d = WorkbenchPlugin
1361: .getDefault().getActionSetRegistry()
1362: .findActionSet(actionSetID);
1363: if (d != null) {
1364: StartupThreading
1365: .runWithoutExceptions(new StartupRunnable() {
1366: public void runWithException()
1367: throws Throwable {
1368: addAlwaysOn(d);
1369: }
1370: });
1371:
1372: knownActionSetIds.add(actionSetID);
1373: }
1374: }
1375:
1376: // Load the always off action sets.
1377: actions = memento
1378: .getChildren(IWorkbenchConstants.TAG_ALWAYS_OFF_ACTION_SET);
1379: for (int x = 0; x < actions.length; x++) {
1380: String actionSetID = actions[x]
1381: .getString(IWorkbenchConstants.TAG_ID);
1382: final IActionSetDescriptor d = WorkbenchPlugin
1383: .getDefault().getActionSetRegistry()
1384: .findActionSet(actionSetID);
1385: if (d != null) {
1386: StartupThreading
1387: .runWithoutExceptions(new StartupRunnable() {
1388: public void runWithException()
1389: throws Throwable {
1390: addAlwaysOff(d);
1391: }
1392: });
1393: knownActionSetIds.add(actionSetID);
1394: }
1395: }
1396:
1397: // Load "show view actions".
1398: actions = memento
1399: .getChildren(IWorkbenchConstants.TAG_SHOW_VIEW_ACTION);
1400: showViewShortcuts = new ArrayList(actions.length);
1401: for (int x = 0; x < actions.length; x++) {
1402: String id = actions[x]
1403: .getString(IWorkbenchConstants.TAG_ID);
1404: showViewShortcuts.add(id);
1405: }
1406:
1407: // Load "show in times".
1408: actions = memento
1409: .getChildren(IWorkbenchConstants.TAG_SHOW_IN_TIME);
1410: for (int x = 0; x < actions.length; x++) {
1411: String id = actions[x]
1412: .getString(IWorkbenchConstants.TAG_ID);
1413: String timeStr = actions[x]
1414: .getString(IWorkbenchConstants.TAG_TIME);
1415: if (id != null && timeStr != null) {
1416: try {
1417: long time = Long.parseLong(timeStr);
1418: showInTimes.put(id, new Long(time));
1419: } catch (NumberFormatException e) {
1420: // skip this one
1421: }
1422: }
1423: }
1424:
1425: // Load "show in parts" from registry, not memento
1426: showInPartIds = getShowInIdsFromRegistry();
1427:
1428: // Load "new wizard actions".
1429: actions = memento
1430: .getChildren(IWorkbenchConstants.TAG_NEW_WIZARD_ACTION);
1431: newWizardShortcuts = new ArrayList(actions.length);
1432: for (int x = 0; x < actions.length; x++) {
1433: String id = actions[x]
1434: .getString(IWorkbenchConstants.TAG_ID);
1435: newWizardShortcuts.add(id);
1436: }
1437:
1438: // Load "perspective actions".
1439: actions = memento
1440: .getChildren(IWorkbenchConstants.TAG_PERSPECTIVE_ACTION);
1441: perspectiveShortcuts = new ArrayList(actions.length);
1442: for (int x = 0; x < actions.length; x++) {
1443: String id = actions[x]
1444: .getString(IWorkbenchConstants.TAG_ID);
1445: perspectiveShortcuts.add(id);
1446: }
1447:
1448: ArrayList extActionSets = getPerspectiveExtensionActionSets();
1449: for (int i = 0; i < extActionSets.size(); i++) {
1450: String actionSetID = (String) extActionSets.get(i);
1451: if (knownActionSetIds.contains(actionSetID)) {
1452: continue;
1453: }
1454: final IActionSetDescriptor d = WorkbenchPlugin
1455: .getDefault().getActionSetRegistry()
1456: .findActionSet(actionSetID);
1457: if (d != null) {
1458: StartupThreading
1459: .runWithoutExceptions(new StartupRunnable() {
1460: public void runWithException()
1461: throws Throwable {
1462: addAlwaysOn(d);
1463: }
1464: });
1465: knownActionSetIds.add(d.getId());
1466: }
1467: }
1468:
1469: // Add the visible set of action sets to our knownActionSetIds
1470: // Now go through the registry to ensure we pick up any new action
1471: // sets
1472: // that have been added but not yet considered by this perspective.
1473: ActionSetRegistry reg = WorkbenchPlugin.getDefault()
1474: .getActionSetRegistry();
1475: IActionSetDescriptor[] array = reg.getActionSets();
1476: int count = array.length;
1477: for (int i = 0; i < count; i++) {
1478: IActionSetDescriptor desc = array[i];
1479: if ((!knownActionSetIds.contains(desc.getId()))
1480: && (desc.isInitiallyVisible())) {
1481: addActionSet(desc);
1482: }
1483: }
1484: } finally {
1485: // restart context changes
1486: if (service != null) {
1487: StartupThreading
1488: .runWithoutExceptions(new StartupRunnable() {
1489: public void runWithException()
1490: throws Throwable {
1491: service
1492: .activateContext(ContextAuthority.SEND_EVENTS);
1493: }
1494: });
1495: }
1496: }
1497:
1498: // Save presentation.
1499: presentation = pres;
1500:
1501: // Hide the editor area if needed. Need to wait for the
1502: // presentation to be fully setup first.
1503: Integer areaVisible = memento
1504: .getInteger(IWorkbenchConstants.TAG_AREA_VISIBLE);
1505: // Rather than hiding the editors now we must wait until after their
1506: // controls
1507: // are created. This ensures that if an editor is instantiated,
1508: // createPartControl
1509: // is also called. See bug 20166.
1510: shouldHideEditorsOnActivate = (areaVisible != null && areaVisible
1511: .intValue() == 0);
1512:
1513: // Restore the trim state of the editor area
1514: IPreferenceStore preferenceStore = PrefUtil
1515: .getAPIPreferenceStore();
1516: boolean useNewMinMax = preferenceStore
1517: .getBoolean(IWorkbenchPreferenceConstants.ENABLE_NEW_MIN_MAX);
1518: if (useNewMinMax) {
1519: Integer trimStateInt = memento
1520: .getInteger(IWorkbenchConstants.TAG_AREA_TRIM_STATE);
1521: if (trimStateInt != null) {
1522: editorAreaState = trimStateInt.intValue() & 0x3; // low order two bits contain the state
1523: editorAreaRestoreOnUnzoom = (trimStateInt.intValue() & 4) != 0;
1524: }
1525: }
1526:
1527: // restore the fixed state
1528: Integer isFixed = memento
1529: .getInteger(IWorkbenchConstants.TAG_FIXED);
1530: fixed = (isFixed != null && isFixed.intValue() == 1);
1531:
1532: return result;
1533: }
1534:
1535: /**
1536: * Restores a fast view to its corrent presentation structure.
1537: * This method is pubilc because the FastViewManager uses it to
1538: * reconstruct it minimized stacks on startup.
1539: *
1540: * @param fvMemento The mement containing the fast view info
1541: * @param result The result status
1542: * @return The reference to the restored view
1543: */
1544: public IViewReference restoreFastView(IMemento fvMemento,
1545: MultiStatus result) {
1546: String viewID = fvMemento.getString(IWorkbenchConstants.TAG_ID);
1547: String secondaryId = ViewFactory.extractSecondaryId(viewID);
1548: if (secondaryId != null) {
1549: viewID = ViewFactory.extractPrimaryId(viewID);
1550: }
1551:
1552: IViewReference viewRef = getViewReference(viewID, secondaryId);
1553: if (viewRef == null) {
1554: String key = ViewFactory.getKey(viewID, secondaryId);
1555: WorkbenchPlugin
1556: .log("Could not create view: '" + key + "'."); //$NON-NLS-1$ //$NON-NLS-2$
1557: result.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID,
1558: 0, NLS.bind(
1559: WorkbenchMessages.Perspective_couldNotFind,
1560: key), null));
1561: return null;
1562: }
1563:
1564: // Restore fast view width ratio
1565: Float ratio = fvMemento.getFloat(IWorkbenchConstants.TAG_RATIO);
1566: if (ratio == null) {
1567: Integer viewWidth = fvMemento
1568: .getInteger(IWorkbenchConstants.TAG_WIDTH);
1569: if (viewWidth == null) {
1570: ratio = new Float(IPageLayout.DEFAULT_FASTVIEW_RATIO);
1571: } else {
1572: ratio = new Float((float) viewWidth.intValue()
1573: / (float) getClientComposite().getSize().x);
1574: }
1575: }
1576: ViewLayoutRec rec = getViewLayoutRec(viewRef, true);
1577: rec.fastViewWidthRatio = ratio.floatValue();
1578:
1579: return viewRef;
1580: }
1581:
1582: /**
1583: * Returns the ActionSets read from perspectiveExtensions in the registry.
1584: */
1585: private ArrayList getPerspectiveExtensionActionSets() {
1586: PerspectiveExtensionReader reader = new PerspectiveExtensionReader();
1587: reader
1588: .setIncludeOnlyTags(new String[] { IWorkbenchRegistryConstants.TAG_ACTION_SET });
1589: PageLayout layout = new PageLayout();
1590: reader.extendLayout(null, descriptor.getOriginalId(), layout);
1591: return layout.getActionSets();
1592: }
1593:
1594: /**
1595: * Returns the Show In... part ids read from the registry.
1596: */
1597: private ArrayList getShowInIdsFromRegistry() {
1598: PerspectiveExtensionReader reader = new PerspectiveExtensionReader();
1599: reader
1600: .setIncludeOnlyTags(new String[] { IWorkbenchRegistryConstants.TAG_SHOW_IN_PART });
1601: PageLayout layout = new PageLayout();
1602: reader.extendLayout(null, descriptor.getOriginalId(), layout);
1603: return layout.getShowInPartIds();
1604: }
1605:
1606: /**
1607: * Save the layout.
1608: */
1609: public void saveDesc() {
1610: saveDescAs(descriptor);
1611: }
1612:
1613: /**
1614: * Save the layout.
1615: */
1616: public void saveDescAs(IPerspectiveDescriptor desc) {
1617: PerspectiveDescriptor realDesc = (PerspectiveDescriptor) desc;
1618: //get the layout from the registry
1619: PerspectiveRegistry perspRegistry = (PerspectiveRegistry) WorkbenchPlugin
1620: .getDefault().getPerspectiveRegistry();
1621: // Capture the layout state.
1622: XMLMemento memento = XMLMemento.createWriteRoot("perspective");//$NON-NLS-1$
1623: IStatus status = saveState(memento, realDesc, false);
1624: if (status.getSeverity() == IStatus.ERROR) {
1625: ErrorDialog.openError((Shell) null,
1626: WorkbenchMessages.Perspective_problemSavingTitle,
1627: WorkbenchMessages.Perspective_problemSavingMessage,
1628: status);
1629: return;
1630: }
1631: //save it to the preference store
1632: try {
1633: perspRegistry.saveCustomPersp(realDesc, memento);
1634: descriptor = realDesc;
1635: } catch (IOException e) {
1636: perspRegistry.deletePerspective(realDesc);
1637: MessageDialog.openError((Shell) null,
1638: WorkbenchMessages.Perspective_problemSavingTitle,
1639: WorkbenchMessages.Perspective_problemSavingMessage);
1640: }
1641: }
1642:
1643: /**
1644: * Save the layout.
1645: */
1646: public IStatus saveState(IMemento memento) {
1647: MultiStatus result = new MultiStatus(
1648: PlatformUI.PLUGIN_ID,
1649: IStatus.OK,
1650: WorkbenchMessages.Perspective_problemsSavingPerspective,
1651: null);
1652:
1653: result.merge(saveState(memento, descriptor, true));
1654:
1655: return result;
1656: }
1657:
1658: /**
1659: * Save the layout.
1660: */
1661: private IStatus saveState(IMemento memento,
1662: PerspectiveDescriptor p, boolean saveInnerViewState) {
1663: MultiStatus result = new MultiStatus(
1664: PlatformUI.PLUGIN_ID,
1665: IStatus.OK,
1666: WorkbenchMessages.Perspective_problemsSavingPerspective,
1667: null);
1668:
1669: if (this .memento != null) {
1670: memento.putMemento(this .memento);
1671: return result;
1672: }
1673:
1674: // Save the version number.
1675: memento.putString(IWorkbenchConstants.TAG_VERSION,
1676: VERSION_STRING);
1677: result.add(p.saveState(memento));
1678: if (!saveInnerViewState) {
1679: Rectangle bounds = page.getWorkbenchWindow().getShell()
1680: .getBounds();
1681: IMemento boundsMem = memento
1682: .createChild(IWorkbenchConstants.TAG_WINDOW);
1683: boundsMem.putInteger(IWorkbenchConstants.TAG_X, bounds.x);
1684: boundsMem.putInteger(IWorkbenchConstants.TAG_Y, bounds.y);
1685: boundsMem.putInteger(IWorkbenchConstants.TAG_HEIGHT,
1686: bounds.height);
1687: boundsMem.putInteger(IWorkbenchConstants.TAG_WIDTH,
1688: bounds.width);
1689: }
1690:
1691: // Save the "always on" action sets.
1692: Iterator itr = alwaysOnActionSets.iterator();
1693: while (itr.hasNext()) {
1694: IActionSetDescriptor desc = (IActionSetDescriptor) itr
1695: .next();
1696: IMemento child = memento
1697: .createChild(IWorkbenchConstants.TAG_ALWAYS_ON_ACTION_SET);
1698: child.putString(IWorkbenchConstants.TAG_ID, desc.getId());
1699: }
1700:
1701: // Save the "always off" action sets.
1702: itr = alwaysOffActionSets.iterator();
1703: while (itr.hasNext()) {
1704: IActionSetDescriptor desc = (IActionSetDescriptor) itr
1705: .next();
1706: IMemento child = memento
1707: .createChild(IWorkbenchConstants.TAG_ALWAYS_OFF_ACTION_SET);
1708: child.putString(IWorkbenchConstants.TAG_ID, desc.getId());
1709: }
1710:
1711: // Save "show view actions"
1712: itr = showViewShortcuts.iterator();
1713: while (itr.hasNext()) {
1714: String str = (String) itr.next();
1715: IMemento child = memento
1716: .createChild(IWorkbenchConstants.TAG_SHOW_VIEW_ACTION);
1717: child.putString(IWorkbenchConstants.TAG_ID, str);
1718: }
1719:
1720: // Save "show in times"
1721: itr = showInTimes.keySet().iterator();
1722: while (itr.hasNext()) {
1723: String id = (String) itr.next();
1724: Long time = (Long) showInTimes.get(id);
1725: IMemento child = memento
1726: .createChild(IWorkbenchConstants.TAG_SHOW_IN_TIME);
1727: child.putString(IWorkbenchConstants.TAG_ID, id);
1728: child.putString(IWorkbenchConstants.TAG_TIME, time
1729: .toString());
1730: }
1731:
1732: // Save "new wizard actions".
1733: itr = newWizardShortcuts.iterator();
1734: while (itr.hasNext()) {
1735: String str = (String) itr.next();
1736: IMemento child = memento
1737: .createChild(IWorkbenchConstants.TAG_NEW_WIZARD_ACTION);
1738: child.putString(IWorkbenchConstants.TAG_ID, str);
1739: }
1740:
1741: // Save "perspective actions".
1742: itr = perspectiveShortcuts.iterator();
1743: while (itr.hasNext()) {
1744: String str = (String) itr.next();
1745: IMemento child = memento
1746: .createChild(IWorkbenchConstants.TAG_PERSPECTIVE_ACTION);
1747: child.putString(IWorkbenchConstants.TAG_ID, str);
1748: }
1749:
1750: // Get visible views.
1751: List viewPanes = new ArrayList(5);
1752: presentation.collectViewPanes(viewPanes);
1753:
1754: // Save the views.
1755: itr = viewPanes.iterator();
1756: int errors = 0;
1757: while (itr.hasNext()) {
1758: ViewPane pane = (ViewPane) itr.next();
1759: IViewReference ref = pane.getViewReference();
1760: IMemento viewMemento = memento
1761: .createChild(IWorkbenchConstants.TAG_VIEW);
1762: viewMemento.putString(IWorkbenchConstants.TAG_ID,
1763: ViewFactory.getKey(ref));
1764: }
1765:
1766: // save all fastview state
1767: if (fastViewManager != null)
1768: fastViewManager.saveState(memento);
1769:
1770: // Save the view layout recs.
1771: for (Iterator i = mapIDtoViewLayoutRec.keySet().iterator(); i
1772: .hasNext();) {
1773: String compoundId = (String) i.next();
1774: ViewLayoutRec rec = (ViewLayoutRec) mapIDtoViewLayoutRec
1775: .get(compoundId);
1776: if (rec != null
1777: && (!rec.isCloseable || !rec.isMoveable || rec.isStandalone)) {
1778: IMemento layoutMemento = memento
1779: .createChild(IWorkbenchConstants.TAG_VIEW_LAYOUT_REC);
1780: layoutMemento.putString(IWorkbenchConstants.TAG_ID,
1781: compoundId);
1782: if (!rec.isCloseable) {
1783: layoutMemento.putString(
1784: IWorkbenchConstants.TAG_CLOSEABLE,
1785: IWorkbenchConstants.FALSE);
1786: }
1787: if (!rec.isMoveable) {
1788: layoutMemento.putString(
1789: IWorkbenchConstants.TAG_MOVEABLE,
1790: IWorkbenchConstants.FALSE);
1791: }
1792: if (rec.isStandalone) {
1793: layoutMemento.putString(
1794: IWorkbenchConstants.TAG_STANDALONE,
1795: IWorkbenchConstants.TRUE);
1796: layoutMemento.putString(
1797: IWorkbenchConstants.TAG_SHOW_TITLE, String
1798: .valueOf(rec.showTitle));
1799: }
1800: }
1801: }
1802:
1803: if (errors > 0) {
1804: String message = WorkbenchMessages.Perspective_multipleErrors;
1805: if (errors == 1) {
1806: message = WorkbenchMessages.Perspective_oneError;
1807: }
1808: MessageDialog.openError(null, WorkbenchMessages.Error,
1809: message);
1810: }
1811:
1812: // Save the layout.
1813: IMemento childMem = memento
1814: .createChild(IWorkbenchConstants.TAG_LAYOUT);
1815: result.add(presentation.saveState(childMem));
1816:
1817: // Save the editor visibility state
1818: if (isEditorAreaVisible()) {
1819: memento.putInteger(IWorkbenchConstants.TAG_AREA_VISIBLE, 1);
1820: } else {
1821: memento.putInteger(IWorkbenchConstants.TAG_AREA_VISIBLE, 0);
1822: }
1823:
1824: // Save the trim state of the editor area if using the new min/max
1825: IPreferenceStore preferenceStore = PrefUtil
1826: .getAPIPreferenceStore();
1827: boolean useNewMinMax = preferenceStore
1828: .getBoolean(IWorkbenchPreferenceConstants.ENABLE_NEW_MIN_MAX);
1829: if (useNewMinMax) {
1830: int trimState = editorAreaState;
1831: trimState |= editorAreaRestoreOnUnzoom ? 4 : 0;
1832: memento.putInteger(IWorkbenchConstants.TAG_AREA_TRIM_STATE,
1833: trimState);
1834: }
1835:
1836: // Save the fixed state
1837: if (fixed) {
1838: memento.putInteger(IWorkbenchConstants.TAG_FIXED, 1);
1839: } else {
1840: memento.putInteger(IWorkbenchConstants.TAG_FIXED, 0);
1841: }
1842:
1843: return result;
1844: }
1845:
1846: public void turnOnActionSets(IActionSetDescriptor[] newArray) {
1847: for (int i = 0; i < newArray.length; i++) {
1848: IActionSetDescriptor descriptor = newArray[i];
1849:
1850: addAlwaysOn(descriptor);
1851: }
1852: }
1853:
1854: public void turnOffActionSets(IActionSetDescriptor[] toDisable) {
1855: for (int i = 0; i < toDisable.length; i++) {
1856: IActionSetDescriptor descriptor = toDisable[i];
1857:
1858: turnOffActionSet(descriptor);
1859: }
1860: }
1861:
1862: public void turnOffActionSet(IActionSetDescriptor toDisable) {
1863: addAlwaysOff(toDisable);
1864: }
1865:
1866: /**
1867: * Return the active fast view or null if there are no
1868: * fast views or if there are all minimized.
1869: */
1870: public IViewReference getActiveFastView() {
1871: return activeFastView;
1872: }
1873:
1874: /**
1875: * Sets the active fast view. If a different fast view is already open,
1876: * it shrinks equally <code>steps</code> times before disappearing
1877: * completely. Then, <code>view</code> becomes active and is shown.
1878: */
1879: /*package*/void setActiveFastView(IViewReference ref, int steps) {
1880: if (activeFastView == ref) {
1881: return;
1882: }
1883:
1884: if (activeFastView != null) {
1885: ViewPane pane = getPane(activeFastView);
1886: if (pane != null) {
1887: if (pane.isZoomed()) {
1888: presentation.zoomOut();
1889: }
1890: hideFastView(activeFastView, steps);
1891: }
1892: }
1893: activeFastView = ref;
1894: try {
1895: if (activeFastView != null) {
1896: if (!showFastView(activeFastView)) {
1897: activeFastView = null;
1898: }
1899: }
1900: } catch (RuntimeException e) {
1901: activeFastView = null;
1902: }
1903: }
1904:
1905: /**
1906: * Sets the active fast view.
1907: */
1908: /*package*/void setActiveFastView(IViewReference ref) {
1909: setActiveFastView(ref, FASTVIEW_HIDE_STEPS);
1910: }
1911:
1912: /**
1913: * Sets the visibility of all fast view pins.
1914: */
1915: private void setAllPinsVisible(boolean visible) {
1916: if (fastViewManager == null)
1917: return;
1918:
1919: Iterator iter = fastViewManager.getFastViews(null).iterator();
1920: while (iter.hasNext()) {
1921: ViewPane pane = getPane((IViewReference) iter.next());
1922: if (pane != null) {
1923: pane.setFast(visible);
1924: }
1925: }
1926: }
1927:
1928: /**
1929: * Sets the selection for the shortcut bar icon representing the givevn fast view.
1930: */
1931: private void setFastViewIconSelection(IViewReference ref,
1932: boolean selected) {
1933: if (fastViewManager == null)
1934: return;
1935:
1936: fastViewManager.setFastViewIconSelection(ref, selected);
1937: }
1938:
1939: /**
1940: * Sets the new wizard actions for the page.
1941: * This is List of Strings.
1942: */
1943: public void setNewWizardActionIds(ArrayList newList) {
1944: newWizardShortcuts = newList;
1945: }
1946:
1947: /**
1948: * Sets the perspective actions for this page.
1949: * This is List of Strings.
1950: */
1951: public void setPerspectiveActionIds(ArrayList list) {
1952: perspectiveShortcuts = list;
1953: }
1954:
1955: /**
1956: * Sets the ids of the parts to list in the Show In... prompter.
1957: * This is a List of Strings.
1958: */
1959: public void setShowInPartIds(ArrayList list) {
1960: showInPartIds = list;
1961: }
1962:
1963: /**
1964: * Sets the ids of the views to list in the Show View shortcuts.
1965: * This is a List of Strings.
1966: */
1967: public void setShowViewActionIds(ArrayList list) {
1968: showViewShortcuts = list;
1969: }
1970:
1971: /**
1972: * Show the editor area if not visible
1973: */
1974: protected void showEditorArea() {
1975: if (isEditorAreaVisible()) {
1976: return;
1977: }
1978:
1979: editorHidden = false;
1980:
1981: // Show the editor in the appropriate location
1982: if (useNewMinMax(this )) {
1983: boolean isMinimized = editorAreaState == IStackPresentationSite.STATE_MINIMIZED;
1984: if (!isMinimized) {
1985: // If the editor area is going to show then we have to restore
1986: if (getPresentation().getMaximizedStack() != null)
1987: getPresentation().getMaximizedStack().setState(
1988: IStackPresentationSite.STATE_RESTORED);
1989:
1990: showEditorAreaLocal();
1991: } else
1992: setEditorAreaTrimVisibility(true);
1993: } else {
1994: showEditorAreaLocal();
1995: }
1996: }
1997:
1998: /**
1999: * Show the editor area if not visible
2000: */
2001: protected void showEditorAreaLocal() {
2002: if (editorHolder == null || editorHidden) {
2003: return;
2004: }
2005:
2006: // Replace the part holder with the editor area.
2007: presentation.getLayout().replace(editorHolder, editorArea);
2008: editorHolder = null;
2009: }
2010:
2011: private EditorAreaTrimToolBar getEditorAreaTrim(
2012: boolean createIfNecessary) {
2013: WorkbenchWindow wbw = (WorkbenchWindow) page
2014: .getWorkbenchWindow();
2015: ITrimManager tbm = wbw.getTrimManager();
2016: if (tbm == null)
2017: return null;
2018:
2019: // Create if necesary
2020: EditorAreaTrimToolBar editorAreaTrim = (EditorAreaTrimToolBar) tbm
2021: .getTrim(IPageLayout.ID_EDITOR_AREA);
2022: if (editorAreaTrim == null && createIfNecessary) {
2023: int suggestedSide = SWT.RIGHT;
2024: int cachedSide = ((TrimLayout) tbm)
2025: .getPreferredArea(IPageLayout.ID_EDITOR_AREA);
2026: if (cachedSide != -1)
2027: suggestedSide = cachedSide;
2028:
2029: IWindowTrim beforeMe = ((TrimLayout) tbm)
2030: .getPreferredLocation(IPageLayout.ID_EDITOR_AREA);
2031:
2032: // Gain access to the trim manager
2033: editorAreaTrim = new EditorAreaTrimToolBar(wbw, editorArea);
2034: editorAreaTrim.dock(suggestedSide);
2035: tbm.addTrim(suggestedSide, editorAreaTrim, beforeMe);
2036: }
2037:
2038: return editorAreaTrim;
2039: }
2040:
2041: public void setEditorAreaState(int newState) {
2042: if (newState == editorAreaState)
2043: return;
2044:
2045: editorAreaState = newState;
2046:
2047: // reset the restore flag if we're not minimized
2048: if (newState != IStackPresentationSite.STATE_MINIMIZED)
2049: editorAreaRestoreOnUnzoom = false;
2050:
2051: refreshEditorAreaVisibility();
2052: }
2053:
2054: public int getEditorAreaState() {
2055: return editorAreaState;
2056: }
2057:
2058: /**
2059: *
2060: */
2061: public void refreshEditorAreaVisibility() {
2062: // Nothing shows up if the editor area isn't visible at all
2063: if (editorHidden) {
2064: hideEditorAreaLocal();
2065: setEditorAreaTrimVisibility(false);
2066: return;
2067: }
2068:
2069: EditorStack editorStack = ((EditorSashContainer) editorArea)
2070: .getUpperRightEditorStack(null);
2071: if (editorStack == null)
2072: return;
2073:
2074: // Whatever we're doing, make the current editor stack match it
2075: editorStack.setStateLocal(editorAreaState);
2076:
2077: // If it's minimized then it's in the trim
2078: if (editorAreaState == IStackPresentationSite.STATE_MINIMIZED) {
2079: // Hide the editor area and show its trim
2080: hideEditorAreaLocal();
2081: setEditorAreaTrimVisibility(true);
2082: } else {
2083: // Show the editor area and hide its trim
2084: setEditorAreaTrimVisibility(false);
2085: showEditorAreaLocal();
2086:
2087: if (editorAreaState == IStackPresentationSite.STATE_MAXIMIZED)
2088: getPresentation().setMaximizedStack(editorStack);
2089: }
2090: }
2091:
2092: protected EditorAreaTrimToolBar setEditorAreaTrimVisibility(
2093: boolean visible) {
2094: WorkbenchWindow wbw = (WorkbenchWindow) page
2095: .getWorkbenchWindow();
2096: ITrimManager tbm = wbw.getTrimManager();
2097: if (tbm == null)
2098: return null;
2099:
2100: // Only create the trim element if it's going to be visible
2101: EditorAreaTrimToolBar editorAreaTrim = getEditorAreaTrim(visible);
2102: if (editorAreaTrim == null)
2103: return null;
2104:
2105: tbm.setTrimVisible(editorAreaTrim, visible);
2106: tbm.forceLayout();
2107:
2108: return editorAreaTrim;
2109: }
2110:
2111: /**
2112: * Shows a fast view.
2113: * @return whether the view was successfully shown
2114: */
2115: boolean showFastView(IViewReference ref) {
2116: if (fastViewManager == null)
2117: return false;
2118:
2119: // Make sure the part is restored.
2120: IWorkbenchPart refPart = ref.getPart(true);
2121: if (refPart == null) {
2122: return false;
2123: }
2124:
2125: ViewPane pane = getPane(ref);
2126: if (pane == null) {
2127: return false;
2128: }
2129:
2130: saveFastViewWidthRatio();
2131:
2132: // Special check to ensure that a 'minimized' intro view shows
2133: // as 'standby'
2134: if (ref.getId().equals("org.eclipse.ui.internal.introview")) { //$NON-NLS-1$
2135: if (refPart instanceof ViewIntroAdapterPart) {
2136: ((ViewIntroAdapterPart) refPart).setStandby(true);
2137: }
2138: }
2139:
2140: // Determine the display orientation
2141: int side = fastViewManager.getViewSide(ref);
2142: fastViewPane.showView(getClientComposite(), pane, side,
2143: getFastViewWidthRatio(ref));
2144:
2145: setFastViewIconSelection(ref, true);
2146:
2147: return true;
2148: }
2149:
2150: private void saveFastViewWidthRatio() {
2151: ViewPane pane = fastViewPane.getCurrentPane();
2152: if (pane != null) {
2153: ViewLayoutRec rec = getViewLayoutRec(pane
2154: .getViewReference(), true);
2155: rec.fastViewWidthRatio = fastViewPane.getCurrentRatio();
2156: }
2157: }
2158:
2159: /**
2160: * Resolves a view's id into its reference, creating the
2161: * view if necessary.
2162: *
2163: * @param viewId The primary id of the view (must not be
2164: * <code>null</code>
2165: * @param secondaryId The secondary id of a multiple-instance view
2166: * (may be <code>null</code>).
2167: *
2168: * @return The reference to the specified view. This may be null if the
2169: * view fails to create (i.e. thrown a PartInitException)
2170: */
2171: public IViewReference getViewReference(String viewId,
2172: String secondaryId) {
2173: IViewReference ref = page
2174: .findViewReference(viewId, secondaryId);
2175: if (ref == null) {
2176: ViewFactory factory = getViewFactory();
2177: try {
2178: ref = factory.createView(viewId, secondaryId);
2179: } catch (PartInitException e) {
2180: IStatus status = StatusUtil.newStatus(IStatus.ERROR, e
2181: .getMessage() == null ? "" : e.getMessage(), //$NON-NLS-1$
2182: e);
2183: StatusUtil.handleStatus(status,
2184: "Failed to create view: id=" + viewId, //$NON-NLS-1$
2185: StatusManager.LOG);
2186: }
2187: }
2188: return ref;
2189: }
2190:
2191: /**
2192: * Shows the view with the given id and secondary id.
2193: */
2194: public IViewPart showView(String viewId, String secondaryId)
2195: throws PartInitException {
2196: ViewFactory factory = getViewFactory();
2197: IViewReference ref = factory.createView(viewId, secondaryId);
2198: IViewPart part = (IViewPart) ref.getPart(true);
2199: if (part == null) {
2200: throw new PartInitException(NLS.bind(
2201: WorkbenchMessages.ViewFactory_couldNotCreate, ref
2202: .getId()));
2203: }
2204: ViewSite site = (ViewSite) part.getSite();
2205: ViewPane pane = (ViewPane) site.getPane();
2206:
2207: IPreferenceStore store = WorkbenchPlugin.getDefault()
2208: .getPreferenceStore();
2209: int openViewMode = store
2210: .getInt(IPreferenceConstants.OPEN_VIEW_MODE);
2211:
2212: if (openViewMode == IPreferenceConstants.OVM_FAST
2213: && fastViewManager != null) {
2214: fastViewManager.addViewReference(
2215: FastViewBar.FASTVIEWBAR_ID, -1, ref, true);
2216: setActiveFastView(ref);
2217: } else if (openViewMode == IPreferenceConstants.OVM_FLOAT
2218: && presentation.canDetach()) {
2219: presentation.addDetachedPart(pane);
2220: } else {
2221: if (useNewMinMax(this )) {
2222: // Is this view going to show in the trim?
2223: LayoutPart vPart = presentation.findPart(viewId,
2224: secondaryId);
2225:
2226: // Determine if there is a trim stack that should get the view
2227: String trimId = null;
2228:
2229: // If we can locate the correct trim stack then do so
2230: if (vPart != null) {
2231: String id = null;
2232: ILayoutContainer container = vPart.getContainer();
2233: if (container instanceof ContainerPlaceholder)
2234: id = ((ContainerPlaceholder) container).getID();
2235: else if (container instanceof ViewStack)
2236: id = ((ViewStack) container).getID();
2237:
2238: // Is this place-holder in the trim?
2239: if (id != null
2240: && fastViewManager.getFastViews(id).size() > 0) {
2241: trimId = id;
2242: }
2243: }
2244:
2245: // No explicit trim found; If we're maximized then we either have to find an
2246: // arbitrary stack...
2247: if (trimId == null
2248: && presentation.getMaximizedStack() != null) {
2249: if (vPart == null) {
2250: ViewStackTrimToolBar blTrimStack = fastViewManager
2251: .getBottomRightTrimStack();
2252: if (blTrimStack != null) {
2253: // OK, we've found a trim stack to add it to...
2254: trimId = blTrimStack.getId();
2255:
2256: // Since there was no placeholder we have to add one
2257: LayoutPart blPart = presentation.findPart(
2258: trimId, null);
2259: if (blPart instanceof ContainerPlaceholder) {
2260: ContainerPlaceholder cph = (ContainerPlaceholder) blPart;
2261: if (cph.getRealContainer() instanceof ViewStack) {
2262: ViewStack vs = (ViewStack) cph
2263: .getRealContainer();
2264:
2265: // Create a 'compound' id if this is a multi-instance part
2266: String compoundId = ref.getId();
2267: if (ref.getSecondaryId() != null)
2268: compoundId = compoundId + ':'
2269: + ref.getSecondaryId();
2270:
2271: // Add the new placeholder
2272: vs.add(new PartPlaceholder(
2273: compoundId));
2274: }
2275: }
2276: }
2277: }
2278: }
2279:
2280: // If we have a trim stack located then add the view to it
2281: if (trimId != null) {
2282: fastViewManager.addViewReference(trimId, -1, ref,
2283: true);
2284: } else {
2285: boolean inMaximizedStack = vPart != null
2286: && vPart.getContainer() == presentation
2287: .getMaximizedStack();
2288:
2289: // Do the default behavior
2290: presentation.addPart(pane);
2291:
2292: // Now, if we're maximized then we have to minimize the new stack
2293: if (presentation.getMaximizedStack() != null
2294: && !inMaximizedStack) {
2295: vPart = presentation.findPart(viewId,
2296: secondaryId);
2297: if (vPart != null
2298: && vPart.getContainer() instanceof ViewStack) {
2299: ViewStack vs = (ViewStack) vPart
2300: .getContainer();
2301: vs
2302: .setState(IStackPresentationSite.STATE_MINIMIZED);
2303:
2304: // setting the state to minimized will create the trim toolbar
2305: // so we don't need a null pointer check here...
2306: fastViewManager.getViewStackTrimToolbar(
2307: vs.getID())
2308: .setRestoreOnUnzoom(true);
2309: }
2310: }
2311: }
2312: } else {
2313: presentation.addPart(pane);
2314: }
2315: }
2316: return part;
2317: }
2318:
2319: /**
2320: * Toggles the visibility of a fast view. If the view is active it
2321: * is deactivated. Otherwise, it is activated.
2322: */
2323: public void toggleFastView(IViewReference ref) {
2324: if (ref == activeFastView) {
2325: setActiveFastView(null);
2326: } else {
2327: setActiveFastView(ref);
2328: }
2329: }
2330:
2331: /**
2332: * Returns the old part reference.
2333: * Returns null if there was no previously active part.
2334: *
2335: * @return the old part reference or <code>null</code>
2336: */
2337: public IWorkbenchPartReference getOldPartRef() {
2338: return oldPartRef;
2339: }
2340:
2341: /**
2342: * Sets the old part reference.
2343: *
2344: * @param oldPartRef The old part reference to set, or <code>null</code>
2345: */
2346: public void setOldPartRef(IWorkbenchPartReference oldPartRef) {
2347: this .oldPartRef = oldPartRef;
2348: }
2349:
2350: //for dynamic UI
2351: /* package */void addActionSet(IActionSetDescriptor newDesc) {
2352: IContextService service = (IContextService) page
2353: .getWorkbenchWindow().getService(IContextService.class);
2354: try {
2355: service.activateContext(ContextAuthority.DEFER_EVENTS);
2356: for (int i = 0; i < alwaysOnActionSets.size(); i++) {
2357: IActionSetDescriptor desc = (IActionSetDescriptor) alwaysOnActionSets
2358: .get(i);
2359: if (desc.getId().equals(newDesc.getId())) {
2360: removeAlwaysOn(desc);
2361: removeAlwaysOff(desc);
2362: break;
2363: }
2364: }
2365: addAlwaysOn(newDesc);
2366: } finally {
2367: service.activateContext(ContextAuthority.SEND_EVENTS);
2368: }
2369: }
2370:
2371: // for dynamic UI
2372: /* package */void removeActionSet(String id) {
2373: IContextService service = (IContextService) page
2374: .getWorkbenchWindow().getService(IContextService.class);
2375: try {
2376: service.activateContext(ContextAuthority.DEFER_EVENTS);
2377: for (int i = 0; i < alwaysOnActionSets.size(); i++) {
2378: IActionSetDescriptor desc = (IActionSetDescriptor) alwaysOnActionSets
2379: .get(i);
2380: if (desc.getId().equals(id)) {
2381: removeAlwaysOn(desc);
2382: break;
2383: }
2384: }
2385:
2386: for (int i = 0; i < alwaysOffActionSets.size(); i++) {
2387: IActionSetDescriptor desc = (IActionSetDescriptor) alwaysOffActionSets
2388: .get(i);
2389: if (desc.getId().equals(id)) {
2390: removeAlwaysOff(desc);
2391: break;
2392: }
2393: }
2394: } finally {
2395: service.activateContext(ContextAuthority.SEND_EVENTS);
2396: }
2397: }
2398:
2399: void removeActionSet(IActionSetDescriptor toRemove) {
2400: removeAlwaysOn(toRemove);
2401: removeAlwaysOff(toRemove);
2402: }
2403:
2404: public void setFastViewState(int newState) {
2405: fastViewPane.setState(newState);
2406: }
2407:
2408: public int getFastViewState() {
2409: return fastViewPane.getState();
2410: }
2411:
2412: /**
2413: * Returns whether the given view is closeable in this perspective.
2414: *
2415: * @since 3.0
2416: */
2417: public boolean isCloseable(IViewReference reference) {
2418: ViewLayoutRec rec = getViewLayoutRec(reference, false);
2419: if (rec != null) {
2420: return rec.isCloseable;
2421: }
2422: return true;
2423: }
2424:
2425: /**
2426: * Returns whether the given view is moveable in this perspective.
2427: *
2428: * @since 3.0
2429: */
2430: public boolean isMoveable(IViewReference reference) {
2431: ViewLayoutRec rec = getViewLayoutRec(reference, false);
2432: if (rec != null) {
2433: return rec.isMoveable;
2434: }
2435: return true;
2436: }
2437:
2438: /**
2439: * Writes a description of the layout to the given string buffer.
2440: * This is used for drag-drop test suites to determine if two layouts are the
2441: * same. Like a hash code, the description should compare as equal iff the
2442: * layouts are the same. However, it should be user-readable in order to
2443: * help debug failed tests. Although these are english readable strings,
2444: * they should not be translated or equality tests will fail.
2445: * <p>
2446: * This is only intended for use by test suites.
2447: * </p>
2448: *
2449: * @param buf
2450: */
2451: public void describeLayout(StringBuffer buf) {
2452: IViewReference[] fastViews = getFastViews();
2453:
2454: if (fastViews.length != 0) {
2455: buf.append("fastviews ("); //$NON-NLS-1$
2456: for (int idx = 0; idx < fastViews.length; idx++) {
2457: IViewReference ref = fastViews[idx];
2458:
2459: if (idx > 0) {
2460: buf.append(", "); //$NON-NLS-1$
2461: }
2462:
2463: buf.append(ref.getPartName());
2464: }
2465: buf.append("), "); //$NON-NLS-1$
2466: }
2467:
2468: getPresentation().describeLayout(buf);
2469: }
2470:
2471: /**
2472: * Sanity-checks the LayoutParts in this perspective. Throws an Assertation exception
2473: * if an object's internal state is invalid.
2474: */
2475: public void testInvariants() {
2476: getPresentation().getLayout().testInvariants();
2477: }
2478:
2479: public IActionSetDescriptor[] getAlwaysOnActionSets() {
2480: return (IActionSetDescriptor[]) alwaysOnActionSets
2481: .toArray(new IActionSetDescriptor[alwaysOnActionSets
2482: .size()]);
2483: }
2484:
2485: public IActionSetDescriptor[] getAlwaysOffActionSets() {
2486: return (IActionSetDescriptor[]) alwaysOffActionSets
2487: .toArray(new IActionSetDescriptor[alwaysOffActionSets
2488: .size()]);
2489: }
2490:
2491: /* package */FastViewPane getFastViewPane() {
2492: return fastViewPane;
2493: }
2494:
2495: /**
2496: * Restores a part in the trim to the actual layout
2497: * @param part The part to restore
2498: */
2499: public void restoreTrimPart(LayoutPart part) {
2500: if (fastViewManager == null)
2501: return;
2502:
2503: // Remove any current fastview
2504: setActiveFastView(null);
2505:
2506: // Set the part's state to place it back in the layout
2507: if (part instanceof ViewStack) {
2508: ViewStack vs = (ViewStack) part;
2509: fastViewManager.restoreToPresentation(vs.getID());
2510: }
2511:
2512: if (part == editorArea) {
2513: setEditorAreaState(IStackPresentationSite.STATE_RESTORED);
2514: editorAreaRestoreOnUnzoom = false;
2515: }
2516: }
2517:
2518: /**
2519: * Determine the correct side to initially dock a new
2520: * trim part on. We do this by checking its rect against
2521: * the editor area.
2522: *
2523: * @param stackBounds The bounds of the stack we want to create trim for
2524: * @return the SWT side to dock the trim element on
2525: */
2526: public int calcStackSide(Rectangle stackBounds) {
2527: // Where is the stack in relation to the EditorArea?
2528: Rectangle editorAreaBounds = editorArea.getBounds();
2529:
2530: // Is this the Editor Area
2531: if (editorAreaBounds.equals(stackBounds))
2532: return SWT.TOP;
2533:
2534: Point stackCenter = Geometry.centerPoint(stackBounds);
2535: Point editorAreaCenter = Geometry.centerPoint(editorAreaBounds);
2536:
2537: int dx = editorAreaCenter.x - stackCenter.x;
2538: int dy = editorAreaCenter.y - stackCenter.y;
2539:
2540: if (Math.abs(dx) > Math.abs(dy)) {
2541: return (dx > 0) ? SWT.LEFT : SWT.RIGHT;
2542: }
2543:
2544: if (dy > 0) {
2545: return (dx > 0) ? SWT.LEFT : SWT.RIGHT;
2546: }
2547:
2548: return SWT.BOTTOM;
2549: }
2550:
2551: /**
2552: * Restore any parts that are showing in the trim as
2553: * a result of a 'zoom' operation
2554: */
2555: public void restoreZoomedParts() {
2556: if (fastViewManager == null)
2557: return;
2558:
2559: // Remove any current fastview
2560: setActiveFastView(null);
2561:
2562: // have the layout restore the parts
2563: fastViewManager.restoreZoomedViewStacks();
2564:
2565: if (editorAreaRestoreOnUnzoom) {
2566: restoreTrimPart(editorArea);
2567: }
2568: }
2569:
2570: /**
2571: * @return Returns the fastViewManager.
2572: */
2573: public FastViewManager getFastViewManager() {
2574: return fastViewManager;
2575: }
2576:
2577: /**
2578: * Sets the restore on unzoom state for the editor area
2579: * @param restore the new state
2580: */
2581: public void setEditorAreaRestoreOnUnzoom(boolean restore) {
2582: editorAreaRestoreOnUnzoom = restore;
2583: }
2584:
2585: /**
2586: * @return the restore on unzoom state
2587: */
2588: public boolean getEditorAreaRestoreOnUnzoom() {
2589: return editorAreaRestoreOnUnzoom;
2590: }
2591:
2592: /**
2593: * Used to restrict the use of the new min/max behavior to envoronments
2594: * in which it has a chance of working...
2595: *
2596: * @param activePerspective We pass this in as an arg so others won't have
2597: * to check it for 'null' (which is one of the failure cases)
2598: *
2599: */
2600: public static boolean useNewMinMax(Perspective activePerspective) {
2601: // We need to have an active perspective
2602: if (activePerspective == null)
2603: return false;
2604:
2605: // We need to have a trim manager (if we don't then we
2606: // don't create a FastViewManager because it'd be useless)
2607: if (activePerspective.getFastViewManager() == null)
2608: return false;
2609:
2610: // Make sure we don't NPE anyplace
2611: WorkbenchWindow wbw = (WorkbenchWindow) activePerspective.page
2612: .getWorkbenchWindow();
2613: if (wbw == null)
2614: return false;
2615:
2616: WorkbenchWindowConfigurer configurer = wbw
2617: .getWindowConfigurer();
2618: if (configurer == null)
2619: return false;
2620:
2621: AbstractPresentationFactory factory = configurer
2622: .getPresentationFactory();
2623: if (factory == null)
2624: return false;
2625:
2626: // Ok, we should be good to go, return the pref
2627: IPreferenceStore preferenceStore = PrefUtil
2628: .getAPIPreferenceStore();
2629: boolean useNewMinMax = preferenceStore
2630: .getBoolean(IWorkbenchPreferenceConstants.ENABLE_NEW_MIN_MAX);
2631: return useNewMinMax;
2632: }
2633: }
|