diff --git a/Changelog b/Changelog index 7b24bfbc8..94f171827 100644 --- a/Changelog +++ b/Changelog @@ -24,6 +24,7 @@ - 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: 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 options a little - COSMETIC: Display more logs messages concerning features diff --git a/TODO b/TODO index a8cd37d2b..9a48b3c9c 100644 --- a/TODO +++ b/TODO @@ -46,5 +46,4 @@ - Allow to scan multiple directories - Fix all (or almost all) opened bugs in bug tracker - Fix sorting with Qt 4.3 - Reported to Trolltech, waiting for fix -- update sorting when a new torrent is added -- properties: reload torrent only if priorities changed \ No newline at end of file +- update sorting when a new torrent is added \ No newline at end of file diff --git a/src/FinishedTorrents.cpp b/src/FinishedTorrents.cpp index f415df1da..d29c10d66 100644 --- a/src/FinishedTorrents.cpp +++ b/src/FinishedTorrents.cpp @@ -307,7 +307,7 @@ void FinishedTorrents::showProperties(const QModelIndex &index){ QString fileHash = finishedListModel->data(finishedListModel->index(row, HASH)).toString(); torrent_handle h = BTSession->getTorrentHandle(fileHash); 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))); prop->show(); } diff --git a/src/GUI.cpp b/src/GUI.cpp index 22525430a..bcd5cdd72 100644 --- a/src/GUI.cpp +++ b/src/GUI.cpp @@ -154,7 +154,6 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent){ // Configure BT session according to options configureSession(true); force_exit = false; - connect(&BTSession, SIGNAL(updateFileSize(QString)), this, SLOT(updateFileSize(QString))); // Resume unfinished torrents BTSession.resumeUnfinishedTorrents(); // 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(); torrent_handle h = BTSession.getTorrentHandle(fileHash); QStringList errors = trackerErrors.value(fileHash, QStringList(tr("None", "i.e: No error message"))); - properties *prop = new properties(this, h, errors); - connect(prop, SIGNAL(changedFilteredFiles(torrent_handle, bool)), &BTSession, SLOT(reloadTorrent(torrent_handle, bool))); + properties *prop = new properties(this, &BTSession, h, errors); + connect(prop, SIGNAL(mustHaveFullAllocationMode(torrent_handle)), &BTSession, SLOT(reloadTorrent(torrent_handle))); + connect(prop, SIGNAL(filteredFilesChanged(const QString&)), this, SLOT(updateFileSize(const QString&))); prop->show(); } -void GUI::updateFileSize(QString hash){ +void GUI::updateFileSize(const QString& hash){ int row = getRowFromHash(hash); DLListModel->setData(DLListModel->index(row, SIZE), QVariant((qlonglong)BTSession.torrentEffectiveSize(hash))); } diff --git a/src/GUI.h b/src/GUI.h index 9a58114cd..3109c2498 100644 --- a/src/GUI.h +++ b/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 trackerAuthenticationRequired(torrent_handle& h); void setTabText(int index, QString text); - void updateFileSize(QString hash); + void updateFileSize(const QString& hash); void sortProgressColumnDelayed(); protected: diff --git a/src/PropListDelegate.h b/src/PropListDelegate.h index 97a57cfda..2d87e958c 100644 --- a/src/PropListDelegate.h +++ b/src/PropListDelegate.h @@ -46,8 +46,13 @@ class PropListDelegate: public QItemDelegate { Q_OBJECT + private: + bool* filteredFilesChanged; + public: - PropListDelegate(QObject *parent=0) : QItemDelegate(parent){} + PropListDelegate(QObject *parent=0, bool* filteredFilesChanged=0) : QItemDelegate(parent){ + this->filteredFilesChanged = filteredFilesChanged; + } ~PropListDelegate(){} @@ -206,21 +211,42 @@ class PropListDelegate: public QItemDelegate { } else { color = "red"; } + unsigned short old_val = index.model()->data(index, Qt::DisplayRole).toInt(); switch(value){ case 0: - model->setData(index, QVariant(IGNORED)); + if(old_val != IGNORED){ + model->setData(index, QVariant(IGNORED)); + if(filteredFilesChanged != 0) + *filteredFilesChanged = true; + } break; case 1: - model->setData(index, QVariant(NORMAL)); + if(old_val != NORMAL){ + model->setData(index, QVariant(NORMAL)); + if(filteredFilesChanged != 0) + *filteredFilesChanged = true; + } break; case 2: - model->setData(index, QVariant(HIGH)); + if(old_val != HIGH){ + model->setData(index, QVariant(HIGH)); + if(filteredFilesChanged != 0) + *filteredFilesChanged = true; + } break; case 3: - model->setData(index, QVariant(MAXIMUM)); + if(old_val != MAXIMUM){ + model->setData(index, QVariant(MAXIMUM)); + if(filteredFilesChanged != 0) + *filteredFilesChanged = true; + } break; default: - model->setData(index, QVariant(NORMAL)); + if(old_val != NORMAL){ + model->setData(index, QVariant(NORMAL)); + if(filteredFilesChanged != 0) + *filteredFilesChanged = true; + } } for(int i=0; icolumnCount(); ++i){ model->setData(model->index(index.row(), i), QVariant(QColor(color)), Qt::TextColorRole); diff --git a/src/bittorrent.cpp b/src/bittorrent.cpp index 127706b7a..14445bf0a 100644 --- a/src/bittorrent.cpp +++ b/src/bittorrent.cpp @@ -132,9 +132,12 @@ void bittorrent::deleteTorrent(const QString& hash, bool permanent){ torrentBackup.remove(hash+".priorities"); torrentBackup.remove(hash+".savepath"); torrentBackup.remove(hash+".trackers"); - // Remove it fro ETAs hash tables + // Remove it from ETAs hash tables ETAstats.take(hash); ETAs.take(hash); + int index = fullAllocationModeList.indexOf(hash); + if(index != -1) + fullAllocationModeList.removeAt(index); if(permanent){ // Remove from Hard drive 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); qDebug("Torrent hash is " + hash.toUtf8()); // Load filtered files - loadFilteredFiles(h); + loadFilesPriorities(h); // Load trackers bool loaded_trackers = loadTrackerFile(hash); // Doing this to order trackers well @@ -440,7 +443,7 @@ void bittorrent::disableDHT(){ // Read pieces priorities from .priorities file // 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(); unsigned int nbFiles = torrentInfo.num_files(); 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"); if(!h.is_valid()){ qDebug("/!\\ Error: Invalid handle"); @@ -767,6 +771,10 @@ void bittorrent::reloadTorrent(const torrent_handle &h, bool compact_mode){ fs::path saveDir = h.save_path(); QString fileName = QString(h.name().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()); torrent_handle new_h; 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"; return; } - new_h = s->add_torrent(t, saveDir, resumeData, compact_mode); - if(compact_mode){ - qDebug("Using compact allocation mode"); - }else{ - qDebug("Using full allocation mode"); - } + new_h = s->add_torrent(t, saveDir, resumeData, false); + qDebug("Using full allocation mode"); // new_h.set_max_connections(60); new_h.set_max_uploads(-1); // Load filtered Files - loadFilteredFiles(new_h); + loadFilesPriorities(new_h); // Pause torrent if it was paused last time 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()); new_h.set_sequenced_download_threshold(15); } - emit updateFileSize(fileHash); } int bittorrent::getListenPort() const{ @@ -828,6 +831,12 @@ session_status bittorrent::getSessionStatus() const{ 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){ QFile savepath_file(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".savepath"); QByteArray line; diff --git a/src/bittorrent.h b/src/bittorrent.h index 3160aaef4..260081e8e 100644 --- a/src/bittorrent.h +++ b/src/bittorrent.h @@ -62,6 +62,7 @@ class bittorrent : public QObject{ QHash > ETAstats; QHash ETAs; QTimer ETARefresher; + QList fullAllocationModeList; protected: QString getSavePath(const QString& hash); @@ -85,6 +86,7 @@ class bittorrent : public QObject{ QStringList getUncheckedTorrentsList() const; long getETA(QString hash) const; size_type torrentEffectiveSize(QString hash) const; + bool inFullAllocationMode(const QString& hash) const; public slots: 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 enableIPFilter(ip_filter filter); void disableIPFilter(); - void reloadTorrent(const torrent_handle &h, bool compact_mode = true); + void reloadTorrent(const torrent_handle &h); void setTorrentFinishedChecking(QString hash); void resumeUnfinishedTorrents(); void updateETAs(); @@ -119,10 +121,10 @@ class bittorrent : public QObject{ void setSessionSettings(session_settings sessionSettings); void setDefaultSavePath(const QString& savepath); void applyEncryptionSettings(pe_settings se); + void loadFilesPriorities(torrent_handle& h); protected slots: void cleanDeleter(deleteThread* deleter); - void loadFilteredFiles(torrent_handle& h); void scanDirectory(); void readAlerts(); void processDownloadedFile(const QString&, const QString&, int, const QString&); diff --git a/src/properties_imp.cpp b/src/properties_imp.cpp index e4689d4cc..a4a909f6e 100644 --- a/src/properties_imp.cpp +++ b/src/properties_imp.cpp @@ -26,8 +26,10 @@ #include // 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); + this->BTSession = BTSession; + changedFilteredfiles = false; lbl_priorities->setText(tr("Priorities:")+"
  • "+tr("Ignored: file is not downloaded at all")+"
  • "+tr("Normal: normal priority. Download order is dependent on availability")+"
  • "+tr("High: higher than normal priority. Pieces are preferred over pieces with the same availability, but not over pieces with lower availability")+"
  • "+tr("Maximum: maximum priority, availability is disregarded, the piece is preferred over any other piece with lower priority")+"
"); // set icons 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(PRIORITY, Qt::Horizontal, tr("Priority")); filesList->setModel(PropListModel); - PropDelegate = new PropListDelegate(); + PropDelegate = new PropListDelegate(0, &changedFilteredfiles); filesList->setItemDelegate(PropDelegate); connect(filesList, SIGNAL(clicked(const QModelIndex&)), filesList, SLOT(edit(const QModelIndex&))); connect(addTracker_button, SIGNAL(clicked()), this, SLOT(askForTracker())); @@ -329,6 +331,7 @@ void properties::on_okButton_clicked(){ } void properties::savePiecesPriorities(){ + if(!changedFilteredfiles) return; qDebug("Saving pieces priorities"); torrent_info torrentInfo = h.get_torrent_info(); bool hasFilteredFiles = false; @@ -351,6 +354,10 @@ void properties::savePiecesPriorities(){ pieces_file.write(QByteArray((misc::toString(priority)+"\n").c_str())); } 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; } diff --git a/src/properties_imp.h b/src/properties_imp.h index b4f1811d5..debfcaa5d 100644 --- a/src/properties_imp.h +++ b/src/properties_imp.h @@ -23,6 +23,7 @@ #define PROPERTIES_H #include "ui_properties.h" +#include "bittorrent.h" #include #include #include @@ -40,6 +41,8 @@ class properties : public QDialog, private Ui::properties{ QStandardItemModel *PropListModel; QTimer *updateProgressTimer; bool has_filtered_files; + bool changedFilteredfiles; + bittorrent *BTSession; protected slots: void on_okButton_clicked(); @@ -56,12 +59,13 @@ class properties : public QDialog, private Ui::properties{ void riseSelectedTracker(); signals: - void changedFilteredFiles(torrent_handle h, bool compact_mode); - void fileSizeChanged(QString fileHash); + void filteredFilesChanged(const QString& fileHash); + void fileSizeChanged(const QString& fileHash); + void mustHaveFullAllocationMode(torrent_handle h); public: // Constructor - properties(QWidget *parent, torrent_handle &h, QStringList trackerErrors = QStringList()); + properties(QWidget *parent, bittorrent *BTSession, torrent_handle &h, QStringList trackerErrors = QStringList()); ~properties(); };