Made QSGNode flags togglable and added StaticSubtreeGeometry.
[profile/ivi/qtdeclarative.git] / src / quick / items / qquickitem.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qquickitem.h"
43
44 #include "qquickcanvas.h"
45 #include <QtDeclarative/qjsengine.h>
46 #include "qquickcanvas_p.h"
47
48 #include "qquickevents_p_p.h"
49 #include "qquickscreen_p.h"
50
51 #include <QtDeclarative/qdeclarativeengine.h>
52 #include <QtDeclarative/qdeclarativecomponent.h>
53 #include <QtDeclarative/qdeclarativeinfo.h>
54 #include <QtGui/qpen.h>
55 #include <QtGui/qcursor.h>
56 #include <QtGui/qguiapplication.h>
57 #include <QtGui/qinputpanel.h>
58 #include <QtCore/qdebug.h>
59 #include <QtCore/qcoreevent.h>
60 #include <QtCore/qnumeric.h>
61
62 #include <private/qdeclarativeengine_p.h>
63 #include <QtQuick/private/qdeclarativestategroup_p.h>
64 #include <private/qdeclarativeopenmetaobject_p.h>
65 #include <QtQuick/private/qdeclarativestate_p.h>
66 #include <private/qlistmodelinterface_p.h>
67 #include <private/qquickitem_p.h>
68 #include <private/qdeclarativeaccessors_p.h>
69
70 #include <float.h>
71
72 // XXX todo Check that elements that create items handle memory correctly after visual ownership change
73
74 QT_BEGIN_NAMESPACE
75
76 static void QQuickItem_parentNotifier(QObject *o, intptr_t, QDeclarativeNotifier **n)
77 {
78     QQuickItemPrivate *d = QQuickItemPrivate::get(static_cast<QQuickItem *>(o));
79     *n = &d->parentNotifier;
80 }
81
82 QML_PRIVATE_ACCESSOR(QQuickItem, QQuickItem *, parent, parentItem)
83 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, x, x)
84 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, y, y)
85 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, width, width)
86 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, height, height)
87
88 static QDeclarativeAccessors QQuickItem_parent = { QQuickItem_parentRead, QQuickItem_parentNotifier };
89 static QDeclarativeAccessors QQuickItem_x = { QQuickItem_xRead, 0 };
90 static QDeclarativeAccessors QQuickItem_y = { QQuickItem_yRead, 0 };
91 static QDeclarativeAccessors QQuickItem_width = { QQuickItem_widthRead, 0 };
92 static QDeclarativeAccessors QQuickItem_height = { QQuickItem_heightRead, 0 };
93
94 QML_DECLARE_PROPERTIES(QQuickItem) {
95     { QML_PROPERTY_NAME(parent), 0, &QQuickItem_parent },
96     { QML_PROPERTY_NAME(x), 0, &QQuickItem_x },
97     { QML_PROPERTY_NAME(y), 0, &QQuickItem_y },
98     { QML_PROPERTY_NAME(width), 0, &QQuickItem_width },
99     { QML_PROPERTY_NAME(height), 0, &QQuickItem_height }
100 };
101
102 void QQuickItemPrivate::registerAccessorProperties()
103 {
104     QML_DEFINE_PROPERTIES(QQuickItem);
105 }
106
107 /*!
108     \qmlclass Transform QQuickTransform
109     \inqmlmodule QtQuick 2
110     \ingroup qml-transform-elements
111     \brief The Transform elements provide a way of building advanced transformations on Items.
112
113     The Transform element is a base type which cannot be instantiated directly.
114     The following concrete Transform types are available:
115
116     \list
117     \o \l Rotation
118     \o \l Scale
119     \o \l Translate
120     \endlist
121
122     The Transform elements let you create and control advanced transformations that can be configured
123     independently using specialized properties.
124
125     You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
126     one at a time.
127 */
128
129 /*!
130     \qmlclass Translate QQuickTranslate
131     \inqmlmodule QtQuick 2
132     \ingroup qml-transform-elements
133     \brief The Translate object provides a way to move an Item without changing its x or y properties.
134
135     The Translate object provides independent control over position in addition to the Item's x and y properties.
136
137     The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
138     to lay the items out as if they had not been transformed:
139     \qml
140     import QtQuick 1.0
141
142     Row {
143         Rectangle {
144             width: 100; height: 100
145             color: "blue"
146             transform: Translate { y: 20 }
147         }
148         Rectangle {
149             width: 100; height: 100
150             color: "red"
151             transform: Translate { y: -20 }
152         }
153     }
154     \endqml
155
156     \image translate.png
157 */
158
159 /*!
160     \qmlproperty real QtQuick2::Translate::x
161
162     The translation along the X axis.
163 */
164
165 /*!
166     \qmlproperty real QtQuick2::Translate::y
167
168     The translation along the Y axis.
169 */
170
171 /*!
172     \qmlclass Scale QQuickScale
173     \inqmlmodule QtQuick 2
174     \ingroup qml-transform-elements
175     \brief The Scale element provides a way to scale an Item.
176
177     The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
178     it allows a different scale for the x and y axes, and allows the scale to be relative to an
179     arbitrary point.
180
181     The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
182     \qml
183     Rectangle {
184         width: 100; height: 100
185         color: "blue"
186         transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
187     }
188     \endqml
189
190     \sa Rotation, Translate
191 */
192
193 /*!
194     \qmlproperty real QtQuick2::Scale::origin.x
195     \qmlproperty real QtQuick2::Scale::origin.y
196
197     The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
198     the rest of the item grows). By default the origin is 0, 0.
199 */
200
201 /*!
202     \qmlproperty real QtQuick2::Scale::xScale
203
204     The scaling factor for the X axis.
205 */
206
207 /*!
208     \qmlproperty real QtQuick2::Scale::yScale
209
210     The scaling factor for the Y axis.
211 */
212
213 /*!
214     \qmlclass Rotation QQuickRotation
215     \inqmlmodule QtQuick 2
216     \ingroup qml-transform-elements
217     \brief The Rotation object provides a way to rotate an Item.
218
219     The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
220     Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
221
222     The following example rotates a Rectangle around its interior point 25, 25:
223     \qml
224     Rectangle {
225         width: 100; height: 100
226         color: "blue"
227         transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
228     }
229     \endqml
230
231     Rotation also provides a way to specify 3D-like rotations for Items. For these types of
232     rotations you must specify the axis to rotate around in addition to the origin point.
233
234     The following example shows various 3D-like rotations applied to an \l Image.
235     \snippet doc/src/snippets/declarative/rotation.qml 0
236
237     \image axisrotation.png
238
239     \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
240 */
241
242 /*!
243     \qmlproperty real QtQuick2::Rotation::origin.x
244     \qmlproperty real QtQuick2::Rotation::origin.y
245
246     The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
247     the rest of the item rotates). By default the origin is 0, 0.
248 */
249
250 /*!
251     \qmlproperty real QtQuick2::Rotation::axis.x
252     \qmlproperty real QtQuick2::Rotation::axis.y
253     \qmlproperty real QtQuick2::Rotation::axis.z
254
255     The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
256     as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
257
258     For a typical 3D-like rotation you will usually specify both the origin and the axis.
259
260     \image 3d-rotation-axis.png
261 */
262
263 /*!
264     \qmlproperty real QtQuick2::Rotation::angle
265
266     The angle to rotate, in degrees clockwise.
267 */
268
269 QQuickTransformPrivate::QQuickTransformPrivate()
270 {
271 }
272
273 QQuickTransform::QQuickTransform(QObject *parent)
274 : QObject(*(new QQuickTransformPrivate), parent)
275 {
276 }
277
278 QQuickTransform::QQuickTransform(QQuickTransformPrivate &dd, QObject *parent)
279 : QObject(dd, parent)
280 {
281 }
282
283 QQuickTransform::~QQuickTransform()
284 {
285     Q_D(QQuickTransform);
286     for (int ii = 0; ii < d->items.count(); ++ii) {
287         QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
288         p->transforms.removeOne(this);
289         p->dirty(QQuickItemPrivate::Transform);
290     }
291 }
292
293 void QQuickTransform::update()
294 {
295     Q_D(QQuickTransform);
296     for (int ii = 0; ii < d->items.count(); ++ii) {
297         QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
298         p->dirty(QQuickItemPrivate::Transform);
299     }
300 }
301
302 QQuickContents::QQuickContents(QQuickItem *item)
303 : m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
304 {
305 }
306
307 QQuickContents::~QQuickContents()
308 {
309     QList<QQuickItem *> children = m_item->childItems();
310     for (int i = 0; i < children.count(); ++i) {
311         QQuickItem *child = children.at(i);
312         QQuickItemPrivate::get(child)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
313     }
314 }
315
316 bool QQuickContents::calcHeight(QQuickItem *changed)
317 {
318     qreal oldy = m_y;
319     qreal oldheight = m_height;
320
321     if (changed) {
322         qreal top = oldy;
323         qreal bottom = oldy + oldheight;
324         qreal y = changed->y();
325         if (y + changed->height() > bottom)
326             bottom = y + changed->height();
327         if (y < top)
328             top = y;
329         m_y = top;
330         m_height = bottom - top;
331     } else {
332         qreal top = FLT_MAX;
333         qreal bottom = 0;
334         QList<QQuickItem *> children = m_item->childItems();
335         for (int i = 0; i < children.count(); ++i) {
336             QQuickItem *child = children.at(i);
337             qreal y = child->y();
338             if (y + child->height() > bottom)
339                 bottom = y + child->height();
340             if (y < top)
341                 top = y;
342         }
343         if (!children.isEmpty())
344             m_y = top;
345         m_height = qMax(bottom - top, qreal(0.0));
346     }
347
348     return (m_height != oldheight || m_y != oldy);
349 }
350
351 bool QQuickContents::calcWidth(QQuickItem *changed)
352 {
353     qreal oldx = m_x;
354     qreal oldwidth = m_width;
355
356     if (changed) {
357         qreal left = oldx;
358         qreal right = oldx + oldwidth;
359         qreal x = changed->x();
360         if (x + changed->width() > right)
361             right = x + changed->width();
362         if (x < left)
363             left = x;
364         m_x = left;
365         m_width = right - left;
366     } else {
367         qreal left = FLT_MAX;
368         qreal right = 0;
369         QList<QQuickItem *> children = m_item->childItems();
370         for (int i = 0; i < children.count(); ++i) {
371             QQuickItem *child = children.at(i);
372             qreal x = child->x();
373             if (x + child->width() > right)
374                 right = x + child->width();
375             if (x < left)
376                 left = x;
377         }
378         if (!children.isEmpty())
379             m_x = left;
380         m_width = qMax(right - left, qreal(0.0));
381     }
382
383     return (m_width != oldwidth || m_x != oldx);
384 }
385
386 void QQuickContents::complete()
387 {
388     QQuickItemPrivate::get(m_item)->addItemChangeListener(this, QQuickItemPrivate::Children);
389
390     QList<QQuickItem *> children = m_item->childItems();
391     for (int i = 0; i < children.count(); ++i) {
392         QQuickItem *child = children.at(i);
393         QQuickItemPrivate::get(child)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
394         //###what about changes to visibility?
395     }
396     calcGeometry();
397 }
398
399 void QQuickContents::updateRect()
400 {
401     QQuickItemPrivate::get(m_item)->emitChildrenRectChanged(rectF());
402 }
403
404 void QQuickContents::itemGeometryChanged(QQuickItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
405 {
406     Q_UNUSED(changed)
407     bool wChanged = false;
408     bool hChanged = false;
409     //### we can only pass changed if the left edge has moved left, or the right edge has moved right
410     if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
411         wChanged = calcWidth(/*changed*/);
412     if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
413         hChanged = calcHeight(/*changed*/);
414     if (wChanged || hChanged)
415         updateRect();
416 }
417
418 void QQuickContents::itemDestroyed(QQuickItem *item)
419 {
420     if (item)
421         QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
422     calcGeometry();
423 }
424
425 void QQuickContents::itemChildRemoved(QQuickItem *, QQuickItem *item)
426 {
427     if (item)
428         QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
429     calcGeometry();
430 }
431
432 void QQuickContents::itemChildAdded(QQuickItem *, QQuickItem *item)
433 {
434     if (item)
435         QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
436     calcGeometry(item);
437 }
438
439 QQuickItemKeyFilter::QQuickItemKeyFilter(QQuickItem *item)
440 : m_processPost(false), m_next(0)
441 {
442     QQuickItemPrivate *p = item?QQuickItemPrivate::get(item):0;
443     if (p) {
444         m_next = p->keyHandler;
445         p->keyHandler = this;
446     }
447 }
448
449 QQuickItemKeyFilter::~QQuickItemKeyFilter()
450 {
451 }
452
453 void QQuickItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
454 {
455     if (m_next) m_next->keyPressed(event, post);
456 }
457
458 void QQuickItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
459 {
460     if (m_next) m_next->keyReleased(event, post);
461 }
462
463 void QQuickItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
464 {
465     if (m_next)
466         m_next->inputMethodEvent(event, post);
467     else
468         event->ignore();
469 }
470
471 QVariant QQuickItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
472 {
473     if (m_next) return m_next->inputMethodQuery(query);
474     return QVariant();
475 }
476
477 void QQuickItemKeyFilter::componentComplete()
478 {
479     if (m_next) m_next->componentComplete();
480 }
481 /*!
482     \qmlclass KeyNavigation QQuickKeyNavigationAttached
483     \inqmlmodule QtQuick 2
484     \ingroup qml-basic-interaction-elements
485     \brief The KeyNavigation attached property supports key navigation by arrow keys.
486
487     Key-based user interfaces commonly allow the use of arrow keys to navigate between
488     focusable items.  The KeyNavigation attached property enables this behavior by providing a
489     convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
490
491     The following example provides key navigation for a 2x2 grid of items:
492
493     \snippet doc/src/snippets/declarative/keynavigation.qml 0
494
495     The top-left item initially receives focus by setting \l {Item::}{focus} to
496     \c true. When an arrow key is pressed, the focus will move to the
497     appropriate item, as defined by the value that has been set for
498     the KeyNavigation \l left, \l right, \l up or \l down properties.
499
500     Note that if a KeyNavigation attached property receives the key press and release
501     events for a requested arrow or tab key, the event is accepted and does not
502     propagate any further.
503
504     By default, KeyNavigation receives key events after the item to which it is attached.
505     If the item accepts the key event, the KeyNavigation attached property will not
506     receive an event for that key.  Setting the \l priority property to
507     \c KeyNavigation.BeforeItem allows the event to be used for key navigation
508     before the item, rather than after.
509
510     If item to which the focus is switching is not enabled or visible, an attempt will
511     be made to skip this item and focus on the next. This is possible if there are
512     a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
513     or visible, they will also be skipped.
514
515     KeyNavigation will implicitly set the other direction to return focus to this item. So if you set
516     \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this
517     item. However, if that item's KeyNavigation has had right explicitly set then no change will occur.
518     This means that the above example could have been written, with the same behaviour, without specifing
519     KeyNavigation.right or KeyNavigation.down for any of the items.
520
521     \sa {Keys}{Keys attached property}
522 */
523
524 /*!
525     \qmlproperty Item QtQuick2::KeyNavigation::left
526     \qmlproperty Item QtQuick2::KeyNavigation::right
527     \qmlproperty Item QtQuick2::KeyNavigation::up
528     \qmlproperty Item QtQuick2::KeyNavigation::down
529     \qmlproperty Item QtQuick2::KeyNavigation::tab
530     \qmlproperty Item QtQuick2::KeyNavigation::backtab
531
532     These properties hold the item to assign focus to
533     when the left, right, up or down cursor keys, or the
534     tab key are pressed.
535 */
536
537 /*!
538     \qmlproperty Item QtQuick2::KeyNavigation::tab
539     \qmlproperty Item QtQuick2::KeyNavigation::backtab
540
541     These properties hold the item to assign focus to
542     when the Tab key or Shift+Tab key combination (Backtab) are pressed.
543 */
544
545 QQuickKeyNavigationAttached::QQuickKeyNavigationAttached(QObject *parent)
546 : QObject(*(new QQuickKeyNavigationAttachedPrivate), parent),
547   QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
548 {
549     m_processPost = true;
550 }
551
552 QQuickKeyNavigationAttached *
553 QQuickKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
554 {
555     return new QQuickKeyNavigationAttached(obj);
556 }
557
558 QQuickItem *QQuickKeyNavigationAttached::left() const
559 {
560     Q_D(const QQuickKeyNavigationAttached);
561     return d->left;
562 }
563
564 void QQuickKeyNavigationAttached::setLeft(QQuickItem *i)
565 {
566     Q_D(QQuickKeyNavigationAttached);
567     if (d->left == i)
568         return;
569     d->left = i;
570     d->leftSet = true;
571     QQuickKeyNavigationAttached* other =
572             qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
573     if (other && !other->d_func()->rightSet){
574         other->d_func()->right = qobject_cast<QQuickItem*>(parent());
575         emit other->rightChanged();
576     }
577     emit leftChanged();
578 }
579
580 QQuickItem *QQuickKeyNavigationAttached::right() const
581 {
582     Q_D(const QQuickKeyNavigationAttached);
583     return d->right;
584 }
585
586 void QQuickKeyNavigationAttached::setRight(QQuickItem *i)
587 {
588     Q_D(QQuickKeyNavigationAttached);
589     if (d->right == i)
590         return;
591     d->right = i;
592     d->rightSet = true;
593     QQuickKeyNavigationAttached* other =
594             qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
595     if (other && !other->d_func()->leftSet){
596         other->d_func()->left = qobject_cast<QQuickItem*>(parent());
597         emit other->leftChanged();
598     }
599     emit rightChanged();
600 }
601
602 QQuickItem *QQuickKeyNavigationAttached::up() const
603 {
604     Q_D(const QQuickKeyNavigationAttached);
605     return d->up;
606 }
607
608 void QQuickKeyNavigationAttached::setUp(QQuickItem *i)
609 {
610     Q_D(QQuickKeyNavigationAttached);
611     if (d->up == i)
612         return;
613     d->up = i;
614     d->upSet = true;
615     QQuickKeyNavigationAttached* other =
616             qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
617     if (other && !other->d_func()->downSet){
618         other->d_func()->down = qobject_cast<QQuickItem*>(parent());
619         emit other->downChanged();
620     }
621     emit upChanged();
622 }
623
624 QQuickItem *QQuickKeyNavigationAttached::down() const
625 {
626     Q_D(const QQuickKeyNavigationAttached);
627     return d->down;
628 }
629
630 void QQuickKeyNavigationAttached::setDown(QQuickItem *i)
631 {
632     Q_D(QQuickKeyNavigationAttached);
633     if (d->down == i)
634         return;
635     d->down = i;
636     d->downSet = true;
637     QQuickKeyNavigationAttached* other =
638             qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
639     if (other && !other->d_func()->upSet) {
640         other->d_func()->up = qobject_cast<QQuickItem*>(parent());
641         emit other->upChanged();
642     }
643     emit downChanged();
644 }
645
646 QQuickItem *QQuickKeyNavigationAttached::tab() const
647 {
648     Q_D(const QQuickKeyNavigationAttached);
649     return d->tab;
650 }
651
652 void QQuickKeyNavigationAttached::setTab(QQuickItem *i)
653 {
654     Q_D(QQuickKeyNavigationAttached);
655     if (d->tab == i)
656         return;
657     d->tab = i;
658     d->tabSet = true;
659     QQuickKeyNavigationAttached* other =
660             qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
661     if (other && !other->d_func()->backtabSet) {
662         other->d_func()->backtab = qobject_cast<QQuickItem*>(parent());
663         emit other->backtabChanged();
664     }
665     emit tabChanged();
666 }
667
668 QQuickItem *QQuickKeyNavigationAttached::backtab() const
669 {
670     Q_D(const QQuickKeyNavigationAttached);
671     return d->backtab;
672 }
673
674 void QQuickKeyNavigationAttached::setBacktab(QQuickItem *i)
675 {
676     Q_D(QQuickKeyNavigationAttached);
677     if (d->backtab == i)
678         return;
679     d->backtab = i;
680     d->backtabSet = true;
681     QQuickKeyNavigationAttached* other =
682             qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
683     if (other && !other->d_func()->tabSet) {
684         other->d_func()->tab = qobject_cast<QQuickItem*>(parent());
685         emit other->tabChanged();
686     }
687     emit backtabChanged();
688 }
689
690 /*!
691     \qmlproperty enumeration QtQuick2::KeyNavigation::priority
692
693     This property determines whether the keys are processed before
694     or after the attached item's own key handling.
695
696     \list
697     \o KeyNavigation.BeforeItem - process the key events before normal
698     item key processing.  If the event is used for key navigation, it will be accepted and will not
699     be passed on to the item.
700     \o KeyNavigation.AfterItem (default) - process the key events after normal item key
701     handling.  If the item accepts the key event it will not be
702     handled by the KeyNavigation attached property handler.
703     \endlist
704 */
705 QQuickKeyNavigationAttached::Priority QQuickKeyNavigationAttached::priority() const
706 {
707     return m_processPost ? AfterItem : BeforeItem;
708 }
709
710 void QQuickKeyNavigationAttached::setPriority(Priority order)
711 {
712     bool processPost = order == AfterItem;
713     if (processPost != m_processPost) {
714         m_processPost = processPost;
715         emit priorityChanged();
716     }
717 }
718
719 void QQuickKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
720 {
721     Q_D(QQuickKeyNavigationAttached);
722     event->ignore();
723
724     if (post != m_processPost) {
725         QQuickItemKeyFilter::keyPressed(event, post);
726         return;
727     }
728
729     bool mirror = false;
730     switch (event->key()) {
731     case Qt::Key_Left: {
732         if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
733             mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
734         QQuickItem* leftItem = mirror ? d->right : d->left;
735         if (leftItem) {
736             setFocusNavigation(leftItem, mirror ? "right" : "left");
737             event->accept();
738         }
739         break;
740     }
741     case Qt::Key_Right: {
742         if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
743             mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
744         QQuickItem* rightItem = mirror ? d->left : d->right;
745         if (rightItem) {
746             setFocusNavigation(rightItem, mirror ? "left" : "right");
747             event->accept();
748         }
749         break;
750     }
751     case Qt::Key_Up:
752         if (d->up) {
753             setFocusNavigation(d->up, "up");
754             event->accept();
755         }
756         break;
757     case Qt::Key_Down:
758         if (d->down) {
759             setFocusNavigation(d->down, "down");
760             event->accept();
761         }
762         break;
763     case Qt::Key_Tab:
764         if (d->tab) {
765             setFocusNavigation(d->tab, "tab");
766             event->accept();
767         }
768         break;
769     case Qt::Key_Backtab:
770         if (d->backtab) {
771             setFocusNavigation(d->backtab, "backtab");
772             event->accept();
773         }
774         break;
775     default:
776         break;
777     }
778
779     if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
780 }
781
782 void QQuickKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
783 {
784     Q_D(QQuickKeyNavigationAttached);
785     event->ignore();
786
787     if (post != m_processPost) {
788         QQuickItemKeyFilter::keyReleased(event, post);
789         return;
790     }
791
792     bool mirror = false;
793     switch (event->key()) {
794     case Qt::Key_Left:
795         if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
796             mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
797         if (mirror ? d->right : d->left)
798             event->accept();
799         break;
800     case Qt::Key_Right:
801         if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
802             mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
803         if (mirror ? d->left : d->right)
804             event->accept();
805         break;
806     case Qt::Key_Up:
807         if (d->up) {
808             event->accept();
809         }
810         break;
811     case Qt::Key_Down:
812         if (d->down) {
813             event->accept();
814         }
815         break;
816     case Qt::Key_Tab:
817         if (d->tab) {
818             event->accept();
819         }
820         break;
821     case Qt::Key_Backtab:
822         if (d->backtab) {
823             event->accept();
824         }
825         break;
826     default:
827         break;
828     }
829
830     if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
831 }
832
833 void QQuickKeyNavigationAttached::setFocusNavigation(QQuickItem *currentItem, const char *dir)
834 {
835     QQuickItem *initialItem = currentItem;
836     bool isNextItem = false;
837     do {
838         isNextItem = false;
839         if (currentItem->isVisible() && currentItem->isEnabled()) {
840             currentItem->setFocus(true);
841         } else {
842             QObject *attached =
843                 qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(currentItem, false);
844             if (attached) {
845                 QQuickItem *tempItem = qvariant_cast<QQuickItem*>(attached->property(dir));
846                 if (tempItem) {
847                     currentItem = tempItem;
848                     isNextItem = true;
849                 }
850             }
851         }
852     }
853     while (currentItem != initialItem && isNextItem);
854 }
855
856 const QQuickKeysAttached::SigMap QQuickKeysAttached::sigMap[] = {
857     { Qt::Key_Left, "leftPressed" },
858     { Qt::Key_Right, "rightPressed" },
859     { Qt::Key_Up, "upPressed" },
860     { Qt::Key_Down, "downPressed" },
861     { Qt::Key_Tab, "tabPressed" },
862     { Qt::Key_Backtab, "backtabPressed" },
863     { Qt::Key_Asterisk, "asteriskPressed" },
864     { Qt::Key_NumberSign, "numberSignPressed" },
865     { Qt::Key_Escape, "escapePressed" },
866     { Qt::Key_Return, "returnPressed" },
867     { Qt::Key_Enter, "enterPressed" },
868     { Qt::Key_Delete, "deletePressed" },
869     { Qt::Key_Space, "spacePressed" },
870     { Qt::Key_Back, "backPressed" },
871     { Qt::Key_Cancel, "cancelPressed" },
872     { Qt::Key_Select, "selectPressed" },
873     { Qt::Key_Yes, "yesPressed" },
874     { Qt::Key_No, "noPressed" },
875     { Qt::Key_Context1, "context1Pressed" },
876     { Qt::Key_Context2, "context2Pressed" },
877     { Qt::Key_Context3, "context3Pressed" },
878     { Qt::Key_Context4, "context4Pressed" },
879     { Qt::Key_Call, "callPressed" },
880     { Qt::Key_Hangup, "hangupPressed" },
881     { Qt::Key_Flip, "flipPressed" },
882     { Qt::Key_Menu, "menuPressed" },
883     { Qt::Key_VolumeUp, "volumeUpPressed" },
884     { Qt::Key_VolumeDown, "volumeDownPressed" },
885     { 0, 0 }
886 };
887
888 bool QQuickKeysAttachedPrivate::isConnected(const char *signalName)
889 {
890     return isSignalConnected(signalIndex(signalName));
891 }
892
893 /*!
894     \qmlclass Keys QQuickKeysAttached
895     \inqmlmodule QtQuick 2
896     \ingroup qml-basic-interaction-elements
897     \brief The Keys attached property provides key handling to Items.
898
899     All visual primitives support key handling via the Keys
900     attached property.  Keys can be handled via the onPressed
901     and onReleased signal properties.
902
903     The signal properties have a \l KeyEvent parameter, named
904     \e event which contains details of the event.  If a key is
905     handled \e event.accepted should be set to true to prevent the
906     event from propagating up the item hierarchy.
907
908     \section1 Example Usage
909
910     The following example shows how the general onPressed handler can
911     be used to test for a certain key; in this case, the left cursor
912     key:
913
914     \snippet doc/src/snippets/declarative/keys/keys-pressed.qml key item
915
916     Some keys may alternatively be handled via specific signal properties,
917     for example \e onSelectPressed.  These handlers automatically set
918     \e event.accepted to true.
919
920     \snippet doc/src/snippets/declarative/keys/keys-handler.qml key item
921
922     See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
923
924     \section1 Key Handling Priorities
925
926     The Keys attached property can be configured to handle key events
927     before or after the item it is attached to. This makes it possible
928     to intercept events in order to override an item's default behavior,
929     or act as a fallback for keys not handled by the item.
930
931     If \l priority is Keys.BeforeItem (default) the order of key event processing is:
932
933     \list 1
934     \o Items specified in \c forwardTo
935     \o specific key handlers, e.g. onReturnPressed
936     \o onKeyPress, onKeyRelease handlers
937     \o Item specific key handling, e.g. TextInput key handling
938     \o parent item
939     \endlist
940
941     If priority is Keys.AfterItem the order of key event processing is:
942
943     \list 1
944     \o Item specific key handling, e.g. TextInput key handling
945     \o Items specified in \c forwardTo
946     \o specific key handlers, e.g. onReturnPressed
947     \o onKeyPress, onKeyRelease handlers
948     \o parent item
949     \endlist
950
951     If the event is accepted during any of the above steps, key
952     propagation stops.
953
954     \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
955 */
956
957 /*!
958     \qmlproperty bool QtQuick2::Keys::enabled
959
960     This flags enables key handling if true (default); otherwise
961     no key handlers will be called.
962 */
963
964 /*!
965     \qmlproperty enumeration QtQuick2::Keys::priority
966
967     This property determines whether the keys are processed before
968     or after the attached item's own key handling.
969
970     \list
971     \o Keys.BeforeItem (default) - process the key events before normal
972     item key processing.  If the event is accepted it will not
973     be passed on to the item.
974     \o Keys.AfterItem - process the key events after normal item key
975     handling.  If the item accepts the key event it will not be
976     handled by the Keys attached property handler.
977     \endlist
978 */
979
980 /*!
981     \qmlproperty list<Object> QtQuick2::Keys::forwardTo
982
983     This property provides a way to forward key presses, key releases, and keyboard input
984     coming from input methods to other items. This can be useful when you want
985     one item to handle some keys (e.g. the up and down arrow keys), and another item to
986     handle other keys (e.g. the left and right arrow keys).  Once an item that has been
987     forwarded keys accepts the event it is no longer forwarded to items later in the
988     list.
989
990     This example forwards key events to two lists:
991     \qml
992     Item {
993         ListView {
994             id: list1
995             // ...
996         }
997         ListView {
998             id: list2
999             // ...
1000         }
1001         Keys.forwardTo: [list1, list2]
1002         focus: true
1003     }
1004     \endqml
1005 */
1006
1007 /*!
1008     \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
1009
1010     This handler is called when a key has been pressed. The \a event
1011     parameter provides information about the event.
1012 */
1013
1014 /*!
1015     \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
1016
1017     This handler is called when a key has been released. The \a event
1018     parameter provides information about the event.
1019 */
1020
1021 /*!
1022     \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
1023
1024     This handler is called when the digit '0' has been pressed. The \a event
1025     parameter provides information about the event.
1026 */
1027
1028 /*!
1029     \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
1030
1031     This handler is called when the digit '1' has been pressed. The \a event
1032     parameter provides information about the event.
1033 */
1034
1035 /*!
1036     \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
1037
1038     This handler is called when the digit '2' has been pressed. The \a event
1039     parameter provides information about the event.
1040 */
1041
1042 /*!
1043     \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
1044
1045     This handler is called when the digit '3' has been pressed. The \a event
1046     parameter provides information about the event.
1047 */
1048
1049 /*!
1050     \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
1051
1052     This handler is called when the digit '4' has been pressed. The \a event
1053     parameter provides information about the event.
1054 */
1055
1056 /*!
1057     \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
1058
1059     This handler is called when the digit '5' has been pressed. The \a event
1060     parameter provides information about the event.
1061 */
1062
1063 /*!
1064     \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
1065
1066     This handler is called when the digit '6' has been pressed. The \a event
1067     parameter provides information about the event.
1068 */
1069
1070 /*!
1071     \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
1072
1073     This handler is called when the digit '7' has been pressed. The \a event
1074     parameter provides information about the event.
1075 */
1076
1077 /*!
1078     \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
1079
1080     This handler is called when the digit '8' has been pressed. The \a event
1081     parameter provides information about the event.
1082 */
1083
1084 /*!
1085     \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
1086
1087     This handler is called when the digit '9' has been pressed. The \a event
1088     parameter provides information about the event.
1089 */
1090
1091 /*!
1092     \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
1093
1094     This handler is called when the Left arrow has been pressed. The \a event
1095     parameter provides information about the event.
1096 */
1097
1098 /*!
1099     \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
1100
1101     This handler is called when the Right arrow has been pressed. The \a event
1102     parameter provides information about the event.
1103 */
1104
1105 /*!
1106     \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
1107
1108     This handler is called when the Up arrow has been pressed. The \a event
1109     parameter provides information about the event.
1110 */
1111
1112 /*!
1113     \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
1114
1115     This handler is called when the Down arrow has been pressed. The \a event
1116     parameter provides information about the event.
1117 */
1118
1119 /*!
1120     \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
1121
1122     This handler is called when the Tab key has been pressed. The \a event
1123     parameter provides information about the event.
1124 */
1125
1126 /*!
1127     \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
1128
1129     This handler is called when the Shift+Tab key combination (Backtab) has
1130     been pressed. The \a event parameter provides information about the event.
1131 */
1132
1133 /*!
1134     \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
1135
1136     This handler is called when the Asterisk '*' has been pressed. The \a event
1137     parameter provides information about the event.
1138 */
1139
1140 /*!
1141     \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
1142
1143     This handler is called when the Escape key has been pressed. The \a event
1144     parameter provides information about the event.
1145 */
1146
1147 /*!
1148     \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
1149
1150     This handler is called when the Return key has been pressed. The \a event
1151     parameter provides information about the event.
1152 */
1153
1154 /*!
1155     \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
1156
1157     This handler is called when the Enter key has been pressed. The \a event
1158     parameter provides information about the event.
1159 */
1160
1161 /*!
1162     \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
1163
1164     This handler is called when the Delete key has been pressed. The \a event
1165     parameter provides information about the event.
1166 */
1167
1168 /*!
1169     \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
1170
1171     This handler is called when the Space key has been pressed. The \a event
1172     parameter provides information about the event.
1173 */
1174
1175 /*!
1176     \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
1177
1178     This handler is called when the Back key has been pressed. The \a event
1179     parameter provides information about the event.
1180 */
1181
1182 /*!
1183     \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
1184
1185     This handler is called when the Cancel key has been pressed. The \a event
1186     parameter provides information about the event.
1187 */
1188
1189 /*!
1190     \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
1191
1192     This handler is called when the Select key has been pressed. The \a event
1193     parameter provides information about the event.
1194 */
1195
1196 /*!
1197     \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
1198
1199     This handler is called when the Yes key has been pressed. The \a event
1200     parameter provides information about the event.
1201 */
1202
1203 /*!
1204     \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
1205
1206     This handler is called when the No key has been pressed. The \a event
1207     parameter provides information about the event.
1208 */
1209
1210 /*!
1211     \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
1212
1213     This handler is called when the Context1 key has been pressed. The \a event
1214     parameter provides information about the event.
1215 */
1216
1217 /*!
1218     \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
1219
1220     This handler is called when the Context2 key has been pressed. The \a event
1221     parameter provides information about the event.
1222 */
1223
1224 /*!
1225     \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
1226
1227     This handler is called when the Context3 key has been pressed. The \a event
1228     parameter provides information about the event.
1229 */
1230
1231 /*!
1232     \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
1233
1234     This handler is called when the Context4 key has been pressed. The \a event
1235     parameter provides information about the event.
1236 */
1237
1238 /*!
1239     \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
1240
1241     This handler is called when the Call key has been pressed. The \a event
1242     parameter provides information about the event.
1243 */
1244
1245 /*!
1246     \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
1247
1248     This handler is called when the Hangup key has been pressed. The \a event
1249     parameter provides information about the event.
1250 */
1251
1252 /*!
1253     \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
1254
1255     This handler is called when the Flip key has been pressed. The \a event
1256     parameter provides information about the event.
1257 */
1258
1259 /*!
1260     \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
1261
1262     This handler is called when the Menu key has been pressed. The \a event
1263     parameter provides information about the event.
1264 */
1265
1266 /*!
1267     \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
1268
1269     This handler is called when the VolumeUp key has been pressed. The \a event
1270     parameter provides information about the event.
1271 */
1272
1273 /*!
1274     \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
1275
1276     This handler is called when the VolumeDown key has been pressed. The \a event
1277     parameter provides information about the event.
1278 */
1279
1280 QQuickKeysAttached::QQuickKeysAttached(QObject *parent)
1281 : QObject(*(new QQuickKeysAttachedPrivate), parent),
1282   QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
1283 {
1284     Q_D(QQuickKeysAttached);
1285     m_processPost = false;
1286     d->item = qobject_cast<QQuickItem*>(parent);
1287 }
1288
1289 QQuickKeysAttached::~QQuickKeysAttached()
1290 {
1291 }
1292
1293 QQuickKeysAttached::Priority QQuickKeysAttached::priority() const
1294 {
1295     return m_processPost ? AfterItem : BeforeItem;
1296 }
1297
1298 void QQuickKeysAttached::setPriority(Priority order)
1299 {
1300     bool processPost = order == AfterItem;
1301     if (processPost != m_processPost) {
1302         m_processPost = processPost;
1303         emit priorityChanged();
1304     }
1305 }
1306
1307 void QQuickKeysAttached::componentComplete()
1308 {
1309     Q_D(QQuickKeysAttached);
1310     if (d->item) {
1311         for (int ii = 0; ii < d->targets.count(); ++ii) {
1312             QQuickItem *targetItem = d->targets.at(ii);
1313             if (targetItem && (targetItem->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1314                 d->item->setFlag(QQuickItem::ItemAcceptsInputMethod);
1315                 break;
1316             }
1317         }
1318     }
1319 }
1320
1321 void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
1322 {
1323     Q_D(QQuickKeysAttached);
1324     if (post != m_processPost || !d->enabled || d->inPress) {
1325         event->ignore();
1326         QQuickItemKeyFilter::keyPressed(event, post);
1327         return;
1328     }
1329
1330     // first process forwards
1331     if (d->item && d->item->canvas()) {
1332         d->inPress = true;
1333         for (int ii = 0; ii < d->targets.count(); ++ii) {
1334             QQuickItem *i = d->targets.at(ii);
1335             if (i && i->isVisible()) {
1336                 d->item->canvas()->sendEvent(i, event);
1337                 if (event->isAccepted()) {
1338                     d->inPress = false;
1339                     return;
1340                 }
1341             }
1342         }
1343         d->inPress = false;
1344     }
1345
1346     QQuickKeyEvent ke(*event);
1347     QByteArray keySignal = keyToSignal(event->key());
1348     if (!keySignal.isEmpty()) {
1349         keySignal += "(QQuickKeyEvent*)";
1350         if (d->isConnected(keySignal)) {
1351             // If we specifically handle a key then default to accepted
1352             ke.setAccepted(true);
1353             int idx = QQuickKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1354             metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QQuickKeyEvent*, &ke));
1355         }
1356     }
1357     if (!ke.isAccepted())
1358         emit pressed(&ke);
1359     event->setAccepted(ke.isAccepted());
1360
1361     if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
1362 }
1363
1364 void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
1365 {
1366     Q_D(QQuickKeysAttached);
1367     if (post != m_processPost || !d->enabled || d->inRelease) {
1368         event->ignore();
1369         QQuickItemKeyFilter::keyReleased(event, post);
1370         return;
1371     }
1372
1373     if (d->item && d->item->canvas()) {
1374         d->inRelease = true;
1375         for (int ii = 0; ii < d->targets.count(); ++ii) {
1376             QQuickItem *i = d->targets.at(ii);
1377             if (i && i->isVisible()) {
1378                 d->item->canvas()->sendEvent(i, event);
1379                 if (event->isAccepted()) {
1380                     d->inRelease = false;
1381                     return;
1382                 }
1383             }
1384         }
1385         d->inRelease = false;
1386     }
1387
1388     QQuickKeyEvent ke(*event);
1389     emit released(&ke);
1390     event->setAccepted(ke.isAccepted());
1391
1392     if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
1393 }
1394
1395 void QQuickKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1396 {
1397     Q_D(QQuickKeysAttached);
1398     if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
1399         d->inIM = true;
1400         for (int ii = 0; ii < d->targets.count(); ++ii) {
1401             QQuickItem *i = d->targets.at(ii);
1402             if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod)) {
1403                 d->item->canvas()->sendEvent(i, event);
1404                 if (event->isAccepted()) {
1405                     d->imeItem = i;
1406                     d->inIM = false;
1407                     return;
1408                 }
1409             }
1410         }
1411         d->inIM = false;
1412     }
1413     QQuickItemKeyFilter::inputMethodEvent(event, post);
1414 }
1415
1416 QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1417 {
1418     Q_D(const QQuickKeysAttached);
1419     if (d->item) {
1420         for (int ii = 0; ii < d->targets.count(); ++ii) {
1421             QQuickItem *i = d->targets.at(ii);
1422             if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod) && i == d->imeItem) {
1423                 //### how robust is i == d->imeItem check?
1424                 QVariant v = i->inputMethodQuery(query);
1425                 if (v.userType() == QVariant::RectF)
1426                     v = d->item->mapRectFromItem(i, v.toRectF());  //### cost?
1427                 return v;
1428             }
1429         }
1430     }
1431     return QQuickItemKeyFilter::inputMethodQuery(query);
1432 }
1433
1434 QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
1435 {
1436     return new QQuickKeysAttached(obj);
1437 }
1438
1439 /*!
1440     \qmlclass LayoutMirroring QQuickLayoutMirroringAttached
1441     \inqmlmodule QtQuick 2
1442     \ingroup qml-utility-elements
1443     \brief The LayoutMirroring attached property is used to mirror layout behavior.
1444
1445     The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
1446     \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
1447     and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
1448     anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
1449     horizontal layout of child items.
1450
1451     Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
1452     only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
1453     behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
1454     for an item, mirroring is not enabled.
1455
1456     The following example shows mirroring in action. The \l Row below is specified as being anchored
1457     to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
1458     reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
1459     from left to right by default, they are now positioned from right to left instead, as demonstrated
1460     by the numbering and opacity of the items:
1461
1462     \snippet doc/src/snippets/declarative/layoutmirroring.qml 0
1463
1464     \image layoutmirroring.png
1465
1466     Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
1467     layout versions of an application to target different language areas. The \l childrenInherit
1468     property allows layout mirroring to be applied without manually setting layout configurations
1469     for every item in an application. Keep in mind, however, that mirroring does not affect any
1470     positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
1471     mirroring enabled, it will often be necessary to apply some layout fixes to support the
1472     desired layout direction. Also, it may be necessary to disable the mirroring of individual
1473     child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
1474     mirroring is not the desired behavior, or if the child item already implements mirroring in
1475     some custom way.
1476
1477     See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
1478     other related features to implement right-to-left support for an application.
1479 */
1480
1481 /*!
1482     \qmlproperty bool QtQuick2::LayoutMirroring::enabled
1483
1484     This property holds whether the item's layout is mirrored horizontally. Setting this to true
1485     horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
1486     and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
1487     (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
1488     this also mirrors the horizontal layout direction of the item.
1489
1490     The default value is false.
1491 */
1492
1493 /*!
1494     \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
1495
1496     This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
1497     is inherited by its children.
1498
1499     The default value is false.
1500 */
1501
1502
1503 QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
1504 {
1505     if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) {
1506         itemPrivate = QQuickItemPrivate::get(item);
1507         itemPrivate->attachedLayoutDirection = this;
1508     } else
1509         qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
1510 }
1511
1512 QQuickLayoutMirroringAttached * QQuickLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
1513 {
1514     return new QQuickLayoutMirroringAttached(object);
1515 }
1516
1517 bool QQuickLayoutMirroringAttached::enabled() const
1518 {
1519     return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
1520 }
1521
1522 void QQuickLayoutMirroringAttached::setEnabled(bool enabled)
1523 {
1524     if (!itemPrivate)
1525         return;
1526
1527     itemPrivate->isMirrorImplicit = false;
1528     if (enabled != itemPrivate->effectiveLayoutMirror) {
1529         itemPrivate->setLayoutMirror(enabled);
1530         if (itemPrivate->inheritMirrorFromItem)
1531              itemPrivate->resolveLayoutMirror();
1532     }
1533 }
1534
1535 void QQuickLayoutMirroringAttached::resetEnabled()
1536 {
1537     if (itemPrivate && !itemPrivate->isMirrorImplicit) {
1538         itemPrivate->isMirrorImplicit = true;
1539         itemPrivate->resolveLayoutMirror();
1540     }
1541 }
1542
1543 bool QQuickLayoutMirroringAttached::childrenInherit() const
1544 {
1545     return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
1546 }
1547
1548 void QQuickLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
1549     if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
1550         itemPrivate->inheritMirrorFromItem = childrenInherit;
1551         itemPrivate->resolveLayoutMirror();
1552         childrenInheritChanged();
1553     }
1554 }
1555
1556 void QQuickItemPrivate::resolveLayoutMirror()
1557 {
1558     Q_Q(QQuickItem);
1559     if (QQuickItem *parentItem = q->parentItem()) {
1560         QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parentItem);
1561         setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
1562     } else {
1563         setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
1564     }
1565 }
1566
1567 void QQuickItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
1568 {
1569     inherit = inherit || inheritMirrorFromItem;
1570     if (!isMirrorImplicit && inheritMirrorFromItem)
1571         mirror = effectiveLayoutMirror;
1572     if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
1573         return;
1574
1575     inheritMirrorFromParent = inherit;
1576     inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
1577
1578     if (isMirrorImplicit)
1579         setLayoutMirror(inherit ? inheritedLayoutMirror : false);
1580     for (int i = 0; i < childItems.count(); ++i) {
1581         if (QQuickItem *child = qobject_cast<QQuickItem *>(childItems.at(i))) {
1582             QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
1583             childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
1584         }
1585     }
1586 }
1587
1588 void QQuickItemPrivate::setLayoutMirror(bool mirror)
1589 {
1590     if (mirror != effectiveLayoutMirror) {
1591         effectiveLayoutMirror = mirror;
1592         if (_anchors) {
1593             QQuickAnchorsPrivate *anchor_d = QQuickAnchorsPrivate::get(_anchors);
1594             anchor_d->fillChanged();
1595             anchor_d->centerInChanged();
1596             anchor_d->updateHorizontalAnchors();
1597             emit _anchors->mirroredChanged();
1598         }
1599         mirrorChange();
1600         if (attachedLayoutDirection) {
1601             emit attachedLayoutDirection->enabledChanged();
1602         }
1603     }
1604 }
1605
1606 /*!
1607     \class QQuickItem
1608     \brief The QQuickItem class provides the most basic of all visual items in QML.
1609
1610     \inmodule QtQuick
1611
1612     All visual items in Qt Declarative inherit from QQuickItem.  Although QQuickItem
1613     has no visual appearance, it defines all the properties that are
1614     common across visual items - such as the x and y position, the
1615     width and height, \l {anchor-layout}{anchoring} and key handling.
1616
1617     You can subclass QQuickItem to provide your own custom visual item that inherits
1618     these features. Note that, because it does not draw anything, QQuickItem sets the
1619     QGraphicsItem::ItemHasNoContents flag. If you subclass QQuickItem to create a visual
1620     item, you will need to unset this flag.
1621
1622 */
1623
1624 /*!
1625     \qmlclass Item QQuickItem
1626     \inqmlmodule QtQuick 2
1627     \ingroup qml-basic-visual-elements
1628     \brief The Item is the most basic of all visual items in QML.
1629
1630     All visual items in Qt Declarative inherit from Item.  Although Item
1631     has no visual appearance, it defines all the properties that are
1632     common across visual items - such as the x and y position, the
1633     width and height, \l {anchor-layout}{anchoring} and key handling.
1634
1635     Item is also useful for grouping items together.
1636
1637     \qml
1638     Item {
1639         Image {
1640             source: "tile.png"
1641         }
1642         Image {
1643             x: 80
1644             width: 100
1645             height: 100
1646             source: "tile.png"
1647         }
1648         Image {
1649             x: 190
1650             width: 100
1651             height: 100
1652             fillMode: Image.Tile
1653             source: "tile.png"
1654         }
1655     }
1656     \endqml
1657
1658
1659     \section1 Key Handling
1660
1661     Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1662     attached property.  The \e Keys attached property provides basic handlers such
1663     as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1664     as well as handlers for specific keys, such as
1665     \l {Keys::onCancelPressed}{onCancelPressed}.  The example below
1666     assigns \l {qmlfocus}{focus} to the item and handles
1667     the Left key via the general \e onPressed handler and the Select key via the
1668     onSelectPressed handler:
1669
1670     \qml
1671     Item {
1672         focus: true
1673         Keys.onPressed: {
1674             if (event.key == Qt.Key_Left) {
1675                 console.log("move left");
1676                 event.accepted = true;
1677             }
1678         }
1679         Keys.onSelectPressed: console.log("Selected");
1680     }
1681     \endqml
1682
1683     See the \l {Keys}{Keys} attached property for detailed documentation.
1684
1685     \section1 Layout Mirroring
1686
1687     Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1688
1689 */
1690
1691 /*!
1692     \fn void QQuickItem::childrenRectChanged(const QRectF &)
1693     \internal
1694 */
1695
1696 /*!
1697     \fn void QQuickItem::baselineOffsetChanged(qreal)
1698     \internal
1699 */
1700
1701 /*!
1702     \fn void QQuickItem::stateChanged(const QString &state)
1703     \internal
1704 */
1705
1706 /*!
1707     \fn void QQuickItem::parentChanged(QQuickItem *)
1708     \internal
1709 */
1710
1711 /*!
1712     \fn void QQuickItem::smoothChanged(bool)
1713     \internal
1714 */
1715
1716 /*!
1717     \fn void QQuickItem::clipChanged(bool)
1718     \internal
1719 */
1720
1721 /*! \fn void QQuickItem::transformOriginChanged(TransformOrigin)
1722   \internal
1723 */
1724
1725 /*!
1726     \fn void QQuickItem::focusChanged(bool)
1727     \internal
1728 */
1729
1730 /*!
1731     \fn void QQuickItem::activeFocusChanged(bool)
1732     \internal
1733 */
1734 /*!
1735     \fn QQuickItem::QQuickItem(QQuickItem *parent)
1736
1737     Constructs a QQuickItem with the given \a parent.
1738 */
1739 QQuickItem::QQuickItem(QQuickItem* parent)
1740 : QObject(*(new QQuickItemPrivate), parent)
1741 {
1742     Q_D(QQuickItem);
1743     d->init(parent);
1744 }
1745
1746 /*! \internal
1747 */
1748 QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
1749 : QObject(dd, parent)
1750 {
1751     Q_D(QQuickItem);
1752     d->init(parent);
1753 }
1754
1755 #ifndef QT_NO_DEBUG
1756 static int qt_item_count = 0;
1757
1758 static void qt_print_item_count()
1759 {
1760     qDebug("Number of leaked items: %i", qt_item_count);
1761     qt_item_count = -1;
1762 }
1763 #endif
1764
1765 /*!
1766     Destroys the QQuickItem.
1767 */
1768 QQuickItem::~QQuickItem()
1769 {
1770 #ifndef QT_NO_DEBUG
1771     --qt_item_count;
1772     if (qt_item_count < 0)
1773         qDebug("Item destroyed after qt_print_item_count() was called.");
1774 #endif
1775
1776     Q_D(QQuickItem);
1777
1778     if (d->parentItem)
1779         setParentItem(0);
1780     else if (d->canvas && d->itemNodeInstance)
1781         QQuickCanvasPrivate::get(d->canvas)->cleanup(d->itemNodeInstance); // cleanup root
1782     // XXX todo - optimize
1783     while (!d->childItems.isEmpty())
1784         d->childItems.first()->setParentItem(0);
1785
1786     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1787         QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1788         if (anchor)
1789             anchor->clearItem(this);
1790     }
1791
1792     /*
1793         update item anchors that depended on us unless they are our child (and will also be destroyed),
1794         or our sibling, and our parent is also being destroyed.
1795     */
1796     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1797         QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1798         if (anchor && anchor->item && anchor->item->parentItem() && anchor->item->parentItem() != this)
1799             anchor->update();
1800     }
1801
1802     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1803         const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1804         if (change.types & QQuickItemPrivate::Destroyed)
1805             change.listener->itemDestroyed(this);
1806     }
1807     d->changeListeners.clear();
1808     delete d->_anchorLines; d->_anchorLines = 0;
1809     delete d->_anchors; d->_anchors = 0;
1810     delete d->_stateGroup; d->_stateGroup = 0;
1811     delete d->_contents; d->_contents = 0;
1812 }
1813
1814 /*!
1815     \qmlproperty enumeration QtQuick2::Item::transformOrigin
1816     This property holds the origin point around which scale and rotation transform.
1817
1818     Nine transform origins are available, as shown in the image below.
1819
1820     \image declarative-transformorigin.png
1821
1822     This example rotates an image around its bottom-right corner.
1823     \qml
1824     Image {
1825         source: "myimage.png"
1826         transformOrigin: Item.BottomRight
1827         rotation: 45
1828     }
1829     \endqml
1830
1831     The default transform origin is \c Item.Center.
1832
1833     To set an arbitrary transform origin point use the \l Scale or \l Rotation
1834     transform elements.
1835 */
1836
1837 /*!
1838     \qmlproperty Item QtQuick2::Item::parent
1839     This property holds the parent of the item.
1840 */
1841
1842 /*!
1843     \property QQuickItem::parent
1844     This property holds the parent of the item.
1845 */
1846 void QQuickItem::setParentItem(QQuickItem *parentItem)
1847 {
1848     Q_D(QQuickItem);
1849     if (parentItem == d->parentItem)
1850         return;
1851
1852     d->removeFromDirtyList();
1853
1854     QQuickItem *oldParentItem = d->parentItem;
1855     QQuickItem *scopeFocusedItem = 0;
1856
1857     if (oldParentItem) {
1858         QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem);
1859
1860         QQuickItem *scopeItem = 0;
1861
1862         if (d->canvas && hasFocus()) {
1863             scopeItem = oldParentItem;
1864             while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1865             scopeFocusedItem = this;
1866         } else if (d->canvas && !isFocusScope() && d->subFocusItem) {
1867             scopeItem = oldParentItem;
1868             while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1869             scopeFocusedItem = d->subFocusItem;
1870         }
1871
1872         if (scopeFocusedItem)
1873             QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
1874                                                                 QQuickCanvasPrivate::DontChangeFocusProperty);
1875
1876         op->removeChild(this);
1877     }
1878
1879     d->parentItem = parentItem;
1880
1881     QQuickCanvas *parentCanvas = parentItem?QQuickItemPrivate::get(parentItem)->canvas:0;
1882     if (d->canvas != parentCanvas) {
1883         QQuickItemPrivate::InitializationState initState;
1884         initState.clear();
1885         d->initCanvas(&initState, parentCanvas);
1886     }
1887
1888     d->dirty(QQuickItemPrivate::ParentChanged);
1889
1890     if (d->parentItem)
1891         QQuickItemPrivate::get(d->parentItem)->addChild(this);
1892
1893     d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
1894     d->setEffectiveEnableRecur(d->calcEffectiveEnable());
1895
1896     if (scopeFocusedItem && d->parentItem && d->canvas) {
1897         // We need to test whether this item becomes scope focused
1898         QQuickItem *scopeItem = 0;
1899         scopeItem = d->parentItem;
1900         while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1901
1902         if (scopeItem->scopedFocusItem()) {
1903             QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
1904             emit scopeFocusedItem->focusChanged(false);
1905         } else {
1906             QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
1907                                                               QQuickCanvasPrivate::DontChangeFocusProperty);
1908         }
1909     }
1910
1911     d->resolveLayoutMirror();
1912
1913     d->itemChange(ItemParentHasChanged, d->parentItem);
1914
1915     d->parentNotifier.notify();
1916     emit parentChanged(d->parentItem);
1917 }
1918
1919 void QQuickItem::stackBefore(const QQuickItem *sibling)
1920 {
1921     Q_D(QQuickItem);
1922     if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
1923         qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
1924         return;
1925     }
1926
1927     QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
1928
1929     int myIndex = parentPrivate->childItems.indexOf(this);
1930     int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
1931
1932     Q_ASSERT(myIndex != -1 && siblingIndex != -1);
1933
1934     if (myIndex == siblingIndex - 1)
1935         return;
1936
1937     parentPrivate->childItems.removeAt(myIndex);
1938
1939     if (myIndex < siblingIndex) --siblingIndex;
1940
1941     parentPrivate->childItems.insert(siblingIndex, this);
1942
1943     parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
1944     parentPrivate->markSortedChildrenDirty(this);
1945
1946     for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
1947         QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
1948 }
1949
1950 void QQuickItem::stackAfter(const QQuickItem *sibling)
1951 {
1952     Q_D(QQuickItem);
1953     if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
1954         qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
1955         return;
1956     }
1957
1958     QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
1959
1960     int myIndex = parentPrivate->childItems.indexOf(this);
1961     int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
1962
1963     Q_ASSERT(myIndex != -1 && siblingIndex != -1);
1964
1965     if (myIndex == siblingIndex + 1)
1966         return;
1967
1968     parentPrivate->childItems.removeAt(myIndex);
1969
1970     if (myIndex < siblingIndex) --siblingIndex;
1971
1972     parentPrivate->childItems.insert(siblingIndex + 1, this);
1973
1974     parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
1975     parentPrivate->markSortedChildrenDirty(this);
1976
1977     for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
1978         QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
1979 }
1980
1981 /*!
1982     Returns the QQuickItem parent of this item.
1983 */
1984 QQuickItem *QQuickItem::parentItem() const
1985 {
1986     Q_D(const QQuickItem);
1987     return d->parentItem;
1988 }
1989
1990 QSGEngine *QQuickItem::sceneGraphEngine() const
1991 {
1992     return canvas()->sceneGraphEngine();
1993 }
1994
1995 QQuickCanvas *QQuickItem::canvas() const
1996 {
1997     Q_D(const QQuickItem);
1998     return d->canvas;
1999 }
2000
2001 static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
2002 {
2003     return lhs->z() < rhs->z();
2004 }
2005
2006 QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
2007 {
2008     if (sortedChildItems)
2009         return *sortedChildItems;
2010
2011     // If none of the items have set Z then the paint order list is the same as
2012     // the childItems list.  This is by far the most common case.
2013     bool haveZ = false;
2014     for (int i = 0; i < childItems.count(); ++i) {
2015         if (QQuickItemPrivate::get(childItems.at(i))->z != 0.) {
2016             haveZ = true;
2017             break;
2018         }
2019     }
2020     if (haveZ) {
2021         sortedChildItems = new QList<QQuickItem*>(childItems);
2022         qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
2023         return *sortedChildItems;
2024     }
2025
2026     sortedChildItems = const_cast<QList<QQuickItem*>*>(&childItems);
2027
2028     return childItems;
2029 }
2030
2031 void QQuickItemPrivate::addChild(QQuickItem *child)
2032 {
2033     Q_Q(QQuickItem);
2034
2035     Q_ASSERT(!childItems.contains(child));
2036
2037     childItems.append(child);
2038
2039     markSortedChildrenDirty(child);
2040     dirty(QQuickItemPrivate::ChildrenChanged);
2041
2042     itemChange(QQuickItem::ItemChildAddedChange, child);
2043
2044     emit q->childrenChanged();
2045 }
2046
2047 void QQuickItemPrivate::removeChild(QQuickItem *child)
2048 {
2049     Q_Q(QQuickItem);
2050
2051     Q_ASSERT(child);
2052     Q_ASSERT(childItems.contains(child));
2053     childItems.removeOne(child);
2054     Q_ASSERT(!childItems.contains(child));
2055
2056     markSortedChildrenDirty(child);
2057     dirty(QQuickItemPrivate::ChildrenChanged);
2058
2059     itemChange(QQuickItem::ItemChildRemovedChange, child);
2060
2061     emit q->childrenChanged();
2062 }
2063
2064 void QQuickItemPrivate::InitializationState::clear()
2065 {
2066     focusScope = 0;
2067 }
2068
2069 void QQuickItemPrivate::InitializationState::clear(QQuickItem *fs)
2070 {
2071     focusScope = fs;
2072 }
2073
2074 QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *item)
2075 {
2076     if (!focusScope) {
2077         QQuickItem *fs = item->parentItem();
2078         while (!fs->isFocusScope())
2079             fs = fs->parentItem();
2080         focusScope = fs;
2081     }
2082     return focusScope;
2083 }
2084
2085 void QQuickItemPrivate::initCanvas(InitializationState *state, QQuickCanvas *c)
2086 {
2087     Q_Q(QQuickItem);
2088
2089     if (canvas) {
2090         removeFromDirtyList();
2091         QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
2092         if (polishScheduled)
2093             c->itemsToPolish.remove(q);
2094         if (c->mouseGrabberItem == q)
2095             c->mouseGrabberItem = 0;
2096         if ( hoverEnabled )
2097             c->hoverItems.removeAll(q);
2098         if (itemNodeInstance)
2099             c->cleanup(itemNodeInstance);
2100     }
2101
2102     canvas = c;
2103
2104     if (canvas && polishScheduled)
2105         QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2106
2107     itemNodeInstance = 0;
2108     opacityNode = 0;
2109     clipNode = 0;
2110     rootNode = 0;
2111     groupNode = 0;
2112     paintNode = 0;
2113     beforePaintNode = 0;
2114
2115     InitializationState _dummy;
2116     InitializationState *childState = state;
2117
2118     if (c && q->isFocusScope()) {
2119         _dummy.clear(q);
2120         childState = &_dummy;
2121     }
2122
2123     for (int ii = 0; ii < childItems.count(); ++ii) {
2124         QQuickItem *child = childItems.at(ii);
2125         QQuickItemPrivate::get(child)->initCanvas(childState, c);
2126     }
2127
2128     if (c && focus) {
2129         // Fixup
2130         if (state->getFocusScope(q)->scopedFocusItem()) {
2131             focus = false;
2132             emit q->focusChanged(false);
2133         } else {
2134             QQuickCanvasPrivate::get(canvas)->setFocusInScope(state->getFocusScope(q), q);
2135         }
2136     }
2137
2138     dirty(Canvas);
2139
2140     if (screenAttached)
2141         screenAttached->canvasChanged(c);
2142     itemChange(QQuickItem::ItemSceneChange, c);
2143 }
2144
2145 /*!
2146 Returns a transform that maps points from canvas space into item space.
2147 */
2148 QTransform QQuickItemPrivate::canvasToItemTransform() const
2149 {
2150     // XXX todo - optimize
2151     return itemToCanvasTransform().inverted();
2152 }
2153
2154 /*!
2155 Returns a transform that maps points from item space into canvas space.
2156 */
2157 QTransform QQuickItemPrivate::itemToCanvasTransform() const
2158 {
2159     // XXX todo
2160     QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2161     itemToParentTransform(rv);
2162     return rv;
2163 }
2164
2165 /*!
2166 Motifies \a t with this items local transform relative to its parent.
2167 */
2168 void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
2169 {
2170     if (x || y)
2171         t.translate(x, y);
2172
2173     if (!transforms.isEmpty()) {
2174         QMatrix4x4 m(t);
2175         for (int ii = transforms.count() - 1; ii >= 0; --ii)
2176             transforms.at(ii)->applyTo(&m);
2177         t = m.toTransform();
2178     }
2179
2180     if (scale != 1. || rotation != 0.) {
2181         QPointF tp = computeTransformOrigin();
2182         t.translate(tp.x(), tp.y());
2183         t.scale(scale, scale);
2184         t.rotate(rotation);
2185         t.translate(-tp.x(), -tp.y());
2186     }
2187 }
2188
2189
2190 /*!
2191     \qmlproperty real QtQuick2::Item::childrenRect.x
2192     \qmlproperty real QtQuick2::Item::childrenRect.y
2193     \qmlproperty real QtQuick2::Item::childrenRect.width
2194     \qmlproperty real QtQuick2::Item::childrenRect.height
2195
2196     The childrenRect properties allow an item access to the geometry of its
2197     children. This property is useful if you have an item that needs to be
2198     sized to fit its children.
2199 */
2200
2201
2202 /*!
2203     \qmlproperty list<Item> QtQuick2::Item::children
2204     \qmlproperty list<Object> QtQuick2::Item::resources
2205
2206     The children property contains the list of visual children of this item.
2207     The resources property contains non-visual resources that you want to
2208     reference by name.
2209
2210     Generally you can rely on Item's default property to handle all this for
2211     you, but it can come in handy in some cases.
2212
2213     \qml
2214     Item {
2215         children: [
2216             Text {},
2217             Rectangle {}
2218         ]
2219         resources: [
2220             Component {
2221                 id: myComponent
2222                 Text {}
2223             }
2224         ]
2225     }
2226     \endqml
2227 */
2228
2229 /*!
2230     Returns true if construction of the QML component is complete; otherwise
2231     returns false.
2232
2233     It is often desirable to delay some processing until the component is
2234     completed.
2235
2236     \sa componentComplete()
2237 */
2238 bool QQuickItem::isComponentComplete() const
2239 {
2240     Q_D(const QQuickItem);
2241     return d->componentComplete;
2242 }
2243
2244 QQuickItemPrivate::QQuickItemPrivate()
2245 : _anchors(0), _contents(0), baselineOffset(0), _anchorLines(0), _stateGroup(0), origin(QQuickItem::Center),
2246
2247   flags(0), widthValid(false), heightValid(false), componentComplete(true),
2248   keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(false), focus(false), activeFocus(false), notifiedFocus(false),
2249   notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2250   effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2251   inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2252   inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
2253   staticSubtreeGeometry(false),
2254
2255   canvas(0), parentItem(0), sortedChildItems(&childItems),
2256
2257   subFocusItem(0),
2258
2259   x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2260   z(0), scale(1), rotation(0), opacity(1),
2261
2262   attachedLayoutDirection(0), acceptedMouseButtons(0),
2263   imHints(Qt::ImhMultiLine),
2264
2265   keyHandler(0),
2266
2267   dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2268
2269   itemNodeInstance(0), opacityNode(0), clipNode(0), rootNode(0), groupNode(0), paintNode(0)
2270   , beforePaintNode(0), effectRefCount(0), hideRefCount(0)
2271   , screenAttached(0)
2272 {
2273 }
2274
2275 QQuickItemPrivate::~QQuickItemPrivate()
2276 {
2277     if (sortedChildItems != &childItems)
2278         delete sortedChildItems;
2279 }
2280
2281 void QQuickItemPrivate::init(QQuickItem *parent)
2282 {
2283 #ifndef QT_NO_DEBUG
2284     ++qt_item_count;
2285     static bool atexit_registered = false;
2286     if (!atexit_registered) {
2287         atexit(qt_print_item_count);
2288         atexit_registered = true;
2289     }
2290 #endif
2291
2292     Q_Q(QQuickItem);
2293     baselineOffset.invalidate();
2294
2295     if (parent) {
2296         q->setParentItem(parent);
2297         QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
2298         setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2299     }
2300 }
2301
2302 void QQuickItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
2303 {
2304     if (!o)
2305         return;
2306
2307     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2308
2309     // This test is measurably (albeit only slightly) faster than qobject_cast<>()
2310     const QMetaObject *mo = o->metaObject();
2311     while (mo && mo != &QQuickItem::staticMetaObject) {
2312         mo = mo->d.superdata;
2313     }
2314
2315     if (mo) {
2316         QQuickItem *item = static_cast<QQuickItem *>(o);
2317         item->setParentItem(that);
2318     } else {
2319         if (o->inherits("QGraphicsItem"))
2320             qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2321
2322         // XXX todo - do we really want this behavior?
2323         o->setParent(that);
2324     }
2325 }
2326
2327 /*!
2328     \qmlproperty list<Object> QtQuick2::Item::data
2329     \default
2330
2331     The data property allows you to freely mix visual children and resources
2332     in an item.  If you assign a visual item to the data list it becomes
2333     a child and if you assign any other object type, it is added as a resource.
2334
2335     So you can write:
2336     \qml
2337     Item {
2338         Text {}
2339         Rectangle {}
2340         Timer {}
2341     }
2342     \endqml
2343
2344     instead of:
2345     \qml
2346     Item {
2347         children: [
2348             Text {},
2349             Rectangle {}
2350         ]
2351         resources: [
2352             Timer {}
2353         ]
2354     }
2355     \endqml
2356
2357     data is a behind-the-scenes property: you should never need to explicitly
2358     specify it.
2359  */
2360
2361 int QQuickItemPrivate::data_count(QDeclarativeListProperty<QObject> *prop)
2362 {
2363     Q_UNUSED(prop);
2364     // XXX todo
2365     return 0;
2366 }
2367
2368 QObject *QQuickItemPrivate::data_at(QDeclarativeListProperty<QObject> *prop, int i)
2369 {
2370     Q_UNUSED(prop);
2371     Q_UNUSED(i);
2372     // XXX todo
2373     return 0;
2374 }
2375
2376 void QQuickItemPrivate::data_clear(QDeclarativeListProperty<QObject> *prop)
2377 {
2378     Q_UNUSED(prop);
2379     // XXX todo
2380 }
2381
2382 QObject *QQuickItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop, int index)
2383 {
2384     const QObjectList children = prop->object->children();
2385     if (index < children.count())
2386         return children.at(index);
2387     else
2388         return 0;
2389 }
2390
2391 void QQuickItemPrivate::resources_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
2392 {
2393     // XXX todo - do we really want this behavior?
2394     o->setParent(prop->object);
2395 }
2396
2397 int QQuickItemPrivate::resources_count(QDeclarativeListProperty<QObject> *prop)
2398 {
2399     return prop->object->children().count();
2400 }
2401
2402 void QQuickItemPrivate::resources_clear(QDeclarativeListProperty<QObject> *prop)
2403 {
2404     // XXX todo - do we really want this behavior?
2405     const QObjectList children = prop->object->children();
2406     for (int index = 0; index < children.count(); index++)
2407         children.at(index)->setParent(0);
2408 }
2409
2410 QQuickItem *QQuickItemPrivate::children_at(QDeclarativeListProperty<QQuickItem> *prop, int index)
2411 {
2412     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2413     if (index >= p->childItems.count() || index < 0)
2414         return 0;
2415     else
2416         return p->childItems.at(index);
2417 }
2418
2419 void QQuickItemPrivate::children_append(QDeclarativeListProperty<QQuickItem> *prop, QQuickItem *o)
2420 {
2421     if (!o)
2422         return;
2423
2424     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2425     if (o->parentItem() == that)
2426         o->setParentItem(0);
2427
2428     o->setParentItem(that);
2429 }
2430
2431 int QQuickItemPrivate::children_count(QDeclarativeListProperty<QQuickItem> *prop)
2432 {
2433     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2434     return p->childItems.count();
2435 }
2436
2437 void QQuickItemPrivate::children_clear(QDeclarativeListProperty<QQuickItem> *prop)
2438 {
2439     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2440     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2441     while (!p->childItems.isEmpty())
2442         p->childItems.at(0)->setParentItem(0);
2443 }
2444
2445 int QQuickItemPrivate::transform_count(QDeclarativeListProperty<QQuickTransform> *prop)
2446 {
2447     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2448     return QQuickItemPrivate::get(that)->transforms.count();
2449 }
2450
2451 void QQuickTransform::appendToItem(QQuickItem *item)
2452 {
2453     Q_D(QQuickTransform);
2454     if (!item)
2455         return;
2456
2457     QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2458
2459     if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2460         p->transforms.removeOne(this);
2461         p->transforms.append(this);
2462     } else {
2463         p->transforms.append(this);
2464         d->items.append(item);
2465     }
2466
2467     p->dirty(QQuickItemPrivate::Transform);
2468 }
2469
2470 void QQuickTransform::prependToItem(QQuickItem *item)
2471 {
2472     Q_D(QQuickTransform);
2473     if (!item)
2474         return;
2475
2476     QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2477
2478     if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2479         p->transforms.removeOne(this);
2480         p->transforms.prepend(this);
2481     } else {
2482         p->transforms.prepend(this);
2483         d->items.append(item);
2484     }
2485
2486     p->dirty(QQuickItemPrivate::Transform);
2487 }
2488
2489 void QQuickItemPrivate::transform_append(QDeclarativeListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2490 {
2491     if (!transform)
2492         return;
2493
2494     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2495     transform->appendToItem(that);
2496 }
2497
2498 QQuickTransform *QQuickItemPrivate::transform_at(QDeclarativeListProperty<QQuickTransform> *prop, int idx)
2499 {
2500     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2501     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2502
2503     if (idx < 0 || idx >= p->transforms.count())
2504         return 0;
2505     else
2506         return p->transforms.at(idx);
2507 }
2508
2509 void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform> *prop)
2510 {
2511     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2512     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2513
2514     for (int ii = 0; ii < p->transforms.count(); ++ii) {
2515         QQuickTransform *t = p->transforms.at(ii);
2516         QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2517         tp->items.removeOne(that);
2518     }
2519
2520     p->transforms.clear();
2521
2522     p->dirty(QQuickItemPrivate::Transform);
2523 }
2524
2525 /*!
2526     \property QQuickItem::childrenRect
2527     \brief The geometry of an item's children.
2528
2529     This property holds the (collective) position and size of the item's children.
2530 */
2531
2532 /*!
2533   \qmlproperty real QtQuick2::Item::x
2534   \qmlproperty real QtQuick2::Item::y
2535   \qmlproperty real QtQuick2::Item::width
2536   \qmlproperty real QtQuick2::Item::height
2537
2538   Defines the item's position and size relative to its parent.
2539
2540   \qml
2541   Item { x: 100; y: 100; width: 100; height: 100 }
2542   \endqml
2543  */
2544
2545 /*!
2546   \qmlproperty real QtQuick2::Item::z
2547
2548   Sets the stacking order of sibling items.  By default the stacking order is 0.
2549
2550   Items with a higher stacking value are drawn on top of siblings with a
2551   lower stacking order.  Items with the same stacking value are drawn
2552   bottom up in the order they appear.  Items with a negative stacking
2553   value are drawn under their parent's content.
2554
2555   The following example shows the various effects of stacking order.
2556
2557   \table
2558   \row
2559   \o \image declarative-item_stacking1.png
2560   \o Same \c z - later children above earlier children:
2561   \qml
2562   Item {
2563       Rectangle {
2564           color: "red"
2565           width: 100; height: 100
2566       }
2567       Rectangle {
2568           color: "blue"
2569           x: 50; y: 50; width: 100; height: 100
2570       }
2571   }
2572   \endqml
2573   \row
2574   \o \image declarative-item_stacking2.png
2575   \o Higher \c z on top:
2576   \qml
2577   Item {
2578       Rectangle {
2579           z: 1
2580           color: "red"
2581           width: 100; height: 100
2582       }
2583       Rectangle {
2584           color: "blue"
2585           x: 50; y: 50; width: 100; height: 100
2586       }
2587   }
2588   \endqml
2589   \row
2590   \o \image declarative-item_stacking3.png
2591   \o Same \c z - children above parents:
2592   \qml
2593   Item {
2594       Rectangle {
2595           color: "red"
2596           width: 100; height: 100
2597           Rectangle {
2598               color: "blue"
2599               x: 50; y: 50; width: 100; height: 100
2600           }
2601       }
2602   }
2603   \endqml
2604   \row
2605   \o \image declarative-item_stacking4.png
2606   \o Lower \c z below:
2607   \qml
2608   Item {
2609       Rectangle {
2610           color: "red"
2611           width: 100; height: 100
2612           Rectangle {
2613               z: -1
2614               color: "blue"
2615               x: 50; y: 50; width: 100; height: 100
2616           }
2617       }
2618   }
2619   \endqml
2620   \endtable
2621  */
2622
2623 /*!
2624     \qmlproperty bool QtQuick2::Item::visible
2625
2626     This property holds whether the item is visible. By default this is true.
2627
2628     Setting this property directly affects the \c visible value of child
2629     items. When set to \c false, the \c visible values of all child items also
2630     become \c false. When set to \c true, the \c visible values of child items
2631     are returned to \c true, unless they have explicitly been set to \c false.
2632
2633     (Because of this flow-on behavior, using the \c visible property may not
2634     have the intended effect if a property binding should only respond to
2635     explicit property changes. In such cases it may be better to use the
2636     \l opacity property instead.)
2637
2638     Setting this property to \c false automatically causes \l focus to be set
2639     to \c false, and this item will longer receive mouse and keyboard events.
2640     (In contrast, setting the \l opacity to 0 does not affect the \l focus
2641     property and the receiving of key events.)
2642
2643     \note This property's value is only affected by changes to this property or
2644     the parent's \c visible property. It does not change, for example, if this
2645     item moves off-screen, or if the \l opacity changes to 0.
2646 */
2647
2648
2649 /*!
2650   \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2651   \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2652   \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2653   \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2654   \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2655   \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2656   \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2657
2658   \qmlproperty Item QtQuick2::Item::anchors.fill
2659   \qmlproperty Item QtQuick2::Item::anchors.centerIn
2660
2661   \qmlproperty real QtQuick2::Item::anchors.margins
2662   \qmlproperty real QtQuick2::Item::anchors.topMargin
2663   \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2664   \qmlproperty real QtQuick2::Item::anchors.leftMargin
2665   \qmlproperty real QtQuick2::Item::anchors.rightMargin
2666   \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2667   \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2668   \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2669
2670   \qmlproperty bool QtQuick2::Item::anchors.mirrored
2671
2672   Anchors provide a way to position an item by specifying its
2673   relationship with other items.
2674
2675   Margins apply to top, bottom, left, right, and fill anchors.
2676   The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2677   Note that margins are anchor-specific and are not applied if an item does not
2678   use anchors.
2679
2680   Offsets apply for horizontal center, vertical center, and baseline anchors.
2681
2682   \table
2683   \row
2684   \o \image declarative-anchors_example.png
2685   \o Text anchored to Image, horizontally centered and vertically below, with a margin.
2686   \qml
2687   Item {
2688       Image {
2689           id: pic
2690           // ...
2691       }
2692       Text {
2693           id: label
2694           anchors.horizontalCenter: pic.horizontalCenter
2695           anchors.top: pic.bottom
2696           anchors.topMargin: 5
2697           // ...
2698       }
2699   }
2700   \endqml
2701   \row
2702   \o \image declarative-anchors_example2.png
2703   \o
2704   Left of Text anchored to right of Image, with a margin. The y
2705   property of both defaults to 0.
2706
2707   \qml
2708   Item {
2709       Image {
2710           id: pic
2711           // ...
2712       }
2713       Text {
2714           id: label
2715           anchors.left: pic.right
2716           anchors.leftMargin: 5
2717           // ...
2718       }
2719   }
2720   \endqml
2721   \endtable
2722
2723   \c anchors.fill provides a convenient way for one item to have the
2724   same geometry as another item, and is equivalent to connecting all
2725   four directional anchors.
2726
2727   To clear an anchor value, set it to \c undefined.
2728
2729   \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2730
2731   \note You can only anchor an item to siblings or a parent.
2732
2733   For more information see \l {anchor-layout}{Anchor Layouts}.
2734 */
2735
2736 /*!
2737   \property QQuickItem::baselineOffset
2738   \brief The position of the item's baseline in local coordinates.
2739
2740   The baseline of a \l Text item is the imaginary line on which the text
2741   sits. Controls containing text usually set their baseline to the
2742   baseline of their text.
2743
2744   For non-text items, a default baseline offset of 0 is used.
2745 */
2746 QQuickAnchors *QQuickItemPrivate::anchors() const
2747 {
2748     if (!_anchors) {
2749         Q_Q(const QQuickItem);
2750         _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2751         if (!componentComplete)
2752             _anchors->classBegin();
2753     }
2754     return _anchors;
2755 }
2756
2757 QQuickItemPrivate::AnchorLines *QQuickItemPrivate::anchorLines() const
2758 {
2759     Q_Q(const QQuickItem);
2760     if (!_anchorLines) _anchorLines =
2761         new AnchorLines(const_cast<QQuickItem *>(q));
2762     return _anchorLines;
2763 }
2764
2765 void QQuickItemPrivate::siblingOrderChanged()
2766 {
2767     Q_Q(QQuickItem);
2768     for (int ii = 0; ii < changeListeners.count(); ++ii) {
2769         const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2770         if (change.types & QQuickItemPrivate::SiblingOrder) {
2771             change.listener->itemSiblingOrderChanged(q);
2772         }
2773     }
2774 }
2775
2776 QDeclarativeListProperty<QObject> QQuickItemPrivate::data()
2777 {
2778     return QDeclarativeListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
2779                                              QQuickItemPrivate::data_count,
2780                                              QQuickItemPrivate::data_at,
2781                                              QQuickItemPrivate::data_clear);
2782 }
2783
2784 QRectF QQuickItem::childrenRect()
2785 {
2786     Q_D(QQuickItem);
2787     if (!d->_contents) {
2788         d->_contents = new QQuickContents(this);
2789         if (d->componentComplete)
2790             d->_contents->complete();
2791     }
2792     return d->_contents->rectF();
2793 }
2794
2795 QList<QQuickItem *> QQuickItem::childItems() const
2796 {
2797     Q_D(const QQuickItem);
2798     return d->childItems;
2799 }
2800
2801 bool QQuickItem::clip() const
2802 {
2803     return flags() & ItemClipsChildrenToShape;
2804 }
2805
2806 void QQuickItem::setClip(bool c)
2807 {
2808     if (clip() == c)
2809         return;
2810
2811     setFlag(ItemClipsChildrenToShape, c);
2812
2813     emit clipChanged(c);
2814 }
2815
2816
2817 /*!
2818   This function is called to handle this item's changes in
2819   geometry from \a oldGeometry to \a newGeometry. If the two
2820   geometries are the same, it doesn't do anything.
2821  */
2822 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
2823 {
2824     Q_D(QQuickItem);
2825
2826     if (d->_anchors)
2827         QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
2828
2829     bool xChange = (newGeometry.x() != oldGeometry.x());
2830     bool yChange = (newGeometry.y() != oldGeometry.y());
2831     bool widthChange = (newGeometry.width() != oldGeometry.width());
2832     bool heightChange = (newGeometry.height() != oldGeometry.height());
2833
2834     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
2835         const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
2836         if (change.types & QQuickItemPrivate::Geometry) {
2837             if (change.gTypes == QQuickItemPrivate::GeometryChange) {
2838                 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
2839             } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
2840                        (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
2841                        (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
2842                        (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
2843                 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
2844             }
2845         }
2846     }
2847
2848     if (xChange)
2849         emit xChanged();
2850     if (yChange)
2851         emit yChanged();
2852     if (widthChange)
2853         emit widthChanged();
2854     if (heightChange)
2855         emit heightChanged();
2856 }
2857
2858 /*!
2859     Called by the rendering thread when it is time to sync the state of the QML objects with the
2860     scene graph objects. The function should return the root of the scene graph subtree for
2861     this item. \a oldNode is the node that was returned the last time the function was called.
2862
2863     The main thread is blocked while this function is executed so it is safe to read
2864     values from the QQuickItem instance and other objects in the main thread.
2865
2866     \warning This is the only function in which it is allowed to make use of scene graph
2867     objects from the main thread. Use of scene graph objects outside this function will
2868     result in race conditions and potential crashes.
2869  */
2870
2871 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
2872 {
2873     delete oldNode;
2874     return 0;
2875 }
2876
2877 QSGTransformNode *QQuickItemPrivate::createTransformNode()
2878 {
2879     return new QSGTransformNode;
2880 }
2881
2882 void QQuickItem::updatePolish()
2883 {
2884 }
2885
2886 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
2887 {
2888     ChangeListener change(listener, types);
2889     changeListeners.removeOne(change);
2890 }
2891
2892 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
2893 {
2894     ChangeListener change(listener, types);
2895     int index = changeListeners.find(change);
2896     if (index > -1)
2897         changeListeners[index].gTypes = change.gTypes;  //we may have different GeometryChangeTypes
2898     else
2899         changeListeners.append(change);
2900 }
2901
2902 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
2903 {
2904     ChangeListener change(listener, types);
2905     if (types == NoChange) {
2906         changeListeners.removeOne(change);
2907     } else {
2908         int index = changeListeners.find(change);
2909         if (index > -1)
2910             changeListeners[index].gTypes = change.gTypes;  //we may have different GeometryChangeTypes
2911     }
2912 }
2913
2914 void QQuickItem::keyPressEvent(QKeyEvent *event)
2915 {
2916     event->ignore();
2917 }
2918
2919 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
2920 {
2921     event->ignore();
2922 }
2923
2924 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
2925 {
2926     event->ignore();
2927 }
2928
2929 void QQuickItem::focusInEvent(QFocusEvent *)
2930 {
2931 }
2932
2933 void QQuickItem::focusOutEvent(QFocusEvent *)
2934 {
2935 }
2936
2937 void QQuickItem::mousePressEvent(QMouseEvent *event)
2938 {
2939     event->ignore();
2940 }
2941
2942 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
2943 {
2944     event->ignore();
2945 }
2946
2947 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
2948 {
2949     event->ignore();
2950 }
2951
2952 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *event)
2953 {
2954     mousePressEvent(event);
2955 }
2956
2957 void QQuickItem::mouseUngrabEvent()
2958 {
2959     // XXX todo
2960 }
2961
2962 void QQuickItem::touchUngrabEvent()
2963 {
2964     // XXX todo
2965 }
2966
2967 void QQuickItem::wheelEvent(QWheelEvent *event)
2968 {
2969     event->ignore();
2970 }
2971
2972 void QQuickItem::touchEvent(QTouchEvent *event)
2973 {
2974     event->ignore();
2975 }
2976
2977 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
2978 {
2979     Q_UNUSED(event);
2980 }
2981
2982 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
2983 {
2984     Q_UNUSED(event);
2985 }
2986
2987 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
2988 {
2989     Q_UNUSED(event);
2990 }
2991
2992 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
2993 {
2994     Q_UNUSED(event);
2995 }
2996
2997 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
2998 {
2999
3000     Q_UNUSED(event);
3001 }
3002
3003 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3004 {
3005
3006     Q_UNUSED(event);
3007 }
3008
3009 void QQuickItem::dropEvent(QDropEvent *event)
3010 {
3011     Q_UNUSED(event);
3012 }
3013
3014 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3015 {
3016     return false;
3017 }
3018
3019 void QQuickItem::windowDeactivateEvent()
3020 {
3021     foreach (QQuickItem* item, childItems()) {
3022         item->windowDeactivateEvent();
3023     }
3024 }
3025
3026 Qt::InputMethodHints QQuickItem::inputMethodHints() const
3027 {
3028     Q_D(const QQuickItem);
3029     return d->imHints;
3030 }
3031
3032 void QQuickItem::setInputMethodHints(Qt::InputMethodHints hints)
3033 {
3034     Q_D(QQuickItem);
3035     d->imHints = hints;
3036
3037     if (!d->canvas || d->canvas->activeFocusItem() != this)
3038         return;
3039
3040     QInputPanel *p = qApp->inputPanel();
3041     if (p->inputItem() == this)
3042         qApp->inputPanel()->update(Qt::ImHints);
3043 }
3044
3045 void QQuickItem::updateMicroFocus()
3046 {
3047     QInputPanel *p = qApp->inputPanel();
3048     if (p->inputItem() == this)
3049         qApp->inputPanel()->update(Qt::ImQueryInput);
3050 }
3051
3052 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3053 {
3054     Q_D(const QQuickItem);
3055     QVariant v;
3056
3057     switch (query) {
3058     case Qt::ImEnabled:
3059         v = (bool)(flags() & ItemAcceptsInputMethod);
3060         break;
3061     case Qt::ImHints:
3062         v = (int)inputMethodHints();
3063         break;
3064     case Qt::ImCursorRectangle:
3065     case Qt::ImFont:
3066     case Qt::ImCursorPosition:
3067     case Qt::ImSurroundingText:
3068     case Qt::ImCurrentSelection:
3069     case Qt::ImMaximumTextLength:
3070     case Qt::ImAnchorPosition:
3071     case Qt::ImPreferredLanguage:
3072         if (d->keyHandler)
3073             v = d->keyHandler->inputMethodQuery(query);
3074     default:
3075         break;
3076     }
3077
3078     return v;
3079 }
3080
3081 QQuickAnchorLine QQuickItemPrivate::left() const
3082 {
3083     return anchorLines()->left;
3084 }
3085
3086 QQuickAnchorLine QQuickItemPrivate::right() const
3087 {
3088     return anchorLines()->right;
3089 }
3090
3091 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3092 {
3093     return anchorLines()->hCenter;
3094 }
3095
3096 QQuickAnchorLine QQuickItemPrivate::top() const
3097 {
3098     return anchorLines()->top;
3099 }
3100
3101 QQuickAnchorLine QQuickItemPrivate::bottom() const
3102 {
3103     return anchorLines()->bottom;
3104 }
3105
3106 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3107 {
3108     return anchorLines()->vCenter;
3109 }
3110
3111 QQuickAnchorLine QQuickItemPrivate::baseline() const
3112 {
3113     return anchorLines()->baseline;
3114 }
3115
3116 qreal QQuickItem::baselineOffset() const
3117 {
3118     Q_D(const QQuickItem);
3119     if (!d->baselineOffset.isValid()) {
3120         return 0.0;
3121     } else
3122         return d->baselineOffset;
3123 }
3124
3125 void QQuickItem::setBaselineOffset(qreal offset)
3126 {
3127     Q_D(QQuickItem);
3128     if (offset == d->baselineOffset)
3129         return;
3130
3131     d->baselineOffset = offset;
3132
3133     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3134         const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3135         if (change.types & QQuickItemPrivate::Geometry) {
3136             QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3137             if (anchor)
3138                 anchor->updateVerticalAnchors();
3139         }
3140     }
3141     emit baselineOffsetChanged(offset);
3142 }
3143
3144 void QQuickItem::update()
3145 {
3146     Q_D(QQuickItem);
3147     Q_ASSERT(flags() & ItemHasContents);
3148     d->dirty(QQuickItemPrivate::Content);
3149 }
3150
3151 void QQuickItem::polish()
3152 {
3153     Q_D(QQuickItem);
3154     if (!d->polishScheduled) {
3155         d->polishScheduled = true;
3156         if (d->canvas) {
3157             QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
3158             bool maybeupdate = p->itemsToPolish.isEmpty();
3159             p->itemsToPolish.insert(this);
3160             if (maybeupdate) d->canvas->maybeUpdate();
3161         }
3162     }
3163 }
3164
3165 void QQuickItem::mapFromItem(QDeclarativeV8Function *args) const
3166 {
3167     if (args->Length() != 0) {
3168         v8::Local<v8::Value> item = (*args)[0];
3169         QV8Engine *engine = args->engine();
3170
3171         QQuickItem *itemObj = 0;
3172         if (!item->IsNull())
3173             itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3174
3175         if (!itemObj && !item->IsNull()) {
3176             qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3177                           << "\" which is neither null nor an Item";
3178             return;
3179         }
3180
3181         v8::Local<v8::Object> rv = v8::Object::New();
3182         args->returnValue(rv);
3183
3184         qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3185         qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3186
3187         QPointF p = mapFromItem(itemObj, QPointF(x, y));
3188
3189         rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3190         rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3191     }
3192 }
3193
3194 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3195 {
3196     Q_D(const QQuickItem);
3197
3198     // XXX todo - we need to be able to handle common parents better and detect
3199     // invalid cases
3200     if (ok) *ok = true;
3201
3202     QTransform t = d->itemToCanvasTransform();
3203     if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
3204
3205     return t;
3206 }
3207
3208 void QQuickItem::mapToItem(QDeclarativeV8Function *args) const
3209 {
3210     if (args->Length() != 0) {
3211         v8::Local<v8::Value> item = (*args)[0];
3212         QV8Engine *engine = args->engine();
3213
3214         QQuickItem *itemObj = 0;
3215         if (!item->IsNull())
3216             itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3217
3218         if (!itemObj && !item->IsNull()) {
3219             qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3220                           << "\" which is neither null nor an Item";
3221             return;
3222         }
3223
3224         v8::Local<v8::Object> rv = v8::Object::New();
3225         args->returnValue(rv);
3226
3227         qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3228         qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3229
3230         QPointF p = mapToItem(itemObj, QPointF(x, y));
3231
3232         rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3233         rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3234     }
3235 }
3236
3237 void QQuickItem::forceActiveFocus()
3238 {
3239     setFocus(true);
3240     QQuickItem *parent = parentItem();
3241     while (parent) {
3242         if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3243             parent->setFocus(true);
3244         }
3245         parent = parent->parentItem();
3246     }
3247 }
3248
3249 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3250 {
3251     // XXX todo - should this include transform etc.?
3252     const QList<QQuickItem *> children = childItems();
3253     for (int i = children.count()-1; i >= 0; --i) {
3254         QQuickItem *child = children.at(i);
3255         if (child->isVisible() && child->x() <= x
3256                 && child->x() + child->width() >= x
3257                 && child->y() <= y
3258                 && child->y() + child->height() >= y)
3259             return child;
3260     }
3261     return 0;
3262 }
3263
3264 QDeclarativeListProperty<QObject> QQuickItemPrivate::resources()
3265 {
3266     return QDeclarativeListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3267                                              QQuickItemPrivate::resources_count,
3268                                              QQuickItemPrivate::resources_at,
3269                                              QQuickItemPrivate::resources_clear);
3270 }
3271
3272 QDeclarativeListProperty<QQuickItem> QQuickItemPrivate::children()
3273 {
3274     return QDeclarativeListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3275                                              QQuickItemPrivate::children_count,
3276                                              QQuickItemPrivate::children_at,
3277                                              QQuickItemPrivate::children_clear);
3278
3279 }
3280
3281 QDeclarativeListProperty<QDeclarativeState> QQuickItemPrivate::states()
3282 {
3283     return _states()->statesProperty();
3284 }
3285
3286 QDeclarativeListProperty<QDeclarativeTransition> QQuickItemPrivate::transitions()
3287 {
3288     return _states()->transitionsProperty();
3289 }
3290
3291 QString QQuickItemPrivate::state() const
3292 {
3293     if (!_stateGroup)
3294         return QString();
3295     else
3296         return _stateGroup->state();
3297 }
3298
3299 void QQuickItemPrivate::setState(const QString &state)
3300 {
3301     _states()->setState(state);
3302 }
3303
3304 QString QQuickItem::state() const
3305 {
3306     Q_D(const QQuickItem);
3307     return d->state();
3308 }
3309
3310 void QQuickItem::setState(const QString &state)
3311 {
3312     Q_D(QQuickItem);
3313     d->setState(state);
3314 }
3315
3316 QDeclarativeListProperty<QQuickTransform> QQuickItem::transform()
3317 {
3318     return QDeclarativeListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3319                                                      QQuickItemPrivate::transform_count,
3320                                                      QQuickItemPrivate::transform_at,
3321                                                      QQuickItemPrivate::transform_clear);
3322 }
3323
3324 void QQuickItem::classBegin()
3325 {
3326     Q_D(QQuickItem);
3327     d->componentComplete = false;
3328     if (d->_stateGroup)
3329         d->_stateGroup->classBegin();
3330     if (d->_anchors)
3331         d->_anchors->classBegin();
3332 }
3333
3334 void QQuickItem::componentComplete()
3335 {
3336     Q_D(QQuickItem);
3337     d->componentComplete = true;
3338     if (d->_stateGroup)
3339         d->_stateGroup->componentComplete();
3340     if (d->_anchors) {
3341         d->_anchors->componentComplete();
3342         QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3343     }
3344     if (d->keyHandler)
3345         d->keyHandler->componentComplete();
3346     if (d->_contents)
3347         d->_contents->complete();
3348 }
3349
3350 QDeclarativeStateGroup *QQuickItemPrivate::_states()
3351 {
3352     Q_Q(QQuickItem);
3353     if (!_stateGroup) {
3354         _stateGroup = new QDeclarativeStateGroup;
3355         if (!componentComplete)
3356             _stateGroup->classBegin();
3357         FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)),
3358                      q, SIGNAL(stateChanged(QString)))
3359     }
3360
3361     return _stateGroup;
3362 }
3363
3364 QQuickItemPrivate::AnchorLines::AnchorLines(QQuickItem *q)
3365 {
3366     left.item = q;
3367     left.anchorLine = QQuickAnchorLine::Left;
3368     right.item = q;
3369     right.anchorLine = QQuickAnchorLine::Right;
3370     hCenter.item = q;
3371     hCenter.anchorLine = QQuickAnchorLine::HCenter;
3372     top.item = q;
3373     top.anchorLine = QQuickAnchorLine::Top;
3374     bottom.item = q;
3375     bottom.anchorLine = QQuickAnchorLine::Bottom;
3376     vCenter.item = q;
3377     vCenter.anchorLine = QQuickAnchorLine::VCenter;
3378     baseline.item = q;
3379     baseline.anchorLine = QQuickAnchorLine::Baseline;
3380 }
3381
3382 QPointF QQuickItemPrivate::computeTransformOrigin() const
3383 {
3384     switch (origin) {
3385     default:
3386     case QQuickItem::TopLeft:
3387         return QPointF(0, 0);
3388     case QQuickItem::Top:
3389         return QPointF(width / 2., 0);
3390     case QQuickItem::TopRight:
3391         return QPointF(width, 0);
3392     case QQuickItem::Left:
3393         return QPointF(0, height / 2.);
3394     case QQuickItem::Center:
3395         return QPointF(width / 2., height / 2.);
3396     case QQuickItem::Right:
3397         return QPointF(width, height / 2.);
3398     case QQuickItem::BottomLeft:
3399         return QPointF(0, height);
3400     case QQuickItem::Bottom:
3401         return QPointF(width / 2., height);
3402     case QQuickItem::BottomRight:
3403         return QPointF(width, height);
3404     }
3405 }
3406
3407 void QQuickItemPrivate::transformChanged()
3408 {
3409 }
3410
3411 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3412 {
3413     Q_Q(QQuickItem);
3414
3415     Q_ASSERT(e->isAccepted());
3416     if (keyHandler) {
3417         if (e->type() == QEvent::KeyPress)
3418             keyHandler->keyPressed(e, false);
3419         else
3420             keyHandler->keyReleased(e, false);
3421
3422         if (e->isAccepted())
3423             return;
3424         else
3425             e->accept();
3426     }
3427
3428     if (e->type() == QEvent::KeyPress)
3429         q->keyPressEvent(e);
3430     else
3431         q->keyReleaseEvent(e);
3432
3433     if (e->isAccepted())
3434         return;
3435
3436     if (keyHandler) {
3437         e->accept();
3438
3439         if (e->type() == QEvent::KeyPress)
3440             keyHandler->keyPressed(e, true);
3441         else
3442             keyHandler->keyReleased(e, true);
3443     }
3444 }
3445
3446 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3447 {
3448     Q_Q(QQuickItem);
3449
3450     Q_ASSERT(e->isAccepted());
3451     if (keyHandler) {
3452         keyHandler->inputMethodEvent(e, false);
3453
3454         if (e->isAccepted())
3455             return;
3456         else
3457             e->accept();
3458     }
3459
3460     q->inputMethodEvent(e);
3461
3462     if (e->isAccepted())
3463         return;
3464
3465     if (keyHandler) {
3466         e->accept();
3467
3468         keyHandler->inputMethodEvent(e, true);
3469     }
3470 }
3471
3472 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3473 {
3474     Q_Q(QQuickItem);
3475
3476     if (e->type() == QEvent::FocusIn) {
3477         q->focusInEvent(e);
3478     } else {
3479         q->focusOutEvent(e);
3480     }
3481 }
3482
3483 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3484 {
3485     Q_Q(QQuickItem);
3486
3487     Q_ASSERT(e->isAccepted());
3488
3489     switch (e->type()) {
3490     default:
3491         Q_ASSERT(!"Unknown event type");
3492     case QEvent::MouseMove:
3493         q->mouseMoveEvent(e);
3494         break;
3495     case QEvent::MouseButtonPress:
3496         q->mousePressEvent(e);
3497         break;
3498     case QEvent::MouseButtonRelease:
3499         q->mouseReleaseEvent(e);
3500         break;
3501     case QEvent::MouseButtonDblClick:
3502         q->mouseDoubleClickEvent(e);
3503         break;
3504     }
3505 }
3506
3507 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3508 {
3509     Q_Q(QQuickItem);
3510     q->wheelEvent(e);
3511 }
3512
3513 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3514 {
3515     Q_Q(QQuickItem);
3516     q->touchEvent(e);
3517 }
3518
3519 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3520 {
3521     Q_Q(QQuickItem);
3522     switch (e->type()) {
3523     default:
3524         Q_ASSERT(!"Unknown event type");
3525     case QEvent::HoverEnter:
3526         q->hoverEnterEvent(e);
3527         break;
3528     case QEvent::HoverLeave:
3529         q->hoverLeaveEvent(e);
3530         break;
3531     case QEvent::HoverMove:
3532         q->hoverMoveEvent(e);
3533         break;
3534     }
3535 }
3536
3537 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3538 {
3539     Q_Q(QQuickItem);
3540     switch (e->type()) {
3541     default:
3542         Q_ASSERT(!"Unknown event type");
3543     case QEvent::DragEnter:
3544         q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3545         break;
3546     case QEvent::DragLeave:
3547         q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3548         break;
3549     case QEvent::DragMove:
3550         q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3551         break;
3552     case QEvent::Drop:
3553         q->dropEvent(static_cast<QDropEvent *>(e));
3554         break;
3555     }
3556 }
3557
3558 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3559 {
3560     Q_UNUSED(change);
3561     Q_UNUSED(value);
3562 }
3563
3564 /*! \internal */
3565 // XXX todo - do we want/need this anymore?
3566 // Note that it's now used for varying clip rect
3567 QRectF QQuickItem::boundingRect() const
3568 {
3569     Q_D(const QQuickItem);
3570     return QRectF(0, 0, d->width, d->height);
3571 }
3572
3573 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3574 {
3575     Q_D(const QQuickItem);
3576     return d->origin;
3577 }
3578
3579 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3580 {
3581     Q_D(QQuickItem);
3582     if (origin == d->origin)
3583         return;
3584
3585     d->origin = origin;
3586     d->dirty(QQuickItemPrivate::TransformOrigin);
3587
3588     emit transformOriginChanged(d->origin);
3589 }
3590
3591 QPointF QQuickItem::transformOriginPoint() const
3592 {
3593     Q_D(const QQuickItem);
3594     if (!d->transformOriginPoint.isNull())
3595         return d->transformOriginPoint;
3596     return d->computeTransformOrigin();
3597 }
3598
3599 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3600 {
3601     Q_D(QQuickItem);
3602     if (d->transformOriginPoint == point)
3603         return;
3604
3605     d->transformOriginPoint = point;
3606     d->dirty(QQuickItemPrivate::TransformOrigin);
3607 }
3608
3609 qreal QQuickItem::z() const
3610 {
3611     Q_D(const QQuickItem);
3612     return d->z;
3613 }
3614
3615 void QQuickItem::setZ(qreal v)
3616 {
3617     Q_D(QQuickItem);
3618     if (d->z == v)
3619         return;
3620
3621     d->z = v;
3622
3623     d->dirty(QQuickItemPrivate::ZValue);
3624     if (d->parentItem) {
3625         QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3626         QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3627     }
3628
3629     emit zChanged();
3630 }
3631
3632
3633 /*!
3634   \qmlproperty real QtQuick2::Item::rotation
3635   This property holds the rotation of the item in degrees clockwise.
3636
3637   This specifies how many degrees to rotate the item around its transformOrigin.
3638   The default rotation is 0 degrees (i.e. not rotated at all).
3639
3640   \table
3641   \row
3642   \o \image declarative-rotation.png
3643   \o
3644   \qml
3645   Rectangle {
3646       color: "blue"
3647       width: 100; height: 100
3648       Rectangle {
3649           color: "red"
3650           x: 25; y: 25; width: 50; height: 50
3651           rotation: 30
3652       }
3653   }
3654   \endqml
3655   \endtable
3656
3657   \sa transform, Rotation
3658 */
3659
3660 /*!
3661   \qmlproperty real QtQuick2::Item::scale
3662   This property holds the scale of the item.
3663
3664   A scale of less than 1 means the item will be displayed smaller than
3665   normal, and a scale of greater than 1 means the item will be
3666   displayed larger than normal.  A negative scale means the item will
3667   be mirrored.
3668
3669   By default, items are displayed at a scale of 1 (i.e. at their
3670   normal size).
3671
3672   Scaling is from the item's transformOrigin.
3673
3674   \table
3675   \row
3676   \o \image declarative-scale.png
3677   \o
3678   \qml
3679   Rectangle {
3680       color: "blue"
3681       width: 100; height: 100
3682       Rectangle {
3683           color: "green"
3684           width: 25; height: 25
3685       }
3686       Rectangle {
3687           color: "red"
3688           x: 25; y: 25; width: 50; height: 50
3689           scale: 1.4
3690       }
3691   }
3692   \endqml
3693   \endtable
3694
3695   \sa transform, Scale
3696 */
3697
3698 /*!
3699   \qmlproperty real QtQuick2::Item::opacity
3700
3701   This property holds the opacity of the item.  Opacity is specified as a
3702   number between 0 (fully transparent) and 1 (fully opaque).  The default is 1.
3703
3704   When this property is set, the specified opacity is also applied
3705   individually to child items.  In almost all cases this is what you want,
3706   but in some cases it may produce undesired results. For example in the
3707   second set of rectangles below, the red rectangle has specified an opacity
3708   of 0.5, which affects the opacity of its blue child rectangle even though
3709   the child has not specified an opacity.
3710
3711   \table
3712   \row
3713   \o \image declarative-item_opacity1.png
3714   \o
3715   \qml
3716     Item {
3717         Rectangle {
3718             color: "red"
3719             width: 100; height: 100
3720             Rectangle {
3721                 color: "blue"
3722                 x: 50; y: 50; width: 100; height: 100
3723             }
3724         }
3725     }
3726   \endqml
3727   \row
3728   \o \image declarative-item_opacity2.png
3729   \o
3730   \qml
3731     Item {
3732         Rectangle {
3733             opacity: 0.5
3734             color: "red"
3735             width: 100; height: 100
3736             Rectangle {
3737                 color: "blue"
3738                 x: 50; y: 50; width: 100; height: 100
3739             }
3740         }
3741     }
3742   \endqml
3743   \endtable
3744
3745   If an item's opacity is set to 0, the item will no longer receive mouse
3746   events, but will continue to receive key events and will retain the keyboard
3747   \l focus if it has been set. (In contrast, setting the \l visible property
3748   to \c false stops both mouse and keyboard events, and also removes focus
3749   from the item.)
3750 */
3751
3752 /*!
3753   Returns a value indicating whether mouse input should
3754   remain with this item exclusively.
3755
3756   \sa setKeepMouseGrab()
3757  */
3758
3759 qreal QQuickItem::rotation() const
3760 {
3761     Q_D(const QQuickItem);
3762     return d->rotation;
3763 }
3764
3765 void QQuickItem::setRotation(qreal r)
3766 {
3767     Q_D(QQuickItem);
3768     if (d->rotation == r)
3769         return;
3770
3771     d->rotation = r;
3772
3773     d->dirty(QQuickItemPrivate::BasicTransform);
3774
3775     d->itemChange(ItemRotationHasChanged, r);
3776
3777     emit rotationChanged();
3778 }
3779
3780 qreal QQuickItem::scale() const
3781 {
3782     Q_D(const QQuickItem);
3783     return d->scale;
3784 }
3785
3786 void QQuickItem::setScale(qreal s)
3787 {
3788     Q_D(QQuickItem);
3789     if (d->scale == s)
3790         return;
3791
3792     d->scale = s;
3793
3794     d->dirty(QQuickItemPrivate::BasicTransform);
3795
3796     emit scaleChanged();
3797 }
3798
3799 qreal QQuickItem::opacity() const
3800 {
3801     Q_D(const QQuickItem);
3802     return d->opacity;
3803 }
3804
3805 void QQuickItem::setOpacity(qreal o)
3806 {
3807     Q_D(QQuickItem);
3808     if (d->opacity == o)
3809         return;
3810
3811     d->opacity = o;
3812
3813     d->dirty(QQuickItemPrivate::OpacityValue);
3814
3815     d->itemChange(ItemOpacityHasChanged, o);
3816
3817     emit opacityChanged();
3818 }
3819
3820 bool QQuickItem::isVisible() const
3821 {
3822     Q_D(const QQuickItem);
3823     return d->effectiveVisible;
3824 }
3825
3826 void QQuickItem::setVisible(bool v)
3827 {
3828     Q_D(QQuickItem);
3829     if (v == d->explicitVisible)
3830         return;
3831
3832     d->explicitVisible = v;
3833
3834     d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
3835 }
3836
3837 bool QQuickItem::isEnabled() const
3838 {
3839     Q_D(const QQuickItem);
3840     return d->effectiveEnable;
3841 }
3842
3843 void QQuickItem::setEnabled(bool e)
3844 {
3845     Q_D(QQuickItem);
3846     if (e == d->explicitEnable)
3847         return;
3848
3849     d->explicitEnable = e;
3850
3851     d->setEffectiveEnableRecur(d->calcEffectiveEnable());
3852 }
3853
3854 bool QQuickItemPrivate::calcEffectiveVisible() const
3855 {
3856     // XXX todo - Should the effective visible of an element with no parent just be the current
3857     // effective visible?  This would prevent pointless re-processing in the case of an element
3858     // moving to/from a no-parent situation, but it is different from what graphics view does.
3859     return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
3860 }
3861
3862 void QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
3863 {
3864     Q_Q(QQuickItem);
3865
3866     if (newEffectiveVisible && !explicitVisible) {
3867         // This item locally overrides visibility
3868         return;
3869     }
3870
3871     if (newEffectiveVisible == effectiveVisible) {
3872         // No change necessary
3873         return;
3874     }
3875
3876     effectiveVisible = newEffectiveVisible;
3877     dirty(Visible);
3878     if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
3879
3880     if (canvas) {
3881         QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
3882         if (canvasPriv->mouseGrabberItem == q)
3883             q->ungrabMouse();
3884     }
3885
3886     for (int ii = 0; ii < childItems.count(); ++ii)
3887         QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
3888
3889     for (int ii = 0; ii < changeListeners.count(); ++ii) {
3890         const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
3891         if (change.types & QQuickItemPrivate::Visibility)
3892             change.listener->itemVisibilityChanged(q);
3893     }
3894
3895     emit q->visibleChanged();
3896 }
3897
3898 bool QQuickItemPrivate::calcEffectiveEnable() const
3899 {
3900     // XXX todo - Should the effective enable of an element with no parent just be the current
3901     // effective enable?  This would prevent pointless re-processing in the case of an element
3902     // moving to/from a no-parent situation, but it is different from what graphics view does.
3903     return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
3904 }
3905
3906 void QQuickItemPrivate::setEffectiveEnableRecur(bool newEffectiveEnable)
3907 {
3908     Q_Q(QQuickItem);
3909
3910     // XXX todo - need to fixup focus
3911
3912     if (newEffectiveEnable && !explicitEnable) {
3913         // This item locally overrides enable
3914         return;
3915     }
3916
3917     if (newEffectiveEnable == effectiveEnable) {
3918         // No change necessary
3919         return;
3920     }
3921
3922     effectiveEnable = newEffectiveEnable;
3923
3924     if (canvas) {
3925         QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
3926         if (canvasPriv->mouseGrabberItem == q)
3927             q->ungrabMouse();
3928     }
3929
3930     for (int ii = 0; ii < childItems.count(); ++ii)
3931         QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(newEffectiveEnable);
3932
3933     emit q->enabledChanged();
3934 }
3935
3936 QString QQuickItemPrivate::dirtyToString() const
3937 {
3938 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
3939     if (!rv.isEmpty()) \
3940         rv.append(QLatin1String("|")); \
3941     rv.append(QLatin1String(#value)); \
3942 }
3943
3944 //    QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
3945     QString rv;
3946
3947     DIRTY_TO_STRING(TransformOrigin);
3948     DIRTY_TO_STRING(Transform);
3949     DIRTY_TO_STRING(BasicTransform);
3950     DIRTY_TO_STRING(Position);
3951     DIRTY_TO_STRING(Size);
3952     DIRTY_TO_STRING(ZValue);
3953     DIRTY_TO_STRING(Content);
3954     DIRTY_TO_STRING(Smooth);
3955     DIRTY_TO_STRING(OpacityValue);
3956     DIRTY_TO_STRING(ChildrenChanged);
3957     DIRTY_TO_STRING(ChildrenStackingChanged);
3958     DIRTY_TO_STRING(ParentChanged);
3959     DIRTY_TO_STRING(Clip);
3960     DIRTY_TO_STRING(Canvas);
3961     DIRTY_TO_STRING(EffectReference);
3962     DIRTY_TO_STRING(Visible);
3963     DIRTY_TO_STRING(HideReference);
3964     DIRTY_TO_STRING(PerformanceHints);
3965
3966     return rv;
3967 }
3968
3969 void QQuickItemPrivate::dirty(DirtyType type)
3970 {
3971     Q_Q(QQuickItem);
3972     if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
3973         transformChanged();
3974
3975     if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
3976         dirtyAttributes |= type;
3977         if (canvas) {
3978             addToDirtyList();
3979             QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
3980         }
3981     }
3982 }
3983
3984 void QQuickItemPrivate::addToDirtyList()
3985 {
3986     Q_Q(QQuickItem);
3987
3988     Q_ASSERT(canvas);
3989     if (!prevDirtyItem) {
3990         Q_ASSERT(!nextDirtyItem);
3991
3992         QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
3993         nextDirtyItem = p->dirtyItemList;
3994         if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
3995         prevDirtyItem = &p->dirtyItemList;
3996         p->dirtyItemList = q;
3997         p->dirtyItem(q);
3998     }
3999     Q_ASSERT(prevDirtyItem);
4000 }
4001
4002 void QQuickItemPrivate::removeFromDirtyList()
4003 {
4004     if (prevDirtyItem) {
4005         if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4006         *prevDirtyItem = nextDirtyItem;
4007         prevDirtyItem = 0;
4008         nextDirtyItem = 0;
4009     }
4010     Q_ASSERT(!prevDirtyItem);
4011     Q_ASSERT(!nextDirtyItem);
4012 }
4013
4014 void QQuickItemPrivate::refFromEffectItem(bool hide)
4015 {
4016     ++effectRefCount;
4017     if (1 == effectRefCount) {
4018         dirty(EffectReference);
4019         if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4020     }
4021     if (hide) {
4022         if (++hideRefCount == 1)
4023             dirty(HideReference);
4024     }
4025 }
4026
4027 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4028 {
4029     Q_ASSERT(effectRefCount);
4030     --effectRefCount;
4031     if (0 == effectRefCount) {
4032         dirty(EffectReference);
4033         if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4034     }
4035     if (unhide) {
4036         if (--hideRefCount == 0)
4037             dirty(HideReference);
4038     }
4039 }
4040
4041 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4042 {
4043     Q_Q(QQuickItem);
4044     switch (change) {
4045     case QQuickItem::ItemChildAddedChange:
4046         q->itemChange(change, data);
4047         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4048             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4049             if (change.types & QQuickItemPrivate::Children) {
4050                 change.listener->itemChildAdded(q, data.item);
4051             }
4052         }
4053         break;
4054     case QQuickItem::ItemChildRemovedChange:
4055         q->itemChange(change, data);
4056         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4057             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4058             if (change.types & QQuickItemPrivate::Children) {
4059                 change.listener->itemChildRemoved(q, data.item);
4060             }
4061         }
4062         break;
4063     case QQuickItem::ItemSceneChange:
4064         q->itemChange(change, data);
4065         break;
4066     case QQuickItem::ItemVisibleHasChanged:
4067         q->itemChange(change, data);
4068         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4069             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4070             if (change.types & QQuickItemPrivate::Visibility) {
4071                 change.listener->itemVisibilityChanged(q);
4072             }
4073         }
4074         break;
4075     case QQuickItem::ItemParentHasChanged:
4076         q->itemChange(change, data);
4077         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4078             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4079             if (change.types & QQuickItemPrivate::Parent) {
4080                 change.listener->itemParentChanged(q, data.item);
4081             }
4082         }
4083         break;
4084     case QQuickItem::ItemOpacityHasChanged:
4085         q->itemChange(change, data);
4086         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4087             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4088             if (change.types & QQuickItemPrivate::Opacity) {
4089                 change.listener->itemOpacityChanged(q);
4090             }
4091         }
4092         break;
4093     case QQuickItem::ItemActiveFocusHasChanged:
4094         q->itemChange(change, data);
4095         break;
4096     case QQuickItem::ItemRotationHasChanged:
4097         q->itemChange(change, data);
4098         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4099             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4100             if (change.types & QQuickItemPrivate::Rotation) {
4101                 change.listener->itemRotationChanged(q);
4102             }
4103         }
4104         break;
4105     }
4106 }
4107
4108 /*!
4109     \property QQuickItem::smooth
4110     \brief whether the item is smoothly transformed.
4111
4112     This property is provided purely for the purpose of optimization. Turning
4113     smooth transforms off is faster, but looks worse; turning smooth
4114     transformations on is slower, but looks better.
4115
4116     By default smooth transformations are off.
4117 */
4118
4119 /*!
4120     Returns true if the item should be drawn with antialiasing and
4121     smooth pixmap filtering, false otherwise.
4122
4123     The default is false.
4124
4125     \sa setSmooth()
4126 */
4127 bool QQuickItem::smooth() const
4128 {
4129     Q_D(const QQuickItem);
4130     return d->smooth;
4131 }
4132
4133 /*!
4134     Sets whether the item should be drawn with antialiasing and
4135     smooth pixmap filtering to \a smooth.
4136
4137     \sa smooth()
4138 */
4139 void QQuickItem::setSmooth(bool smooth)
4140 {
4141     Q_D(QQuickItem);
4142     if (d->smooth == smooth)
4143         return;
4144
4145     d->smooth = smooth;
4146     d->dirty(QQuickItemPrivate::Smooth);
4147
4148     emit smoothChanged(smooth);
4149 }
4150
4151 QQuickItem::Flags QQuickItem::flags() const
4152 {
4153     Q_D(const QQuickItem);
4154     return (QQuickItem::Flags)d->flags;
4155 }
4156
4157 void QQuickItem::setFlag(Flag flag, bool enabled)
4158 {
4159     Q_D(QQuickItem);
4160     if (enabled)
4161         setFlags((Flags)(d->flags | (quint32)flag));
4162     else
4163         setFlags((Flags)(d->flags & ~(quint32)flag));
4164 }
4165
4166 void QQuickItem::setFlags(Flags flags)
4167 {
4168     Q_D(QQuickItem);
4169
4170     if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4171         if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4172             qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
4173             flags &= ~ItemIsFocusScope;
4174         } else if (d->flags & ItemIsFocusScope) {
4175             qWarning("QQuickItem: Cannot unset FocusScope flag.");
4176             flags |= ItemIsFocusScope;
4177         }
4178     }
4179
4180     if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4181         d->dirty(QQuickItemPrivate::Clip);
4182
4183     d->flags = flags;
4184 }
4185
4186 qreal QQuickItem::x() const
4187 {
4188     Q_D(const QQuickItem);
4189     return d->x;
4190 }
4191
4192 qreal QQuickItem::y() const
4193 {
4194     Q_D(const QQuickItem);
4195     return d->y;
4196 }
4197
4198 QPointF QQuickItem::pos() const
4199 {
4200     Q_D(const QQuickItem);
4201     return QPointF(d->x, d->y);
4202 }
4203
4204 void QQuickItem::setX(qreal v)
4205 {
4206     Q_D(QQuickItem);
4207     if (d->x == v)
4208         return;
4209
4210     qreal oldx = d->x;
4211     d->x = v;
4212
4213     d->dirty(QQuickItemPrivate::Position);
4214
4215     geometryChanged(QRectF(x(), y(), width(), height()),
4216                     QRectF(oldx, y(), width(), height()));
4217 }
4218
4219 void QQuickItem::setY(qreal v)
4220 {
4221     Q_D(QQuickItem);
4222     if (d->y == v)
4223         return;
4224
4225     qreal oldy = d->y;
4226     d->y = v;
4227
4228     d->dirty(QQuickItemPrivate::Position);
4229
4230     geometryChanged(QRectF(x(), y(), width(), height()),
4231                     QRectF(x(), oldy, width(), height()));
4232 }
4233
4234 void QQuickItem::setPos(const QPointF &pos)
4235 {
4236     Q_D(QQuickItem);
4237     if (QPointF(d->x, d->y) == pos)
4238         return;
4239
4240     qreal oldx = d->x;
4241     qreal oldy = d->y;
4242
4243     d->x = pos.x();
4244     d->y = pos.y();
4245
4246     d->dirty(QQuickItemPrivate::Position);
4247
4248     geometryChanged(QRectF(x(), y(), width(), height()),
4249                     QRectF(oldx, oldy, width(), height()));
4250 }
4251
4252 qreal QQuickItem::width() const
4253 {
4254     Q_D(const QQuickItem);
4255     return d->width;
4256 }
4257
4258 void QQuickItem::setWidth(qreal w)
4259 {
4260     Q_D(QQuickItem);
4261     if (qIsNaN(w))
4262         return;
4263
4264     d->widthValid = true;
4265     if (d->width == w)
4266         return;
4267
4268     qreal oldWidth = d->width;
4269     d->width = w;
4270
4271     d->dirty(QQuickItemPrivate::Size);
4272
4273     geometryChanged(QRectF(x(), y(), width(), height()),
4274                     QRectF(x(), y(), oldWidth, height()));
4275 }
4276
4277 void QQuickItem::resetWidth()
4278 {
4279     Q_D(QQuickItem);
4280     d->widthValid = false;
4281     setImplicitWidth(implicitWidth());
4282 }
4283
4284 void QQuickItemPrivate::implicitWidthChanged()
4285 {
4286     Q_Q(QQuickItem);
4287     emit q->implicitWidthChanged();
4288 }
4289
4290 qreal QQuickItemPrivate::getImplicitWidth() const
4291 {
4292     return implicitWidth;
4293 }
4294 /*!
4295     Returns the width of the item that is implied by other properties that determine the content.
4296 */
4297 qreal QQuickItem::implicitWidth() const
4298 {
4299     Q_D(const QQuickItem);
4300     return d->getImplicitWidth();
4301 }
4302
4303 /*!
4304     \qmlproperty real QtQuick2::Item::implicitWidth
4305     \qmlproperty real QtQuick2::Item::implicitHeight
4306
4307     Defines the natural width or height of the Item if no \l width or \l height is specified.
4308
4309     The default implicit size for most items is 0x0, however some elements have an inherent
4310     implicit size which cannot be overridden, e.g. Image, Text.
4311
4312     Setting the implicit size is useful for defining components that have a preferred size
4313     based on their content, for example:
4314
4315     \qml
4316     // Label.qml
4317     import QtQuick 1.1
4318
4319     Item {
4320         property alias icon: image.source
4321         property alias label: text.text
4322         implicitWidth: text.implicitWidth + image.implicitWidth
4323         implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4324         Image { id: image }
4325         Text {
4326             id: text
4327             wrapMode: Text.Wrap
4328             anchors.left: image.right; anchors.right: parent.right
4329             anchors.verticalCenter: parent.verticalCenter
4330         }
4331     }
4332     \endqml
4333
4334     \bold Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4335     incurs a performance penalty as the text must be laid out twice.
4336 */
4337
4338 /*!
4339     Sets the implied width of the item to \a w.
4340     This is the width implied by other properties that determine the content.
4341 */
4342 void QQuickItem::setImplicitWidth(qreal w)
4343 {
4344     Q_D(QQuickItem);
4345     bool changed = w != d->implicitWidth;
4346     d->implicitWidth = w;
4347     if (d->width == w || widthValid()) {
4348         if (changed)
4349             d->implicitWidthChanged();
4350         return;
4351     }
4352
4353     qreal oldWidth = d->width;
4354     d->width = w;
4355
4356     d->dirty(QQuickItemPrivate::Size);
4357
4358     geometryChanged(QRectF(x(), y(), width(), height()),
4359                     QRectF(x(), y(), oldWidth, height()));
4360
4361     if (changed)
4362         d->implicitWidthChanged();
4363 }
4364
4365 /*!
4366     Returns whether the width property has been set explicitly.
4367 */
4368 bool QQuickItem::widthValid() const
4369 {
4370     Q_D(const QQuickItem);
4371     return d->widthValid;
4372 }
4373
4374 qreal QQuickItem::height() const
4375 {
4376     Q_D(const QQuickItem);
4377     return d->height;
4378 }
4379
4380 void QQuickItem::setHeight(qreal h)
4381 {
4382     Q_D(QQuickItem);
4383     if (qIsNaN(h))
4384         return;
4385
4386     d->heightValid = true;
4387     if (d->height == h)
4388         return;
4389
4390     qreal oldHeight = d->height;
4391     d->height = h;
4392
4393     d->dirty(QQuickItemPrivate::Size);
4394
4395     geometryChanged(QRectF(x(), y(), width(), height()),
4396                     QRectF(x(), y(), width(), oldHeight));
4397 }
4398
4399 void QQuickItem::resetHeight()
4400 {
4401     Q_D(QQuickItem);
4402     d->heightValid = false;
4403     setImplicitHeight(implicitHeight());
4404 }
4405
4406 void QQuickItemPrivate::implicitHeightChanged()
4407 {
4408     Q_Q(QQuickItem);
4409     emit q->implicitHeightChanged();
4410 }
4411
4412 qreal QQuickItemPrivate::getImplicitHeight() const
4413 {
4414     return implicitHeight;
4415 }
4416
4417 /*!
4418     Returns the height of the item that is implied by other properties that determine the content.
4419 */
4420 qreal QQuickItem::implicitHeight() const
4421 {
4422     Q_D(const QQuickItem);
4423     return d->getImplicitHeight();
4424 }
4425
4426
4427 /*!
4428     Sets the implied height of the item to \a h.
4429     This is the height implied by other properties that determine the content.
4430 */
4431 void QQuickItem::setImplicitHeight(qreal h)
4432 {
4433     Q_D(QQuickItem);
4434     bool changed = h != d->implicitHeight;
4435     d->implicitHeight = h;
4436     if (d->height == h || heightValid()) {
4437         if (changed)
4438             d->implicitHeightChanged();
4439         return;
4440     }
4441
4442     qreal oldHeight = d->height;
4443     d->height = h;
4444
4445     d->dirty(QQuickItemPrivate::Size);
4446
4447     geometryChanged(QRectF(x(), y(), width(), height()),
4448                     QRectF(x(), y(), width(), oldHeight));
4449
4450     if (changed)
4451         d->implicitHeightChanged();
4452 }
4453
4454 void QQuickItem::setImplicitSize(qreal w, qreal h)
4455 {
4456     Q_D(QQuickItem);
4457     bool wChanged = w != d->implicitWidth;
4458     bool hChanged = h != d->implicitHeight;
4459
4460     d->implicitWidth = w;
4461     d->implicitHeight = h;
4462
4463     bool wDone = false;
4464     bool hDone = false;
4465     if (d->width == w || widthValid()) {
4466         if (wChanged)
4467             d->implicitWidthChanged();
4468         wDone = true;
4469     }
4470     if (d->height == h || heightValid()) {
4471         if (hChanged)
4472             d->implicitHeightChanged();
4473         hDone = true;
4474     }
4475     if (wDone && hDone)
4476         return;
4477
4478     qreal oldWidth = d->width;
4479     qreal oldHeight = d->height;
4480     if (!wDone)
4481         d->width = w;
4482     if (!hDone)
4483         d->height = h;
4484
4485     d->dirty(QQuickItemPrivate::Size);
4486
4487     geometryChanged(QRectF(x(), y(), width(), height()),
4488                     QRectF(x(), y(), oldWidth, oldHeight));
4489
4490     if (!wDone && wChanged)
4491         d->implicitWidthChanged();
4492     if (!hDone && hChanged)
4493         d->implicitHeightChanged();
4494 }
4495
4496 /*!
4497     Returns whether the height property has been set explicitly.
4498 */
4499 bool QQuickItem::heightValid() const
4500 {
4501     Q_D(const QQuickItem);
4502     return d->heightValid;
4503 }
4504
4505 void QQuickItem::setSize(const QSizeF &size)
4506 {
4507     Q_D(QQuickItem);
4508     d->heightValid = true;
4509     d->widthValid = true;
4510
4511     if (QSizeF(d->width, d->height) == size)
4512         return;
4513
4514     qreal oldHeight = d->height;
4515     qreal oldWidth = d->width;
4516     d->height = size.height();
4517     d->width = size.width();
4518
4519     d->dirty(QQuickItemPrivate::Size);
4520
4521     geometryChanged(QRectF(x(), y(), width(), height()),
4522                     QRectF(x(), y(), oldWidth, oldHeight));
4523 }
4524
4525 bool QQuickItem::hasActiveFocus() const
4526 {
4527     Q_D(const QQuickItem);
4528     return d->activeFocus;
4529 }
4530
4531 bool QQuickItem::hasFocus() const
4532 {
4533     Q_D(const QQuickItem);
4534     return d->focus;
4535 }
4536
4537 void QQuickItem::setFocus(bool focus)
4538 {
4539     Q_D(QQuickItem);
4540     if (d->focus == focus)
4541         return;
4542
4543     if (d->canvas) {
4544         // Need to find our nearest focus scope
4545         QQuickItem *scope = parentItem();
4546         while (scope && !scope->isFocusScope())
4547             scope = scope->parentItem();
4548         if (focus)
4549             QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4550         else
4551             QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4552     } else {
4553         d->focus = focus;
4554         emit focusChanged(focus);
4555     }
4556 }
4557
4558 bool QQuickItem::isFocusScope() const
4559 {
4560     return flags() & ItemIsFocusScope;
4561 }
4562
4563 QQuickItem *QQuickItem::scopedFocusItem() const
4564 {
4565     Q_D(const QQuickItem);
4566     if (!isFocusScope())
4567         return 0;
4568     else
4569         return d->subFocusItem;
4570 }
4571
4572
4573 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
4574 {
4575     Q_D(const QQuickItem);
4576     return d->acceptedMouseButtons;
4577 }
4578
4579 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4580 {
4581     Q_D(QQuickItem);
4582     d->acceptedMouseButtons = buttons;
4583 }
4584
4585 bool QQuickItem::filtersChildMouseEvents() const
4586 {
4587     Q_D(const QQuickItem);
4588     return d->filtersChildMouseEvents;
4589 }
4590
4591 void QQuickItem::setFiltersChildMouseEvents(bool filter)
4592 {
4593     Q_D(QQuickItem);
4594     d->filtersChildMouseEvents = filter;
4595 }
4596
4597 bool QQuickItem::isUnderMouse() const
4598 {
4599     Q_D(const QQuickItem);
4600     if (!d->canvas)
4601         return false;
4602
4603     QPoint cursorPos = QCursor::pos();
4604     if (QRectF(0, 0, width(), height()).contains(mapFromScene(cursorPos))) // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
4605         return true;
4606     return false;
4607 }
4608
4609 bool QQuickItem::acceptHoverEvents() const
4610 {
4611     Q_D(const QQuickItem);
4612     return d->hoverEnabled;
4613 }
4614
4615 void QQuickItem::setAcceptHoverEvents(bool enabled)
4616 {
4617     Q_D(QQuickItem);
4618     d->hoverEnabled = enabled;
4619 }
4620
4621 void QQuickItem::grabMouse()
4622 {
4623     Q_D(QQuickItem);
4624     if (!d->canvas)
4625         return;
4626     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4627     if (canvasPriv->mouseGrabberItem == this)
4628         return;
4629
4630     QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
4631     canvasPriv->mouseGrabberItem = this;
4632     if (oldGrabber)
4633         oldGrabber->mouseUngrabEvent();
4634 }
4635
4636 void QQuickItem::ungrabMouse()
4637 {
4638     Q_D(QQuickItem);
4639     if (!d->canvas)
4640         return;
4641     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4642     if (canvasPriv->mouseGrabberItem != this) {
4643         qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
4644         return;
4645     }
4646
4647     canvasPriv->mouseGrabberItem = 0;
4648     mouseUngrabEvent();
4649 }
4650
4651 bool QQuickItem::keepMouseGrab() const
4652 {
4653     Q_D(const QQuickItem);
4654     return d->keepMouse;
4655 }
4656
4657 /*!
4658   The flag indicating whether the mouse should remain
4659   with this item is set to \a keep.
4660
4661   This is useful for items that wish to grab and keep mouse
4662   interaction following a predefined gesture.  For example,
4663   an item that is interested in horizontal mouse movement
4664   may set keepMouseGrab to true once a threshold has been
4665   exceeded.  Once keepMouseGrab has been set to true, filtering
4666   items will not react to mouse events.
4667
4668   If the item does not indicate that it wishes to retain mouse grab,
4669   a filtering item may steal the grab. For example, Flickable may attempt
4670   to steal a mouse grab if it detects that the user has begun to
4671   move the viewport.
4672
4673   \sa keepMouseGrab()
4674  */
4675 void QQuickItem::setKeepMouseGrab(bool keep)
4676 {
4677     Q_D(QQuickItem);
4678     d->keepMouse = keep;
4679 }
4680
4681 /*!
4682     Grabs the touch points specified by \a ids.
4683
4684     These touch points will be owned by the item until
4685     they are released. Alternatively, the grab can be stolen
4686     by a filtering item like Flickable. Use setKeepTouchGrab()
4687     to prevent the grab from being stolen.
4688
4689     \sa ungrabTouchPoints(), setKeepTouchGrab()
4690 */
4691 void QQuickItem::grabTouchPoints(const QList<int> &ids)
4692 {
4693     Q_D(QQuickItem);
4694     if (!d->canvas)
4695         return;
4696     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4697
4698     QSet<QQuickItem*> ungrab;
4699     for (int i = 0; i < ids.count(); ++i) {
4700         QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
4701         if (oldGrabber == this)
4702             return;
4703
4704         canvasPriv->itemForTouchPointId[ids.at(i)] = this;
4705         if (oldGrabber)
4706             ungrab.insert(oldGrabber);
4707     }
4708     foreach (QQuickItem *oldGrabber, ungrab)
4709         oldGrabber->touchUngrabEvent();
4710 }
4711
4712 /*!
4713     Ungrabs the touch points owned by this item.
4714
4715     \sa grabTouchPoints()
4716 */
4717 void QQuickItem::ungrabTouchPoints()
4718 {
4719     Q_D(QQuickItem);
4720     if (!d->canvas)
4721         return;
4722     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4723
4724     QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
4725     while (i.hasNext()) {
4726         i.next();
4727         if (i.value() == this)
4728             i.remove();
4729     }
4730     touchUngrabEvent();
4731 }
4732
4733 /*!
4734     Returns a value indicating whether the touch points grabbed by this item
4735     should remain with this item exclusively.
4736
4737     \sa setKeepTouchGrab(), keepMouseGrab()
4738 */
4739 bool QQuickItem::keepTouchGrab() const
4740 {
4741     Q_D(const QQuickItem);
4742     return d->keepTouch;
4743 }
4744
4745 /*!
4746   The flag indicating whether the touch points grabbed
4747   by this item should remain with this item is set to \a keep.
4748
4749   This is useful for items that wish to grab and keep specific touch
4750   points following a predefined gesture.  For example,
4751   an item that is interested in horizontal touch point movement
4752   may set setKeepTouchGrab to true once a threshold has been
4753   exceeded.  Once setKeepTouchGrab has been set to true, filtering
4754   items will not react to the relevant touch points.
4755
4756   If the item does not indicate that it wishes to retain touch point grab,
4757   a filtering item may steal the grab. For example, Flickable may attempt
4758   to steal a touch point grab if it detects that the user has begun to
4759   move the viewport.
4760
4761   \sa keepTouchGrab(), setKeepMouseGrab()
4762  */
4763 void QQuickItem::setKeepTouchGrab(bool keep)
4764 {
4765     Q_D(QQuickItem);
4766     d->keepTouch = keep;
4767 }
4768
4769 /*!
4770     \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
4771
4772     Maps the point (\a x, \a y), which is in \a item's coordinate system, to
4773     this item's coordinate system, and returns an object with \c x and \c y
4774     properties matching the mapped coordinate.
4775
4776     If \a item is a \c null value, this maps the point from the coordinate
4777     system of the root QML view.
4778 */
4779 /*!
4780     \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
4781
4782     Maps the point (\a x, \a y), which is in this item's coordinate system, to
4783     \a item's coordinate system, and returns an object with \c x and \c y
4784     properties matching the mapped coordinate.
4785
4786     If \a item is a \c null value, this maps \a x and \a y to the coordinate
4787     system of the root QML view.
4788 */
4789 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
4790 {
4791     QPointF p = mapToScene(point);
4792     if (item)
4793         p = item->mapFromScene(p);
4794     return p;
4795 }
4796
4797 QPointF QQuickItem::mapToScene(const QPointF &point) const
4798 {
4799     Q_D(const QQuickItem);
4800     return d->itemToCanvasTransform().map(point);
4801 }
4802
4803 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
4804 {
4805     Q_D(const QQuickItem);
4806     QTransform t = d->itemToCanvasTransform();
4807     if (item)
4808         t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
4809     return t.mapRect(rect);
4810 }
4811
4812 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
4813 {
4814     Q_D(const QQuickItem);
4815     return d->itemToCanvasTransform().mapRect(rect);
4816 }
4817
4818 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
4819 {
4820     QPointF p = item?item->mapToScene(point):point;
4821     return mapFromScene(p);
4822 }
4823
4824 QPointF QQuickItem::mapFromScene(const QPointF &point) const
4825 {
4826     Q_D(const QQuickItem);
4827     return d->canvasToItemTransform().map(point);
4828 }
4829
4830 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
4831 {
4832     Q_D(const QQuickItem);
4833     QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
4834     t *= d->canvasToItemTransform();
4835     return t.mapRect(rect);
4836 }
4837
4838 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
4839 {
4840     Q_D(const QQuickItem);
4841     return d->canvasToItemTransform().mapRect(rect);
4842 }
4843
4844
4845 /*!
4846     \qmlmethod QtQuick2::Item::forceActiveFocus()
4847
4848     Forces active focus on the item.
4849
4850     This method sets focus on the item and makes sure that all the focus scopes
4851     higher in the object hierarchy are also given the focus.
4852 */
4853
4854 /*!
4855     Forces active focus on the item.
4856
4857     This method sets focus on the item and makes sure that all the focus scopes
4858     higher in the object hierarchy are also given the focus.
4859 */
4860
4861 /*!
4862   \qmlmethod QtQuick2::Item::childAt(real x, real y)
4863
4864   Returns the visible child item at point (\a x, \a y), which is in this
4865   item's coordinate system, or \c null if there is no such item.
4866 */
4867
4868 /*!
4869   Returns the visible child item at point (\a x, \a y), which is in this
4870   item's coordinate system, or 0 if there is no such item.
4871 */
4872
4873 /*!
4874   \qmlproperty list<State> QtQuick2::Item::states
4875   This property holds a list of states defined by the item.
4876
4877   \qml
4878   Item {
4879       states: [
4880           State {
4881               // ...
4882           },
4883           State {
4884               // ...
4885           }
4886           // ...
4887       ]
4888   }
4889   \endqml
4890
4891   \sa {qmlstate}{States}
4892 */
4893 /*!
4894   \qmlproperty list<Transition> QtQuick2::Item::transitions
4895   This property holds a list of transitions defined by the item.
4896
4897   \qml
4898   Item {
4899       transitions: [
4900           Transition {
4901               // ...
4902           },
4903           Transition {
4904               // ...
4905           }
4906           // ...
4907       ]
4908   }
4909   \endqml
4910
4911   \sa {QML Animation and Transitions}{Transitions}
4912 */
4913 /*
4914   \qmlproperty list<Filter> QtQuick2::Item::filter
4915   This property holds a list of graphical filters to be applied to the item.
4916
4917   \l {Filter}{Filters} include things like \l {Blur}{blurring}
4918   the item, or giving it a \l Reflection.  Some
4919   filters may not be available on all canvases; if a filter is not
4920   available on a certain canvas, it will simply not be applied for
4921   that canvas (but the QML will still be considered valid).
4922
4923   \qml
4924   Item {
4925       filter: [
4926           Blur {
4927               // ...
4928           },
4929           Reflection {
4930               // ...
4931           }
4932           // ...
4933       ]
4934   }
4935   \endqml
4936 */
4937
4938 /*!
4939   \qmlproperty bool QtQuick2::Item::clip
4940   This property holds whether clipping is enabled. The default clip value is \c false.
4941
4942   If clipping is enabled, an item will clip its own painting, as well
4943   as the painting of its children, to its bounding rectangle.
4944
4945   Non-rectangular clipping regions are not supported for performance reasons.
4946 */
4947
4948 /*!
4949   \property QQuickItem::clip
4950   This property holds whether clipping is enabled. The default clip value is \c false.
4951
4952   If clipping is enabled, an item will clip its own painting, as well
4953   as the painting of its children, to its bounding rectangle. If you set
4954   clipping during an item's paint operation, remember to re-set it to
4955   prevent clipping the rest of your scene.
4956
4957   Non-rectangular clipping regions are not supported for performance reasons.
4958 */
4959
4960 /*!
4961   \qmlproperty string QtQuick2::Item::state
4962
4963   This property holds the name of the current state of the item.
4964
4965   This property is often used in scripts to change between states. For
4966   example:
4967
4968   \js
4969   function toggle() {
4970       if (button.state == 'On')
4971           button.state = 'Off';
4972       else
4973           button.state = 'On';
4974   }
4975   \endjs
4976
4977   If the item is in its base state (i.e. no explicit state has been
4978   set), \c state will be a blank string. Likewise, you can return an
4979   item to its base state by setting its current state to \c ''.
4980
4981   \sa {qmlstates}{States}
4982 */
4983
4984 /*!
4985   \qmlproperty list<Transform> QtQuick2::Item::transform
4986   This property holds the list of transformations to apply.
4987
4988   For more information see \l Transform.
4989 */
4990
4991 /*!
4992     \enum QQuickItem::TransformOrigin
4993
4994     Controls the point about which simple transforms like scale apply.
4995
4996     \value TopLeft The top-left corner of the item.
4997     \value Top The center point of the top of the item.
4998     \value TopRight The top-right corner of the item.
4999     \value Left The left most point of the vertical middle.
5000     \value Center The center of the item.
5001     \value Right The right most point of the vertical middle.
5002     \value BottomLeft The bottom-left corner of the item.
5003     \value Bottom The center point of the bottom of the item.
5004     \value BottomRight The bottom-right corner of the item.
5005 */
5006
5007
5008 /*!
5009   \qmlproperty bool QtQuick2::Item::activeFocus
5010
5011   This property indicates whether the item has active focus.
5012
5013   An item with active focus will receive keyboard input,
5014   or is a FocusScope ancestor of the item that will receive keyboard input.
5015
5016   Usually, activeFocus is gained by setting focus on an item and its enclosing
5017   FocusScopes. In the following example \c input will have activeFocus.
5018   \qml
5019   Rectangle {
5020       FocusScope {
5021           focus: true
5022           TextInput {
5023               id: input
5024               focus: true
5025           }
5026       }
5027   }
5028   \endqml
5029
5030   \sa focus, {qmlfocus}{Keyboard Focus}
5031 */
5032
5033 /*!
5034   \qmlproperty bool QtQuick2::Item::focus
5035   This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5036   will gain active focus when the enclosing focus scope gains active focus.
5037   In the following example, \c input will be given active focus when \c scope gains active focus.
5038   \qml
5039   Rectangle {
5040       FocusScope {
5041           id: scope
5042           TextInput {
5043               id: input
5044               focus: true
5045           }
5046       }
5047   }
5048   \endqml
5049
5050   For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5051   On a practical level, that means the following QML will give active focus to \c input on startup.
5052
5053   \qml
5054   Rectangle {
5055       TextInput {
5056           id: input
5057           focus: true
5058       }
5059   }
5060   \endqml
5061
5062   \sa activeFocus, {qmlfocus}{Keyboard Focus}
5063 */
5064
5065
5066 /*!
5067   \property QQuickItem::anchors
5068   \internal
5069 */
5070
5071 /*!
5072   \property QQuickItem::left
5073   \internal
5074 */
5075
5076 /*!
5077   \property QQuickItem::right
5078   \internal
5079 */
5080
5081 /*!
5082   \property QQuickItem::horizontalCenter
5083   \internal
5084 */
5085
5086 /*!
5087   \property QQuickItem::top
5088   \internal
5089 */
5090
5091 /*!
5092   \property QQuickItem::bottom
5093   \internal
5094 */
5095
5096 /*!
5097   \property QQuickItem::verticalCenter
5098   \internal
5099 */
5100
5101 /*!
5102   \property QQuickItem::focus
5103   \internal
5104 */
5105
5106 /*!
5107   \property QQuickItem::transform
5108   \internal
5109 */
5110
5111 /*!
5112   \property QQuickItem::transformOrigin
5113   \internal
5114 */
5115
5116 /*!
5117   \property QQuickItem::activeFocus
5118   \internal
5119 */
5120
5121 /*!
5122   \property QQuickItem::baseline
5123   \internal
5124 */
5125
5126 /*!
5127   \property QQuickItem::data
5128   \internal
5129 */
5130
5131 /*!
5132   \property QQuickItem::resources
5133   \internal
5134 */
5135
5136 /*!
5137   \property QQuickItem::state
5138   \internal
5139 */
5140
5141 /*!
5142   \property QQuickItem::states
5143   \internal
5144 */
5145
5146 /*!
5147   \property QQuickItem::transformOriginPoint
5148   \internal
5149 */
5150
5151 /*!
5152   \property QQuickItem::transitions
5153   \internal
5154 */
5155
5156 bool QQuickItem::event(QEvent *ev)
5157 {
5158 #if 0
5159     if (ev->type() == QEvent::PolishRequest) {
5160         Q_D(QQuickItem);
5161         d->polishScheduled = false;
5162         updatePolish();
5163         return true;
5164     } else {
5165         return QObject::event(ev);
5166     }
5167 #endif
5168     if (ev->type() == QEvent::InputMethodQuery) {
5169         QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5170         Qt::InputMethodQueries queries = query->queries();
5171         for (uint i = 0; i < 32; ++i) {
5172             Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5173             if (q) {
5174                 QVariant v = inputMethodQuery(q);
5175                 query->setValue(q, v);
5176             }
5177         }
5178         query->accept();
5179         return true;
5180     } else if (ev->type() == QEvent::InputMethod) {
5181         inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5182         return true;
5183     }
5184     return QObject::event(ev);
5185 }
5186
5187 #ifndef QT_NO_DEBUG_STREAM
5188 QDebug operator<<(QDebug debug, QQuickItem *item)
5189 {
5190     if (!item) {
5191         debug << "QQuickItem(0)";
5192         return debug;
5193     }
5194
5195     debug << item->metaObject()->className() << "(this =" << ((void*)item)
5196           << ", name=" << item->objectName()
5197           << ", parent =" << ((void*)item->parentItem())
5198           << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5199           << ", z =" << item->z() << ')';
5200     return debug;
5201 }
5202 #endif
5203
5204 qint64 QQuickItemPrivate::consistentTime = -1;
5205 void QQuickItemPrivate::setConsistentTime(qint64 t)
5206 {
5207     consistentTime = t;
5208 }
5209
5210 class QElapsedTimerConsistentTimeHack
5211 {
5212 public:
5213     void start() {
5214         t1 = QQuickItemPrivate::consistentTime;
5215         t2 = 0;
5216     }
5217     qint64 elapsed() {
5218         return QQuickItemPrivate::consistentTime - t1;
5219     }
5220     qint64 restart() {
5221         qint64 val = QQuickItemPrivate::consistentTime - t1;
5222         t1 = QQuickItemPrivate::consistentTime;
5223         t2 = 0;
5224         return val;
5225     }
5226
5227 private:
5228     qint64 t1;
5229     qint64 t2;
5230 };
5231
5232 void QQuickItemPrivate::start(QElapsedTimer &t)
5233 {
5234     if (QQuickItemPrivate::consistentTime == -1)
5235         t.start();
5236     else
5237         ((QElapsedTimerConsistentTimeHack*)&t)->start();
5238 }
5239
5240 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5241 {
5242     if (QQuickItemPrivate::consistentTime == -1)
5243         return t.elapsed();
5244     else
5245         return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5246 }
5247
5248 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5249 {
5250     if (QQuickItemPrivate::consistentTime == -1)
5251         return t.restart();
5252     else
5253         return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5254 }
5255
5256 /*!
5257     \fn bool QQuickItem::isTextureProvider() const
5258
5259     Returns true if this item is a texture provider. The default
5260     implementation returns false.
5261
5262     This function can be called from any thread.
5263  */
5264
5265 /*!
5266     \fn QSGTextureProvider *QQuickItem::textureProvider() const
5267
5268     Returns the texture provider for an item. The default implementation
5269     returns 0.
5270
5271     This function may only be called on the rendering thread.
5272  */
5273
5274 QT_END_NAMESPACE
5275
5276 #include <moc_qquickitem.cpp>