mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-09-19 20:34:49 -04:00
Renamed some defines
Added background color for RTT stats graph Moved statistics pages to statistics folder git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7522 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
938b95c8fe
commit
1fdd6d6447
24 changed files with 32 additions and 33 deletions
378
retroshare-gui/src/gui/statistics/BwCtrlWindow.cpp
Normal file
378
retroshare-gui/src/gui/statistics/BwCtrlWindow.cpp
Normal file
|
@ -0,0 +1,378 @@
|
|||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 2012 Robert Fernie
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
****************************************************************/
|
||||
|
||||
#include "BwCtrlWindow.h"
|
||||
#include "ui_BwCtrlWindow.h"
|
||||
#include <QTimer>
|
||||
#include <QDateTime>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <time.h>
|
||||
|
||||
#include "retroshare-gui/RsAutoUpdatePage.h"
|
||||
#include "retroshare/rsconfig.h"
|
||||
#include "retroshare/rspeers.h"
|
||||
|
||||
#include <QModelIndex>
|
||||
#include <QPainter>
|
||||
#include <limits>
|
||||
|
||||
BWListDelegate::BWListDelegate(QObject *parent) : QAbstractItemDelegate(parent)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
BWListDelegate::~BWListDelegate(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
void BWListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
|
||||
{
|
||||
QString strNA = tr("N/A");
|
||||
QStyleOptionViewItem opt = option;
|
||||
|
||||
QString temp ;
|
||||
float flValue;
|
||||
qint64 qi64Value;
|
||||
|
||||
// prepare
|
||||
painter->save();
|
||||
painter->setClipRect(opt.rect);
|
||||
|
||||
//set text color
|
||||
QVariant value = index.data(Qt::TextColorRole);
|
||||
if(value.isValid() && qvariant_cast<QColor>(value).isValid()) {
|
||||
opt.palette.setColor(QPalette::Text, qvariant_cast<QColor>(value));
|
||||
}
|
||||
QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
|
||||
if(option.state & QStyle::State_Selected){
|
||||
painter->setPen(opt.palette.color(cg, QPalette::HighlightedText));
|
||||
} else {
|
||||
painter->setPen(opt.palette.color(cg, QPalette::Text));
|
||||
}
|
||||
|
||||
// draw the background color
|
||||
if(option.showDecorationSelected && (option.state & QStyle::State_Selected)) {
|
||||
if(cg == QPalette::Normal && !(option.state & QStyle::State_Active)) {
|
||||
cg = QPalette::Inactive;
|
||||
}
|
||||
painter->fillRect(option.rect, option.palette.brush(cg, QPalette::Highlight));
|
||||
} else {
|
||||
value = index.data(Qt::BackgroundRole);
|
||||
if(value.isValid() && qvariant_cast<QColor>(value).isValid()) {
|
||||
painter->fillRect(option.rect, qvariant_cast<QColor>(value));
|
||||
}
|
||||
}
|
||||
|
||||
switch(index.column()) {
|
||||
case COLUMN_IN_RATE:
|
||||
temp.sprintf("%.3f ", index.data().toFloat());
|
||||
//temp=QString::number(index.data().toFloat());
|
||||
painter->drawText(option.rect, Qt::AlignRight, temp);
|
||||
break;
|
||||
case COLUMN_IN_MAX:
|
||||
temp.sprintf("%.3f ", index.data().toFloat());
|
||||
//temp=QString::number(index.data().toFloat());
|
||||
painter->drawText(option.rect, Qt::AlignRight, temp);
|
||||
break;
|
||||
case COLUMN_IN_QUEUE:
|
||||
temp=QString::number(index.data().toInt());
|
||||
painter->drawText(option.rect, Qt::AlignRight, temp);
|
||||
break;
|
||||
case COLUMN_IN_ALLOC:
|
||||
flValue = index.data().toFloat();
|
||||
if (flValue < std::numeric_limits<float>::max()){
|
||||
temp.sprintf("%.3f ", flValue);
|
||||
} else {
|
||||
temp=strNA;
|
||||
}
|
||||
painter->drawText(option.rect, Qt::AlignRight, temp);
|
||||
break;
|
||||
case COLUMN_IN_ALLOC_SENT:
|
||||
qi64Value = index.data().value<qint64>();
|
||||
if (qi64Value < std::numeric_limits<qint64>::max()){
|
||||
temp= QString::number(qi64Value);
|
||||
} else {
|
||||
temp = strNA;
|
||||
}
|
||||
painter->drawText(option.rect, Qt::AlignRight, temp);
|
||||
break;
|
||||
case COLUMN_OUT_RATE:
|
||||
temp.sprintf("%.3f ", index.data().toFloat());
|
||||
//temp=QString::number(index.data().toFloat());
|
||||
painter->drawText(option.rect, Qt::AlignRight, temp);
|
||||
break;
|
||||
case COLUMN_OUT_MAX:
|
||||
temp.sprintf("%.3f ", index.data().toFloat());
|
||||
//temp=QString::number(index.data().toFloat());
|
||||
painter->drawText(option.rect, Qt::AlignRight, temp);
|
||||
break;
|
||||
case COLUMN_OUT_QUEUE:
|
||||
temp=QString::number(index.data().toInt());
|
||||
painter->drawText(option.rect, Qt::AlignRight, temp);
|
||||
break;
|
||||
case COLUMN_OUT_ALLOC:
|
||||
flValue = index.data().toFloat();
|
||||
if (flValue < std::numeric_limits<float>::max()){
|
||||
temp=QString::number(flValue);
|
||||
} else {
|
||||
temp = strNA;
|
||||
}
|
||||
painter->drawText(option.rect, Qt::AlignRight, temp);
|
||||
break;
|
||||
case COLUMN_OUT_ALLOC_SENT:
|
||||
qi64Value = index.data().value<qint64>();
|
||||
if (qi64Value < std::numeric_limits<qint64>::max()){
|
||||
temp= QString::number(qi64Value);
|
||||
} else {
|
||||
temp = strNA;
|
||||
}
|
||||
painter->drawText(option.rect, Qt::AlignRight, temp);
|
||||
break;
|
||||
default:
|
||||
painter->drawText(option.rect, Qt::AlignLeft, index.data().toString());
|
||||
}
|
||||
|
||||
// done
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
QSize BWListDelegate::sizeHint(const QStyleOptionViewItem & /*option*/, const QModelIndex & /*index*/) const
|
||||
{
|
||||
return QSize(50,17);
|
||||
}
|
||||
|
||||
|
||||
BwCtrlWindow::BwCtrlWindow(QWidget *parent)
|
||||
: RsAutoUpdatePage(1000,parent)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
|
||||
BWDelegate = new BWListDelegate();
|
||||
bwTreeWidget->setItemDelegate(BWDelegate);
|
||||
|
||||
/* Set header resize modes and initial section sizes Peer TreeView*/
|
||||
QHeaderView * _header = bwTreeWidget->header () ;
|
||||
_header->resizeSection ( COLUMN_RSNAME, 170 );
|
||||
|
||||
|
||||
}
|
||||
|
||||
BwCtrlWindow::~BwCtrlWindow()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BwCtrlWindow::updateDisplay()
|
||||
{
|
||||
|
||||
/* do nothing if locked, or not visible */
|
||||
if (RsAutoUpdatePage::eventsLocked() == true)
|
||||
{
|
||||
#ifdef DEBUG_BWCTRLWINDOW
|
||||
std::cerr << "BwCtrlWindow::update() events Are Locked" << std::endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rsConfig)
|
||||
{
|
||||
#ifdef DEBUG_BWCTRLWINDOW
|
||||
std::cerr << "BwCtrlWindow::update rsConfig NOT Set" << std::endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
RsAutoUpdatePage::lockAllEvents();
|
||||
|
||||
//std::cerr << "BwCtrlWindow::update()" << std::endl;
|
||||
updateBandwidth();
|
||||
|
||||
RsAutoUpdatePage::unlockAllEvents() ;
|
||||
}
|
||||
|
||||
void BwCtrlWindow::updateBandwidth()
|
||||
{
|
||||
QTreeWidget *peerTreeWidget = bwTreeWidget;
|
||||
|
||||
peerTreeWidget->clear();
|
||||
|
||||
RsConfigDataRates totalRates;
|
||||
std::map<RsPeerId, RsConfigDataRates> rateMap;
|
||||
std::map<RsPeerId, RsConfigDataRates>::iterator it;
|
||||
|
||||
rsConfig->getTotalBandwidthRates(totalRates);
|
||||
rsConfig->getAllBandwidthRates(rateMap);
|
||||
|
||||
/* insert */
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||
peerTreeWidget->addTopLevelItem(item);
|
||||
peerTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
|
||||
updateGraph(totalRates.mRateIn,totalRates.mRateOut);
|
||||
|
||||
/* do Totals */
|
||||
item -> setData(COLUMN_PEERID, Qt::DisplayRole, tr("TOTALS"));
|
||||
item -> setData(COLUMN_RSNAME, Qt::DisplayRole, tr("Totals"));
|
||||
|
||||
item -> setData(COLUMN_IN_RATE, Qt::DisplayRole, totalRates.mRateIn);
|
||||
item -> setData(COLUMN_IN_MAX, Qt::DisplayRole,totalRates.mRateMaxIn);
|
||||
item -> setData(COLUMN_IN_QUEUE, Qt::DisplayRole, totalRates.mQueueIn);
|
||||
item -> setData(COLUMN_IN_ALLOC, Qt::DisplayRole, std::numeric_limits<float>::max());
|
||||
item -> setData(COLUMN_IN_ALLOC_SENT, Qt::DisplayRole, std::numeric_limits<qint64>::max());
|
||||
|
||||
item -> setData(COLUMN_OUT_RATE, Qt::DisplayRole, totalRates.mRateOut);
|
||||
item -> setData(COLUMN_OUT_MAX, Qt::DisplayRole, totalRates.mRateMaxOut);
|
||||
item -> setData(COLUMN_OUT_QUEUE, Qt::DisplayRole, totalRates.mQueueOut);
|
||||
item -> setData(COLUMN_OUT_ALLOC, Qt::DisplayRole, std::numeric_limits<float>::max());
|
||||
item -> setData(COLUMN_OUT_ALLOC_SENT, Qt::DisplayRole, std::numeric_limits<qint64>::max());
|
||||
|
||||
time_t now = time(NULL);
|
||||
for(it = rateMap.begin(); it != rateMap.end(); it++)
|
||||
{
|
||||
/* find the entry */
|
||||
QTreeWidgetItem *peer_item = NULL;
|
||||
#if 0
|
||||
QString qpeerid = QString::fromStdString(*it);
|
||||
int itemCount = peerTreeWidget->topLevelItemCount();
|
||||
for (int nIndex = 0; nIndex < itemCount; nIndex++)
|
||||
{
|
||||
QTreeWidgetItem *tmp_item = peerTreeWidget->topLevelItem(nIndex);
|
||||
if (tmp_item->data(COLUMN_PEERID, Qt::DisplayRole).toString() == qpeerid)
|
||||
{
|
||||
peer_item = tmp_item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!peer_item)
|
||||
{
|
||||
/* insert */
|
||||
peer_item = new QTreeWidgetItem();
|
||||
peerTreeWidget->addTopLevelItem(peer_item);
|
||||
}
|
||||
|
||||
std::string name = rsPeers->getPeerName(it->first);
|
||||
|
||||
peer_item -> setData(COLUMN_PEERID, Qt::DisplayRole, QString::fromStdString(it->first.toStdString()));
|
||||
peer_item -> setData(COLUMN_RSNAME, Qt::DisplayRole, QString::fromStdString(name));
|
||||
|
||||
peer_item -> setData(COLUMN_IN_RATE, Qt::DisplayRole, it->second.mRateIn);
|
||||
peer_item -> setData(COLUMN_IN_MAX, Qt::DisplayRole, it->second.mRateMaxIn);
|
||||
peer_item -> setData(COLUMN_IN_QUEUE, Qt::DisplayRole, it->second.mQueueIn);
|
||||
peer_item -> setData(COLUMN_IN_ALLOC, Qt::DisplayRole, it->second.mAllocIn);
|
||||
peer_item -> setData(COLUMN_IN_ALLOC_SENT, Qt::DisplayRole, qint64(now - it->second.mAllocTs));
|
||||
|
||||
peer_item -> setData(COLUMN_OUT_RATE, Qt::DisplayRole, it->second.mRateOut);
|
||||
peer_item -> setData(COLUMN_OUT_MAX, Qt::DisplayRole, it->second.mRateMaxOut);
|
||||
peer_item -> setData(COLUMN_OUT_QUEUE, Qt::DisplayRole, it->second.mQueueOut);
|
||||
if (it->second.mAllowedTs != 0)
|
||||
{
|
||||
peer_item -> setData(COLUMN_OUT_ALLOC, Qt::DisplayRole, it->second.mAllowedOut);
|
||||
peer_item -> setData(COLUMN_OUT_ALLOC_SENT, Qt::DisplayRole,qint64(now - it->second.mAllowedTs));
|
||||
}
|
||||
else
|
||||
{
|
||||
peer_item -> setData(COLUMN_OUT_ALLOC, Qt::DisplayRole, std::numeric_limits<float>::max());
|
||||
peer_item -> setData(COLUMN_OUT_ALLOC_SENT, Qt::DisplayRole, std::numeric_limits<qint64>::max());
|
||||
}
|
||||
|
||||
|
||||
/* colour the columns */
|
||||
if (it->second.mAllowedTs != 0)
|
||||
{
|
||||
if (it->second.mAllowedOut < it->second.mRateOut)
|
||||
{
|
||||
/* RED */
|
||||
QColor bc("#ff4444"); // red
|
||||
peer_item -> setBackground(COLUMN_OUT_RATE,QBrush(bc));
|
||||
|
||||
}
|
||||
else if (it->second.mAllowedOut < it->second.mRateMaxOut)
|
||||
{
|
||||
/* YELLOW */
|
||||
QColor bc("#ffff66"); // yellow
|
||||
peer_item -> setBackground(COLUMN_OUT_MAX,QBrush(bc));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* GREEN */
|
||||
QColor bc("#44ff44");//bright green
|
||||
peer_item -> setBackground(COLUMN_OUT_ALLOC,QBrush(bc));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* GRAY */
|
||||
QColor bc("#444444");// gray
|
||||
peer_item -> setBackground(COLUMN_OUT_ALLOC,QBrush(bc));
|
||||
peer_item -> setBackground(COLUMN_OUT_ALLOC_SENT,QBrush(bc));
|
||||
|
||||
}
|
||||
|
||||
/* queueOut */
|
||||
#define QUEUE_RED 10000
|
||||
#define QUEUE_ORANGE 2000
|
||||
#define QUEUE_YELLOW 500
|
||||
|
||||
if (it->second.mQueueOut > QUEUE_RED)
|
||||
{
|
||||
/* RED */
|
||||
QColor bc("#ff4444"); // red
|
||||
peer_item -> setBackground(COLUMN_OUT_QUEUE,QBrush(bc));
|
||||
|
||||
}
|
||||
else if (it->second.mQueueOut > QUEUE_ORANGE)
|
||||
{
|
||||
/* ORANGE */
|
||||
QColor bc("#ff9900"); //orange
|
||||
peer_item -> setBackground(COLUMN_OUT_QUEUE,QBrush(bc));
|
||||
|
||||
}
|
||||
else if (it->second.mQueueOut > QUEUE_YELLOW)
|
||||
{
|
||||
/* YELLOW */
|
||||
QColor bc("#ffff66"); // yellow
|
||||
peer_item -> setBackground(COLUMN_OUT_QUEUE,QBrush(bc));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* GREEN */
|
||||
QColor bc("#44ff44");//bright green
|
||||
peer_item -> setBackground(COLUMN_OUT_QUEUE,QBrush(bc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Adds new data to the graph. */
|
||||
void BwCtrlWindow::updateGraph(qreal bytesRead, qreal bytesWritten)
|
||||
{
|
||||
/* Graph only cares about kilobytes */
|
||||
frmGraph->addPoints(bytesRead/*/1024.0*/, bytesWritten/*/1024.0*/);
|
||||
}
|
||||
|
94
retroshare-gui/src/gui/statistics/BwCtrlWindow.h
Normal file
94
retroshare-gui/src/gui/statistics/BwCtrlWindow.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
#ifndef RSBWCTRL_WINDOW_H
|
||||
#define RSBWCTRL_WINDOW_H
|
||||
|
||||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 2012 Robert Fernie
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
****************************************************************/
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
#include <QAbstractItemDelegate>
|
||||
|
||||
#include "RsAutoUpdatePage.h"
|
||||
#include "ui_BwCtrlWindow.h"
|
||||
|
||||
// Defines for download list list columns
|
||||
#define COLUMN_RSNAME 0
|
||||
#define COLUMN_PEERID 1
|
||||
#define COLUMN_IN_RATE 2
|
||||
#define COLUMN_IN_MAX 3
|
||||
#define COLUMN_IN_QUEUE 4
|
||||
#define COLUMN_IN_ALLOC 5
|
||||
#define COLUMN_IN_ALLOC_SENT 6
|
||||
#define COLUMN_OUT_RATE 7
|
||||
#define COLUMN_OUT_MAX 8
|
||||
#define COLUMN_OUT_QUEUE 9
|
||||
#define COLUMN_OUT_ALLOC 10
|
||||
#define COLUMN_OUT_ALLOC_SENT 11
|
||||
#define COLUMN_ALLOWED RECVD 12
|
||||
#define COLUMN_COUNT 13
|
||||
|
||||
|
||||
class QModelIndex;
|
||||
class QPainter;
|
||||
|
||||
class BWListDelegate: public QAbstractItemDelegate {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BWListDelegate(QObject *parent=0);
|
||||
~BWListDelegate();
|
||||
void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
|
||||
QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const;
|
||||
|
||||
private:
|
||||
|
||||
public slots:
|
||||
|
||||
signals:
|
||||
};
|
||||
|
||||
class BwCtrlWindow : public RsAutoUpdatePage, public Ui::BwCtrlWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
BwCtrlWindow(QWidget *parent = 0);
|
||||
~BwCtrlWindow();
|
||||
|
||||
void updateBandwidth();
|
||||
|
||||
public slots:
|
||||
virtual void updateDisplay() ;
|
||||
|
||||
/** Adds new data to the graph */
|
||||
void updateGraph(qreal bytesRead, qreal bytesWritten);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
|
||||
|
||||
BWListDelegate *BWDelegate;
|
||||
|
||||
};
|
||||
|
||||
#endif // RSBWCTRL_WINDOW_H
|
||||
|
123
retroshare-gui/src/gui/statistics/BwCtrlWindow.ui
Normal file
123
retroshare-gui/src/gui/statistics/BwCtrlWindow.ui
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BwCtrlWindow</class>
|
||||
<widget class="QWidget" name="BwCtrlWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>597</width>
|
||||
<height>469</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QTreeWidget" name="bwTreeWidget">
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>ID</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>In (KB/s)</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>InMax (KB/s)</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>InQueue</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>InAllocated (KB/s)</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Allocated Sent</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Out (KB/s)</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>OutMax (KB/s)</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>OutQueue</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>OutAllowed (KB/s)</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Allowed Recvd</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
<widget class="GraphFrame" name="frmGraph">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>80</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::NoContextMenu</enum>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>GraphFrame</class>
|
||||
<extends>QFrame</extends>
|
||||
<header>gui/graphframe.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
705
retroshare-gui/src/gui/statistics/DhtWindow.cpp
Normal file
705
retroshare-gui/src/gui/statistics/DhtWindow.cpp
Normal file
|
@ -0,0 +1,705 @@
|
|||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 2011 Robert Fernie
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
****************************************************************/
|
||||
|
||||
#include "DhtWindow.h"
|
||||
#include "ui_DhtWindow.h"
|
||||
|
||||
#include <QTimer>
|
||||
#include <QDateTime>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <time.h>
|
||||
|
||||
#include "retroshare-gui/RsAutoUpdatePage.h"
|
||||
#include "retroshare/rsdht.h"
|
||||
#include "retroshare/rsconfig.h"
|
||||
#include "retroshare/rspeers.h"
|
||||
|
||||
DhtWindow::DhtWindow(QWidget *parent)
|
||||
: RsAutoUpdatePage(1000,parent)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
|
||||
}
|
||||
|
||||
DhtWindow::~DhtWindow()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DhtWindow::updateDisplay()
|
||||
{
|
||||
/* do nothing if locked, or not visible */
|
||||
if (RsAutoUpdatePage::eventsLocked() == true)
|
||||
{
|
||||
#ifdef DEBUG_DHTWINDOW
|
||||
std::cerr << "DhtWindow::update() events Are Locked" << std::endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rsDht)
|
||||
{
|
||||
#ifdef DEBUG_DHTWINDOW
|
||||
std::cerr << "DhtWindow::update rsDht NOT Set" << std::endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
RsAutoUpdatePage::lockAllEvents();
|
||||
|
||||
//std::cerr << "DhtWindow::update()" << std::endl;
|
||||
updateNetStatus();
|
||||
updateNetPeers();
|
||||
updateDhtPeers();
|
||||
updateRelays();
|
||||
getDHTStatus();
|
||||
|
||||
RsAutoUpdatePage::unlockAllEvents() ;
|
||||
}
|
||||
|
||||
|
||||
void DhtWindow::updateNetStatus()
|
||||
{
|
||||
|
||||
QString status;
|
||||
QString oldstatus;
|
||||
|
||||
#if 0
|
||||
status = QString::fromStdString(mPeerNet->getPeerStatusString());
|
||||
oldstatus = ui.peerLine->text();
|
||||
if (oldstatus != status)
|
||||
{
|
||||
ui.peerLine->setText(status);
|
||||
}
|
||||
#endif
|
||||
|
||||
status = QString::fromStdString(rsDht->getUdpAddressString());
|
||||
oldstatus = ui.peerAddressLabel->text();
|
||||
if (oldstatus != status)
|
||||
{
|
||||
ui.peerAddressLabel->setText(status);
|
||||
}
|
||||
|
||||
uint32_t netMode = rsConfig->getNetworkMode();
|
||||
|
||||
QLabel *label = ui.networkLabel;
|
||||
switch(netMode)
|
||||
{
|
||||
case RSNET_NETWORK_UNKNOWN:
|
||||
label->setText(tr("Unknown NetState"));
|
||||
break;
|
||||
case RSNET_NETWORK_OFFLINE:
|
||||
label->setText(tr("Offline"));
|
||||
break;
|
||||
case RSNET_NETWORK_LOCALNET:
|
||||
label->setText(tr("Local Net"));
|
||||
break;
|
||||
case RSNET_NETWORK_BEHINDNAT:
|
||||
label->setText(tr("Behind NAT"));
|
||||
break;
|
||||
case RSNET_NETWORK_EXTERNALIP:
|
||||
label->setText(tr("External IP"));
|
||||
break;
|
||||
}
|
||||
|
||||
label = ui.natTypeLabel;
|
||||
|
||||
uint32_t natType = rsConfig->getNatTypeMode();
|
||||
switch(natType)
|
||||
{
|
||||
case RSNET_NATTYPE_UNKNOWN:
|
||||
label->setText(tr("UNKNOWN NAT STATE"));
|
||||
break;
|
||||
case RSNET_NATTYPE_SYMMETRIC:
|
||||
label->setText(tr("SYMMETRIC NAT"));
|
||||
break;
|
||||
case RSNET_NATTYPE_DETERM_SYM:
|
||||
label->setText(tr("DETERMINISTIC SYM NAT"));
|
||||
break;
|
||||
case RSNET_NATTYPE_RESTRICTED_CONE:
|
||||
label->setText(tr("RESTRICTED CONE NAT"));
|
||||
break;
|
||||
case RSNET_NATTYPE_FULL_CONE:
|
||||
label->setText(tr("FULL CONE NAT"));
|
||||
break;
|
||||
case RSNET_NATTYPE_OTHER:
|
||||
label->setText(tr("OTHER NAT"));
|
||||
break;
|
||||
case RSNET_NATTYPE_NONE:
|
||||
label->setText(tr("NO NAT"));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
label = ui.natHoleLabel;
|
||||
uint32_t natHole = rsConfig->getNatHoleMode();
|
||||
|
||||
switch(natHole)
|
||||
{
|
||||
case RSNET_NATHOLE_UNKNOWN:
|
||||
label->setText(tr("UNKNOWN NAT HOLE STATUS"));
|
||||
break;
|
||||
case RSNET_NATHOLE_NONE:
|
||||
label->setText(tr("NO NAT HOLE"));
|
||||
break;
|
||||
case RSNET_NATHOLE_UPNP:
|
||||
label->setText(tr("UPNP FORWARD"));
|
||||
break;
|
||||
case RSNET_NATHOLE_NATPMP:
|
||||
label->setText(tr("NATPMP FORWARD"));
|
||||
break;
|
||||
case RSNET_NATHOLE_FORWARDED:
|
||||
label->setText(tr("MANUAL FORWARD"));
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t connect = rsConfig->getConnectModes();
|
||||
|
||||
label = ui.connectLabel;
|
||||
QString connOut;
|
||||
if (connect & RSNET_CONNECT_OUTGOING_TCP)
|
||||
{
|
||||
connOut += "TCP_OUT ";
|
||||
}
|
||||
if (connect & RSNET_CONNECT_ACCEPT_TCP)
|
||||
{
|
||||
connOut += "TCP_IN ";
|
||||
}
|
||||
if (connect & RSNET_CONNECT_DIRECT_UDP)
|
||||
{
|
||||
connOut += "DIRECT_UDP ";
|
||||
}
|
||||
if (connect & RSNET_CONNECT_PROXY_UDP)
|
||||
{
|
||||
connOut += "PROXY_UDP ";
|
||||
}
|
||||
if (connect & RSNET_CONNECT_RELAY_UDP)
|
||||
{
|
||||
connOut += "RELAY_UDP ";
|
||||
}
|
||||
|
||||
label->setText(connOut);
|
||||
|
||||
uint32_t netState = rsConfig->getNetState();
|
||||
|
||||
label = ui.netStatusLabel;
|
||||
switch(netState)
|
||||
{
|
||||
case RSNET_NETSTATE_BAD_UNKNOWN:
|
||||
label->setText(tr("NET BAD: Unknown State"));
|
||||
break;
|
||||
case RSNET_NETSTATE_BAD_OFFLINE:
|
||||
label->setText(tr("NET BAD: Offline"));
|
||||
break;
|
||||
case RSNET_NETSTATE_BAD_NATSYM:
|
||||
label->setText(tr("NET BAD: Behind Symmetric NAT"));
|
||||
break;
|
||||
case RSNET_NETSTATE_BAD_NODHT_NAT:
|
||||
label->setText(tr("NET BAD: Behind NAT & No DHT"));
|
||||
break;
|
||||
case RSNET_NETSTATE_WARNING_RESTART:
|
||||
label->setText(tr("NET WARNING: NET Restart"));
|
||||
break;
|
||||
case RSNET_NETSTATE_WARNING_NATTED:
|
||||
label->setText(tr("NET WARNING: Behind NAT"));
|
||||
break;
|
||||
case RSNET_NETSTATE_WARNING_NODHT:
|
||||
label->setText(tr("NET WARNING: No DHT"));
|
||||
break;
|
||||
case RSNET_NETSTATE_GOOD:
|
||||
label->setText(tr("NET STATE GOOD!"));
|
||||
break;
|
||||
case RSNET_NETSTATE_ADV_FORWARD:
|
||||
label->setText(tr("CAUTION: UNVERIFIABLE FORWARD!"));
|
||||
break;
|
||||
case RSNET_NETSTATE_ADV_DARK_FORWARD:
|
||||
label->setText(tr("CAUTION: UNVERIFIABLE FORWARD & NO DHT"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DhtWindow::updateNetPeers()
|
||||
{
|
||||
QTreeWidget *peerTreeWidget = ui.peerTreeWidget;
|
||||
|
||||
std::list<RsPeerId> peerIds;
|
||||
std::list<RsPeerId>::iterator it;
|
||||
|
||||
rsDht->getNetPeerList(peerIds);
|
||||
|
||||
/* collate peer stats */
|
||||
int nPeers = peerIds.size();
|
||||
|
||||
// from DHT peers
|
||||
int nOnlinePeers = 0;
|
||||
int nUnreachablePeers = 0;
|
||||
int nOfflinePeers = 0;
|
||||
|
||||
// Connect States.
|
||||
int nDisconnPeers = 0;
|
||||
int nDirectPeers = 0;
|
||||
int nProxyPeers = 0;
|
||||
int nRelayPeers = 0;
|
||||
|
||||
|
||||
#define PTW_COL_RSNAME 0
|
||||
#define PTW_COL_PEERID 1
|
||||
#define PTW_COL_DHT_STATUS 2
|
||||
|
||||
#define PTW_COL_PEER_CONNECTLOGIC 3
|
||||
|
||||
#define PTW_COL_PEER_CONNECT_STATUS 4
|
||||
#define PTW_COL_PEER_CONNECT_MODE 5
|
||||
#define PTW_COL_PEER_REQ_STATUS 6
|
||||
|
||||
#define PTW_COL_PEER_CB_MSG 7
|
||||
#define PTW_COL_RSID 8
|
||||
|
||||
#if 0
|
||||
/* clear old entries */
|
||||
int itemCount = peerTreeWidget->topLevelItemCount();
|
||||
for (int nIndex = 0; nIndex < itemCount;)
|
||||
{
|
||||
QTreeWidgetItem *tmp_item = ui.peerTreeWidget->topLevelItem(nIndex);
|
||||
std::string tmpid = tmp_item->data(PTW_COL_PEERID, Qt::DisplayRole).toString().toStdString();
|
||||
if (peerIds.end() == std::find(peerIds.begin(), peerIds.end(), tmpid))
|
||||
{
|
||||
ui.peerTreeWidget->removeItemWidget(tmp_item, 0);
|
||||
/* remove it! */
|
||||
itemCount--;
|
||||
}
|
||||
else
|
||||
{
|
||||
nIndex++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ui.peerTreeWidget->clear();
|
||||
|
||||
for(it = peerIds.begin(); it != peerIds.end(); it++)
|
||||
{
|
||||
/* find the entry */
|
||||
QTreeWidgetItem *peer_item = NULL;
|
||||
#if 0
|
||||
QString qpeerid = QString::fromStdString(*it);
|
||||
int itemCount = ui.peerTreeWidget->topLevelItemCount();
|
||||
for (int nIndex = 0; nIndex < itemCount; nIndex++)
|
||||
{
|
||||
QTreeWidgetItem *tmp_item = ui.peerTreeWidget->topLevelItem(nIndex);
|
||||
if (tmp_item->data(PTW_COL_PEERID, Qt::DisplayRole).toString() == qpeerid)
|
||||
{
|
||||
peer_item = tmp_item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!peer_item)
|
||||
{
|
||||
/* insert */
|
||||
peer_item = new QTreeWidgetItem();
|
||||
ui.peerTreeWidget->addTopLevelItem(peer_item);
|
||||
}
|
||||
|
||||
/* Set header resize modes and initial section sizes Peer TreeView*/
|
||||
QHeaderView * _header = ui.peerTreeWidget->header () ;
|
||||
_header->resizeSection ( PTW_COL_RSNAME, 170 );
|
||||
|
||||
|
||||
/* update the data */
|
||||
RsDhtNetPeer status;
|
||||
rsDht->getNetPeerStatus(*it, status);
|
||||
|
||||
std::string name = rsPeers->getPeerName(*it);
|
||||
|
||||
peer_item -> setData(PTW_COL_PEERID, Qt::DisplayRole, QString::fromStdString(status.mDhtId));
|
||||
peer_item -> setData(PTW_COL_RSNAME, Qt::DisplayRole, QString::fromStdString(name));
|
||||
peer_item -> setData(PTW_COL_RSID, Qt::DisplayRole, QString::fromStdString(status.mRsId.toStdString()));
|
||||
|
||||
QString dhtstate;
|
||||
switch(status.mDhtState)
|
||||
{
|
||||
default:
|
||||
case RSDHT_PEERDHT_NOT_ACTIVE:
|
||||
dhtstate = tr("Not Active (Maybe Connected!)");
|
||||
break;
|
||||
case RSDHT_PEERDHT_SEARCHING:
|
||||
dhtstate = tr("Searching");
|
||||
break;
|
||||
case RSDHT_PEERDHT_FAILURE:
|
||||
dhtstate = tr("Failed");
|
||||
break;
|
||||
case RSDHT_PEERDHT_OFFLINE:
|
||||
dhtstate = tr("offline");
|
||||
nOfflinePeers++;
|
||||
break;
|
||||
case RSDHT_PEERDHT_UNREACHABLE:
|
||||
dhtstate = tr("Unreachable");
|
||||
nUnreachablePeers++;
|
||||
break;
|
||||
case RSDHT_PEERDHT_ONLINE:
|
||||
dhtstate = tr("ONLINE");
|
||||
nOnlinePeers++;
|
||||
break;
|
||||
}
|
||||
|
||||
peer_item -> setData(PTW_COL_DHT_STATUS, Qt::DisplayRole, dhtstate);
|
||||
|
||||
// NOW CONNECT STATE
|
||||
QString cpmstr;
|
||||
switch(status.mPeerConnectMode)
|
||||
{
|
||||
case RSDHT_TOU_MODE_DIRECT:
|
||||
cpmstr = tr("Direct");
|
||||
break;
|
||||
case RSDHT_TOU_MODE_PROXY:
|
||||
cpmstr = tr("Proxy VIA ") + QString::fromStdString(status.mPeerConnectProxyId);
|
||||
break;
|
||||
case RSDHT_TOU_MODE_RELAY:
|
||||
cpmstr = tr("Relay VIA ") + QString::fromStdString(status.mPeerConnectProxyId);
|
||||
break;
|
||||
default:
|
||||
case RSDHT_TOU_MODE_NONE:
|
||||
cpmstr = tr("None");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
QString cpsstr;
|
||||
switch(status.mPeerConnectState)
|
||||
{
|
||||
default:
|
||||
case RSDHT_PEERCONN_DISCONNECTED:
|
||||
cpsstr = tr("Disconnected");
|
||||
nDisconnPeers++;
|
||||
break;
|
||||
case RSDHT_PEERCONN_UDP_STARTED:
|
||||
cpsstr = tr("Udp Started");
|
||||
break;
|
||||
case RSDHT_PEERCONN_CONNECTED:
|
||||
{
|
||||
cpsstr = tr("Connected");
|
||||
break;
|
||||
switch(status.mPeerConnectMode)
|
||||
{
|
||||
default:
|
||||
case RSDHT_TOU_MODE_DIRECT:
|
||||
nDirectPeers++;
|
||||
break;
|
||||
case RSDHT_TOU_MODE_PROXY:
|
||||
nProxyPeers++;
|
||||
break;
|
||||
case RSDHT_TOU_MODE_RELAY:
|
||||
nRelayPeers++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
peer_item -> setData(PTW_COL_PEER_CONNECT_STATUS, Qt::DisplayRole, cpsstr);
|
||||
|
||||
if (status.mPeerConnectState == RSDHT_PEERCONN_DISCONNECTED)
|
||||
{
|
||||
peer_item -> setData(PTW_COL_PEER_CONNECT_MODE, Qt::DisplayRole, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
peer_item -> setData(PTW_COL_PEER_CONNECT_MODE, Qt::DisplayRole, cpmstr);
|
||||
}
|
||||
|
||||
// NOW REQ STATE.
|
||||
QString reqstr;
|
||||
if (status.mExclusiveProxyLock)
|
||||
{
|
||||
reqstr = "(E) ";
|
||||
}
|
||||
switch(status.mPeerReqState)
|
||||
{
|
||||
case RSDHT_PEERREQ_RUNNING:
|
||||
reqstr += tr("Request Active");
|
||||
break;
|
||||
case RSDHT_PEERREQ_STOPPED:
|
||||
reqstr += tr("No Request");
|
||||
break;
|
||||
default:
|
||||
reqstr += tr("Unknown");
|
||||
break;
|
||||
}
|
||||
peer_item -> setData(PTW_COL_PEER_REQ_STATUS, Qt::DisplayRole, reqstr);
|
||||
|
||||
peer_item -> setData(PTW_COL_PEER_CB_MSG, Qt::DisplayRole, QString::fromStdString(status.mCbPeerMsg));
|
||||
peer_item -> setData(PTW_COL_PEER_CONNECTLOGIC, Qt::DisplayRole,
|
||||
QString::fromStdString(status.mConnectState));
|
||||
}
|
||||
|
||||
|
||||
/*QString connstr;
|
||||
connstr = tr("#Peers: ") + QString::number(nPeers);
|
||||
connstr += tr(" DHT: (#off:") + QString::number(nOfflinePeers);
|
||||
connstr += tr(",unreach:") + QString::number(nUnreachablePeers);
|
||||
connstr += tr(",online:") + QString::number(nOnlinePeers);
|
||||
connstr += tr(") Connections: (#dis:") + QString::number(nDisconnPeers);
|
||||
connstr += tr(",#dir:") + QString::number(nDirectPeers);
|
||||
connstr += tr(",#proxy:") + QString::number(nProxyPeers);
|
||||
connstr += tr(",#relay:") + QString::number(nRelayPeers);
|
||||
connstr += ")";*/
|
||||
|
||||
ui.label_peers->setText(QString::number(nPeers));
|
||||
ui.label_offline->setText(QString::number(nOfflinePeers));
|
||||
ui.label_unreachable->setText(QString::number(nUnreachablePeers));
|
||||
ui.label_online->setText(QString::number(nOnlinePeers));
|
||||
|
||||
ui.label_disconnected->setText(QString::number(nDisconnPeers));
|
||||
ui.label_direct->setText(QString::number(nDirectPeers));
|
||||
ui.label_proxy->setText(QString::number(nProxyPeers));
|
||||
ui.label_relay->setText(QString::number(nRelayPeers));
|
||||
|
||||
//peerSummaryLabel->setText(connstr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DhtWindow::updateRelays()
|
||||
{
|
||||
|
||||
QTreeWidget *relayTreeWidget = ui.relayTreeWidget;
|
||||
|
||||
std::list<RsDhtRelayEnd> relayEnds;
|
||||
std::list<RsDhtRelayProxy> relayProxies;
|
||||
|
||||
std::list<RsDhtRelayEnd>::iterator reit;
|
||||
std::list<RsDhtRelayProxy>::iterator rpit;
|
||||
|
||||
rsDht->getRelayEnds(relayEnds);
|
||||
rsDht->getRelayProxies(relayProxies);
|
||||
|
||||
|
||||
#define RTW_COL_TYPE 0
|
||||
#define RTW_COL_SRC 1
|
||||
#define RTW_COL_PROXY 2
|
||||
#define RTW_COL_DEST 3
|
||||
#define RTW_COL_CLASS 4
|
||||
#define RTW_COL_AGE 5
|
||||
#define RTW_COL_LASTSEND 6
|
||||
#define RTW_COL_BANDWIDTH 7
|
||||
|
||||
relayTreeWidget->clear();
|
||||
time_t now = time(NULL);
|
||||
|
||||
for(reit = relayEnds.begin(); reit != relayEnds.end(); reit++)
|
||||
{
|
||||
/* find the entry */
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||
ui.relayTreeWidget->addTopLevelItem(item);
|
||||
|
||||
QString typestr = tr("RELAY END");
|
||||
QString srcstr = tr("Yourself");
|
||||
QString proxystr = QString::fromStdString(reit->mProxyAddr);
|
||||
QString deststr = QString::fromStdString(reit->mRemoteAddr);
|
||||
QString agestr = tr("unknown");
|
||||
QString lastsendstr = tr("unknown");
|
||||
QString bandwidthstr = tr("unlimited");
|
||||
QString classstr = tr("Own Relay");
|
||||
|
||||
//std::ostringstream dhtupdatestr;
|
||||
//dhtupdatestr << now - status.mDhtUpdateTS << " secs ago";
|
||||
|
||||
item -> setData(RTW_COL_TYPE, Qt::DisplayRole, typestr);
|
||||
item -> setData(RTW_COL_SRC, Qt::DisplayRole, srcstr);
|
||||
item -> setData(RTW_COL_PROXY, Qt::DisplayRole, proxystr);
|
||||
item -> setData(RTW_COL_DEST, Qt::DisplayRole, deststr);
|
||||
item -> setData(RTW_COL_CLASS, Qt::DisplayRole, classstr);
|
||||
item -> setData(RTW_COL_AGE, Qt::DisplayRole, agestr);
|
||||
item -> setData(RTW_COL_LASTSEND, Qt::DisplayRole, lastsendstr);
|
||||
item -> setData(RTW_COL_BANDWIDTH, Qt::DisplayRole, bandwidthstr);
|
||||
|
||||
}
|
||||
|
||||
|
||||
for(rpit = relayProxies.begin(); rpit != relayProxies.end(); rpit++)
|
||||
{
|
||||
/* find the entry */
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||
ui.relayTreeWidget->addTopLevelItem(item);
|
||||
|
||||
QString typestr = tr("RELAY PROXY");
|
||||
QString srcstr = QString::fromStdString(rpit->mSrcAddr);
|
||||
QString proxystr = tr("Yourself");
|
||||
QString deststr = QString::fromStdString(rpit->mDestAddr);
|
||||
QString agestr = QString(tr("%1 secs ago")).arg(now - rpit->mCreateTS);
|
||||
QString lastsendstr = QString(tr("%1 secs ago")).arg(now - rpit->mLastTS);
|
||||
QString bandwidthstr = QString(tr("%1B/s")).arg(QString::number(rpit->mBandwidth));
|
||||
QString classstr = QString::number(rpit->mRelayClass);
|
||||
|
||||
item -> setData(RTW_COL_TYPE, Qt::DisplayRole, typestr);
|
||||
item -> setData(RTW_COL_SRC, Qt::DisplayRole, srcstr);
|
||||
item -> setData(RTW_COL_PROXY, Qt::DisplayRole, proxystr);
|
||||
item -> setData(RTW_COL_DEST, Qt::DisplayRole, deststr);
|
||||
item -> setData(RTW_COL_CLASS, Qt::DisplayRole, classstr);
|
||||
item -> setData(RTW_COL_AGE, Qt::DisplayRole, agestr);
|
||||
item -> setData(RTW_COL_LASTSEND, Qt::DisplayRole, lastsendstr);
|
||||
item -> setData(RTW_COL_BANDWIDTH, Qt::DisplayRole, bandwidthstr);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************/
|
||||
|
||||
|
||||
#define DTW_COL_BUCKET 0
|
||||
#define DTW_COL_IPADDR 1
|
||||
#define DTW_COL_PEERID 2
|
||||
#define DTW_COL_FLAGS 3
|
||||
#define DTW_COL_FOUND 4
|
||||
#define DTW_COL_SEND 5
|
||||
#define DTW_COL_RECV 6
|
||||
|
||||
class DhtTreeWidgetItem : public QTreeWidgetItem
|
||||
{
|
||||
public:
|
||||
virtual bool operator<(const QTreeWidgetItem &other) const
|
||||
{
|
||||
int column = treeWidget()->sortColumn();
|
||||
if (column == DTW_COL_RECV || column == DTW_COL_SEND
|
||||
|| column == DTW_COL_BUCKET)
|
||||
{
|
||||
QString t1 = text(column);
|
||||
QString t2 = other.text(column);
|
||||
t1 = t1.left(t1.indexOf(' '));
|
||||
t2 = t2.left(t2.indexOf(' '));
|
||||
return t1.toLong() < t2.toLong();
|
||||
}
|
||||
return text(column) < other.text(column);
|
||||
}
|
||||
};
|
||||
|
||||
void DhtWindow::updateDhtPeers()
|
||||
{
|
||||
|
||||
/* Hackish display of all Dht peers, should be split into buckets (as children) */
|
||||
//QString status = QString::fromStdString(mPeerNet->getDhtStatusString());
|
||||
//dhtLabel->setText(status);
|
||||
|
||||
std::list<RsDhtPeer> allpeers;
|
||||
std::list<RsDhtPeer>::iterator it;
|
||||
int i;
|
||||
for(i = 0; i < 160; i++)
|
||||
{
|
||||
std::list<RsDhtPeer> peers;
|
||||
rsDht->getDhtPeers(i, peers);
|
||||
|
||||
for(it = peers.begin(); it != peers.end(); it++)
|
||||
{
|
||||
allpeers.push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
QTreeWidget *dhtTreeWidget = ui.dhtTreeWidget;
|
||||
|
||||
ui.dhtTreeWidget->clear();
|
||||
|
||||
time_t now = time(NULL);
|
||||
for(it = allpeers.begin(); it != allpeers.end(); it++)
|
||||
{
|
||||
/* find the entry */
|
||||
QTreeWidgetItem *dht_item = NULL;
|
||||
|
||||
/* insert */
|
||||
dht_item = new DhtTreeWidgetItem();
|
||||
|
||||
QString buckstr = QString::number(it->mBucket);
|
||||
QString ipstr = QString::fromStdString(it->mAddr);
|
||||
QString idstr = QString::fromStdString(it->mDhtId);
|
||||
QString flagsstr = QString(tr("0x%1 EX:0x%2")).arg(it->mPeerFlags, 0, 16, QChar('0')).arg(it->mExtraFlags, 0, 16, QChar('0'));
|
||||
QString foundstr = QString(tr("%1 secs ago")).arg(now - it->mFoundTime);
|
||||
|
||||
QString lastsendstr;
|
||||
if (it->mLastSendTime == 0)
|
||||
{
|
||||
lastsendstr = tr("never");
|
||||
}
|
||||
else
|
||||
{
|
||||
lastsendstr = QString (tr("%1 secs ago")).arg(now - it->mLastSendTime);
|
||||
}
|
||||
|
||||
QString lastrecvstr = QString (tr("%1 secs ago")).arg(now - it->mLastRecvTime);
|
||||
|
||||
dht_item -> setData(DTW_COL_BUCKET, Qt::DisplayRole, buckstr);
|
||||
dht_item -> setData(DTW_COL_IPADDR, Qt::DisplayRole, ipstr);
|
||||
dht_item -> setData(DTW_COL_PEERID, Qt::DisplayRole, idstr);
|
||||
dht_item -> setData(DTW_COL_FLAGS, Qt::DisplayRole, flagsstr);
|
||||
|
||||
dht_item -> setData(DTW_COL_FOUND, Qt::DisplayRole, foundstr);
|
||||
dht_item -> setData(DTW_COL_SEND, Qt::DisplayRole, lastsendstr);
|
||||
dht_item -> setData(DTW_COL_RECV, Qt::DisplayRole, lastrecvstr);
|
||||
|
||||
ui.dhtTreeWidget->addTopLevelItem(dht_item);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DhtWindow::getDHTStatus()
|
||||
{
|
||||
|
||||
RsConfigNetStatus config;
|
||||
rsConfig->getConfigNetStatus(config);
|
||||
|
||||
if (!(config.DHTActive))
|
||||
{
|
||||
// GRAY.
|
||||
}
|
||||
else
|
||||
{
|
||||
if (config.netDhtOk)
|
||||
{
|
||||
#define MIN_RS_NET_SIZE 10
|
||||
// YELLOW or GREEN.
|
||||
if (config.netDhtRsNetSize < MIN_RS_NET_SIZE)
|
||||
{
|
||||
updateGraph(config.netDhtRsNetSize,config.netDhtNetSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
updateGraph(config.netDhtRsNetSize,config.netDhtNetSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// RED - some issue.
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Adds new data to the graph. */
|
||||
void DhtWindow::updateGraph(qreal rsDHT, qreal allDHT)
|
||||
{
|
||||
ui.frmGraph->addPoints(rsDHT, allDHT);
|
||||
}
|
||||
|
58
retroshare-gui/src/gui/statistics/DhtWindow.h
Normal file
58
retroshare-gui/src/gui/statistics/DhtWindow.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
#ifndef RSDHT_WINDOW_H
|
||||
#define RSDHT_WINDOW_H
|
||||
|
||||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 2011 Robert Fernie
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
****************************************************************/
|
||||
|
||||
|
||||
#include "RsAutoUpdatePage.h"
|
||||
#include "ui_DhtWindow.h"
|
||||
|
||||
class DhtWindow : public RsAutoUpdatePage/*, public Ui::DhtWindow*/ {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
DhtWindow(QWidget *parent = 0);
|
||||
~DhtWindow();
|
||||
|
||||
void updateNetStatus();
|
||||
void updateNetPeers();
|
||||
void updateDhtPeers();
|
||||
void updateRelays();
|
||||
void getDHTStatus();
|
||||
|
||||
public slots:
|
||||
virtual void updateDisplay() ;
|
||||
|
||||
void updateGraph(qreal rsDHT, qreal allDHT);
|
||||
|
||||
protected:
|
||||
//void changeEvent(QEvent *e);
|
||||
|
||||
private:
|
||||
|
||||
/** Qt Designer generated object */
|
||||
Ui::DhtWindow ui;
|
||||
|
||||
};
|
||||
|
||||
#endif // RSDHT_WINDOW_H
|
||||
|
707
retroshare-gui/src/gui/statistics/DhtWindow.ui
Normal file
707
retroshare-gui/src/gui/statistics/DhtWindow.ui
Normal file
|
@ -0,0 +1,707 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DhtWindow</class>
|
||||
<widget class="QWidget" name="DhtWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>694</width>
|
||||
<height>603</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>DHT</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>DHT</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_16">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Net Status:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="netStatusLabel">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Net Status</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Network Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="networkLabel">
|
||||
<property name="text">
|
||||
<string>Network Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Nat Type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="natTypeLabel">
|
||||
<property name="text">
|
||||
<string>Nat Type</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Nat Hole:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="natHoleLabel">
|
||||
<property name="text">
|
||||
<string>Nat Hole</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_17">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Connect Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="connectLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Connect Options</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Peer Address:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="peerAddressLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Peer Address</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>DHT</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Unreachable:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_unreachable">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Online:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_online">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Offline:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_offline">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Peers:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_peers">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Connections</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_15">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Disconnected:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_disconnected">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Direct:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_direct">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_13">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Proxy:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_proxy">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_14">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Relay:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_relay">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QTreeWidget" name="peerTreeWidget">
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>PeerId</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>DHT Status</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>ConnectLogic</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Connect Status</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Connect Mode</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Request Status</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Cb Status</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>RsId</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
<widget class="QWidget" name="layoutWidget_2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="dhtLabel">
|
||||
<property name="text">
|
||||
<string>DHT Details</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="dhtTreeWidget">
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Bucket</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>IP:Port</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Key</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Status Flags</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Found</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Last Sent</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Last Recv</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="relayTreeWidget">
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Relay Mode</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Source</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Proxy</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Destination</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Class</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Age</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Last Sent</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Bandwidth</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>DHT Graph</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="DhtGraph" name="frmGraph">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>80</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::NoContextMenu</enum>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>DhtGraph</class>
|
||||
<extends>QFrame</extends>
|
||||
<header>gui/dhtgraph.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
286
retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp
Normal file
286
retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp
Normal file
|
@ -0,0 +1,286 @@
|
|||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 20011, RetroShare Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
****************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
#include <QTimer>
|
||||
#include <QObject>
|
||||
#include <QFontMetrics>
|
||||
#include <time.h>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QStylePainter>
|
||||
#include <QLayout>
|
||||
|
||||
#include <retroshare/rsgrouter.h>
|
||||
#include <retroshare/rspeers.h>
|
||||
#include "GlobalRouterStatistics.h"
|
||||
|
||||
#include "gui/settings/rsharesettings.h"
|
||||
|
||||
static const int MAX_TUNNEL_REQUESTS_DISPLAY = 10 ;
|
||||
|
||||
static QColor colorScale(float f)
|
||||
{
|
||||
if(f == 0)
|
||||
return QColor::fromHsv(0,0,192) ;
|
||||
else
|
||||
return QColor::fromHsv((int)((1.0-f)*280),200,255) ;
|
||||
}
|
||||
|
||||
GlobalRouterStatistics::GlobalRouterStatistics(QWidget *parent)
|
||||
: RsAutoUpdatePage(2000,parent)
|
||||
{
|
||||
setupUi(this) ;
|
||||
|
||||
m_bProcessSettings = false;
|
||||
|
||||
_router_F->setWidget( _tst_CW = new GlobalRouterStatisticsWidget() ) ;
|
||||
|
||||
// load settings
|
||||
processSettings(true);
|
||||
}
|
||||
|
||||
GlobalRouterStatistics::~GlobalRouterStatistics()
|
||||
{
|
||||
|
||||
// save settings
|
||||
processSettings(false);
|
||||
}
|
||||
|
||||
void GlobalRouterStatistics::processSettings(bool bLoad)
|
||||
{
|
||||
m_bProcessSettings = true;
|
||||
|
||||
Settings->beginGroup(QString("GlobalRouterStatistics"));
|
||||
|
||||
if (bLoad) {
|
||||
// load settings
|
||||
|
||||
// state of splitter
|
||||
//splitter->restoreState(Settings->value("Splitter").toByteArray());
|
||||
} else {
|
||||
// save settings
|
||||
|
||||
// state of splitter
|
||||
//Settings->setValue("Splitter", splitter->saveState());
|
||||
|
||||
}
|
||||
|
||||
Settings->endGroup();
|
||||
|
||||
m_bProcessSettings = false;
|
||||
}
|
||||
|
||||
void GlobalRouterStatistics::updateDisplay()
|
||||
{
|
||||
_tst_CW->updateContent() ;
|
||||
}
|
||||
|
||||
QString GlobalRouterStatistics::getPeerName(const RsPeerId &peer_id)
|
||||
{
|
||||
static std::map<RsPeerId, QString> names ;
|
||||
|
||||
std::map<RsPeerId,QString>::const_iterator it = names.find(peer_id) ;
|
||||
|
||||
if( it != names.end())
|
||||
return it->second ;
|
||||
else
|
||||
{
|
||||
RsPeerDetails detail ;
|
||||
if(!rsPeers->getPeerDetails(peer_id,detail))
|
||||
return tr("Unknown Peer");
|
||||
|
||||
return (names[peer_id] = QString::fromUtf8(detail.name.c_str())) ;
|
||||
}
|
||||
}
|
||||
|
||||
GlobalRouterStatisticsWidget::GlobalRouterStatisticsWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
maxWidth = 400 ;
|
||||
maxHeight = 0 ;
|
||||
}
|
||||
|
||||
void GlobalRouterStatisticsWidget::updateContent()
|
||||
{
|
||||
std::vector<RsGRouter::GRouterRoutingCacheInfo> cache_infos ;
|
||||
RsGRouter::GRouterRoutingMatrixInfo matrix_info ;
|
||||
|
||||
rsGRouter->getRoutingCacheInfo(cache_infos) ;
|
||||
rsGRouter->getRoutingMatrixInfo(matrix_info) ;
|
||||
|
||||
// What do we need to draw?
|
||||
//
|
||||
// Routing matrix
|
||||
// Key [][][][][][][][][][]
|
||||
//
|
||||
// -> each [] shows a square (one per friend location) that is the routing probabilities for all connected friends
|
||||
// computed using the "computeRoutingProbabilitites()" method.
|
||||
//
|
||||
// Own key ids
|
||||
// key service id description
|
||||
//
|
||||
// Data items
|
||||
// Msg id Local origin Destination Time Status
|
||||
//
|
||||
QPixmap tmppixmap(maxWidth, maxHeight);
|
||||
tmppixmap.fill(this, 0, 0);
|
||||
setFixedHeight(maxHeight);
|
||||
|
||||
QPainter painter(&tmppixmap);
|
||||
painter.initFrom(this);
|
||||
painter.setPen(QColor::fromRgb(0,0,0)) ;
|
||||
|
||||
QFont times_f("Times") ;
|
||||
QFont monospace_f("Monospace") ;
|
||||
monospace_f.setStyleHint(QFont::TypeWriter) ;
|
||||
|
||||
QFontMetrics fm_monospace(monospace_f) ;
|
||||
QFontMetrics fm_times(times_f) ;
|
||||
|
||||
static const int cellx = fm_monospace.width(QString(" ")) ;
|
||||
static const int celly = fm_monospace.height() ;
|
||||
|
||||
maxHeight = 500 ;
|
||||
|
||||
// std::cerr << "Drawing into pixmap of size " << maxWidth << "x" << maxHeight << std::endl;
|
||||
// draw...
|
||||
int ox=5,oy=5 ;
|
||||
|
||||
|
||||
painter.setFont(times_f) ;
|
||||
painter.drawText(ox,oy+celly,tr("Managed keys")+":" + QString::number(matrix_info.published_keys.size())) ; oy += celly*2 ;
|
||||
|
||||
painter.setFont(monospace_f) ;
|
||||
for(std::map<GRouterKeyId,RsGRouter::GRouterPublishedKeyInfo>::const_iterator it(matrix_info.published_keys.begin());it!=matrix_info.published_keys.end();++it)
|
||||
{
|
||||
QString packet_string ;
|
||||
packet_string += QString::fromStdString(it->first.toStdString()) ;
|
||||
packet_string += tr(" : Service ID = ")+QString::number(it->second.service_id,16) ;
|
||||
packet_string += " \""+QString::fromUtf8(it->second.description_string.c_str()) + "\"" ;
|
||||
|
||||
painter.drawText(ox+2*cellx,oy+celly,packet_string ) ; oy += celly ;
|
||||
}
|
||||
oy += celly ;
|
||||
|
||||
QString prob_string ;
|
||||
painter.setFont(times_f) ;
|
||||
QString Q = tr("Routing matrix (") ;
|
||||
|
||||
painter.drawText(ox+0*cellx,oy+fm_times.height(),Q) ;
|
||||
|
||||
// draw scale
|
||||
|
||||
for(int i=0;i<100;++i)
|
||||
{
|
||||
painter.setPen(colorScale(i/100.0)) ;
|
||||
painter.drawLine(fm_times.width(Q)+i,oy+celly+2,fm_times.width(Q)+i,oy+2) ;
|
||||
}
|
||||
painter.setPen(QColor::fromRgb(0,0,0)) ;
|
||||
|
||||
painter.drawText(ox+fm_times.width(Q) + 100,oy+celly,")") ;
|
||||
|
||||
oy += celly ;
|
||||
oy += celly ;
|
||||
|
||||
static const int MaxKeySize = 20 ;
|
||||
painter.setFont(monospace_f) ;
|
||||
|
||||
for(std::map<GRouterKeyId,std::vector<float> >::const_iterator it(matrix_info.per_friend_probabilities.begin());it!=matrix_info.per_friend_probabilities.end();++it)
|
||||
{
|
||||
QString ids = QString::fromStdString(it->first.toStdString())+" : " ;
|
||||
painter.drawText(ox+2*cellx,oy+celly,ids) ;
|
||||
|
||||
for(uint32_t i=0;i<matrix_info.friend_ids.size();++i)
|
||||
painter.fillRect(ox+i*cellx+fm_monospace.width(ids),oy,cellx,celly,colorScale(it->second[i])) ;
|
||||
|
||||
oy += celly ;
|
||||
}
|
||||
|
||||
oy += celly ;
|
||||
|
||||
painter.setFont(times_f) ;
|
||||
painter.drawText(ox,oy+celly,tr("Pending packets")+":" + QString::number(cache_infos.size())) ; oy += celly*2 ;
|
||||
|
||||
painter.setFont(monospace_f) ;
|
||||
|
||||
static const QString status_string[5] = { "UNKN", "PEND","SENT","ACKN","DEAD" } ;
|
||||
time_t now = time(NULL) ;
|
||||
std::map<QString, std::vector<QString> > tos ;
|
||||
|
||||
for(uint32_t i=0;i<cache_infos.size();++i)
|
||||
{
|
||||
QString packet_string ;
|
||||
packet_string += QString("Id=")+QString::number(cache_infos[i].mid,16) ;
|
||||
packet_string += tr(" by ")+QString::fromStdString(cache_infos[i].local_origin.toStdString()) ;
|
||||
packet_string += tr(" size=")+QString::number(cache_infos[i].data_size) ;
|
||||
packet_string += tr(" Status ")+status_string[cache_infos[i].status % 6] ;
|
||||
packet_string += " "+QString::number(now - cache_infos[i].time_stamp) + tr(" secs ago");
|
||||
|
||||
tos[ QString::fromStdString(cache_infos[i].destination.toStdString()) ].push_back(packet_string) ;
|
||||
}
|
||||
|
||||
for(std::map<QString,std::vector<QString> >::const_iterator it(tos.begin());it!=tos.end();++it)
|
||||
{
|
||||
painter.drawText(ox+2*cellx,oy+celly,tr("To: ")+it->first ) ; oy += celly ;
|
||||
|
||||
for(uint32_t i=0;i<it->second.size();++i)
|
||||
{
|
||||
painter.drawText(ox+4*cellx,oy+celly,it->second[i] ) ;
|
||||
oy += celly ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
oy += celly ;
|
||||
oy += celly ;
|
||||
|
||||
// update the pixmap
|
||||
//
|
||||
pixmap = tmppixmap;
|
||||
maxHeight = oy ;
|
||||
}
|
||||
|
||||
QString GlobalRouterStatisticsWidget::speedString(float f)
|
||||
{
|
||||
if(f < 1.0f)
|
||||
return QString("0 B/s") ;
|
||||
if(f < 1024.0f)
|
||||
return QString::number((int)f)+" B/s" ;
|
||||
|
||||
return QString::number(f/1024.0,'f',2) + " KB/s";
|
||||
}
|
||||
|
||||
void GlobalRouterStatisticsWidget::paintEvent(QPaintEvent */*event*/)
|
||||
{
|
||||
QStylePainter(this).drawPixmap(0, 0, pixmap);
|
||||
}
|
||||
|
||||
void GlobalRouterStatisticsWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QRect TaskGraphRect = geometry();
|
||||
maxWidth = TaskGraphRect.width();
|
||||
maxHeight = TaskGraphRect.height() ;
|
||||
|
||||
QWidget::resizeEvent(event);
|
||||
updateContent();
|
||||
}
|
||||
|
71
retroshare-gui/src/gui/statistics/GlobalRouterStatistics.h
Normal file
71
retroshare-gui/src/gui/statistics/GlobalRouterStatistics.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 20011, RetroShare Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
****************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QPoint>
|
||||
#include <retroshare/rsgrouter.h>
|
||||
#include <retroshare/rstypes.h>
|
||||
|
||||
#include "RsAutoUpdatePage.h"
|
||||
#include "ui_GlobalRouterStatistics.h"
|
||||
|
||||
class GlobalRouterStatisticsWidget ;
|
||||
|
||||
class GlobalRouterStatistics: public RsAutoUpdatePage, public Ui::GlobalRouterStatistics
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GlobalRouterStatistics(QWidget *parent = NULL) ;
|
||||
~GlobalRouterStatistics();
|
||||
|
||||
// Cache for peer names.
|
||||
static QString getPeerName(const RsPeerId& peer_id) ;
|
||||
|
||||
private:
|
||||
|
||||
void processSettings(bool bLoad);
|
||||
bool m_bProcessSettings;
|
||||
|
||||
virtual void updateDisplay() ;
|
||||
|
||||
GlobalRouterStatisticsWidget *_tst_CW ;
|
||||
} ;
|
||||
|
||||
class GlobalRouterStatisticsWidget: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GlobalRouterStatisticsWidget(QWidget *parent = NULL) ;
|
||||
|
||||
virtual void paintEvent(QPaintEvent *event) ;
|
||||
virtual void resizeEvent(QResizeEvent *event);
|
||||
|
||||
void updateContent() ;
|
||||
private:
|
||||
static QString speedString(float f) ;
|
||||
|
||||
QPixmap pixmap ;
|
||||
int maxWidth,maxHeight ;
|
||||
};
|
||||
|
51
retroshare-gui/src/gui/statistics/GlobalRouterStatistics.ui
Normal file
51
retroshare-gui/src/gui/statistics/GlobalRouterStatistics.ui
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>GlobalRouterStatistics</class>
|
||||
<widget class="QWidget" name="GlobalRouterStatistics">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>611</width>
|
||||
<height>408</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Router Statistics</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QScrollArea" name="_router_F">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>593</width>
|
||||
<height>390</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="images.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
396
retroshare-gui/src/gui/statistics/RttStatistics.cpp
Normal file
396
retroshare-gui/src/gui/statistics/RttStatistics.cpp
Normal file
|
@ -0,0 +1,396 @@
|
|||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 20011, RetroShare Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
****************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
#include <QTimer>
|
||||
#include <QObject>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QStylePainter>
|
||||
|
||||
#include <retroshare/rsrtt.h>
|
||||
#include <retroshare/rspeers.h>
|
||||
#include "RttStatistics.h"
|
||||
#include "time.h"
|
||||
|
||||
#include "gui/settings/rsharesettings.h"
|
||||
|
||||
#define PLOT_HEIGHT 100
|
||||
#define PLOT_WIDTH 500
|
||||
|
||||
#define MAX_DISPLAY_PERIOD 300
|
||||
|
||||
double convertDtToPixels(double refTs, double minTs, double ts)
|
||||
{
|
||||
double dt = refTs - ts;
|
||||
double maxdt = refTs - minTs;
|
||||
double pix = PLOT_WIDTH - dt / maxdt * PLOT_WIDTH;
|
||||
return pix;
|
||||
}
|
||||
|
||||
|
||||
double convertRttToPixels(double maxRTT, double rtt)
|
||||
{
|
||||
double pix = rtt / maxRTT * PLOT_HEIGHT;
|
||||
return PLOT_HEIGHT - pix;
|
||||
}
|
||||
|
||||
class RttPlot
|
||||
{
|
||||
public:
|
||||
RttPlot(const std::map<RsPeerId, std::list<RsRttPongResult> > &info,
|
||||
double refTS, double maxRTT, double minTS, double maxTS)
|
||||
:mInfo(info), mRefTS(refTS), mMaxRTT(maxRTT), mMinTS(minTS), mMaxTS(maxTS) {}
|
||||
|
||||
|
||||
QColor colorScale(float f)
|
||||
{
|
||||
if(f == 0)
|
||||
return QColor::fromHsv(0,0,192) ;
|
||||
else
|
||||
return QColor::fromHsv((int)((1.0-f)*280),200,255) ;
|
||||
}
|
||||
|
||||
virtual void draw(QPainter *painter,int& ox,int& oy,const QString& title)
|
||||
{
|
||||
static const int cellx = 7 ;
|
||||
static const int celly = 12 ;
|
||||
|
||||
//int save_ox = ox ;
|
||||
painter->setPen(QColor::fromRgb(0,0,0)) ;
|
||||
painter->drawText(2+ox,celly+oy,title) ;
|
||||
oy+=2+2*celly ;
|
||||
|
||||
painter->drawRect(ox, oy, PLOT_WIDTH, PLOT_HEIGHT);
|
||||
painter->fillRect(ox, oy, PLOT_WIDTH, PLOT_HEIGHT, QBrush(Qt::white));
|
||||
|
||||
/* We want antialiased lines and text */
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
painter->setRenderHint(QPainter::TextAntialiasing);
|
||||
|
||||
if(mInfo.empty())
|
||||
return ;
|
||||
|
||||
double maxdt = mRefTS - mMinTS;
|
||||
if (maxdt > MAX_DISPLAY_PERIOD)
|
||||
{
|
||||
mMinTS = mRefTS - MAX_DISPLAY_PERIOD;
|
||||
}
|
||||
|
||||
/* draw a different line for each peer */
|
||||
std::map<RsPeerId, std::list<RsRttPongResult> >::const_iterator mit;
|
||||
int i = 0;
|
||||
int nLines = mInfo.size();
|
||||
for(mit = mInfo.begin(); mit != mInfo.end(); mit++, i++)
|
||||
{
|
||||
QPainterPath path;
|
||||
std::list<RsRttPongResult>::const_iterator it = mit->second.begin();
|
||||
if (it != mit->second.end())
|
||||
{
|
||||
double x = convertDtToPixels(mRefTS, mMinTS, it->mTS);
|
||||
double y = convertRttToPixels(mMaxRTT, it->mRTT);
|
||||
path.moveTo(ox + x, oy + y);
|
||||
it++;
|
||||
}
|
||||
|
||||
for(; it != mit->second.end(); it++)
|
||||
{
|
||||
/* skip old elements */
|
||||
if (it->mTS < mMinTS)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
double x = convertDtToPixels(mRefTS, mMinTS, it->mTS);
|
||||
double y = convertRttToPixels(mMaxRTT, it->mRTT);
|
||||
|
||||
path.lineTo(ox + x, oy + y);
|
||||
}
|
||||
|
||||
/* draw line */
|
||||
painter->setPen(QColor::fromRgb(((255.0 * i) / (nLines-1)),0, 255 - (255.0 * i) / (nLines-1))) ;
|
||||
painter->drawPath(path);
|
||||
|
||||
/* draw name */
|
||||
}
|
||||
|
||||
painter->setPen(QColor::fromRgb(0,0,0)) ;
|
||||
painter->drawText(ox+PLOT_WIDTH + cellx ,oy + celly / 2, QString::number(mMaxRTT)+" "+QObject::tr("secs")) ;
|
||||
oy += PLOT_HEIGHT / 2;
|
||||
painter->drawText(ox+PLOT_WIDTH + cellx ,oy + celly / 2, QString::number(mMaxRTT / 2.0)+" "+QObject::tr("secs")) ;
|
||||
oy += PLOT_HEIGHT / 2;
|
||||
painter->drawText(ox+PLOT_WIDTH + cellx ,oy + celly / 2, QString::number(0.0)+" "+QObject::tr("secs")) ;
|
||||
oy += celly;
|
||||
painter->drawText(ox ,oy, QObject::tr("Old"));
|
||||
painter->drawText(ox + PLOT_WIDTH - cellx ,oy, QObject::tr("Now"));
|
||||
oy += celly;
|
||||
|
||||
// Now do names.
|
||||
i = 0;
|
||||
for(mit = mInfo.begin(); mit != mInfo.end(); mit++, i++)
|
||||
{
|
||||
painter->fillRect(ox,oy,cellx,celly,
|
||||
QColor::fromRgb(((255.0 * i) / (nLines-1)),0, 255 - (255.0 * i) / (nLines-1))) ;
|
||||
|
||||
painter->setPen(QColor::fromRgb(0,0,0)) ;
|
||||
painter->drawRect(ox,oy,cellx,celly) ;
|
||||
painter->drawText(ox + cellx + 4,oy + celly / 2,RttStatistics::getPeerName(mit->first));
|
||||
|
||||
oy += 2 * celly;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const std::map<RsPeerId, std::list<RsRttPongResult> > &mInfo;
|
||||
double mRefTS;
|
||||
double mMaxRTT;
|
||||
double mMinTS;
|
||||
double mMaxTS;
|
||||
|
||||
};
|
||||
|
||||
RttStatistics::RttStatistics(QWidget *parent)
|
||||
: RsAutoUpdatePage(2000,parent)
|
||||
{
|
||||
setupUi(this) ;
|
||||
|
||||
m_bProcessSettings = false;
|
||||
|
||||
_tunnel_statistics_F->setWidget( _tst_CW = new RttStatisticsWidget() ) ;
|
||||
_tunnel_statistics_F->setWidgetResizable(true);
|
||||
_tunnel_statistics_F->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
_tunnel_statistics_F->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
_tunnel_statistics_F->viewport()->setBackgroundRole(QPalette::NoRole);
|
||||
_tunnel_statistics_F->setFrameStyle(QFrame::NoFrame);
|
||||
_tunnel_statistics_F->setFocusPolicy(Qt::NoFocus);
|
||||
|
||||
// load settings
|
||||
processSettings(true);
|
||||
}
|
||||
|
||||
RttStatistics::~RttStatistics()
|
||||
{
|
||||
|
||||
// save settings
|
||||
processSettings(false);
|
||||
}
|
||||
|
||||
void RttStatistics::processSettings(bool bLoad)
|
||||
{
|
||||
m_bProcessSettings = true;
|
||||
|
||||
Settings->beginGroup(QString("RttStatistics"));
|
||||
|
||||
if (bLoad) {
|
||||
// load settings
|
||||
|
||||
// state of splitter
|
||||
//splitter->restoreState(Settings->value("Splitter").toByteArray());
|
||||
} else {
|
||||
// save settings
|
||||
|
||||
// state of splitter
|
||||
//Settings->setValue("Splitter", splitter->saveState());
|
||||
|
||||
}
|
||||
|
||||
Settings->endGroup();
|
||||
|
||||
m_bProcessSettings = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void RttStatistics::updateDisplay()
|
||||
{
|
||||
std::map<RsPeerId, std::list<RsRttPongResult> > info;
|
||||
|
||||
if (!rsRtt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::list<RsPeerId> idList;
|
||||
std::list<RsPeerId>::iterator it;
|
||||
|
||||
rsPeers->getOnlineList(idList);
|
||||
|
||||
time_t now = time(NULL);
|
||||
time_t minTS = now;
|
||||
time_t maxTS = 0;
|
||||
double maxRTT = 0;
|
||||
|
||||
for(it = idList.begin(); it != idList.end(); it++)
|
||||
{
|
||||
std::list<RsRttPongResult> results;
|
||||
std::list<RsRttPongResult>::iterator rit;
|
||||
|
||||
#define MAX_RESULTS 60
|
||||
rsRtt->getPongResults(*it, MAX_RESULTS, results);
|
||||
|
||||
for(rit = results.begin(); rit != results.end(); rit++)
|
||||
{
|
||||
/* only want maxRTT to include plotted bit */
|
||||
double dt = now - rit->mTS;
|
||||
if (dt < MAX_DISPLAY_PERIOD)
|
||||
{
|
||||
if (maxRTT < rit->mRTT)
|
||||
{
|
||||
maxRTT = rit->mRTT;
|
||||
}
|
||||
}
|
||||
if (minTS > rit->mTS)
|
||||
{
|
||||
minTS = rit->mTS;
|
||||
}
|
||||
if (maxTS < rit->mTS)
|
||||
{
|
||||
maxTS = rit->mTS;
|
||||
}
|
||||
}
|
||||
|
||||
info[*it] = results;
|
||||
}
|
||||
|
||||
|
||||
_tst_CW->updateRttStatistics(info, maxRTT, minTS, maxTS);
|
||||
_tst_CW->update();
|
||||
}
|
||||
|
||||
QString RttStatistics::getPeerName(const RsPeerId& peer_id)
|
||||
{
|
||||
static std::map<RsPeerId, QString> names ;
|
||||
|
||||
std::map<RsPeerId,QString>::const_iterator it = names.find(peer_id) ;
|
||||
|
||||
if( it != names.end())
|
||||
return it->second ;
|
||||
else
|
||||
{
|
||||
RsPeerDetails detail ;
|
||||
if(!rsPeers->getPeerDetails(peer_id,detail))
|
||||
return "unknown peer";
|
||||
|
||||
return (names[peer_id] = QString::fromUtf8(detail.name.c_str())) ;
|
||||
}
|
||||
}
|
||||
|
||||
RttStatisticsWidget::RttStatisticsWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
maxWidth = 200 ;
|
||||
maxHeight = 0 ;
|
||||
}
|
||||
|
||||
void RttStatisticsWidget::updateRttStatistics(const std::map<RsPeerId, std::list<RsRttPongResult> >& info,
|
||||
double maxRTT, double minTS, double maxTS)
|
||||
{
|
||||
//static const int cellx = 6 ;
|
||||
//static const int celly = 10+4 ;
|
||||
|
||||
QPixmap tmppixmap(maxWidth, maxHeight);
|
||||
tmppixmap.fill(this, 0, 0);
|
||||
setFixedHeight(maxHeight);
|
||||
|
||||
QPainter painter(&tmppixmap);
|
||||
painter.initFrom(this);
|
||||
|
||||
maxHeight = 500 ;
|
||||
|
||||
//std::cerr << "Drawing into pixmap of size " << maxWidth << "x" << maxHeight << std::endl;
|
||||
// draw...
|
||||
int ox=5,oy=5 ;
|
||||
|
||||
double refTS = time(NULL);
|
||||
|
||||
//painter.setPen(QColor::fromRgb(70,70,70)) ;
|
||||
//painter.drawLine(0,oy,maxWidth,oy) ;
|
||||
//oy += celly ;
|
||||
//painter.setPen(QColor::fromRgb(0,0,0)) ;
|
||||
|
||||
// round up RTT to nearest
|
||||
double roundedRTT = maxRTT;
|
||||
if (maxRTT < 0.018)
|
||||
{
|
||||
roundedRTT = 0.02;
|
||||
}
|
||||
else if (maxRTT < 0.045)
|
||||
{
|
||||
roundedRTT = 0.05;
|
||||
}
|
||||
else if (maxRTT < 0.09)
|
||||
{
|
||||
roundedRTT = 0.1;
|
||||
}
|
||||
else if (maxRTT < 0.18)
|
||||
{
|
||||
roundedRTT = 0.2;
|
||||
}
|
||||
else if (maxRTT < 0.4)
|
||||
{
|
||||
roundedRTT = 0.5;
|
||||
}
|
||||
else if (maxRTT < 0.8)
|
||||
{
|
||||
roundedRTT = 1.0;
|
||||
}
|
||||
else if (maxRTT < 1.8)
|
||||
{
|
||||
roundedRTT = 2.0;
|
||||
}
|
||||
else if (maxRTT < 4.5)
|
||||
{
|
||||
roundedRTT = 5.0;
|
||||
}
|
||||
|
||||
RttPlot(info, refTS, roundedRTT, minTS, maxTS).draw(&painter,ox,oy,QObject::tr("Round Trip Time:")) ;
|
||||
|
||||
// update the pixmap
|
||||
pixmap = tmppixmap;
|
||||
maxHeight = oy; // + PLOT_HEIGHT * 2;
|
||||
}
|
||||
|
||||
QString RttStatisticsWidget::speedString(float f)
|
||||
{
|
||||
if(f < 1.0f)
|
||||
return QString("0 B/s") ;
|
||||
if(f < 1024.0f)
|
||||
return QString::number((int)f)+" B/s" ;
|
||||
|
||||
return QString::number(f/1024.0,'f',2) + " KB/s";
|
||||
}
|
||||
|
||||
void RttStatisticsWidget::paintEvent(QPaintEvent */*event*/)
|
||||
{
|
||||
QStylePainter(this).drawPixmap(0, 0, pixmap);
|
||||
}
|
||||
|
||||
void RttStatisticsWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QRect TaskGraphRect = geometry();
|
||||
maxWidth = TaskGraphRect.width();
|
||||
maxHeight = TaskGraphRect.height() ;
|
||||
|
||||
QWidget::resizeEvent(event);
|
||||
update();
|
||||
}
|
||||
|
||||
|
68
retroshare-gui/src/gui/statistics/RttStatistics.h
Normal file
68
retroshare-gui/src/gui/statistics/RttStatistics.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 20011, RetroShare Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
****************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QPoint>
|
||||
#include <retroshare/rsrtt.h>
|
||||
#include "ui_RttStatistics.h"
|
||||
#include "RsAutoUpdatePage.h"
|
||||
|
||||
class RttStatisticsWidget ;
|
||||
|
||||
class RttStatistics: public RsAutoUpdatePage, public Ui::RttStatistics
|
||||
{
|
||||
public:
|
||||
RttStatistics(QWidget *parent = NULL) ;
|
||||
~RttStatistics();
|
||||
|
||||
// Cache for peer names.
|
||||
static QString getPeerName(const RsPeerId& peer_id) ;
|
||||
|
||||
private:
|
||||
|
||||
void processSettings(bool bLoad);
|
||||
bool m_bProcessSettings;
|
||||
|
||||
virtual void updateDisplay() ;
|
||||
|
||||
RttStatisticsWidget *_tst_CW ;
|
||||
} ;
|
||||
|
||||
class RttStatisticsWidget: public QWidget
|
||||
{
|
||||
public:
|
||||
RttStatisticsWidget(QWidget *parent = NULL) ;
|
||||
|
||||
virtual void paintEvent(QPaintEvent *event) ;
|
||||
virtual void resizeEvent(QResizeEvent *event);
|
||||
|
||||
|
||||
void updateRttStatistics(const std::map<RsPeerId, std::list<RsRttPongResult> >& info,
|
||||
double maxRTT, double minTS, double maxTS);
|
||||
|
||||
private:
|
||||
static QString speedString(float f) ;
|
||||
|
||||
QPixmap pixmap ;
|
||||
int maxWidth,maxHeight ;
|
||||
};
|
||||
|
55
retroshare-gui/src/gui/statistics/RttStatistics.ui
Normal file
55
retroshare-gui/src/gui/statistics/RttStatistics.ui
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>RttStatistics</class>
|
||||
<widget class="QWidget" name="RttStatistics">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>611</width>
|
||||
<height>408</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>RTT Statistics</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/logo/logo_16.png</normaloff>:/images/logo/logo_16.png</iconset>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QScrollArea" name="_tunnel_statistics_F">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>593</width>
|
||||
<height>390</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="images.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -34,10 +34,10 @@
|
|||
#include "retroshare/rspeers.h"
|
||||
#include <retroshare/rsplugin.h>
|
||||
|
||||
#include <gui/FileTransfer/TurtleRouterStatistics.h>
|
||||
#include <gui/settings/GlobalRouterStatistics.h>
|
||||
#include <gui/bwctrl/BwCtrlWindow.h>
|
||||
#include <gui/dht/DhtWindow.h>
|
||||
#include <gui/statistics/TurtleRouterStatistics.h>
|
||||
#include <gui/statistics/GlobalRouterStatistics.h>
|
||||
#include <gui/statistics/BwCtrlWindow.h>
|
||||
#include <gui/statistics/DhtWindow.h>
|
||||
|
||||
/****
|
||||
* #define SHOW_RTT_STATISTICS 1
|
||||
|
@ -45,7 +45,7 @@
|
|||
#define SHOW_RTT_STATISTICS 1
|
||||
|
||||
#ifdef SHOW_RTT_STATISTICS
|
||||
#include "gui/RttStatistics.h"
|
||||
#include "gui/statistics/RttStatistics.h"
|
||||
#endif
|
||||
|
||||
#define IMAGE_DHT ":/images/dht32.png"
|
||||
|
|
216
retroshare-gui/src/gui/statistics/TurtleRouterDialog.cpp
Normal file
216
retroshare-gui/src/gui/statistics/TurtleRouterDialog.cpp
Normal file
|
@ -0,0 +1,216 @@
|
|||
#include <QObject>
|
||||
#include <retroshare/rsturtle.h>
|
||||
#include <retroshare/rspeers.h>
|
||||
#include "TurtleRouterDialog.h"
|
||||
#include <QPainter>
|
||||
#include <QStylePainter>
|
||||
|
||||
#include "gui/settings/rsharesettings.h"
|
||||
|
||||
static const uint MAX_TUNNEL_REQUESTS_DISPLAY = 10 ;
|
||||
|
||||
|
||||
TurtleRouterDialog::TurtleRouterDialog(QWidget *parent)
|
||||
: RsAutoUpdatePage(2000,parent)
|
||||
{
|
||||
setupUi(this) ;
|
||||
|
||||
m_bProcessSettings = false;
|
||||
|
||||
// Init the basic setup.
|
||||
//
|
||||
QStringList stl ;
|
||||
int n=0 ;
|
||||
|
||||
stl.clear() ;
|
||||
stl.push_back(tr("Search requests")) ;
|
||||
top_level_s_requests = new QTreeWidgetItem(_f2f_TW,stl) ;
|
||||
_f2f_TW->insertTopLevelItem(n++,top_level_s_requests) ;
|
||||
|
||||
stl.clear() ;
|
||||
stl.push_back(tr("Tunnel requests")) ;
|
||||
top_level_t_requests = new QTreeWidgetItem(_f2f_TW,stl) ;
|
||||
_f2f_TW->insertTopLevelItem(n++,top_level_t_requests) ;
|
||||
|
||||
top_level_hashes.clear() ;
|
||||
|
||||
// load settings
|
||||
processSettings(true);
|
||||
}
|
||||
|
||||
TurtleRouterDialog::~TurtleRouterDialog()
|
||||
{
|
||||
// save settings
|
||||
processSettings(false);
|
||||
}
|
||||
|
||||
void TurtleRouterDialog::processSettings(bool bLoad)
|
||||
{
|
||||
m_bProcessSettings = true;
|
||||
|
||||
Settings->beginGroup(QString("TurtleRouterDialog"));
|
||||
|
||||
if (bLoad) {
|
||||
// load settings
|
||||
|
||||
// state of splitter
|
||||
//splitter->restoreState(Settings->value("Splitter").toByteArray());
|
||||
} else {
|
||||
// save settings
|
||||
|
||||
// state of splitter
|
||||
//Settings->setValue("Splitter", splitter->saveState());
|
||||
|
||||
}
|
||||
|
||||
Settings->endGroup();
|
||||
|
||||
m_bProcessSettings = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void TurtleRouterDialog::updateDisplay()
|
||||
{
|
||||
std::vector<std::vector<std::string> > hashes_info ;
|
||||
std::vector<std::vector<std::string> > tunnels_info ;
|
||||
std::vector<TurtleRequestDisplayInfo > search_reqs_info ;
|
||||
std::vector<TurtleRequestDisplayInfo > tunnel_reqs_info ;
|
||||
|
||||
rsTurtle->getInfo(hashes_info,tunnels_info,search_reqs_info,tunnel_reqs_info) ;
|
||||
|
||||
updateTunnelRequests(hashes_info,tunnels_info,search_reqs_info,tunnel_reqs_info) ;
|
||||
|
||||
}
|
||||
|
||||
QString TurtleRouterDialog::getPeerName(const RsPeerId& peer_id)
|
||||
{
|
||||
static std::map<RsPeerId, QString> names ;
|
||||
|
||||
std::map<RsPeerId,QString>::const_iterator it = names.find(peer_id) ;
|
||||
|
||||
if( it != names.end())
|
||||
return it->second ;
|
||||
else
|
||||
{
|
||||
RsPeerDetails detail ;
|
||||
if(!rsPeers->getPeerDetails(peer_id,detail))
|
||||
return "unknown peer";
|
||||
|
||||
return (names[peer_id] = QString::fromUtf8(detail.name.c_str())) ;
|
||||
}
|
||||
}
|
||||
|
||||
void TurtleRouterDialog::updateTunnelRequests( const std::vector<std::vector<std::string> >& hashes_info,
|
||||
const std::vector<std::vector<std::string> >& tunnels_info,
|
||||
const std::vector<TurtleRequestDisplayInfo >& search_reqs_info,
|
||||
const std::vector<TurtleRequestDisplayInfo >& tunnel_reqs_info)
|
||||
{
|
||||
// now display this in the QTableWidgets
|
||||
|
||||
QStringList stl ;
|
||||
|
||||
// remove all children of top level objects
|
||||
for(int i=0;i<_f2f_TW->topLevelItemCount();++i)
|
||||
{
|
||||
QTreeWidgetItem *taken ;
|
||||
while( (taken = _f2f_TW->topLevelItem(i)->takeChild(0)) != NULL)
|
||||
delete taken ;
|
||||
}
|
||||
|
||||
for(uint i=0;i<hashes_info.size();++i)
|
||||
findParentHashItem(hashes_info[i][0]) ;
|
||||
|
||||
bool unknown_hash_found = false ;
|
||||
|
||||
// check that an entry exist for all hashes
|
||||
for(uint i=0;i<tunnels_info.size();++i)
|
||||
{
|
||||
const std::string& hash(tunnels_info[i][3]) ;
|
||||
|
||||
QTreeWidgetItem *parent = findParentHashItem(hash) ;
|
||||
|
||||
if(parent->text(0).left(14) == tr("Unknown hashes"))
|
||||
unknown_hash_found = true ;
|
||||
|
||||
QString str = tr("Tunnel id") + ": " + QString::fromUtf8(tunnels_info[i][0].c_str()) + "\t [" + QString::fromUtf8(tunnels_info[i][2].c_str()) + "] --> [" + QString::fromUtf8(tunnels_info[i][1].c_str()) + "]\t\t " + tr("last transfer") + ": " + QString::fromStdString(tunnels_info[i][4]) + "\t " + tr("Speed") + ": " + QString::fromStdString(tunnels_info[i][5]) ;
|
||||
stl.clear() ;
|
||||
stl.push_back(str) ;
|
||||
|
||||
parent->addChild(new QTreeWidgetItem(stl)) ;
|
||||
}
|
||||
|
||||
for(uint i=0;i<search_reqs_info.size();++i)
|
||||
{
|
||||
QString str = tr("Request id: %1\t from [%2]\t %3 secs ago").arg(search_reqs_info[i].request_id,0,16).arg(getPeerName(search_reqs_info[i].source_peer_id)).arg(search_reqs_info[i].age);
|
||||
|
||||
stl.clear() ;
|
||||
stl.push_back(str) ;
|
||||
|
||||
top_level_s_requests->addChild(new QTreeWidgetItem(stl)) ;
|
||||
}
|
||||
top_level_s_requests->setText(0, tr("Search requests") + "(" + QString::number(search_reqs_info.size()) + ")" ) ;
|
||||
|
||||
for(uint i=0;i<tunnel_reqs_info.size();++i)
|
||||
if(i+MAX_TUNNEL_REQUESTS_DISPLAY >= tunnel_reqs_info.size() || i < MAX_TUNNEL_REQUESTS_DISPLAY)
|
||||
{
|
||||
QString str = tr("Request id: %1\t from [%2]\t %3 secs ago").arg(tunnel_reqs_info[i].request_id,0,16).arg(getPeerName(tunnel_reqs_info[i].source_peer_id)).arg(tunnel_reqs_info[i].age);
|
||||
|
||||
stl.clear() ;
|
||||
stl.push_back(str) ;
|
||||
|
||||
top_level_t_requests->addChild(new QTreeWidgetItem(stl)) ;
|
||||
}
|
||||
else if(i == MAX_TUNNEL_REQUESTS_DISPLAY)
|
||||
{
|
||||
stl.clear() ;
|
||||
stl.push_back(QString("...")) ;
|
||||
top_level_t_requests->addChild(new QTreeWidgetItem(stl)) ;
|
||||
|
||||
}
|
||||
|
||||
top_level_t_requests->setText(0, tr("Tunnel requests") + "("+QString::number(tunnel_reqs_info.size()) + ")") ;
|
||||
|
||||
QTreeWidgetItem *unknown_hashs_item = findParentHashItem("") ;
|
||||
unknown_hashs_item->setText(0,tr("Unknown hashes") + " (" + QString::number(unknown_hashs_item->childCount())+QString(")")) ;
|
||||
|
||||
// Ok, this is a N2 search, but there are very few elements in the list.
|
||||
for(int i=2;i<_f2f_TW->topLevelItemCount();)
|
||||
{
|
||||
bool found = false ;
|
||||
|
||||
if(_f2f_TW->topLevelItem(i)->text(0).left(14) == tr("Unknown hashes") && unknown_hash_found)
|
||||
found = true ;
|
||||
|
||||
if(_f2f_TW->topLevelItem(i)->childCount() > 0) // this saves uploading hashes
|
||||
found = true ;
|
||||
|
||||
for(uint j=0;j<hashes_info.size() && !found;++j)
|
||||
if(_f2f_TW->topLevelItem(i)->text(0).toStdString() == hashes_info[j][0])
|
||||
found=true ;
|
||||
|
||||
if(!found)
|
||||
delete _f2f_TW->takeTopLevelItem(i) ;
|
||||
else
|
||||
++i ;
|
||||
}
|
||||
}
|
||||
|
||||
QTreeWidgetItem *TurtleRouterDialog::findParentHashItem(const std::string& hash)
|
||||
{
|
||||
// look for the hash, and insert a new element if necessary.
|
||||
//
|
||||
QList<QTreeWidgetItem*> items = _f2f_TW->findItems((hash=="")?tr("Unknown hashes"):QString::fromStdString(hash),Qt::MatchStartsWith) ;
|
||||
|
||||
if(items.empty())
|
||||
{
|
||||
QStringList stl ;
|
||||
stl.push_back((hash=="")?tr("Unknown hashes"):QString::fromStdString(hash)) ;
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(_f2f_TW,stl) ;
|
||||
_f2f_TW->insertTopLevelItem(0,item) ;
|
||||
|
||||
return item ;
|
||||
}
|
||||
else
|
||||
return items.front() ;
|
||||
}
|
37
retroshare-gui/src/gui/statistics/TurtleRouterDialog.h
Normal file
37
retroshare-gui/src/gui/statistics/TurtleRouterDialog.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
#include <retroshare/rsturtle.h>
|
||||
#include <retroshare/rstypes.h>
|
||||
#include "ui_TurtleRouterDialog.h"
|
||||
#include "RsAutoUpdatePage.h"
|
||||
|
||||
|
||||
class TurtleRouterDialog: public RsAutoUpdatePage, public Ui::TurtleRouterDialogForm
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TurtleRouterDialog(QWidget *parent = NULL) ;
|
||||
~TurtleRouterDialog();
|
||||
|
||||
// Cache for peer names.
|
||||
static QString getPeerName(const RsPeerId &peer_id) ;
|
||||
|
||||
private:
|
||||
void updateTunnelRequests( const std::vector<std::vector<std::basic_string<char> > >&,
|
||||
const std::vector<std::vector<std::basic_string<char> > >&,
|
||||
const std::vector<TurtleRequestDisplayInfo >&,
|
||||
const std::vector<TurtleRequestDisplayInfo >&) ;
|
||||
|
||||
void processSettings(bool bLoad);
|
||||
bool m_bProcessSettings;
|
||||
|
||||
virtual void updateDisplay() ;
|
||||
QTreeWidgetItem *findParentHashItem(const std::string& hash) ;
|
||||
|
||||
std::map<std::string,QTreeWidgetItem*> top_level_hashes ;
|
||||
QTreeWidgetItem *top_level_unknown_hashes ;
|
||||
QTreeWidgetItem *top_level_s_requests ;
|
||||
QTreeWidgetItem *top_level_t_requests ;
|
||||
|
||||
} ;
|
33
retroshare-gui/src/gui/statistics/TurtleRouterDialog.ui
Normal file
33
retroshare-gui/src/gui/statistics/TurtleRouterDialog.ui
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TurtleRouterDialogForm</class>
|
||||
<widget class="QWidget" name="TurtleRouterDialogForm">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>572</width>
|
||||
<height>350</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Router Statistics</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTreeWidget" name="_f2f_TW">
|
||||
<property name="headerHidden">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>F2F router information</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
368
retroshare-gui/src/gui/statistics/TurtleRouterStatistics.cpp
Normal file
368
retroshare-gui/src/gui/statistics/TurtleRouterStatistics.cpp
Normal file
|
@ -0,0 +1,368 @@
|
|||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 20011, RetroShare Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
****************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
#include <QTimer>
|
||||
#include <QObject>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QStylePainter>
|
||||
|
||||
#include <retroshare/rsturtle.h>
|
||||
#include <retroshare/rspeers.h>
|
||||
#include "TurtleRouterStatistics.h"
|
||||
|
||||
#include "gui/settings/rsharesettings.h"
|
||||
|
||||
static const int MAX_TUNNEL_REQUESTS_DISPLAY = 10 ;
|
||||
|
||||
class TRHistogram
|
||||
{
|
||||
public:
|
||||
TRHistogram(const std::vector<TurtleRequestDisplayInfo >& info) :_infos(info) {}
|
||||
|
||||
QColor colorScale(float f)
|
||||
{
|
||||
if(f == 0)
|
||||
return QColor::fromHsv(0,0,192) ;
|
||||
else
|
||||
return QColor::fromHsv((int)((1.0-f)*280),200,255) ;
|
||||
}
|
||||
|
||||
virtual void draw(QPainter *painter,int& ox,int& oy,const QString& title)
|
||||
{
|
||||
static const int MaxTime = 61 ;
|
||||
static const int MaxDepth = 8 ;
|
||||
static const int cellx = 7 ;
|
||||
static const int celly = 12 ;
|
||||
|
||||
int save_ox = ox ;
|
||||
painter->setPen(QColor::fromRgb(0,0,0)) ;
|
||||
painter->drawText(2+ox,celly+oy,title) ;
|
||||
oy+=2+2*celly ;
|
||||
|
||||
if(_infos.empty())
|
||||
return ;
|
||||
|
||||
ox += 10 ;
|
||||
std::map<RsPeerId,std::vector<int> > hits ;
|
||||
std::map<RsPeerId,std::vector<int> > depths ;
|
||||
std::map<RsPeerId,std::vector<int> >::iterator it ;
|
||||
|
||||
int max_hits = 1;
|
||||
int max_depth = 1;
|
||||
|
||||
for(uint32_t i=0;i<_infos.size();++i)
|
||||
{
|
||||
std::vector<int>& h(hits[_infos[i].source_peer_id]) ;
|
||||
std::vector<int>& g(depths[_infos[i].source_peer_id]) ;
|
||||
|
||||
if(h.size() <= _infos[i].age)
|
||||
h.resize(MaxTime,0) ;
|
||||
|
||||
if(g.empty())
|
||||
g.resize(MaxDepth,0) ;
|
||||
|
||||
if(_infos[i].age < h.size())
|
||||
{
|
||||
h[_infos[i].age]++ ;
|
||||
if(h[_infos[i].age] > max_hits)
|
||||
max_hits = h[_infos[i].age] ;
|
||||
}
|
||||
if(_infos[i].depth < g.size())
|
||||
{
|
||||
g[_infos[i].depth]++ ;
|
||||
|
||||
if(g[_infos[i].depth] > max_depth)
|
||||
max_depth = g[_infos[i].depth] ;
|
||||
}
|
||||
}
|
||||
|
||||
int max_bi = std::max(max_hits,max_depth) ;
|
||||
int p=0 ;
|
||||
|
||||
for(it=depths.begin();it!=depths.end();++it,++p)
|
||||
for(int i=0;i<MaxDepth;++i)
|
||||
painter->fillRect(ox+MaxTime*cellx+20+i*cellx,oy+p*celly,cellx,celly,colorScale(it->second[i]/(float)max_bi)) ;
|
||||
|
||||
painter->setPen(QColor::fromRgb(0,0,0)) ;
|
||||
painter->drawRect(ox+MaxTime*cellx+20,oy,MaxDepth*cellx,p*celly) ;
|
||||
|
||||
for(int i=0;i<MaxTime;i+=5)
|
||||
painter->drawText(ox+i*cellx,oy+(p+1)*celly+4,QString::number(i)) ;
|
||||
|
||||
p=0 ;
|
||||
int great_total = 0 ;
|
||||
|
||||
for(it=hits.begin();it!=hits.end();++it,++p)
|
||||
{
|
||||
int total = 0 ;
|
||||
|
||||
for(int i=0;i<MaxTime;++i)
|
||||
{
|
||||
painter->fillRect(ox+i*cellx,oy+p*celly,cellx,celly,colorScale(it->second[i]/(float)max_bi)) ;
|
||||
total += it->second[i] ;
|
||||
}
|
||||
|
||||
painter->setPen(QColor::fromRgb(0,0,0)) ;
|
||||
painter->drawText(ox+MaxDepth*cellx+30+(MaxTime+1)*cellx,oy+(p+1)*celly,TurtleRouterStatistics::getPeerName(it->first)) ;
|
||||
painter->drawText(ox+MaxDepth*cellx+30+(MaxTime+1)*cellx+120,oy+(p+1)*celly,"("+QString::number(total)+")") ;
|
||||
great_total += total ;
|
||||
}
|
||||
|
||||
painter->drawRect(ox,oy,MaxTime*cellx,p*celly) ;
|
||||
|
||||
for(int i=0;i<MaxTime;i+=5)
|
||||
painter->drawText(ox+i*cellx,oy+(p+1)*celly+4,QString::number(i)) ;
|
||||
for(int i=0;i<MaxDepth;i++)
|
||||
painter->drawText(ox+MaxTime*cellx+20+i*cellx,oy+(p+1)*celly+4,QString::number(i)) ;
|
||||
painter->setPen(QColor::fromRgb(255,130,80)) ;
|
||||
painter->drawText(ox+MaxDepth*cellx+30+(MaxTime+1)*cellx+120,oy+(p+1)*celly+4,"("+QString::number(great_total)+")");
|
||||
|
||||
oy += (p+1)*celly+6 ;
|
||||
|
||||
painter->setPen(QColor::fromRgb(0,0,0)) ;
|
||||
painter->drawText(ox,oy+celly,"("+QApplication::translate("TurtleRouterStatistics", "Age in seconds")+")");
|
||||
painter->drawText(ox+MaxTime*cellx+20,oy+celly,"("+QApplication::translate("TurtleRouterStatistics", "Depth")+")");
|
||||
|
||||
painter->drawText(ox+MaxDepth*cellx+30+(MaxTime+1)*cellx+120,oy+celly,"("+QApplication::translate("TurtleRouterStatistics", "total")+")");
|
||||
|
||||
oy += 3*celly ;
|
||||
|
||||
// now, draw a scale
|
||||
|
||||
int last_hts = -1 ;
|
||||
int cellid = 0 ;
|
||||
|
||||
for(int i=0;i<=10;++i)
|
||||
{
|
||||
int hts = (int)(max_bi*i/10.0) ;
|
||||
|
||||
if(hts > last_hts)
|
||||
{
|
||||
painter->fillRect(ox+cellid*(cellx+22),oy,cellx,celly,colorScale(i/10.0f)) ;
|
||||
painter->setPen(QColor::fromRgb(0,0,0)) ;
|
||||
painter->drawRect(ox+cellid*(cellx+22),oy,cellx,celly) ;
|
||||
painter->drawText(ox+cellid*(cellx+22)+cellx+4,oy+celly,QString::number(hts)) ;
|
||||
last_hts = hts ;
|
||||
++cellid ;
|
||||
}
|
||||
}
|
||||
|
||||
oy += celly*2 ;
|
||||
|
||||
ox = save_ox ;
|
||||
}
|
||||
|
||||
private:
|
||||
const std::vector<TurtleRequestDisplayInfo>& _infos ;
|
||||
};
|
||||
|
||||
TurtleRouterStatistics::TurtleRouterStatistics(QWidget *parent)
|
||||
: RsAutoUpdatePage(2000,parent)
|
||||
{
|
||||
setupUi(this) ;
|
||||
|
||||
m_bProcessSettings = false;
|
||||
|
||||
_tunnel_statistics_F->setWidget( _tst_CW = new TurtleRouterStatisticsWidget() ) ;
|
||||
_tunnel_statistics_F->setWidgetResizable(true);
|
||||
_tunnel_statistics_F->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
_tunnel_statistics_F->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
_tunnel_statistics_F->viewport()->setBackgroundRole(QPalette::NoRole);
|
||||
_tunnel_statistics_F->setFrameStyle(QFrame::NoFrame);
|
||||
_tunnel_statistics_F->setFocusPolicy(Qt::NoFocus);
|
||||
|
||||
// load settings
|
||||
processSettings(true);
|
||||
}
|
||||
|
||||
TurtleRouterStatistics::~TurtleRouterStatistics()
|
||||
{
|
||||
|
||||
// save settings
|
||||
processSettings(false);
|
||||
}
|
||||
|
||||
void TurtleRouterStatistics::processSettings(bool bLoad)
|
||||
{
|
||||
m_bProcessSettings = true;
|
||||
|
||||
Settings->beginGroup(QString("TurtleRouterStatistics"));
|
||||
|
||||
if (bLoad) {
|
||||
// load settings
|
||||
|
||||
// state of splitter
|
||||
//splitter->restoreState(Settings->value("Splitter").toByteArray());
|
||||
} else {
|
||||
// save settings
|
||||
|
||||
// state of splitter
|
||||
//Settings->setValue("Splitter", splitter->saveState());
|
||||
|
||||
}
|
||||
|
||||
Settings->endGroup();
|
||||
|
||||
m_bProcessSettings = false;
|
||||
|
||||
}
|
||||
|
||||
void TurtleRouterStatistics::updateDisplay()
|
||||
{
|
||||
std::vector<std::vector<std::string> > hashes_info ;
|
||||
std::vector<std::vector<std::string> > tunnels_info ;
|
||||
std::vector<TurtleRequestDisplayInfo > search_reqs_info ;
|
||||
std::vector<TurtleRequestDisplayInfo > tunnel_reqs_info ;
|
||||
|
||||
rsTurtle->getInfo(hashes_info,tunnels_info,search_reqs_info,tunnel_reqs_info) ;
|
||||
|
||||
//updateTunnelRequests(hashes_info,tunnels_info,search_reqs_info,tunnel_reqs_info) ;
|
||||
_tst_CW->updateTunnelStatistics(hashes_info,tunnels_info,search_reqs_info,tunnel_reqs_info) ;
|
||||
_tst_CW->update();
|
||||
updateTunnelGraph();
|
||||
}
|
||||
|
||||
QString TurtleRouterStatistics::getPeerName(const RsPeerId &peer_id)
|
||||
{
|
||||
static std::map<RsPeerId, QString> names ;
|
||||
|
||||
std::map<RsPeerId,QString>::const_iterator it = names.find(peer_id) ;
|
||||
|
||||
if( it != names.end())
|
||||
return it->second ;
|
||||
else
|
||||
{
|
||||
RsPeerDetails detail ;
|
||||
if(!rsPeers->getPeerDetails(peer_id,detail))
|
||||
return tr("Unknown Peer");
|
||||
|
||||
return (names[peer_id] = QString::fromUtf8(detail.name.c_str())) ;
|
||||
}
|
||||
}
|
||||
|
||||
TurtleRouterStatisticsWidget::TurtleRouterStatisticsWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
maxWidth = 200 ;
|
||||
maxHeight = 0 ;
|
||||
}
|
||||
|
||||
void TurtleRouterStatisticsWidget::updateTunnelStatistics(const std::vector<std::vector<std::string> >& /*hashes_info*/,
|
||||
const std::vector<std::vector<std::string> >& /*tunnels_info*/,
|
||||
const std::vector<TurtleRequestDisplayInfo >& search_reqs_info,
|
||||
const std::vector<TurtleRequestDisplayInfo >& tunnel_reqs_info)
|
||||
|
||||
{
|
||||
static const int cellx = 6 ;
|
||||
static const int celly = 10+4 ;
|
||||
|
||||
QPixmap tmppixmap(maxWidth, maxHeight);
|
||||
tmppixmap.fill(this, 0, 0);
|
||||
setFixedHeight(maxHeight);
|
||||
|
||||
QPainter painter(&tmppixmap);
|
||||
painter.initFrom(this);
|
||||
|
||||
maxHeight = 500 ;
|
||||
|
||||
// std::cerr << "Drawing into pixmap of size " << maxWidth << "x" << maxHeight << std::endl;
|
||||
// draw...
|
||||
int ox=5,oy=5 ;
|
||||
|
||||
TRHistogram(search_reqs_info).draw(&painter,ox,oy,tr("Search requests repartition") + ":") ;
|
||||
|
||||
painter.setPen(QColor::fromRgb(70,70,70)) ;
|
||||
painter.drawLine(0,oy,maxWidth,oy) ;
|
||||
oy += celly ;
|
||||
|
||||
TRHistogram(tunnel_reqs_info).draw(&painter,ox,oy,tr("Tunnel requests repartition") + ":") ;
|
||||
|
||||
// now give information about turtle traffic.
|
||||
//
|
||||
TurtleTrafficStatisticsInfo info ;
|
||||
rsTurtle->getTrafficStatistics(info) ;
|
||||
|
||||
painter.setPen(QColor::fromRgb(70,70,70)) ;
|
||||
painter.drawLine(0,oy,maxWidth,oy) ;
|
||||
oy += celly ;
|
||||
|
||||
painter.drawText(ox,oy+celly,tr("Turtle router traffic")+":") ; oy += celly*2 ;
|
||||
painter.drawText(ox+2*cellx,oy+celly,tr("Tunnel requests Dn")+"\t: " + speedString(info.tr_dn_Bps) ) ; oy += celly ;
|
||||
painter.drawText(ox+2*cellx,oy+celly,tr("Tunnel requests Up")+"\t: " + speedString(info.tr_up_Bps) ) ; oy += celly ;
|
||||
painter.drawText(ox+2*cellx,oy+celly,tr("Incoming file data")+"\t: " + speedString(info.data_dn_Bps) ) ; oy += celly ;
|
||||
painter.drawText(ox+2*cellx,oy+celly,tr("Outgoing file data")+"\t: " + speedString(info.data_up_Bps) ) ; oy += celly ;
|
||||
painter.drawText(ox+2*cellx,oy+celly,tr("Forwarded data ")+"\t: " + speedString(info.unknown_updn_Bps) ) ; oy += celly ;
|
||||
|
||||
QString prob_string ;
|
||||
|
||||
for(uint i=0;i<info.forward_probabilities.size();++i)
|
||||
prob_string += QString::number(info.forward_probabilities[i],'g',2) + " (" + QString::number(i) + ") " ;
|
||||
|
||||
painter.drawText(ox+2*cellx,oy+celly,tr("TR Forward probabilities")+"\t: " + prob_string ) ;
|
||||
oy += celly ;
|
||||
oy += celly ;
|
||||
|
||||
// update the pixmap
|
||||
//
|
||||
pixmap = tmppixmap;
|
||||
maxHeight = oy ;
|
||||
}
|
||||
|
||||
QString TurtleRouterStatisticsWidget::speedString(float f)
|
||||
{
|
||||
if(f < 1.0f)
|
||||
return QString("0 B/s") ;
|
||||
if(f < 1024.0f)
|
||||
return QString::number((int)f)+" B/s" ;
|
||||
|
||||
return QString::number(f/1024.0,'f',2) + " KB/s";
|
||||
}
|
||||
|
||||
void TurtleRouterStatisticsWidget::paintEvent(QPaintEvent */*event*/)
|
||||
{
|
||||
QStylePainter(this).drawPixmap(0, 0, pixmap);
|
||||
}
|
||||
|
||||
void TurtleRouterStatisticsWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QRect TaskGraphRect = geometry();
|
||||
maxWidth = TaskGraphRect.width();
|
||||
maxHeight = TaskGraphRect.height() ;
|
||||
|
||||
QWidget::resizeEvent(event);
|
||||
update();
|
||||
}
|
||||
|
||||
void TurtleRouterStatistics::updateTunnelGraph()
|
||||
{
|
||||
TurtleTrafficStatisticsInfo info ;
|
||||
rsTurtle->getTrafficStatistics(info) ;
|
||||
|
||||
updateGraph(info.tr_up_Bps,info.tr_dn_Bps,info.data_dn_Bps,info.data_up_Bps,info.unknown_updn_Bps);
|
||||
}
|
||||
|
||||
void TurtleRouterStatistics::updateGraph(qreal bytesTrup, qreal bytesTrdown, qreal bytesDatadown, qreal bytesDataup, qreal bytesunknownupdn)
|
||||
{
|
||||
/* Graph only cares about kilobytes */
|
||||
frmGraph->addPoints(bytesTrup/1024.0, bytesTrdown/1024.0, bytesDatadown/1024.0, bytesDataup/1024.0, bytesunknownupdn/1024.0 );
|
||||
}
|
79
retroshare-gui/src/gui/statistics/TurtleRouterStatistics.h
Normal file
79
retroshare-gui/src/gui/statistics/TurtleRouterStatistics.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 20011, RetroShare Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
****************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QPoint>
|
||||
#include <retroshare/rsturtle.h>
|
||||
#include <retroshare/rstypes.h>
|
||||
#include "ui_TurtleRouterStatistics.h"
|
||||
#include "RsAutoUpdatePage.h"
|
||||
|
||||
class TurtleRouterStatisticsWidget ;
|
||||
|
||||
class TurtleRouterStatistics: public RsAutoUpdatePage, public Ui::TurtleRouterStatistics
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TurtleRouterStatistics(QWidget *parent = NULL) ;
|
||||
~TurtleRouterStatistics();
|
||||
|
||||
// Cache for peer names.
|
||||
static QString getPeerName(const RsPeerId& peer_id) ;
|
||||
|
||||
public slots:
|
||||
void updateTunnelGraph();
|
||||
void updateGraph(qreal bytesTrup, qreal bytesTrdown, qreal bytesDatadown, qreal bytesDataup, qreal bytesunknownupdn);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void processSettings(bool bLoad);
|
||||
bool m_bProcessSettings;
|
||||
|
||||
virtual void updateDisplay() ;
|
||||
|
||||
TurtleRouterStatisticsWidget *_tst_CW ;
|
||||
} ;
|
||||
|
||||
class TurtleRouterStatisticsWidget: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TurtleRouterStatisticsWidget(QWidget *parent = NULL) ;
|
||||
|
||||
virtual void paintEvent(QPaintEvent *event) ;
|
||||
virtual void resizeEvent(QResizeEvent *event);
|
||||
|
||||
void updateTunnelStatistics( const std::vector<std::vector<std::basic_string<char> > >&,
|
||||
const std::vector<std::vector<std::basic_string<char> > >&,
|
||||
const std::vector<TurtleRequestDisplayInfo >&,
|
||||
const std::vector<TurtleRequestDisplayInfo >&) ;
|
||||
|
||||
private:
|
||||
static QString speedString(float f) ;
|
||||
|
||||
QPixmap pixmap ;
|
||||
int maxWidth,maxHeight ;
|
||||
};
|
||||
|
87
retroshare-gui/src/gui/statistics/TurtleRouterStatistics.ui
Normal file
87
retroshare-gui/src/gui/statistics/TurtleRouterStatistics.ui
Normal file
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TurtleRouterStatistics</class>
|
||||
<widget class="QWidget" name="TurtleRouterStatistics">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>611</width>
|
||||
<height>513</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Router Statistics</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QScrollArea" name="_tunnel_statistics_F">
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>593</width>
|
||||
<height>289</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="GraphFrameTunnel" name="frmGraph">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>200</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::NoContextMenu</enum>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>GraphFrameTunnel</class>
|
||||
<extends>QFrame</extends>
|
||||
<header>gui/graphframetunnel.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
Loading…
Add table
Add a link
Reference in a new issue