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