Compare commits
	
		
			223 Commits
		
	
	
		
			release-2.
			...
			release-2.
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | e9da810eae | ||
|   | 9a40d7037d | ||
|   | db29364346 | ||
|   | 57d5a739ed | ||
|   | c66df12f8c | ||
|   | 6a8f568d74 | ||
|   | 56c20b1cc4 | ||
|   | 0de843911d | ||
|   | 5a58ace305 | ||
|   | b8f30381c9 | ||
|   | 1197c544aa | ||
|   | 4faaf2b642 | ||
|   | b9f22ef490 | ||
|   | c3e9e85d21 | ||
|   | 1f99a3817f | ||
|   | 0daa61be6c | ||
|   | 9216bb850a | ||
|   | 2706efdb3c | ||
|   | 7a8089fa82 | ||
|   | 8415449ecd | ||
|   | 1603faf873 | ||
|   | 54f1294ef5 | ||
|   | 91068ac17b | ||
|   | 4169ae176f | ||
|   | b2beabd8df | ||
|   | 8ec109e079 | ||
|   | 0c8464e0c8 | ||
|   | 042cbc73ec | ||
|   | 609eb5f518 | ||
|   | 3500553b15 | ||
|   | ca06f9be5c | ||
|   | 287ecf165b | ||
|   | fdf71c3006 | ||
|   | cc6179b26f | ||
|   | 7765b763f0 | ||
|   | 84abef1184 | ||
|   | 0755eccf4f | ||
|   | 425150cd01 | ||
|   | 55d1076573 | ||
|   | 6e74eb45b2 | ||
|   | e258a1a2d2 | ||
|   | 6070fac3f5 | ||
|   | ac3a88d3e3 | ||
|   | e3360713de | ||
|   | 6cb6d2724b | ||
|   | ff8354b1f6 | ||
|   | 1a2cb6aee7 | ||
|   | 25998d69a7 | ||
|   | 3e55e8dc6e | ||
|   | b8b2f96d76 | ||
|   | cc609badec | ||
|   | a1aa507bdb | ||
|   | 779b2baa74 | ||
|   | 58e0d6b11e | ||
|   | 1827337f90 | ||
|   | 08044bc47d | ||
|   | 272852f25b | ||
|   | 6575866907 | ||
|   | 816b61da76 | ||
|   | d0a6366b35 | ||
|   | d4753b2624 | ||
|   | 323fd791c5 | ||
|   | 56e45a11a8 | ||
|   | f04d912fb6 | ||
|   | 2985f85f82 | ||
|   | 49c0e9423e | ||
|   | 15a4abff5b | ||
|   | bd51ffd7ca | ||
|   | 1288c7092b | ||
|   | 9650b268b2 | ||
|   | 30c4c62d2e | ||
|   | 8b6a5d985f | ||
|   | 0bd1410b95 | ||
|   | f1451dafee | ||
|   | 74f16c8e76 | ||
|   | 1b954f157f | ||
|   | e8931c5747 | ||
|   | 31165675b8 | ||
|   | 4001ed304e | ||
|   | e8b3016771 | ||
|   | e3e9461901 | ||
|   | 45c068f0f7 | ||
|   | 4b2d09a07b | ||
|   | 2d57d9d32c | ||
|   | 4a01d01cba | ||
|   | 98cc53e287 | ||
|   | 5ad0bf1d34 | ||
|   | 35a9d30143 | ||
|   | 6bc0aebe0d | ||
|   | c099af380a | ||
|   | 59651545ae | ||
|   | 8469570f80 | ||
|   | d513b7d0d8 | ||
|   | 13e06b3444 | ||
|   | d6206d91eb | ||
|   | cae8a3173d | ||
|   | 48e6b46967 | ||
|   | 9c1bc13d6f | ||
|   | c15a890952 | ||
|   | 12b4ee72fa | ||
|   | e5290e61ca | ||
|   | 08cbe38f96 | ||
|   | 47e337dc5d | ||
|   | cfc4e7c8f6 | ||
|   | 4eb8be372e | ||
|   | 11f79432b5 | ||
|   | ec15e8247d | ||
|   | 6b4588ef6d | ||
|   | ef0a826180 | ||
|   | d79f779c0a | ||
|   | 1dadc08625 | ||
|   | 5f49af5ade | ||
|   | 1e67f0afa4 | ||
|   | dd9cf6c3ab | ||
|   | 36483d795e | ||
|   | 303c209839 | ||
|   | 6790889cc3 | ||
|   | 3a24b66adc | ||
|   | 1a3f5e81e3 | ||
|   | 818a79c9db | ||
|   | 93f635f9f4 | ||
|   | 73ec018732 | ||
|   | 68832df0c4 | ||
|   | ce817836c0 | ||
|   | 89fbfdbd1b | ||
|   | 797d89fc3c | ||
|   | abc6e1c719 | ||
|   | 31558aea8d | ||
|   | be711920fd | ||
|   | 5d899bbe7c | ||
|   | 9c63e418cf | ||
|   | 984e7c7c7b | ||
|   | 1ae460bc67 | ||
|   | c7ffa9096c | ||
|   | 01448f4c14 | ||
|   | 7e8754baf3 | ||
|   | 8206ec9012 | ||
|   | a611361823 | ||
|   | 59c77a3f9c | ||
|   | 8ce9649310 | ||
|   | fe5ac5d083 | ||
|   | 8740627c12 | ||
|   | c47f2e449b | ||
|   | db09e40690 | ||
|   | 3ca3f91590 | ||
|   | ee9a8d0563 | ||
|   | 3542980e50 | ||
|   | f243b8535a | ||
|   | 7953809024 | ||
|   | 3ac65a477c | ||
|   | 00cab62381 | ||
|   | ab31300201 | ||
|   | 754eb2788f | ||
|   | 8dcb9f17bc | ||
|   | 38121920a1 | ||
|   | e815f934e1 | ||
|   | 4a305222be | ||
|   | dcfed67173 | ||
|   | db43606620 | ||
|   | 3b16a89c36 | ||
|   | 4c03e708e0 | ||
|   | 3e0fc5234f | ||
|   | 5ba7e643b9 | ||
|   | c53e265b70 | ||
|   | 2b5f12e014 | ||
|   | ee518973ea | ||
|   | aa08552686 | ||
|   | fa43393b65 | ||
|   | 48dcfb56ad | ||
|   | 511fa5d988 | ||
|   | 5694c8aa8b | ||
|   | e3098c5191 | ||
|   | dbacb1961c | ||
|   | 1092064115 | ||
|   | 7988f15da7 | ||
|   | 689df74d7e | ||
|   | c59dde4f58 | ||
|   | 4bc36b4d28 | ||
|   | 430c7d2deb | ||
|   | d72c79b259 | ||
|   | efbf470585 | ||
|   | 4e20723ae6 | ||
|   | f3268bf49e | ||
|   | 5aba9179c4 | ||
|   | 450814ae23 | ||
|   | ba22fa8331 | ||
|   | 5ce02cb612 | ||
|   | 1013f39a42 | ||
|   | cd5c4bf464 | ||
|   | 84bfc54b03 | ||
|   | 5b3b5eb2ef | ||
|   | 990a863d41 | ||
|   | 7f27d10735 | ||
|   | 1377a75a53 | ||
|   | bcd33fc861 | ||
|   | 46d8fa1656 | ||
|   | 28cf69b84d | ||
|   | 89389df74d | ||
|   | 77c29f48cb | ||
|   | c5d92f3d69 | ||
|   | 54487c8247 | ||
|   | be64008870 | ||
|   | 8113b150dd | ||
|   | 4a33367cb0 | ||
|   | 0af5d82114 | ||
|   | 10c4fd330a | ||
|   | 9a30d5a295 | ||
|   | 724b47d999 | ||
|   | 2c0f7c33a2 | ||
|   | ce33e266fe | ||
|   | 2f291daefa | ||
|   | 722f2aeb5d | ||
|   | d5b9598b5b | ||
|   | cc7d74b67c | ||
|   | e853b0b736 | ||
|   | 5e395b24a9 | ||
|   | 9c3789f83f | ||
|   | 758595dc8c | ||
|   | 01f9e989ef | ||
|   | eb9f0cb559 | ||
|   | 2592948182 | ||
|   | 6f6ab1c439 | ||
|   | b10e606dda | 
							
								
								
									
										11
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						| @@ -3,12 +3,19 @@ Author: | ||||
|  | ||||
| Contributors: | ||||
| * Stefanos Antaris <santaris@csd.auth.gr> | ||||
| * Mohammad Dib <mdib@qbittorrent.org> | ||||
| * Mirco Chinelli <infinity89@fastwebmail.it> | ||||
| * Ishan Arora <ishan@qbittorrent.org> | ||||
| * Arnaud Demaizière <arnaud@qbittorrent.org> | ||||
| * Grigis Gaëtan <cipher16@gmail.com> | ||||
| * Christian Kandeler <zambesi@users.sourceforge.net> | ||||
| * Silvan Scherrer <silvan.scherrer@aroa.ch> | ||||
|  | ||||
| Code from other projects: | ||||
| * files src/qtsingleapp/* | ||||
|   copyright: Nokia Corporation | ||||
|   license: LGPL | ||||
|  | ||||
| * files src/ico.cpp src/ico.h | ||||
|   copyright: Malte Starostik <malte@kde.org> | ||||
|   license: LGPL | ||||
| @@ -60,11 +67,13 @@ Images Authors: | ||||
| Translations authors: | ||||
| * files: src/lang/*.ts | ||||
|   copyright: | ||||
|   - Arabic: SDERAWI (abz8868@msn.com) and sn51234 (nesseyan@gmail.com) | ||||
|   - Brazilian: Nick Marinho (nickmarinho@gmail.com) | ||||
|   - Bulgarian: Tsvetan & Boiko Bankov (emerge_life@users.sourceforge.net) | ||||
|   - Bulgarian: Tsvetan & Boyko Bankoff (emerge_life@users.sourceforge.net) | ||||
|   - Catalan: Francisco Luque Contreras (frannoe@ya.com) | ||||
|   - Chinese (Simplified): Guo Yue (yue.guo0418@gmail.com) | ||||
|   - Chinese (Traditional): Yi-Shun Wang (dnextstep@gmail.com) | ||||
|   - Croatian: Oliver Mucafir (oliver.untwist@gmail.com) | ||||
|   - Czech: Jirka Vilim (web@tets.cz) | ||||
|   - Danish: Mathias Nielsen (comoneo@gmail.com) | ||||
|   - Dutch: Joost Schipper (heavyjoost@users.sourceforge.net) | ||||
|   | ||||
							
								
								
									
										106
									
								
								Changelog
									
									
									
									
									
								
							
							
						
						| @@ -1,4 +1,105 @@ | ||||
| * Unreleased - Christophe Dumez <chris@qbittorrent.org> - v2.2.0 | ||||
| * 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 | ||||
| @@ -15,6 +116,9 @@ | ||||
|     - FEATURE: Support for multiple scan folders (Patch by Christian Kandeler) | ||||
|     - BUGFIX: Only one log window can be opened at a time | ||||
|     - BUGFIX: Optimized RSS module memory usage | ||||
|     - BUGFIX: Consider HTTP downloads >1MB as invalid .torrent files and abort | ||||
|     - BUGFIX: Fix Web UI authentication with some browsers | ||||
|     - BUGFIX: Set Web UI ban period to 1 hour | ||||
|     - COSMETIC: Improved style management | ||||
|  | ||||
| * Mon Jan 18 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.1.0 | ||||
|   | ||||
							
								
								
									
										6
									
								
								INSTALL
									
									
									
									
									
								
							
							
						
						| @@ -14,11 +14,13 @@ qBittorrent - A BitTorrent client in C++ / Qt4 | ||||
|  | ||||
|     - pkg-config executable | ||||
|  | ||||
|     - libtorrent-rasterbar by Arvid Norberg (>= 0.14.4 REQUIRED, >= v0.15.0 ADVISED) | ||||
|     - libtorrent-rasterbar by Arvid Norberg (>= 0.14.4 REQUIRED, compatible with v0.15.x) | ||||
|         -> http://www.libtorrent.net | ||||
|         Be careful: another library (the one used by rTorrent) uses a similar name. | ||||
|  | ||||
|     - libboost: libboost-filesystem, libboost-date-time, libboost-thread, libboost-serialization | ||||
|     - libboost 1.34.x (libboost-filesystem, libboost-thread, libboost-date-time) + libasio | ||||
|       or | ||||
|     - libboost >= 1.35.x (libboost-system, libboost-filesystem, libboost-thread, libboost-date-time) | ||||
|  | ||||
|     - python >= 2.3 (needed by search engine) | ||||
|         * Run time only dependency | ||||
|   | ||||
							
								
								
									
										62
									
								
								README.os2
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,62 @@ | ||||
| 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> | ||||
|  | ||||
|  | ||||
							
								
								
									
										90
									
								
								configure
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -21,6 +21,7 @@ Dependency options: | ||||
|   --disable-gui                      Disable qBittorrent Graphical user | ||||
|                                     interface for headless running | ||||
|   --with-libboost-inc=[path]         Path to libboost include files | ||||
|   --with-libboost-lib=[path]         Path to libboost library files | ||||
|   --disable-libnotify               Disable use of libnotify | ||||
|   --disable-geoip-database          Disable use of geoip-database | ||||
|   --with-geoip-database-embedded     Geoip Database will be embedded in | ||||
| @@ -152,6 +153,11 @@ while [ $# -gt 0 ]; do | ||||
| 			shift | ||||
| 			;; | ||||
|  | ||||
| 		--with-libboost-lib=*) | ||||
| 			QC_WITH_LIBBOOST_LIB=$optarg | ||||
| 			shift | ||||
| 			;; | ||||
|  | ||||
| 		--disable-libnotify) | ||||
| 			QC_DISABLE_libnotify="Y" | ||||
| 			shift | ||||
| @@ -190,6 +196,7 @@ echo DATADIR=$DATADIR | ||||
| echo EX_QTDIR=$EX_QTDIR | ||||
| echo QC_DISABLE_GUI=$QC_DISABLE_GUI | ||||
| echo QC_WITH_LIBBOOST_INC=$QC_WITH_LIBBOOST_INC | ||||
| echo QC_WITH_LIBBOOST_LIB=$QC_WITH_LIBBOOST_LIB | ||||
| echo QC_DISABLE_libnotify=$QC_DISABLE_libnotify | ||||
| echo QC_DISABLE_geoip_database=$QC_DISABLE_geoip_database | ||||
| echo QC_WITH_GEOIP_DATABASE_EMBEDDED=$QC_WITH_GEOIP_DATABASE_EMBEDDED | ||||
| @@ -312,11 +319,7 @@ public: | ||||
| 		if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) { | ||||
| 			conf->addDefine("DISABLE_GUI"); | ||||
| 		}	 | ||||
| 		if(QT_VERSION >= 0x040500) { | ||||
|                         conf->addDefine("QT_4_5"); | ||||
|                 } | ||||
| 		return(QT_VERSION >= 0x040400); | ||||
| 		 | ||||
| 	} | ||||
| }; | ||||
| #line 1 "pkg-config.qcm" | ||||
| @@ -352,25 +355,15 @@ public: | ||||
| 	bool exec(){ | ||||
| 		QStringList incs; | ||||
| 		QString req_ver = "0.14.4"; | ||||
| 		QString adv_ver = "0.15.0"; | ||||
| 		QString version, libs, other; | ||||
| 		VersionMode mode = VersionMin; | ||||
| 		if(!conf->findPkgConfig("libtorrent-rasterbar", mode, req_ver, &version, &incs, &libs, &other)) | ||||
| 			return false; | ||||
| 		for(int n = 0; n < incs.count(); ++n) | ||||
| 			conf->addIncludePath(incs[n]); | ||||
| 		//if(!libs.isEmpty()) | ||||
| 		//	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()); | ||||
| 		if(conf->getenv("QC_DISABLE_GUI").isEmpty()) { | ||||
|   		  conf->addLib("-lcrypto"); | ||||
|                 } | ||||
| 		return true; | ||||
| 	} | ||||
| }; | ||||
| @@ -379,14 +372,39 @@ public: | ||||
| -----BEGIN QCMOD----- | ||||
| name: libboost | ||||
| arg: with-libboost-inc=[path], Path to libboost include files | ||||
| arg: with-libboost-lib=[path], Path to libboost library files | ||||
| -----END QCMOD----- | ||||
| */ | ||||
| #include <boost/version.hpp> | ||||
| class qc_libboost : public ConfObj | ||||
| { | ||||
| public: | ||||
| 	qc_libboost(Conf *c) : ConfObj(c) {} | ||||
| 	QString name() 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(){ | ||||
|         	QString s; | ||||
| 		s = conf->getenv("QC_WITH_LIBBOOST_INC"); | ||||
| @@ -428,6 +446,43 @@ public: | ||||
|       			} | ||||
| 		} | ||||
| 		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; | ||||
| 	} | ||||
| }; | ||||
| @@ -1487,6 +1542,7 @@ export DATADIR | ||||
| export EX_QTDIR | ||||
| export QC_DISABLE_GUI | ||||
| export QC_WITH_LIBBOOST_INC | ||||
| export QC_WITH_LIBBOOST_LIB | ||||
| export QC_DISABLE_libnotify | ||||
| export QC_DISABLE_geoip_database | ||||
| export QC_WITH_GEOIP_DATABASE_EMBEDDED | ||||
|   | ||||
| @@ -2,14 +2,39 @@ | ||||
| -----BEGIN QCMOD----- | ||||
| name: libboost | ||||
| arg: with-libboost-inc=[path], Path to libboost include files | ||||
| arg: with-libboost-lib=[path], Path to libboost library files | ||||
| -----END QCMOD----- | ||||
| */ | ||||
| #include <boost/version.hpp> | ||||
| class qc_libboost : public ConfObj | ||||
| { | ||||
| public: | ||||
| 	qc_libboost(Conf *c) : ConfObj(c) {} | ||||
| 	QString name() 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(){ | ||||
|         	QString s; | ||||
| 		s = conf->getenv("QC_WITH_LIBBOOST_INC"); | ||||
| @@ -51,6 +76,43 @@ public: | ||||
|       			} | ||||
| 		} | ||||
| 		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; | ||||
| 	} | ||||
| }; | ||||
|   | ||||
| @@ -13,25 +13,15 @@ public: | ||||
| 	bool exec(){ | ||||
| 		QStringList incs; | ||||
| 		QString req_ver = "0.14.4"; | ||||
| 		QString adv_ver = "0.15.0"; | ||||
| 		QString version, libs, other; | ||||
| 		VersionMode mode = VersionMin; | ||||
| 		if(!conf->findPkgConfig("libtorrent-rasterbar", mode, req_ver, &version, &incs, &libs, &other)) | ||||
| 			return false; | ||||
| 		for(int n = 0; n < incs.count(); ++n) | ||||
| 			conf->addIncludePath(incs[n]); | ||||
| 		//if(!libs.isEmpty()) | ||||
| 		//	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()); | ||||
| 		if(conf->getenv("QC_DISABLE_GUI").isEmpty()) { | ||||
|   		  conf->addLib("-lcrypto"); | ||||
|                 } | ||||
| 		return true; | ||||
| 	} | ||||
| }; | ||||
|   | ||||
| @@ -15,10 +15,6 @@ public: | ||||
| 		if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) { | ||||
| 			conf->addDefine("DISABLE_GUI"); | ||||
| 		}	 | ||||
| 		if(QT_VERSION >= 0x040500) { | ||||
|                         conf->addDefine("QT_4_5"); | ||||
|                 } | ||||
| 		return(QT_VERSION >= 0x040400); | ||||
| 		 | ||||
| 	} | ||||
| }; | ||||
|   | ||||
							
								
								
									
										163
									
								
								src/GUI.cpp
									
									
									
									
									
								
							
							
						
						
							
								
								
									
										12
									
								
								src/GUI.h
									
									
									
									
									
								
							
							
						
						| @@ -43,7 +43,6 @@ class Bittorrent; | ||||
