Create accessible interfaces only for items with attached prop
[profile/ivi/qtdeclarative.git] / src / quick / items / qquickitem.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 "qquickitem.h"
43
44 #include "qquickcanvas.h"
45 #include <QtQml/qjsengine.h>
46 #include "qquickcanvas_p.h"
47
48 #include "qquickevents_p_p.h"
49 #include "qquickscreen_p.h"
50
51 #include <QtQml/qqmlengine.h>
52 #include <QtQml/qqmlcomponent.h>
53 #include <QtQml/qqmlinfo.h>
54 #include <QtGui/qpen.h>
55 #include <QtGui/qguiapplication.h>
56 #include <QtGui/private/qguiapplication_p.h>
57 #include <QtGui/qinputmethod.h>
58 #include <QtCore/qdebug.h>
59 #include <QtCore/qcoreevent.h>
60 #include <QtCore/qnumeric.h>
61
62 #include <private/qqmlglobal_p.h>
63 #include <private/qqmlengine_p.h>
64 #include <QtQuick/private/qquickstategroup_p.h>
65 #include <private/qqmlopenmetaobject_p.h>
66 #include <QtQuick/private/qquickstate_p.h>
67 #include <private/qlistmodelinterface_p.h>
68 #include <private/qquickitem_p.h>
69 #include <private/qqmlaccessors_p.h>
70 #include <QtQuick/private/qquickaccessibleattached_p.h>
71
72 #include <float.h>
73
74 // XXX todo Check that elements that create items handle memory correctly after visual ownership change
75
76 QT_BEGIN_NAMESPACE
77
78 #ifdef FOCUS_DEBUG
79 void printFocusTree(QQuickItem *item, QQuickItem *scope = 0, int depth = 1);
80 void printFocusTree(QQuickItem *item, QQuickItem *scope, int depth)
81 {
82     qWarning()
83             << QByteArray(depth, '\t').constData()
84             << (scope && QQuickItemPrivate::get(scope)->subFocusItem == item ? '*' : ' ')
85             << item->hasFocus()
86             << item->hasActiveFocus()
87             << item->isFocusScope()
88             << item;
89     foreach (QQuickItem *child, item->childItems()) {
90         printFocusTree(
91                 child,
92                 item->isFocusScope() || !scope ? item : scope,
93                 item->isFocusScope() || !scope ? depth + 1 : depth);
94     }
95 }
96 #endif
97
98 static void QQuickItem_parentNotifier(QObject *o, intptr_t, QQmlNotifier **n)
99 {
100     QQuickItemPrivate *d = QQuickItemPrivate::get(static_cast<QQuickItem *>(o));
101     *n = &d->parentNotifier;
102 }
103
104 QML_PRIVATE_ACCESSOR(QQuickItem, QQuickItem *, parent, parentItem)
105 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, x, x)
106 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, y, y)
107 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, width, width)
108 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, height, height)
109
110 static QQmlAccessors QQuickItem_parent = { QQuickItem_parentRead, QQuickItem_parentNotifier };
111 static QQmlAccessors QQuickItem_x = { QQuickItem_xRead, 0 };
112 static QQmlAccessors QQuickItem_y = { QQuickItem_yRead, 0 };
113 static QQmlAccessors QQuickItem_width = { QQuickItem_widthRead, 0 };
114 static QQmlAccessors QQuickItem_height = { QQuickItem_heightRead, 0 };
115
116 QML_DECLARE_PROPERTIES(QQuickItem) {
117     { QML_PROPERTY_NAME(parent), 0, &QQuickItem_parent },
118     { QML_PROPERTY_NAME(x), 0, &QQuickItem_x },
119     { QML_PROPERTY_NAME(y), 0, &QQuickItem_y },
120     { QML_PROPERTY_NAME(width), 0, &QQuickItem_width },
121     { QML_PROPERTY_NAME(height), 0, &QQuickItem_height }
122 };
123
124 void QQuickItemPrivate::registerAccessorProperties()
125 {
126     QML_DEFINE_PROPERTIES(QQuickItem);
127 }
128
129 /*!
130     \qmlclass Transform QQuickTransform
131     \inqmlmodule QtQuick 2
132     \ingroup qml-transform-elements
133     \brief The Transform elements provide a way of building advanced transformations on Items.
134
135     The Transform element is a base type which cannot be instantiated directly.
136     The following concrete Transform types are available:
137
138     \list
139     \li \l Rotation
140     \li \l Scale
141     \li \l Translate
142     \endlist
143
144     The Transform elements let you create and control advanced transformations that can be configured
145     independently using specialized properties.
146
147     You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
148     one at a time.
149 */
150
151 /*!
152     \qmlclass Translate QQuickTranslate
153     \inqmlmodule QtQuick 2
154     \ingroup qml-transform-elements
155     \brief The Translate object provides a way to move an Item without changing its x or y properties.
156
157     The Translate object provides independent control over position in addition to the Item's x and y properties.
158
159     The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
160     to lay the items out as if they had not been transformed:
161     \qml
162     import QtQuick 2.0
163
164     Row {
165         Rectangle {
166             width: 100; height: 100
167             color: "blue"
168             transform: Translate { y: 20 }
169         }
170         Rectangle {
171             width: 100; height: 100
172             color: "red"
173             transform: Translate { y: -20 }
174         }
175     }
176     \endqml
177
178     \image translate.png
179 */
180
181 /*!
182     \qmlproperty real QtQuick2::Translate::x
183
184     The translation along the X axis.
185 */
186
187 /*!
188     \qmlproperty real QtQuick2::Translate::y
189
190     The translation along the Y axis.
191 */
192
193 /*!
194     \qmlclass Scale QQuickScale
195     \inqmlmodule QtQuick 2
196     \ingroup qml-transform-elements
197     \brief The Scale element provides a way to scale an Item.
198
199     The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
200     it allows a different scale for the x and y axes, and allows the scale to be relative to an
201     arbitrary point.
202
203     The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
204     \qml
205     Rectangle {
206         width: 100; height: 100
207         color: "blue"
208         transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
209     }
210     \endqml
211
212     \sa Rotation, Translate
213 */
214
215 /*!
216     \qmlproperty real QtQuick2::Scale::origin.x
217     \qmlproperty real QtQuick2::Scale::origin.y
218
219     The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
220     the rest of the item grows). By default the origin is 0, 0.
221 */
222
223 /*!
224     \qmlproperty real QtQuick2::Scale::xScale
225
226     The scaling factor for the X axis.
227 */
228
229 /*!
230     \qmlproperty real QtQuick2::Scale::yScale
231
232     The scaling factor for the Y axis.
233 */
234
235 /*!
236     \qmlclass Rotation QQuickRotation
237     \inqmlmodule QtQuick 2
238     \ingroup qml-transform-elements
239     \brief The Rotation object provides a way to rotate an Item.
240
241     The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
242     Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
243
244     The following example rotates a Rectangle around its interior point 25, 25:
245     \qml
246     Rectangle {
247         width: 100; height: 100
248         color: "blue"
249         transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
250     }
251     \endqml
252
253     Rotation also provides a way to specify 3D-like rotations for Items. For these types of
254     rotations you must specify the axis to rotate around in addition to the origin point.
255
256     The following example shows various 3D-like rotations applied to an \l Image.
257     \snippet doc/src/snippets/qml/rotation.qml 0
258
259     \image axisrotation.png
260
261     \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
262 */
263
264 /*!
265     \qmlproperty real QtQuick2::Rotation::origin.x
266     \qmlproperty real QtQuick2::Rotation::origin.y
267
268     The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
269     the rest of the item rotates). By default the origin is 0, 0.
270 */
271
272 /*!
273     \qmlproperty real QtQuick2::Rotation::axis.x
274     \qmlproperty real QtQuick2::Rotation::axis.y
275     \qmlproperty real QtQuick2::Rotation::axis.z
276
277     The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
278     as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
279
280     For a typical 3D-like rotation you will usually specify both the origin and the axis.
281
282     \image 3d-rotation-axis.png
283 */
284
285 /*!
286     \qmlproperty real QtQuick2::Rotation::angle
287
288     The angle to rotate, in degrees clockwise.
289 */
290
291 QQuickTransformPrivate::QQuickTransformPrivate()
292 {
293 }
294
295 QQuickTransform::QQuickTransform(QObject *parent)
296 : QObject(*(new QQuickTransformPrivate), parent)
297 {
298 }
299
300 QQuickTransform::QQuickTransform(QQuickTransformPrivate &dd, QObject *parent)
301 : QObject(dd, parent)
302 {
303 }
304
305 QQuickTransform::~QQuickTransform()
306 {
307     Q_D(QQuickTransform);
308     for (int ii = 0; ii < d->items.count(); ++ii) {
309         QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
310         p->transforms.removeOne(this);
311         p->dirty(QQuickItemPrivate::Transform);
312     }
313 }
314
315 void QQuickTransform::update()
316 {
317     Q_D(QQuickTransform);
318     for (int ii = 0; ii < d->items.count(); ++ii) {
319         QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
320         p->dirty(QQuickItemPrivate::Transform);
321     }
322 }
323
324 QQuickContents::QQuickContents(QQuickItem *item)
325 : m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
326 {
327 }
328
329 QQuickContents::~QQuickContents()
330 {
331     QList<QQuickItem *> children = m_item->childItems();
332     for (int i = 0; i < children.count(); ++i) {
333         QQuickItem *child = children.at(i);
334         QQuickItemPrivate::get(child)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
335     }
336 }
337
338 bool QQuickContents::calcHeight(QQuickItem *changed)
339 {
340     qreal oldy = m_y;
341     qreal oldheight = m_height;
342
343     if (changed) {
344         qreal top = oldy;
345         qreal bottom = oldy + oldheight;
346         qreal y = changed->y();
347         if (y + changed->height() > bottom)
348             bottom = y + changed->height();
349         if (y < top)
350             top = y;
351         m_y = top;
352         m_height = bottom - top;
353     } else {
354         qreal top = FLT_MAX;
355         qreal bottom = 0;
356         QList<QQuickItem *> children = m_item->childItems();
357         for (int i = 0; i < children.count(); ++i) {
358             QQuickItem *child = children.at(i);
359             qreal y = child->y();
360             if (y + child->height() > bottom)
361                 bottom = y + child->height();
362             if (y < top)
363                 top = y;
364         }
365         if (!children.isEmpty())
366             m_y = top;
367         m_height = qMax(bottom - top, qreal(0.0));
368     }
369
370     return (m_height != oldheight || m_y != oldy);
371 }
372
373 bool QQuickContents::calcWidth(QQuickItem *changed)
374 {
375     qreal oldx = m_x;
376     qreal oldwidth = m_width;
377
378     if (changed) {
379         qreal left = oldx;
380         qreal right = oldx + oldwidth;
381         qreal x = changed->x();
382         if (x + changed->width() > right)
383             right = x + changed->width();
384         if (x < left)
385             left = x;
386         m_x = left;
387         m_width = right - left;
388     } else {
389         qreal left = FLT_MAX;
390         qreal right = 0;
391         QList<QQuickItem *> children = m_item->childItems();
392         for (int i = 0; i < children.count(); ++i) {
393             QQuickItem *child = children.at(i);
394             qreal x = child->x();
395             if (x + child->width() > right)
396                 right = x + child->width();
397             if (x < left)
398                 left = x;
399         }
400         if (!children.isEmpty())
401             m_x = left;
402         m_width = qMax(right - left, qreal(0.0));
403     }
404
405     return (m_width != oldwidth || m_x != oldx);
406 }
407
408 void QQuickContents::complete()
409 {
410     QQuickItemPrivate::get(m_item)->addItemChangeListener(this, QQuickItemPrivate::Children);
411
412     QList<QQuickItem *> children = m_item->childItems();
413     for (int i = 0; i < children.count(); ++i) {
414         QQuickItem *child = children.at(i);
415         QQuickItemPrivate::get(child)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
416         //###what about changes to visibility?
417     }
418     calcGeometry();
419 }
420
421 void QQuickContents::updateRect()
422 {
423     QQuickItemPrivate::get(m_item)->emitChildrenRectChanged(rectF());
424 }
425
426 void QQuickContents::itemGeometryChanged(QQuickItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
427 {
428     Q_UNUSED(changed)
429     bool wChanged = false;
430     bool hChanged = false;
431     //### we can only pass changed if the left edge has moved left, or the right edge has moved right
432     if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
433         wChanged = calcWidth(/*changed*/);
434     if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
435         hChanged = calcHeight(/*changed*/);
436     if (wChanged || hChanged)
437         updateRect();
438 }
439
440 void QQuickContents::itemDestroyed(QQuickItem *item)
441 {
442     if (item)
443         QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
444     calcGeometry();
445 }
446
447 void QQuickContents::itemChildRemoved(QQuickItem *, QQuickItem *item)
448 {
449     if (item)
450         QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
451     calcGeometry();
452 }
453
454 void QQuickContents::itemChildAdded(QQuickItem *, QQuickItem *item)
455 {
456     if (item)
457         QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
458     calcGeometry(item);
459 }
460
461 QQuickItemKeyFilter::QQuickItemKeyFilter(QQuickItem *item)
462 : m_processPost(false), m_next(0)
463 {
464     QQuickItemPrivate *p = item?QQuickItemPrivate::get(item):0;
465     if (p) {
466         m_next = p->extra.value().keyHandler;
467         p->extra->keyHandler = this;
468     }
469 }
470
471 QQuickItemKeyFilter::~QQuickItemKeyFilter()
472 {
473 }
474
475 void QQuickItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
476 {
477     if (m_next) m_next->keyPressed(event, post);
478 }
479
480 void QQuickItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
481 {
482     if (m_next) m_next->keyReleased(event, post);
483 }
484
485 void QQuickItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
486 {
487     if (m_next)
488         m_next->inputMethodEvent(event, post);
489     else
490         event->ignore();
491 }
492
493 QVariant QQuickItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
494 {
495     if (m_next) return m_next->inputMethodQuery(query);
496     return QVariant();
497 }
498
499 void QQuickItemKeyFilter::componentComplete()
500 {
501     if (m_next) m_next->componentComplete();
502 }
503 /*!
504     \qmlclass KeyNavigation QQuickKeyNavigationAttached
505     \inqmlmodule QtQuick 2
506     \ingroup qml-basic-interaction-elements
507     \brief The KeyNavigation attached property supports key navigation by arrow keys.
508
509     Key-based user interfaces commonly allow the use of arrow keys to navigate between
510     focusable items.  The KeyNavigation attached property enables this behavior by providing a
511     convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
512
513     The following example provides key navigation for a 2x2 grid of items:
514
515     \snippet doc/src/snippets/qml/keynavigation.qml 0
516
517     The top-left item initially receives focus by setting \l {Item::}{focus} to
518     \c true. When an arrow key is pressed, the focus will move to the
519     appropriate item, as defined by the value that has been set for
520     the KeyNavigation \l left, \l right, \l up or \l down properties.
521
522     Note that if a KeyNavigation attached property receives the key press and release
523     events for a requested arrow or tab key, the event is accepted and does not
524     propagate any further.
525
526     By default, KeyNavigation receives key events after the item to which it is attached.
527     If the item accepts the key event, the KeyNavigation attached property will not
528     receive an event for that key.  Setting the \l priority property to
529     \c KeyNavigation.BeforeItem allows the event to be used for key navigation
530     before the item, rather than after.
531
532     If item to which the focus is switching is not enabled or visible, an attempt will
533     be made to skip this item and focus on the next. This is possible if there are
534     a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
535     or visible, they will also be skipped.
536
537     KeyNavigation will implicitly set the other direction to return focus to this item. So if you set
538     \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this
539     item. However, if that item's KeyNavigation has had right explicitly set then no change will occur.
540     This means that the above example could have been written, with the same behaviour, without specifing
541     KeyNavigation.right or KeyNavigation.down for any of the items.
542
543     \sa {Keys}{Keys attached property}
544 */
545
546 /*!
547     \qmlproperty Item QtQuick2::KeyNavigation::left
548     \qmlproperty Item QtQuick2::KeyNavigation::right
549     \qmlproperty Item QtQuick2::KeyNavigation::up
550     \qmlproperty Item QtQuick2::KeyNavigation::down
551     \qmlproperty Item QtQuick2::KeyNavigation::tab
552     \qmlproperty Item QtQuick2::KeyNavigation::backtab
553
554     These properties hold the item to assign focus to
555     when the left, right, up or down cursor keys, or the
556     tab key are pressed.
557 */
558
559 /*!
560     \qmlproperty Item QtQuick2::KeyNavigation::tab
561     \qmlproperty Item QtQuick2::KeyNavigation::backtab
562
563     These properties hold the item to assign focus to
564     when the Tab key or Shift+Tab key combination (Backtab) are pressed.
565 */
566
567 QQuickKeyNavigationAttached::QQuickKeyNavigationAttached(QObject *parent)
568 : QObject(*(new QQuickKeyNavigationAttachedPrivate), parent),
569   QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
570 {
571     m_processPost = true;
572 }
573
574 QQuickKeyNavigationAttached *
575 QQuickKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
576 {
577     return new QQuickKeyNavigationAttached(obj);
578 }
579
580 QQuickItem *QQuickKeyNavigationAttached::left() const
581 {
582     Q_D(const QQuickKeyNavigationAttached);
583     return d->left;
584 }
585
586 void QQuickKeyNavigationAttached::setLeft(QQuickItem *i)
587 {
588     Q_D(QQuickKeyNavigationAttached);
589     if (d->left == i)
590         return;
591     d->left = i;
592     d->leftSet = true;
593     QQuickKeyNavigationAttached* other =
594             qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
595     if (other && !other->d_func()->rightSet){
596         other->d_func()->right = qobject_cast<QQuickItem*>(parent());
597         emit other->rightChanged();
598     }
599     emit leftChanged();
600 }
601
602 QQuickItem *QQuickKeyNavigationAttached::right() const
603 {
604     Q_D(const QQuickKeyNavigationAttached);
605     return d->right;
606 }
607
608 void QQuickKeyNavigationAttached::setRight(QQuickItem *i)
609 {
610     Q_D(QQuickKeyNavigationAttached);
611     if (d->right == i)
612         return;
613     d->right = i;
614     d->rightSet = true;
615     QQuickKeyNavigationAttached* other =
616             qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
617     if (other && !other->d_func()->leftSet){
618         other->d_func()->left = qobject_cast<QQuickItem*>(parent());
619         emit other->leftChanged();
620     }
621     emit rightChanged();
622 }
623
624 QQuickItem *QQuickKeyNavigationAttached::up() const
625 {
626     Q_D(const QQuickKeyNavigationAttached);
627     return d->up;
628 }
629
630 void QQuickKeyNavigationAttached::setUp(QQuickItem *i)
631 {
632     Q_D(QQuickKeyNavigationAttached);
633     if (d->up == i)
634         return;
635     d->up = i;
636     d->upSet = true;
637     QQuickKeyNavigationAttached* other =
638             qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
639     if (other && !other->d_func()->downSet){
640         other->d_func()->down = qobject_cast<QQuickItem*>(parent());
641         emit other->downChanged();
642     }
643     emit upChanged();
644 }
645
646 QQuickItem *QQuickKeyNavigationAttached::down() const
647 {
648     Q_D(const QQuickKeyNavigationAttached);
649     return d->down;
650 }
651
652 void QQuickKeyNavigationAttached::setDown(QQuickItem *i)
653 {
654     Q_D(QQuickKeyNavigationAttached);
655     if (d->down == i)
656         return;
657     d->down = i;
658     d->downSet = true;
659     QQuickKeyNavigationAttached* other =
660             qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
661     if (other && !other->d_func()->upSet) {
662         other->d_func()->up = qobject_cast<QQuickItem*>(parent());
663         emit other->upChanged();
664     }
665     emit downChanged();
666 }
667
668 QQuickItem *QQuickKeyNavigationAttached::tab() const
669 {
670     Q_D(const QQuickKeyNavigationAttached);
671     return d->tab;
672 }
673
674 void QQuickKeyNavigationAttached::setTab(QQuickItem *i)
675 {
676     Q_D(QQuickKeyNavigationAttached);
677     if (d->tab == i)
678         return;
679     d->tab = i;
680     d->tabSet = true;
681     QQuickKeyNavigationAttached* other =
682             qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
683     if (other && !other->d_func()->backtabSet) {
684         other->d_func()->backtab = qobject_cast<QQuickItem*>(parent());
685         emit other->backtabChanged();
686     }
687     emit tabChanged();
688 }
689
690 QQuickItem *QQuickKeyNavigationAttached::backtab() const
691 {
692     Q_D(const QQuickKeyNavigationAttached);
693     return d->backtab;
694 }
695
696 void QQuickKeyNavigationAttached::setBacktab(QQuickItem *i)
697 {
698     Q_D(QQuickKeyNavigationAttached);
699     if (d->backtab == i)
700         return;
701     d->backtab = i;
702     d->backtabSet = true;
703     QQuickKeyNavigationAttached* other =
704             qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
705     if (other && !other->d_func()->tabSet) {
706         other->d_func()->tab = qobject_cast<QQuickItem*>(parent());
707         emit other->tabChanged();
708     }
709     emit backtabChanged();
710 }
711
712 /*!
713     \qmlproperty enumeration QtQuick2::KeyNavigation::priority
714
715     This property determines whether the keys are processed before
716     or after the attached item's own key handling.
717
718     \list
719     \li KeyNavigation.BeforeItem - process the key events before normal
720     item key processing.  If the event is used for key navigation, it will be accepted and will not
721     be passed on to the item.
722     \li KeyNavigation.AfterItem (default) - process the key events after normal item key
723     handling.  If the item accepts the key event it will not be
724     handled by the KeyNavigation attached property handler.
725     \endlist
726 */
727 QQuickKeyNavigationAttached::Priority QQuickKeyNavigationAttached::priority() const
728 {
729     return m_processPost ? AfterItem : BeforeItem;
730 }
731
732 void QQuickKeyNavigationAttached::setPriority(Priority order)
733 {
734     bool processPost = order == AfterItem;
735     if (processPost != m_processPost) {
736         m_processPost = processPost;
737         emit priorityChanged();
738     }
739 }
740
741 void QQuickKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
742 {
743     Q_D(QQuickKeyNavigationAttached);
744     event->ignore();
745
746     if (post != m_processPost) {
747         QQuickItemKeyFilter::keyPressed(event, post);
748         return;
749     }
750
751     bool mirror = false;
752     switch (event->key()) {
753     case Qt::Key_Left: {
754         if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
755             mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
756         QQuickItem* leftItem = mirror ? d->right : d->left;
757         if (leftItem) {
758             setFocusNavigation(leftItem, mirror ? "right" : "left");
759             event->accept();
760         }
761         break;
762     }
763     case Qt::Key_Right: {
764         if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
765             mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
766         QQuickItem* rightItem = mirror ? d->left : d->right;
767         if (rightItem) {
768             setFocusNavigation(rightItem, mirror ? "left" : "right");
769             event->accept();
770         }
771         break;
772     }
773     case Qt::Key_Up:
774         if (d->up) {
775             setFocusNavigation(d->up, "up");
776             event->accept();
777         }
778         break;
779     case Qt::Key_Down:
780         if (d->down) {
781             setFocusNavigation(d->down, "down");
782             event->accept();
783         }
784         break;
785     case Qt::Key_Tab:
786         if (d->tab) {
787             setFocusNavigation(d->tab, "tab");
788             event->accept();
789         }
790         break;
791     case Qt::Key_Backtab:
792         if (d->backtab) {
793             setFocusNavigation(d->backtab, "backtab");
794             event->accept();
795         }
796         break;
797     default:
798         break;
799     }
800
801     if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
802 }
803
804 void QQuickKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
805 {
806     Q_D(QQuickKeyNavigationAttached);
807     event->ignore();
808
809     if (post != m_processPost) {
810         QQuickItemKeyFilter::keyReleased(event, post);
811         return;
812     }
813
814     bool mirror = false;
815     switch (event->key()) {
816     case Qt::Key_Left:
817         if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
818             mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
819         if (mirror ? d->right : d->left)
820             event->accept();
821         break;
822     case Qt::Key_Right:
823         if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
824             mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
825         if (mirror ? d->left : d->right)
826             event->accept();
827         break;
828     case Qt::Key_Up:
829         if (d->up) {
830             event->accept();
831         }
832         break;
833     case Qt::Key_Down:
834         if (d->down) {
835             event->accept();
836         }
837         break;
838     case Qt::Key_Tab:
839         if (d->tab) {
840             event->accept();
841         }
842         break;
843     case Qt::Key_Backtab:
844         if (d->backtab) {
845             event->accept();
846         }
847         break;
848     default:
849         break;
850     }
851
852     if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
853 }
854
855 void QQuickKeyNavigationAttached::setFocusNavigation(QQuickItem *currentItem, const char *dir)
856 {
857     QQuickItem *initialItem = currentItem;
858     bool isNextItem = false;
859     do {
860         isNextItem = false;
861         if (currentItem->isVisible() && currentItem->isEnabled()) {
862             currentItem->setFocus(true);
863         } else {
864             QObject *attached =
865                 qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(currentItem, false);
866             if (attached) {
867                 QQuickItem *tempItem = qvariant_cast<QQuickItem*>(attached->property(dir));
868                 if (tempItem) {
869                     currentItem = tempItem;
870                     isNextItem = true;
871                 }
872             }
873         }
874     }
875     while (currentItem != initialItem && isNextItem);
876 }
877
878 const QQuickKeysAttached::SigMap QQuickKeysAttached::sigMap[] = {
879     { Qt::Key_Left, "leftPressed" },
880     { Qt::Key_Right, "rightPressed" },
881     { Qt::Key_Up, "upPressed" },
882     { Qt::Key_Down, "downPressed" },
883     { Qt::Key_Tab, "tabPressed" },
884     { Qt::Key_Backtab, "backtabPressed" },
885     { Qt::Key_Asterisk, "asteriskPressed" },
886     { Qt::Key_NumberSign, "numberSignPressed" },
887     { Qt::Key_Escape, "escapePressed" },
888     { Qt::Key_Return, "returnPressed" },
889     { Qt::Key_Enter, "enterPressed" },
890     { Qt::Key_Delete, "deletePressed" },
891     { Qt::Key_Space, "spacePressed" },
892     { Qt::Key_Back, "backPressed" },
893     { Qt::Key_Cancel, "cancelPressed" },
894     { Qt::Key_Select, "selectPressed" },
895     { Qt::Key_Yes, "yesPressed" },
896     { Qt::Key_No, "noPressed" },
897     { Qt::Key_Context1, "context1Pressed" },
898     { Qt::Key_Context2, "context2Pressed" },
899     { Qt::Key_Context3, "context3Pressed" },
900     { Qt::Key_Context4, "context4Pressed" },
901     { Qt::Key_Call, "callPressed" },
902     { Qt::Key_Hangup, "hangupPressed" },
903     { Qt::Key_Flip, "flipPressed" },
904     { Qt::Key_Menu, "menuPressed" },
905     { Qt::Key_VolumeUp, "volumeUpPressed" },
906     { Qt::Key_VolumeDown, "volumeDownPressed" },
907     { 0, 0 }
908 };
909
910 bool QQuickKeysAttachedPrivate::isConnected(const char *signalName)
911 {
912     return isSignalConnected(signalIndex(signalName));
913 }
914
915 /*!
916     \qmlclass Keys QQuickKeysAttached
917     \inqmlmodule QtQuick 2
918     \ingroup qml-basic-interaction-elements
919     \brief The Keys attached property provides key handling to Items.
920
921     All visual primitives support key handling via the Keys
922     attached property.  Keys can be handled via the onPressed
923     and onReleased signal properties.
924
925     The signal properties have a \l KeyEvent parameter, named
926     \e event which contains details of the event.  If a key is
927     handled \e event.accepted should be set to true to prevent the
928     event from propagating up the item hierarchy.
929
930     \section1 Example Usage
931
932     The following example shows how the general onPressed handler can
933     be used to test for a certain key; in this case, the left cursor
934     key:
935
936     \snippet doc/src/snippets/qml/keys/keys-pressed.qml key item
937
938     Some keys may alternatively be handled via specific signal properties,
939     for example \e onSelectPressed.  These handlers automatically set
940     \e event.accepted to true.
941
942     \snippet doc/src/snippets/qml/keys/keys-handler.qml key item
943
944     See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
945
946     \section1 Key Handling Priorities
947
948     The Keys attached property can be configured to handle key events
949     before or after the item it is attached to. This makes it possible
950     to intercept events in order to override an item's default behavior,
951     or act as a fallback for keys not handled by the item.
952
953     If \l priority is Keys.BeforeItem (default) the order of key event processing is:
954
955     \list 1
956     \li Items specified in \c forwardTo
957     \li specific key handlers, e.g. onReturnPressed
958     \li onKeyPress, onKeyRelease handlers
959     \li Item specific key handling, e.g. TextInput key handling
960     \li parent item
961     \endlist
962
963     If priority is Keys.AfterItem the order of key event processing is:
964
965     \list 1
966     \li Item specific key handling, e.g. TextInput key handling
967     \li Items specified in \c forwardTo
968     \li specific key handlers, e.g. onReturnPressed
969     \li onKeyPress, onKeyRelease handlers
970     \li parent item
971     \endlist
972
973     If the event is accepted during any of the above steps, key
974     propagation stops.
975
976     \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
977 */
978
979 /*!
980     \qmlproperty bool QtQuick2::Keys::enabled
981
982     This flags enables key handling if true (default); otherwise
983     no key handlers will be called.
984 */
985
986 /*!
987     \qmlproperty enumeration QtQuick2::Keys::priority
988
989     This property determines whether the keys are processed before
990     or after the attached item's own key handling.
991
992     \list
993     \li Keys.BeforeItem (default) - process the key events before normal
994     item key processing.  If the event is accepted it will not
995     be passed on to the item.
996     \li Keys.AfterItem - process the key events after normal item key
997     handling.  If the item accepts the key event it will not be
998     handled by the Keys attached property handler.
999     \endlist
1000 */
1001
1002 /*!
1003     \qmlproperty list<Object> QtQuick2::Keys::forwardTo
1004
1005     This property provides a way to forward key presses, key releases, and keyboard input
1006     coming from input methods to other items. This can be useful when you want
1007     one item to handle some keys (e.g. the up and down arrow keys), and another item to
1008     handle other keys (e.g. the left and right arrow keys).  Once an item that has been
1009     forwarded keys accepts the event it is no longer forwarded to items later in the
1010     list.
1011
1012     This example forwards key events to two lists:
1013     \qml
1014     Item {
1015         ListView {
1016             id: list1
1017             // ...
1018         }
1019         ListView {
1020             id: list2
1021             // ...
1022         }
1023         Keys.forwardTo: [list1, list2]
1024         focus: true
1025     }
1026     \endqml
1027 */
1028
1029 /*!
1030     \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
1031
1032     This handler is called when a key has been pressed. The \a event
1033     parameter provides information about the event.
1034 */
1035
1036 /*!
1037     \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
1038
1039     This handler is called when a key has been released. The \a event
1040     parameter provides information about the event.
1041 */
1042
1043 /*!
1044     \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
1045
1046     This handler is called when the digit '0' has been pressed. The \a event
1047     parameter provides information about the event.
1048 */
1049
1050 /*!
1051     \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
1052
1053     This handler is called when the digit '1' has been pressed. The \a event
1054     parameter provides information about the event.
1055 */
1056
1057 /*!
1058     \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
1059
1060     This handler is called when the digit '2' has been pressed. The \a event
1061     parameter provides information about the event.
1062 */
1063
1064 /*!
1065     \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
1066
1067     This handler is called when the digit '3' has been pressed. The \a event
1068     parameter provides information about the event.
1069 */
1070
1071 /*!
1072     \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
1073
1074     This handler is called when the digit '4' has been pressed. The \a event
1075     parameter provides information about the event.
1076 */
1077
1078 /*!
1079     \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
1080
1081     This handler is called when the digit '5' has been pressed. The \a event
1082     parameter provides information about the event.
1083 */
1084
1085 /*!
1086     \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
1087
1088     This handler is called when the digit '6' has been pressed. The \a event
1089     parameter provides information about the event.
1090 */
1091
1092 /*!
1093     \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
1094
1095     This handler is called when the digit '7' has been pressed. The \a event
1096     parameter provides information about the event.
1097 */
1098
1099 /*!
1100     \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
1101
1102     This handler is called when the digit '8' has been pressed. The \a event
1103     parameter provides information about the event.
1104 */
1105
1106 /*!
1107     \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
1108
1109     This handler is called when the digit '9' has been pressed. The \a event
1110     parameter provides information about the event.
1111 */
1112
1113 /*!
1114     \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
1115
1116     This handler is called when the Left arrow has been pressed. The \a event
1117     parameter provides information about the event.
1118 */
1119
1120 /*!
1121     \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
1122
1123     This handler is called when the Right arrow has been pressed. The \a event
1124     parameter provides information about the event.
1125 */
1126
1127 /*!
1128     \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
1129
1130     This handler is called when the Up arrow has been pressed. The \a event
1131     parameter provides information about the event.
1132 */
1133
1134 /*!
1135     \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
1136
1137     This handler is called when the Down arrow has been pressed. The \a event
1138     parameter provides information about the event.
1139 */
1140
1141 /*!
1142     \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
1143
1144     This handler is called when the Tab key has been pressed. The \a event
1145     parameter provides information about the event.
1146 */
1147
1148 /*!
1149     \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
1150
1151     This handler is called when the Shift+Tab key combination (Backtab) has
1152     been pressed. The \a event parameter provides information about the event.
1153 */
1154
1155 /*!
1156     \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
1157
1158     This handler is called when the Asterisk '*' has been pressed. The \a event
1159     parameter provides information about the event.
1160 */
1161
1162 /*!
1163     \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
1164
1165     This handler is called when the Escape key has been pressed. The \a event
1166     parameter provides information about the event.
1167 */
1168
1169 /*!
1170     \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
1171
1172     This handler is called when the Return key has been pressed. The \a event
1173     parameter provides information about the event.
1174 */
1175
1176 /*!
1177     \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
1178
1179     This handler is called when the Enter key has been pressed. The \a event
1180     parameter provides information about the event.
1181 */
1182
1183 /*!
1184     \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
1185
1186     This handler is called when the Delete key has been pressed. The \a event
1187     parameter provides information about the event.
1188 */
1189
1190 /*!
1191     \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
1192
1193     This handler is called when the Space key has been pressed. The \a event
1194     parameter provides information about the event.
1195 */
1196
1197 /*!
1198     \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
1199
1200     This handler is called when the Back key has been pressed. The \a event
1201     parameter provides information about the event.
1202 */
1203
1204 /*!
1205     \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
1206
1207     This handler is called when the Cancel key has been pressed. The \a event
1208     parameter provides information about the event.
1209 */
1210
1211 /*!
1212     \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
1213
1214     This handler is called when the Select key has been pressed. The \a event
1215     parameter provides information about the event.
1216 */
1217
1218 /*!
1219     \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
1220
1221     This handler is called when the Yes key has been pressed. The \a event
1222     parameter provides information about the event.
1223 */
1224
1225 /*!
1226     \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
1227
1228     This handler is called when the No key has been pressed. The \a event
1229     parameter provides information about the event.
1230 */
1231
1232 /*!
1233     \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
1234
1235     This handler is called when the Context1 key has been pressed. The \a event
1236     parameter provides information about the event.
1237 */
1238
1239 /*!
1240     \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
1241
1242     This handler is called when the Context2 key has been pressed. The \a event
1243     parameter provides information about the event.
1244 */
1245
1246 /*!
1247     \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
1248
1249     This handler is called when the Context3 key has been pressed. The \a event
1250     parameter provides information about the event.
1251 */
1252
1253 /*!
1254     \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
1255
1256     This handler is called when the Context4 key has been pressed. The \a event
1257     parameter provides information about the event.
1258 */
1259
1260 /*!
1261     \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
1262
1263     This handler is called when the Call key has been pressed. The \a event
1264     parameter provides information about the event.
1265 */
1266
1267 /*!
1268     \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
1269
1270     This handler is called when the Hangup key has been pressed. The \a event
1271     parameter provides information about the event.
1272 */
1273
1274 /*!
1275     \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
1276
1277     This handler is called when the Flip key has been pressed. The \a event
1278     parameter provides information about the event.
1279 */
1280
1281 /*!
1282     \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
1283
1284     This handler is called when the Menu key has been pressed. The \a event
1285     parameter provides information about the event.
1286 */
1287
1288 /*!
1289     \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
1290
1291     This handler is called when the VolumeUp key has been pressed. The \a event
1292     parameter provides information about the event.
1293 */
1294
1295 /*!
1296     \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
1297
1298     This handler is called when the VolumeDown key has been pressed. The \a event
1299     parameter provides information about the event.
1300 */
1301
1302 QQuickKeysAttached::QQuickKeysAttached(QObject *parent)
1303 : QObject(*(new QQuickKeysAttachedPrivate), parent),
1304   QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
1305 {
1306     Q_D(QQuickKeysAttached);
1307     m_processPost = false;
1308     d->item = qobject_cast<QQuickItem*>(parent);
1309 }
1310
1311 QQuickKeysAttached::~QQuickKeysAttached()
1312 {
1313 }
1314
1315 QQuickKeysAttached::Priority QQuickKeysAttached::priority() const
1316 {
1317     return m_processPost ? AfterItem : BeforeItem;
1318 }
1319
1320 void QQuickKeysAttached::setPriority(Priority order)
1321 {
1322     bool processPost = order == AfterItem;
1323     if (processPost != m_processPost) {
1324         m_processPost = processPost;
1325         emit priorityChanged();
1326     }
1327 }
1328
1329 void QQuickKeysAttached::componentComplete()
1330 {
1331     Q_D(QQuickKeysAttached);
1332     if (d->item) {
1333         for (int ii = 0; ii < d->targets.count(); ++ii) {
1334             QQuickItem *targetItem = d->targets.at(ii);
1335             if (targetItem && (targetItem->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1336                 d->item->setFlag(QQuickItem::ItemAcceptsInputMethod);
1337                 break;
1338             }
1339         }
1340     }
1341 }
1342
1343 void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
1344 {
1345     Q_D(QQuickKeysAttached);
1346     if (post != m_processPost || !d->enabled || d->inPress) {
1347         event->ignore();
1348         QQuickItemKeyFilter::keyPressed(event, post);
1349         return;
1350     }
1351
1352     // first process forwards
1353     if (d->item && d->item->canvas()) {
1354         d->inPress = true;
1355         for (int ii = 0; ii < d->targets.count(); ++ii) {
1356             QQuickItem *i = d->targets.at(ii);
1357             if (i && i->isVisible()) {
1358                 d->item->canvas()->sendEvent(i, event);
1359                 if (event->isAccepted()) {
1360                     d->inPress = false;
1361                     return;
1362                 }
1363             }
1364         }
1365         d->inPress = false;
1366     }
1367
1368     QQuickKeyEvent ke(*event);
1369     QByteArray keySignal = keyToSignal(event->key());
1370     if (!keySignal.isEmpty()) {
1371         keySignal += "(QQuickKeyEvent*)";
1372         if (d->isConnected(keySignal)) {
1373             // If we specifically handle a key then default to accepted
1374             ke.setAccepted(true);
1375             int idx = QQuickKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1376             metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QQuickKeyEvent*, &ke));
1377         }
1378     }
1379     if (!ke.isAccepted())
1380         emit pressed(&ke);
1381     event->setAccepted(ke.isAccepted());
1382
1383     if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
1384 }
1385
1386 void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
1387 {
1388     Q_D(QQuickKeysAttached);
1389     if (post != m_processPost || !d->enabled || d->inRelease) {
1390         event->ignore();
1391         QQuickItemKeyFilter::keyReleased(event, post);
1392         return;
1393     }
1394
1395     if (d->item && d->item->canvas()) {
1396         d->inRelease = true;
1397         for (int ii = 0; ii < d->targets.count(); ++ii) {
1398             QQuickItem *i = d->targets.at(ii);
1399             if (i && i->isVisible()) {
1400                 d->item->canvas()->sendEvent(i, event);
1401                 if (event->isAccepted()) {
1402                     d->inRelease = false;
1403                     return;
1404                 }
1405             }
1406         }
1407         d->inRelease = false;
1408     }
1409
1410     QQuickKeyEvent ke(*event);
1411     emit released(&ke);
1412     event->setAccepted(ke.isAccepted());
1413
1414     if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
1415 }
1416
1417 void QQuickKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1418 {
1419     Q_D(QQuickKeysAttached);
1420     if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
1421         d->inIM = true;
1422         for (int ii = 0; ii < d->targets.count(); ++ii) {
1423             QQuickItem *i = d->targets.at(ii);
1424             if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1425                 d->item->canvas()->sendEvent(i, event);
1426                 if (event->isAccepted()) {
1427                     d->imeItem = i;
1428                     d->inIM = false;
1429                     return;
1430                 }
1431             }
1432         }
1433         d->inIM = false;
1434     }
1435     QQuickItemKeyFilter::inputMethodEvent(event, post);
1436 }
1437
1438 QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1439 {
1440     Q_D(const QQuickKeysAttached);
1441     if (d->item) {
1442         for (int ii = 0; ii < d->targets.count(); ++ii) {
1443             QQuickItem *i = d->targets.at(ii);
1444             if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod) && i == d->imeItem) {
1445                 //### how robust is i == d->imeItem check?
1446                 QVariant v = i->inputMethodQuery(query);
1447                 if (v.userType() == QVariant::RectF)
1448                     v = d->item->mapRectFromItem(i, v.toRectF());  //### cost?
1449                 return v;
1450             }
1451         }
1452     }
1453     return QQuickItemKeyFilter::inputMethodQuery(query);
1454 }
1455
1456 QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
1457 {
1458     return new QQuickKeysAttached(obj);
1459 }
1460
1461 /*!
1462     \qmlclass LayoutMirroring QQuickLayoutMirroringAttached
1463     \inqmlmodule QtQuick 2
1464     \ingroup qml-utility-elements
1465     \brief The LayoutMirroring attached property is used to mirror layout behavior.
1466
1467     The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
1468     \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
1469     and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
1470     anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
1471     horizontal layout of child items.
1472
1473     Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
1474     only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
1475     behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
1476     for an item, mirroring is not enabled.
1477
1478     The following example shows mirroring in action. The \l Row below is specified as being anchored
1479     to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
1480     reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
1481     from left to right by default, they are now positioned from right to left instead, as demonstrated
1482     by the numbering and opacity of the items:
1483
1484     \snippet doc/src/snippets/qml/layoutmirroring.qml 0
1485
1486     \image layoutmirroring.png
1487
1488     Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
1489     layout versions of an application to target different language areas. The \l childrenInherit
1490     property allows layout mirroring to be applied without manually setting layout configurations
1491     for every item in an application. Keep in mind, however, that mirroring does not affect any
1492     positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
1493     mirroring enabled, it will often be necessary to apply some layout fixes to support the
1494     desired layout direction. Also, it may be necessary to disable the mirroring of individual
1495     child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
1496     mirroring is not the desired behavior, or if the child item already implements mirroring in
1497     some custom way.
1498
1499     See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
1500     other related features to implement right-to-left support for an application.
1501 */
1502
1503 /*!
1504     \qmlproperty bool QtQuick2::LayoutMirroring::enabled
1505
1506     This property holds whether the item's layout is mirrored horizontally. Setting this to true
1507     horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
1508     and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
1509     (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
1510     this also mirrors the horizontal layout direction of the item.
1511
1512     The default value is false.
1513 */
1514
1515 /*!
1516     \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
1517
1518     This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
1519     is inherited by its children.
1520
1521     The default value is false.
1522 */
1523
1524
1525 QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
1526 {
1527     if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) {
1528         itemPrivate = QQuickItemPrivate::get(item);
1529         itemPrivate->extra.value().layoutDirectionAttached = this;
1530     } else
1531         qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
1532 }
1533
1534 QQuickLayoutMirroringAttached * QQuickLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
1535 {
1536     return new QQuickLayoutMirroringAttached(object);
1537 }
1538
1539 bool QQuickLayoutMirroringAttached::enabled() const
1540 {
1541     return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
1542 }
1543
1544 void QQuickLayoutMirroringAttached::setEnabled(bool enabled)
1545 {
1546     if (!itemPrivate)
1547         return;
1548
1549     itemPrivate->isMirrorImplicit = false;
1550     if (enabled != itemPrivate->effectiveLayoutMirror) {
1551         itemPrivate->setLayoutMirror(enabled);
1552         if (itemPrivate->inheritMirrorFromItem)
1553              itemPrivate->resolveLayoutMirror();
1554     }
1555 }
1556
1557 void QQuickLayoutMirroringAttached::resetEnabled()
1558 {
1559     if (itemPrivate && !itemPrivate->isMirrorImplicit) {
1560         itemPrivate->isMirrorImplicit = true;
1561         itemPrivate->resolveLayoutMirror();
1562     }
1563 }
1564
1565 bool QQuickLayoutMirroringAttached::childrenInherit() const
1566 {
1567     return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
1568 }
1569
1570 void QQuickLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
1571     if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
1572         itemPrivate->inheritMirrorFromItem = childrenInherit;
1573         itemPrivate->resolveLayoutMirror();
1574         childrenInheritChanged();
1575     }
1576 }
1577
1578 void QQuickItemPrivate::resolveLayoutMirror()
1579 {
1580     Q_Q(QQuickItem);
1581     if (QQuickItem *parentItem = q->parentItem()) {
1582         QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parentItem);
1583         setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
1584     } else {
1585         setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
1586     }
1587 }
1588
1589 void QQuickItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
1590 {
1591     inherit = inherit || inheritMirrorFromItem;
1592     if (!isMirrorImplicit && inheritMirrorFromItem)
1593         mirror = effectiveLayoutMirror;
1594     if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
1595         return;
1596
1597     inheritMirrorFromParent = inherit;
1598     inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
1599
1600     if (isMirrorImplicit)
1601         setLayoutMirror(inherit ? inheritedLayoutMirror : false);
1602     for (int i = 0; i < childItems.count(); ++i) {
1603         if (QQuickItem *child = qobject_cast<QQuickItem *>(childItems.at(i))) {
1604             QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
1605             childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
1606         }
1607     }
1608 }
1609
1610 void QQuickItemPrivate::setLayoutMirror(bool mirror)
1611 {
1612     if (mirror != effectiveLayoutMirror) {
1613         effectiveLayoutMirror = mirror;
1614         if (_anchors) {
1615             QQuickAnchorsPrivate *anchor_d = QQuickAnchorsPrivate::get(_anchors);
1616             anchor_d->fillChanged();
1617             anchor_d->centerInChanged();
1618             anchor_d->updateHorizontalAnchors();
1619             emit _anchors->mirroredChanged();
1620         }
1621         mirrorChange();
1622         if (extra.isAllocated() && extra->layoutDirectionAttached) {
1623             emit extra->layoutDirectionAttached->enabledChanged();
1624         }
1625     }
1626 }
1627
1628 void QQuickItemPrivate::setAccessibleFlagAndListener()
1629 {
1630     Q_Q(QQuickItem);
1631     QQuickItem *item = q;
1632     while (item) {
1633         if (item->d_func()->isAccessible)
1634             break; // already set - grandparents should have the flag set as well.
1635
1636         item->d_func()->isAccessible = true;
1637         item = item->d_func()->parentItem;
1638     }
1639 }
1640
1641 void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
1642 {
1643     Q_Q(QQuickItem);
1644     Q_ASSERT(scope);
1645
1646     QQuickItemPrivate *scopePrivate = QQuickItemPrivate::get(scope);
1647
1648     QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
1649     // Correct focus chain in scope
1650     if (oldSubFocusItem) {
1651         QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1652         while (sfi && sfi != scope) {
1653             QQuickItemPrivate::get(sfi)->subFocusItem = 0;
1654             sfi = sfi->parentItem();
1655         }
1656     }
1657
1658     if (focus) {
1659         scopePrivate->subFocusItem = q;
1660         QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1661         while (sfi && sfi != scope) {
1662             QQuickItemPrivate::get(sfi)->subFocusItem = q;
1663             sfi = sfi->parentItem();
1664         }
1665     } else {
1666         scopePrivate->subFocusItem = 0;
1667     }
1668 }
1669
1670
1671 /*!
1672     \class QQuickItem
1673     \brief The QQuickItem class provides the most basic of all visual items in QML.
1674
1675     \inmodule QtQuick
1676
1677     All visual items in Qt Quick inherit from QQuickItem.  Although QQuickItem
1678     has no visual appearance, it defines all the properties that are
1679     common across visual items - such as the x and y position, the
1680     width and height, \l {anchor-layout}{anchoring} and key handling.
1681
1682     You can subclass QQuickItem to provide your own custom visual item that inherits
1683     these features. Note that, because it does not draw anything, QQuickItem sets the
1684     QGraphicsItem::ItemHasNoContents flag. If you subclass QQuickItem to create a visual
1685     item, you will need to unset this flag.
1686
1687 */
1688
1689 /*!
1690     \qmlclass Item QQuickItem
1691     \inherits QtObject
1692     \inqmlmodule QtQuick 2
1693     \ingroup qml-basic-visual-elements
1694     \brief The Item is the most basic of all visual items in QML.
1695
1696     All visual items in Qt Quick inherit from Item.  Although Item
1697     has no visual appearance, it defines all the properties that are
1698     common across visual items - such as the x and y position, the
1699     width and height, \l {anchor-layout}{anchoring} and key handling.
1700
1701     Item is also useful for grouping items together.
1702
1703     \qml
1704     Item {
1705         Image {
1706             source: "tile.png"
1707         }
1708         Image {
1709             x: 80
1710             width: 100
1711             height: 100
1712             source: "tile.png"
1713         }
1714         Image {
1715             x: 190
1716             width: 100
1717             height: 100
1718             fillMode: Image.Tile
1719             source: "tile.png"
1720         }
1721     }
1722     \endqml
1723
1724
1725     \section1 Key Handling
1726
1727     Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1728     attached property.  The \e Keys attached property provides basic handlers such
1729     as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1730     as well as handlers for specific keys, such as
1731     \l {Keys::onCancelPressed}{onCancelPressed}.  The example below
1732     assigns \l {qmlfocus}{focus} to the item and handles
1733     the Left key via the general \e onPressed handler and the Select key via the
1734     onSelectPressed handler:
1735
1736     \qml
1737     Item {
1738         focus: true
1739         Keys.onPressed: {
1740             if (event.key == Qt.Key_Left) {
1741                 console.log("move left");
1742                 event.accepted = true;
1743             }
1744         }
1745         Keys.onSelectPressed: console.log("Selected");
1746     }
1747     \endqml
1748
1749     See the \l {Keys}{Keys} attached property for detailed documentation.
1750
1751     \section1 Layout Mirroring
1752
1753     Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1754
1755 */
1756
1757 /*!
1758     \fn void QQuickItem::childrenRectChanged(const QRectF &)
1759     \internal
1760 */
1761
1762 /*!
1763     \fn void QQuickItem::baselineOffsetChanged(qreal)
1764     \internal
1765 */
1766
1767 /*!
1768     \fn void QQuickItem::stateChanged(const QString &state)
1769     \internal
1770 */
1771
1772 /*!
1773     \fn void QQuickItem::parentChanged(QQuickItem *)
1774     \internal
1775 */
1776
1777 /*!
1778     \fn void QQuickItem::smoothChanged(bool)
1779     \internal
1780 */
1781
1782 /*!
1783     \fn void QQuickItem::clipChanged(bool)
1784     \internal
1785 */
1786
1787 /*! \fn void QQuickItem::transformOriginChanged(TransformOrigin)
1788   \internal
1789 */
1790
1791 /*!
1792     \fn void QQuickItem::focusChanged(bool)
1793     \internal
1794 */
1795
1796 /*!
1797     \fn void QQuickItem::activeFocusChanged(bool)
1798     \internal
1799 */
1800 /*!
1801     \fn QQuickItem::QQuickItem(QQuickItem *parent)
1802
1803     Constructs a QQuickItem with the given \a parent.
1804 */
1805 QQuickItem::QQuickItem(QQuickItem* parent)
1806 : QObject(*(new QQuickItemPrivate), parent)
1807 {
1808     Q_D(QQuickItem);
1809     d->init(parent);
1810 }
1811
1812 /*! \internal
1813 */
1814 QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
1815 : QObject(dd, parent)
1816 {
1817     Q_D(QQuickItem);
1818     d->init(parent);
1819 }
1820
1821 #ifndef QT_NO_DEBUG
1822 static int qt_item_count = 0;
1823
1824 static void qt_print_item_count()
1825 {
1826     qDebug("Number of leaked items: %i", qt_item_count);
1827     qt_item_count = -1;
1828 }
1829 #endif
1830
1831 /*!
1832     Destroys the QQuickItem.
1833 */
1834 QQuickItem::~QQuickItem()
1835 {
1836 #ifndef QT_NO_DEBUG
1837     --qt_item_count;
1838     if (qt_item_count < 0)
1839         qDebug("Item destroyed after qt_print_item_count() was called.");
1840 #endif
1841
1842     Q_D(QQuickItem);
1843
1844     if (d->canvasRefCount > 1)
1845         d->canvasRefCount = 1; // Make sure canvas is set to null in next call to derefCanvas().
1846     if (d->parentItem)
1847         setParentItem(0);
1848     else if (d->canvas)
1849         d->derefCanvas();
1850
1851     // XXX todo - optimize
1852     while (!d->childItems.isEmpty())
1853         d->childItems.first()->setParentItem(0);
1854
1855     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1856         QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1857         if (anchor)
1858             anchor->clearItem(this);
1859     }
1860
1861     /*
1862         update item anchors that depended on us unless they are our child (and will also be destroyed),
1863         or our sibling, and our parent is also being destroyed.
1864     */
1865     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1866         QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1867         if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
1868             anchor->update();
1869     }
1870
1871     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1872         const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1873         if (change.types & QQuickItemPrivate::Destroyed)
1874             change.listener->itemDestroyed(this);
1875     }
1876
1877     d->changeListeners.clear();
1878
1879     if (d->extra.isAllocated()) {
1880         delete d->extra->contents; d->extra->contents = 0;
1881         delete d->extra->layer; d->extra->layer = 0;
1882     }
1883
1884     delete d->_anchors; d->_anchors = 0;
1885     delete d->_stateGroup; d->_stateGroup = 0;
1886 }
1887
1888 /*!
1889     \qmlproperty enumeration QtQuick2::Item::transformOrigin
1890     This property holds the origin point around which scale and rotation transform.
1891
1892     Nine transform origins are available, as shown in the image below.
1893
1894     \image declarative-transformorigin.png
1895
1896     This example rotates an image around its bottom-right corner.
1897     \qml
1898     Image {
1899         source: "myimage.png"
1900         transformOrigin: Item.BottomRight
1901         rotation: 45
1902     }
1903     \endqml
1904
1905     The default transform origin is \c Item.Center.
1906
1907     To set an arbitrary transform origin point use the \l Scale or \l Rotation
1908     transform elements.
1909 */
1910
1911 /*!
1912     \qmlproperty Item QtQuick2::Item::parent
1913     This property holds the parent of the item.
1914 */
1915
1916 /*!
1917     \property QQuickItem::parent
1918     This property holds the parent of the item.
1919 */
1920 void QQuickItem::setParentItem(QQuickItem *parentItem)
1921 {
1922     Q_D(QQuickItem);
1923     if (parentItem == d->parentItem)
1924         return;
1925
1926     if (parentItem) {
1927         QQuickItem *itemAncestor = parentItem->parentItem();
1928         while (itemAncestor != 0) {
1929             if (itemAncestor == this) {
1930                 qWarning("QQuickItem::setParentItem: Parent is already part of this items subtree.");
1931                 return;
1932             }
1933             itemAncestor = itemAncestor->parentItem();
1934         }
1935     }
1936
1937     d->removeFromDirtyList();
1938
1939     QQuickItem *oldParentItem = d->parentItem;
1940     QQuickItem *scopeFocusedItem = 0;
1941
1942     if (oldParentItem) {
1943         QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem);
1944
1945         QQuickItem *scopeItem = 0;
1946
1947         if (hasFocus())
1948             scopeFocusedItem = this;
1949         else if (!isFocusScope() && d->subFocusItem)
1950             scopeFocusedItem = d->subFocusItem;
1951
1952         if (scopeFocusedItem) {
1953             scopeItem = oldParentItem;
1954             while (!scopeItem->isFocusScope() && scopeItem->parentItem())
1955                 scopeItem = scopeItem->parentItem();
1956             if (d->canvas) {
1957                 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1958                                                                 QQuickCanvasPrivate::DontChangeFocusProperty);
1959                 if (scopeFocusedItem != this)
1960                     QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, true);
1961             } else {
1962                 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, false);
1963             }
1964         }
1965
1966         const bool wasVisible = isVisible();
1967         op->removeChild(this);
1968         if (wasVisible) {
1969             emit oldParentItem->visibleChildrenChanged();
1970         }
1971     } else if (d->canvas) {
1972         QQuickCanvasPrivate::get(d->canvas)->parentlessItems.remove(this);
1973     }
1974
1975     QQuickCanvas *oldParentCanvas = oldParentItem ? QQuickItemPrivate::get(oldParentItem)->canvas : 0;
1976     QQuickCanvas *parentCanvas = parentItem ? QQuickItemPrivate::get(parentItem)->canvas : 0;
1977     if (oldParentCanvas == parentCanvas) {
1978         // Avoid freeing and reallocating resources if the canvas stays the same.
1979         d->parentItem = parentItem;
1980     } else {
1981         if (oldParentCanvas)
1982             d->derefCanvas();
1983         d->parentItem = parentItem;
1984         if (parentCanvas)
1985             d->refCanvas(parentCanvas);
1986     }
1987
1988     d->dirty(QQuickItemPrivate::ParentChanged);
1989
1990     if (d->parentItem)
1991         QQuickItemPrivate::get(d->parentItem)->addChild(this);
1992     else if (d->canvas)
1993         QQuickCanvasPrivate::get(d->canvas)->parentlessItems.insert(this);
1994
1995     d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
1996     d->setEffectiveEnableRecur(0, d->calcEffectiveEnable());
1997
1998     if (d->parentItem) {
1999         if (!scopeFocusedItem) {
2000             if (hasFocus())
2001                 scopeFocusedItem = this;
2002             else if (!isFocusScope() && d->subFocusItem)
2003                 scopeFocusedItem = d->subFocusItem;
2004         }
2005
2006         if (scopeFocusedItem) {
2007             // We need to test whether this item becomes scope focused
2008             QQuickItem *scopeItem = d->parentItem;
2009             while (!scopeItem->isFocusScope() && scopeItem->parentItem())
2010                 scopeItem = scopeItem->parentItem();
2011
2012             if (QQuickItemPrivate::get(scopeItem)->subFocusItem
2013                     || (!scopeItem->isFocusScope() && scopeItem->hasFocus())) {
2014                 if (scopeFocusedItem != this)
2015                     QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, false);
2016                 QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
2017                 emit scopeFocusedItem->focusChanged(false);
2018             } else {
2019                 if (d->canvas) {
2020                     QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
2021                                                                   QQuickCanvasPrivate::DontChangeFocusProperty);
2022                 } else {
2023                     QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, true);
2024                 }
2025             }
2026         }
2027     }
2028
2029     d->resolveLayoutMirror();
2030
2031     d->itemChange(ItemParentHasChanged, d->parentItem);
2032
2033     d->parentNotifier.notify();
2034     if (d->isAccessible && d->parentItem) {
2035         d->parentItem->d_func()->setAccessibleFlagAndListener();
2036     }
2037
2038     emit parentChanged(d->parentItem);
2039     if (isVisible() && d->parentItem)
2040         emit d->parentItem->visibleChildrenChanged();
2041 }
2042
2043 void QQuickItem::stackBefore(const QQuickItem *sibling)
2044 {
2045     Q_D(QQuickItem);
2046     if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2047         qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
2048         return;
2049     }
2050
2051     QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2052
2053     int myIndex = parentPrivate->childItems.indexOf(this);
2054     int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2055
2056     Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2057
2058     if (myIndex == siblingIndex - 1)
2059         return;
2060
2061     parentPrivate->childItems.removeAt(myIndex);
2062
2063     if (myIndex < siblingIndex) --siblingIndex;
2064
2065     parentPrivate->childItems.insert(siblingIndex, this);
2066
2067     parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2068     parentPrivate->markSortedChildrenDirty(this);
2069
2070     for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
2071         QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2072 }
2073
2074 void QQuickItem::stackAfter(const QQuickItem *sibling)
2075 {
2076     Q_D(QQuickItem);
2077     if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2078         qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
2079         return;
2080     }
2081
2082     QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2083
2084     int myIndex = parentPrivate->childItems.indexOf(this);
2085     int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2086
2087     Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2088
2089     if (myIndex == siblingIndex + 1)
2090         return;
2091
2092     parentPrivate->childItems.removeAt(myIndex);
2093
2094     if (myIndex < siblingIndex) --siblingIndex;
2095
2096     parentPrivate->childItems.insert(siblingIndex + 1, this);
2097
2098     parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2099     parentPrivate->markSortedChildrenDirty(this);
2100
2101     for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
2102         QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2103 }
2104
2105 /*!
2106     Returns the QQuickItem parent of this item.
2107 */
2108 QQuickItem *QQuickItem::parentItem() const
2109 {
2110     Q_D(const QQuickItem);
2111     return d->parentItem;
2112 }
2113
2114 QSGEngine *QQuickItem::sceneGraphEngine() const
2115 {
2116     return canvas()->sceneGraphEngine();
2117 }
2118
2119 QQuickCanvas *QQuickItem::canvas() const
2120 {
2121     Q_D(const QQuickItem);
2122     return d->canvas;
2123 }
2124
2125 static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
2126 {
2127     return lhs->z() < rhs->z();
2128 }
2129
2130 QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
2131 {
2132     if (sortedChildItems)
2133         return *sortedChildItems;
2134
2135     // If none of the items have set Z then the paint order list is the same as
2136     // the childItems list.  This is by far the most common case.
2137     bool haveZ = false;
2138     for (int i = 0; i < childItems.count(); ++i) {
2139         if (QQuickItemPrivate::get(childItems.at(i))->z() != 0.) {
2140             haveZ = true;
2141             break;
2142         }
2143     }
2144     if (haveZ) {
2145         sortedChildItems = new QList<QQuickItem*>(childItems);
2146         qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
2147         return *sortedChildItems;
2148     }
2149
2150     sortedChildItems = const_cast<QList<QQuickItem*>*>(&childItems);
2151
2152     return childItems;
2153 }
2154
2155 void QQuickItemPrivate::addChild(QQuickItem *child)
2156 {
2157     Q_Q(QQuickItem);
2158
2159     Q_ASSERT(!childItems.contains(child));
2160
2161     childItems.append(child);
2162
2163     markSortedChildrenDirty(child);
2164     dirty(QQuickItemPrivate::ChildrenChanged);
2165
2166     itemChange(QQuickItem::ItemChildAddedChange, child);
2167
2168     emit q->childrenChanged();
2169 }
2170
2171 void QQuickItemPrivate::removeChild(QQuickItem *child)
2172 {
2173     Q_Q(QQuickItem);
2174
2175     Q_ASSERT(child);
2176     Q_ASSERT(childItems.contains(child));
2177     childItems.removeOne(child);
2178     Q_ASSERT(!childItems.contains(child));
2179
2180     markSortedChildrenDirty(child);
2181     dirty(QQuickItemPrivate::ChildrenChanged);
2182
2183     itemChange(QQuickItem::ItemChildRemovedChange, child);
2184
2185     emit q->childrenChanged();
2186 }
2187
2188 void QQuickItemPrivate::InitializationState::clear()
2189 {
2190     focusScope = 0;
2191 }
2192
2193 void QQuickItemPrivate::InitializationState::clear(QQuickItem *fs)
2194 {
2195     focusScope = fs;
2196 }
2197
2198 QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *item)
2199 {
2200     if (!focusScope) {
2201         QQuickItem *fs = item->parentItem();
2202         while (fs->parentItem() && !fs->isFocusScope())
2203             fs = fs->parentItem();
2204         focusScope = fs;
2205     }
2206     return focusScope;
2207 }
2208
2209 void QQuickItemPrivate::refCanvas(InitializationState *state, QQuickCanvas *c)
2210 {
2211     // An item needs a canvas if it is referenced by another item which has a canvas.
2212     // Typically the item is referenced by a parent, but can also be referenced by a
2213     // ShaderEffect or ShaderEffectSource. 'canvasRefCount' counts how many items with
2214     // a canvas is referencing this item. When the reference count goes from zero to one,
2215     // or one to zero, the canvas of this item is updated and propagated to the children.
2216     // As long as the reference count stays above zero, the canvas is unchanged.
2217     // refCanvas() increments the reference count.
2218     // derefCanvas() decrements the reference count.
2219
2220     Q_Q(QQuickItem);
2221     Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2222     Q_ASSERT(c);
2223     if (++canvasRefCount > 1) {
2224         if (c != canvas)
2225             qWarning("QQuickItem: Cannot use same item on different canvases at the same time.");
2226         return; // Canvas already set.
2227     }
2228
2229     Q_ASSERT(canvas == 0);
2230     canvas = c;
2231
2232     if (polishScheduled)
2233         QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2234
2235     InitializationState _dummy;
2236     InitializationState *childState = state;
2237
2238     if (q->isFocusScope()) {
2239         _dummy.clear(q);
2240         childState = &_dummy;
2241     }
2242
2243     if (!parentItem)
2244         QQuickCanvasPrivate::get(canvas)->parentlessItems.insert(q);
2245
2246     for (int ii = 0; ii < childItems.count(); ++ii) {
2247         QQuickItem *child = childItems.at(ii);
2248         QQuickItemPrivate::get(child)->refCanvas(childState, c);
2249     }
2250
2251     dirty(Canvas);
2252
2253     if (extra.isAllocated() && extra->screenAttached)
2254         extra->screenAttached->canvasChanged(c);
2255     itemChange(QQuickItem::ItemSceneChange, c);
2256 }
2257
2258 void QQuickItemPrivate::derefCanvas()
2259 {
2260     Q_Q(QQuickItem);
2261     Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2262
2263     if (!canvas)
2264         return; // This can happen when destroying recursive shader effect sources.
2265
2266     if (--canvasRefCount > 0)
2267         return; // There are still other references, so don't set canvas to null yet.
2268
2269     q->releaseResources();
2270     removeFromDirtyList();
2271     QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
2272     if (polishScheduled)
2273         c->itemsToPolish.remove(q);
2274     if (c->mouseGrabberItem == q)
2275         c->mouseGrabberItem = 0;
2276     if ( hoverEnabled )
2277         c->hoverItems.removeAll(q);
2278     if (itemNodeInstance)
2279         c->cleanup(itemNodeInstance);
2280     if (!parentItem)
2281         c->parentlessItems.remove(q);
2282
2283     canvas = 0;
2284
2285     itemNodeInstance = 0;
2286
2287     if (extra.isAllocated()) {
2288         extra->opacityNode = 0;
2289         extra->clipNode = 0;
2290         extra->rootNode = 0;
2291         extra->beforePaintNode = 0;
2292     }
2293
2294     groupNode = 0;
2295     paintNode = 0;
2296
2297     for (int ii = 0; ii < childItems.count(); ++ii) {
2298         QQuickItem *child = childItems.at(ii);
2299         QQuickItemPrivate::get(child)->derefCanvas();
2300     }
2301
2302     dirty(Canvas);
2303
2304     if (extra.isAllocated() && extra->screenAttached)
2305         extra->screenAttached->canvasChanged(0);
2306     itemChange(QQuickItem::ItemSceneChange, (QQuickCanvas *)0);
2307 }
2308
2309
2310 /*!
2311 Returns a transform that maps points from canvas space into item space.
2312 */
2313 QTransform QQuickItemPrivate::canvasToItemTransform() const
2314 {
2315     // XXX todo - optimize
2316     return itemToCanvasTransform().inverted();
2317 }
2318
2319 /*!
2320 Returns a transform that maps points from item space into canvas space.
2321 */
2322 QTransform QQuickItemPrivate::itemToCanvasTransform() const
2323 {
2324     // XXX todo
2325     QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2326     itemToParentTransform(rv);
2327     return rv;
2328 }
2329
2330 /*!
2331 Motifies \a t with this items local transform relative to its parent.
2332 */
2333 void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
2334 {
2335     if (x || y)
2336         t.translate(x, y);
2337
2338     if (!transforms.isEmpty()) {
2339         QMatrix4x4 m(t);
2340         for (int ii = transforms.count() - 1; ii >= 0; --ii)
2341             transforms.at(ii)->applyTo(&m);
2342         t = m.toTransform();
2343     }
2344
2345     if (scale() != 1. || rotation() != 0.) {
2346         QPointF tp = computeTransformOrigin();
2347         t.translate(tp.x(), tp.y());
2348         t.scale(scale(), scale());
2349         t.rotate(rotation());
2350         t.translate(-tp.x(), -tp.y());
2351     }
2352 }
2353
2354
2355 /*!
2356     \qmlproperty real QtQuick2::Item::childrenRect.x
2357     \qmlproperty real QtQuick2::Item::childrenRect.y
2358     \qmlproperty real QtQuick2::Item::childrenRect.width
2359     \qmlproperty real QtQuick2::Item::childrenRect.height
2360
2361     The childrenRect properties allow an item access to the geometry of its
2362     children. This property is useful if you have an item that needs to be
2363     sized to fit its children.
2364 */
2365
2366
2367 /*!
2368     \qmlproperty list<Item> QtQuick2::Item::children
2369     \qmlproperty list<Object> QtQuick2::Item::resources
2370
2371     The children property contains the list of visual children of this item.
2372     The resources property contains non-visual resources that you want to
2373     reference by name.
2374
2375     Generally you can rely on Item's default property to handle all this for
2376     you, but it can come in handy in some cases.
2377
2378     \qml
2379     Item {
2380         children: [
2381             Text {},
2382             Rectangle {}
2383         ]
2384         resources: [
2385             Component {
2386                 id: myComponent
2387                 Text {}
2388             }
2389         ]
2390     }
2391     \endqml
2392 */
2393
2394 /*!
2395     Returns true if construction of the QML component is complete; otherwise
2396     returns false.
2397
2398     It is often desirable to delay some processing until the component is
2399     completed.
2400
2401     \sa componentComplete()
2402 */
2403 bool QQuickItem::isComponentComplete() const
2404 {
2405     Q_D(const QQuickItem);
2406     return d->componentComplete;
2407 }
2408
2409 QQuickItemPrivate::QQuickItemPrivate()
2410 : _anchors(0), _stateGroup(0),
2411   flags(0), widthValid(false), heightValid(false), baselineOffsetValid(false), componentComplete(true),
2412   keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(true), focus(false), activeFocus(false), notifiedFocus(false),
2413   notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2414   effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2415   inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2416   inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
2417   staticSubtreeGeometry(false),
2418   isAccessible(false),
2419
2420   dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2421
2422   canvas(0), canvasRefCount(0), parentItem(0), sortedChildItems(&childItems),
2423
2424   subFocusItem(0),
2425
2426   x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2427
2428   baselineOffset(0),
2429
2430   itemNodeInstance(0), groupNode(0), paintNode(0)
2431 {
2432 }
2433
2434 QQuickItemPrivate::~QQuickItemPrivate()
2435 {
2436     if (sortedChildItems != &childItems)
2437         delete sortedChildItems;
2438 }
2439
2440 void QQuickItemPrivate::init(QQuickItem *parent)
2441 {
2442 #ifndef QT_NO_DEBUG
2443     ++qt_item_count;
2444     static bool atexit_registered = false;
2445     if (!atexit_registered) {
2446         atexit(qt_print_item_count);
2447         atexit_registered = true;
2448     }
2449 #endif
2450
2451     Q_Q(QQuickItem);
2452
2453     registerAccessorProperties();
2454
2455     baselineOffsetValid = false;
2456
2457     if (parent) {
2458         q->setParentItem(parent);
2459         QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
2460         setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2461     }
2462 }
2463
2464 void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
2465 {
2466     if (!o)
2467         return;
2468
2469     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2470
2471     // This test is measurably (albeit only slightly) faster than qobject_cast<>()
2472     const QMetaObject *mo = o->metaObject();
2473     while (mo && mo != &QQuickItem::staticMetaObject) {
2474         mo = mo->d.superdata;
2475     }
2476
2477     if (mo) {
2478         QQuickItem *item = static_cast<QQuickItem *>(o);
2479         item->setParentItem(that);
2480     } else {
2481         if (o->inherits("QGraphicsItem"))
2482             qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2483
2484         // XXX todo - do we really want this behavior?
2485         o->setParent(that);
2486     }
2487 }
2488
2489 /*!
2490     \qmlproperty list<Object> QtQuick2::Item::data
2491     \default
2492
2493     The data property allows you to freely mix visual children and resources
2494     in an item.  If you assign a visual item to the data list it becomes
2495     a child and if you assign any other object type, it is added as a resource.
2496
2497     So you can write:
2498     \qml
2499     Item {
2500         Text {}
2501         Rectangle {}
2502         Timer {}
2503     }
2504     \endqml
2505
2506     instead of:
2507     \qml
2508     Item {
2509         children: [
2510             Text {},
2511             Rectangle {}
2512         ]
2513         resources: [
2514             Timer {}
2515         ]
2516     }
2517     \endqml
2518
2519     data is a behind-the-scenes property: you should never need to explicitly
2520     specify it.
2521  */
2522
2523 int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *prop)
2524 {
2525     Q_UNUSED(prop);
2526     // XXX todo
2527     return 0;
2528 }
2529
2530 QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *prop, int i)
2531 {
2532     Q_UNUSED(prop);
2533     Q_UNUSED(i);
2534     // XXX todo
2535     return 0;
2536 }
2537
2538 void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *prop)
2539 {
2540     Q_UNUSED(prop);
2541     // XXX todo
2542 }
2543
2544 QObject *QQuickItemPrivate::resources_at(QQmlListProperty<QObject> *prop, int index)
2545 {
2546     const QObjectList children = prop->object->children();
2547     if (index < children.count())
2548         return children.at(index);
2549     else
2550         return 0;
2551 }
2552
2553 void QQuickItemPrivate::resources_append(QQmlListProperty<QObject> *prop, QObject *o)
2554 {
2555     // XXX todo - do we really want this behavior?
2556     o->setParent(prop->object);
2557 }
2558
2559 int QQuickItemPrivate::resources_count(QQmlListProperty<QObject> *prop)
2560 {
2561     return prop->object->children().count();
2562 }
2563
2564 void QQuickItemPrivate::resources_clear(QQmlListProperty<QObject> *prop)
2565 {
2566     // XXX todo - do we really want this behavior?
2567     const QObjectList children = prop->object->children();
2568     for (int index = 0; index < children.count(); index++)
2569         children.at(index)->setParent(0);
2570 }
2571
2572 QQuickItem *QQuickItemPrivate::children_at(QQmlListProperty<QQuickItem> *prop, int index)
2573 {
2574     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2575     if (index >= p->childItems.count() || index < 0)
2576         return 0;
2577     else
2578         return p->childItems.at(index);
2579 }
2580
2581 void QQuickItemPrivate::children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *o)
2582 {
2583     if (!o)
2584         return;
2585
2586     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2587     if (o->parentItem() == that)
2588         o->setParentItem(0);
2589
2590     o->setParentItem(that);
2591 }
2592
2593 int QQuickItemPrivate::children_count(QQmlListProperty<QQuickItem> *prop)
2594 {
2595     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2596     return p->childItems.count();
2597 }
2598
2599 void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop)
2600 {
2601     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2602     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2603     while (!p->childItems.isEmpty())
2604         p->childItems.at(0)->setParentItem(0);
2605 }
2606
2607 void QQuickItemPrivate::visibleChildren_append(QQmlListProperty<QQuickItem>*, QQuickItem *self)
2608 {
2609     // do nothing
2610     qmlInfo(self) << "QQuickItem: visibleChildren property is readonly and cannot be assigned to.";
2611 }
2612
2613 int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop)
2614 {
2615     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2616     int visibleCount = 0;
2617     int c = p->childItems.count();
2618     while (c--) {
2619         if (p->childItems.at(c)->isVisible()) visibleCount++;
2620     }
2621
2622     return visibleCount;
2623 }
2624
2625 QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index)
2626 {
2627     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2628     const int childCount = p->childItems.count();
2629     if (index >= childCount || index < 0)
2630         return 0;
2631
2632     int visibleCount = -1;
2633     for (int i = 0; i < childCount; i++) {
2634         if (p->childItems.at(i)->isVisible()) visibleCount++;
2635         if (visibleCount == index) return p->childItems.at(i);
2636     }
2637     return 0;
2638 }
2639
2640 int QQuickItemPrivate::transform_count(QQmlListProperty<QQuickTransform> *prop)
2641 {
2642     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2643     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2644
2645     return p->transforms.count();
2646 }
2647
2648 void QQuickTransform::appendToItem(QQuickItem *item)
2649 {
2650     Q_D(QQuickTransform);
2651     if (!item)
2652         return;
2653
2654     QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2655
2656     if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2657         p->transforms.removeOne(this);
2658         p->transforms.append(this);
2659     } else {
2660         p->transforms.append(this);
2661         d->items.append(item);
2662     }
2663
2664     p->dirty(QQuickItemPrivate::Transform);
2665 }
2666
2667 void QQuickTransform::prependToItem(QQuickItem *item)
2668 {
2669     Q_D(QQuickTransform);
2670     if (!item)
2671         return;
2672
2673     QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2674
2675     if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2676         p->transforms.removeOne(this);
2677         p->transforms.prepend(this);
2678     } else {
2679         p->transforms.prepend(this);
2680         d->items.append(item);
2681     }
2682
2683     p->dirty(QQuickItemPrivate::Transform);
2684 }
2685
2686 void QQuickItemPrivate::transform_append(QQmlListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2687 {
2688     if (!transform)
2689         return;
2690
2691     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2692     transform->appendToItem(that);
2693 }
2694
2695 QQuickTransform *QQuickItemPrivate::transform_at(QQmlListProperty<QQuickTransform> *prop, int idx)
2696 {
2697     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2698     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2699
2700     if (idx < 0 || idx >= p->transforms.count())
2701         return 0;
2702     else
2703         return p->transforms.at(idx);
2704 }
2705
2706 void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
2707 {
2708     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2709     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2710
2711     for (int ii = 0; ii < p->transforms.count(); ++ii) {
2712         QQuickTransform *t = p->transforms.at(ii);
2713         QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2714         tp->items.removeOne(that);
2715     }
2716
2717     p->transforms.clear();
2718
2719     p->dirty(QQuickItemPrivate::Transform);
2720 }
2721
2722 /*!
2723     \property QQuickItem::childrenRect
2724     \brief The geometry of an item's children.
2725
2726     This property holds the (collective) position and size of the item's children.
2727 */
2728
2729 /*!
2730   \qmlproperty real QtQuick2::Item::x
2731   \qmlproperty real QtQuick2::Item::y
2732   \qmlproperty real QtQuick2::Item::width
2733   \qmlproperty real QtQuick2::Item::height
2734
2735   Defines the item's position and size relative to its parent.
2736
2737   \qml
2738   Item { x: 100; y: 100; width: 100; height: 100 }
2739   \endqml
2740  */
2741
2742 /*!
2743   \qmlproperty real QtQuick2::Item::z
2744
2745   Sets the stacking order of sibling items.  By default the stacking order is 0.
2746
2747   Items with a higher stacking value are drawn on top of siblings with a
2748   lower stacking order.  Items with the same stacking value are drawn
2749   bottom up in the order they appear.  Items with a negative stacking
2750   value are drawn under their parent's content.
2751
2752   The following example shows the various effects of stacking order.
2753
2754   \table
2755   \row
2756   \li \image declarative-item_stacking1.png
2757   \li Same \c z - later children above earlier children:
2758   \qml
2759   Item {
2760       Rectangle {
2761           color: "red"
2762           width: 100; height: 100
2763       }
2764       Rectangle {
2765           color: "blue"
2766           x: 50; y: 50; width: 100; height: 100
2767       }
2768   }
2769   \endqml
2770   \row
2771   \li \image declarative-item_stacking2.png
2772   \li Higher \c z on top:
2773   \qml
2774   Item {
2775       Rectangle {
2776           z: 1
2777           color: "red"
2778           width: 100; height: 100
2779       }
2780       Rectangle {
2781           color: "blue"
2782           x: 50; y: 50; width: 100; height: 100
2783       }
2784   }
2785   \endqml
2786   \row
2787   \li \image declarative-item_stacking3.png
2788   \li Same \c z - children above parents:
2789   \qml
2790   Item {
2791       Rectangle {
2792           color: "red"
2793           width: 100; height: 100
2794           Rectangle {
2795               color: "blue"
2796               x: 50; y: 50; width: 100; height: 100
2797           }
2798       }
2799   }
2800   \endqml
2801   \row
2802   \li \image declarative-item_stacking4.png
2803   \li Lower \c z below:
2804   \qml
2805   Item {
2806       Rectangle {
2807           color: "red"
2808           width: 100; height: 100
2809           Rectangle {
2810               z: -1
2811               color: "blue"
2812               x: 50; y: 50; width: 100; height: 100
2813           }
2814       }
2815   }
2816   \endqml
2817   \endtable
2818  */
2819
2820 /*!
2821     \qmlproperty bool QtQuick2::Item::visible
2822
2823     This property holds whether the item is visible. By default this is true.
2824
2825     Setting this property directly affects the \c visible value of child
2826     items. When set to \c false, the \c visible values of all child items also
2827     become \c false. When set to \c true, the \c visible values of child items
2828     are returned to \c true, unless they have explicitly been set to \c false.
2829
2830     (Because of this flow-on behavior, using the \c visible property may not
2831     have the intended effect if a property binding should only respond to
2832     explicit property changes. In such cases it may be better to use the
2833     \l opacity property instead.)
2834
2835     Setting this property to \c false automatically causes \l focus to be set
2836     to \c false, and this item will longer receive mouse and keyboard events.
2837     (In contrast, setting the \l opacity to 0 does not affect the \l focus
2838     property and the receiving of key events.)
2839
2840     \note This property's value is only affected by changes to this property or
2841     the parent's \c visible property. It does not change, for example, if this
2842     item moves off-screen, or if the \l opacity changes to 0.
2843 */
2844
2845
2846 /*!
2847   \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2848   \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2849   \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2850   \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2851   \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2852   \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2853   \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2854
2855   \qmlproperty Item QtQuick2::Item::anchors.fill
2856   \qmlproperty Item QtQuick2::Item::anchors.centerIn
2857
2858   \qmlproperty real QtQuick2::Item::anchors.margins
2859   \qmlproperty real QtQuick2::Item::anchors.topMargin
2860   \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2861   \qmlproperty real QtQuick2::Item::anchors.leftMargin
2862   \qmlproperty real QtQuick2::Item::anchors.rightMargin
2863   \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2864   \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2865   \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2866
2867   \qmlproperty bool QtQuick2::Item::anchors.mirrored
2868
2869   Anchors provide a way to position an item by specifying its
2870   relationship with other items.
2871
2872   Margins apply to top, bottom, left, right, and fill anchors.
2873   The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2874   Note that margins are anchor-specific and are not applied if an item does not
2875   use anchors.
2876
2877   Offsets apply for horizontal center, vertical center, and baseline anchors.
2878
2879   \table
2880   \row
2881   \li \image declarative-anchors_example.png
2882   \li Text anchored to Image, horizontally centered and vertically below, with a margin.
2883   \qml
2884   Item {
2885       Image {
2886           id: pic
2887           // ...
2888       }
2889       Text {
2890           id: label
2891           anchors.horizontalCenter: pic.horizontalCenter
2892           anchors.top: pic.bottom
2893           anchors.topMargin: 5
2894           // ...
2895       }
2896   }
2897   \endqml
2898   \row
2899   \li \image declarative-anchors_example2.png
2900   \li
2901   Left of Text anchored to right of Image, with a margin. The y
2902   property of both defaults to 0.
2903
2904   \qml
2905   Item {
2906       Image {
2907           id: pic
2908           // ...
2909       }
2910       Text {
2911           id: label
2912           anchors.left: pic.right
2913           anchors.leftMargin: 5
2914           // ...
2915       }
2916   }
2917   \endqml
2918   \endtable
2919
2920   \c anchors.fill provides a convenient way for one item to have the
2921   same geometry as another item, and is equivalent to connecting all
2922   four directional anchors.
2923
2924   To clear an anchor value, set it to \c undefined.
2925
2926   \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2927
2928   \note You can only anchor an item to siblings or a parent.
2929
2930   For more information see \l {anchor-layout}{Anchor Layouts}.
2931 */
2932
2933 /*!
2934   \property QQuickItem::baselineOffset
2935   \brief The position of the item's baseline in local coordinates.
2936
2937   The baseline of a \l Text item is the imaginary line on which the text
2938   sits. Controls containing text usually set their baseline to the
2939   baseline of their text.
2940
2941   For non-text items, a default baseline offset of 0 is used.
2942 */
2943 QQuickAnchors *QQuickItemPrivate::anchors() const
2944 {
2945     if (!_anchors) {
2946         Q_Q(const QQuickItem);
2947         _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2948         if (!componentComplete)
2949             _anchors->classBegin();
2950     }
2951     return _anchors;
2952 }
2953
2954 void QQuickItemPrivate::siblingOrderChanged()
2955 {
2956     Q_Q(QQuickItem);
2957     for (int ii = 0; ii < changeListeners.count(); ++ii) {
2958         const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2959         if (change.types & QQuickItemPrivate::SiblingOrder) {
2960             change.listener->itemSiblingOrderChanged(q);
2961         }
2962     }
2963 }
2964
2965 QQmlListProperty<QObject> QQuickItemPrivate::data()
2966 {
2967     return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
2968                                              QQuickItemPrivate::data_count,
2969                                              QQuickItemPrivate::data_at,
2970                                              QQuickItemPrivate::data_clear);
2971 }
2972
2973 QRectF QQuickItem::childrenRect()
2974 {
2975     Q_D(QQuickItem);
2976     if (!d->extra.isAllocated() || !d->extra->contents) {
2977         d->extra.value().contents = new QQuickContents(this);
2978         if (d->componentComplete)
2979             d->extra->contents->complete();
2980     }
2981     return d->extra->contents->rectF();
2982 }
2983
2984 QList<QQuickItem *> QQuickItem::childItems() const
2985 {
2986     Q_D(const QQuickItem);
2987     return d->childItems;
2988 }
2989
2990 bool QQuickItem::clip() const
2991 {
2992     return flags() & ItemClipsChildrenToShape;
2993 }
2994
2995 void QQuickItem::setClip(bool c)
2996 {
2997     if (clip() == c)
2998         return;
2999
3000     setFlag(ItemClipsChildrenToShape, c);
3001
3002     emit clipChanged(c);
3003 }
3004
3005
3006 /*!
3007   This function is called to handle this item's changes in
3008   geometry from \a oldGeometry to \a newGeometry. If the two
3009   geometries are the same, it doesn't do anything.
3010  */
3011 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
3012 {
3013     Q_D(QQuickItem);
3014
3015     if (d->_anchors)
3016         QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
3017
3018     bool xChange = (newGeometry.x() != oldGeometry.x());
3019     bool yChange = (newGeometry.y() != oldGeometry.y());
3020     bool widthChange = (newGeometry.width() != oldGeometry.width());
3021     bool heightChange = (newGeometry.height() != oldGeometry.height());
3022
3023     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3024         const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3025         if (change.types & QQuickItemPrivate::Geometry) {
3026             if (change.gTypes == QQuickItemPrivate::GeometryChange) {
3027                 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3028             } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
3029                        (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
3030                        (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
3031                        (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
3032                 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3033             }
3034         }
3035     }
3036
3037     if (xChange)
3038         emit xChanged();
3039     if (yChange)
3040         emit yChanged();
3041     if (widthChange)
3042         emit widthChanged();
3043     if (heightChange)
3044         emit heightChanged();
3045 }
3046
3047 /*!
3048     Called by the rendering thread when it is time to sync the state of the QML objects with the
3049     scene graph objects. The function should return the root of the scene graph subtree for
3050     this item. \a oldNode is the node that was returned the last time the function was called.
3051
3052     The main thread is blocked while this function is executed so it is safe to read
3053     values from the QQuickItem instance and other objects in the main thread.
3054
3055     \warning This is the only function in which it is allowed to make use of scene graph
3056     objects from the main thread. Use of scene graph objects outside this function will
3057     result in race conditions and potential crashes.
3058  */
3059
3060 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
3061 {
3062     delete oldNode;
3063     return 0;
3064 }
3065
3066 /*!
3067     This function is called when the item's scene graph resources are no longer needed.
3068     It allows items to free its resources, for instance textures, that are not owned by scene graph
3069     nodes. Note that scene graph nodes are managed by QQuickCanvas and should not be deleted by
3070     this function. Scene graph resources are no longer needed when the parent is set to null and
3071     the item is not used by any \l ShaderEffect or \l ShaderEffectSource.
3072
3073     This function is called from the main thread. Therefore, resources used by the scene graph
3074     should not be deleted directly, but by calling \l QObject::deleteLater().
3075
3076     \note The item destructor still needs to free its scene graph resources if not already done.
3077  */
3078
3079 void QQuickItem::releaseResources()
3080 {
3081 }
3082
3083 QSGTransformNode *QQuickItemPrivate::createTransformNode()
3084 {
3085     return new QSGTransformNode;
3086 }
3087
3088 void QQuickItem::updatePolish()
3089 {
3090 }
3091
3092 void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3093 {
3094     changeListeners.append(ChangeListener(listener, types));
3095 }
3096
3097 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3098 {
3099     ChangeListener change(listener, types);
3100     changeListeners.removeOne(change);
3101 }
3102
3103 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
3104 {
3105     ChangeListener change(listener, types);
3106     int index = changeListeners.find(change);
3107     if (index > -1)
3108         changeListeners[index].gTypes = change.gTypes;  //we may have different GeometryChangeTypes
3109     else
3110         changeListeners.append(change);
3111 }
3112
3113 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
3114                                                              GeometryChangeTypes types)
3115 {
3116     ChangeListener change(listener, types);
3117     if (types == NoChange) {
3118         changeListeners.removeOne(change);
3119     } else {
3120         int index = changeListeners.find(change);
3121         if (index > -1)
3122             changeListeners[index].gTypes = change.gTypes;  //we may have different GeometryChangeTypes
3123     }
3124 }
3125
3126 void QQuickItem::keyPressEvent(QKeyEvent *event)
3127 {
3128     event->ignore();
3129 }
3130
3131 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
3132 {
3133     event->ignore();
3134 }
3135
3136 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
3137 {
3138     event->ignore();
3139 }
3140
3141 void QQuickItem::focusInEvent(QFocusEvent *)
3142 {
3143 #ifndef QT_NO_ACCESSIBILITY
3144     QAccessibleEvent ev(this, QAccessible::Focus);
3145     QAccessible::updateAccessibility(&ev);
3146 #endif
3147 }
3148
3149 void QQuickItem::focusOutEvent(QFocusEvent *)
3150 {
3151 }
3152
3153 void QQuickItem::mousePressEvent(QMouseEvent *event)
3154 {
3155     event->ignore();
3156 }
3157
3158 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
3159 {
3160     event->ignore();
3161 }
3162
3163 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
3164 {
3165     event->ignore();
3166 }
3167
3168 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
3169 {
3170 }
3171
3172 void QQuickItem::mouseUngrabEvent()
3173 {
3174     // XXX todo
3175 }
3176
3177 void QQuickItem::touchUngrabEvent()
3178 {
3179     // XXX todo
3180 }
3181
3182 void QQuickItem::wheelEvent(QWheelEvent *event)
3183 {
3184     event->ignore();
3185 }
3186
3187 void QQuickItem::touchEvent(QTouchEvent *event)
3188 {
3189     event->ignore();
3190 }
3191
3192 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
3193 {
3194     Q_UNUSED(event);
3195 }
3196
3197 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
3198 {
3199     Q_UNUSED(event);
3200 }
3201
3202 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
3203 {
3204     Q_UNUSED(event);
3205 }
3206
3207 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
3208 {
3209     Q_UNUSED(event);
3210 }
3211
3212 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
3213 {
3214
3215     Q_UNUSED(event);
3216 }
3217
3218 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3219 {
3220
3221     Q_UNUSED(event);
3222 }
3223
3224 void QQuickItem::dropEvent(QDropEvent *event)
3225 {
3226     Q_UNUSED(event);
3227 }
3228
3229 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3230 {
3231     return false;
3232 }
3233
3234 void QQuickItem::windowDeactivateEvent()
3235 {
3236     foreach (QQuickItem* item, childItems()) {
3237         item->windowDeactivateEvent();
3238     }
3239 }
3240
3241 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3242 {
3243     Q_D(const QQuickItem);
3244     QVariant v;
3245
3246     switch (query) {
3247     case Qt::ImEnabled:
3248         v = (bool)(flags() & ItemAcceptsInputMethod);
3249         break;
3250     case Qt::ImHints:
3251     case Qt::ImCursorRectangle:
3252     case Qt::ImFont:
3253     case Qt::ImCursorPosition:
3254     case Qt::ImSurroundingText:
3255     case Qt::ImCurrentSelection:
3256     case Qt::ImMaximumTextLength:
3257     case Qt::ImAnchorPosition:
3258     case Qt::ImPreferredLanguage:
3259         if (d->extra.isAllocated() && d->extra->keyHandler)
3260             v = d->extra->keyHandler->inputMethodQuery(query);
3261     default:
3262         break;
3263     }
3264
3265     return v;
3266 }
3267
3268 QQuickAnchorLine QQuickItemPrivate::left() const
3269 {
3270     Q_Q(const QQuickItem);
3271     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left);
3272 }
3273
3274 QQuickAnchorLine QQuickItemPrivate::right() const
3275 {
3276     Q_Q(const QQuickItem);
3277     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right);
3278 }
3279
3280 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3281 {
3282     Q_Q(const QQuickItem);
3283     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter);
3284 }
3285
3286 QQuickAnchorLine QQuickItemPrivate::top() const
3287 {
3288     Q_Q(const QQuickItem);
3289     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top);
3290 }
3291
3292 QQuickAnchorLine QQuickItemPrivate::bottom() const
3293 {
3294     Q_Q(const QQuickItem);
3295     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom);
3296 }
3297
3298 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3299 {
3300     Q_Q(const QQuickItem);
3301     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter);
3302 }
3303
3304 QQuickAnchorLine QQuickItemPrivate::baseline() const
3305 {
3306     Q_Q(const QQuickItem);
3307     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline);
3308 }
3309
3310 qreal QQuickItem::baselineOffset() const
3311 {
3312     Q_D(const QQuickItem);
3313     if (d->baselineOffsetValid) {
3314         return d->baselineOffset;
3315     } else {
3316         return 0.0;
3317     }
3318 }
3319
3320 void QQuickItem::setBaselineOffset(qreal offset)
3321 {
3322     Q_D(QQuickItem);
3323     if (offset == d->baselineOffset)
3324         return;
3325
3326     d->baselineOffset = offset;
3327     d->baselineOffsetValid = true;
3328
3329     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3330         const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3331         if (change.types & QQuickItemPrivate::Geometry) {
3332             QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3333             if (anchor)
3334                 anchor->updateVerticalAnchors();
3335         }
3336     }
3337
3338     if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor))
3339         QQuickAnchorsPrivate::get(d->_anchors)->updateVerticalAnchors();
3340
3341     emit baselineOffsetChanged(offset);
3342 }
3343
3344 void QQuickItem::update()
3345 {
3346     Q_D(QQuickItem);
3347     Q_ASSERT(flags() & ItemHasContents);
3348     d->dirty(QQuickItemPrivate::Content);
3349 }
3350
3351 void QQuickItem::polish()
3352 {
3353     Q_D(QQuickItem);
3354     if (!d->polishScheduled) {
3355         d->polishScheduled = true;
3356         if (d->canvas) {
3357             QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
3358             bool maybeupdate = p->itemsToPolish.isEmpty();
3359             p->itemsToPolish.insert(this);
3360             if (maybeupdate) d->canvas->maybeUpdate();
3361         }
3362     }
3363 }
3364
3365 void QQuickItem::mapFromItem(QQmlV8Function *args) const
3366 {
3367     if (args->Length() != 0) {
3368         v8::Local<v8::Value> item = (*args)[0];
3369         QV8Engine *engine = args->engine();
3370
3371         QQuickItem *itemObj = 0;
3372         if (!item->IsNull())
3373             itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3374
3375         if (!itemObj && !item->IsNull()) {
3376             qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3377                           << "\" which is neither null nor an Item";
3378             return;
3379         }
3380
3381         v8::Local<v8::Object> rv = v8::Object::New();
3382         args->returnValue(rv);
3383
3384         qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3385         qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3386
3387         QPointF p = mapFromItem(itemObj, QPointF(x, y));
3388
3389         rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3390         rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3391     }
3392 }
3393
3394 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3395 {
3396     Q_D(const QQuickItem);
3397
3398     // XXX todo - we need to be able to handle common parents better and detect
3399     // invalid cases
3400     if (ok) *ok = true;
3401
3402     QTransform t = d->itemToCanvasTransform();
3403     if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
3404
3405     return t;
3406 }
3407
3408 void QQuickItem::mapToItem(QQmlV8Function *args) const
3409 {
3410     if (args->Length() != 0) {
3411         v8::Local<v8::Value> item = (*args)[0];
3412         QV8Engine *engine = args->engine();
3413
3414         QQuickItem *itemObj = 0;
3415         if (!item->IsNull())
3416             itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3417
3418         if (!itemObj && !item->IsNull()) {
3419             qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3420                           << "\" which is neither null nor an Item";
3421             return;
3422         }
3423
3424         v8::Local<v8::Object> rv = v8::Object::New();
3425         args->returnValue(rv);
3426
3427         qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3428         qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3429
3430         QPointF p = mapToItem(itemObj, QPointF(x, y));
3431
3432         rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3433         rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3434     }
3435 }
3436
3437 void QQuickItem::forceActiveFocus()
3438 {
3439     setFocus(true);
3440     QQuickItem *parent = parentItem();
3441     while (parent) {
3442         if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3443             parent->setFocus(true);
3444         }
3445         parent = parent->parentItem();
3446     }
3447 }
3448
3449 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3450 {
3451     // XXX todo - should this include transform etc.?
3452     const QList<QQuickItem *> children = childItems();
3453     for (int i = children.count()-1; i >= 0; --i) {
3454         QQuickItem *child = children.at(i);
3455         if (child->isVisible() && child->x() <= x
3456                 && child->x() + child->width() >= x
3457                 && child->y() <= y
3458                 && child->y() + child->height() >= y)
3459             return child;
3460     }
3461     return 0;
3462 }
3463
3464 QQmlListProperty<QObject> QQuickItemPrivate::resources()
3465 {
3466     return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3467                                              QQuickItemPrivate::resources_count,
3468                                              QQuickItemPrivate::resources_at,
3469                                              QQuickItemPrivate::resources_clear);
3470 }
3471
3472 QQmlListProperty<QQuickItem> QQuickItemPrivate::children()
3473 {
3474     return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3475                                              QQuickItemPrivate::children_count,
3476                                              QQuickItemPrivate::children_at,
3477                                              QQuickItemPrivate::children_clear);
3478
3479 }
3480
3481 /*!
3482   \qmlproperty real QtQuick2::Item::visibleChildren
3483   This read-only property lists all of the item's children that are currently visible.
3484   Note that a child's visibility may have changed explicitly, or because the visibility
3485   of this (it's parent) item or another grandparent changed.
3486 */
3487 QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
3488 {
3489     return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
3490                                              QQuickItemPrivate::visibleChildren_count,
3491                                              QQuickItemPrivate::visibleChildren_at);
3492
3493 }
3494
3495 QQmlListProperty<QQuickState> QQuickItemPrivate::states()
3496 {
3497     return _states()->statesProperty();
3498 }
3499
3500 QQmlListProperty<QQuickTransition> QQuickItemPrivate::transitions()
3501 {
3502     return _states()->transitionsProperty();
3503 }
3504
3505 QString QQuickItemPrivate::state() const
3506 {
3507     if (!_stateGroup)
3508         return QString();
3509     else
3510         return _stateGroup->state();
3511 }
3512
3513 void QQuickItemPrivate::setState(const QString &state)
3514 {
3515     _states()->setState(state);
3516 }
3517
3518 QString QQuickItem::state() const
3519 {
3520     Q_D(const QQuickItem);
3521     return d->state();
3522 }
3523
3524 void QQuickItem::setState(const QString &state)
3525 {
3526     Q_D(QQuickItem);
3527     d->setState(state);
3528 }
3529
3530 QQmlListProperty<QQuickTransform> QQuickItem::transform()
3531 {
3532     return QQmlListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3533                                                      QQuickItemPrivate::transform_count,
3534                                                      QQuickItemPrivate::transform_at,
3535                                                      QQuickItemPrivate::transform_clear);
3536 }
3537
3538 void QQuickItem::classBegin()
3539 {
3540     Q_D(QQuickItem);
3541     d->componentComplete = false;
3542     if (d->_stateGroup)
3543         d->_stateGroup->classBegin();
3544     if (d->_anchors)
3545         d->_anchors->classBegin();
3546     if (d->extra.isAllocated() && d->extra->layer)
3547         d->extra->layer->classBegin();
3548 }
3549
3550 void QQuickItem::componentComplete()
3551 {
3552     Q_D(QQuickItem);
3553     d->componentComplete = true;
3554     if (d->_stateGroup)
3555         d->_stateGroup->componentComplete();
3556     if (d->_anchors) {
3557         d->_anchors->componentComplete();
3558         QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3559     }
3560
3561     if (d->extra.isAllocated() && d->extra->layer)
3562         d->extra->layer->componentComplete();
3563
3564     if (d->extra.isAllocated() && d->extra->keyHandler)
3565         d->extra->keyHandler->componentComplete();
3566
3567     if (d->extra.isAllocated() && d->extra->contents)
3568         d->extra->contents->complete();
3569 }
3570
3571 QQuickStateGroup *QQuickItemPrivate::_states()
3572 {
3573     Q_Q(QQuickItem);
3574     if (!_stateGroup) {
3575         _stateGroup = new QQuickStateGroup;
3576         if (!componentComplete)
3577             _stateGroup->classBegin();
3578         FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)),
3579                      q, SIGNAL(stateChanged(QString)))
3580     }
3581
3582     return _stateGroup;
3583 }
3584
3585 QPointF QQuickItemPrivate::computeTransformOrigin() const
3586 {
3587     switch (origin()) {
3588     default:
3589     case QQuickItem::TopLeft:
3590         return QPointF(0, 0);
3591     case QQuickItem::Top:
3592         return QPointF(width / 2., 0);
3593     case QQuickItem::TopRight:
3594         return QPointF(width, 0);
3595     case QQuickItem::Left:
3596         return QPointF(0, height / 2.);
3597     case QQuickItem::Center:
3598         return QPointF(width / 2., height / 2.);
3599     case QQuickItem::Right:
3600         return QPointF(width, height / 2.);
3601     case QQuickItem::BottomLeft:
3602         return QPointF(0, height);
3603     case QQuickItem::Bottom:
3604         return QPointF(width / 2., height);
3605     case QQuickItem::BottomRight:
3606         return QPointF(width, height);
3607     }
3608 }
3609
3610 void QQuickItemPrivate::transformChanged()
3611 {
3612     if (extra.isAllocated() && extra->layer)
3613         extra->layer->updateMatrix();
3614 }
3615
3616 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3617 {
3618     Q_Q(QQuickItem);
3619
3620     Q_ASSERT(e->isAccepted());
3621     if (extra.isAllocated() && extra->keyHandler) {
3622         if (e->type() == QEvent::KeyPress)
3623             extra->keyHandler->keyPressed(e, false);
3624         else
3625             extra->keyHandler->keyReleased(e, false);
3626
3627         if (e->isAccepted())
3628             return;
3629         else
3630             e->accept();
3631     }
3632
3633     if (e->type() == QEvent::KeyPress)
3634         q->keyPressEvent(e);
3635     else
3636         q->keyReleaseEvent(e);
3637
3638     if (e->isAccepted())
3639         return;
3640
3641     if (extra.isAllocated() && extra->keyHandler) {
3642         e->accept();
3643
3644         if (e->type() == QEvent::KeyPress)
3645             extra->keyHandler->keyPressed(e, true);
3646         else
3647             extra->keyHandler->keyReleased(e, true);
3648     }
3649 }
3650
3651 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3652 {
3653     Q_Q(QQuickItem);
3654
3655     Q_ASSERT(e->isAccepted());
3656     if (extra.isAllocated() && extra->keyHandler) {
3657         extra->keyHandler->inputMethodEvent(e, false);
3658
3659         if (e->isAccepted())
3660             return;
3661         else
3662             e->accept();
3663     }
3664
3665     q->inputMethodEvent(e);
3666
3667     if (e->isAccepted())
3668         return;
3669
3670     if (extra.isAllocated() && extra->keyHandler) {
3671         e->accept();
3672
3673         extra->keyHandler->inputMethodEvent(e, true);
3674     }
3675 }
3676
3677 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3678 {
3679     Q_Q(QQuickItem);
3680
3681     if (e->type() == QEvent::FocusIn) {
3682         q->focusInEvent(e);
3683     } else {
3684         q->focusOutEvent(e);
3685     }
3686 }
3687
3688 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3689 {
3690     Q_Q(QQuickItem);
3691
3692     Q_ASSERT(e->isAccepted());
3693
3694     switch (e->type()) {
3695     default:
3696         Q_ASSERT(!"Unknown event type");
3697     case QEvent::MouseMove:
3698         q->mouseMoveEvent(e);
3699         break;
3700     case QEvent::MouseButtonPress:
3701         q->mousePressEvent(e);
3702         break;
3703     case QEvent::MouseButtonRelease:
3704         q->mouseReleaseEvent(e);
3705         break;
3706     case QEvent::MouseButtonDblClick:
3707         q->mouseDoubleClickEvent(e);
3708         break;
3709     }
3710 }
3711
3712 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3713 {
3714     Q_Q(QQuickItem);
3715     q->wheelEvent(e);
3716 }
3717
3718 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3719 {
3720     Q_Q(QQuickItem);
3721     q->touchEvent(e);
3722 }
3723
3724 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3725 {
3726     Q_Q(QQuickItem);
3727     switch (e->type()) {
3728     default:
3729         Q_ASSERT(!"Unknown event type");
3730     case QEvent::HoverEnter:
3731         q->hoverEnterEvent(e);
3732         break;
3733     case QEvent::HoverLeave:
3734         q->hoverLeaveEvent(e);
3735         break;
3736     case QEvent::HoverMove:
3737         q->hoverMoveEvent(e);
3738         break;
3739     }
3740 }
3741
3742 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3743 {
3744     Q_Q(QQuickItem);
3745     switch (e->type()) {
3746     default:
3747         Q_ASSERT(!"Unknown event type");
3748     case QEvent::DragEnter:
3749         q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3750         break;
3751     case QEvent::DragLeave:
3752         q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3753         break;
3754     case QEvent::DragMove:
3755         q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3756         break;
3757     case QEvent::Drop:
3758         q->dropEvent(static_cast<QDropEvent *>(e));
3759         break;
3760     }
3761 }
3762
3763 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3764 {
3765     Q_UNUSED(change);
3766     Q_UNUSED(value);
3767 }
3768
3769 /*!
3770     Notify input method on updated query values if needed. \a indicates changed attributes.
3771 */
3772 void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
3773 {
3774     if (hasActiveFocus())
3775         qApp->inputMethod()->update(queries);
3776 }
3777
3778 /*! \internal */
3779 // XXX todo - do we want/need this anymore?
3780 // Note that it's now used for varying clip rect
3781 QRectF QQuickItem::boundingRect() const
3782 {
3783     Q_D(const QQuickItem);
3784     return QRectF(0, 0, d->width, d->height);
3785 }
3786
3787 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3788 {
3789     Q_D(const QQuickItem);
3790     return d->origin();
3791 }
3792
3793 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3794 {
3795     Q_D(QQuickItem);
3796     if (origin == d->origin())
3797         return;
3798
3799     d->extra.value().origin = origin;
3800     d->dirty(QQuickItemPrivate::TransformOrigin);
3801
3802     emit transformOriginChanged(d->origin());
3803 }
3804
3805 QPointF QQuickItem::transformOriginPoint() const
3806 {
3807     Q_D(const QQuickItem);
3808     if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
3809         return d->extra->userTransformOriginPoint;
3810     return d->computeTransformOrigin();
3811 }
3812
3813 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3814 {
3815     Q_D(QQuickItem);
3816     if (d->extra.value().userTransformOriginPoint == point)
3817         return;
3818
3819     d->extra->userTransformOriginPoint = point;
3820     d->dirty(QQuickItemPrivate::TransformOrigin);
3821 }
3822
3823 qreal QQuickItem::z() const
3824 {
3825     Q_D(const QQuickItem);
3826     return d->z();
3827 }
3828
3829 void QQuickItem::setZ(qreal v)
3830 {
3831     Q_D(QQuickItem);
3832     if (d->z() == v)
3833         return;
3834
3835     d->extra.value().z = v;
3836
3837     d->dirty(QQuickItemPrivate::ZValue);
3838     if (d->parentItem) {
3839         QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3840         QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3841     }
3842
3843     emit zChanged();
3844
3845     if (d->extra.isAllocated() && d->extra->layer)
3846         d->extra->layer->updateZ();
3847 }
3848
3849
3850 /*!
3851   \qmlproperty real QtQuick2::Item::rotation
3852   This property holds the rotation of the item in degrees clockwise.
3853
3854   This specifies how many degrees to rotate the item around its transformOrigin.
3855   The default rotation is 0 degrees (i.e. not rotated at all).
3856
3857   \table
3858   \row
3859   \li \image declarative-rotation.png
3860   \li
3861   \qml
3862   Rectangle {
3863       color: "blue"
3864       width: 100; height: 100
3865       Rectangle {
3866           color: "red"
3867           x: 25; y: 25; width: 50; height: 50
3868           rotation: 30
3869       }
3870   }
3871   \endqml
3872   \endtable
3873
3874   \sa transform, Rotation
3875 */
3876
3877 /*!
3878   \qmlproperty real QtQuick2::Item::scale
3879   This property holds the scale of the item.
3880
3881   A scale of less than 1 means the item will be displayed smaller than
3882   normal, and a scale of greater than 1 means the item will be
3883   displayed larger than normal.  A negative scale means the item will
3884   be mirrored.
3885
3886   By default, items are displayed at a scale of 1 (i.e. at their
3887   normal size).
3888
3889   Scaling is from the item's transformOrigin.
3890
3891   \table
3892   \row
3893   \li \image declarative-scale.png
3894   \li
3895   \qml
3896   Rectangle {
3897       color: "blue"
3898       width: 100; height: 100
3899       Rectangle {
3900           color: "green"
3901           width: 25; height: 25
3902       }
3903       Rectangle {
3904           color: "red"
3905           x: 25; y: 25; width: 50; height: 50
3906           scale: 1.4
3907       }
3908   }
3909   \endqml
3910   \endtable
3911
3912   \sa transform, Scale
3913 */
3914
3915 /*!
3916   \qmlproperty real QtQuick2::Item::opacity
3917
3918   This property holds the opacity of the item.  Opacity is specified as a
3919   number between 0 (fully transparent) and 1 (fully opaque).  The default is 1.
3920
3921   When this property is set, the specified opacity is also applied
3922   individually to child items.  In almost all cases this is what you want,
3923   but in some cases it may produce undesired results. For example in the
3924   second set of rectangles below, the red rectangle has specified an opacity
3925   of 0.5, which affects the opacity of its blue child rectangle even though
3926   the child has not specified an opacity.
3927
3928   \table
3929   \row
3930   \li \image declarative-item_opacity1.png
3931   \li
3932   \qml
3933     Item {
3934         Rectangle {
3935             color: "red"
3936             width: 100; height: 100
3937             Rectangle {
3938                 color: "blue"
3939                 x: 50; y: 50; width: 100; height: 100
3940             }
3941         }
3942     }
3943   \endqml
3944   \row
3945   \li \image declarative-item_opacity2.png
3946   \li
3947   \qml
3948     Item {
3949         Rectangle {
3950             opacity: 0.5
3951             color: "red"
3952             width: 100; height: 100
3953             Rectangle {
3954                 color: "blue"
3955                 x: 50; y: 50; width: 100; height: 100
3956             }
3957         }
3958     }
3959   \endqml
3960   \endtable
3961
3962   If an item's opacity is set to 0, the item will no longer receive mouse
3963   events, but will continue to receive key events and will retain the keyboard
3964   \l focus if it has been set. (In contrast, setting the \l visible property
3965   to \c false stops both mouse and keyboard events, and also removes focus
3966   from the item.)
3967 */
3968
3969 /*!
3970   Returns a value indicating whether mouse input should
3971   remain with this item exclusively.
3972
3973   \sa setKeepMouseGrab()
3974  */
3975
3976 qreal QQuickItem::rotation() const
3977 {
3978     Q_D(const QQuickItem);
3979     return d->rotation();
3980 }
3981
3982 void QQuickItem::setRotation(qreal r)
3983 {
3984     Q_D(QQuickItem);
3985     if (d->rotation() == r)
3986         return;
3987
3988     d->extra.value().rotation = r;
3989
3990     d->dirty(QQuickItemPrivate::BasicTransform);
3991
3992     d->itemChange(ItemRotationHasChanged, r);
3993
3994     emit rotationChanged();
3995 }
3996
3997 qreal QQuickItem::scale() const
3998 {
3999     Q_D(const QQuickItem);
4000     return d->scale();
4001 }
4002
4003 void QQuickItem::setScale(qreal s)
4004 {
4005     Q_D(QQuickItem);
4006     if (d->scale() == s)
4007         return;
4008
4009     d->extra.value().scale = s;
4010
4011     d->dirty(QQuickItemPrivate::BasicTransform);
4012
4013     emit scaleChanged();
4014 }
4015
4016 qreal QQuickItem::opacity() const
4017 {
4018     Q_D(const QQuickItem);
4019     return d->opacity();
4020 }
4021
4022 void QQuickItem::setOpacity(qreal o)
4023 {
4024     Q_D(QQuickItem);
4025     if (d->opacity() == o)
4026         return;
4027
4028     d->extra.value().opacity = o;
4029
4030     d->dirty(QQuickItemPrivate::OpacityValue);
4031
4032     d->itemChange(ItemOpacityHasChanged, o);
4033
4034     emit opacityChanged();
4035 }
4036
4037 bool QQuickItem::isVisible() const
4038 {
4039     Q_D(const QQuickItem);
4040     return d->effectiveVisible;
4041 }
4042
4043 void QQuickItem::setVisible(bool v)
4044 {
4045     Q_D(QQuickItem);
4046     if (v == d->explicitVisible)
4047         return;
4048
4049     d->explicitVisible = v;
4050
4051     const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
4052     if (childVisibilityChanged && d->parentItem)
4053         emit d->parentItem->visibleChildrenChanged();   // signal the parent, not this!
4054 }
4055
4056 bool QQuickItem::isEnabled() const
4057 {
4058     Q_D(const QQuickItem);
4059     return d->effectiveEnable;
4060 }
4061
4062 void QQuickItem::setEnabled(bool e)
4063 {
4064     Q_D(QQuickItem);
4065     if (e == d->explicitEnable)
4066         return;
4067
4068     d->explicitEnable = e;
4069
4070     QQuickItem *scope = parentItem();
4071     while (scope && !scope->isFocusScope())
4072         scope = scope->parentItem();
4073
4074     d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
4075 }
4076
4077 bool QQuickItemPrivate::calcEffectiveVisible() const
4078 {
4079     // XXX todo - Should the effective visible of an element with no parent just be the current
4080     // effective visible?  This would prevent pointless re-processing in the case of an element
4081     // moving to/from a no-parent situation, but it is different from what graphics view does.
4082     return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
4083 }
4084
4085 bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
4086 {
4087     Q_Q(QQuickItem);
4088
4089     if (newEffectiveVisible && !explicitVisible) {
4090         // This item locally overrides visibility
4091         return false;   // effective visibility didn't change
4092     }
4093
4094     if (newEffectiveVisible == effectiveVisible) {
4095         // No change necessary
4096         return false;   // effective visibility didn't change
4097     }
4098
4099     effectiveVisible = newEffectiveVisible;
4100     dirty(Visible);
4101     if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4102
4103     if (canvas) {
4104         QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4105         if (canvasPriv->mouseGrabberItem == q)
4106             q->ungrabMouse();
4107     }
4108
4109     bool childVisibilityChanged = false;
4110     for (int ii = 0; ii < childItems.count(); ++ii)
4111         childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
4112
4113     itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
4114 #ifndef QT_NO_ACCESSIBILITY
4115     if (isAccessible) {
4116         QAccessibleEvent ev(q, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide);
4117         QAccessible::updateAccessibility(&ev);
4118     }
4119 #endif
4120     emit q->visibleChanged();
4121     if (childVisibilityChanged)
4122         emit q->visibleChildrenChanged();
4123
4124     return true;    // effective visibility DID change
4125 }
4126
4127 bool QQuickItemPrivate::calcEffectiveEnable() const
4128 {
4129     // XXX todo - Should the effective enable of an element with no parent just be the current
4130     // effective enable?  This would prevent pointless re-processing in the case of an element
4131     // moving to/from a no-parent situation, but it is different from what graphics view does.
4132     return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
4133 }
4134
4135 void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
4136 {
4137     Q_Q(QQuickItem);
4138
4139     if (newEffectiveEnable && !explicitEnable) {
4140         // This item locally overrides enable
4141         return;
4142     }
4143
4144     if (newEffectiveEnable == effectiveEnable) {
4145         // No change necessary
4146         return;
4147     }
4148
4149     effectiveEnable = newEffectiveEnable;
4150
4151     if (canvas) {
4152         QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4153         if (canvasPriv->mouseGrabberItem == q)
4154             q->ungrabMouse();
4155         if (scope && !effectiveEnable && activeFocus) {
4156             canvasPriv->clearFocusInScope(
4157                     scope, q,  QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4158         }
4159     }
4160
4161     for (int ii = 0; ii < childItems.count(); ++ii) {
4162         QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
4163                 (flags & QQuickItem::ItemIsFocusScope) && scope ? q : scope, newEffectiveEnable);
4164     }
4165
4166     if (canvas && scope && effectiveEnable && focus) {
4167         QQuickCanvasPrivate::get(canvas)->setFocusInScope(
4168                 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4169     }
4170
4171     emit q->enabledChanged();
4172 }
4173
4174 QString QQuickItemPrivate::dirtyToString() const
4175 {
4176 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
4177     if (!rv.isEmpty()) \
4178         rv.append(QLatin1String("|")); \
4179     rv.append(QLatin1String(#value)); \
4180 }
4181
4182 //    QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
4183     QString rv;
4184
4185     DIRTY_TO_STRING(TransformOrigin);
4186     DIRTY_TO_STRING(Transform);
4187     DIRTY_TO_STRING(BasicTransform);
4188     DIRTY_TO_STRING(Position);
4189     DIRTY_TO_STRING(Size);
4190     DIRTY_TO_STRING(ZValue);
4191     DIRTY_TO_STRING(Content);
4192     DIRTY_TO_STRING(Smooth);
4193     DIRTY_TO_STRING(OpacityValue);
4194     DIRTY_TO_STRING(ChildrenChanged);
4195     DIRTY_TO_STRING(ChildrenStackingChanged);
4196     DIRTY_TO_STRING(ParentChanged);
4197     DIRTY_TO_STRING(Clip);
4198     DIRTY_TO_STRING(Canvas);
4199     DIRTY_TO_STRING(EffectReference);
4200     DIRTY_TO_STRING(Visible);
4201     DIRTY_TO_STRING(HideReference);
4202     DIRTY_TO_STRING(PerformanceHints);
4203
4204     return rv;
4205 }
4206
4207 void QQuickItemPrivate::dirty(DirtyType type)
4208 {
4209     Q_Q(QQuickItem);
4210     if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4211         transformChanged();
4212
4213     if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
4214         dirtyAttributes |= type;
4215         if (canvas) {
4216             addToDirtyList();
4217             QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
4218         }
4219     }
4220 }
4221
4222 void QQuickItemPrivate::addToDirtyList()
4223 {
4224     Q_Q(QQuickItem);
4225
4226     Q_ASSERT(canvas);
4227     if (!prevDirtyItem) {
4228         Q_ASSERT(!nextDirtyItem);
4229
4230         QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
4231         nextDirtyItem = p->dirtyItemList;
4232         if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4233         prevDirtyItem = &p->dirtyItemList;
4234         p->dirtyItemList = q;
4235         p->dirtyItem(q);
4236     }
4237     Q_ASSERT(prevDirtyItem);
4238 }
4239
4240 void QQuickItemPrivate::removeFromDirtyList()
4241 {
4242     if (prevDirtyItem) {
4243         if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4244         *prevDirtyItem = nextDirtyItem;
4245         prevDirtyItem = 0;
4246         nextDirtyItem = 0;
4247     }
4248     Q_ASSERT(!prevDirtyItem);
4249     Q_ASSERT(!nextDirtyItem);
4250 }
4251
4252 void QQuickItemPrivate::refFromEffectItem(bool hide)
4253 {
4254     ++extra.value().effectRefCount;
4255     if (1 == extra->effectRefCount) {
4256         dirty(EffectReference);
4257         if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4258     }
4259     if (hide) {
4260         if (++extra->hideRefCount == 1)
4261             dirty(HideReference);
4262     }
4263 }
4264
4265 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4266 {
4267     Q_ASSERT(extra->effectRefCount);
4268     --extra->effectRefCount;
4269     if (0 == extra->effectRefCount) {
4270         dirty(EffectReference);
4271         if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4272     }
4273     if (unhide) {
4274         if (--extra->hideRefCount == 0)
4275             dirty(HideReference);
4276     }
4277 }
4278
4279 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4280 {
4281     Q_Q(QQuickItem);
4282     switch (change) {
4283     case QQuickItem::ItemChildAddedChange:
4284         q->itemChange(change, data);
4285         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4286             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4287             if (change.types & QQuickItemPrivate::Children) {
4288                 change.listener->itemChildAdded(q, data.item);
4289             }
4290         }
4291         break;
4292     case QQuickItem::ItemChildRemovedChange:
4293         q->itemChange(change, data);
4294         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4295             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4296             if (change.types & QQuickItemPrivate::Children) {
4297                 change.listener->itemChildRemoved(q, data.item);
4298             }
4299         }
4300         break;
4301     case QQuickItem::ItemSceneChange:
4302         q->itemChange(change, data);
4303         break;
4304     case QQuickItem::ItemVisibleHasChanged:
4305         q->itemChange(change, data);
4306         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4307             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4308             if (change.types & QQuickItemPrivate::Visibility) {
4309                 change.listener->itemVisibilityChanged(q);
4310             }
4311         }
4312         break;
4313     case QQuickItem::ItemParentHasChanged:
4314         q->itemChange(change, data);
4315         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4316             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4317             if (change.types & QQuickItemPrivate::Parent) {
4318                 change.listener->itemParentChanged(q, data.item);
4319             }
4320         }
4321         break;
4322     case QQuickItem::ItemOpacityHasChanged:
4323         q->itemChange(change, data);
4324         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4325             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4326             if (change.types & QQuickItemPrivate::Opacity) {
4327                 change.listener->itemOpacityChanged(q);
4328             }
4329         }
4330         break;
4331     case QQuickItem::ItemActiveFocusHasChanged:
4332         q->itemChange(change, data);
4333         break;
4334     case QQuickItem::ItemRotationHasChanged:
4335         q->itemChange(change, data);
4336         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4337             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4338             if (change.types & QQuickItemPrivate::Rotation) {
4339                 change.listener->itemRotationChanged(q);
4340             }
4341         }
4342         break;
4343     }
4344 }
4345
4346 /*!
4347     \property QQuickItem::smooth
4348     \brief whether the item is smoothed or not.
4349
4350     Primarily used in image based elements to decide if the item should use smooth
4351     sampling or not. Smooth sampling is performed using linear interpolation, while
4352     non-smooth is performed using nearest neighbor.
4353
4354     In Qt Quick 2.0, this property has minimal impact on performance.
4355
4356     By default is true.
4357 */
4358
4359 /*!
4360     Returns true if the item should be drawn with antialiasing and
4361     smooth pixmap filtering, false otherwise.
4362
4363     The default is false.
4364
4365     \sa setSmooth()
4366 */
4367 bool QQuickItem::smooth() const
4368 {
4369     Q_D(const QQuickItem);
4370     return d->smooth;
4371 }
4372
4373 /*!
4374     Sets whether the item should be drawn with antialiasing and
4375     smooth pixmap filtering to \a smooth.
4376
4377     \sa smooth()
4378 */
4379 void QQuickItem::setSmooth(bool smooth)
4380 {
4381     Q_D(QQuickItem);
4382     if (d->smooth == smooth)
4383         return;
4384
4385     d->smooth = smooth;
4386     d->dirty(QQuickItemPrivate::Smooth);
4387
4388     emit smoothChanged(smooth);
4389 }
4390
4391 QQuickItem::Flags QQuickItem::flags() const
4392 {
4393     Q_D(const QQuickItem);
4394     return (QQuickItem::Flags)d->flags;
4395 }
4396
4397 void QQuickItem::setFlag(Flag flag, bool enabled)
4398 {
4399     Q_D(QQuickItem);
4400     if (enabled)
4401         setFlags((Flags)(d->flags | (quint32)flag));
4402     else
4403         setFlags((Flags)(d->flags & ~(quint32)flag));
4404 }
4405
4406 void QQuickItem::setFlags(Flags flags)
4407 {
4408     Q_D(QQuickItem);
4409
4410     if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4411         if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4412             qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
4413             flags &= ~ItemIsFocusScope;
4414         } else if (d->flags & ItemIsFocusScope) {
4415             qWarning("QQuickItem: Cannot unset FocusScope flag.");
4416             flags |= ItemIsFocusScope;
4417         }
4418     }
4419
4420     if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4421         d->dirty(QQuickItemPrivate::Clip);
4422
4423     d->flags = flags;
4424 }
4425
4426 qreal QQuickItem::x() const
4427 {
4428     Q_D(const QQuickItem);
4429     return d->x;
4430 }
4431
4432 qreal QQuickItem::y() const
4433 {
4434     Q_D(const QQuickItem);
4435     return d->y;
4436 }
4437
4438 QPointF QQuickItem::pos() const
4439 {
4440     Q_D(const QQuickItem);
4441     return QPointF(d->x, d->y);
4442 }
4443
4444 void QQuickItem::setX(qreal v)
4445 {
4446     Q_D(QQuickItem);
4447     if (d->x == v)
4448         return;
4449
4450     qreal oldx = d->x;
4451     d->x = v;
4452
4453     d->dirty(QQuickItemPrivate::Position);
4454
4455     geometryChanged(QRectF(x(), y(), width(), height()),
4456                     QRectF(oldx, y(), width(), height()));
4457 }
4458
4459 void QQuickItem::setY(qreal v)
4460 {
4461     Q_D(QQuickItem);
4462     if (d->y == v)
4463         return;
4464
4465     qreal oldy = d->y;
4466     d->y = v;
4467
4468     d->dirty(QQuickItemPrivate::Position);
4469
4470     geometryChanged(QRectF(x(), y(), width(), height()),
4471                     QRectF(x(), oldy, width(), height()));
4472 }
4473
4474 void QQuickItem::setPos(const QPointF &pos)
4475 {
4476     Q_D(QQuickItem);
4477     if (QPointF(d->x, d->y) == pos)
4478         return;
4479
4480     qreal oldx = d->x;
4481     qreal oldy = d->y;
4482
4483     d->x = pos.x();
4484     d->y = pos.y();
4485
4486     d->dirty(QQuickItemPrivate::Position);
4487
4488     geometryChanged(QRectF(x(), y(), width(), height()),
4489                     QRectF(oldx, oldy, width(), height()));
4490 }
4491
4492 qreal QQuickItem::width() const
4493 {
4494     Q_D(const QQuickItem);
4495     return d->width;
4496 }
4497
4498 void QQuickItem::setWidth(qreal w)
4499 {
4500     Q_D(QQuickItem);
4501     if (qIsNaN(w))
4502         return;
4503
4504     d->widthValid = true;
4505     if (d->width == w)
4506         return;
4507
4508     qreal oldWidth = d->width;
4509     d->width = w;
4510
4511     d->dirty(QQuickItemPrivate::Size);
4512
4513     geometryChanged(QRectF(x(), y(), width(), height()),
4514                     QRectF(x(), y(), oldWidth, height()));
4515 }
4516
4517 void QQuickItem::resetWidth()
4518 {
4519     Q_D(QQuickItem);
4520     d->widthValid = false;
4521     setImplicitWidth(implicitWidth());
4522 }
4523
4524 void QQuickItemPrivate::implicitWidthChanged()
4525 {
4526     Q_Q(QQuickItem);
4527     for (int ii = 0; ii < changeListeners.count(); ++ii) {
4528         const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4529         if (change.types & QQuickItemPrivate::ImplicitWidth) {
4530             change.listener->itemImplicitWidthChanged(q);
4531         }
4532     }
4533     emit q->implicitWidthChanged();
4534 }
4535
4536 qreal QQuickItemPrivate::getImplicitWidth() const
4537 {
4538     return implicitWidth;
4539 }
4540 /*!
4541     Returns the width of the item that is implied by other properties that determine the content.
4542 */
4543 qreal QQuickItem::implicitWidth() const
4544 {
4545     Q_D(const QQuickItem);
4546     return d->getImplicitWidth();
4547 }
4548
4549 /*!
4550     \qmlproperty real QtQuick2::Item::implicitWidth
4551     \qmlproperty real QtQuick2::Item::implicitHeight
4552
4553     Defines the natural width or height of the Item if no \l width or \l height is specified.
4554
4555     The default implicit size for most items is 0x0, however some elements have an inherent
4556     implicit size which cannot be overridden, e.g. Image, Text.
4557
4558     Setting the implicit size is useful for defining components that have a preferred size
4559     based on their content, for example:
4560
4561     \qml
4562     // Label.qml
4563     import QtQuick 2.0
4564
4565     Item {
4566         property alias icon: image.source
4567         property alias label: text.text
4568         implicitWidth: text.implicitWidth + image.implicitWidth
4569         implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4570         Image { id: image }
4571         Text {
4572             id: text
4573             wrapMode: Text.Wrap
4574             anchors.left: image.right; anchors.right: parent.right
4575             anchors.verticalCenter: parent.verticalCenter
4576         }
4577     }
4578     \endqml
4579
4580     \b Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4581     incurs a performance penalty as the text must be laid out twice.
4582 */
4583
4584 /*!
4585     Sets the implied width of the item to \a w.
4586     This is the width implied by other properties that determine the content.
4587 */
4588 void QQuickItem::setImplicitWidth(qreal w)
4589 {
4590     Q_D(QQuickItem);
4591     bool changed = w != d->implicitWidth;
4592     d->implicitWidth = w;
4593     if (d->width == w || widthValid()) {
4594         if (changed)
4595             d->implicitWidthChanged();
4596         return;
4597     }
4598
4599     qreal oldWidth = d->width;
4600     d->width = w;
4601
4602     d->dirty(QQuickItemPrivate::Size);
4603
4604     geometryChanged(QRectF(x(), y(), width(), height()),
4605                     QRectF(x(), y(), oldWidth, height()));
4606
4607     if (changed)
4608         d->implicitWidthChanged();
4609 }
4610
4611 /*!
4612     Returns whether the width property has been set explicitly.
4613 */
4614 bool QQuickItem::widthValid() const
4615 {
4616     Q_D(const QQuickItem);
4617     return d->widthValid;
4618 }
4619
4620 qreal QQuickItem::height() const
4621 {
4622     Q_D(const QQuickItem);
4623     return d->height;
4624 }
4625
4626 void QQuickItem::setHeight(qreal h)
4627 {
4628     Q_D(QQuickItem);
4629     if (qIsNaN(h))
4630         return;
4631
4632     d->heightValid = true;
4633     if (d->height == h)
4634         return;
4635
4636     qreal oldHeight = d->height;
4637     d->height = h;
4638
4639     d->dirty(QQuickItemPrivate::Size);
4640
4641     geometryChanged(QRectF(x(), y(), width(), height()),
4642                     QRectF(x(), y(), width(), oldHeight));
4643 }
4644
4645 void QQuickItem::resetHeight()
4646 {
4647     Q_D(QQuickItem);
4648     d->heightValid = false;
4649     setImplicitHeight(implicitHeight());
4650 }
4651
4652 void QQuickItemPrivate::implicitHeightChanged()
4653 {
4654     Q_Q(QQuickItem);
4655     for (int ii = 0; ii < changeListeners.count(); ++ii) {
4656         const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4657         if (change.types & QQuickItemPrivate::ImplicitHeight) {
4658             change.listener->itemImplicitHeightChanged(q);
4659         }
4660     }
4661     emit q->implicitHeightChanged();
4662 }
4663
4664 qreal QQuickItemPrivate::getImplicitHeight() const
4665 {
4666     return implicitHeight;
4667 }
4668
4669 /*!
4670     Returns the height of the item that is implied by other properties that determine the content.
4671 */
4672 qreal QQuickItem::implicitHeight() const
4673 {
4674     Q_D(const QQuickItem);
4675     return d->getImplicitHeight();
4676 }
4677
4678
4679 /*!
4680     Sets the implied height of the item to \a h.
4681     This is the height implied by other properties that determine the content.
4682 */
4683 void QQuickItem::setImplicitHeight(qreal h)
4684 {
4685     Q_D(QQuickItem);
4686     bool changed = h != d->implicitHeight;
4687     d->implicitHeight = h;
4688     if (d->height == h || heightValid()) {
4689         if (changed)
4690             d->implicitHeightChanged();
4691         return;
4692     }
4693
4694     qreal oldHeight = d->height;
4695     d->height = h;
4696
4697     d->dirty(QQuickItemPrivate::Size);
4698
4699     geometryChanged(QRectF(x(), y(), width(), height()),
4700                     QRectF(x(), y(), width(), oldHeight));
4701
4702     if (changed)
4703         d->implicitHeightChanged();
4704 }
4705
4706 void QQuickItem::setImplicitSize(qreal w, qreal h)
4707 {
4708     Q_D(QQuickItem);
4709     bool wChanged = w != d->implicitWidth;
4710     bool hChanged = h != d->implicitHeight;
4711
4712     d->implicitWidth = w;
4713     d->implicitHeight = h;
4714
4715     bool wDone = false;
4716     bool hDone = false;
4717     if (d->width == w || widthValid()) {
4718         if (wChanged)
4719             d->implicitWidthChanged();
4720         wDone = true;
4721     }
4722     if (d->height == h || heightValid()) {
4723         if (hChanged)
4724             d->implicitHeightChanged();
4725         hDone = true;
4726     }
4727     if (wDone && hDone)
4728         return;
4729
4730     qreal oldWidth = d->width;
4731     qreal oldHeight = d->height;
4732     if (!wDone)
4733         d->width = w;
4734     if (!hDone)
4735         d->height = h;
4736
4737     d->dirty(QQuickItemPrivate::Size);
4738
4739     geometryChanged(QRectF(x(), y(), width(), height()),
4740                     QRectF(x(), y(), oldWidth, oldHeight));
4741
4742     if (!wDone && wChanged)
4743         d->implicitWidthChanged();
4744     if (!hDone && hChanged)
4745         d->implicitHeightChanged();
4746 }
4747
4748 /*!
4749     Returns whether the height property has been set explicitly.
4750 */
4751 bool QQuickItem::heightValid() const
4752 {
4753     Q_D(const QQuickItem);
4754     return d->heightValid;
4755 }
4756
4757 void QQuickItem::setSize(const QSizeF &size)
4758 {
4759     Q_D(QQuickItem);
4760     d->heightValid = true;
4761     d->widthValid = true;
4762
4763     if (QSizeF(d->width, d->height) == size)
4764         return;
4765
4766     qreal oldHeight = d->height;
4767     qreal oldWidth = d->width;
4768     d->height = size.height();
4769     d->width = size.width();
4770
4771     d->dirty(QQuickItemPrivate::Size);
4772
4773     geometryChanged(QRectF(x(), y(), width(), height()),
4774                     QRectF(x(), y(), oldWidth, oldHeight));
4775 }
4776
4777 bool QQuickItem::hasActiveFocus() const
4778 {
4779     Q_D(const QQuickItem);
4780     return d->activeFocus;
4781 }
4782
4783 bool QQuickItem::hasFocus() const
4784 {
4785     Q_D(const QQuickItem);
4786     return d->focus;
4787 }
4788
4789 void QQuickItem::setFocus(bool focus)
4790 {
4791     Q_D(QQuickItem);
4792     if (d->focus == focus)
4793         return;
4794
4795     if (d->canvas || d->parentItem) {
4796         // Need to find our nearest focus scope
4797         QQuickItem *scope = parentItem();
4798         while (scope && !scope->isFocusScope() && scope->parentItem())
4799             scope = scope->parentItem();
4800         if (d->canvas) {
4801             if (focus)
4802                 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4803             else
4804                 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4805         } else {
4806             // do the focus changes from setFocusInScope/clearFocusInScope that are
4807             // unrelated to a canvas
4808             QVarLengthArray<QQuickItem *, 20> changed;
4809             QQuickItem *oldSubFocusItem = QQuickItemPrivate::get(scope)->subFocusItem;
4810             if (oldSubFocusItem) {
4811                 QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(scope, false);
4812                 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
4813                 changed << oldSubFocusItem;
4814             }
4815             d->updateSubFocusItem(scope, focus);
4816
4817             d->focus = focus;
4818             changed << this;
4819             emit focusChanged(focus);
4820
4821             QQuickCanvasPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
4822         }
4823     } else {
4824         d->focus = focus;
4825         emit focusChanged(focus);
4826     }
4827 }
4828
4829 bool QQuickItem::isFocusScope() const
4830 {
4831     return flags() & ItemIsFocusScope;
4832 }
4833
4834 QQuickItem *QQuickItem::scopedFocusItem() const
4835 {
4836     Q_D(const QQuickItem);
4837     if (!isFocusScope())
4838         return 0;
4839     else
4840         return d->subFocusItem;
4841 }
4842
4843
4844 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
4845 {
4846     Q_D(const QQuickItem);
4847     return d->acceptedMouseButtons();
4848 }
4849
4850 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4851 {
4852     Q_D(QQuickItem);
4853     if (buttons & Qt::LeftButton)
4854         d->extra.setFlag();
4855     else
4856         d->extra.clearFlag();
4857
4858     buttons &= ~Qt::LeftButton;
4859     if (buttons || d->extra.isAllocated())
4860         d->extra.value().acceptedMouseButtons = buttons;
4861 }
4862
4863 bool QQuickItem::filtersChildMouseEvents() const
4864 {
4865     Q_D(const QQuickItem);
4866     return d->filtersChildMouseEvents;
4867 }
4868
4869 void QQuickItem::setFiltersChildMouseEvents(bool filter)
4870 {
4871     Q_D(QQuickItem);
4872     d->filtersChildMouseEvents = filter;
4873 }
4874
4875 bool QQuickItem::isUnderMouse() const
4876 {
4877     Q_D(const QQuickItem);
4878     if (!d->canvas)
4879         return false;
4880
4881     QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition;
4882     if (QRectF(0, 0, width(), height()).contains(mapFromScene(cursorPos))) // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
4883         return true;
4884     return false;
4885 }
4886
4887 bool QQuickItem::acceptHoverEvents() const
4888 {
4889     Q_D(const QQuickItem);
4890     return d->hoverEnabled;
4891 }
4892
4893 void QQuickItem::setAcceptHoverEvents(bool enabled)
4894 {
4895     Q_D(QQuickItem);
4896     d->hoverEnabled = enabled;
4897 }
4898
4899 void QQuickItem::grabMouse()
4900 {
4901     Q_D(QQuickItem);
4902     if (!d->canvas)
4903         return;
4904     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4905     if (canvasPriv->mouseGrabberItem == this)
4906         return;
4907
4908     QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
4909     canvasPriv->mouseGrabberItem = this;
4910     if (oldGrabber) {
4911         QEvent ev(QEvent::UngrabMouse);
4912         d->canvas->sendEvent(oldGrabber, &ev);
4913     }
4914 }
4915
4916 void QQuickItem::ungrabMouse()
4917 {
4918     Q_D(QQuickItem);
4919     if (!d->canvas)
4920         return;
4921     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4922     if (canvasPriv->mouseGrabberItem != this) {
4923         qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
4924         return;
4925     }
4926
4927     canvasPriv->mouseGrabberItem = 0;
4928
4929     QEvent ev(QEvent::UngrabMouse);
4930     d->canvas->sendEvent(this, &ev);
4931 }
4932
4933 bool QQuickItem::keepMouseGrab() const
4934 {
4935     Q_D(const QQuickItem);
4936     return d->keepMouse;
4937 }
4938
4939 /*!
4940   The flag indicating whether the mouse should remain
4941   with this item is set to \a keep.
4942
4943   This is useful for items that wish to grab and keep mouse
4944   interaction following a predefined gesture.  For example,
4945   an item that is interested in horizontal mouse movement
4946   may set keepMouseGrab to true once a threshold has been
4947   exceeded.  Once keepMouseGrab has been set to true, filtering
4948   items will not react to mouse events.
4949
4950   If the item does not indicate that it wishes to retain mouse grab,
4951   a filtering item may steal the grab. For example, Flickable may attempt
4952   to steal a mouse grab if it detects that the user has begun to
4953   move the viewport.
4954
4955   \sa keepMouseGrab()
4956  */
4957 void QQuickItem::setKeepMouseGrab(bool keep)
4958 {
4959     Q_D(QQuickItem);
4960     d->keepMouse = keep;
4961 }
4962
4963 /*!
4964     Grabs the touch points specified by \a ids.
4965
4966     These touch points will be owned by the item until
4967     they are released. Alternatively, the grab can be stolen
4968     by a filtering item like Flickable. Use setKeepTouchGrab()
4969     to prevent the grab from being stolen.
4970
4971     \sa ungrabTouchPoints(), setKeepTouchGrab()
4972 */
4973 void QQuickItem::grabTouchPoints(const QList<int> &ids)
4974 {
4975     Q_D(QQuickItem);
4976     if (!d->canvas)
4977         return;
4978     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4979
4980     QSet<QQuickItem*> ungrab;
4981     for (int i = 0; i < ids.count(); ++i) {
4982         QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
4983         if (oldGrabber == this)
4984             return;
4985
4986         canvasPriv->itemForTouchPointId[ids.at(i)] = this;
4987         if (oldGrabber)
4988             ungrab.insert(oldGrabber);
4989     }
4990     foreach (QQuickItem *oldGrabber, ungrab)
4991         oldGrabber->touchUngrabEvent();
4992 }
4993
4994 /*!
4995     Ungrabs the touch points owned by this item.
4996
4997     \sa grabTouchPoints()
4998 */
4999 void QQuickItem::ungrabTouchPoints()
5000 {
5001     Q_D(QQuickItem);
5002     if (!d->canvas)
5003         return;
5004     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5005
5006     QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
5007     while (i.hasNext()) {
5008         i.next();
5009         if (i.value() == this)
5010             i.remove();
5011     }
5012     touchUngrabEvent();
5013 }
5014
5015 /*!
5016     Returns a value indicating whether the touch points grabbed by this item
5017     should remain with this item exclusively.
5018
5019     \sa setKeepTouchGrab(), keepMouseGrab()
5020 */
5021 bool QQuickItem::keepTouchGrab() const
5022 {
5023     Q_D(const QQuickItem);
5024     return d->keepTouch;
5025 }
5026
5027 /*!
5028   The flag indicating whether the touch points grabbed
5029   by this item should remain with this item is set to \a keep.
5030
5031   This is useful for items that wish to grab and keep specific touch
5032   points following a predefined gesture.  For example,
5033   an item that is interested in horizontal touch point movement
5034   may set setKeepTouchGrab to true once a threshold has been
5035   exceeded.  Once setKeepTouchGrab has been set to true, filtering
5036   items will not react to the relevant touch points.
5037
5038   If the item does not indicate that it wishes to retain touch point grab,
5039   a filtering item may steal the grab. For example, Flickable may attempt
5040   to steal a touch point grab if it detects that the user has begun to
5041   move the viewport.
5042
5043   \sa keepTouchGrab(), setKeepMouseGrab()
5044  */
5045 void QQuickItem::setKeepTouchGrab(bool keep)
5046 {
5047     Q_D(QQuickItem);
5048     d->keepTouch = keep;
5049 }
5050
5051 /*!
5052     \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
5053
5054     Maps the point (\a x, \a y), which is in \a item's coordinate system, to
5055     this item's coordinate system, and returns an object with \c x and \c y
5056     properties matching the mapped coordinate.
5057
5058     If \a item is a \c null value, this maps the point from the coordinate
5059     system of the root QML view.
5060 */
5061 /*!
5062     \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
5063
5064     Maps the point (\a x, \a y), which is in this item's coordinate system, to
5065     \a item's coordinate system, and returns an object with \c x and \c y
5066     properties matching the mapped coordinate.
5067
5068     If \a item is a \c null value, this maps \a x and \a y to the coordinate
5069     system of the root QML view.
5070 */
5071 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
5072 {
5073     QPointF p = mapToScene(point);
5074     if (item)
5075         p = item->mapFromScene(p);
5076     return p;
5077 }
5078
5079 QPointF QQuickItem::mapToScene(const QPointF &point) const
5080 {
5081     Q_D(const QQuickItem);
5082     return d->itemToCanvasTransform().map(point);
5083 }
5084
5085 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
5086 {
5087     Q_D(const QQuickItem);
5088     QTransform t = d->itemToCanvasTransform();
5089     if (item)
5090         t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
5091     return t.mapRect(rect);
5092 }
5093
5094 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
5095 {
5096     Q_D(const QQuickItem);
5097     return d->itemToCanvasTransform().mapRect(rect);
5098 }
5099
5100 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
5101 {
5102     QPointF p = item?item->mapToScene(point):point;
5103     return mapFromScene(p);
5104 }
5105
5106 QPointF QQuickItem::mapFromScene(const QPointF &point) const
5107 {
5108     Q_D(const QQuickItem);
5109     return d->canvasToItemTransform().map(point);
5110 }
5111
5112 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
5113 {
5114     Q_D(const QQuickItem);
5115     QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
5116     t *= d->canvasToItemTransform();
5117     return t.mapRect(rect);
5118 }
5119
5120 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
5121 {
5122     Q_D(const QQuickItem);
5123     return d->canvasToItemTransform().mapRect(rect);
5124 }
5125
5126
5127 /*!
5128     \qmlmethod QtQuick2::Item::forceActiveFocus()
5129
5130     Forces active focus on the item.
5131
5132     This method sets focus on the item and makes sure that all the focus scopes
5133     higher in the object hierarchy are also given the focus.
5134 */
5135
5136 /*!
5137     Forces active focus on the item.
5138
5139     This method sets focus on the item and makes sure that all the focus scopes
5140     higher in the object hierarchy are also given the focus.
5141 */
5142
5143 /*!
5144   \qmlmethod QtQuick2::Item::childAt(real x, real y)
5145
5146   Returns the visible child item at point (\a x, \a y), which is in this
5147   item's coordinate system, or \c null if there is no such item.
5148 */
5149
5150 /*!
5151   Returns the visible child item at point (\a x, \a y), which is in this
5152   item's coordinate system, or 0 if there is no such item.
5153 */
5154
5155 /*!
5156   \qmlproperty list<State> QtQuick2::Item::states
5157   This property holds a list of states defined by the item.
5158
5159   \qml
5160   Item {
5161       states: [
5162           State {
5163               // ...
5164           },
5165           State {
5166               // ...
5167           }
5168           // ...
5169       ]
5170   }
5171   \endqml
5172
5173   \sa {qmlstate}{States}
5174 */
5175 /*!
5176   \qmlproperty list<Transition> QtQuick2::Item::transitions
5177   This property holds a list of transitions defined by the item.
5178
5179   \qml
5180   Item {
5181       transitions: [
5182           Transition {
5183               // ...
5184           },
5185           Transition {
5186               // ...
5187           }
5188           // ...
5189       ]
5190   }
5191   \endqml
5192
5193   \sa {QML Animation and Transitions}{Transitions}
5194 */
5195 /*
5196   \qmlproperty list<Filter> QtQuick2::Item::filter
5197   This property holds a list of graphical filters to be applied to the item.
5198
5199   \l {Filter}{Filters} include things like \l {Blur}{blurring}
5200   the item, or giving it a \l Reflection.  Some
5201   filters may not be available on all canvases; if a filter is not
5202   available on a certain canvas, it will simply not be applied for
5203   that canvas (but the QML will still be considered valid).
5204
5205   \qml
5206   Item {
5207       filter: [
5208           Blur {
5209               // ...
5210           },
5211           Reflection {
5212               // ...
5213           }
5214           // ...
5215       ]
5216   }
5217   \endqml
5218 */
5219
5220 /*!
5221   \qmlproperty bool QtQuick2::Item::clip
5222   This property holds whether clipping is enabled. The default clip value is \c false.
5223
5224   If clipping is enabled, an item will clip its own painting, as well
5225   as the painting of its children, to its bounding rectangle.
5226
5227   Non-rectangular clipping regions are not supported for performance reasons.
5228 */
5229
5230 /*!
5231   \property QQuickItem::clip
5232   This property holds whether clipping is enabled. The default clip value is \c false.
5233
5234   If clipping is enabled, an item will clip its own painting, as well
5235   as the painting of its children, to its bounding rectangle. If you set
5236   clipping during an item's paint operation, remember to re-set it to
5237   prevent clipping the rest of your scene.
5238
5239   Non-rectangular clipping regions are not supported for performance reasons.
5240 */
5241
5242 /*!
5243   \qmlproperty string QtQuick2::Item::state
5244
5245   This property holds the name of the current state of the item.
5246
5247   This property is often used in scripts to change between states. For
5248   example:
5249
5250   \js
5251   function toggle() {
5252       if (button.state == 'On')
5253           button.state = 'Off';
5254       else
5255           button.state = 'On';
5256   }
5257   \endjs
5258
5259   If the item is in its base state (i.e. no explicit state has been
5260   set), \c state will be a blank string. Likewise, you can return an
5261   item to its base state by setting its current state to \c ''.
5262
5263   \sa {qmlstates}{States}
5264 */
5265
5266 /*!
5267   \qmlproperty list<Transform> QtQuick2::Item::transform
5268   This property holds the list of transformations to apply.
5269
5270   For more information see \l Transform.
5271 */
5272
5273 /*!
5274     \enum QQuickItem::TransformOrigin
5275
5276     Controls the point about which simple transforms like scale apply.
5277
5278     \value TopLeft The top-left corner of the item.
5279     \value Top The center point of the top of the item.
5280     \value TopRight The top-right corner of the item.
5281     \value Left The left most point of the vertical middle.
5282     \value Center The center of the item.
5283     \value Right The right most point of the vertical middle.
5284     \value BottomLeft The bottom-left corner of the item.
5285     \value Bottom The center point of the bottom of the item.
5286     \value BottomRight The bottom-right corner of the item.
5287 */
5288
5289
5290 /*!
5291   \qmlproperty bool QtQuick2::Item::activeFocus
5292
5293   This property indicates whether the item has active focus.
5294
5295   An item with active focus will receive keyboard input,
5296   or is a FocusScope ancestor of the item that will receive keyboard input.
5297
5298   Usually, activeFocus is gained by setting focus on an item and its enclosing
5299   FocusScopes. In the following example \c input will have activeFocus.
5300   \qml
5301   Rectangle {
5302       FocusScope {
5303           focus: true
5304           TextInput {
5305               id: input
5306               focus: true
5307           }
5308       }
5309   }
5310   \endqml
5311
5312   \sa focus, {qmlfocus}{Keyboard Focus}
5313 */
5314
5315 /*!
5316   \qmlproperty bool QtQuick2::Item::focus
5317   This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5318   will gain active focus when the enclosing focus scope gains active focus.
5319   In the following example, \c input will be given active focus when \c scope gains active focus.
5320   \qml
5321   Rectangle {
5322       FocusScope {
5323           id: scope
5324           TextInput {
5325               id: input
5326               focus: true
5327           }
5328       }
5329   }
5330   \endqml
5331
5332   For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5333   On a practical level, that means the following QML will give active focus to \c input on startup.
5334
5335   \qml
5336   Rectangle {
5337       TextInput {
5338           id: input
5339           focus: true
5340       }
5341   }
5342   \endqml
5343
5344   \sa activeFocus, {qmlfocus}{Keyboard Focus}
5345 */
5346
5347
5348 /*!
5349   \property QQuickItem::anchors
5350   \internal
5351 */
5352
5353 /*!
5354   \property QQuickItem::left
5355   \internal
5356 */
5357
5358 /*!
5359   \property QQuickItem::right
5360   \internal
5361 */
5362
5363 /*!
5364   \property QQuickItem::horizontalCenter
5365   \internal
5366 */
5367
5368 /*!
5369   \property QQuickItem::top
5370   \internal
5371 */
5372
5373 /*!
5374   \property QQuickItem::bottom
5375   \internal
5376 */
5377
5378 /*!
5379   \property QQuickItem::verticalCenter
5380   \internal
5381 */
5382
5383 /*!
5384   \property QQuickItem::focus
5385   \internal
5386 */
5387
5388 /*!
5389   \property QQuickItem::transform
5390   \internal
5391 */
5392
5393 /*!
5394   \property QQuickItem::transformOrigin
5395   \internal
5396 */
5397
5398 /*!
5399   \property QQuickItem::activeFocus
5400   \internal
5401 */
5402
5403 /*!
5404   \property QQuickItem::baseline
5405   \internal
5406 */
5407
5408 /*!
5409   \property QQuickItem::data
5410   \internal
5411 */
5412
5413 /*!
5414   \property QQuickItem::resources
5415   \internal
5416 */
5417
5418 /*!
5419   \property QQuickItem::state
5420   \internal
5421 */
5422
5423 /*!
5424   \property QQuickItem::states
5425   \internal
5426 */
5427
5428 /*!
5429   \property QQuickItem::transformOriginPoint
5430   \internal
5431 */
5432
5433 /*!
5434   \property QQuickItem::transitions
5435   \internal
5436 */
5437
5438 bool QQuickItem::event(QEvent *ev)
5439 {
5440 #if 0
5441     if (ev->type() == QEvent::PolishRequest) {
5442         Q_D(QQuickItem);
5443         d->polishScheduled = false;
5444         updatePolish();
5445         return true;
5446     } else {
5447         return QObject::event(ev);
5448     }
5449 #endif
5450     if (ev->type() == QEvent::InputMethodQuery) {
5451         QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5452         Qt::InputMethodQueries queries = query->queries();
5453         for (uint i = 0; i < 32; ++i) {
5454             Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5455             if (q) {
5456                 QVariant v = inputMethodQuery(q);
5457                 query->setValue(q, v);
5458             }
5459         }
5460         query->accept();
5461         return true;
5462     } else if (ev->type() == QEvent::InputMethod) {
5463         inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5464         return true;
5465     }
5466     return QObject::event(ev);
5467 }
5468
5469 #ifndef QT_NO_DEBUG_STREAM
5470 QDebug operator<<(QDebug debug, QQuickItem *item)
5471 {
5472     if (!item) {
5473         debug << "QQuickItem(0)";
5474         return debug;
5475     }
5476
5477     debug << item->metaObject()->className() << "(this =" << ((void*)item)
5478           << ", name=" << item->objectName()
5479           << ", parent =" << ((void*)item->parentItem())
5480           << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5481           << ", z =" << item->z() << ')';
5482     return debug;
5483 }
5484 #endif
5485
5486 qint64 QQuickItemPrivate::consistentTime = -1;
5487 void QQuickItemPrivate::setConsistentTime(qint64 t)
5488 {
5489     consistentTime = t;
5490 }
5491
5492 class QElapsedTimerConsistentTimeHack
5493 {
5494 public:
5495     void start() {
5496         t1 = QQuickItemPrivate::consistentTime;
5497         t2 = 0;
5498     }
5499     qint64 elapsed() {
5500         return QQuickItemPrivate::consistentTime - t1;
5501     }
5502     qint64 restart() {
5503         qint64 val = QQuickItemPrivate::consistentTime - t1;
5504         t1 = QQuickItemPrivate::consistentTime;
5505         t2 = 0;
5506         return val;
5507     }
5508
5509 private:
5510     qint64 t1;
5511     qint64 t2;
5512 };
5513
5514 void QQuickItemPrivate::start(QElapsedTimer &t)
5515 {
5516     if (QQuickItemPrivate::consistentTime == -1)
5517         t.start();
5518     else
5519         ((QElapsedTimerConsistentTimeHack*)&t)->start();
5520 }
5521
5522 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5523 {
5524     if (QQuickItemPrivate::consistentTime == -1)
5525         return t.elapsed();
5526     else
5527         return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5528 }
5529
5530 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5531 {
5532     if (QQuickItemPrivate::consistentTime == -1)
5533         return t.restart();
5534     else
5535         return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5536 }
5537
5538 /*!
5539     \fn bool QQuickItem::isTextureProvider() const
5540
5541     Returns true if this item is a texture provider. The default
5542     implementation returns false.
5543
5544     This function can be called from any thread.
5545  */
5546
5547 bool QQuickItem::isTextureProvider() const
5548 {
5549     Q_D(const QQuickItem);
5550     return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5551            d->extra->layer->effectSource()->isTextureProvider() : false;
5552 }
5553
5554 /*!
5555     \fn QSGTextureProvider *QQuickItem::textureProvider() const
5556
5557     Returns the texture provider for an item. The default implementation
5558     returns 0.
5559
5560     This function may only be called on the rendering thread.
5561  */
5562
5563 QSGTextureProvider *QQuickItem::textureProvider() const
5564 {
5565     Q_D(const QQuickItem);
5566     return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5567            d->extra->layer->effectSource()->textureProvider() : 0;
5568 }
5569
5570 QQuickItemLayer *QQuickItemPrivate::layer() const
5571 {
5572     if (!extra.isAllocated() || !extra->layer) {
5573         extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
5574         if (!componentComplete)
5575             extra->layer->classBegin();
5576     }
5577     return extra->layer;
5578 }
5579
5580 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
5581     : m_item(item)
5582     , m_enabled(false)
5583     , m_mipmap(false)
5584     , m_smooth(false)
5585     , m_componentComplete(true)
5586     , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
5587     , m_format(QQuickShaderEffectSource::RGBA)
5588     , m_name("source")
5589     , m_effectComponent(0)
5590     , m_effect(0)
5591     , m_effectSource(0)
5592 {
5593 }
5594
5595 QQuickItemLayer::~QQuickItemLayer()
5596 {
5597     delete m_effectSource;
5598     delete m_effect;
5599 }
5600
5601
5602
5603 /*!
5604     \qmlproperty bool QtQuick2::Item::layer.enabled
5605
5606     Holds wether the item is layered or not. Layering is disabled by default.
5607
5608     A layered item is rendered into an offscreen surface and cached until
5609     it is changed. Enabling layering for complex QML item hierarchies can
5610     some times be an optimization.
5611
5612     None of the other layer properties have any effect when the layer
5613     is disabled.
5614  */
5615
5616 void QQuickItemLayer::setEnabled(bool e)
5617 {
5618     if (e == m_enabled)
5619         return;
5620     m_enabled = e;
5621     if (m_componentComplete) {
5622         if (m_enabled)
5623             activate();
5624         else
5625             deactivate();
5626     }
5627
5628     emit enabledChanged(e);
5629 }
5630
5631 void QQuickItemLayer::classBegin()
5632 {
5633     Q_ASSERT(!m_effectSource);
5634     Q_ASSERT(!m_effect);
5635     m_componentComplete = false;
5636 }
5637
5638 void QQuickItemLayer::componentComplete()
5639 {
5640     Q_ASSERT(!m_componentComplete);
5641     m_componentComplete = true;
5642     if (m_enabled)
5643         activate();
5644 }
5645
5646 void QQuickItemLayer::activate()
5647 {
5648     Q_ASSERT(!m_effectSource);
5649     m_effectSource = new QQuickShaderEffectSource();
5650
5651     QQuickItem *parentItem = m_item->parentItem();
5652     if (parentItem) {
5653         m_effectSource->setParentItem(parentItem);
5654         m_effectSource->stackAfter(m_item);
5655     }
5656
5657     m_effectSource->setSourceItem(m_item);
5658     m_effectSource->setHideSource(true);
5659     m_effectSource->setSmooth(m_smooth);
5660     m_effectSource->setTextureSize(m_size);
5661     m_effectSource->setSourceRect(m_sourceRect);
5662     m_effectSource->setMipmap(m_mipmap);
5663     m_effectSource->setWrapMode(m_wrapMode);
5664     m_effectSource->setFormat(m_format);
5665
5666     if (m_effectComponent)
5667         activateEffect();
5668
5669     m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5670
5671     updateZ();
5672     updateGeometry();
5673     updateOpacity();
5674     updateMatrix();
5675
5676     QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5677     id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5678 }
5679
5680 void QQuickItemLayer::deactivate()
5681 {
5682     Q_ASSERT(m_effectSource);
5683
5684     if (m_effectComponent)
5685         deactivateEffect();
5686
5687     delete m_effectSource;
5688     m_effectSource = 0;
5689
5690     QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5691     id->removeItemChangeListener(this,  QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5692 }
5693
5694 void QQuickItemLayer::activateEffect()
5695 {
5696     Q_ASSERT(m_effectSource);
5697     Q_ASSERT(m_effectComponent);
5698     Q_ASSERT(!m_effect);
5699
5700     QObject *created = m_effectComponent->beginCreate(m_effectComponent->creationContext());
5701     m_effect = qobject_cast<QQuickItem *>(created);
5702     if (!m_effect) {
5703         qWarning("Item: layer.effect is not a QML Item.");
5704         m_effectComponent->completeCreate();
5705         delete created;
5706         return;
5707     }
5708     QQuickItem *parentItem = m_item->parentItem();
5709     if (parentItem) {
5710         m_effect->setParentItem(parentItem);
5711         m_effect->stackAfter(m_effectSource);
5712     }
5713     m_effect->setVisible(m_item->isVisible());
5714     m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
5715     m_effectComponent->completeCreate();
5716 }
5717
5718 void QQuickItemLayer::deactivateEffect()
5719 {
5720     Q_ASSERT(m_effectSource);
5721     Q_ASSERT(m_effectComponent);
5722
5723     delete m_effect;
5724     m_effect = 0;
5725 }
5726
5727
5728 /*!
5729     \qmlproperty Component QtQuick2::Item::layer.effect
5730
5731     Holds the effect that is applied to this layer.
5732
5733     The effect is typically a \l ShaderEffect component, although any \l Item component can be
5734     assigned. The effect should have a source texture property with a name matching \l samplerName.
5735
5736     \sa samplerName
5737  */
5738
5739 void QQuickItemLayer::setEffect(QQmlComponent *component)
5740 {
5741     if (component == m_effectComponent)
5742         return;
5743
5744     bool updateNeeded = false;
5745     if (m_effectSource && m_effectComponent) {
5746         deactivateEffect();
5747         updateNeeded = true;
5748     }
5749
5750     m_effectComponent = component;
5751
5752     if (m_effectSource && m_effectComponent) {
5753         activateEffect();
5754         updateNeeded = true;
5755     }
5756
5757     if (updateNeeded) {
5758         updateZ();
5759         updateGeometry();
5760         updateOpacity();
5761         updateMatrix();
5762         m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5763     }
5764
5765     emit effectChanged(component);
5766 }
5767
5768
5769 /*!
5770     \qmlproperty bool QtQuick2::Item::layer.mipmap
5771
5772     If this property is true, mipmaps are generated for the texture.
5773
5774     \note Some OpenGL ES 2 implementations do not support mipmapping of
5775     non-power-of-two textures.
5776  */
5777
5778 void QQuickItemLayer::setMipmap(bool mipmap)
5779 {
5780     if (mipmap == m_mipmap)
5781         return;
5782     m_mipmap = mipmap;
5783
5784     if (m_effectSource)
5785         m_effectSource->setMipmap(m_mipmap);
5786
5787     emit mipmapChanged(mipmap);
5788 }
5789
5790
5791 /*!
5792     \qmlproperty enumeration QtQuick2::Item::layer.format
5793
5794     This property defines the internal OpenGL format of the texture.
5795     Modifying this property makes most sense when the \a layer.effect is also
5796     specified. Depending on the OpenGL implementation, this property might
5797     allow you to save some texture memory.
5798
5799     \list
5800     \li ShaderEffectSource.Alpha - GL_ALPHA
5801     \li ShaderEffectSource.RGB - GL_RGB
5802     \li ShaderEffectSource.RGBA - GL_RGBA
5803     \endlist
5804
5805     \note Some OpenGL implementations do not support the GL_ALPHA format.
5806  */
5807
5808 void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
5809 {
5810     if (f == m_format)
5811         return;
5812     m_format = f;
5813
5814     if (m_effectSource)
5815         m_effectSource->setFormat(m_format);
5816
5817     emit formatChanged(m_format);
5818 }
5819
5820
5821 /*!
5822     \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
5823
5824     This property defines which rectangular area of the \l sourceItem to
5825     render into the texture. The source rectangle can be larger than
5826     \l sourceItem itself. If the rectangle is null, which is the default,
5827     the whole \l sourceItem is rendered to texture.
5828  */
5829
5830 void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
5831 {
5832     if (sourceRect == m_sourceRect)
5833         return;
5834     m_sourceRect = sourceRect;
5835
5836     if (m_effectSource)
5837         m_effectSource->setSourceRect(m_sourceRect);
5838
5839     emit sourceRectChanged(sourceRect);
5840 }
5841
5842
5843
5844 /*!
5845     \qmlproperty bool QtQuick2::Item::layer.smooth
5846
5847     Holds whether the layer is smoothly transformed.
5848  */
5849
5850 void QQuickItemLayer::setSmooth(bool s)
5851 {
5852     if (m_smooth == s)
5853         return;
5854     m_smooth = s;
5855
5856     if (m_effectSource)
5857         m_effectSource->setSmooth(m_smooth);
5858
5859     emit smoothChanged(s);
5860 }
5861
5862
5863
5864 /*!
5865     \qmlproperty size QtQuick2::Item::layer.textureSize
5866
5867     This property holds the requested pixel size of the layers texture. If it is empty,
5868     which is the default, the size of the item is used.
5869
5870     \note Some platforms have a limit on how small framebuffer objects can be,
5871     which means the actual texture size might be larger than the requested
5872     size.
5873  */
5874
5875 void QQuickItemLayer::setSize(const QSize &size)
5876 {
5877     if (size == m_size)
5878         return;
5879     m_size = size;
5880
5881     if (m_effectSource)
5882         m_effectSource->setTextureSize(size);
5883
5884     emit sizeChanged(size);
5885 }
5886
5887
5888
5889 /*!
5890     \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
5891
5892     This property defines the OpenGL wrap modes associated with the texture.
5893     Modifying this property makes most sense when the \a layer.effect is
5894     specified.
5895
5896     \list
5897     \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
5898     \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
5899     \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
5900     \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
5901     \endlist
5902
5903     \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
5904     wrap mode with non-power-of-two textures.
5905  */
5906
5907 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
5908 {
5909     if (mode == m_wrapMode)
5910         return;
5911     m_wrapMode = mode;
5912
5913     if (m_effectSource)
5914         m_effectSource->setWrapMode(m_wrapMode);
5915
5916     emit wrapModeChanged(mode);
5917 }
5918
5919 /*!
5920     \qmlproperty string QtQuick2::Item::layer.samplerName
5921
5922     Holds the name of the effect's source texture property.
5923
5924     samplerName needs to match the name of the effect's source texture property
5925     so that the Item can pass the layer's offscreen surface to the effect correctly.
5926
5927     \sa effect, ShaderEffect
5928  */
5929
5930 void QQuickItemLayer::setName(const QByteArray &name) {
5931     if (m_name == name)
5932         return;
5933     if (m_effect) {
5934         m_effect->setProperty(m_name, QVariant());
5935         m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
5936     }
5937     m_name = name;
5938     emit nameChanged(name);
5939 }
5940
5941 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
5942 {
5943     Q_UNUSED(item)
5944     updateOpacity();
5945 }
5946
5947 void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
5948 {
5949     updateGeometry();
5950 }
5951
5952 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
5953 {
5954     Q_UNUSED(item)
5955     Q_ASSERT(item == m_item);
5956     Q_ASSERT(parent != m_effectSource);
5957     Q_ASSERT(parent == 0 || parent != m_effect);
5958
5959     m_effectSource->setParentItem(parent);
5960     if (parent)
5961         m_effectSource->stackAfter(m_item);
5962
5963     if (m_effect) {
5964         m_effect->setParentItem(parent);
5965         if (parent)
5966             m_effect->stackAfter(m_effectSource);
5967     }
5968 }
5969
5970 void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
5971 {
5972     m_effectSource->stackAfter(m_item);
5973     if (m_effect)
5974         m_effect->stackAfter(m_effectSource);
5975 }
5976
5977 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
5978 {
5979     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5980     Q_ASSERT(l);
5981     l->setVisible(m_item->isVisible());
5982 }
5983
5984 void QQuickItemLayer::updateZ()
5985 {
5986     if (!m_componentComplete || !m_enabled)
5987         return;
5988     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5989     Q_ASSERT(l);
5990     l->setZ(m_item->z());
5991 }
5992
5993 void QQuickItemLayer::updateOpacity()
5994 {
5995     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5996     Q_ASSERT(l);
5997     l->setOpacity(m_item->opacity());
5998 }
5999
6000 void QQuickItemLayer::updateGeometry()
6001 {
6002     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6003     Q_ASSERT(l);
6004     QRectF bounds = m_item->boundingRect();
6005     l->setWidth(bounds.width());
6006     l->setHeight(bounds.height());
6007     l->setX(bounds.x() + m_item->x());
6008     l->setY(bounds.y() + m_item->y());
6009 }
6010
6011 void QQuickItemLayer::updateMatrix()
6012 {
6013     // Called directly from transformChanged(), so needs some extra
6014     // checks.
6015     if (!m_componentComplete || !m_enabled)
6016         return;
6017     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6018     Q_ASSERT(l);
6019     QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
6020     l->setScale(m_item->scale());
6021     l->setRotation(m_item->rotation());
6022     ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
6023     if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
6024         ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
6025     ld->dirty(QQuickItemPrivate::Transform);
6026 }
6027
6028 QQuickItemPrivate::ExtraData::ExtraData()
6029 : z(0), scale(1), rotation(0), opacity(1),
6030   contents(0), screenAttached(0), layoutDirectionAttached(0),
6031   keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
6032   opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
6033   acceptedMouseButtons(0), origin(QQuickItem::Center)
6034 {
6035 }
6036
6037 QT_END_NAMESPACE
6038
6039 #include <moc_qquickitem.cpp>