1
0

qml: add terms of use to setup wizard

This commit is contained in:
f321x
2025-05-12 13:42:41 +02:00
parent e54d57bf73
commit 38f51a3b13
8 changed files with 184 additions and 49 deletions

View File

@@ -0,0 +1,24 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import "wizard"
Wizard {
id: termsofusewizard
wizardTitle: ""
iconSource: ""
header: null
enter: null // disable transition
wiz: Daemon.termsOfUseWizard
finishButtonText: qsTr('Next')
Component.onCompleted: {
var view = wiz.startWizard()
_loadNextComponent(view)
}
}

View File

@@ -360,6 +360,14 @@ ApplicationWindow
}
}
property alias termsOfUseWizard: _termsOfUseWizard
Component {
id: _termsOfUseWizard
TermsOfUseWizard {
onClosed: destroy()
}
}
property alias serverConnectWizard: _serverConnectWizard
Component {
id: _serverConnectWizard
@@ -517,38 +525,57 @@ ApplicationWindow
app.scanDialog = _qtScanDialog
}
if (!Config.autoConnectDefined) {
var dialog = serverConnectWizard.createObject(app)
// without completed serverConnectWizard we can't start
function continueWithServerConnection() {
if (!Config.autoConnectDefined) {
var dialog = serverConnectWizard.createObject(app)
// without completed serverConnectWizard we can't start
dialog.rejected.connect(function() {
app.visible = false
AppController.wantClose = true
Qt.callLater(Qt.quit)
})
dialog.accepted.connect(function() {
Daemon.startNetwork()
var newww = app.newWalletWizard.createObject(app)
newww.walletCreated.connect(function() {
Daemon.availableWallets.reload()
// and load the new wallet
Daemon.loadWallet(newww.path, newww.wizard_data['password'])
})
newww.open()
})
dialog.open()
} else {
Daemon.startNetwork()
if (Daemon.availableWallets.rowCount() > 0) {
Daemon.loadWallet()
} else {
var newww = app.newWalletWizard.createObject(app)
newww.walletCreated.connect(function() {
Daemon.availableWallets.reload()
// and load the new wallet
Daemon.loadWallet(newww.path, newww.wizard_data['password'])
})
newww.open()
}
}
}
if (!Config.termsOfUseAccepted) {
var dialog = termsOfUseWizard.createObject(app)
dialog.rejected.connect(function() {
app.visible = false
AppController.wantClose = true
Qt.callLater(Qt.quit)
})
dialog.accepted.connect(function() {
Daemon.startNetwork()
var newww = app.newWalletWizard.createObject(app)
newww.walletCreated.connect(function() {
Daemon.availableWallets.reload()
// and load the new wallet
Daemon.loadWallet(newww.path, newww.wizard_data['password'])
})
newww.open()
Config.termsOfUseAccepted = true
continueWithServerConnection()
})
dialog.open()
} else {
Daemon.startNetwork()
if (Daemon.availableWallets.rowCount() > 0) {
Daemon.loadWallet()
} else {
var newww = app.newWalletWizard.createObject(app)
newww.walletCreated.connect(function() {
Daemon.availableWallets.reload()
// and load the new wallet
Daemon.loadWallet(newww.path, newww.wizard_data['password'])
})
newww.open()
}
continueWithServerConnection()
}
}

View File

@@ -0,0 +1,48 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import "../controls"
WizardComponent {
valid: true
last: true
Flickable {
anchors.fill: parent
contentHeight: mainLayout.height
clip: true
interactive: height < contentHeight
ColumnLayout {
id: mainLayout
width: parent.width
spacing: constants.paddingLarge
Image {
Layout.fillWidth: true
fillMode: Image.PreserveAspectFit
source: Qt.resolvedUrl('../../../icons/electrum_presplash.png')
// reduce spacing a bit
Layout.topMargin: -100
Layout.bottomMargin: -200
}
Label {
Layout.fillWidth: true
text: qsTr("Terms of Use")
font.pixelSize: constants.fontSizeLarge
font.bold: true
horizontalAlignment: Text.AlignHCenter
}
Label {
Layout.fillWidth: true
text: wiz.termsOfUseText
wrapMode: Text.WordWrap
font.pixelSize: constants.fontSizeMedium
padding: constants.paddingSmall
}
}
}
}

View File

