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