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