Skip to content

Commit 734dd5f

Browse files
committed
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.
1 parent f0a8406 commit 734dd5f

File tree

3 files changed

+30
-4
lines changed

3 files changed

+30
-4
lines changed

src/qt/peertablemodel.cpp

+26-3
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,30 @@ void PeerTableModel::refresh()
155155
new_peers_data.append(stats);
156156
}
157157

158-
Q_EMIT layoutAboutToBeChanged();
159-
m_peers_data.swap(new_peers_data);
160-
Q_EMIT layoutChanged();
158+
// Handle a new peer addition or an old peer in a right way. See:
159+
// - https://doc.qt.io/qt-5/model-view-programming.html#inserting-and-removing-rows
160+
// - https://doc.qt.io/qt-5/model-view-programming.html#resizable-models
161+
// We use the fact that interfaces::Node::getNodesStats
162+
// returns std::vector naturally sorted by nodeid.
163+
for (int i = 0; i < m_peers_data.size(); ) {
164+
if (i < new_peers_data.size() && m_peers_data.at(i).nodeStats.nodeid == new_peers_data.at(i).nodeStats.nodeid) {
165+
++i;
166+
continue;
167+
}
168+
// A peer has been removed from the table.
169+
beginRemoveRows(QModelIndex(), i, i);
170+
m_peers_data.erase(m_peers_data.begin() + i);
171+
endRemoveRows();
172+
}
173+
174+
if (m_peers_data.size() < new_peers_data.size()) {
175+
// Some peers have been added to the end of the table.
176+
beginInsertRows(QModelIndex(), m_peers_data.size(), new_peers_data.size() - 1);
177+
m_peers_data.swap(new_peers_data);
178+
endInsertRows();
179+
} else {
180+
m_peers_data.swap(new_peers_data);
181+
}
182+
183+
Q_EMIT changed();
161184
}

src/qt/peertablemodel.h

+3
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ class PeerTableModel : public QAbstractTableModel
7272
public Q_SLOTS:
7373
void refresh();
7474

75+
Q_SIGNALS:
76+
void changed();
77+
7578
private:
7679
//! Internal peer data structure.
7780
QList<CNodeCombinedStats> m_peers_data{};

src/qt/rpcconsole.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ void RPCConsole::setClientModel(ClientModel *model, int bestblock_height, int64_
623623

624624
// peer table signal handling - update peer details when selecting new node
625625
connect(ui->peerWidget->selectionModel(), &QItemSelectionModel::selectionChanged, this, &RPCConsole::updateDetailWidget);
626-
connect(model->getPeerTableModel(), &PeerTableModel::layoutChanged, this, &RPCConsole::updateDetailWidget);
626+
connect(model->getPeerTableModel(), &PeerTableModel::changed, this, &RPCConsole::updateDetailWidget);
627627

628628
// set up ban table
629629
ui->banlistWidget->setModel(model->getBanTableModel());

0 commit comments

Comments
 (0)