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