|
1 /* |
|
2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 * or visit www.oracle.com if you need additional information or have any |
|
23 * questions. |
|
24 */ |
|
25 |
|
26 #import "JavaTextAccessibility.h" |
|
27 #import "JavaAccessibilityAction.h" |
|
28 #import "JavaAccessibilityUtilities.h" |
|
29 #import "ThreadUtilities.h" |
|
30 |
|
31 |
|
32 static JNF_CLASS_CACHE(sjc_CAccessibleText, "sun/lwawt/macosx/CAccessibleText"); |
|
33 static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleText, sjc_CAccessibility, "getAccessibleText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleText;"); |
|
34 static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleEditableText, sjc_CAccessibleText, "getAccessibleEditableText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleEditableText;"); |
|
35 static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;"); |
|
36 |
|
37 /* |
|
38 * Converts an int array to an NSRange wrapped inside an NSValue |
|
39 * takes [start, end] values and returns [start, end - start] |
|
40 */ |
|
41 NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) { |
|
42 jint *values = (*env)->GetIntArrayElements(env, array, 0); |
|
43 NSValue *value = [NSValue valueWithRange:NSMakeRange(values[0], values[1] - values[0])]; |
|
44 (*env)->ReleaseIntArrayElements(env, array, values, 0); |
|
45 return value; |
|
46 } |
|
47 |
|
48 @implementation JavaTextAccessibility |
|
49 |
|
50 // based strongly upon NSTextViewAccessibility:accessibilityAttributeNames |
|
51 - (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env |
|
52 { |
|
53 static NSArray *attributes = nil; |
|
54 |
|
55 if (attributes == nil) { |
|
56 //APPKIT_LOCK; |
|
57 if (attributes == nil) { |
|
58 NSMutableArray *temp = [[super initializeAttributeNamesWithEnv:env] mutableCopy]; |
|
59 //[temp removeObject:NSAccessibilityTitleAttribute]; // title may have been set in the superclass implementation - some static text reports from java that it has a name |
|
60 [temp addObjectsFromArray:[NSArray arrayWithObjects: |
|
61 NSAccessibilityValueAttribute, |
|
62 NSAccessibilitySelectedTextAttribute, |
|
63 NSAccessibilitySelectedTextRangeAttribute, |
|
64 NSAccessibilityNumberOfCharactersAttribute, |
|
65 NSAccessibilityVisibleCharacterRangeAttribute, |
|
66 NSAccessibilityInsertionPointLineNumberAttribute, |
|
67 // NSAccessibilitySharedTextUIElementsAttribute, // cmcnote: investigate what these two are for. currently unimplemented |
|
68 // NSAccessibilitySharedCharacterRangeAttribute, |
|
69 nil]]; |
|
70 attributes = [[NSArray alloc] initWithArray:temp]; |
|
71 [temp release]; |
|
72 } |
|
73 //APPKIT_UNLOCK; |
|
74 } |
|
75 return attributes; |
|
76 } |
|
77 |
|
78 // copied from NSTextViewAccessibility. |
|
79 - (NSArray *)accessibilityParameterizedAttributeNames |
|
80 { |
|
81 static NSArray *attributes = nil; |
|
82 |
|
83 if (attributes == nil) { |
|
84 //APPKIT_LOCK; |
|
85 if (attributes == nil) { |
|
86 attributes = [[NSArray alloc] initWithObjects: |
|
87 NSAccessibilityLineForIndexParameterizedAttribute, |
|
88 NSAccessibilityRangeForLineParameterizedAttribute, |
|
89 NSAccessibilityStringForRangeParameterizedAttribute, |
|
90 NSAccessibilityRangeForPositionParameterizedAttribute, |
|
91 NSAccessibilityRangeForIndexParameterizedAttribute, |
|
92 NSAccessibilityBoundsForRangeParameterizedAttribute, |
|
93 //NSAccessibilityRTFForRangeParameterizedAttribute, // cmcnote: not sure when/how these three are used. Investigate. radr://3960026 |
|
94 //NSAccessibilityStyleRangeForIndexParameterizedAttribute, |
|
95 //NSAccessibilityAttributedStringForRangeParameterizedAttribute, |
|
96 nil]; |
|
97 } |
|
98 //APPKIT_UNLOCK; |
|
99 } |
|
100 return attributes; |
|
101 } |
|
102 |
|
103 - (NSString *)accessibilityValueAttribute |
|
104 { |
|
105 JNIEnv *env = [ThreadUtilities getJNIEnv]; |
|
106 if ([[self accessibilityRoleAttribute] isEqualToString:NSAccessibilityStaticTextRole]) { |
|
107 // if it's static text, the AppKit AXValue is the java accessibleName |
|
108 jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) |
|
109 if (axName != NULL) { |
|
110 return JNFJavaToNSString(env, axName); |
|
111 } |
|
112 // value is still nil if no accessibleName for static text. Below, try to get the accessibleText. |
|
113 } |
|
114 |
|
115 // cmcnote: inefficient to make three distinct JNI calls. Coalesce. radr://3951923 |
|
116 jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) |
|
117 if (axText == NULL) return nil; |
|
118 |
|
119 jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) |
|
120 if (axEditableText == NULL) return nil; |
|
121 |
|
122 static JNF_STATIC_MEMBER_CACHE(jm_getTextRange, sjc_CAccessibleText, "getTextRange", "(Ljavax/accessibility/AccessibleEditableText;IILjava/awt/Component;)Ljava/lang/String;"); |
|
123 NSString *string = JNFJavaToNSString(env, JNFCallStaticObjectMethod(env, jm_getTextRange, axEditableText, 0, getAxTextCharCount(env, axEditableText, fComponent), fComponent)); // AWT_THREADING Safe (AWTRunLoop) |
|
124 if (string == nil) string = @""; |
|
125 return string; |
|
126 } |
|
127 |
|
128 - (BOOL)accessibilityIsValueAttributeSettable |
|
129 { |
|
130 // if text is enabled and editable, it's settable (according to NSCellTextAttributesAccessibility) |
|
131 BOOL isEnabled = [(NSNumber *)[self accessibilityEnabledAttribute] boolValue]; |
|
132 if (!isEnabled) return NO; |
|
133 |
|
134 JNIEnv* env = [ThreadUtilities getJNIEnv]; |
|
135 jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) |
|
136 if (axEditableText == NULL) return NO; |
|
137 return YES; |
|
138 } |
|
139 |
|
140 - (void)accessibilitySetValueAttribute:(id)value |
|
141 { |
|
142 // cmcnote: should set the accessibleEditableText to the stringValue of value - AccessibleEditableText.setTextContents(String s) |
|
143 #ifdef JAVA_AX_DEBUG |
|
144 NSLog(@"Not yet implemented: %s\n", __FUNCTION__); // radr://3954018 |
|
145 #endif |
|
146 } |
|
147 |
|
148 // Currently selected text (NSString) |
|
149 - (NSString *)accessibilitySelectedTextAttribute |
|
150 { |
|
151 JNIEnv* env = [ThreadUtilities getJNIEnv]; |
|
152 static JNF_STATIC_MEMBER_CACHE(jm_getSelectedText, sjc_CAccessibleText, "getSelectedText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;"); |
|
153 jobject axText = JNFCallStaticObjectMethod(env, jm_getSelectedText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) |
|
154 if (axText == NULL) return @""; |
|
155 return JNFJavaToNSString(env, axText); |
|
156 } |
|
157 |
|
158 - (BOOL)accessibilityIsSelectedTextAttributeSettable |
|
159 { |
|
160 return YES; //cmcnote: for AXTextField that's selectable, it's settable. Investigate further. |
|
161 } |
|
162 |
|
163 - (void)accessibilitySetSelectedTextAttribute:(id)value |
|
164 { |
|
165 #ifdef JAVA_AX_DEBUG_PARMS |
|
166 if (![value isKindOfClass:[NSString class]]) { |
|
167 JavaAccessibilityRaiseSetAttributeToIllegalTypeException(__FUNCTION__, self, NSAccessibilitySelectedTextAttribute, value); |
|
168 return; |
|
169 } |
|
170 #endif |
|
171 |
|
172 JNIEnv *env = [ThreadUtilities getJNIEnv]; |
|
173 jstring jstringValue = JNFNSToJavaString(env, (NSString *)value); |
|
174 static JNF_STATIC_MEMBER_CACHE(jm_setSelectedText, sjc_CAccessibleText, "setSelectedText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;Ljava/lang/String;)V"); |
|
175 JNFCallStaticVoidMethod(env, jm_setSelectedText, fAccessible, fComponent, jstringValue); // AWT_THREADING Safe (AWTRunLoop) |
|
176 } |
|
177 |
|
178 // Range of selected text (NSValue) |
|
179 - (NSValue *)accessibilitySelectedTextRangeAttribute |
|
180 { |
|
181 JNIEnv *env = [ThreadUtilities getJNIEnv]; |
|
182 static JNF_STATIC_MEMBER_CACHE(jm_getSelectedTextRange, sjc_CAccessibleText, "getSelectedTextRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)[I"); |
|
183 jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getSelectedTextRange, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) |
|
184 if (axTextRange == NULL) return nil; |
|
185 |
|
186 return javaIntArrayToNSRangeValue(env, axTextRange); |
|
187 } |
|
188 |
|
189 - (BOOL)accessibilityIsSelectedTextRangeAttributeSettable |
|
190 { |
|
191 return [(NSNumber *)[self accessibilityEnabledAttribute] boolValue]; // cmcnote: also may want to find out if isSelectable. Investigate. |
|
192 } |
|
193 |
|
194 - (void)accessibilitySetSelectedTextRangeAttribute:(id)value |
|
195 { |
|
196 #ifdef JAVA_AX_DEBUG_PARMS |
|
197 if (!([value isKindOfClass:[NSValue class]] && strcmp([(NSValue *)value objCType], @encode(NSRange)) == 0)) { |
|
198 JavaAccessibilityRaiseSetAttributeToIllegalTypeException(__FUNCTION__, self, NSAccessibilitySelectedTextRangeAttribute, value); |
|
199 return; |
|
200 } |
|
201 #endif |
|
202 |
|
203 NSRange range = [(NSValue *)value rangeValue]; |
|
204 jint startIndex = range.location; |
|
205 jint endIndex = startIndex + range.length; |
|
206 |
|
207 JNIEnv *env = [ThreadUtilities getJNIEnv]; |
|
208 static JNF_STATIC_MEMBER_CACHE(jm_setSelectedTextRange, sjc_CAccessibleText, "setSelectedTextRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)V"); |
|
209 JNFCallStaticVoidMethod(env, jm_setSelectedTextRange, fAccessible, fComponent, startIndex, endIndex); // AWT_THREADING Safe (AWTRunLoop) |
|
210 } |
|
211 |
|
212 - (NSNumber *)accessibilityNumberOfCharactersAttribute |
|
213 { |
|
214 // cmcnote: should coalesce these two calls - radr://3951923 |
|
215 // also, static text doesn't always have accessibleText. if axText is null, should get the charcount of the accessibleName instead |
|
216 JNIEnv *env = [ThreadUtilities getJNIEnv]; |
|
217 jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) |
|
218 return [NSNumber numberWithInt:getAxTextCharCount(env, axText, fComponent)]; |
|
219 } |
|
220 |
|
221 - (BOOL)accessibilityIsNumberOfCharactersAttributeSettable |
|
222 { |
|
223 return NO; // according to NSTextViewAccessibility.m and NSCellTextAttributesAccessibility.m |
|
224 } |
|
225 |
|
226 - (NSValue *)accessibilityVisibleCharacterRangeAttribute |
|
227 { |
|
228 JNIEnv *env = [ThreadUtilities getJNIEnv]; |
|
229 static JNF_STATIC_MEMBER_CACHE(jm_getVisibleCharacterRange, sjc_CAccessibleText, "getVisibleCharacterRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)[I"); |
|
230 jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getVisibleCharacterRange, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) |
|
231 if (axTextRange == NULL) return nil; |
|
232 |
|
233 return javaIntArrayToNSRangeValue(env, axTextRange); |
|
234 } |
|
235 |
|
236 - (BOOL)accessibilityIsVisibleCharacterRangeAttributeSettable |
|
237 { |
|
238 #ifdef JAVA_AX_DEBUG |
|
239 NSLog(@"Not yet implemented: %s\n", __FUNCTION__); |
|
240 #endif |
|
241 return NO; |
|
242 } |
|
243 |
|
244 - (NSValue *)accessibilityInsertionPointLineNumberAttribute |
|
245 { |
|
246 JNIEnv *env = [ThreadUtilities getJNIEnv]; |
|
247 static JNF_STATIC_MEMBER_CACHE(jm_getLineNumberForInsertionPoint, sjc_CAccessibleText, "getLineNumberForInsertionPoint", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)I"); |
|
248 jint row = JNFCallStaticIntMethod(env, jm_getLineNumberForInsertionPoint, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop) |
|
249 if (row < 0) return nil; |
|
250 return [NSNumber numberWithInt:row]; |
|
251 } |
|
252 |
|
253 - (BOOL)accessibilityIsInsertionPointLineNumberAttributeSettable |
|
254 { |
|
255 #ifdef JAVA_AX_DEBUG |
|
256 NSLog(@"Not yet implemented: %s\n", __FUNCTION__); |
|
257 #endif |
|
258 return NO; |
|
259 } |
|
260 |
|
261 // parameterized attributes |
|
262 |
|
263 // |
|
264 // Usage of accessibilityBoundsForRangeAttributeForParameter: |
|
265 // --- |
|
266 // called by VoiceOver when interacting with text via ctrl-option-shift-downArrow. |
|
267 // Need to know bounding box for the character / word / line of interest in |
|
268 // order to draw VoiceOver cursor |
|
269 // |
|
270 - (NSValue *)accessibilityBoundsForRangeAttributeForParameter:(id)parameter |
|
271 { |
|
272 #ifdef JAVA_AX_DEBUG_PARMS |
|
273 if (!([parameter isKindOfClass:[NSValue class]] && strcmp([(NSValue *)parameter objCType], @encode(NSRange)) == 0)) { |
|
274 JavaAccessibilityRaiseIllegalParameterTypeException(__FUNCTION__, self, NSAccessibilityBoundsForRangeParameterizedAttribute, parameter); |
|
275 return nil; |
|
276 } |
|
277 #endif |
|
278 |
|
279 NSRange range = [(NSValue *)parameter rangeValue]; |
|
280 |
|
281 JNIEnv *env = [ThreadUtilities getJNIEnv]; |
|
282 static JNF_STATIC_MEMBER_CACHE(jm_getBoundsForRange, sjc_CAccessibleText, "getBoundsForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)[D"); |
|
283 jdoubleArray axBounds = JNFCallStaticObjectMethod(env, jm_getBoundsForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop) |
|
284 if (axBounds == NULL) return nil; |
|
285 |
|
286 // We cheat because we know that the array is 4 elements long (x, y, width, height) |
|
287 jdouble *values = (*env)->GetDoubleArrayElements(env, axBounds, 0); |
|
288 NSRect bounds; |
|
289 bounds.origin.x = values[0]; |
|
290 bounds.origin.y = [[[[self view] window] screen] frame].size.height - values[1] - values[3]; //values[1] is y-coord from top-left of screen. Flip. Account for the height (values[3]) when flipping |
|
291 bounds.size.width = values[2]; |
|
292 bounds.size.height = values[3]; |
|
293 NSValue *result = [NSValue valueWithRect:bounds]; |
|
294 (*env)->ReleaseDoubleArrayElements(env, axBounds, values, 0); |
|
295 return result; |
|
296 } |
|
297 |
|
298 - (NSNumber *)accessibilityLineForIndexAttributeForParameter:(id)parameter |
|
299 { |
|
300 NSNumber *line = (NSNumber *) parameter; |
|
301 if (line == nil) return nil; |
|
302 |
|
303 JNIEnv *env = [ThreadUtilities getJNIEnv]; |
|
304 static JNF_STATIC_MEMBER_CACHE(jm_getLineNumberForIndex, sjc_CAccessibleText, "getLineNumberForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)I"); |
|
305 jint row = JNFCallStaticIntMethod(env, jm_getLineNumberForIndex, fAccessible, fComponent, [line intValue]); // AWT_THREADING Safe (AWTRunLoop) |
|
306 if (row < 0) return nil; |
|
307 return [NSNumber numberWithInt:row]; |
|
308 } |
|
309 |
|
310 - (NSValue *)accessibilityRangeForLineAttributeForParameter:(id)parameter |
|
311 { |
|
312 NSNumber *line = (NSNumber *) parameter; |
|
313 if (line == nil) return nil; |
|
314 |
|
315 JNIEnv *env = [ThreadUtilities getJNIEnv]; |
|
316 static JNF_STATIC_MEMBER_CACHE(jm_getRangeForLine, sjc_CAccessibleText, "getRangeForLine", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I"); |
|
317 jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getRangeForLine, fAccessible, fComponent, [line intValue]); // AWT_THREADING Safe (AWTRunLoop) |
|
318 if (axTextRange == NULL) return nil; |
|
319 |
|
320 return javaIntArrayToNSRangeValue(env,axTextRange); |
|
321 } |
|
322 |
|
323 // |
|
324 // Usage of accessibilityStringForRangeAttributeForParameter: |
|
325 // --- |
|
326 // called by VoiceOver when interacting with text via ctrl-option-shift-downArrow. |
|
327 // VO needs to know the particular string its currently dealing with so it can |
|
328 // speak the string |
|
329 // |
|
330 - (NSString *)accessibilityStringForRangeAttributeForParameter:(id)parameter |
|
331 { |
|
332 #ifdef JAVA_AX_DEBUG_PARMS |
|
333 if (!([parameter isKindOfClass:[NSValue class]] && strcmp([(NSValue *)parameter objCType], @encode(NSRange)) == 0)) { |
|
334 JavaAccessibilityRaiseIllegalParameterTypeException(__FUNCTION__, self, NSAccessibilityBoundsForRangeParameterizedAttribute, parameter); |
|
335 return nil; |
|
336 } |
|
337 #endif |
|
338 |
|
339 NSRange range = [(NSValue *)parameter rangeValue]; |
|
340 |
|
341 JNIEnv *env = [ThreadUtilities getJNIEnv]; |
|
342 static JNF_STATIC_MEMBER_CACHE(jm_getStringForRange, sjc_CAccessibleText, "getStringForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)Ljava/lang/String;"); |
|
343 jstring jstringForRange = JNFCallStaticObjectMethod(env, jm_getStringForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop) |
|
344 |
|
345 if (jstringForRange == NULL) return @""; |
|
346 return JNFJavaToNSString(env, jstringForRange); |
|
347 } |
|
348 |
|
349 // |
|
350 // Usage of accessibilityRangeForPositionAttributeForParameter: |
|
351 // --- |
|
352 // cmcnote: I'm not sure when this is called / how it's used. Investigate. |
|
353 // probably could be used in a special text-only accessibilityHitTest to |
|
354 // find the index of the string under the mouse? |
|
355 // |
|
356 - (NSValue *)accessibilityRangeForPositionAttributeForParameter:(id)parameter |
|
357 { |
|
358 #ifdef JAVA_AX_DEBUG_PARMS |
|
359 if (!([parameter isKindOfClass:[NSValue class]] && strcmp([(NSValue *)parameter objCType], @encode(NSPoint)) == 0)) { |
|
360 JavaAccessibilityRaiseIllegalParameterTypeException(__FUNCTION__, self, NSAccessibilityRangeForPositionParameterizedAttribute, parameter); |
|
361 return nil; |
|
362 } |
|
363 #endif |
|
364 |
|
365 NSPoint point = [(NSValue *)parameter pointValue]; // point is in screen coords |
|
366 point.y = [[[[self view] window] screen] frame].size.height - point.y; // flip into java screen coords (0 is at upper-left corner of screen) |
|
367 |
|
368 JNIEnv *env = [ThreadUtilities getJNIEnv]; |
|
369 static JNF_STATIC_MEMBER_CACHE(jm_getCharacterIndexAtPosition, sjc_CAccessibleText, "getCharacterIndexAtPosition", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)I"); |
|
370 jint charIndex = JNFCallStaticIntMethod(env, jm_getCharacterIndexAtPosition, fAccessible, fComponent, point.x, point.y); // AWT_THREADING Safe (AWTRunLoop) |
|
371 if (charIndex == -1) return nil; |
|
372 |
|
373 // AccessibleText.getIndexAtPoint returns -1 for an invalid point |
|
374 NSRange range = NSMakeRange(charIndex, 1); //range's length is 1 - one-character range |
|
375 return [NSValue valueWithRange:range]; |
|
376 } |
|
377 |
|
378 // |
|
379 // Usage of accessibilityRangeForIndexAttributeForParameter: |
|
380 // --- |
|
381 // cmcnote: I'm not sure when this is called / how it's used. Investigate. |
|
382 // AppKit version calls: [string rangeOfComposedCharacterSequenceAtIndex:index] |
|
383 // We call: CAccessibility.getRangeForIndex, which calls AccessibleText.getAtIndex(AccessibleText.WORD, index) |
|
384 // to determine the word closest to the given index. Then we find the length/location of this string. |
|
385 // |
|
386 - (NSValue *)accessibilityRangeForIndexAttributeForParameter:(id)parameter |
|
387 { |
|
388 #ifdef JAVA_AX_DEBUG_PARMS |
|
389 if (![parameter isKindOfClass:[NSNumber class]]) { |
|
390 JavaAccessibilityRaiseIllegalParameterTypeException(__FUNCTION__, self, NSAccessibilityRangeForIndexParameterizedAttribute, parameter); |
|
391 return nil; |
|
392 } |
|
393 #endif |
|
394 |
|
395 NSUInteger index = [(NSNumber *)parameter unsignedIntegerValue]; |
|
396 |
|
397 JNIEnv *env = [ThreadUtilities getJNIEnv]; |
|
398 static JNF_STATIC_MEMBER_CACHE(jm_getRangeForIndex, sjc_CAccessibleText, "getRangeForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I"); |
|
399 jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getRangeForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop) |
|
400 if (axTextRange == NULL) return nil; |
|
401 |
|
402 return javaIntArrayToNSRangeValue(env, axTextRange); |
|
403 } |
|
404 |
|
405 - (NSDictionary *)getActions:(JNIEnv *)env { |
|
406 // cmcnote: this isn't correct; text can have actions. Not yet implemented. radr://3941691 |
|
407 // Editable text has AXShowMenu. Textfields have AXConfirm. Static text has no actions. |
|
408 #ifdef JAVA_AX_DEBUG |
|
409 NSLog(@"Not yet implemented: %s\n", __FUNCTION__); |
|
410 #endif |
|
411 return nil; |
|
412 } |
|
413 |
|
414 @end |