Compare commits

..

446 Commits

Author SHA1 Message Date
Christophe Dumez
a175812555 - Tagged v1.1.4 and v1.2.0beta6 releases 2008-09-14 10:30:27 +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
200 changed files with 43518 additions and 19083 deletions

68
AUTHORS
View File

@@ -3,3 +3,71 @@ 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>
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/skins/*.png
copyright: Mateusz Tobola <tobejodok@qbittorrent.org>
license: GPLv2
* files: src/menuicons/YYxYY/*.png
copyright: Mateusz Tobola <tobejodok@qbittorrent.org>
license: GPLv2
* 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 (guoyue0418@hotmail.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

View File

@@ -1,4 +1,69 @@
* Unknown - Christophe Dumez <chris@qbittorrent.org> - v1.0.0 * Unknown - 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
- BUGFIX: Disable ETA calculation when ETA column is hidden
- BUGFIX: Removed "disconnected" connection state, detection was far from perfect
- 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)
@@ -41,25 +106,21 @@
- FEATURE: Added an option to automatically delete torrents when they reach a given ratio (>= 1.0) - FEATURE: Added an option to automatically delete torrents when they reach a given ratio (>= 1.0)
- FEATURE: Added an option to display current transfer speeds in title bar - FEATURE: Added an option to display current transfer speeds in title bar
- FEATURE: Torrent content is now displayed as a tree - FEATURE: Torrent content is now displayed as a tree
- FEATURE: Better media file preview (player detected automatically)
- FEATURE: Greatly improved ETA calculation algorithm (use GASA)
- I18N: Added Hungarian translation - I18N: Added Hungarian translation
- I18N: Added Brazilian translation - I18N: Added Brazilian translation
- BUGFIX: Progress of paused torrents is now correct on restart - BUGFIX: Progress of paused torrents is now correct on restart
- BUGFIX: clear the results of a search stops searching
- BUGFIX: Progress column gets sorted on restart it is was during last execution - BUGFIX: Progress column gets sorted on restart it is was during last execution
- BUGFIX: Made ETA more reliable using stats instead of instant values
- BUGFIX: Remove torrent from hard drive used to delete parent folder if empty - BUGFIX: Remove torrent from hard drive used to delete parent folder if empty
- BUGFIX: Fixed a crash when filtering all the files in a torrent - BUGFIX: Fixed a crash when filtering all the files in a torrent
- BUGFIX: Reload torrent only when necessary (properties) - BUGFIX: Reload torrent only when necessary (properties)
- BUGFIX: qBittorrent is not exiting anymore when a dialog is closed and main window is hidden - BUGFIX: qBittorrent is not exiting anymore when a dialog is closed and main window is hidden
- BUGFIX: Catch all possible exceptions when adding a torrent to avoid crashing
- BUGFIX: Search plugin update is not making the GUI freeze anymore (moved to a thread) - BUGFIX: Search plugin update is not making the GUI freeze anymore (moved to a thread)
- BUGFIX: DHT settings were not saved correctly - BUGFIX: DHT settings were not saved correctly
- BUGFIX: Workaround to build on Fedora system (pkg-config problem) - BUGFIX: Workaround to build on Fedora system (pkg-config problem)
- BUGFIX: search plugin update - do not display only last version changelog - BUGFIX: search plugin update - do not display only last version changelog
- BUGFIX: Search plugin update - fixed missing new lines in changelog - BUGFIX: Search plugin update - fixed missing new lines in changelog
- BUGFIX: The number of search results was not reset when clicking on 'Clear' button - BUGFIX: The number of search results was not reset when clicking on 'Clear' button
- BUGFIX: Fixed systray integration when qbittorrent is launched on system startup
- BUGFIX: Update torrent progress when its content changed (filtered files) - BUGFIX: Update torrent progress when its content changed (filtered files)
- BUGFIX: Improved the way menu icons are installed to avoid problems on some systems - BUGFIX: Improved the way menu icons are installed to avoid problems on some systems
- BUGFIX: Improved incremental download - BUGFIX: Improved incremental download
@@ -70,8 +131,6 @@
- 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: Removed build dependency on Python
- BUGFIX: Catching DHT exception in case there is a problem - BUGFIX: Catching DHT exception in case there is a problem
- BUGFIX: Remember properties window size and position
- BUGFIX: Improved proxy support in search engine (HTTP only)
- 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,13 +15,12 @@ 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.13.1 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

49
TODO
View File

@@ -1,49 +1,4 @@
// 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
- Port on MacOS, Windows (and create an installer for Windows) - Slow progress
- Add some transparency (menus,...), improve look / usabilty
- Skins support? (contact Mateusz)
// Harder
- Torrent scheduler ala µtorrent/Bitcomet
// Waiting for libtorrent
- Allow to prioritize torrents (may code this in qBittorrent?)
// Unsure
- Display the peers we are connected to for each torrent with infos (like flag, dl/up speeds, ...)
- Azureus spoofing to prevent ban from trackers?
- 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 // in v1.2.0
- Allow user to organize the downloads into categories/folders? - Split download and uploads in Web UI (Ishan Ahora)
// in v1.1.0
- Tabs support in search
- 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)
rc11 -> final? changelog:
BUGFIX: Fixed systray integration when qbittorrent is launched on system startup
BUGFIX: Catch all possible exceptions when adding a torrent to avoid crashing

36
configure vendored
View File

@@ -18,9 +18,11 @@ 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-libcurl-inc=[path] Path to libcurl include files --with-libcurl-inc=[path] Path to libcurl include files
--with-libcurl-lib=[path] Path to libcurl library files --with-libcurl-lib=[path] Path to libcurl library files
@@ -354,24 +356,28 @@ 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.13"; }
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");
@@ -405,7 +411,7 @@ 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);
@@ -417,7 +423,7 @@ public:
sl << "/usr/local/lib64/"; 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;
} }
@@ -705,7 +711,7 @@ 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);

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,7 +6,7 @@
<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'>

View File

@@ -1,17 +1,17 @@
/* /*
-----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.13"; }
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");
@@ -45,7 +45,7 @@ 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);
@@ -57,7 +57,7 @@ public:
sl << "/usr/local/lib64/"; 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;
} }

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

View File

@@ -34,10 +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_PRIORITY 5
#define F_HASH 6 #define F_HASH 6
class FinishedListDelegate: public QItemDelegate { class FinishedListDelegate: public QItemDelegate {
@@ -67,20 +67,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 = true;
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt,
painter);
break;
}
default: default:
QItemDelegate::paint(painter, option, index); QItemDelegate::paint(painter, option, index);
} }

View File

@@ -31,21 +31,25 @@
#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))); connect(BTSession, SIGNAL(addedTorrent(QTorrentHandle&)), this, SLOT(torrentAdded(QTorrentHandle&)));
finishedListModel = new QStandardItemModel(0,7); 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"));
finishedListModel->setHeaderData(F_PRIORITY, Qt::Horizontal, tr("Priority"));
finishedList->setModel(finishedListModel); finishedList->setModel(finishedListModel);
// Hide ETA & hash column loadHiddenColumns();
// Hide priority column
finishedList->hideColumn(F_PRIORITY);
// 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,11 +58,14 @@ 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&)));
connect(BTSession, SIGNAL(forceFinishedListUpdate()), this, SLOT(updateFinishedList()));
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")));
actionDelete_Permanently->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete_perm.png"))); actionDelete_Permanently->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete_perm.png")));
@@ -67,13 +74,25 @@ FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : par
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(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(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()));
connect(actionHOSColPriority, SIGNAL(triggered()), this, SLOT(hideOrShowColumnPriority()));
} }
FinishedTorrents::~FinishedTorrents(){ FinishedTorrents::~FinishedTorrents(){
saveColWidthFinishedList(); saveColWidthFinishedList();
saveHiddenColumns();
delete finishedListDelegate; delete finishedListDelegate;
delete finishedListModel; delete finishedListModel;
} }
@@ -81,7 +100,15 @@ 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::hidePriorityColumn(bool hide) {
finishedList->setColumnHidden(F_PRIORITY, hide);
if(hide)
getActionHoSCol(F_PRIORITY)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
else
getActionHoSCol(F_PRIORITY)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
} }
void FinishedTorrents::addTorrent(QString hash){ void FinishedTorrents::addTorrent(QString hash){
@@ -97,10 +124,11 @@ 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())));
if(BTSession->isQueueingEnabled())
finishedListModel->setData(finishedListModel->index(row, F_PRIORITY), QVariant((int)BTSession->getUpTorrentPriority(hash)));
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,9 +139,10 @@ 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);
sortFinishedList();
} }
void FinishedTorrents::torrentAdded(QString, QTorrentHandle& h, bool) { void FinishedTorrents::torrentAdded(QTorrentHandle& h) {
QString hash = h.hash(); QString hash = h.hash();
if(BTSession->isFinished(hash)) { if(BTSession->isFinished(hash)) {
addTorrent(hash); addTorrent(hash);
@@ -156,27 +185,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");
} }
@@ -209,31 +271,46 @@ void FinishedTorrents::updateFinishedList(){
row = getRowFromHash(hash); row = getRowFromHash(hash);
} }
Q_ASSERT(row != -1); Q_ASSERT(row != -1);
if(h.is_paused()) continue; // Update priority
if(BTSession->getTorrentsToPauseAfterChecking().indexOf(hash) != -1) { if(BTSession->isQueueingEnabled()) {
finishedListModel->setData(finishedListModel->index(row, F_PROGRESS), QVariant((double)h.progress())); finishedListModel->setData(finishedListModel->index(row, F_PRIORITY), QVariant((int)BTSession->getUpTorrentPriority(hash)));
continue; if(h.is_paused() && BTSession->isUploadQueued(hash)) {
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/queued.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey"));
} }
if(h.state() == torrent_status::downloading || (h.state() != torrent_status::checking_files && h.state() != torrent_status::queued_for_checking && h.progress() < 1.)) { }
if(h.is_paused()) continue;
if(h.state() == torrent_status::downloading || (h.state() != torrent_status::checking_files && h.state() != torrent_status::queued_for_checking && h.is_seed())) {
// What are you doing here? go back to download tab! // What are you doing here? go back to download tab!
int reponse = QMessageBox::question(this, tr("Incomplete torrent in seeding list"), tr("It appears that the state of '%1' torrent changed from 'seeding' to 'downloading'. Would you like to move it back to download list? (otherwise the torrent will simply be deleted)").arg(h.name()), QMessageBox::Yes | QMessageBox::No);
if (reponse == QMessageBox::Yes) {
qDebug("Info: a torrent was moved from finished to download tab"); qDebug("Info: a torrent was moved from finished to download tab");
deleteTorrent(hash); deleteTorrent(hash);
BTSession->setFinishedTorrent(hash); BTSession->setUnfinishedTorrent(hash);
emit torrentMovedFromFinishedList(hash); emit torrentMovedFromFinishedList(hash);
}
else if (reponse == QMessageBox::No) {
qDebug("Deleted from the finished");
BTSession->deleteTorrent(hash, true);
}
continue; continue;
} }
if(h.state() == torrent_status::checking_files){ 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()));
continue; 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);
if(!finishedList->isColumnHidden(F_UPSPEED)) {
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)h.upload_payload_rate())); finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), QVariant((double)h.upload_payload_rate()));
finishedListModel->setData(finishedListModel->index(row, F_SEEDSLEECH), QVariant(misc::toQString(h.num_seeds(), true)+"/"+misc::toQString(h.num_peers() - h.num_seeds(), true))); }
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)))); finishedListModel->setData(finishedListModel->index(row, F_RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash))));
finishedListModel->setData(finishedListModel->index(row, F_PROGRESS), QVariant((double)1.)); }
} }
} }
@@ -250,10 +327,11 @@ 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"));
} }
@@ -283,11 +361,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();
} }
@@ -345,30 +426,205 @@ 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(actionOpen_destination_folder);
myFinishedListMenu.addAction(actionTorrent_Properties); myFinishedListMenu.addAction(actionTorrent_Properties);
if(BTSession->isQueueingEnabled()) {
myFinishedListMenu.addSeparator();
myFinishedListMenu.addAction(actionIncreasePriority);
myFinishedListMenu.addAction(actionDecreasePriority);
}
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;
if(BTSession->isQueueingEnabled()) {
lastCol = F_PRIORITY;
} else {
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);
}
void FinishedTorrents::hideOrShowColumnPriority() {
hideOrShowColumn(F_PRIORITY);
}
// 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;
case F_PRIORITY :
return actionHOSColPriority;
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{ switch(index) {
sortOrder = Qt::AscendingOrder; case F_SIZE:
case F_UPSPEED:
case F_PRIORITY:
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);
} }
}
finishedList->header()->setSortIndicator(index, sortOrder);
switch(index) { 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,15 +57,24 @@ 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 loadLastSortedColumn();
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 torrentAdded(QTorrentHandle& h);
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 hideOrShowColumnPriority();
public slots: public slots:
void addTorrent(QString hash); void addTorrent(QString hash);
@@ -70,10 +83,12 @@ class FinishedTorrents : public QWidget, public Ui::seeding {
void resumeTorrent(QString hash); void resumeTorrent(QString hash);
void propertiesSelection(); void propertiesSelection();
void deleteTorrent(QString hash); void deleteTorrent(QString hash);
void showPropertiesFromHash(QString hash);
void hidePriorityColumn(bool hide);
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);
}; };

View File

@@ -23,8 +23,18 @@
#include <QDesktopWidget> #include <QDesktopWidget>
#include <QTimer> #include <QTimer>
#include <QDesktopServices> #include <QDesktopServices>
#include <QStatusBar>
#include <QFrame>
#ifdef QT_4_4
#include <QLocalServer>
#include <QLocalSocket>
#include <unistd.h>
#include <sys/types.h>
#else
#include <QTcpServer> #include <QTcpServer>
#include <QTcpSocket> #include <QTcpSocket>
#endif
#include <stdlib.h>
#include <QCloseEvent> #include <QCloseEvent>
#include <QShortcut> #include <QShortcut>
#include <QLabel> #include <QLabel>
@@ -45,7 +55,9 @@
#include "options_imp.h" #include "options_imp.h"
#include "previewSelect.h" #include "previewSelect.h"
#include "allocationDlg.h" #include "allocationDlg.h"
#include "stdlib.h" #include <stdlib.h>
#include "console_imp.h"
#include "httpserver.h"
using namespace libtorrent; using namespace libtorrent;
@@ -98,11 +110,10 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
actionSet_global_upload_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png"))); actionSet_global_upload_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png")));
actionSet_global_download_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png"))); actionSet_global_download_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png")));
actionDocumentation->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/qb_question.png"))); actionDocumentation->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/qb_question.png")));
connecStatusLblIcon = new QLabel(); prioSeparator = toolBar->insertSeparator(actionDecreasePriority);
connecStatusLblIcon->setFrameShape(QFrame::NoFrame); prioSeparator2 = menu_Edit->insertSeparator(actionDecreasePriority);
connecStatusLblIcon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/disconnected.png"))); prioSeparator->setVisible(false);
connecStatusLblIcon->setToolTip(QString::fromUtf8("<b>")+tr("Connection status:")+QString::fromUtf8("</b><br>")+tr("Offline")+QString::fromUtf8("<br><i>")+tr("No peers found...")+QString::fromUtf8("</i>")); prioSeparator2->setVisible(false);
toolBar->addWidget(connecStatusLblIcon);
actionDelete_Permanently->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete_perm.png"))); actionDelete_Permanently->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete_perm.png")));
actionTorrent_Properties->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/properties.png"))); actionTorrent_Properties->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/properties.png")));
actionCreate_torrent->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/new.png"))); actionCreate_torrent->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/new.png")));
@@ -110,31 +121,40 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
toolBar->layout()->setSpacing(7); toolBar->layout()->setSpacing(7);
// creating options // creating options
options = new options_imp(this); options = new options_imp(this);
connect(options, SIGNAL(status_changed(QString, bool)), this, SLOT(OptionsSaved(QString, bool))); connect(options, SIGNAL(status_changed(bool)), this, SLOT(OptionsSaved(bool)));
BTSession = new bittorrent(); BTSession = new bittorrent();
connect(BTSession, SIGNAL(fullDiskError(QTorrentHandle&)), this, SLOT(fullDiskError(QTorrentHandle&))); connect(BTSession, SIGNAL(fullDiskError(QTorrentHandle&)), this, SLOT(fullDiskError(QTorrentHandle&)));
connect(BTSession, SIGNAL(finishedTorrent(QTorrentHandle&)), this, SLOT(finishedTorrent(QTorrentHandle&))); connect(BTSession, SIGNAL(finishedTorrent(QTorrentHandle&)), this, SLOT(finishedTorrent(QTorrentHandle&)));
connect(BTSession, SIGNAL(torrentFinishedChecking(QString)), this, SLOT(torrentChecked(QString)));
connect(BTSession, SIGNAL(trackerAuthenticationRequired(QTorrentHandle&)), this, SLOT(trackerAuthenticationRequired(QTorrentHandle&))); connect(BTSession, SIGNAL(trackerAuthenticationRequired(QTorrentHandle&)), this, SLOT(trackerAuthenticationRequired(QTorrentHandle&)));
connect(BTSession, SIGNAL(scanDirFoundTorrents(const QStringList&)), this, SLOT(processScannedFiles(const QStringList&))); connect(BTSession, SIGNAL(scanDirFoundTorrents(const QStringList&)), this, SLOT(processScannedFiles(const QStringList&)));
connect(BTSession, SIGNAL(newDownloadedTorrent(QString, QString)), this, SLOT(processDownloadedFiles(QString, QString))); connect(BTSession, SIGNAL(newDownloadedTorrent(QString, QString)), this, SLOT(processDownloadedFiles(QString, QString)));
connect(BTSession, SIGNAL(downloadFromUrlFailure(QString, QString)), this, SLOT(handleDownloadFromUrlFailure(QString, QString))); connect(BTSession, SIGNAL(downloadFromUrlFailure(QString, QString)), this, SLOT(handleDownloadFromUrlFailure(QString, QString)));
connect(BTSession, SIGNAL(torrent_deleted(QString, QString, bool)), this, SLOT(deleteTorrent(QString, QString, bool))); connect(BTSession, SIGNAL(deletedTorrent(QString)), this, SLOT(deleteTorrent(QString)));
connect(BTSession, SIGNAL(pausedTorrent(QString)), this, SLOT(pauseTorrent(QString)));
connect(BTSession, SIGNAL(updateUnfinishedTorrentNumber()), this, SLOT(updateUnfinishedTorrentNumberCalc()));
connect(BTSession, SIGNAL(updateFinishedTorrentNumber()), this, SLOT(updateFinishedTorrentNumberCalc()));
qDebug("create tabWidget"); qDebug("create tabWidget");
tabs = new QTabWidget(); tabs = new QTabWidget();
// Download torrents tab // Download torrents tab
downloadingTorrentTab = new DownloadingTorrents(this, BTSession); downloadingTorrentTab = new DownloadingTorrents(this, BTSession);
tabs->addTab(downloadingTorrentTab, tr("Downloads") + QString::fromUtf8(" (0)")); tabs->addTab(downloadingTorrentTab, tr("Downloads") + QString::fromUtf8(" (0/0)"));
tabs->setTabIcon(0, QIcon(QString::fromUtf8(":/Icons/skin/downloading.png"))); tabs->setTabIcon(0, QIcon(QString::fromUtf8(":/Icons/skin/downloading.png")));
vboxLayout->addWidget(tabs); vboxLayout->addWidget(tabs);
connect(downloadingTorrentTab, SIGNAL(unfinishedTorrentsNumberChanged(unsigned int)), this, SLOT(updateUnfinishedTorrentNumber(unsigned int))); connect(downloadingTorrentTab, SIGNAL(unfinishedTorrentsNumberChanged(unsigned int)), this, SLOT(updateUnfinishedTorrentNumber(unsigned int)));
connect(downloadingTorrentTab, SIGNAL(torrentDoubleClicked(QString)), this, SLOT(togglePausedState(QString))); connect(downloadingTorrentTab, SIGNAL(torrentDoubleClicked(QString, bool)), this, SLOT(torrentDoubleClicked(QString, bool)));
// Finished torrents tab // Finished torrents tab
finishedTorrentTab = new FinishedTorrents(this, BTSession); finishedTorrentTab = new FinishedTorrents(this, BTSession);
tabs->addTab(finishedTorrentTab, tr("Finished") + QString::fromUtf8(" (0)")); tabs->addTab(finishedTorrentTab, tr("Uploads") + QString::fromUtf8(" (0/0)"));
tabs->setTabIcon(1, QIcon(QString::fromUtf8(":/Icons/skin/seeding.png"))); tabs->setTabIcon(1, QIcon(QString::fromUtf8(":/Icons/skin/seeding.png")));
connect(finishedTorrentTab, SIGNAL(torrentDoubleClicked(QString)), this, SLOT(togglePausedState(QString))); connect(finishedTorrentTab, SIGNAL(torrentDoubleClicked(QString, bool)), this, SLOT(torrentDoubleClicked(QString, bool)));
connect(finishedTorrentTab, SIGNAL(finishedTorrentsNumberChanged(unsigned int)), this, SLOT(updateFinishedTorrentNumber(unsigned int))); connect(finishedTorrentTab, SIGNAL(finishedTorrentsNumberChanged(unsigned int)), this, SLOT(updateFinishedTorrentNumber(unsigned int)));
// Search engine tab
searchEngine = new SearchEngine(BTSession, myTrayIcon, systrayIntegration);
tabs->addTab(searchEngine, tr("Search"));
tabs->setTabIcon(2, QIcon(QString::fromUtf8(":/Icons/skin/search.png")));
readSettings();
// RSS Tab
rssWidget = 0;
// Smooth torrent switching between tabs Downloading <--> Finished // Smooth torrent switching between tabs Downloading <--> Finished
connect(downloadingTorrentTab, SIGNAL(torrentFinished(QString)), finishedTorrentTab, SLOT(addTorrent(QString))); connect(downloadingTorrentTab, SIGNAL(torrentFinished(QString)), finishedTorrentTab, SLOT(addTorrent(QString)));
connect(finishedTorrentTab, SIGNAL(torrentMovedFromFinishedList(QString)), downloadingTorrentTab, SLOT(addTorrent(QString))); connect(finishedTorrentTab, SIGNAL(torrentMovedFromFinishedList(QString)), downloadingTorrentTab, SLOT(addTorrent(QString)));
@@ -146,43 +166,96 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
configureSession(true); configureSession(true);
// Resume unfinished torrents // Resume unfinished torrents
BTSession->resumeUnfinishedTorrents(); BTSession->resumeUnfinishedTorrents();
// Search engine tab
searchEngine = new SearchEngine(BTSession, myTrayIcon, systrayIntegration);
tabs->addTab(searchEngine, tr("Search"));
tabs->setTabIcon(2, QIcon(QString::fromUtf8(":/Icons/skin/search.png")));
// RSS tab
rssWidget = new RSSImp();
tabs->addTab(rssWidget, tr("RSS"));
tabs->setTabIcon(3, QIcon(QString::fromUtf8(":/Icons/rss32.png")));
readSettings();
// Add torrent given on command line // Add torrent given on command line
processParams(torrentCmdLine); processParams(torrentCmdLine);
// Initialize Web UI
httpServer = 0;
if(settings.value("Preferences/WebUI/Enabled", false).toBool())
{
quint16 port = settings.value("Preferences/WebUI/Port", 8080).toUInt();
QString username = settings.value("Preferences/WebUI/Username", "").toString();
QString password = settings.value("Preferences/WebUI/Password", "").toString();
initWebUi(username, password, port);
}
// Use a tcp server to allow only one instance of qBittorrent // Use a tcp server to allow only one instance of qBittorrent
tcpServer = new QTcpServer(); #ifdef QT_4_4
if (!tcpServer->listen(QHostAddress::LocalHost, 1666)) { localServer = new QLocalServer();
QString uid = QString::number(getuid());
if (!localServer->listen("qBittorrent-"+uid)) {
#else
localServer = new QTcpServer();
if (!localServer->listen(QHostAddress::LocalHost)) {
#endif
std::cerr << "Couldn't create socket, single instance mode won't work...\n"; std::cerr << "Couldn't create socket, single instance mode won't work...\n";
} }
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(acceptConnection())); #ifndef QT_4_4
else {
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
settings.setValue(QString::fromUtf8("uniqueInstancePort"), localServer->serverPort());
}
#endif
connect(localServer, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
// Start connection checking timer // Start connection checking timer
checkConnect = new QTimer(this); checkConnect = new QTimer(this);
connect(checkConnect, SIGNAL(timeout()), this, SLOT(checkConnectionStatus())); connect(checkConnect, SIGNAL(timeout()), this, SLOT(checkConnectionStatus()));
checkConnect->start(5000); checkConnect->start(5000);
// Accept drag 'n drops // Accept drag 'n drops
setAcceptDrops(true); setAcceptDrops(true);
if(!settings.value(QString::fromUtf8("Preferences/General/StartMinimized"), false).toBool()) {
show(); show();
}
createKeyboardShortcuts(); createKeyboardShortcuts();
connecStatusLblIcon = new QLabel();
connecStatusLblIcon->setFrameShape(QFrame::NoFrame);
connecStatusLblIcon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/firewalled.png")));
connecStatusLblIcon->setToolTip(QString::fromUtf8("<b>")+tr("Connection status:")+QString::fromUtf8("</b><br>")+QString::fromUtf8("<i>")+tr("No direct connections. This may indicate network configuration problems.")+QString::fromUtf8("</i>"));
dlSpeedLbl = new QLabel(tr("DL: %1 KiB/s").arg("0.0"));
upSpeedLbl = new QLabel(tr("UP: %1 KiB/s").arg("0.0"));
ratioLbl = new QLabel(tr("Ratio: %1").arg("1.0"));
DHTLbl = new QLabel(tr("DHT: %1 nodes").arg(0));
statusSep1 = new QFrame();
statusSep1->setFixedWidth(1);
statusSep1->setFrameStyle(QFrame::Box);
statusSep2 = new QFrame();
statusSep2->setFixedWidth(1);
statusSep2->setFrameStyle(QFrame::Box);
statusSep3 = new QFrame();
statusSep3->setFixedWidth(1);
statusSep3->setFrameStyle(QFrame::Box);
statusSep4 = new QFrame();
statusSep4->setFixedWidth(1);
statusSep4->setFrameStyle(QFrame::Box);
QMainWindow::statusBar()->addPermanentWidget(DHTLbl);
QMainWindow::statusBar()->addPermanentWidget(statusSep1);
QMainWindow::statusBar()->addPermanentWidget(connecStatusLblIcon);
QMainWindow::statusBar()->addPermanentWidget(statusSep2);
QMainWindow::statusBar()->addPermanentWidget(dlSpeedLbl);
QMainWindow::statusBar()->addPermanentWidget(statusSep3);
QMainWindow::statusBar()->addPermanentWidget(upSpeedLbl);
QMainWindow::statusBar()->addPermanentWidget(statusSep4);
QMainWindow::statusBar()->addPermanentWidget(ratioLbl);
qDebug("GUI Built"); qDebug("GUI Built");
} }
// Destructor // Destructor
GUI::~GUI() { GUI::~GUI() {
qDebug("GUI destruction"); qDebug("GUI destruction");
delete dlSpeedLbl;
delete upSpeedLbl;
delete ratioLbl;
delete DHTLbl;
delete statusSep1;
delete statusSep2;
delete statusSep3;
delete statusSep4;
if(rssWidget != 0)
delete rssWidget; delete rssWidget;
delete searchEngine; delete searchEngine;
delete refresher; delete refresher;
delete downloadingTorrentTab; delete downloadingTorrentTab;
delete finishedTorrentTab; delete finishedTorrentTab;
delete checkConnect; delete checkConnect;
qDebug("1");
if(systrayCreator) { if(systrayCreator) {
delete systrayCreator; delete systrayCreator;
} }
@@ -190,16 +263,58 @@ GUI::~GUI() {
delete myTrayIcon; delete myTrayIcon;
delete myTrayIconMenu; delete myTrayIconMenu;
} }
delete tcpServer; qDebug("2");
delete localServer;
delete connecStatusLblIcon; delete connecStatusLblIcon;
delete tabs; delete tabs;
// HTTP Server
if(httpServer)
delete httpServer;
qDebug("3");
// Keyboard shortcuts // Keyboard shortcuts
delete switchSearchShortcut; delete switchSearchShortcut;
delete switchSearchShortcut2; delete switchSearchShortcut2;
delete switchDownShortcut; delete switchDownShortcut;
delete switchUpShortcut; delete switchUpShortcut;
delete switchRSSShortcut; delete switchRSSShortcut;
qDebug("4");
delete BTSession; delete BTSession;
qDebug("5");
}
void GUI::displayRSSTab(bool enable) {
if(enable) {
// RSS tab
if(rssWidget == 0) {
rssWidget = new RSSImp();
tabs->addTab(rssWidget, tr("RSS"));
tabs->setTabIcon(3, QIcon(QString::fromUtf8(":/Icons/rss32.png")));
}
} else {
if(rssWidget != 0) {
delete rssWidget;
rssWidget = 0;
}
}
}
void GUI::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.;
}
ratioLbl->setText(tr("Ratio: %1").arg(QString(QByteArray::number(ratio, 'f', 1))));
// Update DHT nodes
DHTLbl->setText(tr("DHT: %1 nodes").arg(QString::number(sessionStatus.dht_nodes)));
} }
void GUI::on_actionWebsite_triggered() const { void GUI::on_actionWebsite_triggered() const {
@@ -222,27 +337,6 @@ void GUI::writeSettings() {
settings.endGroup(); settings.endGroup();
} }
// Called when a torrent finished checking
void GUI::torrentChecked(QString hash) const {
// Check if the torrent was paused after checking
if(BTSession->isPaused(hash)) {
// Was paused, change its icon/color
if(BTSession->isFinished(hash)) {
// In finished list
qDebug("Automatically paused torrent was in finished list");
finishedTorrentTab->pauseTorrent(hash);
}else{
// In download list
downloadingTorrentTab->pauseTorrent(hash);
}
}
if(!BTSession->isFinished(hash)){
// Delayed Sorting
downloadingTorrentTab->updateFileSizeAndProgress(hash);
downloadingTorrentTab->sortProgressColumnDelayed();
}
}
// called when a torrent has finished // called when a torrent has finished
void GUI::finishedTorrent(QTorrentHandle& h) const { void GUI::finishedTorrent(QTorrentHandle& h) const {
qDebug("In GUI, a torrent has finished"); qDebug("In GUI, a torrent has finished");
@@ -257,7 +351,7 @@ void GUI::finishedTorrent(QTorrentHandle& h) const {
qDebug("We received a finished signal for torrent %s, but it already has a .finished file", hash.toUtf8().data()); qDebug("We received a finished signal for torrent %s, but it already has a .finished file", hash.toUtf8().data());
} }
if(show_msg) if(show_msg)
downloadingTorrentTab->setInfoBar(tr("%1 has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(fileName)); BTSession->addConsoleMessage(tr("%1 has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(fileName));
downloadingTorrentTab->deleteTorrent(hash); downloadingTorrentTab->deleteTorrent(hash);
finishedTorrentTab->addTorrent(hash); finishedTorrentTab->addTorrent(hash);
if(show_msg && systrayIntegration && useNotificationBalloons) { if(show_msg && systrayIntegration && useNotificationBalloons) {
@@ -282,7 +376,7 @@ void GUI::fullDiskError(QTorrentHandle& h) const {
}else{ }else{
downloadingTorrentTab->pauseTorrent(hash); downloadingTorrentTab->pauseTorrent(hash);
} }
downloadingTorrentTab->setInfoBar(tr("An error occured (full disk?), '%1' paused.", "e.g: An error occured (full disk?), 'xxx.avi' paused.").arg(h.name())); BTSession->addConsoleMessage(tr("An error occured (full disk?), '%1' paused.", "e.g: An error occured (full disk?), 'xxx.avi' paused.").arg(h.name()));
} }
void GUI::createKeyboardShortcuts() { void GUI::createKeyboardShortcuts() {
@@ -307,6 +401,8 @@ void GUI::createKeyboardShortcuts() {
actionStart_All->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+Shift+S"))); actionStart_All->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+Shift+S")));
actionPause->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+P"))); actionPause->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+P")));
actionPause_All->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+Shift+P"))); actionPause_All->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+Shift+P")));
actionDecreasePriority->setShortcut(QKeySequence(QString::fromUtf8("Ctrl+-")));
actionIncreasePriority->setShortcut(QKeySequence(QString::fromUtf8("Ctrl++")));
} }
// Keyboard shortcuts slots // Keyboard shortcuts slots
@@ -348,13 +444,13 @@ void GUI::balloonClicked() {
} }
void GUI::acceptConnection() { void GUI::acceptConnection() {
clientConnection = tcpServer->nextPendingConnection(); clientConnection = localServer->nextPendingConnection();
connect(clientConnection, SIGNAL(disconnected()), this, SLOT(readParamsOnSocket())); connect(clientConnection, SIGNAL(disconnected()), this, SLOT(readParamsOnSocket()));
qDebug("accepted connection from another instance"); qDebug("accepted connection from another instance");
} }
void GUI::readParamsOnSocket() { void GUI::readParamsOnSocket() {
if(clientConnection != 0) { if(clientConnection) {
QByteArray params = clientConnection->readAll(); QByteArray params = clientConnection->readAll();
if(!params.isEmpty()) { if(!params.isEmpty()) {
processParams(QString::fromUtf8(params.data()).split(QString::fromUtf8("\n"))); processParams(QString::fromUtf8(params.data()).split(QString::fromUtf8("\n")));
@@ -373,6 +469,10 @@ void GUI::on_actionSet_global_upload_limit_triggered() {
new BandwidthAllocationDialog(this, true, BTSession, QStringList()); new BandwidthAllocationDialog(this, true, BTSession, QStringList());
} }
void GUI::on_actionShow_console_triggered() {
new consoleDlg(this, BTSession);
}
void GUI::on_actionSet_global_download_limit_triggered() { void GUI::on_actionSet_global_download_limit_triggered() {
qDebug("actionSet_global_download_limit_triggered"); qDebug("actionSet_global_download_limit_triggered");
new BandwidthAllocationDialog(this, false, BTSession, QStringList()); new BandwidthAllocationDialog(this, false, BTSession, QStringList());
@@ -394,6 +494,50 @@ void GUI::on_actionPreview_file_triggered() {
new previewSelect(this, h); new previewSelect(this, h);
} }
void GUI::openDestinationFolder() const {
QStringList hashes;
switch(tabs->currentIndex()){
case 0:
hashes = downloadingTorrentTab->getSelectedTorrents(true);
break;
case 1:
hashes = finishedTorrentTab->getSelectedTorrents(true);
break;
default:
return;
}
QString hash;
QStringList pathsList;
foreach(hash, hashes) {
QTorrentHandle h = BTSession->getTorrentHandle(hash);
QString savePath = h.save_path();
if(!pathsList.contains(savePath)) {
pathsList.append(savePath);
QDesktopServices::openUrl(QString("file://")+savePath);
}
}
}
void GUI::goBuyPage() const {
QStringList hashes;
switch(tabs->currentIndex()){
case 0:
hashes = downloadingTorrentTab->getSelectedTorrents(true);
break;
case 1:
hashes = finishedTorrentTab->getSelectedTorrents(true);
break;
default:
return;
}
QString hash;
QStringList pathsList;
foreach(hash, hashes) {
QTorrentHandle h = BTSession->getTorrentHandle(hash);
QDesktopServices::openUrl("http://match.sharemonkey.com/?info_hash="+hash+"&n="+h.name()+"&cid=33");
}
}
// Necessary if we want to close the window // Necessary if we want to close the window
// in one time if "close to systray" is enabled // in one time if "close to systray" is enabled
void GUI::on_actionExit_triggered() { void GUI::on_actionExit_triggered() {
@@ -505,15 +649,18 @@ void GUI::on_actionCreate_torrent_triggered() {
connect(ct, SIGNAL(torrent_to_seed(QString)), this, SLOT(addTorrent(QString))); connect(ct, SIGNAL(torrent_to_seed(QString)), this, SLOT(addTorrent(QString)));
} }
// Called when we minimize the program bool GUI::event(QEvent * e) {
void GUI::hideEvent(QHideEvent *e) { if(e->type() == QEvent::WindowStateChange) {
//Now check to see if the window is minimised
if(isMinimized()) {
qDebug("minimisation");
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
if(systrayIntegration && settings.value(QString::fromUtf8("Preferences/General/MinimizeToTray"), false).toBool()) { if(systrayIntegration && settings.value(QString::fromUtf8("Preferences/General/MinimizeToTray"), false).toBool()) {
// Hide window
hide(); hide();
} }
// Accept hiding }
e->accept(); }
return QMainWindow::event(e);
} }
// Action executed when a file is dropped // Action executed when a file is dropped
@@ -544,9 +691,7 @@ void GUI::dropEvent(QDropEvent *event) {
continue; continue;
} }
if(useTorrentAdditionDialog) { if(useTorrentAdditionDialog) {
torrentAdditionDialog *dialog = new torrentAdditionDialog(this); torrentAdditionDialog *dialog = new torrentAdditionDialog(this, BTSession);
connect(dialog, SIGNAL(torrentAddition(QString, bool, QString)), BTSession, SLOT(addTorrent(QString, bool, QString)));
connect(dialog, SIGNAL(setInfoBarGUI(QString, QColor)), downloadingTorrentTab, SLOT(setInfoBar(QString, QColor)));
dialog->showLoad(file); dialog->showLoad(file);
}else{ }else{
BTSession->addTorrent(file); BTSession->addTorrent(file);
@@ -585,9 +730,7 @@ void GUI::on_actionOpen_triggered() {
unsigned int listSize = pathsList.size(); unsigned int listSize = pathsList.size();
for(unsigned int i=0; i<listSize; ++i) { for(unsigned int i=0; i<listSize; ++i) {
if(useTorrentAdditionDialog) { if(useTorrentAdditionDialog) {
torrentAdditionDialog *dialog = new torrentAdditionDialog(this); torrentAdditionDialog *dialog = new torrentAdditionDialog(this, BTSession);
connect(dialog, SIGNAL(torrentAddition(QString, bool, QString)), BTSession, SLOT(addTorrent(QString, bool, QString)));
connect(dialog, SIGNAL(setInfoBarGUI(QString, QColor)), downloadingTorrentTab, SLOT(setInfoBar(QString, QColor)));
dialog->showLoad(pathsList.at(i)); dialog->showLoad(pathsList.at(i));
}else{ }else{
BTSession->addTorrent(pathsList.at(i)); BTSession->addTorrent(pathsList.at(i));
@@ -640,25 +783,13 @@ void GUI::on_actionDelete_Permanently_triggered() {
QString fileName = h.name(); QString fileName = h.name();
// Remove the torrent // Remove the torrent
BTSession->deleteTorrent(hash, true); BTSession->deleteTorrent(hash, true);
// Delete item from list
if(inDownloadList) {
downloadingTorrentTab->deleteTorrent(hash);
} else {
finishedTorrentTab->deleteTorrent(hash);
}
// Update info bar
downloadingTorrentTab->setInfoBar(tr("'%1' was removed permanently.", "'xxx.avi' was removed permanently.").arg(fileName));
} }
} }
void GUI::deleteTorrent(QString hash, QString fileName, bool finished) { void GUI::deleteTorrent(QString hash) {
if(finished) { // Delete item from list
finishedTorrentTab->deleteTorrent(hash);
} else {
downloadingTorrentTab->deleteTorrent(hash); downloadingTorrentTab->deleteTorrent(hash);
} finishedTorrentTab->deleteTorrent(hash);
// Update info bar
downloadingTorrentTab->setInfoBar(tr("'%1' was removed because its ratio reached the maximum value you set.", "%1 is a file name").arg(fileName));
} }
// delete selected items in the list // delete selected items in the list
@@ -705,14 +836,6 @@ void GUI::on_actionDelete_triggered() {
QString fileName = h.name(); QString fileName = h.name();
// Remove the torrent // Remove the torrent
BTSession->deleteTorrent(hash, false); BTSession->deleteTorrent(hash, false);
// Delete item from list
if(inDownloadList) {
downloadingTorrentTab->deleteTorrent(hash);
} else {
finishedTorrentTab->deleteTorrent(hash);
}
// Update info bar
downloadingTorrentTab->setInfoBar(tr("'%1' was removed.", "'xxx.avi' was removed.").arg(fileName));
} }
} }
@@ -730,9 +853,7 @@ void GUI::processParams(const QStringList& params) {
BTSession->downloadFromUrl(param); BTSession->downloadFromUrl(param);
}else{ }else{
if(useTorrentAdditionDialog) { if(useTorrentAdditionDialog) {
torrentAdditionDialog *dialog = new torrentAdditionDialog(this); torrentAdditionDialog *dialog = new torrentAdditionDialog(this, BTSession);
connect(dialog, SIGNAL(torrentAddition(QString, bool, QString)), BTSession, SLOT(addTorrent(QString, bool, QString)));
connect(dialog, SIGNAL(setInfoBarGUI(QString, QColor)), downloadingTorrentTab, SLOT(setInfoBar(QString, QColor)));
dialog->showLoad(param); dialog->showLoad(param);
}else{ }else{
BTSession->addTorrent(param); BTSession->addTorrent(param);
@@ -751,9 +872,7 @@ void GUI::processScannedFiles(const QStringList& params) {
bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool(); bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool();
foreach(param, params) { foreach(param, params) {
if(useTorrentAdditionDialog) { if(useTorrentAdditionDialog) {
torrentAdditionDialog *dialog = new torrentAdditionDialog(this); torrentAdditionDialog *dialog = new torrentAdditionDialog(this, BTSession);
connect(dialog, SIGNAL(torrentAddition(QString, bool, QString)), BTSession, SLOT(addTorrent(QString, bool, QString)));
connect(dialog, SIGNAL(setInfoBarGUI(QString, QColor)), downloadingTorrentTab, SLOT(setInfoBar(QString, QColor)));
dialog->showLoad(param, true); dialog->showLoad(param, true);
}else{ }else{
BTSession->addTorrent(param, true); BTSession->addTorrent(param, true);
@@ -765,9 +884,7 @@ void GUI::processDownloadedFiles(QString path, QString url) {
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent")); QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool(); bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool();
if(useTorrentAdditionDialog) { if(useTorrentAdditionDialog) {
torrentAdditionDialog *dialog = new torrentAdditionDialog(this); torrentAdditionDialog *dialog = new torrentAdditionDialog(this, BTSession);
connect(dialog, SIGNAL(torrentAddition(QString, bool, QString)), BTSession, SLOT(addTorrent(QString, bool, QString)));
connect(dialog, SIGNAL(setInfoBarGUI(QString, QColor)), downloadingTorrentTab, SLOT(setInfoBar(QString, QColor)));
dialog->showLoad(path, false, url); dialog->showLoad(path, false, url);
}else{ }else{
BTSession->addTorrent(path, false, url); BTSession->addTorrent(path, false, url);
@@ -784,6 +901,11 @@ void GUI::configureSession(bool deleteOptions) {
setWindowTitle(tr("qBittorrent %1", "e.g: qBittorrent v0.x").arg(QString::fromUtf8(VERSION))); setWindowTitle(tr("qBittorrent %1", "e.g: qBittorrent v0.x").arg(QString::fromUtf8(VERSION)));
} }
displaySpeedInTitle = new_displaySpeedInTitle; displaySpeedInTitle = new_displaySpeedInTitle;
if(options->isToolbarDisplayed()) {
toolBar->setVisible(true);
} else {
toolBar->setVisible(false);
}
unsigned int new_refreshInterval = options->getRefreshInterval(); unsigned int new_refreshInterval = options->getRefreshInterval();
if(refreshInterval != new_refreshInterval) { if(refreshInterval != new_refreshInterval) {
refreshInterval = new_refreshInterval; refreshInterval = new_refreshInterval;
@@ -798,6 +920,8 @@ void GUI::configureSession(bool deleteOptions) {
if(options->getScanDir().isNull()) { if(options->getScanDir().isNull()) {
BTSession->disableDirectoryScanning(); BTSession->disableDirectoryScanning();
}else{ }else{
//Interval first
BTSession->setTimerScanInterval(options->getFolderScanInterval());
BTSession->enableDirectoryScanning(options->getScanDir()); BTSession->enableDirectoryScanning(options->getScanDir());
} }
// Connection // Connection
@@ -806,7 +930,7 @@ void GUI::configureSession(bool deleteOptions) {
BTSession->setListeningPortsRange(options->getPorts()); BTSession->setListeningPortsRange(options->getPorts());
unsigned short new_listenPort = BTSession->getListenPort(); unsigned short new_listenPort = BTSession->getListenPort();
if(new_listenPort != old_listenPort) { if(new_listenPort != old_listenPort) {
downloadingTorrentTab->setInfoBar(tr("qBittorrent is bind to port: %1", "e.g: qBittorrent is bind to port: 1666").arg( misc::toQString(new_listenPort))); BTSession->addConsoleMessage(tr("qBittorrent is bind to port: %1", "e.g: qBittorrent is bind to port: 1666").arg( misc::toQString(new_listenPort)));
} }
// * Global download limit // * Global download limit
QPair<int, int> limits = options->getGlobalBandwidthLimits(); QPair<int, int> limits = options->getGlobalBandwidthLimits();
@@ -828,18 +952,18 @@ void GUI::configureSession(bool deleteOptions) {
// * UPnP // * UPnP
if(options->isUPnPEnabled()) { if(options->isUPnPEnabled()) {
BTSession->enableUPnP(true); BTSession->enableUPnP(true);
downloadingTorrentTab->setInfoBar(tr("UPnP support [ON]"), QString::fromUtf8("blue")); BTSession->addConsoleMessage(tr("UPnP support [ON]"), QString::fromUtf8("blue"));
} else { } else {
BTSession->enableUPnP(false); BTSession->enableUPnP(false);
downloadingTorrentTab->setInfoBar(tr("UPnP support [OFF]"), QString::fromUtf8("blue")); BTSession->addConsoleMessage(tr("UPnP support [OFF]"), QString::fromUtf8("blue"));
} }
// * NAT-PMP // * NAT-PMP
if(options->isNATPMPEnabled()) { if(options->isNATPMPEnabled()) {
BTSession->enableNATPMP(true); BTSession->enableNATPMP(true);
downloadingTorrentTab->setInfoBar(tr("NAT-PMP support [ON]"), QString::fromUtf8("blue")); BTSession->addConsoleMessage(tr("NAT-PMP support [ON]"), QString::fromUtf8("blue"));
} else { } else {
BTSession->enableNATPMP(false); BTSession->enableNATPMP(false);
downloadingTorrentTab->setInfoBar(tr("NAT-PMP support [OFF]"), QString::fromUtf8("blue")); BTSession->addConsoleMessage(tr("NAT-PMP support [OFF]"), QString::fromUtf8("blue"));
} }
// * Proxy settings // * Proxy settings
proxy_settings proxySettings; proxy_settings proxySettings;
@@ -887,7 +1011,13 @@ void GUI::configureSession(bool deleteOptions) {
BTSession->setProxySettings(proxySettings, options->useProxyForTrackers(), options->useProxyForPeers(), options->useProxyForWebseeds(), options->useProxyForDHT()); BTSession->setProxySettings(proxySettings, options->useProxyForTrackers(), options->useProxyForPeers(), options->useProxyForWebseeds(), options->useProxyForDHT());
// * Session settings // * Session settings
session_settings sessionSettings; session_settings sessionSettings;
if(options->shouldSpoofAzureus()) {
sessionSettings.user_agent = "Azureus 3.0.5.2";
} else {
sessionSettings.user_agent = "qBittorrent "VERSION; sessionSettings.user_agent = "qBittorrent "VERSION;
}
sessionSettings.upnp_ignore_nonrouters = true;
sessionSettings.use_dht_as_fallback = false;
BTSession->setSessionSettings(sessionSettings); BTSession->setSessionSettings(sessionSettings);
// Bittorrent // Bittorrent
// * Max connections limit // * Max connections limit
@@ -901,29 +1031,29 @@ void GUI::configureSession(bool deleteOptions) {
// Set DHT Port // Set DHT Port
BTSession->setDHTPort(new_listenPort); BTSession->setDHTPort(new_listenPort);
if(BTSession->enableDHT(true)) { if(BTSession->enableDHT(true)) {
downloadingTorrentTab->setInfoBar(tr("DHT support [ON], port: %1").arg(new_listenPort), QString::fromUtf8("blue")); BTSession->addConsoleMessage(tr("DHT support [ON], port: %1").arg(new_listenPort), QString::fromUtf8("blue"));
} else { } else {
downloadingTorrentTab->setInfoBar(tr("DHT support [OFF]"), QString::fromUtf8("red")); BTSession->addConsoleMessage(tr("DHT support [OFF]"), QString::fromUtf8("red"));
} }
} else { } else {
BTSession->enableDHT(false); BTSession->enableDHT(false);
downloadingTorrentTab->setInfoBar(tr("DHT support [OFF]"), QString::fromUtf8("blue")); BTSession->addConsoleMessage(tr("DHT support [OFF]"), QString::fromUtf8("blue"));
} }
// * PeX // * PeX
if(options->isPeXEnabled()) { if(options->isPeXEnabled()) {
downloadingTorrentTab->setInfoBar(tr("PeX support [ON]"), QString::fromUtf8("blue")); BTSession->addConsoleMessage(tr("PeX support [ON]"), QString::fromUtf8("blue"));
BTSession->enablePeerExchange(); BTSession->enablePeerExchange();
}else{ }else{
// TODO: How can we remove the extension? // TODO: How can we remove the extension?
downloadingTorrentTab->setInfoBar(tr("PeX support [OFF]"), QString::fromUtf8("blue")); BTSession->addConsoleMessage(tr("PeX support [OFF]"), QString::fromUtf8("blue"));
} }
// * LSD // * LSD
if(options->isLSDEnabled()) { if(options->isLSDEnabled()) {
BTSession->enableLSD(true); BTSession->enableLSD(true);
downloadingTorrentTab->setInfoBar(tr("Local Peer Discovery [ON]"), QString::fromUtf8("blue")); BTSession->addConsoleMessage(tr("Local Peer Discovery [ON]"), QString::fromUtf8("blue"));
} else { } else {
BTSession->enableLSD(false); BTSession->enableLSD(false);
downloadingTorrentTab->setInfoBar(tr("Local Peer Discovery support [OFF]"), QString::fromUtf8("blue")); BTSession->addConsoleMessage(tr("Local Peer Discovery support [OFF]"), QString::fromUtf8("blue"));
} }
// * Encryption // * Encryption
int encryptionState = options->getEncryptionSetting(); int encryptionState = options->getEncryptionSetting();
@@ -935,17 +1065,17 @@ void GUI::configureSession(bool deleteOptions) {
case 0: //Enabled case 0: //Enabled
encryptionSettings.out_enc_policy = pe_settings::enabled; encryptionSettings.out_enc_policy = pe_settings::enabled;
encryptionSettings.in_enc_policy = pe_settings::enabled; encryptionSettings.in_enc_policy = pe_settings::enabled;
downloadingTorrentTab->setInfoBar(tr("Encryption support [ON]"), QString::fromUtf8("blue")); BTSession->addConsoleMessage(tr("Encryption support [ON]"), QString::fromUtf8("blue"));
break; break;
case 1: // Forced case 1: // Forced
encryptionSettings.out_enc_policy = pe_settings::forced; encryptionSettings.out_enc_policy = pe_settings::forced;
encryptionSettings.in_enc_policy = pe_settings::forced; encryptionSettings.in_enc_policy = pe_settings::forced;
downloadingTorrentTab->setInfoBar(tr("Encryption support [FORCED]"), QString::fromUtf8("blue")); BTSession->addConsoleMessage(tr("Encryption support [FORCED]"), QString::fromUtf8("blue"));
break; break;
default: // Disabled default: // Disabled
encryptionSettings.out_enc_policy = pe_settings::disabled; encryptionSettings.out_enc_policy = pe_settings::disabled;
encryptionSettings.in_enc_policy = pe_settings::disabled; encryptionSettings.in_enc_policy = pe_settings::disabled;
downloadingTorrentTab->setInfoBar(tr("Encryption support [OFF]"), QString::fromUtf8("blue")); BTSession->addConsoleMessage(tr("Encryption support [OFF]"), QString::fromUtf8("blue"));
} }
BTSession->applyEncryptionSettings(encryptionSettings); BTSession->applyEncryptionSettings(encryptionSettings);
// * Desired ratio // * Desired ratio
@@ -955,10 +1085,44 @@ void GUI::configureSession(bool deleteOptions) {
// Ip Filter // Ip Filter
if(options->isFilteringEnabled()) { if(options->isFilteringEnabled()) {
BTSession->enableIPFilter(options->getFilter()); BTSession->enableIPFilter(options->getFilter());
downloadingTorrentTab->setBottomTabEnabled(1, true);
}else{ }else{
BTSession->disableIPFilter(); BTSession->disableIPFilter();
downloadingTorrentTab->setBottomTabEnabled(1, false); }
// RSS
if(options->isRSSEnabled()) {
displayRSSTab(true);
} else {
displayRSSTab(false);
}
// Queueing System
if(options->isQueueingSystemEnabled()) {
if(!BTSession->isQueueingEnabled()) {
downloadingTorrentTab->hidePriorityColumn(false);
finishedTorrentTab->hidePriorityColumn(false);
actionDecreasePriority->setVisible(true);
actionIncreasePriority->setVisible(true);
prioSeparator->setVisible(true);
prioSeparator2->setVisible(true);
toolBar->layout()->setSpacing(7);
}
int max_torrents = options->getMaxActiveTorrents();
int max_downloads = options->getMaxActiveDownloads();
if(max_torrents < max_downloads)
max_torrents = max_downloads;
BTSession->setMaxActiveTorrents(max_torrents);
BTSession->setMaxActiveDownloads(max_downloads);
BTSession->setQueueingEnabled(true);
} else {
if(BTSession->isQueueingEnabled()) {
BTSession->setQueueingEnabled(false);
downloadingTorrentTab->hidePriorityColumn(true);
finishedTorrentTab->hidePriorityColumn(true);
actionDecreasePriority->setVisible(false);
actionIncreasePriority->setVisible(false);
prioSeparator->setVisible(false);
prioSeparator2->setVisible(false);
toolBar->layout()->setSpacing(7);
}
} }
// Clean up // Clean up
if(deleteOptions) { if(deleteOptions) {
@@ -968,11 +1132,57 @@ void GUI::configureSession(bool deleteOptions) {
} }
void GUI::updateUnfinishedTorrentNumber(unsigned int nb) { void GUI::updateUnfinishedTorrentNumber(unsigned int nb) {
tabs->setTabText(0, tr("Downloads") +QString::fromUtf8(" (")+misc::toQString(nb)+QString::fromUtf8(")")); unsigned int paused = BTSession->getUnfinishedPausedTorrentsNb();
tabs->setTabText(0, tr("Downloads") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")"));
}
void GUI::updateUnfinishedTorrentNumberCalc() {
unsigned int paused = BTSession->getUnfinishedPausedTorrentsNb();
unsigned int nb = BTSession->getUnfinishedTorrents().size();
tabs->setTabText(0, tr("Downloads") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")"));
} }
void GUI::updateFinishedTorrentNumber(unsigned int nb) { void GUI::updateFinishedTorrentNumber(unsigned int nb) {
tabs->setTabText(1, tr("Finished") +QString::fromUtf8(" (")+misc::toQString(nb)+QString::fromUtf8(")")); unsigned int paused = BTSession->getFinishedPausedTorrentsNb();
tabs->setTabText(1, tr("Finished") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")"));
}
void GUI::updateFinishedTorrentNumberCalc() {
unsigned int paused = BTSession->getFinishedPausedTorrentsNb();
unsigned int nb = BTSession->getFinishedTorrents().size();
tabs->setTabText(1, tr("Finished") +QString::fromUtf8(" (")+misc::toQString(nb-paused)+"/"+misc::toQString(nb)+QString::fromUtf8(")"));
}
// Allow to change action on double-click
void GUI::torrentDoubleClicked(QString hash, bool finished) {
int action;
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(finished) {
action = settings.value(QString::fromUtf8("Preferences/Downloads/DblClOnTorFN"), 0).toInt();
} else {
action = settings.value(QString::fromUtf8("Preferences/Downloads/DblClOnTorDl"), 0).toInt();
}
switch(action) {
case TOGGLE_PAUSE:
this->togglePausedState(hash);
break;
case OPEN_DEST: {
QTorrentHandle h = BTSession->getTorrentHandle(hash);
QString savePath = h.save_path();
QDesktopServices::openUrl(QUrl(savePath));
break;
}
case SHOW_PROPERTIES :
if(finished) {
finishedTorrentTab->showPropertiesFromHash(hash);
} else {
downloadingTorrentTab->showPropertiesFromHash(hash);
}
break;
}
} }
// Toggle paused state of selected torrent // Toggle paused state of selected torrent
@@ -982,22 +1192,24 @@ void GUI::togglePausedState(QString hash) {
if(tabs->currentIndex() == 1) if(tabs->currentIndex() == 1)
inDownloadList = false; inDownloadList = false;
QTorrentHandle h = BTSession->getTorrentHandle(hash); QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(BTSession->isPaused(hash)) { if(BTSession->isPaused(hash) && !(BTSession->isQueueingEnabled() && (BTSession->isDownloadQueued(hash) || BTSession->isUploadQueued(hash)))) {
BTSession->resumeTorrent(hash); BTSession->resumeTorrent(hash);
downloadingTorrentTab->setInfoBar(tr("'%1' resumed.", "e.g: xxx.avi resumed.").arg(h.name()));
if(inDownloadList) { if(inDownloadList) {
downloadingTorrentTab->resumeTorrent(hash); downloadingTorrentTab->resumeTorrent(hash);
updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList());
}else{ }else{
finishedTorrentTab->resumeTorrent(hash); finishedTorrentTab->resumeTorrent(hash);
updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
} }
}else{ }else{
BTSession->pauseTorrent(hash); BTSession->pauseTorrent(hash);
if(inDownloadList) { if(inDownloadList) {
downloadingTorrentTab->pauseTorrent(hash); downloadingTorrentTab->pauseTorrent(hash);
updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList());
}else{ }else{
finishedTorrentTab->pauseTorrent(hash); finishedTorrentTab->pauseTorrent(hash);
updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
} }
downloadingTorrentTab->setInfoBar(tr("'%1' paused.", "xxx.avi paused.").arg(h.name()));
} }
} }
@@ -1019,8 +1231,55 @@ void GUI::on_actionPause_All_triggered() {
finishedTorrentTab->pauseTorrent(hash); finishedTorrentTab->pauseTorrent(hash);
} }
} }
if(change) if(change) {
downloadingTorrentTab->setInfoBar(tr("All downloads were paused.")); updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList());
updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
}
}
void GUI::on_actionIncreasePriority_triggered() {
bool inDownloadList = true;
if(tabs->currentIndex() > 1) return;
if(tabs->currentIndex() == 1)
inDownloadList = false;
QStringList hashes;
if(inDownloadList) {
hashes = downloadingTorrentTab->getSelectedTorrents();
} else {
hashes = finishedTorrentTab->getSelectedTorrents();
}
foreach(QString hash, hashes) {
if(inDownloadList) {
BTSession->increaseDlTorrentPriority(hash);
downloadingTorrentTab->updateDlList();
} else {
BTSession->increaseUpTorrentPriority(hash);
finishedTorrentTab->updateFinishedList();
}
}
}
void GUI::on_actionDecreasePriority_triggered() {
bool inDownloadList = true;
if(tabs->currentIndex() > 1) return;
if(tabs->currentIndex() == 1)
inDownloadList = false;
QStringList hashes;
if(inDownloadList) {
hashes = downloadingTorrentTab->getSelectedTorrents();
} else {
hashes = finishedTorrentTab->getSelectedTorrents();
}
QString hash;
foreach(QString hash, hashes) {
if(inDownloadList) {
BTSession->decreaseDlTorrentPriority(hash);
downloadingTorrentTab->updateDlList();
} else {
BTSession->decreaseUpTorrentPriority(hash);
finishedTorrentTab->updateFinishedList();
}
}
} }
// pause selected items in the list // pause selected items in the list
@@ -1040,13 +1299,21 @@ void GUI::on_actionPause_triggered() {
if(BTSession->pauseTorrent(hash)){ if(BTSession->pauseTorrent(hash)){
if(inDownloadList) { if(inDownloadList) {
downloadingTorrentTab->pauseTorrent(hash); downloadingTorrentTab->pauseTorrent(hash);
updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList());
} else { } else {
finishedTorrentTab->pauseTorrent(hash); finishedTorrentTab->pauseTorrent(hash);
} updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
downloadingTorrentTab->setInfoBar(tr("'%1' paused.", "xxx.avi paused.").arg(BTSession->getTorrentHandle(hash).name()));
} }
} }
} }
}
void GUI::pauseTorrent(QString hash) {
downloadingTorrentTab->pauseTorrent(hash);
finishedTorrentTab->pauseTorrent(hash);
updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList());
updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
}
// Resume All Downloads in DL list // Resume All Downloads in DL list
void GUI::on_actionStart_All_triggered() { void GUI::on_actionStart_All_triggered() {
@@ -1066,8 +1333,10 @@ void GUI::on_actionStart_All_triggered() {
finishedTorrentTab->resumeTorrent(hash); finishedTorrentTab->resumeTorrent(hash);
} }
} }
if(change) if(change) {
downloadingTorrentTab->setInfoBar(tr("All downloads were resumed.")); updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList());
updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
}
} }
// start selected items in the list // start selected items in the list
@@ -1087,10 +1356,11 @@ void GUI::on_actionStart_triggered() {
if(BTSession->resumeTorrent(hash)){ if(BTSession->resumeTorrent(hash)){
if(inDownloadList) { if(inDownloadList) {
downloadingTorrentTab->resumeTorrent(hash); downloadingTorrentTab->resumeTorrent(hash);
updateUnfinishedTorrentNumber(downloadingTorrentTab->getNbTorrentsInList());
} else { } else {
finishedTorrentTab->resumeTorrent(hash); finishedTorrentTab->resumeTorrent(hash);
updateFinishedTorrentNumber(finishedTorrentTab->getNbTorrentsInList());
} }
downloadingTorrentTab->setInfoBar(tr("'%1' resumed.", "e.g: xxx.avi resumed.").arg(BTSession->getTorrentHandle(hash).name()));
} }
} }
} }
@@ -1115,6 +1385,9 @@ void GUI::on_actionTorrent_Properties_triggered() {
} }
void GUI::updateLists() { void GUI::updateLists() {
// update global informations
dlSpeedLbl->setText(tr("DL: %1 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadDownloadRate()/1024., 'f', 1))));
upSpeedLbl->setText(tr("UP: %1 KiB/s").arg(QString(QByteArray::number(BTSession->getPayloadUploadRate()/1024., 'f', 1))));
switch(getCurrentTabIndex()){ switch(getCurrentTabIndex()){
case 0: case 0:
downloadingTorrentTab->updateDlList(); downloadingTorrentTab->updateDlList();
@@ -1144,8 +1417,7 @@ void GUI::trackerAuthenticationRequired(QTorrentHandle& h) {
void GUI::checkConnectionStatus() { void GUI::checkConnectionStatus() {
// qDebug("Checking connection status"); // qDebug("Checking connection status");
// Update Ratio // Update Ratio
if(getCurrentTabIndex() == 0) updateRatio();
downloadingTorrentTab->updateRatio();
// update global informations // update global informations
if(systrayIntegration) { if(systrayIntegration) {
QString html = "<div style='background-color: #678db2; color: #fff;height: 18px; font-weight: bold; margin-bottom: 5px;'>"; QString html = "<div style='background-color: #678db2; color: #fff;height: 18px; font-weight: bold; margin-bottom: 5px;'>";
@@ -1165,15 +1437,8 @@ void GUI::checkConnectionStatus() {
connecStatusLblIcon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/connected.png"))); connecStatusLblIcon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/connected.png")));
connecStatusLblIcon->setToolTip(QString::fromUtf8("<b>")+tr("Connection Status:")+QString::fromUtf8("</b><br>")+tr("Online")); connecStatusLblIcon->setToolTip(QString::fromUtf8("<b>")+tr("Connection Status:")+QString::fromUtf8("</b><br>")+tr("Online"));
}else{ }else{
if(sessionStatus.num_peers) {
// Firewalled ?
connecStatusLblIcon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/firewalled.png"))); connecStatusLblIcon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/firewalled.png")));
connecStatusLblIcon->setToolTip("<b>"+tr("Connection Status:")+QString::fromUtf8("</b><br>")+tr("Firewalled?", "i.e: Behind a firewall/router?")+QString::fromUtf8("<br><i>")+tr("No incoming connections...")+QString::fromUtf8("</i>")); connecStatusLblIcon->setToolTip(QString::fromUtf8("<b>")+tr("Connection status:")+QString::fromUtf8("</b><br>")+QString::fromUtf8("<i>")+tr("No direct connections. This may indicate network configuration problems.")+QString::fromUtf8("</i>"));
}else{
// Disconnected
connecStatusLblIcon->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/disconnected.png")));
connecStatusLblIcon->setToolTip(QString::fromUtf8("<b>")+tr("Connection status:")+QString::fromUtf8("</b><br>")+tr("Offline")+QString::fromUtf8("<br><i>")+tr("No peers found...")+QString::fromUtf8("</i>"));
}
} }
} }
@@ -1201,7 +1466,6 @@ void GUI::createSystrayDelayed() {
createTrayIcon(); createTrayIcon();
systrayIntegration = true; systrayIntegration = true;
delete systrayCreator; delete systrayCreator;
systrayCreator = 0;
} else { } else {
if(timeout) { if(timeout) {
// Retry a bit later // Retry a bit later
@@ -1211,7 +1475,6 @@ void GUI::createSystrayDelayed() {
// Timed out, apparently system really does not // Timed out, apparently system really does not
// support systray icon // support systray icon
delete systrayCreator; delete systrayCreator;
systrayCreator = 0;
} }
} }
} }
@@ -1251,7 +1514,8 @@ void GUI::on_actionOptions_triggered() {
} }
// Is executed each time options are saved // Is executed each time options are saved
void GUI::OptionsSaved(QString info, bool deleteOptions) { void GUI::OptionsSaved(bool deleteOptions) {
BTSession->addConsoleMessage(tr("Options were saved successfully."));
bool newSystrayIntegration = options->systrayIntegration(); bool newSystrayIntegration = options->systrayIntegration();
if(newSystrayIntegration && !systrayIntegration) { if(newSystrayIntegration && !systrayIntegration) {
// create the trayicon // create the trayicon
@@ -1263,12 +1527,39 @@ void GUI::OptionsSaved(QString info, bool deleteOptions) {
delete myTrayIconMenu; delete myTrayIconMenu;
} }
systrayIntegration = newSystrayIntegration; systrayIntegration = newSystrayIntegration;
// Update info bar // Update Web UI
downloadingTorrentTab->setInfoBar(info); if (options->isWebUiEnabled())
{
quint16 port = options->webUiPort();
QString username = options->webUiUsername();
QString password = options->webUiPassword();
initWebUi(username, password, port);
}
else if(httpServer)
{
delete httpServer;
}
// Update session // Update session
configureSession(deleteOptions); configureSession(deleteOptions);
} }
bool GUI::initWebUi(QString username, QString password, int port)
{
if(httpServer)
{
httpServer->close();
}
else
httpServer = new HttpServer(BTSession, 1000, this);
httpServer->setAuthorization(username, password);
bool success = httpServer->listen(QHostAddress::Any, port);
if (success)
qDebug("Web UI listening on port %d", port);
else
QMessageBox::critical(this, "Web User Interface Error", "Unable to initialize HTTP Server on port " + misc::toQString(port));
return success;
}
/***************************************************** /*****************************************************
* * * *
* HTTP Downloader * * HTTP Downloader *

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;
#ifdef QT_4_4
class QLocalServer;
class QLocalSocket;
#else
class QTcpServer; class QTcpServer;
class QTcpSocket; 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
@@ -59,7 +66,7 @@ class GUI : public QMainWindow, private Ui::MainWindow{
QTabWidget *tabs; QTabWidget *tabs;
options_imp *options; options_imp *options;
QSystemTrayIcon *myTrayIcon; QSystemTrayIcon *myTrayIcon;
QTimer *systrayCreator; QPointer<QTimer> systrayCreator;
QMenu *myTrayIconMenu; QMenu *myTrayIconMenu;
DownloadingTorrents *downloadingTorrentTab; DownloadingTorrents *downloadingTorrentTab;
FinishedTorrents *finishedTorrentTab; FinishedTorrents *finishedTorrentTab;
@@ -69,19 +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;
QAction *prioSeparator;
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
@@ -92,9 +116,11 @@ 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 balloonClicked(); void balloonClicked();
@@ -102,6 +128,8 @@ class GUI : public QMainWindow, private Ui::MainWindow{
void readSettings(); void readSettings();
void on_actionExit_triggered(); void on_actionExit_triggered();
void createTrayIcon(); void createTrayIcon();
void updateUnfinishedTorrentNumberCalc();
void updateFinishedTorrentNumberCalc();
void updateUnfinishedTorrentNumber(unsigned int nb); void updateUnfinishedTorrentNumber(unsigned int nb);
void updateFinishedTorrentNumber(unsigned int nb); void updateFinishedTorrentNumber(unsigned int nb);
void fullDiskError(QTorrentHandle& h) const; void fullDiskError(QTorrentHandle& h) const;
@@ -133,13 +161,16 @@ class GUI : public QMainWindow, private Ui::MainWindow{
void processScannedFiles(const QStringList& params); 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 updateLists(); void updateLists();
bool initWebUi(QString username, QString password, int port);
void pauseTorrent(QString hash);
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();
@@ -147,10 +178,14 @@ 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 *); bool event(QEvent * event);
void displayRSSTab(bool enable);
public: public:
// Construct / Destruct // Construct / Destruct

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.2.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

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

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>

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,9 +72,9 @@ 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> 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>"));

View File

@@ -234,7 +234,7 @@ 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);

File diff suppressed because it is too large Load Diff

View File

@@ -26,6 +26,9 @@
#include <QPair> #include <QPair>
#include <QStringList> #include <QStringList>
#include <QDateTime> #include <QDateTime>
#include <QApplication>
#include <QPalette>
#include <QPointer>
#include <libtorrent/session.hpp> #include <libtorrent/session.hpp>
#include <libtorrent/ip_filter.hpp> #include <libtorrent/ip_filter.hpp>
@@ -36,6 +39,7 @@ using namespace libtorrent;
class downloadThread; class downloadThread;
class deleteThread; class deleteThread;
class QTimer; class QTimer;
class FilterParserThread;
class bittorrent : public QObject { class bittorrent : public QObject {
Q_OBJECT Q_OBJECT
@@ -43,18 +47,19 @@ class bittorrent : public QObject{
private: private:
session *s; session *s;
QString scan_dir; QString scan_dir;
QTimer *timerScan; QPointer<QTimer> timerScan;
QTimer *timerAlerts; QTimer *timerAlerts;
QTimer *fastResumeSaver; QTimer *fastResumeSaver;
QTimer *BigRatioTimer; QPointer<QTimer> BigRatioTimer;
bool DHTEnabled; bool DHTEnabled;
downloadThread *downloader; downloadThread *downloader;
QString defaultSavePath; QString defaultSavePath;
QStringList torrentsToPauseAfterChecking;
QHash<QString, QDateTime> TorrentsStartTime; QHash<QString, QDateTime> TorrentsStartTime;
QHash<QString, size_type> TorrentsStartData; QHash<QString, size_type> TorrentsStartData;
QHash<QString, QPair<size_type,size_type> > ratioData; QHash<QString, QPair<size_type,size_type> > ratioData;
QHash<QString, QList<QPair<QString, QString> > > trackersErrors; QHash<QString, QHash<QString, QString> > trackersErrors;
QStringList consoleMessages;
QStringList peerBanMessages;
deleteThread *deleter; deleteThread *deleter;
QStringList finishedTorrents; QStringList finishedTorrents;
QStringList unfinishedTorrents; QStringList unfinishedTorrents;
@@ -66,6 +71,19 @@ class bittorrent : public QObject{
bool UPnPEnabled; bool UPnPEnabled;
bool NATPMPEnabled; bool NATPMPEnabled;
bool LSDEnabled; bool LSDEnabled;
QPointer<FilterParserThread> filterParser;
QString filterPath;
int folderScanInterval; // in seconds
bool queueingEnabled;
int maxActiveDownloads;
int maxActiveTorrents;
int currentActiveDownloads;
QStringList *downloadQueue;
QStringList *queuedDownloads;
QStringList *uploadQueue;
QStringList *queuedUploads;
bool calculateETA;
QStringList url_skippingDlg;
protected: protected:
QString getSavePath(QString hash); QString getSavePath(QString hash);
@@ -82,15 +100,27 @@ class bittorrent : public QObject{
float getPayloadUploadRate() const; float getPayloadUploadRate() const;
session_status getSessionStatus() const; session_status getSessionStatus() const;
int getListenPort() const; int getListenPort() const;
QStringList getTorrentsToPauseAfterChecking() const;
qlonglong getETA(QString hash) const; qlonglong 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 getFinishedTorrents() const;
QStringList getUnfinishedTorrents() const; QStringList getUnfinishedTorrents() const;
bool isFinished(QString hash) 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;
bool isDownloadQueued(QString hash) const;
bool isUploadQueued(QString hash) const;
int loadTorrentPriority(QString hash);
QStringList getConsoleMessages() const;
QStringList getPeerBanMessages() const;
float getUncheckedTorrentProgress(QString hash) const;
public slots: public slots:
void addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false); void addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false);
@@ -99,6 +129,8 @@ class bittorrent : public QObject{
void deleteTorrent(QString hash, bool permanent = false); void deleteTorrent(QString hash, bool permanent = false);
bool pauseTorrent(QString hash); bool pauseTorrent(QString hash);
bool resumeTorrent(QString hash); bool resumeTorrent(QString hash);
void pauseAllTorrents();
void resumeAllTorrents();
void saveDHTEntry(); void saveDHTEntry();
void preAllocateAllFiles(bool b); void preAllocateAllFiles(bool b);
void saveFastResumeAndRatioData(); void saveFastResumeAndRatioData();
@@ -106,8 +138,9 @@ class bittorrent : public QObject{
void enableDirectoryScanning(QString scan_dir); void enableDirectoryScanning(QString scan_dir);
void disableDirectoryScanning(); void disableDirectoryScanning();
void enablePeerExchange(); void enablePeerExchange();
void enableIPFilter(ip_filter filter); void enableIPFilter(QString filter);
void disableIPFilter(); void disableIPFilter();
void setQueueingEnabled(bool enable);
void resumeUnfinishedTorrents(); void resumeUnfinishedTorrents();
void saveTorrentSpeedLimits(QString hash); void saveTorrentSpeedLimits(QString hash);
void loadTorrentSpeedLimits(QString hash); void loadTorrentSpeedLimits(QString hash);
@@ -115,6 +148,14 @@ class bittorrent : public QObject{
void loadDownloadUploadForTorrent(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 updateDownloadQueue();
void updateUploadQueue();
void increaseDlTorrentPriority(QString hash);
void decreaseDlTorrentPriority(QString hash);
void increaseUpTorrentPriority(QString hash);
void decreaseUpTorrentPriority(QString hash);
void saveTorrentPriority(QString hash, int prio);
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);
@@ -140,6 +181,12 @@ class bittorrent : public QObject{
void enableLSD(bool b); void enableLSD(bool b);
bool enableDHT(bool b); bool enableDHT(bool b);
void reloadTorrent(const QTorrentHandle &h, bool full_alloc); void reloadTorrent(const QTorrentHandle &h, bool full_alloc);
void setTimerScanInterval(int secs);
void setMaxActiveDownloads(int val);
void setMaxActiveTorrents(int val);
void setETACalculation(bool enable);
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();
@@ -150,24 +197,33 @@ class bittorrent : public QObject{
void deleteBigRatios(); void deleteBigRatios();
signals: signals:
void invalidTorrent(QString path); //void invalidTorrent(QString path);
void duplicateTorrent(QString path); //void duplicateTorrent(QString path);
void addedTorrent(QString path, QTorrentHandle& h, bool fastResume); void addedTorrent(QTorrentHandle& h);
void deletedTorrent(QString hash);
void pausedTorrent(QString hash);
void resumedTorrent(QString hash);
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 portListeningFailure();
void trackerAuthenticationRequired(QTorrentHandle& h); void trackerAuthenticationRequired(QTorrentHandle& h);
void scanDirFoundTorrents(const QStringList& pathList); void scanDirFoundTorrents(const QStringList& pathList);
void newDownloadedTorrent(QString path, QString url); void newDownloadedTorrent(QString path, QString url);
void aboutToDownloadFromUrl(QString url); //void aboutToDownloadFromUrl(QString url);
void updateFileSize(QString hash); void updateFileSize(QString hash);
void peerBlocked(QString); //void peerBlocked(QString);
void downloadFromUrlFailure(QString url, QString reason); void downloadFromUrlFailure(QString url, QString reason);
void fastResumeDataRejected(QString name); //void fastResumeDataRejected(QString name);
void urlSeedProblem(QString url, QString msg); //void urlSeedProblem(QString url, QString msg);
void torrentFinishedChecking(QString hash); //void torrentFinishedChecking(QString hash);
void torrent_deleted(QString hash, QString fileName, bool finished); //void torrent_ratio_deleted(QString fileName);
//void UPnPError(QString msg);
//void UPnPSuccess(QString msg);
void updateFinishedTorrentNumber();
void updateUnfinishedTorrentNumber();
void forceUnfinishedListUpdate();
void forceFinishedListUpdate();
}; };
#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

@@ -44,9 +44,17 @@ using namespace boost::filesystem;
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();
connect(creatorThread, SIGNAL(creationSuccess(QString, const char*, QString)), this, SLOT(handleCreationSuccess(QString, const char*, QString)));
connect(creatorThread, SIGNAL(creationFailure(QString)), this, SLOT(handleCreationFailure(QString)));
connect(creatorThread, SIGNAL(updateProgress(int)), this, SLOT(updateProgressBar(int)));
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())
@@ -121,11 +129,22 @@ void createtorrent::on_addURLSeed_button_clicked(){
// Subfunction to add files to a torrent_info structure // Subfunction to add files to a torrent_info structure
// Written by Arvid Norberg (libtorrent Author) // Written by Arvid Norberg (libtorrent Author)
void add_files(torrent_info& t, path const& p, path const& l){ void add_files(torrent_info& t, path const& p, path const& l){
qDebug("p: %s, l: %s, l.leaf(): %s", p.string().c_str(), l.string().c_str(), l.leaf().c_str()); using boost::filesystem::path;
using boost::filesystem::directory_iterator;
#if BOOST_VERSION < 103600
std::string const& leaf = l.leaf();
#else
std::string const& leaf = l.filename();
#endif
if (leaf == ".." || leaf == ".") return;
path f(p / l); path f(p / l);
if (is_directory(f)) { if (is_directory(f)) {
for (directory_iterator i(f), end; i != end; ++i) for (directory_iterator i(f), end; i != end; ++i)
#if BOOST_VERSION < 103600
add_files(t, p, l / i->leaf()); add_files(t, p, l / i->leaf());
#else
add_files(t, p, l / i->filename());
#endif
} else { } else {
qDebug("Adding %s", l.string().c_str()); qDebug("Adding %s", l.string().c_str());
t.add_file(l, file_size(f)); t.add_file(l, file_size(f));
@@ -162,26 +181,74 @@ 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, QString hash) {
if(checkStartSeeding->isChecked()) {
// Create save path file
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 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); boost::intrusive_ptr<torrent_info> t(new torrent_info);
ofstream out(complete(path((const char*)destination.toUtf8())), std::ios_base::binary); ofstream out(complete(path((const char*)save_path.toUtf8())), std::ios_base::binary);
// Adding files to the torrent // Adding files to the torrent
path full_path = complete(path(input.toUtf8().data())); path full_path = complete(path(input_path.toUtf8().data()));
#if BOOST_VERSION < 103600
add_files(*t, full_path.branch_path(), full_path.leaf()); add_files(*t, full_path.branch_path(), full_path.leaf());
#else
add_files(*t, full_path.branch_path(), full_path.filename());
#endif
if(abort) return;
// Set piece size // Set piece size
int piece_size = getPieceSize();
t->set_piece_size(piece_size); 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; file_pool fp;
boost::scoped_ptr<storage_interface> st(default_storage_constructor(t, full_path.branch_path(), fp)); boost::scoped_ptr<storage_interface> st(default_storage_constructor(t, full_path.branch_path(), fp));
@@ -191,34 +258,26 @@ void createtorrent::on_createButton_clicked(){
st->read(&buf[0], i, 0, t->piece_size(i)); st->read(&buf[0], i, 0, t->piece_size(i));
hasher h(&buf[0], t->piece_size(i)); hasher h(&buf[0], t->piece_size(i));
t->set_hash(i, h.final()); t->set_hash(i, h.final());
emit updateProgress((int)(i*100./(float)num));
if(abort) return;
} }
// 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(); entry e = t->create_torrent();
libtorrent::bencode(std::ostream_iterator<char>(out), e); libtorrent::bencode(std::ostream_iterator<char>(out), e);
out.flush(); out.flush();
if(checkStartSeeding->isChecked()) { emit updateProgress(100);
// Create save path file emit creationSuccess(save_path, full_path.branch_path().string().c_str(), misc::toQString(t->info_hash()));
QFile savepath_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+misc::toQString(t->info_hash())+QString::fromUtf8(".savepath"));
savepath_file.open(QIODevice::WriteOnly | QIODevice::Text);
savepath_file.write(full_path.branch_path().string().c_str());
savepath_file.close();
emit torrent_to_seed(destination);
}
} }
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,13 +22,48 @@
#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;
public:
torrentCreatorThread() {}
~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, QString hash);
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;
@@ -43,6 +78,9 @@ 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, QString hash);
void updateProgressBar(int progress);
}; };
#endif #endif

View File

@@ -35,27 +35,30 @@ class subDeleteThread : public QThread {
private: private:
QString save_path; QString save_path;
arborescence *arb; arborescence *arb;
bool abort;
public: public:
subDeleteThread(QObject *parent, QString saveDir, arborescence *arb) : QThread(parent), save_path(saveDir), arb(arb), abort(false){} subDeleteThread(QObject *parent, QString saveDir, arborescence *_arb) : QThread(parent), save_path(saveDir) {
arb = _arb;
}
~subDeleteThread(){ ~subDeleteThread(){
abort = true; qDebug("subDeleteThread successfuly deleted");
wait(); //wait();
} }
signals: signals:
// For subthreads // For subthreads
void deletionSuccessST(subDeleteThread* st); void deletionSuccessST(subDeleteThread* st);
void deletionFailureST(subDeleteThread* st); //void deletionFailureST(subDeleteThread* st);
protected: protected:
void run(){ void run(){
if(arb->removeFromFS(save_path)) /*if(arb->removeFromFS(save_path))
emit deletionSuccessST(this); emit deletionSuccessST(this);
else else
emit deletionFailureST(this); emit deletionFailureST(this);*/
arb->removeFromFS(save_path);
emit deletionSuccessST(this);
delete arb; delete arb;
} }
}; };
@@ -99,13 +102,13 @@ class deleteThread : public QThread {
if(abort) if(abort)
return; return;
mutex.lock(); mutex.lock();
if(torrents_list.size() != 0){ if(!torrents_list.empty()){
QPair<QString, arborescence *> torrent = torrents_list.takeFirst(); QPair<QString, arborescence *> torrent = torrents_list.takeFirst();
mutex.unlock(); mutex.unlock();
subDeleteThread *st = new subDeleteThread(0, torrent.first, torrent.second); subDeleteThread *st = new subDeleteThread(0, torrent.first, torrent.second);
subThreads << st; subThreads << st;
connect(st, SIGNAL(deletionSuccessST(subDeleteThread*)), this, SLOT(deleteSubThread(subDeleteThread*))); connect(st, SIGNAL(deletionSuccessST(subDeleteThread*)), this, SLOT(deleteSubThread(subDeleteThread*)));
connect(st, SIGNAL(deletionFailureST(subDeleteThread*)), this, SLOT(deleteSubThread(subDeleteThread*))); //connect(st, SIGNAL(deletionFailureST(subDeleteThread*)), this, SLOT(deleteSubThread(subDeleteThread*)));
st->start(); st->start();
}else{ }else{
condition.wait(&mutex); condition.wait(&mutex);

View File

@@ -18,188 +18,18 @@
<property name="spacing" > <property name="spacing" >
<number>6</number> <number>6</number>
</property> </property>
<property name="margin" > <property name="leftMargin" >
<number>0</number> <number>0</number>
</property> </property>
<item> <property name="topMargin" >
<layout class="QHBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin" >
<number>0</number> <number>0</number>
</property> </property>
<item> <property name="rightMargin" >
<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> <number>0</number>
</property> </property>
</widget> <property name="bottomMargin" >
</item> <number>0</number>
<item>
<widget class="QLabel" name="unitDL" >
<property name="text" >
<string>KiB/s</string>
</property> </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 +57,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 +73,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 +98,86 @@
<string>Torrent Properties</string> <string>Torrent Properties</string>
</property> </property>
</action> </action>
<action name="actionOpen_destination_folder" >
<property name="icon" >
<iconset resource="icons.qrc" >:/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" >:/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" >:/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" >:/Icons/skin/decrease.png</iconset>
</property>
<property name="text" >
<string>Decrease priority</string>
</property>
</action>
</widget> </widget>
<resources/> <resources>
<include location="icons.qrc" />
</resources>
<connections/> <connections/>
</ui> </ui>

View File

@@ -24,6 +24,8 @@
#include <QSettings> #include <QSettings>
#include <stdio.h> #include <stdio.h>
#define MAX_THREADS 3
// http://curl.rtin.bz/libcurl/c/libcurl-errors.html // http://curl.rtin.bz/libcurl/c/libcurl-errors.html
QString subDownloadThread::errorCodeToString(CURLcode status) { QString subDownloadThread::errorCodeToString(CURLcode status) {
switch(status){ switch(status){
@@ -150,9 +152,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{
@@ -165,8 +165,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;
@@ -187,9 +187,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();
} }
@@ -200,8 +200,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

@@ -30,6 +30,7 @@
#include <QWaitCondition> #include <QWaitCondition>
#include <QStringList> #include <QStringList>
#include <curl/curl.h> #include <curl/curl.h>
#include <QQueue>
class subDownloadThread : public QThread { class subDownloadThread : public QThread {
Q_OBJECT Q_OBJECT
@@ -55,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;

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,18 @@ 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(addedTorrent(QTorrentHandle&)), this, SLOT(torrentAdded(QTorrentHandle&)));
connect(BTSession, SIGNAL(duplicateTorrent(QString)), this, SLOT(torrentDuplicate(QString))); connect(BTSession, SIGNAL(forceUnfinishedListUpdate()), this, SLOT(updateDlList()));
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 +79,56 @@ 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(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,19 +155,16 @@ 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();
} }
@@ -181,26 +187,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;
}
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;
@@ -278,14 +264,201 @@ 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(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;
if(index == ETA) {
BTSession->setETACalculation(false);
qDebug("Disable ETA calculation");
}
} else {
// User want to display the column
downloadList->setColumnHidden(index, false);
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
++nbVisibleColumns;
if(index == ETA) {
BTSession->setETACalculation(true);
qDebug("Enable ETA calculation");
}
}
//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{
@@ -303,53 +476,9 @@ 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() { void DownloadingTorrents::updateDlList() {
// update global informations
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 // browse handles
QStringList unfinishedTorrents = BTSession->getUnfinishedTorrents(); QStringList unfinishedTorrents = BTSession->getUnfinishedTorrents();
QString hash; QString hash;
@@ -368,12 +497,19 @@ void DownloadingTorrents::updateDlList() {
row = getRowFromHash(hash); row = getRowFromHash(hash);
} }
Q_ASSERT(row != -1); Q_ASSERT(row != -1);
// Update Priority
if(BTSession->isQueueingEnabled()) {
DLListModel->setData(DLListModel->index(row, PRIORITY), QVariant((int)BTSession->getDlTorrentPriority(hash)));
if(h.is_paused() && BTSession->isDownloadQueued(hash)) {
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));
}
setRowColor(row, QString::fromUtf8("grey"));
}
}
// No need to update a paused torrent // No need to update a paused torrent
if(h.is_paused()) continue; if(h.is_paused()) continue;
if(BTSession->getTorrentsToPauseAfterChecking().indexOf(hash) != -1) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
continue;
}
// Parse download state // Parse download state
// Setting download state // Setting download state
switch(h.state()) { switch(h.state()) {
@@ -388,43 +524,71 @@ void DownloadingTorrents::updateDlList() {
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"));
if(!downloadList->isColumnHidden(PROGRESS)) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress())); DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
}
break; break;
case torrent_status::connecting_to_tracker: case torrent_status::connecting_to_tracker:
if(h.download_payload_rate() > 0) { if(h.download_payload_rate() > 0) {
// Display "Downloading" status when connecting if download speed > 0 // Display "Downloading" status when connecting if download speed > 0
if(!downloadList->isColumnHidden(ETA)) {
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)BTSession->getETA(hash))); 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); DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/downloading.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("green")); setRowColor(row, QString::fromUtf8("green"));
}else{ }else{
if(!downloadList->isColumnHidden(ETA)) {
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1)); 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); DLListModel->setData(DLListModel->index(row, NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/connecting.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey")); setRowColor(row, QString::fromUtf8("grey"));
} }
if(!downloadList->isColumnHidden(PROGRESS)) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress())); DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
}
if(!downloadList->isColumnHidden(DLSPEED)) {
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)h.download_payload_rate())); 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, 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);
if(!downloadList->isColumnHidden(ETA)) {
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)BTSession->getETA(hash))); 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);
if(!downloadList->isColumnHidden(ETA)) {
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1)); DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
}
setRowColor(row, QApplication::palette().color(QPalette::WindowText)); setRowColor(row, QApplication::palette().color(QPalette::WindowText));
} }
if(!downloadList->isColumnHidden(PROGRESS)) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress())); DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)h.progress()));
}
if(!downloadList->isColumnHidden(DLSPEED)) {
DLListModel->setData(DLListModel->index(row, DLSPEED), QVariant((double)h.download_payload_rate())); 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, UPSPEED), QVariant((double)h.upload_payload_rate()));
}
break; break;
default: default:
if(!downloadList->isColumnHidden(ETA)) {
DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1)); DLListModel->setData(DLListModel->index(row, ETA), QVariant((qlonglong)-1));
} }
}
if(!downloadList->isColumnHidden(SEEDSLEECH)) {
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(misc::toQString(h.num_seeds(), true)+QString::fromUtf8("/")+misc::toQString(h.num_peers() - h.num_seeds(), true))); 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(RATIO)) {
DLListModel->setData(DLListModel->index(row, RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash)))); DLListModel->setData(DLListModel->index(row, RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash))));
}
}catch(invalid_handle e) { }catch(invalid_handle e) {
continue; continue;
} }
@@ -437,6 +601,7 @@ void DownloadingTorrents::addTorrent(QString 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
@@ -447,9 +612,12 @@ void DownloadingTorrents::addTorrent(QString hash) {
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, 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 was paused last time
if(BTSession->isPaused(hash)) { if(BTSession->isPaused(hash)) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)BTSession->getUncheckedTorrentProgress(hash)));
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{
@@ -458,6 +626,7 @@ void DownloadingTorrents::addTorrent(QString hash) {
} }
++nbTorrents; ++nbTorrents;
emit unfinishedTorrentsNumberChanged(nbTorrents); emit unfinishedTorrentsNumberChanged(nbTorrents);
sortDownloadList();
} }
void DownloadingTorrents::sortDownloadListFloat(int index, Qt::SortOrder sortOrder) { void DownloadingTorrents::sortDownloadListFloat(int index, Qt::SortOrder sortOrder) {
@@ -506,27 +675,36 @@ 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:
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::sortDownloadList(int index, Qt::SortOrder sortOrder) {
else if(index == -1) {
downloadList->header()->setSortIndicator(index, Qt::DescendingOrder); index = downloadList->header()->sortIndicatorSection();
sortOrder = downloadList->header()->sortIndicatorOrder();
} else { } else {
downloadList->header()->setSortIndicator(index, sortOrder); downloadList->header()->setSortIndicator(index, sortOrder);
} }
@@ -535,23 +713,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) {
// 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); 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
@@ -560,11 +728,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");
} }
@@ -585,7 +768,14 @@ 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());
} }
loadLastSortedColumn();
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;
@@ -595,18 +785,17 @@ 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 // Called when a torrent is added
void DownloadingTorrents::torrentAdded(QString path, QTorrentHandle& h, bool fastResume) { void DownloadingTorrents::torrentAdded(QTorrentHandle& h) {
QString hash = h.hash(); QString hash = h.hash();
if(BTSession->isFinished(hash)) { if(BTSession->isFinished(hash)) {
return; return;
} }
if(getRowFromHash(hash) != -1) return;
int row = DLListModel->rowCount(); int row = DLListModel->rowCount();
// Adding torrent to download list // Adding torrent to download list
DLListModel->insertRow(row); DLListModel->insertRow(row);
@@ -621,29 +810,16 @@ void DownloadingTorrents::torrentAdded(QString path, QTorrentHandle& h, bool fas
// Pause torrent if it was paused last time // Pause torrent if it was paused last time
// Not using isPaused function because torrents are paused after checking now // 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"))) { if(QFile::exists(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".paused"))) {
DLListModel->setData(DLListModel->index(row, PROGRESS), QVariant((double)BTSession->getUncheckedTorrentProgress(hash)));
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/connecting.png"))), Qt::DecorationRole);
setRowColor(row, QString::fromUtf8("grey")); 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; ++nbTorrents;
emit unfinishedTorrentsNumberChanged(nbTorrents); emit unfinishedTorrentsNumberChanged(nbTorrents);
} sortDownloadList();
// 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) {
@@ -651,13 +827,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
@@ -679,7 +849,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,48 @@ 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); 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 addTorrent(QString hash); void addTorrent(QString hash);
void sortDownloadList(int index, Qt::SortOrder startSortOrder=Qt::AscendingOrder, bool fromLoadColWidth=false); void sortDownloadList(int index=-1, Qt::SortOrder startSortOrder=Qt::AscendingOrder);
void toggleDownloadListSortOrder(int index);
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 torrentAdded(QTorrentHandle& h);
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 loadLastSortedColumn();
public slots: public slots:
void updateDlList(); void updateDlList();
void setInfoBar(QString info, QColor color=QApplication::palette().color(QPalette::WindowText));
void pauseTorrent(QString hash); void pauseTorrent(QString hash);
void resumeTorrent(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);
}; };

