blob: 663cb55d2eedd27f56f33656aa9f14aae43580e5 [file] [log] [blame]
package org.eclipse.ui.internal;
/**********************************************************************
Copyright (c) 2000, 2002 IBM Corp. and others.
All rights reserved.   This program and the accompanying materials
are made available under the terms of the Common Public License v0.5
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/cpl-v05.html
**********************************************************************/
import java.io.*;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.dialogs.*;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.*;
import org.eclipse.ui.internal.registry.*;
import org.eclipse.ui.part.ViewPart;
import java.util.List;
/**
* The ViewManager is a factory for workbench views.
*/
public class Perspective
{
private PerspectiveDescriptor descriptor;
protected WorkbenchPage page;
protected LayoutPart editorArea;
private PartPlaceholder editorHolder;
private ViewFactory viewFactory;
private ArrayList visibleActionSets;
private ArrayList alwaysOnActionSets;
private ArrayList alwaysOffActionSets;
private ArrayList newWizardActionIds;
private ArrayList showViewActionIds;
private ArrayList perspectiveActionIds;
private ArrayList fastViews;
private IViewPart activeFastView;
private IViewPart previousActiveFastView;
private IMemento memento;
protected PerspectivePresentation presentation;
final static private String VERSION_STRING = "0.016";//$NON-NLS-1$
// fields used by fast view resizing via a sash
private static final int SASH_SIZE = 3;
private static final int FASTVIEW_HIDE_STEPS = 3;
private static final RGB RGB_COLOR1 = new RGB(132, 130, 132);
private static final RGB RGB_COLOR2 = new RGB(143, 141, 138);
private static final RGB RGB_COLOR3 = new RGB(171, 168, 165);
private Color borderColor1;
private Color borderColor2;
private Color borderColor3;
private Map mapFastViewToWidthRatio = new HashMap();
private Sash fastViewSash;
private CoolBarLayout toolBarLayout;
//Number of open editors before reusing. If < 0, use the
//user preference settings.
private int reuseEditors = -1;
// resize listener to update fast view height and width when
// window resized.
Listener resizeListener = new Listener() {
public void handleEvent(Event event) {
if (event.type == SWT.Resize && activeFastView != null) {
ViewPane pane = getPane(activeFastView);
if (pane.isZoomed() == false) {
Rectangle bounds = pane.getBounds();
bounds.height = Math.max(0, getClientComposite().getSize().y);
float ratio = getFastViewWidthRatio(pane.getID());
bounds.width = Math.max(0, (int)((float)(getClientComposite().getSize().x) * ratio));
pane.setBounds(bounds);
fastViewSash.setBounds(bounds.width - SASH_SIZE, bounds.y, SASH_SIZE, bounds.height - SASH_SIZE);
fastViewSash.moveAbove(null);
}
}
}
};
private PaintListener paintListener = new PaintListener() {
public void paintControl(PaintEvent event) {
if (borderColor1 == null) borderColor1 = WorkbenchColors.getColor(RGB_COLOR1);
if (borderColor2 == null) borderColor2 = WorkbenchColors.getColor(RGB_COLOR2);
if (borderColor3 == null) borderColor3 = WorkbenchColors.getColor(RGB_COLOR3);
Point size = fastViewSash.getSize();
Rectangle d = new Rectangle(0, 0, size.x, size.y);
GC gc = event.gc;
gc.setForeground(borderColor1);
gc.drawLine(d.x, d.y, d.x, d.y + d.height);
gc.setForeground(borderColor2);
gc.drawLine(d.x + 1, d.y + 1, d.x + 1, d.y + d.height);
gc.setForeground(borderColor3);
gc.drawLine(d.x + 2, d.y + 2, d.x + 2, d.y + d.height);
}
};
private SelectionAdapter selectionListener = new SelectionAdapter () {
public void widgetSelected(SelectionEvent e) {
if (e.detail == SWT.DRAG && activeFastView != null)
checkDragLimit(e);
if (e.detail != SWT.DRAG && activeFastView != null) {
ViewPane pane = getPane(activeFastView);
Rectangle bounds = pane.getBounds();
bounds.width = Math.max(0, e.x - bounds.x);
pane.setBounds(bounds);
Float newRatio = new Float((float)bounds.width/(float)getClientComposite().getSize().x);
mapFastViewToWidthRatio.put(pane.getID(), newRatio);
fastViewSash.setBounds(bounds.width - SASH_SIZE, bounds.y, SASH_SIZE, bounds.height - SASH_SIZE);
fastViewSash.moveAbove(null);
}
}
};
/**
* ViewManager constructor comment.
*/
public Perspective(PerspectiveDescriptor desc, WorkbenchPage page)
throws WorkbenchException
{
this(page);
descriptor = desc;
if(desc != null)
createPresentation(desc);
}
/**
* ViewManager constructor comment.
*/
protected Perspective(WorkbenchPage page) throws WorkbenchException {
this.page = page;
this.editorArea = page.getEditorPresentation().getLayoutPart();
this.viewFactory = page.getViewFactory();
visibleActionSets = new ArrayList(2);
alwaysOnActionSets = new ArrayList(2);
alwaysOffActionSets = new ArrayList(2);
fastViews = new ArrayList(2);
}
/**
* Sets the fast view attribute.
* Note: The page is expected to update action bars.
*/
public void addFastView(IViewPart view) {
ViewPane pane = getPane(view);
if (!isFastView(view)) {
// Only remove the part from the presentation if it
// is actually in the presentation.
if (presentation.hasPlaceholder(pane.getID()) ||
pane.getContainer() != null)
presentation.removePart(pane);
// We are drag-enabling the pane because it has been disabled
// when it was removed from the perspective presentation.
presentation.enableDrag(pane);
fastViews.add(view);
pane.setFast(true);
Control ctrl = pane.getControl();
if (ctrl != null)
ctrl.setEnabled(false); // Remove focus support.
}
}
/**
* Moves a part forward in the Z order of a perspective so it is visible.
*
* @param part the part to bring to move forward
* @return true if the part was brought to top, false if not.
*/
public boolean bringToTop(IViewPart part) {
if (isFastView(part)) {
setActiveFastView(part);
return true;
} else {
ViewPane pane = getPane(part);
return presentation.bringPartToTop(pane);
}
}
/**
* Returns true if a view can close.
*/
public boolean canCloseView(IViewPart view) {
return true;
}
/**
* Prevents the user from making a fast view too narrow or too wide.
*/
private void checkDragLimit(SelectionEvent event) {
if (event.x < ((float)getClientComposite().getSize().x * IPageLayout.RATIO_MIN))
event.x = (int)((float)getClientComposite().getSize().x * IPageLayout.RATIO_MIN);
if (event.x > ((float)getClientComposite().getSize().x * IPageLayout.RATIO_MAX))
event.x = (int)((float)getClientComposite().getSize().x * IPageLayout.RATIO_MAX);
}
/**
* Returns whether a view exists within the perspective.
*/
public boolean containsView(IViewPart view) {
String id = view.getSite().getId();
IViewPart test = findView(id);
return (view == test);
}
/**
* Create the initial list of action sets.
*/
private void createInitialActionSets(List stringList) {
ActionSetRegistry reg = WorkbenchPlugin.getDefault().getActionSetRegistry();
Iterator iter = stringList.iterator();
while (iter.hasNext()) {
String id = (String)iter.next();
IActionSetDescriptor desc = reg.findActionSet(id);
if (desc != null)
visibleActionSets.add(desc);
else
WorkbenchPlugin.log("Unable to find Action Set: " + id);//$NON-NLS-1$
}
}
/**
* Create a presentation for a perspective.
*/
private void createPresentation(PerspectiveDescriptor persp)
throws WorkbenchException
{
if (persp.hasCustomFile()) {
loadCustomPersp(persp);
} else {
loadPredefinedPersp(persp);
}
}
/**
* Dispose the perspective and all views contained within.
*/
public void dispose() {
// Get rid of presentation.
if(presentation == null)
return;
presentation.deactivate();
presentation.disposeSashes();
// Release each view.
IViewPart [] views = getViews();
int length = views.length;
for (int nX = 0; nX < length; nX ++) {
getViewFactory().releaseView(views[nX].getSite().getId());
}
// Dispose of the sash too...
if (fastViewSash != null) {
fastViewSash.dispose();
fastViewSash = null;
}
mapFastViewToWidthRatio.clear();
}
/**
* See IWorkbenchPage@findView.
*/
public IViewPart findView(String id) {
IViewPart [] views = getViews();
for (int nX = 0; nX < views.length; nX ++) {
IViewPart part = views[nX];
if (id.equals(part.getSite().getId()))
return part;
}
return null;
}
/**
* Returns an array of the visible action sets.
*/
public IActionSetDescriptor[] getActionSets() {
int size = visibleActionSets.size();
IActionSetDescriptor [] array = new IActionSetDescriptor[size];
for (int nX = 0; nX < size; nX ++) {
array[nX] = (IActionSetDescriptor)visibleActionSets.get(nX);
}
return array;
}
/**
* Returns the window's client composite widget
* which views and editor area will be parented.
*/
private Composite getClientComposite() {
return page.getClientComposite();
}
/**
* Returns the perspective.
*/
public IPerspectiveDescriptor getDesc() {
return descriptor;
}
/**
* Returns the bounds of the given fast view.
*/
/*package*/ Rectangle getFastViewBounds(IViewPart part) {
// Copy the bounds of the page composite
Rectangle bounds = page.getClientComposite().getBounds();
ViewPane pane = (ViewPane)((ViewSite)part.getSite()).getPane();
// get the width ratio of the fast view
float ratio = getFastViewWidthRatio(pane.getID());
// Compute the actual width of the fast view.
bounds.width = (int)(ratio*(float)getClientComposite().getSize().x);
return bounds;
}
/**
* Returns the docked views.
*/
public IViewPart [] getFastViews() {
int size = fastViews.size();
IViewPart [] array = new IViewPart[size];
array = (IViewPart [])fastViews.toArray(array);
return array;
}
/**
* Returns the new wizard actions the page.
* This is List of Strings.
*/
public ArrayList getNewWizardActionIds() {
return newWizardActionIds;
}
/**
* Returns the pane for a view.
*/
private ViewPane getPane(IViewPart view) {
ViewSite site = (ViewSite)view.getSite();
return (ViewPane)site.getPane();
}
/**
* Returns the perspective actions for this page.
* This is List of Strings.
*/
public ArrayList getPerspectiveActionIds() {
return perspectiveActionIds;
}
/**
* Returns the presentation.
*/
public PerspectivePresentation getPresentation() {
return presentation;
}
/**
* Retrieves the ratio for the fast view with the given ID. If
* the ratio is not known, the default ratio for the view is returned.
*/
private float getFastViewWidthRatio(String id) {
Float f = (Float)mapFastViewToWidthRatio.get(id);
if (f != null) {
return f.floatValue();
} else {
IViewRegistry reg = WorkbenchPlugin.getDefault().getViewRegistry();
float ratio = reg.find(id).getFastViewWidthRatio();
mapFastViewToWidthRatio.put(id, new Float(ratio));
return ratio;
}
}
/**
* Returns the show view actions the page.
* This is List of Strings.
*/
public ArrayList getShowViewActionIds() {
return showViewActionIds;
}
/**
* Returns the toolbar layout for this perspective.
*/
public CoolBarLayout getToolBarLayout() {
return toolBarLayout;
}
/**
* Returns the last active fast view.
*/
/*package*/ IViewPart getPreviousActiveFastView() {
return previousActiveFastView;
}
/**
* Returns the view factory.
*/
private ViewFactory getViewFactory() {
return viewFactory;
}
/**
* Open the tracker to allow the user to move
* the specified part using keyboard.
*/
public void openTracker(ViewPane pane) {
presentation.openTracker(pane);
}
/**
* See IWorkbenchPage.
*/
public IViewReference [] getViewReferences() {
// Get normal views.
if(presentation == null)
return new IViewReference[0];
List panes = new ArrayList(5);
presentation.collectViewPanes(panes);
IViewReference [] resultArray = new IViewReference[panes.size() + fastViews.size()];
// Copy fast views.
int nView = 0;
for (int i = 0; i < fastViews.size(); i ++) {
ViewSite site = (ViewSite)((IViewPart)fastViews.get(i)).getSite();
ViewPane pane = (ViewPane)site.getPane();
resultArray[nView] = pane.getViewReference();
++ nView;
}
// Copy normal views.
for (int i = 0; i < panes.size(); i ++) {
ViewPane pane = (ViewPane)panes.get(i);
resultArray[nView] = pane.getViewReference();
++ nView;
}
return resultArray;
}
/**
* See IWorkbenchPage.
*/
public IViewPart [] getViews() {
// Get normal views.
if(presentation == null)
return new IViewPart[0];
List resVector = new ArrayList(5);
presentation.collectViewPanes(resVector);
// Create a view array.
int nFastViews = fastViews.size();
int nNormalViews = resVector.size();
IViewPart [] resArray = new IViewPart[nNormalViews + nFastViews];
// Copy fast views.
int nView = 0;
for (int nX = 0; nX < nFastViews; nX ++) {
resArray[nView] = (IViewPart)fastViews.get(nX);
++ nView;
}
// Copy normal views.
for (int nX = 0; nX < nNormalViews; nX ++) {
ViewPane pane = (ViewPane)resVector.get(nX);
resArray[nView] = (IViewPart)pane.getViewReference().getPart(true);
++ nView;
}
return resArray;
}
/**
* @see IWorkbenchPage
* Note: The page is expected to update action bars.
*/
public void hideActionSet(String id) {
ActionSetRegistry reg = WorkbenchPlugin.getDefault().getActionSetRegistry();
IActionSetDescriptor desc = reg.findActionSet(id);
if (alwaysOnActionSets.contains(desc))
return;
if (desc != null)
visibleActionSets.remove(desc);
}
/**
* Hide the editor area if visible
*/
protected void hideEditorArea() {
if (!isEditorAreaVisible())
return;
// Replace the editor area with a placeholder so we
// know where to put it back on show editor area request.
editorHolder = new PartPlaceholder(editorArea.getID());
presentation.getLayout().replace(editorArea, editorHolder);
// Disable the entire editor area so if an editor had
// keyboard focus it will let it go.
if (editorArea.getControl() != null)
editorArea.getControl().setEnabled(false);
}
/**
* Hides a fast view. The view shrinks equally <code>steps</code> times
* before disappearing completely.
*/
private void hideFastView(IViewPart part, int steps) {
setFastViewIconSelection(part, false);
// Get pane.
ViewPane pane = getPane(part);
// Hide the right side sash first
if (fastViewSash != null)
fastViewSash.setBounds(0, 0, 0, 0);
Control ctrl = pane.getControl();
if(steps != 0) {
// Slide it off screen.
Rectangle bounds = pane.getBounds();
int increment = bounds.width / steps;
for (int nX = 0; nX <= bounds.width - 2; nX += increment) {
ctrl.setLocation(-nX, bounds.y);
ctrl.getParent().update();
}
}
// Hide it completely.
pane.setBounds(0, 0, 0, 0);
pane.setFastViewSash(null);
ctrl.setEnabled(false); // Remove focus support.
}
/**
* Hides the fast view sash for zooming in a fast view.
*/
void hideFastViewSash() {
if (fastViewSash != null)
fastViewSash.setBounds(0, 0, 0, 0);
}
/**
* See IWorkbenchPage
*/
public boolean hideView(IViewPart view) {
// If the view is locked just return.
ViewSite site = (ViewSite)view.getSite();
ViewPane pane = (ViewPane)site.getPane();
// Remove the view from the current presentation.
if (isFastView(view)) {
fastViews.remove(view);
pane.setFast(false); //force an update of the toolbar
if (activeFastView == view)
setActiveFastView(null);
pane.getControl().setEnabled(true);
} else {
presentation.removePart(pane);
}
// Dispose view if ref count == 0.
getViewFactory().releaseView(site.getId());
return true;
}
/*
* Return whether the editor area is visible or not.
*/
protected boolean isEditorAreaVisible() {
return editorHolder == null;
}
/**
* Returns true if a view is fast.
*/
public boolean isFastView(IViewPart part) {
return fastViews.contains(part);
}
/**
* Creates a new presentation from a persistence file.
* Note: This method should not modify the current state of the perspective.
*/
private void loadCustomPersp(PerspectiveDescriptor persp)
{
try {
InputStream stream = new FileInputStream(persp.getCustomFile());
InputStreamReader reader = new InputStreamReader(stream, "utf-8"); //$NON-NLS-1$
// Restore the layout state.
IMemento memento = XMLMemento.createReadRoot(reader);
restoreState(memento);
restoreState();
reader.close();
} catch (IOException e) {
persp.deleteCustomFile();
MessageDialog.openError((Shell)null,
WorkbenchMessages.getString("Perspective.problemRestoringTitle"), //$NON-NLS-1$
WorkbenchMessages.getString("Perspective.errorReadingState")); //$NON-NLS-1$
return;
}
}
/**
* Create a presentation for a perspective.
* Note: This method should not modify the current state of the perspective.
*/
private void loadPredefinedPersp(
PerspectiveDescriptor persp)
throws WorkbenchException
{
// Create layout engine.
IPerspectiveFactory factory = null;
try {
factory = persp.createFactory();
} catch (CoreException e) {
throw new WorkbenchException(WorkbenchMessages.format("Perspective.unableToLoad", new Object[] {persp.getId()})); //$NON-NLS-1$
}
// Create layout factory.
RootLayoutContainer container = new RootLayoutContainer(page.getMouseDownListener());
PageLayout layout = new PageLayout(container, getViewFactory(), editorArea);
// Run layout engine.
factory.createInitialLayout(layout);
PerspectiveExtensionReader extender = new PerspectiveExtensionReader();
extender.extendLayout(descriptor.getId(), layout);
// Retrieve fast view width ratios stored in the page layout.
mapFastViewToWidthRatio.putAll(layout.getFastViewToWidthRatioMap());
// Create action sets.
createInitialActionSets(layout.getActionSets());
alwaysOnActionSets.addAll(visibleActionSets);
newWizardActionIds = layout.getNewWizardActionIds();
showViewActionIds = layout.getShowViewActionIds();
perspectiveActionIds = layout.getPerspectiveActionIds();
// Create fast views
fastViews = layout.getFastViews();
// Create presentation.
presentation = new PerspectivePresentation(page, container);
// Hide editor area if requested by factory
if (!layout.isEditorAreaVisible())
hideEditorArea();
setEditorReuseThreshold(layout.getEditorReuseThreshold());
}
/**
* activate.
*/
protected void onActivate() {
// Update editor area state.
if (editorArea.getControl() != null) {
if (isEditorAreaVisible()) {
// Enable the editor area now that it will be made
// visible and can accept keyboard focus again.
editorArea.getControl().setEnabled(true);
}
else {
// Disable the entire editor area so if an editor had
// keyboard focus it will let it go.
editorArea.getControl().setEnabled(false);
}
}
// Update fast views.
// Make sure the control for the fastviews are create so they can
// be activated.
for (int i = 0; i < fastViews.size(); i++){
ViewPane pane = getPane((IViewPart)fastViews.get(i));
Control ctrl = pane.getControl();
if (ctrl == null) {
pane.createControl(getClientComposite());
ctrl = pane.getControl();
}
presentation.enableDrag(pane);
ctrl.setEnabled(false); // Remove focus support.
}
setAllPinsVisible(true);
presentation.activate(getClientComposite());
getClientComposite().addListener(SWT.Resize, resizeListener);
}
/**
* deactivate.
*/
protected void onDeactivate() {
getClientComposite().removeListener(SWT.Resize, resizeListener);
presentation.deactivate();
setActiveFastView(null);
setAllPinsVisible(false);
// Update fast views.
for (int i = 0; i < fastViews.size(); i++){
ViewPane pane = getPane((IViewPart)fastViews.get(i));
presentation.disableDrag(pane);
Control ctrl = pane.getControl();
if (ctrl != null)
ctrl.setEnabled(true); // Add focus support.
}
}
/**
* Notifies that a part has been activated.
*/
public void partActivated(IWorkbenchPart activePart) {
// If a fastview is open close it.
if (activeFastView != null && activeFastView != activePart)
setActiveFastView(null);
}
/**
* Sets the fast view attribute.
* Note: The page is expected to update action bars.
*/
public void removeFastView(IViewPart view) {
ViewPane pane = getPane(view);
if (isFastView(view)) {
if (activeFastView == view)
setActiveFastView(null);
fastViews.remove(view);
pane.setFast(false);
Control ctrl = pane.getControl();
if (ctrl != null)
ctrl.setEnabled(true); // Modify focus support.
// We are disabling the pane because it will be enabled when it
// is added to the presentation. When a pane is enabled a drop
// listener is added to it, and we do not want to have multiple
// listeners for a pane
presentation.disableDrag(pane);
presentation.addPart(pane);
}
}
/**
* Fills a presentation with layout data.
* Note: This method should not modify the current state of the perspective.
*/
public void restoreState(IMemento memento) {
// Create persp descriptor.
descriptor = new PerspectiveDescriptor(null,null,null);
descriptor.restoreState(memento);
PerspectiveDescriptor desc = (PerspectiveDescriptor)WorkbenchPlugin
.getDefault().getPerspectiveRegistry().findPerspectiveWithId(descriptor.getId());
if (desc != null)
descriptor = desc;
// Create the toolbar layout.
IMemento layoutMem = memento.getChild(IWorkbenchConstants.TAG_TOOLBAR_LAYOUT);
if (layoutMem != null) {
toolBarLayout = new CoolBarLayout();
toolBarLayout.restoreState(layoutMem);
}
this.memento = memento;
// Add the visible views.
IMemento [] views = memento.getChildren(IWorkbenchConstants.TAG_VIEW);
List errors = new ArrayList();
for (int x = 0; x < views.length; x ++) {
// Get the view details.
IMemento childMem = views[x];
String viewID = childMem.getString(IWorkbenchConstants.TAG_ID);
// Create and open the view.
try {
viewFactory.createView(viewID);
} catch (PartInitException e) {
}
}
}
/**
* Fills a presentation with layout data.
* Note: This method should not modify the current state of the perspective.
*/
public void restoreState() {
if(this.memento == null)
return;
IMemento memento = this.memento;
this.memento = null;
IMemento boundsMem = memento.getChild(IWorkbenchConstants.TAG_WINDOW);
if(boundsMem != null) {
Rectangle r = new Rectangle(0,0,0,0);
r.x = boundsMem.getInteger(IWorkbenchConstants.TAG_X).intValue();
r.y = boundsMem.getInteger(IWorkbenchConstants.TAG_Y).intValue();
r.height = boundsMem.getInteger(IWorkbenchConstants.TAG_HEIGHT).intValue();
r.width = boundsMem.getInteger(IWorkbenchConstants.TAG_WIDTH).intValue();
if(page.getWorkbenchWindow().getPages().length == 0) {
page.getWorkbenchWindow().getShell().setBounds(r);
}
}
// Create an empty presentation..
RootLayoutContainer mainLayout = new RootLayoutContainer(page.getMouseDownListener());
PerspectivePresentation pres = new PerspectivePresentation(page, mainLayout);
// Read the layout.
pres.restoreState(memento.getChild(IWorkbenchConstants.TAG_LAYOUT));
// Add the editor workbook. Do not hide it now.
pres.replacePlaceholderWithPart(editorArea);
// Add the visible views.
IMemento [] views = memento.getChildren(IWorkbenchConstants.TAG_VIEW);
List errors = new ArrayList();
for (int x = 0; x < views.length; x ++) {
// Get the view details.
IMemento childMem = views[x];
String viewID = childMem.getString(IWorkbenchConstants.TAG_ID);
// Create and open the view.
IViewReference ref = viewFactory.getView(viewID);
if(ref == null) {
WorkbenchPlugin.log("Could not create view: '" + viewID + "'."); //$NON-NLS-1$
continue;
}
page.addPart(ref);
IViewPart view = (IViewPart)ref.getPart(true);
ViewSite site = (ViewSite)view.getSite();
ViewPane pane = (ViewPane)site.getPane();
pres.replacePlaceholderWithPart(pane);
}
// Load the fast views
IMemento fastViewsMem = memento.getChild(IWorkbenchConstants.TAG_FAST_VIEWS);
if(fastViewsMem != null) {
views = fastViewsMem.getChildren(IWorkbenchConstants.TAG_VIEW);
for (int x = 0; x < views.length; x ++) {
// Get the view details.
IMemento childMem = views[x];
String viewID = childMem.getString(IWorkbenchConstants.TAG_ID);
Float ratio = childMem.getFloat(IWorkbenchConstants.TAG_RATIO);
if (ratio == null) {
Integer viewWidth = childMem.getInteger(IWorkbenchConstants.TAG_WIDTH);
if (viewWidth == null)
ratio = new Float(IPageLayout.DEFAULT_FASTVIEW_RATIO);
else
ratio = new Float((float)viewWidth.intValue() / (float)getClientComposite().getSize().x);
}
mapFastViewToWidthRatio.put(viewID, ratio);
// Create and open the view.
try {
IViewReference ref = viewFactory.createView(viewID);
page.addPart(ref);
fastViews.add(ref.getPart(true));
} catch (PartInitException e) {
errors.add(e.getStatus());
}
}
}
if(errors.size() > 0) {
String message;
Status s;
if(errors.size() == 1) {
s = (Status)errors.get(0);
message = WorkbenchMessages.getString("Perspective.oneErrorRestoring"); //$NON-NLS-1$
} else {
Status allErrors[] = new Status[errors.size()];
errors.toArray(allErrors);
message = WorkbenchMessages.getString("Perspective.couldNotCreateAllViews"); //$NON-NLS-1$
s = new MultiStatus(PlatformUI.PLUGIN_ID,0,allErrors,WorkbenchMessages.getString("Perspective.multipleErrorsRestoring"),null); //$NON-NLS-1$
}
ErrorDialog.openError(null,WorkbenchMessages.getString("Error"),message,s); //$NON-NLS-1$
}
// Load the action sets.
IMemento [] actions = memento.getChildren(IWorkbenchConstants.TAG_ACTION_SET);
ArrayList result = new ArrayList(actions.length);
for (int x = 0; x < actions.length; x ++) {
String actionSetID = actions[x].getString(IWorkbenchConstants.TAG_ID);
result.add(actionSetID);
}
createInitialActionSets(result);
// Load the always on action sets.
actions = memento.getChildren(IWorkbenchConstants.TAG_ALWAYS_ON_ACTION_SET);
for (int x = 0; x < actions.length; x ++) {
String actionSetID = actions[x].getString(IWorkbenchConstants.TAG_ID);
IActionSetDescriptor d =
WorkbenchPlugin.getDefault().getActionSetRegistry().findActionSet(actionSetID);
if (d != null)
alwaysOnActionSets.add(d);
}
// Load the always off action sets.
actions = memento.getChildren(IWorkbenchConstants.TAG_ALWAYS_OFF_ACTION_SET);
for (int x = 0; x < actions.length; x ++) {
String actionSetID = actions[x].getString(IWorkbenchConstants.TAG_ID);
IActionSetDescriptor d =
WorkbenchPlugin.getDefault().getActionSetRegistry().findActionSet(actionSetID);
if (d != null)
alwaysOffActionSets.add(d);
}
// Load "show view actions".
actions = memento.getChildren(IWorkbenchConstants.TAG_SHOW_VIEW_ACTION);
showViewActionIds = new ArrayList(actions.length);
for (int x = 0; x < actions.length; x ++) {
String id = actions[x].getString(IWorkbenchConstants.TAG_ID);
showViewActionIds.add(id);
}
// Load "new wizard actions".
actions = memento.getChildren(IWorkbenchConstants.TAG_NEW_WIZARD_ACTION);
newWizardActionIds = new ArrayList(actions.length);
for (int x = 0; x < actions.length; x ++) {
String id = actions[x].getString(IWorkbenchConstants.TAG_ID);
newWizardActionIds.add(id);
}
// Load "perspective actions".
actions = memento.getChildren(IWorkbenchConstants.TAG_PERSPECTIVE_ACTION);
perspectiveActionIds = new ArrayList(actions.length);
for (int x = 0; x < actions.length; x ++) {
String id = actions[x].getString(IWorkbenchConstants.TAG_ID);
perspectiveActionIds.add(id);
}
// Save presentation.
presentation = pres;
// Hide the editor area if needed. Need to wait for the
// presentation to be fully setup first.
Integer areaVisible = memento.getInteger(IWorkbenchConstants.TAG_AREA_VISIBLE);
if (areaVisible != null && areaVisible.intValue() == 0)
hideEditorArea();
Integer threshold = memento.getInteger(IWorkbenchConstants.TAG_EDITOR_REUSE_THRESHOLD);
if (threshold != null && threshold.intValue() != 0)
setEditorReuseThreshold(threshold.intValue());
}
/**
* Save the layout.
*/
public void saveDesc() {
saveDescAs(descriptor);
}
/**
* Save the layout.
*/
public void saveDescAs(IPerspectiveDescriptor desc) {
// Capture the layout state.
XMLMemento memento = XMLMemento.createWriteRoot("perspective");//$NON-NLS-1$
saveState(memento, (PerspectiveDescriptor)desc, false);
// Save it to a file.
PerspectiveDescriptor realDesc = (PerspectiveDescriptor)desc;
try {
OutputStream stream = new FileOutputStream(realDesc.getCustomFile());
Writer writer = new OutputStreamWriter(stream, "utf-8"); //$NON-NLS-1$
memento.save(writer);
writer.close();
descriptor = realDesc;
} catch (IOException e) {
realDesc.deleteCustomFile();
MessageDialog.openError((Shell)null,
WorkbenchMessages.getString("Perspective.problemSavingTitle"), //$NON-NLS-1$
WorkbenchMessages.getString("Perspective.problemSavingMessage")); //$NON-NLS-1$
}
}
/**
* Save the layout.
*/
public void saveState(IMemento memento)
{
saveState(memento, descriptor, true);
// Save the toolbar layout.
if (toolBarLayout != null) {
IMemento childMem = memento.createChild(IWorkbenchConstants.TAG_TOOLBAR_LAYOUT);
toolBarLayout.saveState(childMem);
}
}
/**
* Save the layout.
*/
private void saveState(IMemento memento, PerspectiveDescriptor p,
boolean saveInnerViewState)
{
if(this.memento != null) {
memento.putMemento(this.memento);
return;
}
// Save the version number.
memento.putString(IWorkbenchConstants.TAG_VERSION, VERSION_STRING);
p.saveState(memento);
if(!saveInnerViewState) {
Rectangle bounds = page.getWorkbenchWindow().getShell().getBounds();
IMemento boundsMem = memento.createChild(IWorkbenchConstants.TAG_WINDOW);
boundsMem.putInteger(IWorkbenchConstants.TAG_X,bounds.x);
boundsMem.putInteger(IWorkbenchConstants.TAG_Y,bounds.y);
boundsMem.putInteger(IWorkbenchConstants.TAG_HEIGHT,bounds.height);
boundsMem.putInteger(IWorkbenchConstants.TAG_WIDTH,bounds.width);
}
// Save the visible action sets.
Iterator enum = visibleActionSets.iterator();
while (enum.hasNext()) {
IActionSetDescriptor desc = (IActionSetDescriptor)enum.next();
IMemento child = memento.createChild(IWorkbenchConstants.TAG_ACTION_SET);
child.putString(IWorkbenchConstants.TAG_ID, desc.getId());
}
// Save the "always on" action sets.
enum = alwaysOnActionSets.iterator();
while (enum.hasNext()) {
IActionSetDescriptor desc = (IActionSetDescriptor)enum.next();
IMemento child = memento.createChild(IWorkbenchConstants.TAG_ALWAYS_ON_ACTION_SET);
child.putString(IWorkbenchConstants.TAG_ID, desc.getId());
}
// Save the "always off" action sets.
enum = alwaysOffActionSets.iterator();
while (enum.hasNext()) {
IActionSetDescriptor desc = (IActionSetDescriptor)enum.next();
IMemento child = memento.createChild(IWorkbenchConstants.TAG_ALWAYS_OFF_ACTION_SET);
child.putString(IWorkbenchConstants.TAG_ID, desc.getId());
}
// Save "show view actions"
enum = showViewActionIds.iterator();
while (enum.hasNext()) {
String str = (String)enum.next();
IMemento child = memento.createChild(IWorkbenchConstants.TAG_SHOW_VIEW_ACTION);
child.putString(IWorkbenchConstants.TAG_ID, str);
}
// Save "new wizard actions".
enum = newWizardActionIds.iterator();
while (enum.hasNext()) {
String str = (String)enum.next();
IMemento child = memento.createChild(IWorkbenchConstants.TAG_NEW_WIZARD_ACTION);
child.putString(IWorkbenchConstants.TAG_ID, str);
}
// Save "perspective actions".
enum = perspectiveActionIds.iterator();
while (enum.hasNext()) {
String str = (String)enum.next();
IMemento child = memento.createChild(IWorkbenchConstants.TAG_PERSPECTIVE_ACTION);
child.putString(IWorkbenchConstants.TAG_ID, str);
}
// Get visible views.
List viewPanes = new ArrayList(5);
presentation.collectViewPanes(viewPanes);
// Save the views.
boolean active = page.getPerspective().getId().equals(descriptor.getId());
enum = viewPanes.iterator();
int errors = 0;
while (enum.hasNext()) {
ViewPane pane = (ViewPane)enum.next();
IViewReference ref = pane.getViewReference();
IMemento viewMemento = memento.createChild(IWorkbenchConstants.TAG_VIEW);
viewMemento.putString(IWorkbenchConstants.TAG_ID, ref.getId());
}
if(fastViews.size() > 0) {
IMemento childMem = memento.createChild(IWorkbenchConstants.TAG_FAST_VIEWS);
enum = fastViews.iterator();
while (enum.hasNext()) {
IViewPart view = (IViewPart)enum.next();
IMemento viewMemento = childMem.createChild(IWorkbenchConstants.TAG_VIEW);
String id = view.getSite().getId();
viewMemento.putString(IWorkbenchConstants.TAG_ID, id);
float ratio = getFastViewWidthRatio(id);
viewMemento.putFloat(IWorkbenchConstants.TAG_RATIO, ratio);
}
}
if(errors > 0) {
String message = WorkbenchMessages.getString("Perspective.multipleErrors"); //$NON-NLS-1$
if(errors == 1)
message = WorkbenchMessages.getString("Perspective.oneError"); //$NON-NLS-1$
MessageDialog.openError(null, WorkbenchMessages.getString("Error"), message); //$NON-NLS-1$
}
// Save the layout.
IMemento childMem = memento.createChild(IWorkbenchConstants.TAG_LAYOUT);
presentation.saveState(childMem);
// Save the editor visibility state
if (isEditorAreaVisible())
memento.putInteger(IWorkbenchConstants.TAG_AREA_VISIBLE, 1);
else
memento.putInteger(IWorkbenchConstants.TAG_AREA_VISIBLE, 0);
//Save editor reuse threshold
memento.putInteger(IWorkbenchConstants.TAG_EDITOR_REUSE_THRESHOLD,getEditorReuseThreshold());
}
/**
* Sets the visible action sets.
* Note: The page is expected to update action bars.
*/
public void setActionSets(IActionSetDescriptor[] newArray) {
// We assume that changes to action set visibilty should be remembered
// and not reversed as parts are activated.
ArrayList turnedOff = (ArrayList)visibleActionSets.clone();
for (int i = 0; i < newArray.length; i++) {
IActionSetDescriptor desc = newArray[i];
turnedOff.remove(desc);
if (!visibleActionSets.contains(desc)) {
// make sure this always stays visible
alwaysOnActionSets.add(desc);
alwaysOffActionSets.remove(desc);
}
}
for (int i = 0; i < turnedOff.size(); i++) {
IActionSetDescriptor desc = (IActionSetDescriptor)turnedOff.get(i);
// make sure this always stays hidden
alwaysOnActionSets.remove(desc);
alwaysOffActionSets.add(desc);
}
visibleActionSets.clear();
int newSize = newArray.length;
for (int nX = 0; nX < newSize; nX ++) {
visibleActionSets.add(newArray[nX]);
}
}
/**
* Return the active fast view or null if there are no
* fast views or if there are all minimized.
*/
public IViewPart getActiveFastView() {
return activeFastView;
}
/**
* Sets the active fast view. If a different fast view is already open,
* it shrinks equally <code>steps</code> times before disappearing
* completely. Then, <code>view</code> becomes active and is shown.
*/
/*package*/ void setActiveFastView(IViewPart view, int steps) {
if (activeFastView == view)
return;
if (activeFastView != null)
previousActiveFastView = activeFastView;
if (activeFastView != null) {
hideFastView(activeFastView, steps);
}
activeFastView = view;
if (activeFastView != null) {
showFastView(activeFastView);
}
}
/**
* Sets the active fast view.
*/
/*package*/ void setActiveFastView(IViewPart view) {
setActiveFastView(view, FASTVIEW_HIDE_STEPS);
}
/**
* Sets the visibility of all fast view pins.
*/
private void setAllPinsVisible(boolean visible) {
Iterator iter = fastViews.iterator();
while (iter.hasNext()) {
IViewPart view = (IViewPart)iter.next();
ViewPane pane = getPane(view);
pane.setFast(visible);
}
}
/**
* Sets the selection for the shortcut bar icon representing the givevn fast view.
*/
private void setFastViewIconSelection(IViewPart part, boolean selected) {
WorkbenchWindow window = (WorkbenchWindow)page.getWorkbenchWindow();
ToolBar bar = window.getShortcutBar().getControl();
ToolItem[] items = bar.getItems();
for(int i=0; i<items.length; i++) {
if (items[i].getData(ShowFastViewContribution.FAST_VIEW) == part) {
items[i].setSelection(selected);
}
}
}
/**
* Sets the new wizard actions for the page.
* This is List of Strings.
*/
public void setNewWizardActionIds(ArrayList newList ) {
newWizardActionIds = newList;
}
/**
* Sets the perspective actions for this page.
* This is List of Strings.
*/
public void setPerspectiveActionIds(ArrayList list) {
perspectiveActionIds = list;
}
/**
* Sets the show view actions for the page.
* This is List of Strings.
*/
public void setShowViewActionIds(ArrayList list) {
showViewActionIds = list;
}
/**
* Sets the toolbar layout for this perspective.
*/
public void setToolBarLayout(CoolBarLayout layout) {
toolBarLayout = layout;
}
/**
* @see IWorkbenchPage
* Note: The page is expected to update action bars.
*/
public void showActionSet(String id) {
ActionSetRegistry reg = WorkbenchPlugin.getDefault().getActionSetRegistry();
IActionSetDescriptor desc = reg.findActionSet(id);
if (alwaysOffActionSets.contains(desc))
return;
if (desc != null && !visibleActionSets.contains(desc))
visibleActionSets.add(desc);
}
/**
* Show the editor area if not visible
*/
protected void showEditorArea() {
if (isEditorAreaVisible())
return;
// Enable the editor area now that it will be made
// visible and can accept keyboard focus again.
if (editorArea.getControl() != null)
editorArea.getControl().setEnabled(true);
// Replace the part holder with the editor area.
presentation.getLayout().replace(editorHolder, editorArea);
editorHolder = null;
}
/**
* Shows a fast view.
*/
void showFastView(IViewPart part) {
// Get pane.
ViewPane pane = getPane(part);
// Create the control first
Control ctrl = pane.getControl();
if(ctrl == null) {
pane.createControl(getClientComposite());
ctrl = pane.getControl();
}
// Show pane fast.
ctrl.setEnabled(true); // Add focus support.
Composite parent = ctrl.getParent();
Rectangle bounds = getFastViewBounds(part);
pane.setBounds(bounds);
pane.moveAbove(null);
pane.setFocus();
// Show the Sash to enable right side resize
if (fastViewSash == null) {
fastViewSash = new Sash(parent, SWT.VERTICAL);
fastViewSash.addPaintListener(paintListener);
fastViewSash.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
fastViewSash.removePaintListener(paintListener);
}
public void focusLost(FocusEvent e) {
fastViewSash.addPaintListener(paintListener);
}
});
fastViewSash.addSelectionListener(selectionListener);
}
pane.setFastViewSash(fastViewSash);
fastViewSash.setBounds(bounds.width - SASH_SIZE, bounds.y, SASH_SIZE, bounds.height - SASH_SIZE);
fastViewSash.moveAbove(null);
setFastViewIconSelection(part, true);
}
/**
* See IWorkbenchPage.
*/
public IViewPart showView(String viewID)
throws PartInitException
{
IViewReference ref = getViewFactory().createView(viewID);
IViewPart part = (IViewPart)ref.getPart(true);
ViewSite site = (ViewSite)part.getSite();
ViewPane pane = (ViewPane)site.getPane();
IPreferenceStore store = WorkbenchPlugin.getDefault().getPreferenceStore();
int openViewMode = store.getInt(IPreferenceConstants.OPEN_VIEW_MODE);
if (presentation.hasPlaceholder(viewID)) {
presentation.addPart(pane);
}
else if (openViewMode == IPreferenceConstants.OVM_EMBED) {
presentation.addPart(pane);
}
/*
* Detached window no longer supported - remove when confirmed
*
* else if (openViewMode == IPreferenceConstants.OVM_FLOAT && presentation.canDetach()) {
* presentation.addDetachedPart(pane);
* }
*/
else {
showFastView(part);
addFastView(part);
//Refresh the part as there might have been an error when showing
}
return part;
}
/**
* Toggles the visibility of a fast view. If the view is active it
* is deactivated. Otherwise, it is activated.
*/
public void toggleFastView(IViewPart view) {
if (view == activeFastView) {
setActiveFastView(null);
} else {
setActiveFastView(view);
}
}
/**
* Returns the number of open editors before reusing editors.
*
* @return a int
*/
public int getEditorReuseThreshold() {
return reuseEditors;
}
/**
* Set the number of open editors before reusing editors.
* If < 0 the user preference settings will be used.
*/
public void setEditorReuseThreshold(int openEditors) {
reuseEditors = openEditors;
}
}