Fix eliding when text width is reset by an implicitWidth change.
[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         if (d->width == w || widthValid())
4604             return;
4605         changed = false;
4606     }
4607
4608     qreal oldWidth = d->width;
4609     d->width = w;
4610
4611     d->dirty(QQuickItemPrivate::Size);
4612
4613     geometryChanged(QRectF(x(), y(), width(), height()),
4614                     QRectF(x(), y(), oldWidth, height()));
4615
4616     if (changed)
4617         d->implicitWidthChanged();
4618 }
4619
4620 /*!
4621     Returns whether the width property has been set explicitly.
4622 */
4623 bool QQuickItem::widthValid() const
4624 {
4625     Q_D(const QQuickItem);
4626     return d->widthValid;
4627 }
4628
4629 qreal QQuickItem::height() const
4630 {
4631     Q_D(const QQuickItem);
4632     return d->height;
4633 }
4634
4635 void QQuickItem::setHeight(qreal h)
4636 {
4637     Q_D(QQuickItem);
4638     if (qIsNaN(h))
4639         return;
4640
4641     d->heightValid = true;
4642     if (d->height == h)
4643         return;
4644
4645     qreal oldHeight = d->height;
4646     d->height = h;
4647
4648     d->dirty(QQuickItemPrivate::Size);
4649
4650     geometryChanged(QRectF(x(), y(), width(), height()),
4651                     QRectF(x(), y(), width(), oldHeight));
4652 }
4653
4654 void QQuickItem::resetHeight()
4655 {
4656     Q_D(QQuickItem);
4657     d->heightValid = false;
4658     setImplicitHeight(implicitHeight());
4659 }
4660
4661 void QQuickItemPrivate::implicitHeightChanged()
4662 {
4663     Q_Q(QQuickItem);
4664     for (int ii = 0; ii < changeListeners.count(); ++ii) {
4665         const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4666         if (change.types & QQuickItemPrivate::ImplicitHeight) {
4667             change.listener->itemImplicitHeightChanged(q);
4668         }
4669     }
4670     emit q->implicitHeightChanged();
4671 }
4672
4673 qreal QQuickItemPrivate::getImplicitHeight() const
4674 {
4675     return implicitHeight;
4676 }
4677
4678 /*!
4679     Returns the height of the item that is implied by other properties that determine the content.
4680 */
4681 qreal QQuickItem::implicitHeight() const
4682 {
4683     Q_D(const QQuickItem);
4684     return d->getImplicitHeight();
4685 }
4686
4687
4688 /*!
4689     Sets the implied height of the item to \a h.
4690     This is the height implied by other properties that determine the content.
4691 */
4692 void QQuickItem::setImplicitHeight(qreal h)
4693 {
4694     Q_D(QQuickItem);
4695     bool changed = h != d->implicitHeight;
4696     d->implicitHeight = h;
4697     if (d->height == h || heightValid()) {
4698         if (changed)
4699             d->implicitHeightChanged();
4700         if (d->height == h || heightValid())
4701             return;
4702         changed = false;
4703     }
4704
4705     qreal oldHeight = d->height;
4706     d->height = h;
4707
4708     d->dirty(QQuickItemPrivate::Size);
4709
4710     geometryChanged(QRectF(x(), y(), width(), height()),
4711                     QRectF(x(), y(), width(), oldHeight));
4712
4713     if (changed)
4714         d->implicitHeightChanged();
4715 }
4716
4717 void QQuickItem::setImplicitSize(qreal w, qreal h)
4718 {
4719     Q_D(QQuickItem);
4720     bool wChanged = w != d->implicitWidth;
4721     bool hChanged = h != d->implicitHeight;
4722
4723     d->implicitWidth = w;
4724     d->implicitHeight = h;
4725
4726     bool wDone = false;
4727     bool hDone = false;
4728     if (d->width == w || widthValid()) {
4729         if (wChanged)
4730             d->implicitWidthChanged();
4731         wDone = d->width == w || widthValid();
4732         wChanged = false;
4733     }
4734     if (d->height == h || heightValid()) {
4735         if (hChanged)
4736             d->implicitHeightChanged();
4737         hDone = d->height == h || heightValid();
4738         hChanged = false;
4739     }
4740     if (wDone && hDone)
4741         return;
4742
4743     qreal oldWidth = d->width;
4744     qreal oldHeight = d->height;
4745     if (!wDone)
4746         d->width = w;
4747     if (!hDone)
4748         d->height = h;
4749
4750     d->dirty(QQuickItemPrivate::Size);
4751
4752     geometryChanged(QRectF(x(), y(), width(), height()),
4753                     QRectF(x(), y(), oldWidth, oldHeight));
4754
4755     if (!wDone && wChanged)
4756         d->implicitWidthChanged();
4757     if (!hDone && hChanged)
4758         d->implicitHeightChanged();
4759 }
4760
4761 /*!
4762     Returns whether the height property has been set explicitly.
4763 */
4764 bool QQuickItem::heightValid() const
4765 {
4766     Q_D(const QQuickItem);
4767     return d->heightValid;
4768 }
4769
4770 void QQuickItem::setSize(const QSizeF &size)
4771 {
4772     Q_D(QQuickItem);
4773     d->heightValid = true;
4774     d->widthValid = true;
4775
4776     if (QSizeF(d->width, d->height) == size)
4777         return;
4778
4779     qreal oldHeight = d->height;
4780     qreal oldWidth = d->width;
4781     d->height = size.height();
4782     d->width = size.width();
4783
4784     d->dirty(QQuickItemPrivate::Size);
4785
4786     geometryChanged(QRectF(x(), y(), width(), height()),
4787                     QRectF(x(), y(), oldWidth, oldHeight));
4788 }
4789
4790 bool QQuickItem::hasActiveFocus() const
4791 {
4792     Q_D(const QQuickItem);
4793     return d->activeFocus;
4794 }
4795
4796 bool QQuickItem::hasFocus() const
4797 {
4798     Q_D(const QQuickItem);
4799     return d->focus;
4800 }
4801
4802 void QQuickItem::setFocus(bool focus)
4803 {
4804     Q_D(QQuickItem);
4805     if (d->focus == focus)
4806         return;
4807
4808     if (d->canvas || d->parentItem) {
4809         // Need to find our nearest focus scope
4810         QQuickItem *scope = parentItem();
4811         while (scope && !scope->isFocusScope() && scope->parentItem())
4812             scope = scope->parentItem();
4813         if (d->canvas) {
4814             if (focus)
4815                 QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4816             else
4817                 QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4818         } else {
4819             // do the focus changes from setFocusInScope/clearFocusInScope that are
4820             // unrelated to a canvas
4821             QVarLengthArray<QQuickItem *, 20> changed;
4822             QQuickItem *oldSubFocusItem = QQuickItemPrivate::get(scope)->subFocusItem;
4823             if (oldSubFocusItem) {
4824                 QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(scope, false);
4825                 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
4826                 changed << oldSubFocusItem;
4827             }
4828             d->updateSubFocusItem(scope, focus);
4829
4830             d->focus = focus;
4831             changed << this;
4832             emit focusChanged(focus);
4833
4834             QQuickCanvasPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
4835         }
4836     } else {
4837         d->focus = focus;
4838         emit focusChanged(focus);
4839     }
4840 }
4841
4842 bool QQuickItem::isFocusScope() const
4843 {
4844     return flags() & ItemIsFocusScope;
4845 }
4846
4847 QQuickItem *QQuickItem::scopedFocusItem() const
4848 {
4849     Q_D(const QQuickItem);
4850     if (!isFocusScope())
4851         return 0;
4852     else
4853         return d->subFocusItem;
4854 }
4855
4856
4857 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
4858 {
4859     Q_D(const QQuickItem);
4860     return d->acceptedMouseButtons();
4861 }
4862
4863 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4864 {
4865     Q_D(QQuickItem);
4866     if (buttons & Qt::LeftButton)
4867         d->extra.setFlag();
4868     else
4869         d->extra.clearFlag();
4870
4871     buttons &= ~Qt::LeftButton;
4872     if (buttons || d->extra.isAllocated())
4873         d->extra.value().acceptedMouseButtons = buttons;
4874 }
4875
4876 bool QQuickItem::filtersChildMouseEvents() const
4877 {
4878     Q_D(const QQuickItem);
4879     return d->filtersChildMouseEvents;
4880 }
4881
4882 void QQuickItem::setFiltersChildMouseEvents(bool filter)
4883 {
4884     Q_D(QQuickItem);
4885     d->filtersChildMouseEvents = filter;
4886 }
4887
4888 bool QQuickItem::isUnderMouse() const
4889 {
4890     Q_D(const QQuickItem);
4891     if (!d->canvas)
4892         return false;
4893
4894     QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition;
4895     return contains(mapFromScene(cursorPos)); // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
4896 }
4897
4898 bool QQuickItem::acceptHoverEvents() const
4899 {
4900     Q_D(const QQuickItem);
4901     return d->hoverEnabled;
4902 }
4903
4904 void QQuickItem::setAcceptHoverEvents(bool enabled)
4905 {
4906     Q_D(QQuickItem);
4907     d->hoverEnabled = enabled;
4908 }
4909
4910 void QQuickItem::grabMouse()
4911 {
4912     Q_D(QQuickItem);
4913     if (!d->canvas)
4914         return;
4915     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4916     if (canvasPriv->mouseGrabberItem == this)
4917         return;
4918
4919     QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
4920     canvasPriv->mouseGrabberItem = this;
4921     if (oldGrabber) {
4922         QEvent ev(QEvent::UngrabMouse);
4923         d->canvas->sendEvent(oldGrabber, &ev);
4924     }
4925 }
4926
4927 void QQuickItem::ungrabMouse()
4928 {
4929     Q_D(QQuickItem);
4930     if (!d->canvas)
4931         return;
4932     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4933     if (canvasPriv->mouseGrabberItem != this) {
4934         qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
4935         return;
4936     }
4937
4938     canvasPriv->mouseGrabberItem = 0;
4939
4940     QEvent ev(QEvent::UngrabMouse);
4941     d->canvas->sendEvent(this, &ev);
4942 }
4943
4944 bool QQuickItem::keepMouseGrab() const
4945 {
4946     Q_D(const QQuickItem);
4947     return d->keepMouse;
4948 }
4949
4950 /*!
4951   The flag indicating whether the mouse should remain
4952   with this item is set to \a keep.
4953
4954   This is useful for items that wish to grab and keep mouse
4955   interaction following a predefined gesture.  For example,
4956   an item that is interested in horizontal mouse movement
4957   may set keepMouseGrab to true once a threshold has been
4958   exceeded.  Once keepMouseGrab has been set to true, filtering
4959   items will not react to mouse events.
4960
4961   If the item does not indicate that it wishes to retain mouse grab,
4962   a filtering item may steal the grab. For example, Flickable may attempt
4963   to steal a mouse grab if it detects that the user has begun to
4964   move the viewport.
4965
4966   \sa keepMouseGrab()
4967  */
4968 void QQuickItem::setKeepMouseGrab(bool keep)
4969 {
4970     Q_D(QQuickItem);
4971     d->keepMouse = keep;
4972 }
4973
4974 /*!
4975     Grabs the touch points specified by \a ids.
4976
4977     These touch points will be owned by the item until
4978     they are released. Alternatively, the grab can be stolen
4979     by a filtering item like Flickable. Use setKeepTouchGrab()
4980     to prevent the grab from being stolen.
4981
4982     \sa ungrabTouchPoints(), setKeepTouchGrab()
4983 */
4984 void QQuickItem::grabTouchPoints(const QList<int> &ids)
4985 {
4986     Q_D(QQuickItem);
4987     if (!d->canvas)
4988         return;
4989     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4990
4991     QSet<QQuickItem*> ungrab;
4992     for (int i = 0; i < ids.count(); ++i) {
4993         QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
4994         if (oldGrabber == this)
4995             return;
4996
4997         canvasPriv->itemForTouchPointId[ids.at(i)] = this;
4998         if (oldGrabber)
4999             ungrab.insert(oldGrabber);
5000     }
5001     foreach (QQuickItem *oldGrabber, ungrab)
5002         oldGrabber->touchUngrabEvent();
5003 }
5004
5005 /*!
5006     Ungrabs the touch points owned by this item.
5007
5008     \sa grabTouchPoints()
5009 */
5010 void QQuickItem::ungrabTouchPoints()
5011 {
5012     Q_D(QQuickItem);
5013     if (!d->canvas)
5014         return;
5015     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
5016
5017     QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
5018     while (i.hasNext()) {
5019         i.next();
5020         if (i.value() == this)
5021             i.remove();
5022     }
5023     touchUngrabEvent();
5024 }
5025
5026 /*!
5027     Returns a value indicating whether the touch points grabbed by this item
5028     should remain with this item exclusively.
5029
5030     \sa setKeepTouchGrab(), keepMouseGrab()
5031 */
5032 bool QQuickItem::keepTouchGrab() const
5033 {
5034     Q_D(const QQuickItem);
5035     return d->keepTouch;
5036 }
5037
5038 /*!
5039   The flag indicating whether the touch points grabbed
5040   by this item should remain with this item is set to \a keep.
5041
5042   This is useful for items that wish to grab and keep specific touch
5043   points following a predefined gesture.  For example,
5044   an item that is interested in horizontal touch point movement
5045   may set setKeepTouchGrab to true once a threshold has been
5046   exceeded.  Once setKeepTouchGrab has been set to true, filtering
5047   items will not react to the relevant touch points.
5048
5049   If the item does not indicate that it wishes to retain touch point grab,
5050   a filtering item may steal the grab. For example, Flickable may attempt
5051   to steal a touch point grab if it detects that the user has begun to
5052   move the viewport.
5053
5054   \sa keepTouchGrab(), setKeepMouseGrab()
5055  */
5056 void QQuickItem::setKeepTouchGrab(bool keep)
5057 {
5058     Q_D(QQuickItem);
5059     d->keepTouch = keep;
5060 }
5061
5062 /*!
5063   Returns true if this item contains \a point, which is in local coordinates;
5064   returns false otherwise.
5065
5066   This function can be overwritten in order to handle point collisions in items
5067   with custom shapes. The default implementation checks if the point is inside
5068   the item's bounding rect.
5069
5070   Note that it's normally used to check if the item is under the mouse cursor,
5071   and for that reason, the implementation of this function should be as light-weight
5072   as possible.
5073 */
5074 bool QQuickItem::contains(const QPointF &point) const
5075 {
5076     Q_D(const QQuickItem);
5077     return QRectF(0, 0, d->width, d->height).contains(point);
5078 }
5079
5080 /*!
5081     \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
5082
5083     Maps the point (\a x, \a y), which is in \a item's coordinate system, to
5084     this item's coordinate system, and returns an object with \c x and \c y
5085     properties matching the mapped coordinate.
5086
5087     If \a item is a \c null value, this maps the point from the coordinate
5088     system of the root QML view.
5089 */
5090 /*!
5091     \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
5092
5093     Maps the point (\a x, \a y), which is in this item's coordinate system, to
5094     \a item's coordinate system, and returns an object with \c x and \c y
5095     properties matching the mapped coordinate.
5096
5097     If \a item is a \c null value, this maps \a x and \a y to the coordinate
5098     system of the root QML view.
5099 */
5100 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
5101 {
5102     QPointF p = mapToScene(point);
5103     if (item)
5104         p = item->mapFromScene(p);
5105     return p;
5106 }
5107
5108 QPointF QQuickItem::mapToScene(const QPointF &point) const
5109 {
5110     Q_D(const QQuickItem);
5111     return d->itemToCanvasTransform().map(point);
5112 }
5113
5114 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
5115 {
5116     Q_D(const QQuickItem);
5117     QTransform t = d->itemToCanvasTransform();
5118     if (item)
5119         t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
5120     return t.mapRect(rect);
5121 }
5122
5123 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
5124 {
5125     Q_D(const QQuickItem);
5126     return d->itemToCanvasTransform().mapRect(rect);
5127 }
5128
5129 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
5130 {
5131     QPointF p = item?item->mapToScene(point):point;
5132     return mapFromScene(p);
5133 }
5134
5135 QPointF QQuickItem::mapFromScene(const QPointF &point) const
5136 {
5137     Q_D(const QQuickItem);
5138     return d->canvasToItemTransform().map(point);
5139 }
5140
5141 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
5142 {
5143     Q_D(const QQuickItem);
5144     QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
5145     t *= d->canvasToItemTransform();
5146     return t.mapRect(rect);
5147 }
5148
5149 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
5150 {
5151     Q_D(const QQuickItem);
5152     return d->canvasToItemTransform().mapRect(rect);
5153 }
5154
5155
5156 /*!
5157     \qmlmethod QtQuick2::Item::forceActiveFocus()
5158
5159     Forces active focus on the item.
5160
5161     This method sets focus on the item and makes sure that all the focus scopes
5162     higher in the object hierarchy are also given the focus.
5163 */
5164
5165 /*!
5166     Forces active focus on the item.
5167
5168     This method sets focus on the item and makes sure that all the focus scopes
5169     higher in the object hierarchy are also given the focus.
5170 */
5171
5172 /*!
5173   \qmlmethod QtQuick2::Item::childAt(real x, real y)
5174
5175   Returns the visible child item at point (\a x, \a y), which is in this
5176   item's coordinate system, or \c null if there is no such item.
5177 */
5178
5179 /*!
5180   Returns the visible child item at point (\a x, \a y), which is in this
5181   item's coordinate system, or 0 if there is no such item.
5182 */
5183
5184 /*!
5185   \qmlproperty list<State> QtQuick2::Item::states
5186   This property holds a list of states defined by the item.
5187
5188   \qml
5189   Item {
5190       states: [
5191           State {
5192               // ...
5193           },
5194           State {
5195               // ...
5196           }
5197           // ...
5198       ]
5199   }
5200   \endqml
5201
5202   \sa {qmlstate}{States}
5203 */
5204 /*!
5205   \qmlproperty list<Transition> QtQuick2::Item::transitions
5206   This property holds a list of transitions defined by the item.
5207
5208   \qml
5209   Item {
5210       transitions: [
5211           Transition {
5212               // ...
5213           },
5214           Transition {
5215               // ...
5216           }
5217           // ...
5218       ]
5219   }
5220   \endqml
5221
5222   \sa {QML Animation and Transitions}{Transitions}
5223 */
5224 /*
5225   \qmlproperty list<Filter> QtQuick2::Item::filter
5226   This property holds a list of graphical filters to be applied to the item.
5227
5228   \l {Filter}{Filters} include things like \l {Blur}{blurring}
5229   the item, or giving it a \l Reflection.  Some
5230   filters may not be available on all canvases; if a filter is not
5231   available on a certain canvas, it will simply not be applied for
5232   that canvas (but the QML will still be considered valid).
5233
5234   \qml
5235   Item {
5236       filter: [
5237           Blur {
5238               // ...
5239           },
5240           Reflection {
5241               // ...
5242           }
5243           // ...
5244       ]
5245   }
5246   \endqml
5247 */
5248
5249 /*!
5250   \qmlproperty bool QtQuick2::Item::clip
5251   This property holds whether clipping is enabled. The default clip value is \c false.
5252
5253   If clipping is enabled, an item will clip its own painting, as well
5254   as the painting of its children, to its bounding rectangle.
5255
5256   Non-rectangular clipping regions are not supported for performance reasons.
5257 */
5258
5259 /*!
5260   \property QQuickItem::clip
5261   This property holds whether clipping is enabled. The default clip value is \c false.
5262
5263   If clipping is enabled, an item will clip its own painting, as well
5264   as the painting of its children, to its bounding rectangle. If you set
5265   clipping during an item's paint operation, remember to re-set it to
5266   prevent clipping the rest of your scene.
5267
5268   Non-rectangular clipping regions are not supported for performance reasons.
5269 */
5270
5271 /*!
5272   \qmlproperty string QtQuick2::Item::state
5273
5274   This property holds the name of the current state of the item.
5275
5276   This property is often used in scripts to change between states. For
5277   example:
5278
5279   \js
5280   function toggle() {
5281       if (button.state == 'On')
5282           button.state = 'Off';
5283       else
5284           button.state = 'On';
5285   }
5286   \endjs
5287
5288   If the item is in its base state (i.e. no explicit state has been
5289   set), \c state will be a blank string. Likewise, you can return an
5290   item to its base state by setting its current state to \c ''.
5291
5292   \sa {qmlstates}{States}
5293 */
5294
5295 /*!
5296   \qmlproperty list<Transform> QtQuick2::Item::transform
5297   This property holds the list of transformations to apply.
5298
5299   For more information see \l Transform.
5300 */
5301
5302 /*!
5303     \enum QQuickItem::TransformOrigin
5304
5305     Controls the point about which simple transforms like scale apply.
5306
5307     \value TopLeft The top-left corner of the item.
5308     \value Top The center point of the top of the item.
5309     \value TopRight The top-right corner of the item.
5310     \value Left The left most point of the vertical middle.
5311     \value Center The center of the item.
5312     \value Right The right most point of the vertical middle.
5313     \value BottomLeft The bottom-left corner of the item.
5314     \value Bottom The center point of the bottom of the item.
5315     \value BottomRight The bottom-right corner of the item.
5316 */
5317
5318
5319 /*!
5320   \qmlproperty bool QtQuick2::Item::activeFocus
5321
5322   This property indicates whether the item has active focus.
5323
5324   An item with active focus will receive keyboard input,
5325   or is a FocusScope ancestor of the item that will receive keyboard input.
5326
5327   Usually, activeFocus is gained by setting focus on an item and its enclosing
5328   FocusScopes. In the following example \c input will have activeFocus.
5329   \qml
5330   Rectangle {
5331       FocusScope {
5332           focus: true
5333           TextInput {
5334               id: input
5335               focus: true
5336           }
5337       }
5338   }
5339   \endqml
5340
5341   \sa focus, {qmlfocus}{Keyboard Focus}
5342 */
5343
5344 /*!
5345   \qmlproperty bool QtQuick2::Item::focus
5346   This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5347   will gain active focus when the enclosing focus scope gains active focus.
5348   In the following example, \c input will be given active focus when \c scope gains active focus.
5349   \qml
5350   Rectangle {
5351       FocusScope {
5352           id: scope
5353           TextInput {
5354               id: input
5355               focus: true
5356           }
5357       }
5358   }
5359   \endqml
5360
5361   For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5362   On a practical level, that means the following QML will give active focus to \c input on startup.
5363
5364   \qml
5365   Rectangle {
5366       TextInput {
5367           id: input
5368           focus: true
5369       }
5370   }
5371   \endqml
5372
5373   \sa activeFocus, {qmlfocus}{Keyboard Focus}
5374 */
5375
5376
5377 /*!
5378   \property QQuickItem::anchors
5379   \internal
5380 */
5381
5382 /*!
5383   \property QQuickItem::left
5384   \internal
5385 */
5386
5387 /*!
5388   \property QQuickItem::right
5389   \internal
5390 */
5391
5392 /*!
5393   \property QQuickItem::horizontalCenter
5394   \internal
5395 */
5396
5397 /*!
5398   \property QQuickItem::top
5399   \internal
5400 */
5401
5402 /*!
5403   \property QQuickItem::bottom
5404   \internal
5405 */
5406
5407 /*!
5408   \property QQuickItem::verticalCenter
5409   \internal
5410 */
5411
5412 /*!
5413   \property QQuickItem::focus
5414   \internal
5415 */
5416
5417 /*!
5418   \property QQuickItem::transform
5419   \internal
5420 */
5421
5422 /*!
5423   \property QQuickItem::transformOrigin
5424   \internal
5425 */
5426
5427 /*!
5428   \property QQuickItem::activeFocus
5429   \internal
5430 */
5431
5432 /*!
5433   \property QQuickItem::baseline
5434   \internal
5435 */
5436
5437 /*!
5438   \property QQuickItem::data
5439   \internal
5440 */
5441
5442 /*!
5443   \property QQuickItem::resources
5444   \internal
5445 */
5446
5447 /*!
5448   \property QQuickItem::state
5449   \internal
5450 */
5451
5452 /*!
5453   \property QQuickItem::states
5454   \internal
5455 */
5456
5457 /*!
5458   \property QQuickItem::transformOriginPoint
5459   \internal
5460 */
5461
5462 /*!
5463   \property QQuickItem::transitions
5464   \internal
5465 */
5466
5467 bool QQuickItem::event(QEvent *ev)
5468 {
5469 #if 0
5470     if (ev->type() == QEvent::PolishRequest) {
5471         Q_D(QQuickItem);
5472         d->polishScheduled = false;
5473         updatePolish();
5474         return true;
5475     } else {
5476         return QObject::event(ev);
5477     }
5478 #endif
5479     if (ev->type() == QEvent::InputMethodQuery) {
5480         QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5481         Qt::InputMethodQueries queries = query->queries();
5482         for (uint i = 0; i < 32; ++i) {
5483             Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5484             if (q) {
5485                 QVariant v = inputMethodQuery(q);
5486                 query->setValue(q, v);
5487             }
5488         }
5489         query->accept();
5490         return true;
5491     } else if (ev->type() == QEvent::InputMethod) {
5492         inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5493         return true;
5494     }
5495     return QObject::event(ev);
5496 }
5497
5498 #ifndef QT_NO_DEBUG_STREAM
5499 QDebug operator<<(QDebug debug, QQuickItem *item)
5500 {
5501     if (!item) {
5502         debug << "QQuickItem(0)";
5503         return debug;
5504     }
5505
5506     debug << item->metaObject()->className() << "(this =" << ((void*)item)
5507           << ", name=" << item->objectName()
5508           << ", parent =" << ((void*)item->parentItem())
5509           << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5510           << ", z =" << item->z() << ')';
5511     return debug;
5512 }
5513 #endif
5514
5515 qint64 QQuickItemPrivate::consistentTime = -1;
5516 void QQuickItemPrivate::setConsistentTime(qint64 t)
5517 {
5518     consistentTime = t;
5519 }
5520
5521 class QElapsedTimerConsistentTimeHack
5522 {
5523 public:
5524     void start() {
5525         t1 = QQuickItemPrivate::consistentTime;
5526         t2 = 0;
5527     }
5528     qint64 elapsed() {
5529         return QQuickItemPrivate::consistentTime - t1;
5530     }
5531     qint64 restart() {
5532         qint64 val = QQuickItemPrivate::consistentTime - t1;
5533         t1 = QQuickItemPrivate::consistentTime;
5534         t2 = 0;
5535         return val;
5536     }
5537
5538 private:
5539     qint64 t1;
5540     qint64 t2;
5541 };
5542
5543 void QQuickItemPrivate::start(QElapsedTimer &t)
5544 {
5545     if (QQuickItemPrivate::consistentTime == -1)
5546         t.start();
5547     else
5548         ((QElapsedTimerConsistentTimeHack*)&t)->start();
5549 }
5550
5551 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5552 {
5553     if (QQuickItemPrivate::consistentTime == -1)
5554         return t.elapsed();
5555     else
5556         return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5557 }
5558
5559 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5560 {
5561     if (QQuickItemPrivate::consistentTime == -1)
5562         return t.restart();
5563     else
5564         return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5565 }
5566
5567 /*!
5568     \fn bool QQuickItem::isTextureProvider() const
5569
5570     Returns true if this item is a texture provider. The default
5571     implementation returns false.
5572
5573     This function can be called from any thread.
5574  */
5575
5576 bool QQuickItem::isTextureProvider() const
5577 {
5578     Q_D(const QQuickItem);
5579     return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5580            d->extra->layer->effectSource()->isTextureProvider() : false;
5581 }
5582
5583 /*!
5584     \fn QSGTextureProvider *QQuickItem::textureProvider() const
5585
5586     Returns the texture provider for an item. The default implementation
5587     returns 0.
5588
5589     This function may only be called on the rendering thread.
5590  */
5591
5592 QSGTextureProvider *QQuickItem::textureProvider() const
5593 {
5594     Q_D(const QQuickItem);
5595     return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5596            d->extra->layer->effectSource()->textureProvider() : 0;
5597 }
5598
5599 QQuickItemLayer *QQuickItemPrivate::layer() const
5600 {
5601     if (!extra.isAllocated() || !extra->layer) {
5602         extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
5603         if (!componentComplete)
5604             extra->layer->classBegin();
5605     }
5606     return extra->layer;
5607 }
5608
5609 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
5610     : m_item(item)
5611     , m_enabled(false)
5612     , m_mipmap(false)
5613     , m_smooth(false)
5614     , m_componentComplete(true)
5615     , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
5616     , m_format(QQuickShaderEffectSource::RGBA)
5617     , m_name("source")
5618     , m_effectComponent(0)
5619     , m_effect(0)
5620     , m_effectSource(0)
5621 {
5622 }
5623
5624 QQuickItemLayer::~QQuickItemLayer()
5625 {
5626     delete m_effectSource;
5627     delete m_effect;
5628 }
5629
5630
5631
5632 /*!
5633     \qmlproperty bool QtQuick2::Item::layer.enabled
5634
5635     Holds wether the item is layered or not. Layering is disabled by default.
5636
5637     A layered item is rendered into an offscreen surface and cached until
5638     it is changed. Enabling layering for complex QML item hierarchies can
5639     some times be an optimization.
5640
5641     None of the other layer properties have any effect when the layer
5642     is disabled.
5643  */
5644
5645 void QQuickItemLayer::setEnabled(bool e)
5646 {
5647     if (e == m_enabled)
5648         return;
5649     m_enabled = e;
5650     if (m_componentComplete) {
5651         if (m_enabled)
5652             activate();
5653         else
5654             deactivate();
5655     }
5656
5657     emit enabledChanged(e);
5658 }
5659
5660 void QQuickItemLayer::classBegin()
5661 {
5662     Q_ASSERT(!m_effectSource);
5663     Q_ASSERT(!m_effect);
5664     m_componentComplete = false;
5665 }
5666
5667 void QQuickItemLayer::componentComplete()
5668 {
5669     Q_ASSERT(!m_componentComplete);
5670     m_componentComplete = true;
5671     if (m_enabled)
5672         activate();
5673 }
5674
5675 void QQuickItemLayer::activate()
5676 {
5677     Q_ASSERT(!m_effectSource);
5678     m_effectSource = new QQuickShaderEffectSource();
5679
5680     QQuickItem *parentItem = m_item->parentItem();
5681     if (parentItem) {
5682         m_effectSource->setParentItem(parentItem);
5683         m_effectSource->stackAfter(m_item);
5684     }
5685
5686     m_effectSource->setSourceItem(m_item);
5687     m_effectSource->setHideSource(true);
5688     m_effectSource->setSmooth(m_smooth);
5689     m_effectSource->setTextureSize(m_size);
5690     m_effectSource->setSourceRect(m_sourceRect);
5691     m_effectSource->setMipmap(m_mipmap);
5692     m_effectSource->setWrapMode(m_wrapMode);
5693     m_effectSource->setFormat(m_format);
5694
5695     if (m_effectComponent)
5696         activateEffect();
5697
5698     m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5699
5700     updateZ();
5701     updateGeometry();
5702     updateOpacity();
5703     updateMatrix();
5704
5705     QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5706     id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5707 }
5708
5709 void QQuickItemLayer::deactivate()
5710 {
5711     Q_ASSERT(m_effectSource);
5712
5713     if (m_effectComponent)
5714         deactivateEffect();
5715
5716     delete m_effectSource;
5717     m_effectSource = 0;
5718
5719     QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5720     id->removeItemChangeListener(this,  QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5721 }
5722
5723 void QQuickItemLayer::activateEffect()
5724 {
5725     Q_ASSERT(m_effectSource);
5726     Q_ASSERT(m_effectComponent);
5727     Q_ASSERT(!m_effect);
5728
5729     QObject *created = m_effectComponent->beginCreate(m_effectComponent->creationContext());
5730     m_effect = qobject_cast<QQuickItem *>(created);
5731     if (!m_effect) {
5732         qWarning("Item: layer.effect is not a QML Item.");
5733         m_effectComponent->completeCreate();
5734         delete created;
5735         return;
5736     }
5737     QQuickItem *parentItem = m_item->parentItem();
5738     if (parentItem) {
5739         m_effect->setParentItem(parentItem);
5740         m_effect->stackAfter(m_effectSource);
5741     }
5742     m_effect->setVisible(m_item->isVisible());
5743     m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
5744     m_effectComponent->completeCreate();
5745 }
5746
5747 void QQuickItemLayer::deactivateEffect()
5748 {
5749     Q_ASSERT(m_effectSource);
5750     Q_ASSERT(m_effectComponent);
5751
5752     delete m_effect;
5753     m_effect = 0;
5754 }
5755
5756
5757 /*!
5758     \qmlproperty Component QtQuick2::Item::layer.effect
5759
5760     Holds the effect that is applied to this layer.
5761
5762     The effect is typically a \l ShaderEffect component, although any \l Item component can be
5763     assigned. The effect should have a source texture property with a name matching \l samplerName.
5764
5765     \sa samplerName
5766  */
5767
5768 void QQuickItemLayer::setEffect(QQmlComponent *component)
5769 {
5770     if (component == m_effectComponent)
5771         return;
5772
5773     bool updateNeeded = false;
5774     if (m_effectSource && m_effectComponent) {
5775         deactivateEffect();
5776         updateNeeded = true;
5777     }
5778
5779     m_effectComponent = component;
5780
5781     if (m_effectSource && m_effectComponent) {
5782         activateEffect();
5783         updateNeeded = true;
5784     }
5785
5786     if (updateNeeded) {
5787         updateZ();
5788         updateGeometry();
5789         updateOpacity();
5790         updateMatrix();
5791         m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5792     }
5793
5794     emit effectChanged(component);
5795 }
5796
5797
5798 /*!
5799     \qmlproperty bool QtQuick2::Item::layer.mipmap
5800
5801     If this property is true, mipmaps are generated for the texture.
5802
5803     \note Some OpenGL ES 2 implementations do not support mipmapping of
5804     non-power-of-two textures.
5805  */
5806
5807 void QQuickItemLayer::setMipmap(bool mipmap)
5808 {
5809     if (mipmap == m_mipmap)
5810         return;
5811     m_mipmap = mipmap;
5812
5813     if (m_effectSource)
5814         m_effectSource->setMipmap(m_mipmap);
5815
5816     emit mipmapChanged(mipmap);
5817 }
5818
5819
5820 /*!
5821     \qmlproperty enumeration QtQuick2::Item::layer.format
5822
5823     This property defines the internal OpenGL format of the texture.
5824     Modifying this property makes most sense when the \a layer.effect is also
5825     specified. Depending on the OpenGL implementation, this property might
5826     allow you to save some texture memory.
5827
5828     \list
5829     \li ShaderEffectSource.Alpha - GL_ALPHA
5830     \li ShaderEffectSource.RGB - GL_RGB
5831     \li ShaderEffectSource.RGBA - GL_RGBA
5832     \endlist
5833
5834     \note Some OpenGL implementations do not support the GL_ALPHA format.
5835  */
5836
5837 void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
5838 {
5839     if (f == m_format)
5840         return;
5841     m_format = f;
5842
5843     if (m_effectSource)
5844         m_effectSource->setFormat(m_format);
5845
5846     emit formatChanged(m_format);
5847 }
5848
5849
5850 /*!
5851     \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
5852
5853     This property defines which rectangular area of the \l sourceItem to
5854     render into the texture. The source rectangle can be larger than
5855     \l sourceItem itself. If the rectangle is null, which is the default,
5856     the whole \l sourceItem is rendered to texture.
5857  */
5858
5859 void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
5860 {
5861     if (sourceRect == m_sourceRect)
5862         return;
5863     m_sourceRect = sourceRect;
5864
5865     if (m_effectSource)
5866         m_effectSource->setSourceRect(m_sourceRect);
5867
5868     emit sourceRectChanged(sourceRect);
5869 }
5870
5871
5872
5873 /*!
5874     \qmlproperty bool QtQuick2::Item::layer.smooth
5875
5876     Holds whether the layer is smoothly transformed.
5877  */
5878
5879 void QQuickItemLayer::setSmooth(bool s)
5880 {
5881     if (m_smooth == s)
5882         return;
5883     m_smooth = s;
5884
5885     if (m_effectSource)
5886         m_effectSource->setSmooth(m_smooth);
5887
5888     emit smoothChanged(s);
5889 }
5890
5891
5892
5893 /*!
5894     \qmlproperty size QtQuick2::Item::layer.textureSize
5895
5896     This property holds the requested pixel size of the layers texture. If it is empty,
5897     which is the default, the size of the item is used.
5898
5899     \note Some platforms have a limit on how small framebuffer objects can be,
5900     which means the actual texture size might be larger than the requested
5901     size.
5902  */
5903
5904 void QQuickItemLayer::setSize(const QSize &size)
5905 {
5906     if (size == m_size)
5907         return;
5908     m_size = size;
5909
5910     if (m_effectSource)
5911         m_effectSource->setTextureSize(size);
5912
5913     emit sizeChanged(size);
5914 }
5915
5916
5917
5918 /*!
5919     \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
5920
5921     This property defines the OpenGL wrap modes associated with the texture.
5922     Modifying this property makes most sense when the \a layer.effect is
5923     specified.
5924
5925     \list
5926     \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
5927     \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
5928     \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
5929     \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
5930     \endlist
5931
5932     \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
5933     wrap mode with non-power-of-two textures.
5934  */
5935
5936 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
5937 {
5938     if (mode == m_wrapMode)
5939         return;
5940     m_wrapMode = mode;
5941
5942     if (m_effectSource)
5943         m_effectSource->setWrapMode(m_wrapMode);
5944
5945     emit wrapModeChanged(mode);
5946 }
5947
5948 /*!
5949     \qmlproperty string QtQuick2::Item::layer.samplerName
5950
5951     Holds the name of the effect's source texture property.
5952
5953     samplerName needs to match the name of the effect's source texture property
5954     so that the Item can pass the layer's offscreen surface to the effect correctly.
5955
5956     \sa effect, ShaderEffect
5957  */
5958
5959 void QQuickItemLayer::setName(const QByteArray &name) {
5960     if (m_name == name)
5961         return;
5962     if (m_effect) {
5963         m_effect->setProperty(m_name, QVariant());
5964         m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
5965     }
5966     m_name = name;
5967     emit nameChanged(name);
5968 }
5969
5970 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
5971 {
5972     Q_UNUSED(item)
5973     updateOpacity();
5974 }
5975
5976 void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
5977 {
5978     updateGeometry();
5979 }
5980
5981 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
5982 {
5983     Q_UNUSED(item)
5984     Q_ASSERT(item == m_item);
5985     Q_ASSERT(parent != m_effectSource);
5986     Q_ASSERT(parent == 0 || parent != m_effect);
5987
5988     m_effectSource->setParentItem(parent);
5989     if (parent)
5990         m_effectSource->stackAfter(m_item);
5991
5992     if (m_effect) {
5993         m_effect->setParentItem(parent);
5994         if (parent)
5995             m_effect->stackAfter(m_effectSource);
5996     }
5997 }
5998
5999 void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
6000 {
6001     m_effectSource->stackAfter(m_item);
6002     if (m_effect)
6003         m_effect->stackAfter(m_effectSource);
6004 }
6005
6006 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
6007 {
6008     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6009     Q_ASSERT(l);
6010     l->setVisible(m_item->isVisible());
6011 }
6012
6013 void QQuickItemLayer::updateZ()
6014 {
6015     if (!m_componentComplete || !m_enabled)
6016         return;
6017     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6018     Q_ASSERT(l);
6019     l->setZ(m_item->z());
6020 }
6021
6022 void QQuickItemLayer::updateOpacity()
6023 {
6024     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6025     Q_ASSERT(l);
6026     l->setOpacity(m_item->opacity());
6027 }
6028
6029 void QQuickItemLayer::updateGeometry()
6030 {
6031     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6032     Q_ASSERT(l);
6033     QRectF bounds = m_item->clipRect();
6034     l->setWidth(bounds.width());
6035     l->setHeight(bounds.height());
6036     l->setX(bounds.x() + m_item->x());
6037     l->setY(bounds.y() + m_item->y());
6038 }
6039
6040 void QQuickItemLayer::updateMatrix()
6041 {
6042     // Called directly from transformChanged(), so needs some extra
6043     // checks.
6044     if (!m_componentComplete || !m_enabled)
6045         return;
6046     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6047     Q_ASSERT(l);
6048     QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
6049     l->setScale(m_item->scale());
6050     l->setRotation(m_item->rotation());
6051     ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
6052     if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
6053         ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
6054     ld->dirty(QQuickItemPrivate::Transform);
6055 }
6056
6057 QQuickItemPrivate::ExtraData::ExtraData()
6058 : z(0), scale(1), rotation(0), opacity(1),
6059   contents(0), screenAttached(0), layoutDirectionAttached(0),
6060   keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
6061   opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
6062   acceptedMouseButtons(0), origin(QQuickItem::Center)
6063 {
6064 }
6065
6066 QT_END_NAMESPACE
6067
6068 #include <moc_qquickitem.cpp>