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 "CAccessibleTable.h"
43 #include "Accessible2.h"
44 #include "AccessibleTable_i.c"
46 #include "nsIAccessible.h"
47 #include "nsIAccessibleTable.h"
48 #include "nsIWinAccessNode.h"
49 #include "nsAccessNodeWrap.h"
54 #define CANT_QUERY_ASSERTION_MSG \
55 "Subclass of CAccessibleTable doesn't implement nsIAccessibleTable"\
60 CAccessibleTable::QueryInterface(REFIID iid
, void** ppv
)
64 if (IID_IAccessibleTable
== iid
) {
65 *ppv
= static_cast<IAccessibleTable
*>(this);
66 (reinterpret_cast<IUnknown
*>(*ppv
))->AddRef();
76 CAccessibleTable::get_accessibleAt(long aRow
, long aColumn
,
77 IUnknown
**aAccessible
)
82 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
83 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
87 nsCOMPtr
<nsIAccessible
> cell
;
88 nsresult rv
= tableAcc
->CellRefAt(aRow
, aColumn
, getter_AddRefs(cell
));
90 return GetHRESULT(rv
);
92 nsCOMPtr
<nsIWinAccessNode
> winAccessNode(do_QueryInterface(cell
));
96 void *instancePtr
= NULL
;
97 rv
= winAccessNode
->QueryNativeInterface(IID_IAccessible2
, &instancePtr
);
101 *aAccessible
= static_cast<IUnknown
*>(instancePtr
);
104 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
109 CAccessibleTable::get_caption(IUnknown
**aAccessible
)
114 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
115 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
119 nsCOMPtr
<nsIAccessible
> caption
;
120 nsresult rv
= tableAcc
->GetCaption(getter_AddRefs(caption
));
122 return GetHRESULT(rv
);
127 nsCOMPtr
<nsIWinAccessNode
> winAccessNode(do_QueryInterface(caption
));
131 void *instancePtr
= NULL
;
132 rv
= winAccessNode
->QueryNativeInterface(IID_IAccessible2
, &instancePtr
);
136 *aAccessible
= static_cast<IUnknown
*>(instancePtr
);
139 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
144 CAccessibleTable::get_childIndex(long aRowIndex
, long aColumnIndex
,
150 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
151 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
155 PRInt32 childIndex
= 0;
156 nsresult rv
= tableAcc
->GetIndexAt(aRowIndex
, aColumnIndex
, &childIndex
);
158 return GetHRESULT(rv
);
160 *aChildIndex
= childIndex
;
163 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
168 CAccessibleTable::get_columnDescription(long aColumn
, BSTR
*aDescription
)
171 *aDescription
= NULL
;
173 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
174 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
179 nsresult rv
= tableAcc
->GetColumnDescription (aColumn
, descr
);
181 return GetHRESULT(rv
);
186 *aDescription
= ::SysAllocStringLen(descr
.get(), descr
.Length());
187 return *aDescription
? S_OK
: E_OUTOFMEMORY
;
189 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
194 CAccessibleTable::get_columnExtentAt(long aRow
, long aColumn
,
195 long *nColumnsSpanned
)
198 *nColumnsSpanned
= 0;
200 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
201 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
205 PRInt32 columnsSpanned
= 0;
206 nsresult rv
= tableAcc
->GetColumnExtentAt(aRow
, aColumn
, &columnsSpanned
);
208 return GetHRESULT(rv
);
210 *nColumnsSpanned
= columnsSpanned
;
213 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
218 CAccessibleTable::get_columnHeader(IAccessibleTable
**aAccessibleTable
,
219 long *aStartingRowIndex
)
222 *aAccessibleTable
= NULL
;
224 // XXX: starting row index is always 0.
225 *aStartingRowIndex
= 0;
227 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
228 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
232 nsCOMPtr
<nsIAccessibleTable
> header
;
233 nsresult rv
= tableAcc
->GetColumnHeader(getter_AddRefs(header
));
235 return GetHRESULT(rv
);
240 nsCOMPtr
<nsIWinAccessNode
> winAccessNode(do_QueryInterface(header
));
244 void *instancePtr
= NULL
;
245 rv
= winAccessNode
->QueryNativeInterface(IID_IAccessibleTable
, &instancePtr
);
247 return GetHRESULT(rv
);
249 *aAccessibleTable
= static_cast<IAccessibleTable
*>(instancePtr
);
252 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
257 CAccessibleTable::get_columnIndex(long aChildIndex
, long *aColumnIndex
)
262 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
263 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
267 PRInt32 columnIndex
= 0;
268 nsresult rv
= tableAcc
->GetColumnAtIndex(aChildIndex
, &columnIndex
);
270 return GetHRESULT(rv
);
272 *aColumnIndex
= columnIndex
;
275 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
280 CAccessibleTable::get_nColumns(long *aColumnCount
)
285 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
286 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
290 PRInt32 columnCount
= 0;
291 nsresult rv
= tableAcc
->GetColumns(&columnCount
);
293 return GetHRESULT(rv
);
295 *aColumnCount
= columnCount
;
298 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
303 CAccessibleTable::get_nRows(long *aRowCount
)
308 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
309 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
313 PRInt32 rowCount
= 0;
314 nsresult rv
= tableAcc
->GetRows(&rowCount
);
316 return GetHRESULT(rv
);
318 *aRowCount
= rowCount
;
321 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
326 CAccessibleTable::get_nSelectedChildren(long *aChildCount
)
331 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
332 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
337 nsresult rv
= tableAcc
->GetSelectedCellsCount(&count
);
339 return GetHRESULT(rv
);
341 *aChildCount
= count
;
344 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
349 CAccessibleTable::get_nSelectedColumns(long *aColumnCount
)
354 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
355 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
360 nsresult rv
= tableAcc
->GetSelectedColumnsCount(&count
);
362 return GetHRESULT(rv
);
364 *aColumnCount
= count
;
367 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
372 CAccessibleTable::get_nSelectedRows(long *aRowCount
)
377 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
378 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
383 nsresult rv
= tableAcc
->GetSelectedRowsCount(&count
);
385 return GetHRESULT(rv
);
390 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
395 CAccessibleTable::get_rowDescription(long aRow
, BSTR
*aDescription
)
398 *aDescription
= NULL
;
400 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
401 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
406 nsresult rv
= tableAcc
->GetRowDescription (aRow
, descr
);
408 return GetHRESULT(rv
);
413 *aDescription
= ::SysAllocStringLen(descr
.get(), descr
.Length());
414 return *aDescription
? S_OK
: E_OUTOFMEMORY
;
416 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
421 CAccessibleTable::get_rowExtentAt(long aRow
, long aColumn
, long *aNRowsSpanned
)
426 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
427 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
431 PRInt32 rowsSpanned
= 0;
432 nsresult rv
= tableAcc
->GetRowExtentAt(aRow
, aColumn
, &rowsSpanned
);
434 return GetHRESULT(rv
);
436 *aNRowsSpanned
= rowsSpanned
;
439 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
444 CAccessibleTable::get_rowHeader(IAccessibleTable
**aAccessibleTable
,
445 long *aStartingColumnIndex
)
448 *aAccessibleTable
= NULL
;
450 // XXX: starting column index is always 0.
451 *aStartingColumnIndex
= 0;
453 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
454 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
458 nsCOMPtr
<nsIAccessibleTable
> header
;
459 nsresult rv
= tableAcc
->GetRowHeader(getter_AddRefs(header
));
461 return GetHRESULT(rv
);
466 nsCOMPtr
<nsIWinAccessNode
> winAccessNode(do_QueryInterface(header
));
470 void *instancePtr
= NULL
;
471 rv
= winAccessNode
->QueryNativeInterface(IID_IAccessibleTable
,
474 return GetHRESULT(rv
);
476 *aAccessibleTable
= static_cast<IAccessibleTable
*>(instancePtr
);
479 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
484 CAccessibleTable::get_rowIndex(long aChildIndex
, long *aRowIndex
)
489 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
490 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
494 PRInt32 rowIndex
= 0;
495 nsresult rv
= tableAcc
->GetRowAtIndex(aChildIndex
, &rowIndex
);
497 return GetHRESULT(rv
);
499 *aRowIndex
= rowIndex
;
502 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
507 CAccessibleTable::get_selectedChildren(long aMaxChildren
, long **aChildren
,
511 return GetSelectedItems(aMaxChildren
, aChildren
, aNChildren
, ITEMSTYPE_CELLS
);
512 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
517 CAccessibleTable::get_selectedColumns(long aMaxColumns
, long **aColumns
,
521 return GetSelectedItems(aMaxColumns
, aColumns
, aNColumns
, ITEMSTYPE_COLUMNS
);
522 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
527 CAccessibleTable::get_selectedRows(long aMaxRows
, long **aRows
, long *aNRows
)
530 return GetSelectedItems(aMaxRows
, aRows
, aNRows
, ITEMSTYPE_ROWS
);
531 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
536 CAccessibleTable::get_summary(IUnknown
**aAccessible
)
541 // Neither html:table nor xul:tree nor ARIA grid/tree have an ability to
542 // link an accessible object to specify a summary. There is closes method
543 // in nsIAccessibleTable::summary to get a summary as a string which is not
544 // mapped directly to IAccessible2.
546 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
551 CAccessibleTable::get_isColumnSelected(long aColumn
, boolean
*aIsSelected
)
554 *aIsSelected
= false;
556 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
557 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
561 PRBool isSelected
= PR_FALSE
;
562 nsresult rv
= tableAcc
->IsColumnSelected(aColumn
, &isSelected
);
564 return GetHRESULT(rv
);
566 *aIsSelected
= isSelected
;
569 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
574 CAccessibleTable::get_isRowSelected(long aRow
, boolean
*aIsSelected
)
577 *aIsSelected
= false;
579 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
580 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
584 PRBool isSelected
= PR_FALSE
;
585 nsresult rv
= tableAcc
->IsRowSelected(aRow
, &isSelected
);
587 return GetHRESULT(rv
);
589 *aIsSelected
= isSelected
;
592 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
597 CAccessibleTable::get_isSelected(long aRow
, long aColumn
, boolean
*aIsSelected
)
600 *aIsSelected
= false;
602 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
603 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
607 PRBool isSelected
= PR_FALSE
;
608 nsresult rv
= tableAcc
->IsCellSelected(aRow
, aColumn
, &isSelected
);
610 return GetHRESULT(rv
);
612 *aIsSelected
= isSelected
;
615 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
620 CAccessibleTable::selectRow(long aRow
)
623 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
624 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
628 nsresult rv
= tableAcc
->SelectRow(aRow
);
629 return GetHRESULT(rv
);
631 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
636 CAccessibleTable::selectColumn(long aColumn
)
639 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
640 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
644 nsresult rv
= tableAcc
->SelectColumn(aColumn
);
645 return GetHRESULT(rv
);
647 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
652 CAccessibleTable::unselectRow(long aRow
)
655 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
656 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
660 nsresult rv
= tableAcc
->UnselectRow(aRow
);
661 return GetHRESULT(rv
);
663 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
668 CAccessibleTable::unselectColumn(long aColumn
)
671 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
672 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
676 nsresult rv
= tableAcc
->UnselectColumn(aColumn
);
677 return GetHRESULT(rv
);
679 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
684 CAccessibleTable::get_rowColumnExtentsAtIndex(long aIndex
, long *aRow
,
687 long *aColumnExtents
,
688 boolean
*aIsSelected
)
695 *aIsSelected
= false;
697 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
698 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
703 nsresult rv
= tableAcc
->GetRowAtIndex(aIndex
, &row
);
705 return GetHRESULT(rv
);
708 rv
= tableAcc
->GetColumnAtIndex(aIndex
, &column
);
710 return GetHRESULT(rv
);
712 PRInt32 rowExtents
= 0;
713 rv
= tableAcc
->GetRowExtentAt(row
, column
, &rowExtents
);
715 return GetHRESULT(rv
);
717 PRInt32 columnExtents
= 0;
718 rv
= tableAcc
->GetColumnExtentAt(row
, column
, &columnExtents
);
720 return GetHRESULT(rv
);
722 PRBool isSelected
= PR_FALSE
;
723 rv
= tableAcc
->IsCellSelected(row
, column
, &isSelected
);
725 return GetHRESULT(rv
);
729 *aRowExtents
= rowExtents
;
730 *aColumnExtents
= columnExtents
;
731 *aIsSelected
= isSelected
;
734 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
739 CAccessibleTable::get_modelChange(IA2TableModelChange
*aModelChange
)
743 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
750 CAccessibleTable::GetSelectedItems(long aMaxItems
, long **aItems
,
751 long *aItemsCount
, eItemsType aType
)
755 nsCOMPtr
<nsIAccessibleTable
> tableAcc(do_QueryInterface(this));
756 NS_ASSERTION(tableAcc
, CANT_QUERY_ASSERTION_MSG
);
761 PRInt32
*items
= nsnull
;
765 case ITEMSTYPE_CELLS
:
766 rv
= tableAcc
->GetSelectedCells(&size
, &items
);
768 case ITEMSTYPE_COLUMNS
:
769 rv
= tableAcc
->GetSelectedColumns(&size
, &items
);
772 rv
= tableAcc
->GetSelectedRows(&size
, &items
);
779 return GetHRESULT(rv
);
781 if (size
== 0 || !items
)
784 PRUint32 maxSize
= size
< static_cast<PRUint32
>(aMaxItems
) ? size
: aMaxItems
;
785 *aItemsCount
= maxSize
;
787 *aItems
= static_cast<long*>(nsMemory::Alloc((maxSize
) * sizeof(long)));
789 return E_OUTOFMEMORY
;
791 for (PRUint32 index
= 0; index
< maxSize
; ++index
)
792 (*aItems
)[index
] = items
[index
];
794 nsMemory::Free(items
);