mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-09-01 09:45:18 +00:00
qt network dialog: merge "Overview" and "Servers" tabs
This commit is contained in:
parent
bf223470ce
commit
58dee38ed2
1 changed files with 79 additions and 121 deletions
|
@ -56,7 +56,7 @@ class NetworkDialog(QDialog):
|
||||||
def __init__(self, network, config, network_updated_signal_obj):
|
def __init__(self, network, config, network_updated_signal_obj):
|
||||||
QDialog.__init__(self)
|
QDialog.__init__(self)
|
||||||
self.setWindowTitle(_('Network'))
|
self.setWindowTitle(_('Network'))
|
||||||
self.setMinimumSize(500, 300)
|
self.setMinimumSize(500, 500)
|
||||||
self.nlayout = NetworkChoiceLayout(network, config)
|
self.nlayout = NetworkChoiceLayout(network, config)
|
||||||
self.network_updated_signal_obj = network_updated_signal_obj
|
self.network_updated_signal_obj = network_updated_signal_obj
|
||||||
vbox = QVBoxLayout(self)
|
vbox = QVBoxLayout(self)
|
||||||
|
@ -79,12 +79,18 @@ class NodesListWidget(QTreeWidget):
|
||||||
|
|
||||||
SERVER_ADDR_ROLE = Qt.UserRole + 100
|
SERVER_ADDR_ROLE = Qt.UserRole + 100
|
||||||
CHAIN_ID_ROLE = Qt.UserRole + 101
|
CHAIN_ID_ROLE = Qt.UserRole + 101
|
||||||
IS_SERVER_ROLE = Qt.UserRole + 102
|
ITEMTYPE_ROLE = Qt.UserRole + 102
|
||||||
|
|
||||||
|
class ItemType(IntEnum):
|
||||||
|
CHAIN = 0
|
||||||
|
CONNECTED_SERVER = 1
|
||||||
|
DISCONNECTED_SERVER = 2
|
||||||
|
TOPLEVEL = 3
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
QTreeWidget.__init__(self)
|
QTreeWidget.__init__(self)
|
||||||
self.parent = parent # type: NetworkChoiceLayout
|
self.parent = parent # type: NetworkChoiceLayout
|
||||||
self.setHeaderLabels([_('Connected node'), _('Height')])
|
self.setHeaderLabels([_('Server'), _('Height')])
|
||||||
self.setContextMenuPolicy(Qt.CustomContextMenu)
|
self.setContextMenuPolicy(Qt.CustomContextMenu)
|
||||||
self.customContextMenuRequested.connect(self.create_menu)
|
self.customContextMenuRequested.connect(self.create_menu)
|
||||||
|
|
||||||
|
@ -92,14 +98,22 @@ class NodesListWidget(QTreeWidget):
|
||||||
item = self.currentItem()
|
item = self.currentItem()
|
||||||
if not item:
|
if not item:
|
||||||
return
|
return
|
||||||
is_server = bool(item.data(0, self.IS_SERVER_ROLE))
|
item_type = item.data(0, self.ITEMTYPE_ROLE)
|
||||||
menu = QMenu()
|
menu = QMenu()
|
||||||
if is_server:
|
if item_type == self.ItemType.CONNECTED_SERVER:
|
||||||
server = item.data(0, self.SERVER_ADDR_ROLE) # type: ServerAddr
|
server = item.data(0, self.SERVER_ADDR_ROLE) # type: ServerAddr
|
||||||
menu.addAction(_("Use as server"), lambda: self.parent.follow_server(server))
|
menu.addAction(_("Use as server"), lambda: self.parent.follow_server(server))
|
||||||
else:
|
elif item_type == self.ItemType.DISCONNECTED_SERVER:
|
||||||
|
server = item.data(0, self.SERVER_ADDR_ROLE) # type: ServerAddr
|
||||||
|
def func():
|
||||||
|
self.parent.server_e.setText(server.net_addr_str())
|
||||||
|
self.parent.set_server()
|
||||||
|
menu.addAction(_("Use as server"), func)
|
||||||
|
elif item_type == self.ItemType.CHAIN:
|
||||||
chain_id = item.data(0, self.CHAIN_ID_ROLE)
|
chain_id = item.data(0, self.CHAIN_ID_ROLE)
|
||||||
menu.addAction(_("Follow this branch"), lambda: self.parent.follow_branch(chain_id))
|
menu.addAction(_("Follow this branch"), lambda: self.parent.follow_branch(chain_id))
|
||||||
|
else:
|
||||||
|
return
|
||||||
menu.exec_(self.viewport().mapToGlobal(position))
|
menu.exec_(self.viewport().mapToGlobal(position))
|
||||||
|
|
||||||
def keyPressEvent(self, event):
|
def keyPressEvent(self, event):
|
||||||
|
@ -114,9 +128,12 @@ class NodesListWidget(QTreeWidget):
|
||||||
pt.setX(50)
|
pt.setX(50)
|
||||||
self.customContextMenuRequested.emit(pt)
|
self.customContextMenuRequested.emit(pt)
|
||||||
|
|
||||||
def update(self, network: Network):
|
def update(self, *, network: Network, servers: dict, use_tor: bool):
|
||||||
self.clear()
|
self.clear()
|
||||||
self.addChild = self.addTopLevelItem
|
|
||||||
|
# connected servers
|
||||||
|
connected_servers_item = QTreeWidgetItem([_("Connected nodes"), ''])
|
||||||
|
connected_servers_item.setData(0, self.ITEMTYPE_ROLE, self.ItemType.TOPLEVEL)
|
||||||
chains = network.get_blockchains()
|
chains = network.get_blockchains()
|
||||||
n_chains = len(chains)
|
n_chains = len(chains)
|
||||||
for chain_id, interfaces in chains.items():
|
for chain_id, interfaces in chains.items():
|
||||||
|
@ -125,87 +142,51 @@ class NodesListWidget(QTreeWidget):
|
||||||
name = b.get_name()
|
name = b.get_name()
|
||||||
if n_chains > 1:
|
if n_chains > 1:
|
||||||
x = QTreeWidgetItem([name + '@%d'%b.get_max_forkpoint(), '%d'%b.height()])
|
x = QTreeWidgetItem([name + '@%d'%b.get_max_forkpoint(), '%d'%b.height()])
|
||||||
x.setData(0, self.IS_SERVER_ROLE, 0)
|
x.setData(0, self.ITEMTYPE_ROLE, self.ItemType.CHAIN)
|
||||||
x.setData(0, self.CHAIN_ID_ROLE, b.get_id())
|
x.setData(0, self.CHAIN_ID_ROLE, b.get_id())
|
||||||
else:
|
else:
|
||||||
x = self
|
x = connected_servers_item
|
||||||
for i in interfaces:
|
for i in interfaces:
|
||||||
star = ' *' if i == network.interface else ''
|
star = ' *' if i == network.interface else ''
|
||||||
item = QTreeWidgetItem([i.host + star, '%d'%i.tip])
|
item = QTreeWidgetItem([f"{i.server.net_addr_str()}" + star, '%d'%i.tip])
|
||||||
item.setData(0, self.IS_SERVER_ROLE, 1)
|
item.setData(0, self.ITEMTYPE_ROLE, self.ItemType.CONNECTED_SERVER)
|
||||||
item.setData(0, self.SERVER_ADDR_ROLE, i.server)
|
item.setData(0, self.SERVER_ADDR_ROLE, i.server)
|
||||||
item.setToolTip(0, str(i.server))
|
item.setToolTip(0, str(i.server))
|
||||||
x.addChild(item)
|
x.addChild(item)
|
||||||
if n_chains > 1:
|
if n_chains > 1:
|
||||||
self.addTopLevelItem(x)
|
connected_servers_item.addChild(x)
|
||||||
x.setExpanded(True)
|
|
||||||
|
|
||||||
h = self.header()
|
# disconnected servers
|
||||||
h.setStretchLastSection(False)
|
disconnected_servers_item = QTreeWidgetItem([_("Other known servers"), ""])
|
||||||
h.setSectionResizeMode(0, QHeaderView.Stretch)
|
disconnected_servers_item.setData(0, self.ITEMTYPE_ROLE, self.ItemType.TOPLEVEL)
|
||||||
h.setSectionResizeMode(1, QHeaderView.ResizeToContents)
|
connected_hosts = set([iface.host for ifaces in chains.values() for iface in ifaces])
|
||||||
|
|
||||||
super().update()
|
|
||||||
|
|
||||||
|
|
||||||
class ServerListWidget(QTreeWidget):
|
|
||||||
"""List of all known servers."""
|
|
||||||
|
|
||||||
class Columns(IntEnum):
|
|
||||||
HOST = 0
|
|
||||||
PORT = 1
|
|
||||||
|
|
||||||
SERVER_ADDR_ROLE = Qt.UserRole + 100
|
|
||||||
|
|
||||||
def __init__(self, parent):
|
|
||||||
QTreeWidget.__init__(self)
|
|
||||||
self.parent = parent # type: NetworkChoiceLayout
|
|
||||||
self.setHeaderLabels([_('Host'), _('Port')])
|
|
||||||
self.setContextMenuPolicy(Qt.CustomContextMenu)
|
|
||||||
self.customContextMenuRequested.connect(self.create_menu)
|
|
||||||
|
|
||||||
def create_menu(self, position):
|
|
||||||
item = self.currentItem()
|
|
||||||
if not item:
|
|
||||||
return
|
|
||||||
menu = QMenu()
|
|
||||||
server = item.data(self.Columns.HOST, self.SERVER_ADDR_ROLE)
|
|
||||||
menu.addAction(_("Use as server"), lambda: self.set_server(server))
|
|
||||||
menu.exec_(self.viewport().mapToGlobal(position))
|
|
||||||
|
|
||||||
def set_server(self, server: ServerAddr):
|
|
||||||
self.parent.server_e.setText(server.net_addr_str())
|
|
||||||
self.parent.set_server()
|
|
||||||
|
|
||||||
def keyPressEvent(self, event):
|
|
||||||
if event.key() in [ Qt.Key_F2, Qt.Key_Return ]:
|
|
||||||
self.on_activated(self.currentItem(), self.currentColumn())
|
|
||||||
else:
|
|
||||||
QTreeWidget.keyPressEvent(self, event)
|
|
||||||
|
|
||||||
def on_activated(self, item, column):
|
|
||||||
# on 'enter' we show the menu
|
|
||||||
pt = self.visualItemRect(item).bottomLeft()
|
|
||||||
pt.setX(50)
|
|
||||||
self.customContextMenuRequested.emit(pt)
|
|
||||||
|
|
||||||
def update(self, servers, use_tor):
|
|
||||||
self.clear()
|
|
||||||
protocol = PREFERRED_NETWORK_PROTOCOL
|
protocol = PREFERRED_NETWORK_PROTOCOL
|
||||||
for _host, d in sorted(servers.items()):
|
for _host, d in sorted(servers.items()):
|
||||||
|
if _host in connected_hosts:
|
||||||
|
continue
|
||||||
if _host.endswith('.onion') and not use_tor:
|
if _host.endswith('.onion') and not use_tor:
|
||||||
continue
|
continue
|
||||||
port = d.get(protocol)
|
port = d.get(protocol)
|
||||||
if port:
|
if port:
|
||||||
x = QTreeWidgetItem([_host, port])
|
|
||||||
server = ServerAddr(_host, port, protocol=protocol)
|
server = ServerAddr(_host, port, protocol=protocol)
|
||||||
x.setData(self.Columns.HOST, self.SERVER_ADDR_ROLE, server)
|
item = QTreeWidgetItem([server.net_addr_str(), ""])
|
||||||
self.addTopLevelItem(x)
|
item.setData(0, self.ITEMTYPE_ROLE, self.ItemType.DISCONNECTED_SERVER)
|
||||||
|
item.setData(0, self.SERVER_ADDR_ROLE, server)
|
||||||
|
disconnected_servers_item.addChild(item)
|
||||||
|
|
||||||
|
self.addTopLevelItem(connected_servers_item)
|
||||||
|
self.addTopLevelItem(disconnected_servers_item)
|
||||||
|
|
||||||
|
connected_servers_item.setExpanded(True)
|
||||||
|
for i in range(connected_servers_item.childCount()):
|
||||||
|
connected_servers_item.child(i).setExpanded(True)
|
||||||
|
disconnected_servers_item.setExpanded(True)
|
||||||
|
|
||||||
|
# headers
|
||||||
h = self.header()
|
h = self.header()
|
||||||
h.setStretchLastSection(False)
|
h.setStretchLastSection(False)
|
||||||
h.setSectionResizeMode(self.Columns.HOST, QHeaderView.Stretch)
|
h.setSectionResizeMode(0, QHeaderView.Stretch)
|
||||||
h.setSectionResizeMode(self.Columns.PORT, QHeaderView.ResizeToContents)
|
h.setSectionResizeMode(1, QHeaderView.ResizeToContents)
|
||||||
|
|
||||||
super().update()
|
super().update()
|
||||||
|
|
||||||
|
@ -218,44 +199,14 @@ class NetworkChoiceLayout(object):
|
||||||
self.tor_proxy = None
|
self.tor_proxy = None
|
||||||
|
|
||||||
self.tabs = tabs = QTabWidget()
|
self.tabs = tabs = QTabWidget()
|
||||||
server_tab = QWidget()
|
|
||||||
proxy_tab = QWidget()
|
proxy_tab = QWidget()
|
||||||
blockchain_tab = QWidget()
|
blockchain_tab = QWidget()
|
||||||
tabs.addTab(blockchain_tab, _('Overview'))
|
tabs.addTab(blockchain_tab, _('Overview'))
|
||||||
tabs.addTab(server_tab, _('Server'))
|
|
||||||
tabs.addTab(proxy_tab, _('Proxy'))
|
tabs.addTab(proxy_tab, _('Proxy'))
|
||||||
|
|
||||||
fixed_width_hostname = 24 * char_width_in_lineedit()
|
fixed_width_hostname = 24 * char_width_in_lineedit()
|
||||||
fixed_width_port = 6 * char_width_in_lineedit()
|
fixed_width_port = 6 * char_width_in_lineedit()
|
||||||
|
|
||||||
# server tab
|
|
||||||
grid = QGridLayout(server_tab)
|
|
||||||
grid.setSpacing(8)
|
|
||||||
|
|
||||||
self.server_e = QLineEdit()
|
|
||||||
self.server_e.setFixedWidth(fixed_width_hostname + fixed_width_port)
|
|
||||||
self.autoconnect_cb = QCheckBox(_('Select server automatically'))
|
|
||||||
self.autoconnect_cb.setEnabled(self.config.is_modifiable('auto_connect'))
|
|
||||||
|
|
||||||
self.server_e.editingFinished.connect(self.set_server)
|
|
||||||
self.autoconnect_cb.clicked.connect(self.set_server)
|
|
||||||
self.autoconnect_cb.clicked.connect(self.update)
|
|
||||||
|
|
||||||
msg = ' '.join([
|
|
||||||
_("If auto-connect is enabled, Electrum will always use a server that is on the longest blockchain."),
|
|
||||||
_("If it is disabled, you have to choose a server you want to use. Electrum will warn you if your server is lagging.")
|
|
||||||
])
|
|
||||||
grid.addWidget(self.autoconnect_cb, 0, 0, 1, 3)
|
|
||||||
grid.addWidget(HelpButton(msg), 0, 4)
|
|
||||||
|
|
||||||
grid.addWidget(QLabel(_('Server') + ':'), 1, 0)
|
|
||||||
grid.addWidget(self.server_e, 1, 1, 1, 3)
|
|
||||||
|
|
||||||
label = _('Server peers') if network.is_connected() else _('Default Servers')
|
|
||||||
grid.addWidget(QLabel(label), 2, 0, 1, 5)
|
|
||||||
self.servers_list = ServerListWidget(self)
|
|
||||||
grid.addWidget(self.servers_list, 3, 0, 1, 5)
|
|
||||||
|
|
||||||
# Proxy tab
|
# Proxy tab
|
||||||
grid = QGridLayout(proxy_tab)
|
grid = QGridLayout(proxy_tab)
|
||||||
grid.setSpacing(8)
|
grid.setSpacing(8)
|
||||||
|
@ -315,23 +266,36 @@ class NetworkChoiceLayout(object):
|
||||||
grid.addWidget(self.status_label, 0, 1, 1, 3)
|
grid.addWidget(self.status_label, 0, 1, 1, 3)
|
||||||
grid.addWidget(HelpButton(msg), 0, 4)
|
grid.addWidget(HelpButton(msg), 0, 4)
|
||||||
|
|
||||||
self.server_label = QLabel('')
|
self.autoconnect_cb = QCheckBox(_('Select server automatically'))
|
||||||
msg = _("Electrum sends your wallet addresses to a single server, in order to receive your transaction history.")
|
self.autoconnect_cb.setEnabled(self.config.is_modifiable('auto_connect'))
|
||||||
grid.addWidget(QLabel(_('Server') + ':'), 1, 0)
|
self.autoconnect_cb.clicked.connect(self.set_server)
|
||||||
grid.addWidget(self.server_label, 1, 1, 1, 3)
|
self.autoconnect_cb.clicked.connect(self.update)
|
||||||
|
msg = ' '.join([
|
||||||
|
_("If auto-connect is enabled, Electrum will always use a server that is on the longest blockchain."),
|
||||||
|
_("If it is disabled, you have to choose a server you want to use. Electrum will warn you if your server is lagging.")
|
||||||
|
])
|
||||||
|
grid.addWidget(self.autoconnect_cb, 1, 0, 1, 3)
|
||||||
grid.addWidget(HelpButton(msg), 1, 4)
|
grid.addWidget(HelpButton(msg), 1, 4)
|
||||||
|
|
||||||
|
self.server_e = QLineEdit()
|
||||||
|
self.server_e.setFixedWidth(fixed_width_hostname + fixed_width_port)
|
||||||
|
self.server_e.editingFinished.connect(self.set_server)
|
||||||
|
msg = _("Electrum sends your wallet addresses to a single server, in order to receive your transaction history.")
|
||||||
|
grid.addWidget(QLabel(_('Server') + ':'), 2, 0)
|
||||||
|
grid.addWidget(self.server_e, 2, 1, 1, 3)
|
||||||
|
grid.addWidget(HelpButton(msg), 2, 4)
|
||||||
|
|
||||||
self.height_label = QLabel('')
|
self.height_label = QLabel('')
|
||||||
msg = _('This is the height of your local copy of the blockchain.')
|
msg = _('This is the height of your local copy of the blockchain.')
|
||||||
grid.addWidget(QLabel(_('Blockchain') + ':'), 2, 0)
|
grid.addWidget(QLabel(_('Blockchain') + ':'), 3, 0)
|
||||||
grid.addWidget(self.height_label, 2, 1)
|
grid.addWidget(self.height_label, 3, 1)
|
||||||
grid.addWidget(HelpButton(msg), 2, 4)
|
grid.addWidget(HelpButton(msg), 3, 4)
|
||||||
|
|
||||||
self.split_label = QLabel('')
|
self.split_label = QLabel('')
|
||||||
grid.addWidget(self.split_label, 3, 0, 1, 3)
|
grid.addWidget(self.split_label, 4, 0, 1, 3)
|
||||||
|
|
||||||
self.nodes_list_widget = NodesListWidget(self)
|
self.nodes_list_widget = NodesListWidget(self)
|
||||||
grid.addWidget(self.nodes_list_widget, 5, 0, 1, 5)
|
grid.addWidget(self.nodes_list_widget, 6, 0, 1, 5)
|
||||||
|
|
||||||
vbox = QVBoxLayout()
|
vbox = QVBoxLayout()
|
||||||
vbox.addWidget(tabs)
|
vbox.addWidget(tabs)
|
||||||
|
@ -354,27 +318,18 @@ class NetworkChoiceLayout(object):
|
||||||
if self.config.is_modifiable('server'):
|
if self.config.is_modifiable('server'):
|
||||||
enabled = not self.autoconnect_cb.isChecked()
|
enabled = not self.autoconnect_cb.isChecked()
|
||||||
self.server_e.setEnabled(enabled)
|
self.server_e.setEnabled(enabled)
|
||||||
self.servers_list.setEnabled(enabled)
|
|
||||||
else:
|
else:
|
||||||
for w in [self.autoconnect_cb, self.server_e, self.servers_list]:
|
for w in [self.autoconnect_cb, self.server_e, self.nodes_list_widget]:
|
||||||
w.setEnabled(False)
|
w.setEnabled(False)
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
net_params = self.network.get_parameters()
|
net_params = self.network.get_parameters()
|
||||||
server = net_params.server
|
server = net_params.server
|
||||||
proxy_config, auto_connect = net_params.proxy, net_params.auto_connect
|
auto_connect = net_params.auto_connect
|
||||||
if not self.server_e.hasFocus():
|
if not self.server_e.hasFocus():
|
||||||
self.server_e.setText(server.net_addr_str())
|
self.server_e.setText(server.net_addr_str())
|
||||||
self.autoconnect_cb.setChecked(auto_connect)
|
self.autoconnect_cb.setChecked(auto_connect)
|
||||||
|
|
||||||
interface = self.network.interface
|
|
||||||
host = interface.host if interface else _('None')
|
|
||||||
self.server_label.setText(host)
|
|
||||||
|
|
||||||
self.servers = self.network.get_servers()
|
|
||||||
self.servers_list.update(self.servers, self.tor_cb.isChecked())
|
|
||||||
self.enable_set_server()
|
|
||||||
|
|
||||||
height_str = "%d "%(self.network.get_local_height()) + _('blocks')
|
height_str = "%d "%(self.network.get_local_height()) + _('blocks')
|
||||||
self.height_label.setText(height_str)
|
self.height_label.setText(height_str)
|
||||||
n = len(self.network.get_interfaces())
|
n = len(self.network.get_interfaces())
|
||||||
|
@ -391,7 +346,10 @@ class NetworkChoiceLayout(object):
|
||||||
else:
|
else:
|
||||||
msg = ''
|
msg = ''
|
||||||
self.split_label.setText(msg)
|
self.split_label.setText(msg)
|
||||||
self.nodes_list_widget.update(self.network)
|
self.nodes_list_widget.update(network=self.network,
|
||||||
|
servers=self.network.get_servers(),
|
||||||
|
use_tor=self.tor_cb.isChecked())
|
||||||
|
self.enable_set_server()
|
||||||
|
|
||||||
def fill_in_proxy_settings(self):
|
def fill_in_proxy_settings(self):
|
||||||
proxy_config = self.network.get_parameters().proxy
|
proxy_config = self.network.get_parameters().proxy
|
||||||
|
|
Loading…
Add table
Reference in a new issue