diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/CloseEditorHandler.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/CloseEditorHandler.java index b3acfd81940..11894454d03 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/CloseEditorHandler.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/CloseEditorHandler.java @@ -14,16 +14,21 @@ package org.eclipse.ui.internal; +import java.util.List; +import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.expressions.EvaluationResult; -import org.eclipse.core.expressions.Expression; -import org.eclipse.core.expressions.ExpressionInfo; -import org.eclipse.core.expressions.IEvaluationContext; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.workbench.IWorkbench; +import org.eclipse.e4.ui.workbench.modeling.EPartService; import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.ISources; +import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.handlers.HandlerUtil; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; /** * Closes the active editor. @@ -33,43 +38,53 @@ * * @since 3.3 */ -public class CloseEditorHandler extends AbstractEvaluationHandler { - - private Expression enabledWhen; - - public CloseEditorHandler() { - registerEnablement(); - } +public class CloseEditorHandler extends AbstractHandler { @Override public Object execute(ExecutionEvent event) throws ExecutionException { - IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event); - IEditorPart part = HandlerUtil.getActiveEditorChecked(event); - window.getActivePage().closeEditor(part, true); - return null; - } - - @Override - protected Expression getEnabledWhenExpression() { - if (enabledWhen == null) { - enabledWhen = new Expression() { - @Override - public EvaluationResult evaluate(IEvaluationContext context) { - IEditorPart part = InternalHandlerUtil.getActiveEditor(context); - if (part != null) { - return EvaluationResult.TRUE; + IWorkbenchPart activePart = HandlerUtil.getActivePart(event); + if (activePart instanceof IEditorPart) { + IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event); + window.getActivePage().closeEditor((IEditorPart) activePart, true); + } else { + // we may have an E4PartWrapper for a part which has been contributed eg. via a + // PartDescriptor in a model fragment, and which has been tagged as + // representing an Editor + if (activePart instanceof E4PartWrapper) { + // derive the IEclipseContext & EPartService + BundleContext context = FrameworkUtil.getBundle(IWorkbench.class).getBundleContext(); + ServiceReference reference = context.getServiceReference(IWorkbench.class); + IEclipseContext eclipseContext = context.getService(reference).getApplication().getContext(); + EPartService partService = eclipseContext.get(EPartService.class); + // access the wrapped part => save & close it + MPart wrappedPart = ((E4PartWrapper) activePart).wrappedPart; + if (wrappedPart != null && partService != null) { + // ensure the active part does indeed represent an editor + // (and not eg. a view) - checking here is just for extra + // redundancy + if (representsEditor(wrappedPart)) { + if (partService.savePart(wrappedPart, true)) { + partService.hidePart(wrappedPart); + } } - return EvaluationResult.FALSE; } - - @Override - public void collectExpressionInfo(ExpressionInfo info) { - info.addVariableNameAccess(ISources.ACTIVE_EDITOR_NAME); - } - }; + } } - return enabledWhen; + + return null; + } + + /** + * Checks whether the specified part represents an editor instance. + * + * @param part the part to query + * @return true if the specified part represents an editor, false otherwise + */ + private boolean representsEditor(MPart part) { + List partTags = part.getTags(); + return partTags == null || partTags.isEmpty() ? false + : partTags.stream().anyMatch(tag -> Workbench.EDITOR_TAG.equals(tag)); } -} +} \ No newline at end of file diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartTaggedAsEditorPropertyTester.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartTaggedAsEditorPropertyTester.java new file mode 100644 index 00000000000..78acda39cae --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartTaggedAsEditorPropertyTester.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2007, 2015 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ui.internal; + +import java.util.List; +import org.eclipse.core.expressions.PropertyTester; + +/** + *

+ * Tests whether the object under test represents an MPart instance which is + * tagged as being one which represents an Editor (rather than a View). + *

+ * + *

+ * This test is performed via a query of the tags associated with the MPart, and + * checking whether this collection contains the + * {@link org.eclipse.ui.internal.Workbench#EDITOR_TAG} identifier. + *

+ * + */ +public class PartTaggedAsEditorPropertyTester extends PropertyTester { + + @Override + public boolean test(Object receiver, String property, Object[] args, Object expectedValue) { + if (receiver instanceof E4PartWrapper) { + E4PartWrapper partWrapper = (E4PartWrapper) receiver; + if (partWrapper.wrappedPart != null) { + List partTags = partWrapper.wrappedPart.getTags(); + return partTags == null || partTags.isEmpty() ? false + : partTags.stream().anyMatch(tag -> Workbench.EDITOR_TAG.equals(tag)); + } + } + return false; + } +} \ No newline at end of file diff --git a/bundles/org.eclipse.ui/plugin.xml b/bundles/org.eclipse.ui/plugin.xml index f4523fefbd8..d7c0c6f8e16 100644 --- a/bundles/org.eclipse.ui/plugin.xml +++ b/bundles/org.eclipse.ui/plugin.xml @@ -2149,6 +2149,13 @@ properties="isPerspectiveOpen" type="org.eclipse.ui.IWorkbenchWindow"> + + @@ -2207,11 +2214,11 @@ class="org.eclipse.ui.internal.CloseEditorHandler" commandId="org.eclipse.ui.file.close"> - - - + + + + +