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)
54 int QAccessibleQuickItem::childCount() const
56 return childItems().count();
59 QRect QAccessibleQuickItem::rect() const
61 // ### no canvas in some cases.
62 // ### Should we really check for 0 opacity?
63 if (!item()->canvas() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity())) {
67 QSizeF size = QSizeF(item()->width(), item()->height());
68 // ### If the bounding rect fails, we first try the implicit size, then we go for the
69 // parent size. WE MIGHT HAVE TO REVISIT THESE FALLBACKS.
71 size = QSizeF(item()->implicitWidth(), item()->implicitHeight());
73 // ### Seems that the above fallback is not enough, fallback to use the parent size...
74 size = QSizeF(item()->parentItem()->width(), item()->parentItem()->height());
77 QRectF sceneRect = item()->mapRectToScene(QRectF(QPointF(0, 0), size));
78 QPoint screenPos = item()->canvas()->mapToGlobal(sceneRect.topLeft().toPoint());
80 QRect r = QRect(screenPos, sceneRect.size().toSize());
83 qWarning() << item()->metaObject()->className() << item()->property("accessibleText") << r;
88 QRect QAccessibleQuickItem::viewRect() const
90 // ### no canvas in some cases.
91 if (!item()->canvas()) {
95 QQuickCanvas *canvas = item()->canvas();
96 QPoint screenPos = canvas->mapToGlobal(QPoint(0,0));
97 return QRect(screenPos, canvas->size());
101 bool QAccessibleQuickItem::clipsChildren() const
103 return static_cast<QQuickItem *>(item())->clip();
107 QAccessibleInterface *QAccessibleQuickItem::parent() const
109 QQuickItem *parent = item()->parentItem();
111 QQuickCanvas *canvas = item()->canvas();
112 // Jump out to the scene widget if the parent is the root item.
113 // There are two root items, QQuickCanvas::rootItem and
114 // QQuickView::declarativeRoot. The former is the true root item,
115 // but is not a part of the accessibility tree. Check if we hit
116 // it here and return an interface for the scene instead.
117 if (parent == canvas->rootItem()) {
118 return QAccessible::queryAccessibleInterface(canvas);
120 QDeclarativeAccessible *ancestor = new QAccessibleQuickItem(parent);
127 QAccessibleInterface *QAccessibleQuickItem::child(int index) const
129 QList<QQuickItem *> children = childItems();
131 if (index < 0 || index >= children.count())
134 QQuickItem *child = children.at(index);
135 if (!child) // FIXME can this happen?
138 return new QAccessibleQuickItem(child);
141 int QAccessibleQuickItem::navigate(QAccessible::RelationFlag rel, int entry, QAccessibleInterface **target) const
148 *target = new QAccessibleQuickItem(item());
154 int QAccessibleQuickItem::indexOfChild(const QAccessibleInterface *iface) const
156 QList<QQuickItem*> kids = childItems();
157 int idx = kids.indexOf(static_cast<QQuickItem*>(iface->object()));
163 QList<QQuickItem *> QAccessibleQuickItem::childItems() const
165 if ( role() == QAccessible::Button ||
166 role() == QAccessible::CheckBox ||
167 role() == QAccessible::RadioButton ||
168 role() == QAccessible::SpinBox ||
169 role() == QAccessible::EditableText ||
170 role() == QAccessible::Slider ||
171 role() == QAccessible::PageTab ||
172 role() == QAccessible::ProgressBar)
173 return QList<QQuickItem *>();
174 return item()->childItems();
177 QAccessible::State QAccessibleQuickItem::state() const
179 QAccessible::State state;
181 if (item()->hasActiveFocus())
182 state.focused = true;
184 QAccessible::Role r = role();
186 case QAccessible::Button: {
187 QVariant checkable = item()->property("checkable");
188 if (!checkable.toBool())
192 case QAccessible::CheckBox:
193 case QAccessible::RadioButton: {
194 // FIXME when states are extended: state.checkable = true;
195 state.checked = item()->property("checked").toBool();
205 QAccessible::Role QAccessibleQuickItem::role() const
207 // Workaround for setAccessibleRole() not working for
208 // Text items. Text items are special since they are defined
209 // entirely from C++ (setting the role from QML works.)
210 if (qobject_cast<QQuickText*>(const_cast<QQuickItem *>(item())))
211 return QAccessible::StaticText;
213 QVariant v = QQuickAccessibleAttached::property(item(), "role");
215 QAccessible::Role role = (QAccessible::Role)v.toInt(&ok);
216 if (!ok) // Not sure if this check is needed.
217 role = QAccessible::Pane;
221 bool QAccessibleQuickItem::isAccessible() const
223 return item()->d_func()->isAccessible;
226 QString QAccessibleQuickItem::text(QAccessible::Text textType) const
228 // handles generic behavior not specific to an item
230 case QAccessible::Name: {
231 QVariant accessibleName = QQuickAccessibleAttached::property(object(), "name");
232 if (!accessibleName.isNull())
233 return accessibleName.toString();
235 case QAccessible::Description: {
236 QVariant accessibleDecription = QQuickAccessibleAttached::property(object(), "description");
237 if (!accessibleDecription.isNull())
238 return accessibleDecription.toString();
240 #ifdef Q_ACCESSIBLE_QUICK_ITEM_ENABLE_DEBUG_DESCRIPTION
241 case QAccessible::DebugDescription: {
243 debugString = QString::fromAscii(object()->metaObject()->className()) + QLatin1Char(' ');
244 debugString += isAccessible() ? QLatin1String("enabled") : QLatin1String("disabled");
248 case QAccessible::Value:
249 case QAccessible::Help:
250 case QAccessible::Accelerator:
255 // the following blocks handles item-specific behavior
256 if (role() == QAccessible::EditableText) {
257 if (textType == QAccessible::Value) {
258 QVariant text = object()->property("text");
259 return text.toString();
260 } else if (textType == QAccessible::Name) {
261 return object()->objectName();
264 if (textType == QAccessible::Name) {
265 QVariant text = object()->property("text");
266 return text.toString();
273 void *QAccessibleQuickItemValueInterface::interface_cast(QAccessible::InterfaceType t)
275 if (t == QAccessible::ValueInterface)
276 return static_cast<QAccessibleValueInterface*>(this);
277 return QAccessibleQuickItem::interface_cast(t);
280 QVariant QAccessibleQuickItemValueInterface::currentValue() const
282 return item()->property("value");
285 void QAccessibleQuickItemValueInterface::setCurrentValue(const QVariant &value)
287 item()->setProperty("value", value);
290 QVariant QAccessibleQuickItemValueInterface::maximumValue() const
292 return item()->property("maximumValue");
295 QVariant QAccessibleQuickItemValueInterface::minimumValue() const
297 return item()->property("minimumValue");