<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (<EMAIL>)
**
** 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 either Technology Preview License Agreement or the
** Beta Release License Agreement.
**
** 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.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at <EMAIL>.
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QDebug>
#include <QPen>
#include <QFile>
#include <QEvent>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QGraphicsSceneMouseEvent>
#include <QtScript/qscriptengine.h>
#include <private/qfxperf_p.h>
#include <QtGui/qgraphicstransform.h>

#include <QtDeclarative/qmlengine.h>
#include <private/qmlengine_p.h>
#include "qmlstate.h"
#include "qlistmodelinterface.h"
#include "qfxanchors_p.h"

#include "qfxscalegrid.h"
#include "qfxview.h"
#include "qmlstategroup.h"

#include "qfxitem_p.h"
#include "qfxitem.h"
#include "qfxevents_p.h"
#include <qmlcomponent.h>

QT_BEGIN_NAMESPACE

#ifndef FLT_MAX
#define FLT_MAX 1E+37
#endif

QML_DEFINE_NOCREATE_TYPE(QFxContents)
QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Item,QFxItem)

QML_DEFINE_NOCREATE_TYPE(QGraphicsTransform);
QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Scale,QGraphicsScale)
QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Rotation,QGraphicsRotation)
QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Rotation3D,QGraphicsRotation3D)

/*!
    \group group_animation
    \title Animation
*/

/*!
    \group group_coreitems
    \title Basic Items
*/

/*!
    \group group_effects
    \title Effects
*/

/*!
    \group group_layouts
    \title Layouts
*/

/*!
    \group group_states
    \title States and Transitions
*/

/*!
    \group group_utility
    \title Utility
*/

/*!
    \group group_views
    \title Views
*/

/*!
    \group group_widgets
    \title Widgets
*/

/*!
    \internal
    \class QFxContents
    \ingroup group_utility
    \brief The QFxContents class gives access to the height and width of an item's contents.

*/

QFxContents::QFxContents() : m_height(0), m_width(0)
{
}

/*!
    \qmlproperty qreal Item::contents.width
    \qmlproperty qreal Item::contents.height

    The contents properties allow an item access to the size of its
    children. This property is useful if you have an item that needs to be
    sized to fit its children.    
*/

/*!
    \property QFxContents::height
    \brief The height of the contents.
*/
qreal QFxContents::height() const
{
    return m_height;
}

/*!
    \property QFxContents::width
    \brief The width of the contents.
*/
qreal QFxContents::width() const
{
    return m_width;
}

//TODO: optimization: only check sender(), if there is one
void QFxContents::calcHeight()
{
    qreal oldheight = m_height;

    qreal top = FLT_MAX;
    qreal bottom = 0;

    QList<QGraphicsItem *> children = m_item->childItems();
    for (int i = 0; i < children.count(); ++i) {
        QFxItem *child = qobject_cast<QFxItem *>(children.at(i));
        qreal y = child->y();
        if (y + child->height() > bottom)
            bottom = y + child->height();
        if (y < top)
            top = y;
    }
    m_height = qMax(bottom - top, qreal(0.0));

    if (m_height != oldheight)
        emit heightChanged();
}

//TODO: optimization: only check sender(), if there is one
void QFxContents::calcWidth()
{
    qreal oldwidth = m_width;

    qreal left = FLT_MAX;
    qreal right = 0;

    QList<QGraphicsItem *> children = m_item->childItems();
    for (int i = 0; i < children.count(); ++i) {
        QFxItem *child = qobject_cast<QFxItem *>(children.at(i));
        qreal x = child->x();
        if (x + child->width() > right)
            right = x + child->width();
        if (x < left)
            left = x;
    }
    m_width = qMax(right - left, qreal(0.0));

    if (m_width != oldwidth)
        emit widthChanged();
}

void QFxContents::setItem(QFxItem *item)
{
    m_item = item;

    QList<QGraphicsItem *> children = m_item->childItems();
    for (int i = 0; i < children.count(); ++i) {
        QFxItem *child = qobject_cast<QFxItem *>(children.at(i));
        connect(child, SIGNAL(heightChanged()), this, SLOT(calcHeight()));
        connect(child, SIGNAL(yChanged()), this, SLOT(calcHeight()));
        connect(child, SIGNAL(widthChanged()), this, SLOT(calcWidth()));
        connect(child, SIGNAL(xChanged()), this, SLOT(calcWidth()));
    }

    calcHeight();
    calcWidth();
}

