1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
43 #include <QtTest/QtTest>
48 #if defined(Q_OS_WIN) && defined(interface)
53 #include "QtTest/qtestaccessible.h"
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")))
69 typedef QSharedPointer<QAccessibleInterface> QAIPtr;
71 static inline bool verifyChild(QWidget *child, QAccessibleInterface *interface,
72 int index, const QRect &domain)
75 qWarning("tst_QAccessibility::verifyChild: null pointer to child.");
80 qWarning("tst_QAccessibility::verifyChild: null pointer to interface.");
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.");
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;
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)
106 const QRect rectFromInterface = navigatedChildInterface->rect();
107 delete navigatedChildInterface;
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";
120 if (childAtInterface->object() != childInterface->object()) {
121 qWarning("tst_QAccessibility::verifyChild (childAt()):");
122 qWarning() << "Expected:" << childInterface;
123 qWarning() << "Actual: " << childAtInterface;
126 delete childInterface;
127 delete childAtInterface;
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;
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.");
149 static inline int indexOfChild(QAccessibleInterface *parentInterface, QWidget *childWidget)
151 if (!parentInterface || !childWidget)
153 QAccessibleInterface *childInterface = QAccessible::queryAccessibleInterface(childWidget);
156 int index = parentInterface->indexOfChild(childInterface);
157 delete childInterface;
161 #define EXPECT(cond) \
163 if (!errorAt && !(cond)) { \
164 errorAt = __LINE__; \
165 qWarning("level: %d, middle: %d, role: %d (%s)", treelevel, middle, iface->role(), #cond); \
169 static int verifyHierarchy(QAccessibleInterface *iface)
172 static int treelevel = 0; // for error diagnostics
173 QAccessibleInterface *middleChild, *if2;
176 int middle = iface->childCount()/2 + 1;
177 if (iface->childCount() >= 2) {
178 middleChild = iface->child(middle - 1);
180 for (int i = 0; i < iface->childCount() && !errorAt; ++i) {
181 if2 = iface->child(i);
183 // navigate Ancestor...
184 QAccessibleInterface *parent = if2->parent();
185 EXPECT(iface->object() == parent->object());
188 // navigate Sibling...
189 // if (middleChild) {
190 // entry = if2->navigate(QAccessible::Sibling, middle, &if3);
191 // EXPECT(entry == 0 && if3->object() == middleChild->object());
194 // EXPECT(iface->indexOfChild(middleChild) == middle);
197 // verify children...
199 errorAt = verifyHierarchy(if2);
208 QRect childRect(QAccessibleInterface *iface, int index = 0)
210 QAccessibleInterface *child = iface->child(index);
211 QRect rect = child->rect();
216 class tst_QAccessibility : public QObject
220 tst_QAccessibility();
221 virtual ~tst_QAccessibility();
225 void cleanupTestCase();
231 void deletedWidget();
233 void statesStructTest();
234 void navigateHierarchy();
236 void textAttributes();
241 void applicationTest();
242 void mainWindowTest();
244 void scrollBarTest();
246 void tabWidgetTest();
249 void doubleSpinBoxTest();
251 void textBrowserTest();
253 void mdiSubWindowTest();
255 void workspaceTest();
256 void dialogButtonBoxTest();
258 void rubberBandTest();
259 void abstractScrollAreaTest();
260 void scrollAreaTest();
266 void calendarWidgetTest();
267 void dockWidgetTest();
269 void accessibleName();
279 const double Q_PI = 3.14159265358979323846;
281 QString eventName(const int 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";
301 case 0x0116: return "TableModelChanged";
302 case 0x011B: return "TextCaretMoved";
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";
327 QAccessible::State state(QWidget * const widget)
329 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget);
331 qWarning() << "Cannot get QAccessibleInterface for widget";
332 QAccessible::State state = (iface ? iface->state() : QAccessible::State());
337 class QtTestAccessibleWidget: public QWidget
341 QtTestAccessibleWidget(QWidget *parent, const char *name): QWidget(parent)
345 pal.setColor(backgroundRole(), Qt::black);//black is beautiful
351 class QtTestAccessibleWidgetIface: public QAccessibleWidget
354 QtTestAccessibleWidgetIface(QtTestAccessibleWidget *w): QAccessibleWidget(w) {}
355 QString text(QAccessible::Text t) const
357 if (t == QAccessible::Help)
358 return QString::fromLatin1("Help yourself");
359 return QAccessibleWidget::text(t);
361 static QAccessibleInterface *ifaceFactory(const QString &key, QObject *o)
363 if (key == "QtTestAccessibleWidget")
364 return new QtTestAccessibleWidgetIface(static_cast<QtTestAccessibleWidget*>(o));
369 tst_QAccessibility::tst_QAccessibility()
374 tst_QAccessibility::~tst_QAccessibility()
378 void tst_QAccessibility::onClicked()
383 void tst_QAccessibility::initTestCase()
385 QTestAccessibility::initialize();
386 QAccessible::installFactory(QtTestAccessibleWidgetIface::ifaceFactory);
389 void tst_QAccessibility::cleanupTestCase()
391 QTestAccessibility::cleanup();
394 void tst_QAccessibility::init()
396 QTestAccessibility::clearEvents();
399 void tst_QAccessibility::cleanup()
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);
409 QTestAccessibility::clearEvents();
412 void tst_QAccessibility::eventTest()
414 QPushButton* button = new QPushButton(0);
415 button->setObjectName(QString("Olaf"));
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);
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);
431 QVERIFY_EVENT(button, 0, QAccessible::ObjectHide);
436 void tst_QAccessibility::customWidget()
438 QtTestAccessibleWidget* widget = new QtTestAccessibleWidget(0, "Heinz");
440 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget);
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"));
451 void tst_QAccessibility::deletedWidget()
453 QtTestAccessibleWidget *widget = new QtTestAccessibleWidget(0, "Ralf");
454 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget);
456 QVERIFY(iface->isValid());
457 QCOMPARE(iface->object(), (QObject*)widget);
461 QVERIFY(!iface->isValid());
465 void tst_QAccessibility::statesStructTest()
467 QAccessible::State s1;
468 QVERIFY(s1.disabled == 0);
469 QVERIFY(s1.focusable == 0);
470 QVERIFY(s1.modal == 0);
472 QAccessible::State s2;
475 QVERIFY(!(s2 == s1));
478 s1 = QAccessible::State();
479 QVERIFY(!(s2 == s1));
482 QVERIFY(s1.busy == 1);
485 void tst_QAccessibility::sliderTest()
488 QSlider *slider = new QSlider(0);
489 slider->setObjectName(QString("Slidy"));
491 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(slider);
493 QVERIFY(iface->isValid());
495 QCOMPARE(iface->childCount(), 0);
496 QCOMPARE(iface->role(), QAccessible::Slider);
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());
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());
514 QTestAccessibility::clearEvents();
517 void tst_QAccessibility::navigateHierarchy()
520 QWidget *w = new QWidget(0);
521 w->setObjectName(QString("Hans"));
523 QWidget *w1 = new QWidget(w);
524 w1->setObjectName(QString("1"));
526 QWidget *w2 = new QWidget(w);
527 w2->setObjectName(QString("2"));
529 QWidget *w3 = new QWidget(w);
530 w3->setObjectName(QString("3"));
532 QWidget *w31 = new QWidget(w3);
533 w31->setObjectName(QString("31"));
536 QAccessibleInterface *target = 0;
537 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(w);
539 QVERIFY(iface->isValid());
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);
548 QVERIFY(target->isValid());
549 QCOMPARE(target->object(), (QObject*)w1);
550 QVERIFY(interfaceW1 != 0);
551 QVERIFY(interfaceW1->isValid());
552 QCOMPARE(interfaceW1->object(), (QObject*)w1);
554 delete iface; iface = 0;
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;
564 iface = target->child(1);
565 QCOMPARE(iface, (QAccessibleInterface*)0);
566 iface = target->child(0);
568 QVERIFY(iface->isValid());
569 QCOMPARE(iface->object(), (QObject*)w31);
571 iface = QAccessible::queryAccessibleInterface(w);
572 QAccessibleInterface *acc3 = iface->child(2);
573 target = acc3->child(0);
576 QCOMPARE(target->object(), (QObject*)w31);
578 iface = target->parent();
580 QVERIFY(iface->isValid());
581 QCOMPARE(iface->object(), (QObject*)w3);
582 delete iface; iface = 0;
583 delete target; target = 0;
587 QTestAccessibility::clearEvents();
590 #define QSETCOMPARE(thetypename, elements, otherelements) \
591 QCOMPARE((QSet<thetypename>() << elements), (QSet<thetypename>() << otherelements))
593 static QWidget *createWidgets()
595 QWidget *w = new QWidget();
597 QHBoxLayout *box = new QHBoxLayout(w);
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));
632 * QAbstractItemView, QGraphicsView, QScrollArea,
633 * QToolButton, QDockWidget, QFocusFrame, QMainWindow, QMenu, QMenuBar, QSizeGrip, QSplashScreen, QSplitterHandle,
634 * QStatusBar, QSvgWidget, QTabBar, QToolBar, QWorkspace, QSplitter
639 void tst_QAccessibility::accessibleName()
641 QWidget *toplevel = createWidgets();
643 #if defined(Q_OS_UNIX)
644 QCoreApplication::processEvents();
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();
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);
657 QString desc = tr("Widget Description %1").arg(i);
658 child->setAccessibleDescription(desc);
659 QCOMPARE(acc->text(QAccessible::Description), desc);
664 QTestAccessibility::clearEvents();
667 void tst_QAccessibility::textAttributes()
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>."
680 textEdit.setText(text);
681 QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&textEdit);
683 QAccessibleTextInterface *textInterface=interface->textInterface();
685 QVERIFY(textInterface);
686 QCOMPARE(textInterface->characterCount(), 112);
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;")));
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;")));
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\";")));
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;")));
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);")));
721 void tst_QAccessibility::hideShowTest()
723 QWidget * const window = new QWidget();
724 QWidget * const child = new QWidget(window);
726 QVERIFY(state(window).invisible);
727 QVERIFY(state(child).invisible);
729 QTestAccessibility::clearEvents();
731 // show() and veryfy that both window and child are not invisible and get ObjectShow events.
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();
739 // hide() and veryfy that both window and child are invisible and get ObjectHide events.
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();
748 QTestAccessibility::clearEvents();
752 void tst_QAccessibility::actionTest()
755 QCOMPARE(QAccessibleActionInterface::pressAction(), QString(QStringLiteral("Press")));
757 QWidget *widget = new QWidget;
758 widget->setFocusPolicy(Qt::NoFocus);
761 QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(widget);
763 QVERIFY(interface->isValid());
764 QAccessibleActionInterface *actions = interface->actionInterface();
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()));
775 QTestAccessibility::clearEvents();
778 QPushButton *button = new QPushButton;
780 button->clearFocus();
781 QCOMPARE(button->hasFocus(), false);
782 QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(button);
783 QAccessibleActionInterface *actions = interface->actionInterface();
786 // Make sure the "primary action" press comes first!
787 QCOMPARE(actions->actionNames(), QStringList() << QAccessibleActionInterface::pressAction() << QAccessibleActionInterface::setFocusAction());
789 actions->doAction(QAccessibleActionInterface::setFocusAction());
791 QCOMPARE(button->hasFocus(), true);
793 connect(button, SIGNAL(clicked()), this, SLOT(onClicked()));
794 QCOMPARE(click_count, 0);
795 actions->doAction(QAccessibleActionInterface::pressAction());
797 QCOMPARE(click_count, 1);
802 QTestAccessibility::clearEvents();
805 void tst_QAccessibility::applicationTest()
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);
815 void tst_QAccessibility::mainWindowTest()
817 QMainWindow *mw = new QMainWindow;
818 mw->resize(300, 200);
819 mw->show(); // triggers layout
821 QLatin1String name = QLatin1String("I am the main window");
822 mw->setWindowTitle(name);
823 QTest::qWaitForWindowShown(mw);
824 QVERIFY_EVENT(mw, 0, QAccessible::ObjectShow);
826 QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(mw);
827 QCOMPARE(interface->text(QAccessible::Name), name);
828 QCOMPARE(interface->role(), QAccessible::Window);
831 QTestAccessibility::clearEvents();
834 class CounterButton : public QPushButton {
837 CounterButton(const QString& name, QWidget* parent)
838 : QPushButton(name, parent), clickCount(0)
840 connect(this, SIGNAL(clicked(bool)), SLOT(incClickCount()));
844 void incClickCount() {
849 static QAccessibleInterface *relatedInterface(QAccessibleInterface *iface, QAccessible::RelationFlag flag)
851 typedef QPair<QAccessibleInterface *, QAccessible::Relation> RelationPair;
852 QVector<RelationPair> rels = iface->relations(flag);
854 for (int i = 1; i < rels.count(); ++i)
855 delete rels.at(i).first;
857 return rels.value(0).first;
860 void tst_QAccessibility::buttonTest()
863 window.setLayout(new QVBoxLayout);
865 // Standard push button
866 CounterButton pushButton("Ok", &window);
869 QPushButton toggleButton("Toggle", &window);
870 toggleButton.setCheckable(true);
873 QCheckBox checkBox("Check me!", &window);
876 QCheckBox tristate("Tristate!", &window);
877 tristate.setTristate(true);
880 QRadioButton radio("Radio me!", &window);
882 // standard toolbutton
883 QToolButton toolbutton(&window);
884 toolbutton.setText("Tool");
885 toolbutton.setMinimumSize(20,20);
887 // standard toolbutton
888 QToolButton toggletool(&window);
889 toggletool.setCheckable(true);
890 toggletool.setText("Toggle");
891 toggletool.setMinimumSize(20,20);
893 // test Controller/Controlled relations
895 QCheckBox toggler("Toggle me!", &window);
896 bool ok = connect(&pushButton, SIGNAL(clicked()), &toggler, SLOT(toggle()));
898 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&toggler);
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);
908 buttonIFace = QAccessible::queryAccessibleInterface(&pushButton);
909 QVERIFY(buttonIFace);
910 QCOMPARE(buttonIFace->role(), QAccessible::Button);
911 iface = relatedInterface(buttonIFace, QAccessible::Controlled);
913 QCOMPARE(iface->object(), &toggler);
918 QAccessibleInterface* interface = QAccessible::queryAccessibleInterface(&pushButton);
919 QAccessibleActionInterface* actionInterface = interface->actionInterface();
920 QVERIFY(actionInterface != 0);
921 QCOMPARE(interface->role(), QAccessible::PushButton);
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());
929 QCOMPARE(pushButton.clickCount, 1);
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());
942 QVERIFY(toggleButton.isChecked());
943 QCOMPARE(actionInterface->actionNames().at(0), QAccessibleActionInterface::uncheckAction());
944 QVERIFY(interface->state().checked);
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);
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);
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());
975 QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::uncheckAction() << QAccessibleActionInterface::setFocusAction());
976 QVERIFY(interface->state().checked);
977 QVERIFY(checkBox.isChecked());
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());
988 QCOMPARE(actionInterface->actionNames(), QStringList() << QAccessibleActionInterface::checkAction() << QAccessibleActionInterface::setFocusAction());
989 QVERIFY(interface->state().checked);
990 QVERIFY(checkBox.isChecked());
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);
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);
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"));
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);
1042 QTestAccessibility::clearEvents();
1045 void tst_QAccessibility::scrollBarTest()
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);
1053 QVERIFY(!scrollBarInterface->state().invisible);
1054 QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(scrollBar, 0, QAccessible::ObjectShow)));
1055 QTestAccessibility::clearEvents();
1058 QVERIFY(scrollBarInterface->state().invisible);
1059 QVERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(scrollBar, 0, QAccessible::ObjectHide)));
1060 QTestAccessibility::clearEvents();
1062 // Test that the left/right subcontrols are set to unavailable when the scrollBar is at the minimum/maximum.
1064 scrollBar->setMinimum(11);
1065 scrollBar->setMaximum(111);
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());
1080 const QRect scrollBarRect = scrollBarInterface->rect();
1081 QVERIFY(scrollBarRect.isValid());
1083 delete scrollBarInterface;
1086 QTestAccessibility::clearEvents();
1089 void tst_QAccessibility::tabTest()
1091 QTabBar *tabBar = new QTabBar();
1094 QAccessibleInterface * const interface = QAccessible::queryAccessibleInterface(tabBar);
1096 QCOMPARE(interface->childCount(), 2);
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);
1106 for (int i = 0; i < lots; ++i)
1107 tabBar->addTab("Foo");
1109 QAccessibleInterface *child1 = interface->child(0);
1110 QAccessibleInterface *child2 = interface->child(1);
1112 QCOMPARE(child1->role(), QAccessible::PageTab);
1114 QCOMPARE(child2->role(), QAccessible::PageTab);
1116 QVERIFY((child1->state().invisible) == false);
1119 QCoreApplication::processEvents();
1122 QVERIFY(child1->state().invisible);
1125 tabBar->setCurrentIndex(0);
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);
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);
1142 QTestAccessibility::clearEvents();
1145 void tst_QAccessibility::tabWidgetTest()
1147 QTabWidget *tabWidget = new QTabWidget();
1150 // the interface for the tab is just a container for tabbar and stacked widget
1151 QAccessibleInterface * const interface = QAccessible::queryAccessibleInterface(tabWidget);
1153 QCOMPARE(interface->childCount(), 2);
1154 QCOMPARE(interface->role(), QAccessible::Client);
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");
1162 QCOMPARE(interface->childCount(), 2);
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);
1171 QAccessibleInterface* tabButton1Interface = tabBarInterface->child(0);
1172 QVERIFY(tabButton1Interface);
1173 QCOMPARE(tabButton1Interface->role(), QAccessible::PageTab);
1174 QCOMPARE(tabButton1Interface->text(QAccessible::Name), QLatin1String("Tab 1"));
1176 QAccessibleInterface* tabButton2Interface = tabBarInterface->child(1);
1177 QVERIFY(tabButton1Interface);
1178 QCOMPARE(tabButton2Interface->role(), QAccessible::PageTab);
1179 QCOMPARE(tabButton2Interface->text(QAccessible::Name), QLatin1String("Tab 2"));
1181 QAccessibleInterface* tabButtonLeft = tabBarInterface->child(2);
1182 QVERIFY(tabButtonLeft);
1183 QCOMPARE(tabButtonLeft->role(), QAccessible::PushButton);
1184 QCOMPARE(tabButtonLeft->text(QAccessible::Name), QLatin1String("Scroll Left"));
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;
1195 QAccessibleInterface* stackWidgetInterface = interface->child(0);
1196 QVERIFY(stackWidgetInterface);
1197 QCOMPARE(stackWidgetInterface->childCount(), 2);
1198 QCOMPARE(stackWidgetInterface->role(), QAccessible::LayeredPane);
1200 QAccessibleInterface* stackChild1Interface = stackWidgetInterface->child(0);
1201 QVERIFY(stackChild1Interface);
1203 QCOMPARE(stackChild1Interface->childCount(), 0);
1205 QCOMPARE(stackChild1Interface->role(), QAccessible::StaticText);
1206 QCOMPARE(stackChild1Interface->text(QAccessible::Name), QLatin1String("Page 1"));
1207 QCOMPARE(label1, stackChild1Interface->object());
1209 // Navigation in stack widgets should be consistent
1210 QAccessibleInterface* parent = stackChild1Interface->parent();
1213 QCOMPARE(parent->childCount(), 2);
1215 QCOMPARE(parent->role(), QAccessible::LayeredPane);
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));
1225 parent = stackChild2Interface->parent();
1228 QCOMPARE(parent->childCount(), 2);
1230 QCOMPARE(parent->role(), QAccessible::LayeredPane);
1233 delete tabBarInterface;
1234 delete stackChild1Interface;
1235 delete stackChild2Interface;
1236 delete stackWidgetInterface;
1239 QTestAccessibility::clearEvents();
1242 void tst_QAccessibility::menuTest()
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"));
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");
1268 mw.menuBar()->addSeparator();
1270 QMenu *help = mw.menuBar()->addMenu("&Help");
1271 help->addAction("&Contents");
1272 help->addAction("&About");
1274 mw.menuBar()->addAction("Action!");
1276 mw.show(); // triggers layout
1279 QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(mw.menuBar());
1280 QCOMPARE(verifyHierarchy(interface), 0);
1283 QCOMPARE(interface->childCount(), 5);
1284 QCOMPARE(interface->role(), QAccessible::MenuBar);
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);
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);
1299 if (!IsValidCEPlatform())
1300 QSKIP("Tests do not work on Mobile platforms due to native menus");
1302 QCOMPARE(mw.mapFromGlobal(interface->rect().topLeft()), mw.menuBar()->geometry().topLeft());
1303 QCOMPARE(interface->rect().size(), mw.menuBar()->size());
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()));
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!"));
1318 // TODO: Currently not working, task to fix is #100019.
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());
1327 QVERIFY(iFile->actionInterface());
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());
1334 bool menuFade = qApp->isEffectEnabled(Qt::UI_FadeMenu);
1335 int menuFadeDelay = 300;
1336 iFile->actionInterface()->doAction(QAccessibleActionInterface::showMenuAction());
1338 QTest::qWait(menuFadeDelay);
1339 QVERIFY(file->isVisible() && !edit->isVisible() && !help->isVisible());
1340 iEdit->actionInterface()->doAction(QAccessibleActionInterface::showMenuAction());
1342 QTest::qWait(menuFadeDelay);
1343 QVERIFY(!file->isVisible() && edit->isVisible() && !help->isVisible());
1344 iHelp->actionInterface()->doAction(QAccessibleActionInterface::showMenuAction());
1346 QTest::qWait(menuFadeDelay);
1347 QVERIFY(!file->isVisible() && !edit->isVisible() && help->isVisible());
1348 iAction->actionInterface()->doAction(QAccessibleActionInterface::showMenuAction());
1350 QTest::qWait(menuFadeDelay);
1351 QVERIFY(!file->isVisible() && !edit->isVisible() && !help->isVisible());
1353 QVERIFY(interface->actionInterface());
1354 QCOMPARE(interface->actionInterface()->actionNames(), QStringList());
1356 interface = QAccessible::queryAccessibleInterface(file);
1357 QCOMPARE(interface->childCount(), 5);
1358 QCOMPARE(interface->role(), QAccessible::PopupMenu);
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);
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());
1377 QAccessibleInterface *iface = 0;
1378 QAccessibleInterface *iface2 = 0;
1380 // traverse siblings with navigate(Sibling, ...)
1381 iface = interface->child(0);
1383 QCOMPARE(iface->role(), QAccessible::MenuItem);
1385 QAccessible::Role fileRoles[5] = {
1386 QAccessible::MenuItem,
1387 QAccessible::MenuItem,
1388 QAccessible::MenuItem,
1389 QAccessible::Separator,
1390 QAccessible::MenuItem
1392 for (int child = 0; child < 5; ++child) {
1393 iface2 = interface->child(child);
1395 QCOMPARE(iface2->role(), fileRoles[child]);
1401 iface = interface->child(0);
1403 QCOMPARE(iface->role(), QAccessible::MenuItem);
1406 iface2 = iface->child(0);
1410 QCOMPARE(iface->role(), QAccessible::PopupMenu);
1412 // "Text file" menu item
1413 iface2 = iface->child(0);
1417 QCOMPARE(iface->role(), QAccessible::MenuItem);
1421 // move mouse pointer away, since that might influence the
1423 QTest::mouseMove(&mw, QPoint(-1, -1));
1426 QTest::qWait(menuFadeDelay);
1428 iFile->actionInterface()->doAction(QAccessibleActionInterface::showMenuAction());
1429 iFileNew->actionInterface()->doAction(QAccessibleActionInterface::showMenuAction());
1431 QVERIFY(file->isVisible());
1432 QVERIFY(fileNew->isVisible());
1433 QVERIFY(!edit->isVisible());
1434 QVERIFY(!help->isVisible());
1436 QTestAccessibility::clearEvents();
1443 delete iFileSeparator;
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();
1454 QCOMPARE(iface2->role(), QAccessible::Application);
1462 QTestAccessibility::clearEvents();
1465 void tst_QAccessibility::spinBoxTest()
1467 QSpinBox * const spinBox = new QSpinBox();
1468 spinBox->setValue(3);
1471 QAccessibleInterface * const interface = QAccessible::queryAccessibleInterface(spinBox);
1473 QCOMPARE(interface->role(), QAccessible::SpinBox);
1475 const QRect widgetRect = spinBox->geometry();
1476 const QRect accessibleRect = interface->rect();
1477 QCOMPARE(accessibleRect, widgetRect);
1478 QCOMPARE(interface->text(QAccessible::Value), QLatin1String("3"));
1480 // one child, the line edit
1481 const int numChildren = interface->childCount();
1482 QCOMPARE(numChildren, 1);
1483 QAccessibleInterface *lineEdit = interface->child(0);
1485 QCOMPARE(lineEdit->role(), QAccessible::EditableText);
1486 QCOMPARE(lineEdit->text(QAccessible::Value), QLatin1String("3"));
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);
1495 spinBox->setFocus();
1496 QTestAccessibility::clearEvents();
1497 QTest::keyPress(spinBox, Qt::Key_Up);
1499 EventList events = QTestAccessibility::events();
1500 QTestAccessibilityEvent expectedEvent(spinBox, 0, (int)QAccessible::ValueChanged);
1501 QVERIFY(events.contains(expectedEvent));
1503 QTestAccessibility::clearEvents();
1506 void tst_QAccessibility::doubleSpinBoxTest()
1508 QDoubleSpinBox *doubleSpinBox = new QDoubleSpinBox;
1509 doubleSpinBox->show();
1511 QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(doubleSpinBox);
1514 const QRect widgetRect = doubleSpinBox->geometry();
1515 const QRect accessibleRect = interface->rect();
1516 QCOMPARE(accessibleRect, widgetRect);
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());
1527 delete doubleSpinBox;
1528 QTestAccessibility::clearEvents();
1531 void tst_QAccessibility::textEditTest()
1537 QString text = "hello world\nhow are you today?\n";
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()));
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"));
1561 QTestAccessibility::clearEvents();
1564 void tst_QAccessibility::textBrowserTest()
1567 QTextBrowser textBrowser;
1568 QString text = QLatin1String("Hello world\nhow are you today?\n");
1569 textBrowser.setText(text);
1572 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&textBrowser);
1574 QCOMPARE(iface->role(), QAccessible::StaticText);
1575 QCOMPARE(iface->text(QAccessible::Value), text);
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);
1586 QTestAccessibility::clearEvents();
1589 void tst_QAccessibility::mdiAreaTest()
1593 mdiArea.resize(400,300);
1595 const int subWindowCount = 3;
1596 for (int i = 0; i < subWindowCount; ++i)
1597 mdiArea.addSubWindow(new QWidget, Qt::Dialog)->show();
1599 QList<QMdiSubWindow *> subWindows = mdiArea.subWindowList();
1600 QCOMPARE(subWindows.count(), subWindowCount);
1602 QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&mdiArea);
1604 QCOMPARE(interface->childCount(), subWindowCount);
1607 QTestAccessibility::clearEvents();
1610 void tst_QAccessibility::mdiSubWindowTest()
1615 qApp->setActiveWindow(&mdiArea);
1616 #if defined(Q_OS_UNIX)
1617 QCoreApplication::processEvents();
1621 const int subWindowCount = 5;
1622 for (int i = 0; i < subWindowCount; ++i) {
1623 QMdiSubWindow *window = mdiArea.addSubWindow(new QPushButton("QAccessibilityTest"));
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.
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();
1638 QList<QMdiSubWindow *> subWindows = mdiArea.subWindowList();
1639 QCOMPARE(subWindows.count(), subWindowCount);
1641 QMdiSubWindow *testWindow = subWindows.at(3);
1642 QVERIFY(testWindow);
1643 QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(testWindow);
1647 QCOMPARE(interface->childCount(), 1);
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"));
1656 mdiArea.setActiveSubWindow(testWindow);
1659 QAccessible::State state;
1660 state.focusable = true;
1661 state.focused = true;
1662 state.movable = true;
1663 state.sizeable = true;
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);
1688 const QPoint globalPos = testWindow->mapToGlobal(QPoint(0, 0));
1689 QCOMPARE(interface->rect(), QRect(globalPos, testWindow->size()));
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()));
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"));
1711 testWindow->widget()->hide();
1712 QCOMPARE(interface->childAt(globalWidgetPos.x(), globalWidgetPos.y()), static_cast<QAccessibleInterface*>(0));
1715 QTestAccessibility::clearEvents();
1718 void tst_QAccessibility::lineEditTest()
1720 QLineEdit *le = new QLineEdit;
1721 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(le);
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());
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);
1752 QWidget *toplevel = new QWidget;
1753 le->setParent(toplevel);
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());
1763 QLineEdit *le2 = new QLineEdit(toplevel);
1766 le2->activateWindow();
1768 le->setFocus(Qt::TabFocusReason);
1769 QTestAccessibility::clearEvents();
1770 le2->setFocus(Qt::TabFocusReason);
1771 QTRY_VERIFY(QTestAccessibility::events().contains(QTestAccessibilityEvent(le2, 0, QAccessible::Focus)));
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"));
1781 QTestAccessibility::clearEvents();
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();
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();
1796 QCOMPARE(textIface->text(0, 8), QString::fromLatin1("I always"));
1797 QCOMPARE(textIface->textAtOffset(0, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1("I"));
1800 QCOMPARE(textIface->textBeforeOffset(0, QAccessible2::CharBoundary,&start,&end), QString());
1801 QCOMPARE(textIface->textAfterOffset(0, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1(" "));
1805 QCOMPARE(textIface->textAtOffset(5, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1("a"));
1808 QCOMPARE(textIface->textBeforeOffset(5, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1("w"));
1809 QCOMPARE(textIface->textAfterOffset(5, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1("y"));
1811 QCOMPARE(textIface->textAtOffset(5, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("always"));
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"));
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. "));
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. "));
1830 QCOMPARE(textIface->textAtOffset(5, QAccessible2::ParagraphBoundary,&start,&end), cite);
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);
1838 QTestAccessibility::clearEvents();
1841 void tst_QAccessibility::workspaceTest()
1844 QWorkspace workspace;
1845 workspace.resize(400,300);
1847 const int subWindowCount = 3;
1848 for (int i = 0; i < subWindowCount; ++i) {
1849 QWidget *window = workspace.addWindow(new QWidget);
1851 window->move(window->x() + 1, window->y());
1853 window->resize(70, window->height());
1856 QWidgetList subWindows = workspace.windowList();
1857 QCOMPARE(subWindows.count(), subWindowCount);
1859 QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&workspace);
1861 QCOMPARE(interface->childCount(), subWindowCount);
1864 QTestAccessibility::clearEvents();
1867 bool accessibleInterfaceLeftOf(const QAccessibleInterface *a1, const QAccessibleInterface *a2)
1869 return a1->rect().x() < a2->rect().x();
1872 bool accessibleInterfaceAbove(const QAccessibleInterface *a1, const QAccessibleInterface *a2)
1874 return a1->rect().y() < a2->rect().y();
1877 void tst_QAccessibility::dialogButtonBoxTest()
1880 QDialogButtonBox box(QDialogButtonBox::Reset |
1881 QDialogButtonBox::Help |
1882 QDialogButtonBox::Ok, Qt::Horizontal);
1885 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&box);
1888 #if defined(Q_OS_UNIX)
1889 QCoreApplication::processEvents();
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);
1901 QVector<QAccessibleInterface *> buttons;
1902 for (int i = 0; i < iface->childCount(); ++i)
1903 buttons << iface->child(i);
1905 qSort(buttons.begin(), buttons.end(), accessibleInterfaceLeftOf);
1907 for (int i = 0; i < buttons.count(); ++i)
1908 actualOrder << buttons.at(i)->text(QAccessible::Name);
1910 QStringList expectedOrder;
1911 QDialogButtonBox::ButtonLayout btnlout =
1912 QDialogButtonBox::ButtonLayout(QApplication::style()->styleHint(QStyle::SH_DialogButtonLayout));
1914 case QDialogButtonBox::WinLayout:
1915 expectedOrder << QDialogButtonBox::tr("Reset")
1916 << QDialogButtonBox::tr("OK")
1917 << QDialogButtonBox::tr("Help");
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");
1927 QCOMPARE(actualOrder, expectedOrder);
1929 QApplication::processEvents();
1930 QTestAccessibility::clearEvents();
1934 QDialogButtonBox box(QDialogButtonBox::Reset |
1935 QDialogButtonBox::Help |
1936 QDialogButtonBox::Ok, Qt::Horizontal);
1939 // Test up and down navigation
1940 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&box);
1942 box.setOrientation(Qt::Vertical);
1944 #if defined(Q_OS_UNIX)
1945 QCoreApplication::processEvents();
1949 QApplication::processEvents();
1950 QStringList actualOrder;
1952 QVector<QAccessibleInterface *> buttons;
1953 for (int i = 0; i < iface->childCount(); ++i)
1954 buttons << iface->child(i);
1956 qSort(buttons.begin(), buttons.end(), accessibleInterfaceAbove);
1958 for (int i = 0; i < buttons.count(); ++i)
1959 actualOrder << buttons.at(i)->text(QAccessible::Name);
1961 QStringList expectedOrder;
1962 expectedOrder << QDialogButtonBox::tr("OK")
1963 << QDialogButtonBox::tr("Reset")
1964 << QDialogButtonBox::tr("Help");
1966 QCOMPARE(actualOrder, expectedOrder);
1968 QApplication::processEvents();
1971 QTestAccessibility::clearEvents();
1974 void tst_QAccessibility::dialTest()
1978 dial.setMinimum(23);
1979 dial.setMaximum(121);
1981 QCOMPARE(dial.value(), 42);
1984 QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&dial);
1986 QCOMPARE(interface->childCount(), 0);
1988 QCOMPARE(interface->text(QAccessible::Value), QString::number(dial.value()));
1989 QCOMPARE(interface->rect(), dial.geometry());
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);
1997 QCOMPARE(valueIface->currentValue().toInt(), dial.value());
1999 QCOMPARE(valueIface->currentValue().toInt(), dial.value());
2001 QCOMPARE(valueIface->currentValue().toInt(), dial.value());
2002 valueIface->setCurrentValue(77);
2003 QCOMPARE(77, dial.value());
2005 QTestAccessibility::clearEvents();
2008 void tst_QAccessibility::rubberBandTest()
2010 QRubberBand rubberBand(QRubberBand::Rectangle);
2011 QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&rubberBand);
2013 QCOMPARE(interface->role(), QAccessible::Border);
2015 QTestAccessibility::clearEvents();
2018 void tst_QAccessibility::abstractScrollAreaTest()
2021 QAbstractScrollArea abstractScrollArea;
2023 QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&abstractScrollArea);
2025 QVERIFY(!interface->rect().isValid());
2026 QCOMPARE(interface->childAt(200, 200), static_cast<QAccessibleInterface*>(0));
2028 abstractScrollArea.resize(400, 400);
2029 abstractScrollArea.show();
2030 #if defined(Q_OS_UNIX)
2031 QCoreApplication::processEvents();
2034 const QRect globalGeometry = QRect(abstractScrollArea.mapToGlobal(QPoint(0, 0)),
2035 abstractScrollArea.size());
2038 QCOMPARE(interface->childCount(), 1);
2039 QWidget *viewport = abstractScrollArea.viewport();
2041 QVERIFY(verifyChild(viewport, interface, 0, globalGeometry));
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));
2050 // Horizontal scrollBar widgets.
2051 QLabel *secondLeftLabel = new QLabel(QLatin1String("L2"));
2052 abstractScrollArea.addScrollBarWidget(secondLeftLabel, Qt::AlignLeft);
2053 QCOMPARE(interface->childCount(), 2);
2055 QLabel *firstLeftLabel = new QLabel(QLatin1String("L1"));
2056 abstractScrollArea.addScrollBarWidget(firstLeftLabel, Qt::AlignLeft);
2057 QCOMPARE(interface->childCount(), 2);
2059 QLabel *secondRightLabel = new QLabel(QLatin1String("R2"));
2060 abstractScrollArea.addScrollBarWidget(secondRightLabel, Qt::AlignRight);
2061 QCOMPARE(interface->childCount(), 2);
2063 QLabel *firstRightLabel = new QLabel(QLatin1String("R1"));
2064 abstractScrollArea.addScrollBarWidget(firstRightLabel, Qt::AlignRight);
2065 QCOMPARE(interface->childCount(), 2);
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));
2074 // Vertical scrollBar widgets.
2075 QLabel *secondTopLabel = new QLabel(QLatin1String("T2"));
2076 abstractScrollArea.addScrollBarWidget(secondTopLabel, Qt::AlignTop);
2077 QCOMPARE(interface->childCount(), 3);
2079 QLabel *firstTopLabel = new QLabel(QLatin1String("T1"));
2080 abstractScrollArea.addScrollBarWidget(firstTopLabel, Qt::AlignTop);
2081 QCOMPARE(interface->childCount(), 3);
2083 QLabel *secondBottomLabel = new QLabel(QLatin1String("B2"));
2084 abstractScrollArea.addScrollBarWidget(secondBottomLabel, Qt::AlignBottom);
2085 QCOMPARE(interface->childCount(), 3);
2087 QLabel *firstBottomLabel = new QLabel(QLatin1String("B1"));
2088 abstractScrollArea.addScrollBarWidget(firstBottomLabel, Qt::AlignBottom);
2089 QCOMPARE(interface->childCount(), 3);
2092 abstractScrollArea.setCornerWidget(new QLabel(QLatin1String("C")));
2093 QCOMPARE(interface->childCount(), 4);
2094 QWidget *cornerWidget = abstractScrollArea.cornerWidget();
2095 QVERIFY(verifyChild(cornerWidget, interface, 3, globalGeometry));
2097 QCOMPARE(verifyHierarchy(interface), 0);
2102 QTestAccessibility::clearEvents();
2105 void tst_QAccessibility::scrollAreaTest()
2108 QScrollArea scrollArea;
2110 #if defined(Q_OS_UNIX)
2111 QCoreApplication::processEvents();
2114 QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&scrollArea);
2116 QCOMPARE(interface->childCount(), 1); // The viewport.
2119 QTestAccessibility::clearEvents();
2122 void tst_QAccessibility::listTest()
2125 QListWidget *listView = new QListWidget;
2126 listView->addItem("Oslo");
2127 listView->addItem("Berlin");
2128 listView->addItem("Brisbane");
2129 listView->resize(400,400);
2131 QTest::qWait(1); // Need this for indexOfchild to work.
2132 QCoreApplication::processEvents();
2135 QAIPtr iface = QAIPtr(QAccessible::queryAccessibleInterface(listView));
2136 QCOMPARE(verifyHierarchy(iface.data()), 0);
2138 QCOMPARE((int)iface->role(), (int)QAccessible::List);
2139 QCOMPARE(iface->childCount(), 3);
2142 QAIPtr child1 = QAIPtr(iface->child(0));
2144 QCOMPARE(iface->indexOfChild(child1.data()), 0);
2145 QCOMPARE(child1->text(QAccessible::Name), QString("Oslo"));
2146 QCOMPARE(child1->role(), QAccessible::ListItem);
2148 QAIPtr child2 = QAIPtr(iface->child(1));
2150 QCOMPARE(iface->indexOfChild(child2.data()), 1);
2151 QCOMPARE(child2->text(QAccessible::Name), QString("Berlin"));
2153 QAIPtr child3 = QAIPtr(iface->child(2));
2155 QCOMPARE(iface->indexOfChild(child3.data()), 2);
2156 QCOMPARE(child3->text(QAccessible::Name), QString("Brisbane"));
2158 QTestAccessibility::clearEvents();
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)));
2168 listView->addItem("Munich");
2169 QCOMPARE(iface->childCount(), 4);
2172 QAccessibleTableInterface *table2 = iface->tableInterface();
2174 QCOMPARE(table2->columnCount(), 1);
2175 QCOMPARE(table2->rowCount(), 4);
2176 QAIPtr cell1 = QAIPtr(table2->cellAt(0,0));
2178 QCOMPARE(cell1->text(QAccessible::Name), QString("Oslo"));
2180 QAIPtr cell4 = QAIPtr(table2->cellAt(3,0));
2182 QCOMPARE(cell4->text(QAccessible::Name), QString("Munich"));
2183 QCOMPARE(cell4->role(), QAccessible::ListItem);
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*>());
2194 QCOMPARE(QAIPtr(cellInterface->table())->object(), listView);
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());
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);
2213 QTestAccessibility::clearEvents();
2216 void tst_QAccessibility::treeTest()
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);
2225 QTreeWidgetItem *root1 = new QTreeWidgetItem;
2226 root1->setText(0, "Spain");
2227 treeView->addTopLevelItem(root1);
2229 QTreeWidgetItem *item1 = new QTreeWidgetItem;
2230 item1->setText(0, "Picasso");
2231 item1->setText(1, "Guernica");
2232 root1->addChild(item1);
2234 QTreeWidgetItem *item2 = new QTreeWidgetItem;
2235 item2->setText(0, "Tapies");
2236 item2->setText(1, "Ambrosia");
2237 root1->addChild(item2);
2239 QTreeWidgetItem *root2 = new QTreeWidgetItem;
2240 root2->setText(0, "Austria");
2241 treeView->addTopLevelItem(root2);
2243 QTreeWidgetItem *item3 = new QTreeWidgetItem;
2244 item3->setText(0, "Klimt");
2245 item3->setText(1, "The Kiss");
2246 root2->addChild(item3);
2248 treeView->resize(400,400);
2251 QCoreApplication::processEvents();
2254 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(treeView);
2255 QCOMPARE(verifyHierarchy(iface), 0);
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);
2261 QAccessibleInterface *header1 = 0;
2262 header1 = iface->child(0);
2264 QCOMPARE(iface->indexOfChild(header1), 0);
2265 QCOMPARE(header1->text(QAccessible::Name), QString("Artist"));
2266 QCOMPARE(header1->role(), QAccessible::ColumnHeader);
2269 QAccessibleInterface *child1 = 0;
2270 child1 = iface->child(2);
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));
2278 QAccessibleInterface *child2 = 0;
2279 child2 = iface->child(4);
2281 QCOMPARE(iface->indexOfChild(child2), 4);
2282 QCOMPARE(child2->text(QAccessible::Name), QString("Austria"));
2285 QTestAccessibility::clearEvents();
2288 QAccessibleTableInterface *table2 = iface->tableInterface();
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"));
2308 treeView->expandAll();
2310 // Need this for indexOfchild to work.
2311 QCoreApplication::processEvents();
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
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);
2328 QCOMPARE(table2->columnDescription(0), QString("Artist"));
2329 QCOMPARE(table2->columnDescription(1), QString("Work"));
2332 QTestAccessibility::clearEvents();
2335 void tst_QAccessibility::tableTest()
2337 QTableWidget *tableView = new QTableWidget(3, 3);
2338 tableView->setColumnCount(3);
2339 QStringList hHeader;
2340 hHeader << "h1" << "h2" << "h3";
2341 tableView->setHorizontalHeaderLabels(hHeader);
2343 QStringList vHeader;
2344 vHeader << "v1" << "v2" << "v3";
2345 tableView->setVerticalHeaderLabels(vHeader);
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);
2353 tableView->resize(600,600);
2355 QTest::qWait(1); // Need this for indexOfchild to work.
2356 QCoreApplication::processEvents();
2359 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(tableView);
2360 QCOMPARE(verifyHierarchy(iface), 0);
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
2366 QAccessibleInterface *cornerButton = iface->child(0);
2367 QVERIFY(cornerButton);
2368 QCOMPARE(iface->indexOfChild(cornerButton), 0);
2369 QCOMPARE(cornerButton->role(), QAccessible::Pane);
2370 delete cornerButton;
2372 QAccessibleInterface *child1 = iface->child(2);
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));
2380 QAccessibleInterface *child2 = iface->child(10);
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);
2389 QAccessibleInterface *child3 = iface->child(11);
2390 QCOMPARE(iface->indexOfChild(child3), 11);
2391 QCOMPARE(child3->text(QAccessible::Name), QString("1.2"));
2394 QTestAccessibility::clearEvents();
2397 QAccessibleTableInterface *table2 = iface->tableInterface();
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);
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);
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);
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"));
2435 QTestAccessibility::clearEvents();
2438 void tst_QAccessibility::calendarWidgetTest()
2440 #ifndef QT_NO_CALENDARWIDGET
2442 QCalendarWidget calendarWidget;
2444 QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&calendarWidget);
2446 QCOMPARE(interface->role(), QAccessible::Table);
2447 QVERIFY(!interface->rect().isValid());
2448 QCOMPARE(interface->childAt(200, 200), static_cast<QAccessibleInterface*>(0));
2450 calendarWidget.resize(400, 300);
2451 calendarWidget.show();
2452 #if defined(Q_OS_UNIX)
2453 QCoreApplication::processEvents();
2457 // 1 = navigationBar, 2 = view.
2458 QCOMPARE(interface->childCount(), 2);
2460 const QRect globalGeometry = QRect(calendarWidget.mapToGlobal(QPoint(0, 0)),
2461 calendarWidget.size());
2462 QCOMPARE(interface->rect(), globalGeometry);
2464 QWidget *navigationBar = 0;
2465 foreach (QObject *child, calendarWidget.children()) {
2466 if (child->objectName() == QLatin1String("qt_calendar_navigationbar")) {
2467 navigationBar = static_cast<QWidget *>(child);
2471 QVERIFY(navigationBar);
2472 QVERIFY(verifyChild(navigationBar, interface, 0, globalGeometry));
2474 QAbstractItemView *calendarView = 0;
2475 foreach (QObject *child, calendarWidget.children()) {
2476 if (child->objectName() == QLatin1String("qt_calendar_calendarview")) {
2477 calendarView = static_cast<QAbstractItemView *>(child);
2481 QVERIFY(calendarView);
2482 QVERIFY(verifyChild(calendarView, interface, 1, globalGeometry));
2484 // Hide navigation bar.
2485 calendarWidget.setNavigationBarVisible(false);
2486 QCOMPARE(interface->childCount(), 1);
2487 QVERIFY(!navigationBar->isVisible());
2489 QVERIFY(verifyChild(calendarView, interface, 0, globalGeometry));
2491 // Show navigation bar.
2492 calendarWidget.setNavigationBarVisible(true);
2493 QCOMPARE(interface->childCount(), 2);
2494 QVERIFY(navigationBar->isVisible());
2496 // Navigate to the navigation bar via Child.
2497 QAccessibleInterface *navigationBarInterface = interface->child(0);
2498 QVERIFY(navigationBarInterface);
2499 QCOMPARE(navigationBarInterface->object(), (QObject*)navigationBar);
2501 // Navigate to the view via Child.
2502 QAccessibleInterface *calendarViewInterface = interface->child(1);
2503 QVERIFY(calendarViewInterface);
2504 QCOMPARE(calendarViewInterface->object(), (QObject*)calendarView);
2506 QVERIFY(!interface->child(-1));
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;
2517 QTestAccessibility::clearEvents();
2518 #endif // QT_NO_CALENDARWIDGET
2521 void tst_QAccessibility::dockWidgetTest()
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"));
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);
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);
2542 mw->resize(600,400);
2544 #if defined(Q_OS_UNIX)
2545 QCoreApplication::processEvents();
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) {
2564 QCOMPARE(accDock1->role(), QAccessible::Window);
2566 QAccessibleInterface *dock1TitleBar = accDock1->child(0);
2567 QCOMPARE(dock1TitleBar->role(), QAccessible::TitleBar);
2568 QVERIFY(accDock1->rect().contains(dock1TitleBar->rect()));
2569 delete dock1TitleBar;
2571 QPoint globalPos = dock1->mapToGlobal(QPoint(0,0));
2572 globalPos.rx()+=5; //### query style
2574 QAccessibleInterface *childAt = accDock1->childAt(globalPos.x(), globalPos.y()); //###
2575 QCOMPARE(childAt->role(), QAccessible::TitleBar);
2576 int index = accDock1->indexOfChild(childAt);
2578 QAccessibleInterface *accTitleBar = accDock1->child(index);
2580 QCOMPARE(accTitleBar->role(), QAccessible::TitleBar);
2581 QCOMPARE(accDock1->indexOfChild(accTitleBar), 0);
2582 QAccessibleInterface *acc;
2583 acc = accTitleBar->parent();
2585 QCOMPARE(acc->role(), QAccessible::Window);
2595 QTestAccessibility::clearEvents();
2596 #endif // QT_NO_DOCKWIDGET
2599 void tst_QAccessibility::comboBoxTest()
2601 #if defined(Q_OS_WINCE)
2602 if (!IsValidCEPlatform())
2603 QSKIP("Test skipped on Windows Mobile test hardware");
2605 { // not editable combobox
2607 combo.addItems(QStringList() << "one" << "two" << "three");
2609 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&combo);
2610 QCOMPARE(verifyHierarchy(iface), 0);
2612 QCOMPARE(iface->role(), QAccessible::ComboBox);
2613 QCOMPARE(iface->childCount(), 1);
2616 QCOMPARE(iface->text(QAccessible::Name), QLatin1String("one"));
2618 QCOMPARE(iface->text(QAccessible::Value), QLatin1String("one"));
2619 combo.setCurrentIndex(2);
2621 QCOMPARE(iface->text(QAccessible::Name), QLatin1String("three"));
2623 QCOMPARE(iface->text(QAccessible::Value), QLatin1String("three"));
2625 QAccessibleInterface *listIface = iface->child(0);
2626 QCOMPARE(listIface->role(), QAccessible::List);
2627 QCOMPARE(listIface->childCount(), 3);
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());
2638 { // editable combobox
2639 QComboBox editableCombo;
2640 editableCombo.show();
2641 editableCombo.setEditable(true);
2642 editableCombo.addItems(QStringList() << "foo" << "bar" << "baz");
2644 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&editableCombo);
2645 QCOMPARE(verifyHierarchy(iface), 0);
2647 QCOMPARE(iface->role(), QAccessible::ComboBox);
2648 QCOMPARE(iface->childCount(), 2);
2650 QAccessibleInterface *listIface = iface->child(0);
2651 QCOMPARE(listIface->role(), QAccessible::List);
2652 QAccessibleInterface *editIface = iface->child(1);
2653 QCOMPARE(editIface->role(), QAccessible::EditableText);
2660 QTestAccessibility::clearEvents();
2663 void tst_QAccessibility::labelTest()
2665 QString text = "Hello World";
2666 QLabel *label = new QLabel(text);
2669 #if defined(Q_OS_UNIX)
2670 QCoreApplication::processEvents();
2674 QAccessibleInterface *acc_label = QAccessible::queryAccessibleInterface(label);
2677 QCOMPARE(acc_label->text(QAccessible::Name), text);
2681 QTestAccessibility::clearEvents();
2683 QPixmap testPixmap(50, 50);
2687 imageLabel.setPixmap(testPixmap);
2688 imageLabel.setToolTip("Test Description");
2690 acc_label = QAccessible::queryAccessibleInterface(&imageLabel);
2693 QAccessibleImageInterface *imageInterface = acc_label->imageInterface();
2694 QVERIFY(imageInterface);
2696 QCOMPARE(imageInterface->imageSize(), testPixmap.size());
2697 QCOMPARE(imageInterface->imageDescription(), QString::fromLatin1("Test Description"));
2698 QCOMPARE(imageInterface->imagePosition(QAccessible2::RelativeToParent), imageLabel.geometry());
2702 QTestAccessibility::clearEvents();
2705 void tst_QAccessibility::accelerators()
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);
2713 label->setBuddy(le);
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());
2731 #if !defined(QT_NO_DEBUG) && !defined(Q_OS_MAC)
2732 QTest::ignoreMessage(QtWarningMsg, "QKeySequence::mnemonic: \"Q &A&B\" contains multiple occurrences of '&'");
2734 label->setText(tr("Q &A&B"));
2735 QCOMPARE(accLineEdit->text(QAccessible::Accelerator), QKeySequence(Qt::ALT).toString(QKeySequence::NativeText) + QLatin1String("A"));
2737 #if defined(Q_OS_UNIX)
2738 QCoreApplication::processEvents();
2742 QTestAccessibility::clearEvents();
2745 QTEST_MAIN(tst_QAccessibility)
2746 #include "tst_qaccessibility.moc"