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.AccessibleState; 27 import javax.accessibility.AccessibleStateSet; 28 29 import com.sun.star.uno.AnyConverter; 30 import com.sun.star.accessibility.AccessibleStateType; 31 import com.sun.star.accessibility.XAccessibleStateSet; 32 33 public class AccessibleStateAdapter { 34 35 private static final AccessibleState[] stateTypeMap = { 36 null, 37 AccessibleState.ACTIVE, 38 AccessibleState.ARMED, 39 AccessibleState.BUSY, 40 AccessibleState.CHECKED, 41 AccessibleExtendedState.DEFUNCT, 42 AccessibleState.EDITABLE, 43 AccessibleState.ENABLED, 44 AccessibleState.EXPANDABLE, 45 AccessibleState.EXPANDED, 46 AccessibleState.FOCUSABLE, 47 AccessibleState.FOCUSED, 48 AccessibleState.HORIZONTAL, 49 AccessibleState.ICONIFIED, 50 AccessibleExtendedState.INDETERMINATE, 51 AccessibleExtendedState.MANAGES_DESCENDANTS, 52 AccessibleState.MODAL, 53 AccessibleState.MULTI_LINE, 54 AccessibleState.MULTISELECTABLE, 55 AccessibleState.OPAQUE, 56 AccessibleState.PRESSED, 57 AccessibleState.RESIZABLE, 58 AccessibleState.SELECTABLE, 59 AccessibleState.SELECTED, 60 AccessibleExtendedState.SENSITIVE, 61 AccessibleState.SHOWING, 62 AccessibleState.SINGLE_LINE, 63 AccessibleExtendedState.STALE, 64 AccessibleState.TRANSIENT, 65 AccessibleState.VERTICAL, 66 AccessibleState.VISIBLE 67 }; 68 printToplevelStateMessage(AccessibleState s, java.awt.Component c)69 private static void printToplevelStateMessage(AccessibleState s, java.awt.Component c) { 70 System.err.println("*** ERROR *** " + s + " state is a toplevel window state " + c); 71 } 72 getDisplayName(java.awt.Component c)73 private static String getDisplayName(java.awt.Component c) { 74 javax.accessibility.Accessible a = (javax.accessibility.Accessible) c; 75 if( a != null) { 76 javax.accessibility.AccessibleContext ac = a.getAccessibleContext(); 77 return "[" + ac.getAccessibleRole() + "] " + ac.getAccessibleName(); 78 } else { 79 return c.toString(); 80 } 81 } 82 printOutOfSyncMessage(AccessibleState s, java.awt.Component c, boolean enabled)83 private static void printOutOfSyncMessage(AccessibleState s, java.awt.Component c, boolean enabled) { 84 System.err.println("*** ERROR *** " + s + " state out of sync (UNO state set: " + !enabled + ", Java component state: " + enabled + ") for " + getDisplayName(c)); 85 } 86 getAccessibleState(Object any)87 public static AccessibleState getAccessibleState(Object any) { 88 try { 89 if (AnyConverter.isShort(any)) { 90 return getAccessibleState(AnyConverter.toShort(any)); 91 } 92 return null; 93 } catch (com.sun.star.lang.IllegalArgumentException e) { 94 return null; 95 } 96 } 97 getAccessibleState(short unoStateType)98 public static AccessibleState getAccessibleState(short unoStateType) { 99 if (unoStateType > 0 && unoStateType < stateTypeMap.length) { 100 return stateTypeMap[unoStateType]; 101 } 102 return null; 103 } 104 getDefunctStateSet()105 public static AccessibleStateSet getDefunctStateSet() { 106 AccessibleStateSet ass = new AccessibleStateSet(); 107 ass.add(AccessibleExtendedState.DEFUNCT); 108 return ass; 109 } 110 setComponentState(java.awt.Component c, XAccessibleStateSet xAccessibleStateSet)111 public static void setComponentState(java.awt.Component c, 112 XAccessibleStateSet xAccessibleStateSet) { 113 114 try { 115 if (xAccessibleStateSet != null) { 116 // Set the boundings of the component if it is visible .. 117 if (!xAccessibleStateSet.contains(AccessibleStateType.VISIBLE)) { 118 c.setVisible(false); 119 } 120 // Set the components' enabled state .. 121 if (!xAccessibleStateSet.contains(AccessibleStateType.ENABLED)) { 122 c.setEnabled(false); 123 } 124 // Set the components' focusable state .. 125 if (!xAccessibleStateSet.contains(AccessibleStateType.FOCUSABLE)) { 126 c.setFocusable(false); 127 } 128 } 129 } catch (com.sun.star.uno.RuntimeException e) { 130 } 131 } 132 getAccessibleStateSet(java.awt.Component c, XAccessibleStateSet xAccessibleStateSet)133 public static AccessibleStateSet getAccessibleStateSet(java.awt.Component c, 134 XAccessibleStateSet xAccessibleStateSet) { 135 136 try { 137 if (xAccessibleStateSet != null) { 138 AccessibleStateSet as = new AccessibleStateSet(); 139 short[] unoStateTypes = xAccessibleStateSet.getStates(); 140 for (int i=0; i<unoStateTypes.length; i++) { 141 if (unoStateTypes[i] > 0 && 142 unoStateTypes[i] < stateTypeMap.length) { 143 as.add(stateTypeMap[unoStateTypes[i]]); 144 } 145 } 146 147 // Note: COLLAPSED does not exists in the UAA. 148 if (as.contains(AccessibleState.EXPANDABLE) && 149 ! as.contains(AccessibleState.EXPANDED)) { 150 as.add(AccessibleState.COLLAPSED); 151 } 152 153 // Sync office and Java FOCUSED state 154 boolean isFocusInSync; 155 if (c.isFocusOwner()) { 156 isFocusInSync = !as.add(AccessibleState.FOCUSED); 157 } else { 158 isFocusInSync = !as.remove(AccessibleState.FOCUSED); 159 } 160 161 // Sync office and Java ACTIVE state 162 boolean isActiveInSync; 163 if (c instanceof java.awt.Window && ((java.awt.Window) c).isActive()) { 164 isActiveInSync = !as.add(AccessibleState.ACTIVE); 165 } else { 166 isActiveInSync = !as.remove(AccessibleState.ACTIVE); 167 } 168 169 // Report out-of-sync messages 170 if (!Build.PRODUCT) { 171 if (!isFocusInSync) { 172 printOutOfSyncMessage(AccessibleState.FOCUSED, c, c.isFocusOwner()); 173 } 174 if (!isActiveInSync) { 175 printOutOfSyncMessage(AccessibleState.ACTIVE, c, ((java.awt.Window) c).isActive()); 176 } 177 if (as.contains(AccessibleState.ENABLED) != c.isEnabled()) { 178 printOutOfSyncMessage(AccessibleState.ENABLED, c, c.isEnabled()); 179 } 180 if (as.contains(AccessibleState.FOCUSABLE) != c.isFocusable()) { 181 printOutOfSyncMessage(AccessibleState.FOCUSABLE, c, c.isFocusable()); 182 } 183 if (as.contains(AccessibleState.SHOWING) != c.isShowing()) { 184 printOutOfSyncMessage(AccessibleState.SHOWING, c, c.isShowing()); 185 } 186 if (as.contains(AccessibleState.VISIBLE) != c.isVisible()) { 187 printOutOfSyncMessage(AccessibleState.VISIBLE, c, c.isVisible()); 188 } 189 190 // The following states are for toplevel windows only 191 if (! (c instanceof java.awt.Window)) { 192 if (as.contains(AccessibleState.ACTIVE)) { 193 printToplevelStateMessage(AccessibleState.ACTIVE, c); 194 } 195 if (as.contains(AccessibleState.ICONIFIED)) { 196 printToplevelStateMessage(AccessibleState.ICONIFIED, c); 197 } 198 if (as.contains(AccessibleState.MODAL)) { 199 printToplevelStateMessage(AccessibleState.MODAL, c); 200 } 201 } 202 } 203 return as; 204 } 205 return null; 206 } catch (com.sun.star.uno.RuntimeException e) { 207 return getDefunctStateSet(); 208 } 209 } 210 } 211