From 1b0db7b984c49f40cf95c6f685c3c5c790f07606 Mon Sep 17 00:00:00 2001
From: Philip Kaufmann <phil.kaufmann@t-online.de>
Date: Mon, 1 Jun 2015 09:09:51 +0200
Subject: [PATCH 1/3] [Qt] extend rpc console peers tab

- add node id, ping wait, whitelisted and common height
- rephrase some labels to make them easier to understand for users
---
 src/qt/forms/rpcconsole.ui | 142 ++++++++++++++++++++++++++++---------
 src/qt/peertablemodel.cpp  |   1 +
 src/qt/rpcconsole.cpp      |  18 +++--
 3 files changed, 120 insertions(+), 41 deletions(-)

diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui
index c1eb18550..7ae823747 100644
--- a/src/qt/forms/rpcconsole.ui
+++ b/src/qt/forms/rpcconsole.ui
@@ -745,14 +745,14 @@
          </property>
          <layout class="QGridLayout" name="gridLayout_3">
           <item row="0" column="0">
-           <widget class="QLabel" name="label_23">
+           <widget class="QLabel" name="label_30">
             <property name="text">
-             <string>Direction</string>
+             <string>Whitelisted</string>
             </property>
            </widget>
           </item>
           <item row="0" column="2">
-           <widget class="QLabel" name="peerDirection">
+           <widget class="QLabel" name="peerWhitelisted">
             <property name="cursor">
              <cursorShape>IBeamCursor</cursorShape>
             </property>
@@ -768,14 +768,14 @@
            </widget>
           </item>
           <item row="1" column="0">
-           <widget class="QLabel" name="label_21">
+           <widget class="QLabel" name="label_23">
             <property name="text">
-             <string>Version</string>
+             <string>Direction</string>
             </property>
            </widget>
           </item>
           <item row="1" column="2">
-           <widget class="QLabel" name="peerVersion">
+           <widget class="QLabel" name="peerDirection">
             <property name="cursor">
              <cursorShape>IBeamCursor</cursorShape>
             </property>
@@ -791,14 +791,14 @@
            </widget>
           </item>
           <item row="2" column="0">
-           <widget class="QLabel" name="label_28">
+           <widget class="QLabel" name="label_21">
             <property name="text">
-             <string>User Agent</string>
+             <string>Version</string>
             </property>
            </widget>
           </item>
           <item row="2" column="2">
-           <widget class="QLabel" name="peerSubversion">
+           <widget class="QLabel" name="peerVersion">
             <property name="cursor">
              <cursorShape>IBeamCursor</cursorShape>
             </property>
@@ -814,13 +814,36 @@
            </widget>
           </item>
           <item row="3" column="0">
+           <widget class="QLabel" name="label_28">
+            <property name="text">
+             <string>User Agent</string>
+            </property>
+           </widget>
+          </item>
+          <item row="3" column="2">
+           <widget class="QLabel" name="peerSubversion">
+            <property name="cursor">
+             <cursorShape>IBeamCursor</cursorShape>
+            </property>
+            <property name="text">
+             <string>N/A</string>
+            </property>
+            <property name="textFormat">
+             <enum>Qt::PlainText</enum>
+            </property>
+            <property name="textInteractionFlags">
+             <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+            </property>
+           </widget>
+          </item>
+          <item row="4" column="0">
            <widget class="QLabel" name="label_4">
             <property name="text">
              <string>Services</string>
             </property>
            </widget>
           </item>
-          <item row="3" column="2">
+          <item row="4" column="2">
            <widget class="QLabel" name="peerServices">
             <property name="cursor">
              <cursorShape>IBeamCursor</cursorShape>
@@ -839,7 +862,7 @@
           <item row="5" column="0">
            <widget class="QLabel" name="label_29">
             <property name="text">
-             <string>Starting Height</string>
+             <string>Starting Block</string>
             </property>
            </widget>
           </item>
@@ -862,7 +885,7 @@
           <item row="6" column="0">
            <widget class="QLabel" name="label_27">
             <property name="text">
-             <string>Sync Height</string>
+             <string>Synced Headers</string>
             </property>
            </widget>
           </item>
@@ -883,14 +906,14 @@
            </widget>
           </item>
           <item row="7" column="0">
-           <widget class="QLabel" name="label_24">
+           <widget class="QLabel" name="label_25">
             <property name="text">
-             <string>Ban Score</string>
+             <string>Synced Blocks</string>
             </property>
            </widget>
           </item>
           <item row="7" column="2">
-           <widget class="QLabel" name="peerBanScore">
+           <widget class="QLabel" name="peerCommonHeight">
             <property name="cursor">
              <cursorShape>IBeamCursor</cursorShape>
             </property>
@@ -906,14 +929,14 @@
            </widget>
           </item>
           <item row="8" column="0">
-           <widget class="QLabel" name="label_22">
+           <widget class="QLabel" name="label_24">
             <property name="text">
-             <string>Connection Time</string>
+             <string>Ban Score</string>
             </property>
            </widget>
           </item>
           <item row="8" column="2">
-           <widget class="QLabel" name="peerConnTime">
+           <widget class="QLabel" name="peerBanScore">
             <property name="cursor">
              <cursorShape>IBeamCursor</cursorShape>
             </property>
@@ -929,14 +952,14 @@
            </widget>
           </item>
           <item row="9" column="0">
-           <widget class="QLabel" name="label_15">
+           <widget class="QLabel" name="label_22">
             <property name="text">
-             <string>Last Send</string>
+             <string>Connection Time</string>
             </property>
            </widget>
           </item>
           <item row="9" column="2">
-           <widget class="QLabel" name="peerLastSend">
+           <widget class="QLabel" name="peerConnTime">
             <property name="cursor">
              <cursorShape>IBeamCursor</cursorShape>
             </property>
@@ -952,14 +975,14 @@
            </widget>
           </item>
           <item row="10" column="0">
-           <widget class="QLabel" name="label_19">
+           <widget class="QLabel" name="label_15">
             <property name="text">
-             <string>Last Receive</string>
+             <string>Last Send</string>
             </property>
            </widget>
           </item>
           <item row="10" column="2">
-           <widget class="QLabel" name="peerLastRecv">
+           <widget class="QLabel" name="peerLastSend">
             <property name="cursor">
              <cursorShape>IBeamCursor</cursorShape>
             </property>
@@ -975,14 +998,14 @@
            </widget>
           </item>
           <item row="11" column="0">
-           <widget class="QLabel" name="label_18">
+           <widget class="QLabel" name="label_19">
             <property name="text">
-             <string>Bytes Sent</string>
+             <string>Last Receive</string>
             </property>
            </widget>
           </item>
           <item row="11" column="2">
-           <widget class="QLabel" name="peerBytesSent">
+           <widget class="QLabel" name="peerLastRecv">
             <property name="cursor">
              <cursorShape>IBeamCursor</cursorShape>
             </property>
@@ -998,14 +1021,14 @@
            </widget>
           </item>
           <item row="12" column="0">
-           <widget class="QLabel" name="label_20">
+           <widget class="QLabel" name="label_18">
             <property name="text">
-             <string>Bytes Received</string>
+             <string>Bytes Sent</string>
             </property>
            </widget>
           </item>
           <item row="12" column="2">
-           <widget class="QLabel" name="peerBytesRecv">
+           <widget class="QLabel" name="peerBytesSent">
             <property name="cursor">
              <cursorShape>IBeamCursor</cursorShape>
             </property>
@@ -1021,14 +1044,14 @@
            </widget>
           </item>
           <item row="13" column="0">
-           <widget class="QLabel" name="label_26">
+           <widget class="QLabel" name="label_20">
             <property name="text">
-             <string>Ping Time</string>
+             <string>Bytes Received</string>
             </property>
            </widget>
           </item>
           <item row="13" column="2">
-           <widget class="QLabel" name="peerPingTime">
+           <widget class="QLabel" name="peerBytesRecv">
             <property name="cursor">
              <cursorShape>IBeamCursor</cursorShape>
             </property>
@@ -1044,13 +1067,62 @@
            </widget>
           </item>
           <item row="14" column="0">
+           <widget class="QLabel" name="label_26">
+            <property name="text">
+             <string>Ping Time</string>
+            </property>
+           </widget>
+          </item>
+          <item row="14" column="2">
+           <widget class="QLabel" name="peerPingTime">
+            <property name="cursor">
+             <cursorShape>IBeamCursor</cursorShape>
+            </property>
+            <property name="text">
+             <string>N/A</string>
+            </property>
+            <property name="textFormat">
+             <enum>Qt::PlainText</enum>
+            </property>
+            <property name="textInteractionFlags">
+             <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+            </property>
+           </widget>
+          </item>
+          <item row="15" column="0">
+           <widget class="QLabel" name="peerPingWaitLabel">
+            <property name="toolTip">
+             <string>The duration of a currently outstanding ping.</string>
+            </property>
+            <property name="text">
+             <string>Ping Wait</string>
+            </property>
+           </widget>
+          </item>
+          <item row="15" column="2">
+           <widget class="QLabel" name="peerPingWait">
+            <property name="cursor">
+             <cursorShape>IBeamCursor</cursorShape>
+            </property>
+            <property name="text">
+             <string>N/A</string>
+            </property>
+            <property name="textFormat">
+             <enum>Qt::PlainText</enum>
+            </property>
+            <property name="textInteractionFlags">
+             <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+            </property>
+           </widget>
+          </item>
+          <item row="16" column="0">
            <widget class="QLabel" name="label_timeoffset">
             <property name="text">
              <string>Time Offset</string>
             </property>
            </widget>
           </item>
-          <item row="14" column="2">
+          <item row="16" column="2">
            <widget class="QLabel" name="timeoffset">
             <property name="cursor">
              <cursorShape>IBeamCursor</cursorShape>
@@ -1066,7 +1138,7 @@
             </property>
            </widget>
           </item>
-          <item row="15" column="1">
+          <item row="17" column="1">
            <spacer name="verticalSpacer_3">
             <property name="orientation">
              <enum>Qt::Vertical</enum>
diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp
index 220f273d0..06403734e 100644
--- a/src/qt/peertablemodel.cpp
+++ b/src/qt/peertablemodel.cpp
@@ -68,6 +68,7 @@ public:
                 CNodeCombinedStats stats;
                 stats.nodeStateStats.nMisbehavior = 0;
                 stats.nodeStateStats.nSyncHeight = -1;
+                stats.nodeStateStats.nCommonHeight = -1;
                 stats.fNodeStateStatsAvailable = false;
                 pnode->copyStats(stats.nodeStats);
                 cachedNodeStats.append(stats);
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index e99972d49..73ee33cbd 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -611,7 +611,8 @@ void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats)
     cachedNodeid = stats->nodeStats.nodeid;
 
     // update the detail ui with latest node information
-    QString peerAddrDetails(QString::fromStdString(stats->nodeStats.addrName));
+    QString peerAddrDetails(QString::fromStdString(stats->nodeStats.addrName) + " ");
+    peerAddrDetails += tr("(node id: %1)").arg(QString::number(stats->nodeStats.nodeid));
     if (!stats->nodeStats.addrLocal.empty())
         peerAddrDetails += "<br />" + tr("via %1").arg(QString::fromStdString(stats->nodeStats.addrLocal));
     ui->peerHeading->setText(peerAddrDetails);
@@ -622,11 +623,13 @@ void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats)
     ui->peerBytesRecv->setText(FormatBytes(stats->nodeStats.nRecvBytes));
     ui->peerConnTime->setText(GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nTimeConnected));
     ui->peerPingTime->setText(GUIUtil::formatPingTime(stats->nodeStats.dPingTime));
+    ui->peerPingWait->setText(GUIUtil::formatPingTime(stats->nodeStats.dPingWait));
     ui->timeoffset->setText(GUIUtil::formatTimeOffset(stats->nodeStats.nTimeOffset));
-    ui->peerVersion->setText(QString("%1").arg(stats->nodeStats.nVersion));
+    ui->peerVersion->setText(QString("%1").arg(QString::number(stats->nodeStats.nVersion)));
     ui->peerSubversion->setText(QString::fromStdString(stats->nodeStats.cleanSubVer));
     ui->peerDirection->setText(stats->nodeStats.fInbound ? tr("Inbound") : tr("Outbound"));
-    ui->peerHeight->setText(QString("%1").arg(stats->nodeStats.nStartingHeight));
+    ui->peerHeight->setText(QString("%1").arg(QString::number(stats->nodeStats.nStartingHeight)));
+    ui->peerWhitelisted->setText(stats->nodeStats.fWhitelisted ? tr("Yes") : tr("No"));
 
     // This check fails for example if the lock was busy and
     // nodeStateStats couldn't be fetched.
@@ -639,9 +642,12 @@ void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats)
             ui->peerSyncHeight->setText(QString("%1").arg(stats->nodeStateStats.nSyncHeight));
         else
             ui->peerSyncHeight->setText(tr("Unknown"));
-    } else {
-        ui->peerBanScore->setText(tr("Fetching..."));
-        ui->peerSyncHeight->setText(tr("Fetching..."));
+
+        // Common height is init to -1
+        if (stats->nodeStateStats.nCommonHeight > -1)
+            ui->peerCommonHeight->setText(QString("%1").arg(stats->nodeStateStats.nCommonHeight));
+        else
+            ui->peerCommonHeight->setText(tr("Unknown"));
     }
 
     ui->detailWidget->show();

From 7211adad85275db24835bb877a29b28adcf06f62 Mon Sep 17 00:00:00 2001
From: Philip Kaufmann <phil.kaufmann@t-online.de>
Date: Mon, 1 Jun 2015 11:39:52 +0200
Subject: [PATCH 2/3] [Qt] replace Boost foreach with Qt version
 peertablemodel.cpp

---
 src/qt/peertablemodel.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp
index 06403734e..f5904a4d8 100644
--- a/src/qt/peertablemodel.cpp
+++ b/src/qt/peertablemodel.cpp
@@ -63,7 +63,7 @@ public:
 #if QT_VERSION >= 0x040700
             cachedNodeStats.reserve(vNodes.size());
 #endif
-            BOOST_FOREACH(CNode* pnode, vNodes)
+            foreach (CNode* pnode, vNodes)
             {
                 CNodeCombinedStats stats;
                 stats.nodeStateStats.nMisbehavior = 0;
@@ -92,7 +92,7 @@ public:
         // build index map
         mapNodeRows.clear();
         int row = 0;
-        BOOST_FOREACH(CNodeCombinedStats &stats, cachedNodeStats)
+        foreach (const CNodeCombinedStats& stats, cachedNodeStats)
             mapNodeRows.insert(std::pair<NodeId, int>(stats.nodeStats.nodeid, row++));
     }
 

From e0597268116cf90d961abeba9d14aaad0ab682d2 Mon Sep 17 00:00:00 2001
From: Philip Kaufmann <phil.kaufmann@t-online.de>
Date: Sat, 6 Jun 2015 10:38:15 +0200
Subject: [PATCH 3/3] [Qt] deselect peer when switching away from peers tab in
 RPC console

---
 src/qt/rpcconsole.cpp | 32 +++++++++++++++++---------------
 src/qt/rpcconsole.h   |  4 +++-
 2 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 73ee33cbd..681617bd8 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -485,10 +485,10 @@ void RPCConsole::startExecutor()
 
 void RPCConsole::on_tabWidget_currentChanged(int index)
 {
-    if(ui->tabWidget->widget(index) == ui->tab_console)
-    {
+    if (ui->tabWidget->widget(index) == ui->tab_console)
         ui->lineEdit->setFocus();
-    }
+    else if (ui->tabWidget->widget(index) != ui->tab_peers)
+        clearSelectedNode();
 }
 
 void RPCConsole::on_openDebugLogfileButton_clicked()
@@ -558,12 +558,11 @@ void RPCConsole::peerLayoutChanged()
         return;
 
     // find the currently selected row
-    int selectedRow;
+    int selectedRow = -1;
     QModelIndexList selectedModelIndex = ui->peerWidget->selectionModel()->selectedIndexes();
-    if (selectedModelIndex.isEmpty())
-        selectedRow = -1;
-    else
+    if (!selectedModelIndex.isEmpty()) {
         selectedRow = selectedModelIndex.first().row();
+    }
 
     // check if our detail node has a row in the table (it may not necessarily
     // be at selectedRow since its position can change after a layout change)
@@ -573,9 +572,6 @@ void RPCConsole::peerLayoutChanged()
     {
         // detail node dissapeared from table (node disconnected)
         fUnselect = true;
-        cachedNodeid = -1;
-        ui->detailWidget->hide();
-        ui->peerHeading->setText(tr("Select a peer to view detailed information."));
     }
     else
     {
@@ -590,10 +586,8 @@ void RPCConsole::peerLayoutChanged()
         stats = clientModel->getPeerTableModel()->getNodeStats(detailNodeRow);
     }
 
-    if (fUnselect && selectedRow >= 0)
-    {
-        ui->peerWidget->selectionModel()->select(QItemSelection(selectedModelIndex.first(), selectedModelIndex.last()),
-            QItemSelectionModel::Deselect);
+    if (fUnselect && selectedRow >= 0) {
+        clearSelectedNode();
     }
 
     if (fReselect)
@@ -694,6 +688,14 @@ void RPCConsole::disconnectSelectedNode()
     // Find the node, disconnect it and clear the selected node
     if (CNode *bannedNode = FindNode(strNode.toStdString())) {
         bannedNode->CloseSocketDisconnect();
-        ui->peerWidget->selectionModel()->clearSelection();
+        clearSelectedNode();
     }
 }
+
+void RPCConsole::clearSelectedNode()
+{
+    ui->peerWidget->selectionModel()->clearSelection();
+    cachedNodeid = -1;
+    ui->detailWidget->hide();
+    ui->peerHeading->setText(tr("Select a peer to view detailed information."));
+}
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index 767e9aaee..a309df7ba 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -76,7 +76,7 @@ public slots:
     void peerSelected(const QItemSelection &selected, const QItemSelection &deselected);
     /** Handle updated peer information */
     void peerLayoutChanged();
-	/** Disconnect a selected node on the Peers tab */
+    /** Disconnect a selected node on the Peers tab */
     void disconnectSelectedNode();
 
 signals:
@@ -90,6 +90,8 @@ private:
     void setTrafficGraphRange(int mins);
     /** show detailed information on ui about selected node */
     void updateNodeDetail(const CNodeCombinedStats *stats);
+    /** clear the selected node */
+    void clearSelectedNode();
 
     enum ColumnWidths
     {