URI: 
       tDon't refresh whilst editing! - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 0371a3dc32350c1923348c216ee2c2f8eee2d4d1
   DIR parent 544b829f6e43de5ab20d8a6c414d7689e13400d9
  HTML Author: Neil Booth <kyuupichan@gmail.com>
       Date:   Wed,  9 Sep 2015 09:36:35 +0900
       
       Don't refresh whilst editing!
       
       It's long been a pet peeve of mine that whilst editing a label,
       something would cause Electrum to refresh the widget, such as
       an incoming tx or a new block, and you'd lose your edits.
       This changes MyTreeWidget so that, if editing, updates are
       deferred until editing finishes.
       
       Diffstat:
         M gui/qt/history_widget.py            |       5 ++++-
         M gui/qt/main_window.py               |      77 +++++++++++++++----------------
         M gui/qt/util.py                      |      18 +++++++++++++++++-
         M plugins/exchange_rate.py            |       2 +-
       
       4 files changed, 60 insertions(+), 42 deletions(-)
       ---
   DIR diff --git a/gui/qt/history_widget.py b/gui/qt/history_widget.py
       t@@ -55,8 +55,11 @@ class HistoryWidget(MyTreeWidget):
                    icon = QIcon(":icons/confirmed.png")
                return icon, time_str
        
       -    def update(self, h):
       +    def on_update(self):
                self.wallet = self.parent.wallet
       +        domain = self.wallet.get_account_addresses(self.parent.current_account)
       +        h = self.wallet.get_history(domain)
       +
                item = self.currentItem()
                current_tx = item.data(0, Qt.UserRole).toString() if item else None
                self.clear()
   DIR diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
       t@@ -251,7 +251,7 @@ class ElectrumWindow(QMainWindow, PrintError):
                if self.wallet.is_watching_only():
                    title += ' [%s]' % (_('watching only'))
                self.setWindowTitle( title )
       -        self.update_history_tab()
       +        self.history_list.update()
                self.need_update.set()
                # Once GUI has been initialized check if we want to announce something since the callback has been called before the GUI was initialized
                self.notify_transactions()
       t@@ -268,7 +268,7 @@ class ElectrumWindow(QMainWindow, PrintError):
                self.update_buttons_on_seed()
                self.update_console()
                self.clear_receive_tab()
       -        self.update_receive_tab()
       +        self.receive_list.update()
                self.tabs.show()
                self.show()
                if self.wallet.is_watching_only():
       t@@ -544,12 +544,12 @@ class ElectrumWindow(QMainWindow, PrintError):
                    self.update_tabs()
        
            def update_tabs(self):
       -        self.update_history_tab()
       -        self.update_receive_tab()
       -        self.update_address_tab()
       -        self.update_contacts_tab()
       +        self.history_list.update()
       +        self.receive_list.update()
       +        self.address_list.update()
       +        self.contacts_list.update()
       +        self.invoices_list.update()
                self.update_completions()
       -        self.update_invoices_list()
        
            def create_history_tab(self):
                from history_widget import HistoryWidget
       t@@ -565,11 +565,6 @@ class ElectrumWindow(QMainWindow, PrintError):
                '''tx_desc is set only for txs created in the Send tab'''
                show_transaction(tx, self, tx_desc)
        
       -    def update_history_tab(self):
       -        domain = self.wallet.get_account_addresses(self.current_account)
       -        h = self.wallet.get_history(domain)
       -        self.history_list.update(h)
       -
            def create_receive_tab(self):
        
                self.receive_grid = grid = QGridLayout()
       t@@ -635,6 +630,7 @@ class ElectrumWindow(QMainWindow, PrintError):
                self.receive_list.setColumnWidth(0, 180)
                self.receive_list.hideColumn(1)
                self.receive_list.hideColumn(2)
       +        self.receive_list.on_update = self.update_receive_tab
        
                # layout
                vbox_g = QVBoxLayout()
       t@@ -676,7 +672,7 @@ class ElectrumWindow(QMainWindow, PrintError):
            def delete_payment_request(self, item):
                addr = str(item.text(2))
                self.wallet.remove_payment_request(addr, self.config)
       -        self.update_receive_tab()
       +        self.receive_list.update()
                self.clear_receive_tab()
        
            def get_request_URI(self, addr):
       t@@ -739,8 +735,8 @@ class ElectrumWindow(QMainWindow, PrintError):
                req = self.wallet.make_payment_request(addr, amount, message, expiration)
                self.wallet.add_payment_request(req, self.config)
                self.sign_payment_request(addr)
       -        self.update_receive_tab()
       -        self.update_address_tab()
       +        self.receive_list.update()
       +        self.address_list.update()
                self.save_request_button.setEnabled(False)
        
            def view_and_paste(self, title, msg, data):
       t@@ -1002,6 +998,7 @@ class ElectrumWindow(QMainWindow, PrintError):
                self.invoices_list.setSortingEnabled(True)
                self.invoices_list.header().setResizeMode(1, QHeaderView.Interactive)
                self.invoices_list.setColumnWidth(1, 200)
       +        self.invoices_list.on_update = self.update_invoices_list
        
                vbox0 = QVBoxLayout()
                vbox0.addLayout(grid)
       t@@ -1275,7 +1272,7 @@ class ElectrumWindow(QMainWindow, PrintError):
                        if tx_desc is not None and tx.is_complete():
                            self.wallet.set_label(tx.hash(), tx_desc)
                        QMessageBox.information(parent, '', _('Payment sent.') + '\n' + msg, _('OK'))
       -                self.update_invoices_list()
       +                self.invoices_list.update()
                        self.do_clear()
                    else:
                        QMessageBox.warning(parent, _('Error'), msg, _('OK'))
       t@@ -1300,7 +1297,7 @@ class ElectrumWindow(QMainWindow, PrintError):
                pr = self.payment_request
                key = self.invoices.add(pr)
                status = self.invoices.get_status(key)
       -        self.update_invoices_list()
       +        self.invoices_list.update()
                if status == PR_PAID:
                    self.show_message("invoice already paid")
                    self.do_clear()
       t@@ -1389,7 +1386,7 @@ class ElectrumWindow(QMainWindow, PrintError):
        
            def set_frozen_state(self, addrs, freeze):
                self.wallet.set_frozen_state(addrs, freeze)
       -        self.update_address_tab()
       +        self.address_list.update()
                self.update_fee()
        
            def create_list_tab(self, l):
       t@@ -1406,6 +1403,7 @@ class ElectrumWindow(QMainWindow, PrintError):
            def create_addresses_tab(self):
                l = MyTreeWidget(self, self.create_receive_menu, [ _('Address'), _('Label'), _('Balance'), _('Tx')], 1)
                l.setSelectionMode(QAbstractItemView.ExtendedSelection)
       +        l.on_update = self.update_address_tab
                self.address_list = l
                return self.create_list_tab(l)
        
       t@@ -1415,6 +1413,7 @@ class ElectrumWindow(QMainWindow, PrintError):
                l.setSortingEnabled(True)
                l.on_edited = self.on_contact_edited
                l.on_permit_edit = self.on_permit_contact_edit
       +        l.on_update = self.update_contacts_tab
                self.contacts_list = l
                return self.create_list_tab(l)
        
       t@@ -1441,15 +1440,15 @@ class ElectrumWindow(QMainWindow, PrintError):
            def delete_imported_key(self, addr):
                if self.question(_("Do you want to remove")+" %s "%addr +_("from your wallet?")):
                    self.wallet.delete_imported_key(addr)
       -            self.update_address_tab()
       -            self.update_history_tab()
       +            self.address_list.update()
       +            self.history_list.update()
        
            def edit_account_label(self, k):
                text, ok = QInputDialog.getText(self, _('Rename account'), _('Name') + ':', text = self.wallet.labels.get(k,''))
                if ok:
                    label = unicode(text)
                    self.wallet.set_label(k,label)
       -            self.update_address_tab()
       +            self.address_list.update()
        
            def account_set_expanded(self, item, k, b):
                item.setExpanded(b)
       t@@ -1468,7 +1467,7 @@ class ElectrumWindow(QMainWindow, PrintError):
        
            def delete_pending_account(self, k):
                self.wallet.delete_pending_account(k)
       -        self.update_address_tab()
       +        self.address_list.update()
                self.update_account_selector()
        
            def create_receive_menu(self, position):
       t@@ -1564,11 +1563,11 @@ class ElectrumWindow(QMainWindow, PrintError):
            def set_contact(self, label, address):
                if not is_valid(address):
                    QMessageBox.warning(self, _('Error'), _('Invalid Address'), _('OK'))
       -            self.update_contacts_tab()  # Displays original unchanged value
       +            self.contacts_list.update()  # Displays original unchanged value
                    return False
                self.contacts[label] = ('address', address)
       -        self.update_contacts_tab()
       -        self.update_history_tab()
       +        self.contacts_list.update()
       +        self.history_list.update()
                self.update_completions()
                return True
        
       t@@ -1578,8 +1577,8 @@ class ElectrumWindow(QMainWindow, PrintError):
                    return
                for label in labels:
                    self.contacts.pop(label)
       -        self.update_history_tab()
       -        self.update_contacts_tab()
       +        self.history_list.update()
       +        self.contacts_list.update()
                self.update_completions()
        
            def create_contact_menu(self, position):
       t@@ -1664,7 +1663,7 @@ class ElectrumWindow(QMainWindow, PrintError):
                    menu.addAction(_("Pay Now"), lambda: self.do_pay_invoice(key))
                def delete_invoice(key):
                    self.invoices.remove(key)
       -            self.update_invoices_list()
       +            self.invoices_list.update()
                menu.addAction(_("Delete"), lambda: delete_invoice(key))
                menu.exec_(self.invoices_list.viewport().mapToGlobal(position))
        
       t@@ -1778,10 +1777,10 @@ class ElectrumWindow(QMainWindow, PrintError):
                    for k, v in accounts.items():
                        if v == s:
                            self.current_account = k
       -        self.update_history_tab()
       +        self.history_list.update()
                self.update_status()
       -        self.update_address_tab()
       -        self.update_receive_tab()
       +        self.address_list.update()
       +        self.receive_list.update()
        
            def create_status_bar(self):
        
       t@@ -1899,7 +1898,7 @@ class ElectrumWindow(QMainWindow, PrintError):
                    return
                name = str(e.text())
                self.wallet.create_pending_account(name, password)
       -        self.update_address_tab()
       +        self.address_list.update()
                self.update_account_selector()
                self.tabs.setCurrentIndex(3)
        
       t@@ -2526,8 +2525,8 @@ class ElectrumWindow(QMainWindow, PrintError):
                    QMessageBox.information(self, _('Information'), _("The following addresses were added") + ':\n' + '\n'.join(addrlist))
                if badkeys:
                    QMessageBox.critical(self, _('Error'), _("The following inputs could not be imported") + ':\n'+ '\n'.join(badkeys))
       -        self.update_address_tab()
       -        self.update_history_tab()
       +        self.address_list.update()
       +        self.history_list.update()
        
        
            def settings_dialog(self):
       t@@ -2575,8 +2574,8 @@ class ElectrumWindow(QMainWindow, PrintError):
                    if self.num_zeros != value:
                        self.num_zeros = value
                        self.config.set_key('num_zeros', value, True)
       -                self.update_history_tab()
       -                self.update_address_tab()
       +                self.history_list.update()
       +                self.address_list.update()
                nz.valueChanged.connect(on_nz)
                gui_widgets.append((nz_label, nz))
        
       t@@ -2690,9 +2689,9 @@ class ElectrumWindow(QMainWindow, PrintError):
                    else:
                        raise Exception('Unknown base unit')
                    self.config.set_key('decimal_point', self.decimal_point, True)
       -            self.update_history_tab()
       -            self.update_receive_tab()
       -            self.update_address_tab()
       +            self.history_list.update()
       +            self.receive_list.update()
       +            self.address_list.update()
                    fee_e.setAmount(self.wallet.fee_per_kb(self.config))
                    self.update_status()
                unit_combo.currentIndexChanged.connect(on_unit)
   DIR diff --git a/gui/qt/util.py b/gui/qt/util.py
       t@@ -303,6 +303,7 @@ class MyTreeWidget(QTreeWidget):
        
                # Control which columns are editable
                self.editor = None
       +        self.pending_update = False
                if editable_columns is None:
                    editable_columns = [stretch_column]
                self.editable_columns = editable_columns
       t@@ -372,6 +373,11 @@ class MyTreeWidget(QTreeWidget):
                        self.on_edited(*self.editing_itemcol)
                        self.editor = None
        
       +            # Now do any pending updates
       +            if self.editor is None and self.pending_update:
       +                self.pending_update = False
       +                self.on_update()
       +
            def on_edited(self, item, column, prior):
                '''Called only when the text actually changes'''
                key = str(item.data(0, Qt.UserRole).toString())
       t@@ -383,9 +389,19 @@ class MyTreeWidget(QTreeWidget):
                    text = self.parent.wallet.get_default_label(key)
                    item.setText(column, text)
                    item.setForeground(column, QBrush(QColor('gray')))
       -        self.parent.update_history_tab()
       +        self.parent.history_list.update()
                self.parent.update_completions()
        
       +    def update(self):
       +        # Defer updates if editing
       +        if self.editor:
       +            self.pending_update = True
       +        else:
       +            self.on_update()
       +
       +    def on_update(self):
       +        pass
       +
            def get_leaves(self, root):
                child_count = root.childCount()
                if child_count == 0:
   DIR diff --git a/plugins/exchange_rate.py b/plugins/exchange_rate.py
       t@@ -347,7 +347,7 @@ class Plugin(BasePlugin, ThreadJob):
            def on_fx_history(self):
                '''Called when historical fx quotes are updated'''
                for window in self.windows:
       -            window.update_history_tab()
       +            window.history_list.update()
        
            def on_fx_quotes(self):
                '''Called when fresh spot fx quotes come in'''