[Qt] add banlist table below peers table

This commit is contained in:
Jonas Schnelli 2015-06-20 20:27:03 +02:00
parent 50f090884c
commit ad204df1a9
7 changed files with 375 additions and 10 deletions

View file

@ -97,6 +97,7 @@ QT_MOC_CPP = \
qt/moc_addressbookpage.cpp \
qt/moc_addresstablemodel.cpp \
qt/moc_askpassphrasedialog.cpp \
qt/moc_bantablemodel.cpp \
qt/moc_bitcoinaddressvalidator.cpp \
qt/moc_bitcoinamountfield.cpp \
qt/moc_bitcoingui.cpp \
@ -162,6 +163,7 @@ BITCOIN_QT_H = \
qt/addressbookpage.h \
qt/addresstablemodel.h \
qt/askpassphrasedialog.h \
qt/bantablemodel.h \
qt/bitcoinaddressvalidator.h \
qt/bitcoinamountfield.h \
qt/bitcoingui.h \
@ -260,6 +262,7 @@ RES_ICONS = \
qt/res/icons/verify.png
BITCOIN_QT_CPP = \
qt/bantablemodel.cpp \
qt/bitcoinaddressvalidator.cpp \
qt/bitcoinamountfield.cpp \
qt/bitcoingui.cpp \

192
src/qt/bantablemodel.cpp Normal file
View file

@ -0,0 +1,192 @@
// Copyright (c) 2011-2015 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 "bantablemodel.h"
#include "clientmodel.h"
#include "guiconstants.h"
#include "guiutil.h"
#include "net.h"
#include "sync.h"
#include "utiltime.h"
#include <QDebug>
#include <QList>
#include <QTimer>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/c_local_time_adjustor.hpp>
// private implementation
class BanTablePriv
{
public:
/** Local cache of peer information */
QList<CCombinedBan> cachedBanlist;
/** Column to sort nodes by */
int sortColumn;
/** Order (ascending or descending) to sort nodes by */
Qt::SortOrder sortOrder;
/** Pull a full list of banned nodes from CNode into our cache */
void refreshBanlist()
{
std::map<CSubNet, int64_t> banMap;
CNode::GetBanned(banMap);
cachedBanlist.clear();
#if QT_VERSION >= 0x040700
cachedBanlist.reserve(banMap.size());
#endif
std::map<CSubNet, int64_t>::iterator iter;
for (iter = banMap.begin(); iter != banMap.end(); ++iter) {
CCombinedBan banEntry;
banEntry.subnet = iter->first;
banEntry.bantil = iter->second;
cachedBanlist.append(banEntry);
}
}
int size()
{
return cachedBanlist.size();
}
CCombinedBan *index(int idx)
{
if(idx >= 0 && idx < cachedBanlist.size()) {
return &cachedBanlist[idx];
} else {
return 0;
}
}
};
BanTableModel::BanTableModel(ClientModel *parent) :
QAbstractTableModel(parent),
clientModel(parent),
timer(0)
{
columns << tr("IP/Netmask") << tr("Banned Until");
priv = new BanTablePriv();
// default to unsorted
priv->sortColumn = -1;
// set up timer for auto refresh
timer = new QTimer();
connect(timer, SIGNAL(timeout()), SLOT(refresh()));
timer->setInterval(MODEL_UPDATE_DELAY);
// load initial data
refresh();
}
void BanTableModel::startAutoRefresh()
{
timer->start();
}
void BanTableModel::stopAutoRefresh()
{
timer->stop();
}
int BanTableModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return priv->size();
}
int BanTableModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return columns.length();;
}
QVariant BanTableModel::data(const QModelIndex &index, int role) const
{
if(!index.isValid())
return QVariant();
CCombinedBan *rec = static_cast<CCombinedBan*>(index.internalPointer());
if (role == Qt::DisplayRole) {
switch(index.column())
{
case Address:
return QString::fromStdString(rec->subnet.ToString());
case Bantime:
//show time in users local timezone, not 64bit compatible!
//TODO find a way to support 64bit timestamps
boost::posix_time::ptime pt1 = boost::posix_time::from_time_t(rec->bantil);
boost::posix_time::ptime pt2 = boost::date_time::c_local_adjustor<boost::posix_time::ptime>::utc_to_local(pt1);
std::stringstream ss;
ss << pt2;
return QString::fromStdString(ss.str());
}
} else if (role == Qt::TextAlignmentRole) {
if (index.column() == Bantime)
return (int)(Qt::AlignRight | Qt::AlignVCenter);
}
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 0;
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);
}
else
{
return QModelIndex();
}
}
void BanTableModel::refresh()
{
emit layoutAboutToBeChanged();
priv->refreshBanlist();
emit layoutChanged();
}
void BanTableModel::sort(int column, Qt::SortOrder order)
{
priv->sortColumn = column;
priv->sortOrder = order;
refresh();
}
bool BanTableModel::shouldShow()
{
if (priv->size() > 0)
return true;
return false;
}

66
src/qt/bantablemodel.h Normal file
View file

