diff --git a/electrum/contacts.py b/electrum/contacts.py index 6a2378239..76a5d1eb0 100644 --- a/electrum/contacts.py +++ b/electrum/contacts.py @@ -63,6 +63,7 @@ class Contacts(dict, Logger): def save(self): self.db.put('contacts', dict(self)) + trigger_callback('contacts_updated') def import_file(self, path): data = read_json_file(path) diff --git a/electrum/gui/qt/paytoedit.py b/electrum/gui/qt/paytoedit.py index 283dc05f6..f1310da6d 100644 --- a/electrum/gui/qt/paytoedit.py +++ b/electrum/gui/qt/paytoedit.py @@ -26,13 +26,14 @@ from functools import partial from typing import Optional, TYPE_CHECKING -from PyQt6.QtCore import Qt, QTimer, QSize +from PyQt6.QtCore import Qt, QTimer, QSize, QStringListModel from PyQt6.QtCore import pyqtSignal from PyQt6.QtGui import QFontMetrics, QFont -from PyQt6.QtWidgets import QTextEdit, QWidget, QLineEdit, QStackedLayout +from PyQt6.QtWidgets import QTextEdit, QWidget, QLineEdit, QStackedLayout, QCompleter from electrum.payment_identifier import PaymentIdentifier from electrum.logging import Logger +from electrum.util import EventListener, event_listener from . import util from .util import MONOSPACE_FONT, GenericInputHandler, editor_contextMenuEvent, ColorScheme @@ -94,7 +95,7 @@ class ResizingTextEdit(QTextEdit): return QSize(0, self.minimumHeight()) -class PayToEdit(QWidget, Logger, GenericInputHandler): +class PayToEdit(QWidget, Logger, GenericInputHandler, EventListener): paymentIdentifierChanged = pyqtSignal() textChanged = pyqtSignal() @@ -107,6 +108,8 @@ class PayToEdit(QWidget, Logger, GenericInputHandler): self._layout = QStackedLayout() self.setLayout(self._layout) + self.send_tab = send_tab + def text_edit_changed(): text = self.text_edit.toPlainText() if self._text != text: @@ -133,6 +136,21 @@ class PayToEdit(QWidget, Logger, GenericInputHandler): self.text_edit.textReallyChanged.connect(text_edit_changed) self.text_edit.resized.connect(text_edit_resized) + def on_completed(item: str): + text = self._completer_contacts[1][self._completer_contacts[0].index(item)] + self.try_payment_identifier(text) + self.completer.popup().hide() + + self.completer = QCompleter() + self.completer.setCompletionMode(QCompleter.CompletionMode.PopupCompletion) + self.completer.setCaseSensitivity(Qt.CaseSensitivity.CaseInsensitive) + self.completer.setFilterMode(Qt.MatchFlag.MatchContains) + self.completer.activated.connect(on_completed) + + self.update_completer() + + self.line_edit.setCompleter(self.completer) + self.textChanged.connect(self._handle_text_change) self._layout.addWidget(self.line_edit) @@ -185,6 +203,21 @@ class PayToEdit(QWidget, Logger, GenericInputHandler): self.payment_identifier = None # type: Optional[PaymentIdentifier] + self.register_callbacks() + self.destroyed.connect(lambda: self.unregister_callbacks()) + + @event_listener + def on_event_contacts_updated(self): + self.update_completer() + + def update_completer(self): + self._completer_contacts = [], [] + for k, v in self.send_tab.wallet.contacts.items(): + self._completer_contacts[0].append(f'{v[1]} <{k}>') + self._completer_contacts[1].append(k) + + self.completer.setModel(QStringListModel(self._completer_contacts[0])) + @property def multiline(self): return self._multiline