Merge pull request #9820 from f321x/qml_terms_of_use
qml: add terms of use to setup wizard
This commit is contained in:
24
electrum/gui/qml/components/TermsOfUseWizard.qml
Normal file
24
electrum/gui/qml/components/TermsOfUseWizard.qml
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -360,6 +360,14 @@ ApplicationWindow
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property alias termsOfUseWizard: _termsOfUseWizard
|
||||||
|
Component {
|
||||||
|
id: _termsOfUseWizard
|
||||||
|
TermsOfUseWizard {
|
||||||
|
onClosed: destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
property alias serverConnectWizard: _serverConnectWizard
|
property alias serverConnectWizard: _serverConnectWizard
|
||||||
Component {
|
Component {
|
||||||
id: _serverConnectWizard
|
id: _serverConnectWizard
|
||||||
@@ -517,38 +525,57 @@ ApplicationWindow
|
|||||||
app.scanDialog = _qtScanDialog
|
app.scanDialog = _qtScanDialog
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Config.autoConnectDefined) {
|
function continueWithServerConnection() {
|
||||||
var dialog = serverConnectWizard.createObject(app)
|
if (!Config.autoConnectDefined) {
|
||||||
// without completed serverConnectWizard we can't start
|
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() {
|
dialog.rejected.connect(function() {
|
||||||
app.visible = false
|
app.visible = false
|
||||||
AppController.wantClose = true
|
AppController.wantClose = true
|
||||||
Qt.callLater(Qt.quit)
|
Qt.callLater(Qt.quit)
|
||||||
})
|
})
|
||||||
dialog.accepted.connect(function() {
|
dialog.accepted.connect(function() {
|
||||||
Daemon.startNetwork()
|
Config.termsOfUseAccepted = true
|
||||||
var newww = app.newWalletWizard.createObject(app)
|
continueWithServerConnection()
|
||||||
newww.walletCreated.connect(function() {
|
|
||||||
Daemon.availableWallets.reload()
|
|
||||||
// and load the new wallet
|
|
||||||
Daemon.loadWallet(newww.path, newww.wizard_data['password'])
|
|
||||||
})
|
|
||||||
newww.open()
|
|
||||||
})
|
})
|
||||||
dialog.open()
|
dialog.open()
|
||||||
} else {
|
} else {
|
||||||
Daemon.startNetwork()
|
continueWithServerConnection()
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ WizardComponent {
|
|||||||
ProxyConfig {
|
ProxyConfig {
|
||||||
id: pc
|
id: pc
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
proxy_enabled: true
|
proxy_enabled: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
48
electrum/gui/qml/components/wizard/WCTermsOfUseRequest.qml
Normal file
48
electrum/gui/qml/components/wizard/WCTermsOfUseRequest.qml
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,41 +6,29 @@ import "../controls"
|
|||||||
|
|
||||||
WizardComponent {
|
WizardComponent {
|
||||||
valid: true
|
valid: true
|
||||||
wizard_title: qsTr('Electrum Bitcoin Wallet')
|
wizard_title: qsTr('Network Configuration')
|
||||||
|
|
||||||
function apply() {
|
function apply() {
|
||||||
wizard_data['use_defaults'] = !config_advanced.checked
|
wizard_data['use_defaults'] = !config_proxy.checked && !config_server.checked
|
||||||
wizard_data['want_proxy'] = config_advanced.checked && config_proxy.checked
|
wizard_data['want_proxy'] = config_proxy.checked
|
||||||
wizard_data['autoconnect'] = !config_server.checked || !config_advanced.checked
|
wizard_data['autoconnect'] = !config_server.checked
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
Image {
|
Label {
|
||||||
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
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
text: qsTr('Advanced network settings')
|
Layout.preferredWidth: parent.width
|
||||||
checked: false
|
text: qsTr("Optional settings to customize your network connection") + ":"
|
||||||
onCheckedChanged: checkIsLast()
|
wrapMode: Text.WordWrap
|
||||||
|
horizontalAlignment: Text.AlignHLeft
|
||||||
|
font.pixelSize: constants.fontSizeLarge
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.topMargin: 2*constants.paddingXLarge; Layout.bottomMargin: 2*constants.paddingXLarge
|
||||||
opacity: config_advanced.checked ? 1 : 0
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation { duration: 300 }
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckBox {
|
CheckBox {
|
||||||
id: config_proxy
|
id: config_proxy
|
||||||
@@ -55,5 +43,14 @@ WizardComponent {
|
|||||||
onCheckedChanged: checkIsLast()
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ from .qechannelopener import QEChannelOpener
|
|||||||
from .qelnpaymentdetails import QELnPaymentDetails
|
from .qelnpaymentdetails import QELnPaymentDetails
|
||||||
from .qechanneldetails import QEChannelDetails
|
from .qechanneldetails import QEChannelDetails
|
||||||
from .qeswaphelper import QESwapHelper
|
from .qeswaphelper import QESwapHelper
|
||||||
from .qewizard import QENewWalletWizard, QEServerConnectWizard
|
from .qewizard import QENewWalletWizard, QEServerConnectWizard, QETermsOfUseWizard
|
||||||
from .qemodelfilter import QEFilterProxyModel
|
from .qemodelfilter import QEFilterProxyModel
|
||||||
from .qebip39recovery import QEBip39RecoveryListModel
|
from .qebip39recovery import QEBip39RecoveryListModel
|
||||||
|
|
||||||
@@ -428,6 +428,7 @@ class ElectrumQmlApplication(QGuiApplication):
|
|||||||
# TODO QT6 order of declaration is important now?
|
# TODO QT6 order of declaration is important now?
|
||||||
qmlRegisterType(QEAmount, 'org.electrum', 1, 0, 'Amount')
|
qmlRegisterType(QEAmount, 'org.electrum', 1, 0, 'Amount')
|
||||||
qmlRegisterType(QENewWalletWizard, 'org.electrum', 1, 0, 'QNewWalletWizard')
|
qmlRegisterType(QENewWalletWizard, 'org.electrum', 1, 0, 'QNewWalletWizard')
|
||||||
|
qmlRegisterType(QETermsOfUseWizard, 'org.electrum', 1, 0, 'QTermsOfUseWizard')
|
||||||
qmlRegisterType(QEServerConnectWizard, 'org.electrum', 1, 0, 'QServerConnectWizard')
|
qmlRegisterType(QEServerConnectWizard, 'org.electrum', 1, 0, 'QServerConnectWizard')
|
||||||
qmlRegisterType(QEFilterProxyModel, 'org.electrum', 1, 0, 'FilterProxyModel')
|
qmlRegisterType(QEFilterProxyModel, 'org.electrum', 1, 0, 'FilterProxyModel')
|
||||||
qmlRegisterType(QSortFilterProxyModel, 'org.electrum', 1, 0, 'QSortFilterProxyModel')
|
qmlRegisterType(QSortFilterProxyModel, 'org.electrum', 1, 0, 'QSortFilterProxyModel')
|
||||||
|
|||||||
@@ -66,6 +66,19 @@ class QEConfig(AuthMixin, QObject):
|
|||||||
langs_sorted.insert(0, {'value': '', 'text': default})
|
langs_sorted.insert(0, {'value': '', 'text': default})
|
||||||
return langs_sorted
|
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()
|
autoConnectChanged = pyqtSignal()
|
||||||
@pyqtProperty(bool, notify=autoConnectChanged)
|
@pyqtProperty(bool, notify=autoConnectChanged)
|
||||||
def autoConnect(self):
|
def autoConnect(self):
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ from electrum.storage import StorageReadWriteError
|
|||||||
from .auth import AuthMixin, auth_protect
|
from .auth import AuthMixin, auth_protect
|
||||||
from .qefx import QEFX
|
from .qefx import QEFX
|
||||||
from .qewallet import QEWallet
|
from .qewallet import QEWallet
|
||||||
from .qewizard import QENewWalletWizard, QEServerConnectWizard
|
from .qewizard import QENewWalletWizard, QEServerConnectWizard, QETermsOfUseWizard
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from electrum.daemon import Daemon
|
from electrum.daemon import Daemon
|
||||||
@@ -128,6 +128,7 @@ class QEDaemon(AuthMixin, QObject):
|
|||||||
_available_wallets = None
|
_available_wallets = None
|
||||||
_current_wallet = None
|
_current_wallet = None
|
||||||
_new_wallet_wizard = None
|
_new_wallet_wizard = None
|
||||||
|
_terms_of_use_wizard = None
|
||||||
_server_connect_wizard = None
|
_server_connect_wizard = None
|
||||||
_path = None
|
_path = None
|
||||||
_name = None
|
_name = None
|
||||||
@@ -140,6 +141,7 @@ class QEDaemon(AuthMixin, QObject):
|
|||||||
availableWalletsChanged = pyqtSignal()
|
availableWalletsChanged = pyqtSignal()
|
||||||
fxChanged = pyqtSignal()
|
fxChanged = pyqtSignal()
|
||||||
newWalletWizardChanged = pyqtSignal()
|
newWalletWizardChanged = pyqtSignal()
|
||||||
|
termsOfUseWizardChanged = pyqtSignal()
|
||||||
serverConnectWizardChanged = pyqtSignal()
|
serverConnectWizardChanged = pyqtSignal()
|
||||||
loadingChanged = pyqtSignal()
|
loadingChanged = pyqtSignal()
|
||||||
requestNewPassword = pyqtSignal()
|
requestNewPassword = pyqtSignal()
|
||||||
@@ -365,6 +367,12 @@ class QEDaemon(AuthMixin, QObject):
|
|||||||
|
|
||||||
return self._server_connect_wizard
|
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()
|
@pyqtSlot()
|
||||||
def startNetwork(self):
|
def startNetwork(self):
|
||||||
self.daemon.start_network()
|
self.daemon.start_network()
|
||||||
|
|||||||
@@ -5,9 +5,10 @@ from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject
|
|||||||
|
|
||||||
from electrum.logging import get_logger
|
from electrum.logging import get_logger
|
||||||
from electrum import mnemonic
|
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.storage import WalletStorage, StorageReadWriteError
|
||||||
from electrum.util import WalletFileException
|
from electrum.util import WalletFileException
|
||||||
|
from electrum.gui import messages
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from electrum.gui.qml.qedaemon import QEDaemon
|
from electrum.gui.qml.qedaemon import QEDaemon
|
||||||
@@ -183,3 +184,19 @@ class QEServerConnectWizard(ServerConnectWizard, QEAbstractWizard):
|
|||||||
'proxy_config': {'gui': 'WCProxyConfig'},
|
'proxy_config': {'gui': 'WCProxyConfig'},
|
||||||
'server_config': {'gui': 'WCServerConfig'},
|
'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
|
||||||
|
|||||||
Reference in New Issue
Block a user