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