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 "qaccessibledeclarativeitem.h"
44 #include <QtQuick1/qdeclarativeitem.h>
45 #include <QtQuick1/private/qdeclarativeaccessibleattached_p.h>
49 QAccessibleDeclarativeItem::QAccessibleDeclarativeItem(QGraphicsObject *item, QGraphicsView *view)
50 :QDeclarativeAccessible(item)
57 int QAccessibleDeclarativeItem::childCount() const
59 QList<QGraphicsItem *> children = m_item->childItems();
60 return children.count();
63 QRect QAccessibleDeclarativeItem::rect() const
65 QRectF sceneRect = m_item->sceneTransform().mapRect(m_item->boundingRect());
66 QPoint pos = m_view->mapFromScene(m_view->mapToGlobal(sceneRect.topLeft().toPoint()));
67 QSize size = sceneRect.size().toSize();
68 return QRect(pos, size);
71 QRect QAccessibleDeclarativeItem::viewRect() const
73 QPoint screenPos = m_view->mapToGlobal(m_view->pos());
74 return QRect(screenPos, m_view->size());
77 bool QAccessibleDeclarativeItem::clipsChildren() const
79 return static_cast<QDeclarativeItem *>(m_item)->clip();
82 static inline bool isAncestor(const QObject *ancestorCandidate, const QObject *child)
85 if (child == ancestorCandidate)
87 child = child->parent();
93 QAccessibleInterface *QAccessibleDeclarativeItem::parent() const
95 QGraphicsItem *parent = m_item->parentItem();
96 QGraphicsObject *parentObj = parent ? parent->toGraphicsObject() : 0;
97 if (parent && !parentObj)
98 qWarning("Can not make QGraphicsItems accessible");
99 QAccessibleInterface *ancestor = (parentObj
100 ? new QAccessibleDeclarativeItem(parentObj, m_view)
101 : QAccessible::queryAccessibleInterface(m_view));
105 QAccessibleInterface *QAccessibleDeclarativeItem::child(int index) const
107 QList<QGraphicsItem *> children = m_item->childItems();
109 if (index >= children.count())
112 QGraphicsItem *child = children.at(index);
113 QGraphicsObject *childObject = qobject_cast<QGraphicsObject *>(child);
117 return new QAccessibleDeclarativeItem(childObject, m_view);
120 int QAccessibleDeclarativeItem::navigate(QAccessible::RelationFlag rel, int entry, QAccessibleInterface **target) const
122 //qDebug() << "QAccessibleDeclarativeItem navigate" << rel << entry;
123 Q_ASSERT(entry >= 0);
127 *target = new QAccessibleDeclarativeItem(m_item->toGraphicsObject(), m_view);
132 case QAccessible::FocusChild: {
133 QGraphicsObject *focusObject = 0;
134 if (m_item->hasFocus()) {
135 focusObject = m_item->toGraphicsObject();
137 if (QGraphicsItem *focusItem = m_view->scene()->focusItem()) {
138 if (m_item->isAncestorOf(focusItem)) {
139 focusObject = focusItem->toGraphicsObject();
143 //qDebug() << "QAccessibleDeclarativeItem navigate QAccessible::FocusChild" << rel << entry;
145 *target = new QAccessibleDeclarativeItem(focusObject, m_view);
155 int QAccessibleDeclarativeItem::indexOfChild(const QAccessibleInterface *iface) const
157 // ### No QAccessibleInterfaces are created with a QGraphicsItem.
158 // However, we want to support QML, not QGraphicsView in general.
159 // And since the UI is written in QML, this means we can assume that *all*
160 // QGraphicsItems are actually QGraphicsObjects
162 const QGraphicsObject *childObj = static_cast<QGraphicsObject*>(iface->object());
163 if (m_item == childObj)
166 QList<QGraphicsItem*> kids = m_item->childItems();
167 int index = kids.indexOf(const_cast<QGraphicsItem*>(static_cast<const QGraphicsItem*>(childObj)));
174 QFlags<QAccessible::StateFlag> QAccessibleDeclarativeItem::state() const
176 QAccessible::State state = QAccessible::Normal;
178 if (m_item->hasFocus()) {
179 state |= QAccessible::Focused;
184 QAccessible::Role QAccessibleDeclarativeItem::role() const
186 // ### Workaround for setAccessibleRole() not working.
187 // Text items are special since they are defined
188 // entirely from C++ (setting the role from QML works.)
189 // if (qobject_cast<QDeclarative1Text*>(m_item))
190 // return QAccessible::StaticText;
192 QVariant v = QDeclarativeAccessibleAttached::property(m_item, "role");
194 QAccessible::Role role = (QAccessible::Role)v.toInt(&ok);
195 if (!ok) // Not sure if this check is needed.
196 role = QAccessible::Pane;
200 bool QAccessibleDeclarativeItem::isAccessible() const
205 QString QAccessibleDeclarativeItem::text(QAccessible::Text textType) const
207 // handles generic behaviour not specific to an item
209 case QAccessible::Name: {
210 QVariant accessibleName = QDeclarativeAccessibleAttached::property(object(), "name");
211 if (!accessibleName.isNull())
212 return accessibleName.toString();
214 case QAccessible::Description: {
215 QVariant accessibleDecription = QDeclarativeAccessibleAttached::property(object(), "description");
216 if (!accessibleDecription.isNull())
217 return accessibleDecription.toString();
219 case QAccessible::Value:
220 case QAccessible::Help:
221 case QAccessible::Accelerator:
226 // the following blocks handles item-specific behaviour
227 if (role() == QAccessible::EditableText) {
228 if (textType == QAccessible::Value) {
229 QVariant text = object()->property("text");
230 return text.toString();
231 } else if (textType == QAccessible::Name) {
232 return object()->objectName();
235 if (textType == QAccessible::Name) {
236 QVariant text = object()->property("text");
237 return text.toString();