blob: 8c1e49a8023abb9b4263e1b726ad43c0c9b148da [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal;
import java.io.IOException;
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.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveFactory;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.XMLMemento;
import org.eclipse.ui.internal.intro.IIntroConstants;
import org.eclipse.ui.internal.registry.ActionSetRegistry;
import org.eclipse.ui.internal.registry.IActionSetDescriptor;
import org.eclipse.ui.internal.registry.IViewRegistry;
import org.eclipse.ui.internal.registry.PerspectiveDescriptor;
import org.eclipse.ui.internal.registry.PerspectiveExtensionReader;
import org.eclipse.ui.internal.registry.PerspectiveRegistry;
/**
* 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 ArrayList fixedViews;
private boolean fixed;
private ArrayList showInPartIds;
private HashMap showInTimes = new HashMap();
private IViewReference activeFastView;
private IViewReference previousActiveFastView;
private IMemento memento;
protected PerspectivePresentation presentation;
final static private String VERSION_STRING = "0.016";//$NON-NLS-1$
private FastViewPane fastViewPane = new FastViewPane();
// fields used by fast view resizing via a sash
private static final int FASTVIEW_HIDE_STEPS = 5;
private Map mapFastViewToWidthRatio = new HashMap();
private String oldPartID = null;
private boolean shouldHideEditorsOnActivate = false;
/**
* 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);
fixedViews = new ArrayList(2);
}
/**
* Sets the fast view attribute.
* Note: The page is expected to update action bars.
*/
public void addFastView(IViewReference ref) {
ViewPane pane = (ViewPane)((WorkbenchPartReference)ref).getPane();
if (!isFastView(ref)) {
// Only remove the part from the presentation if it
// is actually in the presentation.
if (presentation.hasPlaceholder(ref.getId(), ref.getSecondaryId()) ||
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.
fastViews.add(ref);
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(IViewReference ref) {
if (isFastView(ref)) {
setActiveFastView(ref);
return true;
} else {
return presentation.bringPartToTop(getPane(ref));
}
}
/**
* Returns true if a view can close.
*/
public boolean canCloseView(IViewPart view) {
return true;
}
/**
* Returns whether a view exists within the perspective.
*/
public boolean containsView(IViewPart view) {
IViewSite site = view.getViewSite();
IViewReference ref = findView(site.getId(), site.getSecondaryId());
if(ref == null)
return false;
return (view == ref.getPart(false));
}
/**
* 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.hasCustomDefinition()) {
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.
IViewReference refs[] = getViewReferences();
for (int i = 0,length = refs.length; i < length; i ++) {
getViewFactory().releaseView(refs[i]);
}
fastViewPane.dispose();
mapFastViewToWidthRatio.clear();
}
/**
* Finds the view with the given ID that is open in this page, or <code>null</code>
* if not found.
*
* @param viewId the view ID
*/
public IViewReference findView(String viewId) {
return findView(viewId, null);
}
/**
* Finds the view with the given id and secondary id that is open in this page,
* or <code>null</code> if not found.
*
* @param viewId the view ID
* @param secondaryId the secondary ID
*/
public IViewReference findView(String id, String secondaryId) {
IViewReference refs[] = getViewReferences();
for (int i = 0; i < refs.length; i ++) {
IViewReference ref = refs[i];
if (id.equals(ref.getId())
&& (secondaryId == null ? ref.getSecondaryId() == null : secondaryId.equals(ref
.getSecondaryId())))
return ref;
}
return null;
}
/**
* Returns an array of the visible action sets.
*/
public IActionSetDescriptor[] getActionSets() {
int size = visibleActionSets.size();
IActionSetDescriptor [] array = new IActionSetDescriptor[size];
for (int i = 0; i < size; i ++) {
array[i] = (IActionSetDescriptor)visibleActionSets.get(i);
}
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(IViewReference ref) {
// Copy the bounds of the page composite
Rectangle bounds = page.getClientComposite().getBounds();
// get the width ratio of the fast view
float ratio = getFastViewWidthRatio(ref.getId());
// Compute the actual width of the fast view.
bounds.width = (int)(ratio*(float)getClientComposite().getSize().x);
return bounds;
}
/**
* Returns the docked views.
*/
public IViewReference [] getFastViews() {
IViewReference array[] = new IViewReference[fastViews.size()];
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 reference.
*/
private ViewPane getPane(IViewReference ref) {
return (ViewPane)((WorkbenchPartReference)ref).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 ids of the parts to list in the Show In... dialog.
* This is a List of Strings.
*/
public ArrayList getShowInPartIds() {
return showInPartIds;
}
/**
* Returns the time at which the last Show In was performed
* for the given target part, or 0 if unknown.
*/
public long getShowInTime(String partId) {
Long t = (Long) showInTimes.get(partId);
return t == null ? 0L : t.longValue();
}
/**
* Returns the ids of the views to list in the Show View shortcuts.
* This is a List of Strings.
*/
public ArrayList getShowViewActionIds() {
return showViewActionIds;
}
/**
* 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++) {
resultArray[nView] = (IViewReference)fastViews.get(i);
++ 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
* 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);
setEditorAreaVisible(false);
}
/**
* Hides a fast view. The view shrinks equally <code>steps</code> times
* before disappearing completely.
*/
private void hideFastView(IViewReference ref, int steps) {
setFastViewIconSelection(ref, false);
// Note: We always do at least one step of the animation.
// Note: This doesn't take into account the overhead of doing
if (ref == activeFastView) {
saveFastViewWidthRatio();
fastViewPane.hideView();
}
}
/**
* Hides the fast view sash for zooming in a fast view.
*/
void hideFastViewSash() {
fastViewPane.hideFastViewSash();
}
public boolean hideView(IViewReference ref) {
// If the view is locked just return.
ViewPane pane = getPane(ref);
// Remove the view from the current presentation.
if (isFastView(ref)) {
fastViews.remove(ref);
if(pane != null)
pane.setFast(false); //force an update of the toolbar
if (activeFastView == ref)
setActiveFastView(null);
if(pane != null)
pane.getControl().setEnabled(true);
} else {
presentation.removePart(pane);
}
// Dispose view if ref count == 0.
getViewFactory().releaseView(ref);
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(IViewReference ref) {
return fastViews.contains(ref);
}
/**
* Returns true if a view is fixed.
*
* @since 3.0
*/
public boolean isFixedView(IViewReference ref) {
return fixedViews.contains(ViewFactory.getKey(ref));
}
/**
* Returns true if a layout or perspective is fixed.
*/
public boolean isFixedLayout() {
//@issue is there a difference between a fixed
//layout and a fixed perspective?? If not the API
//may need some polish, WorkbenchPage, PageLayout
//and Perspective all have isFixed methods.
//PageLayout and Perspective have their own fixed
//attribute, we are assuming they are always in sync.
//WorkbenchPage delegates to the perspective.
return fixed;
}
/**
* 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)
{
//get the layout from the registry
PerspectiveRegistry perspRegistry = (PerspectiveRegistry) WorkbenchPlugin.getDefault().getPerspectiveRegistry();
try {
IMemento memento = perspRegistry.getCustomPersp(persp.getId());
// Restore the layout state.
MultiStatus status = new MultiStatus(
PlatformUI.PLUGIN_ID,IStatus.OK,
WorkbenchMessages.format("Perspective.unableToRestorePerspective",new String[]{persp.getLabel()}), //$NON-NLS-1$
null);
status.merge(restoreState(memento));
status.merge(restoreState());
if(status.getSeverity() != IStatus.OK) {
unableToOpenPerspective(persp,status);
}
} catch (IOException e) {
unableToOpenPerspective(persp,null);
} catch (WorkbenchException e) {
unableToOpenPerspective(persp,e.getStatus());
}
}
private void unableToOpenPerspective(PerspectiveDescriptor persp,IStatus status) {
PerspectiveRegistry perspRegistry = (PerspectiveRegistry) WorkbenchPlugin.getDefault().getPerspectiveRegistry();
perspRegistry.deletePerspective(persp);
String title = WorkbenchMessages.getString("Perspective.problemRestoringTitle"); //$NON-NLS-1$
String msg = WorkbenchMessages.getString("Perspective.errorReadingState"); //$NON-NLS-1$
if(status == null) {
MessageDialog.openError((Shell)null,title,msg);
} else {
ErrorDialog.openError((Shell)null,title,msg,status);
}
}
/**
* 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);
PageLayout layout = new PageLayout(container, getViewFactory(), editorArea, descriptor);
layout.setFixed(descriptor.getFixed());
// add the placeholder for the intro view
layout.addPlaceholder(IIntroConstants.INTRO_VIEW_ID, IPageLayout.RIGHT, .75f, IPageLayout.ID_EDITOR_AREA);
// 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();
showInPartIds = layout.getShowInPartIds();
// Create fast views
fastViews = layout.getFastViews();
// Create fixed views
fixedViews = layout.getFixedViews();
// Is the layout fixed
fixed = layout.isFixed();
// Create presentation.
presentation = new PerspectivePresentation(page, container);
// Hide editor area if requested by factory
if (!layout.isEditorAreaVisible())
hideEditorArea();
}
/**
* 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);
setEditorAreaVisible(true);
} else {
// Disable the entire editor area so if an editor had
// keyboard focus it will let it go.
editorArea.getControl().setEnabled(false);
setEditorAreaVisible(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((IViewReference)fastViews.get(i));
if(pane != null) {
Control ctrl = pane.getControl();
if (ctrl == null) {
pane.createControl(getClientComposite());
ctrl = pane.getControl();
}
ctrl.setEnabled(false); // Remove focus support.
}
}
setAllPinsVisible(true);
presentation.activate(getClientComposite());
if (shouldHideEditorsOnActivate) {
// We do this here to ensure that createPartControl is called on the top editor
// before it is hidden. See bug 20166.
hideEditorArea();
shouldHideEditorsOnActivate = false;
}
}
/**
* deactivate.
*/
protected void onDeactivate() {
presentation.deactivate();
setActiveFastView(null);
setAllPinsVisible(false);
// Update fast views.
for (int i = 0; i < fastViews.size(); i++){
ViewPane pane = getPane((IViewReference)fastViews.get(i));
if(pane != null) {
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.getPart(false) != activePart)
setActiveFastView(null);
}
/**
* The user successfully performed a Show In... action on the specified part.
* Update the history.
*/
public void performedShowIn(String partId) {
showInTimes.put(partId, new Long(System.currentTimeMillis()));
}
/**
* Sets the fast view attribute.
* Note: The page is expected to update action bars.
*/
public void removeFastView(IViewReference ref) {
ViewPane pane = getPane(ref);
if (isFastView(ref)) {
if (activeFastView == ref)
setActiveFastView(null);
fastViews.remove(ref);
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.addPart(pane);
}
}
/**
* Fills a presentation with layout data.
* Note: This method should not modify the current state of the perspective.
*/
public IStatus restoreState(IMemento memento) {
MultiStatus result = new MultiStatus(
PlatformUI.PLUGIN_ID,IStatus.OK,
WorkbenchMessages.getString("Perspective.problemsRestoringPerspective"),null); //$NON-NLS-1$
// Create persp descriptor.
descriptor = new PerspectiveDescriptor(null,null,null);
result.add(descriptor.restoreState(memento));
PerspectiveDescriptor desc = (PerspectiveDescriptor)WorkbenchPlugin
.getDefault().getPerspectiveRegistry().findPerspectiveWithId(descriptor.getId());
if (desc != null)
descriptor = desc;
this.memento = memento;
// Add the visible views.
IMemento views[] = memento.getChildren(IWorkbenchConstants.TAG_VIEW);
result.merge(createReferences(views));
memento = memento.getChild(IWorkbenchConstants.TAG_FAST_VIEWS);
if(memento != null) {
views = memento.getChildren(IWorkbenchConstants.TAG_VIEW);
result.merge(createReferences(views));
}
return result;
}
private IStatus createReferences(IMemento views[]) {
MultiStatus result = new MultiStatus(
PlatformUI.PLUGIN_ID,IStatus.OK,
WorkbenchMessages.getString("Perspective.problemsRestoringViews"),null); //$NON-NLS-1$
for (int x = 0; x < views.length; x ++) {
// Get the view details.
IMemento childMem = views[x];
String primaryId = childMem.getString(IWorkbenchConstants.TAG_ID);
String secondaryId = childMem.getString(IWorkbenchConstants.TAG_SECONDARY_ID);
// Create and open the view.
try {
if(!"true".equals(childMem.getString(IWorkbenchConstants.TAG_REMOVED))) { //$NON-NLS-1$
viewFactory.createView(primaryId, secondaryId);
}
} catch (PartInitException e) {
childMem.putString(IWorkbenchConstants.TAG_REMOVED,"true"); //$NON-NLS-1$
result.add(new Status(IStatus.ERROR,PlatformUI.PLUGIN_ID,0,e.getMessage(),e));
}
}
return result;
}
/**
* Fills a presentation with layout data.
* Note: This method should not modify the current state of the perspective.
*/
public IStatus restoreState() {
if(this.memento == null)
return new Status(IStatus.OK,PlatformUI.PLUGIN_ID,0,"",null); //$NON-NLS-1$
MultiStatus result = new MultiStatus(
PlatformUI.PLUGIN_ID,IStatus.OK,
WorkbenchMessages.getString("Perspective.problemsRestoringPerspective"),null); //$NON-NLS-1$
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);
PerspectivePresentation pres = new PerspectivePresentation(page, mainLayout);
// Read the layout.
result.merge(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);
for (int x = 0; x < views.length; x ++) {
// Get the view details.
IMemento childMem = views[x];
String primaryId = childMem.getString(IWorkbenchConstants.TAG_ID);
String secondaryId = childMem.getString(IWorkbenchConstants.TAG_SECONDARY_ID);
if (primaryId.equals(IIntroConstants.INTRO_VIEW_ID))
continue;
// Create and open the view.
WorkbenchPartReference ref = (WorkbenchPartReference)viewFactory.getView(primaryId, secondaryId);
// report error
if(ref == null) {
String key = ViewFactory.getKey(primaryId, secondaryId);
result.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0,
WorkbenchMessages.format("Perspective.couldNotFind", //$NON-NLS-1$
new String[] { key }),
null));
continue;
}
if(ref.getPane() == null) {
ViewPane vp = new ViewPane((IViewReference)ref,page);
ref.setPane(vp);
}
page.addPart(ref);
boolean willPartBeVisible = pres.willPartBeVisible(ref.getId(), secondaryId);
if(willPartBeVisible) {
IStatus restoreStatus = viewFactory.restoreView((IViewReference)ref);
result.add(restoreStatus);
if(restoreStatus.getSeverity() == IStatus.OK) {
IViewPart view = (IViewPart)ref.getPart(true);
if(view != null) {
ViewSite site = (ViewSite)view.getSite();
ViewPane pane = (ViewPane)site.getPane();
pres.replacePlaceholderWithPart(pane);
}
} else {
page.removePart(ref);
}
} else {
pres.replacePlaceholderWithPart(ref.getPane());
}
}
// 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);
String secondaryId = childMem.getString(IWorkbenchConstants.TAG_SECONDARY_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);
}
// FIXME: this needs to work with mutliple view instances
mapFastViewToWidthRatio.put(viewID, ratio);
WorkbenchPartReference ref = (WorkbenchPartReference) viewFactory.getView(viewID, secondaryId);
if(ref == null) {
String key = ViewFactory.getKey(viewID, secondaryId);
WorkbenchPlugin.log("Could not create view: '" + key + "'."); //$NON-NLS-1$ //$NON-NLS-2$
result.add(new Status(
IStatus.ERROR,PlatformUI.PLUGIN_ID,0,
WorkbenchMessages.format("Perspective.couldNotFind", new String[]{key}), //$NON-NLS-1$
null));
continue;
}
// Add to fast view list because creating a view pane
// will come back to check if its a fast view. We really
// need to clean up this code.
fastViews.add(ref);
if(ref.getPane() == null) {
ref.setPane(new ViewPane((IViewReference)ref,page));
}
page.addPart(ref);
}
}
// Load the fixed views
IMemento fixedViewsMem = memento.getChild(IWorkbenchConstants.TAG_FIXED_VIEWS);
if(fixedViewsMem != null) {
views = fixedViewsMem.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);
// we don't really need to create a view here
// we are just adding it to a list
fixedViews.add(viewID);
}
}
// Load the action sets.
IMemento [] actions = memento.getChildren(IWorkbenchConstants.TAG_ACTION_SET);
ArrayList actionsArray = new ArrayList(actions.length);
for (int x = 0; x < actions.length; x ++) {
String actionSetID = actions[x].getString(IWorkbenchConstants.TAG_ID);
actionsArray.add(actionSetID);
}
createInitialActionSets(actionsArray);
// 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 "show in times".
actions = memento.getChildren(IWorkbenchConstants.TAG_SHOW_IN_TIME);
for (int x = 0; x < actions.length; x ++) {
String id = actions[x].getString(IWorkbenchConstants.TAG_ID);
String timeStr = actions[x].getString(IWorkbenchConstants.TAG_TIME);
if (id != null && timeStr != null) {
try {
long time = Long.parseLong(timeStr);
showInTimes.put(id, new Long(time));
}
catch (NumberFormatException e) {
// skip this one
}
}
}
// Load "show in parts" from registry, not memento
showInPartIds = getShowInIdsFromRegistry();
// 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);
// Rather than hiding the editors now we must wait until after their controls
// are created. This ensures that if an editor is instantiated, createPartControl
// is also called. See bug 20166.
shouldHideEditorsOnActivate = (areaVisible != null && areaVisible.intValue() == 0);
// restore the fixed state
Integer isFixed = memento.getInteger(IWorkbenchConstants.TAG_FIXED);
fixed = (isFixed != null && isFixed.intValue() == 1);
return result;
}
/**
* Returns the Show In... part ids read from the registry.
*/
private ArrayList getShowInIdsFromRegistry() {
PerspectiveExtensionReader reader = new PerspectiveExtensionReader();
reader.setIncludeOnlyTags(new String[] { PerspectiveExtensionReader.TAG_SHOW_IN_PART });
PageLayout layout = new PageLayout();
reader.extendLayout(descriptor.getOriginalId(), layout);
return layout.getShowInPartIds();
}
/**
* Save the layout.
*/
public void saveDesc() {
saveDescAs(descriptor);
}
/**
* Save the layout.
*/
public void saveDescAs(IPerspectiveDescriptor desc) {
PerspectiveDescriptor realDesc = (PerspectiveDescriptor)desc;
//get the layout from the registry
PerspectiveRegistry perspRegistry = (PerspectiveRegistry) WorkbenchPlugin.getDefault().getPerspectiveRegistry();
// Capture the layout state.
XMLMemento memento = XMLMemento.createWriteRoot("perspective");//$NON-NLS-1$
IStatus status = saveState(memento, realDesc, false);
if(status.getSeverity() == IStatus.ERROR) {
ErrorDialog.openError((Shell)null,
WorkbenchMessages.getString("Perspective.problemSavingTitle"), //$NON-NLS-1$
WorkbenchMessages.getString("Perspective.problemSavingMessage"), //$NON-NLS-1$
status);
return;
}
//save it to the preference store
try {
perspRegistry.saveCustomPersp(realDesc, memento);
descriptor = realDesc;
} catch (IOException e) {
perspRegistry.deletePerspective(realDesc);
MessageDialog.openError((Shell)null,
WorkbenchMessages.getString("Perspective.problemSavingTitle"), //$NON-NLS-1$
WorkbenchMessages.getString("Perspective.problemSavingMessage")); //$NON-NLS-1$
}
}
/**
* Save the layout.
*/
public IStatus saveState(IMemento memento) {
MultiStatus result = new MultiStatus(
PlatformUI.PLUGIN_ID,IStatus.OK,
WorkbenchMessages.getString("Perspective.problemsSavingPerspective"),null); //$NON-NLS-1$
result.merge(saveState(memento, descriptor, true));
return result;
}
/**
* Save the layout.
*/
private IStatus saveState(IMemento memento, PerspectiveDescriptor p,
boolean saveInnerViewState)
{
MultiStatus result = new MultiStatus(
PlatformUI.PLUGIN_ID,IStatus.OK,
WorkbenchMessages.getString("Perspective.problemsSavingPerspective"),null); //$NON-NLS-1$
if(this.memento != null) {
memento.putMemento(this.memento);
return result;
}
// Save the version number.
memento.putString(IWorkbenchConstants.TAG_VERSION, VERSION_STRING);
result.add(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 "show in times"
enum = showInTimes.keySet().iterator();
while (enum.hasNext()) {
String id = (String) enum.next();
Long time = (Long) showInTimes.get(id);
IMemento child = memento.createChild(IWorkbenchConstants.TAG_SHOW_IN_TIME);
child.putString(IWorkbenchConstants.TAG_ID, id);
child.putString(IWorkbenchConstants.TAG_TIME, time.toString());
}
// 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.
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 (ref.getSecondaryId() != null)
viewMemento.putString(IWorkbenchConstants.TAG_SECONDARY_ID, ref.getSecondaryId());
}
if(fastViews.size() > 0) {
IMemento childMem = memento.createChild(IWorkbenchConstants.TAG_FAST_VIEWS);
enum = fastViews.iterator();
while (enum.hasNext()) {
IViewReference ref = (IViewReference)enum.next();
IMemento viewMemento = childMem.createChild(IWorkbenchConstants.TAG_VIEW);
String id = ref.getId();
viewMemento.putString(IWorkbenchConstants.TAG_ID, id);
float ratio = getFastViewWidthRatio(id);
viewMemento.putFloat(IWorkbenchConstants.TAG_RATIO, ratio);
}
}
if(fixedViews.size() > 0) {
IMemento childMem = memento.createChild(IWorkbenchConstants.TAG_FIXED_VIEWS);
enum = fixedViews.iterator();
while (enum.hasNext()) {
String id = (String)enum.next();
IMemento viewMemento = childMem.createChild(IWorkbenchConstants.TAG_VIEW);
viewMemento.putString(IWorkbenchConstants.TAG_ID, id);
}
}
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);
result.add(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 the fixed state
if (fixed)
memento.putInteger(IWorkbenchConstants.TAG_FIXED, 1);
else
memento.putInteger(IWorkbenchConstants.TAG_FIXED, 0);
return result;
}
/**
* 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 i = 0; i < newSize; i ++) {
visibleActionSets.add(newArray[i]);
}
}
/**
* Return the active fast view or null if there are no
* fast views or if there are all minimized.
*/
public IViewReference 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(IViewReference ref, int steps) {
if (activeFastView == ref)
return;
if (activeFastView != null) {
ViewPane pane = getPane(activeFastView);
if (pane != null) {
if (pane.isZoomed()) {
presentation.zoomOut();
}
hideFastView(activeFastView, steps);
}
}
activeFastView = ref;
try {
if (activeFastView != null) {
if (!showFastView(activeFastView)) {
activeFastView = null;
}
}
}
catch (RuntimeException e) {
activeFastView = null;
}
}
/**
* Sets the active fast view.
*/
/*package*/ void setActiveFastView(IViewReference ref) {
setActiveFastView(ref, FASTVIEW_HIDE_STEPS);
}
/**
* Sets the visibility of all fast view pins.
*/
private void setAllPinsVisible(boolean visible) {
Iterator iter = fastViews.iterator();
while (iter.hasNext()) {
ViewPane pane = getPane((IViewReference)iter.next());
if(pane != null)
pane.setFast(visible);
}
}
/**
* Sets the selection for the shortcut bar icon representing the givevn fast view.
*/
private void setFastViewIconSelection(IViewReference ref, boolean selected) {
WorkbenchWindow window = (WorkbenchWindow) page.getWorkbenchWindow();
FastViewBar bar = window.getFastViewBar();
if (bar != null) {
if (selected) {
bar.setSelection(ref);
} else {
if (ref == bar.getSelection()) {
bar.setSelection(null);
}
}
}
}
/**
* 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 ids of the parts to list in the Show In... prompter.
* This is a List of Strings.
*/
public void setShowInPartIds(ArrayList list) {
showInPartIds = list;
}
/**
* Sets the ids of the views to list in the Show View shortcuts.
* This is a List of Strings.
*/
public void setShowViewActionIds(ArrayList list) {
showViewActionIds = list;
}
/**
* @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);
setEditorAreaVisible(true);
// Replace the part holder with the editor area.
presentation.getLayout().replace(editorHolder, editorArea);
editorHolder = null;
}
private void setEditorAreaVisible(boolean visible) {
ArrayList workbooks = ((EditorArea)editorArea).getEditorWorkbooks();
for (Iterator iter = workbooks.iterator(); iter.hasNext();) {
EditorWorkbook workbook = (EditorWorkbook) iter.next();
workbook.setVisible(visible);
EditorPane pane = workbook.getVisibleEditor();
if(pane != null)
pane.setVisible(visible);
}
editorArea.setVisible(visible);
}
/**
* Shows a fast view.
* @return whether the view was successfully shown
*/
boolean showFastView(IViewReference ref) {
// Make sure the part is restored.
if(ref.getPart(true) == null)
return false;
ViewPane pane = getPane(ref);
if (pane == null)
return false;
saveFastViewWidthRatio();
WorkbenchWindow window = (WorkbenchWindow) page.getWorkbenchWindow();
FastViewBar bar = window.getFastViewBar();
if (bar == null) {
return false;
}
int side = bar.getViewSide(ref);
fastViewPane.showView(getClientComposite(), pane, side, getFastViewWidthRatio(ref.getId()));
setFastViewIconSelection(ref, true);
return true;
}
private void saveFastViewWidthRatio() {
ViewPane pane = fastViewPane.getCurrentPane();
if (pane != null) {
mapFastViewToWidthRatio.put(pane.getViewReference().getId(), new Float(fastViewPane.getCurrentRatio()));
}
}
/**
* Shows the view with the given id and secondary id.
*/
public IViewPart showView(String viewId, String secondaryId)
throws PartInitException
{
ViewFactory factory = getViewFactory();
IViewReference ref = factory.createView(viewId, secondaryId);
IViewPart part = (IViewPart)ref.getPart(false);
if(part == null) {
IStatus status = factory.restoreView(ref);
if(status.getSeverity() == IStatus.ERROR) {
if(status.getException() instanceof PartInitException)
throw (PartInitException)status.getException();
else
throw new PartInitException(status);
} else { //No error so the part has been created
part = (IViewPart)ref.getPart(false);
}
}
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, secondaryId)) {
presentation.addPart(pane);
} else if (openViewMode == IPreferenceConstants.OVM_EMBED) {
presentation.addPart(pane);
} else if (openViewMode == IPreferenceConstants.OVM_FLOAT && presentation.canDetach()) {
presentation.addDetachedPart(pane);
} else {
showFastView(ref);
addFastView(ref);
//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(IViewReference ref) {
if (ref == activeFastView) {
setActiveFastView(null);
} else {
setActiveFastView(ref);
}
}
/**
* Returns the oldPartID.
* @return String
*/
public String getOldPartID() {
return oldPartID;
}
/**
* Sets the oldPartID.
* @param oldPartID The oldPartID to set
*/
public void setOldPartID(String oldPartID) {
this.oldPartID = oldPartID;
}
/**
* Method moveFastView. Moves draggedView to the position above
* destinationView. If placeAtEnd is true, add view to the end. Otherwise,
* either place above destination view, or at the beginning if the
* destinationView is null
* @param draggedView
* @param destinationView
* @param useDestination
*/
/*package*/ void moveFastView(IViewReference draggedView, IViewReference destinationView) {
//PR 6988
//do nothing if views are the same
if (draggedView == destinationView)
return;
int insertIdx = fastViews.indexOf(destinationView);
//move the view
fastViews.remove(draggedView);
if (insertIdx < 0 || insertIdx >= fastViews.size()) {
fastViews.add(draggedView);
} else {
fastViews.add(insertIdx, draggedView);
}
}
//for dynamic UI
/* package */ void addActionSet(IActionSetDescriptor newDesc) {
for (int i = 0; i < visibleActionSets.size(); i++) {
IActionSetDescriptor desc = (IActionSetDescriptor)visibleActionSets.get(i);
if (desc.getId().equals(newDesc.getId())) {
visibleActionSets.remove(desc);
alwaysOnActionSets.remove(desc);
alwaysOffActionSets.remove(desc);
break;
}
}
visibleActionSets.add(newDesc);
alwaysOnActionSets.add(newDesc);
}
//for dynamic UI
/* package */ void removeActionSet(String id) {
for (int i = 0; i < visibleActionSets.size(); i++) {
IActionSetDescriptor desc = (IActionSetDescriptor)visibleActionSets.get(i);
if (desc.getId().equals(id)) {
visibleActionSets.remove(desc);
alwaysOnActionSets.remove(desc);
alwaysOffActionSets.remove(desc);
break;
}
}
}
public void toggleFastViewZoom() {
fastViewPane.toggleZoom();
}
}