More cleanup of WaitingDialog

Simplify its interface
This commit is contained in:
Neil Booth 2015-12-26 11:18:32 +09:00
parent a58c19d7c0
commit 8f91af28a5
5 changed files with 52 additions and 67 deletions

View File

@ -1144,22 +1144,19 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
''' '''
def request_password(self, *args, **kwargs): def request_password(self, *args, **kwargs):
parent = kwargs.get('parent', self) parent = kwargs.get('parent', self)
if self.wallet.use_encryption: password = None
while True: while self.wallet.use_encryption:
password = self.password_dialog(parent=parent) password = self.password_dialog(parent=parent)
if not password: try:
return True, None if password:
try:
self.wallet.check_password(password) self.wallet.check_password(password)
break break
except Exception as e: except Exception as e:
self.show_error(str(e), parent=parent) self.show_error(str(e), parent=parent)
continue continue
else:
password = None
kwargs['password'] = password kwargs['password'] = password
return False, func(self, *args, **kwargs) return func(self, *args, **kwargs)
return request_password return request_password
def read_send_tab(self): def read_send_tab(self):
@ -1259,39 +1256,32 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
self.show_transaction(tx) self.show_transaction(tx)
self.do_clear() self.do_clear()
else: else:
self.broadcast_transaction(tx, tx_desc) self.broadcast_transaction(tx, tx_desc, self)
self.sign_tx_with_password(tx, sign_done, password) self.sign_tx_with_password(tx, sign_done, password, self)
@protected @protected
def sign_tx(self, tx, callback, password, parent=None): def sign_tx(self, tx, callback, password, parent):
self.sign_tx_with_password(tx, callback, password, parent) self.sign_tx_with_password(tx, callback, password, parent)
def sign_tx_with_password(self, tx, callback, password, parent=None): def sign_tx_with_password(self, tx, callback, password, parent):
'''Sign the transaction in a separate thread. When done, calls '''Sign the transaction in a separate thread. When done, calls
the callback with a success code of True or False. the callback with a success code of True or False.
''' '''
if parent == None: if self.wallet.use_encryption and not password:
parent = self callback(False) # User cancelled password input
self.send_button.setDisabled(True) return
# call hook to see if plugin needs gui interaction # call hook to see if plugin needs gui interaction
run_hook('sign_tx', parent, tx) run_hook('sign_tx', parent, tx)
# sign the tx
success = [False] # Array to work around python scoping
def sign_thread(): def sign_thread():
if not self.wallet.is_watching_only(): self.wallet.sign_transaction(tx, password)
self.wallet.sign_transaction(tx, password) return True
def on_signed(ret):
success[0] = True
def on_finished():
self.send_button.setDisabled(False)
callback(success[0])
WaitingDialog(parent, _('Signing transaction...'), sign_thread, WaitingDialog(parent, _('Signing transaction...'), sign_thread,
on_success=on_signed, on_finished=on_finished) callback)
def broadcast_transaction(self, tx, tx_desc, parent=None): def broadcast_transaction(self, tx, tx_desc, parent):
def broadcast_thread(): def broadcast_thread():
# non-GUI thread # non-GUI thread
@ -1313,19 +1303,20 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
msg = ack_msg msg = ack_msg
return status, msg return status, msg
def broadcast_done(status, msg): def broadcast_done(result):
# GUI thread # GUI thread
if status: if result:
if tx_desc is not None and tx.is_complete(): status, msg = result
self.wallet.set_label(tx.hash(), tx_desc) if status:
self.show_message(_('Payment sent.') + '\n' + msg, parent=parent) if tx_desc is not None and tx.is_complete():
self.invoices_list.update() self.wallet.set_label(tx.hash(), tx_desc)
self.do_clear() self.show_message(_('Payment sent.') + '\n' + msg,
else: parent=parent)
self.show_error(msg, parent=parent) self.invoices_list.update()
self.send_button.setDisabled(False) self.do_clear()
else:
self.show_error(msg, parent=parent)
parent = parent or self
WaitingDialog(parent, _('Broadcasting transaction...'), WaitingDialog(parent, _('Broadcasting transaction...'),
broadcast_thread, broadcast_done) broadcast_thread, broadcast_done)

View File

@ -116,7 +116,7 @@ class TxDialog(QDialog, MessageBoxMixin):
self.update() self.update()
def do_broadcast(self): def do_broadcast(self):
self.parent.broadcast_transaction(self.tx, self.desc, parent=self) self.parent.broadcast_transaction(self.tx, self.desc, self)
self.broadcast = True self.broadcast = True
self.update() self.update()
@ -140,14 +140,15 @@ class TxDialog(QDialog, MessageBoxMixin):
def sign(self): def sign(self):
def sign_done(success): def sign_done(success):
self.sign_button.setDisabled(False) self.sign_button.setDisabled(False)
self.prompt_if_unsaved = False if success:
self.saved = False self.prompt_if_unsaved = False
self.update() self.saved = False
self.sign_button.setDisabled(True) self.update()
cancelled, ret = self.parent.sign_tx(self.tx, sign_done, parent=self)
if cancelled:
self.sign_button.setDisabled(False)
self.sign_button.setDisabled(True)
# Note sign_tx is wrapped and parent= is actually passed
# to the password input dialog box
self.parent.sign_tx(self.tx, sign_done, parent=self)
def save(self): def save(self):
name = 'signed_%s.txn' % (self.tx.hash()[0:8]) if self.tx.is_complete() else 'unsigned.txn' name = 'signed_%s.txn' % (self.tx.hash()[0:8]) if self.tx.is_complete() else 'unsigned.txn'

