blob: 4e59501f3bff3f8bf12dc12791949d9c31bca8da [file] [log] [blame]
/*******************************************************************************
* 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;
}
}