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