Browse Source

Merge pull request #8619 from SomberNight/202309_config_tooltips

config: move tooltips from Qt gui into configvars
master
ThomasV 2 years ago committed by GitHub
parent
commit
b0ff95d7c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 26
      electrum/gui/messages.py
  2. 4
      electrum/gui/qt/address_list.py
  3. 51
      electrum/gui/qt/confirm_tx_dialog.py
  4. 6
      electrum/gui/qt/history_list.py
  5. 18
      electrum/gui/qt/my_treeview.py
  6. 4
      electrum/gui/qt/new_channel_dialog.py
  7. 9
      electrum/gui/qt/receive_tab.py
  8. 83
      electrum/gui/qt/settings_dialog.py
  9. 3
      electrum/gui/qt/swap_dialog.py
  10. 5
      electrum/gui/qt/transaction_dialog.py
  11. 5
      electrum/gui/qt/util.py
  12. 207
      electrum/simple_config.py

26
electrum/gui/messages.py

@ -5,20 +5,6 @@ def to_rtf(msg):
return '\n'.join(['<p>' + x + '</p>' for x in msg.split('\n\n')]) return '\n'.join(['<p>' + x + '</p>' for x in msg.split('\n\n')])
MSG_RECOVERABLE_CHANNELS = _(
"""Add extra data to your channel funding transactions, so that a static backup can be recovered from your seed.
Note that static backups only allow you to request a force-close with the remote node. This assumes that the remote node is still online, did not lose its data, and accepts to force close the channel.
If this is enabled, other nodes cannot open a channel to you. Channel recovery data is encrypted, so that only your wallet can decrypt it. However, blockchain analysis will be able to tell that the transaction was probably created by Electrum."""
)
MSG_CONFIG_INSTANT_SWAPS = _(
"""If this option is checked, your client will complete reverse swaps before the funding transaction is confirmed.
Note you are at risk of losing the funds in the swap, if the funding transaction never confirms."""
)
MSG_COOPERATIVE_CLOSE = _( MSG_COOPERATIVE_CLOSE = _(
"""Your node will negotiate the transaction fee with the remote node. This method of closing the channel usually results in the lowest fees.""" """Your node will negotiate the transaction fee with the remote node. This method of closing the channel usually results in the lowest fees."""
) )
@ -43,18 +29,6 @@ MSG_LIGHTNING_SCB_WARNING = _(
MSG_LIGHTNING_WARNING = MSG_LIGHTNING_EXPERIMENTAL_WARNING + "\n\n" + MSG_LIGHTNING_SCB_WARNING MSG_LIGHTNING_WARNING = MSG_LIGHTNING_EXPERIMENTAL_WARNING + "\n\n" + MSG_LIGHTNING_SCB_WARNING
MSG_HELP_TRAMPOLINE = _(
"""Lightning payments require finding a path through the Lightning Network. You may use trampoline routing, or local routing (gossip).
Downloading the network gossip uses quite some bandwidth and storage, and is not recommended on mobile devices. If you use trampoline, you can only open channels with trampoline nodes."""
)
MSG_LEGACY_ADD_TRAMPOLINE = _(
"""When paying a non-trampoline invoice, add an extra trampoline to the route, in order to improve your privacy.
This will result in longer routes; it might increase your fees and decrease the success rate of your payments."""
)
MGS_CONFLICTING_BACKUP_INSTANCE = _( MGS_CONFLICTING_BACKUP_INSTANCE = _(
"""Another instance of this wallet (same seed) has an open channel with the same remote node. If you create this channel, you will not be able to use both wallets at the same time. """Another instance of this wallet (same seed) has an open channel with the same remote node. If you create this channel, you will not be able to use both wallets at the same time.

4
electrum/gui/qt/address_list.py

@ -123,11 +123,11 @@ class AddressList(MyTreeView):
addr = self.get_role_data_for_current_item(col=0, role=self.ROLE_ADDRESS_STR) addr = self.get_role_data_for_current_item(col=0, role=self.ROLE_ADDRESS_STR)
self.main_window.show_address(addr) self.main_window.show_address(addr)
def create_toolbar(self, config): def create_toolbar(self, config: 'SimpleConfig'):
toolbar, menu = self.create_toolbar_with_menu('') toolbar, menu = self.create_toolbar_with_menu('')
self.num_addr_label = toolbar.itemAt(0).widget() self.num_addr_label = toolbar.itemAt(0).widget()
self._toolbar_checkbox = menu.addToggle(_("Show Filter"), lambda: self.toggle_toolbar()) self._toolbar_checkbox = menu.addToggle(_("Show Filter"), lambda: self.toggle_toolbar())
menu.addConfig(_('Show Fiat balances'), config.cv.FX_SHOW_FIAT_BALANCE_FOR_ADDRESSES, callback=self.main_window.app.update_fiat_signal.emit) menu.addConfig(config.cv.FX_SHOW_FIAT_BALANCE_FOR_ADDRESSES, callback=self.main_window.app.update_fiat_signal.emit)
hbox = self.create_toolbar_buttons() hbox = self.create_toolbar_buttons()
toolbar.insertLayout(1, hbox) toolbar.insertLayout(1, hbox)
return toolbar return toolbar

51
electrum/gui/qt/confirm_tx_dialog.py

@ -25,7 +25,7 @@
from decimal import Decimal from decimal import Decimal
from functools import partial from functools import partial
from typing import TYPE_CHECKING, Optional, Union from typing import TYPE_CHECKING, Optional, Union, Callable
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon from PyQt5.QtGui import QIcon
@ -47,6 +47,7 @@ from .util import (WindowModalDialog, ColorScheme, HelpLabel, Buttons, CancelBut
from .fee_slider import FeeSlider, FeeComboBox from .fee_slider import FeeSlider, FeeComboBox
if TYPE_CHECKING: if TYPE_CHECKING:
from electrum.simple_config import ConfigVarWithConfig
from .main_window import ElectrumWindow from .main_window import ElectrumWindow
from .transaction_dialog import TxSizeLabel, TxFiatLabel, TxInOutWidget from .transaction_dialog import TxSizeLabel, TxFiatLabel, TxInOutWidget
@ -384,24 +385,17 @@ class TxEditor(WindowModalDialog):
m.setChecked(b) m.setChecked(b)
m.setToolTip(tooltip) m.setToolTip(tooltip)
return m return m
add_pref_action( def add_cv_action(configvar: 'ConfigVarWithConfig', action: Callable[[], None]):
self.config.GUI_QT_TX_EDITOR_SHOW_IO, b = configvar.get()
self.toggle_io_visibility, short_desc = configvar.get_short_desc()
_('Show inputs and outputs'), '') assert short_desc is not None, f"short_desc missing for {configvar}"
add_pref_action( tooltip = configvar.get_long_desc() or ""
self.config.GUI_QT_TX_EDITOR_SHOW_FEE_DETAILS, return add_pref_action(b, action, short_desc, tooltip)
self.toggle_fee_details, add_cv_action(self.config.cv.GUI_QT_TX_EDITOR_SHOW_IO, self.toggle_io_visibility)
_('Edit fees manually'), '') add_cv_action(self.config.cv.GUI_QT_TX_EDITOR_SHOW_FEE_DETAILS, self.toggle_fee_details)
add_pref_action( add_cv_action(self.config.cv.GUI_QT_TX_EDITOR_SHOW_LOCKTIME, self.toggle_locktime)
self.config.GUI_QT_TX_EDITOR_SHOW_LOCKTIME,
self.toggle_locktime,
_('Edit Locktime'), '')
self.pref_menu.addSeparator() self.pref_menu.addSeparator()
add_pref_action( add_cv_action(self.config.cv.WALLET_SEND_CHANGE_TO_LIGHTNING, self.toggle_send_change_to_lightning)
self.config.WALLET_SEND_CHANGE_TO_LIGHTNING,
self.toggle_send_change_to_lightning,
_('Send change to Lightning'),
_('If possible, send the change of this transaction to your channels, with a submarine swap'))
add_pref_action( add_pref_action(
self.wallet.use_change, self.wallet.use_change,
self.toggle_use_change, self.toggle_use_change,
@ -416,24 +410,9 @@ class TxEditor(WindowModalDialog):
_('This may result in higher transactions fees.') _('This may result in higher transactions fees.')
])) ]))
self.use_multi_change_menu.setEnabled(self.wallet.use_change) self.use_multi_change_menu.setEnabled(self.wallet.use_change)
add_pref_action( add_cv_action(self.config.cv.WALLET_BATCH_RBF, self.toggle_batch_rbf)
self.config.WALLET_BATCH_RBF, add_cv_action(self.config.cv.WALLET_SPEND_CONFIRMED_ONLY, self.toggle_confirmed_only)
self.toggle_batch_rbf, add_cv_action(self.config.cv.WALLET_COIN_CHOOSER_OUTPUT_ROUNDING, self.toggle_output_rounding)
_('Batch unconfirmed transactions'),
_('If you check this box, your unconfirmed transactions will be consolidated into a single transaction.') + '\n' + \
_('This will save fees, but might have unwanted effects in terms of privacy'))
add_pref_action(
self.config.WALLET_SPEND_CONFIRMED_ONLY,
self.toggle_confirmed_only,
_('Spend only confirmed coins'),
_('Spend only confirmed inputs.'))
add_pref_action(
self.config.WALLET_COIN_CHOOSER_OUTPUT_ROUNDING,
self.toggle_output_rounding,
_('Enable output value rounding'),
_('Set the value of the change output so that it has similar precision to the other outputs.') + '\n' + \
_('This might improve your privacy somewhat.') + '\n' + \
_('If enabled, at most 100 satoshis might be lost due to this, per transaction.'))
self.pref_button = QToolButton() self.pref_button = QToolButton()
self.pref_button.setIcon(read_QIcon("preferences.png")) self.pref_button.setIcon(read_QIcon("preferences.png"))
self.pref_button.setMenu(self.pref_menu) self.pref_button.setMenu(self.pref_menu)

