diff --git a/electrum/base_wizard.py b/electrum/base_wizard.py index a6f898ec4..77230839a 100644 --- a/electrum/base_wizard.py +++ b/electrum/base_wizard.py @@ -113,18 +113,21 @@ class BaseWizard(Logger): def can_go_back(self): return len(self._stack) > 1 - def go_back(self): + def go_back(self, *, rerun_previous: bool = True) -> None: if not self.can_go_back(): return # pop 'current' frame self._stack.pop() - # pop 'previous' frame - stack_item = self._stack.pop() + prev_frame = self._stack[-1] # try to undo side effects since we last entered 'previous' frame - # FIXME only self.storage is properly restored - self.data = copy.deepcopy(stack_item.db_data) - # rerun 'previous' frame - self.run(stack_item.action, *stack_item.args, **stack_item.kwargs) + # FIXME only self.data is properly restored + self.data = copy.deepcopy(prev_frame.db_data) + + if rerun_previous: + # pop 'previous' frame + self._stack.pop() + # rerun 'previous' frame + self.run(prev_frame.action, *prev_frame.args, **prev_frame.kwargs) def reset_stack(self): self._stack = [] diff --git a/electrum/gui/qt/installwizard.py b/electrum/gui/qt/installwizard.py index 5a1e8f683..762b931e7 100644 --- a/electrum/gui/qt/installwizard.py +++ b/electrum/gui/qt/installwizard.py @@ -96,19 +96,27 @@ def wizard_dialog(func): def func_wrapper(*args, **kwargs): run_next = kwargs['run_next'] wizard = args[0] # type: InstallWizard - wizard.back_button.setText(_('Back') if wizard.can_go_back() else _('Cancel')) - try: - out = func(*args, **kwargs) - if type(out) is not tuple: - out = (out,) - run_next(*out) - except GoBack: - if wizard.can_go_back(): - wizard.go_back() - return - else: - wizard.close() + while True: + wizard.back_button.setText(_('Back') if wizard.can_go_back() else _('Cancel')) + # current dialog + try: + out = func(*args, **kwargs) + if type(out) is not tuple: + out = (out,) + except GoBack: + if not wizard.can_go_back(): + wizard.close() + # to go back from the current dialog, we just let the caller unroll the stack: raise + # next dialog + try: + run_next(*out) + except GoBack: + # to go back from the next dialog, we ask the wizard to restore state + wizard.go_back(rerun_previous=False) + # and we re-run the current dialog (by continuing) + else: + break return func_wrapper