Browse Source

Merge pull request #2757 from onto/master

Upload/download speed graph widget.
adaptive-webui-19844
sledgehammer999 9 years ago
parent
commit
8dd7014af6
  1. 40
      src/core/bittorrent/sessionstatus.cpp
  2. 10
      src/core/bittorrent/sessionstatus.h
  3. 19
      src/core/preferences.cpp
  4. 6
      src/core/preferences.h
  5. 8
      src/gui/properties/properties.pri
  6. 5
      src/gui/properties/propertieswidget.cpp
  7. 3
      src/gui/properties/propertieswidget.h
  8. 4
      src/gui/properties/propertieswidget.ui
  9. 4
      src/gui/properties/proptabbar.cpp
  10. 2
      src/gui/properties/proptabbar.h
  11. 253
      src/gui/properties/speedplotview.cpp
  12. 107
      src/gui/properties/speedplotview.h
  13. 218
      src/gui/properties/speedwidget.cpp
  14. 79
      src/gui/properties/speedwidget.h
  15. 1
      src/icons.qrc
  16. BIN
      src/icons/oxygen/office-chart-line.png

40
src/core/bittorrent/sessionstatus.cpp

@ -50,6 +50,46 @@ int SessionStatus::payloadUploadRate() const @@ -50,6 +50,46 @@ int SessionStatus::payloadUploadRate() const
return m_nativeStatus.payload_upload_rate;
}
int SessionStatus::downloadRate() const
{
return m_nativeStatus.download_rate;
}
int SessionStatus::uploadRate() const
{
return m_nativeStatus.upload_rate;
}
int SessionStatus::ipOverheadDownloadRate() const
{
return m_nativeStatus.ip_overhead_download_rate;
}
int SessionStatus::ipOverheadUploadRate() const
{
return m_nativeStatus.ip_overhead_upload_rate;
}
int SessionStatus::dhtDownloadRate() const
{
return m_nativeStatus.dht_download_rate;
}
int SessionStatus::dhtUploadRate() const
{
return m_nativeStatus.dht_upload_rate;
}
int SessionStatus::trackerDownloadRate() const
{
return m_nativeStatus.tracker_download_rate;
}
int SessionStatus::trackerUploadRate() const
{
return m_nativeStatus.tracker_upload_rate;
}
qlonglong SessionStatus::totalDownload() const
{
return m_nativeStatus.total_download;

10
src/core/bittorrent/sessionstatus.h

@ -51,6 +51,16 @@ namespace BitTorrent @@ -51,6 +51,16 @@ namespace BitTorrent
// account "useful" part of the rate
int payloadUploadRate() const;
// Additional download/upload rates
int uploadRate() const;
int downloadRate() const;
int ipOverheadUploadRate() const;
int ipOverheadDownloadRate() const;
int dhtUploadRate() const;
int dhtDownloadRate() const;
int trackerUploadRate() const;
int trackerDownloadRate() const;
qlonglong totalDownload() const;
qlonglong totalUpload() const;
qlonglong totalPayloadDownload() const;

19
src/core/preferences.cpp

@ -2501,6 +2501,25 @@ void Preferences::setHostNameCookies(const QString &host_name, const QList<QByte @@ -2501,6 +2501,25 @@ void Preferences::setHostNameCookies(const QString &host_name, const QList<QByte
setValue("Rss/hosts_cookies", hosts_table);
}
int Preferences::getSpeedWidgetPeriod() const {
return value("SpeedWidget/period", 1).toInt();
}
void Preferences::setSpeedWidgetPeriod(const int period) {
setValue("SpeedWidget/period", period);
}
bool Preferences::getSpeedWidgetGraphEnable(int id) const
{
// UP and DOWN graphs enabled by default
return value("SpeedWidget/graph_enable_" + QString::number(id), (id == 0 || id == 1)).toBool();
}
void Preferences::setSpeedWidgetGraphEnable(int id, const bool enable)
{
setValue("SpeedWidget/graph_enable_" + QString::number(id), enable);
}
void Preferences::apply()
{
if (save())

6
src/core/preferences.h

@ -534,6 +534,12 @@ public: @@ -534,6 +534,12 @@ public:
QList<QNetworkCookie> getHostNameQNetworkCookies(const QString& host_name) const;
void setHostNameCookies(const QString &host_name, const QList<QByteArray> &cookies);
// SpeedWidget
int getSpeedWidgetPeriod() const;
void setSpeedWidgetPeriod(const int period);
bool getSpeedWidgetGraphEnable(int id) const;
void setSpeedWidgetGraphEnable(int id, const bool enable);
public slots:
void setStatusFilterState(bool checked);
void setLabelFilterState(bool checked);

8
src/gui/properties/properties.pri

@ -14,7 +14,9 @@ HEADERS += $$PWD/propertieswidget.h \ @@ -14,7 +14,9 @@ HEADERS += $$PWD/propertieswidget.h \
$$PWD/peeraddition.h \
$$PWD/trackersadditiondlg.h \
$$PWD/pieceavailabilitybar.h \
$$PWD/proptabbar.h
$$PWD/proptabbar.h \
$$PWD/speedwidget.h \
$$PWD/speedplotview.h
SOURCES += $$PWD/propertieswidget.cpp \
$$PWD/proplistdelegate.cpp \
@ -24,4 +26,6 @@ SOURCES += $$PWD/propertieswidget.cpp \ @@ -24,4 +26,6 @@ SOURCES += $$PWD/propertieswidget.cpp \
$$PWD/downloadedpiecesbar.cpp \
$$PWD/peeraddition.cpp \
$$PWD/trackersadditiondlg.cpp \
$$PWD/pieceavailabilitybar.cpp
$$PWD/pieceavailabilitybar.cpp \
$$PWD/speedwidget.cpp \
$$PWD/speedplotview.cpp

5
src/gui/properties/propertieswidget.cpp

@ -52,6 +52,7 @@ @@ -52,6 +52,7 @@
#include "torrentcontentfiltermodel.h"
#include "torrentcontentmodel.h"
#include "peerlistwidget.h"
#include "speedwidget.h"
#include "trackerlist.h"
#include "mainwindow.h"
#include "downloadedpiecesbar.h"
@ -122,6 +123,9 @@ PropertiesWidget::PropertiesWidget(QWidget *parent, MainWindow* main_window, Tra @@ -122,6 +123,9 @@ PropertiesWidget::PropertiesWidget(QWidget *parent, MainWindow* main_window, Tra
connect(peersList->header(), SIGNAL(sectionMoved(int, int, int)), peersList, SLOT(saveSettings()));
connect(peersList->header(), SIGNAL(sectionResized(int, int, int)), peersList, SLOT(saveSettings()));
connect(peersList->header(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), peersList, SLOT(saveSettings()));
// Speed widget
speedWidget = new SpeedWidget(this);
speed_layout->addWidget(speedWidget);
// Tab bar
m_tabBar = new PropTabBar();
verticalLayout->addLayout(m_tabBar);
@ -149,6 +153,7 @@ PropertiesWidget::~PropertiesWidget() { @@ -149,6 +153,7 @@ PropertiesWidget::~PropertiesWidget() {
delete refreshTimer;
delete trackerList;
delete peersList;
delete speedWidget;
delete downloaded_pieces;
delete pieces_availability;
delete PropListModel;

3
src/gui/properties/propertieswidget.h

@ -43,6 +43,7 @@ class PropListDelegate; @@ -43,6 +43,7 @@ class PropListDelegate;
class torrent_file;
class PeerListWidget;
class TrackerList;
class SpeedWidget;
class MainWindow;
class DownloadedPiecesBar;
class PieceAvailabilityBar;
@ -68,6 +69,7 @@ public: @@ -68,6 +69,7 @@ public:
TrackerList* getTrackerList() const { return trackerList; }
PeerListWidget* getPeerList() const { return peersList; }
QTreeView* getFilesList() const { return filesList; }
SpeedWidget* getSpeedWidget() const { return speedWidget; }
protected:
QPushButton* getButtonFromIndex(int index);
@ -113,6 +115,7 @@ private: @@ -113,6 +115,7 @@ private:
PropListDelegate *PropDelegate;
PeerListWidget *peersList;
TrackerList *trackerList;
SpeedWidget *speedWidget;
QList<int> slideSizes;
DownloadedPiecesBar *downloaded_pieces;
PieceAvailabilityBar *pieces_availability;

4
src/gui/properties/propertieswidget.ui

@ -1168,6 +1168,10 @@ @@ -1168,6 +1168,10 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="speed_page">
<layout class="QVBoxLayout" name="speed_layout">
</layout>
</widget>
</widget>
</item>
<item>

4
src/gui/properties/proptabbar.cpp

@ -64,6 +64,10 @@ PropTabBar::PropTabBar(QWidget *parent) : @@ -64,6 +64,10 @@ PropTabBar::PropTabBar(QWidget *parent) :
m_btnGroup->addButton(files_button, FILES_TAB);
// Spacer
addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
// Speed tab
QPushButton *speed_button = new QPushButton(GuiIconProvider::instance()->getIcon("office-chart-line"), tr("Speed"), parent);
addWidget(speed_button);
m_btnGroup->addButton(speed_button, SPEED_TAB);
// SIGNAL/SLOT
connect(m_btnGroup, SIGNAL(buttonClicked(int)), SLOT(setCurrentIndex(int)));
// Disable buttons focus

2
src/gui/properties/proptabbar.h

@ -43,7 +43,7 @@ class PropTabBar : public QHBoxLayout @@ -43,7 +43,7 @@ class PropTabBar : public QHBoxLayout
Q_DISABLE_COPY(PropTabBar)
public:
enum PropertyTab {MAIN_TAB, TRACKERS_TAB, PEERS_TAB, URLSEEDS_TAB, FILES_TAB};
enum PropertyTab {MAIN_TAB, TRACKERS_TAB, PEERS_TAB, URLSEEDS_TAB, FILES_TAB, SPEED_TAB};
public:
explicit PropTabBar(QWidget *parent = 0);

253
src/gui/properties/speedplotview.cpp

@ -0,0 +1,253 @@ @@ -0,0 +1,253 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2015 Anton Lashkov <lenton_91@mail.ru>
*
* 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.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*/
#include "speedplotview.h"
#include <QPainter>
#include <QPen>
#include "core/utils/misc.h"
SpeedPlotView::SpeedPlotView(QWidget *parent)
: QGraphicsView(parent)
, m_viewablePointsCount(MIN5_SEC)
, m_maxCapacity(HOUR6_SEC)
{
QPen greenPen;
greenPen.setWidthF(1.5);
greenPen.setColor(QColor(134, 196, 63));
QPen bluePen;
bluePen.setWidthF(1.5);
bluePen.setColor(QColor(50, 153, 255));
m_properties[UP] = GraphProperties(tr("Total Upload"), bluePen);
m_properties[DOWN] = GraphProperties(tr("Total Download"), greenPen);
bluePen.setStyle(Qt::DashLine);
greenPen.setStyle(Qt::DashLine);
m_properties[PAYLOAD_UP] = GraphProperties(tr("Payload Upload"), bluePen);
m_properties[PAYLOAD_DOWN] = GraphProperties(tr("Payload Download"), greenPen);
bluePen.setStyle(Qt::DashDotLine);
greenPen.setStyle(Qt::DashDotLine);
m_properties[OVERHEAD_UP] = GraphProperties(tr("Overhead Upload"), bluePen);
m_properties[OVERHEAD_DOWN] = GraphProperties(tr("Overhead Download"), greenPen);
bluePen.setStyle(Qt::DashDotDotLine);
greenPen.setStyle(Qt::DashDotDotLine);
m_properties[DHT_UP] = GraphProperties(tr("DHT Upload"), bluePen);
m_properties[DHT_DOWN] = GraphProperties(tr("DHT Download"), greenPen);
bluePen.setStyle(Qt::DotLine);
greenPen.setStyle(Qt::DotLine);
m_properties[TRACKER_UP] = GraphProperties(tr("Tracker Upload"), bluePen);
m_properties[TRACKER_DOWN] = GraphProperties(tr("Tracker Download"), greenPen);
}
void SpeedPlotView::setGraphEnable(int id, bool enable)
{
m_properties[id].enable = enable;
}
void SpeedPlotView::pushXPoint(double x)
{
while (m_xData.size() >= m_maxCapacity)
m_xData.pop_front();
m_xData.append(x);
}
void SpeedPlotView::pushYPoint(int id, double y)
{
while (m_yData[id].size() >= m_maxCapacity)
m_yData[id].pop_front();
m_yData[id].append(y);
}
void SpeedPlotView::setViewableLastPoints(int period)
{
m_viewablePointsCount = period;
}
void SpeedPlotView::replot()
{
this->viewport()->update();
}
double SpeedPlotView::maxYValue()
{
double maxYValue = 0;
for (QMap<int, QQueue<double> >::const_iterator it = m_yData.begin(); it != m_yData.end(); ++it) {
if (!m_properties[it.key()].enable)
continue;
QQueue<double> &queue = m_yData[it.key()];
for (int i = queue.size() - 1, j = 0; i >= 0 && j <= m_viewablePointsCount; --i, ++j) {
if (queue.at(i) > maxYValue)
maxYValue = queue.at(i);
}
}
return maxYValue;
}
void SpeedPlotView::paintEvent(QPaintEvent *)
{
QPainter painter(this->viewport());
QRect full_rect = this->viewport()->rect();
QRect rect = this->viewport()->rect();
QFontMetrics font_metrics = painter.fontMetrics();
rect.adjust(4, 4, 0, -4); // Add padding
double max_y = maxYValue();
rect.adjust(0, font_metrics.height(), 0, 0); // Add top padding for top speed text
// draw Y axis speed labels
QVector<QString> speed_labels(QVector<QString>() <<
Utils::Misc::friendlyUnit(max_y, true) <<
Utils::Misc::friendlyUnit(0.75 * max_y, true) <<
Utils::Misc::friendlyUnit(0.5 * max_y, true) <<
Utils::Misc::friendlyUnit(0.25 * max_y, true) <<
Utils::Misc::friendlyUnit(0, true));
int y_axe_width = 0;
for (int i = 0; i < speed_labels.size(); ++i) {
if (font_metrics.width(speed_labels[i]) > y_axe_width)
y_axe_width = font_metrics.width(speed_labels[i]);
}
for (int i = 0; i < speed_labels.size(); ++i) {
QRectF label_rect(rect.topLeft() + QPointF(-y_axe_width, i * 0.25 * rect.height() - font_metrics.height()),
QSizeF(2 * y_axe_width, font_metrics.height()));
painter.drawText(label_rect, speed_labels[i], QTextOption((Qt::AlignRight) | (Qt::AlignTop)));
}
// draw grid lines
rect.adjust(y_axe_width + 4, 0, 0, 0);
QPen grid_pen;
grid_pen.setStyle(Qt::DashLine);
grid_pen.setWidthF(1);
grid_pen.setColor(QColor(128, 128, 128, 128));
painter.setPen(grid_pen);
painter.drawLine(full_rect.left(), rect.top(), rect.right(), rect.top());
painter.drawLine(full_rect.left(), rect.top() + 0.25 * rect.height(), rect.right(), rect.top() + 0.25 * rect.height());
painter.drawLine(full_rect.left(), rect.top() + 0.50 * rect.height(), rect.right(), rect.top() + 0.50 * rect.height());
painter.drawLine(full_rect.left(), rect.top() + 0.75 * rect.height(), rect.right(), rect.top() + 0.75 * rect.height());
painter.drawLine(full_rect.left(), rect.bottom(), rect.right(), rect.bottom());
painter.drawLine(rect.left(), full_rect.top(), rect.left(), full_rect.bottom());
painter.drawLine(rect.left() + 0.2 * rect.width(), full_rect.top(), rect.left() + 0.2 * rect.width(), full_rect.bottom());
painter.drawLine(rect.left() + 0.4 * rect.width(), full_rect.top(), rect.left() + 0.4 * rect.width(), full_rect.bottom());
painter.drawLine(rect.left() + 0.6 * rect.width(), full_rect.top(), rect.left() + 0.6 * rect.width(), full_rect.bottom());
painter.drawLine(rect.left() + 0.8 * rect.width(), full_rect.top(), rect.left() + 0.8 * rect.width(), full_rect.bottom());
// Set antialiasing for graphs
painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing);
// draw graphs
rect.adjust(3, 0, 0, 0); // Need, else graphs cross left gridline
double y_multiplier = rect.height() / max_y;
double x_tick_size = double(rect.width()) / m_viewablePointsCount;
for (QMap<int, QQueue<double> >::const_iterator it = m_yData.begin(); it != m_yData.end(); ++it) {
if (!m_properties[it.key()].enable)
continue;
QQueue<double> &queue = m_yData[it.key()];
QVector<QPointF> points;
for (int i = queue.size() - 1, j = 0; i >= 0 && j <= m_viewablePointsCount; --i, ++j) {
points.push_back(QPointF(rect.right() - j * x_tick_size,
rect.bottom() - queue.at(i) * y_multiplier));
}
painter.setPen(m_properties[it.key()].pen);
painter.drawPolyline(points.data(), points.size());
}
// draw legend
QPoint legend_top_left(rect.left() + 4, full_rect.top() + 4);
double legend_height = 0;
int legend_width = 0;
for (QMap<int, GraphProperties>::const_iterator it = m_properties.begin(); it != m_properties.end(); ++it) {
if (!it.value().enable)
continue;
if (font_metrics.width(it.value().name) > legend_width)
{
legend_width = font_metrics.width(it.value().name);
}
legend_height += 1.5 * font_metrics.height();
}
QRectF legend_background_rect(legend_top_left, QSizeF(legend_width, legend_height));
painter.fillRect(legend_background_rect, QColor(255, 255, 255, 128)); // 50% transparent
int i = 0;
for (QMap<int, GraphProperties>::const_iterator it = m_properties.begin(); it != m_properties.end(); ++it) {
if (!it.value().enable)
continue;
int name_size = font_metrics.width(it.value().name);
double indent = 1.5 * i * font_metrics.height();
painter.setPen(it.value().pen);
painter.drawLine(legend_top_left + QPointF(0, indent + font_metrics.height()),
legend_top_left + QPointF(name_size, indent + font_metrics.height()));
painter.drawText(QRectF(legend_top_left + QPointF(0, indent), QSizeF(2 * name_size, font_metrics.height())),
it.value().name, QTextOption(Qt::AlignVCenter));
++i;
}
}
SpeedPlotView::GraphProperties::GraphProperties()
: name()
, pen()
, enable(false)
{
}
SpeedPlotView::GraphProperties::GraphProperties(const QString &_name, const QPen &_pen, bool _enable)
: name(_name)
, pen(_pen)
, enable(_enable)
{
}

107
src/gui/properties/speedplotview.h

@ -0,0 +1,107 @@ @@ -0,0 +1,107 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2015 Anton Lashkov <lenton_91@mail.ru>
*
* 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.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*/
#ifndef SPEEDPLOTVIEW_H
#define SPEEDPLOTVIEW_H
#include <QGraphicsView>
#include <QMap>
#include <QQueue>
class QPen;
class SpeedPlotView : public QGraphicsView
{
Q_OBJECT
public:
explicit SpeedPlotView(QWidget *parent = 0);
void setGraphEnable(int id, bool enable);
void pushXPoint(double x);
void pushYPoint(int id, double y);
void setViewableLastPoints(int period);
void replot();
enum GraphID
{
UP = 0,
DOWN,
PAYLOAD_UP,
PAYLOAD_DOWN,
OVERHEAD_UP,
OVERHEAD_DOWN,
DHT_UP,
DHT_DOWN,
TRACKER_UP,
TRACKER_DOWN,
NB_GRAPHS
};
enum TimePeriod
{
MIN1 = 0,
MIN5,
MIN30,
HOUR6
};
enum PeriodInSeconds
{
MIN1_SEC = 60,
MIN5_SEC = 300,
MIN30_SEC = 1800,
HOUR6_SEC = 21600
};
protected:
virtual void paintEvent(QPaintEvent *event);
private:
struct GraphProperties
{
GraphProperties();
GraphProperties(const QString &_name, const QPen &_pen, bool _enable = false);
QString name;
QPen pen;
bool enable;
};
QQueue<double> m_xData;
QMap<int, QQueue<double> > m_yData;
QMap<int, GraphProperties> m_properties;
int m_viewablePointsCount;
int m_maxCapacity;
double maxYValue();
};
#endif // SPEEDPLOTVIEW_H

218
src/gui/properties/speedwidget.cpp

@ -0,0 +1,218 @@ @@ -0,0 +1,218 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2015 Anton Lashkov <lenton_91@mail.ru>
*
* 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.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*/
#include "speedwidget.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QComboBox>
#include <QToolButton>
#include <QMenu>
#include <QSignalMapper>
#include <libtorrent/session_status.hpp>
#include "propertieswidget.h"
#include "core/bittorrent/session.h"
#include "core/bittorrent/sessionstatus.h"
#include "core/preferences.h"
#include "core/utils/misc.h"
SpeedWidget::SpeedWidget(PropertiesWidget *parent)
: QWidget(parent)
, m_properties(parent)
{
m_layout = new QVBoxLayout(this);
m_layout->setContentsMargins(0, 0, 0, 0);
m_hlayout = new QHBoxLayout();
m_hlayout->setContentsMargins(0, 0, 0, 0);
m_periodLabel = new QLabel("<b>" + tr("Period:") + "</b>");
m_periodCombobox = new QComboBox();
m_periodCombobox->addItem(tr("1 Minute"));
m_periodCombobox->addItem(tr("5 Minutes"));
m_periodCombobox->addItem(tr("30 Minutes"));
m_periodCombobox->addItem(tr("6 Hours"));
connect(m_periodCombobox, SIGNAL(currentIndexChanged(int)), this, SLOT(onPeriodChange(int)));
m_graphsButton = new QToolButton();
m_graphsButton->setText(tr("Select Graphs"));
m_graphsButton->setPopupMode(QToolButton::InstantPopup);
m_graphsButton->setAutoExclusive(true);
m_graphsMenu = new QMenu();
m_graphsMenu->addAction(tr("Total Upload"));
m_graphsMenu->addAction(tr("Total Download"));
m_graphsMenu->addAction(tr("Payload Upload"));
m_graphsMenu->addAction(tr("Payload Download"));
m_graphsMenu->addAction(tr("Overhead Upload"));
m_graphsMenu->addAction(tr("Overhead Download"));
m_graphsMenu->addAction(tr("DHT Upload"));
m_graphsMenu->addAction(tr("DHT Download"));
m_graphsMenu->addAction(tr("Tracker Upload"));
m_graphsMenu->addAction(tr("Tracker Download"));
m_graphsMenuActions = m_graphsMenu->actions();
m_graphsSignalMapper = new QSignalMapper();
for (int id = SpeedPlotView::UP; id < SpeedPlotView::NB_GRAPHS; ++id) {
QAction *action = m_graphsMenuActions.at(id);
action->setCheckable(true);
action->setChecked(true);
connect(action, SIGNAL(changed()), m_graphsSignalMapper, SLOT(map()));
m_graphsSignalMapper->setMapping(action, id);
}
connect(m_graphsSignalMapper, SIGNAL(mapped(int)), this, SLOT(onGraphChange(int)));
m_graphsButton->setMenu(m_graphsMenu);
m_hlayout->addWidget(m_periodLabel);
m_hlayout->addWidget(m_periodCombobox);
m_hlayout->addStretch();
m_hlayout->addWidget(m_graphsButton);
m_plot = new SpeedPlotView(this);
m_layout->addLayout(m_hlayout);
m_layout->addWidget(m_plot);
loadSettings();
m_isUpdating = true;
m_updateFuture = QtConcurrent::run(this, &SpeedWidget::update);
m_plot->show();
}
SpeedWidget::~SpeedWidget()
{
qDebug("SpeedWidget::~SpeedWidget() ENTER");
m_isUpdating = false;
m_updateFuture.waitForFinished();
saveSettings();
qDebug("SpeedWidget::~SpeedWidget() EXIT");
}
void SpeedWidget::update()
{
while (m_isUpdating) {
BitTorrent::SessionStatus btStatus = BitTorrent::Session::instance()->status();
m_plot->pushXPoint(QDateTime::currentDateTime().toTime_t());
m_plot->pushYPoint(SpeedPlotView::UP, btStatus.uploadRate());
m_plot->pushYPoint(SpeedPlotView::DOWN, btStatus.downloadRate());
m_plot->pushYPoint(SpeedPlotView::PAYLOAD_UP, btStatus.payloadUploadRate());
m_plot->pushYPoint(SpeedPlotView::PAYLOAD_DOWN, btStatus.payloadDownloadRate());
m_plot->pushYPoint(SpeedPlotView::OVERHEAD_UP, btStatus.ipOverheadUploadRate());
m_plot->pushYPoint(SpeedPlotView::OVERHEAD_DOWN, btStatus.ipOverheadDownloadRate());
m_plot->pushYPoint(SpeedPlotView::DHT_UP, btStatus.dhtUploadRate());
m_plot->pushYPoint(SpeedPlotView::DHT_DOWN, btStatus.dhtDownloadRate());
m_plot->pushYPoint(SpeedPlotView::TRACKER_UP, btStatus.trackerUploadRate());
m_plot->pushYPoint(SpeedPlotView::TRACKER_DOWN, btStatus.trackerDownloadRate());
QMetaObject::invokeMethod(this, "graphUpdate");
Utils::Misc::msleep(1000);
}
}
void SpeedWidget::graphUpdate()
{
m_plot->replot();
}
void SpeedWidget::onPeriodChange(int period)
{
switch (period) {
case SpeedPlotView::MIN1:
m_plot->setViewableLastPoints(SpeedPlotView::MIN1_SEC);
break;
case SpeedPlotView::MIN5:
m_plot->setViewableLastPoints(SpeedPlotView::MIN5_SEC);
break;
case SpeedPlotView::MIN30:
m_plot->setViewableLastPoints(SpeedPlotView::MIN30_SEC);
break;
case SpeedPlotView::HOUR6:
m_plot->setViewableLastPoints(SpeedPlotView::HOUR6_SEC);
break;
default:
break;
}
graphUpdate();
}
void SpeedWidget::onGraphChange(int id)
{
QAction *action = m_graphsMenuActions.at(id);
m_plot->setGraphEnable(id, action->isChecked());
graphUpdate();
}
void SpeedWidget::loadSettings()
{
Preferences *preferences = Preferences::instance();
int periodIndex = preferences->getSpeedWidgetPeriod();
m_periodCombobox->setCurrentIndex(periodIndex);
onPeriodChange(periodIndex);
for (int id = SpeedPlotView::UP; id < SpeedPlotView::NB_GRAPHS; ++id) {
QAction *action = m_graphsMenuActions.at(id);
if (preferences->getSpeedWidgetGraphEnable(id)) {
action->setChecked(true);
m_plot->setGraphEnable(id, true);
} else {
action->setChecked(false);
m_plot->setGraphEnable(id, false);
}
}
}
void SpeedWidget::saveSettings() const
{
Preferences *preferences = Preferences::instance();
preferences->setSpeedWidgetPeriod(m_periodCombobox->currentIndex());
for (int id = SpeedPlotView::UP; id < SpeedPlotView::NB_GRAPHS; ++id) {
QAction *action = m_graphsMenuActions.at(id);
preferences->setSpeedWidgetGraphEnable(id, action->isChecked());
}
}

79
src/gui/properties/speedwidget.h

@ -0,0 +1,79 @@ @@ -0,0 +1,79 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2015 Anton Lashkov <lenton_91@mail.ru>
*
* 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.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*/
#ifndef SPEEDWIDGET_H
#define SPEEDWIDGET_H
#include <QWidget>
#include <QtConcurrentRun>
#include "speedplotview.h"
class QVBoxLayout;
class QHBoxLayout;
class QLabel;
class QComboBox;
class QToolButton;
class QMenu;
class QSignalMapper;
class PropertiesWidget;
class SpeedWidget : public QWidget
{
Q_OBJECT
public:
SpeedWidget(PropertiesWidget *parent);
~SpeedWidget();
private slots:
void onPeriodChange(int period);
void onGraphChange(int id);
private:
void update();
void loadSettings();
void saveSettings() const;
Q_INVOKABLE void graphUpdate();
QVBoxLayout *m_layout;
QHBoxLayout *m_hlayout;
QLabel *m_periodLabel;
QComboBox *m_periodCombobox;
SpeedPlotView *m_plot;
PropertiesWidget *m_properties;
QToolButton *m_graphsButton;
QMenu *m_graphsMenu;
QList<QAction *> m_graphsMenuActions;
QSignalMapper *m_graphsSignalMapper;
QFuture<void> m_updateFuture;
bool m_isUpdating;
};
#endif // SPEEDWIDGET_H

1
src/icons.qrc

@ -368,5 +368,6 @@ @@ -368,5 +368,6 @@
<file>icons/oxygen/go-bottom.png</file>
<file>icons/oxygen/go-top.png</file>
<file>icons/oxygen/checked.png</file>
<file>icons/oxygen/office-chart-line.png</file>
</qresource>
</RCC>

BIN
src/icons/oxygen/office-chart-line.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 877 B

Loading…
Cancel
Save