/******************************************************************************* * Copyright (c) 2017 Association for Decentralized Information Management * in Industry THTH ry. * 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: * Semantum Oy - (#7066) initial API and implementation *******************************************************************************/ package org.simantics.views.text.internal; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.concurrent.Callable; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExecutableExtension; import org.eclipse.jface.text.IUndoManager; import org.eclipse.jface.text.TextViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; /** * Handles the undo/redo command for {@link TextViewer}s through * {@link IUndoManager}. * *
* The implementation looks for an IUndoManager from the current focus control
* using the {@link TextViewerConstants#KEY_UNDO_MANAGER} data key. Its
* existence determines whether this handler {@link #isHandled()} returns
* true
or false
.
*
*
* The handler expects to receive a single string as an argument through the
* extension definitions ({@link IExecutableExtension}) that determines which
* method is invoked from IUndoManager (undo
or redo
).
*
*
* Implementation is partially copied from
* org.eclipse.ui.internal.handlers.WidgetMethodHandler
.
*
* @since 1.28.0
*/
public class TextViewerUndoHandler extends AbstractHandler implements IExecutableExtension {
/**
* The parameters to pass to the method this handler invokes. This handler
* always passes no parameters.
*/
protected static final Class>[] NO_PARAMETERS = new Class[0];
public TextViewerUndoHandler() {
display = Display.getCurrent();
if (display != null) {
focusListener = new Listener() {
@Override
public void handleEvent(Event event) {
updateEnablement();
}
};
display.addFilter(SWT.FocusIn, focusListener);
}
}
void updateEnablement() {
boolean rc = isHandled();
if (rc != isEnabled()) {
setBaseEnabled(rc);
}
}
/**
* The name of the method to be invoked by this handler. This value should
* never be null
.
*/
protected String methodName;
private Listener focusListener;
private Display display;
@Override
public Object execute(final ExecutionEvent event) throws ExecutionException {
Callable> runnable = getMethodToExecute();
if (runnable != null) {
try {
runnable.call();
} catch (ExecutionException e) {
throw e;
} catch (Exception e) {
throw new ExecutionException("Unexpected failure executing method " + methodName + " through " + runnable);
}
}
return null;
}
@Override
public final boolean isHandled() {
return getMethodToExecute() != null;
}
/**
* Looks up the method on the focus control.
*
* @return The method on the focus control; null
if none.
*/
protected Callable