/*!
    \qmlclass Item QFxItem
    \brief The Item is the most basic of all visual items in QML.
 */

/*!
    \class QFxItem Item
    \brief The QFxItem class is a generic QFxView item. It is the base class for all other view items.

    \qmltext
    All visual items in Qt Declarative inherit from QFxItem.  Although QFxItem
    has no visual appearance, it defines all the properties that are
    common across visual items - like the x and y position, and the
    width and height.

    QFxItem is also useful for grouping items together.

    \qml
    Item {
        Image {
            file: "tile.png"
        }
        Image {
            x: 80
            width: 100
            height: 100
            file: "tile.png"
        }
        Image {
            x: 190
            width: 100
            height: 100
            tile: true
            file: "tile.png"
        }
    }
    \endqml
    \endqmltext
    
    \ingroup group_coreitems
*/

/*!
    \fn void QFxItem::activeFocusChanged()

    This signal is emitted when this item gains active focus.
*/

/*!
    \fn void QFxItem::baselineOffsetChanged()

    This signal is emitted when the baseline offset of the item
    is changed.
*/

/*!
    \fn void QFxItem::xChanged()

    This signal is emitted when the x coordinate of the item changes.
*/

/*!
    \fn void QFxItem::yChanged()

    This signal is emitted when the y coordinate of the item changes.
*/

/*!
    \fn void QFxItem::widthChanged()

    This signal is emitted when the width of the item changes.
*/

/*!
    \fn void QFxItem::heightChanged()

    This signal is emitted when the height of the item changes.
*/

/*!
    \fn void QFxItem::hcenterChanged()

    This signal is emitted when the horizontal center coordinate of the item changes.
*/

/*!
    \fn void QFxItem::vcenterChanged()

    This signal is emitted when the vertical center coordinate of the item changes.
*/

/*!
    \fn void QFxItem::stateChanged(const QString &state)

    This signal is emitted when the \a state of the item changes.

    \sa states-transitions
*/

/*!
    \qmlsignal Item::onKeyPress(event)

    This handler is called when a key is pressed.

    The key event is available via the KeyEvent \a event.

    \qml
    Item {
        onKeyPress: { if (event.key == Qt.Key_Enter) state='Enter' }
    }
    \endqml
*/

/*!
    \qmlsignal Item::onKeyRelease(event)

    This handler is called when a key is released.

    The key event is available in via the KeyEvent \a event.

    \qml
    Item {
        onKeyRelease: { if (event.key == Qt.Key_Enter) state='Enter' }
    }
    \endqml
*/

/*!
    \fn void QFxItem::parentChanged()

    This signal is emitted when the parent of the item changes.

    \sa setParentItem()
*/

/*!
    \fn void QFxItem::focusChanged()

    This signal is emitted when the item's focus state changes.

    \sa QFxItem::setFocus()
*/

/*!
    \fn QFxItem::QFxItem(QFxItem *parent)

    Constructs a QFxItem with the given \a parent.
*/
QFxItem::QFxItem(QFxItem* parent)
  : QGraphicsObject(*(new QFxItemPrivate), parent, 0)
{
    Q_D(QFxItem);
    d->init(parent);
}

/*! \internal
*/
QFxItem::QFxItem(QFxItemPrivate &dd, QFxItem *parent)
  : QGraphicsObject(dd, parent, 0)
{
    Q_D(QFxItem);
    d->init(parent);
}

/*! \internal
*/
void QFxItem::doUpdate()
{
    update();
}

/*!
    Destroys the QFxItem.
*/
QFxItem::~QFxItem()
{
    Q_D(QFxItem);
    for (int ii = 0; ii < d->dependantAnchors.count(); ++ii) {
        QFxAnchors *anchor = d->dependantAnchors.at(ii);
        anchor->d_func()->clearItem(this);
    }
    for (int ii = 0; ii < d->dependantAnchors.count(); ++ii) {
        QFxAnchors *anchor = d->dependantAnchors.at(ii);
        if (anchor->d_func()->item && anchor->d_func()->item->parentItem() != this) //child will be deleted anyway
            anchor->d_func()->updateOnComplete();
    }
    delete d->_anchorLines; d->_anchorLines = 0;
}

/*!
    \qmlproperty enum 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 scales an image about its center.
    \qml
    Image {
        source: "myimage.png"
        transformOrigin: "Center"
        scale: 4
    }
    \endqml

    The default transform origin is \c TopLeft.
*/

/*!
    \qmlproperty Item Item::parent
    This property holds the parent of the item.
*/

