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