5#include <QtGui/qtguiglobal.h>
6#if QT_CONFIG(accessibility)
8#include "qwindowsuiaselectionprovider.h"
9#include "qwindowsuiamainprovider.h"
10#include "qwindowsuiautils.h"
11#include "qwindowscontext.h"
13#include <QtGui/qaccessible.h>
14#include <QtCore/qloggingcategory.h>
15#include <QtCore/qstring.h>
16#include <QtCore/qlist.h>
20using namespace QWindowsUiAutomation;
23QWindowsUiaSelectionProvider::QWindowsUiaSelectionProvider(QAccessible::Id id) :
24 QWindowsUiaBaseProvider(id)
28QWindowsUiaSelectionProvider::~QWindowsUiaSelectionProvider()
33HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::GetSelection(SAFEARRAY **pRetVal)
35 qCDebug(lcQpaUiAutomation) <<
__FUNCTION__;
41 QAccessibleInterface *accessible = accessibleInterface();
43 return UIA_E_ELEMENTNOTAVAILABLE;
46 QList<QAccessibleInterface *> selectedList;
47 if (QAccessibleSelectionInterface *selectionInterface = accessible->selectionInterface()) {
48 selectedList = selectionInterface->selectedItems();
50 const int childCount = accessible->childCount();
51 selectedList.reserve(childCount);
52 for (
int i = 0; i < childCount; ++i) {
53 if (QAccessibleInterface *child = accessible->child(i)) {
54 if (accessible->role() == QAccessible::PageTabList) {
55 if (child->role() == QAccessible::PageTab && child->state().focused) {
56 selectedList.append(child);
59 if (child->state().selected) {
60 selectedList.append(child);
67 if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, selectedList.size()))) {
68 for (LONG i = 0; i < selectedList.size(); ++i) {
69 if (ComPtr<IRawElementProviderSimple> provider =
70 QWindowsUiaMainProvider::providerForAccessible(selectedList.at(i))) {
71 SafeArrayPutElement(*pRetVal, &i, provider.Get());
78HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_CanSelectMultiple(BOOL *pRetVal)
80 qCDebug(lcQpaUiAutomation) <<
__FUNCTION__;
86 QAccessibleInterface *accessible = accessibleInterface();
88 return UIA_E_ELEMENTNOTAVAILABLE;
90 *pRetVal = accessible->state().multiSelectable;
94HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_IsSelectionRequired(BOOL *pRetVal)
96 qCDebug(lcQpaUiAutomation) <<
__FUNCTION__;
102 QAccessibleInterface *accessible = accessibleInterface();
104 return UIA_E_ELEMENTNOTAVAILABLE;
106 if (accessible->role() == QAccessible::PageTabList) {
111 bool anySelected =
false;
112 if (QAccessibleSelectionInterface *selectionInterface = accessible->selectionInterface()) {
113 anySelected = selectionInterface->selectedItem(0) !=
nullptr;
115 for (
int i = 0; i < accessible->childCount(); ++i) {
116 if (QAccessibleInterface *child = accessible->child(i)) {
117 if (child->state().selected) {
125 *pRetVal = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable;
130HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_FirstSelectedItem(__RPC__deref_out_opt IRawElementProviderSimple **pRetVal)
132 qCDebug(lcQpaUiAutomation) <<
__FUNCTION__;
138 QAccessibleInterface *accessible = accessibleInterface();
140 return UIA_E_ELEMENTNOTAVAILABLE;
142 QAccessibleInterface *firstSelectedChild =
nullptr;
143 if (QAccessibleSelectionInterface *selectionInterface = accessible->selectionInterface()) {
144 firstSelectedChild = selectionInterface->selectedItem(0);
145 if (!firstSelectedChild)
146 return UIA_E_ELEMENTNOTAVAILABLE;
149 while (!firstSelectedChild && i < accessible->childCount()) {
150 if (QAccessibleInterface *child = accessible->child(i)) {
151 if (accessible->role() == QAccessible::PageTabList) {
152 if (child->role() == QAccessible::PageTab && child->state().focused)
153 firstSelectedChild = child;
154 }
else if (child->state().selected) {
155 firstSelectedChild = child;
162 if (!firstSelectedChild)
163 return UIA_E_ELEMENTNOTAVAILABLE;
165 if (ComPtr<IRawElementProviderSimple> childProvider =
166 QWindowsUiaMainProvider::providerForAccessible(firstSelectedChild)) {
167 *pRetVal = childProvider.Detach();
174HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_LastSelectedItem(__RPC__deref_out_opt IRawElementProviderSimple **pRetVal)
176 qCDebug(lcQpaUiAutomation) <<
__FUNCTION__;
182 QAccessibleInterface *accessible = accessibleInterface();
184 return UIA_E_ELEMENTNOTAVAILABLE;
186 QAccessibleInterface *lastSelectedChild =
nullptr;
187 if (QAccessibleSelectionInterface *selectionInterface = accessible->selectionInterface()) {
188 const int selectedItemCount = selectionInterface->selectedItemCount();
189 if (selectedItemCount <= 0)
190 return UIA_E_ELEMENTNOTAVAILABLE;
191 lastSelectedChild = selectionInterface->selectedItem(selectedItemCount - 1);
193 int i = accessible->childCount() - 1;
194 while (!lastSelectedChild && i >= 0) {
195 if (QAccessibleInterface *child = accessible->child(i)) {
196 if (accessible->role() == QAccessible::PageTabList) {
197 if (child->role() == QAccessible::PageTab && child->state().focused)
198 lastSelectedChild = child;
199 }
else if (child->state().selected) {
200 lastSelectedChild = child;
207 if (!lastSelectedChild)
208 return UIA_E_ELEMENTNOTAVAILABLE;
210 if (ComPtr<IRawElementProviderSimple> childProvider =
211 QWindowsUiaMainProvider::providerForAccessible(lastSelectedChild)) {
212 *pRetVal = childProvider.Detach();
219HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_CurrentSelectedItem(__RPC__deref_out_opt IRawElementProviderSimple **pRetVal)
221 qCDebug(lcQpaUiAutomation) <<
__FUNCTION__;
222 return get_FirstSelectedItem(pRetVal);
225HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_ItemCount(__RPC__out
int *pRetVal)
227 qCDebug(lcQpaUiAutomation) <<
__FUNCTION__;
233 QAccessibleInterface *accessible = accessibleInterface();
235 return UIA_E_ELEMENTNOTAVAILABLE;
238 if (QAccessibleSelectionInterface *selectionInterface = accessible->selectionInterface())
239 *pRetVal = selectionInterface->selectedItemCount();
241 int selectedCount = 0;
242 for (
int i = 0; i < accessible->childCount(); i++) {
243 if (QAccessibleInterface *child = accessible->child(i)) {
244 if (accessible->role() == QAccessible::PageTabList) {
245 if (child->role() == QAccessible::PageTab && child->state().focused)
247 }
else if (child->state().selected) {
252 *pRetVal = selectedCount;