4#include <QtGui/qtguiglobal.h>
5#if QT_CONFIG(accessibility)
7#include "qwindowsuiaselectionprovider.h"
8#include "qwindowsuiamainprovider.h"
9#include "qwindowsuiautils.h"
10#include "qwindowscontext.h"
12#include <QtGui/qaccessible.h>
13#include <QtCore/qloggingcategory.h>
14#include <QtCore/qstring.h>
15#include <QtCore/qlist.h>
19using namespace QWindowsUiAutomation;
22QWindowsUiaSelectionProvider::QWindowsUiaSelectionProvider(QAccessible::Id id) :
23 QWindowsUiaBaseProvider(id)
27QWindowsUiaSelectionProvider::~QWindowsUiaSelectionProvider()
32HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::GetSelection(SAFEARRAY **pRetVal)
34 qCDebug(lcQpaUiAutomation) <<
__FUNCTION__;
40 QAccessibleInterface *accessible = accessibleInterface();
42 return UIA_E_ELEMENTNOTAVAILABLE;
45 QList<QAccessibleInterface *> selectedList;
46 if (QAccessibleSelectionInterface *selectionInterface = accessible->selectionInterface()) {
47 selectedList = selectionInterface->selectedItems();
49 const int childCount = accessible->childCount();
50 selectedList.reserve(childCount);
51 for (
int i = 0; i < childCount; ++i) {
52 if (QAccessibleInterface *child = accessible->child(i)) {
53 if (accessible->role() == QAccessible::PageTabList) {
54 if (child->role() == QAccessible::PageTab && child->state().focused) {
55 selectedList.append(child);
58 if (child->state().selected) {
59 selectedList.append(child);
66 if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, selectedList.size()))) {
67 for (LONG i = 0; i < selectedList.size(); ++i) {
68 if (ComPtr<IRawElementProviderSimple> provider =
69 QWindowsUiaMainProvider::providerForAccessible(selectedList.at(i))) {
70 SafeArrayPutElement(*pRetVal, &i, provider.Get());
77HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_CanSelectMultiple(BOOL *pRetVal)
79 qCDebug(lcQpaUiAutomation) <<
__FUNCTION__;
85 QAccessibleInterface *accessible = accessibleInterface();
87 return UIA_E_ELEMENTNOTAVAILABLE;
89 *pRetVal = accessible->state().multiSelectable;
93HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_IsSelectionRequired(BOOL *pRetVal)
95 qCDebug(lcQpaUiAutomation) <<
__FUNCTION__;
101 QAccessibleInterface *accessible = accessibleInterface();
103 return UIA_E_ELEMENTNOTAVAILABLE;
105 if (accessible->role() == QAccessible::PageTabList) {
110 bool anySelected =
false;
111 if (QAccessibleSelectionInterface *selectionInterface = accessible->selectionInterface()) {
112 anySelected = selectionInterface->selectedItem(0) !=
nullptr;
114 for (
int i = 0; i < accessible->childCount(); ++i) {
115 if (QAccessibleInterface *child = accessible->child(i)) {
116 if (child->state().selected) {
124 *pRetVal = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable;
129HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_FirstSelectedItem(__RPC__deref_out_opt IRawElementProviderSimple **pRetVal)
131 qCDebug(lcQpaUiAutomation) <<
__FUNCTION__;
137 QAccessibleInterface *accessible = accessibleInterface();
139 return UIA_E_ELEMENTNOTAVAILABLE;
141 QAccessibleInterface *firstSelectedChild =
nullptr;
142 if (QAccessibleSelectionInterface *selectionInterface = accessible->selectionInterface()) {
143 firstSelectedChild = selectionInterface->selectedItem(0);
144 if (!firstSelectedChild)
145 return UIA_E_ELEMENTNOTAVAILABLE;
148 while (!firstSelectedChild && i < accessible->childCount()) {
149 if (QAccessibleInterface *child = accessible->child(i)) {
150 if (accessible->role() == QAccessible::PageTabList) {
151 if (child->role() == QAccessible::PageTab && child->state().focused)
152 firstSelectedChild = child;
153 }
else if (child->state().selected) {
154 firstSelectedChild = child;
161 if (!firstSelectedChild)
162 return UIA_E_ELEMENTNOTAVAILABLE;
164 if (ComPtr<IRawElementProviderSimple> childProvider =
165 QWindowsUiaMainProvider::providerForAccessible(firstSelectedChild)) {
166 *pRetVal = childProvider.Detach();
173HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_LastSelectedItem(__RPC__deref_out_opt IRawElementProviderSimple **pRetVal)
175 qCDebug(lcQpaUiAutomation) <<
__FUNCTION__;
181 QAccessibleInterface *accessible = accessibleInterface();
183 return UIA_E_ELEMENTNOTAVAILABLE;
185 QAccessibleInterface *lastSelectedChild =
nullptr;
186 if (QAccessibleSelectionInterface *selectionInterface = accessible->selectionInterface()) {
187 const int selectedItemCount = selectionInterface->selectedItemCount();
188 if (selectedItemCount <= 0)
189 return UIA_E_ELEMENTNOTAVAILABLE;
190 lastSelectedChild = selectionInterface->selectedItem(selectedItemCount - 1);
192 int i = accessible->childCount() - 1;
193 while (!lastSelectedChild && i >= 0) {
194 if (QAccessibleInterface *child = accessible->child(i)) {
195 if (accessible->role() == QAccessible::PageTabList) {
196 if (child->role() == QAccessible::PageTab && child->state().focused)
197 lastSelectedChild = child;
198 }
else if (child->state().selected) {
199 lastSelectedChild = child;
206 if (!lastSelectedChild)
207 return UIA_E_ELEMENTNOTAVAILABLE;
209 if (ComPtr<IRawElementProviderSimple> childProvider =
210 QWindowsUiaMainProvider::providerForAccessible(lastSelectedChild)) {
211 *pRetVal = childProvider.Detach();
218HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_CurrentSelectedItem(__RPC__deref_out_opt IRawElementProviderSimple **pRetVal)
220 qCDebug(lcQpaUiAutomation) <<
__FUNCTION__;
221 return get_FirstSelectedItem(pRetVal);
224HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_ItemCount(__RPC__out
int *pRetVal)
226 qCDebug(lcQpaUiAutomation) <<
__FUNCTION__;
232 QAccessibleInterface *accessible = accessibleInterface();
234 return UIA_E_ELEMENTNOTAVAILABLE;
237 if (QAccessibleSelectionInterface *selectionInterface = accessible->selectionInterface())
238 *pRetVal = selectionInterface->selectedItemCount();
240 int selectedCount = 0;
241 for (
int i = 0; i < accessible->childCount(); i++) {
242 if (QAccessibleInterface *child = accessible->child(i)) {
243 if (accessible->role() == QAccessible::PageTabList) {
244 if (child->role() == QAccessible::PageTab && child->state().focused)
246 }
else if (child->state().selected) {
251 *pRetVal = selectedCount;