plugins: move wallet-related settings to the wallet menu
Plugins should use the init_menubar hook. References are kept to the various menu objects.
This commit is contained in:
@@ -706,50 +706,49 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener):
|
|||||||
def init_menubar(self):
|
def init_menubar(self):
|
||||||
menubar = QMenuBar()
|
menubar = QMenuBar()
|
||||||
|
|
||||||
file_menu = menubar.addMenu(_("&File"))
|
self.file_menu = menubar.addMenu(_("&File"))
|
||||||
self.recently_visited_menu = file_menu.addMenu(_("&Recently open"))
|
self.recently_visited_menu = self.file_menu.addMenu(_("&Recently open"))
|
||||||
file_menu.addAction(_("&Open"), self.open_wallet).setShortcut(QKeySequence.StandardKey.Open)
|
self.file_menu.addAction(_("&Open"), self.open_wallet).setShortcut(QKeySequence.StandardKey.Open)
|
||||||
file_menu.addAction(_("&New/Restore"), self.new_wallet).setShortcut(QKeySequence.StandardKey.New)
|
self.file_menu.addAction(_("&New/Restore"), self.new_wallet).setShortcut(QKeySequence.StandardKey.New)
|
||||||
file_menu.addAction(_("&Save backup"), self.backup_wallet).setShortcut(QKeySequence.StandardKey.SaveAs)
|
self.file_menu.addAction(_("&Save backup"), self.backup_wallet).setShortcut(QKeySequence.StandardKey.SaveAs)
|
||||||
file_menu.addAction(_("Delete"), self.remove_wallet)
|
self.file_menu.addAction(_("Delete"), self.remove_wallet)
|
||||||
file_menu.addSeparator()
|
self.file_menu.addSeparator()
|
||||||
file_menu.addAction(_("&Quit"), self.close)
|
self.file_menu.addAction(_("&Quit"), self.close)
|
||||||
|
|
||||||
wallet_menu = menubar.addMenu(_("&Wallet"))
|
self.wallet_menu = menubar.addMenu(_("&Wallet"))
|
||||||
wallet_menu.addAction(_("&Information"), self.show_wallet_info)
|
self.wallet_menu.addAction(_("&Information"), self.show_wallet_info)
|
||||||
wallet_menu.addSeparator()
|
self.wallet_menu.addSeparator()
|
||||||
self.password_menu = wallet_menu.addAction(_("&Password"), self.change_password_dialog)
|
|
||||||
self.seed_menu = wallet_menu.addAction(_("&Seed"), self.show_seed_dialog)
|
self.password_menu = self.wallet_menu.addAction(_("&Password"), self.change_password_dialog)
|
||||||
self.private_keys_menu = wallet_menu.addMenu(_("&Private keys"))
|
self.seed_menu = self.wallet_menu.addAction(_("&Seed"), self.show_seed_dialog)
|
||||||
|
self.private_keys_menu = self.wallet_menu.addMenu(_("&Private keys"))
|
||||||
self.private_keys_menu.addAction(_("&Sweep"), self.sweep_key_dialog)
|
self.private_keys_menu.addAction(_("&Sweep"), self.sweep_key_dialog)
|
||||||
self.import_privkey_menu = self.private_keys_menu.addAction(_("&Import"), self.do_import_privkey)
|
self.import_privkey_menu = self.private_keys_menu.addAction(_("&Import"), self.do_import_privkey)
|
||||||
self.export_menu = self.private_keys_menu.addAction(_("&Export"), self.export_privkeys_dialog)
|
self.export_menu = self.private_keys_menu.addAction(_("&Export"), self.export_privkeys_dialog)
|
||||||
self.import_address_menu = wallet_menu.addAction(_("Import addresses"), self.import_addresses)
|
self.import_address_menu = self.wallet_menu.addAction(_("Import addresses"), self.import_addresses)
|
||||||
wallet_menu.addSeparator()
|
|
||||||
|
|
||||||
labels_menu = wallet_menu.addMenu(_("&Labels"))
|
self.labels_menu = self.wallet_menu.addMenu(_("&Labels"))
|
||||||
labels_menu.addAction(_("&Import"), self.do_import_labels)
|
self.labels_menu.addAction(_("&Import"), self.do_import_labels)
|
||||||
labels_menu.addAction(_("&Export"), self.do_export_labels)
|
self.labels_menu.addAction(_("&Export"), self.do_export_labels)
|
||||||
|
|
||||||
wallet_menu.addSeparator()
|
self.wallet_menu.addAction(_("Find"), self.toggle_search).setShortcut(QKeySequence("Ctrl+F"))
|
||||||
wallet_menu.addAction(_("Find"), self.toggle_search).setShortcut(QKeySequence("Ctrl+F"))
|
self.wallet_menu.addSeparator()
|
||||||
|
|
||||||
def add_toggle_action(view_menu, tab):
|
def add_toggle_action(tab):
|
||||||
is_shown = tab.is_shown_cv.get()
|
is_shown = tab.is_shown_cv.get()
|
||||||
tab.menu_action = view_menu.addAction(tab.tab_description, lambda: self.toggle_tab(tab))
|
tab.menu_action = self.view_menu.addAction(tab.tab_description, lambda: self.toggle_tab(tab))
|
||||||
tab.menu_action.setCheckable(True)
|
tab.menu_action.setCheckable(True)
|
||||||
tab.menu_action.setChecked(is_shown)
|
tab.menu_action.setChecked(is_shown)
|
||||||
|
self.view_menu = menubar.addMenu(_("&View"))
|
||||||
|
add_toggle_action(self.addresses_tab)
|
||||||
|
add_toggle_action(self.utxo_tab)
|
||||||
|
add_toggle_action(self.channels_tab)
|
||||||
|
add_toggle_action(self.contacts_tab)
|
||||||
|
add_toggle_action(self.console_tab)
|
||||||
|
add_toggle_action(self.notes_tab)
|
||||||
|
|
||||||
view_menu = menubar.addMenu(_("&View"))
|
self.tools_menu = menubar.addMenu(_("&Tools")) # type: QMenu
|
||||||
add_toggle_action(view_menu, self.addresses_tab)
|
preferences_action = self.tools_menu.addAction(_("Preferences"), self.settings_dialog) # type: QAction
|
||||||
add_toggle_action(view_menu, self.utxo_tab)
|
|
||||||
add_toggle_action(view_menu, self.channels_tab)
|
|
||||||
add_toggle_action(view_menu, self.contacts_tab)
|
|
||||||
add_toggle_action(view_menu, self.console_tab)
|
|
||||||
add_toggle_action(view_menu, self.notes_tab)
|
|
||||||
|
|
||||||
tools_menu = menubar.addMenu(_("&Tools")) # type: QMenu
|
|
||||||
preferences_action = tools_menu.addAction(_("Preferences"), self.settings_dialog) # type: QAction
|
|
||||||
if sys.platform == 'darwin':
|
if sys.platform == 'darwin':
|
||||||
# "Settings"/"Preferences" are all reserved keywords in macOS.
|
# "Settings"/"Preferences" are all reserved keywords in macOS.
|
||||||
# preferences_action will get picked up based on name (and put into a standardized location,
|
# preferences_action will get picked up based on name (and put into a standardized location,
|
||||||
@@ -757,26 +756,25 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener):
|
|||||||
# Hence, this menu item will be at a "uniform location re macOS processes"
|
# Hence, this menu item will be at a "uniform location re macOS processes"
|
||||||
preferences_action.setMenuRole(QAction.MenuRole.PreferencesRole) # make sure OS recognizes it as preferences
|
preferences_action.setMenuRole(QAction.MenuRole.PreferencesRole) # make sure OS recognizes it as preferences
|
||||||
# Add another preferences item, to also have a "uniform location for Electrum between different OSes"
|
# Add another preferences item, to also have a "uniform location for Electrum between different OSes"
|
||||||
tools_menu.addAction(_("Electrum preferences"), self.settings_dialog)
|
self.tools_menu.addAction(_("Electrum preferences"), self.settings_dialog)
|
||||||
|
|
||||||
tools_menu.addAction(_("&Network"), self.gui_object.show_network_dialog).setEnabled(bool(self.network))
|
self.tools_menu.addAction(_("&Network"), self.gui_object.show_network_dialog).setEnabled(bool(self.network))
|
||||||
tools_menu.addAction(_("&Plugins"), self.gui_object.show_plugins_dialog)
|
self.tools_menu.addAction(_("&Plugins"), self.gui_object.show_plugins_dialog)
|
||||||
tools_menu.addSeparator()
|
self.tools_menu.addSeparator()
|
||||||
tools_menu.addAction(_("&Sign/verify message"), self.sign_verify_message)
|
self.tools_menu.addAction(_("&Sign/verify message"), self.sign_verify_message)
|
||||||
tools_menu.addAction(_("&Encrypt/decrypt message"), self.encrypt_message)
|
self.tools_menu.addAction(_("&Encrypt/decrypt message"), self.encrypt_message)
|
||||||
tools_menu.addSeparator()
|
self.tools_menu.addSeparator()
|
||||||
|
|
||||||
raw_transaction_menu = tools_menu.addMenu(_("&Load transaction"))
|
raw_transaction_menu = self.tools_menu.addMenu(_("&Load transaction"))
|
||||||
raw_transaction_menu.addAction(_("&From file"), self.do_process_from_file)
|
raw_transaction_menu.addAction(_("&From file"), self.do_process_from_file)
|
||||||
raw_transaction_menu.addAction(_("&From text"), self.do_process_from_text)
|
raw_transaction_menu.addAction(_("&From text"), self.do_process_from_text)
|
||||||
raw_transaction_menu.addAction(_("&From the blockchain"), self.do_process_from_txid)
|
raw_transaction_menu.addAction(_("&From the blockchain"), self.do_process_from_txid)
|
||||||
raw_transaction_menu.addAction(_("&From QR code"), self.read_tx_from_qrcode)
|
raw_transaction_menu.addAction(_("&From QR code"), self.read_tx_from_qrcode)
|
||||||
self.raw_transaction_menu = raw_transaction_menu
|
self.raw_transaction_menu = raw_transaction_menu
|
||||||
run_hook('init_menubar_tools', self, tools_menu)
|
|
||||||
|
|
||||||
help_menu = menubar.addMenu(_("&Help"))
|
self.help_menu = menubar.addMenu(_("&Help"))
|
||||||
if sys.platform != 'darwin':
|
if sys.platform != 'darwin':
|
||||||
help_menu.addAction(_("&About"), self.show_about)
|
self.help_menu.addAction(_("&About"), self.show_about)
|
||||||
else:
|
else:
|
||||||
# macOS reserves the "About" menu item name, similarly to "Preferences" (see above).
|
# macOS reserves the "About" menu item name, similarly to "Preferences" (see above).
|
||||||
# The "About" keyword seems even more strictly locked down:
|
# The "About" keyword seems even more strictly locked down:
|
||||||
@@ -784,17 +782,18 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener):
|
|||||||
about_action = QAction(self)
|
about_action = QAction(self)
|
||||||
about_action.triggered.connect(self.show_about)
|
about_action.triggered.connect(self.show_about)
|
||||||
about_action.setMenuRole(QAction.MenuRole.AboutRole) # make sure OS recognizes it as "About"
|
about_action.setMenuRole(QAction.MenuRole.AboutRole) # make sure OS recognizes it as "About"
|
||||||
help_menu.addAction(about_action)
|
self.help_menu.addAction(about_action)
|
||||||
help_menu.addAction(_("&Check for updates"), self.show_update_check)
|
self.help_menu.addAction(_("&Check for updates"), self.show_update_check)
|
||||||
help_menu.addAction(_("&Official website"), lambda: webopen("https://electrum.org"))
|
self.help_menu.addAction(_("&Official website"), lambda: webopen("https://electrum.org"))
|
||||||
help_menu.addSeparator()
|
self.help_menu.addSeparator()
|
||||||
help_menu.addAction(_("&Documentation"), lambda: webopen("http://docs.electrum.org/")).setShortcut(QKeySequence.StandardKey.HelpContents)
|
self.help_menu.addAction(_("&Documentation"), lambda: webopen("http://docs.electrum.org/")).setShortcut(QKeySequence.StandardKey.HelpContents)
|
||||||
if not constants.net.TESTNET:
|
if not constants.net.TESTNET:
|
||||||
help_menu.addAction(_("&Bitcoin Paper"), self.show_bitcoin_paper)
|
self.help_menu.addAction(_("&Bitcoin Paper"), self.show_bitcoin_paper)
|
||||||
help_menu.addAction(_("&Report Bug"), self.show_report_bug)
|
self.help_menu.addAction(_("&Report Bug"), self.show_report_bug)
|
||||||
help_menu.addSeparator()
|
self.help_menu.addSeparator()
|
||||||
help_menu.addAction(_("&Donate to server"), self.donate_to_server)
|
self.help_menu.addAction(_("&Donate to server"), self.donate_to_server)
|
||||||
|
|
||||||
|
run_hook('init_menubar', self)
|
||||||
self.setMenuBar(menubar)
|
self.setMenuBar(menubar)
|
||||||
|
|
||||||
def donate_to_server(self):
|
def donate_to_server(self):
|
||||||
|
|||||||
@@ -1,22 +1,19 @@
|
|||||||
from functools import partial
|
from functools import partial
|
||||||
import traceback
|
|
||||||
import sys
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from PyQt6.QtCore import QObject, pyqtSignal
|
from PyQt6.QtCore import QObject, pyqtSignal
|
||||||
from PyQt6.QtWidgets import (QHBoxLayout, QLabel, QVBoxLayout)
|
|
||||||
|
|
||||||
from electrum.plugin import hook
|
from electrum.plugin import hook
|
||||||
from electrum.i18n import _
|
from electrum.i18n import _
|
||||||
from electrum.gui.qt.util import ThreadedButton, Buttons, EnterButton, WindowModalDialog, OkButton
|
from electrum.gui.qt.util import TaskThread
|
||||||
|
|
||||||
from .labels import LabelsPlugin
|
from .labels import LabelsPlugin
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from electrum.gui.qt import ElectrumGui
|
|
||||||
from electrum.gui.qt.main_window import ElectrumWindow
|
from electrum.gui.qt.main_window import ElectrumWindow
|
||||||
from electrum.wallet import Abstract_Wallet
|
from electrum.wallet import Abstract_Wallet
|
||||||
|
|
||||||
|
|
||||||
class QLabelsSignalObject(QObject):
|
class QLabelsSignalObject(QObject):
|
||||||
labels_changed_signal = pyqtSignal(object)
|
labels_changed_signal = pyqtSignal(object)
|
||||||
|
|
||||||
@@ -28,36 +25,32 @@ class Plugin(LabelsPlugin):
|
|||||||
self.obj = QLabelsSignalObject()
|
self.obj = QLabelsSignalObject()
|
||||||
self._init_qt_received = False
|
self._init_qt_received = False
|
||||||
|
|
||||||
def requires_settings(self):
|
@hook
|
||||||
return True
|
def init_menubar(self, window: 'ElectrumWindow'):
|
||||||
|
wallet = window.wallet
|
||||||
def settings_dialog(self, window: WindowModalDialog, wallet: 'Abstract_Wallet'):
|
|
||||||
if not wallet.get_fingerprint():
|
if not wallet.get_fingerprint():
|
||||||
window.show_error(_("{} plugin does not support this type of wallet.")
|
|
||||||
.format("Label Sync"))
|
|
||||||
return
|
return
|
||||||
d = WindowModalDialog(window, _("Label Settings"))
|
m = window.wallet_menu.addMenu('LabelSync')
|
||||||
hbox = QHBoxLayout()
|
m.addAction("Force upload", lambda: self.do_push(window))
|
||||||
hbox.addWidget(QLabel("Label sync options:"))
|
m.addAction("Force download", lambda: self.do_pull(window))
|
||||||
upload = ThreadedButton("Force upload",
|
|
||||||
partial(self.push, wallet),
|
|
||||||
partial(self.done_processing_success, d),
|
|
||||||
partial(self.done_processing_error, d))
|
|
||||||
download = ThreadedButton("Force download",
|
|
||||||
partial(self.pull, wallet, True),
|
|
||||||
partial(self.done_processing_success, d),
|
|
||||||
partial(self.done_processing_error, d))
|
|
||||||
vbox = QVBoxLayout()
|
|
||||||
vbox.addWidget(upload)
|
|
||||||
vbox.addWidget(download)
|
|
||||||
hbox.addLayout(vbox)
|
|
||||||
vbox = QVBoxLayout(d)
|
|
||||||
vbox.addLayout(hbox)
|
|
||||||
vbox.addSpacing(20)
|
|
||||||
vbox.addLayout(Buttons(OkButton(d)))
|
|
||||||
return bool(d.exec())
|
|
||||||
|
|
||||||
def on_pulled(self, wallet):
|
def do_push(self, window: 'ElectrumWindow'):
|
||||||
|
thread = TaskThread(window)
|
||||||
|
thread.add(
|
||||||
|
partial(self.push, window.wallet),
|
||||||
|
partial(self.done_processing_success, window),
|
||||||
|
thread.stop,
|
||||||
|
partial(self.done_processing_error, window))
|
||||||
|
|
||||||
|
def do_pull(self, window: 'ElectrumWindow'):
|
||||||
|
thread = TaskThread(window)
|
||||||
|
thread.add(
|
||||||
|
partial(self.pull, window.wallet, True),
|
||||||
|
partial(self.done_processing_success, window),
|
||||||
|
thread.stop,
|
||||||
|
partial(self.done_processing_error, window))
|
||||||
|
|
||||||
|
def on_pulled(self, wallet: 'Abstract_Wallet'):
|
||||||
self.obj.labels_changed_signal.emit(wallet)
|
self.obj.labels_changed_signal.emit(wallet)
|
||||||
|
|
||||||
def done_processing_success(self, dialog, result):
|
def done_processing_success(self, dialog, result):
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from electrum.i18n import _
|
from electrum.i18n import _
|
||||||
from .nwcserver import NWCServerPlugin
|
from .nwcserver import NWCServerPlugin
|
||||||
from electrum.gui.qt.util import WindowModalDialog, Buttons, EnterButton, OkButton, CancelButton, \
|
from electrum.gui.qt.util import WindowModalDialog, Buttons, OkButton, CancelButton, \
|
||||||
CloseButton
|
CloseButton
|
||||||
from electrum.gui.common_qt.util import paintQR
|
from electrum.gui.common_qt.util import paintQR
|
||||||
from electrum.plugin import hook
|
from electrum.plugin import hook
|
||||||
@@ -16,7 +16,7 @@ from typing import TYPE_CHECKING, Optional
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from electrum.wallet import Abstract_Wallet
|
from electrum.wallet import Abstract_Wallet
|
||||||
from electrum.gui.qt.main_window import ElectrumWindow
|
from electrum.gui.qt.main_window import ElectrumWindow
|
||||||
from electrum.gui.qt import ElectrumGui
|
|
||||||
|
|
||||||
class Plugin(NWCServerPlugin):
|
class Plugin(NWCServerPlugin):
|
||||||
def __init__(self, *args):
|
def __init__(self, *args):
|
||||||
@@ -29,19 +29,22 @@ class Plugin(NWCServerPlugin):
|
|||||||
return
|
return
|
||||||
self.start_plugin(wallet)
|
self.start_plugin(wallet)
|
||||||
|
|
||||||
def requires_settings(self):
|
@hook
|
||||||
return True
|
def init_menubar(self, window):
|
||||||
|
window.wallet_menu.addAction('Nostr Wallet Connect', partial(self.settings_dialog, window))
|
||||||
|
|
||||||
def settings_dialog(self, window: WindowModalDialog, wallet: 'Abstract_Wallet'):
|
def settings_dialog(self, window: WindowModalDialog):
|
||||||
if not self.initialized:
|
if not self.initialized:
|
||||||
window.show_error(
|
window.show_error(
|
||||||
_("{} plugin requires a lightning enabled wallet. Open a lightning-enabled wallet first.")
|
_("{} plugin requires a lightning enabled wallet. Open a lightning-enabled wallet first.")
|
||||||
.format("NWC"))
|
.format("NWC"))
|
||||||
return
|
return
|
||||||
|
if window.wallet != self.nwc_server.wallet:
|
||||||
|
window.show_error('not using this wallet')
|
||||||
|
return
|
||||||
|
|
||||||
d = WindowModalDialog(window, _("Nostr Wallet Connect"))
|
d = WindowModalDialog(window, _("Nostr Wallet Connect"))
|
||||||
main_layout = QVBoxLayout(d)
|
main_layout = QVBoxLayout(d)
|
||||||
main_layout.addWidget(QLabel(_("Using wallet:") + ' ' + self.nwc_server.wallet.basename()))
|
|
||||||
|
|
||||||
# Connections list
|
# Connections list
|
||||||
main_layout.addWidget(QLabel(_("Existing Connections:")))
|
main_layout.addWidget(QLabel(_("Existing Connections:")))
|
||||||
@@ -117,6 +120,7 @@ class Plugin(NWCServerPlugin):
|
|||||||
|
|
||||||
# Create Connection button
|
# Create Connection button
|
||||||
create_btn = QPushButton(_("Create Connection"))
|
create_btn = QPushButton(_("Create Connection"))
|
||||||
|
|
||||||
def create_connection():
|
def create_connection():
|
||||||
# Show a dialog to create a new connection
|
# Show a dialog to create a new connection
|
||||||
connection_string = self.connection_info_input_dialog(window)
|
connection_string = self.connection_info_input_dialog(window)
|
||||||
@@ -179,8 +183,8 @@ class Plugin(NWCServerPlugin):
|
|||||||
# dropdown menu to select prioritized nwc relay from self.config.NOSTR_RELAYS
|
# dropdown menu to select prioritized nwc relay from self.config.NOSTR_RELAYS
|
||||||
main_relay_label = QLabel(_("Main NWC Relay:"))
|
main_relay_label = QLabel(_("Main NWC Relay:"))
|
||||||
relay_tooltip = (
|
relay_tooltip = (
|
||||||
_("Most clients only use the first relay url encoded in the connection string.")
|
_("Most clients only use the first relay url encoded in the connection string.")
|
||||||
+ "\n" + _("The selected relay will be put first in the connection string."))
|
+ "\n" + _("The selected relay will be put first in the connection string."))
|
||||||
main_relay_label.setToolTip(relay_tooltip)
|
main_relay_label.setToolTip(relay_tooltip)
|
||||||
layout.addWidget(main_relay_label)
|
layout.addWidget(main_relay_label)
|
||||||
relay_combo = QComboBox()
|
relay_combo = QComboBox()
|
||||||
|
|||||||
Reference in New Issue
Block a user