Skip to content

Commit 04dc50b

Browse files
feilimbmickaelistria
authored andcommitted
Modify the 'Close Editor' handler and enabled when evaluation to support for Compatibility parts and new Parts which represent an Editor and are contributed via eg. PartDescriptors in a Model Fragment. Associated with Issue#2176.
1 parent 419bb61 commit 04dc50b

File tree

3 files changed

+110
-41
lines changed

3 files changed

+110
-41
lines changed

bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/CloseEditorHandler.java

Lines changed: 51 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,21 @@
1414

1515
package org.eclipse.ui.internal;
1616

17+
import java.util.List;
18+
import org.eclipse.core.commands.AbstractHandler;
1719
import org.eclipse.core.commands.ExecutionEvent;
1820
import org.eclipse.core.commands.ExecutionException;
19-
import org.eclipse.core.expressions.EvaluationResult;
20-
import org.eclipse.core.expressions.Expression;
21-
import org.eclipse.core.expressions.ExpressionInfo;
22-
import org.eclipse.core.expressions.IEvaluationContext;
21+
import org.eclipse.e4.core.contexts.IEclipseContext;
22+
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
23+
import org.eclipse.e4.ui.workbench.IWorkbench;
24+
import org.eclipse.e4.ui.workbench.modeling.EPartService;
2325
import org.eclipse.ui.IEditorPart;
24-
import org.eclipse.ui.ISources;
26+
import org.eclipse.ui.IWorkbenchPart;
2527
import org.eclipse.ui.IWorkbenchWindow;
2628
import org.eclipse.ui.handlers.HandlerUtil;
29+
import org.osgi.framework.BundleContext;
30+
import org.osgi.framework.FrameworkUtil;
31+
import org.osgi.framework.ServiceReference;
2732

