aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Teichmann <daniel.teichmann@das-netzwerkteam.de>2020-07-27 17:09:49 +0200
committerDaniel Teichmann <daniel.teichmann@das-netzwerkteam.de>2020-07-27 17:13:25 +0200
commit7411d37db68911c59016472e3aead0634cf555ae (patch)
tree72238bf0774ad15a1ac5326ba4607f6caeb7f48f
parent77eefb1b2364737d824cc4cbefbe4b7bb1fd55b9 (diff)
downloadRWA.Support.DesktopApp-7411d37db68911c59016472e3aead0634cf555ae.tar.gz
RWA.Support.DesktopApp-7411d37db68911c59016472e3aead0634cf555ae.tar.bz2
RWA.Support.DesktopApp-7411d37db68911c59016472e3aead0634cf555ae.zip
Move sources to src/ && lots of features
-rw-r--r--main.cpp62
-rw-r--r--qml.qrc11
-rw-r--r--remote-support-desktop.pro12
-rw-r--r--src/RWADBusAdaptor.cpp25
-rw-r--r--src/RWADBusAdaptor.h74
-rw-r--r--src/main.cpp66
-rw-r--r--src/main_qmladaptor.cpp115
-rw-r--r--src/main_qmladaptor.h56
-rw-r--r--src/session.cpp308
-rw-r--r--src/session.h72
10 files changed, 736 insertions, 65 deletions
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 <QGuiApplication>
-#include <QQmlApplicationEngine>
-#include <QQmlComponent>
-#include <QQmlProperty>
-#include <QQuickItem>
-#include <QTranslator>
-#include <QDebug>
-
-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<QQuickItem*>("pin_text");
- if (item)
- item->setProperty("pin", pin);
-}
-
-void gen_random(char *s, const int len) {
- // Initialize random generator
- srand( static_cast<unsigned>(time(NULL)));
-
- static const char alphanum[] =
- "0123456789"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
- for (int i = 0; i < len; ++i) {
- s[i] = alphanum[rand() % static_cast<int>(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 @@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
- <file>main.cpp</file>
<file>locales/bin/de_DE.qm</file>
<file>locales/bin/main_en.qm</file>
<file>locales/de_DE.ts</file>
<file>locales/main_en.ts</file>
<file>locales/bin/es_ES.qm</file>
<file>locales/es_ES.ts</file>
+ <file>images/logo.png</file>
+ <file>images/into-clipboard.svg</file>
+ <file>images/menubar.png</file>
+ <file>src/main.cpp</file>
+ <file>src/main_qmladaptor.cpp</file>
+ <file>src/main_qmladaptor.h</file>
+ <file>src/RWADBusAdaptor.cpp</file>
+ <file>src/RWADBusAdaptor.h</file>
+ <file>src/session.cpp</file>
+ <file>src/session.h</file>
</qresource>
</RCC>
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 <QtCore/QObject>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtDBus/QtDBus>
+
+/*
+ * 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<QString> refresh_status(int pid)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(pid);
+ return asyncCallWithArgumentList(QStringLiteral("refresh_status"), argumentList);
+ }
+
+ inline QDBusPendingReply<QString> start()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QStringLiteral("start"), argumentList);
+ }
+
+ inline QDBusPendingReply<QString> status(int pid)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(pid);
+ return asyncCallWithArgumentList(QStringLiteral("status"), argumentList);
+ }
+
+ inline QDBusPendingReply<QString> stop(int pid)
+ {
+ QList<QVariant> 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 <QApplication>
+#include <QQmlApplicationEngine>
+#include <QQmlComponent>
+#include <QQmlProperty>
+#include <QQuickItem>
+#include <QObject>
+#include <QTranslator>
+#include <QDebug>
+#include <QQmlContext>
+#include <QQuickStyle>
+#include <signal.h>
+
+#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<MainQMLAdaptor> 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> 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<QQuickItem*>("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<QQuickItem*>("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<QQuickItem*>("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<QQuickItem*>("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 <QObject>
+#include <QQmlApplicationEngine>
+#include <QQuickItem>
+#include <QMessageBox>
+#include <QApplication>
+#include <QClipboard>
+
+//#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<QString> 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<QString> 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<QString> 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 <QObject>
+#include <QQmlApplicationEngine>
+#include <QQuickItem>
+#include <QTimerEvent>
+#include <QTranslator>
+#include <QtDBus/QtDBus>
+
+#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();
+};