Bitcoin Core 22.99.0
P2P Digital Currency
bantablemodel.cpp
Go to the documentation of this file.
1// Copyright (c) 2011-2020 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <qt/bantablemodel.h>
6
7#include <interfaces/node.h>
8#include <net_types.h> // For banmap_t
9
10#include <utility>
11
12#include <QDateTime>
13#include <QList>
14#include <QLocale>
15#include <QModelIndex>
16#include <QVariant>
17
18bool BannedNodeLessThan::operator()(const CCombinedBan& left, const CCombinedBan& right) const
19{
20 const CCombinedBan* pLeft = &left;
21 const CCombinedBan* pRight = &right;
22
23 if (order == Qt::DescendingOrder)
24 std::swap(pLeft, pRight);
25
26 switch (static_cast<BanTableModel::ColumnIndex>(column)) {
28 return pLeft->subnet.ToString().compare(pRight->subnet.ToString()) < 0;
30 return pLeft->banEntry.nBanUntil < pRight->banEntry.nBanUntil;
31 } // no default case, so the compiler can warn about missing cases
32 assert(false);
33}
34
35// private implementation
37{
38public:
40 QList<CCombinedBan> cachedBanlist;
42 int sortColumn{-1};
44 Qt::SortOrder sortOrder;
45
48 {
49 banmap_t banMap;
50 node.getBanned(banMap);
51
52 cachedBanlist.clear();
53 cachedBanlist.reserve(banMap.size());
54 for (const auto& entry : banMap)
55 {
56 CCombinedBan banEntry;
57 banEntry.subnet = entry.first;
58 banEntry.banEntry = entry.second;
59 cachedBanlist.append(banEntry);
60 }
61
62 if (sortColumn >= 0)
63 // sort cachedBanlist (use stable sort to prevent rows jumping around unnecessarily)
64 std::stable_sort(cachedBanlist.begin(), cachedBanlist.end(), BannedNodeLessThan(sortColumn, sortOrder));
65 }
66
67 int size() const
68 {
69 return cachedBanlist.size();
70 }
71
73 {
74 if (idx >= 0 && idx < cachedBanlist.size())
75 return &cachedBanlist[idx];
76
77 return nullptr;
78 }
79};
80
82 QAbstractTableModel(parent),
84{
85 columns << tr("IP/Netmask") << tr("Banned Until");
86 priv.reset(new BanTablePriv());
87
88 // load initial data
89 refresh();
90}
91
93{
94 // Intentionally left empty
95}
96
97int BanTableModel::rowCount(const QModelIndex &parent) const
98{
99 if (parent.isValid()) {
100 return 0;
101 }
102 return priv->size();
103}
104
105int BanTableModel::columnCount(const QModelIndex &parent) const
106{
107 if (parent.isValid()) {
108 return 0;
109 }
110 return columns.length();
111}
112
113QVariant BanTableModel::data(const QModelIndex &index, int role) const
114{
115 if(!index.isValid())
116 return QVariant();
117
118 CCombinedBan *rec = static_cast<CCombinedBan*>(index.internalPointer());
119
120 const auto column = static_cast<ColumnIndex>(index.column());
121 if (role == Qt::DisplayRole) {
122 switch (column) {
123 case Address:
124 return QString::fromStdString(rec->subnet.ToString());
125 case Bantime:
126 QDateTime date = QDateTime::fromMSecsSinceEpoch(0);
127 date = date.addSecs(rec->banEntry.nBanUntil);
128 return QLocale::system().toString(date, QLocale::LongFormat);
129 } // no default case, so the compiler can warn about missing cases
130 assert(false);
131 }
132
133 return QVariant();
134}
135
136QVariant BanTableModel::headerData(int section, Qt::Orientation orientation, int role) const
137{
138 if(orientation == Qt::Horizontal)
139 {
140 if(role == Qt::DisplayRole && section < columns.size())
141 {
142 return columns[section];
143 }
144 }
145 return QVariant();
146}
147
148Qt::ItemFlags BanTableModel::flags(const QModelIndex &index) const
149{
150 if (!index.isValid()) return Qt::NoItemFlags;
151
152 Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
153 return retval;
154}
155
156QModelIndex BanTableModel::index(int row, int column, const QModelIndex &parent) const
157{
158 Q_UNUSED(parent);
159 CCombinedBan *data = priv->index(row);
160
161 if (data)
162 return createIndex(row, column, data);
163 return QModelIndex();
164}
165
167{
168 Q_EMIT layoutAboutToBeChanged();
169 priv->refreshBanlist(m_node);
170 Q_EMIT layoutChanged();
171}
172
173void BanTableModel::sort(int column, Qt::SortOrder order)
174{
175 priv->sortColumn = column;
176 priv->sortOrder = order;
177 refresh();
178}
179
181{
182 return priv->size() > 0;
183}
NodeContext m_node
Definition: bitcoin-gui.cpp:36
std::unique_ptr< BanTablePriv > priv
Definition: bantablemodel.h:77
QVariant data(const QModelIndex &index, int role) const override
Qt::ItemFlags flags(const QModelIndex &index) const override
interfaces::Node & m_node
Definition: bantablemodel.h:75
int columnCount(const QModelIndex &parent) const override
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
void sort(int column, Qt::SortOrder order) override
int rowCount(const QModelIndex &parent) const override
QStringList columns
Definition: bantablemodel.h:76
QModelIndex index(int row, int column, const QModelIndex &parent) const override
BanTableModel(interfaces::Node &node, QObject *parent)
int sortColumn
Column to sort nodes by (default to unsorted)
void refreshBanlist(interfaces::Node &node)
Pull a full list of banned nodes from CNode into our cache.
Qt::SortOrder sortOrder
Order (ascending or descending) to sort nodes by.
QList< CCombinedBan > cachedBanlist
Local cache of peer information.
CCombinedBan * index(int idx)
int size() const
Qt::SortOrder order
Definition: bantablemodel.h:36
bool operator()(const CCombinedBan &left, const CCombinedBan &right) const
int64_t nBanUntil
Definition: net_types.h:20
std::string ToString() const
Top-level interface for a bitcoin node (bitcoind process).
Definition: node.h:55
std::map< CSubNet, CBanEntry > banmap_t
Definition: net_types.h:41
CBanEntry banEntry
Definition: bantablemodel.h:24
CSubNet subnet
Definition: bantablemodel.h:23
assert(!tx.IsCoinBase())