aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHennadii Stepanov <32963518+hebasto@users.noreply.github.com>2021-02-22 09:57:06 +0200
committerHennadii Stepanov <32963518+hebasto@users.noreply.github.com>2021-06-07 17:37:40 +0300
commitecbd91153875c8cdd5b92b840afc116f65e457fb (patch)
treeb1d388631085d86928d58634b673a1ba0ff101ee
parent1b66f6e556631a1a2d89aefba70a79894bd14fcd (diff)
downloadbitcoin-ecbd91153875c8cdd5b92b840afc116f65e457fb.tar.xz
qt: Handle peer addition/removal in a right way
This change fixes a bug when a multiple rows selection gets inconsistent after a peer addition/removal.
-rw-r--r--src/qt/peertablemodel.cpp29
-rw-r--r--src/qt/peertablemodel.h3
-rw-r--r--src/qt/rpcconsole.cpp2
3 files changed, 30 insertions, 4 deletions
diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp
index fe03365d76..ba96837c15 100644
--- a/src/qt/peertablemodel.cpp
+++ b/src/qt/peertablemodel.cpp
@@ -153,7 +153,30 @@ void PeerTableModel::refresh()
new_peers_data.append(stats);
}
- Q_EMIT layoutAboutToBeChanged();
- m_peers_data.swap(new_peers_data);
- Q_EMIT layoutChanged();
+ // Handle peer addition or removal as suggested in Qt Docs. See:
+ // - https://doc.qt.io/qt-5/model-view-programming.html#inserting-and-removing-rows
+ // - https://doc.qt.io/qt-5/model-view-programming.html#resizable-models
+ // We take advantage of the fact that the std::vector returned
+ // by interfaces::Node::getNodesStats is sorted by nodeid.
+ for (int i = 0; i < m_peers_data.size();) {
+ if (i < new_peers_data.size() && m_peers_data.at(i).nodeStats.nodeid == new_peers_data.at(i).nodeStats.nodeid) {
+ ++i;
+ continue;
+ }
+ // A peer has been removed from the table.
+ beginRemoveRows(QModelIndex(), i, i);
+ m_peers_data.erase(m_peers_data.begin() + i);
+ endRemoveRows();
+ }
+
+ if (m_peers_data.size() < new_peers_data.size()) {
+ // Some peers have been added to the end of the table.
+ beginInsertRows(QModelIndex(), m_peers_data.size(), new_peers_data.size() - 1);
+ m_peers_data.swap(new_peers_data);
+ endInsertRows();
+ } else {
+ m_peers_data.swap(new_peers_data);
+ }
+
+ Q_EMIT changed();
}
diff --git a/src/qt/peertablemodel.h b/src/qt/peertablemodel.h
index 0d841ebf28..0ff1b5dba7 100644
--- a/src/qt/peertablemodel.h
+++ b/src/qt/peertablemodel.h
@@ -73,6 +73,9 @@ public:
public Q_SLOTS:
void refresh();
+Q_SIGNALS:
+ void changed();
+
private:
//! Internal peer data structure.
QList<CNodeCombinedStats> m_peers_data{};
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 0801455633..f9c2bea437 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -656,7 +656,7 @@ void RPCConsole::setClientModel(ClientModel *model, int bestblock_height, int64_
// peer table signal handling - update peer details when selecting new node
connect(ui->peerWidget->selectionModel(), &QItemSelectionModel::selectionChanged, this, &RPCConsole::updateDetailWidget);
- connect(model->getPeerTableModel(), &PeerTableModel::layoutChanged, this, &RPCConsole::updateDetailWidget);
+ connect(model->getPeerTableModel(), &PeerTableModel::changed, this, &RPCConsole::updateDetailWidget);
// set up ban table
ui->banlistWidget->setModel(model->getBanTableModel());