Skip to content

Commit e984730

Browse files
committed
Merge #8874: Multiple Selection for peer and ban tables
1077577 Fix auto-deselection of peers (Andrew Chow) addfdeb Multiple Selection for peer and ban tables (Andrew Chow)
2 parents 924de0b + 1077577 commit e984730

File tree

4 files changed

+79
-56
lines changed

4 files changed

+79
-56
lines changed

src/qt/guiutil.cpp

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -291,17 +291,11 @@ void copyEntryData(QAbstractItemView *view, int column, int role)
291291
}
292292
}
293293

294-
QVariant getEntryData(QAbstractItemView *view, int column, int role)
294+
QList<QModelIndex> getEntryData(QAbstractItemView *view, int column)
295295
{
296296
if(!view || !view->selectionModel())
297-
return QVariant();
298-
QModelIndexList selection = view->selectionModel()->selectedRows(column);
299-
300-
if(!selection.isEmpty()) {
301-
// Return first item
302-
return (selection.at(0).data(role));
303-
}
304-
return QVariant();
297+
return QList<QModelIndex>();
298+
return view->selectionModel()->selectedRows(column);
305299
}
306300

307301
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir,

src/qt/guiutil.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,9 @@ namespace GUIUtil
6767
/** Return a field of the currently selected entry as a QString. Does nothing if nothing
6868
is selected.
6969
@param[in] column Data column to extract from the model
70-
@param[in] role Data role to extract from the model
7170
@see TransactionView::copyLabel, TransactionView::copyAmount, TransactionView::copyAddress
7271
*/
73-
QVariant getEntryData(QAbstractItemView *view, int column, int role);
72+
QList<QModelIndex> getEntryData(QAbstractItemView *view, int column);
7473

7574
void setClipboard(const QString& str);
7675

src/qt/rpcconsole.cpp

Lines changed: 72 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,6 @@ RPCConsole::RPCConsole(const PlatformStyle *_platformStyle, QWidget *parent) :
343343
ui(new Ui::RPCConsole),
344344
clientModel(0),
345345
historyPtr(0),
346-
cachedNodeid(-1),
347346
platformStyle(_platformStyle),
348347
peersTableContextMenu(0),
349348
banTableContextMenu(0),
@@ -469,19 +468,19 @@ void RPCConsole::setClientModel(ClientModel *model)
469468
ui->peerWidget->verticalHeader()->hide();
470469
ui->peerWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
471470
ui->peerWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
472-
ui->peerWidget->setSelectionMode(QAbstractItemView::SingleSelection);
471+
ui->peerWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
473472
ui->peerWidget->setContextMenuPolicy(Qt::CustomContextMenu);
474473
ui->peerWidget->setColumnWidth(PeerTableModel::Address, ADDRESS_COLUMN_WIDTH);
475474
ui->peerWidget->setColumnWidth(PeerTableModel::Subversion, SUBVERSION_COLUMN_WIDTH);
476475
ui->peerWidget->setColumnWidth(PeerTableModel::Ping, PING_COLUMN_WIDTH);
477476
ui->peerWidget->horizontalHeader()->setStretchLastSection(true);
478477

479478
// create peer table context menu actions
480-
QAction* disconnectAction = new QAction(tr("&Disconnect Node"), this);
481-
QAction* banAction1h = new QAction(tr("Ban Node for") + " " + tr("1 &hour"), this);
482-
QAction* banAction24h = new QAction(tr("Ban Node for") + " " + tr("1 &day"), this);
483-
QAction* banAction7d = new QAction(tr("Ban Node for") + " " + tr("1 &week"), this);
484-
QAction* banAction365d = new QAction(tr("Ban Node for") + " " + tr("1 &year"), this);
479+
QAction* disconnectAction = new QAction(tr("&Disconnect"), this);
480+
QAction* banAction1h = new QAction(tr("Ban for") + " " + tr("1 &hour"), this);
481+
QAction* banAction24h = new QAction(tr("Ban for") + " " + tr("1 &day"), this);
482+
QAction* banAction7d = new QAction(tr("Ban for") + " " + tr("1 &week"), this);
483+
QAction* banAction365d = new QAction(tr("Ban for") + " " + tr("1 &year"), this);
485484

