From 76d0d1926466d42b1b25f0bac642c1e0f239074c Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 15 Sep 2011 21:41:54 +0200 Subject: Add parent and child functions to QAccessibleInterface. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stop the mis-use of navigate to find the parent. In order to make navigation straight forward parent and child functions are now part of QAccessibleInterface. This allows navigating the hierarchy of accessible objects without the 1-based indexes in the navigate function which lead to confusion. Eventually the support for Ancestor in navigate can be completely removed and forwarded in the windows bridge if needed. In addition default parameters for virtual children. This will make the transition smooth since it allows to remove the integer already. Change-Id: I278287ce17161f9fa46797ac244676778c859576 Reviewed-on: http://codereview.qt-project.org/5024 Reviewed-by: Frederik Gladhorn Reviewed-by: Jan-Arve Sæther --- src/widgets/accessible/qaccessible.cpp | 23 ++- src/widgets/accessible/qaccessible.h | 16 +- src/widgets/accessible/qaccessibleobject.cpp | 14 ++ src/widgets/accessible/qaccessibleobject.h | 2 + src/widgets/accessible/qaccessiblewidget.cpp | 210 ++++++++++++--------------- src/widgets/accessible/qaccessiblewidget.h | 3 + 6 files changed, 143 insertions(+), 125 deletions(-) (limited to 'src/widgets/accessible') diff --git a/src/widgets/accessible/qaccessible.cpp b/src/widgets/accessible/qaccessible.cpp index f8f63b1577..a61034a5bd 100644 --- a/src/widgets/accessible/qaccessible.cpp +++ b/src/widgets/accessible/qaccessible.cpp @@ -868,6 +868,27 @@ QVector > QAccessibleInterfa \sa rect() */ +/*! + \fn QAccessibleInterface *parent() const + + Returns the QAccessibleInterface of the parent in the accessible object hierarchy. + + Returns 0 if no parent exists (e.g. for the top level application object). + + \sa child() +*/ + +/*! + \fn QAccessibleInterface *child(int index) const + + Returns the accessible child with index \a index. + 0-based index. The number of children of an object can be checked with childCount. + + Returns 0 when asking for an invalid child (e.g. when the child became invalid in the meantime). + + \sa childCount(), parent() +*/ + /*! \fn int QAccessibleInterface::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const @@ -909,7 +930,7 @@ QVector > QAccessibleInterfa All objects support navigation. - \sa relationTo(), childCount() + \sa relationTo(), childCount(), parent(), child() */ /*! diff --git a/src/widgets/accessible/qaccessible.h b/src/widgets/accessible/qaccessible.h index cbfbca61c5..e6a0f0dd19 100644 --- a/src/widgets/accessible/qaccessible.h +++ b/src/widgets/accessible/qaccessible.h @@ -382,19 +382,21 @@ public: virtual int childAt(int x, int y) const = 0; // navigation + virtual QAccessibleInterface *parent() const = 0; + virtual QAccessibleInterface *child(int index) const = 0; virtual int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const = 0; // properties and state - virtual QString text(Text t, int child) const = 0; + virtual QString text(Text t, int child = 0) const = 0; virtual void setText(Text t, int child, const QString &text) = 0; - virtual QRect rect(int child) const = 0; - virtual Role role(int child) const = 0; - virtual State state(int child) const = 0; + virtual QRect rect(int child = 0) const = 0; + virtual Role role(int child = 0) const = 0; + virtual State state(int child = 0) const = 0; // action - virtual int userActionCount(int child) const = 0; - virtual QString actionText(int action, Text t, int child) const = 0; - virtual bool doAction(int action, int child, const QVariantList ¶ms = QVariantList()) = 0; + virtual int userActionCount(int child = 0) const = 0; + virtual QString actionText(int action, Text t, int child = 0) const = 0; + virtual bool doAction(int action, int child = 0, const QVariantList ¶ms = QVariantList()) = 0; virtual QVariant invokeMethod(Method method, int child = 0, const QVariantList ¶ms = QVariantList()); diff --git a/src/widgets/accessible/qaccessibleobject.cpp b/src/widgets/accessible/qaccessibleobject.cpp index 3f3534baf9..f1c5e1366e 100644 --- a/src/widgets/accessible/qaccessibleobject.cpp +++ b/src/widgets/accessible/qaccessibleobject.cpp @@ -284,6 +284,20 @@ QAccessible::Relation QAccessibleApplication::relationTo(int child, const return Unrelated; } +QAccessibleInterface *QAccessibleApplication::parent() const +{ + return 0; +} + +QAccessibleInterface *QAccessibleApplication::child(int index) const +{ + Q_ASSERT(index >= 0); + const QWidgetList tlw(topLevelWidgets()); + if (index >= 0 && index < tlw.count()) + return QAccessible::queryAccessibleInterface(tlw.at(index)); + return 0; +} + /*! \reimp */ int QAccessibleApplication::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const diff --git a/src/widgets/accessible/qaccessibleobject.h b/src/widgets/accessible/qaccessibleobject.h index b26cfa743b..7d31b6e628 100644 --- a/src/widgets/accessible/qaccessibleobject.h +++ b/src/widgets/accessible/qaccessibleobject.h @@ -91,7 +91,9 @@ public: Relation relationTo(int, const QAccessibleInterface *, int) const; // navigation + QAccessibleInterface *parent() const; int childAt(int x, int y) const; + QAccessibleInterface *child(int index) const; int navigate(RelationFlag, int, QAccessibleInterface **) const; // properties and state diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index 7b8135f836..ec52c4bb71 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -447,6 +447,22 @@ QAccessible::Relation QAccessibleWidget::relationTo(int child, return relation; } +QAccessibleInterface *QAccessibleWidget::parent() const +{ + QObject *parentWidget= widget()->parentWidget(); + if (!parentWidget) + parentWidget = qApp; + return QAccessible::queryAccessibleInterface(parentWidget); +} + +QAccessibleInterface *QAccessibleWidget::child(int index) const +{ + QWidgetList childList = childWidgets(widget()); + if (index >= 0 && index < childList.size()) + return QAccessible::queryAccessibleInterface(childList.at(index)); + return 0; +} + /*! \reimp */ int QAccessibleWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const @@ -457,40 +473,19 @@ int QAccessibleWidget::navigate(RelationFlag relation, int entry, *target = 0; QObject *targetObject = 0; - QWidgetList childList = childWidgets(widget()); - bool complexWidget = childList.size() < childCount(); - switch (relation) { // Hierarchical case Self: targetObject = object(); break; case Child: - if (complexWidget) { - if (entry > 0 && entry <= childList.size()) { - targetObject = childList.at(entry - 1); - break; - } else if (entry > childList.size() && entry <= childCount()) { - return entry; - } - return -1; - }else { - if (entry > 0 && childList.size() >= entry) - targetObject = childList.at(entry - 1); - } - break; + qWarning() << "QAccessibleWidget::navigate is deprecated for QAccessible::Child in:" << object()->metaObject()->className(); + *target = child(entry - 1); + return *target ? 0 : -1; case Ancestor: - { - if (entry <= 0) - return -1; - targetObject = widget()->parentWidget(); - int i; - for (i = entry; i > 1 && targetObject; --i) - targetObject = targetObject->parent(); - if (!targetObject && i == 1) - targetObject = qApp; - } - break; + qWarning() << "QAccessibleWidget::navigate is deprecated for QAccessible::Ancestor in:" << object()->metaObject()->className(); + *target = parent(); + return *target ? 0 : -1; case Sibling: { QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(parentObject()); @@ -506,111 +501,92 @@ int QAccessibleWidget::navigate(RelationFlag relation, int entry, // Geometrical case QAccessible::Left: - if (complexWidget && entry) { - if (entry < 2 || widget()->height() > widget()->width() + 20) // looks vertical - return -1; - return entry - 1; - } // fall through case QAccessible::Right: - if (complexWidget && entry) { - if (entry >= childCount() || widget()->height() > widget()->width() + 20) // looks vertical - return -1; - return entry + 1; - } // fall through case QAccessible::Up: - if (complexWidget && entry) { - if (entry < 2 || widget()->width() > widget()->height() + 20) // looks horizontal - return - 1; - return entry - 1; - } // fall through case QAccessible::Down: - if (complexWidget && entry) { - if (entry >= childCount() || widget()->width() > widget()->height() + 20) // looks horizontal - return - 1; - return entry + 1; - } else { - QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject()); - if (!pIface) - return -1; + { + QAccessibleInterface *pIface = parent(); + if (!pIface) + return -1; - QRect startg = rect(0); - QPoint startc = startg.center(); - QAccessibleInterface *candidate = 0; - int mindist = 100000; - int sibCount = pIface->childCount(); - for (int i = 0; i < sibCount; ++i) { - QAccessibleInterface *sibling = 0; - pIface->navigate(Child, i+1, &sibling); - Q_ASSERT(sibling); - if ((relationTo(0, sibling, 0) & Self) || (sibling->state(0) & QAccessible::Invisible)) { - //ignore ourself and invisible siblings + QRect startg = rect(0); + QPoint startc = startg.center(); + QAccessibleInterface *candidate = 0; + int mindist = 100000; + int sibCount = pIface->childCount(); + for (int i = 0; i < sibCount; ++i) { + QAccessibleInterface *sibling = 0; + sibling = pIface->child(i); + Q_ASSERT(sibling); + if ((relationTo(0, sibling, 0) & Self) || (sibling->state(0) & QAccessible::Invisible)) { + //ignore ourself and invisible siblings + delete sibling; + continue; + } + + QRect sibg = sibling->rect(0); + QPoint sibc = sibg.center(); + QPoint sibp; + QPoint startp; + QPoint distp; + switch (relation) { + case QAccessible::Left: + startp = QPoint(startg.left(), startg.top() + startg.height() / 2); + sibp = QPoint(sibg.right(), sibg.top() + sibg.height() / 2); + if (QPoint(sibc - startc).x() >= 0) { delete sibling; continue; } - - QRect sibg = sibling->rect(0); - QPoint sibc = sibg.center(); - QPoint sibp; - QPoint startp; - QPoint distp; - switch (relation) { - case QAccessible::Left: - startp = QPoint(startg.left(), startg.top() + startg.height() / 2); - sibp = QPoint(sibg.right(), sibg.top() + sibg.height() / 2); - if (QPoint(sibc - startc).x() >= 0) { - delete sibling; - continue; - } - distp = sibp - startp; - break; - case QAccessible::Right: - startp = QPoint(startg.right(), startg.top() + startg.height() / 2); - sibp = QPoint(sibg.left(), sibg.top() + sibg.height() / 2); - if (QPoint(sibc - startc).x() <= 0) { - delete sibling; - continue; - } - distp = sibp - startp; - break; - case QAccessible::Up: - startp = QPoint(startg.left() + startg.width() / 2, startg.top()); - sibp = QPoint(sibg.left() + sibg.width() / 2, sibg.bottom()); - if (QPoint(sibc - startc).y() >= 0) { - delete sibling; - continue; - } - distp = sibp - startp; - break; - case QAccessible::Down: - startp = QPoint(startg.left() + startg.width() / 2, startg.bottom()); - sibp = QPoint(sibg.left() + sibg.width() / 2, sibg.top()); - if (QPoint(sibc - startc).y() <= 0) { - delete sibling; - continue; - } - distp = sibp - startp; - break; - default: - break; + distp = sibp - startp; + break; + case QAccessible::Right: + startp = QPoint(startg.right(), startg.top() + startg.height() / 2); + sibp = QPoint(sibg.left(), sibg.top() + sibg.height() / 2); + if (QPoint(sibc - startc).x() <= 0) { + delete sibling; + continue; } - - int dist = (int)qSqrt((qreal)distp.x() * distp.x() + distp.y() * distp.y()); - if (dist < mindist) { - delete candidate; - candidate = sibling; - mindist = dist; - } else { + distp = sibp - startp; + break; + case QAccessible::Up: + startp = QPoint(startg.left() + startg.width() / 2, startg.top()); + sibp = QPoint(sibg.left() + sibg.width() / 2, sibg.bottom()); + if (QPoint(sibc - startc).y() >= 0) { delete sibling; + continue; } + distp = sibp - startp; + break; + case QAccessible::Down: + startp = QPoint(startg.left() + startg.width() / 2, startg.bottom()); + sibp = QPoint(sibg.left() + sibg.width() / 2, sibg.top()); + if (QPoint(sibc - startc).y() <= 0) { + delete sibling; + continue; + } + distp = sibp - startp; + break; + default: + break; + } + + int dist = (int)qSqrt((qreal)distp.x() * distp.x() + distp.y() * distp.y()); + if (dist < mindist) { + delete candidate; + candidate = sibling; + mindist = dist; + } else { + delete sibling; } - delete pIface; - *target = candidate; - if (*target) - return 0; } + delete pIface; + *target = candidate; + if (*target) + return 0; + } break; case Covers: if (entry > 0) { diff --git a/src/widgets/accessible/qaccessiblewidget.h b/src/widgets/accessible/qaccessiblewidget.h index 52b4566d13..acf900e84b 100644 --- a/src/widgets/accessible/qaccessiblewidget.h +++ b/src/widgets/accessible/qaccessiblewidget.h @@ -65,6 +65,9 @@ public: int childAt(int x, int y) const; QRect rect(int child) const; + + QAccessibleInterface *parent() const; + QAccessibleInterface *child(int index) const; int navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const; QString text(Text t, int child) const; -- cgit v1.2.3