Work with synchronous replies from a custom QNetworkAccessManager
authorAlan Alpert <aalpert@rim.com>
Thu, 28 Feb 2013 17:13:23 +0000 (09:13 -0800)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Mon, 4 Mar 2013 18:47:38 +0000 (19:47 +0100)
Forward port of e5783b79887299d094 from QtQuick 1.

Task-number: QTBUG-27723
Change-Id: I4332dd72bb9d65167307c1ac5ce24e93b14cff5f
Reviewed-by: Peter Hartmann <phartmann@rim.com>

src/qml/qml/qqmltypeloader.cpp
tests/auto/qml/qqmlengine/tst_qqmlengine.cpp

index 5910f60..9547204 100644 (file)
@@ -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();
     }
 }
 
index 4e1ac22..9177ff5 100644 (file)
@@ -48,6 +48,7 @@
 #include <QStandardPaths>
 #include <QSignalSpy>
 #include <QDebug>
+#include <QBuffer>
 #include <QQmlComponent>
 #include <QQmlNetworkAccessManagerFactory>
 #include <QQmlExpression>
@@ -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;