Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify the 'Close Editor' handler and enabled when evaluation to supp… #2315

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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<IWorkbench> 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<String> partTags = part.getTags();
return partTags == null || partTags.isEmpty() ? false
: partTags.stream().anyMatch(tag -> Workbench.EDITOR_TAG.equals(tag));
}
}
}
Original file line number Diff line number Diff line change
@@ -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;

/**
* <p>
* Tests whether the object under test represents an MPart instance which is
* tagged as being one which represents an Editor (rather than a View).
* </p>
*
* <p>
* 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.
* </p>
*
*/
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<String> partTags = partWrapper.wrappedPart.getTags();
return partTags == null || partTags.isEmpty() ? false
: partTags.stream().anyMatch(tag -> Workbench.EDITOR_TAG.equals(tag));
}
}
return false;
}
}
17 changes: 12 additions & 5 deletions bundles/org.eclipse.ui/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2149,6 +2149,13 @@
properties="isPerspectiveOpen"
type="org.eclipse.ui.IWorkbenchWindow">
</propertyTester>
<propertyTester
class="org.eclipse.ui.internal.PartTaggedAsEditorPropertyTester"
id="org.eclipse.ui.isPartTaggedAsEditor"
namespace="org.eclipse.ui"
properties="isPartTaggedAsEditor"
type="org.eclipse.ui.IWorkbenchPart">
</propertyTester>
</extension>
<extension
point="org.eclipse.core.expressions.definitions">
Expand Down Expand Up @@ -2207,11 +2214,11 @@
class="org.eclipse.ui.internal.CloseEditorHandler"
commandId="org.eclipse.ui.file.close">
<enabledWhen>
<with
variable="activeEditor">
<instanceof
value="org.eclipse.ui.IEditorPart">
</instanceof>
<with variable="activePart">
<or>
<instanceof value="org.eclipse.ui.IEditorPart" />
<test property="org.eclipse.ui.isPartTaggedAsEditor" />
</or>
</with>
</enabledWhen>
</handler>
Expand Down
Loading