From 6158ab6eb38f28dda2e79d0f1a0ce2e7149b73d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Burak=20Han=C3=A7erli?= <burak.hancerli@qt.io>
Date: Wed, 6 Mar 2024 10:41:48 +0000
Subject: [PATCH] QDS-12001 Downloads can be safely interrupted now

---
 src/backend.cpp          | 72 +++++++++++++++++++++++-----------------
 src/backend.h            |  3 +-
 src/dsconnector.cpp      |  2 +-
 src/dsconnector.h        |  1 +
 src/serviceconnector.cpp |  5 +++
 src/serviceconnector.h   |  1 +
 ui/main.qml              |  9 +++++
 7 files changed, 61 insertions(+), 32 deletions(-)

diff --git a/src/backend.cpp b/src/backend.cpp
index 7a5d26d..e88b71e 100644
--- a/src/backend.cpp
+++ b/src/backend.cpp
@@ -170,37 +170,43 @@ void Backend::initDesignStudioConnector()
         updatePopup("Receiving project...");
     });
 
-    connect(m_designStudioConnector.data(),
-            &DesignStudioConnector::projectReceived,
-            this,
-            [this](const QByteArray &projectData) {
-                qDebug() << "Project received from Design Studio";
-                initializeProjectManager();
-                emit popupOpen();
-                updatePopup("Unpacking project...");
-                qDebug() << "Project data size: " << projectData.size();
-                const QString projectPath = m_projectManager->unpackProject(projectData);
-
-                if (projectPath.isEmpty()) {
-                    qCritical() << "Could not unpack project. Please check the logs for more "
-                                   "information.";
-                    emit popupClose();
-                    return;
-                }
-
-                qDebug() << "Project unpacked to " << projectPath;
-                updatePopup("Running project...");
-
-                if (!m_projectManager->runProject(projectPath)) {
-                    qCritical() << "Could not run project. Please check the logs for more "
-                                   "information.";
-                } else {
-                    m_projectManager->showAppWindow();
-                }
-
+    connect(
+        m_designStudioConnector.data(),
+        &DesignStudioConnector::projectReceived,
+        this,
+        [this](const QByteArray &projectData) {
+            qDebug() << "Project received from Design Studio";
+            initializeProjectManager();
+            emit popupOpen();
+            updatePopup("Unpacking project...");
+            qDebug() << "Project data size: " << projectData.size();
+            const QString projectPath = m_projectManager->unpackProject(projectData);
+
+            if (projectPath.isEmpty()) {
+                qCritical() << "Could not unpack project. Please check the logs for more "
+                               "information.";
                 emit popupClose();
-                m_designStudioConnector->sendProjectReceived();
-            });
+                return;
+            }
+
+            qDebug() << "Project unpacked to " << projectPath;
+            updatePopup("Running project...");
+
+            qDebug() << "Project received confirmation sent to Design Studio";
+            if (!m_projectManager->runProject(projectPath)) {
+                qCritical() << "Could not run project. Please check the logs for more "
+                               "information.";
+            } else {
+                m_projectManager->showAppWindow();
+            }
+
+            QMetaObject::invokeMethod(m_designStudioConnector.data(),
+                                      "sendProjectReceived",
+                                      Qt::QueuedConnection);
+
+            emit popupClose();
+        },
+        Qt::QueuedConnection);
 
     qDebug() << "Design Studio Connector is initialized";
 }
@@ -429,3 +435,9 @@ void Backend::parseDesignViewerUrl(const QUrl &url)
         qWarning() << "Unknown QR code data: " << urlData;
     }
 }
+
+void Backend::popupInterrupted()
+{
+    qDebug() << "Popup closed prematurely. Interrupting active downloads (if any)";
+    QMetaObject::invokeMethod(&m_serviceConnector, "interrupted", Qt::QueuedConnection);
+}
diff --git a/src/backend.h b/src/backend.h
index 5ce42d7..c7f2090 100644
--- a/src/backend.h
+++ b/src/backend.h
@@ -56,7 +56,6 @@ private:
     QJsonArray m_projectList;
 
     // Other members
-
     ServiceConnector m_serviceConnector;
     QThread m_dsConnectorThread;
     QScopedPointer<ProjectManager> m_projectManager;
@@ -114,6 +113,8 @@ public slots:
     bool autoScaleProject();
     QString userHash();
 
+    void popupInterrupted();
+
 private slots:
     void initializeProjectManager();
     void enableBackgroundUpdate(const bool &enabled);
diff --git a/src/dsconnector.cpp b/src/dsconnector.cpp
index d82c31d..a608535 100644
--- a/src/dsconnector.cpp
+++ b/src/dsconnector.cpp
@@ -121,5 +121,5 @@ void DesignStudioConnector::sendProjectReceived()
     }
 
     m_tcpSocket->write("::qmlrc-received::");
-    m_tcpSocket->flush();
+    m_tcpSocket->waitForBytesWritten(3000);
 }
diff --git a/src/dsconnector.h b/src/dsconnector.h
index 2a5c193..66e1ec5 100644
--- a/src/dsconnector.h
+++ b/src/dsconnector.h
@@ -38,6 +38,7 @@ class DesignStudioConnector : public QObject
 public:
     explicit DesignStudioConnector(QObject *parent = nullptr);
 
+public slots:
     void sendProjectReceived();
 
 private:
diff --git a/src/serviceconnector.cpp b/src/serviceconnector.cpp
index 422709f..f8314f2 100644
--- a/src/serviceconnector.cpp
+++ b/src/serviceconnector.cpp
@@ -46,6 +46,11 @@ std::optional<QByteArray> ServiceConnector::fetchResource(const QString &url, co
                      });
 
     QEventLoop loop;
+    QObject::connect(this, &ServiceConnector::interrupted, reply.data(), [&]() {
+        qDebug() << "Aborting network request";
+        reply->abort();
+        loop.quit();
+    });
     QObject::connect(reply.data(), &QNetworkReply::finished, &loop, &QEventLoop::quit);
     QObject::connect(reply.data(),
                      &QNetworkReply::downloadProgress,
diff --git a/src/serviceconnector.h b/src/serviceconnector.h
index 07b18f1..9d5d4f5 100644
--- a/src/serviceconnector.h
+++ b/src/serviceconnector.h
@@ -49,6 +49,7 @@ private:
 
 signals:
     void downloadProgress(float percentage);
+    void interrupted();
 };
 
 #endif // SERVICECONNECTOR_H
diff --git a/ui/main.qml b/ui/main.qml
index 4b69f68..c10ec23 100644
--- a/ui/main.qml
+++ b/ui/main.qml
@@ -35,6 +35,7 @@ Rectangle {
     }
 
     Popup {
+        property var popupCloseReceived : false
         id: popup
         anchors.centerIn: parent
         width: 300
@@ -43,6 +44,12 @@ Rectangle {
         focus: true
         closePolicy: Popup.CloseOnEscape
 
+        onClosed: {
+            if (!popupCloseReceived) {
+                backend.popupInterrupted();
+            }
+        }
+
         ColumnLayout {
             anchors.fill: parent
             Text {
@@ -62,8 +69,10 @@ Rectangle {
             target: backend
             function onPopupOpen() {
                 popup.open()
+                popup.popupCloseReceived = false
             }
             function onPopupClose() {
+                popup.popupCloseReceived = true
                 popup.close()
             }
             function onPopupTextChanged(text) {
-- 
GitLab