1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qaccessiblequickitem.h"
43 #include "QtQuick/private/qquickitem_p.h"
44 #include "QtQuick/private/qquicktext_p.h"
45 #include "QtQuick/private/qquickaccessibleattached_p.h"
49 QAccessibleQuickItem::QAccessibleQuickItem(QQuickItem *item)
50 : QDeclarativeAccessible(item)
55 int QAccessibleQuickItem::childCount() const
57 return childItems().count();
60 QRect QAccessibleQuickItem::rect() const
62 // ### no canvas in some cases.
63 // ### Should we really check for 0 opacity?
64 if (!m_item->canvas() ||!m_item->isVisible() || qFuzzyIsNull(m_item->opacity())) {
68 QSizeF size = QSizeF(m_item->width(), m_item->height());
69 // ### If the bounding rect fails, we first try the implicit size, then we go for the
70 // parent size. WE MIGHT HAVE TO REVISIT THESE FALLBACKS.
72 size = QSizeF(m_item->implicitWidth(), m_item->implicitHeight());
74 // ### Seems that the above fallback is not enough, fallback to use the parent size...
75 size = QSizeF(m_item->parentItem()->width(), m_item->parentItem()->height());
78 QRectF sceneRect = m_item->mapRectToScene(QRectF(QPointF(0, 0), size));
79 QPoint screenPos = m_item->canvas()->mapToGlobal(sceneRect.topLeft().toPoint());
81 QRect r = QRect(screenPos, sceneRect.size().toSize());
84 qWarning() << m_item->metaObject()->className() << m_item->property("accessibleText") << r;
89 QRect QAccessibleQuickItem::viewRect() const
91 // ### no canvas in some cases.
92 if (!m_item->canvas()) {
96 QQuickCanvas *canvas = m_item->canvas();
97 QPoint screenPos = canvas->mapToGlobal(QPoint(0,0));
98 return QRect(screenPos, canvas->size());
102 bool QAccessibleQuickItem::clipsChildren() const
104 return static_cast<QQuickItem *>(m_item)->clip();
108 QAccessibleInterface *QAccessibleQuickItem::parent() const
110 QQuickItem *parent = m_item->parentItem();
112 QQuickCanvas *canvas = m_item->canvas();
113 // Jump out to the scene widget if the parent is the root item.
114 // There are two root items, QQuickCanvas::rootItem and
115 // QQuickView::declarativeRoot. The former is the true root item,
116 // but is not a part of the accessibility tree. Check if we hit
117 // it here and return an interface for the scene instead.
118 if (parent == canvas->rootItem()) {
119 return QAccessible::queryAccessibleInterface(canvas);
121 QDeclarativeAccessible *ancestor = new QAccessibleQuickItem(parent);
128 QAccessibleInterface *QAccessibleQuickItem::child(int index) const
130 QList<QQuickItem *> children = childItems();
132 if (index < 0 || index >= children.count())
135 QQuickItem *child = children.at(index);
136 if (!child) // FIXME can this happen?
139 return new QAccessibleQuickItem(child);
142 int QAccessibleQuickItem::navigate(QAccessible::RelationFlag rel, int entry, QAccessibleInterface **target) const
146 *target = new QAccessibleQuickItem(m_item);
151 case QAccessible::Child: { // FIMXE
152 QList<QQuickItem *> children = childItems();
153 const int childIndex = entry - 1;
155 if (childIndex >= children.count())
158 QQuickItem *child = children.at(childIndex);
162 *target = new QAccessibleQuickItem(child);
165 case QAccessible::Ancestor: { // FIMXE
166 QQuickItem *parent = m_item->parentItem();
168 QDeclarativeAccessible *ancestor = new QAccessibleQuickItem(parent);
170 QQuickCanvas *canvas = m_item->canvas();
171 // Jump out to the scene widget if the parent is the root item.
172 // There are two root items, QQuickCanvas::rootItem and
173 // QQuickView::declarativeRoot. The former is the true root item,
174 // but is not a part of the accessibility tree. Check if we hit
175 // it here and return an interface for the scene instead.
176 if (parent == canvas->rootItem()) {
177 *target = QAccessible::queryAccessibleInterface(canvas);
182 } else if (entry > 1) {
183 int ret = ancestor->navigate(QAccessible::Ancestor, entry - 1, target);
196 int QAccessibleQuickItem::indexOfChild(const QAccessibleInterface *iface) const
198 QList<QQuickItem*> kids = childItems();
199 int idx = kids.indexOf(static_cast<QQuickItem*>(iface->object()));
205 QList<QQuickItem *> QAccessibleQuickItem::childItems() const
207 if (role() == QAccessible::Button)
208 return QList<QQuickItem *>();
209 return m_item->childItems();
212 QFlags<QAccessible::StateFlag> QAccessibleQuickItem::state() const
214 QAccessible::State state = QAccessible::Normal;
216 if (m_item->hasActiveFocus()) {
217 state |= QAccessible::Focused;
223 QAccessible::Role QAccessibleQuickItem::role() const
225 // Workaround for setAccessibleRole() not working for
226 // Text items. Text items are special since they are defined
227 // entirely from C++ (setting the role from QML works.)
228 if (qobject_cast<QQuickText*>(const_cast<QQuickItem *>(m_item)))
229 return QAccessible::StaticText;
231 QVariant v = QQuickAccessibleAttached::property(m_item, "role");
233 QAccessible::Role role = (QAccessible::Role)v.toInt(&ok);
234 if (!ok) // Not sure if this check is needed.
235 role = QAccessible::Pane;
239 bool QAccessibleQuickItem::isAccessible() const
241 return m_item->d_func()->isAccessible;
244 QString QAccessibleQuickItem::text(QAccessible::Text textType) const
246 // handles generic behavior not specific to an item
248 case QAccessible::Name: {
249 QVariant accessibleName = QQuickAccessibleAttached::property(object(), "name");
250 if (!accessibleName.isNull())
251 return accessibleName.toString();
253 case QAccessible::Description: {
254 QVariant accessibleDecription = QQuickAccessibleAttached::property(object(), "description");
255 if (!accessibleDecription.isNull())
256 return accessibleDecription.toString();
258 #ifdef Q_ACCESSIBLE_QUICK_ITEM_ENABLE_DEBUG_DESCRIPTION
259 case QAccessible::DebugDescription: {
261 debugString = QString::fromAscii(object()->metaObject()->className()) + QLatin1Char(' ');
262 debugString += isAccessible() ? QLatin1String("enabled") : QLatin1String("disabled");
266 case QAccessible::Value:
267 case QAccessible::Help:
268 case QAccessible::Accelerator:
273 // the following blocks handles item-specific behavior
274 if (role() == QAccessible::EditableText) {
275 if (textType == QAccessible::Value) {
276 QVariant text = object()->property("text");
277 return text.toString();
278 } else if (textType == QAccessible::Name) {
279 return object()->objectName();
282 if (textType == QAccessible::Name) {
283 QVariant text = object()->property("text");
284 return text.toString();