summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJan-Arve Saether <jan-arve.saether@nokia.com>2012-02-09 11:20:34 +0100
committerQt by Nokia <qt-info@nokia.com>2012-02-10 15:21:46 +0100
commitff2886db6a3308c1f4ee0879af497a5d43c33133 (patch)
tree50bfc43dbcb2bb34898e7723519abde2181d0347 /src
parent482d96a0c5d523ace63f56bda6851926b4469dd0 (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.cpp6
-rw-r--r--src/gui/accessible/qaccessible.h5
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.cpp61
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.h3
-rw-r--r--src/plugins/platforms/windows/qwindowsaccessibility.cpp23
-rw-r--r--src/widgets/accessible/qaccessiblewidget.cpp177
-rw-r--r--src/widgets/accessible/qaccessiblewidget.h3
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;