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