QQuickCanvas renames
[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 "qquickwindow.h"
45 #include <QtQml/qjsengine.h>
46 #include "qquickwindow_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 type 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 types let you create and control advanced transformations that can be configured
145     independently using specialized properties.
146
147     You can assign any number of Transforms 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 items while still allowing the \l Row
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 type 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->window()) {
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->window()->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->window()) {
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->window()->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->window()) {
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->window()->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} types (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 types 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 items 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} types
1512     (such as \l Row and \l Grid) and view types (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 QQuickWindow, 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 types 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->windowRefCount > 1)
1876         d->windowRefCount = 1; // Make sure window is set to null in next call to derefWindow().
1877     if (d->parentItem)
1878         setParentItem(0);
1879     else if (d->window)
1880         d->derefWindow();
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 types.
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->window) {
1988                 QQuickWindowPrivate::get(d->window)->clearFocusInScope(scopeItem, scopeFocusedItem,
1989                                                                 QQuickWindowPrivate::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->window) {
2003         QQuickWindowPrivate::get(d->window)->parentlessItems.remove(this);
2004     }
2005
2006     QQuickWindow *oldParentWindow = oldParentItem ? QQuickItemPrivate::get(oldParentItem)->window : 0;
2007     QQuickWindow *parentWindow = parentItem ? QQuickItemPrivate::get(parentItem)->window : 0;
2008     if (oldParentWindow == parentWindow) {
2009         // Avoid freeing and reallocating resources if the window stays the same.
2010         d->parentItem = parentItem;
2011     } else {
2012         if (oldParentWindow)
2013             d->derefWindow();
2014         d->parentItem = parentItem;
2015         if (parentWindow)
2016             d->refWindow(parentWindow);
2017     }
2018
2019     d->dirty(QQuickItemPrivate::ParentChanged);
2020
2021     if (d->parentItem)
2022         QQuickItemPrivate::get(d->parentItem)->addChild(this);
2023     else if (d->window)
2024         QQuickWindowPrivate::get(d->window)->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->window) {
2051                     QQuickWindowPrivate::get(d->window)->setFocusInScope(scopeItem, scopeFocusedItem,
2052                                                                   QQuickWindowPrivate::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 QQuickWindow *QQuickItem::window() const
2138 {
2139     Q_D(const QQuickItem);
2140     return d->window;
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::refWindow(QQuickWindow *c)
2207 {
2208     // An item needs a window if it is referenced by another item which has a window.
2209     // Typically the item is referenced by a parent, but can also be referenced by a
2210     // ShaderEffect or ShaderEffectSource. 'windowRefCount' counts how many items with
2211     // a window is referencing this item. When the reference count goes from zero to one,
2212     // or one to zero, the window of this item is updated and propagated to the children.
2213     // As long as the reference count stays above zero, the window is unchanged.
2214     // refWindow() increments the reference count.
2215     // derefWindow() decrements the reference count.
2216
2217     Q_Q(QQuickItem);
2218     Q_ASSERT((window != 0) == (windowRefCount > 0));
2219     Q_ASSERT(c);
2220     if (++windowRefCount > 1) {
2221         if (c != window)
2222             qWarning("QQuickItem: Cannot use same item on different windows at the same time.");
2223         return; // Window already set.
2224     }
2225
2226     Q_ASSERT(window == 0);
2227     window = c;
2228
2229     if (polishScheduled)
2230         QQuickWindowPrivate::get(window)->itemsToPolish.insert(q);
2231
2232     if (!parentItem)
2233         QQuickWindowPrivate::get(window)->parentlessItems.insert(q);
2234
2235     for (int ii = 0; ii < childItems.count(); ++ii) {
2236         QQuickItem *child = childItems.at(ii);
2237         QQuickItemPrivate::get(child)->refWindow(c);
2238     }
2239
2240     dirty(Window);
2241
2242     if (extra.isAllocated() && extra->screenAttached)
2243         extra->screenAttached->windowChanged(c);
2244     itemChange(QQuickItem::ItemSceneChange, c);
2245 }
2246
2247 void QQuickItemPrivate::derefWindow()
2248 {
2249     Q_Q(QQuickItem);
2250     Q_ASSERT((window != 0) == (windowRefCount > 0));
2251
2252     if (!window)
2253         return; // This can happen when destroying recursive shader effect sources.
2254
2255     if (--windowRefCount > 0)
2256         return; // There are still other references, so don't set window to null yet.
2257
2258     q->releaseResources();
2259     removeFromDirtyList();
2260     QQuickWindowPrivate *c = QQuickWindowPrivate::get(window);
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     window = 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)->derefWindow();
2294     }
2295
2296     dirty(Window);
2297
2298     if (extra.isAllocated() && extra->screenAttached)
2299         extra->screenAttached->windowChanged(0);
2300     itemChange(QQuickItem::ItemSceneChange, (QQuickWindow *)0);
2301 }
2302
2303
2304 /*!
2305 Returns a transform that maps points from window space into item space.
2306 */
2307 QTransform QQuickItemPrivate::windowToItemTransform() const
2308 {
2309     // XXX todo - optimize
2310     return itemToWindowTransform().inverted();
2311 }
2312
2313 /*!
2314 Returns a transform that maps points from item space into window space.
2315 */
2316 QTransform QQuickItemPrivate::itemToWindowTransform() const
2317 {
2318     // XXX todo
2319     QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToWindowTransform():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)
2405     , _stateGroup(0)
2406     , flags(0)
2407     , widthValid(false)
2408     , heightValid(false)
2409     , baselineOffsetValid(false)
2410     , componentComplete(true)
2411     , keepMouse(false)
2412     , keepTouch(false)
2413     , hoverEnabled(false)
2414     , smooth(true)
2415     , antialiasing(false)
2416     , focus(false)
2417     , activeFocus(false)
2418     , notifiedFocus(false)
2419     , notifiedActiveFocus(false)
2420     , filtersChildMouseEvents(false)
2421     , explicitVisible(true)
2422     , effectiveVisible(true)
2423     , explicitEnable(true)
2424     , effectiveEnable(true)
2425     , polishScheduled(false)
2426     , inheritedLayoutMirror(false)
2427     , effectiveLayoutMirror(false)
2428     , isMirrorImplicit(true)
2429     , inheritMirrorFromParent(false)
2430     , inheritMirrorFromItem(false)
2431     , isAccessible(false)
2432     , culled(false)
2433     , dirtyAttributes(0)
2434     , nextDirtyItem(0)
2435     , prevDirtyItem(0)
2436     , window(0)
2437     , windowRefCount(0)
2438     , parentItem(0)
2439     , sortedChildItems(&childItems)
2440     , subFocusItem(0)
2441     , x(0)
2442     , y(0)
2443     , width(0)
2444     , height(0)
2445     , implicitWidth(0)
2446     , implicitHeight(0)
2447     , baselineOffset(0)
2448     , itemNodeInstance(0)
2449     , groupNode(0)
2450     , paintNode(0)
2451 {
2452 }
2453
2454 QQuickItemPrivate::~QQuickItemPrivate()
2455 {
2456     if (sortedChildItems != &childItems)
2457         delete sortedChildItems;
2458 }
2459
2460 void QQuickItemPrivate::init(QQuickItem *parent)
2461 {
2462 #ifndef QT_NO_DEBUG
2463     ++qt_item_count;
2464     static bool atexit_registered = false;
2465     if (!atexit_registered) {
2466         atexit(qt_print_item_count);
2467         atexit_registered = true;
2468     }
2469 #endif
2470
2471     Q_Q(QQuickItem);
2472
2473     registerAccessorProperties();
2474
2475     baselineOffsetValid = false;
2476
2477     if (parent) {
2478         q->setParentItem(parent);
2479         QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
2480         setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2481     }
2482 }
2483
2484 void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
2485 {
2486     if (!o)
2487         return;
2488
2489     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2490
2491     if (QQuickItem *item = qmlobject_cast<QQuickItem *>(o)) {
2492         item->setParentItem(that);
2493     } else {
2494         if (o->inherits("QGraphicsItem"))
2495             qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2496
2497         // XXX todo - do we really want this behavior?
2498         o->setParent(that);
2499     }
2500 }
2501
2502 /*!
2503     \qmlproperty list<Object> QtQuick2::Item::data
2504     \default
2505
2506     The data property allows you to freely mix visual children and resources
2507     in an item.  If you assign a visual item to the data list it becomes
2508     a child and if you assign any other object type, it is added as a resource.
2509
2510     So you can write:
2511     \qml
2512     Item {
2513         Text {}
2514         Rectangle {}
2515         Timer {}
2516     }
2517     \endqml
2518
2519     instead of:
2520     \qml
2521     Item {
2522         children: [
2523             Text {},
2524             Rectangle {}
2525         ]
2526         resources: [
2527             Timer {}
2528         ]
2529     }
2530     \endqml
2531
2532     data is a behind-the-scenes property: you should never need to explicitly
2533     specify it.
2534  */
2535
2536 int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *prop)
2537 {
2538     Q_UNUSED(prop);
2539     // XXX todo
2540     return 0;
2541 }
2542
2543 QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *prop, int i)
2544 {
2545     Q_UNUSED(prop);
2546     Q_UNUSED(i);
2547     // XXX todo
2548     return 0;
2549 }
2550
2551 void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *prop)
2552 {
2553     Q_UNUSED(prop);
2554     // XXX todo
2555 }
2556
2557 QObject *QQuickItemPrivate::resources_at(QQmlListProperty<QObject> *prop, int index)
2558 {
2559     const QObjectList children = prop->object->children();
2560     if (index < children.count())
2561         return children.at(index);
2562     else
2563         return 0;
2564 }
2565
2566 void QQuickItemPrivate::resources_append(QQmlListProperty<QObject> *prop, QObject *o)
2567 {
2568     // XXX todo - do we really want this behavior?
2569     o->setParent(prop->object);
2570 }
2571
2572 int QQuickItemPrivate::resources_count(QQmlListProperty<QObject> *prop)
2573 {
2574     return prop->object->children().count();
2575 }
2576
2577 void QQuickItemPrivate::resources_clear(QQmlListProperty<QObject> *prop)
2578 {
2579     // XXX todo - do we really want this behavior?
2580     const QObjectList children = prop->object->children();
2581     for (int index = 0; index < children.count(); index++)
2582         children.at(index)->setParent(0);
2583 }
2584
2585 QQuickItem *QQuickItemPrivate::children_at(QQmlListProperty<QQuickItem> *prop, int index)
2586 {
2587     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2588     if (index >= p->childItems.count() || index < 0)
2589         return 0;
2590     else
2591         return p->childItems.at(index);
2592 }
2593
2594 void QQuickItemPrivate::children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *o)
2595 {
2596     if (!o)
2597         return;
2598
2599     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2600     if (o->parentItem() == that)
2601         o->setParentItem(0);
2602
2603     o->setParentItem(that);
2604 }
2605
2606 int QQuickItemPrivate::children_count(QQmlListProperty<QQuickItem> *prop)
2607 {
2608     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2609     return p->childItems.count();
2610 }
2611
2612 void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop)
2613 {
2614     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2615     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2616     while (!p->childItems.isEmpty())
2617         p->childItems.at(0)->setParentItem(0);
2618 }
2619
2620 void QQuickItemPrivate::visibleChildren_append(QQmlListProperty<QQuickItem>*, QQuickItem *self)
2621 {
2622     // do nothing
2623     qmlInfo(self) << "QQuickItem: visibleChildren property is readonly and cannot be assigned to.";
2624 }
2625
2626 int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop)
2627 {
2628     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2629     int visibleCount = 0;
2630     int c = p->childItems.count();
2631     while (c--) {
2632         if (p->childItems.at(c)->isVisible()) visibleCount++;
2633     }
2634
2635     return visibleCount;
2636 }
2637
2638 QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index)
2639 {
2640     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2641     const int childCount = p->childItems.count();
2642     if (index >= childCount || index < 0)
2643         return 0;
2644
2645     int visibleCount = -1;
2646     for (int i = 0; i < childCount; i++) {
2647         if (p->childItems.at(i)->isVisible()) visibleCount++;
2648         if (visibleCount == index) return p->childItems.at(i);
2649     }
2650     return 0;
2651 }
2652
2653 int QQuickItemPrivate::transform_count(QQmlListProperty<QQuickTransform> *prop)
2654 {
2655     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2656     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2657
2658     return p->transforms.count();
2659 }
2660
2661 void QQuickTransform::appendToItem(QQuickItem *item)
2662 {
2663     Q_D(QQuickTransform);
2664     if (!item)
2665         return;
2666
2667     QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2668
2669     if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2670         p->transforms.removeOne(this);
2671         p->transforms.append(this);
2672     } else {
2673         p->transforms.append(this);
2674         d->items.append(item);
2675     }
2676
2677     p->dirty(QQuickItemPrivate::Transform);
2678 }
2679
2680 void QQuickTransform::prependToItem(QQuickItem *item)
2681 {
2682     Q_D(QQuickTransform);
2683     if (!item)
2684         return;
2685
2686     QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2687
2688     if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2689         p->transforms.removeOne(this);
2690         p->transforms.prepend(this);
2691     } else {
2692         p->transforms.prepend(this);
2693         d->items.append(item);
2694     }
2695
2696     p->dirty(QQuickItemPrivate::Transform);
2697 }
2698
2699 void QQuickItemPrivate::transform_append(QQmlListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2700 {
2701     if (!transform)
2702         return;
2703
2704     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2705     transform->appendToItem(that);
2706 }
2707
2708 QQuickTransform *QQuickItemPrivate::transform_at(QQmlListProperty<QQuickTransform> *prop, int idx)
2709 {
2710     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2711     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2712
2713     if (idx < 0 || idx >= p->transforms.count())
2714         return 0;
2715     else
2716         return p->transforms.at(idx);
2717 }
2718
2719 void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
2720 {
2721     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2722     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2723
2724     for (int ii = 0; ii < p->transforms.count(); ++ii) {
2725         QQuickTransform *t = p->transforms.at(ii);
2726         QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2727         tp->items.removeOne(that);
2728     }
2729
2730     p->transforms.clear();
2731
2732     p->dirty(QQuickItemPrivate::Transform);
2733 }
2734
2735 /*!
2736     \property QQuickItem::childrenRect
2737     \brief Specifies the geometry of an item's children
2738
2739     This property holds the (collective) position and size of the item's children.
2740 */
2741
2742 /*!
2743   \qmlproperty real QtQuick2::Item::x
2744   \qmlproperty real QtQuick2::Item::y
2745   \qmlproperty real QtQuick2::Item::width
2746   \qmlproperty real QtQuick2::Item::height
2747
2748   Defines the item's position and size relative to its parent.
2749
2750   \qml
2751   Item { x: 100; y: 100; width: 100; height: 100 }
2752   \endqml
2753  */
2754
2755 /*!
2756   \qmlproperty real QtQuick2::Item::z
2757
2758   Sets the stacking order of sibling items.  By default the stacking order is 0.
2759
2760   Items with a higher stacking value are drawn on top of siblings with a
2761   lower stacking order.  Items with the same stacking value are drawn
2762   bottom up in the order they appear.  Items with a negative stacking
2763   value are drawn under their parent's content.
2764
2765   The following example shows the various effects of stacking order.
2766
2767   \table
2768   \row
2769   \li \image declarative-item_stacking1.png
2770   \li Same \c z - later children above earlier children:
2771   \qml
2772   Item {
2773       Rectangle {
2774           color: "red"
2775           width: 100; height: 100
2776       }
2777       Rectangle {
2778           color: "blue"
2779           x: 50; y: 50; width: 100; height: 100
2780       }
2781   }
2782   \endqml
2783   \row
2784   \li \image declarative-item_stacking2.png
2785   \li Higher \c z on top:
2786   \qml
2787   Item {
2788       Rectangle {
2789           z: 1
2790           color: "red"
2791           width: 100; height: 100
2792       }
2793       Rectangle {
2794           color: "blue"
2795           x: 50; y: 50; width: 100; height: 100
2796       }
2797   }
2798   \endqml
2799   \row
2800   \li \image declarative-item_stacking3.png
2801   \li Same \c z - children above parents:
2802   \qml
2803   Item {
2804       Rectangle {
2805           color: "red"
2806           width: 100; height: 100
2807           Rectangle {
2808               color: "blue"
2809               x: 50; y: 50; width: 100; height: 100
2810           }
2811       }
2812   }
2813   \endqml
2814   \row
2815   \li \image declarative-item_stacking4.png
2816   \li Lower \c z below:
2817   \qml
2818   Item {
2819       Rectangle {
2820           color: "red"
2821           width: 100; height: 100
2822           Rectangle {
2823               z: -1
2824               color: "blue"
2825               x: 50; y: 50; width: 100; height: 100
2826           }
2827       }
2828   }
2829   \endqml
2830   \endtable
2831  */
2832
2833 /*!
2834     \qmlproperty bool QtQuick2::Item::visible
2835
2836     This property holds whether the item is visible. By default this is true.
2837
2838     Setting this property directly affects the \c visible value of child
2839     items. When set to \c false, the \c visible values of all child items also
2840     become \c false. When set to \c true, the \c visible values of child items
2841     are returned to \c true, unless they have explicitly been set to \c false.
2842
2843     (Because of this flow-on behavior, using the \c visible property may not
2844     have the intended effect if a property binding should only respond to
2845     explicit property changes. In such cases it may be better to use the
2846     \l opacity property instead.)
2847
2848     If this property is set to \c false, the item will no longer receive mouse
2849     events, but will continue to receive key events and will retain the keyboard
2850     \l focus if it has been set. (In contrast, setting the \l enabled property
2851     to \c false stops both mouse and keyboard events, and also removes focus
2852     from the item.)
2853
2854     \note This property's value is only affected by changes to this property or
2855     the parent's \c visible property. It does not change, for example, if this
2856     item moves off-screen, or if the \l opacity changes to 0.
2857 */
2858
2859 /*!
2860     \qmlproperty bool QtQuick2::Item::enabled
2861
2862     This property holds whether the item receives mouse and keyboard events.
2863     By default this is true.
2864
2865     Setting this property directly affects the \c enabled value of child
2866     items. When set to \c false, the \c enabled values of all child items also
2867     become \c false. When set to \c true, the \c enabled values of child items
2868     are returned to \c true, unless they have explicitly been set to \c false.
2869
2870     Setting this property to \c false automatically causes \l activeFocus to be
2871     set to \c false, and this item will longer receive keyboard events.
2872 */
2873
2874 /*!
2875   \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2876   \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2877   \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2878   \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2879   \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2880   \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2881   \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2882
2883   \qmlproperty Item QtQuick2::Item::anchors.fill
2884   \qmlproperty Item QtQuick2::Item::anchors.centerIn
2885
2886   \qmlproperty real QtQuick2::Item::anchors.margins
2887   \qmlproperty real QtQuick2::Item::anchors.topMargin
2888   \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2889   \qmlproperty real QtQuick2::Item::anchors.leftMargin
2890   \qmlproperty real QtQuick2::Item::anchors.rightMargin
2891   \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2892   \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2893   \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2894
2895   \qmlproperty bool QtQuick2::Item::anchors.alignWhenCentered
2896
2897   Anchors provide a way to position an item by specifying its
2898   relationship with other items.
2899
2900   Margins apply to top, bottom, left, right, and fill anchors.
2901   The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2902   It will not override a specific margin that has been previously set; to clear an explicit margin
2903   set it's value to \c undefined.
2904   Note that margins are anchor-specific and are not applied if an item does not
2905   use anchors.
2906
2907   Offsets apply for horizontal center, vertical center, and baseline anchors.
2908
2909   \table
2910   \row
2911   \li \image declarative-anchors_example.png
2912   \li Text anchored to Image, horizontally centered and vertically below, with a margin.
2913   \qml
2914   Item {
2915       Image {
2916           id: pic
2917           // ...
2918       }
2919       Text {
2920           id: label
2921           anchors.horizontalCenter: pic.horizontalCenter
2922           anchors.top: pic.bottom
2923           anchors.topMargin: 5
2924           // ...
2925       }
2926   }
2927   \endqml
2928   \row
2929   \li \image declarative-anchors_example2.png
2930   \li
2931   Left of Text anchored to right of Image, with a margin. The y
2932   property of both defaults to 0.
2933
2934   \qml
2935   Item {
2936       Image {
2937           id: pic
2938           // ...
2939       }
2940       Text {
2941           id: label
2942           anchors.left: pic.right
2943           anchors.leftMargin: 5
2944           // ...
2945       }
2946   }
2947   \endqml
2948   \endtable
2949
2950   \c anchors.fill provides a convenient way for one item to have the
2951   same geometry as another item, and is equivalent to connecting all
2952   four directional anchors.
2953
2954   To clear an anchor value, set it to \c undefined.
2955
2956   \c anchors.alignWhenCentered (default true) forces centered anchors to align to a
2957   whole pixel, i.e. if the item being centered has an odd width/height the item
2958   will be positioned on a whole pixel rather than being placed on a half-pixel.
2959   This ensures the item is painted crisply.  There are cases where this is not
2960   desirable, for example when rotating the item jitters may be apparent as the
2961   center is rounded.
2962
2963   \note You can only anchor an item to siblings or a parent.
2964
2965   For more information see \l {anchor-layout}{Anchor Layouts}.
2966 */
2967
2968 /*!
2969   \property QQuickItem::baselineOffset
2970   \brief Speciifies the position of the item's baseline in local coordinates
2971
2972   The baseline of a \l Text item is the imaginary line on which the text
2973   sits. Controls containing text usually set their baseline to the
2974   baseline of their text.
2975
2976   For non-text items, a default baseline offset of 0 is used.
2977 */
2978 QQuickAnchors *QQuickItemPrivate::anchors() const
2979 {
2980     if (!_anchors) {
2981         Q_Q(const QQuickItem);
2982         _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2983         if (!componentComplete)
2984             _anchors->classBegin();
2985     }
2986     return _anchors;
2987 }
2988
2989 void QQuickItemPrivate::siblingOrderChanged()
2990 {
2991     Q_Q(QQuickItem);
2992     for (int ii = 0; ii < changeListeners.count(); ++ii) {
2993         const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2994         if (change.types & QQuickItemPrivate::SiblingOrder) {
2995             change.listener->itemSiblingOrderChanged(q);
2996         }
2997     }
2998 }
2999
3000 QQmlListProperty<QObject> QQuickItemPrivate::data()
3001 {
3002     return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
3003                                              QQuickItemPrivate::data_count,
3004                                              QQuickItemPrivate::data_at,
3005                                              QQuickItemPrivate::data_clear);
3006 }
3007
3008 QRectF QQuickItem::childrenRect()
3009 {
3010     Q_D(QQuickItem);
3011     if (!d->extra.isAllocated() || !d->extra->contents) {
3012         d->extra.value().contents = new QQuickContents(this);
3013         if (d->componentComplete)
3014             d->extra->contents->complete();
3015     }
3016     return d->extra->contents->rectF();
3017 }
3018
3019 QList<QQuickItem *> QQuickItem::childItems() const
3020 {
3021     Q_D(const QQuickItem);
3022     return d->childItems;
3023 }
3024
3025 bool QQuickItem::clip() const
3026 {
3027     return flags() & ItemClipsChildrenToShape;
3028 }
3029
3030 void QQuickItem::setClip(bool c)
3031 {
3032     if (clip() == c)
3033         return;
3034
3035     setFlag(ItemClipsChildrenToShape, c);
3036
3037     emit clipChanged(c);
3038 }
3039
3040
3041 /*!
3042   This function is called to handle this item's changes in
3043   geometry from \a oldGeometry to \a newGeometry. If the two
3044   geometries are the same, it doesn't do anything.
3045
3046   Derived classes must call the base class method within their implementation.
3047  */
3048 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
3049 {
3050     Q_D(QQuickItem);
3051
3052     if (d->_anchors)
3053         QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
3054
3055     bool xChange = (newGeometry.x() != oldGeometry.x());
3056     bool yChange = (newGeometry.y() != oldGeometry.y());
3057     bool widthChange = (newGeometry.width() != oldGeometry.width());
3058     bool heightChange = (newGeometry.height() != oldGeometry.height());
3059
3060     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3061         const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3062         if (change.types & QQuickItemPrivate::Geometry) {
3063             if (change.gTypes == QQuickItemPrivate::GeometryChange) {
3064                 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3065             } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
3066                        (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
3067                        (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
3068                        (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
3069                 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
3070             }
3071         }
3072     }
3073
3074     if (xChange)
3075         emit xChanged();
3076     if (yChange)
3077         emit yChanged();
3078     if (widthChange)
3079         emit widthChanged();
3080     if (heightChange)
3081         emit heightChanged();
3082 }
3083
3084 /*!
3085     Called by the rendering thread, as a result of
3086     QQuickItem::update(), when it is time to sync the state of the QML
3087     objects with the scene graph objects.
3088
3089     The function should return the root of the scene graph subtree for
3090     this item. Most implementations will return a single
3091     QSGGeometryNode containing the visual representation of this item.
3092     \a oldNode is the node that was returned the last time the
3093     function was called.
3094
3095     \code
3096     QSGNode *MyItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
3097     {
3098         QSGSimpleRectNode *n = static_cast<QSGSimpleRectNode *>(node);
3099         if (!n) {
3100             n = new QSGSimpleRectNode();
3101             n->setColor(Qt::red);
3102         }
3103         n->setRect(boundingRect());
3104         return n;
3105     }
3106     \endcode
3107
3108     The main thread is blocked while this function is executed so it is safe to read
3109     values from the QQuickItem instance and other objects in the main thread.
3110
3111     If no call to QQuickItem::updatePaintNode() result in actual scene graph
3112     changes, like QSGNode::markDirty() or adding and removing nodes, then
3113     the underlying implementation may decide to not render the scene again as
3114     the visual outcome is identical.
3115
3116     \warning It is crucial that OpenGL operations and interaction with
3117     the scene graph happens exclusively on the rendering thread,
3118     primarily during the QQuickItem::updatePaintNode() call. The best
3119     rule of thumb is to only use classes with the "QSG" prefix inside
3120     the QQuickItem::updatePaintNode() function.
3121
3122     \sa QSGMaterial, QSGSimpleMaterial, QSGGeometryNode, QSGGeometry,
3123     QSGFlatColorMaterial, QSGTextureMaterial, QSGNode::markDirty()
3124  */
3125
3126 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
3127 {
3128     delete oldNode;
3129     return 0;
3130 }
3131
3132 /*!
3133     This function is called when the item's scene graph resources are no longer needed.
3134     It allows items to free its resources, for instance textures, that are not owned by scene graph
3135     nodes. Note that scene graph nodes are managed by QQuickWindow and should not be deleted by
3136     this function. Scene graph resources are no longer needed when the parent is set to null and
3137     the item is not used by any \l ShaderEffect or \l ShaderEffectSource.
3138
3139     This function is called from the main thread. Therefore, resources used by the scene graph
3140     should not be deleted directly, but by calling \l QObject::deleteLater().
3141
3142     \note The item destructor still needs to free its scene graph resources if not already done.
3143  */
3144
3145 void QQuickItem::releaseResources()
3146 {
3147 }
3148
3149 QSGTransformNode *QQuickItemPrivate::createTransformNode()
3150 {
3151     return new QSGTransformNode;
3152 }
3153
3154 void QQuickItem::updatePolish()
3155 {
3156 }
3157
3158 void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3159 {
3160     changeListeners.append(ChangeListener(listener, types));
3161 }
3162
3163 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
3164 {
3165     ChangeListener change(listener, types);
3166     changeListeners.removeOne(change);
3167 }
3168
3169 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
3170 {
3171     ChangeListener change(listener, types);
3172     int index = changeListeners.find(change);
3173     if (index > -1)
3174         changeListeners[index].gTypes = change.gTypes;  //we may have different GeometryChangeTypes
3175     else
3176         changeListeners.append(change);
3177 }
3178
3179 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
3180                                                              GeometryChangeTypes types)
3181 {
3182     ChangeListener change(listener, types);
3183     if (types == NoChange) {
3184         changeListeners.removeOne(change);
3185     } else {
3186         int index = changeListeners.find(change);
3187         if (index > -1)
3188             changeListeners[index].gTypes = change.gTypes;  //we may have different GeometryChangeTypes
3189     }
3190 }
3191
3192 void QQuickItem::keyPressEvent(QKeyEvent *event)
3193 {
3194     event->ignore();
3195 }
3196
3197 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
3198 {
3199     event->ignore();
3200 }
3201
3202 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
3203 {
3204     event->ignore();
3205 }
3206
3207 void QQuickItem::focusInEvent(QFocusEvent *)
3208 {
3209 #ifndef QT_NO_ACCESSIBILITY
3210     QAccessibleEvent ev(this, QAccessible::Focus);
3211     QAccessible::updateAccessibility(&ev);
3212 #endif
3213 }
3214
3215 void QQuickItem::focusOutEvent(QFocusEvent *)
3216 {
3217 }
3218
3219 void QQuickItem::mousePressEvent(QMouseEvent *event)
3220 {
3221     event->ignore();
3222 }
3223
3224 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
3225 {
3226     event->ignore();
3227 }
3228
3229 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
3230 {
3231     event->ignore();
3232 }
3233
3234 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
3235 {
3236 }
3237
3238 void QQuickItem::mouseUngrabEvent()
3239 {
3240     // XXX todo
3241 }
3242
3243 void QQuickItem::touchUngrabEvent()
3244 {
3245     // XXX todo
3246 }
3247
3248 void QQuickItem::wheelEvent(QWheelEvent *event)
3249 {
3250     event->ignore();
3251 }
3252
3253 void QQuickItem::touchEvent(QTouchEvent *event)
3254 {
3255     event->ignore();
3256 }
3257
3258 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
3259 {
3260     Q_UNUSED(event);
3261 }
3262
3263 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
3264 {
3265     Q_UNUSED(event);
3266 }
3267
3268 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
3269 {
3270     Q_UNUSED(event);
3271 }
3272
3273 #ifndef QT_NO_DRAGANDDROP
3274 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
3275 {
3276     Q_UNUSED(event);
3277 }
3278
3279 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
3280 {
3281
3282     Q_UNUSED(event);
3283 }
3284
3285 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3286 {
3287
3288     Q_UNUSED(event);
3289 }
3290
3291 void QQuickItem::dropEvent(QDropEvent *event)
3292 {
3293     Q_UNUSED(event);
3294 }
3295 #endif // QT_NO_DRAGANDDROP
3296
3297 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3298 {
3299     return false;
3300 }
3301
3302 void QQuickItem::windowDeactivateEvent()
3303 {
3304     foreach (QQuickItem* item, childItems()) {
3305         item->windowDeactivateEvent();
3306     }
3307 }
3308
3309 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3310 {
3311     Q_D(const QQuickItem);
3312     QVariant v;
3313
3314     switch (query) {
3315     case Qt::ImEnabled:
3316         v = (bool)(flags() & ItemAcceptsInputMethod);
3317         break;
3318     case Qt::ImHints:
3319     case Qt::ImCursorRectangle:
3320     case Qt::ImFont:
3321     case Qt::ImCursorPosition:
3322     case Qt::ImSurroundingText:
3323     case Qt::ImCurrentSelection:
3324     case Qt::ImMaximumTextLength:
3325     case Qt::ImAnchorPosition:
3326     case Qt::ImPreferredLanguage:
3327         if (d->extra.isAllocated() && d->extra->keyHandler)
3328             v = d->extra->keyHandler->inputMethodQuery(query);
3329     default:
3330         break;
3331     }
3332
3333     return v;
3334 }
3335
3336 QQuickAnchorLine QQuickItemPrivate::left() const
3337 {
3338     Q_Q(const QQuickItem);
3339     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left);
3340 }
3341
3342 QQuickAnchorLine QQuickItemPrivate::right() const
3343 {
3344     Q_Q(const QQuickItem);
3345     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right);
3346 }
3347
3348 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3349 {
3350     Q_Q(const QQuickItem);
3351     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter);
3352 }
3353
3354 QQuickAnchorLine QQuickItemPrivate::top() const
3355 {
3356     Q_Q(const QQuickItem);
3357     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top);
3358 }
3359
3360 QQuickAnchorLine QQuickItemPrivate::bottom() const
3361 {
3362     Q_Q(const QQuickItem);
3363     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom);
3364 }
3365
3366 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3367 {
3368     Q_Q(const QQuickItem);
3369     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter);
3370 }
3371
3372 QQuickAnchorLine QQuickItemPrivate::baseline() const
3373 {
3374     Q_Q(const QQuickItem);
3375     return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline);
3376 }
3377
3378 qreal QQuickItem::baselineOffset() const
3379 {
3380     Q_D(const QQuickItem);
3381     if (d->baselineOffsetValid) {
3382         return d->baselineOffset;
3383     } else {
3384         return 0.0;
3385     }
3386 }
3387
3388 void QQuickItem::setBaselineOffset(qreal offset)
3389 {
3390     Q_D(QQuickItem);
3391     if (offset == d->baselineOffset)
3392         return;
3393
3394     d->baselineOffset = offset;
3395     d->baselineOffsetValid = true;
3396
3397     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3398         const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3399         if (change.types & QQuickItemPrivate::Geometry) {
3400             QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3401             if (anchor)
3402                 anchor->updateVerticalAnchors();
3403         }
3404     }
3405
3406     if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor))
3407         QQuickAnchorsPrivate::get(d->_anchors)->updateVerticalAnchors();
3408
3409     emit baselineOffsetChanged(offset);
3410 }
3411
3412
3413 /*!
3414  * Schedules a call to updatePaintNode() for this item.
3415  *
3416  * The call to QQuickItem::updatePaintNode() will always happen if the
3417  * item is showing in a QQuickWindow.
3418  *
3419  * Only items which specifies QQuickItem::ItemHasContents are allowed
3420  * to call QQuickItem::update().
3421  */
3422 void QQuickItem::update()
3423 {
3424     Q_D(QQuickItem);
3425     Q_ASSERT(flags() & ItemHasContents);
3426     d->dirty(QQuickItemPrivate::Content);
3427 }
3428
3429 void QQuickItem::polish()
3430 {
3431     Q_D(QQuickItem);
3432     if (!d->polishScheduled) {
3433         d->polishScheduled = true;
3434         if (d->window) {
3435             QQuickWindowPrivate *p = QQuickWindowPrivate::get(d->window);
3436             bool maybeupdate = p->itemsToPolish.isEmpty();
3437             p->itemsToPolish.insert(this);
3438             if (maybeupdate) d->window->maybeUpdate();
3439         }
3440     }
3441 }
3442
3443 /*!
3444     \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
3445     \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y, real width, real height)
3446
3447     Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in \a
3448     item's coordinate system, to this item's coordinate system, and returns an object with \c x and
3449     \c y (and optionally \c width and \c height) properties matching the mapped coordinate.
3450
3451     If \a item is a \c null value, this maps the point or rect from the coordinate system of
3452     the root QML view.
3453 */
3454 void QQuickItem::mapFromItem(QQmlV8Function *args) const
3455 {
3456     if (args->Length() != 0) {
3457         v8::Local<v8::Value> item = (*args)[0];
3458         QV8Engine *engine = args->engine();
3459
3460         QQuickItem *itemObj = 0;
3461         if (!item->IsNull())
3462             itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3463
3464         if (!itemObj && !item->IsNull()) {
3465             qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3466                           << "\" which is neither null nor an Item";
3467             return;
3468         }
3469
3470         v8::Local<v8::Object> rv = v8::Object::New();
3471         args->returnValue(rv);
3472
3473         qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3474         qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3475
3476         if (args->Length() > 3) {
3477             qreal w = (*args)[3]->NumberValue();
3478             qreal h = (args->Length() > 4)?(*args)[4]->NumberValue():0;
3479
3480             QRectF r = mapRectFromItem(itemObj, QRectF(x, y, w, h));
3481
3482             rv->Set(v8::String::New("x"), v8::Number::New(r.x()));
3483             rv->Set(v8::String::New("y"), v8::Number::New(r.y()));
3484             rv->Set(v8::String::New("width"), v8::Number::New(r.width()));
3485             rv->Set(v8::String::New("height"), v8::Number::New(r.height()));
3486         } else {
3487             QPointF p = mapFromItem(itemObj, QPointF(x, y));
3488
3489             rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3490             rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3491         }
3492     }
3493 }
3494
3495 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3496 {
3497     Q_D(const QQuickItem);
3498
3499     // XXX todo - we need to be able to handle common parents better and detect
3500     // invalid cases
3501     if (ok) *ok = true;
3502
3503     QTransform t = d->itemToWindowTransform();
3504     if (other) t *= QQuickItemPrivate::get(other)->windowToItemTransform();
3505
3506     return t;
3507 }
3508
3509 /*!
3510     \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
3511     \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y, real width, real height)
3512
3513     Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in this
3514     item's coordinate system, to \a item's coordinate system, and returns an object with \c x and
3515     \c y (and optionally \c width and \c height) properties matching the mapped coordinate.
3516
3517     If \a item is a \c null value, this maps the point or rect to the coordinate system of the
3518     root QML view.
3519 */
3520 void QQuickItem::mapToItem(QQmlV8Function *args) const
3521 {
3522     if (args->Length() != 0) {
3523         v8::Local<v8::Value> item = (*args)[0];
3524         QV8Engine *engine = args->engine();
3525
3526         QQuickItem *itemObj = 0;
3527         if (!item->IsNull())
3528             itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3529
3530         if (!itemObj && !item->IsNull()) {
3531             qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3532                           << "\" which is neither null nor an Item";
3533             return;
3534         }
3535
3536         v8::Local<v8::Object> rv = v8::Object::New();
3537         args->returnValue(rv);
3538
3539         qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3540         qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3541
3542         if (args->Length() > 3) {
3543             qreal w = (*args)[3]->NumberValue();
3544             qreal h = (args->Length() > 4)?(*args)[4]->NumberValue():0;
3545
3546             QRectF r = mapRectToItem(itemObj, QRectF(x, y, w, h));
3547
3548             rv->Set(v8::String::New("x"), v8::Number::New(r.x()));
3549             rv->Set(v8::String::New("y"), v8::Number::New(r.y()));
3550             rv->Set(v8::String::New("width"), v8::Number::New(r.width()));
3551             rv->Set(v8::String::New("height"), v8::Number::New(r.height()));
3552         } else {
3553             QPointF p = mapToItem(itemObj, QPointF(x, y));
3554
3555             rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3556             rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3557         }
3558     }
3559 }
3560
3561 void QQuickItem::forceActiveFocus()
3562 {
3563     setFocus(true);
3564     QQuickItem *parent = parentItem();
3565     while (parent) {
3566         if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3567             parent->setFocus(true);
3568         }
3569         parent = parent->parentItem();
3570     }
3571 }
3572
3573 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3574 {
3575     // XXX todo - should this include transform etc.?
3576     const QList<QQuickItem *> children = childItems();
3577     for (int i = children.count()-1; i >= 0; --i) {
3578         QQuickItem *child = children.at(i);
3579         if (child->isVisible() && child->x() <= x
3580                 && child->x() + child->width() >= x
3581                 && child->y() <= y
3582                 && child->y() + child->height() >= y)
3583             return child;
3584     }
3585     return 0;
3586 }
3587
3588 QQmlListProperty<QObject> QQuickItemPrivate::resources()
3589 {
3590     return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3591                                              QQuickItemPrivate::resources_count,
3592                                              QQuickItemPrivate::resources_at,
3593                                              QQuickItemPrivate::resources_clear);
3594 }
3595
3596 QQmlListProperty<QQuickItem> QQuickItemPrivate::children()
3597 {
3598     return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3599                                              QQuickItemPrivate::children_count,
3600                                              QQuickItemPrivate::children_at,
3601                                              QQuickItemPrivate::children_clear);
3602
3603 }
3604
3605 /*!
3606   \qmlproperty real QtQuick2::Item::visibleChildren
3607   This read-only property lists all of the item's children that are currently visible.
3608   Note that a child's visibility may have changed explicitly, or because the visibility
3609   of this (it's parent) item or another grandparent changed.
3610 */
3611 QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
3612 {
3613     return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
3614                                              QQuickItemPrivate::visibleChildren_count,
3615                                              QQuickItemPrivate::visibleChildren_at);
3616
3617 }
3618
3619 QQmlListProperty<QQuickState> QQuickItemPrivate::states()
3620 {
3621     return _states()->statesProperty();
3622 }
3623
3624 QQmlListProperty<QQuickTransition> QQuickItemPrivate::transitions()
3625 {
3626     return _states()->transitionsProperty();
3627 }
3628
3629 QString QQuickItemPrivate::state() const
3630 {
3631     if (!_stateGroup)
3632         return QString();
3633     else
3634         return _stateGroup->state();
3635 }
3636
3637 void QQuickItemPrivate::setState(const QString &state)
3638 {
3639     _states()->setState(state);
3640 }
3641
3642 QString QQuickItem::state() const
3643 {
3644     Q_D(const QQuickItem);
3645     return d->state();
3646 }
3647
3648 void QQuickItem::setState(const QString &state)
3649 {
3650     Q_D(QQuickItem);
3651     d->setState(state);
3652 }
3653
3654 QQmlListProperty<QQuickTransform> QQuickItem::transform()
3655 {
3656     return QQmlListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3657                                                      QQuickItemPrivate::transform_count,
3658                                                      QQuickItemPrivate::transform_at,
3659                                                      QQuickItemPrivate::transform_clear);
3660 }
3661
3662 /*!
3663   \reimp
3664   Derived classes should call the base class method before adding their own action to
3665   perform at classBegin.
3666 */
3667 void QQuickItem::classBegin()
3668 {
3669     Q_D(QQuickItem);
3670     d->componentComplete = false;
3671     if (d->_stateGroup)
3672         d->_stateGroup->classBegin();
3673     if (d->_anchors)
3674         d->_anchors->classBegin();
3675     if (d->extra.isAllocated() && d->extra->layer)
3676         d->extra->layer->classBegin();
3677 }
3678
3679 /*!
3680   \reimp
3681   Derived classes should call the base class method before adding their own actions to
3682   perform at componentComplete.
3683 */
3684 void QQuickItem::componentComplete()
3685 {
3686     Q_D(QQuickItem);
3687     d->componentComplete = true;
3688     if (d->_stateGroup)
3689         d->_stateGroup->componentComplete();
3690     if (d->_anchors) {
3691         d->_anchors->componentComplete();
3692         QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3693     }
3694
3695     if (d->extra.isAllocated() && d->extra->layer)
3696         d->extra->layer->componentComplete();
3697
3698     if (d->extra.isAllocated() && d->extra->keyHandler)
3699         d->extra->keyHandler->componentComplete();
3700
3701     if (d->extra.isAllocated() && d->extra->contents)
3702         d->extra->contents->complete();
3703
3704     if (d->window && d->dirtyAttributes) {
3705         d->addToDirtyList();
3706         QQuickWindowPrivate::get(d->window)->dirtyItem(this);
3707     }
3708 }
3709
3710 QQuickStateGroup *QQuickItemPrivate::_states()
3711 {
3712     Q_Q(QQuickItem);
3713     if (!_stateGroup) {
3714         _stateGroup = new QQuickStateGroup;
3715         if (!componentComplete)
3716             _stateGroup->classBegin();
3717         qmlobject_connect(_stateGroup, QQuickStateGroup, SIGNAL(stateChanged(QString)),
3718                           q, QQuickItem, SIGNAL(stateChanged(QString)))
3719     }
3720
3721     return _stateGroup;
3722 }
3723
3724 QPointF QQuickItemPrivate::computeTransformOrigin() const
3725 {
3726     switch (origin()) {
3727     default:
3728     case QQuickItem::TopLeft:
3729         return QPointF(0, 0);
3730     case QQuickItem::Top:
3731         return QPointF(width / 2., 0);
3732     case QQuickItem::TopRight:
3733         return QPointF(width, 0);
3734     case QQuickItem::Left:
3735         return QPointF(0, height / 2.);
3736     case QQuickItem::Center:
3737         return QPointF(width / 2., height / 2.);
3738     case QQuickItem::Right:
3739         return QPointF(width, height / 2.);
3740     case QQuickItem::BottomLeft:
3741         return QPointF(0, height);
3742     case QQuickItem::Bottom:
3743         return QPointF(width / 2., height);
3744     case QQuickItem::BottomRight:
3745         return QPointF(width, height);
3746     }
3747 }
3748
3749 void QQuickItemPrivate::transformChanged()
3750 {
3751     if (extra.isAllocated() && extra->layer)
3752         extra->layer->updateMatrix();
3753 }
3754
3755 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3756 {
3757     Q_Q(QQuickItem);
3758
3759     Q_ASSERT(e->isAccepted());
3760     if (extra.isAllocated() && extra->keyHandler) {
3761         if (e->type() == QEvent::KeyPress)
3762             extra->keyHandler->keyPressed(e, false);
3763         else
3764             extra->keyHandler->keyReleased(e, false);
3765
3766         if (e->isAccepted())
3767             return;
3768         else
3769             e->accept();
3770     }
3771
3772     if (e->type() == QEvent::KeyPress)
3773         q->keyPressEvent(e);
3774     else
3775         q->keyReleaseEvent(e);
3776
3777     if (e->isAccepted())
3778         return;
3779
3780     if (extra.isAllocated() && extra->keyHandler) {
3781         e->accept();
3782
3783         if (e->type() == QEvent::KeyPress)
3784             extra->keyHandler->keyPressed(e, true);
3785         else
3786             extra->keyHandler->keyReleased(e, true);
3787     }
3788 }
3789
3790 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3791 {
3792     Q_Q(QQuickItem);
3793
3794     Q_ASSERT(e->isAccepted());
3795     if (extra.isAllocated() && extra->keyHandler) {
3796         extra->keyHandler->inputMethodEvent(e, false);
3797
3798         if (e->isAccepted())
3799             return;
3800         else
3801             e->accept();
3802     }
3803
3804     q->inputMethodEvent(e);
3805
3806     if (e->isAccepted())
3807         return;
3808
3809     if (extra.isAllocated() && extra->keyHandler) {
3810         e->accept();
3811
3812         extra->keyHandler->inputMethodEvent(e, true);
3813     }
3814 }
3815
3816 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3817 {
3818     Q_Q(QQuickItem);
3819
3820     if (e->type() == QEvent::FocusIn) {
3821         q->focusInEvent(e);
3822     } else {
3823         q->focusOutEvent(e);
3824     }
3825 }
3826
3827 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3828 {
3829     Q_Q(QQuickItem);
3830
3831     Q_ASSERT(e->isAccepted());
3832
3833     switch (e->type()) {
3834     default:
3835         Q_ASSERT(!"Unknown event type");
3836     case QEvent::MouseMove:
3837         q->mouseMoveEvent(e);
3838         break;
3839     case QEvent::MouseButtonPress:
3840         q->mousePressEvent(e);
3841         break;
3842     case QEvent::MouseButtonRelease:
3843         q->mouseReleaseEvent(e);
3844         break;
3845     case QEvent::MouseButtonDblClick:
3846         q->mouseDoubleClickEvent(e);
3847         break;
3848     }
3849 }
3850
3851 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3852 {
3853     Q_Q(QQuickItem);
3854     q->wheelEvent(e);
3855 }
3856
3857 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3858 {
3859     Q_Q(QQuickItem);
3860     q->touchEvent(e);
3861 }
3862
3863 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3864 {
3865     Q_Q(QQuickItem);
3866     switch (e->type()) {
3867     default:
3868         Q_ASSERT(!"Unknown event type");
3869     case QEvent::HoverEnter:
3870         q->hoverEnterEvent(e);
3871         break;
3872     case QEvent::HoverLeave:
3873         q->hoverLeaveEvent(e);
3874         break;
3875     case QEvent::HoverMove:
3876         q->hoverMoveEvent(e);
3877         break;
3878     }
3879 }
3880
3881 #ifndef QT_NO_DRAGANDDROP
3882 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3883 {
3884     Q_Q(QQuickItem);
3885     switch (e->type()) {
3886     default:
3887         Q_ASSERT(!"Unknown event type");
3888     case QEvent::DragEnter:
3889         q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3890         break;
3891     case QEvent::DragLeave:
3892         q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3893         break;
3894     case QEvent::DragMove:
3895         q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3896         break;
3897     case QEvent::Drop:
3898         q->dropEvent(static_cast<QDropEvent *>(e));
3899         break;
3900     }
3901 }
3902 #endif // QT_NO_DRAGANDDROP
3903
3904 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3905 {
3906     Q_UNUSED(change);
3907     Q_UNUSED(value);
3908 }
3909
3910 /*!
3911     Notify input method on updated query values if needed. \a indicates changed attributes.
3912 */
3913 void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
3914 {
3915     if (hasActiveFocus())
3916         qApp->inputMethod()->update(queries);
3917 }
3918
3919 /*! \internal */
3920 // XXX todo - do we want/need this anymore?
3921 QRectF QQuickItem::boundingRect() const
3922 {
3923     Q_D(const QQuickItem);
3924     return QRectF(0, 0, d->width, d->height);
3925 }
3926
3927 /*! \internal */
3928 QRectF QQuickItem::clipRect() const
3929 {
3930     Q_D(const QQuickItem);
3931     return QRectF(0, 0, d->width, d->height);
3932 }
3933
3934
3935 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3936 {
3937     Q_D(const QQuickItem);
3938     return d->origin();
3939 }
3940
3941 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3942 {
3943     Q_D(QQuickItem);
3944     if (origin == d->origin())
3945         return;
3946
3947     d->extra.value().origin = origin;
3948     d->dirty(QQuickItemPrivate::TransformOrigin);
3949
3950     emit transformOriginChanged(d->origin());
3951 }
3952
3953 QPointF QQuickItem::transformOriginPoint() const
3954 {
3955     Q_D(const QQuickItem);
3956     if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
3957         return d->extra->userTransformOriginPoint;
3958     return d->computeTransformOrigin();
3959 }
3960
3961 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3962 {
3963     Q_D(QQuickItem);
3964     if (d->extra.value().userTransformOriginPoint == point)
3965         return;
3966
3967     d->extra->userTransformOriginPoint = point;
3968     d->dirty(QQuickItemPrivate::TransformOrigin);
3969 }
3970
3971 qreal QQuickItem::z() const
3972 {
3973     Q_D(const QQuickItem);
3974     return d->z();
3975 }
3976
3977 void QQuickItem::setZ(qreal v)
3978 {
3979     Q_D(QQuickItem);
3980     if (d->z() == v)
3981         return;
3982
3983     d->extra.value().z = v;
3984
3985     d->dirty(QQuickItemPrivate::ZValue);
3986     if (d->parentItem) {
3987         QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3988         QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3989     }
3990
3991     emit zChanged();
3992
3993     if (d->extra.isAllocated() && d->extra->layer)
3994         d->extra->layer->updateZ();
3995 }
3996
3997
3998 /*!
3999   \qmlproperty real QtQuick2::Item::rotation
4000   This property holds the rotation of the item in degrees clockwise.
4001
4002   This specifies how many degrees to rotate the item around its transformOrigin.
4003   The default rotation is 0 degrees (i.e. not rotated at all).
4004
4005   \table
4006   \row
4007   \li \image declarative-rotation.png
4008   \li
4009   \qml
4010   Rectangle {
4011       color: "blue"
4012       width: 100; height: 100
4013       Rectangle {
4014           color: "red"
4015           x: 25; y: 25; width: 50; height: 50
4016           rotation: 30
4017       }
4018   }
4019   \endqml
4020   \endtable
4021
4022   \sa transform, Rotation
4023 */
4024
4025 /*!
4026   \qmlproperty real QtQuick2::Item::scale
4027   This property holds the scale of the item.
4028
4029   A scale of less than 1 means the item will be displayed smaller than
4030   normal, and a scale of greater than 1 means the item will be
4031   displayed larger than normal.  A negative scale means the item will
4032   be mirrored.
4033
4034   By default, items are displayed at a scale of 1 (i.e. at their
4035   normal size).
4036
4037   Scaling is from the item's transformOrigin.
4038
4039   \table
4040   \row
4041   \li \image declarative-scale.png
4042   \li
4043   \qml
4044   Rectangle {
4045       color: "blue"
4046       width: 100; height: 100
4047       Rectangle {
4048           color: "green"
4049           width: 25; height: 25
4050       }
4051       Rectangle {
4052           color: "red"
4053           x: 25; y: 25; width: 50; height: 50
4054           scale: 1.4
4055       }
4056   }
4057   \endqml
4058   \endtable
4059
4060   \sa transform, Scale
4061 */
4062
4063 /*!
4064   \qmlproperty real QtQuick2::Item::opacity
4065
4066   This property holds the opacity of the item.  Opacity is specified as a
4067   number between 0 (fully transparent) and 1 (fully opaque).  The default is 1.
4068
4069   When this property is set, the specified opacity is also applied
4070   individually to child items.  In almost all cases this is what you want,
4071   but in some cases it may produce undesired results. For example in the
4072   second set of rectangles below, the red rectangle has specified an opacity
4073   of 0.5, which affects the opacity of its blue child rectangle even though
4074   the child has not specified an opacity.
4075
4076   \table
4077   \row
4078   \li \image declarative-item_opacity1.png
4079   \li
4080   \qml
4081     Item {
4082         Rectangle {
4083             color: "red"
4084             width: 100; height: 100
4085             Rectangle {
4086                 color: "blue"
4087                 x: 50; y: 50; width: 100; height: 100
4088             }
4089         }
4090     }
4091   \endqml
4092   \row
4093   \li \image declarative-item_opacity2.png
4094   \li
4095   \qml
4096     Item {
4097         Rectangle {
4098             opacity: 0.5
4099             color: "red"
4100             width: 100; height: 100
4101             Rectangle {
4102                 color: "blue"
4103                 x: 50; y: 50; width: 100; height: 100
4104             }
4105         }
4106     }
4107   \endqml
4108   \endtable
4109
4110   Changing an items opacity will not affect delivery of input events.  (In contrast
4111   setting \l visible property to \c false stops mouse events, and setting the
4112   \l enabled property to \c false stops mouse and keyboard events, and also removes
4113   active focus from the item.)
4114 */
4115
4116 /*!
4117   Returns a value indicating whether mouse input should
4118   remain with this item exclusively.
4119
4120   \sa setKeepMouseGrab()
4121  */
4122
4123 qreal QQuickItem::rotation() const
4124 {
4125     Q_D(const QQuickItem);
4126     return d->rotation();
4127 }
4128
4129 void QQuickItem::setRotation(qreal r)
4130 {
4131     Q_D(QQuickItem);
4132     if (d->rotation() == r)
4133         return;
4134
4135     d->extra.value().rotation = r;
4136
4137     d->dirty(QQuickItemPrivate::BasicTransform);
4138
4139     d->itemChange(ItemRotationHasChanged, r);
4140
4141     emit rotationChanged();
4142 }
4143
4144 qreal QQuickItem::scale() const
4145 {
4146     Q_D(const QQuickItem);
4147     return d->scale();
4148 }
4149
4150 void QQuickItem::setScale(qreal s)
4151 {
4152     Q_D(QQuickItem);
4153     if (d->scale() == s)
4154         return;
4155
4156     d->extra.value().scale = s;
4157
4158     d->dirty(QQuickItemPrivate::BasicTransform);
4159
4160     emit scaleChanged();
4161 }
4162
4163 qreal QQuickItem::opacity() const
4164 {
4165     Q_D(const QQuickItem);
4166     return d->opacity();
4167 }
4168
4169 void QQuickItem::setOpacity(qreal o)
4170 {
4171     Q_D(QQuickItem);
4172     if (d->opacity() == o)
4173         return;
4174
4175     d->extra.value().opacity = o;
4176
4177     d->dirty(QQuickItemPrivate::OpacityValue);
4178
4179     d->itemChange(ItemOpacityHasChanged, o);
4180
4181     emit opacityChanged();
4182 }
4183
4184 bool QQuickItem::isVisible() const
4185 {
4186     Q_D(const QQuickItem);
4187     return d->effectiveVisible;
4188 }
4189
4190 void QQuickItem::setVisible(bool v)
4191 {
4192     Q_D(QQuickItem);
4193     if (v == d->explicitVisible)
4194         return;
4195
4196     d->explicitVisible = v;
4197     if (!v)
4198         d->dirty(QQuickItemPrivate::Visible);
4199
4200     const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
4201     if (childVisibilityChanged && d->parentItem)
4202         emit d->parentItem->visibleChildrenChanged();   // signal the parent, not this!
4203 }
4204
4205 bool QQuickItem::isEnabled() const
4206 {
4207     Q_D(const QQuickItem);
4208     return d->effectiveEnable;
4209 }
4210
4211 void QQuickItem::setEnabled(bool e)
4212 {
4213     Q_D(QQuickItem);
4214     if (e == d->explicitEnable)
4215         return;
4216
4217     d->explicitEnable = e;
4218
4219     QQuickItem *scope = parentItem();
4220     while (scope && !scope->isFocusScope())
4221         scope = scope->parentItem();
4222
4223     d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
4224 }
4225
4226 bool QQuickItemPrivate::calcEffectiveVisible() const
4227 {
4228     // XXX todo - Should the effective visible of an element with no parent just be the current
4229     // effective visible?  This would prevent pointless re-processing in the case of an element
4230     // moving to/from a no-parent situation, but it is different from what graphics view does.
4231     return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
4232 }
4233
4234 bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
4235 {
4236     Q_Q(QQuickItem);
4237
4238     if (newEffectiveVisible && !explicitVisible) {
4239         // This item locally overrides visibility
4240         return false;   // effective visibility didn't change
4241     }
4242
4243     if (newEffectiveVisible == effectiveVisible) {
4244         // No change necessary
4245         return false;   // effective visibility didn't change
4246     }
4247
4248     effectiveVisible = newEffectiveVisible;
4249     dirty(Visible);
4250     if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4251
4252     if (window) {
4253         QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
4254         if (windowPriv->mouseGrabberItem == q)
4255             q->ungrabMouse();
4256     }
4257
4258     bool childVisibilityChanged = false;
4259     for (int ii = 0; ii < childItems.count(); ++ii)
4260         childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
4261
4262     itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
4263 #ifndef QT_NO_ACCESSIBILITY
4264     if (isAccessible) {
4265         QAccessibleEvent ev(q, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide);
4266         QAccessible::updateAccessibility(&ev);
4267     }
4268 #endif
4269     emit q->visibleChanged();
4270     if (childVisibilityChanged)
4271         emit q->visibleChildrenChanged();
4272
4273     return true;    // effective visibility DID change
4274 }
4275
4276 bool QQuickItemPrivate::calcEffectiveEnable() const
4277 {
4278     // XXX todo - Should the effective enable of an element with no parent just be the current
4279     // effective enable?  This would prevent pointless re-processing in the case of an element
4280     // moving to/from a no-parent situation, but it is different from what graphics view does.
4281     return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
4282 }
4283
4284 void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
4285 {
4286     Q_Q(QQuickItem);
4287
4288     if (newEffectiveEnable && !explicitEnable) {
4289         // This item locally overrides enable
4290         return;
4291     }
4292
4293     if (newEffectiveEnable == effectiveEnable) {
4294         // No change necessary
4295         return;
4296     }
4297
4298     effectiveEnable = newEffectiveEnable;
4299
4300     if (window) {
4301         QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
4302         if (windowPriv->mouseGrabberItem == q)
4303             q->ungrabMouse();
4304         if (scope && !effectiveEnable && activeFocus) {
4305             windowPriv->clearFocusInScope(
4306                     scope, q,  QQuickWindowPrivate::DontChangeFocusProperty | QQuickWindowPrivate::DontChangeSubFocusItem);
4307         }
4308     }
4309
4310     for (int ii = 0; ii < childItems.count(); ++ii) {
4311         QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
4312                 (flags & QQuickItem::ItemIsFocusScope) && scope ? q : scope, newEffectiveEnable);
4313     }
4314
4315     if (window && scope && effectiveEnable && focus) {
4316         QQuickWindowPrivate::get(window)->setFocusInScope(
4317                 scope, q, QQuickWindowPrivate::DontChangeFocusProperty | QQuickWindowPrivate::DontChangeSubFocusItem);
4318     }
4319
4320     emit q->enabledChanged();
4321 }
4322
4323 QString QQuickItemPrivate::dirtyToString() const
4324 {
4325 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
4326     if (!rv.isEmpty()) \
4327         rv.append(QLatin1String("|")); \
4328     rv.append(QLatin1String(#value)); \
4329 }
4330
4331 //    QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
4332     QString rv;
4333
4334     DIRTY_TO_STRING(TransformOrigin);
4335     DIRTY_TO_STRING(Transform);
4336     DIRTY_TO_STRING(BasicTransform);
4337     DIRTY_TO_STRING(Position);
4338     DIRTY_TO_STRING(Size);
4339     DIRTY_TO_STRING(ZValue);
4340     DIRTY_TO_STRING(Content);
4341     DIRTY_TO_STRING(Smooth);
4342     DIRTY_TO_STRING(OpacityValue);
4343     DIRTY_TO_STRING(ChildrenChanged);
4344     DIRTY_TO_STRING(ChildrenStackingChanged);
4345     DIRTY_TO_STRING(ParentChanged);
4346     DIRTY_TO_STRING(Clip);
4347     DIRTY_TO_STRING(Window);
4348     DIRTY_TO_STRING(EffectReference);
4349     DIRTY_TO_STRING(Visible);
4350     DIRTY_TO_STRING(HideReference);
4351     DIRTY_TO_STRING(Antialiasing);
4352
4353     return rv;
4354 }
4355
4356 void QQuickItemPrivate::dirty(DirtyType type)
4357 {
4358     Q_Q(QQuickItem);
4359     if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4360         transformChanged();
4361
4362     if (!(dirtyAttributes & type) || (window && !prevDirtyItem)) {
4363         dirtyAttributes |= type;
4364         if (window && componentComplete) {
4365             addToDirtyList();
4366             QQuickWindowPrivate::get(window)->dirtyItem(q);
4367         }
4368     }
4369 }
4370
4371 void QQuickItemPrivate::addToDirtyList()
4372 {
4373     Q_Q(QQuickItem);
4374
4375     Q_ASSERT(window);
4376     if (!prevDirtyItem) {
4377         Q_ASSERT(!nextDirtyItem);
4378
4379         QQuickWindowPrivate *p = QQuickWindowPrivate::get(window);
4380         nextDirtyItem = p->dirtyItemList;
4381         if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4382         prevDirtyItem = &p->dirtyItemList;
4383         p->dirtyItemList = q;
4384         p->dirtyItem(q);
4385     }
4386     Q_ASSERT(prevDirtyItem);
4387 }
4388
4389 void QQuickItemPrivate::removeFromDirtyList()
4390 {
4391     if (prevDirtyItem) {
4392         if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4393         *prevDirtyItem = nextDirtyItem;
4394         prevDirtyItem = 0;
4395         nextDirtyItem = 0;
4396     }
4397     Q_ASSERT(!prevDirtyItem);
4398     Q_ASSERT(!nextDirtyItem);
4399 }
4400
4401 void QQuickItemPrivate::refFromEffectItem(bool hide)
4402 {
4403     ++extra.value().effectRefCount;
4404     if (1 == extra->effectRefCount) {
4405         dirty(EffectReference);
4406         if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4407     }
4408     if (hide) {
4409         if (++extra->hideRefCount == 1)
4410             dirty(HideReference);
4411     }
4412 }
4413
4414 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4415 {
4416     Q_ASSERT(extra->effectRefCount);
4417     --extra->effectRefCount;
4418     if (0 == extra->effectRefCount) {
4419         dirty(EffectReference);
4420         if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4421     }
4422     if (unhide) {
4423         if (--extra->hideRefCount == 0)
4424             dirty(HideReference);
4425     }
4426 }
4427
4428 void QQuickItemPrivate::setCulled(bool cull)
4429 {
4430     if (cull == culled)
4431         return;
4432
4433     culled = cull;
4434     if ((cull && ++extra->hideRefCount == 1) || (!cull && --extra->hideRefCount == 0))
4435         dirty(HideReference);
4436 }
4437
4438 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4439 {
4440     Q_Q(QQuickItem);
4441     switch (change) {
4442     case QQuickItem::ItemChildAddedChange:
4443         q->itemChange(change, data);
4444         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4445             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4446             if (change.types & QQuickItemPrivate::Children) {
4447                 change.listener->itemChildAdded(q, data.item);
4448             }
4449         }
4450         break;
4451     case QQuickItem::ItemChildRemovedChange:
4452         q->itemChange(change, data);
4453         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4454             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4455             if (change.types & QQuickItemPrivate::Children) {
4456                 change.listener->itemChildRemoved(q, data.item);
4457             }
4458         }
4459         break;
4460     case QQuickItem::ItemSceneChange:
4461         q->itemChange(change, data);
4462         break;
4463     case QQuickItem::ItemVisibleHasChanged:
4464         q->itemChange(change, data);
4465         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4466             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4467             if (change.types & QQuickItemPrivate::Visibility) {
4468                 change.listener->itemVisibilityChanged(q);
4469             }
4470         }
4471         break;
4472     case QQuickItem::ItemParentHasChanged:
4473         q->itemChange(change, data);
4474         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4475             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4476             if (change.types & QQuickItemPrivate::Parent) {
4477                 change.listener->itemParentChanged(q, data.item);
4478             }
4479         }
4480         break;
4481     case QQuickItem::ItemOpacityHasChanged:
4482         q->itemChange(change, data);
4483         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4484             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4485             if (change.types & QQuickItemPrivate::Opacity) {
4486                 change.listener->itemOpacityChanged(q);
4487             }
4488         }
4489         break;
4490     case QQuickItem::ItemActiveFocusHasChanged:
4491         q->itemChange(change, data);
4492         break;
4493     case QQuickItem::ItemRotationHasChanged:
4494         q->itemChange(change, data);
4495         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4496             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4497             if (change.types & QQuickItemPrivate::Rotation) {
4498                 change.listener->itemRotationChanged(q);
4499             }
4500         }
4501         break;
4502     }
4503 }
4504
4505 /*!
4506     \property QQuickItem::smooth
4507     \brief Specifies whether the item is smoothed or not
4508
4509     Primarily used in image based items to decide if the item should use smooth
4510     sampling or not. Smooth sampling is performed using linear interpolation, while
4511     non-smooth is performed using nearest neighbor.
4512
4513     In Qt Quick 2.0, this property has minimal impact on performance.
4514
4515     By default is true.
4516 */
4517
4518 /*!
4519     Returns true if the item should be drawn with
4520     smooth pixmap filtering, false otherwise.
4521
4522     The default is true.
4523
4524     \sa setSmooth()
4525 */
4526 bool QQuickItem::smooth() const
4527 {
4528     Q_D(const QQuickItem);
4529     return d->smooth;
4530 }
4531
4532 /*!
4533     Sets whether the item should be drawn with antialiasing and
4534     smooth pixmap filtering to \a smooth.
4535
4536     \sa smooth()
4537 */
4538 void QQuickItem::setSmooth(bool smooth)
4539 {
4540     Q_D(QQuickItem);
4541     if (d->smooth == smooth)
4542         return;
4543
4544     d->smooth = smooth;
4545     d->dirty(QQuickItemPrivate::Smooth);
4546
4547     emit smoothChanged(smooth);
4548 }
4549
4550 /*!
4551     \property QQuickItem::antialiasing
4552     \brief Specifies whether the item is antialiased or not
4553
4554     Primarily used in Rectangle and image based elements to decide if the item should
4555     use antialiasing or not. Items with antialiasing enabled require more memory and
4556     are potentially slower to render.
4557
4558     The default is false.
4559 */
4560
4561 /*!
4562     Returns true if the item should be drawn with antialiasing, false otherwise.
4563
4564     The default is false.
4565
4566     \sa setAntialiasing()
4567 */
4568 bool QQuickItem::antialiasing() const
4569 {
4570     Q_D(const QQuickItem);
4571     return d->antialiasing;
4572 }
4573
4574 /*!
4575     Sets whether the item should be drawn with antialiasing to \a antialiasing.
4576
4577     \sa antialiasing()
4578 */
4579 void QQuickItem::setAntialiasing(bool antialiasing)
4580 {
4581     Q_D(QQuickItem);
4582     if (d->antialiasing == antialiasing)
4583         return;
4584
4585     d->antialiasing = antialiasing;
4586     d->dirty(QQuickItemPrivate::Antialiasing);
4587
4588     emit antialiasingChanged(antialiasing);
4589 }
4590
4591 QQuickItem::Flags QQuickItem::flags() const
4592 {
4593     Q_D(const QQuickItem);
4594     return (QQuickItem::Flags)d->flags;
4595 }
4596
4597 void QQuickItem::setFlag(Flag flag, bool enabled)
4598 {
4599     Q_D(QQuickItem);
4600     if (enabled)
4601         setFlags((Flags)(d->flags | (quint32)flag));
4602     else
4603         setFlags((Flags)(d->flags & ~(quint32)flag));
4604 }
4605
4606 void QQuickItem::setFlags(Flags flags)
4607 {
4608     Q_D(QQuickItem);
4609
4610     if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4611         if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->window) {
4612             qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a window.");
4613             flags &= ~ItemIsFocusScope;
4614         } else if (d->flags & ItemIsFocusScope) {
4615             qWarning("QQuickItem: Cannot unset FocusScope flag.");
4616             flags |= ItemIsFocusScope;
4617         }
4618     }
4619
4620     if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4621         d->dirty(QQuickItemPrivate::Clip);
4622
4623     d->flags = flags;
4624 }
4625
4626 qreal QQuickItem::x() const
4627 {
4628     Q_D(const QQuickItem);
4629     return d->x;
4630 }
4631
4632 qreal QQuickItem::y() const
4633 {
4634     Q_D(const QQuickItem);
4635     return d->y;
4636 }
4637
4638 QPointF QQuickItem::pos() const
4639 {
4640     Q_D(const QQuickItem);
4641     return QPointF(d->x, d->y);
4642 }
4643
4644 void QQuickItem::setX(qreal v)
4645 {
4646     Q_D(QQuickItem);
4647     if (d->x == v)
4648         return;
4649
4650     qreal oldx = d->x;
4651     d->x = v;
4652
4653     d->dirty(QQuickItemPrivate::Position);
4654
4655     geometryChanged(QRectF(x(), y(), width(), height()),
4656                     QRectF(oldx, y(), width(), height()));
4657 }
4658
4659 void QQuickItem::setY(qreal v)
4660 {
4661     Q_D(QQuickItem);
4662     if (d->y == v)
4663         return;
4664
4665     qreal oldy = d->y;
4666     d->y = v;
4667
4668     d->dirty(QQuickItemPrivate::Position);
4669
4670     geometryChanged(QRectF(x(), y(), width(), height()),
4671                     QRectF(x(), oldy, width(), height()));
4672 }
4673
4674 void QQuickItem::setPos(const QPointF &pos)
4675 {
4676     Q_D(QQuickItem);
4677     if (QPointF(d->x, d->y) == pos)
4678         return;
4679
4680     qreal oldx = d->x;
4681     qreal oldy = d->y;
4682
4683     d->x = pos.x();
4684     d->y = pos.y();
4685
4686     d->dirty(QQuickItemPrivate::Position);
4687
4688     geometryChanged(QRectF(x(), y(), width(), height()),
4689                     QRectF(oldx, oldy, width(), height()));
4690 }
4691
4692 qreal QQuickItem::width() const
4693 {
4694     Q_D(const QQuickItem);
4695     return d->width;
4696 }
4697
4698 void QQuickItem::setWidth(qreal w)
4699 {
4700     Q_D(QQuickItem);
4701     if (qIsNaN(w))
4702         return;
4703
4704     d->widthValid = true;
4705     if (d->width == w)
4706         return;
4707
4708     qreal oldWidth = d->width;
4709     d->width = w;
4710
4711     d->dirty(QQuickItemPrivate::Size);
4712
4713     geometryChanged(QRectF(x(), y(), width(), height()),
4714                     QRectF(x(), y(), oldWidth, height()));
4715 }
4716
4717 void QQuickItem::resetWidth()
4718 {
4719     Q_D(QQuickItem);
4720     d->widthValid = false;
4721     setImplicitWidth(implicitWidth());
4722 }
4723
4724 void QQuickItemPrivate::implicitWidthChanged()
4725 {
4726     Q_Q(QQuickItem);
4727     for (int ii = 0; ii < changeListeners.count(); ++ii) {
4728         const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4729         if (change.types & QQuickItemPrivate::ImplicitWidth) {
4730             change.listener->itemImplicitWidthChanged(q);
4731         }
4732     }
4733     emit q->implicitWidthChanged();
4734 }
4735
4736 qreal QQuickItemPrivate::getImplicitWidth() const
4737 {
4738     return implicitWidth;
4739 }
4740 /*!
4741     Returns the width of the item that is implied by other properties that determine the content.
4742 */
4743 qreal QQuickItem::implicitWidth() const
4744 {
4745     Q_D(const QQuickItem);
4746     return d->getImplicitWidth();
4747 }
4748
4749 /*!
4750     \qmlproperty real QtQuick2::Item::implicitWidth
4751     \qmlproperty real QtQuick2::Item::implicitHeight
4752
4753     Defines the natural width or height of the Item if no \l width or \l height is specified.
4754
4755     The default implicit size for most items is 0x0, however some items have an inherent
4756     implicit size which cannot be overridden, e.g. Image, Text.
4757
4758     Setting the implicit size is useful for defining components that have a preferred size
4759     based on their content, for example:
4760
4761     \qml
4762     // Label.qml
4763     import QtQuick 2.0
4764
4765     Item {
4766         property alias icon: image.source
4767         property alias label: text.text
4768         implicitWidth: text.implicitWidth + image.implicitWidth
4769         implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4770         Image { id: image }
4771         Text {
4772             id: text
4773             wrapMode: Text.Wrap
4774             anchors.left: image.right; anchors.right: parent.right
4775             anchors.verticalCenter: parent.verticalCenter
4776         }
4777     }
4778     \endqml
4779
4780     \b Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4781     incurs a performance penalty as the text must be laid out twice.
4782 */
4783
4784 /*!
4785     Sets the implied width of the item to \a w.
4786     This is the width implied by other properties that determine the content.
4787 */
4788 void QQuickItem::setImplicitWidth(qreal w)
4789 {
4790     Q_D(QQuickItem);
4791     bool changed = w != d->implicitWidth;
4792     d->implicitWidth = w;
4793     if (d->width == w || widthValid()) {
4794         if (changed)
4795             d->implicitWidthChanged();
4796         if (d->width == w || widthValid())
4797             return;
4798         changed = false;
4799     }
4800
4801     qreal oldWidth = d->width;
4802     d->width = w;
4803
4804     d->dirty(QQuickItemPrivate::Size);
4805
4806     geometryChanged(QRectF(x(), y(), width(), height()),
4807                     QRectF(x(), y(), oldWidth, height()));
4808
4809     if (changed)
4810         d->implicitWidthChanged();
4811 }
4812
4813 /*!
4814     Returns whether the width property has been set explicitly.
4815 */
4816 bool QQuickItem::widthValid() const
4817 {
4818     Q_D(const QQuickItem);
4819     return d->widthValid;
4820 }
4821
4822 qreal QQuickItem::height() const
4823 {
4824     Q_D(const QQuickItem);
4825     return d->height;
4826 }
4827
4828 void QQuickItem::setHeight(qreal h)
4829 {
4830     Q_D(QQuickItem);
4831     if (qIsNaN(h))
4832         return;
4833
4834     d->heightValid = true;
4835     if (d->height == h)
4836         return;
4837
4838     qreal oldHeight = d->height;
4839     d->height = h;
4840
4841     d->dirty(QQuickItemPrivate::Size);
4842
4843     geometryChanged(QRectF(x(), y(), width(), height()),
4844                     QRectF(x(), y(), width(), oldHeight));
4845 }
4846
4847 void QQuickItem::resetHeight()
4848 {
4849     Q_D(QQuickItem);
4850     d->heightValid = false;
4851     setImplicitHeight(implicitHeight());
4852 }
4853
4854 void QQuickItemPrivate::implicitHeightChanged()
4855 {
4856     Q_Q(QQuickItem);
4857     for (int ii = 0; ii < changeListeners.count(); ++ii) {
4858         const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4859         if (change.types & QQuickItemPrivate::ImplicitHeight) {
4860             change.listener->itemImplicitHeightChanged(q);
4861         }
4862     }
4863     emit q->implicitHeightChanged();
4864 }
4865
4866 qreal QQuickItemPrivate::getImplicitHeight() const
4867 {
4868     return implicitHeight;
4869 }
4870
4871 /*!
4872     Returns the height of the item that is implied by other properties that determine the content.
4873 */
4874 qreal QQuickItem::implicitHeight() const
4875 {
4876     Q_D(const QQuickItem);
4877     return d->getImplicitHeight();
4878 }
4879
4880
4881 /*!
4882     Sets the implied height of the item to \a h.
4883     This is the height implied by other properties that determine the content.
4884 */
4885 void QQuickItem::setImplicitHeight(qreal h)
4886 {
4887     Q_D(QQuickItem);
4888     bool changed = h != d->implicitHeight;
4889     d->implicitHeight = h;
4890     if (d->height == h || heightValid()) {
4891         if (changed)
4892             d->implicitHeightChanged();
4893         if (d->height == h || heightValid())
4894             return;
4895         changed = false;
4896     }
4897
4898     qreal oldHeight = d->height;
4899     d->height = h;
4900
4901     d->dirty(QQuickItemPrivate::Size);
4902
4903     geometryChanged(QRectF(x(), y(), width(), height()),
4904                     QRectF(x(), y(), width(), oldHeight));
4905
4906     if (changed)
4907         d->implicitHeightChanged();
4908 }
4909
4910 void QQuickItem::setImplicitSize(qreal w, qreal h)
4911 {
4912     Q_D(QQuickItem);
4913     bool wChanged = w != d->implicitWidth;
4914     bool hChanged = h != d->implicitHeight;
4915
4916     d->implicitWidth = w;
4917     d->implicitHeight = h;
4918
4919     bool wDone = false;
4920     bool hDone = false;
4921     if (d->width == w || widthValid()) {
4922         if (wChanged)
4923             d->implicitWidthChanged();
4924         wDone = d->width == w || widthValid();
4925         wChanged = false;
4926     }
4927     if (d->height == h || heightValid()) {
4928         if (hChanged)
4929             d->implicitHeightChanged();
4930         hDone = d->height == h || heightValid();
4931         hChanged = false;
4932     }
4933     if (wDone && hDone)
4934         return;
4935
4936     qreal oldWidth = d->width;
4937     qreal oldHeight = d->height;
4938     if (!wDone)
4939         d->width = w;
4940     if (!hDone)
4941         d->height = h;
4942
4943     d->dirty(QQuickItemPrivate::Size);
4944
4945     geometryChanged(QRectF(x(), y(), width(), height()),
4946                     QRectF(x(), y(), oldWidth, oldHeight));
4947
4948     if (!wDone && wChanged)
4949         d->implicitWidthChanged();
4950     if (!hDone && hChanged)
4951         d->implicitHeightChanged();
4952 }
4953
4954 /*!
4955     Returns whether the height property has been set explicitly.
4956 */
4957 bool QQuickItem::heightValid() const
4958 {
4959     Q_D(const QQuickItem);
4960     return d->heightValid;
4961 }
4962
4963 void QQuickItem::setSize(const QSizeF &size)
4964 {
4965     Q_D(QQuickItem);
4966     d->heightValid = true;
4967     d->widthValid = true;
4968
4969     if (QSizeF(d->width, d->height) == size)
4970         return;
4971
4972     qreal oldHeight = d->height;
4973     qreal oldWidth = d->width;
4974     d->height = size.height();
4975     d->width = size.width();
4976
4977     d->dirty(QQuickItemPrivate::Size);
4978
4979     geometryChanged(QRectF(x(), y(), width(), height()),
4980                     QRectF(x(), y(), oldWidth, oldHeight));
4981 }
4982
4983 bool QQuickItem::hasActiveFocus() const
4984 {
4985     Q_D(const QQuickItem);
4986     return d->activeFocus;
4987 }
4988
4989 bool QQuickItem::hasFocus() const
4990 {
4991     Q_D(const QQuickItem);
4992     return d->focus;
4993 }
4994
4995 void QQuickItem::setFocus(bool focus)
4996 {
4997     Q_D(QQuickItem);
4998     if (d->focus == focus)
4999         return;
5000
5001     if (d->window || d->parentItem) {
5002         // Need to find our nearest focus scope
5003         QQuickItem *scope = parentItem();
5004         while (scope && !scope->isFocusScope() && scope->parentItem())
5005             scope = scope->parentItem();
5006         if (d->window) {
5007             if (focus)
5008                 QQuickWindowPrivate::get(d->window)->setFocusInScope(scope, this);
5009             else
5010                 QQuickWindowPrivate::get(d->window)->clearFocusInScope(scope, this);
5011         } else {
5012             // do the focus changes from setFocusInScope/clearFocusInScope that are
5013             // unrelated to a window
5014             QVarLengthArray<QQuickItem *, 20> changed;
5015             QQuickItem *oldSubFocusItem = QQuickItemPrivate::get(scope)->subFocusItem;
5016             if (oldSubFocusItem) {
5017                 QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(scope, false);
5018                 QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
5019                 changed << oldSubFocusItem;
5020             } else if (!scope->isFocusScope() && scope->hasFocus()) {
5021                 QQuickItemPrivate::get(scope)->focus = false;
5022                 changed << scope;
5023             }
5024             d->updateSubFocusItem(scope, focus);
5025
5026             d->focus = focus;
5027             changed << this;
5028             emit focusChanged(focus);
5029
5030             QQuickWindowPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
5031         }
5032     } else {
5033         QVarLengthArray<QQuickItem *, 20> changed;
5034         QQuickItem *oldSubFocusItem = d->subFocusItem;
5035         if (!isFocusScope() && oldSubFocusItem) {
5036             QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(this, false);
5037             QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
5038             changed << oldSubFocusItem;
5039         }
5040
5041         d->focus = focus;
5042         changed << this;
5043         emit focusChanged(focus);
5044
5045         QQuickWindowPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
5046     }
5047 }
5048
5049 bool QQuickItem::isFocusScope() const
5050 {
5051     return flags() & ItemIsFocusScope;
5052 }
5053
5054 QQuickItem *QQuickItem::scopedFocusItem() const
5055 {
5056     Q_D(const QQuickItem);
5057     if (!isFocusScope())
5058         return 0;
5059     else
5060         return d->subFocusItem;
5061 }
5062
5063
5064 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
5065 {
5066     Q_D(const QQuickItem);
5067     return d->acceptedMouseButtons();
5068 }
5069
5070 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
5071 {
5072     Q_D(QQuickItem);
5073     if (buttons & Qt::LeftButton)
5074         d->extra.setFlag();
5075     else
5076         d->extra.clearFlag();
5077
5078     buttons &= ~Qt::LeftButton;
5079     if (buttons || d->extra.isAllocated())
5080         d->extra.value().acceptedMouseButtons = buttons;
5081 }
5082
5083 bool QQuickItem::filtersChildMouseEvents() const
5084 {
5085     Q_D(const QQuickItem);
5086     return d->filtersChildMouseEvents;
5087 }
5088
5089 void QQuickItem::setFiltersChildMouseEvents(bool filter)
5090 {
5091     Q_D(QQuickItem);
5092     d->filtersChildMouseEvents = filter;
5093 }
5094
5095 bool QQuickItem::isUnderMouse() const
5096 {
5097     Q_D(const QQuickItem);
5098     if (!d->window)
5099         return false;
5100
5101     QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition;
5102     return contains(mapFromScene(d->window->mapFromGlobal(cursorPos.toPoint())));
5103 }
5104
5105 bool QQuickItem::acceptHoverEvents() const
5106 {
5107     Q_D(const QQuickItem);
5108     return d->hoverEnabled;
5109 }
5110
5111 void QQuickItem::setAcceptHoverEvents(bool enabled)
5112 {
5113     Q_D(QQuickItem);
5114     d->hoverEnabled = enabled;
5115 }
5116
5117 void QQuickItem::grabMouse()
5118 {
5119     Q_D(QQuickItem);
5120     if (!d->window)
5121         return;
5122     QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window);
5123     if (windowPriv->mouseGrabberItem == this)
5124         return;
5125
5126     QQuickItem *oldGrabber = windowPriv->mouseGrabberItem;
5127     windowPriv->mouseGrabberItem = this;
5128     if (oldGrabber) {
5129         QEvent ev(QEvent::UngrabMouse);
5130         d->window->sendEvent(oldGrabber, &ev);
5131     }
5132 }
5133
5134 void QQuickItem::ungrabMouse()
5135 {
5136     Q_D(QQuickItem);
5137     if (!d->window)
5138         return;
5139     QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window);
5140     if (windowPriv->mouseGrabberItem != this) {
5141         qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
5142         return;
5143     }
5144
5145     windowPriv->mouseGrabberItem = 0;
5146
5147     QEvent ev(QEvent::UngrabMouse);
5148     d->window->sendEvent(this, &ev);
5149 }
5150
5151 bool QQuickItem::keepMouseGrab() const
5152 {
5153     Q_D(const QQuickItem);
5154     return d->keepMouse;
5155 }
5156
5157 /*!
5158   The flag indicating whether the mouse should remain
5159   with this item is set to \a keep.
5160
5161   This is useful for items that wish to grab and keep mouse
5162   interaction following a predefined gesture.  For example,
5163   an item that is interested in horizontal mouse movement
5164   may set keepMouseGrab to true once a threshold has been
5165   exceeded.  Once keepMouseGrab has been set to true, filtering
5166   items will not react to mouse events.
5167
5168   If the item does not indicate that it wishes to retain mouse grab,
5169   a filtering item may steal the grab. For example, Flickable may attempt
5170   to steal a mouse grab if it detects that the user has begun to
5171   move the viewport.
5172
5173   \sa keepMouseGrab()
5174  */
5175 void QQuickItem::setKeepMouseGrab(bool keep)
5176 {
5177     Q_D(QQuickItem);
5178     d->keepMouse = keep;
5179 }
5180
5181 /*!
5182     Grabs the touch points specified by \a ids.
5183
5184     These touch points will be owned by the item until
5185     they are released. Alternatively, the grab can be stolen
5186     by a filtering item like Flickable. Use setKeepTouchGrab()
5187     to prevent the grab from being stolen.
5188
5189     \sa ungrabTouchPoints(), setKeepTouchGrab()
5190 */
5191 void QQuickItem::grabTouchPoints(const QVector<int> &ids)
5192 {
5193     Q_D(QQuickItem);
5194     if (!d->window)
5195         return;
5196     QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window);
5197
5198     QSet<QQuickItem*> ungrab;
5199     for (int i = 0; i < ids.count(); ++i) {
5200         QQuickItem *oldGrabber = windowPriv->itemForTouchPointId.value(ids.at(i));
5201         if (oldGrabber == this)
5202             return;
5203
5204         windowPriv->itemForTouchPointId[ids.at(i)] = this;
5205         if (oldGrabber)
5206             ungrab.insert(oldGrabber);
5207     }
5208     foreach (QQuickItem *oldGrabber, ungrab)
5209         oldGrabber->touchUngrabEvent();
5210 }
5211
5212 /*!
5213     Ungrabs the touch points owned by this item.
5214
5215     \sa grabTouchPoints()
5216 */
5217 void QQuickItem::ungrabTouchPoints()
5218 {
5219     Q_D(QQuickItem);
5220     if (!d->window)
5221         return;
5222     QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window);
5223
5224     QMutableHashIterator<int, QQuickItem*> i(windowPriv->itemForTouchPointId);
5225     while (i.hasNext()) {
5226         i.next();
5227         if (i.value() == this)
5228             i.remove();
5229     }
5230     touchUngrabEvent();
5231 }
5232
5233 /*!
5234     Returns a value indicating whether the touch points grabbed by this item
5235     should remain with this item exclusively.
5236
5237     \sa setKeepTouchGrab(), keepMouseGrab()
5238 */
5239 bool QQuickItem::keepTouchGrab() const
5240 {
5241     Q_D(const QQuickItem);
5242     return d->keepTouch;
5243 }
5244
5245 /*!
5246   The flag indicating whether the touch points grabbed
5247   by this item should remain with this item is set to \a keep.
5248
5249   This is useful for items that wish to grab and keep specific touch
5250   points following a predefined gesture.  For example,
5251   an item that is interested in horizontal touch point movement
5252   may set setKeepTouchGrab to true once a threshold has been
5253   exceeded.  Once setKeepTouchGrab has been set to true, filtering
5254   items will not react to the relevant touch points.
5255
5256   If the item does not indicate that it wishes to retain touch point grab,
5257   a filtering item may steal the grab. For example, Flickable may attempt
5258   to steal a touch point grab if it detects that the user has begun to
5259   move the viewport.
5260
5261   \sa keepTouchGrab(), setKeepMouseGrab()
5262  */
5263 void QQuickItem::setKeepTouchGrab(bool keep)
5264 {
5265     Q_D(QQuickItem);
5266     d->keepTouch = keep;
5267 }
5268
5269 /*!
5270   Returns true if this item contains \a point, which is in local coordinates;
5271   returns false otherwise.
5272
5273   This function can be overwritten in order to handle point collisions in items
5274   with custom shapes. The default implementation checks if the point is inside
5275   the item's bounding rect.
5276
5277   Note that it's normally used to check if the item is under the mouse cursor,
5278   and for that reason, the implementation of this function should be as light-weight
5279   as possible.
5280 */
5281 bool QQuickItem::contains(const QPointF &point) const
5282 {
5283     Q_D(const QQuickItem);
5284     return QRectF(0, 0, d->width, d->height).contains(point);
5285 }
5286
5287 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
5288 {
5289     QPointF p = mapToScene(point);
5290     if (item)
5291         p = item->mapFromScene(p);
5292     return p;
5293 }
5294
5295 QPointF QQuickItem::mapToScene(const QPointF &point) const
5296 {
5297     Q_D(const QQuickItem);
5298     return d->itemToWindowTransform().map(point);
5299 }
5300
5301 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
5302 {
5303     Q_D(const QQuickItem);
5304     QTransform t = d->itemToWindowTransform();
5305     if (item)
5306         t *= QQuickItemPrivate::get(item)->windowToItemTransform();
5307     return t.mapRect(rect);
5308 }
5309
5310 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
5311 {
5312     Q_D(const QQuickItem);
5313     return d->itemToWindowTransform().mapRect(rect);
5314 }
5315
5316 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
5317 {
5318     QPointF p = item?item->mapToScene(point):point;
5319     return mapFromScene(p);
5320 }
5321
5322 QPointF QQuickItem::mapFromScene(const QPointF &point) const
5323 {
5324     Q_D(const QQuickItem);
5325     return d->windowToItemTransform().map(point);
5326 }
5327
5328 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
5329 {
5330     Q_D(const QQuickItem);
5331     QTransform t = item?QQuickItemPrivate::get(item)->itemToWindowTransform():QTransform();
5332     t *= d->windowToItemTransform();
5333     return t.mapRect(rect);
5334 }
5335
5336 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
5337 {
5338     Q_D(const QQuickItem);
5339     return d->windowToItemTransform().mapRect(rect);
5340 }
5341
5342
5343 /*!
5344     \qmlmethod QtQuick2::Item::forceActiveFocus()
5345
5346     Forces active focus on the item.
5347
5348     This method sets focus on the item and makes sure that all the focus scopes
5349     higher in the object hierarchy are also given the focus.
5350 */
5351
5352 /*!
5353     Forces active focus on the item.
5354
5355     This method sets focus on the item and makes sure that all the focus scopes
5356     higher in the object hierarchy are also given the focus.
5357 */
5358
5359 /*!
5360   \qmlmethod QtQuick2::Item::childAt(real x, real y)
5361
5362   Returns the visible child item at point (\a x, \a y), which is in this
5363   item's coordinate system, or \c null if there is no such item.
5364 */
5365
5366 /*!
5367   Returns the visible child item at point (\a x, \a y), which is in this
5368   item's coordinate system, or 0 if there is no such item.
5369 */
5370
5371 /*!
5372   \qmlproperty list<State> QtQuick2::Item::states
5373   This property holds a list of states defined by the item.
5374
5375   \qml
5376   Item {
5377       states: [
5378           State {
5379               // ...
5380           },
5381           State {
5382               // ...
5383           }
5384           // ...
5385       ]
5386   }
5387   \endqml
5388
5389   \sa {qmlstate}{States}
5390 */
5391 /*!
5392   \qmlproperty list<Transition> QtQuick2::Item::transitions
5393   This property holds a list of transitions defined by the item.
5394
5395   \qml
5396   Item {
5397       transitions: [
5398           Transition {
5399               // ...
5400           },
5401           Transition {
5402               // ...
5403           }
5404           // ...
5405       ]
5406   }
5407   \endqml
5408
5409   \sa {QML Animation and Transitions}{Transitions}
5410 */
5411 /*
5412   \qmlproperty list<Filter> QtQuick2::Item::filter
5413   This property holds a list of graphical filters to be applied to the item.
5414
5415   \l {Filter}{Filters} include things like \l {Blur}{blurring}
5416   the item, or giving it a \l Reflection.  Some
5417   filters may not be available on all windows; if a filter is not
5418   available on a certain window, it will simply not be applied for
5419   that window (but the QML will still be considered valid).
5420
5421   \qml
5422   Item {
5423       filter: [
5424           Blur {
5425               // ...
5426           },
5427           Reflection {
5428               // ...
5429           }
5430           // ...
5431       ]
5432   }
5433   \endqml
5434 */
5435
5436 /*!
5437   \qmlproperty bool QtQuick2::Item::clip
5438   This property holds whether clipping is enabled. The default clip value is \c false.
5439
5440   If clipping is enabled, an item will clip its own painting, as well
5441   as the painting of its children, to its bounding rectangle.
5442
5443   Non-rectangular clipping regions are not supported for performance reasons.
5444 */
5445
5446 /*!
5447   \property QQuickItem::clip
5448   This property holds whether clipping is enabled. The default clip value is \c false.
5449
5450   If clipping is enabled, an item will clip its own painting, as well
5451   as the painting of its children, to its bounding rectangle. If you set
5452   clipping during an item's paint operation, remember to re-set it to
5453   prevent clipping the rest of your scene.
5454
5455   Non-rectangular clipping regions are not supported for performance reasons.
5456 */
5457
5458 /*!
5459   \qmlproperty string QtQuick2::Item::state
5460
5461   This property holds the name of the current state of the item.
5462
5463   This property is often used in scripts to change between states. For
5464   example:
5465
5466   \js
5467   function toggle() {
5468       if (button.state == 'On')
5469           button.state = 'Off';
5470       else
5471           button.state = 'On';
5472   }
5473   \endjs
5474
5475   If the item is in its base state (i.e. no explicit state has been
5476   set), \c state will be a blank string. Likewise, you can return an
5477   item to its base state by setting its current state to \c ''.
5478
5479   \sa {qmlstates}{States}
5480 */
5481
5482 /*!
5483   \qmlproperty list<Transform> QtQuick2::Item::transform
5484   This property holds the list of transformations to apply.
5485
5486   For more information see \l Transform.
5487 */
5488
5489 /*!
5490     \enum QQuickItem::TransformOrigin
5491
5492     Controls the point about which simple transforms like scale apply.
5493
5494     \value TopLeft The top-left corner of the item.
5495     \value Top The center point of the top of the item.
5496     \value TopRight The top-right corner of the item.
5497     \value Left The left most point of the vertical middle.
5498     \value Center The center of the item.
5499     \value Right The right most point of the vertical middle.
5500     \value BottomLeft The bottom-left corner of the item.
5501     \value Bottom The center point of the bottom of the item.
5502     \value BottomRight The bottom-right corner of the item.
5503 */
5504
5505
5506 /*!
5507   \qmlproperty bool QtQuick2::Item::activeFocus
5508
5509   This property indicates whether the item has active focus.
5510
5511   An item with active focus will receive keyboard input,
5512   or is a FocusScope ancestor of the item that will receive keyboard input.
5513
5514   Usually, activeFocus is gained by setting focus on an item and its enclosing
5515   FocusScopes. In the following example \c input will have activeFocus.
5516   \qml
5517   Rectangle {
5518       FocusScope {
5519           focus: true
5520           TextInput {
5521               id: input
5522               focus: true
5523           }
5524       }
5525   }
5526   \endqml
5527
5528   \sa focus, {qmlfocus}{Keyboard Focus}
5529 */
5530
5531 /*!
5532   \qmlproperty bool QtQuick2::Item::focus
5533   This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5534   will gain active focus when the enclosing focus scope gains active focus.
5535   In the following example, \c input will be given active focus when \c scope gains active focus.
5536   \qml
5537   Rectangle {
5538       FocusScope {
5539           id: scope
5540           TextInput {
5541               id: input
5542               focus: true
5543           }
5544       }
5545   }
5546   \endqml
5547
5548   For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5549   On a practical level, that means the following QML will give active focus to \c input on startup.
5550
5551   \qml
5552   Rectangle {
5553       TextInput {
5554           id: input
5555           focus: true
5556       }
5557   }
5558   \endqml
5559
5560   \sa activeFocus, {qmlfocus}{Keyboard Focus}
5561 */
5562
5563
5564 /*!
5565   \property QQuickItem::anchors
5566   \internal
5567 */
5568
5569 /*!
5570   \property QQuickItem::left
5571   \internal
5572 */
5573
5574 /*!
5575   \property QQuickItem::right
5576   \internal
5577 */
5578
5579 /*!
5580   \property QQuickItem::horizontalCenter
5581   \internal
5582 */
5583
5584 /*!
5585   \property QQuickItem::top
5586   \internal
5587 */
5588
5589 /*!
5590   \property QQuickItem::bottom
5591   \internal
5592 */
5593
5594 /*!
5595   \property QQuickItem::verticalCenter
5596   \internal
5597 */
5598
5599 /*!
5600   \property QQuickItem::focus
5601   \internal
5602 */
5603
5604 /*!
5605   \property QQuickItem::transform
5606   \internal
5607 */
5608
5609 /*!
5610   \property QQuickItem::transformOrigin
5611   \internal
5612 */
5613
5614 /*!
5615   \property QQuickItem::activeFocus
5616   \internal
5617 */
5618
5619 /*!
5620   \property QQuickItem::baseline
5621   \internal
5622 */
5623
5624 /*!
5625   \property QQuickItem::data
5626   \internal
5627 */
5628
5629 /*!
5630   \property QQuickItem::resources
5631   \internal
5632 */
5633
5634 /*!
5635   \property QQuickItem::state
5636   \internal
5637 */
5638
5639 /*!
5640   \property QQuickItem::states
5641   \internal
5642 */
5643
5644 /*!
5645   \property QQuickItem::transformOriginPoint
5646   \internal
5647 */
5648
5649 /*!
5650   \property QQuickItem::transitions
5651   \internal
5652 */
5653
5654 bool QQuickItem::event(QEvent *ev)
5655 {
5656 #if 0
5657     if (ev->type() == QEvent::PolishRequest) {
5658         Q_D(QQuickItem);
5659         d->polishScheduled = false;
5660         updatePolish();
5661         return true;
5662     } else {
5663         return QObject::event(ev);
5664     }
5665 #endif
5666     if (ev->type() == QEvent::InputMethodQuery) {
5667         QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5668         Qt::InputMethodQueries queries = query->queries();
5669         for (uint i = 0; i < 32; ++i) {
5670             Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5671             if (q) {
5672                 QVariant v = inputMethodQuery(q);
5673                 query->setValue(q, v);
5674             }
5675         }
5676         query->accept();
5677         return true;
5678     } else if (ev->type() == QEvent::InputMethod) {
5679         inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5680         return true;
5681     }
5682     return QObject::event(ev);
5683 }
5684
5685 #ifndef QT_NO_DEBUG_STREAM
5686 QDebug operator<<(QDebug debug, QQuickItem *item)
5687 {
5688     if (!item) {
5689         debug << "QQuickItem(0)";
5690         return debug;
5691     }
5692
5693     debug << item->metaObject()->className() << "(this =" << ((void*)item)
5694           << ", name=" << item->objectName()
5695           << ", parent =" << ((void*)item->parentItem())
5696           << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5697           << ", z =" << item->z() << ')';
5698     return debug;
5699 }
5700 #endif
5701
5702 qint64 QQuickItemPrivate::consistentTime = -1;
5703 void QQuickItemPrivate::setConsistentTime(qint64 t)
5704 {
5705     consistentTime = t;
5706 }
5707
5708 class QElapsedTimerConsistentTimeHack
5709 {
5710 public:
5711     void start() {
5712         t1 = QQuickItemPrivate::consistentTime;
5713         t2 = 0;
5714     }
5715     qint64 elapsed() {
5716         return QQuickItemPrivate::consistentTime - t1;
5717     }
5718     qint64 restart() {
5719         qint64 val = QQuickItemPrivate::consistentTime - t1;
5720         t1 = QQuickItemPrivate::consistentTime;
5721         t2 = 0;
5722         return val;
5723     }
5724
5725 private:
5726     qint64 t1;
5727     qint64 t2;
5728 };
5729
5730 void QQuickItemPrivate::start(QElapsedTimer &t)
5731 {
5732     if (QQuickItemPrivate::consistentTime == -1)
5733         t.start();
5734     else
5735         ((QElapsedTimerConsistentTimeHack*)&t)->start();
5736 }
5737
5738 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5739 {
5740     if (QQuickItemPrivate::consistentTime == -1)
5741         return t.elapsed();
5742     else
5743         return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5744 }
5745
5746 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5747 {
5748     if (QQuickItemPrivate::consistentTime == -1)
5749         return t.restart();
5750     else
5751         return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5752 }
5753
5754 /*!
5755     \fn bool QQuickItem::isTextureProvider() const
5756
5757     Returns true if this item is a texture provider. The default
5758     implementation returns false.
5759
5760     This function can be called from any thread.
5761  */
5762
5763 bool QQuickItem::isTextureProvider() const
5764 {
5765     Q_D(const QQuickItem);
5766     return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5767            d->extra->layer->effectSource()->isTextureProvider() : false;
5768 }
5769
5770 /*!
5771     \fn QSGTextureProvider *QQuickItem::textureProvider() const
5772
5773     Returns the texture provider for an item. The default implementation
5774     returns 0.
5775
5776     This function may only be called on the rendering thread.
5777  */
5778
5779 QSGTextureProvider *QQuickItem::textureProvider() const
5780 {
5781     Q_D(const QQuickItem);
5782     return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
5783            d->extra->layer->effectSource()->textureProvider() : 0;
5784 }
5785
5786 QQuickItemLayer *QQuickItemPrivate::layer() const
5787 {
5788     if (!extra.isAllocated() || !extra->layer) {
5789         extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
5790         if (!componentComplete)
5791             extra->layer->classBegin();
5792     }
5793     return extra->layer;
5794 }
5795
5796 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
5797     : m_item(item)
5798     , m_enabled(false)
5799     , m_mipmap(false)
5800     , m_smooth(false)
5801     , m_componentComplete(true)
5802     , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
5803     , m_format(QQuickShaderEffectSource::RGBA)
5804     , m_name("source")
5805     , m_effectComponent(0)
5806     , m_effect(0)
5807     , m_effectSource(0)
5808 {
5809 }
5810
5811 QQuickItemLayer::~QQuickItemLayer()
5812 {
5813     delete m_effectSource;
5814     delete m_effect;
5815 }
5816
5817
5818
5819 /*!
5820     \qmlproperty bool QtQuick2::Item::layer.enabled
5821
5822     Holds wether the item is layered or not. Layering is disabled by default.
5823
5824     A layered item is rendered into an offscreen surface and cached until
5825     it is changed. Enabling layering for complex QML item hierarchies can
5826     some times be an optimization.
5827
5828     None of the other layer properties have any effect when the layer
5829     is disabled.
5830  */
5831
5832 void QQuickItemLayer::setEnabled(bool e)
5833 {
5834     if (e == m_enabled)
5835         return;
5836     m_enabled = e;
5837     if (m_componentComplete) {
5838         if (m_enabled)
5839             activate();
5840         else
5841             deactivate();
5842     }
5843
5844     emit enabledChanged(e);
5845 }
5846
5847 void QQuickItemLayer::classBegin()
5848 {
5849     Q_ASSERT(!m_effectSource);
5850     Q_ASSERT(!m_effect);
5851     m_componentComplete = false;
5852 }
5853
5854 void QQuickItemLayer::componentComplete()
5855 {
5856     Q_ASSERT(!m_componentComplete);
5857     m_componentComplete = true;
5858     if (m_enabled)
5859         activate();
5860 }
5861
5862 void QQuickItemLayer::activate()
5863 {
5864     Q_ASSERT(!m_effectSource);
5865     m_effectSource = new QQuickShaderEffectSource();
5866
5867     QQuickItem *parentItem = m_item->parentItem();
5868     if (parentItem) {
5869         m_effectSource->setParentItem(parentItem);
5870         m_effectSource->stackAfter(m_item);
5871     }
5872
5873     m_effectSource->setSourceItem(m_item);
5874     m_effectSource->setHideSource(true);
5875     m_effectSource->setSmooth(m_smooth);
5876     m_effectSource->setTextureSize(m_size);
5877     m_effectSource->setSourceRect(m_sourceRect);
5878     m_effectSource->setMipmap(m_mipmap);
5879     m_effectSource->setWrapMode(m_wrapMode);
5880     m_effectSource->setFormat(m_format);
5881
5882     if (m_effectComponent)
5883         activateEffect();
5884
5885     m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5886
5887     updateZ();
5888     updateGeometry();
5889     updateOpacity();
5890     updateMatrix();
5891
5892     QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5893     id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5894 }
5895
5896 void QQuickItemLayer::deactivate()
5897 {
5898     Q_ASSERT(m_effectSource);
5899
5900     if (m_effectComponent)
5901         deactivateEffect();
5902
5903     delete m_effectSource;
5904     m_effectSource = 0;
5905
5906     QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
5907     id->removeItemChangeListener(this,  QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
5908 }
5909
5910 void QQuickItemLayer::activateEffect()
5911 {
5912     Q_ASSERT(m_effectSource);
5913     Q_ASSERT(m_effectComponent);
5914     Q_ASSERT(!m_effect);
5915
5916     QObject *created = m_effectComponent->beginCreate(m_effectComponent->creationContext());
5917     m_effect = qobject_cast<QQuickItem *>(created);
5918     if (!m_effect) {
5919         qWarning("Item: layer.effect is not a QML Item.");
5920         m_effectComponent->completeCreate();
5921         delete created;
5922         return;
5923     }
5924     QQuickItem *parentItem = m_item->parentItem();
5925     if (parentItem) {
5926         m_effect->setParentItem(parentItem);
5927         m_effect->stackAfter(m_effectSource);
5928     }
5929     m_effect->setVisible(m_item->isVisible());
5930     m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
5931     m_effectComponent->completeCreate();
5932 }
5933
5934 void QQuickItemLayer::deactivateEffect()
5935 {
5936     Q_ASSERT(m_effectSource);
5937     Q_ASSERT(m_effectComponent);
5938
5939     delete m_effect;
5940     m_effect = 0;
5941 }
5942
5943
5944 /*!
5945     \qmlproperty Component QtQuick2::Item::layer.effect
5946
5947     Holds the effect that is applied to this layer.
5948
5949     The effect is typically a \l ShaderEffect component, although any \l Item component can be
5950     assigned. The effect should have a source texture property with a name matching \l samplerName.
5951
5952     \sa samplerName
5953  */
5954
5955 void QQuickItemLayer::setEffect(QQmlComponent *component)
5956 {
5957     if (component == m_effectComponent)
5958         return;
5959
5960     bool updateNeeded = false;
5961     if (m_effectSource && m_effectComponent) {
5962         deactivateEffect();
5963         updateNeeded = true;
5964     }
5965
5966     m_effectComponent = component;
5967
5968     if (m_effectSource && m_effectComponent) {
5969         activateEffect();
5970         updateNeeded = true;
5971     }
5972
5973     if (updateNeeded) {
5974         updateZ();
5975         updateGeometry();
5976         updateOpacity();
5977         updateMatrix();
5978         m_effectSource->setVisible(m_item->isVisible() && !m_effect);
5979     }
5980
5981     emit effectChanged(component);
5982 }
5983
5984
5985 /*!
5986     \qmlproperty bool QtQuick2::Item::layer.mipmap
5987
5988     If this property is true, mipmaps are generated for the texture.
5989
5990     \note Some OpenGL ES 2 implementations do not support mipmapping of
5991     non-power-of-two textures.
5992  */
5993
5994 void QQuickItemLayer::setMipmap(bool mipmap)
5995 {
5996     if (mipmap == m_mipmap)
5997         return;
5998     m_mipmap = mipmap;
5999
6000     if (m_effectSource)
6001         m_effectSource->setMipmap(m_mipmap);
6002
6003     emit mipmapChanged(mipmap);
6004 }
6005
6006
6007 /*!
6008     \qmlproperty enumeration QtQuick2::Item::layer.format
6009
6010     This property defines the internal OpenGL format of the texture.
6011     Modifying this property makes most sense when the \a layer.effect is also
6012     specified. Depending on the OpenGL implementation, this property might
6013     allow you to save some texture memory.
6014
6015     \list
6016     \li ShaderEffectSource.Alpha - GL_ALPHA
6017     \li ShaderEffectSource.RGB - GL_RGB
6018     \li ShaderEffectSource.RGBA - GL_RGBA
6019     \endlist
6020
6021     \note Some OpenGL implementations do not support the GL_ALPHA format.
6022  */
6023
6024 void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
6025 {
6026     if (f == m_format)
6027         return;
6028     m_format = f;
6029
6030     if (m_effectSource)
6031         m_effectSource->setFormat(m_format);
6032
6033     emit formatChanged(m_format);
6034 }
6035
6036
6037 /*!
6038     \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
6039
6040     This property defines which rectangular area of the \l sourceItem to
6041     render into the texture. The source rectangle can be larger than
6042     \l sourceItem itself. If the rectangle is null, which is the default,
6043     the whole \l sourceItem is rendered to texture.
6044  */
6045
6046 void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
6047 {
6048     if (sourceRect == m_sourceRect)
6049         return;
6050     m_sourceRect = sourceRect;
6051
6052     if (m_effectSource)
6053         m_effectSource->setSourceRect(m_sourceRect);
6054
6055     emit sourceRectChanged(sourceRect);
6056 }
6057
6058
6059
6060 /*!
6061     \qmlproperty bool QtQuick2::Item::layer.smooth
6062
6063     Holds whether the layer is smoothly transformed.
6064  */
6065
6066 void QQuickItemLayer::setSmooth(bool s)
6067 {
6068     if (m_smooth == s)
6069         return;
6070     m_smooth = s;
6071
6072     if (m_effectSource)
6073         m_effectSource->setSmooth(m_smooth);
6074
6075     emit smoothChanged(s);
6076 }
6077
6078
6079
6080 /*!
6081     \qmlproperty size QtQuick2::Item::layer.textureSize
6082
6083     This property holds the requested pixel size of the layers texture. If it is empty,
6084     which is the default, the size of the item is used.
6085
6086     \note Some platforms have a limit on how small framebuffer objects can be,
6087     which means the actual texture size might be larger than the requested
6088     size.
6089  */
6090
6091 void QQuickItemLayer::setSize(const QSize &size)
6092 {
6093     if (size == m_size)
6094         return;
6095     m_size = size;
6096
6097     if (m_effectSource)
6098         m_effectSource->setTextureSize(size);
6099
6100     emit sizeChanged(size);
6101 }
6102
6103
6104
6105 /*!
6106     \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
6107
6108     This property defines the OpenGL wrap modes associated with the texture.
6109     Modifying this property makes most sense when the \a layer.effect is
6110     specified.
6111
6112     \list
6113     \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
6114     \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
6115     \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
6116     \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
6117     \endlist
6118
6119     \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
6120     wrap mode with non-power-of-two textures.
6121  */
6122
6123 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
6124 {
6125     if (mode == m_wrapMode)
6126         return;
6127     m_wrapMode = mode;
6128
6129     if (m_effectSource)
6130         m_effectSource->setWrapMode(m_wrapMode);
6131
6132     emit wrapModeChanged(mode);
6133 }
6134
6135 /*!
6136     \qmlproperty string QtQuick2::Item::layer.samplerName
6137
6138     Holds the name of the effect's source texture property.
6139
6140     samplerName needs to match the name of the effect's source texture property
6141     so that the Item can pass the layer's offscreen surface to the effect correctly.
6142
6143     \sa effect, ShaderEffect
6144  */
6145
6146 void QQuickItemLayer::setName(const QByteArray &name) {
6147     if (m_name == name)
6148         return;
6149     if (m_effect) {
6150         m_effect->setProperty(m_name, QVariant());
6151         m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
6152     }
6153     m_name = name;
6154     emit nameChanged(name);
6155 }
6156
6157 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
6158 {
6159     Q_UNUSED(item)
6160     updateOpacity();
6161 }
6162
6163 void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
6164 {
6165     updateGeometry();
6166 }
6167
6168 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
6169 {
6170     Q_UNUSED(item)
6171     Q_ASSERT(item == m_item);
6172     Q_ASSERT(parent != m_effectSource);
6173     Q_ASSERT(parent == 0 || parent != m_effect);
6174
6175     m_effectSource->setParentItem(parent);
6176     if (parent)
6177         m_effectSource->stackAfter(m_item);
6178
6179     if (m_effect) {
6180         m_effect->setParentItem(parent);
6181         if (parent)
6182             m_effect->stackAfter(m_effectSource);
6183     }
6184 }
6185
6186 void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
6187 {
6188     m_effectSource->stackAfter(m_item);
6189     if (m_effect)
6190         m_effect->stackAfter(m_effectSource);
6191 }
6192
6193 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
6194 {
6195     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6196     Q_ASSERT(l);
6197     l->setVisible(m_item->isVisible());
6198 }
6199
6200 void QQuickItemLayer::updateZ()
6201 {
6202     if (!m_componentComplete || !m_enabled)
6203         return;
6204     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6205     Q_ASSERT(l);
6206     l->setZ(m_item->z());
6207 }
6208
6209 void QQuickItemLayer::updateOpacity()
6210 {
6211     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6212     Q_ASSERT(l);
6213     l->setOpacity(m_item->opacity());
6214 }
6215
6216 void QQuickItemLayer::updateGeometry()
6217 {
6218     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6219     Q_ASSERT(l);
6220     QRectF bounds = m_item->clipRect();
6221     l->setWidth(bounds.width());
6222     l->setHeight(bounds.height());
6223     l->setX(bounds.x() + m_item->x());
6224     l->setY(bounds.y() + m_item->y());
6225 }
6226
6227 void QQuickItemLayer::updateMatrix()
6228 {
6229     // Called directly from transformChanged(), so needs some extra
6230     // checks.
6231     if (!m_componentComplete || !m_enabled)
6232         return;
6233     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
6234     Q_ASSERT(l);
6235     QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
6236     l->setScale(m_item->scale());
6237     l->setRotation(m_item->rotation());
6238     ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
6239     if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
6240         ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
6241     ld->dirty(QQuickItemPrivate::Transform);
6242 }
6243
6244 QQuickItemPrivate::ExtraData::ExtraData()
6245 : z(0), scale(1), rotation(0), opacity(1),
6246   contents(0), screenAttached(0), layoutDirectionAttached(0),
6247   keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
6248   opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
6249   acceptedMouseButtons(0), origin(QQuickItem::Center)
6250 {
6251 }
6252
6253 QT_END_NAMESPACE
6254
6255 #include <moc_qquickitem.cpp>