mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-02-05 11:24:15 +00:00
Merge pull request #9562 from dzmat/round_speed_labels
Improve scaling of speed graphs
This commit is contained in:
commit
dea6b3d7e0
@ -84,6 +84,27 @@ namespace
|
|||||||
QT_TRANSLATE_NOOP3("misc", "PiB", "pebibytes (1024 tebibytes)"),
|
QT_TRANSLATE_NOOP3("misc", "PiB", "pebibytes (1024 tebibytes)"),
|
||||||
QT_TRANSLATE_NOOP3("misc", "EiB", "exbibytes (1024 pebibytes)")
|
QT_TRANSLATE_NOOP3("misc", "EiB", "exbibytes (1024 pebibytes)")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// return best userfriendly storage unit (B, KiB, MiB, GiB, TiB, ...)
|
||||||
|
// use Binary prefix standards from IEC 60027-2
|
||||||
|
// see http://en.wikipedia.org/wiki/Kilobyte
|
||||||
|
// value must be given in bytes
|
||||||
|
// to send numbers instead of strings with suffixes
|
||||||
|
bool splitToFriendlyUnit(const qint64 sizeInBytes, qreal &val, Utils::Misc::SizeUnit &unit)
|
||||||
|
{
|
||||||
|
if (sizeInBytes < 0) return false;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
qreal rawVal = static_cast<qreal>(sizeInBytes);
|
||||||
|
|
||||||
|
while ((rawVal >= 1024.) && (i <= static_cast<int>(Utils::Misc::SizeUnit::ExbiByte))) {
|
||||||
|
rawVal /= 1024.;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
val = rawVal;
|
||||||
|
unit = static_cast<Utils::Misc::SizeUnit>(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Utils::Misc::shutdownComputer(const ShutdownDialogAction &action)
|
void Utils::Misc::shutdownComputer(const ShutdownDialogAction &action)
|
||||||
@ -237,52 +258,30 @@ QPoint Utils::Misc::screenCenter(const QWidget *w)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QString Utils::Misc::unitString(Utils::Misc::SizeUnit unit)
|
QString Utils::Misc::unitString(const SizeUnit unit, const bool isSpeed)
|
||||||
{
|
{
|
||||||
return QCoreApplication::translate("misc",
|
const auto &unitString = units[static_cast<int>(unit)];
|
||||||
units[static_cast<int>(unit)].source, units[static_cast<int>(unit)].comment);
|
QString ret = QCoreApplication::translate("misc", unitString.source, unitString.comment);
|
||||||
}
|
if (isSpeed)
|
||||||
|
ret += QCoreApplication::translate("misc", "/s", "per second");
|
||||||
// return best userfriendly storage unit (B, KiB, MiB, GiB, TiB, ...)
|
return ret;
|
||||||
// use Binary prefix standards from IEC 60027-2
|
|
||||||
// see http://en.wikipedia.org/wiki/Kilobyte
|
|
||||||
// value must be given in bytes
|
|
||||||
// to send numbers instead of strings with suffixes
|
|
||||||
bool Utils::Misc::friendlyUnit(qint64 sizeInBytes, qreal &val, Utils::Misc::SizeUnit &unit)
|
|
||||||
{
|
|
||||||
if (sizeInBytes < 0) return false;
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
qreal rawVal = static_cast<qreal>(sizeInBytes);
|
|
||||||
|
|
||||||
while ((rawVal >= 1024.) && (i <= static_cast<int>(SizeUnit::ExbiByte))) {
|
|
||||||
rawVal /= 1024.;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
val = rawVal;
|
|
||||||
unit = static_cast<SizeUnit>(i);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Utils::Misc::friendlyUnit(qint64 bytesValue, bool isSpeed)
|
QString Utils::Misc::friendlyUnit(qint64 bytesValue, bool isSpeed)
|
||||||
{
|
{
|
||||||
SizeUnit unit;
|
SizeUnit unit;
|
||||||
qreal friendlyVal;
|
qreal friendlyVal;
|
||||||
if (!friendlyUnit(bytesValue, friendlyVal, unit))
|
if (!splitToFriendlyUnit(bytesValue, friendlyVal, unit))
|
||||||
return QCoreApplication::translate("misc", "Unknown", "Unknown (size)");
|
return QCoreApplication::translate("misc", "Unknown", "Unknown (size)");
|
||||||
QString ret;
|
return Utils::String::fromDouble(friendlyVal, friendlyUnitPrecision(unit))
|
||||||
if (unit == SizeUnit::Byte)
|
+ QString::fromUtf8(C_NON_BREAKING_SPACE)
|
||||||
ret = QString::number(bytesValue) + QString::fromUtf8(C_NON_BREAKING_SPACE) + unitString(unit);
|
+ unitString(unit, isSpeed);
|
||||||
else
|
|
||||||
ret = Utils::String::fromDouble(friendlyVal, friendlyUnitPrecision(unit)) + QString::fromUtf8(C_NON_BREAKING_SPACE) + unitString(unit);
|
|
||||||
if (isSpeed)
|
|
||||||
ret += QCoreApplication::translate("misc", "/s", "per second");
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Utils::Misc::friendlyUnitPrecision(SizeUnit unit)
|
int Utils::Misc::friendlyUnitPrecision(SizeUnit unit)
|
||||||
{
|
{
|
||||||
// friendlyUnit's number of digits after the decimal point
|
// friendlyUnit's number of digits after the decimal point
|
||||||
|
if (unit == SizeUnit::Byte) return 0;
|
||||||
if (unit <= SizeUnit::MebiByte) return 1;
|
if (unit <= SizeUnit::MebiByte) return 1;
|
||||||
else if (unit == SizeUnit::GibiByte) return 2;
|
else if (unit == SizeUnit::GibiByte) return 2;
|
||||||
else return 3;
|
else return 3;
|
||||||
|
@ -79,11 +79,10 @@ namespace Utils
|
|||||||
QString boostVersionString();
|
QString boostVersionString();
|
||||||
QString libtorrentVersionString();
|
QString libtorrentVersionString();
|
||||||
|
|
||||||
QString unitString(SizeUnit unit);
|
QString unitString(SizeUnit unit, bool isSpeed = false);
|
||||||
|
|
||||||
// return the best user friendly storage unit (B, KiB, MiB, GiB, TiB)
|
// return the best user friendly storage unit (B, KiB, MiB, GiB, TiB)
|
||||||
// value must be given in bytes
|
// value must be given in bytes
|
||||||
bool friendlyUnit(qint64 sizeInBytes, qreal &val, SizeUnit &unit);
|
|
||||||
QString friendlyUnit(qint64 bytesValue, bool isSpeed = false);
|
QString friendlyUnit(qint64 bytesValue, bool isSpeed = false);
|
||||||
int friendlyUnitPrecision(SizeUnit unit);
|
int friendlyUnitPrecision(SizeUnit unit);
|
||||||
qint64 sizeInBytes(qreal size, SizeUnit unit);
|
qint64 sizeInBytes(qreal size, SizeUnit unit);
|
||||||
|
@ -28,9 +28,11 @@
|
|||||||
|
|
||||||
#include "speedplotview.h"
|
#include "speedplotview.h"
|
||||||
|
|
||||||
|
#include <QLocale>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPen>
|
#include <QPen>
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
|
#include "base/unicodestrings.h"
|
||||||
#include "base/utils/misc.h"
|
#include "base/utils/misc.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@ -48,6 +50,63 @@ namespace
|
|||||||
const int HOUR6_BUF_SIZE = 5 * 60;
|
const int HOUR6_BUF_SIZE = 5 * 60;
|
||||||
const int DIVIDER_30MIN = MIN30_SEC / MIN30_BUF_SIZE;
|
const int DIVIDER_30MIN = MIN30_SEC / MIN30_BUF_SIZE;
|
||||||
const int DIVIDER_6HOUR = HOUR6_SEC / HOUR6_BUF_SIZE;
|
const int DIVIDER_6HOUR = HOUR6_SEC / HOUR6_BUF_SIZE;
|
||||||
|
|
||||||
|
|
||||||
|
// table of supposed nice steps for grid marks to get nice looking quarters of scale
|
||||||
|
const double roundingTable[] = {1.2, 1.6, 2, 2.4, 2.8, 3.2, 4, 6, 8};
|
||||||
|
|
||||||
|
struct SplittedValue
|
||||||
|
{
|
||||||
|
double arg;
|
||||||
|
Utils::Misc::SizeUnit unit;
|
||||||
|
qint64 sizeInBytes() const
|
||||||
|
{
|
||||||
|
return Utils::Misc::sizeInBytes(arg, unit);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SplittedValue getRoundedYScale(double value)
|
||||||
|
{
|
||||||
|
using Utils::Misc::SizeUnit;
|
||||||
|
|
||||||
|
if (value == 0.0) return {0, SizeUnit::Byte};
|
||||||
|
if (value <= 12.0) return {12, SizeUnit::Byte};
|
||||||
|
|
||||||
|
SizeUnit calculatedUnit = SizeUnit::Byte;
|
||||||
|
while (value > 1024) {
|
||||||
|
value /= 1024;
|
||||||
|
calculatedUnit = static_cast<SizeUnit>(static_cast<int>(calculatedUnit) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value > 100.0) {
|
||||||
|
int roundedValue = static_cast<int>(value / 40) * 40;
|
||||||
|
while (roundedValue < value)
|
||||||
|
roundedValue += 40;
|
||||||
|
return {static_cast<double>(roundedValue), calculatedUnit};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value > 10.0) {
|
||||||
|
int roundedValue = static_cast<int>(value / 4) * 4;
|
||||||
|
while (roundedValue < value)
|
||||||
|
roundedValue += 4;
|
||||||
|
return {static_cast<double>(roundedValue), calculatedUnit};
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &roundedValue : roundingTable) {
|
||||||
|
if (value <= roundedValue)
|
||||||
|
return {roundedValue, calculatedUnit};
|
||||||
|
}
|
||||||
|
return {10.0, calculatedUnit};
|
||||||
|
}
|
||||||
|
|
||||||
|
QString formatLabel(const double argValue, const Utils::Misc::SizeUnit unit)
|
||||||
|
{
|
||||||
|
// check is there need for digits after decimal separator
|
||||||
|
const int precision = (argValue < 10) ? friendlyUnitPrecision(unit) : 0;
|
||||||
|
return QLocale::system().toString(argValue, 'f', precision)
|
||||||
|
+ QString::fromUtf8(C_NON_BREAKING_SPACE)
|
||||||
|
+ unitString(unit, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SpeedPlotView::Averager::Averager(int divider, boost::circular_buffer<PointData> &sink)
|
SpeedPlotView::Averager::Averager(int divider, boost::circular_buffer<PointData> &sink)
|
||||||
@ -211,18 +270,16 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
|
|||||||
QFontMetrics fontMetrics = painter.fontMetrics();
|
QFontMetrics fontMetrics = painter.fontMetrics();
|
||||||
|
|
||||||
rect.adjust(4, 4, 0, -4); // Add padding
|
rect.adjust(4, 4, 0, -4); // Add padding
|
||||||
|
const SplittedValue niceScale = getRoundedYScale(maxYValue());
|
||||||
quint64 maxY = maxYValue();
|
|
||||||
|
|
||||||
rect.adjust(0, fontMetrics.height(), 0, 0); // Add top padding for top speed text
|
rect.adjust(0, fontMetrics.height(), 0, 0); // Add top padding for top speed text
|
||||||
|
|
||||||
// draw Y axis speed labels
|
// draw Y axis speed labels
|
||||||
QVector<QString> speedLabels = {
|
QVector<QString> speedLabels = {
|
||||||
Utils::Misc::friendlyUnit(maxY, true),
|
formatLabel(niceScale.arg, niceScale.unit),
|
||||||
Utils::Misc::friendlyUnit(0.75 * maxY, true),
|
formatLabel((0.75 * niceScale.arg), niceScale.unit),
|
||||||
Utils::Misc::friendlyUnit(0.5 * maxY, true),
|
formatLabel((0.50 * niceScale.arg), niceScale.unit),
|
||||||
Utils::Misc::friendlyUnit(0.25 * maxY, true),
|
formatLabel((0.25 * niceScale.arg), niceScale.unit),
|
||||||
Utils::Misc::friendlyUnit(0, true)
|
formatLabel(0.0, niceScale.unit),
|
||||||
};
|
};
|
||||||
|
|
||||||
int yAxisWidth = 0;
|
int yAxisWidth = 0;
|
||||||
@ -264,8 +321,8 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
|
|||||||
// draw graphs
|
// draw graphs
|
||||||
rect.adjust(3, 0, 0, 0); // Need, else graphs cross left gridline
|
rect.adjust(3, 0, 0, 0); // Need, else graphs cross left gridline
|
||||||
|
|
||||||
double yMultiplier = (maxY == 0) ? 0.0 : static_cast<double>(rect.height()) / maxY;
|
const double yMultiplier = (niceScale.arg == 0.0) ? 0.0 : (rect.height() / niceScale.sizeInBytes());
|
||||||
double xTickSize = static_cast<double>(rect.width()) / m_viewablePointsCount;
|
const double xTickSize = static_cast<double>(rect.width()) / m_viewablePointsCount;
|
||||||
|
|
||||||
boost::circular_buffer<PointData> &queue = getCurrentData();
|
boost::circular_buffer<PointData> &queue = getCurrentData();
|
||||||
|
|
||||||
|
@ -315,6 +315,8 @@ void SearchJobWidget::updateFilter()
|
|||||||
void SearchJobWidget::fillFilterComboBoxes()
|
void SearchJobWidget::fillFilterComboBoxes()
|
||||||
{
|
{
|
||||||
using Utils::Misc::SizeUnit;
|
using Utils::Misc::SizeUnit;
|
||||||
|
using Utils::Misc::unitString;
|
||||||
|
|
||||||
QStringList unitStrings;
|
QStringList unitStrings;
|
||||||
unitStrings.append(unitString(SizeUnit::Byte));
|
unitStrings.append(unitString(SizeUnit::Byte));
|
||||||
unitStrings.append(unitString(SizeUnit::KibiByte));
|
unitStrings.append(unitString(SizeUnit::KibiByte));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user