| class QTimer; | ||||
| class downloadFromURL; | ||||
| class SearchEngine; | ||||
| class QLocalServer; | ||||
| class QCloseEvent; | ||||
| class RSSImp; | ||||
| class QShortcut; | ||||
| @@ -58,6 +57,7 @@ class StatusBar; | ||||
| class consoleDlg; | ||||
| class about; | ||||
| class createtorrent; | ||||
| class downloadFromURL; | ||||
|  | ||||
| class GUI : public QMainWindow, private Ui::MainWindow{ | ||||
|   Q_OBJECT | ||||
| @@ -69,6 +69,7 @@ public: | ||||
|   // Methods | ||||
|   int getCurrentTabIndex() const; | ||||
|   TransferListWidget* getTransferList() const { return transferList; } | ||||
|   QMenu* getTrayIconMenu(); | ||||
|  | ||||
| public slots: | ||||
|   void trackerAuthenticationRequired(QTorrentHandle& h); | ||||
| @@ -87,8 +88,6 @@ protected slots: | ||||
|   void on_actionWebsite_triggered() const; | ||||
|   void on_actionBugReport_triggered() const; | ||||
|   void on_actionShow_console_triggered(); | ||||
|   void readParamsOnSocket(); | ||||
|   void acceptConnection(); | ||||
|   void balloonClicked(); | ||||
|   void writeSettings(); | ||||
|   void readSettings(); | ||||
| @@ -110,11 +109,13 @@ protected slots: | ||||
|   void on_actionOpen_triggered(); | ||||
|   void updateGUI(); | ||||
|   void loadPreferences(bool configure_session=true); | ||||
|   void processParams(const QString& params); | ||||
|   void processParams(const QStringList& params); | ||||
|   void addTorrent(QString path); | ||||
|   void addUnauthenticatedTracker(const QPair<QTorrentHandle,QString> &tracker); | ||||
|   void processDownloadedFiles(QString path, QString url); | ||||
|   void finishedTorrent(QTorrentHandle& h) const; | ||||
|   void askRecursiveTorrentDownloadConfirmation(QTorrentHandle &h); | ||||
|   // Options slots | ||||
|   void on_actionOptions_triggered(); | ||||
|   void optionsSaved(); | ||||
| @@ -139,9 +140,10 @@ private: | ||||
|   QPointer<consoleDlg> console; | ||||
|   QPointer<about> aboutDlg; | ||||
|   QPointer<createtorrent> createTorrentDlg; | ||||
|   QPointer<downloadFromURL> downloadFromURLDialog; | ||||
|   QPointer<QSystemTrayIcon> systrayIcon; | ||||
|   QPointer<QTimer> systrayCreator; | ||||
|   QMenu *myTrayIconMenu; | ||||
|   QPointer<QMenu> myTrayIconMenu; | ||||
|   TransferListWidget *transferList; | ||||
|   TransferListFiltersWidget *transferListFilters; | ||||
|   PropertiesWidget *properties; | ||||
| @@ -161,8 +163,6 @@ private: | ||||
|   SearchEngine *searchEngine; | ||||
|   // RSS | ||||
|   QPointer<RSSImp> rssWidget; | ||||
|   // Misc | ||||
|   QLocalServer *localServer; | ||||
| }; | ||||
|  | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								src/Icons/flags/saoudi_arabia.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 546 B | 
| @@ -1,8 +1,9 @@ | ||||
| [Desktop Entry] | ||||
| Categories=Qt;Network;P2P; | ||||
| Comment=V2.2.0 | ||||
| Comment=V2.2.10 | ||||
| Exec=qbittorrent %f | ||||
| GenericName=Bittorrent client | ||||
| GenericName[ar]=العميل Bittorrent | ||||
| GenericName[bg]=Торент клиент | ||||
| GenericName[cs]=Bittorrent klient | ||||
| GenericName[de]=Bittorren Client | ||||
| @@ -10,6 +11,7 @@ GenericName[el]=Bittorrent πελάτης | ||||
| GenericName[es]=Cliente Bittorrent | ||||
| GenericName[fi]=Bittorrent-ohjelma | ||||
| GenericName[fr]=Client Bittorrent | ||||
| GenericName[hr]=Bittorrent klijent | ||||
| GenericName[hu]=Bittorrent kliens | ||||
| GenericName[it]=Client Bittorrent | ||||
| GenericName[ja]=Bittorrent クライアント | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								src/Icons/qbittorrent_mac.icns
									
									
									
									
									
										Normal file
									
								
							
							
						
						| Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 80 KiB | 
