Compare commits

..

684 Commits

Author SHA1 Message Date
Christophe Dumez
0b0d473a53 tagged v1.3.0 release 2009-01-14 12:37:31 +00:00
Christophe Dumez
f9f912906e - Fix version in qBittorrent.desktop 2009-01-11 10:19:02 +00:00
Christophe Dumez
7b4eee7a7d - Updated Changelog 2009-01-09 18:18:57 +00:00
Christophe Dumez
e799ac57ed - Updated TODO 2009-01-09 18:11:40 +00:00
Christophe Dumez
30c93b9a4a - v1.3.0final 2009-01-09 18:09:41 +00:00
Christophe Dumez
03dc617874 - Updated some translations 2009-01-06 20:38:52 +00:00
Christophe Dumez
bc29577a7b - Added some debug for proxy settings 2009-01-05 23:16:34 +00:00
Christophe Dumez
5509e94778 - Fixed pausing of queued torrents 2009-01-05 22:16:08 +00:00
Christophe Dumez
89330e11de - Priorities are now remembered across restart (bugfix) 2009-01-05 21:19:55 +00:00
Christophe Dumez
c016c4bf66 - Improved DHT code
- Remove outdated comment
2009-01-05 20:41:35 +00:00
Christophe Dumez
3f1081b621 BUGFIX: Proxy settings are now saved even if disabled 2009-01-05 11:42:37 +00:00
Christophe Dumez
e3ae03c8a8 - Ok, HTTP proxy code is working now 2009-01-05 11:20:32 +00:00
Christophe Dumez
fbe292d06e - Fixed another error in HTTP proxy code 2009-01-05 11:13:05 +00:00
Christophe Dumez
1d294e43f1 - Improve src/src.pro for windows 2009-01-04 19:48:16 +00:00
Christophe Dumez
d883ef27be - Use rootDir as default dir on Windows instead of homeDir 2009-01-04 19:37:55 +00:00
Christophe Dumez
be934837e5 - Fixed possible issue in tracker addition 2009-01-04 17:13:47 +00:00
Christophe Dumez
956f97f6d6 - Fixed systray icon tooltip on Windows 2009-01-04 17:08:52 +00:00
Christophe Dumez
de38ca3e23 - Updated Changelog 2009-01-04 15:45:44 +00:00
Christophe Dumez
1efaea46e3 - Made sure that old fastresume is overwritten when saving new one 2009-01-04 15:37:13 +00:00
Christophe Dumez
2694a0947f - Fixed possible crash when pausing a torrent 2009-01-04 12:44:55 +00:00
Christophe Dumez
f61d9d23f5 - Again 2009-01-04 11:33:18 +00:00
Christophe Dumez
60dda258b3 - typo in src.pro 2009-01-04 11:32:31 +00:00
Christophe Dumez
c79a4a746f - Attempt to fix linking on windows 2009-01-04 09:19:20 +00:00
Christophe Dumez
942b579d8e - Removed dependency on qdbus since we are not using it any longer 2009-01-04 00:05:08 +00:00
Christophe Dumez
93bc6dca95 - A lot of improvement in proxy code 2009-01-03 22:49:21 +00:00
Christophe Dumez
f36052351c - Added debug for proxy code 2009-01-03 22:33:05 +00:00
Christophe Dumez
d40c646561 - Removed useless check in proxy code 2009-01-03 22:26:45 +00:00
Christophe Dumez
9412ced722 - Important HTTP proxy fix 2009-01-03 22:24:56 +00:00
Christophe Dumez
7037b53ff8 - Another HTTP proxy fix 2009-01-03 22:20:57 +00:00
Christophe Dumez
adc72fb9a6 - Bump to rc6 2009-01-03 20:50:48 +00:00
Christophe Dumez
f0ca99ed6c - Fixed default state for UPnP/nat-pmp/lsd (DHT was fixed in previous commit already) 2009-01-03 20:45:07 +00:00
Christophe Dumez
e443aa75b7 - Quick fix for #313549 2009-01-03 20:33:38 +00:00
Christophe Dumez
282d0a4af6 - Save fastresume fata when pausing torrents to speed up qBittorrent shutdown 2009-01-03 20:06:46 +00:00
Christophe Dumez
25adf6b061 - Added a workaround fix for a bug in libtorrent regarding set_priority_up() function 2009-01-03 19:47:03 +00:00
Christophe Dumez
88f0ffe86d - Fixed column sorting restoring on startup 2009-01-03 19:34:09 +00:00
Christophe Dumez
c786c42bb1 - Fix for HTTP Proxy settings 2009-01-03 19:23:33 +00:00
Christophe Dumez
36bc2e96ba - Bump to rc5 2008-12-30 11:52:46 +00:00
Christophe Dumez
f9bf485ed7 - Forgot to consider allocating state in WebUI 2008-12-30 11:52:22 +00:00
Christophe Dumez
c18103539c - Display progress using progress bars in Web UI 2008-12-30 11:23:18 +00:00
Christophe Dumez
727f59f73f - Fix compilation warning 2008-12-30 09:02:06 +00:00
Christophe Dumez
5d2d1dfa94 - Compilation fix for MinGW 2008-12-30 08:57:23 +00:00
Christophe Dumez
cf694d14f3 - Updated Korean translation 2008-12-30 08:48:29 +00:00
Christophe Dumez
ec24fe2f49 - No longer force plastiqueStyle as a default (closes #312333) 2008-12-30 02:17:46 +00:00
Christophe Dumez
a0b4e54410 - Got rid of .paused files, useless with new libtorrent 2008-12-30 00:34:41 +00:00
Christophe Dumez
c97bce4d61 - Removed workaround for getting progress of paused torrents, apparently it works 2008-12-30 00:11:20 +00:00
Christophe Dumez
afbfe1a96d - Hide priority column in Web UI when queueing is disabled 2008-12-29 23:04:45 +00:00
Christophe Dumez
2651ec5f0b - Forgot to hide decrease Priority button when disabling queueing 2008-12-29 23:00:13 +00:00
Christophe Dumez
330905da5e - Added priority actions in Web UI 2008-12-29 22:46:18 +00:00
Christophe Dumez
4c6359276c - Fixed progress display of uncheck torrents 2008-12-29 22:09:39 +00:00
Christophe Dumez
ff1fc527e0 - Made some text bigger in options 2008-12-29 21:47:22 +00:00
Christophe Dumez
d79cb6b66e - French translation fix 2008-12-29 21:46:29 +00:00
Christophe Dumez
0ac2554060 - qBittorrent shutdown is now way faster 2008-12-29 21:22:26 +00:00
Christophe Dumez
1d31e049a4 - Fixed possible deadlock when saving fastresume data 2008-12-29 21:10:31 +00:00
Christophe Dumez
d5a4794610 - Fixed priority display for paused torrents 2008-12-29 20:06:08 +00:00
Christophe Dumez
29886acc01 - Putting back priority buttons in toolBar 2008-12-29 20:01:03 +00:00
Christophe Dumez
f1ed7f06b9 - Removed a function that is no longer used 2008-12-29 18:40:10 +00:00
Christophe Dumez
a848538d66 - Pause / resume in Web UI now updates the GUI
- Code cleanup
2008-12-29 18:36:54 +00:00
Christophe Dumez
b58046b1fc - Use QPlastiqueStyle as a default 2008-12-29 11:31:57 +00:00
Christophe Dumez
fe95e90e05 - Updated Changelog 2008-12-28 21:16:17 +00:00
Christophe Dumez
1544300616 - Allow to delete permanently from WebUI 2008-12-28 21:12:49 +00:00
Christophe Dumez
028041f874 - Updated Czech translation 2008-12-28 09:58:15 +00:00
Christophe Dumez
81f2d7ee4a - Cleaned up src.pro
- Removed some debug
2008-12-28 01:17:57 +00:00
Christophe Dumez
66874fbd2f - This is not needed because a showEvent is raised anyway 2008-12-27 22:40:23 +00:00
Christophe Dumez
f47b3be0be - Removed -O0 compil flag 2008-12-27 22:35:45 +00:00
Christophe Dumez
87eee7029d - Force lists refresh before initially displaying the window to avoid lag
- Removed session tweaking on exit since it does not have any effect
2008-12-27 22:29:37 +00:00
Christophe Dumez
713c80451e - Bump to rc3 2008-12-27 21:34:28 +00:00
Christophe Dumez
60889cac79 - Catch exceptions on torrent aditions to avoid crashing because of a bad torrent (that is correctly loaded by torrent_info for some reason) 2008-12-27 21:25:58 +00:00
Christophe Dumez
d398679c7e - Forgot to add this line back 2008-12-27 20:58:30 +00:00
Christophe Dumez
2e5330e54b - Removed code that is no longer needed 2008-12-27 20:35:25 +00:00
Christophe Dumez
1499138b9b - Fix to avoid crash when loading a path that does not exist 2008-12-27 20:30:19 +00:00
Christophe Dumez
2433a87445 - Bump to rc2 2008-12-27 17:55:46 +00:00
Christophe Dumez
d0de11909f - Translations fix due to latest change 2008-12-27 17:55:07 +00:00
Christophe Dumez
3f5340523f - Fix for queueing system 2008-12-27 17:44:33 +00:00
Christophe Dumez
cc5015773b - Should fix queueing system 2008-12-27 17:23:49 +00:00
Christophe Dumez
cd260198f9 - Fixed remembering of paused torrents cleanly 2008-12-27 17:05:26 +00:00
Christophe Dumez
71e3061c18 - Remember paused torrents on startup 2008-12-27 13:04:06 +00:00
Christophe Dumez
6369401150 - Fixed assert hit in new FSWatcher code 2008-12-27 12:12:13 +00:00
Christophe Dumez
fa05441e74 - A little list refresh optimizing 2008-12-27 10:29:44 +00:00
Christophe Dumez
81aac9ebcc - Fixed pause/resume actions in Web UI 2008-12-27 10:14:16 +00:00
Christophe Dumez
7a1af536b6 - Fixed start action 2008-12-27 10:07:03 +00:00
Christophe Dumez
45efcfce13 - Save session data and fast resume data sooner on exit (in case) 2008-12-27 10:02:42 +00:00
Christophe Dumez
cddc3a0a43 - Remove useless signals 2008-12-27 09:47:31 +00:00
Christophe Dumez
c38a8a2bec - Removed code that is no longer needed 2008-12-27 09:40:21 +00:00
Christophe Dumez
1225d16413 - Removed code that is no longer needed 2008-12-27 09:21:09 +00:00
Christophe Dumez
384f3b23ee - Made seed detection a bit safer (do not use progress) 2008-12-27 09:10:07 +00:00
Christophe Dumez
a3cfa6bba1 - Fixed torrents moving back from finished list to download list (without recheck) 2008-12-26 22:30:23 +00:00
Christophe Dumez
51638eddcc - Some more signal/slot fixing 2008-12-26 22:17:02 +00:00
Christophe Dumez
41c6a847b9 - some more signal / slot fixing 2008-12-26 22:11:40 +00:00
Christophe Dumez
d57062a45a - Fixed broken action "start All / Pause all" due to latest code changes 2008-12-26 22:02:01 +00:00
Christophe Dumez
32f478a8c2 - Removed some useless code due to latest changes 2008-12-26 21:59:54 +00:00
Christophe Dumez
61dae1444b - Code optimization for torrent moving back to download list detection 2008-12-26 21:49:13 +00:00
Christophe Dumez
8ed40cc856 - Do not refresh lists when window is not visible (save cpu)
- Force list refresh on show Event to avoid lag before next UpdateList() timer call
2008-12-26 21:41:09 +00:00
Christophe Dumez
941b8c8d2a - Fixed torrent completed message (was not displayed due to last commit) 2008-12-26 21:26:06 +00:00
Christophe Dumez
4f2a2dfab9 - Huge code refactoring (qBittorrent no longer store torrents and access them using libtorrent API) 2008-12-26 21:18:33 +00:00
Christophe Dumez
4a6ab376af - Workaround for is_seed bug: http://code.rasterbar.com/libtorrent/ticket/402 2008-12-26 19:14:19 +00:00
Christophe Dumez
1e37858cc4 - Reset torrent display once it is queued 2008-12-26 18:57:16 +00:00
Christophe Dumez
668268b6b5 - A little downloadThread aborting improvement 2008-12-26 16:43:55 +00:00
Christophe Dumez
cfcd9b7eaf - Fixed memory leak introduced in last commit 2008-12-26 16:27:52 +00:00
Christophe Dumez
6a3dddd0cc Catch SIGTERM to exit cleanly (e.g. computer shutdown) 2008-12-26 16:23:53 +00:00
Christophe Dumez
dfb2046f82 - Fixed icon for seeding torrents (paused or queued) in Web UI 2008-12-26 15:48:07 +00:00
Christophe Dumez
3ae55b6a6f - Fixed typo 2008-12-26 13:49:45 +00:00
Christophe Dumez
7e53d23e33 - Added some debug output on exit 2008-12-26 13:44:39 +00:00
Christophe Dumez
ce2294ee96 - Made session deletion a bit faster
- Fixed possible memory leak when folder scanning is enabled
2008-12-26 13:39:11 +00:00
Christophe Dumez
14646d0f9e Rewrote folder scanning code (Now uses a filesystem watcher) 2008-12-26 13:17:08 +00:00
Christophe Dumez
717a4b00e1 - Fixed piratebay plugin 2008-12-25 19:12:36 +00:00
Christophe Dumez
fca3b66a25 - Rewrote isohunt plugin which was broken 2008-12-25 18:56:04 +00:00
Christophe Dumez
1a861ef240 - Fixed BTJunkie plugin 2008-12-25 17:40:37 +00:00
Christophe Dumez
1590d9a98f - Updated Changelog 2008-12-25 16:22:46 +00:00
Christophe Dumez
112bcd7255 - Add notification in WebUI when qBittorrent is unreachable 2008-12-25 16:20:30 +00:00
Christophe Dumez
af29228cc9 - Updated Chinese (simplified) translation 2008-12-25 16:06:34 +00:00
Christophe Dumez
b8c79e0b5f - Simplified and optimized json code 2008-12-25 14:33:37 +00:00
Christophe Dumez
0d078f660a - fixed seed detection in eventmanager + code is simpler 2008-12-25 13:48:23 +00:00
Christophe Dumez
e7f89f256a - Updated slovak translation 2008-12-24 16:26:45 +00:00
Christophe Dumez
cb693a0795 - Removed outdated comment 2008-12-24 15:06:58 +00:00
Christophe Dumez
7b57345c4f - Fixed stylesheet warning in console on startup 2008-12-24 15:05:45 +00:00
Christophe Dumez
90879386d5 - Fixed Qt4 warning when deleting options 2008-12-24 14:53:40 +00:00
Christophe Dumez
3678aa4d23 - bump to rc1
- Updated TODO
- Fix for toolBar spacing
- A little code cleanup
2008-12-24 14:41:16 +00:00
Christophe Dumez
e497789ec7 - WebUI is now working for IE7 2008-12-24 11:28:02 +00:00
Christophe Dumez
2134d404a5 - Updated version to v1.3 (WebUI) 2008-12-24 10:05:09 +00:00
Christophe Dumez
e0707f6907 - Simplified page structure 2008-12-24 09:59:06 +00:00
Christophe Dumez
816f35cbab - Ported WebUI to MochaUI 0.9.5 2008-12-23 23:47:30 +00:00
Christophe Dumez
a73d3132df - Removed some useless debug
- Increased httpserver update interval
2008-12-23 16:50:46 +00:00
Christophe Dumez
368c122dce - Queueing system fix 2008-12-23 16:27:47 +00:00
Christophe Dumez
c41d17043c - Fixed another memory leak in torrent addition dialog 2008-12-23 15:51:32 +00:00
Christophe Dumez
3c17a1410b - Fixed memory leak in torrent addition dialog 2008-12-23 15:07:29 +00:00
Christophe Dumez
078110851d - Oops typo 2008-12-23 14:58:38 +00:00
Christophe Dumez
70725bdfe2 - Fixed memory leak in RSS parser 2008-12-23 14:56:17 +00:00
Christophe Dumez
3c0a610a34 - Fixed includes 2008-12-23 14:41:14 +00:00
Christophe Dumez
d5b74eecd0 - Updated french translation 2008-12-23 13:51:08 +00:00
Christophe Dumez
1faf183c73 - Updated some translations 2008-12-23 12:59:47 +00:00
Christophe Dumez
a1773a7cfd - Updated language files 2008-12-20 19:41:08 +00:00
Christophe Dumez
1af3515b00 - Updated splashscreen
- bump to beta
2008-12-15 19:28:09 +00:00
Christophe Dumez
70e2a5d3b3 - Fixed compilation warning in main.cpp
- Removed use of Qt3 backport headers in ico.cpp
2008-12-15 19:24:10 +00:00
Christophe Dumez
78409570a9 - Fixed crash when dht_state is missing 2008-12-15 17:28:05 +00:00
Christophe Dumez
5133931302 - Another patch by Attila to fix mingw32 compilation 2008-12-12 09:20:47 +00:00
Christophe Dumez
8326cebf5c - Fix for compiling with mingw32 (By Attila Olah) 2008-12-11 20:49:21 +00:00
Christophe Dumez
ab46f11af2 - Added name name of new turkish translator to about dialog 2008-11-28 14:30:07 +00:00
Christophe Dumez
91acb1a6ec Updated turkish translation 2008-11-28 14:27:56 +00:00
Christophe Dumez
c721fad54b - Fixed ratio column sorting 2008-11-22 14:05:22 +00:00
Christophe Dumez
2aea2a0032 - got rid of libMagick++ dependency 2008-11-04 22:39:43 +00:00
Christophe Dumez
3164337c3c - Some more cleanup 2008-11-04 19:14:51 +00:00
Christophe Dumez
b984c309ff - removed no longer needed pointer
- made use of QPointer instead of c++ pointer
2008-11-04 19:01:51 +00:00
Christophe Dumez
cfbd06225b - Removed priority buttons from toolBar since it only affects download list now 2008-11-02 20:42:02 +00:00
Christophe Dumez
b0a0abd764 Allow to change the save path of torrents after addition 2008-11-02 19:55:55 +00:00
Christophe Dumez
9618056b4e - Added support for 2 new extensions (uTorrent metadata and smart ban plugin)
- Removed option to disable uTorrent Peer eXchange (PeX) -> always ON
2008-11-02 19:22:10 +00:00
Christophe Dumez
8b40e43432 should speed up startup 2008-11-02 18:19:14 +00:00
Christophe Dumez
01bc15d3f4 - Allow to force rechecking torrents 2008-11-02 13:53:45 +00:00
Christophe Dumez
3282e1bcc9 - Save and load session state to remember it over different sessions 2008-11-02 13:19:27 +00:00
Christophe Dumez
e5b6a5605a - ETA calculation now relies on average speed over all sessions
- New ETA calculation system saves memory
- Updated Changelog
2008-11-02 13:07:38 +00:00
Christophe Dumez
9b67807926 - Queueing system should work fine now (port is complete, needs testing) 2008-11-02 11:43:20 +00:00
Christophe Dumez
f3729fbae6 - Use libtorrent queueing system (probably buggy and queueing currently does not work for seeds) 2008-11-02 10:47:59 +00:00
Christophe Dumez
0538c9c3e8 - Removed some debug 2008-11-02 09:30:35 +00:00
Christophe Dumez
53a0e85b8d - Do not save fastresume data for checking torrents 2008-11-02 00:04:38 +00:00
Christophe Dumez
453dd93abf - Should fix fastresume data code 2008-11-01 23:58:53 +00:00
Christophe Dumez
669cc2395a - Updated changelog 2008-11-01 22:09:09 +00:00
Christophe Dumez
82706141cf Ratio calculation improvement: make usage of new all_time_upload and all_time_download variables in torrent_status. 2008-11-01 22:07:14 +00:00
Christophe Dumez
c536f24d55 - Changed default icon from connecting to stalled since connecting state no longer exists 2008-11-01 21:45:30 +00:00
Christophe Dumez
764b4e72ca - rough port to libtorrent v0.14.0. This is probably buggy but it compiles without warnings 2008-11-01 21:42:56 +00:00
Christophe Dumez
19dd21062b - trunk will now be of v1.3.0 2008-11-01 12:50:07 +00:00
Christophe Dumez
2d24b468b6 Fixed possible crash when deleting a torrent permanently 2008-11-01 12:33:52 +00:00
Christophe Dumez
2dc75cb98d - Updated release date 2008-10-29 20:02:02 +00:00
Christophe Dumez
5e3be25916 - Single instance code is now more reliable on Qt >= 4.4 (closes #286968) 2008-10-29 19:58:44 +00:00
Christophe Dumez
49e8bad7cc - Removed rc from version 2008-10-28 21:39:12 +00:00
Christophe Dumez
796aea19e6 - Webui: refresh download list every 2 seconds to save cpu 2008-10-28 21:37:19 +00:00
Christophe Dumez
dd35f1723b - Updated mootools to v1.2.1 2008-10-28 21:20:08 +00:00
Christophe Dumez
0177e1fee4 - Attempt to fix icon flickering in webui 2008-10-28 21:17:17 +00:00
Christophe Dumez
949eb2b5f5 - WebUI: Uploads should always use seeding icon (not connecting for example) 2008-10-27 20:15:17 +00:00
Christophe Dumez
2d59fe37bf fixed translations 2008-10-17 05:57:03 +00:00
Christophe Dumez
b6f81c199e - fixed italian translation 2008-10-17 05:48:18 +00:00
Christophe Dumez
c2964dc340 - Updated AUTHORS file (from Cristian Greco@Debian) 2008-10-13 07:04:20 +00:00
Christophe Dumez
8aebb93424 - Updated bulgarian and greek translations 2008-10-07 18:32:27 +00:00
Christophe Dumez
96c38f7be4 - Updated Russian translation
- Progress column is now correctly sorted on startup (closes #133925 again)
2008-10-06 18:34:47 +00:00
Christophe Dumez
cf2abe45de - AddinPause feature no longer applies to resumed torrents on startup
(closes #278827)
2008-10-06 12:21:34 +00:00
Christophe Dumez
88ac8adb30 - Bump to rc4
- Disabled debug output
- Updated Chinese traditional translation
2008-10-05 11:34:52 +00:00
Christophe Dumez
b331478179 - Fix "go back to download list dialog" when seeding torrent has filtered files (closes #278508) 2008-10-05 11:10:57 +00:00
Christophe Dumez
bfaa82ccba - Not deleting files on hard drive when user is answering no the the 'move to download list' dialog 2008-10-05 11:05:27 +00:00
Christophe Dumez
77f407724d - German was not updated yet 2008-10-05 09:29:27 +00:00
Christophe Dumez
2f5c2e6404 - Updated Korean, Swedish, Romanian 2008-10-05 09:28:43 +00:00
Christophe Dumez
fbb2cdd1a9 - Updated dutch translation 2008-10-04 21:16:34 +00:00
Christophe Dumez
63a4e06556 - Attempt to fix single instance code on Qt 4.4 2008-10-04 19:36:27 +00:00
Christophe Dumez
3d934b4a9c - bump to rc3 2008-10-04 15:23:31 +00:00
Christophe Dumez
697c275d83 - Fixed torrent queueing system (finally) 2008-10-04 15:21:52 +00:00
Christophe Dumez
25b9601613 - Should fix save path problems 2008-10-04 14:14:07 +00:00
Christophe Dumez
276dfd9df6 BUGFIX: Torrents are no longer starting from scratch when changing default save path (when torrent addition dialog is disabled) 2008-10-04 14:01:55 +00:00
Christophe Dumez
19f05f0a97 - Updated italian translation 2008-10-03 18:37:11 +00:00
Christophe Dumez
293aaefefe - updated hungarian translation 2008-10-02 14:15:40 +00:00
Christophe Dumez
57cdf4ebd1 - Updated german translation 2008-10-01 20:32:04 +00:00
Christophe Dumez
c4a0c8f100 - Should fix bug #276196 2008-10-01 19:17:07 +00:00
Christophe Dumez
306991e776 - More debug 2008-10-01 19:05:17 +00:00
Christophe Dumez
de2384e4a7 - Added some debug 2008-10-01 19:00:59 +00:00
Christophe Dumez
236dbcfb4a - attempt to fix #276196 2008-10-01 07:02:49 +00:00
Christophe Dumez
a1b133d883 - Fixed progress for unchecked paused torrents 2008-09-30 18:37:05 +00:00
Christophe Dumez
4f8825e371 - Fixed priority column sorting (closes #276190) 2008-09-30 06:14:37 +00:00
Christophe Dumez
1aa0936c91 - Updated slovak translation
- french translation fix
2008-09-30 06:09:50 +00:00
Christophe Dumez
d5e22c523e - Fixed typographic error 2008-09-29 20:28:55 +00:00
Christophe Dumez
6618e61a42 - Added Expand/Collapse all buttons to properties dialog 2008-09-29 18:42:45 +00:00
Christophe Dumez
26283ec228 - Updated swedish translation 2008-09-28 18:53:33 +00:00
Christophe Dumez
ed12f5c77e - bump to rc2 2008-09-28 18:02:31 +00:00
Christophe Dumez
8e074a571a - Fixed queueing priorities loading on startup 2008-09-28 17:58:12 +00:00
Christophe Dumez
e2c7c973fd - Improved multiple selection style by blocking browser event 2008-09-28 16:39:39 +00:00
Christophe Dumez
eec04761ef - Block browser event for CTRL+A so that it does not select text (unwanted) : Web Ui 2008-09-28 16:25:51 +00:00
Christophe Dumez
f73256e0ea - Fixed shift selection from bottom to top (Web UI)
- Fixed bug where current selection was not cleared correctly (Web Ui)
- Allow to select all torrents using CRTL+A (Web Ui)
2008-09-28 16:23:08 +00:00
Christophe Dumez
fec1de6383 - Updated finish translation 2008-09-28 16:00:51 +00:00
Christophe Dumez
db35a7efb8 - Updated chinese translations 2008-09-28 15:43:14 +00:00
Christophe Dumez
36eae88a5a - bump to rc1 2008-09-28 11:58:09 +00:00
Christophe Dumez
c01fd75c92 - Updated french translation
- Updated copyright
2008-09-28 11:57:09 +00:00
Christophe Dumez
103f2d0720 - Updated translation files 2008-09-28 11:42:32 +00:00
Christophe Dumez
037c46b587 - bump to beta8 2008-09-28 11:33:21 +00:00
Christophe Dumez
0879f2c0ca - Totally rewritten Web UI list refresh system (fixed memory leak) 2008-09-28 11:30:24 +00:00
Christophe Dumez
a65cd5c39c - some more Web Ui fixes 2008-09-28 10:07:00 +00:00
Christophe Dumez
d219e7afeb - Added some licensing 2008-09-27 21:01:24 +00:00
Christophe Dumez
892bb4c432 - Improved tab look 2008-09-27 20:56:41 +00:00
Christophe Dumez
45b9c6335c - removed useless debug 2008-09-27 20:32:59 +00:00
Christophe Dumez
78e643039c - Fixed torrent exchange from one list to another in Web Ui 2008-09-27 20:31:50 +00:00
Christophe Dumez
04e993c674 - Fixed pause/resume/delete actions on seeding list (Web UI) 2008-09-27 20:10:10 +00:00
Christophe Dumez
c3132fc1b0 - Updated changelog 2008-09-27 19:56:57 +00:00
Christophe Dumez
b1c73cb401 - Split download and upload lists in Web UI 2008-09-27 19:55:56 +00:00
Christophe Dumez
ac6eb8c6bc - fixed pause/resume (broken by multiple selection commit) 2008-09-27 19:28:09 +00:00
Christophe Dumez
8a64412cb5 - Allow the user to use SHIFT key to extend selection in Web UI transfer list 2008-09-27 10:18:27 +00:00
Christophe Dumez
56885cc914 - Allow the user to use CTRL key to select multiple item in Web UI transfer list 2008-09-27 10:08:07 +00:00
Christophe Dumez
cdd1f9b86c - Fixed assert HIT in eventmanager due to queueing system 2008-09-27 09:58:28 +00:00
Christophe Dumez
139360cf76 - Can have different proxy settings for bittorrent and search engine (closes #274791) 2008-09-27 09:12:41 +00:00
Christophe Dumez
2931d51add - Fixed RSS list saving (closes #272651) 2008-09-21 08:35:38 +00:00
Christophe Dumez
aa0bec41b4 - bug fix for preferences saving (introduced recently) 2008-09-21 08:17:29 +00:00
Christophe Dumez
b32b42b53e - Added Collapse/Expand all buttons to torrent addition dialog (closes #272654) 2008-09-21 08:13:23 +00:00
Christophe Dumez
06c4c717bd - bump to beta7 2008-09-17 19:17:55 +00:00
Christophe Dumez
a3ed44baec - Fixed bad check for finished torrents (introduced in beta6) 2008-09-17 19:15:21 +00:00
Christophe Dumez
0cbb4a7074 - Updated polish translation 2008-09-15 17:53:17 +00:00
Ishan Arora
af2e487ef5 Added few debug statements to EventManager timer loop 2008-09-15 05:27:56 +00:00
Christophe Dumez
28fdfdfef1 - bump to beta6 2008-09-14 10:24:52 +00:00
Christophe Dumez
c95cca6436 - Updated changelogs 2008-09-14 10:23:59 +00:00
Christophe Dumez
86024c6c74 - merge from stable branches (WebUI fixes) 2008-09-14 10:14:54 +00:00
Christophe Dumez
75290cf715 - Cleaning memory for Web UI to avoid problems when running for a long time 2008-09-13 20:33:07 +00:00
Christophe Dumez
321b76a72a - fixed sorting in finished list 2008-09-13 19:57:54 +00:00
Christophe Dumez
95ecaec11e - Sync with stable branch (lot of bug fixing) 2008-09-13 18:53:58 +00:00
Christophe Dumez
0e7c16901c fixed a bug in last commit 2008-09-13 13:41:11 +00:00
Christophe Dumez
43dcbf776b Use QPointer when interesting 2008-09-13 07:33:41 +00:00
Christophe Dumez
e21c28e9d2 Fixed memory leak in HTTP server 2008-09-12 19:58:57 +00:00
Christophe Dumez
918c1507d3 - Web UI optimization 2008-09-12 19:56:32 +00:00
Christophe Dumez
a189e4403d - Fixed a string 2008-09-07 12:18:52 +00:00
Christophe Dumez
563291a2e8 - Updated language files 2008-09-07 12:12:16 +00:00
Christophe Dumez
9156c9ac8f - Logs are now in a separate dialog 2008-09-07 12:09:41 +00:00
Christophe Dumez
f0049f1dae - Removed logging panel for now. It will be replaced by a seperate dialog in order to simplify the default UI. 2008-09-07 11:31:29 +00:00
Christophe Dumez
a622152747 - Make use of h.is_seed() instead of h.progress() == 1. 2008-09-03 18:19:17 +00:00
Christophe Dumez
8440e9982f - Display top toolBar as a default 2008-09-03 17:52:40 +00:00
Christophe Dumez
602d73fa82 fix typo in german translation 2008-09-02 19:03:31 +00:00
Christophe Dumez
c32ebb8d9f - Another fix for boost v1.36 2008-08-31 12:35:25 +00:00
Christophe Dumez
deeead4008 - Compilation fix for boost v1.36
- Fixed 'start seeding after torrent creation' feature
2008-08-31 12:21:41 +00:00
Christophe Dumez
937a491409 Updated copyright info 2008-08-27 00:59:58 +00:00
Christophe Dumez
79d5ae18a6 - beta5 release 2008-08-26 07:22:03 +00:00
Christophe Dumez
5cce0c53bf - Fixed a comment
- Added chinese traditional translation to stable branch
- bump to v1.1.3 in stable branch (updated splash screen)
- Updated changelogs
2008-08-26 07:14:38 +00:00
Christophe Dumez
681b8c14ad - Fixed ratio saving for seeding torrents 2008-08-26 06:39:57 +00:00
Christophe Dumez
443567486e - Updated traditional chinese translator's mail 2008-08-25 11:24:02 +00:00
Christophe Dumez
c10ebc3086 - Added traditional Chinese locale 2008-08-25 10:54:14 +00:00
Christophe Dumez
42a2acefd3 - Fixed possible multiple rss tabs bug 2008-08-20 12:15:50 +00:00
Christophe Dumez
c781545609 - max compilation fix 2008-08-19 13:46:13 +00:00
Christophe Dumez
ba06affec7 - Fixed priority column sorting 2008-08-19 12:17:05 +00:00
Christophe Dumez
6140d69fcb - bump to beta4 2008-08-19 00:29:30 +00:00
Christophe Dumez
71a81fd1b7 - Queueing system fixes 2008-08-19 00:28:44 +00:00
Christophe Dumez
4e05b62bbe - Priority column fixes 2008-08-19 00:10:56 +00:00
Christophe Dumez
9d366c8c7d - Updated czech translation 2008-08-18 23:46:50 +00:00
Christophe Dumez
940744b0bf - Added czech flag 2008-08-18 10:52:51 +00:00
Christophe Dumez
6c2518a704 - forgot to commit those files 2008-08-18 10:47:43 +00:00
Christophe Dumez
ef51fabf63 - Added czech translation 2008-08-18 10:38:40 +00:00
Christophe Dumez
1aedd97d4d - Progress calculation patch 2008-08-17 03:47:52 +00:00
Christophe Dumez
ff26ea94f5 - Queued torrents are now identified in Web UI
- Improved transfer list update for queued torrents
- Allow to show/hide top toolbar
- top toolbar is now hidden as a default
- Connection status is now displayed in status bar (bottom)
- Removed "Disconnected" connection status (bad detection)
- Added increase/decrease priority actions to Edit menu
- Added keyboard shortcuts for increase/decrease priority actions
2008-08-08 13:17:26 +00:00
Christophe Dumez
c7a289d183 - Updated french translation 2008-08-02 19:58:19 +00:00
Christophe Dumez
2a70c8f4d8 - Bump to beta2 2008-08-02 19:51:24 +00:00
Christophe Dumez
e27b08d970 - Update queue when pausing a torrent 2008-08-02 19:49:37 +00:00
Christophe Dumez
48ec57604f - A queueing system ASSERT hit fix 2008-08-02 19:46:02 +00:00
Christophe Dumez
db1bbea26a - Updated Russian translation 2008-08-02 18:20:14 +00:00
Christophe Dumez
7bbb2f542b - Slightly improved minimize to systray code (but still experiencing the virtual desktop switching bug) 2008-08-01 20:03:16 +00:00
Christophe Dumez
5563e24781 - Updated resource files 2008-08-01 17:15:03 +00:00
Christophe Dumez
f131f6210f - Updated Changelog 2008-08-01 15:17:22 +00:00
Christophe Dumez
0356fa4538 - Updated bulgarian and greek translations 2008-07-31 12:45:35 +00:00
Christophe Dumez
b9c4a434c9 - Allow to download torrents from a local file (Web UI) 2008-07-31 12:03:28 +00:00
Christophe Dumez
a4318cc060 - Added peerkoel to Dutch translators 2008-07-29 09:57:07 +00:00
Christophe Dumez
d6e7161eff - Updated dutch translation 2008-07-29 09:56:32 +00:00
Christophe Dumez
e428489ebc - Added new Russian translator's name 2008-07-29 07:47:23 +00:00
Christophe Dumez
fa4cffe3d4 - Patch from Alexey Morsov for desktop file to satisfy freedesktop
standard
2008-07-29 07:42:45 +00:00
Christophe Dumez
a355a87ec5 - Updated russian translation 2008-07-29 07:39:53 +00:00
Christophe Dumez
39749620a4 - Added new spanish translator's name 2008-07-28 13:22:34 +00:00
Christophe Dumez
e7674bfaf8 - Updated spanish translation 2008-07-28 13:17:55 +00:00
Christophe Dumez
3e8ad9eb83 - fixed column resizing in torrent addition dialog 2008-07-27 18:07:35 +00:00
Christophe Dumez
6a95f9170c - Optimized downloadThread mmemory usage 2008-07-27 16:23:00 +00:00
Christophe Dumez
cc4a542e9d BUGFIX: Limit the number of concurrent download threads to save memory 2008-07-27 16:13:57 +00:00
Christophe Dumez
fed63b0b85 - Updated version in splash screen 2008-07-27 16:02:27 +00:00
Christophe Dumez
bf7b11d87d - Fixed menus vertical alignement 2008-07-27 15:51:14 +00:00
Christophe Dumez
bb959ba465 BUGFIX: Disable ETA calculation when ETA column is hidden 2008-07-27 15:41:46 +00:00
Christophe Dumez
b77e28fb12 - Updated German translation 2008-07-23 07:02:28 +00:00
Christophe Dumez
261f981a9a - Added new priority icons from Mateusz Tobola 2008-07-22 15:09:52 +00:00
Christophe Dumez
93ad7e889e - Commented ASSERT due to a little string encoding bug in libtorrent 2008-07-22 14:40:01 +00:00
Christophe Dumez
b79e2906e8 - Fixed building on ARM (patch from Cristian Greco 2008-07-22 05:51:46 +00:00
Christophe Dumez
99e8ac3d36 - Moved priority buttons 2008-07-19 20:52:49 +00:00
Christophe Dumez
badd36e81e - Hide priority buttons if queueing system is disabled 2008-07-19 20:39:34 +00:00
Christophe Dumez
c835502692 - Fixed extended selection in search results 2008-07-19 19:21:20 +00:00
Christophe Dumez
4fe7fd537d - a lot of fixes concerning the new queueing system 2008-07-17 21:12:10 +00:00
Christophe Dumez
88ea548eaf - Fix crash when pausing a torrent if queueing system is disabled 2008-07-16 22:09:01 +00:00
Christophe Dumez
360c8500bb - Unqueue torrents before disabling queueing system 2008-07-16 22:06:37 +00:00
Christophe Dumez
7a925f15ba - Fixed a bug in torrent progress calculation (regression) 2008-07-16 21:54:01 +00:00
Christophe Dumez
15ce9a7369 - Queueing systems now updates the number of active torrents in tab titles 2008-07-15 20:19:41 +00:00
Christophe Dumez
4b8532ea2d - Bug fix in session configuring (queueing) 2008-07-15 18:34:28 +00:00
Christophe Dumez
8e7d0f4dc1 - Oops, one } should not be there 2008-07-15 18:24:46 +00:00
Christophe Dumez
de0ac5cda4 - Bump to beta1 2008-07-15 18:22:50 +00:00
Christophe Dumez
9a9fd4e2d1 - Updated Changelog 2008-07-15 18:19:45 +00:00
Christophe Dumez
4be0cbd2e4 - Removed some debug
- Bug fix when applying preferences (queueing)
2008-07-15 18:18:59 +00:00
Christophe Dumez
5fef86ec18 - Upload queueing should now work a lot better :) 2008-07-15 18:11:27 +00:00
Christophe Dumez
1acd05794a - Another bug fix for upload queueing 2008-07-15 18:10:10 +00:00
Christophe Dumez
5a61b7543b - Updated language files 2008-07-14 22:16:26 +00:00
Christophe Dumez
b6b74752a5 - Queueing bug fix 2008-07-14 22:15:25 +00:00
Christophe Dumez
27a71ba123 - Increase/decrease priority buttons should now work for finishedTab too 2008-07-14 22:05:13 +00:00
Christophe Dumez
20ae3d997c - extending Queueing system to seeding list (unfinished) 2008-07-14 22:01:05 +00:00
Christophe Dumez
b73d0548c8 - Download queueing fix 2008-07-14 20:08:24 +00:00
Christophe Dumez
ca118697e9 - Added priority buttons 2008-07-14 20:01:21 +00:00
Christophe Dumez
600308aaa1 - Updated queued icon 2008-07-14 19:33:10 +00:00
Christophe Dumez
9b1ea66659 - Updated some translations 2008-07-14 19:21:37 +00:00
Christophe Dumez
d29cc3325b - Started to work on queueuing 2008-07-14 19:20:18 +00:00
Christophe Dumez
9f6e28b741 - Use infinity symbol for ETA when time is infinite 2008-07-11 18:19:34 +00:00
Christophe Dumez
4c5f349f49 - FEATURE: RSS can now be disabled from program preferences
- COSMETIC: RSS Tab is now hidden as a default
2008-07-11 17:43:57 +00:00
Christophe Dumez
9a321adfb1 - Updated Italian translation 2008-07-11 16:30:52 +00:00
Christophe Dumez
e233f27d1c - Fixed bug in UP/DL speeds updates 2008-07-10 20:23:17 +00:00
Christophe Dumez
1cadf73a40 - Updated translation files 2008-07-10 20:21:07 +00:00
Christophe Dumez
77c97b5b43 - FEATURE: DHT is always ON (no longer used as fallback)
- FEATURE: The number of DHT nodes is displayed
    - COSMETIC: Transfer speed, ratio and DHT nodes are displayed in status bar
2008-07-10 20:19:28 +00:00
Christophe Dumez
0054a330fb - Updated Finnish translation 2008-07-10 18:50:34 +00:00
Christophe Dumez
8ba05c57b0 - Updated romanian translation 2008-07-10 16:54:15 +00:00
Christophe Dumez
284b1c7f87 - Updated slovak and swedish translations 2008-07-10 07:02:23 +00:00
Christophe Dumez
8bc470e427 - Spoof latest Azureus version instead of Vuze 2008-07-09 22:42:04 +00:00
Christophe Dumez
8e5190ffc8 - Spoof latest Azureus/Vuze version (3.1.1.0) 2008-07-09 22:36:12 +00:00
Christophe Dumez
a8298b6c9a - Removed some heavy debug 2008-07-08 11:17:23 +00:00
Christophe Dumez
b5928aa2e3 - Fixed messageBox when listening on busy port (Web UI) 2008-07-08 10:56:35 +00:00
Christophe Dumez
0a9462aa63 - Updated Portuguese and brazilian translations 2008-07-08 09:22:59 +00:00
Christophe Dumez
7b8be9e15c - Forgot Ishan in About 2008-07-08 08:51:00 +00:00
Christophe Dumez
2a41223ce1 - Updated Chinese and Polish translations 2008-07-08 07:31:01 +00:00
Christophe Dumez
214151b57b - Missing blank line at the end 2008-07-07 09:14:49 +00:00
Christophe Dumez
ba8afb6bdc - Update resource files 2008-07-07 09:13:03 +00:00
Christophe Dumez
dbc00a66f0 - Updated Changelog 2008-07-07 08:42:36 +00:00
Christophe Dumez
8dfc68e196 - Updated tranlsations
- Allow to run one instance of qBittorrent per user
- Moved button to close search tabs
2008-07-06 18:39:07 +00:00
Christophe Dumez
2dee67edbd - Fixed slot name 2008-07-04 16:49:08 +00:00
Christophe Dumez
f6cc600b94 - Added missing copyright information 2008-07-04 12:20:03 +00:00
Christophe Dumez
de334d32b1 - Removed useless copyright files
- Added libtorrent-rasterbar qcm for configure
2008-07-04 12:10:47 +00:00
Christophe Dumez
44c86053ca - Forgot copyright information for this file 2008-07-04 07:50:51 +00:00
Christophe Dumez
efebf8e0c3 - Moved some python scripts 2008-07-04 07:49:51 +00:00
Christophe Dumez
06dd495915 - Fixed copyright info 2008-07-04 07:48:15 +00:00
Christophe Dumez
5b0857c01d - Updated Changelog
- Updated INSTALL file information about libtorrent-rasterbar
2008-07-03 15:26:32 +00:00
Christophe Dumez
523b86e28e - Didn't mean to commit this line (not ready yet) 2008-07-03 15:17:34 +00:00
Christophe Dumez
4e28aa1031 - More licensing 2008-07-03 15:12:33 +00:00
Christophe Dumez
166c5b252e - Added some more licensing information 2008-07-03 15:09:39 +00:00
Christophe Dumez
112ca10f32 - Updated AUTHORS file 2008-07-03 15:02:44 +00:00
Christophe Dumez
649a8e0418 - Added more copyright information 2008-07-03 14:59:31 +00:00
Christophe Dumez
c9631c2a3f - Patch from Cristian Greco to fix compilation against libtorrent 0.13.1. Big changes were made recently in libtorrent to allow integration in Debian. 2008-07-02 15:06:22 +00:00
Christophe Dumez
7b65998c72 - Ignore non router for UPnP 2008-07-02 14:36:52 +00:00
Christophe Dumez
6a1db644de - Updated French translation 2008-06-26 18:06:35 +00:00
Christophe Dumez
fcf430eb7b - Updated language files 2008-06-26 17:37:39 +00:00
Christophe Dumez
d916bfd73e - Ask if we want to redownload a torrent if its content gets deleted from hard drive (patch from e-stealth) 2008-06-26 17:31:29 +00:00
Christophe Dumez
949678a4d3 - Updated download button status in search tab when switching tab 2008-06-26 11:24:08 +00:00
Christophe Dumez
322e9e3ccf - Bump to beta3 2008-06-25 20:53:09 +00:00
Christophe Dumez
6098bfebf8 - Give focus to current search tab 2008-06-25 20:48:58 +00:00
Christophe Dumez
3758c98d5e - Allow to close search tabs 2008-06-25 20:46:19 +00:00
Christophe Dumez
dca80c3006 - Moved all_tab to parent class
- Fixed memory leak for all_tab
2008-06-25 20:02:38 +00:00
Christophe Dumez
95bad03321 - Fixed row color update
- Code cleanup
2008-06-25 19:52:39 +00:00
Christophe Dumez
cecd1e11b1 - Tabbed search engine code cleanup (moved SearchTab class to different file) 2008-06-25 19:29:29 +00:00
Christophe Dumez
c6fd400fa5 - Fixed compilation warning 2008-06-25 19:21:16 +00:00
Christophe Dumez
2711794770 - Updated Changelog 2008-06-25 19:06:12 +00:00
Christophe Dumez
505baf4eed - Added Grigis Gaëtan to contributors 2008-06-25 19:05:23 +00:00
Christophe Dumez
0e09ce1dd3 - Initial commit for multi tab support in search engine (code by Grigis Gaëtan) 2008-06-25 19:04:42 +00:00
Christophe Dumez
6f13325e76 - Should fix compilation issues about verticalLayout in GUI.cpp with some versions of Qt4 2008-06-23 18:58:24 +00:00
Christophe Dumez
adda3a2d34 - Fix compilation warning 2008-06-22 14:38:00 +00:00
Christophe Dumez
f22c2f8c7b - Save spitters position to remember them on restart (RSS) 2008-06-20 20:16:56 +00:00
Christophe Dumez
981d7fd5ce - Improved rss layout 2008-06-20 20:01:35 +00:00
Christophe Dumez
80cd14e730 - Fix RSS layout 2008-06-20 19:52:21 +00:00
Christophe Dumez
a28de2fa21 - Bump version to beta2 2008-06-09 20:02:16 +00:00
Christophe Dumez
f143596b91 - COSMETIC: Global UP/DL speeds and ratio are displayed above tabs 2008-06-09 19:59:51 +00:00
Christophe Dumez
d32813ed1f - Allow to resize RSS column 2008-06-09 19:29:26 +00:00
Christophe Dumez
7f44ef75c4 - Updated language files 2008-05-23 20:30:33 +00:00
Christophe Dumez
478c9a871c - Updated Polish translation
- Fixed compilation on Lenny (Web interface code)
- Forgot Q_OBJECT statement in filterParserThread class
2008-05-23 20:29:32 +00:00
Christophe Dumez
296bd07e52 - Fixed a broken signal in program preferences 2008-05-20 10:38:48 +00:00
Christophe Dumez
7ced943b88 - Bump to v1.1.0beta1 2008-05-18 12:29:26 +00:00
Christophe Dumez
1d235b2953 - Updated language files 2008-05-18 12:07:00 +00:00
Christophe Dumez
516f4dad48 - Added some debug
- Fix from #178167 for tree view resizing
2008-05-18 12:01:42 +00:00
Christophe Dumez
edc04292f7 - Fixed multiple selection in tracker list 2008-05-18 11:50:43 +00:00
Christophe Dumez
cb7e48b2e8 - Allow to add several trackers at once 2008-05-18 11:44:50 +00:00
Christophe Dumez
56d80118b7 - Can spoof Azureus peer id and user agent to avoid ban 2008-05-18 09:50:35 +00:00
Christophe Dumez
711699e200 - COSMETIC: Display "unpaused/total_torrent" in download/upload tabs 2008-05-18 09:26:02 +00:00
Christophe Dumez
fc931d8c88 - FEATURE: Allow to customize folder scan interval 2008-05-18 08:40:39 +00:00
Christophe Dumez
d26bebfbe2 - Improved PG2 p2p filter support 2008-05-17 21:55:23 +00:00
Christophe Dumez
7463552dcd - BUGFIX: Threadified IP filter file parser to avoid GUI freeze 2008-05-17 20:32:03 +00:00
Christophe Dumez
ec5325ed3c - Fix in p2p support 2008-05-17 19:36:14 +00:00
Christophe Dumez
8b814c724c - Added a little debug for p2b 2008-05-17 19:31:38 +00:00
Christophe Dumez
ce627de39d - FEATURE: Added support for PeerGuardian p2b filters (binary) 2008-05-17 19:27:08 +00:00
Christophe Dumez
5c054223e8 - FEATURE: Added support for PeerGuardian p2p filters 2008-05-17 18:06:42 +00:00
Christophe Dumez
133007c451 - FEATURE: Improved eMule DAT ip filter parser 2008-05-17 17:55:12 +00:00
Christophe Dumez
b17c8b84d1 - Prepare code for p2p ip filter support 2008-05-17 17:11:01 +00:00
Christophe Dumez
f6210d5857 - Removed IP filter list and buttons to add/remove ranges, I don't think
people handle this manually anyway.
- Prepare code for P2P/P2B filter files (soon to be coded)
2008-05-17 17:01:03 +00:00
Christophe Dumez
6926b3f7a0 - Updated changelog 2008-05-17 14:00:27 +00:00
Christophe Dumez
1a56141430 - Forgot to commit those files too 2008-05-17 13:23:37 +00:00
Christophe Dumez
ffa10adecf - Forgot to commit those 2008-05-17 13:22:54 +00:00
Christophe Dumez
b69a8a0709 - Commit a lot of missing files for web interface 2008-05-17 12:44:42 +00:00
Christophe Dumez
4dece85483 - Fixed default tab in torrent properties window 2008-05-16 22:27:36 +00:00
Christophe Dumez
8deb18fa9d - Updated changelog 2008-05-16 11:02:02 +00:00
Christophe Dumez
5af8bddc16 - Web interface by Ishan Arora 2008-05-16 07:10:50 +00:00
Christophe Dumez
0dd84c37a1 - Commit some tracker changes. Work is not completed and this is probably buggy. I will complete this later. 2008-05-15 19:48:15 +00:00
Christophe Dumez
1be6333601 - Removed legal mention about copyrighted material. 2008-05-09 20:21:56 +00:00
Christophe Dumez
20552ea157 - Patch from Cristian Greco to add an Italian genericname to desktop file and remove a line that is not needed 2008-05-08 15:00:08 +00:00
Christophe Dumez
71a92bbb63 - Fix from Cristian Greco about replacing hyphens by minus 2008-05-08 14:55:46 +00:00
Christophe Dumez
e9865c42bd - Updated slovak translation 2008-04-26 16:00:41 +00:00
Christophe Dumez
9172985173 - Force trackers reannounce after loading them from HD 2008-04-13 14:15:19 +00:00
Christophe Dumez
54bf7e61f7 - libmagick configure improvement 2008-04-11 16:47:55 +00:00
Christophe Dumez
8422cb395a - Fixed unlimited download limit problem (trayicon) 2008-03-14 20:54:02 +00:00
Christophe Dumez
313b9b9bc0 - Fixed mistake in french translation 2008-03-14 20:46:07 +00:00
Christophe Dumez
9d3fcb10d5 - Updated language files 2008-03-14 20:27:40 +00:00
Christophe Dumez
34725dc26b - Fixed index problem in preview selection (closes #192495) 2008-02-17 13:33:43 +00:00
Christophe Dumez
8b576fcc50 - Attempt to fix compilation on vc++ 2008-02-03 10:43:12 +00:00
Christophe Dumez
1b7449ef4e - Fixed torrent names in mininova search engine 2008-01-28 12:26:44 +00:00
Christophe Dumez
596ec6ae4c - Updated slovak translation 2008-01-11 23:35:09 +00:00
Christophe Dumez
569b69689a - updated translation files 2008-01-04 20:53:56 +00:00
Christophe Dumez
07c195f475 - Catch more exceptions when adding a torrent 2008-01-04 20:43:28 +00:00
Christophe Dumez
5e86c8a14d - Fixed systray integration when qbittorrent is launched on system startup 2008-01-04 20:09:37 +00:00
Christophe Dumez
85796d9c2c - Use 16px tray icon on windows 2008-01-04 19:48:26 +00:00
Christophe Dumez
f4120088c6 Updated language files 2008-01-03 16:18:37 +00:00
Christophe Dumez
8d1f1512b0 - Fixed UPnP messages 2008-01-03 16:17:01 +00:00
Christophe Dumez
c6abdacadd - Threadified torrent creation
- Added a progress bar in torrent creation
- Display if UPnP/NAT-PMP was successful or not
2007-12-31 16:57:35 +00:00
Christophe Dumez
fa00d745b2 - Sharemonkey filename fix (Thanks Keiron Waites) 2007-12-30 21:03:05 +00:00
Christophe Dumez
1e1313dffc - Fixed torrent creation from a folder
- Fixed start seeding directly after torrent creation
2007-12-30 18:06:51 +00:00
Christophe Dumez
00b3677867 - Fixed btjunkie search engine 2007-12-28 09:57:05 +00:00
Ishan Arora
8a9a23866f Corrections in RealProgressBarThread
- Fixed a bug related to the size of the array
- Removed the much hated goto statements with loops :)
2007-12-26 16:40:20 +00:00
Christophe Dumez
91328de30f - Disabled libcurl verbosity 2007-12-12 22:20:36 +00:00
Christophe Dumez
204d9ff496 - Fixed eol problems on Windows 2007-12-12 22:00:41 +00:00
Christophe Dumez
5d64373798 should fix eol problems on windows 2007-12-12 21:45:44 +00:00
Christophe Dumez
699d4b1161 - Forgot to call a python script with python executable 2007-12-12 18:17:09 +00:00
Christophe Dumez
0fe9d68be1 - Forgot to call one script with python 2007-12-12 17:55:16 +00:00
Christophe Dumez
b2f9394d6e - Call python scripts using python executable (fix for windows) 2007-12-12 17:14:15 +00:00
Christophe Dumez
56965d444a - Attempt to fix search engine on Windows 2007-12-12 16:56:32 +00:00
Christophe Dumez
07d7a44731 - DownloadThread now write in binary mode (should fix problems on Windows) 2007-12-12 12:23:38 +00:00
Christophe Dumez
f85aa72c72 - Disable libcurl debug 2007-12-11 20:33:57 +00:00
Christophe Dumez
2f5b4a190e - downloads from urls now follow redirections 2007-12-11 20:20:43 +00:00
Christophe Dumez
aada4f3c03 - Forgot to remove temporary download file when addition failed 2007-12-11 20:00:43 +00:00
Christophe Dumez
9540d45c1d - Fixed torrentreactor search engine 2007-12-11 19:32:09 +00:00
Christophe Dumez
cfd7a1bf0b Updated Japanese translation 2007-12-11 17:11:27 +00:00
Arnaud Demaiziere
3e13bd1381 BUGFIX : when shutting down the system, qbt simply quits 2007-12-09 16:35:51 +00:00
Christophe Dumez
3af23ae8a9 - Fixed compilation warning 2007-12-09 15:51:09 +00:00
Christophe Dumez
f1aa1f993d - Fixed preview when path contain spaces 2007-12-09 09:30:06 +00:00
Christophe Dumez
82b1b29906 - Fixed space problem for "open destination folder" action 2007-12-09 09:28:11 +00:00
Christophe Dumez
14882fe38f - Added our sharemonkey campaign id
- Updated hungarian translation
2007-12-08 22:17:01 +00:00
Christophe Dumez
82f60f1b89 - Updated version in menu entry 2007-12-07 22:59:12 +00:00
Christophe Dumez
dab617458a - Added comment for sharemonkey campaign id 2007-12-07 22:56:36 +00:00
Christophe Dumez
1832d518d6 - Updated splash screen for v1.1.0
- Version Bump to v1.1.0alpha2
2007-12-07 22:51:25 +00:00
Christophe Dumez
5ed8517cde - Added an icon for the new "Buy it" action
- Updated language files
2007-12-07 22:48:51 +00:00
Christophe Dumez
b2950afd5c - FEATURE: Allow to buy downloads using ShareMonkey 2007-12-07 22:33:19 +00:00
Christophe Dumez
a84c686090 - Fixed a problem when closing to systray, then closing the app and cancel 2007-12-04 12:04:53 +00:00
Christophe Dumez
efb8315a38 - Fixed nbResult != 0 when clearing results while a search is running 2007-12-03 19:29:57 +00:00
Christophe Dumez
56b018fb95 - Attempt to fix downloadFromUrl on Windows 2007-11-30 16:05:20 +00:00
Christophe Dumez
731438a19a - Updated search engine plugins in order to limit to 10 pages 2007-11-30 11:54:05 +00:00
Christophe Dumez
fd4ce53eb1 - Added a 3 minutes search timeout 2007-11-30 10:48:00 +00:00
Christophe Dumez
b4f0fbdbc4 Updated polish translation 2007-11-29 18:16:45 +00:00
Christophe Dumez
26ae2af198 - Fixed proxy host max length in preferences 2007-11-28 12:50:08 +00:00
Christophe Dumez
bdb625a615 - Fixed compilation on windows (closes #172391) 2007-11-27 19:37:45 +00:00
Christophe Dumez
f68c5114b2 Updated japanese translation 2007-11-25 19:55:19 +00:00
Christophe Dumez
83282bf835 - Updated polish translation 2007-11-25 14:55:16 +00:00
Christophe Dumez
054351e3a4 - Updated translation files 2007-11-25 13:38:21 +00:00
Christophe Dumez
a5dac03956 - Same as last commit but for gnome looks 2007-11-24 23:47:44 +00:00
Christophe Dumez
a760913482 - Same as last commit but for infoBar this time 2007-11-24 23:43:57 +00:00
Christophe Dumez
f3c8889865 - Should fixed text color for stalled torrents when using a dark theme 2007-11-24 23:39:44 +00:00
Christophe Dumez
b24a1e9123 - COSMETIC: Do not display progress bar in seeding list (always 100%) 2007-11-24 22:24:01 +00:00
Christophe Dumez
c4b7622a17 - Do not compute data for hidden columns in order to save CPU 2007-11-24 22:16:00 +00:00
Christophe Dumez
f7fa66c65d - Improved a lot ETA calculation algorithm 2007-11-24 21:55:19 +00:00
Christophe Dumez
a91d2028d8 - Rewrote part of Arnaud's code for column hiding to debug and optimize it 2007-11-24 19:04:28 +00:00
Christophe Dumez
adea644c04 - Removed "Resize all columns" action 2007-11-24 18:33:17 +00:00
Christophe Dumez
31679f0d6d Tagged rc9 release 2007-11-24 12:11:12 +00:00
Arnaud Demaiziere
0d90ad8f7c bufixes on hidden columns in transfert lists 2007-11-24 00:14:19 +00:00
Christophe Dumez
8ab6aeafcc - Fixed compilation warning in Ishan's code 2007-11-23 23:48:05 +00:00
Christophe Dumez
a56baf5b58 - Added some errors code for libcurl
- Added HTTPS download support
2007-11-23 23:06:38 +00:00
Christophe Dumez
61eb921e44 - Moved from libcommoncpp to libcurl for downloads from urls
- Added SOCKS5 proxy support when downloading from urls
2007-11-23 22:57:49 +00:00
Christophe Dumez
8ecf79e91c - Do not use SOCKS5 proxies in downloadThread.cpp (does not work) 2007-11-23 20:48:47 +00:00
Christophe Dumez
349e58fa22 - Fixed minor version number 2007-11-23 17:22:48 +00:00
Christophe Dumez
436f5bbd7e - Fixed HTTP proxy support in downloadThread 2007-11-23 15:54:18 +00:00
Christophe Dumez
64bfdf930c - Fixed not destructing libtorrent session bug 2007-11-23 15:20:26 +00:00
Christophe Dumez
8858518a14 - fixed proxy layout in preferences 2007-11-23 00:23:55 +00:00
Christophe Dumez
def19ef88b - Added h.is_valid check 2007-11-22 21:53:42 +00:00
Christophe Dumez
4f989b674f - Do not save fastresume data for paused torrents anymore 2007-11-22 21:50:22 +00:00
Christophe Dumez
f0ef21e409 - Fixed proxy auth disable problem when disabling proxy 2007-11-22 21:32:30 +00:00
Christophe Dumez
6b0ae4f575 - Some bug fixes (Proxy) 2007-11-22 10:49:10 +00:00
Christophe Dumez
3926b0d787 - Fixed compilation warning 2007-11-21 22:46:13 +00:00
Christophe Dumez
a721e6d943 - Improved proxy support (search, rss, downloadFromUrl...) 2007-11-21 22:30:33 +00:00
Ishan Arora
9c05148a24 few more corrections on RealProgressBar
- removed counting incomplete pieces
- replaced few Q_ASSERT with corrective statements
2007-11-21 21:12:03 +00:00
Christophe Dumez
725ef52cfe - Fixed compilation warning 2007-11-21 20:35:31 +00:00
Christophe Dumez
7982011d0b - Do not save fastresume data regularly for seeding torrents 2007-11-21 20:33:30 +00:00
Christophe Dumez
0a3bb0cfcd - BUGFIX: title bar is now reset when "Display speed in title" is disabled 2007-11-21 20:17:01 +00:00
Christophe Dumez
f75501f781 - Fixed overflow handling in ETA calculation 2007-11-21 18:59:49 +00:00
Christophe Dumez
70f8a00c20 - Save fastresume data every minute instead of every 10 sec 2007-11-21 16:50:26 +00:00
Christophe Dumez
2691677650 - Fixed segfault that would happen when unfiltering files in torrent addition dialog (closes #163379) 2007-11-19 21:42:58 +00:00
Christophe Dumez
be34bed61a - Fixed compilation warning 2007-11-19 21:33:07 +00:00
Christophe Dumez
721ef1d236 - Fixed useless variable in properties 2007-11-19 21:31:48 +00:00
Christophe Dumez
c8b944508b - Saving trackers file only when necessary
- Avoid code duplication for showProperties()
2007-11-19 21:10:57 +00:00
Christophe Dumez
f3f3f2822b - Do not save fastresume data for checking torrents anymore 2007-11-19 20:43:54 +00:00
Christophe Dumez
3ef0c82a8c - Do no pause torrents before saving fastresume data anymore (no longer needed)
- Save fast resume data regularly (every 10 seconds) to avoid downloading from s
cratch when qBittorrent restart
2007-11-19 20:33:31 +00:00
Arnaud Demaiziere
b8200fd7b2 feature : allow to hide/show columns 2007-11-19 00:58:14 +00:00
Ishan Arora
9e62780a6d Added files missing in last revision 2007-11-18 19:40:49 +00:00
Christophe Dumez
58c78fa6f6 - FEATURE: Real progress bar in torrent properties that displays downloaded pieces (contribution by
Ishan Arora)
2007-11-18 18:06:44 +00:00
Christophe Dumez
5484ec923d - Improved proxy support in search engine 2007-11-16 19:59:36 +00:00
Christophe Dumez
54225cd42f - Made properties window a bit larger
- Remember properties window size and position on startup
2007-11-16 19:33:38 +00:00
Christophe Dumez
dc651ffed3 - Updated TODO List 2007-11-16 19:21:24 +00:00
Christophe Dumez
476a7d7be0 Updated language files 2007-11-16 18:54:52 +00:00
Christophe Dumez
c580285fe8 - Allow to open destination folder on right click on a torrent 2007-11-16 18:53:21 +00:00
Christophe Dumez
5b6166ee15 - Simplified file preview using QDesktopServices 2007-11-16 18:36:57 +00:00
Christophe Dumez
18ee43225e - Allow to open destination folder on double-click 2007-11-16 18:26:00 +00:00
Christophe Dumez
b47073901f - Removed a fedora 7 workaround 2007-11-13 10:32:42 +00:00
Christophe Dumez
d45c44868e - Removed Fedora workaround because Fedora 8 is working propery now 2007-11-10 09:25:51 +00:00
Christophe Dumez
4401b60d51 - cleaned up arnaud's code for double-click action 2007-11-08 18:31:41 +00:00
Christophe Dumez
0ce114a7f8 - Fixed double-click default action 2007-11-08 18:22:34 +00:00
Christophe Dumez
38ca306499 - Fixed start minimized 2007-11-07 12:30:20 +00:00
Christophe Dumez
6cb636f85d - Fixed Changelog 2007-11-07 12:19:12 +00:00
Christophe Dumez
7563b09ead - Updated TODO/Changelog 2007-11-07 11:20:28 +00:00
Arnaud Demaiziere
76783c819c clear the results of a search stops it 2007-11-07 08:41:34 +00:00
Arnaud Demaiziere
42312b982b i forgot the changelog ... oups 2007-11-06 21:16:49 +00:00
Arnaud Demaiziere
a329a59719 - Start minimized option in program preferences
*** - In finished list, replace "Seeds/Leechs" column by "Leechers" 
because Seeds are always 0.
- Allow to change action on double-click
  -> in download list
  -> in seeding list
2007-11-06 21:11:09 +00:00
Christophe Dumez
82e548a2fd - Fixed a bug in torrent files filtering (closes #158846) 2007-11-06 20:55:23 +00:00
Christophe Dumez
5bbdb9e119 - Renabled debug
- Bumped to v1.1.0alpha1
2007-11-06 17:40:44 +00:00
Christophe Dumez
68cbcaeab9 - Fixed a little problem with 16x16px icon install 2007-11-04 09:18:31 +00:00
Christophe Dumez
3c88657e0f rc7 release 2007-11-03 11:57:00 +00:00
Christophe Dumez
f836be6736 - BUGFIX: Don't reload seeding torrents anymore (no point) 2007-11-03 00:19:24 +00:00
Christophe Dumez
85fe900afe - Disable debug mode 2007-11-02 22:56:33 +00:00
Christophe Dumez
052ccf2302 - BUGFIX: Don't reload all torrents everytime settings are saved 2007-11-02 22:56:07 +00:00
Christophe Dumez
ae384da609 - Updated TODO 2007-11-02 13:32:24 +00:00
Christophe Dumez
0fc2d289eb - BUGFIX: Pause/Start All now affect all tabs, not only the current one 2007-11-02 13:12:31 +00:00
Christophe Dumez
9ca02aad88 - BUGFIX: Fixed a bug in children update when changing files priorities 2007-10-30 21:29:15 +00:00
Christophe Dumez
8ea34135e4 - BUGFIX: Catching DHT exception in case there is a problem 2007-10-27 20:53:09 +00:00
Christophe Dumez
b66be5b64b - Removed build dependency on Python 2007-10-27 20:24:17 +00:00
Christophe Dumez
ebc738e3a5 - Updated Turkish translation 2007-10-19 22:27:00 +00:00
Christophe Dumez
713474bc43 - Bump to rc6 2007-10-19 21:25:17 +00:00
Christophe Dumez
265a8cada8 - Fixed ETA display 2007-10-19 20:38:00 +00:00
Christophe Dumez
138af31ef9 - BUGFIX: Remember scan directory in program preferences now 2007-10-19 16:08:05 +00:00
Christophe Dumez
a5f6663e65 - BUGFIX: Fixed deletion of subfolders when deleting torrents from hard drive 2007-10-19 16:00:42 +00:00
Christophe Dumez
1519bca46d - Fixed folder progress calculation in torrent properties (closes #154387) 2007-10-19 15:51:13 +00:00
Christophe Dumez
03719cbb87 - Simplified code 2007-10-18 18:30:04 +00:00
Christophe Dumez
98825613fa - Fixed spanish translation 2007-10-17 16:18:40 +00:00
Christophe Dumez
47abadfc67 - Fixed a typo in french translation 2007-10-17 15:47:49 +00:00
Christophe Dumez
a220e01e2e - FEATURE: Added a button to clear search pattern
- I18N: Fixed swedish translation
2007-10-14 12:21:51 +00:00
Christophe Dumez
dea9237aa0 - BUGFIX: Fixed minimize to tray feature 2007-10-14 09:23:29 +00:00
Christophe Dumez
6099544da5 - BUGFIX: configure doesn't require paths with a terminal "/" anymore 2007-10-14 09:15:02 +00:00
Christophe Dumez
902116cbc8 - BUGFIX: configure looks for libraries in lib64 folders too 2007-10-14 09:09:19 +00:00
Christophe Dumez
96a6f450d0 - Make use of this: added option to delete files from disk as a torrent is removed (libtorrent) 2007-10-13 08:54:46 +00:00
Christophe Dumez
6ed565a06b - COSMETIC: Improved progress bar text rendering 2007-10-13 08:32:31 +00:00
Christophe Dumez
1fbbee794c - BUGFIX: Fixed "Automatically start seeding" feature in torrent creation tool 2007-10-12 18:28:30 +00:00
Christophe Dumez
bfab6389b5 - Commented fast resume rejected alert until #182 is fixed in libtorrent 2007-10-12 11:54:29 +00:00
Christophe Dumez
26a4040003 - BUGFIX: Fixed "Missing Input path" error when creating a torrent
- BUGFIX: Fixed some notification messages for torrent addition dialog
2007-10-12 11:50:02 +00:00
Christophe Dumez
e7ac721b3c - Updated TODO 2007-10-11 18:34:14 +00:00
Christophe Dumez
48f5436f6f - Improved ETA calculation code a little and fixed a little typo in the code
- Updated TODO (waiting for a bug fix in libtorrent)
2007-10-10 20:29:07 +00:00
Christophe Dumez
f754e34e35 - BUGFIX: Fixed possible overflow in ETA calculation 2007-10-10 19:57:24 +00:00
Christophe Dumez
9bb18e1a07 - reverted src.pro 2007-10-10 19:17:25 +00:00
Christophe Dumez
0245bbf5ab - BUGFIX: Fixed an ETA calculation problem when the torrent has filtered files 2007-10-10 19:10:34 +00:00
Christophe Dumez
0a0c1f3529 - BUGFIX: AddInPause setting doesn't pause downloads on startup anymore (real fix this time...) 2007-10-10 17:54:09 +00:00
Christophe Dumez
be94c86350 - Revert a change in src.pro I didn't mean to commit 2007-10-10 17:36:02 +00:00
Christophe Dumez
a26333bc65 - BUGFIX: Now filtered don't appear on hard drive anymore (libtorrent >= r1659 REQUIRED)
- BUGFIX: AddInPause setting doesn't pause downloads on startup anymore
2007-10-10 17:34:52 +00:00
Christophe Dumez
4c862597ae - Updated Japanese translation
- rc4 release
2007-10-06 20:00:13 +00:00
Christophe Dumez
937d45d850 - Use system's default style as a default instead of Plastique style 2007-10-03 19:18:55 +00:00
Christophe Dumez
20b6579392 - BUGFIX: Updated INSTALL file
- BUGFIX: Optimized torrent real size calculation
2007-10-01 19:43:24 +00:00
Christophe Dumez
4f25e6c769 - Another attempt to fix compilation on FreeBSD
- Fixed IP Filter preferences (closes #147532)
2007-10-01 09:47:00 +00:00
Christophe Dumez
ce3b8733d1 BUGFIX: Fixed a proxy problem causing connections to be rejected by trackers 2007-09-30 17:46:47 +00:00
Christophe Dumez
b0140fbdbe - We have an optimized way to get the torrent actual size using libtorrent but this is buggy. Hence we don't use it yet. 2007-09-29 08:32:22 +00:00
Christophe Dumez
abcd2b7600 - Ok, Now I'm pretty sure I fixed the compilation problem on FreeBSD 2007-09-29 08:13:20 +00:00
Christophe Dumez
f9998957cd - attempt to fix compilation on FreeBSD 2007-09-29 08:00:14 +00:00
Christophe Dumez
acb8d5679f - rc2 release 2007-09-27 19:15:41 +00:00
Christophe Dumez
c3d3156ec7 - BUGFIX: Fixed search engine plugins update 2007-09-27 19:09:32 +00:00
Christophe Dumez
09abd303bd - Updated plugin version in text file 2007-09-27 18:51:06 +00:00
Christophe Dumez
0678e2e2bd - Fixed mininova search engie plugin 2007-09-27 18:47:26 +00:00
Christophe Dumez
00dbf7ba38 - Updated italian and korean translations
- Fixed infoBar text when adding a torrent
2007-09-27 18:25:37 +00:00
Christophe Dumez
42cacabccd - BUGFIX: Fixed a unsupported character in man page 2007-09-26 18:32:17 +00:00
Christophe Dumez
3d04a944b6 - rc1 release
- disabled debug mode
2007-09-25 17:50:04 +00:00
Christophe Dumez
b02e2c2f9b Updated Hungarian translation 2007-09-24 21:01:46 +00:00
Christophe Dumez
5c0f17bf31 - Fixed a problem in log text color (introduced very recently) 2007-09-24 18:56:14 +00:00
Christophe Dumez
ac9a81985f - Fixed error in last commit 2007-09-24 18:35:35 +00:00
Christophe Dumez
a46c63d883 - Updated spanish translation
- Log text default color uses skin foreground color instead of black now
2007-09-24 18:08:38 +00:00
Christophe Dumez
09a696fc27 updated translations 2007-09-22 13:32:31 +00:00
Christophe Dumez
dedc54d26f - Updated TODO 2007-09-21 20:06:04 +00:00
Christophe Dumez
c0ffb8fa5c - BUGFIX: Fixed overflow in ratio 2007-09-21 07:45:28 +00:00
Christophe Dumez
3e350c5935 - Updated some translation
- Added -NDEBUG to src.pro to fix compilation problem with libtorrent svn
2007-09-20 20:57:41 +00:00
Christophe Dumez
da244d7ef2 - Added more debug when we get a file_error 2007-09-18 22:41:23 +00:00
Christophe Dumez
2fc7039cc7 - COSMETIC: Progress bar text now uses style foreground color 2007-09-18 22:09:06 +00:00
Christophe Dumez
654497cd4a - Disable debug in libtorrent when qBittorrent is in release mode 2007-09-18 20:01:31 +00:00
Christophe Dumez
bdf50483df - Attempt to make progress bar text color dynamic 2007-09-18 19:08:09 +00:00
Christophe Dumez
8a0681744e - Improved tracker deletion code slightly 2007-09-18 17:27:01 +00:00
Christophe Dumez
2699c76afd Updated japanese 2007-09-18 06:52:41 +00:00
Christophe Dumez
773064a081 - beta7 release 2007-09-17 19:50:47 +00:00
Christophe Dumez
7718403419 - Perfected chinese translation 2007-09-17 19:42:31 +00:00
Christophe Dumez
26b4d31810 - Updated a lot of translations 2007-09-17 19:16:12 +00:00
Christophe Dumez
f8dfda0893 - Updated resource files 2007-09-16 19:59:54 +00:00
Christophe Dumez
e8897ae159 - Fixed configure 2007-09-16 19:58:07 +00:00
Christophe Dumez
2f71f9f51a - Updated russian translation 2007-09-16 18:37:24 +00:00
Christophe Dumez
fc595f49d8 - Updated slovak translation 2007-09-16 16:51:56 +00:00
Christophe Dumez
92444fccf4 - Updated swedish translation 2007-09-16 15:15:44 +00:00
Christophe Dumez
6d0aebe9cb - Edit a bit of code in torrent permanent deletion to make sure all files are actually deleted 2007-09-16 15:13:32 +00:00
Christophe Dumez
ef7af6bad6 - Fixed torrent permanent deletion from hd
- Updated Romanian translation
2007-09-16 15:10:25 +00:00
Christophe Dumez
c1a8a58080 - Updated TODO 2007-09-16 14:27:13 +00:00
Christophe Dumez
76047f4ef2 - Fixed transfers list interval setting 2007-09-16 14:25:24 +00:00
Christophe Dumez
9062266a84 - Fixed a ratio assert in libtorrent because we sent it -1 for unlimited instead of 0 2007-09-16 14:16:42 +00:00
Christophe Dumez
9cdcd53234 - Completed french translation 2007-09-16 14:02:06 +00:00
Christophe Dumez
419b94f042 - A lot of improvement and bug fixes in new torrent content selection 2007-09-16 13:33:41 +00:00
Christophe Dumez
3cb34ed7ee - Fixed an overflow that could cause ETA to become negative sometimes (hitted an assert) 2007-09-16 12:30:41 +00:00
Christophe Dumez
925ecb3464 - Fixed search engines plugins saving 2007-09-16 12:08:26 +00:00
Christophe Dumez
488bd90303 - Fixed a bug in torrent content selection when there is only one file in the torrent 2007-09-16 09:41:05 +00:00
Christophe Dumez
c478ba59ac - new torrent content selection (as a tree). Merge from the new-torrent-selection branch 2007-09-16 09:19:22 +00:00
Christophe Dumez
fe7c0db425 - remove ratio should be applied to finished torrent only (and disabled as a default!) - FIXED 2007-09-13 19:50:14 +00:00
Christophe Dumez
b2bf7047d9 - Fixed search resource file 2007-09-13 19:34:21 +00:00
Christophe Dumez
e943449b42 - Updated TODO, spotted a bug 2007-09-13 18:48:52 +00:00
Christophe Dumez
69e2355ff4 Update language files 2007-09-11 19:32:37 +00:00
Christophe Dumez
b7ea2fb51a - Allow to download plugins from their url 2007-09-11 19:31:21 +00:00
Christophe Dumez
4c880fea09 - Improved tooltip title style 2007-09-11 18:49:24 +00:00
Christophe Dumez
a0e895641c - Improved systray tooltip a little 2007-09-11 11:55:58 +00:00
Christophe Dumez
484f1c36c9 - Improved systray style 2007-09-10 20:25:31 +00:00
Christophe Dumez
982ce5c0ad - Updated TODO 2007-09-09 20:12:54 +00:00
Christophe Dumez
7ac5da0acc - Updated TODO 2007-09-09 20:10:49 +00:00
Christophe Dumez
9733716136 - Updated language files 2007-09-09 20:08:53 +00:00
Christophe Dumez
eebdc26e5a - FEATURE: Articles in a RSS feed are now ordered by date (newer at the top)
- FEATURE: Read articles in a feed are not resetted when the feed is refreshed anymore
2007-09-09 20:02:49 +00:00
Christophe Dumez
1f8b9378a3 - FEATURE: Display RSS article date and author if available 2007-09-09 19:19:33 +00:00
Christophe Dumez
b99b838827 - Fix in rss refresh and mark all as read 2007-09-09 17:02:12 +00:00
Christophe Dumez
c4d143c2c0 - Added some RSS preferences 2007-09-09 15:46:23 +00:00
Christophe Dumez
db1bd53f44 - Fixed a typo in RSS 2007-09-09 12:23:29 +00:00
Christophe Dumez
07dc182053 - FEATURE: Added 'Mark all as read' function for RSS feeds 2007-09-09 11:31:51 +00:00
Christophe Dumez
563055e891 Updated language files 2007-09-09 09:47:59 +00:00
Christophe Dumez
b3de2ccc72 - Small fix for proxy options 2007-09-09 09:42:30 +00:00
Christophe Dumez
f4d5ceb3c4 - Fixed a unit problem in last commit 2007-09-09 09:36:10 +00:00
Christophe Dumez
70beef9f94 - FEATURE: Added an option to display current transfer speeds in title bar 2007-09-09 09:35:30 +00:00
Christophe Dumez
47c1908519 - Added some more debug 2007-09-09 09:20:01 +00:00
Christophe Dumez
e1ead940be - Added some more debug 2007-09-09 09:15:29 +00:00
Christophe Dumez
862d24ac48 - FEATURE: Added an option to automatically delete torrents when they reach a given ratio (>= 1.0) 2007-09-09 09:09:24 +00:00
Christophe Dumez
078c80c81d - FEATURE: Added an option to set the max number of connections per torrent
- FEATURE: Added an option to set the max number of uploads per torrent
2007-09-09 07:44:22 +00:00
Christophe Dumez
6ba4588e62 Updated language files 2007-09-08 17:11:08 +00:00
Christophe Dumez
cd70843ee9 - Totally redesigned program preferences
- Added some options, the following are already implemented:
  * Start/Stop LSD/NAT-PMP/UPnP
	* Force preallocation of all files
	* Force new torrents status to pause
- Other new features are going to be implemented soon
2007-09-08 17:07:29 +00:00
Christophe Dumez
cb8ecb74bf - Fixed a bug introduced recently in torrent addition dialog 2007-09-04 04:27:52 +00:00
Christophe Dumez
9f36d521a4 - BUGFIX: Fixed deprecation warning with latest libtorrent svn
- FEATURE: Redesigned torrent creation dialog
- FEATURE: Allow to set piece size when creating a torrent
- improved new options dialog a little
2007-09-04 04:18:51 +00:00
Christophe Dumez
2c2c1093c3 - Reworked options UI file. Now I need to rewrite the code 2007-09-04 02:20:28 +00:00
Christophe Dumez
0e81f3731f - Dropped Qt4.2 support, it becomes too difficult to maintain for me and Trolltech broke backward compatibility for UI files... 2007-09-03 22:59:46 +00:00
Christophe Dumez
f1114387ae - Updated TODO 2007-09-03 22:54:19 +00:00
Christophe Dumez
54516ac231 - In torrent content selection, check if all files are filtered before saving and display an error if it is the case. I removed this checking on right click menu in case people want to filter all torrents, then add one, then save. 2007-09-03 22:52:58 +00:00
Christophe Dumez
913f93ba82 - Updated language files
- Fixed a typo in french translation
- Updated Hungarian translation
2007-09-03 22:38:37 +00:00
Christophe Dumez
11c7255da6 - Added a lot of stuff to TODO list 2007-09-03 22:33:37 +00:00
Christophe Dumez
69fa916e26 - FEATURE: Added zip support in search plugins manager (can put .py & .png inside) 2007-09-03 22:05:40 +00:00
Christophe Dumez
d86335a58e - Rename fake zip files to pyqBT because we will add real zip support soon 2007-09-03 17:58:23 +00:00
Christophe Dumez
24dced2411 - BUGFIX: the function that set the rows color doesn't handle hidden columns anymore
- BUGFIX: improved search engine plugin manager code and fixed bugs
2007-09-03 17:45:16 +00:00
Christophe Dumez
1b71a4a4a4 - Updated TODO 2007-09-03 17:18:31 +00:00
Christophe Dumez
ffedffcead - Updated Itralian, greek and bolgarian translations 2007-09-03 11:14:11 +00:00
Christophe Dumez
1f64e14195 updated french translation 2007-09-02 17:08:55 +00:00
Christophe Dumez
d6a5b1d321 updated language files 2007-09-02 17:05:26 +00:00
Christophe Dumez
792101731f - BUGFIX: Fixed torrent create (can only one file or one folder) 2007-09-02 17:03:33 +00:00
Christophe Dumez
3e783873ec - BUGFIX: Made pause/resume all function affect both (dl/up) tabs when window is hidden 2007-09-02 14:57:07 +00:00
Christophe Dumez
ffb262f0a1 - Fixed log context menu position
- Updated Changelog
2007-09-02 14:42:09 +00:00
Christophe Dumez
4727c1bdca - Updated remove icon 2007-09-02 14:29:43 +00:00
Christophe Dumez
1f1e37ce76 - Updated bug report icon 2007-09-02 14:14:22 +00:00
Christophe Dumez
f40337d2e3 - Updated cryptographie icon 2007-09-02 13:53:34 +00:00
Christophe Dumez
ecc5106f07 - Updated TODO 2007-09-02 13:32:14 +00:00
Christophe Dumez
1b93f4eaf1 - Fixed a little bug in last commit 2007-09-02 13:23:02 +00:00
Christophe Dumez
685ceafc5b - second attempt for drag n drop 2007-09-02 13:19:30 +00:00
Christophe Dumez
cf6128a222 - Fixed drag'ndrop on non-KDE systems 2007-09-02 13:06:42 +00:00
Christophe Dumez
f78c74c1b5 - Updated checking icon 2007-09-02 12:50:38 +00:00
Christophe Dumez
faeee49517 - Use RSS (un)subscribe icons 2007-09-02 12:44:09 +00:00
Christophe Dumez
1918969e28 - Updated RSS icon with one from Oxygen (KDE4 icons) 2007-09-02 12:12:51 +00:00
Christophe Dumez
fa9e3bf564 Updated french translation 2007-09-02 09:37:18 +00:00
Christophe Dumez
8eac154c05 Updated language files 2007-09-02 09:32:59 +00:00
Christophe Dumez
ff12c76a62 - Updated TODO 2007-09-02 09:12:26 +00:00
Christophe Dumez
2c27f952e2 - FEATURE: Allow to drag'n drop plugin to list for install/update
- Added some debug
2007-09-02 09:01:22 +00:00
Christophe Dumez
e3214a9b6a - Updated TODO 2007-09-02 08:23:59 +00:00
Christophe Dumez
4a02d171b4 - BUGFIX: 'Unknown' is now displayed in search results columns where value is -1
- BUGFIX: Improved search engine core a little
- BUGFIX: Forgot to remove *.pyc files when uninstalling a search plugin
2007-09-02 07:58:25 +00:00
Christophe Dumez
7a16a1d8f1 - updated language files 2007-09-02 06:53:55 +00:00
Christophe Dumez
ecc41fbc60 - Display "Unknown" in search engine result columns where value is -1 2007-09-02 06:39:55 +00:00
Christophe Dumez
0125a2b521 - Updated polish translation 2007-09-01 23:05:56 +00:00
Christophe Dumez
d328b93c1a - Updated swedish and German translations 2007-09-01 23:01:15 +00:00
Christophe Dumez
ab588b741e Paused torrents could be displayed as connected for a sec after checking 2007-09-01 22:57:50 +00:00
Christophe Dumez
1588cd5d3d - Updated Ukrainian translation 2007-09-01 12:24:40 +00:00
Christophe Dumez
a597f067e2 - Updated french and dutch translations
- Fixed some typos in engineSelect
- Made search engine plugin install more reliable
- Added some comments
2007-09-01 10:23:39 +00:00
Christophe Dumez
0778f2a19e - Updated Russian translation 2007-08-31 21:32:30 +00:00
Christophe Dumez
6c0d4b9439 - Dropped Hong Kong flag 2007-08-31 17:39:41 +00:00
Christophe Dumez
98d91f7697 - beta6 release 2007-08-31 17:15:38 +00:00
Christophe Dumez
f7ac4ec652 - Updated Italian translation 2007-08-31 16:56:21 +00:00
Christophe Dumez
43b96ea4f2 - Updated slovak translation 2007-08-31 16:55:00 +00:00
Christophe Dumez
91bd5f1d8e - Updated Changelog 2007-08-31 16:51:02 +00:00
Christophe Dumez
f0edd7dcf7 - Added multipage support for mininova 2007-08-31 16:39:29 +00:00
Christophe Dumez
e3f2480fe5 - Added multipage support to btjunkie plugin 2007-08-31 16:15:39 +00:00
Christophe Dumez
26e5785754 - Fixed plugin update && fixed btjunkie search plugin 2007-08-31 16:02:01 +00:00
Christophe Dumez
db12fb292a - Updated French translation 2007-08-31 14:25:07 +00:00
Christophe Dumez
798ee52de1 - Added some more debug 2007-08-31 14:08:47 +00:00
Christophe Dumez
b1f562d7c0 - Fixed a bug in previous commit
- Added some debug
2007-08-31 13:39:27 +00:00
Christophe Dumez
41daeb4c19 - Added a messagebox when plugin are already up to date 2007-08-31 13:35:55 +00:00
Christophe Dumez
d66b788e5f - Update translation files 2007-08-31 12:11:38 +00:00
Christophe Dumez
ff4ab915a2 - Merged custom-search branch. New search plugins management system 2007-08-31 12:06:31 +00:00
222 changed files with 56446 additions and 25781 deletions

74
AUTHORS
View File

@@ -3,3 +3,77 @@ Author:
Contributors: Contributors:
* Arnaud Demaizière <arnaud@qbittorrent.org> * Arnaud Demaizière <arnaud@qbittorrent.org>
* Ishan Arora <ishan@qbittorrent.org>
* Grigis Gaëtan <cipher16@gmail.com>
Code from other projects:
* files src/ico.cpp src/ico.h
copyright: Malte Starostik <malte@kde.org>
license: LGPL
Images Authors:
* files: src/Icons/*.png
copyright: Gnome Icon Theme
license: GPLv2
url: http://ftp.acc.umu.se/pub/GNOME/sources/gnome-icon-theme
* files: src/Icons/flags/*.png
copyright: Open Clip Art Library
license: Creative Commons Public Domain Dedication
url: http://www.openclipart.org
* files: src/Icons/skin/*.png
files: src/menuicons/YYxYY/*.png
copyright: Mateusz Tobola <tobejodok@qbittorrent.org>
license: GPLv2
* file: src/Icons/skin/tabs.gif
copyright: Greg Houston <gregory.houston@gmail.com>
license: MIT
* file: src/search_engine/engines/btjunkie.png
copyright: Downloaded from btjunkie.org
* file: src/search_engine/engines/isohunt.png
copyright: Downloaded from isohunt.com
* file: src/search_engine/engines/mininova.png
copyright: Downloaded from mininova.org
* file: src/search_engine/engines/piratebay.png
copyright: Downloaded from thepiratebay.org
* file: src/search_engine/engines/torrentreactor.png
copyright: Downloaded from torrentreactor.net
Translations authors:
* files: src/lang/*.ts
copyright:
- Brazilian: Nick Marinho (nickmarinho@gmail.com)
- Bulgarian: Tsvetan & Boiko Bankov (emerge_life@users.sourceforge.net)
- Catalan: Gekko Dam Beer (gekko04@users.sourceforge.net)
- Chinese (Simplified): Guo Yue (yue.guo0418@gmail.com)
- Chinese (Traditional): Yi-Shun Wang (dnextstep@gmail.com)
- Czech: Jirka Vilim (web@tets.cz)
- Danish: Mathias Nielsen (comoneo@gmail.com)
- Dutch: Joost Schipper (heavyjoost@users.sourceforge.net)
- English: Christophe Dumez (chris@qbittorrent.org)
- Finnish: Niklas Laxström (nikerabbit@users.sourceforge.net)
- French: Christophe Dumez (chris@qbittorrent.org)
- German: Niels Hoffmann (zentralmaschine@users.sourceforge.net)
- Greek: Tsvetan Bankov (emerge_life@users.sourceforge.net)
- Hungarian: Majoros Péter (majoros.j.p@t-online.hu)
- Italian: Mirko Ferrari (mirkoferrari@gmail.com) and Ferraro Luciano (luciano.ferraro@gmail.com)
- Japanese: Nardog (nardog@e2umail.com)
- Korean: Jin Woo Sin (jin828sin@users.sourceforge.net)
- Norwegian: Lars-Erik Labori (hamil@users.sourceforge.net)
- Polish: Jarek Smieja (ajep9691@wp.pl)
- Portuguese: Nick Marinho (nickmarinho@gmail.com)
- Romanian: Obada Denis (obadadenis@users.sourceforge.net)
- Russian: Nick Khazov (m2k3d0n at users.sourceforge.net)
- Slovak: helix84
- Spanish: Vicente Raul Plata Fonseca (silverxnt@users.sourceforge.net)
- Swedish: Daniel Nylander (po@danielnylander.se)
- Turkish: Erdem Bingöl (erdem84@gmail.com)
- Ukrainian: Andrey Shpachenko (masterfix@users.sourceforge.net)
license: GPLv2

112
Changelog
View File

@@ -1,4 +1,111 @@
* Unknown - Christophe Dumez <chris@qbittorrent.org> - v1.0.0 * Fri Jan 9 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.3.0
- FEATURE: Based on libtorrent-rasterbar v0.14.2
- FEATURE: Improved ratio calculation system
- FEATURE: Torrent creation code cleanup
- FEATURE: Allow to set maximum number of active seeds (queueing)
- FEATURE: Now seeds priorities are handled automatically by libtorrent-rasterbar (queueing)
- FEATURE: Code cleanup and optimization (save memory and cpu)
- FEATURE: ETA calculation now relies on average speed over all sessions
- FEATURE: Allow to force rechecking torrents
- FEATURE: Added support for 2 new extensions (uTorrent metadata and smart ban plugin)
- FEATURE: Allow to change the save path of torrents after addition
- FEATURE: Got rid of libmagick++ dependency
- FEATURE: Updated Web interface to MochaUI v0.9.5
- FEATURE: Added notification in WebUI when qBittorrent is not reachable
- FEATURE: Rewrote folder scanning code (Now uses a filesystem watcher)
- FEATURE: Added torrent deletion from hard drive function in Web UI
- FEATURE: Added queueing priority actions in Web UI
- FEATURE: Display progress using progress bars in Web UI
- BUGFIX: Made usage of fastresume data more reliable
- BUGFIX: qBittorrent shutdown is now faster
- BUGFIX: Fixed several memory leaks
- BUGFIX: WebUI is now working with IE7
- BUGFIX: Fixed spacing problem in toolbar when toggling its visibility
- BUGFIX: Fixed some compilation and Qt4 warnings
- BUGFIX: Do not use an addition dialog for torrents from folder scanning
- BUGFIX: Catch SIGTERM to exit cleanly (e.g. computer shutdown)
- BUGFIX: Improved proxy support code
- BUGFIX: Fixed systray icon tooltip on Windows
- BUGFIX: Proxy settings are now saved even if disabled
* Sun Nov 9 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.2.1
- BUGFIX: Fixed possible crash when deleting a torrent permanently
- BUGFIX: Queued_for_checking torrents were not displayed as checking in seeding list
- BUGFIX: Speed up startup time when having a lot of torrents
* Wed Oct 29th 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.2.0
- FEATURE: Torrent queueing system (with priorities)
- FEATURE: The number of DHT nodes is displayed
- FEATURE: RSS can now be disabled from program preferences
- FEATURE: Added collapse/expand all buttons in addition and properties dialogs
- FEATURE: Can have different proxies for Bittorrent and search engine
- FEATURE: Allow multiple item selection in Web UI transfer list
- FEATURE: Moved uploads to a separate list in Web UI
- BUGFIX: Totally rewritten Web UI list refresh system (fixed memory leak)
- BUGFIX: Disable ETA calculation when ETA column is hidden
- BUGFIX: Removed "disconnected" connection state, detection was far from perfect
- BUGFIX: Torrents are no longer starting from scratch when changing default save path (when torrent addition dialog is disabled)
- BUGFIX: Single instance code is now more reliable on Qt >= 4.4
- COSMETIC: Transfer speed, ratio, connection status and DHT nodes are displayed in status bar
- COSMETIC: RSS Tab is now hidden as a default
- COSMETIC: Allow to hide or display top toolbar
- COSMETIC: Log is now in a separate dialog
* Sun Sept 14 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.1.4
- FEATURE: DHT is no longer used as fallback only
- FEATURE: Ported WebUI to Mootools v1.2
- BUGFIX: Fixed 'start seeding after torrent creation' feature
- BUGFIX: Fixed compilation with boost v1.36
- BUGFIX: Some code optimization
- BUGFIX: Fixed memory leak in Web UI
- BUGFIX: Fixed problems with column sorting
- BUGFIX: Improved code for pausing torrents on startup
- BUGFIX: Torrent addition dialog is now disabled for downloads from WebUI
- BUGFIX: Give focus to input field in WebUI download dialog
* Tue Aug 26 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.1.3
- BUGFIX: Fixed ratio saving for seeding torrents
- I18N: Added czech and traditional chinese translations
* Sun Aug 17 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.1.2
- BUGFIX: Fixed progress calculation
- BUGFIX: Fixed finished torrent detection
* Fri Aug 01 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.1.1
- BUGFIX: Fixed bad resource file for icons
* Fri Aug 01 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.1.0
- FEATURE: Web interface to control qbittorrent (Ishan Arora)
- FEATURE: Can spoof Azureus peer id to avoid ban
- FEATURE: Allow to hide/show some columns in download and seeding lists
- FEATURE: Option to start qBittorrent minimized in systray
- FEATURE: Multi-tab support in search engine (Grigis Gaëtan)
- FEATURE: Allow to define double-click actions in torrents lists
- FEATURE: Allow to open torrent destination folder
- FEATURE: Real progress bar in torrent properties that displays downloaded pieces
- FEATURE: Allow to buy downloads using ShareMonkey
- FEATURE: Display if UPnP/NAT-PMP was successful or not
- FEATURE: Threadified torrent creation
- FEATURE: Improved eMule DAT ip filter parser
- FEATURE: Added support for PeerGuardian p2p filters (text)
- FEATURE: Added support for PeerGuardian p2b filters (binary)
- FEATURE: Allow to customize folder scan interval
- FEATURE: Allow to add several trackers at once
- BUGFIX: Allow to run one instance of qBittorrent per user
- BUGFIX: Do not display seeds number in seeding list (always 0)
- BUGFIX: Threadified IP filter file parser to avoid GUI freeze
- BUGFIX: Ask if we want to redownload if content was deleted from hard drive
- BUGFIX: Added missing copyright/licensing information for some files
- BUGFIX: qBittorrent is no longer conflicting with rTorrent (libtorrent renamed to libtorrent-rasterbar)
- COSMETIC: Do not display progress bar in seeding list (always 100%)
- COSMETIC: Added a progress bar for torrent creation
- COSMETIC: Display tracker errors in a cleaner way
- COSMETIC: Display "unpaused/total_torrent" in download/upload tabs
- COSMETIC: Allow to resize RSS column
- COSMETIC: Global UP/DL speeds and ratio are displayed above tabs
- COSMETIC: Use infinity symbol for ETA when time is infinite
* Fri Apr 11 2008 - Christophe Dumez <chris@qbittorrent.org> - v1.0.0
- FEATURE: Based on new libtorrent v0.13 - FEATURE: Based on new libtorrent v0.13
- FEATURE: Added UPnP / NAT-PMP port forwarding support - FEATURE: Added UPnP / NAT-PMP port forwarding support
- FEATURE: Added encryption support (compatible with Azureus) - FEATURE: Added encryption support (compatible with Azureus)
@@ -6,6 +113,7 @@
- FEATURE: Added RSS support - FEATURE: Added RSS support
- FEATURE: Support files prioritizing in a torrent - FEATURE: Support files prioritizing in a torrent
- FEATURE: Brand new search engine plugins system - FEATURE: Brand new search engine plugins system
- FEATURE: Filtered files don't appear on hard disk anymore
- FEATURE: Finished torrents are now moved to another tab for seeding - FEATURE: Finished torrents are now moved to another tab for seeding
- FEATURE: Display more infos about the torrent in its properties - FEATURE: Display more infos about the torrent in its properties
- FEATURE: Allow the user to edit torrents' trackers - FEATURE: Allow the user to edit torrents' trackers
@@ -63,6 +171,8 @@
- BUGFIX: Prevent downloadFromUrl flooding - BUGFIX: Prevent downloadFromUrl flooding
- BUGFIX: ETA was wrong for torrents with filtered files - BUGFIX: ETA was wrong for torrents with filtered files
- BUGFIX: Fixed drag'n drop on non-KDE systems - BUGFIX: Fixed drag'n drop on non-KDE systems
- BUGFIX: Removed build dependency on Python
- BUGFIX: Catching DHT exception in case there is a problem
- COSMETIC: Redesigned torrent properties a little - COSMETIC: Redesigned torrent properties a little
- COSMETIC: Totally redesigned program preferences - COSMETIC: Totally redesigned program preferences
- COSMETIC: Display more logs messages concerning features - COSMETIC: Display more logs messages concerning features

View File

@@ -15,17 +15,16 @@ will install and execute qBittorrent hopefully without any problems.
Dependencies: Dependencies:
- Qt >= 4.3.0 (libqt-devel, libqtgui, libqtcore, libqtnetwork, libqtxml) - Qt >= 4.3.0 (libqt-devel, libqtgui, libqtcore, libqtnetwork, libqtxml)
Qt >= 4.4.0 is advised
- rblibtorrent by Arvid Norberg (>= v0.13 REQUIRED) - libtorrent-rasterbar by Arvid Norberg (>= v0.14.0 REQUIRED)
-> http://www.qbittorrent.org/download.php (advised) -> http://www.qbittorrent.org/download.php (advised)
-> http://www.libtorrent.net -> http://www.libtorrent.net
Be careful: another library (the one used by rTorrent) use the same name. Be careful: another library (the one used by rTorrent) uses a similar name.
These are TWO different libraries and qBittorrent will only work with the one provided
on sourceforge (created by Arvid Norberg). The two libraries conflicts with each other.
- libboost: libboost-filesystem, libboost-date-time, libboost-thread, libboost-serialization - libboost: libboost-filesystem, libboost-date-time, libboost-thread, libboost-serialization
- libcommoncpp2 - libcurl
- python >= 2.3 (needed by search engine) - python >= 2.3 (needed by search engine)

81
TODO
View File

@@ -1,65 +1,18 @@
// Easy See https://blueprints.launchpad.net/qbittorrent/
- Translations into as many languages as possible
- Use Launchpad/Rosetta for translations once it supports TS files
// Intermediate // translations done in v1.3.0
- Port on MacOS, Windows (and create an installer for Windows) - Slow progress - Romanian
- Add some transparency (menus,...), improve look / usabilty - Russian
- Skins support? (contact Mateusz) - Hungarian
- German
// Harder - Chinese (traditional)
- Display a progress bar that really represents the pieces we have (like in eMule) - Chinese (simplified)
- Torrent scheduler ala µtorrent/Bitcomet - Italian
- Swedish
// Waiting for libtorrent - Turkish
- File selection in a torrent in compact mode - French
- Allow to prioritize torrents (may code this in qBittorrent?) - Slovak
- Czech
// Unsure - Korean
- Display the peers we are connected to for each torrent with infos (like flag, dl/up speeds, ...) - Portuguese
- Azureus spoofing to prevent ban from trackers? - Brazilian
- Option to shutdown computer when downloads are finished
- NAT checker/Tester
- Display hard drive space left?
- Make use of dbus on Linux for the single instance instead of socket communication?
(http://techbase.kde.org/Development/Tutorials/D-Bus/Accessing_Interfaces)
- When favicon can't be downloaded, try to parse the webpage for:
<link rel="icon" href="http://example.com/favicon.ico" type="image/vnd.microsoft.icon">
* Be carefull, the link can be relative
// in v1.2.0
- Allow user to organize the downloads into categories/folders?
// in v1.1.0
- Tabs support in search
- Allow to hide columns?
- Allow to scan multiple directories? (useful?)
- Web interface (turbogears? php? python?)
* Webserver? Try to write a webserver as a plugin for qBittorrent in Python
* http://fragments.turtlemeat.com/pythonwebserver.php
- improve and test tracker authentication code (remember login/pass) (need a tracker to test this)
- support zipped torrents? (useful?)
- Allow to limit the number of downloading torrents simultaneously (other are paused until a download finishes)
- Improve search plugin install (choose in a list taken from plugins.qbittorrent.org)
- Display the number of DHT node if possible
- When adding a duplicate torrent, check if the trackers are different from the existing one and ask the user if he wants to add them
- Display in torrent addition dialog:
* free disk space on selected drive
* free disk space after torrent download (and/or torrent size)
- Allow to change action on double-click
-> in download list
-> in seeding list
// in v1.0.0 - FEATURE FREEZE
- Fix all (or almost all) opened bugs in bug tracker
- debug new torrent content selection
- Recheck doc
- Translations update (IN PROGRESS)
- add qt4-qtconfig as package dependency
rc3->rc4 changelog:
- BUGFIX: Fixed ip filter preferences (couldn't enable it)
- BUGFIX: Fixed compilation problems on FreeBSD (Ok now)
- BUGFIX: Updated INSTALL file
- BUGFIX: Optimized torrent real size calculation
- BUGFIX: Use system default style as a default (instead of Plastique style)

254
configure vendored
View File

@@ -18,15 +18,14 @@ Main options:
--help This help text. --help This help text.
Dependency options: Dependency options:
--with-libtorrent-inc=[path] Path to libtorrent include files --with-libtorrent-inc=[path] Path to libtorrent-rasterbar include
--with-libtorrent-lib=[path] Path to libtorrent library files files
--with-libtorrent-static-lib=[path] Path to libtorrent .a file --with-libtorrent-lib=[path] Path to libtorrent-rasterbar library
files
--with-libtorrent-static-lib=[path] Path to libtorrent-rasterbar .a file
--with-libboost-inc=[path] Path to libboost include files --with-libboost-inc=[path] Path to libboost include files
--with-libcommoncpp2-inc=[path] Path to libcommoncpp2 include files --with-libcurl-inc=[path] Path to libcurl include files
--with-libcommoncpp2-lib=[path] Path to libcommoncpp2 library files --with-libcurl-lib=[path] Path to libcurl library files
--disable-libmagick Disable use of libmagick
--with-libmagick-inc=[path] Path to libmagick++ include files
--with-libmagick-lib=[path] Path to libmagick++ library files
--disable-libzzip Disable use of libzzip --disable-libzzip Disable use of libzzip
--with-libzzip-inc=[path] Path to libzzip++ include files --with-libzzip-inc=[path] Path to libzzip++ include files
--with-libzzip-lib=[path] Path to libzzip++ library files --with-libzzip-lib=[path] Path to libzzip++ library files
@@ -166,28 +165,13 @@ while [ $# -gt 0 ]; do
shift shift
;; ;;
--with-libcommoncpp2-inc=*) --with-libcurl-inc=*)
QC_WITH_LIBCOMMONCPP2_INC=$optarg QC_WITH_LIBCURL_INC=$optarg
shift shift
;; ;;
--with-libcommoncpp2-lib=*) --with-libcurl-lib=*)
QC_WITH_LIBCOMMONCPP2_LIB=$optarg QC_WITH_LIBCURL_LIB=$optarg
shift
;;
--disable-libmagick)
QC_DISABLE_libmagick="Y"
shift
;;
--with-libmagick-inc=*)
QC_WITH_LIBMAGICK_INC=$optarg
shift
;;
--with-libmagick-lib=*)
QC_WITH_LIBMAGICK_LIB=$optarg
shift shift
;; ;;
@@ -231,11 +215,8 @@ echo QC_WITH_LIBTORRENT_INC=$QC_WITH_LIBTORRENT_INC
echo QC_WITH_LIBTORRENT_LIB=$QC_WITH_LIBTORRENT_LIB echo QC_WITH_LIBTORRENT_LIB=$QC_WITH_LIBTORRENT_LIB
echo QC_WITH_LIBTORRENT_STATIC_LIB=$QC_WITH_LIBTORRENT_STATIC_LIB echo QC_WITH_LIBTORRENT_STATIC_LIB=$QC_WITH_LIBTORRENT_STATIC_LIB
echo QC_WITH_LIBBOOST_INC=$QC_WITH_LIBBOOST_INC echo QC_WITH_LIBBOOST_INC=$QC_WITH_LIBBOOST_INC
echo QC_WITH_LIBCOMMONCPP2_INC=$QC_WITH_LIBCOMMONCPP2_INC echo QC_WITH_LIBCURL_INC=$QC_WITH_LIBCURL_INC
echo QC_WITH_LIBCOMMONCPP2_LIB=$QC_WITH_LIBCOMMONCPP2_LIB echo QC_WITH_LIBCURL_LIB=$QC_WITH_LIBCURL_LIB
echo QC_DISABLE_libmagick=$QC_DISABLE_libmagick
echo QC_WITH_LIBMAGICK_INC=$QC_WITH_LIBMAGICK_INC
echo QC_WITH_LIBMAGICK_LIB=$QC_WITH_LIBMAGICK_LIB
echo QC_DISABLE_libzzip=$QC_DISABLE_libzzip echo QC_DISABLE_libzzip=$QC_DISABLE_libzzip
echo QC_WITH_LIBZZIP_INC=$QC_WITH_LIBZZIP_INC echo QC_WITH_LIBZZIP_INC=$QC_WITH_LIBZZIP_INC
echo QC_WITH_LIBZZIP_LIB=$QC_WITH_LIBZZIP_LIB echo QC_WITH_LIBZZIP_LIB=$QC_WITH_LIBZZIP_LIB
@@ -354,29 +335,33 @@ public:
QString shortname() const { return "Qt 4.3"; } QString shortname() const { return "Qt 4.3"; }
bool exec() bool exec()
{ {
if(QT_VERSION >= 0x040400) {
conf->addDefine("QT_4_4");
}
return(QT_VERSION >= 0x040300); return(QT_VERSION >= 0x040300);
} }
}; };
#line 1 "libtorrent.qcm" #line 1 "libtorrent-rasterbar.qcm"
/* /*
-----BEGIN QCMOD----- -----BEGIN QCMOD-----
name: libtorrent name: libtorrent-rasterbar
arg: with-libtorrent-inc=[path], Path to libtorrent include files arg: with-libtorrent-inc=[path], Path to libtorrent-rasterbar include files
arg: with-libtorrent-lib=[path], Path to libtorrent library files arg: with-libtorrent-lib=[path], Path to libtorrent-rasterbar library files
arg: with-libtorrent-static-lib=[path], Path to libtorrent .a file arg: with-libtorrent-static-lib=[path], Path to libtorrent-rasterbar .a file
-----END QCMOD----- -----END QCMOD-----
*/ */
class qc_libtorrent : public ConfObj class qc_libtorrent_rasterbar : public ConfObj
{ {
public: public:
qc_libtorrent(Conf *c) : ConfObj(c) {} qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {}
QString name() const { return "libtorrent >= 0.13"; } QString name() const { return "libtorrent-rasterbar >= 0.14"; }
QString shortname() const { return "libtorrent"; } QString shortname() const { return "libtorrent-rasterbar"; }
bool exec(){ bool exec(){
QString s; QString s;
s = conf->getenv("QC_WITH_LIBTORRENT_INC"); s = conf->getenv("QC_WITH_LIBTORRENT_INC");
if(!s.isEmpty()) { if(!s.isEmpty()) {
if(!conf->checkHeader(s, "libtorrent/lsd.hpp")) { if(!conf->checkHeader(s, "libtorrent/magnet_uri.hpp")) {
return false; return false;
} }
}else{ }else{
@@ -385,7 +370,7 @@ public:
sl << "/usr/local/include"; sl << "/usr/local/include";
bool found = false; bool found = false;
foreach(s, sl){ foreach(s, sl){
if(conf->checkHeader(s, "libtorrent/lsd.hpp")){ if(conf->checkHeader(s, "libtorrent/magnet_uri.hpp")){
found = true; found = true;
break; break;
} }
@@ -405,17 +390,19 @@ public:
s = conf->getenv("QC_WITH_LIBTORRENT_LIB"); s = conf->getenv("QC_WITH_LIBTORRENT_LIB");
if(!s.isEmpty()) { if(!s.isEmpty()) {
if(!conf->checkLibrary(s, "torrent")) { if(!conf->checkLibrary(s, "torrent-rasterbar")) {
return false; return false;
} }
conf->addLib(QString("-L") + s); conf->addLib(QString("-L") + s);
}else{ }else{
QStringList sl; QStringList sl;
sl << "/usr/lib/"; sl << "/usr/lib/";
sl << "/usr/lib64/";
sl << "/usr/local/lib/"; sl << "/usr/local/lib/";
sl << "/usr/local/lib64/";
bool found = false; bool found = false;
foreach(s, sl){ foreach(s, sl){
if(conf->checkLibrary(s, "torrent")){ if(conf->checkLibrary(s, "torrent-rasterbar")){
found = true; found = true;
break; break;
} }
@@ -423,16 +410,6 @@ public:
if(!found) return false; if(!found) return false;
conf->addLib(QString("-L") + s); conf->addLib(QString("-L") + s);
} }
// BUGFIX for Fedora (doesn't support pkg-config?)
QFile issue_file("/etc/issue");
if(issue_file.open(QIODevice::ReadOnly | QIODevice::Text)){
QString content = issue_file.readAll();
issue_file.close();
if(content.indexOf("Fedora") != -1){
qWarning("Fedora detected. WORKAROUND for Fedora pkg-config problem enabled");
conf->addLib("-lssl -lcrypto -lboost_date_time -lboost_filesystem -lboost_thread -lz -ltorrent");
}
}
return true; return true;
} }
}; };
@@ -493,25 +470,25 @@ public:
return true; return true;
} }
}; };
#line 1 "libcommoncpp2.qcm" #line 1 "libcurl.qcm"
/* /*
-----BEGIN QCMOD----- -----BEGIN QCMOD-----
name: libcommoncpp2 name: libcommoncpp2
arg: with-libcommoncpp2-inc=[path], Path to libcommoncpp2 include files arg: with-libcurl-inc=[path], Path to libcurl include files
arg: with-libcommoncpp2-lib=[path], Path to libcommoncpp2 library files arg: with-libcurl-lib=[path], Path to libcurl library files
-----END QCMOD----- -----END QCMOD-----
*/ */
class qc_libcommoncpp2 : public ConfObj class qc_libcurl : public ConfObj
{ {
public: public:
qc_libcommoncpp2(Conf *c) : ConfObj(c) {} qc_libcurl(Conf *c) : ConfObj(c) {}
QString name() const { return "GNU Common C++ library (libcommoncpp2)"; } QString name() const { return "libcurl"; }
QString shortname() const { return "libcommoncpp2"; } QString shortname() const { return "libcurl"; }
bool exec(){ bool exec(){
QString s; QString s;
s = conf->getenv("QC_WITH_LIBCOMMONCPP2_INC"); s = conf->getenv("QC_WITH_LIBCURL_INC");
if(!s.isEmpty()) { if(!s.isEmpty()) {
if(!conf->checkHeader(s, "cc++/url.h")) { if(!conf->checkHeader(s, "curl/curl.h")) {
return false; return false;
} }
}else{ }else{
@@ -520,7 +497,7 @@ public:
sl << "/usr/local/include"; sl << "/usr/local/include";
bool found = false; bool found = false;
foreach(s, sl){ foreach(s, sl){
if(conf->checkHeader(s, "cc++/url.h")){ if(conf->checkHeader(s, "curl/curl.h")){
found = true; found = true;
break; break;
} }
@@ -531,117 +508,27 @@ public:
} }
conf->addIncludePath(s); conf->addIncludePath(s);
s = conf->getenv("QC_WITH_LIBCOMMONCPP2_LIB"); s = conf->getenv("QC_WITH_LIBCURL_LIB");
if(!s.isEmpty()) { if(!s.isEmpty()) {
if(!QFile::exists(s+QString("libccext2.so"))) if(!QFile::exists(s+QString("/libcurl.so")))
return false; return false;
if(!QFile::exists(s+QString("libccgnu2.so")))
return false;
conf->addLib(QString("-L") + s); conf->addLib(QString("-L") + s);
}else{ }else{
QStringList sl; QStringList sl;
sl << "/usr/lib/"; sl << "/usr/lib/";
sl << "/usr/lib64/";
sl << "/usr/local/lib/"; sl << "/usr/local/lib/";
sl << "/usr/local/lib64/";
bool found = false; bool found = false;
foreach(s, sl){ foreach(s, sl){
if(QFile::exists(s+QString("libccext2.so"))){ if(QFile::exists(s+QString("libcurl.so"))){
if(QFile::exists(s+QString("libccgnu2.so"))){ found = true;
found = true; break;
break;
}
} }
} }
if(!found) return false; if(!found) return false;
conf->addLib(QString("-L") + s); conf->addLib(QString("-L") + s);
} }
// BUGFIX for Fedora (doesn't support pkg-config?)
QFile issue_file("/etc/issue");
if(issue_file.open(QIODevice::ReadOnly | QIODevice::Text)){
QString content = issue_file.readAll();
issue_file.close();
if(content.indexOf("Fedora") != -1){
qWarning("Fedora detected. WORKAROUND for Fedora pkg-config problem enabled");
conf->addLib("-pthread -lccext2 -lz -lccgnu2 -ldl -lrt");
}
}
return true;
}
};
#line 1 "libmagick.qcm"
/*
-----BEGIN QCMOD-----
name: libmagick
arg: with-libmagick-inc=[path], Path to libmagick++ include files
arg: with-libmagick-lib=[path], Path to libmagick++ library files
-----END QCMOD-----
*/
#include <QProcess>
class qc_libmagick : public ConfObj
{
public:
qc_libmagick(Conf *c) : ConfObj(c) {}
QString name() const { return "ImageMagick library (libmagick++)"; }
QString shortname() const { return "libmagick++"; }
QString checkString() const {
if(!conf->getenv("QC_DISABLE_libmagick").isEmpty())
return "";
return ConfObj::checkString();
}
bool exec(){
if(!conf->getenv("QC_DISABLE_libmagick").isEmpty())
return false;
QString s;
s = conf->getenv("QC_WITH_LIBMAGICK_INC");
if(!s.isEmpty()) {
if(!conf->checkHeader(s, "Magick++.h")) {
return false;
}
}else{
QStringList sl;
sl << "/usr/include";
sl << "/usr/local/include";
bool found = false;
foreach(s, sl){
if(conf->checkHeader(s, "Magick++.h")){
found = true;
break;
}
}
if(!found)
return false;
}
conf->addIncludePath(s);
s = conf->getenv("QC_WITH_LIBMAGICK_LIB");
if(!s.isEmpty()) {
if(!QFile::exists(s+QString("libMagick++.so"))){
return false;
}
}else{
QStringList sl;
sl << "/usr/lib/";
sl << "/usr/local/lib/";
bool found = false;
foreach(s, sl){
if(QFile::exists(s+QString("libMagick++.so"))){
found = true;
break;
}
}
if(!found)
return false;
}
conf->addLib(QString("-L") + s);
QProcess magickConfig;
QStringList params;
params << "--libs";
magickConfig.start("Magick++-config", params, QIODevice::ReadOnly);
magickConfig.waitForStarted();
magickConfig.waitForFinished();
QByteArray result = magickConfig.readAll();
result = result.replace("\n", "");
conf->addLib(result.data());
conf->addDefine("HAVE_MAGICK");
return true; return true;
} }
}; };
@@ -692,13 +579,15 @@ public:
s = conf->getenv("QC_WITH_LIBZZIP_LIB"); s = conf->getenv("QC_WITH_LIBZZIP_LIB");
if(!s.isEmpty()) { if(!s.isEmpty()) {
if(!QFile::exists(s+QString("libzzip.so"))){ if(!QFile::exists(s+QString("/libzzip.so"))){
return false; return false;
} }
}else{ }else{
QStringList sl; QStringList sl;
sl << "/usr/lib/"; sl << "/usr/lib/";
sl << "/usr/lib64/";
sl << "/usr/local/lib/"; sl << "/usr/local/lib/";
sl << "/usr/local/lib64/";
bool found = false; bool found = false;
foreach(s, sl){ foreach(s, sl){
if(QFile::exists(s+QString("libzzip.so"))){ if(QFile::exists(s+QString("libzzip.so"))){
@@ -715,50 +604,24 @@ public:
return true; return true;
} }
}; };
#line 1 "python.qcm"
/*
-----BEGIN QCMOD-----
name: python
-----END QCMOD-----
*/
class qc_python : public ConfObj
{
public:
qc_python(Conf *c) : ConfObj(c) {}
QString name() const { return "python >= 2.3"; }
QString shortname() const { return "python"; }
bool exec(){
int r = conf->doCommand("python testpython.py");
if(r == 0)
return true;
else
return false;
}
};
EOT EOT
cat >$1/modules_new.cpp <<EOT cat >$1/modules_new.cpp <<EOT
o = new qc_qt4(conf); o = new qc_qt4(conf);
o->required = true; o->required = true;
o->disabled = false; o->disabled = false;
o = new qc_libtorrent(conf); o = new qc_libtorrent_rasterbar(conf);
o->required = true; o->required = true;
o->disabled = false; o->disabled = false;
o = new qc_libboost(conf); o = new qc_libboost(conf);
o->required = true; o->required = true;
o->disabled = false; o->disabled = false;
o = new qc_libcommoncpp2(conf); o = new qc_libcurl(conf);
o->required = true; o->required = true;
o->disabled = false; o->disabled = false;
o = new qc_libmagick(conf);
o->required = false;
o->disabled = false;
o = new qc_libzzip(conf); o = new qc_libzzip(conf);
o->required = false; o->required = false;
o->disabled = false; o->disabled = false;
o = new qc_python(conf);
o->required = true;
o->disabled = false;
EOT EOT
cat >$1/conf4.h <<EOT cat >$1/conf4.h <<EOT
@@ -1708,11 +1571,8 @@ export QC_WITH_LIBTORRENT_INC
export QC_WITH_LIBTORRENT_LIB export QC_WITH_LIBTORRENT_LIB
export QC_WITH_LIBTORRENT_STATIC_LIB export QC_WITH_LIBTORRENT_STATIC_LIB
export QC_WITH_LIBBOOST_INC export QC_WITH_LIBBOOST_INC
export QC_WITH_LIBCOMMONCPP2_INC export QC_WITH_LIBCURL_INC
export QC_WITH_LIBCOMMONCPP2_LIB export QC_WITH_LIBCURL_LIB
export QC_DISABLE_libmagick
export QC_WITH_LIBMAGICK_INC
export QC_WITH_LIBMAGICK_LIB
export QC_DISABLE_libzzip export QC_DISABLE_libzzip
export QC_WITH_LIBZZIP_INC export QC_WITH_LIBZZIP_INC
export QC_WITH_LIBZZIP_LIB export QC_WITH_LIBZZIP_LIB

28
doc/qbittorrent.1 Normal file
View File

@@ -0,0 +1,28 @@
.\" This manpage has been automatically generated by docbook2man
.\" from a DocBook document. This tool can be found at:
.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>.
.TH "QBITTORRENT" "1" "September 1st 2007" "Bittorrent client written in C++ / Qt4" ""
.SH NAME
qBittorrent \- a Bittorrent client written in C++ / Qt4
.SH SYNOPSIS
\fBqbittorrent\fR [FILE | URL] [FILE | URL...]
\fBqbittorrent\fR \-\-help
\fBqbittorrent\fR \-\-version
.PP
.SH "DESCRIPTION"
\fBqBittorrent\fR is an advanced Bittorrent client written in C++ / Qt4,
using the \fBrblibtorrent\fR library by Arvid Norberg. qBittorrent aims
to be a good alternative to all other bittorrent clients out there. qBittorrent
is fast, stable, light, it supports unicode and it provides a good integrated search engine.
It also comes with UPnP port forwarding / NAT-PMP, encryption (Azureus compatible), FAST extension (mainline) and PeX support (utorrent compatible).
Please report any problem to http://bugs.qbittorrent.org
.PP
.SH "AUTHOR"
Christophe Dumez <chris@qbittorrent.org>

Binary file not shown.

View File

@@ -1,134 +0,0 @@
qbittorrent (0.6.1-1) unstable; urgency=low
* Disabled debug mode
-- Christophe Dumez <chris@qbittorrent.org> Mon, 28 Aug 2006 21:22:48 +0200
qbittorrent (0.6.1-0) unstable; urgency=low
* BUGFIX: Fixed possible segfaults when using context menus
* BUGFIX: Cleanup up context menus code
* BUGFIX: Used best gzip compressing for manpage
-- Christophe Dumez <chris@qbittorrent.org> Thu, 24 Aug 2006 19:53:32 +0200
qbittorrent (0.6.0) unstable; urgency=low
* FEATURE: Rewritten the download list from scratch (more flexible)
* FEATURE: Rewritten the search results list from scratch (more flexible)
* FEATURE: Rewritten the torrent properties list from scratch (more flexible)
* FEATURE: Improved and cleaned up search engine code
* FEATURE: Search results are now displayed in real time (not sequentially)
* FEATURE: Added two command lines parameters (--version, --help)
* FEATURE: Added a popup menu for download list
* FEATURE: Double-click on an item now toggles the paused state of a download
* FEATURE: Improved code to be more portable (Windows & MacOS versions should arrive soon)
* FEATURE: Allow to toggle selected state of a file within a torrent using double-click
* FEATURE: Remember columns width in download and search results lists
* BUGFIX: Don't use pkg-config for libcurl anymore (easier to compile)
* BUGFIX: Fixed ETA calculation when downloading while connecting
* BUGFIX: Download progress is now displayed correctly during first seconds of execution (was 0% before)
* BUGFIX: Code cleanup & optimization
* BUGFIX: Fixed sorting in download list
* BUGFIX: Fixed sorting in search results list
* BUGFIX: Fixed Parameters passing between instances
* BUGFIX: Fixed missing icon for clear action in infoBar popup menu
* BUGFIX: Fixed truncated lines in search results
* BUGFIX: Don't refresh download list when user is in search tab (save CPU)
* BUGFIX: Don't update Progress/DL Speed/ETA for finished downloads (save CPU)
* BUGFIX: Save selected search engines only when they have changed (faster program exit)
* COSMETIC: Increased icon size in toolbar from 24px to 32px
* COSMETIC: Display a progress bar to visualize each download progress
* COSMETIC: Size of each result in search are displayed in user friendly units
* COSMETIC: Display a progress bar to visualize each file progress within a torrent
* COSMETIC: Renamed 'ratio' to 'Session ratio' (makes more sense)
* COSMETIC: Improved layout of torrent properties window when maximized
* COSMETIC: Now number of search results is updated in real time
* COSMETIC: Remember last window size
* COSMETIC: Improved splash screen look
* COSMETIC: Improved default width of columns in download and search results lists
-- Christophe Dumez <chris@qbittorrent.org> Wed, 22 Aug 2006 10:42:37 +0200
qbittorrent (0.5.0) unstable; urgency=low
* Improved "Download from url" feature (now supports https, ftp & redirections)
* Added a torrent creation tool
* Display progress for each file within a torrent
* Based on new libtorrent v0.10 (lot of improvements)
* Now possible to clear log textbox (popup menu)
* Added two search engines (isohunt, torrentreactor)
* Now Display share ratio on main window
* Use OSD (On Screen Display) when a download or a search is finished
* Allow only one instance of qBittorrent (and add new parameters to download list)
* Remember last selected search engines in search tab
* Improved search engines status output (Aborted, timed out, finished, no results)
* qBittorrent can now update search plugin from qbittorrent.org
* Added Slovak, Italian, Portuguese, Romanian and Traditional Chinese languages
* Fixed ThePirateBay parser for search engine (website had changed)
* Fixed filenames for results from ThePirateBay search engine
* Fixed unicode support for ThePirateBay search engine
* Now search results are sorted by seeds
* Overwrite nova.py search plugin only if it is outdated
* Fixed possible division by 0 in ETA calculation
* Improved ETA calculation precision
* Fixed default tab in options
* When saving options, reconnect only when listening ports changed
* qBittorrent has now its own new logo
* Display status "downloading" if DL Speed > 0 (even when tracker is down)
* Added a splashscreen
* qBittorrent has new cute icons
* Display number of results in search tab
* Added icons for each item in download list according to its state
* Redesigned Locale settings
* Fixed search engines names width (were cut on the right)
* Moved search engines to the left of the window (better ui)
-- Christophe Dumez <chris@qbittorrent.org> Wed, 2 Aug 2006 19:46:32 +0200
qbittorrent (0.4.1) unstable; urgency=low
* Not counting "protocol chatter" in UP/DL speed anymore
* Download speed is now 0 when download is finished
* Paused torrents remain paused when qbittorrent is re-started
* Added option "go to systray when minimizing"
* Added option "Clear finished downloads on exit"
* Added option "Ask user for confirmation on exit"
* Added "Stalled" status for downloads (colored in orange, paused are in red and finished in green)
* Fixed Search window layout on maximizing
* Fixed a bug that caused upload limit not to be always applied
* Added Bulgarian translation
* Updated Translations
* Code optimization
-- Christophe Dumez <chris@qbittorrent.org> Thu, 22 Jun 2006 20:14:27 +0200
qbittorrent (0.4.0) unstable; urgency=low
* Added a search engine (supports Mininova & thepiratebay websites)
* Fixed critical bug: some options were not applied correctly to BT session
* Possibility to download a torrent file from an URL
* Added confirmation dialog on qbittorrent exit
* Enabled sorting in Download list
* Added Ukrainian translation
* Support urls as program parameters
* Added more actions to trayicon menu
* Fixed exception catching when retrieving fastresume data
* use Binary prefix standards from IEC 60027-2 for units (B, KiB, MiB, GiB, TiB)
* Iconification to systray when minimizing
* Code Cleanup & optimization
-- Christophe Dumez <chris@qbittorrent.org> Wed, 14 Jun 2006 14:47:27 +0200
qbittorrent (0.3.1) unstable; urgency=low
* Fixed toolbar layout (spacing).
* Added Russian translation.
* Resume also finished files on startup (for seeding).
* Added colors corresponding to download state.
* Fixed a segfault when deleting a download (if no scan dir is set).
-- Christophe Dumez <chris@qbittorrent.org> Sat, 6 Jun 2006 21:36:27 +0200
qbittorrent (0.3) unstable; urgency=low
* Initial Release.
-- Christophe Dumez <chris@qbittorrent.org> Sat, 3 Jun 2006 21:57:27 +0200

View File

@@ -1 +0,0 @@
4

View File

@@ -1,15 +0,0 @@
Source: qbittorrent
Section: net
Priority: optional
Maintainer: Christophe Dumez <chris@qbittorrent.org>
Build-Depends: debhelper (>= 4.0.0), autotools-dev, libqt4-core (>= 4.1.0), libqt4-dev (>= 4.1.0), libqt4-gui (>= 4.1.0), rb-libtorrent (>= 0.10), libcurl3-dev
Standards-Version: 3.6.2
Package: qbittorrent
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, rb-libtorrent (>= 0.10), python (>= 2.3)
Description: Bittorrent client in Qt4.1 / C++
qBittorrent is a bittorrent client programmed in C++ / Qt4.1
using rb_libtorrent by Arvid Norberg. It aims to be a good
alternative to other bittorrent client out there. It is fast,
stable and provides unicode support.

View File

@@ -1,26 +0,0 @@
This is qbittorrent, written and maintained by Christophe Dumez <chris@qbittorrent.org>
on Sat, 3 Jun 2006 21:57:27 +0200.
The original source can always be found at:
ftp://ftp.debian.org/dists/unstable/main/source/
Copyright (C) 2006 Christophe Dumez
License:
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this package; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
On Debian systems, the complete text of the GNU General
Public License can be found in `/usr/share/common-licenses/GPL'.

View File

@@ -1,2 +0,0 @@
usr/bin
usr/sbin

View File

@@ -1,3 +0,0 @@
NEWS
README
TODO

View File

@@ -1,107 +0,0 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# This file was originally written by Joey Hess and Craig Small.
# As a special exception, when this file is copied by dh-make into a
# dh-make output file, you may use that output file without restriction.
# This special exception was added by Craig Small in version 0.37 of dh-make.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
# These are used for cross-compiling and for saving the configure script
# from having to guess our platform (since we know it already)
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
CFLAGS = -Wall
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
CFLAGS += -O0
else
CFLAGS += -O2
endif
config.status: configure
dh_testdir
# Add here commands to configure the package.
CFLAGS="$(CFLAGS) -Wl,-z,defs" ./configure --prefix=/usr
build: build-stamp
build-stamp: config.status
dh_testdir
# Add here commands to compile the package.
$(MAKE)
#docbook-to-man debian/qbittorrent.sgml > qbittorrent.1
touch build-stamp
clean:
dh_testdir
dh_testroot
rm -f build-stamp
# Add here commands to clean up after the build process.
-$(MAKE) distclean
ifneq "$(wildcard /usr/share/misc/config.sub)" ""
cp -f /usr/share/misc/config.sub config.sub
endif
ifneq "$(wildcard /usr/share/misc/config.guess)" ""
cp -f /usr/share/misc/config.guess config.guess
endif
dh_clean
install: build
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
# Add here commands to install the package into debian/qbittorrent.
$(MAKE) install INSTALL_ROOT=$(CURDIR)/debian/qbittorrent
# Build architecture-independent files here.
binary-indep: build install
# We have nothing to do by default.
# Build architecture-dependent files here.
binary-arch: build install
dh_testdir
dh_testroot
dh_installchangelogs Changelog
dh_installdocs
dh_installexamples
# dh_install
# dh_installmenu
# dh_installdebconf
# dh_installlogrotate
# dh_installemacsen
# dh_installpam
# dh_installmime
# dh_installinit
# dh_installcron
# dh_installinfo
dh_installman
dh_link
dh_strip
dh_compress
dh_fixperms
# dh_perl
# dh_python
# dh_makeshlibs
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install

View File

@@ -1,249 +0,0 @@
%define name qbittorrent
%define major 0
%define minor 6
%define patch 1
%define version %{major}.%{minor}.%{patch}
%define release %mkrel 2
%define _iconsdir %{_datadir}/icons
%define _mandir %_datadir/man
Name: %{name}
Summary: A Bittorrent Client using C++ / Qt4
Version: %{version}
Release: %{release}
Source0: http://sourceforge.net/projects/qbittorrent/%{name}-%{version}.tar.gz
URL: http://sourceforge.net/projects/qbittorrent
Vendor: http://qbittorrent.sourceforge.net/
Group: Internet/File Transfer
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
License: GPL
BuildRequires: libqt4-devel >= 4.1.2, libqtgui4 >= 4.1.2, libqtcore4 >= 4.1.2, libqtxml4 >= 4.1.2, libqtnetwork4 >= 4.1.2, rb_libtorrent-devel >= 0.10-3, libcurl3-devel
Requires: libqtgui4 >= 4.1.2, libqtcore4 >= 4.1.2, libqtxml4 >= 4.1.2, libqtnetwork4 >= 4.1.2, librb_libtorrent0 >= 0.10-3, python >= 2.3, libcurl3
%description
A Bittorrent client using C++ / libtorrent and a Qt4 Graphical User Interface.
It aims to be as fast as possible and to provide multi-OS, unicode support.
%prep
%setup
%build
# Export the Environment variables
export QTDIR=%_prefix/%_lib/qt4
export KDEDIR=%_prefix
export LD_LIBRARY_PATH=$QTDIR/%_lib:$KDEDIR/%_lib:$LD_LIBRARY_PATH
export PATH=$QTDIR/bin:$KDEDIR/bin:$PATH
# Change to the Source directory and configure
#cd src
CFLAGS="%optflags" CXXFLAGS="%optflags" \
./configure --prefix=%{buildroot}%{_prefix}
# Necessary to remove old compiled files.. if they exist
make clean
%make
%install
%makeinstall --directory=src
# Create the menu directory
install -d %{buildroot}%{_menudir}
# Build the Menu
#<package> <section> <file_in> <file_out> [requires] [title]
kdedesktop2mdkmenu.pl %{name} "%{group}" %{buildroot}%{_datadir}/applications/qBittorrent.desktop %{buildroot}%{_menudir}/%{name}
%clean
%{__rm} -rf %{buildroot}
%post
/sbin/ldconfig
%{update_menus}
%postun
/sbin/ldconfig
%{clean_menus}
%files
%defattr(-,root,root)
%doc README INSTALL NEWS COPYING AUTHORS TODO Changelog
%doc %{_mandir}/man1/*.bz2
# The binaries
%_bindir/*
# Icon files
# Hi and Lo colour icons various sizes
%_iconsdir/hicolor/128x128/apps/qbittorrent.png
%_iconsdir/hicolor/16x16/apps/qbittorrent.png
%_iconsdir/hicolor/192x192/apps/qbittorrent.png
%_iconsdir/hicolor/22x22/apps/qbittorrent.png
%_iconsdir/hicolor/24x24/apps/qbittorrent.png
%_iconsdir/hicolor/32x32/apps/qbittorrent.png
%_iconsdir/hicolor/36x36/apps/qbittorrent.png
%_iconsdir/hicolor/48x48/apps/qbittorrent.png
%_iconsdir/hicolor/64x64/apps/qbittorrent.png
%_iconsdir/hicolor/72x72/apps/qbittorrent.png
%_iconsdir/hicolor/96x96/apps/qbittorrent.png
## %_iconsdir/hicolor/scalable/apps/qbittorrent.svgz
# Desktop Link
%_datadir/applications/qBittorrent.desktop
# The qbittorrent Menu directory
%dir %{_menudir}
%{_menudir}/%{name}
%changelog
* Wed Aug 23 2006 - Christophe Dumez <chris@qbittorrent.org> - 0.6.0-0.1.2006mdk
- FEATURE: Rewritten the download list from scratch (more flexible)
- FEATURE: Rewritten the search results list from scratch (more flexible)
- FEATURE: Rewritten the torrent properties list from scratch (more flexible)
- FEATURE: Improved and cleaned up search engine code
- FEATURE: Search results are now displayed in real time (not sequentially)
- FEATURE: Added two command lines parameters (--version, --help)
- FEATURE: Added a popup menu for download list
- FEATURE: Double-click on an item now toggles the paused state of a download
- FEATURE: Improved code to be more portable (Windows & MacOS versions should arrive soon)
- FEATURE: Allow to toggle selected state of a file within a torrent using double-click
- FEATURE: Remember columns width in download and search results lists
- BUGFIX: Don't use pkg-config for libcurl anymore (easier to compile)
- BUGFIX: Fixed ETA calculation when downloading while connecting
- BUGFIX: Download progress is now displayed correctly during first seconds of execution (was 0% before)
- BUGFIX: Code cleanup & optimization
- BUGFIX: Fixed sorting in download list
- BUGFIX: Fixed sorting in search results list
- BUGFIX: Fixed Parameters passing between instances
- BUGFIX: Fixed missing icon for clear action in infoBar popup menu
- BUGFIX: Fixed truncated lines in search results
- BUGFIX: Don't refresh download list when user is in search tab (save CPU)
- BUGFIX: Don't update Progress/DL Speed/ETA for finished downloads (save CPU)
- BUGFIX: Save selected search engines only when they have changed (faster program exit)
- COSMETIC: Increased icon size in toolbar from 24px to 32px
- COSMETIC: Display a progress bar to visualize each download progress
- COSMETIC: Size of each result in search are displayed in user friendly units
- COSMETIC: Display a progress bar to visualize each file progress within a torrent
- COSMETIC: Renamed 'ratio' to 'Session ratio' (makes more sense)
- COSMETIC: Improved layout of torrent properties window when maximized
- COSMETIC: Now number of search results is updated in real time
- COSMETIC: Remember last window size
- COSMETIC: Improved splash screen look
- COSMETIC: Improved default width of columns in download and search results lists
* Tue Aug 08 2006 - Christophe Dumez <chris@qbittorrent.org> - 0.5.0-0.1.20060mdk
- FEATURE: Improved "Download from url" feature (now supports https, ftp & redirections)
- FEATURE: Added a torrent creation tool
- FEATURE: Display progress for each file within a torrent
- FEATURE: Based on new libtorrent v0.10 (lot of improvements)
- FEATURE: Now possible to clear log textbox (popup menu)
- FEATURE: Added two search engines (isohunt, torrentreactor)
- FEATURE: Now Display share ratio on main window
- FEATURE: Use OSD (On Screen Display) when a download or a search is finished
- FEATURE: Allow only one instance of qBittorrent (and add new parameters to download list)
- FEATURE: Remember last selected search engines in search tab
- FEATURE: Improved search engines status output (Aborted, timed out, finished, no results)
- FEATURE: qBittorrent can now update search plugin from qbittorrent.org
- I18N: Added Slovak, Italian, Portuguese, Romanian and Traditional Chinese languages
- BUGFIX: Fixed ThePirateBay parser for search engine (website had changed)
- BUGFIX: Fixed filenames for results from ThePirateBay search engine
- BUGFIX: Fixed unicode support for ThePirateBay search engine
- BUGFIX: Now search results are sorted by seeds
- BUGFIX: Overwrite nova.py search plugin only if it is outdated
- BUGFIX: Fixed possible division by 0 in ETA calculation
- BUGFIX: Improved ETA calculation precision
- BUGFIX: Fixed default tab in options
- BUGFIX: When saving options, reconnect only when listening ports changed
- COSMETIC: qBittorrent has now its own new logo
- COSMETIC: Display status "downloading" if DL Speed > 0 (even when tracker is down)
- COSMETIC: Added a splashscreen
- COSMETIC: qBittorrent has new cute icons
- COSMETIC: Display number of results in search tab
- COSMETIC: Added icons for each item in download list according to its state
- COSMETIC: Redesigned Locale settings
- COSMETIC: Fixed search engines names width (were cut on the right)
- COSMETIC: Moved search engines to the left of the window (better ui)
* Fri Jun 23 2006 - Christophe Dumez <chris@qbittorrent.org> - 0.4.1-0.1.20060mdk
- Not counting "protocol chatter" in UP/DL speed anymore
- Download speed is now 0 when download is finished
- Paused torrents remain paused when qbittorrent is re-started
- Added option "go to systray when minimizing"
- Added option "Clear finished downloads on exit"
- Added option "Ask user for confirmation on exit"
- Added "Stalled" status for downloads (colored in orange, paused are in red and finished in green)
- Fixed Search window layout on maximizing
- Fixed a bug that caused upload limit not to be always applied
- Added Bulgarian translation
- Updated Translations
- Code optimization
* Tue Jun 13 2006 - Christophe Dumez <chris@qbittorrent.org> - 0.4.0-0.1.20060mdk
- Added a search engine (supports Mininova & thepiratebay websites)
- Fixed critical bug: some options were not applied correctly to BT session
- Possibility to download a torrent file from an URL
- Added confirmation dialog on qbittorrent exit
- Enabled sorting in Download list
- Added Ukrainian translation
- Support urls as program parameters
- Added more actions to trayicon menu
- Fixed exception catching when retrieving fastresume data
- use Binary prefix standards from IEC 60027-2 for units (B, KiB, MiB, GiB, TiB)
- Iconification to systray when minimizing
- Code Cleanup & optimization
* Tue Jun 06 2006 - Christophe Dumez <chris@qbittorrent.org> - 0.3.1-0.1.20060mdk
- Fixed toolbar layout (spacing)
- Added Russian translation
- Resume also finished files on startup (for seeding)
- Added colors corresponding to download state
- Fixed a segfault when deleting a download (if no scan dir is set)
* Mon Jun 05 2006 - Christophe Dumez <chris@qbittorrent.org> - 0.3-0.1.20060mdk
- Fixed auto-resume (worked only once)
- Fixed BT_Backup dir creation on first startup (thanks Peter)
- Now min port and max port are inverted if (min port > max port)
- Fixed memory leaks
- Added qbittorrent man page
- Allow to disable max connections limit (default is disabled)
- Disable upload limit by default
- Added Menu Entry with icon (thanks Peter)
- Restructured directory, now Makefile is in main directory (not src/)
- Updated README / INSTALL
* Fri Jun 02 2006 - Christophe Dumez <chris@qbittorrent.org> 0.2.3-0.1.20060mdk
- Fixed ports checking function (user couldn't type the value he wanted)
- Check tracker errors list size and clear it if it becomes too big.
- qBittorrent does not remove .torrent file from scanned directory anymore
- Small cosmetic change
* Wed May 31 2006 Christophe Dumez <chris@qbittorrent.org> 0.2.2-0.1.20060mdk
- Fixed missing icons
* Sat May 27 2006 Jeffery Fernandez <developer@jefferyfernandez.id.au> 0.2.1-0.1.20060mdk
- Initial Build for Mandriva Linux
* Thu May 25 2006 Christophe Dumez <chris@qbittorrent.org>
- Fixed "make install" rule
- Disabled debug mode
* Thu May 25 2006 Christophe Dumez <chris@qbittorrent.org> - v0.2
- Fixed a compatibility problem with some versions of qmake
- Added translations : Greek, Swedish
- Fixed Polish translation selection
- Fixed come warning because of two unexisting slots
- Improved "Apply" button behaviour in options
- Windows are now resizable
* Tue May 16 2006 Christophe Dumez <chris@qbittorrent.org> - v0.1
- Initial release (lack features & still need a lot of improvements)

View File

@@ -1,147 +0,0 @@
%define package_name rb_libtorrent
%define orig_name libtorrent
%define major 0
%define minor .10
%define patch .1
%define version %{major}%{minor}
%define candidate -rc1
%define lib_name %mklibname %{package_name} %{major}
%define release %mkrel 4
Summary : libtorrent is a C++ bittorrent library.
Name : %{package_name}
Version : %{version}
Release : %{release}
License : GPL
Group : Development/C++
Source0 : http://www.rasterbar.com/products/libtorrent/libtorrent-%{version}.tar.gz
URL : http://www.rasterbar.com
BuildRequires : boost >= 1.33.1
BuildRoot : %{_tmppath}/%{orig_name}-%{version}-%{release}-root
Patch0 : file_progress_arvid.patch.bz2
%description
libtorrent is a C++ library that aims to be a good alternative
to all the other bittorrent implementations around.
%package -n %{package_name}-devel
Group : Development/C++
Summary : Development files for %{package_name}
Conflicts : libtorrent7-devel
%description -n %{package_name}-devel
Development files for %{package_name}
%package -n %{lib_name}
Group : Development/C++
Summary : Library files for %{package_name}
Conflicts : libtorrent7
%description -n %{lib_name}
Library files for %{package_name}
%prep
%setup -n %{orig_name}-%{version}
%build
%configure --prefix=%{_prefix}
%make
%install
%makeinstall
# Create directories for the package
install -d %{buildroot}%{_includedir}/%{orig_name}
install -d %{buildroot}%{_libdir}/pkgconfig
%clean
rm -rf %{buildroot}
# The binaries
%files %(orig_name)
%defattr(0644, root, root, 0755)
%{_bindir}/*
# Documentation
%defattr(-, root, root)
%doc README AUTHORS INSTALL COPYING ChangeLog NEWS
%doc docs/*
# Devel Package
%files -n %{package_name}-devel
%defattr(-,root,root,-)
%dir %{_includedir}/%{orig_name}/
%dir %{_includedir}/%{orig_name}/asio/
%dir %{_includedir}/%{orig_name}/asio/detail/
%dir %{_includedir}/%{orig_name}/asio/impl/
%dir %{_includedir}/%{orig_name}/asio/ip/
%dir %{_includedir}/%{orig_name}/asio/ip/detail/
%dir %{_includedir}/%{orig_name}/asio/ssl/
%dir %{_includedir}/%{orig_name}/asio/ssl/detail/
%{_includedir}/%{orig_name}/*.hpp
%{_includedir}/%{orig_name}/asio/*.hpp
%{_includedir}/%{orig_name}/asio/detail/*.hpp
%{_includedir}/%{orig_name}/asio/impl/*.ipp
%{_includedir}/%{orig_name}/asio/ip/*.hpp
%{_includedir}/%{orig_name}/asio/ip/detail/*.hpp
%{_includedir}/%{orig_name}/asio/ssl/*.hpp
%{_includedir}/%{orig_name}/asio/ssl/detail/*.hpp
%{_libdir}/%{orig_name}.a
%{_libdir}/%{orig_name}.la
%{_libdir}/%{orig_name}.so
%{_libdir}/pkgconfig/libtorrent.pc
# Library Package
%files -n %{lib_name}
%defattr(-,root,root,-)
%_libdir/%{orig_name}.so.*
%changelog
* Wed Aug 23 2006 Christophe Dumez <chris@qbittorrent.org> 10.0.1-2006mdk
- Added patch for Torrent Properties crash fix
* Sat Jul 1 2006 %{packager} %{version}-%{release}
- fixed a bug where the requested number of peers in a tracker request could
be too big.
- fixed a bug where empty files were not created in full allocation mode.
- fixed a bug in storage that would, in rare cases, fail to do a
complete check.
- exposed more settings for tweaking parameters in the piece-picker,
downloader and uploader (http_settings replaced by session_settings).
- tweaked default settings to improve high bandwidth transfers.
- improved the piece picker performance and made it possible to download
popular pieces in sequence to improve disk performance.
- added the possibility to control upload and download limits per peer.
- fixed problem with re-requesting skipped pieces when peer was sending pieces
out of fifo-order.
- added support for http seeding (the GetRight protocol)
- renamed identifiers called 'id' in the public interface to support linking
with Objective.C++
- changed the extensions protocol to use the new one, which is also
implemented by uTorrent.
- factorized the peer_connection and added web_peer_connection which is
able to download from http-sources.
- converted the network code to use asio (resulted in slight api changes
dealing with network addresses).
- made libtorrent build in vc7 (patches from Allen Zhao)
- fixed bug caused when binding outgoing connections to a non-local interface.
- add_torrent() will now throw if called while the session object is
being closed.
- added the ability to limit the number of simultaneous half-open
TCP connections. Flags in peer_info has been added.
* Thu Jun 1 2006 %{packager} %{version}-%{release}
- Initial Build for Mandriva Linux

View File

@@ -1,134 +0,0 @@
qbittorrent (0.6.1-0ubuntu2) dapper; urgency=low
* Disabled debug mode
-- Christophe Dumez <chris@qbittorrent.org> Mon, 28 Aug 2006 19:29:17 +0000
qbittorrent (0.6.1-0ubuntu1) dapper; urgency=low
* BUGFIX: Fixed possible segfaults when using context menus
* BUGFIX: Cleanup up context menus code
* BUGFIX: Used best gzip compressing for manpage
-- Christophe Dumez <chris@qbittorrent.org> Thu, 24 Aug 2006 19:53:32 +0200
qbittorrent (0.6.0) dapper; urgency=low
* FEATURE: Rewritten the download list from scratch (more flexible)
* FEATURE: Rewritten the search results list from scratch (more flexible)
* FEATURE: Rewritten the torrent properties list from scratch (more flexible)
* FEATURE: Improved and cleaned up search engine code
* FEATURE: Search results are now displayed in real time (not sequentially)
* FEATURE: Added two command lines parameters (--version, --help)
* FEATURE: Added a popup menu for download list
* FEATURE: Double-click on an item now toggles the paused state of a download
* FEATURE: Improved code to be more portable (Windows & MacOS versions should arrive soon)
* FEATURE: Allow to toggle selected state of a file within a torrent using double-click
* FEATURE: Remember columns width in download and search results lists
* BUGFIX: Don't use pkg-config for libcurl anymore (easier to compile)
* BUGFIX: Fixed ETA calculation when downloading while connecting
* BUGFIX: Download progress is now displayed correctly during first seconds of execution (was 0% before)
* BUGFIX: Code cleanup & optimization
* BUGFIX: Fixed sorting in download list
* BUGFIX: Fixed sorting in search results list
* BUGFIX: Fixed Parameters passing between instances
* BUGFIX: Fixed missing icon for clear action in infoBar popup menu
* BUGFIX: Fixed truncated lines in search results
* BUGFIX: Don't refresh download list when user is in search tab (save CPU)
* BUGFIX: Don't update Progress/DL Speed/ETA for finished downloads (save CPU)
* BUGFIX: Save selected search engines only when they have changed (faster program exit)
* COSMETIC: Increased icon size in toolbar from 24px to 32px
* COSMETIC: Display a progress bar to visualize each download progress
* COSMETIC: Size of each result in search are displayed in user friendly units
* COSMETIC: Display a progress bar to visualize each file progress within a torrent
* COSMETIC: Renamed 'ratio' to 'Session ratio' (makes more sense)
* COSMETIC: Improved layout of torrent properties window when maximized
* COSMETIC: Now number of search results is updated in real time
* COSMETIC: Remember last window size
* COSMETIC: Improved splash screen look
* COSMETIC: Improved default width of columns in download and search results lists
-- Christophe Dumez <chris@qbittorrent.org> Wed, 22 Aug 2006 10:42:37 +0200
qbittorrent (0.5.0) dapper; urgency=low
* Improved "Download from url" feature (now supports https, ftp & redirections)
* Added a torrent creation tool
* Display progress for each file within a torrent
* Based on new libtorrent v0.10 (lot of improvements)
* Now possible to clear log textbox (popup menu)
* Added two search engines (isohunt, torrentreactor)
* Now Display share ratio on main window
* Use OSD (On Screen Display) when a download or a search is finished
* Allow only one instance of qBittorrent (and add new parameters to download list)
* Remember last selected search engines in search tab
* Improved search engines status output (Aborted, timed out, finished, no results)
* qBittorrent can now update search plugin from qbittorrent.org
* Added Slovak, Italian, Portuguese, Romanian and Traditional Chinese languages
* Fixed ThePirateBay parser for search engine (website had changed)
* Fixed filenames for results from ThePirateBay search engine
* Fixed unicode support for ThePirateBay search engine
* Now search results are sorted by seeds
* Overwrite nova.py search plugin only if it is outdated
* Fixed possible division by 0 in ETA calculation
* Improved ETA calculation precision
* Fixed default tab in options
* When saving options, reconnect only when listening ports changed
* qBittorrent has now its own new logo
* Display status "downloading" if DL Speed > 0 (even when tracker is down)
* Added a splashscreen
* qBittorrent has new cute icons
* Display number of results in search tab
* Added icons for each item in download list according to its state
* Redesigned Locale settings
* Fixed search engines names width (were cut on the right)
* Moved search engines to the left of the window (better ui)
-- Christophe Dumez <chris@qbittorrent.org> Wed, 2 Aug 2006 19:46:32 +0200
qbittorrent (0.4.1) dapper; urgency=low
* Not counting "protocol chatter" in UP/DL speed anymore
* Download speed is now 0 when download is finished
* Paused torrents remain paused when qbittorrent is re-started
* Added option "go to systray when minimizing"
* Added option "Clear finished downloads on exit"
* Added option "Ask user for confirmation on exit"
* Added "Stalled" status for downloads (colored in orange, paused are in red and finished in green)
* Fixed Search window layout on maximizing
* Fixed a bug that caused upload limit not to be always applied
* Added Bulgarian translation
* Updated Translations
* Code optimization
-- Christophe Dumez <chris@qbittorrent.org> Thu, 22 Jun 2006 20:14:27 +0200
qbittorrent (0.4.0) dapper; urgency=low
* Added a search engine (supports Mininova & thepiratebay websites)
* Fixed critical bug: some options were not applied correctly to BT session
* Possibility to download a torrent file from an URL
* Added confirmation dialog on qbittorrent exit
* Enabled sorting in Download list
* Added Ukrainian translation
* Support urls as program parameters
* Added more actions to trayicon menu
* Fixed exception catching when retrieving fastresume data
* use Binary prefix standards from IEC 60027-2 for units (B, KiB, MiB, GiB, TiB)
* Iconification to systray when minimizing
* Code Cleanup & optimization
-- Christophe Dumez <chris@qbittorrent.org> Wed, 14 Jun 2006 14:47:27 +0200
qbittorrent (0.3.1) dapper; urgency=low
* Fixed toolbar layout (spacing).
* Added Russian translation.
* Resume also finished files on startup (for seeding).
* Added colors corresponding to download state.
* Fixed a segfault when deleting a download (if no scan dir is set).
-- Christophe Dumez <chris@qbittorrent.org> Sat, 6 Jun 2006 21:36:27 +0200
qbittorrent (0.3) dapper; urgency=low
* Initial Release.
-- Christophe Dumez <chris@qbittorrent.org> Sat, 3 Jun 2006 21:57:27 +0200

View File

@@ -1 +0,0 @@
4

View File

@@ -1,15 +0,0 @@
Source: qbittorrent
Section: net
Priority: optional
Maintainer: Christophe Dumez <chris@qbittorrent.org>
Build-Depends: debhelper (>= 4.0.0), autotools-dev, libqt4-core (>= 4.1.0), libqt4-dev (>= 4.1.0), libqt4-gui (>= 4.1.0), rb-libtorrent (>= 0.10), libcurl3-dev
Standards-Version: 3.6.2
Package: qbittorrent
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, rb-libtorrent (>= 0.10), python (>= 2.3)
Description: Bittorrent client in Qt4.1 / C++
qBittorrent is a bittorrent client programmed in C++ / Qt4.1
using rb_libtorrent by Arvid Norberg. It aims to be a good
alternative to other bittorrent client out there. It is fast,
stable and provides unicode support.

View File

@@ -1,26 +0,0 @@
This is qbittorrent, written and maintained by Christophe Dumez <chris@qbittorrent.org>
on Sat, 3 Jun 2006 21:57:27 +0200.
The original source can always be found at:
ftp://ftp.debian.org/dists/unstable/main/source/
Copyright (C) 2006 Christophe Dumez
License:
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this package; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
On Debian systems, the complete text of the GNU General
Public License can be found in `/usr/share/common-licenses/GPL'.

View File

@@ -1,2 +0,0 @@
usr/bin
usr/sbin

View File

@@ -1,3 +0,0 @@
NEWS
README
TODO

View File

@@ -1 +0,0 @@
qbittorrent_0.6.1-0ubuntu2_i386.deb net optional

View File

@@ -1 +0,0 @@
shlibs:Depends=libboost-date-time1.33.1, libboost-filesystem1.33.1, libboost-thread1.33.1, libc6 (>= 2.3.4-1), libcurl3 (>= 7.15.0-1), libgcc1 (>= 1:4.0.2), libqt4-core (>= 4.1.2), libqt4-gui (>= 4.1.2), libstdc++6 (>= 4.0.2-4), libx11-6, libxext6, zlib1g (>= 1:1.2.1)

View File

@@ -1,107 +0,0 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# This file was originally written by Joey Hess and Craig Small.
# As a special exception, when this file is copied by dh-make into a
# dh-make output file, you may use that output file without restriction.
# This special exception was added by Craig Small in version 0.37 of dh-make.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
# These are used for cross-compiling and for saving the configure script
# from having to guess our platform (since we know it already)
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
CFLAGS = -Wall
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
CFLAGS += -O0
else
CFLAGS += -O2
endif
config.status: configure
dh_testdir
# Add here commands to configure the package.
CFLAGS="$(CFLAGS) -Wl,-z,defs" ./configure --prefix=/usr
build: build-stamp
build-stamp: config.status
dh_testdir
# Add here commands to compile the package.
$(MAKE)
#docbook-to-man debian/qbittorrent.sgml > qbittorrent.1
touch build-stamp
clean:
dh_testdir
dh_testroot
rm -f build-stamp
# Add here commands to clean up after the build process.
-$(MAKE) distclean
ifneq "$(wildcard /usr/share/misc/config.sub)" ""
cp -f /usr/share/misc/config.sub config.sub
endif
ifneq "$(wildcard /usr/share/misc/config.guess)" ""
cp -f /usr/share/misc/config.guess config.guess
endif
dh_clean
install: build
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
# Add here commands to install the package into debian/qbittorrent.
$(MAKE) install INSTALL_ROOT=$(CURDIR)/debian/qbittorrent
# Build architecture-independent files here.
binary-indep: build install
# We have nothing to do by default.
# Build architecture-dependent files here.
binary-arch: build install
dh_testdir
dh_testroot
dh_installchangelogs Changelog
dh_installdocs
dh_installexamples
# dh_install
# dh_installmenu
# dh_installdebconf
# dh_installlogrotate
# dh_installemacsen
# dh_installpam
# dh_installmime
# dh_installinit
# dh_installcron
# dh_installinfo
dh_installman
dh_link
dh_strip
dh_compress
dh_fixperms
# dh_perl
# dh_python
# dh_makeshlibs
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install

View File

@@ -1,134 +0,0 @@
qbittorrent (0.6.1-0ubuntu2) edgy; urgency=low
* Disabled debug mode
-- Christophe Dumez <chris@qbittorrent.org> Mon, 28 Aug 2006 21:22:48 +0200
qbittorrent (0.6.1-0ubuntu1) edgy; urgency=low
* BUGFIX: Fixed possible segfaults when using context menus
* BUGFIX: Cleanup up context menus code
* BUGFIX: Used best gzip compressing for manpage
-- Christophe Dumez <chris@qbittorrent.org> Thu, 24 Aug 2006 19:53:32 +0200
qbittorrent (0.6.0) edgy; urgency=low
* FEATURE: Rewritten the download list from scratch (more flexible)
* FEATURE: Rewritten the search results list from scratch (more flexible)
* FEATURE: Rewritten the torrent properties list from scratch (more flexible)
* FEATURE: Improved and cleaned up search engine code
* FEATURE: Search results are now displayed in real time (not sequentially)
* FEATURE: Added two command lines parameters (--version, --help)
* FEATURE: Added a popup menu for download list
* FEATURE: Double-click on an item now toggles the paused state of a download
* FEATURE: Improved code to be more portable (Windows & MacOS versions should arrive soon)
* FEATURE: Allow to toggle selected state of a file within a torrent using double-click
* FEATURE: Remember columns width in download and search results lists
* BUGFIX: Don't use pkg-config for libcurl anymore (easier to compile)
* BUGFIX: Fixed ETA calculation when downloading while connecting
* BUGFIX: Download progress is now displayed correctly during first seconds of execution (was 0% before)
* BUGFIX: Code cleanup & optimization
* BUGFIX: Fixed sorting in download list
* BUGFIX: Fixed sorting in search results list
* BUGFIX: Fixed Parameters passing between instances
* BUGFIX: Fixed missing icon for clear action in infoBar popup menu
* BUGFIX: Fixed truncated lines in search results
* BUGFIX: Don't refresh download list when user is in search tab (save CPU)
* BUGFIX: Don't update Progress/DL Speed/ETA for finished downloads (save CPU)
* BUGFIX: Save selected search engines only when they have changed (faster program exit)
* COSMETIC: Increased icon size in toolbar from 24px to 32px
* COSMETIC: Display a progress bar to visualize each download progress
* COSMETIC: Size of each result in search are displayed in user friendly units
* COSMETIC: Display a progress bar to visualize each file progress within a torrent
* COSMETIC: Renamed 'ratio' to 'Session ratio' (makes more sense)
* COSMETIC: Improved layout of torrent properties window when maximized
* COSMETIC: Now number of search results is updated in real time
* COSMETIC: Remember last window size
* COSMETIC: Improved splash screen look
* COSMETIC: Improved default width of columns in download and search results lists
-- Christophe Dumez <chris@qbittorrent.org> Wed, 22 Aug 2006 10:42:37 +0200
qbittorrent (0.5.0) edgy; urgency=low
* Improved "Download from url" feature (now supports https, ftp & redirections)
* Added a torrent creation tool
* Display progress for each file within a torrent
* Based on new libtorrent v0.10 (lot of improvements)
* Now possible to clear log textbox (popup menu)
* Added two search engines (isohunt, torrentreactor)
* Now Display share ratio on main window
* Use OSD (On Screen Display) when a download or a search is finished
* Allow only one instance of qBittorrent (and add new parameters to download list)
* Remember last selected search engines in search tab
* Improved search engines status output (Aborted, timed out, finished, no results)
* qBittorrent can now update search plugin from qbittorrent.org
* Added Slovak, Italian, Portuguese, Romanian and Traditional Chinese languages
* Fixed ThePirateBay parser for search engine (website had changed)
* Fixed filenames for results from ThePirateBay search engine
* Fixed unicode support for ThePirateBay search engine
* Now search results are sorted by seeds
* Overwrite nova.py search plugin only if it is outdated
* Fixed possible division by 0 in ETA calculation
* Improved ETA calculation precision
* Fixed default tab in options
* When saving options, reconnect only when listening ports changed
* qBittorrent has now its own new logo
* Display status "downloading" if DL Speed > 0 (even when tracker is down)
* Added a splashscreen
* qBittorrent has new cute icons
* Display number of results in search tab
* Added icons for each item in download list according to its state
* Redesigned Locale settings
* Fixed search engines names width (were cut on the right)
* Moved search engines to the left of the window (better ui)
-- Christophe Dumez <chris@qbittorrent.org> Wed, 2 Aug 2006 19:46:32 +0200
qbittorrent (0.4.1) edgy; urgency=low
* Not counting "protocol chatter" in UP/DL speed anymore
* Download speed is now 0 when download is finished
* Paused torrents remain paused when qbittorrent is re-started
* Added option "go to systray when minimizing"
* Added option "Clear finished downloads on exit"
* Added option "Ask user for confirmation on exit"
* Added "Stalled" status for downloads (colored in orange, paused are in red and finished in green)
* Fixed Search window layout on maximizing
* Fixed a bug that caused upload limit not to be always applied
* Added Bulgarian translation
* Updated Translations
* Code optimization
-- Christophe Dumez <chris@qbittorrent.org> Thu, 22 Jun 2006 20:14:27 +0200
qbittorrent (0.4.0) edgy; urgency=low
* Added a search engine (supports Mininova & thepiratebay websites)
* Fixed critical bug: some options were not applied correctly to BT session
* Possibility to download a torrent file from an URL
* Added confirmation dialog on qbittorrent exit
* Enabled sorting in Download list
* Added Ukrainian translation
* Support urls as program parameters
* Added more actions to trayicon menu
* Fixed exception catching when retrieving fastresume data
* use Binary prefix standards from IEC 60027-2 for units (B, KiB, MiB, GiB, TiB)
* Iconification to systray when minimizing
* Code Cleanup & optimization
-- Christophe Dumez <chris@qbittorrent.org> Wed, 14 Jun 2006 14:47:27 +0200
qbittorrent (0.3.1) edgy; urgency=low
* Fixed toolbar layout (spacing).
* Added Russian translation.
* Resume also finished files on startup (for seeding).
* Added colors corresponding to download state.
* Fixed a segfault when deleting a download (if no scan dir is set).
-- Christophe Dumez <chris@qbittorrent.org> Sat, 6 Jun 2006 21:36:27 +0200
qbittorrent (0.3) edgy; urgency=low
* Initial Release.
-- Christophe Dumez <chris@qbittorrent.org> Sat, 3 Jun 2006 21:57:27 +0200

View File

@@ -1 +0,0 @@
4

View File

@@ -1,15 +0,0 @@
Source: qbittorrent
Section: net
Priority: optional
Maintainer: Christophe Dumez <chris@qbittorrent.org>
Build-Depends: debhelper (>= 4.0.0), autotools-dev, libqt4-core (>= 4.1.0), libqt4-dev (>= 4.1.0), libqt4-gui (>= 4.1.0), rb-libtorrent (>= 0.10), libcurl3-dev
Standards-Version: 3.6.2
Package: qbittorrent
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, rb-libtorrent (>= 0.10), python (>= 2.3)
Description: Bittorrent client in Qt4.1 / C++
qBittorrent is a bittorrent client programmed in C++ / Qt4.1
using rb_libtorrent by Arvid Norberg. It aims to be a good
alternative to other bittorrent client out there. It is fast,
stable and provides unicode support.

View File

@@ -1,26 +0,0 @@
This is qbittorrent, written and maintained by Christophe Dumez <chris@qbittorrent.org>
on Sat, 3 Jun 2006 21:57:27 +0200.
The original source can always be found at:
ftp://ftp.debian.org/dists/unstable/main/source/
Copyright (C) 2006 Christophe Dumez
License:
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this package; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
On Debian systems, the complete text of the GNU General
Public License can be found in `/usr/share/common-licenses/GPL'.

View File

@@ -1,2 +0,0 @@
usr/bin
usr/sbin

View File

@@ -1,3 +0,0 @@
NEWS
README
TODO

View File

@@ -1 +0,0 @@
qbittorrent_0.6.1-0ubuntu2_i386.deb net optional

View File

@@ -1 +0,0 @@
shlibs:Depends=libboost-date-time1.33.1, libboost-filesystem1.33.1, libboost-thread1.33.1, libc6 (>= 2.4-1), libcurl3 (>= 7.15.4-1), libgcc1 (>= 1:4.1.1-11ubuntu1), libqt4-core (>= 4.1.4), libqt4-gui (>= 4.1.4), libstdc++6 (>= 4.1.1-11ubuntu1), libx11-6, libxext6, zlib1g (>= 1:1.2.1)

View File

@@ -1,107 +0,0 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# This file was originally written by Joey Hess and Craig Small.
# As a special exception, when this file is copied by dh-make into a
# dh-make output file, you may use that output file without restriction.
# This special exception was added by Craig Small in version 0.37 of dh-make.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
# These are used for cross-compiling and for saving the configure script
# from having to guess our platform (since we know it already)
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
CFLAGS = -Wall
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
CFLAGS += -O0
else
CFLAGS += -O2
endif
config.status: configure
dh_testdir
# Add here commands to configure the package.
CFLAGS="$(CFLAGS) -Wl,-z,defs" ./configure --prefix=/usr
build: build-stamp
build-stamp: config.status
dh_testdir
# Add here commands to compile the package.
$(MAKE)
#docbook-to-man debian/qbittorrent.sgml > qbittorrent.1
touch build-stamp
clean:
dh_testdir
dh_testroot
rm -f build-stamp
# Add here commands to clean up after the build process.
-$(MAKE) distclean
ifneq "$(wildcard /usr/share/misc/config.sub)" ""
cp -f /usr/share/misc/config.sub config.sub
endif
ifneq "$(wildcard /usr/share/misc/config.guess)" ""
cp -f /usr/share/misc/config.guess config.guess
endif
dh_clean
install: build
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
# Add here commands to install the package into debian/qbittorrent.
$(MAKE) install INSTALL_ROOT=$(CURDIR)/debian/qbittorrent
# Build architecture-independent files here.
binary-indep: build install
# We have nothing to do by default.
# Build architecture-dependent files here.
binary-arch: build install
dh_testdir
dh_testroot
dh_installchangelogs Changelog
dh_installdocs
dh_installexamples
# dh_install
# dh_installmenu
# dh_installdebconf
# dh_installlogrotate
# dh_installemacsen
# dh_installpam
# dh_installmime
# dh_installinit
# dh_installcron
# dh_installinfo
dh_installman
dh_link
dh_strip
dh_compress
dh_fixperms
# dh_perl
# dh_python
# dh_makeshlibs
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install

View File

@@ -94,13 +94,12 @@
<includestyle>4</includestyle> <includestyle>4</includestyle>
<designerintegration>ExternalDesigner</designerintegration> <designerintegration>ExternalDesigner</designerintegration>
<root>/usr/lib/qt4</root> <root>/usr/lib/qt4</root>
<qmake>/usr/bin/qmake-qt4</qmake> <qmake>/usr/bin/qmake</qmake>
<designer>/usr/bin/designer-qt4</designer> <designer>/usr/bin/designer</designer>
<designerpluginpaths/> <designerpluginpaths/>
</qt> </qt>
<references> <references>
<pcs>automatic_%2Fhome%2Fchris%2Fqbittorrent_svn%2Ftrunk</pcs> <pcs>automatic_%2Fhome%2Fishanarora%2Fprojects%2Fqbittorrent</pcs>
<pcs>Qt4</pcs>
</references> </references>
<codecompletion> <codecompletion>
<automaticCodeCompletion>true</automaticCodeCompletion> <automaticCodeCompletion>true</automaticCodeCompletion>
@@ -149,14 +148,14 @@
</kdevfilecreate> </kdevfilecreate>
<kdevtrollproject> <kdevtrollproject>
<general> <general>
<activedir></activedir> <activedir>src</activedir>
</general> </general>
<run> <run>
<directoryradio>executable</directoryradio> <directoryradio>executable</directoryradio>
<mainprogram>/home/chris/qbittorrent_svn/trunk/src/qbittorrent</mainprogram> <mainprogram>/home/ishanarora/projects/qbittorrent/src/qbittorrent</mainprogram>
<programargs/> <programargs/>
<globaldebugarguments/> <globaldebugarguments/>
<globalcwd>/home/chris/qbittorrent_svn/trunk</globalcwd> <globalcwd>/home/ishanarora/projects/qbittorrent</globalcwd>
<useglobalprogram>true</useglobalprogram> <useglobalprogram>true</useglobalprogram>
<terminal>false</terminal> <terminal>false</terminal>
<autocompile>true</autocompile> <autocompile>true</autocompile>
@@ -187,7 +186,7 @@
</cppsupportpart> </cppsupportpart>
<ctagspart> <ctagspart>
<customArguments/> <customArguments/>
<customTagfilePath>/home/chris/qbittorrent_svn/trunk/tags</customTagfilePath> <customTagfilePath>/home/ishanarora/projects/qbittorrent/tags</customTagfilePath>
<activeTagsFiles/> <activeTagsFiles/>
</ctagspart> </ctagspart>
<kdevdocumentation> <kdevdocumentation>

View File

@@ -6,18 +6,14 @@
<dep type='qt4'> <dep type='qt4'>
<required/> <required/>
</dep> </dep>
<dep type='libtorrent'> <dep type='libtorrent-rasterbar'>
<required/> <required/>
</dep> </dep>
<dep type='libboost'> <dep type='libboost'>
<required/> <required/>
</dep> </dep>
<dep type='libcommoncpp2'> <dep type='libcurl'>
<required/> <required/>
</dep> </dep>
<dep type='libmagick'/>
<dep type='libzzip'/> <dep type='libzzip'/>
<dep type='python'>
<required/>
</dep>
</qconf> </qconf>

View File

@@ -37,15 +37,17 @@ public:
s = conf->getenv("QC_WITH_LIBCOMMONCPP2_LIB"); s = conf->getenv("QC_WITH_LIBCOMMONCPP2_LIB");
if(!s.isEmpty()) { if(!s.isEmpty()) {
if(!QFile::exists(s+QString("libccext2.so"))) if(!QFile::exists(s+QString("/libccext2.so")))
return false; return false;
if(!QFile::exists(s+QString("libccgnu2.so"))) if(!QFile::exists(s+QString("/libccgnu2.so")))
return false; return false;
conf->addLib(QString("-L") + s); conf->addLib(QString("-L") + s);
}else{ }else{
QStringList sl; QStringList sl;
sl << "/usr/lib/"; sl << "/usr/lib/";
sl << "/usr/lib64/";
sl << "/usr/local/lib/"; sl << "/usr/local/lib/";
sl << "/usr/local/lib64/";
bool found = false; bool found = false;
foreach(s, sl){ foreach(s, sl){
if(QFile::exists(s+QString("libccext2.so"))){ if(QFile::exists(s+QString("libccext2.so"))){
@@ -58,16 +60,6 @@ public:
if(!found) return false; if(!found) return false;
conf->addLib(QString("-L") + s); conf->addLib(QString("-L") + s);
} }
// BUGFIX for Fedora (doesn't support pkg-config?)
QFile issue_file("/etc/issue");
if(issue_file.open(QIODevice::ReadOnly | QIODevice::Text)){
QString content = issue_file.readAll();
issue_file.close();
if(content.indexOf("Fedora") != -1){
qWarning("Fedora detected. WORKAROUND for Fedora pkg-config problem enabled");
conf->addLib("-pthread -lccext2 -lz -lccgnu2 -ldl -lrt");
}
}
return true; return true;
} }
}; };

61
qcm/libcurl.qcm Normal file
View File

@@ -0,0 +1,61 @@
/*
-----BEGIN QCMOD-----
name: libcommoncpp2
arg: with-libcurl-inc=[path], Path to libcurl include files
arg: with-libcurl-lib=[path], Path to libcurl library files
-----END QCMOD-----
*/
class qc_libcurl : public ConfObj
{
public:
qc_libcurl(Conf *c) : ConfObj(c) {}
QString name() const { return "libcurl"; }
QString shortname() const { return "libcurl"; }
bool exec(){
QString s;
s = conf->getenv("QC_WITH_LIBCURL_INC");
if(!s.isEmpty()) {
if(!conf->checkHeader(s, "curl/curl.h")) {
return false;
}
}else{
QStringList sl;
sl << "/usr/include";
sl << "/usr/local/include";
bool found = false;
foreach(s, sl){
if(conf->checkHeader(s, "curl/curl.h")){
found = true;
break;
}
}
if(!found) {
return false;
}
}
conf->addIncludePath(s);
s = conf->getenv("QC_WITH_LIBCURL_LIB");
if(!s.isEmpty()) {
if(!QFile::exists(s+QString("/libcurl.so")))
return false;
conf->addLib(QString("-L") + s);
}else{
QStringList sl;
sl << "/usr/lib/";
sl << "/usr/lib64/";
sl << "/usr/local/lib/";
sl << "/usr/local/lib64/";
bool found = false;
foreach(s, sl){
if(QFile::exists(s+QString("libcurl.so"))){
found = true;
break;
}
}
if(!found) return false;
conf->addLib(QString("-L") + s);
}
return true;
}
};

View File

@@ -44,18 +44,20 @@ public:
s = conf->getenv("QC_WITH_LIBMAGICK_LIB"); s = conf->getenv("QC_WITH_LIBMAGICK_LIB");
if(!s.isEmpty()) { if(!s.isEmpty()) {
if(!QFile::exists(s+QString("libMagick++.so"))){ if(!conf->checkLibrary(s, "Magick++")) {
return false; return false;
} }
}else{ }else{
QStringList sl; QStringList sl;
sl << "/usr/lib/"; sl << "/usr/lib/";
sl << "/usr/lib64/";
sl << "/usr/local/lib/"; sl << "/usr/local/lib/";
sl << "/usr/local/lib64/";
bool found = false; bool found = false;
foreach(s, sl){ foreach(s, sl){
if(QFile::exists(s+QString("libMagick++.so"))){ if(conf->checkLibrary(s, "Magick++")) {
found = true; found = true;
break; break;
} }
} }
if(!found) if(!found)

View File

@@ -0,0 +1,70 @@
/*
-----BEGIN QCMOD-----
name: libtorrent-rasterbar
arg: with-libtorrent-inc=[path], Path to libtorrent-rasterbar include files
arg: with-libtorrent-lib=[path], Path to libtorrent-rasterbar library files
arg: with-libtorrent-static-lib=[path], Path to libtorrent-rasterbar .a file
-----END QCMOD-----
*/
class qc_libtorrent_rasterbar : public ConfObj
{
public:
qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {}
QString name() const { return "libtorrent-rasterbar >= 0.14"; }
QString shortname() const { return "libtorrent-rasterbar"; }
bool exec(){
QString s;
s = conf->getenv("QC_WITH_LIBTORRENT_INC");
if(!s.isEmpty()) {
if(!conf->checkHeader(s, "libtorrent/magnet_uri.hpp")) {
return false;
}
}else{
QStringList sl;
sl << "/usr/include";
sl << "/usr/local/include";
bool found = false;
foreach(s, sl){
if(conf->checkHeader(s, "libtorrent/magnet_uri.hpp")){
found = true;
break;
}
}
if(!found) {
return false;
}
}
conf->addIncludePath(s);
conf->addIncludePath(s+QDir::separator()+"libtorrent");
s = conf->getenv("QC_WITH_LIBTORRENT_STATIC_LIB");
if(!s.isEmpty() && QFile::exists(s) && s.endsWith(".a")){
conf->addLib(s);
return true;
}
s = conf->getenv("QC_WITH_LIBTORRENT_LIB");
if(!s.isEmpty()) {
if(!conf->checkLibrary(s, "torrent-rasterbar")) {
return false;
}
conf->addLib(QString("-L") + s);
}else{
QStringList sl;
sl << "/usr/lib/";
sl << "/usr/lib64/";
sl << "/usr/local/lib/";
sl << "/usr/local/lib64/";
bool found = false;
foreach(s, sl){
if(conf->checkLibrary(s, "torrent-rasterbar")){
found = true;
break;
}
}
if(!found) return false;
conf->addLib(QString("-L") + s);
}
return true;
}
};

View File

@@ -1,78 +0,0 @@
/*
-----BEGIN QCMOD-----
name: libtorrent
arg: with-libtorrent-inc=[path], Path to libtorrent include files
arg: with-libtorrent-lib=[path], Path to libtorrent library files
arg: with-libtorrent-static-lib=[path], Path to libtorrent .a file
-----END QCMOD-----
*/
class qc_libtorrent : public ConfObj
{
public:
qc_libtorrent(Conf *c) : ConfObj(c) {}
QString name() const { return "libtorrent >= 0.13"; }
QString shortname() const { return "libtorrent"; }
bool exec(){
QString s;
s = conf->getenv("QC_WITH_LIBTORRENT_INC");
if(!s.isEmpty()) {
if(!conf->checkHeader(s, "libtorrent/lsd.hpp")) {
return false;
}
}else{
QStringList sl;
sl << "/usr/include";
sl << "/usr/local/include";
bool found = false;
foreach(s, sl){
if(conf->checkHeader(s, "libtorrent/lsd.hpp")){
found = true;
break;
}
}
if(!found) {
return false;
}
}
conf->addIncludePath(s);
conf->addIncludePath(s+QDir::separator()+"libtorrent");
s = conf->getenv("QC_WITH_LIBTORRENT_STATIC_LIB");
if(!s.isEmpty() && QFile::exists(s) && s.endsWith(".a")){
conf->addLib(s);
return true;
}
s = conf->getenv("QC_WITH_LIBTORRENT_LIB");
if(!s.isEmpty()) {
if(!conf->checkLibrary(s, "torrent")) {
return false;
}
conf->addLib(QString("-L") + s);
}else{
QStringList sl;
sl << "/usr/lib/";
sl << "/usr/local/lib/";
bool found = false;
foreach(s, sl){
if(conf->checkLibrary(s, "torrent")){
found = true;
break;
}
}
if(!found) return false;
conf->addLib(QString("-L") + s);
}
// BUGFIX for Fedora (doesn't support pkg-config?)
QFile issue_file("/etc/issue");
if(issue_file.open(QIODevice::ReadOnly | QIODevice::Text)){
QString content = issue_file.readAll();
issue_file.close();
if(content.indexOf("Fedora") != -1){
qWarning("Fedora detected. WORKAROUND for Fedora pkg-config problem enabled");
conf->addLib("-lssl -lcrypto -lboost_date_time -lboost_filesystem -lboost_thread -lz -ltorrent");
}
}
return true;
}
};

View File

@@ -44,13 +44,15 @@ public:
s = conf->getenv("QC_WITH_LIBZZIP_LIB"); s = conf->getenv("QC_WITH_LIBZZIP_LIB");
if(!s.isEmpty()) { if(!s.isEmpty()) {
if(!QFile::exists(s+QString("libzzip.so"))){ if(!QFile::exists(s+QString("/libzzip.so"))){
return false; return false;
} }
}else{ }else{
QStringList sl; QStringList sl;
sl << "/usr/lib/"; sl << "/usr/lib/";
sl << "/usr/lib64/";
sl << "/usr/local/lib/"; sl << "/usr/local/lib/";
sl << "/usr/local/lib64/";
bool found = false; bool found = false;
foreach(s, sl){ foreach(s, sl){
if(QFile::exists(s+QString("libzzip.so"))){ if(QFile::exists(s+QString("libzzip.so"))){

View File

@@ -1,19 +0,0 @@
/*
-----BEGIN QCMOD-----
name: python
-----END QCMOD-----
*/
class qc_python : public ConfObj
{
public:
qc_python(Conf *c) : ConfObj(c) {}
QString name() const { return "python >= 2.3"; }
QString shortname() const { return "python"; }
bool exec(){
int r = conf->doCommand("python testpython.py");
if(r == 0)
return true;
else
return false;
}
};

View File

@@ -11,6 +11,10 @@ public:
QString shortname() const { return "Qt 4.3"; } QString shortname() const { return "Qt 4.3"; }
bool exec() bool exec()
{ {
if(QT_VERSION >= 0x040400) {
conf->addDefine("QT_4_4");
}
return(QT_VERSION >= 0x040300); return(QT_VERSION >= 0x040300);
} }
}; };

View File

@@ -40,7 +40,8 @@
#define SEEDSLEECH 5 #define SEEDSLEECH 5
#define RATIO 6 #define RATIO 6
#define ETA 7 #define ETA 7
#define HASH 8 #define PRIORITY 8
#define HASH 9
class DLListDelegate: public QItemDelegate { class DLListDelegate: public QItemDelegate {
Q_OBJECT Q_OBJECT
@@ -83,12 +84,9 @@ class DLListDelegate: public QItemDelegate {
newopt.maximum = 100; newopt.maximum = 100;
newopt.minimum = 0; newopt.minimum = 0;
newopt.state |= QStyle::State_Enabled; newopt.state |= QStyle::State_Enabled;
newopt.textVisible = false; newopt.textVisible = true;
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt,
painter); painter);
QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
painter->setPen(opt.palette.color(cg, QPalette::WindowText));
painter->drawText(opt.rect, Qt::AlignCenter, newopt.text);
break; break;
} }
default: default:

View File

@@ -34,11 +34,10 @@
// Defines for download list list columns // Defines for download list list columns
#define F_NAME 0 #define F_NAME 0
#define F_SIZE 1 #define F_SIZE 1
#define F_PROGRESS 2 #define F_UPSPEED 2
#define F_UPSPEED 3 #define F_LEECH 3
#define F_SEEDSLEECH 4 #define F_RATIO 4
#define F_RATIO 5 #define F_HASH 5
#define F_HASH 6
class FinishedListDelegate: public QItemDelegate { class FinishedListDelegate: public QItemDelegate {
Q_OBJECT Q_OBJECT
@@ -67,23 +66,6 @@ class FinishedListDelegate: public QItemDelegate {
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString(QByteArray::number(ratio, 'f', 1))); QItemDelegate::drawDisplay(painter, opt, opt.rect, QString(QByteArray::number(ratio, 'f', 1)));
break; break;
} }
case F_PROGRESS:{
QStyleOptionProgressBarV2 newopt;
double progress = index.data().toDouble()*100.;
newopt.rect = opt.rect;
newopt.text = QString(QByteArray::number(progress, 'f', 1))+QString::fromUtf8("%");
newopt.progress = (int)progress;
newopt.maximum = 100;
newopt.minimum = 0;
newopt.state |= QStyle::State_Enabled;
newopt.textVisible = false;
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt,
painter);
QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
painter->setPen(opt.palette.color(cg, QPalette::WindowText));
painter->drawText(opt.rect, Qt::AlignCenter, newopt.text);
break;
}
default: default:
QItemDelegate::paint(painter, option, index); QItemDelegate::paint(painter, option, index);
} }

View File

@@ -31,21 +31,21 @@
#include <QStandardItemModel> #include <QStandardItemModel>
#include <QHeaderView> #include <QHeaderView>
#include <QMenu> #include <QMenu>
#include <QMessageBox>
FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : parent(parent), BTSession(BTSession), nbFinished(0){ FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : parent(parent), BTSession(BTSession), nbFinished(0){
setupUi(this); setupUi(this);
actionStart->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/play.png"))); actionStart->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/play.png")));
actionPause->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/pause.png"))); actionPause->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/pause.png")));
connect(BTSession, SIGNAL(addedTorrent(QString, QTorrentHandle&, bool)), this, SLOT(torrentAdded(QString, QTorrentHandle&, bool))); finishedListModel = new QStandardItemModel(0,6);
finishedListModel = new QStandardItemModel(0,7);
finishedListModel->setHeaderData(F_NAME, Qt::Horizontal, tr("Name", "i.e: file name")); finishedListModel->setHeaderData(F_NAME, Qt::Horizontal, tr("Name", "i.e: file name"));
finishedListModel->setHeaderData(F_SIZE, Qt::Horizontal, tr("Size", "i.e: file size")); finishedListModel->setHeaderData(F_SIZE, Qt::Horizontal, tr("Size", "i.e: file size"));
finishedListModel->setHeaderData(F_PROGRESS, Qt::Horizontal, tr("Progress", "i.e: % downloaded"));
finishedListModel->setHeaderData(F_UPSPEED, Qt::Horizontal, tr("UP Speed", "i.e: Upload speed")); finishedListModel->setHeaderData(F_UPSPEED, Qt::Horizontal, tr("UP Speed", "i.e: Upload speed"));
finishedListModel->setHeaderData(F_SEEDSLEECH, Qt::Horizontal, tr("Seeds/Leechs", "i.e: full/partial sources")); finishedListModel->setHeaderData(F_LEECH, Qt::Horizontal, tr("Leechers", "i.e: full/partial sources"));
finishedListModel->setHeaderData(F_RATIO, Qt::Horizontal, tr("Ratio")); finishedListModel->setHeaderData(F_RATIO, Qt::Horizontal, tr("Ratio"));
finishedList->setModel(finishedListModel); finishedList->setModel(finishedListModel);
// Hide ETA & hash column loadHiddenColumns();
// Hide hash column
finishedList->hideColumn(F_HASH); finishedList->hideColumn(F_HASH);
// Load last columns width for download list // Load last columns width for download list
if(!loadColWidthFinishedList()){ if(!loadColWidthFinishedList()){
@@ -54,10 +54,12 @@ FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : par
// Make download list header clickable for sorting // Make download list header clickable for sorting
finishedList->header()->setClickable(true); finishedList->header()->setClickable(true);
finishedList->header()->setSortIndicatorShown(true); finishedList->header()->setSortIndicatorShown(true);
connect(finishedList->header(), SIGNAL(sectionPressed(int)), this, SLOT(sortFinishedList(int))); connect(finishedList->header(), SIGNAL(sectionPressed(int)), this, SLOT(toggleFinishedListSortOrder(int)));
finishedListDelegate = new FinishedListDelegate(finishedList); finishedListDelegate = new FinishedListDelegate(finishedList);
finishedList->setItemDelegate(finishedListDelegate); finishedList->setItemDelegate(finishedListDelegate);
connect(finishedList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFinishedListMenu(const QPoint&))); connect(finishedList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFinishedListMenu(const QPoint&)));
finishedList->header()->setContextMenuPolicy(Qt::CustomContextMenu);
connect(finishedList->header(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFinishedHoSMenu(const QPoint&)));
connect(finishedList, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(notifyTorrentDoubleClicked(const QModelIndex&))); connect(finishedList, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(notifyTorrentDoubleClicked(const QModelIndex&)));
actionDelete->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete.png"))); actionDelete->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete.png")));
actionPreview_file->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/preview.png"))); actionPreview_file->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/preview.png")));
@@ -69,11 +71,21 @@ FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : par
connect(actionDelete, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_triggered())); connect(actionDelete, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_triggered()));
connect(actionPreview_file, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPreview_file_triggered())); connect(actionPreview_file, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPreview_file_triggered()));
connect(actionDelete_Permanently, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_Permanently_triggered())); connect(actionDelete_Permanently, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_Permanently_triggered()));
connect(actionOpen_destination_folder, SIGNAL(triggered()), (GUI*)parent, SLOT(openDestinationFolder()));
connect(actionBuy_it, SIGNAL(triggered()), (GUI*)parent, SLOT(goBuyPage()));
connect(actionTorrent_Properties, SIGNAL(triggered()), this, SLOT(propertiesSelection())); connect(actionTorrent_Properties, SIGNAL(triggered()), this, SLOT(propertiesSelection()));
connect(actionForce_recheck, SIGNAL(triggered()), this, SLOT(forceRecheck()));
connect(actionHOSColName, SIGNAL(triggered()), this, SLOT(hideOrShowColumnName()));
connect(actionHOSColSize, SIGNAL(triggered()), this, SLOT(hideOrShowColumnSize()));
connect(actionHOSColUpSpeed, SIGNAL(triggered()), this, SLOT(hideOrShowColumnUpSpeed()));
connect(actionHOSColLeechers, SIGNAL(triggered()), this, SLOT(hideOrShowColumnLeechers()));
connect(actionHOSColRatio, SIGNAL(triggered()), this, SLOT(hideOrShowColumnRatio()));
} }
FinishedTorrents::~FinishedTorrents(){ FinishedTorrents::~FinishedTorrents(){
saveColWidthFinishedList(); saveColWidthFinishedList();
saveHiddenColumns();
delete finishedListDelegate; delete finishedListDelegate;
delete finishedListModel; delete finishedListModel;
} }
@@ -81,13 +93,10 @@ FinishedTorrents::~FinishedTorrents(){
void FinishedTorrents::notifyTorrentDoubleClicked(const QModelIndex& index) { void FinishedTorrents::notifyTorrentDoubleClicked(const QModelIndex& index) {
unsigned int row = index.row(); unsigned int row = index.row();
QString hash = getHashFromRow(row); QString hash = getHashFromRow(row);
emit torrentDoubleClicked(hash); emit torrentDoubleClicked(hash, true);
} }
void FinishedTorrents::addTorrent(QString hash){ void FinishedTorrents::addTorrent(QString hash){
if(!BTSession->isFinished(hash)){
BTSession->setFinishedTorrent(hash);
}
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
if(row != -1) return; if(row != -1) return;
row = finishedListModel->rowCount(); row = finishedListModel->rowCount();
@@ -97,10 +106,9 @@ void FinishedTorrents::addTorrent(QString hash){
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(h.name())); finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(h.name()));
finishedListModel->setData(finishedListModel->index(row, F_SIZE), QVariant((qlonglong)h.actual_size())); finishedListModel->setData(finishedListModel->index(row, F_SIZE), QVariant((qlonglong)h.actual_size()));
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)0.)); finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)0.));
finishedListModel->setData(finishedListModel->index(row, F_SEEDSLEECH), QVariant("0/0")); finishedListModel->setData(finishedListModel->index(row, F_LEECH), QVariant("0"));
finishedListModel->setData(finishedListModel->index(row, F_RATIO), QVariant(QString::fromUtf8(misc::toString(BTSession->getRealRatio(hash)).c_str()))); finishedListModel->setData(finishedListModel->index(row, F_RATIO), QVariant(QString::fromUtf8(misc::toString(BTSession->getRealRatio(hash)).c_str())));
finishedListModel->setData(finishedListModel->index(row, F_HASH), QVariant(hash)); finishedListModel->setData(finishedListModel->index(row, F_HASH), QVariant(hash));
finishedListModel->setData(finishedListModel->index(row, F_PROGRESS), QVariant((double)1.));
if(h.is_paused()) { if(h.is_paused()) {
finishedListModel->setData(finishedListModel->index(row, F_NAME), QIcon(":/Icons/skin/paused.png"), Qt::DecorationRole); finishedListModel->setData(finishedListModel->index(row, F_NAME), QIcon(":/Icons/skin/paused.png"), Qt::DecorationRole);
setRowColor(row, "red"); setRowColor(row, "red");
@@ -111,13 +119,8 @@ void FinishedTorrents::addTorrent(QString hash){
// Update the number of finished torrents // Update the number of finished torrents
++nbFinished; ++nbFinished;
emit finishedTorrentsNumberChanged(nbFinished); emit finishedTorrentsNumberChanged(nbFinished);
} // Sort List
sortFinishedList();
void FinishedTorrents::torrentAdded(QString, QTorrentHandle& h, bool) {
QString hash = h.hash();
if(BTSession->isFinished(hash)) {
addTorrent(hash);
}
} }
// Set the color of a row in data model // Set the color of a row in data model
@@ -156,27 +159,60 @@ bool FinishedTorrents::loadColWidthFinishedList(){
if(line.isEmpty()) if(line.isEmpty())
return false; return false;
QStringList width_list = line.split(' '); QStringList width_list = line.split(' ');
if(width_list.size() != finishedListModel->columnCount()-1) if(width_list.size() < finishedListModel->columnCount()-1)
return false; return false;
unsigned int listSize = width_list.size(); unsigned int listSize = width_list.size();
for(unsigned int i=0; i<listSize; ++i){ for(unsigned int i=0; i<listSize; ++i){
finishedList->header()->resizeSection(i, width_list.at(i).toInt()); finishedList->header()->resizeSection(i, width_list.at(i).toInt());
} }
loadLastSortedColumn();
qDebug("Finished list columns width loaded"); qDebug("Finished list columns width loaded");
return true; return true;
} }
void FinishedTorrents::loadLastSortedColumn() {
// Loading last sorted column
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QString sortedCol = settings.value(QString::fromUtf8("FinishedListSortedCol"), QString()).toString();
if(!sortedCol.isEmpty()) {
Qt::SortOrder sortOrder;
if(sortedCol.endsWith(QString::fromUtf8("d")))
sortOrder = Qt::DescendingOrder;
else
sortOrder = Qt::AscendingOrder;
sortedCol = sortedCol.left(sortedCol.size()-1);
int index = sortedCol.toInt();
sortFinishedList(index, sortOrder);
}
}
// Save columns width in a file to remember them // Save columns width in a file to remember them
// (finished list) // (finished list)
void FinishedTorrents::saveColWidthFinishedList() const{ void FinishedTorrents::saveColWidthFinishedList() const{
qDebug("Saving columns width in finished list"); qDebug("Saving columns width in finished list");
QSettings settings("qBittorrent", "qBittorrent"); QSettings settings("qBittorrent", "qBittorrent");
QStringList width_list; QStringList width_list;
unsigned int nbColumns = finishedListModel->columnCount()-1; QStringList new_width_list;
for(unsigned int i=0; i<nbColumns; ++i){ short nbColumns = finishedListModel->columnCount()-1;
width_list << QString::fromUtf8(misc::toString(finishedList->columnWidth(i)).c_str());
QString line = settings.value("FinishedListColsWidth", QString()).toString();
if(!line.isEmpty()) {
width_list = line.split(' ');
} }
settings.setValue("FinishedListColsWidth", width_list.join(" ")); for(short i=0; i<nbColumns; ++i){
if(finishedList->columnWidth(i)<1 && width_list.size() == finishedListModel->columnCount()-1 && width_list.at(i).toInt()>=1) {
// load the former width
new_width_list << width_list.at(i);
} else if(finishedList->columnWidth(i)>=1) {
// usual case, save the current width
new_width_list << QString::fromUtf8(misc::toString(finishedList->columnWidth(i)).c_str());
} else {
// default width
finishedList->resizeColumnToContents(i);
new_width_list << QString::fromUtf8(misc::toString(finishedList->columnWidth(i)).c_str());
}
}
settings.setValue("FinishedListColsWidth", new_width_list.join(" "));
qDebug("Finished list columns width saved"); qDebug("Finished list columns width saved");
} }
@@ -193,15 +229,8 @@ void FinishedTorrents::on_actionSet_upload_limit_triggered(){
new BandwidthAllocationDialog(this, true, BTSession, hashes); new BandwidthAllocationDialog(this, true, BTSession, hashes);
} }
void FinishedTorrents::updateFinishedList(){ void FinishedTorrents::updateTorrent(QTorrentHandle h) {
QString hash; QString hash = h.hash();
QStringList finishedSHAs = BTSession->getFinishedTorrents();
foreach(hash, finishedSHAs){
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(!h.is_valid()){
qDebug("Problem: This torrent is not valid in finished list");
continue;
}
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
if(row == -1){ if(row == -1){
qDebug("Cannot find torrent in finished list, adding it"); qDebug("Cannot find torrent in finished list, adding it");
@@ -209,32 +238,36 @@ void FinishedTorrents::updateFinishedList(){
row = getRowFromHash(hash); row = getRowFromHash(hash);
} }
Q_ASSERT(row != -1); Q_ASSERT(row != -1);
if(h.is_paused()) continue; if(h.is_paused()) return;
if(BTSession->getTorrentsToPauseAfterChecking().indexOf(hash) != -1) { // Update queued torrent
finishedListModel->setData(finishedListModel->index(row, F_PROGRESS), QVariant((double)h.progress())); if(BTSession->isQueueingEnabled() && h.is_queued()) {
continue; if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking){
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole);
} else {
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/queued.png"))), Qt::DecorationRole);
}
// Reset upload speed and seeds/leech
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), 0.);
finishedListModel->setData(finishedListModel->index(row, F_LEECH), "0");
setRowColor(row, QString::fromUtf8("grey"));
return;
} }
if(h.state() == torrent_status::downloading || (h.state() != torrent_status::checking_files && h.state() != torrent_status::queued_for_checking && h.progress() < 1.)) { if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking){
// What are you doing here? go back to download tab!
qDebug("Info: a torrent was moved from finished to download tab");
deleteTorrent(hash);
BTSession->setFinishedTorrent(hash);
emit torrentMovedFromFinishedList(hash);
continue;
}
if(h.state() == torrent_status::checking_files){
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole); finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey")); setRowColor(row, QString::fromUtf8("grey"));
finishedListModel->setData(finishedListModel->index(row, F_PROGRESS), QVariant((double)h.progress())); return;
continue;
} }
setRowColor(row, QString::fromUtf8("orange")); setRowColor(row, QString::fromUtf8("orange"));
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png"))), Qt::DecorationRole); finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png"))), Qt::DecorationRole);
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)h.upload_payload_rate())); if(!finishedList->isColumnHidden(F_UPSPEED)) {
finishedListModel->setData(finishedListModel->index(row, F_SEEDSLEECH), QVariant(misc::toQString(h.num_seeds(), true)+"/"+misc::toQString(h.num_peers() - h.num_seeds(), true))); finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)h.upload_payload_rate()));
finishedListModel->setData(finishedListModel->index(row, F_RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash)))); }
finishedListModel->setData(finishedListModel->index(row, F_PROGRESS), QVariant((double)1.)); if(!finishedList->isColumnHidden(F_LEECH)) {
} finishedListModel->setData(finishedListModel->index(row, F_LEECH), misc::toQString(h.num_peers() - h.num_seeds(), true));
}
if(!finishedList->isColumnHidden(F_RATIO)) {
finishedListModel->setData(finishedListModel->index(row, F_RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash))));
}
} }
int FinishedTorrents::getRowFromHash(QString hash) const{ int FinishedTorrents::getRowFromHash(QString hash) const{
@@ -250,20 +283,14 @@ int FinishedTorrents::getRowFromHash(QString hash) const{
// Note: does not actually pause the torrent in BT Session // Note: does not actually pause the torrent in BT Session
void FinishedTorrents::pauseTorrent(QString hash) { void FinishedTorrents::pauseTorrent(QString hash) {
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
Q_ASSERT(row != -1); if(row == -1)
return;
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)0.0)); finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)0.0));
finishedListModel->setData(finishedListModel->index(row, F_NAME), QIcon(QString::fromUtf8(":/Icons/skin/paused.png")), Qt::DecorationRole); finishedListModel->setData(finishedListModel->index(row, F_NAME), QIcon(QString::fromUtf8(":/Icons/skin/paused.png")), Qt::DecorationRole);
finishedListModel->setData(finishedListModel->index(row, F_SEEDSLEECH), QVariant(QString::fromUtf8("0/0"))); finishedListModel->setData(finishedListModel->index(row, F_LEECH), QVariant(QString::fromUtf8("0")));
setRowColor(row, QString::fromUtf8("red")); setRowColor(row, QString::fromUtf8("red"));
} }
void FinishedTorrents::resumeTorrent(QString hash) {
int row = getRowFromHash(hash);
Q_ASSERT(row != -1);
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("orange"));
}
QString FinishedTorrents::getHashFromRow(unsigned int row) const { QString FinishedTorrents::getHashFromRow(unsigned int row) const {
Q_ASSERT(row < (unsigned int)finishedListModel->rowCount()); Q_ASSERT(row < (unsigned int)finishedListModel->rowCount());
return finishedListModel->data(finishedListModel->index(row, F_HASH)).toString(); return finishedListModel->data(finishedListModel->index(row, F_HASH)).toString();
@@ -283,11 +310,14 @@ void FinishedTorrents::deleteTorrent(QString hash){
// Show torrent properties dialog // Show torrent properties dialog
void FinishedTorrents::showProperties(const QModelIndex &index){ void FinishedTorrents::showProperties(const QModelIndex &index){
int row = index.row(); showPropertiesFromHash(finishedListModel->data(finishedListModel->index(index.row(), F_HASH)).toString());
QString hash = finishedListModel->data(finishedListModel->index(row, F_HASH)).toString(); }
void FinishedTorrents::showPropertiesFromHash(QString hash){
QTorrentHandle h = BTSession->getTorrentHandle(hash); QTorrentHandle h = BTSession->getTorrentHandle(hash);
properties *prop = new properties(this, BTSession, h); properties *prop = new properties(this, BTSession, h);
connect(prop, SIGNAL(filteredFilesChanged(QString)), this, SLOT(updateFileSize(QString))); connect(prop, SIGNAL(filteredFilesChanged(QString)), this, SLOT(updateFileSize(QString)));
connect(prop, SIGNAL(trackersChanged(QString)), BTSession, SLOT(saveTrackerFile(QString)));
prop->show(); prop->show();
} }
@@ -308,13 +338,23 @@ void FinishedTorrents::propertiesSelection(){
} }
} }
void FinishedTorrents::forceRecheck(){
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
QModelIndex index;
foreach(index, selectedIndexes){
if(index.column() == F_NAME){
QString hash = finishedListModel->data(finishedListModel->index(index.row(), F_HASH)).toString();
QTorrentHandle h = BTSession->getTorrentHandle(hash);
h.force_recheck();
}
}
}
void FinishedTorrents::displayFinishedListMenu(const QPoint& pos){ void FinishedTorrents::displayFinishedListMenu(const QPoint& pos){
QMenu myFinishedListMenu(this); QMenu myFinishedListMenu(this);
QModelIndex index; QModelIndex index;
// Enable/disable pause/start action given the DL state // Enable/disable pause/start action given the DL state
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes(); QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
QSettings settings("qBittorrent", "qBittorrent");
QString previewProgram = settings.value("Preferences/general/MediaPlayer", QString()).toString();
bool has_pause = false, has_start = false, has_preview = false; bool has_pause = false, has_start = false, has_preview = false;
foreach(index, selectedIndexes) { foreach(index, selectedIndexes) {
if(index.column() == F_NAME) { if(index.column() == F_NAME) {
@@ -334,7 +374,7 @@ void FinishedTorrents::displayFinishedListMenu(const QPoint& pos){
has_pause = true; has_pause = true;
} }
} }
if(!previewProgram.isEmpty() && BTSession->isFilePreviewPossible(hash) && !has_preview) { if(BTSession->isFilePreviewPossible(hash) && !has_preview) {
myFinishedListMenu.addAction(actionPreview_file); myFinishedListMenu.addAction(actionPreview_file);
has_preview = true; has_preview = true;
} }
@@ -347,30 +387,190 @@ void FinishedTorrents::displayFinishedListMenu(const QPoint& pos){
myFinishedListMenu.addSeparator(); myFinishedListMenu.addSeparator();
myFinishedListMenu.addAction(actionSet_upload_limit); myFinishedListMenu.addAction(actionSet_upload_limit);
myFinishedListMenu.addSeparator(); myFinishedListMenu.addSeparator();
myFinishedListMenu.addAction(actionForce_recheck);
myFinishedListMenu.addSeparator();
myFinishedListMenu.addAction(actionOpen_destination_folder);
myFinishedListMenu.addAction(actionTorrent_Properties); myFinishedListMenu.addAction(actionTorrent_Properties);
myFinishedListMenu.addSeparator();
myFinishedListMenu.addAction(actionBuy_it);
// Call menu // Call menu
// XXX: why mapToGlobal() is not enough? // XXX: why mapToGlobal() is not enough?
myFinishedListMenu.exec(mapToGlobal(pos)+QPoint(10,55)); myFinishedListMenu.exec(mapToGlobal(pos)+QPoint(10,58));
} }
/*
* Hiding Columns functions
*/
// hide/show columns menu
void FinishedTorrents::displayFinishedHoSMenu(const QPoint& pos){
QMenu hideshowColumn(this);
hideshowColumn.setTitle(tr("Hide or Show Column"));
int lastCol = F_RATIO;
for(int i=0; i<=lastCol; i++) {
hideshowColumn.addAction(getActionHoSCol(i));
}
// Call menu
hideshowColumn.exec(mapToGlobal(pos)+QPoint(10,34));
}
// toggle hide/show a column
void FinishedTorrents::hideOrShowColumn(int index) {
unsigned int nbVisibleColumns = 0;
unsigned int nbCols = finishedListModel->columnCount();
// Count visible columns
for(unsigned int i=0; i<nbCols; ++i) {
if(!finishedList->isColumnHidden(i))
++nbVisibleColumns;
}
if(!finishedList->isColumnHidden(index)) {
// User wants to hide the column
// Is there at least one other visible column?
if(nbVisibleColumns <= 1) return;
// User can hide the column, do it.
finishedList->setColumnHidden(index, true);
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
--nbVisibleColumns;
} else {
// User want to display the column
finishedList->setColumnHidden(index, false);
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
++nbVisibleColumns;
}
//resize all others non-hidden columns
for(unsigned int i=0; i<nbCols; ++i) {
if(!finishedList->isColumnHidden(i)) {
finishedList->setColumnWidth(i, (int)ceil(finishedList->columnWidth(i)+(finishedList->columnWidth(index)/nbVisibleColumns)));
}
}
}
void FinishedTorrents::hideOrShowColumnName() {
hideOrShowColumn(F_NAME);
}
void FinishedTorrents::hideOrShowColumnSize() {
hideOrShowColumn(F_SIZE);
}
void FinishedTorrents::hideOrShowColumnUpSpeed() {
hideOrShowColumn(F_UPSPEED);
}
void FinishedTorrents::hideOrShowColumnLeechers() {
hideOrShowColumn(F_LEECH);
}
void FinishedTorrents::hideOrShowColumnRatio() {
hideOrShowColumn(F_RATIO);
}
// load the previous settings, and hide the columns
bool FinishedTorrents::loadHiddenColumns() {
bool loaded = false;
QSettings settings("qBittorrent", "qBittorrent");
QString line = settings.value("FinishedListColsHoS", QString()).toString();
QStringList ishidden_list;
if(!line.isEmpty()) {
ishidden_list = line.split(' ');
if(ishidden_list.size() == finishedListModel->columnCount()-1) {
unsigned int listSize = ishidden_list.size();
for(unsigned int i=0; i<listSize; ++i){
finishedList->header()->resizeSection(i, ishidden_list.at(i).toInt());
}
loaded = true;
}
}
for(int i=0; i<finishedListModel->columnCount()-1; i++) {
if(loaded && ishidden_list.at(i) == "0") {
finishedList->setColumnHidden(i, true);
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
} else {
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
}
}
return loaded;
}
// save the hidden columns in settings
void FinishedTorrents::saveHiddenColumns() {
QSettings settings("qBittorrent", "qBittorrent");
QStringList ishidden_list;
short nbColumns = finishedListModel->columnCount()-1;
for(short i=0; i<nbColumns; ++i){
if(finishedList->isColumnHidden(i)) {
ishidden_list << QString::fromUtf8(misc::toString(0).c_str());
} else {
ishidden_list << QString::fromUtf8(misc::toString(1).c_str());
}
}
settings.setValue("FinishedListColsHoS", ishidden_list.join(" "));
}
// getter, return the action hide or show whose id is index
QAction* FinishedTorrents::getActionHoSCol(int index) {
switch(index) {
case F_NAME :
return actionHOSColName;
break;
case F_SIZE :
return actionHOSColSize;
break;
case F_UPSPEED :
return actionHOSColUpSpeed;
break;
case F_LEECH :
return actionHOSColLeechers;
break;
case F_RATIO :
return actionHOSColRatio;
break;
default :
return NULL;
}
}
/* /*
* Sorting functions * Sorting functions
*/ */
void FinishedTorrents::sortFinishedList(int index){ void FinishedTorrents::toggleFinishedListSortOrder(int index) {
static Qt::SortOrder sortOrder = Qt::AscendingOrder; Qt::SortOrder sortOrder = Qt::AscendingOrder;
if(finishedList->header()->sortIndicatorSection() == index){ if(finishedList->header()->sortIndicatorSection() == index){
if(sortOrder == Qt::AscendingOrder){ sortOrder = (Qt::SortOrder)!(bool)finishedList->header()->sortIndicatorOrder();
sortOrder = Qt::DescendingOrder;
}else{
sortOrder = Qt::AscendingOrder;
}
} }
finishedList->header()->setSortIndicator(index, sortOrder); switch(index) {
switch(index){ case F_SIZE:
case F_UPSPEED:
case F_RATIO:
sortFinishedListFloat(index, sortOrder);
break;
default:
sortFinishedListString(index, sortOrder);
}
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QString sortOrderLetter;
if(sortOrder == Qt::AscendingOrder)
sortOrderLetter = QString::fromUtf8("a");
else
sortOrderLetter = QString::fromUtf8("d");
settings.setValue(QString::fromUtf8("FinishedListSortedCol"), misc::toQString(index)+sortOrderLetter);
}
void FinishedTorrents::sortFinishedList(int index, Qt::SortOrder sortOrder){
if(index == -1) {
index = finishedList->header()->sortIndicatorSection();
sortOrder = finishedList->header()->sortIndicatorOrder();
} else {
finishedList->header()->setSortIndicator(index, sortOrder);
}
switch(index) {
case F_SIZE: case F_SIZE:
case F_UPSPEED: case F_UPSPEED:
case F_PROGRESS:
sortFinishedListFloat(index, sortOrder); sortFinishedListFloat(index, sortOrder);
break; break;
default: default:

View File

@@ -39,6 +39,10 @@ class FinishedTorrents : public QWidget, public Ui::seeding {
FinishedListDelegate *finishedListDelegate; FinishedListDelegate *finishedListDelegate;
QStandardItemModel *finishedListModel; QStandardItemModel *finishedListModel;
unsigned int nbFinished; unsigned int nbFinished;
void hideOrShowColumn(int index);
bool loadHiddenColumns();
void saveHiddenColumns();
QAction* getActionHoSCol(int index);
public: public:
FinishedTorrents(QObject *parent, bittorrent *BTSession); FinishedTorrents(QObject *parent, bittorrent *BTSession);
@@ -53,27 +57,35 @@ class FinishedTorrents : public QWidget, public Ui::seeding {
protected slots: protected slots:
void showProperties(const QModelIndex &index); void showProperties(const QModelIndex &index);
void displayFinishedListMenu(const QPoint&); void displayFinishedListMenu(const QPoint&);
void displayFinishedHoSMenu(const QPoint&);
void setRowColor(int row, QString color); void setRowColor(int row, QString color);
void saveColWidthFinishedList() const; void saveColWidthFinishedList() const;
void sortFinishedList(int index); void toggleFinishedListSortOrder(int index);
void sortFinishedList(int index=-1, Qt::SortOrder sortOrder=Qt::AscendingOrder);
void sortFinishedListFloat(int index, Qt::SortOrder sortOrder); void sortFinishedListFloat(int index, Qt::SortOrder sortOrder);
void sortFinishedListString(int index, Qt::SortOrder sortOrder); void sortFinishedListString(int index, Qt::SortOrder sortOrder);
void updateFileSize(QString hash); void updateFileSize(QString hash);
void torrentAdded(QString path, QTorrentHandle& h, bool fastResume);
void on_actionSet_upload_limit_triggered(); void on_actionSet_upload_limit_triggered();
void notifyTorrentDoubleClicked(const QModelIndex& index); void notifyTorrentDoubleClicked(const QModelIndex& index);
void hideOrShowColumnName();
void hideOrShowColumnSize();
void hideOrShowColumnUpSpeed();
void hideOrShowColumnLeechers();
void hideOrShowColumnRatio();
void forceRecheck();
public slots: public slots:
void addTorrent(QString hash); void addTorrent(QString hash);
void updateFinishedList(); void updateTorrent(QTorrentHandle h);
void pauseTorrent(QString hash); void pauseTorrent(QString hash);
void resumeTorrent(QString hash);
void propertiesSelection(); void propertiesSelection();
void deleteTorrent(QString hash); void deleteTorrent(QString hash);
void showPropertiesFromHash(QString hash);
void loadLastSortedColumn();
signals: signals:
void torrentMovedFromFinishedList(QString); void torrentMovedFromFinishedList(QString);
void torrentDoubleClicked(QString hash); void torrentDoubleClicked(QString hash, bool finished);
void finishedTorrentsNumberChanged(unsigned int); void finishedTorrentsNumberChanged(unsigned int);
}; };

File diff suppressed because it is too large Load Diff

View File

@@ -24,7 +24,7 @@
#include <QProcess> #include <QProcess>
#include <QSystemTrayIcon> #include <QSystemTrayIcon>
#include <QPointer>
#include "ui_MainWindow.h" #include "ui_MainWindow.h"
#include "qtorrenthandle.h" #include "qtorrenthandle.h"
@@ -35,8 +35,13 @@ class DownloadingTorrents;
class FinishedTorrents; class FinishedTorrents;
class downloadFromURL; class downloadFromURL;
class SearchEngine; class SearchEngine;
class QTcpServer; #ifdef QT_4_4
class QTcpSocket; class QLocalServer;
class QLocalSocket;
#else
class QTcpServer;
class QTcpSocket;
#endif
class QCloseEvent; class QCloseEvent;
class RSSImp; class RSSImp;
class QShortcut; class QShortcut;
@@ -46,6 +51,8 @@ class options_imp;
class QTabWidget; class QTabWidget;
class QLabel; class QLabel;
class QModelIndex; class QModelIndex;
class HttpServer;
class QFrame;
class GUI : public QMainWindow, private Ui::MainWindow{ class GUI : public QMainWindow, private Ui::MainWindow{
Q_OBJECT Q_OBJECT
@@ -57,8 +64,9 @@ class GUI : public QMainWindow, private Ui::MainWindow{
QList<QPair<QTorrentHandle,QString> > unauthenticated_trackers; QList<QPair<QTorrentHandle,QString> > unauthenticated_trackers;
// GUI related // GUI related
QTabWidget *tabs; QTabWidget *tabs;
options_imp *options; QPointer<options_imp> options;
QSystemTrayIcon *myTrayIcon; QSystemTrayIcon *myTrayIcon;
QPointer<QTimer> systrayCreator;
QMenu *myTrayIconMenu; QMenu *myTrayIconMenu;
DownloadingTorrents *downloadingTorrentTab; DownloadingTorrents *downloadingTorrentTab;
FinishedTorrents *finishedTorrentTab; FinishedTorrents *finishedTorrentTab;
@@ -68,21 +76,36 @@ class GUI : public QMainWindow, private Ui::MainWindow{
bool force_exit; bool force_exit;
unsigned int refreshInterval; unsigned int refreshInterval;
QTimer *refresher; QTimer *refresher;
QLabel *dlSpeedLbl;
QLabel *upSpeedLbl;
QLabel *ratioLbl;
QLabel *DHTLbl;
QFrame *statusSep1;
QFrame *statusSep2;
QFrame *statusSep3;
QFrame *statusSep4;
// Keyboard shortcuts // Keyboard shortcuts
QShortcut *switchSearchShortcut; QShortcut *switchSearchShortcut;
QShortcut *switchSearchShortcut2; QShortcut *switchSearchShortcut2;
QShortcut *switchDownShortcut; QShortcut *switchDownShortcut;
QShortcut *switchUpShortcut; QShortcut *switchUpShortcut;
QShortcut *switchRSSShortcut; QShortcut *switchRSSShortcut;
// Preview QAction *prioSeparator;
QProcess *previewProcess; QAction *prioSeparator2;
// Search // Search
SearchEngine *searchEngine; SearchEngine *searchEngine;
// RSS // RSS
RSSImp *rssWidget; RSSImp *rssWidget;
// Web UI
QPointer<HttpServer> httpServer;
// Misc // Misc
QTcpServer *tcpServer; #ifdef QT_4_4
QLocalServer *localServer;
QLocalSocket *clientConnection;
#else
QTcpServer *localServer;
QTcpSocket *clientConnection; QTcpSocket *clientConnection;
#endif
protected slots: protected slots:
// GUI related slots // GUI related slots
@@ -93,12 +116,13 @@ class GUI : public QMainWindow, private Ui::MainWindow{
void on_actionCreate_torrent_triggered(); void on_actionCreate_torrent_triggered();
void on_actionWebsite_triggered() const; void on_actionWebsite_triggered() const;
void on_actionBugReport_triggered() const; void on_actionBugReport_triggered() const;
void on_actionShow_console_triggered();
void readParamsOnSocket(); void readParamsOnSocket();
void acceptConnection(); void acceptConnection();
void togglePausedState(QString hash); void togglePausedState(QString hash);
void torrentDoubleClicked(QString hash, bool finished);
void on_actionPreview_file_triggered(); void on_actionPreview_file_triggered();
void previewFile(QString filePath); void previewFile(QString filePath);
void cleanTempPreviewFile(int, QProcess::ExitStatus) const;
void balloonClicked(); void balloonClicked();
void writeSettings(); void writeSettings();
void readSettings(); void readSettings();
@@ -108,6 +132,7 @@ class GUI : public QMainWindow, private Ui::MainWindow{
void updateFinishedTorrentNumber(unsigned int nb); void updateFinishedTorrentNumber(unsigned int nb);
void fullDiskError(QTorrentHandle& h) const; void fullDiskError(QTorrentHandle& h) const;
void handleDownloadFromUrlFailure(QString, QString) const; void handleDownloadFromUrlFailure(QString, QString) const;
void createSystrayDelayed();
// Keyboard shortcuts // Keyboard shortcuts
void createKeyboardShortcuts(); void createKeyboardShortcuts();
void displayDownTab() const; void displayDownTab() const;
@@ -131,16 +156,21 @@ class GUI : public QMainWindow, private Ui::MainWindow{
void processParams(const QStringList& params); void processParams(const QStringList& params);
void addTorrent(QString path); void addTorrent(QString path);
void addUnauthenticatedTracker(QPair<QTorrentHandle,QString> tracker); void addUnauthenticatedTracker(QPair<QTorrentHandle,QString> tracker);
void processScannedFiles(const QStringList& params);
void processDownloadedFiles(QString path, QString url); void processDownloadedFiles(QString path, QString url);
void downloadFromURLList(const QStringList& urls); void downloadFromURLList(const QStringList& urls);
void deleteTorrent(QString hash, QString fileName, bool finished); void deleteTorrent(QString hash);
void finishedTorrent(QTorrentHandle& h) const; void finishedTorrent(QTorrentHandle& h) const;
void torrentChecked(QString hash) const; void addedTorrent(QTorrentHandle& h) const;
void updateLists(); void checkedTorrent(QTorrentHandle& h) const;
void pausedTorrent(QTorrentHandle& h) const;
void resumedTorrent(QTorrentHandle& h) const;
void updateLists(bool force=false);
bool initWebUi(QString username, QString password, int port);
void on_actionIncreasePriority_triggered();
void on_actionDecreasePriority_triggered();
// Options slots // Options slots
void on_actionOptions_triggered(); void on_actionOptions_triggered();
void OptionsSaved(QString info, bool deleteOptions); void OptionsSaved(bool deleteOptions);
// HTTP slots // HTTP slots
void on_actionDownload_from_URL_triggered(); void on_actionDownload_from_URL_triggered();
@@ -148,17 +178,22 @@ class GUI : public QMainWindow, private Ui::MainWindow{
public slots: public slots:
void trackerAuthenticationRequired(QTorrentHandle& h); void trackerAuthenticationRequired(QTorrentHandle& h);
void setTabText(int index, QString text) const; void setTabText(int index, QString text) const;
void openDestinationFolder() const;
void goBuyPage() const;
void updateRatio();
protected: protected:
void closeEvent(QCloseEvent *); void closeEvent(QCloseEvent *);
void hideEvent(QHideEvent *); void showEvent(QShowEvent *);
bool event(QEvent * event);
void displayRSSTab(bool enable);
public: public:
// Construct / Destruct // Construct / Destruct
GUI(QWidget *parent=0, QStringList torrentCmdLine=QStringList()); GUI(QWidget *parent=0, QStringList torrentCmdLine=QStringList());
~GUI(); ~GUI();
// Methods // Methods
unsigned int getCurrentTabIndex() const; int getCurrentTabIndex() const;
QPoint screenCenter() const; QPoint screenCenter() const;
}; };

BIN
src/Icons/edit_clear.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 575 B

BIN
src/Icons/flags/czech.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

BIN
src/Icons/flags/taiwan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/Icons/money.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 813 B

View File

@@ -1,14 +1,14 @@
[Desktop Entry] [Desktop Entry]
Categories=Qt;Application;Network;P2P Categories=Qt;Network;P2P
Comment=V1.0.0 Comment=V1.3.0
Encoding=UTF-8 Exec=qbittorrent %f
Exec=qbittorrent
GenericName=Bittorrent client GenericName=Bittorrent client
GenericName[bg]=Торент клиент GenericName[bg]=Торент клиент
GenericName[de]=Bittorren Client GenericName[de]=Bittorren Client
GenericName[el]=Τορεντ πελάτης GenericName[el]=Τορεντ πελάτης
GenericName[es]=Cliente Bittorrent GenericName[es]=Cliente Bittorrent
GenericName[fr]=Client Bittorrent GenericName[fr]=Client Bittorrent
GenericName[it]=Client Bittorrent
GenericName[ja]=Bittorrent クライアント GenericName[ja]=Bittorrent クライアント
GenericName[ko]=비토렌트 클라이언트 GenericName[ko]=비토렌트 클라이언트
GenericName[nl]=Bittorrent client GenericName[nl]=Bittorrent client
@@ -19,7 +19,7 @@ GenericName[tr]=Bittorrent istemcisi
GenericName[uk]=Bittorrent-клієнт GenericName[uk]=Bittorrent-клієнт
GenericName[zh]=Bittorrent之用户 GenericName[zh]=Bittorrent之用户
Icon=qbittorrent Icon=qbittorrent
MimeType=application/x-bittorrent MimeType=application/x-bittorrent;
Name=qBittorrent Name=qBittorrent
Name[ko]=큐비토런트 Name[ko]=큐비토런트
Terminal=false Terminal=false

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 576 B

BIN
src/Icons/skin/decrease.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
src/Icons/skin/increase.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
src/Icons/skin/queued.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 493 B

BIN
src/Icons/skin/tabs.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -5,7 +5,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>849</width> <width>914</width>
<height>563</height> <height>563</height>
</rect> </rect>
</property> </property>
@@ -16,22 +16,15 @@
<string/> <string/>
</property> </property>
<widget class="QWidget" name="centralwidget" > <widget class="QWidget" name="centralwidget" >
<layout class="QVBoxLayout" > <layout class="QVBoxLayout" />
<property name="spacing" >
<number>6</number>
</property>
<property name="margin" >
<number>9</number>
</property>
</layout>
</widget> </widget>
<widget class="QMenuBar" name="menubar" > <widget class="QMenuBar" name="menubar" >
<property name="geometry" > <property name="geometry" >
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>849</width> <width>914</width>
<height>29</height> <height>26</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menu_Edit" > <widget class="QMenu" name="menu_Edit" >
@@ -48,6 +41,8 @@
<addaction name="separator" /> <addaction name="separator" />
<addaction name="actionDelete" /> <addaction name="actionDelete" />
<addaction name="actionDelete_Permanently" /> <addaction name="actionDelete_Permanently" />
<addaction name="actionDecreasePriority" />
<addaction name="actionIncreasePriority" />
</widget> </widget>
<widget class="QMenu" name="menu_Help" > <widget class="QMenu" name="menu_Help" >
<property name="title" > <property name="title" >
@@ -63,6 +58,7 @@
<string>Options</string> <string>Options</string>
</property> </property>
<addaction name="actionOptions" /> <addaction name="actionOptions" />
<addaction name="actionShow_console" />
</widget> </widget>
<widget class="QMenu" name="menu_File" > <widget class="QMenu" name="menu_File" >
<property name="title" > <property name="title" >
@@ -97,8 +93,11 @@
<height>32</height> <height>32</height>
</size> </size>
</property> </property>
<property name="floatable" >
<bool>false</bool>
</property>
<attribute name="toolBarArea" > <attribute name="toolBarArea" >
<number>4</number> <enum>TopToolBarArea</enum>
</attribute> </attribute>
<attribute name="toolBarBreak" > <attribute name="toolBarBreak" >
<bool>false</bool> <bool>false</bool>
@@ -118,9 +117,13 @@
<addaction name="actionPause_All" /> <addaction name="actionPause_All" />
<addaction name="separator" /> <addaction name="separator" />
<addaction name="actionOptions" /> <addaction name="actionOptions" />
<addaction name="actionDecreasePriority" />
<addaction name="actionIncreasePriority" />
<addaction name="separator" />
<addaction name="actionExit" /> <addaction name="actionExit" />
<addaction name="separator" /> <addaction name="separator" />
</widget> </widget>
<widget class="QStatusBar" name="statusBar" />
<action name="actionOpen" > <action name="actionOpen" >
<property name="text" > <property name="text" >
<string>Open</string> <string>Open</string>
@@ -231,7 +234,39 @@
<string>Set global upload limit</string> <string>Set global upload limit</string>
</property> </property>
</action> </action>
<action name="actionDecreasePriority" >
<property name="icon" >
<iconset resource="icons.qrc" >:/Icons/skin/decrease.png</iconset>
</property>
<property name="text" >
<string>Decrease priority</string>
</property>
<property name="visible" >
<bool>false</bool>
</property>
</action>
<action name="actionIncreasePriority" >
<property name="icon" >
<iconset resource="icons.qrc" >:/Icons/skin/increase.png</iconset>
</property>
<property name="text" >
<string>Increase priority</string>
</property>
<property name="visible" >
<bool>false</bool>
</property>
</action>
<action name="actionShow_console" >
<property name="icon" >
<iconset resource="icons.qrc" >:/Icons/log.png</iconset>
</property>
<property name="text" >
<string>Console</string>
</property>
</action>
</widget> </widget>
<resources/> <resources>
<include location="icons.qrc" />
</resources>
<connections/> <connections/>
</ui> </ui>

View File

@@ -61,11 +61,8 @@ class PreviewListDelegate: public QItemDelegate {
newopt.maximum = 100; newopt.maximum = 100;
newopt.minimum = 0; newopt.minimum = 0;
newopt.state |= QStyle::State_Enabled; newopt.state |= QStyle::State_Enabled;
newopt.textVisible = false; newopt.textVisible = true;
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter); QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter);
QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
painter->setPen(opt.palette.color(cg, QPalette::WindowText));
painter->drawText(opt.rect, Qt::AlignCenter, newopt.text);
break; break;
} }
default: default:

View File

@@ -75,11 +75,8 @@ class PropListDelegate: public QItemDelegate {
newopt.maximum = 100; newopt.maximum = 100;
newopt.minimum = 0; newopt.minimum = 0;
newopt.state |= QStyle::State_Enabled; newopt.state |= QStyle::State_Enabled;
newopt.textVisible = false; newopt.textVisible = true;
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter); QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter);
QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
painter->setPen(opt.palette.color(cg, QPalette::WindowText));
painter->drawText(opt.rect, Qt::AlignCenter, newopt.text);
break; break;
} }
case PRIORITY:{ case PRIORITY:{
@@ -177,14 +174,16 @@ class PropListDelegate: public QItemDelegate {
} }
break; break;
case 1: case 1:
if(old_val != NORMAL){ // if(old_val != NORMAL){
// model->setData(index, QVariant(NORMAL));
// if(filteredFilesChanged != 0)
// *filteredFilesChanged = true;
// } else {
model->setData(index, QVariant(HIGH));
model->setData(index, QVariant(NORMAL)); model->setData(index, QVariant(NORMAL));
if(filteredFilesChanged != 0) if(filteredFilesChanged != 0)
*filteredFilesChanged = true; *filteredFilesChanged = true;
} else { // }
model->setData(index, QVariant(HIGH));
model->setData(index, QVariant(NORMAL));
}
break; break;
case 2: case 2:
if(old_val != HIGH){ if(old_val != HIGH){

189
src/SearchTab.cpp Normal file
View File

@@ -0,0 +1,189 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contact : chris@qbittorrent.org
*/
#include <QDir>
#include <QTreeView>
#include <QStandardItemModel>
#include <QHeaderView>
#include <QSettings>
#include "SearchTab.h"
#include "SearchListDelegate.h"
#include "misc.h"
#include "searchEngine.h"
#define SEARCH_NAME 0
#define SEARCH_SIZE 1
#define SEARCH_SEEDERS 2
#define SEARCH_LEECHERS 3
#define SEARCH_ENGINE 4
SearchTab::SearchTab(SearchEngine *parent) : QWidget()
{
box=new QVBoxLayout();
results_lbl=new QLabel();
resultsBrowser = new QTreeView();
resultsBrowser->setSelectionMode(QAbstractItemView::ExtendedSelection);
box->addWidget(results_lbl);
box->addWidget(resultsBrowser);
setLayout(box);
// Set Search results list model
SearchListModel = new QStandardItemModel(0,5);
SearchListModel->setHeaderData(SEARCH_NAME, Qt::Horizontal, tr("Name", "i.e: file name"));
SearchListModel->setHeaderData(SEARCH_SIZE, Qt::Horizontal, tr("Size", "i.e: file size"));
SearchListModel->setHeaderData(SEARCH_SEEDERS, Qt::Horizontal, tr("Seeders", "i.e: Number of full sources"));
SearchListModel->setHeaderData(SEARCH_LEECHERS, Qt::Horizontal, tr("Leechers", "i.e: Number of partial sources"));
SearchListModel->setHeaderData(SEARCH_ENGINE, Qt::Horizontal, tr("Search engine"));
resultsBrowser->setModel(SearchListModel);
SearchDelegate = new SearchListDelegate();
resultsBrowser->setItemDelegate(SearchDelegate);
// Make search list header clickable for sorting
resultsBrowser->header()->setClickable(true);
resultsBrowser->header()->setSortIndicatorShown(true);
// Connect signals to slots (search part)
connect(resultsBrowser, SIGNAL(doubleClicked(const QModelIndex&)), parent, SLOT(downloadSelectedItem(const QModelIndex&)));
connect(resultsBrowser->header(), SIGNAL(sectionPressed(int)), this, SLOT(sortSearchList(int)));
// Load last columns width for search results list
if(!loadColWidthSearchList()){
resultsBrowser->header()->resizeSection(0, 275);
}
}
SearchTab::~SearchTab()
{
saveColWidthSearchList();
delete resultsBrowser;
delete SearchListModel;
delete SearchDelegate;
}
QLabel* SearchTab::getCurrentLabel()
{
return results_lbl;
}
QTreeView* SearchTab::getCurrentTreeView()
{
return resultsBrowser;
}
QStandardItemModel* SearchTab::getCurrentSearchListModel()
{
return SearchListModel;
}
// Set the color of a row in data model
void SearchTab::setRowColor(int row, QString color){
for(int i=0; i<SearchListModel->columnCount(); ++i){
SearchListModel->setData(SearchListModel->index(row, i), QVariant(QColor(color)), Qt::ForegroundRole);
}
}
void SearchTab::sortSearchList(int index){
static Qt::SortOrder sortOrder = Qt::AscendingOrder;
if(resultsBrowser->header()->sortIndicatorSection() == index){
sortOrder = (sortOrder == Qt::DescendingOrder) ? Qt::AscendingOrder : Qt::DescendingOrder; ;
}
resultsBrowser->header()->setSortIndicator(index, sortOrder);
switch(index){
case SEEDERS:
case LEECHERS:
case SIZE:
sortSearchListInt(index, sortOrder);
break;
default:
sortSearchListString(index, sortOrder);
}
}
void SearchTab::sortSearchListInt(int index, Qt::SortOrder sortOrder){
QList<QPair<int, qlonglong> > lines;
// Insertion sorting
for(int i=0; i<SearchListModel->rowCount(); ++i){
misc::insertSort(lines, QPair<int,qlonglong>(i, SearchListModel->data(SearchListModel->index(i, index)).toLongLong()), sortOrder);
}
// Insert items in new model, in correct order
int nbRows_old = lines.size();
for(int row=0; row<lines.size(); ++row){
SearchListModel->insertRow(SearchListModel->rowCount());
int sourceRow = lines[row].first;
for(int col=0; col<5; ++col){
SearchListModel->setData(SearchListModel->index(nbRows_old+row, col), SearchListModel->data(SearchListModel->index(sourceRow, col)));
SearchListModel->setData(SearchListModel->index(nbRows_old+row, col), SearchListModel->data(SearchListModel->index(sourceRow, col), Qt::ForegroundRole), Qt::ForegroundRole);
}
}
// Remove old rows
SearchListModel->removeRows(0, nbRows_old);
}
void SearchTab::sortSearchListString(int index, Qt::SortOrder sortOrder){
QList<QPair<int, QString> > lines;
// Insetion sorting
for(int i=0; i<SearchListModel->rowCount(); ++i){
misc::insertSortString(lines, QPair<int, QString>(i, SearchListModel->data(SearchListModel->index(i, index)).toString()), sortOrder);
}
// Insert items in new model, in correct order
int nbRows_old = lines.size();
for(int row=0; row<nbRows_old; ++row){
SearchListModel->insertRow(SearchListModel->rowCount());
int sourceRow = lines[row].first;
for(int col=0; col<5; ++col){
SearchListModel->setData(SearchListModel->index(nbRows_old+row, col), SearchListModel->data(SearchListModel->index(sourceRow, col)));
SearchListModel->setData(SearchListModel->index(nbRows_old+row, col), SearchListModel->data(SearchListModel->index(sourceRow, col), Qt::ForegroundRole), Qt::ForegroundRole);
}
}
// Remove old rows
SearchListModel->removeRows(0, nbRows_old);
}
// Save columns width in a file to remember them
// (download list)
void SearchTab::saveColWidthSearchList() const{
qDebug("Saving columns width in search list");
QSettings settings("qBittorrent", "qBittorrent");
QStringList width_list;
for(int i=0; i<SearchListModel->columnCount(); ++i){
width_list << misc::toQString(resultsBrowser->columnWidth(i));
}
settings.setValue("SearchListColsWidth", width_list.join(" "));
qDebug("Search list columns width saved");
}
// Load columns width in a file that were saved previously
// (search list)
bool SearchTab::loadColWidthSearchList(){
qDebug("Loading columns width for search list");
QSettings settings("qBittorrent", "qBittorrent");
QString line = settings.value("SearchListColsWidth", QString()).toString();
if(line.isEmpty())
return false;
QStringList width_list = line.split(' ');
if(width_list.size() != SearchListModel->columnCount())
return false;
for(int i=0; i<width_list.size(); ++i){
resultsBrowser->header()->resizeSection(i, width_list.at(i).toInt());
}
qDebug("Search list columns width loaded");
return true;
}

59
src/SearchTab.h Normal file
View File

@@ -0,0 +1,59 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contact : chris@qbittorrent.org
*/
#ifndef SEARCH_TAB_H
#define SEARCH_TAB_H
#include "ui_search.h"
class SearchListDelegate;
class SearchEngine;
class QTreeView;
class QStandardItemModel;
class SearchTab : public QWidget, public Ui::search_engine
{
Q_OBJECT
private:
QVBoxLayout *box;
QLabel *results_lbl;
QTreeView *resultsBrowser;
QStandardItemModel *SearchListModel;
SearchListDelegate *SearchDelegate;
public:
SearchTab(SearchEngine *parent);
~SearchTab();
bool loadColWidthSearchList();
QLabel * getCurrentLabel();
QStandardItemModel * getCurrentSearchListModel();
QTreeView * getCurrentTreeView();
void setRowColor(int row, QString color);
protected slots:
void sortSearchList(int index);
void sortSearchListInt(int index, Qt::SortOrder sortOrder);
void sortSearchListString(int index, Qt::SortOrder sortOrder);
void saveColWidthSearchList() const;
};
#endif

53
src/TrackersAdditionDlg.h Normal file
View File

@@ -0,0 +1,53 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contact : chris@qbittorrent.org
*/
#ifndef TRACKERSADDITION_H
#define TRACKERSADDITION_H
#include <QDialog>
#include <QStringList>
#include "ui_trackersAdd.h"
class TrackersAddDlg : public QDialog, private Ui::TrackersAdditionDlg{
Q_OBJECT
public:
TrackersAddDlg(QWidget *parent): QDialog(parent){
setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
show();
}
~TrackersAddDlg(){}
signals:
void TrackersToAdd(QStringList trackers);
public slots:
void on_buttonBox_accepted() {
QStringList trackers = trackers_list->toPlainText().trimmed().split("\n");
if(trackers.size()) {
emit TrackersToAdd(trackers);
}
}
};
#endif

View File

@@ -44,7 +44,7 @@ class about : public QDialog, private Ui::AboutDlg{
// Thanks // Thanks
te_thanks->append(QString::fromUtf8("<a name='top'></a>")); te_thanks->append(QString::fromUtf8("<a name='top'></a>"));
te_thanks->append(QString::fromUtf8("<ul><li>I would like to thank sourceforge.net for hosting qBittorrent project.</li>")); te_thanks->append(QString::fromUtf8("<ul><li>I would like to thank sourceforge.net for hosting qBittorrent project.</li>"));
te_thanks->append(QString::fromUtf8("<li>I am happy that Arnaud Demaizière is contributing to the project as a developer. His help is greatly appreciated</li>")); te_thanks->append(QString::fromUtf8("<li>I am happy that Ishan Arora and Arnaud Demaizière are contributing to the project as developers. Their help is greatly appreciated</li>"));
te_thanks->append(QString::fromUtf8("<li>I also want to thank Jeffery Fernandez (jeffery@qbittorrent.org), project consultant, RPM packager, for his help and support.</li>")); te_thanks->append(QString::fromUtf8("<li>I also want to thank Jeffery Fernandez (jeffery@qbittorrent.org), project consultant, RPM packager, for his help and support.</li>"));
te_thanks->append(QString::fromUtf8("<li>I am grateful to Peter Koeleman (peter@qbittorrent.org) who is helping port qBittorrent to Windows.</li>")); te_thanks->append(QString::fromUtf8("<li>I am grateful to Peter Koeleman (peter@qbittorrent.org) who is helping port qBittorrent to Windows.</li>"));
te_thanks->append(QString::fromUtf8("<li>Thanks a lot to our graphist Mateusz Toboła (tobejodok@qbittorrent.org) for his great work.</li></ul><br><br>")); te_thanks->append(QString::fromUtf8("<li>Thanks a lot to our graphist Mateusz Toboła (tobejodok@qbittorrent.org) for his great work.</li></ul><br><br>"));
@@ -56,13 +56,15 @@ class about : public QDialog, private Ui::AboutDlg{
"<i>- <u>Brazilian:</u> Nick Marinho (nickmarinho@gmail.com)<br>\ "<i>- <u>Brazilian:</u> Nick Marinho (nickmarinho@gmail.com)<br>\
- <u>Bulgarian:</u> Tsvetan & Boiko Bankov (emerge_life@users.sourceforge.net)<br>\ - <u>Bulgarian:</u> Tsvetan & Boiko Bankov (emerge_life@users.sourceforge.net)<br>\
- <u>Catalan:</u> Gekko Dam Beer (gekko04@users.sourceforge.net)<br>\ - <u>Catalan:</u> Gekko Dam Beer (gekko04@users.sourceforge.net)<br>\
- <u>Chinese (Simplified):</u> Guo Yue (guoyue0418@hotmail.com)<br>\ - <u>Chinese (Simplified):</u> Guo Yue (yue.guo0418@gmail.com)<br>\
- <u>Chinese (Traditional):</u> Yi-Shun Wang (dnextstep@gmail.com)<br>\
- <u>Czech:</u> Jirka Vilim (web@tets.cz)<br>\
- <u>Danish:</u> Mathias Nielsen (comoneo@gmail.com)<br>\ - <u>Danish:</u> Mathias Nielsen (comoneo@gmail.com)<br>\
- <u>Dutch:</u> Joost Schipper (heavyjoost@users.sourceforge.net)<br>\ - <u>Dutch:</u> Joost Schipper (heavyjoost@users.sourceforge.net) and Peter Koeleman (peter@peerweb.nl)<br>\
- <u>Finnish:</u> Niklas Laxström (nikerabbit@users.sourceforge.net)<br>\ - <u>Finnish:</u> Niklas Laxström (nikerabbit@users.sourceforge.net)<br>\
- <u>German:</u> Niels Hoffmann (zentralmaschine@users.sourceforge.net)<br>\ - <u>German:</u> Niels Hoffmann (zentralmaschine@users.sourceforge.net)<br>\
- <u>Greek:</u> Tsvetan Bankov (emerge_life@users.sourceforge.net)<br>\ - <u>Greek:</u> Tsvetan Bankov (emerge_life@users.sourceforge.net)<br>\
- <u>Hungarian:</u> Majoros Péter (majoros.j.p@t-online.hu)<br>\ - <u>Hungarian:</u> Majoros Péter (majoros.peterj@gmail.com)<br>\
- <u>Italian:</u> Mirko Ferrari (mirkoferrari@gmail.com) and Ferraro Luciano (luciano.ferraro@gmail.com)<br>\ - <u>Italian:</u> Mirko Ferrari (mirkoferrari@gmail.com) and Ferraro Luciano (luciano.ferraro@gmail.com)<br>\
- <u>Japanese:</u> Nardog (nardog@e2umail.com)<br>\ - <u>Japanese:</u> Nardog (nardog@e2umail.com)<br>\
- <u>Korean:</u> Jin Woo Sin (jin828sin@users.sourceforge.net)<br>\ - <u>Korean:</u> Jin Woo Sin (jin828sin@users.sourceforge.net)<br>\
@@ -70,11 +72,11 @@ class about : public QDialog, private Ui::AboutDlg{
- <u>Polish:</u> Jarek Smieja (ajep9691@wp.pl)<br>\ - <u>Polish:</u> Jarek Smieja (ajep9691@wp.pl)<br>\
- <u>Portuguese:</u> Nick Marinho (nickmarinho@gmail.com)<br>\ - <u>Portuguese:</u> Nick Marinho (nickmarinho@gmail.com)<br>\
- <u>Romanian:</u> Obada Denis (obadadenis@users.sourceforge.net)<br>\ - <u>Romanian:</u> Obada Denis (obadadenis@users.sourceforge.net)<br>\
- <u>Russian:</u> Nick Khazov (m2k3d0n at users.sourceforge.net)<br>\ - <u>Russian:</u> Nick Khazov (m2k3d0n@users.sourceforge.net) and Alexey Morsov (samurai@ricom.ru)<br>\
- <u>Slovak:</u> helix84<br>\ - <u>Slovak:</u> helix84<br>\
- <u>Spanish:</u> Vicente Raul Plata Fonseca (silverxnt@users.sourceforge.net)<br>\ - <u>Spanish:</u> Vicente Raul Plata Fonseca (silverxnt@users.sourceforge.net) and Gabriel de Oliveira (deadloop@hotmail.com)<br>\
- <u>Swedish:</u> Daniel Nylander (po@danielnylander.se)<br>\ - <u>Swedish:</u> Daniel Nylander (po@danielnylander.se)<br>\
- <u>Turkish:</u> Erdem Bingöl (erdem84@gmail.com)<br>\ - <u>Turkish:</u> Hasan YILMAZ (iletisim@hedefturkce.com) and Erdem Bingöl (erdem84@gmail.com)<br>\
- <u>Ukrainian:</u> Andrey Shpachenko (masterfix@users.sourceforge.net)<br><br>")); - <u>Ukrainian:</u> Andrey Shpachenko (masterfix@users.sourceforge.net)<br><br>"));
te_translation->append(tr("Please contact me if you would like to translate qBittorrent into your own language.")); te_translation->append(tr("Please contact me if you would like to translate qBittorrent into your own language."));
te_translation->scrollToAnchor(QString::fromUtf8("top")); te_translation->scrollToAnchor(QString::fromUtf8("top"));

View File

@@ -13,21 +13,6 @@
<string>Torrent addition dialog</string> <string>Torrent addition dialog</string>
</property> </property>
<layout class="QVBoxLayout" > <layout class="QVBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="leftMargin" >
<number>9</number>
</property>
<property name="topMargin" >
<number>9</number>
</property>
<property name="rightMargin" >
<number>9</number>
</property>
<property name="bottomMargin" >
<number>9</number>
</property>
<item> <item>
<widget class="QLabel" name="fileNameLbl" > <widget class="QLabel" name="fileNameLbl" >
<property name="text" > <property name="text" >
@@ -110,6 +95,50 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<layout class="QHBoxLayout" >
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="collapseAllButton" >
<property name="text" >
<string>Collapse all</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="expandAllButton" >
<property name="text" >
<string>Expand all</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item> <item>
<widget class="QCheckBox" name="checkIncrementalDL" > <widget class="QCheckBox" name="checkIncrementalDL" >
<property name="text" > <property name="text" >

View File

@@ -27,19 +27,19 @@
#include <QDir> #include <QDir>
#include "misc.h" #include "misc.h"
class file { class torrent_file {
private: private:
file *parent; torrent_file *parent;
bool is_dir; bool is_dir;
QString rel_path; QString rel_path;
QList<file*> children; QList<torrent_file*> children;
size_type size; size_type size;
float progress; float progress;
int priority; int priority;
int index; // Index in torrent_info int index; // Index in torrent_info
public: public:
file(file *parent, QString path, bool dir, size_type size=0, int index=-1, float progress=0., int priority=1): parent(parent), is_dir(dir), size(size), progress(progress), priority(priority), index(index){ torrent_file(torrent_file *parent, QString path, bool dir, size_type size=0, int index=-1, float progress=0., int priority=1): parent(parent), is_dir(dir), size(size), progress(progress), priority(priority), index(index){
qDebug("created a file with index %d", index); qDebug("created a file with index %d", index);
rel_path = QDir::cleanPath(path); rel_path = QDir::cleanPath(path);
if(parent) { if(parent) {
@@ -48,7 +48,7 @@ class file {
} }
} }
~file() { ~torrent_file() {
qDeleteAll(children); qDeleteAll(children);
} }
@@ -62,17 +62,25 @@ class file {
void updateProgress() { void updateProgress() {
Q_ASSERT(is_dir); Q_ASSERT(is_dir);
float sum = 0; if(children.isEmpty()) {
file *child; progress = 0.;
foreach(child, children) { return;
sum += child->getProgress();
} }
progress = sum / (float)children.size(); float wanted = 0.;
float done = 0.;
torrent_file *child;
foreach(child, children) {
wanted += child->getSize();
done += child->getSize()*child->getProgress();
}
progress = done / wanted;
Q_ASSERT(progress >= 0.);
Q_ASSERT(progress <= 1.);
} }
void updatePriority(int prio) { void updatePriority(int prio) {
Q_ASSERT(is_dir); Q_ASSERT(is_dir);
file *child; torrent_file *child;
foreach(child, children) { foreach(child, children) {
if(child->getPriority() != prio) return; if(child->getPriority() != prio) return;
} }
@@ -103,13 +111,13 @@ class file {
return (!children.isEmpty()); return (!children.isEmpty());
} }
QList<file*> getChildren() const { QList<torrent_file*> getChildren() const {
return children; return children;
} }
file* getChild(QString fileName) const { torrent_file* getChild(QString fileName) const {
Q_ASSERT(is_dir); Q_ASSERT(is_dir);
file* f; torrent_file* f;
foreach(f, children) { foreach(f, children) {
if(f->name() == fileName) return f; if(f->name() == fileName) return f;
} }
@@ -122,10 +130,10 @@ class file {
parent->addBytes(b); parent->addBytes(b);
} }
file* addChild(QString fileName, bool dir, size_type size=0, int index = -1, float progress=0., int priority=1) { torrent_file* addChild(QString fileName, bool dir, size_type size=0, int index = -1, float progress=0., int priority=1) {
Q_ASSERT(is_dir); Q_ASSERT(is_dir);
qDebug("Adding a new child of size: %ld", (long)size); qDebug("Adding a new child of size: %ld", (long)size);
file *f = new file(this, QDir::cleanPath(rel_path+QDir::separator()+fileName), dir, size, index, progress, priority); torrent_file *f = new torrent_file(this, QDir::cleanPath(rel_path+QDir::separator()+fileName), dir, size, index, progress, priority);
children << f; children << f;
if(size) { if(size) {
addBytes(size); addBytes(size);
@@ -140,7 +148,7 @@ class file {
return true; return true;
} }
bool success = true; bool success = true;
file *f; torrent_file *f;
qDebug("We have %d children", children.size()); qDebug("We have %d children", children.size());
foreach(f, children) { foreach(f, children) {
bool s = f->removeFromFS(saveDir); bool s = f->removeFromFS(saveDir);
@@ -161,44 +169,44 @@ class file {
class arborescence { class arborescence {
private: private:
file *root; torrent_file *root;
public: public:
arborescence(torrent_info t) { arborescence(boost::intrusive_ptr<torrent_info> t) {
torrent_info::file_iterator fi = t.begin_files(); torrent_info::file_iterator fi = t->begin_files();
if(t.num_files() > 1) { if(t->num_files() > 1) {
root = new file(0, misc::toQString(t.name()), true); root = new torrent_file(0, misc::toQString(t->name()), true);
} else { } else {
// XXX: Will crash if there is no file in torrent // XXX: Will crash if there is no file in torrent
root = new file(0, misc::toQString(t.name()), false, fi->size, 0); root = new torrent_file(0, misc::toQString(t->name()), false, fi->size, 0);
return; return;
} }
int i = 0; int i = 0;
while(fi != t.end_files()) { while(fi != t->end_files()) {
QString path = QDir::cleanPath(misc::toQString(fi->path.string())); QString path = QDir::cleanPath(misc::toQString(fi->path.string()));
addFile(path, fi->size, i); addFile(path, fi->size, i);
fi++; fi++;
++i; ++i;
} }
qDebug("real size: %ld, tree size: %ld", (long)t.total_size(), (long)root->getSize()); qDebug("real size: %ld, tree size: %ld", (long)t->total_size(), (long)root->getSize());
Q_ASSERT(root->getSize() == t.total_size()); Q_ASSERT(root->getSize() == t->total_size());
} }
arborescence(torrent_info t, std::vector<float> fp, int *prioritiesTab) { arborescence(torrent_info const& t, std::vector<size_type> fp, int *prioritiesTab) {
torrent_info::file_iterator fi = t.begin_files(); torrent_info::file_iterator fi = t.begin_files();
if(t.num_files() > 1) { if(t.num_files() > 1) {
qDebug("More than one file in the torrent, setting a folder as root"); qDebug("More than one file in the torrent, setting a folder as root");
root = new file(0, misc::toQString(t.name()), true); root = new torrent_file(0, misc::toQString(t.name()), true);
} else { } else {
// XXX: Will crash if there is no file in torrent // XXX: Will crash if there is no file in torrent
qDebug("one file in the torrent, setting it as root with index 0"); qDebug("one file in the torrent, setting it as root with index 0");
root = new file(0, misc::toQString(t.name()), false, fi->size, 0, fp[0], prioritiesTab[0]); root = new torrent_file(0, misc::toQString(t.name()), false, fi->size, 0, fp[0]/t.file_at(0).size, prioritiesTab[0]);
return; return;
} }
int i = 0; int i = 0;
while(fi != t.end_files()) { while(fi != t.end_files()) {
QString path = QDir::cleanPath(misc::toQString(fi->path.string())); QString path = QDir::cleanPath(misc::toQString(fi->path.string()));
addFile(path, fi->size, i, fp[i], prioritiesTab[i]); addFile(path, fi->size, i, fp[i]/t.file_at(i).size, prioritiesTab[i]);
fi++; fi++;
++i; ++i;
} }
@@ -210,7 +218,7 @@ class arborescence {
delete root; delete root;
} }
file* getRoot() const { torrent_file* getRoot() const {
return root; return root;
} }
@@ -226,19 +234,19 @@ class arborescence {
void addFile(QString path, size_type file_size, int index, float progress=0., int priority=1) { void addFile(QString path, size_type file_size, int index, float progress=0., int priority=1) {
Q_ASSERT(root->isDir()); Q_ASSERT(root->isDir());
path = QDir::cleanPath(path); path = QDir::cleanPath(path);
Q_ASSERT(path.startsWith(root->path())); //Q_ASSERT(path.startsWith(root->path()));
QString relative_path = path.remove(0, root->path().size()); QString relative_path = path.remove(0, root->path().size());
if(relative_path.at(0) ==QDir::separator()) if(relative_path.at(0) ==QDir::separator())
relative_path.remove(0, 1); relative_path.remove(0, 1);
QStringList fileNames = relative_path.split(QDir::separator()); QStringList fileNames = relative_path.split(QDir::separator());
QString fileName; QString fileName;
file *dad = root; torrent_file *dad = root;
unsigned int nb_i = 0; unsigned int nb_i = 0;
unsigned int size = fileNames.size(); unsigned int size = fileNames.size();
foreach(fileName, fileNames) { foreach(fileName, fileNames) {
++nb_i; ++nb_i;
if(fileName == ".") continue; if(fileName == ".") continue;
file* child = dad->getChild(fileName); torrent_file* child = dad->getChild(fileName);
if(!child) { if(!child) {
if(nb_i != size) { if(nb_i != size) {
// Folder // Folder

File diff suppressed because it is too large Load Diff

View File

@@ -22,9 +22,10 @@
#define __BITTORRENT_H__ #define __BITTORRENT_H__
#include <QHash> #include <QHash>
#include <QList>
#include <QPair>
#include <QStringList> #include <QStringList>
#include <QApplication>
#include <QPalette>
#include <QPointer>
#include <libtorrent/session.hpp> #include <libtorrent/session.hpp>
#include <libtorrent/ip_filter.hpp> #include <libtorrent/ip_filter.hpp>
@@ -33,36 +34,38 @@
using namespace libtorrent; using namespace libtorrent;
class downloadThread; class downloadThread;
class deleteThread;
class QTimer; class QTimer;
class QFileSystemWatcher;
class QMutex;
class FilterParserThread;
class bittorrent : public QObject{ class bittorrent : public QObject {
Q_OBJECT Q_OBJECT
private: private:
session *s; session *s;
QString scan_dir; QPointer<QFileSystemWatcher> FSWatcher;
QTimer *timerScan; QMutex* FSMutex;
QTimer *timerAlerts; QPointer<QTimer> timerAlerts;
QPointer<QTimer> BigRatioTimer;
bool DHTEnabled; bool DHTEnabled;
downloadThread *downloader; QPointer<downloadThread> downloader;
QString defaultSavePath; QString defaultSavePath;
QStringList torrentsToPauseAfterChecking; QHash<QString, QHash<QString, QString> > trackersErrors;
QStringList reloadingTorrents; QStringList consoleMessages;
QHash<QString, QList<qlonglong> > ETAstats; QStringList peerBanMessages;
QHash<QString, qlonglong> ETAs;
QHash<QString, QPair<size_type,size_type> > ratioData;
QTimer *ETARefresher;
QHash<QString, QList<QPair<QString, QString> > > trackersErrors;
deleteThread *deleter;
QStringList waitingForPause;
QStringList finishedTorrents;
QStringList unfinishedTorrents;
bool preAllocateAll; bool preAllocateAll;
bool addInPause; bool addInPause;
int maxConnecsPerTorrent; int maxConnecsPerTorrent;
int maxUploadsPerTorrent; int maxUploadsPerTorrent;
float max_ratio; float max_ratio;
bool UPnPEnabled;
bool NATPMPEnabled;
bool LSDEnabled;
QPointer<FilterParserThread> filterParser;
QString filterPath;
bool queueingEnabled;
QStringList url_skippingDlg;
protected: protected:
QString getSavePath(QString hash); QString getSavePath(QString hash);
@@ -72,47 +75,59 @@ class bittorrent : public QObject{
bittorrent(); bittorrent();
~bittorrent(); ~bittorrent();
QTorrentHandle getTorrentHandle(QString hash) const; QTorrentHandle getTorrentHandle(QString hash) const;
bool isPaused(QString hash) const; std::vector<torrent_handle> getTorrents() const;
bool isFilePreviewPossible(QString fileHash) const; bool isFilePreviewPossible(QString fileHash) const;
bool isDHTEnabled() const; bool isDHTEnabled() const;
float getPayloadDownloadRate() const; float getPayloadDownloadRate() const;
float getPayloadUploadRate() const; float getPayloadUploadRate() const;
session_status getSessionStatus() const; session_status getSessionStatus() const;
int getListenPort() const; int getListenPort() const;
QStringList getTorrentsToPauseAfterChecking() const;
long getETA(QString hash) const;
float getRealRatio(QString hash) const; float getRealRatio(QString hash) const;
session* getSession() const; session* getSession() const;
QList<QPair<QString, QString> > getTrackersErrors(QString hash) const; QHash<QString, QString> getTrackersErrors(QString hash) const;
QStringList getFinishedTorrents() const;
QStringList getUnfinishedTorrents() const;
bool isFinished(QString hash) const;
bool has_filtered_files(QString hash) const; bool has_filtered_files(QString hash) const;
unsigned int getFinishedPausedTorrentsNb() const;
unsigned int getUnfinishedPausedTorrentsNb() const;
bool isQueueingEnabled() const;
int getDlTorrentPriority(QString hash) const;
int getUpTorrentPriority(QString hash) const;
int getMaximumActiveDownloads() const;
int getMaximumActiveTorrents() const;
int loadTorrentPriority(QString hash);
QStringList getConsoleMessages() const;
QStringList getPeerBanMessages() const;
qlonglong getETA(QString hash) const;
public slots: public slots:
void addTorrent(QString path, bool fromScanDir = false, QString from_url = QString()); QTorrentHandle addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false);
void loadSessionState();
void saveSessionState();
void downloadFromUrl(QString url); void downloadFromUrl(QString url);
void downloadFromURLList(const QStringList& url_list); void downloadFromURLList(const QStringList& url_list);
void deleteTorrent(QString hash, bool permanent = false); void deleteTorrent(QString hash, bool permanent = false);
bool pauseTorrent(QString hash); /* Needed by Web UI */
bool resumeTorrent(QString hash); void pauseAllTorrents();
void resumeAllTorrents();
void pauseTorrent(QString hash);
void resumeTorrent(QString hash);
/* End Web UI */
void saveDHTEntry(); void saveDHTEntry();
void preAllocateAllFiles(bool b); void preAllocateAllFiles(bool b);
void saveFastResumeAndRatioData(); void saveFastResumeData();
void enableDirectoryScanning(QString scan_dir); void enableDirectoryScanning(QString scan_dir);
void disableDirectoryScanning(); void disableDirectoryScanning();
void enablePeerExchange(); void enableIPFilter(QString filter);
void enableIPFilter(ip_filter filter);
void disableIPFilter(); void disableIPFilter();
void pauseAndReloadTorrent(QTorrentHandle h); void setQueueingEnabled(bool enable);
void resumeUnfinishedTorrents(); void resumeUnfinishedTorrents();
void updateETAs(); void saveTorrentPriority(QString hash, int prio);
void saveTorrentSpeedLimits(QString hash); void saveTorrentSpeedLimits(QString hash);
void loadTorrentSpeedLimits(QString hash); void loadTorrentSpeedLimits(QString hash);
void saveDownloadUploadForTorrent(QString hash);
void loadDownloadUploadForTorrent(QString hash);
void handleDownloadFailure(QString url, QString reason); void handleDownloadFailure(QString url, QString reason);
void loadWebSeeds(QString fileHash); void loadWebSeeds(QString fileHash);
void increaseDlTorrentPriority(QString hash);
void decreaseDlTorrentPriority(QString hash);
void downloadUrlAndSkipDialog(QString);
// Session configuration - Setters // Session configuration - Setters
void setListeningPortsRange(std::pair<unsigned short, unsigned short> ports); void setListeningPortsRange(std::pair<unsigned short, unsigned short> ports);
void setMaxConnections(int maxConnec); void setMaxConnections(int maxConnec);
@@ -131,41 +146,34 @@ class bittorrent : public QObject{
void loadFilesPriorities(QTorrentHandle& h); void loadFilesPriorities(QTorrentHandle& h);
void setDownloadLimit(QString hash, long val); void setDownloadLimit(QString hash, long val);
void setUploadLimit(QString hash, long val); void setUploadLimit(QString hash, long val);
void setUnfinishedTorrent(QString hash);
void setFinishedTorrent(QString hash);
void enableUPnP(bool b); void enableUPnP(bool b);
void enableNATPMP(bool b); void enableNATPMP(bool b);
void enableLSD(bool b); void enableLSD(bool b);
void enableDHT(bool b); bool enableDHT(bool b);
void addConsoleMessage(QString msg, QColor color=QApplication::palette().color(QPalette::WindowText));
void addPeerBanMessage(QString msg, bool from_ipfilter);
protected slots: protected slots:
void scanDirectory(); void scanDirectory(QString);
void readAlerts(); void readAlerts();
void processDownloadedFile(QString, QString); void processDownloadedFile(QString, QString);
bool loadTrackerFile(QString hash); bool loadTrackerFile(QString hash);
void saveTrackerFile(QString hash); void saveTrackerFile(QString hash);
void reloadTorrent(const QTorrentHandle &h); // This is protected now, call pauseAndReloadTorrent() instead
void deleteBigRatios(); void deleteBigRatios();
signals: signals:
void invalidTorrent(QString path); void addedTorrent(QTorrentHandle& h);
void duplicateTorrent(QString path); void deletedTorrent(QString hash);
void addedTorrent(QString path, QTorrentHandle& h, bool fastResume); void pausedTorrent(QTorrentHandle& h);
void resumedTorrent(QTorrentHandle& h);
void finishedTorrent(QTorrentHandle& h); void finishedTorrent(QTorrentHandle& h);
void fullDiskError(QTorrentHandle& h); void fullDiskError(QTorrentHandle& h);
void trackerError(QString hash, QString time, QString msg); void trackerError(QString hash, QString time, QString msg);
void portListeningFailure();
void trackerAuthenticationRequired(QTorrentHandle& h); void trackerAuthenticationRequired(QTorrentHandle& h);
void scanDirFoundTorrents(const QStringList& pathList);
void newDownloadedTorrent(QString path, QString url); void newDownloadedTorrent(QString path, QString url);
void aboutToDownloadFromUrl(QString url);
void updateFileSize(QString hash); void updateFileSize(QString hash);
void peerBlocked(QString);
void downloadFromUrlFailure(QString url, QString reason); void downloadFromUrlFailure(QString url, QString reason);
void fastResumeDataRejected(QString name); void torrentFinishedChecking(QTorrentHandle& h);
void urlSeedProblem(QString url, QString msg);
void torrentFinishedChecking(QString hash);
void torrent_deleted(QString hash, QString fileName, bool finished);
}; };
#endif #endif

58
src/console.ui Normal file
View File

@@ -0,0 +1,58 @@
<ui version="4.0" >
<class>ConsoleDlg</class>
<widget class="QDialog" name="ConsoleDlg" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>512</width>
<height>497</height>
</rect>
</property>
<property name="windowTitle" >
<string>qBittorrent console</string>
</property>
<property name="windowIcon" >
<iconset resource="icons.qrc" >:/Icons/log.png</iconset>
</property>
<layout class="QVBoxLayout" >
<item>
<widget class="QTabWidget" name="tabConsole" >
<property name="currentIndex" >
<number>0</number>
</property>
<widget class="QWidget" name="tab" >
<attribute name="title" >
<string>General</string>
</attribute>
<attribute name="icon" >
<iconset resource="icons.qrc" >:/Icons/log.png</iconset>
</attribute>
<layout class="QVBoxLayout" >
<item>
<widget class="QTextBrowser" name="textConsole" />
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2" >
<attribute name="title" >
<string>Blocked IPs</string>
</attribute>
<attribute name="icon" >
<iconset resource="icons.qrc" >:/Icons/filter.png</iconset>
</attribute>
<layout class="QVBoxLayout" >
<item>
<widget class="QTextBrowser" name="textBannedPeers" />
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="icons.qrc" />
</resources>
<connections/>
</ui>

50
src/console_imp.h Normal file
View File

@@ -0,0 +1,50 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contact : chris@qbittorrent.org
*/
#ifndef CONSOLE_H
#define CONSOLE_H
#include "bittorrent.h"
#include "ui_console.h"
using namespace libtorrent;
class consoleDlg : public QDialog, private Ui_ConsoleDlg{
Q_OBJECT
private:
bittorrent *BTSession;
public:
consoleDlg(QWidget *parent, bittorrent* _BTSession) : QDialog(parent) {
setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
BTSession = _BTSession;
textConsole->setHtml(BTSession->getConsoleMessages().join("<br>"));
textBannedPeers->setHtml(BTSession->getPeerBanMessages().join("<br>"));
show();
}
~consoleDlg() {}
};
#endif

View File

@@ -1,19 +0,0 @@
#!/usr/bin/python
import os
LANG_FOLDER = "lang/"
PO_FOLDER = 'po_files'
if __name__ == '__main__':
po_files = os.listdir(os.path.join(LANG_FOLDER, PO_FOLDER))
po_files = [x for x in po_files if os.path.splitext(x)[-1] == ".po"]
for file in po_files:
# First clean up the ts file
ts_file = os.path.join(LANG_FOLDER, os.path.splitext(file)[0]+'.ts')
po_file = os.path.join(LANG_FOLDER, PO_FOLDER, file)
if os.path.exists(ts_file):
os.remove(ts_file)
# Convert to PO
print "Converting %s..." % (po_file,)
os.system("po2ts %s -o %s" % (po_file, ts_file))

View File

@@ -1,24 +0,0 @@
#!/usr/bin/python
import os
LANG_FOLDER = 'lang/'
PO_FOLDER = 'po_files'
if __name__ == '__main__':
ts_files = os.listdir(LANG_FOLDER)
ts_files = [x for x in ts_files if os.path.splitext(x)[-1] == ".ts"]
for file in ts_files:
# First clean up the po file
po_file = os.path.join(LANG_FOLDER, PO_FOLDER, os.path.splitext(file)[0]+'.po')
ts_file = os.path.join(LANG_FOLDER, file)
if os.path.exists(po_file):
os.remove(po_file)
# create po folder if it doesn't exist
if not os.path.exists(os.path.join(LANG_FOLDER, PO_FOLDER)):
os.mkdir(os.path.join(LANG_FOLDER, PO_FOLDER))
# Convert to PO
print "Converting %s..." % (ts_file,)
os.system("ts2po %s -o %s" % (ts_file, po_file))
# Making an archive
os.system("tar czf %s %s" % (os.path.join(LANG_FOLDER, PO_FOLDER)+'.tar.gz', os.path.join(LANG_FOLDER, PO_FOLDER)))

View File

@@ -6,7 +6,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>592</width> <width>592</width>
<height>590</height> <height>655</height>
</rect> </rect>
</property> </property>
<property name="windowTitle" > <property name="windowTitle" >
@@ -477,6 +477,20 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QLabel" name="progressLbl" >
<property name="text" >
<string>Progress:</string>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="progressBar" >
<property name="value" >
<number>0</number>
</property>
</widget>
</item>
<item> <item>
<layout class="QHBoxLayout" > <layout class="QHBoxLayout" >
<property name="spacing" > <property name="spacing" >

View File

@@ -26,6 +26,7 @@
#include <boost/filesystem/operations.hpp> #include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
#include <boost/bind.hpp>
#include <libtorrent/entry.hpp> #include <libtorrent/entry.hpp>
#include <libtorrent/bencode.hpp> #include <libtorrent/bencode.hpp>
@@ -34,18 +35,38 @@
#include <libtorrent/storage.hpp> #include <libtorrent/storage.hpp>
#include <libtorrent/hasher.hpp> #include <libtorrent/hasher.hpp>
#include <libtorrent/file_pool.hpp> #include <libtorrent/file_pool.hpp>
#include <libtorrent/create_torrent.hpp>
#include "createtorrent_imp.h" #include "createtorrent_imp.h"
#include "misc.h"
using namespace libtorrent; using namespace libtorrent;
using namespace boost::filesystem; using namespace boost::filesystem;
// do not include files and folders whose
// name starts with a .
bool file_filter(boost::filesystem::path const& filename)
{
if (filename.leaf()[0] == '.') return false;
std::cerr << filename << std::endl;
return true;
}
createtorrent::createtorrent(QWidget *parent): QDialog(parent){ createtorrent::createtorrent(QWidget *parent): QDialog(parent){
setupUi(this); setupUi(this);
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);
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)));
connect(creatorThread, SIGNAL(updateProgress(int)), this, SLOT(updateProgressBar(int)));
path::default_name_check(no_check);
show(); show();
} }
createtorrent::~createtorrent() {
delete creatorThread;
}
void createtorrent::on_addFolder_button_clicked(){ void createtorrent::on_addFolder_button_clicked(){
QString dir = QFileDialog::getExistingDirectory(this, tr("Select a folder to add to the torrent"), QDir::homePath(), QFileDialog::ShowDirsOnly); QString dir = QFileDialog::getExistingDirectory(this, tr("Select a folder to add to the torrent"), QDir::homePath(), QFileDialog::ShowDirsOnly);
if(!dir.isEmpty()) if(!dir.isEmpty())
@@ -117,18 +138,6 @@ void createtorrent::on_addURLSeed_button_clicked(){
} }
} }
// Subfunction to add files to a torrent_info structure
// Written by Arvid Norberg (libtorrent Author)
void add_files(torrent_info& t, path const& p, path const& l){
path f(p / l);
if (is_directory(f)){
for (directory_iterator i(f), end; i != end; ++i)
add_files(t, p, l / i->leaf());
}else{
t.add_file(l, file_size(f));
}
}
QStringList createtorrent::allItems(QListWidget *list){ QStringList createtorrent::allItems(QListWidget *list){
QStringList res; QStringList res;
unsigned int nbItems = list->count(); unsigned int nbItems = list->count();
@@ -141,7 +150,9 @@ QStringList createtorrent::allItems(QListWidget *list){
// Main function that create a .torrent file // Main function that create a .torrent file
void createtorrent::on_createButton_clicked(){ void createtorrent::on_createButton_clicked(){
QString input = textInputPath->text().trimmed(); QString input = textInputPath->text().trimmed();
if(input.isEmpty() == 0){ if (input.endsWith(QDir::separator()))
input.chop(1);
if(input.isEmpty()){
QMessageBox::critical(0, tr("No input path set"), tr("Please type an input path first")); QMessageBox::critical(0, tr("No input path set"), tr("Please type an input path first"));
return; return;
} }
@@ -157,57 +168,100 @@ void createtorrent::on_createButton_clicked(){
} else { } else {
return; return;
} }
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) {
QMessageBox::information(0, tr("Torrent creation"), tr("Torrent creation was unsuccessful, reason: %1").arg(msg));
hide();
}
void createtorrent::handleCreationSuccess(QString path, const char* branch_path) {
if(checkStartSeeding->isChecked()) {
// Create save path file
boost::intrusive_ptr<torrent_info> t;
try {
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());
QFile savepath_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".savepath"));
savepath_file.open(QIODevice::WriteOnly | QIODevice::Text);
savepath_file.write(branch_path);
savepath_file.close();
emit torrent_to_seed(path);
}
QMessageBox::information(0, tr("Torrent creation"), tr("Torrent was created successfully:")+" "+path);
hide();
}
void createtorrent::updateProgressBar(int progress) {
progressBar->setValue(progress);
}
//
// Torrent Creator Thread
//
void torrentCreatorThread::create(QString _input_path, QString _save_path, QStringList _trackers, QStringList _url_seeds, QString _comment, bool _is_private, int _piece_size) {
input_path = _input_path;
save_path = _save_path;
trackers = _trackers;
url_seeds = _url_seeds;
comment = _comment;
is_private = _is_private;
piece_size = _piece_size;
abort = false;
start();
}
void sendProgressUpdateSignal(int i, int num, QDialog *parent){
((createtorrent*)parent)->updateProgressBar((int)(i*100./(float)num));
}
void torrentCreatorThread::run() {
emit updateProgress(0);
char const* creator_str = "qBittorrent "VERSION; char const* creator_str = "qBittorrent "VERSION;
try { try {
boost::intrusive_ptr<torrent_info> t(new torrent_info); file_storage fs;
ofstream out(complete(path((const char*)destination.toUtf8())), std::ios_base::binary); file_pool fp;
path full_path; path full_path = complete(path(input_path.toUtf8().data()));
// Adding files to the torrent // Adding files to the torrent
full_path = complete(path(input.toUtf8().data())); add_files(fs, full_path, file_filter);
add_files(*t, full_path.branch_path(), full_path.leaf()); if(abort) return;
// Set piece size create_torrent t(fs, piece_size);
int piece_size = getPieceSize();
t->set_piece_size(piece_size);
// Add url seeds // Add url seeds
QStringList urlSeeds = allItems(URLSeeds_list);
QString seed; QString seed;
foreach(seed, urlSeeds){ foreach(seed, url_seeds){
t->add_url_seed(seed.toUtf8().data()); t.add_url_seed(seed.toUtf8().data());
} }
for(int i=0; i<trackers.size(); ++i){ for(int i=0; i<trackers.size(); ++i){
t->add_tracker(trackers.at(i).toUtf8().data()); t.add_tracker(trackers.at(i).toUtf8().data());
} }
if(abort) return;
// calculate the hash for all pieces // calculate the hash for all pieces
file_pool fp; set_piece_hashes(t, full_path.branch_path(), boost::bind<void>(&sendProgressUpdateSignal, _1, t.num_pieces(), parent));
boost::scoped_ptr<storage_interface> st(default_storage_constructor(t, full_path.branch_path(), fp));
int num = t->num_pieces();
std::vector<char> buf(piece_size);
for (int i = 0; i < num; ++i) {
st->read(&buf[0], i, 0, t->piece_size(i));
hasher h(&buf[0], t->piece_size(i));
t->set_hash(i, h.final());
}
// Set qBittorrent as creator and add user comment to // Set qBittorrent as creator and add user comment to
// torrent_info structure // torrent_info structure
t->set_creator(creator_str); t.set_creator(creator_str);
t->set_comment((const char*)txt_comment->toPlainText().toUtf8()); t.set_comment((const char*)comment.toUtf8());
// Is private ? // Is private ?
if(check_private->isChecked()){ if(is_private){
t->set_priv(true); t.set_priv(true);
} }
if(abort) return;
// create the torrent and print it to out // create the torrent and print it to out
entry e = t->create_torrent(); ofstream out(complete(path((const char*)save_path.toUtf8())), std::ios_base::binary);
libtorrent::bencode(std::ostream_iterator<char>(out), e); bencode(std::ostream_iterator<char>(out), t.generate());
if(checkStartSeeding->isChecked()) emit updateProgress(100);
emit torrent_to_seed(destination); emit creationSuccess(save_path, full_path.branch_path().string().c_str());
} }
catch (std::exception& e){ catch (std::exception& e){
std::cerr << e.what() << "\n"; emit creationFailure(QString::fromUtf8(e.what()));
QMessageBox::information(0, tr("Torrent creation"), tr("Torrent creation was unsuccessful, reason: %1").arg(QString::fromUtf8(e.what())));
hide();
return;
} }
hide();
QMessageBox::information(0, tr("Torrent creation"), tr("Torrent was created successfully:")+" "+destination);
} }

View File

@@ -22,19 +22,60 @@
#ifndef CREATE_TORRENT_IMP_H #ifndef CREATE_TORRENT_IMP_H
#define CREATE_TORRENT_IMP_H #define CREATE_TORRENT_IMP_H
#include <QThread>
#include "ui_createtorrent.h" #include "ui_createtorrent.h"
class torrentCreatorThread : public QThread {
Q_OBJECT
QString input_path;
QString save_path;
QStringList trackers;
QStringList url_seeds;
QString comment;
bool is_private;
int piece_size;
bool abort;
QDialog *parent;
public:
torrentCreatorThread(QDialog *_parent) {
parent = _parent;
}
~torrentCreatorThread() {
abort = true;
wait();
}
void create(QString _input_path, QString _save_path, QStringList _trackers, QStringList _url_seeds, QString _comment, bool _is_private, int _piece_size);
protected:
void run();
signals:
void creationFailure(QString msg);
void creationSuccess(QString path, const char* branch_path);
void updateProgress(int progress);
};
class createtorrent : public QDialog, private Ui::createTorrentDialog{ class createtorrent : public QDialog, private Ui::createTorrentDialog{
Q_OBJECT Q_OBJECT
private:
torrentCreatorThread *creatorThread;
public: public:
createtorrent(QWidget *parent = 0); createtorrent(QWidget *parent = 0);
~createtorrent();
QStringList allItems(QListWidget *list); QStringList allItems(QListWidget *list);
int getPieceSize() const; int getPieceSize() const;
signals: signals:
void torrent_to_seed(QString path); void torrent_to_seed(QString path);
public slots:
void updateProgressBar(int progress);
protected slots: protected slots:
void on_createButton_clicked(); void on_createButton_clicked();
void on_addFile_button_clicked(); void on_addFile_button_clicked();
@@ -43,6 +84,8 @@ class createtorrent : public QDialog, private Ui::createTorrentDialog{
void on_removeTracker_button_clicked(); void on_removeTracker_button_clicked();
void on_addURLSeed_button_clicked(); void on_addURLSeed_button_clicked();
void on_removeURLSeed_button_clicked(); void on_removeURLSeed_button_clicked();
void handleCreationFailure(QString msg);
void handleCreationSuccess(QString path, const char* branch_path);
}; };
#endif #endif

View File

@@ -1,125 +0,0 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contact : chris@qbittorrent.org
*/
#ifndef DELETETHREAD_H
#define DELETETHREAD_H
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
#include <QMutexLocker>
#include <QPair>
#include "arborescence.h"
class subDeleteThread : public QThread {
Q_OBJECT
private:
QString save_path;
arborescence *arb;
bool abort;
public:
subDeleteThread(QObject *parent, QString saveDir, arborescence *arb) : QThread(parent), save_path(saveDir), arb(arb), abort(false){}
~subDeleteThread(){
abort = true;
wait();
}
signals:
// For subthreads
void deletionSuccessST(subDeleteThread* st);
void deletionFailureST(subDeleteThread* st);
protected:
void run(){
if(arb->removeFromFS(save_path))
emit deletionSuccessST(this);
else
emit deletionFailureST(this);
delete arb;
}
};
class deleteThread : public QThread {
Q_OBJECT
private:
QList<QPair<QString, arborescence*> > torrents_list;
QMutex mutex;
QWaitCondition condition;
bool abort;
QList<subDeleteThread*> subThreads;
public:
deleteThread(QObject* parent) : QThread(parent), abort(false){}
~deleteThread(){
mutex.lock();
abort = true;
condition.wakeOne();
mutex.unlock();
qDeleteAll(subThreads);
wait();
}
void deleteTorrent(QString saveDir, arborescence *arb){
qDebug("deleteThread called");
QMutexLocker locker(&mutex);
torrents_list << QPair<QString, arborescence*>(saveDir, arb);
if(!isRunning()){
start();
}else{
condition.wakeOne();
}
}
protected:
void run(){
forever{
if(abort)
return;
mutex.lock();
if(torrents_list.size() != 0){
QPair<QString, arborescence *> torrent = torrents_list.takeFirst();
mutex.unlock();
subDeleteThread *st = new subDeleteThread(0, torrent.first, torrent.second);
subThreads << st;
connect(st, SIGNAL(deletionSuccessST(subDeleteThread*)), this, SLOT(deleteSubThread(subDeleteThread*)));
connect(st, SIGNAL(deletionFailureST(subDeleteThread*)), this, SLOT(deleteSubThread(subDeleteThread*)));
st->start();
}else{
condition.wait(&mutex);
mutex.unlock();
}
}
}
protected slots:
void deleteSubThread(subDeleteThread* st){
int index = subThreads.indexOf(st);
Q_ASSERT(index != -1);
subThreads.removeAt(index);
delete st;
}
};
#endif

View File

@@ -21,185 +21,6 @@
<property name="margin" > <property name="margin" >
<number>0</number> <number>0</number>
</property> </property>
<item>
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin" >
<number>0</number>
</property>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="lbl_DLSpeed" >
<property name="text" >
<string>Total DL Speed:</string>
</property>
<property name="alignment" >
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item>
<widget class="QLCDNumber" name="LCD_DownSpeed" >
<property name="autoFillBackground" >
<bool>true</bool>
</property>
<property name="frameShadow" >
<enum>QFrame::Raised</enum>
</property>
<property name="smallDecimalPoint" >
<bool>false</bool>
</property>
<property name="numDigits" >
<number>6</number>
</property>
<property name="segmentStyle" >
<enum>QLCDNumber::Flat</enum>
</property>
<property name="value" stdset="0" >
<double>0.000000000000000</double>
</property>
<property name="intValue" stdset="0" >
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="unitDL" >
<property name="text" >
<string>KiB/s</string>
</property>
<property name="alignment" >
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label" >
<property name="text" >
<string>Session ratio: </string>
</property>
<property name="alignment" >
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item>
<widget class="QLCDNumber" name="LCD_Ratio" >
<property name="autoFillBackground" >
<bool>true</bool>
</property>
<property name="numDigits" >
<number>4</number>
</property>
<property name="segmentStyle" >
<enum>QLCDNumber::Flat</enum>
</property>
<property name="value" stdset="0" >
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lbl_ratio_icon" >
<property name="text" >
<string/>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="lbl_UPSpeed" >
<property name="text" >
<string>Total UP Speed:</string>
</property>
<property name="alignment" >
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item>
<widget class="QLCDNumber" name="LCD_UpSpeed" >
<property name="autoFillBackground" >
<bool>true</bool>
</property>
<property name="smallDecimalPoint" >
<bool>false</bool>
</property>
<property name="numDigits" >
<number>6</number>
</property>
<property name="segmentStyle" >
<enum>QLCDNumber::Flat</enum>
</property>
<property name="value" stdset="0" >
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="unitUP" >
<property name="text" >
<string>KiB/s</string>
</property>
<property name="alignment" >
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item> <item>
<widget class="QTreeView" name="downloadList" > <widget class="QTreeView" name="downloadList" >
<property name="minimumSize" > <property name="minimumSize" >
@@ -227,79 +48,6 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<widget class="QTabWidget" name="tabBottom" >
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>142</height>
</size>
</property>
<property name="tabPosition" >
<enum>QTabWidget::West</enum>
</property>
<property name="currentIndex" >
<number>0</number>
</property>
<widget class="QWidget" name="log_tab" >
<attribute name="title" >
<string>Log</string>
</attribute>
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin" >
<number>9</number>
</property>
<item>
<widget class="QTextBrowser" name="infoBar" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>7</hsizetype>
<vsizetype>7</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>120</height>
</size>
</property>
<property name="contextMenuPolicy" >
<enum>Qt::CustomContextMenu</enum>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="filter_tab" >
<attribute name="title" >
<string>IP filter</string>
</attribute>
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin" >
<number>9</number>
</property>
<item>
<widget class="QTextBrowser" name="textBlockedUsers" >
<property name="maximumSize" >
<size>
<width>16777215</width>
<height>123</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout> </layout>
<action name="actionStart" > <action name="actionStart" >
<property name="text" > <property name="text" >
@@ -316,11 +64,6 @@
<string>Delete</string> <string>Delete</string>
</property> </property>
</action> </action>
<action name="actionClearLog" >
<property name="text" >
<string>Clear</string>
</property>
</action>
<action name="actionPreview_file" > <action name="actionPreview_file" >
<property name="text" > <property name="text" >
<string>Preview file</string> <string>Preview file</string>
@@ -346,7 +89,99 @@
<string>Torrent Properties</string> <string>Torrent Properties</string>
</property> </property>
</action> </action>
<action name="actionOpen_destination_folder" >
<property name="icon" >
<iconset resource="icons.qrc" >
<normaloff>:/Icons/folder.png</normaloff>:/Icons/folder.png</iconset>
</property>
<property name="text" >
<string>Open destination folder</string>
</property>
</action>
<action name="actionHOSColName" >
<property name="text" >
<string>Name</string>
</property>
</action>
<action name="actionHOSColSize" >
<property name="text" >
<string>Size</string>
</property>
</action>
<action name="actionHOSColProgress" >
<property name="text" >
<string>Progress</string>
</property>
</action>
<action name="actionHOSColDownSpeed" >
<property name="text" >
<string>DLSpeed</string>
</property>
</action>
<action name="actionHOSColUpSpeed" >
<property name="text" >
<string>UpSpeed</string>
</property>
</action>
<action name="actionHOSColSeedersLeechers" >
<property name="text" >
<string>Seeds/Leechs</string>
</property>
</action>
<action name="actionHOSColRatio" >
<property name="text" >
<string>Ratio</string>
</property>
</action>
<action name="actionHOSColEta" >
<property name="text" >
<string>ETA</string>
</property>
</action>
<action name="actionBuy_it" >
<property name="icon" >
<iconset resource="icons.qrc" >
<normaloff>:/Icons/money.png</normaloff>:/Icons/money.png</iconset>
</property>
<property name="text" >
<string>Buy it</string>
</property>
</action>
<action name="actionHOSColPriority" >
<property name="text" >
<string>Priority</string>
</property>
</action>
<action name="actionIncreasePriority" >
<property name="icon" >
<iconset resource="icons.qrc" >
<normaloff>:/Icons/skin/increase.png</normaloff>:/Icons/skin/increase.png</iconset>
</property>
<property name="text" >
<string>Increase priority</string>
</property>
</action>
<action name="actionDecreasePriority" >
<property name="icon" >
<iconset resource="icons.qrc" >
<normaloff>:/Icons/skin/decrease.png</normaloff>:/Icons/skin/decrease.png</iconset>
</property>
<property name="text" >
<string>Decrease priority</string>
</property>
</action>
<action name="actionForce_recheck" >
<property name="icon" >
<iconset resource="icons.qrc" >
<normaloff>:/Icons/gear.png</normaloff>:/Icons/gear.png</iconset>
</property>
<property name="text" >
<string>Force recheck</string>
</property>
</action>
</widget> </widget>
<resources/> <resources>
<include location="icons.qrc" />
</resources>
<connections/> <connections/>
</ui> </ui>

View File

@@ -21,43 +21,50 @@
#include "downloadThread.h" #include "downloadThread.h"
#include <iostream> #include <iostream>
#include <cc++/common.h> #include <QSettings>
#include <stdio.h>
QString subDownloadThread::errorCodeToString(int status) { #define MAX_THREADS 3
// http://curl.rtin.bz/libcurl/c/libcurl-errors.html
QString subDownloadThread::errorCodeToString(CURLcode status) {
switch(status){ switch(status){
case 1://ost::URLStream::errUnreachable: case CURLE_FTP_CANT_GET_HOST:
case CURLE_COULDNT_RESOLVE_HOST:
return tr("Host is unreachable"); return tr("Host is unreachable");
case 2://ost::URLStream::errMissing: case CURLE_READ_ERROR:
case CURLE_FILE_COULDNT_READ_FILE:
return tr("File was not found (404)"); return tr("File was not found (404)");
case 3://ost::URLStream::errDenied: case CURLE_FTP_ACCESS_DENIED:
case CURLE_LOGIN_DENIED:
case CURLE_FTP_USER_PASSWORD_INCORRECT:
return tr("Connection was denied"); return tr("Connection was denied");
case 4://ost::URLStream::errInvalid: case CURLE_URL_MALFORMAT:
return tr("Url is invalid"); return tr("Url is invalid");
case 5://ost::URLStream::errForbidden: case CURLE_COULDNT_RESOLVE_PROXY:
return tr("Connection forbidden (403)"); return tr("Could not resolve proxy");
case 6://ost::URLStream::errUnauthorized: //case 5:
return tr("Connection was not authorized (401)"); // return tr("Connection forbidden (403)");
case 7://ost::URLStream::errRelocated: //case 6:
return tr("Content has moved (301)"); // return tr("Connection was not authorized (401)");
case 8://ost::URLStream::errFailure: //case 7:
// return tr("Content has moved (301)");
case CURLE_COULDNT_CONNECT:
return tr("Connection failure"); return tr("Connection failure");
case 9://ost::URLStream::errTimeout: case CURLE_OPERATION_TIMEOUTED:
return tr("Connection was timed out"); return tr("Connection was timed out");
case 10://ost::URLStream::errInterface: case CURLE_INTERFACE_FAILED:
return tr("Incorrect network interface"); return tr("Incorrect network interface");
default: default:
return tr("Unknown error"); return tr("Unknown error");
} }
} }
subDownloadThread::subDownloadThread(QObject *parent, QString url) : QThread(parent), url(url), abort(false){ subDownloadThread::subDownloadThread(QObject *parent, QString url) : QThread(parent), url(url), abort(false){}
url_stream = new ost::URLStream();
}
subDownloadThread::~subDownloadThread(){ subDownloadThread::~subDownloadThread(){
abort = true; abort = true;
wait(); wait();
delete url_stream;
} }
void subDownloadThread::run(){ void subDownloadThread::run(){
@@ -68,38 +75,69 @@ void subDownloadThread::run(){
filePath = tmpfile->fileName(); filePath = tmpfile->fileName();
} }
delete tmpfile; delete tmpfile;
QFile dest_file(filePath); FILE *f = fopen(filePath.toUtf8().data(), "wb");
if(!dest_file.open(QIODevice::WriteOnly | QIODevice::Text)){ if(!f) {
std::cerr << "Error: could't create temporary file: " << (const char*)filePath.toUtf8() << '\n'; std::cerr << "couldn't open destination file" << "\n";
return; return;
} }
ost::URLStream::Error status = url_stream->get((const char*)url.toUtf8()); CURL *curl;
if(status){ CURLcode res = (CURLcode)-1;
// Failure curl = curl_easy_init();
QString error_msg = errorCodeToString((int)status); if(curl) {
qDebug("Download failed for %s, reason: %s", (const char*)url.toUtf8(), (const char*)error_msg.toUtf8()); std::string c_url = url.toUtf8().data();
url_stream->close(); curl_easy_setopt(curl, CURLOPT_URL, c_url.c_str());
emit downloadFailureST(this, url, error_msg); // SSL support
return; curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
} curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
qDebug("Downloading %s...", (const char*)url.toUtf8()); // PROXY SUPPORT
char cbuf[1024]; QSettings settings("qBittorrent", "qBittorrent");
int len; int intValue = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxyType"), 0).toInt();
while(!url_stream->eof()) { if(intValue > 0) {
url_stream->read(cbuf, sizeof(cbuf)); // Proxy enabled
len = url_stream->gcount(); QString IP = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/IP"), "0.0.0.0").toString();
if(len > 0) QString port = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Port"), 8080).toString();
dest_file.write(cbuf, len); qDebug("Using proxy: %s", (IP+QString(":")+port).toUtf8().data());
if(abort){ curl_easy_setopt(curl, CURLOPT_PROXYPORT, (IP+QString(":")+port).toUtf8().data());
dest_file.close(); // Default proxy type is HTTP, we must change if it is SOCKS5
url_stream->close(); if(intValue%2==0) {
return; qDebug("Proxy is SOCKS5, not HTTP");
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
}
// Authentication?
if(intValue > 2) {
qDebug("Proxy requires authentication, authenticating");
QString username = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Username"), QString()).toString();
QString password = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Password"), QString()).toString();
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, (username+QString(":")+password).toUtf8().data());
}
} }
// We have to define CURLOPT_WRITEFUNCTION or it will crash on windows
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, f);
// Verbose
//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
// No progress info (we don't use it)
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
// Redirections
curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, -1);
qDebug("Downloading %s", url.toUtf8().data());
if(!abort)
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
fclose(f);
if(abort)
return;
if(res) {
emit downloadFailureST(this, url, errorCodeToString(res));
} else {
emit downloadFinishedST(this, url, filePath);
}
} else {
std::cerr << "Could not initialize CURL" << "\n";
} }
dest_file.close();
url_stream->close();
emit downloadFinishedST(this, url, filePath);
qDebug("download completed here: %s", (const char*)filePath.toUtf8());
} }
/** Download Thread **/ /** Download Thread **/
@@ -117,9 +155,7 @@ downloadThread::~downloadThread(){
void downloadThread::downloadUrl(QString url){ void downloadThread::downloadUrl(QString url){
QMutexLocker locker(&mutex); QMutexLocker locker(&mutex);
if(downloading_list.contains(url)) return; urls_queue.enqueue(url);
url_list << url;
downloading_list << url;
if(!isRunning()){ if(!isRunning()){
start(); start();
}else{ }else{
@@ -132,8 +168,8 @@ void downloadThread::run(){
if(abort) if(abort)
return; return;
mutex.lock(); mutex.lock();
if(url_list.size() != 0){ if(!urls_queue.empty() && subThreads.size() < MAX_THREADS){
QString url = url_list.takeFirst(); QString url = urls_queue.dequeue();
mutex.unlock(); mutex.unlock();
subDownloadThread *st = new subDownloadThread(0, url); subDownloadThread *st = new subDownloadThread(0, url);
subThreads << st; subThreads << st;
@@ -154,9 +190,9 @@ void downloadThread::propagateDownloadedFile(subDownloadThread* st, QString url,
delete st; delete st;
emit downloadFinished(url, path); emit downloadFinished(url, path);
mutex.lock(); mutex.lock();
index = downloading_list.indexOf(url); if(!urls_queue.empty()) {
Q_ASSERT(index != -1); condition.wakeOne();
downloading_list.removeAt(index); }
mutex.unlock(); mutex.unlock();
} }
@@ -167,8 +203,8 @@ void downloadThread::propagateDownloadFailure(subDownloadThread* st, QString url
delete st; delete st;
emit downloadFailure(url, reason); emit downloadFailure(url, reason);
mutex.lock(); mutex.lock();
index = downloading_list.indexOf(url); if(!urls_queue.empty()) {
Q_ASSERT(index != -1); condition.wakeOne();
downloading_list.removeAt(index); }
mutex.unlock(); mutex.unlock();
} }

View File

@@ -29,22 +29,19 @@
#include <QMutexLocker> #include <QMutexLocker>
#include <QWaitCondition> #include <QWaitCondition>
#include <QStringList> #include <QStringList>
#include <curl/curl.h>
namespace ost { #include <QQueue>
class URLStream;
}
class subDownloadThread : public QThread { class subDownloadThread : public QThread {
Q_OBJECT Q_OBJECT
private: private:
QString url; QString url;
ost::URLStream *url_stream;
bool abort; bool abort;
public: public:
subDownloadThread(QObject *parent, QString url); subDownloadThread(QObject *parent, QString url);
~subDownloadThread(); ~subDownloadThread();
QString errorCodeToString(int status); QString errorCodeToString(CURLcode status);
signals: signals:
// For subthreads // For subthreads
@@ -59,8 +56,7 @@ class downloadThread : public QThread {
Q_OBJECT Q_OBJECT
private: private:
QStringList url_list; QQueue<QString> urls_queue;
QStringList downloading_list;
QMutex mutex; QMutex mutex;
QWaitCondition condition; QWaitCondition condition;
bool abort; bool abort;
@@ -76,13 +72,13 @@ class downloadThread : public QThread {
~downloadThread(); ~downloadThread();
void downloadUrl(QString url); void downloadUrl(QString url);
void setProxy(QString IP, int port, QString username, QString password);
protected: protected:
void run(); void run();
protected slots: protected slots:
void propagateDownloadedFile(subDownloadThread* st, QString url, QString path); void propagateDownloadedFile(subDownloadThread* st, QString url, QString path);
void propagateDownloadFailure(subDownloadThread* st, QString url, QString reason); void propagateDownloadFailure(subDownloadThread* st, QString url, QString reason);
}; };

View File

@@ -33,13 +33,12 @@
#include <QTime> #include <QTime>
#include <QMenu> #include <QMenu>
DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession) : parent(parent), BTSession(BTSession), delayedSorting(false), nbTorrents(0) { DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession) : parent(parent), BTSession(BTSession), nbTorrents(0) {
setupUi(this); setupUi(this);
// Setting icons // Setting icons
actionStart->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/play.png"))); actionStart->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/play.png")));
actionPause->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/pause.png"))); actionPause->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/pause.png")));
actionDelete->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete.png"))); actionDelete->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete.png")));
actionClearLog->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete.png")));
actionPreview_file->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/preview.png"))); actionPreview_file->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/preview.png")));
actionSet_upload_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png"))); actionSet_upload_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png")));
actionSet_download_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png"))); actionSet_download_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png")));
@@ -47,11 +46,9 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
actionTorrent_Properties->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/properties.png"))); actionTorrent_Properties->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/properties.png")));
// tabBottom->setTabIcon(0, QIcon(QString::fromUtf8(":/Icons/log.png"))); // tabBottom->setTabIcon(0, QIcon(QString::fromUtf8(":/Icons/log.png")));
// tabBottom->setTabIcon(1, QIcon(QString::fromUtf8(":/Icons/filter.png"))); // tabBottom->setTabIcon(1, QIcon(QString::fromUtf8(":/Icons/filter.png")));
// Set default ratio
lbl_ratio_icon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/stare.png")));
// Set Download list model // Set Download list model
DLListModel = new QStandardItemModel(0,9); DLListModel = new QStandardItemModel(0,10);
DLListModel->setHeaderData(NAME, Qt::Horizontal, tr("Name", "i.e: file name")); DLListModel->setHeaderData(NAME, Qt::Horizontal, tr("Name", "i.e: file name"));
DLListModel->setHeaderData(SIZE, Qt::Horizontal, tr("Size", "i.e: file size")); DLListModel->setHeaderData(SIZE, Qt::Horizontal, tr("Size", "i.e: file size"));
DLListModel->setHeaderData(PROGRESS, Qt::Horizontal, tr("Progress", "i.e: % downloaded")); DLListModel->setHeaderData(PROGRESS, Qt::Horizontal, tr("Progress", "i.e: % downloaded"));
@@ -60,20 +57,17 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
DLListModel->setHeaderData(SEEDSLEECH, Qt::Horizontal, tr("Seeds/Leechs", "i.e: full/partial sources")); DLListModel->setHeaderData(SEEDSLEECH, Qt::Horizontal, tr("Seeds/Leechs", "i.e: full/partial sources"));
DLListModel->setHeaderData(RATIO, Qt::Horizontal, tr("Ratio")); DLListModel->setHeaderData(RATIO, Qt::Horizontal, tr("Ratio"));
DLListModel->setHeaderData(ETA, Qt::Horizontal, tr("ETA", "i.e: Estimated Time of Arrival / Time left")); DLListModel->setHeaderData(ETA, Qt::Horizontal, tr("ETA", "i.e: Estimated Time of Arrival / Time left"));
DLListModel->setHeaderData(PRIORITY, Qt::Horizontal, tr("Priority"));
downloadList->setModel(DLListModel); downloadList->setModel(DLListModel);
DLDelegate = new DLListDelegate(downloadList); DLDelegate = new DLListDelegate(downloadList);
downloadList->setItemDelegate(DLDelegate); downloadList->setItemDelegate(DLDelegate);
// Hide priority column
downloadList->hideColumn(PRIORITY);
// Hide hash column // Hide hash column
downloadList->hideColumn(HASH); downloadList->hideColumn(HASH);
loadHiddenColumns();
connect(BTSession, SIGNAL(addedTorrent(QString, QTorrentHandle&, bool)), this, SLOT(torrentAdded(QString, QTorrentHandle&, bool))); connect(BTSession, SIGNAL(torrentFinishedChecking(QTorrentHandle&)), this, SLOT(sortProgressColumn(QTorrentHandle&)));
connect(BTSession, SIGNAL(duplicateTorrent(QString)), this, SLOT(torrentDuplicate(QString)));
connect(BTSession, SIGNAL(invalidTorrent(QString)), this, SLOT(torrentCorrupted(QString)));
connect(BTSession, SIGNAL(portListeningFailure()), this, SLOT(portListeningFailure()));
connect(BTSession, SIGNAL(peerBlocked(QString)), this, SLOT(addLogPeerBlocked(const QString)));
connect(BTSession, SIGNAL(fastResumeDataRejected(QString)), this, SLOT(addFastResumeRejectedAlert(QString)));
connect(BTSession, SIGNAL(aboutToDownloadFromUrl(QString)), this, SLOT(displayDownloadingUrlInfos(QString)));
connect(BTSession, SIGNAL(urlSeedProblem(QString, QString)), this, SLOT(addUrlSeedError(QString, QString)));
// Load last columns width for download list // Load last columns width for download list
if(!loadColWidthDLList()) { if(!loadColWidthDLList()) {
@@ -84,43 +78,57 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
downloadList->header()->setSortIndicatorShown(true); downloadList->header()->setSortIndicatorShown(true);
// Connecting Actions to slots // Connecting Actions to slots
connect(downloadList, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(notifyTorrentDoubleClicked(const QModelIndex&))); connect(downloadList, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(notifyTorrentDoubleClicked(const QModelIndex&)));
connect(downloadList->header(), SIGNAL(sectionPressed(int)), this, SLOT(sortDownloadList(int))); connect(downloadList->header(), SIGNAL(sectionPressed(int)), this, SLOT(toggleDownloadListSortOrder(int)));
connect(downloadList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayDLListMenu(const QPoint&))); connect(downloadList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayDLListMenu(const QPoint&)));
connect(infoBar, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayInfoBarMenu(const QPoint&))); downloadList->header()->setContextMenuPolicy(Qt::CustomContextMenu);
connect(downloadList->header(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayDLHoSMenu(const QPoint&)));
// Actions // Actions
connect(actionPause, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPause_triggered())); connect(actionPause, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPause_triggered()));
connect(actionStart, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionStart_triggered())); connect(actionStart, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionStart_triggered()));
connect(actionDelete, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_triggered())); connect(actionDelete, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_triggered()));
connect(actionIncreasePriority, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionIncreasePriority_triggered()));
connect(actionDecreasePriority, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDecreasePriority_triggered()));
connect(actionPreview_file, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPreview_file_triggered())); connect(actionPreview_file, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPreview_file_triggered()));
connect(actionDelete_Permanently, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_Permanently_triggered())); connect(actionDelete_Permanently, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_Permanently_triggered()));
connect(actionOpen_destination_folder, SIGNAL(triggered()), (GUI*)parent, SLOT(openDestinationFolder()));
connect(actionTorrent_Properties, SIGNAL(triggered()), this, SLOT(propertiesSelection())); connect(actionTorrent_Properties, SIGNAL(triggered()), this, SLOT(propertiesSelection()));
connect(actionForce_recheck, SIGNAL(triggered()), this, SLOT(forceRecheck()));
connect(actionBuy_it, SIGNAL(triggered()), (GUI*)parent, SLOT(goBuyPage()));
connect(actionHOSColName, SIGNAL(triggered()), this, SLOT(hideOrShowColumnName()));
connect(actionHOSColSize, SIGNAL(triggered()), this, SLOT(hideOrShowColumnSize()));
connect(actionHOSColProgress, SIGNAL(triggered()), this, SLOT(hideOrShowColumnProgress()));
connect(actionHOSColDownSpeed, SIGNAL(triggered()), this, SLOT(hideOrShowColumnDownSpeed()));
connect(actionHOSColUpSpeed, SIGNAL(triggered()), this, SLOT(hideOrShowColumnUpSpeed()));
connect(actionHOSColSeedersLeechers, SIGNAL(triggered()), this, SLOT(hideOrShowColumnSeedersLeechers()));
connect(actionHOSColRatio, SIGNAL(triggered()), this, SLOT(hideOrShowColumnRatio()));
connect(actionHOSColEta, SIGNAL(triggered()), this, SLOT(hideOrShowColumnEta()));
connect(actionHOSColPriority, SIGNAL(triggered()), this, SLOT(hideOrShowColumnPriority()));
// Set info Bar infos // Set info Bar infos
setInfoBar(tr("qBittorrent %1 started.", "e.g: qBittorrent v0.x started.").arg(QString::fromUtf8(""VERSION))); BTSession->addConsoleMessage(tr("qBittorrent %1 started.", "e.g: qBittorrent v0.x started.").arg(QString::fromUtf8(""VERSION)));
setInfoBar(tr("Be careful, sharing copyrighted material without permission is against the law."), QString::fromUtf8("red"));
qDebug("Download tab built"); qDebug("Download tab built");
} }
DownloadingTorrents::~DownloadingTorrents() { DownloadingTorrents::~DownloadingTorrents() {
saveColWidthDLList(); saveColWidthDLList();
saveHiddenColumns();
delete DLDelegate; delete DLDelegate;
delete DLListModel; delete DLListModel;
} }
void DownloadingTorrents::enablePriorityColumn(bool enable) {
if(enable) {
downloadList->showColumn(PRIORITY);
} else {
downloadList->hideColumn(PRIORITY);
}
}
void DownloadingTorrents::notifyTorrentDoubleClicked(const QModelIndex& index) { void DownloadingTorrents::notifyTorrentDoubleClicked(const QModelIndex& index) {
unsigned int row = index.row(); unsigned int row = index.row();
QString hash = getHashFromRow(row); QString hash = getHashFromRow(row);
emit torrentDoubleClicked(hash); emit torrentDoubleClicked(hash, false);
}
void DownloadingTorrents::addLogPeerBlocked(QString ip) {
static unsigned int nbLines = 0;
++nbLines;
if(nbLines > 200) {
textBlockedUsers->clear();
nbLines = 1;
}
textBlockedUsers->append(QString::fromUtf8("<font color='grey'>")+ QTime::currentTime().toString(QString::fromUtf8("hh:mm:ss")) + QString::fromUtf8("</font> - ")+tr("<font color='red'>%1</font> <i>was blocked</i>", "x.y.z.w was blocked").arg(ip));
} }
unsigned int DownloadingTorrents::getNbTorrentsInList() const { unsigned int DownloadingTorrents::getNbTorrentsInList() const {
@@ -130,14 +138,15 @@ unsigned int DownloadingTorrents::getNbTorrentsInList() const {
// Note: do not actually pause the torrent in BT session // Note: do not actually pause the torrent in BT session
void DownloadingTorrents::pauseTorrent(QString hash) { void DownloadingTorrents::pauseTorrent(QString hash) {
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
Q_ASSERT(row != -1); if(row == -1)
return;
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.0)); DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.0));
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.0)); DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.0));
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1)); DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
DLListModel->setData(DLListModel->index(row, NAME), QIcon(QString::fromUtf8(":/Icons/skin/paused.png")), Qt::DecorationRole); DLListModel->setData(DLListModel->index(row, NAME), QIcon(QString::fromUtf8(":/Icons/skin/paused.png")), Qt::DecorationRole);
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(QString::fromUtf8("0/0"))); DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(QString::fromUtf8("0/0")));
QTorrentHandle h = BTSession->getTorrentHandle(hash); QTorrentHandle h = BTSession->getTorrentHandle(hash);
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress())); //DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
setRowColor(row, QString::fromUtf8("red")); setRowColor(row, QString::fromUtf8("red"));
} }
@@ -146,29 +155,19 @@ QString DownloadingTorrents::getHashFromRow(unsigned int row) const {
return DLListModel->data(DLListModel->index(row, HASH)).toString(); return DLListModel->data(DLListModel->index(row, HASH)).toString();
} }
void DownloadingTorrents::setBottomTabEnabled(unsigned int index, bool b){
if(index and !b)
tabBottom->setCurrentIndex(0);
tabBottom->setTabEnabled(index, b);
}
// Show torrent properties dialog // Show torrent properties dialog
void DownloadingTorrents::showProperties(const QModelIndex &index) { void DownloadingTorrents::showProperties(const QModelIndex &index) {
int row = index.row(); showPropertiesFromHash(DLListModel->data(DLListModel->index(index.row(), HASH)).toString());
QString hash = DLListModel->data(DLListModel->index(row, HASH)).toString(); }
void DownloadingTorrents::showPropertiesFromHash(QString hash) {
QTorrentHandle h = BTSession->getTorrentHandle(hash); QTorrentHandle h = BTSession->getTorrentHandle(hash);
properties *prop = new properties(this, BTSession, h); properties *prop = new properties(this, BTSession, h);
connect(prop, SIGNAL(filteredFilesChanged(QString)), this, SLOT(updateFileSizeAndProgress(QString))); connect(prop, SIGNAL(filteredFilesChanged(QString)), this, SLOT(updateFileSizeAndProgress(QString)));
connect(prop, SIGNAL(trackersChanged(QString)), BTSession, SLOT(saveTrackerFile(QString)));
prop->show(); prop->show();
} }
void DownloadingTorrents::resumeTorrent(QString hash){
int row = getRowFromHash(hash);
Q_ASSERT(row != -1);
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/connecting.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey"));
}
// Remove a torrent from the download list but NOT from the BT Session // Remove a torrent from the download list but NOT from the BT Session
void DownloadingTorrents::deleteTorrent(QString hash) { void DownloadingTorrents::deleteTorrent(QString hash) {
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
@@ -181,27 +180,6 @@ void DownloadingTorrents::deleteTorrent(QString hash) {
emit unfinishedTorrentsNumberChanged(nbTorrents); emit unfinishedTorrentsNumberChanged(nbTorrents);
} }
// Update Info Bar information
void DownloadingTorrents::setInfoBar(QString info, QColor color) {
static unsigned int nbLines = 0;
++nbLines;
// Check log size, clear it if too big
if(nbLines > 200) {
infoBar->clear();
nbLines = 1;
}
qDebug("Color is %s", color.name().toUtf8().data());
infoBar->append(QString::fromUtf8("<font color='grey'>")+ QTime::currentTime().toString(QString::fromUtf8("hh:mm:ss")) + QString::fromUtf8("</font> - <font color='") + color.name() +QString::fromUtf8("'><i>") + info + QString::fromUtf8("</i></font>"));
}
void DownloadingTorrents::addFastResumeRejectedAlert(QString name) {
setInfoBar(tr("Fast resume data was rejected for torrent %1, checking again...").arg(name), QString::fromUtf8("red"));
}
void DownloadingTorrents::addUrlSeedError(QString url, QString msg) {
setInfoBar(tr("Url seed lookup failed for url: %1, message: %2").arg(url).arg(msg), QString::fromUtf8("red"));
}
void DownloadingTorrents::on_actionSet_download_limit_triggered() { void DownloadingTorrents::on_actionSet_download_limit_triggered() {
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes(); QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
QModelIndex index; QModelIndex index;
@@ -241,13 +219,23 @@ void DownloadingTorrents::propertiesSelection(){
} }
} }
void DownloadingTorrents::forceRecheck() {
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
QModelIndex index;
foreach(index, selectedIndexes){
if(index.column() == NAME){
QString hash = DLListModel->data(DLListModel->index(index.row(), HASH)).toString();
QTorrentHandle h = BTSession->getTorrentHandle(hash);
h.force_recheck();
}
}
}
void DownloadingTorrents::displayDLListMenu(const QPoint& pos) { void DownloadingTorrents::displayDLListMenu(const QPoint& pos) {
QMenu myDLLlistMenu(this); QMenu myDLLlistMenu(this);
QModelIndex index; QModelIndex index;
// Enable/disable pause/start action given the DL state // Enable/disable pause/start action given the DL state
QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes(); QModelIndexList selectedIndexes = downloadList->selectionModel()->selectedIndexes();
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QString previewProgram = settings.value(QString::fromUtf8("Preferences/general/MediaPlayer"), QString()).toString();
bool has_pause = false, has_start = false, has_preview = false; bool has_pause = false, has_start = false, has_preview = false;
foreach(index, selectedIndexes) { foreach(index, selectedIndexes) {
if(index.column() == NAME) { if(index.column() == NAME) {
@@ -267,7 +255,7 @@ void DownloadingTorrents::displayDLListMenu(const QPoint& pos) {
has_pause = true; has_pause = true;
} }
} }
if(!previewProgram.isEmpty() && BTSession->isFilePreviewPossible(hash) && !has_preview) { if(BTSession->isFilePreviewPossible(hash) && !has_preview) {
myDLLlistMenu.addAction(actionPreview_file); myDLLlistMenu.addAction(actionPreview_file);
has_preview = true; has_preview = true;
} }
@@ -281,14 +269,195 @@ void DownloadingTorrents::displayDLListMenu(const QPoint& pos) {
myDLLlistMenu.addAction(actionSet_download_limit); myDLLlistMenu.addAction(actionSet_download_limit);
myDLLlistMenu.addAction(actionSet_upload_limit); myDLLlistMenu.addAction(actionSet_upload_limit);
myDLLlistMenu.addSeparator(); myDLLlistMenu.addSeparator();
myDLLlistMenu.addAction(actionForce_recheck);
myDLLlistMenu.addSeparator();
myDLLlistMenu.addAction(actionOpen_destination_folder);
myDLLlistMenu.addAction(actionTorrent_Properties); myDLLlistMenu.addAction(actionTorrent_Properties);
if(BTSession->isQueueingEnabled()) {
myDLLlistMenu.addSeparator();
myDLLlistMenu.addAction(actionIncreasePriority);
myDLLlistMenu.addAction(actionDecreasePriority);
}
myDLLlistMenu.addSeparator();
myDLLlistMenu.addAction(actionBuy_it);
// Call menu // Call menu
// XXX: why mapToGlobal() is not enough? // XXX: why mapToGlobal() is not enough?
myDLLlistMenu.exec(mapToGlobal(pos)+QPoint(10,60)); myDLLlistMenu.exec(mapToGlobal(pos)+QPoint(10,35));
} }
void DownloadingTorrents::on_actionClearLog_triggered() {
infoBar->clear(); /*
* Hiding Columns functions
*/
// hide/show columns menu
void DownloadingTorrents::displayDLHoSMenu(const QPoint& pos){
QMenu hideshowColumn(this);
hideshowColumn.setTitle(tr("Hide or Show Column"));
int lastCol;
if(BTSession->isQueueingEnabled()) {
lastCol = PRIORITY;
} else {
lastCol = ETA;
}
for(int i=0; i <= lastCol; ++i) {
hideshowColumn.addAction(getActionHoSCol(i));
}
// Call menu
hideshowColumn.exec(mapToGlobal(pos)+QPoint(10,10));
}
// toggle hide/show a column
void DownloadingTorrents::hideOrShowColumn(int index) {
unsigned int nbVisibleColumns = 0;
unsigned int nbCols = DLListModel->columnCount();
// Count visible columns
for(unsigned int i=0; i<nbCols; ++i) {
if(!downloadList->isColumnHidden(i))
++nbVisibleColumns;
}
if(!downloadList->isColumnHidden(index)) {
// User wants to hide the column
// Is there at least one other visible column?
if(nbVisibleColumns <= 1) return;
// User can hide the column, do it.
downloadList->setColumnHidden(index, true);
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
--nbVisibleColumns;
} else {
// User want to display the column
downloadList->setColumnHidden(index, false);
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
++nbVisibleColumns;
}
//resize all others non-hidden columns
for(unsigned int i=0; i<nbCols; ++i) {
if(!downloadList->isColumnHidden(i)) {
downloadList->setColumnWidth(i, (int)ceil(downloadList->columnWidth(i)+(downloadList->columnWidth(index)/nbVisibleColumns)));
}
}
}
void DownloadingTorrents::hidePriorityColumn(bool hide) {
downloadList->setColumnHidden(PRIORITY, hide);
if(hide)
getActionHoSCol(PRIORITY)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
else
getActionHoSCol(PRIORITY)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
}
// save the hidden columns in settings
void DownloadingTorrents::saveHiddenColumns() {
QSettings settings("qBittorrent", "qBittorrent");
QStringList ishidden_list;
short nbColumns = DLListModel->columnCount()-1;
for(short i=0; i<nbColumns; ++i){
if(downloadList->isColumnHidden(i)) {
ishidden_list << QString::fromUtf8(misc::toString(0).c_str());
} else {
ishidden_list << QString::fromUtf8(misc::toString(1).c_str());
}
}
settings.setValue("DownloadListColsHoS", ishidden_list.join(" "));
}
// load the previous settings, and hide the columns
bool DownloadingTorrents::loadHiddenColumns() {
bool loaded = false;
QSettings settings("qBittorrent", "qBittorrent");
QString line = settings.value("DownloadListColsHoS", QString()).toString();
QStringList ishidden_list;
if(!line.isEmpty()) {
ishidden_list = line.split(' ');
if(ishidden_list.size() == DLListModel->columnCount()-1) {
unsigned int listSize = ishidden_list.size();
for(unsigned int i=0; i<listSize; ++i){
downloadList->header()->resizeSection(i, ishidden_list.at(i).toInt());
}
loaded = true;
}
}
for(int i=0; i<DLListModel->columnCount()-1; i++) {
if(loaded && ishidden_list.at(i) == "0") {
downloadList->setColumnHidden(i, true);
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
} else {
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
}
}
return loaded;
}
void DownloadingTorrents::hideOrShowColumnName() {
hideOrShowColumn(NAME);
}
void DownloadingTorrents::hideOrShowColumnSize() {
hideOrShowColumn(SIZE);
}
void DownloadingTorrents::hideOrShowColumnProgress() {
hideOrShowColumn(PROGRESS);
}
void DownloadingTorrents::hideOrShowColumnDownSpeed() {
hideOrShowColumn(DLSPEED);
}
void DownloadingTorrents::hideOrShowColumnUpSpeed() {
hideOrShowColumn(UPSPEED);
}
void DownloadingTorrents::hideOrShowColumnSeedersLeechers() {
hideOrShowColumn(SEEDSLEECH);
}
void DownloadingTorrents::hideOrShowColumnRatio() {
hideOrShowColumn(RATIO);
}
void DownloadingTorrents::hideOrShowColumnEta() {
hideOrShowColumn(ETA);
}
void DownloadingTorrents::hideOrShowColumnPriority() {
hideOrShowColumn(PRIORITY);
}
// getter, return the action hide or show whose id is index
QAction* DownloadingTorrents::getActionHoSCol(int index) {
switch(index) {
case NAME :
return actionHOSColName;
break;
case SIZE :
return actionHOSColSize;
break;
case PROGRESS :
return actionHOSColProgress;
break;
case DLSPEED :
return actionHOSColDownSpeed;
break;
case UPSPEED :
return actionHOSColUpSpeed;
break;
case SEEDSLEECH :
return actionHOSColSeedersLeechers;
break;
case RATIO :
return actionHOSColRatio;
break;
case ETA :
return actionHOSColEta;
break;
case PRIORITY :
return actionHOSColPriority;
break;
default :
return NULL;
}
} }
QStringList DownloadingTorrents::getSelectedTorrents(bool only_one) const{ QStringList DownloadingTorrents::getSelectedTorrents(bool only_one) const{
@@ -306,62 +475,10 @@ QStringList DownloadingTorrents::getSelectedTorrents(bool only_one) const{
return res; return res;
} }
void DownloadingTorrents::updateRatio() {
// Update ratio info
float ratio = 1.;
session_status sessionStatus = BTSession->getSessionStatus();
if(sessionStatus.total_payload_download == 0) {
if(sessionStatus.total_payload_upload == 0)
ratio = 1.;
else
ratio = 10.;
}else{
ratio = (double)sessionStatus.total_payload_upload / (double)sessionStatus.total_payload_download;
if(ratio > 10.)
ratio = 10.;
}
LCD_Ratio->display(QString(QByteArray::number(ratio, 'f', 1)));
if(ratio < 0.5) {
lbl_ratio_icon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/unhappy.png")));
}else{
if(ratio > 1.0) {
lbl_ratio_icon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/smile.png")));
}else{
lbl_ratio_icon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/stare.png")));
}
}
}
void DownloadingTorrents::displayInfoBarMenu(const QPoint& pos) {
// Log Menu
QMenu myLogMenu(this);
myLogMenu.addAction(actionClearLog);
// XXX: Why mapToGlobal() is not enough?
myLogMenu.exec(mapToGlobal(pos)+QPoint(44,305));
}
void DownloadingTorrents::sortProgressColumnDelayed() {
if(delayedSorting) {
sortDownloadListFloat(PROGRESS, delayedSortingOrder);
qDebug("Delayed sorting of progress column");
}
}
// get information from torrent handles and // get information from torrent handles and
// update download list accordingly // update download list accordingly
void DownloadingTorrents::updateDlList() { bool DownloadingTorrents::updateTorrent(QTorrentHandle h) {
// update global informations bool added = false;
LCD_UpSpeed->display(QString(QByteArray::number(BTSession->getPayloadUploadRate()/1024., 'f', 1))); // UP LCD
LCD_DownSpeed->display(QString(QByteArray::number(BTSession->getPayloadDownloadRate()/1024., 'f', 1))); // DL LCD
// browse handles
QStringList unfinishedTorrents = BTSession->getUnfinishedTorrents();
QString hash;
foreach(hash, unfinishedTorrents) {
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(!h.is_valid()){
qDebug("We have an invalid handle for: %s", qPrintable(hash));
continue;
}
try{ try{
QString hash = h.hash(); QString hash = h.hash();
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
@@ -369,77 +486,85 @@ void DownloadingTorrents::updateDlList() {
qDebug("Info: Could not find filename in download list, adding it..."); qDebug("Info: Could not find filename in download list, adding it...");
addTorrent(hash); addTorrent(hash);
row = getRowFromHash(hash); row = getRowFromHash(hash);
added = true;
} }
Q_ASSERT(row != -1); Q_ASSERT(row != -1);
// No need to update a paused torrent // Update Priority
if(h.is_paused()) continue; if(BTSession->isQueueingEnabled()) {
if(BTSession->getTorrentsToPauseAfterChecking().indexOf(hash) != -1) { DLListModel->setData(DLListModel->index(row, PRIORITY), QVariant((int)BTSession->getDlTorrentPriority(hash)));
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress())); if(h.is_queued()) {
continue; if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking) {
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole);
if(!downloadList->isColumnHidden(PROGRESS)) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
}
}else {
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/queued.png"))), Qt::DecorationRole);
if(!downloadList->isColumnHidden(ETA)) {
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
}
}
// Reset speeds and seeds/leech
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.));
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.));
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant("0/0"));
setRowColor(row, QString::fromUtf8("grey"));
return added;
}
} }
if(!downloadList->isColumnHidden(PROGRESS))
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
// No need to update a paused torrent
if(h.is_paused()) return added;
// Parse download state // Parse download state
// Setting download state // Setting download state
switch(h.state()) { switch(h.state()) {
case torrent_status::finished:
case torrent_status::seeding:
qDebug("A torrent that was in download tab just finished, moving it to finished tab");
BTSession->setUnfinishedTorrent(hash);
emit torrentFinished(hash);
deleteTorrent(hash);
continue;
case torrent_status::checking_files: case torrent_status::checking_files:
case torrent_status::queued_for_checking: case torrent_status::queued_for_checking:
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole); DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/time.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey")); setRowColor(row, QString::fromUtf8("grey"));
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
break;
case torrent_status::connecting_to_tracker:
if(h.download_payload_rate() > 0) {
// Display "Downloading" status when connecting if download speed > 0
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)BTSession->getETA(hash)));
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("green"));
}else{
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/connecting.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey"));
}
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)h.download_payload_rate()));
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)h.upload_payload_rate()));
break; break;
case torrent_status::downloading: case torrent_status::downloading:
case torrent_status::downloading_metadata: case torrent_status::downloading_metadata:
if(h.download_payload_rate() > 0) { if(h.download_payload_rate() > 0) {
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png"))), Qt::DecorationRole); DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png"))), Qt::DecorationRole);
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)BTSession->getETA(hash))); if(!downloadList->isColumnHidden(ETA)) {
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)BTSession->getETA(hash)));
}
setRowColor(row, QString::fromUtf8("green")); setRowColor(row, QString::fromUtf8("green"));
}else{ }else{
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/stalled.png"))), Qt::DecorationRole); DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/stalled.png"))), Qt::DecorationRole);
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1)); if(!downloadList->isColumnHidden(ETA)) {
setRowColor(row, QPalette::WindowText); DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
}
setRowColor(row, QApplication::palette().color(QPalette::WindowText));
}
if(!downloadList->isColumnHidden(DLSPEED)) {
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)h.download_payload_rate()));
}
if(!downloadList->isColumnHidden(UPSPEED)) {
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)h.upload_payload_rate()));
} }
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)h.download_payload_rate()));
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)h.upload_payload_rate()));
break; break;
default: default:
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1)); if(!downloadList->isColumnHidden(ETA)) {
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
}
} }
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(misc::toQString(h.num_seeds(), true)+QString::fromUtf8("/")+misc::toQString(h.num_peers() - h.num_seeds(), true))); if(!downloadList->isColumnHidden(SEEDSLEECH)) {
DLListModel->setData(DLListModel->index(row, RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash)))); DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(misc::toQString(h.num_seeds(), true)+QString::fromUtf8("/")+misc::toQString(h.num_peers() - h.num_seeds(), true)));
}catch(invalid_handle e) { }
continue; if(!downloadList->isColumnHidden(RATIO)) {
} DLListModel->setData(DLListModel->index(row, RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash))));
} }
}catch(invalid_handle e) {}
return added;
} }
void DownloadingTorrents::addTorrent(QString hash) { void DownloadingTorrents::addTorrent(QString hash) {
if(BTSession->isFinished(hash)){
BTSession->setUnfinishedTorrent(hash);
}
QTorrentHandle h = BTSession->getTorrentHandle(hash); QTorrentHandle h = BTSession->getTorrentHandle(hash);
int row = getRowFromHash(hash); int row = getRowFromHash(hash);
qDebug("DL: addTorrent(): %s, row: %d", (const char*)hash.toUtf8(), row);
if(row != -1) return; if(row != -1) return;
row = DLListModel->rowCount(); row = DLListModel->rowCount();
// Adding torrent to download list // Adding torrent to download list
@@ -449,18 +574,23 @@ void DownloadingTorrents::addTorrent(QString hash) {
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.)); DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.));
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.)); DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.));
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(QString::fromUtf8("0/0"))); DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(QString::fromUtf8("0/0")));
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1)); DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
if(BTSession->isQueueingEnabled())
DLListModel->setData(DLListModel->index(row, PRIORITY), QVariant((int)BTSession->getDlTorrentPriority(hash)));
DLListModel->setData(DLListModel->index(row, HASH), QVariant(hash)); DLListModel->setData(DLListModel->index(row, HASH), QVariant(hash));
// Pause torrent if it was paused last time // Pause torrent if it is
if(BTSession->isPaused(hash)) { if(h.is_paused()) {
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/paused.png"))), Qt::DecorationRole); DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/paused.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("red")); setRowColor(row, QString::fromUtf8("red"));
}else{ }else{
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/connecting.png"))), Qt::DecorationRole); DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/stalled.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey")); setRowColor(row, QString::fromUtf8("grey"));
} }
++nbTorrents; ++nbTorrents;
emit unfinishedTorrentsNumberChanged(nbTorrents); emit unfinishedTorrentsNumberChanged(nbTorrents);
// sort List
sortDownloadList();
} }
void DownloadingTorrents::sortDownloadListFloat(int index, Qt::SortOrder sortOrder) { void DownloadingTorrents::sortDownloadListFloat(int index, Qt::SortOrder sortOrder) {
@@ -509,27 +639,51 @@ void DownloadingTorrents::sortDownloadListString(int index, Qt::SortOrder sortOr
DLListModel->removeRows(0, nbRows_old); DLListModel->removeRows(0, nbRows_old);
} }
void DownloadingTorrents::sortDownloadList(int index, Qt::SortOrder startSortOrder, bool fromLoadColWidth) { void DownloadingTorrents::toggleDownloadListSortOrder(int index) {
qDebug("Called sort download list"); Qt::SortOrder sortOrder = Qt::AscendingOrder;
static Qt::SortOrder sortOrder = startSortOrder; qDebug("Toggling column sort order");
if(!fromLoadColWidth && downloadList->header()->sortIndicatorSection() == index) { if(downloadList->header()->sortIndicatorSection() == index) {
if(sortOrder == Qt::AscendingOrder) { sortOrder = (Qt::SortOrder)!(bool)downloadList->header()->sortIndicatorOrder();
sortOrder = Qt::DescendingOrder;
}else{
sortOrder = Qt::AscendingOrder;
}
} }
switch(index) {
case SIZE:
case ETA:
case UPSPEED:
case DLSPEED:
case PROGRESS:
case PRIORITY:
case RATIO:
sortDownloadListFloat(index, sortOrder);
break;
default:
sortDownloadListString(index, sortOrder);
}
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QString sortOrderLetter; QString sortOrderLetter;
if(sortOrder == Qt::AscendingOrder) if(sortOrder == Qt::AscendingOrder)
sortOrderLetter = QString::fromUtf8("a"); sortOrderLetter = QString::fromUtf8("a");
else else
sortOrderLetter = QString::fromUtf8("d"); sortOrderLetter = QString::fromUtf8("d");
if(fromLoadColWidth) { settings.setValue(QString::fromUtf8("DownloadListSortedCol"), misc::toQString(index)+sortOrderLetter);
// XXX: Why is this needed? }
if(sortOrder == Qt::DescendingOrder)
downloadList->header()->setSortIndicator(index, Qt::AscendingOrder); void DownloadingTorrents::sortProgressColumn(QTorrentHandle& h) {
else QString hash = h.hash();
downloadList->header()->setSortIndicator(index, Qt::DescendingOrder); int index = downloadList->header()->sortIndicatorSection();
if(index == PROGRESS) {
int row = getRowFromHash(hash);
if(row >= 0) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
Qt::SortOrder sortOrder = downloadList->header()->sortIndicatorOrder();
sortDownloadListFloat(index, sortOrder);
}
}
}
void DownloadingTorrents::sortDownloadList(int index, Qt::SortOrder sortOrder) {
if(index == -1) {
index = downloadList->header()->sortIndicatorSection();
sortOrder = downloadList->header()->sortIndicatorOrder();
} else { } else {
downloadList->header()->setSortIndicator(index, sortOrder); downloadList->header()->setSortIndicator(index, sortOrder);
} }
@@ -538,23 +692,13 @@ void DownloadingTorrents::sortDownloadList(int index, Qt::SortOrder startSortOrd
case ETA: case ETA:
case UPSPEED: case UPSPEED:
case DLSPEED: case DLSPEED:
sortDownloadListFloat(index, sortOrder); case PRIORITY:
break;
case PROGRESS: case PROGRESS:
if(fromLoadColWidth) { sortDownloadListFloat(index, sortOrder);
// Progress sorting must be delayed until files are checked (on startup)
delayedSorting = true;
qDebug("Delayed sorting of the progress column");
delayedSortingOrder = sortOrder;
}else{
sortDownloadListFloat(index, sortOrder);
}
break; break;
default: default:
sortDownloadListString(index, sortOrder); sortDownloadListString(index, sortOrder);
} }
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
settings.setValue(QString::fromUtf8("DownloadListSortedCol"), misc::toQString(index)+sortOrderLetter);
} }
// Save columns width in a file to remember them // Save columns width in a file to remember them
@@ -563,11 +707,26 @@ void DownloadingTorrents::saveColWidthDLList() const{
qDebug("Saving columns width in download list"); qDebug("Saving columns width in download list");
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QStringList width_list; QStringList width_list;
unsigned int nbColumns = DLListModel->columnCount()-1; QStringList new_width_list;
for(unsigned int i=0; i<nbColumns; ++i) { short nbColumns = DLListModel->columnCount()-1;
width_list << misc::toQString(downloadList->columnWidth(i)); QString line = settings.value("DownloadListColsWidth", QString()).toString();
if(!line.isEmpty()) {
width_list = line.split(' ');
} }
settings.setValue(QString::fromUtf8("DownloadListColsWidth"), width_list.join(QString::fromUtf8(" "))); for(short i=0; i<nbColumns; ++i){
if(downloadList->columnWidth(i)<1 && width_list.size() == DLListModel->columnCount()-1 && width_list.at(i).toInt()>=1) {
// load the former width
new_width_list << width_list.at(i);
} else if(downloadList->columnWidth(i)>=1) {
// usual case, save the current width
new_width_list << QString::fromUtf8(misc::toString(downloadList->columnWidth(i)).c_str());
} else {
// default width
downloadList->resizeColumnToContents(i);
new_width_list << QString::fromUtf8(misc::toString(downloadList->columnWidth(i)).c_str());
}
}
settings.setValue(QString::fromUtf8("DownloadListColsWidth"), new_width_list.join(QString::fromUtf8(" ")));
qDebug("Download list columns width saved"); qDebug("Download list columns width saved");
} }
@@ -588,7 +747,13 @@ bool DownloadingTorrents::loadColWidthDLList() {
for(unsigned int i=0; i<listSize; ++i) { for(unsigned int i=0; i<listSize; ++i) {
downloadList->header()->resizeSection(i, width_list.at(i).toInt()); downloadList->header()->resizeSection(i, width_list.at(i).toInt());
} }
qDebug("Download list columns width loaded");
return true;
}
void DownloadingTorrents::loadLastSortedColumn() {
// Loading last sorted column // Loading last sorted column
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QString sortedCol = settings.value(QString::fromUtf8("DownloadListSortedCol"), QString()).toString(); QString sortedCol = settings.value(QString::fromUtf8("DownloadListSortedCol"), QString()).toString();
if(!sortedCol.isEmpty()) { if(!sortedCol.isEmpty()) {
Qt::SortOrder sortOrder; Qt::SortOrder sortOrder;
@@ -598,55 +763,8 @@ bool DownloadingTorrents::loadColWidthDLList() {
sortOrder = Qt::AscendingOrder; sortOrder = Qt::AscendingOrder;
sortedCol = sortedCol.left(sortedCol.size()-1); sortedCol = sortedCol.left(sortedCol.size()-1);
int index = sortedCol.toInt(); int index = sortedCol.toInt();
sortDownloadList(index, sortOrder, true); sortDownloadList(index, sortOrder);
} }
qDebug("Download list columns width loaded");
return true;
}
// Called when a torrent is added
void DownloadingTorrents::torrentAdded(QString path, QTorrentHandle& h, bool fastResume) {
QString hash = h.hash();
if(BTSession->isFinished(hash)) {
return;
}
int row = DLListModel->rowCount();
// Adding torrent to download list
DLListModel->insertRow(row);
DLListModel->setData(DLListModel->index(row, NAME), QVariant(h.name()));
DLListModel->setData(DLListModel->index(row, SIZE), QVariant((qlonglong)h.actual_size()));
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)0.));
DLListModel->setData(DLListModel->index(row, UPSPEED), QVariant((double)0.));
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(QString::fromUtf8("0/0")));
DLListModel->setData(DLListModel->index(row, RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash))));
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
DLListModel->setData(DLListModel->index(row, HASH), QVariant(hash));
// Pause torrent if it was paused last time
// Not using isPaused function because torrents are paused after checking now
if(QFile::exists(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".paused"))) {
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/paused.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("red"));
}else{
DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/connecting.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey"));
}
if(!fastResume) {
setInfoBar(tr("'%1' added to download list.", "'/home/y/xxx.torrent' was added to download list.").arg(path));
}else{
setInfoBar(tr("'%1' resumed. (fast resume)", "'/home/y/xxx.torrent' was resumed. (fast resume)").arg(path));
}
++nbTorrents;
emit unfinishedTorrentsNumberChanged(nbTorrents);
}
// Called when trying to add a duplicate torrent
void DownloadingTorrents::torrentDuplicate(QString path) {
setInfoBar(tr("'%1' is already in download list.", "e.g: 'xxx.avi' is already in download list.").arg(path));
}
void DownloadingTorrents::torrentCorrupted(QString path) {
setInfoBar(tr("Unable to decode torrent file: '%1'", "e.g: Unable to decode torrent file: '/home/y/xxx.torrent'").arg(path), QString::fromUtf8("red"));
setInfoBar(tr("This file is either corrupted or this isn't a torrent."),QString::fromUtf8("red"));
} }
void DownloadingTorrents::updateFileSizeAndProgress(QString hash) { void DownloadingTorrents::updateFileSizeAndProgress(QString hash) {
@@ -654,13 +772,7 @@ void DownloadingTorrents::updateFileSizeAndProgress(QString hash) {
Q_ASSERT(row != -1); Q_ASSERT(row != -1);
QTorrentHandle h = BTSession->getTorrentHandle(hash); QTorrentHandle h = BTSession->getTorrentHandle(hash);
DLListModel->setData(DLListModel->index(row, SIZE), QVariant((qlonglong)h.actual_size())); DLListModel->setData(DLListModel->index(row, SIZE), QVariant((qlonglong)h.actual_size()));
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress())); //DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
}
// Called when we couldn't listen on any port
// in the given range.
void DownloadingTorrents::portListeningFailure() {
setInfoBar(tr("Couldn't listen on any of the given ports."), QString::fromUtf8("red"));
} }
// Set the color of a row in data model // Set the color of a row in data model
@@ -682,7 +794,3 @@ int DownloadingTorrents::getRowFromHash(QString hash) const{
} }
return -1; return -1;
} }
void DownloadingTorrents::displayDownloadingUrlInfos(QString url) {
setInfoBar(tr("Downloading '%1', please wait...", "e.g: Downloading 'xxx.torrent', please wait...").arg(url), QPalette::WindowText);
}

View File

@@ -38,9 +38,11 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
bittorrent *BTSession; bittorrent *BTSession;
DLListDelegate *DLDelegate; DLListDelegate *DLDelegate;
QStandardItemModel *DLListModel; QStandardItemModel *DLListModel;
bool delayedSorting;
unsigned int nbTorrents; unsigned int nbTorrents;
Qt::SortOrder delayedSortingOrder; void hideOrShowColumn(int index);
bool loadHiddenColumns();
void saveHiddenColumns();
QAction* getActionHoSCol(int index);
public: public:
DownloadingTorrents(QObject *parent, bittorrent *BTSession); DownloadingTorrents(QObject *parent, bittorrent *BTSession);
@@ -51,46 +53,47 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
QString getHashFromRow(unsigned int row) const; QString getHashFromRow(unsigned int row) const;
QStringList getSelectedTorrents(bool only_one=false) const; QStringList getSelectedTorrents(bool only_one=false) const;
unsigned int getNbTorrentsInList() const; unsigned int getNbTorrentsInList() const;
void enablePriorityColumn(bool enable);
signals: signals:
void unfinishedTorrentsNumberChanged(unsigned int); void unfinishedTorrentsNumberChanged(unsigned int);
void torrentDoubleClicked(QString hash); void torrentDoubleClicked(QString hash, bool finished);
void torrentFinished(QString hash);
protected slots: protected slots:
void addLogPeerBlocked(QString);
void addFastResumeRejectedAlert(QString);
void addUrlSeedError(QString url, QString msg);
void on_actionSet_download_limit_triggered(); void on_actionSet_download_limit_triggered();
void notifyTorrentDoubleClicked(const QModelIndex& index); void notifyTorrentDoubleClicked(const QModelIndex& index);
void on_actionSet_upload_limit_triggered(); void on_actionSet_upload_limit_triggered();
void displayDLListMenu(const QPoint& pos); void displayDLListMenu(const QPoint& pos);
void on_actionClearLog_triggered(); void displayDLHoSMenu(const QPoint&);
void displayInfoBarMenu(const QPoint& pos); void sortDownloadList(int index=-1, Qt::SortOrder startSortOrder=Qt::AscendingOrder);
void addTorrent(QString hash); void toggleDownloadListSortOrder(int index);
void sortDownloadList(int index, Qt::SortOrder startSortOrder=Qt::AscendingOrder, bool fromLoadColWidth=false);
void sortDownloadListFloat(int index, Qt::SortOrder sortOrder); void sortDownloadListFloat(int index, Qt::SortOrder sortOrder);
void sortDownloadListString(int index, Qt::SortOrder sortOrder); void sortDownloadListString(int index, Qt::SortOrder sortOrder);
void saveColWidthDLList() const; void saveColWidthDLList() const;
void torrentAdded(QString path, QTorrentHandle& h, bool fastResume);
void torrentDuplicate(QString path);
void torrentCorrupted(QString path);
void portListeningFailure();
void setRowColor(int row, QColor color); void setRowColor(int row, QColor color);
void displayDownloadingUrlInfos(QString url);
void showProperties(const QModelIndex &index); void showProperties(const QModelIndex &index);
void hideOrShowColumnName();
void hideOrShowColumnSize();
void hideOrShowColumnProgress();
void hideOrShowColumnDownSpeed();
void hideOrShowColumnUpSpeed();
void hideOrShowColumnSeedersLeechers();
void hideOrShowColumnRatio();
void hideOrShowColumnEta();
void hideOrShowColumnPriority();
void forceRecheck();
public slots: public slots:
void updateDlList(); bool updateTorrent(QTorrentHandle h);
void setInfoBar(QString info, QColor color=QPalette::WindowText);
void pauseTorrent(QString hash); void pauseTorrent(QString hash);
void resumeTorrent(QString hash);
void updateRatio();
void deleteTorrent(QString hash); void deleteTorrent(QString hash);
void setBottomTabEnabled(unsigned int index, bool b);
void propertiesSelection(); void propertiesSelection();
void sortProgressColumnDelayed();
void updateFileSizeAndProgress(QString hash); void updateFileSizeAndProgress(QString hash);
void showPropertiesFromHash(QString hash);
void hidePriorityColumn(bool hide);
void sortProgressColumn(QTorrentHandle& h);
void loadLastSortedColumn();
void addTorrent(QString hash);
}; };

View File

@@ -32,11 +32,6 @@
#include <QDropEvent> #include <QDropEvent>
#include <QInputDialog> #include <QInputDialog>
#ifdef HAVE_MAGICK
#include <Magick++.h>
using namespace Magick;
#endif
#ifdef HAVE_ZZIP #ifdef HAVE_ZZIP
#include <zzip/zzip.h> #include <zzip/zzip.h>
#endif #endif
@@ -250,11 +245,13 @@ void engineSelectDlg::setRowColor(int row, QString color){
bool engineSelectDlg::checkInstalled(QString plugin_name) const { bool engineSelectDlg::checkInstalled(QString plugin_name) const {
QProcess nova; QProcess nova;
QStringList params; QStringList params;
params << misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py";
params << "--supported_engines"; params << "--supported_engines";
nova.start(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py", params, QIODevice::ReadOnly); nova.start("python", params, QIODevice::ReadOnly);
nova.waitForStarted(); nova.waitForStarted();
nova.waitForFinished(); nova.waitForFinished();
QByteArray result = nova.readAll(); QByteArray result = nova.readAll();
result = result.replace("\r", "");
result = result.replace("\n", ""); result = result.replace("\n", "");
QList<QByteArray> plugins_list = result.split(','); QList<QByteArray> plugins_list = result.split(',');
return plugins_list.contains(plugin_name.toUtf8()); return plugins_list.contains(plugin_name.toUtf8());
@@ -280,11 +277,13 @@ void engineSelectDlg::loadSupportedSearchEngines(bool first) {
QStringList params; QStringList params;
// Ask nova core for the supported search engines // Ask nova core for the supported search engines
QProcess nova; QProcess nova;
params << misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py";
params << "--supported_engines"; params << "--supported_engines";
nova.start(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py", params, QIODevice::ReadOnly); nova.start("python", params, QIODevice::ReadOnly);
nova.waitForStarted(); nova.waitForStarted();
nova.waitForFinished(); nova.waitForFinished();
QByteArray result = nova.readAll(); QByteArray result = nova.readAll();
result = result.replace("\r", "");
result = result.replace("\n", ""); result = result.replace("\n", "");
qDebug("read: %s", result.data()); qDebug("read: %s", result.data());
QByteArray e; QByteArray e;
@@ -295,11 +294,13 @@ void engineSelectDlg::loadSupportedSearchEngines(bool first) {
installed_engines[en] = old_engines.value(en, true); installed_engines[en] = old_engines.value(en, true);
} }
params.clear(); params.clear();
params << misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py";
params << "--supported_engines_infos"; params << "--supported_engines_infos";
nova.start(misc::qBittorrentPath()+"search_engine"+QDir::separator()+"nova2.py", params, QIODevice::ReadOnly); nova.start("python", params, QIODevice::ReadOnly);
nova.waitForStarted(); nova.waitForStarted();
nova.waitForFinished(); nova.waitForFinished();
result = nova.readAll(); result = nova.readAll();
result = result.replace("\r", "");
result = result.replace("\n", ""); result = result.replace("\n", "");
qDebug("read: %s", result.data()); qDebug("read: %s", result.data());
unsigned int i = 0; unsigned int i = 0;
@@ -605,20 +606,6 @@ void engineSelectDlg::processDownloadedFile(QString url, QString filePath) {
if(url.endsWith("favicon.ico", Qt::CaseInsensitive)){ if(url.endsWith("favicon.ico", Qt::CaseInsensitive)){
// Icon downloaded // Icon downloaded
QImage fileIcon; QImage fileIcon;
#ifdef HAVE_MAGICK
try{
QFile::copy(filePath, filePath+".ico");
Image image(QDir::cleanPath(filePath+".ico").toUtf8().data());
// Convert to PNG since we can't read ICO format
image.magick("PNG");
// Resize to 16x16px
image.sample(Geometry(16, 16));
image.write(filePath.toUtf8().data());
QFile::remove(filePath+".ico");
}catch(Magick::Exception &error_){
qDebug("favicon conversion to PNG failure: %s", error_.what());
}
#endif
if(fileIcon.load(filePath)) { if(fileIcon.load(filePath)) {
QList<QTreeWidgetItem*> items = findItemsWithUrl(url); QList<QTreeWidgetItem*> items = findItemsWithUrl(url);
QTreeWidgetItem *item; QTreeWidgetItem *item;

95
src/eventmanager.cpp Normal file
View File

@@ -0,0 +1,95 @@
/*
* Copyright (C) 2007 by Ishan Arora & Christophe Dumez
* <ishan@qbittorrent.org>, <chris@qbittorrent.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "eventmanager.h"
#include "bittorrent.h"
#include <QDebug>
EventManager::EventManager(QObject *parent, bittorrent *BTSession)
: QObject(parent), BTSession(BTSession)
{
}
QList<QVariantMap> EventManager::getEventList() const {
return event_list.values();
}
void EventManager::addedTorrent(QTorrentHandle& h)
{
modifiedTorrent(h);
}
void EventManager::deletedTorrent(QString hash)
{
event_list.remove(hash);
}
void EventManager::modifiedTorrent(QTorrentHandle h)
{
QString hash = h.hash();
QVariantMap event;
if(h.is_paused()) {
event["state"] = QVariant("paused");
} else {
if(BTSession->isQueueingEnabled() && h.is_queued()) {
event["state"] = QVariant("queued");
} else {
switch(h.state())
{
case torrent_status::finished:
case torrent_status::seeding:
event["state"] = QVariant("seeding");
break;
case torrent_status::checking_files:
case torrent_status::queued_for_checking:
event["state"] = QVariant("checking");
break;
case torrent_status::allocating:
case torrent_status::downloading:
case torrent_status::downloading_metadata:
if(h.download_payload_rate() > 0)
event["state"] = QVariant("downloading");
else
event["state"] = QVariant("stalled");
break;
default:
qDebug("No status, should not happen!!! status is %d", h.state());
event["state"] = QVariant();
}
}
}
event["name"] = QVariant(h.name());
event["size"] = QVariant((qlonglong)h.actual_size());
if(!h.is_seed()) {
event["progress"] = QVariant(h.progress());
event["dlspeed"] = QVariant(h.download_payload_rate());
if(BTSession->isQueueingEnabled()) {
event["priority"] = QVariant(h.queue_position());
} else {
event["priority"] = -1;
}
}
event["upspeed"] = QVariant(h.upload_payload_rate());
event["seed"] = QVariant(h.is_seed());
event["hash"] = QVariant(hash);
event_list[hash] = event;
}

51
src/eventmanager.h Normal file
View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) 2007 by Ishan Arora & Christophe Dumez
* <ishan@qbittorrent.org>, <chris@qbittorrent.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef EVENTMANAGER_H
#define EVENTMANAGER_H
#include "qtorrenthandle.h"
#include <QHash>
#include <QVariant>
struct bittorrent;
class EventManager : public QObject
{
Q_OBJECT
private:
QHash<QString, QVariantMap> event_list;
bittorrent* BTSession;
protected:
void update(QVariantMap event);
public:
EventManager(QObject *parent, bittorrent* BTSession);
QList<QVariantMap> getEventList() const;
public slots:
void addedTorrent(QTorrentHandle& h);
void deletedTorrent(QString hash);
void modifiedTorrent(QTorrentHandle h);
};
#endif

388
src/filterParserThread.h Normal file
View File

@@ -0,0 +1,388 @@
/*
* Bittorrent Client using Qt4 and libtorrent.
* Copyright (C) 2006 Christophe Dumez
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contact : chris@qbittorrent.org
*/
#ifndef FILTERPARSERTHREAD_H
#define FILTERPARSERTHREAD_H
#include <QThread>
#include <QFile>
#include <QDataStream>
#include <QMessageBox>
#include <libtorrent/session.hpp>
#include <libtorrent/ip_filter.hpp>
using namespace libtorrent;
using namespace std;
// P2B Stuff
#include <string.h>
#ifdef Q_WS_WIN
#include <Winsock2.h>
#else
#include <arpa/inet.h>
#endif
// End of P2B stuff
class FilterParserThread : public QThread {
Q_OBJECT
private:
session *s;
ip_filter filter;
bool abort;
QString filePath;
protected:
void run(){
qDebug("Processing filter file");
if(filePath.endsWith(".dat", Qt::CaseInsensitive)) {
// eMule DAT file
parseDATFilterFile(filePath);
} else {
if(filePath.endsWith(".p2p", Qt::CaseInsensitive)) {
// PeerGuardian p2p file
parseP2PFilterFile(filePath);
} else {
if(filePath.endsWith(".p2p", Qt::CaseInsensitive)) {
// PeerGuardian p2p file
parseP2BFilterFile(filePath);
} else {
// Default: eMule DAT format
parseDATFilterFile(filePath);
}
}
}
s->set_ip_filter(filter);
qDebug("IP Filter thread: finished parsing, filter applied");
}
public:
FilterParserThread(QObject* parent, session *s) : QThread(parent), s(s), abort(false) {
}
~FilterParserThread(){
abort = true;
wait();
}
// Parser for eMule ip filter in DAT format
void parseDATFilterFile(QString filePath) {
const QRegExp is_ipv6(QString::fromUtf8("^[0-9a-f]{4}(:[0-9a-f]{4}){7}$"), Qt::CaseInsensitive, QRegExp::RegExp);
const QRegExp is_ipv4(QString::fromUtf8("^(([0-1]?[0-9]?[0-9])|(2[0-4][0-9])|(25[0-5]))(\\.(([0-1]?[0-9]?[0-9])|(2[0-4][0-9])|(25[0-5]))){3}$"), Qt::CaseInsensitive, QRegExp::RegExp);
QString strStartIP, strEndIP;
bool IPv4 = true;
QFile file(filePath);
if (file.exists()){
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("Couldn't open %1 in read mode.").arg(filePath));
return;
}
unsigned int nbLine = 0;
while (!file.atEnd() && !abort) {
++nbLine;
QByteArray line = file.readLine();
// Ignoring empty lines
line = line.trimmed();
if(line.isEmpty()) continue;
// Ignoring commented lines
if(line.startsWith('#') || line.startsWith("//")) continue;
// Line is not commented
QList<QByteArray> partsList = line.split(',');
unsigned int nbElem = partsList.size();
// IP Range can be splitted by a dash or a comma...
// Check if there is a dash in first part
QByteArray firstPart = partsList.at(0);
int nbAccess = 0;
if(firstPart.contains('-')) {
// Range is splitted by a dash
QList<QByteArray> IPs = firstPart.split('-');
if(IPs.size() != 2) {
qDebug("Ipfilter.dat: line %d is malformed.", nbLine);
continue;
}
strStartIP = IPs.at(0).trimmed();
strEndIP = IPs.at(1).trimmed();
// Check if IPs are correct
if(strStartIP.contains(is_ipv4) && strEndIP.contains(is_ipv4)) {
IPv4 = true;
} else {
if(strStartIP.contains(is_ipv6) && strEndIP.contains(is_ipv6)) {
IPv4 = false;
} else {
// Could not determine IP format
qDebug("Ipfilter.dat: line %d is malformed.", nbLine);
continue;
}
}
// Check if there is an access value (apparently not mandatory)
if(nbElem > 1) {
// There is possibly one
bool ok;
nbAccess = partsList.at(1).trimmed().toInt(&ok);
if(!ok){
nbAccess = 0;
}
}
} else {
// Range is probably splitted by a comma
unsigned int nbElem = partsList.size();
if(nbElem > 1) {
strStartIP = firstPart.trimmed();
strEndIP = partsList.at(1).trimmed();
// Check if IPs are correct
if(strStartIP.contains(is_ipv4) && strEndIP.contains(is_ipv4)) {
IPv4 = true;
} else {
if(strStartIP.contains(is_ipv6) && strEndIP.contains(is_ipv6)) {
IPv4 = false;
} else {
// Could not determine IP format
qDebug("Ipfilter.dat: line %d is malformed.", nbLine);
continue;
}
}
// Check if there is an access value (apparently not mandatory)
if(nbElem > 2) {
// There is possibly one
bool ok;
nbAccess = partsList.at(2).trimmed().toInt(&ok);
if(!ok){
nbAccess = 0;
}
}
}
}
if(nbAccess > 127) {
// Ignoring this rule because access value is too high
continue;
}
// Now Add to the filter
QStringList IP;
if(IPv4) {
//IPv4 addresses
IP = strStartIP.split('.');
address_v4 start((IP.at(0).toInt() << 24) + (IP.at(1).toInt() << 16) + (IP.at(2).toInt() << 8) + IP.at(3).toInt());
IP = strEndIP.split('.');
address_v4 last((IP.at(0).toInt() << 24) + (IP.at(1).toInt() << 16) + (IP.at(2).toInt() << 8) + IP.at(3).toInt());
// Apply to bittorrent session
filter.add_rule(start, last, ip_filter::blocked);
} else {
// IPv6, ex : 1fff:0000:0a88:85a3:0000:0000:ac1f:8001
IP = strStartIP.split(':');
address_v6 start = address_v6::from_string(strStartIP.remove(':', 0).toUtf8().data());
IP = strEndIP.split(':');
address_v6 last = address_v6::from_string(strEndIP.remove(':', 0).toUtf8().data());
// Apply to bittorrent session
filter.add_rule(start, last, ip_filter::blocked);
}
}
file.close();
}
}
// Parser for PeerGuardian ip filter in p2p format
void parseP2PFilterFile(QString filePath) {
const QRegExp is_ipv4(QString::fromUtf8("^(([0-1]?[0-9]?[0-9])|(2[0-4][0-9])|(25[0-5]))(\\.(([0-1]?[0-9]?[0-9])|(2[0-4][0-9])|(25[0-5]))){3}$"), Qt::CaseInsensitive, QRegExp::RegExp);
QFile file(filePath);
QStringList IP;
if (file.exists()){
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("Couldn't open %1 in read mode.").arg(filePath));
return;
}
unsigned int nbLine = 0;
while (!file.atEnd() && !abort) {
++nbLine;
QByteArray line = file.readLine();
// Ignoring empty lines
line = line.trimmed();
if(line.isEmpty()) continue;
// Ignoring commented lines
if(line.startsWith('#') || line.startsWith("//")) continue;
// Line is not commented
QList<QByteArray> partsList = line.split(':');
if(partsList.size() < 2){
qDebug("p2p file: line %d is malformed.", nbLine);
continue;
}
// Get IP range
QList<QByteArray> IPs = partsList.last().split('-');
if(IPs.size() != 2) {
qDebug("p2p file: line %d is malformed.", nbLine);
continue;
}
QString strStartIP = IPs.at(0).trimmed();
QString strEndIP = IPs.at(1).trimmed();
// Check IPs format (IPv4 only)
if(strStartIP.contains(is_ipv4) && strEndIP.contains(is_ipv4)) {
// IPv4
IP = strStartIP.split('.');
address_v4 start((IP.at(0).toInt() << 24) + (IP.at(1).toInt() << 16) + (IP.at(2).toInt() << 8) + IP.at(3).toInt());
IP = strEndIP.split('.');
address_v4 last((IP.at(0).toInt() << 24) + (IP.at(1).toInt() << 16) + (IP.at(2).toInt() << 8) + IP.at(3).toInt());
// Apply to bittorrent session
filter.add_rule(start, last, ip_filter::blocked);
} else {
qDebug("p2p file: line %d is malformed.", nbLine);
continue;
}
}
file.close();
}
}
int getlineInStream(QDataStream& stream, string& name, char delim) {
char c;
int total_read = 0;
int read;
do {
read = stream.readRawData(&c, 1);
total_read += read;
if(read > 0) {
if(c != delim) {
name += c;
} else {
// Delim found
return total_read;
}
}
} while(read > 0);
return total_read;
}
// Parser for PeerGuardian ip filter in p2p format
void parseP2BFilterFile(QString filePath) {
QFile file(filePath);
if (file.exists()){
if(!file.open(QIODevice::ReadOnly)){
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("Couldn't open %1 in read mode.").arg(filePath));
return;
}
QDataStream stream(&file);
// Read header
char buf[7];
unsigned char version;
if(
!stream.readRawData(buf, sizeof(buf)) ||
memcmp(buf, "\xFF\xFF\xFF\xFFP2B", 7) ||
!stream.readRawData((char*)&version, sizeof(version))
) {
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
return;
}
if(version==1 || version==2) {
qDebug ("p2b version 1 or 2");
unsigned int start, end;
string name;
while(getlineInStream(stream, name, '\0') && !abort) {
if(
!stream.readRawData((char*)&start, sizeof(start)) ||
!stream.readRawData((char*)&end, sizeof(end))
) {
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
return;
}
// Network byte order to Host byte order
// asio address_v4 contructor expects it
// that way
address_v4 first(ntohl(start));
address_v4 last(ntohl(end));
// Apply to bittorrent session
filter.add_rule(first, last, ip_filter::blocked);
}
}
else if(version==3) {
qDebug ("p2b version 3");
unsigned int namecount;
if(!stream.readRawData((char*)&namecount, sizeof(namecount))) {
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
return;
}
namecount=ntohl(namecount);
// Reading names although, we don't really care about them
for(unsigned int i=0; i<namecount; i++) {
string name;
if(!getlineInStream(stream, name, '\0')) {
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
return;
}
if(abort) return;
}
// Reading the ranges
unsigned int rangecount;
if(!stream.readRawData((char*)&rangecount, sizeof(rangecount))) {
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
return;
}
rangecount=ntohl(rangecount);
unsigned int name, start, end;
for(unsigned int i=0; i<rangecount; i++) {
if(
!stream.readRawData((char*)&name, sizeof(name)) ||
!stream.readRawData((char*)&start, sizeof(start)) ||
!stream.readRawData((char*)&end, sizeof(end))
) {
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
return;
}
// Network byte order to Host byte order
// asio address_v4 contructor expects it
// that way
address_v4 first(ntohl(start));
address_v4 last(ntohl(end));
// Apply to bittorrent session
filter.add_rule(first, last, ip_filter::blocked);
if(abort) return;
}
} else {
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
return;
}
file.close();
}
}
// Process ip filter file
// Supported formats:
// * eMule IP list (DAT): http://wiki.phoenixlabs.org/wiki/DAT_Format
// * PeerGuardian Text (P2P): http://wiki.phoenixlabs.org/wiki/P2P_Format
// * PeerGuardian Binary (P2B): http://wiki.phoenixlabs.org/wiki/P2B_Format
void processFilterFile(QString _filePath){
if(isRunning()) {
// Already parsing a filter, abort first
abort = true;
wait();
}
abort = false;
filePath = _filePath;
// Run it
start();
}
};
#endif

237
src/httpconnection.cpp Normal file
View File

@@ -0,0 +1,237 @@
/*
* Copyright (C) 2007 by Ishan Arora
* ishanarora@gmail.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "httpconnection.h"
#include "httpserver.h"
#include "eventmanager.h"
#include "json.h"
#include <QTcpSocket>
#include <QDateTime>
#include <QStringList>
#include <QHttpRequestHeader>
#include <QHttpResponseHeader>
#include <QFile>
#include <QDebug>
#include <QTemporaryFile>
HttpConnection::HttpConnection(QTcpSocket *socket, HttpServer *parent)
: QObject(parent), socket(socket), parent(parent)
{
socket->setParent(this);
connect(socket, SIGNAL(readyRead()), this, SLOT(read()));
connect(socket, SIGNAL(disconnected()), this, SLOT(deleteLater()));
}
HttpConnection::~HttpConnection()
{
delete socket;
}
void HttpConnection::processDownloadedFile(QString url, QString file_path) {
qDebug("URL %s successfully downloaded !", (const char*)url.toUtf8());
emit torrentReadyToBeDownloaded(file_path, false, url, false);
}
void HttpConnection::handleDownloadFailure(QString url, QString reason) {
std::cerr << "Could not download " << (const char*)url.toUtf8() << ", reason: " << (const char*)reason.toUtf8() << "\n";
}
void HttpConnection::read()
{
QByteArray input = socket->readAll();
/*qDebug(" -------");
qDebug("|REQUEST|");
qDebug(" -------"); */
//qDebug("%s", input.toAscii().constData());
if(input.size() > 100000) {
qDebug("Request too big");
generator.setStatusLine(400, "Bad Request");
write();
return;
}
parser.write(input);
if(parser.isError())
{
generator.setStatusLine(400, "Bad Request");
write();
}
else
if (parser.isParsable())
respond();
}
void HttpConnection::write()
{
QByteArray output = generator.toByteArray();
/*qDebug(" --------");
qDebug("|RESPONSE|");
qDebug(" --------");
qDebug()<<output;*/
socket->write(output);
socket->disconnectFromHost();
}
void HttpConnection::respond()
{
//qDebug("Respond called");
QStringList auth = parser.value("Authorization").split(" ", QString::SkipEmptyParts);
if (auth.size() != 2 || QString::compare(auth[0], "Basic", Qt::CaseInsensitive) != 0 || !parent->isAuthorized(auth[1].toUtf8()))
{
generator.setStatusLine(401, "Unauthorized");
generator.setValue("WWW-Authenticate", "Basic realm=\"you know what\"");
write();
return;
}
QString url = parser.url();
QStringList list = url.split('/', QString::SkipEmptyParts);
if (list.contains(".") || list.contains(".."))
{
respondNotFound();
return;
}
if (list.size() == 0)
list.append("index.html");
if (list.size() == 2)
{
if (list[0] == "json")
{
if (list[1] == "events")
{
respondJson();
return;
}
}
if (list[0] == "command")
{
QString command = list[1];
respondCommand(command);
generator.setStatusLine(200, "OK");
write();
return;
}
}
if (list[0] == "images")
list[0] = "Icons";
else
list.prepend("webui");
url = ":/" + list.join("/");
QFile file(url);
if(!file.open(QIODevice::ReadOnly))
{
respondNotFound();
return;
}
QString ext = list.last();
int index = ext.lastIndexOf('.') + 1;
if (index > 0)
ext.remove(0, index);
else
ext.clear();
QByteArray data = file.readAll();
generator.setStatusLine(200, "OK");
generator.setContentTypeByExt(ext);
generator.setMessage(data);
write();
}
void HttpConnection::respondNotFound()
{
generator.setStatusLine(404, "File not found");
write();
}
void HttpConnection::respondJson()
{
EventManager* manager = parent->eventManager();
QString string = json::toJson(manager->getEventList());
generator.setStatusLine(200, "OK");
generator.setContentTypeByExt("js");
generator.setMessage(string);
write();
}
void HttpConnection::respondCommand(QString command)
{
if(command == "download")
{
QString urls = parser.post("urls");
QStringList list = urls.split('\n');
foreach(QString url, list){
url = url.trimmed();
if(!url.isEmpty()){
qDebug("Downloading url: %s", (const char*)url.toUtf8());
emit UrlReadyToBeDownloaded(url);
}
}
return;
}
if(command == "upload")
{
QByteArray torrentfile = parser.torrent();
// XXX: Trick to get a unique filename
QString filePath;
QTemporaryFile *tmpfile = new QTemporaryFile();
if (tmpfile->open()) {
filePath = tmpfile->fileName();
}
delete tmpfile;
// write it to HD
QFile torrent(filePath);
if(torrent.open(QIODevice::WriteOnly)) {
torrent.write(torrentfile);
torrent.close();
}
emit torrentReadyToBeDownloaded(filePath, false, QString(), false);
return;
}
if(command == "resumeall") {
emit resumeAllTorrents();
return;
}
if(command == "pauseall") {
emit pauseAllTorrents();
return;
}
if(command == "resume") {
emit resumeTorrent(parser.post("hash"));
return;
}
if(command == "pause") {
emit pauseTorrent(parser.post("hash"));
return;
}
if(command == "delete") {
emit deleteTorrent(parser.post("hash"), false);
return;
}
if(command == "deletePerm") {
emit deleteTorrent(parser.post("hash"), true);
return;
}
if(command == "increasePrio") {
emit increasePrioTorrent(parser.post("hash"));
return;
}
if(command == "decreasePrio") {
emit decreasePrioTorrent(parser.post("hash"));
return;
}
}

71
src/httpconnection.h Normal file
View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2007 by Ishan Arora
* ishanarora@gmail.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef HTTPCONNECTION_H
#define HTTPCONNECTION_H
#include "httprequestparser.h"
#include "httpresponsegenerator.h"
#include <QObject>
class QTcpSocket;
class HttpServer;
class HttpConnection : public QObject
{
Q_OBJECT
private:
QTcpSocket *socket;
HttpServer *parent;
protected:
HttpRequestParser parser;
HttpResponseGenerator generator;
protected slots:
void write();
virtual void respond();
void respondJson();
void respondCommand(QString command);
void respondNotFound();
void processDownloadedFile(QString, QString);
void handleDownloadFailure(QString, QString);
public:
HttpConnection(QTcpSocket *socket, HttpServer *parent);
~HttpConnection();
private slots:
void read();
signals:
void UrlReadyToBeDownloaded(QString url);
void torrentReadyToBeDownloaded(QString, bool, QString, bool);
void deleteTorrent(QString hash, bool permanently);
void resumeTorrent(QString hash);
void pauseTorrent(QString hash);
void increasePrioTorrent(QString hash);
void decreasePrioTorrent(QString hash);
void resumeAllTorrents();
void pauseAllTorrents();
};
#endif

138
src/httprequestparser.cpp Normal file
View File

@@ -0,0 +1,138 @@
/*
* Copyright (C) 2007 by Ishan Arora
* ishanarora@gmail.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "httprequestparser.h"
#include <QUrl>
#include <QDebug>
HttpRequestParser::HttpRequestParser()
{
headerDone = false;
messageDone = false;
error = false;
}
HttpRequestParser::~HttpRequestParser()
{
}
bool HttpRequestParser::isParsable() const
{
return !error && headerDone && isValid() && (messageDone || !hasContentLength() || contentLength() == 0);
}
bool HttpRequestParser::isError() const
{
return error;
}
QString HttpRequestParser::url() const
{
return path;
}
QByteArray HttpRequestParser::message() const
{
if(isParsable())
return data;
return QByteArray();
}
QString HttpRequestParser::get(const QString key) const
{
return getMap[key];
}
QString HttpRequestParser::post(const QString key) const
{
return postMap[key];
}
QByteArray HttpRequestParser::torrent() const
{
return torrent_content;
}
void HttpRequestParser::write(QByteArray str)
{
while (!headerDone && str.size()>0)
{
int index = str.indexOf('\n') + 1;
if(index == 0)
{
data += str;
str.clear();
}
else
{
data += str.left(index);
str.remove(0, index);
if(data.right(4) == "\r\n\r\n")
{
QHttpRequestHeader::operator=(QHttpRequestHeader(data));
headerDone = true;
data.clear();
QUrl url = QUrl::fromEncoded(QHttpRequestHeader::path().toAscii());
path = url.path();
//() << path;
QListIterator<QPair<QString, QString> > i(url.queryItems());
while (i.hasNext())
{
QPair<QString, QString> pair = i.next();
getMap[pair.first] = pair.second;
//qDebug() << pair.first << "=" << get(pair.first);
}
}
}
}
if(!messageDone && str.size()>0)
{
if(hasContentLength())
{
data += str;
if(data.size() >= (int) contentLength())
{
data.resize(contentLength());
messageDone = true;
//parse POST data
if(contentType() == "application/x-www-form-urlencoded")
{
QUrl url;
url.setEncodedQuery(data);
QListIterator<QPair<QString, QString> > i(url.queryItems());
while (i.hasNext())
{
QPair<QString, QString> pair = i.next();
postMap[pair.first] = pair.second;
//qDebug() << pair.first << "=" << post(pair.first);
}
}
if(contentType() == "multipart/form-data")
{
//qDebug() << data.right(data.size()-data.indexOf("\r\n\r\n")-QByteArray("\r\n\r\n").size());
torrent_content = data.right(data.size()-data.indexOf("\r\n\r\n")-QByteArray("\r\n\r\n").size());
}
}
}
else
error = true;
}
}

52
src/httprequestparser.h Normal file
View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2007 by Ishan Arora
* ishanarora@gmail.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef HTTPREQUESTPARSER_H
#define HTTPREQUESTPARSER_H
#include<QHttpRequestHeader>
class HttpRequestParser : public QHttpRequestHeader
{
private:
bool headerDone;
bool messageDone;
bool error;
QByteArray data;
QString path;
QMap<QString, QString> postMap;
QMap<QString, QString> getMap;
QByteArray torrent_content;
public:
HttpRequestParser();
~HttpRequestParser();
bool isParsable() const;
bool isError() const;
QString url() const;
QByteArray message() const;
QString get(const QString key) const;
QString post(const QString key) const;
QByteArray torrent() const;
void write(QByteArray str);
};
#endif

Some files were not shown because too many files have changed in this diff Show More