/******************************************************************************* * Copyright (c) 2009 Ketan Padegaonkar and others. * 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: * Ketan Padegaonkar - initial API and implementation *******************************************************************************/ package org.eclipse.swtbot.swt.finder.keyboard; import static org.eclipse.swtbot.swt.finder.utils.SWTUtils.sleep; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.apache.log4j.Logger; import org.eclipse.jface.bindings.keys.KeyStroke; import org.eclipse.swt.SWT; import org.eclipse.swtbot.swt.finder.utils.MessageFormat; import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences; /** * Represents a Keyboard. Allows for typing keys and pressing shortcuts. Pressing shortcuts is different from pressing * normal characters and 'special characters'. * <p> * <b>NOTE:</b> This class needs that a {@link KeyStroke} be split. This means that a single {@link KeyStroke} * representing a SHIFT+T needs to be split into two {@link KeyStroke}s, one representing a SHIFT and another * representing a 'T'. * </p> * <p> * <b>Shortcut:</b> CTRL+SHIFT+T for e.g. needs to press CTRL, SHIFT, T in that order while holding them down, and * release them in the order T, SHIFT, CTRL. * </p> * <p> * <b>Normal characters:</b> 't' requires that you type 'T'. 'T' requires that you type the shortcut SHIFT+T. * </p> * <p> * <b>Special characters:</b> On a US keyboard '#' requires that you type SHIFT+3. ':' requires you to type SHIFT+;. * </p> * * @author Ketan Padegaonkar <KetanPadegaonkar [at] gmail [dot] com> * @version $Id$ * @see Keystrokes#toKeys(int, char) */ public class Keyboard { private static final Logger log = Logger.getLogger(Keyboard.class); private final KeyboardStrategy strategy; /** * Creates a new keyboard. */ Keyboard() { this(new AWTKeyboardStrategy()); } /** * Creates a new keyboard that uses the specified strategy to type on the keyboard. * * @param strategy the keyboard strategy. */ public Keyboard(KeyboardStrategy strategy) { this.strategy = strategy; } /** * Types the string on the keyboard. * * @param text the text to type on the keyboard. */ public void typeText(String text) { typeText(text, SWTBotPreferences.TYPE_INTERVAL); } /** * Types the string on the keyboard. * * @param text the text to type on the keyboard. * @param interval the interval between the keystrokes. */ public void typeText(String text, int interval) { log.debug(MessageFormat.format("Typing text ''{0}'' with an interval of {1}ms. between characters.", text, interval)); for (int i = 0; i < text.length(); i++) { typeCharacter(text.charAt(i)); sleep(interval); } } /** * Types the character on the keyboard. Note that the character may refer to multiple keystrokes. * * @param ch the character to type on the keyboard. */ public void typeCharacter(char ch) { pressShortcut(Keystrokes.create(ch)); } /** * Presses the shortcut specified by the given keys. * * @param modificationKeys the combination of {@link SWT#ALT} | {@link SWT#CTRL} | {@link SWT#SHIFT} | * {@link SWT#COMMAND}. * @param c the character * @see Keystrokes#toKeys(int, char) */ public void pressShortcut(int modificationKeys, char c) { pressShortcut(Keystrokes.toKeys(modificationKeys, c)); } /** * Presses the shortcut specified by the given keys. * * @param keys the keys to press * @see Keystrokes#toKeys(int, char) */ public void pressShortcut(KeyStroke... keys) { log.trace(MessageFormat.format("Pressing shortcut {0}", Arrays.asList(keys))); pressKeys(keys); releaseKeys(reverse(keys)); } /** * Presses the shortcut specified by the given keys. * * @param modificationKeys the combination of {@link SWT#ALT} | {@link SWT#CTRL} | {@link SWT#SHIFT} | * {@link SWT#COMMAND}. * @param keyCode the keyCode, these may be special keys like F1-F12, or navigation keys like HOME, PAGE_UP * @param c the character * @see Keystrokes#toKeys(int, char) */ public void pressShortcut(int modificationKeys, int keyCode, char c) { List<KeyStroke> keys = new ArrayList<KeyStroke>(Arrays.asList(Keystrokes.toKeys(modificationKeys, c))); if (keyCode != 0) addKeyCode(keyCode, c, keys); pressShortcut(keys.toArray(new KeyStroke[keys.size()])); } private KeyStroke[] reverse(KeyStroke... keys) { ArrayList<KeyStroke> copy = new ArrayList<KeyStroke>(Arrays.asList(keys)); Collections.reverse(copy); return copy.toArray(new KeyStroke[copy.size()]); } private void releaseKeys(KeyStroke... keys) { strategy.releaseKeys(keys); } private void pressKeys(KeyStroke... keys) { strategy.pressKeys(keys); } private void addKeyCode(int keyCode, char c, List<KeyStroke> keys) { if (c == 0) keys.add(KeyStroke.getInstance(0, keyCode)); else keys.add(keys.size() - 1, KeyStroke.getInstance(0, keyCode)); } }