| 150 | } |
| 151 | |
| 152 | void PeerTableModel::refresh() |
| 153 | { |
| 154 | interfaces::Node::NodesStats nodes_stats; |
| 155 | m_node.getNodesStats(nodes_stats); |
| 156 | decltype(m_peers_data) new_peers_data; |
| 157 | new_peers_data.reserve(nodes_stats.size()); |
| 158 | for (const auto& node_stats : nodes_stats) { |
| 159 | const CNodeCombinedStats stats{std::get<0>(node_stats), std::get<2>(node_stats), std::get<1>(node_stats)}; |
| 160 | new_peers_data.append(stats); |
| 161 | } |
| 162 | |
| 163 | // Handle peer addition or removal as suggested in Qt Docs. See: |
| 164 | // - https://doc.qt.io/qt-5/model-view-programming.html#inserting-and-removing-rows |
| 165 | // - https://doc.qt.io/qt-5/model-view-programming.html#resizable-models |
| 166 | // We take advantage of the fact that the std::vector returned |
| 167 | // by interfaces::Node::getNodesStats is sorted by nodeid. |
| 168 | for (int i = 0; i < m_peers_data.size();) { |
| 169 | if (i < new_peers_data.size() && m_peers_data.at(i).nodeStats.nodeid == new_peers_data.at(i).nodeStats.nodeid) { |
| 170 | ++i; |
| 171 | continue; |
| 172 | } |
| 173 | // A peer has been removed from the table. |
| 174 | beginRemoveRows(QModelIndex(), i, i); |
| 175 | m_peers_data.erase(m_peers_data.begin() + i); |
| 176 | endRemoveRows(); |
| 177 | } |
| 178 | |
| 179 | if (m_peers_data.size() < new_peers_data.size()) { |
| 180 | // Some peers have been added to the end of the table. |
| 181 | beginInsertRows(QModelIndex(), m_peers_data.size(), new_peers_data.size() - 1); |
| 182 | m_peers_data.swap(new_peers_data); |
| 183 | endInsertRows(); |
| 184 | } else { |
| 185 | m_peers_data.swap(new_peers_data); |
| 186 | } |
| 187 | |
| 188 | const auto top_left = index(0, 0); |
| 189 | const auto bottom_right = index(rowCount() - 1, columnCount() - 1); |
| 190 | Q_EMIT dataChanged(top_left, bottom_right); |
| 191 | } |
nothing calls this directly
no test coverage detected