You've already forked qBittorrent
							
							
				mirror of
				https://github.com/qbittorrent/qBittorrent
				synced 2025-10-30 23:30:54 +01:00 
			
		
		
		
	Compare commits
	
		
			44 Commits
		
	
	
		
			release-2.
			...
			release-1.
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 2b2026e83f | ||
|   | 9b712718bd | ||
|   | dfe6854619 | ||
|   | c871d3642c | ||
|   | fcdc85453a | ||
|   | 51c14e39cd | ||
|   | 28626f51ad | ||
|   | 25233295ba | ||
|   | bd6684405b | ||
|   | a8235dc413 | ||
|   | c2838d9b0c | ||
|   | d6d7797064 | ||
|   | 685216505c | ||
|   | c28c55280d | ||
|   | f1032c4619 | ||
|   | d34bfd13b3 | ||
|   | cfd6a9d734 | ||
|   | c2f22d292a | ||
|   | 9778112b3b | ||
|   | 1708361bd5 | ||
|   | cc04f7eec2 | ||
|   | 395805f9e8 | ||
|   | ba5daee92f | ||
|   | bfef2b5cc0 | ||
|   | af2431afbd | ||
|   | 7a1b92e467 | ||
|   | dc399e9ed9 | ||
|   | dad79d2cc8 | ||
|   | b5d30d5154 | ||
|   | 72df85749b | ||
|   | 6c84288b09 | ||
|   | 78239d6956 | ||
|   | 41be514dcf | ||
|   | 855b539843 | ||
|   | 2e72ab4973 | ||
|   | ae2ad8e747 | ||
|   | 42fa5ef8f3 | ||
|   | 9395f7316d | ||
|   | fa1c4050ed | ||
|   | 565b98a94a | ||
|   | f58efdfefc | ||
|   | a806c27f70 | ||
|   | a8f82d9e12 | ||
|   | fe6054307e | 
							
								
								
									
										2
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								AUTHORS
									
									
									
									
									
								
							| @@ -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) | ||||
|   | ||||
							
								
								
									
										26
									
								
								Changelog
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								Changelog
									
									
									
									
									
								
							| @@ -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 | ||||
|   | ||||
							
								
								
									
										1
									
								
								INSTALL
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								INSTALL
									
									
									
									
									
								
							| @@ -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
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								TODO
									
									
									
									
									
								
							| @@ -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 | ||||
|   | ||||
| @@ -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(); | ||||
|   } | ||||
|   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){ | ||||
|   } | ||||
|   switch(index) { | ||||
|     case F_SIZE: | ||||
|     case F_UPSPEED: | ||||
|       sortFinishedListFloat(index, sortOrder); | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
							
								
								
									
										37
									
								
								src/GUI.cpp
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								src/GUI.cpp
									
									
									
									
									
								
							| @@ -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) | ||||
|   | ||||
| @@ -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
									
								
							
							
						
						
									
										
											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
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/Icons/flags/taiwan.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 333 B | 
| @@ -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 | 
| @@ -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); | ||||
|      | ||||
| @@ -186,3 +187,4 @@ bool SearchTab::loadColWidthSearchList(){ | ||||
|   qDebug("Search list columns width loaded"); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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>")); | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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); | ||||
|     } | ||||
|     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) { | ||||
|   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) { | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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(); | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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); | ||||
|       } | ||||
|       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 | ||||
|   | ||||
| @@ -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); | ||||
|  | ||||
|   | ||||
| @@ -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;*/ | ||||
|   | ||||
| @@ -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); | ||||
| 			} | ||||
| 		} | ||||
| 		return; | ||||
| 	} | ||||
| 		emit urlsReadyToBeDownloaded(url_list_cleaned); | ||||
| 	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") | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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(); | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -20,7 +20,6 @@ | ||||
|  | ||||
|  | ||||
| #include "httpresponsegenerator.h" | ||||
| #include <QDebug> | ||||
|  | ||||
| void HttpResponseGenerator::setMessage(const QByteArray message) | ||||
| { | ||||
|   | ||||
| @@ -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); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
							
								
								
									
										188
									
								
								src/icons.qrc
									
									
									
									
									
								
							
							
						
						
									
										188
									
								
								src/icons.qrc
									
									
									
									
									
								
							| @@ -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
		Reference in New Issue
	
	Block a user