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