Bumping manifests a=b2g-bump
[gecko.git] / accessible / atk / nsMaiInterfaceTable.cpp
blob28db194196506246ab17425c9164d8f9c96cb9f6
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"
14 #include "nsMai.h"
16 #include "nsArrayUtils.h"
18 #include "mozilla/Likely.h"
20 using namespace mozilla::a11y;
22 extern "C" {
23 static AtkObject*
24 refAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx)
26 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
27 if (!accWrap || aRowIdx < 0 || aColIdx < 0)
28 return nullptr;
30 Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, aColIdx);
31 if (!cell)
32 return nullptr;
34 AtkObject* cellAtkObj = AccessibleWrap::GetAtkObject(cell);
35 if (cellAtkObj)
36 g_object_ref(cellAtkObj);
38 return cellAtkObj;
41 static gint
42 getIndexAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx)
44 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
45 if (!accWrap || aRowIdx < 0 || aColIdx < 0)
46 return -1;
48 return static_cast<gint>(accWrap->AsTable()->CellIndexAt(aRowIdx, aColIdx));
51 static gint
52 getColumnAtIndexCB(AtkTable *aTable, gint aIdx)
54 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
55 if (!accWrap || aIdx < 0)
56 return -1;
58 return static_cast<gint>(accWrap->AsTable()->ColIndexAt(aIdx));
61 static gint
62 getRowAtIndexCB(AtkTable *aTable, gint aIdx)
64 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
65 if (!accWrap || aIdx < 0)
66 return -1;
68 return static_cast<gint>(accWrap->AsTable()->RowIndexAt(aIdx));
71 static gint
72 getColumnCountCB(AtkTable *aTable)
74 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
75 if (!accWrap)
76 return -1;
78 return static_cast<gint>(accWrap->AsTable()->ColCount());
81 static gint
82 getRowCountCB(AtkTable *aTable)
84 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
85 if (!accWrap)
86 return -1;
88 return static_cast<gint>(accWrap->AsTable()->RowCount());
91 static gint
92 getColumnExtentAtCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
94 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
95 if (!accWrap || aRowIdx < 0 || aColIdx < 0)
96 return -1;
98 return static_cast<gint>(accWrap->AsTable()->ColExtentAt(aRowIdx, aColIdx));
101 static gint
102 getRowExtentAtCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
104 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
105 if (!accWrap)
106 return -1;
108 return static_cast<gint>(accWrap->AsTable()->RowExtentAt(aRowIdx, aColIdx));
111 static AtkObject*
112 getCaptionCB(AtkTable* aTable)
114 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
115 if (!accWrap)
116 return nullptr;
118 Accessible* caption = accWrap->AsTable()->Caption();
119 return caption ? AccessibleWrap::GetAtkObject(caption) : nullptr;
122 static const gchar*
123 getColumnDescriptionCB(AtkTable *aTable, gint aColumn)
125 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
126 if (!accWrap)
127 return nullptr;
129 nsAutoString autoStr;
130 accWrap->AsTable()->ColDescription(aColumn, autoStr);
132 return AccessibleWrap::ReturnString(autoStr);
135 static AtkObject*
136 getColumnHeaderCB(AtkTable *aTable, gint aColIdx)
138 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
139 if (!accWrap)
140 return nullptr;
142 Accessible* cell = accWrap->AsTable()->CellAt(0, aColIdx);
143 if (!cell)
144 return nullptr;
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();
153 if (!tableCell)
154 return nullptr;
156 nsAutoTArray<Accessible*, 10> headerCells;
157 tableCell->ColHeaderCells(&headerCells);
158 if (headerCells.IsEmpty())
159 return nullptr;
161 return AccessibleWrap::GetAtkObject(headerCells[0]);
164 static const gchar*
165 getRowDescriptionCB(AtkTable *aTable, gint aRow)
167 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
168 if (!accWrap)
169 return nullptr;
171 nsAutoString autoStr;
172 accWrap->AsTable()->RowDescription(aRow, autoStr);
174 return AccessibleWrap::ReturnString(autoStr);
177 static AtkObject*
178 getRowHeaderCB(AtkTable *aTable, gint aRowIdx)
180 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
181 if (!accWrap)
182 return nullptr;
184 Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, 0);
185 if (!cell)
186 return nullptr;
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();
195 if (!tableCell)
196 return nullptr;
198 nsAutoTArray<Accessible*, 10> headerCells;
199 tableCell->RowHeaderCells(&headerCells);
200 if (headerCells.IsEmpty())
201 return nullptr;
203 return AccessibleWrap::GetAtkObject(headerCells[0]);
206 static AtkObject*
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.
213 return nullptr;
216 static gint
217 getSelectedColumnsCB(AtkTable *aTable, gint** aSelected)
219 *aSelected = nullptr;
221 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
222 if (!accWrap)
223 return 0;
225 nsAutoTArray<uint32_t, 10> cols;
226 accWrap->AsTable()->SelectedColIndices(&cols);
227 if (cols.IsEmpty())
228 return 0;
230 gint* atkColumns = g_new(gint, cols.Length());
231 if (!atkColumns) {
232 NS_WARNING("OUT OF MEMORY");
233 return 0;
236 memcpy(atkColumns, cols.Elements(), cols.Length() * sizeof(uint32_t));
237 *aSelected = atkColumns;
238 return cols.Length();
241 static gint
242 getSelectedRowsCB(AtkTable *aTable, gint **aSelected)
244 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
245 if (!accWrap)
246 return 0;
248 nsAutoTArray<uint32_t, 10> rows;
249 accWrap->AsTable()->SelectedRowIndices(&rows);
251 gint* atkRows = g_new(gint, rows.Length());
252 if (!atkRows) {
253 NS_WARNING("OUT OF MEMORY");
254 return 0;
257 memcpy(atkRows, rows.Elements(), rows.Length() * sizeof(uint32_t));
258 *aSelected = atkRows;
259 return rows.Length();
262 static gboolean
263 isColumnSelectedCB(AtkTable *aTable, gint aColIdx)
265 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
266 if (!accWrap)
267 return FALSE;
269 return static_cast<gboolean>(accWrap->AsTable()->IsColSelected(aColIdx));
272 static gboolean
273 isRowSelectedCB(AtkTable *aTable, gint aRowIdx)
275 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
276 if (!accWrap)
277 return FALSE;
279 return static_cast<gboolean>(accWrap->AsTable()->IsRowSelected(aRowIdx));
282 static gboolean
283 isCellSelectedCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
285 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
286 if (!accWrap)
287 return FALSE;
289 return static_cast<gboolean>(accWrap->AsTable()->
290 IsCellSelected(aRowIdx, aColIdx));
294 void
295 tableInterfaceInitCB(AtkTableIface* aIface)
297 NS_ASSERTION(aIface, "no interface!");
298 if (MOZ_UNLIKELY(!aIface))
299 return;
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;