Compare commits
	
		
			116 Commits
		
	
	
		
			release-3.
			...
			release-2.
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | f6a58b3470 | ||
|   | 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 | 
							
								
								
									
										4
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						| @@ -60,11 +60,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) | ||||
|   | ||||
							
								
								
									
										83
									
								
								Changelog
									
									
									
									
									
								
							
							
						
						| @@ -1,4 +1,82 @@ | ||||
| * Unreleased - Christophe Dumez <chris@qbittorrent.org> - v2.2.0 | ||||
| * 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 +93,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> | ||||
|  | ||||
|  | ||||
							
								
								
									
										95
									
								
								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" | ||||
| @@ -361,16 +364,21 @@ public: | ||||
| 			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 | ||||
| 		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()); | ||||
| 		//QStringList params; | ||||
| 		//QByteArray staticlibs; | ||||
| 		//params << "--static" << "--libs" << "libtorrent-rasterbar"; | ||||
| 		//conf->doCommand("pkg-config", params, &staticlibs); | ||||
| 		//conf->addLib(staticlibs.trimmed()); | ||||
| 		//libcrypto | ||||
| 		if(conf->getenv("QC_DISABLE_GUI").isEmpty()) { | ||||
|   		  conf->addLib("-lcrypto"); | ||||
|                 } | ||||
| 		return true; | ||||
| 	} | ||||
| }; | ||||
| @@ -379,14 +387,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 +461,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 +1557,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; | ||||
| 	} | ||||
| }; | ||||
|   | ||||
| @@ -22,16 +22,21 @@ public: | ||||
| 			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 | ||||
| 		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()); | ||||
| 		//QStringList params; | ||||
| 		//QByteArray staticlibs; | ||||
| 		//params << "--static" << "--libs" << "libtorrent-rasterbar"; | ||||
| 		//conf->doCommand("pkg-config", params, &staticlibs); | ||||
| 		//conf->addLib(staticlibs.trimmed()); | ||||
| 		//libcrypto | ||||
| 		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); | ||||
| 		 | ||||
| 	} | ||||
| }; | ||||
|   | ||||
							
								
								
									
										54
									
								
								src/GUI.cpp
									
									
									
									
									
								
							
							
						
						| @@ -66,6 +66,11 @@ | ||||
