diff options
author | Jan-Arve Saether <jan-arve.saether@nokia.com> | 2012-02-09 11:20:34 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-02-10 15:21:46 +0100 |
commit | ff2886db6a3308c1f4ee0879af497a5d43c33133 (patch) | |
tree | 50bfc43dbcb2bb34898e7723519abde2181d0347 /src | |
parent | 482d96a0c5d523ace63f56bda6851926b4469dd0 (diff) |
Move all usages of Relation enum values to QAccessible::relations()
Next step is to remove navigate(), but that has to be done in
qtdeclarative first.
Change-Id: I01ea1386c092446be04cc19d0f70adf53f094adc
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@nokia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/accessible/qaccessible.cpp | 6 | ||||
-rw-r--r-- | src/gui/accessible/qaccessible.h | 5 | ||||
-rw-r--r-- | src/plugins/accessible/widgets/simplewidgets.cpp | 61 | ||||
-rw-r--r-- | src/plugins/accessible/widgets/simplewidgets.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsaccessibility.cpp | 23 | ||||
-rw-r--r-- | src/widgets/accessible/qaccessiblewidget.cpp | 177 | ||||
-rw-r--r-- | src/widgets/accessible/qaccessiblewidget.h | 3 |
7 files changed, 117 insertions, 161 deletions
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index dd0468d9f9..6664e5d312 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -894,17 +894,19 @@ QAccessibleInterface *QAccessibleEvent::accessibleInterface() const */ QAccessible::Relation QAccessibleInterface::relationTo(const QAccessibleInterface *) const { - return QAccessible::Unrelated; + return QAccessible::Relation(); } /*! Returns the meaningful relations to other widgets. Usually this will not return parent/child relations, unless they are handled in a specific way such as in tree views. It will typically return the labelled-by and label relations. + It should never return itself. \sa relationTo(), navigate() */ -QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > QAccessibleInterface::relations() const +QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > +QAccessibleInterface::relations(QAccessible::Relation /*match = QAccessible::AllRelations*/) const { return QVector<QPair<QAccessibleInterface*, QAccessible::Relation> >(); } diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index 214ec20f9c..9fc13a827b 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -306,12 +306,11 @@ public: }; enum RelationFlag { - Unrelated = 0x00000000, Label = 0x00020000, Labelled = 0x00040000, Controller = 0x00080000, Controlled = 0x00100000, - LogicalMask = 0x00ff0000 + AllRelations = 0xffffffff }; Q_DECLARE_FLAGS(Relation, RelationFlag) @@ -380,7 +379,7 @@ public: // relations virtual QAccessible::Relation relationTo(const QAccessibleInterface *other) const; - virtual QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > relations() const; + virtual QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > relations(QAccessible::Relation match = QAccessible::AllRelations) const; virtual QAccessibleInterface *focusChild() const; virtual QAccessibleInterface *childAt(int x, int y) const = 0; diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp index 652150f392..0fdd4490f7 100644 --- a/src/plugins/accessible/widgets/simplewidgets.cpp +++ b/src/plugins/accessible/widgets/simplewidgets.cpp @@ -54,6 +54,7 @@ #include <qlineedit.h> #include <qstyle.h> #include <qstyleoption.h> +#include <QtCore/qvarlengtharray.h> #ifdef Q_OS_MAC #include <qfocusframe.h> @@ -427,52 +428,36 @@ QString QAccessibleDisplay::text(QAccessible::Text t) const return qt_accStripAmp(str); } -QAccessible::Relation QAccessibleDisplay::relationTo(const QAccessibleInterface *other) const +/*! \reimp */ +QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > +QAccessibleDisplay::relations(QAccessible::Relation match /*= QAccessible::AllRelations*/) const { - QAccessible::Relation relation = QAccessibleWidget::relationTo(other); + QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > rels = QAccessibleWidget::relations(match); + if (match & QAccessible::Labelled) { + QVarLengthArray<QObject *, 4> relatedObjects; - QObject *o = other->object(); - QLabel *label = qobject_cast<QLabel*>(object()); - if (label) { #ifndef QT_NO_SHORTCUT - if (o == label->buddy()) - relation |= QAccessible::Label; + if (QLabel *label = qobject_cast<QLabel*>(object())) { + relatedObjects.append(label->buddy()); #endif #ifndef QT_NO_GROUPBOX - } else { - QGroupBox *groupbox = qobject_cast<QGroupBox*>(object()); - if (groupbox && !groupbox->title().isEmpty()) - if (groupbox->children().contains(o)) - relation |= QAccessible::Label; -#endif - } - return relation; -} - -int QAccessibleDisplay::navigate(QAccessible::RelationFlag rel, int entry, QAccessibleInterface **target) const -{ - *target = 0; - if (rel == QAccessible::Labelled) { - QObject *targetObject = 0; - QLabel *label = qobject_cast<QLabel*>(object()); - if (label) { -#ifndef QT_NO_SHORTCUT - if (entry == 1) - targetObject = label->buddy(); -#endif -#ifndef QT_NO_GROUPBOX - } else { - QGroupBox *groupbox = qobject_cast<QGroupBox*>(object()); - if (groupbox && !groupbox->title().isEmpty()) - *target = child(entry - 1); + } else if (QGroupBox *groupbox = qobject_cast<QGroupBox*>(object())) { + if (!groupbox->title().isEmpty()) { + const QList<QWidget*> kids = childWidgets(widget()); + for (int i = 0; i < kids.count(); ++i) { + relatedObjects.append(kids.at(i)); + } + } #endif } - if (targetObject) - *target = QAccessible::queryAccessibleInterface(targetObject); - if (*target) - return 0; + for (int i = 0; i < relatedObjects.count(); ++i) { + const QAccessible::Relation rel = QAccessible::Labelled; + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(relatedObjects.at(i)); + if (iface) + rels.append(qMakePair(iface, rel)); + } } - return QAccessibleWidget::navigate(rel, entry, target); + return rels; } void *QAccessibleDisplay::interface_cast(QAccessible::InterfaceType t) diff --git a/src/plugins/accessible/widgets/simplewidgets.h b/src/plugins/accessible/widgets/simplewidgets.h index bbdececadf..c228775421 100644 --- a/src/plugins/accessible/widgets/simplewidgets.h +++ b/src/plugins/accessible/widgets/simplewidgets.h @@ -104,8 +104,7 @@ public: QString text(QAccessible::Text t) const; QAccessible::Role role() const; - QAccessible::Relation relationTo(const QAccessibleInterface *other) const; - int navigate(QAccessible::RelationFlag, int entry, QAccessibleInterface **target) const; + QVector<QPair<QAccessibleInterface*, QAccessible::Relation> >relations(QAccessible::Relation match = QAccessible::AllRelations) const; void *interface_cast(QAccessible::InterfaceType t); // QAccessibleImageInterface diff --git a/src/plugins/platforms/windows/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/qwindowsaccessibility.cpp index 2c49d8614d..e36e255947 100644 --- a/src/plugins/platforms/windows/qwindowsaccessibility.cpp +++ b/src/plugins/platforms/windows/qwindowsaccessibility.cpp @@ -988,6 +988,17 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accKeyboardShortcut(VARIANT va return *pszKeyboardShortcut ? S_OK : S_FALSE; } +static QAccessibleInterface *relatedInterface(QAccessibleInterface *iface, QAccessible::RelationFlag flag) +{ + typedef QPair<QAccessibleInterface *, QAccessible::Relation> RelationPair; + QVector<RelationPair> rels = iface->relations(flag); + + for (int i = 1; i < rels.count(); ++i) + delete rels.at(i).first; + + return rels.value(0).first; +} + // moz: [important] HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accName(VARIANT varID, BSTR* pszName) { @@ -1001,8 +1012,20 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accName(VARIANT varID, BSTR* p if (!child) return E_FAIL; name = child->text(QAccessible::Name); + if (name.isEmpty()) { + if (QAccessibleInterface *labelInterface = relatedInterface(child.data(), QAccessible::Label)) { + name = labelInterface->text(QAccessible::Name); + delete labelInterface; + } + } } else { name = accessible->text(QAccessible::Name); + if (name.isEmpty()) { + if (QAccessibleInterface *labelInterface = relatedInterface(accessible, QAccessible::Label)) { + name = labelInterface->text(QAccessible::Name); + delete labelInterface; + } + } } if (name.size()) { *pszName = QStringToBSTR(name); diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index 56ba990382..feac42780d 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -327,37 +327,76 @@ static inline bool isAncestor(const QObject *obj, const QObject *child) return false; } - /*! \reimp */ -QAccessible::Relation QAccessibleWidget::relationTo(const QAccessibleInterface *other) const +QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > +QAccessibleWidget::relations(QAccessible::Relation match /*= QAccessible::AllRelations*/) const { - QAccessible::Relation relation = QAccessible::Unrelated; - if (d->asking == this) // recursive call - return relation; - - QObject *o = other ? other->object() : 0; - if (!o) - return relation; + QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > rels; + if (match & QAccessible::Label) { + const QAccessible::Relation rel = QAccessible::Label; + if (QWidget *parent = widget()->parentWidget()) { +#ifndef QT_NO_SHORTCUT + // first check for all siblings that are labels to us + // ideally we would go through all objects and check, but that + // will be too expensive + const QList<QWidget*> kids = childWidgets(parent); + for (int i = 0; i < kids.count(); ++i) { + if (QLabel *labelSibling = qobject_cast<QLabel*>(kids.at(i))) { + if (labelSibling->buddy() == widget()) { + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(labelSibling); + rels.append(qMakePair(iface, rel)); + } + } + } +#endif +#ifndef QT_NO_GROUPBOX + QGroupBox *groupbox = qobject_cast<QGroupBox*>(parent); + if (groupbox && !groupbox->title().isEmpty()) { + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(groupbox); + rels.append(qMakePair(iface, rel)); + } +#endif + } + } - QACConnectionObject *connectionObject = (QACConnectionObject*)object(); - for (int sig = 0; sig < d->primarySignals.count(); ++sig) { - if (connectionObject->isSender(o, d->primarySignals.at(sig).toAscii())) { - relation |= QAccessible::Controller; - break; + if (match & QAccessible::Controller) { + const QAccessible::Relation rel = QAccessible::Controller; + QACConnectionObject *connectionObject = (QACConnectionObject*)object(); + const QObjectList senderList = connectionObject->senderList(); + for (int s = 0; s < senderList.count(); ++s) { + QObject *sender = senderList.at(s); + if (sender->isWidgetType() && sender != object()) { + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(sender); + QACConnectionObject *connectionSender = (QACConnectionObject*)sender; + QStringList senderPrimarySignals = static_cast<QAccessibleWidget*>(iface)->d->primarySignals; + for (int sig = 0; sig < senderPrimarySignals.count(); ++sig) { + const QByteArray strSignal = senderPrimarySignals.at(sig).toAscii(); + if (connectionSender->isSender(object(), strSignal.constData())) + rels.append(qMakePair(iface, rel)); + } + } } } - // test for passive relationships. - // d->asking protects from endless recursion. - d->asking = this; - int inverse = other->relationTo(this); - d->asking = 0; - if (inverse & QAccessible::Controller) - relation |= QAccessible::Controlled; - if (inverse & QAccessible::Label) - relation |= QAccessible::Labelled; + if (match & QAccessible::Controlled) { + QObjectList allReceivers; + QACConnectionObject *connectionObject = (QACConnectionObject*)object(); + for (int sig = 0; sig < d->primarySignals.count(); ++sig) { + const QObjectList receivers = connectionObject->receiverList(d->primarySignals.at(sig).toAscii()); + allReceivers += receivers; + } + + allReceivers.removeAll(object()); //### The object might connect to itself internally - return relation; + for (int i = 0; i < allReceivers.count(); ++i) { + const QAccessible::Relation rel = QAccessible::Controlled; + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(allReceivers.at(i)); + if (iface) + rels.append(qMakePair(iface, rel)); + } + } + + return rels; } /*! \reimp */ @@ -394,96 +433,6 @@ QAccessibleInterface *QAccessibleWidget::focusChild() const } /*! \reimp */ -int QAccessibleWidget::navigate(QAccessible::RelationFlag relation, int entry, - QAccessibleInterface **target) const -{ - if (!target) - return -1; - - *target = 0; - QObject *targetObject = 0; - - switch (relation) { - // Logical - case QAccessible::Label: - if (entry > 0) { - QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject()); - if (!pIface) - return -1; - - // first check for all siblings that are labels to us - // ideally we would go through all objects and check, but that - // will be too expensive - int sibCount = pIface->childCount(); - QAccessibleInterface *candidate = 0; - for (int i = 0; i < sibCount && entry; ++i) { - candidate = pIface->child(i); - Q_ASSERT(candidate); - if (candidate->relationTo(this) & QAccessible::Label) - --entry; - if (!entry) - break; - - delete candidate; - candidate = 0; - } - if (!candidate) { - if (pIface->relationTo(this) & QAccessible::Label) - --entry; - if (!entry) - candidate = pIface; - } - if (pIface != candidate) - delete pIface; - - *target = candidate; - if (*target) - return 0; - } - break; - case QAccessible::Labelled: // only implemented in subclasses - break; - case QAccessible::Controller: - if (entry > 0) { - // check all senders we are connected to, - // and figure out which one are controllers to us - QACConnectionObject *connectionObject = (QACConnectionObject*)object(); - QObjectList allSenders = connectionObject->senderList(); - QObjectList senders; - for (int s = 0; s < allSenders.size(); ++s) { - QObject *sender = allSenders.at(s); - QAccessibleInterface *candidate = QAccessible::queryAccessibleInterface(sender); - if (!candidate) - continue; - if (candidate->relationTo(this) & QAccessible::Controller) - senders << sender; - delete candidate; - } - if (entry <= senders.size()) - targetObject = senders.at(entry-1); - } - break; - case QAccessible::Controlled: - if (entry > 0) { - QObjectList allReceivers; - QACConnectionObject *connectionObject = (QACConnectionObject*)object(); - for (int sig = 0; sig < d->primarySignals.count(); ++sig) { - QObjectList receivers = connectionObject->receiverList(d->primarySignals.at(sig).toAscii()); - allReceivers += receivers; - } - if (entry <= allReceivers.size()) - targetObject = allReceivers.at(entry-1); - } - break; - default: - break; - } - - *target = QAccessible::queryAccessibleInterface(targetObject); - return *target ? 0 : -1; -} - -/*! \reimp */ int QAccessibleWidget::childCount() const { QWidgetList cl = childWidgets(widget()); diff --git a/src/widgets/accessible/qaccessiblewidget.h b/src/widgets/accessible/qaccessiblewidget.h index d34d852e27..4b480ca0ee 100644 --- a/src/widgets/accessible/qaccessiblewidget.h +++ b/src/widgets/accessible/qaccessiblewidget.h @@ -61,14 +61,13 @@ public: QWindow *window() const; int childCount() const; int indexOfChild(const QAccessibleInterface *child) const; - QAccessible::Relation relationTo(const QAccessibleInterface *other) const; + QVector<QPair<QAccessibleInterface*, QAccessible::Relation> > relations(QAccessible::Relation match = QAccessible::AllRelations) const; QAccessibleInterface *focusChild() const; QRect rect() const; QAccessibleInterface *parent() const; QAccessibleInterface *child(int index) const; - int navigate(QAccessible::RelationFlag rel, int entry, QAccessibleInterface **target) const; QString text(QAccessible::Text t) const; QAccessible::Role role() const; |