Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibleText.java
41640 views
1
/*
2
* Copyright (c) 2011, 2016, 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
package sun.lwawt.macosx;
27
28
import java.awt.Component;
29
import java.awt.Point;
30
import java.awt.Rectangle;
31
import java.awt.geom.Rectangle2D;
32
import java.util.concurrent.Callable;
33
34
import javax.accessibility.Accessible;
35
import javax.accessibility.AccessibleContext;
36
import javax.accessibility.AccessibleEditableText;
37
import javax.accessibility.AccessibleText;
38
import javax.swing.text.Element;
39
import javax.swing.text.JTextComponent;
40
41
class CAccessibleText {
42
static AccessibleEditableText getAccessibleEditableText(final Accessible a, final Component c) {
43
if (a == null) return null;
44
45
return CAccessibility.invokeAndWait(new Callable<AccessibleEditableText>() {
46
public AccessibleEditableText call() throws Exception {
47
final AccessibleContext ac = a.getAccessibleContext();
48
if (ac == null) return null;
49
return ac.getAccessibleEditableText();
50
}
51
}, c);
52
}
53
54
static String getSelectedText(final Accessible a, final Component c) {
55
if (a == null) return null;
56
57
return CAccessibility.invokeAndWait(new Callable<String>() {
58
public String call() throws Exception {
59
final AccessibleContext ac = a.getAccessibleContext();
60
if (ac == null) return null;
61
62
final AccessibleText at = ac.getAccessibleText();
63
if (at == null) return null;
64
65
return at.getSelectedText();
66
}
67
}, c);
68
}
69
70
// replace the currently selected text with newText
71
static void setSelectedText(final Accessible a, final Component c, final String newText) {
72
if (a == null) return;
73
74
CAccessibility.invokeLater(new Runnable() {
75
public void run() {
76
final AccessibleContext ac = a.getAccessibleContext();
77
if (ac == null) return;
78
79
final AccessibleEditableText aet = ac.getAccessibleEditableText();
80
if (aet == null) return;
81
82
final int selectionStart = aet.getSelectionStart();
83
final int selectionEnd = aet.getSelectionEnd();
84
aet.replaceText(selectionStart, selectionEnd, newText);
85
}
86
}, c);
87
}
88
89
static void setSelectedTextRange(final Accessible a, final Component c, final int startIndex, final int endIndex) {
90
if (a == null) return;
91
92
CAccessibility.invokeLater(new Runnable() {
93
public void run() {
94
final AccessibleContext ac = a.getAccessibleContext();
95
if (ac == null) return;
96
97
final AccessibleEditableText aet = ac.getAccessibleEditableText();
98
if (aet == null) return;
99
100
final boolean validRange = (startIndex >= 0) && (endIndex >= startIndex) && (endIndex <= aet.getCharCount());
101
if (!validRange) return;
102
103
aet.selectText(startIndex, endIndex);
104
}
105
}, c);
106
}
107
108
static String getTextRange(final AccessibleEditableText aet, final int start, final int stop, final Component c) {
109
if (aet == null) return null;
110
111
return CAccessibility.invokeAndWait(new Callable<String>() {
112
public String call() throws Exception {
113
return aet.getTextRange(start, stop);
114
}
115
}, c);
116
}
117
118
static int getCharacterIndexAtPosition(final Accessible a, final Component c, final int x, final int y) {
119
if (a == null) return 0;
120
121
return CAccessibility.invokeAndWait(new Callable<Integer>() {
122
public Integer call() throws Exception {
123
final AccessibleContext ac = a.getAccessibleContext();
124
if (ac == null) return null;
125
final AccessibleText at = ac.getAccessibleText();
126
if (at == null) return null;
127
// (x, y) passed in as java screen coords - (0, 0) at upper-left corner of screen.
128
// Convert to java component-local coords
129
final Point componentLocation = ac.getAccessibleComponent().getLocationOnScreen();
130
final int localX = x - (int)componentLocation.getX();
131
final int localY = y - (int)componentLocation.getY();
132
133
return at.getIndexAtPoint(new Point(localX, localY));
134
}
135
}, c);
136
}
137
138
static int[] getSelectedTextRange(final Accessible a, final Component c) {
139
if (a == null) return new int[2];
140
141
return CAccessibility.invokeAndWait(new Callable<int[]>() {
142
public int[] call() {
143
final AccessibleContext ac = a.getAccessibleContext();
144
if (ac == null) return new int[2];
145
146
final AccessibleText at = ac.getAccessibleText();
147
if (at == null) return new int[2];
148
149
final int[] ret = new int[2];
150
ret[0] = at.getSelectionStart();
151
ret[1] = at.getSelectionEnd();
152
return ret;
153
}
154
}, c);
155
}
156
157
158
static int[] getVisibleCharacterRange(final Accessible a, final Component c) {
159
if (a == null) return null;
160
return CAccessibility.invokeAndWait(new Callable<int[]>() {
161
public int[] call() {
162
return getVisibleCharacterRange(a);
163
}
164
}, c);
165
}
166
167
static int getLineNumberForIndex(final Accessible a, final Component c, final int index) {
168
if (a == null) return 0;
169
return CAccessibility.invokeAndWait(new Callable<Integer>() {
170
public Integer call() {
171
return Integer.valueOf(getLineNumberForIndex(a, index));
172
}
173
}, c);
174
}
175
176
static int getLineNumberForInsertionPoint(final Accessible a, final Component c) {
177
if (a == null) return 0;
178
return CAccessibility.invokeAndWait(new Callable<Integer>() {
179
public Integer call() {
180
return Integer.valueOf(getLineNumberForInsertionPoint(a));
181
}
182
}, c);
183
}
184
185
static int[] getRangeForLine(final Accessible a, final Component c, final int line) {
186
if (a == null) return null;
187
return CAccessibility.invokeAndWait(new Callable<int[]>() {
188
public int[] call() {
189
return getRangeForLine(a, line);
190
}
191
}, c);
192
}
193
194
static int[] getRangeForIndex(final Accessible a, final Component c, final int index) {
195
if (a == null) return new int[2];
196
197
return CAccessibility.invokeAndWait(new Callable<int[]>() {
198
public int[] call() {
199
final AccessibleContext ac = a.getAccessibleContext();
200
if (ac == null) return new int[2];
201
202
final AccessibleEditableText aet = ac.getAccessibleEditableText();
203
if (aet == null) return new int[2];
204
205
final int charCount = aet.getCharCount();
206
if (index >= charCount) return new int[2];
207
208
final String foundWord = aet.getAtIndex(AccessibleText.WORD, index);
209
final int foundWordLength = foundWord.length();
210
final String wholeString = aet.getTextRange(0, charCount - 1);
211
212
// now we need to find the index of the foundWord in wholeString. It's somewhere pretty close to the passed-in index,
213
// but we don't know if it's before or after the passed-in index. So, look behind and ahead of the passed-in index
214
int foundWordIndex = -1;
215
int offset = 0;
216
while ((foundWordIndex == -1) && (offset < foundWordLength)) {
217
if (wholeString.regionMatches(true, index - offset, foundWord, 0, foundWordLength)) {
218
// is the index of foundWord to the left of the passed-in index?
219
foundWordIndex = index - offset;
220
}
221
if (wholeString.regionMatches(true, index + offset, foundWord, 0, foundWordLength)) {
222
// is the index of the foundWord to the right of the passed-in index?
223
foundWordIndex = index + offset;
224
}
225
offset++;
226
}
227
228
final int[] ret = new int[2];
229
ret[0] = foundWordIndex;
230
ret[1] = foundWordIndex + foundWordLength;
231
return ret;
232
}
233
}, c);
234
}
235
236
// cmcnote: this method does not currently work for JLabels. JLabels, for some reason unbeknownst to me, do not
237
// return a value from getAccessibleText. According to the javadocs, AccessibleJLabels implement AccessibleText,
238
// so this doesn't really make sense. Perhaps a sun bug? Investigate. We currently get the text value out of labels
239
// via "getAccessibleName". This just returns a String - so we don't know it's position, etc, as we do for
240
// AccessibleText.
241
static double[] getBoundsForRange(final Accessible a, final Component c, final int location, final int length) {
242
final double[] ret = new double[4];
243
if (a == null) return ret;
244
245
return CAccessibility.invokeAndWait(new Callable<double[]>() {
246
public double[] call() throws Exception {
247
final AccessibleContext ac = a.getAccessibleContext();
248
if (ac == null) return ret;
249
250
final AccessibleText at = ac.getAccessibleText();
251
if (at == null) {
252
ac.getAccessibleName();
253
ac.getAccessibleEditableText();
254
return ret;
255
}
256
257
final Rectangle2D boundsStart = at.getCharacterBounds(location);
258
final Rectangle2D boundsEnd = at.getCharacterBounds(location + length - 1);
259
if (boundsEnd == null || boundsStart == null) return ret;
260
final Rectangle2D boundsUnion = boundsStart.createUnion(boundsEnd);
261
if (boundsUnion.isEmpty()) return ret;
262
263
final double localX = boundsUnion.getX();
264
final double localY = boundsUnion.getY();
265
266
final Point componentLocation = ac.getAccessibleComponent().getLocationOnScreen();
267
if (componentLocation == null) return ret;
268
269
final double screenX = componentLocation.getX() + localX;
270
final double screenY = componentLocation.getY() + localY;
271
272
ret[0] = screenX;
273
ret[1] = screenY; // in java screen coords (from top-left corner of screen)
274
ret[2] = boundsUnion.getWidth();
275
ret[3] = boundsUnion.getHeight();
276
return ret;
277
}
278
}, c);
279
}
280
281
static String getStringForRange(final Accessible a, final Component c, final int location, final int length) {
282
if (a == null) return null;
283
return CAccessibility.invokeAndWait(new Callable<String>() {
284
public String call() throws Exception {
285
final AccessibleContext ac = a.getAccessibleContext();
286
if (ac == null) return null;
287
288
final AccessibleEditableText aet = ac.getAccessibleEditableText();
289
if (aet == null) return null;
290
291
return aet.getTextRange(location, location + length);
292
}
293
}, c);
294
}
295
296
@SuppressWarnings("deprecation")
297
static int[] getVisibleCharacterRange(final Accessible a) {
298
final Accessible sa = CAccessible.getSwingAccessible(a);
299
if (!(sa instanceof JTextComponent)) return null;
300
301
final JTextComponent jc = (JTextComponent) sa;
302
final Rectangle rect = jc.getVisibleRect();
303
final Point topLeft = new Point(rect.x, rect.y);
304
final Point topRight = new Point(rect.x + rect.width, rect.y);
305
final Point bottomLeft = new Point(rect.x, rect.y + rect.height);
306
final Point bottomRight = new Point(rect.x + rect.width, rect.y + rect.height);
307
308
int start = Math.min(jc.viewToModel(topLeft), jc.viewToModel(topRight));
309
int end = Math.max(jc.viewToModel(bottomLeft), jc.viewToModel(bottomRight));
310
if (start < 0) start = 0;
311
if (end < 0) end = 0;
312
return new int[] { start, end };
313
}
314
315
static int getLineNumberForIndex(final Accessible a, int index) {
316
final Accessible sa = CAccessible.getSwingAccessible(a);
317
if (!(sa instanceof JTextComponent)) return -1;
318
319
final JTextComponent jc = (JTextComponent) sa;
320
final Element root = jc.getDocument().getDefaultRootElement();
321
322
// treat -1 special, returns the current caret position
323
if (index == -1) index = jc.getCaretPosition();
324
325
// Determine line number (can be -1)
326
return root.getElementIndex(index);
327
}
328
329
static int getLineNumberForInsertionPoint(final Accessible a) {
330
return getLineNumberForIndex(a, -1); // uses special -1 for above
331
}
332
333
static int[] getRangeForLine(final Accessible a, final int lineIndex) {
334
Accessible sa = CAccessible.getSwingAccessible(a);
335
if (!(sa instanceof JTextComponent)) return null;
336
337
final JTextComponent jc = (JTextComponent) sa;
338
final Element root = jc.getDocument().getDefaultRootElement();
339
final Element line = root.getElement(lineIndex);
340
if (line == null) return null;
341
342
return new int[] { line.getStartOffset(), line.getEndOffset() };
343
}
344
}
345
346