1
mirror of https://github.com/qbittorrent/qBittorrent synced 2025-10-09 18:32:15 +02:00

Compare commits

...

44 Commits

Author SHA1 Message Date
Christophe Dumez
2b2026e83f - Tagged v1.1.4 and v1.2.0beta6 releases 2008-09-14 10:30:27 +00:00
Christophe Dumez
9b712718bd fix typo in german translation 2008-09-02 18:55:07 +00:00
Christophe Dumez
dfe6854619 - Another fix for boost v1.36 2008-08-31 12:37:16 +00:00
Christophe Dumez
c871d3642c - Updated Changelog 2008-08-31 12:28:29 +00:00
Christophe Dumez
fcdc85453a - Compilation fix for boost v1.36
- Fixed 'start seeding after torrent creation' feature
2008-08-31 12:25:10 +00:00
Christophe Dumez
51c14e39cd Updated copyright info 2008-08-27 00:59:58 +00:00
Christophe Dumez
28626f51ad - Fixed a comment
- Added chinese traditional translation to stable branch
- bump to v1.1.3 in stable branch (updated splash screen)
- Updated changelogs
2008-08-26 07:14:38 +00:00
Christophe Dumez
25233295ba - Fixed ratio saving for seeding torrents 2008-08-26 06:45:24 +00:00
Christophe Dumez
bd6684405b - Added czech translation 2008-08-18 23:58:30 +00:00
Christophe Dumez
a8235dc413 - Progress calculation fix 2008-08-17 03:53:49 +00:00
Christophe Dumez
c2838d9b0c - Forgot to update this 2008-08-01 16:21:14 +00:00
Christophe Dumez
d6d7797064 - v1.1.1 2008-08-01 16:20:27 +00:00
Christophe Dumez
685216505c - Fixed resource file 2008-08-01 16:17:31 +00:00
Christophe Dumez
c28c55280d - Added release date 2008-08-01 14:37:03 +00:00
Christophe Dumez
f1032c4619 - Updated INSTALL file 2008-08-01 14:30:18 +00:00
Christophe Dumez
d34bfd13b3 - Updated resources files 2008-08-01 14:28:28 +00:00
Christophe Dumez
cfd6a9d734 - Removed rc 2008-08-01 14:23:39 +00:00
Christophe Dumez
c2f22d292a - Updated bulgarian and greek translations 2008-07-31 12:45:35 +00:00
Christophe Dumez
9778112b3b - Allow to download torrents from local files in WEB UI 2008-07-31 12:11:01 +00:00
Christophe Dumez
1708361bd5 - Added peerkoel to dutch translators 2008-07-29 09:58:50 +00:00
Christophe Dumez
cc04f7eec2 - Updated dutch translation 2008-07-29 09:56:32 +00:00
Christophe Dumez
395805f9e8 - Added new Russian translator's name 2008-07-29 07:48:26 +00:00
Christophe Dumez
ba5daee92f - Patch from Alexey Morsov for desktop file to satisfy freedesktop
standard
2008-07-29 07:42:45 +00:00
Christophe Dumez
bfef2b5cc0 - updated russian translation 2008-07-29 07:40:03 +00:00
Christophe Dumez
af2431afbd - Added new spanish translator's name 2008-07-28 13:24:14 +00:00
Christophe Dumez
7a1b92e467 - Updated spanish translation 2008-07-28 13:17:55 +00:00
Christophe Dumez
dc399e9ed9 - optimized downloadthreads
- fixed resizing in torrent addition dialog
2008-07-27 18:11:45 +00:00
Christophe Dumez
dad79d2cc8 - Bump to rc2 2008-07-27 16:02:58 +00:00
Christophe Dumez
b5d30d5154 - Fixed vertical alignements of menus 2008-07-27 15:58:33 +00:00
Christophe Dumez
72df85749b - Updated TODO file 2008-07-27 15:42:57 +00:00
Christophe Dumez
6c84288b09 - Updated German translation 2008-07-23 07:00:16 +00:00
Christophe Dumez
78239d6956 - Fixed building on ARM (patch from Cristian Greco) 2008-07-22 19:49:22 +00:00
Christophe Dumez
41be514dcf - Commented ASSERT due to a little string encoding bug in libtorrent 2008-07-22 14:40:01 +00:00
Christophe Dumez
855b539843 - Add missing line at the end 2008-07-19 20:04:01 +00:00
Christophe Dumez
2e72ab4973 - Fixed extented selection in search results list (Bug introduced by Tab support in search engine) 2008-07-19 19:28:57 +00:00
Christophe Dumez
ae2ad8e747 - Fixed a bug in torrent progress display 2008-07-16 21:53:34 +00:00
Christophe Dumez
42fa5ef8f3 - Updated hungarian translation 2008-07-13 21:12:16 +00:00
Christophe Dumez
9395f7316d - Updated hungarian translator's mail 2008-07-13 21:10:18 +00:00
Christophe Dumez
fa1c4050ed - Updated Korean translation 2008-07-12 21:23:27 +00:00
Christophe Dumez
565b98a94a - Updated turkish translation 2008-07-11 21:35:39 +00:00
Christophe Dumez
f58efdfefc - Bump to rc1
- Disable debug
2008-07-11 17:37:13 +00:00
Christophe Dumez
a806c27f70 - Updated Italian translation 2008-07-11 16:30:52 +00:00
Christophe Dumez
a8f82d9e12 - Updated Finnish translation 2008-07-10 18:50:34 +00:00
Christophe Dumez
fe6054307e - Moved v1.1.x to its own branch. Trunk will now be dedicated to v1.2.x 2008-07-10 18:11:26 +00:00
106 changed files with 13032 additions and 5895 deletions

View File

@@ -47,6 +47,8 @@ Translations authors:
- Bulgarian: Tsvetan & Boiko Bankov (emerge_life@users.sourceforge.net)
- Catalan: Gekko Dam Beer (gekko04@users.sourceforge.net)
- Chinese (Simplified): Guo Yue (guoyue0418@hotmail.com)
- Chinese (Traditional): Yi-Shun Wang (dnextstep@gmail.com)
- Czech: Jirka Vilim (web@tets.cz)
- Danish: Mathias Nielsen (comoneo@gmail.com)
- Dutch: Joost Schipper (heavyjoost@users.sourceforge.net)
- English: Christophe Dumez (chris@qbittorrent.org)

View File

@@ -1,4 +1,27 @@
* Unknown - Christophe Dumez <chris@qbittorrent.org> - v1.1.0
* Sun Sept 14 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.1.4
- FEATURE: DHT is no longer used as fallback only
- FEATURE: Ported WebUI to Mootools v1.2
- BUGFIX: Fixed 'start seeding after torrent creation' feature
- BUGFIX: Fixed compilation with boost v1.36
- BUGFIX: Some code optimization
- BUGFIX: Fixed memory leak in Web UI
- BUGFIX: Fixed problems with column sorting
- BUGFIX: Improved code for pausing torrents on startup
- BUGFIX: Torrent addition dialog is now disabled for downloads from WebUI
- BUGFIX: Give focus to input field in WebUI download dialog
* Tue Aug 26 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.1.3
- BUGFIX: Fixed ratio saving for seeding torrents
- I18N: Added czech and traditional chinese translations
* Sun Aug 17 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.1.2
- BUGFIX: Fixed progress calculation
- BUGFIX: Fixed finished torrent detection
* Fri Aug 01 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.1.1
- BUGFIX: Fixed bad resource file for icons
* Fri Aug 01 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.1.0
- FEATURE: Web interface to control qbittorrent (Ishan Arora)
- FEATURE: Can spoof Azureus peer id to avoid ban
- FEATURE: Allow to hide/show some columns in download and seeding lists
@@ -27,6 +50,7 @@
- COSMETIC: Display "unpaused/total_torrent" in download/upload tabs
- COSMETIC: Allow to resize RSS column
- COSMETIC: Global UP/DL speeds and ratio are displayed above tabs
- COSMETIC: Use infinity symbol for ETA when time is infinite
* Fri Apr 11 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.0.0
- FEATURE: Based on new libtorrent v0.13

View File

@@ -18,7 +18,6 @@ Dependencies:
Qt >= 4.4.0 is advised
- libtorrent-rasterbar by Arvid Norberg (>= v0.13.1 REQUIRED)
-> http://www.qbittorrent.org/download.php (advised)
-> http://www.libtorrent.net
Be careful: another library (the one used by rTorrent) uses a similar name.

51
TODO
View File

