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