6
electrum/gui/qt/history_list.py

@ -529,12 +529,12 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
self.end_button.setText(_('To') + ' ' + self.format_date(self.end_date)) self.end_button.setText(_('To') + ' ' + self.format_date(self.end_date))
self.hide_rows() self.hide_rows()
def create_toolbar(self, config): def create_toolbar(self, config: 'SimpleConfig'):
toolbar, menu = self.create_toolbar_with_menu('') toolbar, menu = self.create_toolbar_with_menu('')
self.num_tx_label = toolbar.itemAt(0).widget() self.num_tx_label = toolbar.itemAt(0).widget()
self._toolbar_checkbox = menu.addToggle(_("Filter by Date"), lambda: self.toggle_toolbar()) self._toolbar_checkbox = menu.addToggle(_("Filter by Date"), lambda: self.toggle_toolbar())
self.menu_fiat = menu.addConfig(_('Show Fiat Values'), config.cv.FX_HISTORY_RATES, callback=self.main_window.app.update_fiat_signal.emit) self.menu_fiat = menu.addConfig(config.cv.FX_HISTORY_RATES, short_desc=_('Show Fiat Values'), callback=self.main_window.app.update_fiat_signal.emit)
self.menu_capgains = menu.addConfig(_('Show Capital Gains'), config.cv.FX_HISTORY_RATES_CAPITAL_GAINS, callback=self.main_window.app.update_fiat_signal.emit) self.menu_capgains = menu.addConfig(config.cv.FX_HISTORY_RATES_CAPITAL_GAINS, callback=self.main_window.app.update_fiat_signal.emit)
self.menu_summary = menu.addAction(_("&Summary"), self.show_summary) self.menu_summary = menu.addAction(_("&Summary"), self.show_summary)
menu.addAction(_("&Plot"), self.plot_history_dialog) menu.addAction(_("&Plot"), self.plot_history_dialog)
menu.addAction(_("&Export"), self.export_history_dialog) menu.addAction(_("&Export"), self.export_history_dialog)

18
electrum/gui/qt/my_treeview.py

@ -62,6 +62,8 @@ from electrum.logging import Logger
from electrum.qrreader import MissingQrDetectionLib from electrum.qrreader import MissingQrDetectionLib
from electrum.simple_config import ConfigVarWithConfig from electrum.simple_config import ConfigVarWithConfig
from electrum.gui import messages
from .util import read_QIcon from .util import read_QIcon
if TYPE_CHECKING: if TYPE_CHECKING:
@ -82,13 +84,23 @@ class MyMenu(QMenu):
m.setToolTip(tooltip) m.setToolTip(tooltip)
return m return m
def addConfig(self, text: str, configvar: 'ConfigVarWithConfig', *, tooltip='', callback=None) -> QAction: def addConfig(
self,
configvar: 'ConfigVarWithConfig',
*,
callback=None,
short_desc: Optional[str] = None,
) -> QAction:
assert isinstance(configvar, ConfigVarWithConfig), configvar assert isinstance(configvar, ConfigVarWithConfig), configvar
if short_desc is None:
short_desc = configvar.get_short_desc()
assert short_desc is not None, f"short_desc missing for {configvar}"
b = configvar.get() b = configvar.get()
m = self.addAction(text, lambda: self._do_toggle_config(configvar, callback=callback)) m = self.addAction(short_desc, lambda: self._do_toggle_config(configvar, callback=callback))
m.setCheckable(True) m.setCheckable(True)
m.setChecked(bool(b)) m.setChecked(bool(b))
m.setToolTip(tooltip) if (long_desc := configvar.get_long_desc()) is not None:
m.setToolTip(messages.to_rtf(long_desc))
return m return m
def _do_toggle_config(self, configvar: 'ConfigVarWithConfig', *, callback): def _do_toggle_config(self, configvar: 'ConfigVarWithConfig', *, callback):

4
electrum/gui/qt/new_channel_dialog.py

@ -35,10 +35,8 @@ class NewChannelDialog(WindowModalDialog):
self.min_amount_sat = min_amount_sat or MIN_FUNDING_SAT self.min_amount_sat = min_amount_sat or MIN_FUNDING_SAT
vbox = QVBoxLayout(self) vbox = QVBoxLayout(self)
toolbar, menu = create_toolbar_with_menu(self.config, '') toolbar, menu = create_toolbar_with_menu(self.config, '')
recov_tooltip = messages.to_rtf(messages.MSG_RECOVERABLE_CHANNELS)
menu.addConfig( menu.addConfig(
_("Create recoverable channels"), self.config.cv.LIGHTNING_USE_RECOVERABLE_CHANNELS, self.config.cv.LIGHTNING_USE_RECOVERABLE_CHANNELS,
tooltip=recov_tooltip,
).setEnabled(self.lnworker.can_have_recoverable_channels()) ).setEnabled(self.lnworker.can_have_recoverable_channels())
vbox.addLayout(toolbar) vbox.addLayout(toolbar)
msg = _('Choose a remote node and an amount to fund the channel.') msg = _('Choose a remote node and an amount to fund the channel.')

