1044 lines
35 KiB
QML
1044 lines
35 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/>.
|
|
|
|
// Export dialog
|
|
import QtQuick 2.8
|
|
import QtQuick.Controls 2.2
|
|
import QtQuick.Layouts 1.3
|
|
import QtQuick.Dialogs 1.0
|
|
import ProtonUI 1.0
|
|
import ImportExportUI 1.0
|
|
|
|
Dialog {
|
|
id: root
|
|
|
|
enum Page {
|
|
SelectSourceType=0, ImapSource, LoadingStructure, SourceToTarget, Progress, Report
|
|
}
|
|
|
|
title: "" // qsTr("Importing from: %1", "todo").arg(address)
|
|
|
|
isDialogBusy: currentIndex==3 || currentIndex==4
|
|
|
|
property string account
|
|
property string address
|
|
property string inputPath : ""
|
|
property bool isFromFile : inputEmail.text == "" && root.inputPath != ""
|
|
property bool isFromIMAP : inputEmail.text != ""
|
|
property bool paused : false
|
|
|
|
property string msgDontShowAgain : qsTr("Do not show this message again")
|
|
|
|
|
|
signal cancel()
|
|
signal okay()
|
|
|
|
|
|
Rectangle { // SelectSourceType
|
|
id: sourceType
|
|
width: parent.width
|
|
height: parent.height
|
|
color: "transparent"
|
|
|
|
Text {
|
|
anchors {
|
|
horizontalCenter : parent.horizontalCenter
|
|
top : parent.top
|
|
topMargin : Style.dialog.titleSize
|
|
}
|
|
|
|
font.pointSize: Style.dialog.titleSize * Style.pt
|
|
color: Style.dialog.text
|
|
text: qsTr("Please select the source of the emails that you would like to import:")
|
|
}
|
|
|
|
Row {
|
|
anchors {
|
|
centerIn: parent
|
|
}
|
|
|
|
ImportSourceButton {
|
|
id: imapButton
|
|
width: winMain.width/2
|
|
iconText: "envelope_open"
|
|
text: qsTr("Import from account")
|
|
onClicked: root.incrementCurrentIndex()
|
|
}
|
|
|
|
ImportSourceButton {
|
|
id: fileButton
|
|
width: winMain.width/2
|
|
iconText: "folder_open"
|
|
text: qsTr("Import local files")
|
|
onClicked: { pathDialog.visible = true }
|
|
anchors.bottom: imapButton.bottom
|
|
}
|
|
}
|
|
|
|
FileDialog {
|
|
id: pathDialog
|
|
title: "Select local folder to import"
|
|
folder: shortcuts.home
|
|
onAccepted: {
|
|
sanitizePath(pathDialog.fileUrl.toString())
|
|
root.okay()
|
|
}
|
|
selectFolder: true
|
|
}
|
|
}
|
|
|
|
Rectangle { // ImapSource
|
|
id: imapSource
|
|
|
|
Text {
|
|
id: imapSourceTitle
|
|
anchors {
|
|
top : parent.top
|
|
topMargin: imapSourceTitle.height / 2
|
|
horizontalCenter : parent.horizontalCenter
|
|
}
|
|
|
|
font.pointSize: Style.dialog.titleSize * Style.pt
|
|
color: Style.dialog.text
|
|
text: qsTr("Sign in to your Account")
|
|
}
|
|
|
|
Rectangle { // line
|
|
id: titleLine
|
|
anchors {
|
|
top: imapSourceTitle.bottom
|
|
topMargin: imapSourceTitle.height / 2
|
|
horizontalCenter : parent.horizontalCenter
|
|
}
|
|
width: imapSourceContent.width
|
|
height: Style.main.heightLine
|
|
color: Style.main.line
|
|
}
|
|
|
|
Rectangle {
|
|
id: imapSourceContent
|
|
anchors {
|
|
top: titleLine.bottom
|
|
topMargin: imapSourceTitle.height / 2
|
|
bottom: buttonRow.top
|
|
}
|
|
width: winMain.width
|
|
color: Style.dialog.background
|
|
|
|
Text {
|
|
id: note
|
|
anchors {
|
|
bottom: wrapper.top
|
|
bottomMargin: imapSourceTitle.height / 2
|
|
horizontalCenter : parent.horizontalCenter
|
|
}
|
|
text: qsTr(
|
|
"Many email providers (Gmail, Yahoo, etc.) will require you to allow remote sign-on in order to perform import through IMAP. See <a href=\"%1\">this article</a> for details about how to do this with your email account.",
|
|
"Note added at IMAP credential page."
|
|
).arg("https://protonmail.com/support/knowledge-base/allowing-imap-access-and-entering-imap-details/")
|
|
font {
|
|
pointSize: Style.dialog.fontSize * Style.pt
|
|
}
|
|
color: Style.dialog.text
|
|
linkColor: Style.dialog.textBlue
|
|
wrapMode: Text.WordWrap
|
|
textFormat: Text.StyledText
|
|
horizontalAlignment: Text.AlignHCenter
|
|
|
|
width: parent.width * 0.618
|
|
onLinkActivated: Qt.openUrlExternally(link)
|
|
}
|
|
|
|
Rectangle {
|
|
id: wrapper
|
|
anchors.centerIn: parent
|
|
width: firstRow.width
|
|
height: firstRow.height + secondRow.height + secondRow.anchors.topMargin
|
|
color: Style.transparent
|
|
Row {
|
|
id: firstRow
|
|
spacing: imapSourceTitle.height
|
|
|
|
InputField {
|
|
id: inputEmail
|
|
iconText: Style.fa.user_circle
|
|
label: qsTr("Email", "todo") + ":"
|
|
onEditingFinished: {
|
|
root.guessEmailProvider()
|
|
}
|
|
onAccepted: if (root.check_inputs()) root.okay()
|
|
anchors.horizontalCenter: undefined
|
|
}
|
|
|
|
InputField {
|
|
id: inputPassword
|
|
label : qsTr("Password:")
|
|
iconText : Style.fa.lock
|
|
isPassword: true
|
|
onAccepted: if (root.check_inputs()) root.okay()
|
|
anchors.horizontalCenter: undefined
|
|
}
|
|
}
|
|
|
|
Row {
|
|
id: secondRow
|
|
spacing: imapSourceTitle.height
|
|
anchors {
|
|
top: firstRow.bottom
|
|
topMargin: 2*imapSourceTitle.height
|
|
}
|
|
|
|
InputField {
|
|
id: inputServer
|
|
iconText: Style.fa.server
|
|
label: qsTr("Server address", "todo") + ":"
|
|
onAccepted: if (root.check_inputs()) root.okay()
|
|
anchors.horizontalCenter: undefined
|
|
}
|
|
|
|
InputField {
|
|
id: inputPort
|
|
iconText: Style.fa.hashtag
|
|
label: qsTr("Port:")
|
|
onAccepted: if (root.check_inputs()) root.okay()
|
|
anchors.horizontalCenter: undefined
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Row { // Buttons
|
|
id:buttonRow
|
|
anchors {
|
|
right : parent.right
|
|
bottom : parent.bottom
|
|
rightMargin : Style.dialog.rightMargin
|
|
bottomMargin : Style.dialog.bottomMargin
|
|
}
|
|
spacing: Style.main.leftMargin
|
|
|
|
ButtonRounded {
|
|
fa_icon : Style.fa.times
|
|
text : qsTr("Cancel", "todo")
|
|
color_main : Style.dialog.textBlue
|
|
onClicked : root.cancel()
|
|
}
|
|
|
|
ButtonRounded {
|
|
fa_icon : Style.fa.check
|
|
text : qsTr("Next", "todo")
|
|
color_main : Style.dialog.background
|
|
color_minor : Style.dialog.textBlue
|
|
isOpaque : true
|
|
onClicked : root.okay()
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle { // LoadingStructure
|
|
id: loadingStructures
|
|
color : Style.dialog.background
|
|
width : parent.width
|
|
height : parent.height
|
|
|
|
Text {
|
|
anchors {
|
|
verticalCenter : parent.verticalCenter
|
|
horizontalCenter : parent.horizontalCenter
|
|
topMargin : Style.dialog.titleSize
|
|
}
|
|
font.pointSize: Style.dialog.titleSize * Style.pt
|
|
color: Style.dialog.text
|
|
text: root.isFromFile ? qsTr("Loading folder structures, please wait...") : qsTr("Loading structure of IMAP account, please wait...")
|
|
}
|
|
}
|
|
|
|
Rectangle { // SourceToTarget
|
|
id: dialogStructure
|
|
width : parent.width
|
|
height : parent.height
|
|
|
|
// Import instructions
|
|
ImportStructure {
|
|
id: importInstructions
|
|
anchors.bottom : masterImportSettings.top
|
|
titleFrom : root.isFromFile ? root.inputPath : inputEmail.text
|
|
titleTo : root.address
|
|
}
|
|
|
|
Column {
|
|
id: masterImportSettings
|
|
anchors {
|
|
right : parent.right
|
|
left : parent.left
|
|
bottom : parent.bottom
|
|
|
|
leftMargin : Style.main.leftMargin
|
|
rightMargin : Style.main.leftMargin
|
|
bottomMargin : Style.main.bottomMargin
|
|
}
|
|
|
|
spacing: Style.main.bottomMargin
|
|
|
|
Row {
|
|
spacing: masterImportSettings.width - labelMasterImportSettings.width - resetSourceButton.width
|
|
|
|
Text {
|
|
id: labelMasterImportSettings
|
|
text: qsTr("Master import settings:")
|
|
|
|
font {
|
|
bold: true
|
|
pointSize: Style.main.fontSize * Style.pt
|
|
}
|
|
color: Style.main.text
|
|
|
|
InfoToolTip {
|
|
anchors {
|
|
left: parent.right
|
|
bottom: parent.bottom
|
|
leftMargin : Style.dialog.leftMargin
|
|
}
|
|
info: qsTr(
|
|
"If master import date range is selected only emails within this range will be imported, unless it is specified differently in folder date range.",
|
|
"Text in master import settings tooltip."
|
|
)
|
|
}
|
|
}
|
|
|
|
// Reset all to default
|
|
ClickIconText {
|
|
id: resetSourceButton
|
|
text:qsTr("Reset all settings to default")
|
|
iconText: Style.fa.refresh
|
|
textColor: Style.main.textBlue
|
|
onClicked: {
|
|
go.resetSource()
|
|
root.decrementCurrentIndex()
|
|
timer.start()
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle{
|
|
id: line
|
|
anchors {
|
|
left : parent.left
|
|
right : parent.right
|
|
top : labelMasterImportSettings.bottom
|
|
|
|
topMargin : Style.dialog.spacing
|
|
}
|
|
height : Style.main.border * 2
|
|
color : Style.main.line
|
|
}
|
|
|
|
InlineDateRange {
|
|
id: globalDateRange
|
|
}
|
|
|
|
// Add global label (inline)
|
|
InlineLabelSelect {
|
|
id: globalLabels
|
|
}
|
|
|
|
Row {
|
|
spacing: Style.dialog.spacing
|
|
CheckBoxLabel {
|
|
id: importEncrypted
|
|
text: qsTr("Import encrypted emails as they are")
|
|
anchors {
|
|
bottom: parent.bottom
|
|
bottomMargin: Style.dialog.fontSize/1.8
|
|
}
|
|
}
|
|
|
|
InfoToolTip {
|
|
anchors {
|
|
verticalCenter: importEncrypted.verticalCenter
|
|
}
|
|
info: qsTr("When this option is enabled, encrypted emails will be imported as ciphertext. Otherwise, such messages will be skipped.", "todo")
|
|
}
|
|
}
|
|
}
|
|
|
|
// Buttons
|
|
Row {
|
|
spacing: Style.dialog.spacing
|
|
anchors {
|
|
right: parent.right
|
|
bottom: parent.bottom
|
|
rightMargin: Style.main.leftMargin
|
|
bottomMargin: Style.main.bottomMargin
|
|
}
|
|
|
|
ButtonRounded {
|
|
id: buttonCancelThree
|
|
fa_icon : Style.fa.times
|
|
text : qsTr("Cancel", "todo")
|
|
color_main : Style.dialog.textBlue
|
|
onClicked : root.cancel()
|
|
}
|
|
|
|
ButtonRounded {
|
|
id: buttonNextThree
|
|
fa_icon : Style.fa.check
|
|
text : qsTr("Import", "todo")
|
|
color_main : Style.dialog.background
|
|
color_minor : Style.dialog.textBlue
|
|
isOpaque : true
|
|
onClicked : root.okay()
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle { // Progress
|
|
id: progressStatus
|
|
width : parent.width
|
|
height : parent.height
|
|
color: Style.transparent
|
|
|
|
Column {
|
|
anchors.centerIn: progressStatus
|
|
spacing: Style.dialog.heightSeparator
|
|
|
|
Row { // description
|
|
spacing: Style.main.rightMargin
|
|
AccessibleText {
|
|
id: statusLabel
|
|
text : qsTr("Status:")
|
|
font.pointSize: Style.main.iconSize * Style.pt
|
|
color : Style.main.text
|
|
}
|
|
AccessibleText {
|
|
anchors.baseline: statusLabel.baseline
|
|
text : go.progressDescription == "" ? qsTr("importing") : go.progressDescription
|
|
elide: Text.ElideMiddle
|
|
width: progressbarImport.width - parent.spacing - statusLabel.width
|
|
font.pointSize: Style.dialog.textSize * Style.pt
|
|
color : Style.main.textDisabled
|
|
}
|
|
}
|
|
|
|
ProgressBar {
|
|
id: progressbarImport
|
|
implicitWidth : 2*progressStatus.width/3
|
|
implicitHeight : Style.exporting.rowHeight
|
|
value: go.progress
|
|
property int current: go.total * go.progress
|
|
property bool isFinished: finishedPartBar.width == progressbarImport.width
|
|
|
|
background: Rectangle {
|
|
radius : Style.exporting.boxRadius
|
|
color : Style.exporting.progressBackground
|
|
}
|
|
|
|
contentItem: Item {
|
|
Rectangle {
|
|
id: finishedPartBar
|
|
width : parent.width * progressbarImport.visualPosition
|
|
height : parent.height
|
|
radius : Style.exporting.boxRadius
|
|
gradient : Gradient {
|
|
GradientStop { position: 0.00; color: Qt.lighter(Style.exporting.progressStatus,1.1) }
|
|
GradientStop { position: 0.66; color: Style.exporting.progressStatus }
|
|
GradientStop { position: 1.00; color: Qt.darker(Style.exporting.progressStatus,1.1) }
|
|
}
|
|
|
|
Behavior on width {
|
|
NumberAnimation { duration:800; easing.type: Easing.InOutQuad }
|
|
}
|
|
}
|
|
Text {
|
|
anchors.centerIn: parent
|
|
text: {
|
|
if (progressbarImport.isFinished) return qsTr("Import finished","todo")
|
|
if (
|
|
go.progressDescription == gui.enums.progressInit ||
|
|
(go.progress == 0 && go.progressDescription=="")
|
|
) return qsTr("Estimating the total number of messages","todo")
|
|
if (
|
|
go.progressDescription == gui.enums.progressLooping
|
|
) return qsTr("Loading first message","todo")
|
|
//var msg = qsTr("Importing message %1 of %2 (%3%)","todo")
|
|
var msg = qsTr("Importing messages %1 of %2 (%3%)","todo")
|
|
if (root.paused) msg = qsTr("Importing paused at %1 of %2 (%3%)","todo")
|
|
return msg.arg(progressbarImport.current).arg(go.total).arg(Math.floor(go.progress*100))
|
|
}
|
|
color: Style.main.background
|
|
font {
|
|
pointSize: Style.dialog.fontSize * Style.pt
|
|
}
|
|
}
|
|
}
|
|
|
|
onIsFinishedChanged: { // show report
|
|
console.log("Is finished ", progressbarImport.isFinished)
|
|
if (progressbarImport.isFinished && root.currentIndex == DialogImport.Page.Progress) {
|
|
root.incrementCurrentIndex()
|
|
}
|
|
}
|
|
}
|
|
|
|
Row {
|
|
property int fails: go.progressFails
|
|
visible: fails > 0
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
Text {
|
|
color: Style.main.textRed
|
|
font {
|
|
pointSize : Style.dialog.fontSize * Style.pt
|
|
family : Style.fontawesome.name
|
|
}
|
|
text: Style.fa.exclamation_circle
|
|
}
|
|
|
|
Text {
|
|
property int fails: go.progressFails
|
|
color: Style.main.textRed
|
|
font.pointSize: Style.main.fontSize * Style.pt
|
|
text: " " + (
|
|
fails == 1 ?
|
|
qsTr("%1 message failed to be imported").arg(fails) :
|
|
qsTr("%1 messages failed to be imported").arg(fails)
|
|
)
|
|
}
|
|
}
|
|
|
|
Row { // buttons
|
|
spacing: Style.dialog.rightMargin
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
ButtonRounded {
|
|
id: pauseButton
|
|
fa_icon : root.paused ? Style.fa.play : Style.fa.pause
|
|
text : root.paused ? qsTr("Resume") : qsTr("Pause")
|
|
color_main : Style.dialog.textBlue
|
|
onClicked : {
|
|
if (root.paused) {
|
|
if (winMain.updateState == gui.enums.statusNoInternet) {
|
|
go.notifyError(gui.enums.errNoInternet)
|
|
return
|
|
}
|
|
go.resumeProcess()
|
|
} else {
|
|
go.pauseProcess()
|
|
}
|
|
root.paused = !root.paused
|
|
pauseButton.focus=false
|
|
}
|
|
visible : !progressbarImport.isFinished
|
|
}
|
|
|
|
ButtonRounded {
|
|
fa_icon : Style.fa.times
|
|
text : qsTr("Cancel")
|
|
color_main : Style.dialog.textBlue
|
|
visible : !progressbarImport.isFinished
|
|
onClicked : root.ask_cancel_progress()
|
|
}
|
|
|
|
ButtonRounded {
|
|
id: finish
|
|
fa_icon : Style.fa.check
|
|
text : qsTr("Okay","todo")
|
|
color_main : Style.dialog.background
|
|
color_minor : Style.dialog.textBlue
|
|
isOpaque : true
|
|
visible : progressbarImport.isFinished
|
|
onClicked : root.okay()
|
|
}
|
|
}
|
|
}
|
|
|
|
ImportReport {
|
|
}
|
|
|
|
ClickIconText {
|
|
id: buttonHelp
|
|
anchors {
|
|
bottom: progressStatus.bottom
|
|
right: progressStatus.right
|
|
margins: Style.main.rightMargin
|
|
}
|
|
|
|
textColor : Style.main.textDisabled
|
|
iconText : Style.fa.question_circle
|
|
text : qsTr("Help", "directs the user to the online user guide")
|
|
textBold : true
|
|
onClicked : Qt.openUrlExternally("https://protonmail.com/support/categories/import-export/")
|
|
}
|
|
}
|
|
|
|
Rectangle { // Report
|
|
id: finalReport
|
|
width : parent.width
|
|
height : parent.height
|
|
color: Style.transparent
|
|
|
|
property int imported: go.total - go.progressFails
|
|
|
|
|
|
Column {
|
|
anchors.centerIn : finalReport
|
|
spacing : Style.dialog.heightSeparator
|
|
|
|
Row {
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
Text {
|
|
font {
|
|
pointSize: Style.dialog.fontSize * Style.pt
|
|
family: Style.fontawesome.name
|
|
}
|
|
color: Style.main.textGreen
|
|
text: go.progressDescription!="" ? "" : Style.fa.check_circle
|
|
}
|
|
|
|
Text {
|
|
text: go.progressDescription!="" ? qsTr("Import failed: %1").arg(go.progressDescription) : " " + qsTr("Import completed successfully")
|
|
color: go.progressDescription!="" ? Style.main.textRed : Style.main.textGreen
|
|
font.bold : true
|
|
}
|
|
}
|
|
|
|
Text {
|
|
text: qsTr("<b>Import summary:</b><br>Total number of emails: %1<br>Imported emails: %2<br>Filtered out emails: %3<br>Errors: %4").arg(go.total).arg(go.progressImported).arg(go.progressSkipped).arg(go.progressFails)
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
textFormat: Text.RichText
|
|
horizontalAlignment: Text.AlignHCenter
|
|
}
|
|
|
|
Row {
|
|
spacing: Style.dialog.rightMargin
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
ButtonRounded {
|
|
fa_icon : Style.fa.info_circle
|
|
text : qsTr("View errors")
|
|
color_main : Style.dialog.textBlue
|
|
onClicked : {
|
|
go.loadImportReports()
|
|
reportList.show()
|
|
}
|
|
}
|
|
|
|
ButtonRounded {
|
|
fa_icon : Style.fa.send
|
|
text : qsTr("Report files")
|
|
color_main : Style.dialog.textBlue
|
|
onClicked : {
|
|
root.ask_send_report()
|
|
}
|
|
}
|
|
}
|
|
|
|
ButtonRounded {
|
|
text : qsTr("Close")
|
|
color_main : Style.dialog.background
|
|
color_minor : Style.dialog.textBlue
|
|
isOpaque : true
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
onClicked: root.okay()
|
|
}
|
|
}
|
|
|
|
ImportReport {
|
|
id: reportList
|
|
anchors.fill: finalReport
|
|
}
|
|
|
|
ClickIconText {
|
|
anchors {
|
|
bottom: finalReport.bottom
|
|
right: finalReport.right
|
|
margins: Style.main.rightMargin
|
|
}
|
|
|
|
textColor : Style.main.textDisabled
|
|
iconText : Style.fa.question_circle
|
|
text : qsTr("Help", "directs the user to the online user guide")
|
|
textBold : true
|
|
onClicked : Qt.openUrlExternally("https://protonmail.com/support/categories/import-export/")
|
|
}
|
|
}
|
|
|
|
function guessEmailProvider() {
|
|
var splitMail = inputEmail.text.split("@")
|
|
//console.log("finished ", splitMail)
|
|
if (splitMail.length != 2) return
|
|
switch (splitMail[1]){
|
|
case "yandex.ru":
|
|
case "yandex.com":
|
|
case "ya.ru":
|
|
inputServer.text = "imap.yandex.ru"
|
|
inputPort.text = "993"
|
|
break
|
|
case "outlook.com":
|
|
case "hotmail.com":
|
|
case "live.com":
|
|
case "live.ru":
|
|
inputServer.text = "imap-mail.outlook.com"
|
|
inputPort.text = "993"
|
|
break
|
|
case "seznam.cz":
|
|
case "email.cz":
|
|
case "post.cz":
|
|
inputServer.text = "imap.seznam.cz"
|
|
inputPort.text = "993"
|
|
break
|
|
case "gmx.de":
|
|
inputServer.text = "imap.gmx.net"
|
|
inputPort.text = "993"
|
|
break
|
|
case "rundbox.com":
|
|
inputServer.text = "mail."+splitMail[1]
|
|
inputPort.text = "993"
|
|
break
|
|
case "fastmail.com":
|
|
case "aol.com":
|
|
case "orange.fr":
|
|
case "hushmail.com":
|
|
case "ntlworld.com":
|
|
case "aol.com":
|
|
case "gmx.com":
|
|
case "mail.com":
|
|
case "mail.ru":
|
|
case "gmail.com":
|
|
inputServer.text = "imap."+splitMail[1]
|
|
inputPort.text = "993"
|
|
break
|
|
case (splitMail[1].match(/^yahoo\./) || {}).input:
|
|
inputServer.text = "imap.mail.yahoo.com"
|
|
inputPort.text = "993"
|
|
break
|
|
default:
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
function setServerParams() {
|
|
switch (emailProvider.currentIndex) {
|
|
case 1:
|
|
inputServer.text = "imap.gmail.com"
|
|
inputPort.text = "993"
|
|
break
|
|
case 2:
|
|
inputServer.text = "imap.yandex.com"
|
|
inputPort.text = "993"
|
|
break
|
|
case 3:
|
|
inputServer.text = "imap.outlook.com"
|
|
inputPort.text = "993"
|
|
break
|
|
case 4:
|
|
inputServer.text = "imap.yahoo.com"
|
|
inputPort.text = "993"
|
|
break
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
function update_label_time() {
|
|
var d = new Date();
|
|
var outstring = " "
|
|
outstring+=qsTr("Import")
|
|
outstring+="-"
|
|
outstring+=d.getDate()
|
|
outstring+="-"
|
|
outstring+=d.getMonth()+1
|
|
outstring+="-"
|
|
outstring+=d.getFullYear()
|
|
outstring+=" "
|
|
outstring+=d.getHours()
|
|
outstring+=":"
|
|
outstring+=d.getMinutes()
|
|
outstring+=" "
|
|
importLabel.text = outstring
|
|
}
|
|
|
|
function clear() {
|
|
root.inputPath = ""
|
|
clear_status()
|
|
inputEmail.clear()
|
|
inputPassword.clear()
|
|
inputServer.clear()
|
|
inputPort.clear()
|
|
reportList.hide()
|
|
globalLabels.reset()
|
|
}
|
|
|
|
PopupMessage {
|
|
id: errorPopup
|
|
width : parent.width
|
|
height : parent.height
|
|
msgWidth : root.width * 0.6108
|
|
}
|
|
|
|
Connections {
|
|
target: errorPopup
|
|
|
|
onClickedOkay : errorPopup.hide()
|
|
|
|
onClickedYes : {
|
|
if (errorPopup.msgID == "ask_send_report") {
|
|
errorPopup.hide()
|
|
root.report_sent(go.sendImportReport(root.address))
|
|
return
|
|
}
|
|
root.cancel()
|
|
errorPopup.hide()
|
|
}
|
|
onClickedNo : {
|
|
errorPopup.hide()
|
|
}
|
|
|
|
onClickedRetry : {
|
|
go.answerRetry()
|
|
errorPopup.hide()
|
|
}
|
|
onClickedSkip : {
|
|
go.answerSkip(
|
|
errorPopup.checkbox.text == root.msgDontShowAgain &&
|
|
errorPopup.checkbox.checked
|
|
)
|
|
errorPopup.hide()
|
|
}
|
|
onClickedCancel : {
|
|
root.cancel()
|
|
errorPopup.hide()
|
|
}
|
|
|
|
/*
|
|
onClickedCancel : {
|
|
errorPopup.hide()
|
|
root.ask_cancel_progress()
|
|
}
|
|
*/
|
|
}
|
|
|
|
|
|
function check_inputs() {
|
|
var isOK = true
|
|
switch (currentIndex) {
|
|
case 0: // select source
|
|
var res = go.checkPathStatus(root.inputPath)
|
|
isOK = (
|
|
(res&gui.enums.pathOK)==gui.enums.pathOK &&
|
|
(res&gui.enums.pathNotADir)==0 && // is a dir
|
|
(res&gui.enums.pathDirEmpty)==0 // is nonempty
|
|
)
|
|
if (!isOK) errorPopup.show(qsTr("Please select non-empty folder."))
|
|
break
|
|
// check directory
|
|
case 1: // imap settings
|
|
if (!(
|
|
inputEmail . checkNonEmpty() &&
|
|
inputPassword . checkNonEmpty() &&
|
|
inputServer . checkNonEmpty() &&
|
|
inputPort . checkNonEmpty() &&
|
|
inputPort . checkIsANumber()
|
|
//emailProvider . currentIndex!=0
|
|
)) isOK = false
|
|
if (winMain.updateState == gui.enums.statusNoInternet) { // todo: use main error dialog for this
|
|
errorPopup.show(qsTr("Please check your internet connection."))
|
|
return false
|
|
}
|
|
break
|
|
case 2: // loading structure
|
|
if (winMain.updateState == gui.enums.statusNoInternet) {
|
|
errorPopup.show(qsTr("Please check your internet connection."))
|
|
return false
|
|
}
|
|
break
|
|
case 3: // import insturctions
|
|
/*
|
|
console.log(" ====== TODO ======== ")
|
|
if (!structureExternal.hasTarget()) {
|
|
errorPopup.show(qsTr("Nothing selected for import."))
|
|
return false
|
|
}
|
|
*/
|
|
break
|
|
case 4: // import status
|
|
}
|
|
return isOK
|
|
}
|
|
|
|
onCancel: {
|
|
switch (currentIndex) {
|
|
case DialogImport.Page.ImapSource:
|
|
case DialogImport.Page.LoadingStructure:
|
|
root.clear()
|
|
root.currentIndex=0
|
|
break
|
|
case DialogImport.Page.SelectSourceType:
|
|
case DialogImport.Page.SourceToTarget:
|
|
case DialogImport.Page.Report:
|
|
root.hide()
|
|
break
|
|
case DialogImport.Page.Progress:
|
|
go.cancelProcess()
|
|
root.currentIndex=3
|
|
root.clear_status()
|
|
globalLabels.reset()
|
|
break
|
|
}
|
|
}
|
|
|
|
onOkay: {
|
|
var isOK = check_inputs()
|
|
if (isOK) {
|
|
timer.interval= currentIndex==0 || currentIndex==4 ? 10 : 300
|
|
switch (currentIndex) {
|
|
case DialogImport.Page.SelectSourceType: // select source
|
|
currentIndex=2
|
|
break
|
|
|
|
case DialogImport.Page.SourceToTarget:
|
|
globalDateRange.applyRange()
|
|
if (globalLabels.labelSelected) {
|
|
var isOK = go.createLabelOrFolder(
|
|
winMain.dialogImport.address,
|
|
globalLabels.labelName,
|
|
globalLabels.labelColor,
|
|
true,
|
|
"-1"
|
|
)
|
|
if (!isOK) return
|
|
}
|
|
incrementCurrentIndex()
|
|
break
|
|
|
|
case DialogImport.Page.Report:
|
|
root.clear_status()
|
|
root.hide()
|
|
break
|
|
|
|
case DialogImport.Page.LoadingStructure:
|
|
globalLabels.reset()
|
|
// TODO_: importInstructions.hasItems = (structureExternal.rowCount() > 0)
|
|
importInstructions.hasItems = true
|
|
case DialogImport.Page.ImapSource:
|
|
default:
|
|
incrementCurrentIndex()
|
|
}
|
|
timer.start()
|
|
}
|
|
}
|
|
|
|
onShow : {
|
|
root.clear()
|
|
if (winMain.updateState==gui.enums.statusNoInternet) {
|
|
if (winMain.updateState==gui.enums.statusNoInternet) {
|
|
winMain.popupMessage.show(go.canNotReachAPI)
|
|
root.hide()
|
|
}
|
|
}
|
|
}
|
|
|
|
onHide : {
|
|
root.clear()
|
|
}
|
|
|
|
function clear_status() { // TODO: move this to Gui.qml
|
|
go.progress=0.0
|
|
go.progressFails=0.0
|
|
go.total=0.0
|
|
go.progressDescription=gui.enums.progressInit
|
|
}
|
|
|
|
function ask_send_report(){
|
|
errorPopup.msgID="ask_send_report"
|
|
errorPopup.buttonYes.visible = true
|
|
errorPopup.buttonNo.visible = true
|
|
errorPopup.buttonOkay.visible = false
|
|
errorPopup.show (qsTr("Program will send the report of finished import process to our customer support. The report was filtered to remove all personal information.\n\nDo you want to send report?"))
|
|
}
|
|
|
|
function report_sent(isOK){
|
|
errorPopup.msgID="report_sent"
|
|
if (isOK) {
|
|
errorPopup.show (qsTr("Report sent successfully."))
|
|
} else {
|
|
errorPopup.show (qsTr("Not able to send report. Please contact customer support at importexport@protonmail.com"))
|
|
}
|
|
}
|
|
|
|
function ask_cancel_progress(){
|
|
errorPopup.msgID="ask_cancel_progress"
|
|
errorPopup.buttonYes.visible = true
|
|
errorPopup.buttonNo.visible = true
|
|
errorPopup.buttonOkay.visible = false
|
|
errorPopup.show (qsTr("Are you sure you want to cancel this import?"))
|
|
}
|
|
|
|
function ask_retry_skip_cancel(subject,errorMessage){
|
|
errorPopup.msgID="ask_retry_skip_cancel"
|
|
errorPopup.buttonYes.visible = false
|
|
errorPopup.buttonNo.visible = false
|
|
errorPopup.buttonOkay.visible = false
|
|
|
|
errorPopup.buttonRetry.visible = true
|
|
errorPopup.buttonSkip.visible = true
|
|
errorPopup.buttonCancel.visible = true
|
|
|
|
errorPopup.checkbox.text = root.msgDontShowAgain
|
|
|
|
errorPopup.show(
|
|
qsTr(
|
|
"Cannot import message \"%1\"\n\n%2\nCancel will stop the entire import.",
|
|
"error message while importing: arg1 is message subject, arg2 is error message"
|
|
).arg(subject).arg(errorMessage)
|
|
)
|
|
}
|
|
|
|
function sanitizePath(path) {
|
|
var pattern = "file://"
|
|
if (go.goos=="windows") pattern+="/"
|
|
root.inputPath = path.replace(pattern, "")
|
|
}
|
|
|
|
Connections {
|
|
target: timer
|
|
onTriggered: {
|
|
switch (currentIndex) {
|
|
case DialogImport.Page.SelectSourceType:
|
|
case DialogImport.Page.ImapSource:
|
|
case DialogImport.Page.SourceToTarget:
|
|
globalDateRange.getRange()
|
|
break
|
|
case DialogImport.Page.LoadingStructure:
|
|
go.setupAndLoadForImport(
|
|
root.isFromIMAP,
|
|
root.inputPath,
|
|
inputEmail.text, inputPassword.text, inputServer.text, inputPort.text,
|
|
root.account,
|
|
root.address
|
|
)
|
|
break
|
|
case DialogImport.Page.Progress:
|
|
go.startImport(root.address, importEncrypted.checked)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|