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 util; 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.XWindow; 33 import com.sun.star.frame.XController; 34 import com.sun.star.frame.XFrame; 35 import com.sun.star.frame.XModel; 36 import com.sun.star.lang.XMultiServiceFactory; 37 import com.sun.star.uno.UnoRuntime; 38 import com.sun.star.uno.XInterface; 39 40 import java.io.PrintWriter; 41 42 43 public class AccessibilityTools { 44 public static XAccessibleContext SearchedContext = null; 45 public static XAccessible SearchedAccessible = null; 46 private static boolean debug = false; 47 48 public AccessibilityTools() { 49 //done = false; 50 SearchedContext = null; 51 } 52 53 public static XAccessible getAccessibleObject(XInterface xObject) { 54 return UnoRuntime.queryInterface(XAccessible.class, xObject); 55 } 56 57 public static XWindow getCurrentContainerWindow(XMultiServiceFactory msf, 58 XModel xModel) { 59 return getWindow(msf, xModel, true); 60 } 61 62 public static XWindow getCurrentWindow(XMultiServiceFactory msf, 63 XModel xModel) { 64 return getWindow(msf, xModel, false); 65 } 66 67 private static XWindow getWindow(XMultiServiceFactory msf, XModel xModel, 68 boolean containerWindow) { 69 XWindow xWindow = null; 70 71 try { 72 if (xModel == null) { 73 System.out.println("invalid model (==null)"); 74 } 75 76 XController xController = xModel.getCurrentController(); 77 78 if (xController == null) { 79 System.out.println("can't get controller from model"); 80 } 81 82 XFrame xFrame = xController.getFrame(); 83 84 if (xFrame == null) { 85 System.out.println("can't get frame from controller"); 86 } 87 88 if (containerWindow) 89 xWindow = xFrame.getContainerWindow(); 90 else 91 xWindow = xFrame.getComponentWindow(); 92 93 if (xWindow == null) { 94 System.out.println("can't get window from frame"); 95 } 96 } catch (Exception e) { 97 System.out.println("caught exception while getting current window" + e); 98 } 99 100 return xWindow; 101 } 102 103 public static XAccessibleContext getAccessibleObjectForRole(XAccessible xacc, 104 short role) { 105 SearchedContext = null; 106 SearchedAccessible = null; 107 getAccessibleObjectForRole_(xacc, role); 108 109 return SearchedContext; 110 } 111 112 public static XAccessibleContext getAccessibleObjectForRole(XAccessible xacc, 113 short role, 114 boolean ignoreShowing) { 115 SearchedContext = null; 116 SearchedAccessible = null; 117 118 if (ignoreShowing) { 119 getAccessibleObjectForRoleIgnoreShowing_(xacc, role); 120 } else { 121 getAccessibleObjectForRole_(xacc, role); 122 } 123 124 return SearchedContext; 125 } 126 127 public static void getAccessibleObjectForRoleIgnoreShowing_(XAccessible xacc, 128 short role) { 129 XAccessibleContext ac = xacc.getAccessibleContext(); 130 131 if (ac.getAccessibleRole() == role) { 132 SearchedContext = ac; 133 SearchedAccessible = xacc; 134 } else { 135 int k = ac.getAccessibleChildCount(); 136 137 if (ac.getAccessibleChildCount() > 100) { 138 k = 50; 139 } 140 141 for (int i = 0; i < k; i++) { 142 try { 143 getAccessibleObjectForRoleIgnoreShowing_( 144 ac.getAccessibleChild(i), role); 145 146 if (SearchedContext != null) { 147 return; 148 } 149 } catch (com.sun.star.lang.IndexOutOfBoundsException e) { 150 System.out.println("Couldn't get Child"); 151 } 152 } 153 } 154 } 155 156 public static void getAccessibleObjectForRole_(XAccessible xacc, 157 short role) { 158 XAccessibleContext ac = xacc.getAccessibleContext(); 159 boolean isShowing = ac.getAccessibleStateSet() 160 .contains(com.sun.star.accessibility.AccessibleStateType.SHOWING); 161 162 if ((ac.getAccessibleRole() == role) && isShowing) { 163 SearchedContext = ac; 164 SearchedAccessible = xacc; 165 } else { 166 int k = ac.getAccessibleChildCount(); 167 168 if (ac.getAccessibleChildCount() > 100) { 169 k = 50; 170 } 171 172 for (int i = 0; i < k; i++) { 173 try { 174 getAccessibleObjectForRole_(ac.getAccessibleChild(i), role); 175 176 if (SearchedContext != null) { 177 return; 178 } 179 } catch (com.sun.star.lang.IndexOutOfBoundsException e) { 180 System.out.println("Couldn't get Child"); 181 } 182 } 183 } 184 } 185 186 public static XAccessibleContext getAccessibleObjectForRole(XAccessible xacc, 187 short role, 188 String name) { 189 return getAccessibleObjectForRole(xacc, role, name, ""); 190 } 191 192 public static XAccessibleContext getAccessibleObjectForRole(XAccessible xacc, 193 short role, 194 String name, 195 boolean ignoreShowing) { 196 if (ignoreShowing) { 197 return getAccessibleObjectForRoleIgnoreShowing(xacc, role, name, 198 ""); 199 } else { 200 return getAccessibleObjectForRole(xacc, role, name, ""); 201 } 202 } 203 204 public static XAccessibleContext getAccessibleObjectForRoleIgnoreShowing(XAccessible xacc, 205 short role, 206 String name, 207 String implName) { 208 XAccessibleContext ac = xacc.getAccessibleContext(); 209 if ((ac.getAccessibleRole() == role) && 210 (ac.getAccessibleName().indexOf(name) > -1) && 211 (utils.getImplName(ac).indexOf(implName) > -1)) { 212 SearchedAccessible = xacc; 213 214 //System.out.println("FOUND the desired component -- "+ ac.getAccessibleName() +isShowing); 215 return ac; 216 } else { 217 int k = ac.getAccessibleChildCount(); 218 219 if (ac.getAccessibleChildCount() > 100) { 220 k = 50; 221 } 222 223 for (int i = 0; i < k; i++) { 224 try { 225 XAccessibleContext ac1 = getAccessibleObjectForRoleIgnoreShowing( 226 ac.getAccessibleChild(i), 227 role, name, implName); 228 229 if (ac1 != null) { 230 return ac1; 231 } 232 } catch (com.sun.star.lang.IndexOutOfBoundsException e) { 233 System.out.println("Couldn't get Child"); 234 } 235 } 236 } 237 238 return null; 239 } 240 241 public static XAccessibleContext getAccessibleObjectForRole(XAccessible xacc, 242 short role, 243 String name, 244 String implName) { 245 XAccessibleContext ac = xacc.getAccessibleContext(); 246 boolean isShowing = ac.getAccessibleStateSet() 247 .contains(com.sun.star.accessibility.AccessibleStateType.SHOWING); 248 249 // hotfix for i91828: 250 // if role to serach is 0 then ignore the role. 251 if ( (role == 0 || ac.getAccessibleRole() == role) && 252 (ac.getAccessibleName().indexOf(name) > -1) && 253 (utils.getImplName(ac).indexOf(implName) > -1) && 254 isShowing) { 255 SearchedAccessible = xacc; 256 //System.out.println("FOUND the desired component -- "+ ac.getAccessibleName() +isShowing); 257 return ac; 258 } else { 259 int k = ac.getAccessibleChildCount(); 260 261 if (ac.getAccessibleChildCount() > 100) { 262 k = 50; 263 } 264 265 for (int i = 0; i < k; i++) { 266 try { 267 XAccessibleContext ac1 = getAccessibleObjectForRole( 268 ac.getAccessibleChild(i), 269 role, name, implName); 270 271 if (ac1 != null) { 272 return ac1; 273 } 274 } catch (com.sun.star.lang.IndexOutOfBoundsException e) { 275 System.out.println("Couldn't get Child"); 276 } 277 } 278 } 279 280 return null; 281 } 282 283 /** 284 * This methods retunrs the <CODE>XAccessibleContext</CODE> of a named Sheet-Cell like "G5".<p> 285 * @param xSheetAcc The <CODE>XAccessibleContext</CODE> of a Sheet 286 * @param cellName The name of a cell like "A5" 287 * @return the <CODE>XAccessiblecontext</CODE> of the named cell 288 */ 289 public static XAccessibleContext getSheetCell(XAccessibleContext xSheetAcc, String cellName){ 290 291 int cellIndex = 0; 292 int column =0; 293 int charMem = 0; 294 for (int n=0; n<cellName.length(); n++){ 295 String cha = cellName.substring(n,n+1); 296 System.out.println("char: " + cha + " "); 297 298 byte[] bytes = cha.getBytes(); 299 300 if ((bytes[0] >= 'A') && (bytes[0] <= 'Z')){ 301 charMem = bytes[0]-64; 302 column++; 303 if ( column == 2 ){ 304 cellIndex += charMem * 26; 305 } 306 cellIndex= cellIndex+ (bytes[0]-65); 307 } else { 308 String sNumb = cellName.substring(n, cellName.length()); 309 int iNumb = new Integer(0).valueOf(sNumb).intValue(); 310 cellIndex += (iNumb-1) * 256; 311 System.out.println("numb:" + (iNumb-1) * 256); 312 } 313 314 } 315 316 //System.out.println("cellName: " + cellName + " cellIndex: " + cellIndex); 317 318 try { 319 XAccessibleContext ac = xSheetAcc.getAccessibleChild(cellIndex).getAccessibleContext(); 320 System.out.println(ac.getAccessibleRole() + "," + 321 ac.getAccessibleName() + "(" + 322 ac.getAccessibleDescription() + "):" + 323 utils.getImplName(ac)); 324 325 return ac; 326 } catch (com.sun.star.lang.IndexOutOfBoundsException ex) { 327 System.out.println("ERROR: could not get child at index " + cellIndex +"': " + ex.toString()); 328 return null; 329 } 330 } 331 332 public static void printAccessibleTree(PrintWriter log, XAccessible xacc, boolean debugIsActive) { 333 debug = debugIsActive; 334 if (debug) printAccessibleTree(log, xacc, ""); 335 } 336 337 public static void printAccessibleTree(PrintWriter log, XAccessible xacc) { 338 printAccessibleTree(log, xacc, ""); 339 } 340 341 protected static void printAccessibleTree(PrintWriter log, 342 XAccessible xacc, String indent) { 343 344 XAccessibleContext ac = xacc.getAccessibleContext(); 345 346 logging(log,indent + ac.getAccessibleRole() + "," + 347 ac.getAccessibleName() + "(" + 348 ac.getAccessibleDescription() + "):" + 349 utils.getImplName(ac)); 350 351 XAccessibleComponent aComp = (XAccessibleComponent) UnoRuntime.queryInterface( 352 XAccessibleComponent.class, xacc); 353 354 if (aComp != null) { 355 String bounds = "(" + aComp.getBounds().X + "," + 356 aComp.getBounds().Y + ")" + " (" + 357 aComp.getBounds().Width + "," + 358 aComp.getBounds().Height + ")"; 359 bounds = "The boundary Rectangle is " + bounds; 360 logging(log,indent + indent + bounds); 361 } 362 363 boolean isShowing = ac.getAccessibleStateSet() 364 .contains(com.sun.star.accessibility.AccessibleStateType.SHOWING); 365 logging(log,indent + indent + "StateType contains SHOWING: " + 366 isShowing); 367 368 int k = ac.getAccessibleChildCount(); 369 370 if (ac.getAccessibleChildCount() > 100) { 371 k = 50; 372 } 373 374 for (int i = 0; i < k; i++) { 375 try { 376 printAccessibleTree(log, ac.getAccessibleChild(i), 377 indent + " "); 378 } catch (com.sun.star.lang.IndexOutOfBoundsException e) { 379 System.out.println("Couldn't get Child"); 380 } 381 } 382 383 if (ac.getAccessibleChildCount() > 100) { 384 k = ac.getAccessibleChildCount(); 385 386 int st = ac.getAccessibleChildCount() - 50; 387 logging(log,indent + " " + " ...... [skipped] ......"); 388 389 for (int i = st; i < k; i++) { 390 try { 391 printAccessibleTree(log, ac.getAccessibleChild(i), 392 indent + " "); 393 } catch (com.sun.star.lang.IndexOutOfBoundsException e) { 394 System.out.println("Couldn't get Child"); 395 } 396 } 397 } 398 } 399 400 public static String accessibleToString(Object AC) { 401 XAccessibleContext xAC = (XAccessibleContext) UnoRuntime.queryInterface( 402 XAccessibleContext.class, AC); 403 404 if (xAC != null) { 405 return "" + xAC.getAccessibleRole() + "," + 406 xAC.getAccessibleName() + "(" + 407 xAC.getAccessibleDescription() + "):"; 408 } 409 410 XAccessible xA = (XAccessible) UnoRuntime.queryInterface( 411 XAccessible.class, AC); 412 413 if (xA == null) { 414 return "(Not supported)"; 415 } 416 417 xAC = xA.getAccessibleContext(); 418 419 return "" + xAC.getAccessibleRole() + "," + xAC.getAccessibleName() + 420 "(" + xAC.getAccessibleDescription() + ")"; 421 } 422 423 public static boolean equals(XAccessible c1, XAccessible c2) { 424 if ((c1 == null) || (c2 == null)) { 425 return c1 == c2; 426 } 427 428 return AccessibilityTools.equals(c1.getAccessibleContext(), 429 c2.getAccessibleContext()); 430 } 431 432 public static boolean equals(XAccessibleContext c1, XAccessibleContext c2) { 433 if ((c1 == null) || (c2 == null)) { 434 return c1 == c2; 435 } 436 437 if (c1.getAccessibleRole() != c2.getAccessibleRole()) { 438 return false; 439 } 440 441 if (!c1.getAccessibleName().equals(c2.getAccessibleName())) { 442 return false; 443 } 444 445 if (!c1.getAccessibleDescription() 446 .equals(c2.getAccessibleDescription())) { 447 return false; 448 } 449 450 if (c1.getAccessibleChildCount() != c2.getAccessibleChildCount()) { 451 return false; 452 } 453 454 return AccessibilityTools.equals(c1.getAccessibleParent(), 455 c2.getAccessibleParent()); 456 } 457 458 private static void logging(PrintWriter log, String content){ 459 if (debug) log.println(content); 460 } 461 }