1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 package org.openoffice.test.vcl;
25 
26 import java.awt.AWTException;
27 import java.awt.Robot;
28 import java.awt.event.InputEvent;
29 import java.awt.event.KeyEvent;
30 import java.util.HashMap;
31 import java.util.StringTokenizer;
32 
33 
34 /**
35  *
36  */
37 public class Tester {
38 	static Robot robot;
39 
40 	static double factor = Double.parseDouble(System.getProperty("sleep.factor", "1.0"));
41 
42 	static {
43 		try {
44 			robot = new Robot();
45 		    robot.setAutoDelay(15);
46 		    robot.setAutoWaitForIdle(true);
47 		} catch (AWTException e) {
48 			e.printStackTrace();
49 		}
50 	}
51 
Tester()52 	public Tester() {
53 
54 	}
55 
56 	/**
57 	 *
58 	 * @param delay
59 	 */
sleep(double seconds)60 	public static void sleep(double seconds) {
61 		try {
62 			Thread.sleep((long) (seconds * factor * 1000));
63 		} catch (InterruptedException e) {
64 		}
65 	}
66 
67 	/**
68 	 * Click on the screen
69 	 * @param x
70 	 * @param y
71 	 */
click(int x, int y)72 	public static void click(int x, int y) {
73 		robot.mouseMove(x, y);
74 		robot.mousePress(InputEvent.BUTTON1_MASK);
75 		robot.mouseRelease(InputEvent.BUTTON1_MASK);
76 		robot.delay(100);
77 	}
78 
doubleClick(int x, int y)79 	public static void doubleClick(int x, int y) {
80 		robot.mouseMove(x, y);
81 		robot.mousePress(InputEvent.BUTTON1_MASK);
82 		robot.mouseRelease(InputEvent.BUTTON1_MASK);
83 		robot.mousePress(InputEvent.BUTTON1_MASK);
84 		robot.mouseRelease(InputEvent.BUTTON1_MASK);
85 		robot.delay(100);
86 	}
87 
88 	/**
89 	 * Right click on the screen
90 	 * @param x
91 	 * @param y
92 	 */
rightClick(int x, int y)93 	public static void rightClick(int x, int y) {
94 		robot.mouseMove(x, y);
95 		robot.mousePress(InputEvent.BUTTON3_MASK);
96 		robot.mouseRelease(InputEvent.BUTTON3_MASK);
97 		robot.delay(100);
98 	}
99 
drag(int fromX, int fromY, int toX, int toY)100 	public static void drag(int fromX, int fromY, int toX, int toY) {
101 		robot.mouseMove(fromX, fromY);
102 		robot.mousePress(InputEvent.BUTTON1_MASK);
103 		int x = fromX;
104 		int y = fromY;
105 		// get the direction
106 		int dx = toX > fromX ? 1 : -1;
107 		int dy = toY > fromY ? 1 : -1;
108 		// get the step sizes
109 		final int stepTarget = 10;
110 		int sx = (toX - fromX) / stepTarget;
111 		int sy = (toY - fromY) / stepTarget;
112 		if( sx == 0) sx = dx;
113 		if( sy == 0) sy = dy;
114 		while (x != toX || y != toY) {
115 			x += sx;
116 			y += sy;
117 			// limit drag pos to target pos
118 			if( ((x - toX) * dx) > 0)
119 				x = toX;
120 			if( ((y - toY) * dy) > 0)
121 				y = toY;
122 			robot.mouseMove(x, y);
123 		}
124 		robot.mouseRelease(InputEvent.BUTTON1_MASK);
125 		robot.delay(100);
126 	}
127 
128 	/**
129 	 * Type String
130 	 * @param text
131 	 */
typeText(String text)132 	public static void typeText(String text) {
133 		for (int i = 0; i < text.length(); i++) {
134 			char ch = text.charAt(i);
135 			String[] shiftKeys = keyMap.get(ch);
136 			if (shiftKeys == null)
137 				throw new RuntimeException("Keys is invalid!");
138 			typeShortcut(shiftKeys);
139 		}
140 	}
141 
142 	/**
143 	 * Type shortcut
144 	 * @param keys
145 	 */
typeShortcut(String... keys)146 	public static void typeShortcut(String... keys) {
147 		for(int i = 0; i < keys.length; i++) {
148 			String key = keys[i];
149 			key = key.toLowerCase();
150 			Integer keyCode = keyCodeMap.get(key);
151 			if (keyCode == null)
152 				throw new RuntimeException("Invalid keys!");
153 			robot.keyPress(keyCode);
154 		}
155 
156 		for(int i = keys.length - 1; i >= 0; i--) {
157 			String key = keys[i];
158 			key = key.toLowerCase();
159 			Integer keyCode = keyCodeMap.get(key);
160 			if (keyCode == null)
161 				throw new RuntimeException("Invalid keys!");
162 			robot.keyRelease(keyCode);
163 		}
164 	}
165 
166 	/**
167 	 * Type the keys
168 	 * To input shortcut, use "<key key key ...>". The keys is separated with space and surrounded with angle brackets.
169 	 * For example, input the word "hello" and then press Ctrl+A to select the all content.
170 	 * typeKeys("hello<ctrl a>");
171 	 *
172 	 *
173 	 *
174 	 * @param keys
175 	 */
typeKeys(String keys)176 	public static void typeKeys(String keys) {
177 		StringTokenizer tokenizer = new StringTokenizer(keys, "<>", true);
178 		int state = 0;
179 		while (tokenizer.hasMoreTokens()) {
180 			String token = tokenizer.nextToken();
181 			switch (state) {
182 			case 0:
183 				if ("<".equals(token)) {
184 					state = 1;
185 				} else if (">".equals(token)) {
186 					throw new RuntimeException("Invalid keys!");
187 				} else {
188 					typeText(token);
189 				}
190 			break;
191 			case 1:
192 				if (">".equals(token)) {
193 					state = 0;
194 				} else if ("<".equals(token)){
195 					throw new RuntimeException("Invalid keys!");
196 				} else {
197 					if (token.startsWith("$")) {
198 						String[] ckeys = customizedMap.get(token.substring(1));
199 						if (ckeys == null || ckeys.length == 0)
200 							throw new RuntimeException(token + " is not a customized shortcut!");
201 						typeShortcut(ckeys);
202 					} else {
203 						String[] ckeys = token.split(" ");
204 						typeShortcut(ckeys);
205 					}
206 				}
207 			}
208 		}
209 	}
210 	protected static HashMap<String, Integer> keyCodeMap = new HashMap<String, Integer>();
211 	protected static HashMap<Character, String[]> keyMap = new HashMap<Character, String[]>();
212 	protected static HashMap<String, String[]> customizedMap = new HashMap<String, String[]>();
213 	static {
214 		//US keyboard
215 		keyCodeMap.put("esc", KeyEvent.VK_ESCAPE);
216 		keyCodeMap.put("f1", KeyEvent.VK_F1);
217 		keyCodeMap.put("f2", KeyEvent.VK_F2);
218 		keyCodeMap.put("f3", KeyEvent.VK_F3);
219 		keyCodeMap.put("f4", KeyEvent.VK_F4);
220 		keyCodeMap.put("f5", KeyEvent.VK_F5);
221 		keyCodeMap.put("f6", KeyEvent.VK_F6);
222 		keyCodeMap.put("f7", KeyEvent.VK_F7);
223 		keyCodeMap.put("f8", KeyEvent.VK_F8);
224 		keyCodeMap.put("f9", KeyEvent.VK_F9);
225 		keyCodeMap.put("f10", KeyEvent.VK_F10);
226 		keyCodeMap.put("f11", KeyEvent.VK_F11);
227 		keyCodeMap.put("f12", KeyEvent.VK_F12);
228 		keyCodeMap.put("printscreen", KeyEvent.VK_PRINTSCREEN);
229 		keyCodeMap.put("scrolllock", KeyEvent.VK_SCROLL_LOCK);
230 		keyCodeMap.put("pause", KeyEvent.VK_PAUSE);
231 		keyCodeMap.put("tab", KeyEvent.VK_TAB);
232 		keyCodeMap.put("space", KeyEvent.VK_SPACE);
233 		keyCodeMap.put("capslock", KeyEvent.VK_CAPS_LOCK);
234 		keyCodeMap.put("shift", KeyEvent.VK_SHIFT);
235 		keyCodeMap.put("ctrl", KeyEvent.VK_CONTROL);
236 		keyCodeMap.put("alt", KeyEvent.VK_ALT);
237 		keyCodeMap.put("bs", KeyEvent.VK_BACK_SPACE);
238 		keyCodeMap.put("backspace", KeyEvent.VK_BACK_SPACE);
239 		keyCodeMap.put("enter", KeyEvent.VK_ENTER);
240 		keyCodeMap.put("cr", KeyEvent.VK_ENTER);
241 		keyCodeMap.put("command", 157);
242 		keyCodeMap.put("control", KeyEvent.VK_CONTROL);
243 		keyCodeMap.put("insert", KeyEvent.VK_INSERT);
244 		keyCodeMap.put("del", KeyEvent.VK_DELETE);
245 		keyCodeMap.put("delete", KeyEvent.VK_DELETE);
246 		keyCodeMap.put("home", KeyEvent.VK_HOME);
247 		keyCodeMap.put("end", KeyEvent.VK_END);
248 		keyCodeMap.put("pageup", KeyEvent.VK_PAGE_UP);
249 		keyCodeMap.put("pagedown", KeyEvent.VK_PAGE_DOWN);
250 		keyCodeMap.put("up", KeyEvent.VK_UP);
251 		keyCodeMap.put("left", KeyEvent.VK_LEFT);
252 		keyCodeMap.put("right", KeyEvent.VK_RIGHT);
253 		keyCodeMap.put("down", KeyEvent.VK_DOWN);
254 		keyCodeMap.put("numlock", KeyEvent.VK_NUM_LOCK);
255 		keyCodeMap.put("a", KeyEvent.VK_A);
256 		keyCodeMap.put("b", KeyEvent.VK_B);
257 		keyCodeMap.put("c", KeyEvent.VK_C);
258 		keyCodeMap.put("d", KeyEvent.VK_D);
259 		keyCodeMap.put("e", KeyEvent.VK_E);
260 		keyCodeMap.put("f", KeyEvent.VK_F);
261 		keyCodeMap.put("g", KeyEvent.VK_G);
262 		keyCodeMap.put("h", KeyEvent.VK_H);
263 		keyCodeMap.put("i", KeyEvent.VK_I);
264 		keyCodeMap.put("j", KeyEvent.VK_J);
265 		keyCodeMap.put("k", KeyEvent.VK_K);
266 		keyCodeMap.put("l", KeyEvent.VK_L);
267 		keyCodeMap.put("m", KeyEvent.VK_M);
268 		keyCodeMap.put("n", KeyEvent.VK_N);
269 		keyCodeMap.put("o", KeyEvent.VK_O);
270 		keyCodeMap.put("p", KeyEvent.VK_P);
271 		keyCodeMap.put("q", KeyEvent.VK_Q);
272 		keyCodeMap.put("r", KeyEvent.VK_R);
273 		keyCodeMap.put("s", KeyEvent.VK_S);
274 		keyCodeMap.put("t", KeyEvent.VK_T);
275 		keyCodeMap.put("u", KeyEvent.VK_U);
276 		keyCodeMap.put("v", KeyEvent.VK_V);
277 		keyCodeMap.put("w", KeyEvent.VK_W);
278 		keyCodeMap.put("x", KeyEvent.VK_X);
279 		keyCodeMap.put("y", KeyEvent.VK_Y);
280 		keyCodeMap.put("z", KeyEvent.VK_Z);
281 		keyCodeMap.put("0", KeyEvent.VK_0);
282 		keyCodeMap.put("1", KeyEvent.VK_1);
283 		keyCodeMap.put("2", KeyEvent.VK_2);
284 		keyCodeMap.put("3", KeyEvent.VK_3);
285 		keyCodeMap.put("4", KeyEvent.VK_4);
286 		keyCodeMap.put("5", KeyEvent.VK_5);
287 		keyCodeMap.put("6", KeyEvent.VK_6);
288 		keyCodeMap.put("7", KeyEvent.VK_7);
289 		keyCodeMap.put("8", KeyEvent.VK_8);
290 		keyCodeMap.put("9", KeyEvent.VK_9);
291 		keyCodeMap.put("`", KeyEvent.VK_BACK_QUOTE);
292 		keyCodeMap.put("-", KeyEvent.VK_MINUS);
293 		keyCodeMap.put("=", KeyEvent.VK_EQUALS);
294 		keyCodeMap.put("[", KeyEvent.VK_OPEN_BRACKET);
295 		keyCodeMap.put("]", KeyEvent.VK_CLOSE_BRACKET);
296 		keyCodeMap.put("\\", KeyEvent.VK_BACK_SLASH);
297 		keyCodeMap.put(";", KeyEvent.VK_SEMICOLON);
298 		keyCodeMap.put("\'", KeyEvent.VK_QUOTE);
299 		keyCodeMap.put(",", KeyEvent.VK_COMMA);
300 		keyCodeMap.put(".", KeyEvent.VK_PERIOD);
301 		keyCodeMap.put("/", KeyEvent.VK_SLASH);
302 
303 
304 		String chars = "`1234567890-=qwertyuiop[]\\asdfghjkl;'zxcvbnm,./";
305 		String shiftChars = "~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:\"ZXCVBNM<>?";
306 		for(int i = 0; i < chars.length(); i++) {
chars.charAt(i)307 			keyMap.put(chars.charAt(i), new String[]{chars.substring(i, i + 1)});
shiftChars.charAt(i)308 			keyMap.put(shiftChars.charAt(i), new String[]{"shift", chars.substring(i, i + 1)});
309 		}
310 		keyMap.put(' ', new String[]{"space"});
311 		keyMap.put('\t', new String[]{"tab"});
312 	}
313 
setCustomizedShortcut(String name, String... keys)314     public static void setCustomizedShortcut(String name, String... keys) {
315     	customizedMap.put(name, keys);
316     }
317 
main(String[] args)318     public static void main(String[] args) {
319     	Tester.sleep(3);
320     	Tester.typeKeys("	 ");
321     }
322 }
323