1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Mozilla Foundation.
19 : * Portions created by the Initial Developer are Copyright (C) 2009
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Alexander Surkov <surkov.alexander@gmail.com> (original author)
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #include "nsXULTreeGridAccessibleWrap.h"
40 :
41 : #include "nsAccCache.h"
42 : #include "nsAccessibilityService.h"
43 : #include "nsAccUtils.h"
44 : #include "nsDocAccessible.h"
45 : #include "nsEventShell.h"
46 : #include "Relation.h"
47 : #include "Role.h"
48 : #include "States.h"
49 :
50 : #include "nsITreeSelection.h"
51 : #include "nsComponentManagerUtils.h"
52 :
53 : using namespace mozilla::a11y;
54 :
55 : ////////////////////////////////////////////////////////////////////////////////
56 : // nsXULTreeGridAccessible
57 : ////////////////////////////////////////////////////////////////////////////////
58 :
59 0 : nsXULTreeGridAccessible::
60 : nsXULTreeGridAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
61 0 : nsXULTreeAccessible(aContent, aDoc)
62 : {
63 0 : }
64 :
65 : ////////////////////////////////////////////////////////////////////////////////
66 : // nsXULTreeGridAccessible: nsISupports implementation
67 :
68 0 : NS_IMPL_ISUPPORTS_INHERITED1(nsXULTreeGridAccessible,
69 : nsXULTreeAccessible,
70 : nsIAccessibleTable)
71 :
72 : ////////////////////////////////////////////////////////////////////////////////
73 : // nsXULTreeGridAccessible: nsIAccessibleTable implementation
74 :
75 : NS_IMETHODIMP
76 0 : nsXULTreeGridAccessible::GetCaption(nsIAccessible **aCaption)
77 : {
78 0 : NS_ENSURE_ARG_POINTER(aCaption);
79 0 : *aCaption = nsnull;
80 :
81 0 : return IsDefunct() ? NS_ERROR_FAILURE : NS_OK;
82 : }
83 :
84 : NS_IMETHODIMP
85 0 : nsXULTreeGridAccessible::GetSummary(nsAString &aSummary)
86 : {
87 0 : aSummary.Truncate();
88 0 : return IsDefunct() ? NS_ERROR_FAILURE : NS_OK;
89 : }
90 :
91 : NS_IMETHODIMP
92 0 : nsXULTreeGridAccessible::GetColumnCount(PRInt32 *aColumnCount)
93 : {
94 0 : NS_ENSURE_ARG_POINTER(aColumnCount);
95 0 : *aColumnCount = 0;
96 :
97 0 : if (IsDefunct())
98 0 : return NS_ERROR_FAILURE;
99 :
100 0 : *aColumnCount = nsCoreUtils::GetSensibleColumnCount(mTree);
101 0 : return NS_OK;
102 : }
103 :
104 : NS_IMETHODIMP
105 0 : nsXULTreeGridAccessible::GetRowCount(PRInt32 *arowCount)
106 : {
107 0 : NS_ENSURE_ARG_POINTER(arowCount);
108 0 : *arowCount = nsnull;
109 :
110 0 : if (IsDefunct())
111 0 : return NS_ERROR_FAILURE;
112 :
113 0 : return mTreeView->GetRowCount(arowCount);
114 : }
115 :
116 : NS_IMETHODIMP
117 0 : nsXULTreeGridAccessible::GetSelectedCellCount(PRUint32* aCount)
118 : {
119 0 : NS_ENSURE_ARG_POINTER(aCount);
120 0 : *aCount = 0;
121 :
122 0 : PRUint32 selectedrowCount = 0;
123 0 : nsresult rv = GetSelectedRowCount(&selectedrowCount);
124 0 : NS_ENSURE_SUCCESS(rv, rv);
125 :
126 0 : PRInt32 columnCount = 0;
127 0 : rv = GetColumnCount(&columnCount);
128 0 : NS_ENSURE_SUCCESS(rv, rv);
129 :
130 0 : *aCount = selectedrowCount * columnCount;
131 0 : return NS_OK;
132 : }
133 :
134 : NS_IMETHODIMP
135 0 : nsXULTreeGridAccessible::GetSelectedColumnCount(PRUint32* aCount)
136 : {
137 0 : NS_ENSURE_ARG_POINTER(aCount);
138 0 : *aCount = 0;
139 :
140 0 : if (IsDefunct())
141 0 : return NS_ERROR_FAILURE;
142 :
143 : // If all the row has been selected, then all the columns are selected,
144 : // because we can't select a column alone.
145 :
146 0 : PRInt32 rowCount = 0;
147 0 : nsresult rv = GetRowCount(&rowCount);
148 0 : NS_ENSURE_SUCCESS(rv, rv);
149 :
150 0 : PRInt32 selectedrowCount = 0;
151 0 : rv = GetSelectionCount(&selectedrowCount);
152 0 : NS_ENSURE_SUCCESS(rv, rv);
153 :
154 0 : if (rowCount == selectedrowCount) {
155 0 : PRInt32 columnCount = 0;
156 0 : rv = GetColumnCount(&columnCount);
157 0 : NS_ENSURE_SUCCESS(rv, rv);
158 :
159 0 : *aCount = columnCount;
160 : }
161 :
162 0 : return NS_OK;
163 : }
164 :
165 : NS_IMETHODIMP
166 0 : nsXULTreeGridAccessible::GetSelectedRowCount(PRUint32* aCount)
167 : {
168 0 : NS_ENSURE_ARG_POINTER(aCount);
169 0 : *aCount = 0;
170 :
171 0 : if (IsDefunct())
172 0 : return NS_ERROR_FAILURE;
173 :
174 0 : PRInt32 selectedrowCount = 0;
175 0 : nsresult rv = GetSelectionCount(&selectedrowCount);
176 0 : NS_ENSURE_SUCCESS(rv, rv);
177 :
178 0 : *aCount = selectedrowCount;
179 0 : return NS_OK;
180 : }
181 :
182 : NS_IMETHODIMP
183 0 : nsXULTreeGridAccessible::GetSelectedCells(nsIArray **aCells)
184 : {
185 0 : NS_ENSURE_ARG_POINTER(aCells);
186 0 : *aCells = nsnull;
187 :
188 0 : nsCOMPtr<nsIMutableArray> selCells = do_CreateInstance(NS_ARRAY_CONTRACTID);
189 0 : NS_ENSURE_TRUE(selCells, NS_ERROR_FAILURE);
190 :
191 0 : PRInt32 selectedrowCount = 0;
192 0 : nsresult rv = GetSelectionCount(&selectedrowCount);
193 0 : NS_ENSURE_SUCCESS(rv, rv);
194 :
195 0 : PRInt32 columnCount = 0;
196 0 : rv = GetColumnCount(&columnCount);
197 0 : NS_ENSURE_SUCCESS(rv, rv);
198 :
199 0 : nsCOMPtr<nsITreeSelection> selection;
200 0 : rv = mTreeView->GetSelection(getter_AddRefs(selection));
201 0 : NS_ENSURE_SUCCESS(rv, rv);
202 :
203 0 : PRInt32 rowCount = 0;
204 0 : rv = GetRowCount(&rowCount);
205 0 : NS_ENSURE_SUCCESS(rv, rv);
206 :
207 : bool isSelected;
208 0 : for (PRInt32 rowIdx = 0; rowIdx < rowCount; rowIdx++) {
209 0 : selection->IsSelected(rowIdx, &isSelected);
210 0 : if (isSelected) {
211 0 : for (PRInt32 colIdx = 0; colIdx < columnCount; colIdx++) {
212 0 : nsCOMPtr<nsIAccessible> cell;
213 0 : GetCellAt(rowIdx, colIdx, getter_AddRefs(cell));
214 0 : selCells->AppendElement(cell, false);
215 : }
216 : }
217 : }
218 :
219 0 : NS_ADDREF(*aCells = selCells);
220 0 : return NS_OK;
221 : }
222 :
223 : NS_IMETHODIMP
224 0 : nsXULTreeGridAccessible::GetSelectedCellIndices(PRUint32 *aCellsCount,
225 : PRInt32 **aCells)
226 : {
227 0 : NS_ENSURE_ARG_POINTER(aCellsCount);
228 0 : *aCellsCount = 0;
229 0 : NS_ENSURE_ARG_POINTER(aCells);
230 0 : *aCells = nsnull;
231 :
232 0 : PRInt32 selectedrowCount = 0;
233 0 : nsresult rv = GetSelectionCount(&selectedrowCount);
234 0 : NS_ENSURE_SUCCESS(rv, rv);
235 :
236 0 : PRInt32 columnCount = 0;
237 0 : rv = GetColumnCount(&columnCount);
238 0 : NS_ENSURE_SUCCESS(rv, rv);
239 :
240 0 : PRInt32 selectedCellCount = selectedrowCount * columnCount;
241 : PRInt32* outArray = static_cast<PRInt32*>(
242 0 : nsMemory::Alloc(selectedCellCount * sizeof(PRInt32)));
243 0 : NS_ENSURE_TRUE(outArray, NS_ERROR_OUT_OF_MEMORY);
244 :
245 0 : nsCOMPtr<nsITreeSelection> selection;
246 0 : rv = mTreeView->GetSelection(getter_AddRefs(selection));
247 0 : NS_ENSURE_SUCCESS(rv, rv);
248 :
249 0 : PRInt32 rowCount = 0;
250 0 : rv = GetRowCount(&rowCount);
251 0 : NS_ENSURE_SUCCESS(rv, rv);
252 :
253 : bool isSelected;
254 0 : for (PRInt32 rowIdx = 0, arrayIdx = 0; rowIdx < rowCount; rowIdx++) {
255 0 : selection->IsSelected(rowIdx, &isSelected);
256 0 : if (isSelected) {
257 0 : for (PRInt32 colIdx = 0; colIdx < columnCount; colIdx++)
258 0 : outArray[arrayIdx++] = rowIdx * columnCount + colIdx;
259 : }
260 : }
261 :
262 0 : *aCellsCount = selectedCellCount;
263 0 : *aCells = outArray;
264 0 : return NS_OK;
265 : }
266 :
267 : NS_IMETHODIMP
268 0 : nsXULTreeGridAccessible::GetSelectedColumnIndices(PRUint32 *acolumnCount,
269 : PRInt32 **aColumns)
270 : {
271 0 : NS_ENSURE_ARG_POINTER(acolumnCount);
272 0 : *acolumnCount = 0;
273 0 : NS_ENSURE_ARG_POINTER(aColumns);
274 0 : *aColumns = nsnull;
275 :
276 0 : if (IsDefunct())
277 0 : return NS_ERROR_FAILURE;
278 :
279 : // If all the row has been selected, then all the columns are selected.
280 : // Because we can't select a column alone.
281 :
282 0 : PRInt32 rowCount = 0;
283 0 : nsresult rv = GetRowCount(&rowCount);
284 0 : NS_ENSURE_SUCCESS(rv, rv);
285 :
286 0 : PRInt32 selectedrowCount = 0;
287 0 : rv = GetSelectionCount(&selectedrowCount);
288 0 : NS_ENSURE_SUCCESS(rv, rv);
289 :
290 0 : if (rowCount != selectedrowCount)
291 0 : return NS_OK;
292 :
293 0 : PRInt32 columnCount = 0;
294 0 : rv = GetColumnCount(&columnCount);
295 0 : NS_ENSURE_SUCCESS(rv, rv);
296 :
297 : PRInt32* outArray = static_cast<PRInt32*>(
298 0 : nsMemory::Alloc(columnCount * sizeof(PRInt32)));
299 0 : NS_ENSURE_TRUE(outArray, NS_ERROR_OUT_OF_MEMORY);
300 :
301 0 : for (PRInt32 colIdx = 0; colIdx < columnCount; colIdx++)
302 0 : outArray[colIdx] = colIdx;
303 :
304 0 : *acolumnCount = columnCount;
305 0 : *aColumns = outArray;
306 0 : return NS_OK;
307 : }
308 :
309 : NS_IMETHODIMP
310 0 : nsXULTreeGridAccessible::GetSelectedRowIndices(PRUint32 *arowCount,
311 : PRInt32 **aRows)
312 : {
313 0 : NS_ENSURE_ARG_POINTER(arowCount);
314 0 : *arowCount = 0;
315 0 : NS_ENSURE_ARG_POINTER(aRows);
316 0 : *aRows = nsnull;
317 :
318 0 : if (IsDefunct())
319 0 : return NS_ERROR_FAILURE;
320 :
321 0 : PRInt32 selectedrowCount = 0;
322 0 : nsresult rv = GetSelectionCount(&selectedrowCount);
323 0 : NS_ENSURE_SUCCESS(rv, rv);
324 :
325 : PRInt32* outArray = static_cast<PRInt32*>(
326 0 : nsMemory::Alloc(selectedrowCount * sizeof(PRInt32)));
327 0 : NS_ENSURE_TRUE(outArray, NS_ERROR_OUT_OF_MEMORY);
328 :
329 0 : nsCOMPtr<nsITreeSelection> selection;
330 0 : rv = mTreeView->GetSelection(getter_AddRefs(selection));
331 0 : NS_ENSURE_SUCCESS(rv, rv);
332 :
333 0 : PRInt32 rowCount = 0;
334 0 : rv = GetRowCount(&rowCount);
335 0 : NS_ENSURE_SUCCESS(rv, rv);
336 :
337 : bool isSelected;
338 0 : for (PRInt32 rowIdx = 0, arrayIdx = 0; rowIdx < rowCount; rowIdx++) {
339 0 : selection->IsSelected(rowIdx, &isSelected);
340 0 : if (isSelected)
341 0 : outArray[arrayIdx++] = rowIdx;
342 : }
343 :
344 0 : *arowCount = selectedrowCount;
345 0 : *aRows = outArray;
346 0 : return NS_OK;
347 : }
348 :
349 : NS_IMETHODIMP
350 0 : nsXULTreeGridAccessible::GetCellAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
351 : nsIAccessible **aCell)
352 : {
353 0 : NS_ENSURE_ARG_POINTER(aCell);
354 0 : *aCell = nsnull;
355 :
356 0 : if (IsDefunct())
357 0 : return NS_ERROR_FAILURE;
358 :
359 0 : nsAccessible *rowAccessible = GetTreeItemAccessible(aRowIndex);
360 0 : if (!rowAccessible)
361 0 : return NS_ERROR_INVALID_ARG;
362 :
363 : nsCOMPtr<nsITreeColumn> column =
364 0 : nsCoreUtils::GetSensibleColumnAt(mTree, aColumnIndex);
365 0 : if (!column)
366 0 : return NS_ERROR_INVALID_ARG;
367 :
368 0 : nsRefPtr<nsXULTreeItemAccessibleBase> rowAcc = do_QueryObject(rowAccessible);
369 :
370 0 : NS_IF_ADDREF(*aCell = rowAcc->GetCellAccessible(column));
371 0 : return NS_OK;
372 : }
373 :
374 : NS_IMETHODIMP
375 0 : nsXULTreeGridAccessible::GetCellIndexAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
376 : PRInt32 *aCellIndex)
377 : {
378 0 : NS_ENSURE_ARG_POINTER(aCellIndex);
379 0 : *aCellIndex = -1;
380 :
381 0 : if (IsDefunct())
382 0 : return NS_ERROR_FAILURE;
383 :
384 0 : PRInt32 columnCount = 0;
385 0 : nsresult rv = GetColumnCount(&columnCount);
386 0 : NS_ENSURE_SUCCESS(rv, rv);
387 :
388 0 : *aCellIndex = aRowIndex * columnCount + aColumnIndex;
389 0 : return NS_OK;
390 : }
391 :
392 : NS_IMETHODIMP
393 0 : nsXULTreeGridAccessible::GetColumnIndexAt(PRInt32 aCellIndex,
394 : PRInt32 *aColumnIndex)
395 : {
396 0 : NS_ENSURE_ARG_POINTER(aColumnIndex);
397 0 : *aColumnIndex = -1;
398 :
399 0 : PRInt32 columnCount = 0;
400 0 : nsresult rv = GetColumnCount(&columnCount);
401 0 : NS_ENSURE_SUCCESS(rv, rv);
402 :
403 0 : *aColumnIndex = aCellIndex % columnCount;
404 0 : return NS_OK;
405 : }
406 :
407 : NS_IMETHODIMP
408 0 : nsXULTreeGridAccessible::GetRowIndexAt(PRInt32 aCellIndex, PRInt32 *aRowIndex)
409 : {
410 0 : NS_ENSURE_ARG_POINTER(aRowIndex);
411 0 : *aRowIndex = -1;
412 :
413 : PRInt32 columnCount;
414 0 : nsresult rv = GetColumnCount(&columnCount);
415 0 : NS_ENSURE_SUCCESS(rv, rv);
416 :
417 0 : *aRowIndex = aCellIndex / columnCount;
418 0 : return NS_OK;
419 : }
420 :
421 : NS_IMETHODIMP
422 0 : nsXULTreeGridAccessible::GetRowAndColumnIndicesAt(PRInt32 aCellIndex,
423 : PRInt32* aRowIndex,
424 : PRInt32* aColumnIndex)
425 : {
426 0 : NS_ENSURE_ARG_POINTER(aRowIndex);
427 0 : *aRowIndex = -1;
428 0 : NS_ENSURE_ARG_POINTER(aColumnIndex);
429 0 : *aColumnIndex = -1;
430 :
431 0 : if (IsDefunct())
432 0 : return NS_ERROR_FAILURE;
433 :
434 0 : PRInt32 columnCount = 0;
435 0 : nsresult rv = GetColumnCount(&columnCount);
436 0 : NS_ENSURE_SUCCESS(rv, rv);
437 :
438 0 : *aColumnIndex = aCellIndex % columnCount;
439 0 : *aRowIndex = aCellIndex / columnCount;
440 0 : return NS_OK;
441 : }
442 :
443 : NS_IMETHODIMP
444 0 : nsXULTreeGridAccessible::GetColumnExtentAt(PRInt32 aRowIndex,
445 : PRInt32 aColumnIndex,
446 : PRInt32 *aExtentCount)
447 : {
448 0 : NS_ENSURE_ARG_POINTER(aExtentCount);
449 0 : *aExtentCount = 1;
450 :
451 0 : return NS_OK;
452 : }
453 :
454 : NS_IMETHODIMP
455 0 : nsXULTreeGridAccessible::GetRowExtentAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
456 : PRInt32 *aExtentCount)
457 : {
458 0 : NS_ENSURE_ARG_POINTER(aExtentCount);
459 0 : *aExtentCount = 1;
460 :
461 0 : return NS_OK;
462 : }
463 :
464 : NS_IMETHODIMP
465 0 : nsXULTreeGridAccessible::GetColumnDescription(PRInt32 aColumnIndex,
466 : nsAString& aDescription)
467 : {
468 0 : aDescription.Truncate();
469 :
470 0 : if (IsDefunct())
471 0 : return NS_ERROR_FAILURE;
472 :
473 0 : nsCOMPtr<nsIAccessible> treeColumns;
474 0 : nsAccessible::GetFirstChild(getter_AddRefs(treeColumns));
475 0 : if (treeColumns) {
476 0 : nsCOMPtr<nsIAccessible> treeColumnItem;
477 0 : treeColumns->GetChildAt(aColumnIndex, getter_AddRefs(treeColumnItem));
478 0 : if (treeColumnItem)
479 0 : return treeColumnItem->GetName(aDescription);
480 : }
481 :
482 0 : return NS_OK;
483 : }
484 :
485 : NS_IMETHODIMP
486 0 : nsXULTreeGridAccessible::GetRowDescription(PRInt32 aRowIndex,
487 : nsAString& aDescription)
488 : {
489 0 : aDescription.Truncate();
490 0 : return NS_OK;
491 : }
492 :
493 : NS_IMETHODIMP
494 0 : nsXULTreeGridAccessible::IsColumnSelected(PRInt32 aColumnIndex,
495 : bool *aIsSelected)
496 : {
497 0 : NS_ENSURE_ARG_POINTER(aIsSelected);
498 0 : *aIsSelected = false;
499 :
500 0 : if (IsDefunct())
501 0 : return NS_ERROR_FAILURE;
502 :
503 : // If all the row has been selected, then all the columns are selected.
504 : // Because we can't select a column alone.
505 :
506 0 : PRInt32 rowCount = 0;
507 0 : nsresult rv = GetRowCount(&rowCount);
508 0 : NS_ENSURE_SUCCESS(rv, rv);
509 :
510 0 : PRInt32 selectedrowCount = 0;
511 0 : rv = GetSelectionCount(&selectedrowCount);
512 0 : NS_ENSURE_SUCCESS(rv, rv);
513 :
514 0 : *aIsSelected = rowCount == selectedrowCount;
515 0 : return NS_OK;
516 : }
517 :
518 : NS_IMETHODIMP
519 0 : nsXULTreeGridAccessible::IsRowSelected(PRInt32 aRowIndex, bool *aIsSelected)
520 : {
521 0 : NS_ENSURE_ARG_POINTER(aIsSelected);
522 0 : *aIsSelected = false;
523 :
524 0 : if (IsDefunct())
525 0 : return NS_ERROR_FAILURE;
526 :
527 0 : nsCOMPtr<nsITreeSelection> selection;
528 0 : nsresult rv = mTreeView->GetSelection(getter_AddRefs(selection));
529 0 : NS_ENSURE_SUCCESS(rv, rv);
530 :
531 0 : return selection->IsSelected(aRowIndex, aIsSelected);
532 : }
533 :
534 : NS_IMETHODIMP
535 0 : nsXULTreeGridAccessible::IsCellSelected(PRInt32 aRowIndex, PRInt32 aColumnIndex,
536 : bool *aIsSelected)
537 : {
538 0 : return IsRowSelected(aRowIndex, aIsSelected);
539 : }
540 :
541 : NS_IMETHODIMP
542 0 : nsXULTreeGridAccessible::SelectRow(PRInt32 aRowIndex)
543 : {
544 0 : nsCOMPtr<nsITreeSelection> selection;
545 0 : mTreeView->GetSelection(getter_AddRefs(selection));
546 0 : NS_ENSURE_STATE(selection);
547 :
548 0 : return selection->Select(aRowIndex);
549 : }
550 :
551 : NS_IMETHODIMP
552 0 : nsXULTreeGridAccessible::SelectColumn(PRInt32 aColumnIndex)
553 : {
554 0 : return NS_OK;
555 : }
556 :
557 : NS_IMETHODIMP
558 0 : nsXULTreeGridAccessible::UnselectRow(PRInt32 aRowIndex)
559 : {
560 0 : nsCOMPtr<nsITreeSelection> selection;
561 0 : mTreeView->GetSelection(getter_AddRefs(selection));
562 0 : NS_ENSURE_STATE(selection);
563 :
564 0 : return selection->ClearRange(aRowIndex, aRowIndex);
565 : }
566 :
567 : NS_IMETHODIMP
568 0 : nsXULTreeGridAccessible::UnselectColumn(PRInt32 aColumnIndex)
569 : {
570 0 : return NS_OK;
571 : }
572 :
573 : NS_IMETHODIMP
574 0 : nsXULTreeGridAccessible::IsProbablyForLayout(bool *aIsProbablyForLayout)
575 : {
576 0 : NS_ENSURE_ARG_POINTER(aIsProbablyForLayout);
577 0 : *aIsProbablyForLayout = false;
578 :
579 0 : return NS_OK;
580 : }
581 :
582 : ////////////////////////////////////////////////////////////////////////////////
583 : // nsXULTreeGridAccessible: nsAccessible implementation
584 :
585 : role
586 0 : nsXULTreeGridAccessible::NativeRole()
587 : {
588 0 : nsCOMPtr<nsITreeColumns> treeColumns;
589 0 : mTree->GetColumns(getter_AddRefs(treeColumns));
590 0 : if (!treeColumns) {
591 0 : NS_ERROR("No treecolumns object for tree!");
592 0 : return roles::NOTHING;
593 : }
594 :
595 0 : nsCOMPtr<nsITreeColumn> primaryColumn;
596 0 : treeColumns->GetPrimaryColumn(getter_AddRefs(primaryColumn));
597 :
598 0 : return primaryColumn ? roles::TREE_TABLE : roles::TABLE;
599 : }
600 :
601 : ////////////////////////////////////////////////////////////////////////////////
602 : // nsXULTreeGridAccessible: nsXULTreeAccessible implementation
603 :
604 : already_AddRefed<nsAccessible>
605 0 : nsXULTreeGridAccessible::CreateTreeItemAccessible(PRInt32 aRow)
606 : {
607 : nsRefPtr<nsAccessible> accessible =
608 : new nsXULTreeGridRowAccessible(mContent, mDoc, this, mTree,
609 0 : mTreeView, aRow);
610 :
611 0 : return accessible.forget();
612 : }
613 :
614 :
615 : ////////////////////////////////////////////////////////////////////////////////
616 : // nsXULTreeGridRowAccessible
617 : ////////////////////////////////////////////////////////////////////////////////
618 :
619 0 : nsXULTreeGridRowAccessible::
620 : nsXULTreeGridRowAccessible(nsIContent* aContent, nsDocAccessible* aDoc,
621 : nsAccessible* aTreeAcc, nsITreeBoxObject* aTree,
622 : nsITreeView* aTreeView, PRInt32 aRow) :
623 0 : nsXULTreeItemAccessibleBase(aContent, aDoc, aTreeAcc, aTree, aTreeView, aRow)
624 : {
625 0 : mAccessibleCache.Init(kDefaultTreeCacheSize);
626 0 : }
627 :
628 : ////////////////////////////////////////////////////////////////////////////////
629 : // nsXULTreeGridRowAccessible: nsISupports and cycle collection implementation
630 :
631 1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULTreeGridRowAccessible)
632 :
633 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXULTreeGridRowAccessible,
634 : nsXULTreeItemAccessibleBase)
635 0 : CycleCollectorTraverseCache(tmp->mAccessibleCache, &cb);
636 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
637 :
638 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXULTreeGridRowAccessible,
639 : nsXULTreeItemAccessibleBase)
640 0 : ClearCache(tmp->mAccessibleCache);
641 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
642 :
643 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXULTreeGridRowAccessible)
644 0 : NS_INTERFACE_MAP_STATIC_AMBIGUOUS(nsXULTreeGridRowAccessible)
645 0 : NS_INTERFACE_MAP_END_INHERITING(nsXULTreeItemAccessibleBase)
646 :
647 0 : NS_IMPL_ADDREF_INHERITED(nsXULTreeGridRowAccessible,
648 : nsXULTreeItemAccessibleBase)
649 0 : NS_IMPL_RELEASE_INHERITED(nsXULTreeGridRowAccessible,
650 : nsXULTreeItemAccessibleBase)
651 :
652 : ////////////////////////////////////////////////////////////////////////////////
653 : // nsXULTreeGridRowAccessible: nsAccessNode implementation
654 :
655 : void
656 0 : nsXULTreeGridRowAccessible::Shutdown()
657 : {
658 0 : ClearCache(mAccessibleCache);
659 0 : nsXULTreeItemAccessibleBase::Shutdown();
660 0 : }
661 :
662 : ////////////////////////////////////////////////////////////////////////////////
663 : // nsXULTreeGridRowAccessible: nsAccessible implementation
664 :
665 : role
666 0 : nsXULTreeGridRowAccessible::NativeRole()
667 : {
668 0 : return roles::ROW;
669 : }
670 :
671 : NS_IMETHODIMP
672 0 : nsXULTreeGridRowAccessible::GetName(nsAString& aName)
673 : {
674 0 : aName.Truncate();
675 :
676 0 : if (IsDefunct())
677 0 : return NS_ERROR_FAILURE;
678 :
679 : // XXX: the row name sholdn't be a concatenation of cell names (bug 664384).
680 0 : nsCOMPtr<nsITreeColumn> column = nsCoreUtils::GetFirstSensibleColumn(mTree);
681 0 : while (column) {
682 0 : if (!aName.IsEmpty())
683 0 : aName.AppendLiteral(" ");
684 :
685 0 : nsAutoString cellName;
686 0 : GetCellName(column, cellName);
687 0 : aName.Append(cellName);
688 :
689 0 : column = nsCoreUtils::GetNextSensibleColumn(column);
690 : }
691 :
692 0 : return NS_OK;
693 : }
694 :
695 : nsAccessible*
696 0 : nsXULTreeGridRowAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
697 : EWhichChildAtPoint aWhichChild)
698 : {
699 0 : nsIFrame *frame = GetFrame();
700 0 : if (!frame)
701 0 : return nsnull;
702 :
703 0 : nsPresContext *presContext = frame->PresContext();
704 0 : nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
705 :
706 0 : nsIFrame *rootFrame = presShell->GetRootFrame();
707 0 : NS_ENSURE_TRUE(rootFrame, nsnull);
708 :
709 0 : nsIntRect rootRect = rootFrame->GetScreenRectExternal();
710 :
711 0 : PRInt32 clientX = presContext->DevPixelsToIntCSSPixels(aX - rootRect.x);
712 0 : PRInt32 clientY = presContext->DevPixelsToIntCSSPixels(aY - rootRect.y);
713 :
714 0 : PRInt32 row = -1;
715 0 : nsCOMPtr<nsITreeColumn> column;
716 0 : nsCAutoString childEltUnused;
717 0 : mTree->GetCellAt(clientX, clientY, &row, getter_AddRefs(column),
718 0 : childEltUnused);
719 :
720 : // Return if we failed to find tree cell in the row for the given point.
721 0 : if (row != mRow || !column)
722 0 : return nsnull;
723 :
724 0 : return GetCellAccessible(column);
725 : }
726 :
727 : nsAccessible*
728 0 : nsXULTreeGridRowAccessible::GetChildAt(PRUint32 aIndex)
729 : {
730 0 : if (IsDefunct())
731 0 : return nsnull;
732 :
733 : nsCOMPtr<nsITreeColumn> column =
734 0 : nsCoreUtils::GetSensibleColumnAt(mTree, aIndex);
735 0 : if (!column)
736 0 : return nsnull;
737 :
738 0 : return GetCellAccessible(column);
739 : }
740 :
741 : PRInt32
742 0 : nsXULTreeGridRowAccessible::GetChildCount()
743 : {
744 0 : if (IsDefunct())
745 0 : return -1;
746 :
747 0 : return nsCoreUtils::GetSensibleColumnCount(mTree);
748 : }
749 :
750 : ////////////////////////////////////////////////////////////////////////////////
751 : // nsXULTreeGridRowAccessible: nsXULTreeItemAccessibleBase implementation
752 :
753 : nsAccessible*
754 0 : nsXULTreeGridRowAccessible::GetCellAccessible(nsITreeColumn* aColumn)
755 : {
756 0 : NS_PRECONDITION(aColumn, "No tree column!");
757 :
758 0 : void* key = static_cast<void*>(aColumn);
759 0 : nsAccessible* cachedCell = mAccessibleCache.GetWeak(key);
760 0 : if (cachedCell)
761 0 : return cachedCell;
762 :
763 : nsRefPtr<nsAccessible> cell =
764 : new nsXULTreeGridCellAccessibleWrap(mContent, mDoc, this, mTree,
765 0 : mTreeView, mRow, aColumn);
766 0 : if (cell) {
767 0 : if (mAccessibleCache.Put(key, cell)) {
768 0 : if (Document()->BindToDocument(cell, nsnull))
769 0 : return cell;
770 :
771 0 : mAccessibleCache.Remove(key);
772 : }
773 : }
774 :
775 0 : return nsnull;
776 : }
777 :
778 : void
779 0 : nsXULTreeGridRowAccessible::RowInvalidated(PRInt32 aStartColIdx,
780 : PRInt32 aEndColIdx)
781 : {
782 0 : nsCOMPtr<nsITreeColumns> treeColumns;
783 0 : mTree->GetColumns(getter_AddRefs(treeColumns));
784 0 : if (!treeColumns)
785 : return;
786 :
787 0 : for (PRInt32 colIdx = aStartColIdx; colIdx <= aEndColIdx; ++colIdx) {
788 0 : nsCOMPtr<nsITreeColumn> column;
789 0 : treeColumns->GetColumnAt(colIdx, getter_AddRefs(column));
790 0 : if (column && !nsCoreUtils::IsColumnHidden(column)) {
791 0 : nsAccessible *cellAccessible = GetCellAccessible(column);
792 0 : if (cellAccessible) {
793 0 : nsRefPtr<nsXULTreeGridCellAccessible> cellAcc = do_QueryObject(cellAccessible);
794 :
795 0 : cellAcc->CellInvalidated();
796 : }
797 : }
798 : }
799 : }
800 :
801 : ////////////////////////////////////////////////////////////////////////////////
802 : // nsXULTreeGridRowAccessible: nsAccessible protected implementation
803 :
804 : void
805 0 : nsXULTreeGridRowAccessible::CacheChildren()
806 : {
807 0 : }
808 :
809 : ////////////////////////////////////////////////////////////////////////////////
810 : // nsXULTreeGridCellAccessible
811 : ////////////////////////////////////////////////////////////////////////////////
812 :
813 0 : nsXULTreeGridCellAccessible::
814 : nsXULTreeGridCellAccessible(nsIContent* aContent, nsDocAccessible* aDoc,
815 : nsXULTreeGridRowAccessible* aRowAcc,
816 : nsITreeBoxObject* aTree, nsITreeView* aTreeView,
817 : PRInt32 aRow, nsITreeColumn* aColumn) :
818 : nsLeafAccessible(aContent, aDoc), mTree(aTree),
819 0 : mTreeView(aTreeView), mRow(aRow), mColumn(aColumn)
820 : {
821 0 : mParent = aRowAcc;
822 0 : }
823 :
824 : ////////////////////////////////////////////////////////////////////////////////
825 : // nsXULTreeGridCellAccessible: nsISupports implementation
826 :
827 1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULTreeGridCellAccessible)
828 :
829 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXULTreeGridCellAccessible,
830 : nsLeafAccessible)
831 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTree)
832 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTreeView)
833 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mColumn)
834 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
835 :
836 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXULTreeGridCellAccessible,
837 : nsLeafAccessible)
838 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTree)
839 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTreeView)
840 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mColumn)
841 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
842 :
843 0 : NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsXULTreeGridCellAccessible)
844 0 : NS_INTERFACE_TABLE_INHERITED2(nsXULTreeGridCellAccessible,
845 : nsIAccessibleTableCell,
846 : nsXULTreeGridCellAccessible)
847 0 : NS_INTERFACE_TABLE_TAIL_INHERITING(nsLeafAccessible)
848 0 : NS_IMPL_ADDREF_INHERITED(nsXULTreeGridCellAccessible, nsLeafAccessible)
849 0 : NS_IMPL_RELEASE_INHERITED(nsXULTreeGridCellAccessible, nsLeafAccessible)
850 :
851 : ////////////////////////////////////////////////////////////////////////////////
852 : // nsXULTreeGridCellAccessible: nsIAccessible implementation
853 :
854 : nsAccessible*
855 0 : nsXULTreeGridCellAccessible::FocusedChild()
856 : {
857 0 : return nsnull;
858 : }
859 :
860 : NS_IMETHODIMP
861 0 : nsXULTreeGridCellAccessible::GetName(nsAString& aName)
862 : {
863 0 : aName.Truncate();
864 :
865 0 : if (IsDefunct())
866 0 : return NS_ERROR_FAILURE;
867 :
868 0 : mTreeView->GetCellText(mRow, mColumn, aName);
869 :
870 : // If there is still no name try the cell value:
871 : // This is for graphical cells. We need tree/table view implementors to implement
872 : // FooView::GetCellValue to return a meaningful string for cases where there is
873 : // something shown in the cell (non-text) such as a star icon; in which case
874 : // GetCellValue for that cell would return "starred" or "flagged" for example.
875 0 : if (aName.IsEmpty())
876 0 : mTreeView->GetCellValue(mRow, mColumn, aName);
877 :
878 0 : return NS_OK;
879 : }
880 :
881 : NS_IMETHODIMP
882 0 : nsXULTreeGridCellAccessible::GetBounds(PRInt32 *aX, PRInt32 *aY,
883 : PRInt32 *aWidth, PRInt32 *aHeight)
884 : {
885 0 : NS_ENSURE_ARG_POINTER(aX);
886 0 : *aX = 0;
887 0 : NS_ENSURE_ARG_POINTER(aY);
888 0 : *aY = 0;
889 0 : NS_ENSURE_ARG_POINTER(aWidth);
890 0 : *aWidth = 0;
891 0 : NS_ENSURE_ARG_POINTER(aHeight);
892 0 : *aHeight = 0;
893 :
894 0 : if (IsDefunct())
895 0 : return NS_ERROR_FAILURE;
896 :
897 : // Get bounds for tree cell and add x and y of treechildren element to
898 : // x and y of the cell.
899 0 : nsCOMPtr<nsIBoxObject> boxObj = nsCoreUtils::GetTreeBodyBoxObject(mTree);
900 0 : NS_ENSURE_STATE(boxObj);
901 :
902 0 : PRInt32 x = 0, y = 0, width = 0, height = 0;
903 0 : nsresult rv = mTree->GetCoordsForCellItem(mRow, mColumn,
904 0 : NS_LITERAL_CSTRING("cell"),
905 0 : &x, &y, &width, &height);
906 0 : NS_ENSURE_SUCCESS(rv, rv);
907 :
908 0 : PRInt32 tcX = 0, tcY = 0;
909 0 : boxObj->GetScreenX(&tcX);
910 0 : boxObj->GetScreenY(&tcY);
911 0 : x += tcX;
912 0 : y += tcY;
913 :
914 0 : nsPresContext *presContext = GetPresContext();
915 0 : *aX = presContext->CSSPixelsToDevPixels(x);
916 0 : *aY = presContext->CSSPixelsToDevPixels(y);
917 0 : *aWidth = presContext->CSSPixelsToDevPixels(width);
918 0 : *aHeight = presContext->CSSPixelsToDevPixels(height);
919 :
920 0 : return NS_OK;
921 : }
922 :
923 : PRUint8
924 0 : nsXULTreeGridCellAccessible::ActionCount()
925 : {
926 0 : bool isCycler = false;
927 0 : mColumn->GetCycler(&isCycler);
928 0 : if (isCycler)
929 0 : return 1;
930 :
931 : PRInt16 type;
932 0 : mColumn->GetType(&type);
933 0 : if (type == nsITreeColumn::TYPE_CHECKBOX && IsEditable())
934 0 : return 1;
935 :
936 0 : return 0;
937 : }
938 :
939 : NS_IMETHODIMP
940 0 : nsXULTreeGridCellAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
941 : {
942 0 : aName.Truncate();
943 :
944 0 : if (aIndex != eAction_Click)
945 0 : return NS_ERROR_INVALID_ARG;
946 :
947 0 : if (IsDefunct())
948 0 : return NS_ERROR_FAILURE;
949 :
950 0 : bool isCycler = false;
951 0 : mColumn->GetCycler(&isCycler);
952 0 : if (isCycler) {
953 0 : aName.AssignLiteral("cycle");
954 0 : return NS_OK;
955 : }
956 :
957 : PRInt16 type;
958 0 : mColumn->GetType(&type);
959 0 : if (type == nsITreeColumn::TYPE_CHECKBOX && IsEditable()) {
960 0 : nsAutoString value;
961 0 : mTreeView->GetCellValue(mRow, mColumn, value);
962 0 : if (value.EqualsLiteral("true"))
963 0 : aName.AssignLiteral("uncheck");
964 : else
965 0 : aName.AssignLiteral("check");
966 :
967 0 : return NS_OK;
968 : }
969 :
970 0 : return NS_ERROR_INVALID_ARG;
971 : }
972 :
973 : NS_IMETHODIMP
974 0 : nsXULTreeGridCellAccessible::DoAction(PRUint8 aIndex)
975 : {
976 0 : if (aIndex != eAction_Click)
977 0 : return NS_ERROR_INVALID_ARG;
978 :
979 0 : if (IsDefunct())
980 0 : return NS_ERROR_FAILURE;
981 :
982 0 : bool isCycler = false;
983 0 : mColumn->GetCycler(&isCycler);
984 0 : if (isCycler) {
985 0 : DoCommand();
986 0 : return NS_OK;
987 : }
988 :
989 : PRInt16 type;
990 0 : mColumn->GetType(&type);
991 0 : if (type == nsITreeColumn::TYPE_CHECKBOX && IsEditable()) {
992 0 : DoCommand();
993 0 : return NS_OK;
994 : }
995 :
996 0 : return NS_ERROR_INVALID_ARG;
997 : }
998 :
999 : ////////////////////////////////////////////////////////////////////////////////
1000 : // nsXULTreeGridCellAccessible: nsIAccessibleTableCell implementation
1001 :
1002 : NS_IMETHODIMP
1003 0 : nsXULTreeGridCellAccessible::GetTable(nsIAccessibleTable **aTable)
1004 : {
1005 0 : NS_ENSURE_ARG_POINTER(aTable);
1006 0 : *aTable = nsnull;
1007 :
1008 0 : if (IsDefunct())
1009 0 : return NS_OK;
1010 :
1011 0 : nsAccessible* grandParent = mParent->Parent();
1012 0 : if (grandParent)
1013 0 : CallQueryInterface(grandParent, aTable);
1014 :
1015 0 : return NS_OK;
1016 : }
1017 :
1018 : NS_IMETHODIMP
1019 0 : nsXULTreeGridCellAccessible::GetColumnIndex(PRInt32 *aColumnIndex)
1020 : {
1021 0 : NS_ENSURE_ARG_POINTER(aColumnIndex);
1022 0 : *aColumnIndex = -1;
1023 :
1024 0 : if (IsDefunct())
1025 0 : return NS_ERROR_FAILURE;
1026 :
1027 0 : *aColumnIndex = GetColumnIndex();
1028 0 : return NS_OK;
1029 : }
1030 :
1031 : NS_IMETHODIMP
1032 0 : nsXULTreeGridCellAccessible::GetRowIndex(PRInt32 *aRowIndex)
1033 : {
1034 0 : NS_ENSURE_ARG_POINTER(aRowIndex);
1035 0 : *aRowIndex = -1;
1036 :
1037 0 : if (IsDefunct())
1038 0 : return NS_ERROR_FAILURE;
1039 :
1040 0 : *aRowIndex = mRow;
1041 0 : return NS_OK;
1042 : }
1043 :
1044 : NS_IMETHODIMP
1045 0 : nsXULTreeGridCellAccessible::GetColumnExtent(PRInt32 *aExtentCount)
1046 : {
1047 0 : NS_ENSURE_ARG_POINTER(aExtentCount);
1048 0 : *aExtentCount = 1;
1049 :
1050 0 : return NS_OK;
1051 : }
1052 :
1053 : NS_IMETHODIMP
1054 0 : nsXULTreeGridCellAccessible::GetRowExtent(PRInt32 *aExtentCount)
1055 : {
1056 0 : NS_ENSURE_ARG_POINTER(aExtentCount);
1057 0 : *aExtentCount = 1;
1058 :
1059 0 : return NS_OK;
1060 : }
1061 :
1062 : NS_IMETHODIMP
1063 0 : nsXULTreeGridCellAccessible::GetColumnHeaderCells(nsIArray **aHeaderCells)
1064 : {
1065 0 : NS_ENSURE_ARG_POINTER(aHeaderCells);
1066 0 : *aHeaderCells = nsnull;
1067 :
1068 0 : if (IsDefunct() || !mDoc)
1069 0 : return NS_ERROR_FAILURE;
1070 :
1071 0 : nsresult rv = NS_OK;
1072 : nsCOMPtr<nsIMutableArray> headerCells =
1073 0 : do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
1074 0 : NS_ENSURE_SUCCESS(rv, rv);
1075 :
1076 0 : nsCOMPtr<nsIDOMElement> columnElm;
1077 0 : mColumn->GetElement(getter_AddRefs(columnElm));
1078 :
1079 0 : nsCOMPtr<nsIContent> columnContent(do_QueryInterface(columnElm));
1080 0 : nsAccessible *headerCell = mDoc->GetAccessible(columnContent);
1081 :
1082 0 : if (headerCell)
1083 0 : headerCells->AppendElement(static_cast<nsIAccessible*>(headerCell),
1084 0 : false);
1085 :
1086 0 : NS_ADDREF(*aHeaderCells = headerCells);
1087 0 : return NS_OK;
1088 : }
1089 :
1090 : NS_IMETHODIMP
1091 0 : nsXULTreeGridCellAccessible::GetRowHeaderCells(nsIArray **aHeaderCells)
1092 : {
1093 0 : NS_ENSURE_ARG_POINTER(aHeaderCells);
1094 0 : *aHeaderCells = nsnull;
1095 :
1096 0 : if (IsDefunct())
1097 0 : return NS_ERROR_FAILURE;
1098 :
1099 0 : nsresult rv = NS_OK;
1100 : nsCOMPtr<nsIMutableArray> headerCells =
1101 0 : do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
1102 0 : NS_ENSURE_SUCCESS(rv, rv);
1103 :
1104 0 : NS_ADDREF(*aHeaderCells = headerCells);
1105 0 : return NS_OK;
1106 : }
1107 :
1108 : NS_IMETHODIMP
1109 0 : nsXULTreeGridCellAccessible::IsSelected(bool *aIsSelected)
1110 : {
1111 0 : NS_ENSURE_ARG_POINTER(aIsSelected);
1112 0 : *aIsSelected = false;
1113 :
1114 0 : if (IsDefunct())
1115 0 : return NS_ERROR_FAILURE;
1116 :
1117 0 : nsCOMPtr<nsITreeSelection> selection;
1118 0 : nsresult rv = mTreeView->GetSelection(getter_AddRefs(selection));
1119 0 : NS_ENSURE_SUCCESS(rv, rv);
1120 :
1121 0 : return selection->IsSelected(mRow, aIsSelected);
1122 : }
1123 :
1124 : ////////////////////////////////////////////////////////////////////////////////
1125 : // nsXULTreeGridCellAccessible: nsAccessNode implementation
1126 :
1127 : bool
1128 0 : nsXULTreeGridCellAccessible::IsDefunct() const
1129 : {
1130 0 : return nsLeafAccessible::IsDefunct() || !mParent || !mTree || !mTreeView ||
1131 0 : !mColumn;
1132 : }
1133 :
1134 : bool
1135 0 : nsXULTreeGridCellAccessible::Init()
1136 : {
1137 0 : if (!nsLeafAccessible::Init())
1138 0 : return false;
1139 :
1140 : PRInt16 type;
1141 0 : mColumn->GetType(&type);
1142 0 : if (type == nsITreeColumn::TYPE_CHECKBOX)
1143 0 : mTreeView->GetCellValue(mRow, mColumn, mCachedTextEquiv);
1144 : else
1145 0 : mTreeView->GetCellText(mRow, mColumn, mCachedTextEquiv);
1146 :
1147 0 : return true;
1148 : }
1149 :
1150 : bool
1151 0 : nsXULTreeGridCellAccessible::IsPrimaryForNode() const
1152 : {
1153 0 : return false;
1154 : }
1155 :
1156 : ////////////////////////////////////////////////////////////////////////////////
1157 : // nsXULTreeGridCellAccessible: nsAccessible public implementation
1158 :
1159 : nsresult
1160 0 : nsXULTreeGridCellAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
1161 : {
1162 0 : NS_ENSURE_ARG_POINTER(aAttributes);
1163 :
1164 0 : if (IsDefunct())
1165 0 : return NS_ERROR_FAILURE;
1166 :
1167 : // "table-cell-index" attribute
1168 0 : nsAccessible* grandParent = mParent->Parent();
1169 0 : if (!grandParent)
1170 0 : return NS_OK;
1171 :
1172 0 : nsCOMPtr<nsIAccessibleTable> tableAccessible = do_QueryObject(grandParent);
1173 :
1174 : // XXX - temp fix for crash bug 516047
1175 0 : if (!tableAccessible)
1176 0 : return NS_ERROR_FAILURE;
1177 :
1178 0 : PRInt32 colIdx = GetColumnIndex();
1179 :
1180 0 : PRInt32 cellIdx = -1;
1181 0 : tableAccessible->GetCellIndexAt(mRow, colIdx, &cellIdx);
1182 :
1183 0 : nsAutoString stringIdx;
1184 0 : stringIdx.AppendInt(cellIdx);
1185 : nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::tableCellIndex,
1186 0 : stringIdx);
1187 :
1188 : // "cycles" attribute
1189 0 : bool isCycler = false;
1190 0 : nsresult rv = mColumn->GetCycler(&isCycler);
1191 0 : if (NS_SUCCEEDED(rv) && isCycler)
1192 : nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::cycles,
1193 0 : NS_LITERAL_STRING("true"));
1194 :
1195 0 : return NS_OK;
1196 : }
1197 :
1198 : role
1199 0 : nsXULTreeGridCellAccessible::NativeRole()
1200 : {
1201 0 : return roles::GRID_CELL;
1202 : }
1203 :
1204 : PRUint64
1205 0 : nsXULTreeGridCellAccessible::NativeState()
1206 : {
1207 : // selectable/selected state
1208 0 : PRUint64 states = states::SELECTABLE;
1209 :
1210 0 : nsCOMPtr<nsITreeSelection> selection;
1211 0 : mTreeView->GetSelection(getter_AddRefs(selection));
1212 0 : if (selection) {
1213 0 : bool isSelected = false;
1214 0 : selection->IsSelected(mRow, &isSelected);
1215 0 : if (isSelected)
1216 0 : states |= states::SELECTED;
1217 : }
1218 :
1219 : // checked state
1220 : PRInt16 type;
1221 0 : mColumn->GetType(&type);
1222 0 : if (type == nsITreeColumn::TYPE_CHECKBOX) {
1223 0 : states |= states::CHECKABLE;
1224 0 : nsAutoString checked;
1225 0 : mTreeView->GetCellValue(mRow, mColumn, checked);
1226 0 : if (checked.EqualsIgnoreCase("true"))
1227 0 : states |= states::CHECKED;
1228 : }
1229 :
1230 0 : return states;
1231 : }
1232 :
1233 : PRInt32
1234 0 : nsXULTreeGridCellAccessible::IndexInParent() const
1235 : {
1236 0 : return GetColumnIndex();
1237 : }
1238 :
1239 : Relation
1240 0 : nsXULTreeGridCellAccessible::RelationByType(PRUint32 aType)
1241 : {
1242 0 : return Relation();
1243 : }
1244 :
1245 : ////////////////////////////////////////////////////////////////////////////////
1246 : // nsXULTreeGridCellAccessible: public implementation
1247 :
1248 : PRInt32
1249 0 : nsXULTreeGridCellAccessible::GetColumnIndex() const
1250 : {
1251 0 : PRInt32 index = 0;
1252 0 : nsCOMPtr<nsITreeColumn> column = mColumn;
1253 0 : while (true) {
1254 0 : column = nsCoreUtils::GetPreviousSensibleColumn(column);
1255 0 : if (!column)
1256 : break;
1257 0 : index++;
1258 : }
1259 :
1260 0 : return index;
1261 : }
1262 :
1263 : void
1264 0 : nsXULTreeGridCellAccessible::CellInvalidated()
1265 : {
1266 0 : nsAutoString textEquiv;
1267 :
1268 : PRInt16 type;
1269 0 : mColumn->GetType(&type);
1270 0 : if (type == nsITreeColumn::TYPE_CHECKBOX) {
1271 0 : mTreeView->GetCellValue(mRow, mColumn, textEquiv);
1272 0 : if (mCachedTextEquiv != textEquiv) {
1273 0 : bool isEnabled = textEquiv.EqualsLiteral("true");
1274 : nsRefPtr<AccEvent> accEvent =
1275 0 : new AccStateChangeEvent(this, states::CHECKED, isEnabled);
1276 0 : nsEventShell::FireEvent(accEvent);
1277 :
1278 0 : mCachedTextEquiv = textEquiv;
1279 : }
1280 :
1281 : return;
1282 : }
1283 :
1284 0 : mTreeView->GetCellText(mRow, mColumn, textEquiv);
1285 0 : if (mCachedTextEquiv != textEquiv) {
1286 0 : nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, this);
1287 0 : mCachedTextEquiv = textEquiv;
1288 : }
1289 : }
1290 :
1291 : ////////////////////////////////////////////////////////////////////////////////
1292 : // nsXULTreeGridCellAccessible: nsAccessible protected implementation
1293 :
1294 : nsAccessible*
1295 0 : nsXULTreeGridCellAccessible::GetSiblingAtOffset(PRInt32 aOffset,
1296 : nsresult* aError) const
1297 : {
1298 0 : if (aError)
1299 0 : *aError = NS_OK; // fail peacefully
1300 :
1301 0 : nsCOMPtr<nsITreeColumn> columnAtOffset(mColumn), column;
1302 0 : if (aOffset < 0) {
1303 0 : for (PRInt32 index = aOffset; index < 0 && columnAtOffset; index++) {
1304 0 : column = nsCoreUtils::GetPreviousSensibleColumn(columnAtOffset);
1305 0 : column.swap(columnAtOffset);
1306 : }
1307 : } else {
1308 0 : for (PRInt32 index = aOffset; index > 0 && columnAtOffset; index--) {
1309 0 : column = nsCoreUtils::GetNextSensibleColumn(columnAtOffset);
1310 0 : column.swap(columnAtOffset);
1311 : }
1312 : }
1313 :
1314 0 : if (!columnAtOffset)
1315 0 : return nsnull;
1316 :
1317 0 : nsRefPtr<nsXULTreeItemAccessibleBase> rowAcc = do_QueryObject(Parent());
1318 0 : return rowAcc->GetCellAccessible(columnAtOffset);
1319 : }
1320 :
1321 : void
1322 0 : nsXULTreeGridCellAccessible::DispatchClickEvent(nsIContent *aContent,
1323 : PRUint32 aActionIndex)
1324 : {
1325 0 : if (IsDefunct())
1326 0 : return;
1327 :
1328 0 : nsCoreUtils::DispatchClickEvent(mTree, mRow, mColumn);
1329 : }
1330 :
1331 : ////////////////////////////////////////////////////////////////////////////////
1332 : // nsXULTreeGridCellAccessible: protected implementation
1333 :
1334 : bool
1335 0 : nsXULTreeGridCellAccessible::IsEditable() const
1336 : {
1337 : // XXX: logic corresponds to tree.xml, it's preferable to have interface
1338 : // method to check it.
1339 0 : bool isEditable = false;
1340 0 : nsresult rv = mTreeView->IsEditable(mRow, mColumn, &isEditable);
1341 0 : if (NS_FAILED(rv) || !isEditable)
1342 0 : return false;
1343 :
1344 0 : nsCOMPtr<nsIDOMElement> columnElm;
1345 0 : mColumn->GetElement(getter_AddRefs(columnElm));
1346 0 : if (!columnElm)
1347 0 : return false;
1348 :
1349 0 : nsCOMPtr<nsIContent> columnContent(do_QueryInterface(columnElm));
1350 0 : if (!columnContent->AttrValueIs(kNameSpaceID_None,
1351 : nsGkAtoms::editable,
1352 : nsGkAtoms::_true,
1353 0 : eCaseMatters))
1354 0 : return false;
1355 :
1356 0 : return mContent->AttrValueIs(kNameSpaceID_None,
1357 : nsGkAtoms::editable,
1358 0 : nsGkAtoms::_true, eCaseMatters);
1359 4392 : }
|