| /******************************************************************************* |
| * 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; |
| } |
| } |