View File

@ -200,13 +200,11 @@ class WindowModalDialog(QDialog):
class WaitingDialog(QThread, MessageBoxMixin): class WaitingDialog(QThread, MessageBoxMixin):
'''Shows a please wait dialog whilst runnning a task. It is not '''Shows a please wait dialog whilst runnning a task. It is not
necessary to maintain a reference to this dialog.''' necessary to maintain a reference to this dialog.'''
def __init__(self, parent, message, task, on_success=None, def __init__(self, parent, message, task, on_finished=None):
on_finished=None):
global dialogs global dialogs
dialogs.append(self) # Prevent GC dialogs.append(self) # Prevent GC
QThread.__init__(self) QThread.__init__(self)
self.task = task self.task = task
self.on_success = on_success
self.on_finished = on_finished self.on_finished = on_finished
self.dialog = WindowModalDialog(parent, _("Please wait")) self.dialog = WindowModalDialog(parent, _("Please wait"))
vbox = QVBoxLayout(self.dialog) vbox = QVBoxLayout(self.dialog)
@ -216,26 +214,22 @@ class WaitingDialog(QThread, MessageBoxMixin):
self.start() self.start()
def run(self): def run(self):
self.error = None
try: try:
self.result = self.task() self.result = self.task()
self.error = None
except BaseException as e: except BaseException as e:
traceback.print_exc(file=sys.stdout) traceback.print_exc(file=sys.stdout)
self.error = str(e) self.error = str(e)
self.result = None
def finished(self): def finished(self):
global dialogs global dialogs
dialogs.remove(self) dialogs.remove(self)
self.dialog.accept()
if self.error: if self.error:
self.show_error(self.error, parent=self.dialog.parent()) self.show_error(self.error, parent=self.dialog.parent())
elif self.on_success:
result = self.result
if type(result) is not tuple:
result = (result,)
self.on_success(*result)
if self.on_finished: if self.on_finished:
self.on_finished() self.on_finished(self.result)
self.dialog.accept()
def line_dialog(parent, title, label, ok_label, default=None): def line_dialog(parent, title, label, ok_label, default=None):
dialog = WindowModalDialog(parent, title) dialog = WindowModalDialog(parent, title)

View File

@ -116,7 +116,7 @@ class Plugin(BasePlugin):
amodem.main.recv(config=self.modem_config, src=src, dst=dst) amodem.main.recv(config=self.modem_config, src=src, dst=dst)
return dst.getvalue() return dst.getvalue()
def on_success(blob): def on_finished(blob):
if blob: if blob:
blob = zlib.decompress(blob) blob = zlib.decompress(blob)
print_msg('Received:', repr(blob)) print_msg('Received:', repr(blob))
@ -124,4 +124,4 @@ class Plugin(BasePlugin):
kbps = self.modem_config.modem_bps / 1e3 kbps = self.modem_config.modem_bps / 1e3
msg = 'Receiving from Audio MODEM ({0:.1f} kbps)...'.format(kbps) msg = 'Receiving from Audio MODEM ({0:.1f} kbps)...'.format(kbps)
WaitingDialog(parent, msg, receiver_thread, on_success=on_success) WaitingDialog(parent, msg, receiver_thread, on_finished)

View File

@ -85,10 +85,10 @@ class Plugin(TrustedCoinPlugin):
self.print_error("twofactor: xpub3 not needed") self.print_error("twofactor: xpub3 not needed")
window.wallet.auth_code = auth_code window.wallet.auth_code = auth_code
def waiting_dialog(self, window, on_success=None): def waiting_dialog(self, window, on_finished=None):
task = partial(self.request_billing_info, window.wallet) task = partial(self.request_billing_info, window.wallet)
return WaitingDialog(window, 'Getting billing information...', task, return WaitingDialog(window, 'Getting billing information...', task,
on_success=on_success) on_finished)
@hook @hook
def abort_send(self, window): def abort_send(self, window):
@ -104,8 +104,7 @@ class Plugin(TrustedCoinPlugin):
def settings_dialog(self, window): def settings_dialog(self, window):
on_success = partial(self.show_settings_dialog, window) self.waiting_dialog(window, partial(self.show_settings_dialog, window))
self.waiting_dialog(window, on_success)
def show_settings_dialog(self, window, success): def show_settings_dialog(self, window, success):
if not success: if not success: