diff --git a/src/backend.cpp b/src/backend.cpp index 04315c03da66a60b25e983ed0011f50a5dd2985a..800d3b49211e09c8808f4f4db0a2c8b47a06dedf 100644 --- a/src/backend.cpp +++ b/src/backend.cpp @@ -46,6 +46,12 @@ Backend::Backend(QObject *parent) // This will allow us to open the app with the QR code QDesktopServices::setUrlHandler("qtdesignviewer", this, "parseDesignViewerUrl"); QDesktopServices::setUrlHandler("https", this, "parseDesignViewerUrl"); + connect(&m_dsConnectorThread, + &QThread::started, + this, + &Backend::initDesignStudioConnector, + Qt::DirectConnection); + m_dsConnectorThread.start(); } void Backend::initialize() @@ -198,91 +204,47 @@ void Backend::initializeProjectManager() &Backend::downloadProgress); } -bool Backend::connectDesignStudio() +void Backend::initDesignStudioConnector() { - if (m_designStudioConnector) { - qDebug() << "Design Studio Connector is already initialized"; - return true; - } - - qDebug() << "Initializing Design Studio Connector"; - - connect( - &m_dsConnectorThread, - &QThread::started, - this, - [&] { - m_designStudioConnector.reset(new DesignStudioConnector); - connect(m_designStudioConnector.data(), - &DesignStudioConnector::networkStatusUpdated, - this, - &Backend::networkUpdated); - - 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(); - } - emit popupClose(); - }); - if (!m_designStudioConnector->initialize()) { - qCritical() - << "Could initialize server. Please check the logs for more information."; - m_designStudioConnector.reset(); - } - }, - Qt::DirectConnection); + m_designStudioConnector.reset(new DesignStudioConnector); - m_dsConnectorThread.start(); + connect(m_designStudioConnector.data(), + &DesignStudioConnector::networkStatusUpdated, + this, + &Backend::networkUpdated); - qDebug() << "Design Studio Connector is initialized"; - return true; -} + 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; + } -void Backend::disconnectDesignStudio() -{ - if (!m_designStudioConnector) { - qDebug() << "Design Studio Connector is not initialized"; - return; - } + qDebug() << "Project unpacked to " << projectPath; + updatePopup("Running project..."); - qDebug() << "Disconnecting from Design Studio"; + if (!m_projectManager->runProject(projectPath)) { + qCritical() << "Could not run project. Please check the logs for more " + "information."; + } else { + m_projectManager->showAppWindow(); + } - connect( - &m_dsConnectorThread, - &QThread::finished, - this, - [&] { - qDebug() << "Design Studio Connector is disconnected"; - m_designStudioConnector.reset(); - }, - Qt::DirectConnection); + emit popupClose(); + }); - m_dsConnectorThread.quit(); - m_dsConnectorThread.wait(); + qDebug() << "Design Studio Connector is initialized"; } void Backend::runDemoProject(const QString &projectName) diff --git a/src/backend.h b/src/backend.h index a061edb48278b9fee1246c9d0f0a28ed8604c5b0..d4c08ef082bd818acdd5822c371e3cf83613d0cd 100644 --- a/src/backend.h +++ b/src/backend.h @@ -115,8 +115,7 @@ public slots: void runDemoProject(const QString &projectName); void clearDemoCaches(); - bool connectDesignStudio(); - void disconnectDesignStudio(); + void initDesignStudioConnector(); void parseDesignViewerUrl(const QUrl &url); void registerUser(const QUrl &url); diff --git a/src/dsConnector.cpp b/src/dsConnector.cpp index 97f2c377401c12d1fd324bf5fc4475d2d6d96089..b5cf944fa5975664728adf5cbf6a58cc03e8981a 100644 --- a/src/dsConnector.cpp +++ b/src/dsConnector.cpp @@ -27,37 +27,46 @@ #include <QNetworkInterface> +DesignStudioConnector::DesignStudioConnector(QObject *parent) + : QObject(parent) +{ + initTcpServer(); +} + void DesignStudioConnector::receiveProject() { QByteArray data = m_tcpSocket->readAll(); - // qDebug() << "Data from Design Studio:" << data; + if (data.startsWith("qres")) { qDebug() << "TCP:: Received project start delimeter"; m_projectData.clear(); m_projectData.append(data); m_receivingData = true; - } else if (data.contains("::qmlrc-end::")) { - qDebug() << "TCP:: Received project end delimeter"; - // qDebug() << "TCP:: Last data sequence: " << data; - m_projectData.append(data.mid(0, data.size() - 13)); - emit projectReceived(m_projectData); - m_receivingData = false; } else if (m_receivingData) { - qDebug() << "TCP:: Received data sequence"; - m_projectData.append(data); + if (data.contains("::qmlrc-end::")) { + qDebug() << "TCP:: Received project end delimeter"; + m_projectData.append(data.mid(0, data.size() - 13)); + emit projectReceived(m_projectData); + m_receivingData = false; + } else { + qDebug() << "TCP:: Received data sequence"; + m_projectData.append(data); + } } else { qDebug() << "TCP:: Received unknown data:" << data; } } -bool DesignStudioConnector::initTcpServer() +void DesignStudioConnector::initTcpServer() { const bool retVal = m_tcpServer.listen(QHostAddress::Any, m_tcpPort); + updateIpv4Addr(); + if (!retVal) { qDebug() << "Failed to listen on port " << m_tcpPort; emit networkStatusUpdated("Failed to bind on port " + QString::number(m_tcpPort)); - return false; + return; } qDebug() << "Listening on port " << m_tcpPort; @@ -65,14 +74,14 @@ bool DesignStudioConnector::initTcpServer() qDebug() << "New connection from Design Studio"; emit networkStatusUpdated("Design Studio is connected.\n Waiting for project..."); m_tcpSocket.reset(m_tcpServer.nextPendingConnection()); - m_broadcastTimer.stop(); + m_ipUpdateTimer.stop(); connect(m_tcpSocket.data(), &QTcpSocket::disconnected, this, [this]() { qDebug() << "Disconnected from Design Studio"; emit networkStatusUpdated("\nLocal IP: " + m_ipv4Addr + "\nWaiting for Design Studio to connect..."); - m_broadcastTimer.start(); m_projectData.clear(); + m_ipUpdateTimer.start(); }); connect(m_tcpSocket.data(), @@ -81,49 +90,24 @@ bool DesignStudioConnector::initTcpServer() &DesignStudioConnector::receiveProject); }); - return true; + m_ipUpdateTimer.setInterval(5000); + connect(&m_ipUpdateTimer, &QTimer::timeout, this, &DesignStudioConnector::updateIpv4Addr); + m_ipUpdateTimer.start(); } -void DesignStudioConnector::initBroadcast() +void DesignStudioConnector::updateIpv4Addr() { - // get ipv4 address const QList<QHostAddress> list = QNetworkInterface::allAddresses(); for (const QHostAddress &address : list) { if (address.protocol() == QAbstractSocket::IPv4Protocol && address != QHostAddress::LocalHost) { - qDebug() << "Found IPv4 address:" << address.toString(); + if (m_ipv4Addr != address.toString()) { + qDebug() << "Local IP: " << address.toString(); + } m_ipv4Addr = address.toString(); break; } } - - qDebug() << "Advertising from" << m_ipv4Addr; emit networkStatusUpdated("\nLocal IP: " + m_ipv4Addr + "\nWaiting for Design Studio to connect..."); - - // Broadcast a message to the network in each 2 seconds - // to let the Design Studio know that we are here - connect(&m_broadcastTimer, &QTimer::timeout, this, [this]() { - QByteArray datagram = "qt_ui_viewer_at:" + m_ipv4Addr.toUtf8() + ":" - + QByteArray::number(m_tcpPort); - - m_udpSocket.writeDatagram(datagram.data(), - datagram.size(), - QHostAddress::Broadcast, - m_udpPort); - - qDebug() << "Broadcasting datagram:" << datagram; - }); - - m_broadcastTimer.setSingleShot(false); - m_broadcastTimer.start(2000); -} - -bool DesignStudioConnector::initialize() -{ - if (!initTcpServer()) - return false; - - initBroadcast(); - return true; } diff --git a/src/dsConnector.h b/src/dsConnector.h index 28d3f032e0fd7fab292801043bcc59be91e702c8..d9fb0b67cd86cbbd472bfff3544fa5159265e06f 100644 --- a/src/dsConnector.h +++ b/src/dsConnector.h @@ -36,10 +36,7 @@ class DesignStudioConnector : public QObject { Q_OBJECT public: - explicit DesignStudioConnector(QObject *parent = nullptr) - : QObject(parent) - {} - bool initialize(); + explicit DesignStudioConnector(QObject *parent = nullptr); private: // Tcp connection members @@ -48,19 +45,17 @@ private: const quint32 m_tcpPort = 40000; // Udp connection members - QUdpSocket m_udpSocket; - QTimer m_broadcastTimer; + QTimer m_ipUpdateTimer; QString m_ipv4Addr; - const quint32 m_udpPort = 45000; // Other members QByteArray m_projectData; bool m_receivingData; // Member functions - bool initTcpServer(); - void initBroadcast(); + void initTcpServer(); void receiveProject(); + void updateIpv4Addr(); signals: void networkStatusUpdated(QString); diff --git a/ui/Network.qml b/ui/Network.qml index e2ec0f4b07fdb89ff3afa300fcf41e433a3d4b8a..c0ec1ba5e84285718df5b90de697ad564b6dd6ba 100644 --- a/ui/Network.qml +++ b/ui/Network.qml @@ -29,7 +29,7 @@ Item { id: statusLabel Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter horizontalAlignment: "AlignHCenter" - text: "Click the button below to start\nadvertising this device on the network" + text: "Waiting for backend to be initialized..." Connections { target: backend function onNetworkUpdated(newStatus){ @@ -39,32 +39,11 @@ Item { } Item { - id: item1 - Layout.fillHeight: true - Layout.fillWidth: true - } - - Button { - property bool isRunning: false - id: startConnection - Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter + id: item3 + width: 200 + height: 200 + Layout.preferredHeight: 10 Layout.fillWidth: true - height: 100 - text: qsTr("Start Connection") - onClicked: { - if (isRunning) { - backend.disconnectDesignStudio() - isRunning = false - text = qsTr("Start Connection") - statusLabel.text = "Click the button below to start\nadvertising this device on the network" - } else { - let retval = backend.connectDesignStudio() - if (retval) { - text = qsTr("Stop Connection") - isRunning = true - } - } - } } } } diff --git a/ui/main.qml b/ui/main.qml index 24f84afcad9dc71494cfc132f11c42854465cecc..7be9bc93aa723faecf735f5ed6d07bd9c6efdb15 100644 --- a/ui/main.qml +++ b/ui/main.qml @@ -165,7 +165,6 @@ Rectangle { } } - TabButton { id: examples text: qsTr("Examples") @@ -181,7 +180,6 @@ Rectangle { } } - TabButton { id: logs text: qsTr("Logs") @@ -202,7 +200,7 @@ Rectangle { Layout.fillWidth: true checkable: true autoExclusive: true - visible: false; + visible: true; Connections { target: network @@ -227,7 +225,6 @@ Rectangle { } } - TabButton { id: about text: qsTr("About")