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