commit af4a3328f78ccc0d50efa3f6fa88facb328ef436
parent f985c53f2f1f1453b687bc4c482a4062a71526ce
Author: ThomasV <thomasv@electrum.org>
Date: Sat, 12 Oct 2019 14:30:52 +0200
Qt: separate lightning and watchtower dialogs
Diffstat:
4 files changed, 113 insertions(+), 45 deletions(-)
diff --git a/electrum/gui/qt/__init__.py b/electrum/gui/qt/__init__.py
@@ -56,6 +56,7 @@ from .main_window import ElectrumWindow
from .network_dialog import NetworkDialog
from .stylesheet_patcher import patch_qt_stylesheet
from .lightning_dialog import LightningDialog
+from .watchtower_dialog import WatchtowerDialog
if TYPE_CHECKING:
from electrum.daemon import Daemon
@@ -115,6 +116,7 @@ class ElectrumGui(Logger):
self.network_dialog = None
self.lightning_dialog = None
+ self.watchtower_dialog = None
self.network_updated_signal_obj = QNetworkUpdatedSignalObject()
self._num_wizards_in_progress = 0
self._num_wizards_lock = threading.Lock()
@@ -155,6 +157,7 @@ class ElectrumGui(Logger):
m.clear()
if self.config.get('lightning'):
m.addAction(_("Lightning"), self.show_lightning_dialog)
+ m.addAction(_("Watchtower"), self.show_watchtower_dialog)
for window in self.windows:
name = window.wallet.basename()
submenu = m.addMenu(name)
@@ -191,6 +194,8 @@ class ElectrumGui(Logger):
self.network_dialog.close()
if self.lightning_dialog:
self.lightning_dialog.close()
+ if self.watchtower_dialog:
+ self.watchtower_dialog.close()
def new_window(self, path, uri=None):
# Use a signal as can be called from daemon thread
@@ -201,6 +206,11 @@ class ElectrumGui(Logger):
self.lightning_dialog = LightningDialog(self)
self.lightning_dialog.bring_to_top()
+ def show_watchtower_dialog(self):
+ if not self.watchtower_dialog:
+ self.watchtower_dialog = WatchtowerDialog(self)
+ self.watchtower_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'))
diff --git a/electrum/gui/qt/lightning_dialog.py b/electrum/gui/qt/lightning_dialog.py
@@ -32,28 +32,6 @@ from electrum.i18n import _
from .util import HelpLabel, MyTreeView, Buttons
-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')})
- lnwatcher = self.parent.lnwatcher
- l = lnwatcher.list_sweep_tx()
- for outpoint in l:
- n = lnwatcher.get_num_tx(outpoint)
- status = 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):
@@ -63,37 +41,23 @@ class LightningDialog(QDialog):
self.gui_object = gui_object
self.config = gui_object.config
self.network = gui_object.daemon.network
- self.lnwatcher = self.network.local_watchtower
- self.setWindowTitle(_('Lightning'))
+ self.setWindowTitle(_('Lightning Network'))
self.setMinimumSize(600, 20)
- self.watcher_list = WatcherList(self)
- # channel_db
- network_w = QWidget()
- network_vbox = QVBoxLayout(network_w)
+
+ vbox = QVBoxLayout(self)
self.num_peers = QLabel('')
- network_vbox.addWidget(self.num_peers)
+ vbox.addWidget(self.num_peers)
self.num_nodes = QLabel('')
- network_vbox.addWidget(self.num_nodes)
+ vbox.addWidget(self.num_nodes)
self.num_channels = QLabel('')
- network_vbox.addWidget(self.num_channels)
+ vbox.addWidget(self.num_channels)
self.status = QLabel('')
- network_vbox.addWidget(self.status)
- network_vbox.addStretch(1)
- # watchtower
- watcher_w = QWidget()
- watcher_vbox = QVBoxLayout(watcher_w)
- watcher_vbox.addWidget(self.watcher_list)
+ vbox.addWidget(self.status)
+ vbox.addStretch(1)
- # tabs
- tabs = QTabWidget()
- tabs.addTab(network_w, _('Network'))
- tabs.addTab(watcher_w, _('Watchtower'))
- vbox = QVBoxLayout(self)
- vbox.addWidget(tabs)
b = QPushButton(_('Close'))
b.clicked.connect(self.close)
vbox.addLayout(Buttons(b))
- self.watcher_list.update()
self.network.register_callback(self.update_status, ['ln_status'])
def update_status(self, event, num_peers, num_nodes, known, unknown):
@@ -116,5 +80,5 @@ class LightningDialog(QDialog):
self.raise_()
def closeEvent(self, event):
- self.gui_object.watchtower_window = None
+ self.gui_object.lightning_dialog = None
event.accept()
diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py
@@ -635,6 +635,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
tools_menu.addAction(_("&Network"), lambda: self.gui_object.show_network_dialog(self))
if self.config.get('lightning'):
tools_menu.addAction(_("&Lightning"), self.gui_object.show_lightning_dialog)
+ tools_menu.addAction(_("&Watchtower"), self.gui_object.show_watchtower_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_dialog.py b/electrum/gui/qt/watchtower_dialog.py
@@ -0,0 +1,93 @@
+#!/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.
+
+from PyQt5.QtGui import QStandardItemModel, QStandardItem
+from PyQt5.QtCore import Qt
+from PyQt5.QtWidgets import (QDialog, QWidget, QLabel, QVBoxLayout, QCheckBox,
+ QGridLayout, QPushButton, QLineEdit, QTabWidget)
+
+from electrum.i18n import _
+from .util import HelpLabel, MyTreeView, Buttons
+
+
+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')})
+ lnwatcher = self.parent.lnwatcher
+ l = lnwatcher.list_sweep_tx()
+ for outpoint in l:
+ n = lnwatcher.get_num_tx(outpoint)
+ status = lnwatcher.get_channel_status(outpoint)
+ items = [QStandardItem(e) for e in [outpoint, "%d"%n, status]]
+ self.model().insertRow(self.model().rowCount(), items)
+
+
+class WatchtowerDialog(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.local_watchtower
+ self.setWindowTitle(_('Watchtower'))
+ self.setMinimumSize(600, 20)
+ self.watcher_list = WatcherList(self)
+
+ vbox = QVBoxLayout(self)
+ vbox.addWidget(self.watcher_list)
+ b = QPushButton(_('Close'))
+ b.clicked.connect(self.close)
+ vbox.addLayout(Buttons(b))
+ self.watcher_list.update()
+
+ 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_dialog = None
+ event.accept()