@@ -1,41 +1,6 @@
// Easy
- Translations into as many languages as possible
- Use Launchpad/Rosetta for translations once it supports TS files
See https://blueprints.launchpad.net/qbittorrent/
// Intermediate
- Port on MacOS, Windows (and create an installer for Windows) - Slow progress
- Add some transparency (menus,...), improve look / usabilty
- Skins support? (contact Mateusz)
// Harder
- Torrent scheduler ala µtorrent/Bitcomet
// Waiting for libtorrent
- Allow to prioritize torrents (may code this in qBittorrent?)
// Unsure
- Display the peers we are connected to for each torrent with infos (like flag, dl/up speeds, ...)
- Azureus spoofing to prevent ban from trackers?
- Option to shutdown computer when downloads are finished
- NAT checker/Tester
- Display hard drive space left?
- Make use of dbus on Linux for the single instance instead of socket communication?
(http://techbase.kde.org/Development/Tutorials/D-Bus/Accessing_Interfaces)
- When favicon can't be downloaded, try to parse the webpage for:
<link rel="icon" href="http://example.com/favicon.ico" type="image/vnd.microsoft.icon">
* Be careful, the link can be relative
- Improve search plugin install (choose in a list taken from plugins.qbittorrent.org)
- support zipped torrents? (useful?)
- Allow to limit the number of downloading torrents simultaneously (other are paused until a download finishes)
// in v1.2.0
- Allow user to organize the downloads into categories/folders?
// in v1.1.0
- Stop calculating ETAs when ETA column is hidden
-> See https://blueprints.launchpad.net/qbittorrent
Translations updated:
Translations updated in v1.1.0:
- French
- Chinese
- Polish
@@ -43,3 +8,15 @@ Translations updated:
- Brazilian
- Slovak
- Swedish
- Romanian
- Finnish
- Italian
- Turkish
- Korean
- Hungarian
- German
- Spanish
- Russian
- Dutch
- Bulgarian
- Greek

View File

@@ -55,7 +55,7 @@ FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : par
// Make download list header clickable for sorting
finishedList->header()->setClickable(true);
finishedList->header()->setSortIndicatorShown(true);
connect(finishedList->header(), SIGNAL(sectionPressed(int)), this, SLOT(sortFinishedList(int)));
connect(finishedList->header(), SIGNAL(sectionPressed(int)), this, SLOT(toggleFinishedListSortOrder(int)));
finishedListDelegate = new FinishedListDelegate(finishedList);
finishedList->setItemDelegate(finishedListDelegate);
connect(finishedList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFinishedListMenu(const QPoint&)));
@@ -123,6 +123,7 @@ void FinishedTorrents::addTorrent(QString hash){
// Update the number of finished torrents
++nbFinished;
emit finishedTorrentsNumberChanged(nbFinished);
sortFinishedList();
}
void FinishedTorrents::torrentAdded(QString, QTorrentHandle& h, bool) {
@@ -174,10 +175,27 @@ bool FinishedTorrents::loadColWidthFinishedList(){
for(unsigned int i=0; i<listSize; ++i){
finishedList->header()->resizeSection(i, width_list.at(i).toInt());
}
loadLastSortedColumn();
qDebug("Finished list columns width loaded");
return true;
}
void FinishedTorrents::loadLastSortedColumn() {
// Loading last sorted column
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QString sortedCol = settings.value(QString::fromUtf8("FinishedListSortedCol"), QString()).toString();
if(!sortedCol.isEmpty()) {
Qt::SortOrder sortOrder;
if(sortedCol.endsWith(QString::fromUtf8("d")))
sortOrder = Qt::DescendingOrder;
else
sortOrder = Qt::AscendingOrder;
sortedCol = sortedCol.left(sortedCol.size()-1);
int index = sortedCol.toInt();
sortFinishedList(index, sortOrder);
}
}
// Save columns width in a file to remember them
// (finished list)
void FinishedTorrents::saveColWidthFinishedList() const{
@@ -238,16 +256,13 @@ void FinishedTorrents::updateFinishedList(){
}
Q_ASSERT(row != -1);
if(h.is_paused()) continue;
if(BTSession->getTorrentsToPauseAfterChecking().indexOf(hash) != -1) {
continue;
}
if(h.state() == torrent_status::downloading || (h.state() != torrent_status::checking_files && h.state() != torrent_status::queued_for_checking && h.progress() < 1.)) {
// What are you doing here? go back to download tab!
int reponse = QMessageBox::question(this, tr("Incomplete torrent in seeding list"), tr("It appears that the state of '%1' torrent changed from 'seeding' to 'downloading'. Would you like to move it back to download list? (otherwise the torrent will simply be deleted)").arg(h.name()), QMessageBox::Yes | QMessageBox::No);
if (reponse == QMessageBox::Yes) {
qDebug("Info: a torrent was moved from finished to download tab");
deleteTorrent(hash);
BTSession->setFinishedTorrent(hash);
BTSession->setUnfinishedTorrent(hash);
emit torrentMovedFromFinishedList(hash);
}
else if (reponse == QMessageBox::No) {
@@ -394,7 +409,7 @@ void FinishedTorrents::displayFinishedListMenu(const QPoint& pos){
// Call menu
// XXX: why mapToGlobal() is not enough?
myFinishedListMenu.exec(mapToGlobal(pos)+QPoint(10,55));
myFinishedListMenu.exec(mapToGlobal(pos)+QPoint(10,59));
}
@@ -410,7 +425,7 @@ void FinishedTorrents::displayFinishedHoSMenu(const QPoint& pos){
hideshowColumn.addAction(getActionHoSCol(i));
}
// Call menu
hideshowColumn.exec(mapToGlobal(pos)+QPoint(10,55));
hideshowColumn.exec(mapToGlobal(pos)+QPoint(10,32));
}
// toggle hide/show a column
@@ -535,17 +550,36 @@ QAction* FinishedTorrents::getActionHoSCol(int index) {
* Sorting functions
*/
void FinishedTorrents::sortFinishedList(int index){
static Qt::SortOrder sortOrder = Qt::AscendingOrder;
void FinishedTorrents::toggleFinishedListSortOrder(int index) {
Qt::SortOrder sortOrder = Qt::AscendingOrder;
if(finishedList->header()->sortIndicatorSection() == index){
if(sortOrder == Qt::AscendingOrder){
sortOrder = Qt::DescendingOrder;
}else{
sortOrder = Qt::AscendingOrder;
}
sortOrder = (Qt::SortOrder)!(bool)finishedList->header()->sortIndicatorOrder();
}
finishedList->header()->setSortIndicator(index, sortOrder);
switch(index){
switch(index) {
case F_SIZE:
case F_UPSPEED:
sortFinishedListFloat(index, sortOrder);
break;
default:
sortFinishedListString(index, sortOrder);
}
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QString sortOrderLetter;
if(sortOrder == Qt::AscendingOrder)
sortOrderLetter = QString::fromUtf8("a");
else
sortOrderLetter = QString::fromUtf8("d");
settings.setValue(QString::fromUtf8("FinishedListSortedCol"), misc::toQString(index)+sortOrderLetter);
}
void FinishedTorrents::sortFinishedList(int index, Qt::SortOrder sortOrder){
if(index == -1) {
index = finishedList->header()->sortIndicatorSection();
sortOrder = finishedList->header()->sortIndicatorOrder();
} else {
finishedList->header()->setSortIndicator(index, sortOrder);
}
switch(index) {
case F_SIZE:
case F_UPSPEED:
sortFinishedListFloat(index, sortOrder);

View File

@@ -60,7 +60,9 @@ class FinishedTorrents : public QWidget, public Ui::seeding {
void displayFinishedHoSMenu(const QPoint&);
void setRowColor(int row, QString color);
void saveColWidthFinishedList() const;
void sortFinishedList(int index);
void loadLastSortedColumn();
void toggleFinishedListSortOrder(int index);
void sortFinishedList(int index=-1, Qt::SortOrder sortOrder=Qt::AscendingOrder);
void sortFinishedListFloat(int index, Qt::SortOrder sortOrder);
void sortFinishedListString(int index, Qt::SortOrder sortOrder);
void updateFileSize(QString hash);

View File

@@ -32,14 +32,13 @@
#include <QTcpServer>
#include <QTcpSocket>
#endif
#include <stdlib.h>
#include <QCloseEvent>
#include <QShortcut>
#include <QLabel>
#include <QModelIndex>
#include "GUI.h"
#include "httpserver.h"
#include "downloadingTorrents.h"
#include "misc.h"
#include "createtorrent_imp.h"
@@ -54,7 +53,7 @@
#include "options_imp.h"
#include "previewSelect.h"
#include "allocationDlg.h"
#include "stdlib.h"
#include "httpserver.h"
using namespace libtorrent;
@@ -125,7 +124,6 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
BTSession = new bittorrent();
connect(BTSession, SIGNAL(fullDiskError(QTorrentHandle&)), this, SLOT(fullDiskError(QTorrentHandle&)));
connect(BTSession, SIGNAL(finishedTorrent(QTorrentHandle&)), this, SLOT(finishedTorrent(QTorrentHandle&)));
connect(BTSession, SIGNAL(torrentFinishedChecking(QString)), this, SLOT(torrentChecked(QString)));
connect(BTSession, SIGNAL(trackerAuthenticationRequired(QTorrentHandle&)), this, SLOT(trackerAuthenticationRequired(QTorrentHandle&)));
connect(BTSession, SIGNAL(scanDirFoundTorrents(const QStringList&)), this, SLOT(processScannedFiles(const QStringList&)));
connect(BTSession, SIGNAL(newDownloadedTorrent(QString, QString)), this, SLOT(processDownloadedFiles(QString, QString)));
@@ -293,27 +291,6 @@ void GUI::writeSettings() {
settings.endGroup();
}
// Called when a torrent finished checking
void GUI::torrentChecked(QString hash) const {
// Check if the torrent was paused after checking
if(BTSession->isPaused(hash)) {
// Was paused, change its icon/color
if(BTSession->isFinished(hash)) {
// In finished list
qDebug("Automatically paused torrent was in finished list");
finishedTorrentTab->pauseTorrent(hash);
}else{
// In download list
downloadingTorrentTab->pauseTorrent(hash);
}
}
if(!BTSession->isFinished(hash)){
// Delayed Sorting
downloadingTorrentTab->updateFileSizeAndProgress(hash);
downloadingTorrentTab->sortProgressColumnDelayed();
}
}
// called when a torrent has finished
void GUI::finishedTorrent(QTorrentHandle& h) const {
qDebug("In GUI, a torrent has finished");
@@ -425,7 +402,7 @@ void GUI::acceptConnection() {
}
void GUI::readParamsOnSocket() {
if(clientConnection != 0) {
if(clientConnection) {
QByteArray params = clientConnection->readAll();
if(!params.isEmpty()) {
processParams(QString::fromUtf8(params.data()).split(QString::fromUtf8("\n")));
@@ -999,6 +976,7 @@ void GUI::configureSession(bool deleteOptions) {
sessionSettings.user_agent = "qBittorrent "VERSION;
}
sessionSettings.upnp_ignore_nonrouters = true;
sessionSettings.use_dht_as_fallback = false;
BTSession->setSessionSettings(sessionSettings);
// Bittorrent
// * Max connections limit
@@ -1369,7 +1347,6 @@ void GUI::createSystrayDelayed() {
createTrayIcon();
systrayIntegration = true;
delete systrayCreator;
systrayCreator = 0;
} else {
if(timeout) {
// Retry a bit later
@@ -1379,7 +1356,6 @@ void GUI::createSystrayDelayed() {
// Timed out, apparently system really does not
// support systray icon
delete systrayCreator;
systrayCreator = 0;
}
}
}
@@ -1444,7 +1420,6 @@ void GUI::OptionsSaved(QString info, bool deleteOptions) {
else if(httpServer)
{
delete httpServer;
httpServer = 0;
}
// Update session
configureSession(deleteOptions);
@@ -1453,11 +1428,9 @@ void GUI::OptionsSaved(QString info, bool deleteOptions) {
bool GUI::initWebUi(QString username, QString password, int port)
{
if(httpServer)
{
httpServer->close();
}
else
httpServer = new HttpServer(BTSession, 500, this);
httpServer = new HttpServer(BTSession, 1000, this);
httpServer->setAuthorization(username, password);
bool success = httpServer->listen(QHostAddress::Any, port);
if (success)

View File

@@ -24,7 +24,7 @@
#include <QProcess>
#include <QSystemTrayIcon>
#include <QPointer>
#include "ui_MainWindow.h"
#include "qtorrenthandle.h"
@@ -65,7 +65,7 @@ class GUI : public QMainWindow, private Ui::MainWindow{
QTabWidget *tabs;
options_imp *options;
QSystemTrayIcon *myTrayIcon;
QTimer *systrayCreator;
QPointer<QTimer> systrayCreator;
QMenu *myTrayIconMenu;
DownloadingTorrents *downloadingTorrentTab;
FinishedTorrents *finishedTorrentTab;
@@ -86,7 +86,7 @@ class GUI : public QMainWindow, private Ui::MainWindow{
// RSS
RSSImp *rssWidget;
// Web UI
HttpServer *httpServer;
QPointer<HttpServer> httpServer;
// Misc
#ifdef QT_4_4
QLocalServer *localServer;
@@ -150,7 +150,6 @@ class GUI : public QMainWindow, private Ui::MainWindow{
void deleteTorrent(QString hash);
void deleteRatioTorrent(QString fileName);
void finishedTorrent(QTorrentHandle& h) const;
void torrentChecked(QString hash) const;
void updateLists();
bool initWebUi(QString username, QString password, int port);
void pauseTorrent(QString hash);

BIN
src/Icons/flags/czech.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

BIN
src/Icons/flags/taiwan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 B

View File

@@ -1,7 +1,7 @@
[Desktop Entry]
Categories=Qt;Application;Network;P2P
Comment=V1.1.0
Exec=qbittorrent
Categories=Qt;Network;P2P
Comment=V1.1.4
Exec=qbittorrent %f
GenericName=Bittorrent client
GenericName[bg]=Торент клиент
GenericName[de]=Bittorren Client
@@ -19,7 +19,7 @@ GenericName[tr]=Bittorrent istemcisi
GenericName[uk]=Bittorrent-клієнт
GenericName[zh]=Bittorrent之用户
Icon=qbittorrent
MimeType=application/x-bittorrent
MimeType=application/x-bittorrent;
Name=qBittorrent
Name[ko]=큐비토런트
Terminal=false

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 75 KiB

View File

@@ -41,6 +41,7 @@ SearchTab::SearchTab(SearchEngine *parent) : QWidget()
box=new QVBoxLayout();
results_lbl=new QLabel();
resultsBrowser = new QTreeView();
resultsBrowser->setSelectionMode(QAbstractItemView::ExtendedSelection);
box->addWidget(results_lbl);
box->addWidget(resultsBrowser);
@@ -185,4 +186,5 @@ bool SearchTab::loadColWidthSearchList(){
}
qDebug("Search list columns width loaded");
return true;
}
}

View File

@@ -57,12 +57,14 @@ class about : public QDialog, private Ui::AboutDlg{
- <u>Bulgarian:</u> Tsvetan & Boiko Bankov (emerge_life@users.sourceforge.net)<br>\
- <u>Catalan:</u> Gekko Dam Beer (gekko04@users.sourceforge.net)<br>\
- <u>Chinese (Simplified):</u> Guo Yue (guoyue0418@hotmail.com)<br>\
- <u>Chinese (Traditional):</u> Yi-Shun Wang (dnextstep@gmail.com)<br>\
- <u>Czech:</u> Jirka Vilim (web@tets.cz)<br>\
- <u>Danish:</u> Mathias Nielsen (comoneo@gmail.com)<br>\
- <u>Dutch:</u> Joost Schipper (heavyjoost@users.sourceforge.net)<br>\
- <u>Dutch:</u> Joost Schipper (heavyjoost@users.sourceforge.net) and Peter Koeleman (peter@peerweb.nl)<br>\
- <u>Finnish:</u> Niklas Laxström (nikerabbit@users.sourceforge.net)<br>\
- <u>German:</u> Niels Hoffmann (zentralmaschine@users.sourceforge.net)<br>\
- <u>Greek:</u> Tsvetan Bankov (emerge_life@users.sourceforge.net)<br>\
- <u>Hungarian:</u> Majoros Péter (majoros.j.p@t-online.hu)<br>\
- <u>Hungarian:</u> Majoros Péter (majoros.peterj@gmail.com)<br>\
- <u>Italian:</u> Mirko Ferrari (mirkoferrari@gmail.com) and Ferraro Luciano (luciano.ferraro@gmail.com)<br>\
- <u>Japanese:</u> Nardog (nardog@e2umail.com)<br>\
- <u>Korean:</u> Jin Woo Sin (jin828sin@users.sourceforge.net)<br>\
@@ -70,9 +72,9 @@ class about : public QDialog, private Ui::AboutDlg{
- <u>Polish:</u> Jarek Smieja (ajep9691@wp.pl)<br>\
- <u>Portuguese:</u> Nick Marinho (nickmarinho@gmail.com)<br>\
- <u>Romanian:</u> Obada Denis (obadadenis@users.sourceforge.net)<br>\
- <u>Russian:</u> Nick Khazov (m2k3d0n at users.sourceforge.net)<br>\
- <u>Russian:</u> Nick Khazov (m2k3d0n@users.sourceforge.net) and Alexey Morsov (samurai@ricom.ru)<br>\
- <u>Slovak:</u> helix84<br>\
- <u>Spanish:</u> Vicente Raul Plata Fonseca (silverxnt@users.sourceforge.net)<br>\
- <u>Spanish:</u> Vicente Raul Plata Fonseca (silverxnt@users.sourceforge.net) and Gabriel de Oliveira (deadloop@hotmail.com)<br>\
- <u>Swedish:</u> Daniel Nylander (po@danielnylander.se)<br>\
- <u>Turkish:</u> Erdem Bingöl (erdem84@gmail.com)<br>\
- <u>Ukrainian:</u> Andrey Shpachenko (masterfix@users.sourceforge.net)<br><br>"));

View File

@@ -234,7 +234,7 @@ class arborescence {
void addFile(QString path, size_type file_size, int index, float progress=0., int priority=1) {
Q_ASSERT(root->isDir());
path = QDir::cleanPath(path);
Q_ASSERT(path.startsWith(root->path()));
//Q_ASSERT(path.startsWith(root->path()));
QString relative_path = path.remove(0, root->path().size());
if(relative_path.at(0) ==QDir::separator())
relative_path.remove(0, 1);

View File

@@ -93,9 +93,9 @@ bittorrent::~bittorrent() {
delete deleter;
delete fastResumeSaver;
delete timerAlerts;
if(BigRatioTimer != 0)
if(BigRatioTimer)
delete BigRatioTimer;
if(filterParser != 0)
if(filterParser)
delete filterParser;
delete downloader;
// Delete BT session
@@ -206,8 +206,6 @@ bool bittorrent::isPaused(QString hash) const{
qDebug("/!\\ Error: Invalid handle");
return true;
}
if(torrentsToPauseAfterChecking.contains(hash))
return true;
return h.is_paused();
}
@@ -380,11 +378,6 @@ bool bittorrent::resumeTorrent(QString hash) {
// Delete .paused file
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".paused"))
QFile::remove(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".paused");
int index = torrentsToPauseAfterChecking.indexOf(hash);
if(index != -1) {
torrentsToPauseAfterChecking.removeAt(index);
success = true;
}
return success;
}
@@ -432,7 +425,7 @@ void bittorrent::loadWebSeeds(QString hash) {
}
// Add a torrent to the bittorrent session
void bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url, bool resumed) {
void bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url, bool) {
QTorrentHandle h;
entry resume_data;
bool fastResume=false;
@@ -543,18 +536,15 @@ void bittorrent::addTorrent(QString path, bool fromScanDir, QString from_url, bo
// Copy it to torrentBackup directory
QFile::copy(file, newFile);
}
// Pause torrent if it was paused last time
if((!resumed && addInPause) || QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".paused")) {
torrentsToPauseAfterChecking << hash;
qDebug("Adding a torrent to the torrentsToPauseAfterChecking list");
}
// Incremental download
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".incremental")) {
qDebug("Incremental download enabled for %s", t->name().c_str());
h.set_sequenced_download_threshold(1);
}
// Start torrent because it was added in paused state
h.resume();
if(!addInPause && !QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".paused")) {
// Start torrent because it was added in paused state
h.resume();
}
if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished")) {
finishedTorrents << hash;
}else{
@@ -865,6 +855,14 @@ void bittorrent::loadDownloadUploadForTorrent(QString hash) {
ratioData[hash] = downUp;
}
float bittorrent::getUncheckedTorrentProgress(QString hash) const {
/*if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished"))
return 1.;*/
QTorrentHandle h = getTorrentHandle(hash);
QPair<size_type,size_type> downUpInfo = ratioData.value(hash, QPair<size_type,size_type>(0,0));
return (float)downUpInfo.first / (float)h.actual_size();
}
float bittorrent::getRealRatio(QString hash) const{
QPair<size_type,size_type> downUpInfo = ratioData.value(hash, QPair<size_type,size_type>(0,0));
size_type download = downUpInfo.first;
@@ -933,6 +931,19 @@ void bittorrent::saveFastResumeAndRatioData() {
}
saveFastResumeAndRatioData(hash);
}
hashes = getFinishedTorrents();
foreach(hash, hashes) {
QTorrentHandle h = getTorrentHandle(hash);
if(!h.is_valid()) {
qDebug("/!\\ Error: Invalid handle");
continue;
}
if(h.is_paused()) {
// Do not need to save ratio data for paused torrents
continue;
}
saveDownloadUploadForTorrent(hash);
}
}
void bittorrent::saveFastResumeAndRatioData(QString hash) {
@@ -1032,7 +1043,7 @@ void bittorrent::disableDirectoryScanning() {
timerScan->stop();
}
}
if(timerScan != 0)
if(timerScan)
delete timerScan;
}
@@ -1092,7 +1103,6 @@ void bittorrent::setDeleteRatio(float ratio) {
} else {
if(max_ratio != -1 && ratio == -1) {
delete BigRatioTimer;
BigRatioTimer = 0;
}
}
if(max_ratio != ratio) {
@@ -1117,7 +1127,7 @@ bool bittorrent::loadTrackerFile(QString hash) {
t.tier = parts[1].toInt();
trackers.push_back(t);
}
if(trackers.size() != 0) {
if(!trackers.empty()) {
QTorrentHandle h = getTorrentHandle(hash);
h.replace_trackers(trackers);
h.force_reannounce();
@@ -1278,18 +1288,12 @@ void bittorrent::readAlerts() {
if(h.is_valid()){
QString hash = h.hash();
qDebug("%s have just finished checking", hash.toUtf8().data());
int index = torrentsToPauseAfterChecking.indexOf(hash);
if(index != -1) {
torrentsToPauseAfterChecking.removeAt(index);
// Pause torrent
pauseTorrent(hash);
qDebug("%s was paused after checking", hash.toUtf8().data());
} else {
if(!h.is_paused()) {
// Save Addition DateTime
TorrentsStartTime[hash] = QDateTime::currentDateTime();
TorrentsStartData[hash] = h.total_payload_download();
}
emit torrentFinishedChecking(hash);
}
//emit torrentFinishedChecking(hash);
}
}
a = s->pop_alert();
@@ -1300,10 +1304,6 @@ QHash<QString, QString> bittorrent::getTrackersErrors(QString hash) const{
return trackersErrors.value(hash, QHash<QString, QString>());
}
QStringList bittorrent::getTorrentsToPauseAfterChecking() const{
return torrentsToPauseAfterChecking;
}
// Reload a torrent with full allocation mode
void bittorrent::reloadTorrent(const QTorrentHandle &h, bool full_alloc) {
qDebug("** Reloading a torrent");
@@ -1414,10 +1414,23 @@ void bittorrent::downloadFromUrl(QString url) {
downloader->downloadUrl(url);
}
void bittorrent::downloadUrlAndSkipDialog(QString url) {
emit aboutToDownloadFromUrl(url);
url_skippingDlg << url;
// Launch downloader thread
downloader->downloadUrl(url);
}
// Add to bittorrent session the downloaded torrent file
void bittorrent::processDownloadedFile(QString url, QString file_path) {
// Add file to torrent download list
emit newDownloadedTorrent(file_path, url);
int index = url_skippingDlg.indexOf(url);
if(index < 0) {
// Add file to torrent download list
emit newDownloadedTorrent(file_path, url);
} else {
url_skippingDlg.removeAt(index);
addTorrent(file_path, false, url, false);
}
}
void bittorrent::downloadFromURLList(const QStringList& url_list) {

View File

@@ -26,6 +26,7 @@
#include <QPair>
#include <QStringList>
#include <QDateTime>
#include <QPointer>
#include <libtorrent/session.hpp>
#include <libtorrent/ip_filter.hpp>
@@ -44,14 +45,13 @@ class bittorrent : public QObject{
private:
session *s;
QString scan_dir;
QTimer *timerScan;
QPointer<QTimer> timerScan;
QTimer *timerAlerts;
QTimer *fastResumeSaver;
QTimer *BigRatioTimer;
QPointer<QTimer> BigRatioTimer;
bool DHTEnabled;
downloadThread *downloader;
QString defaultSavePath;
QStringList torrentsToPauseAfterChecking;
QHash<QString, QDateTime> TorrentsStartTime;
QHash<QString, size_type> TorrentsStartData;
QHash<QString, QPair<size_type,size_type> > ratioData;
@@ -67,9 +67,10 @@ class bittorrent : public QObject{
bool UPnPEnabled;
bool NATPMPEnabled;
bool LSDEnabled;
FilterParserThread *filterParser;
QPointer<FilterParserThread> filterParser;
QString filterPath;
int folderScanInterval; // in seconds
QStringList url_skippingDlg;
protected:
QString getSavePath(QString hash);
@@ -86,7 +87,6 @@ class bittorrent : public QObject{
float getPayloadUploadRate() const;
session_status getSessionStatus() const;
int getListenPort() const;
QStringList getTorrentsToPauseAfterChecking() const;
qlonglong getETA(QString hash) const;
float getRealRatio(QString hash) const;
session* getSession() const;
@@ -97,6 +97,7 @@ class bittorrent : public QObject{
bool has_filtered_files(QString hash) const;
unsigned int getFinishedPausedTorrentsNb() const;
unsigned int getUnfinishedPausedTorrentsNb() const;
float getUncheckedTorrentProgress(QString hash) const;
public slots:
void addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false);
@@ -123,6 +124,7 @@ class bittorrent : public QObject{
void loadDownloadUploadForTorrent(QString hash);
void handleDownloadFailure(QString url, QString reason);
void loadWebSeeds(QString fileHash);
void downloadUrlAndSkipDialog(QString);
// Session configuration - Setters
void setListeningPortsRange(std::pair<unsigned short, unsigned short> ports);
void setMaxConnections(int maxConnec);
@@ -178,7 +180,7 @@ class bittorrent : public QObject{
void downloadFromUrlFailure(QString url, QString reason);
void fastResumeDataRejected(QString name);
void urlSeedProblem(QString url, QString msg);
void torrentFinishedChecking(QString hash);
//void torrentFinishedChecking(QString hash);
void torrent_ratio_deleted(QString fileName);
void UPnPError(QString msg);
void UPnPSuccess(QString msg);

View File

@@ -45,7 +45,7 @@ createtorrent::createtorrent(QWidget *parent): QDialog(parent){
setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
creatorThread = new torrentCreatorThread();
connect(creatorThread, SIGNAL(creationSuccess(QString)), this, SLOT(handleCreationSucess(QString)));
connect(creatorThread, SIGNAL(creationSuccess(QString, const char*, QString)), this, SLOT(handleCreationSuccess(QString, const char*, QString)));
connect(creatorThread, SIGNAL(creationFailure(QString)), this, SLOT(handleCreationFailure(QString)));
connect(creatorThread, SIGNAL(updateProgress(int)), this, SLOT(updateProgressBar(int)));
show();
@@ -129,12 +129,23 @@ void createtorrent::on_addURLSeed_button_clicked(){
// Subfunction to add files to a torrent_info structure
// Written by Arvid Norberg (libtorrent Author)
void add_files(torrent_info& t, path const& p, path const& l){
qDebug("p: %s, l: %s, l.leaf(): %s", p.string().c_str(), l.string().c_str(), l.leaf().c_str());
using boost::filesystem::path;
using boost::filesystem::directory_iterator;
#if BOOST_VERSION < 103600
std::string const& leaf = l.leaf();
#else
std::string const& leaf = l.filename();
#endif
if (leaf == ".." || leaf == ".") return;
path f(p / l);
if (is_directory(f)){
if (is_directory(f)) {
for (directory_iterator i(f), end; i != end; ++i)
#if BOOST_VERSION < 103600
add_files(t, p, l / i->leaf());
}else{
#else
add_files(t, p, l / i->filename());
#endif
} else {
qDebug("Adding %s", l.string().c_str());
t.add_file(l, file_size(f));
}
@@ -221,7 +232,11 @@ void torrentCreatorThread::run() {
ofstream out(complete(path((const char*)save_path.toUtf8())), std::ios_base::binary);
// Adding files to the torrent
path full_path = complete(path(input_path.toUtf8().data()));
#if BOOST_VERSION < 103600
add_files(*t, full_path.branch_path(), full_path.leaf());
#else
add_files(*t, full_path.branch_path(), full_path.filename());
#endif
if(abort) return;
// Set piece size
t->set_piece_size(piece_size);

View File

@@ -35,27 +35,30 @@ class subDeleteThread : public QThread {
private:
QString save_path;
arborescence *arb;
bool abort;
public:
subDeleteThread(QObject *parent, QString saveDir, arborescence *arb) : QThread(parent), save_path(saveDir), arb(arb), abort(false){}
subDeleteThread(QObject *parent, QString saveDir, arborescence *_arb) : QThread(parent), save_path(saveDir) {
arb = _arb;
}
~subDeleteThread(){
abort = true;
wait();
qDebug("subDeleteThread successfuly deleted");
//wait();
}
signals:
// For subthreads
void deletionSuccessST(subDeleteThread* st);
void deletionFailureST(subDeleteThread* st);
//void deletionFailureST(subDeleteThread* st);
protected:
void run(){
if(arb->removeFromFS(save_path))
/*if(arb->removeFromFS(save_path))
emit deletionSuccessST(this);
else
emit deletionFailureST(this);
emit deletionFailureST(this);*/
arb->removeFromFS(save_path);
emit deletionSuccessST(this);
delete arb;
}
};
@@ -99,13 +102,13 @@ class deleteThread : public QThread {
if(abort)
return;
mutex.lock();
if(torrents_list.size() != 0){
if(!torrents_list.empty()){
QPair<QString, arborescence *> torrent = torrents_list.takeFirst();
mutex.unlock();
subDeleteThread *st = new subDeleteThread(0, torrent.first, torrent.second);
subThreads << st;
connect(st, SIGNAL(deletionSuccessST(subDeleteThread*)), this, SLOT(deleteSubThread(subDeleteThread*)));
connect(st, SIGNAL(deletionFailureST(subDeleteThread*)), this, SLOT(deleteSubThread(subDeleteThread*)));
//connect(st, SIGNAL(deletionFailureST(subDeleteThread*)), this, SLOT(deleteSubThread(subDeleteThread*)));
st->start();
}else{
condition.wait(&mutex);

View File

@@ -24,6 +24,8 @@
#include <QSettings>
#include <stdio.h>
#define MAX_THREADS 3
// http://curl.rtin.bz/libcurl/c/libcurl-errors.html
QString subDownloadThread::errorCodeToString(CURLcode status) {
switch(status){
@@ -150,9 +152,7 @@ downloadThread::~downloadThread(){
void downloadThread::downloadUrl(QString url){
QMutexLocker locker(&mutex);
if(downloading_list.contains(url)) return;
url_list << url;
downloading_list << url;
urls_queue.enqueue(url);
if(!isRunning()){
start();
}else{
@@ -165,8 +165,8 @@ void downloadThread::run(){
if(abort)
return;
mutex.lock();
if(url_list.size() != 0){
QString url = url_list.takeFirst();
if(!urls_queue.empty() && subThreads.size() < MAX_THREADS){
QString url = urls_queue.dequeue();
mutex.unlock();
subDownloadThread *st = new subDownloadThread(0, url);
subThreads << st;
@@ -187,9 +187,9 @@ void downloadThread::propagateDownloadedFile(subDownloadThread* st, QString url,
delete st;
emit downloadFinished(url, path);
mutex.lock();
index = downloading_list.indexOf(url);
Q_ASSERT(index != -1);
downloading_list.removeAt(index);
if(!urls_queue.empty()) {
condition.wakeOne();
}
mutex.unlock();
}
@@ -200,8 +200,8 @@ void downloadThread::propagateDownloadFailure(subDownloadThread* st, QString url
delete st;
emit downloadFailure(url, reason);
mutex.lock();
index = downloading_list.indexOf(url);
Q_ASSERT(index != -1);
downloading_list.removeAt(index);
if(!urls_queue.empty()) {
condition.wakeOne();
}
mutex.unlock();
}

View File

@@ -30,6 +30,7 @@
#include <QWaitCondition>
#include <QStringList>
#include <curl/curl.h>
#include <QQueue>
class subDownloadThread : public QThread {
Q_OBJECT
@@ -55,8 +56,7 @@ class downloadThread : public QThread {
Q_OBJECT
private:
QStringList url_list;
QStringList downloading_list;
QQueue<QString> urls_queue;
QMutex mutex;
QWaitCondition condition;
bool abort;

View File

@@ -33,7 +33,7 @@
#include <QTime>
#include <QMenu>
DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession) : parent(parent), BTSession(BTSession), delayedSorting(false), nbTorrents(0) {
DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession) : parent(parent), BTSession(BTSession), nbTorrents(0) {
setupUi(this);
// Setting icons
actionStart->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/play.png")));
@@ -85,7 +85,7 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
downloadList->header()->setSortIndicatorShown(true);
// Connecting Actions to slots
connect(downloadList, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(notifyTorrentDoubleClicked(const QModelIndex&)));
connect(downloadList->header(), SIGNAL(sectionPressed(int)), this, SLOT(sortDownloadList(int)));
connect(downloadList->header(), SIGNAL(sectionPressed(int)), this, SLOT(toggleDownloadListSortOrder(int)));
connect(downloadList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayDLListMenu(const QPoint&)));
downloadList->header()->setContextMenuPolicy(Qt::CustomContextMenu);
connect(downloadList->header(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayDLHoSMenu(const QPoint&)));
@@ -153,7 +153,7 @@ void DownloadingTorrents::pauseTorrent(QString hash) {
DLListModel->setData(DLListModel->index(row, NAME), QIcon(QString::fromUtf8(":/Icons/skin/paused.png")), Qt::DecorationRole);
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(QString::fromUtf8("0/0")));
QTorrentHandle h = BTSession->getTorrentHandle(hash);
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
//DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
setRowColor(row, QString::fromUtf8("red"));
}
@@ -311,7 +311,7 @@ void DownloadingTorrents::displayDLListMenu(const QPoint& pos) {
myDLLlistMenu.addAction(actionBuy_it);
// Call menu
// XXX: why mapToGlobal() is not enough?
myDLLlistMenu.exec(mapToGlobal(pos)+QPoint(10,60));
myDLLlistMenu.exec(mapToGlobal(pos)+QPoint(10,35));
}
@@ -327,7 +327,7 @@ void DownloadingTorrents::displayDLHoSMenu(const QPoint& pos){
hideshowColumn.addAction(getActionHoSCol(i));
}
// Call menu
hideshowColumn.exec(mapToGlobal(pos)+QPoint(10,55));
hideshowColumn.exec(mapToGlobal(pos)+QPoint(10,10));
}
// toggle hide/show a column
@@ -496,13 +496,6 @@ void DownloadingTorrents::displayInfoBarMenu(const QPoint& pos) {
myLogMenu.exec(mapToGlobal(pos)+QPoint(44,305));
}
void DownloadingTorrents::sortProgressColumnDelayed() {
if(delayedSorting) {
sortDownloadListFloat(PROGRESS, delayedSortingOrder);
qDebug("Delayed sorting of progress column");
}
}
// get information from torrent handles and
// update download list accordingly
void DownloadingTorrents::updateDlList() {
@@ -526,12 +519,6 @@ void DownloadingTorrents::updateDlList() {
Q_ASSERT(row != -1);
// No need to update a paused torrent
if(h.is_paused()) continue;
if(BTSession->getTorrentsToPauseAfterChecking().indexOf(hash) != -1) {
if(!downloadList->isColumnHidden(PROGRESS)) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
}
continue;
}
// Parse download state
// Setting download state
switch(h.state()) {
@@ -636,6 +623,7 @@ void DownloadingTorrents::addTorrent(QString hash) {
DLListModel->setData(DLListModel->index(row, HASH), QVariant(hash));
// Pause torrent if it was paused last time
if(BTSession->isPaused(hash)) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)BTSession->getUncheckedTorrentProgress(hash)));
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/paused.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("red"));
}else{
@@ -644,6 +632,7 @@ void DownloadingTorrents::addTorrent(QString hash) {
}
++nbTorrents;
emit unfinishedTorrentsNumberChanged(nbTorrents);
sortDownloadList();
}
void DownloadingTorrents::sortDownloadListFloat(int index, Qt::SortOrder sortOrder) {
@@ -692,27 +681,36 @@ void DownloadingTorrents::sortDownloadListString(int index, Qt::SortOrder sortOr
DLListModel->removeRows(0, nbRows_old);
}
void DownloadingTorrents::sortDownloadList(int index, Qt::SortOrder startSortOrder, bool fromLoadColWidth) {
qDebug("Called sort download list");
static Qt::SortOrder sortOrder = startSortOrder;
if(!fromLoadColWidth && downloadList->header()->sortIndicatorSection() == index) {
if(sortOrder == Qt::AscendingOrder) {
sortOrder = Qt::DescendingOrder;
}else{
sortOrder = Qt::AscendingOrder;
}
void DownloadingTorrents::toggleDownloadListSortOrder(int index) {
Qt::SortOrder sortOrder = Qt::AscendingOrder;
qDebug("Toggling column sort order");
if(downloadList->header()->sortIndicatorSection() == index) {
sortOrder = (Qt::SortOrder)!(bool)downloadList->header()->sortIndicatorOrder();
}
switch(index) {
case SIZE:
case ETA:
case UPSPEED:
case DLSPEED:
case PROGRESS:
sortDownloadListFloat(index, sortOrder);
break;
default:
sortDownloadListString(index, sortOrder);
}
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QString sortOrderLetter;
if(sortOrder == Qt::AscendingOrder)
sortOrderLetter = QString::fromUtf8("a");
else
sortOrderLetter = QString::fromUtf8("d");
if(fromLoadColWidth) {
// XXX: Why is this needed?
if(sortOrder == Qt::DescendingOrder)
downloadList->header()->setSortIndicator(index, Qt::AscendingOrder);
else
downloadList->header()->setSortIndicator(index, Qt::DescendingOrder);
settings.setValue(QString::fromUtf8("DownloadListSortedCol"), misc::toQString(index)+sortOrderLetter);
}
void DownloadingTorrents::sortDownloadList(int index, Qt::SortOrder sortOrder) {
if(index == -1) {
index = downloadList->header()->sortIndicatorSection();
sortOrder = downloadList->header()->sortIndicatorOrder();
} else {
downloadList->header()->setSortIndicator(index, sortOrder);
}
@@ -721,23 +719,12 @@ void DownloadingTorrents::sortDownloadList(int index, Qt::SortOrder startSortOrd
case ETA:
case UPSPEED:
case DLSPEED:
sortDownloadListFloat(index, sortOrder);
break;
case PROGRESS:
if(fromLoadColWidth) {
// Progress sorting must be delayed until files are checked (on startup)
delayedSorting = true;
qDebug("Delayed sorting of the progress column");
delayedSortingOrder = sortOrder;
}else{
sortDownloadListFloat(index, sortOrder);
}
sortDownloadListFloat(index, sortOrder);
break;
default:
sortDownloadListString(index, sortOrder);
}
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
settings.setValue(QString::fromUtf8("DownloadListSortedCol"), misc::toQString(index)+sortOrderLetter);
}
// Save columns width in a file to remember them
@@ -786,7 +773,14 @@ bool DownloadingTorrents::loadColWidthDLList() {
for(unsigned int i=0; i<listSize; ++i) {
downloadList->header()->resizeSection(i, width_list.at(i).toInt());
}
loadLastSortedColumn();
qDebug("Download list columns width loaded");
return true;
}
void DownloadingTorrents::loadLastSortedColumn() {
// Loading last sorted column
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QString sortedCol = settings.value(QString::fromUtf8("DownloadListSortedCol"), QString()).toString();
if(!sortedCol.isEmpty()) {
Qt::SortOrder sortOrder;
@@ -796,10 +790,8 @@ bool DownloadingTorrents::loadColWidthDLList() {
sortOrder = Qt::AscendingOrder;
sortedCol = sortedCol.left(sortedCol.size()-1);
int index = sortedCol.toInt();
sortDownloadList(index, sortOrder, true);
sortDownloadList(index, sortOrder);
}
qDebug("Download list columns width loaded");
return true;
}
// Called when a torrent is added
@@ -822,6 +814,7 @@ void DownloadingTorrents::torrentAdded(QString path, QTorrentHandle& h, bool fas
// Pause torrent if it was paused last time
// Not using isPaused function because torrents are paused after checking now
if(QFile::exists(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".paused"))) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)BTSession->getUncheckedTorrentProgress(hash)));
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/paused.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("red"));
}else{
@@ -835,6 +828,7 @@ void DownloadingTorrents::torrentAdded(QString path, QTorrentHandle& h, bool fas
}
++nbTorrents;
emit unfinishedTorrentsNumberChanged(nbTorrents);
sortDownloadList();
}
// Called when trying to add a duplicate torrent
@@ -852,7 +846,7 @@ void DownloadingTorrents::updateFileSizeAndProgress(QString hash) {
Q_ASSERT(row != -1);
QTorrentHandle h = BTSession->getTorrentHandle(hash);
DLListModel->setData(DLListModel->index(row, SIZE), QVariant((qlonglong)h.actual_size()));
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
//DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
}
// Called when we couldn't listen on any port

View File

@@ -38,9 +38,7 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
bittorrent *BTSession;
DLListDelegate *DLDelegate;
QStandardItemModel *DLListModel;
bool delayedSorting;
unsigned int nbTorrents;
Qt::SortOrder delayedSortingOrder;
void hideOrShowColumn(int index);
bool loadHiddenColumns();
void saveHiddenColumns();
@@ -73,7 +71,8 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
void on_actionClearLog_triggered();
void displayInfoBarMenu(const QPoint& pos);
void addTorrent(QString hash);
void sortDownloadList(int index, Qt::SortOrder startSortOrder=Qt::AscendingOrder, bool fromLoadColWidth=false);
void sortDownloadList(int index=-1, Qt::SortOrder startSortOrder=Qt::AscendingOrder);
void toggleDownloadListSortOrder(int index);
void sortDownloadListFloat(int index, Qt::SortOrder sortOrder);
void sortDownloadListString(int index, Qt::SortOrder sortOrder);
void saveColWidthDLList() const;
@@ -94,6 +93,7 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
void hideOrShowColumnEta();
void displayUPnPError(QString msg);
void displayUPnPSuccess(QString msg);
void loadLastSortedColumn();
public slots:
void updateDlList();
@@ -103,7 +103,6 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
void deleteTorrent(QString hash);
void setBottomTabEnabled(unsigned int index, bool b);
void propertiesSelection();
void sortProgressColumnDelayed();
void updateFileSizeAndProgress(QString hash);
void showPropertiesFromHash(QString hash);

View File

@@ -31,11 +31,11 @@ EventManager::EventManager(QObject *parent)
void EventManager::update(QVariantMap event)
{
revision++;
++revision;
events << QPair<ulong, QVariantMap>(revision, event);
emit updated();
qDebug("Added the following event");
qDebug() << event;
//qDebug("Added the following event");
//qDebug() << event;
/* QLinkedList<QPair<ulong, QVariantMap> >::iterator i;
for (i = events.begin(); i != events.end(); i++)
qDebug() << *i;*/

View File

@@ -30,6 +30,7 @@
#include <QHttpResponseHeader>
#include <QFile>
#include <QDebug>
#include <QTemporaryFile>
HttpConnection::HttpConnection(QTcpSocket *socket, HttpServer *parent)
: QObject(parent), socket(socket), parent(parent)
@@ -41,15 +42,31 @@ HttpConnection::HttpConnection(QTcpSocket *socket, HttpServer *parent)
HttpConnection::~HttpConnection()
{
delete socket;
}
void HttpConnection::processDownloadedFile(QString url, QString file_path) {
qDebug("URL %s successfully downloaded !", (const char*)url.toUtf8());
emit torrentReadyToBeDownloaded(file_path, false, url, false);
}
void HttpConnection::handleDownloadFailure(QString url, QString reason) {
std::cerr << "Could not download " << (const char*)url.toUtf8() << ", reason: " << (const char*)reason.toUtf8() << "\n";
}
void HttpConnection::read()
{
QString input = socket->readAll();
qDebug(" -------");
QByteArray input = socket->readAll();
/*qDebug(" -------");
qDebug("|REQUEST|");
qDebug(" -------");
qDebug("%s", input.toAscii().constData());
qDebug(" -------"); */
//qDebug("%s", input.toAscii().constData());
if(input.size() > 100000) {
qDebug("Request too big");
generator.setStatusLine(400, "Bad Request");
write();
return;
}
parser.write(input);
if(parser.isError())
{
@@ -74,6 +91,7 @@ void HttpConnection::write()
void HttpConnection::respond()
{
//qDebug("Respond called");
QStringList auth = parser.value("Authorization").split(" ", QString::SkipEmptyParts);
if (auth.size() != 2 || QString::compare(auth[0], "Basic", Qt::CaseInsensitive) != 0 || !parent->isAuthorized(auth[1].toUtf8()))
{
@@ -164,16 +182,32 @@ void HttpConnection::respondCommand(QString command)
{
QString urls = parser.post("urls");
QStringList list = urls.split('\n');
QStringList url_list_cleaned;
foreach(QString url, list){
url = url.trimmed();
if(!url.isEmpty()){
if(url_list_cleaned.indexOf(QRegExp(url, Qt::CaseInsensitive, QRegExp::FixedString)) < 0){
url_list_cleaned << url;
}
qDebug("Downloading url: %s", (const char*)url.toUtf8());
emit UrlReadyToBeDownloaded(url);
}
}
emit urlsReadyToBeDownloaded(url_list_cleaned);
return;
}
if(command == "upload")
{
QByteArray torrentfile = parser.torrent();
// XXX: Trick to get a unique filename
QString filePath;
QTemporaryFile *tmpfile = new QTemporaryFile();
if (tmpfile->open()) {
filePath = tmpfile->fileName();
}
delete tmpfile;
// write it to HD
QFile torrent(filePath);
if(torrent.open(QIODevice::WriteOnly)) {
torrent.write(torrentfile);
torrent.close();
}
emit torrentReadyToBeDownloaded(filePath, false, QString(), false);
return;
}
if(command == "resumeall")

View File

@@ -27,7 +27,6 @@
#include <QObject>
class QTcpSocket;
class HttpServer;
class HttpConnection : public QObject
@@ -47,6 +46,8 @@ class HttpConnection : public QObject
void respondJson();
void respondCommand(QString command);
void respondNotFound();
void processDownloadedFile(QString, QString);
void handleDownloadFailure(QString, QString);
public:
HttpConnection(QTcpSocket *socket, HttpServer *parent);
@@ -56,7 +57,8 @@ class HttpConnection : public QObject
void read();
signals:
void urlsReadyToBeDownloaded(const QStringList&);
void UrlReadyToBeDownloaded(QString url);
void torrentReadyToBeDownloaded(QString, bool, QString, bool);
void deleteTorrent(QString hash);
void resumeTorrent(QString hash);
void pauseTorrent(QString hash);

View File

@@ -49,11 +49,11 @@ QString HttpRequestParser::url() const
return path;
}
QString HttpRequestParser::message() const
QByteArray HttpRequestParser::message() const
{
if(isParsable())
return data;
return QString();
return QByteArray();
}
QString HttpRequestParser::get(const QString key) const
@@ -66,7 +66,12 @@ QString HttpRequestParser::post(const QString key) const
return postMap[key];
}
void HttpRequestParser::write(QString str)
QByteArray HttpRequestParser::torrent() const
{
return torrent_content;
}
void HttpRequestParser::write(QByteArray str)
{
while (!headerDone && str.size()>0)
{
@@ -111,7 +116,7 @@ void HttpRequestParser::write(QString str)
if(contentType() == "application/x-www-form-urlencoded")
{
QUrl url;
url.setEncodedQuery(data.toAscii());
url.setEncodedQuery(data);
QListIterator<QPair<QString, QString> > i(url.queryItems());
while (i.hasNext())
{
@@ -120,9 +125,15 @@ void HttpRequestParser::write(QString str)
qDebug() << pair.first << "=" << post(pair.first);
}
}
if(contentType() == "multipart/form-data")
{
//qDebug() << data.right(data.size()-data.indexOf("\r\n\r\n")-QByteArray("\r\n\r\n").size());
torrent_content = data.right(data.size()-data.indexOf("\r\n\r\n")-QByteArray("\r\n\r\n").size());
}
}
}
else
error = true;
}
qDebug() << "isError: " << isError();
}

View File

@@ -30,10 +30,11 @@ class HttpRequestParser : public QHttpRequestHeader
bool headerDone;
bool messageDone;
bool error;
QString data;
QByteArray data;
QString path;
QMap<QString, QString> postMap;
QMap<QString, QString> getMap;
QByteArray torrent_content;
public:
HttpRequestParser();
@@ -41,10 +42,11 @@ class HttpRequestParser : public QHttpRequestHeader
bool isParsable() const;
bool isError() const;
QString url() const;
QString message() const;
QByteArray message() const;
QString get(const QString key) const;
QString post(const QString key) const;
void write(QString str);
QByteArray torrent() const;
void write(QByteArray str);
};
#endif

View File

@@ -20,7 +20,6 @@
#include "httpresponsegenerator.h"
#include <QDebug>
void HttpResponseGenerator::setMessage(const QByteArray message)
{

View File

@@ -32,25 +32,28 @@ HttpServer::HttpServer(bittorrent *BTSession, int msec, QObject* parent) : QTcpS
HttpServer::BTSession = BTSession;
manager = new EventManager(this);
//add torrents
QStringList list = BTSession->getUnfinishedTorrents() + BTSession->getFinishedTorrents();
QString hash;
foreach(hash, list)
{
QStringList list = BTSession->getUnfinishedTorrents();
foreach(QString hash, list) {
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(h.is_valid())
manager->addedTorrent(QString(), h);
if(h.is_valid()) manager->addedTorrent(QString(), h);
}
list = BTSession->getFinishedTorrents();
foreach(QString hash, list) {
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(h.is_valid()) manager->addedTorrent(QString(), h);
}
//connect BTSession to manager
connect(BTSession, SIGNAL(addedTorrent(QString, QTorrentHandle&, bool)), manager, SLOT(addedTorrent(QString, QTorrentHandle&)));
connect(BTSession, SIGNAL(deletedTorrent(QString)), manager, SLOT(deletedTorrent(QString)));
//set timer
QTimer *timer = new QTimer(this);
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(onTimer()));
timer->start(msec);
}
HttpServer::~HttpServer()
{
delete timer;
delete manager;
}
@@ -61,7 +64,8 @@ void HttpServer::newHttpConnection()
{
HttpConnection *connection = new HttpConnection(socket, this);
//connect connection to BTSession
connect(connection, SIGNAL(urlsReadyToBeDownloaded(const QStringList&)), BTSession, SLOT(downloadFromURLList(const QStringList&)));
connect(connection, SIGNAL(UrlReadyToBeDownloaded(QString)), BTSession, SLOT(downloadUrlAndSkipDialog(QString)));
connect(connection, SIGNAL(torrentReadyToBeDownloaded(QString, bool, QString, bool)), BTSession, SLOT(addTorrent(QString, bool, QString, bool)));
connect(connection, SIGNAL(deleteTorrent(QString)), BTSession, SLOT(deleteTorrent(QString)));
connect(connection, SIGNAL(pauseTorrent(QString)), BTSession, SLOT(pauseTorrent(QString)));
connect(connection, SIGNAL(resumeTorrent(QString)), BTSession, SLOT(resumeTorrent(QString)));
@@ -72,12 +76,15 @@ void HttpServer::newHttpConnection()
void HttpServer::onTimer()
{
QStringList list = BTSession->getUnfinishedTorrents() + BTSession->getFinishedTorrents();
foreach(QString hash, list)
{
QStringList list = BTSession->getUnfinishedTorrents();
foreach(QString hash, list) {
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(h.is_valid())
manager->modifiedTorrent(h);
if(h.is_valid()) manager->modifiedTorrent(h);
}
list = BTSession->getFinishedTorrents();
foreach(QString hash, list) {
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(h.is_valid()) manager->modifiedTorrent(h);
}
}

View File

@@ -26,7 +26,7 @@
#include <QByteArray>
class bittorrent;
class QTimer;
class EventManager;
class HttpServer : public QTcpServer
@@ -37,6 +37,7 @@ class HttpServer : public QTcpServer
QByteArray base64;
bittorrent *BTSession;
EventManager *manager;
QTimer *timer;
public:
HttpServer(bittorrent *BTSession, int msec, QObject* parent = 0);

View File

@@ -1,106 +1,108 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>Icons/folder.png</file>
<file>Icons/qbittorrent32.png</file>
<file>Icons/file.png</file>
<file>Icons/smile.png</file>
<file>Icons/qbittorrent22.png</file>
<file>Icons/mascot.png</file>
<file>Icons/downarrow.png</file>
<file>Icons/unavailable.png</file>
<file>Icons/proxy.png</file>
<file>Icons/description.png</file>
<file>Icons/log.png</file>
<file>Icons/uparrow.png</file>
<file>Icons/home.png</file>
<file>Icons/unsubscribe.png</file>
<file>Icons/url.png</file>
<file>Icons/unsubscribe16.png</file>
<file>Icons/stare.png</file>
<file>Icons/qbittorrent16.png</file>
<file>Icons/locale.png</file>
<file>Icons/splash.png</file>
<file>Icons/subscribe16.png</file>
<file>Icons/loading.png</file>
<file>Icons/star.png</file>
<file>Icons/gnome-shutdown.png</file>
<file>Icons/style.png</file>
<file>Icons/rss16.png</file>
<file>Icons/add_file.png</file>
<file>Icons/add_folder.png</file>
<file>Icons/bt_settings.png</file>
<file>Icons/button_cancel.png</file>
<file>Icons/button_ok.png</file>
<file>Icons/configure.png</file>
<file>Icons/connection.png</file>
<file>Icons/systemtray.png</file>
<file>Icons/sphere.png</file>
<file>Icons/add_folder.png</file>
<file>Icons/button_cancel.png</file>
<file>Icons/encrypted.png</file>
<file>Icons/wizard.png</file>
<file>Icons/edit_clear.png</file>
<file>Icons/rss32.png</file>
<file>Icons/subscribe.png</file>
<file>Icons/bt_settings.png</file>
<file>Icons/password.png</file>
<file>Icons/newmsg.png</file>
<file>Icons/sphere2.png</file>
<file>Icons/button_ok.png</file>
<file>Icons/unhappy.png</file>
<file>Icons/add_file.png</file>
<file>Icons/filter.png</file>
<file>Icons/money.png</file>
<file>Icons/description.png</file>
<file>Icons/downarrow.png</file>
<file>Icons/download.png</file>
<file>Icons/time.png</file>
<file>Icons/refresh.png</file>
<file>Icons/edit_clear.png</file>
<file>Icons/encrypted.png</file>
<file>Icons/file.png</file>
<file>Icons/filter.png</file>
<file>Icons/folder.png</file>
<file>Icons/gear.png</file>
<file>Icons/skin/new.png</file>
<file>Icons/skin/qb_question.png</file>
<file>Icons/skin/play.png</file>
<file>Icons/skin/connecting.png</file>
<file>Icons/skin/settings.png</file>
<file>Icons/skin/add.png</file>
<file>Icons/skin/open.png</file>
<file>Icons/skin/play_all.png</file>
<file>Icons/skin/info.png</file>
<file>Icons/skin/connected.png</file>
<file>Icons/skin/search.png</file>
<file>Icons/skin/url.png</file>
<file>Icons/skin/firewalled.png</file>
<file>Icons/skin/properties.png</file>
<file>Icons/skin/preview.png</file>
<file>Icons/skin/remove.png</file>
<file>Icons/skin/delete_perm.png</file>
<file>Icons/skin/pause_all.png</file>
<file>Icons/skin/delete_all.png</file>
<file>Icons/skin/stalled.png</file>
<file>Icons/skin/downloading.png</file>
<file>Icons/skin/delete.png</file>
<file>Icons/skin/exit.png</file>
<file>Icons/skin/seeding.png</file>
<file>Icons/skin/paused.png</file>
<file>Icons/skin/disconnected.png</file>
<file>Icons/skin/pause.png</file>
<file>Icons/flags/turkey.png</file>
<file>Icons/flags/portugal.png</file>
<file>Icons/flags/finland.png</file>
<file>Icons/flags/ukraine.png</file>
<file>Icons/flags/bulgaria.png</file>
<file>Icons/flags/spain_catalunya.png</file>
<file>Icons/gnome-shutdown.png</file>
<file>Icons/home.png</file>
<file>Icons/loading.png</file>
<file>Icons/locale.png</file>
<file>Icons/log.png</file>
<file>Icons/mascot.png</file>
<file>Icons/money.png</file>
<file>Icons/newmsg.png</file>
<file>Icons/password.png</file>
<file>Icons/proxy.png</file>
<file>Icons/qbittorrent16.png</file>
<file>Icons/qbittorrent22.png</file>
<file>Icons/qbittorrent32.png</file>
<file>Icons/refresh.png</file>
<file>Icons/rss16.png</file>
<file>Icons/rss32.png</file>
<file>Icons/smile.png</file>
<file>Icons/sphere.png</file>
<file>Icons/sphere2.png</file>
<file>Icons/splash.png</file>
<file>Icons/star.png</file>
<file>Icons/stare.png</file>
<file>Icons/style.png</file>
<file>Icons/subscribe.png</file>
<file>Icons/subscribe16.png</file>
<file>Icons/systemtray.png</file>
<file>Icons/time.png</file>
<file>Icons/unavailable.png</file>
<file>Icons/unhappy.png</file>
<file>Icons/unsubscribe.png</file>
<file>Icons/unsubscribe16.png</file>
<file>Icons/uparrow.png</file>
<file>Icons/url.png</file>
<file>Icons/wizard.png</file>
<file>Icons/flags/brazil.png</file>
<file>Icons/flags/norway.png</file>
<file>Icons/flags/slovakia.png</file>
<file>Icons/flags/romania.png</file>
<file>Icons/flags/united_kingdom.png</file>
<file>Icons/flags/netherlands.png</file>
<file>Icons/flags/bulgaria.png</file>
<file>Icons/flags/china.png</file>
<file>Icons/flags/czech.png</file>
<file>Icons/flags/denmark.png</file>
<file>Icons/flags/hungary.png</file>
<file>Icons/flags/greece.png</file>
<file>Icons/flags/spain.png</file>
<file>Icons/flags/italy.png</file>
<file>Icons/flags/germany.png</file>
<file>Icons/flags/russia.png</file>
<file>Icons/flags/japan.png</file>
<file>Icons/flags/south_korea.png</file>
<file>Icons/flags/finland.png</file>
<file>Icons/flags/france.png</file>
<file>Icons/flags/sweden.png</file>
<file>Icons/flags/germany.png</file>
<file>Icons/flags/greece.png</file>
<file>Icons/flags/hungary.png</file>
<file>Icons/flags/italy.png</file>
<file>Icons/flags/japan.png</file>
<file>Icons/flags/netherlands.png</file>
<file>Icons/flags/norway.png</file>
<file>Icons/flags/poland.png</file>
<file>Icons/flags/portugal.png</file>
<file>Icons/flags/romania.png</file>
<file>Icons/flags/russia.png</file>
<file>Icons/flags/slovakia.png</file>
<file>Icons/flags/south_korea.png</file>
<file>Icons/flags/spain.png</file>
<file>Icons/flags/spain_catalunya.png</file>
<file>Icons/flags/sweden.png</file>
<file>Icons/flags/taiwan.png</file>
<file>Icons/flags/turkey.png</file>
<file>Icons/flags/ukraine.png</file>
<file>Icons/flags/united_kingdom.png</file>
<file>Icons/skin/add.png</file>
<file>Icons/skin/connected.png</file>
<file>Icons/skin/connecting.png</file>
<file>Icons/skin/delete.png</file>
<file>Icons/skin/delete_all.png</file>
<file>Icons/skin/delete_perm.png</file>
<file>Icons/skin/disconnected.png</file>
<file>Icons/skin/downloading.png</file>
<file>Icons/skin/exit.png</file>
<file>Icons/skin/firewalled.png</file>
<file>Icons/skin/info.png</file>
<file>Icons/skin/new.png</file>
<file>Icons/skin/open.png</file>
<file>Icons/skin/pause.png</file>
<file>Icons/skin/pause_all.png</file>
<file>Icons/skin/paused.png</file>
<file>Icons/skin/play.png</file>
<file>Icons/skin/play_all.png</file>
<file>Icons/skin/preview.png</file>
<file>Icons/skin/properties.png</file>
<file>Icons/skin/qb_question.png</file>
<file>Icons/skin/remove.png</file>
<file>Icons/skin/search.png</file>
<file>Icons/skin/seeding.png</file>
<file>Icons/skin/settings.png</file>
<file>Icons/skin/stalled.png</file>
<file>Icons/skin/url.png</file>
</qresource>
</RCC>

Some files were not shown because too many files have changed in this diff Show More