/* * This file is part of the Flowee project * Copyright (C) 2022-2026 Tom Zander * * 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 . */ import QtQuick import QtQuick.Controls.Basic as QQC2 import QtQuick.Layouts import "../Flowee" as Flowee import "../ControlColors.js" as ControlColors FocusScope { id: root property QtObject account: portfolio.current focus: true Flowee.Label { text: qsTr("Protect your wallet with a password") horizontalAlignment: Text.AlignHCenter font.pixelSize: description.font.pixelSize * 1.3 width: parent.width color: "white" } Flickable { id: contentArea anchors.fill: parent anchors.topMargin: 40 anchors.leftMargin: 10 anchors.rightMargin: 10 anchors.bottomMargin: 20 boundsBehavior: Flickable.StopAtBounds // don't show this is a flickable if there is no space issues contentWidth: width contentHeight: contentAreaColumn.height + 20 flickableDirection: Flickable.VerticalFlick clip: true QQC2.ScrollBar.vertical: QQC2.ScrollBar { } function encryptAndExit() { var account = root.account if (optionsRow.selectedKey == 0) account.encryptPinToPay(passwordField.text) if (optionsRow.selectedKey == 1) account.encryptPinToOpen(passwordField.text) passwordField.text = "" accountOverlay.state = "showTransactions" // should close this screen tabbar.currentIndex = 0 } Column { id: contentAreaColumn width: contentArea.width - 40 y: 25 x: 20 spacing: 20 Flow { id: optionsRow anchors.horizontalCenter: parent.horizontalCenter activeFocusOnTab: true focus: true spacing: 20 width: Math.min(contentArea.width - 30, 600) // smaller is OK, wider not property int selectorWidth: (width - spacing * 2) / 2 property int selectedKey: 0 function cardClicked(key) { if (selectedKey !== key) selectedKey = key else // move scroll area. contentArea.flick(0, -1000) } onSelectedKeyChanged: { pinToPay.checked = selectedKey === 0 pinToOpen.checked = selectedKey === 1 } Flowee.CardTypeSelector { id: pinToPay title: qsTr("Pin to Pay") width: parent.selectorWidth onClicked: parent.cardClicked(0) checkable: true checked: true features: [ qsTr("Protect your funds", "pin to pay"), qsTr("Fully open, except for sending funds", "pin to pay"), qsTr("Keeps in sync", "pin to pay"), ] } Flowee.CardTypeSelector { id: pinToOpen title: qsTr("Pin to Open") width: parent.selectorWidth onClicked: parent.cardClicked(1) checkable: true features: [ qsTr("Protect your entire wallet", "pin to open"), qsTr("Balance and history protected", "pin to open"), qsTr("Requires Pin to view, sync or pay", "pin to open"), ] } } Flowee.Label { id: description text: { var type = optionsRow.selectedKey if (type == 0) return qsTr("Make \"%1\" wallet require a pin to pay").arg(portfolio.current.name) return qsTr("Make \"%1\" wallet require a pin to open").arg(portfolio.current.name) } font.pointSize: 14 } StackLayout { id: stack currentIndex: optionsRow.selectedKey width: parent.width Flowee.Label { text: { if (root.account.needsPinToOpen) return qsTr("Wallet already has pin to open applied") if (root.account.needsPinToPay) return qsTr("Wallet already has pin to pay applied") return qsTr("Your wallet will get partially encrypted and payments will become impossible without a password. If you don't have a backup of this wallet, make one first.") } wrapMode: Text.WordWrap width: stack.width } Column { Flowee.Label { text: { if (root.account.needsPinToOpen) return qsTr("Wallet already has pin to open applied") return qsTr("Your full wallet gets encrypted, opening it will need a password. If you don't have a backup of this wallet, make one first.") } wrapMode: Text.WordWrap width: stack.width } Flowee.Label { visible: root.account.needsPinToPay && !root.account.needsPinToOpen text: "This wallet already has pin to pay applied, you may upgrade it to pin to open but it will remove pin to pay. The password you provide must be the same as the one for pin to pay" wrapMode: Text.WordWrap width: stack.width } } } GridLayout { visible: { if (root.account.needsPinToOpen) return false if (root.account.needsPinToPay) return optionsRow.selectedKey == 1 return true } width: parent.width columns: 2 Flowee.Label { text: qsTr("Password") + ":" onEnabledChanged: updateColors() Connections { target: Pay function onUseDarkSkinChanged() { updateColors() } } function updateColors() { ControlColors.applySkin(this) if (enabled) color = palette.text else color = Pay.useDarkSkin ? Qt.darker(palette.text) : Qt.lighter(palette.text, 2) } } Flowee.TextField { id: passwordField Layout.fillWidth: true echoMode: TextInput.Password onAccepted: encryptButton.clicked() } Flowee.Label { visible: !portfolio.singleAccountSetup text: qsTr("Wallet") + ":" } Flowee.Label { visible: !portfolio.singleAccountSetup text: root.account.name } Item { width: 1 height: 1 } Flowee.WarningLabel { Layout.fillWidth: true id: warningLabel } } Item { width: parent.width height: closeButton.height Flowee.Button { id: encryptButton enabled: passwordField.enabled && passwordField.text.length > 3 text: qsTr("Encrypt") anchors.right: closeButton.left anchors.rightMargin: 10 onClicked: { if (account.needsPinToPay) { var ok = account.decrypt(passwordField.text) if (!ok) { warningLabel.text = qsTr("Invalid password to open this wallet") return } contentArea.encryptAndExit() } else { passwdDialog.start() // on click, ask for the password again } } } Flowee.Button { id: closeButton text: qsTr("Close") anchors.right: parent.right onClicked: accountOverlay.state = "showTransactions" } } } } Flowee.CloseIcon { id: closeIcon anchors.right: parent.right anchors.margins: 6 onClicked: accountOverlay.state = "showTransactions" color: "#bbbbbb" } Flowee.PasswdDialog { id: passwdDialog title: qsTr("Repeat password") text: qsTr("Please confirm the password by entering it again") onAccepted: { if (pwd !== passwordField.text) { // mismatching entries. warningLabel.text = qsTr("Typed passwords do not match") return } contentArea.encryptAndExit() } } Keys.onPressed: (event)=> { if (event.key === Qt.Key_Escape) { accountOverlay.state = "showTransactions" event.accepted = true } else if (event.key === Qt.Key_Left && optionsRow.activeFocus) { if (optionsRow.selectedKey > 0) { optionsRow.selectedKey = Math.max(0, optionsRow.selectedKey - 1) event.accepted = true } } else if (event.key === Qt.Key_Right && optionsRow.activeFocus) { if (optionsRow.selectedKey < 1) { optionsRow.selectedKey = Math.min(1, optionsRow.selectedKey + 1) event.accepted = true } } } }