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