@ -0,0 +1,66 @@
// Copyright (c) 2011-2013 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_BANTABLEMODEL_H
#define BITCOIN_QT_BANTABLEMODEL_H
#include "main.h"
#include "net.h"
#include <QAbstractTableModel>
#include <QStringList>
class ClientModel;
class BanTablePriv;
QT_BEGIN_NAMESPACE
class QTimer;
QT_END_NAMESPACE
struct CCombinedBan {
CSubNet subnet;
int64_t bantil;
};
/**
Qt model providing information about connected peers, similar to the
"getpeerinfo" RPC call. Used by the rpc console UI.
*/
class BanTableModel : public QAbstractTableModel
{
Q_OBJECT
public:
explicit BanTableModel(ClientModel *parent = 0);
void startAutoRefresh();
void stopAutoRefresh();
enum ColumnIndex {
Address = 0,
Bantime = 1,
};
/** @name Methods overridden from QAbstractTableModel
@{*/
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
QModelIndex index(int row, int column, const QModelIndex &parent) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
void sort(int column, Qt::SortOrder order);
bool shouldShow();
/*@}*/
public slots:
void refresh();
private:
ClientModel *clientModel;
QStringList columns;
BanTablePriv *priv;
QTimer *timer;
};
#endif // BITCOIN_QT_BANTABLEMODEL_H

View file

@ -4,6 +4,7 @@
#include "clientmodel.h"
#include "bantablemodel.h"
#include "guiconstants.h"
#include "peertablemodel.h"
@ -26,6 +27,7 @@ ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
QObject(parent),
optionsModel(optionsModel),
peerTableModel(0),
banTableModel(0),
cachedNumBlocks(0),
cachedBlockDate(QDateTime()),
cachedReindexing(0),
@ -33,6 +35,7 @@ ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
pollTimer(0)
{
peerTableModel = new PeerTableModel(this);
banTableModel = new BanTableModel(this);
pollTimer = new QTimer(this);
connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer()));
pollTimer->start(MODEL_UPDATE_DELAY);
@ -176,6 +179,11 @@ PeerTableModel *ClientModel::getPeerTableModel()
return peerTableModel;
}
BanTableModel *ClientModel::getBanTableModel()
{
return banTableModel;
}
QString ClientModel::formatFullVersion() const
{
return QString::fromStdString(FormatFullVersion());
@ -206,6 +214,11 @@ QString ClientModel::formatClientStartupTime() const
return QDateTime::fromTime_t(nClientStartupTime).toString();
}
void ClientModel::updateBanlist()
{
banTableModel->refresh();
}
// Handlers for core signals
static void ShowProgress(ClientModel *clientmodel, const std::string &title, int nProgress)
{

View file

@ -9,6 +9,7 @@
#include <QDateTime>
class AddressTableModel;
class BanTableModel;
class OptionsModel;
class PeerTableModel;
class TransactionTableModel;
@ -44,6 +45,7 @@ public:
OptionsModel *getOptionsModel();
PeerTableModel *getPeerTableModel();
BanTableModel *getBanTableModel();
//! Return number of connections, default is in- and outbound (total)
int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const;
@ -72,6 +74,7 @@ public:
private:
OptionsModel *optionsModel;
PeerTableModel *peerTableModel;
BanTableModel *banTableModel;
int cachedNumBlocks;
QDateTime cachedBlockDate;
@ -99,6 +102,7 @@ public Q_SLOTS:
void updateTimer();
void updateNumConnections(int numConnections);
void updateAlert(const QString &hash, int status);
void updateBanlist();
};
#endif // BITCOIN_QT_CLIENTMODEL_H

View file

@ -713,17 +713,91 @@
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" rowspan="2">
<widget class="QTableView" name="peerWidget">
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
<layout class="QVBoxLayout" name="verticalLayout_101">
<property name="spacing">
<number>0</number>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
</widget>
<item>
<widget class="QTableView" name="peerWidget">
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
</widget>
</item>
<item>
<widget class="QLabel" name="banHeading">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>32</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>32</height>
</size>
</property>
<property name="font">
<font>
<pointsize>14</pointsize>
</font>
</property>
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
<property name="text">
<string>Banned peers</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item>
<widget class="QTableView" name="banlistWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<widget class="QLabel" name="peerHeading">

View file

@ -8,6 +8,7 @@
#include "clientmodel.h"
#include "guiutil.h"
#include "platformstyle.h"
#include "bantablemodel.h"
#include "chainparams.h"
#include "rpcserver.h"
@ -351,6 +352,9 @@ void RPCConsole::setClientModel(ClientModel *model)
ui->peerWidget->setColumnWidth(PeerTableModel::Subversion, SUBVERSION_COLUMN_WIDTH);
ui->peerWidget->setColumnWidth(PeerTableModel::Ping, PING_COLUMN_WIDTH);
// set up ban table
ui->banlistWidget->setModel(model->getBanTableModel());
// create context menu actions
QAction* disconnectAction = new QAction(tr("&Disconnect Node"), this);
QAction* banAction1h = new QAction(tr("&Ban Node for 1 hour"), this);
@ -395,6 +399,12 @@ void RPCConsole::setClientModel(ClientModel *model)
ui->buildDate->setText(model->formatBuildDate());
ui->startupTime->setText(model->formatClientStartupTime());
ui->networkName->setText(QString::fromStdString(Params().NetworkIDString()));
if (!clientModel->getBanTableModel()->shouldShow())
{
ui->banlistWidget->hide();
ui->banHeading->hide();
}
}
}
@ -766,6 +776,9 @@ void RPCConsole::banSelectedNode(int bantime)
CNode::Ban(CNetAddr(addr), bantime);
bannedNode->CloseSocketDisconnect();
clearSelectedNode();
ui->banlistWidget->setVisible(true);
ui->banHeading->setVisible(true);
clientModel->updateBanlist();
}
}