1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=2 et sw=2 tw=80: */
3 : /* ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is mozilla.org code.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Mozilla Foundation.
20 : * Portions created by the Initial Developer are Copyright (C) 2012
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Jignesh Kakadiya (jigneshhk1992@gmail.com)
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either of the GNU General Public License Version 2 or later (the "GPL"),
28 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #include "XULSelectControlAccessible.h"
41 :
42 : #include "nsAccessibilityService.h"
43 : #include "nsDocAccessible.h"
44 :
45 : #include "nsIDOMXULContainerElement.h"
46 : #include "nsIDOMXULSelectCntrlItemEl.h"
47 : #include "nsIDOMXULMultSelectCntrlEl.h"
48 : #include "nsIDOMKeyEvent.h"
49 : #include "nsIDOMElement.h"
50 : #include "nsIDOMXULElement.h"
51 : #include "nsIMutableArray.h"
52 : #include "nsIServiceManager.h"
53 :
54 : #include "mozilla/dom/Element.h"
55 :
56 : using namespace mozilla;
57 : using namespace mozilla::a11y;
58 :
59 : ////////////////////////////////////////////////////////////////////////////////
60 : // XULSelectControlAccessible
61 : ////////////////////////////////////////////////////////////////////////////////
62 :
63 0 : XULSelectControlAccessible::
64 : XULSelectControlAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
65 0 : nsAccessibleWrap(aContent, aDoc)
66 : {
67 0 : mSelectControl = do_QueryInterface(aContent);
68 0 : }
69 :
70 : ////////////////////////////////////////////////////////////////////////////////
71 : // XULSelectControlAccessible: nsAccessNode
72 :
73 : void
74 0 : XULSelectControlAccessible::Shutdown()
75 : {
76 0 : mSelectControl = nsnull;
77 0 : nsAccessibleWrap::Shutdown();
78 0 : }
79 :
80 : ////////////////////////////////////////////////////////////////////////////////
81 : // XULSelectControlAccessible: SelectAccessible
82 :
83 : bool
84 0 : XULSelectControlAccessible::IsSelect()
85 : {
86 0 : return !!mSelectControl;
87 : }
88 :
89 : // Interface methods
90 : already_AddRefed<nsIArray>
91 0 : XULSelectControlAccessible::SelectedItems()
92 : {
93 : nsCOMPtr<nsIMutableArray> selectedItems =
94 0 : do_CreateInstance(NS_ARRAY_CONTRACTID);
95 0 : if (!selectedItems || !mDoc)
96 0 : return nsnull;
97 :
98 : // For XUL multi-select control
99 : nsCOMPtr<nsIDOMXULMultiSelectControlElement> xulMultiSelect =
100 0 : do_QueryInterface(mSelectControl);
101 0 : if (xulMultiSelect) {
102 0 : PRInt32 length = 0;
103 0 : xulMultiSelect->GetSelectedCount(&length);
104 0 : for (PRInt32 index = 0; index < length; index++) {
105 0 : nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm;
106 0 : xulMultiSelect->GetSelectedItem(index, getter_AddRefs(itemElm));
107 0 : nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm));
108 0 : nsAccessible* item = mDoc->GetAccessible(itemNode);
109 0 : if (item)
110 0 : selectedItems->AppendElement(static_cast<nsIAccessible*>(item),
111 0 : false);
112 : }
113 : } else { // Single select?
114 0 : nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm;
115 0 : mSelectControl->GetSelectedItem(getter_AddRefs(itemElm));
116 0 : nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm));
117 0 : if(itemNode) {
118 0 : nsAccessible* item = mDoc->GetAccessible(itemNode);
119 0 : if (item)
120 0 : selectedItems->AppendElement(static_cast<nsIAccessible*>(item),
121 0 : false);
122 : }
123 : }
124 :
125 0 : nsIMutableArray* items = nsnull;
126 0 : selectedItems.forget(&items);
127 0 : return items;
128 : }
129 :
130 : nsAccessible*
131 0 : XULSelectControlAccessible::GetSelectedItem(PRUint32 aIndex)
132 : {
133 : nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
134 0 : do_QueryInterface(mSelectControl);
135 :
136 0 : nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm;
137 0 : if (multiSelectControl)
138 0 : multiSelectControl->GetSelectedItem(aIndex, getter_AddRefs(itemElm));
139 0 : else if (aIndex == 0)
140 0 : mSelectControl->GetSelectedItem(getter_AddRefs(itemElm));
141 :
142 0 : nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm));
143 0 : return itemNode && mDoc ? mDoc->GetAccessible(itemNode) : nsnull;
144 : }
145 :
146 : PRUint32
147 0 : XULSelectControlAccessible::SelectedItemCount()
148 : {
149 : // For XUL multi-select control
150 : nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
151 0 : do_QueryInterface(mSelectControl);
152 0 : if (multiSelectControl) {
153 0 : PRInt32 count = 0;
154 0 : multiSelectControl->GetSelectedCount(&count);
155 0 : return count;
156 : }
157 :
158 : // For XUL single-select control/menulist
159 : PRInt32 index;
160 0 : mSelectControl->GetSelectedIndex(&index);
161 0 : return (index >= 0) ? 1 : 0;
162 : }
163 :
164 : bool
165 0 : XULSelectControlAccessible::AddItemToSelection(PRUint32 aIndex)
166 : {
167 0 : nsAccessible* item = GetChildAt(aIndex);
168 0 : if (!item)
169 0 : return false;
170 :
171 : nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
172 0 : do_QueryInterface(item->GetContent());
173 0 : if (!itemElm)
174 0 : return false;
175 :
176 0 : bool isItemSelected = false;
177 0 : itemElm->GetSelected(&isItemSelected);
178 0 : if (isItemSelected)
179 0 : return true;
180 :
181 : nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
182 0 : do_QueryInterface(mSelectControl);
183 :
184 0 : if (multiSelectControl)
185 0 : multiSelectControl->AddItemToSelection(itemElm);
186 : else
187 0 : mSelectControl->SetSelectedItem(itemElm);
188 :
189 0 : return true;
190 : }
191 :
192 : bool
193 0 : XULSelectControlAccessible::RemoveItemFromSelection(PRUint32 aIndex)
194 : {
195 0 : nsAccessible* item = GetChildAt(aIndex);
196 0 : if (!item)
197 0 : return false;
198 :
199 : nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
200 0 : do_QueryInterface(item->GetContent());
201 0 : if (!itemElm)
202 0 : return false;
203 :
204 0 : bool isItemSelected = false;
205 0 : itemElm->GetSelected(&isItemSelected);
206 0 : if (!isItemSelected)
207 0 : return true;
208 :
209 : nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
210 0 : do_QueryInterface(mSelectControl);
211 :
212 0 : if (multiSelectControl)
213 0 : multiSelectControl->RemoveItemFromSelection(itemElm);
214 : else
215 0 : mSelectControl->SetSelectedItem(nsnull);
216 :
217 0 : return true;
218 : }
219 :
220 : bool
221 0 : XULSelectControlAccessible::IsItemSelected(PRUint32 aIndex)
222 : {
223 0 : nsAccessible* item = GetChildAt(aIndex);
224 0 : if (!item)
225 0 : return false;
226 :
227 : nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
228 0 : do_QueryInterface(item->GetContent());
229 0 : if (!itemElm)
230 0 : return false;
231 :
232 0 : bool isItemSelected = false;
233 0 : itemElm->GetSelected(&isItemSelected);
234 0 : return isItemSelected;
235 : }
236 :
237 : bool
238 0 : XULSelectControlAccessible::UnselectAll()
239 : {
240 : nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
241 0 : do_QueryInterface(mSelectControl);
242 : multiSelectControl ?
243 0 : multiSelectControl->ClearSelection() : mSelectControl->SetSelectedIndex(-1);
244 :
245 0 : return true;
246 : }
247 :
248 : bool
249 0 : XULSelectControlAccessible::SelectAll()
250 : {
251 : nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
252 0 : do_QueryInterface(mSelectControl);
253 0 : if (multiSelectControl) {
254 0 : multiSelectControl->SelectAll();
255 0 : return true;
256 : }
257 :
258 : // otherwise, don't support this method
259 0 : return false;
260 : }
261 :
262 : ////////////////////////////////////////////////////////////////////////////////
263 : // XULSelectControlAccessible: Widgets
264 :
265 : nsAccessible*
266 0 : XULSelectControlAccessible::CurrentItem()
267 : {
268 0 : if (!mSelectControl)
269 0 : return nsnull;
270 :
271 0 : nsCOMPtr<nsIDOMXULSelectControlItemElement> currentItemElm;
272 : nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
273 0 : do_QueryInterface(mSelectControl);
274 0 : if (multiSelectControl)
275 0 : multiSelectControl->GetCurrentItem(getter_AddRefs(currentItemElm));
276 : else
277 0 : mSelectControl->GetSelectedItem(getter_AddRefs(currentItemElm));
278 :
279 0 : nsCOMPtr<nsINode> DOMNode;
280 0 : if (currentItemElm)
281 0 : DOMNode = do_QueryInterface(currentItemElm);
282 :
283 0 : if (DOMNode) {
284 0 : nsDocAccessible* document = Document();
285 0 : if (document)
286 0 : return document->GetAccessible(DOMNode);
287 : }
288 :
289 0 : return nsnull;
290 : }
291 :
292 : void
293 0 : XULSelectControlAccessible::SetCurrentItem(nsAccessible* aItem)
294 : {
295 0 : if (!mSelectControl)
296 0 : return;
297 :
298 : nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
299 0 : do_QueryInterface(aItem->GetContent());
300 : nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
301 0 : do_QueryInterface(mSelectControl);
302 0 : if (multiSelectControl)
303 0 : multiSelectControl->SetCurrentItem(itemElm);
304 : else
305 0 : mSelectControl->SetSelectedItem(itemElm);
306 : }
|