You've already forked qBittorrent
							
							
				mirror of
				https://github.com/qbittorrent/qBittorrent
				synced 2025-10-30 23:30:54 +01:00 
			
		
		
		
	Compare commits
	
		
			136 Commits
		
	
	
		
			release-2.
			...
			release-2.
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 7c79537176 | ||
|   | 2b45e1baa3 | ||
|   | 476b395166 | ||
|   | 7157996dc2 | ||
|   | 218f386502 | ||
|   | b492051d32 | ||
|   | 39c7d884c9 | ||
|   | 4d2d0bf08d | ||
|   | 34c1fd759b | ||
|   | 922aebec9a | ||
|   | 4d39b3accd | ||
|   | c713bd56e0 | ||
|   | efcd652e3d | ||
|   | 8d6df1f15f | ||
|   | ca835a105b | ||
|   | 2de1a7cc30 | ||
|   | 3de83319a8 | ||
|   | cfc75905a2 | ||
|   | 2c30d5a1ca | ||
|   | d162d0c3c6 | ||
|   | 509eb9bcf0 | ||
|   | 1766877605 | ||
|   | fa78fba559 | ||
|   | 44ff7161aa | ||
|   | 96837a3658 | ||
|   | e4d93a96e7 | ||
|   | ccb2ed9a69 | ||
|   | ae5693544d | ||
|   | 3a72c11e39 | ||
|   | 4176abd18a | ||
|   | cba36fcb14 | ||
|   | 9f33656e61 | ||
|   | a4123a6462 | ||
|   | 313b2630bd | ||
|   | 87b0ae9a79 | ||
|   | 81778a0090 | ||
|   | 5d0d63d89a | ||
|   | 764e8a365b | ||
|   | e302042520 | ||
|   | e453eb9a91 | ||
|   | 98fcb91dae | ||
|   | c8a1f625f0 | ||
|   | b70cf7c049 | ||
|   | ecdfe63d00 | ||
|   | 7635fe51f7 | ||
|   | 8cba38ac62 | ||
|   | fab63e6ffc | ||
|   | 27f257ba03 | ||
|   | a2aa462030 | ||
|   | 0f44804225 | ||
|   | de78fc495b | ||
|   | 93731f1b3f | ||
|   | 2e9e10299c | ||
|   | 9f627b5ec9 | ||
|   | ad252f432a | ||
|   | eb1feddea6 | ||
|   | 1634014dde | ||
|   | e863772159 | ||
|   | 7c34f4e93c | ||
|   | 91032056e1 | ||
|   | f427d267b6 | ||
|   | a7a8265053 | ||
|   | 827fceca83 | ||
|   | 7aaa3e8f51 | ||
|   | 1fe49198d1 | ||
|   | c582aff563 | ||
|   | 5272f1cba3 | ||
|   | b72d356083 | ||
|   | fbd6533eee | ||
|   | 2998dbd0a1 | ||
|   | cb8da634f4 | ||
|   | e8f229816e | ||
|   | fe0fc952e8 | ||
|   | 29a76ae600 | ||
|   | 5471600dfb | ||
|   | df42c4d59f | ||
|   | 8047495b2e | ||
|   | de04b47c29 | ||
|   | b709bec24d | ||
|   | 35f93e8e16 | ||
|   | 554a84f8b0 | ||
|   | f26fcabde1 | ||
|   | 75b91c204d | ||
|   | 0837c25602 | ||
|   | 34f8937b8d | ||
|   | 4a7f3ee415 | ||
|   | b218531ff7 | ||
|   | e96dee2038 | ||
|   | 080105c088 | ||
|   | 5d2535c1c1 | ||
|   | 49b21059fa | ||
|   | c1af948649 | ||
|   | 36ad3df9e7 | ||
|   | e607d721a2 | ||
|   | 5bfbfeb665 | ||
|   | 1f1eabb1e9 | ||
|   | 762050f8fc | ||
|   | e3c1270205 | ||
|   | 414685910b | ||
|   | d61b9c5d4d | ||
|   | cf86a1cecd | ||
|   | a3f3287e24 | ||
|   | 6e18d780ba | ||
|   | 7dde763fc6 | ||
|   | 8c85ffca5f | ||
|   | 321e568d86 | ||
|   | e0649a7e78 | ||
|   | 4cd3233cd0 | ||
|   | c554528afe | ||
|   | 7ab7f4b0fc | ||
|   | 58c0ac7638 | ||
|   | 2514224a3a | ||
|   | 247f6b4a8e | ||
|   | 3d89864b75 | ||
|   | 7ac75ad772 | ||
|   | caa628371f | ||
|   | fd31f632d9 | ||
|   | a25b6e087b | ||
|   | 1626d938d1 | ||
|   | a4c7640499 | ||
|   | 2c1b93a12b | ||
|   | 8f19025c2a | ||
|   | 20d41bcff2 | ||
|   | 1ad77e00ff | ||
|   | 0b65c02666 | ||
|   | 294095367a | ||
|   | 05a6ffd554 | ||
|   | e0a30dc40c | ||
|   | 1940bc4e73 | ||
|   | a7e4e0273a | ||
|   | 29a9d57cdc | ||
|   | 9c7a4e4983 | ||
|   | 35ead5bcf2 | ||
|   | 645bd58d79 | ||
|   | 6c47a552ab | ||
|   | f54bc8bea4 | 
							
								
								
									
										2
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								AUTHORS
									
									
									
									
									
								
							| @@ -83,7 +83,7 @@ Translations authors: | ||||
|   - German: Niels Hoffmann (zentralmaschine@users.sourceforge.net) | ||||
|   - Greek: Tsvetan Bankov (emerge_life@users.sourceforge.net) and Stephanos Antaris (santaris@csd.auth.gr) | ||||
|   - Hungarian: Majoros Péter (majoros.j.p@t-online.hu) | ||||
|   - Italian: Mirko Ferrari (mirkoferrari@gmail.com) and Ferraro Luciano (luciano.ferraro@gmail.com) | ||||
|   - Italian: Matteo Sechi (bu17714@gmail.com) | ||||
|   - Japanese: Nardog (alphisation@gmail.com) | ||||
|   - Korean: Jin Woo Sin (jin828sin@users.sourceforge.net) | ||||
|   - Norwegian: Lars-Erik Labori (hamil@users.sourceforge.net) | ||||
|   | ||||
							
								
								
									
										101
									
								
								Changelog
									
									
									
									
									
								
							
							
						
						
									
										101
									
								
								Changelog
									
									
									
									
									
								
							| @@ -1,8 +1,99 @@ | ||||
