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.toolkit.accessibility;
25 
26 import com.sun.star.awt.Point;
27 import com.sun.star.awt.Rectangle;
28 import com.sun.star.awt.Size;
29 import com.sun.star.uno.UnoRuntime;
30 import com.sun.star.accessibility.XAccessible;
31 import com.sun.star.accessibility.XAccessibleComponent;
32 import com.sun.star.accessibility.XAccessibleContext;
33 import com.sun.star.uno.XInterface;
34 import java.util.Vector;
35 
36 /**
37  * Testing <code>com.sun.star.accessibility.XAccessibleComponent</code>
38  * interface methods :
39  * <ul>
40  *  <li><code> containsPoint()</code></li>
41  *  <li><code> getAccessibleAtPoint()</code></li>
42  *  <li><code> getBounds()</code></li>
43  *  <li><code> getLocation()</code></li>
44  *  <li><code> getLocationOnScreen()</code></li>
45  *  <li><code> getSize()</code></li>
46  *  <li><code> grabFocus()</code></li>
47  *  <li><code> getAccessibleKeyBinding()</code></li>
48  * </ul> <p>
49  *
50  * @see com.sun.star.accessibility.XAccessibleComponent
51  */
52 public class _XAccessibleComponent {
53 
54     // private LogWriter log;
55 
56     public XAccessibleComponent oObj = null;
57 
58     private Rectangle bounds = null ;
59 
60     private static final String className =
61         "com.sun.star.accessibility.XAccessibleComponent";
62 
63     /**
64      * Constructor
65      * @param object
66      */
_XAccessibleComponent(XInterface object )67     public _XAccessibleComponent(XInterface object/*, LogWriter log*/) {
68         oObj = UnoRuntime.queryInterface(
69                                     XAccessibleComponent.class, object);
70         // this.log = log;
71     }
72 
73      /**
74      * First checks 4 inner bounds (upper, lower, left and right)
75      * of component bounding box to contain
76      * at least one point of the component. Second 4 outer bounds
77      * are checked to not contain any component points.<p>
78      *
79      * Has <b> OK </b> status if inner bounds contain component points
80      * and outer bounds don't contain any component points. <p>
81      *
82      * The following method tests are to be completed successfully before :
83      * <ul>
84      *  <li> <code> getBounds() </code> : to have size of a component.</li>
85      * </ul>
86       * @return
87       */
_containsPoint()88     public boolean _containsPoint() {
89 
90         boolean result = true ;
91 
92         int curX = 0;
93         //while (!oObj.containsPoint(new Point(curX, bounds.Y)) && curX < bounds.Width+bounds.X) {
94         while (!oObj.containsPoint(new Point(curX, 0)) && curX < bounds.Width) {
95             curX++;
96         }
97         //if ((bounds.X <= curX) && (curX < bounds.Width+bounds.X)) {
98         if (curX < bounds.Width) {
99             System.out.println("Upper bound of box contains point ("
100                 + curX + ",0) - OK");
101         } else {
102             System.out.println
103                 ("Upper bound of box contains no component points - FAILED");
104             result = false;
105         }
106 
107         curX = 0;
108         //while (!oObj.containsPoint(new Point(curX, bounds.Y+bounds.Height - 1))
109         while (!oObj.containsPoint(new Point(curX, bounds.Height - 1))
110                && curX < bounds.Width) {
111 
112                System.out.println("Contains returns false for ("+curX+","+bounds.Height+")");
113             curX++;
114         }
115         //if ((bounds.X <= curX) && (curX < bounds.Width+bounds.X)) {
116         if (curX < bounds.Width) {
117             System.out.println("Lower bound of box contains point ("
118                 + curX + "," + (bounds.Height - 1) + ") - OK");
119         } else {
120             System.out.println
121                 ("Lower bound of box contains no component points - FAILED");
122             result = false;
123         }
124 
125         int curY = 0;
126         //while (!oObj.containsPoint(new Point(bounds.X, curY)) && curY < bounds.Height+bounds.Y) {
127         while (!oObj.containsPoint(new Point(0, curY)) && curY < bounds.Height) {
128             curY++;
129         }
130         //if ((bounds.Y <= curY) && (curY < bounds.Height+bounds.Y)) {
131         if (curY < bounds.Height) {
132             System.out.println("Left bound of box contains point (0,"
133                 + curY + ") - OK");
134         } else {
135             System.out.println
136                 ("Left bound of box contains no component points - FAILED");
137             result = false;
138         }
139 
140         curY = 0;
141         //while (!oObj.containsPoint(new Point(bounds.X+bounds.Width - 1, curY))
142         //       && curY < bounds.Height+bounds.Y) {
143         while (!oObj.containsPoint(new Point(bounds.Width - 1, curY)) && curY < bounds.Height) {
144             curY++;
145         }
146         //if ((bounds.Y <= curY) && (curY < bounds.Height + bounds.Y)) {
147         if (curY < bounds.Height) {
148             System.out.println("Right bound of box contains point ("
149                 + (bounds.Width - 1) + "," + curY + ") - OK");
150         } else {
151             System.out.println
152                 ("Right bound of box contains no component points - FAILED");
153             result = false;
154         }
155 
156         boolean locRes = true;
157         for (int x = -1; x <= bounds.Width; x++) {
158             locRes &= !oObj.containsPoint(new Point(x, -1));
159             locRes &= !oObj.containsPoint(new Point(x, bounds.Height+bounds.Y));
160         }
161         if (locRes) {
162             System.out.println("Outer upper and lower bounds contain no component "
163                 + "points - OK");
164         } else {
165             System.out.println("Outer upper and lower bounds CONTAIN some component "
166                 + "points - FAILED");
167             result = false;
168         }
169 
170         locRes = true;
171         for (int y = -1; y <= bounds.Height; y++) {
172             locRes &= !oObj.containsPoint(new Point(-1, y));
173             locRes &= !oObj.containsPoint(new Point(bounds.X+bounds.Width, y));
174         }
175         if (locRes) {
176             System.out.println("Outer left and right bounds contain no component "
177                 + "points - OK");
178         } else {
179             System.out.println("Outer left and right bounds CONTAIN some component "
180                 + "points - FAILED");
181             result = false;
182         }
183 
184         return result;
185     }
186 
187     /**
188      * Iterates through all children which implement
189      * <code>XAccessibleComponent</code> (if they exist) determines their
190      * boundaries and tries to get each child by <code>getAccessibleAtPoint</code>
191      * passing point which belongs to the child.
192      * Also the point is checked which doesn't belong to child boundary
193      * box. <p>
194      *
195      * Has <b> OK </b> status if in the first cases the right children
196      * are returned, and in the second <code>null</code> or
197      * another child is returned.
198      * @return
199      */
_getAccessibleAtPoint()200     public boolean _getAccessibleAtPoint() {
201 
202         boolean result = true ;
203         XAccessibleComponent[] children = getChildrenComponents();
204 
205         if (children.length > 0) {
206             for (int i = 0; i < children.length; i++) {
207                 Rectangle chBnd = children[i].getBounds();
208                 if (chBnd.X == -1)
209                 {
210                     continue;
211                 }
212                 System.out.println("Checking child with bounds " +
213                     "(" + chBnd.X + "," + chBnd.Y + "),("
214                     + chBnd.Width + "," + chBnd.Height + "): "
215                     +  util.AccessibilityTools.accessibleToString(children[i]));
216 
217                 System.out.println("finding the point which lies on the component");
218                 int curX = 0;
219                 int curY = 0;
220                 while (!children[i].containsPoint(new Point(curX, curY))
221                        && curX < chBnd.Width) {
222                     curX++;
223                     curY++;
224                 }
225 
226                 if (curX==chBnd.Width) {
227                     System.out.println("Couldn't find a point with contains");
228                     continue;
229                 }
230 
231                 // trying the point laying on child
232                 XAccessible xAcc = oObj.getAccessibleAtPoint
233                     (new Point(chBnd.X , chBnd.Y));
234                 if (xAcc == null) {
235                     System.out.println("The child not found at point ("
236                         + (chBnd.X ) + "," + chBnd.Y + ") - FAILED");
237                     result = false;
238                 } else {
239                     XAccessible xAccCh = UnoRuntime.queryInterface
240                         (XAccessible.class, children[i]);
241                     System.out.println("Child found at point ("
242                         + (chBnd.X ) + "," + chBnd.Y + ") - OK");
243                     boolean res = util.AccessibilityTools.equals(xAccCh, xAcc);
244                     if (!res) {
245                         int expIndex = xAccCh.getAccessibleContext().getAccessibleIndexInParent();
246                         int gotIndex = xAcc.getAccessibleContext().getAccessibleIndexInParent();
247                         if (expIndex < gotIndex) {
248                             System.out.println("The children found is not the same");
249                             System.out.println("The expected child " +
250                                 xAccCh.getAccessibleContext().getAccessibleName());
251                             System.out.println("is hidden behind the found Child ");
252                             System.out.println(xAcc.getAccessibleContext().getAccessibleName()+" - OK");
253                         } else {
254                             System.out.println("The children found is not the same - FAILED");
255                             System.out.println("Expected: "
256                                 +xAccCh.getAccessibleContext().getAccessibleName());
257                             System.out.println("Found: "
258                                 +xAcc.getAccessibleContext().getAccessibleName());
259                             result = false ;
260                         }
261                     }
262                 }
263 
264                 // trying the point NOT laying on child
265                 xAcc = oObj.getAccessibleAtPoint
266                     (new Point(chBnd.X - 1, chBnd.Y - 1));
267                 if (xAcc == null) {
268                     System.out.println("No children found at point ("
269                         + (chBnd.X - 1) + "," + (chBnd.Y - 1) + ") - OK");
270                     result &= true;
271                 } else {
272                     XAccessible xAccCh = UnoRuntime.queryInterface(XAccessible.class, children[i]);
273                     boolean res = util.AccessibilityTools.equals(xAccCh, xAcc);
274                     if (res) {
275                         System.out.println("The same child found outside "
276                             + "its bounds - FAILED");
277                         result = false ;
278                     }
279                 }
280             }
281         } else {
282             System.out.println("There are no children supporting "
283                 + "XAccessibleComponent");
284         }
285 
286         return result;
287     }
288 
289     /**
290      * Retrieves the component bounds and stores it. <p>
291      *
292      * Has <b> OK </b> status if boundary position (x,y) is not negative
293      * and size (Width, Height) is greater than 0.
294      * @return
295      */
_getBounds()296     public boolean _getBounds() {
297         boolean result = true ;
298 
299         bounds = oObj.getBounds() ;
300         result &= bounds != null
301             && bounds.X >=0 && bounds.Y >=0
302             && bounds.Width >0 && bounds.Height >0;
303 
304         System.out.println("Bounds = " + (bounds != null
305              ? "(" + bounds.X + "," + bounds.Y + "),("
306              + bounds.Width + "," + bounds.Height + ")" : "null"));
307 
308         return result;
309     }
310 
311     /**
312      * Gets the location. <p>
313      *
314      * Has <b> OK </b> status if the location is the same as location
315      * of boundary obtained by <code>getBounds()</code> method.
316      *
317      * The following method tests are to be completed successfully before :
318      * <ul>
319      *  <li> <code> getBounds() </code> : to have bounds </li>
320      * </ul>
321      * @return
322      */
_getLocation()323     public boolean _getLocation() {
324 
325         boolean result = true ;
326         Point loc = oObj.getLocation() ;
327 
328         result &= loc.X == bounds.X && loc.Y == bounds.Y ;
329 
330         return result;
331     }
332 
333     /**
334      * Get the screen location of the component and its parent
335      * (if it exists and supports <code>XAccessibleComponent</code>). <p>
336      *
337      * Has <b> OK </b> status if component screen location equals
338      * to screen location of its parent plus location of the component
339      * relative to the parent. <p>
340      *
341      * The following method tests are to be completed successfully before :
342      * <ul>
343      *  <li> <code> getBounds() </code> : to have location of the component
344      *      relative to its parent</li>
345      * </ul>
346      * @return
347      */
_getLocationOnScreen()348     public boolean _getLocationOnScreen() {
349 
350         XAccessibleComponent parent = getParentComponent();
351 
352         boolean result = true ;
353         Point loc = oObj.getLocationOnScreen();
354         System.out.println("Location is (" + loc.X + "," + loc.Y + ")");
355 
356         if (parent != null) {
357             Point parLoc = parent.getLocationOnScreen();
358             System.out.println("Parent location is ("
359                 + parLoc.X + "," + parLoc.Y + ")");
360 
361             result &= parLoc.X + bounds.X == loc.X;
362             result &= parLoc.Y + bounds.Y == loc.Y;
363         }
364 
365         return result;
366     }
367 
368     /**
369      * Obtains the size of the component. <p>
370      *
371      * Has <b> OK </b> status if the size is the same as in bounds. <p>
372      *
373      * The following method tests are to be completed successfully before :
374      * <ul>
375      *  <li> <code> getBounds() </code>  </li>
376      * </ul>
377      * @return
378      */
_getSize()379     public boolean _getSize() {
380 
381         boolean result = true ;
382         Size size = oObj.getSize() ;
383 
384         result &= size.Width == bounds.Width;
385         result &= size.Height == bounds.Height;
386 
387         return result;
388     }
389 
390     /**
391      * Just calls the method. <p>
392      *
393      * Has <b> OK </b> status if no runtime exceptions occured.
394      * @return
395      */
_grabFocus()396     public boolean _grabFocus() {
397 
398         boolean result = true ;
399         oObj.grabFocus() ;
400 
401         return result ;
402     }
403 
404     /**
405      * Retrieves all children (not more than 50) of the current
406      * component which support <code>XAccessibleComponent</code>.
407      *
408      * @return The array of children. Empty array returned if
409      * such children were not found or some error occured.
410      */
getChildrenComponents()411     private XAccessibleComponent[] getChildrenComponents() {
412         XAccessible xAcc = UnoRuntime.queryInterface(XAccessible.class, oObj) ;
413         if (xAcc == null) {
414             System.out.println("Component doesn't support XAccessible.");
415             return new XAccessibleComponent[0];
416         }
417         XAccessibleContext xAccCon = xAcc.getAccessibleContext();
418         int cnt = xAccCon.getAccessibleChildCount();
419 
420         // for cases when too many children exist checking only first 50
421         if (cnt > 50)
422         {
423             cnt = 50;
424         }
425 
426         Vector childComp = new Vector();
427         for (int i = 0; i < cnt; i++) {
428             try {
429                 XAccessible child = xAccCon.getAccessibleChild(i);
430                 XAccessibleContext xAccConCh = child.getAccessibleContext();
431                 XAccessibleComponent xChAccComp = UnoRuntime.queryInterface(XAccessibleComponent.class, xAccConCh);
432                 if (xChAccComp != null) {
433                     childComp.add(xChAccComp) ;
434                 }
435             } catch (com.sun.star.lang.IndexOutOfBoundsException e) {}
436         }
437 
438         return (XAccessibleComponent[]) childComp.toArray
439             (new XAccessibleComponent[childComp.size()]);
440     }
441 
442     /**
443      * Gets the parent of the current component which support
444      * <code>XAccessibleComponent</code>.
445      *
446      * @return The parent or <code>null</code> if the component
447      * has no parent or some errors occured.
448      */
getParentComponent()449     private XAccessibleComponent getParentComponent() {
450         XAccessible xAcc = UnoRuntime.queryInterface(XAccessible.class, oObj) ;
451         if (xAcc == null) {
452             System.out.println("Component doesn't support XAccessible.");
453             return null;
454         }
455 
456         XAccessibleContext xAccCon = xAcc.getAccessibleContext();
457         XAccessible xAccPar = xAccCon.getAccessibleParent();
458 
459         if (xAccPar == null) {
460             System.out.println("Component has no accessible parent.");
461             return null;
462         }
463         XAccessibleContext xAccConPar = xAccPar.getAccessibleContext();
464         XAccessibleComponent parent = UnoRuntime.queryInterface(XAccessibleComponent.class, xAccConPar);
465         if (parent == null) {
466             System.out.println
467                 ("Accessible parent doesn't support XAccessibleComponent");
468             return null;
469         }
470 
471         return parent;
472     }
473 
474     /**
475      * Just calls the method.
476      * @return
477      */
_getForeground()478     public boolean _getForeground() {
479         int forColor = oObj.getForeground();
480         System.out.println("getForeground(): " + forColor);
481         return true;
482     }
483 
484     /**
485      * Just calls the method.
486      * @return
487      */
_getBackground()488     public boolean _getBackground() {
489         int backColor = oObj.getBackground();
490         System.out.println("getBackground(): " + backColor);
491         return true;
492     }
493 
494 }
495