Back to index

lightning-sunbird  0.9+nobinonly
nsXULTreeAccessibleWrap.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: NPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public
00006  * License Version 1.1 (the "License"); you may not use this file
00007  * except in compliance with the License. You may obtain a copy of
00008  * the License at http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS
00011  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
00012  * implied. See the License for the specific language governing
00013  * rights and limitations under the License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is Sun Microsystems, Inc.
00018  * Portions created by Sun Microsystems are Copyright (C) 2002 Sun
00019  * Microsystems, Inc. All Rights Reserved.
00020  *
00021  * Original Author: Pete Zha (pete.zha@sun.com)
00022  *
00023  * Contributor(s):
00024  *   Kyle Yuan (kyle.yuan@sun.com)
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either the GNU General Public License Version 2 or later (the "GPL"), or
00028  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the NPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the NPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include "nsIDOMElement.h"
00041 #include "nsITreeSelection.h"
00042 #include "nsITreeColumns.h"
00043 #include "nsXULTreeAccessibleWrap.h"
00044 
00045 // --------------------------------------------------------
00046 // nsXULTreeAccessibleWrap Accessible
00047 // --------------------------------------------------------
00048 NS_IMPL_ISUPPORTS_INHERITED1(nsXULTreeAccessibleWrap, nsXULTreeAccessible, nsIAccessibleTable)
00049 
00050 nsXULTreeAccessibleWrap::nsXULTreeAccessibleWrap(nsIDOMNode *aDOMNode, nsIWeakReference *aShell):
00051 nsXULTreeAccessible(aDOMNode, aShell)
00052 {
00053   mCaption = nsnull;
00054 }
00055 
00056 // tree's children count is row count * col count + treecols count
00057 // override "children count = row count + treecols count" defined in
00058 // nsXULTreeAccessible
00059 NS_IMETHODIMP nsXULTreeAccessibleWrap::GetChildCount(PRInt32 *aAccChildCount)
00060 {
00061   NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
00062 
00063   // get treecols count, which is cached by nsAccessibleTreeWalker
00064   // by going through DOM structure of XUL tree
00065   nsAccessible::GetChildCount(aAccChildCount);
00066 
00067   // add the count of table cell (or tree item) accessibles, which are
00068   // created and appended by XUL tree accessible implementation
00069   PRInt32 rowCount, colCount = 1;
00070   mTreeView->GetRowCount(&rowCount);
00071   GetColumnCount(mTree, &colCount);
00072   *aAccChildCount += rowCount * colCount;
00073 
00074   return NS_OK;
00075 }
00076 
00077 NS_IMETHODIMP nsXULTreeAccessibleWrap::GetCaption(nsIAccessible **aCaption)
00078 {
00079   *aCaption = mCaption;
00080   NS_IF_ADDREF(*aCaption);
00081   return NS_OK;
00082 }
00083 
00084 NS_IMETHODIMP nsXULTreeAccessibleWrap::SetCaption(nsIAccessible *aCaption)
00085 {
00086   mCaption = aCaption;
00087   return NS_OK;
00088 }
00089 
00090 NS_IMETHODIMP nsXULTreeAccessibleWrap::GetSummary(nsAString &aSummary)
00091 {
00092   aSummary = mSummary;
00093   return NS_OK;
00094 }
00095 
00096 NS_IMETHODIMP nsXULTreeAccessibleWrap::SetSummary(const nsAString &aSummary)
00097 {
00098   mSummary = aSummary;
00099   return NS_OK;
00100 }
00101 
00102 NS_IMETHODIMP nsXULTreeAccessibleWrap::GetColumns(PRInt32 *aColumns)
00103 {
00104   nsresult rv = NS_OK;
00105 
00106   nsCOMPtr<nsIAccessible> acc;
00107   rv = nsAccessible::GetFirstChild(getter_AddRefs(acc));
00108   NS_ENSURE_TRUE(acc, NS_ERROR_FAILURE);
00109 
00110   return acc->GetChildCount(aColumns);
00111 }
00112 
00113 NS_IMETHODIMP nsXULTreeAccessibleWrap::GetColumnHeader(nsIAccessibleTable **aColumnHeader)
00114 {
00115   nsresult rv = NS_OK;
00116 
00117   nsCOMPtr<nsIAccessible> acc;
00118   nsAccessible::GetFirstChild(getter_AddRefs(acc));
00119   NS_ENSURE_TRUE(acc, NS_ERROR_FAILURE);
00120 
00121   nsCOMPtr<nsIAccessibleTable> accTable(do_QueryInterface(acc, &rv));
00122   NS_ENSURE_SUCCESS(rv, rv);
00123 
00124   *aColumnHeader = accTable;
00125   NS_IF_ADDREF(*aColumnHeader);
00126 
00127   return rv;
00128 }
00129 
00130 NS_IMETHODIMP nsXULTreeAccessibleWrap::GetRows(PRInt32 *aRows)
00131 {
00132   NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
00133 
00134   return mTreeView->GetRowCount(aRows);
00135 }
00136 
00137 NS_IMETHODIMP nsXULTreeAccessibleWrap::GetRowHeader(nsIAccessibleTable **aRowHeader)
00138 {
00139   // Row header not supported
00140   return NS_ERROR_NOT_IMPLEMENTED;
00141 }
00142 
00143 NS_IMETHODIMP nsXULTreeAccessibleWrap::GetSelectedColumns(PRUint32 *aNumColumns, PRInt32 **aColumns)
00144 {
00145   // If all the row has been selected, then all the columns are selected.
00146   // Because we can't select a column alone.
00147   NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
00148   NS_ENSURE_ARG_POINTER(aNumColumns);
00149 
00150   nsresult rv = NS_OK;
00151 
00152   PRInt32 rows;
00153   rv = GetRows(&rows);
00154   NS_ENSURE_SUCCESS(rv, rv);
00155 
00156   PRInt32 selectedRows;
00157   rv = GetSelectionCount(&selectedRows);
00158   NS_ENSURE_SUCCESS(rv, rv);
00159 
00160   if (rows == selectedRows) {
00161     PRInt32 columns;
00162     rv = GetColumns(&columns);
00163     NS_ENSURE_SUCCESS(rv, rv);
00164 
00165     *aNumColumns = columns;
00166   } else {
00167     *aNumColumns = 0;
00168     return rv;
00169   }
00170 
00171   PRInt32 *outArray = (PRInt32 *)nsMemory::Alloc((*aNumColumns) * sizeof(PRInt32));
00172   NS_ENSURE_TRUE(outArray, NS_ERROR_OUT_OF_MEMORY);
00173 
00174   for (PRUint32 index = 0; index < *aNumColumns; index++) {
00175     outArray[index] = index;
00176   }
00177 
00178   *aColumns = outArray;
00179   return rv;
00180 }
00181 
00182 NS_IMETHODIMP nsXULTreeAccessibleWrap::GetSelectedRows(PRUint32 *aNumRows, PRInt32 **aRows)
00183 {
00184   NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
00185   NS_ENSURE_ARG_POINTER(aNumRows);
00186 
00187   nsresult rv = NS_OK;
00188 
00189   rv = GetSelectionCount((PRInt32 *)aNumRows);
00190   NS_ENSURE_SUCCESS(rv, rv);
00191 
00192   PRInt32 *outArray = (PRInt32 *)nsMemory::Alloc((*aNumRows) * sizeof(PRInt32));
00193   NS_ENSURE_TRUE(outArray, NS_ERROR_OUT_OF_MEMORY);
00194 
00195   nsCOMPtr<nsITreeView> view;
00196   rv = mTree->GetView(getter_AddRefs(view));
00197   NS_ENSURE_SUCCESS(rv, rv);
00198 
00199   nsCOMPtr<nsITreeSelection> selection;
00200   rv = view->GetSelection(getter_AddRefs(selection));
00201   NS_ENSURE_SUCCESS(rv, rv);
00202 
00203   PRInt32 rowCount;
00204   rv = GetRows(&rowCount);
00205   NS_ENSURE_SUCCESS(rv, rv);
00206 
00207   PRBool isSelected;
00208   PRInt32 index, curr = 0;
00209   for (index = 0; index < rowCount; index++) {
00210     selection->IsSelected(index, &isSelected);
00211     if (isSelected) {
00212       outArray[curr++] = index;
00213     }
00214   }
00215 
00216   *aRows = outArray;
00217   return rv;
00218 }
00219 
00220 NS_IMETHODIMP nsXULTreeAccessibleWrap::CellRefAt(PRInt32 aRow, PRInt32 aColumn, nsIAccessible **aAccessibleCell)
00221 {
00222   NS_ENSURE_TRUE(mDOMNode && mTree, NS_ERROR_FAILURE);
00223 
00224   nsresult rv = NS_OK;
00225 
00226   PRInt32 index;
00227   rv = GetIndexAt(aRow, aColumn, &index);
00228   NS_ENSURE_SUCCESS(rv, rv);
00229 
00230   return GetChildAt(index, aAccessibleCell);
00231 }
00232 
00233 NS_IMETHODIMP nsXULTreeAccessibleWrap::GetIndexAt(PRInt32 aRow, PRInt32 aColumn, PRInt32 *aIndex)
00234 {
00235   NS_ENSURE_TRUE(mDOMNode, NS_ERROR_FAILURE);
00236   NS_ENSURE_ARG_POINTER(aIndex);
00237 
00238   nsresult rv = NS_OK;
00239 
00240   PRInt32 columns;
00241   rv = GetColumns(&columns);
00242   NS_ENSURE_SUCCESS(rv, rv);
00243 
00244   PRInt32 treeCols;
00245   nsAccessible::GetChildCount(&treeCols);
00246   *aIndex = aRow * columns + aColumn + treeCols;
00247   return NS_OK;
00248 }
00249 
00250 NS_IMETHODIMP nsXULTreeAccessibleWrap::GetColumnAtIndex(PRInt32 aIndex, PRInt32 *_retval)
00251 {
00252   NS_ENSURE_ARG_POINTER(_retval);
00253 
00254   nsresult rv = NS_OK;
00255 
00256   PRInt32 columns;
00257   rv = GetColumns(&columns);
00258   NS_ENSURE_SUCCESS(rv, rv);
00259 
00260   PRInt32 treeCols;
00261   nsAccessible::GetChildCount(&treeCols);
00262 
00263   *_retval = (aIndex - treeCols) % columns;
00264   
00265   return NS_OK;
00266 }
00267 
00268 NS_IMETHODIMP nsXULTreeAccessibleWrap::GetRowAtIndex(PRInt32 aIndex, PRInt32 *_retval)
00269 {
00270   NS_ENSURE_ARG_POINTER(_retval);
00271 
00272   nsresult rv = NS_OK;
00273 
00274   PRInt32 columns;
00275   rv = GetColumns(&columns);
00276   NS_ENSURE_SUCCESS(rv, rv);
00277 
00278   PRInt32 treeCols;
00279   nsAccessible::GetChildCount(&treeCols);
00280 
00281   *_retval = (aIndex - treeCols) / columns;
00282 
00283   return NS_OK;
00284 }
00285 
00286 NS_IMETHODIMP nsXULTreeAccessibleWrap::GetColumnExtentAt(PRInt32 aRow, PRInt32 aColumn, PRInt32 *_retval)
00287 {
00288   NS_ENSURE_ARG_POINTER(_retval);
00289 
00290   *_retval = 1;
00291   return NS_OK;
00292 }
00293 
00294 NS_IMETHODIMP nsXULTreeAccessibleWrap::GetRowExtentAt(PRInt32 aRow, PRInt32 aColumn, PRInt32 *_retval)
00295 {
00296   NS_ENSURE_ARG_POINTER(_retval);
00297 
00298   *_retval = 1;
00299   return NS_OK;
00300 }
00301 
00302 NS_IMETHODIMP nsXULTreeAccessibleWrap::GetColumnDescription(PRInt32 aColumn, nsAString & _retval)
00303 {
00304   nsCOMPtr<nsIAccessibleTable> columnHeader;
00305   nsresult rv = GetColumnHeader(getter_AddRefs(columnHeader));
00306   if (NS_SUCCEEDED(rv) && columnHeader) {
00307     return columnHeader->GetColumnDescription(aColumn, _retval);
00308   }
00309   return NS_ERROR_FAILURE;
00310 }
00311 
00312 NS_IMETHODIMP nsXULTreeAccessibleWrap::GetRowDescription(PRInt32 aRow, nsAString & _retval)
00313 {
00314   return NS_ERROR_NOT_IMPLEMENTED;
00315 }
00316 
00317 NS_IMETHODIMP nsXULTreeAccessibleWrap::IsColumnSelected(PRInt32 aColumn, PRBool *_retval)
00318 {
00319   // If all the row has been selected, then all the columns are selected.
00320   // Because we can't select a column alone.
00321   NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
00322   NS_ENSURE_ARG_POINTER(_retval);
00323 
00324   nsresult rv = NS_OK;
00325 
00326   PRInt32 rows;
00327   rv = GetRows(&rows);
00328   NS_ENSURE_SUCCESS(rv, rv);
00329 
00330   PRInt32 selectedRows;
00331   rv = GetSelectionCount(&selectedRows);
00332   NS_ENSURE_SUCCESS(rv, rv);
00333 
00334   *_retval = rows == selectedRows;
00335   return rv;
00336 }
00337 
00338 NS_IMETHODIMP nsXULTreeAccessibleWrap::IsRowSelected(PRInt32 aRow, PRBool *_retval)
00339 {
00340   NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
00341 
00342   nsresult rv = NS_OK;
00343 
00344   nsCOMPtr<nsITreeView> view;
00345   rv = mTree->GetView(getter_AddRefs(view));
00346   NS_ENSURE_SUCCESS(rv, rv);
00347 
00348   nsCOMPtr<nsITreeSelection> selection;
00349   rv = view->GetSelection(getter_AddRefs(selection));
00350   NS_ENSURE_SUCCESS(rv, rv);
00351 
00352   return selection->IsSelected(aRow, _retval);
00353 }
00354 
00355 NS_IMETHODIMP nsXULTreeAccessibleWrap::IsCellSelected(PRInt32 aRow, PRInt32 aColumn, PRBool *_retval)
00356 {
00357   return IsRowSelected(aRow, _retval);
00358 }
00359 
00360 NS_IMETHODIMP nsXULTreeAccessibleWrap::ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState)
00361 {
00362   NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
00363 
00364   PRInt32 rowIndex;
00365   nsresult rv = GetRowAtIndex(aIndex, &rowIndex);
00366 
00367   nsCOMPtr<nsITreeSelection> selection;
00368   rv = mTreeView->GetSelection(getter_AddRefs(selection));
00369   NS_ASSERTION(selection, "Can't get selection from mTreeView");
00370 
00371   if (selection) {
00372     selection->IsSelected(rowIndex, aSelState);
00373     // XXX: Can move to nsXULTreeAccessible if this can be applied to cross-platform
00374     if ((!(*aSelState) && eSelection_Add == aMethod)) {
00375       nsresult rv = selection->Select(rowIndex);
00376       mTree->EnsureRowIsVisible(aIndex);
00377       return rv;
00378     }
00379     // XXX: Will eSelection_Remove happen for XULTree? Leave the original implementation here
00380     if ((*aSelState) && eSelection_Remove == aMethod) {
00381       return selection->ToggleSelect(rowIndex);
00382     }
00383   }
00384 
00385   return NS_OK;
00386 }
00387 
00388 // --------------------------------------------------------
00389 // nsXULTreeAccessibleWrap Accessible
00390 // --------------------------------------------------------
00391 NS_IMPL_ISUPPORTS_INHERITED1(nsXULTreeColumnsAccessibleWrap, nsXULTreeColumnsAccessible, nsIAccessibleTable)
00392 
00393 nsXULTreeColumnsAccessibleWrap::nsXULTreeColumnsAccessibleWrap(nsIDOMNode *aDOMNode, nsIWeakReference *aShell):
00394 nsXULTreeColumnsAccessible(aDOMNode, aShell)
00395 {
00396   mCaption = nsnull;
00397 }
00398 
00399 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetCaption(nsIAccessible **aCaption)
00400 {
00401   *aCaption = mCaption;
00402   NS_IF_ADDREF(*aCaption);
00403 
00404   return NS_OK;
00405 }
00406 
00407 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::SetCaption(nsIAccessible *aCaption)
00408 {
00409   mCaption = aCaption;
00410   return NS_OK;
00411 }
00412 
00413 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetSummary(nsAString &aSummary)
00414 {
00415   aSummary = mSummary;
00416   return NS_OK;
00417 }
00418 
00419 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::SetSummary(const nsAString &aSummary)
00420 {
00421   mSummary = aSummary;
00422   return NS_OK;
00423 }
00424 
00425 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetColumns(PRInt32 *aColumns)
00426 {
00427   return GetChildCount(aColumns);
00428 }
00429 
00430 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetColumnHeader(nsIAccessibleTable * *aColumnHeader)
00431 {
00432   // Column header not supported.
00433   return NS_ERROR_NOT_IMPLEMENTED;
00434 }
00435 
00436 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetRows(PRInt32 *aRows)
00437 {
00438   NS_ENSURE_ARG_POINTER(aRows);
00439 
00440   *aRows = 1;
00441   return NS_OK;
00442 }
00443 
00444 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetRowHeader(nsIAccessibleTable * *aRowHeader)
00445 {
00446   // Row header not supported.
00447   return NS_ERROR_NOT_IMPLEMENTED;
00448 }
00449 
00450 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetSelectedColumns(PRUint32 *columnsSize, PRInt32 **columns)
00451 {
00452   // Header can not be selected.
00453   return NS_ERROR_NOT_IMPLEMENTED;
00454 }
00455 
00456 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetSelectedRows(PRUint32 *rowsSize, PRInt32 **rows)
00457 {
00458   // Header can not be selected.
00459   return NS_ERROR_NOT_IMPLEMENTED;
00460 }
00461 
00462 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::CellRefAt(PRInt32 aRow, PRInt32 aColumn, nsIAccessible **_retval)
00463 {
00464   nsCOMPtr<nsIAccessible> next, temp;
00465   GetFirstChild(getter_AddRefs(next));
00466   NS_ENSURE_TRUE(next, NS_ERROR_FAILURE);
00467 
00468   for (PRInt32 col = 0; col < aColumn; col++) {
00469     next->GetNextSibling(getter_AddRefs(temp));
00470     NS_ENSURE_TRUE(temp, NS_ERROR_FAILURE);
00471 
00472     next = temp;
00473   }
00474 
00475   *_retval = next;
00476   NS_IF_ADDREF(*_retval);
00477 
00478   return NS_OK;
00479 }
00480 
00481 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetIndexAt(PRInt32 aRow, PRInt32 aColumn, PRInt32 *_retval)
00482 {
00483   NS_ENSURE_ARG_POINTER(_retval);
00484 
00485   *_retval = aColumn;
00486   return NS_OK;
00487 }
00488 
00489 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetColumnAtIndex(PRInt32 aIndex, PRInt32 *_retval)
00490 {
00491   NS_ENSURE_ARG_POINTER(_retval);
00492 
00493   *_retval = aIndex;
00494   return NS_OK;
00495 }
00496 
00497 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetRowAtIndex(PRInt32 aIndex, PRInt32 *_retval)
00498 {
00499   NS_ENSURE_ARG_POINTER(_retval);
00500 
00501   *_retval = 0;
00502   return NS_OK;
00503 }
00504 
00505 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetColumnExtentAt(PRInt32 aRow, PRInt32 aColumn, PRInt32 *_retval)
00506 {
00507   NS_ENSURE_ARG_POINTER(_retval);
00508 
00509   *_retval = 1;
00510   return NS_OK;
00511 }
00512 
00513 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetRowExtentAt(PRInt32 aRow, PRInt32 aColumn, PRInt32 *_retval)
00514 {
00515   NS_ENSURE_ARG_POINTER(_retval);
00516 
00517   *_retval = 1;
00518   return NS_OK;
00519 }
00520 
00521 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetColumnDescription(PRInt32 aColumn, nsAString & _retval)
00522 {
00523   nsCOMPtr<nsIAccessible> column;  
00524   nsresult rv = CellRefAt(0, aColumn, getter_AddRefs(column));
00525   if (NS_SUCCEEDED(rv) && column) {
00526     return column->GetName(_retval);
00527   }
00528   return NS_ERROR_FAILURE;
00529 }
00530 
00531 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetRowDescription(PRInt32 aRow, nsAString & _retval)
00532 {
00533   return NS_ERROR_NOT_IMPLEMENTED;
00534 }
00535 
00536 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::IsColumnSelected(PRInt32 aColumn, PRBool *_retval)
00537 {
00538   // Header can not be selected.
00539   return NS_ERROR_NOT_IMPLEMENTED;
00540 }
00541 
00542 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::IsRowSelected(PRInt32 aRow, PRBool *_retval)
00543 {
00544   // Header can not be selected.
00545   return NS_ERROR_NOT_IMPLEMENTED;
00546 }
00547 
00548 NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::IsCellSelected(PRInt32 aRow, PRInt32 aColumn, PRBool *_retval)
00549 {
00550   // Header can not be selected.
00551   return NS_ERROR_NOT_IMPLEMENTED;
00552 }