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