| * Unreleased - Christophe Dumez <chris@qbittorrent.org> - v2.5.0 | ||||
|     - FEATURE: qBittorrent can now act as a tracker | ||||
|     - FEATURE: Added feature to shutdown qbittorrent on torrents completion | ||||
|     - FEATURE: Added a transfer list column to display the current tracker | ||||
|     - COSMETIC: Replaced message box by on-screen notification for download errors | ||||
| * Unreleased - Christophe Dumez <chris@qbittorrent.org> - v2.4.11 | ||||
|     - BUGFIX: Do not report a progress of 100% in the Web UI unless the | ||||
|     torrent is really complete (closes #674349) | ||||
|     - BUGFIX: Fix possible incorrect behavior with queueing | ||||
|     - BUGFIX: Fix RSS refresh interval saving | ||||
|     - BUGFIX: Fix possible crash when setting RSS proxy (closes #676288) | ||||
|     - BUGFIX: Fix HTTP redirect issue that would cause the torrent addition to | ||||
|     show up for automated RSS downloads (Closes #677565) | ||||
|  | ||||
| * Wed Nov 10 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.10 | ||||
|     - BUGFIX: Fix possible crash when selecting a RSS item (really closes #575624) | ||||
|     - BUGFIX: Improved IPv6 support (IP filter and Peer list) | ||||
|     - BUGFIX: Make IP filter more tolerant towards strangely formatted IPs | ||||
|     - BUGFIX: More reliable folder scanning | ||||
|     - BUGFIX: Do not create the torrent root folder at final destination if | ||||
|     torrent is in the temp dir (closes #673271) | ||||
|     - BUGFIX: Fix compilation with libnotify v0.7.0 (closes #671769) | ||||
|     - BUGFIX: Use a pointing cursor over status bar buttons | ||||
|  | ||||
| * Sun Oct 31 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.9 | ||||
|     - BUGFIX: Fix crash when pressing enter in save path field in torrent addition dialog | ||||
|     - BUGFIX: Fix crash when deleting a torrent with no metadata (closes #667528) | ||||
|     - BUGFIX: Fix possible crash on clicking a RSS article (closes #575624) | ||||
|     - BUGFIX: Correctly update total number of torrents when a torrent is automatically removed (closes #668726) | ||||
|     - BUGFIX: Correctly display the hash of torrents with no metadata | ||||
|     - BUGFIX: Elide status bar text if it is too wide | ||||
|     - BUGFIX: Make sure the splash screen is displayed for 2 seconds | ||||
|     - BUGFIX: Make listening on a particular interface more reliable | ||||
|     - BUGFIX: Fix torrent size update in torrent addition dialog | ||||
|     - BUGFIX: Fix possible crash on qBittorrent shutdown | ||||
|     - BUGFIX: Fix and improve file priorities editing (closes #669084) | ||||
|     - I18N: Updated Arabic, Italian and Croatian translations | ||||
|  | ||||
| * Sun Oct 24 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.8 | ||||
|     - BUGFIX: Fix possible crash on manual peer ban | ||||
|     - BUGFIX: Improved hostname resolution code | ||||
|     - BUGFIX: Several search plugins fixed | ||||
|     - BUGFIX: Auto-disable the shutdown feature | ||||
|     - BUGFIX: Remember the current property tab on startup | ||||
|     - BUGFIX: Fix status list widget height issue on style change | ||||
|     - BUGFIX: Fix rounding issue in torrent progress display | ||||
|     - BUGFIX: Fix issue when altering files priorities of a seeding torrent | ||||
|     - BUGFIX: Better fix for save path editing issues in torrent addition dialog | ||||
|     - BUGFIX: Peers can now be sorted by country | ||||
|  | ||||
| * Tue Oct 19 2010  - Christophe Dumez <chris@qbittorrent.org> - v2.4.7 | ||||
|     - BUGFIX: Display the priority column when the queueing system gets enabled | ||||
|     - BUGFIX: Fix encoding problem in file renaming | ||||
|     - BUGFIX: Delete uneeded files on torrent "soft" deletion | ||||
|     - BUGFIX: Fix issues when marking a file as 'not downloaded' causes the torrent to complete | ||||
|     - BUGFIX: Improved "Set Location" and "Change save path" dialogs | ||||
|     - BUGFIX: Fix display of queued seeding torrents | ||||
|  | ||||
| * Sun Oct 17 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.6 | ||||
|     - BUGFIX: Fix "torrent seeding after creation" feature | ||||
|     - BUGFIX: The properties panel data would sometimes not match the selected torrent | ||||
|     - BUGFIX: Fix detection of files at final destination when temp dir is used | ||||
|     - BUGFIX: Fix moving of a torrent to an unexisting directory | ||||
|  | ||||
| * Tue Oct 12 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.5 | ||||
|     - BUGFIX: Remember torrent completion date correctly | ||||
|     - BUGFIX: Fix feature to keep incomplete torrents in a separate folder | ||||
|     - BUGFIX: Fix display of URL seeds in the UI | ||||
|     - BUGFIX: Improved peer hostname resolution with caching | ||||
|     - BUGFIX: Piece availability/downloaded widgets performance improvement | ||||
|  | ||||
| * Fri Oct 1 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.4 | ||||
|     - BUGFIX: Clean program exit on system shutdown/logout | ||||
|     - BUGFIX: Fix possible search engine plugin update | ||||
|  | ||||
| * Tue Sep 28 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.3 | ||||
|     - BUGFIX: Fix encoding issue in command line parameters processing | ||||
|     - BUGFIX: Fix possible crash when changing the save path in addition dialog | ||||
|     - BUGFIX: Fix wrong mapping to source model | ||||
|  | ||||
| * Sun Sep 26 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.2 | ||||
|     - BUGFIX: Fix display of torrent content in addition dialog | ||||
|     - BUGFIX: Really fix manual editing of save path in torrent addition dialog | ||||
|  | ||||
| * Sun Sep 26 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.1 | ||||
|     - I18N: Updated Arabic translation | ||||
|     - I18N: Fixes to German translation | ||||
|     - BUGFIX: Save path can now be edited in torrent addition dialog | ||||
|     - BUGFIX: Fix save path encoding on non-utf8 systems | ||||
|     - BUGFIX: Fix saving to drive root on Windows | ||||
|     - BUGFIX: OGV can now be previewed | ||||
|     - BUGFIX: Maximum download limit is now 10MB/s | ||||
|     - BUGFIX: Fix 'download in scan dir' persistence | ||||
|     - BUGFIX: Add .torrent extension only when missing (torrent creator) | ||||
|     - BUGFIX: Fix possible issue with temporary download path persistence | ||||
|     - BUGFIX: Added support for | (OR) operator in RSS feed downloader | ||||
|     - BUGFIX: Fix Web UI for spanish users | ||||
|     - BUGFIX: Fix locale switching from Web UI | ||||
|     - BUGFIX: Use AND operator for torrentdownloads.net searches | ||||
|     - BUGFIX: Limit torrent addition dialog width to fit the screen | ||||
|     - COSMETIC: Fix progress bars style on Windows | ||||
|  | ||||
| * Tue Aug 24 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.0 | ||||
|     - FEATURE: Added actions to "Move to top/bottom" of priority queue | ||||
|   | ||||
							
								
								
									
										2
									
								
								INSTALL
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								INSTALL
									
									
									
									
									
								
							| @@ -10,7 +10,7 @@ qBittorrent - A BitTorrent client in C++ / Qt4 | ||||
|   will install and execute qBittorrent hopefully without any problems. | ||||
|  | ||||
|   Dependencies: | ||||
|     - Qt >= 4.5.0 (libqt-devel, libqtgui, libqtcore, libqtnetwork, libqtxml) | ||||
|     - Qt >= 4.4.0 (libqt-devel, libqtgui, libqtcore, libqtnetwork, libqtxml) | ||||
|  | ||||
|     - pkg-config executable | ||||
|  | ||||
|   | ||||
							
								
								
									
										26
									
								
								configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								configure
									
									
									
									
										vendored
									
									
								
							| @@ -325,7 +325,7 @@ cat >$1/modules.cpp <<EOT | ||||
| #line 1 "qt4.qcm" | ||||
| /* | ||||
| -----BEGIN QCMOD----- | ||||
| name: Qt >= 4.5 | ||||
| name: Qt >= 4.4 | ||||
| arg: disable-gui, Disable qBittorrent Graphical user interface for headless running | ||||
| -----END QCMOD----- | ||||
| */ | ||||
| @@ -333,14 +333,14 @@ class qc_qt4 : public ConfObj | ||||
| { | ||||
| public: | ||||
| 	qc_qt4(Conf *c) : ConfObj(c) {} | ||||
| 	QString name() const { return "Qt >= 4.5"; } | ||||
| 	QString shortname() const { return "Qt 4.5"; } | ||||
| 	QString name() const { return "Qt >= 4.4"; } | ||||
| 	QString shortname() const { return "Qt 4.4"; } | ||||
| 	bool exec() | ||||
| 	{ | ||||
| 		if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) { | ||||
| 			conf->addDefine("DISABLE_GUI"); | ||||
| 		}	 | ||||
| 		return(QT_VERSION >= 0x040500); | ||||
| 		return(QT_VERSION >= 0x040400); | ||||
| 	} | ||||
| }; | ||||
| #line 1 "pkg-config.qcm" | ||||
| @@ -616,22 +616,22 @@ arg: with-qtsingleapplication=[system|shipped], Use the shipped qtsingleapplicat | ||||
| class qc_qtsingleapplication : public ConfObj | ||||
| { | ||||
| public: | ||||
|         qc_qtsingleapplication(Conf *c) : ConfObj(c) {} | ||||
|         QString name() const { return "qtsingleapplication library"; } | ||||
|         QString shortname() const { return "qtsingleapplication"; } | ||||
| 	qc_qtsingleapplication(Conf *c) : ConfObj(c) {} | ||||
| 	QString name() const { return "qtsingleapplication library"; } | ||||
| 	QString shortname() const { return "qtsingleapplication"; } | ||||
|  | ||||
|         bool exec(){ | ||||
|                 QString s; | ||||
|                 s = conf->getenv("QC_WITH_QTSINGLEAPPLICATION"); | ||||
| 	bool exec(){ | ||||
|         	QString s; | ||||
| 		s = conf->getenv("QC_WITH_QTSINGLEAPPLICATION"); | ||||
|                 if(s.compare("system", Qt::CaseInsensitive) == 0) { | ||||
|                   // System | ||||
|                   conf->addDefine("USE_SYSTEM_QTSINGLEAPPLICATION"); | ||||
|                   printf(" [system] "); | ||||
|                 } else { | ||||
|                   printf(" [shipped] "); | ||||
|                 } | ||||
|                 return true; | ||||
|         } | ||||
| 		} | ||||
| 		return true; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| EOT | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| /* | ||||
| -----BEGIN QCMOD----- | ||||
| name: Qt >= 4.5 | ||||
| name: Qt >= 4.4 | ||||
| arg: disable-gui, Disable qBittorrent Graphical user interface for headless running | ||||
| -----END QCMOD----- | ||||
| */ | ||||
| @@ -8,13 +8,13 @@ class qc_qt4 : public ConfObj | ||||
| { | ||||
| public: | ||||
| 	qc_qt4(Conf *c) : ConfObj(c) {} | ||||
| 	QString name() const { return "Qt >= 4.5"; } | ||||
| 	QString shortname() const { return "Qt 4.5"; } | ||||
| 	QString name() const { return "Qt >= 4.4"; } | ||||
| 	QString shortname() const { return "Qt 4.4"; } | ||||
| 	bool exec() | ||||
| 	{ | ||||
| 		if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) { | ||||
| 			conf->addDefine("DISABLE_GUI"); | ||||
| 		}	 | ||||
| 		return(QT_VERSION >= 0x040500); | ||||
| 		return(QT_VERSION >= 0x040400); | ||||
| 	} | ||||
| }; | ||||
|   | ||||
							
								
								
									
										46
									
								
								src/GUI.cpp
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								src/GUI.cpp
									
									
									
									
									
								
							| @@ -52,7 +52,7 @@ | ||||
| #include "torrentadditiondlg.h" | ||||
| #include "searchengine.h" | ||||
| #include "rss_imp.h" | ||||
| #include "qbtsession.h" | ||||
| #include "bittorrent.h" | ||||
| #include "about_imp.h" | ||||
| #include "trackerlogin.h" | ||||
| #include "options_imp.h" | ||||
| @@ -126,7 +126,7 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), for | ||||
|   // Fix Tool bar layout | ||||
|   toolBar->layout()->setSpacing(7); | ||||
|   // Creating Bittorrent session | ||||
|   BTSession = new QBtSession(); | ||||
|   BTSession = new Bittorrent(); | ||||
|   connect(BTSession, SIGNAL(fullDiskError(QTorrentHandle&, QString)), this, SLOT(fullDiskError(QTorrentHandle&, QString))); | ||||
|   connect(BTSession, SIGNAL(finishedTorrent(QTorrentHandle&)), this, SLOT(finishedTorrent(QTorrentHandle&))); | ||||
|   connect(BTSession, SIGNAL(trackerAuthenticationRequired(QTorrentHandle&)), this, SLOT(trackerAuthenticationRequired(QTorrentHandle&))); | ||||
| @@ -202,7 +202,6 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), for | ||||
|   displaySearchTab(actionSearch_engine->isChecked()); | ||||
|   displayRSSTab(actionRSS_Reader->isChecked()); | ||||
|   actionShutdown_when_downloads_complete->setChecked(Preferences::shutdownWhenDownloadsComplete()); | ||||
|   actionShutdown_qBittorrent_when_downloads_complete->setChecked(Preferences::shutdownqBTWhenDownloadsComplete()); | ||||
|  | ||||
|   show(); | ||||
|  | ||||
| @@ -211,13 +210,7 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), for | ||||
|   properties->readSettings(); | ||||
|  | ||||
|   // Limit status filters list height | ||||
|   int cur_height = 80; | ||||
|   do { | ||||
|     transferListFilters->getStatusFilters()->setFixedHeight(cur_height); | ||||
|     cur_height += 10; | ||||
|     transferListFilters->getStatusFilters()->scrollToBottom(); | ||||
|   }while(transferListFilters->getStatusFilters()->verticalScrollBar()->sliderPosition() > 0); | ||||
|   transferListFilters->getStatusFilters()->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); | ||||
|   transferListFilters->getStatusFilters()->updateHeight(); | ||||
|  | ||||
|   if(ui_locked) { | ||||
|     hide(); | ||||
| @@ -542,7 +535,7 @@ void GUI::askRecursiveTorrentDownloadConfirmation(QTorrentHandle &h) { | ||||
|  | ||||
| void GUI::handleDownloadFromUrlFailure(QString url, QString reason) const{ | ||||
|   // Display a message box | ||||
|   showNotificationBaloon(tr("Url download error"), tr("Couldn't download file at url: %1, reason: %2.").arg(url).arg(reason)); | ||||
|   QMessageBox::critical(0, tr("Url download error"), tr("Couldn't download file at url: %1, reason: %2.").arg(url).arg(reason)); | ||||
| } | ||||
|  | ||||
| void GUI::on_actionSet_global_upload_limit_triggered() { | ||||
| @@ -922,6 +915,7 @@ void GUI::optionsSaved() { | ||||
| // Load program preferences | ||||
| void GUI::loadPreferences(bool configure_session) { | ||||
|   BTSession->addConsoleMessage(tr("Options were saved successfully.")); | ||||
| #ifndef Q_WS_MAC | ||||
|   const bool newSystrayIntegration = Preferences::systrayIntegration(); | ||||
|   actionLock_qBittorrent->setEnabled(newSystrayIntegration); | ||||
|   if(newSystrayIntegration != (systrayIcon!=0)) { | ||||
| @@ -946,6 +940,7 @@ void GUI::loadPreferences(bool configure_session) { | ||||
|       delete myTrayIconMenu; | ||||
|     } | ||||
|   } | ||||
| #endif | ||||
|   // General | ||||
|   if(Preferences::isToolbarDisplayed()) { | ||||
|     toolBar->setVisible(true); | ||||
| @@ -963,7 +958,7 @@ void GUI::loadPreferences(bool configure_session) { | ||||
|   properties->getPeerList()->setAlternatingRowColors(Preferences::useAlternatingRowColors()); | ||||
|   // Queueing System | ||||
|   if(Preferences::isQueueingSystemEnabled()) { | ||||
|     if(!configure_session || !BTSession->isQueueingEnabled()) { | ||||
|     if(!actionDecreasePriority->isVisible()) { | ||||
|       transferList->hidePriorityColumn(false); | ||||
|       actionDecreasePriority->setVisible(true); | ||||
|       actionIncreasePriority->setVisible(true); | ||||
| @@ -972,7 +967,7 @@ void GUI::loadPreferences(bool configure_session) { | ||||
|       toolBar->layout()->setSpacing(7); | ||||
|     } | ||||
|   } else { | ||||
|     if(BTSession->isQueueingEnabled()) { | ||||
|     if(actionDecreasePriority->isVisible()) { | ||||
|       transferList->hidePriorityColumn(true); | ||||
|       actionDecreasePriority->setVisible(false); | ||||
|       actionIncreasePriority->setVisible(false); | ||||
| @@ -1009,8 +1004,9 @@ void GUI::trackerAuthenticationRequired(QTorrentHandle& h) { | ||||
| // Check connection status and display right icon | ||||
| void GUI::updateGUI() { | ||||
|   // update global informations | ||||
| #ifndef Q_WS_MAC | ||||
|   if(systrayIcon) { | ||||
| #if defined(Q_WS_X11) || defined(Q_WS_MAC) | ||||
| #if defined(Q_WS_X11) | ||||
|     QString html = "<div style='background-color: #678db2; color: #fff;height: 18px; font-weight: bold; margin-bottom: 5px;'>"; | ||||
|     html += tr("qBittorrent"); | ||||
|     html += "</div>"; | ||||
| @@ -1028,6 +1024,7 @@ void GUI::updateGUI() { | ||||
| #endif | ||||
|     systrayIcon->setToolTip(html); // tray icon | ||||
|   } | ||||
| #endif | ||||
|   if(displaySpeedInTitle) { | ||||
|     setWindowTitle(tr("qBittorrent %1 (Down: %2/s, Up: %3/s)", "%1 is qBittorrent version").arg(QString::fromUtf8(VERSION)).arg(misc::friendlyUnit(BTSession->getSessionStatus().payload_download_rate)).arg(misc::friendlyUnit(BTSession->getSessionStatus().payload_upload_rate))); | ||||
|   } | ||||
| @@ -1038,7 +1035,12 @@ void GUI::showNotificationBaloon(QString title, QString msg) const { | ||||
| #ifdef WITH_LIBNOTIFY | ||||
|   if (notify_init ("summary-body")) { | ||||
|     NotifyNotification* notification; | ||||
|     notification = notify_notification_new (qPrintable(title), qPrintable(msg), "qbittorrent", 0); | ||||
|  | ||||
|     notification = notify_notification_new (qPrintable(title), qPrintable(msg), "qbittorrent" | ||||
| #if !defined(NOTIFY_VERSION_MINOR) || (NOTIFY_VERSION_MAJOR == 0 && NOTIFY_VERSION_MINOR < 7) | ||||
|                                             , 0 | ||||
| #endif | ||||
|                                             ); | ||||
|     gboolean success = notify_notification_show (notification, NULL); | ||||
|     g_object_unref(G_OBJECT(notification)); | ||||
|     notify_uninit (); | ||||
| @@ -1047,8 +1049,10 @@ void GUI::showNotificationBaloon(QString title, QString msg) const { | ||||
|     } | ||||
|   } | ||||
| #endif | ||||
| #ifndef Q_WS_MAC | ||||
|   if(systrayIcon && QSystemTrayIcon::supportsMessages()) | ||||
|     systrayIcon->showMessage(title, msg, QSystemTrayIcon::Information, TIME_TRAY_BALLOON); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| /***************************************************** | ||||
| @@ -1085,6 +1089,7 @@ void GUI::downloadFromURLList(const QStringList& url_list) { | ||||
|  *****************************************************/ | ||||
|  | ||||
| void GUI::createSystrayDelayed() { | ||||
| #ifndef Q_WS_MAC | ||||
|   static int timeout = 20; | ||||
|   if(QSystemTrayIcon::isSystemTrayAvailable()) { | ||||
|     // Ok, systray integration is now supported | ||||
| @@ -1105,6 +1110,7 @@ void GUI::createSystrayDelayed() { | ||||
|       Preferences::setSystrayIntegration(false); | ||||
|     } | ||||
|   } | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void GUI::updateAltSpeedsBtn(bool alternative) { | ||||
| @@ -1171,11 +1177,6 @@ void GUI::on_actionShutdown_when_downloads_complete_triggered() { | ||||
|   Preferences::setShutdownWhenDownloadsComplete(is_checked); | ||||
| } | ||||
|  | ||||
| void GUI::on_actionShutdown_qBittorrent_when_downloads_complete_triggered() { | ||||
|   bool is_checked = static_cast<QAction*>(sender())->isChecked(); | ||||
|   Preferences::setShutdownqBTWhenDownloadsComplete(is_checked); | ||||
| } | ||||
|  | ||||
| void GUI::on_actionSpeed_in_title_bar_triggered() { | ||||
|   displaySpeedInTitle = static_cast<QAction*>(sender())->isChecked(); | ||||
|   Preferences::showSpeedInTitleBar(displaySpeedInTitle); | ||||
| @@ -1210,3 +1211,8 @@ void GUI::on_actionDownload_from_URL_triggered() { | ||||
|   } | ||||
| } | ||||
|  | ||||
| void GUI::on_actionDonate_money_triggered() | ||||
| { | ||||
|     QDesktopServices::openUrl(QUrl("http://sourceforge.net/donate/index.php?group_id=163414")); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -37,7 +37,7 @@ | ||||
| #include "ui_mainwindow.h" | ||||
| #include "qtorrenthandle.h" | ||||
|  | ||||
| class QBtSession; | ||||
| class Bittorrent; | ||||
| class QTimer; | ||||
| class downloadFromURL; | ||||
| class SearchEngine; | ||||
| @@ -140,7 +140,7 @@ protected: | ||||
| private: | ||||
|   QFileSystemWatcher *executable_watcher; | ||||
|   // Bittorrent | ||||
|   QBtSession *BTSession; | ||||
|   Bittorrent *BTSession; | ||||
|   QList<QPair<QTorrentHandle,QString> > unauthenticated_trackers; // Still needed? | ||||
|   // GUI related | ||||
|   QTimer *guiUpdater; | ||||
| @@ -183,7 +183,7 @@ private slots: | ||||
|     void on_actionSpeed_in_title_bar_triggered(); | ||||
|     void on_actionTop_tool_bar_triggered(); | ||||
|     void on_actionShutdown_when_downloads_complete_triggered(); | ||||
|     void on_actionShutdown_qBittorrent_when_downloads_complete_triggered(); | ||||
|     void on_actionDonate_money_triggered(); | ||||
| }; | ||||
|  | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								src/Icons/oxygen/emblem-favorite.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/Icons/oxygen/emblem-favorite.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 1.9 KiB | 
| @@ -1,6 +1,6 @@ | ||||
| [Desktop Entry] | ||||
| Categories=Qt;Network;P2P; | ||||
| Comment=V2.5.0 | ||||
| Comment=V2.4.11 | ||||
| Exec=qbittorrent %f | ||||
| GenericName=Bittorrent client | ||||
| GenericName[ar]=العميل Bittorrent | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 75 KiB | 
| @@ -47,7 +47,7 @@ | ||||
| 	<key>CFBundlePackageType</key> | ||||
| 	<string>APPL</string> | ||||
| 	<key>CFBundleGetInfoString</key> | ||||
| 	<string>2.5.0</string> | ||||
| 	<string>2.4.11</string> | ||||
| 	<key>CFBundleSignature</key> | ||||
| 	<string>????</string> | ||||
| 	<key>CFBundleExecutable</key> | ||||
|   | ||||
| @@ -73,7 +73,7 @@ class about : public QDialog, private Ui::AboutDlg{ | ||||
|           <li><u>German:</u> Niels Hoffmann (zentralmaschine@users.sourceforge.net)</li>\ | ||||
|           <li><u>Greek:</u> Tsvetan Bankov (emerge_life@users.sourceforge.net)</li>\ | ||||
|           <li><u>Hungarian:</u> Majoros Péter (majoros.peterj@gmail.com)</li>\ | ||||
|           <li><u>Italian:</u> Mirko Ferrari (mirkoferrari@gmail.com) and Ferraro Luciano (luciano.ferraro@gmail.com)</li>\ | ||||
|           <li><u>Italian:</u> Matteo Sechi (bu17714@gmail.com)</li>\ | ||||
|           <li><u>Japanese:</u> Nardog (alphisation@gmail.com)</li>\ | ||||
|           <li><u>Korean:</u> Jin Woo Sin (jin828sin@users.sourceforge.net)</li>\ | ||||
|           <li><u>Norwegian:</u> Lars-Erik Labori (hamil@users.sourceforge.net)</li>\ | ||||
|   | ||||
| @@ -11,15 +11,15 @@ | ||||
| #include "preferences.h" | ||||
|  | ||||
| enum AdvSettingsCols {PROPERTY, VALUE}; | ||||
| enum AdvSettingsRows {DISK_CACHE, OUTGOING_PORT_MIN, OUTGOING_PORT_MAX, IGNORE_LIMIT_LAN, COUNT_OVERHEAD, RECHECK_COMPLETED, LIST_REFRESH, RESOLVE_COUNTRIES, RESOLVE_HOSTS, MAX_HALF_OPEN, SUPER_SEEDING, NETWORK_IFACE, PROGRAM_NOTIFICATIONS, TRACKER_STATUS, TRACKER_PORT }; | ||||
| #define ROW_COUNT 15 | ||||
| enum AdvSettingsRows {DISK_CACHE, OUTGOING_PORT_MIN, OUTGOING_PORT_MAX, IGNORE_LIMIT_LAN, COUNT_OVERHEAD, RECHECK_COMPLETED, LIST_REFRESH, RESOLVE_COUNTRIES, RESOLVE_HOSTS, MAX_HALF_OPEN, SUPER_SEEDING, NETWORK_IFACE, PROGRAM_NOTIFICATIONS }; | ||||
| #define ROW_COUNT 13 | ||||
|  | ||||
| class AdvancedSettings: public QTableWidget { | ||||
|   Q_OBJECT | ||||
|  | ||||
| private: | ||||
|   QSpinBox *spin_cache, *outgoing_ports_min, *outgoing_ports_max, *spin_list_refresh, *spin_maxhalfopen, *spin_tracker_port; | ||||
|   QCheckBox *cb_ignore_limits_lan, *cb_count_overhead, *cb_recheck_completed, *cb_resolve_countries, *cb_resolve_hosts, *cb_super_seeding, *cb_program_notifications, *cb_tracker_status; | ||||
|   QSpinBox *spin_cache, *outgoing_ports_min, *outgoing_ports_max, *spin_list_refresh, *spin_maxhalfopen; | ||||
|   QCheckBox *cb_ignore_limits_lan, *cb_count_overhead, *cb_recheck_completed, *cb_resolve_countries, *cb_resolve_hosts, *cb_super_seeding, *cb_program_notifications; | ||||
|   QComboBox *combo_iface; | ||||
|  | ||||
| public: | ||||
| @@ -53,8 +53,6 @@ public: | ||||
|     delete cb_super_seeding; | ||||
|     delete combo_iface; | ||||
|     delete cb_program_notifications; | ||||
|     delete spin_tracker_port; | ||||
|     delete cb_tracker_status; | ||||
|   } | ||||
|  | ||||
| public slots: | ||||
| @@ -90,9 +88,6 @@ public slots: | ||||
|     } | ||||
|     // Program notification | ||||
|     Preferences::useProgramNotification(cb_program_notifications->isChecked()); | ||||
|     // Tracker | ||||
|     Preferences::setTrackerEnabled(cb_tracker_status->isChecked()); | ||||
|     Preferences::setTrackerPort(spin_tracker_port->value()); | ||||
|   } | ||||
|  | ||||
| protected slots: | ||||
| @@ -195,25 +190,11 @@ protected slots: | ||||
|     connect(combo_iface, SIGNAL(currentIndexChanged(int)), this, SLOT(emitSettingsChanged())); | ||||
|     setCellWidget(NETWORK_IFACE, VALUE, combo_iface); | ||||
|     // Program notifications | ||||
|     setItem(PROGRAM_NOTIFICATIONS, PROPERTY, new QTableWidgetItem(tr("Display program notification balloons"))); | ||||
|     setItem(PROGRAM_NOTIFICATIONS, PROPERTY, new QTableWidgetItem(tr("Display program notification baloons"))); | ||||
|     cb_program_notifications = new QCheckBox(); | ||||
|     connect(cb_program_notifications, SIGNAL(toggled(bool)), this, SLOT(emitSettingsChanged())); | ||||
|     cb_program_notifications->setChecked(Preferences::useProgramNotification()); | ||||
|     setCellWidget(PROGRAM_NOTIFICATIONS, VALUE, cb_program_notifications); | ||||
|     // Tracker State | ||||
|     setItem(TRACKER_STATUS, PROPERTY, new QTableWidgetItem(tr("Enable embedded tracker"))); | ||||
|     cb_tracker_status = new QCheckBox(); | ||||
|     connect(cb_tracker_status, SIGNAL(toggled(bool)), this, SLOT(emitSettingsChanged())); | ||||
|     cb_tracker_status->setChecked(Preferences::isTrackerEnabled()); | ||||
|     setCellWidget(TRACKER_STATUS, VALUE, cb_tracker_status); | ||||
|     // Tracker port | ||||
|     setItem(TRACKER_PORT, PROPERTY, new QTableWidgetItem(tr("Embedded tracker port"))); | ||||
|     spin_tracker_port = new QSpinBox(); | ||||
|     connect(spin_tracker_port, SIGNAL(valueChanged(int)), this, SLOT(emitSettingsChanged())); | ||||
|     spin_tracker_port->setMinimum(1); | ||||
|     spin_tracker_port->setMaximum(65535); | ||||
|     spin_tracker_port->setValue(Preferences::getTrackerPort()); | ||||
|     setCellWidget(TRACKER_PORT, VALUE, spin_tracker_port); | ||||
|   } | ||||
|  | ||||
|   void emitSettingsChanged() { | ||||
|   | ||||
							
								
								
									
										2692
									
								
								src/bittorrent.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2692
									
								
								src/bittorrent.cpp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -46,10 +46,7 @@ | ||||
| #include <libtorrent/version.hpp> | ||||
| #include <libtorrent/session.hpp> | ||||
| #include <libtorrent/ip_filter.hpp> | ||||
|  | ||||
| #include "qtracker.h" | ||||
| #include "qtorrenthandle.h" | ||||
| #include "trackerinfos.h" | ||||
|  | ||||
| using namespace libtorrent; | ||||
|  | ||||
| @@ -62,13 +59,42 @@ class HttpServer; | ||||
| class BandwidthScheduler; | ||||
| class ScanFoldersModel; | ||||
|  | ||||
| class QBtSession : public QObject { | ||||
| class TrackerInfos { | ||||
| public: | ||||
|   QString name_or_url; | ||||
|   QString last_message; | ||||
|   unsigned long num_peers; | ||||
| #if LIBTORRENT_VERSION_MINOR < 15 | ||||
|   bool verified; | ||||
|   uint fail_count; | ||||
| #endif | ||||
|  | ||||
|   //TrackerInfos() {} | ||||
|   TrackerInfos(const TrackerInfos &b) { | ||||
|     name_or_url = b.name_or_url; | ||||
|     Q_ASSERT(!name_or_url.isEmpty()); | ||||
|     last_message = b.last_message; | ||||
|     num_peers = b.num_peers; | ||||
| #if LIBTORRENT_VERSION_MINOR < 15 | ||||
|     verified = b.verified; | ||||
|     fail_count = b.fail_count; | ||||
| #endif | ||||
|   } | ||||
|   TrackerInfos(QString name_or_url): name_or_url(name_or_url), last_message(""), num_peers(0) { | ||||
| #if LIBTORRENT_VERSION_MINOR < 15 | ||||
|     fail_count = 0; | ||||
|     verified = false; | ||||
| #endif | ||||
|   } | ||||
| }; | ||||
|  | ||||
| class Bittorrent : public QObject { | ||||
|   Q_OBJECT | ||||
|  | ||||
| public: | ||||
|   // Constructor / Destructor | ||||
|   QBtSession(); | ||||
|   ~QBtSession(); | ||||
|   Bittorrent(); | ||||
|   ~Bittorrent(); | ||||
|   QTorrentHandle getTorrentHandle(QString hash) const; | ||||
|   std::vector<torrent_handle> getTorrents() const; | ||||
|   bool isFilePreviewPossible(QString fileHash) const; | ||||
| @@ -166,10 +192,6 @@ public slots: | ||||
| protected: | ||||
|   QString getSavePath(QString hash, bool fromScanDir = false, QString filePath = QString::null, QString root_folder=QString::null); | ||||
|   bool initWebUi(QString username, QString password, int port); | ||||
|   bool loadFastResumeData(QString hash, std::vector<char> &buf); | ||||
|   void loadTorrentSettings(QTorrentHandle h); | ||||
|   void loadTorrentTempData(QTorrentHandle h, QString savePath, bool magnet); | ||||
|   add_torrent_params initializeAddTorrentParams(QString hash); | ||||
|  | ||||
| protected slots: | ||||
|   void addTorrentsFromScanFolder(QStringList&); | ||||
| @@ -181,8 +203,6 @@ protected slots: | ||||
|   void sendNotificationEmail(QTorrentHandle h); | ||||
|   void autoRunExternalProgram(QTorrentHandle h, bool async=true); | ||||
|   void cleanUpAutoRunProcess(int); | ||||
|   void mergeTorrents(QTorrentHandle h_ex, boost::intrusive_ptr<torrent_info> t); | ||||
|   void exportTorrentFile(QTorrentHandle h); | ||||
|  | ||||
| signals: | ||||
|   void addedTorrent(QTorrentHandle& h); | ||||
| @@ -257,8 +277,6 @@ private: | ||||
|   bool geoipDBLoaded; | ||||
|   bool resolve_countries; | ||||
| #endif | ||||
|   // Tracker | ||||
|   QPointer<QTracker> m_tracker; | ||||
|  | ||||
| }; | ||||
|  | ||||
| @@ -31,7 +31,7 @@ | ||||
| #ifndef CONSOLE_H | ||||
| #define CONSOLE_H | ||||
|  | ||||
| #include "qbtsession.h" | ||||
| #include "bittorrent.h" | ||||
| #include "ui_console.h" | ||||
|  | ||||
| using namespace libtorrent; | ||||
| @@ -40,10 +40,10 @@ class consoleDlg : public QDialog, private Ui_ConsoleDlg{ | ||||
|   Q_OBJECT | ||||
|    | ||||
|   private: | ||||
|     QBtSession *BTSession; | ||||
|     Bittorrent *BTSession; | ||||
|    | ||||
|   public: | ||||
|     consoleDlg(QWidget *parent, QBtSession* _BTSession) : QDialog(parent) { | ||||
|     consoleDlg(QWidget *parent, Bittorrent* _BTSession) : QDialog(parent) { | ||||
|       setupUi(this); | ||||
|       setAttribute(Qt::WA_DeleteOnClose); | ||||
|       setModal(true); | ||||
|   | ||||
| @@ -73,8 +73,12 @@ void CookiesDlg::on_del_btn_clicked() { | ||||
| QList<QByteArray> CookiesDlg::getCookies() const { | ||||
|   QList<QByteArray> ret; | ||||
|   for(int i=0; i<ui->cookiesTable->rowCount(); ++i) { | ||||
|     QString key = ui->cookiesTable->item(i, COOKIE_KEY)->text().trimmed(); | ||||
|     QString value = ui->cookiesTable->item(i, COOKIE_VALUE)->text().trimmed(); | ||||
|     QString key; | ||||
|     if(ui->cookiesTable->item(i, COOKIE_KEY)) | ||||
|       key = ui->cookiesTable->item(i, COOKIE_KEY)->text().trimmed(); | ||||
|     QString value; | ||||
|     if(ui->cookiesTable->item(i, COOKIE_VALUE)) | ||||
|       value = ui->cookiesTable->item(i, COOKIE_VALUE)->text().trimmed(); | ||||
|     if(!key.isEmpty() && !value.isEmpty()) { | ||||
|       const QString raw_cookie = key+"="+value; | ||||
|       qDebug("Cookie: %s", qPrintable(raw_cookie)); | ||||
|   | ||||
| @@ -51,7 +51,7 @@ downloadThread::downloadThread(QObject* parent) : QObject(parent) { | ||||
| } | ||||
|  | ||||
| void downloadThread::processDlFinished(QNetworkReply* reply) { | ||||
|   QString url = reply->url().toEncoded().data(); | ||||
|   QString url = reply->url().toString(); | ||||
|   qDebug("Download finished: %s", qPrintable(url)); | ||||
|   if(reply->error() != QNetworkReply::NoError) { | ||||
|     // Failure | ||||
|   | ||||
| @@ -44,7 +44,7 @@ | ||||
| #include <QTemporaryFile> | ||||
|  | ||||
| enum EngineColumns {ENGINE_NAME, ENGINE_URL, ENGINE_STATE, ENGINE_ID}; | ||||
| #define UPDATE_URL "http://qbittorrent.svn.sourceforge.net/viewvc/qbittorrent/trunk/src/search_engine/engines/" | ||||
| #define UPDATE_URL "http://qbittorrent.svn.sourceforge.net/viewvc/qbittorrent/branches/v2_4_x/src/search_engine/engines/" | ||||
|  | ||||
| engineSelectDlg::engineSelectDlg(QWidget *parent, SupportedEngines *supported_engines) : QDialog(parent), supported_engines(supported_engines) { | ||||
|   setupUi(this); | ||||
|   | ||||
| @@ -31,7 +31,7 @@ | ||||
|  | ||||
| #include <libtorrent/version.hpp> | ||||
| #include "eventmanager.h" | ||||
| #include "qbtsession.h" | ||||
| #include "bittorrent.h" | ||||
| #include "scannedfoldersmodel.h" | ||||
| #include "misc.h" | ||||
| #include "preferences.h" | ||||
| @@ -40,7 +40,7 @@ | ||||
| #include <QDebug> | ||||
| #include <QTranslator> | ||||
|  | ||||
| EventManager::EventManager(QObject *parent, QBtSession *BTSession) | ||||
| EventManager::EventManager(QObject *parent, Bittorrent *BTSession) | ||||
|   : QObject(parent), BTSession(BTSession) | ||||
| { | ||||
| } | ||||
| @@ -36,20 +36,20 @@ | ||||
| #include <QHash> | ||||
| #include <QVariant> | ||||
|  | ||||
| class QBtSession; | ||||
| class Bittorrent; | ||||
|  | ||||
| class EventManager : public QObject | ||||
| { | ||||
| 	Q_OBJECT | ||||
| 	private: | ||||
| 		QHash<QString, QVariantMap> event_list; | ||||
|                 QBtSession* BTSession; | ||||
|                 Bittorrent* BTSession; | ||||
|  | ||||
| 	protected: | ||||
| 		void update(QVariantMap event); | ||||
|  | ||||
| 	public: | ||||
|                 EventManager(QObject *parent, QBtSession* BTSession); | ||||
|                 EventManager(QObject *parent, Bittorrent* BTSession); | ||||
|                 QList<QVariantMap> getEventList() const; | ||||
|                 QVariantMap getPropGeneralInfo(QString hash) const; | ||||
|                 QList<QVariantMap> getPropTrackersInfo(QString hash) const; | ||||
							
								
								
									
										221
									
								
								src/feedList.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										221
									
								
								src/feedList.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,221 @@ | ||||
| #ifndef FEEDLIST_H | ||||
| #define FEEDLIST_H | ||||
|  | ||||
| #include <QTreeWidget> | ||||
| #include <QTreeWidgetItem> | ||||
| #include <QDropEvent> | ||||
| #include <QDragMoveEvent> | ||||
| #include <QStringList> | ||||
| #include <QHash> | ||||
| #include <QUrl> | ||||
| #include "rss.h" | ||||
|  | ||||
| class FeedList: public QTreeWidget { | ||||
|   Q_OBJECT | ||||
|  | ||||
| private: | ||||
|   RssManager *rssmanager; | ||||
|   QHash<QTreeWidgetItem*, RssFile*> mapping; | ||||
|   QHash<QString, QTreeWidgetItem*> feeds_items; | ||||
|   QTreeWidgetItem* current_feed; | ||||
|   QTreeWidgetItem *unread_item; | ||||
|  | ||||
| public: | ||||
|   FeedList(QWidget *parent, RssManager *rssmanager): QTreeWidget(parent), rssmanager(rssmanager) { | ||||
|     setContextMenuPolicy(Qt::CustomContextMenu); | ||||
|     setDragDropMode(QAbstractItemView::InternalMove); | ||||
|     setSelectionMode(QAbstractItemView::ExtendedSelection); | ||||
|     setColumnCount(1); | ||||
|     QTreeWidgetItem *___qtreewidgetitem = headerItem(); | ||||
|     ___qtreewidgetitem->setText(0, QApplication::translate("RSS", "RSS feeds", 0, QApplication::UnicodeUTF8)); | ||||
|     unread_item = new QTreeWidgetItem(this); | ||||
|     unread_item->setText(0, tr("Unread") + QString::fromUtf8("  (") + QString::number(rssmanager->getNbUnRead(), 10)+ QString(")")); | ||||
|     unread_item->setData(0,Qt::DecorationRole, QVariant(QIcon(":/Icons/oxygen/mail-folder-inbox.png"))); | ||||
|     itemAdded(unread_item, rssmanager); | ||||
|     connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(updateCurrentFeed(QTreeWidgetItem*))); | ||||
|     setCurrentItem(unread_item); | ||||
|   } | ||||
|  | ||||
|   ~FeedList() { | ||||
|     disconnect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(updateCurrentFeed(QTreeWidgetItem*))); | ||||
|     delete unread_item; | ||||
|   } | ||||
|  | ||||
|   void itemAdded(QTreeWidgetItem *item, RssFile* file) { | ||||
|     mapping[item] = file; | ||||
|     if(file->getType() == RssFile::STREAM) { | ||||
|       feeds_items[file->getID()] = item; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void itemAboutToBeRemoved(QTreeWidgetItem *item) { | ||||
|     RssFile* file = mapping.take(item); | ||||
|     if(file->getType() == RssFile::STREAM) { | ||||
|       feeds_items.remove(file->getID()); | ||||
|     } else { | ||||
|       QList<RssStream*> feeds = ((RssFolder*)file)->getAllFeeds(); | ||||
|       foreach(RssStream* feed, feeds) { | ||||
|         feeds_items.remove(feed->getID()); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   bool hasFeed(QString url) const { | ||||
|     return feeds_items.contains(QUrl(url).toString()); | ||||
|   } | ||||
|  | ||||
|   QList<QTreeWidgetItem*> getAllFeedItems() const { | ||||
|     return feeds_items.values(); | ||||
|   } | ||||
|  | ||||
|   QTreeWidgetItem* getUnreadItem() const { | ||||
|     return unread_item; | ||||
|   } | ||||
|  | ||||
|   QStringList getItemPath(QTreeWidgetItem* item) const { | ||||
|     QStringList path; | ||||
|     if(item) { | ||||
|       if(item->parent()) | ||||
|         path << getItemPath(item->parent()); | ||||
|       path.append(getRSSItem(item)->getID()); | ||||
|     } | ||||
|     return path; | ||||
|   } | ||||
|  | ||||
|   QList<QTreeWidgetItem*> getAllOpenFolders(QTreeWidgetItem *parent=0) const { | ||||
|     QList<QTreeWidgetItem*> open_folders; | ||||
|     int nbChildren; | ||||
|     if(parent) | ||||
|       nbChildren = parent->childCount(); | ||||
|     else | ||||
|       nbChildren = topLevelItemCount(); | ||||
|     for(int i=0; i<nbChildren; ++i) { | ||||
|       QTreeWidgetItem *item; | ||||
|       if(parent) | ||||
|         item = parent->child(i); | ||||
|       else | ||||
|         item = topLevelItem(i); | ||||
|       if(getItemType(item) == RssFile::FOLDER && item->isExpanded()) { | ||||
|         QList<QTreeWidgetItem*> open_subfolders = getAllOpenFolders(item); | ||||
|         if(!open_subfolders.empty()) { | ||||
|           open_folders << open_subfolders; | ||||
|         } else { | ||||
|           open_folders << item; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     return open_folders; | ||||
|   } | ||||
|  | ||||
|   QList<QTreeWidgetItem*> getAllFeedItems(QTreeWidgetItem* folder) { | ||||
|     QList<QTreeWidgetItem*> feeds; | ||||
|     int nbChildren = folder->childCount(); | ||||
|     for(int i=0; i<nbChildren; ++i) { | ||||
|       QTreeWidgetItem *item = folder->child(i); | ||||
|       if(getItemType(item) == RssFile::STREAM) { | ||||
|         feeds << item; | ||||
|       } else { | ||||
|         feeds << getAllFeedItems(item); | ||||
|       } | ||||
|     } | ||||
|     return feeds; | ||||
|   } | ||||
|  | ||||
|   RssFile* getRSSItem(QTreeWidgetItem *item) const { | ||||
|     return mapping.value(item, 0); | ||||
|   } | ||||
|  | ||||
|   RssFile::FileType getItemType(QTreeWidgetItem *item) const { | ||||
|     return mapping.value(item)->getType(); | ||||
|   } | ||||
|  | ||||
|   QString getItemID(QTreeWidgetItem *item) const { | ||||
|     return mapping.value(item)->getID(); | ||||
|   } | ||||
|  | ||||
|   QTreeWidgetItem* getTreeItemFromUrl(QString url) const{ | ||||
|     return feeds_items.value(url, 0); | ||||
|   } | ||||
|  | ||||
|   RssStream* getRSSItemFromUrl(QString url) const { | ||||
|     return (RssStream*)getRSSItem(getTreeItemFromUrl(url)); | ||||
|   } | ||||
|  | ||||
|   QTreeWidgetItem* currentItem() const { | ||||
|     return current_feed; | ||||
|   } | ||||
|  | ||||
|   QTreeWidgetItem* currentFeed() const { | ||||
|     return current_feed; | ||||
|   } | ||||
|  | ||||
| signals: | ||||
|   void foldersAltered(QList<QTreeWidgetItem*> folders); | ||||
|   void overwriteAttempt(QString filename); | ||||
|  | ||||
| protected slots: | ||||
|   void updateCurrentFeed(QTreeWidgetItem* new_item) { | ||||
|     if(!new_item) return; | ||||
|     if(!mapping.contains(new_item)) return; | ||||
|     if((getItemType(new_item) == RssFile::STREAM) || new_item == unread_item) | ||||
|       current_feed = new_item; | ||||
|   } | ||||
|  | ||||
| protected: | ||||
|   void dragMoveEvent(QDragMoveEvent * event) { | ||||
|     QTreeWidgetItem *item = itemAt(event->pos()); | ||||
|     if(item == unread_item) { | ||||
|       event->ignore(); | ||||
|     } else { | ||||
|       if(item && getItemType(item) != RssFile::FOLDER) | ||||
|         event->ignore(); | ||||
|       else { | ||||
|         if(selectedItems().contains(unread_item)) { | ||||
|           event->ignore(); | ||||
|         } else { | ||||
|           QTreeWidget::dragMoveEvent(event); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void dropEvent(QDropEvent *event) { | ||||
|     qDebug("dropEvent"); | ||||
|     QList<QTreeWidgetItem*> folders_altered; | ||||
|     QTreeWidgetItem *dest_folder_item =  itemAt(event->pos()); | ||||
|     RssFolder *dest_folder; | ||||
|     if(dest_folder_item) { | ||||
|       dest_folder = (RssFolder*)getRSSItem(dest_folder_item); | ||||
|       folders_altered << dest_folder_item; | ||||
|     } else { | ||||
|       dest_folder = rssmanager; | ||||
|     } | ||||
|     QList<QTreeWidgetItem *> src_items = selectedItems(); | ||||
|     // Check if there is not going to overwrite another file | ||||
|     foreach(QTreeWidgetItem *src_item, src_items) { | ||||
|       RssFile *file = getRSSItem(src_item); | ||||
|       if(dest_folder->hasChild(file->getID())) { | ||||
|         emit overwriteAttempt(file->getID()); | ||||
|         return; | ||||
|       } | ||||
|     } | ||||
|     // Proceed with the move | ||||
|     foreach(QTreeWidgetItem *src_item, src_items) { | ||||
|       QTreeWidgetItem *parent_folder = src_item->parent(); | ||||
|       if(parent_folder && !folders_altered.contains(parent_folder)) | ||||
|         folders_altered << parent_folder; | ||||
|       // Actually move the file | ||||
|       RssFile *file = getRSSItem(src_item); | ||||
|       rssmanager->moveFile(file, dest_folder); | ||||
|     } | ||||
|     QTreeWidget::dropEvent(event); | ||||
|     if(dest_folder_item) | ||||
|       dest_folder_item->setExpanded(true); | ||||
|     // Emit signal for update | ||||
|     if(!folders_altered.empty()) | ||||
|       emit foldersAltered(folders_altered); | ||||
|   } | ||||
|  | ||||
| }; | ||||
|  | ||||
| #endif // FEEDLIST_H | ||||
							
								
								
									
										514
									
								
								src/feeddownloader.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										514
									
								
								src/feeddownloader.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -3,11 +3,12 @@ | ||||
|  | ||||
| #include <QFileSystemWatcher> | ||||
| #include <QDir> | ||||
|  | ||||
| #ifndef Q_WS_WIN | ||||
| #include <QTimer> | ||||
| #include <QPointer> | ||||
| #include <QStringList> | ||||
| #include <QTimer> | ||||
| #include <QHash> | ||||
|  | ||||
| #ifndef Q_WS_WIN | ||||
| #include <QSet> | ||||
| #include <iostream> | ||||
| #include <errno.h> | ||||
| @@ -19,6 +20,8 @@ | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| #include "misc.h" | ||||
|  | ||||
| #ifndef CIFS_MAGIC_NUMBER | ||||
| #define CIFS_MAGIC_NUMBER 0xFF534D42 | ||||
| #endif | ||||
| @@ -27,6 +30,9 @@ | ||||
| #define NFS_SUPER_MAGIC 0x6969 | ||||
| #endif | ||||
|  | ||||
| const int WATCH_INTERVAL = 10000; // 10 sec | ||||
| const int MAX_PARTIAL_RETRIES = 5; | ||||
|  | ||||
| /* | ||||
|  * Subclassing QFileSystemWatcher in order to support Network File | ||||
|  * System watching (NFS, CIFS) on Linux and Mac OS. | ||||
| @@ -39,11 +45,14 @@ private: | ||||
|   QList<QDir> watched_folders; | ||||
|   QPointer<QTimer> watch_timer; | ||||
| #endif | ||||
|   QStringList filters; | ||||
|   QStringList m_filters; | ||||
|   // Partial torrents | ||||
|   QHash<QString, int> m_partialTorrents; | ||||
|   QPointer<QTimer> m_partialTorrentTimer; | ||||
|  | ||||
| #ifndef Q_WS_WIN | ||||
| protected: | ||||
|   bool isNetworkFileSystem(QString path) { | ||||
| private: | ||||
|   static bool isNetworkFileSystem(QString path) { | ||||
|     QString file = path; | ||||
|     if(!file.endsWith(QDir::separator())) | ||||
|       file += QDir::separator(); | ||||
| @@ -99,7 +108,7 @@ protected: | ||||
|  | ||||
| public: | ||||
|   FileSystemWatcher(QObject *parent): QFileSystemWatcher(parent) { | ||||
|     filters << "*.torrent"; | ||||
|     m_filters << "*.torrent"; | ||||
|     connect(this, SIGNAL(directoryChanged(QString)), this, SLOT(scanLocalFolder(QString))); | ||||
|   } | ||||
|  | ||||
| @@ -108,6 +117,8 @@ public: | ||||
|     if(watch_timer) | ||||
|       delete watch_timer; | ||||
| #endif | ||||
|     if(m_partialTorrentTimer) | ||||
|       delete m_partialTorrentTimer; | ||||
|   } | ||||
|  | ||||
|   QStringList directories() const { | ||||
| @@ -137,7 +148,7 @@ public: | ||||
|       if (!watch_timer) { | ||||
|         watch_timer = new QTimer(this); | ||||
|         connect(watch_timer, SIGNAL(timeout()), this, SLOT(scanNetworkFolders())); | ||||
|         watch_timer->start(5000); // 5 sec | ||||
|         watch_timer->start(WATCH_INTERVAL); // 5 sec | ||||
|       } | ||||
|     } else { | ||||
| #endif | ||||
| @@ -196,21 +207,74 @@ protected slots: | ||||
| #endif | ||||
|   } | ||||
|  | ||||
|   void processPartialTorrents() { | ||||
|     QStringList no_longer_partial; | ||||
|  | ||||
|     // Check which torrents are still partial | ||||
|     foreach(const QString& torrent_path, m_partialTorrents.keys()) { | ||||
|       if(!QFile::exists(torrent_path)) { | ||||
|         m_partialTorrents.remove(torrent_path); | ||||
|         continue; | ||||
|       } | ||||
|       if(misc::isValidTorrentFile(torrent_path)) { | ||||
|         no_longer_partial << torrent_path; | ||||
|          m_partialTorrents.remove(torrent_path); | ||||
|       } else { | ||||
|         if(m_partialTorrents[torrent_path] >= MAX_PARTIAL_RETRIES) { | ||||
|           m_partialTorrents.remove(torrent_path); | ||||
|           QFile::rename(torrent_path, torrent_path+".invalid"); | ||||
|         } else { | ||||
|           m_partialTorrents[torrent_path]++; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Stop the partial timer if necessary | ||||
|     if(m_partialTorrents.empty()) { | ||||
|       m_partialTorrentTimer->stop(); | ||||
|       m_partialTorrentTimer->deleteLater(); | ||||
|       qDebug("No longer any partial torrent."); | ||||
|     } else { | ||||
|       qDebug("Still %d partial torrents after delayed processing.", m_partialTorrents.count()); | ||||
|       m_partialTorrentTimer->start(WATCH_INTERVAL); | ||||
|     } | ||||
|     // Notify of new torrents | ||||
|     if(!no_longer_partial.isEmpty()) | ||||
|       emit torrentsAdded(no_longer_partial); | ||||
|   } | ||||
|  | ||||
| signals: | ||||
|   void torrentsAdded(QStringList &pathList); | ||||
|  | ||||
| private: | ||||
|   void addTorrentsFromDir(const QDir &dir, QStringList &torrents) { | ||||
|     const QStringList files = dir.entryList(filters, QDir::Files, QDir::Unsorted); | ||||
|     foreach(const QString &file, files) { | ||||
| #if defined(Q_WS_WIN) || defined(Q_OS_OS2) | ||||
|       torrents << dir.absoluteFilePath(file).replace("/", "\\"); | ||||
| #else | ||||
|       torrents << dir.absoluteFilePath(file); | ||||
| #endif | ||||
|   void startPartialTorrentTimer() { | ||||
|     Q_ASSERT(!m_partialTorrents.isEmpty()); | ||||
|     if(!m_partialTorrentTimer) { | ||||
|       m_partialTorrentTimer = new QTimer(); | ||||
|       connect(m_partialTorrentTimer, SIGNAL(timeout()), SLOT(processPartialTorrents())); | ||||
|       m_partialTorrentTimer->setSingleShot(true); | ||||
|       m_partialTorrentTimer->start(WATCH_INTERVAL); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void addTorrentsFromDir(const QDir &dir, QStringList &torrents) { | ||||
|     const QStringList files = dir.entryList(m_filters, QDir::Files, QDir::Unsorted); | ||||
|     foreach(const QString &file, files) { | ||||
|       const QString file_abspath = dir.absoluteFilePath(file); | ||||
|       if(misc::isValidTorrentFile(file_abspath)) { | ||||
|         torrents << file_abspath; | ||||
|       } else { | ||||
|         if(!m_partialTorrents.contains(file_abspath)) { | ||||
|           qDebug("Partial torrent detected at: %s", qPrintable(file_abspath)); | ||||
|           qDebug("Delay the file's processing..."); | ||||
|           m_partialTorrents.insert(file_abspath, 0); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     if(!m_partialTorrents.empty()) | ||||
|       startPartialTorrentTimer(); | ||||
|   } | ||||
|  | ||||
| }; | ||||
|  | ||||
| #endif // FILESYSTEMWATCHER_H | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -34,7 +34,7 @@ | ||||
| #include <QObject> | ||||
| #include <QCoreApplication> | ||||
| #include "preferences.h" | ||||
| #include "qbtsession.h" | ||||
| #include "bittorrent.h" | ||||
|  | ||||
| class HeadlessLoader: public QObject { | ||||
|   Q_OBJECT | ||||
| @@ -44,7 +44,7 @@ public: | ||||
|     // Enable Web UI | ||||
|     Preferences::setWebUiEnabled(true); | ||||
|     // Instanciate Bittorrent Object | ||||
|     BTSession = new QBtSession(); | ||||
|     BTSession = new Bittorrent(); | ||||
|     connect(BTSession, SIGNAL(newConsoleMessage(QString)), this, SLOT(displayConsoleMessage(QString))); | ||||
|     // Resume unfinished torrents | ||||
|     BTSession->startUpTorrents(); | ||||
| @@ -103,7 +103,7 @@ public slots: | ||||
|   } | ||||
|  | ||||
| private: | ||||
|   QBtSession *BTSession; | ||||
|   Bittorrent *BTSession; | ||||
|  | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -34,7 +34,7 @@ | ||||
| #include "eventmanager.h" | ||||
| #include "preferences.h" | ||||
| #include "json.h" | ||||
| #include "qbtsession.h" | ||||
| #include "bittorrent.h" | ||||
| #include "misc.h" | ||||
| #include <QTcpSocket> | ||||
| #include <QDateTime> | ||||
| @@ -46,8 +46,8 @@ | ||||
| #include <QRegExp> | ||||
| #include <QTemporaryFile> | ||||
|  | ||||
| HttpConnection::HttpConnection(QTcpSocket *socket, QBtSession *BTSession, HttpServer *parent) | ||||
|   : QObject(parent), socket(socket), parent(parent), BTSession(BTSession) | ||||
| HttpConnection::HttpConnection(QTcpSocket *socket, Bittorrent *BTSession, HttpServer *parent) | ||||
|     : QObject(parent), socket(socket), parent(parent), BTSession(BTSession) | ||||
| { | ||||
|   socket->setParent(this); | ||||
|   connect(socket, SIGNAL(readyRead()), this, SLOT(read())); | ||||
| @@ -231,13 +231,10 @@ void HttpConnection::respond() { | ||||
|       return; | ||||
|     } | ||||
|   } | ||||
|   if (list[0] == "images") { | ||||
|   if (list[0] == "images") | ||||
|     list[0] = "Icons"; | ||||
|   } else { | ||||
|     if(list.last().endsWith(".html")) | ||||
|       list.prepend("html"); | ||||
|   else | ||||
|     list.prepend("webui"); | ||||
|   } | ||||
|   url = ":/" + list.join("/"); | ||||
|   QFile file(url); | ||||
|   if(!file.open(QIODevice::ReadOnly)) | ||||
| @@ -38,7 +38,7 @@ | ||||
|  | ||||
| class QTcpSocket; | ||||
| class HttpServer; | ||||
| class QBtSession; | ||||
| class Bittorrent; | ||||
|  | ||||
| class HttpConnection : public QObject | ||||
| { | ||||
| @@ -46,7 +46,7 @@ class HttpConnection : public QObject | ||||
| 	private: | ||||
| 		QTcpSocket *socket; | ||||
| 		HttpServer *parent; | ||||
|                 QBtSession *BTSession; | ||||
|                 Bittorrent *BTSession; | ||||
|  | ||||
| 	protected: | ||||
| 		HttpRequestParser parser; | ||||
| @@ -54,7 +54,7 @@ class HttpConnection : public QObject | ||||
|  | ||||
| 	protected slots: | ||||
| 		void write(); | ||||
| 		virtual void respond(); | ||||
| 		void respond(); | ||||
| 		void respondJson(); | ||||
|                 void respondGenPropertiesJson(QString hash); | ||||
|                 void respondTrackersPropertiesJson(QString hash); | ||||
| @@ -69,7 +69,7 @@ class HttpConnection : public QObject | ||||
|                 void recheckAllTorrents(); | ||||
|  | ||||
| 	public: | ||||
|                 HttpConnection(QTcpSocket *socket, QBtSession* BTSession, HttpServer *parent); | ||||
|                 HttpConnection(QTcpSocket *socket, Bittorrent* BTSession, HttpServer *parent); | ||||
| 		~HttpConnection(); | ||||
|                 QString translateDocument(QString data); | ||||
|  | ||||
| @@ -68,12 +68,12 @@ QByteArray HttpRequestParser::message() const | ||||
|  | ||||
| QString HttpRequestParser::get(const QString key) const | ||||
| { | ||||
|         return getMap.value(key); | ||||
| 	return getMap[key]; | ||||
| } | ||||
|  | ||||
| QString HttpRequestParser::post(const QString key) const | ||||
| { | ||||
|         return postMap.value(key); | ||||
| 	return postMap[key]; | ||||
| } | ||||
|  | ||||
| QByteArray HttpRequestParser::torrent() const | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user