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