d2a8ada14a27e012fc6037e69b7139467f08df89
[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         if (item->canvas() && item->canvas()->rootItem() == item)
1637             break; // don't add a listener to the canvas root item
1638
1639         item->d_func()->isAccessible = true;
1640         item = item->d_func()->parentItem;
1641     }
1642 }
1643
1644 void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
1645 {
1646     Q_Q(QQuickItem);
1647     Q_ASSERT(scope);
1648
1649     QQuickItemPrivate *scopePrivate = QQuickItemPrivate::get(scope);
1650
1651     QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
1652     // Correct focus chain in scope
1653     if (oldSubFocusItem) {
1654         QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1655         while (sfi && sfi != scope) {
1656             QQuickItemPrivate::get(sfi)->subFocusItem = 0;
1657             sfi = sfi->parentItem();
1658         }
1659     }
1660
1661     if (focus) {
1662         scopePrivate->subFocusItem = q;
1663         QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1664         while (sfi && sfi != scope) {
1665             QQuickItemPrivate::get(sfi)->subFocusItem = q;
1666             sfi = sfi->parentItem();
1667         }
1668     } else {
1669         scopePrivate->subFocusItem = 0;
1670     }
1671 }
1672
1673
1674 /*!
1675     \class QQuickItem
1676     \brief The QQuickItem class provides the most basic of all visual items in QML.
1677
1678     \inmodule QtQuick
1679
1680     All visual items in Qt Quick inherit from QQuickItem.  Although QQuickItem
1681     has no visual appearance, it defines all the properties that are
1682     common across visual items - such as the x and y position, the
1683     width and height, \l {anchor-layout}{anchoring} and key handling.
1684
1685     You can subclass QQuickItem to provide your own custom visual item that inherits
1686     these features. Note that, because it does not draw anything, QQuickItem sets the
1687     QGraphicsItem::ItemHasNoContents flag. If you subclass QQuickItem to create a visual
1688     item, you will need to unset this flag.
1689
1690 */
1691
1692 /*!
1693     \qmlclass Item QQuickItem
1694     \inherits QtObject
1695     \inqmlmodule QtQuick 2
1696     \ingroup qml-basic-visual-elements
1697     \brief The Item is the most basic of all visual items in QML.
1698
1699     All visual items in Qt Quick inherit from Item.  Although Item
1700     has no visual appearance, it defines all the properties that are
1701     common across visual items - such as the x and y position, the
1702     width and height, \l {anchor-layout}{anchoring} and key handling.
1703
1704     Item is also useful for grouping items together.
1705
1706     \qml
1707     Item {
1708         Image {
1709             source: "tile.png"
1710         }
1711         Image {
1712             x: 80
1713             width: 100
1714             height: 100
1715             source: "tile.png"
1716         }
1717         Image {
1718             x: 190
1719             width: 100
1720             height: 100
1721             fillMode: Image.Tile
1722             source: "tile.png"
1723         }
1724     }
1725     \endqml
1726
1727
1728     \section1 Key Handling
1729
1730     Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1731     attached property.  The \e Keys attached property provides basic handlers such
1732     as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1733     as well as handlers for specific keys, such as
1734     \l {Keys::onCancelPressed}{onCancelPressed}.  The example below
1735     assigns \l {qmlfocus}{focus} to the item and handles
1736     the Left key via the general \e onPressed handler and the Select key via the
1737     onSelectPressed handler:
1738
1739     \qml
1740     Item {
1741         focus: true
1742         Keys.onPressed: {
1743             if (event.key == Qt.Key_Left) {
1744                 console.log("move left");
1745                 event.accepted = true;
1746             }
1747         }
1748         Keys.onSelectPressed: console.log("Selected");
1749     }
1750     \endqml
1751
1752     See the \l {Keys}{Keys} attached property for detailed documentation.
1753
1754     \section1 Layout Mirroring
1755
1756     Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1757
1758 */
1759
1760 /*!
1761     \fn void QQuickItem::childrenRectChanged(const QRectF &)
1762     \internal
1763 */
1764
1765 /*!
1766     \fn void QQuickItem::baselineOffsetChanged(qreal)
1767     \internal
1768 */
1769
1770 /*!
1771     \fn void QQuickItem::stateChanged(const QString &state)
1772     \internal
1773 */
1774
1775 /*!
1776     \fn void QQuickItem::parentChanged(QQuickItem *)
1777     \internal
1778 */
1779
1780 /*!
1781     \fn void QQuickItem::smoothChanged(bool)
1782     \internal
1783 */
1784
1785 /*!
1786     \fn void QQuickItem::clipChanged(bool)
1787     \internal
1788 */
1789
1790 /*! \fn void QQuickItem::transformOriginChanged(TransformOrigin)
1791   \internal
1792 */
1793
1794 /*!
1795     \fn void QQuickItem::focusChanged(bool)
1796     \internal
1797 */
1798
1799 /*!
1800     \fn void QQuickItem::activeFocusChanged(bool)
1801     \internal
1802 */
1803 /*!
1804     \fn QQuickItem::QQuickItem(QQuickItem *parent)
1805
1806     Constructs a QQuickItem with the given \a parent.
1807 */
1808 QQuickItem::QQuickItem(QQuickItem* parent)
1809 : QObject(*(new QQuickItemPrivate), parent)
1810 {
1811     Q_D(QQuickItem);
1812     d->init(parent);
1813 }
1814
1815 /*! \internal
1816 */
1817 QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
1818 : QObject(dd, parent)
1819 {
1820     Q_D(QQuickItem);
1821     d->init(parent);
1822 }
1823
1824 #ifndef QT_NO_DEBUG
1825 static int qt_item_count = 0;
1826
1827 static void qt_print_item_count()
1828 {
1829     qDebug("Number of leaked items: %i", qt_item_count);
1830     qt_item_count = -1;
1831 }
1832 #endif
1833
1834 /*!
1835     Destroys the QQuickItem.
1836 */
1837 QQuickItem::~QQuickItem()
1838 {
1839 #ifndef QT_NO_DEBUG
1840     --qt_item_count;
1841     if (qt_item_count < 0)
1842         qDebug("Item destroyed after qt_print_item_count() was called.");
1843 #endif
1844
1845     Q_D(QQuickItem);
1846
1847     if (d->canvasRefCount > 1)
1848         d->canvasRefCount = 1; // Make sure canvas is set to null in next call to derefCanvas().
1849     if (d->parentItem)
1850         setParentItem(0);
1851     else if (d->canvas)
1852         d->derefCanvas();
1853
1854     // XXX todo - optimize
1855     while (!d->childItems.isEmpty())
1856         d->childItems.first()->setParentItem(0);
1857
1858     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1859         QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1860         if (anchor)
1861             anchor->clearItem(this);
1862     }
1863
1864     /*
1865         update item anchors that depended on us unless they are our child (and will also be destroyed),
1866         or our sibling, and our parent is also being destroyed.
1867     */
1868     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1869         QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1870         if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
1871             anchor->update();
1872     }
1873
1874     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1875         const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1876         if (change.types & QQuickItemPrivate::Destroyed)
1877             change.listener->itemDestroyed(this);
1878     }
1879
1880     d->changeListeners.clear();
1881
1882     if (d->extra.isAllocated()) {
1883         delete d->extra->contents; d->extra->contents = 0;
1884         delete d->extra->layer; d->extra->layer = 0;
1885     }
1886
1887     delete d->_anchors; d->_anchors = 0;
1888     delete d->_stateGroup; d->_stateGroup = 0;
1889 }
1890
1891 /*!
1892     \qmlproperty enumeration QtQuick2::Item::transformOrigin
1893     This property holds the origin point around which scale and rotation transform.
1894
1895     Nine transform origins are available, as shown in the image below.
1896
1897     \image declarative-transformorigin.png
1898
1899     This example rotates an image around its bottom-right corner.
1900     \qml
1901     Image {
1902         source: "myimage.png"
1903         transformOrigin: Item.BottomRight
1904         rotation: 45
1905     }
1906     \endqml
1907
1908     The default transform origin is \c Item.Center.
1909
1910     To set an arbitrary transform origin point use the \l Scale or \l Rotation
1911     transform elements.
1912 */
1913
1914 /*!
1915     \qmlproperty Item QtQuick2::Item::parent
1916     This property holds the parent of the item.
1917 */
1918
1919 /*!
1920     \property QQuickItem::parent
1921     This property holds the parent of the item.
1922 */
1923 void QQuickItem::setParentItem(QQuickItem *parentItem)
1924 {
1925     Q_D(QQuickItem);
1926     if (parentItem == d->parentItem)
1927         return;
1928
1929     if (parentItem) {
1930         QQuickItem *itemAncestor = parentItem->parentItem();
1931         while (itemAncestor != 0) {
1932             if (itemAncestor == this) {
1933                 qWarning("QQuickItem::setParentItem: Parent is already part of this items subtree.");
1934                 return;
1935             }
1936             itemAncestor = itemAncestor->parentItem();
1937         }
1938     }
1939
1940     d->removeFromDirtyList();
1941
1942     QQuickItem *oldParentItem = d->parentItem;
1943     QQuickItem *scopeFocusedItem = 0;
1944
1945     if (oldParentItem) {
1946         QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem);
1947
1948         QQuickItem *scopeItem = 0;
1949
1950         if (hasFocus())
1951             scopeFocusedItem = this;
1952         else if (!isFocusScope() && d->subFocusItem)
1953             scopeFocusedItem = d->subFocusItem;
1954
1955         if (scopeFocusedItem) {
1956             scopeItem = oldParentItem;
1957             while (!scopeItem->isFocusScope() && scopeItem->parentItem())
1958                 scopeItem = scopeItem->parentItem();
1959             if (d->canvas) {
1960                 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1961                                                                 QQuickCanvasPrivate::DontChangeFocusProperty);
1962                 if (scopeFocusedItem != this)
1963                     QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, true);
1964             } else {
1965                 QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, false);
1966             }
1967         }
1968
1969         const bool wasVisible = isVisible();
1970         op->removeChild(this);
1971         if (wasVisible) {
1972             emit oldParentItem->visibleChildrenChanged();
1973         }
1974     } else if (d->canvas) {
1975         QQuickCanvasPrivate::get(d->canvas)->parentlessItems.remove(this);
1976     }
1977
1978     QQuickCanvas *oldParentCanvas = oldParentItem ? QQuickItemPrivate::get(oldParentItem)->canvas : 0;
1979     QQuickCanvas *parentCanvas = parentItem ? QQuickItemPrivate::get(parentItem)->canvas : 0;
1980     if (oldParentCanvas == parentCanvas) {
1981         // Avoid freeing and reallocating resources if the canvas stays the same.
1982         d->parentItem = parentItem;
1983     } else {
1984         if (oldParentCanvas)
1985             d->derefCanvas();
1986         d->parentItem = parentItem;
1987         if (parentCanvas)
1988             d->refCanvas(parentCanvas);
1989     }
1990
1991     d->dirty(QQuickItemPrivate::ParentChanged);
1992
1993     if (d->parentItem)
1994         QQuickItemPrivate::get(d->parentItem)->addChild(this);
1995     else if (d->canvas)
1996         QQuickCanvasPrivate::get(d->canvas)->parentlessItems.insert(this);
1997
1998     d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
1999     d->setEffectiveEnableRecur(0, d->calcEffectiveEnable());
2000
2001     if (d->parentItem) {
2002         if (!scopeFocusedItem) {
2003             if (hasFocus())
2004                 scopeFocusedItem = this;
2005             else if (!isFocusScope() && d->subFocusItem)
2006                 scopeFocusedItem = d->subFocusItem;
2007         }
2008
2009         if (scopeFocusedItem) {
2010             // We need to test whether this item becomes scope focused
2011             QQuickItem *scopeItem = d->parentItem;
2012             while (!scopeItem->isFocusScope() && scopeItem->parentItem())
2013                 scopeItem = scopeItem->parentItem();
2014
2015             if (QQuickItemPrivate::get(scopeItem)->subFocusItem
2016                     || (!scopeItem->isFocusScope() && scopeItem->hasFocus())) {
2017                 if (scopeFocusedItem != this)
2018                     QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, false);
2019                 QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
2020                 emit scopeFocusedItem->focusChanged(false);
2021             } else {
2022                 if (d->canvas) {
2023                     QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
2024                                                                   QQuickCanvasPrivate::DontChangeFocusProperty);
2025                 } else {
2026                     QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, true);
2027                 }
2028             }
2029         }
2030     }
2031
2032     d->resolveLayoutMirror();
2033
2034     d->itemChange(ItemParentHasChanged, d->parentItem);
2035
2036     d->parentNotifier.notify();
2037     if (d->isAccessible && d->parentItem) {
2038         d->parentItem->d_func()->setAccessibleFlagAndListener();
2039     }
2040
2041     emit parentChanged(d->parentItem);
2042     if (isVisible() && d->parentItem)
2043         emit d->parentItem->visibleChildrenChanged();
2044 }
2045
2046 void QQuickItem::stackBefore(const QQuickItem *sibling)
2047 {
2048     Q_D(QQuickItem);
2049     if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2050         qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
2051         return;
2052     }
2053
2054     QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2055
2056     int myIndex = parentPrivate->childItems.indexOf(this);
2057     int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2058
2059     Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2060
2061     if (myIndex == siblingIndex - 1)
2062         return;
2063
2064     parentPrivate->childItems.removeAt(myIndex);
2065
2066     if (myIndex < siblingIndex) --siblingIndex;
2067
2068     parentPrivate->childItems.insert(siblingIndex, this);
2069
2070     parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2071     parentPrivate->markSortedChildrenDirty(this);
2072
2073     for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
2074         QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2075 }
2076
2077 void QQuickItem::stackAfter(const QQuickItem *sibling)
2078 {
2079     Q_D(QQuickItem);
2080     if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
2081         qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
2082         return;
2083     }
2084
2085     QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
2086
2087     int myIndex = parentPrivate->childItems.indexOf(this);
2088     int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
2089
2090     Q_ASSERT(myIndex != -1 && siblingIndex != -1);
2091
2092     if (myIndex == siblingIndex + 1)
2093         return;
2094
2095     parentPrivate->childItems.removeAt(myIndex);
2096
2097     if (myIndex < siblingIndex) --siblingIndex;
2098
2099     parentPrivate->childItems.insert(siblingIndex + 1, this);
2100
2101     parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
2102     parentPrivate->markSortedChildrenDirty(this);
2103
2104     for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
2105         QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2106 }
2107
2108 /*!
2109     Returns the QQuickItem parent of this item.
2110 */
2111 QQuickItem *QQuickItem::parentItem() const
2112 {
2113     Q_D(const QQuickItem);
2114     return d->parentItem;
2115 }
2116
2117 QSGEngine *QQuickItem::sceneGraphEngine() const
2118 {
2119     return canvas()->sceneGraphEngine();
2120 }
2121
2122 QQuickCanvas *QQuickItem::canvas() const
2123 {
2124     Q_D(const QQuickItem);
2125     return d->canvas;
2126 }
2127
2128 static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
2129 {
2130     return lhs->z() < rhs->z();
2131 }
2132
2133 QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
2134 {
2135     if (sortedChildItems)
2136         return *sortedChildItems;
2137
2138     // If none of the items have set Z then the paint order list is the same as
2139     // the childItems list.  This is by far the most common case.
2140     bool haveZ = false;
2141     for (int i = 0; i < childItems.count(); ++i) {
2142         if (QQuickItemPrivate::get(childItems.at(i))->z() != 0.) {
2143             haveZ = true;
2144             break;
2145         }
2146     }
2147     if (haveZ) {
2148         sortedChildItems = new QList<QQuickItem*>(childItems);
2149         qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
2150         return *sortedChildItems;
2151     }
2152
2153     sortedChildItems = const_cast<QList<QQuickItem*>*>(&childItems);
2154
2155     return childItems;
2156 }
2157
2158 void QQuickItemPrivate::addChild(QQuickItem *child)
2159 {
2160     Q_Q(QQuickItem);
2161
2162     Q_ASSERT(!childItems.contains(child));
2163
2164     childItems.append(child);
2165
2166     markSortedChildrenDirty(child);
2167     dirty(QQuickItemPrivate::ChildrenChanged);
2168
2169     itemChange(QQuickItem::ItemChildAddedChange, child);
2170
2171     emit q->childrenChanged();
2172 }
2173
2174 void QQuickItemPrivate::removeChild(QQuickItem *child)
2175 {
2176     Q_Q(QQuickItem);
2177
2178     Q_ASSERT(child);
2179     Q_ASSERT(childItems.contains(child));
2180     childItems.removeOne(child);
2181     Q_ASSERT(!childItems.contains(child));
2182
2183     markSortedChildrenDirty(child);
2184     dirty(QQuickItemPrivate::ChildrenChanged);
2185
2186     itemChange(QQuickItem::ItemChildRemovedChange, child);
2187
2188     emit q->childrenChanged();
2189 }
2190
2191 void QQuickItemPrivate::InitializationState::clear()
2192 {
2193     focusScope = 0;
2194 }
2195
2196 void QQuickItemPrivate::InitializationState::clear(QQuickItem *fs)
2197 {
2198     focusScope = fs;
2199 }
2200
2201 QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *item)
2202 {
2203     if (!focusScope) {
2204         QQuickItem *fs = item->parentItem();
2205         while (fs->parentItem() && !fs->isFocusScope())
2206             fs = fs->parentItem();
2207         focusScope = fs;
2208     }
2209     return focusScope;
2210 }
2211
2212 void QQuickItemPrivate::refCanvas(InitializationState *state, QQuickCanvas *c)
2213 {
2214     // An item needs a canvas if it is referenced by another item which has a canvas.
2215     // Typically the item is referenced by a parent, but can also be referenced by a
2216     // ShaderEffect or ShaderEffectSource. 'canvasRefCount' counts how many items with
2217     // a canvas is referencing this item. When the reference count goes from zero to one,
2218     // or one to zero, the canvas of this item is updated and propagated to the children.
2219     // As long as the reference count stays above zero, the canvas is unchanged.
2220     // refCanvas() increments the reference count.
2221     // derefCanvas() decrements the reference count.
2222
2223     Q_Q(QQuickItem);
2224     Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2225     Q_ASSERT(c);
2226     if (++canvasRefCount > 1) {
2227         if (c != canvas)
2228             qWarning("QQuickItem: Cannot use same item on different canvases at the same time.");
2229         return; // Canvas already set.
2230     }
2231
2232     Q_ASSERT(canvas == 0);
2233     canvas = c;
2234
2235     if (polishScheduled)
2236         QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2237
2238     InitializationState _dummy;
2239     InitializationState *childState = state;
2240
2241     if (q->isFocusScope()) {
2242         _dummy.clear(q);
2243         childState = &_dummy;
2244     }
2245
2246     if (!parentItem)
2247         QQuickCanvasPrivate::get(canvas)->parentlessItems.insert(q);
2248
2249     for (int ii = 0; ii < childItems.count(); ++ii) {
2250         QQuickItem *child = childItems.at(ii);
2251         QQuickItemPrivate::get(child)->refCanvas(childState, c);
2252     }
2253
2254     dirty(Canvas);
2255
2256     if (extra.isAllocated() && extra->screenAttached)
2257         extra->screenAttached->canvasChanged(c);
2258     itemChange(QQuickItem::ItemSceneChange, c);
2259 }
2260
2261 void QQuickItemPrivate::derefCanvas()
2262 {
2263     Q_Q(QQuickItem);
2264     Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
2265
2266     if (!canvas)
2267         return; // This can happen when destroying recursive shader effect sources.
2268
2269     if (--canvasRefCount > 0)
2270         return; // There are still other references, so don't set canvas to null yet.
2271
2272     q->releaseResources();
2273     removeFromDirtyList();
2274     QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
2275     if (polishScheduled)
2276         c->itemsToPolish.remove(q);
2277     if (c->mouseGrabberItem == q)
2278         c->mouseGrabberItem = 0;
2279     if ( hoverEnabled )
2280         c->hoverItems.removeAll(q);
2281     if (itemNodeInstance)
2282         c->cleanup(itemNodeInstance);
2283     if (!parentItem)
2284         c->parentlessItems.remove(q);
2285
2286     canvas = 0;
2287
2288     itemNodeInstance = 0;
2289
2290     if (extra.isAllocated()) {
2291         extra->opacityNode = 0;
2292         extra->clipNode = 0;
2293         extra->rootNode = 0;
2294         extra->beforePaintNode = 0;
2295     }
2296
2297     groupNode = 0;
2298     paintNode = 0;
2299
2300     for (int ii = 0; ii < childItems.count(); ++ii) {
2301         QQuickItem *child = childItems.at(ii);
2302         QQuickItemPrivate::get(child)->derefCanvas();
2303     }
2304
2305     dirty(Canvas);
2306
2307     if (extra.isAllocated() && extra->screenAttached)
2308         extra->screenAttached->canvasChanged(0);
2309     itemChange(QQuickItem::ItemSceneChange, (QQuickCanvas *)0);
2310 }
2311
2312
2313 /*!
2314 Returns a transform that maps points from canvas space into item space.
2315 */
2316 QTransform QQuickItemPrivate::canvasToItemTransform() const
2317 {
2318     // XXX todo - optimize
2319     return itemToCanvasTransform().inverted();
2320 }
2321
2322 /*!
2323 Returns a transform that maps points from item space into canvas space.
2324 */
2325 QTransform QQuickItemPrivate::itemToCanvasTransform() const
2326 {
2327     // XXX todo
2328     QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2329     itemToParentTransform(rv);
2330     return rv;
2331 }
2332
2333 /*!
2334 Motifies \a t with this items local transform relative to its parent.
2335 */
2336 void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
2337 {
2338     if (x || y)
2339         t.translate(x, y);
2340
2341     if (!transforms.isEmpty()) {
2342         QMatrix4x4 m(t);
2343         for (int ii = transforms.count() - 1; ii >= 0; --ii)
2344             transforms.at(ii)->applyTo(&m);
2345         t = m.toTransform();
2346     }
2347
2348     if (scale() != 1. || rotation() != 0.) {
2349         QPointF tp = computeTransformOrigin();
2350         t.translate(tp.x(), tp.y());
2351         t.scale(scale(), scale());
2352         t.rotate(rotation());
2353         t.translate(-tp.x(), -tp.y());
2354     }
2355 }
2356
2357
2358 /*!
2359     \qmlproperty real QtQuick2::Item::childrenRect.x
2360     \qmlproperty real QtQuick2::Item::childrenRect.y
2361     \qmlproperty real QtQuick2::Item::childrenRect.width
2362     \qmlproperty real QtQuick2::Item::childrenRect.height
2363
2364     The childrenRect properties allow an item access to the geometry of its
2365     children. This property is useful if you have an item that needs to be
2366     sized to fit its children.
2367 */
2368
2369
2370 /*!
2371     \qmlproperty list<Item> QtQuick2::Item::children
2372     \qmlproperty list<Object> QtQuick2::Item::resources
2373
2374     The children property contains the list of visual children of this item.
2375     The resources property contains non-visual resources that you want to
2376     reference by name.
2377
2378     Generally you can rely on Item's default property to handle all this for
2379     you, but it can come in handy in some cases.
2380
2381     \qml
2382     Item {
2383         children: [
2384             Text {},
2385             Rectangle {}
2386         ]
2387         resources: [
2388             Component {
2389                 id: myComponent
2390                 Text {}
2391             }
2392         ]
2393     }
2394     \endqml
2395 */
2396
2397 /*!
2398     Returns true if construction of the QML component is complete; otherwise
2399     returns false.
2400
2401     It is often desirable to delay some processing until the component is
2402     completed.
2403
2404     \sa componentComplete()
2405 */
2406 bool QQuickItem::isComponentComplete() const
2407 {
2408     Q_D(const QQuickItem);
2409     return d->componentComplete;
2410 }
2411
2412 QQuickItemPrivate::QQuickItemPrivate()
2413 : _anchors(0), _stateGroup(0),
2414   flags(0), widthValid(false), heightValid(false), baselineOffsetValid(false), componentComplete(true),
2415   keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(true), focus(false), activeFocus(false), notifiedFocus(false),
2416   notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2417   effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2418   inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2419   inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
2420   staticSubtreeGeometry(false),
2421   isAccessible(false),
2422
2423   dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2424
2425   canvas(0), canvasRefCount(0), parentItem(0), sortedChildItems(&childItems),
2426
2427   subFocusItem(0),
2428
2429   x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2430
2431   baselineOffset(0),
2432
2433   itemNodeInstance(0), groupNode(0), paintNode(0)
2434 {
2435 }
2436
2437 QQuickItemPrivate::~QQuickItemPrivate()
2438 {
2439     if (sortedChildItems != &childItems)
2440         delete sortedChildItems;
2441 }
2442
2443 void QQuickItemPrivate::init(QQuickItem *parent)
2444 {
2445 #ifndef QT_NO_DEBUG
2446     ++qt_item_count;
2447     static bool atexit_registered = false;
2448     if (!atexit_registered) {
2449         atexit(qt_print_item_count);
2450         atexit_registered = true;
2451     }
2452 #endif
2453
2454     Q_Q(QQuickItem);
2455
2456     registerAccessorProperties();
2457
2458     baselineOffsetValid = false;
2459
2460     if (parent) {
2461         q->setParentItem(parent);
2462         QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
2463         setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2464     }
2465 }
2466
2467 void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
2468 {
2469     if (!o)
2470         return;
2471
2472     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2473
2474     // This test is measurably (albeit only slightly) faster than qobject_cast<>()
2475     const QMetaObject *mo = o->metaObject();
2476     while (mo && mo != &QQuickItem::staticMetaObject) {
2477         mo = mo->d.superdata;
2478     }
2479
2480     if (mo) {
2481         QQuickItem *item = static_cast<QQuickItem *>(o);
2482         item->setParentItem(that);
2483     } else {
2484         if (o->inherits("QGraphicsItem"))
2485             qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2486
2487         // XXX todo - do we really want this behavior?
2488         o->setParent(that);
2489     }
2490 }
2491
2492 /*!
2493     \qmlproperty list<Object> QtQuick2::Item::data
2494     \default
2495
2496     The data property allows you to freely mix visual children and resources
2497     in an item.  If you assign a visual item to the data list it becomes
2498     a child and if you assign any other object type, it is added as a resource.
2499
2500     So you can write:
2501     \qml
2502     Item {
2503         Text {}
2504         Rectangle {}
2505         Timer {}
2506     }
2507     \endqml
2508
2509     instead of:
2510     \qml
2511     Item {
2512         children: [
2513             Text {},
2514             Rectangle {}
2515         ]
2516         resources: [
2517             Timer {}
2518         ]
2519     }
2520     \endqml
2521
2522     data is a behind-the-scenes property: you should never need to explicitly
2523     specify it.
2524  */
2525
2526 int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *prop)
2527 {
2528     Q_UNUSED(prop);
2529     // XXX todo
2530     return 0;
2531 }
2532
2533 QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *prop, int i)
2534 {
2535     Q_UNUSED(prop);
2536     Q_UNUSED(i);
2537     // XXX todo
2538     return 0;
2539 }
2540
2541 void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *prop)
2542 {
2543     Q_UNUSED(prop);
2544     // XXX todo
2545 }
2546
2547 QObject *QQuickItemPrivate::resources_at(QQmlListProperty<QObject> *prop, int index)
2548 {
2549     const QObjectList children = prop->object->children();
2550     if (index < children.count())
2551         return children.at(index);
2552     else
2553         return 0;
2554 }
2555
2556 void QQuickItemPrivate::resources_append(QQmlListProperty<QObject> *prop, QObject *o)
2557 {
2558     // XXX todo - do we really want this behavior?
2559     o->setParent(prop->object);
2560 }
2561
2562 int QQuickItemPrivate::resources_count(QQmlListProperty<QObject> *prop)
2563 {
2564     return prop->object->children().count();
2565 }
2566
2567 void QQuickItemPrivate::resources_clear(QQmlListProperty<QObject> *prop)
2568 {
2569     // XXX todo - do we really want this behavior?
2570     const QObjectList children = prop->object->children();
2571     for (int index = 0; index < children.count(); index++)
2572         children.at(index)->setParent(0);
2573 }
2574
2575 QQuickItem *QQuickItemPrivate::children_at(QQmlListProperty<QQuickItem> *prop, int index)
2576 {
2577     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2578     if (index >= p->childItems.count() || index < 0)
2579         return 0;
2580     else
2581         return p->childItems.at(index);
2582 }
2583
2584 void QQuickItemPrivate::children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *o)
2585 {
2586     if (!o)
2587         return;
2588
2589     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2590     if (o->parentItem() == that)
2591         o->setParentItem(0);
2592
2593     o->setParentItem(that);
2594 }
2595
2596 int QQuickItemPrivate::children_count(QQmlListProperty<QQuickItem> *prop)
2597 {
2598     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2599     return p->childItems.count();
2600 }
2601
2602 void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop)
2603 {
2604     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2605     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2606     while (!p->childItems.isEmpty())
2607         p->childItems.at(0)->setParentItem(0);
2608 }
2609
2610 void QQuickItemPrivate::visibleChildren_append(QQmlListProperty<QQuickItem>*, QQuickItem *self)
2611 {
2612     // do nothing
2613     qmlInfo(self) << "QQuickItem: visibleChildren property is readonly and cannot be assigned to.";
2614 }
2615
2616 int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop)
2617 {
2618     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2619     int visibleCount = 0;
2620     int c = p->childItems.count();
2621     while (c--) {
2622         if (p->childItems.at(c)->isVisible()) visibleCount++;
2623     }
2624
2625     return visibleCount;
2626 }
2627
2628 QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index)
2629 {
2630     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2631     const int childCount = p->childItems.count();
2632     if (index >= childCount || index < 0)
2633         return 0;
2634
2635     int visibleCount = -1;
2636     for (int i = 0; i < childCount; i++) {
2637         if (p->childItems.at(i)->isVisible()) visibleCount++;
2638         if (visibleCount == index) return p->childItems.at(i);
2639     }
2640     return 0;
2641 }
2642
2643 int QQuickItemPrivate::transform_count(QQmlListProperty<QQuickTransform> *prop)
2644 {
2645     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2646     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2647
2648     return p->transforms.count();
2649 }
2650
2651 void QQuickTransform::appendToItem(QQuickItem *item)
2652 {
2653     Q_D(QQuickTransform);
2654     if (!item)
2655         return;
2656
2657     QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2658
2659     if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2660         p->transforms.removeOne(this);
2661         p->transforms.append(this);
2662     } else {
2663         p->transforms.append(this);
2664         d->items.append(item);
2665     }
2666
2667     p->dirty(QQuickItemPrivate::Transform);
2668 }
2669
2670 void QQuickTransform::prependToItem(QQuickItem *item)
2671 {
2672     Q_D(QQuickTransform);
2673     if (!item)
2674         return;
2675
2676     QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2677
2678     if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2679         p->transforms.removeOne(this);
2680         p->transforms.prepend(this);
2681     } else {
2682         p->transforms.prepend(this);
2683         d->items.append(item);
2684     }
2685
2686     p->dirty(QQuickItemPrivate::Transform);
2687 }
2688
2689 void QQuickItemPrivate::transform_append(QQmlListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2690 {
2691     if (!transform)
2692         return;
2693
2694     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2695     transform->appendToItem(that);
2696 }
2697
2698 QQuickTransform *QQuickItemPrivate::transform_at(QQmlListProperty<QQuickTransform> *prop, int idx)
2699 {
2700     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2701     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2702
2703     if (idx < 0 || idx >= p->transforms.count())
2704         return 0;
2705     else
2706         return p->transforms.at(idx);
2707 }
2708
2709 void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
2710 {
2711     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2712     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2713
2714     for (int ii = 0; ii < p->transforms.count(); ++ii) {
2715         QQuickTransform *t = p->transforms.at(ii);
2716         QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2717         tp->items.removeOne(that);
2718     }
2719
2720     p->transforms.clear();
2721
2722     p->dirty(QQuickItemPrivate::Transform);
2723 }
2724
2725 /*!
2726     \property QQuickItem::childrenRect
2727     \brief The geometry of an item's children.
2728
2729     This property holds the (collective) position and size of the item's children.
2730 */
2731
2732 /*!
2733   \qmlproperty real QtQuick2::Item::x
2734   \qmlproperty real QtQuick2::Item::y
2735   \qmlproperty real QtQuick2::Item::width
2736   \qmlproperty real QtQuick2::Item::height
2737
2738   Defines the item's position and size relative to its parent.
2739
2740   \qml
2741   Item { x: 100; y: 100; width: 100; height: 100 }
2742   \endqml
2743  */
2744
2745 /*!
2746   \qmlproperty real QtQuick2::Item::z
2747
2748   Sets the stacking order of sibling items.  By default the stacking order is 0.
2749
2750   Items with a higher stacking value are drawn on top of siblings with a
2751   lower stacking order.  Items with the same stacking value are drawn
2752   bottom up in the order they appear.  Items with a negative stacking
2753   value are drawn under their parent's content.
2754
2755   The following example shows the various effects of stacking order.
2756
2757   \table
2758   \row
2759   \li \image declarative-item_stacking1.png
2760   \li Same \c z - later children above earlier children:
2761   \qml
2762   Item {
2763       Rectangle {
2764           color: "red"
2765           width: 100; height: 100
2766       }
2767       Rectangle {
2768           color: "blue"
2769           x: 50; y: 50; width: 100; height: 100
2770       }
2771   }
2772   \endqml
2773   \row
2774   \li \image declarative-item_stacking2.png
2775   \li Higher \c z on top:
2776   \qml
2777   Item {
2778       Rectangle {
2779           z: 1
2780           color: "red"
2781           width: 100; height: 100
2782       }
2783       Rectangle {
2784           color: "blue"
2785           x: 50; y: 50; width: 100; height: 100
2786       }
2787   }
2788   \endqml
2789   \row
2790   \li \image declarative-item_stacking3.png
2791   \li Same \c z - children above parents:
2792   \qml
2793   Item {
2794       Rectangle {
2795           color: "red"
2796           width: 100; height: 100
2797           Rectangle {
2798               color: "blue"
2799               x: 50; y: 50; width: 100; height: 100
2800           }
2801       }
2802   }
2803   \endqml
2804   \row
2805   \li \image declarative-item_stacking4.png
2806   \li Lower \c z below:
2807   \qml
2808   Item {
2809       Rectangle {
2810           color: "red"
2811           width: 100; height: 100
2812           Rectangle {
2813               z: -1
2814               color: "blue"
2815               x: 50; y: 50; width: 100; height: 100
2816           }
2817       }
2818   }
2819   \endqml
2820   \endtable
2821  */
2822
2823 /*!
2824     \qmlproperty bool QtQuick2::Item::visible
2825
2826     This property holds whether the item is visible. By default this is true.
2827
2828     Setting this property directly affects the \c visible value of child
2829     items. When set to \c false, the \c visible values of all child items also
2830     become \c false. When set to \c true, the \c visible values of child items
2831     are returned to \c true, unless they have explicitly been set to \c false.
2832
2833     (Because of this flow-on behavior, using the \c visible property may not
2834     have the intended effect if a property binding should only respond to
2835     explicit property changes. In such cases it may be better to use the
2836     \l opacity property instead.)
2837
2838     Setting this property to \c false automatically causes \l focus to be set
2839     to \c false, and this item will longer receive mouse and keyboard events.
2840     (In contrast, setting the \l opacity to 0 does not affect the \l focus
2841     property and the receiving of key events.)
2842
2843     \note This property's value is only affected by changes to this property or
2844     the parent's \c visible property. It does not change, for example, if this
2845     item moves off-screen, or if the \l opacity changes to 0.
2846 */
2847
2848
2849 /*!
2850   \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2851   \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2852   \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2853   \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2854   \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2855   \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2856   \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2857
2858   \qmlproperty Item QtQuick2::Item::anchors.fill
2859   \qmlproperty Item QtQuick2::Item::anchors.centerIn
2860
2861   \qmlproperty real QtQuick2::Item::anchors.margins
2862   \qmlproperty real QtQuick2::Item::anchors.topMargin
2863   \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2864   \qmlproperty real QtQuick2::Item::anchors.leftMargin
2865   \qmlproperty real QtQuick2::Item::anchors.rightMargin
2866   \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2867   \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2868   \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2869
2870   \qmlproperty bool QtQuick2::Item::anchors.mirrored
2871
2872   Anchors provide a way to position an item by specifying its
2873   relationship with other items.
2874
2875   Margins apply to top, bottom, left, right, and fill anchors.
2876   The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2877   Note that margins are anchor-specific and are not applied if an item does not
2878   use anchors.
2879
2880   Offsets apply for horizontal center, vertical center, and baseline anchors.
2881
2882   \table
2883   \row
2884   \li \image declarative-anchors_example.png
2885   \li Text anchored to Image, horizontally centered and vertically below, with a margin.
2886   \qml
2887   Item {
2888       Image {
2889           id: pic
2890           // ...
2891       }
2892       Text {
2893           id: label
2894           anchors.horizontalCenter: pic.horizontalCenter
2895           anchors.top: pic.bottom
2896           anchors.topMargin: 5
2897           // ...
2898       }
2899   }
2900   \endqml
2901   \row
2902   \li \image declarative-anchors_example2.png
2903   \li
2904   Left of Text anchored to right of Image, with a margin. The y
2905   property of both defaults to 0.
2906
2907   \qml
2908   Item {
2909       Image {
2910           id: pic
2911           // ...
2912       }
2913       Text {
2914           id: label
2915           anchors.left: pic.right
2916           anchors.leftMargin: 5
2917           // ...
2918       }
2919   }
2920   \endqml
2921   \endtable
2922
2923   \c anchors.fill provides a convenient way for one item to have the
2924   same geometry as another item, and is equivalent to connecting all
2925   four directional anchors.
2926
2927   To clear an anchor value, set it to \c undefined.
2928
2929   \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2930
2931   \note You can only anchor an item to siblings or a parent.
2932
2933   For more information see \l {anchor-layout}{Anchor Layouts}.
2934 */
2935
2936 /*!
2937   \property QQuickItem::baselineOffset
2938   \brief The position of the item's baseline in local coordinates.
2939
2940   The baseline of a \l Text item is the imaginary line on which the text
2941   sits. Controls containing text usually set their baseline to the
2942   baseline of their text.
2943
2944   For non-text items, a default baseline offset of 0 is used.
2945 */
2946 QQuickAnchors *QQuickItemPrivate::anchors() const
2947 {
2948     if (!_anchors) {
2949         Q_Q(const QQuickItem);
2950         _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2951         if (!componentComplete)
2952             _anchors->classBegin();
2953     }
2954     return _anchors;
2955 }
2956
2957 void QQuickItemPrivate::siblingOrderChanged()
2958 {
2959     Q_Q(QQuickItem);
2960     for (int ii = 0; ii < changeListeners.count(); ++ii) {
2961         const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2962         if (change.types & QQuickItemPrivate::SiblingOrder) {
2963             change.listener->itemSiblingOrderChanged(q);
2964         }
2965     }
2966 }
2967
2968 QQmlListProperty<QObject> QQuickItemPrivate::data()
2969 {
2970     return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
2971                                              QQuickItemPrivate::data_count,
2972                                              QQuickItemPrivate::data_at,
2973                                              QQuickItemPrivate::data_clear);
2974 }
2975
2976 QRectF QQuickItem::childrenRect()
2977 {
2978     Q_D(QQuickItem);
2979     if (!d->extra.isAllocated() || !d->extra->contents) {
2980         d->extra.value().contents = new QQuickContents(this);
2981         if (d->componentComplete)
2982             d->extra->contents->complete();
2983     }
2984     return d->extra->contents->rectF();
2985 }
2986
2987 QList<QQuickItem *> QQuickItem::childItems() const
2988 {
2989     Q_D(const QQuickItem);
2990     return d->childItems;
2991 }
2992
2993 bool QQuickItem::clip() const
2994 {
2995     return flags() & ItemClipsChildrenToShape;
2996 }
2997
2998 void QQuickItem::setClip(bool c)
2999 {
3000     if (clip() == c)
3001         return;
3002
3003     setFlag(ItemClipsChildrenToShape, c);
3004
3005     emit clipChanged(c);
3006 }
3007
3008
3009 /*!
3010   This function is called to handle this item's changes in
3011   geometry from \a oldGeometry to \a newGeometry. If the two
3012   geometries are the same, it doesn't do anything.
3013  */
3014 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
3015 {
3016     Q_D(QQuickItem);
3017
3018     if (d->_anchors)
3019         QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
3020
3021     bool xChange = (newGeometry.x() != oldGeometry.x());
3022     bool yChange = (newGeometry.y() != oldGeometry.y());
3023     bool widthChange = (newGeometry.width() != oldGeometry.width());
3024     bool heightChange = (newGeometry.height() != oldGeometry.height());
3025
3026     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3027         const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3028         if (change.types & QQuickItemPrivate::Geometry) {
3029             if (change.gTypes == QQuickItemPrivate::GeometryChange) {
3030                 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3031             } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
3032                        (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
3033                        (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
3034                        (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
3035                 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3036             }
3037         }
3038     }
3039
3040     if (xChange)
3041         emit xChanged();
3042     if (yChange)
3043         emit yChanged();
3044     if (widthChange)
3045         emit widthChanged();
3046     if (heightChange)
3047         emit heightChanged();
3048 }
3049
3050 /*!
3051     Called by the rendering thread when it is time to sync the state of the QML objects with the
3052     scene graph objects. The function should return the root of the scene graph subtree for
3053     this item. \a oldNode is the node that was returned the last time the function was called.
3054
3055     The main thread is blocked while this function is executed so it is safe to read
3056     values from the QQuickItem instance and other objects in the main thread.
3057
3058     \warning This is the only function in which it is allowed to make use of scene graph
3059     objects from the main thread. Use of scene graph objects outside this function will
3060     result in race conditions and potential crashes.
3061  */
3062
3063 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
3064 {
3065     delete oldNode;
3066     return 0;
3067 }
3068
3069 /*!
3070     This function is called when the item's scene graph resources are no longer needed.
3071     It allows items to free its resources, for instance textures, that are not owned by scene graph
3072     nodes. Note that scene graph nodes are managed by QQuickCanvas and should not be deleted by
3073     this function. Scene graph resources are no longer needed when the parent is set to null and
3074     the item is not used by any \l ShaderEffect or \l ShaderEffectSource.
3075
3076     This function is called from the main thread. Therefore, resources used by the scene graph
3077     should not be deleted directly, but by calling \l QObject::deleteLater().
3078
3079     \note The item destructor still needs to free its scene graph resources if not already done.
3080  */
3081
3082 void QQuickItem::releaseResources()
3083 {
3084 }
3085
3086 QSGTransformNode *QQuickItemPrivate::createTransformNode()
3087 {
3088     return new QSGTransformNode;
3089 }
3090
3091 void QQuickItem::updatePolish()
3092 {
3093 }
3094
3095 void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3096 {
3097     changeListeners.append(ChangeListener(listener, types));
3098 }
3099
3100 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3101 {
3102     ChangeListener change(listener, types);
3103     changeListeners.removeOne(change);
3104 }
3105
3106 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
3107 {
3108     ChangeListener change(listener, types);
3109     int index = changeListeners.find(change);
3110     if (index > -1)
3111         changeListeners[index].gTypes = change.gTypes;  //we may have different GeometryChangeTypes
3112     else
3113         changeListeners.append(change);
3114 }
3115
3116 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
3117                                                              GeometryChangeTypes types)
3118 {
3119     ChangeListener change(listener, types);
3120     if (types == NoChange) {
3121         changeListeners.removeOne(change);
3122     } else {
3123         int index = changeListeners.find(change);
3124         if (index > -1)
3125             changeListeners[index].gTypes = change.gTypes;  //we may have different GeometryChangeTypes
3126     }
3127 }
3128
3129 void QQuickItem::keyPressEvent(QKeyEvent *event)
3130 {
3131     event->ignore();
3132 }
3133
3134 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
3135 {
3136     event->ignore();
3137 }
3138
3139 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
3140 {
3141     event->ignore();
3142 }
3143
3144 void QQuickItem::focusInEvent(QFocusEvent *)
3145 {
3146 #ifndef QT_NO_ACCESSIBILITY
3147     QAccessibleEvent ev(this, QAccessible::Focus);
3148     QAccessible::updateAccessibility(&ev);
3149 #endif
3150 }
3151
3152 void QQuickItem::focusOutEvent(QFocusEvent *)
3153 {
3154 }
3155
3156 void QQuickItem::mousePressEvent(QMouseEvent *event)
3157 {
3158     event->ignore();
3159 }
3160
3161 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
3162 {
3163     event->ignore();
3164 }
3165
3166 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
3167 {
3168     event->ignore();
3169 }
3170
3171 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
3172 {
3173 }
3174
3175 void QQuickItem::mouseUngrabEvent()
3176 {
3177     // XXX todo
3178 }
3179
3180 void QQuickItem::touchUngrabEvent()
3181 {
3182     // XXX todo
3183 }
3184
3185 void QQuickItem::wheelEvent(QWheelEvent *event)
3186 {
3187     event->ignore();
3188 }
3189
3190 void QQuickItem::touchEvent(QTouchEvent *event)
3191 {
3192     event->ignore();
3193 }
3194
3195 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
3196 {
3197     Q_UNUSED(event);
3198 }
3199
3200 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
3201 {
3202     Q_UNUSED(event);
3203 }
3204
3205 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
3206 {
3207     Q_UNUSED(event);
3208 }
3209
3210 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
3211 {
3212     Q_UNUSED(event);
3213 }
3214
3215 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
3216 {
3217
3218     Q_UNUSED(event);
3219 }
3220
3221 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3222 {
3223
3224     Q_UNUSED(event);
3225 }
3226
3227 void QQuickItem::dropEvent(QDropEvent *event)
3228 {
3229     Q_UNUSED(event);
3230 }
3231
3232 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3233 {
3234     return false;
3235 }
3236
3237 void QQuickItem::windowDeactivateEvent()
3238 {
3239     foreach (QQuickItem* item, childItems()) {
3240         item->windowDeactivateEvent();
3241     }
3242 }
3243
3244 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3245 {
3246     Q_D(const QQuickItem);
3247     QVariant v;
3248
3249     switch (query) {
3250     case Qt::ImEnabled:
3251         v = (bool)(flags() & ItemAcceptsInputMethod);
3252         break;
3253     case Qt::ImHints:
3254     case Qt::ImCursorRectangle:
3255     case Qt::ImFont:
3256     case Qt::ImCursorPosition:
3257     case Qt::ImSurroundingText:
3258     case Qt::ImCurrentSelection:
3259     case Qt::ImMaximumTextLength:
3260     case Qt::ImAnchorPosition:
3261     case Qt::ImPreferredLanguage:
3262         if (d->extra.isAllocated() && d->extra->keyHandler)
3263             v = d->extra->keyHandler->inputMethodQuery(query);
3264     default:
3265         break;
3266     }
3267
3268     return v;
3269 }
3270
3271 QQuickAnchorLine QQuickItemPrivate::left() const
3272 {
3273     Q_Q(const QQuickItem);
3274     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left);
3275 }
3276
3277 QQuickAnchorLine QQuickItemPrivate::right() const
3278 {
3279     Q_Q(const QQuickItem);
3280     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right);
3281 }
3282
3283 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3284 {
3285     Q_Q(const QQuickItem);
3286     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter);
3287 }
3288
3289 QQuickAnchorLine QQuickItemPrivate::top() const
3290 {
3291     Q_Q(const QQuickItem);
3292     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top);
3293 }
3294
3295 QQuickAnchorLine QQuickItemPrivate::bottom() const
3296 {
3297     Q_Q(const QQuickItem);
3298     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom);
3299 }
3300
3301 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3302 {
3303     Q_Q(const QQuickItem);
3304     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter);
3305 }
3306
3307 QQuickAnchorLine QQuickItemPrivate::baseline() const
3308 {
3309     Q_Q(const QQuickItem);
3310     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline);
3311 }
3312
3313 qreal QQuickItem::baselineOffset() const
3314 {
3315     Q_D(const QQuickItem);
3316     if (d->baselineOffsetValid) {
3317         return d->baselineOffset;
3318     } else {
3319         return 0.0;
3320     }
3321 }
3322
3323 void QQuickItem::setBaselineOffset(qreal offset)
3324 {
3325     Q_D(QQuickItem);
3326     if (offset == d->baselineOffset)
3327         return;
3328
3329     d->baselineOffset = offset;
3330     d->baselineOffsetValid = true;
3331
3332     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3333         const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3334         if (change.types & QQuickItemPrivate::Geometry) {
3335             QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3336             if (anchor)
3337                 anchor->updateVerticalAnchors();
3338         }
3339     }
3340
3341     if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor))
3342         QQuickAnchorsPrivate::get(d->_anchors)->updateVerticalAnchors();
3343
3344     emit baselineOffsetChanged(offset);
3345 }
3346
3347 void QQuickItem::update()
3348 {
3349     Q_D(QQuickItem);
3350     Q_ASSERT(flags() & ItemHasContents);
3351     d->dirty(QQuickItemPrivate::Content);
3352 }
3353
3354 void QQuickItem::polish()
3355 {
3356     Q_D(QQuickItem);
3357     if (!d->polishScheduled) {
3358         d->polishScheduled = true;
3359         if (d->canvas) {
3360             QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
3361             bool maybeupdate = p->itemsToPolish.isEmpty();
3362             p->itemsToPolish.insert(this);
3363             if (maybeupdate) d->canvas->maybeUpdate();
3364         }
3365     }
3366 }
3367
3368 void QQuickItem::mapFromItem(QQmlV8Function *args) const
3369 {
3370     if (args->Length() != 0) {
3371         v8::Local<v8::Value> item = (*args)[0];
3372         QV8Engine *engine = args->engine();
3373
3374         QQuickItem *itemObj = 0;
3375         if (!item->IsNull())
3376             itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3377
3378         if (!itemObj && !item->IsNull()) {
3379             qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3380                           << "\" which is neither null nor an Item";
3381             return;
3382         }
3383
3384         v8::Local<v8::Object> rv = v8::Object::New();
3385         args->returnValue(rv);
3386
3387         qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3388         qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3389
3390         QPointF p = mapFromItem(itemObj, QPointF(x, y));
3391
3392         rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3393         rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3394     }
3395 }
3396
3397 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3398 {
3399     Q_D(const QQuickItem);
3400
3401     // XXX todo - we need to be able to handle common parents better and detect
3402     // invalid cases
3403     if (ok) *ok = true;
3404
3405     QTransform t = d->itemToCanvasTransform();
3406     if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
3407
3408     return t;
3409 }
3410
3411 void QQuickItem::mapToItem(QQmlV8Function *args) const
3412 {
3413     if (args->Length() != 0) {
3414         v8::Local<v8::Value> item = (*args)[0];
3415         QV8Engine *engine = args->engine();
3416
3417         QQuickItem *itemObj = 0;
3418         if (!item->IsNull())
3419             itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3420
3421         if (!itemObj && !item->IsNull()) {
3422             qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3423                           << "\" which is neither null nor an Item";
3424             return;
3425         }
3426
3427         v8::Local<v8::Object> rv = v8::Object::New();
3428         args->returnValue(rv);
3429
3430         qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3431         qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3432
3433         QPointF p = mapToItem(itemObj, QPointF(x, y));
3434
3435         rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3436         rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3437     }
3438 }
3439
3440 void QQuickItem::forceActiveFocus()
3441 {
3442     setFocus(true);
3443     QQuickItem *parent = parentItem();
3444     while (parent) {
3445         if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3446             parent->setFocus(true);
3447         }
3448         parent = parent->parentItem();
3449     }
3450 }
3451
3452 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3453 {
3454     // XXX todo - should this include transform etc.?
3455     const QList<QQuickItem *> children = childItems();
3456     for (int i = children.count()-1; i >= 0; --i) {
3457         QQuickItem *child = children.at(i);
3458         if (child->isVisible() && child->x() <= x
3459                 && child->x() + child->width() >= x
3460                 && child->y() <= y
3461                 && child->y() + child->height() >= y)
3462             return child;
3463     }
3464     return 0;
3465 }
3466
3467 QQmlListProperty<QObject> QQuickItemPrivate::resources()
3468 {
3469     return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3470                                              QQuickItemPrivate::resources_count,
3471                                              QQuickItemPrivate::resources_at,
3472                                              QQuickItemPrivate::resources_clear);
3473 }
3474
3475 QQmlListProperty<QQuickItem> QQuickItemPrivate::children()
3476 {
3477     return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3478                                              QQuickItemPrivate::children_count,
3479                                              QQuickItemPrivate::children_at,
3480                                              QQuickItemPrivate::children_clear);
3481
3482 }
3483
3484 /*!
3485   \qmlproperty real QtQuick2::Item::visibleChildren
3486   This read-only property lists all of the item's children that are currently visible.
3487   Note that a child's visibility may have changed explicitly, or because the visibility
3488   of this (it's parent) item or another grandparent changed.
3489 */
3490 QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
3491 {
3492     return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
3493                                              QQuickItemPrivate::visibleChildren_count,
3494                                              QQuickItemPrivate::visibleChildren_at);
3495
3496 }
3497
3498 QQmlListProperty<QQuickState> QQuickItemPrivate::states()
3499 {
3500     return _states()->statesProperty();
3501 }
3502
3503 QQmlListProperty<QQuickTransition> QQuickItemPrivate::transitions()
3504 {
3505     return _states()->transitionsProperty();
3506 }
3507
3508 QString QQuickItemPrivate::state() const
3509 {
3510     if (!_stateGroup)
3511         return QString();
3512     else
3513         return _stateGroup->state();
3514 }
3515
3516 void QQuickItemPrivate::setState(const QString &state)
3517 {
3518     _states()->setState(state);
3519 }
3520
3521 QString QQuickItem::state() const
3522 {
3523     Q_D(const QQuickItem);
3524     return d->state();
3525 }
3526
3527 void QQuickItem::setState(const QString &state)
3528 {
3529     Q_D(QQuickItem);
3530     d->setState(state);
3531 }
3532
3533 QQmlListProperty<QQuickTransform> QQuickItem::transform()
3534 {
3535     return QQmlListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3536                                                      QQuickItemPrivate::transform_count,
3537                                                      QQuickItemPrivate::transform_at,
3538                                                      QQuickItemPrivate::transform_clear);
3539 }
3540
3541 void QQuickItem::classBegin()
3542 {
3543     Q_D(QQuickItem);
3544     d->componentComplete = false;
3545     if (d->_stateGroup)
3546         d->_stateGroup->classBegin();
3547     if (d->_anchors)
3548         d->_anchors->classBegin();
3549     if (d->extra.isAllocated() && d->extra->layer)
3550         d->extra->layer->classBegin();
3551 }
3552
3553 void QQuickItem::componentComplete()
3554 {
3555     Q_D(QQuickItem);
3556     d->componentComplete = true;
3557     if (d->_stateGroup)
3558         d->_stateGroup->componentComplete();
3559     if (d->_anchors) {
3560         d->_anchors->componentComplete();
3561         QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3562     }
3563
3564     if (d->extra.isAllocated() && d->extra->layer)
3565         d->extra->layer->componentComplete();
3566
3567     if (d->extra.isAllocated() && d->extra->keyHandler)
3568         d->extra->keyHandler->componentComplete();
3569
3570     if (d->extra.isAllocated() && d->extra->contents)
3571         d->extra->contents->complete();
3572 }
3573
3574 QQuickStateGroup *QQuickItemPrivate::_states()
3575 {
3576     Q_Q(QQuickItem);
3577     if (!_stateGroup) {
3578         _stateGroup = new QQuickStateGroup;
3579         if (!componentComplete)
3580             _stateGroup->classBegin();
3581         FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)),
3582                      q, SIGNAL(stateChanged(QString)))
3583     }
3584
3585     return _stateGroup;
3586 }
3587
3588 QPointF QQuickItemPrivate::computeTransformOrigin() const
3589 {
3590     switch (origin()) {
3591     default:
3592     case QQuickItem::TopLeft:
3593         return QPointF(0, 0);
3594     case QQuickItem::Top:
3595         return QPointF(width / 2., 0);
3596     case QQuickItem::TopRight:
3597         return QPointF(width, 0);
3598     case QQuickItem::Left:
3599         return QPointF(0, height / 2.);
3600     case QQuickItem::Center:
3601         return QPointF(width / 2., height / 2.);
3602     case QQuickItem::Right:
3603         return QPointF(width, height / 2.);
3604     case QQuickItem::BottomLeft:
3605         return QPointF(0, height);
3606     case QQuickItem::Bottom:
3607         return QPointF(width / 2., height);
3608     case QQuickItem::BottomRight:
3609         return QPointF(width, height);
3610     }
3611 }
3612
3613 void QQuickItemPrivate::transformChanged()
3614 {
3615     if (extra.isAllocated() && extra->layer)
3616         extra->layer->updateMatrix();
3617 }
3618
3619 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3620 {
3621     Q_Q(QQuickItem);
3622
3623     Q_ASSERT(e->isAccepted());
3624     if (extra.isAllocated() && extra->keyHandler) {
3625         if (e->type() == QEvent::KeyPress)
3626             extra->keyHandler->keyPressed(e, false);
3627         else
3628             extra->keyHandler->keyReleased(e, false);
3629
3630         if (e->isAccepted())
3631             return;
3632         else
3633             e->accept();
3634     }
3635
3636     if (e->type() == QEvent::KeyPress)
3637         q->keyPressEvent(e);
3638     else
3639         q->keyReleaseEvent(e);
3640
3641     if (e->isAccepted())
3642         return;
3643
3644     if (extra.isAllocated() && extra->keyHandler) {
3645         e->accept();
3646
3647         if (e->type() == QEvent::KeyPress)
3648             extra->keyHandler->keyPressed(e, true);
3649         else
3650             extra->keyHandler->keyReleased(e, true);
3651     }
3652 }
3653
3654 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3655 {
3656     Q_Q(QQuickItem);
3657
3658     Q_ASSERT(e->isAccepted());
3659     if (extra.isAllocated() && extra->keyHandler) {
3660         extra->keyHandler->inputMethodEvent(e, false);
3661
3662         if (e->isAccepted())
3663             return;
3664         else
3665             e->accept();
3666     }
3667
3668     q->inputMethodEvent(e);
3669
3670     if (e->isAccepted())
3671         return;
3672
3673     if (extra.isAllocated() && extra->keyHandler) {
3674         e->accept();
3675
3676         extra->keyHandler->inputMethodEvent(e, true);
3677     }
3678 }
3679
3680 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3681 {
3682     Q_Q(QQuickItem);
3683
3684     if (e->type() == QEvent::FocusIn) {
3685         q->focusInEvent(e);
3686     } else {
3687         q->focusOutEvent(e);
3688     }
3689 }
3690
3691 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3692 {
3693     Q_Q(QQuickItem);
3694
3695     Q_ASSERT(e->isAccepted());
3696
3697     switch (e->type()) {
3698     default:
3699         Q_ASSERT(!"Unknown event type");
3700     case QEvent::MouseMove:
3701         q->mouseMoveEvent(e);
3702         break;
3703     case QEvent::MouseButtonPress:
3704         q->mousePressEvent(e);
3705         break;
3706     case QEvent::MouseButtonRelease:
3707         q->mouseReleaseEvent(e);
3708         break;
3709     case QEvent::MouseButtonDblClick:
3710         q->mouseDoubleClickEvent(e);
3711         break;
3712     }
3713 }
3714
3715 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3716 {
3717     Q_Q(QQuickItem);
3718     q->wheelEvent(e);
3719 }
3720
3721 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3722 {
3723     Q_Q(QQuickItem);
3724     q->touchEvent(e);
3725 }
3726
3727 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3728 {
3729     Q_Q(QQuickItem);
3730     switch (e->type()) {
3731     default:
3732         Q_ASSERT(!"Unknown event type");
3733     case QEvent::HoverEnter:
3734         q->hoverEnterEvent(e);
3735         break;
3736     case QEvent::HoverLeave:
3737         q->hoverLeaveEvent(e);
3738         break;
3739     case QEvent::HoverMove:
3740         q->hoverMoveEvent(e);
3741         break;
3742     }
3743 }
3744
3745 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3746 {
3747     Q_Q(QQuickItem);
3748     switch (e->type()) {
3749     default:
3750         Q_ASSERT(!"Unknown event type");
3751     case QEvent::DragEnter:
3752         q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3753         break;
3754     case QEvent::DragLeave:
3755         q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3756         break;
3757     case QEvent::DragMove:
3758         q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3759         break;
3760     case QEvent::Drop:
3761         q->dropEvent(static_cast<QDropEvent *>(e));
3762         break;
3763     }
3764 }
3765
3766 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3767 {
3768     Q_UNUSED(change);
3769     Q_UNUSED(value);
3770 }
3771
3772 /*!
3773     Notify input method on updated query values if needed. \a indicates changed attributes.
3774 */
3775 void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
3776 {
3777     if (hasActiveFocus())
3778         qApp->inputMethod()->update(queries);
3779 }
3780
3781 /*! \internal */
3782 // XXX todo - do we want/need this anymore?
3783 // Note that it's now used for varying clip rect
3784 QRectF QQuickItem::boundingRect() const
3785 {
3786     Q_D(const QQuickItem);
3787     return QRectF(0, 0, d->width, d->height);
3788 }
3789
3790 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3791 {
3792     Q_D(const QQuickItem);
3793     return d->origin();
3794 }
3795
3796 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3797 {
3798     Q_D(QQuickItem);
3799     if (origin == d->origin())
3800         return;
3801
3802     d->extra.value().origin = origin;
3803     d->dirty(QQuickItemPrivate::TransformOrigin);
3804
3805     emit transformOriginChanged(d->origin());
3806 }
3807
3808 QPointF QQuickItem::transformOriginPoint() const
3809 {
3810     Q_D(const QQuickItem);
3811     if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
3812         return d->extra->userTransformOriginPoint;
3813     return d->computeTransformOrigin();
3814 }
3815
3816 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3817 {
3818     Q_D(QQuickItem);
3819     if (d->extra.value().userTransformOriginPoint == point)
3820         return;
3821
3822     d->extra->userTransformOriginPoint = point;
3823     d->dirty(QQuickItemPrivate::TransformOrigin);
3824 }
3825
3826 qreal QQuickItem::z() const
3827 {
3828     Q_D(const QQuickItem);
3829     return d->z();
3830 }
3831
3832 void QQuickItem::setZ(qreal v)
3833 {
3834     Q_D(QQuickItem);
3835     if (d->z() == v)
3836         return;
3837
3838     d->extra.value().z = v;
3839
3840     d->dirty(QQuickItemPrivate::ZValue);
3841     if (d->parentItem) {
3842         QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3843         QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3844     }
3845
3846     emit zChanged();
3847
3848     if (d->extra.isAllocated() && d->extra->layer)
3849         d->extra->layer->updateZ();
3850 }
3851
3852
3853 /*!
3854   \qmlproperty real QtQuick2::Item::rotation
3855   This property holds the rotation of the item in degrees clockwise.
3856
3857   This specifies how many degrees to rotate the item around its transformOrigin.
3858   The default rotation is 0 degrees (i.e. not rotated at all).
3859
3860   \table
3861   \row
3862   \li \image declarative-rotation.png
3863   \li
3864   \qml
3865   Rectangle {
3866       color: "blue"
3867       width: 100; height: 100
3868       Rectangle {
3869           color: "red"
3870           x: 25; y: 25; width: 50; height: 50
3871           rotation: 30
3872       }
3873   }
3874   \endqml
3875   \endtable
3876
3877   \sa transform, Rotation
3878 */
3879
3880 /*!
3881   \qmlproperty real QtQuick2::Item::scale
3882   This property holds the scale of the item.
3883
3884   A scale of less than 1 means the item will be displayed smaller than
3885   normal, and a scale of greater than 1 means the item will be
3886   displayed larger than normal.  A negative scale means the item will
3887   be mirrored.
3888
3889   By default, items are displayed at a scale of 1 (i.e. at their
3890   normal size).
3891
3892   Scaling is from the item's transformOrigin.
3893
3894   \table
3895   \row
3896   \li \image declarative-scale.png
3897   \li
3898   \qml
3899   Rectangle {
3900       color: "blue"
3901       width: 100; height: 100
3902       Rectangle {
3903           color: "green"
3904           width: 25; height: 25
3905       }
3906       Rectangle {
3907           color: "red"
3908           x: 25; y: 25; width: 50; height: 50
3909           scale: 1.4
3910       }
3911   }
3912   \endqml
3913   \endtable
3914
3915   \sa transform, Scale
3916 */
3917
3918 /*!
3919   \qmlproperty real QtQuick2::Item::opacity
3920
3921   This property holds the opacity of the item.  Opacity is specified as a
3922   number between 0 (fully transparent) and 1 (fully opaque).  The default is 1.
3923
3924   When this property is set, the specified opacity is also applied
3925   individually to child items.  In almost all cases this is what you want,
3926   but in some cases it may produce undesired results. For example in the
3927   second set of rectangles below, the red rectangle has specified an opacity
3928   of 0.5, which affects the opacity of its blue child rectangle even though
3929   the child has not specified an opacity.
3930
3931   \table
3932   \row
3933   \li \image declarative-item_opacity1.png
3934   \li
3935   \qml
3936     Item {
3937         Rectangle {
3938             color: "red"
3939             width: 100; height: 100
3940             Rectangle {
3941                 color: "blue"
3942                 x: 50; y: 50; width: 100; height: 100
3943             }
3944         }
3945     }
3946   \endqml
3947   \row
3948   \li \image declarative-item_opacity2.png
3949   \li
3950   \qml
3951     Item {
3952         Rectangle {
3953             opacity: 0.5
3954             color: "red"
3955             width: 100; height: 100
3956             Rectangle {
3957                 color: "blue"
3958                 x: 50; y: 50; width: 100; height: 100
3959             }
3960         }
3961     }
3962   \endqml
3963   \endtable
3964
3965   If an item's opacity is set to 0, the item will no longer receive mouse
3966   events, but will continue to receive key events and will retain the keyboard
3967   \l focus if it has been set. (In contrast, setting the \l visible property
3968   to \c false stops both mouse and keyboard events, and also removes focus
3969   from the item.)
3970 */
3971
3972 /*!
3973   Returns a value indicating whether mouse input should
3974   remain with this item exclusively.
3975
3976   \sa setKeepMouseGrab()
3977  */
3978
3979 qreal QQuickItem::rotation() const
3980 {
3981     Q_D(const QQuickItem);
3982     return d->rotation();
3983 }
3984
3985 void QQuickItem::setRotation(qreal r)
3986 {
3987     Q_D(QQuickItem);
3988     if (d->rotation() == r)
3989         return;
3990
3991     d->extra.value().rotation = r;
3992
3993     d->dirty(QQuickItemPrivate::BasicTransform);
3994
3995     d->itemChange(ItemRotationHasChanged, r);
3996
3997     emit rotationChanged();
3998 }
3999
4000 qreal QQuickItem::scale() const
4001 {
4002     Q_D(const QQuickItem);
4003     return d->scale();
4004 }
4005
4006 void QQuickItem::setScale(qreal s)
4007 {
4008     Q_D(QQuickItem);
4009     if (d->scale() == s)
4010         return;
4011
4012     d->extra.value().scale = s;
4013
4014     d->dirty(QQuickItemPrivate::BasicTransform);
4015
4016     emit scaleChanged();
4017 }
4018
4019 qreal QQuickItem::opacity() const
4020 {
4021     Q_D(const QQuickItem);
4022     return d->opacity();
4023 }
4024
4025 void QQuickItem::setOpacity(qreal o)
4026 {
4027     Q_D(QQuickItem);
4028     if (d->opacity() == o)
4029         return;
4030
4031     d->extra.value().opacity = o;
4032
4033     d->dirty(QQuickItemPrivate::OpacityValue);
4034
4035     d->itemChange(ItemOpacityHasChanged, o);
4036
4037     emit opacityChanged();
4038 }
4039
4040 bool QQuickItem::isVisible() const
4041 {
4042     Q_D(const QQuickItem);
4043     return d->effectiveVisible;
4044 }
4045
4046 void QQuickItem::setVisible(bool v)
4047 {
4048     Q_D(QQuickItem);
4049     if (v == d->explicitVisible)
4050         return;
4051
4052     d->explicitVisible = v;
4053
4054     const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
4055     if (childVisibilityChanged && d->parentItem)
4056         emit d->parentItem->visibleChildrenChanged();   // signal the parent, not this!
4057 }
4058
4059 bool QQuickItem::isEnabled() const
4060 {
4061     Q_D(const QQuickItem);
4062     return d->effectiveEnable;
4063 }
4064
4065 void QQuickItem::setEnabled(bool e)
4066 {
4067     Q_D(QQuickItem);
4068     if (e == d->explicitEnable)
4069         return;
4070
4071     d->explicitEnable = e;
4072
4073     QQuickItem *scope = parentItem();
4074     while (scope && !scope->isFocusScope())
4075         scope = scope->parentItem();
4076
4077     d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
4078 }
4079
4080 bool QQuickItemPrivate::calcEffectiveVisible() const
4081 {
4082     // XXX todo - Should the effective visible of an element with no parent just be the current
4083     // effective visible?  This would prevent pointless re-processing in the case of an element
4084     // moving to/from a no-parent situation, but it is different from what graphics view does.
4085     return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
4086 }
4087
4088 bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
4089 {
4090     Q_Q(QQuickItem);
4091
4092     if (newEffectiveVisible && !explicitVisible) {
4093         // This item locally overrides visibility
4094         return false;   // effective visibility didn't change
4095     }
4096
4097     if (newEffectiveVisible == effectiveVisible) {
4098         // No change necessary
4099         return false;   // effective visibility didn't change
4100     }
4101
4102     effectiveVisible = newEffectiveVisible;
4103     dirty(Visible);
4104     if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4105
4106     if (canvas) {
4107         QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4108         if (canvasPriv->mouseGrabberItem == q)
4109             q->ungrabMouse();
4110     }
4111
4112     bool childVisibilityChanged = false;
4113     for (int ii = 0; ii < childItems.count(); ++ii)
4114         childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
4115
4116     itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
4117 #ifndef QT_NO_ACCESSIBILITY
4118     if (isAccessible) {
4119         QAccessibleEvent ev(q, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide);
4120         QAccessible::updateAccessibility(&ev);
4121     }
4122 #endif
4123     emit q->visibleChanged();
4124     if (childVisibilityChanged)
4125         emit q->visibleChildrenChanged();
4126
4127     return true;    // effective visibility DID change
4128 }
4129
4130 bool QQuickItemPrivate::calcEffectiveEnable() const
4131 {
4132     // XXX todo - Should the effective enable of an element with no parent just be the current
4133     // effective enable?  This would prevent pointless re-processing in the case of an element
4134     // moving to/from a no-parent situation, but it is different from what graphics view does.
4135     return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
4136 }
4137
4138 void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
4139 {
4140     Q_Q(QQuickItem);
4141
4142     if (newEffectiveEnable && !explicitEnable) {
4143         // This item locally overrides enable
4144         return;
4145     }
4146
4147     if (newEffectiveEnable == effectiveEnable) {
4148         // No change necessary
4149         return;
4150     }
4151
4152     effectiveEnable = newEffectiveEnable;
4153
4154     if (canvas) {
4155         QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4156         if (canvasPriv->mouseGrabberItem == q)
4157             q->ungrabMouse();
4158         if (scope && !effectiveEnable && activeFocus) {
4159             canvasPriv->clearFocusInScope(
4160                     scope, q,  QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4161         }
4162     }
4163
4164     for (int ii = 0; ii < childItems.count(); ++ii) {
4165         QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
4166                 (flags & QQuickItem::ItemIsFocusScope) && scope ? q : scope, newEffectiveEnable);
4167     }
4168
4169     if (canvas && scope && effectiveEnable && focus) {
4170         QQuickCanvasPrivate::get(canvas)->setFocusInScope(
4171                 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4172     }
4173
4174     emit q->enabledChanged();
4175 }
4176
4177 QString QQuickItemPrivate::dirtyToString() const
4178 {
4179 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
4180     if (!rv.isEmpty()) \
4181         rv.append(QLatin1String("|")); \
4182     rv.append(QLatin1String(#value)); \
4183 }
4184
4185 //    QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
4186     QString rv;
4187
4188     DIRTY_TO_STRING(TransformOrigin);
4189     DIRTY_TO_STRING(Transform);
4190     DIRTY_TO_STRING(BasicTransform);
4191     DIRTY_TO_STRING(Position);
4192     DIRTY_TO_STRING(Size);
4193     DIRTY_TO_STRING(ZValue);
4194     DIRTY_TO_STRING(Content);
4195     DIRTY_TO_STRING(Smooth);
4196     DIRTY_TO_STRING(OpacityValue);
4197     DIRTY_TO_STRING(ChildrenChanged);
4198     DIRTY_TO_STRING(ChildrenStackingChanged);
4199     DIRTY_TO_STRING(ParentChanged);
4200     DIRTY_TO_STRING(Clip);
4201     DIRTY_TO_STRING(Canvas);
4202     DIRTY_TO_STRING(EffectReference);
4203     DIRTY_TO_STRING(Visible);
4204     DIRTY_TO_STRING(HideReference);
4205     DIRTY_TO_STRING(PerformanceHints);
4206
4207     return rv;
4208 }
4209
4210 void QQuickItemPrivate::dirty(DirtyType type)
4211 {
4212     Q_Q(QQuickItem);
4213     if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4214         transformChanged();
4215
4216     if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
4217         dirtyAttributes |= type;
4218         if (canvas) {
4219             addToDirtyList();
4220             QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
4221         }
4222     }
4223 }
4224
4225 void QQuickItemPrivate::addToDirtyList()
4226 {
4227     Q_Q(QQuickItem);
4228
4229     Q_ASSERT(canvas);
4230     if (!prevDirtyItem) {
4231         Q_ASSERT(!nextDirtyItem);
4232
4233         QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
4234         nextDirtyItem = p->dirtyItemList;
4235         if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4236         prevDirtyItem = &p->dirtyItemList;
4237         p->dirtyItemList = q;
4238         p->dirtyItem(q);
4239     }
4240     Q_ASSERT(prevDirtyItem);
4241 }
4242
4243 void QQuickItemPrivate::removeFromDirtyList()
4244 {
4245     if (prevDirtyItem) {
4246         if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4247         *prevDirtyItem = nextDirtyItem;
4248         prevDirtyItem = 0;
4249         nextDirtyItem = 0;
4250     }
4251     Q_ASSERT(!prevDirtyItem);
4252     Q_ASSERT(!nextDirtyItem);
4253 }
4254
4255 void QQuickItemPrivate::refFromEffectItem(bool hide)
4256 {
4257     ++extra.value().effectRefCount;
4258     if (1 == extra->effectRefCount) {
4259         dirty(EffectReference);
4260         if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4261     }
4262     if (hide) {
4263         if (++extra->hideRefCount == 1)
4264             dirty(HideReference);
4265     }
4266 }
4267
4268 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4269 {
4270     Q_ASSERT(extra->effectRefCount);
4271     --extra->effectRefCount;
4272     if (0 == extra->effectRefCount) {
4273         dirty(EffectReference);
4274         if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4275     }
4276     if (unhide) {
4277         if (--extra->hideRefCount == 0)
4278             dirty(HideReference);
4279     }
4280 }
4281
4282 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4283 {
4284     Q_Q(QQuickItem);
4285     switch (change) {
4286     case QQuickItem::ItemChildAddedChange:
4287         q->itemChange(change, data);
4288         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4289             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4290             if (change.types & QQuickItemPrivate::Children) {
4291                 change.listener->itemChildAdded(q, data.item);
4292             }
4293         }
4294         break;
4295     case QQuickItem::ItemChildRemovedChange:
4296         q->itemChange(change, data);
4297         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4298             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4299             if (change.types & QQuickItemPrivate::Children) {
4300                 change.listener->itemChildRemoved(q, data.item);
4301             }
4302         }
4303         break;
4304     case QQuickItem::ItemSceneChange:
4305         q->itemChange(change, data);
4306         break;
4307     case QQuickItem::ItemVisibleHasChanged:
4308         q->itemChange(change, data);
4309         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4310             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4311             if (change.types & QQuickItemPrivate::Visibility) {
4312                 change.listener->itemVisibilityChanged(q);
4313             }
4314         }
4315         break;
4316     case QQuickItem::ItemParentHasChanged:
4317         q->itemChange(change, data);
4318         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4319             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4320             if (change.types & QQuickItemPrivate::Parent) {
4321                 change.listener->itemParentChanged(q, data.item);
4322             }
4323         }
4324         break;
4325     case QQuickItem::ItemOpacityHasChanged:
4326         q->itemChange(change, data);
4327         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4328             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4329             if (change.types & QQuickItemPrivate::Opacity) {
4330                 change.listener->itemOpacityChanged(q);
4331             }
4332         }
4333         break;
4334     case QQuickItem::ItemActiveFocusHasChanged:
4335         q->itemChange(change, data);
4336         break;
4337     case QQuickItem::ItemRotationHasChanged:
4338         q->itemChange(change, data);
4339         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4340             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4341             if (change.types & QQuickItemPrivate::Rotation) {
4342                 change.listener->itemRotationChanged(q);
4343             }
4344         }
4345         break;
4346     }
4347 }
4348
4349 /*!
4350     \property QQuickItem::smooth
4351     \brief whether the item is smoothed or not.
4352
4353     Primarily used in image based elements to decide if the item should use smooth
4354     sampling or not. Smooth sampling is performed using linear interpolation, while
4355     non-smooth is performed using nearest neighbor.
4356
4357     In Qt Quick 2.0, this property has minimal impact on performance.
4358
4359     By default is true.
4360 */
4361
4362 /*!
4363     Returns true if the item should be drawn with antialiasing and
4364     smooth pixmap filtering, false otherwise.
4365
4366     The default is false.
4367
4368     \sa setSmooth()
4369 */
4370 bool QQuickItem::smooth() const
4371 {
4372     Q_D(const QQuickItem);
4373     return d->smooth;
4374 }
4375
4376 /*!
4377     Sets whether the item should be drawn with antialiasing and
4378     smooth pixmap filtering to \a smooth.
4379
4380     \sa smooth()
4381 */
4382 void QQuickItem::setSmooth(bool smooth)
4383 {
4384     Q_D(QQuickItem);
4385     if (d->smooth == smooth)
4386         return;
4387
4388     d->smooth = smooth;
4389     d->dirty(QQuickItemPrivate::Smooth);
4390
4391     emit smoothChanged(smooth);
4392 }
4393
4394 QQuickItem::Flags QQuickItem::flags() const
4395 {
4396     Q_D(const QQuickItem);
4397     return (QQuickItem::Flags)d->flags;
4398 }
4399
4400 void QQuickItem::setFlag(Flag flag, bool enabled)
4401 {
4402     Q_D(QQuickItem);
4403     if (enabled)
4404         setFlags((Flags)(d->flags | (quint32)flag));
4405     else
4406         setFlags((Flags)(d->flags & ~(quint32)flag));
4407 }
4408
4409 void QQuickItem::setFlags(Flags flags)
4410 {
4411     Q_D(QQuickItem);
4412
4413     if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4414         if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4415             qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
4416             flags &= ~ItemIsFocusScope;
4417         } else if (d->flags & ItemIsFocusScope) {
4418             qWarning("QQuickItem: Cannot unset FocusScope flag.");
4419             flags |= ItemIsFocusScope;
4420         }
4421     }
4422
4423     if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4424         d->dirty(QQuickItemPrivate::Clip);
4425
4426     d->flags = flags;
4427 }
4428
4429 qreal QQuickItem::x() const
4430 {
4431     Q_D(const QQuickItem);
4432     return d->x;
4433 }
4434
4435 qreal QQuickItem::y() const
4436 {
4437     Q_D(const QQuickItem);
4438     return d->y;
4439 }
4440
4441 QPointF QQuickItem::pos() const
4442 {
4443     Q_D(const QQuickItem);
4444     return QPointF(d->x, d->y);
4445 }
4446
4447 void QQuickItem::setX(qreal v)
4448 {
4449     Q_D(QQuickItem);
4450     if (d->x == v)
4451         return;
4452
4453     qreal oldx = d->x;
4454     d->x = v;
4455
4456     d->dirty(QQuickItemPrivate::Position);
4457
4458     geometryChanged(QRectF(x(), y(), width(), height()),
4459                     QRectF(oldx, y(), width(), height()));
4460 }
4461
4462 void QQuickItem::setY(qreal v)
4463 {
4464     Q_D(QQuickItem);
4465     if (d->y == v)
4466         return;
4467
4468     qreal oldy = d->y;
4469     d->y = v;
4470
4471     d->dirty(QQuickItemPrivate::Position);
4472
4473     geometryChanged(QRectF(x(), y(), width(), height()),
4474                     QRectF(x(), oldy, width(), height()));
4475 }
4476
4477 void QQuickItem::setPos(const QPointF &pos)
4478 {
4479     Q_D(QQuickItem);
4480     if (QPointF(d->x, d->y) == pos)
4481         return;
4482
4483     qreal oldx = d->x;
4484     qreal oldy = d->y;
4485
4486     d->x = pos.x();
4487     d->y = pos.y();
4488
4489     d->dirty(QQuickItemPrivate::Position);
4490
4491     geometryChanged(QRectF(x(), y(), width(), height()),
4492                     QRectF(oldx, oldy, width(), height()));
4493 }
4494
4495 qreal QQuickItem::width() const
4496 {
4497     Q_D(const QQuickItem);
4498     return d->width;
4499 }
4500
4501 void QQuickItem::setWidth(qreal w)
4502 {
4503     Q_D(QQuickItem);
4504     if (qIsNaN(w))
4505         return;
4506
4507     d->widthValid = true;
4508     if (d->width == w)
4509         return;
4510
4511     qreal oldWidth = d->width;
4512     d->width = w;
4513
4514     d->dirty(QQuickItemPrivate::Size);
4515
4516     geometryChanged(QRectF(x(), y(), width(), height()),
4517                     QRectF(x(), y(), oldWidth, height()));
4518 }
4519
4520 void QQuickItem::resetWidth()
4521 {
4522     Q_D(QQuickItem);
4523     d->widthValid = false;
4524     setImplicitWidth(implicitWidth());
4525 }
4526
4527 void QQuickItemPrivate::implicitWidthChanged()
4528 {
4529     Q_Q(QQuickItem);
4530     for (int ii = 0; ii < changeListeners.count(); ++ii) {
4531         const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4532         if (change.types & QQuickItemPrivate::ImplicitWidth) {
4533             change.listener->itemImplicitWidthChanged(q);
4534         }
4535     }
4536     emit q->implicitWidthChanged();
4537 }
4538
4539 qreal QQuickItemPrivate::getImplicitWidth() const
4540 {
4541     return implicitWidth;
4542 }
4543 /*!
4544     Returns the width of the item that is implied by other properties that determine the content.
4545 */
4546 qreal QQuickItem::implicitWidth() const
4547 {
4548     Q_D(const QQuickItem);
4549     return d->getImplicitWidth();
4550 }
4551
4552 /*!
4553     \qmlproperty real QtQuick2::Item::implicitWidth
4554     \qmlproperty real QtQuick2::Item::implicitHeight
4555
4556     Defines the natural width or height of the Item if no \l width or \l height is specified.
4557
4558     The default implicit size for most items is 0x0, however some elements have an inherent
4559     implicit size which cannot be overridden, e.g. Image, Text.
4560
4561     Setting the implicit size is useful for defining components that have a preferred size
4562     based on their content, for example:
4563
4564     \qml
4565     // Label.qml
4566     import QtQuick 2.0
4567
4568     Item {
4569         property alias icon: image.source
4570         property alias label: text.text
4571         implicitWidth: text.implicitWidth + image.implicitWidth
4572         implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4573         Image { id: image }
4574         Text {
4575             id: text
4576             wrapMode: Text.Wrap
4577             anchors.left: image.right; anchors.right: parent.right
4578             anchors.verticalCenter: parent.verticalCenter
4579         }
4580     }
4581     \endqml
4582
4583     \b Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4584     incurs a performance penalty as the text must be laid out twice.
4585 */
4586
4587 /*!
4588     Sets the implied width of the item to \a w.
4589     This is the width implied by other properties that determine the content.
4590 */
4591 void QQuickItem::setImplicitWidth(qreal w)
4592 {
4593     Q_D(QQuickItem);
4594     bool changed = w != d->implicitWidth;
4595     d->implicitWidth = w;
4596     if (d->width == w || widthValid()) {
4597         if (changed)
4598             d->implicitWidthChanged();
4599         return;
4600     }
4601
4602     qreal oldWidth = d->width;
4603     d->width = w;
4604
4605     d->dirty(QQuickItemPrivate::Size);
4606
4607     geometryChanged(QRectF(x(), y(), width(), height()),
4608                     QRectF(x(), y(), oldWidth, height()));
4609
4610     if (changed)
4611         d->implicitWidthChanged();
4612 }
4613
4614 /*!
4615     Returns whether the width property has been set explicitly.
4616 */
4617 bool QQuickItem::widthValid() const
4618 {
4619     Q_D(const QQuickItem);
4620     return d->widthValid;
4621 }
4622
4623 qreal QQuickItem::height() const
4624 {
4625     Q_D(const QQuickItem);
4626     return d->height;
4627 }
4628
4629 void QQuickItem::setHeight(qreal h)
4630 {
4631     Q_D(QQuickItem);
4632     if (qIsNaN(h))
4633         return;
4634
4635     d->heightValid = true;
4636     if (d->height == h)
4637         return;
4638
4639     qreal oldHeight = d->height;
4640     d->height = h;
4641
4642     d->dirty(QQuickItemPrivate::Size);
4643
4644     geometryChanged(QRectF(x(), y(), width(), height()),
4645                     QRectF(x(), y(), width(), oldHeight));
4646 }
4647
4648 void QQuickItem::resetHeight()
4649 {
4650     Q_D(QQuickItem);
4651     d->heightValid = false;
4652     setImplicitHeight(implicitHeight());
4653 }
4654
4655 void QQuickItemPrivate::implicitHeightChanged()
4656 {
4657     Q_Q(QQuickItem);
4658     for (int ii = 0; ii < changeListeners.count(); ++ii) {
4659         const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4660         if (change.types & QQuickItemPrivate::ImplicitHeight) {
4661             change.listener->itemImplicitHeightChanged(q);
4662         }
4663     }
4664     emit q->implicitHeightChanged();
4665 }
4666
4667 qreal QQuickItemPrivate::getImplicitHeight() const
4668 {
4669     return implicitHeight;
4670 }
4671
4672 /*!
4673     Returns the height of the item that is implied by other properties that determine the content.
4674 */
4675 qreal QQuickItem::implicitHeight() const
4676 {
4677     Q_D(const QQuickItem);
4678     return d->getImplicitHeight();
4679 }
4680
4681
4682 /*!
4683     Sets the implied height of the item to \a h.
4684     This is the height implied by other properties that determine the content.
4685 */
4686 void QQuickItem::setImplicitHeight(qreal h)
4687 {
4688     Q_D(QQuickItem);
4689     bool changed = h != d->implicitHeight;
4690     d->implicitHeight = h;
4691     if (d->height == h || heightValid()) {
4692         if (changed)
4693             d->implicitHeightChanged();
4694         return;
4695     }
4696
4697     qreal oldHeight = d->height;
4698     d->height = h;
4699
4700     d->dirty(QQuickItemPrivate::Size);
4701
4702     geometryChanged(QRectF(x(), y(), width(), height()),
4703                     QRectF(x(), y(), width(), oldHeight));
4704
4705     if (changed)
4706         d->implicitHeightChanged();
4707 }
4708
4709 void QQuickItem::setImplicitSize(qreal w, qreal h)
4710 {
4711     Q_D(QQuickItem);
4712     bool wChanged = w != d->implicitWidth;
4713     bool hChanged = h != d->implicitHeight;
4714
4715     d->implicitWidth = w;
4716     d->implicitHeight = h;
4717
4718     bool wDone = false;
4719     bool hDone = false;
4720     if (d->width == w || widthValid()) {
4721         if (wChanged)
4722             d->implicitWidthChanged();
4723         wDone = true;
4724     }
4725     if (d->height == h || heightValid()) {
4726         if (hChanged)
4727             d->implicitHeightChanged();
4728         hDone = true;
4729     }
4730     if (wDone && hDone)
4731         return;
4732
4733     qreal oldWidth = d->width;
4734     qreal oldHeight = d->height;
4735     if (!wDone)
4736         d->width = w;
4737     if (!hDone)
4738         d->height = h;
4739
4740     d->dirty(QQuickItemPrivate::Size);
4741
4742     geometryChanged(QRectF(x(), y(), width(), height()),
4743                     QRectF(x(), y(), oldWidth, oldHeight));
4744
4745     if (!wDone && wChanged)
4746         d->implicitWidthChanged();
4747     if (!hDone && hChanged)
4748         d->implicitHeightChanged();
4749 }
4750
4751 /*!
4752     Returns whether the height property has been set explicitly.
4753 */
4754 bool QQuickItem::heightValid() const
4755 {
4756     Q_D(const QQuickItem);
4757     return d->heightValid;
4758 }
4759
4760 void QQuickItem::setSize(const QSizeF &size)
4761 {
4762     Q_D(QQuickItem);
4763     d->heightValid = true;
4764     d->widthValid = true;
4765
4766     if (QSizeF(d->width, d->height) == size)
4767         return;
4768
4769     qreal oldHeight = d->height;
4770     qreal oldWidth = d->width;
4771     d->height = size.height();
4772     d->width = size.width();
4773
4774     d->dirty(QQuickItemPrivate::Size);
4775
4776     geometryChanged(QRectF(x(), y(), width(), height()),
4777                     QRectF(x(), y(), oldWidth, oldHeight));
4778 }
4779
4780 bool QQuickItem::hasActiveFocus() const
4781 {
4782     Q_D(const QQuickItem);
4783     return d->activeFocus;
4784 }
4785
4786 bool QQuickItem::hasFocus() const
4787 {
4788     Q_D(const QQuickItem);
4789     return d->focus;
4790 }
4791
4792 void QQuickItem::setFocus(bool focus)
4793 {
4794     Q_D(QQuickItem);
4795     if (d->focus == focus)
4796         return;
4797
4798     if (d->canvas || d->parentItem) {
4799         // Need to find our nearest focus scope
4800         QQuickItem *scope = parentItem();
4801         while (scope && !scope->isFocusScope() && scope->parentItem())
4802             scope = scope->parentItem();
4803         if (d->canvas) {
4804             if (focus)
4805                 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4806             else
4807                 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4808         } else {
4809             // do the focus changes from setFocusInScope/clearFocusInScope that are
4810             // unrelated to a canvas
4811             QVarLengthArray<QQuickItem *, 20> changed;
4812             QQuickItem *oldSubFocusItem = QQuickItemPrivate::get(scope)->subFocusItem;
4813             if (oldSubFocusItem) {
4814                 QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(scope, false);
4815                 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
4816                 changed << oldSubFocusItem;
4817             }
4818             d->updateSubFocusItem(scope, focus);
4819
4820             d->focus = focus;
4821             changed << this;
4822             emit focusChanged(focus);
4823
4824             QQuickCanvasPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
4825         }
4826     } else {
4827         d->focus = focus;
4828         emit focusChanged(focus);
4829     }
4830 }
4831
4832 bool QQuickItem::isFocusScope() const
4833 {
4834     return flags() & ItemIsFocusScope;
4835 }
4836
4837 QQuickItem *QQuickItem::scopedFocusItem() const
4838 {
4839     Q_D(const QQuickItem);
4840     if (!isFocusScope())
4841         return 0;
4842     else
4843         return d->subFocusItem;
4844 }
4845
4846
4847 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
4848 {
4849     Q_D(const QQuickItem);
4850     return d->acceptedMouseButtons();
4851 }
4852
4853 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4854 {
4855     Q_D(QQuickItem);
4856     if (buttons & Qt::LeftButton)
4857         d->extra.setFlag();
4858     else
4859         d->extra.clearFlag();
4860
4861     buttons &= ~Qt::LeftButton;
4862     if (buttons || d->extra.isAllocated())
4863         d->extra.value().acceptedMouseButtons = buttons;
4864 }
4865
4866 bool QQuickItem::filtersChildMouseEvents() const
4867 {
4868     Q_D(const QQuickItem);
4869     return d->filtersChildMouseEvents;
4870 }
4871
4872 void QQuickItem::setFiltersChildMouseEvents(bool filter)
4873 {
4874     Q_D(QQuickItem);
4875     d->filtersChildMouseEvents = filter;
4876 }
4877
4878 bool QQuickItem::isUnderMouse() const
4879 {
4880     Q_D(const QQuickItem);
4881     if (!d->canvas)
4882         return false;
4883
4884     QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition;
4885     if (QRectF(0, 0, width(), height()).contains(mapFromScene(cursorPos))) // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
4886         return true;
4887     return false;
4888 }
4889
4890 bool QQuickItem::acceptHoverEvents() const
4891 {
4892     Q_D(const QQuickItem);
4893     return d->hoverEnabled;
4894 }
4895
4896 void QQuickItem::setAcceptHoverEvents(bool enabled)
4897 {
4898     Q_D(QQuickItem);
4899     d->hoverEnabled = enabled;
4900 }
4901
4902 void QQuickItem::grabMouse()
4903 {
4904     Q_D(QQuickItem);
4905     if (!d->canvas)
4906         return;
4907     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4908     if (canvasPriv->mouseGrabberItem == this)
4909         return;
4910
4911     QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
4912     canvasPriv->mouseGrabberItem = this;
4913     if (oldGrabber) {
4914         QEvent ev(QEvent::UngrabMouse);
4915         d->canvas->sendEvent(oldGrabber, &ev);
4916     }
4917 }
4918
4919 void QQuickItem::ungrabMouse()
4920 {
4921     Q_D(QQuickItem);
4922     if (!d->canvas)
4923         return;
4924     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4925     if (canvasPriv->mouseGrabberItem != this) {
4926         qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
4927         return;
4928     }
4929
4930     canvasPriv->mouseGrabberItem = 0;
4931
4932     QEvent ev(QEvent::UngrabMouse);
4933     d->canvas->sendEvent(this, &ev);
4934 }
4935
4936 bool QQuickItem::keepMouseGrab() const
4937 {
4938     Q_D(const QQuickItem);
4939     return d->keepMouse;
4940 }
4941
4942 /*!
4943   The flag indicating whether the mouse should remain
4944   with this item is set to \a keep.
4945
4946   This is useful for items that wish to grab and keep mouse
4947   interaction following a predefined gesture.  For example,
4948   an item that is interested in horizontal mouse movement
4949   may set keepMouseGrab to true once a threshold has been
4950   exceeded.  Once keepMouseGrab has been set to true, filtering
4951   items will not react to mouse events.
4952
4953   If the item does not indicate that it wishes to retain mouse grab,
4954   a filtering item may steal the grab. For example, Flickable may attempt
4955   to steal a mouse grab if it detects that the user has begun to
4956   move the viewport.
4957
4958   \sa keepMouseGrab()
4959  */
4960 void QQuickItem::setKeepMouseGrab(bool keep)
4961 {
4962     Q_D(QQuickItem);
4963     d->keepMouse = keep;
4964 }
4965
4966 /*!
4967     Grabs the touch points specified by \a ids.
4968
4969     These touch points will be owned by the item until
4970     they are released. Alternatively, the grab can be stolen
4971     by a filtering item like Flickable. Use setKeepTouchGrab()
4972     to prevent the grab from being stolen.
4973
4974     \sa ungrabTouchPoints(), setKeepTouchGrab()
4975 */
4976 void QQuickItem::grabTouchPoints(const QList<int> &ids)
4977 {
4978     Q_D(QQuickItem);
4979     if (!d->canvas)
4980         return;
4981     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4982
4983     QSet<QQuickItem*> ungrab;
4984     for (int i = 0; i < ids.count(); ++i) {
4985         QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
4986         if (oldGrabber == this)
4987             return;
4988
4989         canvasPriv->itemForTouchPointId[ids.at(i)] = this;
4990         if (oldGrabber)
4991             ungrab.insert(oldGrabber);
4992     }
4993     foreach (QQuickItem *oldGrabber, ungrab)
4994         oldGrabber->touchUngrabEvent();
4995 }
4996
4997 /*!
4998     Ungrabs the touch points owned by this item.
4999
5000     \sa grabTouchPoints()
5001 */
5002 void QQuickItem::ungrabTouchPoints()
5003 {
5004     Q_D(QQuickItem);
5005     if (!d->canvas)
5006         return;
5007     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5008
5009     QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
5010     while (i.hasNext()) {
5011         i.next();
5012         if (i.value() == this)
5013             i.remove();
5014     }
5015     touchUngrabEvent();
5016 }
5017
5018 /*!
5019     Returns a value indicating whether the touch points grabbed by this item
5020     should remain with this item exclusively.
5021
5022     \sa setKeepTouchGrab(), keepMouseGrab()
5023 */
5024 bool QQuickItem::keepTouchGrab() const
5025 {
5026     Q_D(const QQuickItem);
5027     return d->keepTouch;
5028 }
5029
5030 /*!
5031   The flag indicating whether the touch points grabbed
5032   by this item should remain with this item is set to \a keep.
5033
5034   This is useful for items that wish to grab and keep specific touch
5035   points following a predefined gesture.  For example,
5036   an item that is interested in horizontal touch point movement
5037   may set setKeepTouchGrab to true once a threshold has been
5038   exceeded.  Once setKeepTouchGrab has been set to true, filtering
5039   items will not react to the relevant touch points.
5040
5041   If the item does not indicate that it wishes to retain touch point grab,
5042   a filtering item may steal the grab. For example, Flickable may attempt
5043   to steal a touch point grab if it detects that the user has begun to
5044   move the viewport.
5045
5046   \sa keepTouchGrab(), setKeepMouseGrab()
5047  */
5048 void QQuickItem::setKeepTouchGrab(bool keep)
5049 {
5050     Q_D(QQuickItem);
5051     d->keepTouch = keep;
5052 }
5053
5054 /*!
5055     \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
5056
5057     Maps the point (\a x, \a y), which is in \a item's coordinate system, to
5058     this item's coordinate system, and returns an object with \c x and \c y
5059     properties matching the mapped coordinate.
5060
5061     If \a item is a \c null value, this maps the point from the coordinate
5062     system of the root QML view.
5063 */
5064 /*!
5065     \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
5066
5067     Maps the point (\a x, \a y), which is in this item's coordinate system, to
5068     \a item's coordinate system, and returns an object with \c x and \c y
5069     properties matching the mapped coordinate.
5070
5071     If \a item is a \c null value, this maps \a x and \a y to the coordinate
5072     system of the root QML view.
5073 */
5074 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
5075 {
5076     QPointF p = mapToScene(point);
5077     if (item)
5078         p = item->mapFromScene(p);
5079     return p;
5080 }
5081
5082 QPointF QQuickItem::mapToScene(const QPointF &point) const
5083 {
5084     Q_D(const QQuickItem);
5085     return d->itemToCanvasTransform().map(point);
5086 }
5087
5088 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
5089 {
5090     Q_D(const QQuickItem);
5091     QTransform t = d->itemToCanvasTransform();
5092     if (item)
5093         t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
5094     return t.mapRect(rect);
5095 }
5096
5097 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
5098 {
5099     Q_D(const QQuickItem);
5100     return d->itemToCanvasTransform().mapRect(rect);
5101 }
5102
5103 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
5104 {
5105     QPointF p = item?item->mapToScene(point):point;
5106     return mapFromScene(p);
5107 }
5108
5109 QPointF QQuickItem::mapFromScene(const QPointF &point) const
5110 {
5111     Q_D(const QQuickItem);
5112     return d->canvasToItemTransform().map(point);
5113 }
5114
5115 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
5116 {
5117     Q_D(const QQuickItem);
5118     QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
5119     t *= d->canvasToItemTransform();
5120     return t.mapRect(rect);
5121 }
5122
5123 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
5124 {
5125     Q_D(const QQuickItem);
5126     return d->canvasToItemTransform().mapRect(rect);
5127 }
5128
5129
5130 /*!
5131     \qmlmethod QtQuick2::Item::forceActiveFocus()
5132
5133     Forces active focus on the item.
5134
5135     This method sets focus on the item and makes sure that all the focus scopes
5136     higher in the object hierarchy are also given the focus.
5137 */
5138
5139 /*!
5140     Forces active focus on the item.
5141
5142     This method sets focus on the item and makes sure that all the focus scopes
5143     higher in the object hierarchy are also given the focus.
5144 */
5145
5146 /*!
5147   \qmlmethod QtQuick2::Item::childAt(real x, real y)
5148
5149   Returns the visible child item at point (\a x, \a y), which is in this
5150   item's coordinate system, or \c null if there is no such item.
5151 */
5152
5153 /*!
5154   Returns the visible child item at point (\a x, \a y), which is in this
5155   item's coordinate system, or 0 if there is no such item.
5156 */
5157
5158 /*!
5159   \qmlproperty list<State> QtQuick2::Item::states
5160   This property holds a list of states defined by the item.
5161
5162   \qml
5163   Item {
5164       states: [
5165           State {
5166               // ...
5167           },
5168           State {
5169               // ...
5170           }
5171           // ...
5172       ]
5173   }
5174   \endqml
5175
5176   \sa {qmlstate}{States}
5177 */
5178 /*!
5179   \qmlproperty list<Transition> QtQuick2::Item::transitions
5180   This property holds a list of transitions defined by the item.
5181
5182   \qml
5183   Item {
5184       transitions: [
5185           Transition {
5186               // ...
5187           },
5188           Transition {
5189               // ...
5190           }
5191           // ...
5192       ]
5193   }
5194   \endqml
5195
5196   \sa {QML Animation and Transitions}{Transitions}
5197 */
5198 /*
5199   \qmlproperty list<Filter> QtQuick2::Item::filter
5200   This property holds a list of graphical filters to be applied to the item.
5201
5202   \l {Filter}{Filters} include things like \l {Blur}{blurring}
5203   the item, or giving it a \l Reflection.  Some
5204   filters may not be available on all canvases; if a filter is not
5205   available on a certain canvas, it will simply not be applied for
5206   that canvas (but the QML will still be considered valid).
5207
5208   \qml
5209   Item {
5210       filter: [
5211           Blur {
5212               // ...
5213           },
5214           Reflection {
5215               // ...
5216           }
5217           // ...
5218       ]
5219   }
5220   \endqml
5221 */
5222
5223 /*!
5224   \qmlproperty bool QtQuick2::Item::clip
5225   This property holds whether clipping is enabled. The default clip value is \c false.
5226
5227   If clipping is enabled, an item will clip its own painting, as well
5228   as the painting of its children, to its bounding rectangle.
5229
5230   Non-rectangular clipping regions are not supported for performance reasons.
5231 */
5232
5233 /*!
5234   \property QQuickItem::clip
5235   This property holds whether clipping is enabled. The default clip value is \c false.
5236
5237   If clipping is enabled, an item will clip its own painting, as well
5238   as the painting of its children, to its bounding rectangle. If you set
5239   clipping during an item's paint operation, remember to re-set it to
5240   prevent clipping the rest of your scene.
5241
5242   Non-rectangular clipping regions are not supported for performance reasons.
5243 */
5244
5245 /*!
5246   \qmlproperty string QtQuick2::Item::state
5247
5248   This property holds the name of the current state of the item.
5249
5250   This property is often used in scripts to change between states. For
5251   example:
5252
5253   \js
5254   function toggle() {
5255       if (button.state == 'On')
5256           button.state = 'Off';
5257       else
5258           button.state = 'On';
5259   }
5260   \endjs
5261
5262   If the item is in its base state (i.e. no explicit state has been
5263   set), \c state will be a blank string. Likewise, you can return an
5264   item to its base state by setting its current state to \c ''.
5265
5266   \sa {qmlstates}{States}
5267 */
5268
5269 /*!
5270   \qmlproperty list<Transform> QtQuick2::Item::transform
5271   This property holds the list of transformations to apply.
5272
5273   For more information see \l Transform.
5274 */
5275
5276 /*!
5277     \enum QQuickItem::TransformOrigin
5278
5279     Controls the point about which simple transforms like scale apply.
5280
5281     \value TopLeft The top-left corner of the item.
5282     \value Top The center point of the top of the item.
5283     \value TopRight The top-right corner of the item.
5284     \value Left The left most point of the vertical middle.
5285     \value Center The center of the item.
5286     \value Right The right most point of the vertical middle.
5287     \value BottomLeft The bottom-left corner of the item.
5288     \value Bottom The center point of the bottom of the item.
5289     \value BottomRight The bottom-right corner of the item.
5290 */
5291
5292
5293 /*!
5294   \qmlproperty bool QtQuick2::Item::activeFocus
5295
5296   This property indicates whether the item has active focus.
5297
5298   An item with active focus will receive keyboard input,
5299   or is a FocusScope ancestor of the item that will receive keyboard input.
5300
5301   Usually, activeFocus is gained by setting focus on an item and its enclosing
5302   FocusScopes. In the following example \c input will have activeFocus.
5303   \qml
5304   Rectangle {
5305       FocusScope {
5306           focus: true
5307           TextInput {
5308               id: input
5309               focus: true
5310           }
5311       }
5312   }
5313   \endqml
5314
5315   \sa focus, {qmlfocus}{Keyboard Focus}
5316 */
5317
5318 /*!
5319   \qmlproperty bool QtQuick2::Item::focus
5320   This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5321   will gain active focus when the enclosing focus scope gains active focus.
5322   In the following example, \c input will be given active focus when \c scope gains active focus.
5323   \qml
5324   Rectangle {
5325       FocusScope {
5326           id: scope
5327           TextInput {
5328               id: input
5329               focus: true
5330           }
5331       }
5332   }
5333   \endqml
5334
5335   For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5336   On a practical level, that means the following QML will give active focus to \c input on startup.
5337
5338   \qml
5339   Rectangle {
5340       TextInput {
5341           id: input
5342           focus: true
5343       }
5344   }
5345   \endqml
5346
5347   \sa activeFocus, {qmlfocus}{Keyboard Focus}
5348 */
5349
5350
5351 /*!
5352   \property QQuickItem::anchors
5353   \internal
5354 */
5355
5356 /*!
5357   \property QQuickItem::left
5358   \internal
5359 */
5360
5361 /*!
5362   \property QQuickItem::right
5363   \internal
5364 */
5365
5366 /*!
5367   \property QQuickItem::horizontalCenter
5368   \internal
5369 */
5370
5371 /*!
5372   \property QQuickItem::top
5373   \internal
5374 */
5375
5376 /*!
5377   \property QQuickItem::bottom
5378   \internal
5379 */
5380
5381 /*!
5382   \property QQuickItem::verticalCenter
5383   \internal
5384 */
5385
5386 /*!
5387   \property QQuickItem::focus
5388   \internal
5389 */
5390
5391 /*!
5392   \property QQuickItem::transform
5393   \internal
5394 */
5395
5396 /*!
5397   \property QQuickItem::transformOrigin
5398   \internal
5399 */
5400
5401 /*!
5402   \property QQuickItem::activeFocus
5403   \internal
5404 */
5405
5406 /*!
5407   \property QQuickItem::baseline
5408   \internal
5409 */
5410
5411 /*!
5412   \property QQuickItem::data
5413   \internal
5414 */
5415
5416 /*!
5417   \property QQuickItem::resources
5418   \internal
5419 */
5420
5421 /*!
5422   \property QQuickItem::state
5423   \internal
5424 */
5425
5426 /*!
5427   \property QQuickItem::states
5428   \internal
5429 */
5430
5431 /*!
5432   \property QQuickItem::transformOriginPoint
5433   \internal
5434 */
5435
5436 /*!
5437   \property QQuickItem::transitions
5438   \internal
5439 */
5440
5441 bool QQuickItem::event(QEvent *ev)
5442 {
5443 #if 0
5444     if (ev->type() == QEvent::PolishRequest) {
5445         Q_D(QQuickItem);
5446         d->polishScheduled = false;
5447         updatePolish();
5448         return true;
5449     } else {
5450         return QObject::event(ev);
5451     }
5452 #endif
5453     if (ev->type() == QEvent::InputMethodQuery) {
5454         QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5455         Qt::InputMethodQueries queries = query->queries();
5456         for (uint i = 0; i < 32; ++i) {
5457             Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5458             if (q) {
5459                 QVariant v = inputMethodQuery(q);
5460                 query->setValue(q, v);
5461             }
5462         }
5463         query->accept();
5464         return true;
5465     } else if (ev->type() == QEvent::InputMethod) {
5466         inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5467         return true;
5468     }
5469     return QObject::event(ev);
5470 }
5471
5472 #ifndef QT_NO_DEBUG_STREAM
5473 QDebug operator<<(QDebug debug, QQuickItem *item)
5474 {
5475     if (!item) {
5476         debug << "QQuickItem(0)";
5477         return debug;
5478     }
5479
5480     debug << item->metaObject()->className() << "(this =" << ((void*)item)
5481           << ", name=" << item->objectName()
5482           << ", parent =" << ((void*)item->parentItem())
5483           << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5484           << ", z =" << item->z() << ')';
5485     return debug;
5486 }
5487 #endif
5488
5489 qint64 QQuickItemPrivate::consistentTime = -1;
5490 void QQuickItemPrivate::setConsistentTime(qint64 t)
5491 {
5492     consistentTime = t;
5493 }
5494
5495 class QElapsedTimerConsistentTimeHack
5496 {
5497 public:
5498     void start() {
5499         t1 = QQuickItemPrivate::consistentTime;
5500         t2 = 0;
5501     }
5502     qint64 elapsed() {
5503         return QQuickItemPrivate::consistentTime - t1;
5504     }
5505     qint64 restart() {
5506         qint64 val = QQuickItemPrivate::consistentTime - t1;
5507         t1 = QQuickItemPrivate::consistentTime;
5508         t2 = 0;
5509         return val;
5510     }
5511
5512 private:
5513     qint64 t1;
5514     qint64 t2;
5515 };
5516
5517 void QQuickItemPrivate::start(QElapsedTimer &t)
5518 {
5519     if (QQuickItemPrivate::consistentTime == -1)
5520         t.start();
5521     else
5522         ((QElapsedTimerConsistentTimeHack*)&t)->start();
5523 }
5524
5525 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5526 {
5527     if (QQuickItemPrivate::consistentTime == -1)
5528         return t.elapsed();
5529     else
5530         return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5531 }
5532
5533 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5534 {
5535     if (QQuickItemPrivate::consistentTime == -1)
5536         return t.restart();
5537     else
5538         return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5539 }
5540
5541 /*!
5542     \fn bool QQuickItem::isTextureProvider() const
5543
5544     Returns true if this item is a texture provider. The default
5545     implementation returns false.
5546
5547     This function can be called from any thread.
5548  */
5549
5550 bool QQuickItem::isTextureProvider() const
5551 {
5552     Q_D(const QQuickItem);
5553     return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5554            d->extra->layer->effectSource()->isTextureProvider() : false;
5555 }
5556
5557 /*!
5558     \fn QSGTextureProvider *QQuickItem::textureProvider() const
5559
5560     Returns the texture provider for an item. The default implementation
5561     returns 0.
5562
5563     This function may only be called on the rendering thread.
5564  */
5565
5566 QSGTextureProvider *QQuickItem::textureProvider() const
5567 {
5568     Q_D(const QQuickItem);
5569     return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5570            d->extra->layer->effectSource()->textureProvider() : 0;
5571 }
5572
5573 QQuickItemLayer *QQuickItemPrivate::layer() const
5574 {
5575     if (!extra.isAllocated() || !extra->layer) {
5576         extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
5577         if (!componentComplete)
5578             extra->layer->classBegin();
5579     }
5580     return extra->layer;
5581 }
5582
5583 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
5584     : m_item(item)
5585     , m_enabled(false)
5586     , m_mipmap(false)
5587     , m_smooth(false)
5588     , m_componentComplete(true)
5589     , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
5590     , m_format(QQuickShaderEffectSource::RGBA)
5591     , m_name("source")
5592     , m_effectComponent(0)
5593     , m_effect(0)
5594     , m_effectSource(0)
5595 {
5596 }
5597
5598 QQuickItemLayer::~QQuickItemLayer()
5599 {
5600     delete m_effectSource;
5601     delete m_effect;
5602 }
5603
5604
5605
5606 /*!
5607     \qmlproperty bool QtQuick2::Item::layer.enabled
5608
5609     Holds wether the item is layered or not. Layering is disabled by default.
5610
5611     A layered item is rendered into an offscreen surface and cached until
5612     it is changed. Enabling layering for complex QML item hierarchies can
5613     some times be an optimization.
5614
5615     None of the other layer properties have any effect when the layer
5616     is disabled.
5617  */
5618
5619 void QQuickItemLayer::setEnabled(bool e)
5620 {
5621     if (e == m_enabled)
5622         return;
5623     m_enabled = e;
5624     if (m_componentComplete) {
5625         if (m_enabled)
5626             activate();
5627         else
5628             deactivate();
5629     }
5630
5631     emit enabledChanged(e);
5632 }
5633
5634 void QQuickItemLayer::classBegin()
5635 {
5636     Q_ASSERT(!m_effectSource);
5637     Q_ASSERT(!m_effect);
5638     m_componentComplete = false;
5639 }
5640
5641 void QQuickItemLayer::componentComplete()
5642 {
5643     Q_ASSERT(!m_componentComplete);
5644     m_componentComplete = true;
5645     if (m_enabled)
5646         activate();
5647 }
5648
5649 void QQuickItemLayer::activate()
5650 {
5651     Q_ASSERT(!m_effectSource);
5652     m_effectSource = new QQuickShaderEffectSource();
5653
5654     QQuickItem *parentItem = m_item->parentItem();
5655     if (parentItem) {
5656         m_effectSource->setParentItem(parentItem);
5657         m_effectSource->stackAfter(m_item);
5658     }
5659
5660     m_effectSource->setSourceItem(m_item);
5661     m_effectSource->setHideSource(true);
5662     m_effectSource->setSmooth(m_smooth);
5663     m_effectSource->setTextureSize(m_size);
5664     m_effectSource->setSourceRect(m_sourceRect);
5665     m_effectSource->setMipmap(m_mipmap);
5666     m_effectSource->setWrapMode(m_wrapMode);
5667     m_effectSource->setFormat(m_format);
5668
5669     if (m_effectComponent)
5670         activateEffect();
5671
5672     m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5673
5674     updateZ();
5675     updateGeometry();
5676     updateOpacity();
5677     updateMatrix();
5678
5679     QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5680     id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5681 }
5682
5683 void QQuickItemLayer::deactivate()
5684 {
5685     Q_ASSERT(m_effectSource);
5686
5687     if (m_effectComponent)
5688         deactivateEffect();
5689
5690     delete m_effectSource;
5691     m_effectSource = 0;
5692
5693     QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5694     id->removeItemChangeListener(this,  QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5695 }
5696
5697 void QQuickItemLayer::activateEffect()
5698 {
5699     Q_ASSERT(m_effectSource);
5700     Q_ASSERT(m_effectComponent);
5701     Q_ASSERT(!m_effect);
5702
5703     QObject *created = m_effectComponent->beginCreate(m_effectComponent->creationContext());
5704     m_effect = qobject_cast<QQuickItem *>(created);
5705     if (!m_effect) {
5706         qWarning("Item: layer.effect is not a QML Item.");
5707         m_effectComponent->completeCreate();
5708         delete created;
5709         return;
5710     }
5711     QQuickItem *parentItem = m_item->parentItem();
5712     if (parentItem) {
5713         m_effect->setParentItem(parentItem);
5714         m_effect->stackAfter(m_effectSource);
5715     }
5716     m_effect->setVisible(m_item->isVisible());
5717     m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
5718     m_effectComponent->completeCreate();
5719 }
5720
5721 void QQuickItemLayer::deactivateEffect()
5722 {
5723     Q_ASSERT(m_effectSource);
5724     Q_ASSERT(m_effectComponent);
5725
5726     delete m_effect;
5727     m_effect = 0;
5728 }
5729
5730
5731 /*!
5732     \qmlproperty Component QtQuick2::Item::layer.effect
5733
5734     Holds the effect that is applied to this layer.
5735
5736     The effect is typically a \l ShaderEffect component, although any \l Item component can be
5737     assigned. The effect should have a source texture property with a name matching \l samplerName.
5738
5739     \sa samplerName
5740  */
5741
5742 void QQuickItemLayer::setEffect(QQmlComponent *component)
5743 {
5744     if (component == m_effectComponent)
5745         return;
5746
5747     bool updateNeeded = false;
5748     if (m_effectSource && m_effectComponent) {
5749         deactivateEffect();
5750         updateNeeded = true;
5751     }
5752
5753     m_effectComponent = component;
5754
5755     if (m_effectSource && m_effectComponent) {
5756         activateEffect();
5757         updateNeeded = true;
5758     }
5759
5760     if (updateNeeded) {
5761         updateZ();
5762         updateGeometry();
5763         updateOpacity();
5764         updateMatrix();
5765         m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5766     }
5767
5768     emit effectChanged(component);
5769 }
5770
5771
5772 /*!
5773     \qmlproperty bool QtQuick2::Item::layer.mipmap
5774
5775     If this property is true, mipmaps are generated for the texture.
5776
5777     \note Some OpenGL ES 2 implementations do not support mipmapping of
5778     non-power-of-two textures.
5779  */
5780
5781 void QQuickItemLayer::setMipmap(bool mipmap)
5782 {
5783     if (mipmap == m_mipmap)
5784         return;
5785     m_mipmap = mipmap;
5786
5787     if (m_effectSource)
5788         m_effectSource->setMipmap(m_mipmap);
5789
5790     emit mipmapChanged(mipmap);
5791 }
5792
5793
5794 /*!
5795     \qmlproperty enumeration QtQuick2::Item::layer.format
5796
5797     This property defines the internal OpenGL format of the texture.
5798     Modifying this property makes most sense when the \a layer.effect is also
5799     specified. Depending on the OpenGL implementation, this property might
5800     allow you to save some texture memory.
5801
5802     \list
5803     \li ShaderEffectSource.Alpha - GL_ALPHA
5804     \li ShaderEffectSource.RGB - GL_RGB
5805     \li ShaderEffectSource.RGBA - GL_RGBA
5806     \endlist
5807
5808     \note Some OpenGL implementations do not support the GL_ALPHA format.
5809  */
5810
5811 void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
5812 {
5813     if (f == m_format)
5814         return;
5815     m_format = f;
5816
5817     if (m_effectSource)
5818         m_effectSource->setFormat(m_format);
5819
5820     emit formatChanged(m_format);
5821 }
5822
5823
5824 /*!
5825     \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
5826
5827     This property defines which rectangular area of the \l sourceItem to
5828     render into the texture. The source rectangle can be larger than
5829     \l sourceItem itself. If the rectangle is null, which is the default,
5830     the whole \l sourceItem is rendered to texture.
5831  */
5832
5833 void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
5834 {
5835     if (sourceRect == m_sourceRect)
5836         return;
5837     m_sourceRect = sourceRect;
5838
5839     if (m_effectSource)
5840         m_effectSource->setSourceRect(m_sourceRect);
5841
5842     emit sourceRectChanged(sourceRect);
5843 }
5844
5845
5846
5847 /*!
5848     \qmlproperty bool QtQuick2::Item::layer.smooth
5849
5850     Holds whether the layer is smoothly transformed.
5851  */
5852
5853 void QQuickItemLayer::setSmooth(bool s)
5854 {
5855     if (m_smooth == s)
5856         return;
5857     m_smooth = s;
5858
5859     if (m_effectSource)
5860         m_effectSource->setSmooth(m_smooth);
5861
5862     emit smoothChanged(s);
5863 }
5864
5865
5866
5867 /*!
5868     \qmlproperty size QtQuick2::Item::layer.textureSize
5869
5870     This property holds the requested pixel size of the layers texture. If it is empty,
5871     which is the default, the size of the item is used.
5872
5873     \note Some platforms have a limit on how small framebuffer objects can be,
5874     which means the actual texture size might be larger than the requested
5875     size.
5876  */
5877
5878 void QQuickItemLayer::setSize(const QSize &size)
5879 {
5880     if (size == m_size)
5881         return;
5882     m_size = size;
5883
5884     if (m_effectSource)
5885         m_effectSource->setTextureSize(size);
5886
5887     emit sizeChanged(size);
5888 }
5889
5890
5891
5892 /*!
5893     \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
5894
5895     This property defines the OpenGL wrap modes associated with the texture.
5896     Modifying this property makes most sense when the \a layer.effect is
5897     specified.
5898
5899     \list
5900     \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
5901     \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
5902     \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
5903     \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
5904     \endlist
5905
5906     \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
5907     wrap mode with non-power-of-two textures.
5908  */
5909
5910 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
5911 {
5912     if (mode == m_wrapMode)
5913         return;
5914     m_wrapMode = mode;
5915
5916     if (m_effectSource)
5917         m_effectSource->setWrapMode(m_wrapMode);
5918
5919     emit wrapModeChanged(mode);
5920 }
5921
5922 /*!
5923     \qmlproperty string QtQuick2::Item::layer.samplerName
5924
5925     Holds the name of the effect's source texture property.
5926
5927     samplerName needs to match the name of the effect's source texture property
5928     so that the Item can pass the layer's offscreen surface to the effect correctly.
5929
5930     \sa effect, ShaderEffect
5931  */
5932
5933 void QQuickItemLayer::setName(const QByteArray &name) {
5934     if (m_name == name)
5935         return;
5936     if (m_effect) {
5937         m_effect->setProperty(m_name, QVariant());
5938         m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
5939     }
5940     m_name = name;
5941     emit nameChanged(name);
5942 }
5943
5944 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
5945 {
5946     Q_UNUSED(item)
5947     updateOpacity();
5948 }
5949
5950 void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
5951 {
5952     updateGeometry();
5953 }
5954
5955 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
5956 {
5957     Q_UNUSED(item)
5958     Q_ASSERT(item == m_item);
5959     Q_ASSERT(parent != m_effectSource);
5960     Q_ASSERT(parent == 0 || parent != m_effect);
5961
5962     m_effectSource->setParentItem(parent);
5963     if (parent)
5964         m_effectSource->stackAfter(m_item);
5965
5966     if (m_effect) {
5967         m_effect->setParentItem(parent);
5968         if (parent)
5969             m_effect->stackAfter(m_effectSource);
5970     }
5971 }
5972
5973 void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
5974 {
5975     m_effectSource->stackAfter(m_item);
5976     if (m_effect)
5977         m_effect->stackAfter(m_effectSource);
5978 }
5979
5980 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
5981 {
5982     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5983     Q_ASSERT(l);
5984     l->setVisible(m_item->isVisible());
5985 }
5986
5987 void QQuickItemLayer::updateZ()
5988 {
5989     if (!m_componentComplete || !m_enabled)
5990         return;
5991     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5992     Q_ASSERT(l);
5993     l->setZ(m_item->z());
5994 }
5995
5996 void QQuickItemLayer::updateOpacity()
5997 {
5998     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
5999     Q_ASSERT(l);
6000     l->setOpacity(m_item->opacity());
6001 }
6002
6003 void QQuickItemLayer::updateGeometry()
6004 {
6005     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6006     Q_ASSERT(l);
6007     QRectF bounds = m_item->boundingRect();
6008     l->setWidth(bounds.width());
6009     l->setHeight(bounds.height());
6010     l->setX(bounds.x() + m_item->x());
6011     l->setY(bounds.y() + m_item->y());
6012 }
6013
6014 void QQuickItemLayer::updateMatrix()
6015 {
6016     // Called directly from transformChanged(), so needs some extra
6017     // checks.
6018     if (!m_componentComplete || !m_enabled)
6019         return;
6020     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6021     Q_ASSERT(l);
6022     QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
6023     l->setScale(m_item->scale());
6024     l->setRotation(m_item->rotation());
6025     ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
6026     if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
6027         ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
6028     ld->dirty(QQuickItemPrivate::Transform);
6029 }
6030
6031 QQuickItemPrivate::ExtraData::ExtraData()
6032 : z(0), scale(1), rotation(0), opacity(1),
6033   contents(0), screenAttached(0), layoutDirectionAttached(0),
6034   keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
6035   opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
6036   acceptedMouseButtons(0), origin(QQuickItem::Center)
6037 {
6038 }
6039
6040 QT_END_NAMESPACE
6041
6042 #include <moc_qquickitem.cpp>