From 98f060ef4585e8a9cb10b65b1370ffd7dac36dea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Han=C3=A7erli?= <burak.hancerli@qt.io> Date: Mon, 28 Oct 2024 11:49:48 +0000 Subject: [PATCH] QDS-13458 Move server to device --- 3rdparty/qtquickdesigner-components | 2 +- CMakeLists.txt | 17 +- src/CMakeLists.txt | 2 - src/HomePage.qml | 12 +- src/Main.qml | 6 +- src/backend/backend.cpp | 146 +++++++-------- src/backend/backend.h | 13 +- src/backend/dsconnector/ds.cpp | 139 ++++---------- src/backend/dsconnector/ds.h | 55 +----- src/backend/dsconnector/dsdiscovery.cpp | 85 --------- src/backend/dsconnector/dsdiscovery.h | 44 ----- src/backend/dsconnector/dsmanager.cpp | 204 +++++++-------------- src/backend/dsconnector/dsmanager.h | 54 ++---- src/backend/logger.h | 32 +--- src/backend/main.cpp | 2 - src/backend/projectmanager.cpp | 83 ++++----- src/backend/projectmanager.h | 26 +-- src/backend/qrscanner.cpp | 26 +-- src/backend/qrscanner.h | 26 +-- src/backend/settings.cpp | 26 +-- src/backend/settings.h | 27 +-- tests/CMakeLists.txt | 3 - tests/main.cpp | 30 +-- tests/mock.h | 97 ---------- tests/tst_designstudio.cpp | 234 ------------------------ tests/tst_designstudio.h | 62 ------- tests/tst_dsdiscovery.cpp | 67 ------- tests/tst_dsdiscovery.h | 41 ----- tests/tst_settings.cpp | 26 +-- tests/tst_settings.h | 26 +-- 30 files changed, 283 insertions(+), 1330 deletions(-) delete mode 100644 src/backend/dsconnector/dsdiscovery.cpp delete mode 100644 src/backend/dsconnector/dsdiscovery.h delete mode 100644 tests/mock.h delete mode 100644 tests/tst_designstudio.cpp delete mode 100644 tests/tst_designstudio.h delete mode 100644 tests/tst_dsdiscovery.cpp delete mode 100644 tests/tst_dsdiscovery.h diff --git a/3rdparty/qtquickdesigner-components b/3rdparty/qtquickdesigner-components index 20397e2..34b97d4 160000 --- a/3rdparty/qtquickdesigner-components +++ b/3rdparty/qtquickdesigner-components @@ -1 +1 @@ -Subproject commit 20397e26370ff073125fd19f77c7ad013276b5bd +Subproject commit 34b97d40d86d7c243cb6bf8245d717397ef25268 diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d1ca30..bf02083 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,13 +7,6 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -if(NOT EXISTS ${ANDROID_OPENSSL_PATH}) - message(WARNING "Cannot find OpenSSL for Android. Path: ${ANDROID_OPENSSL_PATH}") - message(FATAL_ERROR "Please set ANDROID_OPENSSL_PATH to the path of OpenSSL for Android.") -endif() - -message(STATUS "Found OpenSSL for Android. Path: ${ANDROID_OPENSSL_PATH}") - find_package( QT NAMES Qt6 ) @@ -26,6 +19,16 @@ if(QT_VERSION VERSION_LESS QT_MINIMUM_VERSION) message(FATAL_ERROR "Minimum supported Qt version: ${QT_MINIMUM_VERSION}") endif() +if(ANDROID) + if(NOT EXISTS ${ANDROID_OPENSSL_PATH}) + message(WARNING "Cannot find OpenSSL for Android. Path: ${ANDROID_OPENSSL_PATH}") + message(FATAL_ERROR "Please set ANDROID_OPENSSL_PATH to the path of OpenSSL for Android.") + endif() + message(STATUS "Found OpenSSL for Android. Path: ${ANDROID_OPENSSL_PATH}") +else() + message(STATUS "Building for Desktop") +endif() + qt_standard_project_setup(REQUIRES ${QT_MINIMUM_VERSION}) set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_INSTALL_PREFIX}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e071432..a1ad4cd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,7 +14,6 @@ qt_add_executable(${PROJECT_NAME} backend/projectmanager.cpp backend/projectmanager.h backend/settings.cpp backend/settings.h backend/dsconnector/ds.cpp backend/dsconnector/ds.h - backend/dsconnector/dsdiscovery.cpp backend/dsconnector/dsdiscovery.h backend/dsconnector/dsmanager.cpp backend/dsconnector/dsmanager.h backend/qrscanner.cpp backend/qrscanner.h ../3rdparty/zxing-cpp/example/ZXingQtReader.h @@ -61,7 +60,6 @@ qt_add_library(qtuiviewerlib OBJECT backend/projectmanager.cpp backend/projectmanager.h backend/settings.cpp backend/settings.h backend/dsconnector/ds.cpp backend/dsconnector/ds.h - backend/dsconnector/dsdiscovery.cpp backend/dsconnector/dsdiscovery.h backend/dsconnector/dsmanager.cpp backend/dsconnector/dsmanager.h ) diff --git a/src/HomePage.qml b/src/HomePage.qml index d6e328b..c24cf59 100644 --- a/src/HomePage.qml +++ b/src/HomePage.qml @@ -18,8 +18,8 @@ Flickable { target: Qt.inputMethod function onKeyboardRectangleChanged() { - let mapPositon = optionLayout2.mapToItem(root, ipAddress.x, ipAddress.y) - root.contentY = mapPositon.y + let mapPositon = optionLayout2.mapToItem(root, ipAddress.x, ipAddress.y); + root.contentY = mapPositon.y; } } @@ -101,11 +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 Qt Design Studio"), qsTr("Click Play > Manage Run Targets"), qsTr("In Manage Run Targets window click Add run target button.")] delegate: RowLayout { Layout.fillWidth: true @@ -234,7 +230,7 @@ Flickable { target: backend function onConnectedChanged(isConnected, ip) { - ipAddress.text = ip + ipAddress.text = ip; } } } diff --git a/src/Main.qml b/src/Main.qml index 0baf1ff..e29a59f 100644 --- a/src/Main.qml +++ b/src/Main.qml @@ -53,16 +53,16 @@ Rectangle { font.pixelSize: Constants.smTextSize wrapMode: Text.WordWrap - text: root.connected ? qsTr("Qt Design Studio is connected to " + root.ip) + text: root.connected ? qsTr("Qt Design Studio is connected") : qsTr("Qt Design Studio is disconnected.") } } Connections { target: backend - function onConnectedChanged(isConnected, ip) { + function onConnectedChanged(isConnected) { + console.log("Connected changed to", isConnected) root.connected = isConnected - root.ip = ip } } } diff --git a/src/backend/backend.cpp b/src/backend/backend.cpp index 13b7d22..c9b6b2b 100644 --- a/src/backend/backend.cpp +++ b/src/backend/backend.cpp @@ -29,26 +29,35 @@ #include "logger.h" -Q_DECLARE_JNI_CLASS(Secure, "android/provider/Settings$Secure"); -Q_DECLARE_JNI_CLASS(String, "java/lang/String"); -Q_DECLARE_JNI_CLASS(ContentResolver, "android/content/ContentResolver"); +#ifdef QT_DEBUG +#define buildType "Debug" +#else +#define buildType "Release" +#endif Backend::Backend(QObject *parent) : QObject(parent) { - // This will allow us to open the app with the QR code - QDesktopServices::setUrlHandler("qtdesignviewer", this, "parseDesignViewerUrl"); + // register the `qtdesignstudio` url handler to the Android system QDesktopServices::setUrlHandler("qtdesignstudio", this, "parseDesignViewerUrl"); - QDesktopServices::setUrlHandler("https", this, "parseDesignViewerUrl"); + + if (m_settings.deviceUuid().isEmpty()) { + qDebug() << "Device UUID not found. Generating a new one."; + m_settings.setDeviceUuid(QUuid::createUuid().toString(QUuid::WithoutBraces)); + } m_dsManagerThread.setParent(this); connect(&m_dsManagerThread, &QThread::started, this, &Backend::initDsManager); m_dsManagerThread.start(); + m_projectManagerThread.setParent(this); + connect(&m_projectManagerThread, &QThread::started, this, &Backend::initProjectManager); + m_projectManagerThread.start(); + connect(&Logger::instance(), &Logger::logMessage, this, [this](QtMsgType type, QString &msg) { // if we have any active project running, then reroute // all the logs to the dsmanager with the last project sender id - if (m_projectManager) { + if (m_projectManager && m_projectManager->isRunning()) { QMetaObject::invokeMethod(m_dsManager.get(), "sendProjectLogs", Qt::QueuedConnection, @@ -76,50 +85,28 @@ Backend::Backend(QObject *parent) qDebug() << "-- Product version: " << QSysInfo::productVersion(); qDebug() << "-- Build ABI: " << QSysInfo::buildAbi(); qDebug() << "-- Build CPU architecture: " << QSysInfo::buildCpuArchitecture(); - qDebug() << "-- Device serial: " << getDeviceSerial(); - qDebug() << "-- Device unique ID: " << getDeviceUuid(); + qDebug() << "-- Device unique ID: " << m_settings.deviceUuid(); } Backend::~Backend() { m_dsManagerThread.quit(); + m_projectManagerThread.quit(); m_dsManagerThread.wait(); -} - -// this function returns the device serial number (which is really unique) -// but may not be reliable on all devices. Instead we use the device UUID. -QByteArray Backend::getDeviceSerial() -{ - auto context = QNativeInterface::QAndroidApplication::context(); - auto contentResolver = context.callMethod<QtJniTypes::ContentResolver>("getContentResolver"); - auto androidId = QtJniTypes::Secure::callStaticMethod<jstring>("getString", - contentResolver, - QStringLiteral("android_id")); - return androidId.toString().toLatin1(); -} - -QString Backend::getDeviceUuid() -{ - if (m_settings.deviceUuid().isEmpty()) { - qDebug() << "Device UUID not found. Generating a new one."; - m_settings.setDeviceUuid(QUuid::createUuid().toString(QUuid::WithoutBraces)); - } - - return m_settings.deviceUuid(); + m_projectManagerThread.wait(); } QString Backend::buildInfo() const { -#ifdef QT_DEBUG - const QString buildType = "Debug"; -#else - const QString buildType = "Release"; -#endif - return {QCoreApplication::applicationVersion() + "\nTechnology Preview - " - + QString(CMAKE_VAR_GIT_VERSION) + "\nQt " + QString(QT_VERSION_STR) + " - " + buildType - + " Build" + "\nQt Quick Components " + QString(CMAKE_VAR_QT_QUICK_COMPONENTS_VERSION) - + "\nZXing-Cpp: " + QString(CMAKE_VAR_ZXING_VERSION) - + "\nOpenSSL support: " + QVariant(QSslSocket::supportsSsl()).toString()}; + // clang-format off + return { + QCoreApplication::applicationVersion() + + "\nTechnology Preview - "+ 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 + + "\nOpenSSL support: " + QVariant(QSslSocket::supportsSsl()).toString()}; + // clang-format on } void Backend::updatePopup(const QString &text, bool indeterminate) @@ -129,51 +116,61 @@ void Backend::updatePopup(const QString &text, bool indeterminate) QEventLoop().processEvents(QEventLoop::AllEvents, 1000); } -void Backend::initializeProjectManager() +void Backend::initProjectManager() { - m_projectManager.reset(new ProjectManager(this, m_settings.autoScaleProject())); + m_projectManager.reset(new ProjectManager(this)); - connect(m_projectManager.get(), &QObject::destroyed, this, [this] { + connect(m_projectManager.get(), &ProjectManager::closingProject, this, [this] { QMetaObject::invokeMethod(m_dsManager.get(), "sendProjectStopped", Qt::QueuedConnection, Q_ARG(QString, m_lastProjectSenderId)); }); + + updatePopup("Initializing Project Manager..."); } void Backend::initDsManager() { qDebug() << "Design Studio Manager thread started. Initializing Design Studio Manager"; - m_dsManager.reset(new DesignStudioManager(nullptr, false, getDeviceUuid())); + m_dsManager.reset(new DesignStudioManager(m_settings.deviceUuid(), this)); connect(m_dsManager.get(), &DesignStudioManager::projectReceived, this, &Backend::runProject); connect(m_dsManager.get(), &DesignStudioManager::designStudioConnected, this, - [this](const QString &id, const QString &ipAddr) { - emit connectedChanged(true, ipAddr); - }); + [this](const QString &id, const QString &ipAddr) { emit connectedChanged(true); }); connect(m_dsManager.get(), &DesignStudioManager::designStudioDisconnected, this, [this](const QString &id, const QString &ipAddr) { - if (id == m_lastProjectSenderId && m_projectManager) { - m_projectManager->stopProject(); + if (id == m_lastProjectSenderId) { + QMetaObject::invokeMethod(m_projectManager.get(), + "stopProject", + Qt::QueuedConnection); } - emit connectedChanged(false, ipAddr); }); + connect(m_dsManager.get(), &DesignStudioManager::allDesignStudiosDisconnected, this, [this] { + qDebug() << "All Design Studios disconnected"; + emit connectedChanged(false); + }); + + connect(m_dsManager.get(), &DesignStudioManager::projectIncoming, this, [this] { + emit popupOpen("Receiving project..."); + }); + connect(m_dsManager.get(), &DesignStudioManager::projectStopRequested, this, [this](const QString &id) { - if (m_projectManager) { - m_projectManager->stopProject(); - } + QMetaObject::invokeMethod(m_projectManager.get(), + "stopProject", + Qt::QueuedConnection); }); - m_dsManager->initialize(); + m_dsManager->init(); qDebug() << "Design Studio Manager initialized"; } @@ -189,6 +186,9 @@ void Backend::connectDesignStudio(const QString &ipAddr) void Backend::runProject(const QString &id, const QByteArray &projectData) { + emit popupOpen(); + updatePopup("Running project..."); + // we'll use this to notify the correct DS when the project started/stopped m_lastProjectSenderId = id; QMetaObject::invokeMethod(m_dsManager.get(), @@ -196,19 +196,11 @@ void Backend::runProject(const QString &id, const QByteArray &projectData) Qt::QueuedConnection, Q_ARG(QString, id)); - initializeProjectManager(); - emit popupOpen(); - updatePopup("Unpacking project..."); - QString projectPath = m_projectManager->unpackProject(projectData); - updatePopup("Running project..."); - - if (!m_projectManager->runProject(projectPath)) { - qCritical() << "Could not run project. Please check the logs for more information."; - m_projectManager.reset(); - } else { - m_projectManager->showAppWindow(); - } - + QMetaObject::invokeMethod(m_projectManager.get(), + "runProject", + Qt::QueuedConnection, + Q_ARG(QByteArray, projectData), + Q_ARG(bool, autoScaleProject())); emit popupClose(); } @@ -228,18 +220,18 @@ void Backend::scanQrCode() void Backend::parseDesignViewerUrl(const QUrl &url) { - if (url.scheme() == "qtdesignstudio") { - if (url.host().isEmpty()) { - qWarning() << "No Design Studio IP address found in the QR code. URL:" - << url.toString(); - return; - } - - connectDesignStudio(url.host()); - } else { + if (url.scheme() != "qtdesignstudio") { qWarning() << "Unknown QR code format"; qWarning() << "URL:" << url.toString(); + return; } + + if (url.host().isEmpty()) { + qWarning() << "No Design Studio IP address found in the QR code. URL:" << url.toString(); + return; + } + + connectDesignStudio(url.host()); } void Backend::popupInterrupted() diff --git a/src/backend/backend.h b/src/backend/backend.h index 297cc52..0908b56 100644 --- a/src/backend/backend.h +++ b/src/backend/backend.h @@ -41,13 +41,14 @@ public: ~Backend(); private: - // Other members QScopedPointer<ProjectManager> m_projectManager; - QScopedPointer<QrScanner> m_qrScanner; + QThread m_projectManagerThread; - // DS Connector QScopedPointer<DesignStudioManager> m_dsManager; QThread m_dsManagerThread; + + QScopedPointer<QrScanner> m_qrScanner; + QString m_lastProjectSenderId; // Settings @@ -55,11 +56,9 @@ private: // member functions void updatePopup(const QString &text, bool indeterminate = true); - QByteArray getDeviceSerial(); - QString getDeviceUuid(); void initDsManager(); - void initializeProjectManager(); + void initProjectManager(); void runProject(const QString &id, const QByteArray &projectData); @@ -71,7 +70,7 @@ signals: void popupClose(); // UI signals - from DS Manager page - void connectedChanged(bool connected, const QString &ipAddr); + void connectedChanged(bool connected); // UI signals - from UI void connectToDesignStudio(const QString &url); diff --git a/src/backend/dsconnector/ds.cpp b/src/backend/dsconnector/ds.cpp index 86bb1fa..c95ec8c 100644 --- a/src/backend/dsconnector/ds.cpp +++ b/src/backend/dsconnector/ds.cpp @@ -1,27 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2024 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Viewer of the Qt Toolkit. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "ds.h" @@ -29,17 +7,10 @@ #include <QJsonObject> #include <QScreen> -DesignStudio::DesignStudio(const QString &ipv4Addr, - const quint16 port, - const QString &designStudioId, - const QString &deviceId, - QObject *parent) +DesignStudio::DesignStudio(QWebSocket *socket, const QString &m_deviceUuid, QObject *parent) : QObject(parent) - , m_ipv4Addr(ipv4Addr) - , m_port(port) - , m_url("ws://" + m_ipv4Addr + ":" + QString::number(m_port)) - , m_id(designStudioId) - , m_deviceUuid(deviceId) + , m_deviceUuid(m_deviceUuid) + , m_socket(socket) { initPingPong(); initSocket(); @@ -48,71 +19,46 @@ DesignStudio::DesignStudio(const QString &ipv4Addr, void DesignStudio::initPingPong() { connect(&m_pingTimer, &QTimer::timeout, this, [this]() { - m_socket.ping(); + m_socket->ping(); m_pongTimer.start(15000); }); - connect(&m_socket, &QWebSocket::pong, this, [this](quint64 elapsedTime, const QByteArray &) { - m_pongTimer.stop(); - }); + connect(m_socket.data(), + &QWebSocket::pong, + this, + [this](quint64 elapsedTime, const QByteArray &) { m_pongTimer.stop(); }); connect(&m_pongTimer, &QTimer::timeout, this, [this]() { qDebug() << "Design Studio" << m_id << "is not responding. Reconnecting."; - m_socket.close(); + m_socket->close(); }); } void DesignStudio::initSocket() { - connect(&m_socket, &QWebSocket::textMessageReceived, this, &DesignStudio::processTextMessage); - connect(&m_socket, - &QWebSocket::binaryMessageReceived, - this, - &DesignStudio::processBinaryMessage); - connect(&m_socket, &QWebSocket::disconnected, this, [this]() { - QTimer::singleShot(m_reconnectTimeout, this, [this]() { m_socket.open(m_url); }); - }); + m_pingTimer.start(15000); + m_pongTimer.stop(); - connect(&m_socket, &QWebSocket::stateChanged, this, [this](QAbstractSocket::SocketState state) { - if (state == QAbstractSocket::ConnectedState) { - qDebug() << "Connected to Design Studio" << m_id; - m_socketWasConnected = true; - m_pingTimer.start(15000); - m_pongTimer.stop(); - emit connected(m_id); - } else if (state == QAbstractSocket::UnconnectedState && m_socketWasConnected) { - qDebug() << "Disconnected from Design Studio" << m_id; - m_socketWasConnected = false; - m_pingTimer.stop(); - m_pongTimer.stop(); - emit disconnected(m_id); - } + connect(m_socket.data(), &QWebSocket::disconnected, this, [this]() { + qDebug() << "Design Studio" << m_id << "disconnected"; + m_pingTimer.stop(); + m_pongTimer.stop(); + emit disconnected(m_id); }); -} - -void DesignStudio::connectToDesignStudio() -{ - m_socket.open(m_url); -} -void DesignStudio::disconnectFromDesignStudio() -{ - m_socket.close(); + connect(m_socket.data(), + &QWebSocket::textMessageReceived, + this, + &DesignStudio::processTextMessage); + connect(m_socket.data(), + &QWebSocket::binaryMessageReceived, + this, + &DesignStudio::processBinaryMessage); } QString DesignStudio::ipv4Addr() const { - return m_ipv4Addr; -} - -quint16 DesignStudio::port() const -{ - return m_port; -} - -QUrl DesignStudio::url() const -{ - return m_url; + return m_socket->peerAddress().toString(); } QString DesignStudio::id() const @@ -120,24 +66,6 @@ QString DesignStudio::id() const return m_id; } -bool DesignStudio::isConnected() const -{ - return m_socket.state() == QAbstractSocket::ConnectedState; -} - -void DesignStudio::setIpAddress(const QString &ipv4Addr) -{ - m_socket.close(); - m_ipv4Addr = ipv4Addr; - m_url = QUrl("ws://" + m_ipv4Addr + ":" + QString::number(m_port)); - m_socket.open(m_url); -} - -void DesignStudio::setDesignStudioId(const QString &designStudioId) -{ - m_id = designStudioId; -} - void DesignStudio::sendDeviceInfo() { const QRect screenGeometry = QGuiApplication::primaryScreen()->geometry(); @@ -162,7 +90,7 @@ void DesignStudio::sendData(const QLatin1String &dataType, const QJsonValue &dat message["dataType"] = dataType; message["data"] = data; - m_socket.sendTextMessage(QJsonDocument(message).toJson(QJsonDocument::Compact)); + m_socket->sendTextMessage(QJsonDocument(message).toJson(QJsonDocument::Compact)); } void DesignStudio::processTextMessage(const QString &message) @@ -185,13 +113,10 @@ void DesignStudio::processTextMessage(const QString &message) if (dataType == PackageFromDesignStudio::designStudioReady) { const QString newDesignStudioId = jsonObj.value("data").toString(); - if (m_id != newDesignStudioId) { - qDebug() << "Design Studio" << m_id << "changed ID to" << newDesignStudioId - << "with IP address" << m_ipv4Addr << "Notifying ds manager."; - m_id = newDesignStudioId; - emit idReceived(newDesignStudioId, m_ipv4Addr); - } + qDebug() << "Design Studio ready with ID" << newDesignStudioId; + m_id = newDesignStudioId; sendDeviceInfo(); + emit idReceived(newDesignStudioId, ipv4Addr()); } else if (dataType == PackageFromDesignStudio::projectData) { qDebug() << "Project is expected"; emit projectIncoming(); @@ -203,9 +128,9 @@ void DesignStudio::processTextMessage(const QString &message) } } +// this function should only be triggered when the device is receiving a qmlrc project void DesignStudio::processBinaryMessage(const QByteArray &data) { - // this slot is only triggered when we're receiving a qmlrc project qDebug() << "Binary message received (most probably a project)"; emit projectReceived(m_id, data); } diff --git a/src/backend/dsconnector/ds.h b/src/backend/dsconnector/ds.h index a4cc12a..316b9cd 100644 --- a/src/backend/dsconnector/ds.h +++ b/src/backend/dsconnector/ds.h @@ -1,27 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2024 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Viewer of the Qt Toolkit. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once @@ -48,26 +26,11 @@ class DesignStudio : public QObject { Q_OBJECT public: - DesignStudio(const QString &ipv4Addr, - const quint16 port, - const QString &id = QString(), - const QString &deviceUuid = QString(), - QObject *parent = nullptr); - - // Socket ops - void connectToDesignStudio(); - void disconnectFromDesignStudio(); + DesignStudio(QWebSocket *socket, const QString &m_deviceUuid, QObject *parent = nullptr); // Getters QString ipv4Addr() const; - quint16 port() const; QString id() const; - QUrl url() const; - bool isConnected() const; - - // Setters - void setIpAddress(const QString &ipv4Addr); - void setDesignStudioId(const QString &designStudioId); // Send data void sendDeviceInfo(); @@ -77,11 +40,9 @@ public: private: // Network - QWebSocket m_socket; - QString m_ipv4Addr; - quint16 m_port; - QUrl m_url; - bool m_socketWasConnected = false; + QScopedPointer<QWebSocket> m_socket; + bool m_socketWasConnected; + QTimer m_pingTimer; QTimer m_pongTimer; @@ -89,9 +50,6 @@ private: QString m_id; QString m_deviceUuid; - // Settings - constexpr static int m_reconnectTimeout = 5000; - // DS comm void sendData(const QLatin1String &dataType, const QJsonValue &data = QJsonValue()); @@ -110,7 +68,6 @@ signals: // DS signals void idReceived(const QString &id, const QString &ipv4Addr); - void projectIncoming(); void projectReceived(const QString &id, const QByteArray &data); void projectStopRequested(const QString &id); diff --git a/src/backend/dsconnector/dsdiscovery.cpp b/src/backend/dsconnector/dsdiscovery.cpp deleted file mode 100644 index 09c7c6c..0000000 --- a/src/backend/dsconnector/dsdiscovery.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2024 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Viewer of the Qt Toolkit. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "dsdiscovery.h" - -#include <QNetworkDatagram> -#include <QNetworkInterface> - -#include <QJsonDocument> -#include <QJsonObject> -#include <QJsonParseError> - -DesignStudioDiscovery::DesignStudioDiscovery(QObject *parent) - : QObject(parent) -{ - const QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces(); - for (const QNetworkInterface &interface : interfaces) { - if (interface.flags().testFlag(QNetworkInterface::IsUp) - && interface.flags().testFlag(QNetworkInterface::IsRunning) - && !interface.flags().testFlag(QNetworkInterface::IsLoopBack)) { - for (const QNetworkAddressEntry &entry : interface.addressEntries()) { - if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) { - const bool retVal = m_udpSocket.bind(QHostAddress::AnyIPv4, - 53452, - QUdpSocket::ShareAddress); - if (!retVal) { - qWarning() << "UDP:: Failed to bind to port 53452"; - } - } - } - } - } - - qDebug() << "UDP:: Listening on" << m_udpSocket.localAddress() << "port" - << m_udpSocket.localPort(); - connect(&m_udpSocket, &QUdpSocket::readyRead, this, &DesignStudioDiscovery::onReadyRead); -} - -void DesignStudioDiscovery::onReadyRead() -{ - while (m_udpSocket.hasPendingDatagrams()) { - const QNetworkDatagram datagram = m_udpSocket.receiveDatagram(); - const QString message = datagram.data(); - const QString ipv4Addr = datagram.senderAddress().toString(); - - QJsonParseError jsonError; - const QJsonDocument jsonDoc = QJsonDocument::fromJson(message.toUtf8(), &jsonError); - - if (jsonError.error != QJsonParseError::NoError) { - qDebug() << "UDP:: Failed to parse JSON message:" << jsonError.errorString(); - continue; - } - - const QJsonObject jsonObj = jsonDoc.object(); - - if (!jsonObj.contains("name") && !jsonObj.contains("id")) { - qDebug() << "UDP:: Invalid JSON message:" << jsonObj; - continue; - } - - emit designStudioFound(ipv4Addr, jsonObj.value("id").toString()); - } -} diff --git a/src/backend/dsconnector/dsdiscovery.h b/src/backend/dsconnector/dsdiscovery.h deleted file mode 100644 index f3756c6..0000000 --- a/src/backend/dsconnector/dsdiscovery.h +++ /dev/null @@ -1,44 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2024 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Viewer of the Qt Toolkit. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include <QUdpSocket> - -class DesignStudioDiscovery : public QObject -{ - Q_OBJECT -public: - explicit DesignStudioDiscovery(QObject *parent = nullptr); - -private slots: - void onReadyRead(); - -signals: - void designStudioFound(const QString &ipv4Addr, const QString &id); - -private: - QUdpSocket m_udpSocket; -}; diff --git a/src/backend/dsconnector/dsmanager.cpp b/src/backend/dsconnector/dsmanager.cpp index 777b85c..c0a4c32 100644 --- a/src/backend/dsconnector/dsmanager.cpp +++ b/src/backend/dsconnector/dsmanager.cpp @@ -1,48 +1,21 @@ -/**************************************************************************** -** -** Copyright (C) 2023 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Viewer of the Qt Toolkit. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "dsmanager.h" -#include "backend/dsconnector/ds.h" +#include "ds.h" -#include <QFile> #include <QJsonArray> #include <QJsonDocument> #include <QJsonObject> -#include <QStandardPaths> +#include <QUdpSocket> -DesignStudioManager::DesignStudioManager(QObject *parent, - const bool enableDiscovery, - const QString &deviceUuid) +DesignStudioManager::DesignStudioManager(const QString &deviceUuid, QObject *parent) : QObject(parent) , m_deviceUuid(deviceUuid) - , m_enableDiscovery(enableDiscovery) - , m_settingsPath( - QStandardPaths::writableLocation(QStandardPaths::ConfigLocation).append("/dsmanager.json")) + , m_webSocketServer("DesignStudio", QWebSocketServer::NonSecureMode) {} -void DesignStudioManager::initialize() +void DesignStudioManager::init() { static bool initialized = false; if (initialized) { @@ -50,132 +23,97 @@ void DesignStudioManager::initialize() } initialized = true; - initLastKnownDs(); - - qDebug() << "Device UUID:" << m_deviceUuid; - if (m_enableDiscovery) { - qDebug() << "Starting Design Studio discovery"; - m_discovery = std::make_unique<DesignStudioDiscovery>(); - connect(m_discovery.get(), - &DesignStudioDiscovery::designStudioFound, - this, - &DesignStudioManager::designStudioFound); - } + m_webSocketServer.listen(QHostAddress::Any, 40000); + connect(&m_webSocketServer, + &QWebSocketServer::newConnection, + this, + &DesignStudioManager::incomingConnection); + qDebug() << "TCP server listening on port 40000"; + + m_discoveryTimer.setInterval(10000); + connect(&m_discoveryTimer, &QTimer::timeout, [this]() { + QJsonObject message; + message["name"] = "__qtuiviewer__"; + message["id"] = m_deviceUuid; + QByteArray datagram = QJsonDocument(message).toJson(QJsonDocument::Compact); + + QUdpSocket udpSocket; + const int port = 53452; + udpSocket.writeDatagram(datagram, QHostAddress::LocalHost, port); + udpSocket.writeDatagram(datagram, QHostAddress::Broadcast, port); + }); } -void DesignStudioManager::initLastKnownDs() +void DesignStudioManager::incomingConnection() { - QFile file(m_settingsPath); - - if (!file.exists()) { - qDebug() << "Settings file not found."; + auto *socket = m_webSocketServer.nextPendingConnection(); + if (!socket) { return; } - file.open(QIODevice::ReadOnly); - QJsonDocument doc = QJsonDocument::fromJson(file.readAll()); - file.close(); - - if (!doc.isObject()) { - qDebug() << "Settings file is not a JSON object."; - return; - } - - QJsonObject obj = doc.object(); - QJsonArray dsArray = obj["designStudios"].toArray(); - for (const auto &ds : dsArray) { - QJsonObject dsObj = ds.toObject(); - initDesignStudio(dsObj["ipv4Addr"].toString(), dsObj["designStudioId"].toString()); - } -} - -void DesignStudioManager::initDesignStudio(const QString &ipv4Addr, const QString &designStudioId) -{ - if (m_designStudio) { - if (m_designStudio->ipv4Addr() == ipv4Addr && m_designStudio->isConnected()) { - qDebug() << "Design Studio" << ipv4Addr << "is already connected"; - return; - } - } - - emit designStudioDisconnected(designStudioId, ipv4Addr); - - qDebug() << "Initializing Design Studio" << designStudioId << "with IPv4 address" << ipv4Addr; - m_designStudio.reset(new DesignStudio(ipv4Addr, 40000, designStudioId, m_deviceUuid)); + auto designStudio = QSharedPointer<DesignStudio>(new DesignStudio(socket, m_deviceUuid, this), + &QObject::deleteLater); + connect(designStudio.data(), &DesignStudio::disconnected, this, [this, designStudio]() { + m_designStudios.removeOne(designStudio); + qDebug() << "Remaining Design Studios:" << m_designStudios.size(); + if (m_designStudios.isEmpty()) + emit allDesignStudiosDisconnected(); + }); - connect(m_designStudio.get(), - &DesignStudio::idReceived, - this, - [this](const QString &, const QString &) { updateConfigFile(); }); + connect(designStudio.data(), &DesignStudio::projectIncoming, this, [this]() { + emit projectIncoming(); + }); - connect(m_designStudio.get(), + connect(designStudio.data(), &DesignStudio::projectReceived, this, - &DesignStudioManager::projectReceived); - - connect(m_designStudio.get(), &DesignStudio::connected, this, [this](const QString &id) { - emit designStudioConnected(id, m_designStudio->ipv4Addr()); - }); - - connect(m_designStudio.get(), &DesignStudio::disconnected, this, [this](const QString &id) { - emit designStudioDisconnected(id, m_designStudio->ipv4Addr()); - }); + [this, &designStudio](const QString &id, const QByteArray &project) { + emit projectReceived(id, project); + }); - connect(m_designStudio.get(), + connect(designStudio.data(), &DesignStudio::projectStopRequested, this, - &DesignStudioManager::projectStopRequested); + [this](const QString &id) { emit projectStopRequested(id); }); - m_designStudio->connectToDesignStudio(); - updateConfigFile(); + m_designStudios.append(designStudio); + emit designStudioConnected(designStudio->id(), designStudio->ipv4Addr()); } -void DesignStudioManager::designStudioFound(const QString &ipv4Addr, const QString &id) +void DesignStudioManager::sendProjectRunning(const QString &id) { - qDebug() << "Design Studio found with IPv4 address" << ipv4Addr << "and ID" << id; - - // check if the Design Studio is already in the list - if (m_designStudio->id() == id && m_designStudio->ipv4Addr() != ipv4Addr) { - qDebug() << "Design Studio" << id << "changed IP address from" << m_designStudio->ipv4Addr() - << "to" << ipv4Addr; - m_designStudio->setIpAddress(ipv4Addr); - updateConfigFile(); + for (const auto &designStudio : m_designStudios) { + if (designStudio->id() == id) { + designStudio->sendProjectRunning(); + } } } -void DesignStudioManager::updateConfigFile() +void DesignStudioManager::sendProjectStopped(const QString &id) { - QFile file(m_settingsPath); - if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) { - qDebug() << "Failed to open settings file for writing"; - return; + for (const auto &designStudio : m_designStudios) { + if (designStudio->id() == id) { + designStudio->sendProjectStopped(); + } } - - QJsonObject rootObj; - QJsonArray dsArray; - dsArray.append( - QJsonObject{{"ipv4Addr", m_designStudio->ipv4Addr()}, {"id", m_designStudio->id()}}); - - rootObj["designStudios"] = dsArray; - file.write(QJsonDocument(rootObj).toJson()); } -void DesignStudioManager::sendProjectRunning(const QString &) +void DesignStudioManager::sendProjectLogs(const QString &id, const QString &logs) { - m_designStudio->sendProjectRunning(); -} - -void DesignStudioManager::sendProjectStopped(const QString &) -{ - m_designStudio->sendProjectStopped(); + for (const auto &designStudio : m_designStudios) { + if (designStudio->id() == id) { + designStudio->sendProjectLogs(logs); + } + } } -void DesignStudioManager::sendProjectLogs(const QString &, const QString &logs) +QString DesignStudioManager::getDesignStudioIp(const QString &id) const { - m_designStudio->sendProjectLogs(logs); -} + for (const auto &designStudio : m_designStudios) { + if (designStudio->id() == id) { + return designStudio->ipv4Addr(); + } + } -QString DesignStudioManager::getDesignStudioIp(const QString &) const -{ - return m_designStudio ? m_designStudio->ipv4Addr() : QString(); + return {}; } diff --git a/src/backend/dsconnector/dsmanager.h b/src/backend/dsconnector/dsmanager.h index 913d372..27e964b 100644 --- a/src/backend/dsconnector/dsmanager.h +++ b/src/backend/dsconnector/dsmanager.h @@ -1,72 +1,44 @@ -/**************************************************************************** -** -** Copyright (C) 2023 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Viewer of the Qt Toolkit. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once #include <QObject> +#include <QWebSocketServer> #include "ds.h" -#include "dsdiscovery.h" class DesignStudioManager : public QObject { Q_OBJECT public: - explicit DesignStudioManager(QObject *parent = nullptr, - const bool enableDiscovery = false, - const QString &deviceUuid = {}); + explicit DesignStudioManager(const QString &deviceUuid, QObject *parent = nullptr); - void initialize(); + void init(); public slots: void sendProjectRunning(const QString &id); void sendProjectStopped(const QString &id); void sendProjectLogs(const QString &id, const QString &logs); - void initDesignStudio(const QString &ipv4Addr, const QString &designStudioId = {}); QString getDesignStudioIp(const QString &id) const; private: - // Discovery object - std::unique_ptr<DesignStudioDiscovery> m_discovery; - const bool m_enableDiscovery; + // Network + QWebSocketServer m_webSocketServer; + QTimer m_discoveryTimer; - // Active Design Studio. Only one can be active at a time. - std::unique_ptr<DesignStudio> m_designStudio; + // Connected Design Studios + QList<QSharedPointer<DesignStudio>> m_designStudios; // other members const QString m_deviceUuid; - const QString m_settingsPath; - void initLastKnownDs(); - void updateConfigFile(); - void dsIdReceived(const QString &id, const QString &ipv4Addr); - void designStudioFound(const QString &ipv4Addr, const QString &id); + void incomingConnection(); signals: + void projectIncoming(); void projectReceived(const QString &id, const QByteArray &project); void designStudioConnected(const QString &id, const QString &ipAddr); void designStudioDisconnected(const QString &id, const QString &ipAddr); + void allDesignStudiosDisconnected(); void projectStopRequested(const QString &id); }; diff --git a/src/backend/logger.h b/src/backend/logger.h index 6c233f7..6635e8f 100644 --- a/src/backend/logger.h +++ b/src/backend/logger.h @@ -1,33 +1,13 @@ -/**************************************************************************** -** -** Copyright (C) 2024 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Viewer of the Qt Toolkit. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once #include <QMessageBox> +#ifdef Q_OS_ANDROID #include <android/log.h> +#endif class Logger : public QObject { @@ -70,7 +50,11 @@ public: } newLog += logPrefix + localMsg + logSuffix + "\n"; +#ifdef Q_OS_ANDROID __android_log_print(ANDROID_LOG_DEBUG, "Qt_UI_Viewer", "%s", qPrintable(newLog)); +#else + fprintf(stderr, "%s", qPrintable(newLog)); +#endif if (type == QtCriticalMsg || type == QtFatalMsg) { QMessageBox msgBox{QMessageBox::Critical, "Critical:", msg, QMessageBox::Ok}; diff --git a/src/backend/main.cpp b/src/backend/main.cpp index 2141249..05bd977 100644 --- a/src/backend/main.cpp +++ b/src/backend/main.cpp @@ -23,8 +23,6 @@ ** ****************************************************************************/ -#include <android/log.h> - #include <QApplication> #include <QQmlContext> #include <QQmlEngine> diff --git a/src/backend/projectmanager.cpp b/src/backend/projectmanager.cpp index 3aee233..6f2bcb1 100644 --- a/src/backend/projectmanager.cpp +++ b/src/backend/projectmanager.cpp @@ -33,14 +33,10 @@ #include <QRegularExpression> #include <QResource> #include <QTemporaryDir> -#include <QtCore/private/qzipreader_p.h> -ProjectManager::ProjectManager(QObject *parent, bool autoScaleProject) +ProjectManager::ProjectManager(QObject *parent) : QObject(parent) - , m_autoScaleProject(autoScaleProject) -{ - qDebug() << "ProjectManager created. Auto scale project: " << m_autoScaleProject; -} +{} ProjectManager::~ProjectManager() { @@ -61,51 +57,28 @@ void ProjectManager::cleanupResources() } } -QString ProjectManager::unpackProject(const QByteArray &project, bool extractZip) +QString ProjectManager::unpackProject(const QByteArray &project) { - QTemporaryDir tempDir("qmlprojector"); - QString projectPath = tempDir.path(); - - if (extractZip) { - QDir().mkpath(projectPath); - QBuffer buffer; - buffer.setData(project); - buffer.open(QIODevice::ReadOnly); - QZipReader reader(&buffer); - reader.extractAll(projectPath); - } - - qDebug() << "Initial project location: " << projectPath; - - QDir projectPathDir(projectPath); - - // maybe it was not a zip file so try it as resource binary - if (projectPathDir.isEmpty()) { - if (extractZip) - qWarning("File could not be extracted. Trying to open it as a resource file."); - - cleanupResources(); - - m_projectData = project; - const uchar *data; - data = reinterpret_cast<const uchar *>(m_projectData.data()); - qDebug() << "Registering resource data. Size: " << m_projectData.size(); + cleanupResources(); - const QString resourcePath{"/" + QString::number(QRandomGenerator::global()->generate())}; - m_projectPath = resourcePath; + m_projectData = project; + const uchar *data; + data = reinterpret_cast<const uchar *>(m_projectData.data()); + qDebug() << "Registering resource data. Size: " << m_projectData.size(); - if (!QDir(resourcePath).removeRecursively()) { - qWarning() << "Could not remove resource path: " << resourcePath; - } + const QString resourcePath{"/" + QString::number(QRandomGenerator::global()->generate())}; + m_projectPath = resourcePath; - if (!QResource::registerResource(data, resourcePath)) { - qCritical() << "Can not load the resource data."; - return {}; - } + if (!QDir(resourcePath).removeRecursively()) { + qWarning() << "Could not remove resource path: " << resourcePath; + } - projectPath = ":" + resourcePath; + if (!QResource::registerResource(data, resourcePath)) { + qCritical() << "Can not load the resource data."; + return {}; } - return projectPath; + + return QString(":") + resourcePath; } QString ProjectManager::findFile(const QString &dir, const QString &filter) @@ -171,8 +144,11 @@ bool ProjectManager::isQt6Project(const QString &qmlProjectFileContent) return qt6ProjectMatch.hasMatch(); } -bool ProjectManager::runProject(const QString &projectPath) +bool ProjectManager::runProject(const QByteArray &project, const bool autoScaleProject) { + m_autoScaleProject = autoScaleProject; + + const QString projectPath = unpackProject(project); qDebug() << "Project location: " << projectPath; const QString qmlProjectFile = findFile(projectPath, "*.qmlproject"); @@ -275,6 +251,7 @@ bool ProjectManager::runProject(const QString &projectPath) view->setResizeMode(QQuickView::SizeViewToRootObject); m_quickWindow->setBaseSize(QSize(contentItem->width(), contentItem->height())); } + showAppWindow(); return true; } @@ -337,14 +314,16 @@ void ProjectManager::showAppWindow() m_quickWindow->showMaximized(); } -void ProjectManager::hideAppWindow() -{ - qDebug("Hiding the QML app window"); - m_quickWindow->hide(); -} - void ProjectManager::stopProject() { + if (!m_quickWindow || !m_quickWindow->isVisible()) + return; + qDebug("Stopping the QML app window"); m_quickWindow->close(); } + +bool ProjectManager::isRunning() +{ + return m_quickWindow && m_quickWindow->isVisible(); +} diff --git a/src/backend/projectmanager.h b/src/backend/projectmanager.h index 6a1a746..cde6e95 100644 --- a/src/backend/projectmanager.h +++ b/src/backend/projectmanager.h @@ -31,39 +31,41 @@ class ProjectManager : public QObject { Q_OBJECT public: - explicit ProjectManager(QObject *parent = nullptr, bool autoScaleProject = false); + explicit ProjectManager(QObject *parent = nullptr); ~ProjectManager(); - QString unpackProject(const QByteArray &project, bool extractZip = false); - bool runProject(const QString &projectPath); - void stopProject(); - - void showAppWindow(); - void hideAppWindow(); + bool isRunning(); public slots: - void orientateWindow(Qt::ScreenOrientation orientation); + bool runProject(const QByteArray &project, const bool autoScaleProject); + void stopProject(); private: // Member variables QByteArray m_projectData; QString m_projectPath; - const bool m_autoScaleProject; + bool m_autoScaleProject; // Qml related members QScopedPointer<QQmlEngine> m_qmlEngine; QScopedPointer<QQmlComponent> m_qmlComponent; QScopedPointer<QQuickWindow> m_quickWindow; - // Member functions + // resource management + void cleanupResources(); + QString unpackProject(const QByteArray &project); + + // project parsers QString findFile(const QString &dir, const QString &filter); QString readQmlProjectFile(const QString &qmlProjectFilePath); QString getMainQmlFile(const QString &projectPath, const QString &qmlProjectFileContent); QStringList getImportPaths(const QString &projectPath, const QString &qmlProjectFileContent); bool isQt6Project(const QString &qmlProjectFileContent); - void parseQmlProjectFile(const QString &fileName, QString *mainFile, QStringList *importPaths); - void cleanupResources(); + + // window management + void orientateWindow(Qt::ScreenOrientation orientation); + void showAppWindow(); signals: void closingProject(); diff --git a/src/backend/qrscanner.cpp b/src/backend/qrscanner.cpp index d6c2b7f..f66ec0f 100644 --- a/src/backend/qrscanner.cpp +++ b/src/backend/qrscanner.cpp @@ -1,27 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2024 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Viewer of the Qt Toolkit. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "qrscanner.h" diff --git a/src/backend/qrscanner.h b/src/backend/qrscanner.h index 8931d49..3ba3cc8 100644 --- a/src/backend/qrscanner.h +++ b/src/backend/qrscanner.h @@ -1,27 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2024 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Viewer of the Qt Toolkit. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once diff --git a/src/backend/settings.cpp b/src/backend/settings.cpp index 3dfedfd..0ff2f5b 100644 --- a/src/backend/settings.cpp +++ b/src/backend/settings.cpp @@ -1,27 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2024 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Viewer of the Qt Toolkit. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "settings.h" diff --git a/src/backend/settings.h b/src/backend/settings.h index 96f034f..b88309b 100644 --- a/src/backend/settings.h +++ b/src/backend/settings.h @@ -1,27 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2024 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Viewer of the Qt Toolkit. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + #pragma once #include <QJsonObject> diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b006a33..3e1c7b1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -4,10 +4,7 @@ find_package(Qt6 REQUIRED COMPONENTS Test Core Quick Gui Multimedia WebSockets) enable_testing(true) qt_add_executable(${TARGET_NAME} - tst_designstudio.cpp tst_designstudio.h - tst_dsdiscovery.cpp tst_dsdiscovery.h tst_settings.cpp tst_settings.h - mock.h main.cpp ) diff --git a/tests/main.cpp b/tests/main.cpp index 2947812..7076f50 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -1,34 +1,10 @@ -/**************************************************************************** -** -** Copyright (C) 2024 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Viewer of the Qt Toolkit. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include <QGuiApplication> #include <QTemporaryFile> #include <QTest> -#include "tst_designstudio.h" -#include "tst_dsdiscovery.h" #include "tst_settings.h" #define DEBUG_LINE qDebug() << "Debugline:" << __LINE__ @@ -90,8 +66,6 @@ int main(int argc, char *argv[]) outputFile.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); outputFile.write("<testsuites>\n"); - runTest(new TestDesignStudio); - runTest(new TestDesignStudioDiscovery); runTest(new TestSettings); outputFile.write("</testsuites>\n"); diff --git a/tests/mock.h b/tests/mock.h deleted file mode 100644 index 428bd4f..0000000 --- a/tests/mock.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2024 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Viewer of the Qt Toolkit. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include <QJsonDocument> -#include <QJsonObject> -#include <QObject> -#include <QTimer> -#include <QUdpSocket> -#include <QWebSocket> -#include <QWebSocketServer> -#include <qtypes.h> - -#define UDP_PORT 53452 - -class DesignStudioMock : public QObject -{ - Q_OBJECT - -private: - // self advertisement over udp - QTimer m_discoveryTimer; - const QString m_id; - - // websocket connection to design studio - QWebSocketServer m_webSocketServer; - -public: - DesignStudioMock(QObject *parent = nullptr, const QString &id = "123456") - : QObject(parent) - , m_id(id) - , m_webSocketServer("DesignStudioMock", QWebSocketServer::NonSecureMode, this) - - { - connect(&m_discoveryTimer, &QTimer::timeout, [this] { - QUdpSocket udpSocket; - - QJsonObject message; - message["name"] = "__designstudio__"; - message["id"] = m_id; - QByteArray datagram = QJsonDocument(message).toJson(QJsonDocument::Compact); - - udpSocket.writeDatagram(datagram, QHostAddress::LocalHost, UDP_PORT); - udpSocket.writeDatagram(datagram, QHostAddress::Broadcast, UDP_PORT); - }); - - m_discoveryTimer.setInterval(100); - m_discoveryTimer.start(); - - connect(&m_webSocketServer, &QWebSocketServer::newConnection, [this] { - QWebSocket *socket = m_webSocketServer.nextPendingConnection(); - connect(socket, - &QWebSocket::textMessageReceived, - [this, socket](const QString &message) { - QJsonObject json = QJsonDocument::fromJson(message.toUtf8()).object(); - }); - }); - } - - void enableDiscovery(const bool enable) - { - if (enable) { - m_discoveryTimer.start(); - } else { - m_discoveryTimer.stop(); - } - } - - void connectToDesignStudio(); - void disconnectFromDesignStudio(); - -signals: - void disconnected(); -}; diff --git a/tests/tst_designstudio.cpp b/tests/tst_designstudio.cpp deleted file mode 100644 index 5e71c26..0000000 --- a/tests/tst_designstudio.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2024 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Viewer of the Qt Toolkit. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "tst_designstudio.h" - -#include <QJsonDocument> -#include <QJsonObject> -#include <QLatin1String> -#include <QSignalSpy> -#include <QTest> -#include <QWebSocket> -#include <QWebSocketServer> - -#include "backend/dsconnector/ds.h" - -QJsonObject createPackage(const QLatin1String &type, const QString &data) -{ - QJsonObject obj; - obj.insert("dataType", type.toString()); - obj.insert("data", data); - return obj; -} - -void TestDesignStudio::initTestCase() -{ - qDebug() << "Initialize TestDesignStudio"; - ds = new DesignStudio("localhost", 40000, "id"); - QVERIFY(ds != nullptr); -} - -void TestDesignStudio::testIpv4Addr() -{ - QCOMPARE(ds->ipv4Addr(), QString("localhost")); -} - -void TestDesignStudio::testId() -{ - QCOMPARE(ds->id(), QString("id")); -} - -void TestDesignStudio::testPort() -{ - QCOMPARE(ds->port(), quint16(40000)); -} - -void TestDesignStudio::testUrl() -{ - QCOMPARE(ds->url(), QUrl("ws://localhost:40000")); -} - -void TestDesignStudio::testConnected() -{ - QHostAddress addr = QHostAddress::LocalHost; - QWebSocketServer server("TestDesignStudio", QWebSocketServer::NonSecureMode); - QVERIFY(server.listen(addr, 40001)); - - DesignStudio ds(addr.toString(), 40001, "id", "deviceId"); - ds.connectToDesignStudio(); - QTRY_VERIFY(ds.isConnected()); -} - -void TestDesignStudio::testConnect() -{ - QHostAddress addr = QHostAddress::LocalHost; - QWebSocketServer server("TestDesignStudio", QWebSocketServer::NonSecureMode); - QVERIFY(server.listen(addr, 40002)); - - DesignStudio ds(addr.toString(), 40002, "id", "deviceId"); - ds.connectToDesignStudio(); - QTRY_VERIFY(ds.isConnected()); -} - -void TestDesignStudio::testDisconnect() -{ - QHostAddress addr = QHostAddress::LocalHost; - QWebSocketServer server("TestDesignStudio", QWebSocketServer::NonSecureMode); - QVERIFY(server.listen(addr, 40002)); - - DesignStudio ds(addr.toString(), 40002, "id", "deviceId"); - ds.connectToDesignStudio(); - QTRY_VERIFY(ds.isConnected()); - - ds.disconnectFromDesignStudio(); - QTRY_VERIFY(!ds.isConnected()); -} - -void TestDesignStudio::testSendDeviceInfo() -{ - QWebSocketServer server("TestDesignStudio", QWebSocketServer::NonSecureMode); - QVERIFY(server.listen(QHostAddress::LocalHost, 40003)); - - DesignStudio ds("localhost", 40003, "id", "deviceId"); - ds.connectToDesignStudio(); - QTRY_VERIFY(ds.isConnected()); - - QWebSocket *socket = server.nextPendingConnection(); - QVERIFY(socket != nullptr); - - connect(socket, &QWebSocket::textMessageReceived, [](const QString &message) { - qDebug() << "Received message" << message; - - QJsonObject obj = QJsonDocument::fromJson(message.toUtf8()).object(); - QVERIFY(obj.contains("dataType")); - QVERIFY(obj.contains("data")); - QVERIFY(obj.value("dataType").toString() == PackageToDesignStudio::deviceInfo); - QVERIFY(obj.value("data").toObject().contains("screenHeight")); - QVERIFY(obj.value("data").toObject().contains("screenWidth")); - QVERIFY(obj.value("data").toObject().contains("os")); - QVERIFY(obj.value("data").toObject().contains("osVersion")); - QVERIFY(obj.value("data").toObject().contains("architecture")); - QVERIFY(obj.value("data").toObject().contains("deviceId")); - QVERIFY(obj.value("data").toObject().contains("appVersion")); - }); - - QSignalSpy spy(socket, &QWebSocket::textMessageReceived); - QVERIFY(spy.isValid()); - - const QJsonObject dsReadyPackage = createPackage(PackageFromDesignStudio::designStudioReady, - ds.id()); - socket->sendTextMessage(QJsonDocument(dsReadyPackage).toJson(QJsonDocument::Compact)); - - QTRY_COMPARE(spy.count(), 1); - QTest::qWait(500); -} - -void TestDesignStudio::testConnectedSignal() -{ - QWebSocketServer server("TestDesignStudio", QWebSocketServer::NonSecureMode); - QVERIFY(server.listen(QHostAddress::LocalHost, 40010)); - - DesignStudio ds("localhost", 40010, "id", "deviceId"); - QSignalSpy spy(&ds, &DesignStudio::connected); - QSignalSpy spy2(&ds, &DesignStudio::idReceived); - QVERIFY(spy.isValid()); - QVERIFY(spy2.isValid()); - - ds.connectToDesignStudio(); - QTRY_VERIFY(ds.isConnected()); - - QWebSocket *socket = server.nextPendingConnection(); - QVERIFY(socket != nullptr); - - const QJsonObject dsReadyPackage = createPackage(PackageFromDesignStudio::designStudioReady, - "data"); - socket->sendTextMessage(QJsonDocument(dsReadyPackage).toJson(QJsonDocument::Compact)); - - QTRY_COMPARE(spy.count(), 1); - QTRY_COMPARE(spy2.count(), 1); -} - -void TestDesignStudio::testDisconnectedSignal() -{ - QWebSocketServer server("TestDesignStudio", QWebSocketServer::NonSecureMode); - QVERIFY(server.listen(QHostAddress::LocalHost, 40011)); - - DesignStudio ds("localhost", 40011, "id", "deviceId"); - ds.connectToDesignStudio(); - QTRY_VERIFY(ds.isConnected()); - - QWebSocket *socket = server.nextPendingConnection(); - QVERIFY(socket != nullptr); - - QSignalSpy spy(&ds, &DesignStudio::disconnected); - QVERIFY(spy.isValid()); - - ds.disconnectFromDesignStudio(); - - QTRY_COMPARE(spy.count(), 1); -} - -void TestDesignStudio::testProjectIncomingSignal() -{ - QWebSocketServer server("TestDesignStudio", QWebSocketServer::NonSecureMode); - QVERIFY(server.listen(QHostAddress::LocalHost, 40011)); - - DesignStudio ds("localhost", 40011, "id", "deviceId"); - ds.connectToDesignStudio(); - QTRY_VERIFY(ds.isConnected()); - - QWebSocket *socket = server.nextPendingConnection(); - QVERIFY(socket != nullptr); - - QSignalSpy spy(&ds, &DesignStudio::projectIncoming); - QVERIFY(spy.isValid()); - - const QJsonObject projectIncomingPackage = createPackage(PackageFromDesignStudio::projectData, - "data"); - socket->sendTextMessage(QJsonDocument(projectIncomingPackage).toJson(QJsonDocument::Compact)); - - QTRY_COMPARE(spy.count(), 1); -} - -void TestDesignStudio::testProjectReceivedSignal() -{ - QWebSocketServer server("TestDesignStudio", QWebSocketServer::NonSecureMode); - QVERIFY(server.listen(QHostAddress::LocalHost, 40012)); - - DesignStudio ds("localhost", 40012, "id", "deviceId"); - ds.connectToDesignStudio(); - QTRY_VERIFY(ds.isConnected()); - - QWebSocket *socket = server.nextPendingConnection(); - QVERIFY(socket != nullptr); - - QSignalSpy spy(&ds, &DesignStudio::projectReceived); - QVERIFY(spy.isValid()); - - const QString arbitraryData = "some arbitrary data"; - socket->sendBinaryMessage(arbitraryData.toUtf8()); - - QTRY_COMPARE(spy.count(), 1); -} diff --git a/tests/tst_designstudio.h b/tests/tst_designstudio.h deleted file mode 100644 index 3abbf5f..0000000 --- a/tests/tst_designstudio.h +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2024 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Viewer of the Qt Toolkit. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include "backend/dsconnector/ds.h" - -class TestDesignStudio : public QObject -{ - Q_OBJECT -private: - DesignStudio *ds; - QString m_uuid; - -private slots: - // init - void initTestCase(); - - // test getters - void testIpv4Addr(); - void testId(); - void testPort(); - void testUrl(); - - // test status check - void testConnected(); - - // test connect/disconnect - void testConnect(); - void testDisconnect(); - - // test send data - void testSendDeviceInfo(); - - // test signals - void testConnectedSignal(); - void testDisconnectedSignal(); - void testProjectIncomingSignal(); - void testProjectReceivedSignal(); -}; diff --git a/tests/tst_dsdiscovery.cpp b/tests/tst_dsdiscovery.cpp deleted file mode 100644 index e5d1a7a..0000000 --- a/tests/tst_dsdiscovery.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2024 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Viewer of the Qt Toolkit. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "tst_dsdiscovery.h" - -#include <QJsonArray> -#include <QJsonDocument> -#include <QJsonObject> -#include <QSignalSpy> -#include <QUdpSocket> - -#include "backend/dsconnector/dsdiscovery.h" - -#define UDP_PORT 53452 - -void TestDesignStudioDiscovery::initTestCase() -{ - qDebug() << "Initialize TestDesignStudioDiscovery"; - - connect(&m_timer, &QTimer::timeout, [] { - QUdpSocket udpSocket; - - QJsonObject message; - message["name"] = "__designstudio__"; - message["id"] = "123456"; - QByteArray datagram = QJsonDocument(message).toJson(QJsonDocument::Compact); - - udpSocket.writeDatagram(datagram, QHostAddress::LocalHost, UDP_PORT); - udpSocket.writeDatagram(datagram, QHostAddress::Broadcast, UDP_PORT); - }); -} - -void TestDesignStudioDiscovery::testDesignStudioFoundSignal() -{ - qDebug() << "Test Design Studio Found Signal"; - - DesignStudioDiscovery dsDiscovery; - connect(&dsDiscovery, &DesignStudioDiscovery::designStudioFound, [](const QString &ipv4Addr) { - qDebug() << "Design Studio found at" << ipv4Addr; - }); - - m_timer.start(1000); - - QSignalSpy spy(&dsDiscovery, &DesignStudioDiscovery::designStudioFound); -} diff --git a/tests/tst_dsdiscovery.h b/tests/tst_dsdiscovery.h deleted file mode 100644 index d8f092a..0000000 --- a/tests/tst_dsdiscovery.h +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2024 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Viewer of the Qt Toolkit. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include <QTimer> - -class TestDesignStudioDiscovery : public QObject -{ - Q_OBJECT -private: - QTimer m_timer; - -private slots: - void initTestCase(); - - // test signals - void testDesignStudioFoundSignal(); -}; diff --git a/tests/tst_settings.cpp b/tests/tst_settings.cpp index dcb5ffc..a8922db 100644 --- a/tests/tst_settings.cpp +++ b/tests/tst_settings.cpp @@ -1,27 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2024 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Viewer of the Qt Toolkit. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "tst_settings.h" diff --git a/tests/tst_settings.h b/tests/tst_settings.h index 18ed10d..6c70c64 100644 --- a/tests/tst_settings.h +++ b/tests/tst_settings.h @@ -1,27 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2024 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Viewer of the Qt Toolkit. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once -- GitLab