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