LCOV - code coverage report
Current view: top level - src/qt - peertablemodel.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 0 94 0.0 %
Date: 2015-10-12 22:39:14 Functions: 0 12 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2011-2013 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 "peertablemodel.h"
       6             : 
       7             : #include "clientmodel.h"
       8             : #include "guiconstants.h"
       9             : #include "guiutil.h"
      10             : 
      11             : #include "sync.h"
      12             : 
      13             : #include <QDebug>
      14             : #include <QList>
      15             : #include <QTimer>
      16             : 
      17           0 : bool NodeLessThan::operator()(const CNodeCombinedStats &left, const CNodeCombinedStats &right) const
      18             : {
      19           0 :     const CNodeStats *pLeft = &(left.nodeStats);
      20           0 :     const CNodeStats *pRight = &(right.nodeStats);
      21             : 
      22           0 :     if (order == Qt::DescendingOrder)
      23             :         std::swap(pLeft, pRight);
      24             : 
      25           0 :     switch(column)
      26             :     {
      27             :     case PeerTableModel::Address:
      28           0 :         return pLeft->addrName.compare(pRight->addrName) < 0;
      29             :     case PeerTableModel::Subversion:
      30           0 :         return pLeft->cleanSubVer.compare(pRight->cleanSubVer) < 0;
      31             :     case PeerTableModel::Ping:
      32           0 :         return pLeft->dPingTime < pRight->dPingTime;
      33             :     }
      34             : 
      35             :     return false;
      36             : }
      37             : 
      38             : // private implementation
      39           0 : class PeerTablePriv
      40             : {
      41             : public:
      42             :     /** Local cache of peer information */
      43             :     QList<CNodeCombinedStats> cachedNodeStats;
      44             :     /** Column to sort nodes by */
      45             :     int sortColumn;
      46             :     /** Order (ascending or descending) to sort nodes by */
      47             :     Qt::SortOrder sortOrder;
      48             :     /** Index of rows by node ID */
      49             :     std::map<NodeId, int> mapNodeRows;
      50             : 
      51             :     /** Pull a full list of peers from vNodes into our cache */
      52           0 :     void refreshPeers()
      53             :     {
      54             :         {
      55           0 :             TRY_LOCK(cs_vNodes, lockNodes);
      56           0 :             if (!lockNodes)
      57             :             {
      58             :                 // skip the refresh if we can't immediately get the lock
      59           0 :                 return;
      60             :             }
      61           0 :             cachedNodeStats.clear();
      62             : #if QT_VERSION >= 0x040700
      63           0 :             cachedNodeStats.reserve(vNodes.size());
      64             : #endif
      65           0 :             Q_FOREACH (CNode* pnode, vNodes)
      66             :             {
      67             :                 CNodeCombinedStats stats;
      68           0 :                 stats.nodeStateStats.nMisbehavior = 0;
      69           0 :                 stats.nodeStateStats.nSyncHeight = -1;
      70           0 :                 stats.nodeStateStats.nCommonHeight = -1;
      71           0 :                 stats.fNodeStateStatsAvailable = false;
      72           0 :                 pnode->copyStats(stats.nodeStats);
      73           0 :                 cachedNodeStats.append(stats);
      74           0 :             }
      75             :         }
      76             : 
      77             :         // Try to retrieve the CNodeStateStats for each node.
      78             :         {
      79           0 :             TRY_LOCK(cs_main, lockMain);
      80           0 :             if (lockMain)
      81             :             {
      82           0 :                 BOOST_FOREACH(CNodeCombinedStats &stats, cachedNodeStats)
      83           0 :                     stats.fNodeStateStatsAvailable = GetNodeStateStats(stats.nodeStats.nodeid, stats.nodeStateStats);
      84             :             }
      85             :         }
      86             : 
      87           0 :         if (sortColumn >= 0)
      88             :             // sort cacheNodeStats (use stable sort to prevent rows jumping around unneceesarily)
      89           0 :             qStableSort(cachedNodeStats.begin(), cachedNodeStats.end(), NodeLessThan(sortColumn, sortOrder));
      90             : 
      91             :         // build index map
      92           0 :         mapNodeRows.clear();
      93           0 :         int row = 0;
      94           0 :         Q_FOREACH (const CNodeCombinedStats& stats, cachedNodeStats)
      95           0 :             mapNodeRows.insert(std::pair<NodeId, int>(stats.nodeStats.nodeid, row++));
      96             :     }
      97             : 
      98             :     int size() const
      99             :     {
     100           0 :         return cachedNodeStats.size();
     101             :     }
     102             : 
     103           0 :     CNodeCombinedStats *index(int idx)
     104             :     {
     105           0 :         if (idx >= 0 && idx < cachedNodeStats.size())
     106           0 :             return &cachedNodeStats[idx];
     107             : 
     108             :         return 0;
     109             :     }
     110             : };
     111             : 
     112           0 : PeerTableModel::PeerTableModel(ClientModel *parent) :
     113             :     QAbstractTableModel(parent),
     114             :     clientModel(parent),
     115           0 :     timer(0)
     116             : {
     117           0 :     columns << tr("Node/Service") << tr("User Agent") << tr("Ping Time");
     118           0 :     priv = new PeerTablePriv();
     119             :     // default to unsorted
     120           0 :     priv->sortColumn = -1;
     121             : 
     122             :     // set up timer for auto refresh
     123           0 :     timer = new QTimer();
     124           0 :     connect(timer, SIGNAL(timeout()), SLOT(refresh()));
     125           0 :     timer->setInterval(MODEL_UPDATE_DELAY);
     126             : 
     127             :     // load initial data
     128           0 :     refresh();
     129           0 : }
     130             : 
     131           0 : void PeerTableModel::startAutoRefresh()
     132             : {
     133           0 :     timer->start();
     134           0 : }
     135             : 
     136           0 : void PeerTableModel::stopAutoRefresh()
     137             : {
     138           0 :     timer->stop();
     139           0 : }
     140             : 
     141           0 : int PeerTableModel::rowCount(const QModelIndex &parent) const
     142             : {
     143             :     Q_UNUSED(parent);
     144           0 :     return priv->size();
     145             : }
     146             : 
     147           0 : int PeerTableModel::columnCount(const QModelIndex &parent) const
     148             : {
     149             :     Q_UNUSED(parent);
     150           0 :     return columns.length();;
     151             : }
     152             : 
     153           0 : QVariant PeerTableModel::data(const QModelIndex &index, int role) const
     154             : {
     155           0 :     if(!index.isValid())
     156             :         return QVariant();
     157             : 
     158           0 :     CNodeCombinedStats *rec = static_cast<CNodeCombinedStats*>(index.internalPointer());
     159             : 
     160           0 :     if (role == Qt::DisplayRole) {
     161           0 :         switch(index.column())
     162             :         {
     163             :         case Address:
     164           0 :             return QString::fromStdString(rec->nodeStats.addrName);
     165             :         case Subversion:
     166           0 :             return QString::fromStdString(rec->nodeStats.cleanSubVer);
     167             :         case Ping:
     168           0 :             return GUIUtil::formatPingTime(rec->nodeStats.dPingTime);
     169             :         }
     170           0 :     } else if (role == Qt::TextAlignmentRole) {
     171           0 :         if (index.column() == Ping)
     172           0 :             return (QVariant)(Qt::AlignRight | Qt::AlignVCenter);
     173             :     }
     174             : 
     175             :     return QVariant();
     176             : }
     177             : 
     178           0 : QVariant PeerTableModel::headerData(int section, Qt::Orientation orientation, int role) const
     179             : {
     180           0 :     if(orientation == Qt::Horizontal)
     181             :     {
     182           0 :         if(role == Qt::DisplayRole && section < columns.size())
     183             :         {
     184           0 :             return columns[section];
     185             :         }
     186             :     }
     187             :     return QVariant();
     188             : }
     189             : 
     190           0 : Qt::ItemFlags PeerTableModel::flags(const QModelIndex &index) const
     191             : {
     192           0 :     if(!index.isValid())
     193             :         return 0;
     194             : 
     195             :     Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
     196             :     return retval;
     197             : }
     198             : 
     199           0 : QModelIndex PeerTableModel::index(int row, int column, const QModelIndex &parent) const
     200             : {
     201             :     Q_UNUSED(parent);
     202           0 :     CNodeCombinedStats *data = priv->index(row);
     203             : 
     204           0 :     if (data)
     205           0 :         return createIndex(row, column, data);
     206             :     return QModelIndex();
     207             : }
     208             : 
     209           0 : const CNodeCombinedStats *PeerTableModel::getNodeStats(int idx)
     210             : {
     211           0 :     return priv->index(idx);
     212             : }
     213             : 
     214           0 : void PeerTableModel::refresh()
     215             : {
     216           0 :     Q_EMIT layoutAboutToBeChanged();
     217           0 :     priv->refreshPeers();
     218           0 :     Q_EMIT layoutChanged();
     219           0 : }
     220             : 
     221           0 : int PeerTableModel::getRowByNodeId(NodeId nodeid)
     222             : {
     223           0 :     std::map<NodeId, int>::iterator it = priv->mapNodeRows.find(nodeid);
     224           0 :     if (it == priv->mapNodeRows.end())
     225             :         return -1;
     226             : 
     227           0 :     return it->second;
     228             : }
     229             : 
     230           0 : void PeerTableModel::sort(int column, Qt::SortOrder order)
     231             : {
     232           0 :     priv->sortColumn = column;
     233           0 :     priv->sortOrder = order;
     234           0 :     refresh();
     235           0 : }

Generated by: LCOV version 1.11