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 complex.XUserInputInterception;
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.chart.XChartDocument;
39 import com.sun.star.frame.*;
40 import com.sun.star.lang.*;
41 import com.sun.star.lang.EventObject;
42 import com.sun.star.sheet.XSpreadsheetDocument;
43 import com.sun.star.text.XTextDocument;
44 import com.sun.star.uno.UnoRuntime;
45 import com.sun.star.uno.XInterface;
46 import com.sun.star.util.*;
47 import java.awt.Robot;
48 import java.awt.event.InputEvent;
49
50 import util.AccessibilityTools;
51 import util.SOfficeFactory;
52
53 // ---------- junit imports -----------------
54 import org.junit.After;
55 import org.junit.AfterClass;
56 import org.junit.Before;
57 import org.junit.BeforeClass;
58 import org.junit.Test;
59 import org.openoffice.test.OfficeConnection;
60 import static org.junit.Assert.*;
61 // ------------------------------------------
62 //-----------------------------------------------
63 /**
64 * This <CODE>ComplexTest</CODE> checks the interface
65 * <CODE>XUserInputInterception</CODE>. Therefore it creates a document,
66 * adds a mouse and a key listener onto the interface and fire the
67 * correspond events. If all listener works as expected the test resluts in
68 * <CODE>OK</CODE> status.
69 * @short Check the interface XUserInputIntercaption
70 * @descr checks is a simple way the interface XUserInputInteraction
71 */
72 public class EventTest {
73 //-------------------------------------------
74 // some const
75
76 //-------------------------------------------
77 // member
78
79 /** points to the global uno service manager. */
80 private XMultiServiceFactory m_xMSF = null;
81
82 /** indicates if the mousePressed event was called*/
83 private boolean m_mousePressed = false;
84 /** indicates if the mouseReleased event was called*/
85 private boolean m_mouseReleased = false;
86
87 /** indicates if the mousePressed event was called*/
88 private boolean m_keyPressed = false;
89 /** indicates if the mouseReleased event was called*/
90 private boolean m_keyReleased = false;
91
92 /** points to a global StarOffice factory */
93 private SOfficeFactory m_SOF = null;
94
95 /**
96 * define the miliseconds to wait until a <CODE>EventTrigger</CODE> thread should
97 * be finished with its work
98 */
99 final int m_threadWait = 3000;
100
101 //-------------------------------------------
102 // test environment
103
104 //-------------------------------------------
105 /**
106 * The test methods are:
107 * <ul>
108 * <li><CODE>checkTextDocument</CODE></LI>
109 * <li><CODE>checkCalcDocument</CODE></LI>
110 * <li><CODE>checkDrawDocument</CODE></LI>
111 * <li><CODE>checkImpressDocument</CODE></LI>
112 * <li><CODE>checkChartDocument</CODE></LI>
113 * <li><CODE>checkMathDocument</CODE></li>
114 * </ul>
115 * @short A function to tell the framework,
116 * which test functions are available.
117 * @return All test methods.
118 * @todo Think about selection of tests from outside ...
119 */
120 // public String[] getTestMethodNames() {
121 // return new String[]
122 // { "checkTextDocument",
123 // "checkCalcDocument",
124 // "checkDrawDocument",
125 // "checkImpressDocument",
126 // "checkChartDocument",
127 // "checkMathDocument",
128 // };
129 // }
130
131 //-------------------------------------------
132 /**
133 * creates the mebmer <CODE>m_xMSF</CODE> and <CODE>m_SOF</CODE>
134 * @short Create the environment for following tests.
135 * @descr create an empty test frame, where we can load
136 * different components inside.
137 */
before()138 @Before public void before() {
139 // get uno service manager from global test environment
140 m_xMSF = getMSF();
141
142 // create frame instance
143 try {
144 // get a soffice factory object
145 m_SOF = SOfficeFactory.getFactory(getMSF());
146
147 } catch(java.lang.Throwable ex) {
148 fail("Could not create the XUserInputInterception instance.");
149 }
150 }
151
152 //-------------------------------------------
153 /**
154 * closes the document
155 * @short close the document.
156 * @param xDoc the document to close
157 */
closeDoc(XInterface xDoc)158 public void closeDoc(XInterface xDoc) {
159 XCloseable xClose = UnoRuntime.queryInterface(XCloseable.class, xDoc);
160 try {
161 xClose.close(false);
162 } catch(com.sun.star.util.CloseVetoException exVeto) {
163 System.out.println("document couldn't be closed successfully.");
164 }
165 }
166
167 /**
168 * creates a text document and check the <CODE>XMouseClickHandler</CODE> and
169 * <CODE>XKeyHandler</CODE>
170 * @see com.sun.star.awt.XKeyHandler
171 * @see com.sun.star.awt.XMouseClickHandler
172 */
checkTextDocument()173 @Test public void checkTextDocument(){
174
175 XTextDocument xDoc = null;
176
177 try{
178 xDoc = m_SOF.createTextDoc("WriterTest");
179 } catch (com.sun.star.uno.Exception e){
180 fail("Could not create a text document: " +e.toString());
181 }
182
183 checkListener(xDoc);
184
185 closeDoc(xDoc);
186 }
187
188 /**
189 * creates an impress document and check the <CODE>XMouseClickHandler</CODE> and
190 * <CODE>XKeyHandler</CODE>
191 * @see com.sun.star.awt.XKeyHandler
192 * @see com.sun.star.awt.XMouseClickHandler
193 */
checkImpressDocument()194 @Test public void checkImpressDocument(){
195
196 XComponent xDoc = null;
197
198 try{
199 xDoc = m_SOF.createImpressDoc("ImpressTest");
200 } catch (com.sun.star.uno.Exception e){
201 fail("Could not create an impress document: " +e.toString());
202 }
203
204 checkListener(xDoc);
205
206 closeDoc(xDoc);
207 }
208
209 /**
210 * creates a chart document and check the <CODE>XMouseClickHandler</CODE> and
211 * <CODE>XKeyHandler</CODE>
212 * @see com.sun.star.awt.XKeyHandler
213 * @see com.sun.star.awt.XMouseClickHandler
214 */
215 // TODO!
216 // @Test public void checkChartDocument(){
217 //
218 // XChartDocument xDoc = null;
219 //
220 // try{
221 // xDoc = m_SOF.createChartDoc("ChartTest");
222 // } catch (com.sun.star.uno.Exception e){
223 // fail("Could not create a chart document: " +e.toString());
224 // }
225 //
226 // checkListener(xDoc);
227 //
228 // closeDoc(xDoc);
229 // }
230
231 /**
232 * creates a math document and check the <CODE>XMouseClickHandler</CODE> and
233 * <CODE>XKeyHandler</CODE>
234 * @see com.sun.star.awt.XKeyHandler
235 * @see com.sun.star.awt.XMouseClickHandler
236 */
checkMathDocument()237 @Test public void checkMathDocument(){
238
239 XComponent xDoc = null;
240
241 try{
242 xDoc = m_SOF.createMathDoc("MathTest");
243 } catch (com.sun.star.uno.Exception e){
244 fail("Could not create a math document: " +e.toString());
245 }
246
247 checkListener(xDoc);
248
249 closeDoc(xDoc);
250 }
251
252 /**
253 * creates a draw document and check the <CODE>XMouseClickHandler</CODE> and
254 * <CODE>XKeyHandler</CODE>
255 * @see com.sun.star.awt.XKeyHandler
256 * @see com.sun.star.awt.XMouseClickHandler
257 */
checkDrawDocument()258 @Test public void checkDrawDocument(){
259
260 XComponent xDoc = null;
261
262 try{
263 xDoc = m_SOF.createDrawDoc("DrawTest");
264 } catch (com.sun.star.uno.Exception e){
265 fail("Could not create a draw document: " +e.toString());
266 }
267
268 checkListener(xDoc);
269
270 closeDoc(xDoc);
271 }
272
273 /**
274 * creates a calc document and check the <CODE>XMouseClickHandler</CODE> and
275 * <CODE>XKeyHandler</CODE>
276 * @see com.sun.star.awt.XKeyHandler
277 * @see com.sun.star.awt.XMouseClickHandler
278 */
checkCalcDocument()279 @Test public void checkCalcDocument(){
280
281 XSpreadsheetDocument xDoc = null;
282
283 try{
284 xDoc = m_SOF.createCalcDoc("CalcTest");
285 } catch (com.sun.star.uno.Exception e){
286 fail("Could not create a calc document: " +e.toString());
287 }
288
289 checkListener(xDoc);
290 closeDoc(xDoc);
291 }
292
293 /**
294 * This is the central test method. It is called by ceck[DOCTYPE]Document. It
295 * creates the <CODE>XUserInputInterception</CODE> from the document and call the
296 * <CODE>checkMouseListener</CODE> test and the <CODE>checkKeyListener</CODE> test
297 * @param xDoc the document to test
298 */
checkListener(XInterface xDoc)299 private void checkListener(XInterface xDoc){
300
301 XModel xModel = UnoRuntime.queryInterface(XModel.class, xDoc);
302
303 XUserInputInterception xUII = getUII(xModel);
304
305 checkMouseListener(xUII, xModel);
306 checkKeyListener(xUII, xModel);
307 }
308
309 /**
310 * Creates a <CODE>MyKeyHandler</CODE> and adds it to the
311 * <CODE>XUserInputInterception</CODE>. Then an <CODE>EventTrigger</CODE> thread
312 * was created and started.
313 * Has <CODE>OK</CODE> if the members <CODE>m_keyPressed</CODE> and
314 * <CODE>m_keyReleased</CODE> are <CODE>TRUE</CODE>
315 * @param xUII the XUserInputInterception
316 * @param xModel the XModel of a document
317 * @see EventTest.MyKeyHandler
318 * @see EventTest.EventTrigger
319 */
checkKeyListener(XUserInputInterception xUII, XModel xModel)320 private void checkKeyListener(XUserInputInterception xUII, XModel xModel) {
321 m_keyPressed = false;
322 m_keyReleased = false;
323
324 MyKeyHandler keyListener = new MyKeyHandler();
325
326 xUII.addKeyHandler(keyListener);
327
328 System.out.println("starting thread to check the key listener...");
329 EventTrigger et = new EventTrigger(xModel, EventTriggerType.KEY_TEXT_INTO_DOC);
330
331 et.run();
332
333 util.utils.shortWait(m_threadWait);
334 System.out.println("key listener thread should be finished.");
335
336 assertTrue("key event does not work!", m_keyPressed && m_keyReleased);
337 xUII.removeKeyHandler(keyListener);
338
339 }
340
341 /**
342 * Creates a <CODE>MyMouseClickHandler</CODE> and adds it to the
343 * <CODE>XUserInputInterception</CODE>. Then an <CODE>EventTrigger</CODE> thread
344 * was created and started.
345 * Has <CODE>OK</CODE> if the members <CODE>m_mousePressed</CODE> and
346 * <CODE>m_mouseReleased</CODE> are <CODE>TRUE</CODE>
347 * @param xUII the XUserInputInterception
348 * @param xModel the XModel of a document
349 * @see EventTest.MyMouseClickHander
350 * @see EventTest.EventTrigger
351 */
352
checkMouseListener(XUserInputInterception xUII, XModel xModel)353 private void checkMouseListener(XUserInputInterception xUII, XModel xModel) {
354
355 m_mousePressed = false;
356 m_mouseReleased = false;
357
358 MyMouseClickHandler mouseListener = new MyMouseClickHandler();
359
360 xUII.addMouseClickHandler(mouseListener);
361
362 System.out.println("starting thread to check the mouse listener...");
363 EventTrigger et = new EventTrigger(xModel, EventTriggerType.MOUSE_KLICK_INTO_DOC);
364
365 et.run();
366
367 util.utils.shortWait(m_threadWait);
368 System.out.println("mouse listener thread should be finished.");
369
370 assertTrue("mouse event does not work!", m_mousePressed && m_mouseReleased);
371 xUII.removeMouseClickHandler(mouseListener);
372 }
373
374 /**
375 * returns the <CODE>XUserInputInterception</CODE> from the <CODE>XMdoel</CODE>
376 * @param xModel the XModel of a document
377 * @return the <CODE>XUserInputInterception</CODE> of the document
378 */
getUII(XModel xModel)379 private XUserInputInterception getUII(XModel xModel){
380
381 XController xController = xModel.getCurrentController();
382
383 XUserInputInterception xUII = UnoRuntime.queryInterface(XUserInputInterception.class, xController);
384 if (xUII == null) {
385 fail("could not get XUserInputInterception from XContoller");
386 }
387 return xUII;
388 }
389
390 /**
391 * Listener which added and its method must be called
392 * on <code>keyPressed</code> and <code>keyReleased</code> call.
393 */
394 public class MyKeyHandler implements XKeyHandler {
395 /**
396 * This event sets the member <code>m_keyPressed</coed> to
397 * <code>true</code>
398 * @param oEvent The key event informs about the pressed key.
399 * @return returns <CODE>TRUE</CODE> in erery case
400 */
keyPressed( KeyEvent oEvent )401 public boolean keyPressed( KeyEvent oEvent ){
402 System.out.println("XKeyHandler: keyPressed-Event");
403 m_keyPressed = true;
404 return true;
405 }
406 /**
407 * This event sets the member <code>m_keyReleased</coed> to
408 * <code>true</code>
409 * @param oEvent The key event informs about the pressed key.
410 * @return returns <CODE>TRUE</CODE> in erery case
411 */
keyReleased( KeyEvent oEvent )412 public boolean keyReleased( KeyEvent oEvent ){
413 System.out.println("XKeyHandler: keyReleased-Event");
414 m_keyReleased = true;
415 return true;
416 }
417 /**
418 * This event does nothing useful
419 * @param oEvent refers to the object that fired the event.
420 */
disposing( EventObject oEvent )421 public void disposing( EventObject oEvent ){
422 System.out.println("XKeyHandler: disposing-Event");
423 }
424 }
425
426 /**
427 * Listener which added and its method must be called
428 * on <code>mousePressed</code> and <code>mouseReleased</code> call.
429 */
430 public class MyMouseClickHandler implements XMouseClickHandler {
431 /**
432 * This event sets the member <code>m_mousePressed</coed> to
433 * <code>true</code>
434 * @param oEvent The mouse event informs about the kind of mouse event.
435 * @return returns <CODE>TRUE</CODE> in erery case
436 */
mousePressed( MouseEvent oEvent )437 public boolean mousePressed( MouseEvent oEvent ){
438 System.out.println("XMouseClickHandler: mousePressed-Event");
439 m_mousePressed = true;
440 return true;
441 }
442 /**
443 * This event sets the member <code>m_mouseReleased</coed> to
444 * <code>true</code>
445 * @param oEvent The mouse event informs about the kind of mouse event.
446 * @return returns <CODE>TRUE</CODE> in erery case
447 */
mouseReleased( MouseEvent oEvent )448 public boolean mouseReleased( MouseEvent oEvent ){
449 System.out.println("XMouseClickHandler: mouseReleased-Event");
450 m_mouseReleased = true;
451 return true;
452 }
453 /**
454 * This event does nothing useful
455 * @param oEvent refers to the object that fired the event.
456 */
disposing( EventObject oEvent )457 public void disposing( EventObject oEvent ){
458 System.out.println("XMouseClickHandler: disposing-Event");
459 }
460 };
461
462 /**
463 * To check the events this class is a thread which click a mouse button and
464 * press a key with the <CODE>Robot</CODE> class
465 * @see java.awt.Robot
466 */
467 private class EventTrigger extends Thread{
468
469 /**
470 * represents a <CODE>AccessibilityTools</CODE>
471 */
472 private final AccessibilityTools at = new AccessibilityTools();
473 /**
474 * represents an <CODE>EventType</CODE>
475 * @see EventTest.EventTriggerType
476 */
477 private int eventType = 0;
478 /**
479 * represents a <CODE>XModel</CODE> of a document
480 */
481 private XModel xModel = null;
482
483 /**
484 * Creates an instacne of this class. The parameter <CODE>eType</CODE> represents
485 * the kind of event which will be triggert at <CODE>run()</CODE>
486 * @param model the model of a document
487 * @param eType the kind of event which should be trigger
488 */
EventTrigger(XModel model, int eType)489 public EventTrigger(XModel model, int eType)
490 {
491 this.xModel = model;
492 this.eventType = eType;
493 }
494
495 /**
496 * Triggers the event which is represented by <CODE>eventType</CODE>
497 * The scenarios are:
498 * <ul>
499 * <li>EventTest.EventTriggerType.MOUSE_KLICK_INTO_DOC
500 * which calls
501 * <li><CODE>clickIntoDoc</CODE></LI>
502 * </LI>
503 * <li>EventTest.EventTriggerType.KEY_TEXT_INTO_DOC
504 * which calls
505 * <li><CODE>clickIntodoc</CODE></LI>
506 * <li><CODE>keyIntoDoc</CODE></LI>
507 * </LI>
508 * </UL>
509 */
run()510 public void run(){
511
512 switch (this.eventType){
513
514 case EventTriggerType.MOUSE_KLICK_INTO_DOC:
515 clickIntoDoc();
516 break;
517 case EventTriggerType.KEY_TEXT_INTO_DOC:
518 clickIntoDoc();
519 keyIntoDoc();
520 break;
521
522 }
523 }
524 /**
525 * This method cklicks into the middel of a document. It uses Accessibility
526 * to get the document and query for its position and its range to calculate
527 * the middle. This values was used for <CODE>Robot</CODE> Class. This
528 * Robot class is able to move the mouse and to cklick a mouse button
529 * @see java.awt.Robot
530 */
clickIntoDoc()531 private void clickIntoDoc(){
532 try{
533 // get the position and the range of a scroll bar
534
535 XWindow xWindow = at.getCurrentWindow(
536 getMSF(),
537 xModel);
538
539 XAccessible xRoot = at.getAccessibleObject(xWindow);
540
541
542
543 XAccessibleContext xPanel = at.getAccessibleObjectForRole(xRoot, AccessibleRole.PANEL);
544 XAccessibleComponent xPanelCont = UnoRuntime.queryInterface(XAccessibleComponent.class, xPanel);
545
546 // the position of the panel
547 Point point = xPanelCont.getLocationOnScreen();
548
549 // the range of the panel
550 Rectangle rect = xPanelCont.getBounds();
551
552 try {
553 Robot rob = new Robot();
554 int x = point.X + (rect.Width / 2);
555 int y = point.Y + (rect.Height / 2);
556 System.out.println("try to klick into the middle of the document");
557 rob.mouseMove(x, y);
558 rob.mousePress(InputEvent.BUTTON1_MASK);
559 rob.mouseRelease(InputEvent.BUTTON1_MASK);
560 } catch (java.awt.AWTException e) {
561 System.out.println("couldn't press mouse button");
562 }
563 } catch (java.lang.Exception e){
564 System.out.println("could not click into the scroll bar: " + e.toString());
565 }
566 }
567
568 /**
569 * This method press the "A" key. Therefore it uses the <CODE>Robot</CODE>
570 * class.
571 * @see java.awt.Robot
572 */
keyIntoDoc()573 private void keyIntoDoc(){
574 try {
575 Robot rob = new Robot();
576 System.out.println("try to press 'A'");
577 rob.keyPress(java.awt.event.KeyEvent.VK_A);
578 rob.keyRelease(java.awt.event.KeyEvent.VK_A);
579 } catch (java.awt.AWTException e) {
580 System.out.println("couldn't press key");
581 }
582
583 }
584 }
585
586 /** This interface represents all possible actions which could be used
587 * in the <CODE>EventTrigger</CODE> class.
588 * @see EventTest.EventTrigger
589 */
590 private interface EventTriggerType{
591
592 /** klick the mouse into the scroll bar*/
593 final public static int MOUSE_KLICK_INTO_DOC = 1;
594
595 /** write some text into a spread sheet*/
596 final public static int KEY_TEXT_INTO_DOC = 2;
597 }
598
599
600
601
getMSF()602 private XMultiServiceFactory getMSF()
603 {
604 final XMultiServiceFactory xMSF1 = UnoRuntime.queryInterface(XMultiServiceFactory.class, connection.getComponentContext().getServiceManager());
605 return xMSF1;
606 }
607
608 // setup and close connections
setUpConnection()609 @BeforeClass public static void setUpConnection() throws Exception {
610 System.out.println("setUpConnection()");
611 connection.setUp();
612 }
613
tearDownConnection()614 @AfterClass public static void tearDownConnection()
615 throws InterruptedException, com.sun.star.uno.Exception
616 {
617 System.out.println("tearDownConnection()");
618 connection.tearDown();
619 }
620
621 private static final OfficeConnection connection = new OfficeConnection();
622
623 }
624