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