blob: 45ec9e35d3b56f6a0a8b64cf554d41c9907ea43d [file] [log] [blame]
package org.eclipse.e4.ui.bindings.tests;
import java.util.HashMap;
import java.util.Map;
import junit.framework.TestCase;
import org.eclipse.core.commands.Category;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.commands.contexts.Context;
import org.eclipse.core.commands.contexts.ContextManager;
import org.eclipse.e4.core.commands.CommandServiceAddon;
import org.eclipse.e4.core.commands.ECommandService;
import org.eclipse.e4.core.commands.EHandlerService;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.CanExecute;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.ui.bindings.BindingServiceAddon;
import org.eclipse.e4.ui.bindings.EBindingService;
import org.eclipse.e4.ui.bindings.internal.BindingTable;
import org.eclipse.e4.ui.bindings.internal.BindingTableManager;
import org.eclipse.e4.ui.bindings.internal.ContextSet;
import org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher;
import org.eclipse.e4.ui.internal.services.ActiveContextsFunction;
import org.eclipse.e4.ui.services.ContextServiceAddon;
import org.eclipse.e4.ui.services.EContextService;
import org.eclipse.e4.ui.services.IServiceConstants;
import org.eclipse.jface.bindings.Binding;
import org.eclipse.jface.bindings.TriggerSequence;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
public class KeyDispatcherTest extends TestCase {
private static final String ID_DIALOG = "org.eclipse.ui.contexts.dialog";
private static final String ID_DIALOG_AND_WINDOW = "org.eclipse.ui.contexts.dialogAndWindow";
private static final String ID_WINDOW = "org.eclipse.ui.contexts.window";
final static String[] CONTEXTS = { ID_DIALOG_AND_WINDOW, "DAW", null,
ID_DIALOG, "Dialog", ID_DIALOG_AND_WINDOW, ID_WINDOW, "Window",
ID_DIALOG_AND_WINDOW, };
private static final String TEST_CAT1 = "test.cat1";
private static final String TEST_ID1 = "test.id1";
private static final String TEST_ID2 = "test.id2";
static class CallHandler {
public boolean q1;
public boolean q2;
@CanExecute
public boolean canExecute() {
q1 = true;
return true;
}
@Execute
public Object execute() {
q2 = true;
if (q1) {
return Boolean.TRUE;
}
return Boolean.FALSE;
}
}
private Display display;
private IEclipseContext workbenchContext;
private CallHandler handler;
private CallHandler twoStrokeHandler;
private void defineCommands(IEclipseContext context) {
ECommandService cs = (ECommandService) workbenchContext
.get(ECommandService.class.getName());
Category category = cs.defineCategory(TEST_CAT1, "CAT1", null);
cs.defineCommand(TEST_ID1, "ID1", null, category, null);
cs.defineCommand(TEST_ID2, "ID2", null, category, null);
ParameterizedCommand cmd = cs.createCommand(TEST_ID1, null);
EHandlerService hs = (EHandlerService) workbenchContext
.get(EHandlerService.class.getName());
handler = new CallHandler();
hs.activateHandler(TEST_ID1, handler);
EBindingService bs = (EBindingService) workbenchContext
.get(EBindingService.class.getName());
TriggerSequence seq = bs.createSequence("CTRL+A");
Binding db = createDefaultBinding(bs, seq, cmd);
bs.activateBinding(db);
ParameterizedCommand cmd2 = cs.createCommand(TEST_ID2, null);
twoStrokeHandler = new CallHandler();
hs.activateHandler(TEST_ID2, twoStrokeHandler);
TriggerSequence twoKeys = bs.createSequence("CTRL+5 CTRL+A");
db = createDefaultBinding(bs, twoKeys, cmd2);
bs.activateBinding(db);
}
private Binding createDefaultBinding(EBindingService bs,
TriggerSequence sequence, ParameterizedCommand command) {
Map<String, String> attrs = new HashMap<String,String>();
attrs.put("schemeId", "org.eclipse.ui.defaultAcceleratorConfiguration");
return bs.createBinding(sequence, command, ID_WINDOW, attrs);
}
@Override
protected void setUp() throws Exception {
display = new Display();
IEclipseContext globalContext = Activator.getDefault().getGlobalContext();
workbenchContext = globalContext.createChild("workbenchContext");
ContextInjectionFactory.make(CommandServiceAddon.class, workbenchContext);
ContextInjectionFactory.make(ContextServiceAddon.class, workbenchContext);
ContextInjectionFactory.make(BindingServiceAddon.class, workbenchContext);
defineContexts(workbenchContext);
defineBindingTables(workbenchContext);
defineCommands(workbenchContext);
}
private void defineContexts(IEclipseContext context) {
ContextManager contextManager = context.get(ContextManager.class);
for (int i = 0; i < CONTEXTS.length; i += 3) {
Context c = contextManager.getContext(CONTEXTS[i]);
c.define(CONTEXTS[i + 1], null, CONTEXTS[i + 2]);
}
EContextService cs = (EContextService) context
.get(EContextService.class.getName());
cs.activateContext(ID_DIALOG_AND_WINDOW);
cs.activateContext(ID_WINDOW);
}
private void defineBindingTables(IEclipseContext context) {
BindingTableManager btm = context.get(BindingTableManager.class);
ContextManager cm = context
.get(ContextManager.class);
btm.addTable(new BindingTable(cm.getContext(ID_DIALOG_AND_WINDOW)));
btm.addTable(new BindingTable(cm.getContext(ID_WINDOW)));
btm.addTable(new BindingTable(cm.getContext(ID_DIALOG)));
}
@Override
protected void tearDown() throws Exception {
workbenchContext.dispose();
workbenchContext = null;
display.dispose();
display = null;
}
public void testExecuteOneCommand() throws Exception {
KeyBindingDispatcher dispatcher = new KeyBindingDispatcher();
ContextInjectionFactory.inject(dispatcher, workbenchContext);
final Listener listener = dispatcher.getKeyDownFilter();
display.addFilter(SWT.KeyDown, listener);
display.addFilter(SWT.Traverse, listener);
assertFalse(handler.q2);
Shell shell = new Shell(display, SWT.NONE);
Event event = new Event();
event.type = SWT.KeyDown;
event.keyCode = SWT.CTRL;
shell.notifyListeners(SWT.KeyDown, event);
event = new Event();
event.type = SWT.KeyDown;
event.stateMask = SWT.CTRL;
event.keyCode = 'A';
shell.notifyListeners(SWT.KeyDown, event);
assertTrue(handler.q2);
}
public void testExecuteMultiStrokeBinding() throws Exception {
KeyBindingDispatcher dispatcher = new KeyBindingDispatcher();
ContextInjectionFactory.inject(dispatcher, workbenchContext);
final Listener listener = dispatcher.getKeyDownFilter();
display.addFilter(SWT.KeyDown, listener);
display.addFilter(SWT.Traverse, listener);
assertFalse(twoStrokeHandler.q2);
Shell shell = new Shell(display, SWT.NONE);
Event event = new Event();
event.type = SWT.KeyDown;
event.keyCode = SWT.CTRL;
shell.notifyListeners(SWT.KeyDown, event);
event = new Event();
event.type = SWT.KeyDown;
event.stateMask = SWT.CTRL;
event.keyCode = '5';
shell.notifyListeners(SWT.KeyDown, event);
assertFalse(twoStrokeHandler.q2);
event = new Event();
event.type = SWT.KeyDown;
event.keyCode = SWT.CTRL;
shell.notifyListeners(SWT.KeyDown, event);
event = new Event();
event.type = SWT.KeyDown;
event.stateMask = SWT.CTRL;
event.keyCode = 'A';
shell.notifyListeners(SWT.KeyDown, event);
processEvents();
assertTrue(twoStrokeHandler.q2);
assertFalse(handler.q2);
}
public void TODOtestKeyDispatcherReset() throws Exception {
KeyBindingDispatcher dispatcher = new KeyBindingDispatcher();
ContextInjectionFactory.inject(dispatcher, workbenchContext);
final Listener listener = dispatcher.getKeyDownFilter();
display.addFilter(SWT.KeyDown, listener);
display.addFilter(SWT.Traverse, listener);
assertFalse(twoStrokeHandler.q2);
Shell shell = new Shell(display, SWT.NONE);
Event event = new Event();
event.type = SWT.KeyDown;
event.keyCode = SWT.CTRL;
shell.notifyListeners(SWT.KeyDown, event);
event = new Event();
event.type = SWT.KeyDown;
event.stateMask = SWT.CTRL;
event.keyCode = '5';
shell.notifyListeners(SWT.KeyDown, event);
assertFalse(twoStrokeHandler.q2);
Thread.sleep(2000L);
processEvents();
event = new Event();
event.type = SWT.KeyDown;
event.keyCode = SWT.CTRL;
shell.notifyListeners(SWT.KeyDown, event);
event = new Event();
event.type = SWT.KeyDown;
event.stateMask = SWT.CTRL;
event.keyCode = 'A';
shell.notifyListeners(SWT.KeyDown, event);
processEvents();
assertFalse(twoStrokeHandler.q2);
assertTrue(handler.q2);
}
public void testSendKeyStroke() throws Exception {
KeyBindingDispatcher dispatcher = (KeyBindingDispatcher) ContextInjectionFactory
.make(KeyBindingDispatcher.class, workbenchContext);
final Listener listener = dispatcher.getKeyDownFilter();
display.addFilter(SWT.KeyDown, listener);
display.addFilter(SWT.Traverse, listener);
Shell shell = new Shell(display, SWT.NONE);
shell.setLayout(new FillLayout());
StyledText text = new StyledText(shell, SWT.WRAP | SWT.MULTI);
shell.setBounds(100, 100, 100, 100);
shell.layout();
processEvents();
assertEquals("", text.getText());
Event event = new Event();
event.type = SWT.KeyDown;
event.stateMask = SWT.SHIFT;
event.keyCode = '(';
event.character = '(';
text.notifyListeners(SWT.KeyDown, event);
event = new Event();
event.type = SWT.KeyUp;
event.stateMask = SWT.SHIFT;
event.keyCode = '(';
event.character = '(';
text.notifyListeners(SWT.KeyUp, event);
processEvents();
assertEquals("(", text.getText());
}
private void processEvents() {
while (display.readAndDispatch())
;
}
// KEYS >>> Listener.handleEvent(type = KeyDown, stateMask = 0x0, keyCode =
// 0x40000, time = 2986140, character = 0x0)
// KEYS >>> Listener.handleEvent(type = KeyDown, stateMask = 0x40000,
// keyCode = 0x10000, time = 2986218, character = 0x0)
// KEYS >>> Listener.handleEvent(type = KeyDown, stateMask = 0x50000,
// keyCode = 0x6c, time = 2986515, character = 0xc)
}