Merge branch 'master' of git://github.com/spesmilo/electrum
This commit is contained in:
commit
8bcd132423
@ -407,11 +407,11 @@ class InstallWizard(WindowModalDialog, MessageBoxMixin):
|
|||||||
return self.exec_()
|
return self.exec_()
|
||||||
|
|
||||||
def password_dialog(self):
|
def password_dialog(self):
|
||||||
msg = _("Please choose a password to encrypt your wallet keys.")+'\n'\
|
from password_dialog import PasswordDialog
|
||||||
+_("Leave these fields empty if you want to disable encryption.")
|
msg = _("Please choose a password to encrypt your wallet keys.\n"
|
||||||
from password_dialog import make_password_dialog, run_password_dialog
|
"Leave these fields empty if you want to disable encryption.")
|
||||||
self.set_layout( make_password_dialog(self, None, msg) )
|
dialog = PasswordDialog(self, None, _("Choose a password"), msg, True)
|
||||||
return run_password_dialog(self, None, self)[2]
|
return dialog.run()[2]
|
||||||
|
|
||||||
def run(self, action):
|
def run(self, action):
|
||||||
if self.storage.file_exists and action != 'new':
|
if self.storage.file_exists and action != 'new':
|
||||||
|
|||||||
@ -48,7 +48,7 @@ from electrum import Imported_Wallet, paymentrequest
|
|||||||
from amountedit import BTCAmountEdit, MyLineEdit, BTCkBEdit
|
from amountedit import BTCAmountEdit, MyLineEdit, BTCkBEdit
|
||||||
from network_dialog import NetworkDialog
|
from network_dialog import NetworkDialog
|
||||||
from qrcodewidget import QRCodeWidget, QRDialog
|
from qrcodewidget import QRCodeWidget, QRDialog
|
||||||
from qrtextedit import ScanQRTextEdit, ShowQRTextEdit
|
from qrtextedit import ShowQRTextEdit
|
||||||
from transaction_dialog import show_transaction
|
from transaction_dialog import show_transaction
|
||||||
from installwizard import InstallWizard
|
from installwizard import InstallWizard
|
||||||
|
|
||||||
@ -1568,6 +1568,13 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
|||||||
def paytomany(self):
|
def paytomany(self):
|
||||||
self.tabs.setCurrentIndex(1)
|
self.tabs.setCurrentIndex(1)
|
||||||
self.payto_e.paytomany()
|
self.payto_e.paytomany()
|
||||||
|
msg = '\n'.join([
|
||||||
|
_('Enter a list of outputs in the \'Pay to\' field.'),
|
||||||
|
_('One output per line.'),
|
||||||
|
_('Format: address, amount'),
|
||||||
|
_('You may load a CSV file using the file icon.')
|
||||||
|
])
|
||||||
|
self.show_warning(msg, title=_('Pay to many'))
|
||||||
|
|
||||||
def payto_contacts(self, labels):
|
def payto_contacts(self, labels):
|
||||||
paytos = [self.get_contact_payto(label) for label in labels]
|
paytos = [self.get_contact_payto(label) for label in labels]
|
||||||
@ -1852,8 +1859,39 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
|||||||
|
|
||||||
def change_password_dialog(self):
|
def change_password_dialog(self):
|
||||||
from password_dialog import PasswordDialog
|
from password_dialog import PasswordDialog
|
||||||
d = PasswordDialog(self.wallet, self)
|
|
||||||
d.run()
|
if self.wallet and self.wallet.is_watching_only():
|
||||||
|
self.show_error(_('This is a watching-only wallet'))
|
||||||
|
return
|
||||||
|
|
||||||
|
msg = (_('Your wallet is encrypted. Use this dialog to change your '
|
||||||
|
'password. To disable wallet encryption, enter an empty new '
|
||||||
|
'password.') if self.wallet.use_encryption
|
||||||
|
else _('Your wallet keys are not encrypted'))
|
||||||
|
d = PasswordDialog(self, self.wallet, _("Set Password"), msg, True)
|
||||||
|
ok, password, new_password = d.run()
|
||||||
|
if not ok:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.wallet.check_password(password)
|
||||||
|
except BaseException as e:
|
||||||
|
self.show_error(str(e))
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.wallet.update_password(password, new_password)
|
||||||
|
except:
|
||||||
|
traceback.print_exc(file=sys.stdout)
|
||||||
|
self.show_error(_('Failed to update password'))
|
||||||
|
return
|
||||||
|
|
||||||
|
if new_password:
|
||||||
|
msg = _('Password was updated successfully')
|
||||||
|
else:
|
||||||
|
msg = _('This wallet is not encrypted')
|
||||||
|
self.show_message(msg, title=_("Success"))
|
||||||
|
|
||||||
self.update_lock_icon()
|
self.update_lock_icon()
|
||||||
|
|
||||||
def toggle_search(self):
|
def toggle_search(self):
|
||||||
@ -1985,10 +2023,10 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def show_qrcode(self, data, title = _("QR code")):
|
def show_qrcode(self, data, title = _("QR code"), parent=None):
|
||||||
if not data:
|
if not data:
|
||||||
return
|
return
|
||||||
d = QRDialog(data, self, title)
|
d = QRDialog(data, parent or self, title)
|
||||||
d.exec_()
|
d.exec_()
|
||||||
|
|
||||||
def show_public_keys(self, address):
|
def show_public_keys(self, address):
|
||||||
@ -2154,10 +2192,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
|||||||
layout.addLayout(hbox, 4, 1)
|
layout.addLayout(hbox, 4, 1)
|
||||||
d.exec_()
|
d.exec_()
|
||||||
|
|
||||||
|
|
||||||
def question(self, msg):
|
|
||||||
return QMessageBox.question(self, _('Message'), msg, QMessageBox.Yes | QMessageBox.No, QMessageBox.No) == QMessageBox.Yes
|
|
||||||
|
|
||||||
def password_dialog(self, msg=None, parent=None):
|
def password_dialog(self, msg=None, parent=None):
|
||||||
if parent == None:
|
if parent == None:
|
||||||
parent = self
|
parent = self
|
||||||
@ -2205,7 +2239,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
|||||||
from electrum import qrscanner
|
from electrum import qrscanner
|
||||||
try:
|
try:
|
||||||
data = qrscanner.scan_qr(self.config)
|
data = qrscanner.scan_qr(self.config)
|
||||||
except BaseException as e:
|
except e:
|
||||||
self.show_error(str(e))
|
self.show_error(str(e))
|
||||||
return
|
return
|
||||||
if not data:
|
if not data:
|
||||||
@ -2495,10 +2529,10 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
|||||||
@protected
|
@protected
|
||||||
def do_import_privkey(self, password):
|
def do_import_privkey(self, password):
|
||||||
if not self.wallet.has_imported_keys():
|
if not self.wallet.has_imported_keys():
|
||||||
r = QMessageBox.question(None, _('Warning'), '<b>'+_('Warning') +':\n</b><br/>'+ _('Imported keys are not recoverable from seed.') + ' ' \
|
if not self.question('<b>'+_('Warning') +':\n</b><br/>'+ _('Imported keys are not recoverable from seed.') + ' ' \
|
||||||
+ _('If you ever need to restore your wallet from its seed, these keys will be lost.') + '<p>' \
|
+ _('If you ever need to restore your wallet from its seed, these keys will be lost.') + '<p>' \
|
||||||
+ _('Are you sure you understand what you are doing?'), 3, 4)
|
+ _('Are you sure you understand what you are doing?'), title=_('Warning')):
|
||||||
if r == 4: return
|
return
|
||||||
|
|
||||||
text = text_dialog(self, _('Import private keys'), _("Enter private keys")+':', _("Import"))
|
text = text_dialog(self, _('Import private keys'), _("Enter private keys")+':', _("Import"))
|
||||||
if not text: return
|
if not text: return
|
||||||
|
|||||||
@ -23,84 +23,6 @@ from util import *
|
|||||||
import re
|
import re
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def make_password_dialog(self, wallet, msg, new_pass=True):
|
|
||||||
|
|
||||||
self.pw = QLineEdit()
|
|
||||||
self.pw.setEchoMode(2)
|
|
||||||
self.new_pw = QLineEdit()
|
|
||||||
self.new_pw.setEchoMode(2)
|
|
||||||
self.conf_pw = QLineEdit()
|
|
||||||
self.conf_pw.setEchoMode(2)
|
|
||||||
|
|
||||||
vbox = QVBoxLayout()
|
|
||||||
label = QLabel(msg)
|
|
||||||
label.setWordWrap(True)
|
|
||||||
|
|
||||||
grid = QGridLayout()
|
|
||||||
grid.setSpacing(8)
|
|
||||||
grid.setColumnMinimumWidth(0, 70)
|
|
||||||
grid.setColumnStretch(1,1)
|
|
||||||
|
|
||||||
logo = QLabel()
|
|
||||||
lockfile = ":icons/lock.png" if wallet and wallet.use_encryption else ":icons/unlock.png"
|
|
||||||
logo.setPixmap(QPixmap(lockfile).scaledToWidth(36))
|
|
||||||
logo.setAlignment(Qt.AlignCenter)
|
|
||||||
|
|
||||||
grid.addWidget(logo, 0, 0)
|
|
||||||
grid.addWidget(label, 0, 1, 1, 2)
|
|
||||||
vbox.addLayout(grid)
|
|
||||||
|
|
||||||
grid = QGridLayout()
|
|
||||||
grid.setSpacing(8)
|
|
||||||
grid.setColumnMinimumWidth(0, 250)
|
|
||||||
grid.setColumnStretch(1,1)
|
|
||||||
|
|
||||||
if wallet and wallet.use_encryption:
|
|
||||||
grid.addWidget(QLabel(_('Password')), 0, 0)
|
|
||||||
grid.addWidget(self.pw, 0, 1)
|
|
||||||
|
|
||||||
grid.addWidget(QLabel(_('New Password') if new_pass else _('Password')), 1, 0)
|
|
||||||
grid.addWidget(self.new_pw, 1, 1)
|
|
||||||
|
|
||||||
grid.addWidget(QLabel(_('Confirm Password')), 2, 0)
|
|
||||||
grid.addWidget(self.conf_pw, 2, 1)
|
|
||||||
vbox.addLayout(grid)
|
|
||||||
|
|
||||||
#Password Strength Label
|
|
||||||
self.pw_strength = QLabel()
|
|
||||||
grid.addWidget(self.pw_strength, 3, 0, 1, 2)
|
|
||||||
self.new_pw.textChanged.connect(lambda: update_password_strength(self.pw_strength, self.new_pw.text()))
|
|
||||||
|
|
||||||
vbox.addStretch(1)
|
|
||||||
vbox.addLayout(Buttons(CancelButton(self), OkButton(self)))
|
|
||||||
return vbox
|
|
||||||
|
|
||||||
|
|
||||||
def run_password_dialog(self, wallet, parent):
|
|
||||||
|
|
||||||
if wallet and wallet.is_watching_only():
|
|
||||||
QMessageBox.information(parent, _('Error'), _('This is a watching-only wallet'), _('OK'))
|
|
||||||
return False, None, None
|
|
||||||
|
|
||||||
if not self.exec_():
|
|
||||||
return False, None, None
|
|
||||||
|
|
||||||
password = unicode(self.pw.text()) if wallet and wallet.use_encryption else None
|
|
||||||
new_password = unicode(self.new_pw.text())
|
|
||||||
new_password2 = unicode(self.conf_pw.text())
|
|
||||||
|
|
||||||
if new_password != new_password2:
|
|
||||||
QMessageBox.warning(parent, _('Error'), _('Passwords do not match'), _('OK'))
|
|
||||||
# Retry
|
|
||||||
return run_password_dialog(self, wallet, parent)
|
|
||||||
|
|
||||||
if not new_password:
|
|
||||||
new_password = None
|
|
||||||
|
|
||||||
return True, password, new_password
|
|
||||||
|
|
||||||
def check_password_strength(password):
|
def check_password_strength(password):
|
||||||
|
|
||||||
'''
|
'''
|
||||||
@ -117,57 +39,89 @@ 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))]
|
||||||
|
|
||||||
|
|
||||||
def update_password_strength(pw_strength_label,password):
|
|
||||||
|
|
||||||
'''
|
|
||||||
call the function check_password_strength and update the label pw_strength interactively as the user is typing the password
|
|
||||||
:param pw_strength_label: the label pw_strength
|
|
||||||
:param password: password entered in New Password text box
|
|
||||||
:return: None
|
|
||||||
'''
|
|
||||||
if password:
|
|
||||||
colors = {"Weak":"Red","Medium":"Blue","Strong":"Green", "Very Strong":"Green"}
|
|
||||||
strength = check_password_strength(password)
|
|
||||||
label = _("Password Strength")+ ": "+"<font color=" + colors[strength] + ">" + strength + "</font>"
|
|
||||||
else:
|
|
||||||
label = ""
|
|
||||||
pw_strength_label.setText(label)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PasswordDialog(WindowModalDialog):
|
class PasswordDialog(WindowModalDialog):
|
||||||
|
|
||||||
def __init__(self, wallet, parent):
|
def __init__(self, parent, wallet, title, msg, new_pass):
|
||||||
WindowModalDialog.__init__(self, parent,_("Set Password"))
|
WindowModalDialog.__init__(self, parent, title)
|
||||||
self.wallet = wallet
|
self.wallet = wallet
|
||||||
self.parent = parent
|
|
||||||
msg = (_('Your wallet is encrypted. Use this dialog to change your password.') + ' '\
|
|
||||||
+_('To disable wallet encryption, enter an empty new password.')) \
|
|
||||||
if wallet.use_encryption else _('Your wallet keys are not encrypted')
|
|
||||||
self.setLayout(make_password_dialog(self, wallet, msg))
|
|
||||||
|
|
||||||
|
self.pw = QLineEdit()
|
||||||
|
self.pw.setEchoMode(2)
|
||||||
|
self.new_pw = QLineEdit()
|
||||||
|
self.new_pw.setEchoMode(2)
|
||||||
|
self.conf_pw = QLineEdit()
|
||||||
|
self.conf_pw.setEchoMode(2)
|
||||||
|
|
||||||
|
vbox = QVBoxLayout()
|
||||||
|
label = QLabel(msg)
|
||||||
|
label.setWordWrap(True)
|
||||||
|
|
||||||
|
grid = QGridLayout()
|
||||||
|
grid.setSpacing(8)
|
||||||
|
grid.setColumnMinimumWidth(0, 70)
|
||||||
|
grid.setColumnStretch(1,1)
|
||||||
|
|
||||||
|
logo = QLabel()
|
||||||
|
logo.setAlignment(Qt.AlignCenter)
|
||||||
|
|
||||||
|
grid.addWidget(logo, 0, 0)
|
||||||
|
grid.addWidget(label, 0, 1, 1, 2)
|
||||||
|
vbox.addLayout(grid)
|
||||||
|
|
||||||
|
grid = QGridLayout()
|
||||||
|
grid.setSpacing(8)
|
||||||
|
grid.setColumnMinimumWidth(0, 250)
|
||||||
|
grid.setColumnStretch(1,1)
|
||||||
|
|
||||||
|
if wallet and wallet.use_encryption:
|
||||||
|
grid.addWidget(QLabel(_('Password')), 0, 0)
|
||||||
|
grid.addWidget(self.pw, 0, 1)
|
||||||
|
lockfile = ":icons/lock.png"
|
||||||
|
else:
|
||||||
|
self.pw = None
|
||||||
|
lockfile = ":icons/unlock.png"
|
||||||
|
logo.setPixmap(QPixmap(lockfile).scaledToWidth(36))
|
||||||
|
|
||||||
|
grid.addWidget(QLabel(_('New Password') if new_pass else _('Password')), 1, 0)
|
||||||
|
grid.addWidget(self.new_pw, 1, 1)
|
||||||
|
|
||||||
|
grid.addWidget(QLabel(_('Confirm Password')), 2, 0)
|
||||||
|
grid.addWidget(self.conf_pw, 2, 1)
|
||||||
|
vbox.addLayout(grid)
|
||||||
|
|
||||||
|
# Password Strength Label
|
||||||
|
self.pw_strength = QLabel()
|
||||||
|
grid.addWidget(self.pw_strength, 3, 0, 1, 2)
|
||||||
|
self.new_pw.textChanged.connect(self.pw_changed)
|
||||||
|
self.conf_pw.textChanged.connect(self.check_OKButton)
|
||||||
|
|
||||||
|
self.OKButton = OkButton(self)
|
||||||
|
vbox.addStretch(1)
|
||||||
|
vbox.addLayout(Buttons(CancelButton(self), self.OKButton))
|
||||||
|
self.setLayout(vbox)
|
||||||
|
|
||||||
|
def pw_changed(self):
|
||||||
|
password = self.new_pw.text()
|
||||||
|
if password:
|
||||||
|
colors = {"Weak":"Red", "Medium":"Blue", "Strong":"Green",
|
||||||
|
"Very Strong":"Green"}
|
||||||
|
strength = check_password_strength(password)
|
||||||
|
label = (_("Password Strength") + ": " + "<font color="
|
||||||
|
+ colors[strength] + ">" + strength + "</font>")
|
||||||
|
else:
|
||||||
|
label = ""
|
||||||
|
self.pw_strength.setText(label)
|
||||||
|
self.check_OKButton()
|
||||||
|
|
||||||
|
def check_OKButton(self):
|
||||||
|
self.OKButton.setEnabled(self.new_pw.text() == self.conf_pw.text())
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
ok, password, new_password = run_password_dialog(self, self.wallet, self.parent)
|
if not self.exec_():
|
||||||
if not ok:
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.wallet.check_password(password)
|
|
||||||
except BaseException as e:
|
|
||||||
QMessageBox.warning(self.parent, _('Error'), str(e), _('OK'))
|
|
||||||
return False, None, None
|
return False, None, None
|
||||||
|
|
||||||
try:
|
password = unicode(self.pw.text()) if self.pw else None
|
||||||
self.wallet.update_password(password, new_password)
|
new_password = unicode(self.new_pw.text())
|
||||||
except:
|
new_password2 = unicode(self.conf_pw.text())
|
||||||
import traceback, sys
|
|
||||||
traceback.print_exc(file=sys.stdout)
|
|
||||||
QMessageBox.warning(self.parent, _('Error'), _('Failed to update password'), _('OK'))
|
|
||||||
return
|
|
||||||
|
|
||||||
if new_password:
|
return True, password or None, new_password or None
|
||||||
QMessageBox.information(self.parent, _('Success'), _('Password was updated successfully'), _('OK'))
|
|
||||||
else:
|
|
||||||
QMessageBox.information(self.parent, _('Success'), _('This wallet is not encrypted'), _('OK'))
|
|
||||||
|
|||||||
@ -160,16 +160,8 @@ class PayToEdit(ScanQRTextEdit):
|
|||||||
return len(self.lines()) > 1
|
return len(self.lines()) > 1
|
||||||
|
|
||||||
def paytomany(self):
|
def paytomany(self):
|
||||||
from electrum.i18n import _
|
|
||||||
self.setText("\n\n\n")
|
self.setText("\n\n\n")
|
||||||
self.update_size()
|
self.update_size()
|
||||||
msg = '\n'.join([
|
|
||||||
_('Enter a list of outputs in the \'Pay to\' field.'),
|
|
||||||
_('One output per line.'),
|
|
||||||
_('Format: address, amount.'),
|
|
||||||
_('You may load a CSV file using the file icon.')
|
|
||||||
])
|
|
||||||
QMessageBox.warning(self, _('Pay to many'), msg, _('OK'))
|
|
||||||
|
|
||||||
def update_size(self):
|
def update_size(self):
|
||||||
docHeight = self.document().size().height()
|
docHeight = self.document().size().height()
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
from PyQt4.QtGui import *
|
from PyQt4.QtGui import *
|
||||||
from PyQt4.QtCore import *
|
from PyQt4.QtCore import *
|
||||||
import PyQt4.QtCore as QtCore
|
|
||||||
import PyQt4.QtGui as QtGui
|
import PyQt4.QtGui as QtGui
|
||||||
|
|
||||||
import os
|
import os
|
||||||
@ -9,6 +8,7 @@ import qrcode
|
|||||||
import electrum
|
import electrum
|
||||||
from electrum import bmp
|
from electrum import bmp
|
||||||
from electrum.i18n import _
|
from electrum.i18n import _
|
||||||
|
from util import WindowModalDialog, MessageBoxMixin
|
||||||
|
|
||||||
|
|
||||||
class QRCodeWidget(QWidget):
|
class QRCodeWidget(QWidget):
|
||||||
@ -83,13 +83,11 @@ class QRCodeWidget(QWidget):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class QRDialog(QDialog):
|
class QRDialog(WindowModalDialog, MessageBoxMixin):
|
||||||
|
|
||||||
def __init__(self, data, parent=None, title = "", show_text=False):
|
def __init__(self, data, parent=None, title = "", show_text=False):
|
||||||
QDialog.__init__(self, parent)
|
WindowModalDialog.__init__(self, parent, title)
|
||||||
|
|
||||||
d = self
|
|
||||||
d.setWindowTitle(title)
|
|
||||||
vbox = QVBoxLayout()
|
vbox = QVBoxLayout()
|
||||||
qrw = QRCodeWidget(data)
|
qrw = QRCodeWidget(data)
|
||||||
vbox.addWidget(qrw, 1)
|
vbox.addWidget(qrw, 1)
|
||||||
@ -107,12 +105,12 @@ class QRDialog(QDialog):
|
|||||||
|
|
||||||
def print_qr():
|
def print_qr():
|
||||||
bmp.save_qrcode(qrw.qr, filename)
|
bmp.save_qrcode(qrw.qr, filename)
|
||||||
QMessageBox.information(None, _('Message'), _("QR code saved to file") + " " + filename, _('OK'))
|
self.show_message(_("QR code saved to file") + " " + filename)
|
||||||
|
|
||||||
def copy_to_clipboard():
|
def copy_to_clipboard():
|
||||||
bmp.save_qrcode(qrw.qr, filename)
|
bmp.save_qrcode(qrw.qr, filename)
|
||||||
QApplication.clipboard().setImage(QImage(filename))
|
QApplication.clipboard().setImage(QImage(filename))
|
||||||
QMessageBox.information(None, _('Message'), _("QR code saved to clipboard"), _('OK'))
|
self.show_message(_("QR code copied to clipboard"))
|
||||||
|
|
||||||
b = QPushButton(_("Copy"))
|
b = QPushButton(_("Copy"))
|
||||||
hbox.addWidget(b)
|
hbox.addWidget(b)
|
||||||
@ -124,8 +122,8 @@ class QRDialog(QDialog):
|
|||||||
|
|
||||||
b = QPushButton(_("Close"))
|
b = QPushButton(_("Close"))
|
||||||
hbox.addWidget(b)
|
hbox.addWidget(b)
|
||||||
b.clicked.connect(d.accept)
|
b.clicked.connect(self.accept)
|
||||||
b.setDefault(True)
|
b.setDefault(True)
|
||||||
|
|
||||||
vbox.addLayout(hbox)
|
vbox.addLayout(hbox)
|
||||||
d.setLayout(vbox)
|
self.setLayout(vbox)
|
||||||
|
|||||||
@ -3,7 +3,7 @@ from electrum.plugins import run_hook
|
|||||||
from PyQt4.QtGui import *
|
from PyQt4.QtGui import *
|
||||||
from PyQt4.QtCore import *
|
from PyQt4.QtCore import *
|
||||||
|
|
||||||
from util import ButtonsTextEdit
|
from util import ButtonsTextEdit, MessageBoxMixin
|
||||||
|
|
||||||
|
|
||||||
class ShowQRTextEdit(ButtonsTextEdit):
|
class ShowQRTextEdit(ButtonsTextEdit):
|
||||||
@ -29,7 +29,7 @@ class ShowQRTextEdit(ButtonsTextEdit):
|
|||||||
m.exec_(e.globalPos())
|
m.exec_(e.globalPos())
|
||||||
|
|
||||||
|
|
||||||
class ScanQRTextEdit(ButtonsTextEdit):
|
class ScanQRTextEdit(ButtonsTextEdit, MessageBoxMixin):
|
||||||
|
|
||||||
def __init__(self, text=""):
|
def __init__(self, text=""):
|
||||||
ButtonsTextEdit.__init__(self, text)
|
ButtonsTextEdit.__init__(self, text)
|
||||||
@ -50,8 +50,8 @@ class ScanQRTextEdit(ButtonsTextEdit):
|
|||||||
from electrum import qrscanner, get_config
|
from electrum import qrscanner, get_config
|
||||||
try:
|
try:
|
||||||
data = qrscanner.scan_qr(get_config())
|
data = qrscanner.scan_qr(get_config())
|
||||||
except BaseException, e:
|
except BaseException as e:
|
||||||
QMessageBox.warning(self, _('Error'), _(e), _('OK'))
|
self.show_error(str(e))
|
||||||
return ""
|
return ""
|
||||||
if type(data) != str:
|
if type(data) != str:
|
||||||
return
|
return
|
||||||
|
|||||||
@ -38,7 +38,7 @@ def show_transaction(tx, parent, desc=None, prompt_if_unsaved=False):
|
|||||||
dialogs.append(d)
|
dialogs.append(d)
|
||||||
d.show()
|
d.show()
|
||||||
|
|
||||||
class TxDialog(QDialog):
|
class TxDialog(QDialog, MessageBoxMixin):
|
||||||
|
|
||||||
def __init__(self, tx, parent, desc, prompt_if_unsaved):
|
def __init__(self, tx, parent, desc, prompt_if_unsaved):
|
||||||
'''Transactions in the wallet will show their description.
|
'''Transactions in the wallet will show their description.
|
||||||
@ -62,7 +62,7 @@ class TxDialog(QDialog):
|
|||||||
|
|
||||||
vbox.addWidget(QLabel(_("Transaction ID:")))
|
vbox.addWidget(QLabel(_("Transaction ID:")))
|
||||||
self.tx_hash_e = ButtonsLineEdit()
|
self.tx_hash_e = ButtonsLineEdit()
|
||||||
qr_show = lambda: self.parent.show_qrcode(str(self.tx_hash_e.text()), 'Transaction ID')
|
qr_show = lambda: self.parent.show_qrcode(str(self.tx_hash_e.text()), 'Transaction ID', parent=self)
|
||||||
self.tx_hash_e.addButton(":icons/qrcode.png", qr_show, _("Show as QR code"))
|
self.tx_hash_e.addButton(":icons/qrcode.png", qr_show, _("Show as QR code"))
|
||||||
self.tx_hash_e.setReadOnly(True)
|
self.tx_hash_e.setReadOnly(True)
|
||||||
vbox.addWidget(self.tx_hash_e)
|
vbox.addWidget(self.tx_hash_e)
|
||||||
@ -122,10 +122,7 @@ class TxDialog(QDialog):
|
|||||||
|
|
||||||
def closeEvent(self, event):
|
def closeEvent(self, event):
|
||||||
if (self.prompt_if_unsaved and not self.saved and not self.broadcast
|
if (self.prompt_if_unsaved and not self.saved and not self.broadcast
|
||||||
and QMessageBox.question(
|
and not self.question(_('This transaction is not saved. Close anyway?'), title=_("Warning"))):
|
||||||
self, _('Warning'),
|
|
||||||
_('This transaction is not saved. Close anyway?'),
|
|
||||||
QMessageBox.Yes | QMessageBox.No) == QMessageBox.No):
|
|
||||||
event.ignore()
|
event.ignore()
|
||||||
else:
|
else:
|
||||||
event.accept()
|
event.accept()
|
||||||
@ -135,7 +132,7 @@ class TxDialog(QDialog):
|
|||||||
text = self.tx.raw.decode('hex')
|
text = self.tx.raw.decode('hex')
|
||||||
text = base_encode(text, base=43)
|
text = base_encode(text, base=43)
|
||||||
try:
|
try:
|
||||||
self.parent.show_qrcode(text, 'Transaction')
|
self.parent.show_qrcode(text, 'Transaction', parent=self)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.show_message(str(e))
|
self.show_message(str(e))
|
||||||
|
|
||||||
@ -291,8 +288,3 @@ class TxDialog(QDialog):
|
|||||||
cursor.insertText(format_amount(v), ext)
|
cursor.insertText(format_amount(v), ext)
|
||||||
cursor.insertBlock()
|
cursor.insertBlock()
|
||||||
vbox.addWidget(o_text)
|
vbox.addWidget(o_text)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def show_message(self, msg):
|
|
||||||
QMessageBox.information(self, _('Message'), msg, _('OK'))
|
|
||||||
|
|||||||
@ -193,18 +193,26 @@ class CancelButton(QPushButton):
|
|||||||
self.clicked.connect(dialog.reject)
|
self.clicked.connect(dialog.reject)
|
||||||
|
|
||||||
class MessageBoxMixin:
|
class MessageBoxMixin:
|
||||||
|
def question(self, msg, parent=None, title=None):
|
||||||
|
Yes, No = QMessageBox.Yes, QMessageBox.No
|
||||||
|
return WindowModalDialog.question(parent or self, title, msg,
|
||||||
|
buttons=Yes|No,
|
||||||
|
defaultButton=No) == Yes
|
||||||
|
|
||||||
def show_warning(self, msg, parent=None, title=None):
|
def show_warning(self, msg, parent=None, title=None):
|
||||||
WindowModalDialog.warning(parent or self, title or _('Warning'), msg)
|
return WindowModalDialog.warning(parent or self,
|
||||||
|
title or _('Warning'), msg)
|
||||||
|
|
||||||
def show_error(self, msg, parent=None):
|
def show_error(self, msg, parent=None):
|
||||||
self.show_warning(msg, parent=parent, title=_('Error'))
|
return self.show_warning(msg, parent=parent, title=_('Error'))
|
||||||
|
|
||||||
def show_critical(self, msg, parent=None, title=None):
|
def show_critical(self, msg, parent=None, title=None):
|
||||||
WindowModalDialog.critical(parent or self,
|
return WindowModalDialog.critical(parent or self,
|
||||||
title or _('Critical Error'), msg)
|
title or _('Critical Error'), msg)
|
||||||
|
|
||||||
def show_message(self, msg, parent=None, title=None):
|
def show_message(self, msg, parent=None, title=None):
|
||||||
WindowModalDialog.information(self, title or _('Information'), msg)
|
return WindowModalDialog.information(self, title or _('Information'),
|
||||||
|
msg)
|
||||||
|
|
||||||
class WindowModalDialog(QDialog):
|
class WindowModalDialog(QDialog):
|
||||||
'''Handy wrapper; window modal dialogs are better for our multi-window
|
'''Handy wrapper; window modal dialogs are better for our multi-window
|
||||||
@ -215,6 +223,10 @@ class WindowModalDialog(QDialog):
|
|||||||
if title:
|
if title:
|
||||||
self.setWindowTitle(title)
|
self.setWindowTitle(title)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def question(*args, **kwargs):
|
||||||
|
return WindowModalDialog.msg_box(QMessageBox.Question, *args, **kwargs)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def critical(*args, **kwargs):
|
def critical(*args, **kwargs):
|
||||||
return WindowModalDialog.msg_box(QMessageBox.Critical, *args, **kwargs)
|
return WindowModalDialog.msg_box(QMessageBox.Critical, *args, **kwargs)
|
||||||
|
|||||||
@ -12,7 +12,7 @@ proc = None
|
|||||||
def scan_qr(config):
|
def scan_qr(config):
|
||||||
global proc
|
global proc
|
||||||
if not zbar:
|
if not zbar:
|
||||||
raise BaseException("\n".join([_("Cannot start QR scanner."),_("The zbar package is not available."),_("On Linux, try 'sudo pip install zbar'")]))
|
raise RuntimeError("\n".join([_("Cannot start QR scanner."),_("The zbar package is not available."),_("On Linux, try 'sudo pip install zbar'")]))
|
||||||
if proc is None:
|
if proc is None:
|
||||||
device = config.get("video_device", "default")
|
device = config.get("video_device", "default")
|
||||||
if device == 'default':
|
if device == 'default':
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
from PyQt4.Qt import QMessageBox, QDialog, QVBoxLayout, QLabel, QThread, SIGNAL, QGridLayout, QInputDialog, QPushButton
|
from PyQt4.Qt import QMessageBox, QVBoxLayout, QLabel, QThread, SIGNAL, QGridLayout, QInputDialog, QPushButton
|
||||||
import PyQt4.QtCore as QtCore
|
import PyQt4.QtCore as QtCore
|
||||||
from electrum_gui.qt.util import *
|
from electrum_gui.qt.util import *
|
||||||
from electrum_gui.qt.main_window import StatusBarButton, ElectrumWindow
|
from electrum_gui.qt.main_window import StatusBarButton, ElectrumWindow
|
||||||
@ -73,7 +73,7 @@ class Plugin(KeepKeyPlugin):
|
|||||||
return
|
return
|
||||||
get_label = lambda: self.get_client().features.label
|
get_label = lambda: self.get_client().features.label
|
||||||
update_label = lambda: current_label_label.setText("Label: %s" % get_label())
|
update_label = lambda: current_label_label.setText("Label: %s" % get_label())
|
||||||
d = QDialog()
|
d = WindowModalDialog(window, _("KeepKey Settings"))
|
||||||
layout = QGridLayout(d)
|
layout = QGridLayout(d)
|
||||||
layout.addWidget(QLabel("KeepKey Options"),0,0)
|
layout.addWidget(QLabel("KeepKey Options"),0,0)
|
||||||
layout.addWidget(QLabel("ID:"),1,0)
|
layout.addWidget(QLabel("ID:"),1,0)
|
||||||
@ -132,10 +132,7 @@ class KeepKeyQtHandler:
|
|||||||
return self.passphrase
|
return self.passphrase
|
||||||
|
|
||||||
def pin_dialog(self):
|
def pin_dialog(self):
|
||||||
d = QDialog(None)
|
d = WindowModalDialog(self.win, _("Enter PIN"))
|
||||||
d.setModal(1)
|
|
||||||
d.setWindowTitle(_("Enter PIN"))
|
|
||||||
d.setWindowFlags(d.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
|
|
||||||
matrix = PinMatrixWidget()
|
matrix = PinMatrixWidget()
|
||||||
vbox = QVBoxLayout()
|
vbox = QVBoxLayout()
|
||||||
vbox.addWidget(QLabel(self.message))
|
vbox.addWidget(QLabel(self.message))
|
||||||
@ -153,23 +150,18 @@ class KeepKeyQtHandler:
|
|||||||
self.passphrase = unicodedata.normalize('NFKD', unicode(passphrase)) if passphrase else ''
|
self.passphrase = unicodedata.normalize('NFKD', unicode(passphrase)) if passphrase else ''
|
||||||
else:
|
else:
|
||||||
assert type(self.win) is InstallWizard
|
assert type(self.win) is InstallWizard
|
||||||
from electrum_gui.qt.password_dialog import make_password_dialog, run_password_dialog
|
from electrum_gui.qt.password_dialog import PasswordDialog
|
||||||
d = QDialog()
|
d = PasswordDialog(self.win, None, None, self.message, False)
|
||||||
d.setModal(1)
|
confirmed, p, passphrase = d.run()
|
||||||
d.setLayout(make_password_dialog(d, None, self.message, False))
|
|
||||||
confirmed, p, passphrase = run_password_dialog(d, None, None)
|
|
||||||
if not confirmed:
|
if not confirmed:
|
||||||
QMessageBox.critical(None, _('Error'), _("Password request canceled"), _('OK'))
|
self.win.show_critical(_("Password request canceled"))
|
||||||
self.passphrase = None
|
self.passphrase = None
|
||||||
else:
|
else:
|
||||||
self.passphrase = unicodedata.normalize('NFKD', unicode(passphrase)) if passphrase else ''
|
self.passphrase = unicodedata.normalize('NFKD', unicode(passphrase)) if passphrase else ''
|
||||||
self.done.set()
|
self.done.set()
|
||||||
|
|
||||||
def message_dialog(self):
|
def message_dialog(self):
|
||||||
self.d = QDialog()
|
self.d = WindowModalDialog(self.win, _('Please Check KeepKey Device'))
|
||||||
self.d.setModal(1)
|
|
||||||
self.d.setWindowTitle('Please Check KeepKey Device')
|
|
||||||
self.d.setWindowFlags(self.d.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
|
|
||||||
l = QLabel(self.message)
|
l = QLabel(self.message)
|
||||||
vbox = QVBoxLayout(self.d)
|
vbox = QVBoxLayout(self.d)
|
||||||
vbox.addWidget(l)
|
vbox.addWidget(l)
|
||||||
@ -182,5 +174,3 @@ class KeepKeyQtHandler:
|
|||||||
|
|
||||||
def dialog_stop(self):
|
def dialog_stop(self):
|
||||||
self.d.hide()
|
self.d.hide()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
from PyQt4.Qt import QMessageBox, QDialog, QVBoxLayout, QLabel, QThread, SIGNAL, QGridLayout, QInputDialog, QPushButton
|
from PyQt4.Qt import QMessageBox, QVBoxLayout, QLabel, QThread, SIGNAL, QGridLayout, QInputDialog, QPushButton
|
||||||
import PyQt4.QtCore as QtCore
|
import PyQt4.QtCore as QtCore
|
||||||
from electrum_gui.qt.util import *
|
from electrum_gui.qt.util import *
|
||||||
from electrum_gui.qt.main_window import StatusBarButton, ElectrumWindow
|
from electrum_gui.qt.main_window import StatusBarButton, ElectrumWindow
|
||||||
@ -46,10 +46,7 @@ class TrezorQtHandler:
|
|||||||
return self.passphrase
|
return self.passphrase
|
||||||
|
|
||||||
def pin_dialog(self):
|
def pin_dialog(self):
|
||||||
d = QDialog(None)
|
d = WindowModalDialog(self.win, _("Enter PIN"))
|
||||||
d.setModal(1)
|
|
||||||
d.setWindowTitle(_("Enter PIN"))
|
|
||||||
d.setWindowFlags(d.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
|
|
||||||
matrix = PinMatrixWidget()
|
matrix = PinMatrixWidget()
|
||||||
vbox = QVBoxLayout()
|
vbox = QVBoxLayout()
|
||||||
vbox.addWidget(QLabel(self.message))
|
vbox.addWidget(QLabel(self.message))
|
||||||
@ -67,23 +64,18 @@ class TrezorQtHandler:
|
|||||||
self.passphrase = unicodedata.normalize('NFKD', unicode(passphrase)) if passphrase else ''
|
self.passphrase = unicodedata.normalize('NFKD', unicode(passphrase)) if passphrase else ''
|
||||||
else:
|
else:
|
||||||
assert type(self.win) is InstallWizard
|
assert type(self.win) is InstallWizard
|
||||||
from electrum_gui.qt.password_dialog import make_password_dialog, run_password_dialog
|
from electrum_gui.qt.password_dialog import PasswordDialog
|
||||||
d = QDialog()
|
d = PasswordDialog(self.win, None, None, self.message, False)
|
||||||
d.setModal(1)
|
confirmed, p, passphrase = d.run()
|
||||||
d.setLayout(make_password_dialog(d, None, self.message, False))
|
|
||||||
confirmed, p, passphrase = run_password_dialog(d, None, None)
|
|
||||||
if not confirmed:
|
if not confirmed:
|
||||||
QMessageBox.critical(None, _('Error'), _("Password request canceled"), _('OK'))
|
self.win.show_critical(_("Password request canceled"))
|
||||||
self.passphrase = None
|
self.passphrase = None
|
||||||
else:
|
else:
|
||||||
self.passphrase = unicodedata.normalize('NFKD', unicode(passphrase)) if passphrase else ''
|
self.passphrase = unicodedata.normalize('NFKD', unicode(passphrase)) if passphrase else ''
|
||||||
self.done.set()
|
self.done.set()
|
||||||
|
|
||||||
def message_dialog(self):
|
def message_dialog(self):
|
||||||
self.d = QDialog()
|
self.d = WindowModalDialog(self.win, _('Please Check Trezor Device'))
|
||||||
self.d.setModal(1)
|
|
||||||
self.d.setWindowTitle('Please Check Trezor Device')
|
|
||||||
self.d.setWindowFlags(self.d.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
|
|
||||||
l = QLabel(self.message)
|
l = QLabel(self.message)
|
||||||
vbox = QVBoxLayout(self.d)
|
vbox = QVBoxLayout(self.d)
|
||||||
vbox.addWidget(l)
|
vbox.addWidget(l)
|
||||||
@ -171,7 +163,7 @@ class Plugin(TrezorPlugin):
|
|||||||
return
|
return
|
||||||
get_label = lambda: self.get_client().features.label
|
get_label = lambda: self.get_client().features.label
|
||||||
update_label = lambda: current_label_label.setText("Label: %s" % get_label())
|
update_label = lambda: current_label_label.setText("Label: %s" % get_label())
|
||||||
d = QDialog()
|
d = WindowModalDialog(window, _("Trezor Settings"))
|
||||||
layout = QGridLayout(d)
|
layout = QGridLayout(d)
|
||||||
layout.addWidget(QLabel("Trezor Options"),0,0)
|
layout.addWidget(QLabel("Trezor Options"),0,0)
|
||||||
layout.addWidget(QLabel("ID:"),1,0)
|
layout.addWidget(QLabel("ID:"),1,0)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user