Browse Source

Merge #705: QR code support for BIP78 payjoin receiver in Qt GUI

7414959 QR code support for BIP78 payjoin receiver in Qt GUI (Kristaps Kaupe)
master
Adam Gibson 5 years ago
parent
commit
3b4683527e
No known key found for this signature in database
GPG Key ID: 141001A1AF77F20B
  1. 2
      requirements/gui.txt
  2. 24
      scripts/joinmarket-qt.py
  3. 38
      scripts/qtsupport.py

2
requirements/gui.txt

@ -2,5 +2,5 @@
pywin32; platform_system == "Windows"
PySide2
PyQt5==5.14.2
qrcode[pil]
qrcode
https://github.com/sunu/qt5reactor/archive/58410aaead2185e9917ae9cac9c50fe7b70e4a60.zip#egg=qt5reactor

24
scripts/joinmarket-qt.py

@ -22,7 +22,6 @@ Some widgets copied and modified from https://github.com/spesmilo/electrum
import sys, datetime, os, logging
import platform, json, threading, time
import qrcode
from optparse import OptionParser
from PySide2 import QtCore
@ -31,8 +30,6 @@ from PySide2.QtGui import *
from PySide2.QtWidgets import *
from PIL.ImageQt import ImageQt
if platform.system() == 'Windows':
MONOSPACE_FONT = 'Lucida Console'
elif platform.system() == 'Darwin':
@ -82,7 +79,7 @@ from qtsupport import ScheduleWizard, TumbleRestartWizard, config_tips,\
config_types, QtHandler, XStream, Buttons, OkButton, CancelButton,\
PasswordDialog, MyTreeWidget, JMQtMessageBox, BLUE_FG,\
donation_more_message, BitcoinAmountEdit, JMIntValidator,\
ReceiveBIP78Dialog
ReceiveBIP78Dialog, QRCodePopup
from twisted.internet import task
@ -1302,23 +1299,6 @@ class CoinsTab(QWidget):
lambda: app.clipboard().setText(txid))
menu.exec_(self.cTW.viewport().mapToGlobal(position))
class BitcoinQRCodePopup(QDialog):
def __init__(self, parent, address):
super().__init__(parent)
self.address = address
self.setWindowTitle(address)
img = qrcode.make('bitcoin:' + address)
self.imageLabel = QLabel()
self.imageLabel.setPixmap(QPixmap.fromImage(ImageQt(img)))
layout = QVBoxLayout()
layout.addWidget(self.imageLabel)
self.setLayout(layout)
self.initUI()
def initUI(self):
self.show()
class JMWalletTab(QWidget):
@ -1385,7 +1365,7 @@ class JMWalletTab(QWidget):
menu.exec_(self.walletTree.viewport().mapToGlobal(position))
def openQRCodePopup(self, address):
popup = BitcoinQRCodePopup(self, address)
popup = QRCodePopup(self, address, btc.encode_bip21_uri(address, {}))
popup.show()
def updateWalletInfo(self, walletinfo=None):

38
scripts/qtsupport.py

@ -17,12 +17,15 @@ Qt files for the wizard for initiating a tumbler run.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
import math, re, logging, string
import math, logging, qrcode, re, string
from io import BytesIO
from PySide2 import QtCore
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from jmbitcoin.amount import amount_to_sat, btc_to_sat, sat_to_btc
from jmbitcoin.bip21 import decode_bip21_uri
from jmclient import (jm_single, validate_address, get_tumble_schedule)
@ -943,6 +946,28 @@ class CopyOnClickLineEdit(QLineEdit):
"URI copied to clipboard", mbtype="info")
self.was_copied = True
class QRCodePopup(QDialog):
def __init__(self, parent, title, data):
super().__init__(parent)
self.setWindowTitle(title)
buf = BytesIO()
img = qrcode.make(data)
img.save(buf, "PNG")
self.imageLabel = QLabel()
qt_pixmap = QPixmap()
qt_pixmap.loadFromData(buf.getvalue(), "PNG")
self.imageLabel.setPixmap(qt_pixmap)
layout = QVBoxLayout()
layout.addWidget(self.imageLabel)
self.setLayout(layout)
self.initUI()
def initUI(self):
self.show()
class ReceiveBIP78Dialog(QDialog):
parameter_names = ['Amount to receive', 'Mixdepth']
@ -1015,6 +1040,7 @@ class ReceiveBIP78Dialog(QDialog):
# Give user indication that they
# can quit without cancelling:
self.close_btn.setVisible(True)
self.qr_btn.setVisible(False)
self.btnbox.button(QDialogButtonBox.Cancel).setDisabled(True)
def start_generate(self):
@ -1080,12 +1106,22 @@ class ReceiveBIP78Dialog(QDialog):
self.close_btn = self.btnbox.addButton("C&lose",
QDialogButtonBox.AcceptRole)
self.close_btn.setVisible(False)
self.qr_btn = self.btnbox.addButton("Show &QR code",
QDialogButtonBox.ActionRole)
layout.addWidget(self.btnbox, i+4, 0)
# note that we don't use a standard 'Close' button because
# it is also associated with 'rejection' (and we don't use "OK" because
# concept doesn't quite fit here:
self.btnbox.rejected.connect(self.shutdown_actions)
self.generate_btn.clicked.connect(self.start_generate)
self.qr_btn.clicked.connect(self.open_qr_code_popup)
# does not trigger cancel_fn callback:
self.close_btn.clicked.connect(self.close)
return layout
def open_qr_code_popup(self):
bip21_uri = self.bip21_widget.text()
if bip21_uri:
parsed_uri = decode_bip21_uri(bip21_uri)
popup = QRCodePopup(self, parsed_uri['address'], bip21_uri)
popup.show()

Loading…
Cancel
Save