Add contains method to QQuickItem public API
[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 = 0, int depth = 1);
80 void printFocusTree(QQuickItem *item, QQuickItem *scope, int depth)
81 {
82     qWarning()
83             << QByteArray(depth, '\t').constData()
84             << (scope && QQuickItemPrivate::get(scope)->subFocusItem == item ? '*' : ' ')
85             << item->hasFocus()
86             << item->hasActiveFocus()
87             << item->isFocusScope()
88             << item;
89     foreach (QQuickItem *child, item->childItems()) {
90         printFocusTree(
91                 child,
92                 item->isFocusScope() || !scope ? item : scope,
93                 item->isFocusScope() || !scope ? depth + 1 : depth);
94     }
95 }
96 #endif
97
98 static void QQuickItem_parentNotifier(QObject *o, intptr_t, QQmlNotifier **n)
99 {
100     QQuickItemPrivate *d = QQuickItemPrivate::get(static_cast<QQuickItem *>(o));
101     *n = &d->parentNotifier;
102 }
103
104 QML_PRIVATE_ACCESSOR(QQuickItem, QQuickItem *, parent, parentItem)
105 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, x, x)
106 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, y, y)
107 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, width, width)
108 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, height, height)
109
110 static QQmlAccessors QQuickItem_parent = { QQuickItem_parentRead, QQuickItem_parentNotifier };
111 static QQmlAccessors QQuickItem_x = { QQuickItem_xRead, 0 };
112 static QQmlAccessors QQuickItem_y = { QQuickItem_yRead, 0 };
113 static QQmlAccessors QQuickItem_width = { QQuickItem_widthRead, 0 };
114 static QQmlAccessors QQuickItem_height = { QQuickItem_heightRead, 0 };
115
116 QML_DECLARE_PROPERTIES(QQuickItem) {
117     { QML_PROPERTY_NAME(parent), 0, &QQuickItem_parent },
118     { QML_PROPERTY_NAME(x), 0, &QQuickItem_x },
119     { QML_PROPERTY_NAME(y), 0, &QQuickItem_y },
120     { QML_PROPERTY_NAME(width), 0, &QQuickItem_width },
121     { QML_PROPERTY_NAME(height), 0, &QQuickItem_height }
122 };
123
124 void QQuickItemPrivate::registerAccessorProperties()
125 {
126     QML_DEFINE_PROPERTIES(QQuickItem);
127 }
128
129 /*!
130     \qmlclass Transform QQuickTransform
131     \inqmlmodule QtQuick 2
132     \ingroup qml-transform-elements
133     \brief The Transform elements provide a way of building advanced transformations on Items.
134
135     The Transform element is a base type which cannot be instantiated directly.
136     The following concrete Transform types are available:
137
138     \list
139     \li \l Rotation
140     \li \l Scale
141     \li \l Translate
142     \endlist
143
144     The Transform elements let you create and control advanced transformations that can be configured
145     independently using specialized properties.
146
147     You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
148     one at a time.
149 */
150
151 /*!
152     \qmlclass Translate QQuickTranslate
153     \inqmlmodule QtQuick 2
154     \ingroup qml-transform-elements
155     \brief The Translate object provides a way to move an Item without changing its x or y properties.
156
157     The Translate object provides independent control over position in addition to the Item's x and y properties.
158
159     The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
160     to lay the items out as if they had not been transformed:
161     \qml
162     import QtQuick 2.0
163
164     Row {
165         Rectangle {
166             width: 100; height: 100
167             color: "blue"
168             transform: Translate { y: 20 }
169         }
170         Rectangle {
171             width: 100; height: 100
172             color: "red"
173             transform: Translate { y: -20 }
174         }
175     }
176     \endqml
177
178     \image translate.png
179 */
180
181 /*!
182     \qmlproperty real QtQuick2::Translate::x
183
184     The translation along the X axis.
185 */
186
187 /*!
188     \qmlproperty real QtQuick2::Translate::y
189
190     The translation along the Y axis.
191 */
192
193 /*!
194     \qmlclass Scale QQuickScale
195     \inqmlmodule QtQuick 2
196     \ingroup qml-transform-elements
197     \brief The Scale element provides a way to scale an Item.
198
199     The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
200     it allows a different scale for the x and y axes, and allows the scale to be relative to an
201     arbitrary point.
202
203     The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
204     \qml
205     Rectangle {
206         width: 100; height: 100
207         color: "blue"
208         transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
209     }
210     \endqml
211
212     \sa Rotation, Translate
213 */
214
215 /*!
216     \qmlproperty real QtQuick2::Scale::origin.x
217     \qmlproperty real QtQuick2::Scale::origin.y
218
219     The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
220     the rest of the item grows). By default the origin is 0, 0.
221 */
222
223 /*!
224     \qmlproperty real QtQuick2::Scale::xScale
225
226     The scaling factor for the X axis.
227 */
228
229 /*!
230     \qmlproperty real QtQuick2::Scale::yScale
231
232     The scaling factor for the Y axis.
233 */
234
235 /*!
236     \qmlclass Rotation QQuickRotation
237     \inqmlmodule QtQuick 2
238     \ingroup qml-transform-elements
239     \brief The Rotation object provides a way to rotate an Item.
240
241     The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
242     Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
243
244     The following example rotates a Rectangle around its interior point 25, 25:
245     \qml
246     Rectangle {
247         width: 100; height: 100
248         color: "blue"
249         transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
250     }
251     \endqml
252
253     Rotation also provides a way to specify 3D-like rotations for Items. For these types of
254     rotations you must specify the axis to rotate around in addition to the origin point.
255
256     The following example shows various 3D-like rotations applied to an \l Image.
257     \snippet doc/src/snippets/qml/rotation.qml 0
258
259     \image axisrotation.png
260
261     \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
262 */
263
264 /*!
265     \qmlproperty real QtQuick2::Rotation::origin.x
266     \qmlproperty real QtQuick2::Rotation::origin.y
267
268     The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
269     the rest of the item rotates). By default the origin is 0, 0.
270 */
271
272 /*!
273     \qmlproperty real QtQuick2::Rotation::axis.x
274     \qmlproperty real QtQuick2::Rotation::axis.y
275     \qmlproperty real QtQuick2::Rotation::axis.z
276
277     The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
278     as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
279
280     For a typical 3D-like rotation you will usually specify both the origin and the axis.
281
282     \image 3d-rotation-axis.png
283 */
284
285 /*!
286     \qmlproperty real QtQuick2::Rotation::angle
287
288     The angle to rotate, in degrees clockwise.
289 */
290
291 QQuickTransformPrivate::QQuickTransformPrivate()
292 {
293 }
294
295 QQuickTransform::QQuickTransform(QObject *parent)
296 : QObject(*(new QQuickTransformPrivate), parent)
297 {
298 }
299
300 QQuickTransform::QQuickTransform(QQuickTransformPrivate &dd, QObject *parent)
301 : QObject(dd, parent)
302 {
303 }
304
305 QQuickTransform::~QQuickTransform()
306 {
307     Q_D(QQuickTransform);
308     for (int ii = 0; ii < d->items.count(); ++ii) {
309         QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
310         p->transforms.removeOne(this);
311         p->dirty(QQuickItemPrivate::Transform);
312     }
313 }
314
315 void QQuickTransform::update()
316 {
317     Q_D(QQuickTransform);
318     for (int ii = 0; ii < d->items.count(); ++ii) {
319         QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
320         p->dirty(QQuickItemPrivate::Transform);
321     }
322 }
323
324 QQuickContents::QQuickContents(QQuickItem *item)
325 : m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
326 {
327 }
328
329 QQuickContents::~QQuickContents()
330 {
331     QList<QQuickItem *> children = m_item->childItems();
332     for (int i = 0; i < children.count(); ++i) {
333         QQuickItem *child = children.at(i);
334         QQuickItemPrivate::get(child)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
335     }
336 }
337
338 bool QQuickContents::calcHeight(QQuickItem *changed)
339 {
340     qreal oldy = m_y;
341     qreal oldheight = m_height;
342
343     if (changed) {
344         qreal top = oldy;
345         qreal bottom = oldy + oldheight;
346         qreal y = changed->y();
347         if (y + changed->height() > bottom)
348             bottom = y + changed->height();
349         if (y < top)
350             top = y;
351         m_y = top;
352         m_height = bottom - top;
353     } else {
354         qreal top = FLT_MAX;
355         qreal bottom = 0;
356         QList<QQuickItem *> children = m_item->childItems();
357         for (int i = 0; i < children.count(); ++i) {
358             QQuickItem *child = children.at(i);
359             qreal y = child->y();
360             if (y + child->height() > bottom)
361                 bottom = y + child->height();
362             if (y < top)
363                 top = y;
364         }
365         if (!children.isEmpty())
366             m_y = top;
367         m_height = qMax(bottom - top, qreal(0.0));
368     }
369
370     return (m_height != oldheight || m_y != oldy);
371 }
372
373 bool QQuickContents::calcWidth(QQuickItem *changed)
374 {
375     qreal oldx = m_x;
376     qreal oldwidth = m_width;
377
378     if (changed) {
379         qreal left = oldx;
380         qreal right = oldx + oldwidth;
381         qreal x = changed->x();
382         if (x + changed->width() > right)
383             right = x + changed->width();
384         if (x < left)
385             left = x;
386         m_x = left;
387         m_width = right - left;
388     } else {
389         qreal left = FLT_MAX;
390         qreal right = 0;
391         QList<QQuickItem *> children = m_item->childItems();
392         for (int i = 0; i < children.count(); ++i) {
393             QQuickItem *child = children.at(i);
394             qreal x = child->x();
395             if (x + child->width() > right)
396                 right = x + child->width();
397             if (x < left)
398                 left = x;
399         }
400         if (!children.isEmpty())
401             m_x = left;
402         m_width = qMax(right - left, qreal(0.0));
403     }
404
405     return (m_width != oldwidth || m_x != oldx);
406 }
407
408 void QQuickContents::complete()
409 {
410     QQuickItemPrivate::get(m_item)->addItemChangeListener(this, QQuickItemPrivate::Children);
411
412     QList<QQuickItem *> children = m_item->childItems();
413     for (int i = 0; i < children.count(); ++i) {
414         QQuickItem *child = children.at(i);
415         QQuickItemPrivate::get(child)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
416         //###what about changes to visibility?
417     }
418     calcGeometry();
419 }
420
421 void QQuickContents::updateRect()
422 {
423     QQuickItemPrivate::get(m_item)->emitChildrenRectChanged(rectF());
424 }
425
426 void QQuickContents::itemGeometryChanged(QQuickItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
427 {
428     Q_UNUSED(changed)
429     bool wChanged = false;
430     bool hChanged = false;
431     //### we can only pass changed if the left edge has moved left, or the right edge has moved right
432     if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
433         wChanged = calcWidth(/*changed*/);
434     if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
435         hChanged = calcHeight(/*changed*/);
436     if (wChanged || hChanged)
437         updateRect();
438 }
439
440 void QQuickContents::itemDestroyed(QQuickItem *item)
441 {
442     if (item)
443         QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
444     calcGeometry();
445 }
446
447 void QQuickContents::itemChildRemoved(QQuickItem *, QQuickItem *item)
448 {
449     if (item)
450         QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
451     calcGeometry();
452 }
453
454 void QQuickContents::itemChildAdded(QQuickItem *, QQuickItem *item)
455 {
456     if (item)
457         QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
458     calcGeometry(item);
459 }
460
461 QQuickItemKeyFilter::QQuickItemKeyFilter(QQuickItem *item)
462 : m_processPost(false), m_next(0)
463 {
464     QQuickItemPrivate *p = item?QQuickItemPrivate::get(item):0;
465     if (p) {
466         m_next = p->extra.value().keyHandler;
467         p->extra->keyHandler = this;
468     }
469 }
470
471 QQuickItemKeyFilter::~QQuickItemKeyFilter()
472 {
473 }
474
475 void QQuickItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
476 {
477     if (m_next) m_next->keyPressed(event, post);
478 }
479
480 void QQuickItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
481 {
482     if (m_next) m_next->keyReleased(event, post);
483 }
484
485 void QQuickItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
486 {
487     if (m_next)
488         m_next->inputMethodEvent(event, post);
489     else
490         event->ignore();
491 }
492
493 QVariant QQuickItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
494 {
495     if (m_next) return m_next->inputMethodQuery(query);
496     return QVariant();
497 }
498
499 void QQuickItemKeyFilter::componentComplete()
500 {
501     if (m_next) m_next->componentComplete();
502 }
503 /*!
504     \qmlclass KeyNavigation QQuickKeyNavigationAttached
505     \inqmlmodule QtQuick 2
506     \ingroup qml-basic-interaction-elements
507     \brief The KeyNavigation attached property supports key navigation by arrow keys.
508
509     Key-based user interfaces commonly allow the use of arrow keys to navigate between
510     focusable items.  The KeyNavigation attached property enables this behavior by providing a
511     convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
512
513     The following example provides key navigation for a 2x2 grid of items:
514
515     \snippet doc/src/snippets/qml/keynavigation.qml 0
516
517     The top-left item initially receives focus by setting \l {Item::}{focus} to
518     \c true. When an arrow key is pressed, the focus will move to the
519     appropriate item, as defined by the value that has been set for
520     the KeyNavigation \l left, \l right, \l up or \l down properties.
521
522     Note that if a KeyNavigation attached property receives the key press and release
523     events for a requested arrow or tab key, the event is accepted and does not
524     propagate any further.
525
526     By default, KeyNavigation receives key events after the item to which it is attached.
527     If the item accepts the key event, the KeyNavigation attached property will not
528     receive an event for that key.  Setting the \l priority property to
529     \c KeyNavigation.BeforeItem allows the event to be used for key navigation
530     before the item, rather than after.
531
532     If item to which the focus is switching is not enabled or visible, an attempt will
533     be made to skip this item and focus on the next. This is possible if there are
534     a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
535     or visible, they will also be skipped.
536
537     KeyNavigation will implicitly set the other direction to return focus to this item. So if you set
538     \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this
539     item. However, if that item's KeyNavigation has had right explicitly set then no change will occur.
540     This means that the above example could have been written, with the same behaviour, without specifing
541     KeyNavigation.right or KeyNavigation.down for any of the items.
542
543     \sa {Keys}{Keys attached property}
544 */
545
546 /*!
547     \qmlproperty Item QtQuick2::KeyNavigation::left
548     \qmlproperty Item QtQuick2::KeyNavigation::right
549     \qmlproperty Item QtQuick2::KeyNavigation::up
550     \qmlproperty Item QtQuick2::KeyNavigation::down
551     \qmlproperty Item QtQuick2::KeyNavigation::tab
552     \qmlproperty Item QtQuick2::KeyNavigation::backtab
553
554     These properties hold the item to assign focus to
555     when the left, right, up or down cursor keys, or the
556     tab key are pressed.
557 */
558
559 /*!
560     \qmlproperty Item QtQuick2::KeyNavigation::tab
561     \qmlproperty Item QtQuick2::KeyNavigation::backtab
562
563     These properties hold the item to assign focus to
564     when the Tab key or Shift+Tab key combination (Backtab) are pressed.
565 */
566
567 QQuickKeyNavigationAttached::QQuickKeyNavigationAttached(QObject *parent)
568 : QObject(*(new QQuickKeyNavigationAttachedPrivate), parent),
569   QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
570 {
571     m_processPost = true;
572 }
573
574 QQuickKeyNavigationAttached *
575 QQuickKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
576 {
577     return new QQuickKeyNavigationAttached(obj);
578 }
579
580 QQuickItem *QQuickKeyNavigationAttached::left() const
581 {
582     Q_D(const QQuickKeyNavigationAttached);
583     return d->left;
584 }
585
586 void QQuickKeyNavigationAttached::setLeft(QQuickItem *i)
587 {
588     Q_D(QQuickKeyNavigationAttached);
589     if (d->left == i)
590         return;
591     d->left = i;
592     d->leftSet = true;
593     QQuickKeyNavigationAttached* other =
594             qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
595     if (other && !other->d_func()->rightSet){
596         other->d_func()->right = qobject_cast<QQuickItem*>(parent());
597         emit other->rightChanged();
598     }
599     emit leftChanged();
600 }
601
602 QQuickItem *QQuickKeyNavigationAttached::right() const
603 {
604     Q_D(const QQuickKeyNavigationAttached);
605     return d->right;
606 }
607
608 void QQuickKeyNavigationAttached::setRight(QQuickItem *i)
609 {
610     Q_D(QQuickKeyNavigationAttached);
611     if (d->right == i)
612         return;
613     d->right = i;
614     d->rightSet = true;
615     QQuickKeyNavigationAttached* other =
616             qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
617     if (other && !other->d_func()->leftSet){
618         other->d_func()->left = qobject_cast<QQuickItem*>(parent());
619         emit other->leftChanged();
620     }
621     emit rightChanged();
622 }
623
624 QQuickItem *QQuickKeyNavigationAttached::up() const
625 {
626     Q_D(const QQuickKeyNavigationAttached);
627     return d->up;
628 }
629
630 void QQuickKeyNavigationAttached::setUp(QQuickItem *i)
631 {
632     Q_D(QQuickKeyNavigationAttached);
633     if (d->up == i)
634         return;
635     d->up = i;
636     d->upSet = true;
637     QQuickKeyNavigationAttached* other =
638             qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
639     if (other && !other->d_func()->downSet){
640         other->d_func()->down = qobject_cast<QQuickItem*>(parent());
641         emit other->downChanged();
642     }
643     emit upChanged();
644 }
645
646 QQuickItem *QQuickKeyNavigationAttached::down() const
647 {
648     Q_D(const QQuickKeyNavigationAttached);
649     return d->down;
650 }
651
652 void QQuickKeyNavigationAttached::setDown(QQuickItem *i)
653 {
654     Q_D(QQuickKeyNavigationAttached);
655     if (d->down == i)
656         return;
657     d->down = i;
658     d->downSet = true;
659     QQuickKeyNavigationAttached* other =
660             qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
661     if (other && !other->d_func()->upSet) {
662         other->d_func()->up = qobject_cast<QQuickItem*>(parent());
663         emit other->upChanged();
664     }
665     emit downChanged();
666 }
667
668 QQuickItem *QQuickKeyNavigationAttached::tab() const
669 {
670     Q_D(const QQuickKeyNavigationAttached);
671     return d->tab;
672 }
673
674 void QQuickKeyNavigationAttached::setTab(QQuickItem *i)
675 {
676     Q_D(QQuickKeyNavigationAttached);
677     if (d->tab == i)
678         return;
679     d->tab = i;
680     d->tabSet = true;
681     QQuickKeyNavigationAttached* other =
682             qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
683     if (other && !other->d_func()->backtabSet) {
684         other->d_func()->backtab = qobject_cast<QQuickItem*>(parent());
685         emit other->backtabChanged();
686     }
687     emit tabChanged();
688 }
689
690 QQuickItem *QQuickKeyNavigationAttached::backtab() const
691 {
692     Q_D(const QQuickKeyNavigationAttached);
693     return d->backtab;
694 }
695
696 void QQuickKeyNavigationAttached::setBacktab(QQuickItem *i)
697 {
698     Q_D(QQuickKeyNavigationAttached);
699     if (d->backtab == i)
700         return;
701     d->backtab = i;
702     d->backtabSet = true;
703     QQuickKeyNavigationAttached* other =
704             qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
705     if (other && !other->d_func()->tabSet) {
706         other->d_func()->tab = qobject_cast<QQuickItem*>(parent());
707         emit other->tabChanged();
708     }
709     emit backtabChanged();
710 }
711
712 /*!
713     \qmlproperty enumeration QtQuick2::KeyNavigation::priority
714
715     This property determines whether the keys are processed before
716     or after the attached item's own key handling.
717
718     \list
719     \li KeyNavigation.BeforeItem - process the key events before normal
720     item key processing.  If the event is used for key navigation, it will be accepted and will not
721     be passed on to the item.
722     \li KeyNavigation.AfterItem (default) - process the key events after normal item key
723     handling.  If the item accepts the key event it will not be
724     handled by the KeyNavigation attached property handler.
725     \endlist
726 */
727 QQuickKeyNavigationAttached::Priority QQuickKeyNavigationAttached::priority() const
728 {
729     return m_processPost ? AfterItem : BeforeItem;
730 }
731
732 void QQuickKeyNavigationAttached::setPriority(Priority order)
733 {
734     bool processPost = order == AfterItem;
735     if (processPost != m_processPost) {
736         m_processPost = processPost;
737         emit priorityChanged();
738     }
739 }
740
741 void QQuickKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
742 {
743     Q_D(QQuickKeyNavigationAttached);
744     event->ignore();
745
746     if (post != m_processPost) {
747         QQuickItemKeyFilter::keyPressed(event, post);
748         return;
749     }
750
751     bool mirror = false;
752     switch (event->key()) {
753     case Qt::Key_Left: {
754         if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
755             mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
756         QQuickItem* leftItem = mirror ? d->right : d->left;
757         if (leftItem) {
758             setFocusNavigation(leftItem, mirror ? "right" : "left");
759             event->accept();
760         }
761         break;
762     }
763     case Qt::Key_Right: {
764         if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
765             mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
766         QQuickItem* rightItem = mirror ? d->left : d->right;
767         if (rightItem) {
768             setFocusNavigation(rightItem, mirror ? "left" : "right");
769             event->accept();
770         }
771         break;
772     }
773     case Qt::Key_Up:
774         if (d->up) {
775             setFocusNavigation(d->up, "up");
776             event->accept();
777         }
778         break;
779     case Qt::Key_Down:
780         if (d->down) {
781             setFocusNavigation(d->down, "down");
782             event->accept();
783         }
784         break;
785     case Qt::Key_Tab:
786         if (d->tab) {
787             setFocusNavigation(d->tab, "tab");
788             event->accept();
789         }
790         break;
791     case Qt::Key_Backtab:
792         if (d->backtab) {
793             setFocusNavigation(d->backtab, "backtab");
794             event->accept();
795         }
796         break;
797     default:
798         break;
799     }
800
801     if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
802 }
803
804 void QQuickKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
805 {
806     Q_D(QQuickKeyNavigationAttached);
807     event->ignore();
808
809     if (post != m_processPost) {
810         QQuickItemKeyFilter::keyReleased(event, post);
811         return;
812     }
813
814     bool mirror = false;
815     switch (event->key()) {
816     case Qt::Key_Left:
817         if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
818             mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
819         if (mirror ? d->right : d->left)
820             event->accept();
821         break;
822     case Qt::Key_Right:
823         if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
824             mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
825         if (mirror ? d->left : d->right)
826             event->accept();
827         break;
828     case Qt::Key_Up:
829         if (d->up) {
830             event->accept();
831         }
832         break;
833     case Qt::Key_Down:
834         if (d->down) {
835             event->accept();
836         }
837         break;
838     case Qt::Key_Tab:
839         if (d->tab) {
840             event->accept();
841         }
842         break;
843     case Qt::Key_Backtab:
844         if (d->backtab) {
845             event->accept();
846         }
847         break;
848     default:
849         break;
850     }
851
852     if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
853 }
854
855 void QQuickKeyNavigationAttached::setFocusNavigation(QQuickItem *currentItem, const char *dir)
856 {
857     QQuickItem *initialItem = currentItem;
858     bool isNextItem = false;
859     do {
860         isNextItem = false;
861         if (currentItem->isVisible() && currentItem->isEnabled()) {
862             currentItem->setFocus(true);
863         } else {
864             QObject *attached =
865                 qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(currentItem, false);
866             if (attached) {
867                 QQuickItem *tempItem = qvariant_cast<QQuickItem*>(attached->property(dir));
868                 if (tempItem) {
869                     currentItem = tempItem;
870                     isNextItem = true;
871                 }
872             }
873         }
874     }
875     while (currentItem != initialItem && isNextItem);
876 }
877
878 const QQuickKeysAttached::SigMap QQuickKeysAttached::sigMap[] = {
879     { Qt::Key_Left, "leftPressed" },
880     { Qt::Key_Right, "rightPressed" },
881     { Qt::Key_Up, "upPressed" },
882     { Qt::Key_Down, "downPressed" },
883     { Qt::Key_Tab, "tabPressed" },
884     { Qt::Key_Backtab, "backtabPressed" },
885     { Qt::Key_Asterisk, "asteriskPressed" },
886     { Qt::Key_NumberSign, "numberSignPressed" },
887     { Qt::Key_Escape, "escapePressed" },
888     { Qt::Key_Return, "returnPressed" },
889     { Qt::Key_Enter, "enterPressed" },
890     { Qt::Key_Delete, "deletePressed" },
891     { Qt::Key_Space, "spacePressed" },
892     { Qt::Key_Back, "backPressed" },
893     { Qt::Key_Cancel, "cancelPressed" },
894     { Qt::Key_Select, "selectPressed" },
895     { Qt::Key_Yes, "yesPressed" },
896     { Qt::Key_No, "noPressed" },
897     { Qt::Key_Context1, "context1Pressed" },
898     { Qt::Key_Context2, "context2Pressed" },
899     { Qt::Key_Context3, "context3Pressed" },
900     { Qt::Key_Context4, "context4Pressed" },
901     { Qt::Key_Call, "callPressed" },
902     { Qt::Key_Hangup, "hangupPressed" },
903     { Qt::Key_Flip, "flipPressed" },
904     { Qt::Key_Menu, "menuPressed" },
905     { Qt::Key_VolumeUp, "volumeUpPressed" },
906     { Qt::Key_VolumeDown, "volumeDownPressed" },
907     { 0, 0 }
908 };
909
910 bool QQuickKeysAttachedPrivate::isConnected(const char *signalName)
911 {
912     return isSignalConnected(signalIndex(signalName));
913 }
914
915 /*!
916     \qmlclass Keys QQuickKeysAttached
917     \inqmlmodule QtQuick 2
918     \ingroup qml-basic-interaction-elements
919     \brief The Keys attached property provides key handling to Items.
920
921     All visual primitives support key handling via the Keys
922     attached property.  Keys can be handled via the onPressed
923     and onReleased signal properties.
924
925     The signal properties have a \l KeyEvent parameter, named
926     \e event which contains details of the event.  If a key is
927     handled \e event.accepted should be set to true to prevent the
928     event from propagating up the item hierarchy.
929
930     \section1 Example Usage
931
932     The following example shows how the general onPressed handler can
933     be used to test for a certain key; in this case, the left cursor
934     key:
935
936     \snippet doc/src/snippets/qml/keys/keys-pressed.qml key item
937
938     Some keys may alternatively be handled via specific signal properties,
939     for example \e onSelectPressed.  These handlers automatically set
940     \e event.accepted to true.
941
942     \snippet doc/src/snippets/qml/keys/keys-handler.qml key item
943
944     See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
945
946     \section1 Key Handling Priorities
947
948     The Keys attached property can be configured to handle key events
949     before or after the item it is attached to. This makes it possible
950     to intercept events in order to override an item's default behavior,
951     or act as a fallback for keys not handled by the item.
952
953     If \l priority is Keys.BeforeItem (default) the order of key event processing is:
954
955     \list 1
956     \li Items specified in \c forwardTo
957     \li specific key handlers, e.g. onReturnPressed
958     \li onKeyPress, onKeyRelease handlers
959     \li Item specific key handling, e.g. TextInput key handling
960     \li parent item
961     \endlist
962
963     If priority is Keys.AfterItem the order of key event processing is:
964
965     \list 1
966     \li Item specific key handling, e.g. TextInput key handling
967     \li Items specified in \c forwardTo
968     \li specific key handlers, e.g. onReturnPressed
969     \li onKeyPress, onKeyRelease handlers
970     \li parent item
971     \endlist
972
973     If the event is accepted during any of the above steps, key
974     propagation stops.
975
976     \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
977 */
978
979 /*!
980     \qmlproperty bool QtQuick2::Keys::enabled
981
982     This flags enables key handling if true (default); otherwise
983     no key handlers will be called.
984 */
985
986 /*!
987     \qmlproperty enumeration QtQuick2::Keys::priority
988
989     This property determines whether the keys are processed before
990     or after the attached item's own key handling.
991
992     \list
993     \li Keys.BeforeItem (default) - process the key events before normal
994     item key processing.  If the event is accepted it will not
995     be passed on to the item.
996     \li Keys.AfterItem - process the key events after normal item key
997     handling.  If the item accepts the key event it will not be
998     handled by the Keys attached property handler.
999     \endlist
1000 */
1001
1002 /*!
1003     \qmlproperty list<Object> QtQuick2::Keys::forwardTo
1004
1005     This property provides a way to forward key presses, key releases, and keyboard input
1006     coming from input methods to other items. This can be useful when you want
1007     one item to handle some keys (e.g. the up and down arrow keys), and another item to
1008     handle other keys (e.g. the left and right arrow keys).  Once an item that has been
1009     forwarded keys accepts the event it is no longer forwarded to items later in the
1010     list.
1011
1012     This example forwards key events to two lists:
1013     \qml
1014     Item {
1015         ListView {
1016             id: list1
1017             // ...
1018         }
1019         ListView {
1020             id: list2
1021             // ...
1022         }
1023         Keys.forwardTo: [list1, list2]
1024         focus: true
1025     }
1026     \endqml
1027 */
1028
1029 /*!
1030     \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
1031
1032     This handler is called when a key has been pressed. The \a event
1033     parameter provides information about the event.
1034 */
1035
1036 /*!
1037     \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
1038
1039     This handler is called when a key has been released. The \a event
1040     parameter provides information about the event.
1041 */
1042
1043 /*!
1044     \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
1045
1046     This handler is called when the digit '0' has been pressed. The \a event
1047     parameter provides information about the event.
1048 */
1049
1050 /*!
1051     \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
1052
1053     This handler is called when the digit '1' has been pressed. The \a event
1054     parameter provides information about the event.
1055 */
1056
1057 /*!
1058     \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
1059
1060     This handler is called when the digit '2' has been pressed. The \a event
1061     parameter provides information about the event.
1062 */
1063
1064 /*!
1065     \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
1066
1067     This handler is called when the digit '3' has been pressed. The \a event
1068     parameter provides information about the event.
1069 */
1070
1071 /*!
1072     \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
1073
1074     This handler is called when the digit '4' has been pressed. The \a event
1075     parameter provides information about the event.
1076 */
1077
1078 /*!
1079     \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
1080
1081     This handler is called when the digit '5' has been pressed. The \a event
1082     parameter provides information about the event.
1083 */
1084
1085 /*!
1086     \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
1087
1088     This handler is called when the digit '6' has been pressed. The \a event
1089     parameter provides information about the event.
1090 */
1091
1092 /*!
1093     \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
1094
1095     This handler is called when the digit '7' has been pressed. The \a event
1096     parameter provides information about the event.
1097 */
1098
1099 /*!
1100     \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
1101
1102     This handler is called when the digit '8' has been pressed. The \a event
1103     parameter provides information about the event.
1104 */
1105
1106 /*!
1107     \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
1108
1109     This handler is called when the digit '9' has been pressed. The \a event
1110     parameter provides information about the event.
1111 */
1112
1113 /*!
1114     \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
1115
1116     This handler is called when the Left arrow has been pressed. The \a event
1117     parameter provides information about the event.
1118 */
1119
1120 /*!
1121     \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
1122
1123     This handler is called when the Right arrow has been pressed. The \a event
1124     parameter provides information about the event.
1125 */
1126
1127 /*!
1128     \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
1129
1130     This handler is called when the Up arrow has been pressed. The \a event
1131     parameter provides information about the event.
1132 */
1133
1134 /*!
1135     \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
1136
1137     This handler is called when the Down arrow has been pressed. The \a event
1138     parameter provides information about the event.
1139 */
1140
1141 /*!
1142     \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
1143
1144     This handler is called when the Tab key has been pressed. The \a event
1145     parameter provides information about the event.
1146 */
1147
1148 /*!
1149     \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
1150
1151     This handler is called when the Shift+Tab key combination (Backtab) has
1152     been pressed. The \a event parameter provides information about the event.
1153 */
1154
1155 /*!
1156     \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
1157
1158     This handler is called when the Asterisk '*' has been pressed. The \a event
1159     parameter provides information about the event.
1160 */
1161
1162 /*!
1163     \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
1164
1165     This handler is called when the Escape key has been pressed. The \a event
1166     parameter provides information about the event.
1167 */
1168
1169 /*!
1170     \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
1171
1172     This handler is called when the Return key has been pressed. The \a event
1173     parameter provides information about the event.
1174 */
1175
1176 /*!
1177     \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
1178
1179     This handler is called when the Enter key has been pressed. The \a event
1180     parameter provides information about the event.
1181 */
1182
1183 /*!
1184     \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
1185
1186     This handler is called when the Delete key has been pressed. The \a event
1187     parameter provides information about the event.
1188 */
1189
1190 /*!
1191     \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
1192
1193     This handler is called when the Space key has been pressed. The \a event
1194     parameter provides information about the event.
1195 */
1196
1197 /*!
1198     \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
1199
1200     This handler is called when the Back key has been pressed. The \a event
1201     parameter provides information about the event.
1202 */
1203
1204 /*!
1205     \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
1206
1207     This handler is called when the Cancel key has been pressed. The \a event
1208     parameter provides information about the event.
1209 */
1210
1211 /*!
1212     \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
1213
1214     This handler is called when the Select key has been pressed. The \a event
1215     parameter provides information about the event.
1216 */
1217
1218 /*!
1219     \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
1220
1221     This handler is called when the Yes key has been pressed. The \a event
1222     parameter provides information about the event.
1223 */
1224
1225 /*!
1226     \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
1227
1228     This handler is called when the No key has been pressed. The \a event
1229     parameter provides information about the event.
1230 */
1231
1232 /*!
1233     \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
1234
1235     This handler is called when the Context1 key has been pressed. The \a event
1236     parameter provides information about the event.
1237 */
1238
1239 /*!
1240     \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
1241
1242     This handler is called when the Context2 key has been pressed. The \a event
1243     parameter provides information about the event.
1244 */
1245
1246 /*!
1247     \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
1248
1249     This handler is called when the Context3 key has been pressed. The \a event
1250     parameter provides information about the event.
1251 */
1252
1253 /*!
1254     \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
1255
1256     This handler is called when the Context4 key has been pressed. The \a event
1257     parameter provides information about the event.
1258 */
1259
1260 /*!
1261     \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
1262
1263     This handler is called when the Call key has been pressed. The \a event
1264     parameter provides information about the event.
1265 */
1266
1267 /*!
1268     \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
1269
1270     This handler is called when the Hangup key has been pressed. The \a event
1271     parameter provides information about the event.
1272 */
1273
1274 /*!
1275     \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
1276
1277     This handler is called when the Flip key has been pressed. The \a event
1278     parameter provides information about the event.
1279 */
1280
1281 /*!
1282     \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
1283
1284     This handler is called when the Menu key has been pressed. The \a event
1285     parameter provides information about the event.
1286 */
1287
1288 /*!
1289     \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
1290
1291     This handler is called when the VolumeUp key has been pressed. The \a event
1292     parameter provides information about the event.
1293 */
1294
1295 /*!
1296     \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
1297
1298     This handler is called when the VolumeDown key has been pressed. The \a event
1299     parameter provides information about the event.
1300 */
1301
1302 QQuickKeysAttached::QQuickKeysAttached(QObject *parent)
1303 : QObject(*(new QQuickKeysAttachedPrivate), parent),
1304   QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
1305 {
1306     Q_D(QQuickKeysAttached);
1307     m_processPost = false;
1308     d->item = qobject_cast<QQuickItem*>(parent);
1309 }
1310
1311 QQuickKeysAttached::~QQuickKeysAttached()
1312 {
1313 }
1314
1315 QQuickKeysAttached::Priority QQuickKeysAttached::priority() const
1316 {
1317     return m_processPost ? AfterItem : BeforeItem;
1318 }
1319
1320 void QQuickKeysAttached::setPriority(Priority order)
1321 {
1322     bool processPost = order == AfterItem;
1323     if (processPost != m_processPost) {
1324         m_processPost = processPost;
1325         emit priorityChanged();
1326     }
1327 }
1328
1329 void QQuickKeysAttached::componentComplete()
1330 {
1331     Q_D(QQuickKeysAttached);
1332     if (d->item) {
1333         for (int ii = 0; ii < d->targets.count(); ++ii) {
1334             QQuickItem *targetItem = d->targets.at(ii);
1335             if (targetItem && (targetItem->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1336                 d->item->setFlag(QQuickItem::ItemAcceptsInputMethod);
1337                 break;
1338             }
1339         }
1340     }
1341 }
1342
1343 void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
1344 {
1345     Q_D(QQuickKeysAttached);
1346     if (post != m_processPost || !d->enabled || d->inPress) {
1347         event->ignore();
1348         QQuickItemKeyFilter::keyPressed(event, post);
1349         return;
1350     }
1351
1352     // first process forwards
1353     if (d->item && d->item->canvas()) {
1354         d->inPress = true;
1355         for (int ii = 0; ii < d->targets.count(); ++ii) {
1356             QQuickItem *i = d->targets.at(ii);
1357             if (i && i->isVisible()) {
1358                 d->item->canvas()->sendEvent(i, event);
1359                 if (event->isAccepted()) {
1360                     d->inPress = false;
1361                     return;
1362                 }
1363             }
1364         }
1365         d->inPress = false;
1366     }
1367
1368     QQuickKeyEvent ke(*event);
1369     QByteArray keySignal = keyToSignal(event->key());
1370     if (!keySignal.isEmpty()) {
1371         keySignal += "(QQuickKeyEvent*)";
1372         if (d->isConnected(keySignal)) {
1373             // If we specifically handle a key then default to accepted
1374             ke.setAccepted(true);
1375             int idx = QQuickKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1376             metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QQuickKeyEvent*, &ke));
1377         }
1378     }
1379     if (!ke.isAccepted())
1380         emit pressed(&ke);
1381     event->setAccepted(ke.isAccepted());
1382
1383     if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
1384 }
1385
1386 void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
1387 {
1388     Q_D(QQuickKeysAttached);
1389     if (post != m_processPost || !d->enabled || d->inRelease) {
1390         event->ignore();
1391         QQuickItemKeyFilter::keyReleased(event, post);
1392         return;
1393     }
1394
1395     if (d->item && d->item->canvas()) {
1396         d->inRelease = true;
1397         for (int ii = 0; ii < d->targets.count(); ++ii) {
1398             QQuickItem *i = d->targets.at(ii);
1399             if (i && i->isVisible()) {
1400                 d->item->canvas()->sendEvent(i, event);
1401                 if (event->isAccepted()) {
1402                     d->inRelease = false;
1403                     return;
1404                 }
1405             }
1406         }
1407         d->inRelease = false;
1408     }
1409
1410     QQuickKeyEvent ke(*event);
1411     emit released(&ke);
1412     event->setAccepted(ke.isAccepted());
1413
1414     if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
1415 }
1416
1417 void QQuickKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1418 {
1419     Q_D(QQuickKeysAttached);
1420     if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
1421         d->inIM = true;
1422         for (int ii = 0; ii < d->targets.count(); ++ii) {
1423             QQuickItem *i = d->targets.at(ii);
1424             if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1425                 d->item->canvas()->sendEvent(i, event);
1426                 if (event->isAccepted()) {
1427                     d->imeItem = i;
1428                     d->inIM = false;
1429                     return;
1430                 }
1431             }
1432         }
1433         d->inIM = false;
1434     }
1435     QQuickItemKeyFilter::inputMethodEvent(event, post);
1436 }
1437
1438 QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1439 {
1440     Q_D(const QQuickKeysAttached);
1441     if (d->item) {
1442         for (int ii = 0; ii < d->targets.count(); ++ii) {
1443             QQuickItem *i = d->targets.at(ii);
1444             if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod) && i == d->imeItem) {
1445                 //### how robust is i == d->imeItem check?
1446                 QVariant v = i->inputMethodQuery(query);
1447                 if (v.userType() == QVariant::RectF)
1448                     v = d->item->mapRectFromItem(i, v.toRectF());  //### cost?
1449                 return v;
1450             }
1451         }
1452     }
1453     return QQuickItemKeyFilter::inputMethodQuery(query);
1454 }
1455
1456 QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
1457 {
1458     return new QQuickKeysAttached(obj);
1459 }
1460
1461 /*!
1462     \qmlclass LayoutMirroring QQuickLayoutMirroringAttached
1463     \inqmlmodule QtQuick 2
1464     \ingroup qml-utility-elements
1465     \brief The LayoutMirroring attached property is used to mirror layout behavior.
1466
1467     The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
1468     \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
1469     and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
1470     anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
1471     horizontal layout of child items.
1472
1473     Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
1474     only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
1475     behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
1476     for an item, mirroring is not enabled.
1477
1478     The following example shows mirroring in action. The \l Row below is specified as being anchored
1479     to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
1480     reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
1481     from left to right by default, they are now positioned from right to left instead, as demonstrated
1482     by the numbering and opacity of the items:
1483
1484     \snippet doc/src/snippets/qml/layoutmirroring.qml 0
1485
1486     \image layoutmirroring.png
1487
1488     Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
1489     layout versions of an application to target different language areas. The \l childrenInherit
1490     property allows layout mirroring to be applied without manually setting layout configurations
1491     for every item in an application. Keep in mind, however, that mirroring does not affect any
1492     positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
1493     mirroring enabled, it will often be necessary to apply some layout fixes to support the
1494     desired layout direction. Also, it may be necessary to disable the mirroring of individual
1495     child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
1496     mirroring is not the desired behavior, or if the child item already implements mirroring in
1497     some custom way.
1498
1499     See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
1500     other related features to implement right-to-left support for an application.
1501 */
1502
1503 /*!
1504     \qmlproperty bool QtQuick2::LayoutMirroring::enabled
1505
1506     This property holds whether the item's layout is mirrored horizontally. Setting this to true
1507     horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
1508     and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
1509     (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
1510     this also mirrors the horizontal layout direction of the item.
1511
1512     The default value is false.
1513 */
1514
1515 /*!
1516     \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
1517
1518     This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
1519     is inherited by its children.
1520
1521     The default value is false.
1522 */
1523
1524
1525 QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
1526 {
1527     if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) {
1528         itemPrivate = QQuickItemPrivate::get(item);
1529         itemPrivate->extra.value().layoutDirectionAttached = this;
1530     } else
1531         qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
1532 }
1533
1534 QQuickLayoutMirroringAttached * QQuickLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
1535 {
1536     return new QQuickLayoutMirroringAttached(object);
1537 }
1538
1539 bool QQuickLayoutMirroringAttached::enabled() const
1540 {
1541     return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
1542 }
1543
1544 void QQuickLayoutMirroringAttached::setEnabled(bool enabled)
1545 {
1546     if (!itemPrivate)
1547         return;
1548
1549     itemPrivate->isMirrorImplicit = false;
1550     if (enabled != itemPrivate->effectiveLayoutMirror) {
1551         itemPrivate->setLayoutMirror(enabled);
1552         if (itemPrivate->inheritMirrorFromItem)
1553              itemPrivate->resolveLayoutMirror();
1554     }
1555 }
1556
1557 void QQuickLayoutMirroringAttached::resetEnabled()
1558 {
1559     if (itemPrivate && !itemPrivate->isMirrorImplicit) {
1560         itemPrivate->isMirrorImplicit = true;
1561         itemPrivate->resolveLayoutMirror();
1562     }
1563 }
1564
1565 bool QQuickLayoutMirroringAttached::childrenInherit() const
1566 {
1567     return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
1568 }
1569
1570 void QQuickLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
1571     if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
1572         itemPrivate->inheritMirrorFromItem = childrenInherit;
1573         itemPrivate->resolveLayoutMirror();
1574         childrenInheritChanged();
1575     }
1576 }
1577
1578 void QQuickItemPrivate::resolveLayoutMirror()
1579 {
1580     Q_Q(QQuickItem);
1581     if (QQuickItem *parentItem = q->parentItem()) {
1582         QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parentItem);
1583         setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
1584     } else {
1585         setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
1586     }
1587 }
1588
1589 void QQuickItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
1590 {
1591     inherit = inherit || inheritMirrorFromItem;
1592     if (!isMirrorImplicit && inheritMirrorFromItem)
1593         mirror = effectiveLayoutMirror;
1594     if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
1595         return;
1596
1597     inheritMirrorFromParent = inherit;
1598     inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
1599
1600     if (isMirrorImplicit)
1601         setLayoutMirror(inherit ? inheritedLayoutMirror : false);
1602     for (int i = 0; i < childItems.count(); ++i) {
1603         if (QQuickItem *child = qobject_cast<QQuickItem *>(childItems.at(i))) {
1604             QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
1605             childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
1606         }
1607     }
1608 }
1609
1610 void QQuickItemPrivate::setLayoutMirror(bool mirror)
1611 {
1612     if (mirror != effectiveLayoutMirror) {
1613         effectiveLayoutMirror = mirror;
1614         if (_anchors) {
1615             QQuickAnchorsPrivate *anchor_d = QQuickAnchorsPrivate::get(_anchors);
1616             anchor_d->fillChanged();
1617             anchor_d->centerInChanged();
1618             anchor_d->updateHorizontalAnchors();
1619             emit _anchors->mirroredChanged();
1620         }
1621         mirrorChange();
1622         if (extra.isAllocated() && extra->layoutDirectionAttached) {
1623             emit extra->layoutDirectionAttached->enabledChanged();
1624         }
1625     }
1626 }
1627
1628 void QQuickItemPrivate::setAccessibleFlagAndListener()
1629 {
1630     Q_Q(QQuickItem);
1631     QQuickItem *item = q;
1632     while (item) {
1633         if (item->d_func()->isAccessible)
1634             break; // already set - grandparents should have the flag set as well.
1635
1636         item->d_func()->isAccessible = true;
1637         item = item->d_func()->parentItem;
1638     }
1639 }
1640
1641 void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
1642 {
1643     Q_Q(QQuickItem);
1644     Q_ASSERT(scope);
1645
1646     QQuickItemPrivate *scopePrivate = QQuickItemPrivate::get(scope);
1647
1648     QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
1649     // Correct focus chain in scope
1650     if (oldSubFocusItem) {
1651         QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1652         while (sfi && sfi != scope) {
1653             QQuickItemPrivate::get(sfi)->subFocusItem = 0;
1654             sfi = sfi->parentItem();
1655         }
1656     }
1657
1658     if (focus) {
1659         scopePrivate->subFocusItem = q;
1660         QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
1661         while (sfi && sfi != scope) {
1662             QQuickItemPrivate::get(sfi)->subFocusItem = q;
1663             sfi = sfi->parentItem();
1664         }
1665     } else {
1666         scopePrivate->subFocusItem = 0;
1667     }
1668 }
1669
1670
1671 /*!
1672     \class QQuickItem
1673     \brief The QQuickItem class provides the most basic of all visual items in QML.
1674
1675     \inmodule QtQuick
1676
1677     All visual items in Qt Quick inherit from QQuickItem.  Although QQuickItem
1678     has no visual appearance, it defines all the properties that are
1679     common across visual items - such as the x and y position, the
1680     width and height, \l {anchor-layout}{anchoring} and key handling.
1681
1682     You can subclass QQuickItem to provide your own custom visual item that inherits
1683     these features. Note that, because it does not draw anything, QQuickItem sets the
1684     QGraphicsItem::ItemHasNoContents flag. If you subclass QQuickItem to create a visual
1685     item, you will need to unset this flag.
1686
1687 */
1688
1689 /*!
1690     \qmlclass Item QQuickItem
1691     \inherits QtObject
1692     \inqmlmodule QtQuick 2
1693     \ingroup qml-basic-visual-elements
1694     \brief The Item is the most basic of all visual items in QML.
1695
1696     All visual items in Qt Quick inherit from Item.  Although Item
1697     has no visual appearance, it defines all the properties that are
1698     common across visual items - such as the x and y position, the
1699     width and height, \l {anchor-layout}{anchoring} and key handling.
1700
1701     Item is also useful for grouping items together.
1702
1703     \qml
1704     Item {
1705         Image {
1706             source: "tile.png"
1707         }
1708         Image {
1709             x: 80
1710             width: 100
1711             height: 100
1712             source: "tile.png"
1713         }
1714         Image {
1715             x: 190
1716             width: 100
1717             height: 100
1718             fillMode: Image.Tile
1719             source: "tile.png"
1720         }
1721     }
1722     \endqml
1723
1724
1725     \section1 Key Handling
1726
1727     Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1728     attached property.  The \e Keys attached property provides basic handlers such
1729     as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1730     as well as handlers for specific keys, such as
1731     \l {Keys::onCancelPressed}{onCancelPressed}.  The example below
1732     assigns \l {qmlfocus}{focus} to the item and handles
1733     the Left key via the general \e onPressed handler and the Select key via the
1734     onSelectPressed handler:
1735
1736     \qml
1737     Item {
1738         focus: true
1739         Keys.onPressed: {
1740             if (event.key == Qt.Key_Left) {
1741                 console.log("move left");
1742                 event.accepted = true;
1743             }
1744         }
1745         Keys.onSelectPressed: console.log("Selected");
1746     }
1747     \endqml
1748
1749     See the \l {Keys}{Keys} attached property for detailed documentation.
1750
1751     \section1 Layout Mirroring
1752
1753     Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1754
1755 */
1756
1757 /*!
1758     \fn void QQuickItem::childrenRectChanged(const QRectF &)
1759     \internal
1760 */
1761
1762 /*!
1763     \fn void QQuickItem::baselineOffsetChanged(qreal)
1764     \internal
1765 */
1766
1767 /*!
1768     \fn void QQuickItem::stateChanged(const QString &state)
1769     \internal
1770 */
1771
1772 /*!
1773     \fn void QQuickItem::parentChanged(QQuickItem *)
1774     \internal
1775 */
1776
1777 /*!
1778     \fn void QQuickItem::smoothChanged(bool)
1779     \internal
1780 */
1781
1782 /*!
1783     \fn void QQuickItem::clipChanged(bool)
1784     \internal
1785 */
1786
1787 /*! \fn void QQuickItem::transformOriginChanged(TransformOrigin)
1788   \internal
1789 */
1790
1791 /*!
1792     \fn void QQuickItem::focusChanged(bool)
1793     \internal
1794 */
1795
1796 /*!
1797     \fn void QQuickItem::activeFocusChanged(bool)
1798     \internal
1799 */
1800 /*!
1801     \fn QQuickItem::QQuickItem(QQuickItem *parent)
1802
1803     Constructs a QQuickItem with the given \a parent.
1804 */
1805 QQuickItem::QQuickItem(QQuickItem* parent)
1806 : QObject(*(new QQuickItemPrivate), parent)
1807 {
1808     Q_D(QQuickItem);
1809     d->init(parent);
1810 }
1811
1812 /*! \internal
1813 */
1814 QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
1815 : QObject(dd, parent)
1816 {
1817     Q_D(QQuickItem);
1818     d->init(parent);
1819 }
1820
1821 #ifndef QT_NO_DEBUG
1822 static int qt_item_count = 0;
1823
1824 static void qt_print_item_count()
1825 {
1826     qDebug("Number of leaked items: %i", qt_item_count);
1827     qt_item_count = -1;
1828 }
1829 #endif
1830
1831 /*!
1832     Destroys the QQuickItem.
1833 */
1834 QQuickItem::~QQuickItem()
1835 {
1836 #ifndef QT_NO_DEBUG
1837     --qt_item_count;
1838     if (qt_item_count < 0)
1839         qDebug("Item destroyed after qt_print_item_count() was called.");
1840 #endif
1841
1842     Q_D(QQuickItem);
1843
1844     if (d->canvasRefCount > 1)
1845         d->canvasRefCount = 1; // Make sure canvas is set to null in next call to derefCanvas().
1846     if (d->parentItem)
1847         setParentItem(0);
1848     else if (d->canvas)
1849         d->derefCanvas();
1850
1851     // XXX todo - optimize
1852     while (!d->childItems.isEmpty())
1853         d->childItems.first()->setParentItem(0);
1854
1855     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1856         QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1857         if (anchor)
1858             anchor->clearItem(this);
1859     }
1860
1861     /*
1862         update item anchors that depended on us unless they are our child (and will also be destroyed),
1863         or our sibling, and our parent is also being destroyed.
1864     */
1865     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1866         QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1867         if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
1868             anchor->update();
1869     }
1870
1871     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1872         const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1873         if (change.types & QQuickItemPrivate::Destroyed)
1874             change.listener->itemDestroyed(this);
1875     }
1876
1877     d->changeListeners.clear();
1878
1879     if (d->extra.isAllocated()) {
1880         delete d->extra->contents; d->extra->contents = 0;
1881         delete d->extra->layer; d->extra->layer = 0;
1882     }
1883
1884     delete d->_anchors; d->_anchors = 0;
1885     delete d->_stateGroup; d->_stateGroup = 0;
1886 }
1887
1888 /*!
1889     \qmlproperty enumeration QtQuick2::Item::transformOrigin
1890     This property holds the origin point around which scale and rotation transform.
1891
1892     Nine transform origins are available, as shown in the image below.
1893
1894     \image declarative-transformorigin.png
1895
1896     This example rotates an image around its bottom-right corner.
1897     \qml
1898     Image {
1899         source: "myimage.png"
1900         transformOrigin: Item.BottomRight
1901         rotation: 45
1902     }
1903     \endqml
1904
1905     The default transform origin is \c Item.Center.
1906
1907     To set an arbitrary transform origin point use the \l Scale or \l Rotation
1908     transform elements.
1909 */
1910
1911 /*!
1912     \qmlproperty Item QtQuick2::Item::parent
1913     This property holds the parent of the item.
1914 */
1915
1916 /*!
1917     \property QQuickItem::parent
1918     This property holds the parent of the item.
1919 */
1920 void QQuickItem::setParentItem(QQuickItem *parentItem)
1921 {
1922     Q_D(QQuickItem);
1923     if (parentItem == d->parentItem)
1924         return;
1925
1926     if (parentItem) {
1927         QQuickItem *itemAncestor = parentItem->parentItem();
1928         while (itemAncestor != 0) {
1929             if (itemAncestor == this) {
1930                 qWarning("QQuickItem::setParentItem: Parent is already part of this items subtree.");
1931                 return;
1932             }
1933             itemAncestor = itemAncestor->parentItem();
1934         }
1935     }
1936
1937     d->removeFromDirtyList();
1938
1939     QQuickItem *oldParentItem = d->parentItem;
1940     QQuickItem *scopeFocusedItem = 0;
1941
1942     if (oldParentItem) {
1943         QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem);
1944
1945         QQuickItem *scopeItem = 0;
1946
1947         if (hasFocus())
1948             scopeFocusedItem = this;
1949         else if (!isFocusScope() && d->subFocusItem)
1950             scopeFocusedItem = d->subFocusItem;
1951
1952         if (scopeFocusedItem) {
1953             scopeItem = oldParentItem;
1954             while (!scopeItem->isFocusScope() && scopeItem->parentItem())
1955                 scopeItem = scopeItem->parentItem();
1956             if (d->canvas) {
1957                 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1958                                                                 QQuickCanvasPrivate::DontChangeFocusProperty);
1959                 if (scopeFocusedItem != this)
1960                     QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, true);
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 QRectF QQuickItem::boundingRect() const
3781 {
3782     Q_D(const QQuickItem);
3783     return QRectF(0, 0, d->width, d->height);
3784 }
3785
3786 /*! \internal */
3787 QRectF QQuickItem::clipRect() const
3788 {
3789     Q_D(const QQuickItem);
3790     return QRectF(0, 0, d->width, d->height);
3791 }
3792
3793
3794 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3795 {
3796     Q_D(const QQuickItem);
3797     return d->origin();
3798 }
3799
3800 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3801 {
3802     Q_D(QQuickItem);
3803     if (origin == d->origin())
3804         return;
3805
3806     d->extra.value().origin = origin;
3807     d->dirty(QQuickItemPrivate::TransformOrigin);
3808
3809     emit transformOriginChanged(d->origin());
3810 }
3811
3812 QPointF QQuickItem::transformOriginPoint() const
3813 {
3814     Q_D(const QQuickItem);
3815     if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
3816         return d->extra->userTransformOriginPoint;
3817     return d->computeTransformOrigin();
3818 }
3819
3820 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3821 {
3822     Q_D(QQuickItem);
3823     if (d->extra.value().userTransformOriginPoint == point)
3824         return;
3825
3826     d->extra->userTransformOriginPoint = point;
3827     d->dirty(QQuickItemPrivate::TransformOrigin);
3828 }
3829
3830 qreal QQuickItem::z() const
3831 {
3832     Q_D(const QQuickItem);
3833     return d->z();
3834 }
3835
3836 void QQuickItem::setZ(qreal v)
3837 {
3838     Q_D(QQuickItem);
3839     if (d->z() == v)
3840         return;
3841
3842     d->extra.value().z = v;
3843
3844     d->dirty(QQuickItemPrivate::ZValue);
3845     if (d->parentItem) {
3846         QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3847         QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3848     }
3849
3850     emit zChanged();
3851
3852     if (d->extra.isAllocated() && d->extra->layer)
3853         d->extra->layer->updateZ();
3854 }
3855
3856
3857 /*!
3858   \qmlproperty real QtQuick2::Item::rotation
3859   This property holds the rotation of the item in degrees clockwise.
3860
3861   This specifies how many degrees to rotate the item around its transformOrigin.
3862   The default rotation is 0 degrees (i.e. not rotated at all).
3863
3864   \table
3865   \row
3866   \li \image declarative-rotation.png
3867   \li
3868   \qml
3869   Rectangle {
3870       color: "blue"
3871       width: 100; height: 100
3872       Rectangle {
3873           color: "red"
3874           x: 25; y: 25; width: 50; height: 50
3875           rotation: 30
3876       }
3877   }
3878   \endqml
3879   \endtable
3880
3881   \sa transform, Rotation
3882 */
3883
3884 /*!
3885   \qmlproperty real QtQuick2::Item::scale
3886   This property holds the scale of the item.
3887
3888   A scale of less than 1 means the item will be displayed smaller than
3889   normal, and a scale of greater than 1 means the item will be
3890   displayed larger than normal.  A negative scale means the item will
3891   be mirrored.
3892
3893   By default, items are displayed at a scale of 1 (i.e. at their
3894   normal size).
3895
3896   Scaling is from the item's transformOrigin.
3897
3898   \table
3899   \row
3900   \li \image declarative-scale.png
3901   \li
3902   \qml
3903   Rectangle {
3904       color: "blue"
3905       width: 100; height: 100
3906       Rectangle {
3907           color: "green"
3908           width: 25; height: 25
3909       }
3910       Rectangle {
3911           color: "red"
3912           x: 25; y: 25; width: 50; height: 50
3913           scale: 1.4
3914       }
3915   }
3916   \endqml
3917   \endtable
3918
3919   \sa transform, Scale
3920 */
3921
3922 /*!
3923   \qmlproperty real QtQuick2::Item::opacity
3924
3925   This property holds the opacity of the item.  Opacity is specified as a
3926   number between 0 (fully transparent) and 1 (fully opaque).  The default is 1.
3927
3928   When this property is set, the specified opacity is also applied
3929   individually to child items.  In almost all cases this is what you want,
3930   but in some cases it may produce undesired results. For example in the
3931   second set of rectangles below, the red rectangle has specified an opacity
3932   of 0.5, which affects the opacity of its blue child rectangle even though
3933   the child has not specified an opacity.
3934
3935   \table
3936   \row
3937   \li \image declarative-item_opacity1.png
3938   \li
3939   \qml
3940     Item {
3941         Rectangle {
3942             color: "red"
3943             width: 100; height: 100
3944             Rectangle {
3945                 color: "blue"
3946                 x: 50; y: 50; width: 100; height: 100
3947             }
3948         }
3949     }
3950   \endqml
3951   \row
3952   \li \image declarative-item_opacity2.png
3953   \li
3954   \qml
3955     Item {
3956         Rectangle {
3957             opacity: 0.5
3958             color: "red"
3959             width: 100; height: 100
3960             Rectangle {
3961                 color: "blue"
3962                 x: 50; y: 50; width: 100; height: 100
3963             }
3964         }
3965     }
3966   \endqml
3967   \endtable
3968
3969   If an item's opacity is set to 0, the item will no longer receive mouse
3970   events, but will continue to receive key events and will retain the keyboard
3971   \l focus if it has been set. (In contrast, setting the \l visible property
3972   to \c false stops both mouse and keyboard events, and also removes focus
3973   from the item.)
3974 */
3975
3976 /*!
3977   Returns a value indicating whether mouse input should
3978   remain with this item exclusively.
3979
3980   \sa setKeepMouseGrab()
3981  */
3982
3983 qreal QQuickItem::rotation() const
3984 {
3985     Q_D(const QQuickItem);
3986     return d->rotation();
3987 }
3988
3989 void QQuickItem::setRotation(qreal r)
3990 {
3991     Q_D(QQuickItem);
3992     if (d->rotation() == r)
3993         return;
3994
3995     d->extra.value().rotation = r;
3996
3997     d->dirty(QQuickItemPrivate::BasicTransform);
3998
3999     d->itemChange(ItemRotationHasChanged, r);
4000
4001     emit rotationChanged();
4002 }
4003
4004 qreal QQuickItem::scale() const
4005 {
4006     Q_D(const QQuickItem);
4007     return d->scale();
4008 }
4009
4010 void QQuickItem::setScale(qreal s)
4011 {
4012     Q_D(QQuickItem);
4013     if (d->scale() == s)
4014         return;
4015
4016     d->extra.value().scale = s;
4017
4018     d->dirty(QQuickItemPrivate::BasicTransform);
4019
4020     emit scaleChanged();
4021 }
4022
4023 qreal QQuickItem::opacity() const
4024 {
4025     Q_D(const QQuickItem);
4026     return d->opacity();
4027 }
4028
4029 void QQuickItem::setOpacity(qreal o)
4030 {
4031     Q_D(QQuickItem);
4032     if (d->opacity() == o)
4033         return;
4034
4035     d->extra.value().opacity = o;
4036
4037     d->dirty(QQuickItemPrivate::OpacityValue);
4038
4039     d->itemChange(ItemOpacityHasChanged, o);
4040
4041     emit opacityChanged();
4042 }
4043
4044 bool QQuickItem::isVisible() const
4045 {
4046     Q_D(const QQuickItem);
4047     return d->effectiveVisible;
4048 }
4049
4050 void QQuickItem::setVisible(bool v)
4051 {
4052     Q_D(QQuickItem);
4053     if (v == d->explicitVisible)
4054         return;
4055
4056     d->explicitVisible = v;
4057
4058     const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
4059     if (childVisibilityChanged && d->parentItem)
4060         emit d->parentItem->visibleChildrenChanged();   // signal the parent, not this!
4061 }
4062
4063 bool QQuickItem::isEnabled() const
4064 {
4065     Q_D(const QQuickItem);
4066     return d->effectiveEnable;
4067 }
4068
4069 void QQuickItem::setEnabled(bool e)
4070 {
4071     Q_D(QQuickItem);
4072     if (e == d->explicitEnable)
4073         return;
4074
4075     d->explicitEnable = e;
4076
4077     QQuickItem *scope = parentItem();
4078     while (scope && !scope->isFocusScope())
4079         scope = scope->parentItem();
4080
4081     d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
4082 }
4083
4084 bool QQuickItemPrivate::calcEffectiveVisible() const
4085 {
4086     // XXX todo - Should the effective visible of an element with no parent just be the current
4087     // effective visible?  This would prevent pointless re-processing in the case of an element
4088     // moving to/from a no-parent situation, but it is different from what graphics view does.
4089     return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
4090 }
4091
4092 bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
4093 {
4094     Q_Q(QQuickItem);
4095
4096     if (newEffectiveVisible && !explicitVisible) {
4097         // This item locally overrides visibility
4098         return false;   // effective visibility didn't change
4099     }
4100
4101     if (newEffectiveVisible == effectiveVisible) {
4102         // No change necessary
4103         return false;   // effective visibility didn't change
4104     }
4105
4106     effectiveVisible = newEffectiveVisible;
4107     dirty(Visible);
4108     if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4109
4110     if (canvas) {
4111         QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4112         if (canvasPriv->mouseGrabberItem == q)
4113             q->ungrabMouse();
4114     }
4115
4116     bool childVisibilityChanged = false;
4117     for (int ii = 0; ii < childItems.count(); ++ii)
4118         childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
4119
4120     itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
4121 #ifndef QT_NO_ACCESSIBILITY
4122     if (isAccessible) {
4123         QAccessibleEvent ev(q, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide);
4124         QAccessible::updateAccessibility(&ev);
4125     }
4126 #endif
4127     emit q->visibleChanged();
4128     if (childVisibilityChanged)
4129         emit q->visibleChildrenChanged();
4130
4131     return true;    // effective visibility DID change
4132 }
4133
4134 bool QQuickItemPrivate::calcEffectiveEnable() const
4135 {
4136     // XXX todo - Should the effective enable of an element with no parent just be the current
4137     // effective enable?  This would prevent pointless re-processing in the case of an element
4138     // moving to/from a no-parent situation, but it is different from what graphics view does.
4139     return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
4140 }
4141
4142 void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
4143 {
4144     Q_Q(QQuickItem);
4145
4146     if (newEffectiveEnable && !explicitEnable) {
4147         // This item locally overrides enable
4148         return;
4149     }
4150
4151     if (newEffectiveEnable == effectiveEnable) {
4152         // No change necessary
4153         return;
4154     }
4155
4156     effectiveEnable = newEffectiveEnable;
4157
4158     if (canvas) {
4159         QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
4160         if (canvasPriv->mouseGrabberItem == q)
4161             q->ungrabMouse();
4162         if (scope && !effectiveEnable && activeFocus) {
4163             canvasPriv->clearFocusInScope(
4164                     scope, q,  QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4165         }
4166     }
4167
4168     for (int ii = 0; ii < childItems.count(); ++ii) {
4169         QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
4170                 (flags & QQuickItem::ItemIsFocusScope) && scope ? q : scope, newEffectiveEnable);
4171     }
4172
4173     if (canvas && scope && effectiveEnable && focus) {
4174         QQuickCanvasPrivate::get(canvas)->setFocusInScope(
4175                 scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
4176     }
4177
4178     emit q->enabledChanged();
4179 }
4180
4181 QString QQuickItemPrivate::dirtyToString() const
4182 {
4183 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
4184     if (!rv.isEmpty()) \
4185         rv.append(QLatin1String("|")); \
4186     rv.append(QLatin1String(#value)); \
4187 }
4188
4189 //    QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
4190     QString rv;
4191
4192     DIRTY_TO_STRING(TransformOrigin);
4193     DIRTY_TO_STRING(Transform);
4194     DIRTY_TO_STRING(BasicTransform);
4195     DIRTY_TO_STRING(Position);
4196     DIRTY_TO_STRING(Size);
4197     DIRTY_TO_STRING(ZValue);
4198     DIRTY_TO_STRING(Content);
4199     DIRTY_TO_STRING(Smooth);
4200     DIRTY_TO_STRING(OpacityValue);
4201     DIRTY_TO_STRING(ChildrenChanged);
4202     DIRTY_TO_STRING(ChildrenStackingChanged);
4203     DIRTY_TO_STRING(ParentChanged);
4204     DIRTY_TO_STRING(Clip);
4205     DIRTY_TO_STRING(Canvas);
4206     DIRTY_TO_STRING(EffectReference);
4207     DIRTY_TO_STRING(Visible);
4208     DIRTY_TO_STRING(HideReference);
4209     DIRTY_TO_STRING(PerformanceHints);
4210
4211     return rv;
4212 }
4213
4214 void QQuickItemPrivate::dirty(DirtyType type)
4215 {
4216     Q_Q(QQuickItem);
4217     if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4218         transformChanged();
4219
4220     if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
4221         dirtyAttributes |= type;
4222         if (canvas) {
4223             addToDirtyList();
4224             QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
4225         }
4226     }
4227 }
4228
4229 void QQuickItemPrivate::addToDirtyList()
4230 {
4231     Q_Q(QQuickItem);
4232
4233     Q_ASSERT(canvas);
4234     if (!prevDirtyItem) {
4235         Q_ASSERT(!nextDirtyItem);
4236
4237         QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
4238         nextDirtyItem = p->dirtyItemList;
4239         if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4240         prevDirtyItem = &p->dirtyItemList;
4241         p->dirtyItemList = q;
4242         p->dirtyItem(q);
4243     }
4244     Q_ASSERT(prevDirtyItem);
4245 }
4246
4247 void QQuickItemPrivate::removeFromDirtyList()
4248 {
4249     if (prevDirtyItem) {
4250         if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4251         *prevDirtyItem = nextDirtyItem;
4252         prevDirtyItem = 0;
4253         nextDirtyItem = 0;
4254     }
4255     Q_ASSERT(!prevDirtyItem);
4256     Q_ASSERT(!nextDirtyItem);
4257 }
4258
4259 void QQuickItemPrivate::refFromEffectItem(bool hide)
4260 {
4261     ++extra.value().effectRefCount;
4262     if (1 == extra->effectRefCount) {
4263         dirty(EffectReference);
4264         if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4265     }
4266     if (hide) {
4267         if (++extra->hideRefCount == 1)
4268             dirty(HideReference);
4269     }
4270 }
4271
4272 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4273 {
4274     Q_ASSERT(extra->effectRefCount);
4275     --extra->effectRefCount;
4276     if (0 == extra->effectRefCount) {
4277         dirty(EffectReference);
4278         if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4279     }
4280     if (unhide) {
4281         if (--extra->hideRefCount == 0)
4282             dirty(HideReference);
4283     }
4284 }
4285
4286 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4287 {
4288     Q_Q(QQuickItem);
4289     switch (change) {
4290     case QQuickItem::ItemChildAddedChange:
4291         q->itemChange(change, data);
4292         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4293             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4294             if (change.types & QQuickItemPrivate::Children) {
4295                 change.listener->itemChildAdded(q, data.item);
4296             }
4297         }
4298         break;
4299     case QQuickItem::ItemChildRemovedChange:
4300         q->itemChange(change, data);
4301         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4302             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4303             if (change.types & QQuickItemPrivate::Children) {
4304                 change.listener->itemChildRemoved(q, data.item);
4305             }
4306         }
4307         break;
4308     case QQuickItem::ItemSceneChange:
4309         q->itemChange(change, data);
4310         break;
4311     case QQuickItem::ItemVisibleHasChanged:
4312         q->itemChange(change, data);
4313         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4314             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4315             if (change.types & QQuickItemPrivate::Visibility) {
4316                 change.listener->itemVisibilityChanged(q);
4317             }
4318         }
4319         break;
4320     case QQuickItem::ItemParentHasChanged:
4321         q->itemChange(change, data);
4322         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4323             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4324             if (change.types & QQuickItemPrivate::Parent) {
4325                 change.listener->itemParentChanged(q, data.item);
4326             }
4327         }
4328         break;
4329     case QQuickItem::ItemOpacityHasChanged:
4330         q->itemChange(change, data);
4331         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4332             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4333             if (change.types & QQuickItemPrivate::Opacity) {
4334                 change.listener->itemOpacityChanged(q);
4335             }
4336         }
4337         break;
4338     case QQuickItem::ItemActiveFocusHasChanged:
4339         q->itemChange(change, data);
4340         break;
4341     case QQuickItem::ItemRotationHasChanged:
4342         q->itemChange(change, data);
4343         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4344             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4345             if (change.types & QQuickItemPrivate::Rotation) {
4346                 change.listener->itemRotationChanged(q);
4347             }
4348         }
4349         break;
4350     }
4351 }
4352
4353 /*!
4354     \property QQuickItem::smooth
4355     \brief whether the item is smoothed or not.
4356
4357     Primarily used in image based elements to decide if the item should use smooth
4358     sampling or not. Smooth sampling is performed using linear interpolation, while
4359     non-smooth is performed using nearest neighbor.
4360
4361     In Qt Quick 2.0, this property has minimal impact on performance.
4362
4363     By default is true.
4364 */
4365
4366 /*!
4367     Returns true if the item should be drawn with antialiasing and
4368     smooth pixmap filtering, false otherwise.
4369
4370     The default is false.
4371
4372     \sa setSmooth()
4373 */
4374 bool QQuickItem::smooth() const
4375 {
4376     Q_D(const QQuickItem);
4377     return d->smooth;
4378 }
4379
4380 /*!
4381     Sets whether the item should be drawn with antialiasing and
4382     smooth pixmap filtering to \a smooth.
4383
4384     \sa smooth()
4385 */
4386 void QQuickItem::setSmooth(bool smooth)
4387 {
4388     Q_D(QQuickItem);
4389     if (d->smooth == smooth)
4390         return;
4391
4392     d->smooth = smooth;
4393     d->dirty(QQuickItemPrivate::Smooth);
4394
4395     emit smoothChanged(smooth);
4396 }
4397
4398 QQuickItem::Flags QQuickItem::flags() const
4399 {
4400     Q_D(const QQuickItem);
4401     return (QQuickItem::Flags)d->flags;
4402 }
4403
4404 void QQuickItem::setFlag(Flag flag, bool enabled)
4405 {
4406     Q_D(QQuickItem);
4407     if (enabled)
4408         setFlags((Flags)(d->flags | (quint32)flag));
4409     else
4410         setFlags((Flags)(d->flags & ~(quint32)flag));
4411 }
4412
4413 void QQuickItem::setFlags(Flags flags)
4414 {
4415     Q_D(QQuickItem);
4416
4417     if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4418         if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4419             qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
4420             flags &= ~ItemIsFocusScope;
4421         } else if (d->flags & ItemIsFocusScope) {
4422             qWarning("QQuickItem: Cannot unset FocusScope flag.");
4423             flags |= ItemIsFocusScope;
4424         }
4425     }
4426
4427     if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4428         d->dirty(QQuickItemPrivate::Clip);
4429
4430     d->flags = flags;
4431 }
4432
4433 qreal QQuickItem::x() const
4434 {
4435     Q_D(const QQuickItem);
4436     return d->x;
4437 }
4438
4439 qreal QQuickItem::y() const
4440 {
4441     Q_D(const QQuickItem);
4442     return d->y;
4443 }
4444
4445 QPointF QQuickItem::pos() const
4446 {
4447     Q_D(const QQuickItem);
4448     return QPointF(d->x, d->y);
4449 }
4450
4451 void QQuickItem::setX(qreal v)
4452 {
4453     Q_D(QQuickItem);
4454     if (d->x == v)
4455         return;
4456
4457     qreal oldx = d->x;
4458     d->x = v;
4459
4460     d->dirty(QQuickItemPrivate::Position);
4461
4462     geometryChanged(QRectF(x(), y(), width(), height()),
4463                     QRectF(oldx, y(), width(), height()));
4464 }
4465
4466 void QQuickItem::setY(qreal v)
4467 {
4468     Q_D(QQuickItem);
4469     if (d->y == v)
4470         return;
4471
4472     qreal oldy = d->y;
4473     d->y = v;
4474
4475     d->dirty(QQuickItemPrivate::Position);
4476
4477     geometryChanged(QRectF(x(), y(), width(), height()),
4478                     QRectF(x(), oldy, width(), height()));
4479 }
4480
4481 void QQuickItem::setPos(const QPointF &pos)
4482 {
4483     Q_D(QQuickItem);
4484     if (QPointF(d->x, d->y) == pos)
4485         return;
4486
4487     qreal oldx = d->x;
4488     qreal oldy = d->y;
4489
4490     d->x = pos.x();
4491     d->y = pos.y();
4492
4493     d->dirty(QQuickItemPrivate::Position);
4494
4495     geometryChanged(QRectF(x(), y(), width(), height()),
4496                     QRectF(oldx, oldy, width(), height()));
4497 }
4498
4499 qreal QQuickItem::width() const
4500 {
4501     Q_D(const QQuickItem);
4502     return d->width;
4503 }
4504
4505 void QQuickItem::setWidth(qreal w)
4506 {
4507     Q_D(QQuickItem);
4508     if (qIsNaN(w))
4509         return;
4510
4511     d->widthValid = true;
4512     if (d->width == w)
4513         return;
4514
4515     qreal oldWidth = d->width;
4516     d->width = w;
4517
4518     d->dirty(QQuickItemPrivate::Size);
4519
4520     geometryChanged(QRectF(x(), y(), width(), height()),
4521                     QRectF(x(), y(), oldWidth, height()));
4522 }
4523
4524 void QQuickItem::resetWidth()
4525 {
4526     Q_D(QQuickItem);
4527     d->widthValid = false;
4528     setImplicitWidth(implicitWidth());
4529 }
4530
4531 void QQuickItemPrivate::implicitWidthChanged()
4532 {
4533     Q_Q(QQuickItem);
4534     for (int ii = 0; ii < changeListeners.count(); ++ii) {
4535         const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4536         if (change.types & QQuickItemPrivate::ImplicitWidth) {
4537             change.listener->itemImplicitWidthChanged(q);
4538         }
4539     }
4540     emit q->implicitWidthChanged();
4541 }
4542
4543 qreal QQuickItemPrivate::getImplicitWidth() const
4544 {
4545     return implicitWidth;
4546 }
4547 /*!
4548     Returns the width of the item that is implied by other properties that determine the content.
4549 */
4550 qreal QQuickItem::implicitWidth() const
4551 {
4552     Q_D(const QQuickItem);
4553     return d->getImplicitWidth();
4554 }
4555
4556 /*!
4557     \qmlproperty real QtQuick2::Item::implicitWidth
4558     \qmlproperty real QtQuick2::Item::implicitHeight
4559
4560     Defines the natural width or height of the Item if no \l width or \l height is specified.
4561
4562     The default implicit size for most items is 0x0, however some elements have an inherent
4563     implicit size which cannot be overridden, e.g. Image, Text.
4564
4565     Setting the implicit size is useful for defining components that have a preferred size
4566     based on their content, for example:
4567
4568     \qml
4569     // Label.qml
4570     import QtQuick 2.0
4571
4572     Item {
4573         property alias icon: image.source
4574         property alias label: text.text
4575         implicitWidth: text.implicitWidth + image.implicitWidth
4576         implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4577         Image { id: image }
4578         Text {
4579             id: text
4580             wrapMode: Text.Wrap
4581             anchors.left: image.right; anchors.right: parent.right
4582             anchors.verticalCenter: parent.verticalCenter
4583         }
4584     }
4585     \endqml
4586
4587     \b Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4588     incurs a performance penalty as the text must be laid out twice.
4589 */
4590
4591 /*!
4592     Sets the implied width of the item to \a w.
4593     This is the width implied by other properties that determine the content.
4594 */
4595 void QQuickItem::setImplicitWidth(qreal w)
4596 {
4597     Q_D(QQuickItem);
4598     bool changed = w != d->implicitWidth;
4599     d->implicitWidth = w;
4600     if (d->width == w || widthValid()) {
4601         if (changed)
4602             d->implicitWidthChanged();
4603         return;
4604     }
4605
4606     qreal oldWidth = d->width;
4607     d->width = w;
4608
4609     d->dirty(QQuickItemPrivate::Size);
4610
4611     geometryChanged(QRectF(x(), y(), width(), height()),
4612                     QRectF(x(), y(), oldWidth, height()));
4613
4614     if (changed)
4615         d->implicitWidthChanged();
4616 }
4617
4618 /*!
4619     Returns whether the width property has been set explicitly.
4620 */
4621 bool QQuickItem::widthValid() const
4622 {
4623     Q_D(const QQuickItem);
4624     return d->widthValid;
4625 }
4626
4627 qreal QQuickItem::height() const
4628 {
4629     Q_D(const QQuickItem);
4630     return d->height;
4631 }
4632
4633 void QQuickItem::setHeight(qreal h)
4634 {
4635     Q_D(QQuickItem);
4636     if (qIsNaN(h))
4637         return;
4638
4639     d->heightValid = true;
4640     if (d->height == h)
4641         return;
4642
4643     qreal oldHeight = d->height;
4644     d->height = h;
4645
4646     d->dirty(QQuickItemPrivate::Size);
4647
4648     geometryChanged(QRectF(x(), y(), width(), height()),
4649                     QRectF(x(), y(), width(), oldHeight));
4650 }
4651
4652 void QQuickItem::resetHeight()
4653 {
4654     Q_D(QQuickItem);
4655     d->heightValid = false;
4656     setImplicitHeight(implicitHeight());
4657 }
4658
4659 void QQuickItemPrivate::implicitHeightChanged()
4660 {
4661     Q_Q(QQuickItem);
4662     for (int ii = 0; ii < changeListeners.count(); ++ii) {
4663         const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4664         if (change.types & QQuickItemPrivate::ImplicitHeight) {
4665             change.listener->itemImplicitHeightChanged(q);
4666         }
4667     }
4668     emit q->implicitHeightChanged();
4669 }
4670
4671 qreal QQuickItemPrivate::getImplicitHeight() const
4672 {
4673     return implicitHeight;
4674 }
4675
4676 /*!
4677     Returns the height of the item that is implied by other properties that determine the content.
4678 */
4679 qreal QQuickItem::implicitHeight() const
4680 {
4681     Q_D(const QQuickItem);
4682     return d->getImplicitHeight();
4683 }
4684
4685
4686 /*!
4687     Sets the implied height of the item to \a h.
4688     This is the height implied by other properties that determine the content.
4689 */
4690 void QQuickItem::setImplicitHeight(qreal h)
4691 {
4692     Q_D(QQuickItem);
4693     bool changed = h != d->implicitHeight;
4694     d->implicitHeight = h;
4695     if (d->height == h || heightValid()) {
4696         if (changed)
4697             d->implicitHeightChanged();
4698         return;
4699     }
4700
4701     qreal oldHeight = d->height;
4702     d->height = h;
4703
4704     d->dirty(QQuickItemPrivate::Size);
4705
4706     geometryChanged(QRectF(x(), y(), width(), height()),
4707                     QRectF(x(), y(), width(), oldHeight));
4708
4709     if (changed)
4710         d->implicitHeightChanged();
4711 }
4712
4713 void QQuickItem::setImplicitSize(qreal w, qreal h)
4714 {
4715     Q_D(QQuickItem);
4716     bool wChanged = w != d->implicitWidth;
4717     bool hChanged = h != d->implicitHeight;
4718
4719     d->implicitWidth = w;
4720     d->implicitHeight = h;
4721
4722     bool wDone = false;
4723     bool hDone = false;
4724     if (d->width == w || widthValid()) {
4725         if (wChanged)
4726             d->implicitWidthChanged();
4727         wDone = true;
4728     }
4729     if (d->height == h || heightValid()) {
4730         if (hChanged)
4731             d->implicitHeightChanged();
4732         hDone = true;
4733     }
4734     if (wDone && hDone)
4735         return;
4736
4737     qreal oldWidth = d->width;
4738     qreal oldHeight = d->height;
4739     if (!wDone)
4740         d->width = w;
4741     if (!hDone)
4742         d->height = h;
4743
4744     d->dirty(QQuickItemPrivate::Size);
4745
4746     geometryChanged(QRectF(x(), y(), width(), height()),
4747                     QRectF(x(), y(), oldWidth, oldHeight));
4748
4749     if (!wDone && wChanged)
4750         d->implicitWidthChanged();
4751     if (!hDone && hChanged)
4752         d->implicitHeightChanged();
4753 }
4754
4755 /*!
4756     Returns whether the height property has been set explicitly.
4757 */
4758 bool QQuickItem::heightValid() const
4759 {
4760     Q_D(const QQuickItem);
4761     return d->heightValid;
4762 }
4763
4764 void QQuickItem::setSize(const QSizeF &size)
4765 {
4766     Q_D(QQuickItem);
4767     d->heightValid = true;
4768     d->widthValid = true;
4769
4770     if (QSizeF(d->width, d->height) == size)
4771         return;
4772
4773     qreal oldHeight = d->height;
4774     qreal oldWidth = d->width;
4775     d->height = size.height();
4776     d->width = size.width();
4777
4778     d->dirty(QQuickItemPrivate::Size);
4779
4780     geometryChanged(QRectF(x(), y(), width(), height()),
4781                     QRectF(x(), y(), oldWidth, oldHeight));
4782 }
4783
4784 bool QQuickItem::hasActiveFocus() const
4785 {
4786     Q_D(const QQuickItem);
4787     return d->activeFocus;
4788 }
4789
4790 bool QQuickItem::hasFocus() const
4791 {
4792     Q_D(const QQuickItem);
4793     return d->focus;
4794 }
4795
4796 void QQuickItem::setFocus(bool focus)
4797 {
4798     Q_D(QQuickItem);
4799     if (d->focus == focus)
4800         return;
4801
4802     if (d->canvas || d->parentItem) {
4803         // Need to find our nearest focus scope
4804         QQuickItem *scope = parentItem();
4805         while (scope && !scope->isFocusScope() && scope->parentItem())
4806             scope = scope->parentItem();
4807         if (d->canvas) {
4808             if (focus)
4809                 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4810             else
4811                 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4812         } else {
4813             // do the focus changes from setFocusInScope/clearFocusInScope that are
4814             // unrelated to a canvas
4815             QVarLengthArray<QQuickItem *, 20> changed;
4816             QQuickItem *oldSubFocusItem = QQuickItemPrivate::get(scope)->subFocusItem;
4817             if (oldSubFocusItem) {
4818                 QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(scope, false);
4819                 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
4820                 changed << oldSubFocusItem;
4821             }
4822             d->updateSubFocusItem(scope, focus);
4823
4824             d->focus = focus;
4825             changed << this;
4826             emit focusChanged(focus);
4827
4828             QQuickCanvasPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
4829         }
4830     } else {
4831         d->focus = focus;
4832         emit focusChanged(focus);
4833     }
4834 }
4835
4836 bool QQuickItem::isFocusScope() const
4837 {
4838     return flags() & ItemIsFocusScope;
4839 }
4840
4841 QQuickItem *QQuickItem::scopedFocusItem() const
4842 {
4843     Q_D(const QQuickItem);
4844     if (!isFocusScope())
4845         return 0;
4846     else
4847         return d->subFocusItem;
4848 }
4849
4850
4851 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
4852 {
4853     Q_D(const QQuickItem);
4854     return d->acceptedMouseButtons();
4855 }
4856
4857 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4858 {
4859     Q_D(QQuickItem);
4860     if (buttons & Qt::LeftButton)
4861         d->extra.setFlag();
4862     else
4863         d->extra.clearFlag();
4864
4865     buttons &= ~Qt::LeftButton;
4866     if (buttons || d->extra.isAllocated())
4867         d->extra.value().acceptedMouseButtons = buttons;
4868 }
4869
4870 bool QQuickItem::filtersChildMouseEvents() const
4871 {
4872     Q_D(const QQuickItem);
4873     return d->filtersChildMouseEvents;
4874 }
4875
4876 void QQuickItem::setFiltersChildMouseEvents(bool filter)
4877 {
4878     Q_D(QQuickItem);
4879     d->filtersChildMouseEvents = filter;
4880 }
4881
4882 bool QQuickItem::isUnderMouse() const
4883 {
4884     Q_D(const QQuickItem);
4885     if (!d->canvas)
4886         return false;
4887
4888     QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition;
4889     return contains(mapFromScene(cursorPos)); // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
4890 }
4891
4892 bool QQuickItem::acceptHoverEvents() const
4893 {
4894     Q_D(const QQuickItem);
4895     return d->hoverEnabled;
4896 }
4897
4898 void QQuickItem::setAcceptHoverEvents(bool enabled)
4899 {
4900     Q_D(QQuickItem);
4901     d->hoverEnabled = enabled;
4902 }
4903
4904 void QQuickItem::grabMouse()
4905 {
4906     Q_D(QQuickItem);
4907     if (!d->canvas)
4908         return;
4909     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4910     if (canvasPriv->mouseGrabberItem == this)
4911         return;
4912
4913     QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
4914     canvasPriv->mouseGrabberItem = this;
4915     if (oldGrabber) {
4916         QEvent ev(QEvent::UngrabMouse);
4917         d->canvas->sendEvent(oldGrabber, &ev);
4918     }
4919 }
4920
4921 void QQuickItem::ungrabMouse()
4922 {
4923     Q_D(QQuickItem);
4924     if (!d->canvas)
4925         return;
4926     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4927     if (canvasPriv->mouseGrabberItem != this) {
4928         qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
4929         return;
4930     }
4931
4932     canvasPriv->mouseGrabberItem = 0;
4933
4934     QEvent ev(QEvent::UngrabMouse);
4935     d->canvas->sendEvent(this, &ev);
4936 }
4937
4938 bool QQuickItem::keepMouseGrab() const
4939 {
4940     Q_D(const QQuickItem);
4941     return d->keepMouse;
4942 }
4943
4944 /*!
4945   The flag indicating whether the mouse should remain
4946   with this item is set to \a keep.
4947
4948   This is useful for items that wish to grab and keep mouse
4949   interaction following a predefined gesture.  For example,
4950   an item that is interested in horizontal mouse movement
4951   may set keepMouseGrab to true once a threshold has been
4952   exceeded.  Once keepMouseGrab has been set to true, filtering
4953   items will not react to mouse events.
4954
4955   If the item does not indicate that it wishes to retain mouse grab,
4956   a filtering item may steal the grab. For example, Flickable may attempt
4957   to steal a mouse grab if it detects that the user has begun to
4958   move the viewport.
4959
4960   \sa keepMouseGrab()
4961  */
4962 void QQuickItem::setKeepMouseGrab(bool keep)
4963 {
4964     Q_D(QQuickItem);
4965     d->keepMouse = keep;
4966 }
4967
4968 /*!
4969     Grabs the touch points specified by \a ids.
4970
4971     These touch points will be owned by the item until
4972     they are released. Alternatively, the grab can be stolen
4973     by a filtering item like Flickable. Use setKeepTouchGrab()
4974     to prevent the grab from being stolen.
4975
4976     \sa ungrabTouchPoints(), setKeepTouchGrab()
4977 */
4978 void QQuickItem::grabTouchPoints(const QList<int> &ids)
4979 {
4980     Q_D(QQuickItem);
4981     if (!d->canvas)
4982         return;
4983     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4984
4985     QSet<QQuickItem*> ungrab;
4986     for (int i = 0; i < ids.count(); ++i) {
4987         QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
4988         if (oldGrabber == this)
4989             return;
4990
4991         canvasPriv->itemForTouchPointId[ids.at(i)] = this;
4992         if (oldGrabber)
4993             ungrab.insert(oldGrabber);
4994     }
4995     foreach (QQuickItem *oldGrabber, ungrab)
4996         oldGrabber->touchUngrabEvent();
4997 }
4998
4999 /*!
5000     Ungrabs the touch points owned by this item.
5001
5002     \sa grabTouchPoints()
5003 */
5004 void QQuickItem::ungrabTouchPoints()
5005 {
5006     Q_D(QQuickItem);
5007     if (!d->canvas)
5008         return;
5009     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5010
5011     QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
5012     while (i.hasNext()) {
5013         i.next();
5014         if (i.value() == this)
5015             i.remove();
5016     }
5017     touchUngrabEvent();
5018 }
5019
5020 /*!
5021     Returns a value indicating whether the touch points grabbed by this item
5022     should remain with this item exclusively.
5023
5024     \sa setKeepTouchGrab(), keepMouseGrab()
5025 */
5026 bool QQuickItem::keepTouchGrab() const
5027 {
5028     Q_D(const QQuickItem);
5029     return d->keepTouch;
5030 }
5031
5032 /*!
5033   The flag indicating whether the touch points grabbed
5034   by this item should remain with this item is set to \a keep.
5035
5036   This is useful for items that wish to grab and keep specific touch
5037   points following a predefined gesture.  For example,
5038   an item that is interested in horizontal touch point movement
5039   may set setKeepTouchGrab to true once a threshold has been
5040   exceeded.  Once setKeepTouchGrab has been set to true, filtering
5041   items will not react to the relevant touch points.
5042
5043   If the item does not indicate that it wishes to retain touch point grab,
5044   a filtering item may steal the grab. For example, Flickable may attempt
5045   to steal a touch point grab if it detects that the user has begun to
5046   move the viewport.
5047
5048   \sa keepTouchGrab(), setKeepMouseGrab()
5049  */
5050 void QQuickItem::setKeepTouchGrab(bool keep)
5051 {
5052     Q_D(QQuickItem);
5053     d->keepTouch = keep;
5054 }
5055
5056 /*!
5057   Returns true if this item contains \a point, which is in local coordinates;
5058   returns false otherwise.
5059
5060   This function can be overwritten in order to handle point collisions in items
5061   with custom shapes. The default implementation checks if the point is inside
5062   the item's bounding rect.
5063
5064   Note that it's normally used to check if the item is under the mouse cursor,
5065   and for that reason, the implementation of this function should be as light-weight
5066   as possible.
5067 */
5068 bool QQuickItem::contains(const QPointF &point) const
5069 {
5070     Q_D(const QQuickItem);
5071     return QRectF(0, 0, d->width, d->height).contains(point);
5072 }
5073
5074 /*!
5075     \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
5076
5077     Maps the point (\a x, \a y), which is in \a item's coordinate system, to
5078     this item's coordinate system, and returns an object with \c x and \c y
5079     properties matching the mapped coordinate.
5080
5081     If \a item is a \c null value, this maps the point from the coordinate
5082     system of the root QML view.
5083 */
5084 /*!
5085     \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
5086
5087     Maps the point (\a x, \a y), which is in this item's coordinate system, to
5088     \a item's coordinate system, and returns an object with \c x and \c y
5089     properties matching the mapped coordinate.
5090
5091     If \a item is a \c null value, this maps \a x and \a y to the coordinate
5092     system of the root QML view.
5093 */
5094 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
5095 {
5096     QPointF p = mapToScene(point);
5097     if (item)
5098         p = item->mapFromScene(p);
5099     return p;
5100 }
5101
5102 QPointF QQuickItem::mapToScene(const QPointF &point) const
5103 {
5104     Q_D(const QQuickItem);
5105     return d->itemToCanvasTransform().map(point);
5106 }
5107
5108 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
5109 {
5110     Q_D(const QQuickItem);
5111     QTransform t = d->itemToCanvasTransform();
5112     if (item)
5113         t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
5114     return t.mapRect(rect);
5115 }
5116
5117 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
5118 {
5119     Q_D(const QQuickItem);
5120     return d->itemToCanvasTransform().mapRect(rect);
5121 }
5122
5123 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
5124 {
5125     QPointF p = item?item->mapToScene(point):point;
5126     return mapFromScene(p);
5127 }
5128
5129 QPointF QQuickItem::mapFromScene(const QPointF &point) const
5130 {
5131     Q_D(const QQuickItem);
5132     return d->canvasToItemTransform().map(point);
5133 }
5134
5135 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
5136 {
5137     Q_D(const QQuickItem);
5138     QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
5139     t *= d->canvasToItemTransform();
5140     return t.mapRect(rect);
5141 }
5142
5143 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
5144 {
5145     Q_D(const QQuickItem);
5146     return d->canvasToItemTransform().mapRect(rect);
5147 }
5148
5149
5150 /*!
5151     \qmlmethod QtQuick2::Item::forceActiveFocus()
5152
5153     Forces active focus on the item.
5154
5155     This method sets focus on the item and makes sure that all the focus scopes
5156     higher in the object hierarchy are also given the focus.
5157 */
5158
5159 /*!
5160     Forces active focus on the item.
5161
5162     This method sets focus on the item and makes sure that all the focus scopes
5163     higher in the object hierarchy are also given the focus.
5164 */
5165
5166 /*!
5167   \qmlmethod QtQuick2::Item::childAt(real x, real y)
5168
5169   Returns the visible child item at point (\a x, \a y), which is in this
5170   item's coordinate system, or \c null if there is no such item.
5171 */
5172
5173 /*!
5174   Returns the visible child item at point (\a x, \a y), which is in this
5175   item's coordinate system, or 0 if there is no such item.
5176 */
5177
5178 /*!
5179   \qmlproperty list<State> QtQuick2::Item::states
5180   This property holds a list of states defined by the item.
5181
5182   \qml
5183   Item {
5184       states: [
5185           State {
5186               // ...
5187           },
5188           State {
5189               // ...
5190           }
5191           // ...
5192       ]
5193   }
5194   \endqml
5195
5196   \sa {qmlstate}{States}
5197 */
5198 /*!
5199   \qmlproperty list<Transition> QtQuick2::Item::transitions
5200   This property holds a list of transitions defined by the item.
5201
5202   \qml
5203   Item {
5204       transitions: [
5205           Transition {
5206               // ...
5207           },
5208           Transition {
5209               // ...
5210           }
5211           // ...
5212       ]
5213   }
5214   \endqml
5215
5216   \sa {QML Animation and Transitions}{Transitions}
5217 */
5218 /*
5219   \qmlproperty list<Filter> QtQuick2::Item::filter
5220   This property holds a list of graphical filters to be applied to the item.
5221
5222   \l {Filter}{Filters} include things like \l {Blur}{blurring}
5223   the item, or giving it a \l Reflection.  Some
5224   filters may not be available on all canvases; if a filter is not
5225   available on a certain canvas, it will simply not be applied for
5226   that canvas (but the QML will still be considered valid).
5227
5228   \qml
5229   Item {
5230       filter: [
5231           Blur {
5232               // ...
5233           },
5234           Reflection {
5235               // ...
5236           }
5237           // ...
5238       ]
5239   }
5240   \endqml
5241 */
5242
5243 /*!
5244   \qmlproperty bool QtQuick2::Item::clip
5245   This property holds whether clipping is enabled. The default clip value is \c false.
5246
5247   If clipping is enabled, an item will clip its own painting, as well
5248   as the painting of its children, to its bounding rectangle.
5249
5250   Non-rectangular clipping regions are not supported for performance reasons.
5251 */
5252
5253 /*!
5254   \property QQuickItem::clip
5255   This property holds whether clipping is enabled. The default clip value is \c false.
5256
5257   If clipping is enabled, an item will clip its own painting, as well
5258   as the painting of its children, to its bounding rectangle. If you set
5259   clipping during an item's paint operation, remember to re-set it to
5260   prevent clipping the rest of your scene.
5261
5262   Non-rectangular clipping regions are not supported for performance reasons.
5263 */
5264
5265 /*!
5266   \qmlproperty string QtQuick2::Item::state
5267
5268   This property holds the name of the current state of the item.
5269
5270   This property is often used in scripts to change between states. For
5271   example:
5272
5273   \js
5274   function toggle() {
5275       if (button.state == 'On')
5276           button.state = 'Off';
5277       else
5278           button.state = 'On';
5279   }
5280   \endjs
5281
5282   If the item is in its base state (i.e. no explicit state has been
5283   set), \c state will be a blank string. Likewise, you can return an
5284   item to its base state by setting its current state to \c ''.
5285
5286   \sa {qmlstates}{States}
5287 */
5288
5289 /*!
5290   \qmlproperty list<Transform> QtQuick2::Item::transform
5291   This property holds the list of transformations to apply.
5292
5293   For more information see \l Transform.
5294 */
5295
5296 /*!
5297     \enum QQuickItem::TransformOrigin
5298
5299     Controls the point about which simple transforms like scale apply.
5300
5301     \value TopLeft The top-left corner of the item.
5302     \value Top The center point of the top of the item.
5303     \value TopRight The top-right corner of the item.
5304     \value Left The left most point of the vertical middle.
5305     \value Center The center of the item.
5306     \value Right The right most point of the vertical middle.
5307     \value BottomLeft The bottom-left corner of the item.
5308     \value Bottom The center point of the bottom of the item.
5309     \value BottomRight The bottom-right corner of the item.
5310 */
5311
5312
5313 /*!
5314   \qmlproperty bool QtQuick2::Item::activeFocus
5315
5316   This property indicates whether the item has active focus.
5317
5318   An item with active focus will receive keyboard input,
5319   or is a FocusScope ancestor of the item that will receive keyboard input.
5320
5321   Usually, activeFocus is gained by setting focus on an item and its enclosing
5322   FocusScopes. In the following example \c input will have activeFocus.
5323   \qml
5324   Rectangle {
5325       FocusScope {
5326           focus: true
5327           TextInput {
5328               id: input
5329               focus: true
5330           }
5331       }
5332   }
5333   \endqml
5334
5335   \sa focus, {qmlfocus}{Keyboard Focus}
5336 */
5337
5338 /*!
5339   \qmlproperty bool QtQuick2::Item::focus
5340   This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5341   will gain active focus when the enclosing focus scope gains active focus.
5342   In the following example, \c input will be given active focus when \c scope gains active focus.
5343   \qml
5344   Rectangle {
5345       FocusScope {
5346           id: scope
5347           TextInput {
5348               id: input
5349               focus: true
5350           }
5351       }
5352   }
5353   \endqml
5354
5355   For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5356   On a practical level, that means the following QML will give active focus to \c input on startup.
5357
5358   \qml
5359   Rectangle {
5360       TextInput {
5361           id: input
5362           focus: true
5363       }
5364   }
5365   \endqml
5366
5367   \sa activeFocus, {qmlfocus}{Keyboard Focus}
5368 */
5369
5370
5371 /*!
5372   \property QQuickItem::anchors
5373   \internal
5374 */
5375
5376 /*!
5377   \property QQuickItem::left
5378   \internal
5379 */
5380
5381 /*!
5382   \property QQuickItem::right
5383   \internal
5384 */
5385
5386 /*!
5387   \property QQuickItem::horizontalCenter
5388   \internal
5389 */
5390
5391 /*!
5392   \property QQuickItem::top
5393   \internal
5394 */
5395
5396 /*!
5397   \property QQuickItem::bottom
5398   \internal
5399 */
5400
5401 /*!
5402   \property QQuickItem::verticalCenter
5403   \internal
5404 */
5405
5406 /*!
5407   \property QQuickItem::focus
5408   \internal
5409 */
5410
5411 /*!
5412   \property QQuickItem::transform
5413   \internal
5414 */
5415
5416 /*!
5417   \property QQuickItem::transformOrigin
5418   \internal
5419 */
5420
5421 /*!
5422   \property QQuickItem::activeFocus
5423   \internal
5424 */
5425
5426 /*!
5427   \property QQuickItem::baseline
5428   \internal
5429 */
5430
5431 /*!
5432   \property QQuickItem::data
5433   \internal
5434 */
5435
5436 /*!
5437   \property QQuickItem::resources
5438   \internal
5439 */
5440
5441 /*!
5442   \property QQuickItem::state
5443   \internal
5444 */
5445
5446 /*!
5447   \property QQuickItem::states
5448   \internal
5449 */
5450
5451 /*!
5452   \property QQuickItem::transformOriginPoint
5453   \internal
5454 */
5455
5456 /*!
5457   \property QQuickItem::transitions
5458   \internal
5459 */
5460
5461 bool QQuickItem::event(QEvent *ev)
5462 {
5463 #if 0
5464     if (ev->type() == QEvent::PolishRequest) {
5465         Q_D(QQuickItem);
5466         d->polishScheduled = false;
5467         updatePolish();
5468         return true;
5469     } else {
5470         return QObject::event(ev);
5471     }
5472 #endif
5473     if (ev->type() == QEvent::InputMethodQuery) {
5474         QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5475         Qt::InputMethodQueries queries = query->queries();
5476         for (uint i = 0; i < 32; ++i) {
5477             Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5478             if (q) {
5479                 QVariant v = inputMethodQuery(q);
5480                 query->setValue(q, v);
5481             }
5482         }
5483         query->accept();
5484         return true;
5485     } else if (ev->type() == QEvent::InputMethod) {
5486         inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5487         return true;
5488     }
5489     return QObject::event(ev);
5490 }
5491
5492 #ifndef QT_NO_DEBUG_STREAM
5493 QDebug operator<<(QDebug debug, QQuickItem *item)
5494 {
5495     if (!item) {
5496         debug << "QQuickItem(0)";
5497         return debug;
5498     }
5499
5500     debug << item->metaObject()->className() << "(this =" << ((void*)item)
5501           << ", name=" << item->objectName()
5502           << ", parent =" << ((void*)item->parentItem())
5503           << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5504           << ", z =" << item->z() << ')';
5505     return debug;
5506 }
5507 #endif
5508
5509 qint64 QQuickItemPrivate::consistentTime = -1;
5510 void QQuickItemPrivate::setConsistentTime(qint64 t)
5511 {
5512     consistentTime = t;
5513 }
5514
5515 class QElapsedTimerConsistentTimeHack
5516 {
5517 public:
5518     void start() {
5519         t1 = QQuickItemPrivate::consistentTime;
5520         t2 = 0;
5521     }
5522     qint64 elapsed() {
5523         return QQuickItemPrivate::consistentTime - t1;
5524     }
5525     qint64 restart() {
5526         qint64 val = QQuickItemPrivate::consistentTime - t1;
5527         t1 = QQuickItemPrivate::consistentTime;
5528         t2 = 0;
5529         return val;
5530     }
5531
5532 private:
5533     qint64 t1;
5534     qint64 t2;
5535 };
5536
5537 void QQuickItemPrivate::start(QElapsedTimer &t)
5538 {
5539     if (QQuickItemPrivate::consistentTime == -1)
5540         t.start();
5541     else
5542         ((QElapsedTimerConsistentTimeHack*)&t)->start();
5543 }
5544
5545 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5546 {
5547     if (QQuickItemPrivate::consistentTime == -1)
5548         return t.elapsed();
5549     else
5550         return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5551 }
5552
5553 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5554 {
5555     if (QQuickItemPrivate::consistentTime == -1)
5556         return t.restart();
5557     else
5558         return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5559 }
5560
5561 /*!
5562     \fn bool QQuickItem::isTextureProvider() const
5563
5564     Returns true if this item is a texture provider. The default
5565     implementation returns false.
5566
5567     This function can be called from any thread.
5568  */
5569
5570 bool QQuickItem::isTextureProvider() const
5571 {
5572     Q_D(const QQuickItem);
5573     return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5574            d->extra->layer->effectSource()->isTextureProvider() : false;
5575 }
5576
5577 /*!
5578     \fn QSGTextureProvider *QQuickItem::textureProvider() const
5579
5580     Returns the texture provider for an item. The default implementation
5581     returns 0.
5582
5583     This function may only be called on the rendering thread.
5584  */
5585
5586 QSGTextureProvider *QQuickItem::textureProvider() const
5587 {
5588     Q_D(const QQuickItem);
5589     return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5590            d->extra->layer->effectSource()->textureProvider() : 0;
5591 }
5592
5593 QQuickItemLayer *QQuickItemPrivate::layer() const
5594 {
5595     if (!extra.isAllocated() || !extra->layer) {
5596         extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
5597         if (!componentComplete)
5598             extra->layer->classBegin();
5599     }
5600     return extra->layer;
5601 }
5602
5603 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
5604     : m_item(item)
5605     , m_enabled(false)
5606     , m_mipmap(false)
5607     , m_smooth(false)
5608     , m_componentComplete(true)
5609     , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
5610     , m_format(QQuickShaderEffectSource::RGBA)
5611     , m_name("source")
5612     , m_effectComponent(0)
5613     , m_effect(0)
5614     , m_effectSource(0)
5615 {
5616 }
5617
5618 QQuickItemLayer::~QQuickItemLayer()
5619 {
5620     delete m_effectSource;
5621     delete m_effect;
5622 }
5623
5624
5625
5626 /*!
5627     \qmlproperty bool QtQuick2::Item::layer.enabled
5628
5629     Holds wether the item is layered or not. Layering is disabled by default.
5630
5631     A layered item is rendered into an offscreen surface and cached until
5632     it is changed. Enabling layering for complex QML item hierarchies can
5633     some times be an optimization.
5634
5635     None of the other layer properties have any effect when the layer
5636     is disabled.
5637  */
5638
5639 void QQuickItemLayer::setEnabled(bool e)
5640 {
5641     if (e == m_enabled)
5642         return;
5643     m_enabled = e;
5644     if (m_componentComplete) {
5645         if (m_enabled)
5646             activate();
5647         else
5648             deactivate();
5649     }
5650
5651     emit enabledChanged(e);
5652 }
5653
5654 void QQuickItemLayer::classBegin()
5655 {
5656     Q_ASSERT(!m_effectSource);
5657     Q_ASSERT(!m_effect);
5658     m_componentComplete = false;
5659 }
5660
5661 void QQuickItemLayer::componentComplete()
5662 {
5663     Q_ASSERT(!m_componentComplete);
5664     m_componentComplete = true;
5665     if (m_enabled)
5666         activate();
5667 }
5668
5669 void QQuickItemLayer::activate()
5670 {
5671     Q_ASSERT(!m_effectSource);
5672     m_effectSource = new QQuickShaderEffectSource();
5673
5674     QQuickItem *parentItem = m_item->parentItem();
5675     if (parentItem) {
5676         m_effectSource->setParentItem(parentItem);
5677         m_effectSource->stackAfter(m_item);
5678     }
5679
5680     m_effectSource->setSourceItem(m_item);
5681     m_effectSource->setHideSource(true);
5682     m_effectSource->setSmooth(m_smooth);
5683     m_effectSource->setTextureSize(m_size);
5684     m_effectSource->setSourceRect(m_sourceRect);
5685     m_effectSource->setMipmap(m_mipmap);
5686     m_effectSource->setWrapMode(m_wrapMode);
5687     m_effectSource->setFormat(m_format);
5688
5689     if (m_effectComponent)
5690         activateEffect();
5691
5692     m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5693
5694     updateZ();
5695     updateGeometry();
5696     updateOpacity();
5697     updateMatrix();
5698
5699     QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5700     id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5701 }
5702
5703 void QQuickItemLayer::deactivate()
5704 {
5705     Q_ASSERT(m_effectSource);
5706
5707     if (m_effectComponent)
5708         deactivateEffect();
5709
5710     delete m_effectSource;
5711     m_effectSource = 0;
5712
5713     QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5714     id->removeItemChangeListener(this,  QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5715 }
5716
5717 void QQuickItemLayer::activateEffect()
5718 {
5719     Q_ASSERT(m_effectSource);
5720     Q_ASSERT(m_effectComponent);
5721     Q_ASSERT(!m_effect);
5722
5723     QObject *created = m_effectComponent->beginCreate(m_effectComponent->creationContext());
5724     m_effect = qobject_cast<QQuickItem *>(created);
5725     if (!m_effect) {
5726         qWarning("Item: layer.effect is not a QML Item.");
5727         m_effectComponent->completeCreate();
5728         delete created;
5729         return;
5730     }
5731     QQuickItem *parentItem = m_item->parentItem();
5732     if (parentItem) {
5733         m_effect->setParentItem(parentItem);
5734         m_effect->stackAfter(m_effectSource);
5735     }
5736     m_effect->setVisible(m_item->isVisible());
5737     m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
5738     m_effectComponent->completeCreate();
5739 }
5740
5741 void QQuickItemLayer::deactivateEffect()
5742 {
5743     Q_ASSERT(m_effectSource);
5744     Q_ASSERT(m_effectComponent);
5745
5746     delete m_effect;
5747     m_effect = 0;
5748 }
5749
5750
5751 /*!
5752     \qmlproperty Component QtQuick2::Item::layer.effect
5753
5754     Holds the effect that is applied to this layer.
5755
5756     The effect is typically a \l ShaderEffect component, although any \l Item component can be
5757     assigned. The effect should have a source texture property with a name matching \l samplerName.
5758
5759     \sa samplerName
5760  */
5761
5762 void QQuickItemLayer::setEffect(QQmlComponent *component)
5763 {
5764     if (component == m_effectComponent)
5765         return;
5766
5767     bool updateNeeded = false;
5768     if (m_effectSource && m_effectComponent) {
5769         deactivateEffect();
5770         updateNeeded = true;
5771     }
5772
5773     m_effectComponent = component;
5774
5775     if (m_effectSource && m_effectComponent) {
5776         activateEffect();
5777         updateNeeded = true;
5778     }
5779
5780     if (updateNeeded) {
5781         updateZ();
5782         updateGeometry();
5783         updateOpacity();
5784         updateMatrix();
5785         m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5786     }
5787
5788     emit effectChanged(component);
5789 }
5790
5791
5792 /*!
5793     \qmlproperty bool QtQuick2::Item::layer.mipmap
5794
5795     If this property is true, mipmaps are generated for the texture.
5796
5797     \note Some OpenGL ES 2 implementations do not support mipmapping of
5798     non-power-of-two textures.
5799  */
5800
5801 void QQuickItemLayer::setMipmap(bool mipmap)
5802 {
5803     if (mipmap == m_mipmap)
5804         return;
5805     m_mipmap = mipmap;
5806
5807     if (m_effectSource)
5808         m_effectSource->setMipmap(m_mipmap);
5809
5810     emit mipmapChanged(mipmap);
5811 }
5812
5813
5814 /*!
5815     \qmlproperty enumeration QtQuick2::Item::layer.format
5816
5817     This property defines the internal OpenGL format of the texture.
5818     Modifying this property makes most sense when the \a layer.effect is also
5819     specified. Depending on the OpenGL implementation, this property might
5820     allow you to save some texture memory.
5821
5822     \list
5823     \li ShaderEffectSource.Alpha - GL_ALPHA
5824     \li ShaderEffectSource.RGB - GL_RGB
5825     \li ShaderEffectSource.RGBA - GL_RGBA
5826     \endlist
5827
5828     \note Some OpenGL implementations do not support the GL_ALPHA format.
5829  */
5830
5831 void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
5832 {
5833     if (f == m_format)
5834         return;
5835     m_format = f;
5836
5837     if (m_effectSource)
5838         m_effectSource->setFormat(m_format);
5839
5840     emit formatChanged(m_format);
5841 }
5842
5843
5844 /*!
5845     \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
5846
5847     This property defines which rectangular area of the \l sourceItem to
5848     render into the texture. The source rectangle can be larger than
5849     \l sourceItem itself. If the rectangle is null, which is the default,
5850     the whole \l sourceItem is rendered to texture.
5851  */
5852
5853 void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
5854 {
5855     if (sourceRect == m_sourceRect)
5856         return;
5857     m_sourceRect = sourceRect;
5858
5859     if (m_effectSource)
5860         m_effectSource->setSourceRect(m_sourceRect);
5861
5862     emit sourceRectChanged(sourceRect);
5863 }
5864
5865
5866
5867 /*!
5868     \qmlproperty bool QtQuick2::Item::layer.smooth
5869
5870     Holds whether the layer is smoothly transformed.
5871  */
5872
5873 void QQuickItemLayer::setSmooth(bool s)
5874 {
5875     if (m_smooth == s)
5876         return;
5877     m_smooth = s;
5878
5879     if (m_effectSource)
5880         m_effectSource->setSmooth(m_smooth);
5881
5882     emit smoothChanged(s);
5883 }
5884
5885
5886
5887 /*!
5888     \qmlproperty size QtQuick2::Item::layer.textureSize
5889
5890     This property holds the requested pixel size of the layers texture. If it is empty,
5891     which is the default, the size of the item is used.
5892
5893     \note Some platforms have a limit on how small framebuffer objects can be,
5894     which means the actual texture size might be larger than the requested
5895     size.
5896  */
5897
5898 void QQuickItemLayer::setSize(const QSize &size)
5899 {
5900     if (size == m_size)
5901         return;
5902     m_size = size;
5903
5904     if (m_effectSource)
5905         m_effectSource->setTextureSize(size);
5906
5907     emit sizeChanged(size);
5908 }
5909
5910
5911
5912 /*!
5913     \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
5914
5915     This property defines the OpenGL wrap modes associated with the texture.
5916     Modifying this property makes most sense when the \a layer.effect is
5917     specified.
5918
5919     \list
5920     \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
5921     \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
5922     \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
5923     \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
5924     \endlist
5925
5926     \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
5927     wrap mode with non-power-of-two textures.
5928  */
5929
5930 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
5931 {
5932     if (mode == m_wrapMode)
5933         return;
5934     m_wrapMode = mode;
5935
5936     if (m_effectSource)
5937         m_effectSource->setWrapMode(m_wrapMode);
5938
5939     emit wrapModeChanged(mode);
5940 }
5941
5942 /*!
5943     \qmlproperty string QtQuick2::Item::layer.samplerName
5944
5945     Holds the name of the effect's source texture property.
5946
5947     samplerName needs to match the name of the effect's source texture property
5948     so that the Item can pass the layer's offscreen surface to the effect correctly.
5949
5950     \sa effect, ShaderEffect
5951  */
5952
5953 void QQuickItemLayer::setName(const QByteArray &name) {
5954     if (m_name == name)
5955         return;
5956     if (m_effect) {
5957         m_effect->setProperty(m_name, QVariant());
5958         m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
5959     }
5960     m_name = name;
5961     emit nameChanged(name);
5962 }
5963
5964 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
5965 {
5966     Q_UNUSED(item)
5967     updateOpacity();
5968 }
5969
5970 void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
5971 {
5972     updateGeometry();
5973 }
5974
5975 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
5976 {
5977     Q_UNUSED(item)
5978     Q_ASSERT(item == m_item);
5979     Q_ASSERT(parent != m_effectSource);
5980     Q_ASSERT(parent == 0 || parent != m_effect);
5981
5982     m_effectSource->setParentItem(parent);
5983     if (parent)
5984         m_effectSource->stackAfter(m_item);
5985
5986     if (m_effect) {
5987         m_effect->setParentItem(parent);
5988         if (parent)
5989             m_effect->stackAfter(m_effectSource);
5990     }
5991 }
5992
5993 void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
5994 {
5995     m_effectSource->stackAfter(m_item);
5996     if (m_effect)
5997         m_effect->stackAfter(m_effectSource);
5998 }
5999
6000 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
6001 {
6002     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6003     Q_ASSERT(l);
6004     l->setVisible(m_item->isVisible());
6005 }
6006
6007 void QQuickItemLayer::updateZ()
6008 {
6009     if (!m_componentComplete || !m_enabled)
6010         return;
6011     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6012     Q_ASSERT(l);
6013     l->setZ(m_item->z());
6014 }
6015
6016 void QQuickItemLayer::updateOpacity()
6017 {
6018     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6019     Q_ASSERT(l);
6020     l->setOpacity(m_item->opacity());
6021 }
6022
6023 void QQuickItemLayer::updateGeometry()
6024 {
6025     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6026     Q_ASSERT(l);
6027     QRectF bounds = m_item->clipRect();
6028     l->setWidth(bounds.width());
6029     l->setHeight(bounds.height());
6030     l->setX(bounds.x() + m_item->x());
6031     l->setY(bounds.y() + m_item->y());
6032 }
6033
6034 void QQuickItemLayer::updateMatrix()
6035 {
6036     // Called directly from transformChanged(), so needs some extra
6037     // checks.
6038     if (!m_componentComplete || !m_enabled)
6039         return;
6040     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6041     Q_ASSERT(l);
6042     QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
6043     l->setScale(m_item->scale());
6044     l->setRotation(m_item->rotation());
6045     ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
6046     if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
6047         ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
6048     ld->dirty(QQuickItemPrivate::Transform);
6049 }
6050
6051 QQuickItemPrivate::ExtraData::ExtraData()
6052 : z(0), scale(1), rotation(0), opacity(1),
6053   contents(0), screenAttached(0), layoutDirectionAttached(0),
6054   keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
6055   opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
6056   acceptedMouseButtons(0), origin(QQuickItem::Center)
6057 {
6058 }
6059
6060 QT_END_NAMESPACE
6061
6062 #include <moc_qquickitem.cpp>