summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/accessible/qaccessible2.cpp113
-rw-r--r--src/gui/accessible/qaccessible2.h21
-rw-r--r--src/plugins/accessible/widgets/qaccessiblewidgets.cpp62
-rw-r--r--src/plugins/accessible/widgets/qaccessiblewidgets.h5
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.cpp7
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.h3
-rw-r--r--src/plugins/platforms/windows/accessible/comutils.h5
-rw-r--r--src/plugins/platforms/windows/accessible/iaccessible2.cpp129
-rw-r--r--src/plugins/platforms/windows/accessible/iaccessible2.h6
-rw-r--r--tests/auto/other/qaccessibility/qaccessibility.pro5
-rw-r--r--tests/auto/other/qaccessibility/tst_qaccessibility.cpp181
11 files changed, 284 insertions, 253 deletions
diff --git a/src/gui/accessible/qaccessible2.cpp b/src/gui/accessible/qaccessible2.cpp
index 41275628f2..4936846d6c 100644
--- a/src/gui/accessible/qaccessible2.cpp
+++ b/src/gui/accessible/qaccessible2.cpp
@@ -190,10 +190,6 @@ QT_BEGIN_NAMESPACE
When implementing this interface you will almost certainly also want to implement \l QAccessibleTextInterface.
- Since this interface can be implemented by means of the normal \l QAccessibleTextInterface,
- \l QAccessibleSimpleEditableTextInterface provides a convenience implementation of this interface.
- Consider inheriting \l QAccessibleSimpleEditableTextInterface instead.
-
\sa QAccessibleInterface
\l{IAccessible2 Specification}
@@ -206,14 +202,6 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn void QAccessibleEditableTextInterface::copyText(int startOffset, int endOffset) const
-
- Copies the text from \a startOffset to \a endOffset to the system clip board.
- The \a startOffset is the first character that will be copied.
- The \a endOffset is the first character that will not be copied.
-*/
-
-/*!
\fn void QAccessibleEditableTextInterface::deleteText(int startOffset, int endOffset)
Deletes the text from \a startOffset to \a endOffset.
@@ -226,18 +214,6 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn void QAccessibleEditableTextInterface::cutText(int startOffset, int endOffset)
-
- Removes the text from \a startOffset to \a endOffset and puts it in the system clip board.
-*/
-
-/*!
- \fn void QAccessibleEditableTextInterface::pasteText(int offset)
-
- Pastes text from the system clip board at the position \a offset.
-*/
-
-/*!
\fn void QAccessibleEditableTextInterface::replaceText(int startOffset, int endOffset, const QString &text)
Removes the text from \a startOffset to \a endOffset and instead inserts \a text.
@@ -250,20 +226,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \class QAccessibleSimpleEditableTextInterface
- \inmodule QtGui
- \ingroup accessibility
- \internal
-
- \brief The QAccessibleSimpleEditableTextInterface class is a convenience class for
- text-based widgets. It can be inherited instead of \l QAccessibleEditableTextInterface.
-
- \sa QAccessibleInterface, QAccessibleEditableTextInterface
-
- \l{IAccessible2 Specification}
-*/
-
-/*!
+ \class QAccessibleValueInterface
\class QAccessibleValueInterface
\inmodule QtGui
\ingroup accessibility
@@ -667,80 +630,6 @@ QString Q_GUI_EXPORT qTextAtOffsetFromString(int offset, QAccessible2::BoundaryT
return text.mid(*startOffset, *endOffset - *startOffset);
}
-QAccessibleSimpleEditableTextInterface::QAccessibleSimpleEditableTextInterface(
- QAccessibleInterface *accessibleInterface)
- : iface(accessibleInterface)
-{
- Q_ASSERT(iface);
-}
-
-#ifndef QT_NO_CLIPBOARD
-static QString textForRange(QAccessibleInterface *iface, int startOffset, int endOffset)
-{
- return iface->text(QAccessible::Value).mid(startOffset, endOffset - startOffset);
-}
-#endif
-
-/*! \reimp */
-void QAccessibleSimpleEditableTextInterface::copyText(int startOffset, int endOffset) const
-{
-#ifdef QT_NO_CLIPBOARD
- Q_UNUSED(startOffset);
- Q_UNUSED(endOffset);
-#else
- QGuiApplication::clipboard()->setText(textForRange(iface, startOffset, endOffset));
-#endif
-}
-
-/*! \reimp */
-void QAccessibleSimpleEditableTextInterface::deleteText(int startOffset, int endOffset)
-{
- QString txt = iface->text(QAccessible::Value);
- txt.remove(startOffset, endOffset - startOffset);
- iface->setText(QAccessible::Value, txt);
-}
-
-/*! \reimp */
-void QAccessibleSimpleEditableTextInterface::insertText(int offset, const QString &text)
-{
- QString txt = iface->text(QAccessible::Value);
- txt.insert(offset, text);
- iface->setText(QAccessible::Value, txt);
-}
-
-/*! \reimp */
-void QAccessibleSimpleEditableTextInterface::cutText(int startOffset, int endOffset)
-{
-#ifdef QT_NO_CLIPBOARD
- Q_UNUSED(startOffset);
- Q_UNUSED(endOffset);
-#else
- QString sub = textForRange(iface, startOffset, endOffset);
- deleteText(startOffset, endOffset);
- QGuiApplication::clipboard()->setText(sub);
-#endif
-}
-
-/*! \reimp */
-void QAccessibleSimpleEditableTextInterface::pasteText(int offset)
-{
-#ifdef QT_NO_CLIPBOARD
- Q_UNUSED(offset);
-#else
- QString txt = iface->text(QAccessible::Value);
- txt.insert(offset, QGuiApplication::clipboard()->text());
- iface->setText(QAccessible::Value, txt);
-#endif
-}
-
-/*! \reimp */
-void QAccessibleSimpleEditableTextInterface::replaceText(int startOffset, int endOffset, const QString &text)
-{
- QString txt = iface->text(QAccessible::Value);
- txt.replace(startOffset, endOffset - startOffset, text);
- iface->setText(QAccessible::Value, txt);
-}
-
QT_END_NAMESPACE
#endif // QT_NO_ACCESSIBILITY
diff --git a/src/gui/accessible/qaccessible2.h b/src/gui/accessible/qaccessible2.h
index 922fb73b7d..91f6b73f3e 100644
--- a/src/gui/accessible/qaccessible2.h
+++ b/src/gui/accessible/qaccessible2.h
@@ -97,30 +97,9 @@ class Q_GUI_EXPORT QAccessibleEditableTextInterface
public:
virtual ~QAccessibleEditableTextInterface() {}
- virtual void copyText(int startOffset, int endOffset) const = 0;
virtual void deleteText(int startOffset, int endOffset) = 0;
virtual void insertText(int offset, const QString &text) = 0;
- virtual void cutText(int startOffset, int endOffset) = 0;
- virtual void pasteText(int offset) = 0;
virtual void replaceText(int startOffset, int endOffset, const QString &text) = 0;
- virtual void setAttributes(int startOffset, int endOffset, const QString &attributes) = 0;
-};
-
-class Q_GUI_EXPORT QAccessibleSimpleEditableTextInterface: public QAccessibleEditableTextInterface
-{
-public:
- explicit QAccessibleSimpleEditableTextInterface(QAccessibleInterface *accessibleInterface); //###
-
- void copyText(int startOffset, int endOffset) const;
- void deleteText(int startOffset, int endOffset);
- void insertText(int offset, const QString &text);
- void cutText(int startOffset, int endOffset);
- void pasteText(int offset);
- void replaceText(int startOffset, int endOffset, const QString &text);
- inline void setAttributes(int, int, const QString &) {}
-
-private:
- QAccessibleInterface *iface;
};
class Q_GUI_EXPORT QAccessibleValueInterface
diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
index a002b8bf26..f6ec940b58 100644
--- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
+++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
@@ -142,12 +142,20 @@ void QAccessibleTextEdit::setText(QAccessible::Text t, const QString &text)
textEdit()->setText(text);
}
+QAccessible::State QAccessibleTextEdit::state() const
+{
+ QAccessible::State st = QAccessibleWidget::state();
+ if (textEdit()->isReadOnly())
+ st.readOnly = true;
+ else
+ st.editable = true;
+ return st;
+}
+
void *QAccessibleTextEdit::interface_cast(QAccessible::InterfaceType t)
{
if (t == QAccessible::TextInterface)
return static_cast<QAccessibleTextInterface*>(this);
- else if (t == QAccessible::EditableTextInterface)
- return static_cast<QAccessibleEditableTextInterface*>(this);
return QAccessibleWidget::interface_cast(t);
}
@@ -467,24 +475,9 @@ static QTextCursor cursorForRange(QTextEdit *textEdit, int startOffset, int endO
QTextCursor cursor(textEdit->document());
cursor.setPosition(startOffset, QTextCursor::MoveAnchor);
cursor.setPosition(endOffset, QTextCursor::KeepAnchor);
-
return cursor;
}
-void QAccessibleTextEdit::copyText(int startOffset, int endOffset) const
-{
-#ifndef QT_NO_CLIPBOARD
- QTextCursor previousCursor = textEdit()->textCursor();
- QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset);
-
- if (!cursor.hasSelection())
- return;
-
- textEdit()->setTextCursor(cursor);
- textEdit()->copy();
- textEdit()->setTextCursor(previousCursor);
-#endif
-}
void QAccessibleTextEdit::deleteText(int startOffset, int endOffset)
{
@@ -501,34 +494,6 @@ void QAccessibleTextEdit::insertText(int offset, const QString &text)
cursor.insertText(text);
}
-void QAccessibleTextEdit::cutText(int startOffset, int endOffset)
-{
-#ifndef QT_NO_CLIPBOARD
- QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset);
-
- if (!cursor.hasSelection())
- return;
-
- textEdit()->setTextCursor(cursor);
- textEdit()->cut();
-#endif
-}
-
-void QAccessibleTextEdit::pasteText(int offset)
-{
- QTextEdit *edit = textEdit();
-
- QTextCursor oldCursor = edit->textCursor();
- QTextCursor newCursor = oldCursor;
- newCursor.setPosition(offset);
-
- edit->setTextCursor(newCursor);
-#ifndef QT_NO_CLIPBOARD
- edit->paste();
-#endif
- edit->setTextCursor(oldCursor);
-}
-
void QAccessibleTextEdit::replaceText(int startOffset, int endOffset, const QString &text)
{
QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset);
@@ -537,13 +502,6 @@ void QAccessibleTextEdit::replaceText(int startOffset, int endOffset, const QStr
cursor.insertText(text);
}
-void QAccessibleTextEdit::setAttributes(int startOffset, int endOffset, const QString &attributes)
-{
- // TODO
- Q_UNUSED(startOffset);
- Q_UNUSED(endOffset);
- Q_UNUSED(attributes);
-}
#endif // QT_NO_TEXTEDIT
#ifndef QT_NO_STACKEDWIDGET
diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.h b/src/plugins/accessible/widgets/qaccessiblewidgets.h
index 79ac5ae7b5..dba645570a 100644
--- a/src/plugins/accessible/widgets/qaccessiblewidgets.h
+++ b/src/plugins/accessible/widgets/qaccessiblewidgets.h
@@ -73,6 +73,7 @@ public:
QString text(QAccessible::Text t) const;
void setText(QAccessible::Text t, const QString &text);
+ QAccessible::State state() const;
void *interface_cast(QAccessible::InterfaceType t);
@@ -98,13 +99,9 @@ public:
void scrollToSubstring(int startIndex, int endIndex);
// QAccessibleEditableTextInterface
- void copyText(int startOffset, int endOffset) const;
void deleteText(int startOffset, int endOffset);
void insertText(int offset, const QString &text);
- void cutText(int startOffset, int endOffset);
- void pasteText(int offset);
void replaceText(int startOffset, int endOffset, const QString &text);
- void setAttributes(int startOffset, int endOffset, const QString &attributes);
protected:
QTextEdit *textEdit() const;
diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp
index 0fa6dc9990..cc10f598f6 100644
--- a/src/plugins/accessible/widgets/simplewidgets.cpp
+++ b/src/plugins/accessible/widgets/simplewidgets.cpp
@@ -575,7 +575,7 @@ QStringList QAccessibleGroupBox::keyBindingsForAction(const QString &) const
\a name is propagated to the QAccessibleWidget constructor.
*/
QAccessibleLineEdit::QAccessibleLineEdit(QWidget *w, const QString &name)
-: QAccessibleWidget(w, QAccessible::EditableText, name), QAccessibleSimpleEditableTextInterface(this)
+: QAccessibleWidget(w, QAccessible::EditableText, name)
{
addControllingSignal(QLatin1String("textChanged(const QString&)"));
addControllingSignal(QLatin1String("returnPressed()"));
@@ -626,6 +626,9 @@ QAccessible::State QAccessibleLineEdit::state() const
QLineEdit *l = lineEdit();
if (l->isReadOnly())
state.readOnly = true;
+ else
+ state.editable = true;
+
if (l->echoMode() != QLineEdit::Normal)
state.passwordEdit = true;
state.selectable = true;
@@ -643,8 +646,6 @@ void *QAccessibleLineEdit::interface_cast(QAccessible::InterfaceType t)
{
if (t == QAccessible::TextInterface)
return static_cast<QAccessibleTextInterface*>(this);
- else if (t == QAccessible::EditableTextInterface)
- return static_cast<QAccessibleEditableTextInterface*>(this);
return QAccessibleWidget::interface_cast(t);
}
diff --git a/src/plugins/accessible/widgets/simplewidgets.h b/src/plugins/accessible/widgets/simplewidgets.h
index 74c1da405d..baded3d76b 100644
--- a/src/plugins/accessible/widgets/simplewidgets.h
+++ b/src/plugins/accessible/widgets/simplewidgets.h
@@ -137,8 +137,7 @@ private:
#endif
#ifndef QT_NO_LINEEDIT
-class QAccessibleLineEdit : public QAccessibleWidget, public QAccessibleTextInterface,
- public QAccessibleSimpleEditableTextInterface
+class QAccessibleLineEdit : public QAccessibleWidget, public QAccessibleTextInterface
{
public:
explicit QAccessibleLineEdit(QWidget *o, const QString &name = QString());
diff --git a/src/plugins/platforms/windows/accessible/comutils.h b/src/plugins/platforms/windows/accessible/comutils.h
index 4d8e603899..40b89ed991 100644
--- a/src/plugins/platforms/windows/accessible/comutils.h
+++ b/src/plugins/platforms/windows/accessible/comutils.h
@@ -54,6 +54,11 @@ class QVariant;
bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName, bool out);
+inline QString BSTRToQString(const BSTR &bstr)
+{
+ return QString((QChar*)bstr);
+}
+
inline BSTR QStringToBSTR(const QString &str)
{
return SysAllocStringLen((OLECHAR*)str.unicode(), str.length());
diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
index 71a26aff6b..5a82936a03 100644
--- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp
+++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
@@ -45,6 +45,7 @@
#include "qwindowsaccessibility.h"
#include <QtGui/qaccessible2.h>
+#include <QtGui/qclipboard.h>
#include <QtWidgets/qapplication.h>
#include <QtCore/qdebug.h>
@@ -241,9 +242,11 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::QueryInterface(REFIID id, LPVOI
} else if (id == IID_IAccessibleComponent) {
*iface = (IAccessibleComponent*)this;
} else if (id == IID_IAccessibleEditableText) {
- //if (accessible->editableTextInterface()) {
- //*iface = (IAccessibleEditableText*)this;
- //}
+ if (accessible->editableTextInterface() ||
+ accessible->role() == QAccessible::EditableText)
+ {
+ *iface = (IAccessibleEditableText*)this;
+ }
} else if (id == IID_IAccessibleHyperlink) {
//*iface = (IAccessibleHyperlink*)this;
} else if (id == IID_IAccessibleHypertext) {
@@ -673,6 +676,126 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_background(IA2Color *backgr
}
/**************************************************************\
+ * IAccessibleEditableText *
+ **************************************************************/
+#ifndef QT_NO_CLIPBOARD
+/*!
+ \internal
+
+ if \a endOffset == -1 it means end of the text
+*/
+QString QWindowsIA2Accessible::textForRange(int startOffset, int endOffset) const
+{
+ if (QAccessibleTextInterface *textIface = accessible->textInterface()) {
+ if (endOffset == IA2_TEXT_OFFSET_LENGTH)
+ endOffset = textIface->characterCount();
+ return textIface->text(startOffset, endOffset);
+ }
+ QString txt = accessible->text(QAccessible::Value);
+ if (endOffset == IA2_TEXT_OFFSET_LENGTH)
+ endOffset = txt.length();
+ return txt.mid(startOffset, endOffset - startOffset);
+}
+#endif
+
+/*!
+ \internal
+*/
+void QWindowsIA2Accessible::replaceTextFallback(long startOffset, long endOffset, const QString &txt)
+{
+ QString t = textForRange(0, -1);
+ if (endOffset == IA2_TEXT_OFFSET_LENGTH)
+ endOffset = t.length();
+ if (endOffset - startOffset == 0) {
+ t.insert(startOffset, txt);
+ } else {
+ t.replace(startOffset, endOffset - startOffset, txt);
+ }
+ accessible->setText(QAccessible::Value, t);
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::copyText(long startOffset, long endOffset)
+{
+ accessibleDebugClientCalls(accessible);
+#ifndef QT_NO_CLIPBOARD
+ const QString t = textForRange(startOffset, endOffset);
+ QGuiApplication::clipboard()->setText(t);
+ return S_OK;
+#else
+ return E_NOTIMPL;
+#endif
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::deleteText(long startOffset, long endOffset)
+{
+ accessibleDebugClientCalls(accessible);
+ if (QAccessibleEditableTextInterface *editableTextIface = accessible->editableTextInterface())
+ editableTextIface->deleteText(startOffset, endOffset);
+ else
+ replaceTextFallback(startOffset, endOffset, QString());
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::insertText(long offset, BSTR *text)
+{
+ accessibleDebugClientCalls(accessible);
+ const QString txt(BSTRToQString(*text));
+ if (QAccessibleEditableTextInterface *editableTextIface = accessible->editableTextInterface())
+ editableTextIface->insertText(offset, txt);
+ else
+ replaceTextFallback(offset, offset, txt);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::cutText(long startOffset, long endOffset)
+{
+ accessibleDebugClientCalls(accessible);
+#ifndef QT_NO_CLIPBOARD
+ const QString t = textForRange(startOffset, endOffset);
+ if (QAccessibleEditableTextInterface *editableTextIface = accessible->editableTextInterface())
+ editableTextIface->deleteText(startOffset, endOffset);
+ else
+ replaceTextFallback(startOffset, endOffset, QString());
+ QGuiApplication::clipboard()->setText(t);
+ return S_OK;
+#else
+ return E_NOTIMPL;
+#endif
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::pasteText(long offset)
+{
+ accessibleDebugClientCalls(accessible);
+#ifndef QT_NO_CLIPBOARD
+ const QString txt = QGuiApplication::clipboard()->text();
+ if (QAccessibleEditableTextInterface *editableTextIface = accessible->editableTextInterface())
+ editableTextIface->insertText(offset, txt);
+ else
+ replaceTextFallback(offset, offset, txt);
+ return S_OK;
+#else
+ return E_NOTIMPL;
+#endif
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::replaceText(long startOffset, long endOffset, BSTR *text)
+{
+ accessibleDebugClientCalls(accessible);
+ const QString txt(BSTRToQString(*text));
+ if (QAccessibleEditableTextInterface *editableTextIface = accessible->editableTextInterface())
+ editableTextIface->replaceText(startOffset, endOffset, txt);
+ else
+ replaceTextFallback(startOffset, endOffset, txt);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::setAttributes(long /*startOffset*/, long /*endOffset*/, BSTR * /*attributes*/)
+{
+ return E_NOTIMPL;
+}
+
+
+/**************************************************************\
* IAccessibleTable2 *
**************************************************************/
HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_cellAt( long row, long column, IUnknown **cell)
diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.h b/src/plugins/platforms/windows/accessible/iaccessible2.h
index 0f9d3b3c41..bfd9031e88 100644
--- a/src/plugins/platforms/windows/accessible/iaccessible2.h
+++ b/src/plugins/platforms/windows/accessible/iaccessible2.h
@@ -73,7 +73,7 @@ QT_BEGIN_NAMESPACE
class QWindowsIA2Accessible : public QWindowsMsaaAccessible,
public IAccessibleAction,
public IAccessibleComponent,
- /*public IAccessibleEditableText,*/
+ public IAccessibleEditableText,
public IAccessibleTable2,
public IAccessibleTableCell,
public IAccessibleText,
@@ -122,7 +122,6 @@ public:
HRESULT STDMETHODCALLTYPE get_background(IA2Color *background);
/* IAccessibleEditableText */
- /*
HRESULT STDMETHODCALLTYPE copyText(long startOffset, long endOffset);
HRESULT STDMETHODCALLTYPE deleteText(long startOffset, long endOffset);
HRESULT STDMETHODCALLTYPE insertText(long offset, BSTR *text);
@@ -130,7 +129,6 @@ public:
HRESULT STDMETHODCALLTYPE pasteText(long offset);
HRESULT STDMETHODCALLTYPE replaceText(long startOffset, long endOffset, BSTR *text);
HRESULT STDMETHODCALLTYPE setAttributes(long startOffset, long endOffset, BSTR *attributes);
- */
/* IAccessibleTable2 */
HRESULT STDMETHODCALLTYPE get_cellAt( long row, long column, IUnknown **cell);
@@ -265,6 +263,8 @@ private:
HRESULT wrapListOfCells(const QList<QAccessibleInterface*> &inputCells, IUnknown ***outputAccessibles, long *nCellCount);
uint uniqueID() const;
QByteArray IIDToString(REFIID id);
+ QString textForRange(int startOffset, int endOffset) const;
+ void replaceTextFallback(long startOffset, long endOffset, const QString &txt);
};
diff --git a/tests/auto/other/qaccessibility/qaccessibility.pro b/tests/auto/other/qaccessibility/qaccessibility.pro
index 0c224ad0a8..ac8b6c87a8 100644
--- a/tests/auto/other/qaccessibility/qaccessibility.pro
+++ b/tests/auto/other/qaccessibility/qaccessibility.pro
@@ -13,6 +13,9 @@ wince*: {
}
win32 {
- !*g++: include(../../../../src/3rdparty/iaccessible2/iaccessible2.pri)
+ !*g++ {
+ include(../../../../src/3rdparty/iaccessible2/iaccessible2.pri)
+ DEFINES += QT_SUPPORTS_IACCESSIBLE2
+ }
LIBS += -loleacc -loleaut32 -lole32
}
diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
index 2a4013347e..df7588465d 100644
--- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
+++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
@@ -46,16 +46,19 @@
# include <oleacc.h>
# include <servprov.h>
# include <winuser.h>
-# ifndef Q_CC_MINGW
+# ifdef QT_SUPPORTS_IACCESSIBLE2
# include <Accessible2.h>
# include <AccessibleAction.h>
# include <AccessibleComponent.h>
+# include <AccessibleEditableText.h>
+# include <AccessibleText.h>
# endif
#endif
#include <QtTest/QtTest>
#include <QtGui>
#include <QtWidgets>
#include <math.h>
+#include <qpa/qplatformnativeinterface.h>
#if defined(Q_OS_WIN) && defined(interface)
# undef interface
@@ -1560,12 +1563,6 @@ void tst_QAccessibility::textEditTest()
QCOMPARE(iface->textInterface()->characterRect(5).size(), QSize(fm.width(" "), fm.height()));
QCOMPARE(iface->textInterface()->characterRect(6).size(), QSize(fm.width("w"), fm.height()));
- iface->editableTextInterface()->copyText(6, 11);
- QCOMPARE(QApplication::clipboard()->text(), QLatin1String("world"));
- iface->editableTextInterface()->cutText(12, 16);
- QCOMPARE(QApplication::clipboard()->text(), QLatin1String("how "));
- QCOMPARE(iface->textInterface()->text(12, 15), QLatin1String("are"));
-
QTestAccessibility::clearEvents();
// select text
@@ -2922,6 +2919,28 @@ void tst_QAccessibility::accelerators()
QTestAccessibility::clearEvents();
}
+#ifdef QT_SUPPORTS_IACCESSIBLE2
+static IUnknown *queryIA2(IAccessible *acc, const IID &iid)
+{
+ IUnknown *resultInterface = 0;
+ IServiceProvider *pService = 0;
+ HRESULT hr = acc->QueryInterface(IID_IServiceProvider, (void **)&pService);
+ if (SUCCEEDED(hr)) {
+ IAccessible2 *pIA2 = 0;
+ hr = pService->QueryService(IID_IAccessible, IID_IAccessible2, (void**)&pIA2);
+ if (SUCCEEDED(hr) && pIA2) {
+ // The control supports IAccessible2.
+ // pIA2 is the reference to the accessible object's IAccessible2 interface.
+ hr = pIA2->QueryInterface(iid, (void**)&resultInterface);
+ pIA2->Release();
+ }
+ // The control supports IAccessible2.
+ pService->Release();
+ }
+ return resultInterface;
+}
+#endif
+
void tst_QAccessibility::bridgeTest()
{
// For now this is a simple test to see if the bridge is working at all.
@@ -2931,27 +2950,31 @@ void tst_QAccessibility::bridgeTest()
QWidget *window = new QWidget;
QVBoxLayout *lay = new QVBoxLayout(window);
QPushButton *button = new QPushButton(tr("Push me"), window);
- QLineEdit *le = new QLineEdit(window);
+ QTextEdit *te = new QTextEdit(window);
+ te->setText(QLatin1String("hello world\nhow are you today?\n"));
lay->addWidget(button);
- lay->addWidget(le);
+ lay->addWidget(te);
window->show();
QTest::qWaitForWindowShown(window);
+
+ /**************************************************
+ * QPushButton
+ **************************************************/
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(button);
QPoint buttonPos = button->mapToGlobal(QPoint(0,0));
QRect buttonRect = iface->rect();
QCOMPARE(buttonRect.topLeft(), buttonPos);
-
// All set, now test the bridge.
POINT pt;
pt.x = buttonRect.center().x();
pt.y = buttonRect.center().y();
- IAccessible *iacc;
+ IAccessible *iaccButton;
VARIANT varChild;
- HRESULT hr = ::AccessibleObjectFromPoint(pt, &iacc, &varChild);
+ HRESULT hr = ::AccessibleObjectFromPoint(pt, &iaccButton, &varChild);
QVERIFY(SUCCEEDED(hr));
VARIANT varSELF;
varSELF.vt = VT_I4;
@@ -2959,7 +2982,7 @@ void tst_QAccessibility::bridgeTest()
// **** Test get_accRole ****
VARIANT varRole;
- hr = iacc->get_accRole(varSELF, &varRole);
+ hr = iaccButton->get_accRole(varSELF, &varRole);
QVERIFY(SUCCEEDED(hr));
QCOMPARE(varRole.vt, (VARTYPE)VT_I4);
@@ -2967,52 +2990,106 @@ void tst_QAccessibility::bridgeTest()
// **** Test accLocation ****
long x, y, w, h;
- hr = iacc->accLocation(&x, &y, &w, &h, varSELF);
+ hr = iaccButton->accLocation(&x, &y, &w, &h, varSELF);
QCOMPARE(buttonRect, QRect(x, y, w, h));
-#ifndef Q_CC_MINGW
+#ifdef QT_SUPPORTS_IACCESSIBLE2
// Test IAccessible2 part of bridge
- IServiceProvider *pService = 0;
- hr = iacc->QueryInterface(IID_IServiceProvider, (void **)&pService);
- if (SUCCEEDED(hr)) {
- IAccessible2 *pIA2 = 0;
- hr = pService->QueryService(IID_IAccessible, IID_IAccessible2, (void**)&pIA2);
- if (SUCCEEDED(hr) && pIA2) {
- // The control supports IAccessible2.
- // pIA2 is the reference to the accessible object's IAccessible2 interface.
+ if (IAccessible2 *ia2Button = (IAccessible2*)queryIA2(iaccButton, IID_IAccessible2)) {
+ // The control supports IAccessible2.
+ // ia2Button is the reference to the accessible object's IAccessible2 interface.
+
+ /***** Test IAccessibleComponent *****/
+ IAccessibleComponent *ia2Component = 0;
+ hr = ia2Button->QueryInterface(IID_IAccessibleComponent, (void**)&ia2Component);
+ QVERIFY(SUCCEEDED(hr));
+ long x, y;
+ hr = ia2Component->get_locationInParent(&x, &y);
+ QVERIFY(SUCCEEDED(hr));
+ QCOMPARE(button->pos(), QPoint(x, y));
+ ia2Component->Release();
+
+ /***** Test IAccessibleAction *****/
+ IAccessibleAction *ia2Action = 0;
+ hr = ia2Button->QueryInterface(IID_IAccessibleAction, (void**)&ia2Action);
+ QVERIFY(SUCCEEDED(hr));
+ QVERIFY(ia2Action);
+ long nActions;
+ ia2Action->nActions(&nActions);
+ QVERIFY(nActions >= 1); // "Press" and "SetFocus"
+ BSTR actionName;
+ ia2Action->get_name(0, &actionName);
+ QString name((QChar*)actionName);
+ QCOMPARE(name, QAccessibleActionInterface::pressAction());
+ ia2Action->Release();
+
+
+ // Done testing
+ ia2Button->Release();
+ }
+#endif
+ iaccButton->Release();
- /***** Test IAccessibleComponent *****/
- IAccessibleComponent *ia2Component = 0;
- hr = pIA2->QueryInterface(IID_IAccessibleComponent, (void**)&ia2Component);
- QVERIFY(SUCCEEDED(hr));
- long x, y;
- hr = ia2Component->get_locationInParent(&x, &y);
- QVERIFY(SUCCEEDED(hr));
- QCOMPARE(button->pos(), QPoint(x, y));
- ia2Component->Release();
-
- /***** Test IAccessibleAction *****/
- IAccessibleAction *ia2Action = 0;
- hr = pIA2->QueryInterface(IID_IAccessibleAction, (void**)&ia2Action);
- QVERIFY(SUCCEEDED(hr));
- QVERIFY(ia2Action);
- long nActions;
- ia2Action->nActions(&nActions);
- QVERIFY(nActions >= 1); // "Press" and "SetFocus"
- BSTR actionName;
- ia2Action->get_name(0, &actionName);
- QString name((QChar*)actionName);
- QCOMPARE(name, QAccessibleActionInterface::pressAction());
- ia2Action->Release();
-
- // Done testing
- pIA2->Release();
- }
- pService->Release();
+ /**************************************************
+ * QWidget
+ **************************************************/
+ QWindow *windowHandle = window->windowHandle();
+ QPlatformNativeInterface *platform = QGuiApplication::platformNativeInterface();
+ HWND hWnd = (HWND)platform->nativeResourceForWindow("handle", windowHandle);
+
+ IAccessible *iaccWindow;
+ hr = ::AccessibleObjectFromWindow(hWnd, OBJID_CLIENT, IID_IAccessible, (void**)&iaccWindow);
+ QVERIFY(SUCCEEDED(hr));
+ hr = iaccWindow->get_accRole(varSELF, &varRole);
+ QVERIFY(SUCCEEDED(hr));
+
+ QCOMPARE(varRole.vt, (VARTYPE)VT_I4);
+ QCOMPARE(varRole.lVal, (LONG)ROLE_SYSTEM_CLIENT);
+
+ long nChildren;
+ hr = iaccWindow->get_accChildCount(&nChildren);
+ QVERIFY(SUCCEEDED(hr));
+ QCOMPARE(nChildren, (long)2);
+
+ /**************************************************
+ * QTextEdit
+ **************************************************/
+ // Get the second child (the accessible interface for the text edit)
+ varChild.vt = VT_I4;
+ varChild.lVal = 2;
+ QVERIFY(iaccWindow);
+ IAccessible *iaccTextEdit;
+ hr = iaccWindow->get_accChild(varChild, (IDispatch**)&iaccTextEdit);
+ QVERIFY(SUCCEEDED(hr));
+ QVERIFY(iaccTextEdit);
+ hr = iaccTextEdit->get_accRole(varSELF, &varRole);
+ QVERIFY(SUCCEEDED(hr));
+
+ QCOMPARE(varRole.vt, (VARTYPE)VT_I4);
+ QCOMPARE(varRole.lVal, (LONG)ROLE_SYSTEM_TEXT);
+
+
+
+#ifdef QT_SUPPORTS_IACCESSIBLE2
+ if (IAccessibleEditableText *ia2TextEdit = (IAccessibleEditableText*)queryIA2(iaccTextEdit, IID_IAccessibleEditableText)) {
+ ia2TextEdit->copyText(6, 11);
+ QCOMPARE(QApplication::clipboard()->text(), QLatin1String("world"));
+ ia2TextEdit->cutText(12, 16);
+ QCOMPARE(QApplication::clipboard()->text(), QLatin1String("how "));
+ ia2TextEdit->Release();
+ }
+ if (IAccessibleText *ia2Text = (IAccessibleText*)queryIA2(iaccTextEdit, IID_IAccessibleText)) {
+ BSTR txt;
+ hr = ia2Text->get_text(12, 15, &txt);
+ QVERIFY(SUCCEEDED(hr));
+ QCOMPARE(QString((QChar*)txt), QLatin1String("are"));
+ ia2Text->Release();
}
#endif
- iacc->Release();
+ iaccTextEdit->Release();
+
+ iaccWindow->Release();
QTestAccessibility::clearEvents();
#endif
}