blob: 1c049ec6fad42d46a8ef4522df0af9e933dee759 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
import org.eclipse.e4.compatibility.LegacyEditor;
import org.eclipse.e4.compatibility.LegacyView;
import org.eclipse.e4.core.services.IDisposable;
import org.eclipse.e4.core.services.context.IEclipseContext;
import org.eclipse.e4.extensions.ModelEditorReference;
import org.eclipse.e4.extensions.ModelReference;
import org.eclipse.e4.ui.model.application.MApplicationFactory;
import org.eclipse.e4.ui.model.application.MContribution;
import org.eclipse.e4.ui.model.application.MESCElement;
import org.eclipse.e4.ui.model.application.MEditor;
import org.eclipse.e4.ui.model.application.MEditorSashContainer;
import org.eclipse.e4.ui.model.application.MElementContainer;
import org.eclipse.e4.ui.model.application.MPart;
import org.eclipse.e4.ui.model.application.MPerspective;
import org.eclipse.e4.ui.model.application.MPerspectiveStack;
import org.eclipse.e4.ui.model.application.MUIElement;
import org.eclipse.e4.ui.model.application.MWindow;
import org.eclipse.e4.ui.workbench.swt.internal.AbstractPartRenderer;
import org.eclipse.e4.workbench.ui.api.ModeledPageLayout;
import org.eclipse.e4.workbench.ui.internal.IValueFunction;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.internal.provisional.action.ICoolBarManager2;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.program.Program;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.INavigationHistory;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IPathEditorInput;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IReusableEditor;
import org.eclipse.ui.ISaveablePart;
import org.eclipse.ui.ISaveablesLifecycleListener;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.MultiPartInitException;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.internal.dialogs.CustomizePerspectiveDialog;
import org.eclipse.ui.internal.misc.UIListenerLogging;
import org.eclipse.ui.internal.misc.UIStats;
import org.eclipse.ui.internal.registry.ActionSetRegistry;
import org.eclipse.ui.internal.registry.EditorDescriptor;
import org.eclipse.ui.internal.registry.IActionSetDescriptor;
import org.eclipse.ui.internal.registry.PerspectiveDescriptor;
import org.eclipse.ui.internal.registry.UIExtensionTracker;
import org.eclipse.ui.internal.tweaklets.GrabFocus;
import org.eclipse.ui.internal.tweaklets.TabBehaviour;
import org.eclipse.ui.internal.tweaklets.Tweaklets;
import org.eclipse.ui.internal.tweaklets.WorkbenchImplementation;
import org.eclipse.ui.internal.util.PrefUtil;
import org.eclipse.ui.internal.util.Util;
import org.eclipse.ui.model.IWorkbenchAdapter;
import org.eclipse.ui.part.AbstractMultiEditor;
import org.eclipse.ui.part.EditorPart;
import org.eclipse.ui.presentations.IStackPresentationSite;
/**
* A collection of views and editors in a workbench.
*/
public class WorkbenchPage extends CompatibleWorkbenchPage implements
IWorkbenchPage {
private static final String ATT_AGGREGATE_WORKING_SET_ID = "aggregateWorkingSetId"; //$NON-NLS-1$
private static final IEditorReference[] noEditorRefs = new IEditorReference[0];
protected WorkbenchWindow window;
private IAdaptable input;
private IWorkingSet workingSet;
private AggregateWorkingSet aggregateWorkingSet;
private Composite composite;
private EditorManager editorMgr;
private ArrayList removedEditors = new ArrayList();
private ListenerList propertyChangeListeners = new ListenerList();
private WorkbenchPagePartList partList = null;
private IActionBars actionBars;
private ActionSetManager actionSets;
private ViewFactory viewFactory;
private PerspectiveList perspList = new PerspectiveList();
private PerspectiveDescriptor deferredActivePersp;
private NavigationHistory navigationHistory = null;
private IStickyViewManager stickyViewMan = StickyViewManager
.getInstance(this);
/**
* If we're in the process of activating a part, this points to the new
* part. Otherwise, this is null.
*/
private IWorkbenchPartReference partBeingActivated = null;
/**
* If a part is being opened, don't allow a forceFocus() to request its
* activation as well.
*
* @since 3.4
*/
private boolean partBeingOpened = false;
/**
* Contains a list of perspectives that may be dirty due to plugin
* installation and removal.
*/
private Set dirtyPerspectives = new HashSet();
private IPropertyChangeListener workingSetPropertyChangeListener = new IPropertyChangeListener() {
/*
* Remove the working set from the page if the working set is deleted.
*/
public void propertyChange(PropertyChangeEvent event) {
String property = event.getProperty();
if (IWorkingSetManager.CHANGE_WORKING_SET_REMOVE.equals(property)) {
if (event.getOldValue().equals(workingSet)) {
setWorkingSet(null);
}
// room for optimization here
List newList = new ArrayList(Arrays.asList(workingSets));
if (newList.remove(event.getOldValue())) {
setWorkingSets((IWorkingSet[]) newList
.toArray(new IWorkingSet[newList.size()]));
}
}
}
};
private IExtensionTracker tracker;
private IWorkingSet[] workingSets = new IWorkingSet[0];
private String aggregateWorkingSetId;
private MWindow e4Window;
private IEclipseContext e4Context;
private ISelectionService selectionService;
/**
* Constructs a new page with a given perspective and input.
*
* @param w
* the parent window
* @param layoutID
* must not be <code>null</code>
* @param input
* the page input
* @throws WorkbenchException
* on null layout id
*/
public WorkbenchPage(WorkbenchWindow w, String layoutID, IAdaptable input)
throws WorkbenchException {
super();
if (layoutID == null) {
throw new WorkbenchException(
WorkbenchMessages.WorkbenchPage_UndefinedPerspective);
}
init(w, layoutID, input, true);
}
/**
* Constructs a page. <code>restoreState(IMemento)</code> should be called
* to restore this page from data stored in a persistance file.
*
* @param w
* the parent window
* @param input
* the page input
* @throws WorkbenchException
*/
public WorkbenchPage(WorkbenchWindow w, IAdaptable input)
throws WorkbenchException {
super();
init(w, null, input, false);
}
/**
* Activates a part. The part will be brought to the front and given focus.
*
* @param part
* the part to activate
*/
public void activate(IWorkbenchPart part) {
// Sanity check.
if (part == null || !certifyPart(part) || window.isClosing()) {
return;
}
// Activate the part and set its focus
IWorkbenchPartReference ref = getReference(part);
if (ref instanceof ModelReference) {
ModelReference modelRef = (ModelReference) ref;
MPart modelElement = modelRef.getModel();
if (modelElement != null) {
AbstractPartRenderer renderer = (AbstractPartRenderer) modelElement
.getFactory();
if (renderer != null)
renderer.activate(modelElement);
}
}
}
/**
* Add a fast view.
*/
public void addFastView(IViewReference ref) {
}
/**
* Add a fast view.
*/
public void makeFastView(IViewReference ref) {
}
/**
* Adds an IPartListener to the part service.
*/
public void addPartListener(IPartListener l) {
partList.getPartService().addPartListener(l);
}
/**
* Adds an IPartListener to the part service.
*/
public void addPartListener(IPartListener2 l) {
partList.getPartService().addPartListener(l);
}
/**
* Implements IWorkbenchPage
*
* @see org.eclipse.ui.IWorkbenchPage#addPropertyChangeListener(IPropertyChangeListener)
* @since 2.0
* @deprecated individual views should store a working set if needed and
* register a property change listener directly with the working
* set manager to receive notification when the view working set
* is removed.
*/
public void addPropertyChangeListener(IPropertyChangeListener listener) {
propertyChangeListeners.add(listener);
}
/*
* (non-Javadoc) Method declared on ISelectionListener.
*/
public void addSelectionListener(ISelectionListener listener) {
selectionService.addSelectionListener(listener);
}
/*
* (non-Javadoc) Method declared on ISelectionListener.
*/
public void addSelectionListener(String partId, ISelectionListener listener) {
selectionService.addSelectionListener(partId, listener);
}
/*
* (non-Javadoc) Method declared on ISelectionListener.
*/
public void addPostSelectionListener(ISelectionListener listener) {
selectionService.addPostSelectionListener(listener);
}
/*
* (non-Javadoc) Method declared on ISelectionListener.
*/
public void addPostSelectionListener(String partId,
ISelectionListener listener) {
selectionService.addPostSelectionListener(partId, listener);
}
/**
* Moves a part forward in the Z order of a perspective so it is visible. If
* the part is in the same stack as the active part, the new part is
* activated.
*
* @param part
* the part to bring to move forward
*/
public void bringToTop(IWorkbenchPart part) {
// Sanity check.
Perspective persp = getActivePerspective();
if (persp == null || !certifyPart(part)) {
return;
}
if (!((GrabFocus) Tweaklets.get(GrabFocus.KEY)).grabFocusAllowed(part)) {
return;
}
// TBD we have no shared parts so far. Processing below should be
// updated once shared parts are implemented
if (part instanceof EditorPart) {
MEditorSashContainer ea = (MEditorSashContainer) findPartInCurrentPerspective(ModeledPageLayout
.internalGetEditorArea());
String editorID = ((EditorPart) part).getEditorSite().getId();
IEditorInput editorInput = ((EditorPart) part).getEditorInput();
MEditor editorPart = findEditor(ea, editorID, editorInput);
if (editorPart != null) {
editorPart.setVisible(true);
ea.setActiveChild((MESCElement) editorPart);
} else {
try {
openEditor(editorInput, editorID, true, MATCH_NONE);
} catch (PartInitException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} else {
// TBD implement functionality for views
}
}
/**
* Shows a view.
*
* Assumes that a busy cursor is active.
*/
protected IViewPart busyShowView(String viewID, String secondaryID, int mode)
throws PartInitException {
Perspective persp = getActivePerspective();
if (persp == null) {
return null;
}
// If this view is already visible just return.
IViewReference ref = persp.findView(viewID, secondaryID);
IViewPart view = null;
if (ref != null) {
view = ref.getView(true);
}
if (view != null) {
busyShowView(view, mode);
return view;
}
// Show the view.
view = persp.showView(viewID, secondaryID);
if (view != null) {
window.firePerspectiveChanged(this, getPerspective(), null,
CHANGE_VIEW_SHOW);
window.firePerspectiveChanged(this, getPerspective(),
CHANGE_VIEW_SHOW);
}
return view;
}
/*
* Performs showing of the view in the given mode.
*/
private void busyShowView(IViewPart part, int mode) {
if (!((GrabFocus) Tweaklets.get(GrabFocus.KEY)).grabFocusAllowed(part)) {
return;
}
}
/**
* Returns whether a part exists in the current page.
*/
private boolean certifyPart(IWorkbenchPart part) {
// Workaround for bug 22325
if (part != null && !(part.getSite() instanceof PartSite)) {
return false;
}
return true;
}
/**
* Closes the perspective.
*/
public boolean close() {
final boolean[] ret = new boolean[1];
BusyIndicator.showWhile(null, new Runnable() {
public void run() {
ret[0] = window.closePage(WorkbenchPage.this, true);
}
});
return ret[0];
}
/**
* See IWorkbenchPage
*/
public boolean closeAllSavedEditors() {
// get the Saved editors
IEditorReference editors[] = getEditorReferences();
IEditorReference savedEditors[] = new IEditorReference[editors.length];
int j = 0;
for (int i = 0; i < editors.length; i++) {
IEditorReference editor = editors[i];
if (!editor.isDirty()) {
savedEditors[j++] = editor;
}
}
// there are no unsaved editors
if (j == 0) {
return true;
}
IEditorReference[] newSaved = new IEditorReference[j];
System.arraycopy(savedEditors, 0, newSaved, 0, j);
return closeEditors(newSaved, false);
}
/**
* See IWorkbenchPage
*/
public boolean closeAllEditors(boolean save) {
return closeEditors(getEditorReferences(), save);
}
/**
* See IWorkbenchPage
*/
public boolean closeEditors(IEditorReference[] refArray, boolean save) {
if (refArray.length == 0) {
return true;
}
// Check if we're being asked to close any parts that are already closed
// or cannot
// be closed at this time
ArrayList toClose = new ArrayList();
for (int i = 0; i < refArray.length; i++) {
IEditorReference reference = refArray[i];
// If we're in the middle of creating this part, this is a
// programming error. Abort the entire
// close operation. This usually occurs if someone tries to open a
// dialog in a method that
// isn't allowed to do so, and a *syncExec tries to close the part.
// If this shows up in a log
// file with a dialog's event loop on the stack, then the code that
// opened the dialog is usually
// at fault.
if (reference == partBeingActivated) {
WorkbenchPlugin
.log(new RuntimeException(
"WARNING: Blocked recursive attempt to close part " //$NON-NLS-1$
+ partBeingActivated.getId()
+ " while still in the middle of activating it")); //$NON-NLS-1$
return false;
}
if (reference instanceof WorkbenchPartReference) {
WorkbenchPartReference ref = (WorkbenchPartReference) reference;
// If we're being asked to close a part that is disposed (ie:
// already closed),
// skip it and proceed with closing the remaining parts.
if (ref.isDisposed()) {
continue;
}
}
toClose.add(reference);
}
IEditorReference[] editorRefs = (IEditorReference[]) toClose
.toArray(new IEditorReference[toClose.size()]);
// if active navigation position belongs to an editor being closed,
// update it
// (The navigation position for an editor N was updated as an editor N +
// 1
// was activated. As a result, all but the last editor have up-to-date
// navigation positions.)
for (int i = 0; i < editorRefs.length; i++) {
IEditorReference ref = editorRefs[i];
if (ref == null)
continue;
IEditorPart oldPart = ref.getEditor(false);
if (oldPart == null)
continue;
if (navigationHistory.updateActive(oldPart))
break; // updated - skip the rest
}
// notify the model manager before the close
List partsToClose = new ArrayList();
for (int i = 0; i < editorRefs.length; i++) {
IEditorPart refPart = editorRefs[i].getEditor(false);
if (refPart != null) {
partsToClose.add(refPart);
}
}
SaveablesList modelManager = null;
Object postCloseInfo = null;
if (partsToClose.size() > 0) {
modelManager = (SaveablesList) getWorkbenchWindow().getService(
ISaveablesLifecycleListener.class);
// this may prompt for saving and return null if the user canceled:
postCloseInfo = modelManager.preCloseParts(partsToClose, save,
getWorkbenchWindow());
if (postCloseInfo == null) {
return false;
}
}
// Fire pre-removal changes
for (int i = 0; i < editorRefs.length; i++) {
IEditorReference ref = editorRefs[i];
// Notify interested listeners before the close
window.firePerspectiveChanged(this, getPerspective(), ref,
CHANGE_EDITOR_CLOSE);
}
if (modelManager != null) {
modelManager.postClose(postCloseInfo);
}
// Close all editors.
for (int i = 0; i < editorRefs.length; i++) {
IEditorReference ref = editorRefs[i];
// Remove editor from the presentation
partRemoved(ref);
// now that it has disappeared from the model, dispose its context
MPart mEditorPart = ((ModelEditorReference) ref).getModel();
((IDisposable) mEditorPart.getContext()).dispose();
mEditorPart.setContext(null);
}
// Notify interested listeners after the close
window.firePerspectiveChanged(this, getPerspective(),
CHANGE_EDITOR_CLOSE);
// Return true on success.
return true;
}
/**
* See IWorkbenchPage#closeEditor
*/
public boolean closeEditor(IEditorReference editorRef, boolean save) {
return closeEditors(new IEditorReference[] { editorRef }, save);
}
/**
* See IWorkbenchPage#closeEditor
*/
public boolean closeEditor(IEditorPart editor, boolean save) {
IWorkbenchPartReference ref = getReference(editor);
if (ref instanceof IEditorReference) {
return closeEditors(
new IEditorReference[] { (IEditorReference) ref }, save);
}
return false;
}
/**
* @see IWorkbenchPage#closePerspective(IPerspectiveDescriptor, boolean,
* boolean)
*/
public void closePerspective(IPerspectiveDescriptor desc,
boolean saveParts, boolean closePage) {
Perspective persp = findPerspective(desc);
if (persp != null) {
perspList.openedList.remove(persp);
perspList.usedList.remove(persp);
// If we close the last perspective there is no active one...
if (perspList.openedList.isEmpty())
perspList.setActive(null);
}
}
/**
* Closes the specified perspective in this page. If this is not the last
* perspective in the page, and it is active, then the perspective specified
* by <code>descToActivate</code> will be activated. If the last perspective
* in this page is closed, then all editors are closed. Views that are not
* shown in other perspectives are closed as well. If <code>saveParts</code>
* is <code>true</code>, the user will be prompted to save any unsaved
* changes for parts that are being closed. The page itself is closed if
* <code>closePage</code> is <code>true</code>.
*
* @param desc
* the descriptor of the perspective to be closed
* @param descToActivate
* the descriptor of the perspective to activate
* @param saveParts
* whether the page's parts should be saved if closed
* @param closePage
* whether the page itself should be closed if last perspective
* @since 3.4
*/
public void closePerspective(IPerspectiveDescriptor desc,
IPerspectiveDescriptor descToActivate, boolean saveParts,
boolean closePage) {
Perspective persp = findPerspective(desc);
if (persp != null) {
perspList.openedList.remove(persp);
perspList.usedList.remove(persp);
// If we close the last perspective there is no active one...
if (perspList.openedList.isEmpty())
perspList.setActive(null);
}
}
/**
* Closes the specified perspective. If last perspective, then entire page
* is closed.
*
* @param persp
* the perspective to be closed
* @param saveParts
* whether the parts that are being closed should be saved
* (editors if last perspective, views if not shown in other
* parspectives)
*/
/* package */
void closePerspective(Perspective persp, boolean saveParts,
boolean closePage) {
closePerspective(persp, null, saveParts, closePage);
}
/**
* Closes the specified perspective. If last perspective, then entire page
* is closed.
*
* @param persp
* the perspective to be closed
* @param perspToActivate
* the perspective to activate
* @param saveParts
* whether the parts that are being closed should be saved
* (editors if last perspective, views if not shown in other
* parspectives)
*/
/* package */
void closePerspective(Perspective persp, Perspective perspToActivate,
boolean saveParts, boolean closePage) {
}
/**
* Forces all perspectives on the page to zoom out.
*/
public void unzoomAllPerspectives() {
}
/**
* @see IWorkbenchPage#closeAllPerspectives(boolean, boolean)
*/
public void closeAllPerspectives(boolean saveEditors, boolean closePage) {
if (perspList.isEmpty()) {
return;
}
// Always unzoom
if (isZoomed()) {
zoomOut();
}
if (saveEditors) {
if (!saveAllEditors(true)) {
return;
}
}
// Close all editors
if (!closeAllEditors(false)) {
return;
}
// Deactivate the active perspective and part
setPerspective((Perspective) null);
// Close each perspective in turn
PerspectiveList oldList = perspList;
perspList = new PerspectiveList();
Iterator itr = oldList.iterator();
while (itr.hasNext()) {
closePerspective((Perspective) itr.next(), false, false);
}
if (closePage) {
close();
}
}
/**
* Creates a new view set. Return null on failure.
*
* @param desc
* the perspective descriptor
* @param notify
* whether to fire a perspective opened event
*/
private Perspective createPerspective(PerspectiveDescriptor desc,
boolean notify) {
String label = desc.getId(); // debugging only
try {
UIStats.start(UIStats.CREATE_PERSPECTIVE, label);
Perspective persp = ((WorkbenchImplementation) Tweaklets
.get(WorkbenchImplementation.KEY)).createPerspective(desc,
this);
perspList.add(persp);
if (notify) {
window.firePerspectiveOpened(this, desc);
}
// if the perspective is fresh and uncustomzied then it is not dirty
// no reset will be prompted for
if (!desc.hasCustomDefinition()) {
dirtyPerspectives.remove(desc.getId());
}
return persp;
} catch (WorkbenchException e) {
if (!((Workbench) window.getWorkbench()).isStarting()) {
MessageDialog
.openError(
window.getShell(),
WorkbenchMessages.Error,
NLS
.bind(
WorkbenchMessages.Workbench_showPerspectiveError,
desc.getId()));
}
return null;
} finally {
UIStats.end(UIStats.CREATE_PERSPECTIVE, desc.getId(), label);
}
}
/**
* This is called by child objects after a part has been added to the page.
* The page will in turn notify its listeners.
*/
/* package */void partAdded(WorkbenchPartReference ref) {
partList.addPart(ref);
}
/**
* This is called by child objects after a part has been added to the page.
* The part will be queued for disposal after all listeners have been
* notified
*/
/* package */void partRemoved(IWorkbenchPartReference ref) {
disposePart(ref);
}
private void disposePart(IWorkbenchPartReference ref) {
if (ref instanceof WorkbenchPartReference) {
partList.removePart((WorkbenchPartReference) ref);
((WorkbenchPartReference) ref).dispose();
} else if (ref instanceof ModelReference) {
MPart modelPart = ((ModelReference) ref).getModel();
partList.firePartClosed(ref);
modelPart.setVisible(false);
}
}
/**
* Detaches a view from the WorkbenchWindow.
*/
public void detachView(IViewReference ref) {
}
/**
* Removes a detachedwindow.
*/
public void attachView(IViewReference ref) {
}
/**
* Cleanup.
*/
public void dispose() {
// Always unzoom
if (isZoomed()) {
zoomOut();
}
}
/**
* @return NavigationHistory
*/
public INavigationHistory getNavigationHistory() {
return (INavigationHistory) e4Context.get(INavigationHistory.class
.getName());
}
/**
* Edits the action sets.
*/
public boolean editActionSets() {
Perspective persp = getActivePerspective();
if (persp == null) {
return false;
}
// Create list dialog.
CustomizePerspectiveDialog dlg = window
.createCustomizePerspectiveDialog(persp);
// Open.
boolean ret = (dlg.open() == Window.OK);
if (ret) {
window.updateActionSets();
window.firePerspectiveChanged(this, getPerspective(), CHANGE_RESET);
window.firePerspectiveChanged(this, getPerspective(),
CHANGE_RESET_COMPLETE);
}
return ret;
}
/**
* Returns the first view manager with given ID.
*/
public Perspective findPerspective(IPerspectiveDescriptor desc) {
Iterator itr = perspList.iterator();
while (itr.hasNext()) {
Perspective mgr = (Perspective) itr.next();
if (desc.getId().equals(mgr.getDesc().getId())) {
return mgr;
}
}
return null;
}
/**
* See IWorkbenchPage@findView.
*/
public IViewPart findView(String id) {
IViewReference ref = findViewReference(id);
if (ref == null) {
return null;
}
return ref.getView(true);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchPage
*/
public IViewReference findViewReference(String viewId) {
return findViewReference(viewId, null);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchPage
*/
public IViewReference findViewReference(String viewId, String secondaryId) {
MPart modelPart = ModeledPageLayout.findPart(e4Window, viewId);
if (modelPart instanceof MPart) {
Object obj = ((MPart) modelPart).getObject();
if (!(obj instanceof LegacyView))
return null;
LegacyView lv = (LegacyView) obj;
return (IViewReference) getReference(lv.getViewPart());
}
return null;
}
/**
* Notify property change listeners about a property change.
*
* @param changeId
* the change id
* @param oldValue
* old property value
* @param newValue
* new property value
*/
private void firePropertyChange(String changeId, Object oldValue,
Object newValue) {
UIListenerLogging.logPagePropertyChanged(this, changeId, oldValue,
newValue);
Object[] listeners = propertyChangeListeners.getListeners();
PropertyChangeEvent event = new PropertyChangeEvent(this, changeId,
oldValue, newValue);
for (int i = 0; i < listeners.length; i++) {
((IPropertyChangeListener) listeners[i]).propertyChange(event);
}
}
/*
* Returns the action bars.
*/
public IActionBars getActionBars() {
if (actionBars == null) {
actionBars = new WWinActionBars(window);
}
return actionBars;
}
/**
* Returns an array of the visible action sets.
*/
public IActionSetDescriptor[] getActionSets() {
Collection visibleItems = actionSets.getVisibleItems();
return (IActionSetDescriptor[]) visibleItems
.toArray(new IActionSetDescriptor[visibleItems.size()]);
}
/**
* @see IWorkbenchPage
*/
public IEditorPart getActiveEditor() {
return partList.getActiveEditor();
}
/**
* Returns the reference for the active editor, or <code>null</code> if
* there is no active editor.
*
* @return the active editor reference or <code>null</code>
*/
public IEditorReference getActiveEditorReference() {
return partList.getActiveEditorReference();
}
/*
* (non-Javadoc) Method declared on IPartService
*/
public IWorkbenchPart getActivePart() {
return partList.getActivePart();
}
/*
* (non-Javadoc) Method declared on IPartService
*/
public IWorkbenchPartReference getActivePartReference() {
return partList.getActivePartReference();
}
/**
* Returns the active perspective for the page, <code>null</code> if none.
*/
public Perspective getActivePerspective() {
return perspList.getActive();
}
/**
* Returns the client composite.
*/
public Composite getClientComposite() {
return composite;
}
/**
* Answer the perspective presentation.
*/
public PerspectiveHelper getPerspectivePresentation() {
if (getActivePerspective() != null) {
return getActivePerspective().getPresentation();
}
return null;
}
/**
* See IWorkbenchPage.
*/
public IEditorPart[] getEditors() {
final IEditorReference refs[] = getEditorReferences();
final ArrayList result = new ArrayList(refs.length);
Display d = getWorkbenchWindow().getShell().getDisplay();
// Must be backward compatible.
d.syncExec(new Runnable() {
public void run() {
for (int i = 0; i < refs.length; i++) {
IWorkbenchPart part = refs[i].getPart(true);
if (part != null) {
result.add(part);
}
}
}
});
final IEditorPart editors[] = new IEditorPart[result.size()];
return (IEditorPart[]) result.toArray(editors);
}
public IEditorPart[] getDirtyEditors() {
return new IEditorPart[0];
}
public ISaveablePart[] getDirtyParts() {
List result = new ArrayList(3);
IWorkbenchPartReference[] allParts = getAllParts();
for (int i = 0; i < allParts.length; i++) {
IWorkbenchPartReference reference = allParts[i];
IWorkbenchPart part = reference.getPart(false);
if (part != null && part instanceof ISaveablePart) {
ISaveablePart saveable = (ISaveablePart) part;
if (saveable.isDirty()) {
result.add(saveable);
}
}
}
return (ISaveablePart[]) result
.toArray(new ISaveablePart[result.size()]);
}
/**
* See IWorkbenchPage.
*/
public IEditorPart findEditor(IEditorInput input) {
IEditorReference[] editorReferences = findEditors(input, null,
IWorkbenchPage.MATCH_INPUT);
if (editorReferences.length == 0) {
return null;
}
return editorReferences[0].getEditor(true);
}
/**
* See IWorkbenchPage.
*/
public IEditorReference[] findEditors(IEditorInput input, String editorId,
int matchFlags) {
IEditorReference[] refs = getEditorReferences();
ArrayList<IEditorReference> matches = null;
for (IEditorReference ref : refs) {
if ((matchFlags & IWorkbenchPage.MATCH_ID) != 0) {
String testID = ref.getId();
if ((editorId != null) && !(editorId.equals(testID)))
continue;
if (editorId == null && testID != null)
continue;
}
if ((matchFlags & IWorkbenchPage.MATCH_INPUT) != 0) {
IEditorInput testInput;
try {
testInput = ref.getEditorInput();
} catch (PartInitException e) {
continue;
}
if ((input != null) && !(input.equals(testInput)))
continue;
if (input == null && testInput != null)
continue;
}
if (matches == null)
matches = new ArrayList<IEditorReference>(3);
matches.add(ref);
}
if (matches == null)
return noEditorRefs;
IEditorReference[] result = new IEditorReference[matches.size()];
matches.toArray(result);
return result;
}
/**
* See IWorkbenchPage.
*/
public IEditorReference[] getEditorReferences() {
ArrayList<IEditorReference> result = new ArrayList<IEditorReference>();
getContainedEditorRefs(result, e4Window);
IEditorReference[] typedResult = new IEditorReference[result.size()];
result.toArray(typedResult);
return typedResult;
}
public void getContainedEditorRefs(ArrayList<IEditorReference> result,
MElementContainer<?> container) {
for (MUIElement child : container.getChildren()) {
if (child instanceof MEditor) {
// @issue here we are expected to sort views from editors.
// However, there is no such distinction for E4 elements.
// The code below is only good for legacy views/editors.
Object object = ((MContribution) child).getObject();
if (object instanceof EditorPart)
result.add(new ModelEditorReference((MPart) child, this));
}
if (child instanceof MElementContainer<?>)
getContainedEditorRefs(result,
(MElementContainer<MUIElement>) child);
}
}
/**
* Returns the docked views.
*/
public IViewReference[] getFastViews() {
Perspective persp = getActivePerspective();
if (persp != null) {
return persp.getFastViews();
} else {
return new IViewReference[0];
}
}
/**
* @see IWorkbenchPage
*/
public IAdaptable getInput() {
return input;
}
/**
* Returns the page label. This is a combination of the page input and
* active perspective.
*/
public String getLabel() {
String label = WorkbenchMessages.WorkbenchPage_UnknownLabel;
IWorkbenchAdapter adapter = (IWorkbenchAdapter) Util.getAdapter(input,
IWorkbenchAdapter.class);
if (adapter != null) {
label = adapter.getLabel(input);
}
Perspective persp = getActivePerspective();
if (persp != null) {
label = NLS.bind(WorkbenchMessages.WorkbenchPage_PerspectiveFormat,
label, persp.getDesc().getLabel());
} else if (deferredActivePersp != null) {
label = NLS.bind(WorkbenchMessages.WorkbenchPage_PerspectiveFormat,
label, deferredActivePersp.getLabel());
}
return label;
}
/**
* Returns the perspective.
*/
public IPerspectiveDescriptor getPerspective() {
if (deferredActivePersp != null) {
return deferredActivePersp;
}
Perspective persp = getActivePerspective();
if (persp != null) {
return persp.getDesc();
} else {
return null;
}
}
/*
* (non-Javadoc) Method declared on ISelectionService
*/
public ISelection getSelection() {
return selectionService.getSelection();
}
/*
* (non-Javadoc) Method declared on ISelectionService
*/
public ISelection getSelection(String partId) {
return selectionService.getSelection(partId);
}
/**
* Returns the ids of the parts to list in the Show In... prompter. This is
* a List of Strings.
*/
public ArrayList getShowInPartIds() {
Perspective persp = getActivePerspective();
if (persp != null) {
return persp.getShowInPartIds();
} else {
return new ArrayList();
}
}
/**
* The user successfully performed a Show In... action on the specified
* part. Update the list of Show In items accordingly.
*/
public void performedShowIn(String partId) {
Perspective persp = getActivePerspective();
if (persp != null) {
persp.performedShowIn(partId);
}
}
/**
* Sorts the given collection of show in target part ids in MRU order.
*/
public void sortShowInPartIds(ArrayList partIds) {
final Perspective persp = getActivePerspective();
if (persp != null) {
Collections.sort(partIds, new Comparator() {
public int compare(Object a, Object b) {
long ta = persp.getShowInTime((String) a);
long tb = persp.getShowInTime((String) b);
return (ta == tb) ? 0 : ((ta > tb) ? -1 : 1);
}
});
}
}
/*
* Returns the view factory.
*/
public ViewFactory getViewFactory() {
if (viewFactory == null) {
viewFactory = new ViewFactory(this, WorkbenchPlugin.getDefault()
.getViewRegistry());
}
return viewFactory;
}
/**
* See IWorkbenchPage.
*/
public IViewReference[] getViewReferences() {
Perspective persp = getActivePerspective();
if (persp != null) {
return persp.getViewReferences();
} else {
return new IViewReference[0];
}
}
/**
* See IWorkbenchPage.
*/
public IViewPart[] getViews() {
return getViews(null, true);
}
/**
* Returns all view parts in the specified perspective
*
* @param persp
* the perspective
* @return an array of view parts
* @since 3.1
*/
/* package */IViewPart[] getViews(Perspective persp, boolean restore) {
if (persp == null) {
persp = getActivePerspective();
}
if (persp != null) {
IViewReference refs[] = persp.getViewReferences();
ArrayList parts = new ArrayList(refs.length);
for (int i = 0; i < refs.length; i++) {
IWorkbenchPart part = refs[i].getPart(restore);
if (part != null) {
parts.add(part);
}
}
IViewPart[] result = new IViewPart[parts.size()];
return (IViewPart[]) parts.toArray(result);
}
return new IViewPart[0];
}
/**
* See IWorkbenchPage.
*/
public IWorkbenchWindow getWorkbenchWindow() {
return window;
}
/**
* Implements IWorkbenchPage
*
* @see org.eclipse.ui.IWorkbenchPage#getWorkingSet()
* @since 2.0
* @deprecated individual views should store a working set if needed
*/
public IWorkingSet getWorkingSet() {
return workingSet;
}
/**
* @see IWorkbenchPage
*/
public void hideActionSet(String actionSetID) {
Perspective persp = getActivePerspective();
if (persp != null) {
persp.removeActionSet(actionSetID);
window.updateActionSets();
window.firePerspectiveChanged(this, getPerspective(),
CHANGE_ACTION_SET_HIDE);
}
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ui.IWorkbenchPage#hideView(org.eclipse.ui.IViewReference)
*/
public void hideView(IViewReference ref) {
// Sanity check.
if (ref == null) {
return;
}
Perspective persp = getActivePerspective();
if (persp == null) {
return;
}
IViewPart view = ref.getView(false);
if (view != null) {
if (!certifyPart(view)) {
return;
}
// Confirm.
if (view instanceof ISaveablePart) {
ISaveablePart saveable = (ISaveablePart) view;
if (saveable.isSaveOnCloseNeeded()) {
IWorkbenchWindow window = view.getSite()
.getWorkbenchWindow();
boolean success = EditorManager.saveAll(Collections
.singletonList(view), true, true, false, window);
if (!success) {
// the user cancelled.
return;
}
}
}
}
// Notify interested listeners before the hide
window.firePerspectiveChanged(this, persp.getDesc(), ref,
CHANGE_VIEW_HIDE);
// Hide the part.
persp.hideView(ref);
// Notify interested listeners after the hide
window.firePerspectiveChanged(this, getPerspective(), CHANGE_VIEW_HIDE);
}
/* package */void refreshActiveView() {
}
/**
* See IPerspective
*/
public void hideView(IViewPart view) {
hideView((IViewReference) getReference(view));
}
/**
* Initialize the page.
*
* @param w
* the parent window
* @param layoutID
* may be <code>null</code> if restoring from file
* @param input
* the page input
* @param openExtras
* whether to process the perspective extras preference
*/
private void init(WorkbenchWindow w, String layoutID, IAdaptable input,
boolean openExtras) throws WorkbenchException {
// Save args.
this.window = w;
this.input = input;
actionSets = new ActionSetManager(w);
e4Window = w.getModelWindow();
e4Context = e4Window.getContext();
e4Context.set(IWorkbenchPage.class.getName(), this);
e4Context.set(WorkbenchPage.class.getName(), this);
selectionService = (ISelectionService) e4Context
.get(ISelectionService.class.getName());
partList = new WorkbenchPagePartList(selectionService);
navigationHistory = new NavigationHistory(this);
e4Context.set(INavigationHistory.class.getName(), navigationHistory);
((Notifier) e4Window).eAdapters().add(
new PartsEventTransformer(e4Context, partList));
// Create presentation.
// Get perspective descriptor.
if (layoutID != null) {
PerspectiveDescriptor desc = (PerspectiveDescriptor) WorkbenchPlugin
.getDefault().getPerspectiveRegistry()
.findPerspectiveWithId(layoutID);
if (desc == null) {
throw new WorkbenchException(
NLS
.bind(
WorkbenchMessages.WorkbenchPage_ErrorCreatingPerspective,
layoutID));
}
Perspective persp = findPerspective(desc);
if (persp == null) {
persp = createPerspective(desc, true);
}
perspList.setActive(persp);
window.firePerspectiveActivated(this, desc);
}
// read model extensions
ModelExtensionProcessor extProcessor = new ModelExtensionProcessor(
e4Window);
extProcessor.addModelExtensions();
partEvents();
}
private void partEvents() {
partList.getPartService().addPartListener(new IPartListener() {
public void partOpened(IWorkbenchPart part) {
// TODO Auto-generated method stub
}
public void partDeactivated(IWorkbenchPart part) {
// TODO Auto-generated method stub
}
public void partClosed(IWorkbenchPart part) {
// TODO Auto-generated method stub
}
public void partBroughtToTop(IWorkbenchPart part) {
calculateActionSets(part);
}
public void partActivated(IWorkbenchPart part) {
calculateActionSets(part);
}
});
}
private ArrayList oldActionSets = new ArrayList();
void calculateActionSets(IWorkbenchPart part) {
ArrayList newActionSets = new ArrayList();
if (part != null) {
IActionSetDescriptor[] partActionSets = WorkbenchPlugin
.getDefault().getActionSetRegistry().getActionSetsFor(
part.getSite().getId());
for (int i = 0; i < partActionSets.length; i++) {
newActionSets.add(partActionSets[i]);
}
}
IEditorPart editor = partList.getActiveEditor();
if (editor != null && editor != part) {
IActionSetDescriptor[] editorActionSets = WorkbenchPlugin
.getDefault().getActionSetRegistry().getActionSetsFor(
editor.getSite().getId());
for (int i = 0; i < editorActionSets.length; i++) {
newActionSets.add(editorActionSets[i]);
}
}
if (oldActionSets.equals(newActionSets)) {
return;
}
IContextService service = (IContextService) window
.getService(IContextService.class);
try {
service.deferUpdates(true);
// show the new
for (int i = 0; i < newActionSets.size(); i++) {
actionSets.showAction((IActionSetDescriptor) newActionSets
.get(i));
}
// hide the old
for (int i = 0; i < oldActionSets.size(); i++) {
actionSets.hideAction((IActionSetDescriptor) oldActionSets
.get(i));
}
oldActionSets = newActionSets;
} finally {
service.deferUpdates(false);
}
Perspective persp = getActivePerspective();
if (persp == null) {
return;
}
window.updateActionSets(); // this calls updateActionBars
window.firePerspectiveChanged(WorkbenchPage.this, getPerspective(),
CHANGE_ACTION_SET_SHOW);
}
/**
* Opens the perspectives specified in the PERSPECTIVE_BAR_EXTRAS preference
* (see bug 84226).
*/
public void openPerspectiveExtras() {
String extras = PrefUtil.getAPIPreferenceStore().getString(
IWorkbenchPreferenceConstants.PERSPECTIVE_BAR_EXTRAS);
StringTokenizer tok = new StringTokenizer(extras, ", "); //$NON-NLS-1$
ArrayList descs = new ArrayList();
while (tok.hasMoreTokens()) {
String id = tok.nextToken();
IPerspectiveDescriptor desc = WorkbenchPlugin.getDefault()
.getPerspectiveRegistry().findPerspectiveWithId(id);
if (desc != null) {
descs.add(desc);
}
}
// HACK: The perspective switcher currently adds the button for a new
// perspective to the beginning of the list.
// So, we process the extra perspectives in reverse order here to have
// their buttons appear in the order declared.
for (int i = descs.size(); --i >= 0;) {
PerspectiveDescriptor desc = (PerspectiveDescriptor) descs.get(i);
if (findPerspective(desc) == null) {
createPerspective(desc, true);
}
}
}
/**
* Finds and returns a part in the current perspective with the
* corresponding id.
*
* @param partId
* the id of the part, must not be <code>null</code>
* @return a part in the current perspective with the specified id
*/
private MPart findPartInCurrentPerspective(String partId) {
Assert.isNotNull(partId);
// retrieve the perspective stack from our window
MPerspectiveStack perspStack = (MPerspectiveStack) ModeledPageLayout
.findPart(e4Window, "PerspectiveStack"); //$NON-NLS-1$
// get the active/current one
MPerspective curPersp = (MPerspective) perspStack.getActiveChild();
// try to find a child part
return ModeledPageLayout.findPart(curPersp, partId);
}
/**
* See IWorkbenchPage.
*/
public boolean isPartVisible(IWorkbenchPart part) {
if (part == null) {
return false;
}
MPart modelPart = findPartInCurrentPerspective(part.getSite().getId());
// couldn't find the part, return false
if (modelPart == null) {
return false;
}
MElementContainer<MUIElement> parent = modelPart.getParent();
// no parent, probably not visible
if (parent == null) {
return false;
}
// return whether the parent's active child is us
return parent.getActiveChild() == modelPart;
}
/**
* See IWorkbenchPage.
*/
public boolean isEditorAreaVisible() {
Perspective persp = getActivePerspective();
if (persp == null) {
return false;
}
return persp.isEditorAreaVisible();
}
/**
* Returns whether the view is fast.
*/
public boolean isFastView(IViewReference ref) {
Perspective persp = getActivePerspective();
if (persp != null) {
return persp.isFastView(ref);
} else {
return false;
}
}
/**
* Return whether the view is closeable or not.
*
* @param ref
* the view reference to check. Must not be <code>null</code>.
* @return true if the part is closeable.
* @since 3.1.1
*/
public boolean isCloseable(IViewReference ref) {
Perspective persp = getActivePerspective();
if (persp != null) {
return persp.isCloseable(ref);
}
return false;
}
/**
* Return whether the view is moveable or not.
*
* @param ref
* the view reference to check. Must not be <code>null</code>.
* @return true if the part is moveable.
* @since 3.1.1
*/
public boolean isMoveable(IViewReference ref) {
Perspective persp = getActivePerspective();
if (persp != null) {
return persp.isMoveable(ref);
}
return false;
}
/**
* Returns whether the layout of the active perspective is fixed.
*/
public boolean isFixedLayout() {
Perspective persp = getActivePerspective();
if (persp != null) {
return persp.isFixedLayout();
} else {
return false;
}
}
/**
* Return the active fast view or null if there are no fast views or if
* there are all minimized.
*/
public IViewReference getActiveFastView() {
Perspective persp = getActivePerspective();
if (persp != null) {
return persp.getActiveFastView();
} else {
return null;
}
}
/**
* Return true if the perspective has a dirty editor.
*/
protected boolean isSaveNeeded() {
return false;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchPage#isPageZoomed()
*/
public boolean isPageZoomed() {
return false;
}
/**
* Returns whether the page is zoomed.
*
* @return <code>true</code> if the page is zoomed.
*
* <strong>NOTE:</strong> As of 3.3 this method should always return
* 'false' when using the new min/max behavior. It is only used for
* legacy 'zoom' handling.
*
*/
public boolean isZoomed() {
return false;
}
/**
* This method is called when the page is activated.
*/
protected void onActivate() {
composite.setVisible(true);
Perspective persp = getActivePerspective();
if (persp != null) {
persp.onActivate();
}
}
/**
* This method is called when the page is deactivated.
*/
protected void onDeactivate() {
if (getActivePerspective() != null) {
getActivePerspective().onDeactivate();
}
composite.setVisible(false);
}
/**
* See IWorkbenchPage.
*/
public void reuseEditor(IReusableEditor editor, IEditorInput input) {
// Rather than calling editor.setInput on the editor directly, we do it
// through the part reference.
// This case lets us detect badly behaved editors that are not firing a
// PROP_INPUT event in response
// to the input change... but if all editors obeyed their API contract,
// the "else" branch would be
// sufficient.
IWorkbenchPartReference ref = getReference(editor);
if (ref instanceof EditorReference) {
EditorReference editorRef = (EditorReference) ref;
editorRef.setInput(input);
} else {
editor.setInput(input);
}
navigationHistory.markEditor(editor);
}
/**
* See IWorkbenchPage.
*/
public IEditorPart openEditor(IEditorInput input, String editorID)
throws PartInitException {
return openEditor(input, editorID, true, MATCH_INPUT);
}
/**
* See IWorkbenchPage.
*/
public IEditorPart openEditor(IEditorInput input, String editorID,
boolean activate) throws PartInitException {
return openEditor(input, editorID, activate, MATCH_INPUT);
}
/**
* See IWorkbenchPage.
*/
public IEditorPart openEditor(final IEditorInput input,
final String editorID, final boolean activate, final int matchFlags)
throws PartInitException {
return openEditor(input, editorID, activate, matchFlags, null);
}
/**
* This is not public API but for use internally. editorState can be
* <code>null</code>.
*/
public IEditorPart openEditor(final IEditorInput input,
final String editorID, final boolean activate,
final int matchFlags, final IMemento editorState)
throws PartInitException {
if (input == null || editorID == null) {
throw new IllegalArgumentException();
}
// Special handling for external editors (they have no tabs...)
if ("org.eclipse.ui.systemExternalEditor".equals(editorID) //$NON-NLS-1$
|| "org.eclipse.ui.browser.editorSupport".equals(editorID)) { //$NON-NLS-1$
if (input instanceof IPathEditorInput) {
IPathEditorInput fileInput = (IPathEditorInput) input;
String fullPath = fileInput.getPath().toOSString();
Program.launch(fullPath);
return null;
}
}
// retrieve the editor area
MEditorSashContainer ea = (MEditorSashContainer) findPartInCurrentPerspective(ModeledPageLayout
.internalGetEditorArea());
// TBD need to add processing for other flags: MATCH_INPUT, MATCH_ID
if (matchFlags != IWorkbenchPage.MATCH_NONE) {
// Find a matching editor
MEditor existingEditor = findEditor(ea, editorID, input);
if (existingEditor != null && activate) {
// Set the initial focus
LegacyEditor le = (LegacyEditor) existingEditor.getObject();
Object impl = le.getEditorWBPart();
if (impl instanceof IWorkbenchPart) {
activate((IWorkbenchPart) impl);
} else {
ea.setActiveChild(existingEditor);
}
// return the existing editor
return (IEditorPart) impl;
}
}
// No patching editor found, create one
MEditor editorPart = MApplicationFactory.eINSTANCE.createEditor();
editorPart.setURI(LegacyEditor.LEGACY_VIEW_URI);
editorPart.setId(editorID);
editorPart.setName(input.getName());
// editor part icon will be set in LegacyViewFactory
editorPart.setVisible(false);
ea.getChildren().add(editorPart);
editorPart.getContext().set(IEditorInput.class.getName(), input);
editorPart.setVisible(true);
// Manage the 'close' button
final IEclipseContext editorContext = editorPart.getContext();
final MEditor theEditor = editorPart;
IValueFunction closeFunc = new IValueFunction() {
public Object getValue() {
Object impl = ((MPart) theEditor).getObject();
if (impl instanceof EditorPart) {
EditorPart edPart = (EditorPart) impl;
boolean closed = closeEditor(edPart, true);
return closed;
}
return new Boolean(true);
}
};
editorContext.set("canCloseFunc", closeFunc); //$NON-NLS-1$
LegacyEditor le = (LegacyEditor) editorPart.getObject();
Object impl = le.getEditorWBPart();
if (impl instanceof IWorkbenchPart) { // TBD this is always the case?
IWorkbenchPart workbenchPart = (IWorkbenchPart) impl;
if (activate)
activate(workbenchPart);
else
bringToTop(workbenchPart);
}
return le.getEditorWBPart();
}
/**
* @param ea
* @param editorID
* @param input2
* @return
*/
private MEditor findEditor(MEditorSashContainer ea, String editorID,
IEditorInput input) {
MUIElement ed = ModeledPageLayout.findElementById(ea, editorID);
if (ed instanceof MEditor) {
MEditor editor = (MEditor) ed;
IEditorInput e = (IEditorInput) editor.getContext().get(
IEditorInput.class.getName());
if (input.equals(e)) {
return editor;
}
}
return null;
}
/*
* Added to fix Bug 178235 [EditorMgmt] DBCS 3.3 - Cannot open file with
* external program. Opens a new editor using the given input and
* descriptor. (Normally, editors are opened using an editor ID and an
* input.)
*/
public IEditorPart openEditorFromDescriptor(final IEditorInput input,
final IEditorDescriptor editorDescriptor, final boolean activate,
final IMemento editorState) throws PartInitException {
if (input == null || !(editorDescriptor instanceof EditorDescriptor)) {
throw new IllegalArgumentException();
}
final IEditorPart result[] = new IEditorPart[1];
final PartInitException ex[] = new PartInitException[1];
BusyIndicator.showWhile(window.getWorkbench().getDisplay(),
new Runnable() {
public void run() {
try {
result[0] = busyOpenEditorFromDescriptor(input,
(EditorDescriptor) editorDescriptor,
activate, editorState);
} catch (PartInitException e) {
ex[0] = e;
}
}
});
if (ex[0] != null) {
throw ex[0];
}
return result[0];
}
/*
* Added to fix Bug 178235 [EditorMgmt] DBCS 3.3 - Cannot open file with
* external program. See openEditorFromDescriptor().
*/
private IEditorPart busyOpenEditorFromDescriptor(IEditorInput input,
EditorDescriptor editorDescriptor, boolean activate,
IMemento editorState) throws PartInitException {
final Workbench workbench = (Workbench) getWorkbenchWindow()
.getWorkbench();
workbench.largeUpdateStart();
try {
return busyOpenEditorFromDescriptorBatched(input, editorDescriptor,
activate, editorState);
} finally {
workbench.largeUpdateEnd();
}
}
/**
* Do not call this method. Use <code>busyOpenEditor</code>.
*
* @see IWorkbenchPage#openEditor(IEditorInput, String, boolean)
*/
protected IEditorPart busyOpenEditorBatched(IEditorInput input,
String editorID, boolean activate, int matchFlags,
IMemento editorState) throws PartInitException {
IEditorPart editor = null;
// Otherwise, create a new one. This may cause the new editor to
// become the visible (i.e top) editor.
IEditorReference ref = null;
try {
partBeingOpened = true;
ref = null; // open the editor, somehow
if (ref != null) {
editor = ref.getEditor(true);
}
} finally {
partBeingOpened = false;
}
if (editor != null) {
setEditorAreaVisible(true);
if (activate) {
if (editor instanceof AbstractMultiEditor) {
activate(((AbstractMultiEditor) editor).getActiveEditor());
} else {
activate(editor);
}
} else {
bringToTop(editor);
}
window.firePerspectiveChanged(this, getPerspective(), ref,
CHANGE_EDITOR_OPEN);
window.firePerspectiveChanged(this, getPerspective(),
CHANGE_EDITOR_OPEN);
}
return editor;
}
/*
* Added to fix Bug 178235 [EditorMgmt] DBCS 3.3 - Cannot open file with
* external program. See openEditorFromDescriptor().
*/
private IEditorPart busyOpenEditorFromDescriptorBatched(IEditorInput input,
EditorDescriptor editorDescriptor, boolean activate,
IMemento editorState) throws PartInitException {
IEditorPart editor = null;
// Create a new one. This may cause the new editor to
// become the visible (i.e top) editor.
IEditorReference ref = null;
ref = null; // open the editor somehow
if (ref != null) {
editor = ref.getEditor(true);
}
if (editor != null) {
setEditorAreaVisible(true);
if (activate) {
if (editor instanceof AbstractMultiEditor) {
activate(((AbstractMultiEditor) editor).getActiveEditor());
} else {
activate(editor);
}
} else {
bringToTop(editor);
}
window.firePerspectiveChanged(this, getPerspective(), ref,
CHANGE_EDITOR_OPEN);
window.firePerspectiveChanged(this, getPerspective(),
CHANGE_EDITOR_OPEN);
}
return editor;
}
public void openEmptyTab() {
}
protected void showEditor(boolean activate, IEditorPart editor) {
setEditorAreaVisible(true);
if (activate) {
zoomOutIfNecessary(editor);
activate(editor);
} else {
bringToTop(editor);
}
}
/**
* See IWorkbenchPage.
*/
public boolean isEditorPinned(IEditorPart editor) {
// TBD we need to add "pinned" attribute somewhere in the E4 model. The
// code
// below is just to work around a cast class exception
IWorkbenchPartReference ref = getReference(editor);
if (ref == null)
return false;
if (ref instanceof WorkbenchPartReference)
return ((WorkbenchPartReference) ref).isPinned();
return false;
}
/**
* Returns whether changes to a part will affect zoom. There are a few
* conditions for this .. - we are zoomed. - the part is contained in the
* main window. - the part is not the zoom part - the part is not a fast
* view - the part and the zoom part are not in the same editor workbook
*/
private boolean partChangeAffectsZoom(IWorkbenchPartReference ref) {
PartPane pane = ((WorkbenchPartReference) ref).getPane();
if (pane instanceof MultiEditorInnerPane) {
pane = ((MultiEditorInnerPane) pane).getParentPane();
}
return getActivePerspective().getPresentation().partChangeAffectsZoom(
pane);
}
/**
* Removes a fast view.
*/
public void removeFastView(IViewReference ref) {
Perspective persp = getActivePerspective();
if (persp == null) {
return;
}
// Do real work.
persp.removeFastView(ref);
// Notify listeners.
window.firePerspectiveChanged(this, getPerspective(), ref,
CHANGE_FAST_VIEW_REMOVE);
window.firePerspectiveChanged(this, getPerspective(),
CHANGE_FAST_VIEW_REMOVE);
}
/**
* Removes an IPartListener from the part service.
*/
public void removePartListener(IPartListener l) {
partList.getPartService().removePartListener(l);
}
/**
* Removes an IPartListener from the part service.
*/
public void removePartListener(IPartListener2 l) {
partList.getPartService().removePartListener(l);
}
/**
* Implements IWorkbenchPage
*
* @see org.eclipse.ui.IWorkbenchPage#removePropertyChangeListener(IPropertyChangeListener)
* @since 2.0
* @deprecated individual views should store a working set if needed and
* register a property change listener directly with the working
* set manager to receive notification when the view working set
* is removed.
*/
public void removePropertyChangeListener(IPropertyChangeListener listener) {
propertyChangeListeners.remove(listener);
}
/*
* (non-Javadoc) Method declared on ISelectionListener.
*/
public void removeSelectionListener(ISelectionListener listener) {
selectionService.removeSelectionListener(listener);
}
/*
* (non-Javadoc) Method declared on ISelectionListener.
*/
public void removeSelectionListener(String partId,
ISelectionListener listener) {
selectionService.removeSelectionListener(partId, listener);
}
/*
* (non-Javadoc) Method declared on ISelectionListener.
*/
public void removePostSelectionListener(ISelectionListener listener) {
selectionService.removePostSelectionListener(listener);
}
/*
* (non-Javadoc) Method declared on ISelectionListener.
*/
public void removePostSelectionListener(String partId,
ISelectionListener listener) {
selectionService.removePostSelectionListener(partId, listener);
}
/**
* This method is called when a part is activated by clicking within it. In
* response, the part, the pane, and all of its actions will be activated.
* <p>
* In the current design this method is invoked by the part pane when the
* pane, the part, or any children gain focus.
* </p>
* <p>
* If creating the part causes a forceFocus() well ignore this activation
* request.
* </p>
*/
public void requestActivation(IWorkbenchPart part) {
// Sanity check.
if (!certifyPart(part) || partBeingOpened) {
return;
}
if (part instanceof AbstractMultiEditor) {
part = ((AbstractMultiEditor) part).getActiveEditor();
}
// Real work.
}
/**
* Resets the layout for the perspective. The active part in the old layout
* is activated in the new layout for consistent user context.
*/
public void resetPerspective() {
}
/**
* Restore this page from the memento and ensure that the active perspective
* is equals the active descriptor otherwise create a new perspective for
* that descriptor. If activeDescriptor is null active the old perspective.
*/
public IStatus restoreState(IMemento memento,
final IPerspectiveDescriptor activeDescriptor) {
return Status.OK_STATUS;
}
/**
* See IWorkbenchPage
*/
public boolean saveAllEditors(boolean confirm) {
return saveAllEditors(confirm, false);
}
/**
* @param confirm
* @param addNonPartSources
* true if saveables from non-part sources should be saved too
* @return false if the user cancelled
*
*/
public boolean saveAllEditors(boolean confirm, boolean addNonPartSources) {
// TBD the code below is oversimplified. See 3.x version for all things
// that have to be done:
// return getEditorManager().saveAll(confirm, false, addNonPartSources);
ISaveablePart[] dirtyParts = getDirtyParts();
for (ISaveablePart part : dirtyParts) {
part.doSave(new NullProgressMonitor());
}
return true;
}
/*
* Saves the workbench part.
*/
protected boolean savePart(ISaveablePart saveable, IWorkbenchPart part,
boolean confirm) {
saveable.doSave(new NullProgressMonitor());
return true;
}
/**
* Saves an editors in the workbench. If <code>confirm</code> is
* <code>true</code> the user is prompted to confirm the command.
*
* @param confirm
* if user confirmation should be sought
* @return <code>true</code> if the command succeeded, or <code>false</code>
* if the user cancels the command
*/
public boolean saveEditor(IEditorPart editor, boolean confirm) {
return savePart(editor, editor, confirm);
}
/**
* Saves the current perspective.
*/
public void savePerspective() {
Perspective persp = getActivePerspective();
if (persp == null) {
return;
}
// Always unzoom.
if (isZoomed()) {
zoomOut();
}
persp.saveDesc();
}
/**
* Saves the perspective.
*/
public void savePerspectiveAs(IPerspectiveDescriptor newDesc) {
Perspective persp = getActivePerspective();
if (persp == null) {
return;
}
IPerspectiveDescriptor oldDesc = persp.getDesc();
// Always unzoom.
if (isZoomed()) {
zoomOut();
}
persp.saveDescAs(newDesc);
window.firePerspectiveSavedAs(this, oldDesc, newDesc);
}
/**
* Save the state of the page.
*/
public IStatus saveState(IMemento memento) {
// We must unzoom to get correct layout.
if (isZoomed()) {
zoomOut();
}
// Close any open Fast View
hideFastView();
MultiStatus result = new MultiStatus(
PlatformUI.PLUGIN_ID,
IStatus.OK,
NLS
.bind(
WorkbenchMessages.WorkbenchPage_unableToSavePerspective,
getLabel()), null);
// Save editor manager.
IMemento childMem = memento
.createChild(IWorkbenchConstants.TAG_EDITORS);
result.merge(editorMgr.saveState(childMem));
childMem = memento.createChild(IWorkbenchConstants.TAG_VIEWS);
result.merge(getViewFactory().saveState(childMem));
// Create persp block.
childMem = memento.createChild(IWorkbenchConstants.TAG_PERSPECTIVES);
if (getPerspective() != null) {
childMem.putString(IWorkbenchConstants.TAG_ACTIVE_PERSPECTIVE,
getPerspective().getId());
}
if (getActivePart() != null) {
if (getActivePart() instanceof IViewPart) {
IViewReference ref = (IViewReference) getReference(getActivePart());
if (ref != null) {
childMem.putString(IWorkbenchConstants.TAG_ACTIVE_PART,
ViewFactory.getKey(ref));
}
} else {
childMem.putString(IWorkbenchConstants.TAG_ACTIVE_PART,
getActivePart().getSite().getId());
}
}
// Save each perspective in opened order
Iterator itr = perspList.iterator();
while (itr.hasNext()) {
Perspective persp = (Perspective) itr.next();
IMemento gChildMem = childMem
.createChild(IWorkbenchConstants.TAG_PERSPECTIVE);
result.merge(persp.saveState(gChildMem));
}
// Save working set if set
if (workingSet != null) {
memento.putString(IWorkbenchConstants.TAG_WORKING_SET, workingSet
.getName());
}
IMemento workingSetMem = memento
.createChild(IWorkbenchConstants.TAG_WORKING_SETS);
for (int i = 0; i < workingSets.length; i++) {
workingSetMem.createChild(IWorkbenchConstants.TAG_WORKING_SET,
workingSets[i].getName());
}
if (aggregateWorkingSetId != null) {
memento.putString(ATT_AGGREGATE_WORKING_SET_ID,
aggregateWorkingSetId);
}
navigationHistory.saveState(memento
.createChild(IWorkbenchConstants.TAG_NAVIGATION_HISTORY));
// save the sticky activation state
stickyViewMan.save(memento);
return result;
}
/**
* See IWorkbenchPage.
*/
public void setEditorAreaVisible(boolean showEditorArea) {
Perspective persp = getActivePerspective();
if (persp == null) {
return;
}
if (showEditorArea == persp.isEditorAreaVisible()) {
return;
}
// If parts change always update zoom.
if (isZoomed()) {
zoomOut();
}
// Update editor area visibility.
if (showEditorArea) {
persp.showEditorArea();
window.firePerspectiveChanged(this, getPerspective(),
CHANGE_EDITOR_AREA_SHOW);
} else {
persp.hideEditorArea();
window.firePerspectiveChanged(this, getPerspective(),
CHANGE_EDITOR_AREA_HIDE);
}
}
/**
* Sets the layout of the page. Assumes the new perspective is not null.
* Keeps the active part if possible. Updates the window menubar and toolbar
* if necessary.
*/
private void setPerspective(Perspective newPersp) {
// Don't do anything if already active layout
Perspective oldPersp = getActivePerspective();
if (oldPersp == newPersp) {
return;
}
window.largeUpdateStart();
try {
if (oldPersp != null) {
// fire the pre-deactivate
window.firePerspectivePreDeactivate(this, oldPersp.getDesc());
}
if (newPersp != null) {
IStatus status = newPersp.restoreState();
if (status.getSeverity() != IStatus.OK) {
String title = WorkbenchMessages.WorkbenchPage_problemRestoringTitle;
String msg = WorkbenchMessages.WorkbenchPage_errorReadingState;
ErrorDialog.openError(getWorkbenchWindow().getShell(),
title, msg, status);
}
}
// Deactivate the old layout
if (oldPersp != null) {
oldPersp.onDeactivate();
// Notify listeners of deactivation
window.firePerspectiveDeactivated(this, oldPersp.getDesc());
}
// Activate the new layout
perspList.setActive(newPersp);
if (newPersp != null) {
newPersp.onActivate();
// Notify listeners of activation
window.firePerspectiveActivated(this, newPersp.getDesc());
}
// Update the window
window.updateActionSets();
// Update sticky views
stickyViewMan.update(oldPersp, newPersp);
} finally {
window.largeUpdateEnd();
if (newPersp == null) {
return;
}
IPerspectiveDescriptor desc = newPersp.getDesc();
if (desc == null) {
return;
}
if (dirtyPerspectives.remove(desc.getId())) {
suggestReset();
}
}
}
void perspectiveActionSetChanged(Perspective perspective,
IActionSetDescriptor descriptor, int changeType) {
if (perspective == getActivePerspective()) {
actionSets.change(descriptor, changeType);
}
}
/**
* Sets the perspective.
*
* @param desc
* identifies the new perspective.
*/
public void setPerspective(final IPerspectiveDescriptor desc) {
try {
Perspective oldPersp = getActivePerspective();
if ((oldPersp != null)
&& oldPersp.getDesc().getId() == desc.getId())
return;
Perspective newPersp = findPerspective(desc);
if (newPersp == null) {
newPersp = new Perspective((PerspectiveDescriptor) desc, this);
perspList.add(newPersp);
}
// TBD firePerspectivePreDeactivate
if (oldPersp != null) {
// TBD: exceptions due to null presentations
// oldPersp.onDeactivate();
// TBD firePerspectiveDeactivated
}
// Activate the new layout
perspList.setActive(newPersp);
// also need to let E4 know
MPerspective e4perspective = findPerspectiveE4(e4Window, desc
.getId());
if (e4perspective != null
&& e4perspective.getParent().getActiveChild() != e4perspective)
e4perspective.getParent().setActiveChild(e4perspective);
if (newPersp != null) {
// TBD exceptions due to null presentations
// newPersp.onActivate();
// TBD firePerspectiveActivated(this, newPersp.getDesc());
}
} catch (WorkbenchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Allow access to the part service for this page ... used internally to
* propogate certain types of events to the page part listeners.
*
* @return the part service for this page.
*/
public PartService getPartService() {
return (PartService) partList.getPartService();
}
/**
* Restore the toolbar layout for the active perspective.
*/
protected void resetToolBarLayout() {
ICoolBarManager2 mgr = (ICoolBarManager2) window.getCoolBarManager2();
mgr.resetItemOrder();
}
/**
* Sets the active working set for the workbench page. Notifies property
* change listener about the change.
*
* @param newWorkingSet
* the active working set for the page. May be null.
* @since 2.0
* @deprecated individual views should store a working set if needed
*/
public void setWorkingSet(IWorkingSet newWorkingSet) {
IWorkingSet oldWorkingSet = workingSet;
workingSet = newWorkingSet;
if (oldWorkingSet != newWorkingSet) {
firePropertyChange(CHANGE_WORKING_SET_REPLACE, oldWorkingSet,
newWorkingSet);
}
if (newWorkingSet != null) {
WorkbenchPlugin
.getDefault()
.getWorkingSetManager()
.addPropertyChangeListener(workingSetPropertyChangeListener);
} else {
WorkbenchPlugin.getDefault().getWorkingSetManager()
.removePropertyChangeListener(
workingSetPropertyChangeListener);
}
}
/**
* @see IWorkbenchPage
*/
public void showActionSet(String actionSetID) {
Perspective persp = getActivePerspective();
if (persp != null) {
ActionSetRegistry reg = WorkbenchPlugin.getDefault()
.getActionSetRegistry();
IActionSetDescriptor desc = reg.findActionSet(actionSetID);
if (desc != null) {
persp.addActionSet(desc);
window.updateActionSets();
window.firePerspectiveChanged(this, getPerspective(),
CHANGE_ACTION_SET_SHOW);
}
}
}
/**
* See IWorkbenchPage.
*/
public IViewPart showView(String viewID) throws PartInitException {
return showView(viewID, null, VIEW_ACTIVATE);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchPage#showView(java.lang.String,
* java.lang.String, int)
*/
public IViewPart showView(final String viewID, final String secondaryID,
final int mode) throws PartInitException {
if (secondaryID != null) {
if (secondaryID.length() == 0
|| secondaryID.indexOf(ViewFactory.ID_SEP) != -1) {
throw new IllegalArgumentException(
WorkbenchMessages.WorkbenchPage_IllegalSecondaryId);
}
}
if (!certifyMode(mode)) {
throw new IllegalArgumentException(
WorkbenchMessages.WorkbenchPage_IllegalViewMode);
}
// Run op in busy cursor.
final Object[] result = new Object[1];
BusyIndicator.showWhile(null, new Runnable() {
public void run() {
try {
result[0] = busyShowView(viewID, secondaryID, mode);
} catch (PartInitException e) {
result[0] = e;
}
}
});
if (result[0] instanceof IViewPart) {
return (IViewPart) result[0];
} else if (result[0] instanceof PartInitException) {
throw (PartInitException) result[0];
} else {
throw new PartInitException(
WorkbenchMessages.WorkbenchPage_AbnormalWorkbenchCondition);
}
}
/**
* @param mode
* the mode to test
* @return whether the mode is recognized
* @since 3.0
*/
private boolean certifyMode(int mode) {
switch (mode) {
case VIEW_ACTIVATE:
case VIEW_VISIBLE:
case VIEW_CREATE:
return true;
default:
return false;
}
}
/**
* Hides the active fast view. Has no effect if there is no fast view
* active.
*/
public void hideFastView() {
Perspective persp = getActivePerspective();
if (persp != null) {
IViewReference ref = persp.getActiveFastView();
if (ref != null) {
toggleFastView(ref);
}
}
}
/**
* Toggles the visibility of a fast view. If the view is active it is
* deactivated. Otherwise, it is activated.
*/
public void toggleFastView(IViewReference ref) {
}
/**
* Sets the state of the given part.
*
* @param ref
* part whose state should be modified (not null)
* @param newState
* one of the IStackPresentationSite.STATE_* constants
*/
public void setState(IWorkbenchPartReference ref, int newState) {
Perspective persp = getActivePerspective();
if (persp == null) {
return;
}
PartPane pane = ((WorkbenchPartReference) ref).getPane();
// If target part is detached fire the zoom event. Note this doesn't
// actually cause any changes in size and is required to support
// intro state changes. We may want to introduce the notion of a zoomed
// (fullscreen) detached view at a later time.
if (!pane.isDocked()) {
pane.setZoomed(newState == IStackPresentationSite.STATE_MAXIMIZED);
return;
}
if (ref instanceof IViewReference
&& persp.isFastView((IViewReference) ref)) {
persp.setFastViewState(newState);
return;
}
if (Perspective.useNewMinMax(persp)) {
// set the container's state to the new one
PartStack parent = ((PartStack) pane.getContainer());
parent.setState(newState);
return;
}
boolean wasZoomed = isZoomed();
boolean isZoomed = newState == IStackPresentationSite.STATE_MAXIMIZED;
// Update zoom status.
if (wasZoomed && !isZoomed) {
zoomOut();
} else if (!wasZoomed && isZoomed) {
persp.getPresentation().zoomIn(ref);
activate(ref.getPart(true));
}
PartStack parent = ((PartStack) pane.getContainer());
if (parent != null) {
parent
.setMinimized(newState == IStackPresentationSite.STATE_MINIMIZED);
}
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.ui.IWorkbenchPage#setPartState(org.eclipse.ui.
* IWorkbenchPartReference, int)
*/
public void setPartState(IWorkbenchPartReference ref, int state) {
setState(ref, state);
}
/**
* Returns the maximized/minimized/restored state of the given part
* reference
*
* @param ref
* part to query (not null)
* @return one of the IStackPresentationSite.STATE_* constants
*/
int getState(IWorkbenchPartReference ref) {
Perspective persp = getActivePerspective();
if (persp == null) {
return IStackPresentationSite.STATE_RESTORED;
}
// TBD concept not yet implemented in E4
if (!(ref instanceof WorkbenchPartReference))
return IStackPresentationSite.STATE_RESTORED;
PartPane pane = ((WorkbenchPartReference) ref).getPane();
if (ref instanceof IViewReference
&& persp.isFastView((IViewReference) ref)) {
return persp.getFastViewState();
}
PartStack parent = ((PartStack) pane.getContainer());
if (parent != null) {
return parent.getState();
}
return IStackPresentationSite.STATE_RESTORED;
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.ui.IWorkbenchPage#getPartState(org.eclipse.ui.
* IWorkbenchPartReference)
*/
public int getPartState(IWorkbenchPartReference ref) {
return getState(ref);
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.ui.IWorkbenchPage#toggleZoom(org.eclipse.ui.
* IWorkbenchPartReference)
*/
public void toggleZoom(IWorkbenchPartReference ref) {
int oldState = getState(ref);
boolean shouldZoom = oldState != IStackPresentationSite.STATE_MAXIMIZED;
int newState = shouldZoom ? IStackPresentationSite.STATE_MAXIMIZED
: IStackPresentationSite.STATE_RESTORED;
setState(ref, newState);
}
/**
* updateActionBars method comment.
*/
public void updateActionBars() {
window.updateActionBars();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchPage#zoomOut()
*/
public void zoomOut() {
Perspective persp = getActivePerspective();
if (persp != null) {
persp.getPresentation().zoomOut();
}
}
/**
* Zooms out a zoomed in part if it is necessary to do so for the user to
* view the IWorkbenchPart that is the argument. Otherwise, does nothing.
*
* @param part
* the part to be made viewable
*/
private void zoomOutIfNecessary(IWorkbenchPart part) {
if (isZoomed()
&& partChangeAffectsZoom(((PartSite) part.getSite())
.getPartReference())) {
zoomOut();
}
}
/**
*
*/
public int getEditorReuseThreshold() {
return ((TabBehaviour) Tweaklets.get(TabBehaviour.KEY))
.getEditorReuseThreshold();
}
/**
*
*/
public void setEditorReuseThreshold(int openEditors) {
}
/*
* Returns the editors in activation order (oldest first).
*/
public IEditorReference[] getSortedEditors() {
return getEditorReferences();
}
/**
* @see IWorkbenchPage#getOpenPerspectives()
*/
public IPerspectiveDescriptor[] getOpenPerspectives() {
Perspective opened[] = perspList.getOpenedPerspectives();
IPerspectiveDescriptor[] result = new IPerspectiveDescriptor[opened.length];
for (int i = 0; i < result.length; i++) {
result[i] = opened[i].getDesc();
}
return result;
}
/**
* Return all open Perspective objects.
*
* @return all open Perspective objects
* @since 3.1
*/
/* package */Perspective[] getOpenInternalPerspectives() {
return perspList.getOpenedPerspectives();
}
/**
* Checks perspectives in the order they were activiated for the specfied
* part. The first sorted perspective that contains the specified part is
* returned.
*
* @param part
* specified part to search for
* @return the first sorted perspespective containing the part
* @since 3.1
*/
/* package */Perspective getFirstPerspectiveWithView(IViewPart part) {
Perspective[] perspectives = perspList.getSortedPerspectives();
for (int i = perspectives.length - 1; i >= 0; i--) {
if (perspectives[i].containsView(part)) {
return perspectives[i];
}
}
// we should never get here
return null;
}
/**
* Returns the perspectives in activation order (oldest first).
*/
public IPerspectiveDescriptor[] getSortedPerspectives() {
Perspective sortedArray[] = perspList.getSortedPerspectives();
IPerspectiveDescriptor[] result = new IPerspectiveDescriptor[sortedArray.length];
for (int i = 0; i < result.length; i++) {
result[i] = sortedArray[i].getDesc();
}
return result;
}
/*
* Returns the parts in activation order (oldest first).
*/
public IWorkbenchPartReference[] getSortedParts() {
return new IWorkbenchPartReference[0];
}
/**
* Returns the reference to the given part, or <code>null</code> if it has
* no reference (i.e. it is not a top-level part in this workbench page).
*
* @param part
* the part
* @return the part's reference or <code>null</code> if the given part does
* not belong to this workbench page
*/
public IWorkbenchPartReference getReference(IWorkbenchPart part) {
if (part == null) {
return null;
}
IWorkbenchPartSite site = part.getSite();
if (!(site instanceof PartSite)) {
return null;
}
PartSite partSite = ((PartSite) site);
PartPane pane = partSite.getPane();
if (pane instanceof MultiEditorInnerPane) {
MultiEditorInnerPane innerPane = (MultiEditorInnerPane) pane;
return innerPane.getParentPane().getPartReference();
}
return partSite.getPartReference();
}
/**
* Helper class to keep track of all opened perspective. Both the opened and
* used order is kept.
*/
private class PerspectiveList {
/**
* List of perspectives in the order they were opened;
*/
private List openedList;
/**
* List of perspectives in the order they were used. Last element is the
* most recently used, and first element is the least recently used.
*/
private List usedList;
/**
* The perspective explicitly set as being the active one
*/
private Perspective active;
/**
* Creates an empty instance of the perspective list
*/
public PerspectiveList() {
openedList = new ArrayList();
usedList = new ArrayList();
}
/**
* Return all perspectives in the order they were activated.
*
* @return an array of perspectives sorted by activation order, least
* recently activated perspective last.
*/
public Perspective[] getSortedPerspectives() {
Perspective[] result = new Perspective[usedList.size()];
return (Perspective[]) usedList.toArray(result);
}
/**
* Adds a perspective to the list. No check is done for a duplicate when
* adding.
*
* @param perspective
* the perspective to add
* @return boolean <code>true</code> if the perspective was added
*/
public boolean add(Perspective perspective) {
openedList.add(perspective);
usedList.add(0, perspective);
// It will be moved to top only when activated.
return true;
}
/**
* Returns an iterator on the perspective list in the order they were
* opened.
*/
public Iterator iterator() {
return openedList.iterator();
}
/**
* Returns an array with all opened perspectives
*/
public Perspective[] getOpenedPerspectives() {
Perspective[] result = new Perspective[openedList.size()];
return (Perspective[]) openedList.toArray(result);
}
/**
* Returns whether the list contains any perspectives
*/
public boolean isEmpty() {
return openedList.isEmpty();
}
/**
* Returns the most recently used perspective in the list.
*/
public Perspective getActive() {
return active;
}
/**
* Marks the specified perspective as the most recently used one in the
* list.
*/
public void setActive(Perspective perspective) {
if (perspective == active) {
return;
}
updateActionSets(active, perspective);
active = perspective;
if (perspective != null) {
usedList.remove(perspective);
usedList.add(perspective);
}
}
private void updateActionSets(Perspective oldPersp, Perspective newPersp) {
// Update action sets
IContextService service = (IContextService) window
.getService(IContextService.class);
try {
service.deferUpdates(true);
if (newPersp != null) {
IActionSetDescriptor[] newAlwaysOn = newPersp
.getAlwaysOnActionSets();
for (int i = 0; i < newAlwaysOn.length; i++) {
IActionSetDescriptor descriptor = newAlwaysOn[i];
actionSets.showAction(descriptor);
}
IActionSetDescriptor[] newAlwaysOff = newPersp
.getAlwaysOffActionSets();
for (int i = 0; i < newAlwaysOff.length; i++) {
IActionSetDescriptor descriptor = newAlwaysOff[i];
actionSets.maskAction(descriptor);
}
}
if (oldPersp != null) {
IActionSetDescriptor[] newAlwaysOn = oldPersp
.getAlwaysOnActionSets();
for (int i = 0; i < newAlwaysOn.length; i++) {
IActionSetDescriptor descriptor = newAlwaysOn[i];
actionSets.hideAction(descriptor);
}
IActionSetDescriptor[] newAlwaysOff = oldPersp
.getAlwaysOffActionSets();
for (int i = 0; i < newAlwaysOff.length; i++) {
IActionSetDescriptor descriptor = newAlwaysOff[i];
actionSets.unmaskAction(descriptor);
}
}
} finally {
service.deferUpdates(false);
}
}
}
// for dynamic UI
protected void addPerspective(Perspective persp) {
perspList.add(persp);
window.firePerspectiveOpened(this, persp.getDesc());
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchPage#getViewStack(org.eclipse.ui.IViewPart)
*/
public IViewPart[] getViewStack(IViewPart part) {
// check to make sure this part is in the current perspective
MPart modelPart = findPartInCurrentPerspective(part.getSite().getId());
if (modelPart == null) {
// if not, return null
return null;
}
List<IViewPart> stack = new ArrayList<IViewPart>();
// retrieve the parent stack
MElementContainer<MUIElement> viewStack = modelPart.getParent();
// get the contents of the stack
for (MUIElement child : viewStack.getChildren()) {
if (child instanceof MContribution) {
Object object = ((MContribution) child).getObject();
// queue it up if it's a view
if (object instanceof IViewPart) {
stack.add((IViewPart) object);
}
}
}
return stack.toArray(new IViewPart[stack.size()]);
}
/**
* Allow for programmatically resizing a part.
* <p>
* <em>EXPERIMENTAL</em>
* </p>
* <p>
* Known limitations:
* <ul>
* <li>currently applies only to views</li>
* <li>has no effect when view is zoomed</li>
* </ul>
*/
public void resizeView(IViewPart part, int width, int height) {
SashInfo sashInfo = new SashInfo();
PartPane pane = ((PartSite) part.getSite()).getPane();
ILayoutContainer container = pane.getContainer();
LayoutTree tree = getPerspectivePresentation().getLayout().root
.find(((ViewStack) container));
// retrieve our layout sashes from the layout tree
findSashParts(tree, pane.findSashes(), sashInfo);
// first set the width
float deltaWidth = width - pane.getBounds().width;
if (sashInfo.right != null) {
Rectangle rightBounds = sashInfo.rightNode.getBounds();
// set the new ratio
sashInfo.right
.setRatio(((deltaWidth + sashInfo.right.getBounds().x) - rightBounds.x)
/ rightBounds.width);
// complete the resize
sashInfo.rightNode.setBounds(rightBounds);
} else if (sashInfo.left != null) {
Rectangle leftBounds = sashInfo.leftNode.getBounds();
// set the ratio
sashInfo.left
.setRatio(((sashInfo.left.getBounds().x - deltaWidth) - leftBounds.x)
/ leftBounds.width);
// complete the resize
sashInfo.leftNode.setBounds(sashInfo.leftNode.getBounds());
}
// next set the height
float deltaHeight = height - pane.getBounds().height;
if (sashInfo.bottom != null) {
Rectangle bottomBounds = sashInfo.bottomNode.getBounds();
// set the new ratio
sashInfo.bottom.setRatio(((deltaHeight + sashInfo.bottom
.getBounds().y) - bottomBounds.y)
/ bottomBounds.height);
// complete the resize
sashInfo.bottomNode.setBounds(bottomBounds);
} else if (sashInfo.top != null) {
Rectangle topBounds = sashInfo.topNode.getBounds();
// set the ratio
sashInfo.top
.setRatio(((sashInfo.top.getBounds().y - deltaHeight) - topBounds.y)
/ topBounds.height);
// complete the resize
sashInfo.topNode.setBounds(topBounds);
}
}
// provides sash information for the given pane
private class SashInfo {
private LayoutPartSash right;
private LayoutPartSash left;
private LayoutPartSash top;
private LayoutPartSash bottom;
private LayoutTreeNode rightNode;
private LayoutTreeNode leftNode;
private LayoutTreeNode topNode;
private LayoutTreeNode bottomNode;
}
private void findSashParts(LayoutTree tree, PartPane.Sashes sashes,
SashInfo info) {
LayoutTree parent = tree.getParent();
if (parent == null) {
return;
}
if (parent.part instanceof LayoutPartSash) {
// get the layout part sash from this tree node
LayoutPartSash sash = (LayoutPartSash) parent.part;
// make sure it has a sash control
Control control = sash.getControl();
if (control != null) {
// check for a vertical sash
if (sash.isVertical()) {
if (sashes.left == control) {
info.left = sash;
info.leftNode = parent.findSash(sash);
} else if (sashes.right == control) {
info.right = sash;
info.rightNode = parent.findSash(sash);
}
}
// check for a horizontal sash
else {
if (sashes.top == control) {
info.top = sash;
info.topNode = parent.findSash(sash);
} else if (sashes.bottom == control) {
info.bottom = sash;
info.bottomNode = parent.findSash(sash);
}
}
}
}
// recursive call to continue up the tree
findSashParts(parent, sashes, info);
}
/**
* Returns all parts that are owned by this page
*
* @return all open parts, including non-participating editors.
*/
IWorkbenchPartReference[] getAllParts() {
ArrayList<IWorkbenchPartReference> result = new ArrayList<IWorkbenchPartReference>();
getContainedPartRefs(result, e4Window);
IWorkbenchPartReference[] typedResult = new IWorkbenchPartReference[result
.size()];
result.toArray(typedResult);
return typedResult;
}
// TBD this code repeats multiple times in variations (get editors, get
// views, get parts). When typically callers filter them some more (isDirty,
// isVisble, etc.).
// This needs to be a generic utility
private void getContainedPartRefs(
ArrayList<IWorkbenchPartReference> result,
MElementContainer<?> container) {
for (MUIElement child : container.getChildren()) {
if (child instanceof MPart) {
MPart contributedChild = (MPart) child;
if (contributedChild.isVisible()) {
Object object = contributedChild.getObject();
if (object instanceof IWorkbenchPart)
result.add(new ModelReference(contributedChild, this));
}
}
if (child instanceof MElementContainer<?>)
getContainedPartRefs(result, (MElementContainer<?>) child);
}
}
/**
* Returns all open parts that are owned by this page (that is, all parts
* for which a part opened event would have been sent -- these would be
* activated parts whose controls have already been created.
*/
IWorkbenchPartReference[] getOpenParts() {
IWorkbenchPartReference[] refs = getAllParts();
List result = new ArrayList();
for (int i = 0; i < refs.length; i++) {
IWorkbenchPartReference reference = refs[i];
IWorkbenchPart part = reference.getPart(false);
if (part != null) {
result.add(reference);
}
}
return (IWorkbenchPartReference[]) result
.toArray(new IWorkbenchPartReference[result.size()]);
}
/**
* Sanity-checks the objects in this page. Throws an Assertation exception
* if an object's internal state is invalid. ONLY INTENDED FOR USE IN THE UI
* TEST SUITES.
*/
public void testInvariants() {
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchPage#getExtensionTracker()
*/
public IExtensionTracker getExtensionTracker() {
if (tracker == null) {
tracker = new UIExtensionTracker(getWorkbenchWindow()
.getWorkbench().getDisplay());
}
return tracker;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchPage#getNewWizardShortcuts()
*/
public String[] getNewWizardShortcuts() {
Perspective persp = getActivePerspective();
if (persp == null) {
return new String[0];
}
return persp.getNewWizardShortcuts();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchPage#getPerspectiveShortcuts()
*/
public String[] getPerspectiveShortcuts() {
Perspective persp = getActivePerspective();
if (persp == null) {
return new String[0];
}
return persp.getPerspectiveShortcuts();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchPage#getShowViewShortcuts()
*/
public String[] getShowViewShortcuts() {
Perspective persp = getActivePerspective();
if (persp == null) {
return new String[0];
}
return persp.getShowViewShortcuts();
}
/**
* @since 3.1
*/
private void suggestReset() {
final IWorkbench workbench = getWorkbenchWindow().getWorkbench();
workbench.getDisplay().asyncExec(new Runnable() {
public void run() {
Shell parentShell = null;
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
if (window == null) {
if (workbench.getWorkbenchWindowCount() == 0) {
return;
}
window = workbench.getWorkbenchWindows()[0];
}
parentShell = window.getShell();
if (MessageDialog.openQuestion(parentShell,
WorkbenchMessages.Dynamic_resetPerspectiveTitle,
WorkbenchMessages.Dynamic_resetPerspectiveMessage)) {
IWorkbenchPage page = window.getActivePage();
if (page == null) {
return;
}
page.resetPerspective();
}
}
});
}
public boolean isPartVisible(IWorkbenchPartReference reference) {
IWorkbenchPart part = reference.getPart(false);
// Can't be visible if it isn't created yet
if (part == null) {
return false;
}
return isPartVisible(part);
}
public IWorkingSet[] getWorkingSets() {
return workingSets;
}
public void setWorkingSets(IWorkingSet[] newWorkingSets) {
if (newWorkingSets != null) {
WorkbenchPlugin
.getDefault()
.getWorkingSetManager()
.addPropertyChangeListener(workingSetPropertyChangeListener);
} else {
WorkbenchPlugin.getDefault().getWorkingSetManager()
.removePropertyChangeListener(
workingSetPropertyChangeListener);
}
if (newWorkingSets == null) {
newWorkingSets = new IWorkingSet[0];
}
IWorkingSet[] oldWorkingSets = workingSets;
// filter out any duplicates if necessary
if (newWorkingSets.length > 1) {
Set setOfSets = new HashSet();
for (int i = 0; i < newWorkingSets.length; i++) {
if (newWorkingSets[i] == null) {
throw new IllegalArgumentException();
}
setOfSets.add(newWorkingSets[i]);
}
newWorkingSets = (IWorkingSet[]) setOfSets
.toArray(new IWorkingSet[setOfSets.size()]);
}
workingSets = newWorkingSets;
if (!Arrays.equals(oldWorkingSets, newWorkingSets)) {
firePropertyChange(CHANGE_WORKING_SETS_REPLACE, oldWorkingSets,
newWorkingSets);
if (aggregateWorkingSet != null) {
aggregateWorkingSet.setComponents(workingSets);
}
}
}
public IWorkingSet getAggregateWorkingSet() {
if (aggregateWorkingSet == null) {
IWorkingSetManager workingSetManager = PlatformUI.getWorkbench()
.getWorkingSetManager();
aggregateWorkingSet = (AggregateWorkingSet) workingSetManager
.getWorkingSet(getAggregateWorkingSetId());
if (aggregateWorkingSet == null) {
aggregateWorkingSet = (AggregateWorkingSet) workingSetManager
.createAggregateWorkingSet(
getAggregateWorkingSetId(),
WorkbenchMessages.WorkbenchPage_workingSet_default_label,
getWorkingSets());
workingSetManager.addWorkingSet(aggregateWorkingSet);
}
}
return aggregateWorkingSet;
}
private String getAggregateWorkingSetId() {
if (aggregateWorkingSetId == null) {
aggregateWorkingSetId = "Aggregate for window " + System.currentTimeMillis(); //$NON-NLS-1$
}
return aggregateWorkingSetId;
}
public void showEditor(IEditorReference ref) {
}
public void hideEditor(IEditorReference ref) {
// partList.removePart((WorkbenchPartReference)ref);
}
public IEditorReference[] openEditors(final IEditorInput[] inputs,
final String[] editorIDs, final int matchFlags)
throws MultiPartInitException {
if (inputs == null)
throw new IllegalArgumentException();
if (editorIDs == null)
throw new IllegalArgumentException();
if (inputs.length != editorIDs.length)
throw new IllegalArgumentException();
ArrayList refs = new ArrayList();
for (int i = 0; i < inputs.length; i++) {
IEditorPart ed = null;
try {
// brute force approach
ed = openEditor(inputs[i], editorIDs[i], true, matchFlags);
} catch (PartInitException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (ed != null) {
refs.add(((PartSite) ed.getSite()).getPartReference());
}
}
return (IEditorReference[]) refs.toArray(new IEditorReference[refs
.size()]);
}
public void resetHiddenEditors() {
IEditorReference[] refs = (IEditorReference[]) removedEditors
.toArray(new IEditorReference[removedEditors.size()]);
for (int i = 0; i < refs.length; i++) {
showEditor(refs[i]);
}
}
public MWindow getModelWindow() {
return e4Window;
}
// TBD this code repeats multiple times in variations (get editors, get
// views, get parts). When typically callers filter them some more (isDirty,
// isVisble, etc.).
// This needs to be a generic utility
private MPerspective findPerspectiveE4(MWindow e4Window, String id) {
MUIElement pe = ModeledPageLayout.findElementById(e4Window, id);
if (pe instanceof MPerspective)
return (MPerspective) pe;
return null;
}
}