URI: 
       tSome work on multisig. - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 0219687d4168b80fa85b9dace7c17553a3a92af4
   DIR parent 576500aa2920ac657ae04723472178b213360ce2
  HTML Author: Neil Booth <kyuupichan@gmail.com>
       Date:   Wed, 13 Jan 2016 19:20:58 +0900
       
       Some work on multisig.
       
       Diffstat:
         M gui/qt/installwizard.py             |      82 +++++++++++--------------------
         M gui/qt/seed_dialog.py               |      91 +++++++++++++++++--------------
         M gui/qt/util.py                      |      10 +++++++---
         M plugins/trustedcoin/qt.py           |       2 +-
       
       4 files changed, 89 insertions(+), 96 deletions(-)
       ---
   DIR diff --git a/gui/qt/installwizard.py b/gui/qt/installwizard.py
       t@@ -7,7 +7,7 @@ import PyQt4.QtCore as QtCore
        import electrum
        from electrum.i18n import _
        
       -import seed_dialog
       +from seed_dialog import SeedDisplayLayout, SeedWarningLayout, SeedInputLayout
        from network_dialog import NetworkDialog
        from util import *
        from password_dialog import PasswordLayout, PW_NEW, PW_PASSPHRASE
       t@@ -32,6 +32,8 @@ class CosignWidget(QWidget):
                QWidget.__init__(self)
                self.R = QRect(0, 0, self.size, self.size)
                self.setGeometry(self.R)
       +        self.setMinimumHeight(self.size)
       +        self.setMaximumHeight(self.size)
                self.m = m
                self.n = n
        
       t@@ -74,8 +76,7 @@ class InstallWizard(WindowModalDialog, WizardBase):
                self.setMinimumSize(518, 360)
                self.setMaximumSize(518, 360)
                self.connect(self, QtCore.SIGNAL('accept'), self.accept)
       -        self.title = QLabel()
       -        self.title.setWordWrap(True)
       +        self.title = WWLabel()
                self.main_widget = QWidget()
                self.cancel_button = QPushButton(_("Cancel"), self)
                self.next_button = QPushButton(_("Next"), self)
       t@@ -100,13 +101,12 @@ class InstallWizard(WindowModalDialog, WizardBase):
                icon_vbox.addStretch(1)
                hbox = QHBoxLayout()
                hbox.addLayout(icon_vbox)
       +        hbox.addSpacing(5)
                hbox.addLayout(inner_vbox)
                hbox.setStretchFactor(inner_vbox, 1)
                outer_vbox.addLayout(hbox)
                outer_vbox.addLayout(Buttons(self.cancel_button, self.next_button))
                self.set_icon(':icons/electrum.png')
       -        self.show()
       -        self.raise_()
        
            def set_icon(self, filename):
                prior_filename, self.icon_filename = self.icon_filename, filename
       t@@ -120,6 +120,9 @@ class InstallWizard(WindowModalDialog, WizardBase):
                prior_layout = self.main_widget.layout()
                if prior_layout:
                    QWidget().setLayout(prior_layout)
       +        else:
       +            self.show()
       +            self.raise_()
                self.main_widget.setLayout(layout)
                self.cancel_button.setEnabled(True)
                self.next_button.setEnabled(True)
       t@@ -155,7 +158,7 @@ class InstallWizard(WindowModalDialog, WizardBase):
        
            def request_seed(self, title, is_valid=None):
                is_valid = is_valid or Wallet.is_any
       -        slayout = seed_dialog.SeedLayout(None)
       +        slayout = SeedInputLayout()
                self.next_button.setEnabled(False)
                def sanitized_seed():
                    return clean_text(slayout.seed_edit())
       t@@ -167,7 +170,7 @@ class InstallWizard(WindowModalDialog, WizardBase):
        
            def show_seed(self, seed):
                title =  _("Your wallet generation seed is:")
       -        slayout = seed_dialog.SeedLayout(seed)
       +        slayout = SeedWarningLayout(seed)
                self.set_main_layout(slayout.layout(), title)
        
            def verify_seed(self, seed, is_valid=None):
       t@@ -185,11 +188,8 @@ class InstallWizard(WindowModalDialog, WizardBase):
                self.verify_seed(seed, is_valid)
        
            def pw_layout(self, msg, kind):
       -        hbox = QHBoxLayout()
                playout = PasswordLayout(None, msg, kind, self.next_button)
       -        hbox.addLayout(playout.layout())
       -        #hbox.addStretch(1)
       -        self.set_main_layout(hbox)
       +        self.set_main_layout(playout.layout())
                return playout.new_password()
        
            def request_passphrase(self, device_text, restore=True):
       t@@ -234,13 +234,6 @@ class InstallWizard(WindowModalDialog, WizardBase):
                self.please_wait.setText(MSG_GENERATING_WAIT)
                self.refresh_gui()
        
       -    def set_layout(self, layout):
       -        w = QWidget()
       -        w.setLayout(layout)
       -        self.stack.addWidget(w)
       -        self.stack.setCurrentWidget(w)
       -        self.show()
       -
            def query_create_or_restore(self, wallet_kinds):
                """Ask the user what they want to do, and which wallet kind.
                wallet_kinds is an array of translated wallet descriptions.
       t@@ -264,37 +257,30 @@ class InstallWizard(WindowModalDialog, WizardBase):
            def request_many(self, n, xpub_hot=None):
                vbox = QVBoxLayout()
                scroll = QScrollArea()
       -        scroll.setEnabled(True)
                scroll.setWidgetResizable(True)
       +        scroll.setFrameShape(QFrame.NoFrame)
                vbox.addWidget(scroll)
        
                w = QWidget()
       +        innerVbox = QVBoxLayout(w)
                scroll.setWidget(w)
        
       -        innerVbox = QVBoxLayout()
       -        w.setLayout(innerVbox)
       -
                entries = []
       +
                if xpub_hot:
       -            vbox0 = seed_dialog.show_seed_box(MSG_SHOW_MPK, xpub_hot, 'hot')
       +            layout = SeedDisplayLayout(xpub_hot, title=MSG_SHOW_MPK, sid='hot')
                else:
       -            vbox0, seed_e1 = seed_dialog.enter_seed_box(MSG_ENTER_SEED_OR_MPK, self, 'hot')
       -            entries.append(seed_e1)
       -        innerVbox.addLayout(vbox0)
       +            layout = SeedInputLayout(title=MSG_ENTER_SEED_OR_MPK, sid='hot')
       +            entries.append(slayout.seed_edit())
       +        innerVbox.addLayout(layout.layout())
        
                for i in range(n):
       -            if xpub_hot:
       -                msg = MSG_COSIGNER % (i + 1)
       -            else:
       -                msg = MSG_ENTER_SEED_OR_MPK
       -            vbox2, seed_e2 = seed_dialog.enter_seed_box(msg, self, 'cold')
       -            innerVbox.addLayout(vbox2)
       -            entries.append(seed_e2)
       +            msg = MSG_COSIGNER % (i + 1) if xpub_hot else MSG_ENTER_SEED_OR_MPK
       +            layout = SeedInputLayout(title=msg, sid='cold')
       +            innerVbox.addLayout(layout.layout())
       +            entries.append(layout.seed_edit())
        
       -        vbox.addStretch(1)
       -        button = OkButton(self, _('Next'))
       -        vbox.addLayout(Buttons(CancelButton(self), button))
       -        button.setEnabled(False)
       +        self.next_button.setEnabled(False)
                def get_texts():
                    return [clean_text(entry) for entry in entries]
                def set_enabled():
       t@@ -304,12 +290,10 @@ class InstallWizard(WindowModalDialog, WizardBase):
                    if xpub_hot:
                        texts.append(xpub_hot)
                    has_dups = len(set(texts)) < len(texts)
       -            button.setEnabled(all_valid and not has_dups)
       +            self.next_button.setEnabled(all_valid and not has_dups)
                for e in entries:
                    e.textChanged.connect(set_enabled)
       -        self.set_layout(vbox)
       -        if not self.exec_():
       -            raise UserCancelled
       +        self.set_main_layout(vbox)
                return get_texts()
        
            def network_dialog(self, network):
       t@@ -355,14 +339,7 @@ class InstallWizard(WindowModalDialog, WizardBase):
                return clayout.selected_index()
        
            def query_multisig(self, action):
       -        vbox = QVBoxLayout()
       -        self.set_layout(vbox)
       -        vbox.addWidget(QLabel(_("Multi Signature Wallet")))
       -
                cw = CosignWidget(2, 2)
       -        vbox.addWidget(cw, 1)
       -        vbox.addWidget(QLabel(_("Please choose the number of signatures needed to unlock funds in your wallet") + ':'))
       -
                m_edit = QSpinBox()
                n_edit = QSpinBox()
                m_edit.setValue(2)
       t@@ -384,11 +361,12 @@ class InstallWizard(WindowModalDialog, WizardBase):
                hbox.addWidget(QLabel(_('signatures')))
                hbox.addStretch(1)
        
       +        vbox = QVBoxLayout()
       +        vbox.addWidget(cw)
       +        vbox.addWidget(WWLabel(_("Choose the number of signatures needed "
       +                          "to unlock funds in your wallet:")))
                vbox.addLayout(hbox)
       -        vbox.addStretch(1)
       -        vbox.addLayout(Buttons(CancelButton(self), OkButton(self, _('Next'))))
       -        if not self.exec_():
       -            raise UserCancelled
       +        self.set_main_layout(vbox, _("Multi-Signature Wallet"))
                m = int(m_edit.value())
                n = int(n_edit.value())
                wallet_type = '%dof%d'%(m,n)
   DIR diff --git a/gui/qt/seed_dialog.py b/gui/qt/seed_dialog.py
       t@@ -18,23 +18,11 @@
        
        from PyQt4.QtGui import *
        from PyQt4.QtCore import *
       -import PyQt4.QtCore as QtCore
        from electrum.i18n import _
        
        from util import *
        from qrtextedit import ShowQRTextEdit, ScanQRTextEdit
        
       -class SeedDialog(WindowModalDialog):
       -    def __init__(self, parent, seed, imported_keys):
       -        WindowModalDialog.__init__(self, parent, ('Electrum - ' + _('Seed')))
       -        self.setMinimumWidth(400)
       -        vbox = show_seed_box_msg(seed)
       -        if imported_keys:
       -            vbox.addWidget(QLabel("<b>"+_("WARNING")+":</b> " + _("Your wallet contains imported keys. These keys cannot be recovered from seed.") + "</b><p>"))
       -        vbox.addLayout(Buttons(CloseButton(self)))
       -        self.setLayout(vbox)
       -
       -
        def icon_filename(sid):
            if sid == 'cold':
                return ":icons/cold_seed.png"
       t@@ -43,22 +31,61 @@ def icon_filename(sid):
            else:
                return ":icons/seed.png"
        
       -class SeedLayout(object):
       -    def __init__(self, seed, sid=None):
       +class SeedDialog(WindowModalDialog):
       +    def __init__(self, parent, seed, imported_keys):
       +        WindowModalDialog.__init__(self, parent, ('Electrum - ' + _('Seed')))
       +        self.setMinimumWidth(400)
       +        vbox = QVBoxLayout(self)
       +        vbox.addLayout(SeedDisplayLayout(seed))
       +        if imported_keys:
       +            warning = ("<b>" + _("WARNING") + ":</b> " +
       +                       _("Your wallet contains imported keys. These keys "
       +                         "cannot be recovered from your seed.") + "</b><p>")
       +            vbox.addWidget(WWLabel(warning))
       +        vbox.addLayout(Buttons(CloseButton(self)))
       +
       +
       +class SeedLayoutBase(object):
       +    def _seed_layout(self, seed=None, title=None, sid=None):
       +        logo = QLabel()
       +        logo.setPixmap(QPixmap(icon_filename(sid)).scaledToWidth(56))
       +        logo.setMaximumWidth(60)
                if seed:
       -            self.vbox = self.seed_and_warning_layout(seed, sid)
       +            self.seed_e = ShowQRTextEdit()
       +            self.seed_e.setText(seed)
                else:
       -            self.vbox = self.seed_layout(seed, sid)
       +            self.seed_e = ScanQRTextEdit()
       +            self.seed_e.setTabChangesFocus(True)
       +        self.seed_e.setMaximumHeight(75)
       +        hbox = QHBoxLayout()
       +        hbox.addWidget(logo)
       +        hbox.addWidget(self.seed_e)
       +        if not title:
       +            return hbox
       +        vbox = QVBoxLayout()
       +        vbox.addWidget(WWLabel(title))
       +        vbox.addLayout(hbox)
       +        return vbox
        
            def layout(self):
       -        return self.vbox
       +        return self.layout_
        
            def seed_edit(self):
                return self.seed_e
        
       -    def seed_and_warning_layout(self, seed, sid=None):
       -        vbox = QVBoxLayout()
       -        vbox.addLayout(self.seed_layout(seed, sid))
       +
       +class SeedInputLayout(SeedLayoutBase):
       +    def __init__(self, title=None, sid=None):
       +        self.layout_ = self._seed_layout(title=title, sid=sid)
       +
       +
       +class SeedDisplayLayout(SeedLayoutBase):
       +    def __init__(self, seed, title=None, sid=None):
       +        self.layout_ = self._seed_layout(seed=seed, title=title, sid=sid)
       +
       +
       +class SeedWarningLayout(SeedLayoutBase):
       +    def __init__(self, seed, title=None):
                msg = ''.join([
                    "<p>",
                    _("Please save these %d words on paper (order is important). "),
       t@@ -72,23 +99,7 @@ class SeedLayout(object):
                    "<li>" + _("Do not send your seed to a printer.") + "</li>",
                    "</ul>"
                ]) % len(seed.split())
       -        label2 = QLabel(msg)
       -        label2.setWordWrap(True)
       -        vbox.addWidget(label2)
       -        return vbox
       -
       -    def seed_layout(self, seed, sid=None):
       -        logo = QLabel()
       -        logo.setPixmap(QPixmap(icon_filename(sid)).scaledToWidth(56))
       -        logo.setMaximumWidth(60)
       -        if not seed:
       -            seed_e = ScanQRTextEdit()
       -            seed_e.setTabChangesFocus(True)
       -        else:
       -            seed_e = ShowQRTextEdit(text=seed)
       -        seed_e.setMaximumHeight(100)
       -        self.seed_e = seed_e
       -        hbox = QHBoxLayout()
       -        hbox.addWidget(logo)
       -        hbox.addWidget(seed_e)
       -        return hbox
       +        vbox = QVBoxLayout()
       +        vbox.addLayout(self._seed_layout(seed=seed, title=title))
       +        vbox.addWidget(WWLabel(msg))
       +        self.layout_ = vbox
   DIR diff --git a/gui/qt/util.py b/gui/qt/util.py
       t@@ -86,6 +86,12 @@ class ThreadedButton(QPushButton):
                t.start()
        
        
       +class WWLabel(QLabel):
       +    def __init__ (self, text="", parent=None):
       +        QLabel.__init__(self, text, parent)
       +        self.setWordWrap(True)
       +
       +
        class HelpLabel(QLabel):
        
            def __init__(self, text, help_text):
       t@@ -272,9 +278,7 @@ class ChoicesLayout(object):
            def __init__(self, msg, choices, on_clicked=None):
                vbox = QVBoxLayout()
                if len(msg) > 50:
       -            label = QLabel(msg)
       -            label.setWordWrap(True)
       -            vbox.addWidget(label)
       +            vbox.addWidget(WWLabel(msg))
                    msg = ""
                gb2 = QGroupBox(msg)
                vbox.addWidget(gb2)
   DIR diff --git a/plugins/trustedcoin/qt.py b/plugins/trustedcoin/qt.py
       t@@ -108,7 +108,7 @@ class Plugin(TrustedCoinPlugin):
                label.setWordWrap(True)
                vbox = QVBoxLayout()
                vbox.addWidget(label)
       -        window.set_main_layout(vbox, _("Two-Factor Authentication"))
       +        window.set_main_layout(vbox)
                self.set_enabled(wallet, True)
                window.set_icon(prior_icon)