Qt settings_dialog: use signals
- changes must apply to all windows - do not keep reference to the window object
This commit is contained in:
@@ -21,15 +21,15 @@
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
import re
|
||||
|
||||
import dns
|
||||
import threading
|
||||
from dns.exception import DNSException
|
||||
|
||||
from . import bitcoin
|
||||
from . import dnssec
|
||||
from .util import read_json_file, write_json_file, to_string
|
||||
from .logging import Logger
|
||||
|
||||
from .util import trigger_callback
|
||||
|
||||
class Contacts(dict, Logger):
|
||||
|
||||
@@ -94,6 +94,18 @@ class Contacts(dict, Logger):
|
||||
}
|
||||
raise Exception("Invalid Bitcoin address or alias", k)
|
||||
|
||||
def fetch_openalias(self, config):
|
||||
self.alias_info = None
|
||||
alias = config.get('alias')
|
||||
if alias:
|
||||
alias = str(alias)
|
||||
def f():
|
||||
self.alias_info = self.resolve_openalias(alias)
|
||||
trigger_callback('alias_received')
|
||||
t = threading.Thread(target=f)
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
|
||||
def resolve_openalias(self, url):
|
||||
# support email-style addresses, per the OA standard
|
||||
url = url.replace('@', '.')
|
||||
|
||||
@@ -95,6 +95,11 @@ class OpenFileEventFilter(QObject):
|
||||
class QElectrumApplication(QApplication):
|
||||
new_window_signal = pyqtSignal(str, object)
|
||||
quit_signal = pyqtSignal()
|
||||
refresh_tabs_signal = pyqtSignal()
|
||||
refresh_amount_edits_signal = pyqtSignal()
|
||||
update_status_signal = pyqtSignal()
|
||||
update_fiat_signal = pyqtSignal()
|
||||
alias_received_signal = pyqtSignal()
|
||||
|
||||
|
||||
class QNetworkUpdatedSignalObject(QObject):
|
||||
|
||||
@@ -170,7 +170,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
|
||||
payment_request_error_signal = pyqtSignal()
|
||||
network_signal = pyqtSignal(str, object)
|
||||
#ln_payment_attempt_signal = pyqtSignal(str)
|
||||
alias_received_signal = pyqtSignal()
|
||||
computing_privkeys_signal = pyqtSignal()
|
||||
show_privkeys_signal = pyqtSignal()
|
||||
show_error_signal = pyqtSignal(str)
|
||||
@@ -274,6 +273,11 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
|
||||
for i in range(wrtabs.count()):
|
||||
QShortcut(QKeySequence("Alt+" + str(i + 1)), self, lambda i=i: wrtabs.setCurrentIndex(i))
|
||||
|
||||
self.app.refresh_tabs_signal.connect(self.refresh_tabs)
|
||||
self.app.refresh_amount_edits_signal.connect(self.refresh_amount_edits)
|
||||
self.app.update_status_signal.connect(self.update_status)
|
||||
self.app.update_fiat_signal.connect(self.update_fiat)
|
||||
|
||||
self.payment_request_ok_signal.connect(self.payment_request_ok)
|
||||
self.payment_request_error_signal.connect(self.payment_request_error)
|
||||
self.show_error_signal.connect(self.show_error)
|
||||
@@ -301,7 +305,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
|
||||
#self.fee_slider.update()
|
||||
self.load_wallet(wallet)
|
||||
gui_object.timer.timeout.connect(self.timer_actions)
|
||||
self.fetch_alias()
|
||||
self.contacts.fetch_openalias(self.config)
|
||||
|
||||
# If the option hasn't been set yet
|
||||
if config.get('check_updates') is None:
|
||||
@@ -496,18 +500,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
|
||||
else:
|
||||
self.logger.info(f"unexpected network event: {event} {args}")
|
||||
|
||||
def fetch_alias(self):
|
||||
self.alias_info = None
|
||||
alias = self.config.get('alias')
|
||||
if alias:
|
||||
alias = str(alias)
|
||||
def f():
|
||||
self.alias_info = self.contacts.resolve_openalias(alias)
|
||||
self.alias_received_signal.emit()
|
||||
t = threading.Thread(target=f)
|
||||
t.setDaemon(True)
|
||||
t.start()
|
||||
|
||||
def close_wallet(self):
|
||||
if self.wallet:
|
||||
self.logger.info(f'close_wallet {self.wallet.storage.path}')
|
||||
@@ -3348,21 +3340,26 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
|
||||
header_layout.addWidget(InfoButton(WIF_HELP_TEXT), alignment=Qt.AlignRight)
|
||||
self._do_import(title, header_layout, lambda x: self.wallet.import_private_keys(x, password))
|
||||
|
||||
def refresh_amount_edits(self):
|
||||
edits = self.amount_e, self.receive_amount_e
|
||||
amounts = [edit.get_amount() for edit in edits]
|
||||
for edit, amount in zip(edits, amounts):
|
||||
edit.setAmount(amount)
|
||||
|
||||
def update_fiat(self):
|
||||
b = self.fx and self.fx.is_enabled()
|
||||
self.fiat_send_e.setVisible(b)
|
||||
self.fiat_receive_e.setVisible(b)
|
||||
self.history_model.refresh('update_fiat')
|
||||
self.history_list.update()
|
||||
self.address_list.refresh_headers()
|
||||
self.address_list.refresh_all()
|
||||
self.address_list.update()
|
||||
self.update_status()
|
||||
|
||||
def settings_dialog(self):
|
||||
from .settings_dialog import SettingsDialog
|
||||
d = SettingsDialog(self, self.config)
|
||||
self.alias_received_signal.connect(d.set_alias_color)
|
||||
d.exec_()
|
||||
self.alias_received_signal.disconnect(d.set_alias_color)
|
||||
if self.fx:
|
||||
self.fx.trigger_update()
|
||||
run_hook('close_settings_dialog')
|
||||
|
||||
@@ -27,7 +27,7 @@ import ast
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtWidgets import (QComboBox, QTabWidget,
|
||||
from PyQt5.QtWidgets import (QComboBox, QTabWidget, QDialog,
|
||||
QSpinBox, QFileDialog, QCheckBox, QLabel,
|
||||
QVBoxLayout, QGridLayout, QLineEdit,
|
||||
QPushButton, QWidget, QHBoxLayout)
|
||||
@@ -47,16 +47,22 @@ if TYPE_CHECKING:
|
||||
from .main_window import ElectrumWindow
|
||||
|
||||
|
||||
class SettingsDialog(WindowModalDialog):
|
||||
class SettingsDialog(QDialog):
|
||||
|
||||
def __init__(self, parent: 'ElectrumWindow', config: 'SimpleConfig'):
|
||||
WindowModalDialog.__init__(self, parent, _('Preferences'))
|
||||
def __init__(self, window: 'ElectrumWindow', config: 'SimpleConfig'):
|
||||
QDialog.__init__(self)
|
||||
self.setWindowTitle(_('Preferences'))
|
||||
self.setMinimumWidth(500)
|
||||
self.config = config
|
||||
self.window = parent
|
||||
self.network = window.network
|
||||
self.app = window.app
|
||||
self.need_restart = False
|
||||
self.fx = self.window.fx
|
||||
self.wallet = self.window.wallet
|
||||
|
||||
self.fx = window.fx
|
||||
self.wallet = window.wallet
|
||||
|
||||
util.register_callback(self.on_network_callback, ['alias_received'])
|
||||
self.app.alias_received_signal.connect(self.set_alias_color)
|
||||
|
||||
vbox = QVBoxLayout()
|
||||
tabs = QTabWidget()
|
||||
|
||||
@@ -94,7 +100,7 @@ class SettingsDialog(WindowModalDialog):
|
||||
if self.config.num_zeros != value:
|
||||
self.config.num_zeros = value
|
||||
self.config.set_key('num_zeros', value, True)
|
||||
self.window.refresh_tabs()
|
||||
self.app.refresh_tabs_signal.emit()
|
||||
nz.valueChanged.connect(on_nz)
|
||||
|
||||
# invoices
|
||||
@@ -153,10 +159,10 @@ class SettingsDialog(WindowModalDialog):
|
||||
use_gossip = not bool(use_trampoline)
|
||||
self.config.set_key('use_gossip', use_gossip)
|
||||
if use_gossip:
|
||||
self.window.network.start_gossip()
|
||||
self.network.start_gossip()
|
||||
else:
|
||||
self.window.network.run_from_another_thread(
|
||||
self.window.network.stop_gossip())
|
||||
self.network.run_from_another_thread(
|
||||
self.network.stop_gossip())
|
||||
util.trigger_callback('ln_gossip_sync_progress')
|
||||
# FIXME: update all wallet windows
|
||||
util.trigger_callback('channels_updated', self.wallet)
|
||||
@@ -210,7 +216,7 @@ class SettingsDialog(WindowModalDialog):
|
||||
if self.config.amt_precision_post_satoshi != prec:
|
||||
self.config.amt_precision_post_satoshi = prec
|
||||
self.config.set_key('amt_precision_post_satoshi', prec)
|
||||
self.window.refresh_tabs()
|
||||
self.app.refresh_tabs_signal.emit()
|
||||
msat_cb.stateChanged.connect(on_msat_checked)
|
||||
|
||||
# units
|
||||
@@ -221,19 +227,16 @@ class SettingsDialog(WindowModalDialog):
|
||||
unit_label = HelpLabel(_('Base unit') + ':', msg)
|
||||
unit_combo = QComboBox()
|
||||
unit_combo.addItems(units)
|
||||
unit_combo.setCurrentIndex(units.index(self.window.base_unit()))
|
||||
unit_combo.setCurrentIndex(units.index(self.config.get_base_unit()))
|
||||
def on_unit(x, nz):
|
||||
unit_result = units[unit_combo.currentIndex()]
|
||||
if self.window.base_unit() == unit_result:
|
||||
if self.config.get_base_unit() == unit_result:
|
||||
return
|
||||
edits = self.window.amount_e, self.window.receive_amount_e
|
||||
amounts = [edit.get_amount() for edit in edits]
|
||||
self.config.set_base_unit(unit_result)
|
||||
nz.setMaximum(self.config.decimal_point)
|
||||
self.window.update_tabs()
|
||||
for edit, amount in zip(edits, amounts):
|
||||
edit.setAmount(amount)
|
||||
self.window.update_status()
|
||||
self.app.refresh_tabs_signal.emit()
|
||||
self.app.update_status_signal.emit()
|
||||
self.app.refresh_amount_edits_signal.emit()
|
||||
unit_combo.currentIndexChanged.connect(lambda x: on_unit(x, nz))
|
||||
|
||||
thousandsep_cb = QCheckBox(_("Add thousand separators to bitcoin amounts"))
|
||||
@@ -243,7 +246,7 @@ class SettingsDialog(WindowModalDialog):
|
||||
if self.config.amt_add_thousands_sep != checked:
|
||||
self.config.amt_add_thousands_sep = checked
|
||||
self.config.set_key('amt_add_thousands_sep', checked)
|
||||
self.window.refresh_tabs()
|
||||
self.app.refresh_tabs_signal.emit()
|
||||
thousandsep_cb.stateChanged.connect(on_set_thousandsep)
|
||||
|
||||
qr_combo = QComboBox()
|
||||
@@ -268,7 +271,6 @@ class SettingsDialog(WindowModalDialog):
|
||||
colortheme_label = QLabel(_('Color theme') + ':')
|
||||
def on_colortheme(x):
|
||||
self.config.set_key('qt_gui_color_theme', colortheme_combo.itemData(x), True)
|
||||
#self.window.gui_object.reload_app_stylesheet()
|
||||
self.need_restart = True
|
||||
colortheme_combo.currentIndexChanged.connect(on_colortheme)
|
||||
|
||||
@@ -294,14 +296,14 @@ class SettingsDialog(WindowModalDialog):
|
||||
preview_cb.stateChanged.connect(on_preview)
|
||||
|
||||
usechange_cb = QCheckBox(_('Use change addresses'))
|
||||
usechange_cb.setChecked(self.window.wallet.use_change)
|
||||
usechange_cb.setChecked(self.wallet.use_change)
|
||||
if not self.config.is_modifiable('use_change'): usechange_cb.setEnabled(False)
|
||||
def on_usechange(x):
|
||||
usechange_result = x == Qt.Checked
|
||||
if self.window.wallet.use_change != usechange_result:
|
||||
self.window.wallet.use_change = usechange_result
|
||||
self.window.wallet.db.put('use_change', self.window.wallet.use_change)
|
||||
multiple_cb.setEnabled(self.window.wallet.use_change)
|
||||
if self.wallet.use_change != usechange_result:
|
||||
self.wallet.use_change = usechange_result
|
||||
self.wallet.db.put('use_change', self.wallet.use_change)
|
||||
multiple_cb.setEnabled(self.wallet.use_change)
|
||||
usechange_cb.stateChanged.connect(on_usechange)
|
||||
usechange_cb.setToolTip(_('Using change addresses makes it more difficult for other people to track your transactions.'))
|
||||
|
||||
@@ -407,7 +409,8 @@ class SettingsDialog(WindowModalDialog):
|
||||
ex_combo = QComboBox()
|
||||
|
||||
def update_currencies():
|
||||
if not self.window.fx: return
|
||||
if not self.fx:
|
||||
return
|
||||
currencies = sorted(self.fx.get_currencies(self.fx.get_history_config()))
|
||||
ccy_combo.clear()
|
||||
ccy_combo.addItems([_('None')] + currencies)
|
||||
@@ -453,7 +456,7 @@ class SettingsDialog(WindowModalDialog):
|
||||
self.fx.set_currency(ccy)
|
||||
update_history_cb()
|
||||
update_exchanges()
|
||||
self.window.update_fiat()
|
||||
self.app.update_fiat_signal.emit()
|
||||
|
||||
def on_exchange(idx):
|
||||
exchange = str(ex_combo.currentText())
|
||||
@@ -464,21 +467,20 @@ class SettingsDialog(WindowModalDialog):
|
||||
if not self.fx: return
|
||||
self.fx.set_history_config(checked)
|
||||
update_exchanges()
|
||||
self.window.history_model.refresh('on_history')
|
||||
if self.fx.is_enabled() and checked:
|
||||
self.fx.trigger_update()
|
||||
update_history_capgains_cb()
|
||||
self.app.update_fiat_signal.emit()
|
||||
|
||||
def on_history_capgains(checked):
|
||||
if not self.fx: return
|
||||
self.fx.set_history_capital_gains_config(checked)
|
||||
self.window.history_model.refresh('on_history_capgains')
|
||||
self.app.update_fiat_signal.emit()
|
||||
|
||||
def on_fiat_address(checked):
|
||||
if not self.fx: return
|
||||
self.fx.set_fiat_address_config(checked)
|
||||
self.window.address_list.refresh_headers()
|
||||
self.window.address_list.update()
|
||||
self.app.update_fiat_signal.emit()
|
||||
|
||||
update_currencies()
|
||||
update_history_cb()
|
||||
@@ -531,8 +533,8 @@ class SettingsDialog(WindowModalDialog):
|
||||
|
||||
tabs_info = [
|
||||
(gui_widgets, _('Appearance')),
|
||||
(invoices_widgets, _('Invoices')),
|
||||
(tx_widgets, _('Transactions')),
|
||||
(invoices_widgets, _('Invoices')),
|
||||
(lightning_widgets, _('Lightning')),
|
||||
(fiat_widgets, _('Fiat')),
|
||||
(misc_widgets, _('Misc')),
|
||||
@@ -558,12 +560,16 @@ class SettingsDialog(WindowModalDialog):
|
||||
vbox.addLayout(Buttons(CloseButton(self)))
|
||||
self.setLayout(vbox)
|
||||
|
||||
def on_network_callback(self, cb):
|
||||
if cb == 'alias_received':
|
||||
self.app.alias_received_signal.emit()
|
||||
|
||||
def set_alias_color(self):
|
||||
if not self.config.get('alias'):
|
||||
self.alias_e.setStyleSheet("")
|
||||
return
|
||||
if self.window.alias_info:
|
||||
alias_addr, alias_name, validated = self.window.alias_info
|
||||
if self.wallet.contacts.alias_info:
|
||||
alias_addr, alias_name, validated = self.wallet.contacts.alias_info
|
||||
self.alias_e.setStyleSheet((ColorScheme.GREEN if validated else ColorScheme.RED).as_stylesheet(True))
|
||||
else:
|
||||
self.alias_e.setStyleSheet(ColorScheme.RED.as_stylesheet(True))
|
||||
@@ -573,4 +579,4 @@ class SettingsDialog(WindowModalDialog):
|
||||
alias = str(self.alias_e.text())
|
||||
self.config.set_key('alias', alias, True)
|
||||
if alias:
|
||||
self.window.fetch_alias()
|
||||
self.wallet.contacts.fetch_openalias(self.config)
|
||||
|
||||
Reference in New Issue
Block a user