diff options
author | Martin Jones <martin.jones@nokia.com> | 2009-10-26 06:12:25 (GMT) |
---|---|---|
committer | Martin Jones <martin.jones@nokia.com> | 2009-10-26 06:12:25 (GMT) |
commit | 819503280f9ac63c362957fb551d8a3b0d22eee5 (patch) | |
tree | d5e8ef1f0b42bfde8a5f907910201672f95bbe1c /src/declarative | |
parent | 5dedd5ee9c88c075c6ffeb09526088d93671efaa (diff) | |
parent | db09dc27d32cbc3be51773c86f189418c12ac971 (diff) | |
download | Qt-819503280f9ac63c362957fb551d8a3b0d22eee5.zip Qt-819503280f9ac63c362957fb551d8a3b0d22eee5.tar.gz Qt-819503280f9ac63c362957fb551d8a3b0d22eee5.tar.bz2 |
Merge branch 'kinetic-declarativeui' of scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
Diffstat (limited to 'src/declarative')
45 files changed, 589 insertions, 144 deletions
diff --git a/src/declarative/extra/qmlbehavior.h b/src/declarative/extra/qmlbehavior.h index 994d85c..6508455 100644 --- a/src/declarative/extra/qmlbehavior.h +++ b/src/declarative/extra/qmlbehavior.h @@ -60,6 +60,7 @@ class Q_DECLARATIVE_EXPORT QmlBehavior : public QObject, public QmlPropertyValue Q_OBJECT Q_DECLARE_PRIVATE(QmlBehavior) + Q_INTERFACES(QmlPropertyValueInterceptor) Q_CLASSINFO("DefaultProperty", "animation") Q_PROPERTY(QmlAbstractAnimation *animation READ animation WRITE setAnimation) diff --git a/src/declarative/fx/qfxanchors.cpp b/src/declarative/fx/qfxanchors.cpp index 737aa63..8d4a8b8 100644 --- a/src/declarative/fx/qfxanchors.cpp +++ b/src/declarative/fx/qfxanchors.cpp @@ -181,7 +181,6 @@ void QFxAnchorsPrivate::centerInChanged() void QFxAnchorsPrivate::clearItem(QFxItem *item) { - Q_Q(QFxAnchors); if (!item) return; if (fill == item) diff --git a/src/declarative/fx/qfxgridview.cpp b/src/declarative/fx/qfxgridview.cpp index 36c06a4..0b2a935 100644 --- a/src/declarative/fx/qfxgridview.cpp +++ b/src/declarative/fx/qfxgridview.cpp @@ -736,14 +736,13 @@ QFxGridView::~QFxGridView() \endcode */ -//XXX change to \qmlattachedsignal when it exists. /*! - \qmlattachedproperty void GridView::onAdd + \qmlattachedsignal GridView::onAdd() This attached handler is called immediately after an item is added to the view. */ /*! - \qmlattachedproperty void GridView::onRemove + \qmlattachedsignal GridView::onRemove() This attached handler is called immediately before an item is removed from the view. */ diff --git a/src/declarative/fx/qfxitem.cpp b/src/declarative/fx/qfxitem.cpp index abf20d6..e714494 100644 --- a/src/declarative/fx/qfxitem.cpp +++ b/src/declarative/fx/qfxitem.cpp @@ -79,15 +79,10 @@ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Rotation,QGraphicsRotation) #include "qfxeffects.cpp" /*! - \qmlclass Transform - \brief A transformation. -*/ - -/*! \qmlclass Scale - \brief A Scale object provides a way to scale an Item. + \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, + 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. @@ -105,13 +100,14 @@ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Rotation,QGraphicsRotation) \qmlproperty real Scale::origin.x \qmlproperty real Scale::origin.y - The origin point for the scale. The scale will be relative to this point. + 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. + The scaling factor for the X axis. */ /*! @@ -122,7 +118,10 @@ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Rotation,QGraphicsRotation) /*! \qmlclass Rotation - \brief A Rotation object provides a way to rotate an Item around a point using an axis in 3D space. + \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 @@ -133,7 +132,10 @@ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Rotation,QGraphicsRotation) } \endqml - Here is an example of various rotations applied to an \l Image. + 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 @@ -143,7 +145,8 @@ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Rotation,QGraphicsRotation) \qmlproperty real Rotation::origin.x \qmlproperty real Rotation::origin.y - The point to rotate around. + 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. */ /*! @@ -151,16 +154,18 @@ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Rotation,QGraphicsRotation) \qmlproperty real Rotation::axis.y \qmlproperty real Rotation::axis.z - A rotation axis is specified by a vector in 3D space By default the vector defines a rotation around the z-Axis. + 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: 0 } }). - \image 3d-rotation-axis.png + 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, in degrees, to rotate. + The angle to rotate, in degrees clockwise. */ @@ -1193,6 +1198,19 @@ QFxKeysAttached *QFxKeysAttached::qmlAttachedProperties(QObject *obj) } /*! + \class QFxItem + \brief QFxItem is the most basic of all visual items in QML. + + 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 - such as the x and y position, the + width and height, \l {anchor-layout}{anchoring} and key handling. + + You can subclass QFxItem to provide your own custom visual item that inherits + these features. +*/ + +/*! \qmlclass Item QFxItem \brief The Item is the most basic of all visual items in QML. @@ -1360,7 +1378,7 @@ QFxItem::~QFxItem() \qml Image { source: "myimage.png" - transformOrigin: "Center" + transformOrigin: Item.Center scale: 4 } \endqml @@ -2114,7 +2132,7 @@ void QFxItem::setBaselineOffset(qreal offset) /*! \qmlproperty real Item::rotation - This property holds the rotation of the item in degrees. + 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). diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp index 23bf573..1a4a60c 100644 --- a/src/declarative/fx/qfxlistview.cpp +++ b/src/declarative/fx/qfxlistview.cpp @@ -926,14 +926,13 @@ QFxListView::~QFxListView() \endcode */ -//XXX change to \qmlattachedsignal when it exists. /*! - \qmlattachedproperty void ListView::onAdd + \qmlattachedsignal ListView::onAdd() This attached handler is called immediately after an item is added to the view. */ /*! - \qmlattachedproperty void ListView::onRemove + \qmlattachedsignal ListView::onRemove() This attached handler is called immediately before an item is removed from the view. */ diff --git a/src/declarative/fx/qfxpainteditem.cpp b/src/declarative/fx/qfxpainteditem.cpp index 05fcc93..e0ef99f 100644 --- a/src/declarative/fx/qfxpainteditem.cpp +++ b/src/declarative/fx/qfxpainteditem.cpp @@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE /*! \class QFxPaintedItem \brief The QFxPaintedItem class is an abstract base class for QmlView items that want cached painting. - \ingroup group_coreitems + \internal This is a convenience class for implementing items that paint their contents using a QPainter. The contents of the item are cached behind the scenes. diff --git a/src/declarative/fx/qfxrect.cpp b/src/declarative/fx/qfxrect.cpp index f35fe3d..d4207a6 100644 --- a/src/declarative/fx/qfxrect.cpp +++ b/src/declarative/fx/qfxrect.cpp @@ -43,6 +43,7 @@ #include "qfxrect_p.h" #include <QPainter> +#include <QtCore/qmath.h> QT_BEGIN_NAMESPACE QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Pen,QFxPen) @@ -338,7 +339,8 @@ void QFxRect::generateRoundedRect() Q_D(QFxRect); if (d->rectImage.isNull()) { const int pw = d->pen && d->pen->isValid() ? d->pen->width() : 0; - d->rectImage = QPixmap(d->radius*2 + 3 + pw*2, d->radius*2 + 3 + pw*2); + const int radius = qCeil(d->radius); //ensure odd numbered width/height so we get 1-pixel center + d->rectImage = QPixmap(radius*2 + 3 + pw*2, radius*2 + 3 + pw*2); d->rectImage.fill(Qt::transparent); QPainter p(&(d->rectImage)); p.setRenderHint(QPainter::Antialiasing); @@ -361,7 +363,7 @@ void QFxRect::generateBorderedRect() Q_D(QFxRect); if (d->rectImage.isNull()) { const int pw = d->pen && d->pen->isValid() ? d->pen->width() : 0; - d->rectImage = QPixmap(d->getPen()->width()*2 + 3 + pw*2, d->getPen()->width()*2 + 3 + pw*2); + d->rectImage = QPixmap(pw*2 + 3, pw*2 + 3); d->rectImage.fill(Qt::transparent); QPainter p(&(d->rectImage)); p.setRenderHint(QPainter::Antialiasing); @@ -439,6 +441,7 @@ void QFxRect::drawRect(QPainter &p) QMargins margins(xOffset, yOffset, xOffset, yOffset); QTileRules rules(Qt::StretchTile, Qt::StretchTile); + //NOTE: even though our item may have qreal-based width and height, qDrawBorderPixmap only supports QRects qDrawBorderPixmap(&p, QRect(-pw/2, -pw/2, width()+pw, height()+pw), margins, d->rectImage, d->rectImage.rect(), margins, rules); if (d->smooth) { diff --git a/src/declarative/fx/qfxvisualitemmodel.cpp b/src/declarative/fx/qfxvisualitemmodel.cpp index a078da6..e1ac246 100644 --- a/src/declarative/fx/qfxvisualitemmodel.cpp +++ b/src/declarative/fx/qfxvisualitemmodel.cpp @@ -102,7 +102,7 @@ QHash<QObject*, QFxVisualItemModelAttached*> QFxVisualItemModelAttached::attache class QFxVisualItemModelPrivate : public QObjectPrivate { - Q_DECLARE_PUBLIC(QFxVisualItemModel); + Q_DECLARE_PUBLIC(QFxVisualItemModel) public: QFxVisualItemModelPrivate() : QObjectPrivate(), children(this) {} @@ -143,7 +143,7 @@ public: \code Item { VisualItemModel { - id: ItemModel + id: itemModel Rectangle { height: 30; width: 80; color: "red" } Rectangle { height: 30; width: 80; color: "green" } Rectangle { height: 30; width: 80; color: "blue" } @@ -151,7 +151,7 @@ public: ListView { anchors.fill: parent - model: ItemModel + model: itemModel } } \endcode @@ -416,8 +416,13 @@ int QFxVisualDataModelDataMetaObject::createProperty(const char *name, const cha if ((!model->m_listModelInterface || !model->m_abstractItemModel) && model->m_listAccessor) { model->ensureRoles(); - if (model->m_roleNames.contains(QString::fromUtf8(name))) + if (model->m_roleNames.contains(QString::fromUtf8(name))) { return QmlOpenMetaObject::createProperty(name, type); + } else if (model->m_listAccessor->type() == QmlListAccessor::QmlList) { + QObject *object = model->m_listAccessor->at(data->m_index).value<QObject*>(); + if (object && object->property(name).isValid()) + return QmlOpenMetaObject::createProperty(name, type); + } } else { model->ensureRoles(); QString sname = QString::fromUtf8(name); @@ -448,7 +453,7 @@ QFxVisualDataModelDataMetaObject::propertyCreated(int, QMetaPropertyBuilder &pro return model->m_listAccessor->at(data->m_index); } else { // return any property of a single object instance. - QObject *object = model->m_listAccessor->at(0).value<QObject*>(); + QObject *object = model->m_listAccessor->at(data->m_index).value<QObject*>(); return object->property(prop.name()); } } else if (model->m_listModelInterface) { diff --git a/src/declarative/qml/qbitfield_p.h b/src/declarative/qml/qbitfield_p.h index 70d5041..a8cc9dc 100644 --- a/src/declarative/qml/qbitfield_p.h +++ b/src/declarative/qml/qbitfield_p.h @@ -139,11 +139,11 @@ QBitField QBitField::united(const QBitField &o) rv.data = rv.ownData + 1; if (bits > o.bits) { ::memcpy((quint32 *)rv.data, data, length * sizeof(quint32)); - for (quint32 ii = 0; ii < (o.bits + 31) / 32; ++ii) + for (quint32 ii = 0; ii < (o.bits + quint32(31)) / 32; ++ii) ((quint32 *)rv.data)[ii] |= o.data[ii]; } else { ::memcpy((quint32 *)rv.data, o.data, length * sizeof(quint32)); - for (quint32 ii = 0; ii < (bits + 31) / 32; ++ii) + for (quint32 ii = 0; ii < (bits + quint32(31)) / 32; ++ii) ((quint32 *)rv.data)[ii] |= data[ii]; } return rv; diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri index b6e86a8..cbc2f85 100644 --- a/src/declarative/qml/qml.pri +++ b/src/declarative/qml/qml.pri @@ -37,6 +37,7 @@ SOURCES += qml/qmlparser.cpp \ qml/qmetaobjectbuilder.cpp \ qml/qmlwatcher.cpp \ qml/qmlscript.cpp \ + qml/qmlcleanup.cpp \ qml/qmlpropertycache.cpp \ qml/qmlintegercache.cpp \ qml/qmltypenamecache.cpp \ @@ -100,6 +101,7 @@ HEADERS += qml/qmlparser_p.h \ qml/qmlsqldatabase_p.h \ qml/qmetaobjectbuilder_p.h \ qml/qmlwatcher_p.h \ + qml/qmlcleanup_p.h \ qml/qmlpropertycache_p.h \ qml/qmlintegercache_p.h \ qml/qmltypenamecache_p.h \ diff --git a/src/declarative/qml/qmlcleanup.cpp b/src/declarative/qml/qmlcleanup.cpp new file mode 100644 index 0000000..7799cfc --- /dev/null +++ b/src/declarative/qml/qmlcleanup.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (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 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 qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmlcleanup_p.h" +#include <private/qmlengine_p.h> + +/*! +\internal +\class QmlCleanup +\brief The QmlCleanup provides a callback when a QmlEngine is deleted. + +Any object that needs cleanup to occur before the QmlEngine's QScriptEngine is +destroyed should inherit from QmlCleanup. The clear() virtual method will be +called by QmlEngine just before it deletes the QScriptEngine. +*/ + +/*! +\internal + +Create a QmlCleanup for \a engine +*/ +QmlCleanup::QmlCleanup(QmlEngine *engine) +: prev(0), next(0) +{ + Q_ASSERT(engine); + QmlEnginePrivate *p = QmlEnginePrivate::get(engine); + + if (p->cleanup) next = p->cleanup; + p->cleanup = this; + prev = &p->cleanup; + if (next) next->prev = &next; +} + +/*! +\internal +*/ +QmlCleanup::~QmlCleanup() +{ + if (prev) *prev = next; + if (next) next->prev = prev; + prev = 0; + next = 0; +} + diff --git a/src/declarative/qml/qmlcleanup_p.h b/src/declarative/qml/qmlcleanup_p.h new file mode 100644 index 0000000..e9196a3 --- /dev/null +++ b/src/declarative/qml/qmlcleanup_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (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 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 qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMLCLEANUP_P_H +#define QMLCLEANUP_P_H + +#include <QtCore/qglobal.h> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +class QmlEngine; +class QmlCleanup +{ +public: + QmlCleanup(QmlEngine *); + virtual ~QmlCleanup(); + +protected: + virtual void clear() = 0; + +private: + friend class QmlEnginePrivate; + QmlCleanup **prev; + QmlCleanup *next; +}; + +QT_END_NAMESPACE + +#endif // QMLCLEANUP_P_H + diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp index 12fb120..0894758 100644 --- a/src/declarative/qml/qmlcomponent.cpp +++ b/src/declarative/qml/qmlcomponent.cpp @@ -390,8 +390,6 @@ valid for components created directly from QML. */ QmlContext *QmlComponent::creationContext() const { - Q_D(const QmlComponent); - QmlDeclarativeData *ddata = QmlDeclarativeData::get(this); if (ddata) return ddata->context; diff --git a/src/declarative/qml/qmlcomponent_p.h b/src/declarative/qml/qmlcomponent_p.h index 7eedfbd..f90502f 100644 --- a/src/declarative/qml/qmlcomponent_p.h +++ b/src/declarative/qml/qmlcomponent_p.h @@ -76,7 +76,7 @@ class QmlComponentPrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QmlComponent) public: - QmlComponentPrivate() : typeData(0), progress(0.), start(-1), count(-1), cc(0), completePending(false), componentAttacheds(0), engine(0) {} + QmlComponentPrivate() : typeData(0), progress(0.), start(-1), count(-1), cc(0), componentAttacheds(0), completePending(false), engine(0) {} QObject *create(QmlContext *context, const QBitField &); diff --git a/src/declarative/qml/qmlcompositetypedata_p.h b/src/declarative/qml/qmlcompositetypedata_p.h index fa11137..ffcef4c 100644 --- a/src/declarative/qml/qmlcompositetypedata_p.h +++ b/src/declarative/qml/qmlcompositetypedata_p.h @@ -69,7 +69,8 @@ public: Invalid, Complete, Error, - Waiting + Waiting, + WaitingResources }; Status status; enum ErrorType { diff --git a/src/declarative/qml/qmlcompositetypemanager.cpp b/src/declarative/qml/qmlcompositetypemanager.cpp index 3c76344..b335d31 100644 --- a/src/declarative/qml/qmlcompositetypemanager.cpp +++ b/src/declarative/qml/qmlcompositetypemanager.cpp @@ -352,18 +352,6 @@ void QmlCompositeTypeManager::setData(QmlCompositeTypeData *unit, if (!unit->data.parse(data, url)) { ok = false; unit->errors << unit->data.errors(); - } else { - foreach (QmlScriptParser::Import imp, unit->data.imports()) { - int dot = imp.version.indexOf(QLatin1Char('.')); - if (dot < 0) dot = imp.version.length(); - if (!QmlEnginePrivate::get(engine)->addToImport(&unit->imports, imp.uri, imp.qualifier, imp.version.left(dot).toInt(), imp.version.mid(dot+1).toInt(), imp.type)) { - QmlError error; - error.setUrl(url); - error.setDescription(tr("Import %1 unavailable").arg(imp.uri)); - unit->errors << error; - ok = false; - } - } } if (ok) { @@ -400,25 +388,11 @@ void QmlCompositeTypeManager::doComplete(QmlCompositeTypeResource *resource) void QmlCompositeTypeManager::checkComplete(QmlCompositeTypeData *unit) { - if (unit->status != QmlCompositeTypeData::Waiting) + if (unit->status != QmlCompositeTypeData::Waiting + && unit->status != QmlCompositeTypeData::WaitingResources) return; int waiting = 0; - for (int ii = 0; ii < unit->types.count(); ++ii) { - QmlCompositeTypeData *u = unit->types.at(ii).unit; - - if (!u) - continue; - - if (u->status == QmlCompositeTypeData::Error) { - unit->status = QmlCompositeTypeData::Error; - unit->errors = u->errors; - doComplete(unit); - return; - } else if (u->status == QmlCompositeTypeData::Waiting) { - waiting++; - } - } for (int ii = 0; ii < unit->resources.count(); ++ii) { QmlCompositeTypeResource *r = unit->resources.at(ii); @@ -429,28 +403,84 @@ void QmlCompositeTypeManager::checkComplete(QmlCompositeTypeData *unit) unit->status = QmlCompositeTypeData::Error; QmlError error; error.setUrl(unit->imports.baseUrl()); - error.setDescription(QLatin1String("Resource ") + r->url + - QLatin1String(" unavailable")); + error.setDescription(tr("Resource %1 unavailable").arg(r->url)); unit->errors << error; doComplete(unit); return; - } else if (r->status == QmlCompositeTypeData::Waiting) { + } else if (r->status == QmlCompositeTypeResource::Waiting) { waiting++; } } + if (waiting == 0) { + if (unit->status == QmlCompositeTypeData::WaitingResources) { + waiting += resolveTypes(unit); + if (unit->status != QmlCompositeTypeData::Error) { + if (waiting) + unit->status = QmlCompositeTypeData::Waiting; + } else { + return; + } + } else { + for (int ii = 0; ii < unit->types.count(); ++ii) { + QmlCompositeTypeData *u = unit->types.at(ii).unit; + + if (!u) + continue; + + if (u->status == QmlCompositeTypeData::Error) { + unit->status = QmlCompositeTypeData::Error; + unit->errors = u->errors; + doComplete(unit); + return; + } else if (u->status == QmlCompositeTypeData::Waiting) { + waiting++; + } + } + } + } + if (!waiting) { unit->status = QmlCompositeTypeData::Complete; doComplete(unit); } } -// ### Check ref counting in here -void QmlCompositeTypeManager::compile(QmlCompositeTypeData *unit) +int QmlCompositeTypeManager::resolveTypes(QmlCompositeTypeData *unit) { - QList<QmlScriptParser::TypeReference*> types = unit->data.referencedTypes(); + // not called until all resources are loaded (they include import URLs) int waiting = 0; + + foreach (QmlScriptParser::Import imp, unit->data.imports()) { + int dot = imp.version.indexOf(QLatin1Char('.')); + if (dot < 0) dot = imp.version.length(); + QString qmldir; + if (imp.type == QmlScriptParser::Import::File && imp.qualifier.isEmpty()) { + QUrl importUrl = unit->imports.baseUrl().resolved(QUrl(imp.uri + QLatin1String("/qmldir"))); + for (int ii = 0; ii < unit->resources.count(); ++ii) { + if (unit->resources.at(ii)->url == importUrl) { + qmldir = QString::fromUtf8(unit->resources.at(ii)->data); + break; + } + } + } + if (!QmlEnginePrivate::get(engine)->addToImport( + &unit->imports, qmldir, imp.uri, imp.qualifier, imp.version.left(dot).toInt(), imp.version.mid(dot+1).toInt(), imp.type)) + { + QmlError error; + error.setUrl(unit->imports.baseUrl()); + error.setDescription(tr("Import %1 unavailable").arg(imp.uri)); + unit->status = QmlCompositeTypeData::Error; + unit->errorType = QmlCompositeTypeData::GeneralError; + unit->errors << error; + doComplete(unit); + return 0; + } + } + + QList<QmlScriptParser::TypeReference*> types = unit->data.referencedTypes(); + for (int ii = 0; ii < types.count(); ++ii) { QmlScriptParser::TypeReference *parserRef = types.at(ii); QByteArray typeName = parserRef->name.toUtf8(); @@ -478,7 +508,7 @@ void QmlCompositeTypeManager::compile(QmlCompositeTypeData *unit) unit->errorType = QmlCompositeTypeData::GeneralError; unit->errors << error; doComplete(unit); - return; + return 0; } if (ref.type) { @@ -521,12 +551,13 @@ void QmlCompositeTypeManager::compile(QmlCompositeTypeData *unit) if (urlUnit->errorType != QmlCompositeTypeData::AccessError) unit->errors << urlUnit->errors; doComplete(unit); - return; + return 0; case QmlCompositeTypeData::Complete: break; case QmlCompositeTypeData::Waiting: + case QmlCompositeTypeData::WaitingResources: unit->addref(); ref.unit->dependants << unit; waiting++; @@ -535,8 +566,26 @@ void QmlCompositeTypeManager::compile(QmlCompositeTypeData *unit) unit->types << ref; } + return waiting; +} + +// ### Check ref counting in here +void QmlCompositeTypeManager::compile(QmlCompositeTypeData *unit) +{ + int waiting = 0; QList<QUrl> resourceList = unit->data.referencedResources(); + + foreach (QmlScriptParser::Import imp, unit->data.imports()) { + if (imp.type == QmlScriptParser::Import::File && imp.qualifier.isEmpty()) { + QUrl importUrl = unit->imports.baseUrl().resolved(QUrl(imp.uri + QLatin1String("/qmldir"))); + if (toLocalFileOrQrc(importUrl).isEmpty()) { + // Import requires remote qmldir + resourceList.prepend(importUrl); + } + } + } + for (int ii = 0; ii < resourceList.count(); ++ii) { QUrl url = unit->imports.baseUrl().resolved(resourceList.at(ii)); @@ -558,8 +607,7 @@ void QmlCompositeTypeManager::compile(QmlCompositeTypeData *unit) { QmlError error; error.setUrl(unit->imports.baseUrl()); - error.setDescription(QLatin1String("Resource ") + resource->url + - QLatin1String(" unavailable")); + error.setDescription(tr("Resource %1 unavailable").arg(resource->url)); unit->errors << error; } doComplete(unit); @@ -579,11 +627,18 @@ void QmlCompositeTypeManager::compile(QmlCompositeTypeData *unit) unit->resources << resource; } - if (waiting) { - unit->status = QmlCompositeTypeData::Waiting; + if (waiting == 0) { + waiting += resolveTypes(unit); + if (unit->status != QmlCompositeTypeData::Error) { + if (!waiting) { + unit->status = QmlCompositeTypeData::Complete; + doComplete(unit); + } else { + unit->status = QmlCompositeTypeData::Waiting; + } + } } else { - unit->status = QmlCompositeTypeData::Complete; - doComplete(unit); + unit->status = QmlCompositeTypeData::WaitingResources; } } diff --git a/src/declarative/qml/qmlcompositetypemanager_p.h b/src/declarative/qml/qmlcompositetypemanager_p.h index 843a9cf..b6f84db 100644 --- a/src/declarative/qml/qmlcompositetypemanager_p.h +++ b/src/declarative/qml/qmlcompositetypemanager_p.h @@ -101,6 +101,7 @@ private: void doComplete(QmlCompositeTypeData *); void doComplete(QmlCompositeTypeResource *); void checkComplete(QmlCompositeTypeData *); + int resolveTypes(QmlCompositeTypeData *); QmlEngine *engine; typedef QHash<QString, QmlCompositeTypeData *> Components; diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp index 31d4e1f..7ba3544 100644 --- a/src/declarative/qml/qmlcontext.cpp +++ b/src/declarative/qml/qmlcontext.cpp @@ -396,8 +396,7 @@ void QmlContext::setContextProperty(const QString &name, const QVariant &value) } } -void QmlContextPrivate::setIdProperty(const QString &name, int idx, - QObject *obj) +void QmlContextPrivate::setIdProperty(int idx, QObject *obj) { if (notifyIndex == -1) { Q_Q(QmlContext); @@ -487,7 +486,6 @@ void QmlContext::setBaseUrl(const QUrl &baseUrl) */ QUrl QmlContext::baseUrl() const { - Q_D(const QmlContext); const QmlContext* p = this; while (p && p->d_func()->url.isEmpty()) { p = p->parentContext(); diff --git a/src/declarative/qml/qmlcontext_p.h b/src/declarative/qml/qmlcontext_p.h index 9a77e94..be7bf1d 100644 --- a/src/declarative/qml/qmlcontext_p.h +++ b/src/declarative/qml/qmlcontext_p.h @@ -129,7 +129,7 @@ public: }; ContextGuard *idValues; int idValueCount; - void setIdProperty(const QString &, int, QObject *); + void setIdProperty(int, QObject *); void setIdPropertyData(QmlIntegerCache *); void destroyed(ContextGuard *); diff --git a/src/declarative/qml/qmldom.cpp b/src/declarative/qml/qmldom.cpp index a0601d7..21eeb7c 100644 --- a/src/declarative/qml/qmldom.cpp +++ b/src/declarative/qml/qmldom.cpp @@ -1181,6 +1181,75 @@ QmlDomObject QmlDomValueValueSource::object() const return rv; } +/*! + \class QmlDomValueValueInterceptor + \internal + \brief The QmlDomValueValueInterceptor class represents a value interceptor assignment value. + + In QML, value interceptor are special write-intercepting types that may be + assigned to properties. Value interceptor inherit the QmlPropertyValueInterceptor + class. In the example below, the "x" property is being assigned the + Behavior value interceptor. + + \qml +Rectangle { + x: Behavior { NumberAnimation { duration: 500 } } +} + \endqml +*/ + +/*! + Construct an empty QmlDomValueValueInterceptor. +*/ +QmlDomValueValueInterceptor::QmlDomValueValueInterceptor(): + d(new QmlDomBasicValuePrivate) +{ +} + +/*! + Create a copy of \a other QmlDomValueValueInterceptor. +*/ +QmlDomValueValueInterceptor::QmlDomValueValueInterceptor(const QmlDomValueValueInterceptor &other) +: d(other.d) +{ +} + +/*! + Destroy the QmlDomValueValueInterceptor. +*/ +QmlDomValueValueInterceptor::~QmlDomValueValueInterceptor() +{ +} + +/*! + Assign \a other to this QmlDomValueValueInterceptor. +*/ +QmlDomValueValueInterceptor &QmlDomValueValueInterceptor::operator=(const QmlDomValueValueInterceptor &other) +{ + d = other.d; + return *this; +} + +/*! + Return the value interceptor object. + + In the example below, an object representing the Behavior will be + returned. + \qml +Rectangle { + x: Behavior { NumberAnimation { duration: 500 } } +} + \endqml +*/ +QmlDomObject QmlDomValueValueInterceptor::object() const +{ + QmlDomObject rv; + if (d->value) { + rv.d->object = d->value->object; + rv.d->object->addref(); + } + return rv; +} QmlDomValuePrivate::QmlDomValuePrivate() : property(0), value(0) @@ -1286,6 +1355,7 @@ QmlDomValue &QmlDomValue::operator=(const QmlDomValue &other) \value Literal The QmlDomValue is a literal value assignment. Use QmlDomValue::toLiteral() to access the type instance. \value PropertyBinding The QmlDomValue is a property binding. Use QmlDomValue::toBinding() to access the type instance. \value ValueSource The QmlDomValue is a property value source. Use QmlDomValue::toValueSource() to access the type instance. + \value ValueInterceptor The QmlDomValue is a property value interceptor. Use QmlDomValue::toValueInterceptor() to access the type instance. \value Object The QmlDomValue is an object assignment. Use QmlDomValue::toObject() to access the type instnace. \value List The QmlDomValue is a list of other values. Use QmlDomValue::toList() to access the type instance. */ @@ -1314,6 +1384,8 @@ QmlDomValue::Type QmlDomValue::type() const return PropertyBinding; case QmlParser::Value::ValueSource: return ValueSource; + case QmlParser::Value::ValueInterceptor: + return ValueInterceptor; case QmlParser::Value::CreatedObject: return Object; case QmlParser::Value::SignalObject: @@ -1359,6 +1431,14 @@ bool QmlDomValue::isValueSource() const } /*! + Returns true if this is a value interceptor value, otherwise false. +*/ +bool QmlDomValue::isValueInterceptor() const +{ + return type() == ValueInterceptor; +} + +/*! Returns true if this is an object value, otherwise false. */ bool QmlDomValue::isObject() const @@ -1423,6 +1503,22 @@ QmlDomValueValueSource QmlDomValue::toValueSource() const } /*! + Returns a QmlDomValueValueInterceptor if this value is a property value interceptor + type, otherwise returns an invalid QmlDomValueValueInterceptor. + + \sa QmlDomValue::type() +*/ +QmlDomValueValueInterceptor QmlDomValue::toValueInterceptor() const +{ + QmlDomValueValueInterceptor rv; + if (type() == ValueInterceptor) { + rv.d->value = d->value; + rv.d->value->addref(); + } + return rv; +} + +/*! Returns a QmlDomObject if this value is an object assignment type, otherwise returns an invalid QmlDomObject. diff --git a/src/declarative/qml/qmldom.h b/src/declarative/qml/qmldom.h index f344bb2..5816780 100644 --- a/src/declarative/qml/qmldom.h +++ b/src/declarative/qml/qmldom.h @@ -175,6 +175,7 @@ private: friend class QmlDomComponent; friend class QmlDomValue; friend class QmlDomValueValueSource; + friend class QmlDomValueValueInterceptor; QSharedDataPointer<QmlDomObjectPrivate> d; }; @@ -225,6 +226,22 @@ private: QSharedDataPointer<QmlDomBasicValuePrivate> d; }; +class Q_DECLARATIVE_EXPORT QmlDomValueValueInterceptor +{ +public: + QmlDomValueValueInterceptor(); + QmlDomValueValueInterceptor(const QmlDomValueValueInterceptor &); + ~QmlDomValueValueInterceptor(); + QmlDomValueValueInterceptor &operator=(const QmlDomValueValueInterceptor &); + + QmlDomObject object() const; + +private: + friend class QmlDomValue; + QSharedDataPointer<QmlDomBasicValuePrivate> d; +}; + + class Q_DECLARATIVE_EXPORT QmlDomComponent : public QmlDomObject { public: @@ -244,6 +261,7 @@ public: Literal, PropertyBinding, ValueSource, + ValueInterceptor, Object, List }; @@ -259,12 +277,14 @@ public: bool isLiteral() const; bool isBinding() const; bool isValueSource() const; + bool isValueInterceptor() const; bool isObject() const; bool isList() const; QmlDomValueLiteral toLiteral() const; QmlDomValueBinding toBinding() const; QmlDomValueValueSource toValueSource() const; + QmlDomValueValueInterceptor toValueInterceptor() const; QmlDomObject toObject() const; QmlDomList toList() const; diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index 354114a..df865f1 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -128,7 +128,7 @@ static QString userLocalDataPath(const QString& app) QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e) : rootContext(0), currentExpression(0), isDebugging(false), contextClass(0), objectClass(0), valueTypeClass(0), globalClass(0), - nodeListClass(0), namedNodeMapClass(0), sqlQueryClass(0), scriptEngine(this), + nodeListClass(0), namedNodeMapClass(0), sqlQueryClass(0), cleanup(0), scriptEngine(this), componentAttacheds(0), rootComponent(0), networkAccessManager(0), typeManager(e), uniqueId(1) { QScriptValue qtObject = @@ -168,6 +168,15 @@ QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e) QmlEnginePrivate::~QmlEnginePrivate() { + while (cleanup) { + QmlCleanup *c = cleanup; + cleanup = c->next; + if (cleanup) cleanup->prev = &cleanup; + c->next = 0; + c->prev = 0; + c->clear(); + } + delete rootContext; rootContext = 0; delete contextClass; @@ -1027,6 +1036,7 @@ struct QmlEnginePrivate::ImportedNamespace { QList<int> minversions; QList<bool> isLibrary; QList<bool> isBuiltin; + QList<QString> qmlDirContent; bool find(const QByteArray& type, int *vmajor, int *vminor, QmlType** type_return, QUrl* url_return) const { @@ -1048,36 +1058,39 @@ struct QmlEnginePrivate::ImportedNamespace { } } else { QUrl url = QUrl(urls.at(i) + QLatin1String("/") + QString::fromUtf8(type) + QLatin1String(".qml")); - if (vmaj || vmin) { + QString qmldircontent = qmlDirContent.at(i); + if (vmaj || vmin || !qmldircontent.isEmpty()) { // Check version file - XXX cache these in QmlEngine! - QFile qmldir(toLocalFileOrQrc(QUrl(urls.at(i)+QLatin1String("/qmldir")))); - if (qmldir.open(QIODevice::ReadOnly)) { - do { - QByteArray lineba = qmldir.readLine(); - if (lineba.at(0) == '#') - continue; - int space1 = lineba.indexOf(' '); - if (qstrncmp(lineba,type,space1)==0) { - // eg. 1.2-5 - QString line = QString::fromUtf8(lineba); - space1 = line.indexOf(QLatin1Char(' ')); // refind in Unicode - int space2 = space1 >=0 ? line.indexOf(QLatin1Char(' '),space1+1) : -1; - QString mapversions = line.mid(space1+1,space2<0?line.length()-space1-2:space2-space1-1); - int dot = mapversions.indexOf(QLatin1Char('.')); - int dash = mapversions.indexOf(QLatin1Char('-')); - int mapvmaj = mapversions.left(dot).toInt(); - if (mapvmaj==vmaj) { - int mapvmin_from = (dash <= 0 ? mapversions.mid(dot+1) : mapversions.mid(dot+1,dash-dot-1)).toInt(); - int mapvmin_to = dash <= 0 ? mapvmin_from : mapversions.mid(dash+1).toInt(); - if (vmin >= mapvmin_from && vmin <= mapvmin_to) { - QStringRef mapfile = space2<0 ? QStringRef() : line.midRef(space2+1,line.length()-space2-2); - if (url_return) - *url_return = url.resolved(mapfile.toString()); - return true; - } + if (qmldircontent.isEmpty()) { + QFile qmldir(toLocalFileOrQrc(QUrl(urls.at(i)+QLatin1String("/qmldir")))); + if (qmldir.open(QIODevice::ReadOnly)) { + qmldircontent = QString::fromUtf8(qmldir.readAll()); + } + } + QString typespace = QString::fromUtf8(type)+QLatin1Char(' '); + QStringList lines = qmldircontent.split(QLatin1Char('\n')); + foreach (QString line, lines) { + if (line.isEmpty() || line.at(0) == QLatin1Char('#')) + continue; + if (line.startsWith(typespace)) { + // eg. 1.2-5 + int space1 = line.indexOf(QLatin1Char(' ')); + int space2 = space1 >=0 ? line.indexOf(QLatin1Char(' '),space1+1) : -1; + QString mapversions = line.mid(space1+1,space2<0?line.length()-space1-1:space2-space1-1); + int dot = mapversions.indexOf(QLatin1Char('.')); + int dash = mapversions.indexOf(QLatin1Char('-')); + int mapvmaj = mapversions.left(dot).toInt(); + if (mapvmaj==vmaj) { + int mapvmin_from = (dash <= 0 ? mapversions.mid(dot+1) : mapversions.mid(dot+1,dash-dot-1)).toInt(); + int mapvmin_to = dash <= 0 ? mapvmin_from : mapversions.mid(dash+1).toInt(); + if (vmin >= mapvmin_from && vmin <= mapvmin_to) { + QStringRef mapfile = space2<0 ? QStringRef() : line.midRef(space2+1,line.length()-space2-1); + if (url_return) + *url_return = url.resolved(mapfile.toString()); + return true; } } - } while (!qmldir.atEnd()); + } } } else { // XXX search non-files too! (eg. zip files, see QT-524) @@ -1106,7 +1119,7 @@ public: delete s; } - bool add(const QUrl& base, const QString& uri, const QString& prefix, int vmaj, int vmin, QmlScriptParser::Import::Type importType, const QStringList& importPath) + bool add(const QUrl& base, const QString& qmldircontent, const QString& uri, const QString& prefix, int vmaj, int vmin, QmlScriptParser::Import::Type importType, const QStringList& importPath) { QmlEnginePrivate::ImportedNamespace *s; if (prefix.isEmpty()) { @@ -1142,6 +1155,7 @@ public: s->minversions.prepend(vmin); s->isLibrary.prepend(importType == QmlScriptParser::Import::Library); s->isBuiltin.prepend(isbuiltin); + s->qmlDirContent.prepend(qmldircontent); return true; } @@ -1366,9 +1380,9 @@ QString QmlEngine::offlineStoragePath() const The base URL must already have been set with Import::setBaseUrl(). */ -bool QmlEnginePrivate::addToImport(Imports* imports, const QString& uri, const QString& prefix, int vmaj, int vmin, QmlScriptParser::Import::Type importType) const +bool QmlEnginePrivate::addToImport(Imports* imports, const QString& qmldircontent, const QString& uri, const QString& prefix, int vmaj, int vmin, QmlScriptParser::Import::Type importType) const { - bool ok = imports->d->add(imports->d->base,uri,prefix,vmaj,vmin,importType,fileImportPath); + bool ok = imports->d->add(imports->d->base,qmldircontent,uri,prefix,vmaj,vmin,importType,fileImportPath); if (qmlImportTrace()) qDebug() << "QmlEngine::addToImport(" << imports << uri << prefix << vmaj << "." << vmin << (importType==QmlScriptParser::Import::Library? "Library" : "File") << ": " << ok; return ok; diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index a74854d..69b121e 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -97,6 +97,7 @@ class QmlTypeNameScriptClass; class QmlTypeNameCache; class QmlComponentAttached; class QmlListScriptClass; +class QmlCleanup; class QmlEnginePrivate : public QObjectPrivate { @@ -139,6 +140,9 @@ public: // Used by SQL database API QScriptClass *sqlQueryClass; + // Registered cleanup handlers + QmlCleanup *cleanup; + struct QmlScriptEngine : public QScriptEngine { QmlScriptEngine(QmlEnginePrivate *priv) @@ -223,7 +227,7 @@ public: QmlImportsPrivate *d; }; - bool addToImport(Imports*, const QString& uri, const QString& prefix, int vmaj, int vmin, QmlScriptParser::Import::Type importType) const; + bool addToImport(Imports*, const QString& qmlDirContent,const QString& uri, const QString& prefix, int vmaj, int vmin, QmlScriptParser::Import::Type importType) const; bool resolveType(const Imports&, const QByteArray& type, QmlType** type_return, QUrl* url_return, int *version_major, int *version_minor, diff --git a/src/declarative/qml/qmlenginedebug.cpp b/src/declarative/qml/qmlenginedebug.cpp index 7178e6c..664ca3f 100644 --- a/src/declarative/qml/qmlenginedebug.cpp +++ b/src/declarative/qml/qmlenginedebug.cpp @@ -104,7 +104,7 @@ QmlEngineDebugServer::propertyData(QObject *obj, int propIdx) rv.type = QmlObjectProperty::Unknown; rv.valueTypeName = QString::fromUtf8(prop.typeName()); - rv.name = prop.name(); + rv.name = QString::fromUtf8(prop.name()); rv.hasNotifySignal = prop.hasNotifySignal(); QmlAbstractBinding *binding = QmlMetaProperty(obj, rv.name).binding(); if (binding) @@ -229,7 +229,7 @@ QmlEngineDebugServer::objectData(QObject *object) } rv.objectName = object->objectName(); - rv.objectType = object->metaObject()->className(); + rv.objectType = QString::fromUtf8(object->metaObject()->className()); rv.objectId = QmlDebugService::idForObject(object); rv.contextId = QmlDebugService::idForObject(qmlContext(object)); diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp index 3f531a3..3b89a23 100644 --- a/src/declarative/qml/qmlexpression.cpp +++ b/src/declarative/qml/qmlexpression.cpp @@ -46,6 +46,7 @@ #include "qmlrewrite_p.h" #include "QtCore/qdebug.h" #include "qmlcompiler_p.h" +#include <QtScript/qscriptprogram.h> Q_DECLARE_METATYPE(QList<QObject *>); @@ -109,17 +110,17 @@ void QmlExpressionPrivate::init(QmlContext *ctxt, void *expr, QmlRefCount *rc, QmlEngine *engine = ctxt->engine(); QmlEnginePrivate *ep = QmlEnginePrivate::get(engine); QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine); -#if !defined(Q_OS_SYMBIAN) && !defined(Q_OS_WIN32) //XXX Why doesn't this work? +#if !defined(Q_OS_SYMBIAN) //XXX Why doesn't this work? if (!dd->programs.at(progIdx)) { dd->programs[progIdx] = - new QScriptProgram(scriptEngine->compile(data->expression, data->fileName, data->line)); + new QScriptProgram(data->expression, data->fileName, data->line); } #endif QScriptContext *scriptContext = scriptEngine->pushCleanContext(); scriptContext->pushScope(ep->contextClass->newContext(ctxt, me)); -#if !defined(Q_OS_SYMBIAN) && !defined(Q_OS_WIN32) +#if !defined(Q_OS_SYMBIAN) data->expressionFunction = scriptEngine->evaluate(*dd->programs[progIdx]); #else data->expressionFunction = scriptEngine->evaluate(data->expression); diff --git a/src/declarative/qml/qmlglobalscriptclass.cpp b/src/declarative/qml/qmlglobalscriptclass.cpp index 0ade5ee..91187c7 100644 --- a/src/declarative/qml/qmlglobalscriptclass.cpp +++ b/src/declarative/qml/qmlglobalscriptclass.cpp @@ -70,6 +70,10 @@ QmlGlobalScriptClass::queryProperty(const QScriptValue &object, const QScriptString &name, QueryFlags flags, uint *id) { + Q_UNUSED(object) + Q_UNUSED(name) + Q_UNUSED(flags) + Q_UNUSED(id) return HandlesReadAccess | HandlesWriteAccess; } @@ -78,6 +82,9 @@ QmlGlobalScriptClass::property(const QScriptValue &object, const QScriptString &name, uint id) { + Q_UNUSED(object) + Q_UNUSED(name) + Q_UNUSED(id) return engine()->undefinedValue(); } @@ -85,6 +92,8 @@ void QmlGlobalScriptClass::setProperty(QScriptValue &object, const QScriptString &name, uint id, const QScriptValue &value) { + Q_UNUSED(object) + Q_UNUSED(value) QString error = QLatin1String("Invalid write to global property \"") + name.toString() + QLatin1String("\""); engine()->currentContext()->throwError(error); diff --git a/src/declarative/qml/qmlintegercache.cpp b/src/declarative/qml/qmlintegercache.cpp index 89a18a1..06955c7 100644 --- a/src/declarative/qml/qmlintegercache.cpp +++ b/src/declarative/qml/qmlintegercache.cpp @@ -46,13 +46,21 @@ QT_BEGIN_NAMESPACE QmlIntegerCache::QmlIntegerCache(QmlEngine *e) -: engine(e) +: QmlCleanup(e), engine(e) { } QmlIntegerCache::~QmlIntegerCache() { + clear(); +} + +void QmlIntegerCache::clear() +{ qDeleteAll(stringCache); + stringCache.clear(); + identifierCache.clear(); + engine = 0; } void QmlIntegerCache::add(const QString &id, int value) diff --git a/src/declarative/qml/qmlintegercache_p.h b/src/declarative/qml/qmlintegercache_p.h index e11e0be..6e9fadd 100644 --- a/src/declarative/qml/qmlintegercache_p.h +++ b/src/declarative/qml/qmlintegercache_p.h @@ -55,13 +55,14 @@ #include <private/qmlrefcount_p.h> #include <private/qscriptdeclarativeclass_p.h> +#include <private/qmlcleanup_p.h> #include <QtCore/qhash.h> QT_BEGIN_NAMESPACE class QmlType; class QmlEngine; -class QmlIntegerCache : public QmlRefCount +class QmlIntegerCache : public QmlRefCount, public QmlCleanup { public: QmlIntegerCache(QmlEngine *); @@ -73,6 +74,10 @@ public: inline int value(const QScriptDeclarativeClass::Identifier &id) const; static QmlIntegerCache *createForEnums(QmlType *, QmlEngine *); + +protected: + virtual void clear(); + private: struct Data : public QScriptDeclarativeClass::PersistentIdentifier { Data(const QScriptDeclarativeClass::PersistentIdentifier &i, int v) diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp index baef71f..edec988 100644 --- a/src/declarative/qml/qmlmetaproperty.cpp +++ b/src/declarative/qml/qmlmetaproperty.cpp @@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE /*! \class QmlMetaProperty \brief The QmlMetaProperty class abstracts accessing QML properties. + \internal */ /*! diff --git a/src/declarative/qml/qmlobjectscriptclass.cpp b/src/declarative/qml/qmlobjectscriptclass.cpp index a6edd3b..eac354d 100644 --- a/src/declarative/qml/qmlobjectscriptclass.cpp +++ b/src/declarative/qml/qmlobjectscriptclass.cpp @@ -134,7 +134,6 @@ QmlObjectScriptClass::queryProperty(QObject *obj, const Identifier &name, return 0; QmlEnginePrivate *enginePrivate = QmlEnginePrivate::get(engine); - QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine); QmlPropertyCache *cache = 0; QmlDeclarativeData *ddata = QmlDeclarativeData::get(obj); diff --git a/src/declarative/qml/qmlpropertycache.cpp b/src/declarative/qml/qmlpropertycache.cpp index e00126f..4c24cdd 100644 --- a/src/declarative/qml/qmlpropertycache.cpp +++ b/src/declarative/qml/qmlpropertycache.cpp @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE void QmlPropertyCache::Data::load(const QMetaProperty &p) { propType = p.userType(); - if (propType == QVariant::LastType) + if (QVariant::Type(propType) == QVariant::LastType) propType = qMetaTypeId<QVariant>(); coreIndex = p.propertyIndex(); notifyIndex = p.notifySignalIndex(); @@ -86,12 +86,18 @@ void QmlPropertyCache::Data::load(const QMetaMethod &m) } -QmlPropertyCache::QmlPropertyCache() +QmlPropertyCache::QmlPropertyCache(QmlEngine *engine) +: QmlCleanup(engine) { } QmlPropertyCache::~QmlPropertyCache() { + clear(); +} + +void QmlPropertyCache::clear() +{ for (int ii = 0; ii < indexCache.count(); ++ii) indexCache.at(ii)->release(); @@ -102,6 +108,10 @@ QmlPropertyCache::~QmlPropertyCache() for (IdentifierCache::ConstIterator iter = identifierCache.begin(); iter != identifierCache.end(); ++iter) (*iter)->release(); + + indexCache.clear(); + stringCache.clear(); + identifierCache.clear(); } QmlPropertyCache::Data QmlPropertyCache::create(const QMetaObject *metaObject, @@ -141,7 +151,7 @@ QmlPropertyCache *QmlPropertyCache::create(QmlEngine *engine, const QMetaObject Q_ASSERT(engine); Q_ASSERT(metaObject); - QmlPropertyCache *cache = new QmlPropertyCache; + QmlPropertyCache *cache = new QmlPropertyCache(engine); QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(engine); diff --git a/src/declarative/qml/qmlpropertycache_p.h b/src/declarative/qml/qmlpropertycache_p.h index 91b0c53..6c3142a 100644 --- a/src/declarative/qml/qmlpropertycache_p.h +++ b/src/declarative/qml/qmlpropertycache_p.h @@ -55,16 +55,17 @@ #include <private/qmlrefcount_p.h> #include <private/qscriptdeclarativeclass_p.h> +#include <private/qmlcleanup_p.h> #include <QtCore/qvector.h> QT_BEGIN_NAMESPACE class QmlEngine; class QMetaProperty; -class QmlPropertyCache : public QmlRefCount +class QmlPropertyCache : public QmlRefCount, public QmlCleanup { public: - QmlPropertyCache(); + QmlPropertyCache(QmlEngine *); virtual ~QmlPropertyCache(); struct Data { @@ -112,6 +113,9 @@ public: Data *property(const QString &) const; Data *property(int) const; +protected: + virtual void clear(); + private: struct RData : public Data, public QmlRefCount { QScriptDeclarativeClass::PersistentIdentifier identifier; diff --git a/src/declarative/qml/qmlpropertyvalueinterceptor.cpp b/src/declarative/qml/qmlpropertyvalueinterceptor.cpp index 86905e6..9a9aba8 100644 --- a/src/declarative/qml/qmlpropertyvalueinterceptor.cpp +++ b/src/declarative/qml/qmlpropertyvalueinterceptor.cpp @@ -47,6 +47,7 @@ QT_BEGIN_NAMESPACE /*! \class QmlPropertyValueInterceptor \brief The QmlPropertyValueInterceptor class is inherited by property interceptors such as Behavior. + \internal This class intercepts property writes, allowing for custom handling. For example, Behavior uses this interception to provide a default animation for all changes to a property's value. diff --git a/src/declarative/qml/qmlpropertyvaluesource.cpp b/src/declarative/qml/qmlpropertyvaluesource.cpp index 529ce37..3317289 100644 --- a/src/declarative/qml/qmlpropertyvaluesource.cpp +++ b/src/declarative/qml/qmlpropertyvaluesource.cpp @@ -47,6 +47,7 @@ QT_BEGIN_NAMESPACE /*! \class QmlPropertyValueSource \brief The QmlPropertyValueSource class is inherited by property value sources such as animations and bindings. + \internal */ /*! diff --git a/src/declarative/qml/qmlrewrite.cpp b/src/declarative/qml/qmlrewrite.cpp index 43b2529..7cf8888 100644 --- a/src/declarative/qml/qmlrewrite.cpp +++ b/src/declarative/qml/qmlrewrite.cpp @@ -120,7 +120,7 @@ bool RewriteBinding::visit(AST::ExpressionStatement *ast) return false; } -bool RewriteBinding::visit(AST::DoWhileStatement *ast) +bool RewriteBinding::visit(AST::DoWhileStatement *) { ++_inLoop; return true; @@ -131,7 +131,7 @@ void RewriteBinding::endVisit(AST::DoWhileStatement *) --_inLoop; } -bool RewriteBinding::visit(AST::WhileStatement *ast) +bool RewriteBinding::visit(AST::WhileStatement *) { ++_inLoop; return true; @@ -142,7 +142,7 @@ void RewriteBinding::endVisit(AST::WhileStatement *) --_inLoop; } -bool RewriteBinding::visit(AST::ForStatement *ast) +bool RewriteBinding::visit(AST::ForStatement *) { ++_inLoop; return true; @@ -153,7 +153,7 @@ void RewriteBinding::endVisit(AST::ForStatement *) --_inLoop; } -bool RewriteBinding::visit(AST::LocalForStatement *ast) +bool RewriteBinding::visit(AST::LocalForStatement *) { ++_inLoop; return true; @@ -164,7 +164,7 @@ void RewriteBinding::endVisit(AST::LocalForStatement *) --_inLoop; } -bool RewriteBinding::visit(AST::ForEachStatement *ast) +bool RewriteBinding::visit(AST::ForEachStatement *) { ++_inLoop; return true; @@ -175,7 +175,7 @@ void RewriteBinding::endVisit(AST::ForEachStatement *) --_inLoop; } -bool RewriteBinding::visit(AST::LocalForEachStatement *ast) +bool RewriteBinding::visit(AST::LocalForEachStatement *) { ++_inLoop; return true; diff --git a/src/declarative/qml/qmltypenamecache.cpp b/src/declarative/qml/qmltypenamecache.cpp index aa1c938..d706c63 100644 --- a/src/declarative/qml/qmltypenamecache.cpp +++ b/src/declarative/qml/qmltypenamecache.cpp @@ -45,13 +45,21 @@ QT_BEGIN_NAMESPACE QmlTypeNameCache::QmlTypeNameCache(QmlEngine *e) -: engine(e) +: QmlCleanup(e), engine(e) { } QmlTypeNameCache::~QmlTypeNameCache() { + clear(); +} + +void QmlTypeNameCache::clear() +{ qDeleteAll(stringCache); + stringCache.clear(); + identifierCache.clear(); + engine = 0; } void QmlTypeNameCache::add(const QString &name, QmlType *type) diff --git a/src/declarative/qml/qmltypenamecache_p.h b/src/declarative/qml/qmltypenamecache_p.h index f11fe68..ec1e79d 100644 --- a/src/declarative/qml/qmltypenamecache_p.h +++ b/src/declarative/qml/qmltypenamecache_p.h @@ -55,12 +55,13 @@ #include <private/qmlrefcount_p.h> #include <private/qscriptdeclarativeclass_p.h> +#include <private/qmlcleanup_p.h> QT_BEGIN_NAMESPACE class QmlType; class QmlEngine; -class QmlTypeNameCache : public QmlRefCount +class QmlTypeNameCache : public QmlRefCount, public QmlCleanup { public: QmlTypeNameCache(QmlEngine *); @@ -79,6 +80,9 @@ public: Data *data(const QString &) const; inline Data *data(const QScriptDeclarativeClass::Identifier &id) const; +protected: + virtual void clear(); + private: struct RData : public Data { QScriptDeclarativeClass::PersistentIdentifier identifier; diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp index 802a78f..b986b60 100644 --- a/src/declarative/qml/qmlvme.cpp +++ b/src/declarative/qml/qmlvme.cpp @@ -225,7 +225,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, { QObject *target = stack.top(); // ctxt->setContextProperty(primitives.at(instr.setId.value), target); - cp->setIdProperty(primitives.at(instr.setId.value), instr.setId.index, target); + cp->setIdProperty(instr.setId.index, target); } break; diff --git a/src/declarative/qml/qmlvmemetaobject.cpp b/src/declarative/qml/qmlvmemetaobject.cpp index a627bf9..3e1d931 100644 --- a/src/declarative/qml/qmlvmemetaobject.cpp +++ b/src/declarative/qml/qmlvmemetaobject.cpp @@ -278,7 +278,7 @@ int QmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) QMetaMethod m = method(_id); QList<QByteArray> names = m.parameterNames(); for (int ii = 0; ii < names.count(); ++ii) - newCtxt.setContextProperty(names.at(ii), *(QVariant *)a[ii + 1]); + newCtxt.setContextProperty(QString::fromLatin1(names.at(ii)), *(QVariant *)a[ii + 1]); QmlExpression expr(&newCtxt, code, object); expr.setTrackChange(false); expr.value(); diff --git a/src/declarative/qml/qmlxmlhttprequest.cpp b/src/declarative/qml/qmlxmlhttprequest.cpp index 5117a00..eb7235b 100644 --- a/src/declarative/qml/qmlxmlhttprequest.cpp +++ b/src/declarative/qml/qmlxmlhttprequest.cpp @@ -1102,6 +1102,7 @@ void QmlXMLHttpRequest::abort() void QmlXMLHttpRequest::downloadProgress(qint64 bytes) { + Q_UNUSED(bytes) m_status = m_network->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); m_statusText = @@ -1124,6 +1125,7 @@ void QmlXMLHttpRequest::downloadProgress(qint64 bytes) void QmlXMLHttpRequest::error(QNetworkReply::NetworkError error) { + Q_UNUSED(error) m_status = m_network->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); m_statusText = @@ -1315,6 +1317,7 @@ static QScriptValue qmlxmlhttprequest_abort(QScriptContext *context, QScriptEngi static QScriptValue qmlxmlhttprequest_getResponseHeader(QScriptContext *context, QScriptEngine *engine) { + Q_UNUSED(engine) QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject()); if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object")); @@ -1333,6 +1336,7 @@ static QScriptValue qmlxmlhttprequest_getResponseHeader(QScriptContext *context, static QScriptValue qmlxmlhttprequest_getAllResponseHeaders(QScriptContext *context, QScriptEngine *engine) { + Q_UNUSED(engine) QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject()); if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object")); @@ -1350,6 +1354,7 @@ static QScriptValue qmlxmlhttprequest_getAllResponseHeaders(QScriptContext *cont // XMLHttpRequest properties static QScriptValue qmlxmlhttprequest_readyState(QScriptContext *context, QScriptEngine *engine) { + Q_UNUSED(engine) QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject()); if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object")); @@ -1358,6 +1363,7 @@ static QScriptValue qmlxmlhttprequest_readyState(QScriptContext *context, QScrip static QScriptValue qmlxmlhttprequest_status(QScriptContext *context, QScriptEngine *engine) { + Q_UNUSED(engine) QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject()); if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object")); @@ -1373,6 +1379,7 @@ static QScriptValue qmlxmlhttprequest_status(QScriptContext *context, QScriptEng static QScriptValue qmlxmlhttprequest_statusText(QScriptContext *context, QScriptEngine *engine) { + Q_UNUSED(engine) QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject()); if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object")); @@ -1388,6 +1395,7 @@ static QScriptValue qmlxmlhttprequest_statusText(QScriptContext *context, QScrip static QScriptValue qmlxmlhttprequest_responseText(QScriptContext *context, QScriptEngine *engine) { + Q_UNUSED(engine) QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject()); if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object")); @@ -1412,6 +1420,7 @@ static QScriptValue qmlxmlhttprequest_responseXML(QScriptContext *context, QScri static QScriptValue qmlxmlhttprequest_onreadystatechange(QScriptContext *context, QScriptEngine *engine) { + Q_UNUSED(engine) QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject()); if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object")); diff --git a/src/declarative/util/qmlanimation.h b/src/declarative/util/qmlanimation.h index 7898980..f4f9f38 100644 --- a/src/declarative/util/qmlanimation.h +++ b/src/declarative/util/qmlanimation.h @@ -65,6 +65,7 @@ class Q_AUTOTEST_EXPORT QmlAbstractAnimation : public QObject, public QmlPropert Q_DECLARE_PRIVATE(QmlAbstractAnimation) Q_INTERFACES(QmlParserStatus) + Q_INTERFACES(QmlPropertyValueSource) Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged) Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged) Q_PROPERTY(bool alwaysRunToEnd READ alwaysRunToEnd WRITE setAlwaysRunToEnd NOTIFY alwaysRunToEndChanged()) diff --git a/src/declarative/util/qmllistaccessor.cpp b/src/declarative/util/qmllistaccessor.cpp index 578646b..3e4cb64 100644 --- a/src/declarative/util/qmllistaccessor.cpp +++ b/src/declarative/util/qmllistaccessor.cpp @@ -73,7 +73,7 @@ void QmlListAccessor::setList(const QVariant &v, QmlEngine *engine) m_type = Invalid; } else if (d.type() == QVariant::StringList) { m_type = StringList; - } else if (d.type() == QMetaType::QVariantList) { + } else if (d.type() == (QVariant::Type)QMetaType::QVariantList) { m_type = VariantList; } else if (d.canConvert(QVariant::Int)) { m_type = Integer; @@ -136,7 +136,7 @@ QVariant QmlListAccessor::at(int idx) const QmlPrivate::ListInterface *li = *(QmlPrivate::ListInterface **)d.constData(); void *ptr[1]; li->at(idx, ptr); - return QmlMetaType::fromObject((QObject*)ptr[0], li->type()); //XXX only handles QObject-derived types + return QVariant::fromValue((QObject*)ptr[0]); } case QList: return QmlMetaType::listAt(d, idx); diff --git a/src/declarative/util/qmlpropertychanges.cpp b/src/declarative/util/qmlpropertychanges.cpp index a112245..7e1f15c 100644 --- a/src/declarative/util/qmlpropertychanges.cpp +++ b/src/declarative/util/qmlpropertychanges.cpp @@ -93,7 +93,7 @@ public: QmlMetaProperty property; QmlExpression *expression; QmlExpression *reverseExpression; - QmlExpression *ownedExpression; + QGuard<QmlExpression> ownedExpression; virtual void execute() { ownedExpression = property.setSignalExpression(expression); @@ -272,7 +272,6 @@ QmlPropertyChanges::~QmlPropertyChanges() delete d->expressions.at(ii).second; for(int ii = 0; ii < d->signalReplacements.count(); ++ii) delete d->signalReplacements.at(ii); - } QObject *QmlPropertyChanges::object() const diff --git a/src/declarative/util/qmlview.cpp b/src/declarative/util/qmlview.cpp index 14f8279..f91d0db 100644 --- a/src/declarative/util/qmlview.cpp +++ b/src/declarative/util/qmlview.cpp @@ -360,6 +360,8 @@ void QmlView::continueExecute() emit sceneResized(sz); resize(sz); } + updateGeometry(); + emit initialSize(d->initialSize); } else if (QWidget *wid = qobject_cast<QWidget *>(obj)) { window()->setAttribute(Qt::WA_OpaquePaintEvent, false); window()->setAttribute(Qt::WA_NoSystemBackground, false); @@ -374,6 +376,7 @@ void QmlView::continueExecute() } layout()->addWidget(wid); emit sceneResized(wid->size()); + emit initialSize(wid->size()); } } } @@ -382,6 +385,10 @@ void QmlView::continueExecute() This signal is emitted when the view is resized to \a size. */ +/*! \fn void QmlView::initialSize(QSize size) + This signal is emitted when the initial size of the root item is known. + */ + /*! \fn void QmlView::errors(const QList<QmlError> &errors) This signal is emitted when the qml loaded contains \a errors. */ @@ -425,7 +432,10 @@ void QmlView::timerEvent(QTimerEvent* e) automatically resize the root item. Regardless of this property, the sizeHint of the view - is the initial size of the root item. + is the initial size of the root item. Note though that + since QML may load dynamically, that size may change. + + \sa initialSize() */ void QmlView::setContentResizable(bool on) diff --git a/src/declarative/util/qmlview.h b/src/declarative/util/qmlview.h index faf2564..822827a 100644 --- a/src/declarative/util/qmlview.h +++ b/src/declarative/util/qmlview.h @@ -88,6 +88,7 @@ public: QSize sizeHint() const; Q_SIGNALS: + void initialSize(QSize size); void sceneResized(QSize size); void errors(const QList<QmlError> &error); |