commit
bfbd6f0e9d
|
@ -128,7 +128,7 @@ class InstallWizard(QDialog):
|
|||
def enter_seed_dialog(self, msg, sid, func=None):
|
||||
if func is None:
|
||||
func = self.is_any
|
||||
vbox, seed_e = seed_dialog.enter_seed_box(msg, sid)
|
||||
vbox, seed_e = seed_dialog.enter_seed_box(msg, self, sid)
|
||||
vbox.addStretch(1)
|
||||
hbox, button = ok_cancel_buttons2(self, _('Next'))
|
||||
vbox.addLayout(hbox)
|
||||
|
|
|
@ -45,7 +45,7 @@ from electrum import Imported_Wallet
|
|||
from amountedit import AmountEdit, BTCAmountEdit, MyLineEdit
|
||||
from network_dialog import NetworkDialog
|
||||
from qrcodewidget import QRCodeWidget, QRDialog
|
||||
from qrtextedit import QRTextEdit
|
||||
from qrtextedit import ScanQRTextEdit, ShowQRTextEdit
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
|
@ -1828,15 +1828,36 @@ class ElectrumWindow(QMainWindow):
|
|||
|
||||
main_layout = QGridLayout()
|
||||
mpk_dict = self.wallet.get_master_public_keys()
|
||||
i = 0
|
||||
for key, value in mpk_dict.items():
|
||||
main_layout.addWidget(QLabel(key), i, 0)
|
||||
mpk_text = QRTextEdit()
|
||||
mpk_text.setReadOnly(True)
|
||||
# filter out the empty keys (PendingAccount)
|
||||
mpk_dict = {acc:mpk for acc,mpk in mpk_dict.items() if mpk}
|
||||
|
||||
# only show the combobox in case multiple accounts are available
|
||||
if len(mpk_dict) > 1:
|
||||
main_layout.addWidget(QLabel(_("Select Account")), 0, 0)
|
||||
|
||||
combobox = QComboBox()
|
||||
for name in mpk_dict:
|
||||
combobox.addItem(name)
|
||||
combobox.setCurrentIndex(0)
|
||||
main_layout.addWidget(combobox, 1, 0)
|
||||
|
||||
account = unicode(combobox.currentText())
|
||||
mpk_text = ShowQRTextEdit(text=mpk_dict[account])
|
||||
mpk_text.setMaximumHeight(170)
|
||||
mpk_text.setText(value)
|
||||
main_layout.addWidget(mpk_text, i + 1, 0)
|
||||
i += 2
|
||||
mpk_text.selectAll() # for easy copying
|
||||
main_layout.addWidget(mpk_text, 2, 0)
|
||||
|
||||
def show_mpk(account):
|
||||
mpk = mpk_dict.get(unicode(account), "")
|
||||
mpk_text.setText(mpk)
|
||||
|
||||
combobox.currentIndexChanged[str].connect(lambda acc: show_mpk(acc))
|
||||
elif len(mpk_dict) == 1:
|
||||
mpk = mpk_dict.values()[0]
|
||||
mpk_text = ShowQRTextEdit(text=mpk)
|
||||
mpk_text.setMaximumHeight(170)
|
||||
mpk_text.selectAll() # for easy copying
|
||||
main_layout.addWidget(mpk_text, 2, 0)
|
||||
|
||||
vbox = QVBoxLayout()
|
||||
vbox.addLayout(main_layout)
|
||||
|
@ -1845,7 +1866,6 @@ class ElectrumWindow(QMainWindow):
|
|||
dialog.setLayout(vbox)
|
||||
dialog.exec_()
|
||||
|
||||
|
||||
@protected
|
||||
def show_seed_dialog(self, password):
|
||||
if not self.wallet.has_seed():
|
||||
|
@ -1900,9 +1920,7 @@ class ElectrumWindow(QMainWindow):
|
|||
vbox = QVBoxLayout()
|
||||
vbox.addWidget( QLabel(_("Address") + ': ' + address))
|
||||
vbox.addWidget( QLabel(_("Public key") + ':'))
|
||||
keys = QRTextEdit()
|
||||
keys.setReadOnly(True)
|
||||
keys.setText('\n'.join(pubkey_list))
|
||||
keys = ShowQRTextEdit(text='\n'.join(pubkey_list))
|
||||
vbox.addWidget(keys)
|
||||
vbox.addLayout(close_button(d))
|
||||
d.setLayout(vbox)
|
||||
|
@ -1924,9 +1942,7 @@ class ElectrumWindow(QMainWindow):
|
|||
vbox = QVBoxLayout()
|
||||
vbox.addWidget( QLabel(_("Address") + ': ' + address))
|
||||
vbox.addWidget( QLabel(_("Private key") + ':'))
|
||||
keys = QRTextEdit()
|
||||
keys.setReadOnly(True)
|
||||
keys.setText('\n'.join(pk_list))
|
||||
keys = ShowQRTextEdit(text='\n'.join(pk_list))
|
||||
vbox.addWidget(keys)
|
||||
vbox.addLayout(close_button(d))
|
||||
d.setLayout(vbox)
|
||||
|
@ -2128,6 +2144,12 @@ class ElectrumWindow(QMainWindow):
|
|||
|
||||
def read_tx_from_qrcode(self):
|
||||
from electrum import qrscanner
|
||||
if qrscanner.proc is None:
|
||||
try:
|
||||
qrscanner.init(self.config)
|
||||
except Exception, e:
|
||||
QMessageBox.warning(self, _('Error'), _(e), _('OK'))
|
||||
return
|
||||
try:
|
||||
data = qrscanner.scan_qr(self.config)
|
||||
except BaseException, e:
|
||||
|
@ -2135,12 +2157,14 @@ class ElectrumWindow(QMainWindow):
|
|||
return
|
||||
if not data:
|
||||
return
|
||||
# if the user scanned a bitcoin URI
|
||||
if data.startswith("bitcoin:"):
|
||||
self.pay_from_URI(data)
|
||||
return
|
||||
# else if the user scanned an offline signed tx
|
||||
# transactions are binary, but qrcode seems to return utf8...
|
||||
z = data.decode('utf8')
|
||||
s = ''
|
||||
for b in z:
|
||||
s += chr(ord(b))
|
||||
data = s.encode('hex')
|
||||
data = ''.join(chr(ord(b)) for b in z).encode('hex')
|
||||
tx = self.tx_from_text(data)
|
||||
if not tx:
|
||||
return
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
from PyQt4.QtCore import *
|
||||
from PyQt4.QtGui import *
|
||||
from qrtextedit import QRTextEdit
|
||||
from qrtextedit import ScanQRTextEdit
|
||||
|
||||
import re
|
||||
from decimal import Decimal
|
||||
|
@ -30,11 +30,9 @@ RE_ALIAS = '(.*?)\s*\<([1-9A-HJ-NP-Za-km-z]{26,})\>'
|
|||
frozen_style = "QWidget { background-color:none; border:none;}"
|
||||
normal_style = "QPlainTextEdit { }"
|
||||
|
||||
class PayToEdit(QRTextEdit):
|
||||
|
||||
class PayToEdit(ScanQRTextEdit):
|
||||
def __init__(self, win):
|
||||
QRTextEdit.__init__(self)
|
||||
self.win = win
|
||||
super(PayToEdit,self).__init__(win=win)
|
||||
self.amount_edit = win.amount_e
|
||||
self.document().contentsChanged.connect(self.update_size)
|
||||
self.heightMin = 0
|
||||
|
@ -235,3 +233,10 @@ class PayToEdit(QRTextEdit):
|
|||
cr = self.cursorRect()
|
||||
cr.setWidth(self.c.popup().sizeHintForColumn(0) + self.c.popup().verticalScrollBar().sizeHint().width())
|
||||
self.c.complete(cr)
|
||||
|
||||
|
||||
def qr_input(self):
|
||||
data = super(PayToEdit,self).qr_input()
|
||||
if data.startswith("bitcoin:"):
|
||||
self.scan_f(data)
|
||||
# TODO: update fee
|
||||
|
|
|
@ -114,7 +114,7 @@ class QRDialog(QDialog):
|
|||
|
||||
def copy_to_clipboard():
|
||||
bmp.save_qrcode(qrw.qr, filename)
|
||||
self.parent().app.clipboard().setImage(QImage(filename))
|
||||
QApplication.clipboard().setImage(QImage(filename))
|
||||
QMessageBox.information(None, _('Message'), _("QR code saved to clipboard"), _('OK'))
|
||||
|
||||
b = QPushButton(_("Copy"))
|
||||
|
|
|
@ -3,14 +3,13 @@ from PyQt4.QtGui import *
|
|||
from PyQt4.QtCore import *
|
||||
|
||||
class QRTextEdit(QPlainTextEdit):
|
||||
|
||||
"""Abstract class for QR-code related TextEdits. Do not use directly."""
|
||||
def __init__(self, text=None):
|
||||
QPlainTextEdit.__init__(self, text)
|
||||
super(QRTextEdit, self).__init__(text)
|
||||
self.button = QToolButton(self)
|
||||
self.button.setIcon(QIcon(":icons/qrcode.png"))
|
||||
self.button.setStyleSheet("QToolButton { border: none; padding: 0px; }")
|
||||
self.button.setVisible(True)
|
||||
self.button.clicked.connect(lambda: self.qr_show() if self.isReadOnly() else self.qr_input())
|
||||
self.setText = self.setPlainText
|
||||
|
||||
def resizeEvent(self, e):
|
||||
|
@ -21,13 +20,11 @@ class QRTextEdit(QPlainTextEdit):
|
|||
(self.rect().bottom() - frameWidth - sz.height()))
|
||||
return o
|
||||
|
||||
def contextMenuEvent(self, e):
|
||||
m = self.createStandardContextMenu()
|
||||
if self.isReadOnly():
|
||||
m.addAction(_("Show as QR code"), self.qr_show)
|
||||
else:
|
||||
m.addAction(_("Read QR code"), self.qr_input)
|
||||
m.exec_(e.globalPos())
|
||||
class ShowQRTextEdit(QRTextEdit):
|
||||
def __init__(self, text=None):
|
||||
super(ShowQRTextEdit, self).__init__(text)
|
||||
self.setReadOnly(1)
|
||||
self.button.clicked.connect(self.qr_show)
|
||||
|
||||
def qr_show(self):
|
||||
from qrcodewidget import QRDialog
|
||||
|
@ -37,13 +34,42 @@ class QRTextEdit(QPlainTextEdit):
|
|||
s = unicode(self.toPlainText())
|
||||
QRDialog(s).exec_()
|
||||
|
||||
def contextMenuEvent(self, e):
|
||||
m = self.createStandardContextMenu()
|
||||
m.addAction(_("Show as QR code"), self.qr_show)
|
||||
m.exec_(e.globalPos())
|
||||
|
||||
|
||||
class ScanQRTextEdit(QRTextEdit):
|
||||
def __init__(self, win, text=""):
|
||||
super(ScanQRTextEdit,self).__init__(text)
|
||||
self.setReadOnly(0)
|
||||
self.win = win
|
||||
assert win, "You must pass a window with access to the config to ScanQRTextEdit constructor."
|
||||
if win:
|
||||
assert hasattr(win,"config"), "You must pass a window with access to the config to ScanQRTextEdit constructor."
|
||||
self.button.clicked.connect(self.qr_input)
|
||||
|
||||
|
||||
def qr_input(self):
|
||||
from electrum import qrscanner
|
||||
if qrscanner.proc is None:
|
||||
try:
|
||||
qrscanner.init(self.win.config)
|
||||
except Exception, e:
|
||||
QMessageBox.warning(self, _('Error'), _(e), _('OK'))
|
||||
return
|
||||
try:
|
||||
data = qrscanner.scan_qr(self.win.config)
|
||||
except BaseException, e:
|
||||
QMessageBox.warning(self.win, _('Error'), _(e), _('OK'))
|
||||
QMessageBox.warning(self, _('Error'), _(e), _('OK'))
|
||||
return
|
||||
if type(data) != str:
|
||||
return
|
||||
self.setText(data)
|
||||
return data
|
||||
|
||||
def contextMenuEvent(self, e):
|
||||
m = self.createStandardContextMenu()
|
||||
m.addAction(_("Read QR code"), self.qr_input)
|
||||
m.exec_(e.globalPos())
|
||||
|
|
|
@ -23,7 +23,7 @@ from electrum.i18n import _
|
|||
from electrum import mnemonic
|
||||
from qrcodewidget import QRCodeWidget, QRDialog
|
||||
from util import close_button
|
||||
from qrtextedit import QRTextEdit
|
||||
from qrtextedit import ShowQRTextEdit, ScanQRTextEdit
|
||||
|
||||
class SeedDialog(QDialog):
|
||||
def __init__(self, parent, seed, imported_keys):
|
||||
|
@ -72,15 +72,13 @@ def show_seed_box(seed, sid=None):
|
|||
+ _("If you ever need to recover your wallet from seed, you will need both this seed and your cold seed.") + " " \
|
||||
|
||||
label1 = QLabel(msg+ ":")
|
||||
seed_text = QRTextEdit(seed)
|
||||
seed_text.setReadOnly(True)
|
||||
seed_text = ShowQRTextEdit(text=seed)
|
||||
seed_text.setMaximumHeight(130)
|
||||
|
||||
label2 = QLabel(msg2)
|
||||
label2.setWordWrap(True)
|
||||
|
||||
logo = QLabel()
|
||||
|
||||
logo.setPixmap(QPixmap(icon_filename(sid)).scaledToWidth(56))
|
||||
logo.setMaximumWidth(60)
|
||||
|
||||
|
@ -96,8 +94,7 @@ def show_seed_box(seed, sid=None):
|
|||
return vbox
|
||||
|
||||
|
||||
def enter_seed_box(msg, sid=None):
|
||||
|
||||
def enter_seed_box(msg, window, sid=None):
|
||||
vbox = QVBoxLayout()
|
||||
logo = QLabel()
|
||||
logo.setPixmap(QPixmap(icon_filename(sid)).scaledToWidth(56))
|
||||
|
@ -106,7 +103,7 @@ def enter_seed_box(msg, sid=None):
|
|||
label = QLabel(msg)
|
||||
label.setWordWrap(True)
|
||||
|
||||
seed_e = QRTextEdit()
|
||||
seed_e = ScanQRTextEdit(win=window)
|
||||
seed_e.setMaximumHeight(100)
|
||||
seed_e.setTabChangesFocus(True)
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ def line_dialog(parent, title, label, ok_label, default=None):
|
|||
return unicode(txt.text())
|
||||
|
||||
def text_dialog(parent, title, label, ok_label, default=None):
|
||||
from qrtextedit import QRTextEdit
|
||||
from qrtextedit import ScanQRTextEdit
|
||||
dialog = QDialog(parent)
|
||||
dialog.setMinimumWidth(500)
|
||||
dialog.setWindowTitle(title)
|
||||
|
@ -145,7 +145,7 @@ def text_dialog(parent, title, label, ok_label, default=None):
|
|||
l = QVBoxLayout()
|
||||
dialog.setLayout(l)
|
||||
l.addWidget(QLabel(label))
|
||||
txt = QRTextEdit()
|
||||
txt = ScanQRTextEdit(parent)
|
||||
if default:
|
||||
txt.setText(default)
|
||||
l.addWidget(txt)
|
||||
|
|
|
@ -6,28 +6,37 @@ try:
|
|||
except ImportError:
|
||||
zbar = None
|
||||
|
||||
proc = None
|
||||
|
||||
def scan_qr(config):
|
||||
def init(config):
|
||||
if not zbar:
|
||||
raise BaseException("\n".join([_("Cannot start QR scanner."),_("The zbar package is not available."),_("On Linux, try 'sudo apt-get install python-zbar'")]))
|
||||
device = config.get("video_device", "default")
|
||||
if device == 'default':
|
||||
device = ''
|
||||
global proc
|
||||
proc = zbar.Processor()
|
||||
proc.init(video_device=device)
|
||||
|
||||
def scan_qr(self):
|
||||
if not zbar:
|
||||
raise BaseException("\n".join([_("Cannot start QR scanner."),_("The zbar package is not available."),_("On Linux, try 'sudo apt-get install python-zbar'")]))
|
||||
if proc is None:
|
||||
raise BaseException("Start proc first")
|
||||
proc.visible = True
|
||||
while True:
|
||||
try:
|
||||
proc.process_one()
|
||||
except Exception:
|
||||
# User closed the preview window
|
||||
return {}
|
||||
return ""
|
||||
for r in proc.results:
|
||||
if str(r.type) != 'QRCODE':
|
||||
continue
|
||||
# hiding the preview window stops the camera
|
||||
proc.visible = False
|
||||
return r.data
|
||||
|
||||
|
||||
def _find_system_cameras():
|
||||
device_root = "/sys/class/video4linux"
|
||||
devices = {} # Name -> device
|
||||
|
|
Loading…
Reference in New Issue