mirror of
https://github.com/RetroShare/RetroShare.git
synced 2026-01-22 10:54:53 -05:00
Added own class for GxsNetTunnelsDialog
* Improved GXS Sync Tunnels display * cleanup code
This commit is contained in:
parent
2e0112b730
commit
3380fccced
7 changed files with 636 additions and 225 deletions
376
retroshare-gui/src/gui/statistics/GxsNetTunnelsDialog.cpp
Normal file
376
retroshare-gui/src/gui/statistics/GxsNetTunnelsDialog.cpp
Normal file
|
|
@ -0,0 +1,376 @@
|
|||
/*******************************************************************************
|
||||
* gui/statistics/GxsNetTunnelsDialog.cpp *
|
||||
* *
|
||||
* Copyright (c) 2025 Retroshare Team <retroshare.project@gmail.com> *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
|
||||
#include "retroshare/rsconfig.h"
|
||||
#include <retroshare/rsturtle.h>
|
||||
#include <retroshare/rspeers.h>
|
||||
#include <retroshare/rsgxstunnel.h>
|
||||
#include <retroshare/rsservicecontrol.h>
|
||||
#include <retroshare/rsidentity.h>
|
||||
#include <retroshare/rsgxsdistsync.h>
|
||||
|
||||
#include "GxsNetTunnelsDialog.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QModelIndex>
|
||||
#include <QHeaderView>
|
||||
#include <QPainter>
|
||||
#include <QStylePainter>
|
||||
#include <algorithm> // for sort
|
||||
#include <time.h>
|
||||
|
||||
#include <util/rsprint.h>
|
||||
#include "util/RsQtVersion.h"
|
||||
#include "gui/settings/rsharesettings.h"
|
||||
|
||||
class NetTunnelsListDelegate: public QAbstractItemDelegate
|
||||
{
|
||||
public:
|
||||
NetTunnelsListDelegate(QObject *parent=0);
|
||||
virtual ~NetTunnelsListDelegate();
|
||||
void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
|
||||
QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const;
|
||||
};
|
||||
|
||||
NetTunnelsListDelegate::NetTunnelsListDelegate(QObject *parent) : QAbstractItemDelegate(parent)
|
||||
{
|
||||
}
|
||||
|
||||
NetTunnelsListDelegate::~NetTunnelsListDelegate(void)
|
||||
{
|
||||
}
|
||||
|
||||
void NetTunnelsListDelegate::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::ForegroundRole);
|
||||
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_SERVICE :
|
||||
painter->drawText(option.rect, Qt::AlignLeft, index.data().toString());
|
||||
break;
|
||||
case COLUMN_GROUPID:
|
||||
painter->drawText(option.rect, Qt::AlignLeft, index.data().toString());
|
||||
break;
|
||||
case COLUMN_POLICY:
|
||||
painter->drawText(option.rect, Qt::AlignLeft, index.data().toString());
|
||||
break;
|
||||
case COLUMN_STATUS:
|
||||
painter->drawText(option.rect, Qt::AlignHCenter, index.data().toString());
|
||||
break;
|
||||
case COLUMN_LASTCONTACT:
|
||||
painter->drawText(option.rect, Qt::AlignLeft, index.data().toString());
|
||||
break;
|
||||
default:
|
||||
painter->drawText(option.rect, Qt::AlignLeft, index.data().toString());
|
||||
}
|
||||
|
||||
// done
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
QSize NetTunnelsListDelegate::sizeHint(const QStyleOptionViewItem & option/*option*/, const QModelIndex & index) const
|
||||
{
|
||||
float FS = QFontMetricsF(option.font).height();
|
||||
//float fact = FS/14.0 ;
|
||||
|
||||
float w = QFontMetrics_horizontalAdvance(QFontMetricsF(option.font), index.data(Qt::DisplayRole).toString());
|
||||
|
||||
return QSize(w,FS*1.2);
|
||||
//return QSize(50*fact,17*fact);
|
||||
}
|
||||
|
||||
GxsNetTunnelsDialog::GxsNetTunnelsDialog(QWidget *parent)
|
||||
: RsAutoUpdatePage(2000,parent)
|
||||
{
|
||||
setupUi(this) ;
|
||||
|
||||
m_ProcessSettings = false;
|
||||
|
||||
TunnelDelegate = new NetTunnelsListDelegate();
|
||||
groups_treeWidget->setItemDelegate(TunnelDelegate);
|
||||
|
||||
float FS = QFontMetricsF(font()).height();
|
||||
float fact = FS/14.0 ;
|
||||
|
||||
QHeaderView * _header = groups_treeWidget->header () ;
|
||||
_header->resizeSection (COLUMN_SERVICE, 270*fact);
|
||||
_header->resizeSection (COLUMN_GROUPID, 270*fact);
|
||||
_header->resizeSection (COLUMN_STATUS, 140*fact);
|
||||
|
||||
// load settings
|
||||
processSettings(true);
|
||||
}
|
||||
|
||||
GxsNetTunnelsDialog::~GxsNetTunnelsDialog()
|
||||
{
|
||||
// save settings
|
||||
processSettings(false);
|
||||
}
|
||||
|
||||
void GxsNetTunnelsDialog::processSettings(bool bLoad)
|
||||
{
|
||||
m_ProcessSettings = true;
|
||||
|
||||
Settings->beginGroup(QString("GxsNetTunnelsDialog"));
|
||||
|
||||
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_ProcessSettings = false;
|
||||
|
||||
}
|
||||
|
||||
static QString getGroupStatusString(RsGxsNetTunnelGroupInfo::GroupStatus group_status)
|
||||
{
|
||||
switch(group_status)
|
||||
{
|
||||
default:
|
||||
case RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_STATUS_UNKNOWN : return QObject::tr("Unknown") ;
|
||||
case RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_STATUS_IDLE : return QObject::tr("Idle");
|
||||
case RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_STATUS_VPIDS_AVAILABLE : return QObject::tr("Virtual peers available");
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
static QString getGroupPolicyString(RsGxsNetTunnelGroupInfo::GroupPolicy group_policy)
|
||||
{
|
||||
switch(group_policy)
|
||||
{
|
||||
default:
|
||||
case RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_POLICY_UNKNOWN : return QObject::tr("Unknown") ;
|
||||
case RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_POLICY_PASSIVE : return QObject::tr("Passive") ;
|
||||
case RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_POLICY_ACTIVE : return QObject::tr("Active") ;
|
||||
case RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_POLICY_REQUESTING : return QObject::tr("Requesting peers") ;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
static QString getLastContactString(time_t last_contact)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
|
||||
if(last_contact == 0)
|
||||
return QObject::tr("Never");
|
||||
|
||||
return QString::number(now - last_contact) + " secs ago" ;
|
||||
}
|
||||
|
||||
static QString getServiceNameString(uint16_t service_id)
|
||||
{
|
||||
static RsPeerServiceInfo ownServices;
|
||||
|
||||
if(ownServices.mServiceList.find(service_id) == ownServices.mServiceList.end())
|
||||
rsServiceControl->getOwnServices(ownServices);
|
||||
|
||||
return QString::fromUtf8(ownServices.mServiceList[RsServiceInfo::RsServiceInfoUIn16ToFullServiceId(service_id)].mServiceName.c_str()) ;
|
||||
}
|
||||
|
||||
static QString getVirtualPeerStatusString(uint8_t status)
|
||||
{
|
||||
switch(status)
|
||||
{
|
||||
default:
|
||||
case RsGxsNetTunnelVirtualPeerInfo::RS_GXS_NET_TUNNEL_VP_STATUS_UNKNOWN : return QObject::tr("Unknown") ;
|
||||
case RsGxsNetTunnelVirtualPeerInfo::RS_GXS_NET_TUNNEL_VP_STATUS_TUNNEL_OK : return QObject::tr("Tunnel OK") ;
|
||||
case RsGxsNetTunnelVirtualPeerInfo::RS_GXS_NET_TUNNEL_VP_STATUS_ACTIVE : return QObject::tr("Tunnel active") ;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
static QString getSideString(uint8_t side)
|
||||
{
|
||||
return side?QObject::tr("Client"):QObject::tr("Server") ;
|
||||
}
|
||||
|
||||
static QString getMasterKeyString(const uint8_t *key,uint32_t size)
|
||||
{
|
||||
return QString::fromStdString(RsUtil::BinToHex(key,size,10));
|
||||
}
|
||||
|
||||
void GxsNetTunnelsDialog::updateDisplay()
|
||||
{
|
||||
/* do nothing if locked, or not visible */
|
||||
if (RsAutoUpdatePage::eventsLocked() == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rsConfig)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
updateTunnels();
|
||||
}
|
||||
|
||||
void GxsNetTunnelsDialog::updateTunnels()
|
||||
{
|
||||
// RsGxsNetTunnelGroupInfo:
|
||||
//
|
||||
// enum GroupStatus {
|
||||
// RS_GXS_NET_TUNNEL_GRP_STATUS_UNKNOWN = 0x00, // unknown status
|
||||
// RS_GXS_NET_TUNNEL_GRP_STATUS_IDLE = 0x01, // no virtual peers requested, just waiting
|
||||
// RS_GXS_NET_TUNNEL_GRP_STATUS_VPIDS_AVAILABLE = 0x02 // some virtual peers are available. Data can be read/written
|
||||
// };
|
||||
// enum GroupPolicy {
|
||||
// RS_GXS_NET_TUNNEL_GRP_POLICY_UNKNOWN = 0x00, // nothing has been set
|
||||
// RS_GXS_NET_TUNNEL_GRP_POLICY_PASSIVE = 0x01, // group is available for server side tunnels, but does not explicitely request tunnels
|
||||
// RS_GXS_NET_TUNNEL_GRP_POLICY_ACTIVE = 0x02, // group will only explicitely request tunnels if none available
|
||||
// RS_GXS_NET_TUNNEL_GRP_POLICY_REQUESTING = 0x03, // group explicitely requests tunnels
|
||||
// };
|
||||
//
|
||||
// RsGxsNetTunnelGroupInfo() : group_policy(RS_GXS_NET_TUNNEL_GRP_POLICY_PASSIVE),group_status(RS_GXS_NET_TUNNEL_GRP_STATUS_IDLE),last_contact(0) {}
|
||||
//
|
||||
// GroupPolicy group_policy ;
|
||||
// GroupStatus group_status ;
|
||||
// time_t last_contact ;
|
||||
// RsFileHash hash ;
|
||||
// uint16_t service_id ;
|
||||
// std::set<RsPeerId> virtual_peers ;
|
||||
//
|
||||
// struct RsGxsNetTunnelVirtualPeerInfo:
|
||||
//
|
||||
// enum { RS_GXS_NET_TUNNEL_VP_STATUS_UNKNOWN = 0x00, // unknown status.
|
||||
// RS_GXS_NET_TUNNEL_VP_STATUS_TUNNEL_OK = 0x01, // tunnel has been established and we're waiting for virtual peer id
|
||||
// RS_GXS_NET_TUNNEL_VP_STATUS_ACTIVE = 0x02 // virtual peer id is known. Data can transfer.
|
||||
// };
|
||||
//
|
||||
// RsGxsNetTunnelVirtualPeerInfo() : vpid_status(RS_GXS_NET_TUNNEL_VP_STATUS_UNKNOWN), last_contact(0),side(0) { memset(encryption_master_key,0,32) ; }
|
||||
// virtual ~RsGxsNetTunnelVirtualPeerInfo(){}
|
||||
//
|
||||
// uint8_t vpid_status ; // status of the peer
|
||||
// time_t last_contact ; // last time some data was sent/recvd
|
||||
// uint8_t side ; // client/server
|
||||
// uint8_t encryption_master_key[32];
|
||||
//
|
||||
// RsPeerId turtle_virtual_peer_id ; // turtle peer to use when sending data to this vpid.
|
||||
//
|
||||
// RsGxsGroupId group_id ; // group that virtual peer is providing
|
||||
// uint16_t service_id ; // this is used for checkng consistency of the incoming data
|
||||
|
||||
QTreeWidget *peerTreeWidget = groups_treeWidget;
|
||||
|
||||
// Clear existing items to prevent duplicates on refresh
|
||||
peerTreeWidget->clear();
|
||||
|
||||
// Request info about ongoing tunnels
|
||||
std::map<RsGxsGroupId, RsGxsNetTunnelGroupInfo> groups; // groups on the client and server side
|
||||
std::map<TurtleVirtualPeerId, RsGxsNetTunnelVirtualPeerId> turtle2gxsnettunnel; // convertion table from turtle to net tunnel virtual peer id
|
||||
std::map<RsGxsNetTunnelVirtualPeerId, RsGxsNetTunnelVirtualPeerInfo> virtual_peers; // current virtual peers, which group they provide, and how to talk to them through turtle
|
||||
Bias20Bytes bias;
|
||||
|
||||
// Fetch data from rsGxsDistSync
|
||||
if (rsGxsDistSync) {
|
||||
rsGxsDistSync->getStatistics(groups, virtual_peers, turtle2gxsnettunnel, bias);
|
||||
}
|
||||
|
||||
randombias->setText(tr("Random Bias: %1").arg(getMasterKeyString(bias.toByteArray(),20))) ;
|
||||
peerTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
|
||||
for(auto it = groups.begin(); it != groups.end(); ++it)
|
||||
{
|
||||
// Create the Parent (Group) Item
|
||||
QTreeWidgetItem *groups_item = new QTreeWidgetItem(peerTreeWidget);
|
||||
groups_item->setExpanded(true); // This prevents it from "closing"
|
||||
|
||||
// Populate Group Data
|
||||
groups_item->setData(COLUMN_SERVICE, Qt::DisplayRole, "0x" + QString::number(it->second.service_id, 16) + " (" + getServiceNameString(it->second.service_id) + ")");
|
||||
groups_item->setData(COLUMN_GROUPID, Qt::DisplayRole, QString::fromStdString(it->first.toStdString()));
|
||||
groups_item->setData(COLUMN_POLICY, Qt::DisplayRole, getGroupPolicyString(it->second.group_policy));
|
||||
groups_item->setData(COLUMN_STATUS, Qt::DisplayRole, getGroupStatusString(it->second.group_status));
|
||||
groups_item->setData(COLUMN_LASTCONTACT, Qt::DisplayRole, getLastContactString(it->second.last_contact));
|
||||
|
||||
// Iterate through Virtual Peers for this group
|
||||
for(auto it2 = it->second.virtual_peers.begin(); it2 != it->second.virtual_peers.end(); ++it2)
|
||||
{
|
||||
auto it4 = turtle2gxsnettunnel.find(*it2);
|
||||
QTreeWidgetItem *peers_item = new QTreeWidgetItem(groups_item); // Set parent immediately
|
||||
|
||||
if(it4 != turtle2gxsnettunnel.end())
|
||||
{
|
||||
auto it3 = virtual_peers.find(it4->second);
|
||||
|
||||
if(it3 != virtual_peers.end())
|
||||
{
|
||||
// Populate Peer Data
|
||||
peers_item->setData(COLUMN_SERVICE, Qt::DisplayRole, QString::fromStdString((*it2).toStdString()));
|
||||
peers_item->setData(COLUMN_GROUPID, Qt::DisplayRole, getMasterKeyString(it3->second.encryption_master_key, 32));
|
||||
peers_item->setData(COLUMN_STATUS, Qt::DisplayRole, getVirtualPeerStatusString(it3->second.vpid_status) + " (" + getSideString(it3->second.side) + ")");
|
||||
peers_item->setData(COLUMN_LASTCONTACT, Qt::DisplayRole, getLastContactString(it3->second.last_contact));
|
||||
}
|
||||
else
|
||||
{
|
||||
peers_item->setData(COLUMN_SERVICE, Qt::DisplayRole, QString::fromStdString((*it2).toStdString()) + " (No info)");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
peers_item->setData(COLUMN_SERVICE, Qt::DisplayRole, QString::fromStdString((*it2).toStdString()) );
|
||||
peers_item->setData(COLUMN_GROUPID, Qt::DisplayRole, tr(" (No Peer information available)"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
63
retroshare-gui/src/gui/statistics/GxsNetTunnelsDialog.h
Normal file
63
retroshare-gui/src/gui/statistics/GxsNetTunnelsDialog.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*******************************************************************************
|
||||
* gui/statistics/GxsNetTunnelsDialog.h *
|
||||
* *
|
||||
* Copyright (c) 2025 Retroshare Team <retroshare.project@gmail.com> *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include <QAbstractItemDelegate>
|
||||
|
||||
#include <retroshare/rsturtle.h>
|
||||
#include <retroshare/rstypes.h>
|
||||
|
||||
#include <retroshare-gui/RsAutoUpdatePage.h>
|
||||
|
||||
#include "ui_GxsNetTunnelsDialog.h"
|
||||
|
||||
// Defines for download list list columns
|
||||
#define COLUMN_SERVICE 0
|
||||
#define COLUMN_GROUPID 1
|
||||
#define COLUMN_POLICY 2
|
||||
#define COLUMN_STATUS 3
|
||||
#define COLUMN_LASTCONTACT 4
|
||||
|
||||
class QModelIndex;
|
||||
class QPainter;
|
||||
class NetTunnelsListDelegate ;
|
||||
|
||||
class GxsNetTunnelsDialog: public RsAutoUpdatePage, public Ui::GxsNetTunnelsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GxsNetTunnelsDialog(QWidget *parent = NULL) ;
|
||||
~GxsNetTunnelsDialog();
|
||||
|
||||
void updateTunnels();
|
||||
|
||||
public slots:
|
||||
virtual void updateDisplay() ;
|
||||
|
||||
private:
|
||||
void processSettings(bool bLoad);
|
||||
bool m_ProcessSettings;
|
||||
|
||||
QTreeWidgetItem *peers_item ;
|
||||
|
||||
protected:
|
||||
NetTunnelsListDelegate *TunnelDelegate;
|
||||
} ;
|
||||
72
retroshare-gui/src/gui/statistics/GxsNetTunnelsDialog.ui
Normal file
72
retroshare-gui/src/gui/statistics/GxsNetTunnelsDialog.ui
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>GxsNetTunnelsDialog</class>
|
||||
<widget class="QWidget" name="GxsNetTunnelsDialog">
|
||||
<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_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>GXS Groups</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTreeWidget" name="groups_treeWidget">
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="headerHidden">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Service</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Group ID / Master Key</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Policy</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Status</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Last contact</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="randombias">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
@ -32,6 +32,7 @@
|
|||
#include <algorithm> // for sort
|
||||
#include <time.h>
|
||||
|
||||
#include "util/RsQtVersion.h"
|
||||
#include "gui/settings/rsharesettings.h"
|
||||
|
||||
#define COL_ID 0
|
||||
|
|
@ -46,6 +47,112 @@
|
|||
|
||||
static const uint MAX_TUNNEL_REQUESTS_DISPLAY = 10 ;
|
||||
|
||||
class FTTunnelsListDelegate: public QAbstractItemDelegate
|
||||
{
|
||||
public:
|
||||
FTTunnelsListDelegate(QObject *parent=0);
|
||||
virtual ~FTTunnelsListDelegate();
|
||||
void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
|
||||
QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const;
|
||||
};
|
||||
|
||||
FTTunnelsListDelegate::FTTunnelsListDelegate(QObject *parent) : QAbstractItemDelegate(parent)
|
||||
{
|
||||
}
|
||||
|
||||
FTTunnelsListDelegate::~FTTunnelsListDelegate(void)
|
||||
{
|
||||
}
|
||||
|
||||
void FTTunnelsListDelegate::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::ForegroundRole);
|
||||
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_SERVICE :
|
||||
//temp = QString::asprintf("%.3f ", index.data().toFloat());
|
||||
//temp=QString::number(index.data().toFloat());
|
||||
painter->drawText(option.rect, Qt::AlignLeft, index.data().toString());
|
||||
break;
|
||||
case COLUMN_GROUPID:
|
||||
//temp = QString::asprintf("%.3f ", index.data().toFloat());
|
||||
//temp=QString::number(index.data().toFloat());
|
||||
painter->drawText(option.rect, Qt::AlignLeft, index.data().toString());
|
||||
break;
|
||||
case COLUMN_POLICY:
|
||||
//temp=QString::number(index.data().toInt());
|
||||
painter->drawText(option.rect, Qt::AlignLeft, index.data().toString());
|
||||
break;
|
||||
case COLUMN_STATUS:
|
||||
/*flValue = index.data().toFloat();
|
||||
if (flValue < std::numeric_limits<float>::max()){
|
||||
temp = QString::asprintf("%.3f ", flValue);
|
||||
} else {
|
||||
temp=strNA;
|
||||
}*/
|
||||
/*painter->drawText(option.rect, Qt::AlignHCenter, index.data().toString());
|
||||
break;
|
||||
case COLUMN_LASTCONTACT:
|
||||
/*qi64Value = index.data().value<qint64>();
|
||||
if (qi64Value < std::numeric_limits<qint64>::max()){
|
||||
temp= QString::number(qi64Value);
|
||||
} else {
|
||||
temp = strNA;
|
||||
}*/
|
||||
/*painter->drawText(option.rect, Qt::AlignHCenter, index.data().toString());
|
||||
break;*/
|
||||
default:
|
||||
painter->drawText(option.rect, Qt::AlignLeft, index.data().toString());
|
||||
}
|
||||
|
||||
// done
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
QSize FTTunnelsListDelegate::sizeHint(const QStyleOptionViewItem & option/*option*/, const QModelIndex & index) const
|
||||
{
|
||||
float FS = QFontMetricsF(option.font).height();
|
||||
//float fact = FS/14.0 ;
|
||||
|
||||
float w = QFontMetrics_horizontalAdvance(QFontMetricsF(option.font), index.data(Qt::DisplayRole).toString());
|
||||
|
||||
return QSize(w,FS*1.2);
|
||||
//return QSize(50*fact,17*fact);
|
||||
}
|
||||
|
||||
TurtleRouterDialog::TurtleRouterDialog(QWidget *parent)
|
||||
: RsAutoUpdatePage(2000,parent)
|
||||
|
|
@ -59,6 +166,10 @@ TurtleRouterDialog::TurtleRouterDialog(QWidget *parent)
|
|||
QStringList stl ;
|
||||
int n=0 ;
|
||||
|
||||
FTTDelegate = new FTTunnelsListDelegate();
|
||||
_f2f_TW->setItemDelegate(FTTDelegate);
|
||||
tunnels_treeWidget->setItemDelegate(FTTDelegate);
|
||||
|
||||
stl.clear() ;
|
||||
stl.push_back(tr("Search requests")) ;
|
||||
top_level_s_requests = new QTreeWidgetItem(_f2f_TW,stl) ;
|
||||
|
|
@ -174,6 +285,9 @@ void TurtleRouterDialog::updateTunnelRequests( const std::vector<std::vector<std
|
|||
delete taken ;
|
||||
}
|
||||
|
||||
_f2f_TW->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
tunnels_treeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
|
||||
for(uint i=0;i<hashes_info.size();++i)
|
||||
findParentHashItem(hashes_info[i][0]) ;
|
||||
|
||||
|
|
@ -197,12 +311,6 @@ void TurtleRouterDialog::updateTunnelRequests( const std::vector<std::vector<std
|
|||
num /= 1024.0f,++k;
|
||||
sprintf(tmp,"%3.2f %s",num,units[k].c_str()) ;
|
||||
|
||||
//QString str = tr("Tunnel id") + ": " + QString::fromUtf8(tunnels_info[i][0].c_str()) + "\t" + tr("Speed") + ": " + QString::fromStdString(tmp) + "\t " + tr("last transfer") + ": " + QString::fromStdString(tunnels_info[i][4])+ "\t" + QString::fromUtf8(tunnels_info[i][2].c_str()) + " -> " + QString::fromUtf8(tunnels_info[i][1].c_str());
|
||||
//stl.clear() ;
|
||||
//stl.push_back(str) ;
|
||||
//QTreeWidgetItem *item = new QTreeWidgetItem(stl);
|
||||
//parent->addChild(item);
|
||||
|
||||
QTreeWidgetItem *tunnel_item = NULL;
|
||||
tunnel_item = new QTreeWidgetItem();
|
||||
|
||||
|
|
@ -231,11 +339,7 @@ void TurtleRouterDialog::updateTunnelRequests( const std::vector<std::vector<std
|
|||
|
||||
for(uint i=0;i<search_reqs_info.size();++i)
|
||||
{
|
||||
//QString str = tr("Request id: %1\t %3 secs ago\t from %2\t %4 (%5 hits)").arg(search_reqs_info[i].request_id,0,16).arg(getPeerName(search_reqs_info[i].source_peer_id), -25).arg(search_reqs_info[i].age).arg(QString::fromUtf8(search_reqs_info[i].keywords.c_str(),search_reqs_info[i].keywords.length())).arg(QString::number(search_reqs_info[i].hits));
|
||||
|
||||
//stl.clear() ;
|
||||
//stl.push_back(str) ;
|
||||
|
||||
|
||||
QTreeWidgetItem *sr_item = NULL;
|
||||
sr_item = new QTreeWidgetItem();
|
||||
top_level_s_requests->addChild(sr_item) ;
|
||||
|
|
@ -245,17 +349,12 @@ void TurtleRouterDialog::updateTunnelRequests( const std::vector<std::vector<std
|
|||
sr_item->setData(COL_TIME, Qt::DisplayRole, QString::number(search_reqs_info[i].age) + " secs ago");
|
||||
sr_item->setData(COL_STRING, Qt::DisplayRole, QString::fromUtf8(search_reqs_info[i].keywords.c_str()) + QString::number(search_reqs_info[i].keywords.length()) + " (" + QString::number(search_reqs_info[i].hits) + " hits)");
|
||||
|
||||
//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) ;
|
||||
/* find the entry */
|
||||
QTreeWidgetItem *tunnelr_item = NULL;
|
||||
tunnelr_item = new QTreeWidgetItem();
|
||||
|
|
@ -264,8 +363,6 @@ void TurtleRouterDialog::updateTunnelRequests( const std::vector<std::vector<std
|
|||
tunnelr_item->setData(COL_ID, Qt::DisplayRole, QString::number(tunnel_reqs_info[i].request_id));
|
||||
tunnelr_item->setData(COL_FROM, Qt::DisplayRole, getPeerName(tunnel_reqs_info[i].source_peer_id) ) ;
|
||||
tunnelr_item->setData(COL_TIME, Qt::DisplayRole, QString::number(tunnel_reqs_info[i].age) + " secs ago");
|
||||
|
||||
//top_level_t_requests->addChild(new QTreeWidgetItem(stl)) ;
|
||||
}
|
||||
else if(i == MAX_TUNNEL_REQUESTS_DISPLAY)
|
||||
{
|
||||
|
|
@ -495,198 +592,3 @@ void GxsAuthenticatedTunnelsDialog::updateDisplay()
|
|||
pixmap = tmppixmap;
|
||||
maxHeight = std::max(oy,10*celly);
|
||||
}
|
||||
|
||||
//=======================================================================================================================//
|
||||
|
||||
GxsNetTunnelsDialog::GxsNetTunnelsDialog(QWidget *parent)
|
||||
: TunnelStatisticsDialog(parent)
|
||||
{
|
||||
}
|
||||
|
||||
static QString getGroupStatusString(RsGxsNetTunnelGroupInfo::GroupStatus group_status)
|
||||
{
|
||||
switch(group_status)
|
||||
{
|
||||
default:
|
||||
case RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_STATUS_UNKNOWN : return QObject::tr("Unknown") ;
|
||||
case RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_STATUS_IDLE : return QObject::tr("Idle");
|
||||
case RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_STATUS_VPIDS_AVAILABLE : return QObject::tr("Virtual peers available");
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
static QString getGroupPolicyString(RsGxsNetTunnelGroupInfo::GroupPolicy group_policy)
|
||||
{
|
||||
switch(group_policy)
|
||||
{
|
||||
default:
|
||||
case RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_POLICY_UNKNOWN : return QObject::tr("Unknown") ;
|
||||
case RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_POLICY_PASSIVE : return QObject::tr("Passive") ;
|
||||
case RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_POLICY_ACTIVE : return QObject::tr("Active") ;
|
||||
case RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_POLICY_REQUESTING : return QObject::tr("Requesting peers") ;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
static QString getLastContactString(time_t last_contact)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
|
||||
if(last_contact == 0)
|
||||
return QObject::tr("Never");
|
||||
|
||||
return QString::number(now - last_contact) + " secs ago" ;
|
||||
}
|
||||
|
||||
static QString getServiceNameString(uint16_t service_id)
|
||||
{
|
||||
static RsPeerServiceInfo ownServices;
|
||||
|
||||
if(ownServices.mServiceList.find(service_id) == ownServices.mServiceList.end())
|
||||
rsServiceControl->getOwnServices(ownServices);
|
||||
|
||||
return QString::fromUtf8(ownServices.mServiceList[RsServiceInfo::RsServiceInfoUIn16ToFullServiceId(service_id)].mServiceName.c_str()) ;
|
||||
}
|
||||
|
||||
static QString getVirtualPeerStatusString(uint8_t status)
|
||||
{
|
||||
switch(status)
|
||||
{
|
||||
default:
|
||||
case RsGxsNetTunnelVirtualPeerInfo::RS_GXS_NET_TUNNEL_VP_STATUS_UNKNOWN : return QObject::tr("Unknown") ;
|
||||
case RsGxsNetTunnelVirtualPeerInfo::RS_GXS_NET_TUNNEL_VP_STATUS_TUNNEL_OK : return QObject::tr("Tunnel OK") ;
|
||||
case RsGxsNetTunnelVirtualPeerInfo::RS_GXS_NET_TUNNEL_VP_STATUS_ACTIVE : return QObject::tr("Tunnel active") ;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
static QString getSideString(uint8_t side)
|
||||
{
|
||||
return side?QObject::tr("Client"):QObject::tr("Server") ;
|
||||
}
|
||||
|
||||
static QString getMasterKeyString(const uint8_t *key,uint32_t size)
|
||||
{
|
||||
return QString::fromStdString(RsUtil::BinToHex(key,size,10));
|
||||
}
|
||||
|
||||
void GxsNetTunnelsDialog::updateDisplay()
|
||||
{
|
||||
// Request info about ongoing tunnels
|
||||
|
||||
std::map<RsGxsGroupId,RsGxsNetTunnelGroupInfo> groups; // groups on the client and server side
|
||||
std::map<TurtleVirtualPeerId,RsGxsNetTunnelVirtualPeerId> turtle2gxsnettunnel; // convertion table from turtle to net tunnel virtual peer id
|
||||
std::map<RsGxsNetTunnelVirtualPeerId, RsGxsNetTunnelVirtualPeerInfo> virtual_peers; // current virtual peers, which group they provide, and how to talk to them through turtle
|
||||
Bias20Bytes bias;
|
||||
|
||||
rsGxsDistSync->getStatistics(groups,virtual_peers,turtle2gxsnettunnel,bias) ;
|
||||
|
||||
// RsGxsNetTunnelGroupInfo:
|
||||
//
|
||||
// enum GroupStatus {
|
||||
// RS_GXS_NET_TUNNEL_GRP_STATUS_UNKNOWN = 0x00, // unknown status
|
||||
// RS_GXS_NET_TUNNEL_GRP_STATUS_IDLE = 0x01, // no virtual peers requested, just waiting
|
||||
// RS_GXS_NET_TUNNEL_GRP_STATUS_VPIDS_AVAILABLE = 0x02 // some virtual peers are available. Data can be read/written
|
||||
// };
|
||||
// enum GroupPolicy {
|
||||
// RS_GXS_NET_TUNNEL_GRP_POLICY_UNKNOWN = 0x00, // nothing has been set
|
||||
// RS_GXS_NET_TUNNEL_GRP_POLICY_PASSIVE = 0x01, // group is available for server side tunnels, but does not explicitely request tunnels
|
||||
// RS_GXS_NET_TUNNEL_GRP_POLICY_ACTIVE = 0x02, // group will only explicitely request tunnels if none available
|
||||
// RS_GXS_NET_TUNNEL_GRP_POLICY_REQUESTING = 0x03, // group explicitely requests tunnels
|
||||
// };
|
||||
//
|
||||
// RsGxsNetTunnelGroupInfo() : group_policy(RS_GXS_NET_TUNNEL_GRP_POLICY_PASSIVE),group_status(RS_GXS_NET_TUNNEL_GRP_STATUS_IDLE),last_contact(0) {}
|
||||
//
|
||||
// GroupPolicy group_policy ;
|
||||
// GroupStatus group_status ;
|
||||
// time_t last_contact ;
|
||||
// RsFileHash hash ;
|
||||
// uint16_t service_id ;
|
||||
// std::set<RsPeerId> virtual_peers ;
|
||||
//
|
||||
// struct RsGxsNetTunnelVirtualPeerInfo:
|
||||
//
|
||||
// enum { RS_GXS_NET_TUNNEL_VP_STATUS_UNKNOWN = 0x00, // unknown status.
|
||||
// RS_GXS_NET_TUNNEL_VP_STATUS_TUNNEL_OK = 0x01, // tunnel has been established and we're waiting for virtual peer id
|
||||
// RS_GXS_NET_TUNNEL_VP_STATUS_ACTIVE = 0x02 // virtual peer id is known. Data can transfer.
|
||||
// };
|
||||
//
|
||||
// RsGxsNetTunnelVirtualPeerInfo() : vpid_status(RS_GXS_NET_TUNNEL_VP_STATUS_UNKNOWN), last_contact(0),side(0) { memset(encryption_master_key,0,32) ; }
|
||||
// virtual ~RsGxsNetTunnelVirtualPeerInfo(){}
|
||||
//
|
||||
// uint8_t vpid_status ; // status of the peer
|
||||
// time_t last_contact ; // last time some data was sent/recvd
|
||||
// uint8_t side ; // client/server
|
||||
// uint8_t encryption_master_key[32];
|
||||
//
|
||||
// RsPeerId turtle_virtual_peer_id ; // turtle peer to use when sending data to this vpid.
|
||||
//
|
||||
// RsGxsGroupId group_id ; // group that virtual peer is providing
|
||||
// uint16_t service_id ; // this is used for checkng consistency of the incoming data
|
||||
|
||||
// update the pixmap
|
||||
//
|
||||
|
||||
// now draw the shit
|
||||
QPixmap tmppixmap(maxWidth, maxHeight);
|
||||
tmppixmap.fill(Qt::transparent);
|
||||
//setFixedHeight(maxHeight);
|
||||
|
||||
QPainter painter(&tmppixmap);
|
||||
painter.begin(this);
|
||||
|
||||
// extracts the height of the fonts in pixels. This is used to calibrate the size of the objects to draw.
|
||||
|
||||
float fontHeight = QFontMetricsF(font()).height();
|
||||
float fact = fontHeight/14.0;
|
||||
|
||||
int cellx = 6*fact ;
|
||||
int celly = (10+4)*fact ;
|
||||
int ox=5*fact,oy=5*fact ;
|
||||
|
||||
painter.setPen(QColor::fromRgb(0,0,0)) ;
|
||||
painter.drawText(ox+2*cellx,oy+celly,tr("Random Bias: %1").arg(getMasterKeyString(bias.toByteArray(),20))) ; oy += celly ;
|
||||
painter.drawText(ox+2*cellx,oy+celly,tr("GXS Groups:")) ; oy += celly ;
|
||||
|
||||
for(auto it(groups.begin());it!=groups.end();++it)
|
||||
{
|
||||
painter.drawText(ox+4*cellx,oy+celly,tr("Service: %1 (%2) - Group ID: %3,\t policy: %4, \tstatus: %5, \tlast contact: %6")
|
||||
.arg("0x" + QString::number(it->second.service_id, 16))
|
||||
.arg(getServiceNameString(it->second.service_id))
|
||||
.arg(QString::fromStdString(it->first.toStdString()))
|
||||
.arg(getGroupPolicyString(it->second.group_policy))
|
||||
.arg(getGroupStatusString(it->second.group_status))
|
||||
.arg(getLastContactString(it->second.last_contact))
|
||||
),oy+=celly ;
|
||||
|
||||
|
||||
for(auto it2(it->second.virtual_peers.begin());it2!=it->second.virtual_peers.end();++it2)
|
||||
{
|
||||
auto it4 = turtle2gxsnettunnel.find(*it2) ;
|
||||
|
||||
if(it4 != turtle2gxsnettunnel.end())
|
||||
{
|
||||
auto it3 = virtual_peers.find(it4->second) ;
|
||||
|
||||
if(virtual_peers.end() != it3)
|
||||
painter.drawText(ox+6*cellx,oy+celly,tr("Peer: %1:\tstatus: %2/%3, \tlast contact: %4, \tMaster key: %5.")
|
||||
.arg(QString::fromStdString((*it2).toStdString()))
|
||||
.arg(getVirtualPeerStatusString(it3->second.vpid_status))
|
||||
.arg(getSideString(it3->second.side))
|
||||
.arg(getLastContactString(it3->second.last_contact))
|
||||
.arg(getMasterKeyString(it3->second.encryption_master_key,32))
|
||||
),oy+=celly ;
|
||||
}
|
||||
else
|
||||
painter.drawText(ox+6*cellx,oy+celly,tr("Peer: %1: no information available")
|
||||
.arg(QString::fromStdString((*it2).toStdString()))
|
||||
),oy+=celly;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
oy += celly ;
|
||||
|
||||
pixmap = tmppixmap;
|
||||
maxHeight = std::max(oy,10*celly);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@
|
|||
#include "ui_TurtleRouterDialog.h"
|
||||
#include "ui_TurtleRouterStatistics.h"
|
||||
|
||||
class QModelIndex;
|
||||
class QPainter;
|
||||
class FTTunnelsListDelegate ;
|
||||
|
||||
class TurtleRouterDialog: public RsAutoUpdatePage, public Ui::TurtleRouterDialogForm
|
||||
{
|
||||
|
|
@ -57,6 +60,9 @@ class TurtleRouterDialog: public RsAutoUpdatePage, public Ui::TurtleRouterDialog
|
|||
QTreeWidgetItem *top_level_s_requests ;
|
||||
QTreeWidgetItem *top_level_t_requests ;
|
||||
|
||||
protected:
|
||||
FTTunnelsListDelegate *FTTDelegate;
|
||||
|
||||
} ;
|
||||
|
||||
class TunnelStatisticsDialog: public RsAutoUpdatePage
|
||||
|
|
@ -99,15 +105,3 @@ public:
|
|||
private:
|
||||
virtual void updateDisplay() ;
|
||||
} ;
|
||||
|
||||
class GxsNetTunnelsDialog: public TunnelStatisticsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GxsNetTunnelsDialog(QWidget *parent = NULL) ;
|
||||
~GxsNetTunnelsDialog() {}
|
||||
|
||||
private:
|
||||
virtual void updateDisplay() ;
|
||||
} ;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include <retroshare/rspeers.h>
|
||||
#include "TurtleRouterStatistics.h"
|
||||
#include "TurtleRouterDialog.h"
|
||||
#include "GxsNetTunnelsDialog.h"
|
||||
|
||||
#include "gui/settings/rsharesettings.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -418,6 +418,7 @@ HEADERS += rshare.h \
|
|||
gui/statistics/DhtWindow.h \
|
||||
gui/statistics/GlobalRouterStatistics.h \
|
||||
gui/statistics/GxsTransportStatistics.h \
|
||||
gui/statistics/GxsNetTunnelsDialog.h \
|
||||
gui/statistics/StatisticsWindow.h \
|
||||
gui/statistics/BwCtrlWindow.h \
|
||||
gui/statistics/RttStatistics.h \
|
||||
|
|
@ -723,6 +724,7 @@ FORMS += gui/StartDialog.ui \
|
|||
gui/statistics/GxsIdStatistics.ui \
|
||||
gui/statistics/GlobalRouterStatistics.ui \
|
||||
gui/statistics/GxsTransportStatistics.ui \
|
||||
gui/statistics/GxsNetTunnelsDialog.ui \
|
||||
gui/statistics/StatisticsWindow.ui \
|
||||
gui/statistics/BwCtrlWindow.ui \
|
||||
gui/statistics/RttStatistics.ui \
|
||||
|
|
@ -974,6 +976,7 @@ SOURCES += main.cpp \
|
|||
gui/statistics/GxsIdStatistics.cpp \
|
||||
gui/statistics/GlobalRouterStatistics.cpp \
|
||||
gui/statistics/GxsTransportStatistics.cpp \
|
||||
gui/statistics/GxsNetTunnelsDialog.cpp \
|
||||
gui/statistics/StatisticsWindow.cpp \
|
||||
gui/statistics/BwCtrlWindow.cpp \
|
||||
gui/statistics/RttStatistics.cpp \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue