URI: 
       tCombine QTHandlers for KeepKey and Trezor - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 7b5f3884fadcf1938bec8f60049b1f4101cb8b14
   DIR parent 39c1893a747c7e209aad80f551a7eb08e048c4d4
  HTML Author: Neil Booth <kyuupichan@gmail.com>
       Date:   Sat, 26 Dec 2015 17:40:12 +0900
       
       Combine QTHandlers for KeepKey and Trezor
       
       Again they do the same thing, so share the code
       
       Diffstat:
         M plugins/keepkey/qt.py               |      97 ++++---------------------------
         M plugins/trezor/qt.py                |      84 +++----------------------------
         A plugins/trezor/qt_generic.py        |      91 +++++++++++++++++++++++++++++++
       
       3 files changed, 107 insertions(+), 165 deletions(-)
       ---
   DIR diff --git a/plugins/keepkey/qt.py b/plugins/keepkey/qt.py
       t@@ -2,14 +2,20 @@ from PyQt4.Qt import QVBoxLayout, QLabel, SIGNAL, QGridLayout, QInputDialog, QPu
        import PyQt4.QtCore as QtCore
        from electrum_gui.qt.util import *
        from electrum_gui.qt.main_window import StatusBarButton, ElectrumWindow
       -from electrum_gui.qt.installwizard import InstallWizard
       -from keepkeylib.qt.pinmatrix import PinMatrixWidget
        
        from functools import partial
       +import unicodedata
        
       -from keepkey import KeepKeyPlugin, KeepKeyWallet
       -from electrum.plugins import hook
        from electrum.i18n import _
       +from electrum.plugins import hook
       +
       +from plugins.trezor.qt_generic import QtHandler
       +from keepkeylib.qt.pinmatrix import PinMatrixWidget
       +from keepkey import KeepKeyPlugin, KeepKeyWallet
       +
       +class KeepKeyQtHandler(QtHandler):
       +    device = 'KeepKey'
       +    pin_matrix_widget_class = PinMatrixWidget
        
        class Plugin(KeepKeyPlugin):
        
       t@@ -90,86 +96,3 @@ class Plugin(KeepKeyPlugin):
                layout.addWidget(current_label_label,3,0)
                layout.addWidget(change_label_button,3,1)
                d.exec_()
       -
       -
       -class KeepKeyQtHandler:
       -
       -    def __init__(self, win):
       -        self.win = win
       -        self.win.connect(win, SIGNAL('keepkey_done'), self.dialog_stop)
       -        self.win.connect(win, SIGNAL('message_dialog'), self.message_dialog)
       -        self.win.connect(win, SIGNAL('pin_dialog'), self.pin_dialog)
       -        self.win.connect(win, SIGNAL('passphrase_dialog'), self.passphrase_dialog)
       -        self.done = threading.Event()
       -        self.d = None
       -
       -    def stop(self):
       -        self.win.emit(SIGNAL('keepkey_done'))
       -
       -    def show_message(self, msg_code, msg, client):
       -        self.messsage_code = msg_code
       -        self.message = msg
       -        self.client = client
       -        self.win.emit(SIGNAL('message_dialog'))
       -
       -    def get_pin(self, msg):
       -        self.done.clear()
       -        self.message = msg
       -        self.win.emit(SIGNAL('pin_dialog'))
       -        self.done.wait()
       -        return self.response
       -
       -    def get_passphrase(self, msg):
       -        self.done.clear()
       -        self.message = msg
       -        self.win.emit(SIGNAL('passphrase_dialog'))
       -        self.done.wait()
       -        return self.passphrase
       -
       -    def pin_dialog(self):
       -        d = WindowModalDialog(self.win, _("Enter PIN"))
       -        matrix = PinMatrixWidget()
       -        vbox = QVBoxLayout()
       -        vbox.addWidget(QLabel(self.message))
       -        vbox.addWidget(matrix)
       -        vbox.addLayout(Buttons(CancelButton(d), OkButton(d)))
       -        d.setLayout(vbox)
       -        if not d.exec_():
       -            self.response = None
       -        self.response = str(matrix.get_value())
       -        self.done.set()
       -
       -    def passphrase_dialog(self):
       -        if type(self.win) is ElectrumWindow:
       -            passphrase = self.win.password_dialog(_("Please enter your KeepKey passphrase"))
       -            self.passphrase = unicodedata.normalize('NFKD', unicode(passphrase)) if passphrase else ''
       -        else:
       -            assert type(self.win) is InstallWizard
       -            from electrum_gui.qt.password_dialog import PasswordDialog
       -            d = PasswordDialog(self.win, None, None, self.message, False)
       -            confirmed, p, passphrase = d.run()
       -            if not confirmed:
       -                self.win.show_critical(_("Password request canceled"))
       -                self.passphrase = None
       -            else:
       -                self.passphrase = unicodedata.normalize('NFKD', unicode(passphrase)) if passphrase else ''
       -        self.done.set()
       -
       -    def message_dialog(self):
       -        # Called more than once during signing, to confirm output and fee
       -        self.dialog_stop()
       -        self.d = WindowModalDialog(self.win, _('Please Check KeepKey Device'))
       -        l = QLabel(self.message)
       -        vbox = QVBoxLayout(self.d)
       -        vbox.addWidget(l)
       -
       -        if self.messsage_code in (3, 8):
       -            vbox.addLayout(Buttons(CancelButton(self.d)))
       -            self.d.connect(self.d, SIGNAL('rejected()'), self.client.cancel)
       -
       -        self.d.show()
       -
       -    def dialog_stop(self):
       -        if self.d:
       -            self.d.hide()
       -            self.d = None
   DIR diff --git a/plugins/trezor/qt.py b/plugins/trezor/qt.py
       t@@ -2,92 +2,20 @@ from PyQt4.Qt import QVBoxLayout, QLabel, SIGNAL, QGridLayout, QInputDialog, QPu
        import PyQt4.QtCore as QtCore
        from electrum_gui.qt.util import *
        from electrum_gui.qt.main_window import StatusBarButton, ElectrumWindow
       -from electrum_gui.qt.installwizard import InstallWizard
       -from trezorlib.qt.pinmatrix import PinMatrixWidget
       -
        
        from functools import partial
        import unicodedata
        
        from electrum.i18n import _
       -from electrum.plugins import hook, always_hook, run_hook
       +from electrum.plugins import hook
        
       +from plugins.trezor.qt_generic import QtHandler
        from trezor import TrezorPlugin, TrezorWallet
       +from trezorlib.qt.pinmatrix import PinMatrixWidget
        
       -class TrezorQtHandler:
       -
       -    def __init__(self, win):
       -        self.win = win
       -        self.win.connect(win, SIGNAL('trezor_done'), self.dialog_stop)
       -        self.win.connect(win, SIGNAL('message_dialog'), self.message_dialog)
       -        self.win.connect(win, SIGNAL('pin_dialog'), self.pin_dialog)
       -        self.win.connect(win, SIGNAL('passphrase_dialog'), self.passphrase_dialog)
       -        self.done = threading.Event()
       -        self.d = None
       -
       -    def stop(self):
       -        self.win.emit(SIGNAL('trezor_done'))
       -
       -    def show_message(self, msg):
       -        self.message = msg
       -        self.win.emit(SIGNAL('message_dialog'))
       -
       -    def get_pin(self, msg):
       -        self.done.clear()
       -        self.message = msg
       -        self.win.emit(SIGNAL('pin_dialog'))
       -        self.done.wait()
       -        return self.response
       -
       -    def get_passphrase(self, msg):
       -        self.done.clear()
       -        self.message = msg
       -        self.win.emit(SIGNAL('passphrase_dialog'))
       -        self.done.wait()
       -        return self.passphrase
       -
       -    def pin_dialog(self):
       -        d = WindowModalDialog(self.win, _("Enter PIN"))
       -        matrix = PinMatrixWidget()
       -        vbox = QVBoxLayout()
       -        vbox.addWidget(QLabel(self.message))
       -        vbox.addWidget(matrix)
       -        vbox.addLayout(Buttons(CancelButton(d), OkButton(d)))
       -        d.setLayout(vbox)
       -        if not d.exec_():
       -            self.response = None
       -        self.response = str(matrix.get_value())
       -        self.done.set()
       -
       -    def passphrase_dialog(self):
       -        if type(self.win) is ElectrumWindow:
       -            passphrase = self.win.password_dialog(_("Please enter your Trezor passphrase"))
       -            self.passphrase = unicodedata.normalize('NFKD', unicode(passphrase)) if passphrase else ''
       -        else:
       -            assert type(self.win) is InstallWizard
       -            from electrum_gui.qt.password_dialog import PasswordDialog
       -            d = PasswordDialog(self.win, None, None, self.message, False)
       -            confirmed, p, passphrase = d.run()
       -            if not confirmed:
       -                self.win.show_critical(_("Password request canceled"))
       -                self.passphrase = None
       -            else:
       -                self.passphrase = unicodedata.normalize('NFKD', unicode(passphrase)) if passphrase else ''
       -        self.done.set()
       -
       -    def message_dialog(self):
       -        # Called more than once during signing, to confirm output and fee
       -        self.dialog_stop()
       -        self.d = WindowModalDialog(self.win, _('Please Check Trezor Device'))
       -        l = QLabel(self.message)
       -        vbox = QVBoxLayout(self.d)
       -        vbox.addWidget(l)
       -        self.d.show()
       -
       -    def dialog_stop(self):
       -        if self.d:
       -            self.d.hide()
       -            self.d = None
       +class TrezorQtHandler(QtHandler):
       +    device = 'Trezor'
       +    pin_matrix_widget_class = PinMatrixWidget
        
        class Plugin(TrezorPlugin):
        
   DIR diff --git a/plugins/trezor/qt_generic.py b/plugins/trezor/qt_generic.py
       t@@ -0,0 +1,91 @@
       +from unicodedata import normalize
       +import threading
       +
       +from PyQt4.Qt import QVBoxLayout, QLabel, SIGNAL
       +import PyQt4.QtCore as QtCore
       +from electrum_gui.qt.main_window import ElectrumWindow
       +from electrum_gui.qt.installwizard import InstallWizard
       +from electrum_gui.qt.password_dialog import PasswordDialog
       +from electrum_gui.qt.util import *
       +
       +from electrum.i18n import _
       +
       +class QtHandler:
       +    '''An interface between the GUI (here, QT) and the device handling
       +    logic for handling I/O.  This is a generic implementation of the
       +    Trezor protocol; derived classes can customize it.'''
       +
       +    # Derived classes must provide:
       +    #   device      a string, e.g. "Trezor"
       +    #   pin_matrix_widget_class
       +
       +    def __init__(self, win):
       +        win.connect(win, SIGNAL('message_done'), self.dialog_stop)
       +        win.connect(win, SIGNAL('message_dialog'), self.message_dialog)
       +        win.connect(win, SIGNAL('pin_dialog'), self.pin_dialog)
       +        win.connect(win, SIGNAL('passphrase_dialog'), self.passphrase_dialog)
       +        self.win = win
       +        self.done = threading.Event()
       +        self.dialog = None
       +
       +    def stop(self):
       +        self.win.emit(SIGNAL('message_done'))
       +
       +    def show_message(self, msg):
       +        self.win.emit(SIGNAL('message_dialog'), msg)
       +
       +    def get_pin(self, msg):
       +        self.done.clear()
       +        self.win.emit(SIGNAL('pin_dialog'), msg)
       +        self.done.wait()
       +        return self.response
       +
       +    def get_passphrase(self, msg):
       +        self.done.clear()
       +        self.win.emit(SIGNAL('passphrase_dialog'), msg)
       +        self.done.wait()
       +        return self.passphrase
       +
       +    def pin_dialog(self, msg):
       +        d = WindowModalDialog(self.win, _("Enter PIN"))
       +        matrix = self.pin_matrix_widget_class()
       +        vbox = QVBoxLayout()
       +        vbox.addWidget(QLabel(msg))
       +        vbox.addWidget(matrix)
       +        vbox.addLayout(Buttons(CancelButton(d), OkButton(d)))
       +        d.setLayout(vbox)
       +        if not d.exec_():
       +            self.response = None  # FIXME: this is lost?
       +        self.response = str(matrix.get_value())
       +        self.done.set()
       +
       +    def passphrase_dialog(self, msg):
       +        if type(self.win) is ElectrumWindow:
       +            msg = _("Please enter your %s passphrase") % self.device
       +            passphrase = self.win.password_dialog(msg)
       +        else:
       +            assert type(self.win) is InstallWizard
       +            d = PasswordDialog(self.win, None, None, msg, False)
       +            confirmed, p, passphrase = d.run()
       +
       +        if passphrase is None:
       +            self.win.show_critical(_("Passphrase request canceled"))
       +        else:
       +            passphrase = normalize('NFKD', unicode(passphrase))
       +        self.passphrase = passphrase
       +        self.done.set()
       +
       +    def message_dialog(self, msg):
       +        # Called more than once during signing, to confirm output and fee
       +        self.dialog_stop()
       +        msg = _('Please check your %s Device') % self.device
       +        self.dialog = WindowModalDialog(self.win, msg)
       +        l = QLabel(msg)
       +        vbox = QVBoxLayout(self.dialog)
       +        vbox.addWidget(l)
       +        self.dialog.show()
       +
       +    def dialog_stop(self):
       +        if self.dialog:
       +            self.dialog.hide()
       +            self.dialog = None