1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/accessible/src/xul/XULSelectControlAccessible.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,265 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "XULSelectControlAccessible.h" 1.11 + 1.12 +#include "nsAccessibilityService.h" 1.13 +#include "DocAccessible.h" 1.14 + 1.15 +#include "nsIDOMXULContainerElement.h" 1.16 +#include "nsIDOMXULSelectCntrlItemEl.h" 1.17 +#include "nsIDOMXULMultSelectCntrlEl.h" 1.18 +#include "nsIDOMKeyEvent.h" 1.19 +#include "nsIDOMElement.h" 1.20 +#include "nsIDOMXULElement.h" 1.21 +#include "nsIMutableArray.h" 1.22 +#include "nsIServiceManager.h" 1.23 + 1.24 +#include "mozilla/dom/Element.h" 1.25 + 1.26 +using namespace mozilla; 1.27 +using namespace mozilla::a11y; 1.28 + 1.29 +//////////////////////////////////////////////////////////////////////////////// 1.30 +// XULSelectControlAccessible 1.31 +//////////////////////////////////////////////////////////////////////////////// 1.32 + 1.33 +XULSelectControlAccessible:: 1.34 + XULSelectControlAccessible(nsIContent* aContent, DocAccessible* aDoc) : 1.35 + AccessibleWrap(aContent, aDoc) 1.36 +{ 1.37 + mGenericTypes |= eSelect; 1.38 + mSelectControl = do_QueryInterface(aContent); 1.39 +} 1.40 + 1.41 +//////////////////////////////////////////////////////////////////////////////// 1.42 +// XULSelectControlAccessible: Accessible 1.43 + 1.44 +void 1.45 +XULSelectControlAccessible::Shutdown() 1.46 +{ 1.47 + mSelectControl = nullptr; 1.48 + AccessibleWrap::Shutdown(); 1.49 +} 1.50 + 1.51 +//////////////////////////////////////////////////////////////////////////////// 1.52 +// XULSelectControlAccessible: SelectAccessible 1.53 + 1.54 +already_AddRefed<nsIArray> 1.55 +XULSelectControlAccessible::SelectedItems() 1.56 +{ 1.57 + nsCOMPtr<nsIMutableArray> selectedItems = 1.58 + do_CreateInstance(NS_ARRAY_CONTRACTID); 1.59 + if (!selectedItems || !mDoc) 1.60 + return nullptr; 1.61 + 1.62 + // For XUL multi-select control 1.63 + nsCOMPtr<nsIDOMXULMultiSelectControlElement> xulMultiSelect = 1.64 + do_QueryInterface(mSelectControl); 1.65 + if (xulMultiSelect) { 1.66 + int32_t length = 0; 1.67 + xulMultiSelect->GetSelectedCount(&length); 1.68 + for (int32_t index = 0; index < length; index++) { 1.69 + nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm; 1.70 + xulMultiSelect->MultiGetSelectedItem(index, getter_AddRefs(itemElm)); 1.71 + nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm)); 1.72 + Accessible* item = mDoc->GetAccessible(itemNode); 1.73 + if (item) 1.74 + selectedItems->AppendElement(static_cast<nsIAccessible*>(item), 1.75 + false); 1.76 + } 1.77 + } else { // Single select? 1.78 + nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm; 1.79 + mSelectControl->GetSelectedItem(getter_AddRefs(itemElm)); 1.80 + nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm)); 1.81 + if (itemNode) { 1.82 + Accessible* item = mDoc->GetAccessible(itemNode); 1.83 + if (item) 1.84 + selectedItems->AppendElement(static_cast<nsIAccessible*>(item), 1.85 + false); 1.86 + } 1.87 + } 1.88 + 1.89 + return selectedItems.forget(); 1.90 +} 1.91 + 1.92 +Accessible* 1.93 +XULSelectControlAccessible::GetSelectedItem(uint32_t aIndex) 1.94 +{ 1.95 + nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl = 1.96 + do_QueryInterface(mSelectControl); 1.97 + 1.98 + nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm; 1.99 + if (multiSelectControl) 1.100 + multiSelectControl->MultiGetSelectedItem(aIndex, getter_AddRefs(itemElm)); 1.101 + else if (aIndex == 0) 1.102 + mSelectControl->GetSelectedItem(getter_AddRefs(itemElm)); 1.103 + 1.104 + nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm)); 1.105 + return itemNode && mDoc ? mDoc->GetAccessible(itemNode) : nullptr; 1.106 +} 1.107 + 1.108 +uint32_t 1.109 +XULSelectControlAccessible::SelectedItemCount() 1.110 +{ 1.111 + // For XUL multi-select control 1.112 + nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl = 1.113 + do_QueryInterface(mSelectControl); 1.114 + if (multiSelectControl) { 1.115 + int32_t count = 0; 1.116 + multiSelectControl->GetSelectedCount(&count); 1.117 + return count; 1.118 + } 1.119 + 1.120 + // For XUL single-select control/menulist 1.121 + int32_t index; 1.122 + mSelectControl->GetSelectedIndex(&index); 1.123 + return (index >= 0) ? 1 : 0; 1.124 +} 1.125 + 1.126 +bool 1.127 +XULSelectControlAccessible::AddItemToSelection(uint32_t aIndex) 1.128 +{ 1.129 + Accessible* item = GetChildAt(aIndex); 1.130 + if (!item) 1.131 + return false; 1.132 + 1.133 + nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm = 1.134 + do_QueryInterface(item->GetContent()); 1.135 + if (!itemElm) 1.136 + return false; 1.137 + 1.138 + bool isItemSelected = false; 1.139 + itemElm->GetSelected(&isItemSelected); 1.140 + if (isItemSelected) 1.141 + return true; 1.142 + 1.143 + nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl = 1.144 + do_QueryInterface(mSelectControl); 1.145 + 1.146 + if (multiSelectControl) 1.147 + multiSelectControl->AddItemToSelection(itemElm); 1.148 + else 1.149 + mSelectControl->SetSelectedItem(itemElm); 1.150 + 1.151 + return true; 1.152 +} 1.153 + 1.154 +bool 1.155 +XULSelectControlAccessible::RemoveItemFromSelection(uint32_t aIndex) 1.156 +{ 1.157 + Accessible* item = GetChildAt(aIndex); 1.158 + if (!item) 1.159 + return false; 1.160 + 1.161 + nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm = 1.162 + do_QueryInterface(item->GetContent()); 1.163 + if (!itemElm) 1.164 + return false; 1.165 + 1.166 + bool isItemSelected = false; 1.167 + itemElm->GetSelected(&isItemSelected); 1.168 + if (!isItemSelected) 1.169 + return true; 1.170 + 1.171 + nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl = 1.172 + do_QueryInterface(mSelectControl); 1.173 + 1.174 + if (multiSelectControl) 1.175 + multiSelectControl->RemoveItemFromSelection(itemElm); 1.176 + else 1.177 + mSelectControl->SetSelectedItem(nullptr); 1.178 + 1.179 + return true; 1.180 +} 1.181 + 1.182 +bool 1.183 +XULSelectControlAccessible::IsItemSelected(uint32_t aIndex) 1.184 +{ 1.185 + Accessible* item = GetChildAt(aIndex); 1.186 + if (!item) 1.187 + return false; 1.188 + 1.189 + nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm = 1.190 + do_QueryInterface(item->GetContent()); 1.191 + if (!itemElm) 1.192 + return false; 1.193 + 1.194 + bool isItemSelected = false; 1.195 + itemElm->GetSelected(&isItemSelected); 1.196 + return isItemSelected; 1.197 +} 1.198 + 1.199 +bool 1.200 +XULSelectControlAccessible::UnselectAll() 1.201 +{ 1.202 + nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl = 1.203 + do_QueryInterface(mSelectControl); 1.204 + multiSelectControl ? 1.205 + multiSelectControl->ClearSelection() : mSelectControl->SetSelectedIndex(-1); 1.206 + 1.207 + return true; 1.208 +} 1.209 + 1.210 +bool 1.211 +XULSelectControlAccessible::SelectAll() 1.212 +{ 1.213 + nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl = 1.214 + do_QueryInterface(mSelectControl); 1.215 + if (multiSelectControl) { 1.216 + multiSelectControl->SelectAll(); 1.217 + return true; 1.218 + } 1.219 + 1.220 + // otherwise, don't support this method 1.221 + return false; 1.222 +} 1.223 + 1.224 +//////////////////////////////////////////////////////////////////////////////// 1.225 +// XULSelectControlAccessible: Widgets 1.226 + 1.227 +Accessible* 1.228 +XULSelectControlAccessible::CurrentItem() 1.229 +{ 1.230 + if (!mSelectControl) 1.231 + return nullptr; 1.232 + 1.233 + nsCOMPtr<nsIDOMXULSelectControlItemElement> currentItemElm; 1.234 + nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl = 1.235 + do_QueryInterface(mSelectControl); 1.236 + if (multiSelectControl) 1.237 + multiSelectControl->GetCurrentItem(getter_AddRefs(currentItemElm)); 1.238 + else 1.239 + mSelectControl->GetSelectedItem(getter_AddRefs(currentItemElm)); 1.240 + 1.241 + nsCOMPtr<nsINode> DOMNode; 1.242 + if (currentItemElm) 1.243 + DOMNode = do_QueryInterface(currentItemElm); 1.244 + 1.245 + if (DOMNode) { 1.246 + DocAccessible* document = Document(); 1.247 + if (document) 1.248 + return document->GetAccessible(DOMNode); 1.249 + } 1.250 + 1.251 + return nullptr; 1.252 +} 1.253 + 1.254 +void 1.255 +XULSelectControlAccessible::SetCurrentItem(Accessible* aItem) 1.256 +{ 1.257 + if (!mSelectControl) 1.258 + return; 1.259 + 1.260 + nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm = 1.261 + do_QueryInterface(aItem->GetContent()); 1.262 + nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl = 1.263 + do_QueryInterface(mSelectControl); 1.264 + if (multiSelectControl) 1.265 + multiSelectControl->SetCurrentItem(itemElm); 1.266 + else 1.267 + mSelectControl->SetSelectedItem(itemElm); 1.268 +}