189
src/eventmanager.cpp Normal file
View File

@@ -0,0 +1,189 @@
/*
* 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 "eventmanager.h"
#include "bittorrent.h"
#include "json.h"
#include <QDebug>
EventManager::EventManager(QObject *parent, bittorrent *BTSession)
: QObject(parent), BTSession(BTSession)
{
revision = 0;
}
void EventManager::update(QVariantMap event)
{
++revision;
events << QPair<ulong, QVariantMap>(revision, event);
emit updated();
//qDebug("Added the following event");
//qDebug() << event;
/* QLinkedList<QPair<ulong, QVariantMap> >::iterator i;
for (i = events.begin(); i != events.end(); i++)
qDebug() << *i;*/
}
QVariant EventManager::querySince(ulong r) const
{
QVariantList list;
QLinkedListIterator<QPair<ulong, QVariantMap> > i(events);
i.toBack();
while (i.hasPrevious())
{
QPair<ulong, QVariantMap> pair = i.previous();
if (pair.first <= r)
break;
list.prepend(QVariant(pair.second));
}
QVariantMap map;
map["events"] = QVariant(list);
map["revision"] = QVariant((qulonglong) revision);
return QVariant(map);
}
bool EventManager::isUpdated(ulong r) const
{
return (r < revision);
}
void EventManager::addedTorrent(QTorrentHandle& h)
{
QVariantMap event;
event["type"] = QVariant("add");
event["hash"] = QVariant(h.hash());
event["name"] = QVariant(h.name());
update(event);
}
void EventManager::deletedTorrent(QString hash)
{
QVariantMap event;
event["type"] = QVariant("delete");
event["hash"] = QVariant(hash);
QLinkedList<QPair<ulong, QVariantMap> >::iterator i = events.end();
bool loop = true;
while (loop && i != events.begin()) {
--i;
QVariantMap oldevent = i->second;
if(oldevent["hash"] == QVariant(hash))
{
if(oldevent["type"] == QVariant("add"))
loop = false;
i = events.erase(i);
}
}
update(event);
}
void EventManager::modifiedTorrent(QTorrentHandle h)
{
QString hash = h.hash();
QVariantMap event;
QVariant v;
if(h.is_paused()) {
if(BTSession->isDownloadQueued(hash) || BTSession->isUploadQueued(hash))
v = QVariant("queued");
else
v = QVariant("paused");
} else {
switch(h.state())
{
case torrent_status::finished:
case torrent_status::seeding:
v = QVariant("seeding");
break;
case torrent_status::checking_files:
case torrent_status::queued_for_checking:
v = QVariant("checking");
break;
case torrent_status::connecting_to_tracker:
if(h.download_payload_rate() > 0)
v = QVariant("downloading");
else
v = QVariant("connecting");
break;
case torrent_status::downloading:
case torrent_status::downloading_metadata:
if(h.download_payload_rate() > 0)
v = QVariant("downloading");
else
v = QVariant("stalled");
break;
default:
v = QVariant();
}
}
if(modify(hash, "state", v))
event["state"] = v;
v = QVariant((qlonglong)h.actual_size());
if(modify(hash, "size", v))
event["size"] = v;
v = QVariant(h.progress());
if(modify(hash, "progress", v))
event["progress"] = v;
v = QVariant(h.download_payload_rate());
if(modify(hash, "dlspeed", v))
event["dlspeed"] = v;
v = QVariant(h.upload_payload_rate());
if(modify(hash, "upspeed", v))
event["upspeed"] = v;
if(event.size() > 0)
{
event["type"] = QVariant("modify");
event["hash"] = QVariant(hash);
update(event);
}
}
bool EventManager::modify(QString hash, QString key, QVariant value)
{
QLinkedList<QPair<ulong, QVariantMap> >::iterator i = events.end();
while (i != events.begin()) {
--i;
QVariantMap event = i->second;
if(event["hash"] == QVariant(hash))
{
if(event["type"] == QVariant("add"))
return true;
if(event.contains(key))
{
if(event[key] == value)
return false;
else
{
if(event.size() <= 3)
i = events.erase(i);
else
i->second.remove(key);
return true;
}
}
}
}
return true;
}