| Before Width: | Height: | Size: 910 B After Width: | Height: | Size: 1.7 KiB | 
| Before Width: | Height: | Size: 2.2 KiB | 
| Before Width: | Height: | Size: 680 B After Width: | Height: | Size: 2.3 KiB | 
							
								
								
									
										60
									
								
								src/Info.plist
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,60 @@ | ||||
| <?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.10</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,19 +54,21 @@ class about : public QDialog, private Ui::AboutDlg{ | ||||
|       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("<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 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) for working on qBittorrent port to Windows.</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 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>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")); | ||||
|       // Translation | ||||
|       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(QString::fromUtf8( | ||||
|           "<i>- <u>Brazilian:</u> Nick Marinho (nickmarinho@gmail.com)<br>\ | ||||
|           - <u>Bulgarian:</u> Tsvetan & Boiko Bankov (emerge_life@users.sourceforge.net)<br>\ | ||||
|           "<i><u>Arabic:</u> SDERAWI (abz8868@msn.com) and sn51234 (nesseyan@gmail.com)<br>\ | ||||
|           - <u>Brazilian:</u> Nick Marinho (nickmarinho@gmail.com)<br>\ | ||||
|           - <u>Bulgarian:</u> Tsvetan & Boyko Bankoff (emerge_life@users.sourceforge.net)<br>\ | ||||
|           - <u>Catalan:</u> Francisco Luque Contreras (frannoe@ya.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>Croatian:</u> Oliver Mucafir (oliver.untwist@gmail.com)<br>\ | ||||
|           - <u>Czech:</u> Jirka Vilim (web@tets.cz)<br>\ | ||||
|           - <u>Danish:</u> Mathias Nielsen (comoneo@gmail.com)<br>\ | ||||
|           - <u>Dutch:</u> Joost Schipper (heavyjoost@users.sourceforge.net) and Peter Koeleman (peter@peerweb.nl)<br>\ | ||||
| @@ -92,6 +94,9 @@ class about : public QDialog, private Ui::AboutDlg{ | ||||
|       te_translation->scrollToAnchor(QString::fromUtf8("top")); | ||||
|       // License | ||||
|       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\ | ||||
| addition of the following special exception:\ | ||||
| <br><br>\ | ||||
| @@ -438,6 +443,7 @@ exception statement from your version.</i>\ | ||||
|           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>\ | ||||
|           Public License instead of this License.<br>")); | ||||
| #endif | ||||
|           te_license->scrollToAnchor(QString::fromUtf8("top")); | ||||
|           show(); | ||||
|     } | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
| #include <QHeaderView> | ||||
| #include <QSpinBox> | ||||
| #include <QCheckBox> | ||||
| #include <libtorrent/version.hpp> | ||||
| #include "preferences.h" | ||||
|  | ||||
| enum AdvSettingsCols {PROPERTY, VALUE}; | ||||
|   | ||||
| @@ -41,7 +41,9 @@ | ||||
| #include <QPalette> | ||||
| #endif | ||||
| #include <QPointer> | ||||
| #include <QTimer> | ||||
|  | ||||
| #include <libtorrent/version.hpp> | ||||
| #include <libtorrent/session.hpp> | ||||
| #include <libtorrent/ip_filter.hpp> | ||||
| #include "qtorrenthandle.h" | ||||
| @@ -62,7 +64,7 @@ public: | ||||
|   QString name_or_url; | ||||
|   QString last_message; | ||||
|   unsigned long num_peers; | ||||
| #ifndef LIBTORRENT_0_15 | ||||
| #if LIBTORRENT_VERSION_MINOR < 15 | ||||
|   bool verified; | ||||
|   uint fail_count; | ||||
| #endif | ||||
| @@ -73,13 +75,13 @@ public: | ||||
|     Q_ASSERT(!name_or_url.isEmpty()); | ||||
|     last_message = b.last_message; | ||||
|     num_peers = b.num_peers; | ||||
| #ifndef LIBTORRENT_0_15 | ||||
| #if LIBTORRENT_VERSION_MINOR < 15 | ||||
|     verified = b.verified; | ||||
|     fail_count = b.fail_count; | ||||
| #endif | ||||
|   } | ||||
|   TrackerInfos(QString name_or_url): name_or_url(name_or_url), last_message(""), num_peers(0) { | ||||
| #ifndef LIBTORRENT_0_15 | ||||
| #if LIBTORRENT_VERSION_MINOR < 15 | ||||
|     fail_count = 0; | ||||
|     verified = false; | ||||
| #endif | ||||
| @@ -115,13 +117,14 @@ public: | ||||
|   qlonglong getETA(QString hash); | ||||
|   bool useTemporaryFolder() const; | ||||
|   QString getDefaultSavePath() const; | ||||
|   ScanFoldersModel* getScanFoldersModel() const; | ||||
| #if LIBTORRENT_VERSION_MINOR < 15 | ||||
|   void saveDHTEntry(); | ||||
| #endif | ||||
|  | ||||
| public slots: | ||||
|   QTorrentHandle addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), 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 saveSessionState(); | ||||
|   void downloadFromUrl(QString url); | ||||
| @@ -136,7 +139,6 @@ public slots: | ||||
|   void resumeTorrent(QString hash); | ||||
|   void resumeAllTorrents(); | ||||
|   /* End Web UI */ | ||||
|   void saveDHTEntry(); | ||||
|   void preAllocateAllFiles(bool b); | ||||
|   void saveFastResumeData(); | ||||
|   void enableIPFilter(QString filter); | ||||
| @@ -162,7 +164,7 @@ public slots: | ||||
|   void setAppendLabelToSavePath(bool append); | ||||
|   void appendLabelToTorrentSavePath(QTorrentHandle h); | ||||
|   void changeLabelInTorrentSavePath(QTorrentHandle h, QString old_label, QString new_label); | ||||
| #ifdef LIBTORRENT_0_15 | ||||
| #if LIBTORRENT_VERSION_MINOR > 14 | ||||
|   void appendqBextensionToTorrent(QTorrentHandle h, bool append); | ||||
|   void setAppendqBExtension(bool append); | ||||
| #endif | ||||
| @@ -184,6 +186,7 @@ public slots: | ||||
|   void downloadFromURLList(const QStringList& urls); | ||||
|   void configureSession(); | ||||
|   void banIP(QString ip); | ||||
|   void recursiveTorrentDownload(const QTorrentHandle &h); | ||||
|  | ||||
| protected: | ||||
|   QString getSavePath(QString hash, bool fromScanDir = false, QString filePath = QString()); | ||||
| @@ -195,6 +198,7 @@ protected slots: | ||||
|   void deleteBigRatios(); | ||||
|   void takeETASamples(); | ||||
|   void exportTorrentFiles(QString path); | ||||
|   void saveTempFastResumeData(); | ||||
|  | ||||
| signals: | ||||
|   void addedTorrent(QTorrentHandle& h); | ||||
| @@ -204,7 +208,7 @@ signals: | ||||
|   void finishedTorrent(QTorrentHandle& h); | ||||
|   void fullDiskError(QTorrentHandle& h, QString msg); | ||||
|   void trackerError(QString hash, QString time, QString msg); | ||||
|   void trackerAuthenticationRequired(const QTorrentHandle& h); | ||||
|   void trackerAuthenticationRequired(QTorrentHandle& h); | ||||
|   void newDownloadedTorrent(QString path, QString url); | ||||
|   void updateFileSize(QString hash); | ||||
|   void downloadFromUrlFailure(QString url, QString reason); | ||||
| @@ -213,6 +217,7 @@ signals: | ||||
|   void savePathChanged(QTorrentHandle &h); | ||||
|   void newConsoleMessage(QString msg); | ||||
|   void alternativeSpeedsModeChanged(bool alternative); | ||||
|   void recursiveTorrentDownloadPossible(QTorrentHandle &h); | ||||
|  | ||||
| private: | ||||
|   // Bittorrent | ||||
| @@ -222,6 +227,7 @@ private: | ||||
|   QMap<QUrl, QString> savepath_fromurl; | ||||
|   QHash<QString, QHash<QString, TrackerInfos> > trackersInfos; | ||||
|   QStringList torrentsToPausedAfterChecking; | ||||
|   QTimer resumeDataTimer; | ||||
|   // Ratio | ||||
|   QPointer<QTimer> BigRatioTimer; | ||||
|   // HTTP | ||||
| @@ -244,7 +250,7 @@ private: | ||||
|   bool queueingEnabled; | ||||
|   bool appendLabelToSavePath; | ||||
|   bool torrentExport; | ||||
| #ifdef LIBTORRENT_0_15 | ||||
| #if LIBTORRENT_VERSION_MINOR > 14 | ||||
|   bool appendqBExtension; | ||||
| #endif | ||||
|   QString defaultSavePath; | ||||
|   | ||||
| @@ -46,6 +46,7 @@ class consoleDlg : public QDialog, private Ui_ConsoleDlg{ | ||||
|     consoleDlg(QWidget *parent, Bittorrent* _BTSession) : QDialog(parent) { | ||||
|       setupUi(this); | ||||
|       setAttribute(Qt::WA_DeleteOnClose); | ||||
|       setModal(true); | ||||
|       BTSession = _BTSession; | ||||
|       textConsole->setHtml(BTSession->getConsoleMessages().join("<br>")); | ||||
|       textBannedPeers->setHtml(BTSession->getPeerBanMessages().join("<br>")); | ||||
|   | ||||
| @@ -37,6 +37,7 @@ | ||||
| #include <boost/filesystem/fstream.hpp> | ||||
| #include <boost/bind.hpp> | ||||
|  | ||||
| #include <libtorrent/version.hpp> | ||||
| #include <libtorrent/entry.hpp> | ||||
| #include <libtorrent/bencode.hpp> | ||||
| #include <libtorrent/torrent_info.hpp> | ||||
| @@ -65,8 +66,9 @@ bool file_filter(boost::filesystem::path const& filename) | ||||
| createtorrent::createtorrent(QWidget *parent): QDialog(parent){ | ||||
|   setupUi(this); | ||||
|   setAttribute(Qt::WA_DeleteOnClose); | ||||
|   setModal(true); | ||||
|   creatorThread = new torrentCreatorThread(this); | ||||
|   connect(creatorThread, SIGNAL(creationSuccess(QString, const char*)), this, SLOT(handleCreationSuccess(QString, const char*))); | ||||
|   connect(creatorThread, SIGNAL(creationSuccess(QString, QString)), this, SLOT(handleCreationSuccess(QString, QString))); | ||||
|   connect(creatorThread, SIGNAL(creationFailure(QString)), this, SLOT(handleCreationFailure(QString))); | ||||
|   connect(creatorThread, SIGNAL(updateProgress(int)), this, SLOT(updateProgressBar(int))); | ||||
|   path::default_name_check(no_check); | ||||
| @@ -79,14 +81,22 @@ createtorrent::~createtorrent() { | ||||
|  | ||||
| void createtorrent::on_addFolder_button_clicked(){ | ||||
|   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); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void createtorrent::on_addFile_button_clicked(){ | ||||
|   QString file = QFileDialog::getOpenFileName(this, tr("Select a file to add to the torrent"), QDir::homePath(), QString(), 0, QFileDialog::ShowDirsOnly); | ||||
|   if(!file.isEmpty()) | ||||
|   QString file = QFileDialog::getOpenFileName(this, tr("Select a file to add to the torrent"), QDir::homePath()); | ||||
|   if(!file.isEmpty()) { | ||||
| #if defined(Q_WS_WIN) || defined(Q_OS_OS2) | ||||
|     file = file.replace("/", "\\"); | ||||
| #endif | ||||
|     textInputPath->setText(file); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void createtorrent::on_removeTracker_button_clicked() { | ||||
| @@ -178,28 +188,41 @@ void createtorrent::on_createButton_clicked(){ | ||||
|   } else { | ||||
|     return; | ||||
|   } | ||||
|   // Disable dialog | ||||
|   setEnabled(false); | ||||
|   // Set busy cursor | ||||
|   setCursor(QCursor(Qt::WaitCursor)); | ||||
|   // Actually create the torrent | ||||
|   QStringList url_seeds = allItems(URLSeeds_list); | ||||
|   QString comment = txt_comment->toPlainText(); | ||||
|   creatorThread->create(input, destination, trackers, url_seeds, comment, check_private->isChecked(), getPieceSize()); | ||||
| } | ||||
|  | ||||
| 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)); | ||||
| } | ||||
|  | ||||
| void createtorrent::handleCreationSuccess(QString path, const char* branch_path) { | ||||
| void createtorrent::handleCreationSuccess(QString path, QString branch_path) { | ||||
|   // Enable Dialog | ||||
|   setEnabled(true); | ||||
|   // Remove busy cursor | ||||
|   setCursor(QCursor(Qt::ArrowCursor)); | ||||
|   if(checkStartSeeding->isChecked()) { | ||||
|     // Create save path temp data | ||||
|     boost::intrusive_ptr<torrent_info> t; | ||||
|     try { | ||||
|       t = new torrent_info(path.toLocal8Bit().data()); | ||||
|       t = new torrent_info(path.toUtf8().data()); | ||||
|     } catch(std::exception&) { | ||||
|       QMessageBox::critical(0, tr("Torrent creation"), tr("Created torrent file is invalid. It won't be added to download list.")); | ||||
|       return; | ||||
|     } | ||||
|     QString hash = misc::toQString(t->info_hash()); | ||||
|     TorrentTempData::setSavePath(hash, QString(branch_path)); | ||||
| #ifdef LIBTORRENT_0_15 | ||||
|     TorrentTempData::setSavePath(hash, branch_path); | ||||
| #if LIBTORRENT_VERSION_MINOR > 14 | ||||
|     // Enable seeding mode (do not recheck the files) | ||||
|     TorrentTempData::setSeedingMode(hash, true); | ||||
| #endif | ||||
| @@ -209,6 +232,18 @@ void createtorrent::handleCreationSuccess(QString path, const char* branch_path) | ||||
|   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) { | ||||
|   progressBar->setValue(progress); | ||||
| } | ||||
| @@ -263,7 +298,7 @@ void torrentCreatorThread::run() { | ||||
|     // Set qBittorrent as creator and add user comment to | ||||
|     // torrent_info structure | ||||
|     t.set_creator(creator_str); | ||||
|     t.set_comment((const char*)comment.toLocal8Bit()); | ||||
|     t.set_comment((const char*)comment.toUtf8()); | ||||
|     // Is private ? | ||||
|     t.set_priv(is_private); | ||||
|     if(abort) return; | ||||
| @@ -271,7 +306,7 @@ void torrentCreatorThread::run() { | ||||
|     ofstream out(complete(path((const char*)save_path.toLocal8Bit())), std::ios_base::binary); | ||||
|     bencode(std::ostream_iterator<char>(out), t.generate()); | ||||
|     emit updateProgress(100); | ||||
|     emit creationSuccess(save_path, full_path.branch_path().string().c_str()); | ||||
|     emit creationSuccess(save_path, QString::fromUtf8(full_path.branch_path().string().c_str())); | ||||
|   } | ||||
|   catch (std::exception& e){ | ||||
|     emit creationFailure(QString::fromUtf8(e.what())); | ||||
|   | ||||
| @@ -58,13 +58,14 @@ 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 sendProgressSignal(int progress); | ||||
|     void abortCreation() { abort = true; } | ||||
|    | ||||
|   protected: | ||||
|     void run(); | ||||
|      | ||||
|   signals: | ||||
|     void creationFailure(QString msg); | ||||
|     void creationSuccess(QString path, const char* branch_path); | ||||
|     void creationSuccess(QString path, QString branch_path); | ||||
|  | ||||
|   signals: | ||||
|     void updateProgress(int progress); | ||||
| @@ -87,6 +88,7 @@ class createtorrent : public QDialog, private Ui::createTorrentDialog{ | ||||
|  | ||||
|   public slots: | ||||
|     void updateProgressBar(int progress); | ||||
|     void on_cancelButton_clicked(); | ||||
|  | ||||
|   protected slots: | ||||
|     void on_createButton_clicked(); | ||||
| @@ -97,7 +99,7 @@ class createtorrent : public QDialog, private Ui::createTorrentDialog{ | ||||
|     void on_addURLSeed_button_clicked(); | ||||
|     void on_removeURLSeed_button_clicked(); | ||||
|     void handleCreationFailure(QString msg); | ||||
|     void handleCreationSuccess(QString path, const char* branch_path); | ||||
|     void handleCreationSuccess(QString path, QString branch_path); | ||||
| }; | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -53,34 +53,49 @@ public: | ||||
|     setFixedHeight(BAR_HEIGHT); | ||||
|   } | ||||
|  | ||||
|   void setProgress(bitfield pieces) { | ||||
|   void setProgress(const bitfield &pieces, const bitfield &downloading_pieces) { | ||||
|     if(pieces.empty()) { | ||||
|       // Empty bar | ||||
|       QPixmap pix = QPixmap(1, 1); | ||||
|       pix.fill(); | ||||
|       pixmap = pix; | ||||
|     } else { | ||||
|       int nb_pieces = pieces.size(); | ||||
|       const int nb_pieces = pieces.size(); | ||||
|       // Reduce the number of pieces before creating the pixmap | ||||
|       // otherwise it can crash when there are too many pieces | ||||
|       if(nb_pieces > width()) { | ||||
|         int ratio = floor(nb_pieces/(double)width()); | ||||
|         QVector<bool> scaled_pieces; | ||||
|         const int ratio = floor(nb_pieces/(double)width()); | ||||
|         std::vector<bool> scaled_pieces; | ||||
|         std::vector<bool> scaled_downloading; | ||||
|         for(int i=0; i<nb_pieces; i+= ratio) { | ||||
|           bool have = true; | ||||
|           for(int j=i; j<qMin(i+ratio, nb_pieces); ++j) { | ||||
|             if(!pieces[i]) { have = false; break; } | ||||
|           } | ||||
|           scaled_pieces << have; | ||||
|           scaled_pieces.push_back(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); | ||||
|         pix.fill(); | ||||
|         QPainter painter(&pix); | ||||
|         for(int i=0; i<scaled_pieces.size(); ++i) { | ||||
|           if(scaled_pieces[i]) | ||||
|         for(uint i=0; i<scaled_pieces.size(); ++i) { | ||||
|           if(scaled_pieces[i]) { | ||||
|             painter.setPen(Qt::blue); | ||||
|           else | ||||
|             painter.setPen(Qt::white); | ||||
|           } else { | ||||
|             if(scaled_downloading[i]) { | ||||
|               painter.setPen(Qt::yellow); | ||||
|             } else { | ||||
|               painter.setPen(Qt::white); | ||||
|             } | ||||
|           } | ||||
|           painter.drawPoint(i,0); | ||||
|         } | ||||
|         pixmap = pix; | ||||
| @@ -89,10 +104,15 @@ public: | ||||
|         pix.fill(); | ||||
|         QPainter painter(&pix); | ||||
|         for(uint i=0; i<pieces.size(); ++i) { | ||||
|           if(pieces[i]) | ||||
|           if(pieces[i]) { | ||||
|             painter.setPen(Qt::blue); | ||||
|           else | ||||
|             painter.setPen(Qt::white); | ||||
|           } else { | ||||
|             if(downloading_pieces[i]) { | ||||
|               painter.setPen(Qt::yellow); | ||||
|             } else { | ||||
|               painter.setPen(Qt::white); | ||||
|             } | ||||
|           } | ||||
|           painter.drawPoint(i,0); | ||||
|         } | ||||
|         pixmap = pix; | ||||
|   | ||||
| @@ -47,6 +47,7 @@ class downloadFromURL : public QDialog, private Ui::downloadFromURL{ | ||||
|       setupUi(this); | ||||
|       setAttribute(Qt::WA_DeleteOnClose); | ||||
|       icon_lbl->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/url.png"))); | ||||
|       setModal(true); | ||||
|       show(); | ||||
|       // Paste clipboard if there is an URL in it | ||||
|       QString clip_txt = qApp->clipboard()->text(); | ||||
|   | ||||
| @@ -42,6 +42,9 @@ enum ProxyType {HTTP=1, SOCKS5=2, HTTP_PW=3, SOCKS5_PW=4, SOCKS4=5}; | ||||
| downloadThread::downloadThread(QObject* parent) : QObject(parent) { | ||||
|   networkManager = new QNetworkAccessManager(this); | ||||
|   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(){ | ||||
| @@ -51,7 +54,7 @@ downloadThread::~downloadThread(){ | ||||
| } | ||||
|  | ||||
| void downloadThread::processDlFinished(QNetworkReply* reply) { | ||||
|   QString url = reply->url().toString(); | ||||
|   QString url = reply->url().toEncoded().data(); | ||||
|   if(reply->error() != QNetworkReply::NoError) { | ||||
|     // Failure | ||||
|     emit downloadFailure(url, errorCodeToString(reply->error())); | ||||
| @@ -59,7 +62,7 @@ void downloadThread::processDlFinished(QNetworkReply* reply) { | ||||
|     QVariant redirection = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); | ||||
|     if(redirection.isValid()) { | ||||
|       // We should redirect | ||||
|       qDebug("Redirecting from %s to %s", url.toLocal8Bit().data(), redirection.toUrl().toString().toLocal8Bit().data()); | ||||
|       qDebug("Redirecting from %s to %s", qPrintable(url), qPrintable(redirection.toUrl().toString())); | ||||
|       redirect_mapping.insert(redirection.toUrl().toString(), url); | ||||
|       downloadUrl(redirection.toUrl().toString()); | ||||
|       return; | ||||
| @@ -70,24 +73,27 @@ void downloadThread::processDlFinished(QNetworkReply* reply) { | ||||
|     } | ||||
|     // Success | ||||
|     QString filePath; | ||||
|     QTemporaryFile tmpfile; | ||||
|     tmpfile.setAutoRemove(false); | ||||
|     if (tmpfile.open()) { | ||||
|       filePath = tmpfile.fileName(); | ||||
|       qDebug("Temporary filename is: %s", filePath.toLocal8Bit().data()); | ||||
|     QTemporaryFile *tmpfile = new QTemporaryFile; | ||||
|     tmpfile->setAutoRemove(false); | ||||
|     if (tmpfile->open()) { | ||||
|       filePath = tmpfile->fileName(); | ||||
|       qDebug("Temporary filename is: %s", qPrintable(filePath)); | ||||
|       if(reply->open(QIODevice::ReadOnly)) { | ||||
|         // TODO: Support GZIP compression | ||||
|         tmpfile.write(reply->readAll()); | ||||
|         tmpfile->write(reply->readAll()); | ||||
|         reply->close(); | ||||
|         tmpfile.close(); | ||||
|         tmpfile->close(); | ||||
|         delete tmpfile; | ||||
|         // Send finished signal | ||||
|         emit downloadFinished(url, filePath); | ||||
|       } else { | ||||
|         // Error when reading the request | ||||
|         tmpfile.close(); | ||||
|         tmpfile->close(); | ||||
|         delete tmpfile; | ||||
|         emit downloadFailure(url, tr("I/O Error")); | ||||
|       } | ||||
|     } else { | ||||
|       delete tmpfile; | ||||
|       emit downloadFailure(url, tr("I/O Error")); | ||||
|     } | ||||
|   } | ||||
| @@ -95,7 +101,12 @@ void downloadThread::processDlFinished(QNetworkReply* reply) { | ||||
|   reply->deleteLater(); | ||||
| } | ||||
|  | ||||
| void downloadThread::downloadUrl(QString url){ | ||||
| void downloadThread::downloadTorrentUrl(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 | ||||
|   applyProxySettings(); | ||||
|   // Process download request | ||||
| @@ -104,8 +115,27 @@ void downloadThread::downloadUrl(QString url){ | ||||
|   // Spoof Firefox 3.5 user agent to avoid | ||||
|   // 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"); | ||||
|   qDebug("Downloading %s...", request.url().toString().toLocal8Bit().data()); | ||||
|   networkManager->get(request); | ||||
|   qDebug("Downloading %s...", qPrintable(request.url().toString())); | ||||
|   return 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() { | ||||
| @@ -117,7 +147,7 @@ void downloadThread::applyProxySettings() { | ||||
|     QString IP = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/IP"), "0.0.0.0").toString(); | ||||
|     proxy.setHostName(IP); | ||||
|     QString port = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Port"), 8080).toString(); | ||||
|     qDebug("Using proxy: %s", (IP+QString(":")+port).toLocal8Bit().data()); | ||||
|     qDebug("Using proxy: %s", qPrintable(IP)); | ||||
|     proxy.setPort(port.toUShort()); | ||||
|     // Default proxy type is HTTP, we must change if it is SOCKS5 | ||||
|     if(intValue == SOCKS5 || intValue == SOCKS5_PW) { | ||||
| @@ -189,3 +219,11 @@ QString downloadThread::errorCodeToString(QNetworkReply::NetworkError status) { | ||||
|     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 | ||||
|   | ||||
| @@ -34,6 +34,7 @@ | ||||
| #include <QNetworkReply> | ||||
| #include <QObject> | ||||
| #include <QHash> | ||||
| #include <QSslError> | ||||
|  | ||||
| class QNetworkAccessManager; | ||||
|  | ||||
| @@ -51,7 +52,8 @@ signals: | ||||
| public: | ||||
|   downloadThread(QObject* parent); | ||||
|   ~downloadThread(); | ||||
|   void downloadUrl(QString url); | ||||
|   QNetworkReply* downloadUrl(QString url); | ||||
|   void downloadTorrentUrl(QString url); | ||||
|   //void setProxy(QString IP, int port, QString username, QString password); | ||||
|  | ||||
| protected: | ||||
| @@ -60,6 +62,10 @@ protected: | ||||
|  | ||||
| protected slots: | ||||
|   void processDlFinished(QNetworkReply* reply); | ||||
|   void checkDownloadSize(qint64 bytesReceived, qint64 bytesTotal); | ||||
| #ifndef QT_NO_OPENSSL | ||||
|   void ignoreSslErrors(QNetworkReply*,QList<QSslError>); | ||||
| #endif | ||||
|  | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -81,9 +81,10 @@ void engineSelectDlg::dropEvent(QDropEvent *event) { | ||||
|   QStringList files=event->mimeData()->text().split(QString::fromUtf8("\n")); | ||||
|   QString file; | ||||
|   foreach(file, files) { | ||||
|     qDebug("dropped %s", file.toLocal8Bit().data()); | ||||
|     qDebug("dropped %s", qPrintable(file)); | ||||
|     file = file.replace("file://", ""); | ||||
|     if(file.startsWith("http://", Qt::CaseInsensitive) || file.startsWith("https://", Qt::CaseInsensitive) || file.startsWith("ftp://", Qt::CaseInsensitive)) { | ||||
|       setCursor(QCursor(Qt::WaitCursor)); | ||||
|       downloader->downloadUrl(file); | ||||
|       continue; | ||||
|     } | ||||
| @@ -99,7 +100,7 @@ void engineSelectDlg::dropEvent(QDropEvent *event) { | ||||
| void engineSelectDlg::dragEnterEvent(QDragEnterEvent *event) { | ||||
|   QString mime; | ||||
|   foreach(mime, event->mimeData()->formats()){ | ||||
|     qDebug("mimeData: %s", mime.toLocal8Bit().data()); | ||||
|     qDebug("mimeData: %s", qPrintable(mime)); | ||||
|   } | ||||
|   if (event->mimeData()->hasFormat(QString::fromUtf8("text/plain")) || event->mimeData()->hasFormat(QString::fromUtf8("text/uri-list"))) { | ||||
|     event->acceptProposedAction(); | ||||
| @@ -108,6 +109,7 @@ void engineSelectDlg::dragEnterEvent(QDragEnterEvent *event) { | ||||
|  | ||||
| void engineSelectDlg::on_updateButton_clicked() { | ||||
|   // Download version file from update server on sourceforge | ||||
|   setCursor(QCursor(Qt::WaitCursor)); | ||||
|   downloader->downloadUrl(QString(UPDATE_URL)+"versions.txt"); | ||||
| } | ||||
|  | ||||
| @@ -125,18 +127,17 @@ void engineSelectDlg::toggleEngineState(QTreeWidgetItem *item, int) { | ||||
|  | ||||
| void engineSelectDlg::displayContextMenu(const QPoint&) { | ||||
|   QMenu myContextMenu(this); | ||||
|   QModelIndex index; | ||||
|   // Enable/disable pause/start action given the DL state | ||||
|   QList<QTreeWidgetItem *> items = pluginsTree->selectedItems(); | ||||
|   bool has_enable = false, has_disable = false; | ||||
|   QTreeWidgetItem *item; | ||||
|   foreach(item, items) { | ||||
|     QString id = item->text(ENGINE_ID); | ||||
|     if(supported_engines->value(id)->isEnabled() and !has_disable) { | ||||
|     if(supported_engines->value(id)->isEnabled() && !has_disable) { | ||||
|       myContextMenu.addAction(actionDisable); | ||||
|       has_disable = true; | ||||
|     } | ||||
|     if(!supported_engines->value(id)->isEnabled() and !has_enable) { | ||||
|     if(!supported_engines->value(id)->isEnabled() && !has_enable) { | ||||
|       myContextMenu.addAction(actionEnable); | ||||
|       has_enable = true; | ||||
|     } | ||||
| @@ -251,12 +252,12 @@ bool engineSelectDlg::isUpdateNeeded(QString plugin_name, float new_version) con | ||||
| } | ||||
|  | ||||
| void engineSelectDlg::installPlugin(QString path, QString plugin_name) { | ||||
|   qDebug("Asked to install plugin at %s", path.toLocal8Bit().data()); | ||||
|   qDebug("Asked to install plugin at %s", qPrintable(path)); | ||||
|   float new_version = SearchEngine::getPluginVersion(path); | ||||
|   qDebug("Version to be installed: %.2f", new_version); | ||||
|   if(!isUpdateNeeded(plugin_name, new_version)) { | ||||
|     qDebug("Apparently update is not needed, we have a more recent version"); | ||||
|     QMessageBox::information(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("A more recent version of %1 search engine plugin is already installed.", "%1 is the name of the search engine").arg(plugin_name.toLocal8Bit().data())); | ||||
|     QMessageBox::information(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("A more recent version of %1 search engine plugin is already installed.", "%1 is the name of the search engine").arg(plugin_name)); | ||||
|     return; | ||||
|   } | ||||
|   // Process with install | ||||
| @@ -280,12 +281,12 @@ void engineSelectDlg::installPlugin(QString path, QString plugin_name) { | ||||
|       // restore backup | ||||
|       QFile::copy(dest_path+".bak", dest_path); | ||||
|       QFile::remove(dest_path+".bak"); | ||||
|       QMessageBox::warning(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin could not be updated, keeping old version.", "%1 is the name of the search engine").arg(plugin_name.toLocal8Bit().data())); | ||||
|       QMessageBox::warning(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin could not be updated, keeping old version.", "%1 is the name of the search engine").arg(plugin_name)); | ||||
|       return; | ||||
|     } else { | ||||
|       // Remove broken file | ||||
|       QFile::remove(dest_path); | ||||
|       QMessageBox::warning(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin could not be installed.", "%1 is the name of the search engine").arg(plugin_name.toLocal8Bit().data())); | ||||
|       QMessageBox::warning(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin could not be installed.", "%1 is the name of the search engine").arg(plugin_name)); | ||||
|       return; | ||||
|     } | ||||
|   } | ||||
| @@ -294,10 +295,10 @@ void engineSelectDlg::installPlugin(QString path, QString plugin_name) { | ||||
|     QFile::remove(dest_path+".bak"); | ||||
|   } | ||||
|   if(update) { | ||||
|     QMessageBox::information(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin was successfully updated.", "%1 is the name of the search engine").arg(plugin_name.toLocal8Bit().data())); | ||||
|     QMessageBox::information(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin was successfully updated.", "%1 is the name of the search engine").arg(plugin_name)); | ||||
|     return; | ||||
|   } else { | ||||
|     QMessageBox::information(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin was successfully installed.", "%1 is the name of the search engine").arg(plugin_name.toLocal8Bit().data())); | ||||
|     QMessageBox::information(this, tr("Search plugin install")+" -- "+tr("qBittorrent"), tr("%1 search engine plugin was successfully installed.", "%1 is the name of the search engine").arg(plugin_name)); | ||||
|     return; | ||||
|   } | ||||
| } | ||||
| @@ -350,8 +351,10 @@ void engineSelectDlg::askForPluginUrl() { | ||||
|   QString url = QInputDialog::getText(this, tr("New search engine plugin URL"), | ||||
|                                       tr("URL:"), QLineEdit::Normal, | ||||
|                                       "http://", &ok); | ||||
|   if (ok && !url.isEmpty()) | ||||
|   if (ok && !url.isEmpty()) { | ||||
|     setCursor(QCursor(Qt::WaitCursor)); | ||||
|     downloader->downloadUrl(url); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void engineSelectDlg::askForLocalPlugin() { | ||||
| @@ -390,17 +393,18 @@ bool engineSelectDlg::parseVersionsFile(QString versions_file) { | ||||
|     plugin_name.chop(1); // remove trailing ':' | ||||
|     bool ok; | ||||
|     float version = list.last().toFloat(&ok); | ||||
|     qDebug("read line %s: %.2f", plugin_name.toLocal8Bit().data(), version); | ||||
|     qDebug("read line %s: %.2f", qPrintable(plugin_name), version); | ||||
|     if(!ok) continue; | ||||
|     file_correct = true; | ||||
|     if(isUpdateNeeded(plugin_name, version)) { | ||||
|       qDebug("Plugin: %s is outdated", plugin_name.toLocal8Bit().data()); | ||||
|       qDebug("Plugin: %s is outdated", qPrintable(plugin_name)); | ||||
|       // Downloading update | ||||
|       setCursor(QCursor(Qt::WaitCursor)); | ||||
|       downloader->downloadUrl(UPDATE_URL+plugin_name+".py"); | ||||
|       //downloader->downloadUrl(UPDATE_URL+plugin_name+".png"); | ||||
|       updated = true; | ||||
|     }else { | ||||
|       qDebug("Plugin: %s is up to date", plugin_name.toLocal8Bit().data()); | ||||
|       qDebug("Plugin: %s is up to date", qPrintable(plugin_name)); | ||||
|     } | ||||
|   } | ||||
|   // Close file | ||||
| @@ -414,7 +418,8 @@ bool engineSelectDlg::parseVersionsFile(QString versions_file) { | ||||
| } | ||||
|  | ||||
| void engineSelectDlg::processDownloadedFile(QString url, QString filePath) { | ||||
|   qDebug("engineSelectDlg received %s", url.toLocal8Bit().data()); | ||||
|   setCursor(QCursor(Qt::ArrowCursor)); | ||||
|   qDebug("engineSelectDlg received %s", qPrintable(url)); | ||||
|   if(url.endsWith("favicon.ico", Qt::CaseInsensitive)){ | ||||
|     // Icon downloaded | ||||
|     QImage fileIcon; | ||||
| @@ -455,8 +460,9 @@ void engineSelectDlg::processDownloadedFile(QString url, QString filePath) { | ||||
| } | ||||
|  | ||||
| void engineSelectDlg::handleDownloadFailure(QString url, QString reason) { | ||||
|   setCursor(QCursor(Qt::ArrowCursor)); | ||||
|   if(url.endsWith("favicon.ico", Qt::CaseInsensitive)){ | ||||
|     qDebug("Could not download favicon: %s, reason: %s", url.toLocal8Bit().data(), reason.toLocal8Bit().data()); | ||||
|     qDebug("Could not download favicon: %s, reason: %s", qPrintable(url), qPrintable(reason)); | ||||
|     return; | ||||
|   } | ||||
|   if(url.endsWith("versions.txt")) { | ||||
| @@ -467,6 +473,6 @@ void engineSelectDlg::handleDownloadFailure(QString url, QString reason) { | ||||
|     // a plugin update download has been failed | ||||
|     QString plugin_name = url.split('/').last(); | ||||
|     plugin_name.replace(".py", "", Qt::CaseInsensitive); | ||||
|     QMessageBox::warning(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("Sorry, %1 search plugin install failed.", "%1 is the name of the search engine").arg(plugin_name.toLocal8Bit().data())); | ||||
|     QMessageBox::warning(this, tr("Search plugin update")+" -- "+tr("qBittorrent"), tr("Sorry, %1 search plugin install failed.", "%1 is the name of the search engine").arg(plugin_name)); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -29,8 +29,10 @@ | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #include <libtorrent/version.hpp> | ||||
| #include "eventmanager.h" | ||||
| #include "bittorrent.h" | ||||
| #include "scannedfoldersmodel.h" | ||||
| #include "misc.h" | ||||
| #include "preferences.h" | ||||
| //#include "proplistdelegate.h" | ||||
| @@ -59,7 +61,7 @@ QList<QVariantMap> EventManager::getPropTrackersInfo(QString hash) const { | ||||
|       tracker["url"] = tracker_url; | ||||
|       TrackerInfos data = trackers_data.value(tracker_url, TrackerInfos(tracker_url)); | ||||
|       QString error_message = data.last_message.trimmed(); | ||||
| #ifdef LIBTORRENT_0_15 | ||||
| #if LIBTORRENT_VERSION_MINOR > 14 | ||||
|       if(it->verified) { | ||||
|         tracker["status"] = tr("Working"); | ||||
|       } else { | ||||
| @@ -103,7 +105,7 @@ QList<QVariantMap> EventManager::getPropFilesInfo(QString hash) const { | ||||
|   int i=0; | ||||
|   for(fi=t.begin_files(); fi != t.end_files(); fi++) { | ||||
|     QVariantMap file; | ||||
|     QString path = QDir::cleanPath(misc::toQString(fi->path.string())); | ||||
|     QString path = QDir::cleanPath(misc::toQStringU(fi->path.string())); | ||||
|     QString name = path.split('/').last(); | ||||
|     file["name"] = name; | ||||
|     file["size"] = misc::friendlyUnit((double)fi->size); | ||||
| @@ -129,10 +131,33 @@ void EventManager::setGlobalPreferences(QVariantMap m) const { | ||||
|     Preferences::setTempPathEnabled(m["temp_path_enabled"].toBool()); | ||||
|   if(m.contains("temp_path")) | ||||
|     Preferences::setTempPath(m["temp_path"].toString()); | ||||
|   if(m.contains("scan_dirs")) | ||||
|     Preferences::setScanDirs(m["scan_dirs"].toStringList()); | ||||
|   if(m.contains("download_in_scan_dirs")) | ||||
|     Preferences::setDownloadInScanDirs(m["download_in_scan_dirs"].toList()); | ||||
|   if(m.contains("scan_dirs") && m.contains("download_in_scan_dirs")) { | ||||
|     QVariantList download_at_path_tmp = m["download_in_scan_dirs"].toList(); | ||||
|     QList<bool> download_at_path; | ||||
|     foreach(QVariant var, download_at_path_tmp) { | ||||
|       download_at_path << var.toBool(); | ||||
|     } | ||||
|     QStringList old_folders = Preferences::getScanDirs(); | ||||
|     QStringList new_folders = m["scan_dirs"].toStringList(); | ||||
|     if(download_at_path.size() == new_folders.size()) { | ||||
|       Preferences::setScanDirs(new_folders); | ||||
|       Preferences::setDownloadInScanDirs(download_at_path); | ||||
|       foreach(const QString &old_folder, old_folders) { | ||||
|         // Update deleted folders | ||||
|         if(!new_folders.contains(old_folder)) { | ||||
|           BTSession->getScanFoldersModel()->removePath(old_folder); | ||||
|         } | ||||
|       } | ||||
|       int i = 0; | ||||
|       foreach(const QString &new_folder, new_folders) { | ||||
|         // Update new folders | ||||
|         if(!old_folders.contains(new_folder)) { | ||||
|           BTSession->getScanFoldersModel()->addPath(new_folder, download_at_path.at(i)); | ||||
|         } | ||||
|         ++i; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   if(m.contains("export_dir")) | ||||
|     Preferences::setExportDir(m["export_dir"].toString()); | ||||
|   if(m.contains("preallocate_all")) | ||||
| @@ -145,7 +170,7 @@ void EventManager::setGlobalPreferences(QVariantMap m) const { | ||||
|     Preferences::setMaxActiveTorrents(m["max_active_torrents"].toInt()); | ||||
|   if(m.contains("max_active_uploads")) | ||||
|     Preferences::setMaxActiveUploads(m["max_active_uploads"].toInt()); | ||||
| #ifdef LIBTORRENT_0_15 | ||||
| #if LIBTORRENT_VERSION_MINOR > 14 | ||||
|   if(m.contains("incomplete_files_ext")) | ||||
|     Preferences::useIncompleteFilesExtension(m["incomplete_files_ext"].toBool()); | ||||
| #endif | ||||
| @@ -169,6 +194,10 @@ void EventManager::setGlobalPreferences(QVariantMap m) const { | ||||
|   // Bittorrent | ||||
|   if(m.contains("dht")) | ||||
|     Preferences::setDHTEnabled(m["dht"].toBool()); | ||||
|   if(m.contains("dhtSameAsBT")) | ||||
|     Preferences::setDHTPortSameAsBT(m["dhtSameAsBT"].toBool()); | ||||
|   if(m.contains("dht_port")) | ||||
|     Preferences::setDHTPort(m["dht_port"].toInt()); | ||||
|   if(m.contains("pex")) | ||||
|     Preferences::setPeXEnabled(m["pex"].toBool()); | ||||
|   qDebug("Pex support: %d", (int)m["pex"].toBool()); | ||||
| @@ -232,7 +261,11 @@ QVariantMap EventManager::getGlobalPreferences() const { | ||||
|   data["temp_path_enabled"] = Preferences::isTempPathEnabled(); | ||||
|   data["temp_path"] = Preferences::getTempPath(); | ||||
|   data["scan_dirs"] = Preferences::getScanDirs(); | ||||
|   data["download_in_scan_dirs"] = Preferences::getDownloadInScanDirs(); | ||||
|   QVariantList var_list; | ||||
|   foreach(bool b, Preferences::getDownloadInScanDirs()) { | ||||
|     var_list << b; | ||||
|   } | ||||
|   data["download_in_scan_dirs"] = var_list; | ||||
|   data["export_dir_enabled"] = Preferences::isTorrentExportEnabled(); | ||||
|   data["export_dir"] = Preferences::getExportDir(); | ||||
|   data["preallocate_all"] = Preferences::preAllocateAllFiles(); | ||||
| @@ -240,7 +273,7 @@ QVariantMap EventManager::getGlobalPreferences() const { | ||||
|   data["max_active_downloads"] = Preferences::getMaxActiveDownloads(); | ||||
|   data["max_active_torrents"] = Preferences::getMaxActiveTorrents(); | ||||
|   data["max_active_uploads"] = Preferences::getMaxActiveUploads(); | ||||
| #ifdef LIBTORRENT_0_15 | ||||
| #if LIBTORRENT_VERSION_MINOR > 14 | ||||
|   data["incomplete_files_ext"] = Preferences::useIncompleteFilesExtension(); | ||||
| #endif | ||||
|   // Connection | ||||
| @@ -254,6 +287,8 @@ QVariantMap EventManager::getGlobalPreferences() const { | ||||
|   data["max_uploads_per_torrent"] = Preferences::getMaxUploadsPerTorrent(); | ||||
|   // Bittorrent | ||||
|   data["dht"] = Preferences::isDHTEnabled(); | ||||
|   data["dhtSameAsBT"] = Preferences::isDHTPortSameAsBT(); | ||||
|   data["dht_port"] = Preferences::getDHTPort(); | ||||
|   data["pex"] = Preferences::isPeXEnabled(); | ||||
|   data["lsd"] = Preferences::isLSDEnabled(); | ||||
|   data["encryption"] = Preferences::getEncryptionSetting(); | ||||
| @@ -295,23 +330,23 @@ QVariantMap EventManager::getPropGeneralInfo(QString hash) const { | ||||
|     data["creation_date"] = h.creation_date(); | ||||
|     // Comment | ||||
|     data["comment"] = h.comment(); | ||||
|     data["total_wasted"] = misc::friendlyUnit(h.total_failed_bytes()+h.total_redundant_bytes()); | ||||
|     data["total_uploaded"] = misc::friendlyUnit(h.all_time_upload()) + " ("+misc::friendlyUnit(h.total_payload_upload())+" "+tr("this session")+")"; | ||||
|     data["total_downloaded"] = misc::friendlyUnit(h.all_time_download()) + " ("+misc::friendlyUnit(h.total_payload_download())+" "+tr("this session")+")"; | ||||
|     data["total_wasted"] = QVariant(misc::friendlyUnit(h.total_failed_bytes()+h.total_redundant_bytes())); | ||||
|     data["total_uploaded"] = QVariant(misc::friendlyUnit(h.all_time_upload()) + " ("+misc::friendlyUnit(h.total_payload_upload())+" "+tr("this session")+")"); | ||||
|     data["total_downloaded"] = QVariant(misc::friendlyUnit(h.all_time_download()) + " ("+misc::friendlyUnit(h.total_payload_download())+" "+tr("this session")+")"); | ||||
|     if(h.upload_limit() <= 0) | ||||
|       data["up_limit"] = QString::fromUtf8("∞"); | ||||
|     else | ||||
|       data["up_limit"] = misc::friendlyUnit(h.upload_limit())+tr("/s", "/second (i.e. per second)"); | ||||
|       data["up_limit"] = QVariant(misc::friendlyUnit(h.upload_limit())+tr("/s", "/second (i.e. per second)")); | ||||
|     if(h.download_limit() <= 0) | ||||
|       data["dl_limit"] = QString::fromUtf8("∞"); | ||||
|     else | ||||
|       data["dl_limit"] =  misc::friendlyUnit(h.download_limit())+tr("/s", "/second (i.e. per second)"); | ||||
|       data["dl_limit"] =  QVariant(misc::friendlyUnit(h.download_limit())+tr("/s", "/second (i.e. per second)")); | ||||
|     QString elapsed_txt = misc::userFriendlyDuration(h.active_time()); | ||||
|     if(h.is_seed()) { | ||||
|       elapsed_txt += " ("+tr("Seeded for %1", "e.g. Seeded for 3m10s").arg(misc::userFriendlyDuration(h.seeding_time()))+")"; | ||||
|     } | ||||
|     data["time_elapsed"] = elapsed_txt; | ||||
|     data["nb_connections"] = QString::number(h.num_connections())+" ("+tr("%1 max", "e.g. 10 max").arg(QString::number(h.connections_limit()))+")"; | ||||
|     data["nb_connections"] = QVariant(QString::number(h.num_connections())+" ("+tr("%1 max", "e.g. 10 max").arg(QString::number(h.connections_limit()))+")"); | ||||
|     // Update ratio info | ||||
|     double ratio = BTSession->getRealRatio(h.hash()); | ||||
|     if(ratio > 100.) | ||||
|   | ||||
| @@ -28,15 +28,16 @@ public: | ||||
|     setColumnCount(1); | ||||
|     QTreeWidgetItem *___qtreewidgetitem = headerItem(); | ||||
|     ___qtreewidgetitem->setText(0, QApplication::translate("RSS", "RSS feeds", 0, QApplication::UnicodeUTF8)); | ||||
|     connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(updateCurrentFeed(QTreeWidgetItem*))); | ||||
|     unread_item = new QTreeWidgetItem(this); | ||||
|     unread_item->setText(0, tr("Unread") + QString::fromUtf8("  (") + QString::number(rssmanager->getNbUnRead(), 10)+ QString(")")); | ||||
|     unread_item->setData(0,Qt::DecorationRole, QVariant(QIcon(":/Icons/oxygen/mail-folder-inbox.png"))); | ||||
|     itemAdded(unread_item, rssmanager); | ||||
|     connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(updateCurrentFeed(QTreeWidgetItem*))); | ||||
|     setCurrentItem(unread_item); | ||||
|   } | ||||
|  | ||||
|   ~FeedList() { | ||||
|     disconnect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(updateCurrentFeed(QTreeWidgetItem*))); | ||||
|     delete unread_item; | ||||
|   } | ||||
|  | ||||
| @@ -121,19 +122,19 @@ public: | ||||
|   } | ||||
|  | ||||
|   RssFile* getRSSItem(QTreeWidgetItem *item) const { | ||||
|     return mapping[item]; | ||||
|     return mapping.value(item, 0); | ||||
|   } | ||||
|  | ||||
|   RssFile::FileType getItemType(QTreeWidgetItem *item) const { | ||||
|     return mapping[item]->getType(); | ||||
|     return mapping.value(item)->getType(); | ||||
|   } | ||||
|  | ||||
|   QString getItemID(QTreeWidgetItem *item) const { | ||||
|     return mapping[item]->getID(); | ||||
|     return mapping.value(item)->getID(); | ||||
|   } | ||||
|  | ||||
|   QTreeWidgetItem* getTreeItemFromUrl(QString url) const{ | ||||
|     return feeds_items[url]; | ||||
|     return feeds_items.value(url, 0); | ||||
|   } | ||||
|  | ||||
|   RssStream* getRSSItemFromUrl(QString url) const { | ||||
|   | ||||