aboutsummaryrefslogtreecommitdiff
path: root/src/qt/peertablemodel.cpp
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 /src/qt/peertablemodel.cpp
parent1b66f6e556631a1a2d89aefba70a79894bd14fcd (diff)
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.
Diffstat (limited to 'src/qt/peertablemodel.cpp')
-rw-r--r--src/qt/peertablemodel.cpp29
1 files changed, 26 insertions, 3 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();
}