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