Embed password dialog.

This commit is contained in:
Neil Booth 2016-01-12 23:32:13 +09:00
parent 2ae3543dc4
commit f94d2db9a4
3 changed files with 62 additions and 38 deletions

View File

@ -10,7 +10,7 @@ from electrum.i18n import _
import seed_dialog import seed_dialog
from network_dialog import NetworkDialog from network_dialog import NetworkDialog
from util import * from util import *
from password_dialog import PasswordDialog from password_dialog import PasswordLayout, PW_NEW, PW_PASSPHRASE
from electrum.wallet import Wallet from electrum.wallet import Wallet
from electrum.mnemonic import prepare_seed from electrum.mnemonic import prepare_seed
@ -71,10 +71,11 @@ class InstallWizard(WindowModalDialog, WizardBase):
# Set for base base class # Set for base base class
self.plugins = plugins self.plugins = plugins
self.language_for_seed = config.get('language') self.language_for_seed = config.get('language')
self.setMinimumSize(575, 400) self.setMinimumSize(518, 360)
self.setMaximumSize(575, 400) self.setMaximumSize(518, 360)
self.connect(self, QtCore.SIGNAL('accept'), self.accept) self.connect(self, QtCore.SIGNAL('accept'), self.accept)
self.title = QLabel() self.title = QLabel()
self.title.setWordWrap(True)
self.main_widget = QWidget() self.main_widget = QWidget()
self.cancel_button = QPushButton(_("Cancel"), self) self.cancel_button = QPushButton(_("Cancel"), self)
self.next_button = QPushButton(_("Next"), self) self.next_button = QPushButton(_("Next"), self)
@ -112,8 +113,10 @@ class InstallWizard(WindowModalDialog, WizardBase):
self.logo.setPixmap(QPixmap(filename).scaledToWidth(70)) self.logo.setPixmap(QPixmap(filename).scaledToWidth(70))
return prior_filename return prior_filename
def set_main_layout(self, layout, title): def set_main_layout(self, layout, title=None):
self.title.setText(title) self.title.setText(title or "")
self.title.setVisible(bool(title))
# Get rid of any prior layout
prior_layout = self.main_widget.layout() prior_layout = self.main_widget.layout()
if prior_layout: if prior_layout:
QWidget().setLayout(prior_layout) QWidget().setLayout(prior_layout)
@ -124,7 +127,7 @@ class InstallWizard(WindowModalDialog, WizardBase):
self.please_wait.setVisible(False) self.please_wait.setVisible(False)
if not self.loop.exec_(): if not self.loop.exec_():
raise UserCancelled raise UserCancelled
self.title.setText("") self.title.setVisible(False)
self.cancel_button.setEnabled(False) self.cancel_button.setEnabled(False)
self.next_button.setEnabled(False) self.next_button.setEnabled(False)
self.main_widget.setVisible(False) self.main_widget.setVisible(False)
@ -178,12 +181,13 @@ class InstallWizard(WindowModalDialog, WizardBase):
self.app.clipboard().clear() self.app.clipboard().clear()
self.verify_seed(seed, is_valid) self.verify_seed(seed, is_valid)
def pw_dialog(self, msg, kind): def pw_layout(self, msg, kind):
dialog = PasswordDialog(self, None, msg, kind) hbox = QHBoxLayout()
accepted, p, pass_text = dialog.run() playout = PasswordLayout(None, msg, kind, self.next_button)
if not accepted: hbox.addLayout(playout.layout())
raise UserCancelled #hbox.addStretch(1)
return pass_text self.set_main_layout(hbox)
return playout.new_password()
def request_passphrase(self, device_text, restore=True): def request_passphrase(self, device_text, restore=True):
"""Request a passphrase for a wallet from the given device and """Request a passphrase for a wallet from the given device and
@ -191,12 +195,12 @@ class InstallWizard(WindowModalDialog, WizardBase):
a unicode string.""" a unicode string."""
if restore: if restore:
msg = MSG_RESTORE_PASSPHRASE % device_text msg = MSG_RESTORE_PASSPHRASE % device_text
return unicode(self.pw_dialog(msg, PasswordDialog.PW_PASSPHRASE) or '') return unicode(self.pw_layout(msg, PW_PASSPHRASE) or '')
def request_password(self, msg=None): def request_password(self, msg=None):
"""Request the user enter a new password and confirm it. Return """Request the user enter a new password and confirm it. Return
the password or None for no password.""" the password or None for no password."""
return self.pw_dialog(msg or MSG_ENTER_PASSWORD, PasswordDialog.PW_NEW) return self.pw_layout(msg or MSG_ENTER_PASSWORD, PW_NEW)
def choose_server(self, network): def choose_server(self, network):
self.network_dialog(network) self.network_dialog(network)
@ -246,7 +250,6 @@ class InstallWizard(WindowModalDialog, WizardBase):
actions = [_("Create a new wallet"), actions = [_("Create a new wallet"),
_("Restore a wallet or import keys")] _("Restore a wallet or import keys")]
title = _("Electrum could not find an existing wallet.") title = _("Electrum could not find an existing wallet.")
actions_clayout = ChoicesLayout(_("What do you want to do?"), actions) actions_clayout = ChoicesLayout(_("What do you want to do?"), actions)
wallet_clayout = ChoicesLayout(_("Wallet kind:"), wallet_kinds) wallet_clayout = ChoicesLayout(_("Wallet kind:"), wallet_kinds)
@ -255,6 +258,7 @@ class InstallWizard(WindowModalDialog, WizardBase):
vbox.addLayout(actions_clayout.layout()) vbox.addLayout(actions_clayout.layout())
vbox.addLayout(wallet_clayout.layout()) vbox.addLayout(wallet_clayout.layout())
self.set_main_layout(vbox, title) self.set_main_layout(vbox, title)
action = ['create', 'restore'][actions_clayout.selected_index()] action = ['create', 'restore'][actions_clayout.selected_index()]
return action, wallet_clayout.selected_index() return action, wallet_clayout.selected_index()