| #include "propertieswidget.h" | ||||
| #include "statusbar.h" | ||||
|  | ||||
| #ifdef Q_WS_WIN | ||||
| #include <windows.h> | ||||
| const int UNLEN = 256; | ||||
| #endif | ||||
|  | ||||
| using namespace libtorrent; | ||||
|  | ||||
| #define TIME_TRAY_BALLOON 5000 | ||||
| @@ -117,6 +122,7 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis | ||||
|   connect(BTSession, SIGNAL(newDownloadedTorrent(QString, QString)), this, SLOT(processDownloadedFiles(QString, QString))); | ||||
|   connect(BTSession, SIGNAL(downloadFromUrlFailure(QString, QString)), this, SLOT(handleDownloadFromUrlFailure(QString, QString))); | ||||
|   connect(BTSession, SIGNAL(alternativeSpeedsModeChanged(bool)), this, SLOT(updateAltSpeedsBtn(bool))); | ||||
|   connect(BTSession, SIGNAL(recursiveTorrentDownloadPossible(QTorrentHandle&)), this, SLOT(askRecursiveTorrentDownloadConfirmation(QTorrentHandle&))); | ||||
|  | ||||
|   qDebug("create tabWidget"); | ||||
|   tabs = new QTabWidget(); | ||||
| @@ -160,7 +166,15 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis | ||||
|   processParams(torrentCmdLine); | ||||
|   // Use a tcp server to allow only one instance of qBittorrent | ||||
|   localServer = new QLocalServer(); | ||||
|   QString uid = QString::number(getuid()); | ||||
|   QString uid = ""; | ||||
| #ifdef Q_WS_WIN | ||||
|   char buffer[UNLEN+1] = {0}; | ||||
|   DWORD buffer_len = UNLEN + 1; | ||||
|   if (!GetUserNameA(buffer, &buffer_len)) | ||||
|     uid = QString(buffer); | ||||
| #else | ||||
|     uid = QString::number(getuid()); | ||||
| #endif | ||||
| #ifdef Q_WS_X11 | ||||
|   if(QFile::exists(QDir::tempPath()+QDir::separator()+QString("qBittorrent-")+uid)) { | ||||
|     // Socket was not closed cleanly | ||||
| @@ -227,6 +241,8 @@ GUI::~GUI() { | ||||
|     delete aboutDlg; | ||||
|   if(options) | ||||
|     delete options; | ||||
|   if(downloadFromURLDialog) | ||||
|     delete downloadFromURLDialog; | ||||
|   if(rssWidget) | ||||
|     delete rssWidget; | ||||
|   delete searchEngine; | ||||
| @@ -251,6 +267,12 @@ GUI::~GUI() { | ||||
|   delete switchRSSShortcut; | ||||
|   // Delete BTSession objects | ||||
|   delete BTSession; | ||||
|   // Deleting remaining top level widgets | ||||
|   qDebug("Deleting remaining top level widgets"); | ||||
|   foreach (QWidget *win, QApplication::topLevelWidgets()) { | ||||
|     if(win && win != this) | ||||
|       delete win; | ||||
|   } | ||||
|   // May freeze for a few seconds after the next line | ||||
|   // because the Bittorrent session proxy will | ||||
|   // actually be deleted now and destruction | ||||
| @@ -405,6 +427,12 @@ void GUI::readParamsOnSocket() { | ||||
|   } | ||||
| } | ||||
|  | ||||
| void GUI::askRecursiveTorrentDownloadConfirmation(QTorrentHandle &h) { | ||||
|   if(QMessageBox::question(this, tr("Recursive download confirmation"), tr("The torrent %1 contains torrent files, do you want to proceed with their download?").arg(h.name()), QMessageBox::Yes|QMessageBox::No) == QMessageBox::Yes) { | ||||
|     BTSession->recursiveTorrentDownload(h); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void GUI::handleDownloadFromUrlFailure(QString url, QString reason) const{ | ||||
|   // Display a message box | ||||
|   QMessageBox::critical(0, tr("Url download error"), tr("Couldn't download file at url: %1, reason: %2.").arg(url).arg(reason)); | ||||
| @@ -627,8 +655,8 @@ void GUI::on_actionOpen_triggered() { | ||||
|   // Open File Open Dialog | ||||
|   // Note: it is possible to select more than one file | ||||
|   const QStringList &pathsList = QFileDialog::getOpenFileNames(0, | ||||
|                                                         tr("Open Torrent Files"), settings.value(QString::fromUtf8("MainWindowLastDir"), QDir::homePath()).toString(), | ||||
|                                                         tr("Torrent Files")+QString::fromUtf8(" (*.torrent)")); | ||||
|                                                                tr("Open Torrent Files"), settings.value(QString::fromUtf8("MainWindowLastDir"), QDir::homePath()).toString(), | ||||
|                                                                tr("Torrent Files")+QString::fromUtf8(" (*.torrent)")); | ||||
|   if(!pathsList.empty()) { | ||||
|     const bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool(); | ||||
|     const uint listSize = pathsList.size(); | ||||
| @@ -800,12 +828,7 @@ void GUI::trackerAuthenticationRequired(QTorrentHandle& h) { | ||||
| void GUI::updateGUI() { | ||||
|   // update global informations | ||||
|   if(systrayIcon) { | ||||
| #ifdef Q_WS_WIN | ||||
|     // Windows does not support html here | ||||
|     QString html =tr("DL speed: %1 KiB/s", "e.g: Download speed: 10 KiB/s").arg(QString::number(BTSession->getPayloadDownloadRate()/1024., 'f', 1)); | ||||
|     html += "\n"; | ||||
|     html += tr("UP speed: %1 KiB/s", "e.g: Upload speed: 10 KiB/s").arg(QString::number(BTSession->getPayloadUploadRate()/1024., 'f', 1)); | ||||
| #else | ||||
| #if defined(Q_WS_X11) || defined(Q_WS_MAC) | ||||
|     QString html = "<div style='background-color: #678db2; color: #fff;height: 18px; font-weight: bold; margin-bottom: 5px;'>"; | ||||
|     html += tr("qBittorrent"); | ||||
|     html += "</div>"; | ||||
| @@ -815,6 +838,11 @@ void GUI::updateGUI() { | ||||
|     html += "<div style='vertical-align: baseline; height: 18px;'>"; | ||||
|     html += "<img src=':/Icons/skin/seeding.png'/> "+tr("UP speed: %1 KiB/s", "e.g: Upload speed: 10 KiB/s").arg(QString::number(BTSession->getPayloadUploadRate()/1024., 'f', 1)); | ||||
|     html += "</div>"; | ||||
| #else | ||||
|     // OSes such as Windows do not support html here | ||||
|     QString html =tr("DL speed: %1 KiB/s", "e.g: Download speed: 10 KiB/s").arg(QString::number(BTSession->getPayloadDownloadRate()/1024., 'f', 1)); | ||||
|     html += "\n"; | ||||
|     html += tr("UP speed: %1 KiB/s", "e.g: Upload speed: 10 KiB/s").arg(QString::number(BTSession->getPayloadUploadRate()/1024., 'f', 1)); | ||||
| #endif | ||||
|     systrayIcon->setToolTip(html); // tray icon | ||||
|   } | ||||
| @@ -829,7 +857,7 @@ void GUI::showNotificationBaloon(QString title, QString msg) const { | ||||
| #ifdef WITH_LIBNOTIFY | ||||
|     if (notify_init ("summary-body")) { | ||||
|       NotifyNotification* notification; | ||||
|       notification = notify_notification_new (title.toLocal8Bit().data(), msg.toLocal8Bit().data(), "qbittorrent", 0); | ||||
|       notification = notify_notification_new (qPrintable(title), qPrintable(msg), "qbittorrent", 0); | ||||
|       gboolean success = notify_notification_show (notification, NULL); | ||||
|       g_object_unref(G_OBJECT(notification)); | ||||
|       notify_uninit (); | ||||
| @@ -954,7 +982,9 @@ void GUI::on_actionOptions_triggered() { | ||||
| // Display an input dialog to prompt user for | ||||
| // an url | ||||
| void GUI::on_actionDownload_from_URL_triggered() { | ||||
|   downloadFromURL *downloadFromURLDialog = new downloadFromURL(this); | ||||
|   connect(downloadFromURLDialog, SIGNAL(urlsReadyToBeDownloaded(const QStringList&)), this, SLOT(downloadFromURLList(const QStringList&))); | ||||
|   if(!downloadFromURLDialog) { | ||||
|     downloadFromURLDialog = new downloadFromURL(this); | ||||
|     connect(downloadFromURLDialog, SIGNAL(urlsReadyToBeDownloaded(const QStringList&)), this, SLOT(downloadFromURLList(const QStringList&))); | ||||
|   } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -58,6 +58,7 @@ class StatusBar; | ||||
| class consoleDlg; | ||||
| class about; | ||||
| class createtorrent; | ||||
| class downloadFromURL; | ||||
|  | ||||
| class GUI : public QMainWindow, private Ui::MainWindow{ | ||||
|   Q_OBJECT | ||||
| @@ -115,6 +116,7 @@ protected slots: | ||||
|   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,6 +141,7 @@ private: | ||||
|   QPointer<consoleDlg> console; | ||||
|   QPointer<about> aboutDlg; | ||||
|   QPointer<createtorrent> createTorrentDlg; | ||||
|   QPointer<downloadFromURL> downloadFromURLDialog; | ||||
|   QPointer<QSystemTrayIcon> systrayIcon; | ||||
|   QPointer<QTimer> systrayCreator; | ||||
|   QMenu *myTrayIconMenu; | ||||
|   | ||||
							
								
								
									
										
											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.8 | ||||
| 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 クライアント | ||||
|   | ||||
| Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 79 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 | 
| @@ -62,11 +62,13 @@ class about : public QDialog, private Ui::AboutDlg{ | ||||
|       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(); | ||||
|     } | ||||
|   | ||||
| @@ -41,6 +41,7 @@ | ||||
| #include <QPalette> | ||||
| #endif | ||||
| #include <QPointer> | ||||
| #include <QTimer> | ||||
|  | ||||
| #include <libtorrent/session.hpp> | ||||
| #include <libtorrent/ip_filter.hpp> | ||||
| @@ -115,13 +116,11 @@ public: | ||||
|   qlonglong getETA(QString hash); | ||||
|   bool useTemporaryFolder() const; | ||||
|   QString getDefaultSavePath() const; | ||||
|   ScanFoldersModel* getScanFoldersModel() const; | ||||
|  | ||||
| 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 +135,9 @@ public slots: | ||||
|   void resumeTorrent(QString hash); | ||||
|   void resumeAllTorrents(); | ||||
|   /* End Web UI */ | ||||
| #ifndef LIBTORRENT_0_15 | ||||
|   void saveDHTEntry(); | ||||
| #endif | ||||
|   void preAllocateAllFiles(bool b); | ||||
|   void saveFastResumeData(); | ||||
|   void enableIPFilter(QString filter); | ||||
| @@ -184,6 +185,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 +197,7 @@ protected slots: | ||||
|   void deleteBigRatios(); | ||||
|   void takeETASamples(); | ||||
|   void exportTorrentFiles(QString path); | ||||
|   void saveTempFastResumeData(); | ||||
|  | ||||
| signals: | ||||
|   void addedTorrent(QTorrentHandle& h); | ||||
| @@ -204,7 +207,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 +216,7 @@ signals: | ||||
|   void savePathChanged(QTorrentHandle &h); | ||||
|   void newConsoleMessage(QString msg); | ||||
|   void alternativeSpeedsModeChanged(bool alternative); | ||||
|   void recursiveTorrentDownloadPossible(QTorrentHandle &h); | ||||
|  | ||||
| private: | ||||
|   // Bittorrent | ||||
| @@ -222,6 +226,7 @@ private: | ||||
|   QMap<QUrl, QString> savepath_fromurl; | ||||
|   QHash<QString, QHash<QString, TrackerInfos> > trackersInfos; | ||||
|   QStringList torrentsToPausedAfterChecking; | ||||
|   QTimer resumeDataTimer; | ||||
|   // Ratio | ||||
|   QPointer<QTimer> BigRatioTimer; | ||||
|   // HTTP | ||||
|   | ||||
| @@ -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>")); | ||||
|   | ||||
| @@ -65,6 +65,7 @@ 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(creationFailure(QString)), this, SLOT(handleCreationFailure(QString))); | ||||
| @@ -84,7 +85,7 @@ void createtorrent::on_addFolder_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(), 0, QFileDialog::ShowDirsOnly); | ||||
|   QString file = QFileDialog::getOpenFileName(this, tr("Select a file to add to the torrent"), QDir::homePath()); | ||||
|   if(!file.isEmpty()) | ||||
|     textInputPath->setText(file); | ||||
| } | ||||
| @@ -198,7 +199,7 @@ void createtorrent::handleCreationSuccess(QString path, const char* branch_path) | ||||
|       return; | ||||
|     } | ||||
|     QString hash = misc::toQString(t->info_hash()); | ||||
|     TorrentTempData::setSavePath(hash, QString(branch_path)); | ||||
|     TorrentTempData::setSavePath(hash, QString::fromLocal8Bit(branch_path)); | ||||
| #ifdef LIBTORRENT_0_15 | ||||
|     // Enable seeding mode (do not recheck the files) | ||||
|     TorrentTempData::setSeedingMode(hash, true); | ||||
|   | ||||
| @@ -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; | ||||
| @@ -74,7 +77,7 @@ void downloadThread::processDlFinished(QNetworkReply* reply) { | ||||
|     tmpfile.setAutoRemove(false); | ||||
|     if (tmpfile.open()) { | ||||
|       filePath = tmpfile.fileName(); | ||||
|       qDebug("Temporary filename is: %s", filePath.toLocal8Bit().data()); | ||||
|       qDebug("Temporary filename is: %s", qPrintable(filePath)); | ||||
|       if(reply->open(QIODevice::ReadOnly)) { | ||||
|         // TODO: Support GZIP compression | ||||
|         tmpfile.write(reply->readAll()); | ||||
| @@ -95,7 +98,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 +112,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 +144,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 +216,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,7 +81,7 @@ 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)) { | ||||
|       downloader->downloadUrl(file); | ||||
| @@ -99,7 +99,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(); | ||||
| @@ -251,12 +251,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 +280,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 +294,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; | ||||
|   } | ||||
| } | ||||
| @@ -390,17 +390,17 @@ 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 | ||||
|       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 +414,7 @@ bool engineSelectDlg::parseVersionsFile(QString versions_file) { | ||||
| } | ||||
|  | ||||
| void engineSelectDlg::processDownloadedFile(QString url, QString filePath) { | ||||
|   qDebug("engineSelectDlg received %s", url.toLocal8Bit().data()); | ||||
|   qDebug("engineSelectDlg received %s", qPrintable(url)); | ||||
|   if(url.endsWith("favicon.ico", Qt::CaseInsensitive)){ | ||||
|     // Icon downloaded | ||||
|     QImage fileIcon; | ||||
| @@ -456,7 +456,7 @@ void engineSelectDlg::processDownloadedFile(QString url, QString filePath) { | ||||
|  | ||||
| void engineSelectDlg::handleDownloadFailure(QString url, QString reason) { | ||||
|   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 +467,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)); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -31,6 +31,7 @@ | ||||
|  | ||||
| #include "eventmanager.h" | ||||
| #include "bittorrent.h" | ||||
| #include "scannedfoldersmodel.h" | ||||
| #include "misc.h" | ||||
| #include "preferences.h" | ||||
| //#include "proplistdelegate.h" | ||||
| @@ -129,10 +130,29 @@ 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 = m["download_in_scan_dirs"].toList(); | ||||
|     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).toBool()); | ||||
|         } | ||||
|         ++i; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   if(m.contains("export_dir")) | ||||
|     Preferences::setExportDir(m["export_dir"].toString()); | ||||
|   if(m.contains("preallocate_all")) | ||||
| @@ -169,6 +189,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()); | ||||
| @@ -254,6 +278,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 +321,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 { | ||||
|   | ||||
| @@ -46,7 +46,7 @@ | ||||
| #include "bittorrent.h" | ||||
| #include "ui_feeddownloader.h" | ||||
|  | ||||
| #ifdef QT_4_5 | ||||
| #if QT_VERSION >= 0x040500 | ||||
| #include <QHash> | ||||
| #else | ||||
| #include <QMap> | ||||
| @@ -64,11 +64,9 @@ public: | ||||
|  | ||||
|   bool matches(QString s) { | ||||
|     QStringList match_tokens = getMatchingTokens(); | ||||
|     //qDebug("Checking matching tokens: \"%s\"", getMatchingTokens_str().toLocal8Bit().data()); | ||||
|     foreach(const QString& token, match_tokens) { | ||||
|       if(token.isEmpty() || token == "") | ||||
|         continue; | ||||
|       //qDebug("Token: %s", token.toLocal8Bit().data()); | ||||
|       QRegExp reg(token, Qt::CaseInsensitive, QRegExp::Wildcard); | ||||
|       //reg.setMinimal(false); | ||||
|       if(reg.indexIn(s) < 0) return false; | ||||
| @@ -226,7 +224,7 @@ public: | ||||
|   void save() { | ||||
|     QSettings qBTRSS("qBittorrent", "qBittorrent-rss"); | ||||
|     QHash<QString, QVariant> all_feeds_filters = qBTRSS.value("feed_filters", QHash<QString, QVariant>()).toHash(); | ||||
|     qDebug("Saving filters for feed: %s (%d filters)", feed_url.toLocal8Bit().data(), (*this).size()); | ||||
|     qDebug("Saving filters for feed: %s (%d filters)", qPrintable(feed_url), (*this).size()); | ||||
|     all_feeds_filters[feed_url] = *this; | ||||
|     qBTRSS.setValue("feed_filters", all_feeds_filters); | ||||
|   } | ||||
| @@ -261,7 +259,6 @@ public: | ||||
|     // Restore saved info | ||||
|     enableDl_cb->setChecked(filters.isDownloadingEnabled()); | ||||
|     fillFiltersList(); | ||||
|     filtersList->sortItems(Qt::AscendingOrder); | ||||
|     if(filters.size() > 0) { | ||||
|       // Select first filter | ||||
|       filtersList->setCurrentItem(filtersList->item(0)); | ||||
| @@ -388,7 +385,6 @@ protected slots: | ||||
|       if(selected_filter == current_name) | ||||
|         selected_filter = new_name; | ||||
|       item->setText(new_name); | ||||
|       filtersList->sortItems(Qt::AscendingOrder); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -442,7 +438,6 @@ protected slots: | ||||
|       } | ||||
|     }while(!validated); | ||||
|     QListWidgetItem *it = new QListWidgetItem(filter_name, filtersList); | ||||
|     filtersList->sortItems(Qt::AscendingOrder); | ||||
|     filtersList->setCurrentItem(it); | ||||
|     //showFilterSettings(it); | ||||
|   } | ||||
|   | ||||
| @@ -2,10 +2,10 @@ | ||||
| #define FILESYSTEMWATCHER_H | ||||
|  | ||||
| #include <QFileSystemWatcher> | ||||
| #include <QDir> | ||||
|  | ||||
| #ifndef Q_WS_WIN | ||||
| #include <QTimer> | ||||
| #include <QDir> | ||||
| #include <QPointer> | ||||
| #include <QStringList> | ||||
| #include <QSet> | ||||
| @@ -49,10 +49,10 @@ protected: | ||||
|       file += QDir::separator(); | ||||
|     file += "."; | ||||
|     struct statfs buf; | ||||
|     if(!statfs(file.toLocal8Bit().data(), &buf)) { | ||||
|     if(!statfs(file.toLocal8Bit().constData(), &buf)) { | ||||
|       return (buf.f_type == (long)CIFS_MAGIC_NUMBER || buf.f_type == (long)NFS_SUPER_MAGIC); | ||||
|     } else { | ||||
|       std::cerr << "Error: statfs() call failed for " << file.toLocal8Bit().data() << ". Supposing it is a local folder..." << std::endl; | ||||
|       std::cerr << "Error: statfs() call failed for " << qPrintable(file) << ". Supposing it is a local folder..." << std::endl; | ||||
|       switch(errno) { | ||||
|       case EACCES: | ||||
|         std::cerr << "Search permission is denied for a component of the path prefix of the path" << std::endl; | ||||
| @@ -103,12 +103,6 @@ public: | ||||
|     connect(this, SIGNAL(directoryChanged(QString)), this, SLOT(scanLocalFolder(QString))); | ||||
|   } | ||||
|  | ||||
|   FileSystemWatcher(QString path, QObject *parent): QFileSystemWatcher(parent) { | ||||
|     filters << "*.torrent"; | ||||
|     connect(this, SIGNAL(directoryChanged(QString)), this, SLOT(scanLocalFolder(QString))); | ||||
|     addPath(path); | ||||
|   } | ||||
|  | ||||
|   ~FileSystemWatcher() { | ||||
| #ifndef Q_WS_WIN | ||||
|     if(watch_timer) | ||||
| @@ -148,7 +142,7 @@ public: | ||||
|     } else { | ||||
| #endif | ||||
|       // Normal mode | ||||
|       qDebug("FS Watching is watching %s in normal mode", path.toLocal8Bit().data()); | ||||
|       qDebug("FS Watching is watching %s in normal mode", qPrintable(path)); | ||||
|       QFileSystemWatcher::addPath(path); | ||||
|       scanLocalFolder(path); | ||||
| #ifndef Q_WS_WIN | ||||
| @@ -186,11 +180,12 @@ protected slots: | ||||
|   } | ||||
|  | ||||
|   void scanNetworkFolders() { | ||||
| #ifndef Q_WS_WIN | ||||
|     qDebug("scanNetworkFolders() called"); | ||||
|     QStringList torrents; | ||||
|     // Network folders scan | ||||
|     foreach (const QDir &dir, watched_folders) { | ||||
|       qDebug("FSWatcher: Polling manually folder %s", qPrintable(dir.path())); | ||||
|       //qDebug("FSWatcher: Polling manually folder %s", qPrintable(dir.path())); | ||||
|       addTorrentsFromDir(dir, torrents); | ||||
|     } | ||||
|     // Report detected torrent files | ||||
| @@ -198,6 +193,7 @@ protected slots: | ||||
|       qDebug("The following files are being reported: %s", qPrintable(torrents.join("\n"))); | ||||
|       emit torrentsAdded(torrents); | ||||
|     } | ||||
| #endif | ||||
|   } | ||||
|  | ||||
| signals: | ||||
|   | ||||
| @@ -86,9 +86,9 @@ public: | ||||
|     exportEmbeddedDb(); | ||||
| #endif | ||||
|     if(QFile::exists(geoipDBpath(false))) { | ||||
|       qDebug("Loading GeoIP database from %s...", geoipDBpath(false).toLocal8Bit().data()); | ||||
|       if(!s->load_country_db(geoipDBpath(false).toLocal8Bit().data())) { | ||||
|         std::cerr << "Failed to load Geoip Database at " << geoipDBpath(false).toLocal8Bit().data() << std::endl; | ||||
|       qDebug("Loading GeoIP database from %s...", qPrintable(geoipDBpath(false))); | ||||
|       if(!s->load_country_db(geoipDBpath(false).toLocal8Bit().constData())) { | ||||
|         std::cerr << "Failed to load Geoip Database at " << qPrintable(geoipDBpath(false)) << std::endl; | ||||
|       } | ||||
|     } else { | ||||
|       qDebug("ERROR: Impossible to find local Geoip Database"); | ||||
| @@ -188,6 +188,7 @@ public: | ||||
|       if(iso[1] == 'S') return QIcon(":/Icons/flags/serbia.png"); | ||||
|       break; | ||||
|     case 'S': | ||||
|       if(iso[1] == 'A') return QIcon(":/Icons/flags/saoudi_arabia.png"); | ||||
|       if(iso[1] == 'E') return QIcon(":/Icons/flags/sweden.png"); | ||||
|       if(iso[1] == 'K') return QIcon(":/Icons/flags/slovakia.png"); | ||||
|       if(iso[1] == 'G') return QIcon(":/Icons/flags/singapore.png"); | ||||
|   | ||||
| @@ -41,97 +41,98 @@ | ||||
| class HeadlessLoader: QObject { | ||||
|   Q_OBJECT | ||||
|  | ||||
|   private: | ||||
|     QLocalServer *localServer; | ||||
|     Bittorrent *BTSession; | ||||
|  | ||||
|   public: | ||||
|     HeadlessLoader(QStringList torrentCmdLine) { | ||||
|       // Enable Web UI | ||||
|       Preferences::setWebUiEnabled(true); | ||||
|       // Instanciate Bittorrent Object | ||||
|       BTSession = new Bittorrent(); | ||||
|       connect(BTSession, SIGNAL(newConsoleMessage(QString)), this, SLOT(displayConsoleMessage(QString))); | ||||
|       // Resume unfinished torrents | ||||
|       BTSession->startUpTorrents(); | ||||
|       // Process command line parameters | ||||
|       processParams(torrentCmdLine); | ||||
|       // Use a tcp server to allow only one instance of qBittorrent | ||||
|       localServer = new QLocalServer(); | ||||
|       QString uid = QString::number(getuid()); | ||||
| public: | ||||
|   HeadlessLoader(QStringList torrentCmdLine) { | ||||
|     // Enable Web UI | ||||
|     Preferences::setWebUiEnabled(true); | ||||
|     // Instanciate Bittorrent Object | ||||
|     BTSession = new Bittorrent(); | ||||
|     connect(BTSession, SIGNAL(newConsoleMessage(QString)), this, SLOT(displayConsoleMessage(QString))); | ||||
|     // Resume unfinished torrents | ||||
|     BTSession->startUpTorrents(); | ||||
|     // Process command line parameters | ||||
|     processParams(torrentCmdLine); | ||||
|     // Use a tcp server to allow only one instance of qBittorrent | ||||
|     localServer = new QLocalServer(); | ||||
|     const QString &uid = QString::number(getuid()); | ||||
| #ifdef Q_WS_X11 | ||||
|       if(QFile::exists(QDir::tempPath()+QDir::separator()+QString("qBittorrent-")+uid)) { | ||||
|         // Socket was not closed cleanly | ||||
|         std::cerr << "Warning: Local domain socket was not closed cleanly, deleting file...\n"; | ||||
|         QFile::remove(QDir::tempPath()+QDir::separator()+QString("qBittorrent-")+uid); | ||||
|       } | ||||
|     if(QFile::exists(QDir::tempPath()+QDir::separator()+QString("qBittorrent-")+uid)) { | ||||
|       // Socket was not closed cleanly | ||||
|       std::cerr << "Warning: Local domain socket was not closed cleanly, deleting file..." << std::endl; | ||||
|       QFile::remove(QDir::tempPath()+QDir::separator()+QString("qBittorrent-")+uid); | ||||
|     } | ||||
| #endif | ||||
|       if (!localServer->listen("qBittorrent-"+uid)) { | ||||
|         std::cerr  << "Couldn't create socket, single instance mode won't work...\n"; | ||||
|       } | ||||
|       connect(localServer, SIGNAL(newConnection()), this, SLOT(acceptConnection())); | ||||
|       // Display some information to the user | ||||
|       std::cout << std::endl << "******** " << tr("Information").toLocal8Bit().data() << " ********" << std::endl; | ||||
|       std::cout << tr("To control qBittorrent, access the Web UI at http://localhost:%1").arg(QString::number(Preferences::getWebUiPort())).toLocal8Bit().data() << std::endl; | ||||
|       std::cout << tr("The Web UI administrator user name is: %1").arg(Preferences::getWebUiUsername()).toLocal8Bit().data() << std::endl; | ||||
|       if(Preferences::getWebUiPassword() == "f6fdffe48c908deb0f4c3bd36c032e72") { | ||||
|         std::cout << tr("The Web UI administrator password is still the default one: %1").arg("adminadmin").toLocal8Bit().data() << std::endl; | ||||
|         std::cout << tr("This is a security risk, please consider changing your password from program preferences.").toLocal8Bit().data() << std::endl; | ||||
|       } | ||||
|     if (!localServer->listen("qBittorrent-"+uid)) { | ||||
|       std::cerr  << "Couldn't create socket, single instance mode won't work..." << std::endl; | ||||
|     } | ||||
|  | ||||
|     ~HeadlessLoader() { | ||||
|       delete BTSession; | ||||
|     connect(localServer, SIGNAL(newConnection()), this, SLOT(acceptConnection())); | ||||
|     // Display some information to the user | ||||
|     std::cout << std::endl << "******** " << qPrintable(tr("Information")) << " ********" << std::endl; | ||||
|     std::cout << qPrintable(tr("To control qBittorrent, access the Web UI at http://localhost:%1").arg(QString::number(Preferences::getWebUiPort()))) << std::endl; | ||||
|     std::cout << qPrintable(tr("The Web UI administrator user name is: %1").arg(Preferences::getWebUiUsername())) << std::endl; | ||||
|     if(Preferences::getWebUiPassword() == "f6fdffe48c908deb0f4c3bd36c032e72") { | ||||
|       std::cout << qPrintable(tr("The Web UI administrator password is still the default one: %1").arg("adminadmin")) << std::endl; | ||||
|       std::cout << qPrintable(tr("This is a security risk, please consider changing your password from program preferences.")) << std::endl; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   public slots: | ||||
|     // Call this function to exit qBittorrent headless loader | ||||
|     // and return to prompt (object will be deleted by main) | ||||
|     void exit() { | ||||
|      qApp->quit(); | ||||
|     } | ||||
|   ~HeadlessLoader() { | ||||
|     delete localServer; | ||||
|     delete BTSession; | ||||
|   } | ||||
|  | ||||
|     void displayConsoleMessage(QString msg) { | ||||
|       std::cout << msg.toLocal8Bit().data() << std::endl; | ||||
|     } | ||||
| public slots: | ||||
|   // Call this function to exit qBittorrent headless loader | ||||
|   // and return to prompt (object will be deleted by main) | ||||
|   void exit() { | ||||
|     qApp->quit(); | ||||
|   } | ||||
|  | ||||
|     // As program parameters, we can get paths or urls. | ||||
|     // This function parse the parameters and call | ||||
|     // the right addTorrent function, considering | ||||
|     // the parameter type. | ||||
|     void processParams(const QStringList& params) { | ||||
|       foreach(QString param, params) { | ||||
|         param = param.trimmed(); | ||||
|         if(param.startsWith("--")) continue; | ||||
|         if(param.startsWith(QString::fromUtf8("http://"), Qt::CaseInsensitive) || param.startsWith(QString::fromUtf8("ftp://"), Qt::CaseInsensitive) || param.startsWith(QString::fromUtf8("https://"), Qt::CaseInsensitive)) { | ||||
|           BTSession->downloadFromUrl(param); | ||||
|         }else{ | ||||
|           if(param.startsWith("magnet:", Qt::CaseInsensitive)) { | ||||
|             BTSession->addMagnetUri(param); | ||||
|           } else { | ||||
|             BTSession->addTorrent(param); | ||||
|           } | ||||
|   void displayConsoleMessage(QString msg) { | ||||
|     std::cout << qPrintable(msg) << std::endl; | ||||
|   } | ||||
|  | ||||
|   // As program parameters, we can get paths or urls. | ||||
|   // This function parse the parameters and call | ||||
|   // the right addTorrent function, considering | ||||
|   // the parameter type. | ||||
|   void processParams(const QStringList& params) { | ||||
|     foreach(QString param, params) { | ||||
|       param = param.trimmed(); | ||||
|       if(param.startsWith("--")) continue; | ||||
|       if(param.startsWith(QString::fromUtf8("http://"), Qt::CaseInsensitive) || param.startsWith(QString::fromUtf8("ftp://"), Qt::CaseInsensitive) || param.startsWith(QString::fromUtf8("https://"), Qt::CaseInsensitive)) { | ||||
|         BTSession->downloadFromUrl(param); | ||||
|       }else{ | ||||
|         if(param.startsWith("magnet:", Qt::CaseInsensitive)) { | ||||
|           BTSession->addMagnetUri(param); | ||||
|         } else { | ||||
|           BTSession->addTorrent(param); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|     void acceptConnection() { | ||||
|       QLocalSocket *clientConnection = localServer->nextPendingConnection(); | ||||
|       connect(clientConnection, SIGNAL(disconnected()), this, SLOT(readParamsOnSocket())); | ||||
|       qDebug("accepted connection from another instance"); | ||||
|     } | ||||
|   void acceptConnection() { | ||||
|     QLocalSocket *clientConnection = localServer->nextPendingConnection(); | ||||
|     connect(clientConnection, SIGNAL(disconnected()), this, SLOT(readParamsOnSocket())); | ||||
|     qDebug("accepted connection from another instance"); | ||||
|   } | ||||
|  | ||||
|     void readParamsOnSocket() { | ||||
|       QLocalSocket *clientConnection = static_cast<QLocalSocket*>(sender()); | ||||
|       if(clientConnection) { | ||||
|         QByteArray params = clientConnection->readAll(); | ||||
|         if(!params.isEmpty()) { | ||||
|           processParams(QString::fromUtf8(params.data()).split(QString::fromUtf8("\n"))); | ||||
|           qDebug("Received parameters from another instance"); | ||||
|         } | ||||
|         clientConnection->deleteLater(); | ||||
|   void readParamsOnSocket() { | ||||
|     QLocalSocket *clientConnection = static_cast<QLocalSocket*>(sender()); | ||||
|     if(clientConnection) { | ||||
|       const QByteArray ¶ms = clientConnection->readAll(); | ||||
|       if(!params.isEmpty()) { | ||||
|         processParams(QString(params).split("\n")); | ||||
|         qDebug("Received parameters from another instance"); | ||||
|       } | ||||
|       clientConnection->deleteLater(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| private: | ||||
|   QLocalServer *localServer; | ||||
|   Bittorrent *BTSession; | ||||
|  | ||||
| }; | ||||
|  | ||||
|   | ||||