Skip to content

Commit

Permalink
Fix some residual issues with the invoices / payment requests.
Browse files Browse the repository at this point in the history
- The dynamic child widget freezing code in the send tab used for when a payment request was being retrieved was encountering the filtering field in the invoice list. Now the freezing code explicitly freezes the correct child widgets rather than dynamically doing it for any it finds.
- The invoice list was sorted by expiration date. This is not very helpful as 'Never' comes before any real expiration dates so unexpiring invoices came first. Now we have a 'Received' column and that's sorted by most recent to least recent by default.
- Changed the invoice state 'Pending' to 'Unpaid', as who knows what is pending really.
- Stripped down the 'Requestor' column in the invoice list to only have the domain of the payment host rather than the full URI.
  • Loading branch information
rt121212121 committed Jul 27, 2020
1 parent b342e45 commit 79abe5d
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 20 deletions.
2 changes: 1 addition & 1 deletion electrumsv/gui/qt/constants.py
Expand Up @@ -14,7 +14,7 @@
}

pr_tooltips = {
PaymentFlag.UNPAID:_('Pending'),
PaymentFlag.UNPAID:_('Unpaid'),
PaymentFlag.PAID:_('Paid'),
PaymentFlag.EXPIRED:_('Expired'),
PaymentFlag.UNKNOWN:_('Unknown'),
Expand Down
52 changes: 39 additions & 13 deletions electrumsv/gui/qt/invoice_list.py
Expand Up @@ -25,6 +25,7 @@
import math
import time
from typing import TYPE_CHECKING, Optional
import urllib.parse
import weakref

from PyQt5.QtCore import Qt, QPoint, QTimer
Expand Down Expand Up @@ -53,20 +54,29 @@
logger = logs.get_logger("invoice-list")


COL_RECEIVED = 0
COL_EXPIRES = 1
COL_REQUESTOR = 2
COL_DESCRIPTION = 3
COL_AMOUNT = 4
COL_STATUS = 5


class InvoiceList(MyTreeWidget):
filter_columns = [0, 1, 2, 3] # Date, Requestor, Description, Amount
filter_columns = [COL_RECEIVED, COL_EXPIRES, COL_REQUESTOR, COL_DESCRIPTION, COL_AMOUNT]

def __init__(self, parent: 'SendView', main_window: 'ElectrumWindow') -> None:
MyTreeWidget.__init__(self, parent, main_window, self.create_menu, [
_('Expires'), _('Requestor'), _('Description'), _('Amount'), _('Status')], 2)
_('Received'), _('Expires'), _('Requestor'), _('Description'), _('Amount'),
_('Status')], COL_DESCRIPTION)

self._send_view = parent
self._main_window = weakref.proxy(main_window)

self.monospace_font = QFont(platform.monospace_font)
self.setSortingEnabled(True)
self.header().setSectionResizeMode(1, QHeaderView.Interactive)
self.setColumnWidth(1, 200)
self.header().setSectionResizeMode(COL_REQUESTOR, QHeaderView.Interactive)
self.setColumnWidth(COL_REQUESTOR, 200)

# This is used if there is a pending expiry.
self._timer: Optional[QTimer] = None
Expand Down Expand Up @@ -98,8 +108,17 @@ def on_update(self) -> None:
return

self._stop_timer()

current_id = None
if self._send_view._payment_request is not None:
current_id = self._send_view._payment_request.get_id()
if current_id is None:
current_item = self.currentItem()
current_id = current_item.data(COL_RECEIVED, Qt.UserRole) if current_item else None

self.clear()

current_item = None
current_time = time.time()
nearest_expiry_time = float("inf")

Expand All @@ -111,20 +130,27 @@ def on_update(self) -> None:
else:
nearest_expiry_time = min(nearest_expiry_time, row.date_expires)

date_str = format_time(row.date_expires, _("Unknown")
requestor_uri = urllib.parse.urlparse(row.payment_uri)
requestor_text = requestor_uri.netloc
received_text = format_time(row.date_created, _("Unknown"))
expires_text = format_time(row.date_expires, _("Unknown")
if row.date_expires else _('Never'))
item = QTreeWidgetItem([date_str, row.payment_uri, row.description,
item = QTreeWidgetItem([received_text, expires_text, requestor_text, row.description,
app_state.format_amount(row.value, whitespaces=True),
# The tooltip text should be None to ensure the icon does not have extra RHS space.
pr_tooltips.get(flags, None)])
icon_entry = pr_icons.get(flags)
if icon_entry:
item.setIcon(4, read_QIcon(icon_entry))
item.setData(0, Qt.UserRole, row.invoice_id)
item.setFont(1, self.monospace_font)
item.setFont(3, self.monospace_font)
item.setIcon(COL_STATUS, read_QIcon(icon_entry))
if row.invoice_id == current_id:
current_item = item
item.setData(COL_RECEIVED, Qt.UserRole, row.invoice_id)
item.setFont(COL_REQUESTOR, self.monospace_font)
item.setFont(COL_DESCRIPTION, self.monospace_font)
self.addTopLevelItem(item)
self.setCurrentItem(self.topLevelItem(0))

if current_item is not None:
self.setCurrentItem(current_item)

if nearest_expiry_time != float("inf"):
self._start_timer(nearest_expiry_time)
Expand All @@ -134,7 +160,7 @@ def on_edited(self, item: QTreeWidgetItem, column: int, prior: str) -> None:
text = item.text(column).strip()
if text == "":
text = None
invoice_id = item.data(0, Qt.UserRole)
invoice_id = item.data(COL_RECEIVED, Qt.UserRole)
self._send_view._account.invoices.set_invoice_description(invoice_id, text)

def import_invoices(self, account: AbstractAccount) -> None:
Expand Down Expand Up @@ -164,7 +190,7 @@ def create_menu(self, position: QPoint) -> None:
column_title = self.headerItem().text(column)
column_data = item.text(column).strip()

invoice_id: int = item.data(0, Qt.UserRole)
invoice_id: int = item.data(COL_RECEIVED, Qt.UserRole)
row = self._send_view._account.invoices.get_invoice_for_id(invoice_id)
assert row is not None, f"invoice {invoice_id} not found"

Expand Down
8 changes: 2 additions & 6 deletions electrumsv/gui/qt/send_view.py
Expand Up @@ -192,9 +192,8 @@ def reset_max(t) -> None:
self._is_max = False
self._max_button.setEnabled(not bool(t))
self.amount_e.textEdited.connect(reset_max)
self._fiat_send_e.textEdited.connect(reset_max)

self.amount_e.textChanged.connect(self._on_entry_changed)
self._fiat_send_e.textEdited.connect(reset_max)

self._invoice_list_toolbar_layout = TableTopButtonLayout()
self._invoice_list_toolbar_layout.refresh_signal.connect(self._main_window.refresh_wallet_display)
Expand Down Expand Up @@ -277,10 +276,7 @@ def clear(self) -> None:
self._payment_request = None
self._payto_e.is_pr = False

# TODO: Clean up this with direct clears on widgets so it's not incomprehensible magic.
edit_fields = []
edit_fields.extend(self.findChildren(QPlainTextEdit))
edit_fields.extend(self.findChildren(QLineEdit))
edit_fields = (self._payto_e, self.amount_e, self._fiat_send_e, self._message_e)
for edit_field in edit_fields:
# TODO: Does this work with refresh given the ' ' refresh note in some edit.
edit_field.setText('')
Expand Down

0 comments on commit 79abe5d

Please sign in to comment.