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