commit 2da6692f73921f3b651569900a63e9f3ce7fbc57
parent ef1330df5d3f7b5021bf7fc453657a7ea0d3af1c
Author: SomberNight <somber.night@protonmail.com>
Date: Mon, 4 Mar 2019 02:08:23 +0100
wizard: some fixes
related: #5174
Diffstat:
4 files changed, 66 insertions(+), 55 deletions(-)
diff --git a/electrum/base_wizard.py b/electrum/base_wizard.py
@@ -299,7 +299,8 @@ class BaseWizard(object):
_('Debug message') + '\n',
debug_msg
])
- self.confirm_dialog(title=title, message=msg, run_next= lambda x: self.choose_hw_device(purpose))
+ self.confirm_dialog(title=title, message=msg,
+ run_next=lambda x: self.choose_hw_device(purpose, storage=storage))
return
# select device
self.devices = devices
@@ -326,15 +327,15 @@ class BaseWizard(object):
+ _('Please try again.'))
devmgr = self.plugins.device_manager
devmgr.unpair_id(device_info.device.id_)
- self.choose_hw_device(purpose)
+ self.choose_hw_device(purpose, storage=storage)
return
except (UserCancelled, GoBack):
- self.choose_hw_device(purpose)
+ self.choose_hw_device(purpose, storage=storage)
return
except BaseException as e:
traceback.print_exc(file=sys.stderr)
self.show_error(str(e))
- self.choose_hw_device(purpose)
+ self.choose_hw_device(purpose, storage=storage)
return
if purpose == HWD_SETUP_NEW_WALLET:
def f(derivation, script_type):
diff --git a/electrum/gui/qt/__init__.py b/electrum/gui/qt/__init__.py
@@ -28,6 +28,7 @@ import signal
import sys
import traceback
import threading
+from typing import Optional
try:
@@ -46,9 +47,9 @@ from electrum.plugin import run_hook
from electrum.base_wizard import GoBack
from electrum.util import (UserCancelled, PrintError, profiler,
WalletFileException, BitcoinException, get_new_wallet_name)
-from electrum.wallet import Wallet
+from electrum.wallet import Wallet, Abstract_Wallet
-from .installwizard import InstallWizard
+from .installwizard import InstallWizard, WalletAlreadyOpenInMemory
from .util import get_default_language, read_QIcon, ColorScheme
@@ -191,7 +192,7 @@ class ElectrumGui(PrintError):
self.network_updated_signal_obj)
self.nd.show()
- def create_window_for_wallet(self, wallet):
+ def _create_window_for_wallet(self, wallet):
w = ElectrumWindow(self, wallet)
self.windows.append(w)
self.build_tray_menu()
@@ -212,9 +213,10 @@ class ElectrumGui(PrintError):
return wrapper
@count_wizards_in_progress
- def start_new_window(self, path, uri, app_is_starting=False):
+ def start_new_window(self, path, uri, *, app_is_starting=False):
'''Raises the window for the wallet if it is open. Otherwise
opens the wallet and creates a new window for it'''
+ wallet = None
try:
wallet = self.daemon.load_wallet(path, None)
except BaseException as e:
@@ -222,49 +224,20 @@ class ElectrumGui(PrintError):
d = QMessageBox(QMessageBox.Warning, _('Error'),
_('Cannot load wallet') + ' (1):\n' + str(e))
d.exec_()
- if app_is_starting:
- # do not return so that the wizard can appear
- wallet = None
- else:
+ # if app is starting, still let wizard to appear
+ if not app_is_starting:
return
if not wallet:
- wizard = InstallWizard(self.config, self.app, self.plugins)
- storage = None
- try:
- path, storage = wizard.select_storage(path, self.daemon.get_wallet)
- # storage is None if file does not exist
- if storage is None:
- wizard.path = path # needed by trustedcoin plugin
- wizard.run('new')
- storage = wizard.create_storage(path)
- else:
- wizard.run_upgrades(storage)
- except UserCancelled:
- return
- except GoBack as e:
- self.print_error('[start_new_window] Exception caught (GoBack)', e)
- except (WalletFileException, BitcoinException) as e:
- traceback.print_exc(file=sys.stderr)
- d = QMessageBox(QMessageBox.Warning, _('Error'),
- _('Cannot load wallet') + ' (2):\n' + str(e))
- d.exec_()
- return
- finally:
- wizard.terminate()
- # return if wallet creation is not complete
- if storage is None or storage.get_action():
- return
- wallet = Wallet(storage)
- if not self.daemon.get_wallet(wallet.storage.path):
- # wallet was not in memory
- wallet.start_network(self.daemon.network)
- self.daemon.add_wallet(wallet)
+ wallet = self._start_wizard_to_select_or_create_wallet(path)
+ if not wallet:
+ return
+ # create or raise window
try:
for w in self.windows:
if w.wallet.storage.path == wallet.storage.path:
break
else:
- w = self.create_window_for_wallet(wallet)
+ w = self._create_window_for_wallet(wallet)
except BaseException as e:
traceback.print_exc(file=sys.stdout)
d = QMessageBox(QMessageBox.Warning, _('Error'),
@@ -284,6 +257,37 @@ class ElectrumGui(PrintError):
w.activateWindow()
return w
+ def _start_wizard_to_select_or_create_wallet(self, path) -> Optional[Abstract_Wallet]:
+ wizard = InstallWizard(self.config, self.app, self.plugins)
+ try:
+ path, storage = wizard.select_storage(path, self.daemon.get_wallet)
+ # storage is None if file does not exist
+ if storage is None:
+ wizard.path = path # needed by trustedcoin plugin
+ wizard.run('new')
+ storage = wizard.create_storage(path)
+ else:
+ wizard.run_upgrades(storage)
+ except (UserCancelled, GoBack):
+ return
+ except WalletAlreadyOpenInMemory as e:
+ return e.wallet
+ except (WalletFileException, BitcoinException) as e:
+ traceback.print_exc(file=sys.stderr)
+ d = QMessageBox(QMessageBox.Warning, _('Error'),
+ _('Cannot load wallet') + ' (2):\n' + str(e))
+ d.exec_()
+ return
+ finally:
+ wizard.terminate()
+ # return if wallet creation is not complete
+ if storage is None or storage.get_action():
+ return
+ wallet = Wallet(storage)
+ wallet.start_network(self.daemon.network)
+ self.daemon.add_wallet(wallet)
+ return wallet
+
def close_window(self, window):
if window in self.windows:
self.windows.remove(window)
diff --git a/electrum/gui/qt/installwizard.py b/electrum/gui/qt/installwizard.py
@@ -6,7 +6,7 @@ import os
import sys
import threading
import traceback
-from typing import Tuple, List, Callable
+from typing import Tuple, List, Callable, NamedTuple, Optional
from PyQt5.QtCore import QRect, QEventLoop, Qt, pyqtSignal
from PyQt5.QtGui import QPalette, QPen, QPainter, QPixmap
@@ -14,7 +14,7 @@ from PyQt5.QtWidgets import (QWidget, QDialog, QLabel, QHBoxLayout, QMessageBox,
QVBoxLayout, QLineEdit, QFileDialog, QPushButton,
QGridLayout, QSlider, QScrollArea)
-from electrum.wallet import Wallet
+from electrum.wallet import Wallet, Abstract_Wallet
from electrum.storage import WalletStorage
from electrum.util import UserCancelled, InvalidPassword, WalletFileException
from electrum.base_wizard import BaseWizard, HWD_SETUP_DECRYPT_WALLET, GoBack
@@ -104,6 +104,11 @@ def wizard_dialog(func):
return func_wrapper
+class WalletAlreadyOpenInMemory(Exception):
+ def __init__(self, wallet: Abstract_Wallet):
+ super().__init__()
+ self.wallet = wallet
+
# WindowModalDialog must come first as it overrides show_error
class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
@@ -162,7 +167,7 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
self.raise_()
self.refresh_gui() # Need for QT on MacOSX. Lame.
- def select_storage(self, path, get_wallet_from_daemon):
+ def select_storage(self, path, get_wallet_from_daemon) -> Tuple[str, Optional[WalletStorage]]:
vbox = QVBoxLayout()
hbox = QHBoxLayout()
@@ -254,7 +259,7 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
break
wallet_from_memory = get_wallet_from_daemon(self.temp_storage.path)
if wallet_from_memory:
- return wallet_from_memory
+ raise WalletAlreadyOpenInMemory(wallet_from_memory)
if self.temp_storage.file_exists() and self.temp_storage.is_encrypted():
if self.temp_storage.is_encrypted_with_user_pw():
password = self.pw_e.text()
@@ -267,7 +272,7 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
except BaseException as e:
traceback.print_exc(file=sys.stdout)
QMessageBox.information(None, _('Error'), str(e))
- return
+ raise UserCancelled()
elif self.temp_storage.is_encrypted_with_hw_device():
try:
self.run('choose_hw_device', HWD_SETUP_DECRYPT_WALLET, storage=self.temp_storage)
@@ -281,11 +286,9 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
except BaseException as e:
traceback.print_exc(file=sys.stdout)
QMessageBox.information(None, _('Error'), str(e))
- return
- if self.temp_storage.is_past_initial_decryption():
- break
- else:
- return
+ raise UserCancelled()
+ assert self.temp_storage.is_past_initial_decryption()
+ break
else:
raise Exception('Unexpected encryption version')
diff --git a/electrum/storage.py b/electrum/storage.py
@@ -119,7 +119,10 @@ class WalletStorage(PrintError):
if encryption is disabled completely (self.is_encrypted() == False),
or if encryption is enabled but the contents have already been decrypted.
"""
- return bool(self.db.data)
+ try:
+ return bool(self.db.data)
+ except AttributeError:
+ return False
def is_encrypted(self):
"""Return if storage encryption is currently enabled."""