Skip to content

Commit ecbd911

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 1b66f6e commit ecbd911

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
@@ -153,7 +153,30 @@ void PeerTableModel::refresh()
153153
new_peers_data.append(stats);
154154
}
155155

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

src/qt/peertablemodel.h

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

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

src/qt/rpcconsole.cpp

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

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

661661
// set up ban table
662662
ui->banlistWidget->setModel(model->getBanTableModel());

0 commit comments

Comments
 (0)