Skip to content
Snippets Groups Projects
Commit bf94b218 authored by Burak Hançerli's avatar Burak Hançerli :headphones:
Browse files

QDS-10485 Implement QR code integration

parent 031b0876
No related branches found
No related tags found
1 merge request!12QDS-10485 Implement QR code integration
Pipeline #62794 passed
......@@ -29,6 +29,7 @@ if(QT_VERSION VERSION_LESS QT_MINIMUM_VERSION)
endif()
qt_add_executable(${PROJECT_NAME}
src/importdummy.qml
src/main.cpp
src/backend.cpp src/backend.h
ui/main.qml
......
<?xml version="1.0"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.qt.qtdesignviewer"
android:installLocation="auto"
android:versionCode="1"
android:versionName="1.2">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="io.qt.qtdesignviewer" android:installLocation="auto" android:versionCode="1" android:versionName="1.2">
<!-- %%INSERT_PERMISSIONS -->
<!-- %%INSERT_FEATURES -->
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true" />
<application
android:name="org.qtproject.qt.android.bindings.QtApplication"
android:extractNativeLibs="true"
android:hardwareAccelerated="true"
android:label="Qt Design Viewer"
android:icon="@mipmap/app_icon"
android:requestLegacyExternalStorage="true"
android:allowNativeHeapPointerTagging="false">
<activity
android:name="org.qtproject.qt.android.bindings.QtActivity"
android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density"
android:label="Qt Design Viewer"
android:launchMode="singleTop"
android:screenOrientation="unspecified"
android:exported="true">
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true"/>
<application android:name="org.qtproject.qt.android.bindings.QtApplication" android:extractNativeLibs="true" android:hardwareAccelerated="true" android:label="Qt Design Viewer" android:requestLegacyExternalStorage="true" android:allowNativeHeapPointerTagging="false">
<activity android:name="org.qtproject.qt.android.bindings.QtActivity" android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:label="Qt Design Viewer" android:launchMode="singleTop" android:screenOrientation="unspecified" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="-- %%INSERT_APP_LIB_NAME%% --" />
<meta-data
android:name="android.app.arguments"
android:value="-- %%INSERT_APP_ARGUMENTS%% --" />
<meta-data
android:name="android.app.extract_android_style"
android:value="minimal" />
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="qtdesignviewer"/>
</intent-filter>
<meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
<meta-data android:name="android.app.arguments" android:value="-- %%INSERT_APP_ARGUMENTS%% --"/>
<meta-data android:name="android.app.extract_android_style" android:value="minimal"/>
</activity>
</application>
</manifest>
......@@ -24,29 +24,38 @@
****************************************************************************/
#include "backend.h"
#include "qapplication.h"
#if !defined(Q_OS_WASM)
#include <QBuffer>
#include <QDesktopServices>
#include <QDirIterator>
#include <QEventLoop>
#include <QFileInfo>
#include <QGuiApplication>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QMessageBox>
#include <QNetworkReply>
#include <QQuickItem>
#include <QRandomGenerator>
#include <QRegularExpression>
#include <QResource>
#include <QSettings>
#include <QSslSocket>
#include <QTemporaryDir>
#include <QTemporaryFile>
#include <QtCore/private/qandroidextras_p.h>
#include <QtGui/private/qzipreader_p.h>
#define QSTRN QString::number
Backend::Backend(QObject *parent)
{
QDesktopServices::setUrlHandler("qtdesignviewer", this, "registerUser");
const QRect screenGeometry = QGuiApplication::primaryScreen()->geometry();
printLog("Qt Design Viewer");
......@@ -56,9 +65,25 @@ Backend::Backend(QObject *parent)
printLog("-- Screen height: " + QSTRN(screenGeometry.height()));
printLog("-- Screen width: " + QSTRN(screenGeometry.width()));
m_buildInfo = QCoreApplication::applicationVersion() + "\n" + "Qt " + QString(QT_VERSION_STR)
+ " - OpenSSL support: " + QVariant(QSslSocket::supportsSsl()).toString();
#ifdef QT_DEBUG
QString buildType = "Debug";
#else
QString buildType = "Release";
#endif
m_buildInfo = QCoreApplication::applicationVersion() + "\nQt " + QString(QT_VERSION_STR) + " - "
+ buildType + " Build"
+ "\nOpenSSL support: " + QVariant(QSslSocket::supportsSsl()).toString();
emit buildInfoChanged();
QSettings settings;
m_userHash = settings.value("user/hash").toString();
if (m_userHash.isEmpty())
printLog("User Hash is not registered. Scan QR code to register.");
else {
printLog("User Hash: " + m_userHash);
updateUserProjectList();
}
printLog("Initialization complete");
}
......@@ -424,4 +449,38 @@ void Backend::downloadAndRun(const QString &url)
showAppWindow();
}
void Backend::registerUser(const QUrl &url)
{
const QString userHash = url.toString().remove("qtdesignviewer://");
printLog("Registering User Hash: " + userHash);
m_userHash = userHash;
QSettings().setValue("user/hash", m_userHash);
updateUserProjectList();
}
void Backend::updateUserProjectList()
{
printLog("Fetching available project list for user: " + m_userHash);
auto reply = fetchResource("https://designviewer.qt.io/api/v1/qmlrc/list/" + m_userHash
+ "?key=818815");
if (reply->error() != QNetworkReply::NoError) {
printErr("Could not fetch available project list");
return;
}
QJsonArray projectList = QJsonDocument::fromJson(reply->readAll())
.object()
.value("data")
.toObject()
.value("packages")
.toArray();
printLog("List of available projects fetched:");
for (const auto &project : projectList) {
const QString projectName{project.toObject().value("appName").toString()};
printLog("-- " + projectName);
m_projectList << projectName;
}
emit projectListChanged();
}
#endif // !defined(Q_OS_WASM)
......@@ -40,18 +40,23 @@ class Backend : public QObject
Q_PROPERTY(QString logs READ logs NOTIFY logsChanged)
Q_PROPERTY(QString buildInfo READ buildInfo NOTIFY buildInfoChanged)
Q_PROPERTY(int downloadProgress READ downloadProgress NOTIFY downloadProgressChanged FINAL)
Q_PROPERTY(QStringList projectList READ projectList NOTIFY projectListChanged FINAL)
Q_PROPERTY(QString userHash READ userHash FINAL)
public:
explicit Backend(QObject *parent = nullptr);
QString logs() const { return m_logs; }
QString buildInfo() const { return m_buildInfo; }
int downloadProgress() const { return m_downloadProgress; }
QStringList projectList() const { return m_projectList; }
QString userHash() const { return m_userHash; }
private:
// UI data
QString m_logs;
QString m_buildInfo;
int m_downloadProgress = 0;
QStringList m_projectList;
// Qml related members
QQmlEngine m_qmlEngine;
......@@ -62,6 +67,7 @@ private:
QNetworkAccessManager m_nam;
QByteArray m_projectData;
QString m_projectPath;
QString m_userHash;
// member logger functions
void printLog(const QString &message);
......@@ -76,14 +82,17 @@ private:
QString findFile(const QString &dir, const QString &filter);
void parseQmlprojectFile(const QString &fileName, QString *mainFile, QStringList *importPaths);
bool runProject(const QByteArray &projectData, const QString &projectName);
void updateUserProjectList();
signals:
void logsChanged();
void buildInfoChanged();
void downloadProgressChanged();
void projectListChanged();
public slots:
void downloadAndRun(const QString &url);
void registerUser(const QUrl &url);
private slots:
void orientateWindow(Qt::ScreenOrientation orientation);
......
// Hack to force the qml plugins to be linked statically
import QtQuick
import QtQuick.Controls
import QtQml
import QtQml.Models
import QtQml.StateMachine
import QtQuick3D
import QtQuick3D.AssetUtils
import QtQuick3D.Effects
import QtQuick3D.Helpers
import QtQuick3D.ParticleEffects
import QtQuick3D.Particles3D
import QtQuick.VirtualKeyboard
import QtQuick.Studio.Application
import QtQuick.Studio.Components
import QtQuick.Studio.Effects
import QtQuick.Studio.EventSimulator
import QtQuick.Studio.EventSystem
import QtQuick.Studio.LogicHelper
import QtQuick.Studio.MultiText
import QtQuickUltralite.Extras
import QtQuickUltralite.Layers
import FlowView
ApplicationWindow {
visible: true
width: 640
height: 480
}
......@@ -32,15 +32,10 @@
int main(int argc, char *argv[])
{
qDebug().noquote() << QString("Built on %1 %2\n").arg(__DATE__, __TIME__);
QSurfaceFormat format = QSurfaceFormat::defaultFormat();
format.setVersion(3, 0);
QSurfaceFormat::setDefaultFormat(format);
QCoreApplication::setApplicationVersion(QString("Built on %1 %2").arg(__DATE__, __TIME__));
QApplication app(argc, argv);
QApplication::setOrganizationName("Qt");
QApplication::setApplicationName(QStringLiteral("Qt Design Viewer"));
QApplication::setApplicationVersion(QString("Built on %1 %2").arg(__DATE__, __TIME__));
Backend backend;
......@@ -50,9 +45,5 @@ int main(int argc, char *argv[])
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.showMaximized();
QThread::msleep(2000);
// backend.downloadAndRun("https://designviewer.qt.io/#17e8907b3b84b8206d45be4f551f4e25/"
// "MaterialBundle.qmlrc");
return app.exec();
}
/*
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
*/
import QtQuick 6.4
import QtQuick.Controls 6.4
import QtQuick.Controls.Material
......@@ -52,11 +46,17 @@ Rectangle {
placeholderText: qsTr("Enter URL")
}
Button {
id: downloadButton
text: qsTr("Download and Run")
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
onClicked: backend.downloadAndRun(urlTextField.text)
RowLayout{
id: rowLayout
anchors.left: parent.left
anchors.right: parent.right
Button {
id: downloadButton
Layout.fillWidth: true
text: qsTr("Download and Run")
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
onClicked: backend.downloadAndRun(urlTextField.text)
}
}
}
......@@ -65,7 +65,6 @@ Rectangle {
width: 351
height: gridLayout.height
anchors.top: parent.top
anchors.topMargin: 12
anchors.horizontalCenter: parent.horizontalCenter
GridLayout {
......@@ -77,7 +76,7 @@ Rectangle {
Image {
id: qdsicon
x: 47
y: -23
y: -48
width: 204
height: 202
source: "content/images/dvicon.png"
......@@ -109,23 +108,52 @@ Rectangle {
}
}
ComboBox {
id: projectList
height: 50
anchors.left: parent.left
anchors.right: parent.right
anchors.top: header.bottom
down: false
anchors.topMargin: 15
anchors.rightMargin: 22
anchors.leftMargin: 22
displayText: "Select project..."
model: backend.projectList
currentIndex: -1
onCurrentIndexChanged: {
urlTextField.text = "https://designviewer.qt.io/qmlprojects/"
+ backend.userHash + "/"
+ textAt(currentIndex)
+ ".qmlrc"
displayText = textAt(currentIndex)
}
}
Rectangle {
id: log
visible: root.height > 620
visible: true
color: "#EAEAEA"
anchors.left: parent.left
anchors.right: parent.right
anchors.top: header.bottom
anchors.top: projectList.bottom
anchors.bottom: bar.top
anchors.topMargin: 15
anchors.bottomMargin: 24
anchors.leftMargin: 22
ScrollView {
id: scrollArea
visible: true
anchors.fill: parent
topPadding: 13.1
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
Connections {
target: backend
function onLogsChanged() {
logTextArea.text = backend.logs
scrollArea.ScrollBar.vertical.position = 1.0 - scrollArea.ScrollBar.vertical.size
}
}
TextArea {
clip: false
id: logTextArea
......@@ -139,4 +167,7 @@ Rectangle {
}
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment