2 * Bittorrent Client using Qt and libtorrent.
3 * Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 * In addition, as a special exception, the copyright holders give permission to
20 * link this program with the OpenSSL project's "OpenSSL" library (or with
21 * modified versions of it that use the same license as the "OpenSSL" library),
22 * and distribute the linked executables. You must obey the GNU General Public
23 * License in all respects for all of the code used other than "OpenSSL". If you
24 * modify file(s), you may extend this exception to your version of the file(s),
25 * but you are not obligated to do so. If you do not wish to do so, delete this
26 * exception statement from your version.
29 #include "pieceavailabilitybar.h"
36 #include "base/global.h"
38 PieceAvailabilityBar::PieceAvailabilityBar(QWidget
*parent
)
43 QVector
<float> PieceAvailabilityBar::intToFloatVector(const QVector
<int> &vecin
, int reqSize
)
45 QVector
<float> result(reqSize
, 0.0);
46 if (vecin
.isEmpty()) return result
;
48 const float ratio
= static_cast<float>(vecin
.size()) / reqSize
;
50 const int maxElement
= *std::max_element(vecin
.begin(), vecin
.end());
52 // std::max because in normalization we don't want divide by 0
53 // if maxElement == 0 check will be disabled please enable this line:
54 // const int maxElement = std::max(*std::max_element(avail.begin(), avail.end()), 1);
59 // simple linear transformation algorithm
61 // image.x(0) = pieces.x(0.0 >= x < 1.7)
62 // image.x(1) = pieces.x(1.7 >= x < 3.4)
64 for (int x
= 0; x
< reqSize
; ++x
)
67 const float fromR
= x
* ratio
;
68 const float toR
= (x
+ 1) * ratio
;
71 int fromC
= fromR
;// std::floor not needed
72 int toC
= std::ceil(toR
);
73 if (toC
> vecin
.size())
76 // position in pieces table
79 // little speed up for really big pieces table, 10K+ size
80 const int toCMinusOne
= toC
- 1;
82 // value in returned vector
85 // case when calculated range is (15.2 >= x < 15.7)
86 if (x2
== toCMinusOne
)
89 value
+= ratio
* vecin
[x2
];
92 // case when (15.2 >= x < 17.8)
95 // subcase (15.2 >= x < 16)
99 value
+= (1.0 - (fromR
- fromC
)) * vecin
[x2
];
103 // subcase (16 >= x < 17)
104 for (; x2
< toCMinusOne
; ++x2
)
108 // subcase (17 >= x < 17.8)
109 if (x2
== toCMinusOne
)
112 value
+= (1.0 - (toC
- toR
)) * vecin
[x2
];
117 // normalization <0, 1>
118 value
/= ratio
* maxElement
;
120 // float precision sometimes gives > 1, because it's not possible to store irrational numbers
121 value
= std::min(value
, 1.0f
);
129 bool PieceAvailabilityBar::updateImage(QImage
&image
)
131 QImage
image2(width() - 2 * borderWidth
, 1, QImage::Format_RGB888
);
134 qDebug() << "QImage image2() allocation failed, width():" << width();
138 if (m_pieces
.empty())
140 image2
.fill(backgroundColor());
145 QVector
<float> scaledPieces
= intToFloatVector(m_pieces
, image2
.width());
148 for (int x
= 0; x
< scaledPieces
.size(); ++x
)
150 float piecesToValue
= scaledPieces
.at(x
);
151 image2
.setPixel(x
, 0, pieceColors()[piecesToValue
* 255]);
157 void PieceAvailabilityBar::setAvailability(const QVector
<int> &avail
)
161 requestImageUpdate();
164 void PieceAvailabilityBar::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"))