From cdc50db23a89721f793ef353fb4d64b0631456c0 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 7 Sep 2009 16:19:33 +1000 Subject: Add status and progress properties to Loader. --- src/declarative/QmlChanges.txt | 1 + src/declarative/fx/qfxloader.cpp | 65 ++++++++++++++++++++++++- src/declarative/fx/qfxloader.h | 13 ++++- src/declarative/qml/qmlcomponent.cpp | 23 +++++++-- src/declarative/qml/qmlcomponent.h | 3 ++ src/declarative/qml/qmlcomponent_p.h | 4 +- src/declarative/qml/qmlcompositetypedata_p.h | 2 + src/declarative/qml/qmlcompositetypemanager.cpp | 17 +++++++ src/declarative/qml/qmlcompositetypemanager_p.h | 1 + 9 files changed, 120 insertions(+), 9 deletions(-) diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 8247a35..e63eb8b 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -65,6 +65,7 @@ MouseRegion: add "hoverEnabled" property MouseRegion: add "pressedButtons" property Timer: add start() and stop() slots WebView: add newWindowComponent and newWindowParent properties +Loader: add status() and progress() properties Deletions: Column/VerticalPositioner: lost "margins" property diff --git a/src/declarative/fx/qfxloader.cpp b/src/declarative/fx/qfxloader.cpp index 95ddae3..869a5b0 100644 --- a/src/declarative/fx/qfxloader.cpp +++ b/src/declarative/fx/qfxloader.cpp @@ -111,9 +111,12 @@ void QFxLoader::setSource(const QUrl &url) d->source = url; d->item = 0; + emit itemChanged(); if (d->source.isEmpty()) { emit sourceChanged(); + emit statusChanged(); + emit progressChanged(); return; } @@ -122,14 +125,22 @@ void QFxLoader::setSource(const QUrl &url) (*iter)->setOpacity(1.); d->item = (*iter); emit sourceChanged(); + emit statusChanged(); + emit progressChanged(); + emit itemChanged(); } else { d->qmlcomp = new QmlComponent(qmlEngine(this), d->source, this); - if (!d->qmlcomp->isLoading()) + if (!d->qmlcomp->isLoading()) { d->_q_sourceLoaded(); - else + } else { connect(d->qmlcomp, SIGNAL(statusChanged(QmlComponent::Status)), this, SLOT(_q_sourceLoaded())); + connect(d->qmlcomp, SIGNAL(progressChanged(qreal)), + this, SIGNAL(progressChanged())); + emit statusChanged(); + emit progressChanged(); + } } } @@ -146,6 +157,8 @@ void QFxLoaderPrivate::_q_sourceLoaded() delete qmlcomp; qmlcomp = 0; emit q->sourceChanged(); + emit q->statusChanged(); + emit q->progressChanged(); return; } QObject *obj = qmlcomp->create(ctxt); @@ -163,10 +176,58 @@ void QFxLoaderPrivate::_q_sourceLoaded() delete qmlcomp; qmlcomp = 0; emit q->sourceChanged(); + emit q->statusChanged(); + emit q->progressChanged(); + emit q->itemChanged(); } } /*! + \qmlproperty enum Loader::status + + This property holds the status of QML loading. It can be one of: + \list + \o Null - no QML source has been set + \o Ready - the QML source has been loaded + \o Loading - the QML source is currently being loaded + \o Error - an error occurred while loading the QML source + \endlist + + \sa progress +*/ + +/*! + \qmlproperty real Loader::progress + + This property holds the progress of QML data loading, from 0.0 (nothing loaded) + to 1.0 (finished). + + \sa status +*/ +QFxLoader::Status QFxLoader::status() const +{ + Q_D(const QFxLoader); + + if (d->qmlcomp) + return static_cast(d->qmlcomp->status()); + + if (d->item) + return Ready; + + return d->source.isEmpty() ? Null : Error; +} + +qreal QFxLoader::progress() const +{ + Q_D(const QFxLoader); + + if (d->qmlcomp) + return d->qmlcomp->progress(); + + return d->item ? 1.0 : 0.0; +} + +/*! \qmlproperty Item Loader::item This property holds the top-level item created from source. */ diff --git a/src/declarative/fx/qfxloader.h b/src/declarative/fx/qfxloader.h index 8c555c6..132c8f4 100644 --- a/src/declarative/fx/qfxloader.h +++ b/src/declarative/fx/qfxloader.h @@ -54,12 +54,14 @@ class QFxLoaderPrivate; class Q_DECLARATIVE_EXPORT QFxLoader : public QFxItem { Q_OBJECT + Q_ENUMS(Status) Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) - Q_PROPERTY(QFxItem *item READ item) //### NOTIFY itemChanged + Q_PROPERTY(QFxItem *item READ item NOTIFY itemChanged) + Q_PROPERTY(Status status READ status NOTIFY statusChanged) + Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged) //### sourceItem //### sourceComponent - //### status, progress //### resizeMode { NoResize, SizeLoaderToItem (default), SizeItemToLoader } public: @@ -69,10 +71,17 @@ public: QUrl source() const; void setSource(const QUrl &); + enum Status { Null, Ready, Loading, Error }; + Status status() const; + qreal progress() const; + QFxItem *item() const; Q_SIGNALS: + void itemChanged(); void sourceChanged(); + void statusChanged(); + void progressChanged(); private: Q_DISABLE_COPY(QFxLoader) diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp index e897cce..f291ac0 100644 --- a/src/declarative/qml/qmlcomponent.cpp +++ b/src/declarative/qml/qmlcomponent.cpp @@ -121,6 +121,14 @@ void QmlComponentPrivate::typeDataReady() emit q->statusChanged(q->status()); } +void QmlComponentPrivate::updateProgress(qreal p) +{ + Q_Q(QmlComponent); + + progress = p; + emit q->progressChanged(p); +} + void QmlComponentPrivate::fromTypeData(QmlCompositeTypeData *data) { url = data->imports.baseUrl(); @@ -238,6 +246,12 @@ bool QmlComponent::isLoading() const return status() == Loading; } +qreal QmlComponent::progress() const +{ + Q_D(const QmlComponent); + return d->progress; +} + /*! \fn void QmlComponent::statusChanged(QmlComponent::Status status) @@ -343,7 +357,9 @@ void QmlComponent::setData(const QByteArray &data, const QUrl &url) } + d->progress = 1.0; emit statusChanged(status()); + emit progressChanged(d->progress); } /*! @@ -364,17 +380,16 @@ void QmlComponent::loadUrl(const QUrl &url) QmlEnginePrivate::get(d->engine)->typeManager.get(d->url); if (data->status == QmlCompositeTypeData::Waiting) { - d->typeData = data; d->typeData->addWaiter(d); - + d->progress = data->progress; } else { - d->fromTypeData(data); - + d->progress = 1.0; } emit statusChanged(status()); + emit progressChanged(d->progress); } /*! diff --git a/src/declarative/qml/qmlcomponent.h b/src/declarative/qml/qmlcomponent.h index 60b7ccd..af250e5 100644 --- a/src/declarative/qml/qmlcomponent.h +++ b/src/declarative/qml/qmlcomponent.h @@ -84,6 +84,8 @@ public: QList errors() const; + qreal progress() const; + QUrl url() const; virtual QObject *create(QmlContext *context = 0); @@ -95,6 +97,7 @@ public: Q_SIGNALS: void statusChanged(QmlComponent::Status); + void progressChanged(qreal); protected: QmlComponent(QmlComponentPrivate &dd, QObject* parent); diff --git a/src/declarative/qml/qmlcomponent_p.h b/src/declarative/qml/qmlcomponent_p.h index 4b459c2..2b25b78 100644 --- a/src/declarative/qml/qmlcomponent_p.h +++ b/src/declarative/qml/qmlcomponent_p.h @@ -74,15 +74,17 @@ class QmlComponentPrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QmlComponent) public: - QmlComponentPrivate() : typeData(0), start(-1), count(-1), cc(0), completePending(false), engine(0) {} + QmlComponentPrivate() : typeData(0), progress(0.), start(-1), count(-1), cc(0), completePending(false), engine(0) {} QmlCompositeTypeData *typeData; void typeDataReady(); + void updateProgress(qreal); void fromTypeData(QmlCompositeTypeData *data); QList errors; QUrl url; + qreal progress; int start; int count; diff --git a/src/declarative/qml/qmlcompositetypedata_p.h b/src/declarative/qml/qmlcompositetypedata_p.h index 54933c4..044b4ca 100644 --- a/src/declarative/qml/qmlcompositetypedata_p.h +++ b/src/declarative/qml/qmlcompositetypedata_p.h @@ -108,6 +108,8 @@ struct QmlCompositeTypeData : public QmlRefCount void addWaiter(QmlComponentPrivate *p); void remWaiter(QmlComponentPrivate *p); + qreal progress; + private: friend class QmlCompositeTypeManager; friend class QmlCompiler; diff --git a/src/declarative/qml/qmlcompositetypemanager.cpp b/src/declarative/qml/qmlcompositetypemanager.cpp index f64547c..45d5488 100644 --- a/src/declarative/qml/qmlcompositetypemanager.cpp +++ b/src/declarative/qml/qmlcompositetypemanager.cpp @@ -234,9 +234,26 @@ void QmlCompositeTypeManager::loadSource(QmlCompositeTypeData *unit) engine->networkAccessManager()->get(QNetworkRequest(url)); QObject::connect(reply, SIGNAL(finished()), this, SLOT(replyFinished())); + QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)), + this, SLOT(requestProgress(qint64,qint64))); } } +void QmlCompositeTypeManager::requestProgress(qint64 received, qint64 total) +{ + if (total <= 0) + return; + QNetworkReply *reply = static_cast(sender()); + + QmlCompositeTypeData *unit = components.value(reply->url().toString()); + Q_ASSERT(unit); + + unit->progress = qreal(received)/total; + + foreach (QmlComponentPrivate *comp, unit->waiters) + comp->updateProgress(unit->progress); +} + void QmlCompositeTypeManager::setData(QmlCompositeTypeData *unit, const QByteArray &data, const QUrl &url) diff --git a/src/declarative/qml/qmlcompositetypemanager_p.h b/src/declarative/qml/qmlcompositetypemanager_p.h index cb0fc43..b401b44 100644 --- a/src/declarative/qml/qmlcompositetypemanager_p.h +++ b/src/declarative/qml/qmlcompositetypemanager_p.h @@ -87,6 +87,7 @@ public: private Q_SLOTS: void replyFinished(); + void requestProgress(qint64 received, qint64 total); private: void loadSource(QmlCompositeTypeData *); -- cgit v0.12