Files
amnezia-client/client/ui/qml/main.qml
T

369 lines
11 KiB
QML
Raw Normal View History

import QtQuick
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Layouts
2021-08-09 00:41:52 +07:00
import PageEnum 1.0
2021-11-06 13:47:52 +03:00
import PageType 1.0
import Qt.labs.platform
import Qt.labs.folderlistmodel
import QtQuick.Dialogs
2022-10-24 13:56:12 +01:00
import QtQuick.Controls.Basic
2022-02-04 17:49:48 +03:00
import "Controls"
2021-08-19 01:27:22 +03:00
import "Pages"
2021-09-06 12:30:26 +03:00
import "Pages/Protocols"
2021-11-06 13:47:52 +03:00
import "Pages/Share"
2021-08-19 01:27:22 +03:00
import "Config"
2021-07-28 16:13:29 +07:00
2021-09-13 17:36:48 +03:00
Window {
2021-09-14 00:39:07 +03:00
property var pages: ({})
2021-09-16 16:19:14 +03:00
property var protocolPages: ({})
2021-11-06 13:47:52 +03:00
property var sharePages: ({})
2021-08-19 01:27:22 +03:00
2021-07-28 16:13:29 +07:00
id: root
visible: true
width: GC.screenWidth
2023-01-08 23:10:46 +00:00
height: GC.screenHeight
minimumWidth: GC.isDesktop() ? 360 : 0
2022-02-05 15:52:14 +03:00
minimumHeight: GC.isDesktop() ? 640 : 0
2023-01-08 23:10:46 +00:00
onClosing: function() {
2021-09-13 17:36:48 +03:00
console.debug("QML onClosing signal")
2021-08-09 00:41:52 +07:00
UiLogic.onCloseWindow()
}
2021-07-28 16:13:29 +07:00
title: "AmneziaVPN"
2021-11-06 13:47:52 +03:00
function gotoPage(type, page, reset, slide) {
2021-09-19 14:31:38 +03:00
2021-11-06 13:47:52 +03:00
let p_obj;
if (type === PageType.Basic) p_obj = pages[page]
else if (type === PageType.Proto) p_obj = protocolPages[page]
else if (type === PageType.ShareProto) p_obj = sharePages[page]
else return
2021-09-20 21:51:28 +03:00
2022-02-04 17:49:48 +03:00
//console.debug("QML gotoPage " + type + " " + page + " " + p_obj)
2021-07-28 16:13:29 +07:00
2021-12-20 02:29:23 +03:00
if (pageLoader.depth > 0) {
pageLoader.currentItem.deactivated()
}
2021-09-19 14:31:38 +03:00
2021-09-16 19:49:50 +03:00
if (slide) {
2021-11-06 13:47:52 +03:00
pageLoader.push(p_obj, {}, StackView.PushTransition)
2021-09-16 19:49:50 +03:00
} else {
2021-11-06 13:47:52 +03:00
pageLoader.push(p_obj, {}, StackView.Immediate)
2021-09-16 19:49:50 +03:00
}
2021-09-20 21:51:28 +03:00
2021-11-06 13:47:52 +03:00
if (reset) {
p_obj.logic.onUpdatePage();
}
p_obj.activated(reset)
2021-09-16 19:49:50 +03:00
}
2021-07-28 16:13:29 +07:00
function close_page() {
if (pageLoader.depth <= 1) {
return
}
2021-12-20 02:29:23 +03:00
pageLoader.currentItem.deactivated()
2021-07-28 16:13:29 +07:00
pageLoader.pop()
}
function set_start_page(page, slide) {
2021-12-20 02:29:23 +03:00
if (pageLoader.depth > 0) {
pageLoader.currentItem.deactivated()
}
2021-07-28 16:13:29 +07:00
pageLoader.clear()
if (slide) {
2021-09-14 00:39:07 +03:00
pageLoader.push(pages[page], {}, StackView.PushTransition)
2021-07-28 16:13:29 +07:00
} else {
2021-09-14 00:39:07 +03:00
pageLoader.push(pages[page], {}, StackView.Immediate)
2021-07-28 16:13:29 +07:00
}
2021-08-09 00:41:52 +07:00
if (page === PageEnum.Start) {
2021-07-28 16:13:29 +07:00
UiLogic.pushButtonBackFromStartVisible = !pageLoader.empty
UiLogic.onUpdatePage();
2021-07-28 16:13:29 +07:00
}
}
Rectangle {
y: GC.isDesktop() ? titleBar.height : 0
2021-08-19 01:27:22 +03:00
anchors.fill: parent
2021-07-28 16:13:29 +07:00
color: "white"
}
StackView {
id: pageLoader
y: GC.isDesktop() ? titleBar.height : 0
2021-08-19 01:27:22 +03:00
anchors.fill: parent
2021-09-13 17:36:48 +03:00
focus: true
2021-08-19 01:27:22 +03:00
2023-01-08 23:10:46 +00:00
onCurrentItemChanged: function() {
2021-09-14 00:39:07 +03:00
UiLogic.currentPageValue = currentItem.page
2021-07-28 16:13:29 +07:00
}
2021-09-13 17:36:48 +03:00
2023-01-08 23:10:46 +00:00
onDepthChanged: function() {
2021-11-06 13:47:52 +03:00
UiLogic.pagesStackDepth = depth
}
2023-01-08 23:10:46 +00:00
Keys.onPressed: function(event) {
UiLogic.keyPressEvent(event.key)
2021-10-21 18:10:28 +03:00
event.accepted = true
2021-09-13 17:36:48 +03:00
}
2021-07-28 16:13:29 +07:00
}
2021-09-14 00:39:07 +03:00
FolderListModel {
id: folderModelPages
folder: "qrc:/ui/qml/Pages/"
nameFilters: ["*.qml"]
showDirs: false
onStatusChanged: if (status == FolderListModel.Ready) {
for (var i=0; i<folderModelPages.count; i++) {
2021-11-06 13:47:52 +03:00
createPagesObjects(folderModelPages.get(i, "filePath"), PageType.Basic);
2021-09-14 00:39:07 +03:00
}
UiLogic.initalizeUiLogic()
}
2021-07-28 16:13:29 +07:00
}
2021-09-14 00:39:07 +03:00
FolderListModel {
id: folderModelProtocols
folder: "qrc:/ui/qml/Pages/Protocols/"
nameFilters: ["*.qml"]
showDirs: false
onStatusChanged: if (status == FolderListModel.Ready) {
for (var i=0; i<folderModelProtocols.count; i++) {
2021-11-06 13:47:52 +03:00
createPagesObjects(folderModelProtocols.get(i, "filePath"), PageType.Proto);
2021-09-14 00:39:07 +03:00
}
}
2021-07-28 16:13:29 +07:00
}
2021-11-06 13:47:52 +03:00
FolderListModel {
id: folderModelShareProtocols
folder: "qrc:/ui/qml/Pages/Share/"
nameFilters: ["*.qml"]
showDirs: false
onStatusChanged: if (status == FolderListModel.Ready) {
for (var i=0; i<folderModelShareProtocols.count; i++) {
createPagesObjects(folderModelShareProtocols.get(i, "filePath"), PageType.ShareProto);
}
}
}
function createPagesObjects(file, type) {
2021-09-19 14:31:38 +03:00
if (file.indexOf("Base") !== -1) return; // skip Base Pages
2021-11-06 13:47:52 +03:00
//console.debug("Creating compenent " + file + " for " + type);
2021-09-19 14:31:38 +03:00
2021-09-14 00:39:07 +03:00
var c = Qt.createComponent("qrc" + file);
var finishCreation = function (component){
2021-11-06 13:47:52 +03:00
if (component.status === Component.Ready) {
2021-09-14 00:39:07 +03:00
var obj = component.createObject(root);
2021-11-06 13:47:52 +03:00
if (obj === null) {
2021-09-14 00:39:07 +03:00
console.debug("Error creating object " + component.url);
}
else {
obj.visible = false
2021-11-06 13:47:52 +03:00
if (type === PageType.Basic) {
pages[obj.page] = obj
}
else if (type === PageType.Proto) {
2021-09-16 19:49:50 +03:00
protocolPages[obj.protocol] = obj
}
2021-11-06 13:47:52 +03:00
else if (type === PageType.ShareProto) {
sharePages[obj.protocol] = obj
2021-09-16 19:49:50 +03:00
}
// console.debug("Created compenent " + component.url + " for " + type);
2021-09-14 00:39:07 +03:00
}
2021-11-06 13:47:52 +03:00
} else if (component.status === Component.Error) {
2021-09-14 00:39:07 +03:00
console.debug("Error loading component:", component.errorString());
}
}
2021-11-06 13:47:52 +03:00
if (c.status === Component.Ready)
2021-09-14 00:39:07 +03:00
finishCreation(c);
else {
console.debug("Warning: " + file + " page components are not ready " + c.errorString());
2021-09-14 00:39:07 +03:00
}
}
2021-07-28 16:13:29 +07:00
Connections {
target: UiLogic
function onGoToPage(page, reset, slide) {
2022-02-04 17:49:48 +03:00
//console.debug("Qml Connections onGoToPage " + page);
2021-11-06 13:47:52 +03:00
root.gotoPage(PageType.Basic, page, reset, slide)
2021-07-28 16:13:29 +07:00
}
function onGoToProtocolPage(protocol, reset, slide) {
2022-02-04 17:49:48 +03:00
//console.debug("Qml Connections onGoToProtocolPage " + protocol);
2021-11-06 13:47:52 +03:00
root.gotoPage(PageType.Proto, protocol, reset, slide)
}
function onGoToShareProtocolPage(protocol, reset, slide) {
2022-02-04 17:49:48 +03:00
//console.debug("Qml Connections onGoToShareProtocolPage " + protocol);
2021-11-06 13:47:52 +03:00
root.gotoPage(PageType.ShareProto, protocol, reset, slide)
2021-09-16 19:49:50 +03:00
}
2021-11-06 13:47:52 +03:00
function onClosePage() {
2021-07-28 16:13:29 +07:00
root.close_page()
}
function onSetStartPage(page, slide) {
2021-07-28 16:13:29 +07:00
root.set_start_page(page, slide)
}
function onShowPublicKeyWarning() {
2021-08-09 00:41:52 +07:00
publicKeyWarning.visible = true
}
function onShowConnectErrorDialog() {
2021-08-09 00:41:52 +07:00
connectErrorDialog.visible = true
}
function onShow() {
2021-08-09 00:41:52 +07:00
root.show()
}
function onHide() {
2021-08-09 00:41:52 +07:00
root.hide()
}
2021-11-17 20:24:45 +03:00
function onRaise() {
root.show()
root.raise()
root.requestActivate()
}
2022-02-04 17:49:48 +03:00
function onToggleLogPanel() {
drawer_log.visible = !drawer_log.visible
}
2021-07-28 16:13:29 +07:00
}
2021-09-16 19:49:50 +03:00
2021-07-28 16:13:29 +07:00
MessageDialog {
id: closePrompt
// x: (root.width - width) / 2
// y: (root.height - height) / 2
title: qsTr("Exit")
text: qsTr("Do you really want to quit?")
// standardButtons: StandardButton.Yes | StandardButton.No
// onYesClicked: {
// Qt.quit()
// }
2021-07-28 16:13:29 +07:00
visible: false
}
2021-08-09 00:41:52 +07:00
MessageDialog {
id: publicKeyWarning
title: "AmneziaVPN"
text: qsTr("It's public key. Private key required")
visible: false
}
MessageDialog {
id: connectErrorDialog
title: "AmneziaVPN"
text: UiLogic.dialogConnectErrorText
visible: false
}
2022-02-04 17:49:48 +03:00
Drawer {
id: drawer_log
y: 0
x: 0
edge: Qt.BottomEdge
width: parent.width
height: parent.height * 0.85
modal: true
//interactive: activeFocus
onAboutToHide: {
pageLoader.focus = true
}
onAboutToShow: {
tfSshLog.focus = true
}
Item {
id: itemLog
anchors.fill: parent
Keys.onPressed: {
UiLogic.keyPressEvent(event.key)
event.accepted = true
}
RadioButtonType {
id: rbSshLog
focus: false
anchors.left: parent.left
anchors.leftMargin: 10
anchors.bottom: parent.bottom
anchors.bottomMargin: 2
height: 25
text: qsTr("Ssh log")
}
RadioButtonType {
id: rbAllLog
focus: false
checked: true
anchors.left: rbSshLog.right
anchors.bottom: rbSshLog.bottom
anchors.top: rbSshLog.top
height: rbSshLog.height
text: qsTr("App log")
}
CheckBoxType {
id: cbLogWrap
text: qsTr("Wrap words")
checked: true
anchors.right: parent.right
anchors.bottom: rbAllLog.bottom
anchors.top: rbAllLog.top
height: 15
imageHeight: 15
imageWidth: 15
onCheckedChanged: {
tfSshLog
}
}
TextAreaType {
id: tfSshLog
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: rbSshLog.top
flickableDirection: Flickable.AutoFlickIfNeeded
textArea.readOnly: true
textArea.selectByMouse: true
textArea.verticalAlignment: Text.AlignTop
textArea.text: {
if (!drawer_log.visible) return ""
else if (rbSshLog.checked ) return Debug.sshLog
else return Debug.allLog
}
textArea.wrapMode: cbLogWrap.checked ? TextEdit.WordWrap: TextEdit.NoWrap
Keys.onPressed: {
UiLogic.keyPressEvent(event.key)
event.accepted = true
}
textArea.onTextChanged: {
textArea.cursorPosition = textArea.length-1
}
MouseArea {
anchors.fill: parent
enabled: GC.isDesktop()
acceptedButtons: Qt.RightButton
onClicked: contextMenu.open()
}
ContextMenu {
id: contextMenu
textObj: tfSshLog.textArea
}
}
}
}
2021-07-28 16:13:29 +07:00
}