Change uses of {to,from}Ascii to {to,from}Latin1
[profile/ivi/qtdeclarative.git] / src / plugins / accessible / quick / qaccessiblequickitem.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtQml module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
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"
46
47 QT_BEGIN_NAMESPACE
48
49 QAccessibleQuickItem::QAccessibleQuickItem(QQuickItem *item)
50     : QQmlAccessible(item)
51 {
52 }
53
54 int QAccessibleQuickItem::childCount() const
55 {
56     return childItems().count();
57 }
58
59 QRect QAccessibleQuickItem::rect() const
60 {
61     const QRect r = itemScreenRect(item());
62
63     if (!r.isValid()) {
64         qWarning() << item()->metaObject()->className() << item()->property("accessibleText") << r;
65     }
66     return r;
67 }
68
69 QRect QAccessibleQuickItem::viewRect() const
70 {
71     // ### no canvas in some cases.
72     if (!item()->canvas()) {
73         return QRect();
74     }
75
76     QQuickCanvas *canvas = item()->canvas();
77     QPoint screenPos = canvas->mapToGlobal(QPoint(0,0));
78     return QRect(screenPos, canvas->size());
79 }
80
81
82 bool QAccessibleQuickItem::clipsChildren() const
83 {
84     return static_cast<QQuickItem *>(item())->clip();
85 }
86
87
88 QAccessibleInterface *QAccessibleQuickItem::parent() const
89 {
90     QQuickItem *parent = item()->parentItem();
91     if (parent) {
92         QQuickCanvas *canvas = item()->canvas();
93         // Jump out to the scene widget if the parent is the root item.
94         // There are two root items, QQuickCanvas::rootItem and
95         // QQuickView::declarativeRoot. The former is the true root item,
96         // but is not a part of the accessibility tree. Check if we hit
97         // it here and return an interface for the scene instead.
98         if (canvas && (parent == canvas->rootItem())) {
99             return QAccessible::queryAccessibleInterface(canvas);
100         } else {
101             return QAccessible::queryAccessibleInterface(parent);
102         }
103     }
104     return 0;
105 }
106
107 QAccessibleInterface *QAccessibleQuickItem::child(int index) const
108 {
109     QList<QQuickItem *> children = childItems();
110
111     if (index < 0 || index >= children.count())
112         return 0;
113
114     QQuickItem *child = children.at(index);
115     if (!child) // FIXME can this happen?
116         return 0;
117
118     return QAccessible::queryAccessibleInterface(child);
119 }
120
121 int QAccessibleQuickItem::indexOfChild(const QAccessibleInterface *iface) const
122 {
123     QList<QQuickItem*> kids = childItems();
124     return kids.indexOf(static_cast<QQuickItem*>(iface->object()));
125 }
126
127 QList<QQuickItem *> QAccessibleQuickItem::childItems() const
128 {
129     if (    role() == QAccessible::Button ||
130             role() == QAccessible::CheckBox ||
131             role() == QAccessible::RadioButton ||
132             role() == QAccessible::SpinBox ||
133             role() == QAccessible::EditableText ||
134             role() == QAccessible::Slider ||
135             role() == QAccessible::PageTab ||
136             role() == QAccessible::ProgressBar)
137         return QList<QQuickItem *>();
138
139     QList<QQuickItem *> items;
140     Q_FOREACH (QQuickItem *child, item()->childItems()) {
141         QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(child);
142         if (itemPrivate->isAccessible)
143             items.append(child);
144     }
145     return items;
146 }
147
148 QAccessible::State QAccessibleQuickItem::state() const
149 {
150     QAccessible::State state;
151
152     if (item()->hasActiveFocus())
153         state.focused = true;
154
155     QAccessible::Role r = role();
156     switch (r) {
157     case QAccessible::Button: {
158         QVariant checkable = item()->property("checkable");
159         if (!checkable.toBool())
160             break;
161         // fall through
162     }
163     case QAccessible::CheckBox:
164     case QAccessible::RadioButton: {
165         // FIXME when states are extended: state.checkable = true;
166         state.checked = item()->property("checked").toBool();
167         break;
168     }
169     default:
170         break;
171     }
172
173     return state;
174 }
175
176 QAccessible::Role QAccessibleQuickItem::role() const
177 {
178     // Workaround for setAccessibleRole() not working for
179     // Text items. Text items are special since they are defined
180     // entirely from C++ (setting the role from QML works.)
181     if (qobject_cast<QQuickText*>(const_cast<QQuickItem *>(item())))
182         return QAccessible::StaticText;
183
184     QVariant v = QQuickAccessibleAttached::property(item(), "role");
185     bool ok;
186     QAccessible::Role role = (QAccessible::Role)v.toInt(&ok);
187     if (!ok)    // Not sure if this check is needed.
188         role = QAccessible::Pane;
189     return role;
190 }
191
192 bool QAccessibleQuickItem::isAccessible() const
193 {
194     return item()->d_func()->isAccessible;
195 }
196
197 QString QAccessibleQuickItem::text(QAccessible::Text textType) const
198 {
199     // handles generic behavior not specific to an item
200     switch (textType) {
201     case QAccessible::Name: {
202         QVariant accessibleName = QQuickAccessibleAttached::property(object(), "name");
203         if (!accessibleName.isNull())
204             return accessibleName.toString();
205         break;}
206     case QAccessible::Description: {
207         QVariant accessibleDecription = QQuickAccessibleAttached::property(object(), "description");
208         if (!accessibleDecription.isNull())
209             return accessibleDecription.toString();
210         break;}
211 #ifdef Q_ACCESSIBLE_QUICK_ITEM_ENABLE_DEBUG_DESCRIPTION
212     case QAccessible::DebugDescription: {
213         QString debugString;
214         debugString = QString::fromLatin1(object()->metaObject()->className()) + QLatin1Char(' ');
215         debugString += isAccessible() ? QLatin1String("enabled") : QLatin1String("disabled");
216         return debugString;
217         break; }
218 #endif
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 behavior
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     return QString();
242 }
243
244 void *QAccessibleQuickItemValueInterface::interface_cast(QAccessible::InterfaceType t)
245 {
246     if (t == QAccessible::ValueInterface)
247        return static_cast<QAccessibleValueInterface*>(this);
248     return QAccessibleQuickItem::interface_cast(t);
249 }
250
251 QVariant QAccessibleQuickItemValueInterface::currentValue() const
252 {
253     return item()->property("value");
254 }
255
256 void QAccessibleQuickItemValueInterface::setCurrentValue(const QVariant &value)
257 {
258     item()->setProperty("value", value);
259 }
260
261 QVariant QAccessibleQuickItemValueInterface::maximumValue() const
262 {
263     return item()->property("maximumValue");
264 }
265
266 QVariant QAccessibleQuickItemValueInterface::minimumValue() const
267 {
268     return item()->property("minimumValue");
269 }
270
271 /*!
272   \internal
273   Shared between QAccessibleQuickItem and QAccessibleQuickView
274 */
275 QRect itemScreenRect(QQuickItem *item)
276 {
277     // ### no canvas in some cases.
278     // ### Should we really check for 0 opacity?
279     if (!item->canvas() ||!item->isVisible() || qFuzzyIsNull(item->opacity())) {
280         return QRect();
281     }
282
283     QSize itemSize((int)item->width(), (int)item->height());
284     // ### If the bounding rect fails, we first try the implicit size, then we go for the
285     // parent size. WE MIGHT HAVE TO REVISIT THESE FALLBACKS.
286     if (itemSize.isEmpty()) {
287         itemSize = QSize((int)item->implicitWidth(), (int)item->implicitHeight());
288         if (itemSize.isEmpty() && item->parentItem())
289             // ### Seems that the above fallback is not enough, fallback to use the parent size...
290             itemSize = QSize((int)item->parentItem()->width(), (int)item->parentItem()->height());
291     }
292
293     QPointF scenePoint = item->mapToScene(QPointF(0, 0));
294     QPoint screenPos = item->canvas()->mapToGlobal(scenePoint.toPoint());
295     return QRect(screenPos, itemSize);
296 }
297
298
299
300 QT_END_NAMESPACE