diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2009-03-23 09:18:55 (GMT) |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2009-03-23 09:18:55 (GMT) |
commit | e5fcad302d86d316390c6b0f62759a067313e8a9 (patch) | |
tree | c2afbf6f1066b6ce261f14341cf6d310e5595bc1 /tests/auto/qaccessibility | |
download | Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.zip Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.gz Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.bz2 |
Long live Qt 4.5!
Diffstat (limited to 'tests/auto/qaccessibility')
-rw-r--r-- | tests/auto/qaccessibility/.gitignore | 1 | ||||
-rw-r--r-- | tests/auto/qaccessibility/qaccessibility.pro | 11 | ||||
-rw-r--r-- | tests/auto/qaccessibility/tst_qaccessibility.cpp | 4058 |
3 files changed, 4070 insertions, 0 deletions
diff --git a/tests/auto/qaccessibility/.gitignore b/tests/auto/qaccessibility/.gitignore new file mode 100644 index 0000000..6fd6ae2 --- /dev/null +++ b/tests/auto/qaccessibility/.gitignore @@ -0,0 +1 @@ +tst_qaccessibility diff --git a/tests/auto/qaccessibility/qaccessibility.pro b/tests/auto/qaccessibility/qaccessibility.pro new file mode 100644 index 0000000..e33c04d --- /dev/null +++ b/tests/auto/qaccessibility/qaccessibility.pro @@ -0,0 +1,11 @@ +load(qttest_p4) +SOURCES += tst_qaccessibility.cpp + +unix:!mac:LIBS+=-lm +contains(QT_CONFIG, qt3support): QT += qt3support + +wince*: { + accessneeded.sources = $$QT_BUILD_TREE\plugins\accessible\*.dll + accessneeded.path = accessible + DEPLOYMENT += accessneeded +}
\ No newline at end of file diff --git a/tests/auto/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp new file mode 100644 index 0000000..d023557 --- /dev/null +++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp @@ -0,0 +1,4058 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** 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 version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#ifdef QT3_SUPPORT +#include <Qt3Support/Qt3Support> +#endif +#include <QtTest/QtTest> +#ifndef Q_OS_WINCE +#include "../../shared/util.h" +#include <QtGui> +#include <math.h> + + +#include "QtTest/qtestaccessible.h" + +#if defined(Q_OS_WINCE) +extern "C" bool SystemParametersInfoW(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni); +#define SPI_GETPLATFORMTYPE 257 +inline bool IsValidCEPlatform() { + wchar_t tszPlatform[64]; + if (SystemParametersInfoW(SPI_GETPLATFORMTYPE, sizeof(tszPlatform)/sizeof(*tszPlatform),tszPlatform,0)) { + QString platform = QString::fromUtf16(tszPlatform); + if ((platform == QLatin1String("PocketPC")) || (platform == QLatin1String("Smartphone"))) + return false; + } + return true; +} +#endif + +static inline bool verifyChild(QWidget *child, QAccessibleInterface *interface, + int index, const QRect &domain) +{ + if (!child) { + qWarning("tst_QAccessibility::verifyChild: null pointer to child."); + return false; + } + + if (!interface) { + qWarning("tst_QAccessibility::verifyChild: null pointer to interface."); + return false; + } + + // QAccessibleInterface::childAt(): + // Calculate global child position and check that the interface + // returns the correct index for that position. + QPoint globalChildPos = child->mapToGlobal(QPoint(0, 0)); + int indexFromChildAt = interface->childAt(globalChildPos.x(), globalChildPos.y()); + if (indexFromChildAt != index) { + qWarning("tst_QAccessibility::verifyChild (childAt()):"); + qWarning() << "Expected:" << index; + qWarning() << "Actual: " << indexFromChildAt; + return false; + } + + // QAccessibleInterface::rect(): + // Calculate global child geometry and check that the interface + // returns a QRect which is equal to the calculated QRect. + const QRect expectedGlobalRect = QRect(globalChildPos, child->size()); + const QRect rectFromInterface = interface->rect(index); + if (expectedGlobalRect != rectFromInterface) { + qWarning("tst_QAccessibility::verifyChild (rect()):"); + qWarning() << "Expected:" << expectedGlobalRect; + qWarning() << "Actual: " << rectFromInterface; + return false; + } + + // Verify that the child is within its domain. + if (!domain.contains(rectFromInterface)) { + qWarning("tst_QAccessibility::verifyChild: Child is not within its domain."); + return false; + } + + // Verify that we get a valid QAccessibleInterface for the child. + QAccessibleInterface *childInterface = QAccessible::queryAccessibleInterface(child); + if (!childInterface) { + qWarning("tst_QAccessibility::verifyChild: Failed to retrieve interface for child."); + return false; + } + + // QAccessibleInterface::indexOfChild(): + // Verify that indexOfChild() returns an index equal to the index passed by, + // or -1 if child is "Self" (index == 0). + int indexFromIndexOfChild = interface->indexOfChild(childInterface); + delete childInterface; + int expectedIndex = index == 0 ? -1 : index; + if (indexFromIndexOfChild != expectedIndex) { + qWarning("tst_QAccessibility::verifyChild (indexOfChild()):"); + qWarning() << "Expected:" << expectedIndex; + qWarning() << "Actual: " << indexFromIndexOfChild; + return false; + } + + // Navigate to child, compare its object and role with the interface from queryAccessibleInterface(child). + { + QAccessibleInterface *navigatedChildInterface = 0; + const int status = interface->navigate(QAccessible::Child, index, &navigatedChildInterface); + // We are navigating to a separate widget/interface, so status should be 0. + if (status != 0) + return false; + + if (navigatedChildInterface == 0) + return false; + delete navigatedChildInterface; + } + + return true; +} + +static inline int indexOfChild(QAccessibleInterface *parentInterface, QWidget *childWidget) +{ + if (!parentInterface || !childWidget) + return -1; + QAccessibleInterface *childInterface = QAccessibleInterface::queryAccessibleInterface(childWidget); + if (!childInterface) + return -1; + int index = parentInterface->indexOfChild(childInterface); + delete childInterface; + return index; +} + +#define EXPECT(cond) \ + do { \ + if (!errorAt && !(cond)) { \ + errorAt = __LINE__; \ + qWarning("level: %d, middle: %d, role: %d (%s)", treelevel, middle, iface->role(0), #cond); \ + } \ + } while (0) + +static int verifyHierarchy(QAccessibleInterface *iface) +{ + int errorAt = 0; + int entry = 0; + static int treelevel = 0; // for error diagnostics + QAccessibleInterface *middleChild, *if2, *if3; + middleChild = 0; + ++treelevel; + int middle = iface->childCount()/2 + 1; + if (iface->childCount() >= 2) { + entry = iface->navigate(QAccessible::Child, middle, &middleChild); + } + for (int i = 0; i < iface->childCount() && !errorAt; ++i) { + entry = iface->navigate(QAccessible::Child, i + 1, &if2); + if (entry == 0) { + // navigate Ancestor... + QAccessibleInterface *parent = 0; + entry = if2->navigate(QAccessible::Ancestor, 1, &parent); + EXPECT(entry == 0 && iface->object() == parent->object()); + delete parent; + + // navigate Sibling... + if (middleChild) { + entry = if2->navigate(QAccessible::Sibling, middle, &if3); + EXPECT(entry == 0 && if3->object() == middleChild->object()); + delete if3; + EXPECT(iface->indexOfChild(middleChild) == middle); + } + + // verify children... + if (!errorAt) + errorAt = verifyHierarchy(if2); + delete if2; + } else { + // leaf nodes + } + } + delete middleChild; + + --treelevel; + return errorAt; +} + + +//TESTED_FILES= + +class tst_QAccessibility : public QObject +{ + Q_OBJECT +public: + tst_QAccessibility(); + virtual ~tst_QAccessibility(); + + + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); +private slots: + void eventTest(); + void customWidget(); + void deletedWidget(); + + void childCount(); + void childAt(); // also indexOfChild + void relationTo(); + void navigateGeometric(); + void navigateHierarchy(); + void navigateSlider(); + void navigateCovered(); + void navigateControllers(); + void navigateLabels(); + void text(); + void setText(); + void hideShowTest(); + + void userActionCount(); + void actionText(); + void doAction(); + + void buttonTest(); + void sliderTest(); + void scrollBarTest(); + void tabTest(); + void menuTest(); + void spinBoxTest(); + void doubleSpinBoxTest(); + void textEditTest(); + void textBrowserTest(); + void listViewTest(); + void mdiAreaTest(); + void mdiSubWindowTest(); + void lineEditTest(); + void workspaceTest(); + void dialogButtonBoxTest(); + void dialTest(); + void rubberBandTest(); + void abstractScrollAreaTest(); + void scrollAreaTest(); + void tableWidgetTest(); + void tableViewTest(); + void calendarWidgetTest(); + void dockWidgetTest(); + void pushButtonTest(); + void comboBoxTest(); + void accessibleName(); + void treeWidgetTest(); + void labelTest(); + +private: + QWidget *createGUI(); +}; + +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 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"; + } +} + +static QString stateNames(int state) +{ + QString stateString; + if (state == 0x00000000) stateString += " Normal"; + if (state & 0x00000001) stateString += " Unavailable"; + if (state & 0x00000002) stateString += " Selected"; + if (state & 0x00000004) stateString += " Focused"; + if (state & 0x00000008) stateString += " Pressed"; + if (state & 0x00000010) stateString += " Checked"; + if (state & 0x00000020) stateString += " Mixed"; + if (state & 0x00000040) stateString += " ReadOnly"; + if (state & 0x00000080) stateString += " HotTracked"; + if (state & 0x00000100) stateString += " DefaultButton"; + if (state & 0x00000200) stateString += " Expanded"; + if (state & 0x00000400) stateString += " Collapsed"; + if (state & 0x00000800) stateString += " Busy"; + if (state & 0x00001000) stateString += " Floating"; + if (state & 0x00002000) stateString += " Marqueed"; + if (state & 0x00004000) stateString += " Animated"; + if (state & 0x00008000) stateString += " Invisible"; + if (state & 0x00010000) stateString += " Offscreen"; + if (state & 0x00020000) stateString += " Sizeable"; + if (state & 0x00040000) stateString += " Moveable"; + if (state & 0x00080000) stateString += " SelfVoicing"; + if (state & 0x00100000) stateString += " Focusable"; + if (state & 0x00200000) stateString += " Selectable"; + if (state & 0x00400000) stateString += " Linked"; + if (state & 0x00800000) stateString += " Traversed"; + if (state & 0x01000000) stateString += " MultiSelectable"; + if (state & 0x02000000) stateString += " ExtSelectable"; + if (state & 0x04000000) stateString += " AlertLow"; + if (state & 0x08000000) stateString += " AlertMedium"; + if (state & 0x10000000) stateString += " AlertHigh"; + if (state & 0x20000000) stateString += " Protected"; + if (state & 0x3fffffff) stateString += " Valid"; + + if (stateString.isEmpty()) + stateString = "Unknown state " + QString::number(state); + + return stateString; +} + +QAccessible::State state(QWidget * const widget) +{ + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget); + Q_ASSERT(iface); + QAccessible::State state = iface->state(0); + delete iface; + return state; +} + +void printState(QWidget * const widget) +{ + qDebug() << "State for" << widget->metaObject()->className() << stateNames(state(widget)); +} + +void printState(QAccessibleInterface * const iface, const int child = 0) +{ + qDebug() << "State for" << iface->object()->metaObject()->className() << "child" << child + << iface->text(QAccessible::Name, child) << stateNames(iface->state(child)); +} + + +class QtTestAccessibleWidget: public QWidget +{ + Q_OBJECT +public: + QtTestAccessibleWidget(QWidget *parent, const char *name): QWidget(parent) + { + setObjectName(name); + QPalette pal; + pal.setColor(backgroundRole(), Qt::black);//black is beautiful + setPalette(pal); + setFixedSize(5, 5); + } +}; + +#ifdef QTEST_ACCESSIBILITY +class QtTestAccessibleWidgetIface: public QAccessibleWidget +{ +public: + QtTestAccessibleWidgetIface(QtTestAccessibleWidget *w): QAccessibleWidget(w) {} + QString text(Text t, int control) const + { + if (t == Help) + return QString::fromLatin1("Help yourself"); + return QAccessibleWidget::text(t, control); + } + static QAccessibleInterface *ifaceFactory(const QString &key, QObject *o) + { + if (key == "QtTestAccessibleWidget") + return new QtTestAccessibleWidgetIface(static_cast<QtTestAccessibleWidget*>(o)); + return 0; + } +}; +#endif + +tst_QAccessibility::tst_QAccessibility() +{ +} + +tst_QAccessibility::~tst_QAccessibility() +{ +} + +void tst_QAccessibility::initTestCase() +{ +#ifdef QTEST_ACCESSIBILITY + QTestAccessibility::initialize(); + QAccessible::installFactory(QtTestAccessibleWidgetIface::ifaceFactory); +#endif +} + +void tst_QAccessibility::cleanupTestCase() +{ +#ifdef QTEST_ACCESSIBILITY + QTestAccessibility::cleanup(); +#endif +} + +void tst_QAccessibility::init() +{ + QTestAccessibility::clearEvents(); +} + +void tst_QAccessibility::cleanup() +{ +#ifdef QTEST_ACCESSIBILITY + 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()); + 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); + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::eventTest() +{ +#ifdef QTEST_ACCESSIBILITY + QPushButton* button = new QPushButton(0); + button->setObjectName(QString("Olaf")); + + button->show(); + QVERIFY_EVENT(button, 0, QAccessible::ObjectShow); + button->setFocus(Qt::MouseFocusReason); + QTestAccessibility::clearEvents(); + QTest::mouseClick(button, Qt::LeftButton, 0, QPoint(button->width()-7,button->height()-5)); + QVERIFY_EVENT(button, 0, QAccessible::StateChanged); + QVERIFY_EVENT(button, 0, QAccessible::StateChanged); + + button->hide(); + QVERIFY_EVENT(button, 0, QAccessible::ObjectHide); + + delete button; +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::customWidget() +{ +#ifdef QTEST_ACCESSIBILITY + QtTestAccessibleWidget* widget = new QtTestAccessibleWidget(0, "Heinz"); + + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget); + QVERIFY(iface != 0); + QVERIFY(iface->isValid()); + QCOMPARE(iface->object(), (QObject*)widget); + QCOMPARE(iface->object()->objectName(), QString("Heinz")); + QCOMPARE(iface->text(QAccessible::Help, 0), QString("Help yourself")); + + delete iface; + delete widget; +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::deletedWidget() +{ +#ifdef QTEST_ACCESSIBILITY + QtTestAccessibleWidget *widget = new QtTestAccessibleWidget(0, "Ralf"); + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget); + QVERIFY(iface != 0); + QVERIFY(iface->isValid()); + QCOMPARE(iface->object(), (QObject*)widget); + + delete widget; + widget = 0; + QVERIFY(!iface->isValid()); + delete iface; +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +QWidget *tst_QAccessibility::createGUI() +{ +#if !defined(QT3_SUPPORT) + qWarning( "Should never get here without Qt3Support"); + return 0; +#else +# ifdef QTEST_ACCESSIBILITY + QWidget *toplevel = new QWidget(0, Qt::X11BypassWindowManagerHint); + QGridLayout *grid = new QGridLayout(toplevel, 2, 2); + + // topLeft - hierarchies + Q3VBox *topLeft = new Q3VBox(toplevel, "topLeft"); + topLeft->setSpacing(2); + grid->addWidget(topLeft, 0, 0); + + Q3VButtonGroup *group1 = new Q3VButtonGroup("Title1:", topLeft, "group1"); + /*QPushButton *pb1 = */ new QPushButton("Button&1", group1, "pb1"); + Q3VButtonGroup *group2 = new Q3VButtonGroup("Title2:", topLeft, "group2"); + /*QPushButton *pb2 = */ new QPushButton("Button2", group2, "pb2"); + + Q3WidgetStack *stack = new Q3WidgetStack(topLeft, "stack"); + QLabel *page1 = new QLabel("Page 1", stack, "page1"); + stack->addWidget(page1); + QLabel *page2 = new QLabel("Page 2", stack, "page2"); + stack->addWidget(page2); + QLabel *page3 = new QLabel("Page 3", stack, "page3"); + stack->addWidget(page3); + + // topRight - controlling + Q3VBox *topRight= new Q3VBox(toplevel, "topRight"); + grid->addWidget(topRight, 0, 1); + + QPushButton *pbOk = new QPushButton("Ok", topRight, "pbOk" ); + pbOk->setDefault(TRUE); + QSlider *slider = new QSlider(Qt::Horizontal, topRight, "slider"); + QLCDNumber *sliderLcd = new QLCDNumber(topRight, "sliderLcd"); + QSpinBox *spinBox = new QSpinBox(topRight, "spinBox"); + + connect(pbOk, SIGNAL(clicked()), toplevel, SLOT(close()) ); + connect(slider, SIGNAL(valueChanged(int)), sliderLcd, SLOT(display(int))); + connect(spinBox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int))); + + spinBox->setValue(50); + + // bottomLeft - labeling and controlling + Q3HBox *bottomLeft = new Q3HBox(toplevel, "bottomLeft"); + grid->addWidget(bottomLeft, 1, 0); + + QLabel *label = new QLabel("This is a &lineedit:", bottomLeft, "label"); + QLineEdit *lineedit = new QLineEdit(bottomLeft, "lineedit"); + label->setBuddy(lineedit); + QLabel *label2 = new QLabel(bottomLeft, "label2"); + + connect(lineedit, SIGNAL(textChanged(const QString&)), label2, SLOT(setText(const QString&))); + + Q3VButtonGroup *radiogroup = new Q3VButtonGroup("Exclusive &choices:", bottomLeft, "radiogroup"); + QLineEdit *frequency = new QLineEdit(radiogroup, "frequency"); + frequency->setText("100 Mhz"); + QRadioButton *radioAM = new QRadioButton("&AM", radiogroup, "radioAM"); + /* QRadioButton *radioFM = */ new QRadioButton("&FM", radiogroup, "radioFM"); + /* QRadioButton *radioSW = */ new QRadioButton("&Shortwave", radiogroup, "radioSW"); + + // bottomRight - ### empty + Q3HBox *bottomRight = new Q3HBox(toplevel, "bottomRight"); + grid->addWidget(bottomRight, 1, 1); + + toplevel->adjustSize(); // sends layout and child events + + // some tooltips + QToolTip::add(label, "A label"); + QToolTip::add(lineedit, "A line edit"); + // some whatsthis + QWhatsThis::add(label, "A label displays static text"); + QWhatsThis::add(frequency, "You can enter a single line of text here"); + + radioAM->setFocus(); + QTestAccessibility::clearEvents(); + return toplevel; +# else + Q_ASSERT(0); // this function cannot be called without accessibility support + return 0; +# endif +#endif // !QT3_SUPPORT +} + +void tst_QAccessibility::childAt() +{ +#if !defined(QT3_SUPPORT) + QSKIP("This test needs Qt3Support", SkipAll); +#else +#ifdef QTEST_ACCESSIBILITY + QWidget *toplevel = createGUI(); + QAccessibleInterface *acc_toplevel = QAccessible::queryAccessibleInterface(toplevel); + QVERIFY(acc_toplevel); + // this is necessary to have the layout setup correctly + toplevel->show(); + + QObjectList children = toplevel->queryList("QWidget", 0, 0, 0); + for (int c = 1; c <= children.count(); ++c) { + QWidget *child = qobject_cast<QWidget*>(children.at(c-1)); + QAccessibleInterface *acc_child = QAccessible::queryAccessibleInterface(child); + QVERIFY(acc_child); + QCOMPARE(acc_child->relationTo(0, acc_toplevel, 0) & QAccessible::HierarchyMask, QAccessible::Child); + + QPoint center(child->mapToGlobal(child->rect().center())); + QRect childRect(child->geometry()); + childRect.moveCenter(center); + + QCOMPARE(acc_child->rect(0), childRect); + QCOMPARE(acc_toplevel->childAt(childRect.center().x(), childRect.center().y()), c); + QCOMPARE(acc_toplevel->childAt(childRect.left(), childRect.top()), c); + QCOMPARE(acc_toplevel->childAt(childRect.left(), childRect.bottom()), c); + QCOMPARE(acc_toplevel->childAt(childRect.right(), childRect.top()), c); + QCOMPARE(acc_toplevel->childAt(childRect.right(), childRect.bottom()), c); + + QCOMPARE(acc_toplevel->indexOfChild(acc_child), c); + delete acc_child; + } + + delete acc_toplevel; + delete toplevel; + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +#endif // !QT3_SUPPORT +} + +void tst_QAccessibility::childCount() +{ +#if !defined(QT3_SUPPORT) + QSKIP("This test needs Qt3Support", SkipAll); +#else +#ifdef QTEST_ACCESSIBILITY + QWidget *toplevel = createGUI(); + QObject *topLeft = toplevel->child("topLeft"); + QObject *topRight = toplevel->child("topRight"); + QObject *bottomLeft = toplevel->child("bottomLeft"); + QObject *bottomRight = toplevel->child("bottomRight"); + + QAccessibleInterface* acc_toplevel = QAccessible::queryAccessibleInterface(toplevel); + QAccessibleInterface* acc_topLeft = QAccessible::queryAccessibleInterface(topLeft); + QAccessibleInterface* acc_topRight = QAccessible::queryAccessibleInterface(topRight); + QAccessibleInterface* acc_bottomLeft = QAccessible::queryAccessibleInterface(bottomLeft); + QAccessibleInterface* acc_bottomRight = QAccessible::queryAccessibleInterface(bottomRight); + + QVERIFY(acc_toplevel); + QVERIFY(acc_topLeft); + QVERIFY(acc_topRight); + QVERIFY(acc_bottomLeft); + QVERIFY(acc_bottomRight); + + toplevel->show(); + QCOMPARE(acc_toplevel->childCount(), toplevel->queryList("QWidget", 0, 0, 0).count()); + QCOMPARE(acc_topLeft->childCount(), topLeft->queryList("QWidget", 0, 0, 0).count()); + QCOMPARE(acc_topRight->childCount(), topRight->queryList("QWidget", 0, 0, 0).count()); + QCOMPARE(acc_bottomLeft->childCount(), bottomLeft->queryList("QWidget", 0, 0, 0).count()); + QCOMPARE(acc_bottomRight->childCount(), bottomRight->queryList("QWidget", 0, 0, 0).count()); + + delete acc_toplevel; + delete acc_topLeft; + delete acc_topRight; + delete acc_bottomLeft; + delete acc_bottomRight; + delete toplevel; + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +#endif // !QT3_SUPPORT +} + +void tst_QAccessibility::relationTo() +{ +#if !defined(QT3_SUPPORT) + QSKIP("This test needs Qt3Support", SkipAll); +#else +#ifdef QTEST_ACCESSIBILITY + QWidget *toplevel = createGUI(); + toplevel->resize(400,300); + QObject *topLeft = toplevel->child("topLeft"); + QObject *topRight = toplevel->child("topRight"); + QObject *bottomLeft = toplevel->child("bottomLeft"); + QObject *bottomRight = toplevel->child("bottomRight"); + + toplevel->show(); + + QAccessibleInterface *acc_toplevel = QAccessible::queryAccessibleInterface(toplevel); + + QAccessibleInterface *acc_topLeft = QAccessible::queryAccessibleInterface(topLeft); + QAccessibleInterface *acc_group1 = QAccessible::queryAccessibleInterface(topLeft->child("group1")); + QVERIFY(topLeft->child("group1")); + QAccessibleInterface *acc_pb1 = QAccessible::queryAccessibleInterface(topLeft->child("group1")->child("pb1")); + QAccessibleInterface *acc_group2 = QAccessible::queryAccessibleInterface(topLeft->child("group2")); + QAccessibleInterface *acc_pb2 = 0; + QAccessibleInterface *acc_stack = QAccessible::queryAccessibleInterface(topLeft->child("stack")); + QAccessibleInterface *acc_page1 = QAccessible::queryAccessibleInterface(topLeft->child("stack")->child("page1")); + QAccessibleInterface *acc_page2 = QAccessible::queryAccessibleInterface(topLeft->child("stack")->child("page2")); + QAccessibleInterface *acc_page3 = QAccessible::queryAccessibleInterface(topLeft->child("stack")->child("page3")); + QAccessibleInterface *acc_topRight = QAccessible::queryAccessibleInterface(topRight); + QAccessibleInterface *acc_pbOk = QAccessible::queryAccessibleInterface(topRight->child("pbOk")); + QAccessibleInterface *acc_slider = QAccessible::queryAccessibleInterface(topRight->child("slider")); + QAccessibleInterface *acc_spinBox = QAccessible::queryAccessibleInterface(topRight->child("spinBox")); + QAccessibleInterface *acc_sliderLcd = QAccessible::queryAccessibleInterface(topRight->child("sliderLcd")); + + QAccessibleInterface *acc_bottomLeft = QAccessible::queryAccessibleInterface(bottomLeft); + QAccessibleInterface *acc_label = QAccessible::queryAccessibleInterface(bottomLeft->child("label")); + QAccessibleInterface *acc_lineedit = QAccessible::queryAccessibleInterface(bottomLeft->child("lineedit")); + QAccessibleInterface *acc_label2 = QAccessible::queryAccessibleInterface(bottomLeft->child("label2")); + QAccessibleInterface *acc_radiogroup = QAccessible::queryAccessibleInterface(bottomLeft->child("radiogroup")); + QAccessibleInterface *acc_radioAM = QAccessible::queryAccessibleInterface(bottomLeft->child("radiogroup")->child("radioAM")); + QAccessibleInterface *acc_radioFM = QAccessible::queryAccessibleInterface(bottomLeft->child("radiogroup")->child("radioFM")); + QAccessibleInterface *acc_radioSW = QAccessible::queryAccessibleInterface(bottomLeft->child("radiogroup")->child("radioSW")); + QAccessibleInterface *acc_frequency = QAccessible::queryAccessibleInterface(bottomLeft->child("radiogroup")->child("frequency")); + + QAccessibleInterface *acc_bottomRight = QAccessible::queryAccessibleInterface(bottomRight); + + QVERIFY(acc_toplevel); + QVERIFY(acc_topLeft); + QVERIFY(acc_topRight); + QVERIFY(acc_bottomLeft); + QVERIFY(acc_bottomRight); + QVERIFY(acc_group1); + QVERIFY(acc_group2); + QVERIFY(acc_stack); + QVERIFY(acc_page1); + QVERIFY(acc_page2); + QVERIFY(acc_page3); + QVERIFY(acc_pbOk); + QVERIFY(acc_slider); + QVERIFY(acc_spinBox); + QVERIFY(acc_sliderLcd); + QVERIFY(acc_label); + QVERIFY(acc_lineedit); + QVERIFY(acc_radiogroup); + QVERIFY(acc_radioAM); + QVERIFY(acc_radioFM); + QVERIFY(acc_radioSW); + QVERIFY(acc_frequency); + + // hierachy relations + QCOMPARE(acc_toplevel->relationTo(0, acc_toplevel, 0) & QAccessible::HierarchyMask, + QAccessible::Self); + QCOMPARE(acc_toplevel->relationTo(1, acc_toplevel, 0) & QAccessible::HierarchyMask, + QAccessible::Child); + QCOMPARE(acc_toplevel->relationTo(0, acc_toplevel, 1) & QAccessible::HierarchyMask, + QAccessible::Ancestor); + + QCOMPARE(acc_toplevel->relationTo(0, acc_topLeft, 0) & QAccessible::HierarchyMask, + QAccessible::Ancestor); + QCOMPARE(acc_toplevel->relationTo(0, acc_topRight, 0) & QAccessible::HierarchyMask, + QAccessible::Ancestor); + QCOMPARE(acc_toplevel->relationTo(0, acc_bottomLeft, 0) & QAccessible::HierarchyMask, + QAccessible::Ancestor); + QCOMPARE(acc_toplevel->relationTo(0, acc_bottomRight, 0) & QAccessible::HierarchyMask, + QAccessible::Ancestor); + + QCOMPARE(acc_toplevel->relationTo(0, acc_group1, 0) & QAccessible::HierarchyMask, + QAccessible::Ancestor); + QCOMPARE(acc_toplevel->relationTo(0, acc_page1, 0) & QAccessible::HierarchyMask, + QAccessible::Ancestor); + QCOMPARE(acc_group1->relationTo(0, acc_toplevel, 0) & QAccessible::HierarchyMask, + QAccessible::Descendent); + QCOMPARE(acc_stack->relationTo(0, acc_toplevel, 0) & QAccessible::HierarchyMask, + QAccessible::Descendent); + QCOMPARE(acc_page1->relationTo(0, acc_stack, 0) & QAccessible::HierarchyMask, + QAccessible::Child); + QCOMPARE(acc_page1->relationTo(0, acc_toplevel, 0) & QAccessible::HierarchyMask, + QAccessible::Descendent); + + QCOMPARE(acc_topLeft->relationTo(0, acc_toplevel, 0) & QAccessible::HierarchyMask, + QAccessible::Child); + QCOMPARE(acc_topRight->relationTo(0, acc_toplevel, 0) & QAccessible::HierarchyMask, + QAccessible::Child); + QCOMPARE(acc_bottomLeft->relationTo(0, acc_toplevel, 0) & QAccessible::HierarchyMask, + QAccessible::Child); + QCOMPARE(acc_bottomRight->relationTo(0, acc_toplevel, 0) & QAccessible::HierarchyMask, + QAccessible::Child); + + QCOMPARE(acc_topLeft->relationTo(0, acc_topRight, 0) & QAccessible::HierarchyMask, + QAccessible::Sibling); + QCOMPARE(acc_topLeft->relationTo(0, acc_bottomLeft, 0) & QAccessible::HierarchyMask, + QAccessible::Sibling); + QCOMPARE(acc_topLeft->relationTo(0, acc_bottomRight, 0) & QAccessible::HierarchyMask, + QAccessible::Sibling); + + QCOMPARE(acc_pb1->relationTo(0, acc_pb2, 0), QAccessible::Unrelated); + + // geometrical relations - only valid for siblings + QCOMPARE(acc_topLeft->relationTo(0, acc_topRight, 0), QAccessible::Sibling | QAccessible::Left); + QCOMPARE(acc_topLeft->relationTo(0, acc_bottomLeft, 0), QAccessible::Sibling | QAccessible::Up); + QCOMPARE(acc_topLeft->relationTo(0, acc_bottomRight, 0), QAccessible::Sibling | QAccessible::Left | QAccessible::Up); + + QCOMPARE(acc_bottomRight->relationTo(0, acc_topLeft, 0), QAccessible::Sibling | QAccessible::Right | QAccessible::Down); + QCOMPARE(acc_bottomRight->relationTo(0, acc_topRight, 0), QAccessible::Sibling | QAccessible::Down); + QCOMPARE(acc_bottomRight->relationTo(0, acc_bottomLeft, 0), QAccessible::Sibling | QAccessible::Right); +#ifdef Q_WS_MAC + QEXPECT_FAIL("", "Task 155501", Continue); +#endif + QCOMPARE(acc_group1->relationTo(0, acc_group2, 0), QAccessible::Sibling | QAccessible::Up); +#ifdef Q_WS_MAC + QEXPECT_FAIL("", "Task 155501", Continue); +#endif + QCOMPARE(acc_group2->relationTo(0, acc_group1, 0), QAccessible::Sibling | QAccessible::Down); + + // Covers/Covered tested in navigateCovered + + // logical relations - focus + QCOMPARE(acc_radioAM->relationTo(0, acc_radioFM, 0) & QAccessible::FocusChild, + QAccessible::Unrelated); + QCOMPARE(acc_radioAM->relationTo(0, acc_radiogroup, 0) & QAccessible::FocusChild, + QAccessible::FocusChild); + QCOMPARE(acc_radioAM->relationTo(0, acc_bottomLeft, 0) & QAccessible::FocusChild, + QAccessible::FocusChild); + QCOMPARE(acc_radioAM->relationTo(0, acc_topLeft, 0) & QAccessible::FocusChild, + QAccessible::Unrelated); + QCOMPARE(acc_radioAM->relationTo(0, acc_toplevel, 0) & QAccessible::FocusChild, + QAccessible::FocusChild); + + // logical relations - labels + QCOMPARE(acc_label->relationTo(0, acc_lineedit, 0) & QAccessible::LogicalMask, + QAccessible::Label); + QCOMPARE(acc_lineedit->relationTo(0, acc_label, 0) & QAccessible::LogicalMask, + QAccessible::Labelled); + QCOMPARE(acc_label->relationTo(0, acc_radiogroup, 0) & QAccessible::LogicalMask, + QAccessible::Unrelated); + QCOMPARE(acc_lineedit->relationTo(0, acc_lineedit, 0) & QAccessible::LogicalMask, + QAccessible::Unrelated); + + QEXPECT_FAIL("", "Make me accessible", Continue); + QCOMPARE(acc_radiogroup->relationTo(0, acc_radioAM, 0) & QAccessible::LogicalMask, + QAccessible::Label | QAccessible::Controlled); + QEXPECT_FAIL("", "Make me accessible", Continue); + QCOMPARE(acc_radiogroup->relationTo(0, acc_radioFM, 0) & QAccessible::LogicalMask, + QAccessible::Label | QAccessible::Controlled); + QEXPECT_FAIL("", "Make me accessible", Continue); + QCOMPARE(acc_radiogroup->relationTo(0, acc_radioSW, 0) & QAccessible::LogicalMask, + QAccessible::Label | QAccessible::Controlled); + QCOMPARE(acc_radiogroup->relationTo(0, acc_frequency, 0) & QAccessible::LogicalMask, + QAccessible::Label); + QCOMPARE(acc_frequency->relationTo(0, acc_radiogroup, 0) & QAccessible::LogicalMask, + QAccessible::Labelled); + QCOMPARE(acc_radiogroup->relationTo(0, acc_lineedit, 0) & QAccessible::LogicalMask, + QAccessible::Unrelated); + + // logical relations - controller + QCOMPARE(acc_pbOk->relationTo(0, acc_toplevel, 0) & QAccessible::LogicalMask, + QAccessible::Controller); + QCOMPARE(acc_slider->relationTo(0, acc_sliderLcd, 0) & QAccessible::LogicalMask, + QAccessible::Controller); + QCOMPARE(acc_spinBox->relationTo(0, acc_slider, 0) & QAccessible::LogicalMask, + QAccessible::Controller); + QCOMPARE(acc_lineedit->relationTo(0, acc_label2, 0) & QAccessible::LogicalMask, + QAccessible::Controller); + + delete acc_toplevel; + delete acc_topLeft; + delete acc_group1; + delete acc_pb1; + delete acc_group2; + delete acc_stack; + delete acc_page1; + delete acc_page2; + delete acc_page3; + delete acc_topRight; + delete acc_pbOk; + delete acc_slider; + delete acc_spinBox; + delete acc_sliderLcd; + delete acc_bottomLeft; + delete acc_label; + delete acc_lineedit; + delete acc_label2; + delete acc_radiogroup; + delete acc_radioAM; + delete acc_radioFM; + delete acc_radioSW; + delete acc_frequency; + delete acc_bottomRight; + + delete toplevel; + + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +#endif // !QT3_SUPPORT +} + +void tst_QAccessibility::navigateGeometric() +{ +#ifdef QTEST_ACCESSIBILITY + { + static const int skip = 20; //speed the test up significantly + static const double step = Q_PI / 180; + QWidget *w = new QWidget(0); + w->setObjectName(QString("Josef")); + w->setFixedSize(400, 400); + + // center widget + QtTestAccessibleWidget *center = new QtTestAccessibleWidget(w, "Sol"); + center->move(200, 200); + + // arrange 360 widgets around it in a circle + QtTestAccessibleWidget *aw = 0; + int i; + for (i = 0; i < 360; i += skip) { + aw = new QtTestAccessibleWidget(w, QString::number(i).toLatin1()); + aw->move( int(200.0 + 100.0 * sin(step * (double)i)), int(200.0 + 100.0 * cos(step * (double)i)) ); + } + + aw = new QtTestAccessibleWidget(w, "Earth"); + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(center); + QAccessibleInterface *target = 0; + QVERIFY(iface != 0); + QVERIFY(iface->isValid()); + + w->show(); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(w); + QTest::qWait(100); +#endif + + + // let one widget rotate around center + for (i = 0; i < 360; i+=skip) { + aw->move( int(200.0 + 75.0 * sin(step * (double)i)), int(200.0 + 75.0 * cos(step * (double)i)) ); + + if (i < 45 || i > 315) { + QCOMPARE(iface->navigate(QAccessible::Down, 0, &target), 0); + } else if ( i < 135 ) { + QCOMPARE(iface->navigate(QAccessible::Right, 0, &target), 0); + } else if ( i < 225 ) { + QCOMPARE(iface->navigate(QAccessible::Up, 0, &target), 0); + } else { + QCOMPARE(iface->navigate(QAccessible::Left, 0, &target), 0); + } + + QVERIFY(target); + QVERIFY(target->isValid()); + QVERIFY(target->object()); + QCOMPARE(target->object()->objectName(), aw->objectName()); + delete target; target = 0; + } + + // test invisible widget + target = QAccessible::queryAccessibleInterface(aw); + QVERIFY(!(target->state(0) & QAccessible::Invisible)); + aw->hide(); + QVERIFY(target->state(0) & QAccessible::Invisible); + delete target; target = 0; + + aw->move(center->x() + 10, center->y()); + QCOMPARE(iface->navigate(QAccessible::Right, 0, &target), 0); + QVERIFY(target); + QVERIFY(target->isValid()); + QVERIFY(target->object()); + QVERIFY(QString(target->object()->objectName()) != "Earth"); + delete target; target = 0; + + aw->move(center->x() - 10, center->y()); + QCOMPARE(iface->navigate(QAccessible::Left, 0, &target), 0); + QVERIFY(target); + QVERIFY(target->isValid()); + QVERIFY(target->object()); + QVERIFY(QString(target->object()->objectName()) != "Earth"); + delete target; target = 0; + + aw->move(center->x(), center->y() + 10); + QCOMPARE(iface->navigate(QAccessible::Down, 0, &target), 0); + QVERIFY(target); + QVERIFY(target->isValid()); + QVERIFY(target->object()); + QVERIFY(QString(target->object()->objectName()) != "Earth"); + delete target; target = 0; + + aw->move(center->x(), center->y() - 10); + QCOMPARE(iface->navigate(QAccessible::Up, 0, &target), 0); + QVERIFY(target); + QVERIFY(target->isValid()); + QVERIFY(target->object()); + QVERIFY(QString(target->object()->objectName()) != "Earth"); + delete target; target = 0; + + delete iface; + delete w; + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::navigateSlider() +{ +#ifdef QTEST_ACCESSIBILITY + { + QSlider *slider = new QSlider(0); + slider->setObjectName(QString("Slidy")); + slider->show(); + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(slider); + QAccessibleInterface *target = 0; + QVERIFY(iface != 0); + QVERIFY(iface->isValid()); + QCOMPARE(iface->childCount(), 3); + QCOMPARE(iface->navigate(QAccessible::Child, 1, &target), 1); + QVERIFY(target == 0); + QCOMPARE(iface->navigate(QAccessible::Child, 2, &target), 2); + QVERIFY(target == 0); + QCOMPARE(iface->navigate(QAccessible::Child, 3, &target), 3); + QVERIFY(target == 0); + QCOMPARE(iface->navigate(QAccessible::Child, 4, &target), -1); + QVERIFY(target == 0); + QCOMPARE(iface->navigate(QAccessible::Child, 0, &target), -1); + QVERIFY(target == 0); + QCOMPARE(iface->navigate(QAccessible::Child, -42, &target), -1); + QVERIFY(target == 0); + + delete iface; + delete slider; + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::navigateCovered() +{ +#ifdef QTEST_ACCESSIBILITY + { + QWidget *w = new QWidget(0); + w->setObjectName(QString("Harry")); + QWidget *w1 = new QWidget(w); + w1->setObjectName(QString("1")); + QWidget *w2 = new QWidget(w); + w2->setObjectName(QString("2")); + w->show(); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(w); + QTest::qWait(100); +#endif + + w->setFixedSize(6, 6); + w1->setFixedSize(5, 5); + w2->setFixedSize(5, 5); + w2->move(0, 0); + w1->raise(); + + QAccessibleInterface *iface1 = QAccessible::queryAccessibleInterface(w1); + QVERIFY(iface1 != 0); + QVERIFY(iface1->isValid()); + QAccessibleInterface *iface2 = QAccessible::queryAccessibleInterface(w2); + QVERIFY(iface2 != 0); + QVERIFY(iface2->isValid()); + QAccessibleInterface *iface3 = 0; + + QCOMPARE(iface1->navigate(QAccessible::Covers, -42, &iface3), -1); + QVERIFY(iface3 == 0); + QCOMPARE(iface1->navigate(QAccessible::Covers, 0, &iface3), -1); + QVERIFY(iface3 == 0); + QCOMPARE(iface1->navigate(QAccessible::Covers, 2, &iface3), -1); + QVERIFY(iface3 == 0); + + for (int loop = 0; loop < 2; ++loop) { + for (int x = 0; x < w->width(); ++x) { + for (int y = 0; y < w->height(); ++y) { + w1->move(x, y); + if (w1->geometry().intersects(w2->geometry())) { + QVERIFY(iface1->relationTo(0, iface2, 0) & QAccessible::Covers); + QVERIFY(iface2->relationTo(0, iface1, 0) & QAccessible::Covered); + QCOMPARE(iface1->navigate(QAccessible::Covered, 1, &iface3), 0); + QVERIFY(iface3 != 0); + QVERIFY(iface3->isValid()); + QCOMPARE(iface3->object(), iface2->object()); + delete iface3; iface3 = 0; + QCOMPARE(iface2->navigate(QAccessible::Covers, 1, &iface3), 0); + QVERIFY(iface3 != 0); + QVERIFY(iface3->isValid()); + QCOMPARE(iface3->object(), iface1->object()); + delete iface3; iface3 = 0; + } else { + QVERIFY(!(iface1->relationTo(0, iface2, 0) & QAccessible::Covers)); + QVERIFY(!(iface2->relationTo(0, iface1, 0) & QAccessible::Covered)); + QCOMPARE(iface1->navigate(QAccessible::Covered, 1, &iface3), -1); + QVERIFY(iface3 == 0); + QCOMPARE(iface1->navigate(QAccessible::Covers, 1, &iface3), -1); + QVERIFY(iface3 == 0); + QCOMPARE(iface2->navigate(QAccessible::Covered, 1, &iface3), -1); + QVERIFY(iface3 == 0); + QCOMPARE(iface2->navigate(QAccessible::Covers, 1, &iface3), -1); + QVERIFY(iface3 == 0); + } + } + } + if (!loop) { + // switch children for second loop + w2->raise(); + QAccessibleInterface *temp = iface1; + iface1 = iface2; + iface2 = temp; + } + } + delete iface1; iface1 = 0; + delete iface2; iface2 = 0; + iface1 = QAccessible::queryAccessibleInterface(w1); + QVERIFY(iface1 != 0); + QVERIFY(iface1->isValid()); + iface2 = QAccessible::queryAccessibleInterface(w2); + QVERIFY(iface2 != 0); + QVERIFY(iface2->isValid()); + + w1->move(0,0); + w2->move(0,0); + w1->raise(); + QVERIFY(iface1->relationTo(0, iface2, 0) & QAccessible::Covers); + QVERIFY(iface2->relationTo(0, iface1, 0) & QAccessible::Covered); + QVERIFY(!(iface1->state(0) & QAccessible::Invisible)); + w1->hide(); + QVERIFY(iface1->state(0) & QAccessible::Invisible); + QVERIFY(!(iface1->relationTo(0, iface2, 0) & QAccessible::Covers)); + QVERIFY(!(iface2->relationTo(0, iface1, 0) & QAccessible::Covered)); + QCOMPARE(iface2->navigate(QAccessible::Covered, 1, &iface3), -1); + QVERIFY(iface3 == 0); + QCOMPARE(iface1->navigate(QAccessible::Covers, 1, &iface3), -1); + QVERIFY(iface3 == 0); + + delete iface1; iface1 = 0; + delete iface2; iface2 = 0; + delete w; + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::navigateHierarchy() +{ +#ifdef QTEST_ACCESSIBILITY + { + QWidget *w = new QWidget(0); + w->setObjectName(QString("Hans")); + w->show(); + QWidget *w1 = new QWidget(w); + w1->setObjectName(QString("1")); + w1->show(); + QWidget *w2 = new QWidget(w); + w2->setObjectName(QString("2")); + w2->show(); + QWidget *w3 = new QWidget(w); + w3->setObjectName(QString("3")); + w3->show(); + QWidget *w31 = new QWidget(w3); + w31->setObjectName(QString("31")); + w31->show(); + + QAccessibleInterface *target = 0; + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(w); + QVERIFY(iface != 0); + QVERIFY(iface->isValid()); + + QCOMPARE(iface->navigate(QAccessible::Sibling, -42, &target), -1); + QVERIFY(target == 0); + QCOMPARE(iface->navigate(QAccessible::Sibling, 42, &target), -1); + QVERIFY(target == 0); + QCOMPARE(iface->navigate(QAccessible::Child, 15, &target), -1); + QVERIFY(target == 0); + QCOMPARE(iface->navigate(QAccessible::Child, 0, &target), -1); + QVERIFY(target == 0); + QCOMPARE(iface->navigate(QAccessible::Child, 1, &target), 0); + QVERIFY(target != 0); + QVERIFY(target->isValid()); + QCOMPARE(target->object(), (QObject*)w1); + delete iface; iface = 0; + + QCOMPARE(target->navigate(QAccessible::Sibling, 0, &iface), -1); + QVERIFY(iface == 0); + QCOMPARE(target->navigate(QAccessible::Sibling, 42, &iface), -1); + QVERIFY(iface == 0); + QCOMPARE(target->navigate(QAccessible::Sibling, -42, &iface), -1); + QVERIFY(iface == 0); + QCOMPARE(target->navigate(QAccessible::Sibling, 2, &iface), 0); + QVERIFY(iface != 0); + QVERIFY(iface->isValid()); + QCOMPARE(iface->object(), (QObject*)w2); + delete target; target = 0; + QCOMPARE(iface->navigate(QAccessible::Sibling, 3, &target), 0); + QVERIFY(target != 0); + QVERIFY(target->isValid()); + QCOMPARE(target->object(), (QObject*)w3); + delete iface; iface = 0; + + QCOMPARE(target->navigate(QAccessible::Child, 1, &iface), 0); + QVERIFY(iface != 0); + QVERIFY(iface->isValid()); + QCOMPARE(iface->object(), (QObject*)w31); + delete target; target = 0; + + QCOMPARE(iface->navigate(QAccessible::Sibling, -1, &target), -1); + QVERIFY(target == 0); + QCOMPARE(iface->navigate(QAccessible::Sibling, 0, &target), -1); + QVERIFY(target == 0); + QCOMPARE(iface->navigate(QAccessible::Sibling, 1, &target), 0); + QVERIFY(target != 0); + QVERIFY(target->isValid()); + QCOMPARE(target->object(), (QObject*)w31); + delete iface; iface = 0; + + QCOMPARE(target->navigate(QAccessible::Ancestor, 42, &iface), -1); + QVERIFY(iface == 0); + QCOMPARE(target->navigate(QAccessible::Ancestor, -1, &iface), -1); + QVERIFY(iface == 0); + QCOMPARE(target->navigate(QAccessible::Ancestor, 0, &iface), -1); + QVERIFY(iface == 0); + QCOMPARE(target->navigate(QAccessible::Ancestor, 1, &iface), 0); + QVERIFY(iface != 0); + QVERIFY(iface->isValid()); + QCOMPARE(iface->object(), (QObject*)w3); + delete iface; iface = 0; + QCOMPARE(target->navigate(QAccessible::Ancestor, 2, &iface), 0); + QVERIFY(iface != 0); + QVERIFY(iface->isValid()); + QCOMPARE(iface->object(), (QObject*)w); + delete iface; iface = 0; + QCOMPARE(target->navigate(QAccessible::Ancestor, 3, &iface), 0); + QVERIFY(iface != 0); + QVERIFY(iface->isValid()); + QCOMPARE(iface->object(), (QObject*)qApp); + delete iface; iface = 0; + delete target; target = 0; + + delete w; + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +#define QSETCOMPARE(thetypename, elements, otherelements) \ + QCOMPARE((QSet<thetypename>() << elements), (QSet<thetypename>() << otherelements)) + +void tst_QAccessibility::navigateControllers() +{ +#if !defined(QT3_SUPPORT) + QSKIP("This test needs Qt3Support", SkipAll); +#else +#ifdef QTEST_ACCESSIBILITY + { + Q3VBox vbox; + QSlider slider(&vbox); + QSpinBox spinBox(&vbox); + QLCDNumber lcd1(&vbox); + QLCDNumber lcd2(&vbox); + QLabel label(&vbox); + vbox.show(); + + slider.setObjectName("slider"); + spinBox.setObjectName("spinBox"); + lcd1.setObjectName("lcd1"); + lcd2.setObjectName("lcd2"); + label.setObjectName("label"); + + QTestAccessibility::clearEvents(); + + connect(&slider, SIGNAL(valueChanged(int)), &lcd1, SLOT(display(int))); + connect(&slider, SIGNAL(valueChanged(int)), &lcd2, SLOT(display(int))); + connect(&spinBox, SIGNAL(valueChanged(int)), &lcd2, SLOT(display(int))); + connect(&spinBox, SIGNAL(valueChanged(int)), &lcd1, SLOT(display(int))); + connect(&spinBox, SIGNAL(valueChanged(const QString&)), &label, SLOT(setText(const QString&))); + + QAccessibleInterface *acc_slider = QAccessible::queryAccessibleInterface(&slider); + QAccessibleInterface *acc_spinBox = QAccessible::queryAccessibleInterface(&spinBox); + QAccessibleInterface *acc_lcd1 = QAccessible::queryAccessibleInterface(&lcd1); + QAccessibleInterface *acc_lcd2 = QAccessible::queryAccessibleInterface(&lcd2); + QAccessibleInterface *acc_label = QAccessible::queryAccessibleInterface(&label); + + QVERIFY(acc_slider->relationTo(0, acc_lcd1, 0) & QAccessible::Controller); + QVERIFY(acc_slider->relationTo(0, acc_lcd2, 0) & QAccessible::Controller); + QVERIFY(acc_spinBox->relationTo(0, acc_lcd1, 0) & QAccessible::Controller); + QVERIFY(acc_spinBox->relationTo(0, acc_lcd2, 0) & QAccessible::Controller); + QVERIFY(acc_spinBox->relationTo(0, acc_label, 0) & QAccessible::Controller); + + QAccessibleInterface *acc_target1, *acc_target2, *acc_target3; + // from controller + QCOMPARE(acc_slider->navigate(QAccessible::Controlled, 0, &acc_target1), -1); + QVERIFY(!acc_target1); + QCOMPARE(acc_slider->navigate(QAccessible::Controlled, 1, &acc_target1), 0); + QCOMPARE(acc_slider->navigate(QAccessible::Controlled, 2, &acc_target2), 0); + QSETCOMPARE(QObject*, acc_lcd1->object() << acc_lcd2->object(), + acc_target1->object() << acc_target2->object()); + delete acc_target1; + delete acc_target2; + + QCOMPARE(acc_slider->navigate(QAccessible::Controlled, 3, &acc_target1), -1); + QVERIFY(!acc_target1); + + QCOMPARE(acc_spinBox->navigate(QAccessible::Controlled, 0, &acc_target1), -1); + QVERIFY(!acc_target1); + QCOMPARE(acc_spinBox->navigate(QAccessible::Controlled, 1, &acc_target1), 0); + QCOMPARE(acc_spinBox->navigate(QAccessible::Controlled, 2, &acc_target2), 0); + QCOMPARE(acc_spinBox->navigate(QAccessible::Controlled, 3, &acc_target3), 0); + QSETCOMPARE(QObject*, acc_lcd1->object() << acc_lcd2->object() << acc_label->object(), + acc_target1->object() << acc_target2->object() << acc_target3->object()); + delete acc_target1; + delete acc_target2; + delete acc_target3; + + QCOMPARE(acc_spinBox->navigate(QAccessible::Controlled, 4, &acc_target1), -1); + QVERIFY(!acc_target1); + + // to controller + QCOMPARE(acc_lcd1->navigate(QAccessible::Controller, 0, &acc_target1), -1); + QVERIFY(!acc_target1); + QCOMPARE(acc_lcd1->navigate(QAccessible::Controller, 1, &acc_target1), 0); + QCOMPARE(acc_lcd1->navigate(QAccessible::Controller, 2, &acc_target2), 0); + QSETCOMPARE(QObject*, acc_slider->object() << acc_spinBox->object(), + acc_target1->object() << acc_target2->object()); + delete acc_target1; + delete acc_target2; + QCOMPARE(acc_lcd1->navigate(QAccessible::Controller, 3, &acc_target1), -1); + QVERIFY(!acc_target1); + + delete acc_label; + delete acc_lcd2; + delete acc_lcd1; + delete acc_spinBox; + delete acc_slider; + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +#endif // !QT3_SUPPORT +} + +void tst_QAccessibility::navigateLabels() +{ +#if !defined(QT3_SUPPORT) + QSKIP("This test needs Qt3Support", SkipAll); +#else +#ifdef QTEST_ACCESSIBILITY + { + Q3VBox vbox; + Q3HBox hbox(&vbox); + + QLabel label(&hbox); + label.setText("This is a lineedit:"); + QLineEdit lineedit(&hbox); + label.setBuddy(&lineedit); + + Q3VButtonGroup groupbox(&vbox); + groupbox.setTitle("Be my children!"); + QRadioButton radio(&groupbox); + QLabel label2(&groupbox); + label2.setText("Another lineedit:"); + QLineEdit lineedit2(&groupbox); + label2.setBuddy(&lineedit2); + Q3GroupBox groupbox2(&groupbox); + groupbox2.setTitle("Some grand-children"); + QLineEdit grandchild(&groupbox2); + + Q3GroupBox border(&vbox); + QLineEdit lineedit3(&border); + vbox.show(); + QTestAccessibility::clearEvents(); + + QAccessibleInterface *acc_label = QAccessible::queryAccessibleInterface(&label); + QAccessibleInterface *acc_lineedit = QAccessible::queryAccessibleInterface(&lineedit); + QAccessibleInterface *acc_groupbox = QAccessible::queryAccessibleInterface(&groupbox); + QAccessibleInterface *acc_radio = QAccessible::queryAccessibleInterface(&radio); + QAccessibleInterface *acc_label2 = QAccessible::queryAccessibleInterface(&label2); + QAccessibleInterface *acc_lineedit2 = QAccessible::queryAccessibleInterface(&lineedit2); + QAccessibleInterface *acc_groupbox2 = QAccessible::queryAccessibleInterface(&groupbox2); + QAccessibleInterface *acc_grandchild = QAccessible::queryAccessibleInterface(&grandchild); + QAccessibleInterface *acc_border = QAccessible::queryAccessibleInterface(&border); + QAccessibleInterface *acc_lineedit3 = QAccessible::queryAccessibleInterface(&lineedit3); + + QVERIFY(acc_label->relationTo(0, acc_lineedit,0) & QAccessible::Label); + QVERIFY(acc_groupbox->relationTo(0, acc_radio,0) & QAccessible::Label); + QVERIFY(acc_groupbox->relationTo(0, acc_lineedit2,0) & QAccessible::Label); + QVERIFY(acc_groupbox->relationTo(0, acc_groupbox2,0) & QAccessible::Label); + QVERIFY(acc_groupbox2->relationTo(0, acc_grandchild,0) & QAccessible::Label); + QVERIFY(!(acc_border->relationTo(0, acc_lineedit3,0) & QAccessible::Label)); + + QAccessibleInterface *acc_target; + // from label + QCOMPARE(acc_label->navigate(QAccessible::Labelled, 0, &acc_target), -1); + QVERIFY(!acc_target); + QCOMPARE(acc_label->navigate(QAccessible::Labelled, 1, &acc_target), 0); + QVERIFY(acc_target->object() == acc_lineedit->object()); + delete acc_target; acc_target = 0; + QCOMPARE(acc_label->navigate(QAccessible::Labelled, 2, &acc_target), -1); + QVERIFY(!acc_target); + + QCOMPARE(acc_groupbox->navigate(QAccessible::Labelled, 0, &acc_target), -1); + QVERIFY(!acc_target); + QCOMPARE(acc_groupbox->navigate(QAccessible::Labelled, 1, &acc_target), 0); + QVERIFY(acc_target->object() == acc_radio->object()); + delete acc_target; acc_target = 0; + QCOMPARE(acc_groupbox->navigate(QAccessible::Labelled, 2, &acc_target), 0); + QVERIFY(acc_target->object() == acc_label2->object()); + delete acc_target; acc_target = 0; + QCOMPARE(acc_groupbox->navigate(QAccessible::Labelled, 3, &acc_target), 0); + QVERIFY(acc_target->object() == acc_lineedit2->object()); + delete acc_target; acc_target = 0; + QCOMPARE(acc_groupbox->navigate(QAccessible::Labelled, 4, &acc_target), 0); + QVERIFY(acc_target->object() == acc_groupbox2->object()); + delete acc_target; acc_target = 0; + QCOMPARE(acc_groupbox->navigate(QAccessible::Labelled, 5, &acc_target), -1); + QVERIFY(!acc_target); + + QCOMPARE(acc_border->navigate(QAccessible::Labelled, 0, &acc_target), -1); + QVERIFY(!acc_target); + QCOMPARE(acc_border->navigate(QAccessible::Labelled, 1, &acc_target), -1); + QVERIFY(!acc_target); + + // to label + QCOMPARE(acc_lineedit->navigate(QAccessible::Label, 0, &acc_target), -1); + QVERIFY(!acc_target); + QCOMPARE(acc_lineedit->navigate(QAccessible::Label, 1, &acc_target), 0); + QVERIFY(acc_target->object() == acc_label->object()); + delete acc_target; acc_target = 0; + QCOMPARE(acc_lineedit->navigate(QAccessible::Label, 2, &acc_target), -1); + QVERIFY(!acc_target); + + QCOMPARE(acc_radio->navigate(QAccessible::Label, 0, &acc_target), -1); + QVERIFY(!acc_target); + QCOMPARE(acc_radio->navigate(QAccessible::Label, 1, &acc_target), 0); + QVERIFY(acc_target->object() == acc_groupbox->object()); + delete acc_target; acc_target = 0; + QCOMPARE(acc_radio->navigate(QAccessible::Label, 2, &acc_target), -1); + QVERIFY(!acc_target); + + QCOMPARE(acc_lineedit2->navigate(QAccessible::Label, 1, &acc_target), 0); + QVERIFY(acc_target->object() == acc_label2->object()); + delete acc_target; acc_target = 0; + QCOMPARE(acc_lineedit2->navigate(QAccessible::Label, 2, &acc_target), 0); + QVERIFY(acc_target->object() == acc_groupbox->object()); + delete acc_target; acc_target = 0; + QCOMPARE(acc_lineedit2->navigate(QAccessible::Label, 3, &acc_target), -1); + QVERIFY(!acc_target); + + QCOMPARE(acc_grandchild->navigate(QAccessible::Label, 1, &acc_target), 0); + QVERIFY(acc_target->object() == acc_groupbox2->object()); + delete acc_target; acc_target = 0; + QCOMPARE(acc_grandchild->navigate(QAccessible::Label, 2, &acc_target), -1); + QVERIFY(!acc_target); + QCOMPARE(acc_grandchild->navigate(QAccessible::Label, 3, &acc_target), -1); + QVERIFY(!acc_target); + + delete acc_label; + delete acc_lineedit; + delete acc_groupbox; + delete acc_radio; + delete acc_label2; + delete acc_lineedit2; + delete acc_groupbox2; + delete acc_grandchild; + delete acc_border; + delete acc_lineedit3; + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +#endif // !QT3_SUPPORT +} + +static QWidget *createWidgets() +{ + QWidget *w = new QWidget(); + + QHBoxLayout *box = new QHBoxLayout(w); + + int i = 0; + box->addWidget(new QComboBox(w)); + box->addWidget(new QPushButton(QString::fromAscii("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 QListView(w)); + box->addWidget(new QListWidget(w)); + box->addWidget(new QTableView(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 QFrame(w)); + box->addWidget(new QLineEdit(QString::fromAscii("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 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 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)); + + /* Not in the list + * QAbstractItemView, QGraphicsView, QScrollArea, + * QToolButton, QDockWidget, QFocusFrame, QMainWindow, QMenu, QMenuBar, QSizeGrip, QSplashScreen, QSplitterHandle, + * QStatusBar, QSvgWidget, QTabBar, QToolBar, QWorkspace, QSplitter + */ + return w; +} + +void tst_QAccessibility::accessibleName() +{ +#ifdef QTEST_ACCESSIBILITY + QWidget *toplevel = createWidgets(); + toplevel->show(); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(toplevel); + QTest::qWait(100); +#endif + QLayout *lout = toplevel->layout(); + for (int i = 0; i < lout->count(); i++) { + QLayoutItem *item = lout->itemAt(i); + QWidget *child = item->widget(); + + QString name = tr("Widget Name %1").arg(i); + child->setAccessibleName(name); + QAccessibleInterface *acc = QAccessible::queryAccessibleInterface(child); + QCOMPARE(acc->text(QAccessible::Name, 0), name); + + QString desc = tr("Widget Description %1").arg(i); + child->setAccessibleDescription(desc); + QCOMPARE(acc->text(QAccessible::Description, 0), desc); + + } + + delete toplevel; + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::text() +{ +#if !defined(QT3_SUPPORT) + QSKIP("This test needs Qt3Support", SkipAll); +#else +#ifdef QTEST_ACCESSIBILITY + QWidget *toplevel = createGUI(); + toplevel->show(); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(toplevel); + QTest::qWait(100); +#endif + QObject *topLeft = toplevel->child("topLeft"); + QObject *topRight = toplevel->child("topRight"); + QObject *bottomLeft = toplevel->child("bottomLeft"); + + QAccessibleInterface *acc_pb1 = QAccessible::queryAccessibleInterface(topLeft->child("pb1")); + + QAccessibleInterface *acc_pbOk = QAccessible::queryAccessibleInterface(topRight->child("pbOk")); + QAccessibleInterface *acc_slider = QAccessible::queryAccessibleInterface(topRight->child("slider")); + QAccessibleInterface *acc_spinBox = QAccessible::queryAccessibleInterface(topRight->child("spinBox")); + QAccessibleInterface *acc_sliderLcd = QAccessible::queryAccessibleInterface(topRight->child("sliderLcd")); + + QAccessibleInterface *acc_label = QAccessible::queryAccessibleInterface(bottomLeft->child("label")); + QAccessibleInterface *acc_lineedit = QAccessible::queryAccessibleInterface(bottomLeft->child("lineedit")); + QAccessibleInterface *acc_radiogroup = QAccessible::queryAccessibleInterface(bottomLeft->child("radiogroup")); + QVERIFY(bottomLeft->child("radiogroup")); + QAccessibleInterface *acc_radioAM = QAccessible::queryAccessibleInterface(bottomLeft->child("radiogroup")->child("radioAM")); + QAccessibleInterface *acc_frequency = QAccessible::queryAccessibleInterface(bottomLeft->child("radiogroup")->child("frequency")); + + QVERIFY(acc_pb1); + + QVERIFY(acc_pbOk); + QVERIFY(acc_slider); + QVERIFY(acc_spinBox); + QVERIFY(acc_sliderLcd); + + QVERIFY(acc_label); + QVERIFY(acc_lineedit); + QVERIFY(acc_radiogroup); + QVERIFY(acc_radioAM); + QVERIFY(acc_frequency); + + QVERIFY(acc_label->relationTo(0, acc_lineedit, 0) & QAccessible::Label); + QVERIFY(acc_radiogroup->relationTo(0, acc_frequency, 0) & QAccessible::Label); + QVERIFY(acc_slider->relationTo(0, acc_sliderLcd, 0) & QAccessible::Controller); + QVERIFY(acc_spinBox->relationTo(0, acc_slider, 0) & QAccessible::Controller); + + // Name + QCOMPARE(acc_lineedit->text(QAccessible::Name, 0), acc_label->text(QAccessible::Name,0)); + QCOMPARE(acc_frequency->text(QAccessible::Name, 0), acc_radiogroup->text(QAccessible::Name,0)); + QCOMPARE(acc_sliderLcd->text(QAccessible::Name, 0), acc_slider->text(QAccessible::Value,0)); + QCOMPARE(acc_pbOk->text(QAccessible::Name, 0), QString("Ok")); + QCOMPARE(acc_radioAM->text(QAccessible::Name, 0), QString("AM")); + QCOMPARE(acc_pb1->text(QAccessible::Name, 0), QString("Button1")); + + // Description + QString desc = qobject_cast<QWidget*>(acc_label->object())->toolTip(); + QVERIFY(!desc.isEmpty()); + QCOMPARE(acc_label->text(QAccessible::Description, 0), desc); + desc = qobject_cast<QWidget*>(acc_lineedit->object())->toolTip(); + QVERIFY(!desc.isEmpty()); + QCOMPARE(acc_lineedit->text(QAccessible::Description, 0), desc); + + // Help + QString help = qobject_cast<QWidget*>(acc_label->object())->whatsThis(); + QVERIFY(!help.isEmpty()); + QCOMPARE(acc_label->text(QAccessible::Help, 0), help); + help = qobject_cast<QWidget*>(acc_frequency->object())->whatsThis(); + QVERIFY(!help.isEmpty()); + QCOMPARE(acc_frequency->text(QAccessible::Help, 0), help); + + // Value + QString value = acc_frequency->object()->property("text").toString(); + QVERIFY(!value.isEmpty()); + QCOMPARE(acc_frequency->text(QAccessible::Value, 0), value); + value = acc_slider->object()->property("value").toString(); + QVERIFY(!value.isEmpty()); + QCOMPARE(acc_slider->text(QAccessible::Value, 0), value); + QCOMPARE(acc_spinBox->text(QAccessible::Value, 0), value); + + // Accelerator + QCOMPARE(acc_pbOk->text(QAccessible::Accelerator, 0), Q3Accel::keyToString(Qt::Key_Enter)); + QCOMPARE(acc_pb1->text(QAccessible::Accelerator, 0), Q3Accel::keyToString(Qt::ALT + Qt::Key_1)); + QCOMPARE(acc_lineedit->text(QAccessible::Accelerator, 0), Q3Accel::keyToString(Qt::ALT) + "L"); + QCOMPARE(acc_frequency->text(QAccessible::Accelerator, 0), Q3Accel::keyToString(Qt::ALT) + "C"); + + delete acc_pb1; + delete acc_pbOk; + delete acc_slider; + delete acc_spinBox; + delete acc_sliderLcd; + + delete acc_label; + delete acc_lineedit; + delete acc_radiogroup; + delete acc_radioAM; + delete acc_frequency; + + delete toplevel; + QTestAccessibility::clearEvents(); + +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +#endif // !QT3_SUPPORT +} + +void tst_QAccessibility::setText() +{ +#if !defined(QT3_SUPPORT) + QSKIP("This test needs Qt3Support", SkipAll); +#else +#ifdef QTEST_ACCESSIBILITY + QWidget *toplevel = createGUI(); + toplevel->show(); + QObject *bottomLeft = toplevel->findChild<QObject *>("bottomLeft"); + + QAccessibleInterface *acc_lineedit = QAccessible::queryAccessibleInterface(bottomLeft->findChild<QLineEdit *>("lineedit")); + // Value, read-write + QString txt = acc_lineedit->text(QAccessible::Value, 0); + QVERIFY(txt.isEmpty()); + txt = QLatin1String("Writable"); + acc_lineedit->setText(QAccessible::Value, 0, txt); + QCOMPARE(acc_lineedit->text(QAccessible::Value, 0), txt); + + // Description, read-only + txt = acc_lineedit->text(QAccessible::Description, 0); + QVERIFY(!txt.isEmpty()); + acc_lineedit->setText(QAccessible::Description, 0, QLatin1String("")); + QCOMPARE(acc_lineedit->text(QAccessible::Description, 0), txt); + + QVERIFY(acc_lineedit); + + delete acc_lineedit; + delete toplevel; + QTestAccessibility::clearEvents(); + +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +#endif //QT3_SUPPORT +} + +void tst_QAccessibility::hideShowTest() +{ +#ifdef QTEST_ACCESSIBILITY + QWidget * const window = new QWidget(); + QWidget * const child = new QWidget(window); + + QVERIFY(state(window) & QAccessible::Invisible); + QVERIFY(state(child) & QAccessible::Invisible); + + QTestAccessibility::clearEvents(); + + // show() and veryfy that both window and child are not invisible and get ObjectShow events. + window->show(); + QVERIFY(state(window) ^ QAccessible::Invisible); + QVERIFY(state(child) ^ QAccessible::Invisible); + QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(window, 0, QAccessible::ObjectShow))); + QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(child, 0, QAccessible::ObjectShow))); + QTestAccessibility::clearEvents(); + + // hide() and veryfy that both window and child are invisible and get ObjectHide events. + window->hide(); + QVERIFY(state(window) & QAccessible::Invisible); + QVERIFY(state(child) & QAccessible::Invisible); + QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(window, 0, QAccessible::ObjectHide))); + QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(child, 0, QAccessible::ObjectHide))); + QTestAccessibility::clearEvents(); + + delete window; + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::userActionCount() +{ +#ifdef QTEST_ACCESSIBILITY + QWidget widget; + + QAccessibleInterface *test = QAccessible::queryAccessibleInterface(&widget); + QVERIFY(test); + QVERIFY(test->isValid()); + QCOMPARE(test->userActionCount(0), 0); + QCOMPARE(test->userActionCount(1), 0); + QCOMPARE(test->userActionCount(-1), 0); + delete test; test = 0; + + QFrame frame; + + test = QAccessible::queryAccessibleInterface(&frame); + QVERIFY(test); + QVERIFY(test->isValid()); + QCOMPARE(test->userActionCount(0), 0); + QCOMPARE(test->userActionCount(1), 0); + QCOMPARE(test->userActionCount(-1), 0); + delete test; test = 0; + + QLineEdit lineEdit; + + test = QAccessible::queryAccessibleInterface(&lineEdit); + QVERIFY(test); + QVERIFY(test->isValid()); + QCOMPARE(test->userActionCount(0), 0); + QCOMPARE(test->userActionCount(1), 0); + QCOMPARE(test->userActionCount(-1), 0); + delete test; test = 0; +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::actionText() +{ +#ifdef QTEST_ACCESSIBILITY + QWidget widget; + widget.show(); + + QAccessibleInterface *test = QAccessible::queryAccessibleInterface(&widget); + QVERIFY(test); + QVERIFY(test->isValid()); + + QCOMPARE(test->actionText(1, QAccessible::Name, 0), QString()); + QCOMPARE(test->actionText(0, QAccessible::Name, 1), QString()); + QCOMPARE(test->actionText(1, QAccessible::Name, 1), QString()); + QCOMPARE(test->actionText(QAccessible::SetFocus, QAccessible::Name, -1), QString()); + + QCOMPARE(test->actionText(QAccessible::DefaultAction, QAccessible::Name, 0), QString("SetFocus")); + QCOMPARE(test->actionText(QAccessible::SetFocus, QAccessible::Name, 0), QString("SetFocus")); + + delete test; test = 0; + +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::doAction() +{ +#ifdef QTEST_ACCESSIBILITY + QSKIP("TODO: Implement me", SkipAll); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::buttonTest() +{ +//#ifdef QTEST_ACCESSIBILITY +#if 0 + QAccessibleInterface *test = 0; + Q3VBox vbox; + + // Standard push button + QPushButton pushButton("Ok", &vbox); + + // toggle push button + QPushButton togglepush("Toggle", &vbox); + togglepush.setToggleButton(TRUE); + + // push button with a menu + QPushButton menuButton("Menu", &vbox); + Q3PopupMenu buttonMenu(&menuButton); + buttonMenu.insertItem("Some item"); + menuButton.setPopup(&buttonMenu); + + // standard checkbox + QCheckBox checkBox("Check me!", &vbox); + + // tristate checkbox + QCheckBox tristate("Tristate!", &vbox); + tristate.setTristate(TRUE); + + // radiobutton + QRadioButton radio("Radio me!", &vbox); + + // standard toolbutton + QToolButton toolbutton(&vbox); + toolbutton.setText("Tool"); + toolbutton.setMinimumSize(20,20); + + // standard toolbutton + QToolButton toggletool(&vbox); + toggletool.setToggleButton(TRUE); + toggletool.setText("Toggle"); + toggletool.setMinimumSize(20,20); + + // menu toolbutton + QToolButton menuToolButton(&vbox); + menuToolButton.setText("Menu Tool"); + Q3PopupMenu toolMenu(&menuToolButton); + toolMenu.insertItem("Some item"); + menuToolButton.setPopup(&toolMenu); + menuToolButton.setMinimumSize(20,20); + + // splitted menu toolbutton + QToolButton splitToolButton(&vbox); + splitToolButton.setTextLabel("Split Tool"); + Q3PopupMenu splitMenu(&splitToolButton); + splitMenu.insertItem("Some item"); + splitToolButton.setPopup(&splitMenu); + splitToolButton.setPopupDelay(0); + splitToolButton.setMinimumSize(20,20); + + // test push button + QVERIFY(QAccessible::queryAccessibleInterface(&pushButton, &test)); + QCOMPARE(test->role(0), QAccessible::PushButton); + QCOMPARE(test->defaultAction(0), QAccessible::Press); + QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Press")); + QCOMPARE(test->state(0), (int)QAccessible::Normal); + pushButton.setDown(TRUE); + QCOMPARE(test->state(0), (int)QAccessible::Pressed); + QVERIFY(test->doAction(QAccessible::Press, 0)); + QTest::qWait(500); + QCOMPARE(test->state(0), (int)QAccessible::Normal); + test->release(); + + // test toggle push button + QVERIFY(QAccessible::queryAccessibleInterface(&togglepush, &test)); + QCOMPARE(test->role(0), QAccessible::CheckBox); + QCOMPARE(test->defaultAction(0), QAccessible::Press); + QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); + QCOMPARE(test->state(0), (int)QAccessible::Normal); + QVERIFY(test->doAction(QAccessible::Press, 0)); + QTest::qWait(500); + QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Uncheck")); + QCOMPARE(test->state(0), (int)QAccessible::Checked); + test->release(); + + // test menu push button + QVERIFY(QAccessible::queryAccessibleInterface(&menuButton, &test)); + QCOMPARE(test->role(0), QAccessible::ButtonMenu); + QCOMPARE(test->defaultAction(0), QAccessible::Press); + QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Open")); + QCOMPARE(test->state(0), (int)QAccessible::HasPopup); + test->release(); + + // test check box + QVERIFY(QAccessible::queryAccessibleInterface(&checkBox, &test)); + QCOMPARE(test->role(0), QAccessible::CheckBox); + QCOMPARE(test->defaultAction(0), QAccessible::Press); + QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); + QCOMPARE(test->state(0), (int)QAccessible::Normal); + QVERIFY(test->doAction(QAccessible::Press, 0)); + QTest::qWait(500); + QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Uncheck")); + QCOMPARE(test->state(0), (int)QAccessible::Checked); + test->release(); + + // test tristate check box + QVERIFY(QAccessible::queryAccessibleInterface(&tristate, &test)); + QCOMPARE(test->role(0), QAccessible::CheckBox); + QCOMPARE(test->defaultAction(0), QAccessible::Press); + QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Toggle")); + QCOMPARE(test->state(0), (int)QAccessible::Normal); + QVERIFY(test->doAction(QAccessible::Press, 0)); + QTest::qWait(500); + QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); + QCOMPARE(test->state(0), (int)QAccessible::Mixed); + QVERIFY(test->doAction(QAccessible::Press, 0)); + QTest::qWait(500); + QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Uncheck")); + QCOMPARE(test->state(0), (int)QAccessible::Checked); + test->release(); + + // test radiobutton + QVERIFY(QAccessible::queryAccessibleInterface(&radio, &test)); + QCOMPARE(test->role(0), QAccessible::RadioButton); + QCOMPARE(test->defaultAction(0), QAccessible::Press); + QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); + QCOMPARE(test->state(0), (int)QAccessible::Normal); + QVERIFY(test->doAction(QAccessible::Press, 0)); + QTest::qWait(500); + QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); + QCOMPARE(test->state(0), (int)QAccessible::Checked); + test->release(); + + // test standard toolbutton + QVERIFY(QAccessible::queryAccessibleInterface(&toolbutton, &test)); + QCOMPARE(test->role(0), QAccessible::PushButton); + QCOMPARE(test->defaultAction(0), QAccessible::Press); + QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Press")); + QCOMPARE(test->state(0), (int)QAccessible::Normal); + test->release(); + + // toggle tool button + QVERIFY(QAccessible::queryAccessibleInterface(&toggletool, &test)); + QCOMPARE(test->role(0), QAccessible::CheckBox); + QCOMPARE(test->defaultAction(0), QAccessible::Press); + QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); + QCOMPARE(test->state(0), (int)QAccessible::Normal); + QVERIFY(test->doAction(QAccessible::Press, 0)); + QTest::qWait(500); + QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Uncheck")); + QCOMPARE(test->state(0), (int)QAccessible::Checked); + test->release(); + + // test menu toolbutton + QVERIFY(QAccessible::queryAccessibleInterface(&menuToolButton, &test)); + QCOMPARE(test->role(0), QAccessible::ButtonMenu); + QCOMPARE(test->defaultAction(0), 1); + QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Open")); + QCOMPARE(test->state(0), (int)QAccessible::HasPopup); + QCOMPARE(test->actionCount(0), 1); + QCOMPARE(test->actionText(QAccessible::Press, QAccessible::Name, 0), QString("Press")); + test->release(); + + // test splitted menu toolbutton + QVERIFY(QAccessible::queryAccessibleInterface(&splitToolButton, &test)); + QCOMPARE(test->childCount(), 2); + QCOMPARE(test->role(0), QAccessible::ButtonDropDown); + QCOMPARE(test->role(1), QAccessible::PushButton); + QCOMPARE(test->role(2), QAccessible::ButtonMenu); + QCOMPARE(test->defaultAction(0), QAccessible::Press); + QCOMPARE(test->defaultAction(1), QAccessible::Press); + QCOMPARE(test->defaultAction(2), QAccessible::Press); + QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Press")); + QCOMPARE(test->state(0), (int)QAccessible::HasPopup); + QCOMPARE(test->actionCount(0), 1); + QCOMPARE(test->actionText(1, QAccessible::Name, 0), QString("Open")); + QCOMPARE(test->actionText(test->defaultAction(1), QAccessible::Name, 1), QString("Press")); + QCOMPARE(test->state(1), (int)QAccessible::Normal); + QCOMPARE(test->actionText(test->defaultAction(2), QAccessible::Name, 2), QString("Open")); + QCOMPARE(test->state(2), (int)QAccessible::HasPopup); + test->release(); + + QTestAccessibility::clearEvents(); + +#else +// QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); + QSKIP("No action interface in Qt 4 yet.", SkipAll); +#endif +} + +void tst_QAccessibility::sliderTest() +{ +#if !defined(QT3_SUPPORT) + QSKIP("This test needs Qt3Support", SkipAll); +#else +#ifdef QTEST_ACCESSIBILITY + QAccessibleInterface *test = 0; + Q3VBox vbox; + QLabel labelHorizontal("Horizontal", &vbox); + QSlider sliderHorizontal(Qt::Horizontal, &vbox); + labelHorizontal.setBuddy(&sliderHorizontal); + + QLabel labelVertical("Vertical", &vbox); + QSlider sliderVertical(Qt::Vertical, &vbox); + labelVertical.setBuddy(&sliderVertical); + vbox.show(); + + // test horizontal slider + test = QAccessible::queryAccessibleInterface(&sliderHorizontal); + QVERIFY(test); + QCOMPARE(test->childCount(), 3); + QCOMPARE(test->role(0), QAccessible::Slider); + QCOMPARE(test->role(1), QAccessible::PushButton); + QCOMPARE(test->role(2), QAccessible::Indicator); + QCOMPARE(test->role(3), QAccessible::PushButton); + + QCOMPARE(test->text(QAccessible::Name, 0), labelHorizontal.text()); + QCOMPARE(test->text(QAccessible::Name, 1), QSlider::tr("Page left")); + QCOMPARE(test->text(QAccessible::Name, 2), QSlider::tr("Position")); + QCOMPARE(test->text(QAccessible::Name, 3), QSlider::tr("Page right")); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.value())); + QCOMPARE(test->text(QAccessible::Value, 1), QString()); + QCOMPARE(test->text(QAccessible::Value, 2), QString::number(sliderHorizontal.value())); + QCOMPARE(test->text(QAccessible::Value, 3), QString()); +// Skip acton tests. +#if 0 + QCOMPARE(test->defaultAction(0), QAccessible::SetFocus); + QCOMPARE(test->defaultAction(1), QAccessible::Press); + QCOMPARE(test->defaultAction(2), QAccessible::NoAction); + QCOMPARE(test->defaultAction(3), QAccessible::Press); + QCOMPARE(test->actionText(QAccessible::SetFocus, QAccessible::Name, 0), QSlider::tr("Set Focus")); + QCOMPARE(test->actionText(QAccessible::Press, QAccessible::Name, 1), QSlider::tr("Press")); + QCOMPARE(test->actionText(QAccessible::Increase, QAccessible::Name, 2), QSlider::tr("Increase")); + QCOMPARE(test->actionText(QAccessible::Decrease, QAccessible::Name, 2), QSlider::tr("Decrease")); + QCOMPARE(test->actionText(QAccessible::Press, QAccessible::Name, 3), QSlider::tr("Press")); + QVERIFY(test->doAction(QAccessible::Press, 3)); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.pageStep())); + QVERIFY(test->doAction(QAccessible::Press, 3)); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderHorizontal.pageStep())); + QVERIFY(test->doAction(QAccessible::Press, 1)); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.pageStep())); + QVERIFY(test->doAction(QAccessible::Press, 1)); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(0)); + QVERIFY(test->doAction(QAccessible::Increase, 2)); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.lineStep())); + QVERIFY(test->doAction(QAccessible::Increase, 2)); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderHorizontal.lineStep())); + QVERIFY(test->doAction(QAccessible::Decrease, 2)); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.lineStep())); + QVERIFY(test->doAction(QAccessible::Decrease, 2)); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(0)); +#endif + delete test; + + // test vertical slider + test = QAccessible::queryAccessibleInterface(&sliderVertical); + QVERIFY(test); + QCOMPARE(test->childCount(), 3); + QCOMPARE(test->role(0), QAccessible::Slider); + QCOMPARE(test->role(1), QAccessible::PushButton); + QCOMPARE(test->role(2), QAccessible::Indicator); + QCOMPARE(test->role(3), QAccessible::PushButton); + + QCOMPARE(test->text(QAccessible::Name, 0), labelVertical.text()); + QCOMPARE(test->text(QAccessible::Name, 1), QSlider::tr("Page up")); + QCOMPARE(test->text(QAccessible::Name, 2), QSlider::tr("Position")); + QCOMPARE(test->text(QAccessible::Name, 3), QSlider::tr("Page down")); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.value())); + QCOMPARE(test->text(QAccessible::Value, 1), QString()); + QCOMPARE(test->text(QAccessible::Value, 2), QString::number(sliderVertical.value())); + QCOMPARE(test->text(QAccessible::Value, 3), QString()); +// Skip acton tests. +#if 0 + QCOMPARE(test->defaultAction(0), QAccessible::SetFocus); + QCOMPARE(test->defaultAction(1), QAccessible::Press); + QCOMPARE(test->defaultAction(2), QAccessible::NoAction); + QCOMPARE(test->defaultAction(3), QAccessible::Press); + QCOMPARE(test->actionText(QAccessible::SetFocus, QAccessible::Name, 0), QSlider::tr("Set Focus")); + QCOMPARE(test->actionText(QAccessible::Press, QAccessible::Name, 1), QSlider::tr("Press")); + QCOMPARE(test->actionText(QAccessible::Increase, QAccessible::Name, 2), QSlider::tr("Increase")); + QCOMPARE(test->actionText(QAccessible::Decrease, QAccessible::Name, 2), QSlider::tr("Decrease")); + QCOMPARE(test->actionText(QAccessible::Press, QAccessible::Name, 3), QSlider::tr("Press")); + QVERIFY(test->doAction(QAccessible::Press, 3)); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.pageStep())); + QVERIFY(test->doAction(QAccessible::Press, 3)); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderVertical.pageStep())); + QVERIFY(test->doAction(QAccessible::Press, 1)); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.pageStep())); + QVERIFY(test->doAction(QAccessible::Press, 1)); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(0)); + QVERIFY(test->doAction(QAccessible::Increase, 2)); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.lineStep())); + QVERIFY(test->doAction(QAccessible::Increase, 2)); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderVertical.lineStep())); + QVERIFY(test->doAction(QAccessible::Decrease, 2)); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.lineStep())); + QVERIFY(test->doAction(QAccessible::Decrease, 2)); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(0)); +#endif + delete test; + + // Test that when we hide() a slider, the PageLeft, Indicator, and PageRight also gets the + // Invisible state bit set. + enum SubControls { PageLeft = 1, Position = 2, PageRight = 3 }; + + QSlider *slider = new QSlider(); + QAccessibleInterface * const sliderInterface = QAccessible::queryAccessibleInterface(slider); + QVERIFY(sliderInterface); + + QVERIFY(sliderInterface->state(0) & QAccessible::Invisible); + QVERIFY(sliderInterface->state(PageLeft) & QAccessible::Invisible); + QVERIFY(sliderInterface->state(Position) & QAccessible::Invisible); + QVERIFY(sliderInterface->state(PageRight) & QAccessible::Invisible); + + slider->show(); + QVERIFY(sliderInterface->state(0) ^ QAccessible::Invisible); + QVERIFY(sliderInterface->state(PageLeft) ^ QAccessible::Invisible); + QVERIFY(sliderInterface->state(Position) ^ QAccessible::Invisible); + QVERIFY(sliderInterface->state(PageRight) ^ QAccessible::Invisible); + QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(slider, 0, QAccessible::ObjectShow))); + QTestAccessibility::clearEvents(); + + slider->hide(); + QVERIFY(sliderInterface->state(0) & QAccessible::Invisible); + QVERIFY(sliderInterface->state(PageLeft) & QAccessible::Invisible); + QVERIFY(sliderInterface->state(Position) & QAccessible::Invisible); + QVERIFY(sliderInterface->state(PageRight) & QAccessible::Invisible); + QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(slider, 0, QAccessible::ObjectHide))); + QTestAccessibility::clearEvents(); + + // Test that the left/right subcontrols are set to unavailable when the slider is at the minimum/maximum. + slider->show(); + slider->setMinimum(0); + slider->setMaximum(100); + + slider->setValue(50); + QVERIFY(sliderInterface->state(PageLeft) ^ QAccessible::Unavailable); + QVERIFY(sliderInterface->state(Position) ^ QAccessible::Unavailable); + QVERIFY(sliderInterface->state(PageRight) ^ QAccessible::Unavailable); + + slider->setValue(0); + QVERIFY(sliderInterface->state(PageLeft) & QAccessible::Unavailable); + QVERIFY(sliderInterface->state(Position) ^ QAccessible::Unavailable); + QVERIFY(sliderInterface->state(PageRight) ^ QAccessible::Unavailable); + + slider->setValue(100); + QVERIFY(sliderInterface->state(PageLeft) ^ QAccessible::Unavailable); + QVERIFY(sliderInterface->state(Position) ^ QAccessible::Unavailable); + QVERIFY(sliderInterface->state(PageRight) & QAccessible::Unavailable); + + delete sliderInterface; + delete slider; + + // Test that the rects are ok. + { + QSlider *slider = new QSlider(Qt::Horizontal); + slider->show(); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(slider); + QTest::qWait(100); +#endif + QAccessibleInterface * const sliderInterface = QAccessible::queryAccessibleInterface(slider); + QVERIFY(sliderInterface); + + slider->setMinimum(0); + slider->setMaximum(100); + slider->setValue(50); + + const QRect sliderRect = sliderInterface->rect(0); + QVERIFY(sliderRect.isValid()); + + // Verify that the sub-control rects are valid and inside the slider rect. + for (int i = PageLeft; i <= PageRight; ++i) { + const QRect testRect = sliderInterface->rect(i); + QVERIFY(testRect.isValid()); + QVERIFY(sliderRect.contains(testRect)); + } + + delete slider; + delete sliderInterface; + } + + + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +#endif //!QT3_SUPPORT +} + +void tst_QAccessibility::scrollBarTest() +{ +#ifdef QTEST_ACCESSIBILITY + // Test that when we hide() a slider, the PageLeft, Indicator, and PageRight also gets the + // Invisible state bit set. + enum SubControls { LineUp = 1, + PageUp = 2, + Position = 3, + PageDown = 4, + LineDown = 5 + }; + + QScrollBar *scrollBar = new QScrollBar(); + QAccessibleInterface * const scrollBarInterface = QAccessible::queryAccessibleInterface(scrollBar); + QVERIFY(scrollBarInterface); + + QVERIFY(scrollBarInterface->state(0) & QAccessible::Invisible); + QVERIFY(scrollBarInterface->state(PageUp) & QAccessible::Invisible); + QVERIFY(scrollBarInterface->state(Position) & QAccessible::Invisible); + QVERIFY(scrollBarInterface->state(PageDown) & QAccessible::Invisible); + + scrollBar->show(); + QVERIFY(scrollBarInterface->state(0) ^ QAccessible::Invisible); + QVERIFY(scrollBarInterface->state(PageUp) ^ QAccessible::Invisible); + QVERIFY(scrollBarInterface->state(Position) ^ QAccessible::Invisible); + QVERIFY(scrollBarInterface->state(PageDown) ^ QAccessible::Invisible); + QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(scrollBar, 0, QAccessible::ObjectShow))); + QTestAccessibility::clearEvents(); + + scrollBar->hide(); + QVERIFY(scrollBarInterface->state(0) & QAccessible::Invisible); + QVERIFY(scrollBarInterface->state(PageUp) & QAccessible::Invisible); + QVERIFY(scrollBarInterface->state(Position) & QAccessible::Invisible); + QVERIFY(scrollBarInterface->state(PageDown) & QAccessible::Invisible); + QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(scrollBar, 0, QAccessible::ObjectHide))); + QTestAccessibility::clearEvents(); + + // Test that the left/right subcontrols are set to unavailable when the scrollBar is at the minimum/maximum. + scrollBar->show(); + scrollBar->setMinimum(0); + scrollBar->setMaximum(100); + + scrollBar->setValue(50); + QVERIFY(scrollBarInterface->state(PageUp) ^ QAccessible::Unavailable); + QVERIFY(scrollBarInterface->state(Position) ^ QAccessible::Unavailable); + QVERIFY(scrollBarInterface->state(PageDown) ^ QAccessible::Unavailable); + + scrollBar->setValue(0); + QVERIFY(scrollBarInterface->state(PageUp) & QAccessible::Unavailable); + QVERIFY(scrollBarInterface->state(Position) ^ QAccessible::Unavailable); + QVERIFY(scrollBarInterface->state(PageDown) ^ QAccessible::Unavailable); + + scrollBar->setValue(100); + QVERIFY(scrollBarInterface->state(PageUp) ^ QAccessible::Unavailable); + QVERIFY(scrollBarInterface->state(Position) ^ QAccessible::Unavailable); + QVERIFY(scrollBarInterface->state(PageDown) & QAccessible::Unavailable); + + delete scrollBarInterface; + delete scrollBar; + + // Test that the rects are ok. + { + QScrollBar *scrollBar = new QScrollBar(Qt::Horizontal); + scrollBar->resize(200, 50); + scrollBar->show(); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(scrollBar); + QTest::qWait(100); +#endif + QAccessibleInterface * const scrollBarInterface = QAccessible::queryAccessibleInterface(scrollBar); + QVERIFY(scrollBarInterface); + + scrollBar->setMinimum(0); + scrollBar->setMaximum(100); + scrollBar->setValue(50); + + QApplication::processEvents(); + + const QRect scrollBarRect = scrollBarInterface->rect(0); + QVERIFY(scrollBarRect.isValid()); + + // Verify that the sub-control rects are valid and inside the scrollBar rect. + for (int i = LineUp; i <= LineDown; ++i) { + const QRect testRect = scrollBarInterface->rect(i); + QVERIFY(testRect.isValid()); + QVERIFY(scrollBarRect.contains(testRect)); + } + delete scrollBarInterface; + delete scrollBar; + } + + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif + +} + +void tst_QAccessibility::tabTest() +{ +#ifdef QTEST_ACCESSIBILITY + QTabBar *tabBar = new QTabBar(); + tabBar->show(); + + QAccessibleInterface * const interface = QAccessible::queryAccessibleInterface(tabBar); + QVERIFY(interface); + QCOMPARE(interface->childCount(), 2); + interface->doAction(QAccessible::Press, 1); + interface->doAction(QAccessible::Press, 2); + + // Test that the Invisible bit for the navigation buttons gets set + // and cleared correctly. + QVERIFY(interface->state(1) & QAccessible::Invisible); + + const int lots = 10; + for (int i = 0; i < lots; ++i) + tabBar->addTab("Foo"); + + QVERIFY((interface->state(1) & QAccessible::Invisible) == false); + tabBar->hide(); + QVERIFY(interface->state(1) & QAccessible::Invisible); + + tabBar->show(); + tabBar->setCurrentIndex(0); + + // Test that sending a focus action to a tab does not select it. + interface->doAction(QAccessible::Focus, 2, QVariantList()); + QCOMPARE(tabBar->currentIndex(), 0); + + // Test that sending a press action to a tab selects it. + interface->doAction(QAccessible::Press, 2, QVariantList()); + QCOMPARE(tabBar->currentIndex(), 1); + + delete tabBar; + delete interface; + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::menuTest() +{ +#ifdef QTEST_ACCESSIBILITY + { + QMainWindow mw; + mw.resize(300, 200); + QMenu *file = mw.menuBar()->addMenu("&File"); + QMenu *fileNew = file->addMenu("&New..."); + fileNew->menuAction()->setShortcut(tr("Ctrl+N")); + fileNew->addAction("Text file"); + fileNew->addAction("Image file"); + file->addAction("&Open")->setShortcut(tr("Ctrl+O")); + file->addAction("&Save")->setShortcut(tr("Ctrl+S")); + file->addSeparator(); + file->addAction("E&xit")->setShortcut(tr("Alt+F4")); + + QMenu *edit = mw.menuBar()->addMenu("&Edit"); + edit->addAction("&Undo")->setShortcut(tr("Ctrl+Z")); + edit->addAction("&Redo")->setShortcut(tr("Ctrl+Y")); + edit->addSeparator(); + edit->addAction("Cu&t")->setShortcut(tr("Ctrl+X")); + edit->addAction("&Copy")->setShortcut(tr("Ctrl+C")); + edit->addAction("&Paste")->setShortcut(tr("Ctrl+V")); + edit->addAction("&Delete")->setShortcut(tr("Del")); + edit->addSeparator(); + edit->addAction("Pr&operties"); + + mw.menuBar()->addSeparator(); + + QMenu *help = mw.menuBar()->addMenu("&Help"); + help->addAction("&Contents"); + help->addAction("&About"); + + mw.menuBar()->addAction("Action!"); + + mw.show(); // triggers layout + QTest::qWait(100); + + QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(mw.menuBar()); + + QCOMPARE(verifyHierarchy(interface), 0); + + QVERIFY(interface); + QCOMPARE(interface->childCount(), 5); + QCOMPARE(interface->role(0), QAccessible::MenuBar); + QCOMPARE(interface->role(1), QAccessible::MenuItem); + QCOMPARE(interface->role(2), QAccessible::MenuItem); + QCOMPARE(interface->role(3), QAccessible::Separator); + QCOMPARE(interface->role(4), QAccessible::MenuItem); + QCOMPARE(interface->role(5), QAccessible::MenuItem); +#ifndef Q_WS_MAC +#ifdef Q_OS_WINCE + if (!IsValidCEPlatform()) { + QSKIP("Tests do not work on Mobile platforms due to native menus", SkipAll); + } +#endif + QCOMPARE(mw.mapFromGlobal(interface->rect(0).topLeft()), mw.menuBar()->geometry().topLeft()); + QCOMPARE(interface->rect(0).size(), mw.menuBar()->size()); + + QVERIFY(interface->rect(0).contains(interface->rect(1))); + QVERIFY(interface->rect(0).contains(interface->rect(2))); + // QVERIFY(interface->rect(0).contains(interface->rect(3))); //separator might be invisible + QVERIFY(interface->rect(0).contains(interface->rect(4))); + QVERIFY(interface->rect(0).contains(interface->rect(5))); +#endif + + QCOMPARE(interface->text(QAccessible::Name, 1), QString("File")); + QCOMPARE(interface->text(QAccessible::Name, 2), QString("Edit")); + QCOMPARE(interface->text(QAccessible::Name, 3), QString()); + QCOMPARE(interface->text(QAccessible::Name, 4), QString("Help")); + QCOMPARE(interface->text(QAccessible::Name, 5), QString("Action!")); + +// TODO: Currently not working, task to fix is #100019. +#ifndef Q_OS_MAC + QCOMPARE(interface->text(QAccessible::Accelerator, 1), tr("Alt+F")); + QCOMPARE(interface->text(QAccessible::Accelerator, 2), tr("Alt+E")); + QCOMPARE(interface->text(QAccessible::Accelerator, 4), tr("Alt+H")); + QCOMPARE(interface->text(QAccessible::Accelerator, 3), QString()); + QCOMPARE(interface->text(QAccessible::Accelerator, 4), tr("Alt+H")); + QCOMPARE(interface->text(QAccessible::Accelerator, 5), QString()); +#endif + + QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 1), QString("Open")); + QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 2), QString("Open")); + QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 3), QString()); + QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 4), QString("Open")); + QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 5), QString("Execute")); + + bool menuFade = qApp->isEffectEnabled(Qt::UI_FadeMenu); + int menuFadeDelay = 300; + interface->doAction(QAccessible::DefaultAction, 1); + if(menuFade) + QTest::qWait(menuFadeDelay); + QVERIFY(file->isVisible() && !edit->isVisible() && !help->isVisible()); + interface->doAction(QAccessible::DefaultAction, 2); + if(menuFade) + QTest::qWait(menuFadeDelay); + QVERIFY(!file->isVisible() && edit->isVisible() && !help->isVisible()); + interface->doAction(QAccessible::DefaultAction, 3); + if(menuFade) + QTest::qWait(menuFadeDelay); + QVERIFY(!file->isVisible() && !edit->isVisible() && !help->isVisible()); + interface->doAction(QAccessible::DefaultAction, 4); + if(menuFade) + QTest::qWait(menuFadeDelay); + QVERIFY(!file->isVisible() && !edit->isVisible() && help->isVisible()); + interface->doAction(QAccessible::DefaultAction, 5); + if(menuFade) + QTest::qWait(menuFadeDelay); + QVERIFY(!file->isVisible() && !edit->isVisible() && !help->isVisible()); + + interface->doAction(QAccessible::DefaultAction, 1); + delete interface; + interface = QAccessible::queryAccessibleInterface(file); + QCOMPARE(interface->childCount(), 5); + QCOMPARE(interface->role(0), QAccessible::PopupMenu); + QCOMPARE(interface->role(1), QAccessible::MenuItem); + QCOMPARE(interface->role(2), QAccessible::MenuItem); + QCOMPARE(interface->role(3), QAccessible::MenuItem); + QCOMPARE(interface->role(4), QAccessible::Separator); + QCOMPARE(interface->role(5), QAccessible::MenuItem); + QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 1), QString("Open")); + QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 2), QString("Execute")); + QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 3), QString("Execute")); + QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 4), QString()); + QCOMPARE(interface->actionText(QAccessible::DefaultAction, QAccessible::Name, 5), QString("Execute")); + + QAccessibleInterface *iface = 0; + QAccessibleInterface *iface2 = 0; + + // traverse siblings with navigate(Sibling, ...) + int entry = interface->navigate(QAccessible::Child, 1, &iface); + QCOMPARE(entry, 0); + QVERIFY(iface); + QCOMPARE(iface->role(0), QAccessible::MenuItem); + + QAccessible::Role fileRoles[5] = { + QAccessible::MenuItem, + QAccessible::MenuItem, + QAccessible::MenuItem, + QAccessible::Separator, + QAccessible::MenuItem + }; + for (int child = 0; child < 5; ++child) { + entry = iface->navigate(QAccessible::Sibling, child + 1, &iface2); + QCOMPARE(entry, 0); + QVERIFY(iface2); + QCOMPARE(iface2->role(0), fileRoles[child]); + delete iface2; + } + delete iface; + + // traverse menu items with navigate(Down, ...) + entry = interface->navigate(QAccessible::Child, 1, &iface); + QCOMPARE(entry, 0); + QVERIFY(iface); + QCOMPARE(iface->role(0), QAccessible::MenuItem); + + for (int child = 0; child < 4; ++child) { + entry = iface->navigate(QAccessible::Down, 1, &iface2); + delete iface; + iface = iface2; + QCOMPARE(entry, 0); + QVERIFY(iface); + QCOMPARE(iface->role(0), fileRoles[child + 1]); + } + delete iface; + + // traverse menu items with navigate(Up, ...) + entry = interface->navigate(QAccessible::Child, interface->childCount(), &iface); + QCOMPARE(entry, 0); + QVERIFY(iface); + QCOMPARE(iface->role(0), QAccessible::MenuItem); + + for (int child = 3; child >= 0; --child) { + entry = iface->navigate(QAccessible::Up, 1, &iface2); + delete iface; + iface = iface2; + QCOMPARE(entry, 0); + QVERIFY(iface); + QCOMPARE(iface->role(0), fileRoles[child]); + } + delete iface; + + + + // "New" item + entry = interface->navigate(QAccessible::Child, 1, &iface); + QCOMPARE(entry, 0); + QVERIFY(iface); + QCOMPARE(iface->role(0), QAccessible::MenuItem); + + // "New" menu + entry = iface->navigate(QAccessible::Child, 1, &iface2); + delete iface; + iface = iface2; + QCOMPARE(entry, 0); + QVERIFY(iface); + QCOMPARE(iface->role(0), QAccessible::PopupMenu); + + // "Text file" menu item + entry = iface->navigate(QAccessible::Child, 1, &iface2); + delete iface; + iface = iface2; + QCOMPARE(entry, 0); + QVERIFY(iface); + QCOMPARE(iface->role(0), QAccessible::MenuItem); + + // Traverse to the menubar. + QAccessibleInterface *ifaceMenuBar = 0; + entry = iface->navigate(QAccessible::Ancestor, 5, &ifaceMenuBar); + QCOMPARE(ifaceMenuBar->role(0), QAccessible::MenuBar); + delete ifaceMenuBar; + + delete iface; + + + +#if QT_VERSION < 0x040102 + QEXPECT_FAIL("", "Submenus don't open, task 99301", Continue); +#endif + // move mouse pointer away, since that might influence the + // subsequent tests + QTest::mouseMove(&mw, QPoint(-1, -1)); + QTest::qWait(100); + if (menuFade) + QTest::qWait(menuFadeDelay); + interface->doAction(QAccessible::DefaultAction, 1); + QTestEventLoop::instance().enterLoop(2); + +#if defined (Q_OS_WIN) && QT_VERSION < 0x040300 && !defined(Q_OS_WINCE) + QEXPECT_FAIL("", "Don't expect the File menu to be visible in 4.2", Continue); +#endif + QVERIFY(file->isVisible()); + QVERIFY(fileNew->isVisible()); + QVERIFY(!edit->isVisible()); + QVERIFY(!help->isVisible()); + + QTestAccessibility::clearEvents(); + mw.hide(); + + + // Do not crash if the menu don't have a parent + QMenu *menu = new QMenu; + menu->addAction(QLatin1String("one")); + menu->addAction(QLatin1String("two")); + menu->addAction(QLatin1String("three")); + iface = QAccessible::queryAccessibleInterface(menu); + QCOMPARE(iface->navigate(QAccessible::Ancestor, 1, &iface2), 0); + QCOMPARE(iface2->role(0), QAccessible::Application); + // caused a *crash* + iface2->state(0); + delete iface2; + delete iface; + delete menu; + + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::spinBoxTest() +{ +#ifdef QTEST_ACCESSIBILITY + QSpinBox * const spinBox = new QSpinBox(); + spinBox->show(); + + QAccessibleInterface * const interface = QAccessible::queryAccessibleInterface(spinBox); + QVERIFY(interface); + + const QRect widgetRect = spinBox->geometry(); + const QRect accessibleRect = interface->rect(0); + QCOMPARE(accessibleRect, widgetRect); + + // Test that we get valid rects for all the spinbox child interfaces. + const int numChildren = interface->childCount(); + for (int i = 1; i <= numChildren; ++i) { + const QRect childRect = interface->rect(i); + QVERIFY(childRect.isNull() == false); + } + + delete spinBox; + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::doubleSpinBoxTest() +{ +#ifdef QTEST_ACCESSIBILITY + QDoubleSpinBox *doubleSpinBox = new QDoubleSpinBox; + doubleSpinBox->show(); + + QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(doubleSpinBox); + QVERIFY(interface); + + const QRect widgetRect = doubleSpinBox->geometry(); + const QRect accessibleRect = interface->rect(0); + QCOMPARE(accessibleRect, widgetRect); + + // Test that we get valid rects for all the spinbox child interfaces. + const int numChildren = interface->childCount(); + for (int i = 1; i <= numChildren; ++i) { + const QRect childRect = interface->rect(i); + QVERIFY(childRect.isValid()); + } + + delete doubleSpinBox; + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::textEditTest() +{ +#ifdef QTEST_ACCESSIBILITY + { + QTextEdit edit; + QString text = "hello world\nhow are you today?\n"; + edit.setText(text); + edit.show(); + + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&edit); + QCOMPARE(iface->text(QAccessible::Value, 0), text); + QCOMPARE(iface->childCount(), 6); + QCOMPARE(iface->text(QAccessible::Value, 4), QString("hello world")); + QCOMPARE(iface->text(QAccessible::Value, 5), QString("how are you today?")); + QCOMPARE(iface->text(QAccessible::Value, 6), QString()); + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::textBrowserTest() +{ +#ifdef QTEST_ACCESSIBILITY + { + QTextBrowser textBrowser; + QString text = QLatin1String("Hello world\nhow are you today?\n"); + textBrowser.setText(text); + textBrowser.show(); + + QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&textBrowser); + QVERIFY(interface); + QCOMPARE(interface->role(0), QAccessible::StaticText); + QCOMPARE(interface->text(QAccessible::Value, 0), text); + QCOMPARE(interface->childCount(), 6); + QCOMPARE(interface->text(QAccessible::Value, 4), QString("Hello world")); + QCOMPARE(interface->text(QAccessible::Value, 5), QString("how are you today?")); + QCOMPARE(interface->text(QAccessible::Value, 6), QString()); + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::listViewTest() +{ +#if 1 //def QTEST_ACCESSIBILITY + { + QListView listView; + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&listView); + QVERIFY(iface); + QCOMPARE(iface->childCount(), 1); + delete iface; + } + { + QListWidget listView; + listView.addItem(tr("A")); + listView.addItem(tr("B")); + listView.addItem(tr("C")); + listView.resize(400,400); + listView.show(); + QTest::qWait(1); // Need this for indexOfchild to work. +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(&listView); + QTest::qWait(100); +#endif + + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&listView); + QCOMPARE((int)iface->role(0), (int)QAccessible::Client); + QCOMPARE((int)iface->role(1), (int)QAccessible::List); + QCOMPARE(iface->childCount(), 1); + QAccessibleInterface *child; + iface->navigate(QAccessible::Child, 1, &child); + delete iface; + iface = child; + QCOMPARE(iface->text(QAccessible::Name, 1), QString("A")); + QCOMPARE(iface->text(QAccessible::Name, 2), QString("B")); + QCOMPARE(iface->text(QAccessible::Name, 3), QString("C")); + + QCOMPARE(iface->childCount(), 3); + + QAccessibleInterface *childA = 0; + QCOMPARE(iface->navigate(QAccessible::Child, 1, &childA), 0); + QVERIFY(childA); + QCOMPARE(iface->indexOfChild(childA), 1); + QCOMPARE(childA->text(QAccessible::Name, 1), QString("A")); + delete childA; + + QAccessibleInterface *childB = 0; + QCOMPARE(iface->navigate(QAccessible::Child, 2, &childB), 0); + QVERIFY(childB); + QCOMPARE(iface->indexOfChild(childB), 2); + QCOMPARE(childB->text(QAccessible::Name, 1), QString("B")); + delete childB; + + QAccessibleInterface *childC = 0; + QCOMPARE(iface->navigate(QAccessible::Child, 3, &childC), 0); + QVERIFY(childC); + QCOMPARE(iface->indexOfChild(childC), 3); + QCOMPARE(childC->text(QAccessible::Name, 1), QString("C")); + delete childC; + QTestAccessibility::clearEvents(); + + // Check for events + QTest::mouseClick(listView.viewport(), Qt::LeftButton, 0, listView.visualItemRect(listView.item(1)).center()); + QTest::mouseClick(listView.viewport(), Qt::LeftButton, 0, listView.visualItemRect(listView.item(2)).center()); + QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(listView.viewport(), 2, QAccessible::Selection))); + QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(listView.viewport(), 3, QAccessible::Selection))); + delete iface; + + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + + +void tst_QAccessibility::mdiAreaTest() +{ +#ifdef QTEST_ACCESSIBILITY + { + QMdiArea mdiArea; + mdiArea.resize(400,300); + mdiArea.show(); + const int subWindowCount = 3; + for (int i = 0; i < subWindowCount; ++i) + mdiArea.addSubWindow(new QWidget, Qt::Dialog)->show(); + + QList<QMdiSubWindow *> subWindows = mdiArea.subWindowList(); + QCOMPARE(subWindows.count(), subWindowCount); + + QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&mdiArea); + QVERIFY(interface); + QCOMPARE(interface->childCount(), subWindowCount); + + // Right, right, right, ... + for (int i = 0; i < subWindowCount; ++i) { + QAccessibleInterface *destination = 0; + int index = interface->navigate(QAccessible::Right, i + 1, &destination); + if (i == subWindowCount - 1) { + QVERIFY(!destination); + QCOMPARE(index, -1); + } else { + QVERIFY(destination); + QCOMPARE(index, 0); + QCOMPARE(destination->object(), (QObject*)subWindows.at(i + 1)); + delete destination; + } + } + + // Left, left, left, ... + for (int i = subWindowCount; i > 0; --i) { + QAccessibleInterface *destination = 0; + int index = interface->navigate(QAccessible::Left, i, &destination); + if (i == 1) { + QVERIFY(!destination); + QCOMPARE(index, -1); + } else { + QVERIFY(destination); + QCOMPARE(index, 0); + QCOMPARE(destination->object(), (QObject*)subWindows.at(i - 2)); + delete destination; + } + } + // ### Add test for Up and Down. + + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::mdiSubWindowTest() +{ +#ifdef QTEST_ACCESSIBILITY + { + QMdiArea mdiArea; + mdiArea.show(); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(&mdiArea); + QTest::qWait(100); +#endif + qApp->setActiveWindow(&mdiArea); + + bool isSubWindowsPlacedNextToEachOther = false; + const int subWindowCount = 5; + for (int i = 0; i < subWindowCount; ++i) { + QMdiSubWindow *window = mdiArea.addSubWindow(new QPushButton("QAccessibilityTest")); + 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 + // a width which is larger than subWindow->width() * subWindowCount. + if (i == 0) { + int minimumWidth = window->width() * subWindowCount + 20; + mdiArea.resize(mdiArea.size().expandedTo(QSize(minimumWidth, 0))); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(&mdiArea); + QTest::qWait(100); +#endif + if (mdiArea.width() >= minimumWidth) + isSubWindowsPlacedNextToEachOther = true; + } + } + + QList<QMdiSubWindow *> subWindows = mdiArea.subWindowList(); + QCOMPARE(subWindows.count(), subWindowCount); + + QMdiSubWindow *testWindow = subWindows.at(3); + QVERIFY(testWindow); + QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(testWindow); + + // childCount + QVERIFY(interface); + QCOMPARE(interface->childCount(), 1); + + // setText / text + QCOMPARE(interface->text(QAccessible::Name, 0), QString()); + QCOMPARE(interface->text(QAccessible::Name, 1), QString()); + testWindow->setWindowTitle(QLatin1String("ReplaceMe")); + QCOMPARE(interface->text(QAccessible::Name, 0), QLatin1String("ReplaceMe")); + QCOMPARE(interface->text(QAccessible::Name, 1), QLatin1String("ReplaceMe")); + interface->setText(QAccessible::Name, 0, QLatin1String("TitleSetOnWindow")); + QCOMPARE(interface->text(QAccessible::Name, 0), QLatin1String("TitleSetOnWindow")); + interface->setText(QAccessible::Name, 1, QLatin1String("TitleSetOnChild")); + QCOMPARE(interface->text(QAccessible::Name, 0), QLatin1String("TitleSetOnChild")); + + mdiArea.setActiveSubWindow(testWindow); + + // state + QAccessible::State state = QAccessible::Normal | QAccessible::Focusable | QAccessible::Focused + | QAccessible::Movable | QAccessible::Sizeable; + QCOMPARE(interface->state(0), state); + const QRect originalGeometry = testWindow->geometry(); + testWindow->showMaximized(); + state &= ~QAccessible::Sizeable; + state &= ~QAccessible::Movable; + QCOMPARE(interface->state(0), state); + testWindow->showNormal(); + testWindow->move(-10, 0); + QVERIFY(interface->state(0) & QAccessible::Offscreen); + testWindow->setVisible(false); + QVERIFY(interface->state(0) & QAccessible::Invisible); + testWindow->setVisible(true); + testWindow->setEnabled(false); + QVERIFY(interface->state(0) & QAccessible::Unavailable); + testWindow->setEnabled(true); + qApp->setActiveWindow(&mdiArea); + mdiArea.setActiveSubWindow(testWindow); + testWindow->setFocus(); + QVERIFY(testWindow->isAncestorOf(qApp->focusWidget())); + QVERIFY(interface->state(0) & QAccessible::Focused); + testWindow->setGeometry(originalGeometry); + + if (isSubWindowsPlacedNextToEachOther) { + // This part of the test can only be run if the sub windows are + // placed next to each other. + QAccessibleInterface *destination = 0; + QCOMPARE(interface->navigate(QAccessible::Child, 1, &destination), 0); + QVERIFY(destination); + QCOMPARE(destination->object(), (QObject*)testWindow->widget()); + delete destination; + QCOMPARE(interface->navigate(QAccessible::Left, 0, &destination), 0); + QVERIFY(destination); + QCOMPARE(destination->object(), (QObject*)subWindows.at(2)); + delete destination; + QCOMPARE(interface->navigate(QAccessible::Right, 0, &destination), 0); + QVERIFY(destination); + QCOMPARE(destination->object(), (QObject*)subWindows.at(4)); + delete destination; + } + + // rect + const QPoint globalPos = testWindow->mapToGlobal(QPoint(0, 0)); + QCOMPARE(interface->rect(0), QRect(globalPos, testWindow->size())); + testWindow->hide(); + QCOMPARE(interface->rect(0), QRect()); + QCOMPARE(interface->rect(1), QRect()); + testWindow->showMinimized(); + QCOMPARE(interface->rect(1), QRect()); + testWindow->showNormal(); + testWindow->widget()->hide(); + QCOMPARE(interface->rect(1), QRect()); + testWindow->widget()->show(); + const QRect widgetGeometry = testWindow->contentsRect(); + const QPoint globalWidgetPos = QPoint(globalPos.x() + widgetGeometry.x(), + globalPos.y() + widgetGeometry.y()); + QCOMPARE(interface->rect(1), QRect(globalWidgetPos, widgetGeometry.size())); + + // childAt + QCOMPARE(interface->childAt(-10, 0), -1); + QCOMPARE(interface->childAt(globalPos.x(), globalPos.y()), 0); + QCOMPARE(interface->childAt(globalWidgetPos.x(), globalWidgetPos.y()), 1); + testWindow->widget()->hide(); + QCOMPARE(interface->childAt(globalWidgetPos.x(), globalWidgetPos.y()), 0); + + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::lineEditTest() +{ +#ifdef QTEST_ACCESSIBILITY + QLineEdit *le = new QLineEdit; + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(le); + QVERIFY(iface); + le->show(); + + QApplication::processEvents(); + QCOMPARE(iface->childCount(), 0); + QVERIFY(iface->state(0) & QAccessible::Sizeable); + QVERIFY(iface->state(0) & QAccessible::Movable); + QCOMPARE(bool(iface->state(0) & QAccessible::Focusable), le->isActiveWindow()); + QVERIFY(iface->state(0) & QAccessible::Selectable); + QVERIFY(iface->state(0) & QAccessible::HasPopup); + QCOMPARE(bool(iface->state(0) & QAccessible::Focused), le->hasFocus()); + + QString secret(QLatin1String("secret")); + le->setText(secret); + le->setEchoMode(QLineEdit::Normal); + QVERIFY(!(iface->state(0) & QAccessible::Protected)); + QCOMPARE(iface->text(QAccessible::Value, 0), secret); + le->setEchoMode(QLineEdit::NoEcho); + QVERIFY(iface->state(0) & QAccessible::Protected); + QVERIFY(iface->text(QAccessible::Value, 0).isEmpty()); + le->setEchoMode(QLineEdit::Password); + QVERIFY(iface->state(0) & QAccessible::Protected); + QVERIFY(iface->text(QAccessible::Value, 0).isEmpty()); + le->setEchoMode(QLineEdit::PasswordEchoOnEdit); + QVERIFY(iface->state(0) & QAccessible::Protected); + QVERIFY(iface->text(QAccessible::Value, 0).isEmpty()); + le->setEchoMode(QLineEdit::Normal); + QVERIFY(!(iface->state(0) & QAccessible::Protected)); + QCOMPARE(iface->text(QAccessible::Value, 0), secret); + + QWidget *toplevel = new QWidget; + le->setParent(toplevel); + toplevel->show(); + QApplication::processEvents(); + QVERIFY(!(iface->state(0) & QAccessible::Sizeable)); + QVERIFY(!(iface->state(0) & QAccessible::Movable)); + QCOMPARE(bool(iface->state(0) & QAccessible::Focusable), le->isActiveWindow()); + QVERIFY(iface->state(0) & QAccessible::Selectable); + QVERIFY(iface->state(0) & QAccessible::HasPopup); + QCOMPARE(bool(iface->state(0) & QAccessible::Focused), le->hasFocus()); + + QLineEdit *le2 = new QLineEdit(toplevel); + le2->show(); + QTest::qWait(100); + le2->activateWindow(); + QTest::qWait(100); + le->setFocus(Qt::TabFocusReason); + QTestAccessibility::clearEvents(); + le2->setFocus(Qt::TabFocusReason); + QTRY_VERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(le2, 0, QAccessible::Focus))); + delete iface; + delete le; + delete le2; + delete toplevel; + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::workspaceTest() +{ +#ifdef QTEST_ACCESSIBILITY + { + 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()); + } + + QWidgetList subWindows = workspace.windowList(); + QCOMPARE(subWindows.count(), subWindowCount); + + QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&workspace); + QVERIFY(interface); + QCOMPARE(interface->childCount(), subWindowCount); + + // Right, right, right, ... + for (int i = 0; i < subWindowCount; ++i) { + QAccessibleInterface *destination = 0; + int index = interface->navigate(QAccessible::Right, i + 1, &destination); + if (i == subWindowCount - 1) { + QVERIFY(!destination); + QCOMPARE(index, -1); + } else { + QVERIFY(destination); + QCOMPARE(index, 0); + QCOMPARE(destination->object(), (QObject*)subWindows.at(i + 1)); + delete destination; + } + } + + // Left, left, left, ... + for (int i = subWindowCount; i > 0; --i) { + QAccessibleInterface *destination = 0; + int index = interface->navigate(QAccessible::Left, i, &destination); + if (i == 1) { + QVERIFY(!destination); + QCOMPARE(index, -1); + } else { + QVERIFY(destination); + QCOMPARE(index, 0); + QCOMPARE(destination->object(), (QObject*)subWindows.at(i - 2)); + delete destination; + } + } + // ### Add test for Up and Down. + + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::dialogButtonBoxTest() +{ +#ifdef QTEST_ACCESSIBILITY + { + QDialogButtonBox box(QDialogButtonBox::Reset | + QDialogButtonBox::Help | + QDialogButtonBox::Ok, Qt::Horizontal); + + + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&box); + QVERIFY(iface); + box.show(); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(&box); + QTest::qWait(100); +#endif + + QApplication::processEvents(); + QCOMPARE(iface->childCount(), 3); + QCOMPARE(iface->role(0), QAccessible::Grouping); + QCOMPARE(iface->role(1), QAccessible::PushButton); + QCOMPARE(iface->role(2), QAccessible::PushButton); + QCOMPARE(iface->role(3), QAccessible::PushButton); + QStringList actualOrder; + QAccessibleInterface *child; + QAccessibleInterface *leftmost; + iface->navigate(QAccessible::Child, 1, &child); + // first find the leftmost button + while (child->navigate(QAccessible::Left, 1, &leftmost) != -1) { + delete child; + child = leftmost; + } + leftmost = child; + + // then traverse from left to right to find the correct order of the buttons + int right = 0; + while (right != -1) { + actualOrder << leftmost->text(QAccessible::Name, 0); + right = leftmost->navigate(QAccessible::Right, 1, &child); + delete leftmost; + leftmost = child; + } + + QStringList expectedOrder; + QDialogButtonBox::ButtonLayout btnlout = + QDialogButtonBox::ButtonLayout(QApplication::style()->styleHint(QStyle::SH_DialogButtonLayout)); + switch (btnlout) { + case QDialogButtonBox::WinLayout: + expectedOrder << QDialogButtonBox::tr("Reset") + << QDialogButtonBox::tr("OK") + << QDialogButtonBox::tr("Help"); + break; + case QDialogButtonBox::GnomeLayout: + case QDialogButtonBox::KdeLayout: + case QDialogButtonBox::MacLayout: + expectedOrder << QDialogButtonBox::tr("Help") + << QDialogButtonBox::tr("Reset") + << QDialogButtonBox::tr("OK"); + break; + } + QCOMPARE(actualOrder, expectedOrder); + delete iface; + QApplication::processEvents(); + QTestAccessibility::clearEvents(); + } + + { + QDialogButtonBox box(QDialogButtonBox::Reset | + QDialogButtonBox::Help | + QDialogButtonBox::Ok, Qt::Horizontal); + + + // Test up and down navigation + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&box); + QVERIFY(iface); + box.setOrientation(Qt::Vertical); + box.show(); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(&box); + QTest::qWait(100); +#endif + + QApplication::processEvents(); + QAccessibleInterface *child; + QStringList actualOrder; + iface->navigate(QAccessible::Child, 1, &child); + // first find the topmost button + QAccessibleInterface *other; + while (child->navigate(QAccessible::Up, 1, &other) != -1) { + delete child; + child = other; + } + other = child; + + // then traverse from top to bottom to find the correct order of the buttons + actualOrder.clear(); + int right = 0; + while (right != -1) { + actualOrder << other->text(QAccessible::Name, 0); + right = other->navigate(QAccessible::Down, 1, &child); + delete other; + other = child; + } + + QStringList expectedOrder; + expectedOrder << QDialogButtonBox::tr("OK") + << QDialogButtonBox::tr("Reset") + << QDialogButtonBox::tr("Help"); + + QCOMPARE(actualOrder, expectedOrder); + delete iface; + QApplication::processEvents(); + + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::dialTest() +{ +#ifdef QTEST_ACCESSIBILITY + { + QDial dial; + dial.setValue(20); + QCOMPARE(dial.value(), 20); + dial.show(); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(&dial); + QTest::qWait(100); +#endif + + QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&dial); + QVERIFY(interface); + + // Child count; 1 = SpeedoMeter, 2 = SliderHandle. + QCOMPARE(interface->childCount(), 2); + + QCOMPARE(interface->role(0), QAccessible::Dial); + QCOMPARE(interface->role(1), QAccessible::Slider); + QCOMPARE(interface->role(2), QAccessible::Indicator); + + QCOMPARE(interface->text(QAccessible::Value, 0), QString::number(dial.value())); + QCOMPARE(interface->text(QAccessible::Value, 1), QString::number(dial.value())); + QCOMPARE(interface->text(QAccessible::Value, 2), QString::number(dial.value())); + QCOMPARE(interface->text(QAccessible::Name, 0), QLatin1String("QDial")); + QCOMPARE(interface->text(QAccessible::Name, 1), QLatin1String("SpeedoMeter")); + QCOMPARE(interface->text(QAccessible::Name, 2), QLatin1String("SliderHandle")); + QCOMPARE(interface->text(QAccessible::Name, 3), QLatin1String("")); + + QCOMPARE(interface->state(1), interface->state(0)); + QCOMPARE(interface->state(2), interface->state(0) | QAccessible::HotTracked); + + // Rect + QCOMPARE(interface->rect(0), dial.geometry()); + QVERIFY(interface->rect(1).isValid()); + QVERIFY(dial.geometry().contains(interface->rect(1))); + QVERIFY(interface->rect(2).isValid()); + QVERIFY(interface->rect(1).contains(interface->rect(2))); + QVERIFY(!interface->rect(3).isValid()); + + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::rubberBandTest() +{ +#ifdef QTEST_ACCESSIBILITY + QRubberBand rubberBand(QRubberBand::Rectangle); + QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&rubberBand); + QVERIFY(interface); + QCOMPARE(interface->role(0), QAccessible::Border); + delete interface; + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::abstractScrollAreaTest() +{ +#ifdef QTEST_ACCESSIBILITY + { + QAbstractScrollArea abstractScrollArea; + + QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&abstractScrollArea); + QVERIFY(interface); + QVERIFY(!interface->rect(0).isValid()); + QVERIFY(!interface->rect(1).isValid()); + QCOMPARE(interface->childAt(200, 200), -1); + + abstractScrollArea.resize(400, 400); + abstractScrollArea.show(); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(&abstractScrollArea); + QTest::qWait(100); +#endif + const QRect globalGeometry = QRect(abstractScrollArea.mapToGlobal(QPoint(0, 0)), + abstractScrollArea.size()); + + // Viewport. + QCOMPARE(interface->childCount(), 1); + QWidget *viewport = abstractScrollArea.viewport(); + QVERIFY(viewport); + QVERIFY(verifyChild(viewport, interface, 1, globalGeometry)); + + // Horizontal scrollBar. + abstractScrollArea.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + QCOMPARE(interface->childCount(), 2); + QWidget *horizontalScrollBar = abstractScrollArea.horizontalScrollBar(); + QWidget *horizontalScrollBarContainer = horizontalScrollBar->parentWidget(); + QVERIFY(verifyChild(horizontalScrollBarContainer, interface, 2, globalGeometry)); + + // Horizontal scrollBar widgets. + QLabel *secondLeftLabel = new QLabel(QLatin1String("L2")); + abstractScrollArea.addScrollBarWidget(secondLeftLabel, Qt::AlignLeft); + QCOMPARE(interface->childCount(), 2); + + QLabel *firstLeftLabel = new QLabel(QLatin1String("L1")); + abstractScrollArea.addScrollBarWidget(firstLeftLabel, Qt::AlignLeft); + QCOMPARE(interface->childCount(), 2); + + QLabel *secondRightLabel = new QLabel(QLatin1String("R2")); + abstractScrollArea.addScrollBarWidget(secondRightLabel, Qt::AlignRight); + QCOMPARE(interface->childCount(), 2); + + QLabel *firstRightLabel = new QLabel(QLatin1String("R1")); + abstractScrollArea.addScrollBarWidget(firstRightLabel, Qt::AlignRight); + QCOMPARE(interface->childCount(), 2); + + // Vertical scrollBar. + abstractScrollArea.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + QCOMPARE(interface->childCount(), 3); + QWidget *verticalScrollBar = abstractScrollArea.verticalScrollBar(); + QWidget *verticalScrollBarContainer = verticalScrollBar->parentWidget(); + QVERIFY(verifyChild(verticalScrollBarContainer, interface, 3, globalGeometry)); + + // Vertical scrollBar widgets. + QLabel *secondTopLabel = new QLabel(QLatin1String("T2")); + abstractScrollArea.addScrollBarWidget(secondTopLabel, Qt::AlignTop); + QCOMPARE(interface->childCount(), 3); + + QLabel *firstTopLabel = new QLabel(QLatin1String("T1")); + abstractScrollArea.addScrollBarWidget(firstTopLabel, Qt::AlignTop); + QCOMPARE(interface->childCount(), 3); + + QLabel *secondBottomLabel = new QLabel(QLatin1String("B2")); + abstractScrollArea.addScrollBarWidget(secondBottomLabel, Qt::AlignBottom); + QCOMPARE(interface->childCount(), 3); + + QLabel *firstBottomLabel = new QLabel(QLatin1String("B1")); + abstractScrollArea.addScrollBarWidget(firstBottomLabel, Qt::AlignBottom); + QCOMPARE(interface->childCount(), 3); + + // CornerWidget. + abstractScrollArea.setCornerWidget(new QLabel(QLatin1String("C"))); + QCOMPARE(interface->childCount(), 4); + QWidget *cornerWidget = abstractScrollArea.cornerWidget(); + QVERIFY(verifyChild(cornerWidget, interface, 4, globalGeometry)); + + // Test navigate. + QAccessibleInterface *target = 0; + + // viewport -> Up -> NOTHING + const int viewportIndex = indexOfChild(interface, viewport); + QVERIFY(viewportIndex != -1); + QCOMPARE(interface->navigate(QAccessible::Up, viewportIndex, &target), -1); + QVERIFY(!target); + + // viewport -> Left -> NOTHING + QCOMPARE(interface->navigate(QAccessible::Left, viewportIndex, &target), -1); + QVERIFY(!target); + + // viewport -> Down -> horizontalScrollBarContainer + const int horizontalScrollBarContainerIndex = indexOfChild(interface, horizontalScrollBarContainer); + QVERIFY(horizontalScrollBarContainerIndex != -1); + QCOMPARE(interface->navigate(QAccessible::Down, viewportIndex, &target), 0); + QVERIFY(target); + QCOMPARE(target->object(), static_cast<QObject *>(horizontalScrollBarContainer)); + delete target; + target = 0; + + // horizontalScrollBarContainer -> Left -> NOTHING + QCOMPARE(interface->navigate(QAccessible::Left, horizontalScrollBarContainerIndex, &target), -1); + QVERIFY(!target); + + // horizontalScrollBarContainer -> Down -> NOTHING + QVERIFY(horizontalScrollBarContainerIndex != -1); + QCOMPARE(interface->navigate(QAccessible::Down, horizontalScrollBarContainerIndex, &target), -1); + QVERIFY(!target); + + // horizontalScrollBarContainer -> Right -> cornerWidget + const int cornerWidgetIndex = indexOfChild(interface, cornerWidget); + QVERIFY(cornerWidgetIndex != -1); + QCOMPARE(interface->navigate(QAccessible::Right, horizontalScrollBarContainerIndex, &target), 0); + QVERIFY(target); + QCOMPARE(target->object(), static_cast<QObject *>(cornerWidget)); + delete target; + target = 0; + + // cornerWidget -> Down -> NOTHING + QCOMPARE(interface->navigate(QAccessible::Down, cornerWidgetIndex, &target), -1); + QVERIFY(!target); + + // cornerWidget -> Right -> NOTHING + QVERIFY(cornerWidgetIndex != -1); + QCOMPARE(interface->navigate(QAccessible::Right, cornerWidgetIndex, &target), -1); + QVERIFY(!target); + + // cornerWidget -> Up -> verticalScrollBarContainer + const int verticalScrollBarContainerIndex = indexOfChild(interface, verticalScrollBarContainer); + QVERIFY(verticalScrollBarContainerIndex != -1); + QCOMPARE(interface->navigate(QAccessible::Up, cornerWidgetIndex, &target), 0); + QVERIFY(target); + QCOMPARE(target->object(), static_cast<QObject *>(verticalScrollBarContainer)); + delete target; + target = 0; + + // verticalScrollBarContainer -> Right -> NOTHING + QCOMPARE(interface->navigate(QAccessible::Right, verticalScrollBarContainerIndex, &target), -1); + QVERIFY(!target); + + // verticalScrollBarContainer -> Up -> NOTHING + QCOMPARE(interface->navigate(QAccessible::Up, verticalScrollBarContainerIndex, &target), -1); + QVERIFY(!target); + + // verticalScrollBarContainer -> Left -> viewport + QCOMPARE(interface->navigate(QAccessible::Left, verticalScrollBarContainerIndex, &target), 0); + QVERIFY(target); + QCOMPARE(target->object(), static_cast<QObject *>(viewport)); + delete target; + target = 0; + + QCOMPARE(verifyHierarchy(interface), 0); + + delete interface; + } + + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::scrollAreaTest() +{ +#ifdef QTEST_ACCESSIBILITY + { + QScrollArea scrollArea; + scrollArea.show(); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(&scrollArea); + QTest::qWait(100); +#endif + QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&scrollArea); + QVERIFY(interface); + QCOMPARE(interface->childCount(), 1); // The viewport. + delete interface; + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::tableWidgetTest() +{ +#ifdef QTEST_ACCESSIBILITY + { + QTableWidget *w = new QTableWidget(8,4); + for (int r = 0; r < 8; ++r) { + for (int c = 0; c < 4; ++c) { + w->setItem(r, c, new QTableWidgetItem(tr("%1,%2").arg(c).arg(r))); + } + } + w->resize(100, 100); + w->show(); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(w); + QTest::qWait(100); +#endif + QAccessibleInterface *client = QAccessible::queryAccessibleInterface(w); + QCOMPARE(client->role(0), QAccessible::Client); + QCOMPARE(client->childCount(), 3); + QAccessibleInterface *view = 0; + client->navigate(QAccessible::Child, 1, &view); + QCOMPARE(view->role(0), QAccessible::Table); + QAccessibleInterface *ifRow; + view->navigate(QAccessible::Child, 2, &ifRow); + QCOMPARE(ifRow->role(0), QAccessible::Row); + QAccessibleInterface *item; + int entry = ifRow->navigate(QAccessible::Child, 1, &item); + QCOMPARE(entry, 1); + QCOMPARE(item , (QAccessibleInterface*)0); + QCOMPARE(ifRow->text(QAccessible::Name, 2), QLatin1String("0,0")); + QCOMPARE(ifRow->text(QAccessible::Name, 3), QLatin1String("1,0")); + + QCOMPARE(verifyHierarchy(client), 0); + + delete ifRow; + delete view; + delete client; + delete w; + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif + +} + +class QtTestTableModel: public QAbstractTableModel +{ + Q_OBJECT + +signals: + void invalidIndexEncountered() const; + +public: + QtTestTableModel(int rows = 0, int columns = 0, QObject *parent = 0) + : QAbstractTableModel(parent), + row_count(rows), + column_count(columns) {} + + int rowCount(const QModelIndex& = QModelIndex()) const { return row_count; } + int columnCount(const QModelIndex& = QModelIndex()) const { return column_count; } + + QVariant data(const QModelIndex &idx, int role) const + { + if (!idx.isValid() || idx.row() >= row_count || idx.column() >= column_count) { + qWarning() << "Invalid modelIndex [%d,%d,%p]" << idx; + emit invalidIndexEncountered(); + return QVariant(); + } + + if (role == Qt::DisplayRole || role == Qt::EditRole) + return QString("[%1,%2,%3]").arg(idx.row()).arg(idx.column()).arg(0); + + return QVariant(); + } + + void removeLastRow() + { + beginRemoveRows(QModelIndex(), row_count - 1, row_count - 1); + --row_count; + endRemoveRows(); + } + + void removeAllRows() + { + beginRemoveRows(QModelIndex(), 0, row_count - 1); + row_count = 0; + endRemoveRows(); + } + + void removeLastColumn() + { + beginRemoveColumns(QModelIndex(), column_count - 1, column_count - 1); + --column_count; + endRemoveColumns(); + } + + void removeAllColumns() + { + beginRemoveColumns(QModelIndex(), 0, column_count - 1); + column_count = 0; + endRemoveColumns(); + } + + void reset() + { + QAbstractTableModel::reset(); + } + + int row_count; + int column_count; +}; + +class QtTestDelegate : public QItemDelegate +{ +public: + QtTestDelegate(QWidget *parent = 0) : QItemDelegate(parent) {} + + virtual QSize sizeHint(const QStyleOptionViewItem &/*option*/, const QModelIndex &/*index*/) const + { + return QSize(100,50); + } +}; + +void tst_QAccessibility::tableViewTest() +{ +#ifdef QTEST_ACCESSIBILITY + { + QtTestTableModel *model = new QtTestTableModel(3, 4); + QTableView *w = new QTableView(); + w->setModel(model); + w->setItemDelegate(new QtTestDelegate(w)); + w->resize(450,200); + w->resizeColumnsToContents(); + w->resizeRowsToContents(); + w->show(); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(w); + QTest::qWait(100); +#endif + QAccessibleInterface *client = QAccessible::queryAccessibleInterface(w); + QAccessibleInterface *table2; + client->navigate(QAccessible::Child, 1, &table2); + QVERIFY(table2); + QCOMPARE(table2->role(1), QAccessible::Row); + QAccessibleInterface *toprow = 0; + table2->navigate(QAccessible::Child, 1, &toprow); + QVERIFY(toprow); + QCOMPARE(toprow->role(1), QAccessible::RowHeader); + QCOMPARE(toprow->role(2), QAccessible::ColumnHeader); + delete toprow; + + // call childAt() for each child until we reach the bottom, + // and do it for each row in the table + for (int y = 1; y < 5; ++y) { // this includes the special header + for (int x = 1; x < 6; ++x) { + QCOMPARE(client->role(0), QAccessible::Client); + QRect globalRect = client->rect(0); + QVERIFY(globalRect.isValid()); + // make sure we don't hit the vertical header ##### + QPoint p = globalRect.topLeft() + QPoint(8, 8); + p.ry() += 50 * (y - 1); + p.rx() += 100 * (x - 1); + int index = client->childAt(p.x(), p.y()); + QCOMPARE(index, 1); + QCOMPARE(client->role(index), QAccessible::Table); + + // navigate to table/viewport + QAccessibleInterface *table; + client->navigate(QAccessible::Child, index, &table); + QVERIFY(table); + index = table->childAt(p.x(), p.y()); + QCOMPARE(index, y); + QCOMPARE(table->role(index), QAccessible::Row); + QAccessibleInterface *row; + QCOMPARE(table->role(1), QAccessible::Row); + + // navigate to the row + table->navigate(QAccessible::Child, index, &row); + QVERIFY(row); + QCOMPARE(row->role(1), QAccessible::RowHeader); + index = row->childAt(p.x(), p.y()); + QVERIFY(index > 0); + if (x == 1 && y == 1) { + QCOMPARE(row->role(index), QAccessible::RowHeader); + QCOMPARE(row->text(QAccessible::Name, index), QLatin1String("")); + } else if (x > 1 && y > 1) { + QCOMPARE(row->role(index), QAccessible::Cell); + QCOMPARE(row->text(QAccessible::Name, index), QString::fromAscii("[%1,%2,0]").arg(y - 2).arg(x - 2)); + } else if (x == 1) { + QCOMPARE(row->role(index), QAccessible::RowHeader); + QCOMPARE(row->text(QAccessible::Name, index), QString::fromAscii("%1").arg(y - 1)); + } else if (y == 1) { + QCOMPARE(row->role(index), QAccessible::ColumnHeader); + QCOMPARE(row->text(QAccessible::Name, index), QString::fromAscii("%1").arg(x - 1)); + } + delete table; + delete row; + } + } + delete table2; + delete client; + delete w; + delete model; + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::calendarWidgetTest() +{ +#ifndef QT_NO_CALENDARWIDGET +#ifdef QTEST_ACCESSIBILITY + { + QCalendarWidget calendarWidget; + + QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&calendarWidget); + QVERIFY(interface); + QCOMPARE(interface->role(0), QAccessible::Table); + QVERIFY(!interface->rect(0).isValid()); + QVERIFY(!interface->rect(1).isValid()); + QCOMPARE(interface->childAt(200, 200), -1); + + calendarWidget.resize(400, 300); + calendarWidget.show(); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(&calendarWidget); + QTest::qWait(100); +#endif + + // 1 = navigationBar, 2 = view. + QCOMPARE(interface->childCount(), 2); + + const QRect globalGeometry = QRect(calendarWidget.mapToGlobal(QPoint(0, 0)), + calendarWidget.size()); + QCOMPARE(interface->rect(0), globalGeometry); + + QWidget *navigationBar = 0; + foreach (QObject *child, calendarWidget.children()) { + if (child->objectName() == QLatin1String("qt_calendar_navigationbar")) { + navigationBar = static_cast<QWidget *>(child); + break; + } + } + QVERIFY(navigationBar); + QVERIFY(verifyChild(navigationBar, interface, 1, globalGeometry)); + + QAbstractItemView *calendarView = 0; + foreach (QObject *child, calendarWidget.children()) { + if (child->objectName() == QLatin1String("qt_calendar_calendarview")) { + calendarView = static_cast<QAbstractItemView *>(child); + break; + } + } + QVERIFY(calendarView); + QVERIFY(verifyChild(calendarView, interface, 2, globalGeometry)); + + // Hide navigation bar. + calendarWidget.setNavigationBarVisible(false); + QCOMPARE(interface->childCount(), 1); + QVERIFY(!navigationBar->isVisible()); + + QVERIFY(verifyChild(calendarView, interface, 1, globalGeometry)); + + // Show navigation bar. + calendarWidget.setNavigationBarVisible(true); + QCOMPARE(interface->childCount(), 2); + QVERIFY(navigationBar->isVisible()); + + // Navigate to the navigation bar via Child. + QAccessibleInterface *navigationBarInterface = 0; + QCOMPARE(interface->navigate(QAccessible::Child, 1, &navigationBarInterface), 0); + QVERIFY(navigationBarInterface); + QCOMPARE(navigationBarInterface->object(), (QObject*)navigationBar); + delete navigationBarInterface; + navigationBarInterface = 0; + + // Navigate to the view via Child. + QAccessibleInterface *calendarViewInterface = 0; + QCOMPARE(interface->navigate(QAccessible::Child, 2, &calendarViewInterface), 0); + QVERIFY(calendarViewInterface); + QCOMPARE(calendarViewInterface->object(), (QObject*)calendarView); + delete calendarViewInterface; + calendarViewInterface = 0; + + QAccessibleInterface *doesNotExistsInterface = 0; + QCOMPARE(interface->navigate(QAccessible::Child, 3, &doesNotExistsInterface), -1); + QVERIFY(!doesNotExistsInterface); + + // Navigate from navigation bar -> view (Down). + QCOMPARE(interface->navigate(QAccessible::Down, 1, &calendarViewInterface), 0); + QVERIFY(calendarViewInterface); + QCOMPARE(calendarViewInterface->object(), (QObject*)calendarView); + delete calendarViewInterface; + calendarViewInterface = 0; + + // Navigate from view -> navigation bar (Up). + QCOMPARE(interface->navigate(QAccessible::Up, 2, &navigationBarInterface), 0); + QVERIFY(navigationBarInterface); + QCOMPARE(navigationBarInterface->object(), (QObject*)navigationBar); + delete navigationBarInterface; + navigationBarInterface = 0; + + } + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +#endif // QT_NO_CALENDARWIDGET +} + +void tst_QAccessibility::dockWidgetTest() +{ +#ifndef QT_NO_DOCKWIDGET + +#ifdef QTEST_ACCESSIBILITY + // Set up a proper main window with two dock widgets + QMainWindow *mw = new QMainWindow(); + QFrame *central = new QFrame(mw); + mw->setCentralWidget(central); + QMenuBar *mb = new QMenuBar(mw); + mb->addAction(tr("&File")); + mw->setMenuBar(mb); + + QDockWidget *dock1 = new QDockWidget(mw); + mw->addDockWidget(Qt::LeftDockWidgetArea, dock1); + QPushButton *pb1 = new QPushButton(tr("Push me"), dock1); + dock1->setWidget(pb1); + + QDockWidget *dock2 = new QDockWidget(mw); + mw->addDockWidget(Qt::BottomDockWidgetArea, dock2); + QPushButton *pb2 = new QPushButton(tr("Push me"), dock2); + dock2->setWidget(pb2); + + mw->resize(600,400); + mw->show(); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(mw); + QTest::qWait(100); +#endif + + QAccessibleInterface *accMainWindow = QAccessible::queryAccessibleInterface(mw); + // 4 children: menu bar, dock1, dock2, and central widget + QCOMPARE(accMainWindow->childCount(), 4); + QAccessibleInterface *accDock1 = 0; + for (int i = 1; i <= 4; ++i) { + if (accMainWindow->role(i) == QAccessible::Window) { + accMainWindow->navigate(QAccessible::Child, i, &accDock1); + if (accDock1 && qobject_cast<QDockWidget*>(accDock1->object()) == dock1) { + break; + } else { + delete accDock1; + } + } + } + QVERIFY(accDock1); + QCOMPARE(accDock1->role(0), QAccessible::Window); + QCOMPARE(accDock1->role(1), QAccessible::TitleBar); + QVERIFY(accDock1->rect(0).contains(accDock1->rect(1))); + + QPoint globalPos = dock1->mapToGlobal(QPoint(0,0)); + globalPos.rx()+=5; //### query style + globalPos.ry()+=5; + int entry = accDock1->childAt(globalPos.x(), globalPos.y()); //### + QAccessibleInterface *accTitleBar; + entry = accDock1->navigate(QAccessible::Child, entry, &accTitleBar); + QCOMPARE(accTitleBar->role(0), QAccessible::TitleBar); + QCOMPARE(accDock1->indexOfChild(accTitleBar), 1); + QAccessibleInterface *acc; + entry = accTitleBar->navigate(QAccessible::Ancestor, 1, &acc); + QVERIFY(acc); + QCOMPARE(entry, 0); + QCOMPARE(acc->role(0), QAccessible::Window); + + + delete accTitleBar; + delete accDock1; + delete pb1; + delete pb2; + delete dock1; + delete dock2; + delete mw; + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +#endif // QT_NO_DOCKWIDGET +} + +void tst_QAccessibility::pushButtonTest() +{ +#if !defined(QT3_SUPPORT) + qWarning( "Should never get here without Qt3Support"); + return ; +#else +#ifdef QTEST_ACCESSIBILITY + // Set up a proper main window with two dock widgets + QWidget *toplevel = createGUI(); + QObject *topRight = toplevel->findChild<QObject *>("topRight"); + + toplevel->show(); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(toplevel); + QTest::qWait(100); +#endif + QPushButton *pb = qobject_cast<QPushButton*>(topRight->findChild<QPushButton *>("pbOk")); + QPoint pt = pb->mapToGlobal(pb->geometry().topLeft()); + QRect rect(pt, pb->geometry().size()); + pt = rect.center(); + + QAccessibleInterface *accToplevel = QAccessible::queryAccessibleInterface(toplevel); + QAccessibleInterface *acc; + QAccessibleInterface *acc2; + int entry = accToplevel->childAt(pt.x(), pt.y()); + int child = accToplevel->navigate(QAccessible::Child, entry, &acc); + if (acc) { + entry = acc->childAt(pt.x(), pt.y()); + child = acc->navigate(QAccessible::Child, entry, &acc2); + delete acc; + acc = acc2; + } + QCOMPARE(acc->role(0), QAccessible::PushButton); + QCOMPARE(acc->rect(0), rect); + QCOMPARE(acc->childAt(pt.x(), pt.y()), 0); + + delete acc; + delete accToplevel; + delete toplevel; + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +#endif //QT3_SUPPORT +} + +void tst_QAccessibility::comboBoxTest() +{ +#ifdef QTEST_ACCESSIBILITY +#if defined(Q_OS_WINCE) + if (!IsValidCEPlatform()) { + QSKIP("Test skipped on Windows Mobile test hardware", SkipAll); + } +#endif + QWidget *w = new QWidget(); + QComboBox *cb = new QComboBox(w); + cb->addItems(QStringList() << "one" << "two" << "three"); + w->show(); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(w); + QTest::qWait(100); +#endif + QAccessibleInterface *acc = QAccessible::queryAccessibleInterface(w); + delete acc; + + acc = QAccessible::queryAccessibleInterface(cb); + + QRect accRect = acc->rect(0); + for (int i = 1; i < acc->childCount(); ++i) { + QVERIFY(accRect.contains(acc->rect(i))); + } + QCOMPARE(acc->doAction(QAccessible::Press, 2), true); + QTest::qWait(400); + QAccessibleInterface *accList = 0; + int entry = acc->navigate(QAccessible::Child, 3, &accList); + QCOMPARE(entry, 0); + QAccessibleInterface *acc2 = 0; + entry = accList->navigate(QAccessible::Ancestor, 1, &acc2); + QCOMPARE(entry, 0); + QCOMPARE(verifyHierarchy(acc), 0); + delete acc2; + + delete accList; + delete acc; + delete w; + + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif + +} + +void tst_QAccessibility::treeWidgetTest() +{ +#ifdef QTEST_ACCESSIBILITY + QWidget *w = new QWidget; + QTreeWidget *tree = new QTreeWidget(w); + QHBoxLayout *l = new QHBoxLayout(w); + l->addWidget(tree); + for (int i = 0; i < 10; ++i) { + QStringList strings = QStringList() << QString::fromAscii("row: %1").arg(i) + << QString("column 1") << QString("column 2"); + + tree->addTopLevelItem(new QTreeWidgetItem(strings)); + } + w->show(); +// QTest::qWait(1000); +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(w); + QTest::qWait(100); +#endif + + QAccessibleInterface *acc = QAccessible::queryAccessibleInterface(tree); + QAccessibleInterface *accViewport = 0; + int entry = acc->navigate(QAccessible::Child, 1, &accViewport); + QVERIFY(accViewport); + QCOMPARE(entry, 0); + QAccessibleInterface *accTreeItem = 0; + entry = accViewport->navigate(QAccessible::Child, 1, &accTreeItem); + QCOMPARE(entry, 0); + + QAccessibleInterface *accTreeItem2 = 0; + entry = accTreeItem->navigate(QAccessible::Sibling, 3, &accTreeItem2); + QCOMPARE(entry, 0); + QCOMPARE(accTreeItem2->text(QAccessible::Name, 0), QLatin1String("row: 1")); + + + // test selected/focused state + QItemSelectionModel *selModel = tree->selectionModel(); + QVERIFY(selModel); + selModel->select(QItemSelection(tree->model()->index(0, 0), tree->model()->index(3, 0)), QItemSelectionModel::Select); + selModel->setCurrentIndex(tree->model()->index(1, 0), QItemSelectionModel::Current); + + for (int i = 1; i < 10 ; ++i) { + QAccessible::State expected; + if (i <= 5 && i >= 2) + expected = QAccessible::Selected; + if (i == 3) + expected |= QAccessible::Focused; + + QCOMPARE(accViewport->state(i) & (QAccessible::Focused | QAccessible::Selected), expected); + } + + // Test sanity of its navigation functions + QCOMPARE(verifyHierarchy(acc), 0); + + delete accTreeItem2; + delete accTreeItem; + delete accViewport; + delete acc; + delete w; + + + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + +void tst_QAccessibility::labelTest() +{ +#ifdef QTEST_ACCESSIBILITY + QString text = "Hello World"; + QLabel *label = new QLabel(text); + label->show(); + +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(label); +#endif + QTest::qWait(100); + + QAccessibleInterface *acc_label = QAccessible::queryAccessibleInterface(label); + QVERIFY(acc_label); + + QCOMPARE(acc_label->text(QAccessible::Name, 0), text); + + delete acc_label; + delete label; + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs accessibility support.", SkipAll); +#endif +} + + +QTEST_MAIN(tst_QAccessibility) + +#else // Q_OS_WINCE + +QTEST_NOOP_MAIN + +#endif // Q_OS_WINCE + +#include "tst_qaccessibility.moc" |