9
electrum/gui/qt/receive_tab.py

@ -146,13 +146,8 @@ class ReceiveTab(QWidget, MessageBoxMixin, Logger):
self.update_view_button() self.update_view_button()
self.toolbar.insertWidget(2, self.toggle_view_button) self.toolbar.insertWidget(2, self.toggle_view_button)
# menu # menu
menu.addConfig( menu.addConfig(self.config.cv.WALLET_BOLT11_FALLBACK, callback=self.on_toggle_bolt11_fallback)
_('Add on-chain fallback to lightning requests'), self.config.cv.WALLET_BOLT11_FALLBACK, menu.addConfig(self.config.cv.WALLET_BIP21_LIGHTNING, callback=self.update_current_request)
callback=self.on_toggle_bolt11_fallback)
menu.addConfig(
_('Add lightning requests to bitcoin URIs'), self.config.cv.WALLET_BIP21_LIGHTNING,
tooltip=_('This may result in large QR codes'),
callback=self.update_current_request)
self.qr_menu_action = menu.addToggle(_("Show detached QR code window"), self.window.toggle_qr_window) self.qr_menu_action = menu.addToggle(_("Show detached QR code window"), self.window.toggle_qr_window)
menu.addAction(_("Import requests"), self.window.import_requests) menu.addAction(_("Import requests"), self.window.import_requests)
menu.addAction(_("Export requests"), self.window.export_requests) menu.addAction(_("Export requests"), self.window.export_requests)

83
electrum/gui/qt/settings_dialog.py

