Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qwindowsuiatextprovider.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
8#include "qwindowsuiautils.h"
9#include "qwindowscontext.h"
10
11#include <QtGui/qaccessible.h>
12#include <QtCore/qloggingcategory.h>
13#include <QtCore/qstring.h>
14
16
17using namespace QWindowsUiAutomation;
18
19
20QWindowsUiaTextProvider::QWindowsUiaTextProvider(QAccessible::Id id) :
21 QWindowsUiaBaseProvider(id)
22{
23}
24
25QWindowsUiaTextProvider::~QWindowsUiaTextProvider()
26{
27}
28
29HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::QueryInterface(REFIID iid, LPVOID *iface)
30{
31 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
32
33 if (!iface)
34 return E_INVALIDARG;
35 *iface = nullptr;
36
37 const bool result = qWindowsComQueryUnknownInterfaceMulti<ITextProvider>(this, iid, iface)
38 || qWindowsComQueryInterface<ITextProvider>(this, iid, iface)
39 || qWindowsComQueryInterface<ITextProvider2>(this, iid, iface);
40 return result ? S_OK : E_NOINTERFACE;
41}
42
43// Returns an array of providers for the selected text ranges.
44HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::GetSelection(SAFEARRAY **pRetVal)
45{
46 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
47
48 if (!pRetVal)
49 return E_INVALIDARG;
50 *pRetVal = nullptr;
51
52 QAccessibleInterface *accessible = accessibleInterface();
53 if (!accessible)
55
56 QAccessibleTextInterface *textInterface = accessible->textInterface();
57 if (!textInterface)
59
60 int selCount = textInterface->selectionCount();
61 if (selCount > 0) {
62 // Build a safe array with the text range providers.
63 if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, selCount))) {
64 for (LONG i = 0; i < selCount; ++i) {
65 int startOffset = 0, endOffset = 0;
66 textInterface->selection((int)i, &startOffset, &endOffset);
67 auto *textRangeProvider = new QWindowsUiaTextRangeProvider(id(), startOffset, endOffset);
68 SafeArrayPutElement(*pRetVal, &i, static_cast<IUnknown *>(textRangeProvider));
69 textRangeProvider->Release();
70 }
71 }
72 } else {
73 // If there is no selection, we return an array with a single degenerate (empty) text range at the cursor position.
74 if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, 1))) {
75 LONG i = 0;
76 int cursorPosition = textInterface->cursorPosition();
77 auto *textRangeProvider = new QWindowsUiaTextRangeProvider(id(), cursorPosition, cursorPosition);
78 SafeArrayPutElement(*pRetVal, &i, static_cast<IUnknown *>(textRangeProvider));
79 textRangeProvider->Release();
80 }
81 }
82 return S_OK;
83}
84
85// Returns an array of providers for the visible text ranges.
86HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::GetVisibleRanges(SAFEARRAY **pRetVal)
87{
88 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
89
90 if (!pRetVal)
91 return E_INVALIDARG;
92 *pRetVal = nullptr;
93
94 QAccessibleInterface *accessible = accessibleInterface();
95 if (!accessible)
97
98 QAccessibleTextInterface *textInterface = accessible->textInterface();
99 if (!textInterface)
101
102 // Considering the entire text as visible.
103 if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, 1))) {
104 LONG i = 0;
105 auto *textRangeProvider = new QWindowsUiaTextRangeProvider(id(), 0, textInterface->characterCount());
106 SafeArrayPutElement(*pRetVal, &i, static_cast<IUnknown *>(textRangeProvider));
107 textRangeProvider->Release();
108 }
109 return S_OK;
110}
111
112HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::RangeFromChild(IRawElementProviderSimple * /*childElement*/,
113 ITextRangeProvider **pRetVal)
114{
115 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
116
117 if (!pRetVal)
118 return E_INVALIDARG;
119 *pRetVal = nullptr;
120 // No children supported.
121 return S_OK;
122}
123
124// Returns a degenerate text range at the specified point.
125HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::RangeFromPoint(UiaPoint point, ITextRangeProvider **pRetVal)
126{
127 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
128
129 if (!pRetVal)
130 return E_INVALIDARG;
131 *pRetVal = nullptr;
132
133 QAccessibleInterface *accessible = accessibleInterface();
134 if (!accessible)
136
137 QAccessibleTextInterface *textInterface = accessible->textInterface();
138 if (!textInterface)
140
141 QWindow *window = windowForAccessible(accessible);
142 if (!window)
144
145 QPoint pt;
146 nativeUiaPointToPoint(point, window, &pt);
147
148 int offset = textInterface->offsetAtPoint(pt);
149 if ((offset >= 0) && (offset < textInterface->characterCount())) {
150 *pRetVal = new QWindowsUiaTextRangeProvider(id(), offset, offset);
151 }
152 return S_OK;
153}
154
155// Returns a text range provider for the entire text.
156HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::get_DocumentRange(ITextRangeProvider **pRetVal)
157{
158 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
159
160 if (!pRetVal)
161 return E_INVALIDARG;
162 *pRetVal = nullptr;
163
164 QAccessibleInterface *accessible = accessibleInterface();
165 if (!accessible)
167
168 QAccessibleTextInterface *textInterface = accessible->textInterface();
169 if (!textInterface)
171
172 *pRetVal = new QWindowsUiaTextRangeProvider(id(), 0, textInterface->characterCount());
173 return S_OK;
174}
175
176// Currently supporting single selection.
177HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::get_SupportedTextSelection(SupportedTextSelection *pRetVal)
178{
179 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
180
181 if (!pRetVal)
182 return E_INVALIDARG;
184 return S_OK;
185}
186
187// Not supporting annotations.
188HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::RangeFromAnnotation(IRawElementProviderSimple * /*annotationElement*/, ITextRangeProvider **pRetVal)
189{
190 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
191
192 if (!pRetVal)
193 return E_INVALIDARG;
194 *pRetVal = nullptr;
195 return S_OK;
196}
197
198HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::GetCaretRange(BOOL *isActive, ITextRangeProvider **pRetVal)
199{
200 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
201
202 if (!isActive || !pRetVal)
203 return E_INVALIDARG;
204 *isActive = FALSE;
205 *pRetVal = nullptr;
206
207 QAccessibleInterface *accessible = accessibleInterface();
208 if (!accessible)
210
211 QAccessibleTextInterface *textInterface = accessible->textInterface();
212 if (!textInterface)
214
215 *isActive = accessible->state().focused;
216
217 int cursorPosition = textInterface->cursorPosition();
218 *pRetVal = new QWindowsUiaTextRangeProvider(id(), cursorPosition, cursorPosition);
219 return S_OK;
220}
221
223
224#endif // QT_CONFIG(accessibility)
bool isActive
\inmodule QtCore\reentrant
Definition qpoint.h:23
\inmodule QtGui
Definition qwindow.h:63
Combined button and popup list for selecting options.
constexpr QBindableInterface iface
Definition qproperty.h:664
#define qCDebug(category,...)
GLenum GLuint id
[7]
GLenum GLuint GLintptr offset
GLuint64EXT * result
[6]
long HRESULT
aWidget window() -> setWindowTitle("New Window Title")
[2]
#define UIA_E_ELEMENTNOTAVAILABLE
IRawElementProviderFragment __RPC__deref_out_opt IRawElementProviderFragment ** pRetVal
SupportedTextSelection
Definition uiatypes_p.h:48
@ SupportedTextSelection_Single
Definition uiatypes_p.h:50