/*!
    \property QFxItem::parent
    This property holds the parent of the item.
*/
void QFxItem::setParentItem(QFxItem *parent)
{
    QFxItem *oldParent = parentItem();
    if (parent == oldParent || !parent) return;

    QObject::setParent(parent);
    QGraphicsObject::setParentItem(parent);

    parentChanged(parent, oldParent);
}

/*!
    Returns the QFxItem parent of this item.
*/
QFxItem *QFxItem::parentItem() const
{
    return qobject_cast<QFxItem *>(QGraphicsObject::parentItem());
}

/*!
    \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 {},
            Rect {}
        ]
        resources: [
            Component {
                id: myComponent
                Text {}
            }
        ]
    }
    \endqml
*/

/*!
    \property QFxItem::children

    This property contains the list of visual children of this item. 
*/

/*!
    \property QFxItem::resources

    This property contains non-visual resources that you want to 
    reference by name.
*/

/*!
    Returns true if all of the attributes set via QML have been set;
    otherwise returns false.

    \sa classComplete()
*/
bool QFxItem::isClassComplete() const
{
    Q_D(const QFxItem);
    return d->_classComplete;
}

/*!
    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 QFxItem::isComponentComplete() const
{
    Q_D(const QFxItem);
    return d->_componentComplete;
}

/*!
    \property QFxItem::anchors
    \brief The anchors (alignments) used by the item.
*/
QFxAnchors *QFxItem::anchors()
{
    Q_D(QFxItem);
    return d->anchors();
}

void QFxItemPrivate::data_removeAt(int)
{
    // ###
}

int QFxItemPrivate::data_count() const
{
    // ###
    return 0;
}

void QFxItemPrivate::data_append(QObject *o)
{
    Q_Q(QFxItem);
    QFxItem *i = qobject_cast<QFxItem *>(o);
    if (i)
        q->children()->append(i);
    else
        resources_append(o);
}

void QFxItemPrivate::data_insert(int, QObject *)
{
    // ###
}

QObject *QFxItemPrivate::data_at(int) const
{
    // ###
    return 0;
}

void QFxItemPrivate::data_clear()
{
    // ###
}

void QFxItemPrivate::resources_removeAt(int)
{
    // ###
}

int QFxItemPrivate::resources_count() const
{
    // ###
    return 0;
}

void QFxItemPrivate::resources_append(QObject *o)
{
    Q_Q(QFxItem);
    o->setParent(q);
}

void QFxItemPrivate::resources_insert(int, QObject *)
{
    // ###
}

QObject *QFxItemPrivate::resources_at(int) const
{
    // ###
    return 0;
}

void QFxItemPrivate::resources_clear()
{
    // ###
}

void QFxItemPrivate::children_removeAt(int)
{
    // ###
}

int QFxItemPrivate::children_count() const
{
    // ###
    return 0;
}

void QFxItemPrivate::children_append(QFxItem *i)
{
    Q_Q(QFxItem);
    i->setParentItem(q);
}

void QFxItemPrivate::children_insert(int, QFxItem *)
{
    // ###
}

QFxItem *QFxItemPrivate::children_at(int) const
{
    // ###
    return 0;
}

void QFxItemPrivate::children_clear()
{
    // ###
}


void QFxItemPrivate::transform_removeAt(int i)
{
    if (!transformData)
        return;
    transformData->graphicsTransforms.removeAt(i);
    dirtySceneTransform = 1;
}

int QFxItemPrivate::transform_count() const
{
    return transformData ? transformData->graphicsTransforms.size() : 0;
}

void QFxItemPrivate::transform_append(QGraphicsTransform *item)
{
    appendGraphicsTransform(item);
}

void QFxItemPrivate::transform_insert(int, QGraphicsTransform *)
{
    // ###
}

QGraphicsTransform *QFxItemPrivate::transform_at(int idx) const
{
    if (!transformData)
        return 0;
    return transformData->graphicsTransforms.at(idx);
}

void QFxItemPrivate::transform_clear()
{
    if (!transformData)
        return;
    Q_Q(QFxItem);
    q->setTransformations(QList<QGraphicsTransform *>());
}

/*!
    \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 {}
        Rect {}
        Script {}
    }
    \endqml

    instead of:
    \qml
    Item {
        children: [
            Text {},
            Rect {}
        ]
        resources: [
            Script {}
        ]
    }
    \endqml

    data is a behind-the-scenes property: you should never need to explicitly 
    specify it.
 */

/*!
    \property QFxItem::data

    The data property is allows you to freely mix the visual children
    and the non-visual 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.

    data is a behind-the-scenes property: you should never need to
    explicitly specify it.
 */
QmlList<QObject *> *QFxItem::data()
{
    Q_D(QFxItem);
    return &d->data;
}

/*!
    \property QFxItem::contents
    \brief An object that knows about the size of an item's children.

    contents provides an easy way to access the (collective) width and
    height of the item's children.
*/
QFxContents *QFxItem::contents()
{
    Q_D(QFxItem);
    if (!d->_contents) {
        d->_contents = new QFxContents;
        d->_contents->setParent(this);
        d->_contents->setItem(this);
    }
    return d->_contents;
}

bool QFxItem::clip() const
{
    return flags() & ItemClipsChildrenToShape;
}

void QFxItem::setClip(bool c)
{
    setFlag(ItemClipsChildrenToShape, c);
}

/*!
  \internal
  \property QFxItem::qmlItem
*/

/*! \fn QFxItem *QFxItem::qmlItem() const
  \internal
 */
QFxItem *QFxItem::qmlItem() const
{
    Q_D(const QFxItem);
    return d->qmlItem;
}

/*!
    \qmlproperty url Item::qml
    This property holds the dynamic URL of the QML for the item.

    This property is used for dynamically loading QML into the
    item. Querying for the QML only has meaning if the QML has been
    dynamically set; otherwise an empty URL is returned.
*/

/*! \fn void QFxItem::qmlChanged()
  This signal is emitted whenever the item's dynamic QML
  string changes.

  \sa setQml()
 */

/*!
    \property QFxItem::qml
    This property holds the dynamic URL of the QML for the item.

    This property is used for dynamically loading QML into the
    item. Querying for the QML only has meaning if the QML has been
    dynamically set; otherwise an empty URL is returned.
*/
QUrl QFxItem::qml() const
{
    Q_D(const QFxItem);
    return d->_qml;
}

void QFxItem::setQml(const QUrl &qml)
{
    Q_D(QFxItem);
    if (d->_qml == qml)
        return;

    if (!d->_qml.isEmpty()) {
        QmlChildren::Iterator iter = d->_qmlChildren.find(d->_qml.toString());
        if (iter != d->_qmlChildren.end())
            (*iter)->setOpacity(0.);
    }

    d->_qml = qml;
    d->qmlItem = 0;

    if (d->_qml.isEmpty()) {
        emit qmlChanged();
        return;
    }

    QmlChildren::Iterator iter = d->_qmlChildren.find(d->_qml.toString());
    if (iter != d->_qmlChildren.end()) {
        (*iter)->setOpacity(1.);
        d->qmlItem = (*iter);
        emit qmlChanged();
    } else {
        d->_qmlcomp = 
            new QmlComponent(qmlEngine(this), d->_qml, this);
        if (!d->_qmlcomp->isLoading())
            qmlLoaded();
        else
            QObject::connect(d->_qmlcomp, SIGNAL(statusChanged(QmlComponent::Status)),
                             this, SLOT(qmlLoaded()));
    }
}

/*! \fn void QFxItem::newChildCreated(const QString &url, QScriptValue v)
  This signal is emitted with the \a url and the script value \a v,
  when a new child is created.
 */

/*!
  \internal
 */
void QFxItem::qmlLoaded()
{
    Q_D(QFxItem);

    { // newChild...
        // ###
        for (int i=0; i<d->_qmlnewloading.length(); ++i) {
            QmlComponent *c = d->_qmlnewcomp.at(i);
            if (c->isLoading())
                continue;

            QmlContext *ctxt = new QmlContext(qmlContext(this));
            QObject* o = c ? c->create(ctxt):0;
            QFxItem* ret = qobject_cast<QFxItem*>(o);
            if (ret) {
                ret->setItemParent(this);
                QScriptValue v = QmlEnginePrivate::getScriptEngine(qmlEngine(this))->newQObject(ret);
                emit newChildCreated(d->_qmlnewloading.at(i).toString(),v);
            }

            delete c;
            d->_qmlnewloading.removeAt(i);
            d->_qmlnewcomp.removeAt(i);
            --i;
        }
    }

    // setQml...
    if (d->_qmlcomp) {<commit_msg>fix merge error.<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (<EMAIL>)
**
** 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 either Technology Preview License Agreement or the
** Beta Release License Agreement.
**
** 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.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at <EMAIL>.
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QDebug>
#include <QPen>
#include <QFile>
#include <QEvent>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QGraphicsSceneMouseEvent>
#include <QtScript/qscriptengine.h>
#include <private/qfxperf_p.h>
#include <QtGui/qgraphicstransform.h>

#include <QtDeclarative/qmlengine.h>
#include <private/qmlengine_p.h>
#include "qmlstate.h"
#include "qlistmodelinterface.h"
#include "qfxanchors_p.h"

#include "qfxscalegrid.h"
#include "qfxview.h"
#include "qmlstategroup.h"

#include "qfxitem_p.h"
#include "qfxitem.h"
#include "qfxevents_p.h"
#include <qmlcomponent.h>

QT_BEGIN_NAMESPACE

#ifndef FLT_MAX
#define FLT_MAX 1E+37
#endif

QML_DEFINE_NOCREATE_TYPE(QFxContents)
QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Item,QFxItem)

QML_DEFINE_NOCREATE_TYPE(QGraphicsTransform);
QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Scale,QGraphicsScale)
QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Rotation,QGraphicsRotation)
QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Rotation3D,QGraphicsRotation3D)

/*!
    \group group_animation
    \title Animation
*/

/*!
    \group group_coreitems
    \title Basic Items
*/

/*!
    \group group_effects
    \title Effects
*/

/*!
    \group group_layouts
    \title Layouts
*/

/*!
    \group group_states
    \title States and Transitions
*/

/*!
    \group group_utility
    \title Utility
*/

/*!
    \group group_views
    \title Views
*/

/*!
    \group group_widgets
    \title Widgets
*/

/*!
    \internal
    \class QFxContents
    \ingroup group_utility
    \brief The QFxContents class gives access to the height and width of an item's contents.

*/

QFxContents::QFxContents() : m_height(0), m_width(0)
{
}

/*!
    \qmlproperty qreal Item::contents.width
    \qmlproperty qreal Item::contents.height

    The contents properties allow an item access to the size of its
    children. This property is useful if you have an item that needs to be
    sized to fit its children.    
*/

/*!
    \property QFxContents::height
    \brief The height of the contents.
*/
qreal QFxContents::height() const
{
    return m_height;
}

/*!
    \property QFxContents::width
    \brief The width of the contents.
*/
qreal QFxContents::width() const
{
    return m_width;
}

//TODO: optimization: only check sender(), if there is one
void QFxContents::calcHeight()
{
    qreal oldheight = m_height;

    qreal top = FLT_MAX;
    qreal bottom = 0;

    QList<QGraphicsItem *> children = m_item->childItems();
    for (int i = 0; i < children.count(); ++i) {
        QFxItem *child = qobject_cast<QFxItem *>(children.at(i));
        qreal y = child->y();
        if (y + child->height() > bottom)
            bottom = y + child->height();
        if (y < top)
            top = y;
    }
    m_height = qMax(bottom - top, qreal(0.0));

    if (m_height != oldheight)
        emit heightChanged();
}

//TODO: optimization: only check sender(), if there is one
void QFxContents::calcWidth()
{
    qreal oldwidth = m_width;

    qreal left = FLT_MAX;
    qreal right = 0;

    QList<QGraphicsItem *> children = m_item->childItems();
    for (int i = 0; i < children.count(); ++i) {
        QFxItem *child = qobject_cast<QFxItem *>(children.at(i));
        qreal x = child->x();
        if (x + child->width() > right)
            right = x + child->width();
        if (x < left)
            left = x;
    }
    m_width = qMax(right - left, qreal(0.0));

    if (m_width != oldwidth)
        emit widthChanged();
}

void QFxContents::setItem(QFxItem *item)
{
    m_item = item;

    QList<QGraphicsItem *> children = m_item->childItems();
    for (int i = 0; i < children.count(); ++i) {
        QFxItem *child = qobject_cast<QFxItem *>(children.at(i));
        connect(child, SIGNAL(heightChanged()), this, SLOT(calcHeight()));
        connect(child, SIGNAL(yChanged()), this, SLOT(calcHeight()));
        connect(child, SIGNAL(widthChanged()), this, SLOT(calcWidth()));
        connect(child, SIGNAL(xChanged()), this, SLOT(calcWidth()));
    }

    calcHeight();
    calcWidth();
}

/*!
    \qmlclass Item QFxItem
    \brief The Item is the most basic of all visual items in QML.
 */

/*!
    \class QFxItem Item
    \brief The QFxItem class is a generic QFxView item. It is the base class for all other view items.

    \qmltext
    All visual items in Qt Declarative inherit from QFxItem.  Although QFxItem
    has no visual appearance, it defines all the properties that are
    common across visual items - like the x and y position, and the
    width and height.

    QFxItem is also useful for grouping items together.

    \qml
    Item {
        Image {
            file: "tile.png"
        }
        Image {
            x: 80
            width: 100
            height: 100
            file: "tile.png"
        }
        Image {
            x: 190
            width: 100
            height: 100
            tile: true
            file: "tile.png"
        }
    }
    \endqml
    \endqmltext
    
    \ingroup group_coreitems
*/

/*!
    \fn void QFxItem::activeFocusChanged()

    This signal is emitted when this item gains active focus.
*/

/*!
    \fn void QFxItem::baselineOffsetChanged()

    This signal is emitted when the baseline offset of the item
    is changed.
*/

/*!
    \fn void QFxItem::xChanged()

    This signal is emitted when the x coordinate of the item changes.
*/

/*!
    \fn void QFxItem::yChanged()

    This signal is emitted when the y coordinate of the item changes.
*/

/*!
    \fn void QFxItem::widthChanged()

    This signal is emitted when the width of the item changes.
*/

/*!
    \fn void QFxItem::heightChanged()

    This signal is emitted when the height of the item changes.
*/

/*!
    \fn void QFxItem::hcenterChanged()

    This signal is emitted when the horizontal center coordinate of the item changes.
*/

/*!
    \fn void QFxItem::vcenterChanged()

    This signal is emitted when the vertical center coordinate of the item changes.
*/

/*!
    \fn void QFxItem::stateChanged(const QString &state)

    This signal is emitted when the \a state of the item changes.

    \sa states-transitions
*/

/*!
    \qmlsignal Item::onKeyPress(event)

    This handler is called when a key is pressed.

    The key event is available via the KeyEvent \a event.

    \qml
    Item {
        onKeyPress: { if (event.key == Qt.Key_Enter) state='Enter' }
    }
    \endqml
*/

/*!
    \qmlsignal Item::onKeyRelease(event)

    This handler is called when a key is released.

    The key event is available in via the KeyEvent \a event.

    \qml
    Item {
        onKeyRelease: { if (event.key == Qt.Key_Enter) state='Enter' }
    }
    \endqml
*/

/*!
    \fn void QFxItem::parentChanged()

    This signal is emitted when the parent of the item changes.

    \sa setParentItem()
*/

/*!
    \fn void QFxItem::focusChanged()

    This signal is emitted when the item's focus state changes.

    \sa QFxItem::setFocus()
*/

/*!
    \fn QFxItem::QFxItem(QFxItem *parent)

    Constructs a QFxItem with the given \a parent.
*/
QFxItem::QFxItem(QFxItem* parent)
  : QGraphicsObject(*(new QFxItemPrivate), parent, 0)
{
    Q_D(QFxItem);
    d->init(parent);
}

/*! \internal
*/
QFxItem::QFxItem(QFxItemPrivate &dd, QFxItem *parent)
  : QGraphicsObject(dd, parent, 0)
{
    Q_D(QFxItem);
    d->init(parent);
}

/*! \internal
*/
void QFxItem::doUpdate()
{
    update();
}

/*!
    Destroys the QFxItem.
*/
QFxItem::~QFxItem()
{
    Q_D(QFxItem);
    for (int ii = 0; ii < d->dependantAnchors.count(); ++ii) {
        QFxAnchors *anchor = d->dependantAnchors.at(ii);
        anchor->d_func()->clearItem(this);
    }
    for (int ii = 0; ii < d->dependantAnchors.count(); ++ii) {
        QFxAnchors *anchor = d->dependantAnchors.at(ii);
        if (anchor->d_func()->item && anchor->d_func()->item->parentItem() != this) //child will be deleted anyway
            anchor->d_func()->updateOnComplete();
    }
    delete d->_anchorLines; d->_anchorLines = 0;
}

/*!
    \qmlproperty enum 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 scales an image about its center.
    \qml
    Image {
        source: "myimage.png"
        transformOrigin: "Center"
        scale: 4
    }
    \endqml

    The default transform origin is \c TopLeft.
*/

/*!
    \qmlproperty Item Item::parent
    This property holds the parent of the item.
*/

/*!
    \property QFxItem::parent
    This property holds the parent of the item.
*/
void QFxItem::setParentItem(QFxItem *parent)
{
    QFxItem *oldParent = parentItem();
    if (parent == oldParent || !parent) return;

    QObject::setParent(parent);
    QGraphicsObject::setParentItem(parent);

    parentChanged(parent, oldParent);
}

/*!
    Returns the QFxItem parent of this item.
*/
QFxItem *QFxItem::parentItem() const
{
    return qobject_cast<QFxItem *>(QGraphicsObject::parentItem());
}

/*!
    \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 {},
            Rect {}
        ]
        resources: [
            Component {
                id: myComponent
                Text {}
            }
        ]
    }
    \endqml
*/

/*!
    \property QFxItem::children

    This property contains the list of visual children of this item. 
*/

/*!
    \property QFxItem::resources

    This property contains non-visual resources that you want to 
    reference by name.
*/

/*!
    Returns true if all of the attributes set via QML have been set;
    otherwise returns false.

    \sa classComplete()
*/
bool QFxItem::isClassComplete() const
{
    Q_D(const QFxItem);
    return d->_classComplete;
}

/*!
    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 QFxItem::isComponentComplete() const
{
    Q_D(const QFxItem);
    return d->_componentComplete;
}

/*!
    \property QFxItem::anchors
    \brief The anchors (alignments) used by the item.
*/
QFxAnchors *QFxItem::anchors()
{
    Q_D(QFxItem);
    return d->anchors();
}

void QFxItemPrivate::data_removeAt(int)
{
    // ###
}

int QFxItemPrivate::data_count() const
{
    // ###
    return 0;
}

void QFxItemPrivate::data_append(QObject *o)
{
    Q_Q(QFxItem);
    QFxItem *i = qobject_cast<QFxItem *>(o);
    if (i)
        q->children()->append(i);
    else
        resources_append(o);
}

void QFxItemPrivate::data_insert(int, QObject *)
{
    // ###
}

QObject *QFxItemPrivate::data_at(int) const
{
    // ###
    return 0;
}

void QFxItemPrivate::data_clear()
{
    // ###
}

void QFxItemPrivate::resources_removeAt(int)
{
    // ###
}

int QFxItemPrivate::resources_count() const
{
    // ###
    return 0;
}

void QFxItemPrivate::resources_append(QObject *o)
{
    Q_Q(QFxItem);
    o->setParent(q);
}

void QFxItemPrivate::resources_insert(int, QObject *)
{
    // ###
}

QObject *QFxItemPrivate::resources_at(int) const
{
    // ###
    return 0;
}

void QFxItemPrivate::resources_clear()
{
    // ###
}

void QFxItemPrivate::children_removeAt(int)
{
    // ###
}

int QFxItemPrivate::children_count() const
{
    // ###
    return 0;
}

void QFxItemPrivate::children_append(QFxItem *i)
{
    Q_Q(QFxItem);
    i->setParentItem(q);
}

void QFxItemPrivate::children_insert(int, QFxItem *)
{
    // ###
}

QFxItem *QFxItemPrivate::children_at(int) const
{
    // ###
    return 0;
}

void QFxItemPrivate::children_clear()
{
    // ###
}


void QFxItemPrivate::transform_removeAt(int i)
{
    if (!transformData)
        return;
    transformData->graphicsTransforms.removeAt(i);
    dirtySceneTransform = 1;
}

int QFxItemPrivate::transform_count() const
{
    return transformData ? transformData->graphicsTransforms.size() : 0;
}

void QFxItemPrivate::transform_append(QGraphicsTransform *item)
{
    appendGraphicsTransform(item);
}

void QFxItemPrivate::transform_insert(int, QGraphicsTransform *)
{
    // ###
}

QGraphicsTransform *QFxItemPrivate::transform_at(int idx) const
{
    if (!transformData)
        return 0;
    return transformData->graphicsTransforms.at(idx);
}

void QFxItemPrivate::transform_clear()
{
    if (!transformData)
        return;
    Q_Q(QFxItem);
    q->setTransformations(QList<QGraphicsTransform *>());
}

/*!
    \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 {}
        Rect {}
        Script {}
    }
    \endqml

    instead of:
    \qml
    Item {
        children: [
            Text {},
            Rect {}
        ]
        resources: [
            Script {}
        ]
    }
    \endqml

    data is a behind-the-scenes property: you should never need to explicitly 
    specify it.
 */

/*!
    \property QFxItem::data

    The data property is allows you to freely mix the visual children
    and the non-visual 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.

    data is a behind-the-scenes property: you should never need to
    explicitly specify it.
 */
