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