- Graphically display piece availability in torrent preferences

This commit is contained in:
Christophe Dumez 2009-11-21 19:40:24 +00:00
parent fb6b40ccd1
commit 47d545633d
7 changed files with 182 additions and 7 deletions

View file

@ -18,6 +18,7 @@
- FEATURE: Display the number of peers returned by each tracker & DHT/PeX/LSD
- FEATURE: Global upload/download speeds can be capped from status bar (µTorrent behavior)
- FEATURE: Added option to download first and last piece of a torrent main file first (for preview)
- FEATURE: Graphically display piece availability in torrent properties
- FEATURE: Dropped Qt 4.3 support (Qt >= 4.4 is now required)
- FEATURE: Added per-torrent super seeding mode (libtorrent >= v0.15 only)
- FEATURE: Support for storing symbolic links in .torrent files (libtorrent >= v0.15 only)

View file

@ -1,3 +1,33 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2006 Christophe Dumez
*
* 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.
*
* Contact : chris@qbittorrent.org
*/
#ifndef DOWNLOADEDPIECESBAR_H
#define DOWNLOADEDPIECESBAR_H

View file

@ -0,0 +1,96 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2006 Christophe Dumez
*
* 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.
*
* Contact : chris@qbittorrent.org
*/
#ifndef PIECEAVAILABILITYBAR_H
#define PIECEAVAILABILITYBAR_H
#include <QWidget>
#include <QPainter>
#include <QPixmap>
#include <QColor>
#include <numeric>
#define BAR_HEIGHT 18
class PieceAvailabilityBar: public QWidget {
Q_OBJECT
private:
QPixmap pixmap;
public:
PieceAvailabilityBar(QWidget *parent): QWidget(parent) {
setFixedHeight(BAR_HEIGHT);
}
void setAvailability(std::vector<int>& avail) {
if(avail.empty()) {
// Empty bar
pixmap = QPixmap(1, 1);
QPainter painter(&pixmap);
painter.setPen(Qt::white);
painter.drawPoint(0,0);
} else {
// Look for maximum value
double average = std::accumulate(avail.begin(), avail.end(), 0)/(double)avail.size();
uint nb_pieces = avail.size();
pixmap = QPixmap(nb_pieces, 1);
QPainter painter(&pixmap);
std::vector<int>::iterator it;
for(uint i=0; i < nb_pieces; ++i) {
painter.setPen(getPieceColor(avail[i], average));
painter.drawPoint(i,0);
}
}
update();
}
void clear() {
pixmap = QPixmap();
update();
}
protected:
void paintEvent(QPaintEvent *) {
if(pixmap.isNull()) return;
QPainter painter(this);
painter.drawPixmap(rect(), pixmap);
}
QColor getPieceColor(int avail, double average) {
if(!avail) return Qt::white;
//qDebug("avail: %d/%d", avail, max_avail);
QColor color = Qt::blue; // average avail
double fraction = 100.*average/avail;
return color.lighter(fraction);
}
};
#endif // PIECEAVAILABILITYBAR_H

View file

@ -48,6 +48,7 @@
#include "trackerlist.h"
#include "GUI.h"
#include "downloadedpiecesbar.h"
#include "pieceavailabilitybar.h"
#ifdef Q_WS_MAC
#define DEFAULT_BUTTON_CSS ""
@ -99,9 +100,10 @@ PropertiesWidget::PropertiesWidget(QWidget *parent, GUI* main_window, TransferLi
// Downloaded pieces progress bar
downloaded_pieces = new DownloadedPiecesBar(this);
//progressBar = new RealProgressBar(this);
//progressBar->setForegroundColor(Qt::blue);
ProgressHLayout->insertWidget(1, downloaded_pieces);
// Pieces availability bar
pieces_availability = new PieceAvailabilityBar(this);
ProgressHLayout_2->insertWidget(1, pieces_availability);
// Tracker list
trackerList = new TrackerList(this);
verticalLayout_trackers->addWidget(trackerList);
@ -120,6 +122,7 @@ PropertiesWidget::~PropertiesWidget() {
delete trackerList;
delete peersList;
delete downloaded_pieces;
delete pieces_availability;
delete PropListModel;
delete PropDelegate;
// Delete QActions
@ -165,6 +168,7 @@ void PropertiesWidget::clear() {
progress_lbl->clear();
trackerList->clear();
downloaded_pieces->clear();
pieces_availability->clear();
wasted->clear();
upTotal->clear();
dlTotal->clear();
@ -307,6 +311,10 @@ void PropertiesWidget::loadDynamicData() {
shareRatio->setText(QString(QByteArray::number(ratio, 'f', 1)));
// Downloaded pieces
downloaded_pieces->setProgress(h.pieces());
// Pieces availability
std::vector<int> avail;
h.piece_availability(avail);
pieces_availability->setAvailability(avail);
// Progress
progress_lbl->setText(QString::number(h.progress()*100., 'f', 1)+"%");
return;

View file

@ -47,6 +47,7 @@ class PeerListWidget;
class TrackerList;
class GUI;
class DownloadedPiecesBar;
class PieceAvailabilityBar;
enum Tab {MAIN_TAB, TRACKERS_TAB, PEERS_TAB, URLSEEDS_TAB, FILES_TAB};
enum SlideState {REDUCED, VISIBLE};
@ -71,6 +72,7 @@ private:
QAction *actionHigh;
QList<int> slideSizes;
DownloadedPiecesBar *downloaded_pieces;
PieceAvailabilityBar *pieces_availability;
protected:
QPushButton* getButtonFromIndex(int index);

View file

@ -194,7 +194,8 @@ HEADERS += GUI.h \
deletionconfirmationdlg.h \
statusbar.h \
trackerlist.h \
downloadedpiecesbar.h
downloadedpiecesbar.h \
pieceavailabilitybar.h
FORMS += ui/mainwindow.ui \
ui/options.ui \
ui/about.ui \

View file

@ -55,7 +55,7 @@
<x>0</x>
<y>0</y>
<width>518</width>
<height>348</height>
<height>371</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8">
@ -110,6 +110,45 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="ProgressHLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<widget class="QLabel" name="downloaded_pieces_lbl_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Availability:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_2">
<property name="orientation">
@ -814,8 +853,6 @@ p, li { white-space: pre-wrap; }
</item>
</layout>
</widget>
<resources>
<include location="icons.qrc"/>
</resources>
<resources/>
<connections/>
</ui>