Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qwindowsuiaselectionprovider.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <QtGui/qtguiglobal.h>
5#if QT_CONFIG(accessibility)
6
9#include "qwindowsuiautils.h"
10#include "qwindowscontext.h"
11
12#include <QtGui/qaccessible.h>
13#include <QtCore/qloggingcategory.h>
14#include <QtCore/qstring.h>
15#include <QtCore/qlist.h>
16
18
19using namespace QWindowsUiAutomation;
20
21
22QWindowsUiaSelectionProvider::QWindowsUiaSelectionProvider(QAccessible::Id id) :
23 QWindowsUiaBaseProvider(id)
24{
25}
26
27QWindowsUiaSelectionProvider::~QWindowsUiaSelectionProvider()
28{
29}
30
31// Returns an array of providers with the selected items.
32HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::GetSelection(SAFEARRAY **pRetVal)
33{
34 qCDebug(lcQpaUiAutomation) << __FUNCTION__;
35
36 if (!pRetVal)
37 return E_INVALIDARG;
38 *pRetVal = nullptr;
39
40 QAccessibleInterface *accessible = accessibleInterface();
41 if (!accessible)
42 return UIA_E_ELEMENTNOTAVAILABLE;
43
44 // First get/create list of selected items, then build a safe array with the right size.
45 QList<QAccessibleInterface *> selectedList;
46 if (QAccessibleSelectionInterface *selectionInterface = accessible->selectionInterface()) {
47 selectedList = selectionInterface->selectedItems();
48 } else {
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);
56 }
57 } else {
58 if (child->state().selected) {
59 selectedList.append(child);
60 }
61 }
62 }
63 }
64 }
65
66 if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, selectedList.size()))) {
67 for (LONG i = 0; i < selectedList.size(); ++i) {
68 if (QWindowsUiaMainProvider *childProvider = QWindowsUiaMainProvider::providerForAccessible(selectedList.at(i))) {
69 SafeArrayPutElement(*pRetVal, &i, static_cast<IRawElementProviderSimple *>(childProvider));
70 childProvider->Release();
71 }
72 }
73 }
74 return S_OK;
75}
76
77HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_CanSelectMultiple(BOOL *pRetVal)
78{
79 qCDebug(lcQpaUiAutomation) << __FUNCTION__;
80
81 if (!pRetVal)
82 return E_INVALIDARG;
83 *pRetVal = FALSE;
84
85 QAccessibleInterface *accessible = accessibleInterface();
86 if (!accessible)
87 return UIA_E_ELEMENTNOTAVAILABLE;
88
89 *pRetVal = accessible->state().multiSelectable;
90 return S_OK;
91}
92
93HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_IsSelectionRequired(BOOL *pRetVal)
94{
95 qCDebug(lcQpaUiAutomation) << __FUNCTION__;
96
97 if (!pRetVal)
98 return E_INVALIDARG;
99 *pRetVal = FALSE;
100
101 QAccessibleInterface *accessible = accessibleInterface();
102 if (!accessible)
103 return UIA_E_ELEMENTNOTAVAILABLE;
104
105 if (accessible->role() == QAccessible::PageTabList) {
106 *pRetVal = TRUE;
107 } else {
108
109 // Initially returns false if none are selected. After the first selection, it may be required.
110 bool anySelected = false;
111 if (QAccessibleSelectionInterface *selectionInterface = accessible->selectionInterface()) {
112 anySelected = selectionInterface->selectedItem(0) != nullptr;
113 } else {
114 for (int i = 0; i < accessible->childCount(); ++i) {
115 if (QAccessibleInterface *child = accessible->child(i)) {
116 if (child->state().selected) {
117 anySelected = true;
118 break;
119 }
120 }
121 }
122 }
123
124 *pRetVal = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable;
125 }
126 return S_OK;
127}
128
129HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_FirstSelectedItem(__RPC__deref_out_opt IRawElementProviderSimple **pRetVal)
130{
131 qCDebug(lcQpaUiAutomation) << __FUNCTION__;
132
133 if (!pRetVal)
134 return E_INVALIDARG;
135 *pRetVal = nullptr;
136
137 QAccessibleInterface *accessible = accessibleInterface();
138 if (!accessible)
139 return UIA_E_ELEMENTNOTAVAILABLE;
140
141 QAccessibleInterface *firstSelectedChild = nullptr;
142 if (QAccessibleSelectionInterface *selectionInterface = accessible->selectionInterface()) {
143 firstSelectedChild = selectionInterface->selectedItem(0);
144 if (!firstSelectedChild)
145 return UIA_E_ELEMENTNOTAVAILABLE;
146 } else {
147 int i = 0;
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;
155 }
156 }
157 i++;
158 }
159 }
160
161 if (!firstSelectedChild)
162 return UIA_E_ELEMENTNOTAVAILABLE;
163
164 if (QWindowsUiaMainProvider *childProvider = QWindowsUiaMainProvider::providerForAccessible(firstSelectedChild))
165 {
166 *pRetVal = static_cast<IRawElementProviderSimple *>(childProvider);
167 return S_OK;
168 }
169
170 return S_FALSE;
171}
172
173HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_LastSelectedItem(__RPC__deref_out_opt IRawElementProviderSimple **pRetVal)
174{
175 qCDebug(lcQpaUiAutomation) << __FUNCTION__;
176
177 if (!pRetVal)
178 return E_INVALIDARG;
179 *pRetVal = nullptr;
180
181 QAccessibleInterface *accessible = accessibleInterface();
182 if (!accessible)
183 return UIA_E_ELEMENTNOTAVAILABLE;
184
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);
191 } else {
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;
200 }
201 }
202 i--;
203 }
204 }
205
206 if (!lastSelectedChild)
207 return UIA_E_ELEMENTNOTAVAILABLE;
208
209 if (QWindowsUiaMainProvider *childProvider = QWindowsUiaMainProvider::providerForAccessible(lastSelectedChild))
210 {
211 *pRetVal = static_cast<IRawElementProviderSimple *>(childProvider);
212 return S_OK;
213 }
214
215 return S_FALSE;
216}
217
218HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_CurrentSelectedItem(__RPC__deref_out_opt IRawElementProviderSimple **pRetVal)
219{
220 qCDebug(lcQpaUiAutomation) << __FUNCTION__;
221 return get_FirstSelectedItem(pRetVal);
222}
223
224HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_ItemCount(__RPC__out int *pRetVal)
225{
226 qCDebug(lcQpaUiAutomation) << __FUNCTION__;
227
228 if (!pRetVal)
229 return E_INVALIDARG;
230 *pRetVal = -1;
231
232 QAccessibleInterface *accessible = accessibleInterface();
233 if (!accessible)
234 return UIA_E_ELEMENTNOTAVAILABLE;
235
236
237 if (QAccessibleSelectionInterface *selectionInterface = accessible->selectionInterface())
238 *pRetVal = selectionInterface->selectedItemCount();
239 else {
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)
245 selectedCount++;
246 } else if (child->state().selected) {
247 selectedCount++;
248 }
249 }
250 }
251 *pRetVal = selectedCount;
252 }
253
254 return S_OK;
255}
256
258
259#endif // QT_CONFIG(accessibility)
Combined button and popup list for selecting options.
#define qCDebug(category,...)
GLenum GLuint id
[7]
long HRESULT
QLayoutItem * child
[0]