/*******************************************************************************
* Copyright (c) 2012 Google, Inc.
* 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:
* Google, Inc. - initial API and implementation
*******************************************************************************/
package com.windowtester.runtime.swt.internal.text;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Text;
import com.windowtester.runtime.IUIContext;
import com.windowtester.runtime.swt.condition.SWTIdleCondition;
import com.windowtester.runtime.swt.internal.UIContextSWT;
/**
* Uses incremental set text strategy for Text controls; else defaults to
* {@link UIDriverTextEntryStrategy}.
*/
public class InsertTextEntryStrategy implements ITextEntryStrategy {
/**
* @author kor
*/
public abstract static class CharTyper {
/**
* @param c
* @param chr
*/
protected abstract void typeChar(Control c, char chr);
/**
* Not accurate typer for combo
*/
public static class ComboCharTyper extends CharTyper {
/**
* @see com.chartyper.CharTyper#typeChar(org.eclipse.swt.widgets.Control,
* char)
*/
protected void typeChar(Control c, char chr) {
Combo cmb = (Combo) c;
String text = cmb.getText();
StringBuffer buf = new StringBuffer();
buf.append(text);
buf.append(chr);
cmb.setText(buf.toString());
}
}
/**
* Not accurate typer for ccombo
*/
public static class CComboCharTyper extends CharTyper {
/**
*
*/
public CComboCharTyper() {
}
/**
* @see com.chartyper.CharTyper#typeChar(org.eclipse.swt.widgets.Control,
* char)
*/
protected void typeChar(Control c, char chr) {
CCombo cmb = (CCombo) c;
String text = cmb.getText();
StringBuffer buf = new StringBuffer();
buf.append(text);
buf.append(chr);
cmb.setText(buf.toString());
}
}
/**
* typer for widgets who has key down handler method
*/
public static class ReflectionBasedTyper extends CharTyper {
/**
* method that handles key events
*/
protected final Method typeMethod;
/**
* @param clazz
* @param methodName
*/
public ReflectionBasedTyper(Class<?> clazz, String methodName) {
try {
typeMethod = clazz.getDeclaredMethod(methodName,
new Class[] { Event.class });
typeMethod.setAccessible(true);
} catch (SecurityException e) {
throw new LinkageError();
} catch (NoSuchMethodException e) {
throw new LinkageError();
}
}
/**
* @see com.chartyper.CharTyper#typeChar(org.eclipse.swt.widgets.Control,
* char)
*/
public void typeChar(Control tm, char c) {
Event event = new Event();
event.widget = tm;
event.detail = SWT.KeyDown;
event.display = tm.getDisplay();
event.character = c;
event.keyCode = 0;
try {
typeMethod.invoke(tm, new Object[] { event });
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e.getCause());
}
}
}
/**
*
*
*/
public static class StyledTextTyper extends ReflectionBasedTyper {
/**
*
*/
public StyledTextTyper() {
super(StyledText.class, "handleKeyDown"); //$NON-NLS-1$
}
/**
* @return
*/
protected String getMethodName() {
return "handleKeyDown"; //$NON-NLS-1$
}
}
/**
*
*
*/
public static class TextCharTyper extends CharTyper {
/**
* @see com.chartyper.CharTyper#typeChar(org.eclipse.swt.widgets.Control,
* char)
*/
protected void typeChar(Control c, char chr) {
Text tm = (Text) c;
tm.insert(Character.toString(chr));
}
}
private static HashMap<Class<?>, CharTyper> typers = new HashMap<Class<?>, CharTyper>();
/**
* @param clz
* @param typer
*/
public static void register(Class<?> clz, CharTyper typer) {
typers.put(clz, typer);
}
public static boolean hasTyper(Control c) {
return typers.containsKey(c.getClass());
}
static {
register(Combo.class, new ComboCharTyper());
register(CCombo.class, new CComboCharTyper());
register(StyledText.class, new StyledTextTyper());
register(Text.class, new TextCharTyper());
}
/**
* @param c
* @param chr
* @return true if there is a registered typer for a given control
*/
public static boolean type(Control c, char chr) {
CharTyper object = typers.get(c.getClass());
if (object != null) {
object.typeChar(c, chr);
return true;
}
return false;
}
/**
* @param c
* @param text
* @return true if typing succeed
*/
public static boolean type(Control c, String text) {
if (typers.containsKey(c.getClass())) {
for (int a = 0; a < text.length(); a++) {
type(c, text.charAt(a));
}
return true;
}
return false;
}
}
/*
* (non-Javadoc)
*
* @see
* com.windowtester.event.swt.text.ITextEntryStrategy#enterText(com.windowtester
* .swt.UIContext, java.lang.String)
*/
public void enterText(final IUIContext ui, final String txt) {
final Display display = ((UIContextSWT) ui).getDisplay();
// wait until UI settles down to guard against focus race condition
new SWTIdleCondition(display).waitForIdle();
// get the focus control
final Control focusControl = getFocusControl(display);
// if it's a Text, use our special insert logic
if (CharTyper.hasTyper(focusControl)) {
display.syncExec(new Runnable() {
public void run() {
CharTyper.type(focusControl, txt);
}
});
} else {
// or else, use our default strategy
getDefaultStrategy().enterText(ui, txt);
}
}
private ITextEntryStrategy getDefaultStrategy() {
return TextEntryStrategy.getDefault();
}
private Control getFocusControl(final Display display) {
final Control focusControl[] = new Control[1];
display.syncExec(new Runnable() {
public void run() {
focusControl[0] = display.getFocusControl();
}
});
return focusControl[0];
}
public void keyClick(IUIContext ui, int key) {
// TODO Auto-generated method stub
}
public void keyClick(IUIContext ui, char key) {
// TODO Auto-generated method stub
}
public void keyClick(IUIContext ui, int ctrl, char c) {
// TODO Auto-generated method stub
}
public void keyDown(IUIContext ui, char key) {
// TODO Auto-generated method stub
}
public void keyDown(IUIContext ui, int key) {
// TODO Auto-generated method stub
}
public void keyUp(IUIContext ui, char key) {
// TODO Auto-generated method stub
}
public void keyUp(IUIContext ui, int key) {
// TODO Auto-generated method stub
}
}