src/declarative/graphicsitems/qdeclarativeitem.cpp
changeset 30 5dc02b23752f
child 33 3e2da88830cd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp	Tue Jul 06 15:10:48 2010 +0300
@@ -0,0 +1,3187 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "private/qdeclarativeitem_p.h"
+#include "qdeclarativeitem.h"
+
+#include "private/qdeclarativeevents_p_p.h"
+#include <private/qdeclarativeengine_p.h>
+
+#include <qdeclarativeengine.h>
+#include <qdeclarativeopenmetaobject_p.h>
+#include <qdeclarativestate_p.h>
+#include <qdeclarativeview.h>
+#include <qdeclarativestategroup_p.h>
+#include <qdeclarativecomponent.h>
+#include <qdeclarativeinfo.h>
+
+#include <QDebug>
+#include <QPen>
+#include <QFile>
+#include <QEvent>
+#include <QGraphicsSceneMouseEvent>
+#include <QtCore/qnumeric.h>
+#include <QtScript/qscriptengine.h>
+#include <QtGui/qgraphicstransform.h>
+#include <qlistmodelinterface_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef FLT_MAX
+#define FLT_MAX 1E+37
+#endif
+
+/*!
+    \qmlclass Transform QGraphicsTransform
+    \since 4.7
+    \brief The Transform elements provide a way of building advanced transformations on Items.
+
+    The Transform element is a base type which cannot be instantiated directly.
+    The following concrete Transform types are available:
+
+    \list
+    \o \l Rotation
+    \o \l Scale
+    \o \l Translate
+    \endlist
+
+    The Transform elements let you create and control advanced transformations that can be configured
+    independently using specialized properties.
+
+    You can assign any number of Transform elements to an Item. Each Transform is applied in order,
+    one at a time, to the Item it's assigned to.
+*/
+
+/*!
+    \qmlclass Translate QGraphicsTranslate
+    \since 4.7
+    \brief The Translate object provides a way to move an Item without changing its x or y properties.
+
+    The Translate object provides independent control over position in addition to the Item's x and y properties.
+
+    The following example moves the Y axis of the Rectangles while still allowing the Row element
+    to lay the items out as if they had not been transformed:
+    \qml
+    Row {
+        Rectangle {
+            width: 100; height: 100
+            color: "blue"
+            transform: Translate { y: 20 }
+        }
+        Rectangle {
+            width: 100; height: 100
+            color: "red"
+            transform: Translate { y: -20 }
+        }
+    }
+    \endqml
+*/
+
+/*!
+    \qmlproperty real Translate::x
+
+    The translation along the X axis.
+*/
+
+/*!
+    \qmlproperty real Translate::y
+
+    The translation along the Y axis.
+*/
+
+/*!
+    \qmlclass Scale QGraphicsScale
+    \since 4.7
+    \brief The Scale object provides a way to scale an Item.
+
+    The Scale object gives more control over scaling than using Item's scale property. Specifically,
+    it allows a different scale for the x and y axes, and allows the scale to be relative to an
+    arbitrary point.
+
+    The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
+    \qml
+    Rectangle {
+        width: 100; height: 100
+        color: "blue"
+        transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
+    }
+    \endqml
+*/
+
+/*!
+    \qmlproperty real Scale::origin.x
+    \qmlproperty real Scale::origin.y
+
+    The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
+    the rest of the item grows). By default the origin is 0, 0.
+*/
+
+/*!
+    \qmlproperty real Scale::xScale
+
+    The scaling factor for the X axis.
+*/
+
+/*!
+    \qmlproperty real Scale::yScale
+
+    The scaling factor for the Y axis.
+*/
+
+/*!
+    \qmlclass Rotation QGraphicsRotation
+    \since 4.7
+    \brief The Rotation object provides a way to rotate an Item.
+
+    The Rotation object gives more control over rotation than using Item's rotation property.
+    Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
+
+    The following example rotates a Rectangle around its interior point 25, 25:
+    \qml
+    Rectangle {
+        width: 100; height: 100
+        color: "blue"
+        transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
+    }
+    \endqml
+
+    Rotation also provides a way to specify 3D-like rotations for Items. For these types of
+    rotations you must specify the axis to rotate around in addition to the origin point.
+
+    The following example shows various 3D-like rotations applied to an \l Image.
+    \snippet doc/src/snippets/declarative/rotation.qml 0
+
+    \image axisrotation.png
+*/
+
+/*!
+    \qmlproperty real Rotation::origin.x
+    \qmlproperty real Rotation::origin.y
+
+    The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
+    the rest of the item rotates). By default the origin is 0, 0.
+*/
+
+/*!
+    \qmlproperty real Rotation::axis.x
+    \qmlproperty real Rotation::axis.y
+    \qmlproperty real Rotation::axis.z
+
+    The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
+    as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
+
+    For a typical 3D-like rotation you will usually specify both the origin and the axis.
+
+    \image 3d-rotation-axis.png
+*/
+
+/*!
+    \qmlproperty real Rotation::angle
+
+    The angle to rotate, in degrees clockwise.
+*/
+
+/*!
+    \internal
+    \class QDeclarativeContents
+    \brief The QDeclarativeContents class gives access to the height and width of an item's contents.
+
+*/
+
+QDeclarativeContents::QDeclarativeContents() : m_x(0), m_y(0), m_width(0), m_height(0)
+{
+}
+
+QDeclarativeContents::~QDeclarativeContents()
+{
+    QList<QGraphicsItem *> children = m_item->childItems();
+    for (int i = 0; i < children.count(); ++i) {
+        QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i));
+        if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects?
+            continue;
+        QDeclarativeItemPrivate::get(child)->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
+    }
+}
+
+QRectF QDeclarativeContents::rectF() const
+{
+    return QRectF(m_x, m_y, m_width, m_height);
+}
+
+void QDeclarativeContents::calcHeight(QDeclarativeItem *changed)
+{
+    qreal oldy = m_y;
+    qreal oldheight = m_height;
+
+    if (changed) {
+        qreal top = oldy;
+        qreal bottom = oldy + oldheight;
+        qreal y = changed->y();
+        if (y + changed->height() > bottom)
+            bottom = y + changed->height();
+        if (y < top)
+            top = y;
+        m_y = top;
+        m_height = bottom - top;
+    } else {
+        qreal top = FLT_MAX;
+        qreal bottom = 0;
+        QList<QGraphicsItem *> children = m_item->childItems();
+        for (int i = 0; i < children.count(); ++i) {
+            QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i));
+            if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects?
+                continue;
+            qreal y = child->y();
+            if (y + child->height() > bottom)
+                bottom = y + child->height();
+            if (y < top)
+                top = y;
+        }
+        if (!children.isEmpty())
+            m_y = top;
+        m_height = qMax(bottom - top, qreal(0.0));
+    }
+
+    if (m_height != oldheight || m_y != oldy)
+        emit rectChanged(rectF());
+}
+
+void QDeclarativeContents::calcWidth(QDeclarativeItem *changed)
+{
+    qreal oldx = m_x;
+    qreal oldwidth = m_width;
+
+    if (changed) {
+        qreal left = oldx;
+        qreal right = oldx + oldwidth;
+        qreal x = changed->x();
+        if (x + changed->width() > right)
+            right = x + changed->width();
+        if (x < left)
+            left = x;
+        m_x = left;
+        m_width = right - left;
+    } else {
+        qreal left = FLT_MAX;
+        qreal right = 0;
+        QList<QGraphicsItem *> children = m_item->childItems();
+        for (int i = 0; i < children.count(); ++i) {
+            QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i));
+            if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects?
+                continue;
+            qreal x = child->x();
+            if (x + child->width() > right)
+                right = x + child->width();
+            if (x < left)
+                left = x;
+        }
+        if (!children.isEmpty())
+            m_x = left;
+        m_width = qMax(right - left, qreal(0.0));
+    }
+
+    if (m_width != oldwidth || m_x != oldx)
+        emit rectChanged(rectF());
+}
+
+void QDeclarativeContents::setItem(QDeclarativeItem *item)
+{
+    m_item = item;
+    //### optimize
+    connect(this, SIGNAL(rectChanged(QRectF)), m_item, SIGNAL(childrenRectChanged(QRectF)));
+
+    QList<QGraphicsItem *> children = m_item->childItems();
+    for (int i = 0; i < children.count(); ++i) {
+        QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i));
+        if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects?
+            continue;
+        QDeclarativeItemPrivate::get(child)->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
+        //###what about changes to visibility?
+    }
+
+    //### defer until componentComplete
+    calcHeight();
+    calcWidth();
+}
+
+void QDeclarativeContents::itemGeometryChanged(QDeclarativeItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+    if (newGeometry.width() != oldGeometry.width())
+        calcWidth(changed);
+    if (newGeometry.height() != oldGeometry.height())
+        calcHeight(changed);
+}
+
+void QDeclarativeContents::itemDestroyed(QDeclarativeItem *item)
+{
+    if (item)
+        QDeclarativeItemPrivate::get(item)->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
+    calcWidth();
+    calcHeight();
+}
+
+void QDeclarativeContents::childRemoved(QDeclarativeItem *item)
+{
+    if (item)
+        QDeclarativeItemPrivate::get(item)->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
+    calcWidth();
+    calcHeight();
+}
+
+void QDeclarativeContents::childAdded(QDeclarativeItem *item)
+{
+    if (item)
+        QDeclarativeItemPrivate::get(item)->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry | QDeclarativeItemPrivate::Destroyed);
+    calcWidth(item);
+    calcHeight(item);
+}
+
+QDeclarativeItemKeyFilter::QDeclarativeItemKeyFilter(QDeclarativeItem *item)
+: m_processPost(false), m_next(0)
+{
+    QDeclarativeItemPrivate *p =
+        item?static_cast<QDeclarativeItemPrivate *>(QGraphicsItemPrivate::get(item)):0;
+    if (p) {
+        m_next = p->keyHandler;
+        p->keyHandler = this;
+    }
+}
+
+QDeclarativeItemKeyFilter::~QDeclarativeItemKeyFilter()
+{
+}
+
+void QDeclarativeItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
+{
+    if (m_next) m_next->keyPressed(event, post);
+}
+
+void QDeclarativeItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
+{
+    if (m_next) m_next->keyReleased(event, post);
+}
+
+void QDeclarativeItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
+{
+    if (m_next) m_next->inputMethodEvent(event, post);
+}
+
+QVariant QDeclarativeItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+    if (m_next) return m_next->inputMethodQuery(query);
+    return QVariant();
+}
+
+void QDeclarativeItemKeyFilter::componentComplete()
+{
+    if (m_next) m_next->componentComplete();
+}
+
+
+/*!
+    \qmlclass KeyNavigation
+    \since 4.7
+    \brief The KeyNavigation attached property supports key navigation by arrow keys.
+
+    It is common in key-based UIs to use arrow keys to navigate
+    between focussed items.  The KeyNavigation property provides a
+    convenient way of specifying which item will gain focus
+    when an arrow key is pressed.  The following example provides
+    key navigation for a 2x2 grid of items.
+
+    \code
+    Grid {
+        columns: 2
+        width: 100; height: 100
+        Rectangle {
+            id: item1
+            focus: true
+            width: 50; height: 50
+            color: focus ? "red" : "lightgray"
+            KeyNavigation.right: item2
+            KeyNavigation.down: item3
+        }
+        Rectangle {
+            id: item2
+            width: 50; height: 50
+            color: focus ? "red" : "lightgray"
+            KeyNavigation.left: item1
+            KeyNavigation.down: item4
+        }
+        Rectangle {
+            id: item3
+            width: 50; height: 50
+            color: focus ? "red" : "lightgray"
+            KeyNavigation.right: item4
+            KeyNavigation.up: item1
+        }
+        Rectangle {
+            id: item4
+            width: 50; height: 50
+            color: focus ? "red" : "lightgray"
+            KeyNavigation.left: item3
+            KeyNavigation.up: item2
+        }
+    }
+    \endcode
+
+    By default KeyNavigation receives key events after the item it is attached to.
+    If the item accepts an arrow key event, the KeyNavigation
+    attached property will not receive an event for that key.  Setting the
+    \l priority property to KeyNavigation.BeforeItem allows handling
+    of the key events before normal item processing.
+
+    If an item has been set for a direction and the KeyNavigation
+    attached property receives the corresponding
+    key press and release events, the events will be accepted by
+    KeyNavigation and will not propagate any further.
+
+    \sa {Keys}{Keys attached property}
+*/
+
+/*!
+    \qmlproperty Item KeyNavigation::left
+    \qmlproperty Item KeyNavigation::right
+    \qmlproperty Item KeyNavigation::up
+    \qmlproperty Item KeyNavigation::down
+
+    These properties hold the item to assign focus to
+    when Key_Left, Key_Right, Key_Up or Key_Down are
+    pressed.
+*/
+
+QDeclarativeKeyNavigationAttached::QDeclarativeKeyNavigationAttached(QObject *parent)
+: QObject(*(new QDeclarativeKeyNavigationAttachedPrivate), parent),
+  QDeclarativeItemKeyFilter(qobject_cast<QDeclarativeItem*>(parent))
+{
+    m_processPost = true;
+}
+
+QDeclarativeKeyNavigationAttached *
+QDeclarativeKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
+{
+    return new QDeclarativeKeyNavigationAttached(obj);
+}
+
+QDeclarativeItem *QDeclarativeKeyNavigationAttached::left() const
+{
+    Q_D(const QDeclarativeKeyNavigationAttached);
+    return d->left;
+}
+
+void QDeclarativeKeyNavigationAttached::setLeft(QDeclarativeItem *i)
+{
+    Q_D(QDeclarativeKeyNavigationAttached);
+    d->left = i;
+    emit changed();
+}
+
+QDeclarativeItem *QDeclarativeKeyNavigationAttached::right() const
+{
+    Q_D(const QDeclarativeKeyNavigationAttached);
+    return d->right;
+}
+
+void QDeclarativeKeyNavigationAttached::setRight(QDeclarativeItem *i)
+{
+    Q_D(QDeclarativeKeyNavigationAttached);
+    d->right = i;
+    emit changed();
+}
+
+QDeclarativeItem *QDeclarativeKeyNavigationAttached::up() const
+{
+    Q_D(const QDeclarativeKeyNavigationAttached);
+    return d->up;
+}
+
+void QDeclarativeKeyNavigationAttached::setUp(QDeclarativeItem *i)
+{
+    Q_D(QDeclarativeKeyNavigationAttached);
+    d->up = i;
+    emit changed();
+}
+
+QDeclarativeItem *QDeclarativeKeyNavigationAttached::down() const
+{
+    Q_D(const QDeclarativeKeyNavigationAttached);
+    return d->down;
+}
+
+void QDeclarativeKeyNavigationAttached::setDown(QDeclarativeItem *i)
+{
+    Q_D(QDeclarativeKeyNavigationAttached);
+    d->down = i;
+    emit changed();
+}
+
+QDeclarativeItem *QDeclarativeKeyNavigationAttached::tab() const
+{
+    Q_D(const QDeclarativeKeyNavigationAttached);
+    return d->tab;
+}
+
+void QDeclarativeKeyNavigationAttached::setTab(QDeclarativeItem *i)
+{
+    Q_D(QDeclarativeKeyNavigationAttached);
+    d->tab = i;
+    emit changed();
+}
+
+QDeclarativeItem *QDeclarativeKeyNavigationAttached::backtab() const
+{
+    Q_D(const QDeclarativeKeyNavigationAttached);
+    return d->backtab;
+}
+
+void QDeclarativeKeyNavigationAttached::setBacktab(QDeclarativeItem *i)
+{
+    Q_D(QDeclarativeKeyNavigationAttached);
+    d->backtab = i;
+    emit changed();
+}
+
+/*!
+    \qmlproperty enumeration KeyNavigation::priority
+
+    This property determines whether the keys are processed before
+    or after the attached item's own key handling.
+
+    \list
+    \o KeyNavigation.BeforeItem - process the key events before normal
+    item key processing.  If the event is accepted it will not
+    be passed on to the item.
+    \o KeyNavigation.AfterItem (default) - process the key events after normal item key
+    handling.  If the item accepts the key event it will not be
+    handled by the KeyNavigation attached property handler.
+    \endlist
+*/
+QDeclarativeKeyNavigationAttached::Priority QDeclarativeKeyNavigationAttached::priority() const
+{
+    return m_processPost ? AfterItem : BeforeItem;
+}
+
+void QDeclarativeKeyNavigationAttached::setPriority(Priority order)
+{
+    bool processPost = order == AfterItem;
+    if (processPost != m_processPost) {
+        m_processPost = processPost;
+        emit priorityChanged();
+    }
+}
+
+void QDeclarativeKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
+{
+    Q_D(QDeclarativeKeyNavigationAttached);
+    event->ignore();
+
+    if (post != m_processPost) {
+        QDeclarativeItemKeyFilter::keyPressed(event, post);
+        return;
+    }
+
+    switch(event->key()) {
+    case Qt::Key_Left:
+        if (d->left) {
+            d->left->setFocus(true);
+            event->accept();
+        }
+        break;
+    case Qt::Key_Right:
+        if (d->right) {
+            d->right->setFocus(true);
+            event->accept();
+        }
+        break;
+    case Qt::Key_Up:
+        if (d->up) {
+            d->up->setFocus(true);
+            event->accept();
+        }
+        break;
+    case Qt::Key_Down:
+        if (d->down) {
+            d->down->setFocus(true);
+            event->accept();
+        }
+        break;
+    case Qt::Key_Tab:
+        if (d->tab) {
+            d->tab->setFocus(true);
+            event->accept();
+        }
+        break;
+    case Qt::Key_Backtab:
+        if (d->backtab) {
+            d->backtab->setFocus(true);
+            event->accept();
+        }
+        break;
+    default:
+        break;
+    }
+
+    if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyPressed(event, post);
+}
+
+void QDeclarativeKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
+{
+    Q_D(QDeclarativeKeyNavigationAttached);
+    event->ignore();
+
+    if (post != m_processPost) {
+        QDeclarativeItemKeyFilter::keyReleased(event, post);
+        return;
+    }
+
+    switch(event->key()) {
+    case Qt::Key_Left:
+        if (d->left) {
+            event->accept();
+        }
+        break;
+    case Qt::Key_Right:
+        if (d->right) {
+            event->accept();
+        }
+        break;
+    case Qt::Key_Up:
+        if (d->up) {
+            event->accept();
+        }
+        break;
+    case Qt::Key_Down:
+        if (d->down) {
+            event->accept();
+        }
+        break;
+    case Qt::Key_Tab:
+        if (d->tab) {
+            event->accept();
+        }
+        break;
+    case Qt::Key_Backtab:
+        if (d->backtab) {
+            event->accept();
+        }
+        break;
+    default:
+        break;
+    }
+
+    if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyReleased(event, post);
+}
+
+/*!
+    \qmlclass Keys
+    \since 4.7
+    \brief The Keys attached property provides key handling to Items.
+
+    All visual primitives support key handling via the \e Keys
+    attached property.  Keys can be handled via the \e onPressed
+    and \e onReleased signal properties.
+
+    The signal properties have a \l KeyEvent parameter, named
+    \e event which contains details of the event.  If a key is
+    handled \e event.accepted should be set to true to prevent the
+    event from propagating up the item heirarchy.
+
+    \code
+    Item {
+        focus: true
+        Keys.onPressed: {
+            if (event.key == Qt.Key_Left) {
+                console.log("move left");
+                event.accepted = true;
+            }
+        }
+    }
+    \endcode
+
+    Some keys may alternatively be handled via specific signal properties,
+    for example \e onSelectPressed.  These handlers automatically set
+    \e event.accepted to true.
+
+    \code
+    Item {
+        focus: true
+        Keys.onLeftPressed: console.log("move left")
+    }
+    \endcode
+
+    See \l {Qt::Key}{Qt.Key} for the list of keyboard codes.
+
+    If priority is Keys.BeforeItem (default) the order of key event processing is:
+
+    \list 1
+    \o Items specified in \c forwardTo
+    \o specific key handlers, e.g. onReturnPressed
+    \o onKeyPress, onKeyRelease handlers
+    \o Item specific key handling, e.g. TextInput key handling
+    \o parent item
+    \endlist
+
+    If priority is Keys.AfterItem the order of key event processing is:
+    \list 1
+    \o Item specific key handling, e.g. TextInput key handling
+    \o Items specified in \c forwardTo
+    \o specific key handlers, e.g. onReturnPressed
+    \o onKeyPress, onKeyRelease handlers
+    \o parent item
+    \endlist
+
+    If the event is accepted during any of the above steps, key
+    propagation stops.
+
+    \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
+*/
+
+/*!
+    \qmlproperty bool Keys::enabled
+
+    This flags enables key handling if true (default); otherwise
+    no key handlers will be called.
+*/
+
+/*!
+    \qmlproperty enumeration Keys::priority
+
+    This property determines whether the keys are processed before
+    or after the attached item's own key handling.
+
+    \list
+    \o Keys.BeforeItem (default) - process the key events before normal
+    item key processing.  If the event is accepted it will not
+    be passed on to the item.
+    \o Keys.AfterItem - process the key events after normal item key
+    handling.  If the item accepts the key event it will not be
+    handled by the Keys attached property handler.
+    \endlist
+*/
+
+/*!
+    \qmlproperty list<Object> Keys::forwardTo
+
+    This property provides a way to forward key presses, key releases, and keyboard input
+    coming from input methods to other items. This can be useful when you want
+    one item to handle some keys (e.g. the up and down arrow keys), and another item to
+    handle other keys (e.g. the left and right arrow keys).  Once an item that has been
+    forwarded keys accepts the event it is no longer forwarded to items later in the
+    list.
+
+    This example forwards key events to two lists:
+    \qml
+    ListView { id: list1 ... }
+    ListView { id: list2 ... }
+    Keys.forwardTo: [list1, list2]
+    focus: true
+    \endqml
+*/
+
+/*!
+    \qmlsignal Keys::onPressed(event)
+
+    This handler is called when a key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onReleased(event)
+
+    This handler is called when a key has been released. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onDigit0Pressed(event)
+
+    This handler is called when the digit '0' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onDigit1Pressed(event)
+
+    This handler is called when the digit '1' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onDigit2Pressed(event)
+
+    This handler is called when the digit '2' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onDigit3Pressed(event)
+
+    This handler is called when the digit '3' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onDigit4Pressed(event)
+
+    This handler is called when the digit '4' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onDigit5Pressed(event)
+
+    This handler is called when the digit '5' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onDigit6Pressed(event)
+
+    This handler is called when the digit '6' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onDigit7Pressed(event)
+
+    This handler is called when the digit '7' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onDigit8Pressed(event)
+
+    This handler is called when the digit '8' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onDigit9Pressed(event)
+
+    This handler is called when the digit '9' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onLeftPressed(event)
+
+    This handler is called when the Left arrow has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onRightPressed(event)
+
+    This handler is called when the Right arrow has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onUpPressed(event)
+
+    This handler is called when the Up arrow has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onDownPressed(event)
+
+    This handler is called when the Down arrow has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onAsteriskPressed(event)
+
+    This handler is called when the Asterisk '*' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onEscapePressed(event)
+
+    This handler is called when the Escape key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onReturnPressed(event)
+
+    This handler is called when the Return key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onEnterPressed(event)
+
+    This handler is called when the Enter key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onDeletePressed(event)
+
+    This handler is called when the Delete key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onSpacePressed(event)
+
+    This handler is called when the Space key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onBackPressed(event)
+
+    This handler is called when the Back key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onCancelPressed(event)
+
+    This handler is called when the Cancel key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onSelectPressed(event)
+
+    This handler is called when the Select key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onYesPressed(event)
+
+    This handler is called when the Yes key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onNoPressed(event)
+
+    This handler is called when the No key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onContext1Pressed(event)
+
+    This handler is called when the Context1 key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onContext2Pressed(event)
+
+    This handler is called when the Context2 key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onContext3Pressed(event)
+
+    This handler is called when the Context3 key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onContext4Pressed(event)
+
+    This handler is called when the Context4 key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onCallPressed(event)
+
+    This handler is called when the Call key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onHangupPressed(event)
+
+    This handler is called when the Hangup key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onFlipPressed(event)
+
+    This handler is called when the Flip key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onMenuPressed(event)
+
+    This handler is called when the Menu key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onVolumeUpPressed(event)
+
+    This handler is called when the VolumeUp key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal Keys::onVolumeDownPressed(event)
+
+    This handler is called when the VolumeDown key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+const QDeclarativeKeysAttached::SigMap QDeclarativeKeysAttached::sigMap[] = {
+    { Qt::Key_Left, "leftPressed" },
+    { Qt::Key_Right, "rightPressed" },
+    { Qt::Key_Up, "upPressed" },
+    { Qt::Key_Down, "downPressed" },
+    { Qt::Key_Tab, "tabPressed" },
+    { Qt::Key_Backtab, "backtabPressed" },
+    { Qt::Key_Asterisk, "asteriskPressed" },
+    { Qt::Key_NumberSign, "numberSignPressed" },
+    { Qt::Key_Escape, "escapePressed" },
+    { Qt::Key_Return, "returnPressed" },
+    { Qt::Key_Enter, "enterPressed" },
+    { Qt::Key_Delete, "deletePressed" },
+    { Qt::Key_Space, "spacePressed" },
+    { Qt::Key_Back, "backPressed" },
+    { Qt::Key_Cancel, "cancelPressed" },
+    { Qt::Key_Select, "selectPressed" },
+    { Qt::Key_Yes, "yesPressed" },
+    { Qt::Key_No, "noPressed" },
+    { Qt::Key_Context1, "context1Pressed" },
+    { Qt::Key_Context2, "context2Pressed" },
+    { Qt::Key_Context3, "context3Pressed" },
+    { Qt::Key_Context4, "context4Pressed" },
+    { Qt::Key_Call, "callPressed" },
+    { Qt::Key_Hangup, "hangupPressed" },
+    { Qt::Key_Flip, "flipPressed" },
+    { Qt::Key_Menu, "menuPressed" },
+    { Qt::Key_VolumeUp, "volumeUpPressed" },
+    { Qt::Key_VolumeDown, "volumeDownPressed" },
+    { 0, 0 }
+};
+
+bool QDeclarativeKeysAttachedPrivate::isConnected(const char *signalName)
+{
+    return isSignalConnected(signalIndex(signalName));
+}
+
+QDeclarativeKeysAttached::QDeclarativeKeysAttached(QObject *parent)
+: QObject(*(new QDeclarativeKeysAttachedPrivate), parent),
+  QDeclarativeItemKeyFilter(qobject_cast<QDeclarativeItem*>(parent))
+{
+    Q_D(QDeclarativeKeysAttached);
+    m_processPost = false;
+    d->item = qobject_cast<QDeclarativeItem*>(parent);
+}
+
+QDeclarativeKeysAttached::~QDeclarativeKeysAttached()
+{
+}
+
+QDeclarativeKeysAttached::Priority QDeclarativeKeysAttached::priority() const
+{
+    return m_processPost ? AfterItem : BeforeItem;
+}
+
+void QDeclarativeKeysAttached::setPriority(Priority order)
+{
+    bool processPost = order == AfterItem;
+    if (processPost != m_processPost) {
+        m_processPost = processPost;
+        emit priorityChanged();
+    }
+}
+
+void QDeclarativeKeysAttached::componentComplete()
+{
+    Q_D(QDeclarativeKeysAttached);
+    if (d->item) {
+        for (int ii = 0; ii < d->targets.count(); ++ii) {
+            QGraphicsItem *targetItem = d->finalFocusProxy(d->targets.at(ii));
+            if (targetItem && (targetItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) {
+                d->item->setFlag(QGraphicsItem::ItemAcceptsInputMethod);
+                break;
+            }
+        }
+    }
+}
+
+void QDeclarativeKeysAttached::keyPressed(QKeyEvent *event, bool post)
+{
+    Q_D(QDeclarativeKeysAttached);
+    if (post != m_processPost || !d->enabled || d->inPress) {
+        event->ignore();
+        QDeclarativeItemKeyFilter::keyPressed(event, post);
+        return;
+    }
+
+    // first process forwards
+    if (d->item && d->item->scene()) {
+        d->inPress = true;
+        for (int ii = 0; ii < d->targets.count(); ++ii) {
+            QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii));
+            if (i) {
+                d->item->scene()->sendEvent(i, event);
+                if (event->isAccepted()) {
+                    d->inPress = false;
+                    return;
+                }
+            }
+        }
+        d->inPress = false;
+    }
+
+    QDeclarativeKeyEvent ke(*event);
+    QByteArray keySignal = keyToSignal(event->key());
+    if (!keySignal.isEmpty()) {
+        keySignal += "(QDeclarativeKeyEvent*)";
+        if (d->isConnected(keySignal)) {
+            // If we specifically handle a key then default to accepted
+            ke.setAccepted(true);
+            int idx = QDeclarativeKeysAttached::staticMetaObject.indexOfSignal(keySignal);
+            metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QDeclarativeKeyEvent*, &ke));
+        }
+    }
+    if (!ke.isAccepted())
+        emit pressed(&ke);
+    event->setAccepted(ke.isAccepted());
+
+    if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyPressed(event, post);
+}
+
+void QDeclarativeKeysAttached::keyReleased(QKeyEvent *event, bool post)
+{
+    Q_D(QDeclarativeKeysAttached);
+    if (post != m_processPost || !d->enabled || d->inRelease) {
+        event->ignore();
+        QDeclarativeItemKeyFilter::keyReleased(event, post);
+        return;
+    }
+
+    if (d->item && d->item->scene()) {
+        d->inRelease = true;
+        for (int ii = 0; ii < d->targets.count(); ++ii) {
+            QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii));
+            if (i) {
+                d->item->scene()->sendEvent(i, event);
+                if (event->isAccepted()) {
+                    d->inRelease = false;
+                    return;
+                }
+            }
+        }
+        d->inRelease = false;
+    }
+
+    QDeclarativeKeyEvent ke(*event);
+    emit released(&ke);
+    event->setAccepted(ke.isAccepted());
+
+    if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyReleased(event, post);
+}
+
+void QDeclarativeKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
+{
+    Q_D(QDeclarativeKeysAttached);
+    if (post == m_processPost && d->item && !d->inIM && d->item->scene()) {
+        d->inIM = true;
+        for (int ii = 0; ii < d->targets.count(); ++ii) {
+            QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii));
+            if (i && (i->flags() & QGraphicsItem::ItemAcceptsInputMethod)) {
+                d->item->scene()->sendEvent(i, event);
+                if (event->isAccepted()) {
+                    d->imeItem = i;
+                    d->inIM = false;
+                    return;
+                }
+            }
+        }
+        d->inIM = false;
+    }
+    if (!event->isAccepted()) QDeclarativeItemKeyFilter::inputMethodEvent(event, post);
+}
+
+class QDeclarativeItemAccessor : public QGraphicsItem
+{
+public:
+    QVariant doInputMethodQuery(Qt::InputMethodQuery query) const {
+        return QGraphicsItem::inputMethodQuery(query);
+    }
+};
+
+QVariant QDeclarativeKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+    Q_D(const QDeclarativeKeysAttached);
+    if (d->item) {
+        for (int ii = 0; ii < d->targets.count(); ++ii) {
+                QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii));
+            if (i && (i->flags() & QGraphicsItem::ItemAcceptsInputMethod) && i == d->imeItem) { //### how robust is i == d->imeItem check?
+                QVariant v = static_cast<QDeclarativeItemAccessor *>(i)->doInputMethodQuery(query);
+                if (v.userType() == QVariant::RectF)
+                    v = d->item->mapRectFromItem(i, v.toRectF());  //### cost?
+                return v;
+            }
+        }
+    }
+    return QDeclarativeItemKeyFilter::inputMethodQuery(query);
+}
+
+QDeclarativeKeysAttached *QDeclarativeKeysAttached::qmlAttachedProperties(QObject *obj)
+{
+    return new QDeclarativeKeysAttached(obj);
+}
+
+/*!
+    \class QDeclarativeItem
+    \since 4.7
+    \brief The QDeclarativeItem class provides the most basic of all visual items in QML.
+
+    All visual items in Qt Declarative inherit from QDeclarativeItem.  Although QDeclarativeItem
+    has no visual appearance, it defines all the properties that are
+    common across visual items - such as the x and y position, the
+    width and height, \l {anchor-layout}{anchoring} and key handling.
+
+    You can subclass QDeclarativeItem to provide your own custom visual item that inherits
+    these features. Note that, because it does not draw anything, QDeclarativeItem sets the
+    QGraphicsItem::ItemHasNoContents flag. If you subclass QDeclarativeItem to create a visual
+    item, you will need to unset this flag.
+
+*/
+
+/*!
+    \qmlclass Item QDeclarativeItem
+    \since 4.7
+    \brief The Item is the most basic of all visual items in QML.
+
+    All visual items in Qt Declarative inherit from Item.  Although Item
+    has no visual appearance, it defines all the properties that are
+    common across visual items - such as the x and y position, the
+    width and height, \l {anchor-layout}{anchoring} and key handling.
+
+    Item is also useful for grouping items together.
+
+    \qml
+    Item {
+        Image {
+            source: "tile.png"
+        }
+        Image {
+            x: 80
+            width: 100
+            height: 100
+            source: "tile.png"
+        }
+        Image {
+            x: 190
+            width: 100
+            height: 100
+            fillMode: Image.Tile
+            source: "tile.png"
+        }
+    }
+    \endqml
+
+    \section1 Identity
+
+    Each item has an "id" - the identifier of the Item.
+
+    The identifier can be used in bindings and other expressions to
+    refer to the item. For example:
+
+    \qml
+    Text { id: myText; ... }
+    Text { text: myText.text }
+    \endqml
+
+    The identifier is available throughout to the \l {components}{component}
+    where it is declared.  The identifier must be unique in the component.
+
+    The id should not be thought of as a "property" - it makes no sense
+    to write \c myText.id, for example.
+
+    \section1 Key Handling
+
+    Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
+    attached property.  The \e Keys attached property provides basic handlers such
+    as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
+    as well as handlers for specific keys, such as
+    \l {Keys::onCancelPressed}{onCancelPressed}.  The example below
+    assigns \l {qmlfocus}{focus} to the item and handles
+    the Left key via the general \e onPressed handler and the Select key via the
+    onSelectPressed handler:
+
+    \qml
+    Item {
+        focus: true
+        Keys.onPressed: {
+            if (event.key == Qt.Key_Left) {
+                console.log("move left");
+                event.accepted = true;
+            }
+        }
+        Keys.onSelectPressed: console.log("Selected");
+    }
+    \endqml
+
+    See the \l {Keys}{Keys} attached property for detailed documentation.
+
+    \section1 Property Change Signals
+
+    Most properties on Item and Item derivatives have a signal
+    emitted when they change. By convention, the signals are
+    named <propertyName>Changed, e.g. xChanged will be emitted when an item's
+    x property changes. Note that these also have signal handers e.g.
+    the onXChanged signal handler will be called when an item's x property
+    changes. For many properties in Item or Item derivatives this can be used
+    to add a touch of imperative logic to your application (when absolutely
+    necessary).
+*/
+
+/*!
+    \property QDeclarativeItem::baseline
+    \internal
+*/
+
+/*!
+    \property QDeclarativeItem::focus
+    \internal
+*/
+
+/*!
+    \property QDeclarativeItem::wantsFocus
+    \internal
+*/
+
+/*!
+    \property QDeclarativeItem::transformOrigin
+    \internal
+*/
+
+/*!
+    \fn void QDeclarativeItem::childrenRectChanged(const QRectF &)
+    \internal
+*/
+
+/*!
+    \fn void QDeclarativeItem::baselineOffsetChanged(qreal)
+    \internal
+*/
+
+/*!
+    \fn void QDeclarativeItem::stateChanged(const QString &state)
+    \internal
+*/
+
+/*!
+    \fn void QDeclarativeItem::parentChanged(QDeclarativeItem *)
+    \internal
+*/
+
+/*!
+    \fn void QDeclarativeItem::smoothChanged(bool)
+    \internal
+*/
+
+/*!
+    \fn void QDeclarativeItem::clipChanged(bool)
+    \internal
+*/
+
+/*! \fn void QDeclarativeItem::transformOriginChanged(TransformOrigin)
+  \internal
+*/
+
+/*!
+    \fn void QDeclarativeItem::childrenChanged()
+    \internal
+*/
+
+/*!
+    \fn void QDeclarativeItem::focusChanged(bool)
+    \internal
+*/
+
+/*!
+    \fn void QDeclarativeItem::wantsFocusChanged(bool)
+    \internal
+*/
+
+// ### Must fix
+struct RegisterAnchorLineAtStartup {
+    RegisterAnchorLineAtStartup() {
+        qRegisterMetaType<QDeclarativeAnchorLine>("QDeclarativeAnchorLine");
+    }
+};
+static RegisterAnchorLineAtStartup registerAnchorLineAtStartup;
+
+
+/*!
+    \fn QDeclarativeItem::QDeclarativeItem(QDeclarativeItem *parent)
+
+    Constructs a QDeclarativeItem with the given \a parent.
+*/
+QDeclarativeItem::QDeclarativeItem(QDeclarativeItem* parent)
+  : QGraphicsObject(*(new QDeclarativeItemPrivate), parent, 0)
+{
+    Q_D(QDeclarativeItem);
+    d->init(parent);
+}
+
+/*! \internal
+*/
+QDeclarativeItem::QDeclarativeItem(QDeclarativeItemPrivate &dd, QDeclarativeItem *parent)
+  : QGraphicsObject(dd, parent, 0)
+{
+    Q_D(QDeclarativeItem);
+    d->init(parent);
+}
+
+/*!
+    Destroys the QDeclarativeItem.
+*/
+QDeclarativeItem::~QDeclarativeItem()
+{
+    Q_D(QDeclarativeItem);
+    for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
+        QDeclarativeAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
+        if (anchor)
+            anchor->clearItem(this);
+    }
+    if (!d->parent || (parentItem() && !parentItem()->QGraphicsItem::d_ptr->inDestructor)) {
+        for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
+            QDeclarativeAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
+            if (anchor && anchor->item && anchor->item->parentItem() != this) //child will be deleted anyway
+                anchor->updateOnComplete();
+        }
+    }
+    for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
+        const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
+        if (change.types & QDeclarativeItemPrivate::Destroyed)
+            change.listener->itemDestroyed(this);
+    }
+    d->changeListeners.clear();
+    delete d->_anchorLines; d->_anchorLines = 0;
+    delete d->_anchors; d->_anchors = 0;
+    delete d->_stateGroup; d->_stateGroup = 0;
+    delete d->_contents; d->_contents = 0;
+}
+
+/*!
+    \qmlproperty enumeration Item::transformOrigin
+    This property holds the origin point around which scale and rotation transform.
+
+    Nine transform origins are available, as shown in the image below.
+
+    \image declarative-transformorigin.png
+
+    This example rotates an image around its bottom-right corner.
+    \qml
+    Image {
+        source: "myimage.png"
+        transformOrigin: Item.BottomRight
+        rotation: 45
+    }
+    \endqml
+
+    The default transform origin is \c Item.Center.
+*/
+
+/*!
+    \qmlproperty Item Item::parent
+    This property holds the parent of the item.
+*/
+
+/*!
+    \property QDeclarativeItem::parent
+    This property holds the parent of the item.
+*/
+void QDeclarativeItem::setParentItem(QDeclarativeItem *parent)
+{
+    QGraphicsObject::setParentItem(parent);
+}
+
+/*!
+    Returns the QDeclarativeItem parent of this item.
+*/
+QDeclarativeItem *QDeclarativeItem::parentItem() const
+{
+    return qobject_cast<QDeclarativeItem *>(QGraphicsObject::parentItem());
+}
+
+/*!
+    \qmlproperty real Item::childrenRect.x
+    \qmlproperty real Item::childrenRect.y
+    \qmlproperty real Item::childrenRect.width
+    \qmlproperty real Item::childrenRect.height
+
+    The childrenRect properties allow an item access to the geometry of its
+    children. This property is useful if you have an item that needs to be
+    sized to fit its children.
+*/
+
+
+/*!
+    \qmlproperty list<Item> Item::children
+    \qmlproperty list<Object> Item::resources
+
+    The children property contains the list of visual children of this item.
+    The resources property contains non-visual resources that you want to
+    reference by name.
+
+    Generally you can rely on Item's default property to handle all this for
+    you, but it can come in handy in some cases.
+
+    \qml
+    Item {
+        children: [
+            Text {},
+            Rectangle {}
+        ]
+        resources: [
+            Component {
+                id: myComponent
+                Text {}
+            }
+        ]
+    }
+    \endqml
+*/
+
+/*!
+    Returns true if construction of the QML component is complete; otherwise
+    returns false.
+
+    It is often desireable to delay some processing until the component is
+    completed.
+
+    \sa componentComplete()
+*/
+bool QDeclarativeItem::isComponentComplete() const
+{
+    Q_D(const QDeclarativeItem);
+    return d->_componentComplete;
+}
+
+void QDeclarativeItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
+{
+    if (!o)
+        return;
+
+    QDeclarativeItem *that = static_cast<QDeclarativeItem *>(prop->object);
+
+    // This test is measurably (albeit only slightly) faster than qobject_cast<>()
+    const QMetaObject *mo = o->metaObject();
+    while (mo && mo != &QGraphicsObject::staticMetaObject) mo = mo->d.superdata;
+
+    if (mo) {
+        QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(o))->setParentItemHelper(that, 0, 0);
+    } else {
+        o->setParent(that);
+    }
+}
+
+QObject *QDeclarativeItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop, int index)
+{
+    QObjectList children = prop->object->children();
+    if (index < children.count())
+        return children.at(index);
+    else
+        return 0;
+}
+
+void QDeclarativeItemPrivate::resources_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
+{
+    o->setParent(prop->object);
+}
+
+int QDeclarativeItemPrivate::resources_count(QDeclarativeListProperty<QObject> *prop)
+{
+    return prop->object->children().count();
+}
+
+int QDeclarativeItemPrivate::transform_count(QDeclarativeListProperty<QGraphicsTransform> *list)
+{
+    QGraphicsObject *object = qobject_cast<QGraphicsObject *>(list->object);
+    if (object) {
+        QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(object);
+        return d->transformData ? d->transformData->graphicsTransforms.size() : 0;
+    } else {
+        return 0;
+    }
+}
+
+void QDeclarativeItemPrivate::transform_append(QDeclarativeListProperty<QGraphicsTransform> *list, QGraphicsTransform *item)
+{
+    QGraphicsObject *object = qobject_cast<QGraphicsObject *>(list->object);
+    if (object) // QGraphicsItem applies the list in the wrong order, so we prepend.
+        QGraphicsItemPrivate::get(object)->prependGraphicsTransform(item);
+}
+
+QGraphicsTransform *QDeclarativeItemPrivate::transform_at(QDeclarativeListProperty<QGraphicsTransform> *list, int idx)
+{
+    QGraphicsObject *object = qobject_cast<QGraphicsObject *>(list->object);
+    if (object) {
+        QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(object);
+        if (!d->transformData)
+            return 0;
+        return d->transformData->graphicsTransforms.at(idx);
+    } else {
+        return 0;
+    }
+}
+
+void QDeclarativeItemPrivate::transform_clear(QDeclarativeListProperty<QGraphicsTransform> *list)
+{
+    QGraphicsObject *object = qobject_cast<QGraphicsObject *>(list->object);
+    if (object) {
+        QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(object);
+        if (!d->transformData)
+            return;
+        object->setTransformations(QList<QGraphicsTransform *>());
+    }
+}
+
+void QDeclarativeItemPrivate::parentProperty(QObject *o, void *rv, QDeclarativeNotifierEndpoint *e)
+{
+    QDeclarativeItem *item = static_cast<QDeclarativeItem*>(o);
+    if (e)
+        e->connect(&item->d_func()->parentNotifier);
+    *((QDeclarativeItem **)rv) = item->parentItem();
+}
+
+/*!
+    \qmlproperty list<Object> Item::data
+    \default
+
+    The data property is allows you to freely mix visual children and resources
+    of an item.  If you assign a visual item to the data list it becomes
+    a child and if you assign any other object type, it is added as a resource.
+
+    So you can write:
+    \qml
+    Item {
+        Text {}
+        Rectangle {}
+        Timer {}
+    }
+    \endqml
+
+    instead of:
+    \qml
+    Item {
+        children: [
+            Text {},
+            Rectangle {}
+        ]
+        resources: [
+            Timer {}
+        ]
+    }
+    \endqml
+
+    data is a behind-the-scenes property: you should never need to explicitly
+    specify it.
+ */
+
+/*! \internal */
+QDeclarativeListProperty<QObject> QDeclarativeItemPrivate::data()
+{
+    return QDeclarativeListProperty<QObject>(q_func(), 0, QDeclarativeItemPrivate::data_append);
+}
+
+/*!
+    \property QDeclarativeItem::childrenRect
+    \brief The geometry of an item's children.
+
+    This property holds the (collective) position and size of the item's children.
+*/
+QRectF QDeclarativeItem::childrenRect()
+{
+    Q_D(QDeclarativeItem);
+    if (!d->_contents) {
+        d->_contents = new QDeclarativeContents;
+        d->_contents->setItem(this);
+    }
+    return d->_contents->rectF();
+}
+
+bool QDeclarativeItem::clip() const
+{
+    return flags() & ItemClipsChildrenToShape;
+}
+
+void QDeclarativeItem::setClip(bool c)
+{
+    if (clip() == c)
+        return;
+    setFlag(ItemClipsChildrenToShape, c);
+    emit clipChanged(c);
+}
+
+/*!
+  \qmlproperty real Item::x
+  \qmlproperty real Item::y
+  \qmlproperty real Item::width
+  \qmlproperty real Item::height
+
+  Defines the item's position and size relative to its parent.
+
+  \qml
+  Item { x: 100; y: 100; width: 100; height: 100 }
+  \endqml
+ */
+
+/*!
+  \qmlproperty real Item::z
+
+  Sets the stacking order of the item.  By default the stacking order is 0.
+
+  Items with a higher stacking value are drawn on top of items with a
+  lower stacking order.  Items with the same stacking value are drawn
+  bottom up in the order they appear.  Items with a negative stacking
+  value are drawn under their parent's content.
+
+  The following example shows the various effects of stacking order.
+
+  \table
+  \row
+  \o \image declarative-item_stacking1.png
+  \o Same \c z - later children above earlier children:
+  \qml
+  Item {
+      Rectangle {
+          color: "red"
+          width: 100; height: 100
+      }
+      Rectangle {
+          color: "blue"
+          x: 50; y: 50; width: 100; height: 100
+      }
+  }
+  \endqml
+  \row
+  \o \image declarative-item_stacking2.png
+  \o Higher \c z on top:
+  \qml
+  Item {
+      Rectangle {
+          z: 1
+          color: "red"
+          width: 100; height: 100
+      }
+      Rectangle {
+          color: "blue"
+          x: 50; y: 50; width: 100; height: 100
+      }
+  }
+  \endqml
+  \row
+  \o \image declarative-item_stacking3.png
+  \o Same \c z - children above parents:
+  \qml
+  Item {
+      Rectangle {
+          color: "red"
+          width: 100; height: 100
+          Rectangle {
+              color: "blue"
+              x: 50; y: 50; width: 100; height: 100
+          }
+      }
+  }
+  \endqml
+  \row
+  \o \image declarative-item_stacking4.png
+  \o Lower \c z below:
+  \qml
+  Item {
+      Rectangle {
+          color: "red"
+          width: 100; height: 100
+          Rectangle {
+              z: -1
+              color: "blue"
+              x: 50; y: 50; width: 100; height: 100
+          }
+      }
+  }
+  \endqml
+  \endtable
+ */
+
+/*!
+    \qmlproperty bool Item::visible
+
+    Whether the item is visible. By default this is true.
+
+    \note visible is not linked to actual visibility; if an item
+    moves off screen, or the opacity changes to 0, this will
+    not affect the visible property.
+*/
+
+
+/*!
+  This function is called to handle this item's changes in
+  geometry from \a oldGeometry to \a newGeometry. If the two
+  geometries are the same, it doesn't do anything.
+ */
+void QDeclarativeItem::geometryChanged(const QRectF &newGeometry,
+                              const QRectF &oldGeometry)
+{
+    Q_D(QDeclarativeItem);
+
+    if (d->_anchors)
+        d->_anchors->d_func()->updateMe();
+
+    if (transformOrigin() != QDeclarativeItem::TopLeft
+        && (newGeometry.width() != oldGeometry.width() || newGeometry.height() != oldGeometry.height())) {
+        if (d->transformData) {
+            QPointF origin = d->computeTransformOrigin();
+            if (transformOriginPoint() != origin)
+                setTransformOriginPoint(origin);
+        } else {
+            d->transformOriginDirty = true;
+        }
+    }
+
+    if (newGeometry.x() != oldGeometry.x())
+        emit xChanged();
+    if (newGeometry.width() != oldGeometry.width())
+        emit widthChanged();
+    if (newGeometry.y() != oldGeometry.y())
+        emit yChanged();
+    if (newGeometry.height() != oldGeometry.height())
+        emit heightChanged();
+
+    for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
+        const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
+        if (change.types & QDeclarativeItemPrivate::Geometry)
+            change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
+    }
+}
+
+void QDeclarativeItemPrivate::removeItemChangeListener(QDeclarativeItemChangeListener *listener, ChangeTypes types)
+{
+    ChangeListener change(listener, types);
+    changeListeners.removeOne(change);
+}
+
+/*! \internal */
+void QDeclarativeItem::keyPressEvent(QKeyEvent *event)
+{
+    Q_D(QDeclarativeItem);
+    keyPressPreHandler(event);
+    if (event->isAccepted())
+        return;
+    if (d->keyHandler)
+        d->keyHandler->keyPressed(event, true);
+    else
+        event->ignore();
+}
+
+/*! \internal */
+void QDeclarativeItem::keyReleaseEvent(QKeyEvent *event)
+{
+    Q_D(QDeclarativeItem);
+    keyReleasePreHandler(event);
+    if (event->isAccepted())
+        return;
+    if (d->keyHandler)
+        d->keyHandler->keyReleased(event, true);
+    else
+        event->ignore();
+}
+
+/*! \internal */
+void QDeclarativeItem::inputMethodEvent(QInputMethodEvent *event)
+{
+    Q_D(QDeclarativeItem);
+    inputMethodPreHandler(event);
+    if (event->isAccepted())
+        return;
+    if (d->keyHandler)
+        d->keyHandler->inputMethodEvent(event, true);
+    else
+        event->ignore();
+}
+
+/*! \internal */
+QVariant QDeclarativeItem::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+    Q_D(const QDeclarativeItem);
+    QVariant v;
+    if (d->keyHandler)
+        v = d->keyHandler->inputMethodQuery(query);
+
+    if (!v.isValid())
+        v = QGraphicsObject::inputMethodQuery(query);
+
+    return v;
+}
+
+void QDeclarativeItem::keyPressPreHandler(QKeyEvent *event)
+{
+    Q_D(QDeclarativeItem);
+    if (d->keyHandler && !d->doneEventPreHandler)
+        d->keyHandler->keyPressed(event, false);
+    else
+        event->ignore();
+    d->doneEventPreHandler = true;
+}
+
+void QDeclarativeItem::keyReleasePreHandler(QKeyEvent *event)
+{
+    Q_D(QDeclarativeItem);
+    if (d->keyHandler && !d->doneEventPreHandler)
+        d->keyHandler->keyReleased(event, false);
+    else
+        event->ignore();
+    d->doneEventPreHandler = true;
+}
+
+void QDeclarativeItem::inputMethodPreHandler(QInputMethodEvent *event)
+{
+    Q_D(QDeclarativeItem);
+    if (d->keyHandler && !d->doneEventPreHandler)
+        d->keyHandler->inputMethodEvent(event, false);
+    else
+        event->ignore();
+    d->doneEventPreHandler = true;
+}
+
+
+/*!
+    \internal
+*/
+QDeclarativeAnchorLine QDeclarativeItemPrivate::left() const
+{
+    return anchorLines()->left;
+}
+
+/*!
+    \internal
+*/
+QDeclarativeAnchorLine QDeclarativeItemPrivate::right() const
+{
+    return anchorLines()->right;
+}
+
+/*!
+    \internal
+*/
+QDeclarativeAnchorLine QDeclarativeItemPrivate::horizontalCenter() const
+{
+    return anchorLines()->hCenter;
+}
+
+/*!
+    \internal
+*/
+QDeclarativeAnchorLine QDeclarativeItemPrivate::top() const
+{
+    return anchorLines()->top;
+}
+
+/*!
+    \internal
+*/
+QDeclarativeAnchorLine QDeclarativeItemPrivate::bottom() const
+{
+    return anchorLines()->bottom;
+}
+
+/*!
+    \internal
+*/
+QDeclarativeAnchorLine QDeclarativeItemPrivate::verticalCenter() const
+{
+    return anchorLines()->vCenter;
+}
+
+
+/*!
+    \internal
+*/
+QDeclarativeAnchorLine QDeclarativeItemPrivate::baseline() const
+{
+    return anchorLines()->baseline;
+}
+
+/*!
+  \qmlproperty AnchorLine Item::top
+  \qmlproperty AnchorLine Item::bottom
+  \qmlproperty AnchorLine Item::left
+  \qmlproperty AnchorLine Item::right
+  \qmlproperty AnchorLine Item::horizontalCenter
+  \qmlproperty AnchorLine Item::verticalCenter
+  \qmlproperty AnchorLine Item::baseline
+
+  The anchor lines of the item.
+
+  For more information see \l {anchor-layout}{Anchor Layouts}.
+*/
+
+/*!
+  \qmlproperty AnchorLine Item::anchors.top
+  \qmlproperty AnchorLine Item::anchors.bottom
+  \qmlproperty AnchorLine Item::anchors.left
+  \qmlproperty AnchorLine Item::anchors.right
+  \qmlproperty AnchorLine Item::anchors.horizontalCenter
+  \qmlproperty AnchorLine Item::anchors.verticalCenter
+  \qmlproperty AnchorLine Item::anchors.baseline
+
+  \qmlproperty Item Item::anchors.fill
+  \qmlproperty Item Item::anchors.centerIn
+
+  \qmlproperty real Item::anchors.margins
+  \qmlproperty real Item::anchors.topMargin
+  \qmlproperty real Item::anchors.bottomMargin
+  \qmlproperty real Item::anchors.leftMargin
+  \qmlproperty real Item::anchors.rightMargin
+  \qmlproperty real Item::anchors.horizontalCenterOffset
+  \qmlproperty real Item::anchors.verticalCenterOffset
+  \qmlproperty real Item::anchors.baselineOffset
+
+  Anchors provide a way to position an item by specifying its
+  relationship with other items.
+
+  Margins apply to top, bottom, left, right, and fill anchors.
+  The margins property can be used to set all of the various margins at once, to the same value.
+
+  Offsets apply for horizontal center, vertical center, and baseline anchors.
+
+  \table
+  \row
+  \o \image declarative-anchors_example.png
+  \o Text anchored to Image, horizontally centered and vertically below, with a margin.
+  \qml
+  Image { id: pic; ... }
+  Text {
+      id: label
+      anchors.horizontalCenter: pic.horizontalCenter
+      anchors.top: pic.bottom
+      anchors.topMargin: 5
+      ...
+  }
+  \endqml
+  \row
+  \o \image declarative-anchors_example2.png
+  \o
+  Left of Text anchored to right of Image, with a margin. The y
+  property of both defaults to 0.
+
+  \qml
+    Image { id: pic; ... }
+    Text {
+        id: label
+        anchors.left: pic.right
+        anchors.leftMargin: 5
+        ...
+    }
+  \endqml
+  \endtable
+
+  anchors.fill provides a convenient way for one item to have the
+  same geometry as another item, and is equivalent to connecting all
+  four directional anchors.
+
+  \note You can only anchor an item to siblings or a parent.
+
+  For more information see \l {anchor-layout}{Anchor Layouts}.
+*/
+
+/*!
+  \property QDeclarativeItem::baselineOffset
+  \brief The position of the item's baseline in local coordinates.
+
+  The baseline of a Text item is the imaginary line on which the text
+  sits. Controls containing text usually set their baseline to the
+  baseline of their text.
+
+  For non-text items, a default baseline offset of 0 is used.
+*/
+qreal QDeclarativeItem::baselineOffset() const
+{
+    Q_D(const QDeclarativeItem);
+    if (!d->_baselineOffset.isValid()) {
+        return 0.0;
+    } else
+        return d->_baselineOffset;
+}
+
+void QDeclarativeItem::setBaselineOffset(qreal offset)
+{
+    Q_D(QDeclarativeItem);
+    if (offset == d->_baselineOffset)
+        return;
+
+    d->_baselineOffset = offset;
+
+    for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
+        const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
+        if (change.types & QDeclarativeItemPrivate::Geometry) {
+            QDeclarativeAnchorsPrivate *anchor = change.listener->anchorPrivate();
+            if (anchor)
+                anchor->updateVerticalAnchors();
+        }
+    }
+    emit baselineOffsetChanged(offset);
+}
+
+/*!
+  \qmlproperty real Item::rotation
+  This property holds the rotation of the item in degrees clockwise.
+
+  This specifies how many degrees to rotate the item around its transformOrigin.
+  The default rotation is 0 degrees (i.e. not rotated at all).
+
+  \table
+  \row
+  \o \image declarative-rotation.png
+  \o
+  \qml
+  Rectangle {
+      color: "blue"
+      width: 100; height: 100
+      Rectangle {
+          color: "red"
+          x: 25; y: 25; width: 50; height: 50
+          rotation: 30
+      }
+  }
+  \endqml
+  \endtable
+*/
+
+/*!
+  \qmlproperty real Item::scale
+  This property holds the scale of the item.
+
+  A scale of less than 1 means the item will be displayed smaller than
+  normal, and a scale of greater than 1 means the item will be
+  displayed larger than normal.  A negative scale means the item will
+  be mirrored.
+
+  By default, items are displayed at a scale of 1 (i.e. at their
+  normal size).
+
+  Scaling is from the item's transformOrigin.
+
+  \table
+  \row
+  \o \image declarative-scale.png
+  \o
+  \qml
+  Rectangle {
+      color: "blue"
+      width: 100; height: 100
+      Rectangle {
+          color: "green"
+          width: 25; height: 25
+      }
+      Rectangle {
+          color: "red"
+          x: 25; y: 25; width: 50; height: 50
+          scale: 1.4
+      }
+  }
+  \endqml
+  \endtable
+*/
+
+/*!
+  \qmlproperty real Item::opacity
+
+  The opacity of the item.  Opacity is specified as a number between 0
+  (fully transparent) and 1 (fully opaque).  The default is 1.
+
+  Opacity is an \e inherited attribute.  That is, the opacity is
+  also applied individually to child items.  In almost all cases this
+  is what you want, but in some cases (like the following example)
+  it may produce undesired results.
+
+  \table
+  \row
+  \o \image declarative-item_opacity1.png
+  \o
+  \qml
+    Item {
+        Rectangle {
+            color: "red"
+            width: 100; height: 100
+            Rectangle {
+                color: "blue"
+                x: 50; y: 50; width: 100; height: 100
+            }
+        }
+    }
+  \endqml
+  \row
+  \o \image declarative-item_opacity2.png
+  \o
+  \qml
+    Item {
+        Rectangle {
+            opacity: 0.5
+            color: "red"
+            width: 100; height: 100
+            Rectangle {
+                color: "blue"
+                x: 50; y: 50; width: 100; height: 100
+            }
+        }
+    }
+  \endqml
+  \endtable
+*/
+
+/*!
+  Returns a value indicating whether mouse input should
+  remain with this item exclusively.
+
+  \sa setKeepMouseGrab()
+ */
+bool QDeclarativeItem::keepMouseGrab() const
+{
+    Q_D(const QDeclarativeItem);
+    return d->_keepMouse;
+}
+
+/*!
+  The flag indicating whether the mouse should remain
+  with this item is set to \a keep.
+
+  This is useful for items that wish to grab and keep mouse
+  interaction following a predefined gesture.  For example,
+  an item that is interested in horizontal mouse movement
+  may set keepMouseGrab to true once a threshold has been
+  exceeded.  Once keepMouseGrab has been set to true, filtering
+  items will not react to mouse events.
+
+  If the item does not indicate that it wishes to retain mouse grab,
+  a filtering item may steal the grab. For example, Flickable may attempt
+  to steal a mouse grab if it detects that the user has begun to
+  move the viewport.
+
+  \sa keepMouseGrab()
+ */
+void QDeclarativeItem::setKeepMouseGrab(bool keep)
+{
+    Q_D(QDeclarativeItem);
+    d->_keepMouse = keep;
+}
+
+/*!
+    \qmlmethod object Item::mapFromItem(Item item, real x, real y)
+
+    Maps the point (\a x, \a y), which is in \a item's coordinate system, to
+    this item's coordinate system, and returns an object with \c x and \c y
+    properties matching the mapped cooordinate.
+
+    If \a item is a \c null value, this maps the point from the coordinate
+    system of the root QML view.
+*/
+QScriptValue QDeclarativeItem::mapFromItem(const QScriptValue &item, qreal x, qreal y) const
+{
+    QScriptValue sv = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this))->newObject();
+    QDeclarativeItem *itemObj = qobject_cast<QDeclarativeItem*>(item.toQObject());
+    if (!itemObj && !item.isNull()) {
+        qmlInfo(this) << "mapFromItem() given argument \"" << item.toString() << "\" which is neither null nor an Item";
+        return 0;
+    }
+
+    // If QGraphicsItem::mapFromItem() is called with 0, behaves the same as mapFromScene()
+    QPointF p = qobject_cast<QGraphicsItem*>(this)->mapFromItem(itemObj, x, y);
+    sv.setProperty(QLatin1String("x"), p.x());
+    sv.setProperty(QLatin1String("y"), p.y());
+    return sv;
+}
+
+/*!
+    \qmlmethod object Item::mapToItem(Item item, real x, real y)
+
+    Maps the point (\a x, \a y), which is in this item's coordinate system, to
+    \a item's coordinate system, and returns an object with \c x and \c y
+    properties matching the mapped cooordinate.
+
+    If \a item is a \c null value, this maps \a x and \a y to the coordinate
+    system of the root QML view.
+*/
+QScriptValue QDeclarativeItem::mapToItem(const QScriptValue &item, qreal x, qreal y) const
+{
+    QScriptValue sv = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this))->newObject();
+    QDeclarativeItem *itemObj = qobject_cast<QDeclarativeItem*>(item.toQObject());
+    if (!itemObj && !item.isNull()) {
+        qmlInfo(this) << "mapToItem() given argument \"" << item.toString() << "\" which is neither null nor an Item";
+        return 0;
+    }
+
+    // If QGraphicsItem::mapToItem() is called with 0, behaves the same as mapToScene()
+    QPointF p = qobject_cast<QGraphicsItem*>(this)->mapToItem(itemObj, x, y);
+    sv.setProperty(QLatin1String("x"), p.x());
+    sv.setProperty(QLatin1String("y"), p.y());
+    return sv;
+}
+
+/*!
+    \qmlmethod Item::forceFocus()
+
+    Force the focus on the item.
+    This method sets the focus on the item and makes sure that all the focus scopes higher in the object hierarchy are given focus.
+*/
+void QDeclarativeItem::forceFocus()
+{
+    setFocus(true);
+    QGraphicsItem *parent = parentItem();
+    while (parent) {
+        if (parent->flags() & QGraphicsItem::ItemIsFocusScope)
+            parent->setFocus(Qt::OtherFocusReason);
+        parent = parent->parentItem();
+    }
+}
+
+void QDeclarativeItemPrivate::focusChanged(bool flag)
+{
+    Q_Q(QDeclarativeItem);
+    emit q->focusChanged(flag);
+}
+
+/*! \internal */
+QDeclarativeListProperty<QObject> QDeclarativeItemPrivate::resources()
+{
+    return QDeclarativeListProperty<QObject>(q_func(), 0, QDeclarativeItemPrivate::resources_append,
+                                             QDeclarativeItemPrivate::resources_count,
+                                             QDeclarativeItemPrivate::resources_at);
+}
+
+/*!
+  \qmlproperty list<State> Item::states
+  This property holds a list of states defined by the item.
+
+  \qml
+  Item {
+    states: [
+      State { ... },
+      State { ... }
+      ...
+    ]
+  }
+  \endqml
+
+  \sa {qmlstate}{States}
+*/
+
+/*! \internal */
+QDeclarativeListProperty<QDeclarativeState> QDeclarativeItemPrivate::states()
+{
+    return _states()->statesProperty();
+}
+
+/*!
+  \qmlproperty list<Transition> Item::transitions
+  This property holds a list of transitions defined by the item.
+
+  \qml
+  Item {
+    transitions: [
+      Transition { ... },
+      Transition { ... }
+      ...
+    ]
+  }
+  \endqml
+
+  \sa {state-transitions}{Transitions}
+*/
+
+
+/*! \internal */
+QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeItemPrivate::transitions()
+{
+    return _states()->transitionsProperty();
+}
+
+/*
+  \qmlproperty list<Filter> Item::filter
+  This property holds a list of graphical filters to be applied to the item.
+
+  \l {Filter}{Filters} include things like \l {Blur}{blurring}
+  the item, or giving it a \l Reflection.  Some
+  filters may not be available on all canvases; if a filter is not
+  available on a certain canvas, it will simply not be applied for
+  that canvas (but the QML will still be considered valid).
+
+  \qml
+  Item {
+    filter: [
+      Blur { ... },
+      Relection { ... }
+      ...
+    ]
+  }
+  \endqml
+*/
+
+/*!
+  \qmlproperty bool Item::clip
+  This property holds whether clipping is enabled.
+
+  if clipping is enabled, an item will clip its own painting, as well
+  as the painting of its children, to its bounding rectangle.
+
+  Non-rectangular clipping regions are not supported for performance reasons.
+*/
+
+/*!
+  \property QDeclarativeItem::clip
+  This property holds whether clipping is enabled.
+
+  if clipping is enabled, an item will clip its own painting, as well
+  as the painting of its children, to its bounding rectangle.
+
+  Non-rectangular clipping regions are not supported for performance reasons.
+*/
+
+/*!
+  \qmlproperty string Item::state
+
+  This property holds the name of the current state of the item.
+
+  This property is often used in scripts to change between states. For
+  example:
+
+  \qml
+    function toggle() {
+        if (button.state == 'On')
+            button.state = 'Off';
+        else
+            button.state = 'On';
+    }
+  \endqml
+
+  If the item is in its base state (i.e. no explicit state has been
+  set), \c state will be a blank string. Likewise, you can return an
+  item to its base state by setting its current state to \c ''.
+
+  \sa {qmlstates}{States}
+*/
+
+/*!
+  \property QDeclarativeItem::state
+  \internal
+*/
+
+/*! \internal */
+QString QDeclarativeItemPrivate::state() const
+{
+    if (!_stateGroup)
+        return QString();
+    else
+        return _stateGroup->state();
+}
+
+/*! \internal */
+void QDeclarativeItemPrivate::setState(const QString &state)
+{
+    _states()->setState(state);
+}
+
+/*!
+  \qmlproperty list<Transform> Item::transform
+  This property holds the list of transformations to apply.
+
+  For more information see \l Transform.
+*/
+
+/*!
+  \property QDeclarativeItem::transform
+  \internal
+*/
+
+/*! \internal */
+QDeclarativeListProperty<QGraphicsTransform> QDeclarativeItem::transform()
+{
+    Q_D(QDeclarativeItem);
+    return QDeclarativeListProperty<QGraphicsTransform>(this, 0, d->transform_append, d->transform_count,
+                                               d->transform_at, d->transform_clear);
+}
+
+/*!
+  \internal
+
+  classBegin() is called when the item is constructed, but its
+  properties have not yet been set.
+
+  \sa componentComplete(), isComponentComplete()
+*/
+void QDeclarativeItem::classBegin()
+{
+    Q_D(QDeclarativeItem);
+    d->_componentComplete = false;
+    if (d->_stateGroup)
+        d->_stateGroup->classBegin();
+    if (d->_anchors)
+        d->_anchors->classBegin();
+}
+
+/*!
+  \internal
+
+  componentComplete() is called when all items in the component
+  have been constructed.  It is often desireable to delay some
+  processing until the component is complete an all bindings in the
+  component have been resolved.
+*/
+void QDeclarativeItem::componentComplete()
+{
+    Q_D(QDeclarativeItem);
+    d->_componentComplete = true;
+    if (d->_stateGroup)
+        d->_stateGroup->componentComplete();
+    if (d->_anchors) {
+        d->_anchors->componentComplete();
+        d->_anchors->d_func()->updateOnComplete();
+    }
+    if (d->keyHandler)
+        d->keyHandler->componentComplete();
+}
+
+QDeclarativeStateGroup *QDeclarativeItemPrivate::_states()
+{
+    Q_Q(QDeclarativeItem);
+    if (!_stateGroup) {
+        _stateGroup = new QDeclarativeStateGroup;
+        if (!_componentComplete)
+            _stateGroup->classBegin();
+        QObject::connect(_stateGroup, SIGNAL(stateChanged(QString)),
+                         q, SIGNAL(stateChanged(QString)));
+    }
+
+    return _stateGroup;
+}
+
+QDeclarativeItemPrivate::AnchorLines::AnchorLines(QGraphicsObject *q)
+{
+    left.item = q;
+    left.anchorLine = QDeclarativeAnchorLine::Left;
+    right.item = q;
+    right.anchorLine = QDeclarativeAnchorLine::Right;
+    hCenter.item = q;
+    hCenter.anchorLine = QDeclarativeAnchorLine::HCenter;
+    top.item = q;
+    top.anchorLine = QDeclarativeAnchorLine::Top;
+    bottom.item = q;
+    bottom.anchorLine = QDeclarativeAnchorLine::Bottom;
+    vCenter.item = q;
+    vCenter.anchorLine = QDeclarativeAnchorLine::VCenter;
+    baseline.item = q;
+    baseline.anchorLine = QDeclarativeAnchorLine::Baseline;
+}
+
+QPointF QDeclarativeItemPrivate::computeTransformOrigin() const
+{
+    Q_Q(const QDeclarativeItem);
+
+    QRectF br = q->boundingRect();
+
+    switch(origin) {
+    default:
+    case QDeclarativeItem::TopLeft:
+        return QPointF(0, 0);
+    case QDeclarativeItem::Top:
+        return QPointF(br.width() / 2., 0);
+    case QDeclarativeItem::TopRight:
+        return QPointF(br.width(), 0);
+    case QDeclarativeItem::Left:
+        return QPointF(0, br.height() / 2.);
+    case QDeclarativeItem::Center:
+        return QPointF(br.width() / 2., br.height() / 2.);
+    case QDeclarativeItem::Right:
+        return QPointF(br.width(), br.height() / 2.);
+    case QDeclarativeItem::BottomLeft:
+        return QPointF(0, br.height());
+    case QDeclarativeItem::Bottom:
+        return QPointF(br.width() / 2., br.height());
+    case QDeclarativeItem::BottomRight:
+        return QPointF(br.width(), br.height());
+    }
+}
+
+/*! \internal */
+bool QDeclarativeItem::sceneEvent(QEvent *event)
+{
+    Q_D(QDeclarativeItem);
+    if (event->type() == QEvent::KeyPress) {
+        QKeyEvent *k = static_cast<QKeyEvent *>(event);
+        if ((k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) &&
+            !(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) {
+            keyPressEvent(static_cast<QKeyEvent *>(event));
+            if (!event->isAccepted())
+                return QGraphicsItem::sceneEvent(event);
+            else
+                return true;
+        } else {
+            return QGraphicsItem::sceneEvent(event);
+        }
+    } else {
+        bool rv = QGraphicsItem::sceneEvent(event);
+
+        if (event->type() == QEvent::FocusIn ||
+            event->type() == QEvent::FocusOut) {
+            d->focusChanged(hasFocus());
+        }
+        return rv;
+    }
+}
+
+/*!
+    \reimp
+
+    Note that unlike QGraphicsItems, QDeclarativeItem::itemChange() is \e not called
+    during initial widget polishing. Items wishing to optimize start-up construction
+    should instead consider using componentComplete().
+*/
+QVariant QDeclarativeItem::itemChange(GraphicsItemChange change,
+                                       const QVariant &value)
+{
+    Q_D(QDeclarativeItem);
+    switch (change) {
+    case ItemParentHasChanged:
+        emit parentChanged(parentItem());
+        d->parentNotifier.notify();
+        break;
+    case ItemVisibleHasChanged: {
+            for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
+                const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
+                if (change.types & QDeclarativeItemPrivate::Visibility) {
+                    change.listener->itemVisibilityChanged(this);
+                }
+            }
+        }
+        break;
+    case ItemOpacityHasChanged: {
+            for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
+                const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
+                if (change.types & QDeclarativeItemPrivate::Opacity) {
+                    change.listener->itemOpacityChanged(this);
+                }
+            }
+        }
+        break;
+    case ItemChildAddedChange:
+        if (d->_contents)
+            d->_contents->childAdded(qobject_cast<QDeclarativeItem*>(
+                    value.value<QGraphicsItem*>()));
+        break;
+    case ItemChildRemovedChange:
+        if (d->_contents)
+            d->_contents->childRemoved(qobject_cast<QDeclarativeItem*>(
+                    value.value<QGraphicsItem*>()));
+        break;
+    default:
+        break;
+    }
+
+    return QGraphicsItem::itemChange(change, value);
+}
+
+/*! \internal */
+QRectF QDeclarativeItem::boundingRect() const
+{
+    Q_D(const QDeclarativeItem);
+    return QRectF(0, 0, d->mWidth, d->mHeight);
+}
+
+/*!
+    \enum QDeclarativeItem::TransformOrigin
+
+    Controls the point about which simple transforms like scale apply.
+
+    \value TopLeft The top-left corner of the item.
+    \value Top The center point of the top of the item.
+    \value TopRight The top-right corner of the item.
+    \value Left The left most point of the vertical middle.
+    \value Center The center of the item.
+    \value Right The right most point of the vertical middle.
+    \value BottomLeft The bottom-left corner of the item.
+    \value Bottom The center point of the bottom of the item.
+    \value BottomRight The bottom-right corner of the item.
+*/
+
+/*!
+    Returns the current transform origin.
+*/
+QDeclarativeItem::TransformOrigin QDeclarativeItem::transformOrigin() const
+{
+    Q_D(const QDeclarativeItem);
+    return d->origin;
+}
+
+/*!
+    Set the transform \a origin.
+*/
+void QDeclarativeItem::setTransformOrigin(TransformOrigin origin)
+{
+    Q_D(QDeclarativeItem);
+    if (origin != d->origin) {
+        d->origin = origin;
+        if (d->transformData)
+            QGraphicsItem::setTransformOriginPoint(d->computeTransformOrigin());
+        else
+            d->transformOriginDirty = true;
+        emit transformOriginChanged(d->origin);
+    }
+}
+
+void QDeclarativeItemPrivate::transformChanged()
+{
+    Q_Q(QDeclarativeItem);
+    if (transformOriginDirty) {
+        q->QGraphicsItem::setTransformOriginPoint(computeTransformOrigin());
+        transformOriginDirty = false;
+    }
+}
+
+/*!
+    \property QDeclarativeItem::smooth
+    \brief whether the item is smoothly transformed.
+
+    This property is provided purely for the purpose of optimization. Turning
+    smooth transforms off is faster, but looks worse; turning smooth
+    transformations on is slower, but looks better.
+
+    By default smooth transformations are off.
+*/
+
+/*!
+    Returns true if the item should be drawn with antialiasing and
+    smooth pixmap filtering, false otherwise.
+
+    The default is false.
+
+    \sa setSmooth()
+*/
+bool QDeclarativeItem::smooth() const
+{
+    Q_D(const QDeclarativeItem);
+    return d->smooth;
+}
+
+/*!
+    Sets whether the item should be drawn with antialiasing and
+    smooth pixmap filtering to \a smooth.
+
+    \sa smooth()
+*/
+void QDeclarativeItem::setSmooth(bool smooth)
+{
+    Q_D(QDeclarativeItem);
+    if (d->smooth == smooth)
+        return;
+    d->smooth = smooth;
+    emit smoothChanged(smooth);
+    update();
+}
+
+/*!
+    \internal
+    Return the width of the item
+*/
+qreal QDeclarativeItem::width() const
+{
+    Q_D(const QDeclarativeItem);
+    return d->width();
+}
+
+/*!
+    \internal
+    Set the width of the item
+*/
+void QDeclarativeItem::setWidth(qreal w)
+{
+    Q_D(QDeclarativeItem);
+    d->setWidth(w);
+}
+
+/*!
+    \internal
+    Reset the width of the item
+*/
+void QDeclarativeItem::resetWidth()
+{
+    Q_D(QDeclarativeItem);
+    d->resetWidth();
+}
+
+/*!
+    \internal
+    Return the width of the item
+*/
+qreal QDeclarativeItemPrivate::width() const
+{
+    return mWidth;
+}
+
+/*!
+    \internal
+*/
+void QDeclarativeItemPrivate::setWidth(qreal w)
+{
+    Q_Q(QDeclarativeItem);
+    if (qIsNaN(w))
+        return;
+
+    widthValid = true;
+    if (mWidth == w)
+        return;
+
+    qreal oldWidth = mWidth;
+
+    q->prepareGeometryChange();
+    mWidth = w;
+
+    q->geometryChanged(QRectF(q->x(), q->y(), width(), height()),
+                    QRectF(q->x(), q->y(), oldWidth, height()));
+}
+
+/*!
+    \internal
+*/
+void QDeclarativeItemPrivate::resetWidth()
+{
+    Q_Q(QDeclarativeItem);
+    widthValid = false;
+    q->setImplicitWidth(q->implicitWidth());
+}
+
+/*!
+    Returns the width of the item that is implied by other properties that determine the content.
+*/
+qreal QDeclarativeItem::implicitWidth() const
+{
+    Q_D(const QDeclarativeItem);
+    return d->implicitWidth;
+}
+
+/*!
+    Sets the implied width of the item to \a w.
+    This is the width implied by other properties that determine the content.
+*/
+void QDeclarativeItem::setImplicitWidth(qreal w)
+{
+    Q_D(QDeclarativeItem);
+    d->implicitWidth = w;
+    if (d->mWidth == w || widthValid())
+        return;
+
+    qreal oldWidth = d->mWidth;
+
+    prepareGeometryChange();
+    d->mWidth = w;
+
+    geometryChanged(QRectF(x(), y(), width(), height()),
+                    QRectF(x(), y(), oldWidth, height()));
+}
+
+/*!
+    Returns whether the width property has been set explicitly.
+*/
+bool QDeclarativeItem::widthValid() const
+{
+    Q_D(const QDeclarativeItem);
+    return d->widthValid;
+}
+
+/*!
+    \internal
+    Return the height of the item
+*/
+qreal QDeclarativeItem::height() const
+{
+    Q_D(const QDeclarativeItem);
+    return d->height();
+}
+
+/*!
+    \internal
+    Set the height of the item
+*/
+void QDeclarativeItem::setHeight(qreal h)
+{
+    Q_D(QDeclarativeItem);
+    d->setHeight(h);
+}
+
+/*!
+    \internal
+    Reset the height of the item
+*/
+void QDeclarativeItem::resetHeight()
+{
+    Q_D(QDeclarativeItem);
+    d->resetHeight();
+}
+
+/*!
+    \internal
+*/
+qreal QDeclarativeItemPrivate::height() const
+{
+    return mHeight;
+}
+
+/*!
+    \internal
+*/
+void QDeclarativeItemPrivate::setHeight(qreal h)
+{
+    Q_Q(QDeclarativeItem);
+    if (qIsNaN(h))
+        return;
+
+    heightValid = true;
+    if (mHeight == h)
+        return;
+
+    qreal oldHeight = mHeight;
+
+    q->prepareGeometryChange();
+    mHeight = h;
+
+    q->geometryChanged(QRectF(q->x(), q->y(), width(), height()),
+                    QRectF(q->x(), q->y(), width(), oldHeight));
+}
+
+/*!
+    \internal
+*/
+void QDeclarativeItemPrivate::resetHeight()
+{
+    Q_Q(QDeclarativeItem);
+    heightValid = false;
+    q->setImplicitHeight(q->implicitHeight());
+}
+
+/*!
+    Returns the height of the item that is implied by other properties that determine the content.
+*/
+qreal QDeclarativeItem::implicitHeight() const
+{
+    Q_D(const QDeclarativeItem);
+    return d->implicitHeight;
+}
+
+/*!
+    Sets the implied height of the item to \a h.
+    This is the height implied by other properties that determine the content.
+*/
+void QDeclarativeItem::setImplicitHeight(qreal h)
+{
+    Q_D(QDeclarativeItem);
+    d->implicitHeight = h;
+    if (d->mHeight == h || heightValid())
+        return;
+
+    qreal oldHeight = d->mHeight;
+
+    prepareGeometryChange();
+    d->mHeight = h;
+
+    geometryChanged(QRectF(x(), y(), width(), height()),
+                    QRectF(x(), y(), width(), oldHeight));
+}
+
+/*!
+    Returns whether the height property has been set explicitly.
+*/
+bool QDeclarativeItem::heightValid() const
+{
+    Q_D(const QDeclarativeItem);
+    return d->heightValid;
+}
+
+/*! \internal */
+void QDeclarativeItem::setSize(const QSizeF &size)
+{
+    Q_D(QDeclarativeItem);
+    d->heightValid = true;
+    d->widthValid = true;
+
+    if (d->height() == size.height() && d->width() == size.width())
+        return;
+
+    qreal oldHeight = d->height();
+    qreal oldWidth = d->width();
+
+    prepareGeometryChange();
+    d->setHeight(size.height());
+    d->setWidth(size.width());
+
+    geometryChanged(QRectF(x(), y(), width(), height()),
+                    QRectF(x(), y(), oldWidth, oldHeight));
+}
+
+/*!
+  \qmlproperty bool Item::wantsFocus
+
+  This property indicates whether the item has has an active focus request.
+
+  \sa {qmlfocus}{Keyboard Focus}
+*/
+
+/*! \internal */
+bool QDeclarativeItem::wantsFocus() const
+{
+    return focusItem() != 0;
+}
+
+/*!
+  \qmlproperty bool Item::focus
+  This property indicates whether the item has keyboard input focus. Set this
+  property to true to request focus.
+
+  \sa {qmlfocus}{Keyboard Focus}
+*/
+
+/*! \internal */
+bool QDeclarativeItem::hasFocus() const
+{
+    return QGraphicsItem::hasFocus();
+}
+
+/*! \internal */
+void QDeclarativeItem::setFocus(bool focus)
+{
+    if (focus)
+        QGraphicsItem::setFocus(Qt::OtherFocusReason);
+    else
+        QGraphicsItem::clearFocus();
+}
+
+/*!
+    \internal
+*/
+void QDeclarativeItem::paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *)
+{
+}
+
+/*!
+    \internal
+*/
+bool QDeclarativeItem::event(QEvent *ev)
+{
+    Q_D(QDeclarativeItem);
+    switch (ev->type()) {
+    case QEvent::KeyPress:
+    case QEvent::KeyRelease:
+    case QEvent::InputMethod:
+        d->doneEventPreHandler = false;
+        break;
+    default:
+        break;
+    }
+
+    return QGraphicsObject::event(ev);
+}
+
+QDebug operator<<(QDebug debug, QDeclarativeItem *item)
+{
+    if (!item) {
+        debug << "QDeclarativeItem(0)";
+        return debug;
+    }
+
+    debug << item->metaObject()->className() << "(this =" << ((void*)item)
+          << ", parent =" << ((void*)item->parentItem())
+          << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
+          << ", z =" << item->zValue() << ')';
+    return debug;
+}
+
+int QDeclarativeItemPrivate::consistentTime = -1;
+void QDeclarativeItemPrivate::setConsistentTime(int t)
+{
+    consistentTime = t;
+}
+
+QTime QDeclarativeItemPrivate::currentTime()
+{
+    if (consistentTime == -1)
+        return QTime::currentTime();
+    else
+        return QTime(0, 0).addMSecs(consistentTime);
+}
+
+void QDeclarativeItemPrivate::start(QTime &t)
+{
+    t = currentTime();
+}
+
+int QDeclarativeItemPrivate::elapsed(QTime &t)
+{
+    int n = t.msecsTo(currentTime());
+    if (n < 0)                                // passed midnight
+        n += 86400 * 1000;
+    return n;
+}
+
+int QDeclarativeItemPrivate::restart(QTime &t)
+{
+    QTime time = currentTime();
+    int n = t.msecsTo(time);
+    if (n < 0)                                // passed midnight
+        n += 86400*1000;
+    t = time;
+    return n;
+}
+
+QT_END_NAMESPACE
+
+#include <moc_qdeclarativeitem.cpp>