1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:expandtab:shiftwidth=2:tabstop=2:
4 /* ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
17 * The Original Code is mozilla.org code.
19 * The Initial Developer of the Original Code is
21 * Portions created by the Initial Developer are Copyright (C) 2007
22 * the Initial Developer. All Rights Reserved.
25 * Alexander Surkov <surkov.alexander@gmail.com> (original author)
27 * Alternatively, the contents of this file may be used under the terms of
28 * either the GNU General Public License Version 2 or later (the "GPL"), or
29 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
41 #include "CAccessibleText.h"
43 #include "Accessible2.h"
44 #include "AccessibleText_i.c"
46 #include "nsIAccessible.h"
47 #include "nsIAccessibleText.h"
48 #include "nsIAccessibleTypes.h"
49 #include "nsIWinAccessNode.h"
50 #include "nsAccessNodeWrap.h"
51 #include "nsAccessibleWrap.h"
56 #define GET_NSIACCESSIBLETEXT \
57 nsCOMPtr<nsIAccessibleText> textAcc(do_QueryInterface(this));\
58 NS_ASSERTION(textAcc,\
59 "Subclass of CAccessibleText doesn't implement nsIAccessibleText");\
66 CAccessibleText::QueryInterface(REFIID iid
, void** ppv
)
70 if (IID_IAccessibleText
== iid
) {
71 nsCOMPtr
<nsIAccessibleText
> textAcc(do_QueryInterface(this));
75 *ppv
= static_cast<IAccessibleText
*>(this);
76 (reinterpret_cast<IUnknown
*>(*ppv
))->AddRef();
86 CAccessibleText::addSelection(long aStartOffset
, long aEndOffset
)
91 nsresult rv
= textAcc
->AddSelection(aStartOffset
, aEndOffset
);
92 return GetHRESULT(rv
);
94 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
99 CAccessibleText::get_attributes(long aOffset
, long *aStartOffset
,
100 long *aEndOffset
, BSTR
*aTextAttributes
)
103 if (!aStartOffset
|| !aEndOffset
|| !aTextAttributes
)
108 *aTextAttributes
= NULL
;
110 GET_NSIACCESSIBLETEXT
112 PRInt32 startOffset
= 0, endOffset
= 0;
113 nsCOMPtr
<nsIPersistentProperties
> attributes
;
114 nsresult rv
= textAcc
->GetTextAttributes(PR_TRUE
, aOffset
,
115 &startOffset
, &endOffset
,
116 getter_AddRefs(attributes
));
118 return GetHRESULT(rv
);
120 HRESULT hr
= nsAccessibleWrap::ConvertToIA2Attributes(attributes
,
125 *aStartOffset
= startOffset
;
126 *aEndOffset
= endOffset
;
130 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
135 CAccessibleText::get_caretOffset(long *aOffset
)
140 GET_NSIACCESSIBLETEXT
143 nsresult rv
= textAcc
->GetCaretOffset(&offset
);
145 return GetHRESULT(rv
);
150 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
155 CAccessibleText::get_characterExtents(long aOffset
,
156 enum IA2CoordinateType aCoordType
,
158 long *aWidth
, long *aHeight
)
166 GET_NSIACCESSIBLETEXT
168 PRUint32 geckoCoordType
= (aCoordType
== IA2_COORDTYPE_SCREEN_RELATIVE
) ?
169 nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE
:
170 nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE
;
172 PRInt32 x
= 0, y
=0, width
= 0, height
= 0;
173 nsresult rv
= textAcc
->GetCharacterExtents (aOffset
, &x
, &y
, &width
, &height
,
176 return GetHRESULT(rv
);
184 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
189 CAccessibleText::get_nSelections(long *aNSelections
)
194 GET_NSIACCESSIBLETEXT
196 PRInt32 selCount
= 0;
197 nsresult rv
= textAcc
->GetSelectionCount(&selCount
);
199 return GetHRESULT(rv
);
201 *aNSelections
= selCount
;
204 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
209 CAccessibleText::get_offsetAtPoint(long aX
, long aY
,
210 enum IA2CoordinateType aCoordType
,
216 GET_NSIACCESSIBLETEXT
218 PRUint32 geckoCoordType
= (aCoordType
== IA2_COORDTYPE_SCREEN_RELATIVE
) ?
219 nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE
:
220 nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE
;
223 nsresult rv
= textAcc
->GetOffsetAtPoint(aX
, aY
, geckoCoordType
, &offset
);
225 return GetHRESULT(rv
);
230 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
235 CAccessibleText::get_selection(long aSelectionIndex
, long *aStartOffset
,
242 GET_NSIACCESSIBLETEXT
244 PRInt32 startOffset
= 0, endOffset
= 0;
245 nsresult rv
= textAcc
->GetSelectionBounds(aSelectionIndex
,
246 &startOffset
, &endOffset
);
248 return GetHRESULT(rv
);
250 *aStartOffset
= startOffset
;
251 *aEndOffset
= endOffset
;
254 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
259 CAccessibleText::get_text(long aStartOffset
, long aEndOffset
, BSTR
*aText
)
264 GET_NSIACCESSIBLETEXT
267 nsresult rv
= textAcc
->GetText(aStartOffset
, aEndOffset
, text
);
269 return GetHRESULT(rv
);
274 *aText
= ::SysAllocStringLen(text
.get(), text
.Length());
275 return *aText
? S_OK
: E_OUTOFMEMORY
;
277 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
282 CAccessibleText::get_textBeforeOffset(long aOffset
,
283 enum IA2TextBoundaryType aBoundaryType
,
284 long *aStartOffset
, long *aEndOffset
,
292 GET_NSIACCESSIBLETEXT
296 PRInt32 startOffset
= 0, endOffset
= 0;
298 if (aBoundaryType
== IA2_TEXT_BOUNDARY_ALL
) {
300 textAcc
->GetCharacterCount(&endOffset
);
301 rv
= textAcc
->GetText(startOffset
, endOffset
, text
);
303 nsAccessibleTextBoundary boundaryType
= GetGeckoTextBoundary(aBoundaryType
);
304 if (boundaryType
== -1)
306 rv
= textAcc
->GetTextBeforeOffset(aOffset
, boundaryType
,
307 &startOffset
, &endOffset
, text
);
311 return GetHRESULT(rv
);
313 *aStartOffset
= startOffset
;
314 *aEndOffset
= endOffset
;
319 *aText
= ::SysAllocStringLen(text
.get(), text
.Length());
320 return *aText
? S_OK
: E_OUTOFMEMORY
;
322 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
327 CAccessibleText::get_textAfterOffset(long aOffset
,
328 enum IA2TextBoundaryType aBoundaryType
,
329 long *aStartOffset
, long *aEndOffset
,
337 GET_NSIACCESSIBLETEXT
341 PRInt32 startOffset
= 0, endOffset
= 0;
343 if (aBoundaryType
== IA2_TEXT_BOUNDARY_ALL
) {
345 textAcc
->GetCharacterCount(&endOffset
);
346 rv
= textAcc
->GetText(startOffset
, endOffset
, text
);
348 nsAccessibleTextBoundary boundaryType
= GetGeckoTextBoundary(aBoundaryType
);
349 if (boundaryType
== -1)
351 rv
= textAcc
->GetTextAfterOffset(aOffset
, boundaryType
,
352 &startOffset
, &endOffset
, text
);
356 return GetHRESULT(rv
);
358 *aStartOffset
= startOffset
;
359 *aEndOffset
= endOffset
;
364 *aText
= ::SysAllocStringLen(text
.get(), text
.Length());
365 return *aText
? S_OK
: E_OUTOFMEMORY
;
367 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
372 CAccessibleText::get_textAtOffset(long aOffset
,
373 enum IA2TextBoundaryType aBoundaryType
,
374 long *aStartOffset
, long *aEndOffset
,
382 GET_NSIACCESSIBLETEXT
386 PRInt32 startOffset
= 0, endOffset
= 0;
388 if (aBoundaryType
== IA2_TEXT_BOUNDARY_ALL
) {
390 textAcc
->GetCharacterCount(&endOffset
);
391 rv
= textAcc
->GetText(startOffset
, endOffset
, text
);
393 nsAccessibleTextBoundary boundaryType
= GetGeckoTextBoundary(aBoundaryType
);
394 if (boundaryType
== -1)
396 rv
= textAcc
->GetTextAtOffset(aOffset
, boundaryType
,
397 &startOffset
, &endOffset
, text
);
401 return GetHRESULT(rv
);
403 *aStartOffset
= startOffset
;
404 *aEndOffset
= endOffset
;
409 *aText
= ::SysAllocStringLen(text
.get(), text
.Length());
410 return *aText
? S_OK
: E_OUTOFMEMORY
;
412 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
417 CAccessibleText::removeSelection(long aSelectionIndex
)
420 GET_NSIACCESSIBLETEXT
422 nsresult rv
= textAcc
->RemoveSelection(aSelectionIndex
);
423 return GetHRESULT(rv
);
425 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
430 CAccessibleText::setCaretOffset(long aOffset
)
433 GET_NSIACCESSIBLETEXT
435 nsresult rv
= textAcc
->SetCaretOffset(aOffset
);
436 return GetHRESULT(rv
);
438 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
443 CAccessibleText::setSelection(long aSelectionIndex
, long aStartOffset
,
447 GET_NSIACCESSIBLETEXT
449 nsresult rv
= textAcc
->SetSelectionBounds(aSelectionIndex
,
450 aStartOffset
, aEndOffset
);
451 return GetHRESULT(rv
);
453 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
458 CAccessibleText::get_nCharacters(long *aNCharacters
)
463 GET_NSIACCESSIBLETEXT
465 PRInt32 charCount
= 0;
466 nsresult rv
= textAcc
->GetCharacterCount(&charCount
);
468 return GetHRESULT(rv
);
470 *aNCharacters
= charCount
;
473 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
478 CAccessibleText::scrollSubstringTo(long aStartIndex
, long aEndIndex
,
479 enum IA2ScrollType aScrollType
)
482 GET_NSIACCESSIBLETEXT
484 nsresult rv
= textAcc
->ScrollSubstringTo(aStartIndex
, aEndIndex
, aScrollType
);
485 return GetHRESULT(rv
);
487 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
492 CAccessibleText::scrollSubstringToPoint(long aStartIndex
, long aEndIndex
,
493 enum IA2CoordinateType aCoordType
,
497 GET_NSIACCESSIBLETEXT
499 PRUint32 geckoCoordType
= (aCoordType
== IA2_COORDTYPE_SCREEN_RELATIVE
) ?
500 nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE
:
501 nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE
;
503 nsresult rv
= textAcc
->ScrollSubstringToPoint(aStartIndex
, aEndIndex
,
504 geckoCoordType
, aX
, aY
);
505 return GetHRESULT(rv
);
507 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
512 CAccessibleText::get_newText(IA2TextSegment
*aNewText
)
515 return GetModifiedText(PR_TRUE
, aNewText
);
517 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
522 CAccessibleText::get_oldText(IA2TextSegment
*aOldText
)
525 return GetModifiedText(PR_FALSE
, aOldText
);
527 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
534 CAccessibleText::GetModifiedText(PRBool aGetInsertedText
,
535 IA2TextSegment
*aText
)
537 PRUint32 startOffset
= 0, endOffset
= 0;
540 nsresult rv
= GetModifiedText(aGetInsertedText
, text
,
541 &startOffset
, &endOffset
);
543 return GetHRESULT(rv
);
545 aText
->start
= startOffset
;
546 aText
->end
= endOffset
;
551 aText
->text
= ::SysAllocStringLen(text
.get(), text
.Length());
552 return aText
->text
? S_OK
: E_OUTOFMEMORY
;
555 nsAccessibleTextBoundary
556 CAccessibleText::GetGeckoTextBoundary(enum IA2TextBoundaryType aBoundaryType
)
558 switch (aBoundaryType
) {
559 case IA2_TEXT_BOUNDARY_CHAR
:
560 return nsIAccessibleText::BOUNDARY_CHAR
;
561 case IA2_TEXT_BOUNDARY_WORD
:
562 return nsIAccessibleText::BOUNDARY_WORD_START
;
563 case IA2_TEXT_BOUNDARY_LINE
:
564 return nsIAccessibleText::BOUNDARY_LINE_START
;
565 //case IA2_TEXT_BOUNDARY_SENTENCE:
566 //case IA2_TEXT_BOUNDARY_PARAGRAPH:
567 // XXX: not implemented