xref: /AOO41X/main/qadevOOo/tests/java/ifc/accessibility/_XAccessibleComponent.java (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 package ifc.accessibility;
28 
29 import java.util.Vector;
30 
31 import lib.MultiMethodTest;
32 
33 import com.sun.star.accessibility.XAccessible;
34 import com.sun.star.accessibility.XAccessibleComponent;
35 import com.sun.star.accessibility.XAccessibleContext;
36 import com.sun.star.awt.Point;
37 import com.sun.star.awt.Rectangle;
38 import com.sun.star.awt.Size;
39 import com.sun.star.uno.UnoRuntime;
40 
41 
42 /**
43  * Testing <code>com.sun.star.accessibility.XAccessibleComponent</code>
44  * interface methods :
45  * <ul>
46  *  <li><code> containsPoint()</code></li>
47  *  <li><code> getAccessibleAtPoint()</code></li>
48  *  <li><code> getBounds()</code></li>
49  *  <li><code> getLocation()</code></li>
50  *  <li><code> getLocationOnScreen()</code></li>
51  *  <li><code> getSize()</code></li>
52  *  <li><code> grabFocus()</code></li>
53  *  <li><code> getAccessibleKeyBinding()</code></li>
54  * </ul> <p>
55  *
56  * @see com.sun.star.accessibility.XAccessibleComponent
57  */
58 public class _XAccessibleComponent extends MultiMethodTest {
59 
60     public XAccessibleComponent oObj = null;
61     private Rectangle bounds = null;
62     private Vector KnownBounds = new Vector();
63 
64 
65     /**
66      * First checks 4 inner bounds (upper, lower, left and right)
67      * of component bounding box to contain
68      * at least one point of the component. Second 4 outer bounds
69      * are checked to not contain any component points.<p>
70      *
71      * Has <b> OK </b> status if inner bounds contain component points
72      * and outer bounds don't contain any component points. <p>
73      *
74      * The following method tests are to be completed successfully before :
75      * <ul>
76      *  <li> <code> getBounds() </code> : to have size of a component.</li>
77      * </ul>
78      */
79     public void _containsPoint() {
80         requiredMethod("getBounds()");
81 
82         boolean result = true;
83 
84         int curX = 0;
85 
86         //while (!oObj.containsPoint(new Point(curX, bounds.Y)) && curX < bounds.Width+bounds.X) {
87         while (!oObj.containsPoint(new Point(curX, 0)) &&
88                (curX < bounds.Width)) {
89             curX++;
90         }
91 
92         ;
93 
94         //if ((bounds.X <= curX) && (curX < bounds.Width+bounds.X)) {
95         if (curX < bounds.Width) {
96             log.println("Upper bound of box containsPoint point (" + curX +
97                         ",0) - OK");
98         } else {
99             log.println(
100                     "Upper bound of box containsPoint no component points - FAILED");
101             result = false;
102         }
103 
104         curX = 0;
105 
106         //while (!oObj.containsPoint(new Point(curX, bounds.Y+bounds.Height - 1))
107         while (!oObj.containsPoint(new Point(curX, bounds.Height - 1)) &&
108                (curX < bounds.Width)) {
109             log.println("containsPoint returns false for (" + curX + "," +
110                         bounds.Height + ")");
111             curX++;
112         }
113 
114         ;
115 
116         //if ((bounds.X <= curX) && (curX < bounds.Width+bounds.X)) {
117         if (curX < bounds.Width) {
118             log.println("Lower bound of box containsPoint point (" + curX +
119                         "," + (bounds.Height - 1) + ") - OK");
120         } else {
121             log.println(
122                     "Lower bound of box containsPoint no component points - FAILED");
123             result = false;
124         }
125 
126         int curY = 0;
127 
128         //while (!oObj.containsPoint(new Point(bounds.X, curY)) && curY < bounds.Height+bounds.Y) {
129         while (!oObj.containsPoint(new Point(0, curY)) &&
130                (curY < bounds.Height)) {
131             curY++;
132         }
133 
134         ;
135 
136         //if ((bounds.Y <= curY) && (curY < bounds.Height+bounds.Y)) {
137         if (curY < bounds.Height) {
138             log.println("Left bound of box containsPoint point (0," + curY +
139                         ") - OK");
140         } else {
141             log.println(
142                     "Left bound of box containsPoint no component points - FAILED");
143             result = false;
144         }
145 
146         curY = 0;
147 
148         //while (!oObj.containsPoint(new Point(bounds.X+bounds.Width - 1, curY))
149         //       && curY < bounds.Height+bounds.Y) {
150         while (!oObj.containsPoint(new Point(bounds.Width - 1, curY)) &&
151                (curY < bounds.Height)) {
152             curY++;
153         }
154 
155         ;
156 
157         //if ((bounds.Y <= curY) && (curY < bounds.Height + bounds.Y)) {
158         if (curY < bounds.Height) {
159             log.println("Right bound of box containsPoint point (" +
160                         (bounds.Width - 1) + "," + curY + ") - OK");
161         } else {
162             log.println(
163                     "Right bound of box containsPoint no component points - FAILED");
164             result = false;
165         }
166 
167         boolean locRes = true;
168 
169         for (int x = -1; x <= bounds.Width; x++) {
170             if (oObj.containsPoint(new Point(x, -1))) {
171                 log.println(
172                     "Outer upper and lower bounds CONTAIN some component point"
173                     + " (" + x + ", -1) - FAILED");
174                 locRes = false;
175                 break;
176             }
177             if (oObj.containsPoint(new Point(x, bounds.Height + bounds.Y))) {
178                 log.println(
179                     "Outer upper and lower bounds CONTAIN some component point"
180                     + " (" + x + ", " + bounds.Height + bounds.Y
181                     + ") - FAILED");
182                 locRes = false;
183                 break;
184             }
185         }
186 
187         if (locRes) {
188             log.println("Outer upper and lower bounds contain no component " +
189                         "points - OK");
190         } else {
191             result = false;
192         }
193 
194         locRes = true;
195 
196         for (int y = -1; y <= bounds.Height; y++) {
197             if (oObj.containsPoint(new Point(-1, y))) {
198                 log.println(
199                     "Outer left and right bounds CONTAIN some component point"
200                     + " (-1, " + y + ") - FAILED");
201                 locRes = false;
202                 break;
203             }
204             if (oObj.containsPoint(new Point(bounds.X + bounds.Width, y))) {
205                 log.println(
206                     "Outer left and right bounds CONTAIN some component point"
207                     + " (" + bounds.X + bounds.Width + ", " + y + ") - FAILED");
208                 locRes = false;
209                 break;
210             }
211         }
212 
213         if (locRes) {
214             log.println("Outer left and right bounds contain no component " +
215                         "points - OK");
216         } else {
217             result = false;
218         }
219 
220         tRes.tested("containsPoint()", result);
221     }
222 
223     /**
224      * Iterates through all children which implement
225      * <code>XAccessibleComponent</code> (if they exist) determines their
226      * boundaries and tries to get each child by <code>getAccessibleAtPoint</code>
227      * passing point which belongs to the child.
228      * Also the point is checked which doesn't belong to child boundary
229      * box. <p>
230      *
231      * Has <b> OK </b> status if in the first cases the right children
232      * are returned, and in the second <code>null</code> or
233      * another child is returned.
234      */
235     public void _getAccessibleAtPoint() {
236         boolean result = true;
237         XAccessibleComponent[] children = getChildrenComponents();
238 
239         if (children.length > 0) {
240             for (int i = 0; i < children.length; i++) {
241                 Rectangle chBnd = children[i].getBounds();
242 
243                 if (chBnd.X == -1) {
244                     continue;
245                 }
246 
247                 log.println("Checking child with bounds " + "(" + chBnd.X +
248                             "," + chBnd.Y + "),(" + chBnd.Width + "," +
249                             chBnd.Height + "): " +
250                             util.AccessibilityTools.accessibleToString(
251                                     children[i]));
252 
253                 XAccessibleContext xAc = (XAccessibleContext) UnoRuntime.queryInterface(
254                                                  XAccessibleContext.class,
255                                                  children[i]);
256 
257                 boolean MightBeCovered = false;
258                 boolean isShowing = xAc.getAccessibleStateSet()
259                                        .contains(com.sun.star.accessibility.AccessibleStateType.SHOWING);
260                 log.println("\tStateType containsPoint SHOWING: " +
261                             isShowing);
262 
263                 if (!isShowing) {
264                     log.println("Child is invisible - OK");
265 
266                     continue;
267                 }
268 
269                 log.println("finding the point which lies on the component");
270 
271                 int curX = chBnd.Width / 2;
272                 int curY = chBnd.Height / 2;
273 
274                 while (!children[i].containsPoint(new Point(curX, curY)) &&
275                        (curX > 0) && (curY > 0)) {
276                     curX--;
277                     curY--;
278                 }
279 
280                 ;
281 
282                 if ((curX == chBnd.Width) && isShowing) {
283                     log.println("Couldn't find a point with containsPoint");
284 
285                     continue;
286                 }
287 
288                 // trying the point laying on child
289                 XAccessible xAcc = oObj.getAccessibleAtPoint(
290                                            new Point(chBnd.X + curX,
291                                                      chBnd.Y + curY));
292 
293 
294                 Point p = new Point(chBnd.X + curX,chBnd.X + curX);
295 
296                 if (isCovered(p) && isShowing) {
297                     log.println(
298                             "Child might be covered by another and can't be reached");
299                     MightBeCovered = true;
300                 }
301 
302                 KnownBounds.add(chBnd);
303 
304                 if (xAcc == null) {
305                     log.println("The child not found at point (" +
306                                 (chBnd.X + curX) + "," + (chBnd.Y + curY) +
307                                 ") - FAILED");
308 
309                     if (isShowing) {
310                         result = false;
311                     } else {
312                         result &= true;
313                     }
314                 } else {
315                     XAccessible xAccCh = (XAccessible) UnoRuntime.queryInterface(
316                                                  XAccessible.class,
317                                                  children[i]);
318                     XAccessibleContext xAccC = (XAccessibleContext) UnoRuntime.queryInterface(
319                                                        XAccessibleContext.class,
320                                                        children[i]);
321                     log.println("Child found at point (" + (chBnd.X + curX) +
322                                 "," + (chBnd.Y + curY) + ") - OK");
323 
324                     boolean res = false;
325                     int expIndex;
326                     String expName;
327                     String expDesc;
328 
329                     if (xAccCh != null) {
330                         res = util.AccessibilityTools.equals(xAccCh, xAcc);
331                         expIndex = xAccCh.getAccessibleContext()
332                                          .getAccessibleIndexInParent();
333                         expName = xAccCh.getAccessibleContext()
334                                         .getAccessibleName();
335                         expDesc = xAccCh.getAccessibleContext()
336                                         .getAccessibleDescription();
337                     } else {
338                         res = xAccC.getAccessibleName()
339                                    .equals(xAcc.getAccessibleContext()
340                                                .getAccessibleName());
341                         expIndex = xAccC.getAccessibleIndexInParent();
342                         expName = xAccC.getAccessibleName();
343                         expDesc = xAccC.getAccessibleDescription();
344                     }
345 
346                     if (!res) {
347                         int gotIndex = xAcc.getAccessibleContext()
348                                            .getAccessibleIndexInParent();
349 
350                         if (expIndex < gotIndex) {
351                             log.println("The children found is not the same");
352                             log.println("The expected child " + expName);
353                             log.print("is hidden behind the found Child ");
354                             log.println(xAcc.getAccessibleContext()
355                                             .getAccessibleName() + " - OK");
356                         } else {
357                             log.println(
358                                     "The children found is not the same");
359                             log.println("Expected: " + expName);
360                             log.println("Description:  " + expDesc);
361                             log.println("Found: " +
362                                         xAcc.getAccessibleContext()
363                                             .getAccessibleName());
364                             log.println("Description:  " +
365                                         xAcc.getAccessibleContext()
366                                             .getAccessibleDescription());
367                             if (MightBeCovered) {
368                                 log.println("... Child is covered by another - OK");
369                             } else {
370                                 log.println("... FAILED");
371                                 result = false;
372                             }
373 
374                         }
375                     }
376                 }
377 
378 
379                 // trying the point NOT laying on child
380                 xAcc = oObj.getAccessibleAtPoint(
381                                new Point(chBnd.X - 1, chBnd.Y - 1));
382 
383                 if (xAcc == null) {
384                     log.println("No children found at point (" +
385                                 (chBnd.X - 1) + "," + (chBnd.Y - 1) +
386                                 ") - OK");
387                     result &= true;
388                 } else {
389                     XAccessible xAccCh = (XAccessible) UnoRuntime.queryInterface(
390                                                  XAccessible.class,
391                                                  children[i]);
392                     boolean res = util.AccessibilityTools.equals(xAccCh, xAcc);
393 
394                     if (res) {
395                         log.println("The same child found outside " +
396                                     "its bounds at (" + (chBnd.X - 1) + "," +
397                                     (chBnd.Y - 1) + ") - FAILED");
398                         result = false;
399                     }
400                 }
401             }
402         } else {
403             log.println("There are no children supporting " +
404                         "XAccessibleComponent");
405         }
406 
407         tRes.tested("getAccessibleAtPoint()", result);
408     }
409 
410     /**
411      * Retrieves the component bounds and stores it. <p>
412      *
413      * Has <b> OK </b> status if boundary position (x,y) is not negative
414      * and size (Width, Height) is greater than 0.
415      */
416     public void _getBounds() {
417         boolean result = true;
418 
419         bounds = oObj.getBounds();
420         result &= ((bounds != null) && (bounds.X >= 0) && (bounds.Y >= 0) && (bounds.Width > 0) && (bounds.Height > 0));
421 
422         log.println("Bounds = " +
423                     ((bounds != null)
424                      ? ("(" + bounds.X + "," + bounds.Y + "),(" +
425                                bounds.Width + "," + bounds.Height + ")") : "null"));
426 
427         tRes.tested("getBounds()", result);
428     }
429 
430     /**
431      * Gets the location. <p>
432      *
433      * Has <b> OK </b> status if the location is the same as location
434      * of boundary obtained by <code>getBounds()</code> method.
435      *
436      * The following method tests are to be completed successfully before :
437      * <ul>
438      *  <li> <code> getBounds() </code> : to have bounds </li>
439      * </ul>
440      */
441     public void _getLocation() {
442         requiredMethod("getBounds()");
443 
444         boolean result = true;
445         Point loc = oObj.getLocation();
446 
447         result &= ((loc.X == bounds.X) && (loc.Y == bounds.Y));
448 
449         tRes.tested("getLocation()", result);
450     }
451 
452     /**
453      * Get the screen location of the component and its parent
454      * (if it exists and supports <code>XAccessibleComponent</code>). <p>
455      *
456      * Has <b> OK </b> status if component screen location equals
457      * to screen location of its parent plus location of the component
458      * relative to the parent. <p>
459      *
460      * The following method tests are to be completed successfully before :
461      * <ul>
462      *  <li> <code> getBounds() </code> : to have location of the component
463      *      relative to its parent</li>
464      * </ul>
465      */
466     public void _getLocationOnScreen() {
467         requiredMethod("getBounds()");
468 
469         XAccessibleComponent parent = getParentComponent();
470 
471         boolean result = true;
472         Point loc = oObj.getLocationOnScreen();
473         log.println("Location is (" + loc.X + "," + loc.Y + ")");
474 
475         if (parent != null) {
476             Point parLoc = parent.getLocationOnScreen();
477             log.println("Parent location is (" + parLoc.X + "," + parLoc.Y +
478                         ")");
479 
480             result &= ((parLoc.X + bounds.X) == loc.X);
481             result &= ((parLoc.Y + bounds.Y) == loc.Y);
482         }
483 
484         tRes.tested("getLocationOnScreen()", result);
485     }
486 
487     /**
488      * Obtains the size of the component. <p>
489      *
490      * Has <b> OK </b> status if the size is the same as in bounds. <p>
491      *
492      * The following method tests are to be completed successfully before :
493      * <ul>
494      *  <li> <code> getBounds() </code>  </li>
495      * </ul>
496      */
497     public void _getSize() {
498         requiredMethod("getBounds()");
499 
500         boolean result = true;
501         Size size = oObj.getSize();
502 
503         result &= (size.Width == bounds.Width);
504         result &= (size.Height == bounds.Height);
505 
506         tRes.tested("getSize()", result);
507     }
508 
509     /**
510      * Just calls the method. <p>
511      *
512      * Has <b> OK </b> status if no runtime exceptions occured.
513      */
514     public void _grabFocus() {
515         boolean result = true;
516         oObj.grabFocus();
517 
518         tRes.tested("grabFocus()", result);
519     }
520 
521     /**
522      * Retrieves all children (not more than 50) of the current
523      * component which support <code>XAccessibleComponent</code>.
524      *
525      * @return The array of children. Empty array returned if
526      * such children were not found or some error occured.
527      */
528     private XAccessibleComponent[] getChildrenComponents() {
529         XAccessible xAcc = (XAccessible) UnoRuntime.queryInterface(
530                                    XAccessible.class, oObj);
531 
532         if (xAcc == null) {
533             log.println("Component doesn't support XAccessible.");
534 
535             return new XAccessibleComponent[0];
536         }
537 
538         XAccessibleContext xAccCon = xAcc.getAccessibleContext();
539         int cnt = xAccCon.getAccessibleChildCount();
540 
541         // for cases when too many children exist checking only first 50
542         if (cnt > 50) {
543             cnt = 50;
544         }
545 
546         Vector childComp = new Vector();
547 
548         for (int i = 0; i < cnt; i++) {
549             try {
550                 XAccessible child = xAccCon.getAccessibleChild(i);
551                 XAccessibleContext xAccConCh = child.getAccessibleContext();
552                 XAccessibleComponent xChAccComp = (XAccessibleComponent) UnoRuntime.queryInterface(
553                                                           XAccessibleComponent.class,
554                                                           xAccConCh);
555 
556                 if (xChAccComp != null) {
557                     childComp.add(xChAccComp);
558                 }
559             } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
560             }
561         }
562 
563         return (XAccessibleComponent[]) childComp.toArray(
564                          new XAccessibleComponent[childComp.size()]);
565     }
566 
567     /**
568      * Gets the parent of the current component which support
569      * <code>XAccessibleComponent</code>.
570      *
571      * @return The parent or <code>null</code> if the component
572      * has no parent or some errors occured.
573      */
574     private XAccessibleComponent getParentComponent() {
575         XAccessible xAcc = (XAccessible) UnoRuntime.queryInterface(
576                                    XAccessible.class, oObj);
577 
578         if (xAcc == null) {
579             log.println("Component doesn't support XAccessible.");
580 
581             return null;
582         }
583 
584         XAccessibleContext xAccCon = xAcc.getAccessibleContext();
585         XAccessible xAccPar = xAccCon.getAccessibleParent();
586 
587         if (xAccPar == null) {
588             log.println("Component has no accessible parent.");
589 
590             return null;
591         }
592 
593         XAccessibleContext xAccConPar = xAccPar.getAccessibleContext();
594         XAccessibleComponent parent = (XAccessibleComponent) UnoRuntime.queryInterface(
595                                               XAccessibleComponent.class,
596                                               xAccConPar);
597 
598         if (parent == null) {
599             log.println(
600                     "Accessible parent doesn't support XAccessibleComponent");
601 
602             return null;
603         }
604 
605         return parent;
606     }
607 
608     /**
609      * Just calls the method.
610      */
611     public void _getForeground() {
612         int forColor = oObj.getForeground();
613         log.println("getForeground(): " + forColor);
614         tRes.tested("getForeground()", true);
615     }
616 
617     /**
618      * Just calls the method.
619      */
620     public void _getBackground() {
621         int backColor = oObj.getBackground();
622         log.println("getBackground(): " + backColor);
623         tRes.tested("getBackground()", true);
624     }
625 
626     /**
627      * Restores initial component text.
628      */
629     protected void after() {
630         if (tEnv.getObjRelation("Destroy") != null) {
631             disposeEnvironment();
632         }
633     }
634 
635     private boolean isCovered(Point p) {
636         int elements = KnownBounds.size();
637         boolean Covered = false;
638         for (int k=0;k<elements;k++) {
639             Rectangle known = (Rectangle) KnownBounds.get(k);
640             Covered = (known.X < p.X);
641             Covered &= (known.Y < p.Y);
642             Covered &= (p.Y < known.Y+known.Height);
643             Covered &= (p.X < known.X+known.Width);
644 
645             if (Covered) {
646                 break;
647             }
648         }
649         return Covered;
650     }
651 }