Don't re-parent ShaderEffect source items.
[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     } else if (d->canvas) {
1896         QQuickCanvasPrivate::get(d->canvas)->parentlessItems.remove(this);
1897     }
1898
1899     d->parentItem = parentItem;
1900
1901     QQuickCanvas *parentCanvas = parentItem?QQuickItemPrivate::get(parentItem)->canvas:0;
1902     if (d->canvas != parentCanvas) {
1903         QQuickItemPrivate::InitializationState initState;
1904         initState.clear();
1905         d->initCanvas(&initState, parentCanvas);
1906     }
1907
1908     d->dirty(QQuickItemPrivate::ParentChanged);
1909
1910     if (d->parentItem)
1911         QQuickItemPrivate::get(d->parentItem)->addChild(this);
1912
1913     d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
1914     d->setEffectiveEnableRecur(d->calcEffectiveEnable());
1915
1916     if (scopeFocusedItem && d->parentItem && d->canvas) {
1917         // We need to test whether this item becomes scope focused
1918         QQuickItem *scopeItem = 0;
1919         scopeItem = d->parentItem;
1920         while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
1921
1922         if (scopeItem->scopedFocusItem()) {
1923             QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
1924             emit scopeFocusedItem->focusChanged(false);
1925         } else {
1926             QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
1927                                                               QQuickCanvasPrivate::DontChangeFocusProperty);
1928         }
1929     }
1930
1931     d->resolveLayoutMirror();
1932
1933     d->itemChange(ItemParentHasChanged, d->parentItem);
1934
1935     d->parentNotifier.notify();
1936     if (d->isAccessible && d->parentItem) {
1937         d->parentItem->d_func()->setAccessibleFlagAndListener();
1938     }
1939
1940     emit parentChanged(d->parentItem);
1941 }
1942
1943 void QQuickItem::stackBefore(const QQuickItem *sibling)
1944 {
1945     Q_D(QQuickItem);
1946     if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
1947         qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
1948         return;
1949     }
1950
1951     QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
1952
1953     int myIndex = parentPrivate->childItems.indexOf(this);
1954     int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
1955
1956     Q_ASSERT(myIndex != -1 && siblingIndex != -1);
1957
1958     if (myIndex == siblingIndex - 1)
1959         return;
1960
1961     parentPrivate->childItems.removeAt(myIndex);
1962
1963     if (myIndex < siblingIndex) --siblingIndex;
1964
1965     parentPrivate->childItems.insert(siblingIndex, this);
1966
1967     parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
1968     parentPrivate->markSortedChildrenDirty(this);
1969
1970     for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
1971         QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
1972 }
1973
1974 void QQuickItem::stackAfter(const QQuickItem *sibling)
1975 {
1976     Q_D(QQuickItem);
1977     if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
1978         qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
1979         return;
1980     }
1981
1982     QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
1983
1984     int myIndex = parentPrivate->childItems.indexOf(this);
1985     int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
1986
1987     Q_ASSERT(myIndex != -1 && siblingIndex != -1);
1988
1989     if (myIndex == siblingIndex + 1)
1990         return;
1991
1992     parentPrivate->childItems.removeAt(myIndex);
1993
1994     if (myIndex < siblingIndex) --siblingIndex;
1995
1996     parentPrivate->childItems.insert(siblingIndex + 1, this);
1997
1998     parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
1999     parentPrivate->markSortedChildrenDirty(this);
2000
2001     for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
2002         QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
2003 }
2004
2005 /*!
2006     Returns the QQuickItem parent of this item.
2007 */
2008 QQuickItem *QQuickItem::parentItem() const
2009 {
2010     Q_D(const QQuickItem);
2011     return d->parentItem;
2012 }
2013
2014 QSGEngine *QQuickItem::sceneGraphEngine() const
2015 {
2016     return canvas()->sceneGraphEngine();
2017 }
2018
2019 QQuickCanvas *QQuickItem::canvas() const
2020 {
2021     Q_D(const QQuickItem);
2022     return d->canvas;
2023 }
2024
2025 static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
2026 {
2027     return lhs->z() < rhs->z();
2028 }
2029
2030 QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
2031 {
2032     if (sortedChildItems)
2033         return *sortedChildItems;
2034
2035     // If none of the items have set Z then the paint order list is the same as
2036     // the childItems list.  This is by far the most common case.
2037     bool haveZ = false;
2038     for (int i = 0; i < childItems.count(); ++i) {
2039         if (QQuickItemPrivate::get(childItems.at(i))->z != 0.) {
2040             haveZ = true;
2041             break;
2042         }
2043     }
2044     if (haveZ) {
2045         sortedChildItems = new QList<QQuickItem*>(childItems);
2046         qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
2047         return *sortedChildItems;
2048     }
2049
2050     sortedChildItems = const_cast<QList<QQuickItem*>*>(&childItems);
2051
2052     return childItems;
2053 }
2054
2055 void QQuickItemPrivate::addChild(QQuickItem *child)
2056 {
2057     Q_Q(QQuickItem);
2058
2059     Q_ASSERT(!childItems.contains(child));
2060
2061     childItems.append(child);
2062
2063     markSortedChildrenDirty(child);
2064     dirty(QQuickItemPrivate::ChildrenChanged);
2065
2066     itemChange(QQuickItem::ItemChildAddedChange, child);
2067
2068     emit q->childrenChanged();
2069 }
2070
2071 void QQuickItemPrivate::removeChild(QQuickItem *child)
2072 {
2073     Q_Q(QQuickItem);
2074
2075     Q_ASSERT(child);
2076     Q_ASSERT(childItems.contains(child));
2077     childItems.removeOne(child);
2078     Q_ASSERT(!childItems.contains(child));
2079
2080     markSortedChildrenDirty(child);
2081     dirty(QQuickItemPrivate::ChildrenChanged);
2082
2083     itemChange(QQuickItem::ItemChildRemovedChange, child);
2084
2085     emit q->childrenChanged();
2086 }
2087
2088 void QQuickItemPrivate::InitializationState::clear()
2089 {
2090     focusScope = 0;
2091 }
2092
2093 void QQuickItemPrivate::InitializationState::clear(QQuickItem *fs)
2094 {
2095     focusScope = fs;
2096 }
2097
2098 QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *item)
2099 {
2100     if (!focusScope) {
2101         QQuickItem *fs = item->parentItem();
2102         while (!fs->isFocusScope())
2103             fs = fs->parentItem();
2104         focusScope = fs;
2105     }
2106     return focusScope;
2107 }
2108
2109 void QQuickItemPrivate::initCanvas(InitializationState *state, QQuickCanvas *c)
2110 {
2111     Q_Q(QQuickItem);
2112
2113     if (canvas) {
2114         removeFromDirtyList();
2115         QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
2116         if (polishScheduled)
2117             c->itemsToPolish.remove(q);
2118         if (c->mouseGrabberItem == q)
2119             c->mouseGrabberItem = 0;
2120         if ( hoverEnabled )
2121             c->hoverItems.removeAll(q);
2122         if (itemNodeInstance)
2123             c->cleanup(itemNodeInstance);
2124         if (!parentItem)
2125             c->parentlessItems.remove(q);
2126     }
2127
2128     canvas = c;
2129
2130     if (canvas && polishScheduled)
2131         QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
2132
2133     itemNodeInstance = 0;
2134     opacityNode = 0;
2135     clipNode = 0;
2136     rootNode = 0;
2137     groupNode = 0;
2138     paintNode = 0;
2139     beforePaintNode = 0;
2140
2141     InitializationState _dummy;
2142     InitializationState *childState = state;
2143
2144     if (c && q->isFocusScope()) {
2145         _dummy.clear(q);
2146         childState = &_dummy;
2147     }
2148
2149     if (!parentItem && canvas)
2150         QQuickCanvasPrivate::get(canvas)->parentlessItems.insert(q);
2151
2152     for (int ii = 0; ii < childItems.count(); ++ii) {
2153         QQuickItem *child = childItems.at(ii);
2154         QQuickItemPrivate::get(child)->initCanvas(childState, c);
2155     }
2156
2157     if (c && focus) {
2158         // Fixup
2159         if (state->getFocusScope(q)->scopedFocusItem()) {
2160             focus = false;
2161             emit q->focusChanged(false);
2162         } else {
2163             QQuickCanvasPrivate::get(canvas)->setFocusInScope(state->getFocusScope(q), q);
2164         }
2165     }
2166
2167     dirty(Canvas);
2168
2169     if (screenAttached)
2170         screenAttached->canvasChanged(c);
2171     itemChange(QQuickItem::ItemSceneChange, c);
2172 }
2173
2174 /*!
2175 Returns a transform that maps points from canvas space into item space.
2176 */
2177 QTransform QQuickItemPrivate::canvasToItemTransform() const
2178 {
2179     // XXX todo - optimize
2180     return itemToCanvasTransform().inverted();
2181 }
2182
2183 /*!
2184 Returns a transform that maps points from item space into canvas space.
2185 */
2186 QTransform QQuickItemPrivate::itemToCanvasTransform() const
2187 {
2188     // XXX todo
2189     QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
2190     itemToParentTransform(rv);
2191     return rv;
2192 }
2193
2194 /*!
2195 Motifies \a t with this items local transform relative to its parent.
2196 */
2197 void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
2198 {
2199     if (x || y)
2200         t.translate(x, y);
2201
2202     if (!transforms.isEmpty()) {
2203         QMatrix4x4 m(t);
2204         for (int ii = transforms.count() - 1; ii >= 0; --ii)
2205             transforms.at(ii)->applyTo(&m);
2206         t = m.toTransform();
2207     }
2208
2209     if (scale != 1. || rotation != 0.) {
2210         QPointF tp = computeTransformOrigin();
2211         t.translate(tp.x(), tp.y());
2212         t.scale(scale, scale);
2213         t.rotate(rotation);
2214         t.translate(-tp.x(), -tp.y());
2215     }
2216 }
2217
2218
2219 /*!
2220     \qmlproperty real QtQuick2::Item::childrenRect.x
2221     \qmlproperty real QtQuick2::Item::childrenRect.y
2222     \qmlproperty real QtQuick2::Item::childrenRect.width
2223     \qmlproperty real QtQuick2::Item::childrenRect.height
2224
2225     The childrenRect properties allow an item access to the geometry of its
2226     children. This property is useful if you have an item that needs to be
2227     sized to fit its children.
2228 */
2229
2230
2231 /*!
2232     \qmlproperty list<Item> QtQuick2::Item::children
2233     \qmlproperty list<Object> QtQuick2::Item::resources
2234
2235     The children property contains the list of visual children of this item.
2236     The resources property contains non-visual resources that you want to
2237     reference by name.
2238
2239     Generally you can rely on Item's default property to handle all this for
2240     you, but it can come in handy in some cases.
2241
2242     \qml
2243     Item {
2244         children: [
2245             Text {},
2246             Rectangle {}
2247         ]
2248         resources: [
2249             Component {
2250                 id: myComponent
2251                 Text {}
2252             }
2253         ]
2254     }
2255     \endqml
2256 */
2257
2258 /*!
2259     Returns true if construction of the QML component is complete; otherwise
2260     returns false.
2261
2262     It is often desirable to delay some processing until the component is
2263     completed.
2264
2265     \sa componentComplete()
2266 */
2267 bool QQuickItem::isComponentComplete() const
2268 {
2269     Q_D(const QQuickItem);
2270     return d->componentComplete;
2271 }
2272
2273 QQuickItemPrivate::QQuickItemPrivate()
2274 : _anchors(0), _contents(0), baselineOffset(0), _anchorLines(0), _stateGroup(0), origin(QQuickItem::Center),
2275
2276   flags(0), widthValid(false), heightValid(false), componentComplete(true),
2277   keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(false), focus(false), activeFocus(false), notifiedFocus(false),
2278   notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
2279   effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
2280   inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
2281   inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
2282   staticSubtreeGeometry(false),
2283   isAccessible(false),
2284
2285   canvas(0), parentItem(0), sortedChildItems(&childItems),
2286
2287   subFocusItem(0),
2288
2289   x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
2290   z(0), scale(1), rotation(0), opacity(1),
2291
2292   attachedLayoutDirection(0), acceptedMouseButtons(0),
2293   imHints(Qt::ImhMultiLine),
2294
2295   keyHandler(0),
2296
2297   dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
2298
2299   itemNodeInstance(0), opacityNode(0), clipNode(0), rootNode(0), groupNode(0), paintNode(0)
2300   , beforePaintNode(0), effectRefCount(0), hideRefCount(0)
2301   , screenAttached(0)
2302 {
2303 }
2304
2305 QQuickItemPrivate::~QQuickItemPrivate()
2306 {
2307     if (sortedChildItems != &childItems)
2308         delete sortedChildItems;
2309 }
2310
2311 void QQuickItemPrivate::init(QQuickItem *parent)
2312 {
2313 #ifndef QT_NO_DEBUG
2314     ++qt_item_count;
2315     static bool atexit_registered = false;
2316     if (!atexit_registered) {
2317         atexit(qt_print_item_count);
2318         atexit_registered = true;
2319     }
2320 #endif
2321
2322     Q_Q(QQuickItem);
2323
2324     registerAccessorProperties();
2325
2326     baselineOffset.invalidate();
2327
2328     if (parent) {
2329         q->setParentItem(parent);
2330         QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
2331         setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
2332     }
2333 }
2334
2335 void QQuickItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
2336 {
2337     if (!o)
2338         return;
2339
2340     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2341
2342     // This test is measurably (albeit only slightly) faster than qobject_cast<>()
2343     const QMetaObject *mo = o->metaObject();
2344     while (mo && mo != &QQuickItem::staticMetaObject) {
2345         mo = mo->d.superdata;
2346     }
2347
2348     if (mo) {
2349         QQuickItem *item = static_cast<QQuickItem *>(o);
2350         item->setParentItem(that);
2351     } else {
2352         if (o->inherits("QGraphicsItem"))
2353             qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
2354
2355         // XXX todo - do we really want this behavior?
2356         o->setParent(that);
2357     }
2358 }
2359
2360 /*!
2361     \qmlproperty list<Object> QtQuick2::Item::data
2362     \default
2363
2364     The data property allows you to freely mix visual children and resources
2365     in an item.  If you assign a visual item to the data list it becomes
2366     a child and if you assign any other object type, it is added as a resource.
2367
2368     So you can write:
2369     \qml
2370     Item {
2371         Text {}
2372         Rectangle {}
2373         Timer {}
2374     }
2375     \endqml
2376
2377     instead of:
2378     \qml
2379     Item {
2380         children: [
2381             Text {},
2382             Rectangle {}
2383         ]
2384         resources: [
2385             Timer {}
2386         ]
2387     }
2388     \endqml
2389
2390     data is a behind-the-scenes property: you should never need to explicitly
2391     specify it.
2392  */
2393
2394 int QQuickItemPrivate::data_count(QDeclarativeListProperty<QObject> *prop)
2395 {
2396     Q_UNUSED(prop);
2397     // XXX todo
2398     return 0;
2399 }
2400
2401 QObject *QQuickItemPrivate::data_at(QDeclarativeListProperty<QObject> *prop, int i)
2402 {
2403     Q_UNUSED(prop);
2404     Q_UNUSED(i);
2405     // XXX todo
2406     return 0;
2407 }
2408
2409 void QQuickItemPrivate::data_clear(QDeclarativeListProperty<QObject> *prop)
2410 {
2411     Q_UNUSED(prop);
2412     // XXX todo
2413 }
2414
2415 QObject *QQuickItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop, int index)
2416 {
2417     const QObjectList children = prop->object->children();
2418     if (index < children.count())
2419         return children.at(index);
2420     else
2421         return 0;
2422 }
2423
2424 void QQuickItemPrivate::resources_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
2425 {
2426     // XXX todo - do we really want this behavior?
2427     o->setParent(prop->object);
2428 }
2429
2430 int QQuickItemPrivate::resources_count(QDeclarativeListProperty<QObject> *prop)
2431 {
2432     return prop->object->children().count();
2433 }
2434
2435 void QQuickItemPrivate::resources_clear(QDeclarativeListProperty<QObject> *prop)
2436 {
2437     // XXX todo - do we really want this behavior?
2438     const QObjectList children = prop->object->children();
2439     for (int index = 0; index < children.count(); index++)
2440         children.at(index)->setParent(0);
2441 }
2442
2443 QQuickItem *QQuickItemPrivate::children_at(QDeclarativeListProperty<QQuickItem> *prop, int index)
2444 {
2445     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2446     if (index >= p->childItems.count() || index < 0)
2447         return 0;
2448     else
2449         return p->childItems.at(index);
2450 }
2451
2452 void QQuickItemPrivate::children_append(QDeclarativeListProperty<QQuickItem> *prop, QQuickItem *o)
2453 {
2454     if (!o)
2455         return;
2456
2457     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2458     if (o->parentItem() == that)
2459         o->setParentItem(0);
2460
2461     o->setParentItem(that);
2462 }
2463
2464 int QQuickItemPrivate::children_count(QDeclarativeListProperty<QQuickItem> *prop)
2465 {
2466     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
2467     return p->childItems.count();
2468 }
2469
2470 void QQuickItemPrivate::children_clear(QDeclarativeListProperty<QQuickItem> *prop)
2471 {
2472     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2473     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2474     while (!p->childItems.isEmpty())
2475         p->childItems.at(0)->setParentItem(0);
2476 }
2477
2478 int QQuickItemPrivate::transform_count(QDeclarativeListProperty<QQuickTransform> *prop)
2479 {
2480     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2481     return QQuickItemPrivate::get(that)->transforms.count();
2482 }
2483
2484 void QQuickTransform::appendToItem(QQuickItem *item)
2485 {
2486     Q_D(QQuickTransform);
2487     if (!item)
2488         return;
2489
2490     QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2491
2492     if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2493         p->transforms.removeOne(this);
2494         p->transforms.append(this);
2495     } else {
2496         p->transforms.append(this);
2497         d->items.append(item);
2498     }
2499
2500     p->dirty(QQuickItemPrivate::Transform);
2501 }
2502
2503 void QQuickTransform::prependToItem(QQuickItem *item)
2504 {
2505     Q_D(QQuickTransform);
2506     if (!item)
2507         return;
2508
2509     QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2510
2511     if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
2512         p->transforms.removeOne(this);
2513         p->transforms.prepend(this);
2514     } else {
2515         p->transforms.prepend(this);
2516         d->items.append(item);
2517     }
2518
2519     p->dirty(QQuickItemPrivate::Transform);
2520 }
2521
2522 void QQuickItemPrivate::transform_append(QDeclarativeListProperty<QQuickTransform> *prop, QQuickTransform *transform)
2523 {
2524     if (!transform)
2525         return;
2526
2527     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2528     transform->appendToItem(that);
2529 }
2530
2531 QQuickTransform *QQuickItemPrivate::transform_at(QDeclarativeListProperty<QQuickTransform> *prop, int idx)
2532 {
2533     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2534     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2535
2536     if (idx < 0 || idx >= p->transforms.count())
2537         return 0;
2538     else
2539         return p->transforms.at(idx);
2540 }
2541
2542 void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform> *prop)
2543 {
2544     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
2545     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
2546
2547     for (int ii = 0; ii < p->transforms.count(); ++ii) {
2548         QQuickTransform *t = p->transforms.at(ii);
2549         QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
2550         tp->items.removeOne(that);
2551     }
2552
2553     p->transforms.clear();
2554
2555     p->dirty(QQuickItemPrivate::Transform);
2556 }
2557
2558 /*!
2559     \property QQuickItem::childrenRect
2560     \brief The geometry of an item's children.
2561
2562     This property holds the (collective) position and size of the item's children.
2563 */
2564
2565 /*!
2566   \qmlproperty real QtQuick2::Item::x
2567   \qmlproperty real QtQuick2::Item::y
2568   \qmlproperty real QtQuick2::Item::width
2569   \qmlproperty real QtQuick2::Item::height
2570
2571   Defines the item's position and size relative to its parent.
2572
2573   \qml
2574   Item { x: 100; y: 100; width: 100; height: 100 }
2575   \endqml
2576  */
2577
2578 /*!
2579   \qmlproperty real QtQuick2::Item::z
2580
2581   Sets the stacking order of sibling items.  By default the stacking order is 0.
2582
2583   Items with a higher stacking value are drawn on top of siblings with a
2584   lower stacking order.  Items with the same stacking value are drawn
2585   bottom up in the order they appear.  Items with a negative stacking
2586   value are drawn under their parent's content.
2587
2588   The following example shows the various effects of stacking order.
2589
2590   \table
2591   \row
2592   \o \image declarative-item_stacking1.png
2593   \o Same \c z - later children above earlier children:
2594   \qml
2595   Item {
2596       Rectangle {
2597           color: "red"
2598           width: 100; height: 100
2599       }
2600       Rectangle {
2601           color: "blue"
2602           x: 50; y: 50; width: 100; height: 100
2603       }
2604   }
2605   \endqml
2606   \row
2607   \o \image declarative-item_stacking2.png
2608   \o Higher \c z on top:
2609   \qml
2610   Item {
2611       Rectangle {
2612           z: 1
2613           color: "red"
2614           width: 100; height: 100
2615       }
2616       Rectangle {
2617           color: "blue"
2618           x: 50; y: 50; width: 100; height: 100
2619       }
2620   }
2621   \endqml
2622   \row
2623   \o \image declarative-item_stacking3.png
2624   \o Same \c z - children above parents:
2625   \qml
2626   Item {
2627       Rectangle {
2628           color: "red"
2629           width: 100; height: 100
2630           Rectangle {
2631               color: "blue"
2632               x: 50; y: 50; width: 100; height: 100
2633           }
2634       }
2635   }
2636   \endqml
2637   \row
2638   \o \image declarative-item_stacking4.png
2639   \o Lower \c z below:
2640   \qml
2641   Item {
2642       Rectangle {
2643           color: "red"
2644           width: 100; height: 100
2645           Rectangle {
2646               z: -1
2647               color: "blue"
2648               x: 50; y: 50; width: 100; height: 100
2649           }
2650       }
2651   }
2652   \endqml
2653   \endtable
2654  */
2655
2656 /*!
2657     \qmlproperty bool QtQuick2::Item::visible
2658
2659     This property holds whether the item is visible. By default this is true.
2660
2661     Setting this property directly affects the \c visible value of child
2662     items. When set to \c false, the \c visible values of all child items also
2663     become \c false. When set to \c true, the \c visible values of child items
2664     are returned to \c true, unless they have explicitly been set to \c false.
2665
2666     (Because of this flow-on behavior, using the \c visible property may not
2667     have the intended effect if a property binding should only respond to
2668     explicit property changes. In such cases it may be better to use the
2669     \l opacity property instead.)
2670
2671     Setting this property to \c false automatically causes \l focus to be set
2672     to \c false, and this item will longer receive mouse and keyboard events.
2673     (In contrast, setting the \l opacity to 0 does not affect the \l focus
2674     property and the receiving of key events.)
2675
2676     \note This property's value is only affected by changes to this property or
2677     the parent's \c visible property. It does not change, for example, if this
2678     item moves off-screen, or if the \l opacity changes to 0.
2679 */
2680
2681
2682 /*!
2683   \qmlproperty AnchorLine QtQuick2::Item::anchors.top
2684   \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
2685   \qmlproperty AnchorLine QtQuick2::Item::anchors.left
2686   \qmlproperty AnchorLine QtQuick2::Item::anchors.right
2687   \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
2688   \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
2689   \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
2690
2691   \qmlproperty Item QtQuick2::Item::anchors.fill
2692   \qmlproperty Item QtQuick2::Item::anchors.centerIn
2693
2694   \qmlproperty real QtQuick2::Item::anchors.margins
2695   \qmlproperty real QtQuick2::Item::anchors.topMargin
2696   \qmlproperty real QtQuick2::Item::anchors.bottomMargin
2697   \qmlproperty real QtQuick2::Item::anchors.leftMargin
2698   \qmlproperty real QtQuick2::Item::anchors.rightMargin
2699   \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
2700   \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
2701   \qmlproperty real QtQuick2::Item::anchors.baselineOffset
2702
2703   \qmlproperty bool QtQuick2::Item::anchors.mirrored
2704
2705   Anchors provide a way to position an item by specifying its
2706   relationship with other items.
2707
2708   Margins apply to top, bottom, left, right, and fill anchors.
2709   The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2710   Note that margins are anchor-specific and are not applied if an item does not
2711   use anchors.
2712
2713   Offsets apply for horizontal center, vertical center, and baseline anchors.
2714
2715   \table
2716   \row
2717   \o \image declarative-anchors_example.png
2718   \o Text anchored to Image, horizontally centered and vertically below, with a margin.
2719   \qml
2720   Item {
2721       Image {
2722           id: pic
2723           // ...
2724       }
2725       Text {
2726           id: label
2727           anchors.horizontalCenter: pic.horizontalCenter
2728           anchors.top: pic.bottom
2729           anchors.topMargin: 5
2730           // ...
2731       }
2732   }
2733   \endqml
2734   \row
2735   \o \image declarative-anchors_example2.png
2736   \o
2737   Left of Text anchored to right of Image, with a margin. The y
2738   property of both defaults to 0.
2739
2740   \qml
2741   Item {
2742       Image {
2743           id: pic
2744           // ...
2745       }
2746       Text {
2747           id: label
2748           anchors.left: pic.right
2749           anchors.leftMargin: 5
2750           // ...
2751       }
2752   }
2753   \endqml
2754   \endtable
2755
2756   \c anchors.fill provides a convenient way for one item to have the
2757   same geometry as another item, and is equivalent to connecting all
2758   four directional anchors.
2759
2760   To clear an anchor value, set it to \c undefined.
2761
2762   \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2763
2764   \note You can only anchor an item to siblings or a parent.
2765
2766   For more information see \l {anchor-layout}{Anchor Layouts}.
2767 */
2768
2769 /*!
2770   \property QQuickItem::baselineOffset
2771   \brief The position of the item's baseline in local coordinates.
2772
2773   The baseline of a \l Text item is the imaginary line on which the text
2774   sits. Controls containing text usually set their baseline to the
2775   baseline of their text.
2776
2777   For non-text items, a default baseline offset of 0 is used.
2778 */
2779 QQuickAnchors *QQuickItemPrivate::anchors() const
2780 {
2781     if (!_anchors) {
2782         Q_Q(const QQuickItem);
2783         _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
2784         if (!componentComplete)
2785             _anchors->classBegin();
2786     }
2787     return _anchors;
2788 }
2789
2790 QQuickItemPrivate::AnchorLines *QQuickItemPrivate::anchorLines() const
2791 {
2792     Q_Q(const QQuickItem);
2793     if (!_anchorLines) _anchorLines =
2794         new AnchorLines(const_cast<QQuickItem *>(q));
2795     return _anchorLines;
2796 }
2797
2798 void QQuickItemPrivate::siblingOrderChanged()
2799 {
2800     Q_Q(QQuickItem);
2801     for (int ii = 0; ii < changeListeners.count(); ++ii) {
2802         const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
2803         if (change.types & QQuickItemPrivate::SiblingOrder) {
2804             change.listener->itemSiblingOrderChanged(q);
2805         }
2806     }
2807 }
2808
2809 QDeclarativeListProperty<QObject> QQuickItemPrivate::data()
2810 {
2811     return QDeclarativeListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
2812                                              QQuickItemPrivate::data_count,
2813                                              QQuickItemPrivate::data_at,
2814                                              QQuickItemPrivate::data_clear);
2815 }
2816
2817 QRectF QQuickItem::childrenRect()
2818 {
2819     Q_D(QQuickItem);
2820     if (!d->_contents) {
2821         d->_contents = new QQuickContents(this);
2822         if (d->componentComplete)
2823             d->_contents->complete();
2824     }
2825     return d->_contents->rectF();
2826 }
2827
2828 QList<QQuickItem *> QQuickItem::childItems() const
2829 {
2830     Q_D(const QQuickItem);
2831     return d->childItems;
2832 }
2833
2834 bool QQuickItem::clip() const
2835 {
2836     return flags() & ItemClipsChildrenToShape;
2837 }
2838
2839 void QQuickItem::setClip(bool c)
2840 {
2841     if (clip() == c)
2842         return;
2843
2844     setFlag(ItemClipsChildrenToShape, c);
2845
2846     emit clipChanged(c);
2847 }
2848
2849
2850 /*!
2851   This function is called to handle this item's changes in
2852   geometry from \a oldGeometry to \a newGeometry. If the two
2853   geometries are the same, it doesn't do anything.
2854  */
2855 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
2856 {
2857     Q_D(QQuickItem);
2858
2859     if (d->_anchors)
2860         QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
2861
2862     bool xChange = (newGeometry.x() != oldGeometry.x());
2863     bool yChange = (newGeometry.y() != oldGeometry.y());
2864     bool widthChange = (newGeometry.width() != oldGeometry.width());
2865     bool heightChange = (newGeometry.height() != oldGeometry.height());
2866
2867     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
2868         const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
2869         if (change.types & QQuickItemPrivate::Geometry) {
2870             if (change.gTypes == QQuickItemPrivate::GeometryChange) {
2871                 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
2872             } else if ((xChange && (change.gTypes & QQuickItemPrivate::XChange)) ||
2873                        (yChange && (change.gTypes & QQuickItemPrivate::YChange)) ||
2874                        (widthChange && (change.gTypes & QQuickItemPrivate::WidthChange)) ||
2875                        (heightChange && (change.gTypes & QQuickItemPrivate::HeightChange))) {
2876                 change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
2877             }
2878         }
2879     }
2880
2881     if (xChange)
2882         emit xChanged();
2883     if (yChange)
2884         emit yChanged();
2885     if (widthChange)
2886         emit widthChanged();
2887     if (heightChange)
2888         emit heightChanged();
2889 }
2890
2891 /*!
2892     Called by the rendering thread when it is time to sync the state of the QML objects with the
2893     scene graph objects. The function should return the root of the scene graph subtree for
2894     this item. \a oldNode is the node that was returned the last time the function was called.
2895
2896     The main thread is blocked while this function is executed so it is safe to read
2897     values from the QQuickItem instance and other objects in the main thread.
2898
2899     \warning This is the only function in which it is allowed to make use of scene graph
2900     objects from the main thread. Use of scene graph objects outside this function will
2901     result in race conditions and potential crashes.
2902  */
2903
2904 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
2905 {
2906     delete oldNode;
2907     return 0;
2908 }
2909
2910 QSGTransformNode *QQuickItemPrivate::createTransformNode()
2911 {
2912     return new QSGTransformNode;
2913 }
2914
2915 void QQuickItem::updatePolish()
2916 {
2917 }
2918
2919 void QQuickItem::sendAccessibilityUpdate()
2920 {
2921     Q_D(QQuickItem);
2922 }
2923
2924 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
2925 {
2926     ChangeListener change(listener, types);
2927     changeListeners.removeOne(change);
2928 }
2929
2930 void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
2931 {
2932     ChangeListener change(listener, types);
2933     int index = changeListeners.find(change);
2934     if (index > -1)
2935         changeListeners[index].gTypes = change.gTypes;  //we may have different GeometryChangeTypes
2936     else
2937         changeListeners.append(change);
2938 }
2939
2940 void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
2941 {
2942     ChangeListener change(listener, types);
2943     if (types == NoChange) {
2944         changeListeners.removeOne(change);
2945     } else {
2946         int index = changeListeners.find(change);
2947         if (index > -1)
2948             changeListeners[index].gTypes = change.gTypes;  //we may have different GeometryChangeTypes
2949     }
2950 }
2951
2952 void QQuickItem::keyPressEvent(QKeyEvent *event)
2953 {
2954     event->ignore();
2955 }
2956
2957 void QQuickItem::keyReleaseEvent(QKeyEvent *event)
2958 {
2959     event->ignore();
2960 }
2961
2962 void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
2963 {
2964     event->ignore();
2965 }
2966
2967 void QQuickItem::focusInEvent(QFocusEvent *)
2968 {
2969     QAccessible::updateAccessibility(this, 0, QAccessible::Focus);
2970 }
2971
2972 void QQuickItem::focusOutEvent(QFocusEvent *)
2973 {
2974 }
2975
2976 void QQuickItem::mousePressEvent(QMouseEvent *event)
2977 {
2978     event->ignore();
2979 }
2980
2981 void QQuickItem::mouseMoveEvent(QMouseEvent *event)
2982 {
2983     event->ignore();
2984 }
2985
2986 void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
2987 {
2988     event->ignore();
2989 }
2990
2991 void QQuickItem::mouseDoubleClickEvent(QMouseEvent *event)
2992 {
2993     mousePressEvent(event);
2994 }
2995
2996 void QQuickItem::mouseUngrabEvent()
2997 {
2998     // XXX todo
2999 }
3000
3001 void QQuickItem::touchUngrabEvent()
3002 {
3003     // XXX todo
3004 }
3005
3006 void QQuickItem::wheelEvent(QWheelEvent *event)
3007 {
3008     event->ignore();
3009 }
3010
3011 void QQuickItem::touchEvent(QTouchEvent *event)
3012 {
3013     event->ignore();
3014 }
3015
3016 void QQuickItem::hoverEnterEvent(QHoverEvent *event)
3017 {
3018     Q_UNUSED(event);
3019 }
3020
3021 void QQuickItem::hoverMoveEvent(QHoverEvent *event)
3022 {
3023     Q_UNUSED(event);
3024 }
3025
3026 void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
3027 {
3028     Q_UNUSED(event);
3029 }
3030
3031 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
3032 {
3033     Q_UNUSED(event);
3034 }
3035
3036 void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
3037 {
3038
3039     Q_UNUSED(event);
3040 }
3041
3042 void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
3043 {
3044
3045     Q_UNUSED(event);
3046 }
3047
3048 void QQuickItem::dropEvent(QDropEvent *event)
3049 {
3050     Q_UNUSED(event);
3051 }
3052
3053 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
3054 {
3055     return false;
3056 }
3057
3058 void QQuickItem::windowDeactivateEvent()
3059 {
3060     foreach (QQuickItem* item, childItems()) {
3061         item->windowDeactivateEvent();
3062     }
3063 }
3064
3065 Qt::InputMethodHints QQuickItem::inputMethodHints() const
3066 {
3067     Q_D(const QQuickItem);
3068     return d->imHints;
3069 }
3070
3071 void QQuickItem::setInputMethodHints(Qt::InputMethodHints hints)
3072 {
3073     Q_D(QQuickItem);
3074     d->imHints = hints;
3075
3076     if (!d->canvas || d->canvas->activeFocusItem() != this)
3077         return;
3078
3079     QInputPanel *p = qApp->inputPanel();
3080     if (p->inputItem() == this)
3081         qApp->inputPanel()->update(Qt::ImHints);
3082 }
3083
3084 void QQuickItem::updateMicroFocus()
3085 {
3086     QInputPanel *p = qApp->inputPanel();
3087     if (p->inputItem() == this)
3088         qApp->inputPanel()->update(Qt::ImQueryInput);
3089 }
3090
3091 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
3092 {
3093     Q_D(const QQuickItem);
3094     QVariant v;
3095
3096     switch (query) {
3097     case Qt::ImEnabled:
3098         v = (bool)(flags() & ItemAcceptsInputMethod);
3099         break;
3100     case Qt::ImHints:
3101         v = (int)inputMethodHints();
3102         break;
3103     case Qt::ImCursorRectangle:
3104     case Qt::ImFont:
3105     case Qt::ImCursorPosition:
3106     case Qt::ImSurroundingText:
3107     case Qt::ImCurrentSelection:
3108     case Qt::ImMaximumTextLength:
3109     case Qt::ImAnchorPosition:
3110     case Qt::ImPreferredLanguage:
3111         if (d->keyHandler)
3112             v = d->keyHandler->inputMethodQuery(query);
3113     default:
3114         break;
3115     }
3116
3117     return v;
3118 }
3119
3120 QQuickAnchorLine QQuickItemPrivate::left() const
3121 {
3122     return anchorLines()->left;
3123 }
3124
3125 QQuickAnchorLine QQuickItemPrivate::right() const
3126 {
3127     return anchorLines()->right;
3128 }
3129
3130 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
3131 {
3132     return anchorLines()->hCenter;
3133 }
3134
3135 QQuickAnchorLine QQuickItemPrivate::top() const
3136 {
3137     return anchorLines()->top;
3138 }
3139
3140 QQuickAnchorLine QQuickItemPrivate::bottom() const
3141 {
3142     return anchorLines()->bottom;
3143 }
3144
3145 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
3146 {
3147     return anchorLines()->vCenter;
3148 }
3149
3150 QQuickAnchorLine QQuickItemPrivate::baseline() const
3151 {
3152     return anchorLines()->baseline;
3153 }
3154
3155 qreal QQuickItem::baselineOffset() const
3156 {
3157     Q_D(const QQuickItem);
3158     if (!d->baselineOffset.isValid()) {
3159         return 0.0;
3160     } else
3161         return d->baselineOffset;
3162 }
3163
3164 void QQuickItem::setBaselineOffset(qreal offset)
3165 {
3166     Q_D(QQuickItem);
3167     if (offset == d->baselineOffset)
3168         return;
3169
3170     d->baselineOffset = offset;
3171
3172     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
3173         const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3174         if (change.types & QQuickItemPrivate::Geometry) {
3175             QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
3176             if (anchor)
3177                 anchor->updateVerticalAnchors();
3178         }
3179     }
3180     emit baselineOffsetChanged(offset);
3181 }
3182
3183 void QQuickItem::update()
3184 {
3185     Q_D(QQuickItem);
3186     Q_ASSERT(flags() & ItemHasContents);
3187     d->dirty(QQuickItemPrivate::Content);
3188 }
3189
3190 void QQuickItem::polish()
3191 {
3192     Q_D(QQuickItem);
3193     if (!d->polishScheduled) {
3194         d->polishScheduled = true;
3195         if (d->canvas) {
3196             QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
3197             bool maybeupdate = p->itemsToPolish.isEmpty();
3198             p->itemsToPolish.insert(this);
3199             if (maybeupdate) d->canvas->maybeUpdate();
3200         }
3201     }
3202 }
3203
3204 void QQuickItem::mapFromItem(QDeclarativeV8Function *args) const
3205 {
3206     if (args->Length() != 0) {
3207         v8::Local<v8::Value> item = (*args)[0];
3208         QV8Engine *engine = args->engine();
3209
3210         QQuickItem *itemObj = 0;
3211         if (!item->IsNull())
3212             itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3213
3214         if (!itemObj && !item->IsNull()) {
3215             qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
3216                           << "\" which is neither null nor an Item";
3217             return;
3218         }
3219
3220         v8::Local<v8::Object> rv = v8::Object::New();
3221         args->returnValue(rv);
3222
3223         qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3224         qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3225
3226         QPointF p = mapFromItem(itemObj, QPointF(x, y));
3227
3228         rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3229         rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3230     }
3231 }
3232
3233 QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
3234 {
3235     Q_D(const QQuickItem);
3236
3237     // XXX todo - we need to be able to handle common parents better and detect
3238     // invalid cases
3239     if (ok) *ok = true;
3240
3241     QTransform t = d->itemToCanvasTransform();
3242     if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
3243
3244     return t;
3245 }
3246
3247 void QQuickItem::mapToItem(QDeclarativeV8Function *args) const
3248 {
3249     if (args->Length() != 0) {
3250         v8::Local<v8::Value> item = (*args)[0];
3251         QV8Engine *engine = args->engine();
3252
3253         QQuickItem *itemObj = 0;
3254         if (!item->IsNull())
3255             itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
3256
3257         if (!itemObj && !item->IsNull()) {
3258             qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
3259                           << "\" which is neither null nor an Item";
3260             return;
3261         }
3262
3263         v8::Local<v8::Object> rv = v8::Object::New();
3264         args->returnValue(rv);
3265
3266         qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
3267         qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
3268
3269         QPointF p = mapToItem(itemObj, QPointF(x, y));
3270
3271         rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
3272         rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
3273     }
3274 }
3275
3276 void QQuickItem::forceActiveFocus()
3277 {
3278     setFocus(true);
3279     QQuickItem *parent = parentItem();
3280     while (parent) {
3281         if (parent->flags() & QQuickItem::ItemIsFocusScope) {
3282             parent->setFocus(true);
3283         }
3284         parent = parent->parentItem();
3285     }
3286 }
3287
3288 QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
3289 {
3290     // XXX todo - should this include transform etc.?
3291     const QList<QQuickItem *> children = childItems();
3292     for (int i = children.count()-1; i >= 0; --i) {
3293         QQuickItem *child = children.at(i);
3294         if (child->isVisible() && child->x() <= x
3295                 && child->x() + child->width() >= x
3296                 && child->y() <= y
3297                 && child->y() + child->height() >= y)
3298             return child;
3299     }
3300     return 0;
3301 }
3302
3303 QDeclarativeListProperty<QObject> QQuickItemPrivate::resources()
3304 {
3305     return QDeclarativeListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
3306                                              QQuickItemPrivate::resources_count,
3307                                              QQuickItemPrivate::resources_at,
3308                                              QQuickItemPrivate::resources_clear);
3309 }
3310
3311 QDeclarativeListProperty<QQuickItem> QQuickItemPrivate::children()
3312 {
3313     return QDeclarativeListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
3314                                              QQuickItemPrivate::children_count,
3315                                              QQuickItemPrivate::children_at,
3316                                              QQuickItemPrivate::children_clear);
3317
3318 }
3319
3320 QDeclarativeListProperty<QDeclarativeState> QQuickItemPrivate::states()
3321 {
3322     return _states()->statesProperty();
3323 }
3324
3325 QDeclarativeListProperty<QDeclarativeTransition> QQuickItemPrivate::transitions()
3326 {
3327     return _states()->transitionsProperty();
3328 }
3329
3330 QString QQuickItemPrivate::state() const
3331 {
3332     if (!_stateGroup)
3333         return QString();
3334     else
3335         return _stateGroup->state();
3336 }
3337
3338 void QQuickItemPrivate::setState(const QString &state)
3339 {
3340     _states()->setState(state);
3341 }
3342
3343 QString QQuickItem::state() const
3344 {
3345     Q_D(const QQuickItem);
3346     return d->state();
3347 }
3348
3349 void QQuickItem::setState(const QString &state)
3350 {
3351     Q_D(QQuickItem);
3352     d->setState(state);
3353 }
3354
3355 QDeclarativeListProperty<QQuickTransform> QQuickItem::transform()
3356 {
3357     return QDeclarativeListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
3358                                                      QQuickItemPrivate::transform_count,
3359                                                      QQuickItemPrivate::transform_at,
3360                                                      QQuickItemPrivate::transform_clear);
3361 }
3362
3363 void QQuickItem::classBegin()
3364 {
3365     Q_D(QQuickItem);
3366     d->componentComplete = false;
3367     if (d->_stateGroup)
3368         d->_stateGroup->classBegin();
3369     if (d->_anchors)
3370         d->_anchors->classBegin();
3371 }
3372
3373 void QQuickItem::componentComplete()
3374 {
3375     Q_D(QQuickItem);
3376     d->componentComplete = true;
3377     if (d->_stateGroup)
3378         d->_stateGroup->componentComplete();
3379     if (d->_anchors) {
3380         d->_anchors->componentComplete();
3381         QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
3382     }
3383     if (d->keyHandler)
3384         d->keyHandler->componentComplete();
3385     if (d->_contents)
3386         d->_contents->complete();
3387 }
3388
3389 QDeclarativeStateGroup *QQuickItemPrivate::_states()
3390 {
3391     Q_Q(QQuickItem);
3392     if (!_stateGroup) {
3393         _stateGroup = new QDeclarativeStateGroup;
3394         if (!componentComplete)
3395             _stateGroup->classBegin();
3396         FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)),
3397                      q, SIGNAL(stateChanged(QString)))
3398     }
3399
3400     return _stateGroup;
3401 }
3402
3403 QQuickItemPrivate::AnchorLines::AnchorLines(QQuickItem *q)
3404 {
3405     left.item = q;
3406     left.anchorLine = QQuickAnchorLine::Left;
3407     right.item = q;
3408     right.anchorLine = QQuickAnchorLine::Right;
3409     hCenter.item = q;
3410     hCenter.anchorLine = QQuickAnchorLine::HCenter;
3411     top.item = q;
3412     top.anchorLine = QQuickAnchorLine::Top;
3413     bottom.item = q;
3414     bottom.anchorLine = QQuickAnchorLine::Bottom;
3415     vCenter.item = q;
3416     vCenter.anchorLine = QQuickAnchorLine::VCenter;
3417     baseline.item = q;
3418     baseline.anchorLine = QQuickAnchorLine::Baseline;
3419 }
3420
3421 QPointF QQuickItemPrivate::computeTransformOrigin() const
3422 {
3423     switch (origin) {
3424     default:
3425     case QQuickItem::TopLeft:
3426         return QPointF(0, 0);
3427     case QQuickItem::Top:
3428         return QPointF(width / 2., 0);
3429     case QQuickItem::TopRight:
3430         return QPointF(width, 0);
3431     case QQuickItem::Left:
3432         return QPointF(0, height / 2.);
3433     case QQuickItem::Center:
3434         return QPointF(width / 2., height / 2.);
3435     case QQuickItem::Right:
3436         return QPointF(width, height / 2.);
3437     case QQuickItem::BottomLeft:
3438         return QPointF(0, height);
3439     case QQuickItem::Bottom:
3440         return QPointF(width / 2., height);
3441     case QQuickItem::BottomRight:
3442         return QPointF(width, height);
3443     }
3444 }
3445
3446 void QQuickItemPrivate::transformChanged()
3447 {
3448 }
3449
3450 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
3451 {
3452     Q_Q(QQuickItem);
3453
3454     Q_ASSERT(e->isAccepted());
3455     if (keyHandler) {
3456         if (e->type() == QEvent::KeyPress)
3457             keyHandler->keyPressed(e, false);
3458         else
3459             keyHandler->keyReleased(e, false);
3460
3461         if (e->isAccepted())
3462             return;
3463         else
3464             e->accept();
3465     }
3466
3467     if (e->type() == QEvent::KeyPress)
3468         q->keyPressEvent(e);
3469     else
3470         q->keyReleaseEvent(e);
3471
3472     if (e->isAccepted())
3473         return;
3474
3475     if (keyHandler) {
3476         e->accept();
3477
3478         if (e->type() == QEvent::KeyPress)
3479             keyHandler->keyPressed(e, true);
3480         else
3481             keyHandler->keyReleased(e, true);
3482     }
3483 }
3484
3485 void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
3486 {
3487     Q_Q(QQuickItem);
3488
3489     Q_ASSERT(e->isAccepted());
3490     if (keyHandler) {
3491         keyHandler->inputMethodEvent(e, false);
3492
3493         if (e->isAccepted())
3494             return;
3495         else
3496             e->accept();
3497     }
3498
3499     q->inputMethodEvent(e);
3500
3501     if (e->isAccepted())
3502         return;
3503
3504     if (keyHandler) {
3505         e->accept();
3506
3507         keyHandler->inputMethodEvent(e, true);
3508     }
3509 }
3510
3511 void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
3512 {
3513     Q_Q(QQuickItem);
3514
3515     if (e->type() == QEvent::FocusIn) {
3516         q->focusInEvent(e);
3517     } else {
3518         q->focusOutEvent(e);
3519     }
3520 }
3521
3522 void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
3523 {
3524     Q_Q(QQuickItem);
3525
3526     Q_ASSERT(e->isAccepted());
3527
3528     switch (e->type()) {
3529     default:
3530         Q_ASSERT(!"Unknown event type");
3531     case QEvent::MouseMove:
3532         q->mouseMoveEvent(e);
3533         break;
3534     case QEvent::MouseButtonPress:
3535         q->mousePressEvent(e);
3536         break;
3537     case QEvent::MouseButtonRelease:
3538         q->mouseReleaseEvent(e);
3539         break;
3540     case QEvent::MouseButtonDblClick:
3541         q->mouseDoubleClickEvent(e);
3542         break;
3543     }
3544 }
3545
3546 void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
3547 {
3548     Q_Q(QQuickItem);
3549     q->wheelEvent(e);
3550 }
3551
3552 void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
3553 {
3554     Q_Q(QQuickItem);
3555     q->touchEvent(e);
3556 }
3557
3558 void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
3559 {
3560     Q_Q(QQuickItem);
3561     switch (e->type()) {
3562     default:
3563         Q_ASSERT(!"Unknown event type");
3564     case QEvent::HoverEnter:
3565         q->hoverEnterEvent(e);
3566         break;
3567     case QEvent::HoverLeave:
3568         q->hoverLeaveEvent(e);
3569         break;
3570     case QEvent::HoverMove:
3571         q->hoverMoveEvent(e);
3572         break;
3573     }
3574 }
3575
3576 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
3577 {
3578     Q_Q(QQuickItem);
3579     switch (e->type()) {
3580     default:
3581         Q_ASSERT(!"Unknown event type");
3582     case QEvent::DragEnter:
3583         q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
3584         break;
3585     case QEvent::DragLeave:
3586         q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
3587         break;
3588     case QEvent::DragMove:
3589         q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
3590         break;
3591     case QEvent::Drop:
3592         q->dropEvent(static_cast<QDropEvent *>(e));
3593         break;
3594     }
3595 }
3596
3597 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
3598 {
3599     Q_UNUSED(change);
3600     Q_UNUSED(value);
3601 }
3602
3603 /*! \internal */
3604 // XXX todo - do we want/need this anymore?
3605 // Note that it's now used for varying clip rect
3606 QRectF QQuickItem::boundingRect() const
3607 {
3608     Q_D(const QQuickItem);
3609     return QRectF(0, 0, d->width, d->height);
3610 }
3611
3612 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
3613 {
3614     Q_D(const QQuickItem);
3615     return d->origin;
3616 }
3617
3618 void QQuickItem::setTransformOrigin(TransformOrigin origin)
3619 {
3620     Q_D(QQuickItem);
3621     if (origin == d->origin)
3622         return;
3623
3624     d->origin = origin;
3625     d->dirty(QQuickItemPrivate::TransformOrigin);
3626
3627     emit transformOriginChanged(d->origin);
3628 }
3629
3630 QPointF QQuickItem::transformOriginPoint() const
3631 {
3632     Q_D(const QQuickItem);
3633     if (!d->transformOriginPoint.isNull())
3634         return d->transformOriginPoint;
3635     return d->computeTransformOrigin();
3636 }
3637
3638 void QQuickItem::setTransformOriginPoint(const QPointF &point)
3639 {
3640     Q_D(QQuickItem);
3641     if (d->transformOriginPoint == point)
3642         return;
3643
3644     d->transformOriginPoint = point;
3645     d->dirty(QQuickItemPrivate::TransformOrigin);
3646 }
3647
3648 qreal QQuickItem::z() const
3649 {
3650     Q_D(const QQuickItem);
3651     return d->z;
3652 }
3653
3654 void QQuickItem::setZ(qreal v)
3655 {
3656     Q_D(QQuickItem);
3657     if (d->z == v)
3658         return;
3659
3660     d->z = v;
3661
3662     d->dirty(QQuickItemPrivate::ZValue);
3663     if (d->parentItem) {
3664         QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
3665         QQuickItemPrivate::get(d->parentItem)->markSortedChildrenDirty(this);
3666     }
3667
3668     emit zChanged();
3669 }
3670
3671
3672 /*!
3673   \qmlproperty real QtQuick2::Item::rotation
3674   This property holds the rotation of the item in degrees clockwise.
3675
3676   This specifies how many degrees to rotate the item around its transformOrigin.
3677   The default rotation is 0 degrees (i.e. not rotated at all).
3678
3679   \table
3680   \row
3681   \o \image declarative-rotation.png
3682   \o
3683   \qml
3684   Rectangle {
3685       color: "blue"
3686       width: 100; height: 100
3687       Rectangle {
3688           color: "red"
3689           x: 25; y: 25; width: 50; height: 50
3690           rotation: 30
3691       }
3692   }
3693   \endqml
3694   \endtable
3695
3696   \sa transform, Rotation
3697 */
3698
3699 /*!
3700   \qmlproperty real QtQuick2::Item::scale
3701   This property holds the scale of the item.
3702
3703   A scale of less than 1 means the item will be displayed smaller than
3704   normal, and a scale of greater than 1 means the item will be
3705   displayed larger than normal.  A negative scale means the item will
3706   be mirrored.
3707
3708   By default, items are displayed at a scale of 1 (i.e. at their
3709   normal size).
3710
3711   Scaling is from the item's transformOrigin.
3712
3713   \table
3714   \row
3715   \o \image declarative-scale.png
3716   \o
3717   \qml
3718   Rectangle {
3719       color: "blue"
3720       width: 100; height: 100
3721       Rectangle {
3722           color: "green"
3723           width: 25; height: 25
3724       }
3725       Rectangle {
3726           color: "red"
3727           x: 25; y: 25; width: 50; height: 50
3728           scale: 1.4
3729       }
3730   }
3731   \endqml
3732   \endtable
3733
3734   \sa transform, Scale
3735 */
3736
3737 /*!
3738   \qmlproperty real QtQuick2::Item::opacity
3739
3740   This property holds the opacity of the item.  Opacity is specified as a
3741   number between 0 (fully transparent) and 1 (fully opaque).  The default is 1.
3742
3743   When this property is set, the specified opacity is also applied
3744   individually to child items.  In almost all cases this is what you want,
3745   but in some cases it may produce undesired results. For example in the
3746   second set of rectangles below, the red rectangle has specified an opacity
3747   of 0.5, which affects the opacity of its blue child rectangle even though
3748   the child has not specified an opacity.
3749
3750   \table
3751   \row
3752   \o \image declarative-item_opacity1.png
3753   \o
3754   \qml
3755     Item {
3756         Rectangle {
3757             color: "red"
3758             width: 100; height: 100
3759             Rectangle {
3760                 color: "blue"
3761                 x: 50; y: 50; width: 100; height: 100
3762             }
3763         }
3764     }
3765   \endqml
3766   \row
3767   \o \image declarative-item_opacity2.png
3768   \o
3769   \qml
3770     Item {
3771         Rectangle {
3772             opacity: 0.5
3773             color: "red"
3774             width: 100; height: 100
3775             Rectangle {
3776                 color: "blue"
3777                 x: 50; y: 50; width: 100; height: 100
3778             }
3779         }
3780     }
3781   \endqml
3782   \endtable
3783
3784   If an item's opacity is set to 0, the item will no longer receive mouse
3785   events, but will continue to receive key events and will retain the keyboard
3786   \l focus if it has been set. (In contrast, setting the \l visible property
3787   to \c false stops both mouse and keyboard events, and also removes focus
3788   from the item.)
3789 */
3790
3791 /*!
3792   Returns a value indicating whether mouse input should
3793   remain with this item exclusively.
3794
3795   \sa setKeepMouseGrab()
3796  */
3797
3798 qreal QQuickItem::rotation() const
3799 {
3800     Q_D(const QQuickItem);
3801     return d->rotation;
3802 }
3803
3804 void QQuickItem::setRotation(qreal r)
3805 {
3806     Q_D(QQuickItem);
3807     if (d->rotation == r)
3808         return;
3809
3810     d->rotation = r;
3811
3812     d->dirty(QQuickItemPrivate::BasicTransform);
3813
3814     d->itemChange(ItemRotationHasChanged, r);
3815
3816     emit rotationChanged();
3817 }
3818
3819 qreal QQuickItem::scale() const
3820 {
3821     Q_D(const QQuickItem);
3822     return d->scale;
3823 }
3824
3825 void QQuickItem::setScale(qreal s)
3826 {
3827     Q_D(QQuickItem);
3828     if (d->scale == s)
3829         return;
3830
3831     d->scale = s;
3832
3833     d->dirty(QQuickItemPrivate::BasicTransform);
3834
3835     emit scaleChanged();
3836 }
3837
3838 qreal QQuickItem::opacity() const
3839 {
3840     Q_D(const QQuickItem);
3841     return d->opacity;
3842 }
3843
3844 void QQuickItem::setOpacity(qreal o)
3845 {
3846     Q_D(QQuickItem);
3847     if (d->opacity == o)
3848         return;
3849
3850     d->opacity = o;
3851
3852     d->dirty(QQuickItemPrivate::OpacityValue);
3853
3854     d->itemChange(ItemOpacityHasChanged, o);
3855
3856     emit opacityChanged();
3857 }
3858
3859 bool QQuickItem::isVisible() const
3860 {
3861     Q_D(const QQuickItem);
3862     return d->effectiveVisible;
3863 }
3864
3865 void QQuickItem::setVisible(bool v)
3866 {
3867     Q_D(QQuickItem);
3868     if (v == d->explicitVisible)
3869         return;
3870
3871     d->explicitVisible = v;
3872
3873     d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
3874 }
3875
3876 bool QQuickItem::isEnabled() const
3877 {
3878     Q_D(const QQuickItem);
3879     return d->effectiveEnable;
3880 }
3881
3882 void QQuickItem::setEnabled(bool e)
3883 {
3884     Q_D(QQuickItem);
3885     if (e == d->explicitEnable)
3886         return;
3887
3888     d->explicitEnable = e;
3889
3890     d->setEffectiveEnableRecur(d->calcEffectiveEnable());
3891 }
3892
3893 bool QQuickItemPrivate::calcEffectiveVisible() const
3894 {
3895     // XXX todo - Should the effective visible of an element with no parent just be the current
3896     // effective visible?  This would prevent pointless re-processing in the case of an element
3897     // moving to/from a no-parent situation, but it is different from what graphics view does.
3898     return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
3899 }
3900
3901 void QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
3902 {
3903     Q_Q(QQuickItem);
3904
3905     if (newEffectiveVisible && !explicitVisible) {
3906         // This item locally overrides visibility
3907         return;
3908     }
3909
3910     if (newEffectiveVisible == effectiveVisible) {
3911         // No change necessary
3912         return;
3913     }
3914
3915     effectiveVisible = newEffectiveVisible;
3916     dirty(Visible);
3917     if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
3918
3919     if (canvas) {
3920         QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
3921         if (canvasPriv->mouseGrabberItem == q)
3922             q->ungrabMouse();
3923     }
3924
3925     for (int ii = 0; ii < childItems.count(); ++ii)
3926         QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
3927
3928     for (int ii = 0; ii < changeListeners.count(); ++ii) {
3929         const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
3930         if (change.types & QQuickItemPrivate::Visibility)
3931             change.listener->itemVisibilityChanged(q);
3932     }
3933
3934     if (isAccessible)
3935         QAccessible::updateAccessibility(q, 0, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide );
3936
3937     emit q->visibleChanged();
3938 }
3939
3940 bool QQuickItemPrivate::calcEffectiveEnable() const
3941 {
3942     // XXX todo - Should the effective enable of an element with no parent just be the current
3943     // effective enable?  This would prevent pointless re-processing in the case of an element
3944     // moving to/from a no-parent situation, but it is different from what graphics view does.
3945     return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
3946 }
3947
3948 void QQuickItemPrivate::setEffectiveEnableRecur(bool newEffectiveEnable)
3949 {
3950     Q_Q(QQuickItem);
3951
3952     // XXX todo - need to fixup focus
3953
3954     if (newEffectiveEnable && !explicitEnable) {
3955         // This item locally overrides enable
3956         return;
3957     }
3958
3959     if (newEffectiveEnable == effectiveEnable) {
3960         // No change necessary
3961         return;
3962     }
3963
3964     effectiveEnable = newEffectiveEnable;
3965
3966     if (canvas) {
3967         QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
3968         if (canvasPriv->mouseGrabberItem == q)
3969             q->ungrabMouse();
3970     }
3971
3972     for (int ii = 0; ii < childItems.count(); ++ii)
3973         QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(newEffectiveEnable);
3974
3975     emit q->enabledChanged();
3976 }
3977
3978 QString QQuickItemPrivate::dirtyToString() const
3979 {
3980 #define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
3981     if (!rv.isEmpty()) \
3982         rv.append(QLatin1String("|")); \
3983     rv.append(QLatin1String(#value)); \
3984 }
3985
3986 //    QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
3987     QString rv;
3988
3989     DIRTY_TO_STRING(TransformOrigin);
3990     DIRTY_TO_STRING(Transform);
3991     DIRTY_TO_STRING(BasicTransform);
3992     DIRTY_TO_STRING(Position);
3993     DIRTY_TO_STRING(Size);
3994     DIRTY_TO_STRING(ZValue);
3995     DIRTY_TO_STRING(Content);
3996     DIRTY_TO_STRING(Smooth);
3997     DIRTY_TO_STRING(OpacityValue);
3998     DIRTY_TO_STRING(ChildrenChanged);
3999     DIRTY_TO_STRING(ChildrenStackingChanged);
4000     DIRTY_TO_STRING(ParentChanged);
4001     DIRTY_TO_STRING(Clip);
4002     DIRTY_TO_STRING(Canvas);
4003     DIRTY_TO_STRING(EffectReference);
4004     DIRTY_TO_STRING(Visible);
4005     DIRTY_TO_STRING(HideReference);
4006     DIRTY_TO_STRING(PerformanceHints);
4007
4008     return rv;
4009 }
4010
4011 void QQuickItemPrivate::dirty(DirtyType type)
4012 {
4013     Q_Q(QQuickItem);
4014     if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
4015         transformChanged();
4016
4017     if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
4018         dirtyAttributes |= type;
4019         if (canvas) {
4020             addToDirtyList();
4021             QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
4022         }
4023     }
4024 }
4025
4026 void QQuickItemPrivate::addToDirtyList()
4027 {
4028     Q_Q(QQuickItem);
4029
4030     Q_ASSERT(canvas);
4031     if (!prevDirtyItem) {
4032         Q_ASSERT(!nextDirtyItem);
4033
4034         QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
4035         nextDirtyItem = p->dirtyItemList;
4036         if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
4037         prevDirtyItem = &p->dirtyItemList;
4038         p->dirtyItemList = q;
4039         p->dirtyItem(q);
4040     }
4041     Q_ASSERT(prevDirtyItem);
4042 }
4043
4044 void QQuickItemPrivate::removeFromDirtyList()
4045 {
4046     if (prevDirtyItem) {
4047         if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
4048         *prevDirtyItem = nextDirtyItem;
4049         prevDirtyItem = 0;
4050         nextDirtyItem = 0;
4051     }
4052     Q_ASSERT(!prevDirtyItem);
4053     Q_ASSERT(!nextDirtyItem);
4054 }
4055
4056 void QQuickItemPrivate::refFromEffectItem(bool hide)
4057 {
4058     ++effectRefCount;
4059     if (1 == effectRefCount) {
4060         dirty(EffectReference);
4061         if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4062     }
4063     if (hide) {
4064         if (++hideRefCount == 1)
4065             dirty(HideReference);
4066     }
4067 }
4068
4069 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
4070 {
4071     Q_ASSERT(effectRefCount);
4072     --effectRefCount;
4073     if (0 == effectRefCount) {
4074         dirty(EffectReference);
4075         if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
4076     }
4077     if (unhide) {
4078         if (--hideRefCount == 0)
4079             dirty(HideReference);
4080     }
4081 }
4082
4083 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
4084 {
4085     Q_Q(QQuickItem);
4086     switch (change) {
4087     case QQuickItem::ItemChildAddedChange:
4088         q->itemChange(change, data);
4089         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4090             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4091             if (change.types & QQuickItemPrivate::Children) {
4092                 change.listener->itemChildAdded(q, data.item);
4093             }
4094         }
4095         break;
4096     case QQuickItem::ItemChildRemovedChange:
4097         q->itemChange(change, data);
4098         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4099             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4100             if (change.types & QQuickItemPrivate::Children) {
4101                 change.listener->itemChildRemoved(q, data.item);
4102             }
4103         }
4104         break;
4105     case QQuickItem::ItemSceneChange:
4106         q->itemChange(change, data);
4107         break;
4108     case QQuickItem::ItemVisibleHasChanged:
4109         q->itemChange(change, data);
4110         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4111             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4112             if (change.types & QQuickItemPrivate::Visibility) {
4113                 change.listener->itemVisibilityChanged(q);
4114             }
4115         }
4116         break;
4117     case QQuickItem::ItemParentHasChanged:
4118         q->itemChange(change, data);
4119         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4120             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4121             if (change.types & QQuickItemPrivate::Parent) {
4122                 change.listener->itemParentChanged(q, data.item);
4123             }
4124         }
4125         break;
4126     case QQuickItem::ItemOpacityHasChanged:
4127         q->itemChange(change, data);
4128         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4129             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4130             if (change.types & QQuickItemPrivate::Opacity) {
4131                 change.listener->itemOpacityChanged(q);
4132             }
4133         }
4134         break;
4135     case QQuickItem::ItemActiveFocusHasChanged:
4136         q->itemChange(change, data);
4137         break;
4138     case QQuickItem::ItemRotationHasChanged:
4139         q->itemChange(change, data);
4140         for (int ii = 0; ii < changeListeners.count(); ++ii) {
4141             const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
4142             if (change.types & QQuickItemPrivate::Rotation) {
4143                 change.listener->itemRotationChanged(q);
4144             }
4145         }
4146         break;
4147     }
4148 }
4149
4150 /*!
4151     \property QQuickItem::smooth
4152     \brief whether the item is smoothly transformed.
4153
4154     This property is provided purely for the purpose of optimization. Turning
4155     smooth transforms off is faster, but looks worse; turning smooth
4156     transformations on is slower, but looks better.
4157
4158     By default smooth transformations are off.
4159 */
4160
4161 /*!
4162     Returns true if the item should be drawn with antialiasing and
4163     smooth pixmap filtering, false otherwise.
4164
4165     The default is false.
4166
4167     \sa setSmooth()
4168 */
4169 bool QQuickItem::smooth() const
4170 {
4171     Q_D(const QQuickItem);
4172     return d->smooth;
4173 }
4174
4175 /*!
4176     Sets whether the item should be drawn with antialiasing and
4177     smooth pixmap filtering to \a smooth.
4178
4179     \sa smooth()
4180 */
4181 void QQuickItem::setSmooth(bool smooth)
4182 {
4183     Q_D(QQuickItem);
4184     if (d->smooth == smooth)
4185         return;
4186
4187     d->smooth = smooth;
4188     d->dirty(QQuickItemPrivate::Smooth);
4189
4190     emit smoothChanged(smooth);
4191 }
4192
4193 QQuickItem::Flags QQuickItem::flags() const
4194 {
4195     Q_D(const QQuickItem);
4196     return (QQuickItem::Flags)d->flags;
4197 }
4198
4199 void QQuickItem::setFlag(Flag flag, bool enabled)
4200 {
4201     Q_D(QQuickItem);
4202     if (enabled)
4203         setFlags((Flags)(d->flags | (quint32)flag));
4204     else
4205         setFlags((Flags)(d->flags & ~(quint32)flag));
4206 }
4207
4208 void QQuickItem::setFlags(Flags flags)
4209 {
4210     Q_D(QQuickItem);
4211
4212     if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
4213         if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
4214             qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
4215             flags &= ~ItemIsFocusScope;
4216         } else if (d->flags & ItemIsFocusScope) {
4217             qWarning("QQuickItem: Cannot unset FocusScope flag.");
4218             flags |= ItemIsFocusScope;
4219         }
4220     }
4221
4222     if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
4223         d->dirty(QQuickItemPrivate::Clip);
4224
4225     d->flags = flags;
4226 }
4227
4228 qreal QQuickItem::x() const
4229 {
4230     Q_D(const QQuickItem);
4231     return d->x;
4232 }
4233
4234 qreal QQuickItem::y() const
4235 {
4236     Q_D(const QQuickItem);
4237     return d->y;
4238 }
4239
4240 QPointF QQuickItem::pos() const
4241 {
4242     Q_D(const QQuickItem);
4243     return QPointF(d->x, d->y);
4244 }
4245
4246 void QQuickItem::setX(qreal v)
4247 {
4248     Q_D(QQuickItem);
4249     if (d->x == v)
4250         return;
4251
4252     qreal oldx = d->x;
4253     d->x = v;
4254
4255     d->dirty(QQuickItemPrivate::Position);
4256
4257     geometryChanged(QRectF(x(), y(), width(), height()),
4258                     QRectF(oldx, y(), width(), height()));
4259 }
4260
4261 void QQuickItem::setY(qreal v)
4262 {
4263     Q_D(QQuickItem);
4264     if (d->y == v)
4265         return;
4266
4267     qreal oldy = d->y;
4268     d->y = v;
4269
4270     d->dirty(QQuickItemPrivate::Position);
4271
4272     geometryChanged(QRectF(x(), y(), width(), height()),
4273                     QRectF(x(), oldy, width(), height()));
4274 }
4275
4276 void QQuickItem::setPos(const QPointF &pos)
4277 {
4278     Q_D(QQuickItem);
4279     if (QPointF(d->x, d->y) == pos)
4280         return;
4281
4282     qreal oldx = d->x;
4283     qreal oldy = d->y;
4284
4285     d->x = pos.x();
4286     d->y = pos.y();
4287
4288     d->dirty(QQuickItemPrivate::Position);
4289
4290     geometryChanged(QRectF(x(), y(), width(), height()),
4291                     QRectF(oldx, oldy, width(), height()));
4292 }
4293
4294 qreal QQuickItem::width() const
4295 {
4296     Q_D(const QQuickItem);
4297     return d->width;
4298 }
4299
4300 void QQuickItem::setWidth(qreal w)
4301 {
4302     Q_D(QQuickItem);
4303     if (qIsNaN(w))
4304         return;
4305
4306     d->widthValid = true;
4307     if (d->width == w)
4308         return;
4309
4310     qreal oldWidth = d->width;
4311     d->width = w;
4312
4313     d->dirty(QQuickItemPrivate::Size);
4314
4315     geometryChanged(QRectF(x(), y(), width(), height()),
4316                     QRectF(x(), y(), oldWidth, height()));
4317 }
4318
4319 void QQuickItem::resetWidth()
4320 {
4321     Q_D(QQuickItem);
4322     d->widthValid = false;
4323     setImplicitWidth(implicitWidth());
4324 }
4325
4326 void QQuickItemPrivate::implicitWidthChanged()
4327 {
4328     Q_Q(QQuickItem);
4329     emit q->implicitWidthChanged();
4330 }
4331
4332 qreal QQuickItemPrivate::getImplicitWidth() const
4333 {
4334     return implicitWidth;
4335 }
4336 /*!
4337     Returns the width of the item that is implied by other properties that determine the content.
4338 */
4339 qreal QQuickItem::implicitWidth() const
4340 {
4341     Q_D(const QQuickItem);
4342     return d->getImplicitWidth();
4343 }
4344
4345 /*!
4346     \qmlproperty real QtQuick2::Item::implicitWidth
4347     \qmlproperty real QtQuick2::Item::implicitHeight
4348
4349     Defines the natural width or height of the Item if no \l width or \l height is specified.
4350
4351     The default implicit size for most items is 0x0, however some elements have an inherent
4352     implicit size which cannot be overridden, e.g. Image, Text.
4353
4354     Setting the implicit size is useful for defining components that have a preferred size
4355     based on their content, for example:
4356
4357     \qml
4358     // Label.qml
4359     import QtQuick 1.1
4360
4361     Item {
4362         property alias icon: image.source
4363         property alias label: text.text
4364         implicitWidth: text.implicitWidth + image.implicitWidth
4365         implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
4366         Image { id: image }
4367         Text {
4368             id: text
4369             wrapMode: Text.Wrap
4370             anchors.left: image.right; anchors.right: parent.right
4371             anchors.verticalCenter: parent.verticalCenter
4372         }
4373     }
4374     \endqml
4375
4376     \bold Note: using implicitWidth of Text or TextEdit and setting the width explicitly
4377     incurs a performance penalty as the text must be laid out twice.
4378 */
4379
4380 /*!
4381     Sets the implied width of the item to \a w.
4382     This is the width implied by other properties that determine the content.
4383 */
4384 void QQuickItem::setImplicitWidth(qreal w)
4385 {
4386     Q_D(QQuickItem);
4387     bool changed = w != d->implicitWidth;
4388     d->implicitWidth = w;
4389     if (d->width == w || widthValid()) {
4390         if (changed)
4391             d->implicitWidthChanged();
4392         return;
4393     }
4394
4395     qreal oldWidth = d->width;
4396     d->width = w;
4397
4398     d->dirty(QQuickItemPrivate::Size);
4399
4400     geometryChanged(QRectF(x(), y(), width(), height()),
4401                     QRectF(x(), y(), oldWidth, height()));
4402
4403     if (changed)
4404         d->implicitWidthChanged();
4405 }
4406
4407 /*!
4408     Returns whether the width property has been set explicitly.
4409 */
4410 bool QQuickItem::widthValid() const
4411 {
4412     Q_D(const QQuickItem);
4413     return d->widthValid;
4414 }
4415
4416 qreal QQuickItem::height() const
4417 {
4418     Q_D(const QQuickItem);
4419     return d->height;
4420 }
4421
4422 void QQuickItem::setHeight(qreal h)
4423 {
4424     Q_D(QQuickItem);
4425     if (qIsNaN(h))
4426         return;
4427
4428     d->heightValid = true;
4429     if (d->height == h)
4430         return;
4431
4432     qreal oldHeight = d->height;
4433     d->height = h;
4434
4435     d->dirty(QQuickItemPrivate::Size);
4436
4437     geometryChanged(QRectF(x(), y(), width(), height()),
4438                     QRectF(x(), y(), width(), oldHeight));
4439 }
4440
4441 void QQuickItem::resetHeight()
4442 {
4443     Q_D(QQuickItem);
4444     d->heightValid = false;
4445     setImplicitHeight(implicitHeight());
4446 }
4447
4448 void QQuickItemPrivate::implicitHeightChanged()
4449 {
4450     Q_Q(QQuickItem);
4451     emit q->implicitHeightChanged();
4452 }
4453
4454 qreal QQuickItemPrivate::getImplicitHeight() const
4455 {
4456     return implicitHeight;
4457 }
4458
4459 /*!
4460     Returns the height of the item that is implied by other properties that determine the content.
4461 */
4462 qreal QQuickItem::implicitHeight() const
4463 {
4464     Q_D(const QQuickItem);
4465     return d->getImplicitHeight();
4466 }
4467
4468
4469 /*!
4470     Sets the implied height of the item to \a h.
4471     This is the height implied by other properties that determine the content.
4472 */
4473 void QQuickItem::setImplicitHeight(qreal h)
4474 {
4475     Q_D(QQuickItem);
4476     bool changed = h != d->implicitHeight;
4477     d->implicitHeight = h;
4478     if (d->height == h || heightValid()) {
4479         if (changed)
4480             d->implicitHeightChanged();
4481         return;
4482     }
4483
4484     qreal oldHeight = d->height;
4485     d->height = h;
4486
4487     d->dirty(QQuickItemPrivate::Size);
4488
4489     geometryChanged(QRectF(x(), y(), width(), height()),
4490                     QRectF(x(), y(), width(), oldHeight));
4491
4492     if (changed)
4493         d->implicitHeightChanged();
4494 }
4495
4496 void QQuickItem::setImplicitSize(qreal w, qreal h)
4497 {
4498     Q_D(QQuickItem);
4499     bool wChanged = w != d->implicitWidth;
4500     bool hChanged = h != d->implicitHeight;
4501
4502     d->implicitWidth = w;
4503     d->implicitHeight = h;
4504
4505     bool wDone = false;
4506     bool hDone = false;
4507     if (d->width == w || widthValid()) {
4508         if (wChanged)
4509             d->implicitWidthChanged();
4510         wDone = true;
4511     }
4512     if (d->height == h || heightValid()) {
4513         if (hChanged)
4514             d->implicitHeightChanged();
4515         hDone = true;
4516     }
4517     if (wDone && hDone)
4518         return;
4519
4520     qreal oldWidth = d->width;
4521     qreal oldHeight = d->height;
4522     if (!wDone)
4523         d->width = w;
4524     if (!hDone)
4525         d->height = h;
4526
4527     d->dirty(QQuickItemPrivate::Size);
4528
4529     geometryChanged(QRectF(x(), y(), width(), height()),
4530                     QRectF(x(), y(), oldWidth, oldHeight));
4531
4532     if (!wDone && wChanged)
4533         d->implicitWidthChanged();
4534     if (!hDone && hChanged)
4535         d->implicitHeightChanged();
4536 }
4537
4538 /*!
4539     Returns whether the height property has been set explicitly.
4540 */
4541 bool QQuickItem::heightValid() const
4542 {
4543     Q_D(const QQuickItem);
4544     return d->heightValid;
4545 }
4546
4547 void QQuickItem::setSize(const QSizeF &size)
4548 {
4549     Q_D(QQuickItem);
4550     d->heightValid = true;
4551     d->widthValid = true;
4552
4553     if (QSizeF(d->width, d->height) == size)
4554         return;
4555
4556     qreal oldHeight = d->height;
4557     qreal oldWidth = d->width;
4558     d->height = size.height();
4559     d->width = size.width();
4560
4561     d->dirty(QQuickItemPrivate::Size);
4562
4563     geometryChanged(QRectF(x(), y(), width(), height()),
4564                     QRectF(x(), y(), oldWidth, oldHeight));
4565 }
4566
4567 bool QQuickItem::hasActiveFocus() const
4568 {
4569     Q_D(const QQuickItem);
4570     return d->activeFocus;
4571 }
4572
4573 bool QQuickItem::hasFocus() const
4574 {
4575     Q_D(const QQuickItem);
4576     return d->focus;
4577 }
4578
4579 void QQuickItem::setFocus(bool focus)
4580 {
4581     Q_D(QQuickItem);
4582     if (d->focus == focus)
4583         return;
4584
4585     if (d->canvas) {
4586         // Need to find our nearest focus scope
4587         QQuickItem *scope = parentItem();
4588         while (scope && !scope->isFocusScope())
4589             scope = scope->parentItem();
4590         if (focus)
4591             QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
4592         else
4593             QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
4594     } else {
4595         d->focus = focus;
4596         emit focusChanged(focus);
4597     }
4598 }
4599
4600 bool QQuickItem::isFocusScope() const
4601 {
4602     return flags() & ItemIsFocusScope;
4603 }
4604
4605 QQuickItem *QQuickItem::scopedFocusItem() const
4606 {
4607     Q_D(const QQuickItem);
4608     if (!isFocusScope())
4609         return 0;
4610     else
4611         return d->subFocusItem;
4612 }
4613
4614
4615 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
4616 {
4617     Q_D(const QQuickItem);
4618     return d->acceptedMouseButtons;
4619 }
4620
4621 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
4622 {
4623     Q_D(QQuickItem);
4624     d->acceptedMouseButtons = buttons;
4625 }
4626
4627 bool QQuickItem::filtersChildMouseEvents() const
4628 {
4629     Q_D(const QQuickItem);
4630     return d->filtersChildMouseEvents;
4631 }
4632
4633 void QQuickItem::setFiltersChildMouseEvents(bool filter)
4634 {
4635     Q_D(QQuickItem);
4636     d->filtersChildMouseEvents = filter;
4637 }
4638
4639 bool QQuickItem::isUnderMouse() const
4640 {
4641     Q_D(const QQuickItem);
4642     if (!d->canvas)
4643         return false;
4644
4645     QPoint cursorPos = QCursor::pos();
4646     if (QRectF(0, 0, width(), height()).contains(mapFromScene(cursorPos))) // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
4647         return true;
4648     return false;
4649 }
4650
4651 bool QQuickItem::acceptHoverEvents() const
4652 {
4653     Q_D(const QQuickItem);
4654     return d->hoverEnabled;
4655 }
4656
4657 void QQuickItem::setAcceptHoverEvents(bool enabled)
4658 {
4659     Q_D(QQuickItem);
4660     d->hoverEnabled = enabled;
4661 }
4662
4663 void QQuickItem::grabMouse()
4664 {
4665     Q_D(QQuickItem);
4666     if (!d->canvas)
4667         return;
4668     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4669     if (canvasPriv->mouseGrabberItem == this)
4670         return;
4671
4672     QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
4673     canvasPriv->mouseGrabberItem = this;
4674     if (oldGrabber)
4675         oldGrabber->mouseUngrabEvent();
4676 }
4677
4678 void QQuickItem::ungrabMouse()
4679 {
4680     Q_D(QQuickItem);
4681     if (!d->canvas)
4682         return;
4683     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4684     if (canvasPriv->mouseGrabberItem != this) {
4685         qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
4686         return;
4687     }
4688
4689     canvasPriv->mouseGrabberItem = 0;
4690     mouseUngrabEvent();
4691 }
4692
4693 bool QQuickItem::keepMouseGrab() const
4694 {
4695     Q_D(const QQuickItem);
4696     return d->keepMouse;
4697 }
4698
4699 /*!
4700   The flag indicating whether the mouse should remain
4701   with this item is set to \a keep.
4702
4703   This is useful for items that wish to grab and keep mouse
4704   interaction following a predefined gesture.  For example,
4705   an item that is interested in horizontal mouse movement
4706   may set keepMouseGrab to true once a threshold has been
4707   exceeded.  Once keepMouseGrab has been set to true, filtering
4708   items will not react to mouse events.
4709
4710   If the item does not indicate that it wishes to retain mouse grab,
4711   a filtering item may steal the grab. For example, Flickable may attempt
4712   to steal a mouse grab if it detects that the user has begun to
4713   move the viewport.
4714
4715   \sa keepMouseGrab()
4716  */
4717 void QQuickItem::setKeepMouseGrab(bool keep)
4718 {
4719     Q_D(QQuickItem);
4720     d->keepMouse = keep;
4721 }
4722
4723 /*!
4724     Grabs the touch points specified by \a ids.
4725
4726     These touch points will be owned by the item until
4727     they are released. Alternatively, the grab can be stolen
4728     by a filtering item like Flickable. Use setKeepTouchGrab()
4729     to prevent the grab from being stolen.
4730
4731     \sa ungrabTouchPoints(), setKeepTouchGrab()
4732 */
4733 void QQuickItem::grabTouchPoints(const QList<int> &ids)
4734 {
4735     Q_D(QQuickItem);
4736     if (!d->canvas)
4737         return;
4738     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4739
4740     QSet<QQuickItem*> ungrab;
4741     for (int i = 0; i < ids.count(); ++i) {
4742         QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
4743         if (oldGrabber == this)
4744             return;
4745
4746         canvasPriv->itemForTouchPointId[ids.at(i)] = this;
4747         if (oldGrabber)
4748             ungrab.insert(oldGrabber);
4749     }
4750     foreach (QQuickItem *oldGrabber, ungrab)
4751         oldGrabber->touchUngrabEvent();
4752 }
4753
4754 /*!
4755     Ungrabs the touch points owned by this item.
4756
4757     \sa grabTouchPoints()
4758 */
4759 void QQuickItem::ungrabTouchPoints()
4760 {
4761     Q_D(QQuickItem);
4762     if (!d->canvas)
4763         return;
4764     QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
4765
4766     QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
4767     while (i.hasNext()) {
4768         i.next();
4769         if (i.value() == this)
4770             i.remove();
4771     }
4772     touchUngrabEvent();
4773 }
4774
4775 /*!
4776     Returns a value indicating whether the touch points grabbed by this item
4777     should remain with this item exclusively.
4778
4779     \sa setKeepTouchGrab(), keepMouseGrab()
4780 */
4781 bool QQuickItem::keepTouchGrab() const
4782 {
4783     Q_D(const QQuickItem);
4784     return d->keepTouch;
4785 }
4786
4787 /*!
4788   The flag indicating whether the touch points grabbed
4789   by this item should remain with this item is set to \a keep.
4790
4791   This is useful for items that wish to grab and keep specific touch
4792   points following a predefined gesture.  For example,
4793   an item that is interested in horizontal touch point movement
4794   may set setKeepTouchGrab to true once a threshold has been
4795   exceeded.  Once setKeepTouchGrab has been set to true, filtering
4796   items will not react to the relevant touch points.
4797
4798   If the item does not indicate that it wishes to retain touch point grab,
4799   a filtering item may steal the grab. For example, Flickable may attempt
4800   to steal a touch point grab if it detects that the user has begun to
4801   move the viewport.
4802
4803   \sa keepTouchGrab(), setKeepMouseGrab()
4804  */
4805 void QQuickItem::setKeepTouchGrab(bool keep)
4806 {
4807     Q_D(QQuickItem);
4808     d->keepTouch = keep;
4809 }
4810
4811 /*!
4812     \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
4813
4814     Maps the point (\a x, \a y), which is in \a item's coordinate system, to
4815     this item's coordinate system, and returns an object with \c x and \c y
4816     properties matching the mapped coordinate.
4817
4818     If \a item is a \c null value, this maps the point from the coordinate
4819     system of the root QML view.
4820 */
4821 /*!
4822     \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
4823
4824     Maps the point (\a x, \a y), which is in this item's coordinate system, to
4825     \a item's coordinate system, and returns an object with \c x and \c y
4826     properties matching the mapped coordinate.
4827
4828     If \a item is a \c null value, this maps \a x and \a y to the coordinate
4829     system of the root QML view.
4830 */
4831 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
4832 {
4833     QPointF p = mapToScene(point);
4834     if (item)
4835         p = item->mapFromScene(p);
4836     return p;
4837 }
4838
4839 QPointF QQuickItem::mapToScene(const QPointF &point) const
4840 {
4841     Q_D(const QQuickItem);
4842     return d->itemToCanvasTransform().map(point);
4843 }
4844
4845 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
4846 {
4847     Q_D(const QQuickItem);
4848     QTransform t = d->itemToCanvasTransform();
4849     if (item)
4850         t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
4851     return t.mapRect(rect);
4852 }
4853
4854 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
4855 {
4856     Q_D(const QQuickItem);
4857     return d->itemToCanvasTransform().mapRect(rect);
4858 }
4859
4860 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
4861 {
4862     QPointF p = item?item->mapToScene(point):point;
4863     return mapFromScene(p);
4864 }
4865
4866 QPointF QQuickItem::mapFromScene(const QPointF &point) const
4867 {
4868     Q_D(const QQuickItem);
4869     return d->canvasToItemTransform().map(point);
4870 }
4871
4872 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
4873 {
4874     Q_D(const QQuickItem);
4875     QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
4876     t *= d->canvasToItemTransform();
4877     return t.mapRect(rect);
4878 }
4879
4880 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
4881 {
4882     Q_D(const QQuickItem);
4883     return d->canvasToItemTransform().mapRect(rect);
4884 }
4885
4886
4887 /*!
4888     \qmlmethod QtQuick2::Item::forceActiveFocus()
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     Forces active focus on the item.
4898
4899     This method sets focus on the item and makes sure that all the focus scopes
4900     higher in the object hierarchy are also given the focus.
4901 */
4902
4903 /*!
4904   \qmlmethod QtQuick2::Item::childAt(real x, real y)
4905
4906   Returns the visible child item at point (\a x, \a y), which is in this
4907   item's coordinate system, or \c null if there is no such item.
4908 */
4909
4910 /*!
4911   Returns the visible child item at point (\a x, \a y), which is in this
4912   item's coordinate system, or 0 if there is no such item.
4913 */
4914
4915 /*!
4916   \qmlproperty list<State> QtQuick2::Item::states
4917   This property holds a list of states defined by the item.
4918
4919   \qml
4920   Item {
4921       states: [
4922           State {
4923               // ...
4924           },
4925           State {
4926               // ...
4927           }
4928           // ...
4929       ]
4930   }
4931   \endqml
4932
4933   \sa {qmlstate}{States}
4934 */
4935 /*!
4936   \qmlproperty list<Transition> QtQuick2::Item::transitions
4937   This property holds a list of transitions defined by the item.
4938
4939   \qml
4940   Item {
4941       transitions: [
4942           Transition {
4943               // ...
4944           },
4945           Transition {
4946               // ...
4947           }
4948           // ...
4949       ]
4950   }
4951   \endqml
4952
4953   \sa {QML Animation and Transitions}{Transitions}
4954 */
4955 /*
4956   \qmlproperty list<Filter> QtQuick2::Item::filter
4957   This property holds a list of graphical filters to be applied to the item.
4958
4959   \l {Filter}{Filters} include things like \l {Blur}{blurring}
4960   the item, or giving it a \l Reflection.  Some
4961   filters may not be available on all canvases; if a filter is not
4962   available on a certain canvas, it will simply not be applied for
4963   that canvas (but the QML will still be considered valid).
4964
4965   \qml
4966   Item {
4967       filter: [
4968           Blur {
4969               // ...
4970           },
4971           Reflection {
4972               // ...
4973           }
4974           // ...
4975       ]
4976   }
4977   \endqml
4978 */
4979
4980 /*!
4981   \qmlproperty bool QtQuick2::Item::clip
4982   This property holds whether clipping is enabled. The default clip value is \c false.
4983
4984   If clipping is enabled, an item will clip its own painting, as well
4985   as the painting of its children, to its bounding rectangle.
4986
4987   Non-rectangular clipping regions are not supported for performance reasons.
4988 */
4989
4990 /*!
4991   \property QQuickItem::clip
4992   This property holds whether clipping is enabled. The default clip value is \c false.
4993
4994   If clipping is enabled, an item will clip its own painting, as well
4995   as the painting of its children, to its bounding rectangle. If you set
4996   clipping during an item's paint operation, remember to re-set it to
4997   prevent clipping the rest of your scene.
4998
4999   Non-rectangular clipping regions are not supported for performance reasons.
5000 */
5001
5002 /*!
5003   \qmlproperty string QtQuick2::Item::state
5004
5005   This property holds the name of the current state of the item.
5006
5007   This property is often used in scripts to change between states. For
5008   example:
5009
5010   \js
5011   function toggle() {
5012       if (button.state == 'On')
5013           button.state = 'Off';
5014       else
5015           button.state = 'On';
5016   }
5017   \endjs
5018
5019   If the item is in its base state (i.e. no explicit state has been
5020   set), \c state will be a blank string. Likewise, you can return an
5021   item to its base state by setting its current state to \c ''.
5022
5023   \sa {qmlstates}{States}
5024 */
5025
5026 /*!
5027   \qmlproperty list<Transform> QtQuick2::Item::transform
5028   This property holds the list of transformations to apply.
5029
5030   For more information see \l Transform.
5031 */
5032
5033 /*!
5034     \enum QQuickItem::TransformOrigin
5035
5036     Controls the point about which simple transforms like scale apply.
5037
5038     \value TopLeft The top-left corner of the item.
5039     \value Top The center point of the top of the item.
5040     \value TopRight The top-right corner of the item.
5041     \value Left The left most point of the vertical middle.
5042     \value Center The center of the item.
5043     \value Right The right most point of the vertical middle.
5044     \value BottomLeft The bottom-left corner of the item.
5045     \value Bottom The center point of the bottom of the item.
5046     \value BottomRight The bottom-right corner of the item.
5047 */
5048
5049
5050 /*!
5051   \qmlproperty bool QtQuick2::Item::activeFocus
5052
5053   This property indicates whether the item has active focus.
5054
5055   An item with active focus will receive keyboard input,
5056   or is a FocusScope ancestor of the item that will receive keyboard input.
5057
5058   Usually, activeFocus is gained by setting focus on an item and its enclosing
5059   FocusScopes. In the following example \c input will have activeFocus.
5060   \qml
5061   Rectangle {
5062       FocusScope {
5063           focus: true
5064           TextInput {
5065               id: input
5066               focus: true
5067           }
5068       }
5069   }
5070   \endqml
5071
5072   \sa focus, {qmlfocus}{Keyboard Focus}
5073 */
5074
5075 /*!
5076   \qmlproperty bool QtQuick2::Item::focus
5077   This property indicates whether the item has focus within the enclosing focus scope. If true, this item
5078   will gain active focus when the enclosing focus scope gains active focus.
5079   In the following example, \c input will be given active focus when \c scope gains active focus.
5080   \qml
5081   Rectangle {
5082       FocusScope {
5083           id: scope
5084           TextInput {
5085               id: input
5086               focus: true
5087           }
5088       }
5089   }
5090   \endqml
5091
5092   For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
5093   On a practical level, that means the following QML will give active focus to \c input on startup.
5094
5095   \qml
5096   Rectangle {
5097       TextInput {
5098           id: input
5099           focus: true
5100       }
5101   }
5102   \endqml
5103
5104   \sa activeFocus, {qmlfocus}{Keyboard Focus}
5105 */
5106
5107
5108 /*!
5109   \property QQuickItem::anchors
5110   \internal
5111 */
5112
5113 /*!
5114   \property QQuickItem::left
5115   \internal
5116 */
5117
5118 /*!
5119   \property QQuickItem::right
5120   \internal
5121 */
5122
5123 /*!
5124   \property QQuickItem::horizontalCenter
5125   \internal
5126 */
5127
5128 /*!
5129   \property QQuickItem::top
5130   \internal
5131 */
5132
5133 /*!
5134   \property QQuickItem::bottom
5135   \internal
5136 */
5137
5138 /*!
5139   \property QQuickItem::verticalCenter
5140   \internal
5141 */
5142
5143 /*!
5144   \property QQuickItem::focus
5145   \internal
5146 */
5147
5148 /*!
5149   \property QQuickItem::transform
5150   \internal
5151 */
5152
5153 /*!
5154   \property QQuickItem::transformOrigin
5155   \internal
5156 */
5157
5158 /*!
5159   \property QQuickItem::activeFocus
5160   \internal
5161 */
5162
5163 /*!
5164   \property QQuickItem::baseline
5165   \internal
5166 */
5167
5168 /*!
5169   \property QQuickItem::data
5170   \internal
5171 */
5172
5173 /*!
5174   \property QQuickItem::resources
5175   \internal
5176 */
5177
5178 /*!
5179   \property QQuickItem::state
5180   \internal
5181 */
5182
5183 /*!
5184   \property QQuickItem::states
5185   \internal
5186 */
5187
5188 /*!
5189   \property QQuickItem::transformOriginPoint
5190   \internal
5191 */
5192
5193 /*!
5194   \property QQuickItem::transitions
5195   \internal
5196 */
5197
5198 bool QQuickItem::event(QEvent *ev)
5199 {
5200 #if 0
5201     if (ev->type() == QEvent::PolishRequest) {
5202         Q_D(QQuickItem);
5203         d->polishScheduled = false;
5204         updatePolish();
5205         return true;
5206     } else {
5207         return QObject::event(ev);
5208     }
5209 #endif
5210     if (ev->type() == QEvent::InputMethodQuery) {
5211         QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
5212         Qt::InputMethodQueries queries = query->queries();
5213         for (uint i = 0; i < 32; ++i) {
5214             Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
5215             if (q) {
5216                 QVariant v = inputMethodQuery(q);
5217                 query->setValue(q, v);
5218             }
5219         }
5220         query->accept();
5221         return true;
5222     } else if (ev->type() == QEvent::InputMethod) {
5223         inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
5224         return true;
5225     }
5226     return QObject::event(ev);
5227 }
5228
5229 #ifndef QT_NO_DEBUG_STREAM
5230 QDebug operator<<(QDebug debug, QQuickItem *item)
5231 {
5232     if (!item) {
5233         debug << "QQuickItem(0)";
5234         return debug;
5235     }
5236
5237     debug << item->metaObject()->className() << "(this =" << ((void*)item)
5238           << ", name=" << item->objectName()
5239           << ", parent =" << ((void*)item->parentItem())
5240           << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
5241           << ", z =" << item->z() << ')';
5242     return debug;
5243 }
5244 #endif
5245
5246 qint64 QQuickItemPrivate::consistentTime = -1;
5247 void QQuickItemPrivate::setConsistentTime(qint64 t)
5248 {
5249     consistentTime = t;
5250 }
5251
5252 class QElapsedTimerConsistentTimeHack
5253 {
5254 public:
5255     void start() {
5256         t1 = QQuickItemPrivate::consistentTime;
5257         t2 = 0;
5258     }
5259     qint64 elapsed() {
5260         return QQuickItemPrivate::consistentTime - t1;
5261     }
5262     qint64 restart() {
5263         qint64 val = QQuickItemPrivate::consistentTime - t1;
5264         t1 = QQuickItemPrivate::consistentTime;
5265         t2 = 0;
5266         return val;
5267     }
5268
5269 private:
5270     qint64 t1;
5271     qint64 t2;
5272 };
5273
5274 void QQuickItemPrivate::start(QElapsedTimer &t)
5275 {
5276     if (QQuickItemPrivate::consistentTime == -1)
5277         t.start();
5278     else
5279         ((QElapsedTimerConsistentTimeHack*)&t)->start();
5280 }
5281
5282 qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
5283 {
5284     if (QQuickItemPrivate::consistentTime == -1)
5285         return t.elapsed();
5286     else
5287         return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
5288 }
5289
5290 qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
5291 {
5292     if (QQuickItemPrivate::consistentTime == -1)
5293         return t.restart();
5294     else
5295         return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
5296 }
5297
5298 /*!
5299     \fn bool QQuickItem::isTextureProvider() const
5300
5301     Returns true if this item is a texture provider. The default
5302     implementation returns false.
5303
5304     This function can be called from any thread.
5305  */
5306
5307 /*!
5308     \fn QSGTextureProvider *QQuickItem::textureProvider() const
5309
5310     Returns the texture provider for an item. The default implementation
5311     returns 0.
5312
5313     This function may only be called on the rendering thread.
5314  */
5315
5316 QT_END_NAMESPACE
5317
5318 #include <moc_qquickitem.cpp>