accessible/src/windows/ia2/ia2AccessibleText.cpp

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:c6e3f6c10552
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:expandtab:shiftwidth=2:tabstop=2:
3 */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7
8 #include "ia2AccessibleText.h"
9
10 #include "Accessible2.h"
11 #include "AccessibleText_i.c"
12
13 #include "HyperTextAccessibleWrap.h"
14 #include "HyperTextAccessible-inl.h"
15
16 using namespace mozilla::a11y;
17
18 // IAccessibleText
19
20 STDMETHODIMP
21 ia2AccessibleText::addSelection(long aStartOffset, long aEndOffset)
22 {
23 A11Y_TRYBLOCK_BEGIN
24
25 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
26 if (textAcc->IsDefunct())
27 return CO_E_OBJNOTCONNECTED;
28
29 return textAcc->AddToSelection(aStartOffset, aEndOffset) ?
30 S_OK : E_INVALIDARG;
31
32 A11Y_TRYBLOCK_END
33 }
34
35 STDMETHODIMP
36 ia2AccessibleText::get_attributes(long aOffset, long *aStartOffset,
37 long *aEndOffset, BSTR *aTextAttributes)
38 {
39 A11Y_TRYBLOCK_BEGIN
40
41 if (!aStartOffset || !aEndOffset || !aTextAttributes)
42 return E_INVALIDARG;
43
44 *aStartOffset = 0;
45 *aEndOffset = 0;
46 *aTextAttributes = nullptr;
47
48 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
49 if (textAcc->IsDefunct())
50 return CO_E_OBJNOTCONNECTED;
51
52 int32_t startOffset = 0, endOffset = 0;
53 nsCOMPtr<nsIPersistentProperties> attributes =
54 textAcc->TextAttributes(true, aOffset, &startOffset, &endOffset);
55
56 HRESULT hr = AccessibleWrap::ConvertToIA2Attributes(attributes,
57 aTextAttributes);
58 if (FAILED(hr))
59 return hr;
60
61 *aStartOffset = startOffset;
62 *aEndOffset = endOffset;
63
64 return S_OK;
65
66 A11Y_TRYBLOCK_END
67 }
68
69 STDMETHODIMP
70 ia2AccessibleText::get_caretOffset(long *aOffset)
71 {
72 A11Y_TRYBLOCK_BEGIN
73
74 if (!aOffset)
75 return E_INVALIDARG;
76
77 *aOffset = -1;
78
79 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
80 if (textAcc->IsDefunct())
81 return CO_E_OBJNOTCONNECTED;
82
83 *aOffset = textAcc->CaretOffset();
84 return *aOffset != -1 ? S_OK : S_FALSE;
85
86 A11Y_TRYBLOCK_END
87 }
88
89 STDMETHODIMP
90 ia2AccessibleText::get_characterExtents(long aOffset,
91 enum IA2CoordinateType aCoordType,
92 long* aX, long* aY,
93 long* aWidth, long* aHeight)
94 {
95 A11Y_TRYBLOCK_BEGIN
96
97 if (!aX || !aY || !aWidth || !aHeight)
98 return E_INVALIDARG;
99 *aX = *aY = *aWidth = *aHeight = 0;
100
101 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
102 if (textAcc->IsDefunct())
103 return CO_E_OBJNOTCONNECTED;
104
105 uint32_t geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
106 nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
107 nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
108
109 nsIntRect rect = textAcc->CharBounds(aOffset, geckoCoordType);
110
111 *aX = rect.x;
112 *aY = rect.y;
113 *aWidth = rect.width;
114 *aHeight = rect.height;
115 return S_OK;
116
117 A11Y_TRYBLOCK_END
118 }
119
120 STDMETHODIMP
121 ia2AccessibleText::get_nSelections(long* aNSelections)
122 {
123 A11Y_TRYBLOCK_BEGIN
124
125 if (!aNSelections)
126 return E_INVALIDARG;
127 *aNSelections = 0;
128
129 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
130 if (textAcc->IsDefunct())
131 return CO_E_OBJNOTCONNECTED;
132
133 *aNSelections = textAcc->SelectionCount();
134 return S_OK;
135
136 A11Y_TRYBLOCK_END
137 }
138
139 STDMETHODIMP
140 ia2AccessibleText::get_offsetAtPoint(long aX, long aY,
141 enum IA2CoordinateType aCoordType,
142 long* aOffset)
143 {
144 A11Y_TRYBLOCK_BEGIN
145
146 if (!aOffset)
147 return E_INVALIDARG;
148 *aOffset = 0;
149
150 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
151 if (textAcc->IsDefunct())
152 return CO_E_OBJNOTCONNECTED;
153
154 uint32_t geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
155 nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
156 nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
157
158 *aOffset = textAcc->OffsetAtPoint(aX, aY, geckoCoordType);
159 return *aOffset == -1 ? S_FALSE : S_OK;
160
161 A11Y_TRYBLOCK_END
162 }
163
164 STDMETHODIMP
165 ia2AccessibleText::get_selection(long aSelectionIndex, long* aStartOffset,
166 long* aEndOffset)
167 {
168 A11Y_TRYBLOCK_BEGIN
169
170 if (!aStartOffset || !aEndOffset)
171 return E_INVALIDARG;
172 *aStartOffset = *aEndOffset = 0;
173
174 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
175 if (textAcc->IsDefunct())
176 return CO_E_OBJNOTCONNECTED;
177
178 int32_t startOffset = 0, endOffset = 0;
179 if (!textAcc->SelectionBoundsAt(aSelectionIndex, &startOffset, &endOffset))
180 return E_INVALIDARG;
181
182 *aStartOffset = startOffset;
183 *aEndOffset = endOffset;
184 return S_OK;
185
186 A11Y_TRYBLOCK_END
187 }
188
189 STDMETHODIMP
190 ia2AccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR* aText)
191 {
192 A11Y_TRYBLOCK_BEGIN
193
194 if (!aText)
195 return E_INVALIDARG;
196
197 *aText = nullptr;
198
199 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
200 if (textAcc->IsDefunct())
201 return CO_E_OBJNOTCONNECTED;
202
203 if (!textAcc->IsValidRange(aStartOffset, aEndOffset))
204 return E_INVALIDARG;
205
206 nsAutoString text;
207 textAcc->TextSubstring(aStartOffset, aEndOffset, text);
208 if (text.IsEmpty())
209 return S_FALSE;
210
211 *aText = ::SysAllocStringLen(text.get(), text.Length());
212 return *aText ? S_OK : E_OUTOFMEMORY;
213
214 A11Y_TRYBLOCK_END
215 }
216
217 STDMETHODIMP
218 ia2AccessibleText::get_textBeforeOffset(long aOffset,
219 enum IA2TextBoundaryType aBoundaryType,
220 long* aStartOffset, long* aEndOffset,
221 BSTR* aText)
222 {
223 A11Y_TRYBLOCK_BEGIN
224
225 if (!aStartOffset || !aEndOffset || !aText)
226 return E_INVALIDARG;
227
228 *aStartOffset = *aEndOffset = 0;
229 *aText = nullptr;
230
231 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
232 if (textAcc->IsDefunct())
233 return CO_E_OBJNOTCONNECTED;
234
235 if (!textAcc->IsValidOffset(aOffset))
236 return E_INVALIDARG;
237
238 nsAutoString text;
239 int32_t startOffset = 0, endOffset = 0;
240
241 if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) {
242 startOffset = 0;
243 endOffset = textAcc->CharacterCount();
244 textAcc->TextSubstring(startOffset, endOffset, text);
245 } else {
246 AccessibleTextBoundary boundaryType = GetGeckoTextBoundary(aBoundaryType);
247 if (boundaryType == -1)
248 return S_FALSE;
249
250 textAcc->TextBeforeOffset(aOffset, boundaryType, &startOffset, &endOffset, text);
251 }
252
253 *aStartOffset = startOffset;
254 *aEndOffset = endOffset;
255
256 if (text.IsEmpty())
257 return S_FALSE;
258
259 *aText = ::SysAllocStringLen(text.get(), text.Length());
260 return *aText ? S_OK : E_OUTOFMEMORY;
261
262 A11Y_TRYBLOCK_END
263 }
264
265 STDMETHODIMP
266 ia2AccessibleText::get_textAfterOffset(long aOffset,
267 enum IA2TextBoundaryType aBoundaryType,
268 long* aStartOffset, long* aEndOffset,
269 BSTR* aText)
270 {
271 A11Y_TRYBLOCK_BEGIN
272
273 if (!aStartOffset || !aEndOffset || !aText)
274 return E_INVALIDARG;
275
276 *aStartOffset = 0;
277 *aEndOffset = 0;
278 *aText = nullptr;
279
280 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
281 if (textAcc->IsDefunct())
282 return CO_E_OBJNOTCONNECTED;
283
284 if (!textAcc->IsValidOffset(aOffset))
285 return E_INVALIDARG;
286
287 nsAutoString text;
288 int32_t startOffset = 0, endOffset = 0;
289
290 if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) {
291 startOffset = 0;
292 endOffset = textAcc->CharacterCount();
293 textAcc->TextSubstring(startOffset, endOffset, text);
294 } else {
295 AccessibleTextBoundary boundaryType = GetGeckoTextBoundary(aBoundaryType);
296 if (boundaryType == -1)
297 return S_FALSE;
298 textAcc->TextAfterOffset(aOffset, boundaryType, &startOffset, &endOffset, text);
299 }
300
301 *aStartOffset = startOffset;
302 *aEndOffset = endOffset;
303
304 if (text.IsEmpty())
305 return S_FALSE;
306
307 *aText = ::SysAllocStringLen(text.get(), text.Length());
308 return *aText ? S_OK : E_OUTOFMEMORY;
309
310 A11Y_TRYBLOCK_END
311 }
312
313 STDMETHODIMP
314 ia2AccessibleText::get_textAtOffset(long aOffset,
315 enum IA2TextBoundaryType aBoundaryType,
316 long* aStartOffset, long* aEndOffset,
317 BSTR* aText)
318 {
319 A11Y_TRYBLOCK_BEGIN
320
321 if (!aStartOffset || !aEndOffset || !aText)
322 return E_INVALIDARG;
323
324 *aStartOffset = *aEndOffset = 0;
325 *aText = nullptr;
326
327 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
328 if (textAcc->IsDefunct())
329 return CO_E_OBJNOTCONNECTED;
330
331 if (!textAcc->IsValidOffset(aOffset))
332 return E_INVALIDARG;
333
334 nsAutoString text;
335 int32_t startOffset = 0, endOffset = 0;
336 if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) {
337 startOffset = 0;
338 endOffset = textAcc->CharacterCount();
339 textAcc->TextSubstring(startOffset, endOffset, text);
340 } else {
341 AccessibleTextBoundary boundaryType = GetGeckoTextBoundary(aBoundaryType);
342 if (boundaryType == -1)
343 return S_FALSE;
344 textAcc->TextAtOffset(aOffset, boundaryType, &startOffset, &endOffset, text);
345 }
346
347 *aStartOffset = startOffset;
348 *aEndOffset = endOffset;
349
350 if (text.IsEmpty())
351 return S_FALSE;
352
353 *aText = ::SysAllocStringLen(text.get(), text.Length());
354 return *aText ? S_OK : E_OUTOFMEMORY;
355
356 A11Y_TRYBLOCK_END
357 }
358
359 STDMETHODIMP
360 ia2AccessibleText::removeSelection(long aSelectionIndex)
361 {
362 A11Y_TRYBLOCK_BEGIN
363
364 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
365 if (textAcc->IsDefunct())
366 return CO_E_OBJNOTCONNECTED;
367
368 return textAcc->RemoveFromSelection(aSelectionIndex) ?
369 S_OK : E_INVALIDARG;
370
371 A11Y_TRYBLOCK_END
372 }
373
374 STDMETHODIMP
375 ia2AccessibleText::setCaretOffset(long aOffset)
376 {
377 A11Y_TRYBLOCK_BEGIN
378
379 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
380 if (textAcc->IsDefunct())
381 return CO_E_OBJNOTCONNECTED;
382
383 if (!textAcc->IsValidOffset(aOffset))
384 return E_INVALIDARG;
385
386 textAcc->SetCaretOffset(aOffset);
387 return S_OK;
388
389 A11Y_TRYBLOCK_END
390 }
391
392 STDMETHODIMP
393 ia2AccessibleText::setSelection(long aSelectionIndex, long aStartOffset,
394 long aEndOffset)
395 {
396 A11Y_TRYBLOCK_BEGIN
397
398 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
399 if (textAcc->IsDefunct())
400 return CO_E_OBJNOTCONNECTED;
401
402 return textAcc->SetSelectionBoundsAt(aSelectionIndex, aStartOffset, aEndOffset) ?
403 S_OK : E_INVALIDARG;
404
405 A11Y_TRYBLOCK_END
406 }
407
408 STDMETHODIMP
409 ia2AccessibleText::get_nCharacters(long* aNCharacters)
410 {
411 A11Y_TRYBLOCK_BEGIN
412
413 if (!aNCharacters)
414 return E_INVALIDARG;
415 *aNCharacters = 0;
416
417 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
418 if (textAcc->IsDefunct())
419 return CO_E_OBJNOTCONNECTED;
420
421 *aNCharacters = textAcc->CharacterCount();
422 return S_OK;
423
424 A11Y_TRYBLOCK_END
425 }
426
427 STDMETHODIMP
428 ia2AccessibleText::scrollSubstringTo(long aStartIndex, long aEndIndex,
429 enum IA2ScrollType aScrollType)
430 {
431 A11Y_TRYBLOCK_BEGIN
432
433 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
434 if (textAcc->IsDefunct())
435 return CO_E_OBJNOTCONNECTED;
436
437 if (!textAcc->IsValidRange(aStartIndex, aEndIndex))
438 return E_INVALIDARG;
439
440 textAcc->ScrollSubstringTo(aStartIndex, aEndIndex, aScrollType);
441 return S_OK;
442
443 A11Y_TRYBLOCK_END
444 }
445
446 STDMETHODIMP
447 ia2AccessibleText::scrollSubstringToPoint(long aStartIndex, long aEndIndex,
448 enum IA2CoordinateType aCoordType,
449 long aX, long aY)
450 {
451 A11Y_TRYBLOCK_BEGIN
452
453 HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
454 if (textAcc->IsDefunct())
455 return CO_E_OBJNOTCONNECTED;
456
457 if (!textAcc->IsValidRange(aStartIndex, aEndIndex))
458 return E_INVALIDARG;
459
460 uint32_t geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
461 nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
462 nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
463
464 textAcc->ScrollSubstringToPoint(aStartIndex, aEndIndex,
465 geckoCoordType, aX, aY);
466 return S_OK;
467
468 A11Y_TRYBLOCK_END
469 }
470
471 STDMETHODIMP
472 ia2AccessibleText::get_newText(IA2TextSegment *aNewText)
473 {
474 A11Y_TRYBLOCK_BEGIN
475
476 return GetModifiedText(true, aNewText);
477
478 A11Y_TRYBLOCK_END
479 }
480
481 STDMETHODIMP
482 ia2AccessibleText::get_oldText(IA2TextSegment *aOldText)
483 {
484 A11Y_TRYBLOCK_BEGIN
485
486 return GetModifiedText(false, aOldText);
487
488 A11Y_TRYBLOCK_END
489 }
490
491 // ia2AccessibleText
492
493 HRESULT
494 ia2AccessibleText::GetModifiedText(bool aGetInsertedText,
495 IA2TextSegment *aText)
496 {
497 if (!aText)
498 return E_INVALIDARG;
499
500 uint32_t startOffset = 0, endOffset = 0;
501 nsAutoString text;
502
503 nsresult rv = GetModifiedText(aGetInsertedText, text,
504 &startOffset, &endOffset);
505 if (NS_FAILED(rv))
506 return GetHRESULT(rv);
507
508 aText->start = startOffset;
509 aText->end = endOffset;
510
511 if (text.IsEmpty())
512 return S_FALSE;
513
514 aText->text = ::SysAllocStringLen(text.get(), text.Length());
515 return aText->text ? S_OK : E_OUTOFMEMORY;
516 }
517
518 AccessibleTextBoundary
519 ia2AccessibleText::GetGeckoTextBoundary(enum IA2TextBoundaryType aBoundaryType)
520 {
521 switch (aBoundaryType) {
522 case IA2_TEXT_BOUNDARY_CHAR:
523 return nsIAccessibleText::BOUNDARY_CHAR;
524 case IA2_TEXT_BOUNDARY_WORD:
525 return nsIAccessibleText::BOUNDARY_WORD_START;
526 case IA2_TEXT_BOUNDARY_LINE:
527 return nsIAccessibleText::BOUNDARY_LINE_START;
528 //case IA2_TEXT_BOUNDARY_SENTENCE:
529 //case IA2_TEXT_BOUNDARY_PARAGRAPH:
530 // XXX: not implemented
531 default:
532 return -1;
533 }
534 }
535

mercurial