486485
// create peer table context menu
487486
peersTableContextMenu = new QMenu();
@@ -514,7 +513,9 @@ void RPCConsole::setClientModel(ClientModel *model)
514513
this, SLOT(peerSelected(const QItemSelection &, const QItemSelection &)));
515514
// peer table signal handling - update peer details when new nodes are added to the model
516515
connect(model->getPeerTableModel(), SIGNAL(layoutChanged()), this, SLOT(peerLayoutChanged()));
517-
516+
// peer table signal handling - cache selected node ids
517+
connect(model->getPeerTableModel(), SIGNAL(layoutAboutToChange()), this, SLOT(peerLayoutAboutToChange()));
518+
518519
// set up ban table
519520
ui->banlistWidget->setModel(model->getBanTableModel());
520521
ui->banlistWidget->verticalHeader()->hide();
@@ -527,7 +528,7 @@ void RPCConsole::setClientModel(ClientModel *model)
527528
ui->banlistWidget->horizontalHeader()->setStretchLastSection(true);
528529

529530
// create ban table context menu action
530-
QAction* unbanAction = new QAction(tr("&Unban Node"), this);
531+
QAction* unbanAction = new QAction(tr("&Unban"), this);
531532

532533
// create ban table context menu
533534
banTableContextMenu = new QMenu();
@@ -825,6 +826,17 @@ void RPCConsole::peerSelected(const QItemSelection &selected, const QItemSelecti
825826
updateNodeDetail(stats);
826827
}
827828

