From 2e51af59005f78f53309992d1b51ab4d253f15a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Han=C3=A7erli?= <burak.hancerli@qt.io> Date: Tue, 14 Jan 2025 11:25:23 +0000 Subject: [PATCH] QDS-14287 Support interruptable operations --- CMakeLists.txt | 9 +- src/CMakeLists.txt | 3 +- src/HomePage.qml | 27 ++++- src/backend/backend.cpp | 77 +++++++++----- src/backend/backend.h | 1 + src/backend/dsconnector/ds.cpp | 144 ++++++++++++++++++++------ src/backend/dsconnector/ds.h | 31 +++--- src/backend/dsconnector/dsmanager.cpp | 31 +++--- src/backend/dsconnector/dsmanager.h | 4 +- src/backend/importdummy.qml | 3 + src/backend/projectmanager.cpp | 8 +- src/backend/projectmanager.h | 7 +- 12 files changed, 238 insertions(+), 107 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ffdee5d..42061f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,16 +47,15 @@ execute_process(COMMAND git -C ${CMAKE_SOURCE_DIR}/3rdparty/zxing-cpp describe - add_definitions( -DCMAKE_VAR_GIT_VERSION="${CMAKE_VAR_GIT_VERSION}" ) add_definitions( -DCMAKE_VAR_QT_QUICK_COMPONENTS_VERSION="${CMAKE_VAR_QT_QUICK_COMPONENTS_VERSION}" ) add_definitions( -DCMAKE_VAR_ZXING_VERSION="${CMAKE_VAR_ZXING_VERSION}" ) - -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/zxing-cpp) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tests) - # this needs to be increased with every new release if(NOT DEFINED GOOGLE_PLAY_APP_VERSION) set(GOOGLE_PLAY_APP_VERSION 31) endif() +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/zxing-cpp) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tests) + message(STATUS "GOOGLE_PLAY_APP_VERSION: ${GOOGLE_PLAY_APP_VERSION}") message(STATUS "PROJECT VERSION: ${CMAKE_VAR_GIT_VERSION}") message(STATUS "QT_VERSION: ${QT_VERSION}") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c140b57..4330115 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -78,7 +78,7 @@ target_include_directories(qtuiviewerlib PUBLIC set_target_properties(${PROJECT_NAME} PROPERTIES QT_ANDROID_PACKAGE_NAME "io.qt.qtdesignviewer") set_property(TARGET ${PROJECT_NAME} - APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/android +APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/android ) set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY QT_ANDROID_EXTRA_LIBS @@ -86,5 +86,6 @@ set_property(TARGET ${PROJECT_NAME} ${ANDROID_OPENSSL_PATH}/libssl_3.so ) + # CMAKE_VAR_GIT_VERSION (coming from the top-level CMakeLists.txt) and GOOGLE_PLAY_APP_VERSION replaced in the following file configure_file(${CMAKE_CURRENT_SOURCE_DIR}/android/AndroidManifest.xml.in ${CMAKE_CURRENT_SOURCE_DIR}/android/AndroidManifest.xml) diff --git a/src/HomePage.qml b/src/HomePage.qml index d00944a..f5b8bfb 100644 --- a/src/HomePage.qml +++ b/src/HomePage.qml @@ -101,7 +101,7 @@ Flickable { } Repeater { - model: [qsTr("Open Qt Design Studio"), qsTr("Click Play > Manage Run Targets"), qsTr("In Manage Run Targets window click Add run target button.")] + model: [qsTr("Open up the Qt Design Studio, and a project"), qsTr("Click on the dropdown menu of the Play button in the header"), qsTr("Select Open Device Manager from the menu"), qsTr("In the Device Manager window click on Set Device IP and type in the IP address found from below")] delegate: RowLayout { Layout.fillWidth: true @@ -150,16 +150,35 @@ Flickable { Layout.fillWidth: true text: qsTr("xxx.xxx.xxx.xxx") font.pixelSize: Constants.lgTextSize - font.bold: true + font.bold: false wrapMode: Text.WordWrap - Component.onCompleted: { + function updateIpAddresses() { ipAddress.text = ''; var val = backend.getIpAddresses(); - for(var i = 0; i < val.length; i++) { + + if(val.length === 0) + ipAddress.text = qsTr("Not connected to any network."); + + for(var i = 0; i < val.length; i++) ipAddress.text += val[i].interface + ': ' + val[i].ip + '\n'; + } + + Timer { + id: timer + interval: 1000 + running: true + repeat: true + + onTriggered: { + ipAddress.updateIpAddresses(); } } + + Component.onCompleted: { + ipAddress.updateIpAddresses(); + timer.start(); + } } } } diff --git a/src/backend/backend.cpp b/src/backend/backend.cpp index cc2c8f7..8a5e82c 100644 --- a/src/backend/backend.cpp +++ b/src/backend/backend.cpp @@ -110,7 +110,7 @@ QString Backend::buildInfo() const // clang-format off return { QCoreApplication::applicationVersion() + - "\nTechnology Preview - "+ CMAKE_VAR_GIT_VERSION + + "\n"+ CMAKE_VAR_GIT_VERSION + "\nQt " + QT_VERSION_STR + " - " + buildType + " Build" + "\nQt Quick Components " + CMAKE_VAR_QT_QUICK_COMPONENTS_VERSION + "\nZXing-Cpp: " + CMAKE_VAR_ZXING_VERSION + @@ -138,12 +138,21 @@ void Backend::initProjectManager() { m_projectManager.reset(new ProjectManager(this)); - connect(m_projectManager.get(), &ProjectManager::closingProject, this, [this] { - QMetaObject::invokeMethod(m_dsManager.get(), - "sendProjectStopped", - Qt::QueuedConnection, - Q_ARG(QString, m_lastProjectSenderId)); - }); + connect(m_projectManager.get(), + &ProjectManager::closingProject, + this, + [this](const QString &sessionId) { + // most likely the project was running from the leftover session + // (DS connected, project started, DS disconnected without stopping the project) + // so we'll stop the project and do not send any signals to the DS + if (sessionId != m_lastSessionId) + return; + + QMetaObject::invokeMethod(m_dsManager.get(), + "sendProjectStopped", + Qt::QueuedConnection, + Q_ARG(QString, m_lastProjectSenderId)); + }); } void Backend::initDsManager() @@ -175,23 +184,36 @@ void Backend::initDsManager() connect(m_dsManager.get(), &DesignStudioManager::projectIncoming, this, - [this](const int projectSize) { + [this](const QString &id, const int projectSize) { qDebug() << "Project incoming with size" << projectSize; emit updatePopupText("Receiving project..."); + // we'll use this to notify the correct DS when the project started/stopped + m_lastProjectSenderId = id; + m_lastSessionId = QUuid::createUuid().toString(QUuid::WithoutBraces); + QMetaObject::invokeMethod(m_projectManager.get(), + "stopProject", + Qt::QueuedConnection); + }); - // connect(m_dsManager.get(), - // &DesignStudioManager::projectIncomingProgress, - // this, - // [this](const QString &id, const int percentage) { updatePopupProgress(percentage); }); + connect(m_dsManager.get(), + &DesignStudioManager::projectIncomingProgress, + this, + [this](const QString &id, const int percentage) { updatePopupProgress(percentage); }); connect(m_dsManager.get(), &DesignStudioManager::projectStopRequested, this, [this](const QString &id) { + qDebug() << "Project stop requested"; + emit popupClose(); QMetaObject::invokeMethod(m_projectManager.get(), "stopProject", Qt::QueuedConnection); + QMetaObject::invokeMethod(m_dsManager.get(), + "sendProjectStopped", + Qt::QueuedConnection, + Q_ARG(QString, m_lastProjectSenderId)); }); m_dsManager->init(); @@ -211,20 +233,22 @@ void Backend::runProject(const QString &id, const QByteArray &projectData) { emit updatePopupText("Running project..."); - // we'll use this to notify the correct DS when the project started/stopped - m_lastProjectSenderId = id; - QMetaObject::invokeMethod(m_dsManager.get(), "sendProjectRunning", Q_ARG(QString, id)); - bool retVal; - QMetaObject::invokeMethod(m_projectManager.get(), - "runProject", - Q_RETURN_ARG(bool, retVal), - Q_ARG(QByteArray, projectData), - Q_ARG(bool, autoScaleProject())); - - if (!retVal) - QMetaObject::invokeMethod(m_dsManager.get(), "sendProjectStopped", Q_ARG(QString, id)); - - emit popupClose(); + QTimer::singleShot(1000, [this, id, projectData] { + bool retVal; + QMetaObject::invokeMethod(m_projectManager.get(), + "runProject", + Q_RETURN_ARG(bool, retVal), + Q_ARG(QByteArray, projectData), + Q_ARG(bool, autoScaleProject()), + Q_ARG(QString, m_lastSessionId)); + + if (!retVal) + QMetaObject::invokeMethod(m_dsManager.get(), "sendProjectStopped", Q_ARG(QString, id)); + else + QMetaObject::invokeMethod(m_dsManager.get(), "sendProjectRunning", Q_ARG(QString, id)); + + emit popupClose(); + }); } void Backend::scanQrCode() @@ -310,7 +334,6 @@ QJsonArray Backend::getIpAddresses() const for (const auto &interface : networkInterface.allInterfaces()) { for (const auto &entry : interface.addressEntries()) { if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol && !entry.ip().isLoopback()) { - qDebug() << "Interface:" << interface.name() << "IP:" << entry.ip().toString(); ipAddresses.append( QJsonObject{{"interface", interface.name()}, {"ip", entry.ip().toString()}}); } diff --git a/src/backend/backend.h b/src/backend/backend.h index 072ce8d..27858b0 100644 --- a/src/backend/backend.h +++ b/src/backend/backend.h @@ -51,6 +51,7 @@ private: QScopedPointer<QrScanner> m_qrScanner; QString m_lastProjectSenderId; + QString m_lastSessionId; // Settings Settings m_settings; diff --git a/src/backend/dsconnector/ds.cpp b/src/backend/dsconnector/ds.cpp index 5554a41..464ec80 100644 --- a/src/backend/dsconnector/ds.cpp +++ b/src/backend/dsconnector/ds.cpp @@ -7,15 +7,48 @@ #include <QJsonObject> #include <QScreen> -DesignStudio::DesignStudio(QWebSocket *socket, const QString &m_deviceUuid, QObject *parent) +namespace PackageFromDesignStudio { +using namespace Qt::Literals; +constexpr auto designStudioReady = "designStudioReady"_L1; +constexpr auto projectData = "projectData"_L1; +constexpr auto stopRunningProject = "stopRunningProject"_L1; +}; // namespace PackageFromDesignStudio + +namespace PackageToDesignStudio { +using namespace Qt::Literals; +constexpr auto deviceInfo = "deviceInfo"_L1; +constexpr auto projectReceivingProgress = "projectReceivingProgress"_L1; +constexpr auto projectStarting = "projectStarting"_L1; +constexpr auto projectRunning = "projectRunning"_L1; +constexpr auto projectStopped = "projectStopped"_L1; +constexpr auto projectLogs = "projectLogs"_L1; +}; // namespace PackageToDesignStudio + +DesignStudio::DesignStudio(QWebSocket *socket, const QString &deviceID, QObject *parent) : QObject(parent) - , m_deviceUuid(m_deviceUuid) + , m_deviceID(deviceID) , m_socket(socket) { initPingPong(); initSocket(); + startPingPong(); + m_projectStallTimer.setInterval(5000); + m_projectStallTimer.setSingleShot(true); + connect(&m_projectStallTimer, &QTimer::timeout, this, [this]() { + qDebug() << "Project is stalled. Closing the connection."; + m_socket->close(); + m_socket->abort(); + emit disconnected(m_designStudioID); + }); - m_pingTimer.start(); + m_speedCalculator.setInterval(1000); + m_speedCalculator.setSingleShot(false); + connect(&m_speedCalculator, &QTimer::timeout, this, [this]() { + quint64 elapsedTime = m_projectNotificationTime.msecsTo(QTime::currentTime()) / 1000; + int receiveSpeed = elapsedTime > 0 ? m_projectData.size() / elapsedTime / 1024 : 0; + qDebug() << "Receive speed" << receiveSpeed << "KB/s (" << receiveSpeed / 1024 << "MB/s )" + << "percentage" << m_lastPercentage << "%"; + }); } void DesignStudio::initPingPong() @@ -27,7 +60,7 @@ void DesignStudio::initPingPong() connect(&m_pingTimer, &QTimer::timeout, this, [this]() { m_socket->ping(); - m_pongTimer.start(); + startPingPong(); }); connect(m_socket.data(), @@ -39,20 +72,32 @@ void DesignStudio::initPingPong() }); connect(&m_pongTimer, &QTimer::timeout, this, [this]() { - qDebug() << "Design Studio" << m_id << "is not responding. Closing the connection."; + qDebug() << "Design Studio" << m_designStudioID + << "is not responding. Closing the connection."; m_socket->close(); m_socket->abort(); - emit disconnected(m_id); + emit disconnected(m_designStudioID); }); } +void DesignStudio::stopPingPong() +{ + m_pingTimer.stop(); + m_pongTimer.stop(); +} + +void DesignStudio::startPingPong() +{ + m_pingTimer.start(); +} + void DesignStudio::initSocket() { connect(m_socket.data(), &QWebSocket::disconnected, this, [this]() { - qDebug() << "Design Studio" << m_id << "disconnected"; + qDebug() << "Design Studio" << m_designStudioID << "disconnected"; m_pingTimer.stop(); m_pongTimer.stop(); - emit disconnected(m_id); + emit disconnected(m_designStudioID); }); connect(m_socket.data(), @@ -61,20 +106,9 @@ void DesignStudio::initSocket() &DesignStudio::processTextMessage); connect(m_socket.data(), - &QWebSocket::binaryFrameReceived, + &QWebSocket::binaryMessageReceived, this, - [this](const QByteArray &frame, bool isLastFrame) { - m_projectData.append(frame); - int percentage = m_projectData.size() * 100 / m_incomingProjectSize; - qDebug() << "frame size:" << frame.size() << "current size:" << m_projectData.size() - << "total size:" << m_incomingProjectSize << "percentage:" << percentage - << "isLastFrame:" << isLastFrame; - emit projectIncomingProgress(m_id, - m_projectData.size() * 100 / m_incomingProjectSize); - if (isLastFrame) { - emit projectReceived(m_id, m_projectData); - } - }); + &DesignStudio::processBinaryMessage); } QString DesignStudio::ipv4Addr() const @@ -84,7 +118,7 @@ QString DesignStudio::ipv4Addr() const QString DesignStudio::id() const { - return m_id; + return m_designStudioID; } void DesignStudio::sendDeviceInfo() @@ -97,7 +131,7 @@ void DesignStudio::sendDeviceInfo() deviceInfo["os"] = QSysInfo::prettyProductName(); deviceInfo["osVersion"] = QSysInfo::productVersion(); deviceInfo["architecture"] = QSysInfo::currentCpuArchitecture(); - deviceInfo["deviceId"] = m_deviceUuid; + deviceInfo["deviceId"] = m_deviceID; deviceInfo["appVersion"] = QString(CMAKE_VAR_GIT_VERSION); qDebug() << "Sending device info to Design Studio" << deviceInfo; @@ -131,31 +165,73 @@ void DesignStudio::processTextMessage(const QString &message) } const QString dataType = jsonObj.value("dataType").toString(); + const QJsonObject data = jsonObj.value("data").toObject(); if (dataType == PackageFromDesignStudio::designStudioReady) { - const QString newDesignStudioId = jsonObj.value("data").toString(); - qDebug() << "Design Studio ready with ID" << newDesignStudioId; - m_id = newDesignStudioId; + const QString newDesignStudioId = data["designStudioID"].toString(); + const int commVersion = data["commVersion"].toInt(); + qDebug() << "Design Studio ready with ID" << newDesignStudioId << "and comm version" + << commVersion; + m_designStudioID = newDesignStudioId; sendDeviceInfo(); emit idReceived(newDesignStudioId, ipv4Addr()); } else if (dataType == PackageFromDesignStudio::projectData) { - m_incomingProjectSize = jsonObj.value("data").toInt(); - qDebug() << "Project is expected with size" << m_incomingProjectSize; + m_incomingProjectSize = data["projectSize"].toInt(); + const QString qtVersion = data["qtVersion"].toString(); + + auto qcompare = QString::compare(qtVersion, QT_VERSION_STR, Qt::CaseInsensitive); + if (qcompare != 0) { + qDebug() << "Qt version mismatch. Expected" << QT_VERSION_STR " or lower, but got" + << qtVersion << ". Project may not work correctly."; + emit projectVersionMismatch(QT_VERSION_STR, qtVersion); + } + + qDebug() << "Project is expected with size" << m_incomingProjectSize << "and Qt version" + << qtVersion; m_projectData.clear(); - emit projectIncoming(m_incomingProjectSize); + m_projectNotificationTime = QTime::currentTime(); + m_speedCalculator.start(); + m_projectStallTimer.start(); + + stopPingPong(); + emit projectIncoming(m_designStudioID, m_incomingProjectSize); } else if (dataType == PackageFromDesignStudio::stopRunningProject) { qDebug() << "Stop running project requested"; - emit projectStopRequested(m_id); + m_projectData.clear(); + m_speedCalculator.stop(); + m_projectStallTimer.stop(); + emit projectStopRequested(m_designStudioID); } else { - qDebug() << "Unkown JSON message"; + qDebug() << "Unkown JSON message type:" << dataType; } } -// this function should only be triggered when the device is receiving a qmlrc project void DesignStudio::processBinaryMessage(const QByteArray &data) { - qDebug() << "Binary message received (most probably a project)"; - emit projectReceived(m_id, data); + m_projectStallTimer.start(); + m_projectData.append(data); + const bool isProjectComplete = m_projectData.size() == m_incomingProjectSize; + + int percentage = m_projectData.size() * 100 / m_incomingProjectSize; + + if (m_lastPercentage != percentage) { + emit projectIncomingProgress(m_designStudioID, percentage); + m_lastPercentage = percentage; + sendData(PackageToDesignStudio::projectReceivingProgress, percentage); + } + + if (isProjectComplete) { + startPingPong(); + sendProjectStarting(); + emit projectReceived(m_designStudioID, m_projectData); + m_speedCalculator.stop(); + m_projectStallTimer.stop(); + } +} + +void DesignStudio::sendProjectStarting() +{ + sendData(PackageToDesignStudio::projectStarting); } void DesignStudio::sendProjectRunning() diff --git a/src/backend/dsconnector/ds.h b/src/backend/dsconnector/ds.h index 468381b..db69e0c 100644 --- a/src/backend/dsconnector/ds.h +++ b/src/backend/dsconnector/ds.h @@ -7,26 +7,11 @@ #include <QTimer> #include <QWebSocket> -namespace PackageFromDesignStudio { -using namespace Qt::Literals; -constexpr auto designStudioReady = "designStudioReady"_L1; -constexpr auto projectData = "projectData"_L1; -constexpr auto stopRunningProject = "stopRunningProject"_L1; -}; // namespace PackageFromDesignStudio - -namespace PackageToDesignStudio { -using namespace Qt::Literals; -constexpr auto deviceInfo = "deviceInfo"_L1; -constexpr auto projectRunning = "projectRunning"_L1; -constexpr auto projectStopped = "projectStopped"_L1; -constexpr auto projectLogs = "projectLogs"_L1; -}; // namespace PackageToDesignStudio - class DesignStudio : public QObject { Q_OBJECT public: - DesignStudio(QWebSocket *socket, const QString &m_deviceUuid, QObject *parent = nullptr); + DesignStudio(QWebSocket *socket, const QString &deviceID, QObject *parent = nullptr); // Getters QString ipv4Addr() const; @@ -34,6 +19,7 @@ public: // Send data void sendDeviceInfo(); + void sendProjectStarting(); void sendProjectRunning(); void sendProjectStopped(); void sendProjectLogs(const QString &logs); @@ -47,18 +33,24 @@ private: QTimer m_pongTimer; // DS data - QString m_id; - QString m_deviceUuid; + QString m_designStudioID; + QString m_deviceID; // project QByteArray m_projectData; int m_incomingProjectSize; + int m_lastPercentage; + QTime m_projectNotificationTime; + QTimer m_speedCalculator; + QTimer m_projectStallTimer; // DS comm void sendData(const QLatin1String &dataType, const QJsonValue &data = QJsonValue()); // Internal void initPingPong(); + void startPingPong(); + void stopPingPong(); void initSocket(); private slots: @@ -72,7 +64,8 @@ signals: // DS signals void idReceived(const QString &id, const QString &ipv4Addr); - void projectIncoming(const int projectSize); + void projectVersionMismatch(const QString &version, const QString &got); + void projectIncoming(const QString &id, const int projectSize); void projectIncomingProgress(const QString &id, const int percentage); void projectReceived(const QString &id, const QByteArray &data); void projectStopRequested(const QString &id); diff --git a/src/backend/dsconnector/dsmanager.cpp b/src/backend/dsconnector/dsmanager.cpp index 20cf38d..e2c44b3 100644 --- a/src/backend/dsconnector/dsmanager.cpp +++ b/src/backend/dsconnector/dsmanager.cpp @@ -76,55 +76,62 @@ void DesignStudioManager::incomingConnection() this, &DesignStudioManager::projectIncomingProgress); + connect(designStudio.data(), + &DesignStudio::projectVersionMismatch, + this, + &DesignStudioManager::projectVersionMismatch); + connect(designStudio.data(), &DesignStudio::projectReceived, this, - [this, &designStudio](const QString &id, const QByteArray &project) { - emit projectReceived(id, project); - }); + &DesignStudioManager::projectReceived); connect(designStudio.data(), &DesignStudio::projectStopRequested, this, - [this](const QString &id) { emit projectStopRequested(id); }); + &DesignStudioManager::projectStopRequested); m_designStudios.append(designStudio); emit designStudioConnected(designStudio->id(), designStudio->ipv4Addr()); } +void DesignStudioManager::sendProjectStarting(const QString &id) +{ + for (const auto &designStudio : m_designStudios) { + if (designStudio->id() == id) + designStudio->sendProjectStarting(); + } +} + void DesignStudioManager::sendProjectRunning(const QString &id) { for (const auto &designStudio : m_designStudios) { - if (designStudio->id() == id) { + if (designStudio->id() == id) designStudio->sendProjectRunning(); - } } } void DesignStudioManager::sendProjectStopped(const QString &id) { for (const auto &designStudio : m_designStudios) { - if (designStudio->id() == id) { + if (designStudio->id() == id) designStudio->sendProjectStopped(); - } } } void DesignStudioManager::sendProjectLogs(const QString &id, const QString &logs) { for (const auto &designStudio : m_designStudios) { - if (designStudio->id() == id) { + if (designStudio->id() == id) designStudio->sendProjectLogs(logs); - } } } QString DesignStudioManager::getDesignStudioIp(const QString &id) const { for (const auto &designStudio : m_designStudios) { - if (designStudio->id() == id) { + if (designStudio->id() == id) return designStudio->ipv4Addr(); - } } return {}; diff --git a/src/backend/dsconnector/dsmanager.h b/src/backend/dsconnector/dsmanager.h index de38167..708190b 100644 --- a/src/backend/dsconnector/dsmanager.h +++ b/src/backend/dsconnector/dsmanager.h @@ -16,6 +16,7 @@ public: void init(); public slots: + void sendProjectStarting(const QString &id); void sendProjectRunning(const QString &id); void sendProjectStopped(const QString &id); void sendProjectLogs(const QString &id, const QString &logs); @@ -35,7 +36,8 @@ private: void incomingConnection(); signals: - void projectIncoming(const int &projectSize); + void projectVersionMismatch(const QString &expected, const QString &got); + void projectIncoming(const QString &id, const int &projectSize); void projectIncomingProgress(const QString &id, const int percentage); void projectReceived(const QString &id, const QByteArray &project); void designStudioConnected(const QString &id, const QString &ipAddr); diff --git a/src/backend/importdummy.qml b/src/backend/importdummy.qml index cb75b90..334e5ae 100644 --- a/src/backend/importdummy.qml +++ b/src/backend/importdummy.qml @@ -25,6 +25,9 @@ import QtQuick.Studio.MultiText import QtQuick.Studio.Utils import QtQuick.Studio.DesignEffects +import QtQuick.Timeline +import QtQuick.Timeline.BlendTrees + import QtQuickUltralite.Extras import QtQuickUltralite.Layers diff --git a/src/backend/projectmanager.cpp b/src/backend/projectmanager.cpp index acb50e3..13fed11 100644 --- a/src/backend/projectmanager.cpp +++ b/src/backend/projectmanager.cpp @@ -198,9 +198,12 @@ bool ProjectManager::isQt6Project(const QString &qmlProjectFileContent) return qt6ProjectMatch.hasMatch(); } -bool ProjectManager::runProject(const QByteArray &project, const bool autoScaleProject) +bool ProjectManager::runProject(const QByteArray &project, + const bool autoScaleProject, + const QString &sessionId) { m_autoScaleProject = autoScaleProject; + m_sessionId = sessionId; const QString projectPath = unpackProject(project); qDebug() << "Project location: " << projectPath; @@ -361,7 +364,7 @@ void ProjectManager::showAppWindow() disconnect(screen, &QScreen::orientationChanged, this, &ProjectManager::orientateWindow); // this signal is connected to the lambda in the backend // which will reset the project manager - emit closingProject(); + emit closingProject(m_sessionId); }); m_quickWindow->setFlags(Qt::Window | Qt::WindowStaysOnTopHint); @@ -373,6 +376,7 @@ void ProjectManager::stopProject() if (!m_quickWindow || !m_quickWindow->isVisible()) return; + m_sessionId.clear(); qDebug("Stopping the QML app window"); m_quickWindow->close(); } diff --git a/src/backend/projectmanager.h b/src/backend/projectmanager.h index 5240f85..ef92360 100644 --- a/src/backend/projectmanager.h +++ b/src/backend/projectmanager.h @@ -37,13 +37,16 @@ public: bool isRunning(); public slots: - bool runProject(const QByteArray &project, const bool autoScaleProject); + bool runProject(const QByteArray &project, + const bool autoScaleProject, + const QString &sessionId); void stopProject(); private: // Member variables QByteArray m_projectData; QString m_projectPath; + QString m_sessionId; bool m_autoScaleProject; // Qml related members @@ -70,5 +73,5 @@ private: void showAppWindow(); signals: - void closingProject(); + void closingProject(const QString &sessionId); }; -- GitLab