| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| package complex.XUserInputInterception; |
| |
| import com.sun.star.accessibility.AccessibleRole; |
| import com.sun.star.accessibility.XAccessible; |
| import com.sun.star.accessibility.XAccessibleComponent; |
| import com.sun.star.accessibility.XAccessibleContext; |
| import com.sun.star.awt.KeyEvent; |
| import com.sun.star.awt.MouseEvent; |
| import com.sun.star.awt.Point; |
| import com.sun.star.awt.Rectangle; |
| import com.sun.star.awt.XKeyHandler; |
| import com.sun.star.awt.XMouseClickHandler; |
| import com.sun.star.awt.XUserInputInterception; |
| import com.sun.star.awt.XWindow; |
| import com.sun.star.chart.XChartDocument; |
| import com.sun.star.frame.*; |
| import com.sun.star.lang.*; |
| import com.sun.star.lang.EventObject; |
| import com.sun.star.sheet.XSpreadsheetDocument; |
| import com.sun.star.text.XTextDocument; |
| import com.sun.star.uno.UnoRuntime; |
| import com.sun.star.uno.XInterface; |
| import com.sun.star.util.*; |
| import java.awt.Robot; |
| import java.awt.event.InputEvent; |
| |
| import util.AccessibilityTools; |
| import util.SOfficeFactory; |
| |
| // ---------- junit imports ----------------- |
| import org.junit.After; |
| import org.junit.AfterClass; |
| import org.junit.Before; |
| import org.junit.BeforeClass; |
| import org.junit.Test; |
| import org.openoffice.test.OfficeConnection; |
| import static org.junit.Assert.*; |
| // ------------------------------------------ |
| //----------------------------------------------- |
| /** |
| * This <CODE>ComplexTest</CODE> checks the interface |
| * <CODE>XUserInputInterception</CODE>. Therefore it creates a document, |
| * adds a mouse and a key listener onto the interface and fire the |
| * correspond events. If all listener works as expected the test resluts in |
| * <CODE>OK</CODE> status. |
| * @short Check the interface XUserInputIntercaption |
| * @descr checks is a simple way the interface XUserInputInteraction |
| */ |
| public class EventTest { |
| //------------------------------------------- |
| // some const |
| |
| //------------------------------------------- |
| // member |
| |
| /** points to the global uno service manager. */ |
| private XMultiServiceFactory m_xMSF = null; |
| |
| /** indicates if the mousePressed event was called*/ |
| private boolean m_mousePressed = false; |
| /** indicates if the mouseReleased event was called*/ |
| private boolean m_mouseReleased = false; |
| |
| /** indicates if the mousePressed event was called*/ |
| private boolean m_keyPressed = false; |
| /** indicates if the mouseReleased event was called*/ |
| private boolean m_keyReleased = false; |
| |
| /** points to a global StarOffice factory */ |
| private SOfficeFactory m_SOF = null; |
| |
| /** |
| * define the miliseconds to wait until a <CODE>EventTrigger</CODE> thread should |
| * be finished with its work |
| */ |
| final int m_threadWait = 3000; |
| |
| //------------------------------------------- |
| // test environment |
| |
| //------------------------------------------- |
| /** |
| * The test methods are: |
| * <ul> |
| * <li><CODE>checkTextDocument</CODE></LI> |
| * <li><CODE>checkCalcDocument</CODE></LI> |
| * <li><CODE>checkDrawDocument</CODE></LI> |
| * <li><CODE>checkImpressDocument</CODE></LI> |
| * <li><CODE>checkChartDocument</CODE></LI> |
| * <li><CODE>checkMathDocument</CODE></li> |
| * </ul> |
| * @short A function to tell the framework, |
| * which test functions are available. |
| * @return All test methods. |
| * @todo Think about selection of tests from outside ... |
| */ |
| // public String[] getTestMethodNames() { |
| // return new String[] |
| // { "checkTextDocument", |
| // "checkCalcDocument", |
| // "checkDrawDocument", |
| // "checkImpressDocument", |
| // "checkChartDocument", |
| // "checkMathDocument", |
| // }; |
| // } |
| |
| //------------------------------------------- |
| /** |
| * creates the mebmer <CODE>m_xMSF</CODE> and <CODE>m_SOF</CODE> |
| * @short Create the environment for following tests. |
| * @descr create an empty test frame, where we can load |
| * different components inside. |
| */ |
| @Before public void before() { |
| // get uno service manager from global test environment |
| m_xMSF = getMSF(); |
| |
| // create frame instance |
| try { |
| // get a soffice factory object |
| m_SOF = SOfficeFactory.getFactory(getMSF()); |
| |
| } catch(java.lang.Throwable ex) { |
| fail("Could not create the XUserInputInterception instance."); |
| } |
| } |
| |
| //------------------------------------------- |
| /** |
| * closes the document |
| * @short close the document. |
| * @param xDoc the document to close |
| */ |
| public void closeDoc(XInterface xDoc) { |
| XCloseable xClose = UnoRuntime.queryInterface(XCloseable.class, xDoc); |
| try { |
| xClose.close(false); |
| } catch(com.sun.star.util.CloseVetoException exVeto) { |
| System.out.println("document couldn't be closed successfully."); |
| } |
| } |
| |
| /** |
| * creates a text document and check the <CODE>XMouseClickHandler</CODE> and |
| * <CODE>XKeyHandler</CODE> |
| * @see com.sun.star.awt.XKeyHandler |
| * @see com.sun.star.awt.XMouseClickHandler |
| */ |
| @Test public void checkTextDocument(){ |
| |
| XTextDocument xDoc = null; |
| |
| try{ |
| xDoc = m_SOF.createTextDoc("WriterTest"); |
| } catch (com.sun.star.uno.Exception e){ |
| fail("Could not create a text document: " +e.toString()); |
| } |
| |
| checkListener(xDoc); |
| |
| closeDoc(xDoc); |
| } |
| |
| /** |
| * creates an impress document and check the <CODE>XMouseClickHandler</CODE> and |
| * <CODE>XKeyHandler</CODE> |
| * @see com.sun.star.awt.XKeyHandler |
| * @see com.sun.star.awt.XMouseClickHandler |
| */ |
| @Test public void checkImpressDocument(){ |
| |
| XComponent xDoc = null; |
| |
| try{ |
| xDoc = m_SOF.createImpressDoc("ImpressTest"); |
| } catch (com.sun.star.uno.Exception e){ |
| fail("Could not create an impress document: " +e.toString()); |
| } |
| |
| checkListener(xDoc); |
| |
| closeDoc(xDoc); |
| } |
| |
| /** |
| * creates a chart document and check the <CODE>XMouseClickHandler</CODE> and |
| * <CODE>XKeyHandler</CODE> |
| * @see com.sun.star.awt.XKeyHandler |
| * @see com.sun.star.awt.XMouseClickHandler |
| */ |
| // TODO! |
| // @Test public void checkChartDocument(){ |
| // |
| // XChartDocument xDoc = null; |
| // |
| // try{ |
| // xDoc = m_SOF.createChartDoc("ChartTest"); |
| // } catch (com.sun.star.uno.Exception e){ |
| // fail("Could not create a chart document: " +e.toString()); |
| // } |
| // |
| // checkListener(xDoc); |
| // |
| // closeDoc(xDoc); |
| // } |
| |
| /** |
| * creates a math document and check the <CODE>XMouseClickHandler</CODE> and |
| * <CODE>XKeyHandler</CODE> |
| * @see com.sun.star.awt.XKeyHandler |
| * @see com.sun.star.awt.XMouseClickHandler |
| */ |
| @Test public void checkMathDocument(){ |
| |
| XComponent xDoc = null; |
| |
| try{ |
| xDoc = m_SOF.createMathDoc("MathTest"); |
| } catch (com.sun.star.uno.Exception e){ |
| fail("Could not create a math document: " +e.toString()); |
| } |
| |
| checkListener(xDoc); |
| |
| closeDoc(xDoc); |
| } |
| |
| /** |
| * creates a draw document and check the <CODE>XMouseClickHandler</CODE> and |
| * <CODE>XKeyHandler</CODE> |
| * @see com.sun.star.awt.XKeyHandler |
| * @see com.sun.star.awt.XMouseClickHandler |
| */ |
| @Test public void checkDrawDocument(){ |
| |
| XComponent xDoc = null; |
| |
| try{ |
| xDoc = m_SOF.createDrawDoc("DrawTest"); |
| } catch (com.sun.star.uno.Exception e){ |
| fail("Could not create a draw document: " +e.toString()); |
| } |
| |
| checkListener(xDoc); |
| |
| closeDoc(xDoc); |
| } |
| |
| /** |
| * creates a calc document and check the <CODE>XMouseClickHandler</CODE> and |
| * <CODE>XKeyHandler</CODE> |
| * @see com.sun.star.awt.XKeyHandler |
| * @see com.sun.star.awt.XMouseClickHandler |
| */ |
| @Test public void checkCalcDocument(){ |
| |
| XSpreadsheetDocument xDoc = null; |
| |
| try{ |
| xDoc = m_SOF.createCalcDoc("CalcTest"); |
| } catch (com.sun.star.uno.Exception e){ |
| fail("Could not create a calc document: " +e.toString()); |
| } |
| |
| checkListener(xDoc); |
| closeDoc(xDoc); |
| } |
| |
| /** |
| * This is the central test method. It is called by ceck[DOCTYPE]Document. It |
| * creates the <CODE>XUserInputInterception</CODE> from the document and call the |
| * <CODE>checkMouseListener</CODE> test and the <CODE>checkKeyListener</CODE> test |
| * @param xDoc the document to test |
| */ |
| private void checkListener(XInterface xDoc){ |
| |
| XModel xModel = UnoRuntime.queryInterface(XModel.class, xDoc); |
| |
| XUserInputInterception xUII = getUII(xModel); |
| |
| checkMouseListener(xUII, xModel); |
| checkKeyListener(xUII, xModel); |
| } |
| |
| /** |
| * Creates a <CODE>MyKeyHandler</CODE> and adds it to the |
| * <CODE>XUserInputInterception</CODE>. Then an <CODE>EventTrigger</CODE> thread |
| * was created and started. |
| * Has <CODE>OK</CODE> if the members <CODE>m_keyPressed</CODE> and |
| * <CODE>m_keyReleased</CODE> are <CODE>TRUE</CODE> |
| * @param xUII the XUserInputInterception |
| * @param xModel the XModel of a document |
| * @see EventTest.MyKeyHandler |
| * @see EventTest.EventTrigger |
| */ |
| private void checkKeyListener(XUserInputInterception xUII, XModel xModel) { |
| m_keyPressed = false; |
| m_keyReleased = false; |
| |
| MyKeyHandler keyListener = new MyKeyHandler(); |
| |
| xUII.addKeyHandler(keyListener); |
| |
| System.out.println("starting thread to check the key listener..."); |
| EventTrigger et = new EventTrigger(xModel, EventTriggerType.KEY_TEXT_INTO_DOC); |
| |
| et.run(); |
| |
| util.utils.shortWait(m_threadWait); |
| System.out.println("key listener thread should be finished."); |
| |
| assertTrue("key event does not work!", m_keyPressed && m_keyReleased); |
| xUII.removeKeyHandler(keyListener); |
| |
| } |
| |
| /** |
| * Creates a <CODE>MyMouseClickHandler</CODE> and adds it to the |
| * <CODE>XUserInputInterception</CODE>. Then an <CODE>EventTrigger</CODE> thread |
| * was created and started. |
| * Has <CODE>OK</CODE> if the members <CODE>m_mousePressed</CODE> and |
| * <CODE>m_mouseReleased</CODE> are <CODE>TRUE</CODE> |
| * @param xUII the XUserInputInterception |
| * @param xModel the XModel of a document |
| * @see EventTest.MyMouseClickHander |
| * @see EventTest.EventTrigger |
| */ |
| |
| private void checkMouseListener(XUserInputInterception xUII, XModel xModel) { |
| |
| m_mousePressed = false; |
| m_mouseReleased = false; |
| |
| MyMouseClickHandler mouseListener = new MyMouseClickHandler(); |
| |
| xUII.addMouseClickHandler(mouseListener); |
| |
| System.out.println("starting thread to check the mouse listener..."); |
| EventTrigger et = new EventTrigger(xModel, EventTriggerType.MOUSE_KLICK_INTO_DOC); |
| |
| et.run(); |
| |
| util.utils.shortWait(m_threadWait); |
| System.out.println("mouse listener thread should be finished."); |
| |
| assertTrue("mouse event does not work!", m_mousePressed && m_mouseReleased); |
| xUII.removeMouseClickHandler(mouseListener); |
| } |
| |
| /** |
| * returns the <CODE>XUserInputInterception</CODE> from the <CODE>XMdoel</CODE> |
| * @param xModel the XModel of a document |
| * @return the <CODE>XUserInputInterception</CODE> of the document |
| */ |
| private XUserInputInterception getUII(XModel xModel){ |
| |
| XController xController = xModel.getCurrentController(); |
| |
| XUserInputInterception xUII = UnoRuntime.queryInterface(XUserInputInterception.class, xController); |
| if (xUII == null) { |
| fail("could not get XUserInputInterception from XContoller"); |
| } |
| return xUII; |
| } |
| |
| /** |
| * Listener which added and its method must be called |
| * on <code>keyPressed</code> and <code>keyReleased</code> call. |
| */ |
| public class MyKeyHandler implements XKeyHandler { |
| /** |
| * This event sets the member <code>m_keyPressed</coed> to |
| * <code>true</code> |
| * @param oEvent The key event informs about the pressed key. |
| * @return returns <CODE>TRUE</CODE> in erery case |
| */ |
| public boolean keyPressed( KeyEvent oEvent ){ |
| System.out.println("XKeyHandler: keyPressed-Event"); |
| m_keyPressed = true; |
| return true; |
| } |
| /** |
| * This event sets the member <code>m_keyReleased</coed> to |
| * <code>true</code> |
| * @param oEvent The key event informs about the pressed key. |
| * @return returns <CODE>TRUE</CODE> in erery case |
| */ |
| public boolean keyReleased( KeyEvent oEvent ){ |
| System.out.println("XKeyHandler: keyReleased-Event"); |
| m_keyReleased = true; |
| return true; |
| } |
| /** |
| * This event does nothing useful |
| * @param oEvent refers to the object that fired the event. |
| */ |
| public void disposing( EventObject oEvent ){ |
| System.out.println("XKeyHandler: disposing-Event"); |
| } |
| } |
| |
| /** |
| * Listener which added and its method must be called |
| * on <code>mousePressed</code> and <code>mouseReleased</code> call. |
| */ |
| public class MyMouseClickHandler implements XMouseClickHandler { |
| /** |
| * This event sets the member <code>m_mousePressed</coed> to |
| * <code>true</code> |
| * @param oEvent The mouse event informs about the kind of mouse event. |
| * @return returns <CODE>TRUE</CODE> in erery case |
| */ |
| public boolean mousePressed( MouseEvent oEvent ){ |
| System.out.println("XMouseClickHandler: mousePressed-Event"); |
| m_mousePressed = true; |
| return true; |
| } |
| /** |
| * This event sets the member <code>m_mouseReleased</coed> to |
| * <code>true</code> |
| * @param oEvent The mouse event informs about the kind of mouse event. |
| * @return returns <CODE>TRUE</CODE> in erery case |
| */ |
| public boolean mouseReleased( MouseEvent oEvent ){ |
| System.out.println("XMouseClickHandler: mouseReleased-Event"); |
| m_mouseReleased = true; |
| return true; |
| } |
| /** |
| * This event does nothing useful |
| * @param oEvent refers to the object that fired the event. |
| */ |
| public void disposing( EventObject oEvent ){ |
| System.out.println("XMouseClickHandler: disposing-Event"); |
| } |
| }; |
| |
| /** |
| * To check the events this class is a thread which click a mouse button and |
| * press a key with the <CODE>Robot</CODE> class |
| * @see java.awt.Robot |
| */ |
| private class EventTrigger extends Thread{ |
| |
| /** |
| * represents a <CODE>AccessibilityTools</CODE> |
| */ |
| private final AccessibilityTools at = new AccessibilityTools(); |
| /** |
| * represents an <CODE>EventType</CODE> |
| * @see EventTest.EventTriggerType |
| */ |
| private int eventType = 0; |
| /** |
| * represents a <CODE>XModel</CODE> of a document |
| */ |
| private XModel xModel = null; |
| |
| /** |
| * Creates an instacne of this class. The parameter <CODE>eType</CODE> represents |
| * the kind of event wich will be triggert at <CODE>run()</CODE> |
| * @param model the model of a document |
| * @param eType the kind of event which should be trigger |
| */ |
| public EventTrigger(XModel model, int eType) |
| { |
| this.xModel = model; |
| this.eventType = eType; |
| } |
| |
| /** |
| * Triggers the event wich is represented by <CODE>eventType</CODE> |
| * The scenarios are: |
| * <ul> |
| * <li>EventTest.EventTriggerType.MOUSE_KLICK_INTO_DOC |
| * which calls |
| * <li><CODE>clickIntoDoc</CODE></LI> |
| * </LI> |
| * <li>EventTest.EventTriggerType.KEY_TEXT_INTO_DOC |
| * which calls |
| * <li><CODE>clickIntodoc</CODE></LI> |
| * <li><CODE>keyIntoDoc</CODE></LI> |
| * </LI> |
| * </UL> |
| */ |
| public void run(){ |
| |
| switch (this.eventType){ |
| |
| case EventTriggerType.MOUSE_KLICK_INTO_DOC: |
| clickIntoDoc(); |
| break; |
| case EventTriggerType.KEY_TEXT_INTO_DOC: |
| clickIntoDoc(); |
| keyIntoDoc(); |
| break; |
| |
| } |
| } |
| /** |
| * This method cklicks into the middel of a document. It uses Accessibility |
| * to get the document and query for its position and its range to calculate |
| * the middle. This values was used for <CODE>Robot</CODE> Class. This |
| * Robot class is able to move the mouse and to cklick a mouse button |
| * @see java.awt.Robot |
| */ |
| private void clickIntoDoc(){ |
| try{ |
| // get the position and the range of a scroll bar |
| |
| XWindow xWindow = at.getCurrentWindow( |
| getMSF(), |
| xModel); |
| |
| XAccessible xRoot = at.getAccessibleObject(xWindow); |
| |
| |
| |
| XAccessibleContext xPanel = at.getAccessibleObjectForRole(xRoot, AccessibleRole.PANEL); |
| XAccessibleComponent xPanelCont = UnoRuntime.queryInterface(XAccessibleComponent.class, xPanel); |
| |
| // the position of the panel |
| Point point = xPanelCont.getLocationOnScreen(); |
| |
| // the range of the panel |
| Rectangle rect = xPanelCont.getBounds(); |
| |
| try { |
| Robot rob = new Robot(); |
| int x = point.X + (rect.Width / 2); |
| int y = point.Y + (rect.Height / 2); |
| System.out.println("try to klick into the middle of the document"); |
| rob.mouseMove(x, y); |
| rob.mousePress(InputEvent.BUTTON1_MASK); |
| rob.mouseRelease(InputEvent.BUTTON1_MASK); |
| } catch (java.awt.AWTException e) { |
| System.out.println("couldn't press mouse button"); |
| } |
| } catch (java.lang.Exception e){ |
| System.out.println("could not click into the scroll bar: " + e.toString()); |
| } |
| } |
| |
| /** |
| * This method press the "A" key. Therefore it uses the <CODE>Robot</CODE> |
| * class. |
| * @see java.awt.Robot |
| */ |
| private void keyIntoDoc(){ |
| try { |
| Robot rob = new Robot(); |
| System.out.println("try to press 'A'"); |
| rob.keyPress(java.awt.event.KeyEvent.VK_A); |
| rob.keyRelease(java.awt.event.KeyEvent.VK_A); |
| } catch (java.awt.AWTException e) { |
| System.out.println("couldn't press key"); |
| } |
| |
| } |
| } |
| |
| /** This interface represents all possible actions which could be used |
| * in the <CODE>EventTrigger</CODE> class. |
| * @see EventTest.EventTrigger |
| */ |
| private interface EventTriggerType{ |
| |
| /** klick the mouse into the scroll bar*/ |
| final public static int MOUSE_KLICK_INTO_DOC = 1; |
| |
| /** write some text into a spread sheet*/ |
| final public static int KEY_TEXT_INTO_DOC = 2; |
| } |
| |
| |
| |
| |
| private XMultiServiceFactory getMSF() |
| { |
| final XMultiServiceFactory xMSF1 = UnoRuntime.queryInterface(XMultiServiceFactory.class, connection.getComponentContext().getServiceManager()); |
| return xMSF1; |
| } |
| |
| // setup and close connections |
| @BeforeClass public static void setUpConnection() throws Exception { |
| System.out.println("setUpConnection()"); |
| connection.setUp(); |
| } |
| |
| @AfterClass public static void tearDownConnection() |
| throws InterruptedException, com.sun.star.uno.Exception |
| { |
| System.out.println("tearDownConnection()"); |
| connection.tearDown(); |
| } |
| |
| private static final OfficeConnection connection = new OfficeConnection(); |
| |
| } |