proton-bridge/internal/frontend/qml/ImportExportUI/MainWindow.qml

449 lines
14 KiB
QML

// Copyright (c) 2021 Proton Technologies AG
//
// This file is part of ProtonMail Bridge.
//
// ProtonMail Bridge 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 3 of the License, or
// (at your option) any later version.
//
// ProtonMail Bridge 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 ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
// This is main window
import QtQuick 2.8
import QtQuick.Window 2.2
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.3
import ImportExportUI 1.0
import ProtonUI 1.0
// Main Window
Window {
id : root
property alias tabbar : tabbar
property alias viewContent : viewContent
property alias viewAccount : viewAccount
property alias dialogAddUser : dialogAddUser
property alias dialogGlobal : dialogGlobal
property alias dialogCredits : dialogCredits
property alias dialogUpdate : dialogUpdate
property alias popupMessage : popupMessage
property alias popupFolderEdit : popupFolderEdit
property alias updateState : infoBar.state
property alias dialogExport : dialogExport
property alias dialogImport : dialogImport
property alias addAccountTip : addAccountTip
property int heightContent : height-titleBar.height
property real innerWindowBorder : go.goos=="darwin" ? 0 : Style.main.border
// main window appearance
width : Style.main.width
height : Style.main.height
flags : go.goos=="darwin" ? Qt.Window : Qt.Window | Qt.FramelessWindowHint
color: go.goos=="windows" ? Style.main.background : Style.transparent
title: go.programTitle
minimumWidth : Style.main.width
minimumHeight : Style.main.height
property bool isOutdateVersion : root.updateState == "forceUpgrade"
property bool activeContent :
!dialogAddUser .visible &&
!dialogCredits .visible &&
!dialogGlobal .visible &&
!dialogUpdate .visible &&
!dialogImport .visible &&
!dialogExport .visible &&
!popupFolderEdit .visible &&
!popupMessage .visible
Accessible.role: Accessible.Grouping
Accessible.description: qsTr("Window %1").arg(title)
Accessible.name: Accessible.description
WindowTitleBar {
id: titleBar
window: root
visible: go.goos!="darwin"
}
Rectangle {
anchors {
top : titleBar.bottom
left : parent.left
right : parent.right
bottom : parent.bottom
}
color: Style.title.background
}
InformationBar {
id: infoBar
anchors {
left : parent.left
right : parent.right
top : titleBar.bottom
leftMargin: innerWindowBorder
rightMargin: innerWindowBorder
}
}
TabLabels {
id: tabbar
currentIndex : 0
enabled: root.activeContent
anchors {
top : infoBar.bottom
right : parent.right
left : parent.left
leftMargin: innerWindowBorder
rightMargin: innerWindowBorder
}
model: [
{ "title" : qsTr("Import-Export" , "title of tab that shows account list" ), "iconText": Style.fa.home },
{ "title" : qsTr("Settings" , "title of tab that allows user to change settings" ), "iconText": Style.fa.cogs },
{ "title" : qsTr("Help" , "title of tab that shows the help menu" ), "iconText": Style.fa.life_ring }
]
}
// Content of tabs
StackLayout {
id: viewContent
enabled: root.activeContent
// dimensions
anchors {
left : parent.left
right : parent.right
top : tabbar.bottom
bottom : parent.bottom
leftMargin: innerWindowBorder
rightMargin: innerWindowBorder
bottomMargin: innerWindowBorder
}
// attributes
currentIndex : { return root.tabbar.currentIndex}
clip : true
// content
AccountView {
id : viewAccount
onAddAccount : dialogAddUser.show()
model : accountsModel
hasFooter : false
delegate : AccountDelegate {
row_width : viewContent.width
}
}
SettingsView { id: viewSettings; }
HelpView { id: viewHelp; }
}
// Bubble prevent action
Rectangle {
anchors {
left: parent.left
right: parent.right
top: titleBar.bottom
bottom: parent.bottom
}
visible: bubbleNote.visible
color: "#aa222222"
MouseArea {
anchors.fill: parent
hoverEnabled: true
}
}
BubbleNote {
id : bubbleNote
visible : false
Component.onCompleted : {
bubbleNote.place(0)
}
}
BubbleNote {
id:addAccountTip
anchors.topMargin: viewAccount.separatorNoAccount - 2*Style.main.fontSize
text : qsTr("Click here to start", "on first launch, this is displayed above the Add Account button to tell the user what to do first")
state: (go.isFirstStart && viewAccount.numAccounts==0 && root.viewContent.currentIndex==0) ? "Visible" : "Invisible"
bubbleColor: Style.main.textBlue
Component.onCompleted : {
addAccountTip.place(-1)
}
enabled: false
states: [
State {
name: "Visible"
// hack: opacity 100% makes buttons dialog windows quit wrong color
PropertyChanges{target: addAccountTip; opacity: 0.999; visible: true}
},
State {
name: "Invisible"
PropertyChanges{target: addAccountTip; opacity: 0.0; visible: false}
}
]
transitions: [
Transition {
from: "Visible"
to: "Invisible"
SequentialAnimation{
NumberAnimation {
target: addAccountTip
property: "opacity"
duration: 0
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: addAccountTip
property: "visible"
duration: 0
}
}
},
Transition {
from: "Invisible"
to: "Visible"
SequentialAnimation{
NumberAnimation {
target: addAccountTip
property: "visible"
duration: 300
}
NumberAnimation {
target: addAccountTip
property: "opacity"
duration: 500
easing.type: Easing.InOutQuad
}
}
}
]
}
// Dialogs
DialogAddUser {
id: dialogAddUser
anchors {
top : infoBar.bottom
bottomMargin: innerWindowBorder
leftMargin: innerWindowBorder
rightMargin: innerWindowBorder
}
onCreateAccount: Qt.openUrlExternally("https://protonmail.com/signup")
}
DialogUpdate {
id: dialogUpdate
title: root.isOutdateVersion ?
qsTr("%1 is outdated", "title of outdate dialog").arg(go.programTitle):
qsTr("%1 update to %2", "title of update dialog").arg(go.programTitle).arg(go.newversion)
introductionText: {
if (root.isOutdateVersion) {
if (go.goos=="linux") {
return qsTr('You are using an outdated version of our software.<br>
Please dowload and install the latest version to continue using %1.<br><br>
<a href="%2">%2</a>',
"Message for force-update in Linux").arg(go.programTitle).arg(go.landingPage)
} else {
return qsTr('You are using an outdated version of our software.<br>
Please dowload and install the latest version to continue using %1.<br><br>
You can continue with update or download and install the new version manually from<br><br>
<a href="%2">%2</a>',
"Message for force-update in Win/Mac").arg(go.programTitle).arg(go.landingPage)
}
} else {
if (go.goos=="linux") {
return qsTr('A new version of %1 is available.<br>
Check <a href="%2">release notes</a> to learn what is new in %3.<br>
Use your package manager to update or download and install new the version manually from<br><br>
<a href="%4">%4</a>',
"Message for update in Linux").arg(go.programTitle).arg(go.releaseNotesLink).arg(go.newversion).arg(go.landingPage)
} else {
return qsTr('A new version of %1 is available.<br>
Check <a href="%2">release notes</a> to learn what is new in %3.<br>
You can continue with update or download and install new the version manually from<br><br>
<a href="%4">%4</a>',
"Message for update in Win/Mac").arg(go.programTitle).arg(go.releaseNotesLink).arg(go.newversion).arg(go.landingPage)
}
}
}
}
DialogExport {
id: dialogExport
anchors {
top : infoBar.bottom
bottomMargin: innerWindowBorder
leftMargin: innerWindowBorder
rightMargin: innerWindowBorder
}
}
DialogImport {
id: dialogImport
anchors {
top : infoBar.bottom
bottomMargin: innerWindowBorder
leftMargin: innerWindowBorder
rightMargin: innerWindowBorder
}
}
Dialog {
id: dialogCredits
anchors {
top : infoBar.bottom
bottomMargin: innerWindowBorder
leftMargin: innerWindowBorder
rightMargin: innerWindowBorder
}
title: qsTr("Credits", "title for list of credited libraries")
Credits { }
}
DialogYesNo {
id: dialogGlobal
question : ""
answer : ""
z: 100
}
PopupEditFolder {
id: popupFolderEdit
anchors {
left: parent.left
right: parent.right
top: infoBar.bottom
bottom: parent.bottom
}
}
// Popup
PopupMessage {
id: popupMessage
anchors {
left : parent.left
right : parent.right
top : infoBar.bottom
bottom : parent.bottom
}
onClickedNo: popupMessage.hide()
onClickedOkay: popupMessage.hide()
onClickedCancel: popupMessage.hide()
onClickedYes: {
if (popupMessage.text == gui.areYouSureYouWantToQuit) Qt.quit()
}
}
// resize
MouseArea { // bottom
id: resizeBottom
property int diff: 0
anchors {
bottom : parent.bottom
left : parent.left
right : parent.right
}
cursorShape: Qt.SizeVerCursor
height: Style.main.fontSize
onPressed: {
var globPos = mapToGlobal(mouse.x, mouse.y)
resizeBottom.diff = root.height
resizeBottom.diff -= globPos.y
}
onMouseYChanged : {
var globPos = mapToGlobal(mouse.x, mouse.y)
root.height = Math.max(root.minimumHeight, globPos.y + resizeBottom.diff)
}
}
MouseArea { // right
id: resizeRight
property int diff: 0
anchors {
top : titleBar.bottom
bottom : parent.bottom
right : parent.right
}
cursorShape: Qt.SizeHorCursor
width: Style.main.fontSize/2
onPressed: {
var globPos = mapToGlobal(mouse.x, mouse.y)
resizeRight.diff = root.width
resizeRight.diff -= globPos.x
}
onMouseXChanged : {
var globPos = mapToGlobal(mouse.x, mouse.y)
root.width = Math.max(root.minimumWidth, globPos.x + resizeRight.diff)
}
}
function showAndRise(){
go.loadAccounts()
root.show()
root.raise()
if (!root.active) {
root.requestActivate()
}
}
// Toggle window
function toggle() {
go.loadAccounts()
if (root.visible) {
if (!root.active) {
root.raise()
root.requestActivate()
} else {
root.hide()
}
} else {
root.show()
root.raise()
}
}
onClosing : {
close.accepted=false
if (
(dialogImport.visible && dialogImport.currentIndex == 4 && go.progress!=1) ||
(dialogExport.visible && dialogExport.currentIndex == 2 && go.progress!=1)
) {
popupMessage.buttonOkay .visible = false
popupMessage.buttonYes .visible = false
popupMessage.buttonQuit .visible = true
popupMessage.buttonCancel .visible = true
popupMessage.show ( gui.areYouSureYouWantToQuit )
return
}
close.accepted=true
go.processFinished()
}
}