| /******************************************************************************* |
| * Copyright (c) 2000, 2009 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Carlos Devoto carlos.devoto@compuware.com Bug 213645 |
| * Marco Maccaferri, maccasoft.com - patch for defect 222750 |
| *******************************************************************************/ |
| |
| package org.eclipse.ui.internal; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Enumeration; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Vector; |
| |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.graphics.Rectangle; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.ui.IMemento; |
| import org.eclipse.ui.IViewReference; |
| import org.eclipse.ui.IWorkbenchPartReference; |
| import org.eclipse.ui.internal.misc.StringMatcher; |
| import org.eclipse.ui.presentations.IStackPresentationSite; |
| |
| /** |
| * A perspective presentation is a collection of parts with a layout. Each part |
| * is parented to a main window, so you can create more than one presentation |
| * on a set of parts and change the layout just by activating / deactivating a |
| * presentation. |
| * |
| * In addition, the user can change the position of any part by mouse |
| * manipulation (drag & drop). If a part is removed, we leave a placeholder |
| * behind to indicate where it goes should the part be added back. |
| */ |
| public class PerspectiveHelper { |
| // RAP [rh] unused code |
| // private WorkbenchPage page; |
| |
| protected Perspective perspective; |
| |
| protected Composite parentWidget; |
| |
| private ViewSashContainer mainLayout; |
| |
| private PartStack maximizedStack; |
| |
| /** |
| * If there is a ViewStack maximized on shutdown the id is |
| * cached and restored into this field on 'restoreState'. |
| * This is then used to bash the ViewStack's presentation state |
| * into the correct value on activation (the startup life-cycle |
| * is such that we have to use this 'latch' because the window |
| * state isn't valid until the activate happens. |
| */ |
| private String maximizedStackId; |
| |
| // RAP [rh] unused code |
| // private ArrayList detachedWindowList = new ArrayList(1); |
| |
| private ArrayList detachedPlaceHolderList = new ArrayList(1); |
| |
| /** |
| * Maps a stack's id to its current bounds |
| * this is used to capture the current bounds of all |
| * stacks -before- starting a maximize (since the |
| * iterative 'minimize' calls cause the intial stack's |
| * bounds to change. |
| */ |
| private Map boundsMap = new HashMap(); |
| |
| private boolean detachable = false; |
| |
| protected boolean active = false; |
| |
| // key is the LayoutPart object, value is the PartDragDrop object |
| //private IPartDropListener partDropListener; |
| |
| // RAP [rh] unused code |
| // private static final int MIN_DETACH_WIDTH = 150; |
| |
| // private static final int MIN_DETACH_HEIGHT = 250; |
| |
| // RAP [rh] DnD not supported |
| // protected ActualDropTarget dropTarget; |
| // |
| // private IDragOverListener dragTarget = new IDragOverListener() { |
| // |
| // public IDropTarget drag(Control currentControl, Object draggedObject, |
| // Point position, final Rectangle dragRectangle) { |
| // |
| // if (!(draggedObject instanceof ViewPane || draggedObject instanceof ViewStack)) { |
| // return null; |
| // } |
| // final LayoutPart part = (LayoutPart) draggedObject; |
| // |
| // if (part.getWorkbenchWindow() != page.getWorkbenchWindow()) { |
| // return null; |
| // } |
| // |
| // if (dropTarget == null) { |
| // dropTarget = new ActualDropTarget(part, dragRectangle); |
| // } else { |
| // dropTarget.setTarget(part, dragRectangle); |
| // } |
| // |
| // return dropTarget; |
| // } |
| // |
| // }; |
| // |
| // private final class ActualDropTarget extends AbstractDropTarget { |
| // private LayoutPart part; |
| // |
| // private Rectangle dragRectangle; |
| // |
| // private ActualDropTarget(LayoutPart part, Rectangle dragRectangle) { |
| // super(); |
| // setTarget(part, dragRectangle); |
| // } |
| // |
| // /** |
| // * @param part |
| // * @param dragRectangle |
| // * @since 3.1 |
| // */ |
| // private void setTarget(LayoutPart part, Rectangle dragRectangle) { |
| // this.part = part; |
| // this.dragRectangle = dragRectangle; |
| // } |
| // |
| // public void drop() { |
| // |
| // Shell shell = part.getShell(); |
| // if (shell.getData() instanceof DetachedWindow) { |
| // // only one tab folder in a detach window, so do window |
| // // move |
| // if (part instanceof ViewStack) { |
| // shell.setLocation(dragRectangle.x, |
| // dragRectangle.y); |
| // return; |
| // } |
| // // if only one view in tab folder then do a window move |
| // ILayoutContainer container = part.getContainer(); |
| // if (container instanceof ViewStack) { |
| // if (((ViewStack) container).getItemCount() == 1) { |
| // shell.setLocation(dragRectangle.x, |
| // dragRectangle.y); |
| // return; |
| // } |
| // } |
| // } |
| // |
| // // If layout is modified always zoom out. |
| // if (isZoomed()) { |
| // zoomOut(); |
| // } |
| // // do a normal part detach |
| // detach(part, dragRectangle.x, dragRectangle.y); |
| // } |
| // |
| // public Cursor getCursor() { |
| // return DragCursors.getCursor(DragCursors.OFFSCREEN); |
| // } |
| // } |
| |
| private class MatchingPart implements Comparable { |
| String pid; |
| |
| String sid; |
| |
| LayoutPart part; |
| |
| boolean hasWildcard; |
| |
| int len; |
| |
| MatchingPart(String pid, String sid, LayoutPart part) { |
| this.pid = pid; |
| this.sid = sid; |
| this.part = part; |
| this.len = (pid == null ? 0 : pid.length()) |
| + (sid == null ? 0 : sid.length()); |
| this.hasWildcard = (pid != null && pid |
| .indexOf(PartPlaceholder.WILD_CARD) != -1) |
| || (sid != null && sid.indexOf(PartPlaceholder.WILD_CARD) != -1); |
| } |
| |
| public int compareTo(Object a) { |
| // specific ids always outweigh ids with wildcards |
| MatchingPart ma = (MatchingPart) a; |
| if (this.hasWildcard && !ma.hasWildcard) { |
| return -1; |
| } |
| if (!this.hasWildcard && ma.hasWildcard) { |
| return 1; |
| } |
| // if both are specific or both have wildcards, simply compare based on length |
| return ma.len - this.len; |
| } |
| } |
| |
| |
| /** |
| * Constructs a new object. |
| */ |
| public PerspectiveHelper(WorkbenchPage workbenchPage, |
| ViewSashContainer mainLayout, Perspective perspective) { |
| // RAP [rh] unused code |
| // this.page = workbenchPage; |
| this.mainLayout = mainLayout; |
| this.perspective = perspective; |
| |
| // Views can be detached if the feature is enabled (true by default, |
| // use the plug-in customization file to disable), and if the platform |
| // supports detaching. |
| |
| // RAP [bm]: no detachable view |
| // final IPreferenceStore store = PlatformUI.getPreferenceStore(); |
| // this.detachable = store.getBoolean(IWorkbenchPreferenceConstants.ENABLE_DETACHED_VIEWS); |
| this.detachable = false; |
| // RAPEND: [bm] |
| |
| if (this.detachable) { |
| // Check if some arbitrary Composite supports reparenting. If it |
| // doesn't, views cannot be detached. |
| |
| Composite client = workbenchPage.getClientComposite(); |
| if (client == null) { |
| // The workbench page is not initialized. I don't think this can happen, |
| // but if it does, silently set detachable to false. |
| this.detachable = false; |
| } else { |
| Composite testChild = new Composite(client, SWT.NONE); |
| this.detachable = testChild.isReparentable(); |
| testChild.dispose(); |
| } |
| } |
| } |
| |
| /** |
| * Show the presentation. |
| */ |
| public void activate(Composite parent) { |
| |
| if (active) { |
| return; |
| } |
| |
| parentWidget = parent; |
| |
| // Activate main layout |
| // make sure all the views have been properly parented |
| Vector children = new Vector(); |
| collectViewPanes(children, mainLayout.getChildren()); |
| Enumeration itr = children.elements(); |
| while (itr.hasMoreElements()) { |
| LayoutPart part = (LayoutPart) itr.nextElement(); |
| part.reparent(parent); |
| } |
| mainLayout.createControl(parent); |
| mainLayout.setActive(true); |
| |
| // RAP [rh] DetachedWindow not supported |
| // // Open the detached windows. |
| // for (int i = 0, length = detachedWindowList.size(); i < length; i++) { |
| // DetachedWindow dwindow = (DetachedWindow) detachedWindowList.get(i); |
| // dwindow.open(); |
| // } |
| |
| // RAP [rh] DnD not suuported |
| // enableAllDrag(); |
| |
| // Ensure that the maximized stack's presentation state is correct |
| if (maximizedStackId != null) { |
| LayoutPart part = findPart(maximizedStackId); |
| if (part instanceof PartStack) { |
| maximizedStack = (PartStack) part; |
| maximizedStackId = null; |
| } |
| } |
| |
| // NOTE: we only handle ViewStacks here; Editor Stacks are handled by the |
| // perspective |
| if (maximizedStack instanceof ViewStack) { |
| maximizedStack.setPresentationState(IStackPresentationSite.STATE_MAXIMIZED); |
| } |
| |
| active = true; |
| } |
| |
| /** |
| * Adds a part to the presentation. If a placeholder exists for the part |
| * then swap the part in. Otherwise, add the part in the bottom right |
| * corner of the presentation. |
| */ |
| public void addPart(LayoutPart part) { |
| |
| // Look for a placeholder. |
| PartPlaceholder placeholder = null; |
| LayoutPart testPart = null; |
| String primaryId = part.getID(); |
| String secondaryId = null; |
| |
| IViewReference ref = null; |
| if (part instanceof ViewPane) { |
| ViewPane pane = (ViewPane) part; |
| ref = (IViewReference) pane.getPartReference(); |
| secondaryId = ref.getSecondaryId(); |
| } |
| if (secondaryId != null) { |
| testPart = findPart(primaryId, secondaryId); |
| } else { |
| testPart = findPart(primaryId); |
| } |
| |
| // validate the testPart |
| if (testPart != null && testPart instanceof PartPlaceholder) { |
| placeholder = (PartPlaceholder) testPart; |
| } |
| |
| // If there is no placeholder do a simple add. Otherwise, replace the |
| // placeholder if its not a pattern matching placholder |
| if (placeholder == null) { |
| part.reparent(mainLayout.getParent()); |
| LayoutPart relative = mainLayout.findBottomRight(); |
| if (relative != null && relative instanceof ILayoutContainer) { |
| ILayoutContainer stack = (ILayoutContainer)relative; |
| if (stack.allowsAdd(part)) { |
| mainLayout.stack(part, stack); |
| } else { |
| mainLayout.add(part); |
| } |
| } else { |
| mainLayout.add(part); |
| } |
| } else { |
| ILayoutContainer container = placeholder.getContainer(); |
| if (container != null) { |
| // RAP [rh] DetachedWindow not supported |
| // if (container instanceof DetachedPlaceHolder) { |
| // //Create a detached window add the part on it. |
| // DetachedPlaceHolder holder = (DetachedPlaceHolder) container; |
| // detachedPlaceHolderList.remove(holder); |
| // container.remove(testPart); |
| // DetachedWindow window = new DetachedWindow(page); |
| // detachedWindowList.add(window); |
| // window.create(); |
| // part.createControl(window.getShell()); |
| // // Open window. |
| // window.getShell().setBounds(holder.getBounds()); |
| // window.open(); |
| // // add part to detached window. |
| // ViewPane pane = (ViewPane) part; |
| // window.add(pane); |
| // LayoutPart otherChildren[] = holder.getChildren(); |
| // for (int i = 0; i < otherChildren.length; i++) { |
| // part.getContainer().add(otherChildren[i]); |
| // } |
| // } else |
| { |
| // show parent if necessary |
| if (container instanceof ContainerPlaceholder) { |
| ContainerPlaceholder containerPlaceholder = (ContainerPlaceholder) container; |
| ILayoutContainer parentContainer = containerPlaceholder |
| .getContainer(); |
| container = (ILayoutContainer) containerPlaceholder |
| .getRealContainer(); |
| if (container instanceof LayoutPart) { |
| parentContainer.replace(containerPlaceholder, |
| (LayoutPart) container); |
| } |
| containerPlaceholder.setRealContainer(null); |
| } |
| |
| // reparent part. |
| if (!(container instanceof ViewStack)) { |
| // We don't need to reparent children of PartTabFolders since they will automatically |
| // reparent their children when they become visible. This if statement used to be |
| // part of an else branch. Investigate if it is still necessary. |
| part.reparent(mainLayout.getParent()); |
| } |
| |
| // see if we should replace the placeholder |
| if (placeholder.hasWildCard()) { |
| if (container instanceof PartSashContainer) { |
| ((PartSashContainer) container) |
| .addChildForPlaceholder(part, placeholder); |
| } else { |
| container.add(part); |
| } |
| } else { |
| container.replace(placeholder, part); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Attaches a part that was previously detached to the mainLayout. |
| * |
| * @param ref |
| */ |
| public void attachPart(IViewReference ref) { |
| ViewPane pane = (ViewPane)((WorkbenchPartReference)ref).getPane(); |
| |
| // Restore any maximized part before re-attaching. |
| // Note that 'getMaximizedStack != null' implies 'useNewMinMax' |
| if (getMaximizedStack() != null) { |
| getMaximizedStack().setState(IStackPresentationSite.STATE_RESTORED); |
| } |
| |
| derefPart(pane); |
| addPart(pane); |
| bringPartToTop(pane); |
| pane.setFocus(); |
| } |
| |
| /** |
| * Return whether detachable parts can be supported. |
| */ |
| public boolean canDetach() { |
| return detachable; |
| } |
| |
| /** |
| * Bring a part forward so it is visible. |
| * |
| * @return true if the part was brought to top, false if not. |
| */ |
| public boolean bringPartToTop(LayoutPart part) { |
| ILayoutContainer container = part.getContainer(); |
| if (container != null && container instanceof PartStack) { |
| PartStack folder = (PartStack) container; |
| if (folder.getSelection() != part) { |
| folder.setSelection(part); |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Returns true if the given part is visible. |
| * A part is visible if it's top-level (not in a tab folder) or if it is the top one |
| * in a tab folder. |
| */ |
| public boolean isPartVisible(IWorkbenchPartReference partRef) { |
| LayoutPart foundPart; |
| if (partRef instanceof IViewReference) { |
| foundPart = findPart(partRef.getId(), ((IViewReference) partRef).getSecondaryId()); |
| } else { |
| foundPart = findPart(partRef.getId()); |
| } |
| if (foundPart == null) { |
| return false; |
| } |
| if (foundPart instanceof PartPlaceholder) { |
| return false; |
| } |
| |
| ILayoutContainer container = foundPart.getContainer(); |
| |
| if (container instanceof ContainerPlaceholder) { |
| return false; |
| } |
| |
| if (container instanceof ViewStack) { |
| ViewStack folder = (ViewStack) container; |
| PartPane visiblePart = folder.getSelection(); |
| if (visiblePart == null) { |
| return false; |
| } |
| return partRef.equals(visiblePart.getPartReference()); |
| } |
| return true; |
| } |
| |
| /** |
| * Returns true is not in a tab folder or if it is the top one in a tab |
| * folder. |
| */ |
| public boolean willPartBeVisible(String partId) { |
| return willPartBeVisible(partId, null); |
| } |
| |
| public boolean willPartBeVisible(String partId, String secondaryId) { |
| LayoutPart part = findPart(partId, secondaryId); |
| if (part == null) { |
| return false; |
| } |
| ILayoutContainer container = part.getContainer(); |
| if (container != null && container instanceof ContainerPlaceholder) { |
| container = (ILayoutContainer) ((ContainerPlaceholder) container) |
| .getRealContainer(); |
| } |
| |
| if (container != null && container instanceof ViewStack) { |
| ViewStack folder = (ViewStack) container; |
| if (folder.getSelection() == null) { |
| return false; |
| } |
| return part.getCompoundId().equals( |
| folder.getSelection().getCompoundId()); |
| } |
| return true; |
| } |
| |
| /** |
| * Answer a list of the PartPlaceholder objects. |
| */ |
| private PartPlaceholder[] collectPlaceholders() { |
| // Scan the main window. |
| PartPlaceholder[] results = collectPlaceholders(mainLayout |
| .getChildren()); |
| |
| // RAP [rh] DetachedWindow not supported |
| // // Scan each detached window. |
| // if (detachable) { |
| // for (int i = 0, length = detachedWindowList.size(); i < length; i++) { |
| // DetachedWindow win = (DetachedWindow) detachedWindowList.get(i); |
| // PartPlaceholder[] moreResults = collectPlaceholders(win |
| // .getChildren()); |
| // if (moreResults.length > 0) { |
| // int newLength = results.length + moreResults.length; |
| // PartPlaceholder[] newResults = new PartPlaceholder[newLength]; |
| // System.arraycopy(results, 0, newResults, 0, results.length); |
| // System.arraycopy(moreResults, 0, newResults, |
| // results.length, moreResults.length); |
| // results = newResults; |
| // } |
| // } |
| // } |
| return results; |
| } |
| |
| /** |
| * Answer a list of the PartPlaceholder objects. |
| */ |
| private PartPlaceholder[] collectPlaceholders(LayoutPart[] parts) { |
| PartPlaceholder[] result = new PartPlaceholder[0]; |
| |
| for (int i = 0, length = parts.length; i < length; i++) { |
| LayoutPart part = parts[i]; |
| if (part instanceof ILayoutContainer) { |
| // iterate through sub containers to find sub-parts |
| PartPlaceholder[] newParts = collectPlaceholders(((ILayoutContainer) part) |
| .getChildren()); |
| PartPlaceholder[] newResult = new PartPlaceholder[result.length |
| + newParts.length]; |
| System.arraycopy(result, 0, newResult, 0, result.length); |
| System.arraycopy(newParts, 0, newResult, result.length, |
| newParts.length); |
| result = newResult; |
| } else if (part instanceof PartPlaceholder) { |
| PartPlaceholder[] newResult = new PartPlaceholder[result.length + 1]; |
| System.arraycopy(result, 0, newResult, 0, result.length); |
| newResult[result.length] = (PartPlaceholder) part; |
| result = newResult; |
| } |
| } |
| |
| return result; |
| } |
| |
| /** |
| * Answer a list of the view panes. |
| */ |
| public void collectViewPanes(List result) { |
| // Scan the main window. |
| collectViewPanes(result, mainLayout.getChildren()); |
| |
| // RAP [rh] DetachedWindow not supporte |
| // // Scan each detached window. |
| // if (detachable) { |
| // for (int i = 0, length = detachedWindowList.size(); i < length; i++) { |
| // DetachedWindow win = (DetachedWindow) detachedWindowList.get(i); |
| // collectViewPanes(result, win.getChildren()); |
| // } |
| // } |
| } |
| |
| /** |
| * Answer a list of the view panes. |
| */ |
| private void collectViewPanes(List result, LayoutPart[] parts) { |
| for (int i = 0, length = parts.length; i < length; i++) { |
| LayoutPart part = parts[i]; |
| if (part instanceof ViewPane) { |
| result.add(part); |
| } else if (part instanceof ILayoutContainer) { |
| collectViewPanes(result, ((ILayoutContainer) part) |
| .getChildren()); |
| } |
| } |
| } |
| |
| /** |
| * Hide the presentation. |
| */ |
| public void deactivate() { |
| if (!active) { |
| return; |
| } |
| |
| // RAP [rh] DnD not supported |
| // disableAllDrag(); |
| |
| // Reparent all views to the main window |
| Composite parent = mainLayout.getParent(); |
| Vector children = new Vector(); |
| collectViewPanes(children, mainLayout.getChildren()); |
| |
| // RAP [rh] DetachedWindow not supported |
| // for (int i = 0, length = detachedWindowList.size(); i < length; i++) { |
| // DetachedWindow window = (DetachedWindow) detachedWindowList.get(i); |
| // collectViewPanes(children, window.getChildren()); |
| // } |
| |
| // *** Do we even need to do this if detached windows not supported? |
| Enumeration itr = children.elements(); |
| while (itr.hasMoreElements()) { |
| LayoutPart part = (LayoutPart) itr.nextElement(); |
| part.reparent(parent); |
| } |
| |
| // Dispose main layout. |
| |
| mainLayout.setActive(false); |
| |
| // RAP [rh] DetachedWindow not supported |
| // // Dispose the detached windows |
| // for (int i = 0, length = detachedWindowList.size(); i < length; i++) { |
| // DetachedWindow window = (DetachedWindow) detachedWindowList.get(i); |
| // window.close(); |
| // } |
| |
| active = false; |
| } |
| |
| public void dispose() { |
| mainLayout.dispose(); |
| mainLayout.disposeSashes(); |
| } |
| |
| /** |
| * Writes a description of the layout to the given string buffer. |
| * This is used for drag-drop test suites to determine if two layouts are the |
| * same. Like a hash code, the description should compare as equal iff the |
| * layouts are the same. However, it should be user-readable in order to |
| * help debug failed tests. Although these are english readable strings, |
| * they should not be translated or equality tests will fail. |
| * <p> |
| * This is only intended for use by test suites. |
| * </p> |
| * |
| * @param buf |
| */ |
| public void describeLayout(StringBuffer buf) { |
| |
| // RAP [rh] DetachedWindow not supported |
| // if (detachable) { |
| // if(detachedWindowList.size() != 0){ |
| // buf.append("detachedWindows ("); //$NON-NLS-1$ |
| // |
| // for (int i = 0, length = detachedWindowList.size(); i < length; i++) { |
| // DetachedWindow window = (DetachedWindow) detachedWindowList.get(i); |
| // LayoutPart[] children = window.getChildren(); |
| // if(children.length != 0){ |
| // buf.append("dWindow ("); //$NON-NLS-1$ |
| // for(int j = 0; j < children.length; j++){ |
| // buf.append(((ViewPane)children[j]).getViewReference().getPartName()); |
| // if(j < (children.length - 1)) { |
| // buf.append(", "); //$NON-NLS-1$ |
| // } |
| // } |
| // buf.append(")"); //$NON-NLS-1$ |
| // } |
| // |
| // } |
| // buf.append("), "); //$NON-NLS-1$ |
| // } |
| // } |
| |
| getLayout().describeLayout(buf); |
| } |
| |
| /** |
| * Deref a given part. Deconstruct its container as required. Do not remove |
| * drag listeners. |
| */ |
| /* package */void derefPart(LayoutPart part) { |
| if (part instanceof ViewPane) { |
| IViewReference ref = ((ViewPane) part).getViewReference(); |
| if (perspective.isFastView(ref)) { |
| // Special check: if it's a fast view then it's actual ViewStack |
| // may only contain placeholders and the stack is represented in |
| // the presentation by a container placeholder...make sure the |
| // PartPlaceHolder for 'ref' is removed from the ViewStack |
| String id = perspective.getFastViewManager().getIdForRef(ref); |
| LayoutPart parentPart = findPart(id, null); |
| if (parentPart instanceof ContainerPlaceholder) { |
| ViewStack vs = (ViewStack) ((ContainerPlaceholder)parentPart).getRealContainer(); |
| LayoutPart[] kids = vs.getChildren(); |
| for (int i = 0; i < kids.length; i++) { |
| if (kids[i] instanceof PartPlaceholder) { |
| if (ref.getId().equals(kids[i].id)) |
| vs.remove(kids[i]); |
| } |
| } |
| } |
| perspective.getFastViewManager().removeViewReference(ref, true, true); |
| } |
| } |
| |
| // Get vital part stats before reparenting. |
| ILayoutContainer oldContainer = part.getContainer(); |
| boolean wasDocked = part.isDocked(); |
| // RAP [rh] unused code |
| // Shell oldShell = part.getShell(); |
| |
| // Reparent the part back to the main window |
| part.reparent(mainLayout.getParent()); |
| |
| // Update container. |
| if (oldContainer == null) { |
| return; |
| } |
| |
| oldContainer.remove(part); |
| |
| LayoutPart[] children = oldContainer.getChildren(); |
| if (wasDocked) { |
| boolean hasChildren = (children != null) && (children.length > 0); |
| if (hasChildren) { |
| // make sure one is at least visible |
| int childVisible = 0; |
| for (int i = 0; i < children.length; i++) { |
| if (children[i].getControl() != null) { |
| childVisible++; |
| } |
| } |
| |
| // none visible, then reprarent and remove container |
| if (oldContainer instanceof ViewStack) { |
| ViewStack folder = (ViewStack) oldContainer; |
| |
| // Is the part in the trim? |
| boolean inTrim = false; |
| // Safety check...there may be no FastViewManager |
| if (perspective.getFastViewManager() != null) |
| inTrim = perspective.getFastViewManager().getFastViews(folder.getID()).size() > 0; |
| |
| if (childVisible == 0 && !inTrim) { |
| ILayoutContainer parentContainer = folder.getContainer(); |
| hasChildren = folder.getChildren().length > 0; |
| |
| // We maintain the stack as a place-holder if it has children |
| // (which at this point would represent view place-holders) |
| if (hasChildren) { |
| folder.dispose(); |
| |
| // replace the real container with a ContainerPlaceholder |
| ContainerPlaceholder placeholder = new ContainerPlaceholder(folder.getID()); |
| placeholder.setRealContainer(folder); |
| parentContainer.replace(folder, placeholder); |
| } |
| hasChildren = false; |
| } else if (childVisible == 1) { |
| LayoutTree layout = mainLayout.getLayoutTree(); |
| layout = layout.find(folder); |
| layout.setBounds(layout.getBounds()); |
| } |
| } |
| } |
| |
| if (!hasChildren && !(oldContainer instanceof ViewStack && ((ViewStack)oldContainer).getDurable())) { |
| // There are no more children in this container, so get rid of |
| // it (but only if the container is not a durable ViewStack) |
| if (oldContainer instanceof LayoutPart) { |
| LayoutPart parent = (LayoutPart) oldContainer; |
| ILayoutContainer parentContainer = parent.getContainer(); |
| if (parentContainer != null) { |
| parentContainer.remove(parent); |
| parent.dispose(); |
| } |
| } |
| } |
| // RAP [rh] DetachedWindow not supported |
| // } else if (!wasDocked) { |
| // if (children == null || children.length == 0) { |
| // // There are no more children in this container, so get rid of |
| // // it |
| // // Turn on redraw again just in case it was off. |
| // //oldShell.setRedraw(true); |
| // DetachedWindow w = (DetachedWindow)oldShell.getData(); |
| // oldShell.close(); |
| // detachedWindowList.remove(w); |
| // } else { |
| // // There are children. If none are visible hide detached |
| // // window. |
| // boolean allInvisible = true; |
| // for (int i = 0, length = children.length; i < length; i++) { |
| // if (!(children[i] instanceof PartPlaceholder)) { |
| // allInvisible = false; |
| // break; |
| // } |
| // } |
| // if (allInvisible) { |
| // DetachedPlaceHolder placeholder = new DetachedPlaceHolder( |
| // "", //$NON-NLS-1$ |
| // oldShell.getBounds()); |
| // for (int i = 0, length = children.length; i < length; i++) { |
| // oldContainer.remove(children[i]); |
| // children[i].setContainer(placeholder); |
| // placeholder.add(children[i]); |
| // } |
| // detachedPlaceHolderList.add(placeholder); |
| // DetachedWindow w = (DetachedWindow)oldShell.getData(); |
| // oldShell.close(); |
| // detachedWindowList.remove(w); |
| // } |
| // } |
| } |
| |
| } |
| |
| // RAP [rh] DetachedWindow not supported |
| // /** |
| // * Create a detached window containing a part. |
| // */ |
| // private void detach(LayoutPart source, int x, int y) { |
| // |
| // // Detaching is disabled on some platforms .. |
| // if (!detachable) { |
| // return; |
| // } |
| // |
| // LayoutPart part = source.getPart(); |
| // // Calculate detached window size. |
| // Point size = part.getSize(); |
| // if (size.x == 0 || size.y == 0) { |
| // ILayoutContainer container = part.getContainer(); |
| // if (container instanceof LayoutPart) { |
| // size = ((LayoutPart) container).getSize(); |
| // } |
| // } |
| // int width = Math.max(size.x, MIN_DETACH_WIDTH); |
| // int height = Math.max(size.y, MIN_DETACH_HEIGHT); |
| // |
| // // Create detached window. |
| // DetachedWindow window = new DetachedWindow(page); |
| // detachedWindowList.add(window); |
| // |
| // // Open window. |
| // window.create(); |
| // window.getShell().setBounds(x, y, width, height); |
| // window.open(); |
| // |
| // if (part instanceof ViewStack) { |
| // window.getShell().setRedraw(false); |
| // parentWidget.setRedraw(false); |
| // LayoutPart visiblePart = ((ViewStack) part).getSelection(); |
| // LayoutPart children[] = ((ViewStack) part).getChildren(); |
| // for (int i = 0; i < children.length; i++) { |
| // if (children[i] instanceof ViewPane) { |
| // // remove the part from its current container |
| // derefPart(children[i]); |
| // // add part to detached window. |
| // ViewPane pane = (ViewPane) children[i]; |
| // window.add(pane); |
| // } |
| // } |
| // if (visiblePart != null) { |
| // bringPartToTop(visiblePart); |
| // visiblePart.setFocus(); |
| // } |
| // window.getShell().setRedraw(true); |
| // parentWidget.setRedraw(true); |
| // } else { |
| // // remove the part from its current container |
| // derefPart(part); |
| // // add part to detached window. |
| // ViewPane pane = (ViewPane) part; |
| // window.add(pane); |
| // part.setFocus(); |
| // } |
| // |
| // } |
| |
| // RAP [rh] DetachedWindow not supported |
| // /** |
| // * Detached a part from the mainLayout. Presently this does not use placeholders |
| // * since the current implementation is not robust enough to remember a view's position |
| // * in more than one root container. For now the view is simply derefed and will dock |
| // * in the default position when attachPart is called. |
| // * |
| // * By default parts detached this way are set to float on top of the workbench |
| // * without docking. It is assumed that people that want to drag a part back onto |
| // * the WorkbenchWindow will detach it via drag and drop. |
| // * |
| // * @param ref |
| // */ |
| // public void detachPart(IViewReference ref) { |
| // ViewPane pane = (ViewPane)((WorkbenchPartReference)ref).getPane(); |
| // if (canDetach() && pane != null) { |
| // if (getMaximizedStack() != null) |
| // getMaximizedStack().setState(IStackPresentationSite.STATE_RESTORED); |
| // |
| // Rectangle bounds = pane.getParentBounds(); |
| // detach(pane, bounds.x ,bounds.y); |
| // } |
| // } |
| // |
| // /** |
| // * Create a detached window containing a part. |
| // */ |
| // public void addDetachedPart(LayoutPart part) { |
| // // Calculate detached window size. |
| // Rectangle bounds = parentWidget.getShell().getBounds(); |
| // bounds.x = bounds.x + (bounds.width - 300) / 2; |
| // bounds.y = bounds.y + (bounds.height - 300) / 2; |
| // |
| // addDetachedPart(part, bounds); |
| // } |
| // |
| // public void addDetachedPart(LayoutPart part, Rectangle bounds) { |
| // // Detaching is disabled on some platforms .. |
| // if (!detachable) { |
| // addPart(part); |
| // return; |
| // } |
| // |
| // // Create detached window. |
| // DetachedWindow window = new DetachedWindow(page); |
| // detachedWindowList.add(window); |
| // window.create(); |
| // |
| // // add part to detached window. |
| // part.createControl(window.getShell()); |
| // ViewPane pane = (ViewPane) part; |
| // window.add(pane); |
| // |
| // // Open window. |
| // window.getShell().setBounds(bounds.x, bounds.y, bounds.width, bounds.height); |
| // window.open(); |
| // |
| // part.setFocus(); |
| // |
| // } |
| |
| // RAP [rh] DnD not supported |
| // /** |
| // * disableDragging. |
| // */ |
| // private void disableAllDrag() { |
| // DragUtil.removeDragTarget(null, dragTarget); |
| // } |
| // |
| // /** |
| // * enableDragging. |
| // */ |
| // private void enableAllDrag() { |
| // DragUtil.addDragTarget(null, dragTarget); |
| // } |
| |
| /** |
| * Find the first part with a given ID in the presentation. |
| * Wild cards now supported. |
| */ |
| private LayoutPart findPart(String id) { |
| return findPart(id, null); |
| } |
| |
| /** |
| * Find the first part that matches the specified |
| * primary and secondary id pair. Wild cards |
| * are supported. |
| */ |
| public LayoutPart findPart(String primaryId, String secondaryId) { |
| // check main window. |
| ArrayList matchingParts = new ArrayList(); |
| LayoutPart part = (secondaryId != null) ? findPart(primaryId, |
| secondaryId, mainLayout.getChildren(), matchingParts) |
| : findPart(primaryId, mainLayout.getChildren(), matchingParts); |
| if (part != null) { |
| return part; |
| } |
| |
| // RAP [rh] DetachedWIndow not supported |
| // // check each detached windows. |
| // for (int i = 0, length = detachedWindowList.size(); i < length; i++) { |
| // DetachedWindow window = (DetachedWindow) detachedWindowList.get(i); |
| // part = (secondaryId != null) ? findPart(primaryId, secondaryId, |
| // window.getChildren(), matchingParts) : findPart(primaryId, |
| // window.getChildren(), matchingParts); |
| // if (part != null) { |
| // return part; |
| // } |
| // } |
| for (int i = 0; i < detachedPlaceHolderList.size(); i++) { |
| DetachedPlaceHolder holder = (DetachedPlaceHolder) detachedPlaceHolderList |
| .get(i); |
| part = (secondaryId != null) ? findPart(primaryId, secondaryId, |
| holder.getChildren(), matchingParts) : findPart(primaryId, |
| holder.getChildren(), matchingParts); |
| if (part != null) { |
| return part; |
| } |
| } |
| |
| // sort the matching parts |
| if (matchingParts.size() > 0) { |
| Collections.sort(matchingParts); |
| MatchingPart mostSignificantPart = (MatchingPart) matchingParts |
| .get(0); |
| if (mostSignificantPart != null) { |
| return mostSignificantPart.part; |
| } |
| } |
| |
| // Not found. |
| return null; |
| } |
| |
| /** |
| * Find the first part with a given ID in the presentation. |
| */ |
| private LayoutPart findPart(String id, LayoutPart[] parts, |
| ArrayList matchingParts) { |
| for (int i = 0, length = parts.length; i < length; i++) { |
| LayoutPart part = parts[i]; |
| // check for part equality, parts with secondary ids fail |
| if (part.getID().equals(id)) { |
| if (part instanceof ViewPane) { |
| ViewPane pane = (ViewPane) part; |
| IViewReference ref = (IViewReference) pane |
| .getPartReference(); |
| if (ref.getSecondaryId() != null) { |
| continue; |
| } |
| } |
| return part; |
| } |
| // check pattern matching placeholders |
| else if (part instanceof PartPlaceholder |
| && ((PartPlaceholder) part).hasWildCard()) { |
| StringMatcher sm = new StringMatcher(part.getID(), true, false); |
| if (sm.match(id)) { |
| matchingParts |
| .add(new MatchingPart(part.getID(), null, part)); |
| } |
| } else if (part instanceof EditorSashContainer) { |
| // Skip. |
| } else if (part instanceof ILayoutContainer) { |
| part = findPart(id, ((ILayoutContainer) part).getChildren(), |
| matchingParts); |
| if (part != null) { |
| return part; |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Find the first part that matches the specified |
| * primary and secondary id pair. Wild cards |
| * are supported. |
| */ |
| private LayoutPart findPart(String primaryId, String secondaryId, |
| LayoutPart[] parts, ArrayList matchingParts) { |
| for (int i = 0, length = parts.length; i < length; i++) { |
| LayoutPart part = parts[i]; |
| // check containers first |
| if (part instanceof ILayoutContainer) { |
| LayoutPart testPart = findPart(primaryId, secondaryId, |
| ((ILayoutContainer) part).getChildren(), matchingParts); |
| if (testPart != null) { |
| return testPart; |
| } |
| } |
| // check for view part equality |
| if (part instanceof ViewPane) { |
| ViewPane pane = (ViewPane) part; |
| IViewReference ref = (IViewReference) pane.getPartReference(); |
| if (ref.getId().equals(primaryId) |
| && ref.getSecondaryId() != null |
| && ref.getSecondaryId().equals(secondaryId)) { |
| return part; |
| } |
| } |
| // check placeholders |
| else if ((parts[i] instanceof PartPlaceholder)) { |
| String id = part.getID(); |
| |
| // optimization: don't bother parsing id if it has no separator -- it can't match |
| String phSecondaryId = ViewFactory.extractSecondaryId(id); |
| if (phSecondaryId == null) { |
| // but still need to check for wildcard case |
| if (id.equals(PartPlaceholder.WILD_CARD)) { |
| matchingParts.add(new MatchingPart(id, null, part)); |
| } |
| continue; |
| } |
| |
| String phPrimaryId = ViewFactory.extractPrimaryId(id); |
| // perfect matching pair |
| if (phPrimaryId.equals(primaryId) |
| && phSecondaryId.equals(secondaryId)) { |
| return part; |
| } |
| // check for partial matching pair |
| StringMatcher sm = new StringMatcher(phPrimaryId, true, false); |
| if (sm.match(primaryId)) { |
| sm = new StringMatcher(phSecondaryId, true, false); |
| if (sm.match(secondaryId)) { |
| matchingParts.add(new MatchingPart(phPrimaryId, |
| phSecondaryId, part)); |
| } |
| } |
| } else if (part instanceof EditorSashContainer) { |
| // Skip. |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Returns true if a placeholder exists for a given ID. |
| */ |
| public boolean hasPlaceholder(String id) { |
| return hasPlaceholder(id, null); |
| } |
| |
| /** |
| * Returns true if a placeholder exists for a given ID. |
| */ |
| public boolean hasPlaceholder(String primaryId, String secondaryId) { |
| LayoutPart testPart; |
| if (secondaryId == null) { |
| testPart = findPart(primaryId); |
| } else { |
| testPart = findPart(primaryId, secondaryId); |
| } |
| return (testPart != null && testPart instanceof PartPlaceholder); |
| } |
| |
| /** |
| * Returns the layout container. |
| */ |
| public ViewSashContainer getLayout() { |
| return mainLayout; |
| } |
| |
| /** |
| * Gets the active state. |
| */ |
| public boolean isActive() { |
| return active; |
| } |
| |
| /** |
| * Returns whether the presentation is zoomed. |
| * |
| * <strong>NOTE:</strong> As of 3.3 this method should always return 'false' |
| * when using the new min/max behavior. It is only used for |
| * legacy 'zoom' handling. |
| */ |
| public boolean isZoomed() { |
| return mainLayout.getZoomedPart() != null; |
| } |
| |
| /** |
| * @return The currently maxmized stack (if any) |
| */ |
| public PartStack getMaximizedStack() { |
| return maximizedStack; |
| } |
| |
| /** |
| * Sets the currently maximized stack. Used for query |
| * and 'unZoom' purposes in the 3.3 presentation. |
| * |
| * @param stack The newly maximized stack |
| */ |
| public void setMaximizedStack(PartStack stack) { |
| if (stack == maximizedStack) |
| return; |
| |
| maximizedStack = stack; |
| } |
| |
| /** |
| * Returns the ratio that should be used when docking the given source |
| * part onto the given target |
| * |
| * @param source newly added part |
| * @param target existing part being dragged over |
| * @return the final size of the source part (wrt the current size of target) |
| * after it is docked |
| */ |
| public static float getDockingRatio(LayoutPart source, LayoutPart target) { |
| if ((source instanceof ViewPane || source instanceof ViewStack) |
| && target instanceof EditorSashContainer) { |
| return 0.25f; |
| } |
| return 0.5f; |
| } |
| |
| /** |
| * Returns whether changes to a part will affect zoom. There are a few |
| * conditions for this .. - we are zoomed. - the part is contained in the |
| * main window. - the part is not the zoom part - the part is not a fast |
| * view - the part and the zoom part are not in the same editor workbook |
| * - the part and the zoom part are not in the same view stack. |
| */ |
| public boolean partChangeAffectsZoom(LayoutPart pane) { |
| return pane.isObscuredByZoom(); |
| } |
| |
| /** |
| * Remove all references to a part. |
| */ |
| public void removePart(LayoutPart part) { |
| |
| // Reparent the part back to the main window |
| Composite parent = mainLayout.getParent(); |
| part.reparent(parent); |
| |
| // Replace part with a placeholder |
| ILayoutContainer container = part.getContainer(); |
| if (container != null) { |
| String placeHolderId = part.getPlaceHolderId(); |
| container.replace(part, new PartPlaceholder(placeHolderId)); |
| |
| // If the parent is root we're done. Do not try to replace |
| // it with placeholder. |
| if (container == mainLayout) { |
| return; |
| } |
| |
| // If the parent is empty replace it with a placeholder. |
| LayoutPart[] children = container.getChildren(); |
| if (children != null) { |
| boolean allInvisible = true; |
| if (container instanceof ViewStack && !((ViewStack) container).isMinimized && ((ViewStack) container).getDurable()) { |
| allInvisible = false; |
| } else { |
| for (int i = 0, length = children.length; i < length; i++) { |
| if (!(children[i] instanceof PartPlaceholder)) { |
| allInvisible = false; |
| break; |
| } |
| } |
| } |
| if (allInvisible && (container instanceof LayoutPart)) { |
| // what type of window are we in? |
| LayoutPart cPart = (LayoutPart) container; |
| //Window oldWindow = cPart.getWindow(); |
| // RAP [rh] DetachedWindow not supported |
| // boolean wasDocked = cPart.isDocked(); |
| // Shell oldShell = cPart.getShell(); |
| // if (wasDocked) { |
| |
| // PR 1GDFVBY: ViewStack not disposed when page |
| // closed. |
| if (container instanceof ViewStack) { |
| ((ViewStack) container).dispose(); |
| } |
| |
| // replace the real container with a |
| // ContainerPlaceholder |
| ILayoutContainer parentContainer = cPart.getContainer(); |
| ContainerPlaceholder placeholder = new ContainerPlaceholder( |
| cPart.getID()); |
| placeholder.setRealContainer(container); |
| parentContainer.replace(cPart, placeholder); |
| |
| // RAP [rh] DetachedWindow not supported |
| // } else { |
| // DetachedPlaceHolder placeholder = new DetachedPlaceHolder( |
| // "", oldShell.getBounds()); //$NON-NLS-1$ |
| // for (int i = 0, length = children.length; i < length; i++) { |
| // children[i].getContainer().remove(children[i]); |
| // children[i].setContainer(placeholder); |
| // placeholder.add(children[i]); |
| // } |
| // detachedPlaceHolderList.add(placeholder); |
| // DetachedWindow w = (DetachedWindow)oldShell.getData(); |
| // oldShell.close(); |
| // detachedWindowList.remove(w); |
| // } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Add a part to the presentation. |
| * |
| * Note: unlike all other LayoutParts, PartPlaceholders will still point to |
| * their parent container even when it is inactive. This method relies on this |
| * fact to locate the parent. |
| */ |
| public void replacePlaceholderWithPart(LayoutPart part) { |
| |
| // Look for a PartPlaceholder that will tell us how to position this |
| // object |
| PartPlaceholder[] placeholders = collectPlaceholders(); |
| for (int i = 0, length = placeholders.length; i < length; i++) { |
| if (placeholders[i].getCompoundId().equals(part.getCompoundId())) { |
| // found a matching placeholder which we can replace with the |
| // new View |
| ILayoutContainer container = placeholders[i].getContainer(); |
| if (container != null) { |
| if (container instanceof ContainerPlaceholder) { |
| // One of the children is now visible so replace the |
| // ContainerPlaceholder with the real container |
| ContainerPlaceholder containerPlaceholder = (ContainerPlaceholder) container; |
| ILayoutContainer parentContainer = containerPlaceholder |
| .getContainer(); |
| container = (ILayoutContainer) containerPlaceholder |
| .getRealContainer(); |
| if (container instanceof LayoutPart) { |
| parentContainer.replace(containerPlaceholder, |
| (LayoutPart) container); |
| } |
| containerPlaceholder.setRealContainer(null); |
| } |
| container.replace(placeholders[i], part); |
| return; |
| } |
| } |
| } |
| |
| } |
| |
| /** |
| * @see org.eclipse.ui.IPersistable |
| */ |
| public IStatus restoreState(IMemento memento) { |
| // Restore main window. |
| IMemento childMem = memento |
| .getChild(IWorkbenchConstants.TAG_MAIN_WINDOW); |
| IStatus r = mainLayout.restoreState(childMem); |
| |
| //RAP [rh] DetachedWindow not supported |
| // // Restore each floating window. |
| // if (detachable) { |
| // IMemento detachedWindows[] = memento |
| // .getChildren(IWorkbenchConstants.TAG_DETACHED_WINDOW); |
| // for (int nX = 0; nX < detachedWindows.length; nX++) { |
| // DetachedWindow win = new DetachedWindow(page); |
| // detachedWindowList.add(win); |
| // win.restoreState(detachedWindows[nX]); |
| // } |
| // IMemento childrenMem[] = memento |
| // .getChildren(IWorkbenchConstants.TAG_HIDDEN_WINDOW); |
| // for (int i = 0, length = childrenMem.length; i < length; i++) { |
| // DetachedPlaceHolder holder = new DetachedPlaceHolder( |
| // "", new Rectangle(0, 0, 0, 0)); //$NON-NLS-1$ |
| // holder.restoreState(childrenMem[i]); |
| // detachedPlaceHolderList.add(holder); |
| // } |
| // } |
| |
| // Get the cached id of the currently maximized stack |
| maximizedStackId = childMem.getString(IWorkbenchConstants.TAG_MAXIMIZED); |
| |
| return r; |
| } |
| |
| /** |
| * @see org.eclipse.ui.IPersistable |
| */ |
| public IStatus saveState(IMemento memento) { |
| // Persist main window. |
| IMemento childMem = memento |
| .createChild(IWorkbenchConstants.TAG_MAIN_WINDOW); |
| IStatus r = mainLayout.saveState(childMem); |
| |
| // RAP [rh] DetachedWindow not supported |
| // if (detachable) { |
| // // Persist each detached window. |
| // for (int i = 0, length = detachedWindowList.size(); i < length; i++) { |
| // DetachedWindow window = (DetachedWindow) detachedWindowList |
| // .get(i); |
| // childMem = memento |
| // .createChild(IWorkbenchConstants.TAG_DETACHED_WINDOW); |
| // window.saveState(childMem); |
| // } |
| // for (int i = 0, length = detachedPlaceHolderList.size(); i < length; i++) { |
| // DetachedPlaceHolder holder = (DetachedPlaceHolder) detachedPlaceHolderList |
| // .get(i); |
| // childMem = memento |
| // .createChild(IWorkbenchConstants.TAG_HIDDEN_WINDOW); |
| // holder.saveState(childMem); |
| // } |
| // } |
| |
| // Write out the id of the maximized (View) stack (if any) |
| // NOTE: we only write this out if it's a ViewStack since the |
| // Editor Area is handled by the perspective |
| if (maximizedStack instanceof ViewStack) { |
| childMem.putString(IWorkbenchConstants.TAG_MAXIMIZED, maximizedStack.getID()); |
| } |
| else if (maximizedStackId != null) { |
| // Maintain the cache if the perspective has never been activated |
| childMem.putString(IWorkbenchConstants.TAG_MAXIMIZED, maximizedStackId); |
| } |
| |
| return r; |
| } |
| |
| /** |
| * Zoom in on a particular layout part. |
| */ |
| public void zoomIn(IWorkbenchPartReference ref) { |
| PartPane pane = ((WorkbenchPartReference) ref).getPane(); |
| |
| |
| parentWidget.setRedraw(false); |
| try { |
| pane.requestZoomIn(); |
| } finally { |
| parentWidget.setRedraw(true); |
| } |
| } |
| |
| /** |
| * Zoom out. |
| */ |
| public void zoomOut() { |
| // New 3.3 behavior |
| if (Perspective.useNewMinMax(perspective)) { |
| if (maximizedStack != null) |
| maximizedStack.setState(IStackPresentationSite.STATE_RESTORED); |
| return; |
| } |
| |
| LayoutPart zoomPart = mainLayout.getZoomedPart(); |
| if (zoomPart != null) { |
| zoomPart.requestZoomOut(); |
| } |
| } |
| |
| /** |
| * Forces the perspective to have no zoomed or minimized parts. |
| * This is used when switching to the 3.3 presentation... |
| */ |
| public void forceNoZoom() { |
| // Ensure that nobody's zoomed |
| zoomOut(); |
| |
| // Now, walk the layout ensuring that nothing is minimized |
| LayoutPart[] kids = mainLayout.getChildren(); |
| for (int i = 0; i < kids.length; i++) { |
| if (kids[i] instanceof ViewStack) { |
| ((ViewStack)kids[i]).setMinimized(false); |
| } |
| else if (kids[i] instanceof EditorSashContainer) { |
| LayoutPart[] editorStacks = ((EditorSashContainer)kids[i]).getChildren(); |
| for (int j = 0; j < editorStacks.length; j++) { |
| if (editorStacks[j] instanceof EditorStack) { |
| ((EditorStack)editorStacks[j]).setMinimized(false); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Captures the current bounds of all ViewStacks and the editor |
| * area and puts them into an ID -> Rectangle map. This info is |
| * used to cache the bounds so that we can correctly place minimized |
| * stacks during a 'maximized' operation (where the iterative min's |
| * affect the current layout while being performed. |
| */ |
| public void updateBoundsMap() { |
| boundsMap.clear(); |
| |
| // Walk the layout gathering the current bounds of each stack |
| // and the editor area |
| LayoutPart[] kids = mainLayout.getChildren(); |
| for (int i = 0; i < kids.length; i++) { |
| if (kids[i] instanceof ViewStack) { |
| ViewStack vs = (ViewStack)kids[i]; |
| boundsMap.put(vs.getID(), vs.getBounds()); |
| } |
| else if (kids[i] instanceof EditorSashContainer) { |
| EditorSashContainer esc = (EditorSashContainer)kids[i]; |
| boundsMap.put(esc.getID(), esc.getBounds()); |
| } |
| } |
| } |
| |
| /** |
| * Resets the bounds map so that it won't interfere with normal minimize |
| * operayions |
| */ |
| public void resetBoundsMap() { |
| boundsMap.clear(); |
| } |
| |
| public Rectangle getCachedBoundsFor(String id) { |
| return (Rectangle) boundsMap.get(id); |
| } |
| } |