From e65a7e2f9955bb873c569fcb7e40dd645d9846c2 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Thu, 28 Feb 2013 09:13:23 -0800 Subject: [PATCH] Work with synchronous replies from a custom QNetworkAccessManager Forward port of e5783b79887299d094 from QtQuick 1. Task-number: QTBUG-27723 Change-Id: I4332dd72bb9d65167307c1ac5ce24e93b14cff5f Reviewed-by: Peter Hartmann --- src/qml/qml/qqmltypeloader.cpp | 27 +++++++++++--- tests/auto/qml/qqmlengine/tst_qqmlengine.cpp | 49 ++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 6 deletions(-) diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 5910f60..9547204 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -124,6 +124,7 @@ public: public slots: void finished(); void downloadProgress(qint64, qint64); + void manualFinished(QNetworkReply*); private: QQmlDataLoader *l; @@ -183,6 +184,14 @@ void QQmlDataLoaderNetworkReplyProxy::downloadProgress(qint64 bytesReceived, qin l->networkReplyProgress(reply, bytesReceived, bytesTotal); } +// This function is for when you want to shortcut the signals and call directly +void QQmlDataLoaderNetworkReplyProxy::manualFinished(QNetworkReply *reply) +{ + qint64 replySize = reply->size(); + l->networkReplyProgress(reply, replySize, replySize); + l->networkReplyFinished(reply); +} + /*! \class QQmlDataBlob @@ -1008,17 +1017,23 @@ void QQmlDataLoader::loadThread(QQmlDataBlob *blob) } else { QNetworkReply *reply = m_thread->networkAccessManager()->get(QNetworkRequest(blob->m_url)); - QObject *nrp = m_thread->networkReplyProxy(); - QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)), - nrp, SLOT(downloadProgress(qint64,qint64))); - QObject::connect(reply, SIGNAL(finished()), - nrp, SLOT(finished())); + QQmlDataLoaderNetworkReplyProxy *nrp = m_thread->networkReplyProxy(); + blob->addref(); m_networkReplies.insert(reply, blob); + + if (reply->isFinished()) { + nrp->manualFinished(reply); + } else { + QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)), + nrp, SLOT(downloadProgress(qint64,qint64))); + QObject::connect(reply, SIGNAL(finished()), + nrp, SLOT(finished())); + } + #ifdef DATABLOB_DEBUG qWarning("QQmlDataBlob: requested %s", qPrintable(blob->url().toString())); #endif - blob->addref(); } } diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp index 4e1ac22..9177ff5 100644 --- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp +++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +64,7 @@ public: private slots: void rootContext(); void networkAccessManager(); + void synchronousNetworkAccessManager(); void baseUrl(); void contextForObject(); void offlineStoragePath(); @@ -127,6 +129,53 @@ void tst_qqmlengine::networkAccessManager() delete engine; } +class ImmediateReply : public QNetworkReply { + + Q_OBJECT + +public: + ImmediateReply() { + setFinished(true); + } + virtual qint64 readData(char* , qint64 ) { + return 0; + } + virtual void abort() { } +}; + +class ImmediateManager : public QNetworkAccessManager { + + Q_OBJECT + +public: + ImmediateManager(QObject *parent = 0) : QNetworkAccessManager(parent) { + } + + QNetworkReply *createRequest(Operation, const QNetworkRequest & , QIODevice * outgoingData = 0) { + Q_UNUSED(outgoingData); + return new ImmediateReply; + } +}; + +class ImmediateFactory : public QQmlNetworkAccessManagerFactory { + +public: + QNetworkAccessManager *create(QObject *) { + return new ImmediateManager; + } +}; + +void tst_qqmlengine::synchronousNetworkAccessManager() +{ + ImmediateFactory factory; + QQmlEngine engine; + engine.setNetworkAccessManagerFactory(&factory); + QQmlComponent c(&engine, QUrl("myScheme://test.qml")); + // reply is finished, so should not be in loading state. + QVERIFY(!c.isLoading()); +} + + void tst_qqmlengine::baseUrl() { QQmlEngine engine; -- 1.7.2.5