electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit f5c58c5e19fdc7098197f33cb3cf3e7d86080f1c
parent db60634774edb1fe7f44ed909ad6c511d944c121
Author: ThomasV <thomasv@electrum.org>
Date:   Tue,  7 May 2019 09:10:23 +0200

lightning network dialog

Diffstat:
Melectrum/gui/qt/__init__.py | 36++++++++++++++++++------------------
Melectrum/gui/qt/channels_list.py | 10----------
Aelectrum/gui/qt/lightning_dialog.py | 139+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Melectrum/gui/qt/main_window.py | 8++------
Delectrum/gui/qt/watchtower_window.py | 123-------------------------------------------------------------------------------
5 files changed, 159 insertions(+), 157 deletions(-)

diff --git a/electrum/gui/qt/__init__.py b/electrum/gui/qt/__init__.py @@ -55,6 +55,7 @@ from .util import get_default_language, read_QIcon, ColorScheme, custom_message_ from .main_window import ElectrumWindow from .network_dialog import NetworkDialog from .stylesheet_patcher import patch_qt_stylesheet +from .lightning_dialog import LightningDialog class OpenFileEventFilter(QObject): @@ -107,8 +108,8 @@ class ElectrumGui(Logger): self.timer.setSingleShot(False) self.timer.setInterval(500) # msec - self.nd = None - self.watchtower_window = None + self.network_dialog = None + self.lightning_dialog = None self.network_updated_signal_obj = QNetworkUpdatedSignalObject() self._num_wizards_in_progress = 0 self._num_wizards_lock = threading.Lock() @@ -148,7 +149,7 @@ class ElectrumGui(Logger): m = self.tray.contextMenu() m.clear() if self.config.get('lightning'): - m.addAction(_("Watchtower"), self.show_watchtower_dialog) + m.addAction(_("Lightning"), self.show_lightning_dialog) for window in self.windows: name = window.wallet.basename() submenu = m.addMenu(name) @@ -181,33 +182,32 @@ class ElectrumGui(Logger): def close(self): for window in self.windows: window.close() - if self.nd: - self.nd.close() - if self.watchtower_window: - self.watchtower_window.close() + if self.network_dialog: + self.network_dialog.close() + if self.lightning_dialog: + self.lightning_dialog.close() def new_window(self, path, uri=None): # Use a signal as can be called from daemon thread self.app.new_window_signal.emit(path, uri) - def show_watchtower_dialog(self, parent=None): - from .watchtower_window import WatchTowerWindow - if not self.watchtower_window: - self.watchtower_window = WatchTowerWindow(self) - self.watchtower_window.bring_to_top() + def show_lightning_dialog(self): + if not self.lightning_dialog: + self.lightning_dialog = LightningDialog(self) + self.lightning_dialog.bring_to_top() def show_network_dialog(self, parent): if not self.daemon.network: parent.show_warning(_('You are using Electrum in offline mode; restart Electrum if you want to get connected'), title=_('Offline')) return - if self.nd: - self.nd.on_update() - self.nd.show() - self.nd.raise_() + if self.network_dialog: + self.network_dialog.on_update() + self.network_dialog.show() + self.network_dialog.raise_() return - self.nd = NetworkDialog(self.daemon.network, self.config, + self.network_dialog = NetworkDialog(self.daemon.network, self.config, self.network_updated_signal_obj) - self.nd.show() + self.network_dialog.show() def _create_window_for_wallet(self, wallet): w = ElectrumWindow(self, wallet) diff --git a/electrum/gui/qt/channels_list.py b/electrum/gui/qt/channels_list.py @@ -23,7 +23,6 @@ class ChannelsList(MyTreeView): self.main_window = parent self.update_rows.connect(self.do_update_rows) self.update_single_row.connect(self.do_update_single_row) - self.status = QLabel('') def format_fields(self, chan): labels = {} @@ -98,19 +97,10 @@ class ChannelsList(MyTreeView): def get_toolbar(self): h = QHBoxLayout() - h.addWidget(self.status) h.addStretch() h.addWidget(EnterButton(_('Open Channel'), self.new_channel_dialog)) return h - def update_status(self): - network = self.parent.network - if network.lngossip is None: - return - channel_db = self.parent.network.channel_db - num_peers = sum([p.initialized.is_set() for p in network.lngossip.peers.values()]) - msg = _('{} peers, {} nodes, {} channels.').format(num_peers, channel_db.num_nodes, channel_db.num_channels) - self.status.setText(msg) def statistics_dialog(self): channel_db = self.parent.network.channel_db diff --git a/electrum/gui/qt/lightning_dialog.py b/electrum/gui/qt/lightning_dialog.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python +# +# Electrum - lightweight Bitcoin client +# Copyright (C) 2012 thomasv@gitorious +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import socket + +from PyQt5.QtGui import * +from PyQt5.QtCore import * +from PyQt5.QtWidgets import * +import PyQt5.QtCore as QtCore + +from electrum.i18n import _ +from .util import * + +help_about = _("""The local watchtower will persist on this computer after you close +your wallet, but it requires to be online regularly.""") + +help_remote = _(""" To setup a remote watchtower, configure a remote electrum daemon +with 'watchtower_host' and 'watchtower_port' """) + +class WatcherList(MyTreeView): + def __init__(self, parent): + super().__init__(parent, self.create_menu, stretch_column=0, editable_columns=[]) + self.setModel(QStandardItemModel(self)) + self.setSortingEnabled(True) + self.update() + + def create_menu(self, x): + pass + + def update(self): + if self.parent.lnwatcher is None: + return + self.model().clear() + self.update_headers({0:_('Outpoint'), 1:_('Tx'), 2:_('Status')}) + sweepstore = self.parent.lnwatcher.sweepstore + for outpoint in sweepstore.list_sweep_tx(): + n = sweepstore.get_num_tx(outpoint) + status = self.parent.lnwatcher.get_channel_status(outpoint) + items = [QStandardItem(e) for e in [outpoint, "%d"%n, status]] + self.model().insertRow(self.model().rowCount(), items) + + +class LightningDialog(QDialog): + + def __init__(self, gui_object): + QDialog.__init__(self) + self.gui_object = gui_object + self.config = gui_object.config + self.network = gui_object.daemon.network + self.lnwatcher = self.network.lnwatcher + self.setWindowTitle(_('Lightning')) + self.setMinimumSize(600, 20) + watchtower_url = self.config.get('watchtower_url') + self.watchtower_e = QLineEdit(watchtower_url) + self.watcher_list = WatcherList(self) + # channel_db + network_w = QWidget() + network_vbox = QVBoxLayout(network_w) + self.status = QLabel('') + network_vbox.addWidget(self.status) + # local + local_w = QWidget() + vbox_local = QVBoxLayout(local_w) + vbox_local.addWidget(WWLabel(help_about)) + vbox_local.addWidget(self.watcher_list) + # remote + remote_w = QWidget() + vbox_remote = QVBoxLayout(remote_w) + vbox_remote.addWidget(WWLabel(help_remote)) + g = QGridLayout(remote_w) + g.addWidget(QLabel(_('URL') + ':'), 1, 0) + g.addWidget(self.watchtower_e, 1, 1) + vbox_remote.addLayout(g) + vbox_remote.addStretch(1) + # tabs + tabs = QTabWidget() + tabs.addTab(network_w, _('Network')) + tabs.addTab(local_w, _('Watchtower')) + tabs.addTab(remote_w, _('Settings')) + vbox = QVBoxLayout(self) + vbox.addWidget(tabs) + b = QPushButton(_('Close')) + b.clicked.connect(self.on_close) + vbox.addLayout(Buttons(b)) + self.watcher_list.update() + self.gui_object.timer.timeout.connect(self.update_status) + + def update_status(self): + if self.network.lngossip is None: + return + channel_db = self.network.channel_db + num_peers = sum([p.initialized.is_set() for p in self.network.lngossip.peers.values()]) + msg = _('{} peers, {} nodes, {} channels.').format(num_peers, channel_db.num_nodes, channel_db.num_channels) + self.status.setText(msg) + + def on_close(self): + url = self.watchtower_e.text() + if url: + self.lnwatcher.set_remote_watchtower() + self.hide() + + def is_hidden(self): + return self.isMinimized() or self.isHidden() + + def show_or_hide(self): + if self.is_hidden(): + self.bring_to_top() + else: + self.hide() + + def bring_to_top(self): + self.show() + self.raise_() + + def closeEvent(self, event): + self.gui_object.watchtower_window = None + event.accept() diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py @@ -157,8 +157,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): self.create_status_bar() self.need_update = threading.Event() - self.need_update_ln = threading.Event() - self.decimal_point = config.get('decimal_point', DECIMAL_POINT_DEFAULT) try: decimal_point_to_base_unit_name(self.decimal_point) @@ -224,7 +222,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): interests = ['wallet_updated', 'network_updated', 'blockchain_updated', 'new_transaction', 'status', 'banner', 'verified', 'fee', 'fee_histogram', 'on_quotes', - 'on_history', 'channel', 'channels', 'ln_status', 'ln_message', + 'on_history', 'channel', 'channels', 'ln_message', 'ln_payment_completed'] # To avoid leaking references to "self" that prevent the # window from being GC-ed when closed, callbacks should be @@ -374,8 +372,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): elif event == 'channel': self.channels_list.update_single_row.emit(*args) self.update_status() - elif event == 'ln_status': - self.need_update_ln.set() elif event == 'ln_payment_completed': # FIXME it is really inefficient to force update the whole GUI # just for a single LN payment. individual rows in lists should be updated instead. @@ -638,7 +634,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): tools_menu.addAction(_("Electrum preferences") if sys.platform == 'darwin' else _("Preferences"), self.settings_dialog) tools_menu.addAction(_("&Network"), lambda: self.gui_object.show_network_dialog(self)) if self.config.get('lightning'): - tools_menu.addAction(_("&Watchtower"), lambda: self.gui_object.show_watchtower_dialog(self)) + tools_menu.addAction(_("&Lightning"), self.gui_object.show_lightning_dialog) tools_menu.addAction(_("&Plugins"), self.plugins_dialog) tools_menu.addSeparator() tools_menu.addAction(_("&Sign/verify message"), self.sign_verify_message) diff --git a/electrum/gui/qt/watchtower_window.py b/electrum/gui/qt/watchtower_window.py @@ -1,123 +0,0 @@ -#!/usr/bin/env python -# -# Electrum - lightweight Bitcoin client -# Copyright (C) 2012 thomasv@gitorious -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation files -# (the "Software"), to deal in the Software without restriction, -# including without limitation the rights to use, copy, modify, merge, -# publish, distribute, sublicense, and/or sell copies of the Software, -# and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -import socket - -from PyQt5.QtGui import * -from PyQt5.QtCore import * -from PyQt5.QtWidgets import * -import PyQt5.QtCore as QtCore - -from electrum.i18n import _ -from .util import * - -help_about = _("""The local watchtower will persist on this computer after you close -your wallet, but it requires to be online regularly.""") - -help_remote = _(""" To setup a remote watchtower, configure a remote electrum daemon -with 'watchtower_host' and 'watchtower_port' """) - -class WatcherList(MyTreeView): - def __init__(self, parent): - super().__init__(parent, self.create_menu, stretch_column=0, editable_columns=[]) - self.setModel(QStandardItemModel(self)) - self.setSortingEnabled(True) - self.update() - - def create_menu(self, x): - pass - - def update(self): - if self.parent.lnwatcher is None: - return - self.model().clear() - self.update_headers({0:_('Outpoint'), 1:_('Tx'), 2:_('Status')}) - sweepstore = self.parent.lnwatcher.sweepstore - for outpoint in sweepstore.list_sweep_tx(): - n = sweepstore.get_num_tx(outpoint) - status = self.parent.lnwatcher.get_channel_status(outpoint) - items = [QStandardItem(e) for e in [outpoint, "%d"%n, status]] - self.model().insertRow(self.model().rowCount(), items) - - -class WatchTowerWindow(QDialog): - - def __init__(self, gui_object): - QDialog.__init__(self) - self.gui_object = gui_object - self.config = gui_object.config - self.lnwatcher = gui_object.daemon.network.lnwatcher - self.setWindowTitle(_('Watchtower')) - self.setMinimumSize(600, 20) - watchtower_url = self.config.get('watchtower_url') - self.watchtower_e = QLineEdit(watchtower_url) - self.channel_list = WatcherList(self) - # local - local_w = QWidget() - vbox_local = QVBoxLayout(local_w) - vbox_local.addWidget(WWLabel(help_about)) - vbox_local.addWidget(self.channel_list) - # remote - remote_w = QWidget() - vbox_remote = QVBoxLayout(remote_w) - vbox_remote.addWidget(WWLabel(help_remote)) - g = QGridLayout(remote_w) - g.addWidget(QLabel(_('URL') + ':'), 1, 0) - g.addWidget(self.watchtower_e, 1, 1) - vbox_remote.addLayout(g) - vbox_remote.addStretch(1) - # tabs - tabs = QTabWidget() - tabs.addTab(local_w, _('Local')) - tabs.addTab(remote_w, _('Remote')) - vbox = QVBoxLayout(self) - vbox.addWidget(tabs) - b = QPushButton(_('Close')) - b.clicked.connect(self.on_close) - vbox.addLayout(Buttons(b)) - self.channel_list.update() - - def on_close(self): - url = self.watchtower_e.text() - if url: - self.lnwatcher.set_remote_watchtower() - self.hide() - - def is_hidden(self): - return self.isMinimized() or self.isHidden() - - def show_or_hide(self): - if self.is_hidden(): - self.bring_to_top() - else: - self.hide() - - def bring_to_top(self): - self.show() - self.raise_() - - def closeEvent(self, event): - self.gui_object.watchtower_window = None - event.accept()