Move all usages of Relation enum values to QAccessible::relations()
[profile/ivi/qtbase.git] / tests / auto / other / qaccessibility / tst_qaccessibility.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42
43 #include <QtTest/QtTest>
44 #include <QtGui>
45 #include <QtWidgets>
46 #include <math.h>
47
48 #if defined(Q_OS_WIN) && defined(interface)
49 #   undef interface
50 #endif
51
52
53 #include "QtTest/qtestaccessible.h"
54
55 #if defined(Q_OS_WINCE)
56 extern "C" bool SystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni);
57 #define SPI_GETPLATFORMTYPE 257
58 inline bool IsValidCEPlatform() {
59     wchar_t tszPlatform[64];
60     if (SystemParametersInfo(SPI_GETPLATFORMTYPE, sizeof(tszPlatform) / sizeof(*tszPlatform), tszPlatform, 0)) {
61         QString platform = QString::fromWCharArray(tszPlatform);
62         if ((platform == QLatin1String("PocketPC")) || (platform == QLatin1String("Smartphone")))
63             return false;
64     }
65     return true;
66 }
67 #endif
68
69 typedef QSharedPointer<QAccessibleInterface> QAIPtr;
70
71 static inline bool verifyChild(QWidget *child, QAccessibleInterface *interface,
72                                int index, const QRect &domain)
73 {
74     if (!child) {
75         qWarning("tst_QAccessibility::verifyChild: null pointer to child.");
76         return false;
77     }
78
79     if (!interface) {
80         qWarning("tst_QAccessibility::verifyChild: null pointer to interface.");
81         return false;
82     }
83
84     // Verify that we get a valid QAccessibleInterface for the child.
85     QAccessibleInterface *childInterface = QAccessible::queryAccessibleInterface(child);
86     if (!childInterface) {
87         qWarning("tst_QAccessibility::verifyChild: Failed to retrieve interface for child.");
88         return false;
89     }
90
91     // QAccessibleInterface::indexOfChild():
92     // Verify that indexOfChild() returns an index equal to the index passed in
93     int indexFromIndexOfChild = interface->indexOfChild(childInterface);
94     if (indexFromIndexOfChild != index) {
95         qWarning("tst_QAccessibility::verifyChild (indexOfChild()):");
96         qWarning() << "Expected:" << index;
97         qWarning() << "Actual:  " << indexFromIndexOfChild;
98         return false;
99     }
100
101     // Navigate to child, compare its object and role with the interface from queryAccessibleInterface(child).
102     QAccessibleInterface *navigatedChildInterface = interface->child(index);
103     if (navigatedChildInterface == 0)
104         return false;
105
106     const QRect rectFromInterface = navigatedChildInterface->rect();
107     delete navigatedChildInterface;
108
109     // QAccessibleInterface::childAt():
110     // Calculate global child position and check that the interface
111     // returns the correct index for that position.
112     QPoint globalChildPos = child->mapToGlobal(QPoint(0, 0));
113     QAccessibleInterface *childAtInterface = interface->childAt(globalChildPos.x(), globalChildPos.y());
114     if (!childAtInterface) {
115         qWarning("tst_QAccessibility::verifyChild (childAt()):");
116         qWarning() << "Expected:" << childInterface;
117         qWarning() << "Actual:  no child";
118         return false;
119     }
120     if (childAtInterface->object() != childInterface->object()) {
121         qWarning("tst_QAccessibility::verifyChild (childAt()):");
122         qWarning() << "Expected:" << childInterface;
123         qWarning() << "Actual:  " << childAtInterface;
124         return false;
125     }
126     delete childInterface;
127     delete childAtInterface;
128
129     // QAccessibleInterface::rect():
130     // Calculate global child geometry and check that the interface
131     // returns a QRect which is equal to the calculated QRect.
132     const QRect expectedGlobalRect = QRect(globalChildPos, child->size());
133     if (expectedGlobalRect != rectFromInterface) {
134         qWarning("tst_QAccessibility::verifyChild (rect()):");
135         qWarning() << "Expected:" << expectedGlobalRect;
136         qWarning() << "Actual:  " << rectFromInterface;
137         return false;
138     }
139
140     // Verify that the child is within its domain.
141     if (!domain.contains(rectFromInterface)) {
142         qWarning("tst_QAccessibility::verifyChild: Child is not within its domain.");
143         return false;
144     }
145
146     return true;
147 }
148
149 static inline int indexOfChild(QAccessibleInterface *parentInterface, QWidget *childWidget)
150 {
151     if (!parentInterface || !childWidget)
152         return -1;
153     QAccessibleInterface *childInterface = QAccessible::queryAccessibleInterface(childWidget);
154     if (!childInterface)
155         return -1;
156     int index = parentInterface->indexOfChild(childInterface);
157     delete childInterface;
158     return index;
159 }
160
161 #define EXPECT(cond) \
162     do { \
163         if (!errorAt && !(cond)) { \
164             errorAt = __LINE__; \
165             qWarning("level: %d, middle: %d, role: %d (%s)", treelevel, middle, iface->role(), #cond); \
166         } \
167     } while (0)
168
169 static int verifyHierarchy(QAccessibleInterface *iface)
170 {
171     int errorAt = 0;
172     static int treelevel = 0;   // for error diagnostics
173     QAccessibleInterface *middleChild, *if2;
174     middleChild = 0;
175     ++treelevel;
176     int middle = iface->childCount()/2 + 1;
177     if (iface->childCount() >= 2) {
178         middleChild = iface->child(middle - 1);
179     }
180     for (int i = 0; i < iface->childCount() && !errorAt; ++i) {
181         if2 = iface->child(i);
182         EXPECT(if2 != 0);
183         // navigate Ancestor...
184         QAccessibleInterface *parent = if2->parent();
185         EXPECT(iface->object() == parent->object());
186         delete parent;
187
188             // navigate Sibling...
189 //            if (middleChild) {
190 //                entry = if2->navigate(QAccessible::Sibling, middle, &if3);
191 //                EXPECT(entry == 0 && if3->object() == middleChild->object());
192 //                if (entry == 0)
193 //                    delete if3;
194 //                EXPECT(iface->indexOfChild(middleChild) == middle);
195 //            }
196
197         // verify children...
198         if (!errorAt)
199             errorAt = verifyHierarchy(if2);
200         delete if2;
201     }
202     delete middleChild;
203
204     --treelevel;
205     return errorAt;
206 }
207
208 QRect childRect(QAccessibleInterface *iface, int index = 0)
209 {
210     QAccessibleInterface *child = iface->child(index);
211     QRect rect = child->rect();
212     delete child;
213     return rect;
214 }
215
216 class tst_QAccessibility : public QObject
217 {
218     Q_OBJECT
219 public:
220     tst_QAccessibility();
221     virtual ~tst_QAccessibility();
222
223 public slots:
224     void initTestCase();
225     void cleanupTestCase();
226     void init();
227     void cleanup();
228 private slots:
229     void eventTest();
230     void customWidget();
231     void deletedWidget();
232
233     void statesStructTest();
234     void navigateHierarchy();
235     void sliderTest();
236     void textAttributes();
237     void hideShowTest();
238
239     void actionTest();
240
241     void applicationTest();
242     void mainWindowTest();
243     void buttonTest();
244     void scrollBarTest();
245     void tabTest();
246     void tabWidgetTest();
247     void menuTest();
248     void spinBoxTest();
249     void doubleSpinBoxTest();
250     void textEditTest();
251     void textBrowserTest();
252     void mdiAreaTest();
253     void mdiSubWindowTest();
254     void lineEditTest();
255     void workspaceTest();
256     void dialogButtonBoxTest();
257     void dialTest();
258     void rubberBandTest();
259     void abstractScrollAreaTest();
260     void scrollAreaTest();
261
262     void listTest();
263     void treeTest();
264     void tableTest();
265
266     void calendarWidgetTest();
267     void dockWidgetTest();
268     void comboBoxTest();
269     void accessibleName();
270     void labelTest();
271     void accelerators();
272
273 protected slots:
274     void onClicked();
275 private:
276     int click_count;
277 };
278
279 const double Q_PI = 3.14159265358979323846;
280
281 QString eventName(const int ev)
282 {
283     switch(ev) {
284     case 0x0001: return "SoundPlayed";
285     case 0x0002: return "Alert";
286     case 0x0003: return "ForegroundChanged";
287     case 0x0004: return "MenuStart";
288     case 0x0005: return "MenuEnd";
289     case 0x0006: return "PopupMenuStart";
290     case 0x0007: return "PopupMenuEnd";
291     case 0x000C: return "ContextHelpStart";
292     case 0x000D: return "ContextHelpEnd";
293     case 0x000E: return "DragDropStart";
294     case 0x000F: return "DragDropEnd";
295     case 0x0010: return "DialogStart";
296     case 0x0011: return "DialogEnd";
297     case 0x0012: return "ScrollingStart";
298     case 0x0013: return "ScrollingEnd";
299     case 0x0018: return "MenuCommand";
300
301     case 0x0116: return "TableModelChanged";
302     case 0x011B: return "TextCaretMoved";
303
304     case 0x8000: return "ObjectCreated";
305     case 0x8001: return "ObjectDestroyed";
306     case 0x8002: return "ObjectShow";
307     case 0x8003: return "ObjectHide";
308     case 0x8004: return "ObjectReorder";
309     case 0x8005: return "Focus";
310     case 0x8006: return "Selection";
311     case 0x8007: return "SelectionAdd";
312     case 0x8008: return "SelectionRemove";
313     case 0x8009: return "SelectionWithin";
314     case 0x800A: return "StateChanged";
315     case 0x800B: return "LocationChanged";
316     case 0x800C: return "NameChanged";
317     case 0x800D: return "DescriptionChanged";
318     case 0x800E: return "ValueChanged";
319     case 0x800F: return "ParentChanged";
320     case 0x80A0: return "HelpChanged";
321     case 0x80B0: return "DefaultActionChanged";
322     case 0x80C0: return "AcceleratorChanged";
323     default: return "Unknown Event";
324     }
325 }
326
327 QAccessible::State state(QWidget * const widget)
328 {
329     QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget);
330     if (!iface)
331         qWarning() << "Cannot get QAccessibleInterface for widget";
332     QAccessible::State state = (iface ? iface->state() : QAccessible::State());
333     delete iface;
334     return state;
335 }
336
337 class QtTestAccessibleWidget: public QWidget
338 {
339     Q_OBJECT
340 public:
341     QtTestAccessibleWidget(QWidget *parent, const char *name): QWidget(parent)
342     {
343         setObjectName(name);
344         QPalette pal;
345         pal.setColor(backgroundRole(), Qt::black);//black is beautiful
346         setPalette(pal);
347         setFixedSize(5, 5);
348     }
349 };
350
351 class QtTestAccessibleWidgetIface: public QAccessibleWidget
352 {
353 public:
354     QtTestAccessibleWidgetIface(QtTestAccessibleWidget *w): QAccessibleWidget(w) {}
355     QString text(QAccessible::Text t) const
356     {
357         if (t == QAccessible::Help)
358             return QString::fromLatin1("Help yourself");
359         return QAccessibleWidget::text(t);
360     }
361     static QAccessibleInterface *ifaceFactory(const QString &key, QObject *o)
362     {
363         if (key == "QtTestAccessibleWidget")
364             return new QtTestAccessibleWidgetIface(static_cast<QtTestAccessibleWidget*>(o));
365         return 0;
366     }
367 };
368
369 tst_QAccessibility::tst_QAccessibility()
370 {
371     click_count = 0;
372 }
373
374 tst_QAccessibility::~tst_QAccessibility()
375 {
376 }
377
378 void tst_QAccessibility::onClicked()
379 {
380     click_count++;
381 }
382
383 void tst_QAccessibility::initTestCase()
384 {
385     QTestAccessibility::initialize();
386     QAccessible::installFactory(QtTestAccessibleWidgetIface::ifaceFactory);
387 }
388
389 void tst_QAccessibility::cleanupTestCase()
390 {
391     QTestAccessibility::cleanup();
392 }
393
394 void tst_QAccessibility::init()
395 {
396     QTestAccessibility::clearEvents();
397 }
398
399 void tst_QAccessibility::cleanup()
400 {
401     const EventList list = QTestAccessibility::events();
402     if (!list.isEmpty()) {
403         qWarning("%d accessibility event(s) were not handled in testfunction '%s':", list.count(),
404                  QString(QTest::currentTestFunction()).toAscii().constData());
405         for (int i = 0; i < list.count(); ++i)
406             qWarning(" %d: Object: %p Event: '%s' (%d) Child: %d", i + 1, list.at(i).object,
407                      eventName(list.at(i).event).toAscii().constData(), list.at(i).event, list.at(i).child);
408     }
409     QTestAccessibility::clearEvents();
410 }
411
412 void tst_QAccessibility::eventTest()
413 {
414     QPushButton* button = new QPushButton(0);
415     button->setObjectName(QString("Olaf"));
416
417     button->show();
418     QVERIFY_EVENT(button, 0, QAccessible::ObjectShow);
419     button->setFocus(Qt::MouseFocusReason);
420     QTestAccessibility::clearEvents();
421     QTest::mouseClick(button, Qt::LeftButton, 0);
422     QVERIFY_EVENT(button, 0, QAccessible::StateChanged);
423     QVERIFY_EVENT(button, 0, QAccessible::StateChanged);
424
425     button->setAccessibleName("Olaf the second");
426     QVERIFY_EVENT(button, 0, QAccessible::NameChanged);
427     button->setAccessibleDescription("This is a button labeled Olaf");
428     QVERIFY_EVENT(button, 0, QAccessible::DescriptionChanged);
429
430     button->hide();
431     QVERIFY_EVENT(button, 0, QAccessible::ObjectHide);
432
433     delete button;
434 }
435
436 void tst_QAccessibility::customWidget()
437 {
438     QtTestAccessibleWidget* widget = new QtTestAccessibleWidget(0, "Heinz");
439
440     QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget);
441     QVERIFY(iface != 0);
442     QVERIFY(iface->isValid());
443     QCOMPARE(iface->object(), (QObject*)widget);
444     QCOMPARE(iface->object()->objectName(), QString("Heinz"));
445     QCOMPARE(iface->text(QAccessible::Help), QString("Help yourself"));
446
447     delete iface;
448     delete widget;
449 }
450
451 void tst_QAccessibility::deletedWidget()
452 {
453     QtTestAccessibleWidget *widget = new QtTestAccessibleWidget(0, "Ralf");
454     QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget);
455     QVERIFY(iface != 0);
456     QVERIFY(iface->isValid());
457     QCOMPARE(iface->object(), (QObject*)widget);
458
459     delete widget;
460     widget = 0;
461     QVERIFY(!iface->isValid());
462     delete iface;
463 }
464
465 void tst_QAccessibility::statesStructTest()
466 {
467     QAccessible::State s1;
468     QVERIFY(s1.disabled == 0);
469     QVERIFY(s1.focusable == 0);
470     QVERIFY(s1.modal == 0);
471
472     QAccessible::State s2;
473     QVERIFY(s2 == s1);
474     s2.busy = true;
475     QVERIFY(!(s2 == s1));
476     s1.busy = true;
477     QVERIFY(s2 == s1);
478     s1 = QAccessible::State();
479     QVERIFY(!(s2 == s1));
480     s1 = s2;
481     QVERIFY(s2 == s1);
482     QVERIFY(s1.busy == 1);
483 }
484
485 void tst_QAccessibility::sliderTest()
486 {
487     {
488     QSlider *slider = new QSlider(0);
489     slider->setObjectName(QString("Slidy"));
490     slider->show();
491     QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(slider);
492     QVERIFY(iface != 0);
493     QVERIFY(iface->isValid());
494
495     QCOMPARE(iface->childCount(), 0);
496     QCOMPARE(iface->role(), QAccessible::Slider);
497
498     QAccessibleValueInterface *valueIface = iface->valueInterface();
499     QVERIFY(valueIface != 0);
500     QCOMPARE(valueIface->minimumValue().toInt(), slider->minimum());
501     QCOMPARE(valueIface->maximumValue().toInt(), slider->maximum());
502     slider->setValue(50);
503     QCOMPARE(valueIface->currentValue().toInt(), slider->value());
504     slider->setValue(0);
505     QCOMPARE(valueIface->currentValue().toInt(), slider->value());
506     slider->setValue(100);
507     QCOMPARE(valueIface->currentValue().toInt(), slider->value());
508     valueIface->setCurrentValue(77);
509     QCOMPARE(77, slider->value());
510
511     delete iface;
512     delete slider;
513     }
514     QTestAccessibility::clearEvents();
515 }
516
517 void tst_QAccessibility::navigateHierarchy()
518 {
519     {
520     QWidget *w = new QWidget(0);
521     w->setObjectName(QString("Hans"));
522     w->show();
523     QWidget *w1 = new QWidget(w);
524     w1->setObjectName(QString("1"));
525     w1->show();
526     QWidget *w2 = new QWidget(w);
527     w2->setObjectName(QString("2"));
528     w2->show();
529     QWidget *w3 = new QWidget(w);
530     w3->setObjectName(QString("3"));
531     w3->show();
532     QWidget *w31 = new QWidget(w3);
533     w31->setObjectName(QString("31"));
534     w31->show();
535
536     QAccessibleInterface *target = 0;
537     QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(w);
538     QVERIFY(iface != 0);
539     QVERIFY(iface->isValid());
540
541     target = iface->child(14);
542     QVERIFY(target == 0);
543     target = iface->child(-1);
544     QVERIFY(target == 0);
545     target = iface->child(0);
546     QAccessibleInterface *interfaceW1 = iface->child(0);
547     QVERIFY(target);
548     QVERIFY(target->isValid());
549     QCOMPARE(target->object(), (QObject*)w1);
550     QVERIFY(interfaceW1 != 0);
551     QVERIFY(interfaceW1->isValid());
552     QCOMPARE(interfaceW1->object(), (QObject*)w1);
553     delete interfaceW1;
554     delete iface; iface = 0;
555
556     iface = QAccessible::queryAccessibleInterface(w);
557     target = iface->child(2);
558     QVERIFY(target != 0);
559     QVERIFY(target->isValid());
560     QCOMPARE(target->object(), (QObject*)w3);
561     delete iface; iface = 0;
562
563
564     iface = target->child(1);
565     QCOMPARE(iface, (QAccessibleInterface*)0);
566     iface = target->child(0);
567     QVERIFY(iface != 0);
568     QVERIFY(iface->isValid());
569     QCOMPARE(iface->object(), (QObject*)w31);
570
571     iface = QAccessible::queryAccessibleInterface(w);
572     QAccessibleInterface *acc3 = iface->child(2);
573     target = acc3->child(0);
574     delete acc3;
575     delete iface;
576     QCOMPARE(target->object(), (QObject*)w31);
577
578     iface = target->parent();
579     QVERIFY(iface != 0);
580     QVERIFY(iface->isValid());
581     QCOMPARE(iface->object(), (QObject*)w3);
582     delete iface; iface = 0;
583     delete target; target = 0;
584
585     delete w;
586     }
587     QTestAccessibility::clearEvents();
588 }
589
590 #define QSETCOMPARE(thetypename, elements, otherelements) \
591     QCOMPARE((QSet<thetypename>() << elements), (QSet<thetypename>() << otherelements))
592
593 static QWidget *createWidgets()
594 {
595     QWidget *w = new QWidget();
596
597     QHBoxLayout *box = new QHBoxLayout(w);
598
599     int i = 0;
600     box->addWidget(new QComboBox(w));
601     box->addWidget(new QPushButton(QString::fromAscii("widget text %1").arg(i++), w));
602     box->addWidget(new QHeaderView(Qt::Vertical, w));
603     box->addWidget(new QTreeView(w));
604     box->addWidget(new QTreeWidget(w));
605     box->addWidget(new QListView(w));
606     box->addWidget(new QListWidget(w));
607     box->addWidget(new QTableView(w));
608     box->addWidget(new QTableWidget(w));
609     box->addWidget(new QCalendarWidget(w));
610     box->addWidget(new QDialogButtonBox(w));
611     box->addWidget(new QGroupBox(QString::fromAscii("widget text %1").arg(i++), w));
612     box->addWidget(new QFrame(w));
613     box->addWidget(new QLineEdit(QString::fromAscii("widget text %1").arg(i++), w));
614     box->addWidget(new QProgressBar(w));
615     box->addWidget(new QTabWidget(w));
616     box->addWidget(new QCheckBox(QString::fromAscii("widget text %1").arg(i++), w));
617     box->addWidget(new QRadioButton(QString::fromAscii("widget text %1").arg(i++), w));
618     box->addWidget(new QDial(w));
619     box->addWidget(new QScrollBar(w));
620     box->addWidget(new QSlider(w));
621     box->addWidget(new QDateTimeEdit(w));
622     box->addWidget(new QDoubleSpinBox(w));
623     box->addWidget(new QSpinBox(w));
624     box->addWidget(new QLabel(QString::fromAscii("widget text %1").arg(i++), w));
625     box->addWidget(new QLCDNumber(w));
626     box->addWidget(new QStackedWidget(w));
627     box->addWidget(new QToolBox(w));
628     box->addWidget(new QLabel(QString::fromAscii("widget text %1").arg(i++), w));
629     box->addWidget(new QTextEdit(QString::fromAscii("widget text %1").arg(i++), w));
630
631     /* Not in the list
632      * QAbstractItemView, QGraphicsView, QScrollArea,
633      * QToolButton, QDockWidget, QFocusFrame, QMainWindow, QMenu, QMenuBar, QSizeGrip, QSplashScreen, QSplitterHandle,
634      * QStatusBar, QSvgWidget, QTabBar, QToolBar, QWorkspace, QSplitter
635      */
636     return w;
637 }
638
639 void tst_QAccessibility::accessibleName()
640 {
641     QWidget *toplevel = createWidgets();
642     toplevel->show();
643 #if defined(Q_OS_UNIX)
644     QCoreApplication::processEvents();
645     QTest::qWait(100);
646 #endif
647     QLayout *lout = toplevel->layout();
648     for (int i = 0; i < lout->count(); i++) {
649         QLayoutItem *item = lout->itemAt(i);
650         QWidget *child = item->widget();
651
652         QString name = tr("Widget Name %1").arg(i);
653         child->setAccessibleName(name);
654         QAccessibleInterface *acc = QAccessible::queryAccessibleInterface(child);
655         QCOMPARE(acc->text(QAccessible::Name), name);
656
657         QString desc = tr("Widget Description %1").arg(i);
658         child->setAccessibleDescription(desc);
659         QCOMPARE(acc->text(QAccessible::Description), desc);
660
661     }
662
663     delete toplevel;
664     QTestAccessibility::clearEvents();
665 }
666
667 void tst_QAccessibility::textAttributes()
668 {
669     QTextEdit textEdit;
670     int startOffset;
671     int endOffset;
672     QString attributes;
673     QString text("<html><head></head><body>"
674                  "Hello, <b>this</b> is an <i><b>example</b> text</i>."
675                  "<span style=\"font-family: monospace\">Multiple fonts are used.</span>"
676                  "Multiple <span style=\"font-size: 8pt\">text sizes</span> are used."
677                  "Let's give some color to <span style=\"color:#f0f1f2; background-color:#14f01e\">Qt</span>."
678                  "</body></html>");
679
680     textEdit.setText(text);
681     QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&textEdit);
682
683     QAccessibleTextInterface *textInterface=interface->textInterface();
684
685     QVERIFY(textInterface);
686     QCOMPARE(textInterface->characterCount(), 112);
687
688     attributes = textInterface->attributes(10, &startOffset, &endOffset);
689     QCOMPARE(startOffset, 7);
690     QCOMPARE(endOffset, 11);
691     attributes.prepend(';');
692     QVERIFY(attributes.contains(QLatin1String(";font-weight:bold;")));
693
694     attributes = textInterface->attributes(18, &startOffset, &endOffset);
695     QCOMPARE(startOffset, 18);
696     QCOMPARE(endOffset, 25);
697     attributes.prepend(';');
698     QVERIFY(attributes.contains(QLatin1String(";font-weight:bold;")));
699     QVERIFY(attributes.contains(QLatin1String(";font-style:italic;")));
700
701     attributes = textInterface->attributes(34, &startOffset, &endOffset);
702     QCOMPARE(startOffset, 31);
703     QCOMPARE(endOffset, 55);
704     attributes.prepend(';');
705     QVERIFY(attributes.contains(QLatin1String(";font-family:\"monospace\";")));
706
707     attributes = textInterface->attributes(65, &startOffset, &endOffset);
708     QCOMPARE(startOffset, 64);
709     QCOMPARE(endOffset, 74);
710     attributes.prepend(';');
711     QVERIFY(attributes.contains(QLatin1String(";font-size:8pt;")));
712
713     attributes = textInterface->attributes(110, &startOffset, &endOffset);
714     QCOMPARE(startOffset, 109);
715     QCOMPARE(endOffset, 111);
716     attributes.prepend(';');
717     QVERIFY(attributes.contains(QLatin1String(";background-color:rgb(20,240,30);")));
718     QVERIFY(attributes.contains(QLatin1String(";color:rgb(240,241,242);")));
719 }
720
721 void tst_QAccessibility::hideShowTest()
722 {
723     QWidget * const window = new QWidget();
724     QWidget * const child = new QWidget(window);
725
726     QVERIFY(state(window).invisible);
727     QVERIFY(state(child).invisible);
728
729     QTestAccessibility::clearEvents();
730
731     // show() and veryfy that both window and child are not invisible and get ObjectShow events.
732     window->show();
733     QVERIFY(!state(window).invisible);
734     QVERIFY(!state(child).invisible);
735     QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(window, 0, QAccessible::ObjectShow)));
736     QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(child, 0, QAccessible::ObjectShow)));
737     QTestAccessibility::clearEvents();
738
739     // hide() and veryfy that both window and child are invisible and get ObjectHide events.
740     window->hide();
741     QVERIFY(state(window).invisible);
742     QVERIFY(state(child).invisible);
743     QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(window, 0, QAccessible::ObjectHide)));
744     QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(child, 0, QAccessible::ObjectHide)));
745     QTestAccessibility::clearEvents();
746
747     delete window;
748     QTestAccessibility::clearEvents();
749 }
750
751
752 void tst_QAccessibility::actionTest()
753 {
754     {
755     QCOMPARE(QAccessibleActionInterface::pressAction(), QString(QStringLiteral("Press")));
756
757     QWidget *widget = new QWidget;
758     widget->setFocusPolicy(Qt::NoFocus);
759     widget->show();
760
761     QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(widget);
762     QVERIFY(interface);
763     QVERIFY(interface->isValid());
764     QAccessibleActionInterface *actions = interface->actionInterface();
765     QVERIFY(actions);
766
767     // no actions by default, except when focusable
768     QCOMPARE(actions->actionNames(), QStringList());
769     widget->setFocusPolicy(Qt::StrongFocus);
770     QCOMPARE(actions->actionNames(), QStringList(QAccessibleActionInterface::setFocusAction()));
771
772     delete interface;
773     delete widget;
774     }
775     QTestAccessibility::clearEvents();
776
777     {
778     QPushButton *button = new QPushButton;
779     button->show();
780     button->clearFocus();
781     QCOMPARE(button->hasFocus(), false);
782     QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(button);
783     QAccessibleActionInterface *actions = interface->actionInterface();
784     QVERIFY(actions);
785
786     // Make sure the "primary action" press comes first!
787     QCOMPARE(actions->actionNames(), QStringList() << QAccessibleActionInterface::pressAction() << QAccessibleActionInterface::setFocusAction());
788
789     actions->doAction(QAccessibleActionInterface::setFocusAction());
790     QTest::qWait(500);
791     QCOMPARE(button->hasFocus(), true);
792
793     connect(button, SIGNAL(clicked()), this, SLOT(onClicked()));
794     QCOMPARE(click_count, 0);
795     actions->doAction(QAccessibleActionInterface::pressAction());
796     QTest::qWait(500);
797     QCOMPARE(click_count, 1);
798
799     delete interface;
800     delete button;
801     }
802     QTestAccessibility::clearEvents();
803 }
804
805 void tst_QAccessibility::applicationTest()
806 {
807     QLatin1String name = QLatin1String("My Name");
808     qApp->setApplicationName(name);
809     QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(qApp);
810     QCOMPARE(interface->text(QAccessible::Name), name);
811     QCOMPARE(interface->role(), QAccessible::Application);
812     delete interface;
813 }
814
815 void tst_QAccessibility::mainWindowTest()
816 {
817     QMainWindow *mw = new QMainWindow;
818     mw->resize(300, 200);
819     mw->show(); // triggers layout
820
821     QLatin1String name = QLatin1String("I am the main window");
822     mw->setWindowTitle(name);
823     QTest::qWaitForWindowShown(mw);
824     QVERIFY_EVENT(mw, 0, QAccessible::ObjectShow);
825
826     QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(mw);
827     QCOMPARE(interface->text(QAccessible::Name), name);
828     QCOMPARE(interface->role(), QAccessible::Window);
829     delete interface;
830     delete mw;
831     QTestAccessibility::clearEvents();
832 }
833
834 class CounterButton : public QPushButton {
835     Q_OBJECT
836 public:
837     CounterButton(const QString& name, QWidget* parent)
838         : QPushButton(name, parent), clickCount(0)
839     {
840         connect(this, SIGNAL(clicked(bool)), SLOT(incClickCount()));
841     }
842     int clickCount;
843 public Q_SLOTS:
844     void incClickCount() {
845         ++clickCount;
846     }
847 };
848
849 static QAccessibleInterface *relatedInterface(QAccessibleInterface *iface, QAccessible::RelationFlag flag)
850 {
851     typedef QPair<QAccessibleInterface *, QAccessible::Relation> RelationPair;
852     QVector<RelationPair> rels = iface->relations(flag);
853
854     for (int i = 1; i < rels.count(); ++i)
855         delete rels.at(i).first;
856
857     return rels.value(0).first;
858 }
859
860 void tst_QAccessibility::buttonTest()
861 {
862     QWidget window;
863     window.setLayout(new QVBoxLayout);
864
865     // Standard push button
866     CounterButton pushButton("Ok", &window);
867
868     // toggle button
869     QPushButton toggleButton("Toggle", &window);
870     toggleButton.setCheckable(true);
871
872     // standard checkbox
873     QCheckBox checkBox("Check me!", &window);
874
875     // tristate checkbox
876     QCheckBox tristate("Tristate!", &window);
877     tristate.setTristate(true);
878
879     // radiobutton
880     QRadioButton radio("Radio me!", &window);
881
882     // standard toolbutton
883     QToolButton toolbutton(&window);
884     toolbutton.setText("Tool");
885     toolbutton.setMinimumSize(20,20);
886
887     // standard toolbutton
888     QToolButton toggletool(&window);
889     toggletool.setCheckable(true);
890     toggletool.setText("Toggle");
891     toggletool.setMinimumSize(20,20);
892
893     // test Controller/Controlled relations
894     {
895     QCheckBox toggler("Toggle me!", &window);
896     bool ok = connect(&pushButton, SIGNAL(clicked()), &toggler, SLOT(toggle()));
897     QCOMPARE(ok, true);
898     QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&toggler);
899     QVERIFY(iface);
900     QCOMPARE(iface->role(), QAccessible::CheckBox);
901     QAccessibleInterface *buttonIFace = relatedInterface(iface, QAccessible::Controller);
902     QVERIFY(buttonIFace);
903     QCOMPARE(buttonIFace->role(), QAccessible::Button);
904     QCOMPARE(buttonIFace->object(), &pushButton);
905     delete buttonIFace;
906     delete iface;
907
908     buttonIFace = QAccessible::queryAccessibleInterface(&pushButton);
909     QVERIFY(buttonIFace);
910     QCOMPARE(buttonIFace->role(), QAccessible::Button);
911     iface = relatedInterface(buttonIFace, QAccessible::Controlled);
912     QVERIFY(iface);
913     QCOMPARE(iface->object(), &toggler);
914
915     }
916
917     // test push button
918     QAccessibleInterface* interface = QAccessible::queryAccessibleInterface(&pushButton);
919     QAccessibleActionInterface* actionInterface = interface->actionInterface();
920     QVERIFY(actionInterface != 0);
921     QCOMPARE(interface->role(), QAccessible::PushButton);
922
923     // buttons only have a click action
924     QCOMPARE(actionInterface->actionNames().size(), 2);
925     QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::pressAction() << QAccessibleActionInterface::setFocusAction());
926     QCOMPARE(pushButton.clickCount, 0);
927     actionInterface->doAction(QAccessibleActionInterface::pressAction());
928     QTest::qWait(500);
929     QCOMPARE(pushButton.clickCount, 1);
930     delete interface;
931
932     // test toggle button
933     interface = QAccessible::queryAccessibleInterface(&toggleButton);
934     actionInterface = interface->actionInterface();
935     QCOMPARE(interface->role(), QAccessible::CheckBox);
936     QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::checkAction() << QAccessibleActionInterface::setFocusAction());
937     QCOMPARE(actionInterface->localizedActionDescription(QAccessibleActionInterface::checkAction()), QString("Checks the checkbox"));
938     QVERIFY(!toggleButton.isChecked());
939     QVERIFY(!interface->state().checked);
940     actionInterface->doAction(QAccessibleActionInterface::checkAction());
941     QTest::qWait(500);
942     QVERIFY(toggleButton.isChecked());
943     QCOMPARE(actionInterface->actionNames().at(0), QAccessibleActionInterface::uncheckAction());
944     QVERIFY(interface->state().checked);
945     delete interface;
946
947     {
948     // test menu push button
949     QAction *foo = new QAction("Foo", 0);
950     foo->setShortcut(QKeySequence("Ctrl+F"));
951     QMenu *menu = new QMenu();
952     menu->addAction(foo);
953     QPushButton menuButton;
954     menuButton.setMenu(menu);
955     menuButton.show();
956     QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&menuButton);
957     QCOMPARE(interface->role(), QAccessible::ButtonMenu);
958     QVERIFY(interface->state().hasPopup);
959     QCOMPARE(interface->actionInterface()->actionNames(), QStringList() << QAccessibleActionInterface::showMenuAction() << QAccessibleActionInterface::setFocusAction());
960     // showing the menu enters a new event loop...
961 //    interface->actionInterface()->doAction(QAccessibleActionInterface::showMenuAction());
962 //    QTest::qWait(500);
963     delete interface;
964     delete menu;
965     }
966
967     // test check box
968     interface = QAccessible::queryAccessibleInterface(&checkBox);
969     actionInterface = interface->actionInterface();
970     QCOMPARE(interface->role(), QAccessible::CheckBox);
971     QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::checkAction() << QAccessibleActionInterface::setFocusAction());
972     QVERIFY(!interface->state().checked);
973     actionInterface->doAction(QAccessibleActionInterface::checkAction());
974     QTest::qWait(500);
975     QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::uncheckAction() << QAccessibleActionInterface::setFocusAction());
976     QVERIFY(interface->state().checked);
977     QVERIFY(checkBox.isChecked());
978     delete interface;
979
980     // test radiobutton
981     interface = QAccessible::queryAccessibleInterface(&radio);
982     actionInterface = interface->actionInterface();
983     QCOMPARE(interface->role(), QAccessible::RadioButton);
984     QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::checkAction() << QAccessibleActionInterface::setFocusAction());
985     QVERIFY(!interface->state().checked);
986     actionInterface->doAction(QAccessibleActionInterface::checkAction());
987     QTest::qWait(500);
988     QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::checkAction() << QAccessibleActionInterface::setFocusAction());
989     QVERIFY(interface->state().checked);
990     QVERIFY(checkBox.isChecked());
991     delete interface;
992
993 //    // test standard toolbutton
994 //    QVERIFY(QAccessible::queryAccessibleInterface(&toolbutton, &test));
995 //    QCOMPARE(test->role(), QAccessible::PushButton);
996 //    QCOMPARE(test->defaultAction(0), QAccessible::Press);
997 //    QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Press"));
998 //    QCOMPARE(test->state(), (int)QAccessible::Normal);
999 //    test->release();
1000
1001 //    // toggle tool button
1002 //    QVERIFY(QAccessible::queryAccessibleInterface(&toggletool, &test));
1003 //    QCOMPARE(test->role(), QAccessible::CheckBox);
1004 //    QCOMPARE(test->defaultAction(0), QAccessible::Press);
1005 //    QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check"));
1006 //    QCOMPARE(test->state(), (int)QAccessible::Normal);
1007 //    QVERIFY(test->doAction(QAccessible::Press, 0));
1008 //    QTest::qWait(500);
1009 //    QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Uncheck"));
1010 //    QCOMPARE(test->state(), (int)QAccessible::Checked);
1011 //    test->release();
1012
1013 //    // test menu toolbutton
1014 //    QVERIFY(QAccessible::queryAccessibleInterface(&menuToolButton, &test));
1015 //    QCOMPARE(test->role(), QAccessible::ButtonMenu);
1016 //    QCOMPARE(test->defaultAction(0), 1);
1017 //    QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Open"));
1018 //    QCOMPARE(test->state(), (int)QAccessible::HasPopup);
1019 //    QCOMPARE(test->actionCount(0), 1);
1020 //    QCOMPARE(test->actionText(QAccessible::Press, QAccessible::Name, 0), QString("Press"));
1021 //    test->release();
1022
1023 //    // test split menu toolbutton
1024 //    QVERIFY(QAccessible::queryAccessibleInterface(&splitToolButton, &test));
1025 //    QCOMPARE(test->childCount(), 2);
1026 //    QCOMPARE(test->role(), QAccessible::ButtonDropDown);
1027 //    QCOMPARE(test->role(1), QAccessible::PushButton);
1028 //    QCOMPARE(test->role(2), QAccessible::ButtonMenu);
1029 //    QCOMPARE(test->defaultAction(0), QAccessible::Press);
1030 //    QCOMPARE(test->defaultAction(1), QAccessible::Press);
1031 //    QCOMPARE(test->defaultAction(2), QAccessible::Press);
1032 //    QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Press"));
1033 //    QCOMPARE(test->state(), (int)QAccessible::HasPopup);
1034 //    QCOMPARE(test->actionCount(0), 1);
1035 //    QCOMPARE(test->actionText(1, QAccessible::Name, 0), QString("Open"));
1036 //    QCOMPARE(test->actionText(test->defaultAction(1), QAccessible::Name, 1), QString("Press"));
1037 //    QCOMPARE(test->state(1), (int)QAccessible::Normal);
1038 //    QCOMPARE(test->actionText(test->defaultAction(2), QAccessible::Name, 2), QString("Open"));
1039 //    QCOMPARE(test->state(2), (int)QAccessible::HasPopup);
1040 //    test->release();
1041
1042     QTestAccessibility::clearEvents();
1043 }
1044
1045 void tst_QAccessibility::scrollBarTest()
1046 {
1047     QScrollBar *scrollBar  = new QScrollBar(Qt::Horizontal);
1048     QAccessibleInterface * const scrollBarInterface = QAccessible::queryAccessibleInterface(scrollBar);
1049     QVERIFY(scrollBarInterface);
1050     QVERIFY(scrollBarInterface->state().invisible);
1051     scrollBar->resize(200, 50);
1052     scrollBar->show();
1053     QVERIFY(!scrollBarInterface->state().invisible);
1054     QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(scrollBar, 0, QAccessible::ObjectShow)));
1055     QTestAccessibility::clearEvents();
1056
1057     scrollBar->hide();
1058     QVERIFY(scrollBarInterface->state().invisible);
1059     QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(scrollBar, 0, QAccessible::ObjectHide)));
1060     QTestAccessibility::clearEvents();
1061
1062     // Test that the left/right subcontrols are set to unavailable when the scrollBar is at the minimum/maximum.
1063     scrollBar->show();
1064     scrollBar->setMinimum(11);
1065     scrollBar->setMaximum(111);
1066
1067     QAccessibleValueInterface *valueIface = scrollBarInterface->valueInterface();
1068     QVERIFY(valueIface != 0);
1069     QCOMPARE(valueIface->minimumValue().toInt(), scrollBar->minimum());
1070     QCOMPARE(valueIface->maximumValue().toInt(), scrollBar->maximum());
1071     scrollBar->setValue(50);
1072     QCOMPARE(valueIface->currentValue().toInt(), scrollBar->value());
1073     scrollBar->setValue(0);
1074     QCOMPARE(valueIface->currentValue().toInt(), scrollBar->value());
1075     scrollBar->setValue(100);
1076     QCOMPARE(valueIface->currentValue().toInt(), scrollBar->value());
1077     valueIface->setCurrentValue(77);
1078     QCOMPARE(77, scrollBar->value());
1079
1080     const QRect scrollBarRect = scrollBarInterface->rect();
1081     QVERIFY(scrollBarRect.isValid());
1082
1083     delete scrollBarInterface;
1084     delete scrollBar;
1085
1086     QTestAccessibility::clearEvents();
1087 }
1088
1089 void tst_QAccessibility::tabTest()
1090 {
1091     QTabBar *tabBar = new QTabBar();
1092     tabBar->show();
1093
1094     QAccessibleInterface * const interface = QAccessible::queryAccessibleInterface(tabBar);
1095     QVERIFY(interface);
1096     QCOMPARE(interface->childCount(), 2);
1097
1098     // Test that the Invisible bit for the navigation buttons gets set
1099     // and cleared correctly.
1100     QAccessibleInterface *leftButton = interface->child(0);
1101     QCOMPARE(leftButton->role(), QAccessible::PushButton);
1102     QVERIFY(leftButton->state().invisible);
1103     delete leftButton;
1104
1105     const int lots = 5;
1106     for (int i = 0; i < lots; ++i)
1107         tabBar->addTab("Foo");
1108
1109     QAccessibleInterface *child1 = interface->child(0);
1110     QAccessibleInterface *child2 = interface->child(1);
1111     QVERIFY(child1);
1112     QCOMPARE(child1->role(), QAccessible::PageTab);
1113     QVERIFY(child2);
1114     QCOMPARE(child2->role(), QAccessible::PageTab);
1115
1116     QVERIFY((child1->state().invisible) == false);
1117     tabBar->hide();
1118
1119     QCoreApplication::processEvents();
1120     QTest::qWait(100);
1121
1122     QVERIFY(child1->state().invisible);
1123
1124     tabBar->show();
1125     tabBar->setCurrentIndex(0);
1126
1127     // Test that sending a focus action to a tab does not select it.
1128 //    child2->doAction(QAccessible::Focus, 2, QVariantList());
1129     QCOMPARE(tabBar->currentIndex(), 0);
1130
1131     // Test that sending a press action to a tab selects it.
1132     QVERIFY(child2->actionInterface());
1133     QCOMPARE(child2->actionInterface()->actionNames(), QStringList() << QAccessibleActionInterface::pressAction());
1134     QCOMPARE(tabBar->currentIndex(), 0);
1135     child2->actionInterface()->doAction(QAccessibleActionInterface::pressAction());
1136     QCOMPARE(tabBar->currentIndex(), 1);
1137
1138     delete tabBar;
1139     delete interface;
1140     delete child1;
1141     delete child2;
1142     QTestAccessibility::clearEvents();
1143 }
1144
1145 void tst_QAccessibility::tabWidgetTest()
1146 {
1147     QTabWidget *tabWidget = new QTabWidget();
1148     tabWidget->show();
1149
1150     // the interface for the tab is just a container for tabbar and stacked widget
1151     QAccessibleInterface * const interface = QAccessible::queryAccessibleInterface(tabWidget);
1152     QVERIFY(interface);
1153     QCOMPARE(interface->childCount(), 2);
1154     QCOMPARE(interface->role(), QAccessible::Client);
1155
1156     // Create pages, check navigation
1157     QLabel *label1 = new QLabel("Page 1", tabWidget);
1158     tabWidget->addTab(label1, "Tab 1");
1159     QLabel *label2 = new QLabel("Page 2", tabWidget);
1160     tabWidget->addTab(label2, "Tab 2");
1161
1162     QCOMPARE(interface->childCount(), 2);
1163
1164     QAccessibleInterface* tabBarInterface = 0;
1165     // there is no special logic to sort the children, so the contents will be 1, the tab bar 2
1166     tabBarInterface = interface->child(1);
1167     QVERIFY(tabBarInterface);
1168     QCOMPARE(tabBarInterface->childCount(), 4);
1169     QCOMPARE(tabBarInterface->role(), QAccessible::PageTabList);
1170
1171     QAccessibleInterface* tabButton1Interface = tabBarInterface->child(0);
1172     QVERIFY(tabButton1Interface);
1173     QCOMPARE(tabButton1Interface->role(), QAccessible::PageTab);
1174     QCOMPARE(tabButton1Interface->text(QAccessible::Name), QLatin1String("Tab 1"));
1175
1176     QAccessibleInterface* tabButton2Interface = tabBarInterface->child(1);
1177     QVERIFY(tabButton1Interface);
1178     QCOMPARE(tabButton2Interface->role(), QAccessible::PageTab);
1179     QCOMPARE(tabButton2Interface->text(QAccessible::Name), QLatin1String("Tab 2"));
1180
1181     QAccessibleInterface* tabButtonLeft = tabBarInterface->child(2);
1182     QVERIFY(tabButtonLeft);
1183     QCOMPARE(tabButtonLeft->role(), QAccessible::PushButton);
1184     QCOMPARE(tabButtonLeft->text(QAccessible::Name), QLatin1String("Scroll Left"));
1185
1186     QAccessibleInterface* tabButtonRight = tabBarInterface->child(3);
1187     QVERIFY(tabButtonRight);
1188     QCOMPARE(tabButtonRight->role(), QAccessible::PushButton);
1189     QCOMPARE(tabButtonRight->text(QAccessible::Name), QLatin1String("Scroll Right"));
1190     delete tabButton1Interface;
1191     delete tabButton2Interface;
1192     delete tabButtonLeft;
1193     delete tabButtonRight;
1194
1195     QAccessibleInterface* stackWidgetInterface = interface->child(0);
1196     QVERIFY(stackWidgetInterface);
1197     QCOMPARE(stackWidgetInterface->childCount(), 2);
1198     QCOMPARE(stackWidgetInterface->role(), QAccessible::LayeredPane);
1199
1200     QAccessibleInterface* stackChild1Interface = stackWidgetInterface->child(0);
1201     QVERIFY(stackChild1Interface);
1202 #ifndef Q_CC_INTEL
1203     QCOMPARE(stackChild1Interface->childCount(), 0);
1204 #endif
1205     QCOMPARE(stackChild1Interface->role(), QAccessible::StaticText);
1206     QCOMPARE(stackChild1Interface->text(QAccessible::Name), QLatin1String("Page 1"));
1207     QCOMPARE(label1, stackChild1Interface->object());
1208
1209     // Navigation in stack widgets should be consistent
1210     QAccessibleInterface* parent = stackChild1Interface->parent();
1211     QVERIFY(parent);
1212 #ifndef Q_CC_INTEL
1213     QCOMPARE(parent->childCount(), 2);
1214 #endif
1215     QCOMPARE(parent->role(), QAccessible::LayeredPane);
1216     delete parent;
1217
1218     QAccessibleInterface* stackChild2Interface = stackWidgetInterface->child(1);
1219     QVERIFY(stackChild2Interface);
1220     QCOMPARE(stackChild2Interface->childCount(), 0);
1221     QCOMPARE(stackChild2Interface->role(), QAccessible::StaticText);
1222     QCOMPARE(label2, stackChild2Interface->object());
1223     QCOMPARE(label2->text(), stackChild2Interface->text(QAccessible::Name));
1224
1225     parent = stackChild2Interface->parent();
1226     QVERIFY(parent);
1227 #ifndef Q_CC_INTEL
1228     QCOMPARE(parent->childCount(), 2);
1229 #endif
1230     QCOMPARE(parent->role(), QAccessible::LayeredPane);
1231     delete parent;
1232
1233     delete tabBarInterface;
1234     delete stackChild1Interface;
1235     delete stackChild2Interface;
1236     delete stackWidgetInterface;
1237     delete interface;
1238     delete tabWidget;
1239     QTestAccessibility::clearEvents();
1240 }
1241
1242 void tst_QAccessibility::menuTest()
1243 {
1244     {
1245     QMainWindow mw;
1246     mw.resize(300, 200);
1247     QMenu *file = mw.menuBar()->addMenu("&File");
1248     QMenu *fileNew = file->addMenu("&New...");
1249     fileNew->menuAction()->setShortcut(tr("Ctrl+N"));
1250     fileNew->addAction("Text file");
1251     fileNew->addAction("Image file");
1252     file->addAction("&Open")->setShortcut(tr("Ctrl+O"));
1253     file->addAction("&Save")->setShortcut(tr("Ctrl+S"));
1254     file->addSeparator();
1255     file->addAction("E&xit")->setShortcut(tr("Alt+F4"));
1256
1257     QMenu *edit = mw.menuBar()->addMenu("&Edit");
1258     edit->addAction("&Undo")->setShortcut(tr("Ctrl+Z"));
1259     edit->addAction("&Redo")->setShortcut(tr("Ctrl+Y"));
1260     edit->addSeparator();
1261     edit->addAction("Cu&t")->setShortcut(tr("Ctrl+X"));
1262     edit->addAction("&Copy")->setShortcut(tr("Ctrl+C"));
1263     edit->addAction("&Paste")->setShortcut(tr("Ctrl+V"));
1264     edit->addAction("&Delete")->setShortcut(tr("Del"));
1265     edit->addSeparator();
1266     edit->addAction("Pr&operties");
1267
1268     mw.menuBar()->addSeparator();
1269
1270     QMenu *help = mw.menuBar()->addMenu("&Help");
1271     help->addAction("&Contents");
1272     help->addAction("&About");
1273
1274     mw.menuBar()->addAction("Action!");
1275
1276     mw.show(); // triggers layout
1277     QTest::qWait(100);
1278
1279     QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(mw.menuBar());
1280     QCOMPARE(verifyHierarchy(interface),  0);
1281
1282     QVERIFY(interface);
1283     QCOMPARE(interface->childCount(), 5);
1284     QCOMPARE(interface->role(), QAccessible::MenuBar);
1285
1286     QAccessibleInterface *iFile = interface->child(0);
1287     QAccessibleInterface *iEdit = interface->child(1);
1288     QAccessibleInterface *iSeparator = interface->child(2);
1289     QAccessibleInterface *iHelp = interface->child(3);
1290     QAccessibleInterface *iAction = interface->child(4);
1291
1292     QCOMPARE(iFile->role(), QAccessible::MenuItem);
1293     QCOMPARE(iEdit->role(), QAccessible::MenuItem);
1294     QCOMPARE(iSeparator->role(), QAccessible::Separator);
1295     QCOMPARE(iHelp->role(), QAccessible::MenuItem);
1296     QCOMPARE(iAction->role(), QAccessible::MenuItem);
1297 #ifndef Q_OS_MAC
1298 #ifdef Q_OS_WINCE
1299     if (!IsValidCEPlatform())
1300         QSKIP("Tests do not work on Mobile platforms due to native menus");
1301 #endif
1302     QCOMPARE(mw.mapFromGlobal(interface->rect().topLeft()), mw.menuBar()->geometry().topLeft());
1303     QCOMPARE(interface->rect().size(), mw.menuBar()->size());
1304
1305     QVERIFY(interface->rect().contains(iFile->rect()));
1306     QVERIFY(interface->rect().contains(iEdit->rect()));
1307     // QVERIFY(interface->rect().contains(childSeparator->rect())); //separator might be invisible
1308     QVERIFY(interface->rect().contains(iHelp->rect()));
1309     QVERIFY(interface->rect().contains(iAction->rect()));
1310 #endif
1311
1312     QCOMPARE(iFile->text(QAccessible::Name), QString("File"));
1313     QCOMPARE(iEdit->text(QAccessible::Name), QString("Edit"));
1314     QCOMPARE(iSeparator->text(QAccessible::Name), QString());
1315     QCOMPARE(iHelp->text(QAccessible::Name), QString("Help"));
1316     QCOMPARE(iAction->text(QAccessible::Name), QString("Action!"));
1317
1318 // TODO: Currently not working, task to fix is #100019.
1319 #ifndef Q_OS_MAC
1320     QCOMPARE(iFile->text(QAccessible::Accelerator), tr("Alt+F"));
1321     QCOMPARE(iEdit->text(QAccessible::Accelerator), tr("Alt+E"));
1322     QCOMPARE(iSeparator->text(QAccessible::Accelerator), QString());
1323     QCOMPARE(iHelp->text(QAccessible::Accelerator), tr("Alt+H"));
1324     QCOMPARE(iAction->text(QAccessible::Accelerator), QString());
1325 #endif
1326
1327     QVERIFY(iFile->actionInterface());
1328
1329     QCOMPARE(iFile->actionInterface()->actionNames(), QStringList() << QAccessibleActionInterface::showMenuAction());
1330     QCOMPARE(iSeparator->actionInterface()->actionNames(), QStringList());
1331     QCOMPARE(iHelp->actionInterface()->actionNames(), QStringList() << QAccessibleActionInterface::showMenuAction());
1332     QCOMPARE(iAction->actionInterface()->actionNames(), QStringList() << QAccessibleActionInterface::pressAction());
1333
1334     bool menuFade = qApp->isEffectEnabled(Qt::UI_FadeMenu);
1335     int menuFadeDelay = 300;
1336     iFile->actionInterface()->doAction(QAccessibleActionInterface::showMenuAction());
1337     if(menuFade)
1338         QTest::qWait(menuFadeDelay);
1339     QVERIFY(file->isVisible() && !edit->isVisible() && !help->isVisible());
1340     iEdit->actionInterface()->doAction(QAccessibleActionInterface::showMenuAction());
1341     if(menuFade)
1342         QTest::qWait(menuFadeDelay);
1343     QVERIFY(!file->isVisible() && edit->isVisible() && !help->isVisible());
1344     iHelp->actionInterface()->doAction(QAccessibleActionInterface::showMenuAction());
1345     if(menuFade)
1346         QTest::qWait(menuFadeDelay);
1347     QVERIFY(!file->isVisible() && !edit->isVisible() && help->isVisible());
1348     iAction->actionInterface()->doAction(QAccessibleActionInterface::showMenuAction());
1349     if(menuFade)
1350         QTest::qWait(menuFadeDelay);
1351     QVERIFY(!file->isVisible() && !edit->isVisible() && !help->isVisible());
1352
1353     QVERIFY(interface->actionInterface());
1354     QCOMPARE(interface->actionInterface()->actionNames(), QStringList());
1355     delete interface;
1356     interface = QAccessible::queryAccessibleInterface(file);
1357     QCOMPARE(interface->childCount(), 5);
1358     QCOMPARE(interface->role(), QAccessible::PopupMenu);
1359
1360     QAccessibleInterface *iFileNew = interface->child(0);
1361     QAccessibleInterface *iFileOpen = interface->child(1);
1362     QAccessibleInterface *iFileSave = interface->child(2);
1363     QAccessibleInterface *iFileSeparator = interface->child(3);
1364     QAccessibleInterface *iFileExit = interface->child(4);
1365
1366     QCOMPARE(iFileNew->role(), QAccessible::MenuItem);
1367     QCOMPARE(iFileOpen->role(), QAccessible::MenuItem);
1368     QCOMPARE(iFileSave->role(), QAccessible::MenuItem);
1369     QCOMPARE(iFileSeparator->role(), QAccessible::Separator);
1370     QCOMPARE(iFileExit->role(), QAccessible::MenuItem);
1371     QCOMPARE(iFileNew->actionInterface()->actionNames(), QStringList() << QAccessibleActionInterface::showMenuAction());
1372     QCOMPARE(iFileOpen->actionInterface()->actionNames(), QStringList() << QAccessibleActionInterface::pressAction());
1373     QCOMPARE(iFileSave->actionInterface()->actionNames(), QStringList() << QAccessibleActionInterface::pressAction());
1374     QCOMPARE(iFileSeparator->actionInterface()->actionNames(), QStringList());
1375     QCOMPARE(iFileExit->actionInterface()->actionNames(), QStringList() << QAccessibleActionInterface::pressAction());
1376
1377     QAccessibleInterface *iface = 0;
1378     QAccessibleInterface *iface2 = 0;
1379
1380     // traverse siblings with navigate(Sibling, ...)
1381     iface = interface->child(0);
1382     QVERIFY(iface);
1383     QCOMPARE(iface->role(), QAccessible::MenuItem);
1384
1385     QAccessible::Role fileRoles[5] = {
1386         QAccessible::MenuItem,
1387         QAccessible::MenuItem,
1388         QAccessible::MenuItem,
1389         QAccessible::Separator,
1390         QAccessible::MenuItem
1391     };
1392     for (int child = 0; child < 5; ++child) {
1393         iface2 = interface->child(child);
1394         QVERIFY(iface2);
1395         QCOMPARE(iface2->role(), fileRoles[child]);
1396         delete iface2;
1397     }
1398     delete iface;
1399
1400     // "New" item
1401     iface = interface->child(0);
1402     QVERIFY(iface);
1403     QCOMPARE(iface->role(), QAccessible::MenuItem);
1404
1405     // "New" menu
1406     iface2 = iface->child(0);
1407     delete iface;
1408     iface = iface2;
1409     QVERIFY(iface);
1410     QCOMPARE(iface->role(), QAccessible::PopupMenu);
1411
1412     // "Text file" menu item
1413     iface2 = iface->child(0);
1414     delete iface;
1415     iface = iface2;
1416     QVERIFY(iface);
1417     QCOMPARE(iface->role(), QAccessible::MenuItem);
1418
1419     delete iface;
1420
1421     // move mouse pointer away, since that might influence the
1422     // subsequent tests
1423     QTest::mouseMove(&mw, QPoint(-1, -1));
1424     QTest::qWait(100);
1425     if (menuFade)
1426         QTest::qWait(menuFadeDelay);
1427
1428     iFile->actionInterface()->doAction(QAccessibleActionInterface::showMenuAction());
1429     iFileNew->actionInterface()->doAction(QAccessibleActionInterface::showMenuAction());
1430
1431     QVERIFY(file->isVisible());
1432     QVERIFY(fileNew->isVisible());
1433     QVERIFY(!edit->isVisible());
1434     QVERIFY(!help->isVisible());
1435
1436     QTestAccessibility::clearEvents();
1437     mw.hide();
1438
1439     delete iFile;
1440     delete iFileNew;
1441     delete iFileOpen;
1442     delete iFileSave;
1443     delete iFileSeparator;
1444     delete iFileExit;
1445
1446     // Do not crash if the menu don't have a parent
1447     QMenu *menu = new QMenu;
1448     menu->addAction(QLatin1String("one"));
1449     menu->addAction(QLatin1String("two"));
1450     menu->addAction(QLatin1String("three"));
1451     iface = QAccessible::queryAccessibleInterface(menu);
1452     iface2 = iface->parent();
1453     QVERIFY(iface2);
1454     QCOMPARE(iface2->role(), QAccessible::Application);
1455     // caused a *crash*
1456     iface2->state();
1457     delete iface2;
1458     delete iface;
1459     delete menu;
1460
1461     }
1462     QTestAccessibility::clearEvents();
1463 }
1464
1465 void tst_QAccessibility::spinBoxTest()
1466 {
1467     QSpinBox * const spinBox = new QSpinBox();
1468     spinBox->setValue(3);
1469     spinBox->show();
1470
1471     QAccessibleInterface * const interface = QAccessible::queryAccessibleInterface(spinBox);
1472     QVERIFY(interface);
1473     QCOMPARE(interface->role(), QAccessible::SpinBox);
1474
1475     const QRect widgetRect = spinBox->geometry();
1476     const QRect accessibleRect = interface->rect();
1477     QCOMPARE(accessibleRect, widgetRect);
1478     QCOMPARE(interface->text(QAccessible::Value), QLatin1String("3"));
1479
1480     // one child, the line edit
1481     const int numChildren = interface->childCount();
1482     QCOMPARE(numChildren, 1);
1483     QAccessibleInterface *lineEdit = interface->child(0);
1484
1485     QCOMPARE(lineEdit->role(), QAccessible::EditableText);
1486     QCOMPARE(lineEdit->text(QAccessible::Value), QLatin1String("3"));
1487     delete lineEdit;
1488
1489     QVERIFY(interface->valueInterface());
1490     QCOMPARE(interface->valueInterface()->currentValue().toInt(), 3);
1491     interface->valueInterface()->setCurrentValue(23);
1492     QCOMPARE(interface->valueInterface()->currentValue().toInt(), 23);
1493     QCOMPARE(spinBox->value(), 23);
1494
1495     spinBox->setFocus();
1496     QTestAccessibility::clearEvents();
1497     QTest::keyPress(spinBox, Qt::Key_Up);
1498     QTest::qWait(200);
1499     EventList events = QTestAccessibility::events();
1500     QTestAccessibilityEvent expectedEvent(spinBox, 0, (int)QAccessible::ValueChanged);
1501     QVERIFY(events.contains(expectedEvent));
1502     delete spinBox;
1503     QTestAccessibility::clearEvents();
1504 }
1505
1506 void tst_QAccessibility::doubleSpinBoxTest()
1507 {
1508     QDoubleSpinBox *doubleSpinBox = new QDoubleSpinBox;
1509     doubleSpinBox->show();
1510
1511     QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(doubleSpinBox);
1512     QVERIFY(interface);
1513
1514     const QRect widgetRect = doubleSpinBox->geometry();
1515     const QRect accessibleRect = interface->rect();
1516     QCOMPARE(accessibleRect, widgetRect);
1517
1518     // Test that we get valid rects for all the spinbox child interfaces.
1519     const int numChildren = interface->childCount();
1520     for (int i = 0; i < numChildren; ++i) {
1521         QAccessibleInterface *childIface = interface->child(i);
1522         const QRect childRect = childIface->rect();
1523         QVERIFY(childRect.isValid());
1524         delete childIface;
1525     }
1526
1527     delete doubleSpinBox;
1528     QTestAccessibility::clearEvents();
1529 }
1530
1531 void tst_QAccessibility::textEditTest()
1532 {
1533     {
1534     QTextEdit edit;
1535     int startOffset;
1536     int endOffset;
1537     QString text = "hello world\nhow are you today?\n";
1538     edit.setText(text);
1539     edit.show();
1540
1541     QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&edit);
1542     QCOMPARE(iface->text(QAccessible::Value), text);
1543     QCOMPARE(iface->textInterface()->textAtOffset(8, QAccessible2::WordBoundary, &startOffset, &endOffset), QString("world"));
1544     QCOMPARE(startOffset, 6);
1545     QCOMPARE(endOffset, 11);
1546     QCOMPARE(iface->textInterface()->textAtOffset(14, QAccessible2::LineBoundary, &startOffset, &endOffset), QString("how are you today?"));
1547     QCOMPARE(startOffset, 12);
1548     QCOMPARE(endOffset, 30);
1549     QCOMPARE(iface->textInterface()->characterCount(), 31);
1550     QFontMetrics fm(edit.font());
1551     QCOMPARE(iface->textInterface()->characterRect(0, QAccessible2::RelativeToParent).size(), QSize(fm.width("h"), fm.height()));
1552     QCOMPARE(iface->textInterface()->characterRect(5, QAccessible2::RelativeToParent).size(), QSize(fm.width(" "), fm.height()));
1553     QCOMPARE(iface->textInterface()->characterRect(6, QAccessible2::RelativeToParent).size(), QSize(fm.width("w"), fm.height()));
1554
1555     iface->editableTextInterface()->copyText(6, 11);
1556     QCOMPARE(QApplication::clipboard()->text(), QLatin1String("world"));
1557     iface->editableTextInterface()->cutText(12, 16);
1558     QCOMPARE(QApplication::clipboard()->text(), QLatin1String("how "));
1559     QCOMPARE(iface->textInterface()->text(12, 15), QLatin1String("are"));
1560     }
1561     QTestAccessibility::clearEvents();
1562 }
1563
1564 void tst_QAccessibility::textBrowserTest()
1565 {
1566     {
1567     QTextBrowser textBrowser;
1568     QString text = QLatin1String("Hello world\nhow are you today?\n");
1569     textBrowser.setText(text);
1570     textBrowser.show();
1571
1572     QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&textBrowser);
1573     QVERIFY(iface);
1574     QCOMPARE(iface->role(), QAccessible::StaticText);
1575     QCOMPARE(iface->text(QAccessible::Value), text);
1576     int startOffset;
1577     int endOffset;
1578     QCOMPARE(iface->textInterface()->textAtOffset(8, QAccessible2::WordBoundary, &startOffset, &endOffset), QString("world"));
1579     QCOMPARE(startOffset, 6);
1580     QCOMPARE(endOffset, 11);
1581     QCOMPARE(iface->textInterface()->textAtOffset(14, QAccessible2::LineBoundary, &startOffset, &endOffset), QString("how are you today?"));
1582     QCOMPARE(startOffset, 12);
1583     QCOMPARE(endOffset, 30);
1584     QCOMPARE(iface->textInterface()->characterCount(), 31);
1585     }
1586     QTestAccessibility::clearEvents();
1587 }
1588
1589 void tst_QAccessibility::mdiAreaTest()
1590 {
1591     {
1592     QMdiArea mdiArea;
1593     mdiArea.resize(400,300);
1594     mdiArea.show();
1595     const int subWindowCount = 3;
1596     for (int i = 0; i < subWindowCount; ++i)
1597         mdiArea.addSubWindow(new QWidget, Qt::Dialog)->show();
1598
1599     QList<QMdiSubWindow *> subWindows = mdiArea.subWindowList();
1600     QCOMPARE(subWindows.count(), subWindowCount);
1601
1602     QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&mdiArea);
1603     QVERIFY(interface);
1604     QCOMPARE(interface->childCount(), subWindowCount);
1605
1606     }
1607     QTestAccessibility::clearEvents();
1608 }
1609
1610 void tst_QAccessibility::mdiSubWindowTest()
1611 {
1612     {
1613     QMdiArea mdiArea;
1614     mdiArea.show();
1615     qApp->setActiveWindow(&mdiArea);
1616 #if defined(Q_OS_UNIX)
1617     QCoreApplication::processEvents();
1618     QTest::qWait(150);
1619 #endif
1620
1621     const int subWindowCount =  5;
1622     for (int i = 0; i < subWindowCount; ++i) {
1623         QMdiSubWindow *window = mdiArea.addSubWindow(new QPushButton("QAccessibilityTest"));
1624         window->show();
1625         // Parts of this test requires that the sub windows are placed next
1626         // to each other. In order to achieve that QMdiArea must have
1627         // a width which is larger than subWindow->width() * subWindowCount.
1628         if (i == 0) {
1629             int minimumWidth = window->width() * subWindowCount + 20;
1630             mdiArea.resize(mdiArea.size().expandedTo(QSize(minimumWidth, 0)));
1631 #if defined(Q_OS_UNIX)
1632             QCoreApplication::processEvents();
1633             QTest::qWait(100);
1634 #endif
1635         }
1636     }
1637
1638     QList<QMdiSubWindow *> subWindows = mdiArea.subWindowList();
1639     QCOMPARE(subWindows.count(), subWindowCount);
1640
1641     QMdiSubWindow *testWindow = subWindows.at(3);
1642     QVERIFY(testWindow);
1643     QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(testWindow);
1644
1645     // childCount
1646     QVERIFY(interface);
1647     QCOMPARE(interface->childCount(), 1);
1648
1649     // setText / text
1650     QCOMPARE(interface->text(QAccessible::Name), QString());
1651     testWindow->setWindowTitle(QLatin1String("ReplaceMe"));
1652     QCOMPARE(interface->text(QAccessible::Name), QLatin1String("ReplaceMe"));
1653     interface->setText(QAccessible::Name, QLatin1String("TitleSetOnWindow"));
1654     QCOMPARE(interface->text(QAccessible::Name), QLatin1String("TitleSetOnWindow"));
1655
1656     mdiArea.setActiveSubWindow(testWindow);
1657
1658     // state
1659     QAccessible::State state;
1660     state.focusable = true;
1661     state.focused = true;
1662     state.movable = true;
1663     state.sizeable = true;
1664
1665     QCOMPARE(interface->state(), state);
1666     const QRect originalGeometry = testWindow->geometry();
1667     testWindow->showMaximized();
1668     state.sizeable = false;
1669     state.movable = false;
1670     QCOMPARE(interface->state(), state);
1671     testWindow->showNormal();
1672     testWindow->move(-10, 0);
1673     QVERIFY(interface->state().offscreen);
1674     testWindow->setVisible(false);
1675     QVERIFY(interface->state().invisible);
1676     testWindow->setVisible(true);
1677     testWindow->setEnabled(false);
1678     QVERIFY(interface->state().disabled);
1679     testWindow->setEnabled(true);
1680     qApp->setActiveWindow(&mdiArea);
1681     mdiArea.setActiveSubWindow(testWindow);
1682     testWindow->setFocus();
1683     QVERIFY(testWindow->isAncestorOf(qApp->focusWidget()));
1684     QVERIFY(interface->state().focused);
1685     testWindow->setGeometry(originalGeometry);
1686
1687     // rect
1688     const QPoint globalPos = testWindow->mapToGlobal(QPoint(0, 0));
1689     QCOMPARE(interface->rect(), QRect(globalPos, testWindow->size()));
1690     testWindow->hide();
1691     QCOMPARE(interface->rect(), QRect());
1692     QCOMPARE(childRect(interface), QRect());
1693     testWindow->showMinimized();
1694     QCOMPARE(childRect(interface), QRect());
1695     testWindow->showNormal();
1696     testWindow->widget()->hide();
1697     QCOMPARE(childRect(interface), QRect());
1698     testWindow->widget()->show();
1699     const QRect widgetGeometry = testWindow->contentsRect();
1700     const QPoint globalWidgetPos = QPoint(globalPos.x() + widgetGeometry.x(),
1701                                           globalPos.y() + widgetGeometry.y());
1702     QCOMPARE(childRect(interface), QRect(globalWidgetPos, widgetGeometry.size()));
1703
1704     // childAt
1705     QCOMPARE(interface->childAt(-10, 0), static_cast<QAccessibleInterface*>(0));
1706     QCOMPARE(interface->childAt(globalPos.x(), globalPos.y()), static_cast<QAccessibleInterface*>(0));
1707     QAccessibleInterface *child = interface->childAt(globalWidgetPos.x(), globalWidgetPos.y());
1708     QCOMPARE(child->role(), QAccessible::PushButton);
1709     QCOMPARE(child->text(QAccessible::Name), QString("QAccessibilityTest"));
1710     delete child;
1711     testWindow->widget()->hide();
1712     QCOMPARE(interface->childAt(globalWidgetPos.x(), globalWidgetPos.y()), static_cast<QAccessibleInterface*>(0));
1713
1714     }
1715     QTestAccessibility::clearEvents();
1716 }
1717
1718 void tst_QAccessibility::lineEditTest()
1719 {
1720     QLineEdit *le = new QLineEdit;
1721     QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(le);
1722     QVERIFY(iface);
1723     le->show();
1724
1725     QApplication::processEvents();
1726     QCOMPARE(iface->childCount(), 0);
1727     QVERIFY(iface->state().sizeable);
1728     QVERIFY(iface->state().movable);
1729     QVERIFY(iface->state().focusable);
1730     QVERIFY(iface->state().selectable);
1731     QVERIFY(iface->state().hasPopup);
1732     QCOMPARE(bool(iface->state().focused), le->hasFocus());
1733
1734     QString secret(QLatin1String("secret"));
1735     le->setText(secret);
1736     le->setEchoMode(QLineEdit::Normal);
1737     QVERIFY(!(iface->state().passwordEdit));
1738     QCOMPARE(iface->text(QAccessible::Value), secret);
1739     le->setEchoMode(QLineEdit::NoEcho);
1740     QVERIFY(iface->state().passwordEdit);
1741     QVERIFY(iface->text(QAccessible::Value).isEmpty());
1742     le->setEchoMode(QLineEdit::Password);
1743     QVERIFY(iface->state().passwordEdit);
1744     QVERIFY(iface->text(QAccessible::Value).isEmpty());
1745     le->setEchoMode(QLineEdit::PasswordEchoOnEdit);
1746     QVERIFY(iface->state().passwordEdit);
1747     QVERIFY(iface->text(QAccessible::Value).isEmpty());
1748     le->setEchoMode(QLineEdit::Normal);
1749     QVERIFY(!(iface->state().passwordEdit));
1750     QCOMPARE(iface->text(QAccessible::Value), secret);
1751
1752     QWidget *toplevel = new QWidget;
1753     le->setParent(toplevel);
1754     toplevel->show();
1755     QApplication::processEvents();
1756     QVERIFY(!(iface->state().sizeable));
1757     QVERIFY(!(iface->state().movable));
1758     QVERIFY(iface->state().focusable);
1759     QVERIFY(iface->state().selectable);
1760     QVERIFY(iface->state().hasPopup);
1761     QCOMPARE(bool(iface->state().focused), le->hasFocus());
1762
1763     QLineEdit *le2 = new QLineEdit(toplevel);
1764     le2->show();
1765     QTest::qWait(100);
1766     le2->activateWindow();
1767     QTest::qWait(100);
1768     le->setFocus(Qt::TabFocusReason);
1769     QTestAccessibility::clearEvents();
1770     le2->setFocus(Qt::TabFocusReason);
1771     QTRY_VERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(le2, 0, QAccessible::Focus)));
1772
1773     le->setText(QLatin1String("500"));
1774     le->setValidator(new QIntValidator());
1775     iface->setText(QAccessible::Value, QLatin1String("This text is not a number"));
1776     QCOMPARE(le->text(), QLatin1String("500"));
1777
1778     delete iface;
1779     delete le;
1780     delete le2;
1781     QTestAccessibility::clearEvents();
1782
1783     // IA2
1784     QString cite = "I always pass on good advice. It is the only thing to do with it. It is never of any use to oneself. --Oscar Wilde";
1785     QLineEdit *le3 = new QLineEdit(cite, toplevel);
1786     iface = QAccessible::queryAccessibleInterface(le3);
1787     QAccessibleTextInterface* textIface = iface->textInterface();
1788     le3->deselect();
1789     le3->setCursorPosition(3);
1790     QCOMPARE(textIface->cursorPosition(), 3);
1791     QTRY_VERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(le3, 0, QAccessible::TextCaretMoved)));
1792     QCOMPARE(textIface->selectionCount(), 0);
1793     QTestAccessibility::clearEvents();
1794
1795     int start, end;
1796     QCOMPARE(textIface->text(0, 8), QString::fromLatin1("I always"));
1797     QCOMPARE(textIface->textAtOffset(0, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1("I"));
1798     QCOMPARE(start, 0);
1799     QCOMPARE(end, 1);
1800     QCOMPARE(textIface->textBeforeOffset(0, QAccessible2::CharBoundary,&start,&end), QString());
1801     QCOMPARE(textIface->textAfterOffset(0, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1(" "));
1802     QCOMPARE(start, 1);
1803     QCOMPARE(end, 2);
1804
1805     QCOMPARE(textIface->textAtOffset(5, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1("a"));
1806     QCOMPARE(start, 5);
1807     QCOMPARE(end, 6);
1808     QCOMPARE(textIface->textBeforeOffset(5, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1("w"));
1809     QCOMPARE(textIface->textAfterOffset(5, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1("y"));
1810
1811     QCOMPARE(textIface->textAtOffset(5, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("always"));
1812     QCOMPARE(start, 2);
1813     QCOMPARE(end, 8);
1814
1815     QCOMPARE(textIface->textAtOffset(2, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("always"));
1816     QCOMPARE(textIface->textAtOffset(7, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("always"));
1817     QCOMPARE(textIface->textAtOffset(8, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(" "));
1818     QCOMPARE(textIface->textAtOffset(25, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("advice"));
1819     QCOMPARE(textIface->textAtOffset(92, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("oneself"));
1820
1821     QCOMPARE(textIface->textBeforeOffset(5, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(" "));
1822     QCOMPARE(textIface->textAfterOffset(5, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(" "));
1823     QCOMPARE(textIface->textAtOffset(5, QAccessible2::SentenceBoundary,&start,&end), QString::fromLatin1("I always pass on good advice. "));
1824     QCOMPARE(start, 0);
1825     QCOMPARE(end, 30);
1826
1827     QCOMPARE(textIface->textBeforeOffset(40, QAccessible2::SentenceBoundary,&start,&end), QString::fromLatin1("I always pass on good advice. "));
1828     QCOMPARE(textIface->textAfterOffset(5, QAccessible2::SentenceBoundary,&start,&end), QString::fromLatin1("It is the only thing to do with it. "));
1829
1830     QCOMPARE(textIface->textAtOffset(5, QAccessible2::ParagraphBoundary,&start,&end), cite);
1831     QCOMPARE(start, 0);
1832     QCOMPARE(end, cite.length());
1833     QCOMPARE(textIface->textAtOffset(5, QAccessible2::LineBoundary,&start,&end), cite);
1834     QCOMPARE(textIface->textAtOffset(5, QAccessible2::NoBoundary,&start,&end), cite);
1835
1836     delete iface;
1837     delete toplevel;
1838     QTestAccessibility::clearEvents();
1839 }
1840
1841 void tst_QAccessibility::workspaceTest()
1842 {
1843     {
1844     QWorkspace workspace;
1845     workspace.resize(400,300);
1846     workspace.show();
1847     const int subWindowCount =  3;
1848     for (int i = 0; i < subWindowCount; ++i) {
1849         QWidget *window = workspace.addWindow(new QWidget);
1850         if (i > 0)
1851             window->move(window->x() + 1, window->y());
1852         window->show();
1853         window->resize(70, window->height());
1854     }
1855
1856     QWidgetList subWindows = workspace.windowList();
1857     QCOMPARE(subWindows.count(), subWindowCount);
1858
1859     QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&workspace);
1860     QVERIFY(interface);
1861     QCOMPARE(interface->childCount(), subWindowCount);
1862
1863     }
1864     QTestAccessibility::clearEvents();
1865 }
1866
1867 bool accessibleInterfaceLeftOf(const QAccessibleInterface *a1, const QAccessibleInterface *a2)
1868 {
1869     return a1->rect().x() < a2->rect().x();
1870 }
1871
1872 bool accessibleInterfaceAbove(const QAccessibleInterface *a1, const QAccessibleInterface *a2)
1873 {
1874     return a1->rect().y() < a2->rect().y();
1875 }
1876
1877 void tst_QAccessibility::dialogButtonBoxTest()
1878 {
1879     {
1880     QDialogButtonBox box(QDialogButtonBox::Reset |
1881                          QDialogButtonBox::Help |
1882                          QDialogButtonBox::Ok, Qt::Horizontal);
1883
1884
1885     QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&box);
1886     QVERIFY(iface);
1887     box.show();
1888 #if defined(Q_OS_UNIX)
1889     QCoreApplication::processEvents();
1890     QTest::qWait(100);
1891 #endif
1892
1893     QApplication::processEvents();
1894     QCOMPARE(iface->childCount(), 3);
1895     QCOMPARE(iface->role(), QAccessible::Grouping);
1896     QStringList actualOrder;
1897     QAccessibleInterface *child;
1898     child = iface->child(0);
1899     QCOMPARE(child->role(), QAccessible::PushButton);
1900
1901     QVector<QAccessibleInterface *> buttons;
1902     for (int i = 0; i < iface->childCount(); ++i)
1903         buttons <<  iface->child(i);
1904
1905     qSort(buttons.begin(), buttons.end(), accessibleInterfaceLeftOf);
1906
1907     for (int i = 0; i < buttons.count(); ++i)
1908         actualOrder << buttons.at(i)->text(QAccessible::Name);
1909
1910     QStringList expectedOrder;
1911     QDialogButtonBox::ButtonLayout btnlout =
1912         QDialogButtonBox::ButtonLayout(QApplication::style()->styleHint(QStyle::SH_DialogButtonLayout));
1913     switch (btnlout) {
1914     case QDialogButtonBox::WinLayout:
1915         expectedOrder << QDialogButtonBox::tr("Reset")
1916                       << QDialogButtonBox::tr("OK")
1917                       << QDialogButtonBox::tr("Help");
1918         break;
1919     case QDialogButtonBox::GnomeLayout:
1920     case QDialogButtonBox::KdeLayout:
1921     case QDialogButtonBox::MacLayout:
1922         expectedOrder << QDialogButtonBox::tr("Help")
1923                       << QDialogButtonBox::tr("Reset")
1924                       << QDialogButtonBox::tr("OK");
1925         break;
1926     }
1927     QCOMPARE(actualOrder, expectedOrder);
1928     delete iface;
1929     QApplication::processEvents();
1930     QTestAccessibility::clearEvents();
1931     }
1932
1933     {
1934     QDialogButtonBox box(QDialogButtonBox::Reset |
1935                          QDialogButtonBox::Help |
1936                          QDialogButtonBox::Ok, Qt::Horizontal);
1937
1938
1939     // Test up and down navigation
1940     QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&box);
1941     QVERIFY(iface);
1942     box.setOrientation(Qt::Vertical);
1943     box.show();
1944 #if defined(Q_OS_UNIX)
1945     QCoreApplication::processEvents();
1946     QTest::qWait(100);
1947 #endif
1948
1949     QApplication::processEvents();
1950     QStringList actualOrder;
1951
1952     QVector<QAccessibleInterface *> buttons;
1953     for (int i = 0; i < iface->childCount(); ++i)
1954         buttons <<  iface->child(i);
1955
1956     qSort(buttons.begin(), buttons.end(), accessibleInterfaceAbove);
1957
1958     for (int i = 0; i < buttons.count(); ++i)
1959         actualOrder << buttons.at(i)->text(QAccessible::Name);
1960
1961     QStringList expectedOrder;
1962     expectedOrder << QDialogButtonBox::tr("OK")
1963                   << QDialogButtonBox::tr("Reset")
1964                   << QDialogButtonBox::tr("Help");
1965
1966     QCOMPARE(actualOrder, expectedOrder);
1967     delete iface;
1968     QApplication::processEvents();
1969
1970     }
1971     QTestAccessibility::clearEvents();
1972 }
1973
1974 void tst_QAccessibility::dialTest()
1975 {
1976     {
1977     QDial dial;
1978     dial.setMinimum(23);
1979     dial.setMaximum(121);
1980     dial.setValue(42);
1981     QCOMPARE(dial.value(), 42);
1982     dial.show();
1983
1984     QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&dial);
1985     QVERIFY(interface);
1986     QCOMPARE(interface->childCount(), 0);
1987
1988     QCOMPARE(interface->text(QAccessible::Value), QString::number(dial.value()));
1989     QCOMPARE(interface->rect(), dial.geometry());
1990
1991     QAccessibleValueInterface *valueIface = interface->valueInterface();
1992     QVERIFY(valueIface != 0);
1993     QCOMPARE(valueIface->minimumValue().toInt(), dial.minimum());
1994     QCOMPARE(valueIface->maximumValue().toInt(), dial.maximum());
1995     QCOMPARE(valueIface->currentValue().toInt(), 42);
1996     dial.setValue(50);
1997     QCOMPARE(valueIface->currentValue().toInt(), dial.value());
1998     dial.setValue(0);
1999     QCOMPARE(valueIface->currentValue().toInt(), dial.value());
2000     dial.setValue(100);
2001     QCOMPARE(valueIface->currentValue().toInt(), dial.value());
2002     valueIface->setCurrentValue(77);
2003     QCOMPARE(77, dial.value());
2004     }
2005     QTestAccessibility::clearEvents();
2006 }
2007
2008 void tst_QAccessibility::rubberBandTest()
2009 {
2010     QRubberBand rubberBand(QRubberBand::Rectangle);
2011     QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&rubberBand);
2012     QVERIFY(interface);
2013     QCOMPARE(interface->role(), QAccessible::Border);
2014     delete interface;
2015     QTestAccessibility::clearEvents();
2016 }
2017
2018 void tst_QAccessibility::abstractScrollAreaTest()
2019 {
2020     {
2021     QAbstractScrollArea abstractScrollArea;
2022
2023     QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&abstractScrollArea);
2024     QVERIFY(interface);
2025     QVERIFY(!interface->rect().isValid());
2026     QCOMPARE(interface->childAt(200, 200), static_cast<QAccessibleInterface*>(0));
2027
2028     abstractScrollArea.resize(400, 400);
2029     abstractScrollArea.show();
2030 #if defined(Q_OS_UNIX)
2031     QCoreApplication::processEvents();
2032     QTest::qWait(100);
2033 #endif
2034     const QRect globalGeometry = QRect(abstractScrollArea.mapToGlobal(QPoint(0, 0)),
2035                                        abstractScrollArea.size());
2036
2037     // Viewport.
2038     QCOMPARE(interface->childCount(), 1);
2039     QWidget *viewport = abstractScrollArea.viewport();
2040     QVERIFY(viewport);
2041     QVERIFY(verifyChild(viewport, interface, 0, globalGeometry));
2042
2043     // Horizontal scrollBar.
2044     abstractScrollArea.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
2045     QCOMPARE(interface->childCount(), 2);
2046     QWidget *horizontalScrollBar = abstractScrollArea.horizontalScrollBar();
2047     QWidget *horizontalScrollBarContainer = horizontalScrollBar->parentWidget();
2048     QVERIFY(verifyChild(horizontalScrollBarContainer, interface, 1, globalGeometry));
2049
2050     // Horizontal scrollBar widgets.
2051     QLabel *secondLeftLabel = new QLabel(QLatin1String("L2"));
2052     abstractScrollArea.addScrollBarWidget(secondLeftLabel, Qt::AlignLeft);
2053     QCOMPARE(interface->childCount(), 2);
2054
2055     QLabel *firstLeftLabel = new QLabel(QLatin1String("L1"));
2056     abstractScrollArea.addScrollBarWidget(firstLeftLabel, Qt::AlignLeft);
2057     QCOMPARE(interface->childCount(), 2);
2058
2059     QLabel *secondRightLabel = new QLabel(QLatin1String("R2"));
2060     abstractScrollArea.addScrollBarWidget(secondRightLabel, Qt::AlignRight);
2061     QCOMPARE(interface->childCount(), 2);
2062
2063     QLabel *firstRightLabel = new QLabel(QLatin1String("R1"));
2064     abstractScrollArea.addScrollBarWidget(firstRightLabel, Qt::AlignRight);
2065     QCOMPARE(interface->childCount(), 2);
2066
2067     // Vertical scrollBar.
2068     abstractScrollArea.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
2069     QCOMPARE(interface->childCount(), 3);
2070     QWidget *verticalScrollBar = abstractScrollArea.verticalScrollBar();
2071     QWidget *verticalScrollBarContainer = verticalScrollBar->parentWidget();
2072     QVERIFY(verifyChild(verticalScrollBarContainer, interface, 2, globalGeometry));
2073
2074     // Vertical scrollBar widgets.
2075     QLabel *secondTopLabel = new QLabel(QLatin1String("T2"));
2076     abstractScrollArea.addScrollBarWidget(secondTopLabel, Qt::AlignTop);
2077     QCOMPARE(interface->childCount(), 3);
2078
2079     QLabel *firstTopLabel = new QLabel(QLatin1String("T1"));
2080     abstractScrollArea.addScrollBarWidget(firstTopLabel, Qt::AlignTop);
2081     QCOMPARE(interface->childCount(), 3);
2082
2083     QLabel *secondBottomLabel = new QLabel(QLatin1String("B2"));
2084     abstractScrollArea.addScrollBarWidget(secondBottomLabel, Qt::AlignBottom);
2085     QCOMPARE(interface->childCount(), 3);
2086
2087     QLabel *firstBottomLabel = new QLabel(QLatin1String("B1"));
2088     abstractScrollArea.addScrollBarWidget(firstBottomLabel, Qt::AlignBottom);
2089     QCOMPARE(interface->childCount(), 3);
2090
2091     // CornerWidget.
2092     abstractScrollArea.setCornerWidget(new QLabel(QLatin1String("C")));
2093     QCOMPARE(interface->childCount(), 4);
2094     QWidget *cornerWidget = abstractScrollArea.cornerWidget();
2095     QVERIFY(verifyChild(cornerWidget, interface, 3, globalGeometry));
2096
2097     QCOMPARE(verifyHierarchy(interface), 0);
2098
2099     delete interface;
2100     }
2101
2102     QTestAccessibility::clearEvents();
2103 }
2104
2105 void tst_QAccessibility::scrollAreaTest()
2106 {
2107     {
2108     QScrollArea scrollArea;
2109     scrollArea.show();
2110 #if defined(Q_OS_UNIX)
2111     QCoreApplication::processEvents();
2112     QTest::qWait(100);
2113 #endif
2114     QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&scrollArea);
2115     QVERIFY(interface);
2116     QCOMPARE(interface->childCount(), 1); // The viewport.
2117     delete interface;
2118     }
2119     QTestAccessibility::clearEvents();
2120 }
2121
2122 void tst_QAccessibility::listTest()
2123 {
2124     {
2125     QListWidget *listView = new QListWidget;
2126     listView->addItem("Oslo");
2127     listView->addItem("Berlin");
2128     listView->addItem("Brisbane");
2129     listView->resize(400,400);
2130     listView->show();
2131     QTest::qWait(1); // Need this for indexOfchild to work.
2132     QCoreApplication::processEvents();
2133     QTest::qWait(100);
2134
2135     QAIPtr iface = QAIPtr(QAccessible::queryAccessibleInterface(listView));
2136     QCOMPARE(verifyHierarchy(iface.data()), 0);
2137
2138     QCOMPARE((int)iface->role(), (int)QAccessible::List);
2139     QCOMPARE(iface->childCount(), 3);
2140
2141     {
2142     QAIPtr child1 = QAIPtr(iface->child(0));
2143     QVERIFY(child1);
2144     QCOMPARE(iface->indexOfChild(child1.data()), 0);
2145     QCOMPARE(child1->text(QAccessible::Name), QString("Oslo"));
2146     QCOMPARE(child1->role(), QAccessible::ListItem);
2147
2148     QAIPtr child2 = QAIPtr(iface->child(1));
2149     QVERIFY(child2);
2150     QCOMPARE(iface->indexOfChild(child2.data()), 1);
2151     QCOMPARE(child2->text(QAccessible::Name), QString("Berlin"));
2152
2153     QAIPtr child3 = QAIPtr(iface->child(2));
2154     QVERIFY(child3);
2155     QCOMPARE(iface->indexOfChild(child3.data()), 2);
2156     QCOMPARE(child3->text(QAccessible::Name), QString("Brisbane"));
2157     }
2158     QTestAccessibility::clearEvents();
2159
2160     // Check for events
2161     QTest::mouseClick(listView->viewport(), Qt::LeftButton, 0, listView->visualItemRect(listView->item(1)).center());
2162     QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(listView, 2, QAccessible::Selection)));
2163     QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(listView, 2, QAccessible::Focus)));
2164     QTest::mouseClick(listView->viewport(), Qt::LeftButton, 0, listView->visualItemRect(listView->item(2)).center());
2165     QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(listView, 3, QAccessible::Selection)));
2166     QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(listView, 3, QAccessible::Focus)));
2167
2168     listView->addItem("Munich");
2169     QCOMPARE(iface->childCount(), 4);
2170
2171     // table 2
2172     QAccessibleTableInterface *table2 = iface->tableInterface();
2173     QVERIFY(table2);
2174     QCOMPARE(table2->columnCount(), 1);
2175     QCOMPARE(table2->rowCount(), 4);
2176     QAIPtr cell1 = QAIPtr(table2->cellAt(0,0));
2177     QVERIFY(cell1);
2178     QCOMPARE(cell1->text(QAccessible::Name), QString("Oslo"));
2179
2180     QAIPtr cell4 = QAIPtr(table2->cellAt(3,0));
2181     QVERIFY(cell4);
2182     QCOMPARE(cell4->text(QAccessible::Name), QString("Munich"));
2183     QCOMPARE(cell4->role(), QAccessible::ListItem);
2184
2185     QAccessibleTableCellInterface *cellInterface = cell4->tableCellInterface();
2186     QVERIFY(cellInterface);
2187     QCOMPARE(cellInterface->rowIndex(), 3);
2188     QCOMPARE(cellInterface->columnIndex(), 0);
2189     QCOMPARE(cellInterface->rowExtent(), 1);
2190     QCOMPARE(cellInterface->columnExtent(), 1);
2191     QCOMPARE(cellInterface->rowHeaderCells(), QList<QAccessibleInterface*>());
2192     QCOMPARE(cellInterface->columnHeaderCells(), QList<QAccessibleInterface*>());
2193
2194     QCOMPARE(QAIPtr(cellInterface->table())->object(), listView);
2195
2196     listView->clearSelection();
2197     QVERIFY(!(cell4->state().expandable));
2198     QVERIFY( (cell4->state().selectable));
2199     QVERIFY(!(cell4->state().selected));
2200     table2->selectRow(3);
2201     QCOMPARE(listView->selectedItems().size(), 1);
2202     QCOMPARE(listView->selectedItems().at(0)->text(), QLatin1String("Munich"));
2203     QVERIFY(cell4->state().selected);
2204     QVERIFY(cellInterface->isSelected());
2205
2206     QVERIFY(table2->cellAt(-1, 0) == 0);
2207     QVERIFY(table2->cellAt(0, -1) == 0);
2208     QVERIFY(table2->cellAt(0, 1) == 0);
2209     QVERIFY(table2->cellAt(4, 0) == 0);
2210
2211     delete listView;
2212     }
2213     QTestAccessibility::clearEvents();
2214 }
2215
2216 void tst_QAccessibility::treeTest()
2217 {
2218     QTreeWidget *treeView = new QTreeWidget;
2219     treeView->setColumnCount(2);
2220     QTreeWidgetItem *header = new QTreeWidgetItem;
2221     header->setText(0, "Artist");
2222     header->setText(1, "Work");
2223     treeView->setHeaderItem(header);
2224
2225     QTreeWidgetItem *root1 = new QTreeWidgetItem;
2226     root1->setText(0, "Spain");
2227     treeView->addTopLevelItem(root1);
2228
2229     QTreeWidgetItem *item1 = new QTreeWidgetItem;
2230     item1->setText(0, "Picasso");
2231     item1->setText(1, "Guernica");
2232     root1->addChild(item1);
2233
2234     QTreeWidgetItem *item2 = new QTreeWidgetItem;
2235     item2->setText(0, "Tapies");
2236     item2->setText(1, "Ambrosia");
2237     root1->addChild(item2);
2238
2239     QTreeWidgetItem *root2 = new QTreeWidgetItem;
2240     root2->setText(0, "Austria");
2241     treeView->addTopLevelItem(root2);
2242
2243     QTreeWidgetItem *item3 = new QTreeWidgetItem;
2244     item3->setText(0, "Klimt");
2245     item3->setText(1, "The Kiss");
2246     root2->addChild(item3);
2247
2248     treeView->resize(400,400);
2249     treeView->show();
2250
2251     QCoreApplication::processEvents();
2252     QTest::qWait(100);
2253
2254     QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(treeView);
2255     QCOMPARE(verifyHierarchy(iface), 0);
2256
2257     QCOMPARE((int)iface->role(), (int)QAccessible::Tree);
2258     // header and 2 rows (the others are not expanded, thus not visible)
2259     QCOMPARE(iface->childCount(), 6);
2260
2261     QAccessibleInterface *header1 = 0;
2262     header1 = iface->child(0);
2263     QVERIFY(header1);
2264     QCOMPARE(iface->indexOfChild(header1), 0);
2265     QCOMPARE(header1->text(QAccessible::Name), QString("Artist"));
2266     QCOMPARE(header1->role(), QAccessible::ColumnHeader);
2267     delete header1;
2268
2269     QAccessibleInterface *child1 = 0;
2270     child1 = iface->child(2);
2271     QVERIFY(child1);
2272     QCOMPARE(iface->indexOfChild(child1), 2);
2273     QCOMPARE(child1->text(QAccessible::Name), QString("Spain"));
2274     QCOMPARE(child1->role(), QAccessible::TreeItem);
2275     QVERIFY(!(child1->state().expanded));
2276     delete child1;
2277
2278     QAccessibleInterface *child2 = 0;
2279     child2 = iface->child(4);
2280     QVERIFY(child2);
2281     QCOMPARE(iface->indexOfChild(child2), 4);
2282     QCOMPARE(child2->text(QAccessible::Name), QString("Austria"));
2283     delete child2;
2284
2285     QTestAccessibility::clearEvents();
2286
2287     // table 2
2288     QAccessibleTableInterface *table2 = iface->tableInterface();
2289     QVERIFY(table2);
2290     QCOMPARE(table2->columnCount(), 2);
2291     QCOMPARE(table2->rowCount(), 2);
2292     QAccessibleInterface *cell1;
2293     QVERIFY(cell1 = table2->cellAt(0,0));
2294     QCOMPARE(cell1->text(QAccessible::Name), QString("Spain"));
2295     QAccessibleInterface *cell2;
2296     QVERIFY(cell2 = table2->cellAt(1,0));
2297     QCOMPARE(cell2->text(QAccessible::Name), QString("Austria"));
2298     QCOMPARE(cell2->role(), QAccessible::TreeItem);
2299     QCOMPARE(cell2->tableCellInterface()->rowIndex(), 1);
2300     QCOMPARE(cell2->tableCellInterface()->columnIndex(), 0);
2301     QVERIFY(cell2->state().expandable);
2302     QCOMPARE(iface->indexOfChild(cell2), 4);
2303     QVERIFY(!(cell2->state().expanded));
2304     QCOMPARE(table2->columnDescription(1), QString("Work"));
2305     delete cell2;
2306     delete cell1;
2307
2308     treeView->expandAll();
2309
2310     // Need this for indexOfchild to work.
2311     QCoreApplication::processEvents();
2312     QTest::qWait(100);
2313
2314     QCOMPARE(table2->columnCount(), 2);
2315     QCOMPARE(table2->rowCount(), 5);
2316     cell1 = table2->cellAt(1,0);
2317     QCOMPARE(cell1->text(QAccessible::Name), QString("Picasso"));
2318     QCOMPARE(iface->indexOfChild(cell1), 4); // 2 header + 2 for root item
2319
2320     cell2 = table2->cellAt(4,0);
2321     QCOMPARE(cell2->text(QAccessible::Name), QString("Klimt"));
2322     QCOMPARE(cell2->role(), QAccessible::TreeItem);
2323     QCOMPARE(cell2->tableCellInterface()->rowIndex(), 4);
2324     QCOMPARE(cell2->tableCellInterface()->columnIndex(), 0);
2325     QVERIFY(!(cell2->state().expandable));
2326     QCOMPARE(iface->indexOfChild(cell2), 10);
2327
2328     QCOMPARE(table2->columnDescription(0), QString("Artist"));
2329     QCOMPARE(table2->columnDescription(1), QString("Work"));
2330
2331     delete iface;
2332     QTestAccessibility::clearEvents();
2333 }
2334
2335 void tst_QAccessibility::tableTest()
2336 {
2337     QTableWidget *tableView = new QTableWidget(3, 3);
2338     tableView->setColumnCount(3);
2339     QStringList hHeader;
2340     hHeader << "h1" << "h2" << "h3";
2341     tableView->setHorizontalHeaderLabels(hHeader);
2342
2343     QStringList vHeader;
2344     vHeader << "v1" << "v2" << "v3";
2345     tableView->setVerticalHeaderLabels(vHeader);
2346
2347     for (int i = 0; i<9; ++i) {
2348         QTableWidgetItem *item = new QTableWidgetItem;
2349         item->setText(QString::number(i/3) + QString(".") + QString::number(i%3));
2350         tableView->setItem(i/3, i%3, item);
2351     }
2352
2353     tableView->resize(600,600);
2354     tableView->show();
2355     QTest::qWait(1); // Need this for indexOfchild to work.
2356     QCoreApplication::processEvents();
2357     QTest::qWait(100);
2358
2359     QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(tableView);
2360     QCOMPARE(verifyHierarchy(iface), 0);
2361
2362     QCOMPARE((int)iface->role(), (int)QAccessible::Table);
2363     // header and 2 rows (the others are not expanded, thus not visible)
2364     QCOMPARE(iface->childCount(), 9+3+3+1); // cell+headers+topleft button
2365
2366     QAccessibleInterface *cornerButton = iface->child(0);
2367     QVERIFY(cornerButton);
2368     QCOMPARE(iface->indexOfChild(cornerButton), 0);
2369     QCOMPARE(cornerButton->role(), QAccessible::Pane);
2370     delete cornerButton;
2371
2372     QAccessibleInterface *child1 = iface->child(2);
2373     QVERIFY(child1);
2374     QCOMPARE(iface->indexOfChild(child1), 2);
2375     QCOMPARE(child1->text(QAccessible::Name), QString("h2"));
2376     QCOMPARE(child1->role(), QAccessible::ColumnHeader);
2377     QVERIFY(!(child1->state().expanded));
2378     delete child1;
2379
2380     QAccessibleInterface *child2 = iface->child(10);
2381     QVERIFY(child2);
2382     QCOMPARE(iface->indexOfChild(child2), 10);
2383     QCOMPARE(child2->text(QAccessible::Name), QString("1.1"));
2384     QAccessibleTableCellInterface *cell2Iface = child2->tableCellInterface();
2385     QCOMPARE(cell2Iface->rowIndex(), 1);
2386     QCOMPARE(cell2Iface->columnIndex(), 1);
2387     delete child2;
2388
2389     QAccessibleInterface *child3 = iface->child(11);
2390     QCOMPARE(iface->indexOfChild(child3), 11);
2391     QCOMPARE(child3->text(QAccessible::Name), QString("1.2"));
2392     delete child3;
2393
2394     QTestAccessibility::clearEvents();
2395
2396     // table 2
2397     QAccessibleTableInterface *table2 = iface->tableInterface();
2398     QVERIFY(table2);
2399     QCOMPARE(table2->columnCount(), 3);
2400     QCOMPARE(table2->rowCount(), 3);
2401     QAccessibleInterface *cell1;
2402     QVERIFY(cell1 = table2->cellAt(0,0));
2403     QCOMPARE(cell1->text(QAccessible::Name), QString("0.0"));
2404     QCOMPARE(iface->indexOfChild(cell1), 5);
2405
2406     QAccessibleInterface *cell2;
2407     QVERIFY(cell2 = table2->cellAt(0,1));
2408     QCOMPARE(cell2->text(QAccessible::Name), QString("0.1"));
2409     QCOMPARE(cell2->role(), QAccessible::Cell);
2410     QCOMPARE(cell2->tableCellInterface()->rowIndex(), 0);
2411     QCOMPARE(cell2->tableCellInterface()->columnIndex(), 1);
2412     QCOMPARE(iface->indexOfChild(cell2), 6);
2413     delete cell2;
2414
2415     QAccessibleInterface *cell3;
2416     QVERIFY(cell3 = table2->cellAt(1,2));
2417     QCOMPARE(cell3->text(QAccessible::Name), QString("1.2"));
2418     QCOMPARE(cell3->role(), QAccessible::Cell);
2419     QCOMPARE(cell3->tableCellInterface()->rowIndex(), 1);
2420     QCOMPARE(cell3->tableCellInterface()->columnIndex(), 2);
2421     QCOMPARE(iface->indexOfChild(cell3), 11);
2422     delete cell3;
2423
2424     QCOMPARE(table2->columnDescription(0), QString("h1"));
2425     QCOMPARE(table2->columnDescription(1), QString("h2"));
2426     QCOMPARE(table2->columnDescription(2), QString("h3"));
2427     QCOMPARE(table2->rowDescription(0), QString("v1"));
2428     QCOMPARE(table2->rowDescription(1), QString("v2"));
2429     QCOMPARE(table2->rowDescription(2), QString("v3"));
2430
2431     delete iface;
2432
2433     delete tableView;
2434
2435     QTestAccessibility::clearEvents();
2436 }
2437
2438 void tst_QAccessibility::calendarWidgetTest()
2439 {
2440 #ifndef QT_NO_CALENDARWIDGET
2441     {
2442     QCalendarWidget calendarWidget;
2443
2444     QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&calendarWidget);
2445     QVERIFY(interface);
2446     QCOMPARE(interface->role(), QAccessible::Table);
2447     QVERIFY(!interface->rect().isValid());
2448     QCOMPARE(interface->childAt(200, 200), static_cast<QAccessibleInterface*>(0));
2449
2450     calendarWidget.resize(400, 300);
2451     calendarWidget.show();
2452 #if defined(Q_OS_UNIX)
2453     QCoreApplication::processEvents();
2454     QTest::qWait(100);
2455 #endif
2456
2457     // 1 = navigationBar, 2 = view.
2458     QCOMPARE(interface->childCount(), 2);
2459
2460     const QRect globalGeometry = QRect(calendarWidget.mapToGlobal(QPoint(0, 0)),
2461                                        calendarWidget.size());
2462     QCOMPARE(interface->rect(), globalGeometry);
2463
2464     QWidget *navigationBar = 0;
2465     foreach (QObject *child, calendarWidget.children()) {
2466         if (child->objectName() == QLatin1String("qt_calendar_navigationbar")) {
2467             navigationBar = static_cast<QWidget *>(child);
2468             break;
2469         }
2470     }
2471     QVERIFY(navigationBar);
2472     QVERIFY(verifyChild(navigationBar, interface, 0, globalGeometry));
2473
2474     QAbstractItemView *calendarView = 0;
2475     foreach (QObject *child, calendarWidget.children()) {
2476         if (child->objectName() == QLatin1String("qt_calendar_calendarview")) {
2477             calendarView = static_cast<QAbstractItemView *>(child);
2478             break;
2479         }
2480     }
2481     QVERIFY(calendarView);
2482     QVERIFY(verifyChild(calendarView, interface, 1, globalGeometry));
2483
2484     // Hide navigation bar.
2485     calendarWidget.setNavigationBarVisible(false);
2486     QCOMPARE(interface->childCount(), 1);
2487     QVERIFY(!navigationBar->isVisible());
2488
2489     QVERIFY(verifyChild(calendarView, interface, 0, globalGeometry));
2490
2491     // Show navigation bar.
2492     calendarWidget.setNavigationBarVisible(true);
2493     QCOMPARE(interface->childCount(), 2);
2494     QVERIFY(navigationBar->isVisible());
2495
2496     // Navigate to the navigation bar via Child.
2497     QAccessibleInterface *navigationBarInterface = interface->child(0);
2498     QVERIFY(navigationBarInterface);
2499     QCOMPARE(navigationBarInterface->object(), (QObject*)navigationBar);
2500
2501     // Navigate to the view via Child.
2502     QAccessibleInterface *calendarViewInterface = interface->child(1);
2503     QVERIFY(calendarViewInterface);
2504     QCOMPARE(calendarViewInterface->object(), (QObject*)calendarView);
2505
2506     QVERIFY(!interface->child(-1));
2507
2508     // In order for geometric navigation to work they must share the same parent
2509     QCOMPARE(navigationBarInterface->parent()->object(), calendarViewInterface->parent()->object());
2510     QVERIFY(navigationBarInterface->rect().bottom() < calendarViewInterface->rect().top());
2511     delete calendarViewInterface;
2512     calendarViewInterface = 0;
2513     delete navigationBarInterface;
2514     navigationBarInterface = 0;
2515
2516     }
2517     QTestAccessibility::clearEvents();
2518 #endif // QT_NO_CALENDARWIDGET
2519 }
2520
2521 void tst_QAccessibility::dockWidgetTest()
2522 {
2523 #ifndef QT_NO_DOCKWIDGET
2524     // Set up a proper main window with two dock widgets
2525     QMainWindow *mw = new QMainWindow();
2526     QFrame *central = new QFrame(mw);
2527     mw->setCentralWidget(central);
2528     QMenuBar *mb = new QMenuBar(mw);
2529     mb->addAction(tr("&File"));
2530     mw->setMenuBar(mb);
2531
2532     QDockWidget *dock1 = new QDockWidget(mw);
2533     mw->addDockWidget(Qt::LeftDockWidgetArea, dock1);
2534     QPushButton *pb1 = new QPushButton(tr("Push me"), dock1);
2535     dock1->setWidget(pb1);
2536
2537     QDockWidget *dock2 = new QDockWidget(mw);
2538     mw->addDockWidget(Qt::BottomDockWidgetArea, dock2);
2539     QPushButton *pb2 = new QPushButton(tr("Push me"), dock2);
2540     dock2->setWidget(pb2);
2541
2542     mw->resize(600,400);
2543     mw->show();
2544 #if defined(Q_OS_UNIX)
2545     QCoreApplication::processEvents();
2546     QTest::qWait(100);
2547 #endif
2548
2549     QAccessibleInterface *accMainWindow = QAccessible::queryAccessibleInterface(mw);
2550     // 4 children: menu bar, dock1, dock2, and central widget
2551     QCOMPARE(accMainWindow->childCount(), 4);
2552     QAccessibleInterface *accDock1 = 0;
2553     for (int i = 0; i < 4; ++i) {
2554         accDock1 = accMainWindow->child(i);
2555         if (accMainWindow->role() == QAccessible::Window) {
2556             if (accDock1 && qobject_cast<QDockWidget*>(accDock1->object()) == dock1) {
2557                 break;
2558             } else {
2559                 delete accDock1;
2560             }
2561         }
2562     }
2563     QVERIFY(accDock1);
2564     QCOMPARE(accDock1->role(), QAccessible::Window);
2565
2566     QAccessibleInterface *dock1TitleBar = accDock1->child(0);
2567     QCOMPARE(dock1TitleBar->role(), QAccessible::TitleBar);
2568     QVERIFY(accDock1->rect().contains(dock1TitleBar->rect()));
2569     delete dock1TitleBar;
2570
2571     QPoint globalPos = dock1->mapToGlobal(QPoint(0,0));
2572     globalPos.rx()+=5;  //### query style
2573     globalPos.ry()+=5;
2574     QAccessibleInterface *childAt = accDock1->childAt(globalPos.x(), globalPos.y());    //###
2575     QCOMPARE(childAt->role(), QAccessible::TitleBar);
2576     int index = accDock1->indexOfChild(childAt);
2577     delete childAt;
2578     QAccessibleInterface *accTitleBar = accDock1->child(index);
2579
2580     QCOMPARE(accTitleBar->role(), QAccessible::TitleBar);
2581     QCOMPARE(accDock1->indexOfChild(accTitleBar), 0);
2582     QAccessibleInterface *acc;
2583     acc = accTitleBar->parent();
2584     QVERIFY(acc);
2585     QCOMPARE(acc->role(), QAccessible::Window);
2586
2587
2588     delete accTitleBar;
2589     delete accDock1;
2590     delete pb1;
2591     delete pb2;
2592     delete dock1;
2593     delete dock2;
2594     delete mw;
2595     QTestAccessibility::clearEvents();
2596 #endif // QT_NO_DOCKWIDGET
2597 }
2598
2599 void tst_QAccessibility::comboBoxTest()
2600 {
2601 #if defined(Q_OS_WINCE)
2602     if (!IsValidCEPlatform())
2603         QSKIP("Test skipped on Windows Mobile test hardware");
2604 #endif
2605     { // not editable combobox
2606     QComboBox combo;
2607     combo.addItems(QStringList() << "one" << "two" << "three");
2608     combo.show();
2609     QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&combo);
2610     QCOMPARE(verifyHierarchy(iface), 0);
2611
2612     QCOMPARE(iface->role(), QAccessible::ComboBox);
2613     QCOMPARE(iface->childCount(), 1);
2614
2615 #ifdef Q_OS_UNIX
2616     QCOMPARE(iface->text(QAccessible::Name), QLatin1String("one"));
2617 #endif
2618     QCOMPARE(iface->text(QAccessible::Value), QLatin1String("one"));
2619     combo.setCurrentIndex(2);
2620 #ifdef Q_OS_UNIX
2621     QCOMPARE(iface->text(QAccessible::Name), QLatin1String("three"));
2622 #endif
2623     QCOMPARE(iface->text(QAccessible::Value), QLatin1String("three"));
2624
2625     QAccessibleInterface *listIface = iface->child(0);
2626     QCOMPARE(listIface->role(), QAccessible::List);
2627     QCOMPARE(listIface->childCount(), 3);
2628
2629     QVERIFY(!combo.view()->isVisible());
2630     QVERIFY(iface->actionInterface());
2631     QCOMPARE(iface->actionInterface()->actionNames(), QStringList() << QAccessibleActionInterface::showMenuAction());
2632     iface->actionInterface()->doAction(QAccessibleActionInterface::showMenuAction());
2633     QVERIFY(combo.view()->isVisible());
2634
2635     delete iface;
2636     }
2637
2638     { // editable combobox
2639     QComboBox editableCombo;
2640     editableCombo.show();
2641     editableCombo.setEditable(true);
2642     editableCombo.addItems(QStringList() << "foo" << "bar" << "baz");
2643
2644     QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&editableCombo);
2645     QCOMPARE(verifyHierarchy(iface), 0);
2646
2647     QCOMPARE(iface->role(), QAccessible::ComboBox);
2648     QCOMPARE(iface->childCount(), 2);
2649
2650     QAccessibleInterface *listIface = iface->child(0);
2651     QCOMPARE(listIface->role(), QAccessible::List);
2652     QAccessibleInterface *editIface = iface->child(1);
2653     QCOMPARE(editIface->role(), QAccessible::EditableText);
2654
2655     delete listIface;
2656     delete editIface;
2657     delete iface;
2658     }
2659
2660     QTestAccessibility::clearEvents();
2661 }
2662
2663 void tst_QAccessibility::labelTest()
2664 {
2665     QString text = "Hello World";
2666     QLabel *label = new QLabel(text);
2667     label->show();
2668
2669 #if defined(Q_OS_UNIX)
2670     QCoreApplication::processEvents();
2671 #endif
2672     QTest::qWait(100);
2673
2674     QAccessibleInterface *acc_label = QAccessible::queryAccessibleInterface(label);
2675     QVERIFY(acc_label);
2676
2677     QCOMPARE(acc_label->text(QAccessible::Name), text);
2678
2679     delete acc_label;
2680     delete label;
2681     QTestAccessibility::clearEvents();
2682
2683     QPixmap testPixmap(50, 50);
2684     testPixmap.fill();
2685
2686     QLabel imageLabel;
2687     imageLabel.setPixmap(testPixmap);
2688     imageLabel.setToolTip("Test Description");
2689
2690     acc_label = QAccessible::queryAccessibleInterface(&imageLabel);
2691     QVERIFY(acc_label);
2692
2693     QAccessibleImageInterface *imageInterface = acc_label->imageInterface();
2694     QVERIFY(imageInterface);
2695
2696     QCOMPARE(imageInterface->imageSize(), testPixmap.size());
2697     QCOMPARE(imageInterface->imageDescription(), QString::fromLatin1("Test Description"));
2698     QCOMPARE(imageInterface->imagePosition(QAccessible2::RelativeToParent), imageLabel.geometry());
2699
2700     delete acc_label;
2701
2702     QTestAccessibility::clearEvents();
2703 }
2704
2705 void tst_QAccessibility::accelerators()
2706 {
2707     QWidget *window = new QWidget;
2708     QHBoxLayout *lay = new QHBoxLayout(window);
2709     QLabel *label = new QLabel(tr("&Line edit"), window);
2710     QLineEdit *le = new QLineEdit(window);
2711     lay->addWidget(label);
2712     lay->addWidget(le);
2713     label->setBuddy(le);
2714
2715     window->show();
2716
2717     QAccessibleInterface *accLineEdit = QAccessible::queryAccessibleInterface(le);
2718     QCOMPARE(accLineEdit->text(QAccessible::Accelerator), QKeySequence(Qt::ALT).toString(QKeySequence::NativeText) + QLatin1String("L"));
2719     QCOMPARE(accLineEdit->text(QAccessible::Accelerator), QKeySequence(Qt::ALT).toString(QKeySequence::NativeText) + QLatin1String("L"));
2720     label->setText(tr("Q &"));
2721     QCOMPARE(accLineEdit->text(QAccessible::Accelerator), QString());
2722     label->setText(tr("Q &&"));
2723     QCOMPARE(accLineEdit->text(QAccessible::Accelerator), QString());
2724     label->setText(tr("Q && A"));
2725     QCOMPARE(accLineEdit->text(QAccessible::Accelerator), QString());
2726     label->setText(tr("Q &&&A"));
2727     QCOMPARE(accLineEdit->text(QAccessible::Accelerator), QKeySequence(Qt::ALT).toString(QKeySequence::NativeText) + QLatin1String("A"));
2728     label->setText(tr("Q &&A"));
2729     QCOMPARE(accLineEdit->text(QAccessible::Accelerator), QString());
2730
2731 #if !defined(QT_NO_DEBUG) && !defined(Q_OS_MAC)
2732     QTest::ignoreMessage(QtWarningMsg, "QKeySequence::mnemonic: \"Q &A&B\" contains multiple occurrences of '&'");
2733 #endif
2734     label->setText(tr("Q &A&B"));
2735     QCOMPARE(accLineEdit->text(QAccessible::Accelerator), QKeySequence(Qt::ALT).toString(QKeySequence::NativeText) + QLatin1String("A"));
2736
2737 #if defined(Q_OS_UNIX)
2738     QCoreApplication::processEvents();
2739 #endif
2740     QTest::qWait(100);
2741     delete window;
2742     QTestAccessibility::clearEvents();
2743 }
2744
2745 QTEST_MAIN(tst_QAccessibility)
2746 #include "tst_qaccessibility.moc"