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
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
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 auto *textRangeProvider = new QWindowsUiaTextRangeProvider(id(), startOffset, endOffset);
54 SafeArrayPutElement(*pRetVal, &i, static_cast<IUnknown *>(textRangeProvider));
55 textRangeProvider->Release();
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 auto *textRangeProvider = new QWindowsUiaTextRangeProvider(id(), cursorPosition, cursorPosition);
64 SafeArrayPutElement(*pRetVal, &i, static_cast<IUnknown *>(textRangeProvider));
65 textRangeProvider->Release();
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 auto *textRangeProvider = new QWindowsUiaTextRangeProvider(id(), 0, textInterface->characterCount());
92 SafeArrayPutElement(*pRetVal, &i, static_cast<IUnknown *>(textRangeProvider));
93 textRangeProvider->Release();
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 = new QWindowsUiaTextRangeProvider(id(), offset, offset);
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 = new QWindowsUiaTextRangeProvider(id(), 0, textInterface->characterCount());
160 return S_OK;
161}
162
163// Currently supporting single selection.
164HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::get_SupportedTextSelection(SupportedTextSelection *pRetVal)
165{
166 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
167
168 if (!pRetVal)
169 return E_INVALIDARG;
170 *pRetVal = SupportedTextSelection_Single;
171 return S_OK;
172}
173
174// Not supporting annotations.
175HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::RangeFromAnnotation(IRawElementProviderSimple * /*annotationElement*/, ITextRangeProvider **pRetVal)
176{
177 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
178
179 if (!pRetVal)
180 return E_INVALIDARG;
181 *pRetVal = nullptr;
182 return S_OK;
183}
184
185HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::GetCaretRange(BOOL *isActive, ITextRangeProvider **pRetVal)
186{
187 qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this;
188
189 if (!isActive || !pRetVal)
190 return E_INVALIDARG;
191 *isActive = FALSE;
192 *pRetVal = nullptr;
193
194 QAccessibleInterface *accessible = accessibleInterface();
195 if (!accessible)
196 return UIA_E_ELEMENTNOTAVAILABLE;
197
198 QAccessibleTextInterface *textInterface = accessible->textInterface();
199 if (!textInterface)
200 return UIA_E_ELEMENTNOTAVAILABLE;
201
202 *isActive = accessible->state().focused;
203
204 int cursorPosition = textInterface->cursorPosition();
205 *pRetVal = new QWindowsUiaTextRangeProvider(id(), cursorPosition, cursorPosition);
206 return S_OK;
207}
208
210
211#endif // QT_CONFIG(accessibility)
bool isActive
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtGui
Definition qwindow.h:63
Combined button and popup list for selecting options.
#define qCDebug(category,...)
GLenum GLuint id
[7]
GLenum GLuint GLintptr offset
long HRESULT
aWidget window() -> setWindowTitle("New Window Title")
[2]