mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-08-23 17:47:31 +00:00
qt wizard: make "GoBack" unroll the call stack to avoid stack overflow
fixes #6069
This commit is contained in:
parent
aa32e31a3d
commit
f13f46c555
2 changed files with 30 additions and 19 deletions
|
@ -113,18 +113,21 @@ class BaseWizard(Logger):
|
||||||
def can_go_back(self):
|
def can_go_back(self):
|
||||||
return len(self._stack) > 1
|
return len(self._stack) > 1
|
||||||
|
|
||||||
def go_back(self):
|
def go_back(self, *, rerun_previous: bool = True) -> None:
|
||||||
if not self.can_go_back():
|
if not self.can_go_back():
|
||||||
return
|
return
|
||||||
# pop 'current' frame
|
# pop 'current' frame
|
||||||
self._stack.pop()
|
self._stack.pop()
|
||||||
# pop 'previous' frame
|
prev_frame = self._stack[-1]
|
||||||
stack_item = self._stack.pop()
|
|
||||||
# try to undo side effects since we last entered 'previous' frame
|
# try to undo side effects since we last entered 'previous' frame
|
||||||
# FIXME only self.storage is properly restored
|
# FIXME only self.data is properly restored
|
||||||
self.data = copy.deepcopy(stack_item.db_data)
|
self.data = copy.deepcopy(prev_frame.db_data)
|
||||||
|
|
||||||
|
if rerun_previous:
|
||||||
|
# pop 'previous' frame
|
||||||
|
self._stack.pop()
|
||||||
# rerun 'previous' frame
|
# rerun 'previous' frame
|
||||||
self.run(stack_item.action, *stack_item.args, **stack_item.kwargs)
|
self.run(prev_frame.action, *prev_frame.args, **prev_frame.kwargs)
|
||||||
|
|
||||||
def reset_stack(self):
|
def reset_stack(self):
|
||||||
self._stack = []
|
self._stack = []
|
||||||
|
|
|
@ -96,19 +96,27 @@ def wizard_dialog(func):
|
||||||
def func_wrapper(*args, **kwargs):
|
def func_wrapper(*args, **kwargs):
|
||||||
run_next = kwargs['run_next']
|
run_next = kwargs['run_next']
|
||||||
wizard = args[0] # type: InstallWizard
|
wizard = args[0] # type: InstallWizard
|
||||||
|
while True:
|
||||||
wizard.back_button.setText(_('Back') if wizard.can_go_back() else _('Cancel'))
|
wizard.back_button.setText(_('Back') if wizard.can_go_back() else _('Cancel'))
|
||||||
|
# current dialog
|
||||||
try:
|
try:
|
||||||
out = func(*args, **kwargs)
|
out = func(*args, **kwargs)
|
||||||
if type(out) is not tuple:
|
if type(out) is not tuple:
|
||||||
out = (out,)
|
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)
|
run_next(*out)
|
||||||
except GoBack:
|
except GoBack:
|
||||||
if wizard.can_go_back():
|
# to go back from the next dialog, we ask the wizard to restore state
|
||||||
wizard.go_back()
|
wizard.go_back(rerun_previous=False)
|
||||||
return
|
# and we re-run the current dialog (by continuing)
|
||||||
else:
|
else:
|
||||||
wizard.close()
|
break
|
||||||
raise
|
|
||||||
return func_wrapper
|
return func_wrapper
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue