URI: 
       tFix "same wallet can be opened multiple times via InstallWizard" (#4076) - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 9837a02c951a505e7a13fab3867e894f9e54d9d2
   DIR parent 8dd19a5920d5e586d6f03df405f07515482167fd
  HTML Author: Jason Bruderer <Lastrellik@gmail.com>
       Date:   Wed, 14 Mar 2018 23:46:23 -0600
       
       Fix "same wallet can be opened multiple times via InstallWizard" (#4076)
       
       * Fix #4073
       
       * Account for if the wallet is already in the daemon
       
       * Only start a new thread if it doesn't exist
       
       * Modify run_and_get_wallet to not return duplicate wallets
       
       * Inform user if encrypted wallet is already open in memory
       
       Diffstat:
         M gui/qt/__init__.py                  |      66 ++++++++++++++++---------------
         M gui/qt/installwizard.py             |      21 +++++++++++++++------
       
       2 files changed, 49 insertions(+), 38 deletions(-)
       ---
   DIR diff --git a/gui/qt/__init__.py b/gui/qt/__init__.py
       t@@ -185,42 +185,44 @@ class ElectrumGui:
        
            def start_new_window(self, path, uri):
                '''Raises the window for the wallet if it is open.  Otherwise
       -        opens the wallet and creates a new window for it.'''
       -        for w in self.windows:
       -            if w.wallet.storage.path == path:
       -                w.bring_to_top()
       -                break
       -        else:
       +        opens the wallet and creates a new window for it'''
       +        try:
       +            wallet = self.daemon.load_wallet(path, None)
       +        except BaseException as e:
       +            traceback.print_exc(file=sys.stdout)
       +            d = QMessageBox(QMessageBox.Warning, _('Error'),
       +                            _('Cannot load wallet:') + '\n' + str(e))
       +            d.exec_()
       +            return
       +        if not wallet:
       +            storage = WalletStorage(path, manual_upgrades=True)
       +            wizard = InstallWizard(self.config, self.app, self.plugins, storage)
                    try:
       -                wallet = self.daemon.load_wallet(path, None)
       -            except BaseException as e:
       -                traceback.print_exc(file=sys.stdout)
       -                d = QMessageBox(QMessageBox.Warning, _('Error'),
       -                                _('Cannot load wallet:') + '\n' + str(e))
       -                d.exec_()
       -                return
       +                wallet = wizard.run_and_get_wallet(self.daemon.get_wallet)
       +            except UserCancelled:
       +                pass
       +            except GoBack as e:
       +                print_error('[start_new_window] Exception caught (GoBack)', e)
       +            wizard.terminate()
                    if not wallet:
       -                storage = WalletStorage(path, manual_upgrades=True)
       -                wizard = InstallWizard(self.config, self.app, self.plugins, storage)
       -                try:
       -                    wallet = wizard.run_and_get_wallet()
       -                except UserCancelled:
       -                    pass
       -                except GoBack as e:
       -                    print_error('[start_new_window] Exception caught (GoBack)', e)
       -                wizard.terminate()
       -                if not wallet:
       -                    return
       +                return
       +
       +            if not self.daemon.get_wallet(wallet.storage.path):
       +                # wallet was not in memory
                        wallet.start_threads(self.daemon.network)
                        self.daemon.add_wallet(wallet)
       -            try:
       -                w = self.create_window_for_wallet(wallet)
       -            except BaseException as e:
       -                traceback.print_exc(file=sys.stdout)
       -                d = QMessageBox(QMessageBox.Warning, _('Error'),
       -                                _('Cannot create window for wallet:') + '\n' + str(e))
       -                d.exec_()
       -                return
       +        try:
       +            for w in self.windows:
       +                if w.wallet.storage.path == wallet.storage.path:
       +                    w.bring_to_top()
       +                    return
       +            w = self.create_window_for_wallet(wallet)
       +        except BaseException as e:
       +            traceback.print_exc(file=sys.stdout)
       +            d = QMessageBox(QMessageBox.Warning, _('Error'),
       +                            _('Cannot create window for wallet:') + '\n' + str(e))
       +            d.exec_()
       +            return
                if uri:
                    w.pay_to_URI(uri)
                w.bring_to_top()
   DIR diff --git a/gui/qt/installwizard.py b/gui/qt/installwizard.py
       t@@ -148,7 +148,7 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                self.raise_()
                self.refresh_gui()  # Need for QT on MacOSX.  Lame.
        
       -    def run_and_get_wallet(self):
       +    def run_and_get_wallet(self, get_wallet_from_daemon):
        
                vbox = QVBoxLayout()
                hbox = QHBoxLayout()
       t@@ -181,8 +181,12 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
        
                def on_filename(filename):
                    path = os.path.join(wallet_folder, filename)
       +            wallet_from_memory = get_wallet_from_daemon(path)
                    try:
       -                self.storage = WalletStorage(path, manual_upgrades=True)
       +                if wallet_from_memory:
       +                    self.storage = wallet_from_memory.storage
       +                else:
       +                    self.storage = WalletStorage(path, manual_upgrades=True)
                        self.next_button.setEnabled(True)
                    except BaseException:
                        traceback.print_exc(file=sys.stderr)
       t@@ -193,7 +197,7 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                            msg =_("This file does not exist.") + '\n' \
                                  + _("Press 'Next' to create this wallet, or choose another file.")
                            pw = False
       -                else:
       +                elif not wallet_from_memory:
                            if self.storage.is_encrypted_with_user_pw():
                                msg = _("This file is encrypted with a password.") + '\n' \
                                      + _('Enter your password or choose another file.')
       t@@ -205,6 +209,10 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                            else:
                                msg = _("Press 'Next' to open this wallet.")
                                pw = False
       +                else:
       +                    msg = _("This file is already open in memory.") + "\n" \
       +                        + _("Press 'Next' to create/focus window.")
       +                    pw = False
                    else:
                        msg = _('Cannot read file')
                        pw = False
       t@@ -229,6 +237,9 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                        return
                    if not self.storage.file_exists():
                        break
       +            wallet_from_memory = get_wallet_from_daemon(self.storage.path)
       +            if wallet_from_memory:
       +                return wallet_from_memory
                    if self.storage.file_exists() and self.storage.is_encrypted():
                        if self.storage.is_encrypted_with_user_pw():
                            password = self.pw_e.text()
       t@@ -251,7 +262,7 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                                    _('Failed to decrypt using this hardware device.') + '\n' +
                                    _('If you use a passphrase, make sure it is correct.'))
                                self.stack = []
       -                        return self.run_and_get_wallet()
       +                        return self.run_and_get_wallet(get_wallet_from_daemon)
                            except BaseException as e:
                                traceback.print_exc(file=sys.stdout)
                                QMessageBox.information(None, _('Error'), str(e))
       t@@ -301,8 +312,6 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
                self.wallet = Wallet(self.storage)
                return self.wallet
        
       -
       -
            def finished(self):
                """Called in hardware client wrapper, in order to close popups."""
                return