From 945c478b6e974f36af17c11ff53708c286698ea8 Mon Sep 17 00:00:00 2001 From: "surkov.alexander%gmail.com" Date: Tue, 19 Feb 2008 09:07:36 +0000 Subject: [PATCH] =?UTF-8?q?Bug=20365973=20=C3=A2=C2=80=C2=93=20cant=20expo?= =?UTF-8?q?se=20=20with=20multiple=20columns,=20r=3Devan.yan,=20a?= =?UTF-8?q?=3Dmtschrep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: svn://10.0.0.236/trunk@245956 18797224-902f-48f8-a5cc-f745e15eee43 --- .../public/nsIAccessibleProvider.idl | 3 +- .../src/base/nsAccessibilityAtomList.h | 2 + .../src/base/nsAccessibilityService.cpp | 3 + .../src/base/nsAccessibilityService.h | 6 +- .../src/xul/nsXULSelectAccessible.cpp | 435 +++++++++++++++++- .../src/xul/nsXULSelectAccessible.h | 33 +- mozilla/toolkit/content/widgets/listbox.xml | 32 ++ 7 files changed, 493 insertions(+), 21 deletions(-) diff --git a/mozilla/accessible/public/nsIAccessibleProvider.idl b/mozilla/accessible/public/nsIAccessibleProvider.idl index 3f7b22774b1..749009712a2 100644 --- a/mozilla/accessible/public/nsIAccessibleProvider.idl +++ b/mozilla/accessible/public/nsIAccessibleProvider.idl @@ -77,9 +77,10 @@ interface nsIAccessibleProvider : nsISupports const long XULImage = 0x00001009; const long XULLink = 0x0000100A; const long XULListbox = 0x0000100B; - const long XULListitem = 0x0000100C; + const long XULListCell = 0x00001026; const long XULListHead = 0x00001024; const long XULListHeader = 0x00001025; + const long XULListitem = 0x0000100C; const long XULMenubar = 0x0000100D; const long XULMenuitem = 0x0000100E; const long XULMenupopup = 0x0000100F; diff --git a/mozilla/accessible/src/base/nsAccessibilityAtomList.h b/mozilla/accessible/src/base/nsAccessibilityAtomList.h index b942a0cf8b5..85d436067c1 100755 --- a/mozilla/accessible/src/base/nsAccessibilityAtomList.h +++ b/mozilla/accessible/src/base/nsAccessibilityAtomList.h @@ -116,6 +116,8 @@ ACCESSIBILITY_ATOM(label, "label") ACCESSIBILITY_ATOM(legend, "legend") ACCESSIBILITY_ATOM(li, "li") ACCESSIBILITY_ATOM(link, "link") +ACCESSIBILITY_ATOM(listhead, "listhead") // XUL +ACCESSIBILITY_ATOM(listheader, "listheader") // XUL ACCESSIBILITY_ATOM(map, "map") ACCESSIBILITY_ATOM(math, "math") ACCESSIBILITY_ATOM(menu, "menu") // XUL diff --git a/mozilla/accessible/src/base/nsAccessibilityService.cpp b/mozilla/accessible/src/base/nsAccessibilityService.cpp index ea16e4120dc..4ba2a7dcff6 100644 --- a/mozilla/accessible/src/base/nsAccessibilityService.cpp +++ b/mozilla/accessible/src/base/nsAccessibilityService.cpp @@ -1698,6 +1698,9 @@ nsresult nsAccessibilityService::GetAccessibleByType(nsIDOMNode *aNode, case nsIAccessibleProvider::XULListbox: *aAccessible = new nsXULListboxAccessible(aNode, weakShell); break; + case nsIAccessibleProvider::XULListCell: + *aAccessible = new nsXULListCellAccessible(aNode, weakShell); + break; case nsIAccessibleProvider::XULListHead: *aAccessible = new nsXULColumnsAccessible(aNode, weakShell); break; diff --git a/mozilla/accessible/src/base/nsAccessibilityService.h b/mozilla/accessible/src/base/nsAccessibilityService.h index 1de8f0dfe70..b2000c92369 100644 --- a/mozilla/accessible/src/base/nsAccessibilityService.h +++ b/mozilla/accessible/src/base/nsAccessibilityService.h @@ -258,7 +258,11 @@ static const char kRoleNames[][20] = { "calendar", //ROLE_CALENDAR "combobox list", //ROLE_COMBOBOX_LIST "combobox option", //ROLE_COMBOBOX_OPTION - "image map" //ROLE_IMAGE_MAP + "image map", //ROLE_IMAGE_MAP + "listbox option", //ROLE_OPTION + "listbox rich option", //ROLE_RICH_OPTION + "listbox" //ROLE_LISTBOX + }; /** diff --git a/mozilla/accessible/src/xul/nsXULSelectAccessible.cpp b/mozilla/accessible/src/xul/nsXULSelectAccessible.cpp index 76ea5b58a24..565f2c6901d 100644 --- a/mozilla/accessible/src/xul/nsXULSelectAccessible.cpp +++ b/mozilla/accessible/src/xul/nsXULSelectAccessible.cpp @@ -144,21 +144,53 @@ nsXULColumnItemAccessible::DoAction(PRUint8 aIndex) //////////////////////////////////////////////////////////////////////////////// // nsXULListboxAccessible -/** Constructor */ -nsXULListboxAccessible::nsXULListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell): -nsXULSelectableAccessible(aDOMNode, aShell) +nsXULListboxAccessible:: + nsXULListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell) : + nsXULSelectableAccessible(aDOMNode, aShell) { } -/** - * As a nsXULListboxAccessible we can have the following states: - * nsIAccessibleStates::STATE_FOCUSED - * nsIAccessibleStates::STATE_READONLY - * nsIAccessibleStates::STATE_FOCUSABLE - */ +NS_IMPL_ADDREF_INHERITED(nsXULListboxAccessible, nsXULSelectableAccessible) +NS_IMPL_RELEASE_INHERITED(nsXULListboxAccessible, nsXULSelectableAccessible) + +nsresult +nsXULListboxAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + nsresult rv = nsXULSelectableAccessible::QueryInterface(aIID, aInstancePtr); + if (*aInstancePtr) + return rv; + + if (aIID.Equals(NS_GET_IID(nsIAccessibleTable)) && IsTree()) { + *aInstancePtr = static_cast(this); + NS_ADDREF_THIS(); + return NS_OK; + } + + return NS_ERROR_NO_INTERFACE; +} + +PRBool +nsXULListboxAccessible::IsTree() +{ + PRInt32 numColumns = 0; + nsresult rv = GetColumns(&numColumns); + if (NS_FAILED(rv)) + return PR_FALSE; + + return numColumns > 1; +} + +//////////////////////////////////////////////////////////////////////////////// +// nsXULListboxAccessible. nsIAccessible + NS_IMETHODIMP nsXULListboxAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState) { + // As a nsXULListboxAccessible we can have the following states: + // STATE_FOCUSED + // STATE_READONLY + // STATE_FOCUSABLE + // Get focus status from base class nsresult rv = nsAccessible::GetState(aState, aExtraState); NS_ENSURE_SUCCESS(rv, rv); @@ -208,15 +240,343 @@ NS_IMETHODIMP nsXULListboxAccessible::GetRole(PRUint32 *aRole) return NS_OK; } } - *aRole = nsIAccessibleRole::ROLE_LIST; + + if (IsTree()) + *aRole = nsIAccessibleRole::ROLE_TABLE; + else + *aRole = nsIAccessibleRole::ROLE_LISTBOX; + return NS_OK; } -/** ----- nsXULListitemAccessible ----- */ +//////////////////////////////////////////////////////////////////////////////// +// nsXULListboxAccessible. nsIAccessibleTable -/** Constructor */ -nsXULListitemAccessible::nsXULListitemAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell): -nsXULMenuitemAccessible(aDOMNode, aShell) +NS_IMETHODIMP +nsXULListboxAccessible::GetCaption(nsIAccessible **aCaption) +{ + NS_ENSURE_ARG_POINTER(aCaption); + *aCaption = nsnull; + + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXULListboxAccessible::GetSummary(nsAString &aSummary) +{ + aSummary.Truncate(); + + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXULListboxAccessible::GetColumns(PRInt32 *aNumColumns) +{ + NS_ENSURE_ARG_POINTER(aNumColumns); + *aNumColumns = 0; + + if (!mDOMNode) + return NS_ERROR_FAILURE; + + nsCOMPtr content(do_QueryInterface(mDOMNode)); + + nsCOMPtr headContent; + PRUint32 count = content->GetChildCount(); + + for (PRUint32 index = 0; index < count; ++index) { + nsCOMPtr childContent(content->GetChildAt(index)); + NS_ENSURE_STATE(childContent); + + if (childContent->NodeInfo()->Equals(nsAccessibilityAtoms::listhead, + kNameSpaceID_XUL)) { + headContent = childContent; + } + } + + if (!headContent) + return NS_OK; + + PRUint32 columnCount = 0; + count = headContent->GetChildCount(); + + for (PRUint32 index = 0; index < count; ++index) { + nsCOMPtr childContent(headContent->GetChildAt(index)); + NS_ENSURE_STATE(childContent); + + if (childContent->NodeInfo()->Equals(nsAccessibilityAtoms::listheader, + kNameSpaceID_XUL)) { + columnCount++; + } + } + + *aNumColumns = columnCount; + return NS_OK; +} + +NS_IMETHODIMP +nsXULListboxAccessible::GetColumnHeader(nsIAccessibleTable **aColumnHeader) +{ + NS_ENSURE_ARG_POINTER(aColumnHeader); + *aColumnHeader = nsnull; + + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXULListboxAccessible::GetRows(PRInt32 *aNumRows) +{ + NS_ENSURE_ARG_POINTER(aNumRows); + *aNumRows = 0; + + if (!mDOMNode) + return NS_ERROR_FAILURE; + + nsCOMPtr element(do_QueryInterface(mDOMNode)); + NS_ENSURE_STATE(element); + + PRUint32 itemCount = 0; + nsresult rv = element->GetItemCount(&itemCount); + NS_ENSURE_SUCCESS(rv, rv); + + *aNumRows = itemCount; + return NS_OK; +} + +NS_IMETHODIMP +nsXULListboxAccessible::GetRowHeader(nsIAccessibleTable **aRowHeader) +{ + NS_ENSURE_ARG_POINTER(aRowHeader); + *aRowHeader = nsnull; + + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXULListboxAccessible::CellRefAt(PRInt32 aRow, PRInt32 aColumn, + nsIAccessible **aAccessibleCell) +{ + NS_ENSURE_ARG_POINTER(aAccessibleCell); + *aAccessibleCell = nsnull; + + if (IsDefunct()) + return NS_OK; + + nsCOMPtr control = + do_QueryInterface(mDOMNode); + + nsCOMPtr item; + control->GetItemAtIndex(aRow, getter_AddRefs(item)); + NS_ENSURE_TRUE(item, NS_ERROR_INVALID_ARG); + + nsCOMPtr accessibleRow; + GetAccService()->GetAccessibleInWeakShell(item, mWeakShell, + getter_AddRefs(accessibleRow)); + NS_ENSURE_STATE(accessibleRow); + + nsresult rv = accessibleRow->GetChildAt(aColumn, aAccessibleCell); + NS_ENSURE_SUCCESS(rv, NS_ERROR_INVALID_ARG); + + return NS_OK; +} + +NS_IMETHODIMP +nsXULListboxAccessible::GetIndexAt(PRInt32 aRow, PRInt32 aColumn, + PRInt32 *aIndex) +{ + NS_ENSURE_ARG_POINTER(aIndex); + *aIndex = -1; + + PRInt32 rowCount = 0; + nsresult rv = GetRows(&rowCount); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(0 <= aRow && aRow <= rowCount, NS_ERROR_INVALID_ARG); + + PRInt32 columnCount = 0; + rv = GetColumns(&columnCount); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(0 <= aColumn && aColumn <= columnCount, NS_ERROR_INVALID_ARG); + + *aIndex = aRow * columnCount + aColumn; + return NS_OK; +} + +NS_IMETHODIMP +nsXULListboxAccessible::GetColumnAtIndex(PRInt32 aIndex, PRInt32 *aColumn) +{ + NS_ENSURE_ARG_POINTER(aColumn); + *aColumn = -1; + + PRInt32 columnCount = 0; + nsresult rv = GetColumns(&columnCount); + NS_ENSURE_SUCCESS(rv, rv); + + *aColumn = aIndex % columnCount; + return NS_OK; +} + +NS_IMETHODIMP +nsXULListboxAccessible::GetRowAtIndex(PRInt32 aIndex, PRInt32 *aRow) +{ + NS_ENSURE_ARG_POINTER(aRow); + *aRow = -1; + + PRInt32 columnCount = 0; + nsresult rv = GetColumns(&columnCount); + NS_ENSURE_SUCCESS(rv, rv); + + *aRow = aIndex / columnCount; + return NS_OK; +} + +NS_IMETHODIMP +nsXULListboxAccessible::GetColumnExtentAt(PRInt32 aRow, PRInt32 aColumn, + PRInt32 *aCellSpans) +{ + NS_ENSURE_ARG_POINTER(aCellSpans); + *aCellSpans = 1; + + return NS_OK; +} + +NS_IMETHODIMP +nsXULListboxAccessible::GetRowExtentAt(PRInt32 aRow, PRInt32 aColumn, + PRInt32 *aCellSpans) +{ + NS_ENSURE_ARG_POINTER(aCellSpans); + *aCellSpans = 1; + + return NS_OK; +} + +NS_IMETHODIMP +nsXULListboxAccessible::GetColumnDescription(PRInt32 aColumn, + nsAString& aDescription) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXULListboxAccessible::GetRowDescription(PRInt32 aRow, nsAString& aDescription) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXULListboxAccessible::IsColumnSelected(PRInt32 aColumn, PRBool *aIsSelected) +{ + NS_ENSURE_ARG_POINTER(aIsSelected); + + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXULListboxAccessible::IsRowSelected(PRInt32 aRow, PRBool *aIsSelected) +{ + NS_ENSURE_ARG_POINTER(aIsSelected); + + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXULListboxAccessible::IsCellSelected(PRInt32 aRow, PRInt32 aColumn, + PRBool *aIsSelected) +{ + NS_ENSURE_ARG_POINTER(aIsSelected); + + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXULListboxAccessible::GetSelectedCellsCount(PRUint32* aCount) +{ + NS_ENSURE_ARG_POINTER(aCount); + + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXULListboxAccessible::GetSelectedColumnsCount(PRUint32* aCount) +{ + NS_ENSURE_ARG_POINTER(aCount); + + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXULListboxAccessible::GetSelectedRowsCount(PRUint32* aCount) +{ + NS_ENSURE_ARG_POINTER(aCount); + + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXULListboxAccessible::GetSelectedCells(PRUint32 *aNumCells, PRInt32 **aCells) +{ + NS_ENSURE_ARG_POINTER(aNumCells); + NS_ENSURE_ARG_POINTER(aCells); + + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXULListboxAccessible::GetSelectedColumns(PRUint32 *aNumColumns, + PRInt32 **aColumns) +{ + NS_ENSURE_ARG_POINTER(aNumColumns); + NS_ENSURE_ARG_POINTER(aColumns); + + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXULListboxAccessible::GetSelectedRows(PRUint32 *aNumRows, PRInt32 **aRows) +{ + NS_ENSURE_ARG_POINTER(aNumRows); + NS_ENSURE_ARG_POINTER(aRows); + + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXULListboxAccessible::SelectRow(PRInt32 aRow) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXULListboxAccessible::SelectColumn(PRInt32 aColumn) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXULListboxAccessible::UnselectRow(PRInt32 aRow) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXULListboxAccessible::UnselectColumn(PRInt32 aColumn) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsXULListboxAccessible::IsProbablyForLayout(PRBool *aIsProbablyForLayout) +{ + NS_ENSURE_ARG_POINTER(aIsProbablyForLayout); + *aIsProbablyForLayout = PR_FALSE; + + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////////////// +// nsXULListitemAccessible + +nsXULListitemAccessible:: + nsXULListitemAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell) : + nsXULMenuitemAccessible(aDOMNode, aShell) { mIsCheckbox = PR_FALSE; nsCOMPtr listItem (do_QueryInterface(mDOMNode)); @@ -231,6 +591,28 @@ nsXULMenuitemAccessible(aDOMNode, aShell) /** Inherit the ISupports impl from nsAccessible, we handle nsIAccessibleSelectable */ NS_IMPL_ISUPPORTS_INHERITED0(nsXULListitemAccessible, nsAccessible) +already_AddRefed +nsXULListitemAccessible::GetListAccessible() +{ + if (IsDefunct()) + return nsnull; + + nsCOMPtr listItem = + do_QueryInterface(mDOMNode); + + nsCOMPtr list; + listItem->GetControl(getter_AddRefs(list)); + if (!list) + return nsnull; + + nsIAccessible *listAcc = nsnull; + GetAccService()->GetAccessibleInWeakShell(list, mWeakShell, &listAcc); + return listAcc; +} + +//////////////////////////////////////////////////////////////////////////////// +// nsXULListitemAccessible. nsIAccessible + /** * If there is a Listcell as a child ( not anonymous ) use it, otherwise * default to getting the name from GetXULName @@ -260,6 +642,14 @@ NS_IMETHODIMP nsXULListitemAccessible::GetName(nsAString& _retval) */ NS_IMETHODIMP nsXULListitemAccessible::GetRole(PRUint32 *aRole) { + nsCOMPtr listAcc = GetListAccessible(); + NS_ENSURE_STATE(listAcc); + + if (Role(listAcc) == nsIAccessibleRole::ROLE_TABLE) { + *aRole = nsIAccessibleRole::ROLE_ROW; + return NS_OK; + } + if (mIsCheckbox) *aRole = nsIAccessibleRole::ROLE_CHECKBUTTON; else if (mParent && Role(mParent) == nsIAccessibleRole::ROLE_COMBOBOX_LIST) @@ -331,6 +721,23 @@ nsXULListitemAccessible::GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildr return NS_OK; } +//////////////////////////////////////////////////////////////////////////////// +// nsXULListCellAccessible +nsXULListCellAccessible:: + nsXULListCellAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell): + nsHyperTextAccessibleWrap(aDOMNode, aShell) +{ +} + +NS_IMETHODIMP +nsXULListCellAccessible::GetRole(PRUint32 *aRole) +{ + NS_ENSURE_ARG_POINTER(aRole); + + *aRole = nsIAccessibleRole::ROLE_CELL; + return NS_OK; +} + /** ------------------------------------------------------ */ /** Finally, the Combobox widgets */ /** ------------------------------------------------------ */ diff --git a/mozilla/accessible/src/xul/nsXULSelectAccessible.h b/mozilla/accessible/src/xul/nsXULSelectAccessible.h index b256ecd4664..4e58d4b820f 100644 --- a/mozilla/accessible/src/xul/nsXULSelectAccessible.h +++ b/mozilla/accessible/src/xul/nsXULSelectAccessible.h @@ -38,6 +38,8 @@ #ifndef __nsXULSelectAccessible_h__ #define __nsXULSelectAccessible_h__ +#include "nsIAccessibleTable.h" + #include "nsCOMPtr.h" #include "nsXULMenuAccessible.h" #include "nsBaseWidgetAccessible.h" @@ -101,17 +103,23 @@ public: /* * A class the represents the XUL Listbox widget. */ -class nsXULListboxAccessible : public nsXULSelectableAccessible +class nsXULListboxAccessible : public nsXULSelectableAccessible, + public nsIAccessibleTable { public: - nsXULListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); virtual ~nsXULListboxAccessible() {} - /* ----- nsIAccessible ----- */ - NS_IMETHOD GetRole(PRUint32 *_retval); + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIACCESSIBLETABLE + + // nsIAccessible + NS_IMETHOD GetRole(PRUint32 *aRole); NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState); - NS_IMETHOD GetValue(nsAString& _retval); + NS_IMETHOD GetValue(nsAString& aValue); + +protected: + PRBool IsTree(); }; /** @@ -136,10 +144,25 @@ public: NS_IMETHOD GetDescription(nsAString& aDesc) { return nsAccessibleWrap::GetDescription(aDesc); } NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren); +protected: + already_AddRefed GetListAccessible(); + private: PRBool mIsCheckbox; }; +/** + * Class represents xul:listcell. + */ +class nsXULListCellAccessible : public nsHyperTextAccessibleWrap +{ +public: + nsXULListCellAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + + // nsIAccessible + NS_IMETHOD GetRole(PRUint32 *aRole); +}; + /** ------------------------------------------------------ */ /** Finally, the Combobox widgets */ /** ------------------------------------------------------ */ diff --git a/mozilla/toolkit/content/widgets/listbox.xml b/mozilla/toolkit/content/widgets/listbox.xml index d61b5c09243..298deb4a379 100644 --- a/mozilla/toolkit/content/widgets/listbox.xml +++ b/mozilla/toolkit/content/widgets/listbox.xml @@ -1067,6 +1067,38 @@ + + + + + + + +