/****************************************************************************
**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
****************************************************************************/
+#include <QtCore/qglobal.h>
+#ifdef Q_OS_WIN
+# include <QtCore/qt_windows.h>
+# include <oleacc.h>
+# include <servprov.h>
+# include <winuser.h>
+# 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
void mdiAreaTest();
void mdiSubWindowTest();
void lineEditTest();
- void workspaceTest();
+ void groupBoxTest();
void dialogButtonBoxTest();
void dialTest();
void rubberBandTest();
void accessibleName();
void labelTest();
void accelerators();
+ void bridgeTest();
protected slots:
void onClicked();
const double Q_PI = 3.14159265358979323846;
-QString eventName(const int ev)
-{
- switch(ev) {
- case 0x0001: return "SoundPlayed";
- case 0x0002: return "Alert";
- case 0x0003: return "ForegroundChanged";
- case 0x0004: return "MenuStart";
- case 0x0005: return "MenuEnd";
- case 0x0006: return "PopupMenuStart";
- case 0x0007: return "PopupMenuEnd";
- case 0x000C: return "ContextHelpStart";
- case 0x000D: return "ContextHelpEnd";
- case 0x000E: return "DragDropStart";
- case 0x000F: return "DragDropEnd";
- case 0x0010: return "DialogStart";
- case 0x0011: return "DialogEnd";
- case 0x0012: return "ScrollingStart";
- case 0x0013: return "ScrollingEnd";
- case 0x0018: return "MenuCommand";
-
- case 0x0116: return "TableModelChanged";
- case 0x011B: return "TextCaretMoved";
-
- case 0x8000: return "ObjectCreated";
- case 0x8001: return "ObjectDestroyed";
- case 0x8002: return "ObjectShow";
- case 0x8003: return "ObjectHide";
- case 0x8004: return "ObjectReorder";
- case 0x8005: return "Focus";
- case 0x8006: return "Selection";
- case 0x8007: return "SelectionAdd";
- case 0x8008: return "SelectionRemove";
- case 0x8009: return "SelectionWithin";
- case 0x800A: return "StateChanged";
- case 0x800B: return "LocationChanged";
- case 0x800C: return "NameChanged";
- case 0x800D: return "DescriptionChanged";
- case 0x800E: return "ValueChanged";
- case 0x800F: return "ParentChanged";
- case 0x80A0: return "HelpChanged";
- case 0x80B0: return "DefaultActionChanged";
- case 0x80C0: return "AcceleratorChanged";
- default: return "Unknown Event";
- }
-}
-
QAccessible::State state(QWidget * const widget)
{
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget);
const EventList list = QTestAccessibility::events();
if (!list.isEmpty()) {
qWarning("%d accessibility event(s) were not handled in testfunction '%s':", list.count(),
- QString(QTest::currentTestFunction()).toAscii().constData());
+ QString(QTest::currentTestFunction()).toLatin1().constData());
for (int i = 0; i < list.count(); ++i)
- qWarning(" %d: Object: %p Event: '%s' (%d) Child: %d", i + 1, list.at(i).object,
- eventName(list.at(i).event).toAscii().constData(), list.at(i).event, list.at(i).child);
+ qWarning(" %d: Object: %p Event: '%s' Child: %d", i + 1, list.at(i)->object(),
+ qAccessibleEventString(list.at(i)->type()), list.at(i)->child());
}
QTestAccessibility::clearEvents();
}
button->setObjectName(QString("Olaf"));
button->show();
- QVERIFY_EVENT(button, 0, QAccessible::ObjectShow);
+ QAccessibleEvent showEvent(button, QAccessible::ObjectShow);
+ // some platforms might send other events first, (such as state change event active=1)
+ QVERIFY(QTestAccessibility::containsEvent(&showEvent));
button->setFocus(Qt::MouseFocusReason);
QTestAccessibility::clearEvents();
QTest::mouseClick(button, Qt::LeftButton, 0);
- QVERIFY_EVENT(button, 0, QAccessible::StateChanged);
- QVERIFY_EVENT(button, 0, QAccessible::StateChanged);
button->setAccessibleName("Olaf the second");
- QVERIFY_EVENT(button, 0, QAccessible::NameChanged);
+ QAccessibleEvent nameEvent(button, QAccessible::NameChanged);
+ QVERIFY_EVENT(&nameEvent);
button->setAccessibleDescription("This is a button labeled Olaf");
- QVERIFY_EVENT(button, 0, QAccessible::DescriptionChanged);
+ QAccessibleEvent descEvent(button, QAccessible::DescriptionChanged);
+ QVERIFY_EVENT(&descEvent);
button->hide();
- QVERIFY_EVENT(button, 0, QAccessible::ObjectHide);
+ QAccessibleEvent hideEvent(button, QAccessible::ObjectHide);
+ // some platforms might send other events first, (such as state change event active=1)
+ QVERIFY(QTestAccessibility::containsEvent(&hideEvent));
delete button;
}
int i = 0;
box->addWidget(new QComboBox(w));
- box->addWidget(new QPushButton(QString::fromAscii("widget text %1").arg(i++), w));
+ box->addWidget(new QPushButton(QString::fromLatin1("widget text %1").arg(i++), w));
box->addWidget(new QHeaderView(Qt::Vertical, w));
box->addWidget(new QTreeView(w));
box->addWidget(new QTreeWidget(w));
box->addWidget(new QTableWidget(w));
box->addWidget(new QCalendarWidget(w));
box->addWidget(new QDialogButtonBox(w));
- box->addWidget(new QGroupBox(QString::fromAscii("widget text %1").arg(i++), w));
+ box->addWidget(new QGroupBox(QString::fromLatin1("widget text %1").arg(i++), w));
box->addWidget(new QFrame(w));
- box->addWidget(new QLineEdit(QString::fromAscii("widget text %1").arg(i++), w));
+ box->addWidget(new QLineEdit(QString::fromLatin1("widget text %1").arg(i++), w));
box->addWidget(new QProgressBar(w));
box->addWidget(new QTabWidget(w));
- box->addWidget(new QCheckBox(QString::fromAscii("widget text %1").arg(i++), w));
- box->addWidget(new QRadioButton(QString::fromAscii("widget text %1").arg(i++), w));
+ box->addWidget(new QCheckBox(QString::fromLatin1("widget text %1").arg(i++), w));
+ box->addWidget(new QRadioButton(QString::fromLatin1("widget text %1").arg(i++), w));
box->addWidget(new QDial(w));
box->addWidget(new QScrollBar(w));
box->addWidget(new QSlider(w));
box->addWidget(new QDateTimeEdit(w));
box->addWidget(new QDoubleSpinBox(w));
box->addWidget(new QSpinBox(w));
- box->addWidget(new QLabel(QString::fromAscii("widget text %1").arg(i++), w));
+ box->addWidget(new QLabel(QString::fromLatin1("widget text %1").arg(i++), w));
box->addWidget(new QLCDNumber(w));
box->addWidget(new QStackedWidget(w));
box->addWidget(new QToolBox(w));
- box->addWidget(new QLabel(QString::fromAscii("widget text %1").arg(i++), w));
- box->addWidget(new QTextEdit(QString::fromAscii("widget text %1").arg(i++), w));
+ box->addWidget(new QLabel(QString::fromLatin1("widget text %1").arg(i++), w));
+ box->addWidget(new QTextEdit(QString::fromLatin1("widget text %1").arg(i++), w));
/* Not in the list
* QAbstractItemView, QGraphicsView, QScrollArea,
* QToolButton, QDockWidget, QFocusFrame, QMainWindow, QMenu, QMenuBar, QSizeGrip, QSplashScreen, QSplitterHandle,
- * QStatusBar, QSvgWidget, QTabBar, QToolBar, QWorkspace, QSplitter
+ * QStatusBar, QSvgWidget, QTabBar, QToolBar, QSplitter
*/
return w;
}
window->show();
QVERIFY(!state(window).invisible);
QVERIFY(!state(child).invisible);
- QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(window, 0, QAccessible::ObjectShow)));
- QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(child, 0, QAccessible::ObjectShow)));
+
+ QAccessibleEvent show(window, QAccessible::ObjectShow);
+ QVERIFY(QTestAccessibility::containsEvent(&show));
+ QAccessibleEvent showChild(child, QAccessible::ObjectShow);
+ QVERIFY(QTestAccessibility::containsEvent(&showChild));
QTestAccessibility::clearEvents();
// hide() and veryfy that both window and child are invisible and get ObjectHide events.
window->hide();
QVERIFY(state(window).invisible);
QVERIFY(state(child).invisible);
- QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(window, 0, QAccessible::ObjectHide)));
- QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(child, 0, QAccessible::ObjectHide)));
+ QAccessibleEvent hide(window, QAccessible::ObjectHide);
+ QVERIFY(QTestAccessibility::containsEvent(&hide));
+ QAccessibleEvent hideChild(child, QAccessible::ObjectHide);
+ QVERIFY(QTestAccessibility::containsEvent(&hideChild));
QTestAccessibility::clearEvents();
delete window;
{
QPushButton *button = new QPushButton;
button->show();
+ QVERIFY(QTest::qWaitForWindowExposed(button));
button->clearFocus();
QCOMPARE(button->hasFocus(), false);
QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(button);
void tst_QAccessibility::mainWindowTest()
{
+ {
QMainWindow *mw = new QMainWindow;
mw->resize(300, 200);
mw->show(); // triggers layout
+ qApp->setActiveWindow(mw);
QLatin1String name = QLatin1String("I am the main window");
mw->setWindowTitle(name);
- QTest::qWaitForWindowShown(mw);
- QVERIFY_EVENT(mw, 0, QAccessible::ObjectShow);
+ QVERIFY(QTest::qWaitForWindowActive(mw));
- QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(mw);
- QCOMPARE(interface->text(QAccessible::Name), name);
- QCOMPARE(interface->role(), QAccessible::Window);
- delete interface;
+ // The order of events is not really that important.
+ QAccessibleEvent show(mw, QAccessible::ObjectShow);
+ QVERIFY(QTestAccessibility::containsEvent(&show));
+ QAccessible::State activeState;
+ activeState.active = true;
+ QAccessibleStateChangeEvent active(mw, activeState);
+ QVERIFY(QTestAccessibility::containsEvent(&active));
+
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(mw);
+ QCOMPARE(iface->text(QAccessible::Name), name);
+ QCOMPARE(iface->role(), QAccessible::Window);
+ QVERIFY(iface->state().active);
+
+
+ delete iface;
delete mw;
+ }
QTestAccessibility::clearEvents();
+
+ {
+ QWindow window;
+ window.setGeometry(80, 80, 40, 40);
+ window.show();
+ QTRY_VERIFY(QGuiApplication::focusWindow() == &window);
+
+// We currently don't have an accessible interface for QWindow
+// the active state is either in the QMainWindow or QQuickView
+// QAIPtr windowIface(QAccessible::queryAccessibleInterface(&window));
+// QVERIFY(windowIface->state().active);
+
+ QAccessible::State activeState;
+ activeState.active = true;
+ QAccessibleStateChangeEvent active(&window, activeState);
+ QVERIFY_EVENT(&active);
+
+ QWindow child;
+ child.setParent(&window);
+ child.setGeometry(10, 10, 20, 20);
+ child.show();
+
+ child.requestActivateWindow();
+ QTRY_VERIFY(QGuiApplication::focusWindow() == &child);
+
+ QAccessibleStateChangeEvent deactivate(&window, activeState);
+ QVERIFY_EVENT(&deactivate); // deactivation of parent
+
+ QAccessibleStateChangeEvent activeChild(&child, activeState);
+ QVERIFY_EVENT(&activeChild);
+ }
}
class CounterButton : public QPushButton {
interface = QAccessible::queryAccessibleInterface(&toggleButton);
actionInterface = interface->actionInterface();
QCOMPARE(interface->role(), QAccessible::CheckBox);
- QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::checkAction() << QAccessibleActionInterface::setFocusAction());
- QCOMPARE(actionInterface->localizedActionDescription(QAccessibleActionInterface::checkAction()), QString("Checks the checkbox"));
+ QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::toggleAction() << QAccessibleActionInterface::setFocusAction());
+ QCOMPARE(actionInterface->localizedActionDescription(QAccessibleActionInterface::toggleAction()), QString("Toggles the state"));
QVERIFY(!toggleButton.isChecked());
QVERIFY(!interface->state().checked);
- actionInterface->doAction(QAccessibleActionInterface::checkAction());
+ actionInterface->doAction(QAccessibleActionInterface::toggleAction());
QTest::qWait(500);
QVERIFY(toggleButton.isChecked());
- QCOMPARE(actionInterface->actionNames().at(0), QAccessibleActionInterface::uncheckAction());
+ QCOMPARE(actionInterface->actionNames().at(0), QAccessibleActionInterface::toggleAction());
QVERIFY(interface->state().checked);
delete interface;
delete menu;
}
+
+ QTestAccessibility::clearEvents();
+ {
// test check box
interface = QAccessible::queryAccessibleInterface(&checkBox);
actionInterface = interface->actionInterface();
QCOMPARE(interface->role(), QAccessible::CheckBox);
- QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::checkAction() << QAccessibleActionInterface::setFocusAction());
+ QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::toggleAction() << QAccessibleActionInterface::setFocusAction());
QVERIFY(!interface->state().checked);
- actionInterface->doAction(QAccessibleActionInterface::checkAction());
+ actionInterface->doAction(QAccessibleActionInterface::toggleAction());
+
QTest::qWait(500);
- QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::uncheckAction() << QAccessibleActionInterface::setFocusAction());
+ QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::toggleAction() << QAccessibleActionInterface::setFocusAction());
QVERIFY(interface->state().checked);
QVERIFY(checkBox.isChecked());
+ QAccessible::State st;
+ st.checked = true;
+ QAccessibleStateChangeEvent ev(&checkBox, st);
+ QVERIFY_EVENT(&ev);
+ checkBox.setChecked(false);
+ QVERIFY_EVENT(&ev);
delete interface;
+ }
+ {
// test radiobutton
interface = QAccessible::queryAccessibleInterface(&radio);
actionInterface = interface->actionInterface();
QCOMPARE(interface->role(), QAccessible::RadioButton);
- QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::checkAction() << QAccessibleActionInterface::setFocusAction());
+ QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::toggleAction() << QAccessibleActionInterface::setFocusAction());
QVERIFY(!interface->state().checked);
- actionInterface->doAction(QAccessibleActionInterface::checkAction());
+ actionInterface->doAction(QAccessibleActionInterface::toggleAction());
QTest::qWait(500);
- QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::checkAction() << QAccessibleActionInterface::setFocusAction());
+ QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::toggleAction() << QAccessibleActionInterface::setFocusAction());
QVERIFY(interface->state().checked);
- QVERIFY(checkBox.isChecked());
+ QVERIFY(radio.isChecked());
+ QAccessible::State st;
+ st.checked = true;
+ QAccessibleStateChangeEvent ev(&radio, st);
+ QVERIFY_EVENT(&ev);
delete interface;
+ }
// // test standard toolbutton
// QVERIFY(QAccessible::queryAccessibleInterface(&toolbutton, &test));
// QCOMPARE(test->actionText(test->defaultAction(2), QAccessible::Name, 2), QString("Open"));
// QCOMPARE(test->state(2), (int)QAccessible::HasPopup);
// test->release();
-
- QTestAccessibility::clearEvents();
}
void tst_QAccessibility::scrollBarTest()
scrollBar->resize(200, 50);
scrollBar->show();
QVERIFY(!scrollBarInterface->state().invisible);
- QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(scrollBar, 0, QAccessible::ObjectShow)));
+ QAccessibleEvent show(scrollBar, QAccessible::ObjectShow);
+ QVERIFY(QTestAccessibility::containsEvent(&show));
QTestAccessibility::clearEvents();
scrollBar->hide();
QVERIFY(scrollBarInterface->state().invisible);
- QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(scrollBar, 0, QAccessible::ObjectHide)));
+ QAccessibleEvent hide(scrollBar, QAccessible::ObjectHide);
+ QVERIFY(QTestAccessibility::containsEvent(&hide));
QTestAccessibility::clearEvents();
// Test that the left/right subcontrols are set to unavailable when the scrollBar is at the minimum/maximum.
QVERIFY(interface);
QCOMPARE(interface->role(), QAccessible::SpinBox);
+ QVERIFY(QTest::qWaitForWindowExposed(spinBox));
+
const QRect widgetRect = spinBox->geometry();
const QRect accessibleRect = interface->rect();
QCOMPARE(accessibleRect, widgetRect);
QTestAccessibility::clearEvents();
QTest::keyPress(spinBox, Qt::Key_Up);
QTest::qWait(200);
- EventList events = QTestAccessibility::events();
- QTestAccessibilityEvent expectedEvent(spinBox, 0, (int)QAccessible::ValueChanged);
- QVERIFY(events.contains(expectedEvent));
+ QAccessibleValueChangeEvent expectedEvent(spinBox, spinBox->value());
+ QVERIFY(QTestAccessibility::containsEvent(&expectedEvent));
delete spinBox;
QTestAccessibility::clearEvents();
}
QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(doubleSpinBox);
QVERIFY(interface);
+ QVERIFY(QTest::qWaitForWindowExposed(doubleSpinBox));
+
const QRect widgetRect = doubleSpinBox->geometry();
const QRect accessibleRect = interface->rect();
QCOMPARE(accessibleRect, widgetRect);
QTestAccessibility::clearEvents();
}
+static QRect characterRect(const QTextEdit &edit, int offset)
+{
+ QTextBlock block = edit.document()->findBlock(offset);
+ QTextLayout *layout = block.layout();
+ QPointF layoutPosition = layout->position();
+ int relativeOffset = offset - block.position();
+ QTextLine line = layout->lineForTextPosition(relativeOffset);
+ QFontMetrics fm(edit.font());
+ QChar ch = edit.document()->characterAt(offset);
+ int w = fm.width(ch);
+ int h = fm.height();
+
+ qreal x = line.cursorToX(relativeOffset);
+ QRect r(layoutPosition.x() + x, layoutPosition.y() + line.y(), w, h);
+ r.moveTo(edit.viewport()->mapToGlobal(r.topLeft()));
+
+ return r;
+}
+
void tst_QAccessibility::textEditTest()
{
- {
- QTextEdit edit;
- int startOffset;
- int endOffset;
- QString text = "hello world\nhow are you today?\n";
- edit.setText(text);
- edit.show();
+ for (int pass = 0; pass < 2; ++pass) {
+ {
+ QTextEdit edit;
+ int startOffset;
+ int endOffset;
+ // create two blocks of text. The first block has two lines.
+ QString text = "<p>hello world.<br/>How are you today?</p><p>I'm fine, thanks</p>";
+ edit.setHtml(text);
+ if (pass == 1) {
+ QFont font("Helvetica");
+ font.setPointSizeF(12.5);
+ font.setWordSpacing(1.1);
+ edit.setFont(font);
+ }
- QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&edit);
- QCOMPARE(iface->text(QAccessible::Value), text);
- QCOMPARE(iface->textInterface()->textAtOffset(8, QAccessible2::WordBoundary, &startOffset, &endOffset), QString("world"));
- QCOMPARE(startOffset, 6);
- QCOMPARE(endOffset, 11);
- QCOMPARE(iface->textInterface()->textAtOffset(14, QAccessible2::LineBoundary, &startOffset, &endOffset), QString("how are you today?"));
- QCOMPARE(startOffset, 12);
- QCOMPARE(endOffset, 30);
- QCOMPARE(iface->textInterface()->characterCount(), 31);
- QFontMetrics fm(edit.font());
- QCOMPARE(iface->textInterface()->characterRect(0, QAccessible2::RelativeToParent).size(), QSize(fm.width("h"), fm.height()));
- QCOMPARE(iface->textInterface()->characterRect(5, QAccessible2::RelativeToParent).size(), QSize(fm.width(" "), fm.height()));
- QCOMPARE(iface->textInterface()->characterRect(6, QAccessible2::RelativeToParent).size(), QSize(fm.width("w"), fm.height()));
+ edit.show();
+ QTest::qWaitForWindowShown(&edit);
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&edit);
+ QCOMPARE(iface->text(QAccessible::Value), edit.toPlainText());
+ QCOMPARE(iface->textInterface()->textAtOffset(8, QAccessible2::WordBoundary, &startOffset, &endOffset), QString("world"));
+ QCOMPARE(startOffset, 6);
+ QCOMPARE(endOffset, 11);
+ QCOMPARE(iface->textInterface()->textAtOffset(15, QAccessible2::LineBoundary, &startOffset, &endOffset), QString("How are you today?"));
+ QCOMPARE(startOffset, 13);
+ QCOMPARE(endOffset, 31);
+ QCOMPARE(iface->textInterface()->characterCount(), 48);
+ QFontMetrics fm(edit.font());
+ QCOMPARE(iface->textInterface()->characterRect(0).size(), QSize(fm.width("h"), fm.height()));
+ QCOMPARE(iface->textInterface()->characterRect(5).size(), QSize(fm.width(" "), fm.height()));
+ QCOMPARE(iface->textInterface()->characterRect(6).size(), QSize(fm.width("w"), fm.height()));
+
+ int offset = 10;
+ QCOMPARE(iface->textInterface()->text(offset, offset + 1), QStringLiteral("d"));
+ QCOMPARE(iface->textInterface()->characterRect(offset), characterRect(edit, offset));
+ offset = 13;
+ QCOMPARE(iface->textInterface()->text(offset, offset + 1), QStringLiteral("H"));
+ QCOMPARE(iface->textInterface()->characterRect(offset), characterRect(edit, offset));
+ offset = 21;
+ QCOMPARE(iface->textInterface()->text(offset, offset + 1), QStringLiteral("y"));
+ QCOMPARE(iface->textInterface()->characterRect(offset), characterRect(edit, offset));
+ offset = 32;
+ QCOMPARE(iface->textInterface()->text(offset, offset + 1), QStringLiteral("I"));
+ QCOMPARE(iface->textInterface()->characterRect(offset), characterRect(edit, offset));
+
+ QTestAccessibility::clearEvents();
+
+ // select text
+ QTextCursor c = edit.textCursor();
+ c.setPosition(2);
+ c.setPosition(4, QTextCursor::KeepAnchor);
+ edit.setTextCursor(c);
+ QAccessibleTextSelectionEvent sel(&edit, 2, 4);
+ QVERIFY_EVENT(&sel);
+
+ edit.selectAll();
+ int end = edit.textCursor().position();
+ sel.setCursorPosition(end);
+ sel.setSelection(0, end);
+ QVERIFY_EVENT(&sel);
+ }
+ QTestAccessibility::clearEvents();
}
- QTestAccessibility::clearEvents();
}
void tst_QAccessibility::textBrowserTest()
QMdiArea mdiArea;
mdiArea.show();
qApp->setActiveWindow(&mdiArea);
-#if defined(Q_OS_UNIX)
- QCoreApplication::processEvents();
- QTest::qWait(150);
-#endif
+ QVERIFY(QTest::qWaitForWindowActive(&mdiArea));
+
const int subWindowCount = 5;
for (int i = 0; i < subWindowCount; ++i) {
QMdiSubWindow *window = mdiArea.addSubWindow(new QPushButton("QAccessibilityTest"));
+ window->setAttribute(Qt::WA_LayoutUsesWidgetRect);
window->show();
// Parts of this test requires that the sub windows are placed next
// to each other. In order to achieve that QMdiArea must have
const QRect widgetGeometry = testWindow->contentsRect();
const QPoint globalWidgetPos = QPoint(globalPos.x() + widgetGeometry.x(),
globalPos.y() + widgetGeometry.y());
+#ifdef Q_OS_MAC
+ QSKIP("QTBUG-22812");
+#endif
QCOMPARE(childRect(interface), QRect(globalWidgetPos, widgetGeometry.size()));
// childAt
void tst_QAccessibility::lineEditTest()
{
+ QWidget *toplevel = new QWidget;
+ {
QLineEdit *le = new QLineEdit;
- QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(le);
+ QAIPtr iface(QAccessible::queryAccessibleInterface(le));
QVERIFY(iface);
le->show();
QCOMPARE(iface->childCount(), 0);
QVERIFY(iface->state().sizeable);
QVERIFY(iface->state().movable);
- QCOMPARE(bool(iface->state().focusable), le->isActiveWindow());
+ QVERIFY(iface->state().focusable);
QVERIFY(iface->state().selectable);
QVERIFY(iface->state().hasPopup);
QCOMPARE(bool(iface->state().focused), le->hasFocus());
QVERIFY(!(iface->state().passwordEdit));
QCOMPARE(iface->text(QAccessible::Value), secret);
- QWidget *toplevel = new QWidget;
le->setParent(toplevel);
toplevel->show();
QApplication::processEvents();
QVERIFY(!(iface->state().sizeable));
QVERIFY(!(iface->state().movable));
- QCOMPARE(bool(iface->state().focusable), le->isActiveWindow());
+ QVERIFY(iface->state().focusable);
QVERIFY(iface->state().selectable);
QVERIFY(iface->state().hasPopup);
QCOMPARE(bool(iface->state().focused), le->hasFocus());
le->setFocus(Qt::TabFocusReason);
QTestAccessibility::clearEvents();
le2->setFocus(Qt::TabFocusReason);
- QTRY_VERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(le2, 0, QAccessible::Focus)));
+ QAccessibleEvent ev(le2, QAccessible::Focus);
+ QTRY_VERIFY(QTestAccessibility::containsEvent(&ev));
le->setText(QLatin1String("500"));
le->setValidator(new QIntValidator());
iface->setText(QAccessible::Value, QLatin1String("This text is not a number"));
QCOMPARE(le->text(), QLatin1String("500"));
- delete iface;
delete le;
delete le2;
- QTestAccessibility::clearEvents();
+ }
- // IA2
+ {
+ // Text interface to get the current text
QString cite = "I always pass on good advice. It is the only thing to do with it. It is never of any use to oneself. --Oscar Wilde";
QLineEdit *le3 = new QLineEdit(cite, toplevel);
- iface = QAccessible::queryAccessibleInterface(le3);
+ le3->show();
+ QAIPtr iface(QAccessible::queryAccessibleInterface(le3));
QAccessibleTextInterface* textIface = iface->textInterface();
le3->deselect();
+ QTestAccessibility::clearEvents();
le3->setCursorPosition(3);
QCOMPARE(textIface->cursorPosition(), 3);
- QTRY_VERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(le3, 0, QAccessible::TextCaretMoved)));
+
+ QAccessibleTextCursorEvent caretEvent(le3, 3);
+ QTRY_VERIFY(QTestAccessibility::containsEvent(&caretEvent));
QCOMPARE(textIface->selectionCount(), 0);
QTestAccessibility::clearEvents();
QCOMPARE(textIface->textAtOffset(8, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(" "));
QCOMPARE(textIface->textAtOffset(25, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("advice"));
QCOMPARE(textIface->textAtOffset(92, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("oneself"));
+ QCOMPARE(textIface->textAtOffset(101, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(". --"));
QCOMPARE(textIface->textBeforeOffset(5, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(" "));
QCOMPARE(textIface->textAfterOffset(5, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(" "));
QCOMPARE(textIface->textAtOffset(5, QAccessible2::LineBoundary,&start,&end), cite);
QCOMPARE(textIface->textAtOffset(5, QAccessible2::NoBoundary,&start,&end), cite);
- delete iface;
+ QTestAccessibility::clearEvents();
+ }
+
+ {
+ // Test events: cursor movement, selection, text changes
+ QString text = "Hello, world";
+ QLineEdit *lineEdit = new QLineEdit(text, toplevel);
+ lineEdit->show();
+ QTestAccessibility::clearEvents();
+ // cursor
+ lineEdit->setCursorPosition(5);
+ QAccessibleTextCursorEvent cursorEvent(lineEdit, 5);
+ QVERIFY_EVENT(&cursorEvent);
+ lineEdit->setCursorPosition(0);
+ cursorEvent.setCursorPosition(0);
+ QVERIFY_EVENT(&cursorEvent);
+
+ // selection
+ lineEdit->setSelection(2, 4);
+
+ QAccessibleTextSelectionEvent sel(lineEdit, 2, 2+4);
+ QVERIFY_EVENT(&sel);
+
+ lineEdit->selectAll();
+ sel.setSelection(0, lineEdit->text().length());
+ sel.setCursorPosition(lineEdit->text().length());
+ QVERIFY_EVENT(&sel);
+
+ lineEdit->setSelection(10, -4);
+ QCOMPARE(lineEdit->cursorPosition(), 6);
+ QAccessibleTextSelectionEvent sel2(lineEdit, 6, 10);
+ sel2.setCursorPosition(6);
+ QVERIFY_EVENT(&sel2);
+
+ lineEdit->deselect();
+ QAccessibleTextSelectionEvent sel3(lineEdit, -1, -1);
+ sel3.setCursorPosition(6);
+ QVERIFY_EVENT(&sel3);
+
+ // editing
+ lineEdit->clear();
+ // FIXME: improve redundant updates
+ QAccessibleTextRemoveEvent remove(lineEdit, 0, text);
+ QVERIFY_EVENT(&remove);
+
+ QAccessibleTextSelectionEvent noSel(lineEdit, -1, -1);
+ QVERIFY_EVENT(&noSel);
+ QAccessibleTextCursorEvent cursor(lineEdit, 0);
+ QVERIFY_EVENT(&cursor);
+
+ lineEdit->setText("foo");
+ cursorEvent.setCursorPosition(3);
+ QVERIFY_EVENT(&cursorEvent);
+
+ QAccessibleTextInsertEvent e(lineEdit, 0, "foo");
+ QVERIFY(QTestAccessibility::containsEvent(&e));
+
+ lineEdit->setText("bar");
+ QAccessibleTextUpdateEvent update(lineEdit, 0, "foo", "bar");
+ QVERIFY(QTestAccessibility::containsEvent(&update));
+
+ // FIXME check what extra events are around and get rid of them
+ QTestAccessibility::clearEvents();
+
+ QTestEventList keys;
+ keys.addKeyClick('D');
+ keys.simulate(lineEdit);
+
+ QAccessibleTextInsertEvent insertD(lineEdit, 3, "D");
+ QVERIFY_EVENT(&insertD);
+ keys.clear();
+ keys.addKeyClick('E');
+ keys.simulate(lineEdit);
+
+ QAccessibleTextInsertEvent insertE(lineEdit, 4, "E");
+ QVERIFY(QTestAccessibility::containsEvent(&insertE));
+ keys.clear();
+ keys.addKeyClick(Qt::Key_Left);
+ keys.addKeyClick(Qt::Key_Left);
+ keys.simulate(lineEdit);
+ cursorEvent.setCursorPosition(4);
+ QVERIFY(QTestAccessibility::containsEvent(&cursorEvent));
+ cursorEvent.setCursorPosition(3);
+ QVERIFY(QTestAccessibility::containsEvent(&cursorEvent));
+
+ keys.clear();
+ keys.addKeyClick('C');
+ keys.simulate(lineEdit);
+
+ QAccessibleTextInsertEvent insertC(lineEdit, 3, "C");
+ QVERIFY(QTestAccessibility::containsEvent(&insertC));
+
+ keys.clear();
+ keys.addKeyClick('O');
+ keys.simulate(lineEdit);
+ QAccessibleTextInsertEvent insertO(lineEdit, 4, "O");
+ QVERIFY(QTestAccessibility::containsEvent(&insertO));
+ }
delete toplevel;
QTestAccessibility::clearEvents();
}
-void tst_QAccessibility::workspaceTest()
+void tst_QAccessibility::groupBoxTest()
{
{
- QWorkspace workspace;
- workspace.resize(400,300);
- workspace.show();
- const int subWindowCount = 3;
- for (int i = 0; i < subWindowCount; ++i) {
- QWidget *window = workspace.addWindow(new QWidget);
- if (i > 0)
- window->move(window->x() + 1, window->y());
- window->show();
- window->resize(70, window->height());
- }
+ QGroupBox *groupBox = new QGroupBox();
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(groupBox);
- QWidgetList subWindows = workspace.windowList();
- QCOMPARE(subWindows.count(), subWindowCount);
+ groupBox->setTitle(QLatin1String("Test QGroupBox"));
- QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&workspace);
- QVERIFY(interface);
- QCOMPARE(interface->childCount(), subWindowCount);
+ QAccessibleEvent ev(groupBox, QAccessible::NameChanged);
+ QVERIFY_EVENT(&ev);
+
+ groupBox->setToolTip(QLatin1String("This group box will be used to test accessibility"));
+ QVBoxLayout *layout = new QVBoxLayout();
+ QRadioButton *rbutton = new QRadioButton();
+ layout->addWidget(rbutton);
+ groupBox->setLayout(layout);
+ QAccessibleInterface *rButtonIface = QAccessible::queryAccessibleInterface(rbutton);
+
+ QCOMPARE(iface->childCount(), 1);
+ QCOMPARE(iface->role(), QAccessible::Grouping);
+ QCOMPARE(iface->text(QAccessible::Name), QLatin1String("Test QGroupBox"));
+ QCOMPARE(iface->text(QAccessible::Description), QLatin1String("This group box will be used to test accessibility"));
+ QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > relations = rButtonIface->relations();
+ QVERIFY(relations.size() == 1);
+ QPair<QAccessibleInterface*, QAccessible::Relation> relation = relations.first();
+ QCOMPARE(relation.first->object(), groupBox);
+ QCOMPARE(relation.second, QAccessible::Label);
+
+ delete relation.first;
+
+ delete rButtonIface;
+ delete iface;
+ delete groupBox;
+ }
+
+ {
+ QGroupBox *groupBox = new QGroupBox();
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(groupBox);
+ QVERIFY(!iface->state().checkable);
+ groupBox->setCheckable(true);
+
+ groupBox->setChecked(false);
+ QAccessible::State st;
+ st.checked = true;
+ QAccessibleStateChangeEvent ev(groupBox, st);
+ QVERIFY_EVENT(&ev);
+
+ QCOMPARE(iface->role(), QAccessible::CheckBox);
+ QAccessibleActionInterface *actionIface = iface->actionInterface();
+ QVERIFY(actionIface);
+ QAccessible::State state = iface->state();
+ QVERIFY(state.checkable);
+ QVERIFY(!state.checked);
+ QVERIFY(actionIface->actionNames().contains(QAccessibleActionInterface::toggleAction()));
+ actionIface->doAction(QAccessibleActionInterface::toggleAction());
+ QVERIFY(groupBox->isChecked());
+ state = iface->state();
+ QVERIFY(state.checked);
+ QAccessibleStateChangeEvent ev2(groupBox, st);
+ QVERIFY_EVENT(&ev2);
+ delete iface;
+ delete groupBox;
}
- QTestAccessibility::clearEvents();
}
bool accessibleInterfaceLeftOf(const QAccessibleInterface *a1, const QAccessibleInterface *a2)
QVERIFY(interface);
QCOMPARE(interface->childCount(), 0);
+ QVERIFY(QTest::qWaitForWindowExposed(&dial));
+
QCOMPARE(interface->text(QAccessible::Value), QString::number(dial.value()));
QCOMPARE(interface->rect(), dial.geometry());
// Check for events
QTest::mouseClick(listView->viewport(), Qt::LeftButton, 0, listView->visualItemRect(listView->item(1)).center());
- QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(listView, 2, QAccessible::Selection)));
- QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(listView, 2, QAccessible::Focus)));
+ QAccessibleEvent selectionEvent(listView, QAccessible::Selection);
+ selectionEvent.setChild(2);
+ QAccessibleEvent focusEvent(listView, QAccessible::Focus);
+ focusEvent.setChild(2);
+ QVERIFY(QTestAccessibility::containsEvent(&selectionEvent));
+ QVERIFY(QTestAccessibility::containsEvent(&focusEvent));
QTest::mouseClick(listView->viewport(), Qt::LeftButton, 0, listView->visualItemRect(listView->item(2)).center());
- QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(listView, 3, QAccessible::Selection)));
- QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(listView, 3, QAccessible::Focus)));
+
+ QAccessibleEvent selectionEvent2(listView, QAccessible::Selection);
+ selectionEvent2.setChild(3);
+ QAccessibleEvent focusEvent2(listView, QAccessible::Focus);
+ focusEvent2.setChild(3);
+ QVERIFY(QTestAccessibility::containsEvent(&selectionEvent2));
+ QVERIFY(QTestAccessibility::containsEvent(&focusEvent2));
listView->addItem("Munich");
QCOMPARE(iface->childCount(), 4);
{ // not editable combobox
QComboBox combo;
combo.addItems(QStringList() << "one" << "two" << "three");
+ // Fully decorated windows have a minimum width of 160 on Windows.
+ combo.setMinimumWidth(200);
combo.show();
+ QVERIFY(QTest::qWaitForWindowShown(&combo));
+
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&combo);
QCOMPARE(verifyHierarchy(iface), 0);
QVERIFY(iface->actionInterface());
QCOMPARE(iface->actionInterface()->actionNames(), QStringList() << QAccessibleActionInterface::showMenuAction());
iface->actionInterface()->doAction(QAccessibleActionInterface::showMenuAction());
- QVERIFY(combo.view()->isVisible());
+ QTRY_VERIFY(combo.view()->isVisible());
delete iface;
}
{ // editable combobox
QComboBox editableCombo;
+ editableCombo.setMinimumWidth(200);
editableCombo.show();
editableCombo.setEditable(true);
editableCombo.addItems(QStringList() << "foo" << "bar" << "baz");
QCOMPARE(imageInterface->imageSize(), testPixmap.size());
QCOMPARE(imageInterface->imageDescription(), QString::fromLatin1("Test Description"));
- QCOMPARE(imageInterface->imagePosition(QAccessible2::RelativeToParent), imageLabel.geometry());
+ const QPoint labelPos = imageLabel.mapToGlobal(QPoint(0,0));
+ QCOMPARE(imageInterface->imagePosition().topLeft(), labelPos);
delete acc_label;
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.
+ // Ideally it should be extended to test all aspects of the bridge.
+#ifdef Q_OS_WIN
+ // First, test MSAA part of bridge
+ QWidget *window = new QWidget;
+ QVBoxLayout *lay = new QVBoxLayout(window);
+ QPushButton *button = new QPushButton(tr("Push me"), window);
+ QTextEdit *te = new QTextEdit(window);
+ te->setText(QLatin1String("hello world\nhow are you today?\n"));
+ lay->addWidget(button);
+ lay->addWidget(te);
+
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(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 *iaccButton;
+
+ VARIANT varChild;
+ HRESULT hr = ::AccessibleObjectFromPoint(pt, &iaccButton, &varChild);
+ QVERIFY(SUCCEEDED(hr));
+ VARIANT varSELF;
+ varSELF.vt = VT_I4;
+ varSELF.lVal = 0;
+
+ // **** Test get_accRole ****
+ VARIANT varRole;
+ hr = iaccButton->get_accRole(varSELF, &varRole);
+ QVERIFY(SUCCEEDED(hr));
+
+ QCOMPARE(varRole.vt, (VARTYPE)VT_I4);
+ QCOMPARE(varRole.lVal, (LONG)ROLE_SYSTEM_PUSHBUTTON);
+
+ // **** Test accLocation ****
+ long x, y, w, h;
+ hr = iaccButton->accLocation(&x, &y, &w, &h, varSELF);
+ QCOMPARE(buttonRect, QRect(x, y, w, h));
+
+#ifdef QT_SUPPORTS_IACCESSIBLE2
+ // Test IAccessible2 part of bridge
+ 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();
+
+ /**************************************************
+ * 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
+ iaccTextEdit->Release();
+
+
+ iaccWindow->Release();
+ QTestAccessibility::clearEvents();
+#endif
+}
+
QTEST_MAIN(tst_QAccessibility)
#include "tst_qaccessibility.moc"