6e4f27adb24c6dcebd762e709349c4cd0a6bd9be
[profile/ivi/qtdeclarative.git] / src / plugins / accessible / qtquick1 / qaccessibledeclarativeitem.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
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.
17 **
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.
21 **
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.
29 **
30 ** Other Usage
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.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qaccessibledeclarativeitem.h"
43
44 #include <QtQuick1/qdeclarativeitem.h>
45 #include <QtQuick1/private/qdeclarativeaccessibleattached_p.h>
46
47 QT_BEGIN_NAMESPACE
48
49 QAccessibleDeclarativeItem::QAccessibleDeclarativeItem(QGraphicsObject *item, QGraphicsView *view)
50     :QDeclarativeAccessible(item)
51     ,m_item(item)
52     ,m_view(view)
53 {
54
55 }
56
57 int QAccessibleDeclarativeItem::childCount() const
58 {
59     QList<QGraphicsItem *> children = m_item->childItems();
60     return children.count();
61 }
62
63 QRect QAccessibleDeclarativeItem::rect() const
64 {
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);
69 }
70
71 QRect QAccessibleDeclarativeItem::viewRect() const
72 {
73     QPoint screenPos = m_view->mapToGlobal(m_view->pos());
74     return QRect(screenPos, m_view->size());
75 }
76
77 bool QAccessibleDeclarativeItem::clipsChildren() const
78 {
79     return static_cast<QDeclarativeItem *>(m_item)->clip();
80 }
81
82 static inline bool isAncestor(const QObject *ancestorCandidate, const QObject *child)
83 {
84     while (child) {
85         if (child == ancestorCandidate)
86             return true;
87         child = child->parent();
88     }
89     return false;
90 }
91
92
93 QAccessibleInterface *QAccessibleDeclarativeItem::parent() const
94 {
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));
102     return ancestor;
103 }
104
105 QAccessibleInterface *QAccessibleDeclarativeItem::child(int index) const
106 {
107     QList<QGraphicsItem *> children = m_item->childItems();
108
109     if (index >= children.count())
110         return 0;
111
112     QGraphicsItem *child = children.at(index);
113     QGraphicsObject *childObject = qobject_cast<QGraphicsObject *>(child);
114     if (!childObject)
115         return 0;
116
117     return new QAccessibleDeclarativeItem(childObject, m_view);
118 }
119
120 int QAccessibleDeclarativeItem::navigate(QAccessible::RelationFlag rel, int entry, QAccessibleInterface **target) const
121 {
122     //qDebug() << "QAccessibleDeclarativeItem navigate" << rel << entry;
123     Q_ASSERT(entry >= 0);
124
125     *target = 0;
126     if (entry == 0) {
127         *target = new QAccessibleDeclarativeItem(m_item->toGraphicsObject(), m_view);
128         return 0;
129     }
130
131     switch (rel) {
132     case QAccessible::FocusChild: {
133         QGraphicsObject *focusObject = 0;
134         if (m_item->hasFocus()) {
135             focusObject = m_item->toGraphicsObject();
136         } else {
137             if (QGraphicsItem *focusItem = m_view->scene()->focusItem()) {
138                 if (m_item->isAncestorOf(focusItem)) {
139                     focusObject = focusItem->toGraphicsObject();
140                 }
141             }
142         }
143         //qDebug() << "QAccessibleDeclarativeItem navigate QAccessible::FocusChild" << rel << entry;
144         if (focusObject) {
145             *target = new QAccessibleDeclarativeItem(focusObject, m_view);
146             return 0;
147         }
148     }
149     default: break;
150     }
151
152     return -1;
153 }
154
155 int QAccessibleDeclarativeItem::indexOfChild(const QAccessibleInterface *iface) const
156 {
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
161
162     const QGraphicsObject *childObj = static_cast<QGraphicsObject*>(iface->object());
163     if (m_item == childObj)
164         return 0;
165
166     QList<QGraphicsItem*> kids = m_item->childItems();
167     int index = kids.indexOf(const_cast<QGraphicsItem*>(static_cast<const QGraphicsItem*>(childObj)));
168     if (index != -1) {
169         ++index;
170     }
171     return index;
172 }
173
174 QFlags<QAccessible::StateFlag> QAccessibleDeclarativeItem::state() const
175 {
176     QAccessible::State state = QAccessible::Normal;
177
178     if (m_item->hasFocus()) {
179         state |= QAccessible::Focused;
180     }
181     return state;
182 }
183
184 QAccessible::Role QAccessibleDeclarativeItem::role() const
185 {
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;
191
192     QVariant v = QDeclarativeAccessibleAttached::property(m_item, "role");
193     bool ok;
194     QAccessible::Role role = (QAccessible::Role)v.toInt(&ok);
195     if (!ok)    // Not sure if this check is needed.
196         role = QAccessible::Pane;
197     return role;
198 }
199
200 bool QAccessibleDeclarativeItem::isAccessible() const
201 {
202     return true;
203 }
204
205 QString QAccessibleDeclarativeItem::text(QAccessible::Text textType) const
206 {
207     // handles generic behaviour not specific to an item
208     switch (textType) {
209     case QAccessible::Name: {
210         QVariant accessibleName = QDeclarativeAccessibleAttached::property(object(), "name");
211         if (!accessibleName.isNull())
212             return accessibleName.toString();
213         break;}
214     case QAccessible::Description: {
215         QVariant accessibleDecription = QDeclarativeAccessibleAttached::property(object(), "description");
216         if (!accessibleDecription.isNull())
217             return accessibleDecription.toString();
218         break;}
219     case QAccessible::Value:
220     case QAccessible::Help:
221     case QAccessible::Accelerator:
222     default:
223         break;
224     }
225
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();
233         }
234     } else {
235         if (textType == QAccessible::Name) {
236             QVariant text = object()->property("text");
237             return text.toString();
238         }
239     }
240
241
242     return QString();
243 }
244
245 QT_END_NAMESPACE