Initial import from the monolithic Qt.
[profile/ivi/qtdeclarative.git] / src / declarative / graphicsitems / qdeclarativeitem.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 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qdeclarativeitem.h"
43
44 #include "private/qdeclarativeevents_p_p.h"
45 #include <private/qdeclarativeengine_p.h>
46 #include <private/qgraphicsitem_p.h>
47 #include <QtDeclarative/private/qdeclarativeitem_p.h>
48
49 #include <qdeclarativeengine.h>
50 #include <qdeclarativeopenmetaobject_p.h>
51 #include <qdeclarativestate_p.h>
52 #include <qdeclarativeview.h>
53 #include <qdeclarativestategroup_p.h>
54 #include <qdeclarativecomponent.h>
55 #include <qdeclarativeinfo.h>
56
57 #include <QDebug>
58 #include <QPen>
59 #include <QEvent>
60 #include <QGraphicsSceneMouseEvent>
61 #include <QtCore/qnumeric.h>
62 #include <QtScript/qscriptengine.h>
63 #include <QtGui/qgraphicstransform.h>
64 #include <qlistmodelinterface_p.h>
65
66 #include <float.h>
67
68 QT_BEGIN_NAMESPACE
69
70 /*!
71     \qmlclass Transform QGraphicsTransform
72     \ingroup qml-transform-elements
73     \since 4.7
74     \brief The Transform elements provide a way of building advanced transformations on Items.
75
76     The Transform element is a base type which cannot be instantiated directly.
77     The following concrete Transform types are available:
78
79     \list
80     \o \l Rotation
81     \o \l Scale
82     \o \l Translate
83     \endlist
84
85     The Transform elements let you create and control advanced transformations that can be configured
86     independently using specialized properties.
87
88     You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
89     one at a time.
90 */
91
92 /*!
93     \qmlclass Translate QDeclarativeTranslate
94     \ingroup qml-transform-elements
95     \since 4.7
96     \brief The Translate object provides a way to move an Item without changing its x or y properties.
97
98     The Translate object provides independent control over position in addition to the Item's x and y properties.
99
100     The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
101     to lay the items out as if they had not been transformed:
102     \qml
103     import QtQuick 1.0
104
105     Row {
106         Rectangle {
107             width: 100; height: 100
108             color: "blue"
109             transform: Translate { y: 20 }
110         }
111         Rectangle {
112             width: 100; height: 100
113             color: "red"
114             transform: Translate { y: -20 }
115         }
116     }
117     \endqml
118
119     \image translate.png
120 */
121
122 /*!
123     \qmlproperty real Translate::x
124
125     The translation along the X axis.
126 */
127
128 /*!
129     \qmlproperty real Translate::y
130
131     The translation along the Y axis.
132 */
133
134 /*!
135     \qmlclass Scale QGraphicsScale
136     \ingroup qml-transform-elements
137     \since 4.7
138     \brief The Scale element provides a way to scale an Item.
139
140     The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
141     it allows a different scale for the x and y axes, and allows the scale to be relative to an
142     arbitrary point.
143
144     The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
145     \qml
146     Rectangle {
147         width: 100; height: 100
148         color: "blue"
149         transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
150     }
151     \endqml
152
153     \sa Rotation, Translate
154 */
155
156 /*!
157     \qmlproperty real Scale::origin.x
158     \qmlproperty real Scale::origin.y
159
160     The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
161     the rest of the item grows). By default the origin is 0, 0.
162 */
163
164 /*!
165     \qmlproperty real Scale::xScale
166
167     The scaling factor for the X axis.
168 */
169
170 /*!
171     \qmlproperty real Scale::yScale
172
173     The scaling factor for the Y axis.
174 */
175
176 /*!
177     \qmlclass Rotation QGraphicsRotation
178     \ingroup qml-transform-elements
179     \since 4.7
180     \brief The Rotation object provides a way to rotate an Item.
181
182     The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
183     Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
184
185     The following example rotates a Rectangle around its interior point 25, 25:
186     \qml
187     Rectangle {
188         width: 100; height: 100
189         color: "blue"
190         transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
191     }
192     \endqml
193
194     Rotation also provides a way to specify 3D-like rotations for Items. For these types of
195     rotations you must specify the axis to rotate around in addition to the origin point.
196
197     The following example shows various 3D-like rotations applied to an \l Image.
198     \snippet doc/src/snippets/declarative/rotation.qml 0
199
200     \image axisrotation.png
201
202     \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
203 */
204
205 /*!
206     \qmlproperty real Rotation::origin.x
207     \qmlproperty real Rotation::origin.y
208
209     The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
210     the rest of the item rotates). By default the origin is 0, 0.
211 */
212
213 /*!
214     \qmlproperty real Rotation::axis.x
215     \qmlproperty real Rotation::axis.y
216     \qmlproperty real Rotation::axis.z
217
218     The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
219     as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
220
221     For a typical 3D-like rotation you will usually specify both the origin and the axis.
222
223     \image 3d-rotation-axis.png
224 */
225
226 /*!
227     \qmlproperty real Rotation::angle
228
229     The angle to rotate, in degrees clockwise.
230 */
231
232 QDeclarativeContents::QDeclarativeContents(QDeclarativeItem *item) : m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
233 {
234     //### optimize
235     connect(this, SIGNAL(rectChanged(QRectF)), m_item, SIGNAL(childrenRectChanged(QRectF)));
236 }
237
238 QDeclarativeContents::~QDeclarativeContents()
239 {
240     QList<QGraphicsItem *> children = m_item->childItems();
241     for (int i = 0; i < children.count(); ++i) {
242         QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i));
243         if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects?
244             continue;
245         QDeclarativeItemPrivate::get(child)->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
246     }
247 }
248
249 QRectF QDeclarativeContents::rectF() const
250 {
251     return QRectF(m_x, m_y, m_width, m_height);
252 }
253
254 void QDeclarativeContents::calcHeight(QDeclarativeItem *changed)
255 {
256     qreal oldy = m_y;
257     qreal oldheight = m_height;
258
259     if (changed) {
260         qreal top = oldy;
261         qreal bottom = oldy + oldheight;
262         qreal y = changed->y();
263         if (y + changed->height() > bottom)
264             bottom = y + changed->height();
265         if (y < top)
266             top = y;
267         m_y = top;
268         m_height = bottom - top;
269     } else {
270         qreal top = FLT_MAX;
271         qreal bottom = 0;
272         QList<QGraphicsItem *> children = m_item->childItems();
273         for (int i = 0; i < children.count(); ++i) {
274             QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i));
275             if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects?
276                 continue;
277             qreal y = child->y();
278             if (y + child->height() > bottom)
279                 bottom = y + child->height();
280             if (y < top)
281                 top = y;
282         }
283         if (!children.isEmpty())
284             m_y = top;
285         m_height = qMax(bottom - top, qreal(0.0));
286     }
287
288     if (m_height != oldheight || m_y != oldy)
289         emit rectChanged(rectF());
290 }
291
292 void QDeclarativeContents::calcWidth(QDeclarativeItem *changed)
293 {
294     qreal oldx = m_x;
295     qreal oldwidth = m_width;
296
297     if (changed) {
298         qreal left = oldx;
299         qreal right = oldx + oldwidth;
300         qreal x = changed->x();
301         if (x + changed->width() > right)
302             right = x + changed->width();
303         if (x < left)
304             left = x;
305         m_x = left;
306         m_width = right - left;
307     } else {
308         qreal left = FLT_MAX;
309         qreal right = 0;
310         QList<QGraphicsItem *> children = m_item->childItems();
311         for (int i = 0; i < children.count(); ++i) {
312             QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i));
313             if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects?
314                 continue;
315             qreal x = child->x();
316             if (x + child->width() > right)
317                 right = x + child->width();
318             if (x < left)
319                 left = x;
320         }
321         if (!children.isEmpty())
322             m_x = left;
323         m_width = qMax(right - left, qreal(0.0));
324     }
325
326     if (m_width != oldwidth || m_x != oldx)
327         emit rectChanged(rectF());
328 }
329
330 void QDeclarativeContents::complete()
331 {
332     QList<QGraphicsItem *> children = m_item->childItems();
333     for (int i = 0; i < children.count(); ++i) {
334         QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i));
335         if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects?
336             continue;
337         QDeclarativeItemPrivate::get(child)->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
338         //###what about changes to visibility?
339     }
340
341     calcGeometry();
342 }
343
344 void QDeclarativeContents::itemGeometryChanged(QDeclarativeItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
345 {
346     Q_UNUSED(changed)
347     //### we can only pass changed if the left edge has moved left, or the right edge has moved right
348     if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
349         calcWidth(/*changed*/);
350     if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
351         calcHeight(/*changed*/);
352 }
353
354 void QDeclarativeContents::itemDestroyed(QDeclarativeItem *item)
355 {
356     if (item)
357         QDeclarativeItemPrivate::get(item)->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
358     calcGeometry();
359 }
360
361 void QDeclarativeContents::childRemoved(QDeclarativeItem *item)
362 {
363     if (item)
364         QDeclarativeItemPrivate::get(item)->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
365     calcGeometry();
366 }
367
368 void QDeclarativeContents::childAdded(QDeclarativeItem *item)
369 {
370     if (item)
371         QDeclarativeItemPrivate::get(item)->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
372     calcWidth(item);
373     calcHeight(item);
374 }
375
376 QDeclarativeItemKeyFilter::QDeclarativeItemKeyFilter(QDeclarativeItem *item)
377 : m_processPost(false), m_next(0)
378 {
379     QDeclarativeItemPrivate *p =
380         item?static_cast<QDeclarativeItemPrivate *>(QGraphicsItemPrivate::get(item)):0;
381     if (p) {
382         m_next = p->keyHandler;
383         p->keyHandler = this;
384     }
385 }
386
387 QDeclarativeItemKeyFilter::~QDeclarativeItemKeyFilter()
388 {
389 }
390
391 void QDeclarativeItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
392 {
393     if (m_next) m_next->keyPressed(event, post);
394 }
395
396 void QDeclarativeItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
397 {
398     if (m_next) m_next->keyReleased(event, post);
399 }
400
401 void QDeclarativeItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
402 {
403     if (m_next) m_next->inputMethodEvent(event, post);
404 }
405
406 QVariant QDeclarativeItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
407 {
408     if (m_next) return m_next->inputMethodQuery(query);
409     return QVariant();
410 }
411
412 void QDeclarativeItemKeyFilter::componentComplete()
413 {
414     if (m_next) m_next->componentComplete();
415 }
416
417
418 /*!
419     \qmlclass KeyNavigation QDeclarativeKeyNavigationAttached
420     \ingroup qml-basic-interaction-elements
421     \since 4.7
422     \brief The KeyNavigation attached property supports key navigation by arrow keys.
423
424     Key-based user interfaces commonly allow the use of arrow keys to navigate between
425     focusable items.  The KeyNavigation attached property enables this behavior by providing a
426     convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
427
428     The following example provides key navigation for a 2x2 grid of items:
429
430     \snippet doc/src/snippets/declarative/keynavigation.qml 0
431
432     The top-left item initially receives focus by setting \l {Item::}{focus} to
433     \c true. When an arrow key is pressed, the focus will move to the
434     appropriate item, as defined by the value that has been set for
435     the KeyNavigation \l left, \l right, \l up or \l down properties.
436
437     Note that if a KeyNavigation attached property receives the key press and release
438     events for a requested arrow or tab key, the event is accepted and does not
439     propagate any further.
440
441     By default, KeyNavigation receives key events after the item to which it is attached.
442     If the item accepts the key event, the KeyNavigation attached property will not
443     receive an event for that key.  Setting the \l priority property to
444     \c KeyNavigation.BeforeItem allows the event to be used for key navigation
445     before the item, rather than after.
446
447     If item to which the focus is switching is not enabled or visible, an attempt will
448     be made to skip this item and focus on the next. This is possible if there are
449     a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
450     or visible, they will also be skipped.
451
452     \sa {Keys}{Keys attached property}
453 */
454
455 /*!
456     \qmlproperty Item KeyNavigation::left
457     \qmlproperty Item KeyNavigation::right
458     \qmlproperty Item KeyNavigation::up
459     \qmlproperty Item KeyNavigation::down
460     \qmlproperty Item KeyNavigation::tab
461     \qmlproperty Item KeyNavigation::backtab
462
463     These properties hold the item to assign focus to
464     when the left, right, up or down cursor keys, or the
465     tab key are pressed.
466 */
467
468 /*!
469     \qmlproperty Item KeyNavigation::tab
470     \qmlproperty Item KeyNavigation::backtab
471
472     These properties hold the item to assign focus to
473     when the Tab key or Shift+Tab key combination (Backtab) are pressed.
474 */
475
476 QDeclarativeKeyNavigationAttached::QDeclarativeKeyNavigationAttached(QObject *parent)
477 : QObject(*(new QDeclarativeKeyNavigationAttachedPrivate), parent),
478   QDeclarativeItemKeyFilter(qobject_cast<QDeclarativeItem*>(parent))
479 {
480     m_processPost = true;
481 }
482
483 QDeclarativeKeyNavigationAttached *
484 QDeclarativeKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
485 {
486     return new QDeclarativeKeyNavigationAttached(obj);
487 }
488
489 QDeclarativeItem *QDeclarativeKeyNavigationAttached::left() const
490 {
491     Q_D(const QDeclarativeKeyNavigationAttached);
492     return d->left;
493 }
494
495 void QDeclarativeKeyNavigationAttached::setLeft(QDeclarativeItem *i)
496 {
497     Q_D(QDeclarativeKeyNavigationAttached);
498     if (d->left == i)
499         return;
500     d->left = i;
501     emit leftChanged();
502 }
503
504 QDeclarativeItem *QDeclarativeKeyNavigationAttached::right() const
505 {
506     Q_D(const QDeclarativeKeyNavigationAttached);
507     return d->right;
508 }
509
510 void QDeclarativeKeyNavigationAttached::setRight(QDeclarativeItem *i)
511 {
512     Q_D(QDeclarativeKeyNavigationAttached);
513     if (d->right == i)
514         return;
515     d->right = i;
516     emit rightChanged();
517 }
518
519 QDeclarativeItem *QDeclarativeKeyNavigationAttached::up() const
520 {
521     Q_D(const QDeclarativeKeyNavigationAttached);
522     return d->up;
523 }
524
525 void QDeclarativeKeyNavigationAttached::setUp(QDeclarativeItem *i)
526 {
527     Q_D(QDeclarativeKeyNavigationAttached);
528     if (d->up == i)
529         return;
530     d->up = i;
531     emit upChanged();
532 }
533
534 QDeclarativeItem *QDeclarativeKeyNavigationAttached::down() const
535 {
536     Q_D(const QDeclarativeKeyNavigationAttached);
537     return d->down;
538 }
539
540 void QDeclarativeKeyNavigationAttached::setDown(QDeclarativeItem *i)
541 {
542     Q_D(QDeclarativeKeyNavigationAttached);
543     if (d->down == i)
544         return;
545     d->down = i;
546     emit downChanged();
547 }
548
549 QDeclarativeItem *QDeclarativeKeyNavigationAttached::tab() const
550 {
551     Q_D(const QDeclarativeKeyNavigationAttached);
552     return d->tab;
553 }
554
555 void QDeclarativeKeyNavigationAttached::setTab(QDeclarativeItem *i)
556 {
557     Q_D(QDeclarativeKeyNavigationAttached);
558     if (d->tab == i)
559         return;
560     d->tab = i;
561     emit tabChanged();
562 }
563
564 QDeclarativeItem *QDeclarativeKeyNavigationAttached::backtab() const
565 {
566     Q_D(const QDeclarativeKeyNavigationAttached);
567     return d->backtab;
568 }
569
570 void QDeclarativeKeyNavigationAttached::setBacktab(QDeclarativeItem *i)
571 {
572     Q_D(QDeclarativeKeyNavigationAttached);
573     if (d->backtab == i)
574         return;
575     d->backtab = i;
576     emit backtabChanged();
577 }
578
579 /*!
580     \qmlproperty enumeration KeyNavigation::priority
581
582     This property determines whether the keys are processed before
583     or after the attached item's own key handling.
584
585     \list
586     \o KeyNavigation.BeforeItem - process the key events before normal
587     item key processing.  If the event is used for key navigation, it will be accepted and will not
588     be passed on to the item.
589     \o KeyNavigation.AfterItem (default) - process the key events after normal item key
590     handling.  If the item accepts the key event it will not be
591     handled by the KeyNavigation attached property handler.
592     \endlist
593 */
594 QDeclarativeKeyNavigationAttached::Priority QDeclarativeKeyNavigationAttached::priority() const
595 {
596     return m_processPost ? AfterItem : BeforeItem;
597 }
598
599 void QDeclarativeKeyNavigationAttached::setPriority(Priority order)
600 {
601     bool processPost = order == AfterItem;
602     if (processPost != m_processPost) {
603         m_processPost = processPost;
604         emit priorityChanged();
605     }
606 }
607
608 void QDeclarativeKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
609 {
610     Q_D(QDeclarativeKeyNavigationAttached);
611     event->ignore();
612
613     if (post != m_processPost) {
614         QDeclarativeItemKeyFilter::keyPressed(event, post);
615         return;
616     }
617
618     bool mirror = false;
619     switch(event->key()) {
620     case Qt::Key_Left: {
621         if (QDeclarativeItem *parentItem = qobject_cast<QDeclarativeItem*>(parent()))
622             mirror = QDeclarativeItemPrivate::get(parentItem)->effectiveLayoutMirror;
623         QDeclarativeItem* leftItem = mirror ? d->right : d->left;
624         if (leftItem) {
625             setFocusNavigation(leftItem, mirror ? "right" : "left");
626             event->accept();
627         }
628         break;
629     }
630     case Qt::Key_Right: {
631         if (QDeclarativeItem *parentItem = qobject_cast<QDeclarativeItem*>(parent()))
632             mirror = QDeclarativeItemPrivate::get(parentItem)->effectiveLayoutMirror;
633         QDeclarativeItem* rightItem = mirror ? d->left : d->right;
634         if (rightItem) {
635             setFocusNavigation(rightItem, mirror ? "left" : "right");
636             event->accept();
637         }
638         break;
639     }
640     case Qt::Key_Up:
641         if (d->up) {
642             setFocusNavigation(d->up, "up");
643             event->accept();
644         }
645         break;
646     case Qt::Key_Down:
647         if (d->down) {
648             setFocusNavigation(d->down, "down");
649             event->accept();
650         }
651         break;
652     case Qt::Key_Tab:
653         if (d->tab) {
654             setFocusNavigation(d->tab, "tab");
655             event->accept();
656         }
657         break;
658     case Qt::Key_Backtab:
659         if (d->backtab) {
660             setFocusNavigation(d->backtab, "backtab");
661             event->accept();
662         }
663         break;
664     default:
665         break;
666     }
667
668     if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyPressed(event, post);
669 }
670
671 void QDeclarativeKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
672 {
673     Q_D(QDeclarativeKeyNavigationAttached);
674     event->ignore();
675
676     if (post != m_processPost) {
677         QDeclarativeItemKeyFilter::keyReleased(event, post);
678         return;
679     }
680
681     bool mirror = false;
682     switch(event->key()) {
683     case Qt::Key_Left:
684         if (QDeclarativeItem *parentItem = qobject_cast<QDeclarativeItem*>(parent()))
685             mirror = QDeclarativeItemPrivate::get(parentItem)->effectiveLayoutMirror;
686         if (mirror ? d->right : d->left)
687             event->accept();
688         break;
689     case Qt::Key_Right:
690         if (QDeclarativeItem *parentItem = qobject_cast<QDeclarativeItem*>(parent()))
691             mirror = QDeclarativeItemPrivate::get(parentItem)->effectiveLayoutMirror;
692         if (mirror ? d->left : d->right)
693             event->accept();
694         break;
695     case Qt::Key_Up:
696         if (d->up) {
697             event->accept();
698         }
699         break;
700     case Qt::Key_Down:
701         if (d->down) {
702             event->accept();
703         }
704         break;
705     case Qt::Key_Tab:
706         if (d->tab) {
707             event->accept();
708         }
709         break;
710     case Qt::Key_Backtab:
711         if (d->backtab) {
712             event->accept();
713         }
714         break;
715     default:
716         break;
717     }
718
719     if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyReleased(event, post);
720 }
721
722 void QDeclarativeKeyNavigationAttached::setFocusNavigation(QDeclarativeItem *currentItem, const char *dir)
723 {
724     QDeclarativeItem *initialItem = currentItem;
725     bool isNextItem = false;
726     do {
727         isNextItem = false;
728         if (currentItem->isVisible() && currentItem->isEnabled()) {
729             currentItem->setFocus(true);
730         } else {
731             QObject *attached =
732                 qmlAttachedPropertiesObject<QDeclarativeKeyNavigationAttached>(currentItem, false);
733             if (attached) {
734                 QDeclarativeItem *tempItem = qvariant_cast<QDeclarativeItem*>(attached->property(dir));
735                 if (tempItem) {
736                     currentItem = tempItem;
737                     isNextItem = true;
738                 }
739             }
740         }
741     }
742     while (currentItem != initialItem && isNextItem);
743 }
744
745 /*!
746     \qmlclass LayoutMirroring QDeclarativeLayoutMirroringAttached
747     \since QtQuick 1.1
748     \ingroup qml-utility-elements
749     \brief The LayoutMirroring attached property is used to mirror layout behavior.
750
751     The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
752     \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
753     and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
754     anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
755     horizontal layout of child items.
756
757     Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
758     only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
759     behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
760     for an item, mirroring is not enabled.
761
762     The following example shows mirroring in action. The \l Row below is specified as being anchored
763     to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
764     reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
765     from left to right by default, they are now positioned from right to left instead, as demonstrated
766     by the numbering and opacity of the items:
767
768     \snippet doc/src/snippets/declarative/layoutmirroring.qml 0
769
770     \image layoutmirroring.png
771
772     Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
773     layout versions of an application to target different language areas. The \l childrenInherit
774     property allows layout mirroring to be applied without manually setting layout configurations
775     for every item in an application. Keep in mind, however, that mirroring does not affect any
776     positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
777     mirroring enabled, it will often be necessary to apply some layout fixes to support the
778     desired layout direction. Also, it may be necessary to disable the mirroring of individual
779     child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
780     mirroring is not the desired behavior, or if the child item already implements mirroring in
781     some custom way.
782
783     See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
784     other related features to implement right-to-left support for an application.
785 */
786
787 /*!
788     \qmlproperty bool LayoutMirroring::enabled
789
790     This property holds whether the item's layout is mirrored horizontally. Setting this to true
791     horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
792     and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
793     (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
794     this also mirrors the horizontal layout direction of the item.
795
796     The default value is false.
797 */
798
799 /*!
800     \qmlproperty bool LayoutMirroring::childrenInherit
801
802     This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
803     is inherited by its children.
804
805     The default value is false.
806 */
807
808 QDeclarativeLayoutMirroringAttached::QDeclarativeLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
809 {
810     if (QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent)) {
811         itemPrivate = QDeclarativeItemPrivate::get(item);
812         itemPrivate->attachedLayoutDirection = this;
813     } else
814         qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
815 }
816
817 QDeclarativeLayoutMirroringAttached * QDeclarativeLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
818 {
819     return new QDeclarativeLayoutMirroringAttached(object);
820 }
821
822 bool QDeclarativeLayoutMirroringAttached::enabled() const
823 {
824     return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
825 }
826
827 void QDeclarativeLayoutMirroringAttached::setEnabled(bool enabled)
828 {
829     if (!itemPrivate)
830         return;
831
832     itemPrivate->isMirrorImplicit = false;
833     if (enabled != itemPrivate->effectiveLayoutMirror) {
834         itemPrivate->setLayoutMirror(enabled);
835         if (itemPrivate->inheritMirrorFromItem)
836              itemPrivate->resolveLayoutMirror();
837     }
838 }
839
840 void QDeclarativeLayoutMirroringAttached::resetEnabled()
841 {
842     if (itemPrivate && !itemPrivate->isMirrorImplicit) {
843         itemPrivate->isMirrorImplicit = true;
844         itemPrivate->resolveLayoutMirror();
845     }
846 }
847
848 bool QDeclarativeLayoutMirroringAttached::childrenInherit() const
849 {
850     return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
851 }
852
853 void QDeclarativeLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
854     if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
855         itemPrivate->inheritMirrorFromItem = childrenInherit;
856         itemPrivate->resolveLayoutMirror();
857         childrenInheritChanged();
858     }
859 }
860
861 void QDeclarativeItemPrivate::resolveLayoutMirror()
862 {
863     Q_Q(QDeclarativeItem);
864     if (QDeclarativeItem *parentItem = q->parentItem()) {
865         QDeclarativeItemPrivate *parentPrivate = QDeclarativeItemPrivate::get(parentItem);
866         setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
867     } else {
868         setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
869     }
870 }
871
872 void QDeclarativeItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
873 {
874     inherit = inherit || inheritMirrorFromItem;
875     if (!isMirrorImplicit && inheritMirrorFromItem)
876         mirror = effectiveLayoutMirror;
877     if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
878         return;
879
880     inheritMirrorFromParent = inherit;
881     inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
882
883     if (isMirrorImplicit)
884         setLayoutMirror(inherit ? inheritedLayoutMirror : false);
885     for (int i = 0; i < children.count(); ++i) {
886         if (QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i))) {
887             QDeclarativeItemPrivate *childPrivate = QDeclarativeItemPrivate::get(child);
888             childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
889         }
890     }
891 }
892
893 void QDeclarativeItemPrivate::setLayoutMirror(bool mirror)
894 {
895     if (mirror != effectiveLayoutMirror) {
896         effectiveLayoutMirror = mirror;
897         if (_anchors) {
898             _anchors->d_func()->fillChanged();
899             _anchors->d_func()->centerInChanged();
900             _anchors->d_func()->updateHorizontalAnchors();
901             emit _anchors->mirroredChanged();
902         }
903         mirrorChange();
904         if (attachedLayoutDirection) {
905             emit attachedLayoutDirection->enabledChanged();
906         }
907     }
908 }
909
910 /*!
911     \qmlclass Keys QDeclarativeKeysAttached
912     \ingroup qml-basic-interaction-elements
913     \since 4.7
914     \brief The Keys attached property provides key handling to Items.
915
916     All visual primitives support key handling via the Keys
917     attached property.  Keys can be handled via the onPressed
918     and onReleased signal properties.
919
920     The signal properties have a \l KeyEvent parameter, named
921     \e event which contains details of the event.  If a key is
922     handled \e event.accepted should be set to true to prevent the
923     event from propagating up the item hierarchy.
924
925     \section1 Example Usage
926
927     The following example shows how the general onPressed handler can
928     be used to test for a certain key; in this case, the left cursor
929     key:
930
931     \snippet doc/src/snippets/declarative/keys/keys-pressed.qml key item
932
933     Some keys may alternatively be handled via specific signal properties,
934     for example \e onSelectPressed.  These handlers automatically set
935     \e event.accepted to true.
936
937     \snippet doc/src/snippets/declarative/keys/keys-handler.qml key item
938
939     See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
940
941     \section1 Key Handling Priorities
942
943     The Keys attached property can be configured to handle key events
944     before or after the item it is attached to. This makes it possible
945     to intercept events in order to override an item's default behavior,
946     or act as a fallback for keys not handled by the item.
947
948     If \l priority is Keys.BeforeItem (default) the order of key event processing is:
949
950     \list 1
951     \o Items specified in \c forwardTo
952     \o specific key handlers, e.g. onReturnPressed
953     \o onKeyPress, onKeyRelease handlers
954     \o Item specific key handling, e.g. TextInput key handling
955     \o parent item
956     \endlist
957
958     If priority is Keys.AfterItem the order of key event processing is:
959
960     \list 1
961     \o Item specific key handling, e.g. TextInput key handling
962     \o Items specified in \c forwardTo
963     \o specific key handlers, e.g. onReturnPressed
964     \o onKeyPress, onKeyRelease handlers
965     \o parent item
966     \endlist
967
968     If the event is accepted during any of the above steps, key
969     propagation stops.
970
971     \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
972 */
973
974 /*!
975     \qmlproperty bool Keys::enabled
976
977     This flags enables key handling if true (default); otherwise
978     no key handlers will be called.
979 */
980
981 /*!
982     \qmlproperty enumeration Keys::priority
983
984     This property determines whether the keys are processed before
985     or after the attached item's own key handling.
986
987     \list
988     \o Keys.BeforeItem (default) - process the key events before normal
989     item key processing.  If the event is accepted it will not
990     be passed on to the item.
991     \o Keys.AfterItem - process the key events after normal item key
992     handling.  If the item accepts the key event it will not be
993     handled by the Keys attached property handler.
994     \endlist
995 */
996
997 /*!
998     \qmlproperty list<Object> Keys::forwardTo
999
1000     This property provides a way to forward key presses, key releases, and keyboard input
1001     coming from input methods to other items. This can be useful when you want
1002     one item to handle some keys (e.g. the up and down arrow keys), and another item to
1003     handle other keys (e.g. the left and right arrow keys).  Once an item that has been
1004     forwarded keys accepts the event it is no longer forwarded to items later in the
1005     list.
1006
1007     This example forwards key events to two lists:
1008     \qml
1009     Item {
1010         ListView {
1011             id: list1
1012             // ...
1013         }
1014         ListView {
1015             id: list2
1016             // ...
1017         }
1018         Keys.forwardTo: [list1, list2]
1019         focus: true
1020     }
1021     \endqml
1022 */
1023
1024 /*!
1025     \qmlsignal Keys::onPressed(KeyEvent event)
1026
1027     This handler is called when a key has been pressed. The \a event
1028     parameter provides information about the event.
1029 */
1030
1031 /*!
1032     \qmlsignal Keys::onReleased(KeyEvent event)
1033
1034     This handler is called when a key has been released. The \a event
1035     parameter provides information about the event.
1036 */
1037
1038 /*!
1039     \qmlsignal Keys::onDigit0Pressed(KeyEvent event)
1040
1041     This handler is called when the digit '0' has been pressed. The \a event
1042     parameter provides information about the event.
1043 */
1044
1045 /*!
1046     \qmlsignal Keys::onDigit1Pressed(KeyEvent event)
1047
1048     This handler is called when the digit '1' has been pressed. The \a event
1049     parameter provides information about the event.
1050 */
1051
1052 /*!
1053     \qmlsignal Keys::onDigit2Pressed(KeyEvent event)
1054
1055     This handler is called when the digit '2' has been pressed. The \a event
1056     parameter provides information about the event.
1057 */
1058
1059 /*!
1060     \qmlsignal Keys::onDigit3Pressed(KeyEvent event)
1061
1062     This handler is called when the digit '3' has been pressed. The \a event
1063     parameter provides information about the event.
1064 */
1065
1066 /*!
1067     \qmlsignal Keys::onDigit4Pressed(KeyEvent event)
1068
1069     This handler is called when the digit '4' has been pressed. The \a event
1070     parameter provides information about the event.
1071 */
1072
1073 /*!
1074     \qmlsignal Keys::onDigit5Pressed(KeyEvent event)
1075
1076     This handler is called when the digit '5' has been pressed. The \a event
1077     parameter provides information about the event.
1078 */
1079
1080 /*!
1081     \qmlsignal Keys::onDigit6Pressed(KeyEvent event)
1082
1083     This handler is called when the digit '6' has been pressed. The \a event
1084     parameter provides information about the event.
1085 */
1086
1087 /*!
1088     \qmlsignal Keys::onDigit7Pressed(KeyEvent event)
1089
1090     This handler is called when the digit '7' has been pressed. The \a event
1091     parameter provides information about the event.
1092 */
1093
1094 /*!
1095     \qmlsignal Keys::onDigit8Pressed(KeyEvent event)
1096
1097     This handler is called when the digit '8' has been pressed. The \a event
1098     parameter provides information about the event.
1099 */
1100
1101 /*!
1102     \qmlsignal Keys::onDigit9Pressed(KeyEvent event)
1103
1104     This handler is called when the digit '9' has been pressed. The \a event
1105     parameter provides information about the event.
1106 */
1107
1108 /*!
1109     \qmlsignal Keys::onLeftPressed(KeyEvent event)
1110
1111     This handler is called when the Left arrow has been pressed. The \a event
1112     parameter provides information about the event.
1113 */
1114
1115 /*!
1116     \qmlsignal Keys::onRightPressed(KeyEvent event)
1117
1118     This handler is called when the Right arrow has been pressed. The \a event
1119     parameter provides information about the event.
1120 */
1121
1122 /*!
1123     \qmlsignal Keys::onUpPressed(KeyEvent event)
1124
1125     This handler is called when the Up arrow has been pressed. The \a event
1126     parameter provides information about the event.
1127 */
1128
1129 /*!
1130     \qmlsignal Keys::onDownPressed(KeyEvent event)
1131
1132     This handler is called when the Down arrow has been pressed. The \a event
1133     parameter provides information about the event.
1134 */
1135
1136 /*!
1137     \qmlsignal Keys::onTabPressed(KeyEvent event)
1138
1139     This handler is called when the Tab key has been pressed. The \a event
1140     parameter provides information about the event.
1141 */
1142
1143 /*!
1144     \qmlsignal Keys::onBacktabPressed(KeyEvent event)
1145
1146     This handler is called when the Shift+Tab key combination (Backtab) has
1147     been pressed. The \a event parameter provides information about the event.
1148 */
1149
1150 /*!
1151     \qmlsignal Keys::onAsteriskPressed(KeyEvent event)
1152
1153     This handler is called when the Asterisk '*' has been pressed. The \a event
1154     parameter provides information about the event.
1155 */
1156
1157 /*!
1158     \qmlsignal Keys::onEscapePressed(KeyEvent event)
1159
1160     This handler is called when the Escape key has been pressed. The \a event
1161     parameter provides information about the event.
1162 */
1163
1164 /*!
1165     \qmlsignal Keys::onReturnPressed(KeyEvent event)
1166
1167     This handler is called when the Return key has been pressed. The \a event
1168     parameter provides information about the event.
1169 */
1170
1171 /*!
1172     \qmlsignal Keys::onEnterPressed(KeyEvent event)
1173
1174     This handler is called when the Enter key has been pressed. The \a event
1175     parameter provides information about the event.
1176 */
1177
1178 /*!
1179     \qmlsignal Keys::onDeletePressed(KeyEvent event)
1180
1181     This handler is called when the Delete key has been pressed. The \a event
1182     parameter provides information about the event.
1183 */
1184
1185 /*!
1186     \qmlsignal Keys::onSpacePressed(KeyEvent event)
1187
1188     This handler is called when the Space key has been pressed. The \a event
1189     parameter provides information about the event.
1190 */
1191
1192 /*!
1193     \qmlsignal Keys::onBackPressed(KeyEvent event)
1194
1195     This handler is called when the Back key has been pressed. The \a event
1196     parameter provides information about the event.
1197 */
1198
1199 /*!
1200     \qmlsignal Keys::onCancelPressed(KeyEvent event)
1201
1202     This handler is called when the Cancel key has been pressed. The \a event
1203     parameter provides information about the event.
1204 */
1205
1206 /*!
1207     \qmlsignal Keys::onSelectPressed(KeyEvent event)
1208
1209     This handler is called when the Select key has been pressed. The \a event
1210     parameter provides information about the event.
1211 */
1212
1213 /*!
1214     \qmlsignal Keys::onYesPressed(KeyEvent event)
1215
1216     This handler is called when the Yes key has been pressed. The \a event
1217     parameter provides information about the event.
1218 */
1219
1220 /*!
1221     \qmlsignal Keys::onNoPressed(KeyEvent event)
1222
1223     This handler is called when the No key has been pressed. The \a event
1224     parameter provides information about the event.
1225 */
1226
1227 /*!
1228     \qmlsignal Keys::onContext1Pressed(KeyEvent event)
1229
1230     This handler is called when the Context1 key has been pressed. The \a event
1231     parameter provides information about the event.
1232 */
1233
1234 /*!
1235     \qmlsignal Keys::onContext2Pressed(KeyEvent event)
1236
1237     This handler is called when the Context2 key has been pressed. The \a event
1238     parameter provides information about the event.
1239 */
1240
1241 /*!
1242     \qmlsignal Keys::onContext3Pressed(KeyEvent event)
1243
1244     This handler is called when the Context3 key has been pressed. The \a event
1245     parameter provides information about the event.
1246 */
1247
1248 /*!
1249     \qmlsignal Keys::onContext4Pressed(KeyEvent event)
1250
1251     This handler is called when the Context4 key has been pressed. The \a event
1252     parameter provides information about the event.
1253 */
1254
1255 /*!
1256     \qmlsignal Keys::onCallPressed(KeyEvent event)
1257
1258     This handler is called when the Call key has been pressed. The \a event
1259     parameter provides information about the event.
1260 */
1261
1262 /*!
1263     \qmlsignal Keys::onHangupPressed(KeyEvent event)
1264
1265     This handler is called when the Hangup key has been pressed. The \a event
1266     parameter provides information about the event.
1267 */
1268
1269 /*!
1270     \qmlsignal Keys::onFlipPressed(KeyEvent event)
1271
1272     This handler is called when the Flip key has been pressed. The \a event
1273     parameter provides information about the event.
1274 */
1275
1276 /*!
1277     \qmlsignal Keys::onMenuPressed(KeyEvent event)
1278
1279     This handler is called when the Menu key has been pressed. The \a event
1280     parameter provides information about the event.
1281 */
1282
1283 /*!
1284     \qmlsignal Keys::onVolumeUpPressed(KeyEvent event)
1285
1286     This handler is called when the VolumeUp key has been pressed. The \a event
1287     parameter provides information about the event.
1288 */
1289
1290 /*!
1291     \qmlsignal Keys::onVolumeDownPressed(KeyEvent event)
1292
1293     This handler is called when the VolumeDown key has been pressed. The \a event
1294     parameter provides information about the event.
1295 */
1296
1297 const QDeclarativeKeysAttached::SigMap QDeclarativeKeysAttached::sigMap[] = {
1298     { Qt::Key_Left, "leftPressed" },
1299     { Qt::Key_Right, "rightPressed" },
1300     { Qt::Key_Up, "upPressed" },
1301     { Qt::Key_Down, "downPressed" },
1302     { Qt::Key_Tab, "tabPressed" },
1303     { Qt::Key_Backtab, "backtabPressed" },
1304     { Qt::Key_Asterisk, "asteriskPressed" },
1305     { Qt::Key_NumberSign, "numberSignPressed" },
1306     { Qt::Key_Escape, "escapePressed" },
1307     { Qt::Key_Return, "returnPressed" },
1308     { Qt::Key_Enter, "enterPressed" },
1309     { Qt::Key_Delete, "deletePressed" },
1310     { Qt::Key_Space, "spacePressed" },
1311     { Qt::Key_Back, "backPressed" },
1312     { Qt::Key_Cancel, "cancelPressed" },
1313     { Qt::Key_Select, "selectPressed" },
1314     { Qt::Key_Yes, "yesPressed" },
1315     { Qt::Key_No, "noPressed" },
1316     { Qt::Key_Context1, "context1Pressed" },
1317     { Qt::Key_Context2, "context2Pressed" },
1318     { Qt::Key_Context3, "context3Pressed" },
1319     { Qt::Key_Context4, "context4Pressed" },
1320     { Qt::Key_Call, "callPressed" },
1321     { Qt::Key_Hangup, "hangupPressed" },
1322     { Qt::Key_Flip, "flipPressed" },
1323     { Qt::Key_Menu, "menuPressed" },
1324     { Qt::Key_VolumeUp, "volumeUpPressed" },
1325     { Qt::Key_VolumeDown, "volumeDownPressed" },
1326     { 0, 0 }
1327 };
1328
1329 bool QDeclarativeKeysAttachedPrivate::isConnected(const char *signalName)
1330 {
1331     return isSignalConnected(signalIndex(signalName));
1332 }
1333
1334 QDeclarativeKeysAttached::QDeclarativeKeysAttached(QObject *parent)
1335 : QObject(*(new QDeclarativeKeysAttachedPrivate), parent),
1336   QDeclarativeItemKeyFilter(qobject_cast<QDeclarativeItem*>(parent))
1337 {
1338     Q_D(QDeclarativeKeysAttached);
1339     m_processPost = false;
1340     d->item = qobject_cast<QDeclarativeItem*>(parent);
1341 }
1342
1343 QDeclarativeKeysAttached::~QDeclarativeKeysAttached()
1344 {
1345 }
1346
1347 QDeclarativeKeysAttached::Priority QDeclarativeKeysAttached::priority() const
1348 {
1349     return m_processPost ? AfterItem : BeforeItem;
1350 }
1351
1352 void QDeclarativeKeysAttached::setPriority(Priority order)
1353 {
1354     bool processPost = order == AfterItem;
1355     if (processPost != m_processPost) {
1356         m_processPost = processPost;
1357         emit priorityChanged();
1358     }
1359 }
1360
1361 void QDeclarativeKeysAttached::componentComplete()
1362 {
1363     Q_D(QDeclarativeKeysAttached);
1364     if (d->item) {
1365         for (int ii = 0; ii < d->targets.count(); ++ii) {
1366             QGraphicsItem *targetItem = d->finalFocusProxy(d->targets.at(ii));
1367             if (targetItem && (targetItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) {
1368                 d->item->setFlag(QGraphicsItem::ItemAcceptsInputMethod);
1369                 break;
1370             }
1371         }
1372     }
1373 }
1374
1375 void QDeclarativeKeysAttached::keyPressed(QKeyEvent *event, bool post)
1376 {
1377     Q_D(QDeclarativeKeysAttached);
1378     if (post != m_processPost || !d->enabled || d->inPress) {
1379         event->ignore();
1380         QDeclarativeItemKeyFilter::keyPressed(event, post);
1381         return;
1382     }
1383
1384     // first process forwards
1385     if (d->item && d->item->scene()) {
1386         d->inPress = true;
1387         for (int ii = 0; ii < d->targets.count(); ++ii) {
1388             QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii));
1389             if (i && i->isVisible()) {
1390                 d->item->scene()->sendEvent(i, event);
1391                 if (event->isAccepted()) {
1392                     d->inPress = false;
1393                     return;
1394                 }
1395             }
1396         }
1397         d->inPress = false;
1398     }
1399
1400     QDeclarativeKeyEvent ke(*event);
1401     QByteArray keySignal = keyToSignal(event->key());
1402     if (!keySignal.isEmpty()) {
1403         keySignal += "(QDeclarativeKeyEvent*)";
1404         if (d->isConnected(keySignal)) {
1405             // If we specifically handle a key then default to accepted
1406             ke.setAccepted(true);
1407             int idx = QDeclarativeKeysAttached::staticMetaObject.indexOfSignal(keySignal);
1408             metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QDeclarativeKeyEvent*, &ke));
1409         }
1410     }
1411     if (!ke.isAccepted())
1412         emit pressed(&ke);
1413     event->setAccepted(ke.isAccepted());
1414
1415     if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyPressed(event, post);
1416 }
1417
1418 void QDeclarativeKeysAttached::keyReleased(QKeyEvent *event, bool post)
1419 {
1420     Q_D(QDeclarativeKeysAttached);
1421     if (post != m_processPost || !d->enabled || d->inRelease) {
1422         event->ignore();
1423         QDeclarativeItemKeyFilter::keyReleased(event, post);
1424         return;
1425     }
1426
1427     if (d->item && d->item->scene()) {
1428         d->inRelease = true;
1429         for (int ii = 0; ii < d->targets.count(); ++ii) {
1430             QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii));
1431             if (i && i->isVisible()) {
1432                 d->item->scene()->sendEvent(i, event);
1433                 if (event->isAccepted()) {
1434                     d->inRelease = false;
1435                     return;
1436                 }
1437             }
1438         }
1439         d->inRelease = false;
1440     }
1441
1442     QDeclarativeKeyEvent ke(*event);
1443     emit released(&ke);
1444     event->setAccepted(ke.isAccepted());
1445
1446     if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyReleased(event, post);
1447 }
1448
1449 void QDeclarativeKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
1450 {
1451     Q_D(QDeclarativeKeysAttached);
1452     if (post == m_processPost && d->item && !d->inIM && d->item->scene()) {
1453         d->inIM = true;
1454         for (int ii = 0; ii < d->targets.count(); ++ii) {
1455             QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii));
1456             if (i && i->isVisible() && (i->flags() & QGraphicsItem::ItemAcceptsInputMethod)) {
1457                 d->item->scene()->sendEvent(i, event);
1458                 if (event->isAccepted()) {
1459                     d->imeItem = i;
1460                     d->inIM = false;
1461                     return;
1462                 }
1463             }
1464         }
1465         d->inIM = false;
1466     }
1467     if (!event->isAccepted()) QDeclarativeItemKeyFilter::inputMethodEvent(event, post);
1468 }
1469
1470 class QDeclarativeItemAccessor : public QGraphicsItem
1471 {
1472 public:
1473     QVariant doInputMethodQuery(Qt::InputMethodQuery query) const {
1474         return QGraphicsItem::inputMethodQuery(query);
1475     }
1476 };
1477
1478 QVariant QDeclarativeKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
1479 {
1480     Q_D(const QDeclarativeKeysAttached);
1481     if (d->item) {
1482         for (int ii = 0; ii < d->targets.count(); ++ii) {
1483                 QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii));
1484             if (i && i->isVisible() && (i->flags() & QGraphicsItem::ItemAcceptsInputMethod) && i == d->imeItem) { //### how robust is i == d->imeItem check?
1485                 QVariant v = static_cast<QDeclarativeItemAccessor *>(i)->doInputMethodQuery(query);
1486                 if (v.userType() == QVariant::RectF)
1487                     v = d->item->mapRectFromItem(i, v.toRectF());  //### cost?
1488                 return v;
1489             }
1490         }
1491     }
1492     return QDeclarativeItemKeyFilter::inputMethodQuery(query);
1493 }
1494
1495 QDeclarativeKeysAttached *QDeclarativeKeysAttached::qmlAttachedProperties(QObject *obj)
1496 {
1497     return new QDeclarativeKeysAttached(obj);
1498 }
1499
1500 /*!
1501     \class QDeclarativeItem
1502     \since 4.7
1503     \brief The QDeclarativeItem class provides the most basic of all visual items in QML.
1504
1505     All visual items in Qt Declarative inherit from QDeclarativeItem.  Although QDeclarativeItem
1506     has no visual appearance, it defines all the properties that are
1507     common across visual items - such as the x and y position, the
1508     width and height, \l {anchor-layout}{anchoring} and key handling.
1509
1510     You can subclass QDeclarativeItem to provide your own custom visual item that inherits
1511     these features. Note that, because it does not draw anything, QDeclarativeItem sets the
1512     QGraphicsItem::ItemHasNoContents flag. If you subclass QDeclarativeItem to create a visual
1513     item, you will need to unset this flag.
1514
1515 */
1516
1517 /*!
1518     \qmlclass Item QDeclarativeItem
1519     \ingroup qml-basic-visual-elements
1520     \since 4.7
1521     \brief The Item is the most basic of all visual items in QML.
1522
1523     All visual items in Qt Declarative inherit from Item.  Although Item
1524     has no visual appearance, it defines all the properties that are
1525     common across visual items - such as the x and y position, the
1526     width and height, \l {anchor-layout}{anchoring} and key handling.
1527
1528     Item is also useful for grouping items together.
1529
1530     \qml
1531     Item {
1532         Image {
1533             source: "tile.png"
1534         }
1535         Image {
1536             x: 80
1537             width: 100
1538             height: 100
1539             source: "tile.png"
1540         }
1541         Image {
1542             x: 190
1543             width: 100
1544             height: 100
1545             fillMode: Image.Tile
1546             source: "tile.png"
1547         }
1548     }
1549     \endqml
1550
1551
1552     \section1 Key Handling
1553
1554     Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
1555     attached property.  The \e Keys attached property provides basic handlers such
1556     as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
1557     as well as handlers for specific keys, such as
1558     \l {Keys::onCancelPressed}{onCancelPressed}.  The example below
1559     assigns \l {qmlfocus}{focus} to the item and handles
1560     the Left key via the general \e onPressed handler and the Select key via the
1561     onSelectPressed handler:
1562
1563     \qml
1564     Item {
1565         focus: true
1566         Keys.onPressed: {
1567             if (event.key == Qt.Key_Left) {
1568                 console.log("move left");
1569                 event.accepted = true;
1570             }
1571         }
1572         Keys.onSelectPressed: console.log("Selected");
1573     }
1574     \endqml
1575
1576     See the \l {Keys}{Keys} attached property for detailed documentation.
1577
1578     \section1 Layout Mirroring
1579
1580     Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
1581
1582 */
1583
1584 /*!
1585     \fn void QDeclarativeItem::childrenRectChanged(const QRectF &)
1586     \internal
1587 */
1588
1589 /*!
1590     \fn void QDeclarativeItem::baselineOffsetChanged(qreal)
1591     \internal
1592 */
1593
1594 /*!
1595     \fn void QDeclarativeItem::stateChanged(const QString &state)
1596     \internal
1597 */
1598
1599 /*!
1600     \fn void QDeclarativeItem::parentChanged(QDeclarativeItem *)
1601     \internal
1602 */
1603
1604 /*!
1605     \fn void QDeclarativeItem::smoothChanged(bool)
1606     \internal
1607 */
1608
1609 /*!
1610     \fn void QDeclarativeItem::clipChanged(bool)
1611     \internal
1612 */
1613
1614 /*! \fn void QDeclarativeItem::transformOriginChanged(TransformOrigin)
1615   \internal
1616 */
1617
1618 /*!
1619     \fn void QDeclarativeItem::focusChanged(bool)
1620     \internal
1621 */
1622
1623 /*!
1624     \fn void QDeclarativeItem::activeFocusChanged(bool)
1625     \internal
1626 */
1627
1628 // ### Must fix
1629 struct RegisterAnchorLineAtStartup {
1630     RegisterAnchorLineAtStartup() {
1631         qRegisterMetaType<QDeclarativeAnchorLine>("QDeclarativeAnchorLine");
1632     }
1633 };
1634 static RegisterAnchorLineAtStartup registerAnchorLineAtStartup;
1635
1636
1637 /*!
1638     \fn QDeclarativeItem::QDeclarativeItem(QDeclarativeItem *parent)
1639
1640     Constructs a QDeclarativeItem with the given \a parent.
1641 */
1642 QDeclarativeItem::QDeclarativeItem(QDeclarativeItem* parent)
1643   : QGraphicsObject(*(new QDeclarativeItemPrivate), parent, 0)
1644 {
1645     Q_D(QDeclarativeItem);
1646     d->init(parent);
1647 }
1648
1649 /*! \internal
1650 */
1651 QDeclarativeItem::QDeclarativeItem(QDeclarativeItemPrivate &dd, QDeclarativeItem *parent)
1652   : QGraphicsObject(dd, parent, 0)
1653 {
1654     Q_D(QDeclarativeItem);
1655     d->init(parent);
1656 }
1657
1658 /*!
1659     Destroys the QDeclarativeItem.
1660 */
1661 QDeclarativeItem::~QDeclarativeItem()
1662 {
1663     Q_D(QDeclarativeItem);
1664     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1665         QDeclarativeAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1666         if (anchor)
1667             anchor->clearItem(this);
1668     }
1669     if (!d->parent || (parentItem() && !parentItem()->QGraphicsItem::d_ptr->inDestructor)) {
1670         for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
1671             QDeclarativeAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
1672             if (anchor && anchor->item && anchor->item->parentItem() != this) //child will be deleted anyway
1673                 anchor->updateOnComplete();
1674         }
1675     }
1676     for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
1677         const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
1678         if (change.types & QDeclarativeItemPrivate::Destroyed)
1679             change.listener->itemDestroyed(this);
1680     }
1681     d->changeListeners.clear();
1682     delete d->_anchorLines; d->_anchorLines = 0;
1683     delete d->_anchors; d->_anchors = 0;
1684     delete d->_stateGroup; d->_stateGroup = 0;
1685     delete d->_contents; d->_contents = 0;
1686 }
1687
1688 /*!
1689     \qmlproperty enumeration Item::transformOrigin
1690     This property holds the origin point around which scale and rotation transform.
1691
1692     Nine transform origins are available, as shown in the image below.
1693
1694     \image declarative-transformorigin.png
1695
1696     This example rotates an image around its bottom-right corner.
1697     \qml
1698     Image {
1699         source: "myimage.png"
1700         transformOrigin: Item.BottomRight
1701         rotation: 45
1702     }
1703     \endqml
1704
1705     The default transform origin is \c Item.Center.
1706
1707     To set an arbitrary transform origin point use the \l Scale or \l Rotation
1708     transform elements.
1709 */
1710
1711 /*!
1712     \qmlproperty Item Item::parent
1713     This property holds the parent of the item.
1714 */
1715
1716 /*!
1717     \property QDeclarativeItem::parent
1718     This property holds the parent of the item.
1719 */
1720 void QDeclarativeItem::setParentItem(QDeclarativeItem *parent)
1721 {
1722     QGraphicsObject::setParentItem(parent);
1723 }
1724
1725 /*!
1726     Returns the QDeclarativeItem parent of this item.
1727 */
1728 QDeclarativeItem *QDeclarativeItem::parentItem() const
1729 {
1730     return qobject_cast<QDeclarativeItem *>(QGraphicsObject::parentItem());
1731 }
1732
1733 /*!
1734     \qmlproperty real Item::childrenRect.x
1735     \qmlproperty real Item::childrenRect.y
1736     \qmlproperty real Item::childrenRect.width
1737     \qmlproperty real Item::childrenRect.height
1738
1739     The childrenRect properties allow an item access to the geometry of its
1740     children. This property is useful if you have an item that needs to be
1741     sized to fit its children.
1742 */
1743
1744
1745 /*!
1746     \qmlproperty list<Item> Item::children
1747     \qmlproperty list<Object> Item::resources
1748
1749     The children property contains the list of visual children of this item.
1750     The resources property contains non-visual resources that you want to
1751     reference by name.
1752
1753     Generally you can rely on Item's default property to handle all this for
1754     you, but it can come in handy in some cases.
1755
1756     \qml
1757     Item {
1758         children: [
1759             Text {},
1760             Rectangle {}
1761         ]
1762         resources: [
1763             Component {
1764                 id: myComponent
1765                 Text {}
1766             }
1767         ]
1768     }
1769     \endqml
1770 */
1771
1772 /*!
1773     Returns true if construction of the QML component is complete; otherwise
1774     returns false.
1775
1776     It is often desirable to delay some processing until the component is
1777     completed.
1778
1779     \sa componentComplete()
1780 */
1781 bool QDeclarativeItem::isComponentComplete() const
1782 {
1783     Q_D(const QDeclarativeItem);
1784     return d->componentComplete;
1785 }
1786
1787 void QDeclarativeItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
1788 {
1789     if (!o)
1790         return;
1791
1792     QDeclarativeItem *that = static_cast<QDeclarativeItem *>(prop->object);
1793
1794     // This test is measurably (albeit only slightly) faster than qobject_cast<>()
1795     const QMetaObject *mo = o->metaObject();
1796     while (mo && mo != &QGraphicsObject::staticMetaObject) mo = mo->d.superdata;
1797
1798     if (mo) {
1799         QGraphicsObject *graphicsObject = static_cast<QGraphicsObject *>(o);
1800         QDeclarativeItemPrivate *contentItemPrivate = static_cast<QDeclarativeItemPrivate *>(QGraphicsItemPrivate::get(graphicsObject));
1801         if (contentItemPrivate->componentComplete) {
1802             graphicsObject->setParentItem(that);
1803         } else {
1804             contentItemPrivate->setParentItemHelper(that, /*newParentVariant=*/0, /*thisPointerVariant=*/0);
1805         }
1806     } else {
1807         o->setParent(that);
1808     }
1809 }
1810
1811 static inline int children_count_helper(QDeclarativeListProperty<QObject> *prop)
1812 {
1813     QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(prop->object));
1814     return d->children.count();
1815 }
1816
1817 static inline QObject *children_at_helper(QDeclarativeListProperty<QObject> *prop, int index)
1818 {
1819     QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(prop->object));
1820     if (index >= 0 && index < d->children.count())
1821         return d->children.at(index)->toGraphicsObject();
1822     else
1823         return 0;
1824 }
1825
1826 static inline void children_clear_helper(QDeclarativeListProperty<QObject> *prop)
1827 {
1828     QDeclarativeItemPrivate *d = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(prop->object)));
1829     int childCount = d->children.count();
1830     if (d->componentComplete) {
1831         for (int index = 0 ;index < childCount; index++)
1832             d->children.at(0)->setParentItem(0);
1833     } else {
1834         for (int index = 0 ;index < childCount; index++)
1835             QGraphicsItemPrivate::get(d->children.at(0))->setParentItemHelper(0, /*newParentVariant=*/0, /*thisPointerVariant=*/0);
1836     }
1837 }
1838
1839 int QDeclarativeItemPrivate::data_count(QDeclarativeListProperty<QObject> *prop)
1840 {
1841     return resources_count(prop) + children_count_helper(prop);
1842 }
1843
1844 QObject *QDeclarativeItemPrivate::data_at(QDeclarativeListProperty<QObject> *prop, int i)
1845 {
1846     int resourcesCount = resources_count(prop);
1847     if (i < resourcesCount)
1848         return resources_at(prop, i);
1849     const int j = i - resourcesCount;
1850     if (j < children_count_helper(prop))
1851         return children_at_helper(prop, j);
1852     return 0;
1853 }
1854
1855 void QDeclarativeItemPrivate::data_clear(QDeclarativeListProperty<QObject> *prop)
1856 {
1857     resources_clear(prop);
1858     children_clear_helper(prop);
1859 }
1860
1861 QObject *QDeclarativeItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop, int index)
1862 {
1863     const QObjectList children = prop->object->children();
1864     if (index < children.count())
1865         return children.at(index);
1866     else
1867         return 0;
1868 }
1869
1870 void QDeclarativeItemPrivate::resources_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
1871 {
1872     o->setParent(prop->object);
1873 }
1874
1875 int QDeclarativeItemPrivate::resources_count(QDeclarativeListProperty<QObject> *prop)
1876 {
1877     return prop->object->children().count();
1878 }
1879
1880 void QDeclarativeItemPrivate::resources_clear(QDeclarativeListProperty<QObject> *prop)
1881 {
1882     const QObjectList children = prop->object->children();
1883     for (int index = 0; index < children.count(); index++)
1884         children.at(index)->setParent(0);
1885 }
1886
1887 int QDeclarativeItemPrivate::transform_count(QDeclarativeListProperty<QGraphicsTransform> *list)
1888 {
1889     QGraphicsObject *object = qobject_cast<QGraphicsObject *>(list->object);
1890     if (object) {
1891         QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(object);
1892         return d->transformData ? d->transformData->graphicsTransforms.size() : 0;
1893     } else {
1894         return 0;
1895     }
1896 }
1897
1898 void QDeclarativeItemPrivate::transform_append(QDeclarativeListProperty<QGraphicsTransform> *list, QGraphicsTransform *item)
1899 {
1900     QGraphicsObject *object = qobject_cast<QGraphicsObject *>(list->object);
1901     if (object && item) // QGraphicsItem applies the list in the wrong order, so we prepend.
1902         QGraphicsItemPrivate::get(object)->prependGraphicsTransform(item);
1903 }
1904
1905 QGraphicsTransform *QDeclarativeItemPrivate::transform_at(QDeclarativeListProperty<QGraphicsTransform> *list, int idx)
1906 {
1907     QGraphicsObject *object = qobject_cast<QGraphicsObject *>(list->object);
1908     if (object) {
1909         QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(object);
1910         if (!d->transformData)
1911             return 0;
1912         return d->transformData->graphicsTransforms.at(idx);
1913     } else {
1914         return 0;
1915     }
1916 }
1917
1918 void QDeclarativeItemPrivate::transform_clear(QDeclarativeListProperty<QGraphicsTransform> *list)
1919 {
1920     QGraphicsObject *object = qobject_cast<QGraphicsObject *>(list->object);
1921     if (object) {
1922         QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(object);
1923         if (!d->transformData)
1924             return;
1925         object->setTransformations(QList<QGraphicsTransform *>());
1926     }
1927 }
1928
1929 void QDeclarativeItemPrivate::parentProperty(QObject *o, void *rv, QDeclarativeNotifierEndpoint *e)
1930 {
1931     QDeclarativeItem *item = static_cast<QDeclarativeItem*>(o);
1932     if (e)
1933         e->connect(&item->d_func()->parentNotifier);
1934     *((QDeclarativeItem **)rv) = item->parentItem();
1935 }
1936
1937 /*!
1938     \qmlproperty list<Object> Item::data
1939     \default
1940
1941     The data property allows you to freely mix visual children and resources
1942     in an item.  If you assign a visual item to the data list it becomes
1943     a child and if you assign any other object type, it is added as a resource.
1944
1945     So you can write:
1946     \qml
1947     Item {
1948         Text {}
1949         Rectangle {}
1950         Timer {}
1951     }
1952     \endqml
1953
1954     instead of:
1955     \qml
1956     Item {
1957         children: [
1958             Text {},
1959             Rectangle {}
1960         ]
1961         resources: [
1962             Timer {}
1963         ]
1964     }
1965     \endqml
1966
1967     data is a behind-the-scenes property: you should never need to explicitly
1968     specify it.
1969  */
1970
1971 QDeclarativeListProperty<QObject> QDeclarativeItemPrivate::data()
1972 {
1973     return QDeclarativeListProperty<QObject>(q_func(), 0, QDeclarativeItemPrivate::data_append,
1974                                              QDeclarativeItemPrivate::data_count,
1975                                              QDeclarativeItemPrivate::data_at,
1976                                              QDeclarativeItemPrivate::data_clear
1977                                              );
1978 }
1979
1980 /*!
1981     \property QDeclarativeItem::childrenRect
1982     \brief The geometry of an item's children.
1983
1984     This property holds the (collective) position and size of the item's children.
1985 */
1986 QRectF QDeclarativeItem::childrenRect()
1987 {
1988     Q_D(QDeclarativeItem);
1989     if (!d->_contents) {
1990         d->_contents = new QDeclarativeContents(this);
1991         if (d->componentComplete)
1992             d->_contents->complete();
1993     }
1994     return d->_contents->rectF();
1995 }
1996
1997 bool QDeclarativeItem::clip() const
1998 {
1999     return flags() & ItemClipsChildrenToShape;
2000 }
2001
2002 void QDeclarativeItem::setClip(bool c)
2003 {
2004     if (clip() == c)
2005         return;
2006     setFlag(ItemClipsChildrenToShape, c);
2007     emit clipChanged(c);
2008 }
2009
2010 /*!
2011   \qmlproperty real Item::x
2012   \qmlproperty real Item::y
2013   \qmlproperty real Item::width
2014   \qmlproperty real Item::height
2015
2016   Defines the item's position and size relative to its parent.
2017
2018   \qml
2019   Item { x: 100; y: 100; width: 100; height: 100 }
2020   \endqml
2021  */
2022
2023 /*!
2024   \qmlproperty real Item::z
2025
2026   Sets the stacking order of sibling items.  By default the stacking order is 0.
2027
2028   Items with a higher stacking value are drawn on top of siblings with a
2029   lower stacking order.  Items with the same stacking value are drawn
2030   bottom up in the order they appear.  Items with a negative stacking
2031   value are drawn under their parent's content.
2032
2033   The following example shows the various effects of stacking order.
2034
2035   \table
2036   \row
2037   \o \image declarative-item_stacking1.png
2038   \o Same \c z - later children above earlier children:
2039   \qml
2040   Item {
2041       Rectangle {
2042           color: "red"
2043           width: 100; height: 100
2044       }
2045       Rectangle {
2046           color: "blue"
2047           x: 50; y: 50; width: 100; height: 100
2048       }
2049   }
2050   \endqml
2051   \row
2052   \o \image declarative-item_stacking2.png
2053   \o Higher \c z on top:
2054   \qml
2055   Item {
2056       Rectangle {
2057           z: 1
2058           color: "red"
2059           width: 100; height: 100
2060       }
2061       Rectangle {
2062           color: "blue"
2063           x: 50; y: 50; width: 100; height: 100
2064       }
2065   }
2066   \endqml
2067   \row
2068   \o \image declarative-item_stacking3.png
2069   \o Same \c z - children above parents:
2070   \qml
2071   Item {
2072       Rectangle {
2073           color: "red"
2074           width: 100; height: 100
2075           Rectangle {
2076               color: "blue"
2077               x: 50; y: 50; width: 100; height: 100
2078           }
2079       }
2080   }
2081   \endqml
2082   \row
2083   \o \image declarative-item_stacking4.png
2084   \o Lower \c z below:
2085   \qml
2086   Item {
2087       Rectangle {
2088           color: "red"
2089           width: 100; height: 100
2090           Rectangle {
2091               z: -1
2092               color: "blue"
2093               x: 50; y: 50; width: 100; height: 100
2094           }
2095       }
2096   }
2097   \endqml
2098   \endtable
2099  */
2100
2101 /*!
2102     \qmlproperty bool Item::visible
2103
2104     This property holds whether the item is visible. By default this is true.
2105
2106     Setting this property directly affects the \c visible value of child
2107     items. When set to \c false, the \c visible values of all child items also
2108     become \c false. When set to \c true, the \c visible values of child items
2109     are returned to \c true, unless they have explicitly been set to \c false.
2110
2111     (Because of this flow-on behavior, using the \c visible property may not
2112     have the intended effect if a property binding should only respond to
2113     explicit property changes. In such cases it may be better to use the
2114     \l opacity property instead.)
2115
2116     Setting this property to \c false automatically causes \l focus to be set
2117     to \c false, and this item will longer receive mouse and keyboard events.
2118     (In contrast, setting the \l opacity to 0 does not affect the \l focus
2119     property and the receiving of key events.)
2120
2121     \note This property's value is only affected by changes to this property or
2122     the parent's \c visible property. It does not change, for example, if this
2123     item moves off-screen, or if the \l opacity changes to 0.
2124 */
2125
2126
2127 /*!
2128   This function is called to handle this item's changes in
2129   geometry from \a oldGeometry to \a newGeometry. If the two
2130   geometries are the same, it doesn't do anything.
2131  */
2132 void QDeclarativeItem::geometryChanged(const QRectF &newGeometry,
2133                               const QRectF &oldGeometry)
2134 {
2135     Q_D(QDeclarativeItem);
2136
2137     if (d->_anchors)
2138         d->_anchors->d_func()->updateMe();
2139
2140     if (transformOrigin() != QDeclarativeItem::TopLeft
2141         && (newGeometry.width() != oldGeometry.width() || newGeometry.height() != oldGeometry.height())) {
2142         if (d->transformData) {
2143             QPointF origin = d->computeTransformOrigin();
2144             if (transformOriginPoint() != origin)
2145                 setTransformOriginPoint(origin);
2146         } else {
2147             d->transformOriginDirty = true;
2148         }
2149     }
2150
2151     for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
2152         const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
2153         if (change.types & QDeclarativeItemPrivate::Geometry)
2154             change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
2155     }
2156
2157     if (newGeometry.width() != oldGeometry.width())
2158         emit widthChanged();
2159     if (newGeometry.height() != oldGeometry.height())
2160         emit heightChanged();
2161 }
2162
2163 void QDeclarativeItemPrivate::removeItemChangeListener(QDeclarativeItemChangeListener *listener, ChangeTypes types)
2164 {
2165     ChangeListener change(listener, types);
2166     changeListeners.removeOne(change);
2167 }
2168
2169 /*! \internal */
2170 void QDeclarativeItem::keyPressEvent(QKeyEvent *event)
2171 {
2172     Q_D(QDeclarativeItem);
2173     keyPressPreHandler(event);
2174     if (event->isAccepted())
2175         return;
2176     if (d->keyHandler)
2177         d->keyHandler->keyPressed(event, true);
2178     else
2179         event->ignore();
2180 }
2181
2182 /*! \internal */
2183 void QDeclarativeItem::keyReleaseEvent(QKeyEvent *event)
2184 {
2185     Q_D(QDeclarativeItem);
2186     keyReleasePreHandler(event);
2187     if (event->isAccepted())
2188         return;
2189     if (d->keyHandler)
2190         d->keyHandler->keyReleased(event, true);
2191     else
2192         event->ignore();
2193 }
2194
2195 /*! \internal */
2196 void QDeclarativeItem::inputMethodEvent(QInputMethodEvent *event)
2197 {
2198     Q_D(QDeclarativeItem);
2199     inputMethodPreHandler(event);
2200     if (event->isAccepted())
2201         return;
2202     if (d->keyHandler)
2203         d->keyHandler->inputMethodEvent(event, true);
2204     else
2205         event->ignore();
2206 }
2207
2208 /*! \internal */
2209 QVariant QDeclarativeItem::inputMethodQuery(Qt::InputMethodQuery query) const
2210 {
2211     Q_D(const QDeclarativeItem);
2212     QVariant v;
2213     if (d->keyHandler)
2214         v = d->keyHandler->inputMethodQuery(query);
2215
2216     if (!v.isValid())
2217         v = QGraphicsObject::inputMethodQuery(query);
2218
2219     return v;
2220 }
2221
2222 /*!
2223   \internal
2224  */
2225 void QDeclarativeItem::keyPressPreHandler(QKeyEvent *event)
2226 {
2227     Q_D(QDeclarativeItem);
2228     if (d->keyHandler && !d->doneEventPreHandler)
2229         d->keyHandler->keyPressed(event, false);
2230     else
2231         event->ignore();
2232     d->doneEventPreHandler = true;
2233 }
2234
2235 /*!
2236   \internal
2237  */
2238 void QDeclarativeItem::keyReleasePreHandler(QKeyEvent *event)
2239 {
2240     Q_D(QDeclarativeItem);
2241     if (d->keyHandler && !d->doneEventPreHandler)
2242         d->keyHandler->keyReleased(event, false);
2243     else
2244         event->ignore();
2245     d->doneEventPreHandler = true;
2246 }
2247
2248 /*!
2249   \internal
2250  */
2251 void QDeclarativeItem::inputMethodPreHandler(QInputMethodEvent *event)
2252 {
2253     Q_D(QDeclarativeItem);
2254     if (d->keyHandler && !d->doneEventPreHandler)
2255         d->keyHandler->inputMethodEvent(event, false);
2256     else
2257         event->ignore();
2258     d->doneEventPreHandler = true;
2259 }
2260
2261 /*!
2262     \internal
2263 */
2264 QDeclarativeAnchorLine QDeclarativeItemPrivate::left() const
2265 {
2266     return anchorLines()->left;
2267 }
2268
2269 /*!
2270     \internal
2271 */
2272 QDeclarativeAnchorLine QDeclarativeItemPrivate::right() const
2273 {
2274     return anchorLines()->right;
2275 }
2276
2277 /*!
2278     \internal
2279 */
2280 QDeclarativeAnchorLine QDeclarativeItemPrivate::horizontalCenter() const
2281 {
2282     return anchorLines()->hCenter;
2283 }
2284
2285 /*!
2286     \internal
2287 */
2288 QDeclarativeAnchorLine QDeclarativeItemPrivate::top() const
2289 {
2290     return anchorLines()->top;
2291 }
2292
2293 /*!
2294     \internal
2295 */
2296 QDeclarativeAnchorLine QDeclarativeItemPrivate::bottom() const
2297 {
2298     return anchorLines()->bottom;
2299 }
2300
2301 /*!
2302     \internal
2303 */
2304 QDeclarativeAnchorLine QDeclarativeItemPrivate::verticalCenter() const
2305 {
2306     return anchorLines()->vCenter;
2307 }
2308
2309
2310 /*!
2311     \internal
2312 */
2313 QDeclarativeAnchorLine QDeclarativeItemPrivate::baseline() const
2314 {
2315     return anchorLines()->baseline;
2316 }
2317
2318 /*!
2319   \qmlproperty AnchorLine Item::anchors.top
2320   \qmlproperty AnchorLine Item::anchors.bottom
2321   \qmlproperty AnchorLine Item::anchors.left
2322   \qmlproperty AnchorLine Item::anchors.right
2323   \qmlproperty AnchorLine Item::anchors.horizontalCenter
2324   \qmlproperty AnchorLine Item::anchors.verticalCenter
2325   \qmlproperty AnchorLine Item::anchors.baseline
2326
2327   \qmlproperty Item Item::anchors.fill
2328   \qmlproperty Item Item::anchors.centerIn
2329
2330   \qmlproperty real Item::anchors.margins
2331   \qmlproperty real Item::anchors.topMargin
2332   \qmlproperty real Item::anchors.bottomMargin
2333   \qmlproperty real Item::anchors.leftMargin
2334   \qmlproperty real Item::anchors.rightMargin
2335   \qmlproperty real Item::anchors.horizontalCenterOffset
2336   \qmlproperty real Item::anchors.verticalCenterOffset
2337   \qmlproperty real Item::anchors.baselineOffset
2338
2339   \qmlproperty bool Item::anchors.mirrored
2340
2341   Anchors provide a way to position an item by specifying its
2342   relationship with other items.
2343
2344   Margins apply to top, bottom, left, right, and fill anchors.
2345   The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
2346   Note that margins are anchor-specific and are not applied if an item does not
2347   use anchors.
2348
2349   Offsets apply for horizontal center, vertical center, and baseline anchors.
2350
2351   \table
2352   \row
2353   \o \image declarative-anchors_example.png
2354   \o Text anchored to Image, horizontally centered and vertically below, with a margin.
2355   \qml
2356   Item {
2357       Image {
2358           id: pic
2359           // ...
2360       }
2361       Text {
2362           id: label
2363           anchors.horizontalCenter: pic.horizontalCenter
2364           anchors.top: pic.bottom
2365           anchors.topMargin: 5
2366           // ...
2367       }
2368   }
2369   \endqml
2370   \row
2371   \o \image declarative-anchors_example2.png
2372   \o
2373   Left of Text anchored to right of Image, with a margin. The y
2374   property of both defaults to 0.
2375
2376   \qml
2377   Item {
2378       Image {
2379           id: pic
2380           // ...
2381       }
2382       Text {
2383           id: label
2384           anchors.left: pic.right
2385           anchors.leftMargin: 5
2386           // ...
2387       }
2388   }
2389   \endqml
2390   \endtable
2391
2392   \c anchors.fill provides a convenient way for one item to have the
2393   same geometry as another item, and is equivalent to connecting all
2394   four directional anchors.
2395
2396   To clear an anchor value, set it to \c undefined.
2397
2398   \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
2399
2400   \note You can only anchor an item to siblings or a parent.
2401
2402   For more information see \l {anchor-layout}{Anchor Layouts}.
2403 */
2404
2405 /*!
2406   \property QDeclarativeItem::baselineOffset
2407   \brief The position of the item's baseline in local coordinates.
2408
2409   The baseline of a \l Text item is the imaginary line on which the text
2410   sits. Controls containing text usually set their baseline to the
2411   baseline of their text.
2412
2413   For non-text items, a default baseline offset of 0 is used.
2414 */
2415 qreal QDeclarativeItem::baselineOffset() const
2416 {
2417     Q_D(const QDeclarativeItem);
2418     if (!d->baselineOffset.isValid()) {
2419         return 0.0;
2420     } else
2421         return d->baselineOffset;
2422 }
2423
2424 void QDeclarativeItem::setBaselineOffset(qreal offset)
2425 {
2426     Q_D(QDeclarativeItem);
2427     if (offset == d->baselineOffset)
2428         return;
2429
2430     d->baselineOffset = offset;
2431
2432     for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
2433         const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
2434         if (change.types & QDeclarativeItemPrivate::Geometry) {
2435             QDeclarativeAnchorsPrivate *anchor = change.listener->anchorPrivate();
2436             if (anchor)
2437                 anchor->updateVerticalAnchors();
2438         }
2439     }
2440     emit baselineOffsetChanged(offset);
2441 }
2442
2443 /*!
2444   \qmlproperty real Item::rotation
2445   This property holds the rotation of the item in degrees clockwise.
2446
2447   This specifies how many degrees to rotate the item around its transformOrigin.
2448   The default rotation is 0 degrees (i.e. not rotated at all).
2449
2450   \table
2451   \row
2452   \o \image declarative-rotation.png
2453   \o
2454   \qml
2455   Rectangle {
2456       color: "blue"
2457       width: 100; height: 100
2458       Rectangle {
2459           color: "red"
2460           x: 25; y: 25; width: 50; height: 50
2461           rotation: 30
2462       }
2463   }
2464   \endqml
2465   \endtable
2466
2467   \sa transform, Rotation
2468 */
2469
2470 /*!
2471   \qmlproperty real Item::scale
2472   This property holds the scale of the item.
2473
2474   A scale of less than 1 means the item will be displayed smaller than
2475   normal, and a scale of greater than 1 means the item will be
2476   displayed larger than normal.  A negative scale means the item will
2477   be mirrored.
2478
2479   By default, items are displayed at a scale of 1 (i.e. at their
2480   normal size).
2481
2482   Scaling is from the item's transformOrigin.
2483
2484   \table
2485   \row
2486   \o \image declarative-scale.png
2487   \o
2488   \qml
2489   Rectangle {
2490       color: "blue"
2491       width: 100; height: 100
2492       Rectangle {
2493           color: "green"
2494           width: 25; height: 25
2495       }
2496       Rectangle {
2497           color: "red"
2498           x: 25; y: 25; width: 50; height: 50
2499           scale: 1.4
2500       }
2501   }
2502   \endqml
2503   \endtable
2504
2505   \sa transform, Scale
2506 */
2507
2508 /*!
2509   \qmlproperty real Item::opacity
2510
2511   This property holds the opacity of the item.  Opacity is specified as a
2512   number between 0 (fully transparent) and 1 (fully opaque).  The default is 1.
2513
2514   When this property is set, the specified opacity is also applied
2515   individually to child items.  In almost all cases this is what you want,
2516   but in some cases it may produce undesired results. For example in the
2517   second set of rectangles below, the red rectangle has specified an opacity
2518   of 0.5, which affects the opacity of its blue child rectangle even though
2519   the child has not specified an opacity.
2520
2521   \table
2522   \row
2523   \o \image declarative-item_opacity1.png
2524   \o
2525   \qml
2526     Item {
2527         Rectangle {
2528             color: "red"
2529             width: 100; height: 100
2530             Rectangle {
2531                 color: "blue"
2532                 x: 50; y: 50; width: 100; height: 100
2533             }
2534         }
2535     }
2536   \endqml
2537   \row
2538   \o \image declarative-item_opacity2.png
2539   \o
2540   \qml
2541     Item {
2542         Rectangle {
2543             opacity: 0.5
2544             color: "red"
2545             width: 100; height: 100
2546             Rectangle {
2547                 color: "blue"
2548                 x: 50; y: 50; width: 100; height: 100
2549             }
2550         }
2551     }
2552   \endqml
2553   \endtable
2554
2555   If an item's opacity is set to 0, the item will no longer receive mouse
2556   events, but will continue to receive key events and will retain the keyboard
2557   \l focus if it has been set. (In contrast, setting the \l visible property
2558   to \c false stops both mouse and keyboard events, and also removes focus
2559   from the item.)
2560 */
2561
2562 /*!
2563   Returns a value indicating whether mouse input should
2564   remain with this item exclusively.
2565
2566   \sa setKeepMouseGrab()
2567  */
2568 bool QDeclarativeItem::keepMouseGrab() const
2569 {
2570     Q_D(const QDeclarativeItem);
2571     return d->keepMouse;
2572 }
2573
2574 /*!
2575   The flag indicating whether the mouse should remain
2576   with this item is set to \a keep.
2577
2578   This is useful for items that wish to grab and keep mouse
2579   interaction following a predefined gesture.  For example,
2580   an item that is interested in horizontal mouse movement
2581   may set keepMouseGrab to true once a threshold has been
2582   exceeded.  Once keepMouseGrab has been set to true, filtering
2583   items will not react to mouse events.
2584
2585   If the item does not indicate that it wishes to retain mouse grab,
2586   a filtering item may steal the grab. For example, Flickable may attempt
2587   to steal a mouse grab if it detects that the user has begun to
2588   move the viewport.
2589
2590   \sa keepMouseGrab()
2591  */
2592 void QDeclarativeItem::setKeepMouseGrab(bool keep)
2593 {
2594     Q_D(QDeclarativeItem);
2595     d->keepMouse = keep;
2596 }
2597
2598 /*!
2599     \qmlmethod object Item::mapFromItem(Item item, real x, real y)
2600
2601     Maps the point (\a x, \a y), which is in \a item's coordinate system, to
2602     this item's coordinate system, and returns an object with \c x and \c y
2603     properties matching the mapped cooordinate.
2604
2605     If \a item is a \c null value, this maps the point from the coordinate
2606     system of the root QML view.
2607 */
2608 QScriptValue QDeclarativeItem::mapFromItem(const QScriptValue &item, qreal x, qreal y) const
2609 {
2610     QScriptValue sv = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this))->newObject();
2611     QDeclarativeItem *itemObj = qobject_cast<QDeclarativeItem*>(item.toQObject());
2612     if (!itemObj && !item.isNull()) {
2613         qmlInfo(this) << "mapFromItem() given argument \"" << item.toString() << "\" which is neither null nor an Item";
2614         return 0;
2615     }
2616
2617     // If QGraphicsItem::mapFromItem() is called with 0, behaves the same as mapFromScene()
2618     QPointF p = qobject_cast<QGraphicsItem*>(this)->mapFromItem(itemObj, x, y);
2619     sv.setProperty(QLatin1String("x"), p.x());
2620     sv.setProperty(QLatin1String("y"), p.y());
2621     return sv;
2622 }
2623
2624 /*!
2625     \qmlmethod object Item::mapToItem(Item item, real x, real y)
2626
2627     Maps the point (\a x, \a y), which is in this item's coordinate system, to
2628     \a item's coordinate system, and returns an object with \c x and \c y
2629     properties matching the mapped cooordinate.
2630
2631     If \a item is a \c null value, this maps \a x and \a y to the coordinate
2632     system of the root QML view.
2633 */
2634 QScriptValue QDeclarativeItem::mapToItem(const QScriptValue &item, qreal x, qreal y) const
2635 {
2636     QScriptValue sv = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this))->newObject();
2637     QDeclarativeItem *itemObj = qobject_cast<QDeclarativeItem*>(item.toQObject());
2638     if (!itemObj && !item.isNull()) {
2639         qmlInfo(this) << "mapToItem() given argument \"" << item.toString() << "\" which is neither null nor an Item";
2640         return 0;
2641     }
2642
2643     // If QGraphicsItem::mapToItem() is called with 0, behaves the same as mapToScene()
2644     QPointF p = qobject_cast<QGraphicsItem*>(this)->mapToItem(itemObj, x, y);
2645     sv.setProperty(QLatin1String("x"), p.x());
2646     sv.setProperty(QLatin1String("y"), p.y());
2647     return sv;
2648 }
2649
2650 /*!
2651     \qmlmethod Item::forceActiveFocus()
2652
2653     Force active focus on the item.
2654     This method sets focus on the item and makes sure that all the focus scopes higher in the object hierarchy are also given focus.
2655 */
2656 void QDeclarativeItem::forceActiveFocus()
2657 {
2658     setFocus(true);
2659     QGraphicsItem *parent = parentItem();
2660     while (parent) {
2661         if (parent->flags() & QGraphicsItem::ItemIsFocusScope)
2662             parent->setFocus(Qt::OtherFocusReason);
2663         parent = parent->parentItem();
2664     }
2665 }
2666
2667
2668 /*!
2669   \qmlmethod Item::childAt(real x, real y)
2670
2671   Returns the visible child item at point (\a x, \a y), which is in this
2672   item's coordinate system, or \c null if there is no such item.
2673   */
2674 QDeclarativeItem *QDeclarativeItem::childAt(qreal x, qreal y) const
2675 {
2676     const QList<QGraphicsItem *> children = childItems();
2677     for (int i = children.count()-1; i >= 0; --i) {
2678         if (QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i))) {
2679             if (child->isVisible() && child->x() <= x
2680                 && child->x() + child->width() >= x
2681                 && child->y() <= y
2682                 && child->y() + child->height() >= y)
2683                 return child;
2684         }
2685     }
2686     return 0;
2687 }
2688
2689 void QDeclarativeItemPrivate::focusChanged(bool flag)
2690 {
2691     Q_Q(QDeclarativeItem);
2692     if (!(flags & QGraphicsItem::ItemIsFocusScope) && parent)
2693         emit q->activeFocusChanged(flag);   //see also QDeclarativeItemPrivate::subFocusItemChange()
2694     emit q->focusChanged(flag);
2695 }
2696
2697 QDeclarativeListProperty<QObject> QDeclarativeItemPrivate::resources()
2698 {
2699     return QDeclarativeListProperty<QObject>(q_func(), 0, QDeclarativeItemPrivate::resources_append,
2700                                              QDeclarativeItemPrivate::resources_count,
2701                                              QDeclarativeItemPrivate::resources_at,
2702                                              QDeclarativeItemPrivate::resources_clear
2703                                              );
2704 }
2705
2706 /*!
2707   \qmlproperty list<State> Item::states
2708   This property holds a list of states defined by the item.
2709
2710   \qml
2711   Item {
2712       states: [
2713           State {
2714               // ...
2715           },
2716           State {
2717               // ...
2718           }
2719           // ...
2720       ]
2721   }
2722   \endqml
2723
2724   \sa {qmlstate}{States}
2725 */
2726
2727 QDeclarativeListProperty<QDeclarativeState> QDeclarativeItemPrivate::states()
2728 {
2729     return _states()->statesProperty();
2730 }
2731
2732 /*!
2733   \qmlproperty list<Transition> Item::transitions
2734   This property holds a list of transitions defined by the item.
2735
2736   \qml
2737   Item {
2738       transitions: [
2739           Transition {
2740               // ...
2741           },
2742           Transition {
2743               // ...
2744           }
2745           // ...
2746       ]
2747   }
2748   \endqml
2749
2750   \sa {QML Animation and Transitions}{Transitions}
2751 */
2752
2753
2754 QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeItemPrivate::transitions()
2755 {
2756     return _states()->transitionsProperty();
2757 }
2758
2759 /*
2760   \qmlproperty list<Filter> Item::filter
2761   This property holds a list of graphical filters to be applied to the item.
2762
2763   \l {Filter}{Filters} include things like \l {Blur}{blurring}
2764   the item, or giving it a \l Reflection.  Some
2765   filters may not be available on all canvases; if a filter is not
2766   available on a certain canvas, it will simply not be applied for
2767   that canvas (but the QML will still be considered valid).
2768
2769   \qml
2770   Item {
2771       filter: [
2772           Blur {
2773               // ...
2774           },
2775           Reflection {
2776               // ...
2777           }
2778           // ...
2779       ]
2780   }
2781   \endqml
2782 */
2783
2784 /*!
2785   \qmlproperty bool Item::clip
2786   This property holds whether clipping is enabled. The default clip value is \c false.
2787
2788   If clipping is enabled, an item will clip its own painting, as well
2789   as the painting of its children, to its bounding rectangle.
2790
2791   Non-rectangular clipping regions are not supported for performance reasons.
2792 */
2793
2794 /*!
2795   \property QDeclarativeItem::clip
2796   This property holds whether clipping is enabled. The default clip value is \c false.
2797
2798   If clipping is enabled, an item will clip its own painting, as well
2799   as the painting of its children, to its bounding rectangle. If you set
2800   clipping during an item's paint operation, remember to re-set it to 
2801   prevent clipping the rest of your scene.
2802
2803   Non-rectangular clipping regions are not supported for performance reasons.
2804 */
2805
2806 /*!
2807   \qmlproperty string Item::state
2808
2809   This property holds the name of the current state of the item.
2810
2811   This property is often used in scripts to change between states. For
2812   example:
2813
2814   \js
2815   function toggle() {
2816       if (button.state == 'On')
2817           button.state = 'Off';
2818       else
2819           button.state = 'On';
2820   }
2821   \endjs
2822
2823   If the item is in its base state (i.e. no explicit state has been
2824   set), \c state will be a blank string. Likewise, you can return an
2825   item to its base state by setting its current state to \c ''.
2826
2827   \sa {qmlstates}{States}
2828 */
2829
2830 QString QDeclarativeItemPrivate::state() const
2831 {
2832     if (!_stateGroup)
2833         return QString();
2834     else
2835         return _stateGroup->state();
2836 }
2837
2838 void QDeclarativeItemPrivate::setState(const QString &state)
2839 {
2840     _states()->setState(state);
2841 }
2842
2843 /*!
2844   \qmlproperty list<Transform> Item::transform
2845   This property holds the list of transformations to apply.
2846
2847   For more information see \l Transform.
2848 */
2849
2850 /*! \internal */
2851 QDeclarativeListProperty<QGraphicsTransform> QDeclarativeItem::transform()
2852 {
2853     Q_D(QDeclarativeItem);
2854     return QDeclarativeListProperty<QGraphicsTransform>(this, 0, d->transform_append, d->transform_count,
2855                                                d->transform_at, d->transform_clear);
2856 }
2857
2858 /*!
2859   \internal
2860
2861   classBegin() is called when the item is constructed, but its
2862   properties have not yet been set.
2863
2864   \sa componentComplete(), isComponentComplete()
2865 */
2866 void QDeclarativeItem::classBegin()
2867 {
2868     Q_D(QDeclarativeItem);
2869     d->componentComplete = false;
2870     if (d->_stateGroup)
2871         d->_stateGroup->classBegin();
2872     if (d->_anchors)
2873         d->_anchors->classBegin();
2874 }
2875
2876 /*!
2877   \internal
2878
2879   componentComplete() is called when all items in the component
2880   have been constructed.  It is often desirable to delay some
2881   processing until the component is complete an all bindings in the
2882   component have been resolved.
2883 */
2884 void QDeclarativeItem::componentComplete()
2885 {
2886     Q_D(QDeclarativeItem);
2887     d->componentComplete = true;
2888     if (d->_stateGroup)
2889         d->_stateGroup->componentComplete();
2890     if (d->_anchors) {
2891         d->_anchors->componentComplete();
2892         d->_anchors->d_func()->updateOnComplete();
2893     }
2894     if (d->keyHandler)
2895         d->keyHandler->componentComplete();
2896     if (d->_contents)
2897         d->_contents->complete();
2898 }
2899
2900 QDeclarativeStateGroup *QDeclarativeItemPrivate::_states()
2901 {
2902     Q_Q(QDeclarativeItem);
2903     if (!_stateGroup) {
2904         _stateGroup = new QDeclarativeStateGroup;
2905         if (!componentComplete)
2906             _stateGroup->classBegin();
2907         QObject::connect(_stateGroup, SIGNAL(stateChanged(QString)),
2908                          q, SIGNAL(stateChanged(QString)));
2909     }
2910
2911     return _stateGroup;
2912 }
2913
2914 QDeclarativeItemPrivate::AnchorLines::AnchorLines(QGraphicsObject *q)
2915 {
2916     left.item = q;
2917     left.anchorLine = QDeclarativeAnchorLine::Left;
2918     right.item = q;
2919     right.anchorLine = QDeclarativeAnchorLine::Right;
2920     hCenter.item = q;
2921     hCenter.anchorLine = QDeclarativeAnchorLine::HCenter;
2922     top.item = q;
2923     top.anchorLine = QDeclarativeAnchorLine::Top;
2924     bottom.item = q;
2925     bottom.anchorLine = QDeclarativeAnchorLine::Bottom;
2926     vCenter.item = q;
2927     vCenter.anchorLine = QDeclarativeAnchorLine::VCenter;
2928     baseline.item = q;
2929     baseline.anchorLine = QDeclarativeAnchorLine::Baseline;
2930 }
2931
2932 QPointF QDeclarativeItemPrivate::computeTransformOrigin() const
2933 {
2934     Q_Q(const QDeclarativeItem);
2935
2936     QRectF br = q->boundingRect();
2937
2938     switch(origin) {
2939     default:
2940     case QDeclarativeItem::TopLeft:
2941         return QPointF(0, 0);
2942     case QDeclarativeItem::Top:
2943         return QPointF(br.width() / 2., 0);
2944     case QDeclarativeItem::TopRight:
2945         return QPointF(br.width(), 0);
2946     case QDeclarativeItem::Left:
2947         return QPointF(0, br.height() / 2.);
2948     case QDeclarativeItem::Center:
2949         return QPointF(br.width() / 2., br.height() / 2.);
2950     case QDeclarativeItem::Right:
2951         return QPointF(br.width(), br.height() / 2.);
2952     case QDeclarativeItem::BottomLeft:
2953         return QPointF(0, br.height());
2954     case QDeclarativeItem::Bottom:
2955         return QPointF(br.width() / 2., br.height());
2956     case QDeclarativeItem::BottomRight:
2957         return QPointF(br.width(), br.height());
2958     }
2959 }
2960
2961 /*! \internal */
2962 bool QDeclarativeItem::sceneEvent(QEvent *event)
2963 {
2964     Q_D(QDeclarativeItem);
2965     if (event->type() == QEvent::KeyPress) {
2966         QKeyEvent *k = static_cast<QKeyEvent *>(event);
2967         if ((k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) &&
2968             !(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) {
2969             keyPressEvent(static_cast<QKeyEvent *>(event));
2970             if (!event->isAccepted())
2971                 return QGraphicsItem::sceneEvent(event);
2972             else
2973                 return true;
2974         } else {
2975             return QGraphicsItem::sceneEvent(event);
2976         }
2977     } else {
2978         bool rv = QGraphicsItem::sceneEvent(event);
2979
2980         if (event->type() == QEvent::FocusIn ||
2981             event->type() == QEvent::FocusOut) {
2982             d->focusChanged(hasActiveFocus());
2983         }
2984         return rv;
2985     }
2986 }
2987
2988 /*!
2989     \internal
2990
2991     Note that unlike QGraphicsItems, QDeclarativeItem::itemChange() is \e not called
2992     during initial widget polishing. Items wishing to optimize start-up construction
2993     should instead consider using componentComplete().
2994 */
2995 QVariant QDeclarativeItem::itemChange(GraphicsItemChange change,
2996                                        const QVariant &value)
2997 {
2998     Q_D(QDeclarativeItem);
2999     switch (change) {
3000     case ItemParentHasChanged:
3001         d->resolveLayoutMirror();
3002         emit parentChanged(parentItem());
3003         d->parentNotifier.notify();
3004         break;
3005     case ItemVisibleHasChanged: {
3006             for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
3007                 const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3008                 if (change.types & QDeclarativeItemPrivate::Visibility) {
3009                     change.listener->itemVisibilityChanged(this);
3010                 }
3011             }
3012         }
3013         break;
3014     case ItemOpacityHasChanged: {
3015             for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
3016                 const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
3017                 if (change.types & QDeclarativeItemPrivate::Opacity) {
3018                     change.listener->itemOpacityChanged(this);
3019                 }
3020             }
3021         }
3022         break;
3023     case ItemChildAddedChange:
3024         if (d->_contents && d->componentComplete)
3025             d->_contents->childAdded(qobject_cast<QDeclarativeItem*>(
3026                     value.value<QGraphicsItem*>()));
3027         break;
3028     case ItemChildRemovedChange:
3029         if (d->_contents && d->componentComplete)
3030             d->_contents->childRemoved(qobject_cast<QDeclarativeItem*>(
3031                     value.value<QGraphicsItem*>()));
3032         break;
3033     default:
3034         break;
3035     }
3036
3037     return QGraphicsItem::itemChange(change, value);
3038 }
3039
3040 /*! \internal */
3041 QRectF QDeclarativeItem::boundingRect() const
3042 {
3043     Q_D(const QDeclarativeItem);
3044     return QRectF(0, 0, d->mWidth, d->mHeight);
3045 }
3046
3047 /*!
3048     \enum QDeclarativeItem::TransformOrigin
3049
3050     Controls the point about which simple transforms like scale apply.
3051
3052     \value TopLeft The top-left corner of the item.
3053     \value Top The center point of the top of the item.
3054     \value TopRight The top-right corner of the item.
3055     \value Left The left most point of the vertical middle.
3056     \value Center The center of the item.
3057     \value Right The right most point of the vertical middle.
3058     \value BottomLeft The bottom-left corner of the item.
3059     \value Bottom The center point of the bottom of the item.
3060     \value BottomRight The bottom-right corner of the item.
3061 */
3062
3063 /*!
3064     Returns the current transform origin.
3065 */
3066 QDeclarativeItem::TransformOrigin QDeclarativeItem::transformOrigin() const
3067 {
3068     Q_D(const QDeclarativeItem);
3069     return d->origin;
3070 }
3071
3072 /*!
3073     Set the transform \a origin.
3074 */
3075 void QDeclarativeItem::setTransformOrigin(TransformOrigin origin)
3076 {
3077     Q_D(QDeclarativeItem);
3078     if (origin != d->origin) {
3079         d->origin = origin;
3080         if (d->transformData)
3081             QGraphicsItem::setTransformOriginPoint(d->computeTransformOrigin());
3082         else
3083             d->transformOriginDirty = true;
3084         emit transformOriginChanged(d->origin);
3085     }
3086 }
3087
3088 void QDeclarativeItemPrivate::transformChanged()
3089 {
3090     Q_Q(QDeclarativeItem);
3091     if (transformOriginDirty) {
3092         q->QGraphicsItem::setTransformOriginPoint(computeTransformOrigin());
3093         transformOriginDirty = false;
3094     }
3095 }
3096
3097 /*!
3098     \property QDeclarativeItem::smooth
3099     \brief whether the item is smoothly transformed.
3100
3101     This property is provided purely for the purpose of optimization. Turning
3102     smooth transforms off is faster, but looks worse; turning smooth
3103     transformations on is slower, but looks better.
3104
3105     By default smooth transformations are off.
3106 */
3107
3108 /*!
3109     Returns true if the item should be drawn with antialiasing and
3110     smooth pixmap filtering, false otherwise.
3111
3112     The default is false.
3113
3114     \sa setSmooth()
3115 */
3116 bool QDeclarativeItem::smooth() const
3117 {
3118     Q_D(const QDeclarativeItem);
3119     return d->smooth;
3120 }
3121
3122 /*!
3123     Sets whether the item should be drawn with antialiasing and
3124     smooth pixmap filtering to \a smooth.
3125
3126     \sa smooth()
3127 */
3128 void QDeclarativeItem::setSmooth(bool smooth)
3129 {
3130     Q_D(QDeclarativeItem);
3131     if (d->smooth == smooth)
3132         return;
3133     d->smooth = smooth;
3134     emit smoothChanged(smooth);
3135     update();
3136 }
3137
3138 /*!
3139   \property QDeclarativeItem::anchors
3140   \internal
3141 */
3142
3143 /*!
3144   \property QDeclarativeItem::left
3145   \internal
3146 */
3147
3148 /*!
3149   \property QDeclarativeItem::right
3150   \internal
3151 */
3152
3153 /*!
3154   \property QDeclarativeItem::horizontalCenter
3155   \internal
3156 */
3157
3158 /*!
3159   \property QDeclarativeItem::top
3160   \internal
3161 */
3162
3163 /*!
3164   \property QDeclarativeItem::bottom
3165   \internal
3166 */
3167
3168 /*!
3169   \property QDeclarativeItem::verticalCenter
3170   \internal
3171 */
3172
3173 /*!
3174   \property QDeclarativeItem::focus
3175   \internal
3176 */
3177
3178 /*!
3179   \property QDeclarativeItem::transform
3180   \internal
3181 */
3182
3183 /*!
3184   \property QDeclarativeItem::transformOrigin
3185   \internal
3186 */
3187
3188 /*!
3189   \property QDeclarativeItem::activeFocus
3190   \internal
3191 */
3192
3193 /*!
3194   \property QDeclarativeItem::baseline
3195   \internal
3196 */
3197
3198 /*!
3199   \property QDeclarativeItem::data
3200   \internal
3201 */
3202
3203 /*!
3204   \property QDeclarativeItem::resources
3205   \internal
3206 */
3207
3208 /*!
3209   \property QDeclarativeItem::state
3210   \internal
3211 */
3212
3213 /*!
3214   \property QDeclarativeItem::states
3215   \internal
3216 */
3217
3218 /*!
3219   \property QDeclarativeItem::transformOriginPoint
3220   \internal
3221 */
3222
3223 /*!
3224   \property QDeclarativeItem::transitions
3225   \internal
3226 */
3227
3228 /*!
3229     \internal
3230     Return the width of the item
3231 */
3232 qreal QDeclarativeItem::width() const
3233 {
3234     Q_D(const QDeclarativeItem);
3235     return d->width();
3236 }
3237
3238 /*!
3239     \internal
3240     Set the width of the item
3241 */
3242 void QDeclarativeItem::setWidth(qreal w)
3243 {
3244     Q_D(QDeclarativeItem);
3245     d->setWidth(w);
3246 }
3247
3248 /*!
3249     \internal
3250     Reset the width of the item
3251 */
3252 void QDeclarativeItem::resetWidth()
3253 {
3254     Q_D(QDeclarativeItem);
3255     d->resetWidth();
3256 }
3257
3258 /*!
3259     \internal
3260     Return the width of the item
3261 */
3262 qreal QDeclarativeItemPrivate::width() const
3263 {
3264     return mWidth;
3265 }
3266
3267 /*!
3268     \internal
3269 */
3270 void QDeclarativeItemPrivate::setWidth(qreal w)
3271 {
3272     Q_Q(QDeclarativeItem);
3273     if (qIsNaN(w))
3274         return;
3275
3276     widthValid = true;
3277     if (mWidth == w)
3278         return;
3279
3280     qreal oldWidth = mWidth;
3281
3282     q->prepareGeometryChange();
3283     mWidth = w;
3284
3285     q->geometryChanged(QRectF(q->x(), q->y(), width(), height()),
3286                     QRectF(q->x(), q->y(), oldWidth, height()));
3287 }
3288
3289 /*!
3290     \internal
3291 */
3292 void QDeclarativeItemPrivate::resetWidth()
3293 {
3294     Q_Q(QDeclarativeItem);
3295     widthValid = false;
3296     q->setImplicitWidth(q->implicitWidth());
3297 }
3298
3299 void QDeclarativeItemPrivate::implicitWidthChanged()
3300 {
3301     Q_Q(QDeclarativeItem);
3302     emit q->implicitWidthChanged();
3303 }
3304
3305 qreal QDeclarativeItemPrivate::implicitWidth() const
3306 {
3307     return mImplicitWidth;
3308 }
3309
3310 /*!
3311     Returns the width of the item that is implied by other properties that determine the content.
3312 */
3313 qreal QDeclarativeItem::implicitWidth() const
3314 {
3315     Q_D(const QDeclarativeItem);
3316     return d->implicitWidth();
3317 }
3318
3319 /*!
3320     Sets the implied width of the item to \a w.
3321     This is the width implied by other properties that determine the content.
3322 */
3323 void QDeclarativeItem::setImplicitWidth(qreal w)
3324 {
3325     Q_D(QDeclarativeItem);
3326     bool changed = w != d->mImplicitWidth;
3327     d->mImplicitWidth = w;
3328     if (d->mWidth == w || widthValid()) {
3329         if (changed)
3330             d->implicitWidthChanged();
3331         return;
3332     }
3333
3334     qreal oldWidth = d->mWidth;
3335
3336     prepareGeometryChange();
3337     d->mWidth = w;
3338
3339     geometryChanged(QRectF(x(), y(), width(), height()),
3340                     QRectF(x(), y(), oldWidth, height()));
3341
3342     if (changed)
3343         d->implicitWidthChanged();
3344 }
3345
3346 /*!
3347     Returns whether the width property has been set explicitly.
3348 */
3349 bool QDeclarativeItem::widthValid() const
3350 {
3351     Q_D(const QDeclarativeItem);
3352     return d->widthValid;
3353 }
3354
3355 /*!
3356     \internal
3357     Return the height of the item
3358 */
3359 qreal QDeclarativeItem::height() const
3360 {
3361     Q_D(const QDeclarativeItem);
3362     return d->height();
3363 }
3364
3365 /*!
3366     \internal
3367     Set the height of the item
3368 */
3369 void QDeclarativeItem::setHeight(qreal h)
3370 {
3371     Q_D(QDeclarativeItem);
3372     d->setHeight(h);
3373 }
3374
3375 /*!
3376     \internal
3377     Reset the height of the item
3378 */
3379 void QDeclarativeItem::resetHeight()
3380 {
3381     Q_D(QDeclarativeItem);
3382     d->resetHeight();
3383 }
3384
3385 /*!
3386     \internal
3387 */
3388 qreal QDeclarativeItemPrivate::height() const
3389 {
3390     return mHeight;
3391 }
3392
3393 /*!
3394     \internal
3395 */
3396 void QDeclarativeItemPrivate::setHeight(qreal h)
3397 {
3398     Q_Q(QDeclarativeItem);
3399     if (qIsNaN(h))
3400         return;
3401
3402     heightValid = true;
3403     if (mHeight == h)
3404         return;
3405
3406     qreal oldHeight = mHeight;
3407
3408     q->prepareGeometryChange();
3409     mHeight = h;
3410
3411     q->geometryChanged(QRectF(q->x(), q->y(), width(), height()),
3412                     QRectF(q->x(), q->y(), width(), oldHeight));
3413 }
3414
3415 /*!
3416     \internal
3417 */
3418 void QDeclarativeItemPrivate::resetHeight()
3419 {
3420     Q_Q(QDeclarativeItem);
3421     heightValid = false;
3422     q->setImplicitHeight(q->implicitHeight());
3423 }
3424
3425 void QDeclarativeItemPrivate::implicitHeightChanged()
3426 {
3427     Q_Q(QDeclarativeItem);
3428     emit q->implicitHeightChanged();
3429 }
3430
3431 qreal QDeclarativeItemPrivate::implicitHeight() const
3432 {
3433     return mImplicitHeight;
3434 }
3435
3436 /*!
3437     Returns the height of the item that is implied by other properties that determine the content.
3438 */
3439 qreal QDeclarativeItem::implicitHeight() const
3440 {
3441     Q_D(const QDeclarativeItem);
3442     return d->implicitHeight();
3443 }
3444
3445 /*!
3446     \qmlproperty real Item::implicitWidth
3447     \qmlproperty real Item::implicitHeight
3448     \since Quick 1.1
3449
3450     Defines the natural width or height of the Item if no \l width or \l height is specified.
3451
3452     The default implicit size for most items is 0x0, however some elements have an inherent
3453     implicit size which cannot be overridden, e.g. Image, Text.
3454
3455     Setting the implicit size is useful for defining components that have a preferred size
3456     based on their content, for example:
3457
3458     \qml
3459     // Label.qml
3460     import QtQuick 1.1
3461
3462     Item {
3463         property alias icon: image.source
3464         property alias label: text.text
3465         implicitWidth: text.implicitWidth + image.implicitWidth
3466         implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
3467         Image { id: image }
3468         Text {
3469             id: text
3470             wrapMode: Text.Wrap
3471             anchors.left: image.right; anchors.right: parent.right
3472             anchors.verticalCenter: parent.verticalCenter
3473         }
3474     }
3475     \endqml
3476
3477     \bold Note: using implicitWidth of Text or TextEdit and setting the width explicitly
3478     incurs a performance penalty as the text must be laid out twice.
3479 */
3480
3481
3482 /*!
3483     Sets the implied height of the item to \a h.
3484     This is the height implied by other properties that determine the content.
3485 */
3486 void QDeclarativeItem::setImplicitHeight(qreal h)
3487 {
3488     Q_D(QDeclarativeItem);
3489     bool changed = h != d->mImplicitHeight;
3490     d->mImplicitHeight = h;
3491     if (d->mHeight == h || heightValid()) {
3492         if (changed)
3493             d->implicitHeightChanged();
3494         return;
3495     }
3496
3497     qreal oldHeight = d->mHeight;
3498
3499     prepareGeometryChange();
3500     d->mHeight = h;
3501
3502     geometryChanged(QRectF(x(), y(), width(), height()),
3503                     QRectF(x(), y(), width(), oldHeight));
3504
3505     if (changed)
3506         d->implicitHeightChanged();
3507 }
3508
3509 /*!
3510     Returns whether the height property has been set explicitly.
3511 */
3512 bool QDeclarativeItem::heightValid() const
3513 {
3514     Q_D(const QDeclarativeItem);
3515     return d->heightValid;
3516 }
3517
3518 /*! \internal */
3519 void QDeclarativeItem::setSize(const QSizeF &size)
3520 {
3521     Q_D(QDeclarativeItem);
3522     d->heightValid = true;
3523     d->widthValid = true;
3524
3525     if (d->height() == size.height() && d->width() == size.width())
3526         return;
3527
3528     qreal oldHeight = d->height();
3529     qreal oldWidth = d->width();
3530
3531     prepareGeometryChange();
3532     d->setHeight(size.height());
3533     d->setWidth(size.width());
3534
3535     geometryChanged(QRectF(x(), y(), width(), height()),
3536                     QRectF(x(), y(), oldWidth, oldHeight));
3537 }
3538
3539 /*!
3540   \qmlproperty bool Item::activeFocus
3541
3542   This property indicates whether the item has active focus.
3543
3544   An item with active focus will receive keyboard input,
3545   or is a FocusScope ancestor of the item that will receive keyboard input.
3546
3547   Usually, activeFocus is gained by setting focus on an item and its enclosing
3548   FocusScopes. In the following example \c input will have activeFocus.
3549   \qml
3550   Rectangle {
3551       FocusScope {
3552           focus: true
3553           TextInput {
3554               id: input
3555               focus: true
3556           }
3557       }
3558   }
3559   \endqml
3560
3561   \sa focus, {qmlfocus}{Keyboard Focus}
3562 */
3563
3564 /*! \internal */
3565 bool QDeclarativeItem::hasActiveFocus() const
3566 {
3567     Q_D(const QDeclarativeItem);
3568     return focusItem() == this ||
3569            (d->flags & QGraphicsItem::ItemIsFocusScope && focusItem() != 0);
3570 }
3571
3572 /*!
3573   \qmlproperty bool Item::focus
3574   This property indicates whether the item has focus within the enclosing focus scope. If true, this item
3575   will gain active focus when the enclosing focus scope gains active focus.
3576   In the following example, \c input will be given active focus when \c scope gains active focus.
3577   \qml
3578   Rectangle {
3579       FocusScope {
3580           id: scope
3581           TextInput {
3582               id: input
3583               focus: true
3584           }
3585       }
3586   }
3587   \endqml
3588
3589   For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
3590   On a practical level, that means the following QML will give active focus to \c input on startup.
3591
3592   \qml
3593   Rectangle {
3594       TextInput {
3595           id: input
3596           focus: true
3597       }
3598   }
3599   \endqml
3600
3601   \sa activeFocus, {qmlfocus}{Keyboard Focus}
3602 */
3603
3604 /*! \internal */
3605 bool QDeclarativeItem::hasFocus() const
3606 {
3607     Q_D(const QDeclarativeItem);
3608     QGraphicsItem *p = d->parent;
3609     while (p) {
3610         if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
3611             return p->focusScopeItem() == this;
3612         }
3613         p = p->parentItem();
3614     }
3615
3616     return hasActiveFocus();
3617 }
3618
3619 /*! \internal */
3620 void QDeclarativeItem::setFocus(bool focus)
3621 {
3622     if (focus)
3623         QGraphicsItem::setFocus(Qt::OtherFocusReason);
3624     else
3625         QGraphicsItem::clearFocus();
3626 }
3627
3628 /*!
3629     \internal
3630 */
3631 void QDeclarativeItem::paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *)
3632 {
3633 }
3634
3635 /*!
3636     \internal
3637 */
3638 bool QDeclarativeItem::event(QEvent *ev)
3639 {
3640     Q_D(QDeclarativeItem);
3641     switch (ev->type()) {
3642     case QEvent::KeyPress:
3643     case QEvent::KeyRelease:
3644     case QEvent::InputMethod:
3645         d->doneEventPreHandler = false;
3646         break;
3647     default:
3648         break;
3649     }
3650
3651     return QGraphicsObject::event(ev);
3652 }
3653
3654 #ifndef QT_NO_DEBUG_STREAM
3655 QDebug operator<<(QDebug debug, QDeclarativeItem *item)
3656 {
3657     if (!item) {
3658         debug << "QDeclarativeItem(0)";
3659         return debug;
3660     }
3661
3662     debug << item->metaObject()->className() << "(this =" << ((void*)item)
3663           << ", parent =" << ((void*)item->parentItem())
3664           << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
3665           << ", z =" << item->zValue() << ')';
3666     return debug;
3667 }
3668 #endif
3669
3670 qint64 QDeclarativeItemPrivate::consistentTime = -1;
3671 void QDeclarativeItemPrivate::setConsistentTime(qint64 t)
3672 {
3673     consistentTime = t;
3674 }
3675
3676 class QElapsedTimerConsistentTimeHack
3677 {
3678 public:
3679     void start() {
3680         t1 = QDeclarativeItemPrivate::consistentTime;
3681         t2 = 0;
3682     }
3683     qint64 elapsed() {
3684         return QDeclarativeItemPrivate::consistentTime - t1;
3685     }
3686     qint64 restart() {
3687         qint64 val = QDeclarativeItemPrivate::consistentTime - t1;
3688         t1 = QDeclarativeItemPrivate::consistentTime;
3689         t2 = 0;
3690         return val;
3691     }
3692
3693 private:
3694     qint64 t1;
3695     qint64 t2;
3696 };
3697
3698 void QDeclarativeItemPrivate::start(QElapsedTimer &t)
3699 {
3700     if (QDeclarativeItemPrivate::consistentTime == -1)
3701         t.start();
3702     else
3703         ((QElapsedTimerConsistentTimeHack*)&t)->start();
3704 }
3705
3706 qint64 QDeclarativeItemPrivate::elapsed(QElapsedTimer &t)
3707 {
3708     if (QDeclarativeItemPrivate::consistentTime == -1)
3709         return t.elapsed();
3710     else
3711         return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
3712 }
3713
3714 qint64 QDeclarativeItemPrivate::restart(QElapsedTimer &t)
3715 {
3716     if (QDeclarativeItemPrivate::consistentTime == -1)
3717         return t.restart();
3718     else
3719         return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
3720 }
3721
3722 QT_END_NAMESPACE
3723
3724 #include <moc_qdeclarativeitem.cpp>