604 lines
21 KiB
Java
604 lines
21 KiB
Java
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* 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 .
|
|
*/
|
|
package ifc.accessibility;
|
|
|
|
import java.util.ArrayList;
|
|
import lib.MultiMethodTest;
|
|
|
|
import com.sun.star.accessibility.XAccessible;
|
|
import com.sun.star.accessibility.XAccessibleComponent;
|
|
import com.sun.star.accessibility.XAccessibleContext;
|
|
import com.sun.star.awt.Point;
|
|
import com.sun.star.awt.Rectangle;
|
|
import com.sun.star.awt.Size;
|
|
import com.sun.star.uno.UnoRuntime;
|
|
|
|
|
|
/**
|
|
* Testing <code>com.sun.star.accessibility.XAccessibleComponent</code>
|
|
* interface methods :
|
|
* <ul>
|
|
* <li><code> containsPoint()</code></li>
|
|
* <li><code> getAccessibleAtPoint()</code></li>
|
|
* <li><code> getBounds()</code></li>
|
|
* <li><code> getLocation()</code></li>
|
|
* <li><code> getLocationOnScreen()</code></li>
|
|
* <li><code> getSize()</code></li>
|
|
* <li><code> grabFocus()</code></li>
|
|
* <li><code> getAccessibleKeyBinding()</code></li>
|
|
* </ul> <p>
|
|
*
|
|
* @see com.sun.star.accessibility.XAccessibleComponent
|
|
*/
|
|
public class _XAccessibleComponent extends MultiMethodTest {
|
|
|
|
public XAccessibleComponent oObj = null;
|
|
private final ArrayList<Rectangle> KnownBounds = new ArrayList<Rectangle>();
|
|
|
|
|
|
/**
|
|
* First checks 4 inner bounds (upper, lower, left and right)
|
|
* of component bounding box to contain
|
|
* at least one point of the component. Second 4 outer bounds
|
|
* are checked to not contain any component points.<p>
|
|
*
|
|
* Has <b> OK </b> status if inner bounds contain component points
|
|
* and outer bounds don't contain any component points. <p>
|
|
*
|
|
* The following method tests are to be completed successfully before :
|
|
* <ul>
|
|
* <li> <code> getBounds() </code> : to have size of a component.</li>
|
|
* </ul>
|
|
*/
|
|
public void _containsPoint() {
|
|
Rectangle bounds = oObj.getBounds();
|
|
|
|
boolean result = true;
|
|
|
|
int curX = 0;
|
|
|
|
while (!oObj.containsPoint(new Point(curX, 0)) &&
|
|
(curX < bounds.Width)) {
|
|
curX++;
|
|
}
|
|
|
|
if (curX < bounds.Width) {
|
|
log.println("Upper bound of box containsPoint point (" + curX +
|
|
",0) - OK");
|
|
} else {
|
|
log.println(
|
|
"Upper bound of box containsPoint no component points - FAILED");
|
|
result = false;
|
|
}
|
|
|
|
curX = 0;
|
|
|
|
while (!oObj.containsPoint(new Point(curX, bounds.Height - 1)) &&
|
|
(curX < bounds.Width)) {
|
|
log.println("containsPoint returns false for (" + curX + "," +
|
|
bounds.Height + ")");
|
|
curX++;
|
|
}
|
|
|
|
if (curX < bounds.Width) {
|
|
log.println("Lower bound of box containsPoint point (" + curX +
|
|
"," + (bounds.Height - 1) + ") - OK");
|
|
} else {
|
|
log.println(
|
|
"Lower bound of box containsPoint no component points - FAILED");
|
|
result = false;
|
|
}
|
|
|
|
int curY = 0;
|
|
|
|
while (!oObj.containsPoint(new Point(0, curY)) &&
|
|
(curY < bounds.Height)) {
|
|
curY++;
|
|
}
|
|
|
|
if (curY < bounds.Height) {
|
|
log.println("Left bound of box containsPoint point (0," + curY +
|
|
") - OK");
|
|
} else {
|
|
log.println(
|
|
"Left bound of box containsPoint no component points - FAILED");
|
|
result = false;
|
|
}
|
|
|
|
curY = 0;
|
|
|
|
while (!oObj.containsPoint(new Point(bounds.Width - 1, curY)) &&
|
|
(curY < bounds.Height)) {
|
|
curY++;
|
|
}
|
|
|
|
if (curY < bounds.Height) {
|
|
log.println("Right bound of box containsPoint point (" +
|
|
(bounds.Width - 1) + "," + curY + ") - OK");
|
|
} else {
|
|
log.println(
|
|
"Right bound of box containsPoint no component points - FAILED");
|
|
result = false;
|
|
}
|
|
|
|
boolean locRes = true;
|
|
|
|
for (int x = -1; x <= bounds.Width; x++) {
|
|
if (oObj.containsPoint(new Point(x, -1))) {
|
|
log.println(
|
|
"Outer upper and lower bounds CONTAIN some component point"
|
|
+ " (" + x + ", -1) - FAILED");
|
|
locRes = false;
|
|
break;
|
|
}
|
|
if (oObj.containsPoint(new Point(x, bounds.Height + bounds.Y))) {
|
|
log.println(
|
|
"Outer upper and lower bounds CONTAIN some component point"
|
|
+ " (" + x + ", " + (bounds.Height + bounds.Y)
|
|
+ ") - FAILED");
|
|
locRes = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (locRes) {
|
|
log.println("Outer upper and lower bounds contain no component " +
|
|
"points - OK");
|
|
} else {
|
|
result = false;
|
|
}
|
|
|
|
locRes = true;
|
|
|
|
for (int y = -1; y <= bounds.Height; y++) {
|
|
if (oObj.containsPoint(new Point(-1, y))) {
|
|
log.println(
|
|
"Outer left and right bounds CONTAIN some component point"
|
|
+ " (-1, " + y + ") - FAILED");
|
|
locRes = false;
|
|
break;
|
|
}
|
|
if (oObj.containsPoint(new Point(bounds.X + bounds.Width, y))) {
|
|
log.println(
|
|
"Outer left and right bounds CONTAIN some component point"
|
|
+ " (" + (bounds.X + bounds.Width) + ", " + y + ") - FAILED");
|
|
locRes = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (locRes) {
|
|
log.println("Outer left and right bounds contain no component " +
|
|
"points - OK");
|
|
} else {
|
|
result = false;
|
|
}
|
|
|
|
tRes.tested("containsPoint()", result);
|
|
}
|
|
|
|
/**
|
|
* Iterates through all children which implement
|
|
* <code>XAccessibleComponent</code> (if they exist) determines their
|
|
* boundaries and tries to get each child by <code>getAccessibleAtPoint</code>
|
|
* passing point which belongs to the child.
|
|
* Also the point is checked which doesn't belong to child boundary
|
|
* box. <p>
|
|
*
|
|
* Has <b> OK </b> status if in the first cases the right children
|
|
* are returned, and in the second <code>null</code> or
|
|
* another child is returned.
|
|
*/
|
|
public void _getAccessibleAtPoint() {
|
|
boolean result = true;
|
|
XAccessibleComponent[] children = getChildrenComponents();
|
|
|
|
if (children.length == 0) {
|
|
log.println("There are no children supporting XAccessibleComponent");
|
|
tRes.tested("getAccessibleAtPoint()", result);
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < children.length; i++) {
|
|
Rectangle chBnd = children[i].getBounds();
|
|
|
|
if (chBnd.X == -1) {
|
|
continue;
|
|
}
|
|
|
|
log.println("Checking child with bounds " + "(" + chBnd.X +
|
|
"," + chBnd.Y + "),(" + chBnd.Width + "," +
|
|
chBnd.Height + "): " +
|
|
util.AccessibilityTools.accessibleToString(
|
|
children[i]));
|
|
|
|
XAccessibleContext xAc = UnoRuntime.queryInterface(
|
|
XAccessibleContext.class,
|
|
children[i]);
|
|
|
|
boolean MightBeCovered = false;
|
|
boolean isShowing = (xAc.getAccessibleStateSet() &
|
|
com.sun.star.accessibility.AccessibleStateType.SHOWING) != 0;
|
|
log.println("\tStateType containsPoint SHOWING: " +
|
|
isShowing);
|
|
|
|
if (!isShowing) {
|
|
log.println("Child is invisible - OK");
|
|
continue;
|
|
}
|
|
|
|
log.println("finding the point which lies on the component");
|
|
|
|
int curX = chBnd.Width / 2;
|
|
int curY = chBnd.Height / 2;
|
|
|
|
while (!children[i].containsPoint(new Point(curX, curY)) &&
|
|
(curX > 0) && (curY > 0)) {
|
|
curX--;
|
|
curY--;
|
|
}
|
|
|
|
if (curX == chBnd.Width) {
|
|
log.println("Couldn't find a point with containsPoint");
|
|
|
|
continue;
|
|
}
|
|
|
|
// trying the point laying on child
|
|
XAccessible xAcc = oObj.getAccessibleAtPoint(
|
|
new Point(chBnd.X + curX,
|
|
chBnd.Y + curY));
|
|
|
|
|
|
Point p = new Point(chBnd.X + curX,chBnd.Y + curY);
|
|
|
|
if (isCovered(p)) {
|
|
log.println(
|
|
"Child might be covered by another and can't be reached");
|
|
MightBeCovered = true;
|
|
}
|
|
|
|
KnownBounds.add(chBnd);
|
|
|
|
if (xAcc == null) {
|
|
log.println("The child not found at point (" +
|
|
(chBnd.X + curX) + "," + (chBnd.Y + curY) +
|
|
") - FAILED");
|
|
|
|
result = false;
|
|
} else {
|
|
XAccessible xAccCh = UnoRuntime.queryInterface(
|
|
XAccessible.class,
|
|
children[i]);
|
|
XAccessibleContext xAccC = UnoRuntime.queryInterface(
|
|
XAccessibleContext.class,
|
|
children[i]);
|
|
log.println("Child found at point (" + (chBnd.X + curX) +
|
|
"," + (chBnd.Y + curY) + ") - OK");
|
|
|
|
boolean res = false;
|
|
long expIndex;
|
|
String expName;
|
|
String expDesc;
|
|
|
|
if (xAccCh != null) {
|
|
res = util.AccessibilityTools.equals(xAccCh, xAcc);
|
|
expIndex = xAccCh.getAccessibleContext()
|
|
.getAccessibleIndexInParent();
|
|
expName = xAccCh.getAccessibleContext()
|
|
.getAccessibleName();
|
|
expDesc = xAccCh.getAccessibleContext()
|
|
.getAccessibleDescription();
|
|
} else {
|
|
res = xAccC.getAccessibleName()
|
|
.equals(xAcc.getAccessibleContext()
|
|
.getAccessibleName());
|
|
expIndex = xAccC.getAccessibleIndexInParent();
|
|
expName = xAccC.getAccessibleName();
|
|
expDesc = xAccC.getAccessibleDescription();
|
|
}
|
|
|
|
if (!res) {
|
|
long gotIndex = xAcc.getAccessibleContext()
|
|
.getAccessibleIndexInParent();
|
|
|
|
if (expIndex < gotIndex) {
|
|
log.println("The children found is not the same");
|
|
log.println("The expected child " + expName);
|
|
log.print("is hidden behind the found Child ");
|
|
log.println(xAcc.getAccessibleContext()
|
|
.getAccessibleName() + " - OK");
|
|
} else {
|
|
log.println(
|
|
"The children found is not the same");
|
|
log.println("Expected: " + expName);
|
|
log.println("Description: " + expDesc);
|
|
log.println("Found: " +
|
|
xAcc.getAccessibleContext()
|
|
.getAccessibleName());
|
|
log.println("Description: " +
|
|
xAcc.getAccessibleContext()
|
|
.getAccessibleDescription());
|
|
if (MightBeCovered) {
|
|
log.println("... Child is covered by another - OK");
|
|
} else {
|
|
log.println(
|
|
"(xAccCh==null: " + (xAccCh == null) + "; expIndex: " + expIndex
|
|
+ "; gotIndex: " + gotIndex + ")");
|
|
log.println("... FAILED");
|
|
result = false;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// trying the point NOT laying on child
|
|
xAcc = oObj.getAccessibleAtPoint(
|
|
new Point(chBnd.X - 1, chBnd.Y - 1));
|
|
|
|
if (xAcc == null) {
|
|
log.println("No children found at point (" +
|
|
(chBnd.X - 1) + "," + (chBnd.Y - 1) +
|
|
") - OK");
|
|
result &= true;
|
|
} else {
|
|
XAccessible xAccCh = UnoRuntime.queryInterface(
|
|
XAccessible.class,
|
|
children[i]);
|
|
boolean res = util.AccessibilityTools.equals(xAccCh, xAcc);
|
|
|
|
if (res) {
|
|
log.println("The same child found outside " +
|
|
"its bounds at (" + (chBnd.X - 1) + "," +
|
|
(chBnd.Y - 1) + ") - FAILED");
|
|
result = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
tRes.tested("getAccessibleAtPoint()", result);
|
|
}
|
|
|
|
/**
|
|
* Retrieves the component bounds and discards it. <p>
|
|
*
|
|
* Has <b> OK </b> status if boundary position (x,y) is not negative
|
|
* and size (Width, Height) is greater than 0.
|
|
*/
|
|
public void _getBounds() {
|
|
boolean result = true;
|
|
|
|
Rectangle bounds = oObj.getBounds();
|
|
result &= ((bounds != null) && (bounds.X >= 0) && (bounds.Y >= 0) && (bounds.Width > 0) && (bounds.Height > 0));
|
|
|
|
log.println("Bounds = " +
|
|
((bounds != null)
|
|
? ("(" + bounds.X + "," + bounds.Y + "),(" +
|
|
bounds.Width + "," + bounds.Height + ")") : "null"));
|
|
|
|
tRes.tested("getBounds()", result);
|
|
}
|
|
|
|
/**
|
|
* Gets the location. <p>
|
|
*
|
|
* Has <b> OK </b> status if the location is the same as location
|
|
* of boundary obtained by <code>getBounds()</code> method.
|
|
*/
|
|
public void _getLocation() {
|
|
Rectangle bounds = oObj.getBounds();
|
|
Point loc = oObj.getLocation();
|
|
boolean result = loc.X == bounds.X && loc.Y == bounds.Y;
|
|
log.println(
|
|
"loc.X=" + loc.X + " vs. bounds.X=" + bounds.X + ", loc.Y="
|
|
+ loc.Y + " vs. bounds.Y=" + bounds.Y);
|
|
tRes.tested("getLocation()", result);
|
|
}
|
|
|
|
/**
|
|
* Get the screen location of the component and its parent
|
|
* (if it exists and supports <code>XAccessibleComponent</code>). <p>
|
|
*
|
|
* Has <b> OK </b> status if component screen location equals
|
|
* to screen location of its parent plus location of the component
|
|
* relative to the parent. <p>
|
|
*/
|
|
public void _getLocationOnScreen() {
|
|
XAccessibleComponent parent = getParentComponent();
|
|
|
|
boolean result = true;
|
|
Rectangle bounds = oObj.getBounds();
|
|
Point loc = oObj.getLocationOnScreen();
|
|
log.println("Location is (" + loc.X + "," + loc.Y + ")");
|
|
|
|
if (parent != null) {
|
|
Point parLoc = parent.getLocationOnScreen();
|
|
log.println("Parent location is (" + parLoc.X + "," + parLoc.Y +
|
|
")");
|
|
|
|
result &= ((parLoc.X + bounds.X) == loc.X);
|
|
result &= ((parLoc.Y + bounds.Y) == loc.Y);
|
|
}
|
|
|
|
tRes.tested("getLocationOnScreen()", result);
|
|
}
|
|
|
|
/**
|
|
* Obtains the size of the component. <p>
|
|
*
|
|
* Has <b> OK </b> status if the size is the same as in bounds. <p>
|
|
*/
|
|
public void _getSize() {
|
|
requiredMethod("getBounds()");
|
|
|
|
boolean result = true;
|
|
Rectangle bounds = oObj.getBounds();
|
|
Size size = oObj.getSize();
|
|
|
|
result &= (size.Width == bounds.Width);
|
|
result &= (size.Height == bounds.Height);
|
|
|
|
tRes.tested("getSize()", result);
|
|
}
|
|
|
|
/**
|
|
* Just calls the method. <p>
|
|
*
|
|
* Has <b> OK </b> status if no runtime exceptions occurred.
|
|
*/
|
|
public void _grabFocus() {
|
|
boolean result = true;
|
|
oObj.grabFocus();
|
|
|
|
tRes.tested("grabFocus()", result);
|
|
}
|
|
|
|
/**
|
|
* Retrieves all children (not more than 50) of the current
|
|
* component which support <code>XAccessibleComponent</code>.
|
|
*
|
|
* @return The array of children. Empty array returned if
|
|
* such children were not found or some error occurred.
|
|
*/
|
|
private XAccessibleComponent[] getChildrenComponents() {
|
|
XAccessible xAcc = UnoRuntime.queryInterface(
|
|
XAccessible.class, oObj);
|
|
|
|
if (xAcc == null) {
|
|
log.println("Component doesn't support XAccessible.");
|
|
|
|
return new XAccessibleComponent[0];
|
|
}
|
|
|
|
XAccessibleContext xAccCon = xAcc.getAccessibleContext();
|
|
long cnt = xAccCon.getAccessibleChildCount();
|
|
|
|
// for cases when too many children exist checking only first 50
|
|
if (cnt > 50) {
|
|
cnt = 50;
|
|
}
|
|
|
|
ArrayList<XAccessibleComponent> childComp = new ArrayList<XAccessibleComponent>();
|
|
|
|
for (long i = 0; i < cnt; i++) {
|
|
try {
|
|
XAccessible child = xAccCon.getAccessibleChild(i);
|
|
XAccessibleContext xAccConCh = child.getAccessibleContext();
|
|
XAccessibleComponent xChAccComp = UnoRuntime.queryInterface(
|
|
XAccessibleComponent.class,
|
|
xAccConCh);
|
|
|
|
if (xChAccComp != null) {
|
|
childComp.add(xChAccComp);
|
|
}
|
|
} catch (com.sun.star.lang.IndexOutOfBoundsException e) {
|
|
}
|
|
}
|
|
|
|
return childComp.toArray(
|
|
new XAccessibleComponent[childComp.size()]);
|
|
}
|
|
|
|
/**
|
|
* Gets the parent of the current component which support
|
|
* <code>XAccessibleComponent</code>.
|
|
*
|
|
* @return The parent or <code>null</code> if the component
|
|
* has no parent or some errors occurred.
|
|
*/
|
|
private XAccessibleComponent getParentComponent() {
|
|
XAccessible xAcc = UnoRuntime.queryInterface(
|
|
XAccessible.class, oObj);
|
|
|
|
if (xAcc == null) {
|
|
log.println("Component doesn't support XAccessible.");
|
|
|
|
return null;
|
|
}
|
|
|
|
XAccessibleContext xAccCon = xAcc.getAccessibleContext();
|
|
XAccessible xAccPar = xAccCon.getAccessibleParent();
|
|
|
|
if (xAccPar == null) {
|
|
log.println("Component has no accessible parent.");
|
|
|
|
return null;
|
|
}
|
|
|
|
XAccessibleContext xAccConPar = xAccPar.getAccessibleContext();
|
|
XAccessibleComponent parent = UnoRuntime.queryInterface(
|
|
XAccessibleComponent.class,
|
|
xAccConPar);
|
|
|
|
if (parent == null) {
|
|
log.println(
|
|
"Accessible parent doesn't support XAccessibleComponent");
|
|
|
|
return null;
|
|
}
|
|
|
|
return parent;
|
|
}
|
|
|
|
/**
|
|
* Just calls the method.
|
|
*/
|
|
public void _getForeground() {
|
|
int forColor = oObj.getForeground();
|
|
log.println("getForeground(): " + forColor);
|
|
tRes.tested("getForeground()", true);
|
|
}
|
|
|
|
/**
|
|
* Just calls the method.
|
|
*/
|
|
public void _getBackground() {
|
|
int backColor = oObj.getBackground();
|
|
log.println("getBackground(): " + backColor);
|
|
tRes.tested("getBackground()", true);
|
|
}
|
|
|
|
/**
|
|
* Restores initial component text.
|
|
*/
|
|
@Override
|
|
protected void after() {
|
|
if (tEnv.getObjRelation("Destroy") != null) {
|
|
disposeEnvironment();
|
|
}
|
|
}
|
|
|
|
private boolean isCovered(Point p) {
|
|
int elements = KnownBounds.size();
|
|
boolean Covered = false;
|
|
for (int k=0;k<elements;k++) {
|
|
Rectangle known = KnownBounds.get(k);
|
|
Covered = (known.X < p.X);
|
|
Covered &= (known.Y < p.Y);
|
|
Covered &= (p.Y < known.Y+known.Height);
|
|
Covered &= (p.X < known.X+known.Width);
|
|
|
|
if (Covered) {
|
|
break;
|
|
}
|
|
}
|
|
return Covered;
|
|
}
|
|
}
|