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 24 package org.openoffice.java.accessibility; 25 26 import javax.accessibility.AccessibleContext; 27 import javax.accessibility.AccessibleState; 28 29 import com.sun.star.uno.AnyConverter; 30 import com.sun.star.uno.UnoRuntime; 31 import com.sun.star.accessibility.*; 32 33 public class List extends DescendantManager implements javax.accessibility.Accessible { 34 List(XAccessible xAccessible, XAccessibleContext xAccessibleContext)35 protected List(XAccessible xAccessible, XAccessibleContext xAccessibleContext) { 36 super(xAccessible, xAccessibleContext); 37 } 38 setActiveDescendant(javax.accessibility.Accessible descendant)39 protected void setActiveDescendant(javax.accessibility.Accessible descendant) { 40 javax.accessibility.Accessible oldAD = activeDescendant; 41 activeDescendant = descendant; 42 firePropertyChange(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY, 43 oldAD, descendant); 44 } 45 setActiveDescendant(Object any)46 protected void setActiveDescendant(Object any) { 47 javax.accessibility.Accessible descendant = null; 48 try { 49 if (AnyConverter.isObject(any)) { 50 XAccessible unoAccessible = (XAccessible) AnyConverter.toObject( 51 AccessibleObjectFactory.XAccessibleType, any); 52 if (unoAccessible != null) { 53 // FIXME: have to handle non transient objects here .. 54 descendant = new ListItem(unoAccessible); 55 if (Build.DEBUG) { 56 try { 57 if (Build.DEBUG) { 58 System.err.println("[List] retrieved active descendant event: new descendant is " + 59 unoAccessible.getAccessibleContext().getAccessibleName()); 60 } 61 } catch (java.lang.NullPointerException e) { 62 System.err.println("*** ERROR *** new active descendant not accessible"); 63 } 64 } 65 } 66 } 67 setActiveDescendant(descendant); 68 } catch (com.sun.star.lang.IllegalArgumentException e) { 69 } 70 } 71 add(XAccessible unoAccessible)72 protected void add(XAccessible unoAccessible) { 73 if (unoAccessible != null) { 74 ListItem item = new ListItem(unoAccessible); 75 // The AccessBridge for Windows expects an instance of AccessibleContext 76 // as parameters 77 firePropertyChange(AccessibleContext.ACCESSIBLE_CHILD_PROPERTY, 78 null, item.getAccessibleContext()); 79 } 80 } 81 remove(XAccessible unoAccessible)82 protected void remove(XAccessible unoAccessible) { 83 if (unoAccessible != null) { 84 ListItem item = new ListItem(unoAccessible); 85 // The AccessBridge for Windows expects an instance of AccessibleContext 86 // as parameters 87 firePropertyChange(AccessibleContext.ACCESSIBLE_CHILD_PROPERTY, 88 item.getAccessibleContext(), null); 89 } 90 } 91 add(Object any)92 protected void add(Object any) { 93 try { 94 add((XAccessible) AnyConverter.toObject(AccessibleObjectFactory.XAccessibleType, any)); 95 } catch (com.sun.star.lang.IllegalArgumentException e) { 96 } 97 } 98 remove(Object any)99 protected void remove(Object any) { 100 try { 101 remove((XAccessible) AnyConverter.toObject(AccessibleObjectFactory.XAccessibleType, any)); 102 } catch (com.sun.star.lang.IllegalArgumentException e) { 103 } 104 } 105 106 /** 107 * Update the proxy objects appropriatly on property change events 108 */ 109 protected class AccessibleListListener extends AccessibleDescendantManagerListener { 110 AccessibleListListener()111 protected AccessibleListListener() { 112 super(); 113 } 114 115 /** Called by OpenOffice process to notify property changes */ notifyEvent(AccessibleEventObject event)116 public void notifyEvent(AccessibleEventObject event) { 117 switch (event.EventId) { 118 case AccessibleEventId.ACTIVE_DESCENDANT_CHANGED: 119 setActiveDescendant(event.NewValue); 120 break; 121 case AccessibleEventId.CHILD: 122 if (AnyConverter.isObject(event.OldValue)) { 123 remove(event.OldValue); 124 } 125 if (AnyConverter.isObject(event.NewValue)) { 126 add(event.NewValue); 127 } 128 break; 129 case AccessibleEventId.INVALIDATE_ALL_CHILDREN: 130 // Since List items a transient a child events are mostly used 131 // to attach/detach listeners, it is save to ignore it here 132 break; 133 default: 134 super.notifyEvent(event); 135 } 136 } 137 } 138 createEventListener()139 protected XAccessibleEventListener createEventListener() { 140 return new AccessibleListListener(); 141 } 142 143 /** Creates the AccessibleContext associated with this object */ createAccessibleContext()144 public javax.accessibility.AccessibleContext createAccessibleContext() { 145 return new AccessibleList(); 146 } 147 148 protected class AccessibleList extends AccessibleDescendantManager { 149 150 /** Gets the role of this object */ getAccessibleRole()151 public javax.accessibility.AccessibleRole getAccessibleRole() { 152 return javax.accessibility.AccessibleRole.LIST; 153 } 154 155 /** Returns the specified Accessible child of the object */ getAccessibleChild(int i)156 public javax.accessibility.Accessible getAccessibleChild(int i) { 157 javax.accessibility.Accessible child = null; 158 try { 159 XAccessible xAccessible = unoAccessibleContext.getAccessibleChild(i); 160 if (xAccessible != null) { 161 // Re-use the active descandant wrapper if possible 162 javax.accessibility.Accessible activeDescendant = List.this.activeDescendant; 163 if ((activeDescendant instanceof ListItem) && xAccessible.equals(((ListItem) activeDescendant).unoAccessible)) { 164 child = activeDescendant; 165 } else { 166 child = new ListItem(xAccessible); 167 } 168 } 169 } catch (com.sun.star.lang.IndexOutOfBoundsException e) { 170 } catch (com.sun.star.uno.RuntimeException e) { 171 } 172 return child; 173 } 174 175 /* 176 * AccessibleComponent 177 */ 178 179 /** Returns the Accessible child, if one exists, contained at the local coordinate Point */ getAccessibleAt(java.awt.Point p)180 public javax.accessibility.Accessible getAccessibleAt(java.awt.Point p) { 181 javax.accessibility.Accessible child = null; 182 try { 183 XAccessible xAccessible = unoAccessibleComponent.getAccessibleAtPoint(new com.sun.star.awt.Point(p.x, p.y)); 184 if (xAccessible != null) { 185 // Re-use the active descandant wrapper if possible 186 javax.accessibility.Accessible activeDescendant = List.this.activeDescendant; 187 if ((activeDescendant instanceof ListItem) && xAccessible.equals(((ListItem) activeDescendant).unoAccessible)) { 188 child = activeDescendant; 189 } else { 190 child = new ListItem(xAccessible); 191 } 192 } 193 return child; 194 } catch (com.sun.star.uno.RuntimeException e) { 195 return null; 196 } 197 } 198 199 /* 200 * AccessibleSelection 201 */ 202 203 /** Returns an Accessible representing the specified selected child of the object */ getAccessibleSelection(int i)204 public javax.accessibility.Accessible getAccessibleSelection(int i) { 205 javax.accessibility.Accessible child = null; 206 try { 207 XAccessible xAccessible = unoAccessibleSelection.getSelectedAccessibleChild(i); 208 if (xAccessible != null) { 209 // Re-use the active descandant wrapper if possible 210 javax.accessibility.Accessible activeDescendant = List.this.activeDescendant; 211 if ((activeDescendant instanceof ListItem) && xAccessible.equals(((ListItem) activeDescendant).unoAccessible)) { 212 child = activeDescendant; 213 } else { 214 child = new ListItem(xAccessible); 215 } 216 } else if (Build.DEBUG) { 217 System.out.println(i + "th selected child is not accessible"); 218 } 219 } catch (com.sun.star.lang.IndexOutOfBoundsException e) { 220 if (Build.DEBUG) { 221 System.err.println("IndexOutOfBoundsException caught for AccessibleList.getAccessibleSelection(" + i + ")"); 222 } 223 } catch (com.sun.star.uno.RuntimeException e) { 224 } 225 return child; 226 } 227 } 228 229 class ListItem extends java.awt.Component implements javax.accessibility.Accessible { 230 231 protected XAccessible unoAccessible; 232 ListItem(XAccessible xAccessible)233 public ListItem(XAccessible xAccessible) { 234 unoAccessible = xAccessible; 235 } 236 create(Object[] targetSet)237 public Object[] create(Object[] targetSet) { 238 try { 239 java.util.ArrayList list = new java.util.ArrayList(targetSet.length); 240 for (int i=0; i < targetSet.length; i++) { 241 XAccessible xAccessible = (XAccessible) UnoRuntime.queryInterface( 242 XAccessible.class, targetSet[i]); 243 if (xAccessible != null) { 244 list.add(new ListItem(xAccessible)); 245 } 246 } 247 list.trimToSize(); 248 return list.toArray(); 249 } catch (com.sun.star.uno.RuntimeException e) { 250 return null; 251 } 252 } 253 254 javax.accessibility.AccessibleContext accessibleContext = null; 255 256 /** Returns the AccessibleContext associated with this object */ getAccessibleContext()257 public javax.accessibility.AccessibleContext getAccessibleContext() { 258 if (accessibleContext == null) { 259 try { 260 XAccessibleContext xAccessibleContext = unoAccessible.getAccessibleContext(); 261 if (xAccessibleContext != null) { 262 javax.accessibility.AccessibleContext ac = new AccessibleListItem(xAccessibleContext); 263 if (ac != null) { 264 ac.setAccessibleParent(List.this); 265 accessibleContext = ac; 266 } 267 AccessibleStateAdapter.setComponentState(this, xAccessibleContext.getAccessibleStateSet()); 268 } 269 } catch (com.sun.star.uno.RuntimeException e) { 270 } 271 } 272 return accessibleContext; 273 } 274 275 protected class AccessibleListItem extends javax.accessibility.AccessibleContext { 276 277 XAccessibleContext unoAccessibleContext; 278 AccessibleListItem(XAccessibleContext xAccessibleContext)279 public AccessibleListItem(XAccessibleContext xAccessibleContext) { 280 unoAccessibleContext = xAccessibleContext; 281 } 282 283 /** Returns the accessible name of this object */ getAccessibleName()284 public String getAccessibleName() { 285 try { 286 return unoAccessibleContext.getAccessibleName(); 287 } catch (com.sun.star.uno.RuntimeException e) { 288 return null; 289 } 290 } 291 292 /** Sets the accessible name of this object */ setAccessibleName(String name)293 public void setAccessibleName(String name) { 294 // Not supported 295 } 296 297 /** Returns the accessible name of this object */ getAccessibleDescription()298 public String getAccessibleDescription() { 299 try { 300 return unoAccessibleContext.getAccessibleDescription(); 301 } catch (com.sun.star.uno.RuntimeException e) { 302 return null; 303 } 304 } 305 306 /** Sets the accessible name of this object */ setAccessibleDescription(String name)307 public void setAccessibleDescription(String name) { 308 // Not supported 309 } 310 311 /** Returns the accessible role of this object */ getAccessibleRole()312 public javax.accessibility.AccessibleRole getAccessibleRole() { 313 try { 314 javax.accessibility.AccessibleRole role = AccessibleRoleAdapter.getAccessibleRole( 315 unoAccessibleContext.getAccessibleRole()); 316 return (role != null) ? role : javax.accessibility.AccessibleRole.LABEL; 317 } catch(com.sun.star.uno.RuntimeException e) { 318 return null; 319 } 320 } 321 322 /** Gets the locale of the component */ getLocale()323 public java.util.Locale getLocale() throws java.awt.IllegalComponentStateException { 324 try { 325 com.sun.star.lang.Locale unoLocale = unoAccessibleContext.getLocale(); 326 return new java.util.Locale(unoLocale.Language, unoLocale.Country); 327 } catch (IllegalAccessibleComponentStateException e) { 328 throw new java.awt.IllegalComponentStateException(e.getMessage()); 329 } catch (com.sun.star.uno.RuntimeException e) { 330 return List.this.getLocale(); 331 } 332 } 333 334 /** Gets the 0-based index of this object in its accessible parent */ getAccessibleIndexInParent()335 public int getAccessibleIndexInParent() { 336 try { 337 return unoAccessibleContext.getAccessibleIndexInParent(); 338 } catch (com.sun.star.uno.RuntimeException e) { 339 return -1; 340 } 341 } 342 343 /** Returns the number of accessible children of the object. */ getAccessibleChildrenCount()344 public int getAccessibleChildrenCount() { 345 try { 346 return unoAccessibleContext.getAccessibleChildCount(); 347 } catch (com.sun.star.uno.RuntimeException e) { 348 return 0; 349 } 350 } 351 352 /** Returns the specified Accessible child of the object. */ getAccessibleChild(int i)353 public javax.accessibility.Accessible getAccessibleChild(int i) { 354 javax.accessibility.Accessible child = null; 355 try { 356 XAccessible xAccessible = unoAccessibleContext.getAccessibleChild(i); 357 // Re-use the active descandant wrapper if possible 358 javax.accessibility.Accessible activeDescendant = List.this.activeDescendant; 359 if ((activeDescendant instanceof ListItem) && ((ListItem) activeDescendant).unoAccessible.equals(xAccessible)) { 360 child = activeDescendant; 361 } else if (xAccessible != null) { 362 child = new ListItem(xAccessible); 363 } 364 } catch (com.sun.star.lang.IndexOutOfBoundsException e) { 365 } catch (com.sun.star.uno.RuntimeException e) { 366 } 367 return child; 368 } 369 370 /** Returns the state set of this object */ getAccessibleStateSet()371 public javax.accessibility.AccessibleStateSet getAccessibleStateSet() { 372 try { 373 return AccessibleStateAdapter.getAccessibleStateSet(ListItem.this, 374 unoAccessibleContext.getAccessibleStateSet()); 375 } catch (com.sun.star.uno.RuntimeException e) { 376 return AccessibleStateAdapter.getDefunctStateSet(); 377 } 378 } 379 380 /** Gets the AccessibleComponent associated with this object that has a graphical representation */ getAccessibleComponent()381 public javax.accessibility.AccessibleComponent getAccessibleComponent() { 382 try { 383 XAccessibleComponent unoAccessibleComponent = (XAccessibleComponent) 384 UnoRuntime.queryInterface(XAccessibleComponent.class, unoAccessibleContext); 385 return (unoAccessibleComponent != null) ? 386 new AccessibleComponentImpl(unoAccessibleComponent) : null; 387 } catch (com.sun.star.uno.RuntimeException e) { 388 return null; 389 } 390 } 391 392 /** Gets the AccessibleAction associated with this object that has a graphical representation */ getAccessibleAction()393 public javax.accessibility.AccessibleAction getAccessibleAction() { 394 try { 395 XAccessibleAction unoAccessibleAction = (XAccessibleAction) 396 UnoRuntime.queryInterface(XAccessibleAction.class, unoAccessibleContext); 397 return (unoAccessibleAction != null) ? 398 new AccessibleActionImpl(unoAccessibleAction) : null; 399 } catch (com.sun.star.uno.RuntimeException e) { 400 return null; 401 } 402 } 403 404 /** Gets the AccessibleText associated with this object that has a graphical representation */ getAccessibleText()405 public javax.accessibility.AccessibleText getAccessibleText() { 406 407 if (disposed) 408 return null; 409 410 try { 411 XAccessibleText unoAccessibleText = (XAccessibleText) 412 UnoRuntime.queryInterface(XAccessibleText.class, unoAccessibleContext); 413 return (unoAccessibleText != null) ? 414 new AccessibleTextImpl(unoAccessibleText) : null; 415 } catch (com.sun.star.uno.RuntimeException e) { 416 return null; 417 } 418 } 419 420 /** Gets the AccessibleValue associated with this object that has a graphical representation */ getAccessibleValue()421 public javax.accessibility.AccessibleValue getAccessibleValue() { 422 try { 423 XAccessibleValue unoAccessibleValue = (XAccessibleValue) 424 UnoRuntime.queryInterface(XAccessibleValue.class, unoAccessibleContext); 425 return (unoAccessibleValue != null) ? 426 new AccessibleValueImpl(unoAccessibleValue) : null; 427 } catch (com.sun.star.uno.RuntimeException e) { 428 return null; 429 } 430 } 431 432 /** Gets the AccessibleText associated with this object presenting text on the display */ getAccessibleIcon()433 public javax.accessibility.AccessibleIcon[] getAccessibleIcon() { 434 try { 435 XAccessibleImage unoAccessibleImage = (XAccessibleImage) 436 UnoRuntime.queryInterface(XAccessibleImage.class, unoAccessibleContext); 437 if (unoAccessibleImage != null) { 438 javax.accessibility.AccessibleIcon[] icons = { new AccessibleIconImpl(unoAccessibleImage) }; 439 return icons; 440 } 441 } catch (com.sun.star.uno.RuntimeException e) { 442 } 443 return null; 444 } 445 } 446 } 447 } 448 449