From 5ea614c81ae6e909aaeeb7ac0f974df7bbf8f190 Mon Sep 17 00:00:00 2001 From: SomberNight Date: Mon, 23 Jun 2025 16:10:14 +0000 Subject: [PATCH] qt: qrtextedit: rm some duplication There was too much code duplication - there still is a bit... - in some places buttons had text "Read QR code with camera", in others it was "Read QR code from camera" - https://github.com/spesmilo/electrum/commit/63c224cb53739c5b4b5630e3a0bfb8208d785879 added a "on_qr_from_file_input_btn" input method, which was not added everywhere. - was missing in add_qr_input_combined_button and in editor_contextMenuEvent --- electrum/gui/qt/paytoedit.py | 16 ++++++---- electrum/gui/qt/qrtextedit.py | 19 ++++-------- electrum/gui/qt/send_tab.py | 7 ++--- electrum/gui/qt/util.py | 56 ++++++++++------------------------- 4 files changed, 34 insertions(+), 64 deletions(-) diff --git a/electrum/gui/qt/paytoedit.py b/electrum/gui/qt/paytoedit.py index f1310da6d..6bd561457 100644 --- a/electrum/gui/qt/paytoedit.py +++ b/electrum/gui/qt/paytoedit.py @@ -24,11 +24,11 @@ # SOFTWARE. from functools import partial -from typing import Optional, TYPE_CHECKING +from typing import Optional, TYPE_CHECKING, Union from PyQt6.QtCore import Qt, QTimer, QSize, QStringListModel from PyQt6.QtCore import pyqtSignal -from PyQt6.QtGui import QFontMetrics, QFont +from PyQt6.QtGui import QFontMetrics, QFont, QContextMenuEvent from PyQt6.QtWidgets import QTextEdit, QWidget, QLineEdit, QStackedLayout, QCompleter from electrum.payment_identifier import PaymentIdentifier @@ -36,7 +36,7 @@ from electrum.logging import Logger from electrum.util import EventListener, event_listener from . import util -from .util import MONOSPACE_FONT, GenericInputHandler, editor_contextMenuEvent, ColorScheme +from .util import MONOSPACE_FONT, GenericInputHandler, ColorScheme, add_input_actions_to_context_menu if TYPE_CHECKING: from .send_tab import SendTab @@ -193,8 +193,8 @@ class PayToEdit(QWidget, Logger, GenericInputHandler, EventListener): setText=self.try_payment_identifier, ) - self.text_edit.contextMenuEvent = partial(editor_contextMenuEvent, self.text_edit, self) - self.line_edit.contextMenuEvent = partial(editor_contextMenuEvent, self.line_edit, self) + self.text_edit.contextMenuEvent = partial(self.custom_context_menu_event, tl_edit=self.text_edit) + self.line_edit.contextMenuEvent = partial(self.custom_context_menu_event, tl_edit=self.line_edit) self.edit_timer = QTimer(self) self.edit_timer.setSingleShot(True) @@ -206,6 +206,12 @@ class PayToEdit(QWidget, Logger, GenericInputHandler, EventListener): self.register_callbacks() self.destroyed.connect(lambda: self.unregister_callbacks()) + def custom_context_menu_event(self, e: 'QContextMenuEvent', *, tl_edit: Union[QTextEdit, QLineEdit]) -> None: + m = tl_edit.createStandardContextMenu() + m.addSeparator() + add_input_actions_to_context_menu(self, m) + m.exec(e.globalPos()) + @event_listener def on_event_contacts_updated(self): self.update_completer() diff --git a/electrum/gui/qt/qrtextedit.py b/electrum/gui/qt/qrtextedit.py index 80bc6bbac..74205e0c8 100644 --- a/electrum/gui/qt/qrtextedit.py +++ b/electrum/gui/qt/qrtextedit.py @@ -6,7 +6,7 @@ from electrum.plugin import run_hook from electrum.simple_config import SimpleConfig from .util import ButtonsTextEdit, MessageBoxMixin, ColorScheme, read_QIcon -from .util import get_icon_camera, get_icon_qrcode +from .util import get_icon_camera, get_icon_qrcode, add_input_actions_to_context_menu class ShowQRTextEdit(ButtonsTextEdit): @@ -78,27 +78,20 @@ class ScanQRTextEdit(ButtonsTextEdit, MessageBoxMixin): def contextMenuEvent(self, e): m = self.createStandardContextMenu() m.addSeparator() - m.addAction(get_icon_camera(), _("Read QR code with camera"), self.on_qr_from_camera_input_btn) - m.addAction(read_QIcon("picture_in_picture.png"), _("Read QR code from screen"), self.on_qr_from_screenshot_input_btn) - m.addAction(read_QIcon("qr_file.png"), _("Read QR code from file"), self.on_qr_from_file_input_btn) - m.addAction(read_QIcon("file.png"), _("Read text from file"), self.on_input_file) + add_input_actions_to_context_menu(self, m) m.exec(e.globalPos()) -class ScanShowQRTextEdit(ButtonsTextEdit, MessageBoxMixin): +class ScanShowQRTextEdit(ScanQRTextEdit): - def __init__(self, text="", allow_multi: bool = False, *, config: SimpleConfig): - ButtonsTextEdit.__init__(self, text) - self.setReadOnly(False) - self.add_qr_input_combined_button(config=config, show_error=self.show_error, allow_multi=allow_multi) + def __init__(self, *args, config: SimpleConfig, **kwargs): + ScanQRTextEdit.__init__(self, *args, **kwargs, config=config) self.add_qr_show_button(config=config) - run_hook('scan_text_edit', self) run_hook('show_text_edit', self) def contextMenuEvent(self, e): m = self.createStandardContextMenu() m.addSeparator() - m.addAction(get_icon_camera(), _("Read QR code from camera"), self.on_qr_from_camera_input_btn) - m.addAction(read_QIcon("picture_in_picture.png"), _("Read QR code from screen"), self.on_qr_from_screenshot_input_btn) + add_input_actions_to_context_menu(self, m) m.addAction(get_icon_qrcode(), _("Show as QR code"), self.on_qr_show_btn) m.exec(e.globalPos()) diff --git a/electrum/gui/qt/send_tab.py b/electrum/gui/qt/send_tab.py index 22fd022a6..e82841bdd 100644 --- a/electrum/gui/qt/send_tab.py +++ b/electrum/gui/qt/send_tab.py @@ -25,7 +25,7 @@ from electrum.fee_policy import FeePolicy, FixedFeePolicy from .amountedit import AmountEdit, BTCAmountEdit, SizedFreezableLineEdit from .paytoedit import InvalidPaymentIdentifier from .util import (WaitingDialog, HelpLabel, MessageBoxMixin, EnterButton, char_width_in_lineedit, - get_icon_camera, read_QIcon, ColorScheme, IconLabel, Spinner) + get_icon_camera, read_QIcon, ColorScheme, IconLabel, Spinner, add_input_actions_to_context_menu) from .invoice_list import InvoiceList if TYPE_CHECKING: @@ -178,10 +178,7 @@ class SendTab(QWidget, MessageBoxMixin, Logger): self.invoice_list = InvoiceList(self) self.toolbar, menu = self.invoice_list.create_toolbar_with_menu('') - menu.addAction(get_icon_camera(), _("Read QR code with camera"), self.payto_e.on_qr_from_camera_input_btn) - menu.addAction(read_QIcon("picture_in_picture.png"), _("Read QR code from screen"), self.payto_e.on_qr_from_screenshot_input_btn) - menu.addAction(read_QIcon("qr_file.png"), _("Read QR code from file"), self.payto_e.on_qr_from_file_input_btn) - menu.addAction(read_QIcon("file.png"), _("Read invoice from file"), self.payto_e.on_input_file) + add_input_actions_to_context_menu(self.payto_e, menu) self.paytomany_menu = menu.addToggle(_("&Pay to many"), self.toggle_paytomany) menu.addSeparator() menu.addAction(_("Import invoices"), self.window.import_invoices) diff --git a/electrum/gui/qt/util.py b/electrum/gui/qt/util.py index b41159c44..007c687fc 100644 --- a/electrum/gui/qt/util.py +++ b/electrum/gui/qt/util.py @@ -726,13 +726,15 @@ def get_icon_camera() -> QIcon: return read_QIcon(name) -def editor_contextMenuEvent(self, p: 'PayToEdit', e: 'QContextMenuEvent') -> None: - m = self.createStandardContextMenu() - m.addSeparator() - m.addAction(get_icon_camera(), _("Read QR code with camera"), p.on_qr_from_camera_input_btn) - m.addAction(read_QIcon("picture_in_picture.png"), _("Read QR code from screen"), p.on_qr_from_screenshot_input_btn) - m.addAction(read_QIcon("file.png"), _("Read file"), p.on_input_file) - m.exec(e.globalPos()) +def add_input_actions_to_context_menu(gih: 'GenericInputHandler', m: QMenu) -> None: + if gih.on_qr_from_camera_input_btn: + m.addAction(get_icon_camera(), _("Read QR code with camera"), gih.on_qr_from_camera_input_btn) + if gih.on_qr_from_screenshot_input_btn: + m.addAction(read_QIcon("picture_in_picture.png"), _("Read QR code from screen"), gih.on_qr_from_screenshot_input_btn) + if gih.on_qr_from_file_input_btn: + m.addAction(read_QIcon("qr_file.png"), _("Read QR code from file"), gih.on_qr_from_file_input_btn) + if gih.on_input_file: + m.addAction(read_QIcon("file.png"), _("Read text from file"), gih.on_input_file) def scan_qr_from_screenshot() -> QrCodeResult: @@ -758,6 +760,11 @@ def scan_qr_from_screenshot() -> QrCodeResult: class GenericInputHandler: + on_qr_from_camera_input_btn: Callable[[], None] = None + on_qr_from_screenshot_input_btn: Callable[[], None] = None + on_qr_from_file_input_btn: Callable[[], None] = None + on_input_file: Callable[[], None] = None + def input_qr_from_camera( self, *, @@ -1019,39 +1026,6 @@ class OverlayControlMixin(GenericInputHandler): # side-effect: we export this method: self.on_qr_show_btn = qr_show - def add_qr_input_combined_button( - self, - *, - config: 'SimpleConfig', - allow_multi: bool = False, - show_error: Callable[[str], None], - setText: Callable[[str], None] = None, - ): - input_qr_from_camera = partial( - self.input_qr_from_camera, - config=config, - allow_multi=allow_multi, - show_error=show_error, - setText=setText, - ) - input_qr_from_screenshot = partial( - self.input_qr_from_screenshot, - allow_multi=allow_multi, - show_error=show_error, - setText=setText, - ) - self.add_menu_button( - icon=get_icon_camera(), - tooltip=_("Read QR code"), - options=[ - (get_icon_camera(), _("Read QR code from camera"), input_qr_from_camera), - ("picture_in_picture.png", _("Read QR code from screen"), input_qr_from_screenshot), - ], - ) - # side-effect: we export these methods: - self.on_qr_from_camera_input_btn = input_qr_from_camera - self.on_qr_from_screenshot_input_btn = input_qr_from_screenshot - def add_qr_input_from_camera_button( self, *, @@ -1067,7 +1041,7 @@ class OverlayControlMixin(GenericInputHandler): show_error=show_error, setText=setText, ) - self.addButton(get_icon_camera(), input_qr_from_camera, _("Read QR code from camera")) + self.addButton(get_icon_camera(), input_qr_from_camera, _("Read QR code with camera")) # side-effect: we export these methods: self.on_qr_from_camera_input_btn = input_qr_from_camera