379 lines
12 KiB
C++
Raw Normal View History

2018-12-23 20:09:23 +01:00
/*******************************************************************************
* gui/statistics/BwCtrlWindow.cpp *
* *
* Copyright (c) 2012 Robert Fernie <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 "BwCtrlWindow.h"
#include "gui/common/RSGraphWidget.h"
#include "ui_BwCtrlWindow.h"
#include "util/QtVersion.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 <QHeaderView>
#include <QPainter>
#include <limits>
class BWListDelegate: public QAbstractItemDelegate
{
public:
BWListDelegate(QObject *parent=0);
virtual ~BWListDelegate();
void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const;
};
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/*option*/, const QModelIndex & index) const
{
float FS = QFontMetricsF(option.font).height();
2016-06-05 11:05:52 -04:00
//float fact = FS/14.0 ;
float w = QFontMetricsF(option.font).width(index.data(Qt::DisplayRole).toString());
return QSize(w,FS*1.2);
//return QSize(50*fact,17*fact);
}
BwCtrlWindow::BwCtrlWindow(QWidget *parent)
: RsAutoUpdatePage(1000,parent)
{
setupUi(this);
BWDelegate = new BWListDelegate();
bwTreeWidget->setItemDelegate(BWDelegate);
2016-06-05 11:05:52 -04:00
//float FS = QFontMetricsF(font()).height();
//float fact = FS/14.0 ;
/* Set header resize modes and initial section sizes Peer TreeView*/
QHeaderView * _header = bwTreeWidget->header () ;
// _header->resizeSection ( COLUMN_RSNAME, 170*fact );
QHeaderView_setSectionResizeMode(_header, QHeaderView::ResizeToContents);
}
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;
}
updateBandwidth();
}
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);
/* 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::fromUtf8(name.c_str()));
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));
}
}
}