/* * This file is part of Remote Support Desktop * https://gitlab.das-netzwerkteam.de/RemoteWebApp/remote-support-desktop * Copyright 2020, 2021 Daniel Teichmann * Copyright 2020, 2021 Mike Gabriel * SPDX-License-Identifier: GPL-2.0-or-later * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import QtQuick 2.9 import QtQuick.Window 2.2 import QtQuick.Extras 1.4 import QtQuick.Controls 2.2 import QtQuick.Controls.Styles 1.4 import QtQuick.Dialogs 1.2 import QtQuick.Controls.Material 2.3 import "scenes" as Scenes /*! The main.qml file contains the window, with its header, sidebar, toast and main_content. */ ApplicationWindow { readonly property int normal_width: 650 readonly property int normal_height: 500 readonly property bool inPortrait: window.width < window.height minimumWidth: 400 minimumHeight: 460 width: normal_width height: normal_height id: window visible: true title: qsTr("Remote Support for your Desktop") onClosing: { mainqmladaptor.onCloseHandler(); } function minimizeWindow() { showMinimized(); console.log("Minimizing window now..."); } function showWindow() { showNormal(); console.log("Opening window now..."); } function main_content_pop(item) { if(item) { if(item.search(main_content.currentItem.objectName) >= 0) return } return main_content.pop(item) } function main_content_push(item) { if(item) { if(item.search(main_content.currentItem.objectName) >= 0) return } return main_content.push(item) } function main_content_replace(item) { if(item) { if(item.search(main_content.currentItem.objectName) >= 0) return } return main_content.replace(item) } MessageDialog { id: message_dialog objectName: "message_dialog" title: qsTr("Remote Support for your Desktop") text: qsTr("You are not supposed to see this message.\nThis is a bug.") icon: StandardIcon.Critical } ToastManager { id: toast anchors.leftMargin: inPortrait ? 0 : sidebar_drawer.width anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom anchors.top: parent.top } Connections { target: mainqmladaptor function onShowToastSignal(text, durationMs, type) { toast.show(text, durationMs, type) } } Connections { target: mainqmladaptor function onShowMessageDialogChanged(show) { message_dialog.visible = show } } StackView { id: main_content objectName: "main_content" anchors.top: top_menu_bar_frame.bottom anchors.right: parent.right anchors.bottom: parent.bottom anchors.left: parent.left anchors.leftMargin: !inPortrait ? sidebar_drawer.width : 0 anchors.topMargin: 0 // Our Application will start with the following content: initialItem: "scenes/Scene_placeholder.qml" replaceEnter: Transition { PropertyAnimation { property: "opacity" from: 0 to:1 duration: 100 } } replaceExit: Transition { PropertyAnimation { property: "opacity" from: 1 to:0 duration: 100 } } } Connections { target: mainqmladaptor function onMessageDialogTextChanged(text) { message_dialog.text = text } } Connections { target: mainqmladaptor function onMessageDialogTitleChanged(title) { message_dialog.title = title } } Connections { target: mainqmladaptor function onMessageDialogIconChanged(iconindex) { message_dialog.icon = iconindex } } /*! This is our sidebar (sidemenu) for navigation purposes. It will collapse if the window gets resized to a portrait format. Then it can be opened using the now visible button in the header or by swiping from left to right. main_content's leftMargin depends on sidebar_drawers's width We don't want them to overlap on different window heights und widths. */ Drawer { id: sidebar_drawer objectName: "sidebar_drawer" y: top_menu_bar_frame.height width: !inPortrait ? Math.min(300, Math.max(200, window.width * 0.333)) : (window.width * 0.5) height: window.height - top_menu_bar_frame.height modal: inPortrait interactive: inPortrait position: inPortrait ? 0 : 1 dragMargin: 1 margins: -2 visible: !inPortrait signal rwaHostSelected(string host_uuid) property bool rwaHostIsSelected: false ListView { id: sidebar_listview boundsBehavior: Flickable.StopAtBounds interactive: true clip: true anchors.fill: parent model: mainModel header: Rectangle { height: 50 width: parent.width color: Material.background ComboBox { id: server_chooser objectName: "server_chooser" padding: 0 width: parent.width height: 56 - y y: -6 model: mainqmladaptor.rwaHostModel textRole: "alias" onCurrentIndexChanged: { var rwa_host = mainqmladaptor.rwaHostModel if (rwa_host[currentIndex] !== undefined) { sidebar_drawer.rwaHostSelected(rwa_host[currentIndex].uuid) displayText = rwa_host[currentIndex].alias } } } } footer: ItemDelegate { id: footer text: " " + qsTr("Settings") width: parent.width enabled: false onClicked: { var scene_url = "scenes/Scene_placeholder.qml" header_text.text = qsTr("Settings") if (inPortrait) sidebar_drawer.close() if (scene_url.search(main_content.currentItem.objectName) >= 0) return main_content.replace(scene_url, StackView.Transition) } MenuSeparator { parent: footer width: parent.width anchors.verticalCenter: parent.top } } VisualItemModel { id: mainModel ListItem { text: " " + qsTr("Remote Control") scene_url: "scenes/remote_control/Scene_remote_control.qml" onListItemClick: { header_text.text = qsTr("Allow remote control") if (inPortrait) sidebar_drawer.close() if (scene_url.search(main_content.currentItem.objectName) >= 0) return main_content.replace(scene_url, StackView.Transition) } // Disabled till a RWAHost object is selected. enabled: sidebar_drawer.rwaHostIsSelected } ListItem { text: " " + qsTr("Remote View") scene_url: "scenes/Scene_remote_view.qml" onListItemClick: { header_text.text = qsTr("Allow remote view") if (inPortrait) sidebar_drawer.close() if (scene_url.search(main_content.currentItem.objectName) >= 0) return main_content.replace(scene_url, StackView.Transition) } // Disabled till a RWAHost object is selected. //enabled: sidebar_drawer.rwaHostIsSelected // But remote view is not implemented yet enabled: false } ListItem { text: " " + qsTr("Add RWA-Server") scene_url: "scenes/add_rwahost_wizard/Scene_step_1.qml" onListItemClick: { header_text.text = qsTr("Server addition wizard") if (inPortrait) sidebar_drawer.close() if (scene_url.search(main_content.currentItem.objectName) >= 0) return main_content.push(scene_url, StackView.ReplaceTransition) } } } ScrollIndicator.vertical: ScrollIndicator { } } } // Set dark/light theme based on the slider setting Material.theme: inPortrait ? (theme_portrait.position < 1 ? Material.Light : Material.Dark) : (theme_landscape.position < 1 ? Material.Light : Material.Dark) ToolBar { id: top_menu_bar_frame width: parent.width height: parent.height * 0.10 background: Rectangle { color: parent.Material.background border.color: parent.Material.background } Material.background: "#0d5eaf" Material.foreground: "#ffffff" anchors.margins: 0 anchors.left: parent.left anchors.top: parent.top Switch { id: theme_landscape width: 150 implicitWidth: 100 visible: !inPortrait parent: inPortrait ? sidebar_listview : top_menu_bar_frame height: parent.height anchors.margins: 10 text: qsTr("Dark theme") anchors.left: parent.left anchors.verticalCenterOffset: 0 anchors.leftMargin: 0 anchors.verticalCenter: parent.verticalCenter /*! Here is the default setting for dark/light mode */ checked: true onCheckedChanged: { theme_portrait.checked = checked } } Switch { id: theme_portrait visible: inPortrait parent: sidebar_listview height: 50 width: parent.width anchors.bottom: parent.bottom text: qsTr("Dark theme") checked: theme_landscape.checked onCheckedChanged: { theme_landscape.checked = checked } } Label { id: header_text height: parent.height color: "white" text: qsTr("Allow Remote Control") font.pointSize: 20 fontSizeMode: Text.Fit horizontalAlignment: Text.AlignRight verticalAlignment: Text.AlignVCenter anchors.left: inPortrait ? burger_button.right : parent.left anchors.leftMargin: inPortrait ? 5 : theme_landscape.width anchors.right: parent.right anchors.rightMargin: 5 anchors.verticalCenter: parent.verticalCenter padding: 5 } Button { id: burger_button width: 50 height: parent.height + 10 visible: inPortrait text: "≡" checkable: false font.pointSize: 24 flat: true anchors.left: parent.left anchors.leftMargin: 0 anchors.verticalCenter: parent.verticalCenter enabled: !sidebar_drawer.opened onClicked: { sidebar_drawer.open() enabled: false } } } } /*##^## Designer { D{i:14;anchors_width:650} } ##^##*/