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 "downloadedpiecesbar.h"
38 #include "base/global.h"
42 QColor
dlPieceColor(const QColor
&pieceColor
)
44 const QColor green
{Qt::green
};
45 return QColor::fromHsl(green
.hslHue(), pieceColor
.hslSaturation(), pieceColor
.lightness());
49 DownloadedPiecesBar::DownloadedPiecesBar(QWidget
*parent
)
55 QList
<float> DownloadedPiecesBar::bitfieldToFloatVector(const QBitArray
&vecin
, int reqSize
)
57 QList
<float> result(reqSize
, 0.0);
58 if (vecin
.isEmpty()) return result
;
60 const float ratio
= vecin
.size() / static_cast<float>(reqSize
);
62 // simple linear transformation algorithm
64 // image.x(0) = pieces.x(0.0 >= x < 1.7)
65 // image.x(1) = pieces.x(1.7 >= x < 3.4)
67 for (int x
= 0; x
< reqSize
; ++x
)
70 const float fromR
= x
* ratio
;
71 const float toR
= (x
+ 1) * ratio
;
74 int fromC
= fromR
; // std::floor not needed
75 int toC
= std::ceil(toR
);
76 if (toC
> vecin
.size())
79 // position in pieces table
82 // little speed up for really big pieces table, 10K+ size
83 const int toCMinusOne
= toC
- 1;
85 // value in returned vector
88 // case when calculated range is (15.2 >= x < 15.7)
89 if (x2
== toCMinusOne
)
95 // case when (15.2 >= x < 17.8)
98 // subcase (15.2 >= x < 16)
102 value
+= 1.0 - (fromR
- fromC
);
106 // subcase (16 >= x < 17)
107 for (; x2
< toCMinusOne
; ++x2
)
111 // subcase (17 >= x < 17.8)
112 if (x2
== toCMinusOne
)
115 value
+= 1.0 - (toC
- toR
);
120 // normalization <0, 1>
123 // float precision sometimes gives > 1, because it's not possible to store irrational numbers
124 value
= std::min(value
, 1.0f
);
132 QImage
DownloadedPiecesBar::renderImage()
134 // qDebug() << "updateImage";
135 QImage image
{width() - 2 * borderWidth
, 1, QImage::Format_RGB888
};
138 qDebug() << "QImage allocation failed, width():" << width();
142 if (m_pieces
.isEmpty())
144 image
.fill(backgroundColor());
148 QList
<float> scaledPieces
= bitfieldToFloatVector(m_pieces
, image
.width());
149 QList
<float> scaledPiecesDl
= bitfieldToFloatVector(m_downloadedPieces
, image
.width());
152 for (int x
= 0; x
< scaledPieces
.size(); ++x
)
154 float piecesToValue
= scaledPieces
.at(x
);
155 float piecesToValueDl
= scaledPiecesDl
.at(x
);
156 if (piecesToValueDl
!= 0)
158 float fillRatio
= piecesToValue
+ piecesToValueDl
;
159 float ratio
= piecesToValueDl
/ fillRatio
;
161 QRgb mixedColor
= mixTwoColors(pieceColor().rgb(), m_dlPieceColor
.rgb(), ratio
);
162 mixedColor
= mixTwoColors(backgroundColor().rgb(), mixedColor
, fillRatio
);
164 image
.setPixel(x
, 0, mixedColor
);
168 image
.setPixel(x
, 0, pieceColors()[piecesToValue
* 255]);
175 void DownloadedPiecesBar::setProgress(const QBitArray
&pieces
, const QBitArray
&downloadedPieces
)
178 m_downloadedPieces
= downloadedPieces
;
183 void DownloadedPiecesBar::clear()
186 m_downloadedPieces
.clear();
190 QString
DownloadedPiecesBar::simpleToolTipText() const
192 const QString borderColor
= colorBoxBorderColor().name();
193 const QString rowHTML
= u
"<tr><td width=20 bgcolor='%1' style='border: 1px solid \"%2\";'></td><td>%3</td></tr>"_s
;
194 return u
"<table cellspacing=4>"
195 + rowHTML
.arg(backgroundColor().name(), borderColor
, tr("Missing pieces"))
196 + rowHTML
.arg(m_dlPieceColor
.name(), borderColor
, tr("Partial pieces"))
197 + rowHTML
.arg(pieceColor().name(), borderColor
, tr("Completed pieces"))
202 void DownloadedPiecesBar::updateColors()
204 PiecesBar::updateColors();
208 void DownloadedPiecesBar::updateColorsImpl()
210 m_dlPieceColor
= dlPieceColor(pieceColor());