summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/accessible/widgets/qaccessiblewidgets.cpp228
-rw-r--r--src/plugins/accessible/widgets/qaccessiblewidgets.h23
-rw-r--r--src/widgets/widgets/qdockwidget.cpp10
-rw-r--r--tests/auto/other/qaccessibility/tst_qaccessibility.cpp133
4 files changed, 144 insertions, 250 deletions
diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
index cbb3092b1d..79a5c82fe0 100644
--- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
+++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
@@ -558,37 +558,56 @@ QWidget *QAccessibleCalendarWidget::navigationBar() const
#endif // QT_NO_CALENDARWIDGET
#ifndef QT_NO_DOCKWIDGET
+
+// Dock Widget - order of children:
+// - Content widget
+// - Float button
+// - Close button
+// If there is a custom title bar widget, that one becomes child 1, after the content 0
+// (in that case the buttons are ignored)
QAccessibleDockWidget::QAccessibleDockWidget(QWidget *widget)
: QAccessibleWidget(widget, QAccessible::Window)
{
+}
+QDockWidgetLayout *QAccessibleDockWidget::dockWidgetLayout() const
+{
+ return qobject_cast<QDockWidgetLayout*>(dockWidget()->layout());
}
-QAccessibleInterface *QAccessibleDockWidget::child(int index) const
+int QAccessibleDockWidget::childCount() const
{
- if (index == 0) {
- return new QAccessibleTitleBar(dockWidget());
- } else if (index == 1 && dockWidget()->widget()) {
- return QAccessible::queryAccessibleInterface(dockWidget()->widget());
+ if (dockWidget()->titleBarWidget()) {
+ return dockWidget()->widget() ? 2 : 1;
}
- return 0;
+ return dockWidgetLayout()->count();
}
-int QAccessibleDockWidget::childCount() const
+QAccessibleInterface *QAccessibleDockWidget::child(int index) const
{
- return dockWidget()->widget() ? 2 : 1;
+ if (dockWidget()->titleBarWidget()) {
+ if ((!dockWidget()->widget() && index == 0) || (index == 1))
+ return QAccessible::queryAccessibleInterface(dockWidget()->titleBarWidget());
+ if (index == 0)
+ return QAccessible::queryAccessibleInterface(dockWidget()->widget());
+ } else {
+ QLayoutItem *item = dockWidgetLayout()->itemAt(index);
+ if (item)
+ return QAccessible::queryAccessibleInterface(item->widget());
+ }
+ return 0;
}
int QAccessibleDockWidget::indexOfChild(const QAccessibleInterface *child) const
{
- if (child) {
- if (child->role() == QAccessible::TitleBar) {
- return 0;
- } else {
- return 1; // FIXME
- }
+ if (!child || !child->object() || child->object()->parent() != object())
+ return -1;
+
+ if (dockWidget()->titleBarWidget() == child->object()) {
+ return dockWidget()->widget() ? 1 : 0;
}
- return -1;
+
+ return dockWidgetLayout()->indexOf(qobject_cast<QWidget*>(child->object()));
}
QRect QAccessibleDockWidget::rect() const
@@ -610,190 +629,13 @@ QDockWidget *QAccessibleDockWidget::dockWidget() const
return static_cast<QDockWidget *>(object());
}
-////
-// QAccessibleTitleBar
-////
-QAccessibleTitleBar::QAccessibleTitleBar(QDockWidget *widget)
- : m_dockWidget(widget)
-{
-
-}
-
-QAccessibleInterface *QAccessibleTitleBar::parent() const
-{
- return new QAccessibleDockWidget(dockWidget());
-}
-
-QAccessibleInterface *QAccessibleTitleBar::child(int index) const
-{
- if (index >= 0) {
- QDockWidgetLayout *layout = dockWidgetLayout();
- int role;
- int currentIndex = 0;
- for (role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) {
- QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role);
- if (!w || !w->isVisible())
- continue;
- if (currentIndex == index)
- return QAccessible::queryAccessibleInterface(w);
- ++currentIndex;
- }
- }
- return 0;
-}
-
-int QAccessibleTitleBar::indexOfChild(const QAccessibleInterface * /*child*/) const
-{
- return -1;
-}
-
-int QAccessibleTitleBar::childCount() const
-{
- QDockWidgetLayout *layout = dockWidgetLayout();
- int count = 0;
- for (int role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) {
- QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role);
- if (w && w->isVisible())
- ++count;
- }
- return count;
-}
-
-QString QAccessibleTitleBar::text(QAccessible::Text t) const
+QString QAccessibleDockWidget::text(QAccessible::Text t) const
{
if (t == QAccessible::Name || t == QAccessible::Value) {
return qt_accStripAmp(dockWidget()->windowTitle());
}
return QString();
}
-
-QAccessible::State QAccessibleTitleBar::state() const
-{
- QAccessible::State state;
-
- QDockWidget *w = dockWidget();
- if (w->testAttribute(Qt::WA_WState_Visible) == false)
- state.invisible = true;
- if (w->focusPolicy() != Qt::NoFocus && w->isActiveWindow())
- state.focusable = true;
- if (w->hasFocus())
- state.focused = true;
- if (!w->isEnabled())
- state.disabled = true;
-
- return state;
-}
-
-QRect QAccessibleTitleBar::rect() const
-{
- bool mapToGlobal = true;
- QRect rect;
-
- if (dockWidget()->isFloating()) {
- rect = dockWidget()->frameGeometry();
- if (dockWidget()->widget()) {
- QPoint globalPos = dockWidget()->mapToGlobal(dockWidget()->widget()->rect().topLeft());
- globalPos.ry()--;
- rect.setBottom(globalPos.y());
- mapToGlobal = false;
- }
- } else {
- QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(dockWidget()->layout());
- rect = layout->titleArea();
- }
-
- if (rect.isNull())
- return rect;
-
- if (mapToGlobal)
- rect.moveTopLeft(dockWidget()->mapToGlobal(rect.topLeft()));
- return rect;
-}
-
-QAccessibleInterface *QAccessibleTitleBar::childAt(int x, int y) const
-{
- for (int i = 0; i < childCount(); ++i) {
- QAccessibleInterface *childIface = child(i);
- if (childIface->rect().contains(x,y)) {
- return childIface;
- }
- }
- return 0;
-}
-
-QObject *QAccessibleTitleBar::object() const
-{
- return 0;
-}
-
-QDockWidgetLayout *QAccessibleTitleBar::dockWidgetLayout() const
-{
- return qobject_cast<QDockWidgetLayout*>(dockWidget()->layout());
-}
-
-QDockWidget *QAccessibleTitleBar::dockWidget() const
-{
- return m_dockWidget;
-}
-
-//QString QAccessibleTitleBar::actionText(int action, Text t, int child) const
-//{
-// QString str;
-// if (child >= 1 && child <= childCount()) {
-// if (t == Name) {
-// switch (action) {
-// case Press:
-// case DefaultAction:
-// if (child == QDockWidgetLayout::CloseButton) {
-// str = QDockWidget::tr("Close");
-// } else if (child == QDockWidgetLayout::FloatButton) {
-// str = dockWidget()->isFloating() ? QDockWidget::tr("Dock")
-// : QDockWidget::tr("Float");
-// }
-// break;
-// default:
-// break;
-// }
-// }
-// }
-// return str;
-//}
-
-//bool QAccessibleTitleBar::doAction(int action, int child, const QVariantList& /*params*/)
-//{
-// if (!child || !dockWidget()->isEnabled())
-// return false;
-
-// switch (action) {
-// case DefaultAction:
-// case Press: {
-// QDockWidgetLayout *layout = dockWidgetLayout();
-// QAbstractButton *btn = static_cast<QAbstractButton *>(layout->widgetForRole((QDockWidgetLayout::Role)child));
-// if (btn)
-// btn->animateClick();
-// return true;
-// break;}
-// default:
-// break;
-// }
-
-// return false;
-//}
-
-QAccessible::Role QAccessibleTitleBar::role() const
-{
- return QAccessible::TitleBar;
-}
-
-void QAccessibleTitleBar::setText(QAccessible::Text /*t*/, const QString &/*text*/)
-{
-}
-
-bool QAccessibleTitleBar::isValid() const
-{
- return dockWidget();
-}
-
#endif // QT_NO_DOCKWIDGET
#ifndef QT_NO_CURSOR
diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.h b/src/plugins/accessible/widgets/qaccessiblewidgets.h
index 3e982e82d6..3f50010685 100644
--- a/src/plugins/accessible/widgets/qaccessiblewidgets.h
+++ b/src/plugins/accessible/widgets/qaccessiblewidgets.h
@@ -283,31 +283,10 @@ public:
int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE;
int childCount() const Q_DECL_OVERRIDE;
QRect rect () const Q_DECL_OVERRIDE;
-
- QDockWidget *dockWidget() const;
-};
-
-class QAccessibleTitleBar : public QAccessibleInterface
-{
-public:
- explicit QAccessibleTitleBar(QDockWidget *widget);
-
- QAccessibleInterface *parent() const Q_DECL_OVERRIDE;
- QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE;
- int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE;
- int childCount() const Q_DECL_OVERRIDE;
- QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE;
- void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE;
QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
- QAccessible::Role role() const Q_DECL_OVERRIDE;
- QRect rect () const Q_DECL_OVERRIDE;
- QAccessible::State state() const Q_DECL_OVERRIDE;
- QObject *object() const Q_DECL_OVERRIDE;
- bool isValid() const Q_DECL_OVERRIDE;
-
- QPointer<QDockWidget> m_dockWidget;
QDockWidget *dockWidget() const;
+protected:
QDockWidgetLayout *dockWidgetLayout() const;
};
diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp
index a9b21cbc81..8b151e65bd 100644
--- a/src/widgets/widgets/qdockwidget.cpp
+++ b/src/widgets/widgets/qdockwidget.cpp
@@ -674,12 +674,18 @@ void QDockWidgetPrivate::updateButtons()
= qobject_cast<QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::FloatButton));
button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, q));
button->setVisible(canFloat && !hideButtons);
-
+#ifndef QT_NO_ACCESSIBILITY
+ button->setAccessibleName(QDockWidget::tr("Float"));
+ button->setAccessibleDescription(QDockWidget::tr("Undocks and re-attaches the dock widget"));
+#endif
button
= qobject_cast <QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::CloseButton));
button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, q));
button->setVisible(canClose && !hideButtons);
-
+#ifndef QT_NO_ACCESSIBILITY
+ button->setAccessibleName(QDockWidget::tr("Close"));
+ button->setAccessibleDescription(QDockWidget::tr("Closes the dock widget"));
+#endif
q->setAttribute(Qt::WA_ContentsPropagated,
(canFloat || canClose) && !hideButtons);
diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
index 092995c0aa..c4a0d9c76c 100644
--- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
+++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
@@ -3056,60 +3056,127 @@ void tst_QAccessibility::dockWidgetTest()
mw->setMenuBar(mb);
QDockWidget *dock1 = new QDockWidget(mw);
+ dock1->setWindowTitle("Dock 1");
mw->addDockWidget(Qt::LeftDockWidgetArea, dock1);
QPushButton *pb1 = new QPushButton(tr("Push me"), dock1);
dock1->setWidget(pb1);
QDockWidget *dock2 = new QDockWidget(mw);
+ dock2->setWindowTitle("Dock 2");
mw->addDockWidget(Qt::BottomDockWidgetArea, dock2);
QPushButton *pb2 = new QPushButton(tr("Push me"), dock2);
dock2->setWidget(pb2);
+ dock2->setFeatures(QDockWidget::DockWidgetClosable);
mw->resize(600,400);
mw->show();
-#if defined(Q_OS_UNIX)
- QCoreApplication::processEvents();
- QTest::qWait(100);
-#endif
+ QTest::qWaitForWindowExposed(mw);
QAccessibleInterface *accMainWindow = QAccessible::queryAccessibleInterface(mw);
// 4 children: menu bar, dock1, dock2, and central widget
QCOMPARE(accMainWindow->childCount(), 4);
QAccessibleInterface *accDock1 = 0;
+ QAccessibleInterface *accDock2 = 0;
for (int i = 0; i < 4; ++i) {
- accDock1 = accMainWindow->child(i);
- if (accMainWindow->role() == QAccessible::Window) {
- if (accDock1 && qobject_cast<QDockWidget*>(accDock1->object()) == dock1) {
- break;
- }
- }
+ QAccessibleInterface *child = accMainWindow->child(i);
+ if (child && child->object() == dock1)
+ accDock1 = child;
+ if (child && child->object() == dock2)
+ accDock2 = child;
}
+
+ // Dock widgets consist of
+ // 0 contents
+ // 1 close button
+ // 2 float button
QVERIFY(accDock1);
QCOMPARE(accDock1->role(), QAccessible::Window);
+ QCOMPARE(accDock1->text(QAccessible::Name), dock1->windowTitle());
+ QCOMPARE(accDock1->childCount(), 3);
+
+ QAccessibleInterface *dock1Widget = accDock1->child(0);
+ QCOMPARE(dock1Widget->role(), QAccessible::Button);
+ QCOMPARE(dock1Widget->text(QAccessible::Name), pb1->text());
+
+#ifdef Q_OS_MAC
+ QEXPECT_FAIL("", "Dock Widget geometry on Mac seems broken.", Continue);
+#endif
+ QVERIFY(accDock1->rect().contains(dock1Widget->rect()));
+ QCOMPARE(accDock1->indexOfChild(dock1Widget), 0);
+ QCOMPARE(dock1Widget->parent()->object(), dock1);
+
+ QAccessibleInterface *dock1Close = accDock1->child(1);
+ QCOMPARE(dock1Close->role(), QAccessible::Button);
+ QCOMPARE(dock1Close->text(QAccessible::Name), QDockWidget::tr("Close"));
+ QVERIFY(accDock1->rect().contains(dock1Close->rect()));
+ QCOMPARE(accDock1->indexOfChild(dock1Close), 1);
+ QCOMPARE(dock1Close->parent()->object(), dock1);
+
+ QAccessibleInterface *dock1Float = accDock1->child(2);
+ QCOMPARE(dock1Float->role(), QAccessible::Button);
+ QCOMPARE(dock1Float->text(QAccessible::Name), QDockWidget::tr("Float"));
+ QVERIFY(accDock1->rect().contains(dock1Float->rect()));
+ QCOMPARE(accDock1->indexOfChild(dock1Float), 2);
+ QVERIFY(!dock1Float->state().invisible);
+
+ QVERIFY(accDock2);
+ QCOMPARE(accDock2->role(), QAccessible::Window);
+ QCOMPARE(accDock2->text(QAccessible::Name), dock2->windowTitle());
+ QCOMPARE(accDock2->childCount(), 3);
+
+ QAccessibleInterface *dock2Widget = accDock2->child(0);
+ QCOMPARE(dock2Widget->role(), QAccessible::Button);
+ QCOMPARE(dock2Widget->text(QAccessible::Name), pb1->text());
+#ifdef Q_OS_MAC
+ QEXPECT_FAIL("", "Dock Widget geometry on Mac seems broken.", Continue);
+#endif
+ QVERIFY(accDock2->rect().contains(dock2Widget->rect()));
+ QCOMPARE(accDock2->indexOfChild(dock2Widget), 0);
+
+ QAccessibleInterface *dock2Close = accDock2->child(1);
+ QCOMPARE(dock2Close->role(), QAccessible::Button);
+ QCOMPARE(dock2Close->text(QAccessible::Name), QDockWidget::tr("Close"));
+ QVERIFY(accDock2->rect().contains(dock2Close->rect()));
+ QCOMPARE(accDock2->indexOfChild(dock2Close), 1);
+ QVERIFY(!dock2Close->state().invisible);
+
+ QAccessibleInterface *dock2Float = accDock2->child(2);
+ QCOMPARE(dock2Float->role(), QAccessible::Button);
+ QCOMPARE(dock2Float->text(QAccessible::Name), QDockWidget::tr("Float"));
+ QCOMPARE(accDock2->indexOfChild(dock2Float), 2);
+ QVERIFY(dock2Float->state().invisible);
+
+ QPoint buttonPoint = pb2->mapToGlobal(QPoint(pb2->width()/2, pb2->height()/2));
+ QAccessibleInterface *childAt = accDock2->childAt(buttonPoint.x(), buttonPoint.y());
+ QVERIFY(childAt);
+ QVERIFY(childAt->object() == pb2);
+
+ QWidget *close1 = qobject_cast<QWidget*>(dock1Close->object());
+ QPoint close1ButtonPoint = close1->mapToGlobal(QPoint(close1->width()/2, close1->height()/2));
+ QAccessibleInterface *childAt2 = accDock1->childAt(close1ButtonPoint.x(), close1ButtonPoint.y());
+ QVERIFY(childAt2);
+ QVERIFY(childAt2->object() == close1);
+
+ // custom title bar widget
+ QDockWidget *dock3 = new QDockWidget(mw);
+ dock3->setWindowTitle("Dock 3");
+ mw->addDockWidget(Qt::LeftDockWidgetArea, dock3);
+ QPushButton *pb3 = new QPushButton(tr("Push me"), dock3);
+ dock3->setWidget(pb3);
+ QLabel *titleLabel = new QLabel("I am a title widget");
+ dock3->setTitleBarWidget(titleLabel);
+
+ QAccessibleInterface *accDock3 = accMainWindow->child(4);
+ QVERIFY(accDock3);
+ QCOMPARE(accDock3->role(), QAccessible::Window);
+ QCOMPARE(accDock3->text(QAccessible::Name), dock3->windowTitle());
+ QCOMPARE(accDock3->childCount(), 2);
+ QAccessibleInterface *titleWidget = accDock3->child(1);
+ QVERIFY(titleWidget);
+ QCOMPARE(titleWidget->text(QAccessible::Name), titleLabel->text());
+ QAccessibleInterface *dock3Widget = accDock3->child(0);
+ QCOMPARE(dock3Widget->text(QAccessible::Name), pb3->text());
- QAccessibleInterface *dock1TitleBar = accDock1->child(0);
- QCOMPARE(dock1TitleBar->role(), QAccessible::TitleBar);
- QVERIFY(accDock1->rect().contains(dock1TitleBar->rect()));
-
- QPoint globalPos = dock1->mapToGlobal(QPoint(0,0));
- globalPos.rx()+=5; //### query style
- globalPos.ry()+=5;
- QAccessibleInterface *childAt = accDock1->childAt(globalPos.x(), globalPos.y()); //###
- QCOMPARE(childAt->role(), QAccessible::TitleBar);
- int index = accDock1->indexOfChild(childAt);
- QAccessibleInterface *accTitleBar = accDock1->child(index);
-
- QCOMPARE(accTitleBar->role(), QAccessible::TitleBar);
- QCOMPARE(accDock1->indexOfChild(accTitleBar), 0);
- QAccessibleInterface *acc;
- acc = accTitleBar->parent();
- QVERIFY(acc);
- QCOMPARE(acc->role(), QAccessible::Window);
-
- delete pb1;
- delete pb2;
- delete dock1;
- delete dock2;
delete mw;
QTestAccessibility::clearEvents();
#endif // QT_NO_DOCKWIDGET