/**
* Copyright (c) 2009, 2010 Mark Feber, MulgaSoft
*
* 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
*/
package com.mulgasoft.emacsplus.commands;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.ui.texteditor.ITextEditor;
/**
* Abstract class to provide required selection changed behavior for commands that invoke other commands
*
* @author Mark Feber - initial API and implementation
*/
public abstract class ExecuteCommandHandler extends MinibufferExecHandler {
/* Hack Alert: The JavaEditor (maybe others) adds a post selection listener that clears the status
* message (bogosity). Since we want the key binding help (or other message) to stick around, we have
* to add a temporary selection changed listener to restore the message if it gets removed.
*
* In some cases, JavaEditor.selectionChanged (which clears the status line) is called directly instead
* of from iterating through listeners (e.g org.eclipse.jdt.internal.ui.javaeditor.reconciled)
* (even more bogosity) which means the appropriate message won't always redisplay correctly and
* there is nothing obvious we can do about it.
*/
/**
* Call execute on checkers with an additional listener for selection change during execution
*
* @param editor
* @param checkers
*/
protected void executeWithSelectionCheck(final ITextEditor editor, IWithSelectionCheck checkers) {
ISelectionChangedListener listener = new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
ExecuteCommandHandler.this.showResultMessage(editor);
removeListener(event.getSelectionProvider(),this);
}
};
ITextSelection before = getCurrentSelection(editor);
try {
addListener(editor.getSelectionProvider(),listener);
checkers.execute();
} finally {
if (before.equals(getCurrentSelection(editor))) {
// remove it if the selection did not change
removeListener(editor.getSelectionProvider(),listener);
}
}
}
/**
* Add the selection changed listener
*
* @param selectionProvider
*/
private void addListener(ISelectionProvider selectionProvider, ISelectionChangedListener listener) {
if (selectionProvider instanceof IPostSelectionProvider) {
IPostSelectionProvider provider= (IPostSelectionProvider) selectionProvider;
provider.addPostSelectionChangedListener(listener);
} else {
selectionProvider.addSelectionChangedListener(listener);
}
}
/**
* Remove the selection changed listener
*
* @param selectionProvider
*/
private void removeListener(ISelectionProvider selectionProvider, ISelectionChangedListener listener) {
if (selectionProvider instanceof IPostSelectionProvider) {
IPostSelectionProvider provider= (IPostSelectionProvider) selectionProvider;
provider.removePostSelectionChangedListener(listener);
} else {
selectionProvider.removeSelectionChangedListener(listener);
}
}
/**
* Work around issue with Eclipse where a selection change listener is required to redisplay
* a cleared message if a selection changed occurred during execution
*
* @author Mark Feber - initial API and implementation
*/
protected interface IWithSelectionCheck {
void execute();
}
}