nsMaiInterfaceTable.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "InterfaceInitFuncs.h"
  6. #include "Accessible-inl.h"
  7. #include "AccessibleWrap.h"
  8. #include "nsAccUtils.h"
  9. #include "TableAccessible.h"
  10. #include "TableCellAccessible.h"
  11. #include "nsMai.h"
  12. #include "ProxyAccessible.h"
  13. #include "nsArrayUtils.h"
  14. #include "mozilla/Likely.h"
  15. using namespace mozilla::a11y;
  16. extern "C" {
  17. static AtkObject*
  18. refAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx)
  19. {
  20. if (aRowIdx < 0 || aColIdx < 0) {
  21. return nullptr;
  22. }
  23. AtkObject* cellAtkObj = nullptr;
  24. AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
  25. if (accWrap) {
  26. Accessible* cell = accWrap->AsTable()->CellAt(aRowIdx, aColIdx);
  27. if (!cell) {
  28. return nullptr;
  29. }
  30. cellAtkObj = AccessibleWrap::GetAtkObject(cell);
  31. } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
  32. ProxyAccessible* cell = proxy->TableCellAt(aRowIdx, aColIdx);
  33. if (!cell) {
  34. return nullptr;
  35. }
  36. cellAtkObj = GetWrapperFor(cell);
  37. }
  38. if (cellAtkObj) {
  39. g_object_ref(cellAtkObj);
  40. }
  41. return cellAtkObj;
  42. }
  43. static gint
  44. getIndexAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx)
  45. {
  46. if (aRowIdx < 0 || aColIdx < 0) {
  47. return -1;
  48. }
  49. AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
  50. if (accWrap) {
  51. return static_cast<gint>(accWrap->AsTable()->CellIndexAt(aRowIdx, aColIdx));
  52. }
  53. if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
  54. return static_cast<gint>(proxy->TableCellIndexAt(aRowIdx, aColIdx));
  55. }
  56. return -1;
  57. }
  58. static gint
  59. getColumnAtIndexCB(AtkTable *aTable, gint aIdx)
  60. {
  61. if (aIdx < 0) {
  62. return -1;
  63. }
  64. AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
  65. if (accWrap) {
  66. return static_cast<gint>(accWrap->AsTable()->ColIndexAt(aIdx));
  67. }
  68. if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
  69. return static_cast<gint>(proxy->TableColumnIndexAt(aIdx));
  70. }
  71. return -1;
  72. }
  73. static gint
  74. getRowAtIndexCB(AtkTable *aTable, gint aIdx)
  75. {
  76. if (aIdx < 0) {
  77. return -1;
  78. }
  79. AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
  80. if (accWrap) {
  81. return static_cast<gint>(accWrap->AsTable()->RowIndexAt(aIdx));
  82. }
  83. if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
  84. return static_cast<gint>(proxy->TableRowIndexAt(aIdx));
  85. }
  86. return -1;
  87. }
  88. static gint
  89. getColumnCountCB(AtkTable *aTable)
  90. {
  91. AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
  92. if (accWrap) {
  93. return static_cast<gint>(accWrap->AsTable()->ColCount());
  94. }
  95. if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
  96. return static_cast<gint>(proxy->TableColumnCount());
  97. }
  98. return -1;
  99. }
  100. static gint
  101. getRowCountCB(AtkTable *aTable)
  102. {
  103. AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
  104. if (accWrap) {
  105. return static_cast<gint>(accWrap->AsTable()->RowCount());
  106. }
  107. if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
  108. return static_cast<gint>(proxy->TableRowCount());
  109. }
  110. return -1;
  111. }
  112. static gint
  113. getColumnExtentAtCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
  114. {
  115. if (aRowIdx < 0 || aColIdx < 0) {
  116. return -1;
  117. }
  118. AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
  119. if (accWrap) {
  120. return static_cast<gint>(accWrap->AsTable()->ColExtentAt(aRowIdx, aColIdx));
  121. }
  122. if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
  123. return static_cast<gint>(proxy->TableColumnExtentAt(aRowIdx, aColIdx));
  124. }
  125. return -1;
  126. }
  127. static gint
  128. getRowExtentAtCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
  129. {
  130. AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
  131. if (accWrap) {
  132. return static_cast<gint>(accWrap->AsTable()->RowExtentAt(aRowIdx, aColIdx));
  133. }
  134. if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
  135. return static_cast<gint>(proxy->TableRowExtentAt(aRowIdx, aColIdx));
  136. }
  137. return -1;
  138. }
  139. static AtkObject*
  140. getCaptionCB(AtkTable* aTable)
  141. {
  142. AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
  143. if (accWrap) {
  144. Accessible* caption = accWrap->AsTable()->Caption();
  145. return caption ? AccessibleWrap::GetAtkObject(caption) : nullptr;
  146. }
  147. if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
  148. ProxyAccessible* caption = proxy->TableCaption();
  149. return caption ? GetWrapperFor(caption) : nullptr;
  150. }
  151. return nullptr;
  152. }
  153. static const gchar*
  154. getColumnDescriptionCB(AtkTable *aTable, gint aColumn)
  155. {
  156. nsAutoString autoStr;
  157. AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
  158. if (accWrap) {
  159. accWrap->AsTable()->ColDescription(aColumn, autoStr);
  160. } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
  161. proxy->TableColumnDescription(aColumn, autoStr);
  162. } else {
  163. return nullptr;
  164. }
  165. return AccessibleWrap::ReturnString(autoStr);
  166. }
  167. static AtkObject*
  168. getColumnHeaderCB(AtkTable *aTable, gint aColIdx)
  169. {
  170. AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
  171. if (accWrap) {
  172. Accessible* header =
  173. AccessibleWrap::GetColumnHeader(accWrap->AsTable(), aColIdx);
  174. return header ? AccessibleWrap::GetAtkObject(header) : nullptr;
  175. }
  176. if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
  177. ProxyAccessible* header = proxy->AtkTableColumnHeader(aColIdx);
  178. return header ? GetWrapperFor(header) : nullptr;
  179. }
  180. return nullptr;
  181. }
  182. static const gchar*
  183. getRowDescriptionCB(AtkTable *aTable, gint aRow)
  184. {
  185. nsAutoString autoStr;
  186. AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
  187. if (accWrap) {
  188. accWrap->AsTable()->RowDescription(aRow, autoStr);
  189. } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
  190. proxy->TableRowDescription(aRow, autoStr);
  191. } else {
  192. return nullptr;
  193. }
  194. return AccessibleWrap::ReturnString(autoStr);
  195. }
  196. static AtkObject*
  197. getRowHeaderCB(AtkTable *aTable, gint aRowIdx)
  198. {
  199. AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
  200. if (accWrap) {
  201. Accessible* header =
  202. AccessibleWrap::GetRowHeader(accWrap->AsTable(), aRowIdx);
  203. return header ? AccessibleWrap::GetAtkObject(header) : nullptr;
  204. }
  205. if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
  206. ProxyAccessible* header = proxy->AtkTableRowHeader(aRowIdx);
  207. return header ? GetWrapperFor(header) : nullptr;
  208. }
  209. return nullptr;
  210. }
  211. static AtkObject*
  212. getSummaryCB(AtkTable *aTable)
  213. {
  214. // Neither html:table nor xul:tree nor ARIA grid/tree have an ability to
  215. // link an accessible object to specify a summary. There is closes method
  216. // in TableAccessible::summary to get a summary as a string which is not
  217. // mapped directly to ATK.
  218. return nullptr;
  219. }
  220. static gint
  221. getSelectedColumnsCB(AtkTable *aTable, gint** aSelected)
  222. {
  223. *aSelected = nullptr;
  224. AutoTArray<uint32_t, 10> cols;
  225. AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
  226. if (accWrap) {
  227. accWrap->AsTable()->SelectedColIndices(&cols);
  228. } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
  229. proxy->TableSelectedColumnIndices(&cols);
  230. } else {
  231. return 0;
  232. }
  233. if (cols.IsEmpty())
  234. return 0;
  235. gint* atkColumns = g_new(gint, cols.Length());
  236. if (!atkColumns) {
  237. NS_WARNING("OUT OF MEMORY");
  238. return 0;
  239. }
  240. memcpy(atkColumns, cols.Elements(), cols.Length() * sizeof(uint32_t));
  241. *aSelected = atkColumns;
  242. return cols.Length();
  243. }
  244. static gint
  245. getSelectedRowsCB(AtkTable *aTable, gint **aSelected)
  246. {
  247. AutoTArray<uint32_t, 10> rows;
  248. AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
  249. if (accWrap) {
  250. accWrap->AsTable()->SelectedRowIndices(&rows);
  251. } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
  252. proxy->TableSelectedRowIndices(&rows);
  253. } else {
  254. return 0;
  255. }
  256. gint* atkRows = g_new(gint, rows.Length());
  257. if (!atkRows) {
  258. NS_WARNING("OUT OF MEMORY");
  259. return 0;
  260. }
  261. memcpy(atkRows, rows.Elements(), rows.Length() * sizeof(uint32_t));
  262. *aSelected = atkRows;
  263. return rows.Length();
  264. }
  265. static gboolean
  266. isColumnSelectedCB(AtkTable *aTable, gint aColIdx)
  267. {
  268. AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
  269. if (accWrap) {
  270. return static_cast<gboolean>(accWrap->AsTable()->IsColSelected(aColIdx));
  271. } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
  272. return static_cast<gboolean>(proxy->TableColumnSelected(aColIdx));
  273. }
  274. return FALSE;
  275. }
  276. static gboolean
  277. isRowSelectedCB(AtkTable *aTable, gint aRowIdx)
  278. {
  279. AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
  280. if (accWrap) {
  281. return static_cast<gboolean>(accWrap->AsTable()->IsRowSelected(aRowIdx));
  282. } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
  283. return static_cast<gboolean>(proxy->TableRowSelected(aRowIdx));
  284. }
  285. return FALSE;
  286. }
  287. static gboolean
  288. isCellSelectedCB(AtkTable *aTable, gint aRowIdx, gint aColIdx)
  289. {
  290. AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
  291. if (accWrap) {
  292. return static_cast<gboolean>(accWrap->AsTable()->
  293. IsCellSelected(aRowIdx, aColIdx));
  294. } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aTable))) {
  295. return static_cast<gboolean>(proxy->TableCellSelected(aRowIdx, aColIdx));
  296. }
  297. return FALSE;
  298. }
  299. }
  300. void
  301. tableInterfaceInitCB(AtkTableIface* aIface)
  302. {
  303. NS_ASSERTION(aIface, "no interface!");
  304. if (MOZ_UNLIKELY(!aIface))
  305. return;
  306. aIface->ref_at = refAtCB;
  307. aIface->get_index_at = getIndexAtCB;
  308. aIface->get_column_at_index = getColumnAtIndexCB;
  309. aIface->get_row_at_index = getRowAtIndexCB;
  310. aIface->get_n_columns = getColumnCountCB;
  311. aIface->get_n_rows = getRowCountCB;
  312. aIface->get_column_extent_at = getColumnExtentAtCB;
  313. aIface->get_row_extent_at = getRowExtentAtCB;
  314. aIface->get_caption = getCaptionCB;
  315. aIface->get_column_description = getColumnDescriptionCB;
  316. aIface->get_column_header = getColumnHeaderCB;
  317. aIface->get_row_description = getRowDescriptionCB;
  318. aIface->get_row_header = getRowHeaderCB;
  319. aIface->get_summary = getSummaryCB;
  320. aIface->get_selected_columns = getSelectedColumnsCB;
  321. aIface->get_selected_rows = getSelectedRowsCB;
  322. aIface->is_column_selected = isColumnSelectedCB;
  323. aIface->is_row_selected = isRowSelectedCB;
  324. aIface->is_selected = isCellSelectedCB;
  325. }