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