Files
bitcoin/src/qt/bantablemodel.cpp
fanquake 7193245cd6 doc: remove For ... comments
We don't add or maintain these, and they are of little value, as
well as having the effect of polluting diffs.

They are also wrong, i.e DEFAULT_SCRIPTCHECK_THREADS is not in
validation.h.
2025-05-19 16:40:33 +01:00

187 lines
4.8 KiB
C++

// Copyright (c) 2011-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <qt/bantablemodel.h>
#include <interfaces/node.h>
#include <net_types.h>
#include <utility>
#include <QDateTime>
#include <QList>
#include <QLocale>
#include <QModelIndex>
#include <QVariant>
bool BannedNodeLessThan::operator()(const CCombinedBan& left, const CCombinedBan& right) const
{
const CCombinedBan* pLeft = &left;
const CCombinedBan* pRight = &right;
if (order == Qt::DescendingOrder)
std::swap(pLeft, pRight);
switch (static_cast<BanTableModel::ColumnIndex>(column)) {
case BanTableModel::Address:
return pLeft->subnet.ToString().compare(pRight->subnet.ToString()) < 0;
case BanTableModel::Bantime:
return pLeft->banEntry.nBanUntil < pRight->banEntry.nBanUntil;
} // no default case, so the compiler can warn about missing cases
assert(false);
}
// private implementation
class BanTablePriv
{
public:
/** Local cache of peer information */
QList<CCombinedBan> cachedBanlist;
/** Column to sort nodes by (default to unsorted) */
int sortColumn{-1};
/** Order (ascending or descending) to sort nodes by */
Qt::SortOrder sortOrder;
/** Pull a full list of banned nodes from interfaces::Node into our cache */
void refreshBanlist(interfaces::Node& node)
{
banmap_t banMap;
node.getBanned(banMap);
cachedBanlist.clear();
cachedBanlist.reserve(banMap.size());
for (const auto& entry : banMap)
{
CCombinedBan banEntry;
banEntry.subnet = entry.first;
banEntry.banEntry = entry.second;
cachedBanlist.append(banEntry);
}
if (sortColumn >= 0)
// sort cachedBanlist (use stable sort to prevent rows jumping around unnecessarily)
std::stable_sort(cachedBanlist.begin(), cachedBanlist.end(), BannedNodeLessThan(sortColumn, sortOrder));
}
int size() const
{
return cachedBanlist.size();
}
CCombinedBan *index(int idx)
{
if (idx >= 0 && idx < cachedBanlist.size())
return &cachedBanlist[idx];
return nullptr;
}
};
BanTableModel::BanTableModel(interfaces::Node& node, QObject* parent) :
QAbstractTableModel(parent),
m_node(node)
{
columns << tr("IP/Netmask") << tr("Banned Until");
priv.reset(new BanTablePriv());
// load initial data
refresh();
}
BanTableModel::~BanTableModel() = default;
int BanTableModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid()) {
return 0;
}
return priv->size();
}
int BanTableModel::columnCount(const QModelIndex &parent) const
{
if (parent.isValid()) {
return 0;
}
return columns.length();
}
QVariant BanTableModel::data(const QModelIndex &index, int role) const
{
if(!index.isValid())
return QVariant();
CCombinedBan *rec = static_cast<CCombinedBan*>(index.internalPointer());
const auto column = static_cast<ColumnIndex>(index.column());
if (role == Qt::DisplayRole) {
switch (column) {
case Address:
return QString::fromStdString(rec->subnet.ToString());
case Bantime:
QDateTime date = QDateTime::fromMSecsSinceEpoch(0);
date = date.addSecs(rec->banEntry.nBanUntil);
return QLocale::system().toString(date, QLocale::LongFormat);
} // no default case, so the compiler can warn about missing cases
assert(false);
}
return QVariant();
}
QVariant BanTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if(orientation == Qt::Horizontal)
{
if(role == Qt::DisplayRole && section < columns.size())
{
return columns[section];
}
}
return QVariant();
}
Qt::ItemFlags BanTableModel::flags(const QModelIndex &index) const
{
if (!index.isValid()) return Qt::NoItemFlags;
Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
return retval;
}
QModelIndex BanTableModel::index(int row, int column, const QModelIndex &parent) const
{
Q_UNUSED(parent);
CCombinedBan *data = priv->index(row);
if (data)
return createIndex(row, column, data);
return QModelIndex();
}
void BanTableModel::refresh()
{
Q_EMIT layoutAboutToBeChanged();
priv->refreshBanlist(m_node);
Q_EMIT layoutChanged();
}
void BanTableModel::sort(int column, Qt::SortOrder order)
{
priv->sortColumn = column;
priv->sortOrder = order;
refresh();
}
bool BanTableModel::shouldShow()
{
return priv->size() > 0;
}
bool BanTableModel::unban(const QModelIndex& index)
{
CCombinedBan* ban{static_cast<CCombinedBan*>(index.internalPointer())};
return ban != nullptr && m_node.unban(ban->subnet);
}