1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/accessible/src/atk/nsMaiInterfaceTable.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,320 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "InterfaceInitFuncs.h" 1.11 + 1.12 +#include "Accessible-inl.h" 1.13 +#include "AccessibleWrap.h" 1.14 +#include "nsAccUtils.h" 1.15 +#include "TableAccessible.h" 1.16 +#include "TableCellAccessible.h" 1.17 +#include "nsMai.h" 1.18 + 1.19 +#include "nsArrayUtils.h" 1.20 + 1.21 +#include "mozilla/Likely.h" 1.22 + 1.23 +using namespace mozilla::a11y; 1.24 + 1.25 +extern "C" { 1.26 +static AtkObject* 1.27 +refAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx) 1.28 +{ 1.29 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); 1.30 + if (!accWrap || aRowIdx < 0 || aColIdx < 0) 1.31 + return nullptr; 1.32 + 1.33 + Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, aColIdx); 1.34 + if (!cell) 1.35 + return nullptr; 1.36 + 1.37 + AtkObject* cellAtkObj = AccessibleWrap::GetAtkObject(cell); 1.38 + if (cellAtkObj) 1.39 + g_object_ref(cellAtkObj); 1.40 + 1.41 + return cellAtkObj; 1.42 +} 1.43 + 1.44 +static gint 1.45 +getIndexAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx) 1.46 +{ 1.47 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); 1.48 + if (!accWrap || aRowIdx < 0 || aColIdx < 0) 1.49 + return -1; 1.50 + 1.51 + return static_cast<gint>(accWrap->AsTable()->CellIndexAt(aRowIdx, aColIdx)); 1.52 +} 1.53 + 1.54 +static gint 1.55 +getColumnAtIndexCB(AtkTable *aTable, gint aIdx) 1.56 +{ 1.57 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); 1.58 + if (!accWrap || aIdx < 0) 1.59 + return -1; 1.60 + 1.61 + return static_cast<gint>(accWrap->AsTable()->ColIndexAt(aIdx)); 1.62 +} 1.63 + 1.64 +static gint 1.65 +getRowAtIndexCB(AtkTable *aTable, gint aIdx) 1.66 +{ 1.67 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); 1.68 + if (!accWrap || aIdx < 0) 1.69 + return -1; 1.70 + 1.71 + return static_cast<gint>(accWrap->AsTable()->RowIndexAt(aIdx)); 1.72 +} 1.73 + 1.74 +static gint 1.75 +getColumnCountCB(AtkTable *aTable) 1.76 +{ 1.77 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); 1.78 + if (!accWrap) 1.79 + return -1; 1.80 + 1.81 + return static_cast<gint>(accWrap->AsTable()->ColCount()); 1.82 +} 1.83 + 1.84 +static gint 1.85 +getRowCountCB(AtkTable *aTable) 1.86 +{ 1.87 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); 1.88 + if (!accWrap) 1.89 + return -1; 1.90 + 1.91 + return static_cast<gint>(accWrap->AsTable()->RowCount()); 1.92 +} 1.93 + 1.94 +static gint 1.95 +getColumnExtentAtCB(AtkTable *aTable, gint aRowIdx, gint aColIdx) 1.96 +{ 1.97 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); 1.98 + if (!accWrap || aRowIdx < 0 || aColIdx < 0) 1.99 + return -1; 1.100 + 1.101 + return static_cast<gint>(accWrap->AsTable()->ColExtentAt(aRowIdx, aColIdx)); 1.102 +} 1.103 + 1.104 +static gint 1.105 +getRowExtentAtCB(AtkTable *aTable, gint aRowIdx, gint aColIdx) 1.106 +{ 1.107 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); 1.108 + if (!accWrap) 1.109 + return -1; 1.110 + 1.111 + return static_cast<gint>(accWrap->AsTable()->RowExtentAt(aRowIdx, aColIdx)); 1.112 +} 1.113 + 1.114 +static AtkObject* 1.115 +getCaptionCB(AtkTable* aTable) 1.116 +{ 1.117 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); 1.118 + if (!accWrap) 1.119 + return nullptr; 1.120 + 1.121 + Accessible* caption = accWrap->AsTable()->Caption(); 1.122 + return caption ? AccessibleWrap::GetAtkObject(caption) : nullptr; 1.123 +} 1.124 + 1.125 +static const gchar* 1.126 +getColumnDescriptionCB(AtkTable *aTable, gint aColumn) 1.127 +{ 1.128 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); 1.129 + if (!accWrap) 1.130 + return nullptr; 1.131 + 1.132 + nsAutoString autoStr; 1.133 + accWrap->AsTable()->ColDescription(aColumn, autoStr); 1.134 + 1.135 + return AccessibleWrap::ReturnString(autoStr); 1.136 +} 1.137 + 1.138 +static AtkObject* 1.139 +getColumnHeaderCB(AtkTable *aTable, gint aColIdx) 1.140 +{ 1.141 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); 1.142 + if (!accWrap) 1.143 + return nullptr; 1.144 + 1.145 + Accessible* cell = accWrap->AsTable()->CellAt(0, aColIdx); 1.146 + if (!cell) 1.147 + return nullptr; 1.148 + 1.149 + // If the cell at the first row is column header then assume it is column 1.150 + // header for all rows, 1.151 + if (cell->Role() == roles::COLUMNHEADER) 1.152 + return AccessibleWrap::GetAtkObject(cell); 1.153 + 1.154 + // otherwise get column header for the data cell at the first row. 1.155 + TableCellAccessible* tableCell = cell->AsTableCell(); 1.156 + if (!tableCell) 1.157 + return nullptr; 1.158 + 1.159 + nsAutoTArray<Accessible*, 10> headerCells; 1.160 + tableCell->ColHeaderCells(&headerCells); 1.161 + if (headerCells.IsEmpty()) 1.162 + return nullptr; 1.163 + 1.164 + return AccessibleWrap::GetAtkObject(headerCells[0]); 1.165 +} 1.166 + 1.167 +static const gchar* 1.168 +getRowDescriptionCB(AtkTable *aTable, gint aRow) 1.169 +{ 1.170 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); 1.171 + if (!accWrap) 1.172 + return nullptr; 1.173 + 1.174 + nsAutoString autoStr; 1.175 + accWrap->AsTable()->RowDescription(aRow, autoStr); 1.176 + 1.177 + return AccessibleWrap::ReturnString(autoStr); 1.178 +} 1.179 + 1.180 +static AtkObject* 1.181 +getRowHeaderCB(AtkTable *aTable, gint aRowIdx) 1.182 +{ 1.183 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); 1.184 + if (!accWrap) 1.185 + return nullptr; 1.186 + 1.187 + Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, 0); 1.188 + if (!cell) 1.189 + return nullptr; 1.190 + 1.191 + // If the cell at the first column is row header then assume it is row 1.192 + // header for all columns, 1.193 + if (cell->Role() == roles::ROWHEADER) 1.194 + return AccessibleWrap::GetAtkObject(cell); 1.195 + 1.196 + // otherwise get row header for the data cell at the first column. 1.197 + TableCellAccessible* tableCell = cell->AsTableCell(); 1.198 + if (!tableCell) 1.199 + return nullptr; 1.200 + 1.201 + nsAutoTArray<Accessible*, 10> headerCells; 1.202 + tableCell->RowHeaderCells(&headerCells); 1.203 + if (headerCells.IsEmpty()) 1.204 + return nullptr; 1.205 + 1.206 + return AccessibleWrap::GetAtkObject(headerCells[0]); 1.207 +} 1.208 + 1.209 +static AtkObject* 1.210 +getSummaryCB(AtkTable *aTable) 1.211 +{ 1.212 + // Neither html:table nor xul:tree nor ARIA grid/tree have an ability to 1.213 + // link an accessible object to specify a summary. There is closes method 1.214 + // in TableAccessible::summary to get a summary as a string which is not 1.215 + // mapped directly to ATK. 1.216 + return nullptr; 1.217 +} 1.218 + 1.219 +static gint 1.220 +getSelectedColumnsCB(AtkTable *aTable, gint** aSelected) 1.221 +{ 1.222 + *aSelected = nullptr; 1.223 + 1.224 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); 1.225 + if (!accWrap) 1.226 + return 0; 1.227 + 1.228 + nsAutoTArray<uint32_t, 10> cols; 1.229 + accWrap->AsTable()->SelectedColIndices(&cols); 1.230 + if (cols.IsEmpty()) 1.231 + return 0; 1.232 + 1.233 + gint* atkColumns = g_new(gint, cols.Length()); 1.234 + if (!atkColumns) { 1.235 + NS_WARNING("OUT OF MEMORY"); 1.236 + return 0; 1.237 + } 1.238 + 1.239 + memcpy(atkColumns, cols.Elements(), cols.Length() * sizeof(uint32_t)); 1.240 + *aSelected = atkColumns; 1.241 + return cols.Length(); 1.242 +} 1.243 + 1.244 +static gint 1.245 +getSelectedRowsCB(AtkTable *aTable, gint **aSelected) 1.246 +{ 1.247 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); 1.248 + if (!accWrap) 1.249 + return 0; 1.250 + 1.251 + nsAutoTArray<uint32_t, 10> rows; 1.252 + accWrap->AsTable()->SelectedRowIndices(&rows); 1.253 + 1.254 + gint* atkRows = g_new(gint, rows.Length()); 1.255 + if (!atkRows) { 1.256 + NS_WARNING("OUT OF MEMORY"); 1.257 + return 0; 1.258 + } 1.259 + 1.260 + memcpy(atkRows, rows.Elements(), rows.Length() * sizeof(uint32_t)); 1.261 + *aSelected = atkRows; 1.262 + return rows.Length(); 1.263 +} 1.264 + 1.265 +static gboolean 1.266 +isColumnSelectedCB(AtkTable *aTable, gint aColIdx) 1.267 +{ 1.268 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); 1.269 + if (!accWrap) 1.270 + return FALSE; 1.271 + 1.272 + return static_cast<gboolean>(accWrap->AsTable()->IsColSelected(aColIdx)); 1.273 +} 1.274 + 1.275 +static gboolean 1.276 +isRowSelectedCB(AtkTable *aTable, gint aRowIdx) 1.277 +{ 1.278 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); 1.279 + if (!accWrap) 1.280 + return FALSE; 1.281 + 1.282 + return static_cast<gboolean>(accWrap->AsTable()->IsRowSelected(aRowIdx)); 1.283 +} 1.284 + 1.285 +static gboolean 1.286 +isCellSelectedCB(AtkTable *aTable, gint aRowIdx, gint aColIdx) 1.287 +{ 1.288 + AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable)); 1.289 + if (!accWrap) 1.290 + return FALSE; 1.291 + 1.292 + return static_cast<gboolean>(accWrap->AsTable()-> 1.293 + IsCellSelected(aRowIdx, aColIdx)); 1.294 +} 1.295 +} 1.296 + 1.297 +void 1.298 +tableInterfaceInitCB(AtkTableIface* aIface) 1.299 +{ 1.300 + NS_ASSERTION(aIface, "no interface!"); 1.301 + if (MOZ_UNLIKELY(!aIface)) 1.302 + return; 1.303 + 1.304 + aIface->ref_at = refAtCB; 1.305 + aIface->get_index_at = getIndexAtCB; 1.306 + aIface->get_column_at_index = getColumnAtIndexCB; 1.307 + aIface->get_row_at_index = getRowAtIndexCB; 1.308 + aIface->get_n_columns = getColumnCountCB; 1.309 + aIface->get_n_rows = getRowCountCB; 1.310 + aIface->get_column_extent_at = getColumnExtentAtCB; 1.311 + aIface->get_row_extent_at = getRowExtentAtCB; 1.312 + aIface->get_caption = getCaptionCB; 1.313 + aIface->get_column_description = getColumnDescriptionCB; 1.314 + aIface->get_column_header = getColumnHeaderCB; 1.315 + aIface->get_row_description = getRowDescriptionCB; 1.316 + aIface->get_row_header = getRowHeaderCB; 1.317 + aIface->get_summary = getSummaryCB; 1.318 + aIface->get_selected_columns = getSelectedColumnsCB; 1.319 + aIface->get_selected_rows = getSelectedRowsCB; 1.320 + aIface->is_column_selected = isColumnSelectedCB; 1.321 + aIface->is_row_selected = isRowSelectedCB; 1.322 + aIface->is_selected = isCellSelectedCB; 1.323 +}