From 92c6d911570d0d0aa84ca835ab613b2cb7372f19 Mon Sep 17 00:00:00 2001 From: ThomasV Date: Sat, 19 Mar 2022 12:10:23 +0100 Subject: [PATCH] Qt: on status changes, refresh item in invoice_list and request_list, instead of calling update(), which repopulates the model. --- electrum/gui/qt/invoice_list.py | 23 +++++++++-------- electrum/gui/qt/main_window.py | 17 +++++++------ electrum/gui/qt/request_list.py | 44 +++++++++++---------------------- electrum/gui/qt/util.py | 20 +++++++++++++++ 4 files changed, 54 insertions(+), 50 deletions(-) diff --git a/electrum/gui/qt/invoice_list.py b/electrum/gui/qt/invoice_list.py index 1b5773e06..c788627ef 100644 --- a/electrum/gui/qt/invoice_list.py +++ b/electrum/gui/qt/invoice_list.py @@ -48,6 +48,7 @@ ROLE_SORT_ORDER = Qt.UserRole + 2 class InvoiceList(MyTreeView): + key_role = ROLE_REQUEST_ID class Columns(IntEnum): DATE = 0 @@ -74,14 +75,11 @@ class InvoiceList(MyTreeView): self.setSelectionMode(QAbstractItemView.ExtendedSelection) self.update() - def update_item(self, key, invoice: Invoice): - model = self.std_model - for row in range(0, model.rowCount()): - item = model.item(row, 0) - if item.data(ROLE_REQUEST_ID) == key: - break - else: + def refresh_row(self, key, row): + invoice = self.parent.wallet.invoices.get(key) + if invoice is None: return + model = self.std_model status_item = model.item(row, self.Columns.STATUS) status = self.parent.wallet.get_invoice_status(invoice) status_str = invoice.get_status_str(status) @@ -125,11 +123,12 @@ class InvoiceList(MyTreeView): self.proxy.setDynamicSortFilter(True) # sort requests by date self.sortByColumn(self.Columns.DATE, Qt.DescendingOrder) - # hide list if empty - if self.parent.isVisible(): - b = self.std_model.rowCount() > 0 - self.setVisible(b) - self.parent.invoices_label.setVisible(b) + self.hide_if_empty() + + def hide_if_empty(self): + b = self.std_model.rowCount() > 0 + self.setVisible(b) + self.parent.invoices_label.setVisible(b) def create_menu(self, position): wallet = self.parent.wallet diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py index ab1dcc661..e4a80a034 100644 --- a/electrum/gui/qt/main_window.py +++ b/electrum/gui/qt/main_window.py @@ -875,7 +875,8 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): self.tray.showMessage("Electrum", message, QSystemTrayIcon.Information, 20000) def timer_actions(self): - self.request_list.refresh_status() + self.request_list.refresh_all() + self.invoice_list.refresh_all() # Note this runs in the GUI thread if self.need_update.is_set(): self.need_update.clear() @@ -1028,11 +1029,11 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): if wallet != self.wallet: return self.history_model.refresh('update_tabs') - self.request_list.update() + self.request_list.refresh_all() + self.invoice_list.refresh_all() self.address_list.update() self.utxo_list.update() self.contact_list.update() - self.invoice_list.update() self.channels_list.update_rows.emit(wallet) self.update_completions() @@ -1211,7 +1212,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): def delete_requests(self, keys): for key in keys: self.wallet.delete_request(key) - self.request_list.update() + self.request_list.delete_item(key) self.clear_receive_tab() def delete_lightning_payreq(self, payreq_key): @@ -1596,7 +1597,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): self.notify(_('Payment received') + '\n' + key) self.need_update.set() else: - self.request_list.update_item(key, req) + self.request_list.refresh_item(key) def on_invoice_status(self, wallet, key): if wallet != self.wallet: @@ -1606,9 +1607,9 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): return status = self.wallet.get_invoice_status(invoice) if status == PR_PAID: - self.invoice_list.update() + self.invoice_list.delete_item(key) else: - self.invoice_list.update_item(key, invoice) + self.invoice_list.refresh_item(key) def on_payment_succeeded(self, wallet, key): description = self.wallet.get_label(key) @@ -1944,7 +1945,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): def delete_invoices(self, keys): for key in keys: self.wallet.delete_invoice(key) - self.invoice_list.update() + self.invoice_list.delete_item(key) def payment_request_ok(self): pr = self.payment_request diff --git a/electrum/gui/qt/request_list.py b/electrum/gui/qt/request_list.py index f18622d4e..4b3f1be04 100644 --- a/electrum/gui/qt/request_list.py +++ b/electrum/gui/qt/request_list.py @@ -48,6 +48,7 @@ ROLE_SORT_ORDER = Qt.UserRole + 2 class RequestList(MyTreeView): + key_role = ROLE_KEY class Columns(IntEnum): DATE = 0 @@ -111,32 +112,14 @@ class RequestList(MyTreeView): super().clearSelection() self.selectionModel().clearCurrentIndex() - def refresh_status(self): - m = self.std_model - for r in range(m.rowCount()): - idx = m.index(r, self.Columns.STATUS) - date_idx = idx.sibling(idx.row(), self.Columns.DATE) - date_item = m.itemFromIndex(date_idx) - status_item = m.itemFromIndex(idx) - key = date_item.data(ROLE_KEY) - req = self.wallet.get_request(key) - if req: - status = self.parent.wallet.get_request_status(key) - status_str = req.get_status_str(status) - status_item.setText(status_str) - status_item.setIcon(read_QIcon(pr_icons.get(status))) - - def update_item(self, key, invoice: Invoice): + def refresh_row(self, key, row): model = self.std_model - for row in range(0, model.rowCount()): - item = model.item(row, 0) - if item.data(ROLE_KEY) == key: - break - else: + request = self.wallet.get_request(key) + if request is None: return status_item = model.item(row, self.Columns.STATUS) status = self.parent.wallet.get_request_status(key) - status_str = invoice.get_status_str(status) + status_str = request.get_status_str(status) status_item.setText(status_str) status_item.setIcon(read_QIcon(pr_icons.get(status))) @@ -176,14 +159,15 @@ class RequestList(MyTreeView): self.proxy.setDynamicSortFilter(True) # sort requests by date self.sortByColumn(self.Columns.DATE, Qt.DescendingOrder) - # hide list if empty - if self.parent.isVisible(): - b = self.std_model.rowCount() > 0 - self.setVisible(b) - self.parent.receive_requests_label.setVisible(b) - if not b: - # list got hidden, so selected item should also be cleared: - self.item_changed(None) + self.hide_if_empty() + + def hide_if_empty(self): + b = self.std_model.rowCount() > 0 + self.setVisible(b) + self.parent.receive_requests_label.setVisible(b) + if not b: + # list got hidden, so selected item should also be cleared: + self.item_changed(None) def create_menu(self, position): items = self.selected_in_column(0) diff --git a/electrum/gui/qt/util.py b/electrum/gui/qt/util.py index 2468dcb50..40a4c1af9 100644 --- a/electrum/gui/qt/util.py +++ b/electrum/gui/qt/util.py @@ -783,6 +783,26 @@ class MyTreeView(QTreeView): self._pending_update = defer return defer + def find_row_by_key(self, key): + for row in range(0, self.std_model.rowCount()): + item = self.std_model.item(row, 0) + if item.data(self.key_role) == key: + return row + + def refresh_all(self): + for row in range(0, self.std_model.rowCount()): + item = self.std_model.item(row, 0) + key = item.data(self.key_role) + self.refresh_row(key, row) + + def refresh_item(self, key): + row = self.find_row_by_key(key) + self.refresh_row(key, row) + + def delete_item(self, key): + row = self.find_row_by_key(key) + self.std_model.takeRow(row) + self.hide_if_empty() class MySortModel(QSortFilterProxyModel): def __init__(self, parent, *, sort_role):