URI: 
       tadd file selector and password dialog to wizard (fix #1730) - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 45f25586ef586c998ae3e24d731a7c3f651d90f2
   DIR parent 83e925c0cd31e31c467343c39fba0f889157f21a
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Sun,  5 Mar 2017 13:30:57 +0100
       
       add file selector and password dialog to wizard (fix #1730)
       
       Diffstat:
         M gui/qt/__init__.py                  |      33 +++++++++++---------------------
         M gui/qt/installwizard.py             |     111 ++++++++++++++++++++++++++-----
         M lib/base_wizard.py                  |       7 +++----
         M lib/daemon.py                       |       3 +++
       
       4 files changed, 113 insertions(+), 41 deletions(-)
       ---
   DIR diff --git a/gui/qt/__init__.py b/gui/qt/__init__.py
       t@@ -159,30 +159,19 @@ class ElectrumGui:
                        w.bring_to_top()
                        break
                else:
       -            if not os.path.exists(path):
       -                wizard = InstallWizard(self.config, self.app, self.plugins, path)
       -                wallet = wizard.run_and_get_wallet()
       -                if not wallet:
       -                    return
       +            wallet = self.daemon.get_wallet(path)
       +            if not wallet:
       +                storage = WalletStorage(path)
       +                if not storage.file_exists or storage.is_encrypted():
       +                    wizard = InstallWizard(self.config, self.app, self.plugins, storage)
       +                    wallet = wizard.run_and_get_wallet()
       +                    if not wallet:
       +                        return
       +                else:
       +                    storage.read(None)
       +                    wallet = Wallet(storage)
                        wallet.start_threads(self.daemon.network)
                        self.daemon.add_wallet(wallet)
       -            else:
       -                from password_dialog import PasswordDialog
       -                msg = _("The file '%s' is encrypted.") % os.path.basename(path)
       -                password_getter = lambda: PasswordDialog(msg=msg).run()
       -                while True:
       -                    try:
       -                        wallet = self.daemon.load_wallet(path, password_getter)
       -                        break
       -                    except UserCancelled:
       -                        return
       -                    except InvalidPassword as e:
       -                        QMessageBox.information(None, _('Error'), str(e), _('OK'))
       -                        continue
       -                    except BaseException as e:
       -                        traceback.print_exc(file=sys.stdout)
       -                        QMessageBox.information(None, _('Error'), str(e), _('OK'))
       -                        return
                    w = self.create_window_for_wallet(wallet)
                if uri:
                    w.pay_to_URI(uri)
   DIR diff --git a/gui/qt/installwizard.py b/gui/qt/installwizard.py
       t@@ -6,8 +6,8 @@ from PyQt4.QtCore import *
        import PyQt4.QtCore as QtCore
        
        import electrum
       -from electrum.wallet import Wallet
       -from electrum.util import UserCancelled
       +from electrum.wallet import Wallet, WalletStorage
       +from electrum.util import UserCancelled, InvalidPassword
        from electrum.base_wizard import BaseWizard
        from electrum.i18n import _
        
       t@@ -147,6 +147,78 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
        
            def run_and_get_wallet(self):
        
       +        def on_filename():
       +            wallet_folder = os.path.dirname(self.storage.path)
       +            path = unicode(QFileDialog.getOpenFileName(self, "Select your wallet file", wallet_folder))
       +            if path:
       +                self.name_e.setText(path)
       +                self.storage = WalletStorage(path)
       +                update_layout()
       +        def update_layout():
       +            name = os.path.basename(self.storage.path)
       +            vbox = QVBoxLayout()
       +            hbox = QHBoxLayout()
       +            hbox.addWidget(QLabel(_('Wallet') + ':'))
       +            self.name_e = QLineEdit(text=name)
       +            hbox.addWidget(self.name_e)
       +            button = QPushButton(_('Choose...'))
       +            button.clicked.connect(on_filename)
       +            hbox.addWidget(button)
       +            vbox.addLayout(hbox)
       +            self.pw_e = None
       +
       +            if not self.storage.file_exists:
       +                msg = _("This file does not exist.") + '\n' \
       +                      + _("Press 'Next' to create this wallet, or chose another file.")
       +                vbox.addWidget(QLabel(msg))
       +
       +            elif self.storage.file_exists and self.storage.is_encrypted():
       +                msg = _("This file is encrypted.") + '\n' + _('Enter your password or choose another file.')
       +                vbox.addWidget(QLabel(msg))
       +                hbox2 = QHBoxLayout()
       +                self.pw_e = QLineEdit('', self)
       +                self.pw_e.setFixedWidth(150)
       +                self.pw_e.setEchoMode(2)
       +                hbox2.addWidget(QLabel(_('Password') + ':'))
       +                hbox2.addWidget(self.pw_e)
       +                hbox2.addStretch()
       +                vbox.addLayout(hbox2)
       +            else:
       +                msg = _("Press 'Next' to open this wallet.")
       +                vbox.addWidget(QLabel(msg))
       +
       +            self.set_layout(vbox, title=_('Electrum wallet'))
       +            if self.pw_e:
       +                self.pw_e.show()
       +                self.pw_e.setFocus()
       +
       +        while True:
       +            update_layout()
       +
       +            if self.storage.file_exists and not self.storage.is_encrypted():
       +                self.storage.read(None)
       +                break
       +
       +            if not self.loop.exec_():
       +                return
       +
       +            if not self.storage.file_exists:
       +                break
       +
       +            if self.storage.file_exists and self.storage.is_encrypted():
       +                password = unicode(self.pw_e.text())
       +                try:
       +                    self.storage.read(password)
       +                    break
       +                except InvalidPassword as e:
       +                    QMessageBox.information(None, _('Error'), str(e), _('OK'))
       +                    continue
       +                except BaseException as e:
       +                    traceback.print_exc(file=sys.stdout)
       +                    QMessageBox.information(None, _('Error'), str(e), _('OK'))
       +                    return
       +
       +
                path = self.storage.path
                if self.storage.requires_split():
                    self.hide()
       t@@ -188,6 +260,11 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                    self.run(action)
                    return self.wallet
        
       +        self.wallet = Wallet(self.storage)
       +        self.terminate()
       +        return self.wallet
       +
       +
        
            def finished(self):
                """Called in hardware client wrapper, in order to close popups."""
       t@@ -203,7 +280,7 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                self.logo.setPixmap(QPixmap(filename).scaledToWidth(60))
                return prior_filename
        
       -    def set_main_layout(self, layout, title=None, raise_on_cancel=True,
       +    def set_layout(self, layout, title=None, raise_on_cancel=True,
                                next_enabled=True):
                self.title.setText("<b>%s</b>"%title if title else "")
                self.title.setVisible(bool(title))
       t@@ -218,6 +295,10 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                    self.next_button.setFocus()
                self.main_widget.setVisible(True)
                self.please_wait.setVisible(False)
       +
       +    def exec_layout(self, layout, title=None, raise_on_cancel=True,
       +                        next_enabled=True):
       +        self.set_layout(layout, title, next_enabled)
                result = self.loop.exec_()
                if not result and raise_on_cancel:
                    raise UserCancelled
       t@@ -241,12 +322,12 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
        
            def text_input(self, title, message, is_valid):
                slayout = KeysLayout(parent=self, title=message, is_valid=is_valid)
       -        self.set_main_layout(slayout, title, next_enabled=False)
       +        self.exec_layout(slayout, title, next_enabled=False)
                return slayout.get_text()
        
            def seed_input(self, title, message, is_seed, options):
                slayout = SeedLayout(title=message, is_seed=is_seed, options=options, parent=self)
       -        self.set_main_layout(slayout, title, next_enabled=False)
       +        self.exec_layout(slayout, title, next_enabled=False)
                return slayout.get_seed(), slayout.is_bip39, slayout.is_ext
        
            @wizard_dialog
       t@@ -289,13 +370,13 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
            def show_seed_dialog(self, run_next, seed_text):
                title =  _("Your wallet generation seed is:")
                slayout = SeedLayout(seed=seed_text, title=title, msg=True, options=['ext'])
       -        self.set_main_layout(slayout)
       +        self.exec_layout(slayout)
                return slayout.is_ext
        
            def pw_layout(self, msg, kind):
                playout = PasswordLayout(None, msg, kind, self.next_button)
                playout.encrypt_cb.setChecked(True)
       -        self.set_main_layout(playout.layout())
       +        self.exec_layout(playout.layout())
                return playout.new_password(), playout.encrypt_cb.isChecked()
        
            @wizard_dialog
       t@@ -332,7 +413,7 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
            def confirm(self, message, title):
                vbox = QVBoxLayout()
                vbox.addWidget(WWLabel(message))
       -        self.set_main_layout(vbox, title)
       +        self.exec_layout(vbox, title)
        
            @wizard_dialog
            def action_dialog(self, action, run_next):
       t@@ -355,7 +436,7 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                clayout = ChoicesLayout(message, c_titles)
                vbox = QVBoxLayout()
                vbox.addLayout(clayout.layout())
       -        self.set_main_layout(vbox, title)
       +        self.exec_layout(vbox, title)
                action = c_values[clayout.selected_index()]
                return action
        
       t@@ -364,7 +445,7 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                clayout = ChoicesLayout(msg, choices)
                vbox = QVBoxLayout()
                vbox.addLayout(clayout.layout())
       -        self.set_main_layout(vbox, '')
       +        self.exec_layout(vbox, '')
                return clayout.selected_index()
        
            @wizard_dialog
       t@@ -378,7 +459,7 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                line.textEdited.connect(f)
                vbox.addWidget(line)
                vbox.addWidget(WWLabel(warning))
       -        self.set_main_layout(vbox, title, next_enabled=test(default))
       +        self.exec_layout(vbox, title, next_enabled=test(default))
                return ' '.join(unicode(line.text()).split())
        
            @wizard_dialog
       t@@ -390,7 +471,7 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                vbox = QVBoxLayout()
                layout = SeedLayout(xpub, title=msg, icon=False)
                vbox.addLayout(layout.layout())
       -        self.set_main_layout(vbox, _('Master Public Key'))
       +        self.exec_layout(vbox, _('Master Public Key'))
                return None
        
            def init_network(self, network):
       t@@ -404,14 +485,14 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                title = _("How do you want to connect to a server? ")
                clayout = ChoicesLayout(message, choices)
                self.back_button.setText(_('Cancel'))
       -        self.set_main_layout(clayout.layout(), title)
       +        self.exec_layout(clayout.layout(), title)
                r = clayout.selected_index()
                if r == 0:
                    auto_connect = True
                elif r == 1:
                    auto_connect = True
                    nlayout = NetworkChoiceLayout(network, self.config, wizard=True)
       -            if self.set_main_layout(nlayout.layout()):
       +            if self.exec_layout(nlayout.layout()):
                        auto_connect = False
                else:
                    auto_connect = True
       t@@ -451,7 +532,7 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                vbox.addWidget(cw)
                vbox.addWidget(WWLabel(_("Choose the number of signatures needed to unlock funds in your wallet:")))
                vbox.addLayout(grid)
       -        self.set_main_layout(vbox, _("Multi-Signature Wallet"))
       +        self.exec_layout(vbox, _("Multi-Signature Wallet"))
                m = int(m_edit.value())
                n = int(n_edit.value())
                return (m, n)
   DIR diff --git a/lib/base_wizard.py b/lib/base_wizard.py
       t@@ -32,10 +32,10 @@ from plugins import run_hook
        
        class BaseWizard(object):
        
       -    def __init__(self, config, path):
       +    def __init__(self, config, storage):
                super(BaseWizard, self).__init__()
                self.config = config
       -        self.storage = WalletStorage(path)
       +        self.storage = storage
                self.wallet = None
                self.stack = []
                self.plugin = None
       t@@ -72,9 +72,8 @@ class BaseWizard(object):
        
            def new(self):
                name = os.path.basename(self.storage.path)
       -        title = _("Welcome to the Electrum installation wizard.")
       +        title = _("Create '%s'"%name)
                message = '\n'.join([
       -            _("The wallet '%s' does not exist.") % name,
                    _("What kind of wallet do you want to create?")
                ])
                wallet_kinds = [
   DIR diff --git a/lib/daemon.py b/lib/daemon.py
       t@@ -228,6 +228,9 @@ class Daemon(DaemonThread):
                path = wallet.storage.path
                self.wallets[path] = wallet
        
       +    def get_wallet(self, path):
       +        return self.wallets.get(path)
       +
            def stop_wallet(self, path):
                wallet = self.wallets.pop(path)
                wallet.stop_threads()