Bug 329457 [compatibility] Editors do not get reused
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorReference.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorReference.java index f5b3578..368a208 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorReference.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorReference.java
@@ -236,16 +236,6 @@ /* * (non-Javadoc) * - * @see org.eclipse.ui.IEditorReference#isPinned() - */ - public boolean isPinned() { - // FIXME compat implement pinning - return false; - } - - /* - * (non-Javadoc) - * * @see org.eclipse.ui.IEditorReference#getEditorInput() */ public IEditorInput getEditorInput() throws PartInitException {
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java index a24f782..1de70d7 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java
@@ -130,6 +130,8 @@ import org.eclipse.ui.internal.registry.PerspectiveDescriptor; import org.eclipse.ui.internal.registry.UIExtensionTracker; import org.eclipse.ui.internal.registry.ViewDescriptor; +import org.eclipse.ui.internal.tweaklets.TabBehaviour; +import org.eclipse.ui.internal.tweaklets.Tweaklets; import org.eclipse.ui.internal.util.Util; import org.eclipse.ui.model.IWorkbenchAdapter; import org.eclipse.ui.part.IShowInSource; @@ -2019,40 +2021,63 @@ List<EditorReference> references = getCurrentEditorReferences(); return references.toArray(new IEditorReference[references.size()]); } + + public IEditorReference[] getSortedEditors() { + IWorkbenchPartReference[] parts = getSortedParts(true, false); + IEditorReference[] editors = new IEditorReference[parts.length]; + System.arraycopy(parts, 0, editors, 0, parts.length); + return editors; + } public IWorkbenchPartReference[] getSortedParts() { + return getSortedParts(true, true); + } + + private IWorkbenchPartReference[] getSortedParts(boolean editors, boolean views) { + if (!editors && !views) { + return new IWorkbenchPartReference[0]; + } + List<IWorkbenchPartReference> sortedReferences = new ArrayList<IWorkbenchPartReference>(); IViewReference[] viewReferences = getViewReferences(); List<EditorReference> editorReferences = getCurrentEditorReferences(); activationLoop: for (MPart part : activationList) { + if (views) { + for (IViewReference ref : viewReferences) { + if (((ViewReference) ref).getModel() == part) { + sortedReferences.add(ref); + continue activationLoop; + } + } + } + + if (editors) { + for (EditorReference ref : editorReferences) { + if (ref.getModel() == part) { + sortedReferences.add(ref); + break; + } + } + } + } + + if (views) { for (IViewReference ref : viewReferences) { - if (((ViewReference) ref).getModel() == part) { + if (!sortedReferences.contains(ref)) { sortedReferences.add(ref); - continue activationLoop; } } + } + if (editors) { for (EditorReference ref : editorReferences) { - if (ref.getModel() == part) { + if (!sortedReferences.contains(ref)) { sortedReferences.add(ref); - break; } } } - for (IViewReference ref : viewReferences) { - if (!sortedReferences.contains(ref)) { - sortedReferences.add(ref); - } - } - - for (EditorReference ref : editorReferences) { - if (!sortedReferences.contains(ref)) { - sortedReferences.add(ref); - } - } - return sortedReferences.toArray(new IWorkbenchPartReference[sortedReferences.size()]); } @@ -2669,6 +2694,31 @@ recordEditor(input, descriptor); return editor; + } else if (descriptor.isInternal()) { + // look for an editor to reuse + EditorReference reusableEditorRef = (EditorReference) ((TabBehaviour) Tweaklets + .get(TabBehaviour.KEY)).findReusableEditor(this); + if (reusableEditorRef != null) { + IEditorPart reusableEditor = reusableEditorRef.getEditor(false); + if (editorId.equals(reusableEditorRef.getId()) + && reusableEditor instanceof IReusableEditor) { + // reusable editors that share the same id are okay + recordEditor(input, descriptor); + reuseEditor((IReusableEditor) reusableEditor, input); + + MPart editor = reusableEditorRef.getModel(); + partService.showPart(editor, PartState.VISIBLE); + if (activate) { + partService.activate(editor); + } else { + updateActiveEditorSources(editor); + } + return reusableEditor; + } + // should have saved already if necessary, close this editor, a + // new one will be opened + closeEditor(reusableEditorRef, false); + } } else if (descriptor.isOpenExternal()) { openExternalEditor(descriptor, input); // no editor parts for external editors, return null
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/tweaklets/TabBehaviourMRU.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/tweaklets/TabBehaviourMRU.java index 0897ddb..13bf68a 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/tweaklets/TabBehaviourMRU.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/tweaklets/TabBehaviourMRU.java
@@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 IBM Corporation and others. + * Copyright (c) 2007, 2011 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 @@ -11,9 +11,18 @@ package org.eclipse.ui.internal.tweaklets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorReference; import org.eclipse.ui.internal.IPreferenceConstants; +import org.eclipse.ui.internal.WorkbenchMessages; import org.eclipse.ui.internal.WorkbenchPage; import org.eclipse.ui.internal.WorkbenchPlugin; import org.eclipse.ui.internal.e4.compatibility.E4Util; @@ -35,7 +44,90 @@ if (!reuse) { return null; } - return null; + + IEditorReference editors[] = page.getSortedEditors(); + int length = editors.length; + if (length < page.getEditorReuseThreshold()) { + return null; + } else if (length > page.getEditorReuseThreshold()) { + List<IEditorReference> refs = new ArrayList<IEditorReference>(); + List<IEditorReference> keep = new ArrayList<IEditorReference>(Arrays.asList(editors)); + int extra = length - page.getEditorReuseThreshold(); + // look for extra editors that should be closed + for (int i = 0; i < editors.length; i++) { + if (extra == 0) { + break; + } + + if (editors[i].isPinned() || editors[i].isDirty()) { + continue; + } + + refs.add(editors[i]); + extra--; + } + + for (IEditorReference ref : refs) { + page.closeEditor(ref, false); + keep.remove(ref); + } + + editors = keep.toArray(new IEditorReference[keep.size()]); + } + + IEditorReference dirtyEditor = null; + + // find an editor to reuse, go in reverse due to activation order + for (int i = editors.length - 1; i > -1; i--) { + IEditorReference editor = editors[i]; + if (editor.isPinned()) { + // skip pinned editors + continue; + } + if (editor.isDirty()) { + // record dirty editors + if (dirtyEditor == null) { + dirtyEditor = editor; + } + continue; + } + // an editor is neither pinned nor dirty, use this one + return editor; + } + // can't find anything, return null + if (dirtyEditor == null) { + return null; + } + + /* fix for 11122 */ + boolean reuseDirty = WorkbenchPlugin.getDefault().getPreferenceStore() + .getBoolean(IPreferenceConstants.REUSE_DIRTY_EDITORS); + if (!reuseDirty) { + return null; + } + + MessageDialog dialog = new MessageDialog( + page.getWorkbenchWindow().getShell(), + WorkbenchMessages.EditorManager_reuseEditorDialogTitle, + null, // accept the default window icon + NLS.bind(WorkbenchMessages.EditorManager_saveChangesQuestion, dirtyEditor.getName()), + MessageDialog.QUESTION, new String[] { IDialogConstants.YES_LABEL, + IDialogConstants.NO_LABEL, + WorkbenchMessages.EditorManager_openNewEditorLabel }, 0) { + protected int getShellStyle() { + return super.getShellStyle() | SWT.SHEET; + } + }; + int result = dialog.open(); + if (result == 0) { // YES + IEditorPart editor = dirtyEditor.getEditor(true); + if (!page.saveEditor(editor, false)) { + return null; + } + } else if ((result == 2) || (result == -1)) { + return null; + } + return dirtyEditor; } public IEditorReference reuseInternalEditor(WorkbenchPage page,