QmlList<QObject *> *QFxItem::data()
{
    Q_D(QFxItem);
    return &d->data;
}

/*!
    \property QFxItem::contents
    \brief An object that knows about the size of an item's children.

    contents provides an easy way to access the (collective) width and
    height of the item's children.
*/
QFxContents *QFxItem::contents()
{
    Q_D(QFxItem);
    if (!d->_contents) {
        d->_contents = new QFxContents;
        d->_contents->setParent(this);
        d->_contents->setItem(this);
    }
    return d->_contents;
}

bool QFxItem::clip() const
{
    return flags() & ItemClipsChildrenToShape;
}

void QFxItem::setClip(bool c)
{
    setFlag(ItemClipsChildrenToShape, c);
}

/*!
  \internal
  \property QFxItem::qmlItem
*/

/*! \fn QFxItem *QFxItem::qmlItem() const
  \internal
 */
QFxItem *QFxItem::qmlItem() const
{
    Q_D(const QFxItem);
    return d->qmlItem;
}

/*!
    \qmlproperty url Item::qml
    This property holds the dynamic URL of the QML for the item.

    This property is used for dynamically loading QML into the
    item. Querying for the QML only has meaning if the QML has been
    dynamically set; otherwise an empty URL is returned.
*/

/*! \fn void QFxItem::qmlChanged()
  This signal is emitted whenever the item's dynamic QML
  string changes.

  \sa setQml()
 */

/*!
    \property QFxItem::qml
    This property holds the dynamic URL of the QML for the item.

    This property is used for dynamically loading QML into the
    item. Querying for the QML only has meaning if the QML has been
    dynamically set; otherwise an empty URL is returned.
*/
QUrl QFxItem::qml() const
{
    Q_D(const QFxItem);
    return d->_qml;
}

void QFxItem::setQml(const QUrl &qml)
{
    Q_D(QFxItem);
    if (d->_qml == qml)
        return;

    if (!d->_qml.isEmpty()) {
        QmlChildren::Iterator iter = d->_qmlChildren.find(d->_qml.toString());
        if (iter != d->_qmlChildren.end())
            (*iter)->setOpacity(0.);
    }

    d->_qml = qml;
    d->qmlItem = 0;

    if (d->_qml.isEmpty()) {
        emit qmlChanged();
        return;
    }

    QmlChildren::Iterator iter = d->_qmlChildren.find(d->_qml.toString());
    if (iter != d->_qmlChildren.end()) {
        (*iter)->setOpacity(1.);
        d->qmlItem = (*iter);
        emit qmlChanged();
    } else {
        d->_qmlcomp = 
            new QmlComponent(qmlEngine(this), d->_qml, this);
        if (!d->_qmlcomp->isLoading())
            qmlLoaded();
        else
            QObject::connect(d->_qmlcomp, SIGNAL(statusChanged(QmlComponent::Status)),
                             this, SLOT(qmlLoaded()));
    }
}

/*! \fn void QFxItem::newChildCreated(const QString &url, QScriptValue v)
  This signal is emitted with the \a url and the script value \a v,
  when a new child is created.
 */

/*!
  \internal
 */
void QFxItem::qmlLoaded()
{
    Q_D(QFxItem);

    { // newChild...
        // ###
        for (int i=0; i<d->_qmlnewloading.length(); ++i) {
            QmlComponent *c = d->_qmlnewcomp.at(i);
            if (c->isLoading())
                continue;

            QmlContext *ctxt = new QmlContext(qmlContext(this));
            QObject* o = c ? c->create(ctxt):0;
            QFxItem* ret = qobject_cast<QFxItem*>(o);
            if (ret) {
                ret->setParentItem(this);
                QScriptValue v = QmlEnginePrivate::getScriptEngine(qmlEngine(this))->newQObject(ret);
                emit newChildCreated(d->_qmlnewloading.at(i).toString(),v);
            }

            delete c;
            d->_qmlnewloading.removeAt(i);
            d->_qmlnewcomp.removeAt(i);
            --i;
        }
    }

    // setQml...
    if (d->_qmlcomp) {
{'fraction_non_alphanumeric': 0.12495831302429389, 'fraction_numerical': 0.005182011749313768, 'mean_word_length': 2.7671047545419403, 'pattern_counts': {'":': 0, '<': 77, '<?xml version=': 0, '>': 233, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4714896', 'n_tokens_mistral': 12913, 'n_tokens_neox': 12530, 'n_words': 3644}