@@ -6,41 +6,29 @@ import "../controls"
WizardComponent {
valid: true
wizard_title: qsTr('Electrum Bitcoin Wallet')
wizard_title: qsTr('Network Configuration')
function apply() {
wizard_data['use_defaults'] = !config_advanced.checked
wizard_data['want_proxy'] = config_advanced.checked && config_proxy.checked
wizard_data['autoconnect'] = !config_server.checked || !config_advanced.checked
wizard_data['use_defaults'] = !config_proxy.checked && !config_server.checked
wizard_data['want_proxy'] = config_proxy.checked
wizard_data['autoconnect'] = !config_server.checked
}
ColumnLayout {
width: parent.width
Image {
Layout.fillWidth: true
fillMode: Image.PreserveAspectFit
source: Qt.resolvedUrl('../../../icons/electrum_presplash.png')
// reduce spacing a bit
Layout.topMargin: -50
Layout.bottomMargin: -120
}
CheckBox {
id: config_advanced
Label {
Layout.alignment: Qt.AlignHCenter
text: qsTr('Advanced network settings')
checked: false
onCheckedChanged: checkIsLast()
Layout.preferredWidth: parent.width
text: qsTr("Optional settings to customize your network connection") + ":"
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHLeft
font.pixelSize: constants.fontSizeLarge
}
ColumnLayout {
Layout.alignment: Qt.AlignHCenter
opacity: config_advanced.checked ? 1 : 0
Behavior on opacity {
NumberAnimation { duration: 300 }
}
Layout.topMargin: 2*constants.paddingXLarge; Layout.bottomMargin: 2*constants.paddingXLarge
CheckBox {
id: config_proxy
@@ -55,5 +43,14 @@ WizardComponent {
onCheckedChanged: checkIsLast()
}
}
Label {
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: parent.width
text: qsTr("If you are unsure what this is, leave them unchecked and Electrum will automatically select servers.")
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHLeft
font.pixelSize: constants.fontSizeMedium
}
}
}

View File

@@ -41,7 +41,7 @@ from .qechannelopener import QEChannelOpener
from .qelnpaymentdetails import QELnPaymentDetails
from .qechanneldetails import QEChannelDetails
from .qeswaphelper import QESwapHelper
from .qewizard import QENewWalletWizard, QEServerConnectWizard
from .qewizard import QENewWalletWizard, QEServerConnectWizard, QETermsOfUseWizard
from .qemodelfilter import QEFilterProxyModel
from .qebip39recovery import QEBip39RecoveryListModel
@@ -428,6 +428,7 @@ class ElectrumQmlApplication(QGuiApplication):
# TODO QT6 order of declaration is important now?
qmlRegisterType(QEAmount, 'org.electrum', 1, 0, 'Amount')
qmlRegisterType(QENewWalletWizard, 'org.electrum', 1, 0, 'QNewWalletWizard')
qmlRegisterType(QETermsOfUseWizard, 'org.electrum', 1, 0, 'QTermsOfUseWizard')
qmlRegisterType(QEServerConnectWizard, 'org.electrum', 1, 0, 'QServerConnectWizard')
qmlRegisterType(QEFilterProxyModel, 'org.electrum', 1, 0, 'FilterProxyModel')
qmlRegisterType(QSortFilterProxyModel, 'org.electrum', 1, 0, 'QSortFilterProxyModel')

View File

@@ -66,6 +66,19 @@ class QEConfig(AuthMixin, QObject):
langs_sorted.insert(0, {'value': '', 'text': default})
return langs_sorted
termsOfUseChanged = pyqtSignal()
@pyqtProperty(bool, notify=termsOfUseChanged)
def termsOfUseAccepted(self) -> bool:
return self.config.TERMS_OF_USE_ACCEPTED >= messages.TERMS_OF_USE_LATEST_VERSION
@termsOfUseAccepted.setter
def termsOfUseAccepted(self, accepted: bool) -> None:
if accepted:
self.config.TERMS_OF_USE_ACCEPTED = messages.TERMS_OF_USE_LATEST_VERSION
else:
self.config.TERMS_OF_USE_ACCEPTED = 0
self.termsOfUseChanged.emit()
autoConnectChanged = pyqtSignal()
@pyqtProperty(bool, notify=autoConnectChanged)
def autoConnect(self):

View File

@@ -18,7 +18,7 @@ from electrum.storage import StorageReadWriteError
from .auth import AuthMixin, auth_protect
from .qefx import QEFX
from .qewallet import QEWallet
from .qewizard import QENewWalletWizard, QEServerConnectWizard
from .qewizard import QENewWalletWizard, QEServerConnectWizard, QETermsOfUseWizard
if TYPE_CHECKING:
from electrum.daemon import Daemon
@@ -128,6 +128,7 @@ class QEDaemon(AuthMixin, QObject):
_available_wallets = None
_current_wallet = None
_new_wallet_wizard = None
_terms_of_use_wizard = None
_server_connect_wizard = None
_path = None
_name = None
@@ -140,6 +141,7 @@ class QEDaemon(AuthMixin, QObject):
availableWalletsChanged = pyqtSignal()
fxChanged = pyqtSignal()
newWalletWizardChanged = pyqtSignal()
termsOfUseWizardChanged = pyqtSignal()
serverConnectWizardChanged = pyqtSignal()
loadingChanged = pyqtSignal()
requestNewPassword = pyqtSignal()
@@ -365,6 +367,12 @@ class QEDaemon(AuthMixin, QObject):
return self._server_connect_wizard
@pyqtProperty(QETermsOfUseWizard, notify=termsOfUseWizardChanged)
def termsOfUseWizard(self):
if not self._terms_of_use_wizard:
self._terms_of_use_wizard = QETermsOfUseWizard(self)
return self._terms_of_use_wizard
@pyqtSlot()
def startNetwork(self):
self.daemon.start_network()

View File

@@ -5,9 +5,10 @@ from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject
from electrum.logging import get_logger
from electrum import mnemonic
from electrum.wizard import NewWalletWizard, ServerConnectWizard
from electrum.wizard import NewWalletWizard, ServerConnectWizard, TermsOfUseWizard
from electrum.storage import WalletStorage, StorageReadWriteError
from electrum.util import WalletFileException
from electrum.gui import messages
if TYPE_CHECKING:
from electrum.gui.qml.qedaemon import QEDaemon
@@ -183,3 +184,19 @@ class QEServerConnectWizard(ServerConnectWizard, QEAbstractWizard):
'proxy_config': {'gui': 'WCProxyConfig'},
'server_config': {'gui': 'WCServerConfig'},
})
class QETermsOfUseWizard(TermsOfUseWizard, QEAbstractWizard):
def __init__(self, daemon: 'QEDaemon', parent=None):
TermsOfUseWizard.__init__(self, daemon.daemon.config)
QEAbstractWizard.__init__(self, parent)
# attach gui classes
self.navmap_merge({
'terms_of_use': {'gui': 'WCTermsOfUseRequest'},
})
termsOfUseChanged = pyqtSignal()
@pyqtProperty(str, notify=termsOfUseChanged)
def termsOfUseText(self):
return messages.MSG_TERMS_OF_USE