58
src/eventmanager.h Normal file
View File

@@ -0,0 +1,58 @@
/*
* 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 EVENTMANAGER_H
#define EVENTMANAGER_H
#include "qtorrenthandle.h"
#include <QLinkedList>
#include <QPair>
#include <QVariant>
struct bittorrent;
class EventManager : public QObject
{
Q_OBJECT
private:
ulong revision;
QLinkedList<QPair <ulong, QVariantMap> > events;
bool modify(QString hash, QString key, QVariant value);
bittorrent* BTSession;
protected:
void update(QVariantMap event);
public:
EventManager(QObject *parent, bittorrent* BTSession);
QVariant querySince(ulong r) const;
bool isUpdated(ulong r) const;
signals:
void updated();
public slots:
void addedTorrent(QTorrentHandle& h);
void deletedTorrent(QString hash);
void modifiedTorrent(QTorrentHandle h);
};
#endif

383
src/filterParserThread.h Normal file
View File

@@ -0,0 +1,383 @@
/*
* 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>
#include <arpa/inet.h>
// 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;
do {
int 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

238
src/httpconnection.cpp Normal file
View File

@@ -0,0 +1,238 @@
/*
* 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")
{
EventManager* manager = parent->eventManager();
uint r = parser.get("r").toUInt();
if(manager->isUpdated(r))
respondJson();
else
connect(manager, SIGNAL(updated()), this, SLOT(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 temp = parser.get("r");
uint r = parser.get("r").toUInt();
QVariant data = manager->querySince(r);
QString string = toJson(data);
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"));
return;
}
}

69
src/httpconnection.h Normal file
View File

@@ -0,0 +1,69 @@
/*
* 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);
void resumeTorrent(QString hash);
void pauseTorrent(QString hash);
void resumeAllTorrents();
void pauseAllTorrents();
};
#endif

139
src/httprequestparser.cpp Normal file
View File

@@ -0,0 +1,139 @@
/*
* 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();
qDebug() << 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;
}
qDebug() << "isError: " << isError();
}

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

View File

@@ -0,0 +1,72 @@
/*
* 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 "httpresponsegenerator.h"
void HttpResponseGenerator::setMessage(const QByteArray message)
{
HttpResponseGenerator::message = message;
setContentLength(message.size());
}
void HttpResponseGenerator::setMessage(const QString message)
{
setMessage(message.QString::toUtf8());
}
void HttpResponseGenerator::stripMessage()
{
message.clear();
}
QByteArray HttpResponseGenerator::toByteArray() const
{
return QHttpResponseHeader::toString().toUtf8() + message;
}
void HttpResponseGenerator::setContentTypeByExt(const QString ext)
{
if(ext == "css")
{
setContentType("text/css");
return;
}
if(ext == "gif")
{
setContentType("image/gif");
return;
}
if(ext == "htm" || ext == "html")
{
setContentType("text/html");
return;
}
if(ext == "js")
{
setContentType("text/javascript");
return;
}
if(ext == "png")
{
setContentType("image/x-png");
return;
}
}

View File

@@ -0,0 +1,40 @@
/*
* 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 HTTPRESPONSEGENERATOR_H
#define HTTPRESPONSEGENERATOR_H
#include<QHttpResponseHeader>
class HttpResponseGenerator : public QHttpResponseHeader
{
private:
QByteArray message;
public:
void setMessage(const QByteArray message);
void setMessage(const QString message);
void stripMessage();
void setContentTypeByExt(const QString ext);
virtual QByteArray toByteArray() const;
};
#endif

105
src/httpserver.cpp Normal file
View File

@@ -0,0 +1,105 @@
/*
* 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 "httpserver.h"
#include "httpconnection.h"
#include "eventmanager.h"
#include "bittorrent.h"
#include <QTimer>
HttpServer::HttpServer(bittorrent *BTSession, int msec, QObject* parent) : QTcpServer(parent)
{
base64 = QByteArray(":").toBase64();
connect(this, SIGNAL(newConnection()), this, SLOT(newHttpConnection()));
HttpServer::BTSession = BTSession;
manager = new EventManager(this, BTSession);
//add torrents
QStringList list = BTSession->getUnfinishedTorrents();
foreach(QString hash, list) {
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(h.is_valid()) manager->addedTorrent(h);
}
list = BTSession->getFinishedTorrents();
foreach(QString hash, list) {
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(h.is_valid()) manager->addedTorrent(h);
}
//connect BTSession to manager
connect(BTSession, SIGNAL(addedTorrent(QTorrentHandle&)), manager, SLOT(addedTorrent(QTorrentHandle&)));
connect(BTSession, SIGNAL(deletedTorrent(QString)), manager, SLOT(deletedTorrent(QString)));
//set timer
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(onTimer()));
timer->start(msec);
}
HttpServer::~HttpServer()
{
delete timer;
delete manager;
}
void HttpServer::newHttpConnection()
{
QTcpSocket *socket;
while((socket = nextPendingConnection()))
{
HttpConnection *connection = new HttpConnection(socket, this);
//connect connection to BTSession
connect(connection, SIGNAL(UrlReadyToBeDownloaded(QString)), BTSession, SLOT(downloadUrlAndSkipDialog(QString)));
connect(connection, SIGNAL(torrentReadyToBeDownloaded(QString, bool, QString, bool)), BTSession, SLOT(addTorrent(QString, bool, QString, bool)));
connect(connection, SIGNAL(deleteTorrent(QString)), BTSession, SLOT(deleteTorrent(QString)));
connect(connection, SIGNAL(pauseTorrent(QString)), BTSession, SLOT(pauseTorrent(QString)));
connect(connection, SIGNAL(resumeTorrent(QString)), BTSession, SLOT(resumeTorrent(QString)));
connect(connection, SIGNAL(pauseAllTorrents()), BTSession, SLOT(pauseAllTorrents()));
connect(connection, SIGNAL(resumeAllTorrents()), BTSession, SLOT(resumeAllTorrents()));
}
}
void HttpServer::onTimer()
{
QStringList list = BTSession->getUnfinishedTorrents();
foreach(QString hash, list) {
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(h.is_valid()) manager->modifiedTorrent(h);
}
list = BTSession->getFinishedTorrents();
foreach(QString hash, list) {
QTorrentHandle h = BTSession->getTorrentHandle(hash);
if(h.is_valid()) manager->modifiedTorrent(h);
}
}
void HttpServer::setAuthorization(QString username, QString password)
{
QString cat = username + ":" + password;
base64 = QByteArray(cat.toUtf8()).toBase64();
}
bool HttpServer::isAuthorized(QByteArray auth) const
{
return (auth == base64);
}
EventManager *HttpServer::eventManager() const
{
return manager;
}

54
src/httpserver.h Normal file
View File

@@ -0,0 +1,54 @@
/*
* 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 HTTPSERVER_H
#define HTTPSERVER_H
#include <QTcpServer>
#include <QByteArray>
class bittorrent;
class QTimer;
class EventManager;
class HttpServer : public QTcpServer
{
Q_OBJECT
private:
QByteArray base64;
bittorrent *BTSession;
EventManager *manager;
QTimer *timer;
public:
HttpServer(bittorrent *BTSession, int msec, QObject* parent = 0);
~HttpServer();
void setAuthorization(QString username, QString password);
bool isAuthorized(QByteArray auth) const;
EventManager *eventManager() const;
private slots:
void newHttpConnection();
void onTimer();
};
#endif

View File

@@ -1,104 +1,107 @@
<!DOCTYPE RCC><RCC version="1.0"> <!DOCTYPE RCC><RCC version="1.0">
<qresource> <qresource>
<file>Icons/time.png</file>
<file>Icons/connection.png</file>
<file>Icons/locale.png</file>
<file>Icons/newmsg.png</file>
<file>Icons/url.png</file>
<file>Icons/button_ok.png</file>
<file>Icons/stare.png</file>
<file>Icons/log.png</file>
<file>Icons/qbittorrent32.png</file>
<file>Icons/downarrow.png</file>
<file>Icons/description.png</file>
<file>Icons/qbittorrent16.png</file>
<file>Icons/file.png</file>
<file>Icons/systemtray.png</file>
<file>Icons/unhappy.png</file>
<file>Icons/filter.png</file>
<file>Icons/sphere.png</file>
<file>Icons/mascot.png</file>
<file>Icons/encrypted.png</file>
<file>Icons/refresh.png</file>
<file>Icons/uparrow.png</file>
<file>Icons/style.png</file>
<file>Icons/wizard.png</file>
<file>Icons/password.png</file>
<file>Icons/gear.png</file>
<file>Icons/sphere2.png</file>
<file>Icons/smile.png</file>
<file>Icons/loading.png</file>
<file>Icons/button_cancel.png</file>
<file>Icons/qbittorrent22.png</file>
<file>Icons/proxy.png</file>
<file>Icons/add_folder.png</file>
<file>Icons/unavailable.png</file>
<file>Icons/add_file.png</file> <file>Icons/add_file.png</file>
<file>Icons/home.png</file> <file>Icons/add_folder.png</file>
<file>Icons/splash.png</file>
<file>Icons/rss32.png</file>
<file>Icons/rss16.png</file>
<file>Icons/unsubscribe.png</file>
<file>Icons/subscribe.png</file>
<file>Icons/unsubscribe16.png</file>
<file>Icons/subscribe16.png</file>
<file>Icons/bt_settings.png</file> <file>Icons/bt_settings.png</file>
<file>Icons/star.png</file> <file>Icons/button_cancel.png</file>
<file>Icons/button_ok.png</file>
<file>Icons/configure.png</file> <file>Icons/configure.png</file>
<file>Icons/connection.png</file>
<file>Icons/description.png</file>
<file>Icons/downarrow.png</file>
<file>Icons/download.png</file> <file>Icons/download.png</file>
<file>Icons/folder.png</file>
<file>Icons/edit_clear.png</file> <file>Icons/edit_clear.png</file>
<file>Icons/flags/portugal.png</file> <file>Icons/encrypted.png</file>
<file>Icons/file.png</file>
<file>Icons/filter.png</file>
<file>Icons/folder.png</file>
<file>Icons/gear.png</file>
<file>Icons/gnome-shutdown.png</file>
<file>Icons/home.png</file>
<file>Icons/loading.png</file>
<file>Icons/locale.png</file>
<file>Icons/log.png</file>
<file>Icons/mascot.png</file>
<file>Icons/money.png</file>
<file>Icons/newmsg.png</file>
<file>Icons/password.png</file>
<file>Icons/proxy.png</file>
<file>Icons/qbittorrent16.png</file>
<file>Icons/qbittorrent22.png</file>
<file>Icons/qbittorrent32.png</file>
<file>Icons/refresh.png</file>
<file>Icons/rss16.png</file>
<file>Icons/rss32.png</file>
<file>Icons/sphere.png</file>
<file>Icons/sphere2.png</file>
<file>Icons/splash.png</file>
<file>Icons/star.png</file>
<file>Icons/style.png</file>
<file>Icons/subscribe.png</file>
<file>Icons/subscribe16.png</file>
<file>Icons/systemtray.png</file>
<file>Icons/time.png</file>
<file>Icons/unavailable.png</file>
<file>Icons/unsubscribe.png</file>
<file>Icons/unsubscribe16.png</file>
<file>Icons/uparrow.png</file>
<file>Icons/url.png</file>
<file>Icons/wizard.png</file>
<file>Icons/flags/brazil.png</file>
<file>Icons/flags/bulgaria.png</file>
<file>Icons/flags/china.png</file>
<file>Icons/flags/czech.png</file>
<file>Icons/flags/denmark.png</file>
<file>Icons/flags/finland.png</file>
<file>Icons/flags/france.png</file> <file>Icons/flags/france.png</file>
<file>Icons/flags/germany.png</file>
<file>Icons/flags/greece.png</file>
<file>Icons/flags/hungary.png</file>
<file>Icons/flags/italy.png</file>
<file>Icons/flags/japan.png</file>
<file>Icons/flags/netherlands.png</file>
<file>Icons/flags/norway.png</file>
<file>Icons/flags/poland.png</file>
<file>Icons/flags/portugal.png</file>
<file>Icons/flags/romania.png</file>
<file>Icons/flags/russia.png</file>
<file>Icons/flags/slovakia.png</file>
<file>Icons/flags/south_korea.png</file>
<file>Icons/flags/spain.png</file>
<file>Icons/flags/spain_catalunya.png</file>
<file>Icons/flags/sweden.png</file>
<file>Icons/flags/taiwan.png</file>
<file>Icons/flags/turkey.png</file>
<file>Icons/flags/ukraine.png</file> <file>Icons/flags/ukraine.png</file>
<file>Icons/flags/united_kingdom.png</file> <file>Icons/flags/united_kingdom.png</file>
<file>Icons/flags/germany.png</file>
<file>Icons/flags/russia.png</file>
<file>Icons/flags/netherlands.png</file>
<file>Icons/flags/slovakia.png</file>
<file>Icons/flags/spain.png</file>
<file>Icons/flags/finland.png</file>
<file>Icons/flags/spain_catalunya.png</file>
<file>Icons/flags/poland.png</file>
<file>Icons/flags/hungary.png</file>
<file>Icons/flags/norway.png</file>
<file>Icons/flags/denmark.png</file>
<file>Icons/flags/italy.png</file>
<file>Icons/flags/china.png</file>
<file>Icons/flags/brazil.png</file>
<file>Icons/flags/south_korea.png</file>
<file>Icons/flags/turkey.png</file>
<file>Icons/flags/sweden.png</file>
<file>Icons/flags/bulgaria.png</file>
<file>Icons/flags/romania.png</file>
<file>Icons/flags/japan.png</file>
<file>Icons/flags/greece.png</file>
<file>Icons/skin/properties.png</file>
<file>Icons/skin/play_all.png</file>
<file>Icons/skin/remove.png</file>
<file>Icons/skin/settings.png</file>
<file>Icons/skin/open.png</file>
<file>Icons/skin/disconnected.png</file>
<file>Icons/skin/delete.png</file>
<file>Icons/skin/connected.png</file>
<file>Icons/skin/url.png</file>
<file>Icons/skin/pause_all.png</file>
<file>Icons/skin/downloading.png</file>
<file>Icons/skin/play.png</file>
<file>Icons/skin/search.png</file>
<file>Icons/skin/exit.png</file>
<file>Icons/skin/pause.png</file>
<file>Icons/skin/firewalled.png</file>
<file>Icons/skin/seeding.png</file>
<file>Icons/skin/paused.png</file>
<file>Icons/skin/preview.png</file>
<file>Icons/skin/delete_perm.png</file>
<file>Icons/skin/connecting.png</file>
<file>Icons/skin/add.png</file> <file>Icons/skin/add.png</file>
<file>Icons/skin/stalled.png</file> <file>Icons/skin/connected.png</file>
<file>Icons/skin/new.png</file> <file>Icons/skin/connecting.png</file>
<file>Icons/skin/qb_question.png</file> <file>Icons/skin/decrease.png</file>
<file>Icons/skin/delete.png</file>
<file>Icons/skin/delete_all.png</file> <file>Icons/skin/delete_all.png</file>
<file>Icons/skin/delete_perm.png</file>
<file>Icons/skin/downloading.png</file>
<file>Icons/skin/exit.png</file>
<file>Icons/skin/firewalled.png</file>
<file>Icons/skin/increase.png</file>
<file>Icons/skin/info.png</file> <file>Icons/skin/info.png</file>
<file>Icons/skin/new.png</file>
<file>Icons/skin/open.png</file>
<file>Icons/skin/pause.png</file>
<file>Icons/skin/pause_all.png</file>
<file>Icons/skin/paused.png</file>
<file>Icons/skin/play.png</file>
<file>Icons/skin/play_all.png</file>
<file>Icons/skin/preview.png</file>
<file>Icons/skin/properties.png</file>
<file>Icons/skin/qb_question.png</file>
<file>Icons/skin/queued.png</file>
<file>Icons/skin/remove.png</file>
<file>Icons/skin/search.png</file>
<file>Icons/skin/seeding.png</file>
<file>Icons/skin/settings.png</file>
<file>Icons/skin/stalled.png</file>
<file>Icons/skin/url.png</file>
</qresource> </qresource>
</RCC> </RCC>

103
src/json.cpp Normal file
View File

@@ -0,0 +1,103 @@
/*
* 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 "json.h"
QString toJson(QVariant v)
{
if (v.isNull())
return "null";
QString result;
switch(v.type())
{
case QVariant::Bool:
case QVariant::Double:
case QVariant::Int:
case QVariant::LongLong:
case QVariant::UInt:
case QVariant::ULongLong:
return v.value<QString>();
case QVariant::String:
{
QString s = v.value<QString>();
result = "\"";
for(int i=0; i<s.size(); i++)
{
QChar ch = s[i];
switch(ch.toAscii())
{
case '\b':
result += "\\b";
break;
case '\f':
result += "\\f";
break;
case '\n':
result += "\\n";
break;
case '\r':
result += "\\r";
break;
case '\t':
result += "\\t";
break;
case '\"':
case '\'':
case '\\':
case '&':
result += '\\';
case '\0':
default:
result += ch;
}
}
result += "\"";
return result;
}
case QVariant::List:
{
result = "[";
QListIterator<QVariant> it(v.value<QVariantList>());
while (it.hasNext())
result += toJson(it.next()) + ",";
if(result.size() > 1)
result.chop(1);
result += "]";
return result;
}
case QVariant::Map:
{
result = "{";
QMapIterator<QString, QVariant> it(v.value<QVariantMap>());
while (it.hasNext()) {
it.next();
if(it.value().isValid())
result += toJson(QVariant(it.key())) + ":" + toJson(it.value()) + ",";
}
if(result.size() > 1)
result.chop(1);
result += "}";
return result;
}
default:
return "undefined";
}
}

29
src/json.h Normal file
View File

@@ -0,0 +1,29 @@
/*
* 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 JSON_H
#define JSON_H
#include <QVariant>
QString toJson(QVariant v);
#endif

View File

@@ -1,29 +1,31 @@
<!DOCTYPE RCC><RCC version="1.0"> <!DOCTYPE RCC><RCC version="1.0">
<qresource> <qresource>
<file>lang/qbittorrent_es.qm</file> <file>lang/qbittorrent_bg.qm</file>
<file>lang/qbittorrent_ko.qm</file> <file>lang/qbittorrent_ca.qm</file>
<file>lang/qbittorrent_hu.qm</file> <file>lang/qbittorrent_cs.qm</file>
<file>lang/qbittorrent_sk.qm</file> <file>lang/qbittorrent_da.qm</file>
<file>lang/qbittorrent_uk.qm</file> <file>lang/qbittorrent_de.qm</file>
<file>lang/qbittorrent_ro.qm</file>
<file>lang/qbittorrent_ru.qm</file>
<file>lang/qbittorrent_nb.qm</file>
<file>lang/qbittorrent_el.qm</file> <file>lang/qbittorrent_el.qm</file>
<file>lang/qbittorrent_en.qm</file> <file>lang/qbittorrent_en.qm</file>
<file>lang/qbittorrent_pt_BR.qm</file> <file>lang/qbittorrent_es.qm</file>
<file>lang/qbittorrent_fi.qm</file>
<file>lang/qbittorrent_fr.qm</file> <file>lang/qbittorrent_fr.qm</file>
<file>lang/qbittorrent_hu.qm</file>
<file>lang/qbittorrent_it.qm</file>
<file>lang/qbittorrent_ja.qm</file>
<file>lang/qbittorrent_ko.qm</file>
<file>lang/qbittorrent_nb.qm</file>
<file>lang/qbittorrent_nl.qm</file> <file>lang/qbittorrent_nl.qm</file>
<file>lang/qbittorrent_pl.qm</file> <file>lang/qbittorrent_pl.qm</file>
<file>lang/qbittorrent_it.qm</file>
<file>lang/qbittorrent_zh.qm</file>
<file>lang/qbittorrent_ca.qm</file>
<file>lang/qbittorrent_pt.qm</file> <file>lang/qbittorrent_pt.qm</file>
<file>lang/qbittorrent_da.qm</file> <file>lang/qbittorrent_pt_BR.qm</file>
<file>lang/qbittorrent_tr.qm</file> <file>lang/qbittorrent_ro.qm</file>
<file>lang/qbittorrent_bg.qm</file> <file>lang/qbittorrent_ru.qm</file>
<file>lang/qbittorrent_de.qm</file> <file>lang/qbittorrent_sk.qm</file>
<file>lang/qbittorrent_sv.qm</file> <file>lang/qbittorrent_sv.qm</file>
<file>lang/qbittorrent_ja.qm</file> <file>lang/qbittorrent_tr.qm</file>
<file>lang/qbittorrent_fi.qm</file> <file>lang/qbittorrent_uk.qm</file>
<file>lang/qbittorrent_zh.qm</file>
<file>lang/qbittorrent_zh_TW.qm</file>
</qresource> </qresource>
</RCC> </RCC>

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

BIN
src/lang/qbittorrent_cs.qm Normal file

Binary file not shown.

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