Compare commits
	
		
			78 Commits
		
	
	
		
			release-2.
			...
			release-2.
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | b46d8934ed | ||
|   | 493b537215 | ||
|   | fae08f7014 | ||
|   | 31d65ddf77 | ||
|   | 4cd9cfdb59 | ||
|   | 8d55368f6a | ||
|   | 2a07fc0dea | ||
|   | be6099a797 | ||
|   | b131b139f7 | ||
|   | c40455dbbf | ||
|   | 75f0d86710 | ||
|   | 33447bf9fb | ||
|   | a9365bc126 | ||
|   | f54b65a56d | ||
|   | f9abbea1cc | ||
|   | c267f6911d | ||
|   | dd51d39f5b | ||
|   | a3e90e1c05 | ||
|   | 6bd1d2551b | ||
|   | cf0c359abf | ||
|   | 461cca2f52 | ||
|   | 1ee45151a1 | ||
|   | 772f05c5d4 | ||
|   | de9e215404 | ||
|   | eeabf85e3b | ||
|   | 6b99c84fe3 | ||
|   | 7d42969505 | ||
|   | 90351c4a57 | ||
|   | 492b9dc88f | ||
|   | c9a8c1d053 | ||
|   | c8fdf8dc10 | ||
|   | 119f83fbf0 | ||
|   | e8db20a558 | ||
|   | 508a811a8a | ||
|   | 296267ec20 | ||
|   | 39d4af1d6e | ||
|   | 2e8f50b709 | ||
|   | fdccf9cc1c | ||
|   | 31819e148f | ||
|   | 5371fb15f8 | ||
|   | f845acb207 | ||
|   | f42eec5ad9 | ||
|   | ec1a06d7c8 | ||
|   | e9b6a726e3 | ||
|   | a3f54fc3b9 | ||
|   | 10f58b4eed | ||
|   | 52fef5ac38 | ||
|   | 4d0cdea1c9 | ||
|   | 86ca755dfe | ||
|   | 659664509a | ||
|   | 412f947db5 | ||
|   | ad47565b93 | ||
|   | 89175ea827 | ||
|   | 8dc34463e3 | ||
|   | cab38857d1 | ||
|   | 14db21c241 | ||
|   | 975ab9ad64 | ||
|   | b810278452 | ||
|   | 86ac0a430e | ||
|   | 78a0f34645 | ||
|   | 3ae09658c9 | ||
|   | 7d9caad31e | ||
|   | c9c627dec2 | ||
|   | 5b104cdd9b | ||
|   | 8f667dce5c | ||
|   | 89412e5050 | ||
|   | 63c121ecc7 | ||
|   | 33b60779d6 | ||
|   | 26b2367833 | ||
|   | 9b40a036a7 | ||
|   | d4cc0e9e4a | ||
|   | ca802a6233 | ||
|   | 35394c4966 | ||
|   | 077dd11af6 | ||
|   | a5c9c8d670 | ||
|   | 1ef0bcbc06 | ||
|   | e15eab9b6a | ||
|   | 8f1c56babd | 
							
								
								
									
										14
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						| @@ -3,19 +3,11 @@ Author: | |||||||
|  |  | ||||||
| Contributors: | Contributors: | ||||||
| * Stefanos Antaris <santaris@csd.auth.gr> | * Stefanos Antaris <santaris@csd.auth.gr> | ||||||
| * Mohammad Dib <mdib@qbittorrent.org> |  | ||||||
| * Mirco Chinelli <infinity89@fastwebmail.it> |  | ||||||
| * Ishan Arora <ishan@qbittorrent.org> | * Ishan Arora <ishan@qbittorrent.org> | ||||||
| * Arnaud Demaizière <arnaud@qbittorrent.org> | * Arnaud Demaizière <arnaud@qbittorrent.org> | ||||||
| * Grigis Gaëtan <cipher16@gmail.com> | * Grigis Gaëtan <cipher16@gmail.com> | ||||||
| * Christian Kandeler <zambesi@users.sourceforge.net> |  | ||||||
| * Silvan Scherrer <silvan.scherrer@aroa.ch> |  | ||||||
|  |  | ||||||
| Code from other projects: | Code from other projects: | ||||||
| * files src/qtsingleapp/* |  | ||||||
|   copyright: Nokia Corporation |  | ||||||
|   license: LGPL |  | ||||||
|  |  | ||||||
| * files src/ico.cpp src/ico.h | * files src/ico.cpp src/ico.h | ||||||
|   copyright: Malte Starostik <malte@kde.org> |   copyright: Malte Starostik <malte@kde.org> | ||||||
|   license: LGPL |   license: LGPL | ||||||
| @@ -67,13 +59,11 @@ Images Authors: | |||||||
| Translations authors: | Translations authors: | ||||||
| * files: src/lang/*.ts | * files: src/lang/*.ts | ||||||
|   copyright: |   copyright: | ||||||
|   - Arabic: SDERAWI (abz8868@msn.com) and sn51234 (nesseyan@gmail.com) |  | ||||||
|   - Brazilian: Nick Marinho (nickmarinho@gmail.com) |   - Brazilian: Nick Marinho (nickmarinho@gmail.com) | ||||||
|   - Bulgarian: Tsvetan & Boyko Bankoff (emerge_life@users.sourceforge.net) |   - Bulgarian: Tsvetan & Boiko Bankov (emerge_life@users.sourceforge.net) | ||||||
|   - Catalan: Francisco Luque Contreras (frannoe@ya.com) |   - Catalan: Francisco Luque Contreras (frannoe@ya.com) | ||||||
|   - Chinese (Simplified): Guo Yue (yue.guo0418@gmail.com) |   - Chinese (Simplified): Guo Yue (yue.guo0418@gmail.com) | ||||||
|   - Chinese (Traditional): Yi-Shun Wang (dnextstep@gmail.com) |   - Chinese (Traditional): Yi-Shun Wang (dnextstep@gmail.com) | ||||||
|   - Croatian: Oliver Mucafir (oliver.untwist@gmail.com) |  | ||||||
|   - Czech: Jirka Vilim (web@tets.cz) |   - Czech: Jirka Vilim (web@tets.cz) | ||||||
|   - Danish: Mathias Nielsen (comoneo@gmail.com) |   - Danish: Mathias Nielsen (comoneo@gmail.com) | ||||||
|   - Dutch: Joost Schipper (heavyjoost@users.sourceforge.net) |   - Dutch: Joost Schipper (heavyjoost@users.sourceforge.net) | ||||||
| @@ -96,5 +86,5 @@ Translations authors: | |||||||
|   - Spanish: Francisco Luque Contreras (frannoe@ya.com) |   - Spanish: Francisco Luque Contreras (frannoe@ya.com) | ||||||
|   - Swedish: Daniel Nylander (po@danielnylander.se) |   - Swedish: Daniel Nylander (po@danielnylander.se) | ||||||
|   - Turkish: Hasan Yilmaz (iletisim@hedefturkce.com) |   - Turkish: Hasan Yilmaz (iletisim@hedefturkce.com) | ||||||
|   - Ukrainian: Andrey Shpachenko (masterfix@users.sourceforge.net) and Oleh Prypin (blaxpirit@gmail.com) |   - Ukrainian: Andrey Shpachenko (masterfix@users.sourceforge.net) | ||||||
|   license: GPLv2 |   license: GPLv2 | ||||||
|   | |||||||
							
								
								
									
										185
									
								
								Changelog
									
									
									
									
									
								
							
							
						
						| @@ -1,132 +1,61 @@ | |||||||
| * Wed Jul 21 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.2.11 | * Thu Mar 4 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.1.6 | ||||||
|     - BUGFIX: Fix parsing of program arguments with spaces |     - BUGFIX: Fix Web UI authentication with Konqueror | ||||||
|     - BUGFIX: Fix possible crash when using alternative speed limits (#598272) |     - BUGFIX: Fix save path display in properties | ||||||
|     - BUGFIX: Fix possible crash on exit when using |     - BUGFIX: Fix ratio calculation for directly seeded torrents (Thanks phorane) | ||||||
|     - BUGFIX: Require GTK+ headers on compilation when libnotify is used |     - BUGFIX: Fix memory leak in RSS parser | ||||||
|     - BUGFIX: Added configure flag to avoid using the shipped qtsingleapplication |  | ||||||
|  |  | ||||||
| * Wed Jun 23 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.2.10 |  | ||||||
|     - BUGFIX: Fix Web UI in qBittorrent nox version |  | ||||||
|     - BUGFIX: Improved ETA display (more user friendly) |  | ||||||
|     - BUGFIX: Fix possible compilation errors with libtorrent v0.15 |  | ||||||
|     - BUGFIX: Fix minor issues in torrent creation tool |  | ||||||
|     - BUGFIX: Use checkable actions to avoid issues on systems hiding menu icons (e.g. recent Gnome) |  | ||||||
|     - BUGFIX: Use busy cursor for search plugin updates |  | ||||||
|     - BUGFIX: Free disk space calculation now works if destination folder does not exist |  | ||||||
|     - BUGFIX: Fix "append .!qB extension to incomplete files" feature |  | ||||||
|     - BUGFIX: Several OS/2 fixes by Silvan Scherrer |  | ||||||
|     - COSMETIC: Display "Alternative speed limits" button as pressed when enabled |  | ||||||
|  |  | ||||||
| * Sun Jun 13 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.2.9 |  | ||||||
|     - FEATURE: Official support for Win32 platform |  | ||||||
|     - FEATURE: Better integration with Mac OS |  | ||||||
|     - BUGFIX: Fix torrent availability computation (closes #587337) |  | ||||||
|     - BUGFIX: Disable torrent addition dialog as a default |  | ||||||
|     - BUGFIX: Fix Web UI authentication with Opera Browser |  | ||||||
|     - BUGFIX: Fix Javascript error in Web UI when using IE |  | ||||||
|     - BUGFIX: Fix a lot of encoding problems on non UTF-8 systems |  | ||||||
|     - BUGFIX: Fix race condition allowing to run multiple instances (closes #286968) |  | ||||||
|     - BUGFIX: Fix window hiding problem when having a modal window (closes #589070) |  | ||||||
|  |  | ||||||
| * Mon May 24 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.2.8 |  | ||||||
|     - BUGFIX: ETA for finished torrent is now 0 instead of Infinite (closes #583704) |  | ||||||
|     - BUGFIX: Fix sorting of ETA column when having infinite values (closes #583347) |  | ||||||
|     - BUGFIX: Torrent queue position now starts at 1 (closes #581130) |  | ||||||
|     - BUGFIX: Fix unicode issue in start seeding after torrent creation code |  | ||||||
|     - BUGFIX: Fix torrent error state clearance on resuming |  | ||||||
|     - BUGFIX: Fix possible checkbox update in Web UI |  | ||||||
|     - COSMETIC: Fix torrent properties layout |  | ||||||
|  |  | ||||||
| * Wed May 12 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.2.7 |  | ||||||
|     - BUGFIX: Fix unicode problem in torrent moving code |  | ||||||
|     - BUGFIX: Fix possible initialization problem in Web UI |  | ||||||
|     - BUGFIX: Fix torrent moving after completion feature |  | ||||||
|     - BUGFIX: Improved empty folder removing code |  | ||||||
|     - BUGFIX: Use guid or news url as RSS items identifier (instead of title) |  | ||||||
|     - BUGFIX: Fix possible crash in RSS item selection code |  | ||||||
|     - BUGFIX: Added support for url encoded ampersands in RSS |  | ||||||
|     - COSMETIC: Sort torrent labels in popup menu |  | ||||||
|     - I18N: Added Croatian translation |  | ||||||
|  |  | ||||||
| * Sun Apr 18 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.2.6 |  | ||||||
|     - BUGFIX: Announce to all trackers at once |  | ||||||
|     - BUGFIX: Added support for single-thread boost |  | ||||||
|     - BUGFIX: Remove old folder when moving a torrent |  | ||||||
|     - BUGFIX: Improved reliability of torrent moving |  | ||||||
|     - BUGFIX: Stop rechecking torrents when they are moved |  | ||||||
|     - BUGFIX: Status filters height stays correct when the visual style changes |  | ||||||
|     - I18N: Added Arabic translation |  | ||||||
|  |  | ||||||
| * Wed Apr 07 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.2.5 |  | ||||||
|     - BUGFIX: Fix crash when adding a new torrent label |  | ||||||
|     - BUGFIX: Fix HTTPS protocol support in torrent/rss downloader |  | ||||||
|     - BUGFIX: Fix default width of file name column in torrent content |  | ||||||
|     - BUGFIX: Fix torrent addition dialog buttons height |  | ||||||
|     - BUGFIX: Fix deprecation warnings with libtorrent v0.15 |  | ||||||
|     - BUGFIX: Fix "Download from URL" title size in Web UI |  | ||||||
|     - BUGFIX: Fix transparency of speed limits icons |  | ||||||
|     - BUGFIX: Dropped dependency on Qt gif library |  | ||||||
|     - BUGFIX: Improved libboost detection by configure file |  | ||||||
|     - BUGFIX: Bring back compatibility with boost v1.34 |  | ||||||
|     - COSMETIC: Added icons to menu actions in Web UI |  | ||||||
|  |  | ||||||
| * Tue Apr 06 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.2.4 |  | ||||||
|     - BUGFIX: Fix possible crash when adding a torrent |  | ||||||
|     - BUGFIX: Fix failure to remember some torrents on startup |  | ||||||
|     - BUGFIX: Fix torrent addition window layout (torrent content not expanding) |  | ||||||
|     - BUGFIX: Fix about dialog in Web UI |  | ||||||
|     - BUGFIX: Correctly clear trackers error messages once they work |  | ||||||
|     - BUGFIX: Display correct share ratio for paused torrents |  | ||||||
|     - COSMETIC: Improved alternative speed limits icons |  | ||||||
|  |  | ||||||
| * Sun Apr 04 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.2.3 |  | ||||||
|     - BUGFIX: Fix possible crash when deleting a torrent just after pausing it |  | ||||||
|     - BUGFIX: Enable Apply button when alternative rate limits are changed |  | ||||||
|     - BUGFIX: Source compatibility with Windows (Thanks Ishan Arora) |  | ||||||
|     - BUGFIX: Source compatibility with eCS (OS/2) (Thanks Silvan Scherrer) |  | ||||||
|     - BUGFIX: Cleaner binutils gold linker support |  | ||||||
|     - BUGFIX: Clean fix for progress display with cleanlooks style |  | ||||||
|  |  | ||||||
| * Mon Mar 22 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.2.2 |  | ||||||
|     - FEATURE: DHT port can be set from Web UI |  | ||||||
|     - BUGFIX: Fix possible crash with folder scanning |  | ||||||
|     - BUGFIX: Fix Mac compilation |  | ||||||
|     - BUGFIX: Save fast resume data every 3 minutes (for robustness) |  | ||||||
|     - I18N: Updated Polish translation (thanks Szymon Świerkosz) |  | ||||||
|  |  | ||||||
| * Sat Mar 20 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.2.1 |  | ||||||
|     - FEATURE: Display pieces that are being downloaded |  | ||||||
|     - FEATURE: Added back folder watching in Web UI |  | ||||||
|     - FEATURE: Added back file prioritizing in Web UI |  | ||||||
|     - BUGFIX: Fix compilation with Qt 4.4 |  | ||||||
|     - BUGFIX: Fix Web UI compatibility with Safari |  | ||||||
|     - BUGFIX: Fix progress display with cleanlook style |  | ||||||
|     - BUGFIX: Fix file filtering in complex torrents |  | ||||||
|     - BUGFIX: Ask for user confirmation for recursive torrent download |  | ||||||
|     - BUGFIX: Fix "add file" dialog in torrent creation tool |  | ||||||
|     - BUGFIX: Fix "Ctrl+A" in Web UI |  | ||||||
|  |  | ||||||
| * Sun Mar 14 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.2.0 |  | ||||||
|     - FEATURE: User can set alternative speed limits for fast toggling |  | ||||||
|     - FEATURE: Bandwidth scheduler (automatically use alternative speed limits for a given period) |  | ||||||
|     - FEATURE: Added "Added/Completed On" columns to transfer list |  | ||||||
|     - FEATURE: Added "Upload/Download limit" columns to transfer list |  | ||||||
|     - FEATURE: Torrent files can be exported to a given directory |  | ||||||
|     - FEATURE: Outgoing ports range can be customized (for QoS) |  | ||||||
|     - FEATURE: User can choose to apply transfer limits on LAN too |  | ||||||
|     - FEATURE: User can choose to include the protocol overhead in transfer limits |  | ||||||
|     - FEATURE: Torrents can be automatically rechecked on completion |  | ||||||
|     - FEATURE: If 2 torrents have the same hash, add new trackers/URL seeds to the existing torrent |  | ||||||
|     - FEATURE: Trackers can be added from Web UI |  | ||||||
|     - FEATURE: Global transfer information are displayed in the new Web UI status bar |  | ||||||
|     - FEATURE: Allow to change the priority of several files at once |  | ||||||
|     - FEATURE: Support for multiple scan folders (Patch by Christian Kandeler) |  | ||||||
|     - BUGFIX: Only one log window can be opened at a time |     - BUGFIX: Only one log window can be opened at a time | ||||||
|     - BUGFIX: Optimized RSS module memory usage |     - BUGFIX: Command-line parameters are no longer required to be in UTF-8 | ||||||
|     - BUGFIX: Consider HTTP downloads >1MB as invalid .torrent files and abort |  | ||||||
|     - BUGFIX: Fix Web UI authentication with some browsers | * Web Feb 10 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.1.5 | ||||||
|     - BUGFIX: Set Web UI ban period to 1 hour |     - BUGFIX: Fix actions on selected torrents (non-selected torrents could be affected) | ||||||
|     - COSMETIC: Improved style management |     - BUGFIX: Only one program preferences dialog is allowed at a time | ||||||
|  |     - BUGFIX: Link against boost and ssl to fix issues with gold linker | ||||||
|  |     - BUGFIX: Fix memory leak in RSS | ||||||
|  |     - BUGFIX: Improved HTTP gzip compression detection in downloader | ||||||
|  |     - BUGFIX: Fix possible race condition in search engine | ||||||
|  |  | ||||||
|  | * Mon Feb 8 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.1.4 | ||||||
|  |     - BUGFIX: Fix file prioritizing in a torrent | ||||||
|  |     - BUGFIX: Make sure seeding torrents display a progress of 100% | ||||||
|  |     - BUGFIX: Usage display was improved and localized (--help) | ||||||
|  |     - BUGFIX: Fix possible crash when deleting a torrent | ||||||
|  |     - BUGFIX: Fix possible crash when changing torrents label | ||||||
|  |  | ||||||
|  | * Sun Jan 31 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.1.3 | ||||||
|  |     - BUGFIX: Fix "Append .!qB extension to complete files" (libtorrent v0.15) | ||||||
|  |     - BUGFIX: Make sure bandwidth limiting dialogs are centered on screen | ||||||
|  |     - BUGFIX: Added support for HTTP redirection | ||||||
|  |     - BUGFIX: Fix compilation error when geoip database is embedded | ||||||
|  |     - BUGFIX: Fix crash when double-clicking on a torrent that has no metadata to open its save path | ||||||
|  |     - BUGFIX: Fix Scan directory preferences in Web UI | ||||||
|  |     - BUGFIX: Clear torrent error state when resuming it | ||||||
|  |  | ||||||
|  | * Sun Jan 24 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.1.2 | ||||||
|  |     - FEATURE: Added back file prioritizing in a torrent | ||||||
|  |     - BUGFIX: Fix issue causing torrents not to be displayed in the list | ||||||
|  |     - BUGFIX: Make sure invalid torrent are removed from the transfer list | ||||||
|  |     - BUGFIX: Fix overwrite check when renaming a folder in a torrent | ||||||
|  |     - BUGFIX: Force a recheck after renaming files to avoid overwriting | ||||||
|  |     - BUGFIX: Improve "Open destination folder" behavior | ||||||
|  |     - BUGFIX: Fix race condition in RSS that could cause a crash on startup | ||||||
|  |     - BUGFIX: Improved user friendlyness of size units | ||||||
|  |     - BUGFIX: Optimized transfer list repainting | ||||||
|  |     - COSMETIC: Improved transfer speed display in peers list | ||||||
|  |  | ||||||
|  | * Wed Jan 20 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.1.1 | ||||||
|  |     - BUGFIX: Fix compilation with Qt4.4 | ||||||
|  |     - BUGFIX: Save torrent metadata so that it does not have to be re-downloaded on restart (Magnet links) | ||||||
|  |     - BUGFIX: Fix folder renaming in a torrent (would rename children under certain conditions) | ||||||
|  |     - BUGFIX: Nox version no longer requires libQtXml | ||||||
|  |     - BUGFIX: Configure file now checks for pkg-config executable which is required | ||||||
|  |     - BUGFIX: Torrents added from magnet links were not remembered on restart | ||||||
|  |     - BUGFIX: "Add in pause" setting can be ignored from torrent addition dialog | ||||||
|  |     - BUGFIX: Fix renaming of files with unicode characters in their name | ||||||
|  |     - BUGFIX: Fix typo in legal notice (startup) | ||||||
|  |     - BUGFIX: Can listen on ports < 1024 (must be root) | ||||||
|  |     - BUGFIX: Paused torrents can now be rechecked | ||||||
|  |     - BUGFIX: Fix "open torrent destination" feature when path contains spaces | ||||||
|  |     - I18N: Updated translations (Hungarian, Chinese, Russian) | ||||||
|  |  | ||||||
| * Mon Jan 18 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.1.0 | * Mon Jan 18 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.1.0 | ||||||
|     - FEATURE: Graphical User Interface can be disabled at compilation time (headless running) |     - FEATURE: Graphical User Interface can be disabled at compilation time (headless running) | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								INSTALL
									
									
									
									
									
								
							
							
						
						| @@ -14,13 +14,11 @@ qBittorrent - A BitTorrent client in C++ / Qt4 | |||||||
|  |  | ||||||
|     - pkg-config executable |     - pkg-config executable | ||||||
|  |  | ||||||
|     - libtorrent-rasterbar by Arvid Norberg (>= 0.14.4 REQUIRED, compatible with v0.15.x) |     - libtorrent-rasterbar by Arvid Norberg (>= 0.14.4 REQUIRED, >= v0.15.0 ADVISED) | ||||||
|         -> http://www.libtorrent.net |         -> http://www.libtorrent.net | ||||||
|         Be careful: another library (the one used by rTorrent) uses a similar name. |         Be careful: another library (the one used by rTorrent) uses a similar name. | ||||||
|  |  | ||||||
|     - libboost 1.34.x (libboost-filesystem, libboost-thread, libboost-date-time) + libasio |     - libboost: libboost-filesystem, libboost-date-time, libboost-thread, libboost-serialization | ||||||
|       or |  | ||||||
|     - libboost >= 1.35.x (libboost-system, libboost-filesystem, libboost-thread, libboost-date-time) |  | ||||||
|  |  | ||||||
|     - python >= 2.3 (needed by search engine) |     - python >= 2.3 (needed by search engine) | ||||||
|         * Run time only dependency |         * Run time only dependency | ||||||
|   | |||||||
							
								
								
									
										62
									
								
								README.os2
									
									
									
									
									
								
							
							
						
						| @@ -1,62 +0,0 @@ | |||||||
| qBittorrent - A BitTorrent client in Qt4 |  | ||||||
| ------------------------------------------ |  | ||||||
|  |  | ||||||
| This is the eComStation (OS/2) qBittorrent part of the readme. See also README for more general information. |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Building qBittorrent |  | ||||||
| ******************** |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Requirements |  | ||||||
| ============ |  | ||||||
|  |  | ||||||
| - gcc based build env (recommended gcc v4.4.2 or greater) |  | ||||||
|    |  | ||||||
| - Qt4 for eCS (OS/2) dev package (see http://svn.netlabs.org/qt4 for more information) |  | ||||||
|  |  | ||||||
| - libtorrent-rasterbar for eCS (OS/2) port (see http://svn.netlabs.org/ports for more information) |  | ||||||
|  |  | ||||||
| - boost for eCS (OS/2) port (see http://svn.netlabs.org/ports for more information) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| How to build |  | ||||||
| ============ |  | ||||||
|  |  | ||||||
| First you need to create the conf.pri file in the same dir as this readme.os2 is. |  | ||||||
| the conf.pri file has the following content: |  | ||||||
|  |  | ||||||
| ##### conf.pri content beginn ##### |  | ||||||
| PREFIX = . |  | ||||||
| BINDIR = ./bin |  | ||||||
| INCDIR = ./include |  | ||||||
| LIBDIR = ./lib |  | ||||||
| DATADIR = ./share |  | ||||||
|  |  | ||||||
| CONFIG += staticlib |  | ||||||
| INCLUDEPATH += x:/trees/libtorrent/trunk/include |  | ||||||
| LIBS += -Lx:/trees/libtorrent/trunk/src/.libs \ |  | ||||||
|         -Lx:/trees/boost/trunk/stage/lib \ |  | ||||||
|         -Lx:/trees/openssl \ |  | ||||||
| 	-Lx:/extras/lib |  | ||||||
| ##### conf.pri content end ##### |  | ||||||
|  |  | ||||||
| Of course all the above path references have to be adjusted to your build env. |  | ||||||
|  |  | ||||||
| It should now be easy to build qBittorrent: |  | ||||||
|  |  | ||||||
| Simply type: |  | ||||||
| $ qmake |  | ||||||
|  |  | ||||||
| Followed by: |  | ||||||
| $ make |  | ||||||
|  |  | ||||||
| If all works fine you should get a working qbittorrent executable. |  | ||||||
|  |  | ||||||
| If you have any question regarding the eCS (OS/2) port of qBittorrent you can meet me (_diver) on IRC: |  | ||||||
| #netlabs on irc.freenode.net |  | ||||||
|  |  | ||||||
| ------------------------------------------ |  | ||||||
| Silvan Scherrer <silvan.scherrer@aroa.ch> |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -19,6 +19,4 @@ | |||||||
|   </dep> |   </dep> | ||||||
|   <dep type='geoip-database'> |   <dep type='geoip-database'> | ||||||
|   </dep> |   </dep> | ||||||
|   <dep type='qtsingleapplication'> |  | ||||||
|   </dep> |  | ||||||
| </qconf> | </qconf> | ||||||
|   | |||||||
| @@ -2,39 +2,14 @@ | |||||||
| -----BEGIN QCMOD----- | -----BEGIN QCMOD----- | ||||||
| name: libboost | name: libboost | ||||||
| arg: with-libboost-inc=[path], Path to libboost include files | arg: with-libboost-inc=[path], Path to libboost include files | ||||||
| arg: with-libboost-lib=[path], Path to libboost library files |  | ||||||
| -----END QCMOD----- | -----END QCMOD----- | ||||||
| */ | */ | ||||||
| #include <boost/version.hpp> |  | ||||||
| class qc_libboost : public ConfObj | class qc_libboost : public ConfObj | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	qc_libboost(Conf *c) : ConfObj(c) {} | 	qc_libboost(Conf *c) : ConfObj(c) {} | ||||||
| 	QString name() const { return "libboost"; } | 	QString name() const { return "libboost"; } | ||||||
| 	QString shortname() const { return "libboost"; } | 	QString shortname() const { return "libboost"; } | ||||||
|   QString findBoostLib(QString path, QString lib) const { |  | ||||||
|     QString name; |  | ||||||
|     QDir libDir(path); |  | ||||||
|     QStringList filters; |  | ||||||
|     filters << "libboost_"+lib+"*-mt*.so"; |  | ||||||
|     QStringList result = libDir.entryList(filters, QDir::Files); |  | ||||||
|     if(!result.empty()) { |  | ||||||
|       name = result.first().mid(3); |  | ||||||
|       // Remove .so |  | ||||||
|       name.chop(3); |  | ||||||
|     } else { |  | ||||||
|       // Fall back to non -mt boost lib |  | ||||||
|       filters.clear(); |  | ||||||
|       filters << "libboost_"+lib+"*.so"; |  | ||||||
|       result = libDir.entryList(filters, QDir::Files); |  | ||||||
|       if(!result.empty()) { |  | ||||||
|         name = result.first().mid(3); |  | ||||||
|         // Remove .so |  | ||||||
|         name.chop(3); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     return name; |  | ||||||
|   } |  | ||||||
| 	bool exec(){ | 	bool exec(){ | ||||||
|         	QString s; |         	QString s; | ||||||
| 		s = conf->getenv("QC_WITH_LIBBOOST_INC"); | 		s = conf->getenv("QC_WITH_LIBBOOST_INC"); | ||||||
| @@ -76,43 +51,6 @@ public: | |||||||
|       			} |       			} | ||||||
| 		} | 		} | ||||||
| 		conf->addIncludePath(s); | 		conf->addIncludePath(s); | ||||||
| 		// Find library |  | ||||||
| 		s = conf->getenv("QC_WITH_LIBBOOST_LIB"); |  | ||||||
|     QStringList required_libs; |  | ||||||
| #if BOOST_VERSION >= 103500 |  | ||||||
|       required_libs << "system";  |  | ||||||
| #endif |  | ||||||
|     if(conf->getenv("QC_DISABLE_GUI").isEmpty()) { |  | ||||||
|       // Not required by nox |  | ||||||
|       required_libs << "filesystem" << "thread"; |  | ||||||
|     } |  | ||||||
|     QStringList libDirs; |  | ||||||
|     libDirs << "/usr/lib/" << "/usr/lib64/" << "/usr/local/lib/" << "/usr/local/lib64/"; |  | ||||||
|     foreach(const QString& lib, required_libs) { |  | ||||||
|       if(!s.isEmpty()) { |  | ||||||
|         QString detected_name = findBoostLib(s, lib); |  | ||||||
|         if(detected_name.isEmpty()) { |  | ||||||
|           printf("Could not find boost %s library!\n", qPrintable(lib)); |  | ||||||
|           return false; |  | ||||||
|         } else { |  | ||||||
|           conf->addLib("-l"+detected_name); |  | ||||||
|         } |  | ||||||
|       } else { |  | ||||||
|         bool found = false; |  | ||||||
|         foreach(const QString& libDir, libDirs) { |  | ||||||
|           QString detected_name = findBoostLib(libDir, lib); |  | ||||||
|           if(!detected_name.isEmpty()) { |  | ||||||
|             conf->addLib("-l"+detected_name); |  | ||||||
|             found = true; |  | ||||||
|             break; |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|         if(!found) { |  | ||||||
|           printf("Could not find boost %s library!\n", qPrintable(lib)); |  | ||||||
|           return false; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -40,17 +40,6 @@ public: | |||||||
| 			} else { | 			} else { | ||||||
| 				return false; | 				return false; | ||||||
| 			} | 			} | ||||||
| 			QStringList incs3; |  | ||||||
|                         QString req_ver3 = "2.0"; |  | ||||||
|                         QString version3, libs3, other3; |  | ||||||
| 			if(conf->findPkgConfig("gtk+-2.0", mode, req_ver3, &version3, &incs3, &libs3, &other3)) { |  | ||||||
|                                 for(int n = 0; n < incs3.count(); ++n) |  | ||||||
|                                 conf->addIncludePath(incs3[n]); |  | ||||||
|                                 if(!libs3.isEmpty()) |  | ||||||
|                                         conf->addLib(libs3); |  | ||||||
|                         } else { |  | ||||||
|                                 return false; |  | ||||||
|                         } |  | ||||||
| 		} else { | 		} else { | ||||||
| 			return false; | 			return false; | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -13,15 +13,25 @@ public: | |||||||
| 	bool exec(){ | 	bool exec(){ | ||||||
| 		QStringList incs; | 		QStringList incs; | ||||||
| 		QString req_ver = "0.14.4"; | 		QString req_ver = "0.14.4"; | ||||||
|  | 		QString adv_ver = "0.15.0"; | ||||||
| 		QString version, libs, other; | 		QString version, libs, other; | ||||||
| 		VersionMode mode = VersionMin; | 		VersionMode mode = VersionMin; | ||||||
| 		if(!conf->findPkgConfig("libtorrent-rasterbar", mode, req_ver, &version, &incs, &libs, &other)) | 		if(!conf->findPkgConfig("libtorrent-rasterbar", mode, req_ver, &version, &incs, &libs, &other)) | ||||||
| 			return false; | 			return false; | ||||||
| 		for(int n = 0; n < incs.count(); ++n) | 		for(int n = 0; n < incs.count(); ++n) | ||||||
| 			conf->addIncludePath(incs[n]); | 			conf->addIncludePath(incs[n]); | ||||||
| 		if(conf->getenv("QC_DISABLE_GUI").isEmpty()) { | 		//if(!libs.isEmpty()) | ||||||
|   		  conf->addLib("-lcrypto"); | 		//	conf->addLib(libs); | ||||||
|                 } | 		if(!conf->findPkgConfig("libtorrent-rasterbar", mode, adv_ver, &version, &incs, &libs, &other)) | ||||||
|  |                         printf("\nWarning: libtorrent-rasterbar v%s was detected. Some feature will be disabled because they require v%s.\n", version.toLocal8Bit().data(), adv_ver.toUtf8().data()); | ||||||
|  | 		else | ||||||
|  | 			conf->addDefine("LIBTORRENT_0_15"); | ||||||
|  | 		// Get linking parameters | ||||||
|  | 		QStringList params; | ||||||
|  | 		QByteArray staticlibs; | ||||||
|  | 		params << "--static" << "--libs" << "libtorrent-rasterbar"; | ||||||
|  | 		conf->doCommand("pkg-config", params, &staticlibs); | ||||||
|  | 		conf->addLib(staticlibs.trimmed()); | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -15,6 +15,10 @@ public: | |||||||
| 		if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) { | 		if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) { | ||||||
| 			conf->addDefine("DISABLE_GUI"); | 			conf->addDefine("DISABLE_GUI"); | ||||||
| 		}	 | 		}	 | ||||||
|  | 		if(QT_VERSION >= 0x040500) { | ||||||
|  |                         conf->addDefine("QT_4_5"); | ||||||
|  |                 } | ||||||
| 		return(QT_VERSION >= 0x040400); | 		return(QT_VERSION >= 0x040400); | ||||||
|  | 		 | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
|   | |||||||
							
								
								
									
										239
									
								
								src/GUI.cpp
									
									
									
									
									
								
							
							
						
						
							
								
								
									
										108
									
								
								src/GUI.h
									
									
									
									
									
								
							
							
						
						| @@ -43,6 +43,7 @@ class Bittorrent; | |||||||
| class QTimer; | class QTimer; | ||||||
| class downloadFromURL; | class downloadFromURL; | ||||||
| class SearchEngine; | class SearchEngine; | ||||||
|  | class QLocalServer; | ||||||
| class QCloseEvent; | class QCloseEvent; | ||||||
| class RSSImp; | class RSSImp; | ||||||
| class QShortcut; | class QShortcut; | ||||||
| @@ -55,28 +56,44 @@ class QSplitter; | |||||||
| class PropertiesWidget; | class PropertiesWidget; | ||||||
| class StatusBar; | class StatusBar; | ||||||
| class consoleDlg; | class consoleDlg; | ||||||
| class about; |  | ||||||
| class createtorrent; |  | ||||||
| class downloadFromURL; |  | ||||||
|  |  | ||||||
| class GUI : public QMainWindow, private Ui::MainWindow{ | class GUI : public QMainWindow, private Ui::MainWindow{ | ||||||
|   Q_OBJECT |   Q_OBJECT | ||||||
|  |  | ||||||
| public: | private: | ||||||
|   // Construct / Destruct |   // Bittorrent | ||||||
|   GUI(QWidget *parent=0, QStringList torrentCmdLine=QStringList()); |   Bittorrent *BTSession; | ||||||
|   ~GUI(); |   QList<QPair<QTorrentHandle,QString> > unauthenticated_trackers; // Still needed? | ||||||
|   // Methods |   // GUI related | ||||||
|   int getCurrentTabIndex() const; |   QTimer *guiUpdater; | ||||||
|   TransferListWidget* getTransferList() const { return transferList; } |   QTabWidget *tabs; | ||||||
|   QMenu* getTrayIconMenu(); |   StatusBar *status_bar; | ||||||
|  |   QPointer<options_imp> options; | ||||||
| public slots: |   QPointer<consoleDlg> console; | ||||||
|   void trackerAuthenticationRequired(QTorrentHandle& h); |   QPointer<QSystemTrayIcon> systrayIcon; | ||||||
|   void setTabText(int index, QString text) const; |   QPointer<QTimer> systrayCreator; | ||||||
|   void showNotificationBaloon(QString title, QString msg) const; |   QMenu *myTrayIconMenu; | ||||||
|   void downloadFromURLList(const QStringList& urls); |   TransferListWidget *transferList; | ||||||
|   void updateAltSpeedsBtn(bool alternative); |   TransferListFiltersWidget *transferListFilters; | ||||||
|  |   PropertiesWidget *properties; | ||||||
|  |   bool displaySpeedInTitle; | ||||||
|  |   bool force_exit; | ||||||
|  |   // Keyboard shortcuts | ||||||
|  |   QShortcut *switchSearchShortcut; | ||||||
|  |   QShortcut *switchSearchShortcut2; | ||||||
|  |   QShortcut *switchTransferShortcut; | ||||||
|  |   QShortcut *switchRSSShortcut; | ||||||
|  |   // Widgets | ||||||
|  |   QAction *prioSeparator; | ||||||
|  |   QAction *prioSeparator2; | ||||||
|  |   QSplitter *hSplitter; | ||||||
|  |   QSplitter *vSplitter; | ||||||
|  |   // Search | ||||||
|  |   SearchEngine *searchEngine; | ||||||
|  |   // RSS | ||||||
|  |   QPointer<RSSImp> rssWidget; | ||||||
|  |   // Misc | ||||||
|  |   QLocalServer *localServer; | ||||||
|  |  | ||||||
| protected slots: | protected slots: | ||||||
|   // GUI related slots |   // GUI related slots | ||||||
| @@ -88,6 +105,8 @@ protected slots: | |||||||
|   void on_actionWebsite_triggered() const; |   void on_actionWebsite_triggered() const; | ||||||
|   void on_actionBugReport_triggered() const; |   void on_actionBugReport_triggered() const; | ||||||
|   void on_actionShow_console_triggered(); |   void on_actionShow_console_triggered(); | ||||||
|  |   void readParamsOnSocket(); | ||||||
|  |   void acceptConnection(); | ||||||
|   void balloonClicked(); |   void balloonClicked(); | ||||||
|   void writeSettings(); |   void writeSettings(); | ||||||
|   void readSettings(); |   void readSettings(); | ||||||
| @@ -109,60 +128,37 @@ protected slots: | |||||||
|   void on_actionOpen_triggered(); |   void on_actionOpen_triggered(); | ||||||
|   void updateGUI(); |   void updateGUI(); | ||||||
|   void loadPreferences(bool configure_session=true); |   void loadPreferences(bool configure_session=true); | ||||||
|   void processParams(const QString& params); |  | ||||||
|   void processParams(const QStringList& params); |   void processParams(const QStringList& params); | ||||||
|   void addTorrent(QString path); |   void addTorrent(QString path); | ||||||
|   void addUnauthenticatedTracker(const QPair<QTorrentHandle,QString> &tracker); |   void addUnauthenticatedTracker(QPair<QTorrentHandle,QString> tracker); | ||||||
|   void processDownloadedFiles(QString path, QString url); |   void processDownloadedFiles(QString path, QString url); | ||||||
|   void finishedTorrent(QTorrentHandle& h) const; |   void finishedTorrent(QTorrentHandle& h) const; | ||||||
|   void askRecursiveTorrentDownloadConfirmation(QTorrentHandle &h); |  | ||||||
|   // Options slots |   // Options slots | ||||||
|   void on_actionOptions_triggered(); |   void on_actionOptions_triggered(); | ||||||
|   void optionsSaved(); |   void optionsSaved(); | ||||||
|   // HTTP slots |   // HTTP slots | ||||||
|   void on_actionDownload_from_URL_triggered(); |   void on_actionDownload_from_URL_triggered(); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | public slots: | ||||||
|  |   void trackerAuthenticationRequired(QTorrentHandle& h); | ||||||
|  |   void setTabText(int index, QString text) const; | ||||||
|  |   void showNotificationBaloon(QString title, QString msg) const; | ||||||
|  |   void downloadFromURLList(const QStringList& urls); | ||||||
|  |  | ||||||
| protected: | protected: | ||||||
|   void closeEvent(QCloseEvent *); |   void closeEvent(QCloseEvent *); | ||||||
|   void showEvent(QShowEvent *); |   void showEvent(QShowEvent *); | ||||||
|   bool event(QEvent * event); |   bool event(QEvent * event); | ||||||
|   void displayRSSTab(bool enable); |   void displayRSSTab(bool enable); | ||||||
|  |  | ||||||
| private: | public: | ||||||
|   // Bittorrent |   // Construct / Destruct | ||||||
|   Bittorrent *BTSession; |   GUI(QWidget *parent=0, QStringList torrentCmdLine=QStringList()); | ||||||
|   QList<QPair<QTorrentHandle,QString> > unauthenticated_trackers; // Still needed? |   ~GUI(); | ||||||
|   // GUI related |   // Methods | ||||||
|   QTimer *guiUpdater; |   int getCurrentTabIndex() const; | ||||||
|   QTabWidget *tabs; |   TransferListWidget* getTransferList() const { return transferList; } | ||||||
|   StatusBar *status_bar; |  | ||||||
|   QPointer<options_imp> options; |  | ||||||
|   QPointer<consoleDlg> console; |  | ||||||
|   QPointer<about> aboutDlg; |  | ||||||
|   QPointer<createtorrent> createTorrentDlg; |  | ||||||
|   QPointer<downloadFromURL> downloadFromURLDialog; |  | ||||||
|   QPointer<QSystemTrayIcon> systrayIcon; |  | ||||||
|   QPointer<QTimer> systrayCreator; |  | ||||||
|   QPointer<QMenu> myTrayIconMenu; |  | ||||||
|   TransferListWidget *transferList; |  | ||||||
|   TransferListFiltersWidget *transferListFilters; |  | ||||||
|   PropertiesWidget *properties; |  | ||||||
|   bool displaySpeedInTitle; |  | ||||||
|   bool force_exit; |  | ||||||
|   // Keyboard shortcuts |  | ||||||
|   QShortcut *switchSearchShortcut; |  | ||||||
|   QShortcut *switchSearchShortcut2; |  | ||||||
|   QShortcut *switchTransferShortcut; |  | ||||||
|   QShortcut *switchRSSShortcut; |  | ||||||
|   // Widgets |  | ||||||
|   QAction *prioSeparator; |  | ||||||
|   QAction *prioSeparator2; |  | ||||||
|   QSplitter *hSplitter; |  | ||||||
|   QSplitter *vSplitter; |  | ||||||
|   // Search |  | ||||||
|   SearchEngine *searchEngine; |  | ||||||
|   // RSS |  | ||||||
|   QPointer<RSSImp> rssWidget; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| Before Width: | Height: | Size: 546 B | 
| Before Width: | Height: | Size: 7.0 KiB | 
| Before Width: | Height: | Size: 1.8 KiB | 
| @@ -1,9 +1,8 @@ | |||||||
| [Desktop Entry] | [Desktop Entry] | ||||||
| Categories=Qt;Network;P2P; | Categories=Qt;Network;P2P; | ||||||
| Comment=V2.2.11 | Comment=V2.1.6 | ||||||
| Exec=qbittorrent %f | Exec=qbittorrent %f | ||||||
| GenericName=Bittorrent client | GenericName=Bittorrent client | ||||||
| GenericName[ar]=العميل Bittorrent |  | ||||||
| GenericName[bg]=Торент клиент | GenericName[bg]=Торент клиент | ||||||
| GenericName[cs]=Bittorrent klient | GenericName[cs]=Bittorrent klient | ||||||
| GenericName[de]=Bittorren Client | GenericName[de]=Bittorren Client | ||||||
| @@ -11,7 +10,6 @@ GenericName[el]=Bittorrent πελάτης | |||||||
| GenericName[es]=Cliente Bittorrent | GenericName[es]=Cliente Bittorrent | ||||||
| GenericName[fi]=Bittorrent-ohjelma | GenericName[fi]=Bittorrent-ohjelma | ||||||
| GenericName[fr]=Client Bittorrent | GenericName[fr]=Client Bittorrent | ||||||
| GenericName[hr]=Bittorrent klijent |  | ||||||
| GenericName[hu]=Bittorrent kliens | GenericName[hu]=Bittorrent kliens | ||||||
| GenericName[it]=Client Bittorrent | GenericName[it]=Client Bittorrent | ||||||
| GenericName[ja]=Bittorrent クライアント | GenericName[ja]=Bittorrent クライアント | ||||||
|   | |||||||
| Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 78 KiB | 
| Before Width: | Height: | Size: 1.7 KiB | 
| Before Width: | Height: | Size: 2.3 KiB | 
| @@ -1,60 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |  | ||||||
| <plist version="1.0"> |  | ||||||
| <dict> |  | ||||||
| 	<key>CFBundleDocumentTypes</key> |  | ||||||
| 	<array> |  | ||||||
| 		<dict> |  | ||||||
| 			<key>CFBundleTypeExtensions</key> |  | ||||||
| 			<array> |  | ||||||
| 				<string>torrent</string> |  | ||||||
| 			</array> |  | ||||||
| 			<key>CFBundleTypeIconFile</key> |  | ||||||
| 			<string>qbittorrentDocument</string> |  | ||||||
| 			<key>CFBundleTypeName</key> |  | ||||||
| 			<string>BitTorrent Document</string> |  | ||||||
|                         <key>CFBundleTypeMIMETypes</key> |  | ||||||
|                 	<array> |  | ||||||
|         	            <string>application/x-bittorrent</string> |  | ||||||
| 	                </array> |  | ||||||
| 			<key>CFBundleTypeRole</key> |  | ||||||
| 			<string>Viewer</string> |  | ||||||
| 			<key>LSHandlerRank</key> |  | ||||||
| 			<string>Owner</string> |  | ||||||
| 			<key>LSItemContentTypes</key> |  | ||||||
| 			<array> |  | ||||||
| 				<string>org.bittorrent.torrent</string> |  | ||||||
| 			</array> |  | ||||||
| 			<key>LSIsAppleDefaultForType</key> |  | ||||||
| 			<true/> |  | ||||||
| 		</dict> |  | ||||||
| 	</array> |  | ||||||
| 	<key>CFBundleURLTypes</key> |  | ||||||
| 	<array> |  | ||||||
| 		<dict> |  | ||||||
| 			<key>CFBundleURLSchemes</key> |  | ||||||
| 			<array> |  | ||||||
| 				<string>magnet</string> |  | ||||||
| 			</array> |  | ||||||
| 			<key>CFBundleURLName</key> |  | ||||||
| 			<string>BitTorrent Magnet URL</string> |  | ||||||
| 		</dict> |  | ||||||
| 	</array> |  | ||||||
| 	<key>CFBundleIconFile</key> |  | ||||||
| 	<string>qbittorrent_mac.icns</string> |  | ||||||
| 	<key>CFBundleInfoDictionaryVersion</key> |  | ||||||
| 	<string>6.0</string> |  | ||||||
| 	<key>CFBundlePackageType</key> |  | ||||||
| 	<string>APPL</string> |  | ||||||
| 	<key>CFBundleGetInfoString</key> |  | ||||||
| 	<string>2.2.11</string> |  | ||||||
| 	<key>CFBundleSignature</key> |  | ||||||
| 	<string>????</string> |  | ||||||
| 	<key>CFBundleExecutable</key> |  | ||||||
| 	<string>qbittorrent</string> |  | ||||||
| 	<key>CFBundleIdentifier</key> |  | ||||||
| 	<string>org.qbittorrent</string> |  | ||||||
| 	<key>NOTE</key> |  | ||||||
| 	<string>This file was generated by Qt/QMake.</string> |  | ||||||
| </dict> |  | ||||||
| </plist> |  | ||||||
| @@ -54,21 +54,19 @@ class about : public QDialog, private Ui::AboutDlg{ | |||||||
|       te_thanks->append(QString::fromUtf8("<a name='top'></a>")); |       te_thanks->append(QString::fromUtf8("<a name='top'></a>")); | ||||||
|       te_thanks->append(QString::fromUtf8("<ul><li>I would first like to thank sourceforge.net for hosting qBittorrent project and for their support.</li>")); |       te_thanks->append(QString::fromUtf8("<ul><li>I would first like to thank sourceforge.net for hosting qBittorrent project and for their support.</li>")); | ||||||
|       te_thanks->append(QString::fromUtf8("<li>I am pleased that people from all over the world are contributing to qBittorrent: Ishan Arora (India), Arnaud Demaizière (France) and Stephanos Antaris (Greece). Their help is greatly appreciated</li>")); |       te_thanks->append(QString::fromUtf8("<li>I am pleased that people from all over the world are contributing to qBittorrent: Ishan Arora (India), Arnaud Demaizière (France) and Stephanos Antaris (Greece). Their help is greatly appreciated</li>")); | ||||||
|       te_thanks->append(QString::fromUtf8("<li>I also want to thank Στέφανος Αντάρης (santaris@csd.auth.gr) and Mirco Chinelli (infinity89@fastwebmail.it) for working on Mac OS X packaging.</li>")); |       te_thanks->append(QString::fromUtf8("<li>I also want to thank Jeffery Fernandez (jeffery@qbittorrent.org), project consultant, for his help and support since the beginning of this project.</li>")); | ||||||
|       te_thanks->append(QString::fromUtf8("<li>I am grateful to Peter Koeleman (peter@qbittorrent.org) and Mohammad Dib (mdib@qbittorrent.org) for working on qBittorrent port to Windows.</li>")); |       te_thanks->append(QString::fromUtf8("<li>I am grateful to Peter Koeleman (peter@qbittorrent.org) for working on qBittorrent port to Windows.</li>")); | ||||||
|       te_thanks->append(QString::fromUtf8("<li>Thanks a lot to our graphist Mateusz Toboła (tobejodok@qbittorrent.org) for his great work.</li></ul><br><br>")); |       te_thanks->append(QString::fromUtf8("<li>Thanks a lot to our graphist Mateusz Toboła (tobejodok@qbittorrent.org) for his great work.</li></ul><br><br>")); | ||||||
|       te_thanks->scrollToAnchor(QString::fromUtf8("top")); |       te_thanks->scrollToAnchor(QString::fromUtf8("top")); | ||||||
|       // Translation |       // Translation | ||||||
|       te_translation->append(QString::fromUtf8("<a name='top'></a>")); |       te_translation->append(QString::fromUtf8("<a name='top'></a>")); | ||||||
|       te_translation->append(tr("I would like to thank the following people who volunteered to translate qBittorrent:")+QString::fromUtf8("<br>")); |       te_translation->append(tr("I would like to thank the following people who volunteered to translate qBittorrent:")+QString::fromUtf8("<br>")); | ||||||
|       te_translation->append(QString::fromUtf8( |       te_translation->append(QString::fromUtf8( | ||||||
|           "<i><u>Arabic:</u> SDERAWI (abz8868@msn.com) and sn51234 (nesseyan@gmail.com)<br>\ |           "<i>- <u>Brazilian:</u> Nick Marinho (nickmarinho@gmail.com)<br>\ | ||||||
|           - <u>Brazilian:</u> Nick Marinho (nickmarinho@gmail.com)<br>\ |           - <u>Bulgarian:</u> Tsvetan & Boiko Bankov (emerge_life@users.sourceforge.net)<br>\ | ||||||
|           - <u>Bulgarian:</u> Tsvetan & Boyko Bankoff (emerge_life@users.sourceforge.net)<br>\ |  | ||||||
|           - <u>Catalan:</u> Francisco Luque Contreras (frannoe@ya.com)<br>\ |           - <u>Catalan:</u> Francisco Luque Contreras (frannoe@ya.com)<br>\ | ||||||
|           - <u>Chinese (Simplified):</u> Guo Yue (yue.guo0418@gmail.com)<br>\ |           - <u>Chinese (Simplified):</u> Guo Yue (yue.guo0418@gmail.com)<br>\ | ||||||
|           - <u>Chinese (Traditional):</u> Yi-Shun Wang (dnextstep@gmail.com)<br>\ |           - <u>Chinese (Traditional):</u> Yi-Shun Wang (dnextstep@gmail.com)<br>\ | ||||||
|           - <u>Croatian:</u> Oliver Mucafir (oliver.untwist@gmail.com)<br>\ |  | ||||||
|           - <u>Czech:</u> Jirka Vilim (web@tets.cz)<br>\ |           - <u>Czech:</u> Jirka Vilim (web@tets.cz)<br>\ | ||||||
|           - <u>Danish:</u> Mathias Nielsen (comoneo@gmail.com)<br>\ |           - <u>Danish:</u> Mathias Nielsen (comoneo@gmail.com)<br>\ | ||||||
|           - <u>Dutch:</u> Joost Schipper (heavyjoost@users.sourceforge.net) and Peter Koeleman (peter@peerweb.nl)<br>\ |           - <u>Dutch:</u> Joost Schipper (heavyjoost@users.sourceforge.net) and Peter Koeleman (peter@peerweb.nl)<br>\ | ||||||
| @@ -89,14 +87,11 @@ class about : public QDialog, private Ui::AboutDlg{ | |||||||
|           - <u>Spanish:</u> Francisco Luque Contreras (frannoe@ya.com)<br>\ |           - <u>Spanish:</u> Francisco Luque Contreras (frannoe@ya.com)<br>\ | ||||||
|           - <u>Swedish:</u> Daniel Nylander (po@danielnylander.se)<br>\ |           - <u>Swedish:</u> Daniel Nylander (po@danielnylander.se)<br>\ | ||||||
|           - <u>Turkish:</u> Hasan YILMAZ (iletisim@hedefturkce.com) and Erdem Bingöl (erdem84@gmail.com)<br>\ |           - <u>Turkish:</u> Hasan YILMAZ (iletisim@hedefturkce.com) and Erdem Bingöl (erdem84@gmail.com)<br>\ | ||||||
|           - <u>Ukrainian:</u> Andrey Shpachenko (masterfix@users.sourceforge.net) and Oleh Prypin (blaxpirit@gmail.com)<br><br>")); |           - <u>Ukrainian:</u> Andrey Shpachenko (masterfix@users.sourceforge.net)<br><br>")); | ||||||
|       te_translation->append(tr("Please contact me if you would like to translate qBittorrent into your own language.")); |       te_translation->append(tr("Please contact me if you would like to translate qBittorrent into your own language.")); | ||||||
|       te_translation->scrollToAnchor(QString::fromUtf8("top")); |       te_translation->scrollToAnchor(QString::fromUtf8("top")); | ||||||
|       // License |       // License | ||||||
|       te_license->append(QString::fromUtf8("<a name='top'></a>")); |       te_license->append(QString::fromUtf8("<a name='top'></a>")); | ||||||
| #ifdef Q_WS_WIN |  | ||||||
|       te_license->append(QString::fromUtf8("qBittorrent is licensed under the GNU General Public License version 2.")); |  | ||||||
| #else |  | ||||||
|       te_license->append(QString::fromUtf8("qBittorrent is licensed under the GNU General Public License version 2 with the\ |       te_license->append(QString::fromUtf8("qBittorrent is licensed under the GNU General Public License version 2 with the\ | ||||||
| addition of the following special exception:\ | addition of the following special exception:\ | ||||||
| <br><br>\ | <br><br>\ | ||||||
| @@ -443,7 +438,6 @@ exception statement from your version.</i>\ | |||||||
|           consider it more useful to permit linking proprietary applications with the<br>\ |           consider it more useful to permit linking proprietary applications with the<br>\ | ||||||
|           library.  If this is what you want to do, use the GNU Library General<br>\ |           library.  If this is what you want to do, use the GNU Library General<br>\ | ||||||
|           Public License instead of this License.<br>")); |           Public License instead of this License.<br>")); | ||||||
| #endif |  | ||||||
|           te_license->scrollToAnchor(QString::fromUtf8("top")); |           te_license->scrollToAnchor(QString::fromUtf8("top")); | ||||||
|           show(); |           show(); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,147 +0,0 @@ | |||||||
| #ifndef ADVANCEDSETTINGS_H |  | ||||||
| #define ADVANCEDSETTINGS_H |  | ||||||
|  |  | ||||||
| #include <QTableWidget> |  | ||||||
| #include <QHeaderView> |  | ||||||
| #include <QSpinBox> |  | ||||||
| #include <QCheckBox> |  | ||||||
| #include <libtorrent/version.hpp> |  | ||||||
| #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 }; |  | ||||||
| #define ROW_COUNT 9 |  | ||||||
|  |  | ||||||
| class AdvancedSettings: public QTableWidget { |  | ||||||
|   Q_OBJECT |  | ||||||
|  |  | ||||||
| private: |  | ||||||
|   QSpinBox *spin_cache, *outgoing_ports_min, *outgoing_ports_max, *spin_list_refresh; |  | ||||||
|   QCheckBox *cb_ignore_limits_lan, *cb_count_overhead, *cb_recheck_completed, *cb_resolve_countries, *cb_resolve_hosts; |  | ||||||
|  |  | ||||||
| public: |  | ||||||
|   AdvancedSettings(QWidget *parent=0): QTableWidget(parent) { |  | ||||||
|     // Set visual appearance |  | ||||||
|     setEditTriggers(QAbstractItemView::NoEditTriggers); |  | ||||||
|     setAlternatingRowColors(true); |  | ||||||
|     setColumnCount(2); |  | ||||||
|     QStringList header; |  | ||||||
|     header << tr("Property") << tr("Value"); |  | ||||||
|     setHorizontalHeaderLabels(header); |  | ||||||
|     setColumnWidth(0, width()/2); |  | ||||||
|     horizontalHeader()->setStretchLastSection(true); |  | ||||||
|     verticalHeader()->setVisible(false); |  | ||||||
|     setRowCount(ROW_COUNT); |  | ||||||
|     // Load settings |  | ||||||
|     loadAdvancedSettings(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   ~AdvancedSettings() { |  | ||||||
|     delete spin_cache; |  | ||||||
|     delete outgoing_ports_min; |  | ||||||
|     delete outgoing_ports_max; |  | ||||||
|     delete cb_ignore_limits_lan; |  | ||||||
|     delete cb_count_overhead; |  | ||||||
|     delete cb_recheck_completed; |  | ||||||
|     delete spin_list_refresh; |  | ||||||
|     delete cb_resolve_countries; |  | ||||||
|     delete cb_resolve_hosts; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| public slots: |  | ||||||
|   void saveAdvancedSettings() { |  | ||||||
|     // Disk write cache |  | ||||||
|     Preferences::setDiskCacheSize(spin_cache->value()); |  | ||||||
|     // Outgoing ports |  | ||||||
|     Preferences::setOutgoingPortsMin(outgoing_ports_min->value()); |  | ||||||
|     Preferences::setOutgoingPortsMax(outgoing_ports_max->value()); |  | ||||||
|     // Ignore limits on LAN |  | ||||||
|     Preferences::ignoreLimitsOnLAN(cb_ignore_limits_lan->isChecked()); |  | ||||||
|     // Include protocol overhead in transfer limits |  | ||||||
|     Preferences::includeOverheadInLimits(cb_count_overhead->isChecked()); |  | ||||||
|     // Recheck torrents on completion |  | ||||||
|     Preferences::recheckTorrentsOnCompletion(cb_recheck_completed->isChecked()); |  | ||||||
|     // Transfer list refresh interval |  | ||||||
|     Preferences::setRefreshInterval(spin_list_refresh->value()); |  | ||||||
|     // Peer resolution |  | ||||||
|     Preferences::resolvePeerCountries(cb_resolve_countries->isChecked()); |  | ||||||
|     Preferences::resolvePeerHostNames(cb_resolve_hosts->isChecked()); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| protected slots: |  | ||||||
|   void loadAdvancedSettings() { |  | ||||||
|     // Disk write cache |  | ||||||
|     setItem(DISK_CACHE, PROPERTY, new QTableWidgetItem(tr("Disk write cache size"))); |  | ||||||
|     spin_cache = new QSpinBox(); |  | ||||||
|     connect(spin_cache, SIGNAL(valueChanged(int)), this, SLOT(emitSettingsChanged())); |  | ||||||
|     spin_cache->setMinimum(1); |  | ||||||
|     spin_cache->setMaximum(200); |  | ||||||
|     spin_cache->setValue(Preferences::diskCacheSize()); |  | ||||||
|     spin_cache->setSuffix(tr(" MiB")); |  | ||||||
|     setCellWidget(DISK_CACHE, VALUE, spin_cache); |  | ||||||
|     // Outgoing port Min |  | ||||||
|     setItem(OUTGOING_PORT_MIN, PROPERTY, new QTableWidgetItem(tr("Outgoing ports (Min) [0: Disabled]"))); |  | ||||||
|     outgoing_ports_min = new QSpinBox(); |  | ||||||
|     connect(outgoing_ports_min, SIGNAL(valueChanged(int)), this, SLOT(emitSettingsChanged())); |  | ||||||
|     outgoing_ports_min->setMinimum(0); |  | ||||||
|     outgoing_ports_min->setMaximum(65535); |  | ||||||
|     outgoing_ports_min->setValue(Preferences::outgoingPortsMin()); |  | ||||||
|     setCellWidget(OUTGOING_PORT_MIN, VALUE, outgoing_ports_min); |  | ||||||
|     // Outgoing port Min |  | ||||||
|     setItem(OUTGOING_PORT_MAX, PROPERTY, new QTableWidgetItem(tr("Outgoing ports (Max) [0: Disabled]"))); |  | ||||||
|     outgoing_ports_max = new QSpinBox(); |  | ||||||
|     connect(outgoing_ports_max, SIGNAL(valueChanged(int)), this, SLOT(emitSettingsChanged())); |  | ||||||
|     outgoing_ports_max->setMinimum(0); |  | ||||||
|     outgoing_ports_max->setMaximum(65535); |  | ||||||
|     outgoing_ports_max->setValue(Preferences::outgoingPortsMax()); |  | ||||||
|     setCellWidget(OUTGOING_PORT_MAX, VALUE, outgoing_ports_max); |  | ||||||
|     // Ignore transfer limits on local network |  | ||||||
|     setItem(IGNORE_LIMIT_LAN, PROPERTY, new QTableWidgetItem(tr("Ignore transfer limits on local network"))); |  | ||||||
|     cb_ignore_limits_lan = new QCheckBox(); |  | ||||||
|     connect(cb_ignore_limits_lan, SIGNAL(toggled(bool)), this, SLOT(emitSettingsChanged())); |  | ||||||
|     cb_ignore_limits_lan->setChecked(Preferences::ignoreLimitsOnLAN()); |  | ||||||
|     setCellWidget(IGNORE_LIMIT_LAN, VALUE, cb_ignore_limits_lan); |  | ||||||
|     // Consider protocol overhead in transfer limits |  | ||||||
|     setItem(COUNT_OVERHEAD, PROPERTY, new QTableWidgetItem(tr("Include TCP/IP overhead in transfer limits"))); |  | ||||||
|     cb_count_overhead = new QCheckBox(); |  | ||||||
|     connect(cb_count_overhead, SIGNAL(toggled(bool)), this, SLOT(emitSettingsChanged())); |  | ||||||
|     cb_count_overhead->setChecked(Preferences::includeOverheadInLimits()); |  | ||||||
|     setCellWidget(COUNT_OVERHEAD, VALUE, cb_count_overhead); |  | ||||||
|     // Recheck completed torrents |  | ||||||
|     setItem(RECHECK_COMPLETED, PROPERTY, new QTableWidgetItem(tr("Recheck torrents on completion"))); |  | ||||||
|     cb_recheck_completed = new QCheckBox(); |  | ||||||
|     connect(cb_recheck_completed, SIGNAL(toggled(bool)), this, SLOT(emitSettingsChanged())); |  | ||||||
|     cb_recheck_completed->setChecked(Preferences::recheckTorrentsOnCompletion()); |  | ||||||
|     setCellWidget(RECHECK_COMPLETED, VALUE, cb_recheck_completed); |  | ||||||
|     // Transfer list refresh interval |  | ||||||
|     setItem(LIST_REFRESH, PROPERTY, new QTableWidgetItem(tr("Transfer list refresh interval"))); |  | ||||||
|     spin_list_refresh = new QSpinBox(); |  | ||||||
|     connect(spin_list_refresh, SIGNAL(valueChanged(int)), this, SLOT(emitSettingsChanged())); |  | ||||||
|     spin_list_refresh->setMinimum(30); |  | ||||||
|     spin_list_refresh->setMaximum(99999); |  | ||||||
|     spin_list_refresh->setValue(Preferences::getRefreshInterval()); |  | ||||||
|     spin_list_refresh->setSuffix(tr(" ms", " milliseconds")); |  | ||||||
|     setCellWidget(LIST_REFRESH, VALUE, spin_list_refresh); |  | ||||||
|     // Resolve Peer countries |  | ||||||
|     setItem(RESOLVE_COUNTRIES, PROPERTY, new QTableWidgetItem(tr("Resolve peer countries (GeoIP)"))); |  | ||||||
|     cb_resolve_countries = new QCheckBox(); |  | ||||||
|     connect(cb_resolve_countries, SIGNAL(toggled(bool)), this, SLOT(emitSettingsChanged())); |  | ||||||
|     cb_resolve_countries->setChecked(Preferences::resolvePeerCountries()); |  | ||||||
|     setCellWidget(RESOLVE_COUNTRIES, VALUE, cb_resolve_countries); |  | ||||||
|     // Resolve peer hosts |  | ||||||
|     setItem(RESOLVE_HOSTS, PROPERTY, new QTableWidgetItem(tr("Resolve peer host names"))); |  | ||||||
|     cb_resolve_hosts = new QCheckBox(); |  | ||||||
|     connect(cb_resolve_hosts, SIGNAL(toggled(bool)), this, SLOT(emitSettingsChanged())); |  | ||||||
|     cb_resolve_hosts->setChecked(Preferences::resolvePeerHostNames()); |  | ||||||
|     setCellWidget(RESOLVE_HOSTS, VALUE, cb_resolve_hosts); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   void emitSettingsChanged() { |  | ||||||
|     emit settingsChanged(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| signals: |  | ||||||
|   void settingsChanged(); |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| #endif // ADVANCEDSETTINGS_H |  | ||||||
| @@ -1,111 +0,0 @@ | |||||||
| #ifndef BANDWIDTHSCHEDULER_H |  | ||||||
| #define BANDWIDTHSCHEDULER_H |  | ||||||
|  |  | ||||||
| #include <QTimer> |  | ||||||
| #include <QTime> |  | ||||||
| #include <QDateTime> |  | ||||||
| #include "preferences.h" |  | ||||||
| #include <iostream> |  | ||||||
|  |  | ||||||
| class BandwidthScheduler: public QTimer { |  | ||||||
|   Q_OBJECT |  | ||||||
|  |  | ||||||
| private: |  | ||||||
|   bool in_alternative_mode; |  | ||||||
|  |  | ||||||
| public: |  | ||||||
|   BandwidthScheduler(QObject *parent): QTimer(parent), in_alternative_mode(false) { |  | ||||||
|     Q_ASSERT(Preferences::isSchedulerEnabled()); |  | ||||||
|     // Signal shot, we call start() again manually |  | ||||||
|     setSingleShot(true); |  | ||||||
|     // Connect Signals/Slots |  | ||||||
|     connect(this, SIGNAL(timeout()), this, SLOT(switchMode())); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| public slots: |  | ||||||
|   void start() { |  | ||||||
|     Q_ASSERT(Preferences::isSchedulerEnabled()); |  | ||||||
|  |  | ||||||
|     QTime startAltSpeeds = Preferences::getSchedulerStartTime(); |  | ||||||
|     QTime endAltSpeeds = Preferences::getSchedulerEndTime(); |  | ||||||
|     if(startAltSpeeds == endAltSpeeds) { |  | ||||||
|       std::cerr << "Error: bandwidth scheduler have the same start time and end time." << std::endl; |  | ||||||
|       std::cerr << "The bandwidth scheduler will be disabled" << std::endl; |  | ||||||
|       stop(); |  | ||||||
|       emit switchToAlternativeMode(false); |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // Determine what the closest QTime is |  | ||||||
|     QTime now = QTime::currentTime(); |  | ||||||
|     uint time_to_start = secsTo(now, startAltSpeeds); |  | ||||||
|     uint time_to_end = secsTo(now, endAltSpeeds); |  | ||||||
|     if(time_to_end < time_to_start) { |  | ||||||
|       // We should be in alternative mode |  | ||||||
|       in_alternative_mode = true; |  | ||||||
|       // Start counting |  | ||||||
|       QTimer::start(time_to_end*1000); |  | ||||||
|     } else { |  | ||||||
|       // We should be in normal mode |  | ||||||
|       in_alternative_mode = false; |  | ||||||
|       // Start counting |  | ||||||
|       QTimer::start(time_to_start*1000); |  | ||||||
|     } |  | ||||||
|     // Send signal to notify BTSession |  | ||||||
|     emit switchToAlternativeMode(in_alternative_mode); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   void switchMode() { |  | ||||||
|     // Get the day this mode was started (either today or yesterday) |  | ||||||
|     QDate current_date = QDateTime::currentDateTime().toLocalTime().date(); |  | ||||||
|     int day = current_date.dayOfWeek(); |  | ||||||
|     if(in_alternative_mode) { |  | ||||||
|       // It is possible that starttime was yesterday |  | ||||||
|       if(QTime::currentTime().secsTo(Preferences::getSchedulerStartTime()) > 0) { |  | ||||||
|         current_date.addDays(-1); // Go to yesterday |  | ||||||
|         day = current_date.day(); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     // Check if the day is in scheduler days |  | ||||||
|     // Notify BTSession only if necessary |  | ||||||
|     switch(Preferences::getSchedulerDays()) { |  | ||||||
|     case EVERY_DAY: |  | ||||||
|       emit switchToAlternativeMode(!in_alternative_mode); |  | ||||||
|       break; |  | ||||||
|     case WEEK_ENDS: |  | ||||||
|       if(day == Qt::Saturday || day == Qt::Sunday) |  | ||||||
|         emit switchToAlternativeMode(!in_alternative_mode); |  | ||||||
|       break; |  | ||||||
|     case WEEK_DAYS: |  | ||||||
|       if(day != Qt::Saturday && day != Qt::Sunday) |  | ||||||
|         emit switchToAlternativeMode(!in_alternative_mode); |  | ||||||
|       break; |  | ||||||
|     default: |  | ||||||
|       // Convert our enum index to Qt enum index |  | ||||||
|       int scheduler_day = ((int)Preferences::getSchedulerDays()) - 2; |  | ||||||
|       if(day == scheduler_day) |  | ||||||
|         emit switchToAlternativeMode(!in_alternative_mode); |  | ||||||
|       break; |  | ||||||
|     } |  | ||||||
|     // Call start again |  | ||||||
|     start(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| signals: |  | ||||||
|   void switchToAlternativeMode(bool alternative); |  | ||||||
|  |  | ||||||
| private: |  | ||||||
|   // Qt function can return negative values and we |  | ||||||
|   // don't want that |  | ||||||
|   uint secsTo(QTime now, QTime t) { |  | ||||||
|     int diff = now.secsTo(t); |  | ||||||
|     if(diff < 0) { |  | ||||||
|       // 86400 seconds in a day |  | ||||||
|       diff += 86400; |  | ||||||
|     } |  | ||||||
|     Q_ASSERT(diff >= 0); |  | ||||||
|     return diff; |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| #endif // BANDWIDTHSCHEDULER_H |  | ||||||
							
								
								
									
										1127
									
								
								src/bittorrent.cpp
									
									
									
									
									
								
							
							
						
						
							
								
								
									
										147
									
								
								src/bittorrent.h
									
									
									
									
									
								
							
							
						
						| @@ -41,9 +41,7 @@ | |||||||
| #include <QPalette> | #include <QPalette> | ||||||
| #endif | #endif | ||||||
| #include <QPointer> | #include <QPointer> | ||||||
| #include <QTimer> |  | ||||||
|  |  | ||||||
| #include <libtorrent/version.hpp> |  | ||||||
| #include <libtorrent/session.hpp> | #include <libtorrent/session.hpp> | ||||||
| #include <libtorrent/ip_filter.hpp> | #include <libtorrent/ip_filter.hpp> | ||||||
| #include "qtorrenthandle.h" | #include "qtorrenthandle.h" | ||||||
| @@ -54,17 +52,16 @@ using namespace libtorrent; | |||||||
|  |  | ||||||
| class downloadThread; | class downloadThread; | ||||||
| class QTimer; | class QTimer; | ||||||
|  | class FileSystemWatcher; | ||||||
| class FilterParserThread; | class FilterParserThread; | ||||||
| class HttpServer; | class HttpServer; | ||||||
| class BandwidthScheduler; |  | ||||||
| class ScanFoldersModel; |  | ||||||
|  |  | ||||||
| class TrackerInfos { | class TrackerInfos { | ||||||
| public: | public: | ||||||
|   QString name_or_url; |   QString name_or_url; | ||||||
|   QString last_message; |   QString last_message; | ||||||
|   unsigned long num_peers; |   unsigned long num_peers; | ||||||
| #if LIBTORRENT_VERSION_MINOR < 15 | #ifndef LIBTORRENT_0_15 | ||||||
|   bool verified; |   bool verified; | ||||||
|   uint fail_count; |   uint fail_count; | ||||||
| #endif | #endif | ||||||
| @@ -75,13 +72,13 @@ public: | |||||||
|     Q_ASSERT(!name_or_url.isEmpty()); |     Q_ASSERT(!name_or_url.isEmpty()); | ||||||
|     last_message = b.last_message; |     last_message = b.last_message; | ||||||
|     num_peers = b.num_peers; |     num_peers = b.num_peers; | ||||||
| #if LIBTORRENT_VERSION_MINOR < 15 | #ifndef LIBTORRENT_0_15 | ||||||
|     verified = b.verified; |     verified = b.verified; | ||||||
|     fail_count = b.fail_count; |     fail_count = b.fail_count; | ||||||
| #endif | #endif | ||||||
|   } |   } | ||||||
|   TrackerInfos(QString name_or_url): name_or_url(name_or_url), last_message(""), num_peers(0) { |   TrackerInfos(QString name_or_url): name_or_url(name_or_url), last_message(""), num_peers(0) { | ||||||
| #if LIBTORRENT_VERSION_MINOR < 15 | #ifndef LIBTORRENT_0_15 | ||||||
|     fail_count = 0; |     fail_count = 0; | ||||||
|     verified = false; |     verified = false; | ||||||
| #endif | #endif | ||||||
| @@ -91,6 +88,60 @@ public: | |||||||
| class Bittorrent : public QObject { | class Bittorrent : public QObject { | ||||||
|   Q_OBJECT |   Q_OBJECT | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |   // Bittorrent | ||||||
|  |   session *s; | ||||||
|  |   QPointer<QTimer> timerAlerts; | ||||||
|  |   QMap<QUrl, QString> savepath_fromurl; | ||||||
|  |   QHash<QString, QHash<QString, TrackerInfos> > trackersInfos; | ||||||
|  |   QStringList torrentsToPausedAfterChecking; | ||||||
|  |   // Ratio | ||||||
|  |   QPointer<QTimer> BigRatioTimer; | ||||||
|  |   // HTTP | ||||||
|  |   QPointer<downloadThread> downloader; | ||||||
|  |   // File System | ||||||
|  |   QPointer<FileSystemWatcher> FSWatcher; | ||||||
|  |   // Console / Log | ||||||
|  |   QStringList consoleMessages; | ||||||
|  |   QStringList peerBanMessages; | ||||||
|  |   // Settings | ||||||
|  |   bool preAllocateAll; | ||||||
|  |   bool addInPause; | ||||||
|  |   float ratio_limit; | ||||||
|  |   bool UPnPEnabled; | ||||||
|  |   bool NATPMPEnabled; | ||||||
|  |   bool LSDEnabled; | ||||||
|  |   bool DHTEnabled; | ||||||
|  |   int current_dht_port; | ||||||
|  |   bool PeXEnabled; | ||||||
|  |   bool queueingEnabled; | ||||||
|  |   bool appendLabelToSavePath; | ||||||
|  | #ifdef LIBTORRENT_0_15 | ||||||
|  |   bool appendqBExtension; | ||||||
|  | #endif | ||||||
|  |   QString defaultSavePath; | ||||||
|  |   QString defaultTempPath; | ||||||
|  |   // GeoIP | ||||||
|  | #ifndef DISABLE_GUI | ||||||
|  |   bool resolve_countries; | ||||||
|  |   bool geoipDBLoaded; | ||||||
|  | #endif | ||||||
|  |   // ETA Computation | ||||||
|  |   QPointer<QTimer> timerETA; | ||||||
|  |   QHash<QString, QList<int> > ETA_samples; | ||||||
|  |   // IP filtering | ||||||
|  |   QPointer<FilterParserThread> filterParser; | ||||||
|  |   QString filterPath; | ||||||
|  |   // Web UI | ||||||
|  |   QPointer<HttpServer> httpServer; | ||||||
|  |   QList<QUrl> url_skippingDlg; | ||||||
|  |   // Fast exit (async) | ||||||
|  |   bool exiting; | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  |   QString getSavePath(QString hash); | ||||||
|  |   bool initWebUi(QString username, QString password, int port); | ||||||
|  |  | ||||||
| public: | public: | ||||||
|   // Constructor / Destructor |   // Constructor / Destructor | ||||||
|   Bittorrent(); |   Bittorrent(); | ||||||
| @@ -117,14 +168,13 @@ public: | |||||||
|   qlonglong getETA(QString hash); |   qlonglong getETA(QString hash); | ||||||
|   bool useTemporaryFolder() const; |   bool useTemporaryFolder() const; | ||||||
|   QString getDefaultSavePath() const; |   QString getDefaultSavePath() const; | ||||||
|   ScanFoldersModel* getScanFoldersModel() const; |  | ||||||
| #if LIBTORRENT_VERSION_MINOR < 15 |  | ||||||
|   void saveDHTEntry(); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| public slots: | public slots: | ||||||
|   QTorrentHandle addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false); |   QTorrentHandle addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false); | ||||||
|   QTorrentHandle addMagnetUri(QString magnet_uri, bool resumed=false); |   QTorrentHandle addMagnetUri(QString magnet_uri, bool resumed=false); | ||||||
|  |   void importOldTorrents(); | ||||||
|  |   void applyFormerAttributeFiles(QTorrentHandle h); | ||||||
|  |   void importOldTempData(QString torrent_path); | ||||||
|   void loadSessionState(); |   void loadSessionState(); | ||||||
|   void saveSessionState(); |   void saveSessionState(); | ||||||
|   void downloadFromUrl(QString url); |   void downloadFromUrl(QString url); | ||||||
| @@ -132,15 +182,17 @@ public slots: | |||||||
|   void startUpTorrents(); |   void startUpTorrents(); | ||||||
|   session_proxy asyncDeletion(); |   session_proxy asyncDeletion(); | ||||||
|   void recheckTorrent(QString hash); |   void recheckTorrent(QString hash); | ||||||
|   void useAlternativeSpeedsLimit(bool alternative); |  | ||||||
|   /* Needed by Web UI */ |   /* Needed by Web UI */ | ||||||
|   void pauseAllTorrents(); |   void pauseAllTorrents(); | ||||||
|   void pauseTorrent(QString hash); |   void pauseTorrent(QString hash); | ||||||
|   void resumeTorrent(QString hash); |   void resumeTorrent(QString hash); | ||||||
|   void resumeAllTorrents(); |   void resumeAllTorrents(); | ||||||
|   /* End Web UI */ |   /* End Web UI */ | ||||||
|  |   void saveDHTEntry(); | ||||||
|   void preAllocateAllFiles(bool b); |   void preAllocateAllFiles(bool b); | ||||||
|   void saveFastResumeData(); |   void saveFastResumeData(); | ||||||
|  |   void enableDirectoryScanning(QString scan_dir); | ||||||
|  |   void disableDirectoryScanning(); | ||||||
|   void enableIPFilter(QString filter); |   void enableIPFilter(QString filter); | ||||||
|   void disableIPFilter(); |   void disableIPFilter(); | ||||||
|   void setQueueingEnabled(bool enable); |   void setQueueingEnabled(bool enable); | ||||||
| @@ -156,15 +208,15 @@ public slots: | |||||||
|   void setGlobalRatio(float ratio); |   void setGlobalRatio(float ratio); | ||||||
|   void setDeleteRatio(float ratio); |   void setDeleteRatio(float ratio); | ||||||
|   void setDHTPort(int dht_port); |   void setDHTPort(int dht_port); | ||||||
|   void setPeerProxySettings(const proxy_settings &proxySettings); |   void setPeerProxySettings(proxy_settings proxySettings); | ||||||
|   void setHTTPProxySettings(const proxy_settings &proxySettings); |   void setHTTPProxySettings(proxy_settings proxySettings); | ||||||
|   void setSessionSettings(const session_settings &sessionSettings); |   void setSessionSettings(session_settings sessionSettings); | ||||||
|   void startTorrentsInPause(bool b); |   void startTorrentsInPause(bool b); | ||||||
|   void setDefaultTempPath(QString temppath); |   void setDefaultTempPath(QString temppath); | ||||||
|   void setAppendLabelToSavePath(bool append); |   void setAppendLabelToSavePath(bool append); | ||||||
|   void appendLabelToTorrentSavePath(QTorrentHandle h); |   void appendLabelToTorrentSavePath(QTorrentHandle h); | ||||||
|   void changeLabelInTorrentSavePath(QTorrentHandle h, QString old_label, QString new_label); |   void changeLabelInTorrentSavePath(QTorrentHandle h, QString old_label, QString new_label); | ||||||
| #if LIBTORRENT_VERSION_MINOR > 14 | #ifdef LIBTORRENT_0_15 | ||||||
|   void appendqBextensionToTorrent(QTorrentHandle h, bool append); |   void appendqBextensionToTorrent(QTorrentHandle h, bool append); | ||||||
|   void setAppendqBExtension(bool append); |   void setAppendqBExtension(bool append); | ||||||
| #endif | #endif | ||||||
| @@ -186,19 +238,12 @@ public slots: | |||||||
|   void downloadFromURLList(const QStringList& urls); |   void downloadFromURLList(const QStringList& urls); | ||||||
|   void configureSession(); |   void configureSession(); | ||||||
|   void banIP(QString ip); |   void banIP(QString ip); | ||||||
|   void recursiveTorrentDownload(const QTorrentHandle &h); |  | ||||||
|  |  | ||||||
| protected: |  | ||||||
|   QString getSavePath(QString hash, bool fromScanDir = false, QString filePath = QString()); |  | ||||||
|   bool initWebUi(QString username, QString password, int port); |  | ||||||
|  |  | ||||||
| protected slots: | protected slots: | ||||||
|   void addTorrentsFromScanFolder(QStringList&); |   void addTorrentsFromScanFolder(QStringList&); | ||||||
|   void readAlerts(); |   void readAlerts(); | ||||||
|   void deleteBigRatios(); |   void deleteBigRatios(); | ||||||
|   void takeETASamples(); |   void takeETASamples(); | ||||||
|   void exportTorrentFiles(QString path); |  | ||||||
|   void saveTempFastResumeData(); |  | ||||||
|  |  | ||||||
| signals: | signals: | ||||||
|   void addedTorrent(QTorrentHandle& h); |   void addedTorrent(QTorrentHandle& h); | ||||||
| @@ -216,62 +261,6 @@ signals: | |||||||
|   void metadataReceived(QTorrentHandle &h); |   void metadataReceived(QTorrentHandle &h); | ||||||
|   void savePathChanged(QTorrentHandle &h); |   void savePathChanged(QTorrentHandle &h); | ||||||
|   void newConsoleMessage(QString msg); |   void newConsoleMessage(QString msg); | ||||||
|   void alternativeSpeedsModeChanged(bool alternative); |  | ||||||
|   void recursiveTorrentDownloadPossible(QTorrentHandle &h); |  | ||||||
|  |  | ||||||
| private: |  | ||||||
|   // Bittorrent |  | ||||||
|   session *s; |  | ||||||
|   QPointer<QTimer> timerAlerts; |  | ||||||
|   QPointer<BandwidthScheduler> bd_scheduler; |  | ||||||
|   QMap<QUrl, QString> savepath_fromurl; |  | ||||||
|   QHash<QString, QHash<QString, TrackerInfos> > trackersInfos; |  | ||||||
|   QStringList torrentsToPausedAfterChecking; |  | ||||||
|   QTimer resumeDataTimer; |  | ||||||
|   // Ratio |  | ||||||
|   QPointer<QTimer> BigRatioTimer; |  | ||||||
|   // HTTP |  | ||||||
|   QPointer<downloadThread> downloader; |  | ||||||
|   // File System |  | ||||||
|   ScanFoldersModel *m_scanFolders; |  | ||||||
|   // Console / Log |  | ||||||
|   QStringList consoleMessages; |  | ||||||
|   QStringList peerBanMessages; |  | ||||||
|   // Settings |  | ||||||
|   bool preAllocateAll; |  | ||||||
|   bool addInPause; |  | ||||||
|   float ratio_limit; |  | ||||||
|   bool UPnPEnabled; |  | ||||||
|   bool NATPMPEnabled; |  | ||||||
|   bool LSDEnabled; |  | ||||||
|   bool DHTEnabled; |  | ||||||
|   int current_dht_port; |  | ||||||
|   bool PeXEnabled; |  | ||||||
|   bool queueingEnabled; |  | ||||||
|   bool appendLabelToSavePath; |  | ||||||
|   bool torrentExport; |  | ||||||
| #if LIBTORRENT_VERSION_MINOR > 14 |  | ||||||
|   bool appendqBExtension; |  | ||||||
| #endif |  | ||||||
|   QString defaultSavePath; |  | ||||||
|   QString defaultTempPath; |  | ||||||
|   // ETA Computation |  | ||||||
|   QPointer<QTimer> timerETA; |  | ||||||
|   QHash<QString, QList<int> > ETA_samples; |  | ||||||
|   // IP filtering |  | ||||||
|   QPointer<FilterParserThread> filterParser; |  | ||||||
|   QString filterPath; |  | ||||||
|   // Web UI |  | ||||||
|   QPointer<HttpServer> httpServer; |  | ||||||
|   QList<QUrl> url_skippingDlg; |  | ||||||
|   // Fast exit (async) |  | ||||||
|   bool exiting; |  | ||||||
|   // GeoIP |  | ||||||
| #ifndef DISABLE_GUI |  | ||||||
|   bool geoipDBLoaded; |  | ||||||
|   bool resolve_countries; |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -46,7 +46,6 @@ class consoleDlg : public QDialog, private Ui_ConsoleDlg{ | |||||||
|     consoleDlg(QWidget *parent, Bittorrent* _BTSession) : QDialog(parent) { |     consoleDlg(QWidget *parent, Bittorrent* _BTSession) : QDialog(parent) { | ||||||
|       setupUi(this); |       setupUi(this); | ||||||
|       setAttribute(Qt::WA_DeleteOnClose); |       setAttribute(Qt::WA_DeleteOnClose); | ||||||
|       setModal(true); |  | ||||||
|       BTSession = _BTSession; |       BTSession = _BTSession; | ||||||
|       textConsole->setHtml(BTSession->getConsoleMessages().join("<br>")); |       textConsole->setHtml(BTSession->getConsoleMessages().join("<br>")); | ||||||
|       textBannedPeers->setHtml(BTSession->getPeerBanMessages().join("<br>")); |       textBannedPeers->setHtml(BTSession->getPeerBanMessages().join("<br>")); | ||||||
|   | |||||||
| @@ -37,7 +37,6 @@ | |||||||
| #include <boost/filesystem/fstream.hpp> | #include <boost/filesystem/fstream.hpp> | ||||||
| #include <boost/bind.hpp> | #include <boost/bind.hpp> | ||||||
|  |  | ||||||
| #include <libtorrent/version.hpp> |  | ||||||
| #include <libtorrent/entry.hpp> | #include <libtorrent/entry.hpp> | ||||||
| #include <libtorrent/bencode.hpp> | #include <libtorrent/bencode.hpp> | ||||||
| #include <libtorrent/torrent_info.hpp> | #include <libtorrent/torrent_info.hpp> | ||||||
| @@ -66,9 +65,8 @@ bool file_filter(boost::filesystem::path const& filename) | |||||||
| createtorrent::createtorrent(QWidget *parent): QDialog(parent){ | createtorrent::createtorrent(QWidget *parent): QDialog(parent){ | ||||||
|   setupUi(this); |   setupUi(this); | ||||||
|   setAttribute(Qt::WA_DeleteOnClose); |   setAttribute(Qt::WA_DeleteOnClose); | ||||||
|   setModal(true); |  | ||||||
|   creatorThread = new torrentCreatorThread(this); |   creatorThread = new torrentCreatorThread(this); | ||||||
|   connect(creatorThread, SIGNAL(creationSuccess(QString, QString)), this, SLOT(handleCreationSuccess(QString, QString))); |   connect(creatorThread, SIGNAL(creationSuccess(QString, const char*)), this, SLOT(handleCreationSuccess(QString, const char*))); | ||||||
|   connect(creatorThread, SIGNAL(creationFailure(QString)), this, SLOT(handleCreationFailure(QString))); |   connect(creatorThread, SIGNAL(creationFailure(QString)), this, SLOT(handleCreationFailure(QString))); | ||||||
|   connect(creatorThread, SIGNAL(updateProgress(int)), this, SLOT(updateProgressBar(int))); |   connect(creatorThread, SIGNAL(updateProgress(int)), this, SLOT(updateProgressBar(int))); | ||||||
|   path::default_name_check(no_check); |   path::default_name_check(no_check); | ||||||
| @@ -81,22 +79,14 @@ createtorrent::~createtorrent() { | |||||||
|  |  | ||||||
| void createtorrent::on_addFolder_button_clicked(){ | void createtorrent::on_addFolder_button_clicked(){ | ||||||
|   QString dir = QFileDialog::getExistingDirectory(this, tr("Select a folder to add to the torrent"), QDir::homePath(), QFileDialog::ShowDirsOnly); |   QString dir = QFileDialog::getExistingDirectory(this, tr("Select a folder to add to the torrent"), QDir::homePath(), QFileDialog::ShowDirsOnly); | ||||||
|   if(!dir.isEmpty()) { |   if(!dir.isEmpty()) | ||||||
| #if defined(Q_WS_WIN) || defined(Q_OS_OS2) |  | ||||||
|     dir = dir.replace("/", "\\"); |  | ||||||
| #endif |  | ||||||
|     textInputPath->setText(dir); |     textInputPath->setText(dir); | ||||||
|   } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void createtorrent::on_addFile_button_clicked(){ | void createtorrent::on_addFile_button_clicked(){ | ||||||
|   QString file = QFileDialog::getOpenFileName(this, tr("Select a file to add to the torrent"), QDir::homePath()); |   QString file = QFileDialog::getOpenFileName(this, tr("Select a file to add to the torrent"), QDir::homePath(), QString(), 0, QFileDialog::ShowDirsOnly); | ||||||
|   if(!file.isEmpty()) { |   if(!file.isEmpty()) | ||||||
| #if defined(Q_WS_WIN) || defined(Q_OS_OS2) |  | ||||||
|     file = file.replace("/", "\\"); |  | ||||||
| #endif |  | ||||||
|     textInputPath->setText(file); |     textInputPath->setText(file); | ||||||
|   } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void createtorrent::on_removeTracker_button_clicked() { | void createtorrent::on_removeTracker_button_clicked() { | ||||||
| @@ -188,41 +178,28 @@ void createtorrent::on_createButton_clicked(){ | |||||||
|   } else { |   } else { | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   // Disable dialog |  | ||||||
|   setEnabled(false); |  | ||||||
|   // Set busy cursor |  | ||||||
|   setCursor(QCursor(Qt::WaitCursor)); |  | ||||||
|   // Actually create the torrent |  | ||||||
|   QStringList url_seeds = allItems(URLSeeds_list); |   QStringList url_seeds = allItems(URLSeeds_list); | ||||||
|   QString comment = txt_comment->toPlainText(); |   QString comment = txt_comment->toPlainText(); | ||||||
|   creatorThread->create(input, destination, trackers, url_seeds, comment, check_private->isChecked(), getPieceSize()); |   creatorThread->create(input, destination, trackers, url_seeds, comment, check_private->isChecked(), getPieceSize()); | ||||||
| } | } | ||||||
|  |  | ||||||
| void createtorrent::handleCreationFailure(QString msg) { | void createtorrent::handleCreationFailure(QString msg) { | ||||||
|   // Enable dialog |  | ||||||
|   setEnabled(true); |  | ||||||
|   // Remove busy cursor |  | ||||||
|   setCursor(QCursor(Qt::ArrowCursor)); |  | ||||||
|   QMessageBox::information(0, tr("Torrent creation"), tr("Torrent creation was unsuccessful, reason: %1").arg(msg)); |   QMessageBox::information(0, tr("Torrent creation"), tr("Torrent creation was unsuccessful, reason: %1").arg(msg)); | ||||||
| } | } | ||||||
|  |  | ||||||
| void createtorrent::handleCreationSuccess(QString path, QString branch_path) { | void createtorrent::handleCreationSuccess(QString path, const char* branch_path) { | ||||||
|   // Enable Dialog |  | ||||||
|   setEnabled(true); |  | ||||||
|   // Remove busy cursor |  | ||||||
|   setCursor(QCursor(Qt::ArrowCursor)); |  | ||||||
|   if(checkStartSeeding->isChecked()) { |   if(checkStartSeeding->isChecked()) { | ||||||
|     // Create save path temp data |     // Create save path temp data | ||||||
|     boost::intrusive_ptr<torrent_info> t; |     boost::intrusive_ptr<torrent_info> t; | ||||||
|     try { |     try { | ||||||
|       t = new torrent_info(path.toUtf8().data()); |       t = new torrent_info(path.toLocal8Bit().data()); | ||||||
|     } catch(std::exception&) { |     } catch(std::exception&) { | ||||||
|       QMessageBox::critical(0, tr("Torrent creation"), tr("Created torrent file is invalid. It won't be added to download list.")); |       QMessageBox::critical(0, tr("Torrent creation"), tr("Created torrent file is invalid. It won't be added to download list.")); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|     QString hash = misc::toQString(t->info_hash()); |     QString hash = misc::toQString(t->info_hash()); | ||||||
|     TorrentTempData::setSavePath(hash, branch_path); |     TorrentTempData::setSavePath(hash, QString(branch_path)); | ||||||
| #if LIBTORRENT_VERSION_MINOR > 14 | #ifdef LIBTORRENT_0_15 | ||||||
|     // Enable seeding mode (do not recheck the files) |     // Enable seeding mode (do not recheck the files) | ||||||
|     TorrentTempData::setSeedingMode(hash, true); |     TorrentTempData::setSeedingMode(hash, true); | ||||||
| #endif | #endif | ||||||
| @@ -232,18 +209,6 @@ void createtorrent::handleCreationSuccess(QString path, QString branch_path) { | |||||||
|   close(); |   close(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void createtorrent::on_cancelButton_clicked() { |  | ||||||
|   // End torrent creation thread |  | ||||||
|   if(creatorThread->isRunning()) { |  | ||||||
|     creatorThread->abortCreation(); |  | ||||||
|     creatorThread->terminate(); |  | ||||||
|     // Wait for termination |  | ||||||
|     creatorThread->wait(); |  | ||||||
|   } |  | ||||||
|   // Close the dialog |  | ||||||
|   reject(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void createtorrent::updateProgressBar(int progress) { | void createtorrent::updateProgressBar(int progress) { | ||||||
|   progressBar->setValue(progress); |   progressBar->setValue(progress); | ||||||
| } | } | ||||||
| @@ -298,7 +263,7 @@ void torrentCreatorThread::run() { | |||||||
|     // Set qBittorrent as creator and add user comment to |     // Set qBittorrent as creator and add user comment to | ||||||
|     // torrent_info structure |     // torrent_info structure | ||||||
|     t.set_creator(creator_str); |     t.set_creator(creator_str); | ||||||
|     t.set_comment((const char*)comment.toUtf8()); |     t.set_comment((const char*)comment.toLocal8Bit()); | ||||||
|     // Is private ? |     // Is private ? | ||||||
|     t.set_priv(is_private); |     t.set_priv(is_private); | ||||||
|     if(abort) return; |     if(abort) return; | ||||||
| @@ -306,7 +271,7 @@ void torrentCreatorThread::run() { | |||||||
|     ofstream out(complete(path((const char*)save_path.toLocal8Bit())), std::ios_base::binary); |     ofstream out(complete(path((const char*)save_path.toLocal8Bit())), std::ios_base::binary); | ||||||
|     bencode(std::ostream_iterator<char>(out), t.generate()); |     bencode(std::ostream_iterator<char>(out), t.generate()); | ||||||
|     emit updateProgress(100); |     emit updateProgress(100); | ||||||
|     emit creationSuccess(save_path, QString::fromUtf8(full_path.branch_path().string().c_str())); |     emit creationSuccess(save_path, full_path.branch_path().string().c_str()); | ||||||
|   } |   } | ||||||
|   catch (std::exception& e){ |   catch (std::exception& e){ | ||||||
|     emit creationFailure(QString::fromUtf8(e.what())); |     emit creationFailure(QString::fromUtf8(e.what())); | ||||||
|   | |||||||
| @@ -58,14 +58,13 @@ class torrentCreatorThread : public QThread { | |||||||
|     } |     } | ||||||
|     void create(QString _input_path, QString _save_path, QStringList _trackers, QStringList _url_seeds, QString _comment, bool _is_private, int _piece_size); |     void create(QString _input_path, QString _save_path, QStringList _trackers, QStringList _url_seeds, QString _comment, bool _is_private, int _piece_size); | ||||||
|     void sendProgressSignal(int progress); |     void sendProgressSignal(int progress); | ||||||
|     void abortCreation() { abort = true; } |  | ||||||
|    |    | ||||||
|   protected: |   protected: | ||||||
|     void run(); |     void run(); | ||||||
|      |      | ||||||
|   signals: |   signals: | ||||||
|     void creationFailure(QString msg); |     void creationFailure(QString msg); | ||||||
|     void creationSuccess(QString path, QString branch_path); |     void creationSuccess(QString path, const char* branch_path); | ||||||
|  |  | ||||||
|   signals: |   signals: | ||||||
|     void updateProgress(int progress); |     void updateProgress(int progress); | ||||||
| @@ -88,7 +87,6 @@ class createtorrent : public QDialog, private Ui::createTorrentDialog{ | |||||||
|  |  | ||||||
|   public slots: |   public slots: | ||||||
|     void updateProgressBar(int progress); |     void updateProgressBar(int progress); | ||||||
|     void on_cancelButton_clicked(); |  | ||||||
|  |  | ||||||
|   protected slots: |   protected slots: | ||||||
|     void on_createButton_clicked(); |     void on_createButton_clicked(); | ||||||
| @@ -99,7 +97,7 @@ class createtorrent : public QDialog, private Ui::createTorrentDialog{ | |||||||
|     void on_addURLSeed_button_clicked(); |     void on_addURLSeed_button_clicked(); | ||||||
|     void on_removeURLSeed_button_clicked(); |     void on_removeURLSeed_button_clicked(); | ||||||
|     void handleCreationFailure(QString msg); |     void handleCreationFailure(QString msg); | ||||||
|     void handleCreationSuccess(QString path, QString branch_path); |     void handleCreationSuccess(QString path, const char* branch_path); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -53,49 +53,34 @@ public: | |||||||
|     setFixedHeight(BAR_HEIGHT); |     setFixedHeight(BAR_HEIGHT); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void setProgress(const bitfield &pieces, const bitfield &downloading_pieces) { |   void setProgress(bitfield pieces) { | ||||||
|     if(pieces.empty()) { |     if(pieces.empty()) { | ||||||
|       // Empty bar |       // Empty bar | ||||||
|       QPixmap pix = QPixmap(1, 1); |       QPixmap pix = QPixmap(1, 1); | ||||||
|       pix.fill(); |       pix.fill(); | ||||||
|       pixmap = pix; |       pixmap = pix; | ||||||
|     } else { |     } else { | ||||||
|       const int nb_pieces = pieces.size(); |       int nb_pieces = pieces.size(); | ||||||
|       // Reduce the number of pieces before creating the pixmap |       // Reduce the number of pieces before creating the pixmap | ||||||
|       // otherwise it can crash when there are too many pieces |       // otherwise it can crash when there are too many pieces | ||||||
|       if(nb_pieces > width()) { |       if(nb_pieces > width()) { | ||||||
|         const int ratio = floor(nb_pieces/(double)width()); |         int ratio = floor(nb_pieces/(double)width()); | ||||||
|         std::vector<bool> scaled_pieces; |         QVector<bool> scaled_pieces; | ||||||
|         std::vector<bool> scaled_downloading; |  | ||||||
|         for(int i=0; i<nb_pieces; i+= ratio) { |         for(int i=0; i<nb_pieces; i+= ratio) { | ||||||
|           bool have = true; |           bool have = true; | ||||||
|           for(int j=i; j<qMin(i+ratio, nb_pieces); ++j) { |           for(int j=i; j<qMin(i+ratio, nb_pieces); ++j) { | ||||||
|             if(!pieces[i]) { have = false; break; } |             if(!pieces[i]) { have = false; break; } | ||||||
|           } |           } | ||||||
|           scaled_pieces.push_back(have); |           scaled_pieces << have; | ||||||
|           if(have) { |  | ||||||
|             scaled_downloading.push_back(false); |  | ||||||
|           } else { |  | ||||||
|             bool downloading = false; |  | ||||||
|             for(int j=i; j<qMin(i+ratio, nb_pieces); ++j) { |  | ||||||
|               if(downloading_pieces[i]) { downloading = true; break; } |  | ||||||
|             } |  | ||||||
|             scaled_downloading.push_back(downloading); |  | ||||||
|           } |  | ||||||
|         } |         } | ||||||
|         QPixmap pix = QPixmap(scaled_pieces.size(), 1); |         QPixmap pix = QPixmap(scaled_pieces.size(), 1); | ||||||
|         pix.fill(); |         pix.fill(); | ||||||
|         QPainter painter(&pix); |         QPainter painter(&pix); | ||||||
|         for(uint i=0; i<scaled_pieces.size(); ++i) { |         for(int i=0; i<scaled_pieces.size(); ++i) { | ||||||
|           if(scaled_pieces[i]) { |           if(scaled_pieces[i]) | ||||||
|             painter.setPen(Qt::blue); |             painter.setPen(Qt::blue); | ||||||
|           } else { |           else | ||||||
|             if(scaled_downloading[i]) { |             painter.setPen(Qt::white); | ||||||
|               painter.setPen(Qt::yellow); |  | ||||||
|             } else { |  | ||||||
|               painter.setPen(Qt::white); |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|           painter.drawPoint(i,0); |           painter.drawPoint(i,0); | ||||||
|         } |         } | ||||||
|         pixmap = pix; |         pixmap = pix; | ||||||
| @@ -104,15 +89,10 @@ public: | |||||||
|         pix.fill(); |         pix.fill(); | ||||||
|         QPainter painter(&pix); |         QPainter painter(&pix); | ||||||
|         for(uint i=0; i<pieces.size(); ++i) { |         for(uint i=0; i<pieces.size(); ++i) { | ||||||
|           if(pieces[i]) { |           if(pieces[i]) | ||||||
|             painter.setPen(Qt::blue); |             painter.setPen(Qt::blue); | ||||||
|           } else { |           else | ||||||
|             if(downloading_pieces[i]) { |             painter.setPen(Qt::white); | ||||||
|               painter.setPen(Qt::yellow); |  | ||||||
|             } else { |  | ||||||
|               painter.setPen(Qt::white); |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|           painter.drawPoint(i,0); |           painter.drawPoint(i,0); | ||||||
|         } |         } | ||||||
|         pixmap = pix; |         pixmap = pix; | ||||||
|   | |||||||
| @@ -47,7 +47,6 @@ class downloadFromURL : public QDialog, private Ui::downloadFromURL{ | |||||||
|       setupUi(this); |       setupUi(this); | ||||||
|       setAttribute(Qt::WA_DeleteOnClose); |       setAttribute(Qt::WA_DeleteOnClose); | ||||||
|       icon_lbl->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/url.png"))); |       icon_lbl->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/url.png"))); | ||||||
|       setModal(true); |  | ||||||
|       show(); |       show(); | ||||||
|       // Paste clipboard if there is an URL in it |       // Paste clipboard if there is an URL in it | ||||||
|       QString clip_txt = qApp->clipboard()->text(); |       QString clip_txt = qApp->clipboard()->text(); | ||||||
|   | |||||||
| @@ -42,9 +42,6 @@ enum ProxyType {HTTP=1, SOCKS5=2, HTTP_PW=3, SOCKS5_PW=4, SOCKS4=5}; | |||||||
| downloadThread::downloadThread(QObject* parent) : QObject(parent) { | downloadThread::downloadThread(QObject* parent) : QObject(parent) { | ||||||
|   networkManager = new QNetworkAccessManager(this); |   networkManager = new QNetworkAccessManager(this); | ||||||
|   connect(networkManager, SIGNAL(finished (QNetworkReply*)), this, SLOT(processDlFinished(QNetworkReply*))); |   connect(networkManager, SIGNAL(finished (QNetworkReply*)), this, SLOT(processDlFinished(QNetworkReply*))); | ||||||
| #ifndef QT_NO_OPENSSL |  | ||||||
|   connect(networkManager, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)), this, SLOT(ignoreSslErrors(QNetworkReply*,QList<QSslError>))); |  | ||||||
| #endif |  | ||||||
| } | } | ||||||
|  |  | ||||||
| downloadThread::~downloadThread(){ | downloadThread::~downloadThread(){ | ||||||
| @@ -54,7 +51,7 @@ downloadThread::~downloadThread(){ | |||||||
| } | } | ||||||
|  |  | ||||||
| void downloadThread::processDlFinished(QNetworkReply* reply) { | void downloadThread::processDlFinished(QNetworkReply* reply) { | ||||||
|   QString url = reply->url().toEncoded().data(); |   QString url = reply->url().toString(); | ||||||
|   if(reply->error() != QNetworkReply::NoError) { |   if(reply->error() != QNetworkReply::NoError) { | ||||||
|     // Failure |     // Failure | ||||||
|     emit downloadFailure(url, errorCodeToString(reply->error())); |     emit downloadFailure(url, errorCodeToString(reply->error())); | ||||||
| @@ -62,7 +59,7 @@ void downloadThread::processDlFinished(QNetworkReply* reply) { | |||||||
|     QVariant redirection = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); |     QVariant redirection = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); | ||||||
|     if(redirection.isValid()) { |     if(redirection.isValid()) { | ||||||
|       // We should redirect |       // We should redirect | ||||||
|       qDebug("Redirecting from %s to %s", qPrintable(url), qPrintable(redirection.toUrl().toString())); |       qDebug("Redirecting from %s to %s", url.toLocal8Bit().data(), redirection.toUrl().toString().toLocal8Bit().data()); | ||||||
|       redirect_mapping.insert(redirection.toUrl().toString(), url); |       redirect_mapping.insert(redirection.toUrl().toString(), url); | ||||||
|       downloadUrl(redirection.toUrl().toString()); |       downloadUrl(redirection.toUrl().toString()); | ||||||
|       return; |       return; | ||||||
| @@ -73,27 +70,23 @@ void downloadThread::processDlFinished(QNetworkReply* reply) { | |||||||
|     } |     } | ||||||
|     // Success |     // Success | ||||||
|     QString filePath; |     QString filePath; | ||||||
|     QTemporaryFile *tmpfile = new QTemporaryFile; |     QTemporaryFile tmpfile; | ||||||
|     tmpfile->setAutoRemove(false); |     tmpfile.setAutoRemove(false); | ||||||
|     if (tmpfile->open()) { |     if (tmpfile.open()) { | ||||||
|       filePath = tmpfile->fileName(); |       filePath = tmpfile.fileName(); | ||||||
|       qDebug("Temporary filename is: %s", qPrintable(filePath)); |       qDebug("Temporary filename is: %s", filePath.toLocal8Bit().data()); | ||||||
|       if(reply->open(QIODevice::ReadOnly)) { |       if(reply->open(QIODevice::ReadOnly)) { | ||||||
|         // TODO: Support GZIP compression |         tmpfile.write(reply->readAll()); | ||||||
|         tmpfile->write(reply->readAll()); |  | ||||||
|         reply->close(); |         reply->close(); | ||||||
|         tmpfile->close(); |         tmpfile.close(); | ||||||
|         delete tmpfile; |  | ||||||
|         // Send finished signal |         // Send finished signal | ||||||
|         emit downloadFinished(url, filePath); |         emit downloadFinished(url, filePath); | ||||||
|       } else { |       } else { | ||||||
|         // Error when reading the request |         // Error when reading the request | ||||||
|         tmpfile->close(); |         tmpfile.close(); | ||||||
|         delete tmpfile; |  | ||||||
|         emit downloadFailure(url, tr("I/O Error")); |         emit downloadFailure(url, tr("I/O Error")); | ||||||
|       } |       } | ||||||
|     } else { |     } else { | ||||||
|       delete tmpfile; |  | ||||||
|       emit downloadFailure(url, tr("I/O Error")); |       emit downloadFailure(url, tr("I/O Error")); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -101,12 +94,7 @@ void downloadThread::processDlFinished(QNetworkReply* reply) { | |||||||
|   reply->deleteLater(); |   reply->deleteLater(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void downloadThread::downloadTorrentUrl(QString url){ | void downloadThread::downloadUrl(QString url){ | ||||||
|   QNetworkReply *reply = downloadUrl(url); |  | ||||||
|   connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(checkDownloadSize(qint64,qint64))); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| QNetworkReply* downloadThread::downloadUrl(QString url){ |  | ||||||
|   // Update proxy settings |   // Update proxy settings | ||||||
|   applyProxySettings(); |   applyProxySettings(); | ||||||
|   // Process download request |   // Process download request | ||||||
| @@ -115,27 +103,9 @@ QNetworkReply* downloadThread::downloadUrl(QString url){ | |||||||
|   // Spoof Firefox 3.5 user agent to avoid |   // Spoof Firefox 3.5 user agent to avoid | ||||||
|   // Web server banning |   // Web server banning | ||||||
|   request.setRawHeader("User-Agent", "Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5"); |   request.setRawHeader("User-Agent", "Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5"); | ||||||
|   qDebug("Downloading %s...", qPrintable(request.url().toString())); |   request.setRawHeader("Accept-Encoding", ""); | ||||||
|   return networkManager->get(request); |   qDebug("Downloading %s...", request.url().toString().toLocal8Bit().data()); | ||||||
| } |   networkManager->get(request); | ||||||
|  |  | ||||||
| void downloadThread::checkDownloadSize(qint64 bytesReceived, qint64 bytesTotal) { |  | ||||||
|   if(bytesTotal > 0) { |  | ||||||
|     QNetworkReply *reply = static_cast<QNetworkReply*>(sender()); |  | ||||||
|     // Total number of bytes is available |  | ||||||
|     if(bytesTotal > 1048576) { |  | ||||||
|       // More than 1MB, this is probably not a torrent file, aborting... |  | ||||||
|       reply->abort(); |  | ||||||
|     } else { |  | ||||||
|       disconnect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(checkDownloadSize(qint64,qint64))); |  | ||||||
|     } |  | ||||||
|   } else { |  | ||||||
|     if(bytesReceived  > 1048576) { |  | ||||||
|       // More than 1MB, this is probably not a torrent file, aborting... |  | ||||||
|       QNetworkReply *reply = static_cast<QNetworkReply*>(sender()); |  | ||||||
|       reply->abort(); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void downloadThread::applyProxySettings() { | void downloadThread::applyProxySettings() { | ||||||
| @@ -147,7 +117,7 @@ void downloadThread::applyProxySettings() { | |||||||
|     QString IP = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/IP"), "0.0.0.0").toString(); |     QString IP = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/IP"), "0.0.0.0").toString(); | ||||||
|     proxy.setHostName(IP); |     proxy.setHostName(IP); | ||||||
|     QString port = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Port"), 8080).toString(); |     QString port = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Port"), 8080).toString(); | ||||||
|     qDebug("Using proxy: %s", qPrintable(IP)); |     qDebug("Using proxy: %s", (IP+QString(":")+port).toLocal8Bit().data()); | ||||||
|     proxy.setPort(port.toUShort()); |     proxy.setPort(port.toUShort()); | ||||||
|     // Default proxy type is HTTP, we must change if it is SOCKS5 |     // Default proxy type is HTTP, we must change if it is SOCKS5 | ||||||
|     if(intValue == SOCKS5 || intValue == SOCKS5_PW) { |     if(intValue == SOCKS5 || intValue == SOCKS5_PW) { | ||||||
| @@ -219,11 +189,3 @@ QString downloadThread::errorCodeToString(QNetworkReply::NetworkError status) { | |||||||
|     return tr("Unknown error"); |     return tr("Unknown error"); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| #ifndef QT_NO_OPENSSL |  | ||||||
| void downloadThread::ignoreSslErrors(QNetworkReply* reply,QList<QSslError> errors) { |  | ||||||
|   Q_UNUSED(errors) |  | ||||||
|   // Ignore all SSL errors |  | ||||||
|   reply->ignoreSslErrors(); |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
|   | |||||||