| /******************************************************************************* |
| * Copyright (c) 2007 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 |
| ******************************************************************************/ |
| |
| package org.eclipse.ui.internal; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.core.runtime.MultiStatus; |
| import org.eclipse.jface.util.Geometry; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.graphics.Rectangle; |
| import org.eclipse.ui.IMemento; |
| import org.eclipse.ui.IPerspectiveDescriptor; |
| import org.eclipse.ui.IPerspectiveListener2; |
| import org.eclipse.ui.IViewReference; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.IWorkbenchPartReference; |
| import org.eclipse.ui.internal.StartupThreading.StartupRunnable; |
| import org.eclipse.ui.internal.layout.IWindowTrim; |
| import org.eclipse.ui.internal.layout.LayoutUtil; |
| import org.eclipse.ui.internal.layout.TrimLayout; |
| import org.eclipse.ui.internal.presentations.PresentablePart; |
| import org.eclipse.ui.internal.presentations.util.TabbedStackPresentation; |
| import org.eclipse.ui.internal.tweaklets.Animations; |
| import org.eclipse.ui.internal.tweaklets.Tweaklets; |
| import org.eclipse.ui.internal.util.Util; |
| import org.eclipse.ui.presentations.IPresentablePart; |
| import org.eclipse.ui.presentations.IStackPresentationSite; |
| |
| /** |
| * Manage all Fast views for a particular perspective. As of 3.3 fast views |
| * appear in more than one manner (legacy FVB and Trim Stacks). The manager is |
| * responsible for providing a single implementation for the methods relating to |
| * fast views regardless of their UI presentation. |
| * |
| * @since 3.3 |
| * |
| */ |
| public class FastViewManager { |
| private Perspective perspective; |
| private WorkbenchPage page; |
| private WorkbenchWindow wbw; |
| private TrimLayout tbm; |
| |
| /** |
| * Maps a String to a list of IViewReferences. The string represents the |
| * 'id' of either the legacy FBV or the ViewStack id of some stack which may |
| * have elements in the trim. |
| * <p> |
| * NOTE: For TrimStacks, the order of the view ref's in the contained list |
| * is the order in which they will appear in the tab folder when the stack |
| * un-minimizes. |
| * </p> |
| */ |
| private Map idToFastViewsMap = new HashMap(); |
| |
| /** |
| * Batch update management |
| */ |
| private boolean deferringUpdates = false; |
| |
| /** |
| * animation whose life-cycle spans a |
| * 'deferUpdates' cycle. |
| */ |
| private AnimationEngine batchAnimation = null; |
| |
| /** |
| * Used for non-deferred animations |
| */ |
| private AnimationEngine oneShotAnimation = null; |
| //private RectangleAnimation oneShotAnimation = null; |
| |
| private IPerspectiveListener2 perspListener = new IPerspectiveListener2() { |
| public void perspectiveActivated(IWorkbenchPage page, |
| IPerspectiveDescriptor perspective) { |
| // Only listen for changes in -this- perspective |
| if (FastViewManager.this.perspective.getDesc() == perspective) |
| handlePerspectiveActivation(page, perspective); |
| } |
| |
| public void perspectiveChanged(IWorkbenchPage changedPage, |
| IPerspectiveDescriptor perspective, |
| IWorkbenchPartReference partRef, String changeId) { |
| // Only listen for changes in -this- perspective |
| if (FastViewManager.this.perspective.getDesc() == perspective) |
| handlePerspectiveChange(changedPage, perspective, partRef, |
| changeId); |
| } |
| |
| public void perspectiveChanged(IWorkbenchPage changedPage, |
| IPerspectiveDescriptor perspective, String changeId) { |
| // Only listen for changes in -this- perspective |
| if (FastViewManager.this.perspective.getDesc() == perspective) |
| handlePerspectiveChange(changedPage, perspective, changeId); |
| } |
| }; |
| |
| /** |
| * Creates a new manager for a particular perspective |
| * |
| * @param perspective |
| * @param page |
| */ |
| public FastViewManager(Perspective perspective, WorkbenchPage page) { |
| this.perspective = perspective; |
| this.page = page; |
| |
| // Access the trim manager for this window |
| wbw = (WorkbenchWindow) page.getWorkbenchWindow(); |
| tbm = (TrimLayout) wbw.getTrimManager(); |
| } |
| |
| protected void handlePerspectiveActivation(IWorkbenchPage activatingPage, |
| IPerspectiveDescriptor activatingPerspective) { |
| // If this perspective is activating then update the |
| // legacy FVB to show this perspective's refs |
| if (activatingPage == page |
| && perspective.getDesc() == activatingPerspective) |
| updateTrim(FastViewBar.FASTVIEWBAR_ID); |
| } |
| |
| protected void handlePerspectiveChange(IWorkbenchPage changedPage, |
| IPerspectiveDescriptor changedPerspective, |
| IWorkbenchPartReference partRef, String changeId) { |
| // Only handle changes for our perspective |
| if (changedPage != page && perspective.getDesc() != changedPerspective) |
| return; |
| |
| if (changeId.equals(IWorkbenchPage.CHANGE_VIEW_HIDE)) { |
| if (partRef instanceof IViewReference) { |
| ViewReference ref = (ViewReference) partRef; |
| if (ref.getPane().getContainer() instanceof ViewStack) { |
| int viewCount = 0; |
| LayoutPart[] children = ref.getPane().getContainer().getChildren(); |
| for (int i = 0; i < children.length; i++) { |
| if (children[i] instanceof ViewPane && children[i] != ref.getPane()) |
| viewCount++; |
| } |
| |
| if (viewCount == 0) |
| ref.getPane().getStack().setState(IStackPresentationSite.STATE_RESTORED); |
| } |
| } |
| // Remove the view from any FV list that it may be in |
| // Do this here since the view's controls may be about |
| // to be disposed... |
| removeViewReference((IViewReference) partRef, false, true); |
| } |
| |
| if (changeId.equals(IWorkbenchPage.CHANGE_FAST_VIEW_REMOVE)) { |
| // Remove the view from any FV list that it may be in |
| // Do this here since the view's controls may be about |
| // to be disposed... |
| removeViewReference((IViewReference) partRef, false, true); |
| } |
| } |
| |
| protected void handlePerspectiveChange(IWorkbenchPage changedPage, |
| IPerspectiveDescriptor changedPerspective, String changeId) { |
| } |
| |
| /** |
| * @return The list of current fast views associated with the given id or |
| * the complete list of fastviews if the id == null. |
| */ |
| public List getFastViews(String forId) { |
| List fvs = new ArrayList(); |
| |
| Iterator mapIter = idToFastViewsMap.keySet().iterator(); |
| while (mapIter.hasNext()) { |
| String id = (String) mapIter.next(); |
| if (forId == null || forId.equals(id)) { |
| List fvList = (List) idToFastViewsMap.get(id); |
| for (Iterator fvIter = fvList.iterator(); fvIter.hasNext();) { |
| fvs.add(fvIter.next()); |
| } |
| } |
| } |
| |
| return fvs; |
| } |
| |
| /** |
| * Casues the given {@link IViewReference} to be added to the list |
| * identified by the 'id' parameter. The reference is added at the specified |
| * index or at the end if the index is -1. If there was a previous entry for |
| * this ref it will be removed so that only the ref will only ever be in one |
| * list at a time. |
| * <p> |
| * NOTE: The trim life-cycle is managed at the stack level so there -must- |
| * be an entry in the map and a corresponding trim element before calling |
| * this method, |
| * </p> |
| * <p> |
| * The page/perspective are updated to make the view a fastview if |
| * necessary. |
| * </p> |
| * |
| * @param id |
| * The id of the {@link IWindowTrim} that is to show the ref |
| * @param index |
| * The index to insert the ref at |
| * @param ref |
| * The {@link IViewReference} to add |
| * @param update |
| * cause the trim to update if <code>true</code> |
| */ |
| public void addViewReference(String id, int index, IViewReference ref, |
| boolean update) { |
| if (id == null || ref == null) |
| return; |
| |
| List fvList = (List) idToFastViewsMap.get(id); |
| if (fvList == null) { |
| // Not in the model yet, add it |
| fvList = new ArrayList(); |
| idToFastViewsMap.put(id, fvList); |
| } |
| |
| // bounds checking |
| if (index < 0 || index > fvList.size()) |
| index = fvList.size(); |
| |
| // Is it already in a list? |
| String curLocation = getIdForRef(ref); |
| if (curLocation != null) { |
| // is it the same list that it's being added to? |
| if (id.equals(curLocation)) { |
| int curIndex = fvList.indexOf(ref); |
| if (index == curIndex) |
| return; // No-Op |
| |
| // If we're inserting after where we |
| // were then decrement the index to |
| // account for the removal of the old ref |
| if (index > curIndex) |
| index--; |
| } |
| |
| // Remove it... |
| removeViewReference(ref, false, true); |
| } else { |
| // It's not a fastview, make it one |
| makeFast(ref, true, false); |
| } |
| |
| fvList.add(index, ref); |
| |
| // Note that the update call will create and show the ViewStackTrimToolbar |
| // if necessary |
| if (update) |
| updateTrim(id); |
| } |
| |
| /** |
| * Create the Trim element for the stack containing the given reference |
| * |
| * @param suggestedSide |
| * @param paneOrientation |
| * @param ref |
| * The {@link IViewReference} whose stack needs trim creation. |
| */ |
| private ViewStackTrimToolBar getTrimForViewStack(String id, |
| int suggestedSide, int paneOrientation) { |
| // Do we already have one?? |
| ViewStackTrimToolBar trim = (ViewStackTrimToolBar) tbm.getTrim(id); |
| if (trim == null) { |
| int cachedSide = tbm.getPreferredArea(id); |
| if (cachedSide != -1) |
| suggestedSide = cachedSide; |
| |
| IWindowTrim beforeMe = tbm.getPreferredLocation(id); |
| |
| trim = new ViewStackTrimToolBar(id, suggestedSide, |
| paneOrientation, wbw); |
| tbm.addTrim(suggestedSide, trim, beforeMe); |
| updateTrim(trim.getId()); |
| } |
| |
| return trim; |
| } |
| |
| /** |
| * Causes the trim element associated with the id to synch itself with the |
| * current list of views. This method will create a new ViewStackTrimToolbar |
| * if necessary (i.e. on the first call after views have been added to the map) |
| * and will also hide the trim element when the number of views in the mapped |
| * list goes to zero. |
| * |
| * @param id |
| * The id of the {@link IWindowTrim} to update |
| */ |
| private void updateTrim(String id) { |
| // Get the trim part from the trim manager |
| IWindowTrim trim = tbm.getTrim(id); |
| |
| // If it's not there there's not much we can do |
| if (trim == null) |
| return; |
| |
| // If there are no fast views for the bar then hide it |
| List fvs = (List) idToFastViewsMap.get(id); |
| if (fvs != null && fvs.size() == 0 |
| && !FastViewBar.FASTVIEWBAR_ID.equals(id)) { |
| if (trim.getControl().getVisible()) { |
| tbm.setTrimVisible(trim, false); |
| tbm.forceLayout(); |
| } |
| return; |
| } |
| |
| // Ensure that the trim is displayed |
| if (!trim.getControl().getVisible()) { |
| tbm.setTrimVisible(trim, true); |
| } |
| |
| if (trim instanceof FastViewBar) { |
| FastViewBar fvb = (FastViewBar) trim; |
| fvb.update(true); |
| } else if (trim instanceof ViewStackTrimToolBar) { |
| ViewStackTrimToolBar vstb = (ViewStackTrimToolBar) trim; |
| vstb.update(true); |
| vstb.getControl().pack(); |
| LayoutUtil.resize(trim.getControl()); |
| } |
| |
| tbm.forceLayout(); |
| } |
| |
| /** |
| * Remove the view reference from its existing location |
| * |
| * @param ref |
| * The {@link IViewReference} to remove |
| */ |
| public void removeViewReference(IViewReference ref, boolean makeUnfast, boolean update) { |
| String id = getIdForRef(ref); |
| |
| if (id != null) { |
| // Remove the ref |
| List fvList = (List) idToFastViewsMap.get(id); |
| fvList.remove(ref); |
| |
| if (makeUnfast) |
| makeFast(ref, false, false); |
| |
| if (update) |
| updateTrim(id); |
| } |
| } |
| |
| /** |
| * |
| * @param ref |
| * @param makeFast |
| * @param activate |
| */ |
| private void makeFast(IViewReference ref, boolean makeFast, boolean activate) { |
| if (ref == null || page == null) |
| return; |
| |
| if (makeFast) { |
| page.makeFastView(ref); |
| } else { |
| page.removeFastView(ref); |
| |
| if (activate) { |
| IWorkbenchPart toActivate = ref.getPart(true); |
| if (toActivate != null) { |
| page.activate(toActivate); |
| } |
| } |
| } |
| } |
| |
| /** |
| * @param ref |
| * The IViewRference to check |
| * @return true iff the ref is in -any- list |
| */ |
| boolean isFastView(IViewReference ref) { |
| return getIdForRef(ref) != null; |
| } |
| |
| /** |
| * @param ref |
| * The IViewRference to check |
| * @return The id of the trim bar currently showing the reference or |
| * <code>null</code> if it's not in any list |
| */ |
| public String getIdForRef(IViewReference ref) { |
| Iterator mapIter = idToFastViewsMap.keySet().iterator(); |
| while (mapIter.hasNext()) { |
| String id = (String) mapIter.next(); |
| List fvList = (List) idToFastViewsMap.get(id); |
| if (fvList.contains(ref)) |
| return id; |
| } |
| |
| return null; |
| } |
| |
| /** |
| * @return The side that the fast view pane should be attached to based on |
| * the position of the trim element containing the ref. |
| */ |
| public int getViewSide(IViewReference ref) { |
| IWindowTrim trim = getTrimForRef(ref); |
| if (trim == null) |
| return SWT.BOTTOM; |
| |
| int curSide = SWT.BOTTOM; |
| int paneOrientation = SWT.BOTTOM; |
| |
| if (trim instanceof ViewStackTrimToolBar) { |
| curSide = ((ViewStackTrimToolBar) trim).getCurrentSide(); |
| paneOrientation = ((ViewStackTrimToolBar) trim) |
| .getPaneOrientation(); |
| } else if (trim instanceof FastViewBar) { |
| curSide = ((FastViewBar) trim).getSide(); |
| paneOrientation = ((FastViewBar) trim).getOrientation(ref); |
| } |
| |
| // Get trim layout info |
| Point trimCenter = Geometry.centerPoint(trim.getControl().getBounds()); |
| Point shellCenter = Geometry.centerPoint(trim.getControl().getShell() |
| .getClientArea()); |
| |
| // Horizontal has to snap to either TOP or BOTTOM... |
| if (paneOrientation == SWT.HORIZONTAL) { |
| if (curSide == SWT.TOP || curSide == SWT.BOTTOM) |
| return curSide; |
| |
| // Are we on the top or bottom 'end' of the trim area? |
| return (trimCenter.y < shellCenter.y) ? SWT.TOP : SWT.BOTTOM; |
| } |
| |
| if (paneOrientation == SWT.VERTICAL) { |
| if (curSide == SWT.LEFT || curSide == SWT.RIGHT) |
| return curSide; |
| |
| // Are we on the left or right 'end' of the trim area? |
| return (trimCenter.x < shellCenter.x) ? SWT.LEFT : SWT.RIGHT; |
| } |
| |
| return SWT.BOTTOM; |
| } |
| |
| /** |
| * Return the trim element showing the given reference |
| * |
| * @param ref |
| * The reference to find |
| * @return the IWindowTrim showing the ref |
| */ |
| private IWindowTrim getTrimForRef(IViewReference ref) { |
| String id = getIdForRef(ref); |
| if (id == null) |
| return null; // Not in trim |
| |
| return tbm.getTrim(id); |
| } |
| |
| /** |
| * @return a List of <code>IViewReference</code> sorted into the order in |
| * which they appear in the visual stack. |
| */ |
| private List getTrueViewOrder(ViewStack stack) { |
| List orderedViews = new ArrayList(); |
| IPresentablePart[] parts = null; |
| if (stack.getPresentation() instanceof TabbedStackPresentation) { |
| TabbedStackPresentation tsp = (TabbedStackPresentation) stack |
| .getPresentation(); |
| // KLUDGE!! uses a 'testing only' API to get the parts in their 'visible' order |
| parts = tsp.getPartList(); |
| } |
| |
| // If we didn't get the parts from the tab list then try the presentable part API |
| // ViewStack's declared 'no title' fail the call above, returning an empty array |
| if (parts == null || parts.length == 0){ |
| // We'll have to process the parts in the order given... |
| // This is certain to fail on drag re-ordering of the |
| // icons in the trim since we have no API to inform the |
| // custom presentation |
| List partList = stack.getPresentableParts(); |
| parts = (IPresentablePart[]) partList.toArray(new IPresentablePart[partList.size()]); |
| } |
| |
| // Now, process the parts... |
| for (int i = 0; i < parts.length; i++) { |
| if (parts[i] instanceof PresentablePart) { |
| PresentablePart part = (PresentablePart) parts[i]; |
| IWorkbenchPartReference ref = part.getPane() |
| .getPartReference(); |
| if (ref instanceof IViewReference) |
| orderedViews.add(ref); |
| } |
| } |
| |
| return orderedViews; |
| } |
| |
| public void moveToTrim(ViewStack vs, boolean restoreOnUnzoom) { |
| // Don't do anything when initializing... |
| if (vs.getBounds().width == 0) |
| return; // indicates that we're startin up |
| |
| // If we're part of a 'maximize' operation then use the cached |
| // bounds... |
| Rectangle stackBounds = perspective.getPresentation().getCachedBoundsFor(vs.getID()); |
| |
| // OK, no cache means that we use the current stack position |
| if (stackBounds == null) |
| stackBounds = vs.getBounds(); |
| |
| int paneOrientation = (stackBounds.width > stackBounds.height) ? SWT.HORIZONTAL |
| : SWT.VERTICAL; |
| |
| // Remember the tab that was selected when we minimized |
| String selId = ""; //$NON-NLS-1$ |
| PartPane selectedTab = vs.getSelection(); |
| if (selectedTab != null) |
| selId = selectedTab.getCompoundId(); |
| |
| vs.deferUpdates(true); |
| |
| // animate the minimize |
| RectangleAnimationFeedbackBase animation = (RectangleAnimationFeedbackBase) getDeferrableAnimation().getFeedback(); |
| animation.addStartRect(vs.getControl()); |
| |
| //long startTick = System.currentTimeMillis(); |
| // Update the model first |
| List toMove = getTrueViewOrder(vs); |
| for (Iterator viewIter = toMove.iterator(); viewIter.hasNext();) { |
| IViewReference ref = (IViewReference) viewIter.next(); |
| addViewReference(vs.getID(), -1, ref, false); |
| } |
| |
| vs.deferUpdates(false); |
| |
| // Find (or create) the trim stack to move to |
| ViewStackTrimToolBar vstb = getTrimForViewStack(vs.getID(), perspective |
| .calcStackSide(stackBounds), paneOrientation); |
| vstb.setRestoreOnUnzoom(restoreOnUnzoom); |
| vstb.setSelectedTabId(selId); |
| updateTrim(vstb.getId()); |
| |
| //System.out.println("minimize time: " + (System.currentTimeMillis()-startTick)); //$NON-NLS-1$ |
| if (vstb != null) { |
| animation.addEndRect(vstb.getControl()); |
| scheduleDeferrableAnimation(); |
| } |
| } |
| |
| /** |
| * Restore the trim element representing a ViewStack back into the |
| * presentation. |
| * |
| * @param viewStackTrimToolBar |
| * The trim version to restore |
| */ |
| public void restoreToPresentation(String id) { |
| ViewStackTrimToolBar vstb = getViewStackTrimToolbar(id); |
| |
| // The IntroPart uses the old min/max behavior; ensure that |
| // we were really a minimized trim stack |
| if (vstb == null) |
| return; |
| |
| // remove any showing fast view |
| page.hideFastView(); |
| |
| // The stored id may be 'compound' if it's a multi-instance |
| // view; split out the secondary id (if any) |
| String selectedTabId = vstb.getSelectedTabId(); |
| String[] idParts = Util.split(selectedTabId, ':'); |
| if (idParts[0].length() == selectedTabId.length()) |
| idParts[1] = null; |
| |
| List fvs = getFastViews(id); |
| for (Iterator fvIter = fvs.iterator(); fvIter.hasNext();) { |
| IViewReference ref = (IViewReference) fvIter.next(); |
| removeViewReference(ref, true, !fvIter.hasNext()); |
| } |
| |
| // Restore the correct tab to the 'top' |
| LayoutPart stack = perspective.getPresentation().findPart(id, null); |
| if (stack instanceof PartStack) { |
| LayoutPart selTab = perspective.getPresentation().findPart(idParts[0], idParts[1]); |
| if (selTab instanceof PartPane && selTab instanceof ViewPane) { |
| ((PartStack)stack).setSelection(selTab); |
| |
| // activate the view if we're not doing a compound operation |
| if (!deferringUpdates) |
| ((ViewPane)selTab).requestActivation(); |
| } |
| } |
| |
| // Hide the Trim |
| updateTrim(id); |
| } |
| |
| /** |
| * Restore all fact view stacks created as part of a zoom |
| */ |
| public void restoreZoomedViewStacks() { |
| Iterator mapIter = idToFastViewsMap.keySet().iterator(); |
| while (mapIter.hasNext()) { |
| String id = (String) mapIter.next(); |
| IWindowTrim trim = tbm.getTrim(id); |
| if (trim != null && trim instanceof ViewStackTrimToolBar) { |
| ViewStackTrimToolBar vstb = (ViewStackTrimToolBar) trim; |
| if (vstb.restoreOnUnzoom()) |
| restoreToPresentation(vstb.getId()); |
| } |
| } |
| } |
| |
| /** |
| * @param ref |
| * Sets the ref of the icon |
| * @param selected |
| * the selection state of the icon |
| */ |
| public void setFastViewIconSelection(IViewReference ref, boolean selected) { |
| String id = getIdForRef(ref); |
| IWindowTrim trim = tbm.getTrim(id); |
| if (trim instanceof ViewStackTrimToolBar) { |
| ViewStackTrimToolBar vstb = (ViewStackTrimToolBar) trim; |
| vstb.setIconSelection(ref, selected); |
| } else if (trim instanceof FastViewBar) { |
| FastViewBar fvb = (FastViewBar) trim; |
| if (selected) { |
| fvb.setSelection(ref); |
| } else { |
| if (ref == fvb.getSelection()) { |
| fvb.setSelection(null); |
| } |
| } |
| } |
| |
| } |
| |
| /** |
| * Activate the manager. Called from the Perspecive's 'onActivate' |
| */ |
| public void activate() { |
| wbw.addPerspectiveListener(perspListener); |
| setTrimStackVisibility(true); |
| } |
| |
| /** |
| * Activate the manager. Called from the Perspecive's 'onActivate' |
| */ |
| public void deActivate() { |
| wbw.removePerspectiveListener(perspListener); |
| setTrimStackVisibility(false); |
| } |
| |
| /** |
| * Restore any trim stacks. This method is used when the presentation |
| * is switched back to 3.0; if we aren't using the new min/max story |
| * then we shouldn't -have- any trim stacks. |
| */ |
| public boolean restoreAllTrimStacks() { |
| boolean stacksWereRestored = false; |
| |
| Iterator mapIter = idToFastViewsMap.keySet().iterator(); |
| while (mapIter.hasNext()) { |
| String id = (String) mapIter.next(); |
| |
| // Skip the legacy FstViewBar |
| if (id.equals(FastViewBar.FASTVIEWBAR_ID)) |
| continue; |
| |
| // Restore the views |
| List fvs = getFastViews(id); |
| for (Iterator fvIter = fvs.iterator(); fvIter.hasNext();) { |
| IViewReference ref = (IViewReference) fvIter.next(); |
| removeViewReference(ref, true, !fvIter.hasNext()); |
| } |
| |
| // Blow the trim away |
| IWindowTrim trim = tbm.getTrim(id); |
| if (trim != null && trim instanceof ViewStackTrimToolBar) { |
| tbm.removeTrim(trim); |
| trim.getControl().dispose(); |
| |
| stacksWereRestored = true; |
| } |
| } |
| |
| tbm.forceLayout(); |
| |
| return stacksWereRestored; |
| } |
| |
| /** |
| * Show all non-empty trim stacks. Create the stack if necessary |
| */ |
| private void setTrimStackVisibility(boolean visible) { |
| Iterator mapIter = idToFastViewsMap.keySet().iterator(); |
| while (mapIter.hasNext()) { |
| String id = (String) mapIter.next(); |
| List fvs = getFastViews(id); |
| |
| // Never show 'empty' stacks |
| if (visible && fvs.size() == 0) |
| continue; |
| |
| IWindowTrim trim = tbm.getTrim(id); |
| if (trim != null && trim instanceof ViewStackTrimToolBar) { |
| ((ViewStackTrimToolBar)trim).update(true); |
| tbm.setTrimVisible(trim, visible); |
| } |
| } |
| } |
| |
| public void saveState(IMemento memento) { |
| // Output legacy fastviews |
| FastViewBar fvb = wbw.getFastViewBar(); |
| if (fvb != null) { |
| List fvRefs = getFastViews(FastViewBar.FASTVIEWBAR_ID); |
| if (fvRefs.size() > 0) { |
| IMemento childMem = memento |
| .createChild(IWorkbenchConstants.TAG_FAST_VIEWS); |
| Iterator itr = fvRefs.iterator(); |
| while (itr.hasNext()) { |
| IViewReference ref = (IViewReference) itr.next(); |
| IMemento viewMemento = childMem |
| .createChild(IWorkbenchConstants.TAG_VIEW); |
| String id = ViewFactory.getKey(ref); |
| viewMemento.putString(IWorkbenchConstants.TAG_ID, id); |
| float ratio = perspective.getFastViewWidthRatio(ref); |
| viewMemento.putFloat(IWorkbenchConstants.TAG_RATIO, ratio); |
| } |
| } |
| } |
| |
| // Write all the current (non-empty) bars |
| IMemento barsMemento = memento |
| .createChild(IWorkbenchConstants.TAG_FAST_VIEW_BARS); |
| |
| Iterator mapIter = idToFastViewsMap.keySet().iterator(); |
| while (mapIter.hasNext()) { |
| String id = (String) mapIter.next(); |
| |
| // Legacy FV's are stored above... |
| if (FastViewBar.FASTVIEWBAR_ID.equals(id)) |
| continue; |
| |
| List fvs = getFastViews(id); |
| if (fvs.size() > 0) { |
| IMemento barMemento = barsMemento |
| .createChild(IWorkbenchConstants.TAG_FAST_VIEW_BAR); |
| barMemento.putString(IWorkbenchConstants.TAG_ID, id); |
| |
| // Orientation / restore |
| ViewStackTrimToolBar vstb = (ViewStackTrimToolBar) tbm |
| .getTrim(id); |
| if (vstb != null) { |
| barMemento.putInteger( |
| IWorkbenchConstants.TAG_FAST_VIEW_SIDE, |
| vstb.getCurrentSide()); |
| |
| barMemento.putInteger( |
| IWorkbenchConstants.TAG_FAST_VIEW_ORIENTATION, |
| vstb.getPaneOrientation()); |
| |
| int boolVal = vstb.restoreOnUnzoom() ? 1 : 0; |
| barMemento.putInteger(IWorkbenchConstants.TAG_FAST_VIEW_STYLE, boolVal); |
| |
| barMemento.putString(IWorkbenchConstants.TAG_FAST_VIEW_SEL_ID, vstb.getSelectedTabId()); |
| } |
| |
| IMemento viewsMem = barMemento |
| .createChild(IWorkbenchConstants.TAG_FAST_VIEWS); |
| Iterator itr = fvs.iterator(); |
| while (itr.hasNext()) { |
| IMemento refMem = viewsMem |
| .createChild(IWorkbenchConstants.TAG_VIEW); |
| IViewReference ref = (IViewReference) itr.next(); |
| |
| // id |
| String viewId = ViewFactory.getKey(ref); |
| refMem.putString(IWorkbenchConstants.TAG_ID, viewId); |
| |
| // width ratio |
| float ratio = perspective.getFastViewWidthRatio(ref); |
| refMem.putFloat(IWorkbenchConstants.TAG_RATIO, ratio); |
| } |
| } |
| } |
| } |
| |
| public void restoreState(IMemento memento, MultiStatus result) { |
| // Load the fast views |
| IMemento fastViewsMem = memento |
| .getChild(IWorkbenchConstants.TAG_FAST_VIEWS); |
| |
| // -Replace- the current list with the one from the store |
| List refsList = new ArrayList(); |
| idToFastViewsMap.put(FastViewBar.FASTVIEWBAR_ID, refsList); |
| |
| if (fastViewsMem != null) { |
| IMemento[] views = fastViewsMem |
| .getChildren(IWorkbenchConstants.TAG_VIEW); |
| for (int x = 0; x < views.length; x++) { |
| // Get the view details. |
| IMemento childMem = views[x]; |
| IViewReference ref = perspective.restoreFastView(childMem, |
| result); |
| if (ref != null) |
| refsList.add(ref); |
| } |
| } |
| |
| // Load the Trim Stack info |
| IMemento barsMem = memento |
| .getChild(IWorkbenchConstants.TAG_FAST_VIEW_BARS); |
| |
| // It's not there for old workspaces |
| if (barsMem == null) |
| return; |
| |
| IMemento[] bars = barsMem |
| .getChildren(IWorkbenchConstants.TAG_FAST_VIEW_BAR); |
| for (int i = 0; i < bars.length; i++) { |
| final String id = bars[i].getString(IWorkbenchConstants.TAG_ID); |
| fastViewsMem = bars[i].getChild(IWorkbenchConstants.TAG_FAST_VIEWS); |
| |
| // -Replace- the current list with the one from the store |
| refsList = new ArrayList(); |
| idToFastViewsMap.put(id, refsList); |
| |
| if (fastViewsMem != null) { |
| IMemento[] views = fastViewsMem |
| .getChildren(IWorkbenchConstants.TAG_VIEW); |
| result.merge(perspective.createReferences(views)); |
| |
| // Create the trim area for the trim stack |
| // Only create the TB if there are views in it |
| if (views.length > 0) { |
| final int side = bars[i].getInteger( |
| IWorkbenchConstants.TAG_FAST_VIEW_SIDE) |
| .intValue(); |
| final int orientation = bars[i].getInteger( |
| IWorkbenchConstants.TAG_FAST_VIEW_ORIENTATION) |
| .intValue(); |
| int boolVal = bars[i].getInteger( |
| IWorkbenchConstants.TAG_FAST_VIEW_STYLE).intValue(); |
| final boolean restoreOnUnzoom = (boolVal > 0); |
| |
| final String selId = bars[i].getString(IWorkbenchConstants.TAG_FAST_VIEW_SEL_ID); |
| |
| // Create the stack |
| StartupThreading.runWithoutExceptions(new StartupRunnable() { |
| public void runWithException() throws Throwable { |
| ViewStackTrimToolBar vstb = getTrimForViewStack(id, side, orientation); |
| vstb.setRestoreOnUnzoom(restoreOnUnzoom); |
| if (selId != null) |
| vstb.setSelectedTabId(selId); |
| } |
| }); |
| } |
| |
| for (int x = 0; x < views.length; x++) { |
| // Get the view details. |
| IMemento childMem = views[x]; |
| IViewReference ref = perspective.restoreFastView(childMem, |
| result); |
| if (ref != null) |
| refsList.add(ref); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Returns the trim element for the given id if it exists. This |
| * will not be <code>null</code> if there are entries in the |
| * 'idToFastViewsMap' for this id. |
| * |
| * @param id The id of the view stack to get the trim toolbar for. |
| */ |
| public ViewStackTrimToolBar getViewStackTrimToolbar(String id) { |
| return (ViewStackTrimToolBar) tbm.getTrim(id); |
| } |
| |
| public void printFVModel() { |
| Iterator mapIter = idToFastViewsMap.keySet().iterator(); |
| while (mapIter.hasNext()) { |
| String id = (String) mapIter.next(); |
| List fvList = (List) idToFastViewsMap.get(id); |
| System.out.println("FastView: " + id + " count = " + fvList.size()); //$NON-NLS-1$//$NON-NLS-2$ |
| for (Iterator fvIter = fvList.iterator(); fvIter.hasNext();) { |
| IViewReference ref = (IViewReference) fvIter.next(); |
| System.out.println(" Ref: " + ref.getId()); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| /** |
| * Informs the manager that a batch operation has started |
| * (say 'maximize', where many stacks will change state). |
| * |
| * @param defer |
| * true when starting a batch operation |
| * false when ending the operation |
| */ |
| public void deferUpdates(boolean defer) { |
| if (defer && !deferringUpdates) { |
| deferringUpdates = defer; |
| |
| deferAnimations(true); |
| |
| return; |
| } |
| |
| // 'false': reset and run any necessary updates |
| deferringUpdates = false; |
| deferAnimations(false); |
| } |
| |
| /** |
| * When 'defer' is true we create a RectangleAnimation object |
| * to be used for any desired feedback. When ending it |
| * schedules the animation and resets. |
| * |
| * @param defer |
| * true when starting a batch operation |
| * false when ending the operation |
| */ |
| private void deferAnimations(boolean defer) { |
| if (defer) { |
| RectangleAnimationFeedbackBase feedback = ((Animations) Tweaklets |
| .get(Animations.KEY)).createFeedback(wbw.getShell()); |
| batchAnimation = new AnimationEngine(feedback, 400); |
| return; |
| } |
| |
| if (batchAnimation != null) |
| batchAnimation.schedule(); |
| batchAnimation = null; |
| } |
| |
| /** |
| * Returns the animation object appropriate for the deferred state |
| * @return Either a 'one-shot' or a 'batch' animation object |
| */ |
| private AnimationEngine getDeferrableAnimation() { |
| if (deferringUpdates) |
| return batchAnimation; |
| |
| // Create a 'one-shot' animation |
| RectangleAnimationFeedbackBase feedback = ((Animations) Tweaklets |
| .get(Animations.KEY)).createFeedback(wbw.getShell()); |
| oneShotAnimation = new AnimationEngine(feedback, 400); |
| return oneShotAnimation; |
| } |
| |
| private void scheduleDeferrableAnimation() { |
| if (deferringUpdates) |
| return; |
| |
| // We can only schedule the 'one-shot' animations |
| // the batch ones are sheduled at batch end |
| if (oneShotAnimation != null) |
| oneShotAnimation.schedule(); |
| oneShotAnimation = null; |
| } |
| |
| /** |
| * Returns the 'bottom/right' trim stack. This is used to |
| * match the old behavior when opening a new view that has no placeholder |
| * in the case where there WB is maximized. |
| * |
| * @return The 'bottom/right' trim stack or null if there are no |
| * defined trim stacks |
| */ |
| public ViewStackTrimToolBar getBottomRightTrimStack() { |
| ViewStackTrimToolBar blTrimStack = null; |
| Point blPt = new Point(0,0); |
| |
| Iterator mapIter = idToFastViewsMap.keySet().iterator(); |
| while (mapIter.hasNext()) { |
| String id = (String) mapIter.next(); |
| |
| // Skip the legacy FstViewBar |
| if (id.equals(FastViewBar.FASTVIEWBAR_ID)) |
| continue; |
| |
| if (getFastViews(id).size() > 0) { |
| // if we have views in the model then 'vstt' will not be null |
| ViewStackTrimToolBar vstt = getViewStackTrimToolbar(id); |
| Point loc = vstt.getControl().getLocation(); |
| if (loc.y > blPt.y || (loc.y == blPt.y && loc.x > blPt.x)) { |
| blPt = loc; |
| blTrimStack = vstt; |
| } |
| } |
| } |
| |
| return blTrimStack; |
| } |
| } |