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