diff --git a/accessible/macbuild/accessibleIDL.xml b/accessible/macbuild/accessibleIDL.xml index 6ddcf5872a26..9b6d5ac26ca9 100644 --- a/accessible/macbuild/accessibleIDL.xml +++ b/accessible/macbuild/accessibleIDL.xml @@ -780,13 +780,6 @@ Text - - Name - nsIAccessibleSelection.idl - MacOS - Text - - Name nsIAccessibleValue.idl @@ -867,11 +860,6 @@ nsIAccessibleAction.idl MacOS - - Name - nsIAccessibleSelection.idl - MacOS - Name nsIAccessibleValue.idl @@ -1631,13 +1619,6 @@ Text - - Name - nsIAccessibleSelection.idl - MacOS - Text - - Name nsIAccessibleValue.idl @@ -1718,11 +1699,6 @@ nsIAccessibleAction.idl MacOS - - Name - nsIAccessibleSelection.idl - MacOS - Name nsIAccessibleValue.idl @@ -1813,12 +1789,6 @@ nsIAccessibleAction.idl MacOS - - headers - Name - nsIAccessibleSelection.idl - MacOS - headers Name diff --git a/accessible/public/Makefile.in b/accessible/public/Makefile.in index 99aa95c5a719..f4954c671857 100644 --- a/accessible/public/Makefile.in +++ b/accessible/public/Makefile.in @@ -41,7 +41,6 @@ XPIDLSRCS = \ nsIAccessibleHyperText.idl \ nsIAccessibleProvider.idl \ nsIAccessibleSelectable.idl \ - nsIAccessibleSelection.idl \ nsIAccessibleTable.idl \ nsIAccessibleText.idl \ nsIAccessibleValue.idl \ diff --git a/accessible/public/makefile.win b/accessible/public/makefile.win index 713ed534bb00..d51316a4c7d8 100644 --- a/accessible/public/makefile.win +++ b/accessible/public/makefile.win @@ -35,7 +35,6 @@ XPIDLSRCS = \ .\nsIAccessibleHyperText.idl \ .\nsIAccessibleProvider.idl \ .\nsIAccessibleSelectable.idl \ - .\nsIAccessibleSelection.idl \ .\nsIAccessibleTable.idl \ .\nsIAccessibleText.idl \ .\nsIAccessibleValue.idl \ diff --git a/accessible/public/nsIAccessibleSelectable.idl b/accessible/public/nsIAccessibleSelectable.idl index 45908df85c4c..f1cbbc6bfe08 100644 --- a/accessible/public/nsIAccessibleSelectable.idl +++ b/accessible/public/nsIAccessibleSelectable.idl @@ -21,7 +21,11 @@ * * Contributor(s): * John Gaunt - */ + * Marc Mulcahy (marc.mulcahy@sun.com) + * Paul Sandoz (paul.sandoz@sun.com) + * Bill Haneman (bill.haneman@sun.com) + * Kyle Yuan (kyle.yuan@sun.com) +*/ #include "nsISupports.idl" #include "nsIAccessible.idl" @@ -30,5 +34,43 @@ [scriptable, uuid(34d268d6-1dd2-11b2-9d63-83a5e0ada290)] interface nsIAccessibleSelectable : nsISupports { - nsISupportsArray GetSelectedChildren(); + nsISupportsArray GetSelectedChildren(); + + /** + * Returns the number of accessible children currently selected. + */ + readonly attribute long selectionCount; + + /** + * Adds the specified accessible child of the object to the + * object's selection. + */ + void addSelection(in long index); + + /** + * Removes the specified child of the object from the object's selection. + */ + void removeSelection(in long index); + + /** + * Clears the selection in the object so that no children in the object + * are selected. + */ + void clearSelection(); + + /** + * Returns a reference to the accessible object representing the specified + * selected child of the object. + */ + nsIAccessible refSelection(in long index); + + /** + * Determines if the current child of this object is selected + */ + boolean isChildSelected(in long index); + + /** + * If the object does not accept multiple selection, return false. + */ + boolean selectAllSelection(); }; diff --git a/accessible/src/base/nsSelectAccessible.cpp b/accessible/src/base/nsSelectAccessible.cpp index beef5559ad4d..86c31f2d0fa6 100644 --- a/accessible/src/base/nsSelectAccessible.cpp +++ b/accessible/src/base/nsSelectAccessible.cpp @@ -22,7 +22,7 @@ * Contributor(s): * Original Author: Eric Vaughan (evaughan@netscape.com) * Contributor(s): John Gaunt (jgaunt@netscape.com) - * + * Kyle Yuan (kyle.yuan@sun.com) * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -42,19 +42,20 @@ #include "nsFormControlAccessible.h" #include "nsIAtom.h" #include "nsIComboboxControlFrame.h" -#include "nsIDOMEventReceiver.h" -#include "nsIDOMHTMLCollection.h" -#include "nsIDOMHTMLOptionElement.h" #include "nsIDOMHTMLOptGroupElement.h" -#include "nsIDOMText.h" #include "nsIDOMHTMLSelectElement.h" +#include "nsIDOMText.h" +#include "nsIDOMXULMultSelectCntrlEl.h" +#include "nsIDOMXULSelectCntrlEl.h" +#include "nsIDOMXULSelectCntrlItemEl.h" #include "nsIFrame.h" #include "nsIListControlFrame.h" #include "nsISelectControlFrame.h" +#include "nsIServiceManager.h" #include "nsLayoutAtoms.h" #include "nsRootAccessible.h" #include "nsSelectAccessible.h" -#include "nsIServiceManager.h" + /** ------------------------------------------------------ */ /** First, the common widgets */ @@ -196,206 +197,6 @@ NS_IMETHODIMP nsSelectOptionAccessible::GetAccName(nsAString& _retval) return NS_ERROR_FAILURE; } -/** ------------------------------------------------------ */ -/** Secondly, the Listbox widget */ -/** ------------------------------------------------------ */ - -/** ----- nsListboxAccessible ----- */ - -/** Constructor */ -nsListboxAccessible::nsListboxAccessible(nsIDOMNode* aDOMNode, - nsIWeakReference* aShell): -nsAccessible(aDOMNode, aShell) -{ -} - -NS_IMPL_ISUPPORTS_INHERITED1(nsListboxAccessible, nsAccessible, nsIAccessibleSelectable) - -/** We are a window, as far as MSAA is concerned */ -NS_IMETHODIMP nsListboxAccessible::GetAccRole(PRUint32 *_retval) -{ - *_retval = ROLE_WINDOW; - return NS_OK; -} - -/** - * We always have 1 child: a subclass of nsSelectListAccessible. - */ -NS_IMETHODIMP nsListboxAccessible::GetAccChildCount(PRInt32 *_retval) -{ - *_retval = 1; - return NS_OK; -} - -/** - * As a nsHTMLListboxAccessible we can have the following states: - * STATE_FOCUSED - * STATE_READONLY - * STATE_FOCUSABLE - */ -NS_IMETHODIMP nsListboxAccessible::GetAccState(PRUint32 *_retval) -{ - // Get focus status from base class - nsAccessible::GetAccState(_retval); - - *_retval |= STATE_READONLY | STATE_FOCUSABLE; - - return NS_OK; -} - -/** - * No-op method body. subclasses MUST override this method - */ -NS_IMETHODIMP nsListboxAccessible::GetSelectedChildren(nsISupportsArray **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -/** ------------------------------------------------------ */ -/** Finally, the Combobox widgets */ -/** ------------------------------------------------------ */ - -/** ----- nsComboboxAccessible ----- */ - -/** - * Constructor -- set initial state - closed, register ourself - */ -nsComboboxAccessible::nsComboboxAccessible(nsIDOMNode* aDOMNode, - nsIWeakReference* aShell): -nsAccessible(aDOMNode, aShell) -{ - mRegistered = PR_FALSE; - mOpen = PR_FALSE; - SetupMenuListener(); -} - -/** - * Destructor -- If we are registered, remove ourselves as a listener. - */ -nsComboboxAccessible::~nsComboboxAccessible() -{ - if (mRegistered) { - nsCOMPtr eventReceiver(do_QueryInterface(mDOMNode)); - if (eventReceiver) - eventReceiver->RemoveEventListener(NS_LITERAL_STRING("popupshowing"), this, PR_TRUE); - } -} - -/** - * Inherit the ISupports impl from nsAccessible, - * handle nsIDOMXULListener and nsIAccessibleSelectable ourself - */ -NS_IMPL_ISUPPORTS_INHERITED2(nsComboboxAccessible, nsAccessible, nsIDOMXULListener, nsIAccessibleSelectable) - -/** - * If we aren't already registered, register ourselves as a - * listener to "popupshowing" events on our DOM node. Set our - * state to registered, but don't notify MSAA as they - * don't need to know about this state. - */ -void -nsComboboxAccessible::SetupMenuListener() -{ - // if not already registered as a popup listener, register ourself - if (!mRegistered) { - nsCOMPtr eventReceiver(do_QueryInterface(mDOMNode)); - if (eventReceiver && NS_SUCCEEDED(eventReceiver->AddEventListener(NS_LITERAL_STRING("popupshowing"), this, PR_TRUE))) - mRegistered = PR_TRUE; - } -} - -/** We are a combobox */ -NS_IMETHODIMP nsComboboxAccessible::GetAccRole(PRUint32 *_retval) -{ - *_retval = ROLE_COMBOBOX; - return NS_OK; -} - -/** - * We always have 3 children: TextField, Button, Window. In that order - */ -NS_IMETHODIMP nsComboboxAccessible::GetAccChildCount(PRInt32 *_retval) -{ - *_retval = 3; - return NS_OK; -} - -/** - * nsIAccessibleSelectable method. No-op because our selection is returned through - * GetValue(). This _may_ change just to provide additional info for the vendors - * and another option for them to get at stuff. Despite the fact that we are - * single selection only. - */ -NS_IMETHODIMP nsComboboxAccessible::GetSelectedChildren(nsISupportsArray **_retval) -{ - *_retval = nsnull; - return NS_OK; -} - -/** - * As a nsComboboxAccessible we can have the following states: - * STATE_FOCUSED - * STATE_READONLY - * STATE_FOCUSABLE - * STATE_HASPOPUP - * STATE_EXPANDED - * STATE_COLLAPSED - */ -NS_IMETHODIMP nsComboboxAccessible::GetAccState(PRUint32 *_retval) -{ - // Get focus status from base class - nsAccessible::GetAccState(_retval); - - if (mOpen) - *_retval |= STATE_EXPANDED; - else - *_retval |= STATE_COLLAPSED; - - *_retval |= STATE_HASPOPUP | STATE_READONLY | STATE_FOCUSABLE; - - return NS_OK; -} - -/** - * Set our state to open and (TBD) fire an event to MSAA saying our state - * has changed. - */ -NS_IMETHODIMP nsComboboxAccessible::PopupShowing(nsIDOMEvent* aEvent) -{ - mOpen = PR_TRUE; - - /* TBD send state change event */ - - return NS_OK; -} - -/** - * Set our state to not open and (TDB) fire an event to MSAA saying - * our state has changed. - */ -NS_IMETHODIMP nsComboboxAccessible::PopupHiding(nsIDOMEvent* aEvent) -{ - mOpen = PR_FALSE; - - /* TBD send state change event */ - - return NS_OK; -} - -/** - * Set our state to not open and (TDB) fire an event to MSAA saying - * our state has changed. - */ -NS_IMETHODIMP nsComboboxAccessible::Close(nsIDOMEvent* aEvent) -{ - mOpen = PR_FALSE; - - /* TBD send state change event */ - - return NS_OK; -} - /** ----- nsComboboxTextFieldAccessible ----- */ /** Constructor */ diff --git a/accessible/src/base/nsSelectAccessible.h b/accessible/src/base/nsSelectAccessible.h index d1494b10d00a..cb6f0f031d6c 100644 --- a/accessible/src/base/nsSelectAccessible.h +++ b/accessible/src/base/nsSelectAccessible.h @@ -22,7 +22,7 @@ * Contributor(s): * Original Author: Eric Vaughan (evaughan@netscape.com) * Contributor(s): John Gaunt (jgaunt@netscape.com) - * + * Kyle Yuan (kyle.yuan@sun.com) * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -43,12 +43,15 @@ #include "nsBaseWidgetAccessible.h" #include "nsIAccessibleSelectable.h" +#include "nsIDOMEventReceiver.h" #include "nsIDOMXULListener.h" /** ------------------------------------------------------ */ /** First, the common widgets */ /** ------------------------------------------------------ */ +enum { eSelection_Add=0, eSelection_Remove=1, eSelection_GetState=2 }; + /** * The list that contains all the options in the select. */ @@ -91,76 +94,6 @@ protected: nsCOMPtr mParent; }; -/** ------------------------------------------------------ */ -/** Secondly, the Listbox widget */ -/** ------------------------------------------------------ */ - -/** - * A class that represents the Listbox widget. - */ -class nsListboxAccessible : public nsAccessible, - public nsIAccessibleSelectable -{ -public: - - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIACCESSIBLESELECTABLE - - nsListboxAccessible (nsIDOMNode* aDOMNode, nsIWeakReference* aShell); - virtual ~nsListboxAccessible () {} - - /* ----- nsIAccessible ----- */ - NS_IMETHOD GetAccRole(PRUint32 *_retval); - NS_IMETHOD GetAccChildCount(PRInt32 *_retval); - NS_IMETHOD GetAccState(PRUint32 *_retval); - -}; - -/** ------------------------------------------------------ */ -/** Finally, the Combobox widgets */ -/** ------------------------------------------------------ */ - -/** - * A class the represents the HTML Combobox widget. - */ -class nsComboboxAccessible : public nsAccessible, - public nsIAccessibleSelectable, - public nsIDOMXULListener -{ -public: - - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIACCESSIBLESELECTABLE - - nsComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); - virtual ~nsComboboxAccessible(); - - /* ----- nsIAccessible ----- */ - NS_IMETHOD GetAccRole(PRUint32 *_retval); - NS_IMETHOD GetAccChildCount(PRInt32 *_retval); - NS_IMETHOD GetAccState(PRUint32 *_retval); - - /* ----- nsIDOMXULListener ----- */ - NS_IMETHOD PopupShowing(nsIDOMEvent* aEvent); - NS_IMETHOD PopupShown(nsIDOMEvent* aEvent) { return NS_OK; } - NS_IMETHOD PopupHiding(nsIDOMEvent* aEvent); - NS_IMETHOD PopupHidden(nsIDOMEvent* aEvent) { return NS_OK; } - - NS_IMETHOD Close(nsIDOMEvent* aEvent); - NS_IMETHOD Command(nsIDOMEvent* aEvent) { return NS_OK; } - NS_IMETHOD Broadcast(nsIDOMEvent* aEvent) { return NS_OK; } - NS_IMETHOD CommandUpdate(nsIDOMEvent* aEvent) { return NS_OK; } - NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; } - - virtual void SetupMenuListener(); - -protected: - - PRBool mRegistered; - PRBool mOpen; - -}; - /** * A class the represents the text field in the Combobox to the left * of the drop down button diff --git a/accessible/src/html/nsHTMLSelectAccessible.cpp b/accessible/src/html/nsHTMLSelectAccessible.cpp index 958ed5cacba9..7cb7be02ada0 100644 --- a/accessible/src/html/nsHTMLSelectAccessible.cpp +++ b/accessible/src/html/nsHTMLSelectAccessible.cpp @@ -21,7 +21,7 @@ * * Contributor(s): * Original Author: Eric Vaughan (evaughan@netscape.com) - * + * Contributor(s): Kyle Yuan (kyle.yuan@sun.com) * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -80,6 +80,242 @@ * - nsHTMLSelectOptionAccessible */ +/** ------------------------------------------------------ */ +/** Impl. of nsHTMLSelectableAccessible */ +/** ------------------------------------------------------ */ + +// Helper class +nsHTMLSelectableAccessible::iterator::iterator(nsHTMLSelectableAccessible *aParent) : mParent(aParent) +{ + mLength = mIndex = 0; + mSelCount = 0; + + nsCOMPtr htmlSelect(do_QueryInterface(mParent->mDOMNode)); + if (htmlSelect) { + htmlSelect->GetOptions(getter_AddRefs(mOptions)); + if (mOptions) + mOptions->GetLength(&mLength); + } +} + +PRBool nsHTMLSelectableAccessible::iterator::Advance() +{ + if (mIndex < mLength) { + nsCOMPtr tempNode; + if (mOptions) { + mOptions->Item(mIndex, getter_AddRefs(tempNode)); + mOption = do_QueryInterface(tempNode); + } + mIndex++; + return PR_TRUE; + } + return PR_FALSE; +} + +void nsHTMLSelectableAccessible::iterator::CalcSelectionCount(PRInt32 *aSelectionCount) +{ + PRBool isSelected = PR_FALSE; + + if (mOption) + mOption->GetSelected(&isSelected); + + if (isSelected) + (*aSelectionCount)++; +} + +void nsHTMLSelectableAccessible::iterator::AddAccessibleIfSelected(nsIAccessibilityService *aAccService, + nsISupportsArray *aSelectedAccessibles, + nsIPresContext *aContext) +{ + PRBool isSelected = PR_FALSE; + nsCOMPtr tempAccess; + + if (mOption) { + mOption->GetSelected(&isSelected); + if (isSelected) + aAccService->CreateHTMLSelectOptionAccessible(mOption, mParent, aContext, getter_AddRefs(tempAccess)); + } + + if (tempAccess) + aSelectedAccessibles->AppendElement(tempAccess); +} + +PRBool nsHTMLSelectableAccessible::iterator::GetAccessibleIfSelected(PRInt32 aIndex, + nsIAccessibilityService *aAccService, + nsIPresContext *aContext, + nsIAccessible **_retval) +{ + PRBool isSelected = PR_FALSE; + nsCOMPtr tempAccess; + + *_retval = nsnull; + + if (mOption) { + mOption->GetSelected(&isSelected); + if (isSelected) { + if (mSelCount == aIndex) { + aAccService->CreateHTMLSelectOptionAccessible(mOption, mParent, aContext, getter_AddRefs(tempAccess)); + *_retval = tempAccess; + NS_IF_ADDREF(*_retval); + return PR_TRUE; + } + mSelCount++; + } + } + + return PR_FALSE; +} + +void nsHTMLSelectableAccessible::iterator::Select(PRBool aSelect) +{ + if (mOption) + mOption->SetSelected(aSelect); +} + +nsHTMLSelectableAccessible::nsHTMLSelectableAccessible(nsIDOMNode* aDOMNode, + nsIWeakReference* aShell): +nsAccessible(aDOMNode, aShell) +{ +} + +NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLSelectableAccessible, nsAccessible, nsIAccessibleSelectable) + +// Helper methods +NS_IMETHODIMP nsHTMLSelectableAccessible::ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState) +{ + *aSelState = PR_FALSE; + + nsCOMPtr htmlSelect(do_QueryInterface(mDOMNode)); + if (!htmlSelect) + return NS_ERROR_FAILURE; + + nsCOMPtr options; + htmlSelect->GetOptions(getter_AddRefs(options)); + if (!options) + return NS_ERROR_FAILURE; + + nsCOMPtr tempNode; + options->Item(aIndex, getter_AddRefs(tempNode)); + nsCOMPtr tempOption(do_QueryInterface(tempNode)); + if (!tempOption) + return NS_ERROR_FAILURE; + + tempOption->GetSelected(aSelState); + if (eSelection_Add == aMethod && !(*aSelState)) + tempOption->SetSelected(PR_TRUE); + else if (eSelection_Remove == aMethod && (*aSelState)) + tempOption->SetSelected(PR_FALSE); + return NS_OK; +} + +// Interface methods +NS_IMETHODIMP nsHTMLSelectableAccessible::GetSelectedChildren(nsISupportsArray **_retval) +{ + *_retval = nsnull; + + nsCOMPtr accService(do_GetService("@mozilla.org/accessibilityService;1")); + if (!accService) + return NS_ERROR_FAILURE; + + nsCOMPtr selectedAccessibles; + NS_NewISupportsArray(getter_AddRefs(selectedAccessibles)); + if (!selectedAccessibles) + return NS_ERROR_OUT_OF_MEMORY; + + nsCOMPtr context; + GetPresContext(context); + if (!context) + return NS_ERROR_FAILURE; + + nsHTMLSelectableAccessible::iterator iter(this); + while (iter.Advance()) + iter.AddAccessibleIfSelected(accService, selectedAccessibles, context); + + PRUint32 uLength = 0; + selectedAccessibles->Count(&uLength); + if (uLength != 0) { // length of nsISupportsArray containing selected options + *_retval = selectedAccessibles; + NS_ADDREF(*_retval); + } + return NS_OK; +} + +// return the nth selected child's nsIAccessible object +NS_IMETHODIMP nsHTMLSelectableAccessible::RefSelection(PRInt32 aIndex, nsIAccessible **_retval) +{ + *_retval = nsnull; + + nsCOMPtr accService(do_GetService("@mozilla.org/accessibilityService;1")); + if (!accService) + return NS_ERROR_FAILURE; + + nsCOMPtr context; + GetPresContext(context); + if (!context) + return NS_ERROR_FAILURE; + + nsHTMLSelectableAccessible::iterator iter(this); + while (iter.Advance()) + if (iter.GetAccessibleIfSelected(aIndex, accService, context, _retval)) + return NS_OK; + + // No matched item found + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP nsHTMLSelectableAccessible::GetSelectionCount(PRInt32 *aSelectionCount) +{ + *aSelectionCount = 0; + + nsHTMLSelectableAccessible::iterator iter(this); + while (iter.Advance()) + iter.CalcSelectionCount(aSelectionCount); + return NS_OK; +} + +NS_IMETHODIMP nsHTMLSelectableAccessible::AddSelection(PRInt32 aIndex) +{ + PRBool isSelected; + return ChangeSelection(aIndex, eSelection_Add, &isSelected); +} + +NS_IMETHODIMP nsHTMLSelectableAccessible::RemoveSelection(PRInt32 aIndex) +{ + PRBool isSelected; + return ChangeSelection(aIndex, eSelection_Remove, &isSelected); +} + +NS_IMETHODIMP nsHTMLSelectableAccessible::IsChildSelected(PRInt32 aIndex, PRBool *_retval) +{ + *_retval = PR_FALSE; + return ChangeSelection(aIndex, eSelection_GetState, _retval); +} + +NS_IMETHODIMP nsHTMLSelectableAccessible::ClearSelection() +{ + nsHTMLSelectableAccessible::iterator iter(this); + while (iter.Advance()) + iter.Select(PR_FALSE); + return NS_OK; +} + +NS_IMETHODIMP nsHTMLSelectableAccessible::SelectAllSelection(PRBool *_retval) +{ + *_retval = PR_FALSE; + + nsCOMPtr htmlSelect(do_QueryInterface(mDOMNode)); + if (!htmlSelect) + return NS_ERROR_FAILURE; + + htmlSelect->GetMultiple(_retval); + if (*_retval) { + nsHTMLSelectableAccessible::iterator iter(this); + while (iter.Advance()) + iter.Select(PR_TRUE); + } + return NS_OK; +} + /** ------------------------------------------------------ */ /** First, the common widgets */ /** ------------------------------------------------------ */ @@ -478,8 +714,6 @@ NS_IMETHODIMP nsHTMLSelectOptGroupAccessible::GetAccNumActions(PRUint8 *_retval) return NS_ERROR_NOT_IMPLEMENTED; } - - /** ------------------------------------------------------ */ /** Secondly, the Listbox widget */ /** ------------------------------------------------------ */ @@ -488,10 +722,42 @@ NS_IMETHODIMP nsHTMLSelectOptGroupAccessible::GetAccNumActions(PRUint8 *_retval) /** Constructor */ nsHTMLListboxAccessible::nsHTMLListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell): -nsListboxAccessible(aDOMNode, aShell) +nsHTMLSelectableAccessible(aDOMNode, aShell) { } +/** We are a window, as far as MSAA is concerned */ +NS_IMETHODIMP nsHTMLListboxAccessible::GetAccRole(PRUint32 *_retval) +{ + *_retval = ROLE_WINDOW; + return NS_OK; +} + +/** + * We always have 1 child: a subclass of nsSelectListAccessible. + */ +NS_IMETHODIMP nsHTMLListboxAccessible::GetAccChildCount(PRInt32 *_retval) +{ + *_retval = 1; + return NS_OK; +} + +/** + * As a nsHTMLListboxAccessible we can have the following states: + * STATE_FOCUSED + * STATE_READONLY + * STATE_FOCUSABLE + */ +NS_IMETHODIMP nsHTMLListboxAccessible::GetAccState(PRUint32 *_retval) +{ + // Get focus status from base class + nsAccessible::GetAccState(_retval); + + *_retval |= STATE_READONLY | STATE_FOCUSABLE; + + return NS_OK; +} + /** * Our last (and only) child is an nsHTMLSelectListAccessible object */ @@ -530,79 +796,59 @@ NS_IMETHODIMP nsHTMLListboxAccessible::GetAccValue(nsAString& _retval) return NS_ERROR_FAILURE; } -/** - * nsIAccessibleSelectable method. - * - gets from the Select DOMNode the list of all Select Options - * - iterates through all of the options looking for selected Options - * - creates IAccessible objects for selected Options - * - Returns the IAccessibles for selectd Options in the nsISupportsArray - * - * retval will be nsnull if: - * - there are no Options in the Select Element - * - there are Options but none are selected - * - the DOMNode is not a nsIDOMHTMLSelectElement ( shouldn't happen ) - */ -NS_IMETHODIMP nsHTMLListboxAccessible::GetSelectedChildren(nsISupportsArray **_retval) -{ - nsCOMPtr select(do_QueryInterface(mDOMNode)); - if(select) { - nsCOMPtr options; - // get all the options in the select - select->GetOptions(getter_AddRefs(options)); - if (options) { - // set up variables we need to get the selected options and to get their nsIAccessile objects - PRUint32 length; - options->GetLength(&length); - nsCOMPtr accService(do_GetService("@mozilla.org/accessibilityService;1")); - nsCOMPtr selectedAccessibles; - NS_NewISupportsArray(getter_AddRefs(selectedAccessibles)); - if (!selectedAccessibles || !accService) - return NS_ERROR_FAILURE; - // find the selected options and get the accessible objects; - PRBool isSelected = PR_FALSE; - nsCOMPtr context; - GetPresContext(context); - for (PRUint32 i = 0 ; i < length ; i++) { - nsCOMPtr tempNode; - options->Item(i,getter_AddRefs(tempNode)); - if (tempNode) { - nsCOMPtr tempOption(do_QueryInterface(tempNode)); - if (tempOption) - tempOption->GetSelected(&isSelected); - if (isSelected) { - nsCOMPtr tempAccess; - accService->CreateHTMLSelectOptionAccessible(tempOption, this, context, getter_AddRefs(tempAccess)); - if ( tempAccess ) - selectedAccessibles->AppendElement(tempAccess); - isSelected = PR_FALSE; - } - } - } - selectedAccessibles->Count(&length); // reusing length - if ( length != 0 ) { // length of nsISupportsArray containing selected options - *_retval = selectedAccessibles; - NS_IF_ADDREF(*_retval); - return NS_OK; - } - } - } - // no options, not a select or none of the options are selected - *_retval = nsnull; - return NS_OK; -} - /** ------------------------------------------------------ */ /** Finally, the Combobox widgets */ /** ------------------------------------------------------ */ /** ----- nsHTMLComboboxAccessible ----- */ -/** Constructor */ nsHTMLComboboxAccessible::nsHTMLComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell): -nsComboboxAccessible(aDOMNode, aShell) +nsHTMLSelectableAccessible(aDOMNode, aShell) { } +/** We are a combobox */ +NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccRole(PRUint32 *_retval) +{ + *_retval = ROLE_COMBOBOX; + return NS_OK; +} + +/** + * We always have 3 children: TextField, Button, Window. In that order + */ +NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccChildCount(PRInt32 *_retval) +{ + *_retval = 3; + return NS_OK; +} + +/** + * As a nsComboboxAccessible we can have the following states: + * STATE_FOCUSED + * STATE_READONLY + * STATE_FOCUSABLE + * STATE_HASPOPUP + * STATE_EXPANDED + * STATE_COLLAPSED + */ +NS_IMETHODIMP nsHTMLComboboxAccessible::GetAccState(PRUint32 *_retval) +{ + // Get focus status from base class + nsAccessible::GetAccState(_retval); + + // we are open or closed + PRBool isOpen = PR_FALSE; + nsCOMPtr comboFrame(do_QueryInterface(GetBoundsFrame())); + if (comboFrame) + comboFrame->IsDroppedDown(&isOpen); + + *_retval |= isOpen ? STATE_EXPANDED : STATE_COLLAPSED; + *_retval |= STATE_HASPOPUP | STATE_READONLY | STATE_FOCUSABLE; + + return NS_OK; +} + /** * Our last child is an nsHTMLComboboxWindowAccessible object */ diff --git a/accessible/src/html/nsHTMLSelectAccessible.h b/accessible/src/html/nsHTMLSelectAccessible.h index 4fcc2a0a0dfc..d416c4c999e2 100644 --- a/accessible/src/html/nsHTMLSelectAccessible.h +++ b/accessible/src/html/nsHTMLSelectAccessible.h @@ -21,7 +21,7 @@ * * Contributor(s): * Original Author: Eric Vaughan (evaughan@netscape.com) - * + * Contributor(s): Kyle Yuan (kyle.yuan@sun.com) * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -41,6 +41,8 @@ #include "nsCOMPtr.h" #include "nsIAccessibleSelectable.h" +#include "nsIDOMHTMLCollection.h" +#include "nsIDOMHTMLOptionElement.h" #include "nsIDOMNode.h" #include "nsIWeakReference.h" #include "nsSelectAccessible.h" @@ -69,6 +71,48 @@ /** First, the common widgets */ /** ------------------------------------------------------ */ +/* + * The basic implemetation of nsIAccessibleSelectable. + */ +class nsHTMLSelectableAccessible : public nsAccessible, + public nsIAccessibleSelectable +{ +public: + + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIACCESSIBLESELECTABLE + + nsHTMLSelectableAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsHTMLSelectableAccessible() {} + +protected: + + NS_IMETHOD ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState); + + class iterator + { + protected: + PRUint32 mLength; + PRUint32 mIndex; + PRInt32 mSelCount; + nsHTMLSelectableAccessible *mParent; + nsCOMPtr mOptions; + nsCOMPtr mOption; + + public: + iterator(nsHTMLSelectableAccessible *aParent); + + void CalcSelectionCount(PRInt32 *aSelectionCount); + void Select(PRBool aSelect); + void AddAccessibleIfSelected(nsIAccessibilityService *aAccService, nsISupportsArray *aSelectedAccessibles, nsIPresContext *aContext); + PRBool GetAccessibleIfSelected(PRInt32 aIndex, nsIAccessibilityService *aAccService, nsIPresContext *aContext, nsIAccessible **_retval); + + PRBool Advance(); + }; + + friend class iterator; +}; + /* * The list that contains all the options in the select. */ @@ -132,16 +176,18 @@ public: /* * A class the represents the HTML Listbox widget. */ -class nsHTMLListboxAccessible : public nsListboxAccessible +class nsHTMLListboxAccessible : public nsHTMLSelectableAccessible { public: - NS_DECL_NSIACCESSIBLESELECTABLE - nsHTMLListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); virtual ~nsHTMLListboxAccessible() {} /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccRole(PRUint32 *_retval); + NS_IMETHOD GetAccChildCount(PRInt32 *_retval); + NS_IMETHOD GetAccState(PRUint32 *_retval); + NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); NS_IMETHOD GetAccValue(nsAString& _retval); @@ -155,7 +201,7 @@ public: /* * A class the represents the HTML Combobox widget. */ -class nsHTMLComboboxAccessible : public nsComboboxAccessible +class nsHTMLComboboxAccessible : public nsHTMLSelectableAccessible { public: @@ -163,6 +209,10 @@ public: virtual ~nsHTMLComboboxAccessible() {} /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccRole(PRUint32 *_retval); + NS_IMETHOD GetAccChildCount(PRInt32 *_retval); + NS_IMETHOD GetAccState(PRUint32 *_retval); + NS_IMETHOD GetAccLastChild(nsIAccessible **_retval); NS_IMETHOD GetAccFirstChild(nsIAccessible **_retval); NS_IMETHOD GetAccValue(nsAString& _retval); diff --git a/accessible/src/xul/nsXULSelectAccessible.cpp b/accessible/src/xul/nsXULSelectAccessible.cpp index c280ab113fda..9eebc7ddff5e 100644 --- a/accessible/src/xul/nsXULSelectAccessible.cpp +++ b/accessible/src/xul/nsXULSelectAccessible.cpp @@ -21,7 +21,7 @@ * * Contributor(s): * Original Author: Eric Vaughan (evaughan@netscape.com) - * + * Kyle Yuan (kyle.yuan@sun.com) * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -42,6 +42,7 @@ #include "nsIAccessibilityService.h" #include "nsIDOMEventReceiver.h" #include "nsIDOMNodeList.h" +#include "nsIDOMXULMenuListElement.h" #include "nsIDOMXULMultSelectCntrlEl.h" #include "nsIDOMXULSelectCntrlItemEl.h" #include "nsIDOMXULSelectCntrlEl.h" @@ -68,6 +69,192 @@ * - nsXULSelectOptionAccessible */ +/** ------------------------------------------------------ */ +/** Impl. of nsXULSelectableAccessible */ +/** ------------------------------------------------------ */ + +// Helper methos +nsXULSelectableAccessible::nsXULSelectableAccessible(nsIDOMNode* aDOMNode, + nsIWeakReference* aShell): +nsAccessible(aDOMNode, aShell) +{ +} + +NS_IMPL_ISUPPORTS_INHERITED1(nsXULSelectableAccessible, nsAccessible, nsIAccessibleSelectable) + +NS_IMETHODIMP nsXULSelectableAccessible::ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState) +{ + *aSelState = PR_FALSE; + + nsCOMPtr xulMultiSelect(do_QueryInterface(mDOMNode)); + if (xulMultiSelect) { + nsCOMPtr nodeList; + xulMultiSelect->GetChildNodes(getter_AddRefs(nodeList)); + if (nodeList) { + nsCOMPtr node; + nodeList->Item(aIndex, getter_AddRefs(node)); + nsCOMPtr item(do_QueryInterface(node)); + item->GetSelected(aSelState); + if (eSelection_Add == aMethod && !(*aSelState)) + xulMultiSelect->AddItemToSelection(item); + else if (eSelection_Remove == aMethod && (*aSelState)) + xulMultiSelect->RemoveItemFromSelection(item); + } + return NS_OK; + } + + nsCOMPtr xulSelect(do_QueryInterface(mDOMNode)); + if (xulSelect) { + PRInt32 selIndex; + xulSelect->GetSelectedIndex(&selIndex); + if (selIndex == aIndex) + *aSelState = PR_TRUE; + if (eSelection_Add == aMethod && !(*aSelState)) + xulSelect->SetSelectedIndex(aIndex); + else if (eSelection_Remove == aMethod && (*aSelState)) { + xulSelect->SetSelectedIndex(-1); + } + return NS_OK; + } + + return NS_ERROR_FAILURE; +} + +// Interface methods +NS_IMETHODIMP nsXULSelectableAccessible::GetSelectedChildren(nsISupportsArray **_retval) +{ + *_retval = nsnull; + + nsCOMPtr accService(do_GetService("@mozilla.org/accessibilityService;1")); + if (!accService) + return NS_ERROR_FAILURE; + + nsCOMPtr selectedAccessibles; + NS_NewISupportsArray(getter_AddRefs(selectedAccessibles)); + if (!selectedAccessibles) + return NS_ERROR_OUT_OF_MEMORY; + + // For XUL multi-select control + nsCOMPtr xulMultiSelect(do_QueryInterface(mDOMNode)); + if (xulMultiSelect) { + PRInt32 length = 0; + xulMultiSelect->GetSelectedCount(&length); + for (PRInt32 index = 0; index < length; index++) { + nsCOMPtr tempAccessible; + nsCOMPtr tempNode; + xulMultiSelect->GetSelectedItem(index, getter_AddRefs(tempNode)); + nsCOMPtr tempDOMNode (do_QueryInterface(tempNode)); + accService->CreateXULListitemAccessible(tempDOMNode, getter_AddRefs(tempAccessible)); + if (tempAccessible) + selectedAccessibles->AppendElement(tempAccessible); + } + } + + PRUint32 uLength = 0; + selectedAccessibles->Count(&uLength); + if (uLength != 0) { // length of nsISupportsArray containing selected options + *_retval = selectedAccessibles; + NS_ADDREF(*_retval); + } + + return NS_OK; +} + +// return the nth selected child's nsIAccessible object +NS_IMETHODIMP nsXULSelectableAccessible::RefSelection(PRInt32 aIndex, nsIAccessible **_retval) +{ + *_retval = nsnull; + + nsCOMPtr accService(do_GetService("@mozilla.org/accessibilityService;1")); + if (!accService) + return NS_ERROR_FAILURE; + + nsCOMPtr tempDOMNode; + nsCOMPtr xulMultiSelect(do_QueryInterface(mDOMNode)); + if (xulMultiSelect) + xulMultiSelect->GetSelectedItem(aIndex, getter_AddRefs(tempDOMNode)); + + nsCOMPtr xulSelect(do_QueryInterface(mDOMNode)); + if (xulSelect && aIndex == 0) + xulSelect->GetSelectedItem(getter_AddRefs(tempDOMNode)); + + if (tempDOMNode) { + nsCOMPtr tempAccess; + accService->CreateXULListitemAccessible(tempDOMNode, getter_AddRefs(tempAccess)); + *_retval = tempAccess; + NS_ADDREF(*_retval); + return NS_OK; + } + + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP nsXULSelectableAccessible::GetSelectionCount(PRInt32 *aSelectionCount) +{ + *aSelectionCount = 0; + + // For XUL multi-select control + nsCOMPtr xulMultiSelect(do_QueryInterface(mDOMNode)); + if (xulMultiSelect) + return xulMultiSelect->GetSelectedCount(aSelectionCount); + + // For XUL single-select control/menulist + nsCOMPtr xulSelect(do_QueryInterface(mDOMNode)); + if (xulSelect) { + PRInt32 index; + xulSelect->GetSelectedIndex(&index); + if (index >= 0) + *aSelectionCount = 1; + return NS_OK; + } + + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP nsXULSelectableAccessible::AddSelection(PRInt32 aIndex) +{ + PRBool isSelected; + return ChangeSelection(aIndex, eSelection_Add, &isSelected); +} + +NS_IMETHODIMP nsXULSelectableAccessible::RemoveSelection(PRInt32 aIndex) +{ + PRBool isSelected; + return ChangeSelection(aIndex, eSelection_Remove, &isSelected); +} + +NS_IMETHODIMP nsXULSelectableAccessible::IsChildSelected(PRInt32 aIndex, PRBool *_retval) +{ + *_retval = PR_FALSE; + return ChangeSelection(aIndex, eSelection_GetState, _retval); +} + +NS_IMETHODIMP nsXULSelectableAccessible::ClearSelection() +{ + nsCOMPtr xulMultiSelect(do_QueryInterface(mDOMNode)); + if (xulMultiSelect) + return xulMultiSelect->ClearSelection(); + + nsCOMPtr xulSelect(do_QueryInterface(mDOMNode)); + if (xulSelect) + return xulSelect->SetSelectedIndex(-1); + + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP nsXULSelectableAccessible::SelectAllSelection(PRBool *_retval) +{ + *_retval = PR_TRUE; + + nsCOMPtr xulMultiSelect(do_QueryInterface(mDOMNode)); + if (xulMultiSelect) + return xulMultiSelect->SelectAll(); + + // otherwise, don't support this method + *_retval = PR_FALSE; + return NS_OK; +} + /** ------------------------------------------------------ */ /** First, the common widgets */ /** ------------------------------------------------------ */ @@ -147,7 +334,7 @@ NS_IMETHODIMP nsXULSelectOptionAccessible::GetAccState(PRUint32 *_retval) /** Constructor */ nsXULListboxAccessible::nsXULListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell): -nsListboxAccessible(aDOMNode, aShell) +nsXULSelectableAccessible(aDOMNode, aShell) { } @@ -168,7 +355,9 @@ NS_IMETHODIMP nsXULListboxAccessible::GetAccChildCount(PRInt32 *_retval) NS_IMETHODIMP nsXULListboxAccessible::GetAccState(PRUint32 *_retval) { // Get focus status from base class - nsListboxAccessible::GetAccState(_retval); + nsAccessible::GetAccState(_retval); + + *_retval |= STATE_READONLY | STATE_FOCUSABLE; // see if we are multiple select if so set ourselves as such nsCOMPtr element (do_QueryInterface(mDOMNode)); @@ -205,55 +394,6 @@ NS_IMETHODIMP nsXULListboxAccessible::GetAccRole(PRUint32 *_retval) return NS_OK; } -/** - * nsIAccessibleSelectable method. - * - gets from the Select DOMNode the list of all Select Options - * - iterates through all of the options looking for selected Options - * - creates IAccessible objects for selected Options - * - Returns the IAccessibles for selected Options in the nsISupportsArray - * - * retval will be nsnull if: - * - there are no Options in the Select Element - * - there are Options but none are selected - * - the DOMNode is not a nsIDOMXULSelectControlElement ( shouldn't happen ) - */ -NS_IMETHODIMP nsXULListboxAccessible::GetSelectedChildren(nsISupportsArray **_retval) -{ - *_retval = nsnull; - - nsCOMPtr accService(do_GetService("@mozilla.org/accessibilityService;1")); - nsCOMPtr selectedAccessibles; - NS_NewISupportsArray(getter_AddRefs(selectedAccessibles)); - if (!selectedAccessibles || !accService) - return NS_ERROR_FAILURE; - - nsCOMPtr selectedItems; - nsCOMPtr listbox (do_QueryInterface(mDOMNode)); - PRInt32 length = 0; - if (listbox) { - listbox->GetSelectedCount(&length); - for ( PRInt32 i = 0 ; i < length ; i++ ) { - nsCOMPtr tempAccessible; - nsCOMPtr tempNode; - listbox->GetSelectedItem(i, getter_AddRefs(tempNode)); - nsCOMPtr tempDOMNode (do_QueryInterface(tempNode)); - accService->CreateXULListitemAccessible(tempDOMNode, getter_AddRefs(tempAccessible)); - if (tempAccessible) - selectedAccessibles->AppendElement(tempAccessible); - } - } - - PRUint32 uLength = 0; - selectedAccessibles->Count(&uLength); - if ( uLength != 0 ) { // length of nsISupportsArray containing selected options - *_retval = selectedAccessibles; - NS_ADDREF(*_retval); - } - - // no options, not a select or none of the options are selected - return NS_OK; -} - /** ----- nsXULListitemAccessible ----- */ /** Constructor */ @@ -335,10 +475,55 @@ NS_IMETHODIMP nsXULListitemAccessible::GetAccState(PRUint32 *_retval) /** Constructor */ nsXULComboboxAccessible::nsXULComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell): -nsComboboxAccessible(aDOMNode, aShell) +nsXULSelectableAccessible(aDOMNode, aShell) { } +/** We are a combobox */ +NS_IMETHODIMP nsXULComboboxAccessible::GetAccRole(PRUint32 *_retval) +{ + *_retval = ROLE_COMBOBOX; + return NS_OK; +} + +/** + * We always have 3 children: TextField, Button, Window. In that order + */ +NS_IMETHODIMP nsXULComboboxAccessible::GetAccChildCount(PRInt32 *_retval) +{ + *_retval = 3; + return NS_OK; +} + +/** + * As a nsComboboxAccessible we can have the following states: + * STATE_FOCUSED + * STATE_READONLY + * STATE_FOCUSABLE + * STATE_HASPOPUP + * STATE_EXPANDED + * STATE_COLLAPSED + */ +NS_IMETHODIMP nsXULComboboxAccessible::GetAccState(PRUint32 *_retval) +{ + // Get focus status from base class + nsAccessible::GetAccState(_retval); + + nsCOMPtr menuList(do_QueryInterface(mDOMNode)); + if (menuList) { + PRBool isOpen; + menuList->GetOpen(&isOpen); + if (isOpen) + *_retval |= STATE_EXPANDED; + else + *_retval |= STATE_COLLAPSED; + } + + *_retval |= STATE_HASPOPUP | STATE_READONLY | STATE_FOCUSABLE; + + return NS_OK; +} + /** * Our value is the value of our ( first ) selected child. nsIDOMXULSelectElement * returns this by default with GetValue(). @@ -353,5 +538,3 @@ NS_IMETHODIMP nsXULComboboxAccessible::GetAccValue(nsAString& _retval) } return NS_ERROR_FAILURE; } - - diff --git a/accessible/src/xul/nsXULSelectAccessible.h b/accessible/src/xul/nsXULSelectAccessible.h index 4d1b997507d8..dcdbe596116c 100644 --- a/accessible/src/xul/nsXULSelectAccessible.h +++ b/accessible/src/xul/nsXULSelectAccessible.h @@ -21,7 +21,7 @@ * * Contributor(s): * Original Author: Eric Vaughan (evaughan@netscape.com) - * + * Contributor(s): Kyle Yuan (kyle.yuan@sun.com) * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -70,6 +70,23 @@ /** First, the common widgets */ /** ------------------------------------------------------ */ +/* + * The basic implemetation of nsIAccessibleSelectable. + */ +class nsXULSelectableAccessible : public nsAccessible, + public nsIAccessibleSelectable +{ +public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIACCESSIBLESELECTABLE + + nsXULSelectableAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); + virtual ~nsXULSelectableAccessible() {} + +protected: + NS_IMETHOD ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState); +}; + /* * The list that contains all the options in the select. */ @@ -109,12 +126,10 @@ public: /* * A class the represents the XUL Listbox widget. */ -class nsXULListboxAccessible : public nsListboxAccessible +class nsXULListboxAccessible : public nsXULSelectableAccessible { public: - NS_DECL_NSIACCESSIBLESELECTABLE - nsXULListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell); virtual ~nsXULListboxAccessible() {} @@ -151,7 +166,7 @@ public: /* * A class the represents the XUL Combobox widget. */ -class nsXULComboboxAccessible : public nsComboboxAccessible +class nsXULComboboxAccessible : public nsXULSelectableAccessible { public: @@ -159,6 +174,10 @@ public: virtual ~nsXULComboboxAccessible() {} /* ----- nsIAccessible ----- */ + NS_IMETHOD GetAccRole(PRUint32 *_retval); + NS_IMETHOD GetAccChildCount(PRInt32 *_retval); + NS_IMETHOD GetAccState(PRUint32 *_retval); + NS_IMETHOD GetAccValue(nsAString& _retval); }; diff --git a/accessible/src/xul/nsXULTreeAccessible.cpp b/accessible/src/xul/nsXULTreeAccessible.cpp index 528e59353910..bd9da7dbf6d7 100644 --- a/accessible/src/xul/nsXULTreeAccessible.cpp +++ b/accessible/src/xul/nsXULTreeAccessible.cpp @@ -50,7 +50,7 @@ // ---------- nsXULTreeAccessible ---------- nsXULTreeAccessible::nsXULTreeAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell): -nsAccessible(aDOMNode, aShell) +nsXULSelectableAccessible(aDOMNode, aShell) { GetTreeBoxObject(aDOMNode, getter_AddRefs(mTree)); if (mTree) @@ -58,7 +58,7 @@ nsAccessible(aDOMNode, aShell) NS_ASSERTION(mTree && mTreeView, "Can't get mTree or mTreeView!\n"); } -NS_IMPL_ISUPPORTS_INHERITED1(nsXULTreeAccessible, nsAccessible, nsIAccessibleSelectable) +NS_IMPL_ISUPPORTS_INHERITED0(nsXULTreeAccessible, nsXULSelectableAccessible) NS_IMETHODIMP nsXULTreeAccessible::GetAccState(PRUint32 *_retval) { @@ -68,10 +68,11 @@ NS_IMETHODIMP nsXULTreeAccessible::GetAccState(PRUint32 *_retval) // see if we are multiple select if so set ourselves as such nsCOMPtr element (do_QueryInterface(mDOMNode)); if (element) { + // the default selection type is multiple nsAutoString selType; element->GetAttribute(NS_LITERAL_STRING("seltype"), selType); - if (!selType.IsEmpty() && selType.Equals(NS_LITERAL_STRING("multiple"))) - *_retval |= STATE_MULTISELECTABLE; + if (selType.IsEmpty() || !selType.Equals(NS_LITERAL_STRING("single"))) + *_retval |= STATE_MULTISELECTABLE; } *_retval |= STATE_READONLY | STATE_FOCUSABLE; @@ -201,6 +202,121 @@ NS_IMETHODIMP nsXULTreeAccessible::GetSelectedChildren(nsISupportsArray **_retva return NS_OK; } +NS_IMETHODIMP nsXULTreeAccessible::GetSelectionCount(PRInt32 *aSelectionCount) +{ + *aSelectionCount = 0; + + NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE); + + nsCOMPtr selection; + mTree->GetSelection(getter_AddRefs(selection)); + if (selection) + selection->GetCount(aSelectionCount); + + return NS_OK; +} + +NS_IMETHODIMP nsXULTreeAccessible::ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState) +{ + NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE); + + nsCOMPtr selection; + mTree->GetSelection(getter_AddRefs(selection)); + if (selection) { + selection->IsSelected(aIndex, aSelState); + if ((!(*aSelState) && eSelection_Add == aMethod) || + ((*aSelState) && eSelection_Remove == aMethod)) + selection->ToggleSelect(aIndex); + } + + return NS_OK; +} + +NS_IMETHODIMP nsXULTreeAccessible::AddSelection(PRInt32 aIndex) +{ + PRBool isSelected; + return ChangeSelection(aIndex, eSelection_Add, &isSelected); +} + +NS_IMETHODIMP nsXULTreeAccessible::RemoveSelection(PRInt32 aIndex) +{ + PRBool isSelected; + return ChangeSelection(aIndex, eSelection_Remove, &isSelected); +} + +NS_IMETHODIMP nsXULTreeAccessible::IsChildSelected(PRInt32 aIndex, PRBool *_retval) +{ + return ChangeSelection(aIndex, eSelection_GetState, _retval); +} + +NS_IMETHODIMP nsXULTreeAccessible::ClearSelection() +{ + NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE); + + nsCOMPtr selection; + mTree->GetSelection(getter_AddRefs(selection)); + if (selection) + selection->ClearSelection(); + + return NS_OK; +} + +NS_IMETHODIMP nsXULTreeAccessible::RefSelection(PRInt32 aIndex, nsIAccessible **_retval) +{ + *_retval = nsnull; + + NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE); + + nsCOMPtr selection; + mTree->GetSelection(getter_AddRefs(selection)); + if (!selection) + return NS_ERROR_FAILURE; + + PRInt32 rowIndex, rowCount; + PRInt32 selCount = 0; + PRBool isSelected; + mTreeView->GetRowCount(&rowCount); + for (rowIndex = 0; rowIndex < rowCount; rowIndex++) { + selection->IsSelected(rowIndex, &isSelected); + if (isSelected) { + if (selCount == aIndex) { + nsCOMPtr tempAccess; + tempAccess = new nsXULTreeitemAccessible(this, mDOMNode, mPresShell, rowIndex); + if (!tempAccess) + return NS_ERROR_OUT_OF_MEMORY; + *_retval = tempAccess; + NS_ADDREF(*_retval); + } + selCount++; + } + } + + return NS_OK; +} + +NS_IMETHODIMP nsXULTreeAccessible::SelectAllSelection(PRBool *_retval) +{ + *_retval = PR_FALSE; + + NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE); + + // see if we are multiple select if so set ourselves as such + nsCOMPtr element (do_QueryInterface(mDOMNode)); + if (element) { + nsAutoString selType; + element->GetAttribute(NS_LITERAL_STRING("seltype"), selType); + if (selType.IsEmpty() || !selType.Equals(NS_LITERAL_STRING("single"))) { + *_retval = PR_TRUE; + nsCOMPtr selection; + mTree->GetSelection(getter_AddRefs(selection)); + if (selection) + selection->SelectAll(); + } + } + + return NS_OK; +} + // Get the nsITreeBoxObject interface from any levels DOMNode under the void nsXULTreeAccessible::GetTreeBoxObject(nsIDOMNode *aDOMNode, nsITreeBoxObject **aBoxObject) { diff --git a/accessible/src/xul/nsXULTreeAccessible.h b/accessible/src/xul/nsXULTreeAccessible.h index dd4b2d8346d8..e04b3cabe992 100644 --- a/accessible/src/xul/nsXULTreeAccessible.h +++ b/accessible/src/xul/nsXULTreeAccessible.h @@ -42,17 +42,16 @@ #include "nsAccessible.h" #include "nsBaseWidgetAccessible.h" #include "nsCOMPtr.h" -#include "nsIAccessibleSelectable.h" #include "nsIDOMNode.h" #include "nsIWeakReference.h" #include "nsITreeBoxObject.h" #include "nsITreeView.h" +#include "nsXULSelectAccessible.h" /* * A class the represents the XUL Tree widget. */ -class nsXULTreeAccessible : public nsAccessible, - public nsIAccessibleSelectable +class nsXULTreeAccessible : public nsXULSelectableAccessible { public: NS_DECL_ISUPPORTS_INHERITED @@ -75,6 +74,8 @@ public: private: nsCOMPtr mTree; nsCOMPtr mTreeView; + + NS_IMETHOD ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState); }; /**