From 7411d37db68911c59016472e3aead0634cf555ae Mon Sep 17 00:00:00 2001 From: Daniel Teichmann Date: Mon, 27 Jul 2020 17:09:49 +0200 Subject: Move sources to src/ && lots of features --- main.cpp | 62 --------- qml.qrc | 11 +- remote-support-desktop.pro | 12 +- src/RWADBusAdaptor.cpp | 25 ++++ src/RWADBusAdaptor.h | 74 +++++++++++ src/main.cpp | 66 ++++++++++ src/main_qmladaptor.cpp | 115 +++++++++++++++++ src/main_qmladaptor.h | 56 +++++++++ src/session.cpp | 308 +++++++++++++++++++++++++++++++++++++++++++++ src/session.h | 72 +++++++++++ 10 files changed, 736 insertions(+), 65 deletions(-) delete mode 100644 main.cpp create mode 100644 src/RWADBusAdaptor.cpp create mode 100644 src/RWADBusAdaptor.h create mode 100644 src/main.cpp create mode 100644 src/main_qmladaptor.cpp create mode 100644 src/main_qmladaptor.h create mode 100644 src/session.cpp create mode 100644 src/session.h diff --git a/main.cpp b/main.cpp deleted file mode 100644 index 091f649..0000000 --- a/main.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -void changePin(QString pin, QQmlApplicationEngine &engine); -void gen_random(char *s, const int len); - -int main(int argc, char *argv[]) -{ - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - - QGuiApplication app(argc, argv); - - - QTranslator translator; - - qDebug() << "Im about to load: :/locales/bin/" + QLocale::system().name() + " locale!"; - if(translator.load(":/locales/bin/" + QLocale::system().name())) { - app.installTranslator(&translator); - qDebug() << "Loaded: " + QLocale::system().name() + " locale!"; - } else { - qDebug() << "Unable to load translation"; - } - - QQmlApplicationEngine engine; - engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); - if (engine.rootObjects().isEmpty()) - return -1; - - #define PIN_LENGTH 5 - // The char array in which the random pin will be written to - char rand_pin[PIN_LENGTH+1]; - gen_random(rand_pin, PIN_LENGTH); - changePin(rand_pin, engine); - - return app.exec(); -} - -void changePin(QString pin, QQmlApplicationEngine &engine){ - QQuickItem *item = engine.rootObjects().at(0)->findChild("pin_text"); - if (item) - item->setProperty("pin", pin); -} - -void gen_random(char *s, const int len) { - // Initialize random generator - srand( static_cast(time(NULL))); - - static const char alphanum[] = - "0123456789" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - for (int i = 0; i < len; ++i) { - s[i] = alphanum[rand() % static_cast(sizeof(alphanum) - 1)]; - } - - s[len] = 0; -} diff --git a/qml.qrc b/qml.qrc index befdf6f..6653eea 100644 --- a/qml.qrc +++ b/qml.qrc @@ -1,12 +1,21 @@ main.qml - main.cpp locales/bin/de_DE.qm locales/bin/main_en.qm locales/de_DE.ts locales/main_en.ts locales/bin/es_ES.qm locales/es_ES.ts + images/logo.png + images/into-clipboard.svg + images/menubar.png + src/main.cpp + src/main_qmladaptor.cpp + src/main_qmladaptor.h + src/RWADBusAdaptor.cpp + src/RWADBusAdaptor.h + src/session.cpp + src/session.h diff --git a/remote-support-desktop.pro b/remote-support-desktop.pro index a517b75..64b6136 100644 --- a/remote-support-desktop.pro +++ b/remote-support-desktop.pro @@ -1,4 +1,11 @@ QT += quick +QT += quickcontrols2 +QT += widgets + +message(Building with DBUS (Freedesktop notifications) support) +DEFINES += USE_DBUS +QT += dbus + CONFIG += c++11 # The following define makes your compiler emit warnings if you use @@ -12,8 +19,9 @@ DEFINES += QT_DEPRECATED_WARNINGS # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -SOURCES += \ - main.cpp +SOURCES += src/main.cpp src/session.cpp src/main_qmladaptor.cpp + +HEADERS += src/RWADBusAdaptor.h src/session.h src/main_qmladaptor.h RESOURCES += qml.qrc diff --git a/src/RWADBusAdaptor.cpp b/src/RWADBusAdaptor.cpp new file mode 100644 index 0000000..8fd9e7d --- /dev/null +++ b/src/RWADBusAdaptor.cpp @@ -0,0 +1,25 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -i RWADBusAdaptor.h -p :RWADBusAdaptor.cpp rwa.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "RWADBusAdaptor.h" +/* + * Implementation of interface class OrgArcticaProjectRWAInterface + */ + +OrgArcticaProjectRWAInterface::OrgArcticaProjectRWAInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +OrgArcticaProjectRWAInterface::~OrgArcticaProjectRWAInterface() +{ +} + diff --git a/src/RWADBusAdaptor.h b/src/RWADBusAdaptor.h new file mode 100644 index 0000000..5e90fe9 --- /dev/null +++ b/src/RWADBusAdaptor.h @@ -0,0 +1,74 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -p RWADBusAdaptor.h: rwa.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef RWADBUSADAPTOR_H +#define RWADBUSADAPTOR_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface org.ArcticaProject.RWA + */ +class OrgArcticaProjectRWAInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "org.ArcticaProject.RWA"; } + +public: + OrgArcticaProjectRWAInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~OrgArcticaProjectRWAInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply refresh_status(int pid) + { + QList argumentList; + argumentList << QVariant::fromValue(pid); + return asyncCallWithArgumentList(QStringLiteral("refresh_status"), argumentList); + } + + inline QDBusPendingReply start() + { + QList argumentList; + return asyncCallWithArgumentList(QStringLiteral("start"), argumentList); + } + + inline QDBusPendingReply status(int pid) + { + QList argumentList; + argumentList << QVariant::fromValue(pid); + return asyncCallWithArgumentList(QStringLiteral("status"), argumentList); + } + + inline QDBusPendingReply stop(int pid) + { + QList argumentList; + argumentList << QVariant::fromValue(pid); + return asyncCallWithArgumentList(QStringLiteral("stop"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +namespace org { + namespace ArcticaProject { + typedef ::OrgArcticaProjectRWAInterface RWA; + } +} +#endif diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..a1b1b9f --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "RWADBusAdaptor.cpp" +#include "session.h" + +int main(int argc, char *argv[]) { + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication app(argc, argv); + + QQuickStyle::setStyle("Material"); + + QTranslator translator; + qDebug() << "Loading locale: qrc:/locales/bin/" + QLocale::system().name(); + if(translator.load(":/locales/bin/" + QLocale::system().name())) { + app.installTranslator(&translator); + qDebug() << "Loaded: " + QLocale::system().name() + " locale!"; + } else { + qDebug() << "Unable to load translation"; + } + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + if (engine.rootObjects().isEmpty()) + return -1; + + QScopedPointer main_gui (new MainQMLAdaptor(&app, &engine)); + //MainQMLAdaptor *main_gui = new MainQMLAdaptor(&app, &engine); + // Make mainqmladaptor available to QML + engine.rootContext()->setContextProperty("mainqmladaptor", main_gui.data()); + + QScopedPointer session (new Session(&app, &engine, main_gui.data())); + //Session *session = new Session(&app, &engine, main_gui); + // Make 'session' available to QML + engine.rootContext()->setContextProperty("session", session.data()); + + // We don't want users to have multiple instances of this app running + QString tmpDirPath = QDir::tempPath() + "/rwa"; + QString tmpFilePath = tmpDirPath + "/remote-support-desktop-application-prevent-multiple-instances.lock"; + QDir tmpDir(tmpDirPath); + if (!tmpDir.exists()) { + // Ensure that the path exists + tmpDir.mkpath("."); + } + QLockFile lockFile(tmpFilePath); + qDebug() << "Checking for a lockfile at: " + tmpFilePath; + + if(!lockFile.tryLock(100)){ + qDebug() << QObject::tr("You already have this app running."); + qDebug() << QObject::tr("Only one instance is allowed."); + qDebug() << QObject::tr("Closing application now with an error."); + + return 1; + } + + return app.exec(); +} diff --git a/src/main_qmladaptor.cpp b/src/main_qmladaptor.cpp new file mode 100644 index 0000000..2366b03 --- /dev/null +++ b/src/main_qmladaptor.cpp @@ -0,0 +1,115 @@ +#pragma once + +#include "main_qmladaptor.h" + +MainQMLAdaptor::MainQMLAdaptor(QObject *parent, QQmlApplicationEngine* engine) : QObject(parent) +{ + _engine = engine; +} + +//void MainQMLAdaptor::setSession(Session session) { +// _session = session; +//} + +bool MainQMLAdaptor::setConnectButtonEnabled(bool enabled) { + // Find item via 'objectName' + QQuickItem *item = _engine->rootObjects().at(0)->findChild("start_support_button"); + if (item) { + item->setProperty("enabled", enabled); + if (item->property("checked").toBool()) { + item->setProperty("text", tr("Stop remote support session")); + } else { + item->setProperty("text", tr("Start remote support session")); + } + } else { + qWarning() << "Unable to find 'start_support_button' Item!"; + return false; + } + + return true; +} + +bool MainQMLAdaptor::setConnectButtonChecked(bool checked) { + // Find item via 'objectName' + QQuickItem *item = _engine->rootObjects().at(0)->findChild("start_support_button"); + if (item) { + item->setProperty("checked", checked); + } else { + qWarning() << "Unable to find 'start_support_button' Item!"; + return false; + } + + return true; +} + +bool MainQMLAdaptor::setStatus(QString status) { + // Find item via 'objectName' + QQuickItem *item = _engine->rootObjects().at(0)->findChild("dbus_api_status_text"); + if (item) { + item->setProperty("text", status); + } else { + qWarning() << "Unable to find 'dbus_api_status_text' Item!"; + return false; + } + + return true; +} + +bool MainQMLAdaptor::openMessageDialog(QString title, QString text, QMessageBox::Icon icon) { + _messageDialogText = text; + _messageDialogTitle = title; + _messageDialogIcon = icon; + _showMessageDialog = true; + emit messageDialogIconChanged(_messageDialogIcon); + emit messageDialogTitleChanged(_messageDialogTitle); + emit messageDialogTextChanged(_messageDialogText); + + emit showMessageDialogChanged(_showMessageDialog); + + qDebug() << "Opening MessageDialog!"; + return true; +} + +QString MainQMLAdaptor::getMessageDialogTitle() { + return _messageDialogTitle; +} + +QString MainQMLAdaptor::getMessageDialogText() { + return _messageDialogText; +} + +QMessageBox::Icon MainQMLAdaptor::getMessageDialogIcon() { + return _messageDialogIcon; +} + +bool MainQMLAdaptor::getShowMessageDialog() { + return _showMessageDialog; +} + +bool MainQMLAdaptor::setStatusIndicator(bool active, QColor color) { + // Find item via 'objectName' + QQuickItem *item = _engine->rootObjects().at(0)->findChild("dbus_api_status_indicator"); + if (item) { + item->setProperty("active", active); + item->setProperty("color", color); + } else { + qWarning() << "Unable to find 'dbus_api_status_indicator' Item!"; + return false; + } + + return true; +} + +void MainQMLAdaptor::handleCopyToClipboardButtonClick(QString copy_data) { + QClipboard *clipboard = QApplication::clipboard(); + QString originalText = clipboard->text(); + clipboard->setText(copy_data); + qDebug() << "Copied into clipboard:" << copy_data; +} + +//void MainQMLAdaptor::onCloseHandler() { +// qDebug() << "Inside MainQMLAdaptor::onCloseHandler()"; + +// // Sending onClose signal to main and there to Session::onCloseHandler() +// emit MainQMLAdaptor::onCloseSignal(); +//} diff --git a/src/main_qmladaptor.h b/src/main_qmladaptor.h new file mode 100644 index 0000000..30aae97 --- /dev/null +++ b/src/main_qmladaptor.h @@ -0,0 +1,56 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +//#include "session.cpp" + +class MainQMLAdaptor : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool showMessageDialog READ getShowMessageDialog NOTIFY showMessageDialogChanged) // this makes showMessageDialog available as a QML property + Q_PROPERTY(QString _messageDialogTitle READ getMessageDialogTitle NOTIFY messageDialogTitleChanged) // this makes showMessageDialogTitle available as a QML property + Q_PROPERTY(QString _messageDialogText READ getMessageDialogText NOTIFY messageDialogTextChanged) // this makes showMessageDialogText available as a QML property + Q_PROPERTY(QMessageBox::Icon _messageDialogIcon READ getMessageDialogIcon NOTIFY messageDialogIconChanged) // this makes showMessageDialogIcon available as a QML property +public: + explicit MainQMLAdaptor(QObject *parent, QQmlApplicationEngine *engine = nullptr); + +// void setSession(Session session); + + bool setConnectButtonEnabled(bool enabled); + bool setConnectButtonChecked(bool checked); + + bool setStatusIndicator(bool active, QColor color = QColor(255,255,255)); + bool setStatus(QString status); + + bool openMessageDialog(QString title, QString text, QMessageBox::Icon); + QString getMessageDialogTitle(); + QString getMessageDialogText(); + QMessageBox::Icon getMessageDialogIcon(); + bool getShowMessageDialog(); +signals: + void showMessageDialogChanged(bool show); + void messageDialogTextChanged(QString text); + void messageDialogTitleChanged(QString title); + void messageDialogIconChanged(int iconindex); + +// static void onCloseSignal(); + +//protected: +// Session _session; +private: + QQmlApplicationEngine* _engine; + + bool _showMessageDialog; + QString _messageDialogTitle; + QString _messageDialogText; + QMessageBox::Icon _messageDialogIcon; + +public slots: + void handleCopyToClipboardButtonClick(QString copy_data); +// static void onCloseHandler(); +}; diff --git a/src/session.cpp b/src/session.cpp new file mode 100644 index 0000000..d668e85 --- /dev/null +++ b/src/session.cpp @@ -0,0 +1,308 @@ +#pragma once + +#include "session.h" + +Session::Session(QObject *parent, QQmlApplicationEngine* engine, MainQMLAdaptor* main_gui) : QObject(parent) { + _initDBus(); + + _engine = engine; + + _main_gui = main_gui; + + statusTimer = new QTimer(this); + connect(statusTimer, &QTimer::timeout, this, &Session::statusTimerEvent); + + this->init_vars(); +} + +void Session::statusTimerEvent() { + this->refresh_status(this->getId()); +} + +void Session::init_vars() { + setPin("-----"); + setId(-1); + setURL(tr("Not available yet")); + setStatus("unknown"); + + _main_gui->setConnectButtonChecked(false); + _main_gui->setConnectButtonEnabled(true); + _main_gui->setStatusIndicator(false); + + this->statusTimer->stop(); +} + +QString Session::getStatus() { + return _status; +} + +QString Session::getURL() { + return _url; +} + +int Session::getId() { + return _id; +} + +QString Session::getPin() { + return _pin; +} + +void Session::setStatus(QString status) { + _status = status; + + QString guiString = tr("Unknown state of service"); + _main_gui->setStatusIndicator(false); + + if (status == "running") { + guiString = tr("Remote Support session is ready to be connected to"); + _main_gui->setStatusIndicator(true, QColor(255, 255, 0, 127)); + } else if (status == "dead") { + guiString = tr("Remote Support session was stopped ungracefully"); + + // Clear current variables + this->init_vars(); + _main_gui->setStatusIndicator(true, QColor(255, 0, 0, 127)); + } else if (status == "stopped") { + guiString = tr("Remote Support session was stopped"); + + // Clear current variables + this->init_vars(); + } else if (status == "active") { + guiString = tr("Your partner is connected to the Remote Support session"); + _main_gui->setStatusIndicator(true, QColor(0, 255, 0, 127)); + } else if (status == "waiting_start_request_answer") { + guiString = tr("Trying to reach session service..."); + } + + _main_gui->setStatus(guiString); + + emit statusChanged(_status); +} + +void Session::setURL(QString url) { + _url = url; + emit urlChanged(url); +} + +void Session::setId(int id) { + _id = id; + emit idChanged(id); +} + +void Session::setPin(QString pin) { + _pin = pin; + emit pinChanged(pin); +} + +void Session::handleConnectButtonClick(bool checked) { + qDebug() << "-----Connect button handler-----\nCurrent session #" << this->getId(); + + // Stopping even if nothing is running + this->stop(this->getId()); + + if (checked) { + // Start the Session again + this->start(); + } + qDebug() << "-----\\Connect button handler-----"; +} + +void Session::_initDBus() { + if (!QDBusConnection::sessionBus().isConnected()) { + qCritical() << "Cannot connect to the D-Bus session bus."; + } + + // Create DBus object + _dbus_rwa = new OrgArcticaProjectRWAInterface("org.ArcticaProject.RWA", "/RWA", + QDBusConnection::sessionBus(), this->parent()); + + qDebug("Initialized DBus object!"); +} + +void Session::start() { + qDebug() << "Requesting D-Bus session service to start a new session"; + + // Make an asynchrous 'start' call (Response will be sent to 'start_dbus_replied') + QDBusPendingCall async = _dbus_rwa->asyncCall("start"); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this); + + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(start_dbus_replied(QDBusPendingCallWatcher*))); + + // Disable connect button to reduce spam. + // And don't enable it as long there is no status update. + // (Or something fails) + _main_gui->setConnectButtonEnabled(false); + this->setStatus("waiting_start_request_answer"); +} + +void Session::start_dbus_replied(QDBusPendingCallWatcher *call) { + QString result = ""; + + QDBusPendingReply reply = *call; + if (reply.isError()) { + qCritical("Error: cannot parse 'start' reply from D-Bus service"); + qDebug() << "The reply" << reply.error(); + + // The user should have the oportunity to try again. + this->init_vars(); + + _main_gui->openMessageDialog(tr("Remote Support for your Desktop"), + tr("D-Bus response was invalid.\nFunction call: '%1'\nMaybe service isn't listening?").arg("start"), + QMessageBox::Icon::Critical); + + return; + } else { + result = reply.argumentAt<0>(); + } + call->deleteLater(); + + qDebug() << "Raw JSON from starting session is:" << result; + QJsonDocument doc = QJsonDocument::fromJson(result.toUtf8()); + + // Get the QJsonObject + QJsonObject jObject = doc.object(); + QVariantMap mainMap = jObject.toVariantMap(); + + // Session ID == PID + int sessionid = mainMap["id"].toInt(); + this->setId(sessionid); + + // URL of remote web app frontend + QString url = mainMap["url"].toString(); + this->setURL(url); + + // PIN + QString pin = mainMap["pin"].toString(); + this->setPin(pin); + + qDebug() << "Got session id:" << sessionid; + qDebug() << "Got url:" << url; + qDebug() << "Got pin:" << pin; + + this->getStatus(); + emit pinChanged(pin); + emit urlChanged(url); + emit idChanged(sessionid); + + statusTimer->start(1000); +} + +void Session::stop(int pid) { + if (pid <= 0 ){ + qDebug() << "Won't send a request to D-Bus service to stop a session when session ID <= 0"; + return; + } + + // Stopping now. + qDebug() << "Requesting D-Bus session service to stop session #" << pid; + + // Make an asynchrous 'stop' call (Response will be sent to 'stop_dbus_replied') + QDBusPendingCall async = _dbus_rwa->asyncCall("stop", pid); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this); + + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(stop_dbus_replied(QDBusPendingCallWatcher*))); + + // Clear current variables + this->init_vars(); + + // Disable connect button to reduce spam. + // And don't enable it as long there is no status update. + // (Or something fails) + _main_gui->setConnectButtonEnabled(false); +} + +void Session::stop_dbus_replied(QDBusPendingCallWatcher *call) { + QString result = ""; + + QDBusPendingReply reply = *call; + if (reply.isError()) { + qCritical("Error: cannot parse 'stop' reply from D-Bus service"); + qDebug() << "The reply" << reply.error(); + + this->init_vars(); + + _main_gui->openMessageDialog(tr("Remote Support for your Desktop"), + tr("D-Bus response was invalid.\nFunction call: '%1'\nMaybe service isn't listening?").arg("stop"), + QMessageBox::Icon::Critical); + + return; + } else { + result = reply.argumentAt<0>(); + } + call->deleteLater(); + + // Get the QJsonObject + QJsonDocument doc = QJsonDocument::fromJson(result.toUtf8()); + QJsonObject jObject = doc.object(); + QVariantMap mainMap = jObject.toVariantMap(); + qDebug() << "Refreshed status:" << mainMap["status"].toString(); + this->setStatus(mainMap["status"].toString()); + + // Clear current variables + this->init_vars(); +} + +void Session::status(int pid) { + // Requesting status now. + qDebug() << "Requesting status for session #" << pid; + + // Make an asynchrous 'status' call (Response will be sent to 'status_dbus_replied') + QDBusPendingCall async = _dbus_rwa->asyncCall("status", pid); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this); + + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(stop_dbus_replied(QDBusPendingCallWatcher*))); +} + +void Session::refresh_status(int pid) { + // Refreshing status + qDebug() << "Requesting status refresh for session #" << pid; + + // Make an asynchrous 'refresh_status' call (Response will be sent to 'status_dbus_replied') + QDBusPendingCall async = _dbus_rwa->asyncCall("refresh_status", pid); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this); + + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(status_dbus_replied(QDBusPendingCallWatcher*))); +} + +void Session::status_dbus_replied(QDBusPendingCallWatcher *call) { + QString result = ""; + + QDBusPendingReply reply = *call; + if (reply.isError()) { + qCritical("Error: cannot parse 'status' reply from D-Bus service"); + qDebug() << "The reply" << reply.error(); + + _main_gui->openMessageDialog(tr("Remote Support for your Desktop"), + tr("D-Bus response was invalid.\nFunction call: '%1'\nMaybe service isn't listening?").arg("status"), + QMessageBox::Icon::Critical); + + // Includes stopping status-refreshing timer + this->init_vars(); + + return; + } else { + result = reply.argumentAt<0>(); + } + call->deleteLater(); + + // Get the QJsonObject + QJsonDocument doc = QJsonDocument::fromJson(result.toUtf8()); + QJsonObject jObject = doc.object(); + QVariantMap mainMap = jObject.toVariantMap(); + qDebug() << "Refreshed status:" << mainMap["status"].toString(); + this->setStatus(mainMap["status"].toString()); + + // Enable (dis)connect button + _main_gui->setConnectButtonEnabled(true); +} + +//void Session::onCloseHandler() { +// qDebug() << "Inside Session::onCloseHandler()"; + +// this->stop(this->getId()); +//} diff --git a/src/session.h b/src/session.h new file mode 100644 index 0000000..bc9a7cf --- /dev/null +++ b/src/session.h @@ -0,0 +1,72 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "RWADBusAdaptor.h" +#include "main_qmladaptor.h" +//#include "session.cpp" + +class Session : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString status READ getStatus NOTIFY statusChanged) // this makes status available as a QML property + Q_PROPERTY(int id READ getId NOTIFY idChanged ) // this makes id available as a QML property + Q_PROPERTY(QString url READ getURL NOTIFY urlChanged ) // this makes url available as a QML property + Q_PROPERTY(QString pin READ getPin NOTIFY pinChanged ) // this makes pin available as a QML property +public: + explicit Session(QObject *parent, QQmlApplicationEngine *engine = nullptr, MainQMLAdaptor *main_gui = nullptr); + void init_vars(); + + QString getStatus(); + QString getURL(); + int getId(); + QString getPin(); + + void setStatus(QString status); + void setURL(QString url); + void setId(int id); + void setPin(QString pin); + + // Starts a VNC Session + void start(); + // Refreshes a VNC Session's status + void refresh_status(int pid); + // Stop the Session + void stop(int pid); + // Gets a VNC Session's status + void status(int pid); + +protected: + QString _status; + QTimer *statusTimer; + void statusTimerEvent(); +private: + QQmlApplicationEngine* _engine; + MainQMLAdaptor* _main_gui; + int _id; + QString _url; + QString _pin; + OrgArcticaProjectRWAInterface* _dbus_rwa; + void _initDBus(); + +signals: + void finished(); + void statusChanged(QString status); + void idChanged(int id); + void urlChanged(QString URL); + void pinChanged(QString pin); + +public slots: + void handleConnectButtonClick(bool checked); + + void start_dbus_replied(QDBusPendingCallWatcher *call); + void stop_dbus_replied(QDBusPendingCallWatcher *call); + void status_dbus_replied(QDBusPendingCallWatcher *call); + +// void onCloseHandler(); +}; -- cgit v1.2.3