diff --git a/TODO b/TODO index 184c79ea7..1f33925b7 100644 --- a/TODO +++ b/TODO @@ -56,31 +56,5 @@ - Recheck doc - Translations update (IN PROGRESS) -LANGUAGES UPDATED: -- French *OK* -- English *OK* -- Japanese *OK* -- Swedish *OK* -- Slovak *OK* -- Ukrainian *OK* -- Chinese (simplified) *OK* -- Hungarian *OK* -- Italian *OK* -- Polish *OK* -- Portuguese *OK* -- Brazilian *OK* -- Spanish *OK* -- German *OK* -- Russian *OK* -- Korean *OK* -- Greek *OK* -- Dutch *OK* -- Romanian *OK* -- Bulgarian *OK* - -rc1->rc2 changelog: -- BUGFIX: Fixed search engine plugins update -- BUGFIX: Fixed mininova search engine plugin -- BUGFIX: Fixed infoBar text when adding a torrent -- BUGFIX: Fixed a unsupported character in man page -- I18N: Updated Italian and Korean translations +rc2->rc3 changelog: +- BUGFIX: Fixed compilation problem on FreeBSD \ No newline at end of file diff --git a/src/bittorrent.cpp b/src/bittorrent.cpp index 981249fd7..8d9e02fb8 100644 --- a/src/bittorrent.cpp +++ b/src/bittorrent.cpp @@ -24,6 +24,11 @@ #include #include +#include "bittorrent.h" +#include "misc.h" +#include "downloadThread.h" +#include "deleteThread.h" + #include #include #include @@ -34,11 +39,6 @@ #include #include -#include "bittorrent.h" -#include "misc.h" -#include "downloadThread.h" -#include "deleteThread.h" - #define ETAS_MAX_VALUES 3 #define ETA_REFRESH_INTERVAL 10000 #define MAX_TRACKER_ERRORS 2 diff --git a/src/downloadThread.cpp b/src/downloadThread.cpp new file mode 100644 index 000000000..fea1205f8 --- /dev/null +++ b/src/downloadThread.cpp @@ -0,0 +1,173 @@ +/* + * 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. + * + * Contact : chris@qbittorrent.org + */ + +#include "downloadThread.h" +#include + +QString subDownloadThread::errorCodeToString(ost::URLStream::Error status) { + switch(status){ + case ost::URLStream::errUnreachable: + return tr("Host is unreachable"); + case ost::URLStream::errMissing: + return tr("File was not found (404)"); + case ost::URLStream::errDenied: + return tr("Connection was denied"); + case ost::URLStream::errInvalid: + return tr("Url is invalid"); + case ost::URLStream::errForbidden: + return tr("Connection forbidden (403)"); + case ost::URLStream::errUnauthorized: + return tr("Connection was not authorized (401)"); + case ost::URLStream::errRelocated: + return tr("Content has moved (301)"); + case ost::URLStream::errFailure: + return tr("Connection failure"); + case ost::URLStream::errTimeout: + return tr("Connection was timed out"); + case ost::URLStream::errInterface: + return tr("Incorrect network interface"); + default: + return tr("Unknown error"); + } +} + +subDownloadThread::subDownloadThread(QObject *parent, QString url) : QThread(parent), url(url), abort(false){ + url_stream = new ost::URLStream(); +} + +subDownloadThread::~subDownloadThread(){ + abort = true; + wait(); + delete url_stream; +} + +void subDownloadThread::run(){ + // XXX: Trick to get a unique filename + QString filePath; + QTemporaryFile *tmpfile = new QTemporaryFile(); + if (tmpfile->open()) { + filePath = tmpfile->fileName(); + } + delete tmpfile; + QFile dest_file(filePath); + if(!dest_file.open(QIODevice::WriteOnly | QIODevice::Text)){ + std::cerr << "Error: could't create temporary file: " << (const char*)filePath.toUtf8() << '\n'; + return; + } + ost::URLStream::Error status = url_stream->get((const char*)url.toUtf8()); + if(status){ + // Failure + QString error_msg = errorCodeToString(status); + qDebug("Download failed for %s, reason: %s", (const char*)url.toUtf8(), (const char*)error_msg.toUtf8()); + url_stream->close(); + emit downloadFailureST(this, url, error_msg); + return; + } + qDebug("Downloading %s...", (const char*)url.toUtf8()); + char cbuf[1024]; + int len; + while(!url_stream->eof()) { + url_stream->read(cbuf, sizeof(cbuf)); + len = url_stream->gcount(); + if(len > 0) + dest_file.write(cbuf, len); + if(abort){ + dest_file.close(); + url_stream->close(); + return; + } + } + dest_file.close(); + url_stream->close(); + emit downloadFinishedST(this, url, filePath); + qDebug("download completed here: %s", (const char*)filePath.toUtf8()); +} + +/** Download Thread **/ + +downloadThread::downloadThread(QObject* parent) : QThread(parent), abort(false){} + +downloadThread::~downloadThread(){ + mutex.lock(); + abort = true; + condition.wakeOne(); + mutex.unlock(); + qDeleteAll(subThreads); + wait(); +} + +void downloadThread::downloadUrl(QString url){ + QMutexLocker locker(&mutex); + if(downloading_list.contains(url)) return; + url_list << url; + downloading_list << url; + if(!isRunning()){ + start(); + }else{ + condition.wakeOne(); + } +} + +void downloadThread::run(){ + forever{ + if(abort) + return; + mutex.lock(); + if(url_list.size() != 0){ + QString url = url_list.takeFirst(); + mutex.unlock(); + subDownloadThread *st = new subDownloadThread(0, url); + subThreads << st; + connect(st, SIGNAL(downloadFinishedST(subDownloadThread*, QString, QString)), this, SLOT(propagateDownloadedFile(subDownloadThread*, QString, QString))); + connect(st, SIGNAL(downloadFailureST(subDownloadThread*, QString, QString)), this, SLOT(propagateDownloadFailure(subDownloadThread*, QString, QString))); + st->start(); + }else{ + condition.wait(&mutex); + mutex.unlock(); + } + } +} + +void downloadThread::propagateDownloadedFile(subDownloadThread* st, QString url, QString path){ + int index = subThreads.indexOf(st); + Q_ASSERT(index != -1); + subThreads.removeAt(index); + delete st; + emit downloadFinished(url, path); + mutex.lock(); + index = downloading_list.indexOf(url); + Q_ASSERT(index != -1); + downloading_list.removeAt(index); + mutex.unlock(); +} + +void downloadThread::propagateDownloadFailure(subDownloadThread* st, QString url, QString reason){ + int index = subThreads.indexOf(st); + Q_ASSERT(index != -1); + subThreads.removeAt(index); + delete st; + emit downloadFailure(url, reason); + mutex.lock(); + index = downloading_list.indexOf(url); + Q_ASSERT(index != -1); + downloading_list.removeAt(index); + mutex.unlock(); +} diff --git a/src/downloadThread.h b/src/downloadThread.h index 37e7095a8..0ec576ccf 100644 --- a/src/downloadThread.h +++ b/src/downloadThread.h @@ -29,55 +29,20 @@ #include #include #include -#include -#include -#ifdef CCXX_NAMESPACES -using namespace std; -using namespace ost; -#endif +#include class subDownloadThread : public QThread { Q_OBJECT private: QString url; - URLStream url_stream; + ost::URLStream *url_stream; bool abort; public: - subDownloadThread(QObject *parent, QString url) : QThread(parent), url(url), abort(false){} - - ~subDownloadThread(){ - abort = true; - wait(); - } - - static QString errorCodeToString(URLStream::Error status){ - switch(status){ - case URLStream::errUnreachable: - return tr("Host is unreachable"); - case URLStream::errMissing: - return tr("File was not found (404)"); - case URLStream::errDenied: - return tr("Connection was denied"); - case URLStream::errInvalid: - return tr("Url is invalid"); - case URLStream::errForbidden: - return tr("Connection forbidden (403)"); - case URLStream::errUnauthorized: - return tr("Connection was not authorized (401)"); - case URLStream::errRelocated: - return tr("Content has moved (301)"); - case URLStream::errFailure: - return tr("Connection failure"); - case URLStream::errTimeout: - return tr("Connection was timed out"); - case URLStream::errInterface: - return tr("Incorrect network interface"); - default: - return tr("Unknown error"); - } - } + subDownloadThread(QObject *parent, QString url); + ~subDownloadThread(); + QString errorCodeToString(ost::URLStream::Error status); signals: // For subthreads @@ -85,47 +50,7 @@ class subDownloadThread : public QThread { void downloadFailureST(subDownloadThread* st, QString url, QString reason); protected: - void run(){ - // XXX: Trick to get a unique filename - QString filePath; - QTemporaryFile *tmpfile = new QTemporaryFile(); - if (tmpfile->open()) { - filePath = tmpfile->fileName(); - } - delete tmpfile; - QFile dest_file(filePath); - if(!dest_file.open(QIODevice::WriteOnly | QIODevice::Text)){ - std::cerr << "Error: could't create temporary file: " << (const char*)filePath.toUtf8() << '\n'; - return; - } - URLStream::Error status = url_stream.get((const char*)url.toUtf8()); - if(status){ - // Failure - QString error_msg = errorCodeToString(status); - qDebug("Download failed for %s, reason: %s", (const char*)url.toUtf8(), (const char*)error_msg.toUtf8()); - url_stream.close(); - emit downloadFailureST(this, url, error_msg); - return; - } - qDebug("Downloading %s...", (const char*)url.toUtf8()); - char cbuf[1024]; - int len; - while(!url_stream.eof()) { - url_stream.read(cbuf, sizeof(cbuf)); - len = url_stream.gcount(); - if(len > 0) - dest_file.write(cbuf, len); - if(abort){ - dest_file.close(); - url_stream.close(); - return; - } - } - dest_file.close(); - url_stream.close(); - emit downloadFinishedST(this, url, filePath); - qDebug("download completed here: %s", (const char*)filePath.toUtf8()); - } + void run(); }; class downloadThread : public QThread { @@ -144,75 +69,19 @@ class downloadThread : public QThread { void downloadFailure(QString url, QString reason); public: - downloadThread(QObject* parent) : QThread(parent), abort(false){} + downloadThread(QObject* parent); - ~downloadThread(){ - mutex.lock(); - abort = true; - condition.wakeOne(); - mutex.unlock(); - qDeleteAll(subThreads); - wait(); - } + ~downloadThread(); - void downloadUrl(QString url){ - QMutexLocker locker(&mutex); - if(downloading_list.contains(url)) return; - url_list << url; - downloading_list << url; - if(!isRunning()){ - start(); - }else{ - condition.wakeOne(); - } - } + void downloadUrl(QString url); protected: - void run(){ - forever{ - if(abort) - return; - mutex.lock(); - if(url_list.size() != 0){ - QString url = url_list.takeFirst(); - mutex.unlock(); - subDownloadThread *st = new subDownloadThread(0, url); - subThreads << st; - connect(st, SIGNAL(downloadFinishedST(subDownloadThread*, QString, QString)), this, SLOT(propagateDownloadedFile(subDownloadThread*, QString, QString))); - connect(st, SIGNAL(downloadFailureST(subDownloadThread*, QString, QString)), this, SLOT(propagateDownloadFailure(subDownloadThread*, QString, QString))); - st->start(); - }else{ - condition.wait(&mutex); - mutex.unlock(); - } - } - } - protected slots: - void propagateDownloadedFile(subDownloadThread* st, QString url, QString path){ - int index = subThreads.indexOf(st); - Q_ASSERT(index != -1); - subThreads.removeAt(index); - delete st; - emit downloadFinished(url, path); - mutex.lock(); - index = downloading_list.indexOf(url); - Q_ASSERT(index != -1); - downloading_list.removeAt(index); - mutex.unlock(); - } + void run(); - void propagateDownloadFailure(subDownloadThread* st, QString url, QString reason){ - int index = subThreads.indexOf(st); - Q_ASSERT(index != -1); - subThreads.removeAt(index); - delete st; - emit downloadFailure(url, reason); - mutex.lock(); - index = downloading_list.indexOf(url); - Q_ASSERT(index != -1); - downloading_list.removeAt(index); - mutex.unlock(); - } + protected slots: + void propagateDownloadedFile(subDownloadThread* st, QString url, QString path); + + void propagateDownloadFailure(subDownloadThread* st, QString url, QString reason); }; #endif diff --git a/src/rss_imp.cpp b/src/rss_imp.cpp index 3b7d1620c..3950654e5 100644 --- a/src/rss_imp.cpp +++ b/src/rss_imp.cpp @@ -28,6 +28,7 @@ #include #include #include +#include // display a right-click menu void RSSImp::displayRSSListMenu(const QPoint& pos){ @@ -259,13 +260,13 @@ void RSSImp::updateFeedNbNews(QString url){ QTreeWidgetItem *item = getTreeItemFromUrl(url); RssStream *stream = rssmanager->getFeed(url); - item->setText(0, stream->getAliasOrUrl() + QString::fromUtf8(" (") + QString::number(stream->getNbUnRead(), 10)+ String(")")); + item->setText(0, stream->getAliasOrUrl() + QString::fromUtf8(" (") + QString::number(stream->getNbUnRead(), 10)+ QString(")")); } void RSSImp::updateFeedInfos(QString url, QString aliasOrUrl, unsigned int nbUnread){ QTreeWidgetItem *item = getTreeItemFromUrl(url); RssStream *stream = rssmanager->getFeed(url); - item->setText(0, aliasOrUrl + QString::fromUtf8(" (") + QString::number(nbUnread, 10)+ String(")")); + item->setText(0, aliasOrUrl + QString::fromUtf8(" (") + QString::number(nbUnread, 10)+ QString(")")); item->setData(0,Qt::DecorationRole, QVariant(QIcon(stream->getIconPath()))); item->setToolTip(0, QString::fromUtf8("")+tr("Description:")+QString::fromUtf8(" ")+stream->getDescription()+QString::fromUtf8("
")+tr("url:")+QString::fromUtf8(" ")+stream->getUrl()+QString::fromUtf8("
")+tr("Last refresh:")+QString::fromUtf8(" ")+stream->getLastRefreshElapsedString()); // If the feed is selected, update the displayed news diff --git a/src/src.pro b/src/src.pro index 2fca2e647..9158a8143 100644 --- a/src/src.pro +++ b/src/src.pro @@ -159,5 +159,6 @@ SOURCES += GUI.cpp \ FinishedTorrents.cpp \ qtorrenthandle.cpp \ downloadingTorrents.cpp \ - engineSelectDlg.cpp + engineSelectDlg.cpp \ + downloadThread.cpp