Prechádzať zdrojové kódy

Resolve "US51: GUI final layout change"

Sander, Paul 4 rokov pred
rodič
commit
1fe350c835
33 zmenil súbory, kde vykonal 926 pridanie a 753 odobranie
  1. 68 0
      gui/Readme.md
  2. 1 0
      gui/include/cmdmanager.h
  3. 1 0
      gui/include/jsonhandler.h
  4. 21 23
      gui/include/qmlhandler.h
  5. 20 1
      gui/src/Forms/Connect/IpPopup.ui.qml
  6. 0 120
      gui/src/Forms/Connect/LoginForm.ui.qml
  7. 312 2
      gui/src/Forms/Connect/LoginSignupPopup.ui.qml
  8. 0 148
      gui/src/Forms/Connect/SignupForm.ui.qml
  9. 0 20
      gui/src/Forms/Help/HelpForm.ui.qml
  10. 40 0
      gui/src/Forms/Log/LogForm.ui.qml
  11. 29 47
      gui/src/Forms/Main/FooterForm.ui.qml
  12. 6 2
      gui/src/Forms/Main/InvalidCliPathPopup.ui.qml
  13. 5 1
      gui/src/Forms/Main/InvalidConfigPopup.ui.qml
  14. 6 2
      gui/src/Forms/Main/NoConfigFoundPopup.ui.qml
  15. 66 32
      gui/src/Forms/Main/main.qml
  16. 0 84
      gui/src/Forms/Messages/MessagesForm.ui.qml
  17. 0 2
      gui/src/Forms/Notifications/NotificationTemplate.ui.qml
  18. 2 3
      gui/src/Forms/Notifications/NotificationsForm.ui.qml
  19. 0 76
      gui/src/Forms/Receiving/ReceivingForm.ui.qml
  20. 0 95
      gui/src/Forms/Sending/SendingForm.ui.qml
  21. 9 10
      gui/src/Forms/ServerFiles/ServerFilesFileTemplate.ui.qml
  22. 6 2
      gui/src/Forms/ServerFiles/ServerFilesFileTemplateDeletePopup.ui.qml
  23. 225 0
      gui/src/Forms/ServerFiles/ServerFilesForm.ui.qml
  24. 9 1
      gui/src/Forms/Settings/DeleteMePopup.ui.qml
  25. 14 19
      gui/src/Forms/Settings/SettingsForm.ui.qml
  26. 6 9
      gui/src/climanager.cpp
  27. 28 14
      gui/src/cmdmanager.cpp
  28. BIN
      gui/src/images/tray-icon.png
  29. 23 3
      gui/src/jsonhandler.cpp
  30. 1 0
      gui/src/main.cpp
  31. 5 13
      gui/src/qml.qrc
  32. 18 22
      gui/src/qmlhandler.cpp
  33. 5 2
      gui/src/qtquickcontrols2.conf

+ 68 - 0
gui/Readme.md

@@ -0,0 +1,68 @@
+# Using the Graphical User Interface (GUI)
+
+The GUI of the Covert Channel Application provides an easy way to interact with a covert channel server. It is using the CLI for this interaction, so a valid CLI executable is required for it to work.
+
+
+## Starting the GUI
+
+The graphical user interface should be started without any additional parameters.
+
+
+## Configuration
+
+The GUI uses a configuration file. This file should be called <i>configGUI.txt</i> and should be located in the same folder where the GUI is executed from. On start, the program will check if a valid configuration file exists and if the specified CLI path is valid.
+
+If no configuration file exists, the program will generate a default file. The user will be notified about this and will be asked to set a path to the CLI.
+
+If the configuration file is not valid, the user will get notified and has the option to either quit the program or to generate the default configuration file. The latter would overwrite the existing one.
+
+### Configuration Values
+
+`Autofill-IP`: Should the default IP automatically be filled in on startup.<br/>
+`Autofill-Username`: Should the default Username automatically be filled in on startup.<br/>
+`CLI-Path`: The absolute path to the command line interface (CLI) file.<br/>
+`Default-IP`: The default IP to be used for the autofill.<br/>
+`Default-Username`: The default Username to be used for the autofill.<br/>
+`Keyfile-Path`: The absolute path to the keyfile to be used for encryption.<br/>
+
+
+## Connecting to a server
+
+On startup, the GUI asks the user for an IP-address to connect to. This address can contain a port (for example `127.0.0.1:1234`). If no port is specified, the default port <i>1234</i> is used. Additionally, the user has the option to set the given IP-address as the default one in the configuration file.
+
+If the connection was successful, the user will be asked to either log in or sign up using the given forms. Additionally, the user has the option to set the given username as the default one in the configuration file.
+
+
+## Layout Overview
+
+The GUI is splitted into 3 parts: The menubar, the main window and the footer.
+
+The menubar on the top gives the user the option to change the server, to quit the application and to show the <i>about</i> page.
+
+The footer shows the user some information about his active connection such as the server status, the IP-address and their username. Additionally, any error that occurs will be shown here for 3 seconds.
+
+The main window contains of the following 4 tabs:
+
+### Server Files
+
+This tab shows the user all the files that are currently on the server, including their size, encryption and status. The user has the option to enqueue/dequeue, download or delete the files.
+
+Downloading a file will download it to the same folder where the GUI is executed from.
+
+At the bottom, the user can select a file to be uploaded to the server. The selection is done with a file dialog.
+
+### Notifications
+
+This tab shows the user all notifications that get sent from the server (for example when a transfer is complete). Every notification can be dismissed. Additionally, notifications will trigger a system notification.
+
+The title of this tab will contain a star (<b>* Notifications</b>) when there is a new notification.
+
+### Settings
+
+This tab shows the user the current settings that are specified in the configuration file. These can be changed and saved to the file. Additionally the user has the option to reset the settings to the default values.
+
+In this tab, the user can also delete his account from the server. This requires the users password.
+
+### Log
+
+This tab shows the user the log.

+ 1 - 0
gui/include/cmdmanager.h

@@ -51,6 +51,7 @@ void handleDequeue(Json::Value root);
 void handleExtendedStatus(Json::Value root);
 void handleExtendedStatus(Json::Value root);
 void handleKeyfile(Json::Value root);
 void handleKeyfile(Json::Value root);
 void handleClosekey(Json::Value root);
 void handleClosekey(Json::Value root);
+void handleDisconnect(Json::Value root);
 } // namespace CmdManager
 } // namespace CmdManager
 
 
 #endif // CMDMANAGER_H
 #endif // CMDMANAGER_H

+ 1 - 0
gui/include/jsonhandler.h

@@ -5,6 +5,7 @@
 #include <json/json.h>
 #include <json/json.h>
 
 
 namespace JsonHandler {
 namespace JsonHandler {
+void setQmlHandler(QMLHandler *q);
 void parseJSON(std::string buffer);
 void parseJSON(std::string buffer);
 } // namespace JsonHandler
 } // namespace JsonHandler
 
 

+ 21 - 23
gui/include/qmlhandler.h

@@ -34,17 +34,16 @@ signals:
 	void invalidConfigPopupOpen();
 	void invalidConfigPopupOpen();
 	void invalidConfigPopupClose();
 	void invalidConfigPopupClose();
 
 
-	// Sending
-	void sendingSetFileUrlText(QString signalText);
-	void sendingEnableSendButton();
-	void sendingDisableSendButton();
-
-	// Receiving
-	void receivingClearFileList();
-	void receivingListFile(QString fileName, QString fileSize, QString fileDecryptable, bool existsLocally);
-	void receivingUpdateFile(QString fileName, QString fileProgress, bool isQueued);
-	void receivingDisableDownloadButton(QString fileName);
-	void receivingCloseConfirmDeletePopup();
+	// Server Files
+	void serverFilesSetFileUrlText(QString signalText);
+	void serverFilesEnableSendButton();
+	void serverFilesDisableSendButton();
+
+	void serverFilesClearFileList();
+	void serverFilesListFile(QString fileName, QString fileSize, QString fileDecryptable, bool existsLocally);
+	void serverFilesUpdateFile(QString fileName, QString fileProgress, bool isQueued);
+	void serverFilesDisableDownloadButton(QString fileName);
+	void serverFilesCloseConfirmDeletePopup();
 
 
 	// Messages
 	// Messages
 	void message(QString msg);
 	void message(QString msg);
@@ -86,6 +85,7 @@ signals:
 	// Footer
 	// Footer
 	void log(QString logText);
 	void log(QString logText);
 	void footerSetStatus(QString status);
 	void footerSetStatus(QString status);
+	void footerSetError(QString error);
 
 
 	// Notifications
 	// Notifications
 	void notification(QString message);
 	void notification(QString message);
@@ -94,7 +94,10 @@ signals:
 
 
 	// QML -> C++
 	// QML -> C++
 public slots:
 public slots:
-	void onStart();
+	// Main
+	void onStart(bool startWithCli);
+
+	void onSwitchServer();
 
 
 	// No Config Found Popup
 	// No Config Found Popup
 	void onNoConfigFoundPopupContinueButton(QString cli_path);
 	void onNoConfigFoundPopupContinueButton(QString cli_path);
@@ -107,15 +110,13 @@ public slots:
 	void onInvalidConfigPopupCreateDefaultButton();
 	void onInvalidConfigPopupCreateDefaultButton();
 	void onInvalidConfigPopupQuitButton();
 	void onInvalidConfigPopupQuitButton();
 
 
-	// Sending
-	void onSendingSelectFileButton(QUrl url);
-	void onSendingSendFileButton();
-	void onSendingClearSelectionButton();
+	// Server Files
+	void onServerFilesSelectFileButton(QUrl url);
+	void onServerFilesSendFileButton();
+	void onServerFilesClearSelectionButton();
 
 
-	// Receiving
-	void onReceivingListFilesButton();
-	void onReceivingDownloadFileButton(QString fileName);
-	void onReceivingConfirmDeleteFileButton(QString fileName);
+	void onServerFilesDownloadFileButton(QString fileName);
+	void onServerFilesConfirmDeleteFileButton(QString fileName);
 
 
 	// Messages
 	// Messages
 	void onMessagesSendButton(QString msg);
 	void onMessagesSendButton(QString msg);
@@ -137,9 +138,6 @@ public slots:
 	// Signup
 	// Signup
 	void onSignupRegisterButton(QString username, QString passwordOne, QString passwordTwo, bool saveAsDefault);
 	void onSignupRegisterButton(QString username, QString passwordOne, QString passwordTwo, bool saveAsDefault);
 
 
-	// Footer
-	void onFooterGetStatusButton();
-
 	// Notifications
 	// Notifications
 	void onDismissNotificationButton(int id);
 	void onDismissNotificationButton(int id);
 
 

+ 20 - 1
gui/src/Forms/Connect/IpPopup.ui.qml

