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