@ -33,7 +33,7 @@ from PyQt5.QtWidgets import (QComboBox, QTabWidget, QDialog,
QPushButton, QWidget, QHBoxLayout) QPushButton, QWidget, QHBoxLayout)
from electrum.i18n import _, languages from electrum.i18n import _, languages
from electrum import util, coinchooser, paymentrequest from electrum import util, paymentrequest
from electrum.util import base_units_list, event_listener from electrum.util import base_units_list, event_listener
from electrum.gui import messages from electrum.gui import messages
@ -43,10 +43,19 @@ from .util import (ColorScheme, WindowModalDialog, HelpLabel, Buttons,
if TYPE_CHECKING: if TYPE_CHECKING:
from electrum.simple_config import SimpleConfig from electrum.simple_config import SimpleConfig, ConfigVarWithConfig
from .main_window import ElectrumWindow from .main_window import ElectrumWindow
def checkbox_from_configvar(cv: 'ConfigVarWithConfig') -> QCheckBox:
short_desc = cv.get_short_desc()
assert short_desc is not None, f"short_desc missing for {cv}"
cb = QCheckBox(short_desc)
if (long_desc := cv.get_long_desc()) is not None:
cb.setToolTip(messages.to_rtf(long_desc))
return cb
class SettingsDialog(QDialog, QtEventListener): class SettingsDialog(QDialog, QtEventListener):
def __init__(self, window: 'ElectrumWindow', config: 'SimpleConfig'): def __init__(self, window: 'ElectrumWindow', config: 'SimpleConfig'):
@ -67,8 +76,7 @@ class SettingsDialog(QDialog, QtEventListener):
tabs = QTabWidget() tabs = QTabWidget()
# language # language
lang_help = _('Select which language is used in the GUI (after restart).') lang_label = HelpLabel.from_configvar(self.config.cv.LOCALIZATION_LANGUAGE)
lang_label = HelpLabel(_('Language') + ':', lang_help)
lang_combo = QComboBox() lang_combo = QComboBox()
lang_combo.addItems(list(languages.values())) lang_combo.addItems(list(languages.values()))
lang_keys = list(languages.keys()) lang_keys = list(languages.keys())
@ -87,8 +95,7 @@ class SettingsDialog(QDialog, QtEventListener):
self.need_restart = True self.need_restart = True
lang_combo.currentIndexChanged.connect(on_lang) lang_combo.currentIndexChanged.connect(on_lang)
nz_help = _('Number of zeros displayed after the decimal point. For example, if this is set to 2, "1." will be displayed as "1.00"') nz_label = HelpLabel.from_configvar(self.config.cv.BTC_AMOUNTS_FORCE_NZEROS_AFTER_DECIMAL_POINT)
nz_label = HelpLabel(_('Zeros after decimal point') + ':', nz_help)
nz = QSpinBox() nz = QSpinBox()
nz.setMinimum(0) nz.setMinimum(0)
nz.setMaximum(self.config.decimal_point) nz.setMaximum(self.config.decimal_point)
@ -105,9 +112,7 @@ class SettingsDialog(QDialog, QtEventListener):
nz.valueChanged.connect(on_nz) nz.valueChanged.connect(on_nz)
# lightning # lightning
help_trampoline = messages.MSG_HELP_TRAMPOLINE trampoline_cb = checkbox_from_configvar(self.config.cv.LIGHTNING_USE_GOSSIP)
trampoline_cb = QCheckBox(_("Use trampoline routing"))
trampoline_cb.setToolTip(messages.to_rtf(help_trampoline))
trampoline_cb.setChecked(not self.config.LIGHTNING_USE_GOSSIP) trampoline_cb.setChecked(not self.config.LIGHTNING_USE_GOSSIP)
def on_trampoline_checked(use_trampoline): def on_trampoline_checked(use_trampoline):
use_trampoline = bool(use_trampoline) use_trampoline = bool(use_trampoline)
@ -130,21 +135,13 @@ class SettingsDialog(QDialog, QtEventListener):
util.trigger_callback('channels_updated', self.wallet) util.trigger_callback('channels_updated', self.wallet)
trampoline_cb.stateChanged.connect(on_trampoline_checked) trampoline_cb.stateChanged.connect(on_trampoline_checked)
help_legacy_add_trampoline = messages.MSG_LEGACY_ADD_TRAMPOLINE legacy_add_trampoline_cb = checkbox_from_configvar(self.config.cv.LIGHTNING_LEGACY_ADD_TRAMPOLINE)
legacy_add_trampoline_cb = QCheckBox(_("Add extra trampoline to legacy payments"))
legacy_add_trampoline_cb.setToolTip(messages.to_rtf(help_legacy_add_trampoline))
legacy_add_trampoline_cb.setChecked(self.config.LIGHTNING_LEGACY_ADD_TRAMPOLINE) legacy_add_trampoline_cb.setChecked(self.config.LIGHTNING_LEGACY_ADD_TRAMPOLINE)
def on_legacy_add_trampoline_checked(b): def on_legacy_add_trampoline_checked(b):
self.config.LIGHTNING_LEGACY_ADD_TRAMPOLINE = bool(b) self.config.LIGHTNING_LEGACY_ADD_TRAMPOLINE = bool(b)
legacy_add_trampoline_cb.stateChanged.connect(on_legacy_add_trampoline_checked) legacy_add_trampoline_cb.stateChanged.connect(on_legacy_add_trampoline_checked)
help_remote_wt = ' '.join([ remote_wt_cb = checkbox_from_configvar(self.config.cv.WATCHTOWER_CLIENT_ENABLED)
_("A watchtower is a daemon that watches your channels and prevents the other party from stealing funds by broadcasting an old state."),
_("If you have private a watchtower, enter its URL here."),
_("Check our online documentation if you want to configure Electrum as a watchtower."),
])
remote_wt_cb = QCheckBox(_("Use a remote watchtower"))
remote_wt_cb.setToolTip('<p>'+help_remote_wt+'</p>')
remote_wt_cb.setChecked(self.config.WATCHTOWER_CLIENT_ENABLED) remote_wt_cb.setChecked(self.config.WATCHTOWER_CLIENT_ENABLED)
def on_remote_wt_checked(x): def on_remote_wt_checked(x):
self.config.WATCHTOWER_CLIENT_ENABLED = bool(x) self.config.WATCHTOWER_CLIENT_ENABLED = bool(x)
@ -158,17 +155,13 @@ class SettingsDialog(QDialog, QtEventListener):
self.config.WATCHTOWER_CLIENT_URL = url self.config.WATCHTOWER_CLIENT_URL = url
self.watchtower_url_e.editingFinished.connect(on_wt_url) self.watchtower_url_e.editingFinished.connect(on_wt_url)
msg = _('OpenAlias record, used to receive coins and to sign payment requests.') + '\n\n'\ alias_label = HelpLabel.from_configvar(self.config.cv.OPENALIAS_ID)
+ _('The following alias providers are available:') + '\n'\
+ '\n'.join(['https://cryptoname.co/', 'http://xmr.link']) + '\n\n'\
+ 'For more information, see https://openalias.org'
alias_label = HelpLabel(_('OpenAlias') + ':', msg)
alias = self.config.OPENALIAS_ID alias = self.config.OPENALIAS_ID
self.alias_e = QLineEdit(alias) self.alias_e = QLineEdit(alias)
self.set_alias_color() self.set_alias_color()
self.alias_e.editingFinished.connect(self.on_alias_edit) self.alias_e.editingFinished.connect(self.on_alias_edit)
msat_cb = QCheckBox(_("Show Lightning amounts with msat precision")) msat_cb = checkbox_from_configvar(self.config.cv.BTC_AMOUNTS_PREC_POST_SAT)
msat_cb.setChecked(self.config.BTC_AMOUNTS_PREC_POST_SAT > 0) msat_cb.setChecked(self.config.BTC_AMOUNTS_PREC_POST_SAT > 0)
def on_msat_checked(v): def on_msat_checked(v):
prec = 3 if v == Qt.Checked else 0 prec = 3 if v == Qt.Checked else 0
@ -198,7 +191,7 @@ class SettingsDialog(QDialog, QtEventListener):
self.app.refresh_amount_edits_signal.emit() self.app.refresh_amount_edits_signal.emit()
unit_combo.currentIndexChanged.connect(lambda x: on_unit(x, nz)) unit_combo.currentIndexChanged.connect(lambda x: on_unit(x, nz))
thousandsep_cb = QCheckBox(_("Add thousand separators to bitcoin amounts")) thousandsep_cb = checkbox_from_configvar(self.config.cv.BTC_AMOUNTS_ADD_THOUSANDS_SEP)
thousandsep_cb.setChecked(self.config.BTC_AMOUNTS_ADD_THOUSANDS_SEP) thousandsep_cb.setChecked(self.config.BTC_AMOUNTS_ADD_THOUSANDS_SEP)
def on_set_thousandsep(v): def on_set_thousandsep(v):
checked = v == Qt.Checked checked = v == Qt.Checked
@ -210,9 +203,7 @@ class SettingsDialog(QDialog, QtEventListener):
qr_combo = QComboBox() qr_combo = QComboBox()
qr_combo.addItem("Default", "default") qr_combo.addItem("Default", "default")
msg = (_("For scanning QR codes.") + "\n" qr_label = HelpLabel.from_configvar(self.config.cv.VIDEO_DEVICE_PATH)
+ _("Install the zbar package to enable this."))
qr_label = HelpLabel(_('Video Device') + ':', msg)
from .qrreader import find_system_cameras from .qrreader import find_system_cameras
system_cameras = find_system_cameras() system_cameras = find_system_cameras()
for cam_desc, cam_path in system_cameras.items(): for cam_desc, cam_path in system_cameras.items():
@ -228,53 +219,31 @@ class SettingsDialog(QDialog, QtEventListener):
colortheme_combo.addItem(_('Dark'), 'dark') colortheme_combo.addItem(_('Dark'), 'dark')
index = colortheme_combo.findData(self.config.GUI_QT_COLOR_THEME) index = colortheme_combo.findData(self.config.GUI_QT_COLOR_THEME)
colortheme_combo.setCurrentIndex(index) colortheme_combo.setCurrentIndex(index)
colortheme_label = QLabel(_('Color theme') + ':') colortheme_label = QLabel(self.config.cv.GUI_QT_COLOR_THEME.get_short_desc() + ':')
def on_colortheme(x): def on_colortheme(x):
self.config.GUI_QT_COLOR_THEME = colortheme_combo.itemData(x) self.config.GUI_QT_COLOR_THEME = colortheme_combo.itemData(x)
self.need_restart = True self.need_restart = True
colortheme_combo.currentIndexChanged.connect(on_colortheme) colortheme_combo.currentIndexChanged.connect(on_colortheme)
updatecheck_cb = QCheckBox(_("Automatically check for software updates")) updatecheck_cb = checkbox_from_configvar(self.config.cv.AUTOMATIC_CENTRALIZED_UPDATE_CHECKS)
updatecheck_cb.setChecked(self.config.AUTOMATIC_CENTRALIZED_UPDATE_CHECKS) updatecheck_cb.setChecked(self.config.AUTOMATIC_CENTRALIZED_UPDATE_CHECKS)
def on_set_updatecheck(v): def on_set_updatecheck(v):
self.config.AUTOMATIC_CENTRALIZED_UPDATE_CHECKS = (v == Qt.Checked) self.config.AUTOMATIC_CENTRALIZED_UPDATE_CHECKS = (v == Qt.Checked)
updatecheck_cb.stateChanged.connect(on_set_updatecheck) updatecheck_cb.stateChanged.connect(on_set_updatecheck)
filelogging_cb = QCheckBox(_("Write logs to file")) filelogging_cb = checkbox_from_configvar(self.config.cv.WRITE_LOGS_TO_DISK)
filelogging_cb.setChecked(self.config.WRITE_LOGS_TO_DISK) filelogging_cb.setChecked(self.config.WRITE_LOGS_TO_DISK)
def on_set_filelogging(v): def on_set_filelogging(v):
self.config.WRITE_LOGS_TO_DISK = (v == Qt.Checked) self.config.WRITE_LOGS_TO_DISK = (v == Qt.Checked)
self.need_restart = True self.need_restart = True
filelogging_cb.stateChanged.connect(on_set_filelogging) filelogging_cb.stateChanged.connect(on_set_filelogging)
filelogging_cb.setToolTip(_('Debug logs can be persisted to disk. These are useful for troubleshooting.'))
def fmt_docs(key, klass):
lines = [ln.lstrip(" ") for ln in klass.__doc__.split("\n")]
return '\n'.join([key, "", " ".join(lines)])
choosers = sorted(coinchooser.COIN_CHOOSERS.keys())
if len(choosers) > 1:
chooser_name = coinchooser.get_name(self.config)
msg = _('Choose coin (UTXO) selection method. The following are available:\n\n')
msg += '\n\n'.join(fmt_docs(*item) for item in coinchooser.COIN_CHOOSERS.items())
chooser_label = HelpLabel(_('Coin selection') + ':', msg)
chooser_combo = QComboBox()
chooser_combo.addItems(choosers)
i = choosers.index(chooser_name) if chooser_name in choosers else 0
chooser_combo.setCurrentIndex(i)
def on_chooser(x):
chooser_name = choosers[chooser_combo.currentIndex()]
self.config.WALLET_COIN_CHOOSER_POLICY = chooser_name
chooser_combo.currentIndexChanged.connect(on_chooser)
block_explorers = sorted(util.block_explorer_info().keys()) block_explorers = sorted(util.block_explorer_info().keys())
BLOCK_EX_CUSTOM_ITEM = _("Custom URL") BLOCK_EX_CUSTOM_ITEM = _("Custom URL")
if BLOCK_EX_CUSTOM_ITEM in block_explorers: # malicious translation? if BLOCK_EX_CUSTOM_ITEM in block_explorers: # malicious translation?
block_explorers.remove(BLOCK_EX_CUSTOM_ITEM) block_explorers.remove(BLOCK_EX_CUSTOM_ITEM)
block_explorers.append(BLOCK_EX_CUSTOM_ITEM) block_explorers.append(BLOCK_EX_CUSTOM_ITEM)
msg = _('Choose which online block explorer to use for functions that open a web browser') block_ex_label = HelpLabel.from_configvar(self.config.cv.BLOCK_EXPLORER)
block_ex_label = HelpLabel(_('Online Block Explorer') + ':', msg)
block_ex_combo = QComboBox() block_ex_combo = QComboBox()
block_ex_custom_e = QLineEdit(str(self.config.BLOCK_EXPLORER_CUSTOM or '')) block_ex_custom_e = QLineEdit(str(self.config.BLOCK_EXPLORER_CUSTOM or ''))
block_ex_combo.addItems(block_explorers) block_ex_combo.addItems(block_explorers)
@ -309,7 +278,7 @@ class SettingsDialog(QDialog, QtEventListener):
block_ex_hbox_w.setLayout(block_ex_hbox) block_ex_hbox_w.setLayout(block_ex_hbox)
# Fiat Currency # Fiat Currency
self.history_rates_cb = QCheckBox(_('Download historical rates')) self.history_rates_cb = checkbox_from_configvar(self.config.cv.FX_HISTORY_RATES)
ccy_combo = QComboBox() ccy_combo = QComboBox()
ex_combo = QComboBox() ex_combo = QComboBox()
@ -391,8 +360,6 @@ class SettingsDialog(QDialog, QtEventListener):
misc_widgets.append((filelogging_cb, None)) misc_widgets.append((filelogging_cb, None))
misc_widgets.append((alias_label, self.alias_e)) misc_widgets.append((alias_label, self.alias_e))
misc_widgets.append((qr_label, qr_combo)) misc_widgets.append((qr_label, qr_combo))
if len(choosers) > 1:
misc_widgets.append((chooser_label, chooser_combo))
tabs_info = [ tabs_info = [
(gui_widgets, _('Appearance')), (gui_widgets, _('Appearance')),

3
electrum/gui/qt/swap_dialog.py

@ -45,8 +45,7 @@ class SwapDialog(WindowModalDialog, QtEventListener):
vbox = QVBoxLayout(self) vbox = QVBoxLayout(self)
toolbar, menu = create_toolbar_with_menu(self.config, '') toolbar, menu = create_toolbar_with_menu(self.config, '')
menu.addConfig( menu.addConfig(
_("Allow instant swaps"), self.config.cv.LIGHTNING_ALLOW_INSTANT_SWAPS, self.config.cv.LIGHTNING_ALLOW_INSTANT_SWAPS,
tooltip=messages.to_rtf(messages.MSG_CONFIG_INSTANT_SWAPS),
).setEnabled(self.lnworker.can_have_recoverable_channels()) ).setEnabled(self.lnworker.can_have_recoverable_channels())
vbox.addLayout(toolbar) vbox.addLayout(toolbar)
self.description_label = WWLabel(self.get_description()) self.description_label = WWLabel(self.get_description())

5
electrum/gui/qt/transaction_dialog.py

@ -441,10 +441,7 @@ class TxDialog(QDialog, MessageBoxMixin):
self.setLayout(vbox) self.setLayout(vbox)
toolbar, menu = create_toolbar_with_menu(self.config, '') toolbar, menu = create_toolbar_with_menu(self.config, '')
menu.addConfig( menu.addConfig(
_('Download missing data'), self.config.cv.GUI_QT_TX_DIALOG_FETCH_TXIN_DATA, self.config.cv.GUI_QT_TX_DIALOG_FETCH_TXIN_DATA,
tooltip=_(
'Download parent transactions from the network.\n'
'Allows filling in missing fee and input details.'),
callback=self.maybe_fetch_txin_data) callback=self.maybe_fetch_txin_data)
vbox.addLayout(toolbar) vbox.addLayout(toolbar)

5
electrum/gui/qt/util.py

@ -42,6 +42,7 @@ if TYPE_CHECKING:
from .paytoedit import PayToEdit from .paytoedit import PayToEdit
from electrum.simple_config import SimpleConfig from electrum.simple_config import SimpleConfig
from electrum.simple_config import ConfigVarWithConfig
if platform.system() == 'Windows': if platform.system() == 'Windows':
@ -152,6 +153,10 @@ class HelpLabel(HelpMixin, QLabel):
self.app = QCoreApplication.instance() self.app = QCoreApplication.instance()
self.font = self.font() self.font = self.font()
@classmethod
def from_configvar(cls, cv: 'ConfigVarWithConfig') -> 'HelpLabel':
return HelpLabel(cv.get_short_desc() + ':', cv.get_long_desc())
def mouseReleaseEvent(self, x): def mouseReleaseEvent(self, x):
self.show_help() self.show_help()

207
electrum/simple_config.py

@ -63,10 +63,18 @@ class ConfigVar(property):
*, *,
default: Union[Any, Callable[['SimpleConfig'], Any]], # typically a literal, but can also be a callable default: Union[Any, Callable[['SimpleConfig'], Any]], # typically a literal, but can also be a callable
type_=None, type_=None,
short_desc: Callable[[], str] = None,
long_desc: Callable[[], str] = None,
): ):
self._key = key self._key = key
self._default = default self._default = default
self._type = type_ self._type = type_
# note: the descriptions are callables instead of str literals, to delay evaluating the _() translations
# until after the language is set.
assert short_desc is None or callable(short_desc)
assert long_desc is None or callable(long_desc)
self._short_desc = short_desc
self._long_desc = long_desc
property.__init__(self, self._get_config_value, self._set_config_value) property.__init__(self, self._get_config_value, self._set_config_value)
assert key not in _config_var_from_key, f"duplicate config key str: {key!r}" assert key not in _config_var_from_key, f"duplicate config key str: {key!r}"
_config_var_from_key[key] = self _config_var_from_key[key] = self
@ -102,6 +110,14 @@ class ConfigVar(property):
def get_default_value(self) -> Any: def get_default_value(self) -> Any:
return self._default return self._default
def get_short_desc(self) -> Optional[str]:
desc = self._short_desc
return desc() if desc else None
def get_long_desc(self) -> Optional[str]:
desc = self._long_desc
return desc() if desc else None
def __repr__(self): def __repr__(self):
return f"<ConfigVar key={self._key!r}>" return f"<ConfigVar key={self._key!r}>"
@ -128,6 +144,12 @@ class ConfigVarWithConfig:
def get_default_value(self) -> Any: def get_default_value(self) -> Any:
return self._config_var.get_default_value() return self._config_var.get_default_value()
def get_short_desc(self) -> Optional[str]:
return self._config_var.get_short_desc()
def get_long_desc(self) -> Optional[str]:
return self._config_var.get_long_desc()
def is_modifiable(self) -> bool: def is_modifiable(self) -> bool:
return self._config.is_modifiable(self._config_var) return self._config.is_modifiable(self._config_var)
@ -867,33 +889,96 @@ class SimpleConfig(Logger):
NETWORK_MAX_INCOMING_MSG_SIZE = ConfigVar('network_max_incoming_msg_size', default=1_000_000, type_=int) # in bytes NETWORK_MAX_INCOMING_MSG_SIZE = ConfigVar('network_max_incoming_msg_size', default=1_000_000, type_=int) # in bytes
NETWORK_TIMEOUT = ConfigVar('network_timeout', default=None, type_=int) NETWORK_TIMEOUT = ConfigVar('network_timeout', default=None, type_=int)
WALLET_BATCH_RBF = ConfigVar('batch_rbf', default=False, type_=bool) WALLET_BATCH_RBF = ConfigVar(
WALLET_SPEND_CONFIRMED_ONLY = ConfigVar('confirmed_only', default=False, type_=bool) 'batch_rbf', default=False, type_=bool,
short_desc=lambda: _('Batch unconfirmed transactions'),
long_desc=lambda: (
_('If you check this box, your unconfirmed transactions will be consolidated into a single transaction.') + '\n' +
_('This will save fees, but might have unwanted effects in terms of privacy')),
)
WALLET_SPEND_CONFIRMED_ONLY = ConfigVar(
'confirmed_only', default=False, type_=bool,
short_desc=lambda: _('Spend only confirmed coins'),
long_desc=lambda: _('Spend only confirmed inputs.'),
)
WALLET_COIN_CHOOSER_POLICY = ConfigVar('coin_chooser', default='Privacy', type_=str) WALLET_COIN_CHOOSER_POLICY = ConfigVar('coin_chooser', default='Privacy', type_=str)
WALLET_COIN_CHOOSER_OUTPUT_ROUNDING = ConfigVar('coin_chooser_output_rounding', default=True, type_=bool) WALLET_COIN_CHOOSER_OUTPUT_ROUNDING = ConfigVar(
'coin_chooser_output_rounding', default=True, type_=bool,
short_desc=lambda: _('Enable output value rounding'),
long_desc=lambda: (
_('Set the value of the change output so that it has similar precision to the other outputs.') + '\n' +
_('This might improve your privacy somewhat.') + '\n' +
_('If enabled, at most 100 satoshis might be lost due to this, per transaction.')),
)
WALLET_UNCONF_UTXO_FREEZE_THRESHOLD_SAT = ConfigVar('unconf_utxo_freeze_threshold', default=5_000, type_=int) WALLET_UNCONF_UTXO_FREEZE_THRESHOLD_SAT = ConfigVar('unconf_utxo_freeze_threshold', default=5_000, type_=int)
WALLET_BIP21_LIGHTNING = ConfigVar('bip21_lightning', default=False, type_=bool) WALLET_BIP21_LIGHTNING = ConfigVar(
WALLET_BOLT11_FALLBACK = ConfigVar('bolt11_fallback', default=True, type_=bool) 'bip21_lightning', default=False, type_=bool,
short_desc=lambda: _('Add lightning requests to bitcoin URIs'),
long_desc=lambda: _('This may result in large QR codes'),
)
WALLET_BOLT11_FALLBACK = ConfigVar(
'bolt11_fallback', default=True, type_=bool,
short_desc=lambda: _('Add on-chain fallback to lightning requests'),
)
WALLET_PAYREQ_EXPIRY_SECONDS = ConfigVar('request_expiry', default=invoices.PR_DEFAULT_EXPIRATION_WHEN_CREATING, type_=int) WALLET_PAYREQ_EXPIRY_SECONDS = ConfigVar('request_expiry', default=invoices.PR_DEFAULT_EXPIRATION_WHEN_CREATING, type_=int)
WALLET_USE_SINGLE_PASSWORD = ConfigVar('single_password', default=False, type_=bool) WALLET_USE_SINGLE_PASSWORD = ConfigVar('single_password', default=False, type_=bool)
# note: 'use_change' and 'multiple_change' are per-wallet settings # note: 'use_change' and 'multiple_change' are per-wallet settings
WALLET_SEND_CHANGE_TO_LIGHTNING = ConfigVar('send_change_to_lightning', default=False, type_=bool) WALLET_SEND_CHANGE_TO_LIGHTNING = ConfigVar(
'send_change_to_lightning', default=False, type_=bool,
short_desc=lambda: _('Send change to Lightning'),
long_desc=lambda: _('If possible, send the change of this transaction to your channels, with a submarine swap'),
)
FX_USE_EXCHANGE_RATE = ConfigVar('use_exchange_rate', default=False, type_=bool) FX_USE_EXCHANGE_RATE = ConfigVar('use_exchange_rate', default=False, type_=bool)
FX_CURRENCY = ConfigVar('currency', default='EUR', type_=str) FX_CURRENCY = ConfigVar('currency', default='EUR', type_=str)
FX_EXCHANGE = ConfigVar('use_exchange', default='CoinGecko', type_=str) # default exchange should ideally provide historical rates FX_EXCHANGE = ConfigVar('use_exchange', default='CoinGecko', type_=str) # default exchange should ideally provide historical rates
FX_HISTORY_RATES = ConfigVar('history_rates', default=False, type_=bool) FX_HISTORY_RATES = ConfigVar(
FX_HISTORY_RATES_CAPITAL_GAINS = ConfigVar('history_rates_capital_gains', default=False, type_=bool) 'history_rates', default=False, type_=bool,
FX_SHOW_FIAT_BALANCE_FOR_ADDRESSES = ConfigVar('fiat_address', default=False, type_=bool) short_desc=lambda: _('Download historical rates'),
)
FX_HISTORY_RATES_CAPITAL_GAINS = ConfigVar(
'history_rates_capital_gains', default=False, type_=bool,
short_desc=lambda: _('Show Capital Gains'),
)
FX_SHOW_FIAT_BALANCE_FOR_ADDRESSES = ConfigVar(
'fiat_address', default=False, type_=bool,
short_desc=lambda: _('Show Fiat balances'),
)
LIGHTNING_LISTEN = ConfigVar('lightning_listen', default=None, type_=str) LIGHTNING_LISTEN = ConfigVar('lightning_listen', default=None, type_=str)
LIGHTNING_PEERS = ConfigVar('lightning_peers', default=None) LIGHTNING_PEERS = ConfigVar('lightning_peers', default=None)
LIGHTNING_USE_GOSSIP = ConfigVar('use_gossip', default=False, type_=bool) LIGHTNING_USE_GOSSIP = ConfigVar(
LIGHTNING_USE_RECOVERABLE_CHANNELS = ConfigVar('use_recoverable_channels', default=True, type_=bool) 'use_gossip', default=False, type_=bool,
LIGHTNING_ALLOW_INSTANT_SWAPS = ConfigVar('allow_instant_swaps', default=False, type_=bool) short_desc=lambda: _("Use trampoline routing"),
long_desc=lambda: _("""Lightning payments require finding a path through the Lightning Network. You may use trampoline routing, or local routing (gossip).
Downloading the network gossip uses quite some bandwidth and storage, and is not recommended on mobile devices. If you use trampoline, you can only open channels with trampoline nodes."""),
)
LIGHTNING_USE_RECOVERABLE_CHANNELS = ConfigVar(
'use_recoverable_channels', default=True, type_=bool,
short_desc=lambda: _("Create recoverable channels"),
long_desc=lambda: _("""Add extra data to your channel funding transactions, so that a static backup can be recovered from your seed.
Note that static backups only allow you to request a force-close with the remote node. This assumes that the remote node is still online, did not lose its data, and accepts to force close the channel.
If this is enabled, other nodes cannot open a channel to you. Channel recovery data is encrypted, so that only your wallet can decrypt it. However, blockchain analysis will be able to tell that the transaction was probably created by Electrum."""),
)
LIGHTNING_ALLOW_INSTANT_SWAPS = ConfigVar(
'allow_instant_swaps', default=False, type_=bool,
short_desc=lambda: _("Allow instant swaps"),
long_desc=lambda: _("""If this option is checked, your client will complete reverse swaps before the funding transaction is confirmed.
Note you are at risk of losing the funds in the swap, if the funding transaction never confirms."""),
)
LIGHTNING_TO_SELF_DELAY_CSV = ConfigVar('lightning_to_self_delay', default=7 * 144, type_=int) LIGHTNING_TO_SELF_DELAY_CSV = ConfigVar('lightning_to_self_delay', default=7 * 144, type_=int)
LIGHTNING_MAX_FUNDING_SAT = ConfigVar('lightning_max_funding_sat', default=LN_MAX_FUNDING_SAT_LEGACY, type_=int) LIGHTNING_MAX_FUNDING_SAT = ConfigVar('lightning_max_funding_sat', default=LN_MAX_FUNDING_SAT_LEGACY, type_=int)
LIGHTNING_LEGACY_ADD_TRAMPOLINE = ConfigVar('lightning_legacy_add_trampoline', default=False, type_=bool) LIGHTNING_LEGACY_ADD_TRAMPOLINE = ConfigVar(
'lightning_legacy_add_trampoline', default=False, type_=bool,
short_desc=lambda: _("Add extra trampoline to legacy payments"),
long_desc=lambda: _("""When paying a non-trampoline invoice, add an extra trampoline to the route, in order to improve your privacy.
This will result in longer routes; it might increase your fees and decrease the success rate of your payments."""),
)
EXPERIMENTAL_LN_FORWARD_PAYMENTS = ConfigVar('lightning_forward_payments', default=False, type_=bool) EXPERIMENTAL_LN_FORWARD_PAYMENTS = ConfigVar('lightning_forward_payments', default=False, type_=bool)
EXPERIMENTAL_LN_FORWARD_TRAMPOLINE_PAYMENTS = ConfigVar('lightning_forward_trampoline_payments', default=False, type_=bool) EXPERIMENTAL_LN_FORWARD_TRAMPOLINE_PAYMENTS = ConfigVar('lightning_forward_trampoline_payments', default=False, type_=bool)
@ -921,18 +1006,36 @@ class SimpleConfig(Logger):
GUI_NAME = ConfigVar('gui', default='qt', type_=str) GUI_NAME = ConfigVar('gui', default='qt', type_=str)
GUI_LAST_WALLET = ConfigVar('gui_last_wallet', default=None, type_=str) GUI_LAST_WALLET = ConfigVar('gui_last_wallet', default=None, type_=str)
GUI_QT_COLOR_THEME = ConfigVar('qt_gui_color_theme', default='default', type_=str) GUI_QT_COLOR_THEME = ConfigVar(
'qt_gui_color_theme', default='default', type_=str,
short_desc=lambda: _('Color theme'),
)
GUI_QT_DARK_TRAY_ICON = ConfigVar('dark_icon', default=False, type_=bool) GUI_QT_DARK_TRAY_ICON = ConfigVar('dark_icon', default=False, type_=bool)
GUI_QT_WINDOW_IS_MAXIMIZED = ConfigVar('is_maximized', default=False, type_=bool) GUI_QT_WINDOW_IS_MAXIMIZED = ConfigVar('is_maximized', default=False, type_=bool)
GUI_QT_HIDE_ON_STARTUP = ConfigVar('hide_gui', default=False, type_=bool) GUI_QT_HIDE_ON_STARTUP = ConfigVar('hide_gui', default=False, type_=bool)
GUI_QT_HISTORY_TAB_SHOW_TOOLBAR = ConfigVar('show_toolbar_history', default=False, type_=bool) GUI_QT_HISTORY_TAB_SHOW_TOOLBAR = ConfigVar('show_toolbar_history', default=False, type_=bool)
GUI_QT_ADDRESSES_TAB_SHOW_TOOLBAR = ConfigVar('show_toolbar_addresses', default=False, type_=bool) GUI_QT_ADDRESSES_TAB_SHOW_TOOLBAR = ConfigVar('show_toolbar_addresses', default=False, type_=bool)
GUI_QT_TX_DIALOG_FETCH_TXIN_DATA = ConfigVar('tx_dialog_fetch_txin_data', default=False, type_=bool) GUI_QT_TX_DIALOG_FETCH_TXIN_DATA = ConfigVar(
'tx_dialog_fetch_txin_data', default=False, type_=bool,
short_desc=lambda: _('Download missing data'),
long_desc=lambda: _(
'Download parent transactions from the network.\n'
'Allows filling in missing fee and input details.'),
)
GUI_QT_RECEIVE_TABS_INDEX = ConfigVar('receive_tabs_index', default=0, type_=int) GUI_QT_RECEIVE_TABS_INDEX = ConfigVar('receive_tabs_index', default=0, type_=int)
GUI_QT_RECEIVE_TAB_QR_VISIBLE = ConfigVar('receive_qr_visible', default=False, type_=bool) GUI_QT_RECEIVE_TAB_QR_VISIBLE = ConfigVar('receive_qr_visible', default=False, type_=bool)
GUI_QT_TX_EDITOR_SHOW_IO = ConfigVar('show_tx_io', default=False, type_=bool) GUI_QT_TX_EDITOR_SHOW_IO = ConfigVar(
GUI_QT_TX_EDITOR_SHOW_FEE_DETAILS = ConfigVar('show_tx_fee_details', default=False, type_=bool) 'show_tx_io', default=False, type_=bool,
GUI_QT_TX_EDITOR_SHOW_LOCKTIME = ConfigVar('show_tx_locktime', default=False, type_=bool) short_desc=lambda: _('Show inputs and outputs'),
)
GUI_QT_TX_EDITOR_SHOW_FEE_DETAILS = ConfigVar(
'show_tx_fee_details', default=False, type_=bool,
short_desc=lambda: _('Edit fees manually'),
)
GUI_QT_TX_EDITOR_SHOW_LOCKTIME = ConfigVar(
'show_tx_locktime', default=False, type_=bool,
short_desc=lambda: _('Edit Locktime'),
)
GUI_QT_SHOW_TAB_ADDRESSES = ConfigVar('show_addresses_tab', default=False, type_=bool) GUI_QT_SHOW_TAB_ADDRESSES = ConfigVar('show_addresses_tab', default=False, type_=bool)
GUI_QT_SHOW_TAB_CHANNELS = ConfigVar('show_channels_tab', default=False, type_=bool) GUI_QT_SHOW_TAB_CHANNELS = ConfigVar('show_channels_tab', default=False, type_=bool)
GUI_QT_SHOW_TAB_UTXO = ConfigVar('show_utxo_tab', default=False, type_=bool) GUI_QT_SHOW_TAB_UTXO = ConfigVar('show_utxo_tab', default=False, type_=bool)
@ -943,21 +1046,59 @@ class SimpleConfig(Logger):
GUI_QML_USER_KNOWS_PRESS_AND_HOLD = ConfigVar('user_knows_press_and_hold', default=False, type_=bool) GUI_QML_USER_KNOWS_PRESS_AND_HOLD = ConfigVar('user_knows_press_and_hold', default=False, type_=bool)
BTC_AMOUNTS_DECIMAL_POINT = ConfigVar('decimal_point', default=DECIMAL_POINT_DEFAULT, type_=int) BTC_AMOUNTS_DECIMAL_POINT = ConfigVar('decimal_point', default=DECIMAL_POINT_DEFAULT, type_=int)
BTC_AMOUNTS_FORCE_NZEROS_AFTER_DECIMAL_POINT = ConfigVar('num_zeros', default=0, type_=int) BTC_AMOUNTS_FORCE_NZEROS_AFTER_DECIMAL_POINT = ConfigVar(
BTC_AMOUNTS_PREC_POST_SAT = ConfigVar('amt_precision_post_satoshi', default=0, type_=int) 'num_zeros', default=0, type_=int,
BTC_AMOUNTS_ADD_THOUSANDS_SEP = ConfigVar('amt_add_thousands_sep', default=False, type_=bool) short_desc=lambda: _('Zeros after decimal point'),
long_desc=lambda: _('Number of zeros displayed after the decimal point. For example, if this is set to 2, "1." will be displayed as "1.00"'),
BLOCK_EXPLORER = ConfigVar('block_explorer', default='Blockstream.info', type_=str) )
BTC_AMOUNTS_PREC_POST_SAT = ConfigVar(
'amt_precision_post_satoshi', default=0, type_=int,
short_desc=lambda: _("Show Lightning amounts with msat precision"),
)
BTC_AMOUNTS_ADD_THOUSANDS_SEP = ConfigVar(
'amt_add_thousands_sep', default=False, type_=bool,
short_desc=lambda: _("Add thousand separators to bitcoin amounts"),
)
BLOCK_EXPLORER = ConfigVar(
'block_explorer', default='Blockstream.info', type_=str,
short_desc=lambda: _('Online Block Explorer'),
long_desc=lambda: _('Choose which online block explorer to use for functions that open a web browser'),
)
BLOCK_EXPLORER_CUSTOM = ConfigVar('block_explorer_custom', default=None) BLOCK_EXPLORER_CUSTOM = ConfigVar('block_explorer_custom', default=None)
VIDEO_DEVICE_PATH = ConfigVar('video_device', default='default', type_=str) VIDEO_DEVICE_PATH = ConfigVar(
OPENALIAS_ID = ConfigVar('alias', default="", type_=str) 'video_device', default='default', type_=str,
short_desc=lambda: _('Video Device'),
long_desc=lambda: (_("For scanning QR codes.") + "\n" +
_("Install the zbar package to enable this.")),
)
OPENALIAS_ID = ConfigVar(
'alias', default="", type_=str,
short_desc=lambda: 'OpenAlias',
long_desc=lambda: (
_('OpenAlias record, used to receive coins and to sign payment requests.') + '\n\n' +
_('The following alias providers are available:') + '\n' +
'\n'.join(['https://cryptoname.co/', 'http://xmr.link']) + '\n\n' +
'For more information, see https://openalias.org'),
)
HWD_SESSION_TIMEOUT = ConfigVar('session_timeout', default=300, type_=int) HWD_SESSION_TIMEOUT = ConfigVar('session_timeout', default=300, type_=int)
CLI_TIMEOUT = ConfigVar('timeout', default=60, type_=float) CLI_TIMEOUT = ConfigVar('timeout', default=60, type_=float)
AUTOMATIC_CENTRALIZED_UPDATE_CHECKS = ConfigVar('check_updates', default=False, type_=bool) AUTOMATIC_CENTRALIZED_UPDATE_CHECKS = ConfigVar(
WRITE_LOGS_TO_DISK = ConfigVar('log_to_file', default=False, type_=bool) 'check_updates', default=False, type_=bool,
short_desc=lambda: _("Automatically check for software updates"),
)
WRITE_LOGS_TO_DISK = ConfigVar(
'log_to_file', default=False, type_=bool,
short_desc=lambda: _("Write logs to file"),
long_desc=lambda: _('Debug logs can be persisted to disk. These are useful for troubleshooting.'),
)
LOGS_NUM_FILES_KEEP = ConfigVar('logs_num_files_keep', default=10, type_=int) LOGS_NUM_FILES_KEEP = ConfigVar('logs_num_files_keep', default=10, type_=int)
GUI_ENABLE_DEBUG_LOGS = ConfigVar('gui_enable_debug_logs', default=False, type_=bool) GUI_ENABLE_DEBUG_LOGS = ConfigVar('gui_enable_debug_logs', default=False, type_=bool)
LOCALIZATION_LANGUAGE = ConfigVar('language', default="", type_=str) LOCALIZATION_LANGUAGE = ConfigVar(
'language', default="", type_=str,
short_desc=lambda: _("Language"),
long_desc=lambda: _("Select which language is used in the GUI (after restart)."),
)
BLOCKCHAIN_PREFERRED_BLOCK = ConfigVar('blockchain_preferred_block', default=None) BLOCKCHAIN_PREFERRED_BLOCK = ConfigVar('blockchain_preferred_block', default=None)
SHOW_CRASH_REPORTER = ConfigVar('show_crash_reporter', default=True, type_=bool) SHOW_CRASH_REPORTER = ConfigVar('show_crash_reporter', default=True, type_=bool)
DONT_SHOW_TESTNET_WARNING = ConfigVar('dont_show_testnet_warning', default=False, type_=bool) DONT_SHOW_TESTNET_WARNING = ConfigVar('dont_show_testnet_warning', default=False, type_=bool)
@ -975,7 +1116,15 @@ class SimpleConfig(Logger):
TEST_SWAPSERVER_REFUND = ConfigVar('test_swapserver_refund', default=False, type_=bool) TEST_SWAPSERVER_REFUND = ConfigVar('test_swapserver_refund', default=False, type_=bool)
# connect to remote WT # connect to remote WT
WATCHTOWER_CLIENT_ENABLED = ConfigVar('use_watchtower', default=False, type_=bool) WATCHTOWER_CLIENT_ENABLED = ConfigVar(
'use_watchtower', default=False, type_=bool,
short_desc=lambda: _("Use a remote watchtower"),
long_desc=lambda: ' '.join([
_("A watchtower is a daemon that watches your channels and prevents the other party from stealing funds by broadcasting an old state."),
_("If you have private a watchtower, enter its URL here."),
_("Check our online documentation if you want to configure Electrum as a watchtower."),
]),
)
WATCHTOWER_CLIENT_URL = ConfigVar('watchtower_url', default=None, type_=str) WATCHTOWER_CLIENT_URL = ConfigVar('watchtower_url', default=None, type_=str)
# run WT locally # run WT locally

Loading…
Cancel
Save