4#include <QtGui/qtguiglobal.h>
5#if QT_CONFIG(accessibility)
12#include <QtGui/qaccessible.h>
13#include <QtCore/qloggingcategory.h>
14#include <QtCore/qstring.h>
15#include <QtCore/qvarlengtharray.h>
19using namespace QWindowsUiAutomation;
22QWindowsUiaTextRangeProvider::QWindowsUiaTextRangeProvider(QAccessible::Id
id,
int startOffset,
int endOffset) :
23 QWindowsUiaBaseProvider(
id),
24 m_startOffset(startOffset),
25 m_endOffset(endOffset)
27 qCDebug(lcQpaUiAutomation) << __FUNCTION__ <<
this << startOffset << endOffset;
30QWindowsUiaTextRangeProvider::~QWindowsUiaTextRangeProvider()
32 qCDebug(lcQpaUiAutomation) << __FUNCTION__ <<
this;
35HRESULT QWindowsUiaTextRangeProvider::AddToSelection()
37 qCDebug(lcQpaUiAutomation) << __FUNCTION__ <<
this;
41HRESULT QWindowsUiaTextRangeProvider::Clone(ITextRangeProvider **
pRetVal)
43 qCDebug(lcQpaUiAutomation) << __FUNCTION__ <<
this;
48 *
pRetVal =
new QWindowsUiaTextRangeProvider(
id(), m_startOffset, m_endOffset);
55 qCDebug(lcQpaUiAutomation) << __FUNCTION__ <<
this;
60 auto *targetProvider =
static_cast<QWindowsUiaTextRangeProvider *
>(
range);
61 *
pRetVal = ((targetProvider->m_startOffset == m_startOffset) && (targetProvider->m_endOffset == m_endOffset));
67 ITextRangeProvider *targetRange,
71 qCDebug(lcQpaUiAutomation) << __FUNCTION__
72 <<
"endpoint=" << endpoint <<
"targetRange=" << targetRange
73 <<
"targetEndpoint=" << targetEndpoint <<
"this: " <<
this;
78 auto *targetProvider =
static_cast<QWindowsUiaTextRangeProvider *
>(targetRange);
82 targetProvider->m_startOffset : targetProvider->m_endOffset;
88HRESULT QWindowsUiaTextRangeProvider::ExpandToEnclosingUnit(
TextUnit unit)
90 qCDebug(lcQpaUiAutomation) << __FUNCTION__ <<
"unit=" << unit <<
"this: " <<
this;
92 QAccessibleInterface *accessible = accessibleInterface();
96 QAccessibleTextInterface *textInterface = accessible->textInterface();
100 int len = textInterface->characterCount();
106 m_startOffset =
qBound(0, m_startOffset,
len - 1);
107 m_endOffset = m_startOffset + 1;
110 const int start = m_startOffset >= 0 && m_startOffset <
len
111 ? m_startOffset :
len - 1;
113 if (!isTextUnitSeparator(unit,
text[
t]) && ((
t == 0) || isTextUnitSeparator(unit,
text[
t - 1]))) {
118 for (
int t = m_startOffset;
t <
len; ++
t) {
119 if ((
t ==
len - 1) || (isTextUnitSeparator(unit,
text[
t]) && ((unit ==
TextUnit_Word) || !isTextUnitSeparator(unit,
text[
t + 1])))) {
144 qCDebug(lcQpaUiAutomation) << __FUNCTION__ <<
"attributeId=" << attributeId <<
"this: " <<
this;
150 QAccessibleInterface *accessible = accessibleInterface();
154 QAccessibleTextInterface *textInterface = accessible->textInterface();
158 switch (attributeId) {
160 setVariantBool(accessible->state().readOnly,
pRetVal);
163 if (textInterface->cursorPosition() == 0)
165 else if (textInterface->cursorPosition() == textInterface->characterCount())
177HRESULT QWindowsUiaTextRangeProvider::GetBoundingRectangles(SAFEARRAY **
pRetVal)
179 qCDebug(lcQpaUiAutomation) << __FUNCTION__ <<
this;
184 QAccessibleInterface *accessible = accessibleInterface();
188 QAccessibleTextInterface *textInterface = accessible->textInterface();
196 int len = textInterface->characterCount();
199 if ((m_startOffset >= 0) && (m_endOffset <=
len) && (m_startOffset < m_endOffset)) {
201 textInterface->textAtOffset(m_startOffset, QAccessible::LineBoundary, &
start, &
end);
202 while ((
start >= 0) && (
end >= 0)) {
203 int startRange =
qMax(
start, m_startOffset);
204 int endRange =
qMin(
end, m_endOffset);
205 if (startRange < endRange) {
207 const QRect startRect = textInterface->characterRect(startRange);
208 const QRect endRect = textInterface->characterRect(endRange - 1);
209 const QRect lineRect(
qMin(startRect.
x(), endRect.
x()),
210 qMin(startRect.
y(), endRect.
y()),
211 qMax(startRect.
x() + startRect.
width(), endRect.
x() + endRect.
width()) -
qMin(startRect.
x(), endRect.
x()),
213 rectList.
append(lineRect);
216 textInterface->textAfterOffset(
end + 1, QAccessible::LineBoundary, &
start, &
end);
220 if ((*
pRetVal = SafeArrayCreateVector(VT_R8, 0, 4 * rectList.
size()))) {
221 for (
int i = 0;
i < rectList.
size(); ++
i) {
224 rectToNativeUiaRect(rectList[
i],
window, &uiaRect);
226 for (
int j = 0;
j < 4; ++
j) {
227 LONG idx = 4 *
i +
j;
236HRESULT QWindowsUiaTextRangeProvider::GetChildren(SAFEARRAY **
pRetVal)
238 qCDebug(lcQpaUiAutomation) << __FUNCTION__ <<
this;
243 *
pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, 0);
248HRESULT QWindowsUiaTextRangeProvider::GetEnclosingElement(IRawElementProviderSimple **
pRetVal)
250 qCDebug(lcQpaUiAutomation) << __FUNCTION__ <<
this;
255 QAccessibleInterface *accessible = accessibleInterface();
259 *
pRetVal = QWindowsUiaMainProvider::providerForAccessible(accessible);
266 qCDebug(lcQpaUiAutomation) << __FUNCTION__ <<
maxLength <<
"this: " <<
this;
272 QAccessibleInterface *accessible = accessibleInterface();
276 QAccessibleTextInterface *textInterface = accessible->textInterface();
280 int len = textInterface->characterCount();
282 if ((m_startOffset >= 0) && (m_endOffset <=
len) && (m_startOffset < m_endOffset))
283 rangeText = textInterface->text(m_startOffset, m_endOffset);
287 *
pRetVal = bStrFromQString(rangeText);
294 qCDebug(lcQpaUiAutomation) << __FUNCTION__ <<
"unit=" << unit <<
"count=" <<
count <<
"this: " <<
this;
300 QAccessibleInterface *accessible = accessibleInterface();
304 QAccessibleTextInterface *textInterface = accessible->textInterface();
308 int len = textInterface->characterCount();
317 m_endOffset = (m_endOffset > m_startOffset) ?
start + 1 :
start;
319 m_startOffset =
start;
334 ITextRangeProvider *targetRange,
340 qCDebug(lcQpaUiAutomation) << __FUNCTION__
341 <<
"endpoint=" << endpoint <<
"targetRange=" << targetRange <<
"targetEndpoint=" << targetEndpoint <<
"this: " <<
this;
343 auto *targetProvider =
static_cast<QWindowsUiaTextRangeProvider *
>(targetRange);
346 targetProvider->m_startOffset : targetProvider->m_endOffset;
350 m_startOffset = targetPoint;
351 if (m_endOffset < m_startOffset)
352 m_endOffset = m_startOffset;
354 m_endOffset = targetPoint;
355 if (m_endOffset < m_startOffset)
356 m_startOffset = m_endOffset;
366 qCDebug(lcQpaUiAutomation) << __FUNCTION__
367 <<
"endpoint=" << endpoint <<
"unit=" << unit <<
"count=" <<
count <<
"this: " <<
this;
373 QAccessibleInterface *accessible = accessibleInterface();
377 QAccessibleTextInterface *textInterface = accessible->textInterface();
381 int len = textInterface->characterCount();
391 m_endOffset =
qBound(m_startOffset, m_endOffset,
len);
396 m_startOffset =
qBound(0, m_startOffset, m_endOffset);
404 for (
int t = m_startOffset; (
t <
len - 1) && (moved <
count); ++
t) {
405 if (isTextUnitSeparator(unit,
text[
t]) && !isTextUnitSeparator(unit,
text[
t + 1])) {
406 m_startOffset =
t + 1;
410 m_endOffset =
qBound(m_startOffset, m_endOffset,
len);
412 const int start = m_startOffset >= 0 && m_startOffset <=
len
413 ? m_startOffset :
len;
415 if (!isTextUnitSeparator(unit,
text[
t]) && ((
t == 0) || isTextUnitSeparator(unit,
text[
t - 1]))) {
423 for (
int t = m_endOffset; (
t <
len) && (moved <
count); ++
t) {
424 if ((
t ==
len - 1) || (isTextUnitSeparator(unit,
text[
t]) && ((unit ==
TextUnit_Word) || !isTextUnitSeparator(unit,
text[
t + 1])))) {
431 for (
int t = m_endOffset - 2; (
t > 0) && (moved >
count); --
t) {
432 if (isTextUnitSeparator(unit,
text[
t]) && ((unit ==
TextUnit_Word) || !isTextUnitSeparator(unit,
text[
t + 1]))) {
438 m_startOffset =
qBound(0, m_startOffset, m_endOffset);
446HRESULT QWindowsUiaTextRangeProvider::RemoveFromSelection()
448 qCDebug(lcQpaUiAutomation) << __FUNCTION__;
454HRESULT QWindowsUiaTextRangeProvider::ScrollIntoView(BOOL alignToTop)
456 qCDebug(lcQpaUiAutomation) << __FUNCTION__ <<
"alignToTop=" << alignToTop <<
"this: " <<
this;
458 QAccessibleInterface *accessible = accessibleInterface();
462 QAccessibleTextInterface *textInterface = accessible->textInterface();
466 textInterface->scrollToSubstring(m_startOffset, m_endOffset);
471HRESULT QWindowsUiaTextRangeProvider::Select()
473 qCDebug(lcQpaUiAutomation) << __FUNCTION__ <<
this;
475 QAccessibleInterface *accessible = accessibleInterface();
479 QAccessibleTextInterface *textInterface = accessible->textInterface();
485 textInterface->addSelection(m_startOffset, m_endOffset);
490HRESULT QWindowsUiaTextRangeProvider::FindText(BSTR , BOOL ,
501HRESULT QWindowsUiaTextRangeProvider::unselect()
503 qCDebug(lcQpaUiAutomation) << __FUNCTION__ <<
this;
505 QAccessibleInterface *accessible = accessibleInterface();
509 QAccessibleTextInterface *textInterface = accessible->textInterface();
513 int selCount = textInterface->selectionCount();
515 for (
int i = selCount - 1;
i >= 0; --
i)
516 textInterface->removeSelection(
i);
\inmodule QtCore\reentrant
constexpr int height() const noexcept
Returns the height of the rectangle.
constexpr int x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
constexpr int width() const noexcept
Returns the width of the rectangle.
constexpr int y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
\macro QT_RESTRICTED_CAST_FROM_ASCII
void truncate(qsizetype pos)
Truncates the string at the given position index.
qsizetype size() const
Returns the number of characters in this string.
constexpr size_type size() const noexcept
Combined button and popup list for selecting options.
#define qCDebug(category,...)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qBound(const T &min, const T &val, const T &max)
constexpr const T & qMax(const T &a, const T &b)
GLsizei const GLubyte GLsizei GLenum const void * coords
GLenum GLenum GLsizei count
#define UIA_IsReadOnlyAttributeId
#define UIA_CaretPositionAttributeId
#define UIA_E_ELEMENTNOTAVAILABLE
virtual HRESULT STDMETHODCALLTYPE Select()=0
IRawElementProviderFragment __RPC__deref_out_opt IRawElementProviderFragment ** pRetVal
virtual HRESULT STDMETHODCALLTYPE MoveEndpointByUnit(enum TextPatternRangeEndpoint endpoint, enum TextUnit unit, int count, __RPC__out int *pRetVal)=0
@ TextPatternRangeEndpoint_End
@ TextPatternRangeEndpoint_Start
@ CaretPosition_BeginningOfLine
@ CaretPosition_EndOfLine