diff options
author | Roberto Raggi <roberto.raggi@nokia.com> | 2010-02-23 08:44:01 (GMT) |
---|---|---|
committer | Roberto Raggi <roberto.raggi@nokia.com> | 2010-02-23 08:44:01 (GMT) |
commit | ab3a625e1bc03481f740a32cdbe8c4559cf7cb1e (patch) | |
tree | 01adb2ad207b9a2980492a24cb820925f7e48635 /src/declarative | |
parent | 20fc9f2e264f34dd8580949ddbe5511b78ab0ac4 (diff) | |
parent | 48161233af2a6071bc0ba99e546da98f705b8281 (diff) | |
download | Qt-ab3a625e1bc03481f740a32cdbe8c4559cf7cb1e.zip Qt-ab3a625e1bc03481f740a32cdbe8c4559cf7cb1e.tar.gz Qt-ab3a625e1bc03481f740a32cdbe8c4559cf7cb1e.tar.bz2 |
Merge remote branch 'origin/master' into qtruntime
Diffstat (limited to 'src/declarative')
44 files changed, 964 insertions, 488 deletions
diff --git a/src/declarative/graphicsitems/qmlgraphicsparticles.cpp b/src/declarative/graphicsitems/qmlgraphicsparticles.cpp index 08fce74..e23f6f0 100644 --- a/src/declarative/graphicsitems/qmlgraphicsparticles.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsparticles.cpp @@ -188,13 +188,13 @@ void QmlGraphicsParticleMotionLinear::advance(QmlGraphicsParticle &p, int interv */ /*! - \qmlproperty int ParticleMotionGravity::xattractor - \qmlproperty int ParticleMotionGravity::yattractor + \qmlproperty qreal ParticleMotionGravity::xattractor + \qmlproperty qreal ParticleMotionGravity::yattractor These properties hold the x and y coordinates of the point attracting the particles. */ /*! - \qmlproperty int ParticleMotionGravity::acceleration + \qmlproperty qreal ParticleMotionGravity::acceleration This property holds the acceleration to apply to the particles. */ @@ -213,6 +213,31 @@ void QmlGraphicsParticleMotionLinear::advance(QmlGraphicsParticle &p, int interv \brief the acceleration to apply to the particles. */ +void QmlGraphicsParticleMotionGravity::setXAttractor(qreal x) +{ + if (qFuzzyCompare(x, _xAttr)) + return; + _xAttr = x; + emit xattractorChanged(); +} + +void QmlGraphicsParticleMotionGravity::setYAttractor(qreal y) +{ + if (qFuzzyCompare(y, _yAttr)) + return; + _yAttr = y; + emit yattractorChanged(); +} + +void QmlGraphicsParticleMotionGravity::setAcceleration(qreal accel) +{ + qreal scaledAccel = accel/1000000.0; + if (qFuzzyCompare(scaledAccel, _accel)) + return; + _accel = scaledAccel; + emit accelerationChanged(); +} + void QmlGraphicsParticleMotionGravity::advance(QmlGraphicsParticle &p, int interval) { qreal xdiff = p.x - _xAttr; @@ -276,14 +301,14 @@ Rectangle { */ /*! - \qmlproperty int QmlGraphicsParticleMotionWander::xvariance - \qmlproperty int QmlGraphicsParticleMotionWander::yvariance + \qmlproperty qreal QmlGraphicsParticleMotionWander::xvariance + \qmlproperty qreal QmlGraphicsParticleMotionWander::yvariance These properties set the amount to wander in the x and y directions. */ /*! - \qmlproperty int QmlGraphicsParticleMotionWander::pace + \qmlproperty qreal QmlGraphicsParticleMotionWander::pace This property holds how quickly the paricles will move from side to side. */ @@ -335,6 +360,33 @@ void QmlGraphicsParticleMotionWander::destroy(QmlGraphicsParticle &p) delete (Data*)p.data; } +void QmlGraphicsParticleMotionWander::setXVariance(qreal var) +{ + qreal scaledVar = var / 1000.0; + if (qFuzzyCompare(scaledVar, _xvariance)) + return; + _xvariance = scaledVar; + emit xvarianceChanged(); +} + +void QmlGraphicsParticleMotionWander::setYVariance(qreal var) +{ + qreal scaledVar = var / 1000.0; + if (qFuzzyCompare(scaledVar, _yvariance)) + return; + _yvariance = scaledVar; + emit yvarianceChanged(); +} + +void QmlGraphicsParticleMotionWander::setPace(qreal pace) +{ + qreal scaledPace = pace / 1000.0; + if (qFuzzyCompare(scaledPace, _pace)) + return; + _pace = scaledPace; + emit paceChanged(); +} + //--------------------------------------------------------------------------- class QmlGraphicsParticlesPainter : public QmlGraphicsItem { @@ -1125,7 +1177,10 @@ QmlGraphicsParticleMotion *QmlGraphicsParticles::motion() const void QmlGraphicsParticles::setMotion(QmlGraphicsParticleMotion *motion) { Q_D(QmlGraphicsParticles); + if (motion == d->motion) + return; d->motion = motion; + emit motionChanged(); } /*! diff --git a/src/declarative/graphicsitems/qmlgraphicsparticles_p.h b/src/declarative/graphicsitems/qmlgraphicsparticles_p.h index 7f0f9cd..8e66335 100644 --- a/src/declarative/graphicsitems/qmlgraphicsparticles_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsparticles_p.h @@ -77,27 +77,32 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsParticleMotionGravity : public QmlGraphics { Q_OBJECT - Q_PROPERTY(int xattractor READ xAttractor WRITE setXAttractor) - Q_PROPERTY(int yattractor READ yAttractor WRITE setYAttractor) - Q_PROPERTY(int acceleration READ acceleration WRITE setAcceleration) + Q_PROPERTY(qreal xattractor READ xAttractor WRITE setXAttractor NOTIFY xattractorChanged) + Q_PROPERTY(qreal yattractor READ yAttractor WRITE setYAttractor NOTIFY yattractorChanged) + Q_PROPERTY(qreal acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged) public: QmlGraphicsParticleMotionGravity(QObject *parent=0) - : QmlGraphicsParticleMotion(parent), _xAttr(0), _yAttr(0), _accel(0.00005) {} + : QmlGraphicsParticleMotion(parent), _xAttr(0.0), _yAttr(0.0), _accel(0.00005) {} - int xAttractor() const { return _xAttr; } - void setXAttractor(int x) { _xAttr = x; } + qreal xAttractor() const { return _xAttr; } + void setXAttractor(qreal x); - int yAttractor() const { return _yAttr; } - void setYAttractor(int y) { _yAttr = y; } + qreal yAttractor() const { return _yAttr; } + void setYAttractor(qreal y); - int acceleration() const { return int(_accel * 1000000); } - void setAcceleration(int accel) { _accel = qreal(accel)/1000000.0; } + qreal acceleration() const { return _accel * 1000000; } + void setAcceleration(qreal accel); virtual void advance(QmlGraphicsParticle &, int interval); +Q_SIGNALS: + void xattractorChanged(); + void yattractorChanged(); + void accelerationChanged(); + private: - int _xAttr; - int _yAttr; + qreal _xAttr; + qreal _yAttr; qreal _accel; }; @@ -121,18 +126,23 @@ public: qreal y_var; }; - Q_PROPERTY(int xvariance READ xVariance WRITE setXVariance) - int xVariance() const { return int(_xvariance * 1000); } - void setXVariance(int var) { _xvariance = var / 1000.0; } + Q_PROPERTY(qreal xvariance READ xVariance WRITE setXVariance NOTIFY xvarianceChanged) + qreal xVariance() const { return _xvariance * 1000.0; } + void setXVariance(qreal var); - Q_PROPERTY(int yvariance READ yVariance WRITE setYVariance) - int yVariance() const { return int(_yvariance * 1000); } - void setYVariance(int var) { _yvariance = var / 1000.0; } + Q_PROPERTY(qreal yvariance READ yVariance WRITE setYVariance NOTIFY yvarianceChanged) + qreal yVariance() const { return _yvariance * 1000.0; } + void setYVariance(qreal var); - Q_PROPERTY(int pace READ pace WRITE setPace) - int pace() const { return int(_pace * 1000); } - void setPace(int pace) { _pace = pace / 1000.0; } + Q_PROPERTY(qreal pace READ pace WRITE setPace NOTIFY paceChanged) + qreal pace() const { return _pace * 1000.0; } + void setPace(qreal pace); +Q_SIGNALS: + void xvarianceChanged(); + void yvarianceChanged(); + void paceChanged(); + private: QmlGraphicsParticles *particles; qreal _xvariance; @@ -157,7 +167,7 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsParticles : public QmlGraphicsItem Q_PROPERTY(qreal angleDeviation READ angleDeviation WRITE setAngleDeviation NOTIFY angleDeviationChanged) Q_PROPERTY(qreal velocity READ velocity WRITE setVelocity NOTIFY velocityChanged) Q_PROPERTY(qreal velocityDeviation READ velocityDeviation WRITE setVelocityDeviation NOTIFY velocityDeviationChanged) - Q_PROPERTY(QmlGraphicsParticleMotion *motion READ motion WRITE setMotion) + Q_PROPERTY(QmlGraphicsParticleMotion *motion READ motion WRITE setMotion NOTIFY motionChanged) Q_CLASSINFO("DefaultProperty", "motion") public: @@ -225,6 +235,7 @@ Q_SIGNALS: void velocityChanged(); void velocityDeviationChanged(); void emittingChanged(); + void motionChanged(); private Q_SLOTS: void imageLoaded(); diff --git a/src/declarative/graphicsitems/qmlgraphicspositioners.cpp b/src/declarative/graphicsitems/qmlgraphicspositioners.cpp index 8adf239..805c912 100644 --- a/src/declarative/graphicsitems/qmlgraphicspositioners.cpp +++ b/src/declarative/graphicsitems/qmlgraphicspositioners.cpp @@ -138,7 +138,10 @@ QmlTransition *QmlGraphicsBasePositioner::move() const void QmlGraphicsBasePositioner::setMove(QmlTransition *mt) { Q_D(QmlGraphicsBasePositioner); + if (mt == d->moveTransition) + return; d->moveTransition = mt; + emit moveChanged(); } QmlTransition *QmlGraphicsBasePositioner::add() const @@ -150,7 +153,11 @@ QmlTransition *QmlGraphicsBasePositioner::add() const void QmlGraphicsBasePositioner::setAdd(QmlTransition *add) { Q_D(QmlGraphicsBasePositioner); + if (add == d->addTransition) + return; + d->addTransition = add; + emit addChanged(); } void QmlGraphicsBasePositioner::componentComplete() @@ -362,7 +369,7 @@ Column { move: Transition { NumberAnimation { properties: "y" - ease: "easeOutBounce" + easing: "easeOutBounce" } } } @@ -647,6 +654,24 @@ QmlGraphicsGrid::QmlGraphicsGrid(QmlGraphicsItem *parent) : many rows some rows will be of zero width. */ +void QmlGraphicsGrid::setColumns(const int columns) +{ + if (columns == _columns) + return; + _columns = columns; + prePositioning(); + emit columnsChanged(); +} + +void QmlGraphicsGrid::setRows(const int rows) +{ + if (rows == _rows) + return; + _rows = rows; + prePositioning(); + emit rowsChanged(); +} + void QmlGraphicsGrid::doPositioning() { int c=_columns,r=_rows;//Actual number of rows/columns diff --git a/src/declarative/graphicsitems/qmlgraphicspositioners_p.h b/src/declarative/graphicsitems/qmlgraphicspositioners_p.h index 1fb687a..2f905e5 100644 --- a/src/declarative/graphicsitems/qmlgraphicspositioners_p.h +++ b/src/declarative/graphicsitems/qmlgraphicspositioners_p.h @@ -62,8 +62,8 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsBasePositioner : public QmlGraphicsItem Q_OBJECT Q_PROPERTY(int spacing READ spacing WRITE setSpacing NOTIFY spacingChanged) - Q_PROPERTY(QmlTransition *move READ move WRITE setMove) - Q_PROPERTY(QmlTransition *add READ add WRITE setAdd) + Q_PROPERTY(QmlTransition *move READ move WRITE setMove NOTIFY moveChanged) + Q_PROPERTY(QmlTransition *add READ add WRITE setAdd NOTIFY addChanged) public: enum PositionerType { None = 0x0, Horizontal = 0x1, Vertical = 0x2, Both = 0x3 }; QmlGraphicsBasePositioner(PositionerType, QmlGraphicsItem *parent); @@ -86,6 +86,8 @@ protected: Q_SIGNALS: void spacingChanged(); + void moveChanged(); + void addChanged(); protected Q_SLOTS: virtual void doPositioning()=0; @@ -134,16 +136,21 @@ private: class Q_DECLARATIVE_EXPORT QmlGraphicsGrid : public QmlGraphicsBasePositioner { Q_OBJECT - Q_PROPERTY(int rows READ rows WRITE setRows) - Q_PROPERTY(int columns READ columns WRITE setcolumns) + Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowChanged) + Q_PROPERTY(int columns READ columns WRITE setColumns NOTIFY columnsChanged) public: QmlGraphicsGrid(QmlGraphicsItem *parent=0); int rows() const {return _rows;} - void setRows(const int rows){_rows = rows;} + void setRows(const int rows); int columns() const {return _columns;} - void setcolumns(const int columns){_columns = columns;} + void setColumns(const int columns); + +Q_SIGNALS: + void rowsChanged(); + void columnsChanged(); + protected Q_SLOTS: virtual void doPositioning(); diff --git a/src/declarative/graphicsitems/qmlgraphicstext.cpp b/src/declarative/graphicsitems/qmlgraphicstext.cpp index ab2f9a3..409fa3a 100644 --- a/src/declarative/graphicsitems/qmlgraphicstext.cpp +++ b/src/declarative/graphicsitems/qmlgraphicstext.cpp @@ -554,6 +554,7 @@ void QmlGraphicsTextPrivate::updateSize() else doc->setTextWidth(doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug) dy -= (int)doc->size().height(); + cachedLayoutSize = doc->size().toSize(); } int yoff = 0; @@ -769,7 +770,7 @@ void QmlGraphicsText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidg { Q_D(QmlGraphicsText); - if (d->cache || d->richText || d->style != Normal) { + if (d->cache || d->style != Normal) { d->checkImgCache(); if (d->imgCache.isNull()) return; @@ -846,7 +847,15 @@ void QmlGraphicsText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidg p->save(); p->setClipRect(boundingRect(), Qt::IntersectClip); } - d->drawWrappedText(p, QPointF(0,y), false); + if (d->richText) { + QAbstractTextDocumentLayout::PaintContext context; + context.palette.setColor(QPalette::Text, d->color); + p->translate(0, y); + d->doc->documentLayout()->draw(p, context); + p->translate(0, -y); + } else { + d->drawWrappedText(p, QPointF(0,y), false); + } if (needClip) p->restore(); } diff --git a/src/declarative/graphicsitems/qmlgraphicstext_p_p.h b/src/declarative/graphicsitems/qmlgraphicstext_p_p.h index 46d2d0e..f67d57c 100644 --- a/src/declarative/graphicsitems/qmlgraphicstext_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicstext_p_p.h @@ -75,7 +75,7 @@ public: dirty(true), wrap(false), richText(false), singleline(false), cache(true), doc(0), format(QmlGraphicsText::AutoText) { -#ifdef QML_NO_TEXT_CACHE +#if defined(QML_NO_TEXT_CACHE) cache = false; #endif } diff --git a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp index b96f399..bf3df03 100644 --- a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp @@ -187,7 +187,6 @@ QVariant QmlGraphicsVisualItemModel::evaluate(int index, const QString &expressi QmlContext *ctxt = new QmlContext(ccontext); ctxt->addDefaultObject(d->children.at(index)); QmlExpression e(ctxt, expression, objectContext); - e.setTrackChange(false); QVariant value = e.value(); delete ctxt; return value; @@ -327,7 +326,7 @@ public: if (m_listModelInterface) return m_listModelInterface->count(); if (m_abstractItemModel) - return m_abstractItemModel->rowCount(); + return m_abstractItemModel->rowCount(m_root); if (m_listAccessor) return m_listAccessor->count(); return 0; @@ -348,6 +347,8 @@ public: QVariant m_modelVariant; QmlListAccessor *m_listAccessor; + + QModelIndex m_root; }; class QmlGraphicsVisualDataModelDataMetaObject : public QmlOpenMetaObject @@ -415,7 +416,7 @@ int QmlGraphicsVisualDataModelDataMetaObject::createProperty(const char *name, c if (model->m_listAccessor->type() == QmlListAccessor::ListProperty) { model->ensureRoles(); QObject *object = model->m_listAccessor->at(data->m_index).value<QObject*>(); - if (object && object->property(name).isValid()) + if (object && (object->property(name).isValid() || qstrcmp(name,"modelData")==0)) return QmlOpenMetaObject::createProperty(name, type); } } @@ -461,7 +462,7 @@ QVariant QmlGraphicsVisualDataModelDataMetaObject::initialValue(int propId) QHash<QByteArray,int>::const_iterator it = model->m_roleNames.find(propName); if (it != model->m_roleNames.end()) { roleToProp.insert(*it, propId); - QModelIndex index = model->m_abstractItemModel->index(data->m_index, 0); + QModelIndex index = model->m_abstractItemModel->index(data->m_index, 0, model->m_root); return model->m_abstractItemModel->data(index, *it); } } @@ -560,6 +561,39 @@ QmlGraphicsVisualDataModelData *QmlGraphicsVisualDataModelPrivate::data(QObject //--------------------------------------------------------------------------- +/*! + \qmlclass VisualDataModel QmlGraphicsVisualDataModel + \brief The VisualDataModel encapsulates a model and delegate + + A VisualDataModel encapsulates a model and the delegate that will + be instantiated for items in the model. + + It is usually not necessary to create a VisualDataModel directly, + since the QML views will create one internally. + + The example below illustrates using a VisualDataModel with a ListView. + + \code + VisualDataModel { + id: visualModel + model: myModel + delegate: Component { + Rectangle { + height: 25 + width: 100 + Text { text: "Name:" + name} + } + } + } + ListView { + width: 100 + height: 100 + anchors.fill: parent + model: visualModel + } + \endcode +*/ + QmlGraphicsVisualDataModel::QmlGraphicsVisualDataModel() : QmlGraphicsVisualModel(*(new QmlGraphicsVisualDataModelPrivate(0))) { @@ -579,6 +613,20 @@ QmlGraphicsVisualDataModel::~QmlGraphicsVisualDataModel() d->m_delegateDataType->release(); } +/*! + \qmlproperty model VisualDataModel::model + This property holds the model providing data for the VisualDataModel. + + The model provides a set of data that is used to create the items + for a view. For large or dynamic datasets the model is usually + provided by a C++ model object. The C++ model object must be a \l + {QAbstractItemModel} subclass or a simple list. + + Models can also be created directly in QML, using a \l{ListModel} or + \l{XmlListModel}. + + \sa {qmlmodels}{Data Models} +*/ QVariant QmlGraphicsVisualDataModel::model() const { Q_D(const QmlGraphicsVisualDataModel); @@ -682,6 +730,16 @@ void QmlGraphicsVisualDataModel::setModel(const QVariant &model) } } +/*! + \qmlproperty component VisualDataModel::delegate + + The delegate provides a template defining each item instantiated by a view. + The index is exposed as an accessible \c index property. Properties of the + model are also available depending upon the type of \l {qmlmodels}{Data Model}. + + Here is an example delegate: + \snippet doc/src/snippets/declarative/listview/listview.qml 0 +*/ QmlComponent *QmlGraphicsVisualDataModel::delegate() const { Q_D(const QmlGraphicsVisualDataModel); @@ -705,6 +763,104 @@ void QmlGraphicsVisualDataModel::setDelegate(QmlComponent *delegate) } } +/*! + \qmlproperty QModelIndex VisualDataModel::rootIndex + + QAbstractItemModel provides a heirachical tree of data, whereas + QML only operates on list data. rootIndex allows the children of + any node in a QAbstractItemModel to be provided by this model. + + This property only affects models of type QAbstractItemModel. + + \code + // main.cpp + Q_DECLARE_METATYPE(QModelIndex) + + class MyModel : public QDirModel + { + Q_OBJECT + public: + MyModel(QmlContext *ctxt) : QDirModel(), context(ctxt) { + QHash<int,QByteArray> roles = roleNames(); + roles.insert(FilePathRole, "path"); + setRoleNames(roles); + context->setContextProperty("myModel", this); + context->setContextProperty("myRoot", QVariant::fromValue(index(0,0,QModelIndex()))); + } + + Q_INVOKABLE void setRoot(const QString &path) { + QModelIndex root = index(path); + context->setContextProperty("myRoot", QVariant::fromValue(root)); + } + + QmlContext *context; + }; + + int main(int argc, char ** argv) + { + QApplication app(argc, argv); + + QmlView view; + + MyModel model(view.rootContext()); + + view.setSource(QUrl("qrc:view.qml")); + view.show(); + + return app.exec(); + } + + #include "main.moc" + \endcode + + \code + // view.qml + import Qt 4.6 + + ListView { + width: 200 + height: 200 + model: VisualDataModel { + model: myModel + rootIndex: myRoot + delegate: Component { + Rectangle { + height: 25; width: 100 + Text { text: path } + MouseRegion { + anchors.fill: parent; + onClicked: myModel.setRoot(path) + } + } + } + } + } + \endcode + +*/ +QModelIndex QmlGraphicsVisualDataModel::rootIndex() const +{ + Q_D(const QmlGraphicsVisualDataModel); + return d->m_root; +} + +void QmlGraphicsVisualDataModel::setRootIndex(const QModelIndex &root) +{ + Q_D(QmlGraphicsVisualDataModel); + if (d->m_root != root) { + int oldCount = d->modelCount(); + d->m_root = root; + int newCount = d->modelCount(); + if (d->m_delegate && oldCount) + emit itemsRemoved(0, oldCount); + if (d->m_delegate && newCount) + emit itemsInserted(0, newCount); + if (newCount != oldCount) + emit countChanged(); + emit rootIndexChanged(); + } +} + QString QmlGraphicsVisualDataModel::part() const { Q_D(const QmlGraphicsVisualDataModel); @@ -786,7 +942,6 @@ QmlGraphicsItem *QmlGraphicsVisualDataModel::item(int index, const QByteArray &v if (d->modelCount() <= 0 || !d->m_delegate) return 0; - QObject *nobj = d->m_cache.getItem(index); if (!nobj) { QmlContext *ccontext = d->m_context; @@ -900,7 +1055,6 @@ QVariant QmlGraphicsVisualDataModel::evaluate(int index, const QString &expressi QmlGraphicsItem *item = qobject_cast<QmlGraphicsItem *>(nobj); if (item) { QmlExpression e(qmlContext(item), expression, objectContext); - e.setTrackChange(false); value = e.value(); } } else { @@ -910,7 +1064,6 @@ QVariant QmlGraphicsVisualDataModel::evaluate(int index, const QString &expressi QmlGraphicsVisualDataModelData *data = new QmlGraphicsVisualDataModelData(index, this); ctxt->addDefaultObject(data); QmlExpression e(ctxt, expression, objectContext); - e.setTrackChange(false); value = e.value(); delete data; delete ctxt; @@ -943,7 +1096,7 @@ void QmlGraphicsVisualDataModel::_q_itemsChanged(int index, int count, if (d->m_listModelInterface) { data->setValue(propId, d->m_listModelInterface->data(ii, QList<int>() << role).value(role)); } else if (d->m_abstractItemModel) { - QModelIndex index = d->m_abstractItemModel->index(ii, 0); + QModelIndex index = d->m_abstractItemModel->index(ii, 0, d->m_root); data->setValue(propId, d->m_abstractItemModel->data(index, role)); } } diff --git a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel_p.h b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel_p.h index 49f9b27..7dc41a8 100644 --- a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel_p.h @@ -49,6 +49,8 @@ QT_BEGIN_HEADER +Q_DECLARE_METATYPE(QModelIndex) + QT_BEGIN_NAMESPACE QT_MODULE(Declarative) @@ -147,6 +149,7 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsVisualDataModel : public QmlGraphicsVisual Q_PROPERTY(QmlComponent *delegate READ delegate WRITE setDelegate) Q_PROPERTY(QString part READ part WRITE setPart) Q_PROPERTY(QObject *parts READ parts CONSTANT) + Q_PROPERTY(QModelIndex rootIndex READ rootIndex WRITE setRootIndex NOTIFY rootIndexChanged) Q_CLASSINFO("DefaultProperty", "delegate") public: QmlGraphicsVisualDataModel(); @@ -159,6 +162,9 @@ public: QmlComponent *delegate() const; void setDelegate(QmlComponent *); + QModelIndex rootIndex() const; + void setRootIndex(const QModelIndex &root); + QString part() const; void setPart(const QString &); @@ -178,6 +184,7 @@ public: Q_SIGNALS: void createdPackage(int index, QmlPackage *package); void destroyingPackage(QmlPackage *package); + void rootIndexChanged(); private Q_SLOTS: void _q_itemsChanged(int, int, const QList<int> &); diff --git a/src/declarative/graphicsitems/qmlgraphicswebview.cpp b/src/declarative/graphicsitems/qmlgraphicswebview.cpp index 0c21f75..f9bbb22 100644 --- a/src/declarative/graphicsitems/qmlgraphicswebview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicswebview.cpp @@ -483,6 +483,8 @@ void QmlGraphicsWebView::setRenderingEnabled(bool enabled) if (d->rendering == enabled) return; d->rendering = enabled; + emit renderingEnabledChanged(); + setCacheFrozen(!enabled); if (enabled) clearCache(); @@ -596,7 +598,10 @@ int QmlGraphicsWebView::pressGrabTime() const void QmlGraphicsWebView::setPressGrabTime(int ms) { Q_D(QmlGraphicsWebView); + if (d->pressTime == ms) + return; d->pressTime = ms; + emit pressGrabTimeChanged(); } void QmlGraphicsWebView::mousePressEvent(QGraphicsSceneMouseEvent *event) @@ -1024,6 +1029,7 @@ void QmlGraphicsWebView::setHtml(const QString &html, const QUrl &baseUrl) d->pending_url = baseUrl; d->pending_string = html; } + emit htmlChanged(); } void QmlGraphicsWebView::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl) @@ -1116,8 +1122,10 @@ QmlComponent *QmlGraphicsWebView::newWindowComponent() const void QmlGraphicsWebView::setNewWindowComponent(QmlComponent *newWindow) { Q_D(QmlGraphicsWebView); - delete d->newWindowComponent; + if (newWindow == d->newWindowComponent) + return; d->newWindowComponent = newWindow; + emit newWindowComponentChanged(); } @@ -1137,8 +1145,16 @@ QmlGraphicsItem *QmlGraphicsWebView::newWindowParent() const void QmlGraphicsWebView::setNewWindowParent(QmlGraphicsItem *parent) { Q_D(QmlGraphicsWebView); - delete d->newWindowParent; + if (parent == d->newWindowParent) + return; + if (d->newWindowParent && parent) { + QList<QGraphicsItem *> children = d->newWindowParent->childItems(); + for (int i = 0; i < children.count(); ++i) { + children.at(i)->setParentItem(parent); + } + } d->newWindowParent = parent; + emit newWindowParentChanged(); } /*! diff --git a/src/declarative/graphicsitems/qmlgraphicswebview_p.h b/src/declarative/graphicsitems/qmlgraphicswebview_p.h index 30ba0e4..ca63be9 100644 --- a/src/declarative/graphicsitems/qmlgraphicswebview_p.h +++ b/src/declarative/graphicsitems/qmlgraphicswebview_p.h @@ -97,9 +97,9 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsWebView : public QmlGraphicsPaintedItem Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor NOTIFY zoomFactorChanged) Q_PROPERTY(QString statusText READ statusText NOTIFY statusTextChanged) - Q_PROPERTY(QString html READ html WRITE setHtml) + Q_PROPERTY(QString html READ html WRITE setHtml NOTIFY htmlChanged) - Q_PROPERTY(int pressGrabTime READ pressGrabTime WRITE setPressGrabTime) + Q_PROPERTY(int pressGrabTime READ pressGrabTime WRITE setPressGrabTime NOTIFY pressGrabTimeChanged) Q_PROPERTY(int preferredWidth READ preferredWidth WRITE setPreferredWidth NOTIFY preferredWidthChanged) Q_PROPERTY(int preferredHeight READ preferredHeight WRITE setPreferredHeight NOTIFY preferredHeightChanged) @@ -116,10 +116,10 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsWebView : public QmlGraphicsPaintedItem Q_PROPERTY(QmlListProperty<QObject> javaScriptWindowObjects READ javaScriptWindowObjects CONSTANT) - Q_PROPERTY(QmlComponent* newWindowComponent READ newWindowComponent WRITE setNewWindowComponent) - Q_PROPERTY(QmlGraphicsItem* newWindowParent READ newWindowParent WRITE setNewWindowParent) + Q_PROPERTY(QmlComponent* newWindowComponent READ newWindowComponent WRITE setNewWindowComponent NOTIFY newWindowComponentChanged) + Q_PROPERTY(QmlGraphicsItem* newWindowParent READ newWindowParent WRITE setNewWindowParent NOTIFY newWindowParentChanged) - Q_PROPERTY(bool renderingEnabled READ renderingEnabled WRITE setRenderingEnabled) + Q_PROPERTY(bool renderingEnabled READ renderingEnabled WRITE setRenderingEnabled NOTIFY renderingEnabledChanged) public: QmlGraphicsWebView(QmlGraphicsItem *parent=0); @@ -192,7 +192,12 @@ Q_SIGNALS: void titleChanged(const QString&); void iconChanged(); void statusTextChanged(); + void htmlChanged(); + void pressGrabTimeChanged(); void zoomFactorChanged(); + void newWindowComponentChanged(); + void newWindowParentChanged(); + void renderingEnabledChanged(); void loadStarted(); void loadFinished(); diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri index daee431..4f75391 100644 --- a/src/declarative/qml/qml.pri +++ b/src/declarative/qml/qml.pri @@ -62,8 +62,8 @@ HEADERS += \ $$PWD/qmlinstruction_p.h \ $$PWD/qmlvmemetaobject_p.h \ $$PWD/qml.h \ - $$PWD/qmlbinding.h \ $$PWD/qmlbinding_p.h \ + $$PWD/qmlbinding_p_p.h \ $$PWD/qmlmetaproperty.h \ $$PWD/qmlmoduleplugin.h \ $$PWD/qmlcomponent.h \ diff --git a/src/declarative/qml/qmlbinding.cpp b/src/declarative/qml/qmlbinding.cpp index feadd0f..aeda28b 100644 --- a/src/declarative/qml/qmlbinding.cpp +++ b/src/declarative/qml/qmlbinding.cpp @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#include "qmlbinding.h" #include "qmlbinding_p.h" +#include "qmlbinding_p_p.h" #include "qml.h" #include "qmlcontext.h" @@ -85,12 +85,14 @@ QmlBinding::QmlBinding(void *data, QmlRefCount *rc, QObject *obj, QmlContext *ct : QmlExpression(ctxt, data, rc, obj, url, lineNumber, *new QmlBindingPrivate) { setParent(parent); + setNotifyOnValueChanged(true); } QmlBinding::QmlBinding(const QString &str, QObject *obj, QmlContext *ctxt, QObject *parent) : QmlExpression(ctxt, str, obj, *new QmlBindingPrivate) { setParent(parent); + setNotifyOnValueChanged(true); } QmlBinding::~QmlBinding() @@ -198,17 +200,17 @@ void QmlBinding::update(QmlMetaProperty::WriteFlags flags) data->release(); } -void QmlBinding::emitValueChanged() +void QmlBindingPrivate::emitValueChanged() { - update(); - // don't bother calling valueChanged() + Q_Q(QmlBinding); + q->update(); } void QmlBinding::setEnabled(bool e, QmlMetaProperty::WriteFlags flags) { Q_D(QmlBinding); d->bindingData()->enabled = e; - setTrackChange(e); + setNotifyOnValueChanged(e); QmlAbstractBinding::setEnabled(e, flags); diff --git a/src/declarative/qml/qmlbinding.h b/src/declarative/qml/qmlbinding.h deleted file mode 100644 index 151b71c..0000000 --- a/src/declarative/qml/qmlbinding.h +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QMLBINDING_H -#define QMLBINDING_H - -#include "qml.h" -#include "qmlpropertyvaluesource.h" -#include "qmlexpression.h" - -#include <QtCore/QObject> -#include <QtCore/QMetaProperty> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -class Q_DECLARATIVE_EXPORT QmlAbstractBinding -{ -public: - QmlAbstractBinding(); - virtual ~QmlAbstractBinding(); - - virtual void destroy(); - - virtual QString expression() const; - - void setEnabled(bool e) { setEnabled(e, QmlMetaProperty::DontRemoveBinding); } - virtual void setEnabled(bool, QmlMetaProperty::WriteFlags) = 0; - virtual int propertyIndex() = 0; - - void update() { update(QmlMetaProperty::DontRemoveBinding); } - virtual void update(QmlMetaProperty::WriteFlags) = 0; - - void addToObject(QObject *); - void removeFromObject(); - -protected: - void clear(); - -private: - friend class QmlDeclarativeData; - friend class QmlMetaProperty; - friend class QmlMetaPropertyPrivate; - friend class QmlVME; - - QObject *m_object; - QmlAbstractBinding **m_mePtr; - QmlAbstractBinding **m_prevBinding; - QmlAbstractBinding *m_nextBinding; -}; - -class QmlContext; -class QmlBindingPrivate; -class Q_DECLARATIVE_EXPORT QmlBinding : public QmlExpression, - public QmlAbstractBinding -{ -Q_OBJECT -public: - QmlBinding(const QString &, QObject *, QmlContext *, QObject *parent=0); - QmlBinding(void *, QmlRefCount *, QObject *, QmlContext *, const QString &, int, - QObject *parent); - ~QmlBinding(); - - void setTarget(const QmlMetaProperty &); - QmlMetaProperty property() const; - - bool enabled() const; - - // Inherited from QmlAbstractBinding - virtual void setEnabled(bool, QmlMetaProperty::WriteFlags flags); - virtual int propertyIndex(); - virtual void update(QmlMetaProperty::WriteFlags flags); - virtual QString expression() const; - -public Q_SLOTS: - void update() { update(QmlMetaProperty::DontRemoveBinding); } - -protected: - void emitValueChanged(); - -private: - Q_DECLARE_PRIVATE(QmlBinding) -}; - -QT_END_NAMESPACE - -QML_DECLARE_TYPE(QmlBinding); - -QT_END_HEADER - -#endif // QMLBINDING_H diff --git a/src/declarative/qml/qmlbinding_p.h b/src/declarative/qml/qmlbinding_p.h index b4f88b5..4594476 100644 --- a/src/declarative/qml/qmlbinding_p.h +++ b/src/declarative/qml/qmlbinding_p.h @@ -53,36 +53,82 @@ // We mean it. // -#include "qmlbinding.h" +#include "qml.h" +#include "qmlpropertyvaluesource.h" +#include "qmlexpression.h" -#include "qmlmetaproperty.h" -#include "qmlexpression_p.h" +#include <QtCore/QObject> +#include <QtCore/QMetaProperty> QT_BEGIN_NAMESPACE -class QmlBindingData : public QmlExpressionData +class Q_AUTOTEST_EXPORT QmlAbstractBinding { public: - QmlBindingData(); - virtual ~QmlBindingData(); + QmlAbstractBinding(); + virtual ~QmlAbstractBinding(); - bool updating:1; - bool enabled:1; + virtual void destroy(); - QmlMetaProperty property; + virtual QString expression() const; - virtual void refresh(); + void setEnabled(bool e) { setEnabled(e, QmlMetaProperty::DontRemoveBinding); } + virtual void setEnabled(bool, QmlMetaProperty::WriteFlags) = 0; + virtual int propertyIndex() = 0; + + void update() { update(QmlMetaProperty::DontRemoveBinding); } + virtual void update(QmlMetaProperty::WriteFlags) = 0; + + void addToObject(QObject *); + void removeFromObject(); + +protected: + void clear(); + +private: + friend class QmlDeclarativeData; + friend class QmlMetaProperty; + friend class QmlMetaPropertyPrivate; + friend class QmlVME; + + QObject *m_object; + QmlAbstractBinding **m_mePtr; + QmlAbstractBinding **m_prevBinding; + QmlAbstractBinding *m_nextBinding; }; -class QmlBindingPrivate : public QmlExpressionPrivate +class QmlContext; +class QmlBindingPrivate; +class Q_AUTOTEST_EXPORT QmlBinding : public QmlExpression, public QmlAbstractBinding { - Q_DECLARE_PUBLIC(QmlBinding) +Q_OBJECT public: - QmlBindingPrivate(); + QmlBinding(const QString &, QObject *, QmlContext *, QObject *parent=0); + QmlBinding(void *, QmlRefCount *, QObject *, QmlContext *, const QString &, int, + QObject *parent); + ~QmlBinding(); + + void setTarget(const QmlMetaProperty &); + QmlMetaProperty property() const; + + bool enabled() const; + + // Inherited from QmlAbstractBinding + virtual void setEnabled(bool, QmlMetaProperty::WriteFlags flags); + virtual int propertyIndex(); + virtual void update(QmlMetaProperty::WriteFlags flags); + virtual QString expression() const; + +public Q_SLOTS: + void update() { update(QmlMetaProperty::DontRemoveBinding); } + +protected: + void emitValueChanged(); - QmlBindingData *bindingData() { return static_cast<QmlBindingData *>(data); } - const QmlBindingData *bindingData() const { return static_cast<const QmlBindingData *>(data); } +private: + Q_DECLARE_PRIVATE(QmlBinding) }; +Q_DECLARE_METATYPE(QmlBinding*); QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlbinding_p_p.h b/src/declarative/qml/qmlbinding_p_p.h new file mode 100644 index 0000000..131bacc --- /dev/null +++ b/src/declarative/qml/qmlbinding_p_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMLBINDING_P_P_H +#define QMLBINDING_P_P_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. +// + +#include "qmlbinding_p.h" + +#include "qmlmetaproperty.h" +#include "qmlexpression_p.h" + +QT_BEGIN_NAMESPACE + +class QmlBindingData : public QmlExpressionData +{ +public: + QmlBindingData(); + virtual ~QmlBindingData(); + + bool updating:1; + bool enabled:1; + + QmlMetaProperty property; + + virtual void refresh(); +}; + +class QmlBindingPrivate : public QmlExpressionPrivate +{ + Q_DECLARE_PUBLIC(QmlBinding) +public: + QmlBindingPrivate(); + + QmlBindingData *bindingData() { return static_cast<QmlBindingData *>(data); } + const QmlBindingData *bindingData() const { return static_cast<const QmlBindingData *>(data); } + + virtual void emitValueChanged(); +}; + +QT_END_NAMESPACE + +#endif // QMLBINDING_P_P_H diff --git a/src/declarative/qml/qmlboundsignal.cpp b/src/declarative/qml/qmlboundsignal.cpp index a075899..db5fd61 100644 --- a/src/declarative/qml/qmlboundsignal.cpp +++ b/src/declarative/qml/qmlboundsignal.cpp @@ -124,7 +124,6 @@ QmlBoundSignal::QmlBoundSignal(QmlContext *ctxt, const QString &val, QMetaObject::connect(scope, m_signal.methodIndex(), this, evaluateIdx); m_expression = new QmlExpression(ctxt, val, scope); - m_expression->setTrackChange(false); } QmlBoundSignal::~QmlBoundSignal() @@ -157,7 +156,7 @@ QmlExpression *QmlBoundSignal::setExpression(QmlExpression *e) { QmlExpression *rv = m_expression; m_expression = e; - if (m_expression) m_expression->setTrackChange(false); + if (m_expression) m_expression->setNotifyOnValueChanged(false); return rv; } diff --git a/src/declarative/qml/qmlcompiledbindings_p.h b/src/declarative/qml/qmlcompiledbindings_p.h index 38fb2a3..056cc21 100644 --- a/src/declarative/qml/qmlcompiledbindings_p.h +++ b/src/declarative/qml/qmlcompiledbindings_p.h @@ -54,7 +54,7 @@ // #include "qmlexpression_p.h" -#include "qmlbinding.h" +#include "qmlbinding_p.h" QT_BEGIN_HEADER diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index bbae201..4508964 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -63,7 +63,7 @@ #include "qmlscriptstring.h" #include "qmlglobal_p.h" #include "qmlscriptparser_p.h" -#include "qmlbinding.h" +#include "qmlbinding_p.h" #include "qmlcompiledbindings_p.h" #include <qfxperf_p_p.h> @@ -2609,7 +2609,13 @@ int QmlCompiler::genContextCache() int QmlCompiler::genValueTypeData(QmlParser::Property *valueTypeProp, QmlParser::Property *prop) { - return output->indexForByteArray(QmlMetaPropertyPrivate::saveValueType(prop->parent->metaObject(), prop->index, valueTypeProp->index, valueTypeProp->type)); + QByteArray data = + QmlMetaPropertyPrivate::saveValueType(prop->parent->metaObject(), prop->index, + QmlEnginePrivate::get(engine)->valueTypes[prop->type]->metaObject(), + valueTypeProp->index); +// valueTypeProp->index, valueTypeProp->type); + + return output->indexForByteArray(data); } int QmlCompiler::genPropertyData(QmlParser::Property *prop) diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp index 87ecb8a..4ab4f70 100644 --- a/src/declarative/qml/qmlcomponent.cpp +++ b/src/declarative/qml/qmlcomponent.cpp @@ -49,8 +49,8 @@ #include "qmlvme_p.h" #include "qml.h" #include "qmlengine.h" -#include "qmlbinding.h" #include "qmlbinding_p.h" +#include "qmlbinding_p_p.h" #include "qmlglobal_p.h" #include "qmlscriptparser_p.h" diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index d47db9b..67d8c7d 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -51,7 +51,7 @@ #include "qmlcomponent.h" #include "qmlmetaproperty_p.h" #include "qmlmoduleplugin.h" -#include "qmlbinding_p.h" +#include "qmlbinding_p_p.h" #include "qmlvme_p.h" #include "qmlenginedebug_p.h" #include "qmlstringconverters_p.h" diff --git a/src/declarative/qml/qmlenginedebug.cpp b/src/declarative/qml/qmlenginedebug.cpp index 654157c..973e5e5 100644 --- a/src/declarative/qml/qmlenginedebug.cpp +++ b/src/declarative/qml/qmlenginedebug.cpp @@ -45,7 +45,7 @@ #include "qmlengine.h" #include "qmlmetatype.h" #include "qmlmetaproperty.h" -#include "qmlbinding.h" +#include "qmlbinding_p.h" #include "qmlcontext_p.h" #include "qmlwatcher_p.h" @@ -408,14 +408,13 @@ void QmlEngineDebugServer::messageReceived(const QByteArray &message) QmlContext *context = qmlContext(object); QVariant result; if (object && context) { - QmlExpression *exprObj = new QmlExpression(context, expr, object); + QmlExpression exprObj(context, expr, object); bool undefined = false; - QVariant value = exprObj->value(&undefined); + QVariant value = exprObj.value(&undefined); if (undefined) result = QLatin1String("<undefined>"); else result = valueContents(value); - delete exprObj; } else { result = QLatin1String("<unknown context>"); } diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp index 8f0c945..64b2d7f 100644 --- a/src/declarative/qml/qmlexpression.cpp +++ b/src/declarative/qml/qmlexpression.cpp @@ -70,7 +70,7 @@ bool QmlDelayedError::addError(QmlEnginePrivate *e) QmlExpressionData::QmlExpressionData() : q(0), dataRef(0), expressionFunctionValid(false), expressionRewritten(false), me(0), - trackChange(true), isShared(false), line(-1), guardList(0), guardListLength(0) + trackChange(false), isShared(false), line(-1), guardList(0), guardListLength(0) { } @@ -273,14 +273,6 @@ QString QmlExpression::expression() const } /*! - Clear the expression. -*/ -void QmlExpression::clearExpression() -{ - setExpression(QString()); -} - -/*! Set the expression to \a expression. */ void QmlExpression::setExpression(const QString &expression) @@ -495,44 +487,34 @@ QVariant QmlExpression::value(bool *isUndefined) } /*! - Returns true if the expression results in a constant value. - QmlExpression::value() must have been invoked at least once before the - return from this method is valid. - */ -bool QmlExpression::isConstant() const -{ - Q_D(const QmlExpression); - return !d->data->guardList; -} - -/*! - Returns true if the changes are tracked in the expression's value. +Returns true if the valueChanged() signal is emitted when the expression's evaluated +value changes. */ -bool QmlExpression::trackChange() const +bool QmlExpression::notifyOnValueChanged() const { Q_D(const QmlExpression); return d->data->trackChange; } /*! - Set whether changes are tracked in the expression's value to \a trackChange. +Sets whether the valueChanged() signal is emitted when the expression's evaluated +value changes. - If true, the QmlExpression will monitor properties involved in the - expression's evaluation, and call QmlExpression::valueChanged() if they have - changed. This allows an application to ensure that any value associated - with the result of the expression remains up to date. +If true, the QmlExpression will monitor properties involved in the expression's +evaluation, and emit QmlExpression::valueChanged() if they have changed. This allows +an application to ensure that any value associated with the result of the expression +remains up to date. - If false, the QmlExpression will not montitor properties involved in the - expression's evaluation, and QmlExpression::valueChanged() will never be - called. This is more efficient if an application wants a "one off" - evaluation of the expression. +If false, the QmlExpression will not montitor properties involved in the expression's +evaluation, and QmlExpression::valueChanged() will never be emitted. This is more efficient +if an application wants a "one off" evaluation of the expression. - By default, trackChange is true. +By default, notifyOnChange is false. */ -void QmlExpression::setTrackChange(bool trackChange) +void QmlExpression::setNotifyOnValueChanged(bool notifyOnChange) { Q_D(QmlExpression); - d->data->trackChange = trackChange; + d->data->trackChange = notifyOnChange; } /*! @@ -618,7 +600,8 @@ QmlError QmlExpression::error() const /*! \internal */ void QmlExpression::__q_notify() { - emitValueChanged(); + Q_D(QmlExpression); + d->emitValueChanged(); } void QmlExpressionPrivate::clearGuards() @@ -765,13 +748,10 @@ void QmlExpressionPrivate::updateGuards(const QPODVector<QmlEnginePrivate::Captu calling QmlExpression::value()) before this signal will be emitted. */ -/*! - Subclasses can capture the emission of the valueChanged() signal by overriding - this function. They can choose whether to then call valueChanged(). -*/ -void QmlExpression::emitValueChanged() +void QmlExpressionPrivate::emitValueChanged() { - emit valueChanged(); + Q_Q(QmlExpression); + emit q->valueChanged(); } QmlAbstractExpression::QmlAbstractExpression() diff --git a/src/declarative/qml/qmlexpression.h b/src/declarative/qml/qmlexpression.h index 428eefa..61374f2 100644 --- a/src/declarative/qml/qmlexpression.h +++ b/src/declarative/qml/qmlexpression.h @@ -70,12 +70,10 @@ public: QmlContext *context() const; QString expression() const; - void clearExpression(); - virtual void setExpression(const QString &); - bool isConstant() const; + void setExpression(const QString &); - bool trackChange() const; - void setTrackChange(bool); + bool notifyOnValueChanged() const; + void setNotifyOnValueChanged(bool); QString sourceFile() const; int lineNumber() const; @@ -87,15 +85,12 @@ public: void clearError(); QmlError error() const; -public Q_SLOTS: QVariant value(bool *isUndefined = 0); Q_SIGNALS: void valueChanged(); protected: - virtual void emitValueChanged(); - QmlExpression(QmlContext *, const QString &, QObject *, QmlExpressionPrivate &dd); QmlExpression(QmlContext *, void *, QmlRefCount *rc, QObject *me, const QString &, diff --git a/src/declarative/qml/qmlexpression_p.h b/src/declarative/qml/qmlexpression_p.h index e52a199..e4bed05 100644 --- a/src/declarative/qml/qmlexpression_p.h +++ b/src/declarative/qml/qmlexpression_p.h @@ -177,6 +177,8 @@ public: return expr->q_func(); } + virtual void emitValueChanged(); + static void exceptionToError(QScriptEngine *, QmlError &); static QScriptValue evalInObjectScope(QmlContext *, QObject *, const QString &); static QScriptValue evalInObjectScope(QmlContext *, QObject *, const QScriptProgram &); diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp index 7c273dc..d731393 100644 --- a/src/declarative/qml/qmlmetaproperty.cpp +++ b/src/declarative/qml/qmlmetaproperty.cpp @@ -44,7 +44,7 @@ #include "qmlcompositetypedata_p.h" #include "qml.h" -#include "qmlbinding.h" +#include "qmlbinding_p.h" #include "qmlcontext.h" #include "qmlcontext_p.h" #include "qmlboundsignal_p.h" @@ -378,7 +378,9 @@ QmlMetaProperty &QmlMetaProperty::operator=(const QmlMetaProperty &other) d->object = other.d->object; d->isDefaultProperty = other.d->isDefaultProperty; + d->isNameCached = other.d->isNameCached; d->core = other.d->core; + d->nameCache = other.d->nameCache; d->valueType = other.d->valueType; @@ -775,6 +777,7 @@ bool QmlMetaPropertyPrivate::writeValueProperty(const QVariant &value, writeBack->read(object, core.coreIndex); QmlPropertyCache::Data data = core; + data.flags = valueType.flags; data.coreIndex = valueType.valueTypeCoreIdx; data.propType = valueType.valueTypePropType; rv = write(writeBack, data, value, context, flags); @@ -811,22 +814,22 @@ bool QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data return writeEnumProperty(prop, coreIdx, object, v, flags); } - int t = property.propType; - int vt = value.userType(); + int propertyType = property.propType; + int variantType = value.userType(); QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(context); - if (t == QVariant::Url) { + if (propertyType == QVariant::Url) { QUrl u; bool found = false; - if (vt == QVariant::Url) { + if (variantType == QVariant::Url) { u = value.toUrl(); found = true; - } else if (vt == QVariant::ByteArray) { + } else if (variantType == QVariant::ByteArray) { u = QUrl(QString::fromUtf8(value.toByteArray())); found = true; - } else if (vt == QVariant::String) { + } else if (variantType == QVariant::String) { u = QUrl(value.toString()); found = true; } @@ -840,12 +843,12 @@ bool QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data void *argv[] = { &u, 0, &status, &flags }; QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, argv); - } else if (vt == t) { + } else if (variantType == propertyType) { void *a[] = { (void *)value.constData(), 0, &status, &flags }; QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); - } else if (qMetaTypeId<QVariant>() == t) { + } else if (qMetaTypeId<QVariant>() == propertyType) { void *a[] = { (void *)&value, 0, &status, &flags }; QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); @@ -858,7 +861,7 @@ bool QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data return false; QObject *o = *(QObject **)value.constData(); - const QMetaObject *propMo = rawMetaObjectForType(enginePriv, t); + const QMetaObject *propMo = rawMetaObjectForType(enginePriv, propertyType); if (o) valMo = o->metaObject(); @@ -914,25 +917,25 @@ bool QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data } } else { - Q_ASSERT(vt != t); + Q_ASSERT(variantType != propertyType); QVariant v = value; - if (v.convert((QVariant::Type)t)) { + if (v.convert((QVariant::Type)propertyType)) { void *a[] = { (void *)v.constData(), 0, &status, &flags}; QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); - } else if ((uint)t >= QVariant::UserType && vt == QVariant::String) { - QmlMetaType::StringConverter con = QmlMetaType::customStringConverter(t); + } else if ((uint)propertyType >= QVariant::UserType && variantType == QVariant::String) { + QmlMetaType::StringConverter con = QmlMetaType::customStringConverter(propertyType); if (!con) return false; QVariant v = con(value.toString()); - if (v.userType() == t) { + if (v.userType() == propertyType) { void *a[] = { (void *)v.constData(), 0, &status, &flags}; QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); } - } else if (vt == QVariant::String) { + } else if (variantType == QVariant::String) { bool ok = false; - QVariant v = QmlStringConverters::variantFromString(value.toString(), t, &ok); + QVariant v = QmlStringConverters::variantFromString(value.toString(), propertyType, &ok); if (!ok) return false; @@ -1080,15 +1083,20 @@ struct ValueTypeSerializedData : public SerializedData { }; QByteArray QmlMetaPropertyPrivate::saveValueType(const QMetaObject *metaObject, int index, - int subIndex, int subType) + const QMetaObject *subObject, int subIndex) { + QMetaProperty prop = metaObject->property(index); + QMetaProperty subProp = subObject->property(subIndex); + ValueTypeSerializedData sd; sd.type = QmlMetaProperty::ValueTypeProperty; sd.core.load(metaObject->property(index)); + sd.valueType.flags = QmlPropertyCache::Data::flagsForProperty(subProp); sd.valueType.valueTypeCoreIdx = subIndex; - sd.valueType.valueTypePropType = subType; + sd.valueType.valueTypePropType = subProp.userType(); QByteArray rv((const char *)&sd, sizeof(sd)); + return rv; } diff --git a/src/declarative/qml/qmlmetaproperty_p.h b/src/declarative/qml/qmlmetaproperty_p.h index b99e5be..9236bd3 100644 --- a/src/declarative/qml/qmlmetaproperty_p.h +++ b/src/declarative/qml/qmlmetaproperty_p.h @@ -111,7 +111,8 @@ public: static QmlAbstractBinding *setBinding(QObject *, const QmlPropertyCache::Data &, QmlAbstractBinding *, QmlMetaProperty::WriteFlags flags = QmlMetaProperty::DontRemoveBinding); - static QByteArray saveValueType(const QMetaObject *, int, int, int); + static QByteArray saveValueType(const QMetaObject *, int, + const QMetaObject *, int); static QByteArray saveProperty(const QMetaObject *, int); static QmlMetaProperty restore(const QByteArray &, QObject *, QmlContext * = 0); diff --git a/src/declarative/qml/qmlobjectscriptclass.cpp b/src/declarative/qml/qmlobjectscriptclass.cpp index 15ece1d..155a7d6 100644 --- a/src/declarative/qml/qmlobjectscriptclass.cpp +++ b/src/declarative/qml/qmlobjectscriptclass.cpp @@ -46,7 +46,7 @@ #include "qmldeclarativedata_p.h" #include "qmltypenamescriptclass_p.h" #include "qmllistscriptclass_p.h" -#include "qmlbinding.h" +#include "qmlbinding_p.h" #include "qmlguard_p.h" #include "qmlvmemetaobject_p.h" diff --git a/src/declarative/qml/qmlpropertycache.cpp b/src/declarative/qml/qmlpropertycache.cpp index a3e655b..81f8e51 100644 --- a/src/declarative/qml/qmlpropertycache.cpp +++ b/src/declarative/qml/qmlpropertycache.cpp @@ -42,20 +42,18 @@ #include "qmlpropertycache_p.h" #include "qmlengine_p.h" -#include "qmlbinding.h" -#include "qdebug.h" +#include "qmlbinding_p.h" +#include <QtCore/qdebug.h> Q_DECLARE_METATYPE(QScriptValue); QT_BEGIN_NAMESPACE -void QmlPropertyCache::Data::load(const QMetaProperty &p, QmlEngine *engine) +QmlPropertyCache::Data::Flags QmlPropertyCache::Data::flagsForProperty(const QMetaProperty &p, QmlEngine *engine) { - propType = p.userType(); - if (QVariant::Type(propType) == QVariant::LastType) - propType = qMetaTypeId<QVariant>(); - coreIndex = p.propertyIndex(); - notifyIndex = p.notifySignalIndex(); + int propType = p.userType(); + + Flags flags; if (p.isConstant()) flags |= Data::IsConstant; @@ -78,6 +76,18 @@ void QmlPropertyCache::Data::load(const QMetaProperty &p, QmlEngine *engine) else if (cat == QmlMetaType::List) flags |= Data::IsQList; } + + return flags; +} + +void QmlPropertyCache::Data::load(const QMetaProperty &p, QmlEngine *engine) +{ + propType = p.userType(); + if (QVariant::Type(propType) == QVariant::LastType) + propType = qMetaTypeId<QVariant>(); + coreIndex = p.propertyIndex(); + notifyIndex = p.notifySignalIndex(); + flags = flagsForProperty(p, engine); } void QmlPropertyCache::Data::load(const QMetaMethod &m) diff --git a/src/declarative/qml/qmlpropertycache_p.h b/src/declarative/qml/qmlpropertycache_p.h index 18eea80..4a98b88 100644 --- a/src/declarative/qml/qmlpropertycache_p.h +++ b/src/declarative/qml/qmlpropertycache_p.h @@ -104,6 +104,7 @@ public: int coreIndex; int notifyIndex; + static Flags flagsForProperty(const QMetaProperty &, QmlEngine *engine = 0); void load(const QMetaProperty &, QmlEngine *engine = 0); void load(const QMetaMethod &); QString name(QObject *); @@ -113,6 +114,7 @@ public: struct ValueTypeData { inline ValueTypeData(); inline bool operator==(const ValueTypeData &); + Data::Flags flags; // flags on the value type wrapper int valueTypeCoreIdx; // The prop index of the access property on the value type wrapper int valueTypePropType; // The QVariant::Type of access property on the value type wrapper }; @@ -173,13 +175,14 @@ QmlPropertyCache::property(const QScriptDeclarativeClass::Identifier &id) const } QmlPropertyCache::ValueTypeData::ValueTypeData() -: valueTypeCoreIdx(-1), valueTypePropType(0) +: flags(QmlPropertyCache::Data::NoFlags), valueTypeCoreIdx(-1), valueTypePropType(0) { } bool QmlPropertyCache::ValueTypeData::operator==(const ValueTypeData &o) { - return valueTypeCoreIdx == o.valueTypeCoreIdx && + return flags == o.flags && + valueTypeCoreIdx == o.valueTypeCoreIdx && valueTypePropType == o.valueTypePropType; } diff --git a/src/declarative/qml/qmlvaluetype.cpp b/src/declarative/qml/qmlvaluetype.cpp index 33c3e76..e3b4219 100644 --- a/src/declarative/qml/qmlvaluetype.cpp +++ b/src/declarative/qml/qmlvaluetype.cpp @@ -75,6 +75,8 @@ QmlValueType *QmlValueTypeFactory::valueType(int t) return new QmlRectFValueType; case QVariant::Vector3D: return new QmlVector3DValueType; + case QVariant::EasingCurve: + return new QmlEasingValueType; case QVariant::Font: return new QmlFontValueType; default: @@ -473,6 +475,74 @@ void QmlVector3DValueType::setZ(qreal z) vector.setZ(z); } +QmlEasingValueType::QmlEasingValueType(QObject *parent) +: QmlValueType(parent) +{ +} + +void QmlEasingValueType::read(QObject *obj, int idx) +{ + void *a[] = { &easing, 0 }; + QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a); +} + +void QmlEasingValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags) +{ + int status = -1; + void *a[] = { &easing, 0, &status, &flags }; + QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a); +} + +QVariant QmlEasingValueType::value() +{ + return QVariant(easing); +} + +void QmlEasingValueType::setValue(QVariant value) +{ + easing = qvariant_cast<QEasingCurve>(value); +} + +QmlEasingValueType::Type QmlEasingValueType::type() const +{ + return (QmlEasingValueType::Type)easing.type(); +} + +qreal QmlEasingValueType::amplitude() const +{ + return easing.amplitude(); +} + +qreal QmlEasingValueType::overshoot() const +{ + return easing.overshoot(); +} + +qreal QmlEasingValueType::period() const +{ + return easing.period(); +} + +void QmlEasingValueType::setType(QmlEasingValueType::Type type) +{ + easing.setType((QEasingCurve::Type)type); +} + +void QmlEasingValueType::setAmplitude(qreal amplitude) +{ + easing.setAmplitude(amplitude); +} + +void QmlEasingValueType::setOvershoot(qreal overshoot) +{ + easing.setOvershoot(overshoot); +} + +void QmlEasingValueType::setPeriod(qreal period) +{ + easing.setPeriod(period); +} + QmlFontValueType::QmlFontValueType(QObject *parent) : QmlValueType(parent), hasPixelSize(false) { diff --git a/src/declarative/qml/qmlvaluetype_p.h b/src/declarative/qml/qmlvaluetype_p.h index 0a152e8..6dd3703 100644 --- a/src/declarative/qml/qmlvaluetype_p.h +++ b/src/declarative/qml/qmlvaluetype_p.h @@ -57,6 +57,7 @@ #include <QtCore/qobject.h> #include <QtCore/qrect.h> +#include <QtCore/qeasingcurve.h> #include <QtCore/qvariant.h> #include <QtGui/qvector3d.h> #include <QtGui/qfont.h> @@ -256,6 +257,62 @@ private: QVector3D vector; }; +class Q_AUTOTEST_EXPORT QmlEasingValueType : public QmlValueType +{ + Q_OBJECT + Q_ENUMS(Type) + + Q_PROPERTY(QmlEasingValueType::Type type READ type WRITE setType) + Q_PROPERTY(qreal amplitude READ amplitude WRITE setAmplitude) + Q_PROPERTY(qreal overshoot READ overshoot WRITE setOvershoot) + Q_PROPERTY(qreal period READ period WRITE setPeriod) +public: + enum Type { + Linear = QEasingCurve::Linear, + InQuad = QEasingCurve::InQuad, OutQuad = QEasingCurve::OutQuad, + InOutQuad = QEasingCurve::InOutQuad, OutInQuad = QEasingCurve::OutInQuad, + InCubic = QEasingCurve::InCubic, OutCubic = QEasingCurve::OutCubic, + InOutCubic = QEasingCurve::InOutCubic, OutInCubic = QEasingCurve::OutInCubic, + InQuart = QEasingCurve::InQuart, OutQuart = QEasingCurve::OutQuart, + InOutQuart = QEasingCurve::InOutQuart, OutInQuart = QEasingCurve::OutInQuart, + InQuint = QEasingCurve::InQuint, OutQuint = QEasingCurve::OutQuint, + InOutQuint = QEasingCurve::InOutQuint, OutInQuint = QEasingCurve::OutInQuint, + InSine = QEasingCurve::InSine, OutSine = QEasingCurve::OutSine, + InOutSine = QEasingCurve::InOutSine, OutInSine = QEasingCurve::OutInSine, + InExpo = QEasingCurve::InExpo, OutExpo = QEasingCurve::OutExpo, + InOutExpo = QEasingCurve::InOutExpo, OutInExpo = QEasingCurve::OutInExpo, + InCirc = QEasingCurve::InCirc, OutCirc = QEasingCurve::OutCirc, + InOutCirc = QEasingCurve::InOutCirc, OutInCirc = QEasingCurve::OutInCirc, + InElastic = QEasingCurve::InElastic, OutElastic = QEasingCurve::OutElastic, + InOutElastic = QEasingCurve::InOutElastic, OutInElastic = QEasingCurve::OutInElastic, + InBack = QEasingCurve::InBack, OutBack = QEasingCurve::OutBack, + InOutBack = QEasingCurve::InOutBack, OutInBack = QEasingCurve::OutInBack, + InBounce = QEasingCurve::InBounce, OutBounce = QEasingCurve::OutBounce, + InOutBounce = QEasingCurve::InOutBounce, OutInBounce = QEasingCurve::OutInBounce, + InCurve = QEasingCurve::InCurve, OutCurve = QEasingCurve::OutCurve, + SineCurve = QEasingCurve::SineCurve, CosineCurve = QEasingCurve::CosineCurve, + }; + + QmlEasingValueType(QObject *parent = 0); + + virtual void read(QObject *, int); + virtual void write(QObject *, int, QmlMetaProperty::WriteFlags); + virtual QVariant value(); + virtual void setValue(QVariant value); + + Type type() const; + qreal amplitude() const; + qreal overshoot() const; + qreal period() const; + void setType(Type); + void setAmplitude(qreal); + void setOvershoot(qreal); + void setPeriod(qreal); + +private: + QEasingCurve easing; +}; + class Q_AUTOTEST_EXPORT QmlFontValueType : public QmlValueType { Q_OBJECT diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp index 8655809..f8f1ff0 100644 --- a/src/declarative/qml/qmlvme.cpp +++ b/src/declarative/qml/qmlvme.cpp @@ -51,11 +51,11 @@ #include "qmlengine.h" #include "qmlcontext.h" #include "qmlcomponent.h" -#include "qmlbinding.h" +#include "qmlbinding_p.h" #include "qmlengine_p.h" #include "qmlcomponent_p.h" #include "qmlvmemetaobject_p.h" -#include "qmlbinding_p.h" +#include "qmlbinding_p_p.h" #include "qmlcontext_p.h" #include "qmlcompiledbindings_p.h" #include "qmlglobal_p.h" diff --git a/src/declarative/qml/qmlwatcher.cpp b/src/declarative/qml/qmlwatcher.cpp index 59503de..a8a94c5 100644 --- a/src/declarative/qml/qmlwatcher.cpp +++ b/src/declarative/qml/qmlwatcher.cpp @@ -154,6 +154,7 @@ bool QmlWatcher::addWatch(int id, quint32 objectId, const QString &expr) QmlContext *context = qmlContext(object); if (context) { QmlExpression *exprObj = new QmlExpression(context, expr, object); + exprObj->setNotifyOnValueChanged(true); QmlWatchProxy *proxy = new QmlWatchProxy(id, exprObj, objectId, this); exprObj->setParent(proxy); m_proxies[id].append(proxy); diff --git a/src/declarative/util/qmlanimation.cpp b/src/declarative/util/qmlanimation.cpp index c044f97..2f24167 100644 --- a/src/declarative/util/qmlanimation.cpp +++ b/src/declarative/util/qmlanimation.cpp @@ -66,79 +66,6 @@ QT_BEGIN_NAMESPACE -static QEasingCurve stringToCurve(const QString &curve, QObject *obj) -{ - QEasingCurve easingCurve; - - QString normalizedCurve = curve; - bool hasParams = curve.contains(QLatin1Char('(')); - QStringList props; - - if (hasParams) { - QString easeName = curve.trimmed(); - if (!easeName.endsWith(QLatin1Char(')'))) { - qmlInfo(obj) << QmlPropertyAnimation::tr("Unmatched parenthesis in easing function \"%1\"").arg(curve); - return easingCurve; - } - - int idx = easeName.indexOf(QLatin1Char('(')); - QString prop_str = - easeName.mid(idx + 1, easeName.length() - 1 - idx - 1); - normalizedCurve = easeName.left(idx); - if (!normalizedCurve.startsWith(QLatin1String("ease"))) { - qmlInfo(obj) << QmlPropertyAnimation::tr("Easing function \"%1\" must start with \"ease\"").arg(curve); - return easingCurve; - } - - props = prop_str.split(QLatin1Char(',')); - } - - if (normalizedCurve.startsWith(QLatin1String("ease"))) - normalizedCurve = normalizedCurve.mid(4); - - static int index = QEasingCurve::staticMetaObject.indexOfEnumerator("Type"); - static QMetaEnum me = QEasingCurve::staticMetaObject.enumerator(index); - - int value = me.keyToValue(normalizedCurve.toUtf8().constData()); - if (value < 0) { - qmlInfo(obj) << QmlPropertyAnimation::tr("Unknown easing curve \"%1\"").arg(curve); - return easingCurve; - } - easingCurve.setType((QEasingCurve::Type)value); - - if (hasParams) { - foreach(const QString &str, props) { - int sep = str.indexOf(QLatin1Char(':')); - - if (sep == -1) { - qmlInfo(obj) << QmlPropertyAnimation::tr("Improperly specified parameter in easing function \"%1\"").arg(curve); - continue; - } - - QString propName = str.left(sep).trimmed(); - bool isOk; - qreal propValue = str.mid(sep + 1).trimmed().toDouble(&isOk); - - if (propName.isEmpty() || !isOk) { - qmlInfo(obj) << QmlPropertyAnimation::tr("Improperly specified parameter in easing function \"%1\"").arg(curve); - continue; - } - - if (propName == QLatin1String("amplitude")) { - easingCurve.setAmplitude(propValue); - } else if (propName == QLatin1String("period")) { - easingCurve.setPeriod(propValue); - } else if (propName == QLatin1String("overshoot")) { - easingCurve.setOvershoot(propValue); - } else { - qmlInfo(obj) << QmlPropertyAnimation::tr("Unknown easing parameter \"%1\"").arg(propName); - continue; - } - } - } - return easingCurve; -} - QML_DEFINE_NOCREATE_TYPE(QmlAbstractAnimation) /*! @@ -793,7 +720,6 @@ void QmlScriptActionPrivate::execute() const QString &str = scriptStr.script(); if (!str.isEmpty()) { QmlExpression expr(scriptStr.context(), str, scriptStr.scopeObject()); - expr.setTrackChange(false); expr.value(); } } @@ -1928,195 +1854,195 @@ void QmlPropertyAnimation::setTo(const QVariant &t) } /*! - \qmlproperty string PropertyAnimation::easing + \qmlproperty QEasingCurve PropertyAnimation::easing \brief the easing curve used for the transition. Available values are: \table \row - \o \c easeLinear + \o \c Linear \o Easing curve for a linear (t) function: velocity is constant. \o \inlineimage qeasingcurve-linear.png \row - \o \c easeInQuad + \o \c InQuad \o Easing curve for a quadratic (t^2) function: accelerating from zero velocity. \o \inlineimage qeasingcurve-inquad.png \row - \o \c easeOutQuad + \o \c OutQuad \o Easing curve for a quadratic (t^2) function: decelerating to zero velocity. \o \inlineimage qeasingcurve-outquad.png \row - \o \c easeInOutQuad + \o \c InOutQuad \o Easing curve for a quadratic (t^2) function: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutquad.png \row - \o \c easeOutInQuad + \o \c OutInQuad \o Easing curve for a quadratic (t^2) function: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outinquad.png \row - \o \c easeInCubic + \o \c InCubic \o Easing curve for a cubic (t^3) function: accelerating from zero velocity. \o \inlineimage qeasingcurve-incubic.png \row - \o \c easeOutCubic + \o \c OutCubic \o Easing curve for a cubic (t^3) function: decelerating from zero velocity. \o \inlineimage qeasingcurve-outcubic.png \row - \o \c easeInOutCubic + \o \c InOutCubic \o Easing curve for a cubic (t^3) function: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutcubic.png \row - \o \c easeOutInCubic + \o \c OutInCubic \o Easing curve for a cubic (t^3) function: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outincubic.png \row - \o \c easeInQuart + \o \c InQuart \o Easing curve for a quartic (t^4) function: accelerating from zero velocity. \o \inlineimage qeasingcurve-inquart.png \row - \o \c easeOutQuart + \o \c OutQuart \o Easing curve for a cubic (t^4) function: decelerating from zero velocity. \o \inlineimage qeasingcurve-outquart.png \row - \o \c easeInOutQuart + \o \c InOutQuart \o Easing curve for a cubic (t^4) function: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutquart.png \row - \o \c easeOutInQuart + \o \c OutInQuart \o Easing curve for a cubic (t^4) function: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outinquart.png \row - \o \c easeInQuint + \o \c InQuint \o Easing curve for a quintic (t^5) function: accelerating from zero velocity. \o \inlineimage qeasingcurve-inquint.png \row - \o \c easeOutQuint + \o \c OutQuint \o Easing curve for a cubic (t^5) function: decelerating from zero velocity. \o \inlineimage qeasingcurve-outquint.png \row - \o \c easeInOutQuint + \o \c InOutQuint \o Easing curve for a cubic (t^5) function: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutquint.png \row - \o \c easeOutInQuint + \o \c OutInQuint \o Easing curve for a cubic (t^5) function: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outinquint.png \row - \o \c easeInSine + \o \c InSine \o Easing curve for a sinusoidal (sin(t)) function: accelerating from zero velocity. \o \inlineimage qeasingcurve-insine.png \row - \o \c easeOutSine + \o \c OutSine \o Easing curve for a sinusoidal (sin(t)) function: decelerating from zero velocity. \o \inlineimage qeasingcurve-outsine.png \row - \o \c easeInOutSine + \o \c InOutSine \o Easing curve for a sinusoidal (sin(t)) function: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutsine.png \row - \o \c easeOutInSine + \o \c OutInSine \o Easing curve for a sinusoidal (sin(t)) function: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outinsine.png \row - \o \c easeInExpo + \o \c InExpo \o Easing curve for an exponential (2^t) function: accelerating from zero velocity. \o \inlineimage qeasingcurve-inexpo.png \row - \o \c easeOutExpo + \o \c OutExpo \o Easing curve for an exponential (2^t) function: decelerating from zero velocity. \o \inlineimage qeasingcurve-outexpo.png \row - \o \c easeInOutExpo + \o \c InOutExpo \o Easing curve for an exponential (2^t) function: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutexpo.png \row - \o \c easeOutInExpo + \o \c OutInExpo \o Easing curve for an exponential (2^t) function: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outinexpo.png \row - \o \c easeInCirc + \o \c InCirc \o Easing curve for a circular (sqrt(1-t^2)) function: accelerating from zero velocity. \o \inlineimage qeasingcurve-incirc.png \row - \o \c easeOutCirc + \o \c OutCirc \o Easing curve for a circular (sqrt(1-t^2)) function: decelerating from zero velocity. \o \inlineimage qeasingcurve-outcirc.png \row - \o \c easeInOutCirc + \o \c InOutCirc \o Easing curve for a circular (sqrt(1-t^2)) function: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutcirc.png \row - \o \c easeOutInCirc + \o \c OutInCirc \o Easing curve for a circular (sqrt(1-t^2)) function: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outincirc.png \row - \o \c easeInElastic + \o \c InElastic \o Easing curve for an elastic (exponentially decaying sine wave) function: accelerating from zero velocity. \br The peak amplitude can be set with the \e amplitude parameter, and the period of decay by the \e period parameter. \o \inlineimage qeasingcurve-inelastic.png \row - \o \c easeOutElastic + \o \c OutElastic \o Easing curve for an elastic (exponentially decaying sine wave) function: decelerating from zero velocity. \br The peak amplitude can be set with the \e amplitude parameter, and the period of decay by the \e period parameter. \o \inlineimage qeasingcurve-outelastic.png \row - \o \c easeInOutElastic + \o \c InOutElastic \o Easing curve for an elastic (exponentially decaying sine wave) function: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutelastic.png \row - \o \c easeOutInElastic + \o \c OutInElastic \o Easing curve for an elastic (exponentially decaying sine wave) function: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outinelastic.png \row - \o \c easeInBack + \o \c InBack \o Easing curve for a back (overshooting cubic function: (s+1)*t^3 - s*t^2) easing in: accelerating from zero velocity. \o \inlineimage qeasingcurve-inback.png \row - \o \c easeOutBack + \o \c OutBack \o Easing curve for a back (overshooting cubic function: (s+1)*t^3 - s*t^2) easing out: decelerating to zero velocity. \o \inlineimage qeasingcurve-outback.png \row - \o \c easeInOutBack + \o \c InOutBack \o Easing curve for a back (overshooting cubic function: (s+1)*t^3 - s*t^2) easing in/out: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutback.png \row - \o \c easeOutInBack + \o \c OutInBack \o Easing curve for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out/in: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outinback.png \row - \o \c easeInBounce + \o \c InBounce \o Easing curve for a bounce (exponentially decaying parabolic bounce) function: accelerating from zero velocity. \o \inlineimage qeasingcurve-inbounce.png \row - \o \c easeOutBounce + \o \c OutBounce \o Easing curve for a bounce (exponentially decaying parabolic bounce) function: decelerating from zero velocity. \o \inlineimage qeasingcurve-outbounce.png \row - \o \c easeInOutBounce + \o \c InOutBounce \o Easing curve for a bounce (exponentially decaying parabolic bounce) function easing in/out: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutbounce.png \row - \o \c easeOutInBounce + \o \c OutInBounce \o Easing curve for a bounce (exponentially decaying parabolic bounce) function easing out/in: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outinbounce.png \endtable */ -QString QmlPropertyAnimation::easing() const +QEasingCurve QmlPropertyAnimation::easing() const { Q_D(const QmlPropertyAnimation); return d->easing; } -void QmlPropertyAnimation::setEasing(const QString &e) +void QmlPropertyAnimation::setEasing(const QEasingCurve &e) { Q_D(QmlPropertyAnimation); if (d->easing == e) return; d->easing = e; - d->va->setEasingCurve(stringToCurve(d->easing, this)); + d->va->setEasingCurve(d->easing); emit easingChanged(e); } diff --git a/src/declarative/util/qmlanimation_p.h b/src/declarative/util/qmlanimation_p.h index 623ad8d..fd868bc 100644 --- a/src/declarative/util/qmlanimation_p.h +++ b/src/declarative/util/qmlanimation_p.h @@ -51,6 +51,7 @@ #include <qmlscriptstring.h> #include <QtCore/qvariant.h> +#include <QtCore/qeasingcurve.h> #include <QtCore/QAbstractAnimation> #include <QtGui/qcolor.h> @@ -261,7 +262,7 @@ class Q_AUTOTEST_EXPORT QmlPropertyAnimation : public QmlAbstractAnimation Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged) Q_PROPERTY(QVariant from READ from WRITE setFrom NOTIFY fromChanged) Q_PROPERTY(QVariant to READ to WRITE setTo NOTIFY toChanged) - Q_PROPERTY(QString easing READ easing WRITE setEasing NOTIFY easingChanged) + Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged) Q_PROPERTY(QObject *target READ target WRITE setTarget NOTIFY targetChanged) Q_PROPERTY(QString property READ property WRITE setProperty NOTIFY targetChanged) Q_PROPERTY(QString properties READ properties WRITE setProperties NOTIFY propertiesChanged) @@ -281,8 +282,8 @@ public: QVariant to() const; void setTo(const QVariant &); - QString easing() const; - void setEasing(const QString &); + QEasingCurve easing() const; + void setEasing(const QEasingCurve &); QObject *target() const; void setTarget(QObject *); @@ -307,7 +308,7 @@ Q_SIGNALS: void durationChanged(int); void fromChanged(QVariant); void toChanged(QVariant); - void easingChanged(const QString &); + void easingChanged(const QEasingCurve &); void propertiesChanged(const QString &); void targetChanged(QObject *, const QString &); }; diff --git a/src/declarative/util/qmlanimation_p_p.h b/src/declarative/util/qmlanimation_p_p.h index 056ce82..8c88f14 100644 --- a/src/declarative/util/qmlanimation_p_p.h +++ b/src/declarative/util/qmlanimation_p_p.h @@ -327,7 +327,7 @@ public: QVariant from; QVariant to; - QString easing; + QEasingCurve easing; QObject *target; QString propertyName; diff --git a/src/declarative/util/qmlpropertychanges.cpp b/src/declarative/util/qmlpropertychanges.cpp index 068cb4d..3abbadd 100644 --- a/src/declarative/util/qmlpropertychanges.cpp +++ b/src/declarative/util/qmlpropertychanges.cpp @@ -47,7 +47,7 @@ #include <qmlcustomparser_p.h> #include <qmlparser_p.h> #include <qmlexpression.h> -#include <qmlbinding.h> +#include <qmlbinding_p.h> #include <qmlcontext.h> #include <qmlguard_p.h> @@ -277,14 +277,12 @@ void QmlPropertyChangesPrivate::decode() QmlMetaProperty prop = property(name); //### better way to check for signal property? if (prop.type() & QmlMetaProperty::SignalProperty) { QmlExpression *expression = new QmlExpression(qmlContext(q), data.toString(), object); - expression->setTrackChange(false); QmlReplaceSignalHandler *handler = new QmlReplaceSignalHandler; handler->property = prop; handler->expression = expression; signalReplacements << handler; } else if (isScript) { QmlExpression *expression = new QmlExpression(qmlContext(q), data.toString(), object); - expression->setTrackChange(false); expressions << qMakePair(name, expression); } else { properties << qMakePair(name, data); diff --git a/src/declarative/util/qmlstate.cpp b/src/declarative/util/qmlstate.cpp index 4462b1f..ea99bd5 100644 --- a/src/declarative/util/qmlstate.cpp +++ b/src/declarative/util/qmlstate.cpp @@ -48,7 +48,7 @@ #include "qmlanimation_p.h" #include "qmlanimation_p_p.h" -#include <qmlbinding.h> +#include <qmlbinding_p.h> #include <qmlglobal_p.h> #include <QtCore/qdebug.h> diff --git a/src/declarative/util/qmlstategroup.cpp b/src/declarative/util/qmlstategroup.cpp index 4ad77c8..7a5db1b 100644 --- a/src/declarative/util/qmlstategroup.cpp +++ b/src/declarative/util/qmlstategroup.cpp @@ -44,7 +44,7 @@ #include "qmltransition_p.h" #include "qmlstate_p_p.h" -#include <qmlbinding.h> +#include <qmlbinding_p.h> #include <qmlglobal_p.h> #include <QtCore/qdebug.h> diff --git a/src/declarative/util/qmlstateoperations.cpp b/src/declarative/util/qmlstateoperations.cpp index bd1f5f0..fff8774 100644 --- a/src/declarative/util/qmlstateoperations.cpp +++ b/src/declarative/util/qmlstateoperations.cpp @@ -373,7 +373,6 @@ void QmlStateChangeScript::execute() const QString &script = d->script.script(); if (!script.isEmpty()) { QmlExpression expr(d->script.context(), script, d->script.scopeObject()); - expr.setTrackChange(false); expr.value(); } } diff --git a/src/declarative/util/qmltransitionmanager.cpp b/src/declarative/util/qmltransitionmanager.cpp index f2a4d64..60d9a60 100644 --- a/src/declarative/util/qmltransitionmanager.cpp +++ b/src/declarative/util/qmltransitionmanager.cpp @@ -43,7 +43,7 @@ #include "qmlstate_p_p.h" -#include <qmlbinding.h> +#include <qmlbinding_p.h> #include <qmlglobal_p.h> QT_BEGIN_NAMESPACE diff --git a/src/declarative/util/qmlview.cpp b/src/declarative/util/qmlview.cpp index 8844430..9e95b66 100644 --- a/src/declarative/util/qmlview.cpp +++ b/src/declarative/util/qmlview.cpp @@ -132,6 +132,8 @@ public: QmlViewPrivate(QmlView *view) : q(view), root(0), component(0), resizeMode(QmlView::SizeViewToRootObject) {} + void execute(); + QmlView *q; QGuard<QGraphicsObject> root; @@ -152,6 +154,20 @@ public: QGraphicsScene scene; }; +void QmlViewPrivate::execute() +{ + delete root; + delete component; + component = new QmlComponent(&engine, source, q); + + if (!component->isLoading()) { + q->continueExecute(); + } else { + QObject::connect(component, SIGNAL(statusChanged(QmlComponent::Status)), q, SLOT(continueExecute())); + } +} + + /*! \class QmlView \brief The QmlView class provides a widget for displaying a Qt Declarative user interface. @@ -188,9 +204,6 @@ public: QUrl url(fileName); view->setSource(url); - ... - view->execute(); - ... view->show(); \endcode @@ -220,6 +233,19 @@ QmlView::QmlView(QWidget *parent) d->init(); } +/*! + \fn QmlView::QmlView(const QUrl &source, QWidget *parent) + + Constructs a QmlView with the given QML \a source and \a parent. +*/ +QmlView::QmlView(const QUrl &source, QWidget *parent) +: QGraphicsView(parent), d(new QmlViewPrivate(this)) +{ + setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred); + d->init(); + setSource(source); +} + void QmlViewPrivate::init() { #ifdef Q_ENABLE_PERFORMANCE_LOG @@ -254,15 +280,14 @@ QmlView::~QmlView() } /*! - Sets the source to the \a url. - - Call \l execute() to load the QML and instantiate the component. - - \sa execute() + Sets the source to the \a url, loads the QML component and instantiates it. */ void QmlView::setSource(const QUrl& url) { - d->source = url; + if (url != d->source) { + d->source = url; + d->execute(); + } } /*! @@ -296,23 +321,6 @@ QmlContext* QmlView::rootContext() return d->engine.rootContext(); } -/*! - Loads and instantiates the QML component set by the \l setSource() method. - - \sa setSource() -*/ -void QmlView::execute() -{ - delete d->root; - delete d->component; - d->component = new QmlComponent(&d->engine, d->source, this); - - if (!d->component->isLoading()) { - continueExecute(); - } else { - connect(d->component, SIGNAL(statusChanged(QmlComponent::Status)), this, SLOT(continueExecute())); - } -} /*! \enum QmlView::Status diff --git a/src/declarative/util/qmlview.h b/src/declarative/util/qmlview.h index c5e57c2..26be18f 100644 --- a/src/declarative/util/qmlview.h +++ b/src/declarative/util/qmlview.h @@ -67,6 +67,7 @@ class Q_DECLARATIVE_EXPORT QmlView : public QGraphicsView public: explicit QmlView(QWidget *parent = 0); + QmlView(const QUrl &source, QWidget *parent = 0); virtual ~QmlView(); QUrl source() const; @@ -74,7 +75,6 @@ public: QmlEngine* engine(); QmlContext* rootContext(); - void execute(); QGraphicsObject *rootObject() const; @@ -103,6 +103,7 @@ protected: virtual void timerEvent(QTimerEvent*); virtual void setRootObject(QObject *obj); + friend class QmlViewPrivate; QmlViewPrivate *d; }; diff --git a/src/declarative/util/qmlxmllistmodel.cpp b/src/declarative/util/qmlxmllistmodel.cpp index e631cd9..6c9c03e 100644 --- a/src/declarative/util/qmlxmllistmodel.cpp +++ b/src/declarative/util/qmlxmllistmodel.cpp @@ -63,6 +63,8 @@ QT_BEGIN_NAMESPACE QML_DEFINE_TYPE(Qt,4,6,XmlRole,QmlXmlListModelRole) QML_DEFINE_TYPE(Qt,4,6,XmlListModel,QmlXmlListModel) +typedef QPair<int, int> QmlXmlListRange; + /*! \qmlclass XmlRole QmlXmlListModelRole \brief The XmlRole element allows you to specify a role for an XmlListModel. @@ -94,14 +96,26 @@ QML_DEFINE_TYPE(Qt,4,6,XmlListModel,QmlXmlListModel) \endqml */ +/*! + \qmlproperty bool XmlRole::isKey + Defines whether this is a key role. + + Key roles are used to to determine whether a set of values should + be updated or added to the XML list model when XmlListModel::reload() + is called. + + \sa XmlListModel +*/ + class Q_DECLARATIVE_EXPORT QmlXmlListModelRole : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName) Q_PROPERTY(QString query READ query WRITE setQuery) + Q_PROPERTY(bool isKey READ isKey WRITE setIsKey) public: - QmlXmlListModelRole() {} + QmlXmlListModelRole() : m_isKey(false) {} ~QmlXmlListModelRole() {} QString name() const { return m_name; } @@ -117,6 +131,9 @@ public: m_query = query; } + bool isKey() const { return m_isKey; } + void setIsKey(bool b) { m_isKey = b; } + bool isValid() { return !m_name.isEmpty() && !m_query.isEmpty(); } @@ -124,6 +141,7 @@ public: private: QString m_name; QString m_query; + bool m_isKey; }; QT_END_NAMESPACE QML_DECLARE_TYPE(QmlXmlListModelRole) @@ -153,7 +171,6 @@ public: int doQuery(QString query, QString namespaces, QByteArray data, QList<QmlXmlListModelRole *> *roleObjects) { QMutexLocker locker(&m_mutex); - m_modelData.clear(); m_size = 0; m_data = data; m_query = QLatin1String("doc($src)") + query; @@ -175,6 +192,16 @@ public: return m_modelData; } + QList<QmlXmlListRange> insertedItemRanges() { + QMutexLocker locker(&m_mutex); + return m_insertedItemRanges; + } + + QList<QmlXmlListRange> removedItemRanges() { + QMutexLocker locker(&m_mutex); + return m_removedItemRanges; + } + Q_SIGNALS: void queryCompleted(int queryId, int size); @@ -184,13 +211,12 @@ protected: m_mutex.lock(); int queryId = m_queryId; doQueryJob(); - if (m_size > 0) - doSubQueryJob(); + doSubQueryJob(); m_data.clear(); // no longer needed m_mutex.unlock(); m_mutex.lock(); - if (!m_abort && m_size > 0) + if (!m_abort) emit queryCompleted(queryId, m_size); if (!m_restart) m_condition.wait(&m_mutex); @@ -203,6 +229,8 @@ protected: private: void doQueryJob(); void doSubQueryJob(); + void getValuesOfKeyRoles(QStringList *values, QXmlQuery *query) const; + void addIndexToRangeList(QList<QmlXmlListRange> *ranges, int index) const; private: QMutex m_mutex; @@ -218,6 +246,9 @@ private: int m_queryId; const QList<QmlXmlListModelRole *> *m_roleObjects; QList<QList<QVariant> > m_modelData; + QStringList m_keysValues; + QList<QmlXmlListRange> m_insertedItemRanges; + QList<QmlXmlListRange> m_removedItemRanges; }; void QmlXmlQuery::doQueryJob() @@ -262,6 +293,40 @@ void QmlXmlQuery::doQueryJob() m_size = count; } +void QmlXmlQuery::getValuesOfKeyRoles(QStringList *values, QXmlQuery *query) const +{ + QStringList keysQueries; + for (int i=0; i<m_roleObjects->count(); i++) { + if (m_roleObjects->at(i)->isKey()) + keysQueries << m_roleObjects->at(i)->query(); + } + QString keysQuery; + if (keysQueries.count() == 1) + keysQuery = m_prefix + keysQueries[0]; + else if (keysQueries.count() > 1) + keysQuery = m_prefix + QLatin1String("concat(") + keysQueries.join(QLatin1String(",")) + QLatin1String(")"); + + if (!keysQuery.isEmpty()) { + query->setQuery(keysQuery); + QXmlResultItems resultItems; + query->evaluateTo(&resultItems); + QXmlItem item(resultItems.next()); + while (!item.isNull()) { + values->append(item.toAtomicValue().toString()); + item = resultItems.next(); + } + } +} + +void QmlXmlQuery::addIndexToRangeList(QList<QmlXmlListRange> *ranges, int index) const { + if (ranges->isEmpty()) + ranges->append(qMakePair(index, 1)); + else if (ranges->last().first + ranges->last().second == index) + ranges->last().second += 1; + else + ranges->append(qMakePair(index, 1)); +} + void QmlXmlQuery::doSubQueryJob() { m_modelData.clear(); @@ -272,6 +337,35 @@ void QmlXmlQuery::doSubQueryJob() QXmlQuery subquery; subquery.bindVariable(QLatin1String("inputDocument"), &b); + QStringList keysValues; + getValuesOfKeyRoles(&keysValues, &subquery); + + // See if any values of key roles have been inserted or removed. + m_insertedItemRanges.clear(); + m_removedItemRanges.clear(); + if (m_keysValues.isEmpty()) { + m_insertedItemRanges << qMakePair(0, m_size); + } else { + if (keysValues != m_keysValues) { + QStringList temp; + for (int i=0; i<m_keysValues.count(); i++) { + if (!keysValues.contains(m_keysValues[i])) + addIndexToRangeList(&m_removedItemRanges, i); + else + temp << m_keysValues[i]; + } + + for (int i=0; i<keysValues.count(); i++) { + if (temp.count() == i || keysValues[i] != temp[i]) { + temp.insert(i, keysValues[i]); + addIndexToRangeList(&m_insertedItemRanges, i); + } + } + } + } + m_keysValues = keysValues; + + // Get the new values for each role. //### we might be able to condense even further (query for everything in one go) for (int i = 0; i < m_roleObjects->size(); ++i) { QmlXmlListModelRole *role = m_roleObjects->at(i); @@ -283,13 +377,13 @@ void QmlXmlQuery::doSubQueryJob() continue; } subquery.setQuery(m_prefix + QLatin1String("(let $v := ") + role->query() + QLatin1String(" return if ($v) then ") + role->query() + QLatin1String(" else \"\")")); - QXmlResultItems output3; - subquery.evaluateTo(&output3); - QXmlItem item(output3.next()); + QXmlResultItems resultItems; + subquery.evaluateTo(&resultItems); + QXmlItem item(resultItems.next()); QList<QVariant> resultList; while (!item.isNull()) { resultList << item.toAtomicValue(); //### we used to trim strings - item = output3.next(); + item = resultItems.next(); } //### should warn here if things have gone wrong. while (resultList.count() < m_size) @@ -392,25 +486,40 @@ void QmlXmlListModelPrivate::clear_role(QmlListProperty<QmlXmlListModelRole> *li /*! \qmlclass XmlListModel QmlXmlListModel - \brief The XmlListModel element allows you to specify a model using XPath expressions. + \brief The XmlListModel element is used to specify a model using XPath expressions. - XmlListModel allows you to construct a model from XML data that can then be used as a data source - for the view classes (ListView, PathView, GridView) and any other classes that interact with model - data (like Repeater). + XmlListModel is used to create a model from XML data that can be used as a data source + for the view classes (such as ListView, PathView, GridView) and other classes that interact with model + data (such as Repeater). - The following is an example of a model containing news from a Yahoo RSS feed: + Here is an example of a model containing news from a Yahoo RSS feed: \qml XmlListModel { id: feedModel source: "http://rss.news.yahoo.com/rss/oceania" query: "/rss/channel/item" XmlRole { name: "title"; query: "title/string()" } - XmlRole { name: "link"; query: "link/string()" } + XmlRole { name: "pubDate"; query: "pubDate/string()" } XmlRole { name: "description"; query: "description/string()" } } \endqml - \note The model is currently static, so the above is really just a snapshot of an RSS feed. To force a - reload of the entire model, you can call the reload function. + + You can also define certain roles as "keys" so that the model only adds data + that contains new values for these keys when reload() is called. + + For example, if the roles above were defined like this: + + \qml + XmlRole { name: "title"; query: "title/string()"; isKey: true } + XmlRole { name: "pubDate"; query: "pubDate/string()"; isKey: true } + \endqml + + Then when reload() is called, the model will only add new items with a + "title" and "pubDate" value combination that is not already present in + the model. + + This is useful to provide incremental updates and avoid repainting an + entire model in a view. */ QmlXmlListModel::QmlXmlListModel(QObject *parent) @@ -526,9 +635,9 @@ void QmlXmlListModel::setXml(const QString &xml) } /*! - \qmlproperty url XmlListModel::query + \qmlproperty string XmlListModel::query An absolute XPath query representing the base query for the model items. The query should start with - a '/' or '//'. + '/' or '//'. */ QString QmlXmlListModel::query() const { @@ -619,8 +728,13 @@ void QmlXmlListModel::componentComplete() /*! \qmlmethod XmlListModel::reload() - Reloads the model. All the existing model data will be removed, and the model - will be rebuilt from scratch. + Reloads the model. + + If no key roles have been specified, all existing model + data is removed, and the model is rebuilt from scratch. + + Otherwise, items are only added if the model does not already + contain items with matching key role values. */ void QmlXmlListModel::reload() { @@ -632,12 +746,8 @@ void QmlXmlListModel::reload() d->qmlXmlQuery.abort(); d->queryId = -1; - //clear existing data - int count = d->size; - d->size = 0; - d->data.clear(); - if (count > 0) - emit itemsRemoved(0, count); + if (d->size < 0) + d->size = 0; if (d->src.isEmpty() && d->xml.isEmpty()) return; @@ -704,12 +814,19 @@ void QmlXmlListModel::queryCompleted(int id, int size) Q_D(QmlXmlListModel); if (id != d->queryId) return; + bool sizeChanged = size != d->size; d->size = size; - if (size > 0) { - d->data = d->qmlXmlQuery.modelData(); - emit itemsInserted(0, d->size); + d->data = d->qmlXmlQuery.modelData(); + + QList<QmlXmlListRange> removed = d->qmlXmlQuery.removedItemRanges(); + for (int i=0; i<removed.count(); i++) + emit itemsRemoved(removed[i].first, removed[i].second); + QList<QmlXmlListRange> inserted = d->qmlXmlQuery.insertedItemRanges(); + for (int i=0; i<inserted.count(); i++) + emit itemsInserted(inserted[i].first, inserted[i].second); + + if (sizeChanged) emit countChanged(); - } } QT_END_NAMESPACE |