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