Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
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
7#include "qwindowsuiatextprovider.h"
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#include <QtCore/private/qcomptr_p.h>
15QT_BEGIN_NAMESPACE
16
17using namespace QWindowsUiAutomation;
18
19
20QWindowsUiaTextProvider::QWindowsUiaTextProvider(QAccessible::Id id) :
21 QWindowsUiaBaseProvider(id)
22{
23}
24
25QWindowsUiaTextProvider::~QWindowsUiaTextProvider()
26{
27}
28
29// Returns an array of providers for the selected text ranges.
30HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::GetSelection(SAFEARRAY **pRetVal)
31{
32 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
33
34 if (!pRetVal)
35 return E_INVALIDARG;
36 *pRetVal = nullptr;
37
38 QAccessibleInterface *accessible = accessibleInterface();
39 if (!accessible)
40 return UIA_E_ELEMENTNOTAVAILABLE;
41
42 QAccessibleTextInterface *textInterface = accessible->textInterface();
43 if (!textInterface)
44 return UIA_E_ELEMENTNOTAVAILABLE;
45
46 int selCount = textInterface->selectionCount();
47 if (selCount > 0) {
48 // Build a safe array with the text range providers.
49 if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, selCount))) {
50 for (LONG i = 0; i < selCount; ++i) {
51 int startOffset = 0, endOffset = 0;
52 textInterface->selection((int)i, &startOffset, &endOffset);
53 ComPtr<IUnknown> textRangeProvider =
54 makeComObject<QWindowsUiaTextRangeProvider>(id(), startOffset, endOffset);
55 SafeArrayPutElement(*pRetVal, &i, textRangeProvider.Get());
56 }
57 }
58 } else {
59 // If there is no selection, we return an array with a single degenerate (empty) text range at the cursor position.
60 if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, 1))) {
61 LONG i = 0;
62 int cursorPosition = textInterface->cursorPosition();
63 ComPtr<IUnknown> textRangeProvider = makeComObject<QWindowsUiaTextRangeProvider>(
64 id(), cursorPosition, cursorPosition);
65 SafeArrayPutElement(*pRetVal, &i, textRangeProvider.Get());
66 }
67 }
68 return S_OK;
69}
70
71// Returns an array of providers for the visible text ranges.
72HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::GetVisibleRanges(SAFEARRAY **pRetVal)
73{
74 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
75
76 if (!pRetVal)
77 return E_INVALIDARG;
78 *pRetVal = nullptr;
79
80 QAccessibleInterface *accessible = accessibleInterface();
81 if (!accessible)
82 return UIA_E_ELEMENTNOTAVAILABLE;
83
84 QAccessibleTextInterface *textInterface = accessible->textInterface();
85 if (!textInterface)
86 return UIA_E_ELEMENTNOTAVAILABLE;
87
88 // Considering the entire text as visible.
89 if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, 1))) {
90 LONG i = 0;
91 ComPtr<IUnknown> textRangeProvider =
92 makeComObject<QWindowsUiaTextRangeProvider>(id(), 0, textInterface->characterCount());
93 SafeArrayPutElement(*pRetVal, &i, textRangeProvider.Get());
94 }
95 return S_OK;
96}
97
98HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::RangeFromChild(IRawElementProviderSimple * /*childElement*/,
99 ITextRangeProvider **pRetVal)
100{
101 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
102
103 if (!pRetVal)
104 return E_INVALIDARG;
105 *pRetVal = nullptr;
106 // No children supported.
107 return S_OK;
108}
109
110// Returns a degenerate text range at the specified point.
111HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::RangeFromPoint(UiaPoint point, ITextRangeProvider **pRetVal)
112{
113 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
114
115 if (!pRetVal)
116 return E_INVALIDARG;
117 *pRetVal = nullptr;
118
119 QAccessibleInterface *accessible = accessibleInterface();
120 if (!accessible)
121 return UIA_E_ELEMENTNOTAVAILABLE;
122
123 QAccessibleTextInterface *textInterface = accessible->textInterface();
124 if (!textInterface)
125 return UIA_E_ELEMENTNOTAVAILABLE;
126
127 QWindow *window = windowForAccessible(accessible);
128 if (!window)
129 return UIA_E_ELEMENTNOTAVAILABLE;
130
131 QPoint pt;
132 nativeUiaPointToPoint(point, window, &pt);
133
134 int offset = textInterface->offsetAtPoint(pt);
135 if (offset < 0 || offset >= textInterface->characterCount())
136 return UIA_E_ELEMENTNOTAVAILABLE;
137
138 *pRetVal = makeComObject<QWindowsUiaTextRangeProvider>(id(), offset, offset).Detach();
139 return S_OK;
140}
141
142// Returns a text range provider for the entire text.
143HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::get_DocumentRange(ITextRangeProvider **pRetVal)
144{
145 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
146
147 if (!pRetVal)
148 return E_INVALIDARG;
149 *pRetVal = nullptr;
150
151 QAccessibleInterface *accessible = accessibleInterface();
152 if (!accessible)
153 return UIA_E_ELEMENTNOTAVAILABLE;
154
155 QAccessibleTextInterface *textInterface = accessible->textInterface();
156 if (!textInterface)
157 return UIA_E_ELEMENTNOTAVAILABLE;
158
159 *pRetVal = makeComObject<QWindowsUiaTextRangeProvider>(id(), 0, textInterface->characterCount())
160 .Detach();
161 return S_OK;
162}
163
164// Currently supporting single selection.
165HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::get_SupportedTextSelection(SupportedTextSelection *pRetVal)
166{
167 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
168
169 if (!pRetVal)
170 return E_INVALIDARG;
171 *pRetVal = SupportedTextSelection_Single;
172 return S_OK;
173}
174
175// Not supporting annotations.
176HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::RangeFromAnnotation(IRawElementProviderSimple * /*annotationElement*/, ITextRangeProvider **pRetVal)
177{
178 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
179
180 if (!pRetVal)
181 return E_INVALIDARG;
182 *pRetVal = nullptr;
183 return S_OK;
184}
185
186HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::GetCaretRange(BOOL *isActive, ITextRangeProvider **pRetVal)
187{
188 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
189
190 if (!isActive || !pRetVal)
191 return E_INVALIDARG;
192 *isActive = FALSE;
193 *pRetVal = nullptr;
194
195 QAccessibleInterface *accessible = accessibleInterface();
196 if (!accessible)
197 return UIA_E_ELEMENTNOTAVAILABLE;
198
199 QAccessibleTextInterface *textInterface = accessible->textInterface();
200 if (!textInterface)
201 return UIA_E_ELEMENTNOTAVAILABLE;
202
203 *isActive = accessible->state().focused;
204
205 int cursorPosition = textInterface->cursorPosition();
206 *pRetVal = makeComObject<QWindowsUiaTextRangeProvider>(id(), cursorPosition, cursorPosition)
207 .Detach();
208 return S_OK;
209}
210
211QT_END_NAMESPACE
212
213#endif // QT_CONFIG(accessibility)