Enable customizing the save statistics time interval
[qBittorrent.git] / src / gui / properties / pieceavailabilitybar.cpp
blob5a9e618457a910294c295b251346a6cc33a0de98
1 /*
2 * Bittorrent Client using Qt and libtorrent.
3 * Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
4 * Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * In addition, as a special exception, the copyright holders give permission to
21 * link this program with the OpenSSL project's "OpenSSL" library (or with
22 * modified versions of it that use the same license as the "OpenSSL" library),
23 * and distribute the linked executables. You must obey the GNU General Public
24 * License in all respects for all of the code used other than "OpenSSL". If you
25 * modify file(s), you may extend this exception to your version of the file(s),
26 * but you are not obligated to do so. If you do not wish to do so, delete this
27 * exception statement from your version.
30 #include "pieceavailabilitybar.h"
32 #include <algorithm>
33 #include <cmath>
35 #include <QDebug>
37 #include "base/global.h"
39 PieceAvailabilityBar::PieceAvailabilityBar(QWidget *parent)
40 : base {parent}
44 QList<float> PieceAvailabilityBar::intToFloatVector(const QList<int> &vecin, int reqSize)
46 QList<float> result(reqSize, 0.0);
47 if (vecin.isEmpty()) return result;
49 const float ratio = static_cast<float>(vecin.size()) / reqSize;
51 const int maxElement = *std::max_element(vecin.begin(), vecin.end());
53 // std::max because in normalization we don't want divide by 0
54 // if maxElement == 0 check will be disabled please enable this line:
55 // const int maxElement = std::max(*std::max_element(avail.begin(), avail.end()), 1);
57 if (maxElement == 0)
58 return result;
60 // simple linear transformation algorithm
61 // for example:
62 // image.x(0) = pieces.x(0.0 >= x < 1.7)
63 // image.x(1) = pieces.x(1.7 >= x < 3.4)
65 for (int x = 0; x < reqSize; ++x)
67 // R - real
68 const float fromR = x * ratio;
69 const float toR = (x + 1) * ratio;
71 // C - integer
72 int fromC = fromR;// std::floor not needed
73 int toC = std::ceil(toR);
74 if (toC > vecin.size())
75 --toC;
77 // position in pieces table
78 int x2 = fromC;
80 // little speed up for really big pieces table, 10K+ size
81 const int toCMinusOne = toC - 1;
83 // value in returned vector
84 float value = 0;
86 // case when calculated range is (15.2 >= x < 15.7)
87 if (x2 == toCMinusOne)
89 if (vecin[x2])
90 value += ratio * vecin[x2];
91 ++x2;
93 // case when (15.2 >= x < 17.8)
94 else
96 // subcase (15.2 >= x < 16)
97 if (x2 != fromR)
99 if (vecin[x2])
100 value += (1.0 - (fromR - fromC)) * vecin[x2];
101 ++x2;
104 // subcase (16 >= x < 17)
105 for (; x2 < toCMinusOne; ++x2)
106 if (vecin[x2])
107 value += vecin[x2];
109 // subcase (17 >= x < 17.8)
110 if (x2 == toCMinusOne)
112 if (vecin[x2])
113 value += (1.0 - (toC - toR)) * vecin[x2];
114 ++x2;
118 // normalization <0, 1>
119 value /= ratio * maxElement;
121 // float precision sometimes gives > 1, because it's not possible to store irrational numbers
122 value = std::min(value, 1.0f);
124 result[x] = value;
127 return result;
130 QImage PieceAvailabilityBar::renderImage()
132 QImage image {width() - 2 * borderWidth, 1, QImage::Format_RGB888};
133 if (image.isNull())
135 qDebug() << "QImage allocation failed, width():" << width();
136 return image;
139 if (m_pieces.empty())
141 image.fill(backgroundColor());
142 return image;
145 QList<float> scaledPieces = intToFloatVector(m_pieces, image.width());
147 // filling image
148 for (int x = 0; x < scaledPieces.size(); ++x)
150 float piecesToValue = scaledPieces.at(x);
151 image.setPixel(x, 0, pieceColors()[piecesToValue * 255]);
154 return image;
157 void PieceAvailabilityBar::setAvailability(const QList<int> &avail)
159 m_pieces = avail;
161 redraw();
164 void PieceAvailabilityBar::clear()
166 m_pieces.clear();
167 base::clear();
170 QString PieceAvailabilityBar::simpleToolTipText() const
172 const QString borderColor = colorBoxBorderColor().name();
173 const QString rowHTML = u"<tr><td width=20 bgcolor='%1' style='border: 1px solid \"%2\";'></td><td>%3</td></tr>"_s;
174 return u"<table cellspacing=4>"
175 + rowHTML.arg(backgroundColor().name(), borderColor, tr("Unavailable pieces"))
176 + rowHTML.arg(pieceColor().name(), borderColor, tr("Available pieces"))
177 + u"</table>";