diff --git a/Changelog b/Changelog index 4d3bb61a3..dd41e4004 100644 --- a/Changelog +++ b/Changelog @@ -41,6 +41,7 @@ - BUGFIX: search plugin update - do not display only last version changelog - BUGFIX: Search plugin update - fixed missing new lines in changelog - BUGFIX: The number of search results was not reset when clicking on 'Clear' button + - BUGFIX: Transfers lists refreshers were moved to separate threads - 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 b8ef1f0a2..46d2511a4 100644 --- a/TODO +++ b/TODO @@ -42,7 +42,6 @@ * beta3 - Windows port (Chris - Peerkoel) - Translations update - - Move transfer lists refreshers to threads? - Optimize and cleanup code - Wait for some bug fixes in libtorrent : - upload/download limit per torrent diff --git a/src/FinishedTorrents.cpp b/src/FinishedTorrents.cpp index 9fea4eb9b..98be9941e 100644 --- a/src/FinishedTorrents.cpp +++ b/src/FinishedTorrents.cpp @@ -30,6 +30,7 @@ #include #include #include +#include FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession){ setupUi(this); @@ -51,6 +52,7 @@ FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession){ finishedList->header()->resizeSection(0, 200); } // Make download list header clickable for sorting + qRegisterMetaType("QModelIndex"); finishedList->header()->setClickable(true); finishedList->header()->setSortIndicatorShown(true); connect(finishedList->header(), SIGNAL(sectionPressed(int)), this, SLOT(sortFinishedList(int))); @@ -67,12 +69,15 @@ FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession){ connect(actionPreview_file, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPreview_file_triggered())); connect(actionDelete_Permanently, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_Permanently_triggered())); connect(actionTorrent_Properties, SIGNAL(triggered()), this, SLOT(propertiesSelection())); + refresher = new FinishedListRefresher(this); + refresher->start(); } FinishedTorrents::~FinishedTorrents(){ saveColWidthFinishedList(); delete finishedListDelegate; delete finishedListModel; + delete refresher; } void FinishedTorrents::addFinishedSHA(QString hash){ @@ -80,6 +85,7 @@ void FinishedTorrents::addFinishedSHA(QString hash){ BTSession->setTorrentFinishedChecking(hash); } if(finishedSHAs.indexOf(hash) == -1) { + QMutexLocker locker(&finishedListAccess); finishedSHAs << hash; int row = finishedListModel->rowCount(); torrent_handle h = BTSession->getTorrentHandle(hash); @@ -168,6 +174,8 @@ void FinishedTorrents::on_actionSet_upload_limit_triggered(){ void FinishedTorrents::updateFinishedList(){ // qDebug("Updating finished list"); + if(((GUI*)parent)->getCurrentTab() != 1) return; + QMutexLocker locker(&finishedListAccess); QString hash; foreach(hash, finishedSHAs){ torrent_handle h = BTSession->getTorrentHandle(hash); @@ -213,6 +221,7 @@ int FinishedTorrents::getRowFromHash(QString hash) const{ // Will move it to download tab void FinishedTorrents::deleteFromFinishedList(QString hash){ + QMutexLocker locker(&finishedListAccess); int row = getRowFromHash(hash); if(row == -1){ std::cerr << "Error: couldn't find hash in finished list\n"; @@ -246,6 +255,7 @@ void FinishedTorrents::showProperties(const QModelIndex &index){ } void FinishedTorrents::updateFileSize(QString hash){ + QMutexLocker locker(&finishedListAccess); int row = getRowFromHash(hash); finishedListModel->setData(finishedListModel->index(row, F_SIZE), QVariant((qlonglong)BTSession->torrentEffectiveSize(hash))); } @@ -294,6 +304,7 @@ void FinishedTorrents::displayFinishedListMenu(const QPoint& pos){ */ void FinishedTorrents::sortFinishedList(int index){ + QMutexLocker locker(&finishedListAccess); static Qt::SortOrder sortOrder = Qt::AscendingOrder; if(finishedList->header()->sortIndicatorSection() == index){ if(sortOrder == Qt::AscendingOrder){ diff --git a/src/FinishedTorrents.h b/src/FinishedTorrents.h index dd8cdfdff..b7784c922 100644 --- a/src/FinishedTorrents.h +++ b/src/FinishedTorrents.h @@ -25,9 +25,13 @@ #include "ui_seeding.h" #include +#include +#include + class QStandardItemModel; class bittorrent; class FinishedListDelegate; +class FinishedListRefresher; using namespace libtorrent; @@ -40,6 +44,8 @@ class FinishedTorrents : public QWidget, public Ui::seeding{ QStringList finishedSHAs; QStandardItemModel *finishedListModel; unsigned int nbFinished; + FinishedListRefresher *refresher; + QMutex finishedListAccess; public: FinishedTorrents(QObject *parent, bittorrent *BTSession); @@ -73,4 +79,27 @@ class FinishedTorrents : public QWidget, public Ui::seeding{ }; +class FinishedListRefresher : public QThread { + private: + FinishedTorrents* parent; + bool abort; + public: + FinishedListRefresher(FinishedTorrents* parent){ + this->parent = parent; + abort = false; + } + ~FinishedListRefresher(){ + abort = true; + wait(); + } + protected: + void run(){ + forever{ + if(abort) return; + parent->updateFinishedList(); + msleep(2000); + } + } +}; + #endif diff --git a/src/GUI.cpp b/src/GUI.cpp index 5102ec668..c91c0b181 100644 --- a/src/GUI.cpp +++ b/src/GUI.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include "GUI.h" #include "misc.h" @@ -179,10 +180,6 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent){ connect(downloadList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayDLListMenu(const QPoint&))); // connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayGUIMenu(const QPoint&))); connect(infoBar, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayInfoBarMenu(const QPoint&))); - // Start download list refresher - refresher = new QTimer(this); - connect(refresher, SIGNAL(timeout()), this, SLOT(updateDlList())); - refresher->start(2000); // Use a tcp server to allow only one instance of qBittorrent tcpServer = new QTcpServer(); if (!tcpServer->listen(QHostAddress::LocalHost, 1666)) { @@ -195,6 +192,9 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent){ checkConnect->start(5000); previewProcess = new QProcess(this); connect(previewProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(cleanTempPreviewFile(int, QProcess::ExitStatus))); + // Download list refresher thread + refresher = new DownloadListRefresher(this); + refresher->start(); // Accept drag 'n drops setAcceptDrops(true); // Set info Bar infos @@ -231,6 +231,14 @@ GUI::~GUI(){ delete switchRSSShortcut; } +int GUI::getCurrentTab() const{ + if(isHidden() || isMinimized()){ + return -1; + }else{ + return tabs->currentIndex(); + } +} + void GUI::on_actionWebsite_triggered(){ QDesktopServices::openUrl(QUrl("http://www.qbittorrent.org")); } @@ -554,17 +562,14 @@ void GUI::updateDlList(bool force){ if(systrayIntegration){ myTrayIcon->setToolTip(""+tr("qBittorrent")+"
"+tr("DL speed: %1 KiB/s", "e.g: Download speed: 10 KiB/s").arg(QString(tmp2))+"
"+tr("UP speed: %1 KiB/s", "e.g: Upload speed: 10 KiB/s").arg(QString(tmp))); // tray icon } - if( !force && (isMinimized() || isHidden() || tabs->currentIndex() > 1)){ + if( !force && getCurrentTab()){ // No need to update if qBittorrent DL list is hidden return; } - if(tabs->currentIndex()){ - finishedTorrentTab->updateFinishedList(); - return; - } // qDebug("Updating download list"); LCD_UpSpeed->display(tmp); // UP LCD LCD_DownSpeed->display(tmp2); // DL LCD + QMutexLocker locker(&DLListAccess); // browse handles std::vector handles = BTSession->getTorrentHandles(); QStringList finishedSHAs = finishedTorrentTab->getFinishedSHAs(); @@ -658,6 +663,7 @@ void GUI::updateDlList(bool force){ } void GUI::restoreInDownloadList(torrent_handle h){ + QMutexLocker locker(&DLListAccess); unsigned int row = DLListModel->rowCount(); QString hash = QString(misc::toString(h.info_hash()).c_str()); // Adding torrent to download list @@ -732,6 +738,7 @@ void GUI::sortDownloadListString(int index, Qt::SortOrder sortOrder){ void GUI::sortDownloadList(int index, Qt::SortOrder startSortOrder, bool fromLoadColWidth){ qDebug("Called sort download list"); + QMutexLocker locker(&DLListAccess); static Qt::SortOrder sortOrder = startSortOrder; if(!fromLoadColWidth && downloadList->header()->sortIndicatorSection() == index){ if(sortOrder == Qt::AscendingOrder){ @@ -987,6 +994,7 @@ void GUI::on_actionOpen_triggered(){ // delete from download list AND from hard drive void GUI::on_actionDelete_Permanently_triggered(){ if(tabs->currentIndex() > 1) return; + QMutexLocker locker(&DLListAccess); QModelIndexList selectedIndexes; bool inDownloadList; if(tabs->currentIndex() == 0) { @@ -1058,6 +1066,7 @@ void GUI::on_actionDelete_Permanently_triggered(){ // delete selected items in the list void GUI::on_actionDelete_triggered(){ + QMutexLocker locker(&DLListAccess); if(tabs->currentIndex() > 1) return; QModelIndexList selectedIndexes; bool inDownloadList = true; @@ -1129,6 +1138,7 @@ void GUI::on_actionDelete_triggered(){ // Called when a torrent is added void GUI::torrentAdded(QString path, torrent_handle& h, bool fastResume){ + QMutexLocker locker(&DLListAccess); QString hash = QString(misc::toString(h.info_hash()).c_str()); if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished")){ finishedTorrentTab->addFinishedSHA(hash); @@ -1371,6 +1381,7 @@ void GUI::configureSession(bool deleteOptions){ // Pause All Downloads in DL list void GUI::on_actionPause_All_triggered(){ + QMutexLocker locker(&DLListAccess); QString fileHash; // Pause all torrents if(BTSession->pauseAllTorrents()){ @@ -1396,6 +1407,7 @@ void GUI::on_actionPause_All_triggered(){ // pause selected items in the list void GUI::on_actionPause_triggered(){ + QMutexLocker locker(&DLListAccess); QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes(); QModelIndex index; foreach(index, selectedIndexes){ @@ -1421,6 +1433,7 @@ void GUI::on_actionPause_triggered(){ // Resume All Downloads in DL list void GUI::on_actionStart_All_triggered(){ + QMutexLocker locker(&DLListAccess); QString fileHash; // Pause all torrents if(BTSession->resumeAllTorrents()){ @@ -1440,6 +1453,7 @@ void GUI::on_actionStart_All_triggered(){ // start selected items in the list void GUI::on_actionStart_triggered(){ + QMutexLocker locker(&DLListAccess); QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes(); QModelIndex index; foreach(index, selectedIndexes){ @@ -1486,6 +1500,7 @@ void GUI::on_actionTorrent_Properties_triggered(){ // called when a torrent has finished void GUI::finishedTorrent(torrent_handle& h){ + QMutexLocker locker(&DLListAccess); QSettings settings("qBittorrent", "qBittorrent"); QString fileName = QString(h.name().c_str()); int useOSD = settings.value("Options/OSDEnabled", 1).toInt(); diff --git a/src/GUI.h b/src/GUI.h index da4bef538..82e269ad7 100644 --- a/src/GUI.h +++ b/src/GUI.h @@ -23,7 +23,9 @@ #define GUI_H #include +#include #include +#include #include #include "ui_MainWindow.h" @@ -45,6 +47,7 @@ class about; class previewSelect; class options_imp; class QStandardItemModel; +class DownloadListRefresher; using namespace libtorrent; namespace fs = boost::filesystem; @@ -64,7 +67,6 @@ class GUI : public QMainWindow, private Ui::MainWindow{ // GUI related options_imp *options; createtorrent *createWindow; - QTimer *refresher; QSystemTrayIcon *myTrayIcon; QMenu *myTrayIconMenu; about *aboutdlg; @@ -77,6 +79,8 @@ class GUI : public QMainWindow, private Ui::MainWindow{ bool force_exit; bool delayedSorting; Qt::SortOrder delayedSortingOrder; + DownloadListRefresher *refresher; + QMutex DLListAccess; // Keyboard shortcuts QShortcut *createShortcut; QShortcut *openShortcut; @@ -111,7 +115,6 @@ class GUI : public QMainWindow, private Ui::MainWindow{ void toggleVisibility(QSystemTrayIcon::ActivationReason e); void on_actionAbout_triggered(); void setInfoBar(QString info, QString color="black"); - void updateDlList(bool force=false); void on_actionCreate_torrent_triggered(); void on_actionClearLog_triggered(); void on_actionWebsite_triggered(); @@ -190,6 +193,7 @@ class GUI : public QMainWindow, private Ui::MainWindow{ void setTabText(int index, QString text); void updateFileSize(QString hash); void sortProgressColumnDelayed(); + void updateDlList(bool force=false); protected: void closeEvent(QCloseEvent *); @@ -202,6 +206,30 @@ class GUI : public QMainWindow, private Ui::MainWindow{ // Methods int getRowFromHash(QString hash) const; QPoint screenCenter(); + int getCurrentTab() const; +}; + +class DownloadListRefresher : public QThread { + private: + GUI* parent; + bool abort; + public: + DownloadListRefresher(GUI* parent){ + this->parent = parent; + abort = false; + } + ~DownloadListRefresher(){ + abort = true; + wait(); + } + protected: + void run(){ + forever{ + if(abort) return; + ((GUI*)parent)->updateDlList(); + msleep(1500); + } + } }; #endif diff --git a/src/src.pro b/src/src.pro index 09eaf37aa..4302cadad 100644 --- a/src/src.pro +++ b/src/src.pro @@ -25,8 +25,8 @@ contains(DEBUG_MODE, 0){ message(Release build!) } -QMAKE_CXXFLAGS_RELEASE += -fwrapv -O2 -QMAKE_CXXFLAGS_DEBUG += -fwrapv -O2 +QMAKE_CXXFLAGS_RELEASE += -fwrapv +QMAKE_CXXFLAGS_DEBUG += -fwrapv CONFIG += link_pkgconfig PKGCONFIG += libtorrent libccext2 libccgnu2