@@ -13,6 +13,16 @@ Popup {
     closePolicy: Popup.NoAutoClose
     closePolicy: Popup.NoAutoClose
     anchors.centerIn: Overlay.overlay
     anchors.centerIn: Overlay.overlay
 
 
+    signal resetOnClose
+
+    onClosed: {
+        resetOnClose()
+    }
+
+    Overlay.modal: Rectangle {
+        color: "#b5c5c5c5"
+    }
+
     Connections {
     Connections {
         target: _qmlHandler
         target: _qmlHandler
         onIpPopupSetIP: {
         onIpPopupSetIP: {
@@ -45,7 +55,6 @@ Popup {
         Text {
         Text {
             Layout.alignment: Qt.AlignCenter
             Layout.alignment: Qt.AlignCenter
             id: ipPopupText
             id: ipPopupText
-            color: "#ffffff"
             text: qsTr("Enter the IP to connect:")
             text: qsTr("Enter the IP to connect:")
             horizontalAlignment: Text.AlignHCenter
             horizontalAlignment: Text.AlignHCenter
             verticalAlignment: Text.AlignVCenter
             verticalAlignment: Text.AlignVCenter
@@ -69,6 +78,11 @@ Popup {
             Keys.onEnterPressed: ipPopupConnectButton.activate()
             Keys.onEnterPressed: ipPopupConnectButton.activate()
 
 
             onTextEdited: ipPopupConnectButton.enabled = ipPopupIpInput.acceptableInput
             onTextEdited: ipPopupConnectButton.enabled = ipPopupIpInput.acceptableInput
+
+            Connections {
+                target: popup
+                onResetOnClose: ipPopupIpInput.text = ""
+            }
         }
         }
 
 
         CheckBox {
         CheckBox {
@@ -88,6 +102,11 @@ Popup {
             font.pixelSize: 20
             font.pixelSize: 20
             wrapMode: Text.WordWrap
             wrapMode: Text.WordWrap
             Layout.preferredWidth: parent.width
             Layout.preferredWidth: parent.width
+
+            Connections {
+                target: popup
+                onResetOnClose: ipPopupStatusText.text = ""
+            }
         }
         }
 
 
         Button {
         Button {

+ 0 - 120
gui/src/Forms/Connect/LoginForm.ui.qml

@@ -1,120 +0,0 @@
-import QtQuick 2.12
-import QtQuick.Controls 2.5
-import QtQuick.Layouts 1.3
-
-Page {
-    width: 400
-    height: 400
-    title: ""
-
-    Connections {
-        target: _qmlHandler
-        onLoginSetUsername: {
-            loginUsernameInput.text = username
-        }
-        onLoginSetStatus: {
-            loginStatusText.text = status
-        }
-        onLoginEnableLoginButton: {
-            loginLoginButton.enabled = true
-        }
-        onLoginDisableLoginButton: {
-            loginLoginButton.enabled = false
-        }
-        onLoginSignupCheckSaveCheckbox: {
-            loginSetDefaultCheckbox.checked = true
-        }
-    }
-
-    ColumnLayout {
-        anchors.fill: parent
-
-        Text {
-            Layout.alignment: Qt.AlignCenter
-            id: loginTitle
-            color: "#ffffff"
-            text: qsTr("Login")
-            horizontalAlignment: Text.AlignHCenter
-            verticalAlignment: Text.AlignVCenter
-            font.pixelSize: 20
-        }
-
-        TextField {
-            Layout.alignment: Qt.AlignCenter
-            id: loginUsernameInput
-            selectByMouse: true
-            focus: true
-            text: qsTr("")
-            placeholderText: "Username"
-            horizontalAlignment: Text.AlignHCenter
-            // @disable-check M222
-            Keys.onReturnPressed: loginLoginButton.activate()
-            // @disable-check M222
-            Keys.onEnterPressed: loginLoginButton.activate()
-
-            onTextEdited: loginLoginButton.enabled = (loginUsernameInput.text != ""
-                                                      && loginPasswordInput.text != "")
-        }
-
-        TextField {
-            Layout.alignment: Qt.AlignCenter
-            id: loginPasswordInput
-            selectByMouse: true
-            text: qsTr("")
-            placeholderText: "Password"
-            horizontalAlignment: Text.AlignHCenter
-            // @disable-check M222
-            Keys.onReturnPressed: loginLoginButton.activate()
-            // @disable-check M222
-            Keys.onEnterPressed: loginLoginButton.activate()
-            echoMode: TextInput.Password
-
-            onTextEdited: loginLoginButton.enabled = (loginUsernameInput.text != ""
-                                                      && loginPasswordInput.text != "")
-        }
-
-        CheckBox {
-            id: loginSetDefaultCheckbox
-            Layout.alignment: Qt.AlignCenter
-            checked: false
-            text: "Save as default user"
-        }
-
-        Text {
-            id: loginStatusText
-            color: "#df3f3f"
-            text: qsTr("")
-            wrapMode: Text.WordWrap
-            Layout.preferredWidth: parent.width
-            horizontalAlignment: Text.AlignHCenter
-            verticalAlignment: Text.AlignVCenter
-            Layout.alignment: Qt.AlignCenter
-            font.pixelSize: 20
-        }
-
-        Button {
-            Layout.alignment: Qt.AlignCenter
-            id: loginLoginButton
-            text: qsTr("Login")
-            enabled: false
-            font.pointSize: 16
-            // @disable-check M223
-            onClicked: {
-                // @disable-check M222
-                loginLoginButton.activate()
-            }
-
-            // @disable-check M222
-            function activate() {
-                // @disable-check M223
-                if (loginLoginButton.enabled) {
-                    // @disable-check M222
-                    _qmlHandler.onLoginLoginButton(
-                                loginUsernameInput.text,
-                                loginPasswordInput.text,
-                                loginSetDefaultCheckbox.checked)
-                }
-            }
-        }
-    }
-}

+ 312 - 2
gui/src/Forms/Connect/LoginSignupPopup.ui.qml

@@ -13,6 +13,16 @@ Popup {
     closePolicy: Popup.NoAutoClose
     closePolicy: Popup.NoAutoClose
     anchors.centerIn: Overlay.overlay
     anchors.centerIn: Overlay.overlay
 
 
+    signal resetOnClose
+
+    onClosed: {
+        resetOnClose()
+    }
+
+    Overlay.modal: Rectangle {
+        color: "#b5c5c5c5"
+    }
+
     Connections {
     Connections {
         target: _qmlHandler
         target: _qmlHandler
         onLoginSignupPopupClose: {
         onLoginSignupPopupClose: {
@@ -21,6 +31,33 @@ Popup {
         onLoginSignupPopupOpen: {
         onLoginSignupPopupOpen: {
             popup.open()
             popup.open()
         }
         }
+
+        onLoginSetUsername: {
+            loginUsernameInput.text = username
+        }
+        onLoginSetStatus: {
+            loginStatusText.text = status
+        }
+        onLoginEnableLoginButton: {
+            loginLoginButton.enabled = true
+        }
+        onLoginDisableLoginButton: {
+            loginLoginButton.enabled = false
+        }
+        onLoginSignupCheckSaveCheckbox: {
+            loginSetDefaultCheckbox.checked = true
+            signupSetDefaultCheckbox.checked = true
+        }
+
+        onSignupSetStatus: {
+            signupStatusText.text = status
+        }
+        onSignupEnableRegisterButton: {
+            signupRegisterButton.enabled = true
+        }
+        onSignupDisableRegisterButton: {
+            signupRegisterButton.enabled = false
+        }
     }
     }
 
 
     Page {
     Page {
@@ -46,10 +83,283 @@ Popup {
             currentIndex: header.currentIndex
             currentIndex: header.currentIndex
             clip: true
             clip: true
 
 
-            LoginForm {
+            // Login
+            Page {
+                width: 400
+                height: 400
+                title: ""
+
+                ColumnLayout {
+                    anchors.fill: parent
+
+                    Text {
+                        Layout.alignment: Qt.AlignCenter
+                        id: loginTitle
+
+                        text: qsTr("Login")
+                        horizontalAlignment: Text.AlignHCenter
+                        verticalAlignment: Text.AlignVCenter
+                        font.pixelSize: 20
+                    }
+
+                    TextField {
+                        Layout.alignment: Qt.AlignCenter
+                        id: loginUsernameInput
+                        selectByMouse: true
+                        focus: true
+                        text: qsTr("")
+                        placeholderText: "Username"
+                        horizontalAlignment: Text.AlignHCenter
+                        // @disable-check M222
+                        Keys.onReturnPressed: loginLoginButton.activate()
+                        // @disable-check M222
+                        Keys.onEnterPressed: loginLoginButton.activate()
+
+                        onTextEdited: loginLoginButton.enabled
+                                      = (loginUsernameInput.text != ""
+                                         && loginPasswordInput.text != "")
+
+                        Connections {
+                            target: popup
+                            onResetOnClose: loginUsernameInput.text = ""
+                        }
+                    }
+
+                    TextField {
+                        Layout.alignment: Qt.AlignCenter
+                        id: loginPasswordInput
+                        selectByMouse: true
+                        text: qsTr("")
+                        placeholderText: "Password"
+                        horizontalAlignment: Text.AlignHCenter
+                        // @disable-check M222
+                        Keys.onReturnPressed: loginLoginButton.activate()
+                        // @disable-check M222
+                        Keys.onEnterPressed: loginLoginButton.activate()
+                        echoMode: TextInput.Password
+
+                        onTextEdited: loginLoginButton.enabled
+                                      = (loginUsernameInput.text != ""
+                                         && loginPasswordInput.text != "")
+
+                        Connections {
+                            target: popup
+                            onResetOnClose: loginPasswordInput.text = ""
+                        }
+                    }
+
+                    CheckBox {
+                        id: loginSetDefaultCheckbox
+                        Layout.alignment: Qt.AlignCenter
+                        checked: false
+                        text: "Save as default user"
+
+                        Connections {
+                            target: popup
+                            onResetOnClose: loginSetDefaultCheckbox.checked = false
+                        }
+                    }
+
+                    Text {
+                        id: loginStatusText
+                        color: "#df3f3f"
+                        text: qsTr("")
+                        wrapMode: Text.WordWrap
+                        Layout.preferredWidth: parent.width
+                        horizontalAlignment: Text.AlignHCenter
+                        verticalAlignment: Text.AlignVCenter
+                        Layout.alignment: Qt.AlignCenter
+                        font.pixelSize: 20
+
+                        Connections {
+                            target: popup
+                            onResetOnClose: loginStatusText.text = ""
+                        }
+                    }
+
+                    Button {
+                        Layout.alignment: Qt.AlignCenter
+                        id: loginLoginButton
+                        text: qsTr("Login")
+                        enabled: false
+                        font.pointSize: 16
+                        // @disable-check M223
+                        onClicked: {
+                            // @disable-check M222
+                            loginLoginButton.activate()
+                        }
+
+                        // @disable-check M222
+                        function activate() {
+                            // @disable-check M223
+                            if (loginLoginButton.enabled) {
+                                // @disable-check M222
+                                _qmlHandler.onLoginLoginButton(
+                                            loginUsernameInput.text,
+                                            loginPasswordInput.text,
+                                            loginSetDefaultCheckbox.checked)
+                            }
+                        }
+                    }
+                }
             }
             }
 
 
-            SignupForm {
+            // Signup
+            Page {
+                width: 400
+                height: 400
+
+                ColumnLayout {
+                    anchors.fill: parent
+
+                    Text {
+                        Layout.alignment: Qt.AlignCenter
+                        id: signupTitle
+
+                        text: qsTr("Signup")
+                        horizontalAlignment: Text.AlignHCenter
+                        verticalAlignment: Text.AlignVCenter
+                        font.pixelSize: 20
+                    }
+
+                    TextField {
+                        Layout.alignment: Qt.AlignCenter
+                        id: signupUsernameInput
+                        selectByMouse: true
+                        focus: true
+                        text: qsTr("")
+                        placeholderText: "Username"
+                        horizontalAlignment: Text.AlignHCenter
+                        // @disable-check M222
+                        Keys.onReturnPressed: signupRegisterButton.activate()
+                        // @disable-check M222
+                        Keys.onEnterPressed: signupRegisterButton.activate()
+
+                        onTextEdited: {
+                            signupStatusText.text = ""
+                            signupRegisterButton.enabled
+                                    = (signupUsernameInput.text != ""
+                                       && signupPasswordOneInput.text != ""
+                                       && signupPasswordTwoInput.text != "")
+                        }
+
+                        Connections {
+                            target: popup
+                            onResetOnClose: signupUsernameInput.text = ""
+                        }
+                    }
+
+                    TextField {
+                        Layout.alignment: Qt.AlignCenter
+                        id: signupPasswordOneInput
+                        selectByMouse: true
+                        focus: true
+                        text: qsTr("")
+                        placeholderText: "Password"
+                        horizontalAlignment: Text.AlignHCenter
+                        // @disable-check M222
+                        Keys.onReturnPressed: signupRegisterButton.activate()
+                        // @disable-check M222
+                        Keys.onEnterPressed: signupRegisterButton.activate()
+                        echoMode: TextInput.Password
+
+                        onTextEdited: {
+                            signupStatusText.text = ""
+                            signupRegisterButton.enabled
+                                    = (signupUsernameInput.text != ""
+                                       && signupPasswordOneInput.text != ""
+                                       && signupPasswordTwoInput.text != "")
+                        }
+
+                        Connections {
+                            target: popup
+                            onResetOnClose: signupPasswordOneInput.text = ""
+                        }
+                    }
+
+                    TextField {
+                        Layout.alignment: Qt.AlignCenter
+                        id: signupPasswordTwoInput
+                        selectByMouse: true
+                        focus: true
+                        text: qsTr("")
+                        placeholderText: "Repeat Passw."
+                        horizontalAlignment: Text.AlignHCenter
+                        // @disable-check M222
+                        Keys.onReturnPressed: signupRegisterButton.activate()
+                        // @disable-check M222
+                        Keys.onEnterPressed: signupRegisterButton.activate()
+                        echoMode: TextInput.Password
+
+                        onTextEdited: {
+                            signupStatusText.text = ""
+                            signupRegisterButton.enabled
+                                    = (signupUsernameInput.text != ""
+                                       && signupPasswordOneInput.text != ""
+                                       && signupPasswordTwoInput.text != "")
+                        }
+
+                        Connections {
+                            target: popup
+                            onResetOnClose: signupPasswordTwoInput.text = ""
+                        }
+                    }
+
+                    CheckBox {
+                        id: signupSetDefaultCheckbox
+                        Layout.alignment: Qt.AlignCenter
+                        checked: false
+                        text: "Save as default user"
+
+                        Connections {
+                            target: popup
+                            onResetOnClose: signupSetDefaultCheckbox.checked = false
+                        }
+                    }
+
+                    Text {
+                        id: signupStatusText
+                        color: "#df3f3f"
+                        text: qsTr("")
+                        horizontalAlignment: Text.AlignHCenter
+                        verticalAlignment: Text.AlignVCenter
+                        Layout.alignment: Qt.AlignCenter
+                        wrapMode: Text.WordWrap
+                        Layout.preferredWidth: parent.width
+                        font.pixelSize: 20
+
+                        Connections {
+                            target: popup
+                            onResetOnClose: signupStatusText.text = ""
+                        }
+                    }
+
+                    Button {
+                        Layout.alignment: Qt.AlignCenter
+                        id: signupRegisterButton
+                        text: qsTr("Register")
+                        enabled: false
+                        font.pointSize: 16
+                        // @disable-check M223
+                        onClicked: {
+                            // @disable-check M222
+                            signupRegisterButton.activate()
+                        }
+
+                        // @disable-check M222
+                        function activate() {
+                            // @disable-check M223
+                            if (signupRegisterButton.enabled) {
+                                // @disable-check M222
+                                _qmlHandler.onSignupRegisterButton(
+                                            signupUsernameInput.text,
+                                            signupPasswordOneInput.text,
+                                            signupPasswordTwoInput.text,
+                                            signupSetDefaultCheckbox.checked)
+                            }
+                        }
+                    }
+                }
             }
             }
         }
         }
     }
     }

+ 0 - 148
gui/src/Forms/Connect/SignupForm.ui.qml

@@ -1,148 +0,0 @@
-import QtQuick 2.12
-import QtQuick.Controls 2.5
-import QtQuick.Layouts 1.3
-
-Page {
-    width: 400
-    height: 400
-
-    Connections {
-        target: _qmlHandler
-        onSignupSetStatus: {
-            signupStatusText.text = status
-        }
-        onSignupEnableRegisterButton: {
-            signupRegisterButton.enabled = true
-        }
-        onSignupDisableRegisterButton: {
-            signupRegisterButton.enabled = false
-        }
-        onLoginSignupCheckSaveCheckbox: {
-            signupSetDefaultCheckbox.checked = true
-        }
-    }
-
-    ColumnLayout {
-        anchors.fill: parent
-
-        Text {
-            Layout.alignment: Qt.AlignCenter
-            id: signupTitle
-            color: "#ffffff"
-            text: qsTr("Signup")
-            horizontalAlignment: Text.AlignHCenter
-            verticalAlignment: Text.AlignVCenter
-            font.pixelSize: 20
-        }
-
-        TextField {
-            Layout.alignment: Qt.AlignCenter
-            id: signupUsernameInput
-            selectByMouse: true
-            focus: true
-            text: qsTr("")
-            placeholderText: "Username"
-            horizontalAlignment: Text.AlignHCenter
-            // @disable-check M222
-            Keys.onReturnPressed: signupRegisterButton.activate()
-            // @disable-check M222
-            Keys.onEnterPressed: signupRegisterButton.activate()
-
-            onTextEdited: {
-                signupStatusText.text = ""
-                signupRegisterButton.enabled = (signupUsernameInput.text != ""
-                                                && signupPasswordOneInput.text != ""
-                                                && signupPasswordTwoInput.text != "")
-            }
-        }
-
-        TextField {
-            Layout.alignment: Qt.AlignCenter
-            id: signupPasswordOneInput
-            selectByMouse: true
-            focus: true
-            text: qsTr("")
-            placeholderText: "Password"
-            horizontalAlignment: Text.AlignHCenter
-            // @disable-check M222
-            Keys.onReturnPressed: signupRegisterButton.activate()
-            // @disable-check M222
-            Keys.onEnterPressed: signupRegisterButton.activate()
-            echoMode: TextInput.Password
-
-            onTextEdited: {
-                signupStatusText.text = ""
-                signupRegisterButton.enabled = (signupUsernameInput.text != ""
-                                                && signupPasswordOneInput.text != ""
-                                                && signupPasswordTwoInput.text != "")
-            }
-        }
-
-        TextField {
-            Layout.alignment: Qt.AlignCenter
-            id: signupPasswordTwoInput
-            selectByMouse: true
-            focus: true
-            text: qsTr("")
-            placeholderText: "Repeat Passw."
-            horizontalAlignment: Text.AlignHCenter
-            // @disable-check M222
-            Keys.onReturnPressed: signupRegisterButton.activate()
-            // @disable-check M222
-            Keys.onEnterPressed: signupRegisterButton.activate()
-            echoMode: TextInput.Password
-
-            onTextEdited: {
-                signupStatusText.text = ""
-                signupRegisterButton.enabled = (signupUsernameInput.text != ""
-                                                && signupPasswordOneInput.text != ""
-                                                && signupPasswordTwoInput.text != "")
-            }
-        }
-
-        CheckBox {
-            id: signupSetDefaultCheckbox
-            Layout.alignment: Qt.AlignCenter
-            checked: false
-            text: "Save as default user"
-        }
-
-        Text {
-            id: signupStatusText
-            color: "#df3f3f"
-            text: qsTr("")
-            horizontalAlignment: Text.AlignHCenter
-            verticalAlignment: Text.AlignVCenter
-            Layout.alignment: Qt.AlignCenter
-            wrapMode: Text.WordWrap
-            Layout.preferredWidth: parent.width
-            font.pixelSize: 20
-        }
-
-        Button {
-            Layout.alignment: Qt.AlignCenter
-            id: signupRegisterButton
-            text: qsTr("Register")
-            enabled: false
-            font.pointSize: 16
-            // @disable-check M223
-            onClicked: {
-                // @disable-check M222
-                signupRegisterButton.activate()
-            }
-
-            // @disable-check M222
-            function activate() {
-                // @disable-check M223
-                if (signupRegisterButton.enabled) {
-                    // @disable-check M222
-                    _qmlHandler.onSignupRegisterButton(
-                                signupUsernameInput.text,
-                                signupPasswordOneInput.text,
-                                signupPasswordTwoInput.text,
-                                signupSetDefaultCheckbox.checked)
-                }
-            }
-        }
-    }
-}

+ 0 - 20
gui/src/Forms/Help/HelpForm.ui.qml

@@ -1,20 +0,0 @@
-import QtQuick 2.12
-import QtQuick.Controls 2.5
-
-Page {
-    width: 1280
-    height: 470
-
-    Text {
-        id: helpPlaceholder
-        x: 220
-        y: 135
-        width: 840
-        height: 200
-        color: "#ffffff"
-        text: qsTr("Tons of useful information goes here")
-        horizontalAlignment: Text.AlignHCenter
-        verticalAlignment: Text.AlignVCenter
-        font.pixelSize: 40
-    }
-}

+ 40 - 0
gui/src/Forms/Log/LogForm.ui.qml

@@ -0,0 +1,40 @@
+import QtQuick 2.4
+import QtQuick.Controls 2.4
+import QtQuick.Layouts 1.3
+
+Page {
+    width: 1280
+    height: 570
+    id: logForm
+
+    font.capitalization: Font.MixedCase
+
+    Connections {
+        target: _qmlHandler
+        onLog: {
+            log.append(new Date().toLocaleTimeString(Qt.locale("C"),
+                                                     "[hh:mm:ss]\n") + logText)
+            logFlickable.contentY = log.height - logFlickable.height
+        }
+    }
+
+    Flickable {
+        anchors.fill: parent
+        id: logFlickable
+        flickableDirection: Flickable.VerticalFlick
+        Layout.preferredHeight: 170
+        Layout.preferredWidth: parent.width
+
+        TextArea.flickable: TextArea {
+            selectByMouse: true
+            id: log
+            readOnly: true
+            wrapMode: TextArea.Wrap
+            text: qsTr("")
+            font.pointSize: 15
+        }
+
+        ScrollBar.vertical: ScrollBar {
+        }
+    }
+}

+ 29 - 47
gui/src/Forms/Main/FooterForm.ui.qml

@@ -4,75 +4,57 @@ import QtQuick.Layouts 1.3
 
 
 Page {
 Page {
     width: 1280
     width: 1280
-    height: 200
+    height: 70
 
 
     font.capitalization: Font.MixedCase
     font.capitalization: Font.MixedCase
 
 
     Connections {
     Connections {
         target: _qmlHandler
         target: _qmlHandler
-        onLog: {
-            footerLog.append(new Date().toLocaleTimeString(
-                                 Qt.locale("C"), "[hh:mm:ss]\n") + logText)
-            footerFlickable.contentY = footerLog.height - footerFlickable.height
-        }
-
         onFooterSetStatus: {
         onFooterSetStatus: {
             footerStatusText.text = "Status: " + status
             footerStatusText.text = "Status: " + status
         }
         }
+
+        onFooterSetError: {
+            footerErrorText.text = "Error: " + error
+            timer.start()
+        }
     }
     }
 
 
     Rectangle {
     Rectangle {
         anchors.fill: parent
         anchors.fill: parent
-        color: "#404040"
+        color: "#c4c4c4"
 
 
         ColumnLayout {
         ColumnLayout {
+            spacing: 3
             anchors.fill: parent
             anchors.fill: parent
 
 
-            RowLayout {
-                Layout.preferredHeight: 30
+            Text {
+                id: footerStatusText
                 Layout.preferredWidth: parent.width
                 Layout.preferredWidth: parent.width
 
 
-                Text {
-                    id: footerStatusText
-                    Layout.preferredHeight: parent.height
-                    Layout.preferredWidth: 1000
-                    color: "#ffffff"
-                    text: qsTr("")
-                    font.pixelSize: 23
-                }
-
-                Button {
-                    id: footerGetStatusButton
-                    Layout.preferredHeight: 30
-                    Layout.preferredWidth: 250
-                    text: qsTr("Get Status")
-                    // @disable-check M223
-                    onClicked: {
-                        footerStatusText.text = ""
-                        // @disable-check M222
-                        _qmlHandler.onFooterGetStatusButton()
-                    }
-                }
+                text: qsTr("")
+                Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+                verticalAlignment: Text.AlignVCenter
+                font.pixelSize: 23
             }
             }
 
 
-            Flickable {
-                id: footerFlickable
-                flickableDirection: Flickable.VerticalFlick
-                Layout.preferredHeight: 170
+            Text {
+                id: footerErrorText
                 Layout.preferredWidth: parent.width
                 Layout.preferredWidth: parent.width
-
-                TextArea.flickable: TextArea {
-                    selectByMouse: true
-                    id: footerLog
-                    readOnly: true
-                    wrapMode: TextArea.Wrap
-                    text: qsTr("")
-                    font.pointSize: 15
-                }
-
-                ScrollBar.vertical: ScrollBar {
-                }
+                color: "#fa3737"
+                text: qsTr("")
+                Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+                verticalAlignment: Text.AlignVCenter
+                font.pixelSize: 23
             }
             }
         }
         }
     }
     }
+
+    Timer {
+        id: timer
+        interval: 3000
+        onTriggered: {
+            footerErrorText.text = ""
+        }
+    }
 }
 }

+ 6 - 2
gui/src/Forms/Main/InvalidCliPathPopup.ui.qml

@@ -14,6 +14,10 @@ Popup {
     closePolicy: Popup.NoAutoClose
     closePolicy: Popup.NoAutoClose
     anchors.centerIn: Overlay.overlay
     anchors.centerIn: Overlay.overlay
 
 
+    Overlay.modal: Rectangle {
+        color: "#b5c5c5c5"
+    }
+
     Connections {
     Connections {
         target: _qmlHandler
         target: _qmlHandler
         onInvalidCliPathPopupClose: {
         onInvalidCliPathPopupClose: {
@@ -32,7 +36,7 @@ Popup {
             Layout.preferredWidth: parent.width
             Layout.preferredWidth: parent.width
             Layout.preferredHeight: 50
             Layout.preferredHeight: 50
             id: invalidCliPathPopupText
             id: invalidCliPathPopupText
-            color: "#ffffff"
+
             text: qsTr("Invalid CLI-Path: CLI could not be found on the location specified in the config file.\nPlease specify the new location of the CLI:")
             text: qsTr("Invalid CLI-Path: CLI could not be found on the location specified in the config file.\nPlease specify the new location of the CLI:")
             wrapMode: Text.WordWrap
             wrapMode: Text.WordWrap
             horizontalAlignment: Text.AlignHCenter
             horizontalAlignment: Text.AlignHCenter
@@ -50,7 +54,7 @@ Popup {
                 Layout.preferredHeight: parent.height
                 Layout.preferredHeight: parent.height
                 Layout.preferredWidth: 600
                 Layout.preferredWidth: 600
                 id: invalidCliPathPopupCliPath
                 id: invalidCliPathPopupCliPath
-                color: "#ffffff"
+
                 text: qsTr("Select CLI Path >>>")
                 text: qsTr("Select CLI Path >>>")
                 horizontalAlignment: Text.AlignLeft
                 horizontalAlignment: Text.AlignLeft
                 font.italic: true
                 font.italic: true

+ 5 - 1
gui/src/Forms/Main/InvalidConfigPopup.ui.qml

@@ -14,6 +14,10 @@ Popup {
     closePolicy: Popup.NoAutoClose
     closePolicy: Popup.NoAutoClose
     anchors.centerIn: Overlay.overlay
     anchors.centerIn: Overlay.overlay
 
 
+    Overlay.modal: Rectangle {
+        color: "#b5c5c5c5"
+    }
+
     Connections {
     Connections {
         target: _qmlHandler
         target: _qmlHandler
         onInvalidConfigPopupClose: {
         onInvalidConfigPopupClose: {
@@ -32,7 +36,7 @@ Popup {
             Layout.preferredWidth: parent.width
             Layout.preferredWidth: parent.width
             Layout.preferredHeight: 50
             Layout.preferredHeight: 50
             id: invalidConfigPopupText
             id: invalidConfigPopupText
-            color: "#ffffff"
+
             text: qsTr("Configuration file invalid!\nWarning: Creating the default config will overwrite your config file!")
             text: qsTr("Configuration file invalid!\nWarning: Creating the default config will overwrite your config file!")
             wrapMode: Text.WordWrap
             wrapMode: Text.WordWrap
             horizontalAlignment: Text.AlignHCenter
             horizontalAlignment: Text.AlignHCenter

+ 6 - 2
gui/src/Forms/Main/NoConfigFoundPopup.ui.qml

@@ -14,6 +14,10 @@ Popup {
     closePolicy: Popup.NoAutoClose
     closePolicy: Popup.NoAutoClose
     anchors.centerIn: Overlay.overlay
     anchors.centerIn: Overlay.overlay
 
 
+    Overlay.modal: Rectangle {
+        color: "#b5c5c5c5"
+    }
+
     Connections {
     Connections {
         target: _qmlHandler
         target: _qmlHandler
         onNoConfigFoundPopupClose: {
         onNoConfigFoundPopupClose: {
@@ -32,7 +36,7 @@ Popup {
             Layout.preferredWidth: parent.width
             Layout.preferredWidth: parent.width
             Layout.preferredHeight: 50
             Layout.preferredHeight: 50
             id: noConfigFoundPopupText
             id: noConfigFoundPopupText
-            color: "#ffffff"
+
             text: qsTr("No configuration file found. Default config will be created.\nPlease specify the location of the CLI:")
             text: qsTr("No configuration file found. Default config will be created.\nPlease specify the location of the CLI:")
             wrapMode: Text.WordWrap
             wrapMode: Text.WordWrap
             horizontalAlignment: Text.AlignHCenter
             horizontalAlignment: Text.AlignHCenter
@@ -50,7 +54,7 @@ Popup {
                 Layout.preferredHeight: parent.height
                 Layout.preferredHeight: parent.height
                 Layout.preferredWidth: 600
                 Layout.preferredWidth: 600
                 id: noConfigFoundPopupCliPath
                 id: noConfigFoundPopupCliPath
-                color: "#ffffff"
+
                 text: qsTr("Select CLI Path >>>")
                 text: qsTr("Select CLI Path >>>")
                 horizontalAlignment: Text.AlignLeft
                 horizontalAlignment: Text.AlignLeft
                 font.italic: true
                 font.italic: true

+ 66 - 32
gui/src/Forms/Main/main.qml

@@ -1,12 +1,10 @@
 import QtQuick 2.12
 import QtQuick 2.12
 import QtQuick.Controls 2.5
 import QtQuick.Controls 2.5
-import "../Sending"
-import "../Receiving"
-import "../Messages"
+import "../ServerFiles"
 import "../Settings"
 import "../Settings"
-import "../Help"
 import "../Connect"
 import "../Connect"
 import "../Notifications"
 import "../Notifications"
+import "../Log"
 
 
 ApplicationWindow {
 ApplicationWindow {
     id: window
     id: window
@@ -19,7 +17,7 @@ ApplicationWindow {
 
 
     minimumHeight: height
     minimumHeight: height
     minimumWidth: width
     minimumWidth: width
-    title: qsTr("Covert Channel - Control Panel")
+    title: qsTr("Covert Channel Application")
 
 
     property string notificationTabTitle: "Notifications"
     property string notificationTabTitle: "Notifications"
 
 
@@ -27,25 +25,48 @@ ApplicationWindow {
         target: _qmlHandler
         target: _qmlHandler
 
 
         onNotification: {
         onNotification: {
-            if (swipeView.currentIndex != 5)
+            if (swipeView.currentIndex != 2)
               notificationTabTitle = "* Notifications"
               notificationTabTitle = "* Notifications"
         }
         }
     }
     }
 
 
+    menuBar: MenuBar {
+        contentHeight: 30
+        Menu {
+            title: qsTr("&File")
+            Action {
+                text: qsTr("Change Server...")
+                onTriggered: {
+                    _qmlHandler.onSwitchServer()
+                    _qmlHandler.onStart(false)
+                    ipPopup.open()
+                }
+            }
+            MenuSeparator { }
+            Action {
+                text: qsTr("&Quit")
+                onTriggered: window.close()
+            }
+        }
+        Menu {
+            title: qsTr("&Help")
+            Action {
+                text: qsTr("About")
+                onTriggered: aboutPopup.open()
+            }
+        }
+    }
+
     SwipeView {
     SwipeView {
         id: swipeView
         id: swipeView
         anchors.fill: parent
         anchors.fill: parent
         currentIndex: header.currentIndex
         currentIndex: header.currentIndex
 
 
-        SendingForm {
-
-        }
-
-        ReceivingForm {
+        ServerFilesForm {
 
 
         }
         }
 
 
-        MessagesForm {
+        NotificationsForm {
 
 
         }
         }
 
 
@@ -53,11 +74,7 @@ ApplicationWindow {
 
 
         }
         }
 
 
-        HelpForm {
-
-        }
-
-        NotificationsForm {
+        LogForm {
 
 
         }
         }
     }
     }
@@ -68,15 +85,15 @@ ApplicationWindow {
         contentHeight: 50
         contentHeight: 50
 
 
         TabButton {
         TabButton {
-            text: qsTr("Sending")
+            text: qsTr("Server Files")
         }
         }
 
 
         TabButton {
         TabButton {
-            text: qsTr("Receiving")
-        }
+            text: notificationTabTitle
 
 
-        TabButton {
-            text: qsTr("Messages")
+            onClicked: {
+                text = "Notifications"
+            }
         }
         }
 
 
         TabButton {
         TabButton {
@@ -84,15 +101,7 @@ ApplicationWindow {
         }
         }
 
 
         TabButton {
         TabButton {
-            text: qsTr("Help")
-        }
-
-        TabButton {
-            text: notificationTabTitle
-
-            onClicked: {
-                text = "Notifications"
-            }
+            text: qsTr("Log")
         }
         }
     }
     }
 
 
@@ -120,9 +129,34 @@ ApplicationWindow {
         id: invalidCliPathPopup
         id: invalidCliPathPopup
     }
     }
 
 
+    Popup {
+        id: aboutPopup
+        height: 300
+        dim: true
+        clip: false
+        width: 400
+        modal: true
+        focus: true
+        anchors.centerIn: Overlay.overlay
+
+        Overlay.modal: Rectangle {
+                color: "#b5b5b5e7"
+            }
+
+        TextArea {
+            anchors.fill: parent
+            text: "Covert Channel Application\n\nDeveloped by:\n\nTobias Alexander Wach\nPaul Leonard Sander\nMarius Rescheleit\nDenys Serdyukov\nJonas Pflanzer\n\nLicensed under the GNU General Public License v3.0"
+            wrapMode: Text.WordWrap
+            horizontalAlignment: Text.AlignHCenter
+            verticalAlignment: Text.AlignVCenter
+            font.pixelSize: 20
+        }
+    }
+
+
     Component.onCompleted: {
     Component.onCompleted: {
       swipeView.interactive = false
       swipeView.interactive = false
       ipPopup.open()
       ipPopup.open()
-      _qmlHandler.onStart()
+      _qmlHandler.onStart(true)
     }
     }
 }
 }

+ 0 - 84
gui/src/Forms/Messages/MessagesForm.ui.qml

@@ -1,84 +0,0 @@
-import QtQuick 2.12
-import QtQuick.Controls 2.5
-import QtQuick.Layouts 1.3
-
-Page {
-    width: 1280
-    height: 470
-
-    font.capitalization: Font.MixedCase
-
-    Connections {
-        target: _qmlHandler
-        onMessage: {
-            messagesLog.append(msg)
-            messagesFlickable.contentY = messagesLog.height - messagesFlickable.height
-        }
-    }
-
-    ColumnLayout {
-        anchors.fill: parent
-
-        Flickable {
-            id: messagesFlickable
-            flickableDirection: Flickable.VerticalFlick
-            Layout.preferredHeight: 400
-            Layout.preferredWidth: parent.width
-
-            TextArea.flickable: TextArea {
-                id: messagesLog
-                readOnly: true
-                selectByMouse: true
-                wrapMode: TextArea.Wrap
-                font.pointSize: 15
-            }
-
-            ScrollBar.vertical: ScrollBar {
-            }
-        }
-
-        RowLayout {
-            Layout.preferredHeight: 70
-            Layout.preferredWidth: parent.width
-
-            TextField {
-                id: messagesInputField
-                selectByMouse: true
-                Layout.preferredWidth: 1060
-                Layout.preferredHeight: parent.height
-                placeholderText: "Enter message..."
-                text: qsTr("")
-                font.pixelSize: 20
-                // @disable-check M222
-                Keys.onReturnPressed: messagesSendButton.activate()
-                // @disable-check M222
-                Keys.onEnterPressed: messagesSendButton.activate()
-            }
-
-            Button {
-                id: messagesSendButton
-                Layout.preferredWidth: 180
-                Layout.preferredHeight: parent.height
-                text: qsTr("Send")
-
-                // @disable-check M223
-                onClicked: {
-                    // @disable-check M222
-                    messagesSendButton.activate()
-                }
-
-                enabled: messagesInputField.text != ""
-                // @disable-check M222
-                function activate() {
-                    // @disable-check M223
-                    if (messagesInputField.text != "") {
-                        // @disable-check M222
-                        _qmlHandler.onMessagesSendButton(
-                                    messagesInputField.text)
-                        messagesInputField.text = ""
-                    }
-                }
-            }
-        }
-    }
-}

+ 0 - 2
gui/src/Forms/Notifications/NotificationTemplate.ui.qml

@@ -21,7 +21,6 @@ Item {
             verticalAlignment: Text.AlignVCenter
             verticalAlignment: Text.AlignVCenter
             horizontalAlignment: Text.AlignHLeft
             horizontalAlignment: Text.AlignHLeft
             text: notificationDateText
             text: notificationDateText
-            color: "#ffffff"
         }
         }
 
 
         Text {
         Text {
@@ -32,7 +31,6 @@ Item {
             verticalAlignment: Text.AlignVCenter
             verticalAlignment: Text.AlignVCenter
             horizontalAlignment: Text.AlignHLeft
             horizontalAlignment: Text.AlignHLeft
             text: notificationMessageText
             text: notificationMessageText
-            color: "#ffffff"
         }
         }
 
 
         Button {
         Button {

+ 2 - 3
gui/src/Forms/Notifications/NotificationsForm.ui.qml

@@ -5,7 +5,7 @@ import Qt.labs.platform 1.1
 
 
 Page {
 Page {
     width: 1280
     width: 1280
-    height: 470
+    height: 570
     id: notificationsForm
     id: notificationsForm
 
 
     font.capitalization: Font.MixedCase
     font.capitalization: Font.MixedCase
@@ -60,7 +60,7 @@ Page {
             Layout.preferredWidth: parent.width
             Layout.preferredWidth: parent.width
             Layout.preferredHeight: 30
             Layout.preferredHeight: 30
             id: loginTitle
             id: loginTitle
-            color: "#ffffff"
+
             text: qsTr("No new notifications!")
             text: qsTr("No new notifications!")
             horizontalAlignment: Text.AlignHCenter
             horizontalAlignment: Text.AlignHCenter
             verticalAlignment: Text.AlignVCenter
             verticalAlignment: Text.AlignVCenter
@@ -88,6 +88,5 @@ Page {
     SystemTrayIcon {
     SystemTrayIcon {
         id: trayIcon
         id: trayIcon
         visible: true
         visible: true
-        icon.source: "qrc:/images/tray-icon.png"
     }
     }
 }
 }

+ 0 - 76
gui/src/Forms/Receiving/ReceivingForm.ui.qml

@@ -1,76 +0,0 @@
-import QtQuick 2.12
-import QtQuick.Controls 2.5
-import QtQuick.Layouts 1.3
-
-Page {
-    width: 1280
-    height: 470
-    id: receivingForm
-
-    font.capitalization: Font.MixedCase
-
-    Connections {
-        target: _qmlHandler
-        onReceivingListFile: {
-            fileList.append({
-                                "fileName": fileName,
-                                "fileSize": fileSize + " kB",
-                                "fileProgress": "",
-                                "fileDecryptable": fileDecryptable,
-                                "fileExistsLocally": existsLocally
-                            })
-        }
-
-        onReceivingClearFileList: {
-            fileList.clear()
-        }
-    }
-
-    ColumnLayout {
-        anchors.fill: parent
-
-        ScrollView {
-            Layout.preferredWidth: parent.width
-            Layout.preferredHeight: 400
-
-            ListView {
-                anchors.fill: parent
-                model: fileList
-                clip: true
-
-                delegate: ReceivingFileTemplate {
-                    fileNameText: fileName
-                    fileSizeText: fileSize
-                    fileProgressText: fileProgress
-                    fileDecryptableText: fileDecryptable
-                    fileExists: fileExistsLocally
-                }
-            }
-        }
-
-        ListModel {
-            id: fileList
-        }
-
-        RowLayout {
-            Layout.preferredWidth: parent.width
-            Layout.preferredHeight: 70
-
-            Button {
-                id: receivingListFilesButton
-                Layout.preferredWidth: 180
-                Layout.preferredHeight: parent.height
-                text: qsTr("Refresh File List")
-
-                // @disable-check M223
-                onClicked: {
-                    // @disable-check M222
-                    _qmlHandler.onReceivingListFilesButton()
-                }
-            }
-        }
-    }
-}
-
-
-

+ 0 - 95
gui/src/Forms/Sending/SendingForm.ui.qml

@@ -1,95 +0,0 @@
-import QtQuick 2.12
-import QtQuick.Controls 2.5
-import QtQuick.Dialogs 1.0
-
-Page {
-    width: 1280
-    height: 470
-    font.capitalization: Font.MixedCase
-
-    title: qsTr("Sending")
-
-    Connections {
-        target: _qmlHandler
-        onSendingSetFileUrlText: {
-            sendingSelectedFileText.text = signalText
-        }
-        onSendingEnableSendButton: {
-            sendingSendFileButton.enabled = true
-        }
-        onSendingDisableSendButton: {
-            sendingSendFileButton.enabled = false
-        }
-    }
-
-    Button {
-        id: sendingClearFileButton
-        x: 900
-        y: 40
-        width: 260
-        height: 90
-        text: qsTr("Clear Selection")
-        enabled: sendingSendFileButton.enabled
-        font.pointSize: 16
-        // @disable-check M223
-        onClicked: {
-            // @disable-check M222
-            _qmlHandler.onSendingClearSelectionButton()
-        }
-    }
-
-    Button {
-        id: sendingSelectFileButton
-        x: 120
-        y: 40
-        width: 260
-        height: 90
-        text: qsTr("Select File")
-        font.pointSize: 16
-        // @disable-check M223
-        onClicked: {
-            // @disable-check M222
-            sendingFileDialog.open()
-        }
-    }
-
-    Text {
-        id: sendingSelectedFileText
-        x: 54
-        y: 186
-        width: 1172
-        height: 52
-        color: "#ffffff"
-        text: qsTr("Selected File: None")
-        verticalAlignment: Text.AlignVCenter
-        horizontalAlignment: Text.AlignHCenter
-        font.pixelSize: 23
-    }
-
-    FileDialog {
-        id: sendingFileDialog
-        title: "Please choose a file"
-        folder: shortcuts.home
-        // @disable-check M223
-        onAccepted: {
-            // @disable-check M222
-            _qmlHandler.onSendingSelectFileButton(sendingFileDialog.fileUrl)
-        }
-    }
-
-    Button {
-        id: sendingSendFileButton
-        x: 510
-        y: 304
-        enabled: false
-        width: 260
-        height: 90
-        text: qsTr("Send File")
-        font.pointSize: 16
-        // @disable-check M223
-        onClicked: {
-            // @disable-check M222
-            _qmlHandler.onSendingSendFileButton()
-        }
-    }
-}

+ 9 - 10
gui/src/Forms/Receiving/ReceivingFileTemplate.ui.qml → gui/src/Forms/ServerFiles/ServerFilesFileTemplate.ui.qml

@@ -14,20 +14,20 @@ Item {
 
 
     Connections {
     Connections {
         target: _qmlHandler
         target: _qmlHandler
-        onReceivingDisableDownloadButton: {
+        onServerFilesDisableDownloadButton: {
             if (fileNameText == fileName) {
             if (fileNameText == fileName) {
                 fileExists = true
                 fileExists = true
             }
             }
         }
         }
 
 
-        onReceivingUpdateFile: {
+        onServerFilesUpdateFile: {
             if (fileNameText == fileName) {
             if (fileNameText == fileName) {
                 fileProgressText = fileProgress
                 fileProgressText = fileProgress
                 fileQueued = isQueued
                 fileQueued = isQueued
             }
             }
         }
         }
 
 
-        onReceivingCloseConfirmDeletePopup: {
+        onServerFilesCloseConfirmDeletePopup: {
             confirmDeletePopup.close()
             confirmDeletePopup.close()
         }
         }
     }
     }
@@ -43,7 +43,6 @@ Item {
             Layout.preferredWidth: 400
             Layout.preferredWidth: 400
             verticalAlignment: Text.AlignVCenter
             verticalAlignment: Text.AlignVCenter
             text: fileNameText
             text: fileNameText
-            color: "#ffffff"
         }
         }
 
 
         Text {
         Text {
@@ -52,9 +51,8 @@ Item {
             Layout.preferredHeight: parent.height
             Layout.preferredHeight: parent.height
             Layout.preferredWidth: 100
             Layout.preferredWidth: 100
             verticalAlignment: Text.AlignVCenter
             verticalAlignment: Text.AlignVCenter
-            horizontalAlignment: Text.AlignHCenter
+            horizontalAlignment: Text.AlignRight
             text: fileSizeText
             text: fileSizeText
-            color: "#ffffff"
         }
         }
 
 
         Text {
         Text {
@@ -65,7 +63,6 @@ Item {
             verticalAlignment: Text.AlignVCenter
             verticalAlignment: Text.AlignVCenter
             horizontalAlignment: Text.AlignHCenter
             horizontalAlignment: Text.AlignHCenter
             text: fileProgressText
             text: fileProgressText
-            color: "#ffffff"
         }
         }
 
 
         Text {
         Text {
@@ -76,7 +73,9 @@ Item {
             verticalAlignment: Text.AlignVCenter
             verticalAlignment: Text.AlignVCenter
             horizontalAlignment: Text.AlignHCenter
             horizontalAlignment: Text.AlignHCenter
             text: fileDecryptableText
             text: fileDecryptableText
-            color: (fileDecryptableText == "decryptable") ? "#3fdf3f" : (fileDecryptableText == "undecryptable") ? "#df3f3f" : "#ffffff"
+            color: (fileDecryptableText
+                    == "decryptable") ? "#3fdf3f" : (fileDecryptableText
+                                                     == "undecryptable") ? "#df3f3f" : "#000000"
         }
         }
 
 
         Button {
         Button {
@@ -107,7 +106,7 @@ Item {
             // @disable-check M223
             // @disable-check M223
             onClicked: {
             onClicked: {
                 // @disable-check M222
                 // @disable-check M222
-                _qmlHandler.onReceivingDownloadFileButton(fileNameText)
+                _qmlHandler.onServerFilesDownloadFileButton(fileNameText)
             }
             }
         }
         }
 
 
@@ -126,7 +125,7 @@ Item {
         }
         }
     }
     }
 
 
-    ReceivingFileTemplateDeletePopup {
+    ServerFilesFileTemplateDeletePopup {
         id: confirmDeletePopup
         id: confirmDeletePopup
     }
     }
 }
 }

+ 6 - 2
gui/src/Forms/Receiving/ReceivingFileTemplateDeletePopup.ui.qml → gui/src/Forms/ServerFiles/ServerFilesFileTemplateDeletePopup.ui.qml

@@ -13,6 +13,10 @@ Popup {
     closePolicy: Popup.NoAutoClose
     closePolicy: Popup.NoAutoClose
     anchors.centerIn: Overlay.overlay
     anchors.centerIn: Overlay.overlay
 
 
+    Overlay.modal: Rectangle {
+        color: "#b5c5c5c5"
+    }
+
     ColumnLayout {
     ColumnLayout {
         anchors.fill: parent
         anchors.fill: parent
 
 
@@ -26,7 +30,6 @@ Popup {
             horizontalAlignment: Text.AlignHCenter
             horizontalAlignment: Text.AlignHCenter
             wrapMode: Text.WordWrap
             wrapMode: Text.WordWrap
             font.pointSize: 15
             font.pointSize: 15
-            color: "#ffffff"
         }
         }
         RowLayout {
         RowLayout {
             Layout.preferredHeight: 80
             Layout.preferredHeight: 80
@@ -39,7 +42,8 @@ Popup {
                 // @disable-check M223
                 // @disable-check M223
                 onClicked: {
                 onClicked: {
                     // @disable-check M222
                     // @disable-check M222
-                    _qmlHandler.onReceivingConfirmDeleteFileButton(fileNameText)
+                    _qmlHandler.onServerFilesConfirmDeleteFileButton(
+                                fileNameText)
                 }
                 }
             }
             }
 
 

+ 225 - 0
gui/src/Forms/ServerFiles/ServerFilesForm.ui.qml

@@ -0,0 +1,225 @@
+import QtQuick 2.12
+import QtQuick.Controls 2.5
+import QtQuick.Controls.Material 2.3
+import QtQuick.Layouts 1.3
+import QtQuick.Dialogs 1.0
+
+Page {
+    width: 1280
+    height: 570
+    id: serverFilesForm
+
+    font.capitalization: Font.MixedCase
+
+    Connections {
+        target: _qmlHandler
+        onServerFilesListFile: {
+            fileList.append({
+                                "fileName": fileName,
+                                "fileSize": fileSize + " kB",
+                                "fileProgress": "",
+                                "fileDecryptable": fileDecryptable,
+                                "fileExistsLocally": existsLocally
+                            })
+        }
+
+        onServerFilesClearFileList: {
+            fileList.clear()
+        }
+
+        onServerFilesSetFileUrlText: {
+            sendingSelectedFileText.text = signalText
+        }
+
+        onServerFilesEnableSendButton: {
+            sendingSendFileButton.enabled = true
+        }
+
+        onServerFilesDisableSendButton: {
+            sendingSendFileButton.enabled = false
+        }
+    }
+
+    ColumnLayout {
+        anchors.fill: parent
+
+        RowLayout {
+            Layout.preferredWidth: 750
+            Layout.preferredHeight: 30
+
+            Text {
+
+                text: qsTr("File Name")
+                Layout.alignment: Qt.AlignCenter
+                Layout.preferredWidth: 400
+                Layout.preferredHeight: parent.height
+                verticalAlignment: Text.AlignVCenter
+                horizontalAlignment: Text.AlignLeft
+                font.pixelSize: 15
+            }
+
+            Text {
+
+                text: qsTr("Size")
+                Layout.alignment: Qt.AlignCenter
+                Layout.preferredWidth: 100
+                Layout.preferredHeight: parent.height
+                verticalAlignment: Text.AlignVCenter
+                horizontalAlignment: Text.AlignHCenter
+                font.pixelSize: 15
+            }
+
+            Text {
+
+                text: qsTr("Status")
+                Layout.alignment: Qt.AlignCenter
+                Layout.preferredWidth: 100
+                Layout.preferredHeight: parent.height
+                verticalAlignment: Text.AlignVCenter
+                horizontalAlignment: Text.AlignHCenter
+                font.pixelSize: 15
+            }
+
+            Text {
+
+                text: qsTr("Encryption")
+                Layout.alignment: Qt.AlignCenter
+                Layout.preferredWidth: 150
+                Layout.preferredHeight: parent.height
+                verticalAlignment: Text.AlignVCenter
+                horizontalAlignment: Text.AlignHCenter
+                font.pixelSize: 15
+            }
+        }
+
+        Rectangle {
+            Layout.alignment: Qt.AlignCenter
+            Layout.preferredWidth: parent.width
+            Layout.preferredHeight: 2
+            color: "#404040"
+        }
+
+        ScrollView {
+            Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
+            Layout.preferredWidth: parent.width
+
+            Layout.preferredHeight: 440
+            ListView {
+                anchors.fill: parent
+                model: fileList
+                clip: true
+
+                delegate: ServerFilesFileTemplate {
+                    fileNameText: fileName
+                    fileSizeText: fileSize
+                    fileProgressText: fileProgress
+                    fileDecryptableText: fileDecryptable
+                    fileExists: fileExistsLocally
+                }
+            }
+        }
+
+        ListModel {
+            id: fileList
+        }
+
+        Rectangle {
+            Layout.alignment: Qt.AlignCenter
+            Layout.preferredWidth: parent.width
+            Layout.preferredHeight: 2
+            color: Material.accent
+        }
+
+        RowLayout {
+            Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+            Layout.preferredWidth: parent.width
+
+            Text {
+
+                text: qsTr("Selected File: ")
+                Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
+                Layout.preferredWidth: 150
+                Layout.preferredHeight: 50
+                verticalAlignment: Text.AlignVCenter
+                horizontalAlignment: Text.AlignHCenter
+                font.pixelSize: 23
+            }
+
+            Text {
+                id: sendingSelectedFileText
+
+                text: qsTr("None")
+                Layout.preferredWidth: 450
+                Layout.preferredHeight: 50
+                verticalAlignment: Text.AlignVCenter
+                horizontalAlignment: Text.AlignLeft
+                font.pixelSize: 23
+                elide: Text.ElideLeft
+                ToolTip.visible: mouseArea.containsMouse
+                ToolTip.text: text
+                ToolTip.delay: 200
+
+                MouseArea {
+                    id: mouseArea
+                    anchors.fill: parent
+                    hoverEnabled: true
+                }
+            }
+
+            Button {
+                id: sendingClearFileButton
+                text: qsTr("Clear Selection")
+                Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+                Layout.preferredWidth: 200
+                Layout.preferredHeight: 50
+                enabled: sendingSendFileButton.enabled
+                font.pointSize: 16
+                // @disable-check M223
+                onClicked: {
+                    // @disable-check M222
+                    _qmlHandler.onServerFilesClearSelectionButton()
+                }
+            }
+
+            Button {
+                id: sendingSelectFileButton
+                text: qsTr("Select File")
+                Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+                Layout.preferredWidth: 200
+                Layout.preferredHeight: 50
+                font.pointSize: 16
+                // @disable-check M223
+                onClicked: {
+                    // @disable-check M222
+                    sendingFileDialog.open()
+                }
+            }
+
+            Button {
+                id: sendingSendFileButton
+                enabled: false
+                text: qsTr("Upload File")
+                Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+                Layout.preferredWidth: 200
+                Layout.preferredHeight: 50
+                font.pointSize: 16
+                // @disable-check M223
+                onClicked: {
+                    // @disable-check M222
+                    _qmlHandler.onServerFilesSendFileButton()
+                }
+            }
+        }
+    }
+
+    FileDialog {
+        id: sendingFileDialog
+        title: "Please choose a file"
+        folder: shortcuts.home
+        // @disable-check M223
+        onAccepted: {
+            // @disable-check M222
+            _qmlHandler.onServerFilesSelectFileButton(sendingFileDialog.fileUrl)
+        }
+    }
+}

+ 9 - 1
gui/src/Forms/Settings/DeleteMePopup.ui.qml

@@ -15,6 +15,10 @@ Popup {
 
 
     signal resetStatus
     signal resetStatus
 
 
+    Overlay.modal: Rectangle {
+        color: "#b5c5c5c5"
+    }
+
     onClosed: {
     onClosed: {
         resetStatus()
         resetStatus()
     }
     }
@@ -33,7 +37,7 @@ Popup {
             Layout.alignment: Qt.AlignCenter
             Layout.alignment: Qt.AlignCenter
             Layout.preferredWidth: parent.width
             Layout.preferredWidth: parent.width
             Layout.preferredHeight: 100
             Layout.preferredHeight: 100
-            color: "#ffffff"
+
             text: qsTr("Are you sure you want to delete your account on the server?\nThe application will restart.")
             text: qsTr("Are you sure you want to delete your account on the server?\nThe application will restart.")
             wrapMode: Text.WordWrap
             wrapMode: Text.WordWrap
             horizontalAlignment: Text.AlignHCenter
             horizontalAlignment: Text.AlignHCenter
@@ -67,6 +71,10 @@ Popup {
             text: ""
             text: ""
             horizontalAlignment: Text.AlignHCenter
             horizontalAlignment: Text.AlignHCenter
             placeholderText: "Enter password to confirm"
             placeholderText: "Enter password to confirm"
+            Connections {
+                target: popup
+                onResetStatus: deleteMePopupPasswordInput.text = ""
+            }
         }
         }
 
 
         RowLayout {
         RowLayout {

+ 14 - 19
gui/src/Forms/Settings/SettingsForm.ui.qml

@@ -6,8 +6,8 @@ import QtQuick.Dialogs 1.0
 
 
 Page {
 Page {
     width: 1280
     width: 1280
-    height: 470
-    id: page
+    height: 570
+    id: settingsForm
 
 
     font.capitalization: Font.MixedCase
     font.capitalization: Font.MixedCase
 
 
@@ -20,14 +20,13 @@ Page {
             settingsSaveIpSwitch.checked = saveIP
             settingsSaveIpSwitch.checked = saveIP
             settingsSaveUsernameSwitch.checked = saveUsername
             settingsSaveUsernameSwitch.checked = saveUsername
             settingsCliPath.text = "CLI-Path:   " + cliPath
             settingsCliPath.text = "CLI-Path:   " + cliPath
-            settingsKeyPath.text = "CLI-Path:   " + keyPath
+            settingsKeyPath.text = "            " + keyPath
         }
         }
         onKeyfileStatus: {
         onKeyfileStatus: {
-            if(success) {
+            if (success) {
                 settingsKeyStatus.text = "Keyfile: OK"
                 settingsKeyStatus.text = "Keyfile: OK"
                 settingsKeyStatus.color = "#3fdf3f"
                 settingsKeyStatus.color = "#3fdf3f"
-            }
-            else {
+            } else {
                 settingsKeyStatus.text = "Keyfile: Error"
                 settingsKeyStatus.text = "Keyfile: Error"
                 settingsKeyStatus.color = "#df3f3f"
                 settingsKeyStatus.color = "#df3f3f"
                 settingsKeyPath.text = msg
                 settingsKeyPath.text = msg
@@ -35,7 +34,7 @@ Page {
         }
         }
         onKeyfileClosedOK: {
         onKeyfileClosedOK: {
             settingsKeyStatus.text = "Keyfile:"
             settingsKeyStatus.text = "Keyfile:"
-            settingsKeyStatus.color = "#ffffff"
+            settingsKeyStatus.color = "#000000"
             settingsKeyPath.text = "   "
             settingsKeyPath.text = "   "
         }
         }
     }
     }
@@ -58,7 +57,7 @@ Page {
                     Layout.alignment: Qt.AlignCenter
                     Layout.alignment: Qt.AlignCenter
                     Layout.preferredWidth: 400
                     Layout.preferredWidth: 400
                     Layout.preferredHeight: 50
                     Layout.preferredHeight: 50
-                    color: "#ffffff"
+
                     text: "Autofill default IP on start:"
                     text: "Autofill default IP on start:"
                     verticalAlignment: Text.AlignVCenter
                     verticalAlignment: Text.AlignVCenter
                     horizontalAlignment: Text.AlignLeft
                     horizontalAlignment: Text.AlignLeft
@@ -69,7 +68,7 @@ Page {
                     Layout.alignment: Qt.AlignCenter
                     Layout.alignment: Qt.AlignCenter
                     Layout.preferredWidth: 400
                     Layout.preferredWidth: 400
                     Layout.preferredHeight: 50
                     Layout.preferredHeight: 50
-                    color: "#ffffff"
+
                     text: "Autofill default username on start:"
                     text: "Autofill default username on start:"
                     verticalAlignment: Text.AlignVCenter
                     verticalAlignment: Text.AlignVCenter
                     horizontalAlignment: Text.AlignLeft
                     horizontalAlignment: Text.AlignLeft
@@ -81,7 +80,7 @@ Page {
                     Layout.alignment: Qt.AlignCenter
                     Layout.alignment: Qt.AlignCenter
                     Layout.preferredWidth: 400
                     Layout.preferredWidth: 400
                     Layout.preferredHeight: 50
                     Layout.preferredHeight: 50
-                    color: "#ffffff"
+
                     text: "CLI-Path:   "
                     text: "CLI-Path:   "
                     verticalAlignment: Text.AlignVCenter
                     verticalAlignment: Text.AlignVCenter
                     horizontalAlignment: Text.AlignLeft
                     horizontalAlignment: Text.AlignLeft
@@ -93,7 +92,7 @@ Page {
                     Layout.alignment: Qt.AlignCenter
                     Layout.alignment: Qt.AlignCenter
                     Layout.preferredWidth: 400
                     Layout.preferredWidth: 400
                     Layout.preferredHeight: 50
                     Layout.preferredHeight: 50
-                    color: "#ffffff"
+
                     text: "Keyfile:"
                     text: "Keyfile:"
                     verticalAlignment: Text.AlignVCenter
                     verticalAlignment: Text.AlignVCenter
                     horizontalAlignment: Text.AlignLeft
                     horizontalAlignment: Text.AlignLeft
@@ -105,7 +104,7 @@ Page {
                     Layout.alignment: Qt.AlignCenter
                     Layout.alignment: Qt.AlignCenter
                     Layout.preferredWidth: 400
                     Layout.preferredWidth: 400
                     Layout.preferredHeight: 50
                     Layout.preferredHeight: 50
-                    color: "#ffffff"
+
                     text: "   "
                     text: "   "
                     verticalAlignment: Text.AlignVCenter
                     verticalAlignment: Text.AlignVCenter
                     horizontalAlignment: Text.AlignLeft
                     horizontalAlignment: Text.AlignLeft
@@ -116,7 +115,7 @@ Page {
                     Layout.alignment: Qt.AlignCenter
                     Layout.alignment: Qt.AlignCenter
                     Layout.preferredWidth: 400
                     Layout.preferredWidth: 400
                     Layout.preferredHeight: 50
                     Layout.preferredHeight: 50
-                    color: "#ffffff"
+
                     text: "Delete my account:"
                     text: "Delete my account:"
                     verticalAlignment: Text.AlignVCenter
                     verticalAlignment: Text.AlignVCenter
                     horizontalAlignment: Text.AlignLeft
                     horizontalAlignment: Text.AlignLeft
@@ -154,7 +153,7 @@ Page {
                     Layout.alignment: Qt.AlignCenter
                     Layout.alignment: Qt.AlignCenter
                     Layout.preferredHeight: 50
                     Layout.preferredHeight: 50
                     Layout.preferredWidth: 220
                     Layout.preferredWidth: 220
-                    text: "Change (needs restart)"
+                    text: "Change (req. restart)"
                     font.pixelSize: 20
                     font.pixelSize: 20
                     // @disable-check M223
                     // @disable-check M223
                     onClicked: {
                     onClicked: {
@@ -254,8 +253,7 @@ Page {
                                 settingsCliPath.text.replace("CLI-Path:   ",
                                 settingsCliPath.text.replace("CLI-Path:   ",
                                                              ""),
                                                              ""),
                                 // @disable-check M222
                                 // @disable-check M222
-                                settingsKeyPath.text.replace("   ",
-                                                             ""))
+                                settingsKeyPath.text.replace("   ", ""))
                 }
                 }
             }
             }
 
 
@@ -308,6 +306,3 @@ Page {
         id: deleteMePopup
         id: deleteMePopup
     }
     }
 }
 }
-
-
-

+ 6 - 9
gui/src/climanager.cpp

@@ -58,7 +58,9 @@ void CliManager::onExit() {
 void CliManager::setQmlHandler(QMLHandler *q) { qmlHandler = q; }
 void CliManager::setQmlHandler(QMLHandler *q) { qmlHandler = q; }
 
 
 void CliManager::init() {
 void CliManager::init() {
+	// TODO: Remove
 	qInfo() << QString::fromStdString(string("InitCLI with path ") + Config::getValue("CLI-Path"));
 	qInfo() << QString::fromStdString(string("InitCLI with path ") + Config::getValue("CLI-Path"));
+	emit qmlHandler->log(QString::fromStdString(string("InitCLI with path ") + Config::getValue("CLI-Path")));
 	if (!Config::getValue("CLI-Path").size()) {
 	if (!Config::getValue("CLI-Path").size()) {
 		qInfo() << "Empty CLI-Path!";
 		qInfo() << "Empty CLI-Path!";
 		return;
 		return;
@@ -135,9 +137,6 @@ void CliManager::readPipeLoop() {
 			pipeInput.append(buf);
 			pipeInput.append(buf);
 			inputs = tokenizeByNewlines(pipeInput);
 			inputs = tokenizeByNewlines(pipeInput);
 			for (string s : inputs) {
 			for (string s : inputs) {
-				emit qmlHandler->log(QString::fromStdString(s));
-				qInfo() << QString::fromStdString(s);
-				// handleJSON(s);
 				JsonHandler::parseJSON(s);
 				JsonHandler::parseJSON(s);
 			}
 			}
 			pipeInput = string();
 			pipeInput = string();
@@ -145,7 +144,11 @@ void CliManager::readPipeLoop() {
 			pollCount = 0;
 			pollCount = 0;
 			readOffset = 0;
 			readOffset = 0;
 			if (waitpid(childpid, NULL, WNOHANG)) {
 			if (waitpid(childpid, NULL, WNOHANG)) {
+				// TODO: Remove
 				qInfo() << "CLI has exited/did not launch";
 				qInfo() << "CLI has exited/did not launch";
+				emit qmlHandler->log("CLI has exited/did not launch");
+
+				emit qmlHandler->footerSetError("CLI crashed. Please restart the application.");
 				setProgramActive(false);
 				setProgramActive(false);
 				// nonzero means error or childid has changed state
 				// nonzero means error or childid has changed state
 				// for us that means child has exited -> CLI is dead
 				// for us that means child has exited -> CLI is dead
@@ -157,15 +160,9 @@ void CliManager::readPipeLoop() {
 			pipeInput.append(buf);
 			pipeInput.append(buf);
 			inputs = tokenizeByNewlines(pipeInput);
 			inputs = tokenizeByNewlines(pipeInput);
 			for (unsigned i = 0; i < inputs.size() - 1; i++) { // process all lines except the last, potentially incomplete one
 			for (unsigned i = 0; i < inputs.size() - 1; i++) { // process all lines except the last, potentially incomplete one
-				// do not log these lines, Qt/Quick has no simple way of limiting the number of lines in the logging window so we might go OoM real quick
-				//~ emit qmlHandler->log(QString::fromStdString(inputs[i]));
-				qInfo() << QString::fromStdString(inputs[i]);
-				// handleJSON(s);
 				JsonHandler::parseJSON(inputs[i]);
 				JsonHandler::parseJSON(inputs[i]);
 			}
 			}
 			if (pipeInput.back() == '\n') { // process last line if it was complete
 			if (pipeInput.back() == '\n') { // process last line if it was complete
-				qInfo() << QString::fromStdString(inputs.back());
-				// handleJSON(s);
 				JsonHandler::parseJSON(inputs.back());
 				JsonHandler::parseJSON(inputs.back());
 				pipeInput = string();
 				pipeInput = string();
 			} else {
 			} else {

+ 28 - 14
gui/src/cmdmanager.cpp

@@ -38,6 +38,7 @@ void CmdManager::init() {
 	cmdmap["extendedstatus"] = &CmdManager::handleExtendedStatus;
 	cmdmap["extendedstatus"] = &CmdManager::handleExtendedStatus;
 	cmdmap["keyfile"] = &CmdManager::handleKeyfile;
 	cmdmap["keyfile"] = &CmdManager::handleKeyfile;
 	cmdmap["closekey"] = &CmdManager::handleClosekey;
 	cmdmap["closekey"] = &CmdManager::handleClosekey;
+	cmdmap["disconnect"] = &CmdManager::handleDisconnect;
 
 
 	filemap.clear();
 	filemap.clear();
 }
 }
@@ -69,11 +70,11 @@ void CmdManager::emitFileList() {
 				progstr = it->second.type + " via " + it->second.method + "\n" + std::to_string(it->second.progress) + "%" + " @ " + speedbuf;
 				progstr = it->second.type + " via " + it->second.method + "\n" + std::to_string(it->second.progress) + "%" + " @ " + speedbuf;
 			} else
 			} else
 				progstr = it->second.type + "\n" + std::to_string(it->second.progress) + "%";
 				progstr = it->second.type + "\n" + std::to_string(it->second.progress) + "%";
-			emit qmlHandler->receivingUpdateFile(it->first.c_str(), progstr.c_str(), it->second.type == "Queued" || it->second.type == "Sending");
+			emit qmlHandler->serverFilesUpdateFile(it->first.c_str(), progstr.c_str(), it->second.type == "Queued" || it->second.type == "Sending");
 		}
 		}
 		// else emit plain entry
 		// else emit plain entry
 		else
 		else
-			emit qmlHandler->receivingUpdateFile(it->first.c_str(), "", false);
+			emit qmlHandler->serverFilesUpdateFile(it->first.c_str(), "", false);
 	}
 	}
 }
 }
 
 
@@ -109,6 +110,7 @@ void CmdManager::executeCmd(string cmd, Json::Value root) {
 }
 }
 
 
 void CmdManager::setCachedIP(QString ip) { cachedIP = ip; }
 void CmdManager::setCachedIP(QString ip) { cachedIP = ip; }
+
 void CmdManager::setCachedPort(QString port) { cachedPort = port; }
 void CmdManager::setCachedPort(QString port) { cachedPort = port; }
 
 
 void CmdManager::handleError(Json::Value root) { emit qmlHandler->log(root["error"].asString().c_str()); }
 void CmdManager::handleError(Json::Value root) { emit qmlHandler->log(root["error"].asString().c_str()); }
@@ -121,14 +123,14 @@ void CmdManager::handleList(Json::Value root) {
 	char sizebuf[256];
 	char sizebuf[256];
 	snprintf(sizebuf, 256, "%.2f", 4.2f);
 	snprintf(sizebuf, 256, "%.2f", 4.2f);
 	if (root["accept"] == true) {
 	if (root["accept"] == true) {
-		emit qmlHandler->receivingClearFileList();
+		emit qmlHandler->serverFilesClearFileList();
 		filemap.clear();
 		filemap.clear();
 
 
 		// Get the array of file Names
 		// Get the array of file Names
 		auto fileNames = root["names"];
 		auto fileNames = root["names"];
 		for (int i = 0; i < fileNames.size(); i++) {
 		for (int i = 0; i < fileNames.size(); i++) {
-			emit qmlHandler->receivingListFile(QString::fromStdString(fileNames[i].asString()), QString::fromStdString(sizebuf), QString("Decryptable"),
-			                                   !!ifstream(fileNames[i].asString()));
+			emit qmlHandler->serverFilesListFile(QString::fromStdString(fileNames[i].asString()), QString::fromStdString(sizebuf), QString("Decryptable"),
+			                                     !!ifstream(fileNames[i].asString()));
 			filemap[fileNames[i].asString()] = {false, "", "", 0, 0};
 			filemap[fileNames[i].asString()] = {false, "", "", 0, 0};
 		}
 		}
 	} else {
 	} else {
@@ -139,15 +141,15 @@ void CmdManager::handleList(Json::Value root) {
 void CmdManager::handleExtendedList(Json::Value root) {
 void CmdManager::handleExtendedList(Json::Value root) {
 	char sizebuf[256];
 	char sizebuf[256];
 	if (root["accept"] == true) {
 	if (root["accept"] == true) {
-		emit qmlHandler->receivingClearFileList();
+		emit qmlHandler->serverFilesClearFileList();
 		filemap.clear();
 		filemap.clear();
 
 
 		// Get the array of file Names
 		// Get the array of file Names
 		auto files = root["files"];
 		auto files = root["files"];
 		for (Json::Value f : files) {
 		for (Json::Value f : files) {
 			snprintf(sizebuf, 256, "%.2f", f["size"].asFloat());
 			snprintf(sizebuf, 256, "%.2f", f["size"].asFloat());
-			emit qmlHandler->receivingListFile(QString::fromStdString(f["name"].asString()), QString::fromStdString(sizebuf),
-			                                   QString::fromStdString(f["encrypted"].asString()), !!ifstream(f["name"].asString()));
+			emit qmlHandler->serverFilesListFile(QString::fromStdString(f["name"].asString()), QString::fromStdString(sizebuf),
+			                                     QString::fromStdString(f["encrypted"].asString()), !!ifstream(f["name"].asString()));
 			filemap[f["name"].asString()] = {false, "", "", 0, 0};
 			filemap[f["name"].asString()] = {false, "", "", 0, 0};
 		}
 		}
 	} else {
 	} else {
@@ -206,7 +208,10 @@ void CmdManager::handlePut(Json::Value root) {
 }
 }
 
 
 void CmdManager::handlePutData(Json::Value root) {
 void CmdManager::handlePutData(Json::Value root) {
-	// TODO: Show speed and handle Error
+	if (root["cancel"] == true) {
+		QString errorMessage = QString::fromStdString(string("Error when uploading file " + root["file"].asString() + ":\n" + root["error"].asString()));
+		emit qmlHandler->log(errorMessage);
+	}
 }
 }
 
 
 void CmdManager::handleGet(Json::Value root) {
 void CmdManager::handleGet(Json::Value root) {
@@ -215,17 +220,20 @@ void CmdManager::handleGet(Json::Value root) {
 		emit qmlHandler->log(errorMessage);
 		emit qmlHandler->log(errorMessage);
 	} else {
 	} else {
 		string fileName = root["file"].asString();
 		string fileName = root["file"].asString();
-		// TODO: Only do this in getdata when remaining is 0 (when the file is fully downloaded) - maybe set text to "downloading.." in between
-		emit qmlHandler->receivingDisableDownloadButton(QString::fromStdString(fileName));
+		emit qmlHandler->serverFilesDisableDownloadButton(QString::fromStdString(fileName));
 	}
 	}
 }
 }
 
 
 void CmdManager::handleGetData(Json::Value root) {
 void CmdManager::handleGetData(Json::Value root) {
-	// TODO: Show speed and handle Error
+	if (root["cancel"] == true) {
+		QString errorMessage = QString::fromStdString(string("Error when downloading file " + root["file"].asString() + ":\n" + root["error"].asString()));
+		emit qmlHandler->log(errorMessage);
+	}
 }
 }
 
 
 void CmdManager::handleDeleteMe(Json::Value root) {
 void CmdManager::handleDeleteMe(Json::Value root) {
 	if (root["accept"] == true) {
 	if (root["accept"] == true) {
+		CliManager::loggedin = true;
 		qmlHandler->setRestart(true);
 		qmlHandler->setRestart(true);
 		emit qmlHandler->closeWindow();
 		emit qmlHandler->closeWindow();
 	} else {
 	} else {
@@ -235,7 +243,7 @@ void CmdManager::handleDeleteMe(Json::Value root) {
 }
 }
 
 
 void CmdManager::handleDeleteFile(Json::Value root) {
 void CmdManager::handleDeleteFile(Json::Value root) {
-	emit qmlHandler->receivingCloseConfirmDeletePopup();
+	emit qmlHandler->serverFilesCloseConfirmDeletePopup();
 	if (root["accept"] == false) {
 	if (root["accept"] == false) {
 		QString errorMessage = QString::fromStdString(string("Error when deleting file " + root["file"].asString() + ":\n" + root["error"].asString()));
 		QString errorMessage = QString::fromStdString(string("Error when deleting file " + root["file"].asString() + ":\n" + root["error"].asString()));
 		emit qmlHandler->log(errorMessage);
 		emit qmlHandler->log(errorMessage);
@@ -325,4 +333,10 @@ void CmdManager::handleClosekey(Json::Value root) {
 	} else {
 	} else {
 		emit qmlHandler->keyfileClosedOK();
 		emit qmlHandler->keyfileClosedOK();
 	}
 	}
-}
+}
+
+void CmdManager::handleDisconnect(Json::Value root) {
+	if (root["accept"] == true) {
+		CliManager::loggedin = false;
+	}
+}

BIN
gui/src/images/tray-icon.png


+ 23 - 3
gui/src/jsonhandler.cpp

@@ -1,8 +1,16 @@
-#include "../include/jsonhandler.h"
+#include <QDebug>
+
 #include "../include/cmdmanager.h"
 #include "../include/cmdmanager.h"
+#include "../include/jsonhandler.h"
 
 
 using namespace std;
 using namespace std;
 
 
+namespace JsonHandler {
+QMLHandler *qmlHandler;
+}
+
+void JsonHandler::setQmlHandler(QMLHandler *q) { qmlHandler = q; }
+
 // This method gets a string and tries to read it as Json
 // This method gets a string and tries to read it as Json
 // If it fails to do so, return and do nothing, else handle the content
 // If it fails to do so, return and do nothing, else handle the content
 void JsonHandler::parseJSON(string buffer) {
 void JsonHandler::parseJSON(string buffer) {
@@ -11,8 +19,7 @@ void JsonHandler::parseJSON(string buffer) {
 	Json::CharReader *reader = builder.newCharReader();
 	Json::CharReader *reader = builder.newCharReader();
 	string jsonError;
 	string jsonError;
 
 
-	// Try to parse the string as Json and store the result of the pasring in a
-	// boolean
+	// Try to parse the string as Json and store the result of the parsing in a boolean
 	bool parsingSuccessful = reader->parse(buffer.c_str(), buffer.c_str() + buffer.size(), &root, &jsonError);
 	bool parsingSuccessful = reader->parse(buffer.c_str(), buffer.c_str() + buffer.size(), &root, &jsonError);
 
 
 	delete (reader);
 	delete (reader);
@@ -23,6 +30,19 @@ void JsonHandler::parseJSON(string buffer) {
 	}
 	}
 
 
 	string cmd = root["command"].asString();
 	string cmd = root["command"].asString();
+	string err = root["error"].asString();
+
+	// Filter the commands to not be printed
+	if (cmd.compare("notifications") && cmd.compare("extendedlist") && cmd.compare("extendedstatus") && cmd.compare("status") && cmd.compare("putdata") &&
+	    cmd.compare("getdata")) {
+		emit qmlHandler->log(QString::fromStdString(buffer));
+		// TODO: Remove
+		qInfo() << QString::fromStdString(buffer);
+	}
+
+	if (err.compare("")) {
+		emit qmlHandler->footerSetError(QString::fromStdString(err));
+	}
 
 
 	CmdManager::executeCmd(cmd, root);
 	CmdManager::executeCmd(cmd, root);
 }
 }

+ 1 - 0
gui/src/main.cpp

@@ -34,6 +34,7 @@ int main(int argc, char *argv[]) {
 	CmdManager::setQmlHandler(&qmlHandler);
 	CmdManager::setQmlHandler(&qmlHandler);
 	CmdManager::init();
 	CmdManager::init();
 	CliManager::setQmlHandler(&qmlHandler);
 	CliManager::setQmlHandler(&qmlHandler);
+	JsonHandler::setQmlHandler(&qmlHandler);
 
 
 	// Set the context for the window, so that the qml files can be connected to
 	// Set the context for the window, so that the qml files can be connected to
 	// the qmlHandler
 	// the qmlHandler

+ 5 - 13
gui/src/qml.qrc

@@ -8,27 +8,19 @@
         <file>Forms/Main/InvalidCliPathPopup.ui.qml</file>
         <file>Forms/Main/InvalidCliPathPopup.ui.qml</file>
         <file>Forms/Main/InvalidConfigPopup.ui.qml</file>
         <file>Forms/Main/InvalidConfigPopup.ui.qml</file>
 
 
-        <file>Forms/Connect/LoginForm.ui.qml</file>
+        <file>Forms/ServerFiles/ServerFilesForm.ui.qml</file>
+        <file>Forms/ServerFiles/ServerFilesFileTemplate.ui.qml</file>
+        <file>Forms/ServerFiles/ServerFilesFileTemplateDeletePopup.ui.qml</file>
+
         <file>Forms/Connect/IpPopup.ui.qml</file>
         <file>Forms/Connect/IpPopup.ui.qml</file>
         <file>Forms/Connect/LoginSignupPopup.ui.qml</file>
         <file>Forms/Connect/LoginSignupPopup.ui.qml</file>
-        <file>Forms/Connect/SignupForm.ui.qml</file>
-
-        <file>Forms/Sending/SendingForm.ui.qml</file>
-
-        <file>Forms/Receiving/ReceivingForm.ui.qml</file>
-        <file>Forms/Receiving/ReceivingFileTemplate.ui.qml</file>
-        <file>Forms/Receiving/ReceivingFileTemplateDeletePopup.ui.qml</file>
 
 
-        <file>Forms/Messages/MessagesForm.ui.qml</file>
+        <file>Forms/Log/LogForm.ui.qml</file>
 
 
         <file>Forms/Settings/DeleteMePopup.ui.qml</file>
         <file>Forms/Settings/DeleteMePopup.ui.qml</file>
         <file>Forms/Settings/SettingsForm.ui.qml</file>
         <file>Forms/Settings/SettingsForm.ui.qml</file>
 
 
         <file>Forms/Notifications/NotificationsForm.ui.qml</file>
         <file>Forms/Notifications/NotificationsForm.ui.qml</file>
         <file>Forms/Notifications/NotificationTemplate.ui.qml</file>
         <file>Forms/Notifications/NotificationTemplate.ui.qml</file>
-
-        <file>Forms/Help/HelpForm.ui.qml</file>
-
-        <file>images/tray-icon.png</file>
     </qresource>
     </qresource>
 </RCC>
 </RCC>

+ 18 - 22
gui/src/qmlhandler.cpp

@@ -42,7 +42,8 @@ void QMLHandler::loadSettingsToGUI() {
 
 
 // ### QML Handlers ###
 // ### QML Handlers ###
 
 
-void QMLHandler::onStart() {
+// Main
+void QMLHandler::onStart(bool startWithCli) {
 	bool configExists = Config::loadFile();
 	bool configExists = Config::loadFile();
 
 
 	if (configExists) {
 	if (configExists) {
@@ -60,7 +61,7 @@ void QMLHandler::onStart() {
 			if (!ifstream(Config::getValue("CLI-Path"))) {
 			if (!ifstream(Config::getValue("CLI-Path"))) {
 				// Invalid CLI Path
 				// Invalid CLI Path
 				emit invalidCliPathPopupOpen();
 				emit invalidCliPathPopupOpen();
-			} else {
+			} else if (startWithCli) {
 				// Everything OK, init CLI
 				// Everything OK, init CLI
 				CliManager::init();
 				CliManager::init();
 			}
 			}
@@ -75,18 +76,20 @@ void QMLHandler::onStart() {
 	}
 	}
 }
 }
 
 
+void QMLHandler::onSwitchServer() { CliManager::writeToCli("disconnect"); }
+
 // No Config Found Popup
 // No Config Found Popup
 void QMLHandler::onNoConfigFoundPopupContinueButton(QString cli_path) {
 void QMLHandler::onNoConfigFoundPopupContinueButton(QString cli_path) {
 	Config::setValue("CLI-Path", cli_path.toUtf8().constData());
 	Config::setValue("CLI-Path", cli_path.toUtf8().constData());
 	Config::saveFile();
 	Config::saveFile();
-	onStart();
+	onStart(true);
 }
 }
 
 
 // Invalid Cli Path Popup
 // Invalid Cli Path Popup
 void QMLHandler::onInvalidCliPathPopupContinueButton(QString cli_path) {
 void QMLHandler::onInvalidCliPathPopupContinueButton(QString cli_path) {
 	Config::setValue("CLI-Path", cli_path.toUtf8().constData());
 	Config::setValue("CLI-Path", cli_path.toUtf8().constData());
 	Config::saveFile();
 	Config::saveFile();
-	onStart();
+	onStart(true);
 }
 }
 
 
 void QMLHandler::onInvalidCliPathPopupQuitButton() { emit closeWindow(); }
 void QMLHandler::onInvalidCliPathPopupQuitButton() { emit closeWindow(); }
@@ -99,39 +102,34 @@ void QMLHandler::onInvalidConfigPopupCreateDefaultButton() {
 	emit noConfigFoundPopupOpen();
 	emit noConfigFoundPopupOpen();
 }
 }
 
 
-// Sending
-void QMLHandler::onSendingSelectFileButton(QUrl url) {
+// Server Files
+void QMLHandler::onServerFilesSelectFileButton(QUrl url) {
 	sendFileUrl = url.toLocalFile();
 	sendFileUrl = url.toLocalFile();
 	emit log("File Selected: " + sendFileUrl.toString());
 	emit log("File Selected: " + sendFileUrl.toString());
-	emit sendingSetFileUrlText("Selected File: " + sendFileUrl.toString());
-	emit sendingEnableSendButton();
+	emit serverFilesSetFileUrlText(sendFileUrl.toString());
+	emit serverFilesEnableSendButton();
 }
 }
 
 
-void QMLHandler::onSendingSendFileButton() {
+void QMLHandler::onServerFilesSendFileButton() {
 	QString command = "put \"" + sendFileUrl.toString() + "\"";
 	QString command = "put \"" + sendFileUrl.toString() + "\"";
 	CliManager::writeToCli(command);
 	CliManager::writeToCli(command);
-	CliManager::writeToCli("extendedlist");
 }
 }
 
 
-void QMLHandler::onSendingClearSelectionButton() {
+void QMLHandler::onServerFilesClearSelectionButton() {
 	sendFileUrl = QUrl("");
 	sendFileUrl = QUrl("");
 	emit log("Cleared Selection");
 	emit log("Cleared Selection");
-	emit sendingSetFileUrlText("Selected File: None");
-	emit sendingDisableSendButton();
+	emit serverFilesSetFileUrlText("None");
+	emit serverFilesDisableSendButton();
 }
 }
 
 
-// Receiving
-void QMLHandler::onReceivingListFilesButton() { CliManager::writeToCli("extendedlist"); }
-
-void QMLHandler::onReceivingDownloadFileButton(QString fileName) {
+void QMLHandler::onServerFilesDownloadFileButton(QString fileName) {
 	QString command = "get \"" + fileName + "\"";
 	QString command = "get \"" + fileName + "\"";
 	CliManager::writeToCli(command);
 	CliManager::writeToCli(command);
 }
 }
 
 
-void QMLHandler::onReceivingConfirmDeleteFileButton(QString fileName) {
+void QMLHandler::onServerFilesConfirmDeleteFileButton(QString fileName) {
 	QString command = "deletefile \"" + fileName + "\"";
 	QString command = "deletefile \"" + fileName + "\"";
 	CliManager::writeToCli(command);
 	CliManager::writeToCli(command);
-	CliManager::writeToCli("extendedlist");
 }
 }
 
 
 // Messages
 // Messages
@@ -143,6 +141,7 @@ void QMLHandler::onKeyfileSelected(QString path) {
 	CliManager::writeToCli(command);
 	CliManager::writeToCli(command);
 }
 }
 void QMLHandler::onKeyfileClosed() { CliManager::writeToCli("closekey"); }
 void QMLHandler::onKeyfileClosed() { CliManager::writeToCli("closekey"); }
+
 void QMLHandler::onSettingsDeleteMeButton(QString password) {
 void QMLHandler::onSettingsDeleteMeButton(QString password) {
 	QString command = "deleteme " + password;
 	QString command = "deleteme " + password;
 	CliManager::writeToCli(command);
 	CliManager::writeToCli(command);
@@ -223,9 +222,6 @@ void QMLHandler::onSignupRegisterButton(QString username, QString passwordOne, Q
 	}
 	}
 }
 }
 
 
-// Footer
-void QMLHandler::onFooterGetStatusButton() { CliManager::writeToCli("extendedstatus"); }
-
 // Notifications
 // Notifications
 void QMLHandler::onDismissNotificationButton(int index) { emit dismissNotification(index); }
 void QMLHandler::onDismissNotificationButton(int index) { emit dismissNotification(index); }
 
 

+ 5 - 2
gui/src/qtquickcontrols2.conf

@@ -3,8 +3,11 @@
 ; http://doc.qt.io/qt-5/qtquickcontrols2-configuration.html
 ; http://doc.qt.io/qt-5/qtquickcontrols2-configuration.html
 
 
 [Controls]
 [Controls]
-Style=Material
+Style=Fusion
 
 
 [Material]
 [Material]
-Theme=Dark
 Accent=Cyan
 Accent=Cyan
+
+[Fusion]
+Palette\Window=#dedede
+Palette\WindowText=#000000