1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 package ifc.awt; 29 30 import com.sun.star.accessibility.AccessibleRole; 31 import com.sun.star.accessibility.XAccessible; 32 import com.sun.star.accessibility.XAccessibleComponent; 33 import com.sun.star.accessibility.XAccessibleContext; 34 import com.sun.star.awt.KeyEvent; 35 import com.sun.star.awt.MouseEvent; 36 import com.sun.star.awt.Point; 37 import com.sun.star.awt.Rectangle; 38 import com.sun.star.awt.XKeyHandler; 39 import com.sun.star.awt.XMouseClickHandler; 40 import com.sun.star.awt.XUserInputInterception; 41 import com.sun.star.awt.XWindow; 42 import com.sun.star.frame.XModel; 43 import com.sun.star.lang.EventObject; 44 import com.sun.star.lang.XMultiServiceFactory; 45 import com.sun.star.uno.UnoRuntime; 46 import java.awt.Robot; 47 import java.awt.event.InputEvent; 48 import lib.MultiMethodTest; 49 import util.AccessibilityTools; 50 51 /** 52 * Testing <code>com.sun.star.awt.XUserInputInterception</code> 53 * interface methods: 54 * <ul> 55 * <li><code> addKeyHandler() </code></li> 56 * <li><code> removeKeyHandler() </code></li> 57 * <li><code> addMouseClickHandler() </code></li> 58 * <li><code> removeMouseClickHandler() </code></li> 59 * </ul><p> 60 * This test needs the following object relations : 61 * <ul> 62 * <li> <code>'XUserInputInterception.XModel'</code> (of type <code>XModel</code>): 63 * used as model where a mouse click or a key press could be done </li> 64 * </ul> <p> 65 * Test is <b> NOT </b> multithread compilant. <p> 66 * @see com.sun.star.awt.XUserInputInterception 67 */ 68 public class _XUserInputInterception extends MultiMethodTest { 69 public XUserInputInterception oObj = null; 70 71 private XModel m_XModel = null; 72 73 /** the listener 1 for the mouse click test */ 74 private MyMouseClickHandler1 m_MouseListener1 = null; 75 /** the listener 2 for the mouse click test */ 76 private MyMouseClickHandler2 m_MouseListener2 = null; 77 78 /** the listener 1 for the key event test */ 79 private MyKeyHandler1 m_KeyListener1 = null; 80 /** the listener 2 for the key event test */ 81 private MyKeyHandler2 m_KeyListener2 = null; 82 83 /** indicates if the mousePressed event was called*/ 84 private boolean m_mousePressed1 = false; 85 /** indicates if the mouseReleased event was called*/ 86 private boolean m_mouseReleased1 = false; 87 88 /** indicates if the mousePressed event was called*/ 89 private boolean m_mousePressed2 = false; 90 /** indicates if the mouseReleased event was called*/ 91 private boolean m_mouseReleased2 = false; 92 93 /** indicates if the mousePressed event was called*/ 94 private boolean m_keyPressed1 = false; 95 /** indicates if the mouseReleased event was called*/ 96 private boolean m_keyReleased1 = false; 97 98 /** indicates if the mousePressed event was called*/ 99 private boolean m_keyPressed2 = false; 100 /** indicates if the mouseReleased event was called*/ 101 private boolean m_keyReleased2 = false; 102 103 /** get the object rlation XUserInputInterception.XModel from the 104 * test environment 105 */ 106 protected void before() { 107 log.print("try to get object relation 'XUserInputInterception.XModel': "); 108 m_XModel = (XModel)tEnv.getObjRelation("XUserInputInterception.XModel"); 109 if (m_XModel == null) log.println("failed => null"); 110 else log.println("OK"); 111 112 } 113 114 /** 115 * This test adds two different key listener to the object. <p> 116 * 117 * Has <b> OK </b> if no exception is thrown. 118 */ 119 public void _addKeyHandler() { 120 121 log.println("creating key listener 1"); 122 m_KeyListener1 = new MyKeyHandler1(); 123 124 log.println("creating key listener 2"); 125 m_KeyListener2 = new MyKeyHandler2(); 126 127 128 log.println("adding key listener 1"); 129 oObj.addKeyHandler(m_KeyListener1); 130 131 132 log.println("adding key listener 2"); 133 oObj.addKeyHandler(m_KeyListener2); 134 135 tRes.tested("addKeyHandler()", true); 136 } 137 138 /** 139 * The test requires <CODE>addKeyHandler()</CODE> which adds two key listener. 140 * Then one of them will be removed. In a second thread a key event is released 141 * by the <CODE>robot</CODE> class.<p> 142 * Has <b> OK </b> status if only one of the listener are triggered. <p> 143 * The following method tests are to be completed successfully before : 144 * <ul> 145 * <li> <code> addKeyHandler() </code> : adds two key listener </li> 146 * </ul> 147 */ 148 public void _removeKeyHandler() { 149 requiredMethod("addKeyHandler()"); 150 151 log.println("remove key listener 2"); 152 153 oObj.removeKeyHandler(m_KeyListener2); 154 155 log.println("starting thread to check the key listener..."); 156 EventTrigger et = new EventTrigger(m_XModel, EventTriggerType.KEY_TEXT_INTO_DOC); 157 158 et.run(); 159 160 util.utils.shortWait(tParam.getInt(util.PropertyName.SHORT_WAIT) * 2); 161 log.println("key listener thread should be finished."); 162 163 164 boolean bOK = m_keyPressed1 & m_keyReleased1 & 165 ! m_keyPressed2 & ! m_keyReleased2; 166 167 if (! bOK){ 168 log.println("The key listener has not the expectd status:"); 169 log.println("listener\texpected\tgot"); 170 log.println("keyPressed1\ttrue\t"+m_keyPressed1); 171 log.println("keyReleased1\ttrue\t"+m_keyReleased1); 172 log.println("keyPressed2\tfalse\t"+m_keyPressed2); 173 log.println("keyReleased2\tfalse\t"+m_keyReleased2); 174 } 175 176 log.println("remove Key listener 1"); 177 oObj.removeKeyHandler(m_KeyListener1); 178 179 tRes.tested("removeKeyHandler()", bOK); 180 } 181 182 /** 183 * This test adds two different mouse klick listener to the object. <p> 184 * 185 * Has <b> OK </b> if no exception is thrown. 186 */ 187 public void _addMouseClickHandler() { 188 log.println("creating mouse listener 1"); 189 m_MouseListener1 = new MyMouseClickHandler1(); 190 log.println("creating mouse listener 2"); 191 m_MouseListener2 = new MyMouseClickHandler2(); 192 193 log.println("adding mouse listener 1"); 194 oObj.addMouseClickHandler(m_MouseListener1); 195 log.println("adding mouse listener 2"); 196 oObj.addMouseClickHandler(m_MouseListener2); 197 198 tRes.tested("addMouseClickHandler()", true); 199 } 200 201 /** 202 * The test requires <CODE>addMouseClickHandler()</CODE> which adds two key listener. 203 * Then one of them will be removed. In a second thread a mouse klick event is released 204 * by the <CODE>robot</CODE> class.<p> 205 * Has <b> OK </b> status if only one of the listener are triggered. <p> 206 * The following method tests are to be completed successfully before : 207 * <ul> 208 * <li> <code> addMouseKlickHandler() </code> : adds two key listener </li> 209 * </ul> 210 */ 211 public void _removeMouseClickHandler() { 212 requiredMethod("addMouseClickHandler"); 213 214 log.println("remove mouse listener 2"); 215 216 oObj.removeMouseClickHandler(m_MouseListener2); 217 218 log.println("starting thread to check the mouse listener..."); 219 EventTrigger et = new EventTrigger(m_XModel, EventTriggerType.MOUSE_KLICK_INTO_DOC); 220 221 et.run(); 222 223 util.utils.shortWait(tParam.getInt(util.PropertyName.SHORT_WAIT) * 2); 224 log.println("mouse listener thread should be finished."); 225 226 boolean bOK = m_mousePressed1 & m_mouseReleased1 & 227 ! m_mousePressed2 & ! m_mouseReleased2; 228 229 if (! bOK){ 230 log.println("The mouse listener has not the expectd status:"); 231 log.println("listener\t\texpected\tgot"); 232 log.println("mousePressed1\ttrue\t\t"+m_mousePressed1); 233 log.println("mouseReleased1\ttrue\t\t"+m_mouseReleased1); 234 log.println("mousePressed2\tfalse\t\t"+m_mousePressed2); 235 log.println("mouseReleased2\tfalse\t\t"+m_mouseReleased2); 236 } 237 238 log.println("remove mouse listener 1"); 239 oObj.removeMouseClickHandler(m_MouseListener1); 240 241 tRes.tested("removeMouseClickHandler()", bOK); 242 } 243 244 245 /** 246 * Forces environment recreation. 247 */ 248 protected void after() { 249 disposeEnvironment(); 250 } 251 252 /** 253 * Listener which added and its method must be called 254 * on <code>keyPressed</code> and <code>keyReleased</code> call. 255 */ 256 public class MyKeyHandler1 implements XKeyHandler { 257 /** 258 * This event sets the member <code>m_keyPressed</coed> to 259 * <code>true</code> 260 * @param oEvent The key event informs about the pressed key. 261 * @return returns <CODE>TRUE</CODE> in erery case 262 */ 263 public boolean keyPressed( KeyEvent oEvent ){ 264 log.println("XKeyHandler 1: keyPressed-Event"); 265 m_keyPressed1 = true; 266 return true; 267 } 268 /** 269 * This event sets the member <code>m_keyReleased</coed> to 270 * <code>true</code> 271 * @param oEvent The key event informs about the pressed key. 272 * @return returns <CODE>TRUE</CODE> in erery case 273 */ 274 public boolean keyReleased( KeyEvent oEvent ){ 275 log.println("XKeyHandler 1: keyReleased-Event"); 276 m_keyReleased1 = true; 277 return true; 278 } 279 /** 280 * This event does nothing usefull 281 * @param oEvent refers to the object that fired the event. 282 */ 283 public void disposing( EventObject oEvent ){ 284 log.println("XKeyHandler 1: disposing-Event"); 285 } 286 } 287 /** 288 * Listener which added and its method must be called 289 * on <code>keyPressed</code> and <code>keyReleased</code> call. 290 */ 291 public class MyKeyHandler2 implements XKeyHandler { 292 /** 293 * This event sets the member <code>m_keyPressed</coed> to 294 * <code>true</code> 295 * @param oEvent The key event informs about the pressed key. 296 * @return returns <CODE>TRUE</CODE> in erery case 297 */ 298 public boolean keyPressed( KeyEvent oEvent ){ 299 log.println("XKeyHandler 2: keyPressed-Event: " + 300 "This should not be happen because listener is removed!"); 301 m_keyPressed2 = true; 302 return true; 303 } 304 /** 305 * This event sets the member <code>m_keyReleased</coed> to 306 * <code>true</code> 307 * @param oEvent The key event informs about the pressed key. 308 * @return returns <CODE>TRUE</CODE> in erery case 309 */ 310 public boolean keyReleased( KeyEvent oEvent ){ 311 log.println("XKeyHandler 2: keyReleased-Event: " + 312 "This should not be happen because listener is removed!"); 313 m_keyReleased2 = true; 314 return true; 315 } 316 /** 317 * This event does nothing usefull 318 * @param oEvent refers to the object that fired the event. 319 */ 320 public void disposing( EventObject oEvent ){ 321 log.println("XKeyHandler 2: disposing-Event: " + 322 "This should not be happen because listener is removed!"); 323 } 324 } 325 326 /** 327 * Listener which added and its method must be called 328 * on <code>mousePressed</code> and <code>mouseReleased</code> call. 329 */ 330 public class MyMouseClickHandler1 implements XMouseClickHandler { 331 /** 332 * This event sets the member <code>m_mousePressed</coed> to 333 * <code>true</code> 334 * @param oEvent The mouse event informs about the kind of mouse event. 335 * @return returns <CODE>TRUE</CODE> in erery case 336 */ 337 public boolean mousePressed( MouseEvent oEvent ){ 338 log.println("XMouseClickHandler 1: mousePressed-Event"); 339 m_mousePressed1 = true; 340 return true; 341 } 342 /** 343 * This event sets the member <code>m_mouseReleased</coed> to 344 * <code>true</code> 345 * @param oEvent The mouse event informs about the kind of mouse event. 346 * @return returns <CODE>TRUE</CODE> in erery case 347 */ 348 public boolean mouseReleased( MouseEvent oEvent ){ 349 log.println("XMouseClickHandler 1: mouseReleased-Event"); 350 m_mouseReleased1 = true; 351 return true; 352 } 353 /** 354 * This event does nothing usefull 355 * @param oEvent refers to the object that fired the event. 356 */ 357 public void disposing( EventObject oEvent ){ 358 log.println("XMouseClickHandler 1: disposing-Event"); 359 } 360 }; 361 362 /** 363 * Listener which added and removed. Its method must NOT be called 364 * on <code>mousePressed</code> and <code>mouseReleased</code> call. 365 */ 366 public class MyMouseClickHandler2 implements XMouseClickHandler { 367 /** 368 * This event sets the member <code>m_mousePressed</coed> to 369 * <code>true</code> 370 * @param oEvent The mouse event informs about the kind of mouse event. 371 * @return returns <CODE>TRUE</CODE> in erery case 372 */ 373 public boolean mousePressed( MouseEvent oEvent ){ 374 log.println("XMouseClickHandler 2: mousePressed-Event: " + 375 "This should not be happen because listener is removed!"); 376 m_mousePressed2 = true; 377 return true; 378 } 379 /** 380 * This event sets the member <code>m_mouseReleased</coed> to 381 * <code>true</code> 382 * @param oEvent The mouse event informs about the kind of mouse event. 383 * @return returns <CODE>TRUE</CODE> in erery case 384 */ 385 public boolean mouseReleased( MouseEvent oEvent ){ 386 log.println("XMouseClickHandler 2: mouseReleased-Event: " + 387 "This should not be happen because listener is removed!"); 388 m_mouseReleased2 = true; 389 return true; 390 } 391 /** 392 * This event does nothing usefull 393 * @param oEvent refers to the object that fired the event. 394 */ 395 public void disposing( EventObject oEvent ){ 396 log.println("XMouseClickHandler 2: disposing-Event: " + 397 " This should not be happen because listener is removed!"); 398 } 399 }; 400 401 /** 402 * To check the events this class is a thread which click a mouse button and 403 * press a key with the <CODE>Robot</CODE> class 404 * @see java.awt.Robot 405 */ 406 private class EventTrigger extends Thread{ 407 408 /** 409 * represents a <CODE>AccessibilityTools</CODE> 410 */ 411 private final AccessibilityTools at = new AccessibilityTools(); 412 /** 413 * represents an <CODE>EventType</CODE> 414 * @see EventTest.EventTriggerType 415 */ 416 private int eventType = 0; 417 /** 418 * represents a <CODE>XModel</CODE> of a document 419 */ 420 private XModel xModel = null; 421 422 /** 423 * Creates an instacne of this class. The parameter <CODE>eType</CODE> represents 424 * the kind of event wich will be triggert at <CODE>run()</CODE> 425 * @param model the model of a document 426 * @param eType the kind of event which should be trigger 427 */ 428 public EventTrigger(XModel model, int eType) 429 { 430 this.xModel = model; 431 this.eventType = eType; 432 } 433 434 /** 435 * Triggers the event wich is represented by <CODE>eventType</CODE> 436 * The scenarios are: 437 * <ul> 438 * <li>EventTest.EventTriggerType.MOUSE_KLICK_INTO_DOC 439 * which calls 440 * <li><CODE>clickIntoDoc</CODE></LI> 441 * </LI> 442 * <li>EventTest.EventTriggerType.KEY_TEXT_INTO_DOC 443 * which calls 444 * <li><CODE>clickIntodoc</CODE></LI> 445 * <li><CODE>keyIntoDoc</CODE></LI> 446 * </LI> 447 * </UL> 448 */ 449 public void run(){ 450 451 switch (this.eventType){ 452 453 case EventTriggerType.MOUSE_KLICK_INTO_DOC: 454 clickIntoDoc(); 455 break; 456 case EventTriggerType.KEY_TEXT_INTO_DOC: 457 clickIntoDoc(); 458 keyIntoDoc(); 459 break; 460 461 } 462 } 463 /** 464 * This method cklicks into the middel of a document. It uses Accessibility 465 * to get the document and query for its position and its range to calculate 466 * the middle. This values was used for <CODE>Robot</CODE> Class. This 467 * Robot class is able to move the mouse and to cklick a mouse button 468 * @see java.awt.Robot 469 */ 470 private void clickIntoDoc(){ 471 try{ 472 473 util.DesktopTools.bringWindowToFront(xModel); 474 475 XWindow xWindow = at.getCurrentWindow( 476 (XMultiServiceFactory) tParam.getMSF(), 477 xModel); 478 479 XAccessible xRoot = at.getAccessibleObject(xWindow); 480 481 482 483 XAccessibleContext xPanel = at.getAccessibleObjectForRole(xRoot, AccessibleRole.PANEL); 484 XAccessibleComponent xPanelCont = (XAccessibleComponent) UnoRuntime.queryInterface(XAccessibleComponent.class, xPanel); 485 486 // the position of the panel 487 Point point = xPanelCont.getLocationOnScreen(); 488 489 // the range of the panel 490 Rectangle rect = xPanelCont.getBounds(); 491 492 try { 493 Robot rob = new Robot(); 494 int x = point.X + (rect.Width / 2); 495 int y = point.Y + (rect.Height / 2); 496 log.println("try to klick into the middle of the document"); 497 rob.mouseMove(x, y); 498 rob.mousePress(InputEvent.BUTTON1_MASK); 499 rob.mouseRelease(InputEvent.BUTTON1_MASK); 500 } catch (java.awt.AWTException e) { 501 log.println("couldn't press mouse button"); 502 } 503 } catch (java.lang.Exception e){ 504 log.println("could not click into the scroll bar: " + e.toString()); 505 } 506 } 507 508 /** 509 * This method press the "A" key. Therefore it uses the <CODE>Robot</CODE> 510 * class. 511 * @see java.awt.Robot 512 */ 513 private void keyIntoDoc(){ 514 try { 515 Robot rob = new Robot(); 516 log.println("try to press 'A'"); 517 rob.keyPress(java.awt.event.KeyEvent.VK_A); 518 rob.keyRelease(java.awt.event.KeyEvent.VK_A); 519 } catch (java.awt.AWTException e) { 520 log.println("couldn't press key"); 521 } 522 523 } 524 } 525 526 /** This interface represents all possible actions which could be used 527 * in the <CODE>EventTrigger</CODE> class. 528 * @see EventTest.EventTrigger 529 */ 530 private interface EventTriggerType{ 531 532 /** klick the mouse into the scroll bar*/ 533 final public static int MOUSE_KLICK_INTO_DOC = 1; 534 535 /** write some text into a spread sheet*/ 536 final public static int KEY_TEXT_INTO_DOC = 2; 537 } 538 } 539 540