Browse Source

- Reloading a torrent only when necessary (properties, when files are filtered but full allocation mode is disabled)

adaptive-webui-19844
Christophe Dumez 18 years ago
parent
commit
18ec98c3fb
  1. 1
      Changelog
  2. 3
      TODO
  3. 2
      src/FinishedTorrents.cpp
  4. 8
      src/GUI.cpp
  5. 2
      src/GUI.h
  6. 38
      src/PropListDelegate.h
  7. 33
      src/bittorrent.cpp
  8. 6
      src/bittorrent.h
  9. 13
      src/properties_imp.cpp
  10. 10
      src/properties_imp.h

1
Changelog

@ -24,6 +24,7 @@
- BUGFIX: Made ETA more reliable using stats instead of instant values - BUGFIX: Made ETA more reliable using stats instead of instant values
- BUGFIX: Remove torrent from hard drive used to delete parent folder if empty - BUGFIX: Remove torrent from hard drive used to delete parent folder if empty
- BUGFIX: Fixed a crash when filtering all the files in a torrent - BUGFIX: Fixed a crash when filtering all the files in a torrent
- BUGFIX: Reload torrent only when necessary (properties)
- COSMETIC: Redesigned torrent properties a little - COSMETIC: Redesigned torrent properties a little
- COSMETIC: Redesigned options a little - COSMETIC: Redesigned options a little
- COSMETIC: Display more logs messages concerning features - COSMETIC: Display more logs messages concerning features

3
TODO

@ -46,5 +46,4 @@
- Allow to scan multiple directories - Allow to scan multiple directories
- Fix all (or almost all) opened bugs in bug tracker - Fix all (or almost all) opened bugs in bug tracker
- Fix sorting with Qt 4.3 - Reported to Trolltech, waiting for fix - Fix sorting with Qt 4.3 - Reported to Trolltech, waiting for fix
- update sorting when a new torrent is added - update sorting when a new torrent is added
- properties: reload torrent only if priorities changed

2
src/FinishedTorrents.cpp

@ -307,7 +307,7 @@ void FinishedTorrents::showProperties(const QModelIndex &index){
QString fileHash = finishedListModel->data(finishedListModel->index(row, HASH)).toString(); QString fileHash = finishedListModel->data(finishedListModel->index(row, HASH)).toString();
torrent_handle h = BTSession->getTorrentHandle(fileHash); torrent_handle h = BTSession->getTorrentHandle(fileHash);
QStringList errors = ((GUI*)parent)->trackerErrors.value(fileHash, QStringList(tr("None", "i.e: No error message"))); QStringList errors = ((GUI*)parent)->trackerErrors.value(fileHash, QStringList(tr("None", "i.e: No error message")));
properties *prop = new properties(this, h, errors); properties *prop = new properties(this, BTSession, h, errors);
connect(prop, SIGNAL(changedFilteredFiles(torrent_handle, bool)), BTSession, SLOT(reloadTorrent(torrent_handle, bool))); connect(prop, SIGNAL(changedFilteredFiles(torrent_handle, bool)), BTSession, SLOT(reloadTorrent(torrent_handle, bool)));
prop->show(); prop->show();
} }

8
src/GUI.cpp

@ -154,7 +154,6 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent){
// Configure BT session according to options // Configure BT session according to options
configureSession(true); configureSession(true);
force_exit = false; force_exit = false;
connect(&BTSession, SIGNAL(updateFileSize(QString)), this, SLOT(updateFileSize(QString)));
// Resume unfinished torrents // Resume unfinished torrents
BTSession.resumeUnfinishedTorrents(); BTSession.resumeUnfinishedTorrents();
// Load last columns width for download list // Load last columns width for download list
@ -1163,12 +1162,13 @@ void GUI::showProperties(const QModelIndex &index){
QString fileHash = DLListModel->data(DLListModel->index(row, HASH)).toString(); QString fileHash = DLListModel->data(DLListModel->index(row, HASH)).toString();
torrent_handle h = BTSession.getTorrentHandle(fileHash); torrent_handle h = BTSession.getTorrentHandle(fileHash);
QStringList errors = trackerErrors.value(fileHash, QStringList(tr("None", "i.e: No error message"))); QStringList errors = trackerErrors.value(fileHash, QStringList(tr("None", "i.e: No error message")));
properties *prop = new properties(this, h, errors); properties *prop = new properties(this, &BTSession, h, errors);
connect(prop, SIGNAL(changedFilteredFiles(torrent_handle, bool)), &BTSession, SLOT(reloadTorrent(torrent_handle, bool))); connect(prop, SIGNAL(mustHaveFullAllocationMode(torrent_handle)), &BTSession, SLOT(reloadTorrent(torrent_handle)));
connect(prop, SIGNAL(filteredFilesChanged(const QString&)), this, SLOT(updateFileSize(const QString&)));
prop->show(); prop->show();
} }
void GUI::updateFileSize(QString hash){ void GUI::updateFileSize(const QString& hash){
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
DLListModel->setData(DLListModel->index(row, SIZE), QVariant((qlonglong)BTSession.torrentEffectiveSize(hash))); DLListModel->setData(DLListModel->index(row, SIZE), QVariant((qlonglong)BTSession.torrentEffectiveSize(hash)));
} }

2
src/GUI.h

@ -171,7 +171,7 @@ class GUI : public QMainWindow, private Ui::MainWindow{
void trackerError(const QString& hash, const QString& time, const QString& msg); void trackerError(const QString& hash, const QString& time, const QString& msg);
void trackerAuthenticationRequired(torrent_handle& h); void trackerAuthenticationRequired(torrent_handle& h);
void setTabText(int index, QString text); void setTabText(int index, QString text);
void updateFileSize(QString hash); void updateFileSize(const QString& hash);
void sortProgressColumnDelayed(); void sortProgressColumnDelayed();
protected: protected:

38
src/PropListDelegate.h

@ -46,8 +46,13 @@
class PropListDelegate: public QItemDelegate { class PropListDelegate: public QItemDelegate {
Q_OBJECT Q_OBJECT
private:
bool* filteredFilesChanged;
public: public:
PropListDelegate(QObject *parent=0) : QItemDelegate(parent){} PropListDelegate(QObject *parent=0, bool* filteredFilesChanged=0) : QItemDelegate(parent){
this->filteredFilesChanged = filteredFilesChanged;
}
~PropListDelegate(){} ~PropListDelegate(){}
@ -206,21 +211,42 @@ class PropListDelegate: public QItemDelegate {
} else { } else {
color = "red"; color = "red";
} }
unsigned short old_val = index.model()->data(index, Qt::DisplayRole).toInt();
switch(value){ switch(value){
case 0: case 0:
model->setData(index, QVariant(IGNORED)); if(old_val != IGNORED){
model->setData(index, QVariant(IGNORED));
if(filteredFilesChanged != 0)
*filteredFilesChanged = true;
}
break; break;
case 1: case 1:
model->setData(index, QVariant(NORMAL)); if(old_val != NORMAL){
model->setData(index, QVariant(NORMAL));
if(filteredFilesChanged != 0)
*filteredFilesChanged = true;
}
break; break;
case 2: case 2:
model->setData(index, QVariant(HIGH)); if(old_val != HIGH){
model->setData(index, QVariant(HIGH));
if(filteredFilesChanged != 0)
*filteredFilesChanged = true;
}
break; break;
case 3: case 3:
model->setData(index, QVariant(MAXIMUM)); if(old_val != MAXIMUM){
model->setData(index, QVariant(MAXIMUM));
if(filteredFilesChanged != 0)
*filteredFilesChanged = true;
}
break; break;
default: default:
model->setData(index, QVariant(NORMAL)); if(old_val != NORMAL){
model->setData(index, QVariant(NORMAL));
if(filteredFilesChanged != 0)
*filteredFilesChanged = true;
}
} }
for(int i=0; i<model->columnCount(); ++i){ for(int i=0; i<model->columnCount(); ++i){
model->setData(model->index(index.row(), i), QVariant(QColor(color)), Qt::TextColorRole); model->setData(model->index(index.row(), i), QVariant(QColor(color)), Qt::TextColorRole);

33
src/bittorrent.cpp

@ -132,9 +132,12 @@ void bittorrent::deleteTorrent(const QString& hash, bool permanent){
torrentBackup.remove(hash+".priorities"); torrentBackup.remove(hash+".priorities");
torrentBackup.remove(hash+".savepath"); torrentBackup.remove(hash+".savepath");
torrentBackup.remove(hash+".trackers"); torrentBackup.remove(hash+".trackers");
// Remove it fro ETAs hash tables // Remove it from ETAs hash tables
ETAstats.take(hash); ETAstats.take(hash);
ETAs.take(hash); ETAs.take(hash);
int index = fullAllocationModeList.indexOf(hash);
if(index != -1)
fullAllocationModeList.removeAt(index);
if(permanent){ if(permanent){
// Remove from Hard drive // Remove from Hard drive
qDebug("Removing this on hard drive: %s", qPrintable(savePath+QDir::separator()+fileName)); qDebug("Removing this on hard drive: %s", qPrintable(savePath+QDir::separator()+fileName));
@ -266,7 +269,7 @@ void bittorrent::addTorrent(const QString& path, bool fromScanDir, bool onStartu
h.set_max_uploads(-1); h.set_max_uploads(-1);
qDebug("Torrent hash is " + hash.toUtf8()); qDebug("Torrent hash is " + hash.toUtf8());
// Load filtered files // Load filtered files
loadFilteredFiles(h); loadFilesPriorities(h);
// Load trackers // Load trackers
bool loaded_trackers = loadTrackerFile(hash); bool loaded_trackers = loadTrackerFile(hash);
// Doing this to order trackers well // Doing this to order trackers well
@ -440,7 +443,7 @@ void bittorrent::disableDHT(){
// Read pieces priorities from .priorities file // Read pieces priorities from .priorities file
// and ask torrent_handle to consider them // and ask torrent_handle to consider them
void bittorrent::loadFilteredFiles(torrent_handle &h){ void bittorrent::loadFilesPriorities(torrent_handle &h){
torrent_info torrentInfo = h.get_torrent_info(); torrent_info torrentInfo = h.get_torrent_info();
unsigned int nbFiles = torrentInfo.num_files(); unsigned int nbFiles = torrentInfo.num_files();
if(!h.is_valid()){ if(!h.is_valid()){
@ -757,7 +760,8 @@ void bittorrent::readAlerts(){
} }
} }
void bittorrent::reloadTorrent(const torrent_handle &h, bool compact_mode){ // Reload a torrent with full allocation mode
void bittorrent::reloadTorrent(const torrent_handle &h){
qDebug("** Reloading a torrent"); qDebug("** Reloading a torrent");
if(!h.is_valid()){ if(!h.is_valid()){
qDebug("/!\\ Error: Invalid handle"); qDebug("/!\\ Error: Invalid handle");
@ -767,6 +771,10 @@ void bittorrent::reloadTorrent(const torrent_handle &h, bool compact_mode){
fs::path saveDir = h.save_path(); fs::path saveDir = h.save_path();
QString fileName = QString(h.name().c_str()); QString fileName = QString(h.name().c_str());
QString fileHash = QString(misc::toString(h.info_hash()).c_str()); QString fileHash = QString(misc::toString(h.info_hash()).c_str());
int index = fullAllocationModeList.indexOf(fileHash);
if(index == -1){
fullAllocationModeList << fileHash;
}
qDebug("Reloading torrent: %s", (const char*)fileName.toUtf8()); qDebug("Reloading torrent: %s", (const char*)fileName.toUtf8());
torrent_handle new_h; torrent_handle new_h;
entry resumeData; entry resumeData;
@ -796,17 +804,13 @@ void bittorrent::reloadTorrent(const torrent_handle &h, bool compact_mode){
std::cerr << "Error: Couldn't reload the torrent\n"; std::cerr << "Error: Couldn't reload the torrent\n";
return; return;
} }
new_h = s->add_torrent(t, saveDir, resumeData, compact_mode); new_h = s->add_torrent(t, saveDir, resumeData, false);
if(compact_mode){ qDebug("Using full allocation mode");
qDebug("Using compact allocation mode");
}else{
qDebug("Using full allocation mode");
}
// new_h.set_max_connections(60); // new_h.set_max_connections(60);
new_h.set_max_uploads(-1); new_h.set_max_uploads(-1);
// Load filtered Files // Load filtered Files
loadFilteredFiles(new_h); loadFilesPriorities(new_h);
// Pause torrent if it was paused last time // Pause torrent if it was paused last time
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+fileHash+".paused")){ if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+fileHash+".paused")){
@ -817,7 +821,6 @@ void bittorrent::reloadTorrent(const torrent_handle &h, bool compact_mode){
qDebug("Incremental download enabled for %s", (const char*)fileName.toUtf8()); qDebug("Incremental download enabled for %s", (const char*)fileName.toUtf8());
new_h.set_sequenced_download_threshold(15); new_h.set_sequenced_download_threshold(15);
} }
emit updateFileSize(fileHash);
} }
int bittorrent::getListenPort() const{ int bittorrent::getListenPort() const{
@ -828,6 +831,12 @@ session_status bittorrent::getSessionStatus() const{
return s->status(); return s->status();
} }
bool bittorrent::inFullAllocationMode(const QString& hash) const{
if(fullAllocationModeList.indexOf(hash) != -1)
return true;
return false;
}
QString bittorrent::getSavePath(const QString& hash){ QString bittorrent::getSavePath(const QString& hash){
QFile savepath_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".savepath"); QFile savepath_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".savepath");
QByteArray line; QByteArray line;

6
src/bittorrent.h

@ -62,6 +62,7 @@ class bittorrent : public QObject{
QHash<QString, QList<long> > ETAstats; QHash<QString, QList<long> > ETAstats;
QHash<QString, long> ETAs; QHash<QString, long> ETAs;
QTimer ETARefresher; QTimer ETARefresher;
QList<QString> fullAllocationModeList;
protected: protected:
QString getSavePath(const QString& hash); QString getSavePath(const QString& hash);
@ -85,6 +86,7 @@ class bittorrent : public QObject{
QStringList getUncheckedTorrentsList() const; QStringList getUncheckedTorrentsList() const;
long getETA(QString hash) const; long getETA(QString hash) const;
size_type torrentEffectiveSize(QString hash) const; size_type torrentEffectiveSize(QString hash) const;
bool inFullAllocationMode(const QString& hash) const;
public slots: public slots:
void addTorrent(const QString& path, bool fromScanDir = false, bool onStartup = false, const QString& from_url = QString()); void addTorrent(const QString& path, bool fromScanDir = false, bool onStartup = false, const QString& from_url = QString());
@ -104,7 +106,7 @@ class bittorrent : public QObject{
void enablePeerExchange(); void enablePeerExchange();
void enableIPFilter(ip_filter filter); void enableIPFilter(ip_filter filter);
void disableIPFilter(); void disableIPFilter();
void reloadTorrent(const torrent_handle &h, bool compact_mode = true); void reloadTorrent(const torrent_handle &h);
void setTorrentFinishedChecking(QString hash); void setTorrentFinishedChecking(QString hash);
void resumeUnfinishedTorrents(); void resumeUnfinishedTorrents();
void updateETAs(); void updateETAs();
@ -119,10 +121,10 @@ class bittorrent : public QObject{
void setSessionSettings(session_settings sessionSettings); void setSessionSettings(session_settings sessionSettings);
void setDefaultSavePath(const QString& savepath); void setDefaultSavePath(const QString& savepath);
void applyEncryptionSettings(pe_settings se); void applyEncryptionSettings(pe_settings se);
void loadFilesPriorities(torrent_handle& h);
protected slots: protected slots:
void cleanDeleter(deleteThread* deleter); void cleanDeleter(deleteThread* deleter);
void loadFilteredFiles(torrent_handle& h);
void scanDirectory(); void scanDirectory();
void readAlerts(); void readAlerts();
void processDownloadedFile(const QString&, const QString&, int, const QString&); void processDownloadedFile(const QString&, const QString&, int, const QString&);

13
src/properties_imp.cpp

@ -26,8 +26,10 @@
#include <QMessageBox> #include <QMessageBox>
// Constructor // Constructor
properties::properties(QWidget *parent, torrent_handle &h, QStringList trackerErrors): QDialog(parent), h(h){ properties::properties(QWidget *parent, bittorrent *BTSession, torrent_handle &h, QStringList trackerErrors): QDialog(parent), h(h){
setupUi(this); setupUi(this);
this->BTSession = BTSession;
changedFilteredfiles = false;
lbl_priorities->setText(tr("Priorities:")+"<ul><li>"+tr("Ignored: file is not downloaded at all")+"</li><li>"+tr("Normal: normal priority. Download order is dependent on availability")+"</li><li>"+tr("High: higher than normal priority. Pieces are preferred over pieces with the same availability, but not over pieces with lower availability")+"</li><li>"+tr("Maximum: maximum priority, availability is disregarded, the piece is preferred over any other piece with lower priority")+"</li></ul>"); lbl_priorities->setText(tr("Priorities:")+"<ul><li>"+tr("Ignored: file is not downloaded at all")+"</li><li>"+tr("Normal: normal priority. Download order is dependent on availability")+"</li><li>"+tr("High: higher than normal priority. Pieces are preferred over pieces with the same availability, but not over pieces with lower availability")+"</li><li>"+tr("Maximum: maximum priority, availability is disregarded, the piece is preferred over any other piece with lower priority")+"</li></ul>");
// set icons // set icons
addTracker_button->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/add.png"))); addTracker_button->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/add.png")));
@ -42,7 +44,7 @@ properties::properties(QWidget *parent, torrent_handle &h, QStringList trackerEr
PropListModel->setHeaderData(PROGRESS, Qt::Horizontal, tr("Progress")); PropListModel->setHeaderData(PROGRESS, Qt::Horizontal, tr("Progress"));
PropListModel->setHeaderData(PRIORITY, Qt::Horizontal, tr("Priority")); PropListModel->setHeaderData(PRIORITY, Qt::Horizontal, tr("Priority"));
filesList->setModel(PropListModel); filesList->setModel(PropListModel);
PropDelegate = new PropListDelegate(); PropDelegate = new PropListDelegate(0, &changedFilteredfiles);
filesList->setItemDelegate(PropDelegate); filesList->setItemDelegate(PropDelegate);
connect(filesList, SIGNAL(clicked(const QModelIndex&)), filesList, SLOT(edit(const QModelIndex&))); connect(filesList, SIGNAL(clicked(const QModelIndex&)), filesList, SLOT(edit(const QModelIndex&)));
connect(addTracker_button, SIGNAL(clicked()), this, SLOT(askForTracker())); connect(addTracker_button, SIGNAL(clicked()), this, SLOT(askForTracker()));
@ -329,6 +331,7 @@ void properties::on_okButton_clicked(){
} }
void properties::savePiecesPriorities(){ void properties::savePiecesPriorities(){
if(!changedFilteredfiles) return;
qDebug("Saving pieces priorities"); qDebug("Saving pieces priorities");
torrent_info torrentInfo = h.get_torrent_info(); torrent_info torrentInfo = h.get_torrent_info();
bool hasFilteredFiles = false; bool hasFilteredFiles = false;
@ -351,6 +354,10 @@ void properties::savePiecesPriorities(){
pieces_file.write(QByteArray((misc::toString(priority)+"\n").c_str())); pieces_file.write(QByteArray((misc::toString(priority)+"\n").c_str()));
} }
pieces_file.close(); pieces_file.close();
emit changedFilteredFiles(h, !hasFilteredFiles); if(hasFilteredFiles && !BTSession->inFullAllocationMode(fileHash)){
emit mustHaveFullAllocationMode(h);
}
BTSession->loadFilesPriorities(h);
emit filteredFilesChanged(fileHash);
has_filtered_files = hasFilteredFiles; has_filtered_files = hasFilteredFiles;
} }

10
src/properties_imp.h

@ -23,6 +23,7 @@
#define PROPERTIES_H #define PROPERTIES_H
#include "ui_properties.h" #include "ui_properties.h"
#include "bittorrent.h"
#include <libtorrent/session.hpp> #include <libtorrent/session.hpp>
#include <QStandardItemModel> #include <QStandardItemModel>
#include <QTimer> #include <QTimer>
@ -40,6 +41,8 @@ class properties : public QDialog, private Ui::properties{
QStandardItemModel *PropListModel; QStandardItemModel *PropListModel;
QTimer *updateProgressTimer; QTimer *updateProgressTimer;
bool has_filtered_files; bool has_filtered_files;
bool changedFilteredfiles;
bittorrent *BTSession;
protected slots: protected slots:
void on_okButton_clicked(); void on_okButton_clicked();
@ -56,12 +59,13 @@ class properties : public QDialog, private Ui::properties{
void riseSelectedTracker(); void riseSelectedTracker();
signals: signals:
void changedFilteredFiles(torrent_handle h, bool compact_mode); void filteredFilesChanged(const QString& fileHash);
void fileSizeChanged(QString fileHash); void fileSizeChanged(const QString& fileHash);
void mustHaveFullAllocationMode(torrent_handle h);
public: public:
// Constructor // Constructor
properties(QWidget *parent, torrent_handle &h, QStringList trackerErrors = QStringList()); properties(QWidget *parent, bittorrent *BTSession, torrent_handle &h, QStringList trackerErrors = QStringList());
~properties(); ~properties();
}; };

Loading…
Cancel
Save