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