1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: _XAccessibleComponent.java,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 package ifc
.accessibility
;
32 import java
.util
.Vector
;
34 import lib
.MultiMethodTest
;
36 import com
.sun
.star
.accessibility
.XAccessible
;
37 import com
.sun
.star
.accessibility
.XAccessibleComponent
;
38 import com
.sun
.star
.accessibility
.XAccessibleContext
;
39 import com
.sun
.star
.awt
.Point
;
40 import com
.sun
.star
.awt
.Rectangle
;
41 import com
.sun
.star
.awt
.Size
;
42 import com
.sun
.star
.uno
.UnoRuntime
;
46 * Testing <code>com.sun.star.accessibility.XAccessibleComponent</code>
49 * <li><code> containsPoint()</code></li>
50 * <li><code> getAccessibleAtPoint()</code></li>
51 * <li><code> getBounds()</code></li>
52 * <li><code> getLocation()</code></li>
53 * <li><code> getLocationOnScreen()</code></li>
54 * <li><code> getSize()</code></li>
55 * <li><code> grabFocus()</code></li>
56 * <li><code> getAccessibleKeyBinding()</code></li>
59 * @see com.sun.star.accessibility.XAccessibleComponent
61 public class _XAccessibleComponent
extends MultiMethodTest
{
63 public XAccessibleComponent oObj
= null;
64 private Rectangle bounds
= null;
65 private Vector KnownBounds
= new Vector();
69 * First checks 4 inner bounds (upper, lower, left and right)
70 * of component bounding box to contain
71 * at least one point of the component. Second 4 outer bounds
72 * are checked to not contain any component points.<p>
74 * Has <b> OK </b> status if inner bounds contain component points
75 * and outer bounds don't contain any component points. <p>
77 * The following method tests are to be completed successfully before :
79 * <li> <code> getBounds() </code> : to have size of a component.</li>
82 public void _containsPoint() {
83 requiredMethod("getBounds()");
85 boolean result
= true;
89 //while (!oObj.containsPoint(new Point(curX, bounds.Y)) && curX < bounds.Width+bounds.X) {
90 while (!oObj
.containsPoint(new Point(curX
, 0)) &&
91 (curX
< bounds
.Width
)) {
97 //if ((bounds.X <= curX) && (curX < bounds.Width+bounds.X)) {
98 if (curX
< bounds
.Width
) {
99 log
.println("Upper bound of box containsPoint point (" + curX
+
103 "Upper bound of box containsPoint no component points - FAILED");
109 //while (!oObj.containsPoint(new Point(curX, bounds.Y+bounds.Height - 1))
110 while (!oObj
.containsPoint(new Point(curX
, bounds
.Height
- 1)) &&
111 (curX
< bounds
.Width
)) {
112 log
.println("containsPoint returns false for (" + curX
+ "," +
113 bounds
.Height
+ ")");
119 //if ((bounds.X <= curX) && (curX < bounds.Width+bounds.X)) {
120 if (curX
< bounds
.Width
) {
121 log
.println("Lower bound of box containsPoint point (" + curX
+
122 "," + (bounds
.Height
- 1) + ") - OK");
125 "Lower bound of box containsPoint no component points - FAILED");
131 //while (!oObj.containsPoint(new Point(bounds.X, curY)) && curY < bounds.Height+bounds.Y) {
132 while (!oObj
.containsPoint(new Point(0, curY
)) &&
133 (curY
< bounds
.Height
)) {
139 //if ((bounds.Y <= curY) && (curY < bounds.Height+bounds.Y)) {
140 if (curY
< bounds
.Height
) {
141 log
.println("Left bound of box containsPoint point (0," + curY
+
145 "Left bound of box containsPoint no component points - FAILED");
151 //while (!oObj.containsPoint(new Point(bounds.X+bounds.Width - 1, curY))
152 // && curY < bounds.Height+bounds.Y) {
153 while (!oObj
.containsPoint(new Point(bounds
.Width
- 1, curY
)) &&
154 (curY
< bounds
.Height
)) {
160 //if ((bounds.Y <= curY) && (curY < bounds.Height + bounds.Y)) {
161 if (curY
< bounds
.Height
) {
162 log
.println("Right bound of box containsPoint point (" +
163 (bounds
.Width
- 1) + "," + curY
+ ") - OK");
166 "Right bound of box containsPoint no component points - FAILED");
170 boolean locRes
= true;
172 for (int x
= -1; x
<= bounds
.Width
; x
++) {
173 locRes
&= !oObj
.containsPoint(new Point(x
, -1));
174 locRes
&= !oObj
.containsPoint(
175 new Point(x
, bounds
.Height
+ bounds
.Y
));
179 log
.println("Outer upper and lower bounds contain no component " +
182 log
.println("Outer upper and lower bounds CONTAIN some component " +
189 for (int y
= -1; y
<= bounds
.Height
; y
++) {
190 locRes
&= !oObj
.containsPoint(new Point(-1, y
));
191 locRes
&= !oObj
.containsPoint(
192 new Point(bounds
.X
+ bounds
.Width
, y
));
196 log
.println("Outer left and right bounds contain no component " +
199 log
.println("Outer left and right bounds CONTAIN some component " +
204 tRes
.tested("containsPoint()", result
);
208 * Iterates through all children which implement
209 * <code>XAccessibleComponent</code> (if they exist) determines their
210 * boundaries and tries to get each child by <code>getAccessibleAtPoint</code>
211 * passing point which belongs to the child.
212 * Also the point is checked which doesn't belong to child boundary
215 * Has <b> OK </b> status if in the first cases the right children
216 * are returned, and in the second <code>null</code> or
217 * another child is returned.
219 public void _getAccessibleAtPoint() {
220 boolean result
= true;
221 XAccessibleComponent
[] children
= getChildrenComponents();
223 if (children
.length
> 0) {
224 for (int i
= 0; i
< children
.length
; i
++) {
225 Rectangle chBnd
= children
[i
].getBounds();
231 log
.println("Checking child with bounds " + "(" + chBnd
.X
+
232 "," + chBnd
.Y
+ "),(" + chBnd
.Width
+ "," +
233 chBnd
.Height
+ "): " +
234 util
.AccessibilityTools
.accessibleToString(
237 XAccessibleContext xAc
= (XAccessibleContext
) UnoRuntime
.queryInterface(
238 XAccessibleContext
.class,
241 boolean MightBeCovered
= false;
242 boolean isShowing
= xAc
.getAccessibleStateSet()
243 .contains(com
.sun
.star
.accessibility
.AccessibleStateType
.SHOWING
);
244 log
.println("\tStateType containsPoint SHOWING: " +
248 log
.println("Child is invisible - OK");
253 log
.println("finding the point which lies on the component");
255 int curX
= chBnd
.Width
/ 2;
256 int curY
= chBnd
.Height
/ 2;
258 while (!children
[i
].containsPoint(new Point(curX
, curY
)) &&
259 (curX
> 0) && (curY
> 0)) {
266 if ((curX
== chBnd
.Width
) && isShowing
) {
267 log
.println("Couldn't find a point with containsPoint");
272 // trying the point laying on child
273 XAccessible xAcc
= oObj
.getAccessibleAtPoint(
274 new Point(chBnd
.X
+ curX
,
278 Point p
= new Point(chBnd
.X
+ curX
,chBnd
.X
+ curX
);
280 if (isCovered(p
) && isShowing
) {
282 "Child might be covered by another and can't be reached");
283 MightBeCovered
= true;
286 KnownBounds
.add(chBnd
);
289 log
.println("The child not found at point (" +
290 (chBnd
.X
+ curX
) + "," + (chBnd
.Y
+ curY
) +
299 XAccessible xAccCh
= (XAccessible
) UnoRuntime
.queryInterface(
302 XAccessibleContext xAccC
= (XAccessibleContext
) UnoRuntime
.queryInterface(
303 XAccessibleContext
.class,
305 log
.println("Child found at point (" + (chBnd
.X
+ curX
) +
306 "," + (chBnd
.Y
+ curY
) + ") - OK");
313 if (xAccCh
!= null) {
314 res
= util
.AccessibilityTools
.equals(xAccCh
, xAcc
);
315 expIndex
= xAccCh
.getAccessibleContext()
316 .getAccessibleIndexInParent();
317 expName
= xAccCh
.getAccessibleContext()
318 .getAccessibleName();
319 expDesc
= xAccCh
.getAccessibleContext()
320 .getAccessibleDescription();
322 res
= xAccC
.getAccessibleName()
323 .equals(xAcc
.getAccessibleContext()
324 .getAccessibleName());
325 expIndex
= xAccC
.getAccessibleIndexInParent();
326 expName
= xAccC
.getAccessibleName();
327 expDesc
= xAccC
.getAccessibleDescription();
331 int gotIndex
= xAcc
.getAccessibleContext()
332 .getAccessibleIndexInParent();
334 if (expIndex
< gotIndex
) {
335 log
.println("The children found is not the same");
336 log
.println("The expected child " + expName
);
337 log
.print("is hidden behind the found Child ");
338 log
.println(xAcc
.getAccessibleContext()
339 .getAccessibleName() + " - OK");
342 "The children found is not the same");
343 log
.println("Expected: " + expName
);
344 log
.println("Description: " + expDesc
);
345 log
.println("Found: " +
346 xAcc
.getAccessibleContext()
347 .getAccessibleName());
348 log
.println("Description: " +
349 xAcc
.getAccessibleContext()
350 .getAccessibleDescription());
351 if (MightBeCovered
) {
352 log
.println("... Child is covered by another - OK");
354 log
.println("... FAILED");
363 // trying the point NOT laying on child
364 xAcc
= oObj
.getAccessibleAtPoint(
365 new Point(chBnd
.X
- 1, chBnd
.Y
- 1));
368 log
.println("No children found at point (" +
369 (chBnd
.X
- 1) + "," + (chBnd
.Y
- 1) +
373 XAccessible xAccCh
= (XAccessible
) UnoRuntime
.queryInterface(
376 boolean res
= util
.AccessibilityTools
.equals(xAccCh
, xAcc
);
379 log
.println("The same child found outside " +
380 "its bounds at (" + (chBnd
.X
- 1) + "," +
381 (chBnd
.Y
- 1) + ") - FAILED");
387 log
.println("There are no children supporting " +
388 "XAccessibleComponent");
391 tRes
.tested("getAccessibleAtPoint()", result
);
395 * Retrieves the component bounds and stores it. <p>
397 * Has <b> OK </b> status if boundary position (x,y) is not negative
398 * and size (Width, Height) is greater than 0.
400 public void _getBounds() {
401 boolean result
= true;
403 bounds
= oObj
.getBounds();
404 result
&= ((bounds
!= null) && (bounds
.X
>= 0) && (bounds
.Y
>= 0) && (bounds
.Width
> 0) && (bounds
.Height
> 0));
406 log
.println("Bounds = " +
408 ?
("(" + bounds
.X
+ "," + bounds
.Y
+ "),(" +
409 bounds
.Width
+ "," + bounds
.Height
+ ")") : "null"));
411 tRes
.tested("getBounds()", result
);
415 * Gets the location. <p>
417 * Has <b> OK </b> status if the location is the same as location
418 * of boundary obtained by <code>getBounds()</code> method.
420 * The following method tests are to be completed successfully before :
422 * <li> <code> getBounds() </code> : to have bounds </li>
425 public void _getLocation() {
426 requiredMethod("getBounds()");
428 boolean result
= true;
429 Point loc
= oObj
.getLocation();
431 result
&= ((loc
.X
== bounds
.X
) && (loc
.Y
== bounds
.Y
));
433 tRes
.tested("getLocation()", result
);
437 * Get the screen location of the component and its parent
438 * (if it exists and supports <code>XAccessibleComponent</code>). <p>
440 * Has <b> OK </b> status if component screen location equals
441 * to screen location of its parent plus location of the component
442 * relative to the parent. <p>
444 * The following method tests are to be completed successfully before :
446 * <li> <code> getBounds() </code> : to have location of the component
447 * relative to its parent</li>
450 public void _getLocationOnScreen() {
451 requiredMethod("getBounds()");
453 XAccessibleComponent parent
= getParentComponent();
455 boolean result
= true;
456 Point loc
= oObj
.getLocationOnScreen();
457 log
.println("Location is (" + loc
.X
+ "," + loc
.Y
+ ")");
459 if (parent
!= null) {
460 Point parLoc
= parent
.getLocationOnScreen();
461 log
.println("Parent location is (" + parLoc
.X
+ "," + parLoc
.Y
+
464 result
&= ((parLoc
.X
+ bounds
.X
) == loc
.X
);
465 result
&= ((parLoc
.Y
+ bounds
.Y
) == loc
.Y
);
468 tRes
.tested("getLocationOnScreen()", result
);
472 * Obtains the size of the component. <p>
474 * Has <b> OK </b> status if the size is the same as in bounds. <p>
476 * The following method tests are to be completed successfully before :
478 * <li> <code> getBounds() </code> </li>
481 public void _getSize() {
482 requiredMethod("getBounds()");
484 boolean result
= true;
485 Size size
= oObj
.getSize();
487 result
&= (size
.Width
== bounds
.Width
);
488 result
&= (size
.Height
== bounds
.Height
);
490 tRes
.tested("getSize()", result
);
494 * Just calls the method. <p>
496 * Has <b> OK </b> status if no runtime exceptions occured.
498 public void _grabFocus() {
499 boolean result
= true;
502 tRes
.tested("grabFocus()", result
);
506 * Retrieves all children (not more than 50) of the current
507 * component which support <code>XAccessibleComponent</code>.
509 * @return The array of children. Empty array returned if
510 * such children were not found or some error occured.
512 private XAccessibleComponent
[] getChildrenComponents() {
513 XAccessible xAcc
= (XAccessible
) UnoRuntime
.queryInterface(
514 XAccessible
.class, oObj
);
517 log
.println("Component doesn't support XAccessible.");
519 return new XAccessibleComponent
[0];
522 XAccessibleContext xAccCon
= xAcc
.getAccessibleContext();
523 int cnt
= xAccCon
.getAccessibleChildCount();
525 // for cases when too many children exist checking only first 50
530 Vector childComp
= new Vector();
532 for (int i
= 0; i
< cnt
; i
++) {
534 XAccessible child
= xAccCon
.getAccessibleChild(i
);
535 XAccessibleContext xAccConCh
= child
.getAccessibleContext();
536 XAccessibleComponent xChAccComp
= (XAccessibleComponent
) UnoRuntime
.queryInterface(
537 XAccessibleComponent
.class,
540 if (xChAccComp
!= null) {
541 childComp
.add(xChAccComp
);
543 } catch (com
.sun
.star
.lang
.IndexOutOfBoundsException e
) {
547 return (XAccessibleComponent
[]) childComp
.toArray(
548 new XAccessibleComponent
[childComp
.size()]);
552 * Gets the parent of the current component which support
553 * <code>XAccessibleComponent</code>.
555 * @return The parent or <code>null</code> if the component
556 * has no parent or some errors occured.
558 private XAccessibleComponent
getParentComponent() {
559 XAccessible xAcc
= (XAccessible
) UnoRuntime
.queryInterface(
560 XAccessible
.class, oObj
);
563 log
.println("Component doesn't support XAccessible.");
568 XAccessibleContext xAccCon
= xAcc
.getAccessibleContext();
569 XAccessible xAccPar
= xAccCon
.getAccessibleParent();
571 if (xAccPar
== null) {
572 log
.println("Component has no accessible parent.");
577 XAccessibleContext xAccConPar
= xAccPar
.getAccessibleContext();
578 XAccessibleComponent parent
= (XAccessibleComponent
) UnoRuntime
.queryInterface(
579 XAccessibleComponent
.class,
582 if (parent
== null) {
584 "Accessible parent doesn't support XAccessibleComponent");
593 * Just calls the method.
595 public void _getForeground() {
596 int forColor
= oObj
.getForeground();
597 log
.println("getForeground(): " + forColor
);
598 tRes
.tested("getForeground()", true);
602 * Just calls the method.
604 public void _getBackground() {
605 int backColor
= oObj
.getBackground();
606 log
.println("getBackground(): " + backColor
);
607 tRes
.tested("getBackground()", true);
611 * Restores initial component text.
613 protected void after() {
614 if (tEnv
.getObjRelation("Destroy") != null) {
615 disposeEnvironment();
619 private boolean isCovered(Point p
) {
620 int elements
= KnownBounds
.size();
621 boolean Covered
= false;
622 for (int k
=0;k
<elements
;k
++) {
623 Rectangle known
= (Rectangle
) KnownBounds
.get(k
);
624 Covered
= (known
.X
< p
.X
);
625 Covered
&= (known
.Y
< p
.Y
);
626 Covered
&= (p
.Y
< known
.Y
+known
.Height
);
627 Covered
&= (p
.X
< known
.X
+known
.Width
);