View File

@ -39,13 +39,15 @@ def check_password_strength(password):
password_strength = {0:"Weak",1:"Medium",2:"Strong",3:"Very Strong"} password_strength = {0:"Weak",1:"Medium",2:"Strong",3:"Very Strong"}
return password_strength[min(3, int(score))] return password_strength[min(3, int(score))]
class PasswordDialog(WindowModalDialog):
PW_NEW, PW_CHANGE, PW_PASSPHRASE = range(0, 3) PW_NEW, PW_CHANGE, PW_PASSPHRASE = range(0, 3)
class PasswordLayout(object):
titles = [_("Enter Password"), _("Change Password"), _("Enter Passphrase")] titles = [_("Enter Password"), _("Change Password"), _("Enter Passphrase")]
def __init__(self, parent, wallet, msg, kind): def __init__(self, wallet, msg, kind, OK_button):
WindowModalDialog.__init__(self, parent, self.titles[kind])
self.wallet = wallet self.wallet = wallet
self.pw = QLineEdit() self.pw = QLineEdit()
@ -55,6 +57,7 @@ class PasswordDialog(WindowModalDialog):
self.conf_pw = QLineEdit() self.conf_pw = QLineEdit()
self.conf_pw.setEchoMode(2) self.conf_pw.setEchoMode(2)
self.kind = kind self.kind = kind
self.OK_button = OK_button
vbox = QVBoxLayout() vbox = QVBoxLayout()
label = QLabel(msg + "\n") label = QLabel(msg + "\n")
@ -66,7 +69,7 @@ class PasswordDialog(WindowModalDialog):
grid.setColumnMinimumWidth(1, 100) grid.setColumnMinimumWidth(1, 100)
grid.setColumnStretch(1,1) grid.setColumnStretch(1,1)
if kind == self.PW_PASSPHRASE: if kind == PW_PASSPHRASE:
vbox.addWidget(label) vbox.addWidget(label)
msgs = [_('Passphrase:'), _('Confirm Passphrase:')] msgs = [_('Passphrase:'), _('Confirm Passphrase:')]
else: else:
@ -82,7 +85,7 @@ class PasswordDialog(WindowModalDialog):
logo_grid.addWidget(label, 0, 1, 1, 2) logo_grid.addWidget(label, 0, 1, 1, 2)
vbox.addLayout(logo_grid) vbox.addLayout(logo_grid)
m1 = _('New Password:') if kind == self.PW_NEW else _('Password:') m1 = _('New Password:') if kind == PW_NEW else _('Password:')
msgs = [m1, _('Confirm Password:')] msgs = [m1, _('Confirm Password:')]
if wallet and wallet.use_encryption: if wallet and wallet.use_encryption:
grid.addWidget(QLabel(_('Current Password:')), 0, 0) grid.addWidget(QLabel(_('Current Password:')), 0, 0)
@ -100,18 +103,23 @@ class PasswordDialog(WindowModalDialog):
vbox.addLayout(grid) vbox.addLayout(grid)
# Password Strength Label # Password Strength Label
if kind != self.PW_PASSPHRASE: if kind != PW_PASSPHRASE:
self.pw_strength = QLabel() self.pw_strength = QLabel()
grid.addWidget(self.pw_strength, 3, 0, 1, 2) grid.addWidget(self.pw_strength, 3, 0, 1, 2)
self.new_pw.textChanged.connect(self.pw_changed) self.new_pw.textChanged.connect(self.pw_changed)
self.new_pw.textChanged.connect(self.check_OKButton) def enable_OK():
self.conf_pw.textChanged.connect(self.check_OKButton) OK_button.setEnabled(self.new_pw.text() == self.conf_pw.text())
self.new_pw.textChanged.connect(enable_OK)
self.conf_pw.textChanged.connect(enable_OK)
self.OKButton = OkButton(self) self.vbox = vbox
vbox.addStretch(1)
vbox.addLayout(Buttons(CancelButton(self), self.OKButton)) def title(self):
self.setLayout(vbox) return self.titles[self.kind]
def layout(self):
return self.vbox
def pw_changed(self): def pw_changed(self):
password = self.new_pw.text() password = self.new_pw.text()
@ -125,17 +133,29 @@ class PasswordDialog(WindowModalDialog):
label = "" label = ""
self.pw_strength.setText(label) self.pw_strength.setText(label)
def check_OKButton(self): def old_password(self):
self.OKButton.setEnabled(self.new_pw.text() == self.conf_pw.text()) if self.kind == PW_CHANGE:
return unicode(self.pw.text()) or None
return None
def new_password(self):
return unicode(self.new_pw.text()) or None
class PasswordDialog(WindowModalDialog):
def __init__(self, parent, wallet, msg, kind):
WindowModalDialog.__init__(self)
OK_button = OkButton(self)
self.playout = PasswordLayout(wallet, msg, kind, OK_button)
self.setTitle(slef.playout.title())
vbox = QVBoxLayout(self)
vbox.addLayout(self.playout.layout())
vbox.addStretch(1)
vbox.addLayout(Buttons(CancelButton(self), OK_button))
def run(self): def run(self):
if not self.exec_(): if not self.exec_():
return False, None, None return False, None, None
if self.kind == self.PW_CHANGE: return True, self.playout.old_password(), self.playout.new_password()
old_password = unicode(self.pw.text()) or None
else:
old_password = None
new_password = unicode(self.new_pw.text()) or None
return True, old_password, new_password

View File

@ -63,7 +63,7 @@ class SeedLayout(object):
"<p>", "<p>",
_("Please save these %d words on paper (order is important). "), _("Please save these %d words on paper (order is important). "),
_("This seed will allow you to recover your wallet in case " _("This seed will allow you to recover your wallet in case "
"of computer failure.") + "<br/>", "of computer failure."),
"</p>", "</p>",
"<b>" + _("WARNING") + ":</b> ", "<b>" + _("WARNING") + ":</b> ",
"<ul>", "<ul>",