mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-12-31 16:20:26 -05:00
Merge dd81d97085 into a17699e166
This commit is contained in:
commit
eb48c88fec
3 changed files with 216 additions and 49 deletions
|
|
@ -18,12 +18,18 @@
|
|||
* *
|
||||
*******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* gui/statistics/RttStatistics.cpp *
|
||||
*******************************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <QTimer>
|
||||
#include <QObject>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QStylePainter>
|
||||
#include <QHostAddress>
|
||||
#include <QHash>
|
||||
|
||||
#include <retroshare/rsrtt.h>
|
||||
#include <retroshare/rspeers.h>
|
||||
|
|
@ -32,13 +38,49 @@
|
|||
|
||||
#include "gui/settings/rsharesettings.h"
|
||||
|
||||
// --- Custom Item for Sorting (Table) ---
|
||||
class RttTreeItem : public QTreeWidgetItem {
|
||||
public:
|
||||
using QTreeWidgetItem::QTreeWidgetItem;
|
||||
|
||||
bool operator<(const QTreeWidgetItem &other) const {
|
||||
int sortCol = treeWidget() ? treeWidget()->sortColumn() : 0;
|
||||
|
||||
// RTT Sort
|
||||
if (sortCol == 1) {
|
||||
QString txt1 = text(1);
|
||||
QString txt2 = other.text(1);
|
||||
long val1 = (txt1 == "?") ? std::numeric_limits<long>::max() : txt1.toLong();
|
||||
long val2 = (txt2 == "?") ? std::numeric_limits<long>::max() : txt2.toLong();
|
||||
return val1 < val2;
|
||||
}
|
||||
// IP Sort
|
||||
if (sortCol == 3) {
|
||||
QString s1 = text(3);
|
||||
QString s2 = other.text(3);
|
||||
QHostAddress ip1(s1); QHostAddress ip2(s2);
|
||||
bool isTorI2p1 = s1.contains(".onion") || s1.contains(".i2p");
|
||||
bool isTorI2p2 = s2.contains(".onion") || s2.contains(".i2p");
|
||||
|
||||
if (!ip1.isNull() && !ip2.isNull() && !isTorI2p1 && !isTorI2p2) {
|
||||
if (ip1.protocol() != ip2.protocol()) return ip1.protocol() < ip2.protocol();
|
||||
if (ip1.protocol() == QAbstractSocket::IPv4Protocol) return ip1.toIPv4Address() < ip2.toIPv4Address();
|
||||
}
|
||||
return s1 < s2;
|
||||
}
|
||||
return QTreeWidgetItem::operator<(other);
|
||||
}
|
||||
};
|
||||
|
||||
// --- Main Constructor ---
|
||||
|
||||
RttStatistics::RttStatistics(QWidget * /*parent*/)
|
||||
{
|
||||
setupUi(this) ;
|
||||
|
||||
|
||||
m_bProcessSettings = false;
|
||||
|
||||
// Setup Graph in Tab 1
|
||||
_tunnel_statistics_F->setWidget( _tst_CW = new RttStatisticsGraph(this) ) ;
|
||||
_tunnel_statistics_F->setWidgetResizable(true);
|
||||
_tunnel_statistics_F->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
|
@ -46,14 +88,24 @@ RttStatistics::RttStatistics(QWidget * /*parent*/)
|
|||
_tunnel_statistics_F->viewport()->setBackgroundRole(QPalette::NoRole);
|
||||
_tunnel_statistics_F->setFrameStyle(QFrame::NoFrame);
|
||||
_tunnel_statistics_F->setFocusPolicy(Qt::NoFocus);
|
||||
|
||||
|
||||
// Setup Table in Tab 2
|
||||
treeWidget->setAlternatingRowColors(true);
|
||||
treeWidget->setSortingEnabled(true);
|
||||
treeWidget->sortByColumn(1, Qt::AscendingOrder);
|
||||
|
||||
// Timer for Table Update
|
||||
m_timer = new QTimer(this);
|
||||
connect(m_timer, SIGNAL(timeout()), this, SLOT(updateRttValues()));
|
||||
m_timer->start(1000);
|
||||
|
||||
// load settings
|
||||
processSettings(true);
|
||||
}
|
||||
|
||||
RttStatistics::~RttStatistics()
|
||||
{
|
||||
|
||||
if(m_timer) m_timer->stop();
|
||||
// save settings
|
||||
processSettings(false);
|
||||
}
|
||||
|
|
@ -66,23 +118,75 @@ void RttStatistics::processSettings(bool bLoad)
|
|||
|
||||
if (bLoad) {
|
||||
// load settings
|
||||
QByteArray state = Settings->value("TreeState").toByteArray();
|
||||
if (!state.isEmpty()) treeWidget->header()->restoreState(state);
|
||||
|
||||
// state of splitter
|
||||
//splitter->restoreState(Settings->value("Splitter").toByteArray());
|
||||
tabWidget->setCurrentIndex(Settings->value("ActiveTab", 0).toInt());
|
||||
} else {
|
||||
// save settings
|
||||
|
||||
// state of splitter
|
||||
//Settings->setValue("Splitter", splitter->saveState());
|
||||
|
||||
Settings->setValue("TreeState", treeWidget->header()->saveState());
|
||||
Settings->setValue("ActiveTab", tabWidget->currentIndex());
|
||||
}
|
||||
|
||||
Settings->endGroup();
|
||||
|
||||
m_bProcessSettings = false;
|
||||
|
||||
m_bProcessSettings = false;
|
||||
}
|
||||
|
||||
// --- Table Update Logic (O(N) Optimized) ---
|
||||
void RttStatistics::updateRttValues()
|
||||
{
|
||||
// Only update if the rtt tab is visible and the table view is selected
|
||||
if (!isVisible() || tabWidget->currentIndex() != 1) return;
|
||||
|
||||
std::list<RsPeerId> idList;
|
||||
if (!rsPeers) return;
|
||||
rsPeers->getOnlineList(idList);
|
||||
|
||||
QHash<QString, QTreeWidgetItem*> existingItems;
|
||||
for(int i = 0; i < treeWidget->topLevelItemCount(); ++i) {
|
||||
QTreeWidgetItem* item = treeWidget->topLevelItem(i);
|
||||
existingItems.insert(item->data(0, Qt::UserRole).toString(), item);
|
||||
}
|
||||
|
||||
for(std::list<RsPeerId>::const_iterator it = idList.begin(); it != idList.end(); ++it)
|
||||
{
|
||||
std::string peerIdStr = (*it).toStdString();
|
||||
QString qPeerId = QString::fromStdString(peerIdStr);
|
||||
|
||||
std::list<RsRttPongResult> results;
|
||||
rsRtt->getPongResults(*it, 1, results);
|
||||
int rttInMs = -1;
|
||||
if (!results.empty()) {
|
||||
float rttSec = results.back().mRTT;
|
||||
if (rttSec > 0.000001f) rttInMs = (int)(rttSec * 1000.0f);
|
||||
}
|
||||
|
||||
RsPeerDetails details;
|
||||
rsPeers->getPeerDetails(*it, details);
|
||||
QString peerName = QString::fromUtf8(details.name.c_str());
|
||||
QString ipAddress = QString::fromStdString(details.extAddr);
|
||||
|
||||
QTreeWidgetItem* item = existingItems.take(qPeerId);
|
||||
|
||||
if (!item) {
|
||||
item = new RttTreeItem(treeWidget);
|
||||
item->setData(0, Qt::UserRole, qPeerId);
|
||||
}
|
||||
|
||||
item->setText(0, peerName);
|
||||
if (rttInMs != -1) item->setText(1, QString::number(rttInMs));
|
||||
else item->setText(1, "?");
|
||||
item->setText(2, qPeerId);
|
||||
item->setText(3, ipAddress);
|
||||
}
|
||||
|
||||
qDeleteAll(existingItems);
|
||||
}
|
||||
|
||||
|
||||
// --- Graph Source Implementation (Unchanged logic) ---
|
||||
|
||||
QString RttGraphSource::unitName() const
|
||||
{
|
||||
return QObject::tr("secs") ;
|
||||
|
|
@ -109,8 +213,9 @@ void RttGraphSource::getValues(std::map<std::string,float>& vals) const
|
|||
for(std::list<RsPeerId>::const_iterator it(idList.begin());it!=idList.end();++it)
|
||||
{
|
||||
rsRtt->getPongResults(*it, 1, results);
|
||||
|
||||
vals[(*it).toStdString()] = results.back().mRTT ;
|
||||
if(!results.empty()) {
|
||||
vals[(*it).toStdString()] = results.back().mRTT ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,9 +18,16 @@
|
|||
* *
|
||||
*******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* gui/statistics/RttStatistics.h *
|
||||
*******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QPoint>
|
||||
#include <QTimer>
|
||||
#include <QTreeWidget>
|
||||
#include <QHeaderView>
|
||||
#include <retroshare/rsrtt.h>
|
||||
#include <retroshare-gui/RsAutoUpdatePage.h>
|
||||
|
||||
|
|
@ -47,17 +54,19 @@ public:
|
|||
|
||||
class RttStatistics: public MainPage, public Ui::RttStatistics
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RttStatistics(QWidget *parent = NULL) ;
|
||||
~RttStatistics();
|
||||
|
||||
private slots:
|
||||
void updateRttValues(); // Slot for table update
|
||||
|
||||
private:
|
||||
void processSettings(bool bLoad);
|
||||
bool m_bProcessSettings;
|
||||
|
||||
RttStatisticsGraph *_tst_CW ;
|
||||
QTimer *m_timer; // Timer for the table
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,44 +6,97 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>611</width>
|
||||
<height>408</height>
|
||||
<width>700</width>
|
||||
<height>500</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>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_Main">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</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 class="QWidget" name="tab_graph">
|
||||
<attribute name="title">
|
||||
<string>Graph View</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_Graph">
|
||||
<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>100</width>
|
||||
<height>100</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
||||
<widget class="QWidget" name="tab_table">
|
||||
<attribute name="title">
|
||||
<string>Table View</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_Table">
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="treeWidget">
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Peer Name</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>RTT (ms)</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Node ID</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>IP Address</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue