accessible/src/atk/nsMaiInterfaceTable.cpp

branch
TOR_BUG_9701
changeset 8
97036ab72558
equal deleted inserted replaced
-1:000000000000 0:b5ffa122b0d9
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/. */
6
7 #include "InterfaceInitFuncs.h"
8
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"
15
16 #include "nsArrayUtils.h"
17
18 #include "mozilla/Likely.h"
19
20 using namespace mozilla::a11y;
21
22 extern "C" {
23 static AtkObject*
24 refAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx)
25 {
26 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
27 if (!accWrap || aRowIdx < 0 || aColIdx < 0)
28 return nullptr;
29
30 Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, aColIdx);
31 if (!cell)
32 return nullptr;
33
34 AtkObject* cellAtkObj = AccessibleWrap::GetAtkObject(cell);
35 if (cellAtkObj)
36 g_object_ref(cellAtkObj);
37
38 return cellAtkObj;
39 }
40
41 static gint
42 getIndexAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx)
43 {
44 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
45 if (!accWrap || aRowIdx < 0 || aColIdx < 0)
46 return -1;
47
48 return static_cast<gint>(accWrap->AsTable()->CellIndexAt(aRowIdx, aColIdx));
49 }
50
51 static gint
52 getColumnAtIndexCB(AtkTable *aTable, gint aIdx)
53 {
54 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
55 if (!accWrap || aIdx < 0)
56 return -1;
57
58 return static_cast<gint>(accWrap->AsTable()->ColIndexAt(aIdx));
59 }
60
61 static gint
62 getRowAtIndexCB(AtkTable *aTable, gint aIdx)
63 {
64 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
65 if (!accWrap || aIdx < 0)
66 return -1;
67
68 return static_cast<gint>(accWrap->AsTable()->RowIndexAt(aIdx));
69 }
70
71 static gint
72 getColumnCountCB(AtkTable *aTable)
73 {
74 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
75 if (!accWrap)
76 return -1;
77
78 return static_cast<gint>(accWrap->AsTable()->ColCount());
79 }
80
81 static gint
82 getRowCountCB(AtkTable *aTable)
83 {
84 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
85 if (!accWrap)
86 return -1;
87
88 return static_cast<gint>(accWrap->AsTable()->RowCount());
89 }
90
91 static gint
92 getColumnExtentAtCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
93 {
94 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
95 if (!accWrap || aRowIdx < 0 || aColIdx < 0)
96 return -1;
97
98 return static_cast<gint>(accWrap->AsTable()->ColExtentAt(aRowIdx, aColIdx));
99 }
100
101 static gint
102 getRowExtentAtCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
103 {
104 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
105 if (!accWrap)
106 return -1;
107
108 return static_cast<gint>(accWrap->AsTable()->RowExtentAt(aRowIdx, aColIdx));
109 }
110
111 static AtkObject*
112 getCaptionCB(AtkTable* aTable)
113 {
114 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
115 if (!accWrap)
116 return nullptr;
117
118 Accessible* caption = accWrap->AsTable()->Caption();
119 return caption ? AccessibleWrap::GetAtkObject(caption) : nullptr;
120 }
121
122 static const gchar*
123 getColumnDescriptionCB(AtkTable *aTable, gint aColumn)
124 {
125 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
126 if (!accWrap)
127 return nullptr;
128
129 nsAutoString autoStr;
130 accWrap->AsTable()->ColDescription(aColumn, autoStr);
131
132 return AccessibleWrap::ReturnString(autoStr);
133 }
134
135 static AtkObject*
136 getColumnHeaderCB(AtkTable *aTable, gint aColIdx)
137 {
138 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
139 if (!accWrap)
140 return nullptr;
141
142 Accessible* cell = accWrap->AsTable()->CellAt(0, aColIdx);
143 if (!cell)
144 return nullptr;
145
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);
150
151 // otherwise get column header for the data cell at the first row.
152 TableCellAccessible* tableCell = cell->AsTableCell();
153 if (!tableCell)
154 return nullptr;
155
156 nsAutoTArray<Accessible*, 10> headerCells;
157 tableCell->ColHeaderCells(&headerCells);
158 if (headerCells.IsEmpty())
159 return nullptr;
160
161 return AccessibleWrap::GetAtkObject(headerCells[0]);
162 }
163
164 static const gchar*
165 getRowDescriptionCB(AtkTable *aTable, gint aRow)
166 {
167 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
168 if (!accWrap)
169 return nullptr;
170
171 nsAutoString autoStr;
172 accWrap->AsTable()->RowDescription(aRow, autoStr);
173
174 return AccessibleWrap::ReturnString(autoStr);
175 }
176
177 static AtkObject*
178 getRowHeaderCB(AtkTable *aTable, gint aRowIdx)
179 {
180 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
181 if (!accWrap)
182 return nullptr;
183
184 Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, 0);
185 if (!cell)
186 return nullptr;
187
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);
192
193 // otherwise get row header for the data cell at the first column.
194 TableCellAccessible* tableCell = cell->AsTableCell();
195 if (!tableCell)
196 return nullptr;
197
198 nsAutoTArray<Accessible*, 10> headerCells;
199 tableCell->RowHeaderCells(&headerCells);
200 if (headerCells.IsEmpty())
201 return nullptr;
202
203 return AccessibleWrap::GetAtkObject(headerCells[0]);
204 }
205
206 static AtkObject*
207 getSummaryCB(AtkTable *aTable)
208 {
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;
214 }
215
216 static gint
217 getSelectedColumnsCB(AtkTable *aTable, gint** aSelected)
218 {
219 *aSelected = nullptr;
220
221 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
222 if (!accWrap)
223 return 0;
224
225 nsAutoTArray<uint32_t, 10> cols;
226 accWrap->AsTable()->SelectedColIndices(&cols);
227 if (cols.IsEmpty())
228 return 0;
229
230 gint* atkColumns = g_new(gint, cols.Length());
231 if (!atkColumns) {
232 NS_WARNING("OUT OF MEMORY");
233 return 0;
234 }
235
236 memcpy(atkColumns, cols.Elements(), cols.Length() * sizeof(uint32_t));
237 *aSelected = atkColumns;
238 return cols.Length();
239 }
240
241 static gint
242 getSelectedRowsCB(AtkTable *aTable, gint **aSelected)
243 {
244 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
245 if (!accWrap)
246 return 0;
247
248 nsAutoTArray<uint32_t, 10> rows;
249 accWrap->AsTable()->SelectedRowIndices(&rows);
250
251 gint* atkRows = g_new(gint, rows.Length());
252 if (!atkRows) {
253 NS_WARNING("OUT OF MEMORY");
254 return 0;
255 }
256
257 memcpy(atkRows, rows.Elements(), rows.Length() * sizeof(uint32_t));
258 *aSelected = atkRows;
259 return rows.Length();
260 }
261
262 static gboolean
263 isColumnSelectedCB(AtkTable *aTable, gint aColIdx)
264 {
265 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
266 if (!accWrap)
267 return FALSE;
268
269 return static_cast<gboolean>(accWrap->AsTable()->IsColSelected(aColIdx));
270 }
271
272 static gboolean
273 isRowSelectedCB(AtkTable *aTable, gint aRowIdx)
274 {
275 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
276 if (!accWrap)
277 return FALSE;
278
279 return static_cast<gboolean>(accWrap->AsTable()->IsRowSelected(aRowIdx));
280 }
281
282 static gboolean
283 isCellSelectedCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
284 {
285 AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
286 if (!accWrap)
287 return FALSE;
288
289 return static_cast<gboolean>(accWrap->AsTable()->
290 IsCellSelected(aRowIdx, aColIdx));
291 }
292 }
293
294 void
295 tableInterfaceInitCB(AtkTableIface* aIface)
296 {
297 NS_ASSERTION(aIface, "no interface!");
298 if (MOZ_UNLIKELY(!aIface))
299 return;
300
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;
320 }

mercurial