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