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