From 1440eab5bf8e49b0593d9e68502cbd3e5b7aaafa Mon Sep 17 00:00:00 2001 From: Sander van Grieken Date: Thu, 27 Jul 2023 00:04:50 +0200 Subject: [PATCH] qt wizardcomponent receives qeabstractwizard instance --- electrum/gui/qt/wizard/server_connect.py | 27 ++++++----- electrum/gui/qt/wizard/wizard.py | 58 +++++++++++++++++------- 2 files changed, 57 insertions(+), 28 deletions(-) diff --git a/electrum/gui/qt/wizard/server_connect.py b/electrum/gui/qt/wizard/server_connect.py index bd637a244..949281e76 100644 --- a/electrum/gui/qt/wizard/server_connect.py +++ b/electrum/gui/qt/wizard/server_connect.py @@ -4,8 +4,8 @@ from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget from electrum.i18n import _ from .wizard import QEAbstractWizard, WizardComponent from electrum.logging import get_logger -from electrum import mnemonic from electrum.wizard import ServerConnectWizard +from ..network_dialog import ProxyWidget, ServerWidget from ..util import ChoicesLayout @@ -26,8 +26,8 @@ class QEServerConnectWizard(ServerConnectWizard, QEAbstractWizard): class WCAutoConnect(WizardComponent): - def __init__(self, parent=None): - WizardComponent.__init__(self, parent, title=_("How do you want to connect to a server? ")) + def __init__(self, parent, wizard): + WizardComponent.__init__(self, parent, wizard, title=_("How do you want to connect to a server? ")) message = _("Electrum communicates with remote servers to get " "information about your transactions and addresses. The " "servers all fulfill the same purpose only differing in " @@ -35,8 +35,7 @@ class WCAutoConnect(WizardComponent): "pick one at random. However if you prefer feel free to " "select a server manually.") choices = [_("Auto connect"), _("Select server manually")] - self.clayout = ChoicesLayout(message, choices) - self.clayout.group.buttonClicked.connect(self.on_updated) + self.clayout = ChoicesLayout(message, choices, on_clicked=self.on_updated) self.layout().addLayout(self.clayout.layout()) self._valid = True @@ -54,8 +53,8 @@ class WCAutoConnect(WizardComponent): class WCProxyAsk(WizardComponent): - def __init__(self, parent=None): - WizardComponent.__init__(self, parent, title=_("Proxy")) + def __init__(self, parent, wizard): + WizardComponent.__init__(self, parent, wizard, title=_("Proxy")) message = _("Do you use a local proxy service such as TOR to reach the internet?") choices = [_("Yes"), _("No")] self.clayout = ChoicesLayout(message, choices) @@ -67,16 +66,22 @@ class WCProxyAsk(WizardComponent): class WCProxyConfig(WizardComponent): - def __init__(self, parent=None): - WizardComponent.__init__(self, parent, title=_("Proxy")) + def __init__(self, parent, wizard): + WizardComponent.__init__(self, parent, wizard, title=_("Proxy")) + pw = ProxyWidget(self) + self.layout().addWidget(pw) def apply(self): + # TODO pass class WCServerConfig(WizardComponent): - def __init__(self, parent=None): - WizardComponent.__init__(self, parent, title=_("Server")) + def __init__(self, parent, wizard): + WizardComponent.__init__(self, parent, wizard, title=_("Server")) + sw = ServerWidget(self) + self.layout().addWidget(sw) def apply(self): + # TODO pass diff --git a/electrum/gui/qt/wizard/wizard.py b/electrum/gui/qt/wizard/wizard.py index 80e398731..d29d8314e 100644 --- a/electrum/gui/qt/wizard/wizard.py +++ b/electrum/gui/qt/wizard/wizard.py @@ -1,6 +1,7 @@ from abc import abstractmethod +from typing import Dict, Any -from PyQt5.QtCore import Qt, QVariant, QTimer, pyqtSignal, pyqtSlot +from PyQt5.QtCore import Qt, QTimer, pyqtSignal, pyqtSlot from PyQt5.QtGui import QPixmap from PyQt5.QtWidgets import (QDialog, QApplication, QPushButton, QWidget, QLabel, QVBoxLayout, QScrollArea, QHBoxLayout, QLayout, QStackedWidget) @@ -77,18 +78,22 @@ class QEAbstractWizard(QDialog): def load_next_component(self, view, wdata={}): comp = self.view_to_component(view) - page = comp(self.main_widget) + page = comp(self.main_widget, self) page.wizard_data = wdata + page.config = self.config page.updated.connect(self.on_page_updated) self._logger.debug(f'{page!r}') + + # add to stack and update wizard self.main_widget.setCurrentIndex(self.main_widget.addWidget(page)) page.apply() - self.update(page.wizard_data) + self.update() @pyqtSlot(object) def on_page_updated(self, page): page.apply() - self.update(page.wizard_data) + if page == self.main_widget.currentWidget(): + self.update() def set_icon(self, filename): prior_filename, self.icon_filename = self.icon_filename, filename @@ -96,25 +101,30 @@ class QEAbstractWizard(QDialog): .scaledToWidth(60, mode=Qt.SmoothTransformation)) return prior_filename - def can_go_back(self): + def can_go_back(self) -> bool: return len(self._stack) > 0 - def update(self, wdata: dict): + def update(self): + page = self.main_widget.currentWidget() + self.title.setText(page.title) self.back_button.setText(_('Back') if self.can_go_back() else _('Cancel')) - self.next_button.setText(_('Next') if not self.is_last(wdata) else _('Finish')) + self.next_button.setText(_('Next') if not self.is_last(page.wizard_data) else _('Finish')) + self.next_button.setEnabled(page.valid) + self.main_widget.setVisible(not page.busy) + self.please_wait.setVisible(page.busy) def on_back_button_clicked(self): if self.can_go_back(): - wdata = self.prev() + self.prev() self.main_widget.removeWidget(self.main_widget.currentWidget()) - self.update(wdata) + self.update() else: self.close() def on_next_button_clicked(self): - wc = self.main_widget.currentWidget() - wc.apply() - wd = wc.wizard_data.copy() + page = self.main_widget.currentWidget() + page.apply() + wd = page.wizard_data.copy() if self.is_last(wd): self.finished(wd) self.close() @@ -131,7 +141,6 @@ class QEAbstractWizard(QDialog): def submit(self, wizard_data) -> dict: wdata = wizard_data.copy() - self.log_state(wdata) view = self.resolve_next(self._current.view, wdata) return { 'view': view.view, @@ -147,23 +156,38 @@ class QEAbstractWizard(QDialog): return self.is_last_view(self._current.view, wdata) -### support classes - - class WizardComponent(QWidget): updated = pyqtSignal(object) - def __init__(self, parent: QWidget = None, *, title: str = None, layout: QLayout = None): + def __init__(self, parent: QWidget, wizard: QEAbstractWizard, *, title: str = None, layout: QLayout = None): super().__init__(parent) self.setLayout(layout if layout else QVBoxLayout(self)) self.wizard_data = {} self.title = title if title is not None else 'No title' + self.wizard = wizard self._valid = False + self._busy = False @property def valid(self): return self._valid + @valid.setter + def valid(self, is_valid): + if self._valid != is_valid: + self._valid = is_valid + self.on_updated() + + @property + def busy(self): + return self._busy + + @busy.setter + def busy(self, is_busy): + if self._busy != is_busy: + self._busy = is_busy + self.on_updated() + @abstractmethod def apply(self): pass