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 }