client-qml: add initial commit
Change-Id: I32bfdd2a618aa7ac6181da2697e241667b010aab
diff --git a/src/wizardview/WizardView.qml b/src/wizardview/WizardView.qml
new file mode 100644
index 0000000..0f3c29d
--- /dev/null
+++ b/src/wizardview/WizardView.qml
@@ -0,0 +1,736 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * 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 3 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, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Window 2.14
+import QtQuick.Controls 1.4 as CT
+import QtQuick.Controls 2.14
+import QtQuick.Controls.Universal 2.12
+import QtQuick.Layouts 1.3
+import QtGraphicalEffects 1.14
+import net.jami.Models 1.0
+
+import "../commoncomponents"
+import "../constant"
+import "components"
+
+Window {
+ id: wizardViewWindow
+
+ enum Mode {
+ CREATE,
+ IMPORT,
+ MIGRATE,
+ CREATESIP,
+ CONNECTMANAGER
+ }
+
+ enum NameRegistrationState {
+ BLANK,
+ INVALID,
+ TAKEN,
+ FREE,
+ SEARCHING
+ }
+
+ property int layoutWidth: 768
+ property int layoutHeight: 768
+ property int textFontSize: 9
+ property int wizardMode: WizardView.CREATE
+ property int addedAccountIndex: -1
+ property bool registrationStateOk: false
+ property string fileToImport: ""
+ property string registedName: ""
+
+ property var inputParaObject: ({})
+
+ /*
+ * signal to redirect the page to main view
+ */
+ signal needToShowMainViewWindow(int accountIndex)
+ signal wizardViewIsClosed
+
+ title: "Jami"
+ visible: true
+ width: layoutWidth
+ height: layoutHeight
+
+ onClosing: {
+ close.accepted = false
+ changePageQML(controlPanelStackView.welcomePageStackId)
+ wizardViewWindow.hide()
+ wizardViewWindow.wizardViewIsClosed()
+ }
+
+ Component.onCompleted: {
+ changePageQML(
+ controlPanelStackView.welcomePageStackId)
+ }
+
+ Connections{
+ target: ClientWrapper.accountAdaptor
+
+ function onAccountAdded(showBackUp, index) {
+ addedAccountIndex = index
+ if (showBackUp) {
+ changePageQML(controlPanelStackView.backupKeysPageId)
+ } else {
+ wizardViewWindow.hide()
+ changePageQML(controlPanelStackView.welcomePageStackId)
+ needToShowMainViewWindow(addedAccountIndex)
+ ClientWrapper.lrcInstance.accountListChanged()
+ }
+ }
+
+ // reportFailure
+ function onReportFailure() {
+ reportFailureQML()
+ }
+ }
+
+ Connections {
+ id: registeredNameFoundConnection
+ target: ClientWrapper.nameDirectory
+ enabled: false
+
+ function onRegisteredNameFound(status, address, name) {
+ slotRegisteredNameFound(status, address, name)
+ }
+ }
+
+ // failure redirect timer and qml object holder
+ Timer {
+ id: failureRedirectPageTimer
+
+ repeat: false
+ triggeredOnStart: false
+ interval: 1000
+
+ onTriggered: {
+ spinnerPage.successState = true
+ }
+ }
+
+ function reportFailureQML() {
+ spinnerPage.successState = false
+ failureRedirectPageTimer.restart()
+ }
+
+ function createAccountQML() {
+ switch (wizardMode) {
+ case WizardView.CONNECTMANAGER:
+ ClientWrapper.accountAdaptor.createJAMSAccount(inputParaObject)
+ break
+ case WizardView.CREATE:
+ case WizardView.IMPORT:
+ ClientWrapper.accountAdaptor.createJamiAccount(registedName,
+ inputParaObject,
+ createAccountPage.boothImgBase64,
+ (wizardMode === WizardView.CREATE))
+ break
+ default:
+ ClientWrapper.accountAdaptor.createSIPAccount(inputParaObject,createSIPAccountPage.boothImgBase64)
+ }
+
+ changePageQML(controlPanelStackView.spinnerPageId)
+ update()
+ }
+
+ function slotRegisteredNameFound(status, address, name) {
+ if (name.length < 3) {
+ registrationStateOk = false
+ createAccountPage.nameRegistrationUIState = WizardView.INVALID
+ } else if (registedName === name) {
+ switch (status) {
+ case NameDirectory.LookupStatus.NOT_FOUND:
+ case NameDirectory.LookupStatus.ERROR:
+ registrationStateOk = true
+ createAccountPage.nameRegistrationUIState = WizardView.FREE
+ break
+ case NameDirectory.LookupStatus.INVALID_NAME:
+ case NameDirectory.LookupStatus.INVALID:
+ registrationStateOk = false
+ createAccountPage.nameRegistrationUIState = WizardView.INVALID
+ break
+ case NameDirectory.LookupStatus.SUCCESS:
+ registrationStateOk = false
+ createAccountPage.nameRegistrationUIState = WizardView.TAKEN
+ break
+ }
+ }
+ validateWizardProgressionQML()
+ }
+
+ // function to set up nav bar visibility and the three buttons' visibiliy
+ function setNavBarVisibility(navVisible, back) {
+ navBarView.visible = (navVisible == true) || (back == true)
+ btnNext.visible = (navVisible == true)
+ btnPevious.visible = (navVisible == true)
+ btnBack.visible = (back == true)
+ && (ClientWrapper.utilsAdaptor.getAccountListSize() != 0)
+ }
+
+ function processWizardInformationsQML() {
+ inputParaObject = {}
+ switch (wizardMode) {
+ case WizardView.CREATE:
+ spinnerPage.progressLabelEditText = qsTr(
+ "Generating your Jami account...")
+ inputParaObject["alias"] = createAccountPage.text_fullNameEditAlias
+
+ inputParaObject["password"] = createAccountPage.text_confirmPasswordEditAlias
+
+ createAccountPage.clearAllTextFields()
+ break
+ case WizardView.IMPORT:
+ registedName = ""
+ spinnerPage.progressLabelEditText = qsTr(
+ "Importing account archive...")
+ // should only work in import from backup page or import from device page
+ if (controlPanelStackView.currentIndex
+ == controlPanelStackView.importFromBackupPageId) {
+ inputParaObject["password"]
+ = importFromBackupPage.text_passwordFromDeviceAlias
+ importFromBackupPage.clearAllTextFields()
+ } else if (controlPanelStackView.currentIndex
+ == controlPanelStackView.importFromDevicePageId) {
+ inputParaObject["archivePin"] = importFromBackupPage.text_pinFromDeviceAlias
+ inputParaObject["password"]
+ = importFromDevicePage.text_passwordFromDeviceAlias
+ importFromDevicePage.clearAllTextFields()
+ }
+ break
+ case WizardView.MIGRATE:
+ spinnerPage.progressLabelEditText = qsTr(
+ "Migrating your Jami account...")
+ break
+ case WizardView.CREATESIP:
+ spinnerPage.progressLabelEditText = qsTr(
+ "Generating your SIP account...")
+ if (createSIPAccountPage.text_sipFullNameEditAlias.length == 0) {
+ inputParaObject["alias"] = "SIP"
+ } else {
+ inputParaObject["alias"] = createSIPAccountPage.text_sipFullNameEditAlias
+ }
+
+ inputParaObject["hostname"] = createSIPAccountPage.text_sipServernameEditAlias
+ inputParaObject["username"] = createSIPAccountPage.text_sipUsernameEditAlias
+ inputParaObject["password"] = createSIPAccountPage.text_sipPasswordEditAlias
+ inputParaObject["proxy"] = createSIPAccountPage.text_sipProxyEditAlias
+
+ break
+ case WizardView.CONNECTMANAGER:
+ spinnerPage.progressLabelEditText = qsTr(
+ "Connecting to account manager...")
+ inputParaObject["username"]
+ = connectToAccountManagerPage.text_usernameManagerEditAlias
+ inputParaObject["password"]
+ = connectToAccountManagerPage.text_passwordManagerEditAlias
+ inputParaObject["manager"]
+ = connectToAccountManagerPage.text_accountManagerEditAlias
+ connectToAccountManagerPage.clearAllTextFields()
+ break
+ }
+
+ inputParaObject["archivePath"] = fileToImport
+
+ if (!("archivePin" in inputParaObject)) {
+ inputParaObject["archivePath"] = ""
+ }
+
+ // change page to spinner page
+ changePageQML(controlPanelStackView.spinnerPageId)
+ //create account
+ createAccountQML()
+ ClientWrapper.utilsAdaptor.createStartupLink()
+ }
+
+ function changePageQML(pageIndex) {
+ if (pageIndex == controlPanelStackView.spinnerPageId) {
+ setNavBarVisibility(false)
+ }
+ controlPanelStackView.currentIndex = pageIndex
+ if (pageIndex == controlPanelStackView.welcomePageStackId) {
+ fileToImport = ""
+ setNavBarVisibility(false, true)
+ createAccountPage.nameRegistrationUIState = WizardView.BLANK
+ } else if (pageIndex == controlPanelStackView.createAccountPageId) {
+ createAccountPage.initializeOnShowUp()
+ setNavBarVisibility(true)
+ // connection between register name found and its slot
+ registeredNameFoundConnection.enabled = true
+ // validate wizard progression
+ validateWizardProgressionQML()
+ // start photobooth
+ createAccountPage.startBooth()
+ } else if (pageIndex == controlPanelStackView.createSIPAccountPageId) {
+ createSIPAccountPage.initializeOnShowUp()
+ setNavBarVisibility(true)
+ btnNext.enabled = true
+ // start photo booth
+ createSIPAccountPage.startBooth()
+ } else if (pageIndex == controlPanelStackView.importFromDevicePageId) {
+ importFromDevicePage.initializeOnShowUp()
+ setNavBarVisibility(true)
+ } else if (pageIndex == controlPanelStackView.spinnerPageId) {
+ createAccountPage.nameRegistrationUIState = WizardView.BLANK
+ createAccountPage.isToSetPassword_checkState_choosePasswordCheckBox = false
+ } else if (pageIndex == controlPanelStackView.connectToAccountManagerPageId) {
+ setNavBarVisibility(true)
+ connectToAccountManagerPage.initializeOnShowUp()
+ btnNext.enabled = false
+ } else if (pageIndex == controlPanelStackView.importFromBackupPageId) {
+ setNavBarVisibility(true)
+ importFromBackupPage.clearAllTextFields()
+ fileToImport = ""
+ btnNext.enabled = false
+ } else if (pageIndex == controlPanelStackView.backupKeysPageId) {
+ setNavBarVisibility(false)
+ }
+ }
+
+ function validateWizardProgressionQML() {
+ if (controlPanelStackView.currentIndex
+ == controlPanelStackView.importFromDevicePageId) {
+ var validPin = !(importFromDevicePage.text_pinFromDeviceAlias.length == 0)
+ btnNext.enabled = validPin
+ return
+ } else if (controlPanelStackView.currentIndex
+ == controlPanelStackView.connectToAccountManagerPageId) {
+ var validUsername = !(connectToAccountManagerPage.text_usernameManagerEditAlias.length == 0)
+ var validPassword = !(connectToAccountManagerPage.text_passwordManagerEditAlias.length == 0)
+ var validManager = !(connectToAccountManagerPage.text_accountManagerEditAlias.length == 0)
+ btnNext.enabled = validUsername && validPassword
+ && validManager
+ return
+ } else if (controlPanelStackView.currentIndex
+ == controlPanelStackView.importFromBackupPageId) {
+ var validImport = !(fileToImport.length == 0)
+ btnNext.enabled = validImport
+ return
+ }
+
+ var usernameOk = !createAccountPage.checkState_signUpCheckboxAlias
+ || (createAccountPage.checkState_signUpCheckboxAlias
+ && !(registedName.length == 0)
+ && (registedName == createAccountPage.text_usernameEditAlias)
+ && (registrationStateOk == true))
+ var passwordOk = (createAccountPage.text_passwordEditAlias
+ == createAccountPage.text_confirmPasswordEditAlias)
+
+ // set password status label
+ if (passwordOk
+ && !(createAccountPage.text_passwordEditAlias.length == 0)) {
+ createAccountPage.displayState_passwordStatusLabelAlias = "Success"
+ } else if (!passwordOk) {
+ createAccountPage.displayState_passwordStatusLabelAlias = "Fail"
+ } else {
+ createAccountPage.displayState_passwordStatusLabelAlias = "Hide"
+ }
+ //set enable state of next button
+ btnNext.enabled = (usernameOk && passwordOk)
+ }
+
+ PasswordDialog {
+ id: passwordDialog
+
+ anchors.centerIn: parent.Center
+ x: (parent.width - width) / 2
+ y: (parent.height - height) / 2
+
+ visible: false
+ purpose: PasswordDialog.ExportAccount
+
+ onDoneSignal: {
+ if (currentPurpose === passwordDialog.ExportAccount) {
+ var success = (code === successCode)
+
+ var title = success ? qsTr("Success") : qsTr("Error")
+ var info = success ? qsTr("Export Successful") : qsTr(
+ "Export Failed")
+
+ ClientWrapper.accountAdaptor.passwordSetStatusMessageBox(success,
+ title, info)
+ if (success) {
+ console.log("Account Export Succeed")
+ wizardViewWindow.hide()
+ needToShowMainViewWindow(addedAccountIndex)
+ ClientWrapper.lrcInstance.accountListChanged()
+ }
+ }
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: forceActiveFocus()
+ }
+
+ // main frame rectangle
+ ScrollView {
+ id: wizardViewRect
+ anchors.fill: parent
+
+ clip: true
+
+ ColumnLayout {
+ id: content
+ width: wizardViewWindow.width // ensure correct width
+ height: wizardViewWindow.height // ensure correct height
+
+ Layout.alignment: Qt.AlignHCenter
+ RowLayout {
+ Layout.alignment: Qt.AlignHCenter
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ StackLayout {
+ id: controlPanelStackView
+ currentIndex: welcomePageStackId
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ property int welcomePageStackId: 0
+ property int createAccountPageId: 1
+ property int createSIPAccountPageId: 2
+ property int importFromBackupPageId: 3
+ property int backupKeysPageId: 4
+ property int importFromDevicePageId: 5
+ property int connectToAccountManagerPageId: 6
+ property int spinnerPageId: 7
+
+ WelcomePageLayout {
+ // welcome page, index 0
+ id: welcomePage
+
+ onWelcomePageRedirectPage: {
+ changePageQML(toPageIndex)
+ }
+
+ onVisibleChanged: {
+ if (visible)
+ setNavBarVisibility(false,
+ true)
+ }
+
+ Component.onCompleted: {
+ setNavBarVisibility(false, true)
+ }
+ }
+
+ CreateAccountPage {
+ // create account page, index 1
+ id: createAccountPage
+
+ onText_usernameEditAliasChanged: {
+ registrationStateOk = false
+ if (createAccountPage.checkState_signUpCheckboxAlias
+ && (createAccountPage.text_usernameEditAlias.length != 0)) {
+ registedName = ClientWrapper.utilsAdaptor.stringSimplifier(
+ createAccountPage.text_usernameEditAlias)
+ lookupTimer.restart()
+ } else {
+ createAccountPage.nameRegistrationUIState = WizardView.BLANK
+ lookupTimer.stop()
+ if (createAccountPage.text_usernameEditAlias.length == 0) {
+ lookupTimer.restart()
+ }
+ }
+ validateWizardProgressionQML()
+ }
+
+ onValidateWizardProgressionCreateAccountPage: {
+ validateWizardProgressionQML()
+ }
+
+ onText_passwordEditAliasChanged: {
+ validateWizardProgressionQML()
+ }
+
+ onText_confirmPasswordEditAliasChanged: {
+ validateWizardProgressionQML()
+ }
+
+ Timer {
+ id: lookupTimer
+
+ repeat: false
+ triggeredOnStart: false
+ interval: 200
+
+ onTriggered: {
+ if (createAccountPage.checkState_signUpCheckboxAlias
+ && (createAccountPage.text_usernameEditAlias.length != 0)) {
+ createAccountPage.nameRegistrationUIState = WizardView.SEARCHING
+ ClientWrapper.nameDirectory.lookupName("", registedName)
+ }
+ }
+ }
+ }
+
+ CreateSIPAccountPage {
+ // create SIP account page, index 2
+ id: createSIPAccountPage
+ }
+
+ ImportFromBackupPage {
+ // import from backup page, index 3
+ id: importFromBackupPage
+
+ onText_passwordFromBackupEditAliasChanged: {
+ validateWizardProgressionQML()
+ }
+
+ onImportFromFile_Dialog_Accepted: {
+ fileToImport = ClientWrapper.utilsAdaptor.toNativeSeparators(fileDir)
+ inputParaObject[""]
+
+ if (fileToImport.length != 0) {
+ importFromBackupPage.fileImportBtnText = ClientWrapper.utilsAdaptor.toFileInfoName(
+ fileToImport)
+ } else {
+ importFromBackupPage.fileImportBtnText = qsTr(
+ "Archive(none)")
+ }
+ validateWizardProgressionQML()
+ }
+ }
+
+ BackupKeyPage {
+ // backup keys page, index 4
+ id: backupKeysPage
+
+ onNeverShowAgainBoxClicked: {
+ ClientWrapper.accountAdaptor.settingsNeverShowAgain(isChecked)
+ }
+
+ onExport_Btn_FileDialogAccepted: {
+ if (accepted) {
+ // is there password? If so, go to password dialog, else, go to following directly
+ if (ClientWrapper.accountAdaptor.hasPassword()) {
+ passwordDialog.path = ClientWrapper.utilsAdaptor.getAbsPath(folderDir)
+ passwordDialog.open()
+ return
+ } else {
+ if (folderDir.length > 0) {
+ ClientWrapper.accountAdaptor.exportToFile(
+ ClientWrapper.utilsAdaptor.getCurrAccId(),
+ ClientWrapper.utilsAdaptor.getAbsPath(folderDir))
+ }
+ }
+ }
+
+ wizardViewWindow.hide()
+ changePageQML(controlPanelStackView.welcomePageStackId)
+ needToShowMainViewWindow(addedAccountIndex)
+ ClientWrapper.lrcInstance.accountListChanged()
+ }
+
+
+ onSkip_Btn_Clicked: {
+ wizardViewWindow.hide()
+ changePageQML(controlPanelStackView.welcomePageStackId)
+ needToShowMainViewWindow(addedAccountIndex)
+ ClientWrapper.lrcInstance.accountListChanged()
+ }
+ }
+
+ ImportFromDevicePage {
+ // import from device page, index 5
+ id: importFromDevicePage
+
+ onText_pinFromDeviceAliasChanged: {
+ validateWizardProgressionQML()
+ }
+
+ onText_passwordFromDeviceAliasChanged: {
+ validateWizardProgressionQML()
+ }
+ }
+
+ ConnectToAccountManagerPage {
+ // connect to account manager Page, index 6
+ id: connectToAccountManagerPage
+
+ onText_usernameManagerEditAliasChanged: {
+ validateWizardProgressionQML()
+ }
+
+ onText_passwordManagerEditAliasChanged: {
+ validateWizardProgressionQML()
+ }
+
+ onText_accountManagerEditAliasChanged: {
+ validateWizardProgressionQML()
+ }
+ }
+
+ SpinnerPage {
+ // spinner Page, index 7
+ id: spinnerPage
+ }
+ }
+ }
+
+ RowLayout {
+ id: navBarView
+
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
+ Layout.fillWidth: true
+
+ Layout.maximumHeight: 52
+ Layout.preferredHeight: 52
+
+ HoverableGradientButton {
+ id: btnPevious
+ Layout.alignment: Qt.AlignLeft
+ width: 85
+ height: 30
+ radius: height / 2
+
+ Layout.leftMargin: 11
+
+ Layout.preferredWidth: 85
+ Layout.preferredHeight: 30
+ text: qsTr("Previous")
+ font.pointSize: 10
+ font.kerning: true
+
+ onClicked: {
+ // stop photobooth previewing
+ if(controlPanelStackView.currentIndex == controlPanelStackView.createAccountPageId) {
+ createAccountPage.stopBooth()
+ }
+ if(controlPanelStackView.currentIndex == controlPanelStackView.createSIPAccountPageId) {
+ createSIPAccountPage.stopBooth()
+ }
+
+ // Disconnect registered name found Connection
+ registeredNameFoundConnection.enabled = false
+ // deal with look up status label and collapsible password widget
+ createAccountPage.nameRegistrationUIState = WizardView.BLANK
+ createAccountPage.isToSetPassword_checkState_choosePasswordCheckBox = false
+ // switch to welcome page
+ if (controlPanelStackView.currentIndex
+ == controlPanelStackView.createAccountPageId
+ || controlPanelStackView.currentIndex
+ == controlPanelStackView.createSIPAccountPageId
+ || controlPanelStackView.currentIndex
+ == controlPanelStackView.importFromBackupPageId
+ || controlPanelStackView.currentIndex
+ == controlPanelStackView.importFromDevicePageId
+ || controlPanelStackView.currentIndex
+ == controlPanelStackView.connectToAccountManagerPageId) {
+ changePageQML(
+ controlPanelStackView.welcomePageStackId)
+ }
+ }
+ }
+
+ Item {
+ Layout.alignment: Qt.AlignHCenter
+ Layout.fillHeight: true
+ Layout.minimumWidth: 40
+ Layout.fillWidth: true
+ }
+
+ HoverableGradientButton {
+ id: btnBack
+ Layout.alignment: Qt.AlignLeft
+ width: 85
+ height: 30
+ radius: height / 2
+
+ Layout.preferredWidth: 85
+ Layout.preferredHeight: 30
+ text: qsTr("Back")
+ font.pointSize: 10
+ font.kerning: true
+
+ onClicked: {
+ wizardViewWindow.hide()
+ needToShowMainViewWindow(addedAccountIndex)
+ }
+ }
+
+ Item {
+ Layout.alignment: Qt.AlignHCenter
+ Layout.fillHeight: true
+ Layout.minimumWidth: 40
+ Layout.fillWidth: true
+ }
+
+ HoverableGradientButton {
+ id: btnNext
+ Layout.alignment: Qt.AlignRight
+ width: 85
+ height: 30
+ radius: height / 2
+
+ Layout.rightMargin: 11
+
+ Layout.minimumWidth: 85
+ Layout.preferredWidth: 85
+ Layout.maximumWidth: 85
+
+ Layout.minimumHeight: 30
+ Layout.preferredHeight: 30
+ Layout.maximumHeight: 30
+
+ text: qsTr("Next")
+ font.pointSize: 10
+ font.kerning: true
+
+ onClicked: {
+ // stop photobooth previewing
+ if(controlPanelStackView.currentIndex == controlPanelStackView.createAccountPageId) {
+ createAccountPage.stopBooth()
+ }
+ if(controlPanelStackView.currentIndex == controlPanelStackView.createSIPAccountPageId) {
+ createSIPAccountPage.stopBooth()
+ }
+
+ registeredNameFoundConnection.enabled = false
+
+ if (controlPanelStackView.currentIndex
+ == controlPanelStackView.createAccountPageId) {
+ wizardMode = WizardView.CREATE
+ processWizardInformationsQML()
+ } else if (controlPanelStackView.currentIndex
+ == controlPanelStackView.importFromDevicePageId) {
+ wizardMode = WizardView.IMPORT
+ processWizardInformationsQML()
+ } else if (controlPanelStackView.currentIndex
+ == controlPanelStackView.createSIPAccountPageId) {
+ wizardMode = WizardView.CREATESIP
+ processWizardInformationsQML()
+ } else if (controlPanelStackView.currentIndex
+ == controlPanelStackView.connectToAccountManagerPageId) {
+ wizardMode = WizardView.CONNECTMANAGER
+ processWizardInformationsQML()
+ } else if (controlPanelStackView.currentIndex
+ == controlPanelStackView.importFromBackupPageId) {
+ wizardMode = WizardView.IMPORT
+ processWizardInformationsQML()
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/wizardview/components/BackupKeyPage.qml b/src/wizardview/components/BackupKeyPage.qml
new file mode 100644
index 0000000..59ec3ef
--- /dev/null
+++ b/src/wizardview/components/BackupKeyPage.qml
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * 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 3 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, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+import Qt.labs.platform 1.1
+
+import "../../constant"
+import "../../commoncomponents"
+
+ColumnLayout {
+ signal neverShowAgainBoxClicked(bool isChecked)
+ signal skip_Btn_Clicked
+ signal export_Btn_FileDialogAccepted(bool accepted, string folderDir)
+
+ /*
+ * JamiFileDialog for exporting account
+ */
+ JamiFileDialog {
+ id: exportBtn_Dialog
+
+ mode: JamiFileDialog.SaveFile
+
+ title: qsTr("Export Account Here")
+ folder: StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/Desktop"
+
+ nameFilters: [qsTr("Jami archive files") + " (*.gz)", qsTr(
+ "All files") + " (*)"]
+
+ onAccepted: {
+ export_Btn_FileDialogAccepted(true, file)
+ }
+
+ onRejected: {
+ export_Btn_FileDialogAccepted(false, folder)
+ }
+
+ onVisibleChanged: {
+ if (!visible) {
+ rejected()
+ }
+ }
+ }
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ Item {
+ Layout.alignment: Qt.AlignHCenter
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+
+ /*
+ * Main layout for BackupKeyPage which consists of the buttons and "never show again" check box
+ */
+ ColumnLayout {
+ Layout.alignment: Qt.AlignCenter
+ Layout.maximumWidth: 366
+
+ spacing: 12
+
+ Label {
+ id: backupKeysLabel
+ Layout.alignment: Qt.AlignHCenter
+
+ Layout.maximumWidth: 366
+ Layout.maximumHeight: 21
+ Layout.preferredWidth: 366
+ Layout.preferredHeight: 21
+
+ text: qsTr("Backup your account")
+ font.pointSize: 13
+ font.kerning: true
+ }
+ Label {
+ id: backupInfoLabel1
+ Layout.maximumWidth: 366
+ Layout.maximumHeight: 57
+ Layout.preferredWidth: 366
+ Layout.preferredHeight: 57
+
+ text: qsTr("This account only exists on this device. If you lost your device or uninstall the application,your account will be deleted. You can backup your account now or later.")
+ wrapMode: Text.WordWrap
+ horizontalAlignment: Text.AlignJustify
+ verticalAlignment: Text.AlignVCenter
+ }
+ CheckBox {
+ id: neverShowAgainBox
+ checked: false
+
+ Layout.maximumWidth: 366
+ Layout.maximumHeight: 19
+ Layout.preferredWidth: 366
+ Layout.preferredHeight: 19
+
+ indicator.implicitWidth: 10
+ indicator.implicitHeight:10
+
+ text: qsTr("Never show me this again")
+ font.pointSize: 8
+
+ onClicked: {
+ neverShowAgainBoxClicked(checked)
+ }
+ }
+ RowLayout {
+ Layout.fillWidth: true
+ Layout.maximumHeight: 20
+
+ Item {
+ Layout.alignment: Qt.AlignVCenter
+ Layout.fillHeight: true
+ Layout.maximumWidth: 40
+ Layout.minimumWidth: 10
+ }
+
+ HoverableGradientButton {
+ id: exportBtn
+
+ Layout.alignment: Qt.AlignVCenter
+ Layout.minimumWidth: 85
+ Layout.preferredWidth: 85
+ Layout.maximumWidth: 85
+
+ Layout.minimumHeight: 30
+ Layout.preferredHeight: 30
+ Layout.maximumHeight: 30
+
+ text: qsTr("Export")
+ font.kerning: true
+ fontPointSize: 10
+ radius: height / 2
+ backgroundColor: JamiTheme.releaseColor
+
+ onClicked: {
+ exportBtn_Dialog.open()
+ }
+ }
+
+ Item {
+ Layout.alignment: Qt.AlignVCenter
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+
+ HoverableGradientButton {
+ id: skipBtn
+
+ Layout.alignment: Qt.AlignVCenter
+ Layout.minimumWidth: 85
+ Layout.preferredWidth: 85
+ Layout.maximumWidth: 85
+
+ Layout.minimumHeight: 30
+ Layout.preferredHeight: 30
+ Layout.maximumHeight: 30
+
+ text: qsTr("Skip")
+ fontPointSize: 10
+ font.kerning: true
+ radius: height / 2
+ backgroundColor: JamiTheme.releaseColor
+
+ onClicked: {
+ skip_Btn_Clicked()
+ }
+ }
+
+ Item {
+ Layout.alignment: Qt.AlignVCenter
+ Layout.fillHeight: true
+ Layout.maximumWidth: 40
+ Layout.minimumWidth: 10
+ }
+ }
+ }
+
+ Item {
+ Layout.alignment: Qt.AlignHCenter
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+}
diff --git a/src/wizardview/components/CollapsiblePasswordWidget.qml b/src/wizardview/components/CollapsiblePasswordWidget.qml
new file mode 100644
index 0000000..82af6e2
--- /dev/null
+++ b/src/wizardview/components/CollapsiblePasswordWidget.qml
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * 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 3 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, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+
+import "../../constant"
+import "../../commoncomponents"
+
+/*
+ * an independent widget that keeps the password's textfields, including password field and confirm password field
+ */
+
+GridLayout {
+ id: root
+
+ property alias text_passwordEditAlias: passwordEdit.text
+ property alias text_confirmPasswordEditAlias: confirmPasswordEdit.text
+ property alias state_passwordStatusLabelAlias: passwordStatusLabel.passwordStatusState
+
+ property bool visibleCollapsble: false
+
+ function clearAllTextFields() {
+ passwordEdit.clear()
+ confirmPasswordEdit.clear()
+ }
+
+ visible: visibleCollapsble
+ Layout.fillWidth: true
+ rowSpacing: 6
+ columnSpacing: 6
+
+ rows: 2
+ columns: 2
+
+ Layout.leftMargin: 32
+
+ InfoLineEdit {
+ id: passwordEdit
+
+ visible: visibleCollapsble
+
+ Layout.row: 0
+ Layout.column: 0
+
+ fieldLayoutWidth: 261
+
+ Layout.alignment: Qt.AlignHCenter
+
+ selectByMouse: true
+ echoMode: TextInput.Password
+ placeholderText: qsTr("Password")
+ font.pointSize: 10
+ font.kerning: true
+ }
+
+ Item {
+ Layout.row: 0
+ Layout.column: 1
+
+ Layout.maximumWidth: 32
+ Layout.preferredWidth: 32
+ Layout.minimumWidth: 32
+
+ Layout.maximumHeight: 30
+ Layout.preferredHeight: 30
+ Layout.minimumHeight: 30
+ }
+
+ InfoLineEdit {
+ id: confirmPasswordEdit
+
+ visible: visibleCollapsble
+
+ Layout.row: 1
+ Layout.column: 0
+
+ fieldLayoutWidth: 261
+
+ Layout.alignment: Qt.AlignHCenter
+
+ selectByMouse: true
+ echoMode: TextInput.Password
+ placeholderText: qsTr("Confirm Password")
+ font.pointSize: 10
+ font.kerning: true
+ }
+
+ Label {
+ id: passwordStatusLabel
+
+ visible: visibleCollapsble
+
+ Layout.row: 1
+ Layout.column: 1
+
+ Layout.maximumWidth: 32
+ Layout.preferredWidth: 32
+ Layout.minimumWidth: 32
+
+ Layout.maximumHeight: 30
+ Layout.preferredHeight: 30
+ Layout.minimumHeight: 30
+
+ Layout.alignment: Qt.AlignRight
+
+ property string passwordStatusState: "Hide"
+
+ background: {
+ switch (passwordStatusState) {
+ case "Hide":
+ return Qt.createQmlObject("import QtQuick 2.14;
+import \"qrc:/src/constant/\";
+Rectangle {
+anchors.fill: parent;
+color: \"transparent\"; }", passwordStatusLabel)
+ case "Fail":
+ return Qt.createQmlObject("import QtQuick 2.14;
+import \"qrc:/src/constant/\";
+Rectangle {
+anchors.fill: parent;
+Image{
+anchors.fill: parent;
+source: \"image://tintedPixmap/\"+ (\"qrc:/images/icons/baseline-close-24px.svg\").replace(\"qrc:/images/icons/\",\"\") + \"+\" + JamiTheme.red_;
+mipmap: true;}
+}", passwordStatusLabel)
+ case "Success":
+ return Qt.createQmlObject("import QtQuick 2.14;
+import \"qrc:/src/constant/\";
+Rectangle {
+anchors.fill: parent;
+Image {
+anchors.fill: parent;
+source: \"image://tintedPixmap/\"+ (\"qrc:/images/icons/baseline-done-24px.svg\").replace(\"qrc:/images/icons/\",\"\") + \"+\" + JamiTheme.presenceGreen_;
+mipmap: true;}
+}", passwordStatusLabel)
+ }
+ }
+ }
+}
diff --git a/src/wizardview/components/ConnectToAccountManagerPage.qml b/src/wizardview/components/ConnectToAccountManagerPage.qml
new file mode 100644
index 0000000..c41dcef
--- /dev/null
+++ b/src/wizardview/components/ConnectToAccountManagerPage.qml
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * 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 3 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, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+
+import "../../constant"
+import "../../commoncomponents"
+
+ColumnLayout {
+ property alias text_usernameManagerEditAlias: usernameManagerEdit.text
+ property alias text_passwordManagerEditAlias: passwordManagerEdit.text
+ property alias text_accountManagerEditAlias: accountManagerEdit.text
+
+ function initializeOnShowUp() {
+ clearAllTextFields()
+ }
+
+ function clearAllTextFields() {
+ usernameManagerEdit.clear()
+ passwordManagerEdit.clear()
+ accountManagerEdit.clear()
+ }
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ Item {
+ Layout.alignment: Qt.AlignHCenter
+ Layout.preferredHeight: 40
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+
+ ColumnLayout {
+ Layout.alignment: Qt.AlignCenter
+ Layout.fillWidth: true
+
+ spacing: 12
+
+ Label {
+ id: signInLabel
+
+ Layout.alignment: Qt.AlignHCenter
+ Layout.minimumWidth: 256
+ Layout.preferredHeight: 21
+ text: qsTr("Sign in")
+ font.pointSize: 13
+ font.kerning: true
+ }
+
+ InfoLineEdit {
+ id: usernameManagerEdit
+
+ Layout.alignment: Qt.AlignHCenter
+
+ selectByMouse: true
+ placeholderText: qsTr("Username")
+ }
+
+ InfoLineEdit {
+ id: passwordManagerEdit
+
+ Layout.alignment: Qt.AlignHCenter
+ selectByMouse: true
+ echoMode: TextInput.Password
+ placeholderText: qsTr("Password")
+ }
+
+ InfoLineEdit {
+ id: accountManagerEdit
+
+ Layout.alignment: Qt.AlignHCenter
+
+ selectByMouse: true
+ placeholderText: qsTr("Account Manager")
+ }
+ }
+
+ Item {
+ Layout.alignment: Qt.AlignHCenter
+ Layout.preferredHeight: 40
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+}
diff --git a/src/wizardview/components/CreateAccountPage.qml b/src/wizardview/components/CreateAccountPage.qml
new file mode 100644
index 0000000..f59b2c6
--- /dev/null
+++ b/src/wizardview/components/CreateAccountPage.qml
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * 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 3 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, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+
+import "../"
+import "../../constant"
+import "../../commoncomponents"
+
+ColumnLayout {
+ property alias text_fullNameEditAlias: fullNameEdit.text
+ property alias text_usernameEditAlias: usernameEdit.text
+
+ property int nameRegistrationUIState: WizardView.BLANK
+
+ property alias checkState_signUpCheckboxAlias: signUpCheckbox.checked
+ property alias isToSetPassword_checkState_choosePasswordCheckBox: choosePasswordCheckBox.checked
+
+ // photo booth alias
+ property alias boothImgBase64: setAvatarWidget.imgBase64
+
+ // collapse password widget property aliases
+ property alias text_passwordEditAlias: collapsiblePasswordWidget.text_passwordEditAlias
+ property alias text_confirmPasswordEditAlias: collapsiblePasswordWidget.text_confirmPasswordEditAlias
+ property alias displayState_passwordStatusLabelAlias: collapsiblePasswordWidget.state_passwordStatusLabelAlias
+
+ signal validateWizardProgressionCreateAccountPage
+
+ function initializeOnShowUp() {
+ clearAllTextFields()
+
+ signUpCheckbox.checked = true
+ choosePasswordCheckBox.checked = false
+ usernameEdit.enabled = true
+ fullNameEdit.enabled = true
+ }
+
+ function clearAllTextFields() {
+ usernameEdit.clear()
+ fullNameEdit.clear()
+
+ collapsiblePasswordWidget.clearAllTextFields()
+ }
+
+ function setCollapsiblePasswordWidgetVisibility(visible) {
+ choosePasswordCheckBox.checked = visible
+ if (visible) {
+ choosePasswordCheckBox.visible = true
+ }
+ }
+
+ function startBooth(){
+ setAvatarWidget.startBooth()
+ }
+
+ function stopBooth(){
+ setAvatarWidget.stopBooth()
+ }
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ spacing: 6
+
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+
+ ColumnLayout {
+ Layout.alignment: Qt.AlignHCenter
+
+ spacing: 5
+
+ ColumnLayout {
+ Layout.fillWidth: true
+ spacing: 6
+
+ Layout.alignment: Qt.AlignHCenter
+
+ Label {
+ id: profileSectionLabel
+
+
+ Layout.alignment: Qt.AlignHCenter
+
+ text: qsTr("Profile")
+ font.pointSize: 13
+ font.kerning: true
+
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+
+ PhotoboothView{
+ id: setAvatarWidget
+
+ Layout.alignment: Qt.AlignHCenter
+
+ Layout.maximumWidth: 261
+ Layout.preferredWidth: 261
+ Layout.minimumWidth: 261
+ Layout.maximumHeight: 261
+ Layout.preferredHeight: 261
+ Layout.minimumHeight: 261
+ }
+
+ RowLayout {
+ spacing: 6
+ Layout.alignment: Qt.AlignHCenter
+ Layout.maximumHeight: 30
+
+ Item {
+ Layout.fillWidth: true
+ Layout.maximumHeight: 10
+ }
+
+ InfoLineEdit {
+ id: fullNameEdit
+
+ fieldLayoutWidth: 261
+
+ Layout.alignment: Qt.AlignCenter
+
+ selectByMouse: true
+ placeholderText: qsTr("Profile name")
+ font.pointSize: 10
+ font.kerning: true
+ }
+
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+ }
+ }
+ }
+
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+
+ ColumnLayout {
+ Layout.alignment: Qt.AlignHCenter
+
+ spacing: 5
+ Label {
+ id: accountSectionLabel
+ Layout.alignment: Qt.AlignHCenter
+
+ Layout.maximumWidth: 261
+ Layout.preferredWidth: 261
+ Layout.minimumWidth: 261
+ Layout.maximumHeight: 30
+ Layout.preferredHeight: 30
+ Layout.minimumHeight: 30
+
+ text: qsTr("Account")
+ font.pointSize: 13
+ font.kerning: true
+
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+
+ ColumnLayout {
+ Layout.fillWidth: true
+ spacing: 6
+
+ CheckBox {
+ id: signUpCheckbox
+ checked: true
+
+ indicator.width: 10
+ indicator.height: 10
+
+ Layout.leftMargin: 32
+
+ Layout.minimumWidth: 261
+
+ Layout.maximumHeight: 30
+ Layout.preferredHeight: 30
+ Layout.minimumHeight: 25
+
+ Layout.alignment: Qt.AlignLeft
+
+ text: qsTr("Register public username")
+ font.pointSize: 10
+ font.kerning: true
+
+ indicator.implicitWidth: 20
+ indicator.implicitHeight:20
+
+ onClicked: {
+ if (!checked) {
+ usernameEdit.clear()
+ }
+
+ validateWizardProgressionCreateAccountPage()
+ }
+ }
+ }
+
+ RowLayout {
+ spacing: 6
+ Layout.fillWidth: true
+
+ Layout.leftMargin: 32
+
+ InfoLineEdit {
+ id: usernameEdit
+
+ fieldLayoutWidth: 261
+
+ Layout.alignment: Qt.AlignHCenter
+
+ selectByMouse: true
+ placeholderText: qsTr("Choose your username")
+ font.pointSize: 10
+ font.kerning: true
+
+ enabled: signUpCheckbox.visible && signUpCheckbox.checked
+ }
+
+ LookupStatusLabel{
+ id: lookupStatusLabel
+
+ visible: true
+
+ lookupStatusState: {
+ switch (nameRegistrationUIState) {
+ case WizardView.BLANK:
+ return "Blank"
+ case WizardView.INVALID:
+ return "Invalid"
+ case WizardView.TAKEN:
+ return "Taken"
+ case WizardView.FREE:
+ return "Free"
+ case WizardView.SEARCHING:
+ return "Searching"
+ default:
+ return "Blank"
+ }
+ }
+ }
+ }
+
+ ColumnLayout {
+ Layout.fillWidth: true
+ spacing: 6
+
+ CheckBox {
+ id: choosePasswordCheckBox
+ checked: false
+
+ indicator.width: 10
+ indicator.height: 10
+
+ Layout.leftMargin: 32
+
+ Layout.minimumWidth: 261
+
+ Layout.preferredHeight: 30
+ Layout.minimumHeight: 25
+
+ indicator.implicitWidth: 20
+ indicator.implicitHeight:20
+
+ Layout.alignment: Qt.AlignLeft
+
+ text: qsTr("Choose a password for enhanced security")
+ font.pointSize: 8
+ font.kerning: true
+
+ onClicked: {
+ if (!checked) {
+ collapsiblePasswordWidget.clearAllTextFields()
+ }
+
+ validateWizardProgressionCreateAccountPage()
+ }
+ }
+
+ CollapsiblePasswordWidget {
+ id: collapsiblePasswordWidget
+
+ Layout.alignment: Qt.AlignHCenter
+
+ visibleCollapsble: choosePasswordCheckBox.checked
+ && choosePasswordCheckBox.visible
+ }
+ }
+
+ Item {
+ Layout.maximumWidth: 261
+ Layout.preferredWidth: 261
+ Layout.minimumWidth: 261
+
+ Layout.maximumHeight: 30
+ Layout.preferredHeight: 30
+ Layout.minimumHeight: 30
+
+ Layout.alignment: Qt.AlignHCenter
+ }
+ }
+}
diff --git a/src/wizardview/components/CreateSIPAccountPage.qml b/src/wizardview/components/CreateSIPAccountPage.qml
new file mode 100644
index 0000000..3f3da17
--- /dev/null
+++ b/src/wizardview/components/CreateSIPAccountPage.qml
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * 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 3 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, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+
+import "../../constant"
+import "../../commoncomponents"
+
+ColumnLayout {
+ property alias text_sipFullNameEditAlias: sipFullNameEdit.text
+ property alias text_sipServernameEditAlias: sipServernameEdit.text
+ property alias text_sipProxyEditAlias: sipProxyEdit.text
+ property alias text_sipUsernameEditAlias: sipUsernameEdit.text
+ property alias text_sipPasswordEditAlias: sipPasswordEdit.text
+
+ property alias boothImgBase64: setSIPAvatarWidget.imgBase64
+
+ function initializeOnShowUp() {
+ clearAllTextFields()
+ }
+
+ function clearAllTextFields() {
+ sipUsernameEdit.clear()
+ sipPasswordEdit.clear()
+ sipServernameEdit.clear()
+ sipProxyEdit.clear()
+ sipFullNameEdit.clear()
+ sipUsernameEdit.clear()
+ }
+
+ function startBooth(){
+ setSIPAvatarWidget.startBooth()
+ }
+
+ function stopBooth(){
+ setSIPAvatarWidget.stopBooth()
+ }
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ spacing: 6
+
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+
+ Label {
+ id: sipProfileSectionLabel
+
+ Layout.maximumWidth: 368
+ Layout.preferredWidth: 368
+ Layout.maximumHeight: 21
+ Layout.preferredHeight: 21
+
+ Layout.alignment: Qt.AlignHCenter
+
+ text: qsTr("Profile")
+ font.pointSize: 13
+ font.kerning: true
+
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+
+ PhotoboothView{
+ id: setSIPAvatarWidget
+
+ Layout.alignment: Qt.AlignHCenter
+
+ Layout.maximumWidth: 261
+ Layout.preferredWidth: 261
+ Layout.minimumWidth: 261
+ Layout.maximumHeight: 261
+ Layout.preferredHeight: 261
+ Layout.minimumHeight: 261
+ }
+
+ RowLayout {
+ spacing: 0
+ Layout.alignment: Qt.AlignHCenter
+ Layout.maximumHeight: 30
+
+ Item {
+ Layout.fillWidth: true
+ Layout.maximumHeight: 10
+ }
+
+ InfoLineEdit {
+ id: sipFullNameEdit
+
+ fieldLayoutWidth : 261
+ Layout.alignment: Qt.AlignCenter
+ selectByMouse: true
+ placeholderText: qsTr("Profile name")
+ font.pointSize: 10
+ font.kerning: true
+ }
+
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+ }
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+
+ Label {
+ id: sipAccountSectionLabel
+ Layout.maximumWidth: 368
+ Layout.preferredWidth: 368
+ Layout.maximumHeight: 21
+ Layout.preferredHeight: 21
+
+ Layout.alignment: Qt.AlignHCenter
+
+ text: qsTr("SIP Account")
+ font.pointSize: 12
+ font.kerning: true
+
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+
+ ColumnLayout {
+ Layout.alignment: Qt.AlignHCenter
+ spacing: 7
+
+ Item {
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignHCenter
+ Layout.maximumHeight: 40
+ Layout.minimumHeight: 30
+ Layout.preferredHeight: 40
+ }
+
+ InfoLineEdit {
+ id: sipServernameEdit
+ Layout.alignment: Qt.AlignHCenter
+ fieldLayoutWidth: 261
+
+ selectByMouse: true
+ placeholderText: qsTr("Server")
+ font.pointSize: 10
+ font.kerning: true
+ }
+
+ InfoLineEdit {
+ id: sipProxyEdit
+ Layout.alignment: Qt.AlignHCenter
+ fieldLayoutWidth: 261
+
+ selectByMouse: true
+ placeholderText: qsTr("Proxy")
+ font.pointSize: 10
+ font.kerning: true
+ }
+
+ InfoLineEdit {
+ id: sipUsernameEdit
+ Layout.alignment: Qt.AlignHCenter
+ fieldLayoutWidth: 261
+
+ selectByMouse: true
+ placeholderText: qsTr("Username")
+ font.pointSize: 10
+ font.kerning: true
+ }
+
+ InfoLineEdit {
+ id: sipPasswordEdit
+ Layout.alignment: Qt.AlignHCenter
+ fieldLayoutWidth: 261
+
+ selectByMouse: true
+ echoMode: TextInput.Password
+ placeholderText: qsTr("Password")
+ font.pointSize: 10
+ font.kerning: true
+ }
+ }
+}
diff --git a/src/wizardview/components/HoverableGradientButton.qml b/src/wizardview/components/HoverableGradientButton.qml
new file mode 100644
index 0000000..905bd41
--- /dev/null
+++ b/src/wizardview/components/HoverableGradientButton.qml
@@ -0,0 +1,142 @@
+
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
+ *
+ * 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 3 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, see <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.15
+import QtQuick.Controls 2.14
+import QtGraphicalEffects 1.15
+import net.jami.Models 1.0
+
+
+/*
+ * HoverableButton contains the following configurable properties:
+ * 1. Color changes on different button state
+ * 2. Radius control (rounded)
+ * 3. Text content or image content
+ * 4. Can use OnClicked slot to implement some click logic
+ */
+Button {
+ id: hoverableButton
+ property int fontPointSize: 9
+ property string backgroundColor: JamiTheme.releaseColor
+ property string backgroundColorDisabled : Qt.rgba(242/256, 242/256, 242/256, 0.8)
+
+ property string startColor :"#109ede"
+ property string endColor : "#2b5084"
+
+ property string startColorPressed :"#043161"
+ property string endColorPressed : "#00113f"
+
+ property string startColorHovered :"#2b4b7e"
+ property string endColorHovered : "#001d4d"
+
+ property string onPressColor: JamiTheme.pressColor
+ property string onReleaseColor: backgroundColor
+ property string onEnterColor: JamiTheme.hoverColor
+ property string onExitColor: backgroundColor
+ property string textColor: "white"
+
+ property alias radius: hoverableButtonBackground.radius
+
+ property bool isHovering: false
+ property bool isBeingPressed: false
+
+ radius: height / 2
+ font.pointSize: fontPointSize
+ font.kerning: true
+ hoverEnabled: true
+
+ contentItem: Text {
+ text: hoverableButton.text
+ font: hoverableButton.font
+ opacity: enabled ? 1.0 : 0.3
+ color: enabled? textColor : "grey"
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ elide: Text.ElideRight
+ }
+
+ background: Rectangle {
+ id: hoverableButtonBackground
+ color: backgroundColor
+
+ MouseArea {
+ id: btnMouseArea
+ anchors.fill: hoverableButtonBackground
+ hoverEnabled: true
+ onPressed: {
+ hoverableButtonBackground.color = onPressColor
+ isBeingPressed = true
+ }
+ onReleased: {
+ hoverableButtonBackground.color = onReleaseColor
+ isBeingPressed = false
+ hoverableButton.clicked()
+ }
+ onEntered: {
+ hoverableButtonBackground.color = onEnterColor
+ isHovering = true
+ }
+ onExited: {
+ hoverableButtonBackground.color = onExitColor
+ isHovering = false
+ }
+ }
+ }
+
+ LinearGradient {
+ id: backgroundGradient
+
+ source: hoverableButtonBackground
+ anchors.fill: hoverableButtonBackground
+ start: Qt.point(0, 0)
+ end: Qt.point(width, 0)
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: {
+ if(!hoverableButton.enabled){
+ return backgroundColorDisabled
+ }
+
+ if(isBeingPressed){
+ return startColorPressed
+ } else {
+ if(isHovering){
+ return startColorHovered
+ } else {
+ return startColor
+ }
+ }
+ } }
+
+ GradientStop { position: 1.0; color: {
+ if(!hoverableButton.enabled){
+ return backgroundColorDisabled
+ }
+
+ if(isBeingPressed){
+ return endColorPressed
+ } else {
+ if(isHovering){
+ return endColorHovered
+ } else {
+ return endColor
+ }
+ }
+ } }
+ }
+ }
+}
diff --git a/src/wizardview/components/ImportFromBackupPage.qml b/src/wizardview/components/ImportFromBackupPage.qml
new file mode 100644
index 0000000..bd7d26e
--- /dev/null
+++ b/src/wizardview/components/ImportFromBackupPage.qml
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * 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 3 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, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+import Qt.labs.platform 1.1
+
+import "../../constant"
+import "../../commoncomponents"
+
+ColumnLayout {
+ property alias text_passwordFromBackupEditAlias: passwordFromBackupEdit.text
+ property string fileImportBtnText: qsTr("Archive(none)")
+
+ signal importFromFile_Dialog_Accepted(string fileDir)
+
+ function clearAllTextFields() {
+ passwordFromBackupEdit.clear()
+ fileImportBtnText = qsTr("Archive(none)")
+ }
+
+ JamiFileDialog {
+ id: importFromFile_Dialog
+
+ mode: JamiFileDialog.OpenFile
+ title: qsTr("Open File")
+ folder: StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/Desktop"
+
+ nameFilters: [qsTr("Jami archive files") + " (*.gz)", qsTr(
+ "All files") + " (*)"]
+
+ onAccepted: {
+ importFromFile_Dialog_Accepted(file)
+ }
+ }
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ Item {
+ Layout.alignment: Qt.AlignHCenter
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+
+ ColumnLayout {
+ Layout.alignment: Qt.AlignCenter
+ Layout.maximumWidth: 366
+
+ spacing: 12
+
+ RowLayout {
+ Layout.fillWidth: true
+ Layout.maximumHeight: 24
+ spacing: 0
+
+ Item {
+ Layout.alignment: Qt.AlignVCenter
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+
+ Label {
+ id: importFromBackupLabel
+ Layout.minimumHeight: 24
+ Layout.minimumWidth: 234
+ text: qsTr("Import from backup")
+ font.pointSize: 13
+ font.kerning: true
+ horizontalAlignment: Qt.AlignLeft
+ verticalAlignment: Qt.AlignVCenter
+ }
+
+ HoverableRadiusButton {
+ id: backupInfoBtn
+
+ buttonImageHeight: height
+ buttonImageWidth: width
+
+ Layout.alignment: Qt.AlignVCenter
+ Layout.minimumWidth: 24
+ Layout.preferredWidth: 24
+ Layout.maximumWidth: 24
+
+ Layout.minimumHeight: 24
+ Layout.preferredHeight: 24
+ Layout.maximumHeight: 24
+
+ radius: height / 2
+ icon.source: "/images/icons/info-24px.svg"
+ icon.height: 24
+ icon.width: 24
+
+ backgroundColor: JamiTheme.releaseColor
+ onClicked: {
+ backupInfoLabel.visible = !backupInfoLabel.visible
+ }
+ }
+ Item {
+ Layout.alignment: Qt.AlignVCenter
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+ }
+
+ HoverableGradientButton {
+ id: fileImportBtn
+
+ Layout.alignment: Qt.AlignHCenter
+ Layout.maximumWidth: 256
+ Layout.preferredWidth: 256
+
+ Layout.maximumHeight: 30
+ Layout.preferredHeight: 30
+ Layout.minimumHeight: 30
+
+ text: fileImportBtnText
+ font.pointSize: 10
+ font.kerning: true
+
+ radius: height / 2
+ backgroundColor: JamiTheme.releaseColor
+
+ onClicked: {
+ importFromFile_Dialog.open()
+ }
+ }
+
+ InfoLineEdit {
+ id: passwordFromBackupEdit
+
+ Layout.alignment: Qt.AlignHCenter
+
+ selectByMouse: true
+ echoMode: TextInput.Password
+ placeholderText: qsTr("Password")
+ }
+
+ Label {
+ id: backupInfoLabel
+
+ Layout.alignment: Qt.AlignHCenter
+ Layout.maximumWidth: 366
+ Layout.preferredWidth: 366
+
+ text: qsTr("You can obtain an archive by clicking on \"Export account\" in the account settings. This will create a .gz file on your device.")
+ wrapMode: Text.WordWrap
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+
+ visible: false
+ }
+ }
+
+ Item {
+ Layout.alignment: Qt.AlignHCenter
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+}
diff --git a/src/wizardview/components/ImportFromDevicePage.qml b/src/wizardview/components/ImportFromDevicePage.qml
new file mode 100644
index 0000000..5181635
--- /dev/null
+++ b/src/wizardview/components/ImportFromDevicePage.qml
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * 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 3 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, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+
+import "../../constant"
+import "../../commoncomponents"
+
+ColumnLayout {
+ property alias text_pinFromDeviceAlias: pinFromDevice.text
+ property alias text_passwordFromDeviceAlias: passwordFromDevice.text
+
+ function initializeOnShowUp() {
+ clearAllTextFields()
+ }
+
+ function clearAllTextFields() {
+ pinFromDevice.clear()
+ passwordFromDevice.clear()
+ }
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ Item {
+ Layout.alignment: Qt.AlignHCenter
+ Layout.preferredHeight: 40
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+
+ ColumnLayout {
+ Layout.alignment: Qt.AlignCenter
+ Layout.fillWidth: true
+
+ spacing: 12
+
+ RowLayout {
+ Layout.fillWidth: true
+ Layout.maximumHeight: 24
+ spacing: 0
+
+ Item {
+ Layout.alignment: Qt.AlignVCenter
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+
+ Label {
+ id: importFromDeviceLabel
+ Layout.minimumHeight: 24
+ Layout.minimumWidth: 234
+ text: qsTr("Import from device")
+ font.pointSize: 13
+ font.kerning: true
+ }
+
+ HoverableRadiusButton {
+ id: pinInfoBtn
+
+ buttonImageHeight: height
+ buttonImageWidth: width
+
+ Layout.alignment: Qt.AlignVCenter
+ Layout.minimumWidth: 24
+ Layout.maximumWidth: 24
+ Layout.minimumHeight: 24
+ Layout.maximumHeight: 24
+
+ radius: height / 2
+ icon.source: "/images/icons/info-24px.svg"
+ backgroundColor: JamiTheme.releaseColor
+
+ onClicked: {
+ pinInfoLabel.visible = !pinInfoLabel.visible
+ }
+ }
+ Item {
+ Layout.alignment: Qt.AlignVCenter
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+ }
+ InfoLineEdit {
+ id: pinFromDevice
+
+ Layout.alignment: Qt.AlignHCenter
+
+ selectByMouse: true
+ placeholderText: qsTr("PIN")
+ }
+
+ InfoLineEdit {
+ id: passwordFromDevice
+
+ Layout.alignment: Qt.AlignHCenter
+
+ selectByMouse: true
+ echoMode: TextInput.Password
+ placeholderText: qsTr("Password")
+ }
+
+ Label {
+ id: pinInfoLabel
+
+ Layout.alignment: Qt.AlignHCenter
+ Layout.minimumWidth: 256
+ Layout.maximumWidth: 256
+
+ text: qsTr("To obtain a PIN (valid for 10 minutes), you need to open the account settings on the other device and click on \"Link to another device\".")
+ wrapMode: Text.WordWrap
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+
+ visible: false
+ }
+ }
+
+ Item {
+ Layout.alignment: Qt.AlignHCenter
+ Layout.preferredHeight: 40
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+}
diff --git a/src/wizardview/components/SpinnerPage.qml b/src/wizardview/components/SpinnerPage.qml
new file mode 100644
index 0000000..2fb3f8d
--- /dev/null
+++ b/src/wizardview/components/SpinnerPage.qml
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * 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 3 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, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+
+import "../../constant"
+
+ColumnLayout {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ spacing: 6
+
+ property bool successState: true
+ property string progressLabelEditText: "Generating your Jami account"
+
+ Item {
+ Layout.alignment: Qt.AlignHCenter
+ Layout.preferredHeight: 40
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+ Label {
+ id: spinnerLabel
+ Layout.alignment: Qt.AlignHCenter
+ Layout.minimumWidth: 200
+ Layout.minimumHeight: 200
+
+ Layout.maximumWidth: 16777215
+ Layout.maximumHeight: 16777215
+
+ property string spinnerDisplyState: successState ? "spinnerLabel_Regular" : "spinnerLabel_Failure"
+ onSpinnerDisplyStateChanged: {
+ switch (spinnerDisplyState) {
+ case "spinnerLabel_Regular":
+ background = Qt.createQmlObject("import QtQuick 2.14;
+AnimatedImage {
+source: \"qrc:/images/jami_eclipse_spinner.gif\"
+
+playing: true
+paused: false
+fillMode: Image.PreserveAspectFit
+mipmap: true
+}", spinnerLabel)
+ break
+ case "spinnerLabel_Failure":
+ background = Qt.createQmlObject("import QtQuick 2.14;
+import \"qrc:/src/constant/\";
+Image {
+anchors.fill: parent;
+source:\"image://tintedPixmap/\" + (\"qrc:/images/icons/baseline-error_outline-24px.svg\").replace(\"qrc:/images/icons/\", \"\") + \"+\" + JamiTheme.urgentOrange_;
+mipmap: true;}", spinnerLabel)
+ break
+ }
+ }
+ }
+ Item {
+ Layout.alignment: Qt.AlignHCenter
+ Layout.preferredHeight: 40
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+ Label {
+ id: progressLabel
+ Layout.alignment: Qt.AlignHCenter
+ text: successState ? progressLabelEditText : "Error creating account"
+ font.pointSize: 11
+ font.kerning: true
+
+ property string progressLabelState: successState ? "color_success" : "color_fail"
+ onProgressLabelStateChanged: {
+ switch (progressLabelState) {
+ case "color_success":
+ background = Qt.createQmlObject(
+ "import QtQuick 2.14; Rectangle { anchors.fill: parent; color: \"transparent\"; }",
+ progressLabel)
+ break
+ case "color_fail":
+ background = Qt.createQmlObject(
+ "import QtQuick 2.14; Rectangle { anchors.fill: parent; color: \"red\"; }",
+ progressLabel)
+ break
+ }
+ }
+ }
+ Item {
+ Layout.alignment: Qt.AlignHCenter
+ Layout.minimumHeight: 20
+ Layout.maximumHeight: 20
+ Layout.preferredHeight: 20
+ Layout.fillWidth: true
+ Layout.fillHeight: false
+ }
+}
diff --git a/src/wizardview/components/WelcomePageLayout.qml b/src/wizardview/components/WelcomePageLayout.qml
new file mode 100644
index 0000000..3c7190b
--- /dev/null
+++ b/src/wizardview/components/WelcomePageLayout.qml
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * 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 3 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, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+
+import "../../constant"
+import "../../commoncomponents"
+
+ColumnLayout {
+ property alias connectAccountManagerButtonAlias: connectAccountManagerButton
+ property alias newSIPAccountButtonAlias: newSIPAccountButton
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ spacing: 6
+
+ signal welcomePageRedirectPage(int toPageIndex)
+
+ Item {
+ // put a spacer to make the buttons closs to the middle
+ Layout.minimumHeight: 57
+ Layout.maximumHeight: 57
+ Layout.preferredHeight: 57
+ Layout.fillWidth: true
+ }
+ RowLayout {
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignHCenter
+ Label {
+ id: welcomeLabel
+ Layout.maximumHeight: 40
+ Layout.alignment: Qt.AlignCenter
+ text: qsTr("Welcome to")
+ font.pointSize: 30
+ font.kerning: true
+ }
+ }
+ Item {
+ Layout.minimumHeight: 17
+ Layout.maximumHeight: 17
+ Layout.preferredHeight: 17
+ Layout.fillWidth: true
+ }
+
+ RowLayout {
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignHCenter
+ Label {
+ id: welcomeLogo
+ Layout.alignment: Qt.AlignCenter
+ Layout.minimumWidth: 100
+ Layout.minimumHeight: 100
+ Layout.maximumWidth: 16777215
+ Layout.maximumHeight: 16777215
+ Layout.preferredWidth: 300
+ Layout.preferredHeight: 150
+ color: "transparent"
+ background: Image {
+ id: logoIMG
+ source: "qrc:/images/logo-jami-standard-coul.png"
+ fillMode: Image.PreserveAspectFit
+ mipmap: true
+ }
+ }
+ }
+ Item {
+ // put a spacer to make the buttons closs to the middle
+ Layout.preferredHeight: 57
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+ RowLayout {
+ spacing: 6
+ Layout.fillWidth: true
+ Layout.maximumHeight: 30
+ Layout.alignment: Qt.AlignHCenter
+ HoverableGradientButton {
+ id: newAccountButton
+
+ Layout.alignment: Qt.AlignCenter
+ Layout.preferredWidth: 256
+ Layout.preferredHeight: 30
+ text: qsTr("Create local account")
+ font.pointSize: 10
+ font.kerning: true
+ radius: height / 2
+
+ onClicked: {
+ welcomePageRedirectPage(1)
+ }
+ }
+ }
+ RowLayout {
+ spacing: 6
+ Layout.fillWidth: true
+
+ Layout.maximumHeight: 30
+ Layout.alignment: Qt.AlignHCenter
+ HoverableGradientButton {
+ id: fromDeviceButton
+ Layout.alignment: Qt.AlignCenter
+ Layout.preferredWidth: 256
+ Layout.preferredHeight: 30
+ text: qsTr("Import from device")
+ font.pointSize: 10
+ font.kerning: true
+
+ backgroundColor: JamiTheme.releaseColor
+ radius: height / 2
+
+ onClicked: {
+ welcomePageRedirectPage(5)
+ }
+ }
+ }
+ RowLayout {
+ spacing: 6
+ Layout.fillWidth: true
+
+ Layout.maximumHeight: 30
+ Layout.alignment: Qt.AlignHCenter
+ HoverableGradientButton {
+ id: fromBackupButton
+ Layout.alignment: Qt.AlignCenter
+ Layout.preferredWidth: 256
+ Layout.preferredHeight: 30
+ text: qsTr("Import from backup")
+ font.pointSize: 10
+ font.kerning: true
+
+ backgroundColor: JamiTheme.releaseColor
+ radius: height / 2
+
+ onClicked: {
+ welcomePageRedirectPage(3)
+ }
+ }
+ }
+ RowLayout {
+ spacing: 6
+ Layout.fillWidth: true
+
+ Layout.maximumHeight: 30
+ Layout.alignment: Qt.AlignHCenter
+ Button {
+ id: showAdvancedButton
+ Layout.preferredWidth: 256
+ Layout.preferredHeight: 30
+ Layout.alignment: Qt.AlignCenter
+ text: qsTr("Show Advanced")
+ font.pointSize: 8
+ font.kerning: true
+
+ background: Rectangle{
+ anchors.fill: parent
+
+ color: "transparent"
+ radius: height /2
+ }
+
+ onClicked: {
+ connectAccountManagerButton.visible = !connectAccountManagerButton.visible
+ newSIPAccountButton.visible = !newSIPAccountButton.visible
+ }
+ }
+ }
+ RowLayout {
+ spacing: 6
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignHCenter
+
+ Layout.maximumHeight: 30
+ HoverableGradientButton {
+ id: connectAccountManagerButton
+ Layout.preferredWidth: 256
+ Layout.preferredHeight: 30
+ Layout.alignment: Qt.AlignCenter
+ text: qsTr("Connect to account manager")
+ visible: false
+ font.pointSize: 10
+ font.kerning: true
+
+ backgroundColor: JamiTheme.releaseColor
+ radius: height / 2
+
+ onClicked: {
+ welcomePageRedirectPage(6)
+ }
+ }
+ }
+ RowLayout {
+ spacing: 6
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignHCenter
+ Layout.maximumHeight: 30
+
+ HoverableGradientButton {
+ id: newSIPAccountButton
+ Layout.preferredWidth: 256
+ Layout.preferredHeight: 30
+ Layout.alignment: Qt.AlignCenter
+ text: qsTr("Add a new SIP account")
+ visible: false
+ font.pointSize: 10
+ font.kerning: true
+
+ radius: height / 2
+ backgroundColor: JamiTheme.releaseColor
+
+ onClicked: {
+ welcomePageRedirectPage(2)
+ }
+ }
+ }
+ Item {
+ // put a spacer to make the buttons closs to the middle
+ Layout.fillHeight: true
+ Layout.preferredHeight: 65
+ Layout.fillWidth: true
+ }
+}