From 34a8ec64f8d77cb8dc12e2d7290454831f7e4f18 Mon Sep 17 00:00:00 2001 From: ThomasV Date: Tue, 15 Apr 2025 13:26:54 +0200 Subject: [PATCH] move audio_modem icons to plugin dir, so that the plugin is self-contained. This requires changing the API of OverlayControlMixin.addButton --- electrum/gui/qml/components/TxDetails.qml | 2 +- electrum/gui/qt/qrtextedit.py | 10 ++--- electrum/gui/qt/receive_tab.py | 4 +- electrum/gui/qt/send_tab.py | 4 +- electrum/gui/qt/transaction_dialog.py | 4 +- electrum/gui/qt/util.py | 36 +++++++++--------- electrum/plugins/audio_modem/manifest.json | 1 + .../audio_modem}/microphone.png | Bin electrum/plugins/audio_modem/qt.py | 12 +++--- .../icons => plugins/audio_modem}/speaker.png | Bin electrum/plugins/bitbox02/qt.py | 4 +- 11 files changed, 41 insertions(+), 36 deletions(-) rename electrum/{gui/icons => plugins/audio_modem}/microphone.png (100%) rename electrum/{gui/icons => plugins/audio_modem}/speaker.png (100%) diff --git a/electrum/gui/qml/components/TxDetails.qml b/electrum/gui/qml/components/TxDetails.qml index c2240d54d..6c87fbd38 100644 --- a/electrum/gui/qml/components/TxDetails.qml +++ b/electrum/gui/qml/components/TxDetails.qml @@ -416,7 +416,7 @@ Pane { FlatButton { Layout.fillWidth: true Layout.preferredWidth: 1 - icon.source: '../../icons/microphone.png' + icon.source: '../../icons/tab_send.png' text: qsTr('Broadcast') visible: txdetails.canBroadcast enabled: !txdetails.lockDelay diff --git a/electrum/gui/qt/qrtextedit.py b/electrum/gui/qt/qrtextedit.py index c8172f7bb..54514d548 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_iconname_camera, get_iconname_qrcode +from .util import get_icon_camera, get_icon_qrcode class ShowQRTextEdit(ButtonsTextEdit): @@ -19,7 +19,7 @@ class ShowQRTextEdit(ButtonsTextEdit): def contextMenuEvent(self, e): m = self.createStandardContextMenu() - m.addAction(read_QIcon(get_iconname_qrcode()), _("Show as QR code"), self.on_qr_show_btn) + m.addAction(get_icon_qrcode(), _("Show as QR code"), self.on_qr_show_btn) m.exec(e.globalPos()) @@ -70,7 +70,7 @@ class ScanQRTextEdit(ButtonsTextEdit, MessageBoxMixin): def contextMenuEvent(self, e): m = self.createStandardContextMenu() m.addSeparator() - m.addAction(read_QIcon(get_iconname_camera()), _("Read QR code with camera"), self.on_qr_from_camera_input_btn) + 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("file.png"), _("Read file"), self.on_input_file) m.exec(e.globalPos()) @@ -89,7 +89,7 @@ class ScanShowQRTextEdit(ButtonsTextEdit, MessageBoxMixin): def contextMenuEvent(self, e): m = self.createStandardContextMenu() m.addSeparator() - m.addAction(read_QIcon(get_iconname_camera()), _("Read QR code from camera"), self.on_qr_from_camera_input_btn) + 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) - m.addAction(read_QIcon(get_iconname_qrcode()), _("Show as QR code"), self.on_qr_show_btn) + m.addAction(get_icon_qrcode(), _("Show as QR code"), self.on_qr_show_btn) m.exec(e.globalPos()) diff --git a/electrum/gui/qt/receive_tab.py b/electrum/gui/qt/receive_tab.py index eb0f4a8b7..be2bf0a00 100644 --- a/electrum/gui/qt/receive_tab.py +++ b/electrum/gui/qt/receive_tab.py @@ -16,7 +16,7 @@ from electrum.logging import Logger from .amountedit import AmountEdit, BTCAmountEdit, SizedFreezableLineEdit from .qrcodewidget import QRCodeWidget -from .util import read_QIcon, WWLabel, MessageBoxMixin, MONOSPACE_FONT, get_iconname_qrcode +from .util import read_QIcon, WWLabel, MessageBoxMixin, MONOSPACE_FONT, get_icon_qrcode if TYPE_CHECKING: from .main_window import ElectrumWindow @@ -144,7 +144,7 @@ class ReceiveTab(QWidget, MessageBoxMixin, Logger): self.toolbar, menu = self.request_list.create_toolbar_with_menu('') self.toggle_qr_button = QPushButton('') - self.toggle_qr_button.setIcon(read_QIcon(get_iconname_qrcode())) + self.toggle_qr_button.setIcon(get_icon_qrcode()) self.toggle_qr_button.setToolTip(_('Switch between text and QR code view')) self.toggle_qr_button.clicked.connect(self.toggle_receive_qr) self.toggle_qr_button.setEnabled(False) diff --git a/electrum/gui/qt/send_tab.py b/electrum/gui/qt/send_tab.py index dd73c3eb5..81c9ca3fd 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_iconname_camera, read_QIcon, ColorScheme, IconLabel, Spinner) + get_icon_camera, read_QIcon, ColorScheme, IconLabel, Spinner) from .invoice_list import InvoiceList if TYPE_CHECKING: @@ -178,7 +178,7 @@ class SendTab(QWidget, MessageBoxMixin, Logger): self.invoice_list = InvoiceList(self) self.toolbar, menu = self.invoice_list.create_toolbar_with_menu('') - menu.addAction(read_QIcon(get_iconname_camera()), _("Read QR code with camera"), self.payto_e.on_qr_from_camera_input_btn) + 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("file.png"), _("Read invoice from file"), self.payto_e.on_input_file) self.paytomany_menu = menu.addToggle(_("&Pay to many"), self.toggle_paytomany) diff --git a/electrum/gui/qt/transaction_dialog.py b/electrum/gui/qt/transaction_dialog.py index 64abfcb28..07b377f5b 100644 --- a/electrum/gui/qt/transaction_dialog.py +++ b/electrum/gui/qt/transaction_dialog.py @@ -57,7 +57,7 @@ from .util import (MessageBoxMixin, read_QIcon, Buttons, icon_path, TRANSACTION_FILE_EXTENSION_FILTER_ONLY_COMPLETE_TX, TRANSACTION_FILE_EXTENSION_FILTER_ONLY_PARTIAL_TX, getSaveFileName, ColorSchemeItem, - get_iconname_qrcode, VLine, WaitingDialog) + get_icon_qrcode, VLine, WaitingDialog) from .rate_limiter import rate_limited from .my_treeview import create_toolbar_with_menu, QMenuWithConfig @@ -628,7 +628,7 @@ class TxDialog(QDialog, MessageBoxMixin): action.triggered.connect(lambda: self.copy_to_clipboard(tx=gettx())) menu.addAction(action) - action = QAction(read_QIcon(get_iconname_qrcode()), _("Show as QR code"), self) + action = QAction(get_icon_qrcode(), _("Show as QR code"), self) action.triggered.connect(lambda: self.show_qr(tx=gettx())) menu.addAction(action) diff --git a/electrum/gui/qt/util.py b/electrum/gui/qt/util.py index 6ee320b1d..7dee6a8f5 100644 --- a/electrum/gui/qt/util.py +++ b/electrum/gui/qt/util.py @@ -669,18 +669,20 @@ def filename_field(parent, config, defaultname, select_msg): return vbox, filename_e, b1 -def get_iconname_qrcode() -> str: - return "qrcode_white.png" if ColorScheme.dark_scheme else "qrcode.png" +def get_icon_qrcode() -> str: + name = "qrcode_white.png" if ColorScheme.dark_scheme else "qrcode.png" + return read_QIcon(name) -def get_iconname_camera() -> str: - return "camera_white.png" if ColorScheme.dark_scheme else "camera_dark.png" +def get_icon_camera() -> str: + name = "camera_white.png" if ColorScheme.dark_scheme else "camera_dark.png" + return read_QIcon(name) def editor_contextMenuEvent(self, p: 'PayToEdit', e: 'QContextMenuEvent') -> None: m = self.createStandardContextMenu() m.addSeparator() - m.addAction(read_QIcon(get_iconname_camera()), _("Read QR code with camera"), p.on_qr_from_camera_input_btn) + 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()) @@ -872,10 +874,10 @@ class OverlayControlMixin(GenericInputHandler): # The old code positioned the items the other way around, so we just insert at position 0 instead self.overlay_layout.insertWidget(0, widget) - def addButton(self, icon_name: str, on_click, tooltip: str) -> QPushButton: + def addButton(self, icon: QIcon, on_click, tooltip: str) -> QPushButton: button = QPushButton(self.overlay_widget) button.setToolTip(tooltip) - button.setIcon(read_QIcon(icon_name)) + button.setIcon(icon) button.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) button.clicked.connect(on_click) self.addWidget(button) @@ -886,8 +888,7 @@ class OverlayControlMixin(GenericInputHandler): app = QApplication.instance() app.clipboard().setText(self.text()) QToolTip.showText(QCursor.pos(), _("Text copied to clipboard"), self) - - self.addButton("copy.png", on_copy, _("Copy to clipboard")) + self.addButton(read_QIcon("copy.png"), on_copy, _("Copy to clipboard")) def addPasteButton( self, @@ -898,7 +899,7 @@ class OverlayControlMixin(GenericInputHandler): self.input_paste_from_clipboard, setText=setText, ) - self.addButton("copy.png", input_paste_from_clipboard, _("Paste from clipboard")) + self.addButton(read_QIcon("copy.png"), input_paste_from_clipboard, _("Paste from clipboard")) def add_qr_show_button(self, *, config: 'SimpleConfig', title: Optional[str] = None): if title is None: @@ -919,7 +920,7 @@ class OverlayControlMixin(GenericInputHandler): config=config, ).exec() - self.addButton(get_iconname_qrcode(), qr_show, _("Show as QR code")) + self.addButton(get_icon_qrcode(), qr_show, _("Show as QR code")) # side-effect: we export this method: self.on_qr_show_btn = qr_show @@ -945,10 +946,10 @@ class OverlayControlMixin(GenericInputHandler): setText=setText, ) self.add_menu_button( - icon=get_iconname_camera(), + icon=get_icon_camera(), tooltip=_("Read QR code"), options=[ - (get_iconname_camera(), _("Read QR code from camera"), input_qr_from_camera), + (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), ], ) @@ -971,7 +972,7 @@ class OverlayControlMixin(GenericInputHandler): show_error=show_error, setText=setText, ) - self.addButton(get_iconname_camera(), input_qr_from_camera, _("Read QR code from camera")) + self.addButton(get_icon_camera(), input_qr_from_camera, _("Read QR code from camera")) # side-effect: we export these methods: self.on_qr_from_camera_input_btn = input_qr_from_camera @@ -988,17 +989,18 @@ class OverlayControlMixin(GenericInputHandler): show_error=show_error, setText=setText, ) - self.addButton("file.png", input_file, _("Read file")) + self.addButton(read_QIcon("file.png"), input_file, _("Read file")) def add_menu_button( self, *, options: Sequence[Tuple[Optional[str], str, Callable[[], None]]], # list of (icon, text, cb) - icon: Optional[str] = None, + icon: Optional[QIcon] = None, tooltip: Optional[str] = None, ): if icon is None: - icon = "menu_vertical_white.png" if ColorScheme.dark_scheme else "menu_vertical.png" + icon_name = "menu_vertical_white.png" if ColorScheme.dark_scheme else "menu_vertical.png" + icon = read_QIcon(icon_name) if tooltip is None: tooltip = _("Other options") btn = self.addButton(icon, lambda: None, tooltip) diff --git a/electrum/plugins/audio_modem/manifest.json b/electrum/plugins/audio_modem/manifest.json index cdbc6d9bc..3bad0fcd6 100644 --- a/electrum/plugins/audio_modem/manifest.json +++ b/electrum/plugins/audio_modem/manifest.json @@ -3,5 +3,6 @@ "fullname": "Audio MODEM", "description": "Provides support for air-gapped transaction signing.", "requires": [["amodem", "http://github.com/romanz/amodem/"]], + "icon":"speaker.png", "available_for": ["qt"] } diff --git a/electrum/gui/icons/microphone.png b/electrum/plugins/audio_modem/microphone.png similarity index 100% rename from electrum/gui/icons/microphone.png rename to electrum/plugins/audio_modem/microphone.png diff --git a/electrum/plugins/audio_modem/qt.py b/electrum/plugins/audio_modem/qt.py index 39c3159d6..937498042 100644 --- a/electrum/plugins/audio_modem/qt.py +++ b/electrum/plugins/audio_modem/qt.py @@ -12,6 +12,7 @@ from electrum.plugin import BasePlugin, hook from electrum.gui.qt.util import WaitingDialog, EnterButton, WindowModalDialog, read_QIcon from electrum.i18n import _ from electrum.logging import get_logger +from electrum.gui.qt.util import read_QIcon_from_bytes if TYPE_CHECKING: from electrum.gui.qt.transaction_dialog import TxDialog @@ -74,8 +75,8 @@ class Plugin(BasePlugin): @hook def transaction_dialog(self, dialog: 'TxDialog'): b = QPushButton() - b.setIcon(read_QIcon("speaker.png")) - + icon = read_QIcon_from_bytes(self.read_file("speaker.png")) + b.setIcon(icon) def handler(): blob = dialog.tx.serialize() self._send(parent=dialog, blob=blob) @@ -84,15 +85,16 @@ class Plugin(BasePlugin): @hook def scan_text_edit(self, parent): - parent.addButton('microphone.png', partial(self._recv, parent), - _("Read from microphone")) + icon = read_QIcon_from_bytes(self.read_file("microphone.png")) + parent.addButton(icon, partial(self._recv, parent), _("Read from microphone")) @hook def show_text_edit(self, parent): def handler(): blob = str(parent.toPlainText()) self._send(parent=parent, blob=blob) - parent.addButton('speaker.png', handler, _("Send to speaker")) + icon = read_QIcon_from_bytes(self.read_file("speaker.png")) + parent.addButton(icon, handler, _("Send to speaker")) def _audio_interface(self): interface = amodem.audio.Interface(config=self.modem_config) diff --git a/electrum/gui/icons/speaker.png b/electrum/plugins/audio_modem/speaker.png similarity index 100% rename from electrum/gui/icons/speaker.png rename to electrum/plugins/audio_modem/speaker.png diff --git a/electrum/plugins/bitbox02/qt.py b/electrum/plugins/bitbox02/qt.py index 1ed04a600..089063a7e 100644 --- a/electrum/plugins/bitbox02/qt.py +++ b/electrum/plugins/bitbox02/qt.py @@ -14,7 +14,7 @@ from electrum.hw_wallet.qt import QtHandlerBase, QtPluginBase from electrum.hw_wallet.plugin import only_hook_if_libraries_available, OperationCancelled from electrum.gui.qt.wizard.wallet import WCScriptAndDerivation, WCHWUnlock, WCHWUninitialized, WCHWXPub -from electrum.gui.qt.util import WindowModalDialog, OkButton, ButtonsTextEdit +from electrum.gui.qt.util import WindowModalDialog, OkButton, ButtonsTextEdit, read_QIcon if TYPE_CHECKING: from electrum.gui.qt.wizard.wallet import QENewWalletWizard @@ -58,7 +58,7 @@ class Plugin(BitBox02Plugin, QtPluginBase): ) device_name = "{} ({})".format(self.device, keystore.label) - mpk_text.addButton("eye1.png", on_button_click, _("Show on {}").format(device_name)) + mpk_text.addButton(read_QIcon("eye1.png"), on_button_click, _("Show on {}").format(device_name)) @hook def init_wallet_wizard(self, wizard: 'QENewWalletWizard'):