1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "InterfaceInitFuncs.h"
9 #include "Accessible-inl.h"
10 #include "AccessibleWrap.h"
11 #include "nsAccUtils.h"
12 #include "TableAccessible.h"
13 #include "TableCellAccessible.h"
16 #include "nsArrayUtils.h"
18 #include "mozilla/Likely.h"
20 using namespace mozilla::a11y
;
24 refAtCB(AtkTable
* aTable
, gint aRowIdx
, gint aColIdx
)
26 AccessibleWrap
* accWrap
= GetAccessibleWrap(ATK_OBJECT(aTable
));
27 if (!accWrap
|| aRowIdx
< 0 || aColIdx
< 0)
30 Accessible
* cell
= accWrap
->AsTable()->CellAt(aRowIdx
, aColIdx
);
34 AtkObject
* cellAtkObj
= AccessibleWrap::GetAtkObject(cell
);
36 g_object_ref(cellAtkObj
);
42 getIndexAtCB(AtkTable
* aTable
, gint aRowIdx
, gint aColIdx
)
44 AccessibleWrap
* accWrap
= GetAccessibleWrap(ATK_OBJECT(aTable
));
45 if (!accWrap
|| aRowIdx
< 0 || aColIdx
< 0)
48 return static_cast<gint
>(accWrap
->AsTable()->CellIndexAt(aRowIdx
, aColIdx
));
52 getColumnAtIndexCB(AtkTable
*aTable
, gint aIdx
)
54 AccessibleWrap
* accWrap
= GetAccessibleWrap(ATK_OBJECT(aTable
));
55 if (!accWrap
|| aIdx
< 0)
58 return static_cast<gint
>(accWrap
->AsTable()->ColIndexAt(aIdx
));
62 getRowAtIndexCB(AtkTable
*aTable
, gint aIdx
)
64 AccessibleWrap
* accWrap
= GetAccessibleWrap(ATK_OBJECT(aTable
));
65 if (!accWrap
|| aIdx
< 0)
68 return static_cast<gint
>(accWrap
->AsTable()->RowIndexAt(aIdx
));
72 getColumnCountCB(AtkTable
*aTable
)
74 AccessibleWrap
* accWrap
= GetAccessibleWrap(ATK_OBJECT(aTable
));
78 return static_cast<gint
>(accWrap
->AsTable()->ColCount());
82 getRowCountCB(AtkTable
*aTable
)
84 AccessibleWrap
* accWrap
= GetAccessibleWrap(ATK_OBJECT(aTable
));
88 return static_cast<gint
>(accWrap
->AsTable()->RowCount());
92 getColumnExtentAtCB(AtkTable
*aTable
, gint aRowIdx
, gint aColIdx
)
94 AccessibleWrap
* accWrap
= GetAccessibleWrap(ATK_OBJECT(aTable
));
95 if (!accWrap
|| aRowIdx
< 0 || aColIdx
< 0)
98 return static_cast<gint
>(accWrap
->AsTable()->ColExtentAt(aRowIdx
, aColIdx
));
102 getRowExtentAtCB(AtkTable
*aTable
, gint aRowIdx
, gint aColIdx
)
104 AccessibleWrap
* accWrap
= GetAccessibleWrap(ATK_OBJECT(aTable
));
108 return static_cast<gint
>(accWrap
->AsTable()->RowExtentAt(aRowIdx
, aColIdx
));
112 getCaptionCB(AtkTable
* aTable
)
114 AccessibleWrap
* accWrap
= GetAccessibleWrap(ATK_OBJECT(aTable
));
118 Accessible
* caption
= accWrap
->AsTable()->Caption();
119 return caption
? AccessibleWrap::GetAtkObject(caption
) : nullptr;
123 getColumnDescriptionCB(AtkTable
*aTable
, gint aColumn
)
125 AccessibleWrap
* accWrap
= GetAccessibleWrap(ATK_OBJECT(aTable
));
129 nsAutoString autoStr
;
130 accWrap
->AsTable()->ColDescription(aColumn
, autoStr
);
132 return AccessibleWrap::ReturnString(autoStr
);
136 getColumnHeaderCB(AtkTable
*aTable
, gint aColIdx
)
138 AccessibleWrap
* accWrap
= GetAccessibleWrap(ATK_OBJECT(aTable
));
142 Accessible
* cell
= accWrap
->AsTable()->CellAt(0, aColIdx
);
146 // If the cell at the first row is column header then assume it is column
147 // header for all rows,
148 if (cell
->Role() == roles::COLUMNHEADER
)
149 return AccessibleWrap::GetAtkObject(cell
);
151 // otherwise get column header for the data cell at the first row.
152 TableCellAccessible
* tableCell
= cell
->AsTableCell();
156 nsAutoTArray
<Accessible
*, 10> headerCells
;
157 tableCell
->ColHeaderCells(&headerCells
);
158 if (headerCells
.IsEmpty())
161 return AccessibleWrap::GetAtkObject(headerCells
[0]);
165 getRowDescriptionCB(AtkTable
*aTable
, gint aRow
)
167 AccessibleWrap
* accWrap
= GetAccessibleWrap(ATK_OBJECT(aTable
));
171 nsAutoString autoStr
;
172 accWrap
->AsTable()->RowDescription(aRow
, autoStr
);
174 return AccessibleWrap::ReturnString(autoStr
);
178 getRowHeaderCB(AtkTable
*aTable
, gint aRowIdx
)
180 AccessibleWrap
* accWrap
= GetAccessibleWrap(ATK_OBJECT(aTable
));
184 Accessible
* cell
= accWrap
->AsTable()->CellAt(aRowIdx
, 0);
188 // If the cell at the first column is row header then assume it is row
189 // header for all columns,
190 if (cell
->Role() == roles::ROWHEADER
)
191 return AccessibleWrap::GetAtkObject(cell
);
193 // otherwise get row header for the data cell at the first column.
194 TableCellAccessible
* tableCell
= cell
->AsTableCell();
198 nsAutoTArray
<Accessible
*, 10> headerCells
;
199 tableCell
->RowHeaderCells(&headerCells
);
200 if (headerCells
.IsEmpty())
203 return AccessibleWrap::GetAtkObject(headerCells
[0]);
207 getSummaryCB(AtkTable
*aTable
)
209 // Neither html:table nor xul:tree nor ARIA grid/tree have an ability to
210 // link an accessible object to specify a summary. There is closes method
211 // in TableAccessible::summary to get a summary as a string which is not
212 // mapped directly to ATK.
217 getSelectedColumnsCB(AtkTable
*aTable
, gint
** aSelected
)
219 *aSelected
= nullptr;
221 AccessibleWrap
* accWrap
= GetAccessibleWrap(ATK_OBJECT(aTable
));
225 nsAutoTArray
<uint32_t, 10> cols
;
226 accWrap
->AsTable()->SelectedColIndices(&cols
);
230 gint
* atkColumns
= g_new(gint
, cols
.Length());
232 NS_WARNING("OUT OF MEMORY");
236 memcpy(atkColumns
, cols
.Elements(), cols
.Length() * sizeof(uint32_t));
237 *aSelected
= atkColumns
;
238 return cols
.Length();
242 getSelectedRowsCB(AtkTable
*aTable
, gint
**aSelected
)
244 AccessibleWrap
* accWrap
= GetAccessibleWrap(ATK_OBJECT(aTable
));
248 nsAutoTArray
<uint32_t, 10> rows
;
249 accWrap
->AsTable()->SelectedRowIndices(&rows
);
251 gint
* atkRows
= g_new(gint
, rows
.Length());
253 NS_WARNING("OUT OF MEMORY");
257 memcpy(atkRows
, rows
.Elements(), rows
.Length() * sizeof(uint32_t));
258 *aSelected
= atkRows
;
259 return rows
.Length();
263 isColumnSelectedCB(AtkTable
*aTable
, gint aColIdx
)
265 AccessibleWrap
* accWrap
= GetAccessibleWrap(ATK_OBJECT(aTable
));
269 return static_cast<gboolean
>(accWrap
->AsTable()->IsColSelected(aColIdx
));
273 isRowSelectedCB(AtkTable
*aTable
, gint aRowIdx
)
275 AccessibleWrap
* accWrap
= GetAccessibleWrap(ATK_OBJECT(aTable
));
279 return static_cast<gboolean
>(accWrap
->AsTable()->IsRowSelected(aRowIdx
));
283 isCellSelectedCB(AtkTable
*aTable
, gint aRowIdx
, gint aColIdx
)
285 AccessibleWrap
* accWrap
= GetAccessibleWrap(ATK_OBJECT(aTable
));
289 return static_cast<gboolean
>(accWrap
->AsTable()->
290 IsCellSelected(aRowIdx
, aColIdx
));
295 tableInterfaceInitCB(AtkTableIface
* aIface
)
297 NS_ASSERTION(aIface
, "no interface!");
298 if (MOZ_UNLIKELY(!aIface
))
301 aIface
->ref_at
= refAtCB
;
302 aIface
->get_index_at
= getIndexAtCB
;
303 aIface
->get_column_at_index
= getColumnAtIndexCB
;
304 aIface
->get_row_at_index
= getRowAtIndexCB
;
305 aIface
->get_n_columns
= getColumnCountCB
;
306 aIface
->get_n_rows
= getRowCountCB
;
307 aIface
->get_column_extent_at
= getColumnExtentAtCB
;
308 aIface
->get_row_extent_at
= getRowExtentAtCB
;
309 aIface
->get_caption
= getCaptionCB
;
310 aIface
->get_column_description
= getColumnDescriptionCB
;
311 aIface
->get_column_header
= getColumnHeaderCB
;
312 aIface
->get_row_description
= getRowDescriptionCB
;
313 aIface
->get_row_header
= getRowHeaderCB
;
314 aIface
->get_summary
= getSummaryCB
;
315 aIface
->get_selected_columns
= getSelectedColumnsCB
;
316 aIface
->get_selected_rows
= getSelectedRowsCB
;
317 aIface
->is_column_selected
= isColumnSelectedCB
;
318 aIface
->is_row_selected
= isRowSelectedCB
;
319 aIface
->is_selected
= isCellSelectedCB
;