2833
/**
2934
* Closes the active editor.
@@ -33,43 +38,53 @@
3338
*
3439
* @since 3.3
3540
*/
36-
public class CloseEditorHandler extends AbstractEvaluationHandler {
37-
38-
private Expression enabledWhen;
39-
40-
public CloseEditorHandler() {
41-
registerEnablement();
42-
}
41+
public class CloseEditorHandler extends AbstractHandler {
4342

4443
@Override
4544
public Object execute(ExecutionEvent event) throws ExecutionException {
46-
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
47-
IEditorPart part = HandlerUtil.getActiveEditorChecked(event);
48-
window.getActivePage().closeEditor(part, true);
4945

50-
return null;
51-
}
52-
53-
@Override
54-
protected Expression getEnabledWhenExpression() {
55-
if (enabledWhen == null) {
56-
enabledWhen = new Expression() {
57-
@Override
58-
public EvaluationResult evaluate(IEvaluationContext context) {
59-
IEditorPart part = InternalHandlerUtil.getActiveEditor(context);
60-
if (part != null) {
61-
return EvaluationResult.TRUE;
46+
IWorkbenchPart activePart = HandlerUtil.getActivePart(event);
47+
if (activePart instanceof IEditorPart) {
48+
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
49+
window.getActivePage().closeEditor((IEditorPart) activePart, true);
50+
} else {
51+
// we may have an E4PartWrapper for a part which has been contributed eg. via a
52+
// PartDescriptor in a model fragment, and which has been tagged as
53+
// representing an Editor
54+
if (activePart instanceof E4PartWrapper) {
55+
// derive the IEclipseContext & EPartService
56+
BundleContext context = FrameworkUtil.getBundle(IWorkbench.class).getBundleContext();
57+
ServiceReference<IWorkbench> reference = context.getServiceReference(IWorkbench.class);
58+
IEclipseContext eclipseContext = context.getService(reference).getApplication().getContext();
59+
EPartService partService = eclipseContext.get(EPartService.class);
6260

61+
// access the wrapped part => save & close it
62+
MPart wrappedPart = ((E4PartWrapper) activePart).wrappedPart;
63+
if (wrappedPart != null && partService != null) {
64+
// ensure the active part does indeed represent an editor
65+
// (and not eg. a view) - checking here is just for extra
66+
// redundancy
67+
if (representsEditor(wrappedPart)) {
68+
if (partService.savePart(wrappedPart, true)) {
69+
partService.hidePart(wrappedPart);
70+
}
6371
}
64-
return EvaluationResult.FALSE;
6572
}
66-
67-
@Override
68-
public void collectExpressionInfo(ExpressionInfo info) {
69-
info.addVariableNameAccess(ISources.ACTIVE_EDITOR_NAME);
70-
}
71-
};
73+
}
7274
}
73-
return enabledWhen;
75+
76+
return null;
77+
}
78+
79+
/**
80+
* Checks whether the specified part represents an editor instance.
81+
*
82+
* @param part the part to query
83+
* @return true if the specified part represents an editor, false otherwise
84+
*/
85+
private boolean representsEditor(MPart part) {
86+
List<String> partTags = part.getTags();
87+
return partTags == null || partTags.isEmpty() ? false
88+
: partTags.stream().anyMatch(tag -> Workbench.EDITOR_TAG.equals(tag));
7489
}
75-
}
90+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2007, 2015 IBM Corporation and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* IBM Corporation - initial API and implementation
13+
******************************************************************************/
14+
15+
package org.eclipse.ui.internal;
16+
17+
import java.util.List;
18+
import org.eclipse.core.expressions.PropertyTester;
19+
20+
/**
21+
* <p>
22+
* Tests whether the object under test represents an MPart instance which is
23+
* tagged as being one which represents an Editor (rather than a View).
24+
* </p>
25+
*
26+
* <p>
27+
* This test is performed via a query of the tags associated with the MPart, and
28+
* checking whether this collection contains the
29+
* {@link org.eclipse.ui.internal.Workbench#EDITOR_TAG} identifier.
30+
* </p>
31+
*
32+
*/
33+
public class PartTaggedAsEditorPropertyTester extends PropertyTester {
34+
35+
@Override
36+
public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
37+
if (receiver instanceof E4PartWrapper) {
38+
E4PartWrapper partWrapper = (E4PartWrapper) receiver;
39+
if (partWrapper.wrappedPart != null) {
40+
List<String> partTags = partWrapper.wrappedPart.getTags();
41+
return partTags == null || partTags.isEmpty() ? false
42+
: partTags.stream().anyMatch(tag -> Workbench.EDITOR_TAG.equals(tag));
43+
}
44+
}
45+
return false;
46+
}
47+
}

bundles/org.eclipse.ui/plugin.xml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2149,6 +2149,13 @@
21492149
properties="isPerspectiveOpen"
21502150
type="org.eclipse.ui.IWorkbenchWindow">
21512151
</propertyTester>
2152+
<propertyTester
2153+
class="org.eclipse.ui.internal.PartTaggedAsEditorPropertyTester"
2154+
id="org.eclipse.ui.isPartTaggedAsEditor"
2155+
namespace="org.eclipse.ui"
2156+
properties="isPartTaggedAsEditor"
2157+
type="org.eclipse.ui.IWorkbenchPart">
2158+
</propertyTester>
21522159
</extension>
21532160
<extension
21542161
point="org.eclipse.core.expressions.definitions">
@@ -2207,11 +2214,11 @@
22072214
class="org.eclipse.ui.internal.CloseEditorHandler"
22082215
commandId="org.eclipse.ui.file.close">
22092216
<enabledWhen>
2210-
<with
2211-
variable="activeEditor">
2212-
<instanceof
2213-
value="org.eclipse.ui.IEditorPart">
2214-
</instanceof>
2217+
<with variable="activePart">
2218+
<or>
2219+
<instanceof value="org.eclipse.ui.IEditorPart" />
2220+
<test property="org.eclipse.ui.isPartTaggedAsEditor" />
2221+
</or>
22152222
</with>
22162223
</enabledWhen>
22172224
</handler>

0 commit comments

Comments
 (0)