diff --git a/electrum/gui/qt/qrtextedit.py b/electrum/gui/qt/qrtextedit.py index a7cb553bc..7a23ef5ee 100644 --- a/electrum/gui/qt/qrtextedit.py +++ b/electrum/gui/qt/qrtextedit.py @@ -1,95 +1,21 @@ -from functools import partial -from typing import Callable - from electrum.i18n import _ from electrum.plugin import run_hook from electrum.simple_config import SimpleConfig -from .util import ButtonsTextEdit, MessageBoxMixin, ColorScheme, getOpenFileName -from .qrreader import scan_qrcode - - -def qr_show(text_edit, *, config: SimpleConfig) -> None: - from .qrcodewidget import QRDialog - try: - s = str(text_edit.text()) - except: - s = text_edit.text() - if not s: - return - QRDialog( - data=s, - parent=text_edit, - config=config, - ).exec_() - - -def qr_input( - text_edit, - *, - config: SimpleConfig, - allow_multi: bool = False, - show_error: Callable[[str], None], -) -> None: - def cb(success: bool, error: str, data): - if not success: - if error: - show_error(error) - return - if not data: - data = '' - if allow_multi: - new_text = text_edit.text() + data + '\n' - else: - new_text = data - text_edit.setText(new_text) - - scan_qrcode(parent=text_edit, config=config, callback=cb) - - -def file_input( - text_edit, - *, - config: SimpleConfig, - show_error: Callable[[str], None], -) -> None: - fileName = getOpenFileName( - parent=text_edit, - title='select file', - config=config, - ) - if not fileName: - return - try: - try: - with open(fileName, "r") as f: - data = f.read() - except UnicodeError as e: - with open(fileName, "rb") as f: - data = f.read() - data = data.hex() - except BaseException as e: - show_error(_('Error opening file') + ':\n' + repr(e)) - else: - text_edit.setText(data) +from .util import ButtonsTextEdit, MessageBoxMixin class ShowQRTextEdit(ButtonsTextEdit): def __init__(self, text=None, *, config: SimpleConfig): ButtonsTextEdit.__init__(self, text) - self.config = config self.setReadOnly(True) - # qr_show - self.qr_show = partial(qr_show, self, config=config) - icon = "qrcode_white.png" if ColorScheme.dark_scheme else "qrcode.png" - self.addButton(icon, self.qr_show, _("Show as QR code")) - + self.add_qr_show_button(config=config) run_hook('show_text_edit', self) def contextMenuEvent(self, e): m = self.createStandardContextMenu() - m.addAction(_("Show as QR code"), self.qr_show) + m.addAction(_("Show as QR code"), self.on_qr_show_btn) m.exec_(e.globalPos()) @@ -97,21 +23,14 @@ class ScanQRTextEdit(ButtonsTextEdit, MessageBoxMixin): def __init__(self, text="", allow_multi: bool = False, *, config: SimpleConfig): ButtonsTextEdit.__init__(self, text) - self.config = config self.setReadOnly(False) - # file_input - self.file_input = partial(file_input, self, config=config, show_error=self.show_error) - self.addButton("file.png", self.file_input, _("Read file")) - # qr_input - self.qr_input = partial(qr_input, self, config=config, show_error=self.show_error, allow_multi=allow_multi) - icon = "camera_white.png" if ColorScheme.dark_scheme else "camera_dark.png" - self.addButton(icon, self.qr_input, _("Read QR code")) - + self.add_file_input_button(config=config, show_error=self.show_error) + self.add_qr_input_button(config=config, show_error=self.show_error, allow_multi=allow_multi) run_hook('scan_text_edit', self) def contextMenuEvent(self, e): m = self.createStandardContextMenu() - m.addAction(_("Read QR code"), self.qr_input) + m.addAction(_("Read QR code"), self.on_qr_input_btn) m.exec_(e.globalPos()) @@ -119,22 +38,14 @@ class ScanShowQRTextEdit(ButtonsTextEdit, MessageBoxMixin): def __init__(self, text="", allow_multi: bool = False, *, config: SimpleConfig): ButtonsTextEdit.__init__(self, text) - self.config = config self.setReadOnly(False) - # qr_input - self.qr_input = partial(qr_input, self, config=config, show_error=self.show_error, allow_multi=allow_multi) - icon = "camera_white.png" if ColorScheme.dark_scheme else "camera_dark.png" - self.addButton(icon, self.qr_input, _("Read QR code")) - # qr_show - self.qr_show = partial(qr_show, self, config=config) - icon = "qrcode_white.png" if ColorScheme.dark_scheme else "qrcode.png" - self.addButton(icon, self.qr_show, _("Show as QR code")) - + self.add_qr_input_button(config=config, show_error=self.show_error, allow_multi=allow_multi) + 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.addAction(_("Read QR code"), self.qr_input) - m.addAction(_("Show as QR code"), self.qr_show) + m.addAction(_("Read QR code"), self.on_qr_input_btn) + m.addAction(_("Show as QR code"), self.on_qr_show_btn) m.exec_(e.globalPos()) diff --git a/electrum/gui/qt/util.py b/electrum/gui/qt/util.py index 0ad39346d..52e23339b 100644 --- a/electrum/gui/qt/util.py +++ b/electrum/gui/qt/util.py @@ -853,7 +853,7 @@ class ButtonsWidget(QWidget): self.buttons.append(button) return button - def addCopyButton(self, app): + def addCopyButton(self, app: QApplication): self.app = app self.addButton("copy.png", self.on_copy, _("Copy to clipboard")) @@ -861,13 +861,91 @@ class ButtonsWidget(QWidget): self.app.clipboard().setText(self.text()) QToolTip.showText(QCursor.pos(), _("Text copied to clipboard"), self) - def addPasteButton(self, app): + def addPasteButton(self, app: QApplication): self.app = app self.addButton("copy.png", self.on_paste, _("Paste from clipboard")) def on_paste(self): self.setText(self.app.clipboard().text()) + def add_qr_show_button(self, *, config: 'SimpleConfig'): + def qr_show(): + from .qrcodewidget import QRDialog + try: + s = str(self.text()) + except: + s = self.text() + if not s: + return + QRDialog( + data=s, + parent=self, + config=config, + ).exec_() + + icon = "qrcode_white.png" if ColorScheme.dark_scheme else "qrcode.png" + self.addButton(icon, qr_show, _("Show as QR code")) + # side-effect: we export this method: + self.on_qr_show_btn = qr_show + + def add_qr_input_button( + self, + *, + config: 'SimpleConfig', + allow_multi: bool = False, + show_error: Callable[[str], None], + ): + def qr_input(): + def cb(success: bool, error: str, data): + if not success: + if error: + show_error(error) + return + if not data: + data = '' + if allow_multi: + new_text = self.text() + data + '\n' + else: + new_text = data + self.setText(new_text) + + from .qrreader import scan_qrcode + scan_qrcode(parent=self, config=config, callback=cb) + + icon = "camera_white.png" if ColorScheme.dark_scheme else "camera_dark.png" + self.addButton(icon, qr_input, _("Read QR code")) + # side-effect: we export this method: + self.on_qr_input_btn = qr_input + + def add_file_input_button( + self, + *, + config: 'SimpleConfig', + show_error: Callable[[str], None], + ) -> None: + def file_input(): + fileName = getOpenFileName( + parent=self, + title='select file', + config=config, + ) + if not fileName: + return + try: + try: + with open(fileName, "r") as f: + data = f.read() + except UnicodeError as e: + with open(fileName, "rb") as f: + data = f.read() + data = data.hex() + except BaseException as e: + show_error(_('Error opening file') + ':\n' + repr(e)) + else: + self.setText(data) + + self.addButton("file.png", file_input, _("Read file")) + class ButtonsLineEdit(QLineEdit, ButtonsWidget): def __init__(self, text=None):