829+
void RPCConsole::peerLayoutAboutToChange()
830+
{
831+
QModelIndexList selected = ui->peerWidget->selectionModel()->selectedIndexes();
832+
cachedNodeids.clear();
833+
for(int i = 0; i < selected.size(); i++)
834+
{
835+
const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(selected.at(i).row());
836+
cachedNodeids.append(stats->nodeStats.nodeid);
837+
}
838+
}
839+
828840
void RPCConsole::peerLayoutChanged()
829841
{
830842
if (!clientModel || !clientModel->getPeerTableModel())
@@ -834,7 +846,7 @@ void RPCConsole::peerLayoutChanged()
834846
bool fUnselect = false;
835847
bool fReselect = false;
836848

837-
if (cachedNodeid == -1) // no node selected yet
849+
if (cachedNodeids.empty()) // no node selected yet
838850
return;
839851

840852
// find the currently selected row
@@ -846,7 +858,7 @@ void RPCConsole::peerLayoutChanged()
846858

847859
// check if our detail node has a row in the table (it may not necessarily
848860
// be at selectedRow since its position can change after a layout change)
849-
int detailNodeRow = clientModel->getPeerTableModel()->getRowByNodeId(cachedNodeid);
861+
int detailNodeRow = clientModel->getPeerTableModel()->getRowByNodeId(cachedNodeids.first());
850862

851863
if (detailNodeRow < 0)
852864
{
@@ -872,7 +884,10 @@ void RPCConsole::peerLayoutChanged()
872884

873885
if (fReselect)
874886
{
875-
ui->peerWidget->selectRow(detailNodeRow);
887+
for(int i = 0; i < cachedNodeids.size(); i++)
888+
{
889+
ui->peerWidget->selectRow(clientModel->getPeerTableModel()->getRowByNodeId(cachedNodeids.at(i)));
890+
}
876891
}
877892

878893
if (stats)
@@ -881,9 +896,6 @@ void RPCConsole::peerLayoutChanged()
881896

882897
void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats)
883898
{
884-
// Update cached nodeid
885-
cachedNodeid = stats->nodeStats.nodeid;
886-
887899
// update the detail ui with latest node information
888900
QString peerAddrDetails(QString::fromStdString(stats->nodeStats.addrName) + " ");
889901
peerAddrDetails += tr("(node id: %1)").arg(QString::number(stats->nodeStats.nodeid));
@@ -973,56 +985,72 @@ void RPCConsole::disconnectSelectedNode()
973985
{
974986
if(!g_connman)
975987
return;
976-
// Get currently selected peer address
977-
NodeId id = GUIUtil::getEntryData(ui->peerWidget, 0, PeerTableModel::NetNodeId).toInt();
978-
// Find the node, disconnect it and clear the selected node
979-
if(g_connman->DisconnectNode(id))
980-
clearSelectedNode();
988+
989+
// Get selected peer addresses
990+
QList<QModelIndex> nodes = GUIUtil::getEntryData(ui->peerWidget, 0);
991+
for(int i = 0; i < nodes.count(); i++)
992+
{
993+
// Get currently selected peer address
994+
NodeId id = nodes.at(i).data(PeerTableModel::NetNodeId).toInt();
995+
// Find the node, disconnect it and clear the selected node
996+
if(g_connman->DisconnectNode(id))
997+
clearSelectedNode();
998+
}
981999
}
9821000

9831001
void RPCConsole::banSelectedNode(int bantime)
9841002
{
9851003
if (!clientModel || !g_connman)
9861004
return;
987-
988-
if(cachedNodeid == -1)
989-
return;
990-
991-
// Get currently selected peer address
992-
int detailNodeRow = clientModel->getPeerTableModel()->getRowByNodeId(cachedNodeid);
993-
if(detailNodeRow < 0)
994-
return;
995-
996-
// Find possible nodes, ban it and clear the selected node
997-
const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(detailNodeRow);
998-
if(stats) {
999-
g_connman->Ban(stats->nodeStats.addr, BanReasonManuallyAdded, bantime);
1000-
clearSelectedNode();
1001-
clientModel->getBanTableModel()->refresh();
1005+
1006+
// Get selected peer addresses
1007+
QList<QModelIndex> nodes = GUIUtil::getEntryData(ui->peerWidget, 0);
1008+
for(int i = 0; i < nodes.count(); i++)
1009+
{
1010+
// Get currently selected peer address
1011+
NodeId id = nodes.at(i).data(PeerTableModel::NetNodeId).toInt();
1012+
1013+
// Get currently selected peer address
1014+
int detailNodeRow = clientModel->getPeerTableModel()->getRowByNodeId(id);
1015+
if(detailNodeRow < 0)
1016+
return;
1017+
1018+
// Find possible nodes, ban it and clear the selected node
1019+
const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(detailNodeRow);
1020+
if(stats) {
1021+
g_connman->Ban(stats->nodeStats.addr, BanReasonManuallyAdded, bantime);
1022+
}
10021023
}
1024+
clearSelectedNode();
1025+
clientModel->getBanTableModel()->refresh();
10031026
}
10041027

10051028
void RPCConsole::unbanSelectedNode()
10061029
{
10071030
if (!clientModel)
10081031
return;
10091032

1010-
// Get currently selected ban address
1011-
QString strNode = GUIUtil::getEntryData(ui->banlistWidget, 0, BanTableModel::Address).toString();
1012-
CSubNet possibleSubnet;
1013-
1014-
LookupSubNet(strNode.toStdString().c_str(), possibleSubnet);
1015-
if (possibleSubnet.IsValid() && g_connman)
1033+
// Get selected ban addresses
1034+
QList<QModelIndex> nodes = GUIUtil::getEntryData(ui->banlistWidget, 0);
1035+
for(int i = 0; i < nodes.count(); i++)
10161036
{
1017-
g_connman->Unban(possibleSubnet);
1018-
clientModel->getBanTableModel()->refresh();
1037+
// Get currently selected ban address
1038+
QString strNode = nodes.at(i).data(BanTableModel::Address).toString();
1039+
CSubNet possibleSubnet;
1040+
1041+
LookupSubNet(strNode.toStdString().c_str(), possibleSubnet);
1042+
if (possibleSubnet.IsValid() && g_connman)
1043+
{
1044+
g_connman->Unban(possibleSubnet);
1045+
clientModel->getBanTableModel()->refresh();
1046+
}
10191047
}
10201048
}
10211049

10221050
void RPCConsole::clearSelectedNode()
10231051
{
10241052
ui->peerWidget->selectionModel()->clearSelection();
1025-
cachedNodeid = -1;
1053+
cachedNodeids.clear();
10261054
ui->detailWidget->hide();
10271055
ui->peerHeading->setText(tr("Select a peer to view detailed information."));
10281056
}

src/qt/rpcconsole.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ public Q_SLOTS:
9898
void scrollToEnd();
9999
/** Handle selection of peer in peers list */
100100
void peerSelected(const QItemSelection &selected, const QItemSelection &deselected);
101+
/** Handle selection caching before update */
102+
void peerLayoutAboutToChange();
101103
/** Handle updated peer information */
102104
void peerLayoutChanged();
103105
/** Disconnect a selected node on the Peers tab */
@@ -135,7 +137,7 @@ public Q_SLOTS:
135137
ClientModel *clientModel;
136138
QStringList history;
137139
int historyPtr;
138-
NodeId cachedNodeid;
140+
QList<NodeId> cachedNodeids;
139141
const PlatformStyle *platformStyle;
140142
RPCTimerInterface *rpcTimerInterface;
141143
QMenu *peersTableContextMenu;

0 commit comments

Comments
 (0)