Compare commits
24 Commits
release-3.
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3783b11e98 | ||
|
|
03cf510f7f | ||
|
|
610dfefa26 | ||
|
|
6c477fcf75 | ||
|
|
604f8542a7 | ||
|
|
e9b4c6c047 | ||
|
|
985ac3be68 | ||
|
|
562c748c50 | ||
|
|
7a685f5ab6 | ||
|
|
9500b212c7 | ||
|
|
5a2e92ad79 | ||
|
|
9772fccde3 | ||
|
|
f26bcec56f | ||
|
|
52a62b6f0f | ||
|
|
f27b49f9a3 | ||
|
|
3e4fe1f823 | ||
|
|
a8a6911aa8 | ||
|
|
e299288367 | ||
|
|
de64a641d0 | ||
|
|
ab13a58614 | ||
|
|
c863ff6335 | ||
|
|
e20a09ca3e | ||
|
|
40966ae421 | ||
|
|
a87098629b |
14
.gitignore
vendored
@@ -1,14 +0,0 @@
|
|||||||
src/geoip/GeoIP.dat
|
|
||||||
src/qbittorrent
|
|
||||||
qbittorrent.pro.user
|
|
||||||
conf.pri
|
|
||||||
Makefile
|
|
||||||
*.pyc
|
|
||||||
*.log
|
|
||||||
# Compiled object files
|
|
||||||
*.o
|
|
||||||
# Generated MOC, resource and UI files
|
|
||||||
moc_*.cpp
|
|
||||||
qrc_*.cpp
|
|
||||||
ui_*.h
|
|
||||||
*.moc
|
|
||||||
57
AUTHORS
@@ -2,29 +2,15 @@ Author:
|
|||||||
* Christophe Dumez <chris@qbittorrent.org>
|
* Christophe Dumez <chris@qbittorrent.org>
|
||||||
|
|
||||||
Contributors:
|
Contributors:
|
||||||
* Vladimir Golovnev <glassez@yandex.ru>
|
|
||||||
* Stefanos Antaris <santaris@csd.auth.gr>
|
|
||||||
* Mohammad Dib <mdib@qbittorrent.org>
|
|
||||||
* Mirco Chinelli <infinity89@fastwebmail.it>
|
|
||||||
* Ishan Arora <ishan@qbittorrent.org>
|
|
||||||
* Arnaud Demaizière <arnaud@qbittorrent.org>
|
* Arnaud Demaizière <arnaud@qbittorrent.org>
|
||||||
|
* Ishan Arora <ishan@qbittorrent.org>
|
||||||
* Grigis Gaëtan <cipher16@gmail.com>
|
* Grigis Gaëtan <cipher16@gmail.com>
|
||||||
* Christian Kandeler <zambesi@users.sourceforge.net>
|
|
||||||
* Silvan Scherrer <silvan.scherrer@aroa.ch>
|
|
||||||
|
|
||||||
Code from other projects:
|
Code from other projects:
|
||||||
* files src/qtsingleapp/* src/lineedit/*
|
|
||||||
copyright: Nokia Corporation
|
|
||||||
license: LGPL
|
|
||||||
|
|
||||||
* files src/ico.cpp src/ico.h
|
* files src/ico.cpp src/ico.h
|
||||||
copyright: Malte Starostik <malte@kde.org>
|
copyright: Malte Starostik <malte@kde.org>
|
||||||
license: LGPL
|
license: LGPL
|
||||||
|
|
||||||
* files src/search_engine/socks.py
|
|
||||||
copyright: Dan Haim <negativeiq@users.sourceforge.net>
|
|
||||||
license: BSD
|
|
||||||
|
|
||||||
Images Authors:
|
Images Authors:
|
||||||
* files: src/Icons/*.png
|
* files: src/Icons/*.png
|
||||||
copyright: Gnome Icon Theme
|
copyright: Gnome Icon Theme
|
||||||
@@ -37,9 +23,9 @@ Images Authors:
|
|||||||
url: http://www.oxygen-icons.org
|
url: http://www.oxygen-icons.org
|
||||||
|
|
||||||
* files: src/Icons/flags/*.png
|
* files: src/Icons/flags/*.png
|
||||||
copyright: Mark James <mjames@gmail.com>
|
copyright: Open Clip Art Library
|
||||||
license: Public Domain
|
license: Creative Commons Public Domain Dedication
|
||||||
url: http://www.famfamfam.com
|
url: http://www.openclipart.org
|
||||||
|
|
||||||
* files: src/Icons/skin/*.png
|
* files: src/Icons/skin/*.png
|
||||||
files: src/menuicons/YYxYY/*.png
|
files: src/menuicons/YYxYY/*.png
|
||||||
@@ -50,10 +36,6 @@ Images Authors:
|
|||||||
copyright: Greg Houston <gregory.houston@gmail.com>
|
copyright: Greg Houston <gregory.houston@gmail.com>
|
||||||
license: MIT
|
license: MIT
|
||||||
|
|
||||||
* file: src/Icons/skin/qbittorrent_mono*
|
|
||||||
copyright: Daniel Eguren <deguren@gmail.com>
|
|
||||||
license: LGPL
|
|
||||||
|
|
||||||
* file: src/search_engine/engines/btjunkie.png
|
* file: src/search_engine/engines/btjunkie.png
|
||||||
copyright: Downloaded from btjunkie.org
|
copyright: Downloaded from btjunkie.org
|
||||||
|
|
||||||
@@ -72,40 +54,31 @@ Images Authors:
|
|||||||
Translations authors:
|
Translations authors:
|
||||||
* files: src/lang/*.ts
|
* files: src/lang/*.ts
|
||||||
copyright:
|
copyright:
|
||||||
- Arabic: SDERAWI (abz8868@msn.com) and sn51234 (nesseyan@gmail.com)
|
|
||||||
- Armenian: Hrant Ohanyan (hrantohanyan@mail.am)
|
|
||||||
- Basque: Xabier Aramendi (azpidatziak@gmail.com)
|
|
||||||
- Belarusian: Mihas Varantsou (meequz@gmail.com)
|
|
||||||
- Brazilian: Nick Marinho (nickmarinho@gmail.com)
|
- Brazilian: Nick Marinho (nickmarinho@gmail.com)
|
||||||
- Bulgarian: Tsvetan & Boyko Bankoff (emerge_life@users.sourceforge.net)
|
- Bulgarian: Tsvetan & Boiko Bankov (emerge_life@users.sourceforge.net)
|
||||||
- Catalan: Francisco Luque Contreras (frannoe@ya.com)
|
- Catalan: Gekko Dam Beer (gekko04@users.sourceforge.net)
|
||||||
- Chinese (Simplified): Guo Yue (yue.guo0418@gmail.com)
|
- Chinese (Simplified): Guo Yue (yue.guo0418@gmail.com)
|
||||||
- Chinese (Traditional): Yi-Shun Wang (dnextstep@gmail.com)
|
- Chinese (Traditional): Yi-Shun Wang (dnextstep@gmail.com)
|
||||||
- Croatian: Oliver Mucafir (oliver.untwist@gmail.com)
|
|
||||||
- Czech: Jirka Vilim (web@tets.cz)
|
- Czech: Jirka Vilim (web@tets.cz)
|
||||||
- Danish: Mathias Nielsen (comoneo@gmail.com)
|
- Danish: Mathias Nielsen (comoneo@gmail.com)
|
||||||
- Dutch: Pieter Heyvaert (pieter_heyvaert@hotmail.com)
|
- Dutch: Joost Schipper (heavyjoost@users.sourceforge.net)
|
||||||
- English: Christophe Dumez (chris@qbittorrent.org)
|
- English: Christophe Dumez (chris@qbittorrent.org)
|
||||||
- Finnish: Niklas Laxström (nikerabbit@users.sourceforge.net)
|
- Finnish: Niklas Laxström (nikerabbit@users.sourceforge.net)
|
||||||
- French: Christophe Dumez (chris@qbittorrent.org)
|
- French: Christophe Dumez (chris@qbittorrent.org)
|
||||||
- Galician: Marcos Lans (marcoslansgarza@gmail.com)
|
|
||||||
- Georgian: Beqa Arabuli (arabulibeqa@yahoo.com)
|
|
||||||
- German: Niels Hoffmann (zentralmaschine@users.sourceforge.net)
|
- German: Niels Hoffmann (zentralmaschine@users.sourceforge.net)
|
||||||
- Greek: Tsvetan Bankov (emerge_life@users.sourceforge.net) and Stephanos Antaris (santaris@csd.auth.gr)
|
- Greek: Tsvetan Bankov (emerge_life@users.sourceforge.net)
|
||||||
- Hungarian: Majoros Péter (majoros.j.p@t-online.hu)
|
- Hungarian: Majoros Péter (majoros.j.p@t-online.hu)
|
||||||
- Italian: Matteo Sechi (bu17714@gmail.com)
|
- Italian: Mirko Ferrari (mirkoferrari@gmail.com) and Ferraro Luciano (luciano.ferraro@gmail.com)
|
||||||
- Japanese: Masato Hashimoto (cabezon.hashimoto@gmail.com)
|
- Japanese: Nardog (nardog@e2umail.com)
|
||||||
- Korean: Jin Woo Sin (jin828sin@users.sourceforge.net)
|
- Korean: Jin Woo Sin (jin828sin@users.sourceforge.net)
|
||||||
- Lithuanian: Naglis Jonaitis (njonaitis@gmail.com)
|
- Norwegian: Lars-Erik Labori (hamil@users.sourceforge.net)
|
||||||
- Norwegian: Tomaso
|
- Polish: Jarek Smieja (ajep9691@wp.pl)
|
||||||
- Polish: Mariusz Fik (fisiu@opensuse.org)
|
|
||||||
- Portuguese: Nick Marinho (nickmarinho@gmail.com)
|
- Portuguese: Nick Marinho (nickmarinho@gmail.com)
|
||||||
- Romanian: Obada Denis (obadadenis@users.sourceforge.net)
|
- Romanian: Obada Denis (obadadenis@users.sourceforge.net)
|
||||||
- Russian: Nick Khazov (m2k3d0n at users.sourceforge.net)
|
- Russian: Nick Khazov (m2k3d0n at users.sourceforge.net)
|
||||||
- Serbian: Anaximandar Milet (anaximandar at operamail.com)
|
|
||||||
- Slovak: helix84
|
- Slovak: helix84
|
||||||
- Spanish: Francisco Luque Contreras (frannoe@ya.com)
|
- Spanish: Vicente Raul Plata Fonseca (silverxnt@users.sourceforge.net)
|
||||||
- Swedish: Daniel Nylander (po@danielnylander.se)
|
- Swedish: Daniel Nylander (po@danielnylander.se)
|
||||||
- Turkish: Hasan Yilmaz (iletisim@hedefturkce.com)
|
- Turkish: Erdem Bingöl (erdem84@gmail.com)
|
||||||
- Ukrainian: Oleh Prypin (blaxpirit@gmail.com)
|
- Ukrainian: Andrey Shpachenko (masterfix@users.sourceforge.net)
|
||||||
license: GPLv2
|
license: GPLv2
|
||||||
|
|||||||
356
Changelog
@@ -1,359 +1,3 @@
|
|||||||
* Sat Sep 1 2012 - Christophe Dumez <chris@qbittorrent.org> - v3.0.2
|
|
||||||
- FEATURE: Add "clear" functionality to search field (closes #59)
|
|
||||||
- BUGFIX: Attempt to use qBittorrent icon from theme if available (closes #49)
|
|
||||||
- BUGFIX: Fix crash when a fastresume file is empty (closes #52)
|
|
||||||
- BUGFIX: Fix encoding problem for detected XDG Download folder (closes #53)
|
|
||||||
- BUGFIX: Improve performance when showing torrent content panel (Improves #24)
|
|
||||||
- BUGFIX: Fix label-based filtering of torrents whose label contains special characters
|
|
||||||
- BUGFIX: Fix possible crash due to labels (closes #64)
|
|
||||||
|
|
||||||
* Tue Aug 21 2012 - Christophe Dumez <chris@qbittorrent.org> - v3.0.1
|
|
||||||
- BUGFIX: Fix possible crash when adding a tracker to a magnet torrent without metadata (Closes #1034254)
|
|
||||||
- BUGFIX: Remember queue position for torrents without metadata (closes #17)
|
|
||||||
- BUGFIX: Fix crash when using unauthorized characters in label names (closes #19)
|
|
||||||
- BUGFIX: Fix search plugins updating (closes #25)
|
|
||||||
- BUGFIX: Make uTP connections rate limited by default
|
|
||||||
|
|
||||||
* Thu Aug 09 2012 - Christophe Dumez <chris@qbittorrent.org> - v3.0.0
|
|
||||||
- FEATURE: Brand new torrent addition dialog
|
|
||||||
- FEATURE: Add the ability to choose the save path when using magnet links (mutoso)
|
|
||||||
- FEATURE: Add support for adding multiple local torrents at once (Web UI)
|
|
||||||
- COSMETIC: Improve style of left panel
|
|
||||||
- BUGFIX: Lower panels no longer gets disabled
|
|
||||||
- BUGFIX: Major code refactoring and various optimizations.
|
|
||||||
- BUGFIX: No longer strip root folder from torrent files
|
|
||||||
- OTHER: Drop support for libtorrent v0.14.x
|
|
||||||
- OTHER: Drop support for Qt 4.5
|
|
||||||
|
|
||||||
* Sat Oct 08 2011 - Christophe Dumez <chris@qbittorrent.org> - v2.9.0
|
|
||||||
- FEATURE: Add file association settings to program preferences (Windows)
|
|
||||||
- FEATURE: Add setting to ignore slow torrents in queueing system
|
|
||||||
- FEATURE: Add advanced setting to announce to all trackers
|
|
||||||
- FEATURE: Add support for anonymous mode (libtorrent >= v0.16)
|
|
||||||
- FEATURE: Add quick "set as default save path" checkbox to torrent addition dialog (sledgehammer999)
|
|
||||||
- BUGFIX: Add tray menu entry for toggling window visibility
|
|
||||||
- BUGFIX: Fix execution log lines selection and copying
|
|
||||||
- BUGFIX: Reduce CPU usage when running Web UI
|
|
||||||
- BUGFIX: Save RSS items to disk regularly for safety
|
|
||||||
- BUGFIX: Fix ratio calculation (use all_time_download)
|
|
||||||
- BUGFIX: Fix torrent upload issues (Web UI)
|
|
||||||
- BUGFIX: Fix some IE incompatibilities (Web UI)
|
|
||||||
- COSMETIC: Display speed at the beginning of the Window title
|
|
||||||
- COSMETIC: Several cosmetic fixes to the Web UI
|
|
||||||
- COSMETIC: Make top toolbar follow system style
|
|
||||||
- OTHER: Display libraries versions in about dialog (sledgehammer999)
|
|
||||||
- OTHER: Display qBittorrent version in Web UI about dialog
|
|
||||||
|
|
||||||
* Thu Jun 02 2011 - Christophe Dumez <chris@qbittorrent.org> - v2.8.0
|
|
||||||
- FEATURE: Added full libtorrent v0.16 support (uTP, ...)
|
|
||||||
- FEATURE: Proxy can be disabled for peer connections
|
|
||||||
- FEATURE: Added support for secure SMTP connection (SSL)
|
|
||||||
- FEATURE: Added support for SMTP authentication
|
|
||||||
- FEATURE: Added UPnP/NAT-PMP port forward for the Web UI port
|
|
||||||
- FEATURE: qBittorrent can update dynamic DNS services (DynDNS, no-ip)
|
|
||||||
- FEATURE: Display peer connection type in peer list (BT, uTP, Web)
|
|
||||||
- FEATURE: Added full regex support to RSS downloader
|
|
||||||
- FEATURE: Added regex help and validation in RSS downloader
|
|
||||||
- FEATURE: Added HTTPS support to Web UI (Ishan Arora)
|
|
||||||
- BUGFIX: Change systray icon on the fly (no restart needed)
|
|
||||||
- BUGFIX: Remember peer-level rate limits (requires libtorrent v0.16)
|
|
||||||
- BUGFIX: Stop annoncing to trackers an all tiers (more respectful)
|
|
||||||
- BUGFIX: Stop sharing private trackers with other peers
|
|
||||||
- BUGFIX: Tracker exchange extension can be disabled
|
|
||||||
- BUGFIX: Cleaner program exit on system log out
|
|
||||||
- BUGFIX: Fix possible magnet link parsing problems
|
|
||||||
- BUGFIX: Fix possible RSS URL parsing problems
|
|
||||||
- COSMETIC: Added monochrome icon for light themes
|
|
||||||
|
|
||||||
* Sun Mar 20 2011 - Christophe Dumez <chris@qbittorrent.org> - v2.7.0
|
|
||||||
- FEATURE: Added search field for torrent content
|
|
||||||
- FEATURE: Added auto-shutdown confirmation dialog
|
|
||||||
- FEATURE: Added option to skip torrent deletion confirmation (Ville Kiiskinen)
|
|
||||||
- FEATURE: IP address reported to trackers is now customizable
|
|
||||||
- FEATURE: Inhibit system sleep when torrents are active (Vladimir Golovnev)
|
|
||||||
- FEATURE: Added option to bypass Web UI authentication for localhost
|
|
||||||
- FEATURE: Added option to disable program exit confirmation
|
|
||||||
- FEATURE: Added per-torrent ratio limiting (Christian Kandeler)
|
|
||||||
- FEATURE: Torrent content list is now sortable
|
|
||||||
- BUGFIX: Fix compilation with namespaced Qt (Christian Kandeler)
|
|
||||||
- BUGFIX: Added length restriction on UI lock password
|
|
||||||
- COSMETIC: Added monochrome tray icon
|
|
||||||
- COSMETIC: Improved status bar's style
|
|
||||||
- OTHER: Make QtDBus dependency optional (X11)
|
|
||||||
|
|
||||||
* Sun Jan 9 2011 - Christophe Dumez <chris@qbittorrent.org> - v2.6.0
|
|
||||||
- FEATURE: Use system icons (Linux, Qt >= 4.6)
|
|
||||||
- FEATURE: Improved ETA calculation
|
|
||||||
- FEATURE: Simplify program preferences
|
|
||||||
- FEATURE: Software update check can now be disabled (Mac OS X / Windows)
|
|
||||||
- FEATURE: Display pieces size in torrent properties
|
|
||||||
- FEATURE: Added "Time Active/Seeded" column to transfer list
|
|
||||||
- FEATURE: Give feedback regarding the IP filter parsing
|
|
||||||
- FEATURE: Added a button to reload the IP filter
|
|
||||||
- FEATURE: Search engine results can now be opened in a Web browser
|
|
||||||
- FEATURE: Added a search engine plugin to extratorrent.com
|
|
||||||
- FEATURE: Added a search engine plugin for kickasstorrents.com
|
|
||||||
- FEATURE: Added auto-suspend upon downloads completion feature
|
|
||||||
- BUGFIX: Hide unwanted files that have to be partly downloaded
|
|
||||||
- BUGFIX: Do not allocate space for unwanted files (preallocation mode)
|
|
||||||
- I18N: Added Galician translation
|
|
||||||
- COSMETIC: Same deletion confirmation dialog in the GUI and Web UI
|
|
||||||
- COSMETIC: Simplified the top toolbar
|
|
||||||
- COSMETIC: Display execution log as a tab instead of a modal window
|
|
||||||
|
|
||||||
* Sun Dec 5 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.5.0
|
|
||||||
- FEATURE: qBittorrent can now act as a tracker
|
|
||||||
- FEATURE: New and improved RSS feed automated downloader
|
|
||||||
- FEATURE: Added feature to shutdown qbittorrent on torrents completion
|
|
||||||
- FEATURE: Added a torrent import assistant to seed or keep downloading outside torrents
|
|
||||||
- FEATURE: qBittorrent can update itself from Sourceforge (Windows/Mac OS X only)
|
|
||||||
- FEATURE: Added a transfer list column to display the current tracker
|
|
||||||
- FEATURE: Remember the last trackers used in the torrent creation tool
|
|
||||||
- FEATURE: The optimal piece size is now automatically computed in the torrent creation tool
|
|
||||||
- FEATURE: Bring up the connection settings when clicking on the connection status icon
|
|
||||||
- FEATURE: Major code refactoring and optimization
|
|
||||||
- FEATURE: Added "Amount downloaded/left" columns to transfer list
|
|
||||||
- FEATURE: Simplified proxy settings
|
|
||||||
- FEATURE: Optimized and improved the peer country resolution code
|
|
||||||
- FEATURE: Download first/last pieces first when sequential download is
|
|
||||||
enabled (Thanks Ahmad)
|
|
||||||
- FEATURE: Download first/last pieces first now applies to all media files
|
|
||||||
in the torrent (Thanks Ahmad)
|
|
||||||
- BUGFIX: Fix SOCKS5 proxy authentication in search engine(closes #680072)
|
|
||||||
- BUGFIX: Fix two advanced settings (ignore limits on LAN and protocol
|
|
||||||
overhead inclusion in rate limiter)
|
|
||||||
- BUGFIX: Fix strict super seeding (was not working)
|
|
||||||
- BUGFIX: Improve magnet save path handling (closes #683395)
|
|
||||||
- BUGFIX: Disable overwrite confirmation in torrent addition dialog (closes # 685269)
|
|
||||||
- COSMETIC: Replaced message box by on-screen notification for download errors
|
|
||||||
- COSMETIC: Improved the torrent creation tool appearance
|
|
||||||
- COSMETIC: Use country flags by Mark James (Thanks to Dmytro Pukha)
|
|
||||||
- COSMETIC: Use bigger alternative speed icon
|
|
||||||
- OTHERS: Dropped support for Qt <= 4.4
|
|
||||||
|
|
||||||
* Tue Aug 24 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.0
|
|
||||||
- FEATURE: Added actions to "Move to top/bottom" of priority queue
|
|
||||||
- FEATURE: Auto-Shutdown on downloads completion
|
|
||||||
- FEATURE: Email notification on download completion
|
|
||||||
- FEATURE: Added button to password-lock the UI
|
|
||||||
- FEATURE: Added label-level Pause/Resume/Delete actions
|
|
||||||
- FEATURE: Torrents can now be filtered by name
|
|
||||||
- FEATURE: Run external program on torrent completion
|
|
||||||
- FEATURE: Detect executable updates in order to advise the user to restart
|
|
||||||
|
|
||||||
* Tue Jul 27 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.3.0
|
|
||||||
- FEATURE: Simplified torrent root folder renaming/truncating (< v2.3.0 is no longer forward compatible)
|
|
||||||
- FEATURE: Remember previous save paths in torrent addition dialog
|
|
||||||
- FEATURE: Max number of half-open connections can now be edited
|
|
||||||
- FEATURE: Added support for strict super seeding
|
|
||||||
- FEATURE: The user can force listening on a particular network interface
|
|
||||||
- FEATURE: Added cookie support for RSS feeds
|
|
||||||
- FEATURE: User can force tracker reannounce
|
|
||||||
- FEATURE: Added "No action" setting for double-click action
|
|
||||||
- FEATURE: Several torrents can be moved at once
|
|
||||||
- FEATURE: Added error state for torrents (error is displayed in a tooltip)
|
|
||||||
- FEATURE: Added filter for paused/error torrents
|
|
||||||
- FEATURE: Add Check/Uncheck all feature in Web UI
|
|
||||||
- FEATURE: Search engine can now be disabled
|
|
||||||
- FEATURE: Torrents can be automatically paused once they reach a given ratio
|
|
||||||
- FEATURE: Several files can now be disabled at once
|
|
||||||
- FEATURE: Added "Select All/None" buttons to files list
|
|
||||||
- FEATURE: Added support for BitComet links (bc://bt/...)
|
|
||||||
- BUGFIX: Hide seeding torrents files priorities in Web UI
|
|
||||||
- BUGFIX: The user can disable permanently recursive torrent download
|
|
||||||
- BUGFIX: Peer Exchange status is now correctly reported
|
|
||||||
- BUGFIX: Use an INI file instead of the registry on Windows (More reliable)
|
|
||||||
- BUGFIX: Removed client spoofing feature to avoid tracker blacklisting
|
|
||||||
- COSMETIC: Display peers country name in tooltip
|
|
||||||
- COSMETIC: Display number of torrents in transfers tab label
|
|
||||||
- COSMETIC: Simplified program preferences
|
|
||||||
- COSMETIC: Fix naming of actions opening new dialogs (use Name...)
|
|
||||||
|
|
||||||
* Sun Mar 14 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.2.0
|
|
||||||
- FEATURE: User can set alternative speed limits for fast toggling
|
|
||||||
- FEATURE: Bandwidth scheduler (automatically use alternative speed limits for a given period)
|
|
||||||
- FEATURE: Added "Added/Completed On" columns to transfer list
|
|
||||||
- FEATURE: Added "Upload/Download limit" columns to transfer list
|
|
||||||
- FEATURE: Torrent files can be exported to a given directory
|
|
||||||
- FEATURE: Outgoing ports range can be customized (for QoS)
|
|
||||||
- FEATURE: User can choose to apply transfer limits on LAN too
|
|
||||||
- FEATURE: User can choose to include the protocol overhead in transfer limits
|
|
||||||
- FEATURE: Torrents can be automatically rechecked on completion
|
|
||||||
- FEATURE: If 2 torrents have the same hash, add new trackers/URL seeds to the existing torrent
|
|
||||||
- FEATURE: Trackers can be added from Web UI
|
|
||||||
- FEATURE: Global transfer information are displayed in the new Web UI status bar
|
|
||||||
- FEATURE: Allow to change the priority of several files at once
|
|
||||||
- FEATURE: Support for multiple scan folders (Patch by Christian Kandeler)
|
|
||||||
- BUGFIX: Only one log window can be opened at a time
|
|
||||||
- BUGFIX: Optimized RSS module memory usage
|
|
||||||
- BUGFIX: Consider HTTP downloads >1MB as invalid .torrent files and abort
|
|
||||||
- BUGFIX: Fix Web UI authentication with some browsers
|
|
||||||
- BUGFIX: Set Web UI ban period to 1 hour
|
|
||||||
- COSMETIC: Improved style management
|
|
||||||
|
|
||||||
* Mon Jan 18 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.1.0
|
|
||||||
- FEATURE: Graphical User Interface can be disabled at compilation time (headless running)
|
|
||||||
- FEATURE: Torrents can be labeled/categorized
|
|
||||||
- FEATURE: Labeled torrent can be downloaded corresponding subfolders
|
|
||||||
- FEATURE: Disk cache size can be set from preferences
|
|
||||||
- FEATURE: Peer Exchange (PeX) can be disabled from preferences
|
|
||||||
- FEATURE: Append !.qB extension to incomplete files option (libtorrent >= v0.15 only)
|
|
||||||
- FEATURE: Torrent files/folders can be renamed (torrent addition dialog or files properties)
|
|
||||||
- FEATURE: uTorrent compatible tracker list support (use torrentz.com url as a default)
|
|
||||||
- FEATURE: Better proxy support and preferences remodeling
|
|
||||||
- FEATURE: qBittorrent can identify itself as uTorrent, Vuze or KTorrent (Any stable version)
|
|
||||||
- FEATURE: Torrents can be renamed in transfer list
|
|
||||||
- FEATURE: Display torrent addition dialog for magnet links too
|
|
||||||
- FEATURE: Files contained in a torrent are opened on double click (files panel)
|
|
||||||
- FEATURE: Added support for magnet links in search engine
|
|
||||||
- FEATURE: Added vertor.com and torrentdownloads.net search plugins
|
|
||||||
- FEATURE: Search engine can now use a SOCKS5 proxy
|
|
||||||
- FEATURE: HTTP proxy support for peer communication
|
|
||||||
- BUGFIX: Search engine loads new proxy settings without program restart
|
|
||||||
- BUGFIX: Use XDG folders (.cache, .local) instead of .qbittorrent
|
|
||||||
- BUGFIX: Added legal notice on startup that the user must accept
|
|
||||||
- BUGFIX: Protect Web UI authentication against brute forcing
|
|
||||||
- BUGFIX: Use HTTP digest mode for Web UI authentication (instead of Basic)
|
|
||||||
- BUGFIX: Properly display torrents with one file in subfolder(s)
|
|
||||||
- BUGFIX: Display Web UI favicon
|
|
||||||
- BUGFIX: File priority can be set for finished torrents that have filtered files
|
|
||||||
- COSMETIC: Use checkboxes to filter torrent content instead of comboboxes
|
|
||||||
- COSMETIC: Use alternating row colors in transfer list (set in program preferences)
|
|
||||||
- COSMETIC: Added a spin box to speed limiting dialog for manual input
|
|
||||||
|
|
||||||
* Mon Jan 11 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.0.7
|
|
||||||
- BUGFIX: Fix 'Add in pause' setting in torrent addition dialog
|
|
||||||
- BUGFIX: Update RSS feed as soon as feed downloader is enabled
|
|
||||||
- BUGFIX: RSS Feed downloader ignores articles above maximum number of articles
|
|
||||||
- BUGFIX: Fix possible bug when deleting a RSS folder
|
|
||||||
- BUGFIX: Remove persistant data when a RSS feed is deleted
|
|
||||||
- BUGFIX: RSS filters are now alphabetically sorted
|
|
||||||
- BUGFIX: Fix crash when renaming currently displayed RSS filter
|
|
||||||
- BUGFIX: Remove overwriting confirmation when exporting RSS filters since Qt takes care of it
|
|
||||||
|
|
||||||
* Tue Jan 5 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.0.6
|
|
||||||
- BUGFIX: Fix detection of invalid torrent files
|
|
||||||
- BUGFIX: Stop catching signals once one has been caught to avoid possible infinite loop
|
|
||||||
- BUGFIX: Force data recheck whenever a torrent is moved
|
|
||||||
- BUGFIX: Detect existing torrent data even if incomplete torrents are saved to a different folder
|
|
||||||
- COSMETIC: Improve torrent deletion confirmation dialog so that the text that not get truncated
|
|
||||||
|
|
||||||
* Thu Dec 31 2009 - Christophe Dumez <chris@qbittorrent.org> - v2.0.5
|
|
||||||
- BUGFIX: Fix crash with downloaded/availability bars when the torrent has too many pieces
|
|
||||||
|
|
||||||
* Wed Dec 30 2009 - Christophe Dumez <chris@qbittorrent.org> - v2.0.4
|
|
||||||
- BUGFIX: Fix PeerGuardian .p2b binary filter support
|
|
||||||
- BUGFIX: Fix possible crash when closing a search engine tab
|
|
||||||
- BUGFIX: Make sure service port does not change
|
|
||||||
- BUGFIX: Fix possible DHT port saving issue
|
|
||||||
- BUGFIX: Fix communication between qBittorrent and Web UI (Qt 4.6)
|
|
||||||
- BUGFIX: Use Wildcard matching instead of full regex in RSS feed downloader
|
|
||||||
- BUGFIX: Fix code for listening on a random port whenever it failed to listen on the one defined
|
|
||||||
- BUGFIX: Use global maximum transfer rates as maximum values in per-torrent speed limiting dialogs
|
|
||||||
- BUGFIX: Fix global download rate limiting from Web UI
|
|
||||||
- COSMETIC: Display a disconnected icon in status bar whenever qBittorrent failed to listen on the port defined
|
|
||||||
|
|
||||||
* Wed Dec 23 2009 - Christophe Dumez <chris@qbittorrent.org> - v2.0.3
|
|
||||||
- BUGFIX: Minor cosmetic fix to program preferences
|
|
||||||
- BUGFIX: Fix "Temp path" button in program preferences
|
|
||||||
- BUGFIX: Handle paths with [~, ., ..] properly
|
|
||||||
- BUGFIX: Trackers are now displayed for torrents without metadata
|
|
||||||
- BUGFIX: Fix issue with speed limiting (unlimited was not handled properly)
|
|
||||||
- BUGFIX: Use the save path set in program preferences as a default in torrent addition dialog
|
|
||||||
|
|
||||||
* Fri Dec 18 2009 - Christophe Dumez <chris@qbittorrent.org> - v2.0.2
|
|
||||||
- BUGFIX: Fix .qbittorrent folder not being created (critical bug introduced in v2.0.1 that makes qBittorrent unusuable for new users)
|
|
||||||
- BUGFIX: Fix RSS Feed downloader for some feeds
|
|
||||||
- BUGFIX: Do not use home folder as a fallback when the save path is not accessible
|
|
||||||
- BUGFIX: Fix Mininova, ThePirateBay search engine plugins
|
|
||||||
- BUGFIX: Read RSS articles are remembered on restart for feeds with no torrents attached
|
|
||||||
|
|
||||||
* Sun Dec 13 2009 - Christophe Dumez <chris@qbittorrent.org> - v2.0.1
|
|
||||||
- BUGFIX: µTorrent user-agent is now spoofed correctly
|
|
||||||
- BUGFIX: Fix column hiding behavior when queueing system is disabled
|
|
||||||
- BUGFIX: Fix link to plugins.qbittorrent.org in plugins dialog
|
|
||||||
- BUGFIX: ~/qBT_dir is created only when it is actually used
|
|
||||||
- BUGFIX: Fix possible missing slot message (toggleSelectedTorrentsSuperSeeding)
|
|
||||||
- BUGFIX: Fix possible crash in torrent properties (files)
|
|
||||||
- BUGFIX: Added Hex Magnet Links support (Thanks Haypo)
|
|
||||||
|
|
||||||
* Thu Dec 10 2009 - Christophe Dumez <chris@qbittorrent.org> - v2.0.0
|
|
||||||
- FEATURE: Added program option to disable splash screen
|
|
||||||
- FEATURE: Dropped dependency on libcurl and libzzip
|
|
||||||
- FEATURE: Display more information regarding the torrent in its properties
|
|
||||||
- FEATURE: Various optimizations to save CPU and memory
|
|
||||||
- FEATURE: Folder scanning now works with CIFS and NFS mounted folders
|
|
||||||
- FEATURE: Speed up qBittorrent startup and shutdown
|
|
||||||
- FEATURE: Display per-torrent peer list
|
|
||||||
- FEATURE: Make sure torrent files are always sorted by name
|
|
||||||
- FEATURE: Seeds and Peers columns are now sortable
|
|
||||||
- FEATURE: Torrents can be rechecked from Web UI (Stephanos Antaris)
|
|
||||||
- FEATURE: New peers can manually be added to the torrents
|
|
||||||
- FEATURE: Support per-peer rate limiting
|
|
||||||
- FEATURE: Support peer manual ban
|
|
||||||
- FEATURE: Display total amounts transferred in status bar
|
|
||||||
- FEATURE: Display trackers status as well as error/warning messages
|
|
||||||
- FEATURE: Display the number of peers returned by each tracker & DHT/PeX/LSD
|
|
||||||
- FEATURE: Global upload/download speeds can be capped from status bar (µTorrent behavior)
|
|
||||||
- FEATURE: Added option to download first and last piece of a torrent main file first (for preview)
|
|
||||||
- FEATURE: Graphically display piece availability in torrent properties
|
|
||||||
- FEATURE: Dropped Qt 4.3 support (Qt >= 4.4 is now required)
|
|
||||||
- FEATURE: Display close tab button into the tabs in search engine (Qt >= 4.5 only)
|
|
||||||
- FEATURE: Show official documentation when pressing F1 key
|
|
||||||
- FEATURE: Search engine plugins now handle HTTP protocol gzip compression
|
|
||||||
- FEATURE: Enabled lazy bitfield as a counter-measure for ISP speed throttling
|
|
||||||
- FEATURE: Fall back to a random port if qBittorrent could not listen on the chosen port
|
|
||||||
- FEATURE: Announce to all trackers specified for a torrent (µTorrent behavior) (libtorrent >= v0.15 only)
|
|
||||||
- FEATURE: Added per-torrent super seeding mode (libtorrent >= v0.15 only)
|
|
||||||
- FEATURE: Support for storing symbolic links in .torrent files (libtorrent >= v0.15 only)
|
|
||||||
- FEATURE: Support for uTorrent interpretation of multi-tracker torrents (libtorrent >= v0.15 only)
|
|
||||||
- FEATURE: Handle torrents with duplicate filenames (libtorrent >= v0.15 only)
|
|
||||||
- FEATURE: Support for merkle hash tree torrents (.merkle.torrent) (libtorrent >= v0.15 only)
|
|
||||||
- FEATURE: Metadata download from swarm is now compatible with µtorrent (libtorrent >= v0.15 only)
|
|
||||||
- FEATURE: Support tracker exchange between peers (libtorrent >= v0.15 only)
|
|
||||||
- FEATURE: Better http seed support (libtorrent >= v0.15 only)
|
|
||||||
- FEATURE: Tracker connections are now also subject to IP filtering (libtorrent >= v0.15 only)
|
|
||||||
- FEATURE: Include DHT traffic in the rate limiter (libtorrent >= v0.15 only)
|
|
||||||
- FEATURE: Support for bitcomet padding files (libtorrent >= v0.15 only)
|
|
||||||
- FEATURE: Option to skip file checking and start seeding immediately in torrent addition dialog (Stephanos Antaris) (libtorrent >= v0.15 only)
|
|
||||||
- BUGFIX: Made sure qBittorrent does not scrape the tracker too frequently (libtorrent >= 0.15 only)
|
|
||||||
- BUGFIX: Fix Paste action in search engine field
|
|
||||||
- BUGFIX: Fix possible double free in search engine destructor
|
|
||||||
- BUGFIX: Properly handle trackers error messages
|
|
||||||
- WEB UI: Remodeled Web UI to match new qBittorrent UI (Properties and preferences available)
|
|
||||||
- WEB UI: Added internationalization support
|
|
||||||
- WEB UI: Reduced computation in Javascript (do this one server side instead)
|
|
||||||
- WEB UI: Fixed Transfer list flickering
|
|
||||||
- WEB UI: Password is now stored as md5
|
|
||||||
- I18N: Added Serbian translation (By Anaximandar Milet)
|
|
||||||
- COSMETIC: Merged download / upload lists
|
|
||||||
- COSMETIC: Torrents can be filtered based on their status
|
|
||||||
- COSMETIC: Torrent properties are now displayed in main window
|
|
||||||
- COSMETIC: Made program preferences scrollable for usability on small screens (e.g. netbooks)
|
|
||||||
- COSMETIC: Added a "torrent status" column to transfer list
|
|
||||||
- COSMETIC: Display Seeds and Peers in two separate columns
|
|
||||||
- COSMETIC: New deletion confirmation dialog (Merged delete/delete permanently actions)
|
|
||||||
- COSMETIC: Improved status bar layout spacing
|
|
||||||
- COSMETIC: Display speeds with more user friendly units instead of always using KiB/s
|
|
||||||
- COSMETIC: New torrent status icons by Mateusz Tolola
|
|
||||||
- COSMETIC: Make use of libnotify if available for system notifications (Ubuntu, ...)
|
|
||||||
|
|
||||||
* Tue Nov 17 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.5.6
|
|
||||||
- BUGFIX: RSS feed articles can now be displayed using keyboard arrows
|
|
||||||
- BUGFIX: RSS feed downloader can only process unread articles now
|
|
||||||
- BUGFIX: Fixed memory leak in RSS parser
|
|
||||||
- BUGFIX: Fixed possible crash in search autocompletion
|
|
||||||
- BUGFIX: Improved ETA calculation for big torrents
|
|
||||||
- BUGFIX: Fixed per-torrent speed limiting
|
|
||||||
|
|
||||||
* Wed Nov 4 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.5.5
|
|
||||||
- BUGFIX: Fixed man page
|
|
||||||
- BUGFIX: Fix crash on torrent addition (if libtorrent-rasterbar has debug enabled)
|
|
||||||
- BUGFIX: Fix trackers addition to torrents (bug introduced in v1.5.4)
|
|
||||||
- BUGFIX: Suppress compilation warning regarding sortNewsList() not being used
|
|
||||||
- BUGFIX: Make sure scan folder is different than qBittorrent backup directory to avoid torrents deletion
|
|
||||||
- BUGFIX: Added safety mecanism which adds the torrents back to the list in case qbittorrent-resume.conf gets deleted or corrupted.
|
|
||||||
|
|
||||||
* Sun Oct 25 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.5.4
|
* Sun Oct 25 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.5.4
|
||||||
- BUGFIX: Updated man page
|
- BUGFIX: Updated man page
|
||||||
- BUGFIX: Fixed possible crash with torrents containing unicode characters
|
- BUGFIX: Fixed possible crash with torrents containing unicode characters
|
||||||
|
|||||||
65
INSTALL
@@ -1,55 +1,42 @@
|
|||||||
qBittorrent - A BitTorrent client in C++ / Qt4
|
qBittorrent - A BitTorrent client in C++ / Qt4
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
|
|
||||||
1) Compile and install qBittorrent with Qt4 Graphical Interface
|
*** Necessary if qt3 is default on your system ***
|
||||||
|
export QTDIR=/usr/include/qt4
|
||||||
|
export PATH=$QTDIR/bin:$PATH
|
||||||
|
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$QTDIR/lib
|
||||||
|
*** End ***
|
||||||
|
|
||||||
$ ./configure
|
./configure
|
||||||
$ make && make install
|
make && make install
|
||||||
$ qbittorrent
|
qbittorrent
|
||||||
|
|
||||||
will install and execute qBittorrent hopefully without any problems.
|
will install and execute qBittorrent hopefully without any problems.
|
||||||
|
|
||||||
Dependencies:
|
Dependencies:
|
||||||
- Qt >= 4.6.0 (libqtgui, libqtcore, libqtnetwork, libqtxml, libqtdbus/optional)
|
- Qt >= 4.3.0 (libqt-devel, libqtgui, libqtcore, libqtnetwork, libqtxml)
|
||||||
|
Qt >= 4.4.0 is advised
|
||||||
|
|
||||||
- pkg-config executable
|
- libtorrent-rasterbar by Arvid Norberg (>= v0.14.0 REQUIRED)
|
||||||
|
-> http://www.qbittorrent.org/download.php (advised)
|
||||||
|
-> http://www.libtorrent.net
|
||||||
|
Be careful: another library (the one used by rTorrent) uses a similar name.
|
||||||
|
|
||||||
- libtorrent-rasterbar by Arvid Norberg (>= 0.15.0)
|
- libboost: libboost-filesystem, libboost-date-time, libboost-thread, libboost-serialization
|
||||||
-> http://www.libtorrent.net
|
|
||||||
Be careful: another library (the one used by rTorrent) uses a similar name.
|
|
||||||
|
|
||||||
- libboost 1.34.x (libboost-filesystem°) + libasio
|
- libcurl
|
||||||
or
|
|
||||||
- libboost >= 1.35.x (libboost-system, libboost-filesystem°)
|
|
||||||
|
|
||||||
°libboost-filesystem is not needed if libtorrent-rasterbar >= v0.16.x is used
|
- python >= 2.3 (needed by search engine)
|
||||||
|
|
||||||
- python >= 2.3 (needed by search engine)
|
- libmagick++ (advised, not required)
|
||||||
* Run time only dependency
|
* Needed for favicons support (RSS / Search plugins)
|
||||||
|
|
||||||
- geoip-database (optional)
|
- libzzip (advised, not required)
|
||||||
* If qBittorrent cannot find this database, it will try to resolve countries using the Internet but it will be a lot slower.
|
* Needed for zip support (Search plugins)
|
||||||
* Run time only dependency
|
|
||||||
|
|
||||||
2) Compile and install qBittorrent without Qt4 Graphical interface
|
|
||||||
|
|
||||||
$ ./configure --disable-gui
|
|
||||||
$ make && make install
|
|
||||||
$ qbittorrent
|
|
||||||
|
|
||||||
will install and execute qBittorrent hopefully without any problems.
|
|
||||||
|
|
||||||
Dependencies:
|
|
||||||
- Qt >= 4.4.0 (libqt-devel, libqtcore, libqtnetwork)
|
|
||||||
|
|
||||||
- pkg-config executable
|
|
||||||
|
|
||||||
- libtorrent-rasterbar by Arvid Norberg (>= v0.15.0)
|
|
||||||
-> http://www.libtorrent.net
|
|
||||||
Be careful: another library (the one used by rTorrent) uses a similar name.
|
|
||||||
|
|
||||||
- libboost: libboost-filesystem, libboost-date-time, libboost-thread, libboost-serialization
|
|
||||||
|
|
||||||
|
NOTE FOR NON-KDE USERS:
|
||||||
|
- qt4-qtconfig package is advised when using other systems than KDE.
|
||||||
|
You can also change qBittorrent style to Cleanlooks (GNOME like)
|
||||||
|
|
||||||
DOCUMENTATION:
|
DOCUMENTATION:
|
||||||
Please note that there is a documentation with a "compiling howto" at http://wiki.qbittorrent.org.
|
Please note that there is a documentation with a "compiling howto" at http://wiki.qbittorrent.org.
|
||||||
|
|||||||
6
README
@@ -10,9 +10,6 @@ It aims to be a good alternative to all other bittorrent clients
|
|||||||
out there. qBittorrent is fast, stable and provides unicode
|
out there. qBittorrent is fast, stable and provides unicode
|
||||||
support as well as many features.
|
support as well as many features.
|
||||||
|
|
||||||
This product includes GeoLite data created by MaxMind, available from
|
|
||||||
http://maxmind.com/
|
|
||||||
|
|
||||||
Installation:
|
Installation:
|
||||||
********************************
|
********************************
|
||||||
For installation, follow the instructions from INSTALL file, but simple:
|
For installation, follow the instructions from INSTALL file, but simple:
|
||||||
@@ -26,9 +23,6 @@ will install and execute qBittorrent hopefully without any problem.
|
|||||||
For more information please visit:
|
For more information please visit:
|
||||||
http://www.qbittorrent.org
|
http://www.qbittorrent.org
|
||||||
|
|
||||||
or our wiki here:
|
|
||||||
http://wiki.qbittorrent.org
|
|
||||||
|
|
||||||
Please report any bug (or feature request) to:
|
Please report any bug (or feature request) to:
|
||||||
http://bugs.qbittorrent.org
|
http://bugs.qbittorrent.org
|
||||||
|
|
||||||
|
|||||||
61
README.os2
@@ -1,61 +0,0 @@
|
|||||||
qBittorrent - A BitTorrent client in Qt4
|
|
||||||
------------------------------------------
|
|
||||||
|
|
||||||
This is the eComStation (OS/2) qBittorrent part of the readme. See also README for more general information.
|
|
||||||
|
|
||||||
|
|
||||||
Building qBittorrent
|
|
||||||
********************
|
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
|
||||||
============
|
|
||||||
|
|
||||||
- gcc based build env (recommended gcc v4.4.2 or greater)
|
|
||||||
|
|
||||||
- Qt4 for eCS (OS/2) dev package (see http://svn.netlabs.org/qt4 for more information)
|
|
||||||
|
|
||||||
- libtorrent-rasterbar for eCS (OS/2) port (see http://svn.netlabs.org/ports for more information)
|
|
||||||
|
|
||||||
- boost for eCS (OS/2) port (see http://svn.netlabs.org/ports for more information)
|
|
||||||
|
|
||||||
|
|
||||||
How to build
|
|
||||||
============
|
|
||||||
|
|
||||||
First you need to create the conf.pri file in the same dir as this readme.os2 is.
|
|
||||||
the conf.pri file has the following content:
|
|
||||||
|
|
||||||
##### conf.pri content beginn #####
|
|
||||||
BINDIR = ./bin
|
|
||||||
INCDIR = ./include
|
|
||||||
LIBDIR = ./lib
|
|
||||||
DATADIR = ./share
|
|
||||||
|
|
||||||
CONFIG += staticlib
|
|
||||||
INCLUDEPATH += x:/trees/libtorrent/trunk/include
|
|
||||||
LIBS += -Lx:/trees/libtorrent/trunk/src/.libs \
|
|
||||||
-Lx:/trees/boost/trunk/stage/lib \
|
|
||||||
-Lx:/trees/openssl \
|
|
||||||
-Lx:/extras/lib
|
|
||||||
##### conf.pri content end #####
|
|
||||||
|
|
||||||
Of course all the above path references have to be adjusted to your build env.
|
|
||||||
|
|
||||||
It should now be easy to build qBittorrent:
|
|
||||||
|
|
||||||
Simply type:
|
|
||||||
$ qmake
|
|
||||||
|
|
||||||
Followed by:
|
|
||||||
$ make
|
|
||||||
|
|
||||||
If all works fine you should get a working qbittorrent executable.
|
|
||||||
|
|
||||||
If you have any question regarding the eCS (OS/2) port of qBittorrent you can meet me (_diver) on IRC:
|
|
||||||
#netlabs on irc.freenode.net
|
|
||||||
|
|
||||||
------------------------------------------
|
|
||||||
Silvan Scherrer <silvan.scherrer@aroa.ch>
|
|
||||||
|
|
||||||
|
|
||||||
498
configure
vendored
@@ -18,24 +18,12 @@ Main options:
|
|||||||
--help This help text.
|
--help This help text.
|
||||||
|
|
||||||
Dependency options:
|
Dependency options:
|
||||||
--enable-debug Enable debug mode
|
--with-libboost-inc=[path] Path to libboost include files
|
||||||
--disable-gui Disable qBittorrent
|
--with-libcurl-inc=[path] Path to libcurl include files
|
||||||
Graphical user interface for
|
--with-libcurl-lib=[path] Path to libcurl library files
|
||||||
headless running
|
--disable-libzzip Disable use of libzzip
|
||||||
--disable-qt-dbus Disable use of qt-dbus
|
--with-libzzip-inc=[path] Path to libzzip++ include files
|
||||||
--with-libboost-inc=[path] Path to libboost include
|
--with-libzzip-lib=[path] Path to libzzip++ library files
|
||||||
files
|
|
||||||
--with-libboost-lib=[path] Path to libboost library
|
|
||||||
files
|
|
||||||
--disable-geoip-database Disable use of geoip-database
|
|
||||||
--with-geoip-database-embedded Geoip Database will be
|
|
||||||
embedded in qBittorrent
|
|
||||||
executable (please follow
|
|
||||||
instructions in
|
|
||||||
src/geoip/README)
|
|
||||||
--with-qtsingleapplication=[system|shipped] Use the shipped
|
|
||||||
qtsingleapplication library
|
|
||||||
or the system one
|
|
||||||
|
|
||||||
EOT
|
EOT
|
||||||
}
|
}
|
||||||
@@ -152,43 +140,33 @@ while [ $# -gt 0 ]; do
|
|||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
|
||||||
--enable-debug)
|
|
||||||
QC_ENABLE_DEBUG="Y"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
|
|
||||||
--disable-gui)
|
|
||||||
QC_DISABLE_GUI="Y"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
|
|
||||||
--disable-qt-dbus)
|
|
||||||
QC_DISABLE_qt_dbus="Y"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
|
|
||||||
--with-libboost-inc=*)
|
--with-libboost-inc=*)
|
||||||
QC_WITH_LIBBOOST_INC=$optarg
|
QC_WITH_LIBBOOST_INC=$optarg
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
|
||||||
--with-libboost-lib=*)
|
--with-libcurl-inc=*)
|
||||||
QC_WITH_LIBBOOST_LIB=$optarg
|
QC_WITH_LIBCURL_INC=$optarg
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
|
||||||
--disable-geoip-database)
|
--with-libcurl-lib=*)
|
||||||
QC_DISABLE_geoip_database="Y"
|
QC_WITH_LIBCURL_LIB=$optarg
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
|
||||||
--with-geoip-database-embedded)
|
--disable-libzzip)
|
||||||
QC_WITH_GEOIP_DATABASE_EMBEDDED="Y"
|
QC_DISABLE_libzzip="Y"
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
|
||||||
--with-qtsingleapplication=*)
|
--with-libzzip-inc=*)
|
||||||
QC_WITH_QTSINGLEAPPLICATION=$optarg
|
QC_WITH_LIBZZIP_INC=$optarg
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
|
||||||
|
--with-libzzip-lib=*)
|
||||||
|
QC_WITH_LIBZZIP_LIB=$optarg
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
|
||||||
@@ -213,14 +191,12 @@ echo PREFIX=$PREFIX
|
|||||||
echo BINDIR=$BINDIR
|
echo BINDIR=$BINDIR
|
||||||
echo DATADIR=$DATADIR
|
echo DATADIR=$DATADIR
|
||||||
echo EX_QTDIR=$EX_QTDIR
|
echo EX_QTDIR=$EX_QTDIR
|
||||||
echo QC_ENABLE_DEBUG=$QC_ENABLE_DEBUG
|
|
||||||
echo QC_DISABLE_GUI=$QC_DISABLE_GUI
|
|
||||||
echo QC_DISABLE_qt_dbus=$QC_DISABLE_qt_dbus
|
|
||||||
echo QC_WITH_LIBBOOST_INC=$QC_WITH_LIBBOOST_INC
|
echo QC_WITH_LIBBOOST_INC=$QC_WITH_LIBBOOST_INC
|
||||||
echo QC_WITH_LIBBOOST_LIB=$QC_WITH_LIBBOOST_LIB
|
echo QC_WITH_LIBCURL_INC=$QC_WITH_LIBCURL_INC
|
||||||
echo QC_DISABLE_geoip_database=$QC_DISABLE_geoip_database
|
echo QC_WITH_LIBCURL_LIB=$QC_WITH_LIBCURL_LIB
|
||||||
echo QC_WITH_GEOIP_DATABASE_EMBEDDED=$QC_WITH_GEOIP_DATABASE_EMBEDDED
|
echo QC_DISABLE_libzzip=$QC_DISABLE_libzzip
|
||||||
echo QC_WITH_QTSINGLEAPPLICATION=$QC_WITH_QTSINGLEAPPLICATION
|
echo QC_WITH_LIBZZIP_INC=$QC_WITH_LIBZZIP_INC
|
||||||
|
echo QC_WITH_LIBZZIP_LIB=$QC_WITH_LIBZZIP_LIB
|
||||||
echo
|
echo
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -325,87 +301,22 @@ cat >$1/modules.cpp <<EOT
|
|||||||
#line 1 "qt4.qcm"
|
#line 1 "qt4.qcm"
|
||||||
/*
|
/*
|
||||||
-----BEGIN QCMOD-----
|
-----BEGIN QCMOD-----
|
||||||
name: Qt >= 4.6
|
name: Qt >= 4.3
|
||||||
arg: enable-debug, Enable debug mode
|
|
||||||
arg: disable-gui, Disable qBittorrent Graphical user interface for headless running
|
|
||||||
-----END QCMOD-----
|
-----END QCMOD-----
|
||||||
*/
|
*/
|
||||||
class qc_qt4 : public ConfObj
|
class qc_qt4 : public ConfObj
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
qc_qt4(Conf *c) : ConfObj(c) {}
|
qc_qt4(Conf *c) : ConfObj(c) {}
|
||||||
QString name() const { return "Qt >= 4.6"; }
|
QString name() const { return "Qt >= 4.3"; }
|
||||||
QString shortname() const { return "Qt 4.6"; }
|
QString shortname() const { return "Qt 4.3"; }
|
||||||
bool exec()
|
bool exec()
|
||||||
{
|
{
|
||||||
// NOX mode
|
if(QT_VERSION >= 0x040400) {
|
||||||
if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) {
|
conf->addDefine("QT_4_4");
|
||||||
conf->addExtra("CONFIG += nox");
|
|
||||||
}
|
}
|
||||||
// Debug mode
|
return(QT_VERSION >= 0x040300);
|
||||||
if(!conf->getenv("QC_ENABLE_DEBUG").isEmpty()) {
|
|
||||||
conf->addExtra("CONFIG -= release");
|
|
||||||
conf->addExtra("CONFIG += debug");
|
|
||||||
} else {
|
|
||||||
conf->addExtra("CONFIG -= debug");
|
|
||||||
conf->addExtra("CONFIG += release");
|
|
||||||
}
|
|
||||||
#ifdef Q_OS_FREEBSD
|
|
||||||
conf->addLib("-lexecinfo");
|
|
||||||
conf->addExtra("MANPREFIX = \$\$PREFIX");
|
|
||||||
#else
|
|
||||||
conf->addExtra("MANPREFIX = \$\$PREFIX/share");
|
|
||||||
#endif
|
|
||||||
return(QT_VERSION >= 0x040600);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#line 1 "qt-dbus.qcm"
|
|
||||||
/*
|
|
||||||
-----BEGIN QCMOD-----
|
|
||||||
name: qt-dbus
|
|
||||||
-----END QCMOD-----
|
|
||||||
*/
|
|
||||||
// see Conf::findPkgConfig
|
|
||||||
class qc_qt_dbus : public ConfObj
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
qc_qt_dbus(Conf *c) : ConfObj(c) {}
|
|
||||||
QString name() const { return "QtDBus >= 4.5"; }
|
|
||||||
QString shortname() const { return "qt-dbus"; }
|
|
||||||
QString checkString() const {
|
|
||||||
if(!conf->getenv("QC_DISABLE_qt_dbus").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty())
|
|
||||||
return "";
|
|
||||||
return ConfObj::checkString();
|
|
||||||
}
|
|
||||||
bool exec(){
|
|
||||||
if(!conf->getenv("QC_DISABLE_qt_dbus").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty())
|
|
||||||
return false;
|
|
||||||
QStringList incs;
|
|
||||||
QString req_ver = "4.5.0";
|
|
||||||
QString version, libs, other;
|
|
||||||
VersionMode mode = VersionMin;
|
|
||||||
if(conf->findPkgConfig("QtDBus", mode, req_ver, &version, &incs, &libs, &other)) {
|
|
||||||
conf->addExtra("CONFIG += dbus");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#line 1 "pkg-config.qcm"
|
|
||||||
/*
|
|
||||||
-----BEGIN QCMOD-----
|
|
||||||
name: pkg-config
|
|
||||||
-----END QCMOD-----
|
|
||||||
*/
|
|
||||||
#include <QProcess>
|
|
||||||
class qc_pkg_config : public ConfObj
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
qc_pkg_config(Conf *c) : ConfObj(c) {}
|
|
||||||
QString name() const { return "pkg-config executable"; }
|
|
||||||
QString shortname() const { return "pkg-config"; }
|
|
||||||
bool exec(){
|
|
||||||
return !conf->findProgram("pkg-config").isEmpty();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#line 1 "libtorrent-rasterbar.qcm"
|
#line 1 "libtorrent-rasterbar.qcm"
|
||||||
@@ -419,17 +330,22 @@ class qc_libtorrent_rasterbar : public ConfObj
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {}
|
qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {}
|
||||||
QString name() const { return "libtorrent-rasterbar >= 0.15.0"; }
|
QString name() const { return "libtorrent-rasterbar >= 0.14.0 (>= 0.14.4 advised)"; }
|
||||||
QString shortname() const { return "libtorrent-rasterbar"; }
|
QString shortname() const { return "libtorrent-rasterbar"; }
|
||||||
bool exec(){
|
bool exec(){
|
||||||
QStringList incs;
|
QStringList incs;
|
||||||
QString req_ver = "0.15.0";
|
QString req_ver = "0.14.0";
|
||||||
|
QString adv_ver = "0.14.4";
|
||||||
QString version, libs, other;
|
QString version, libs, other;
|
||||||
VersionMode mode = VersionMin;
|
VersionMode mode = VersionMin;
|
||||||
if(!conf->findPkgConfig("libtorrent-rasterbar", mode, req_ver, &version, &incs, &libs, &other))
|
if(!conf->findPkgConfig("libtorrent-rasterbar", mode, req_ver, &version, &incs, &libs, &other))
|
||||||
return false;
|
return false;
|
||||||
for(int n = 0; n < incs.count(); ++n)
|
for(int n = 0; n < incs.count(); ++n)
|
||||||
conf->addIncludePath(incs[n]);
|
conf->addIncludePath(incs[n]);
|
||||||
|
if(!libs.isEmpty())
|
||||||
|
conf->addLib(libs);
|
||||||
|
if(!conf->findPkgConfig("libtorrent-rasterbar", mode, adv_ver, &version, &incs, &libs, &other))
|
||||||
|
printf("\nWarning: libtorrent-rasterbar v%s was detected. Although it will compile and run, you will probably experience some bugs. Please consider updating to v%s!\n", version.toUtf8().data(), adv_ver.toUtf8().data());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -438,163 +354,191 @@ public:
|
|||||||
-----BEGIN QCMOD-----
|
-----BEGIN QCMOD-----
|
||||||
name: libboost
|
name: libboost
|
||||||
arg: with-libboost-inc=[path], Path to libboost include files
|
arg: with-libboost-inc=[path], Path to libboost include files
|
||||||
arg: with-libboost-lib=[path], Path to libboost library files
|
|
||||||
-----END QCMOD-----
|
-----END QCMOD-----
|
||||||
*/
|
*/
|
||||||
#include <boost/version.hpp>
|
|
||||||
#include <libtorrent/version.hpp>
|
|
||||||
|
|
||||||
class qc_libboost : public ConfObj
|
class qc_libboost : public ConfObj
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
qc_libboost(Conf *c) : ConfObj(c) {}
|
qc_libboost(Conf *c) : ConfObj(c) {}
|
||||||
QString name() const { return "libboost"; }
|
QString name() const { return "libboost"; }
|
||||||
QString shortname() const { return "libboost"; }
|
QString shortname() const { return "libboost"; }
|
||||||
|
bool exec(){
|
||||||
QString findBoostLib(QString path, QString lib) const {
|
QString s;
|
||||||
QString name;
|
s = conf->getenv("QC_WITH_LIBBOOST_INC");
|
||||||
QDir libDir(path);
|
if(!s.isEmpty()) {
|
||||||
QStringList filters;
|
if(!conf->checkHeader(s, "boost/format.hpp")) {
|
||||||
filters << "libboost_"+lib+"*-mt*.so";
|
return false;
|
||||||
QStringList result = libDir.entryList(filters, QDir::Files);
|
}
|
||||||
if(!result.empty()) {
|
if(!conf->checkHeader(s, "boost/date_time/posix_time/posix_time.hpp")) {
|
||||||
name = result.first().mid(3);
|
return false;
|
||||||
// Remove .so
|
}
|
||||||
name.chop(3);
|
if(!conf->checkHeader(s, "boost/filesystem/path.hpp")) {
|
||||||
} else {
|
return false;
|
||||||
// Fall back to non -mt boost lib
|
}
|
||||||
filters.clear();
|
if(!conf->checkHeader(s, "boost/thread.hpp")) {
|
||||||
filters << "libboost_"+lib+"*.so";
|
return false;
|
||||||
result = libDir.entryList(filters, QDir::Files);
|
}
|
||||||
if(!result.empty()) {
|
}else{
|
||||||
name = result.first().mid(3);
|
QStringList sl;
|
||||||
// Remove .so
|
sl << "/usr/include";
|
||||||
name.chop(3);
|
sl << "/usr/local/include";
|
||||||
}
|
bool found = false;
|
||||||
}
|
foreach(s, sl){
|
||||||
return name;
|
if(conf->checkHeader(s, "boost/format.hpp")){
|
||||||
}
|
found = true;
|
||||||
|
break;
|
||||||
bool exec(){
|
}
|
||||||
QStringList sl;
|
}
|
||||||
QString s = conf->getenv("QC_WITH_LIBBOOST_INC");
|
if(!found) {
|
||||||
if (!s.isEmpty())
|
return false;
|
||||||
sl << s;
|
}
|
||||||
sl << "/usr/include";
|
if(!conf->checkHeader(s, "boost/date_time/posix_time/posix_time.hpp")) {
|
||||||
sl << "/usr/local/include";
|
return false;
|
||||||
bool found = false;
|
}
|
||||||
foreach (s, sl) {
|
if(!conf->checkHeader(s, "boost/filesystem/path.hpp")) {
|
||||||
if (conf->checkHeader(s, "boost/format.hpp")
|
return false;
|
||||||
#if LIBTORRENT_VERSION_MAJOR == 0 && LIBTORRENT_VERSION_MINOR < 16
|
}
|
||||||
&& conf->checkHeader(s, "boost/filesystem/path.hpp")
|
if(!conf->checkHeader(s, "boost/thread.hpp")) {
|
||||||
#endif
|
return false;
|
||||||
) {
|
}
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
conf->addIncludePath(s);
|
|
||||||
|
|
||||||
// Find library
|
|
||||||
s = conf->getenv("QC_WITH_LIBBOOST_LIB");
|
|
||||||
QStringList required_libs;
|
|
||||||
#if BOOST_VERSION >= 103500
|
|
||||||
required_libs << "system";
|
|
||||||
#endif
|
|
||||||
#if LIBTORRENT_VERSION_MAJOR == 0 && LIBTORRENT_VERSION_MINOR < 16
|
|
||||||
required_libs << "filesystem" ;
|
|
||||||
#endif
|
|
||||||
required_libs << "thread";
|
|
||||||
QStringList libDirs;
|
|
||||||
if (!s.isEmpty())
|
|
||||||
libDirs << s;
|
|
||||||
libDirs << "/usr/lib/" << "/usr/lib64/" << "/usr/local/lib/" << "/usr/local/lib64/";
|
|
||||||
|
|
||||||
foreach(const QString& lib, required_libs) {
|
|
||||||
bool found = false;
|
|
||||||
foreach(const QString& libDir, libDirs) {
|
|
||||||
QString detected_name = findBoostLib(libDir, lib);
|
|
||||||
if(!detected_name.isEmpty()) {
|
|
||||||
conf->addLib("-l"+detected_name);
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!found) {
|
|
||||||
printf("Could not find boost %s library!\n", qPrintable(lib));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#line 1 "geoip-database.qcm"
|
|
||||||
/*
|
|
||||||
-----BEGIN QCMOD-----
|
|
||||||
name: geoip-database
|
|
||||||
arg: with-geoip-database-embedded, Geoip Database will be embedded in qBittorrent executable (please follow instructions in src/geoip/README)
|
|
||||||
-----END QCMOD-----
|
|
||||||
*/
|
|
||||||
// see Conf::findPkgConfig
|
|
||||||
class qc_geoip_database : public ConfObj
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
qc_geoip_database(Conf *c) : ConfObj(c) {}
|
|
||||||
QString name() const { return "GeoIP Database (optional)"; }
|
|
||||||
QString shortname() const { return "GeoIP Database"; }
|
|
||||||
QString checkString() const {
|
|
||||||
if(!conf->getenv("QC_DISABLE_geoip_database").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty())
|
|
||||||
return "";
|
|
||||||
return ConfObj::checkString();
|
|
||||||
}
|
|
||||||
bool exec() {
|
|
||||||
if(!conf->getenv("QC_DISABLE_geoip_database").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#ifdef Q_WS_X11
|
|
||||||
if(!conf->getenv("QC_WITH_GEOIP_DATABASE_EMBEDDED").isEmpty()) {
|
|
||||||
#endif
|
|
||||||
conf->addDefine("WITH_GEOIP_EMBEDDED");
|
|
||||||
printf(" embedded and");
|
|
||||||
return true;
|
|
||||||
#ifdef Q_WS_X11
|
|
||||||
}
|
}
|
||||||
if(QFile::exists("/usr/share/GeoIP/GeoIP.dat") || QFile::exists("/usr/local/share/GeoIP/GeoIP.dat") || QFile::exists("/var/lib/GeoIP/GeoIP.dat"))
|
conf->addIncludePath(s);
|
||||||
return true;
|
return true;
|
||||||
printf("\nWarning: GeoIP database was not found at /usr/share/GeoIP/GeoIP.dat or /var/lib/GeoIP/GeoIP.dat\nCountry resolution will be slow.");
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#line 1 "qtsingleapplication.qcm"
|
#line 1 "libcurl.qcm"
|
||||||
/*
|
/*
|
||||||
-----BEGIN QCMOD-----
|
-----BEGIN QCMOD-----
|
||||||
name: qtsingleapplication
|
name: libcommoncpp2
|
||||||
arg: with-qtsingleapplication=[system|shipped], Use the shipped qtsingleapplication library or the system one
|
arg: with-libcurl-inc=[path], Path to libcurl include files
|
||||||
|
arg: with-libcurl-lib=[path], Path to libcurl library files
|
||||||
-----END QCMOD-----
|
-----END QCMOD-----
|
||||||
*/
|
*/
|
||||||
class qc_qtsingleapplication : public ConfObj
|
class qc_libcurl : public ConfObj
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
qc_qtsingleapplication(Conf *c) : ConfObj(c) {}
|
qc_libcurl(Conf *c) : ConfObj(c) {}
|
||||||
QString name() const { return "qtsingleapplication library"; }
|
QString name() const { return "libcurl"; }
|
||||||
QString shortname() const { return "qtsingleapplication"; }
|
QString shortname() const { return "libcurl"; }
|
||||||
|
bool exec(){
|
||||||
|
QString s;
|
||||||
|
s = conf->getenv("QC_WITH_LIBCURL_INC");
|
||||||
|
if(!s.isEmpty()) {
|
||||||
|
if(!conf->checkHeader(s, "curl/curl.h")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
QStringList sl;
|
||||||
|
sl << "/usr/include";
|
||||||
|
sl << "/usr/local/include";
|
||||||
|
bool found = false;
|
||||||
|
foreach(s, sl){
|
||||||
|
if(conf->checkHeader(s, "curl/curl.h")){
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!found) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
conf->addIncludePath(s);
|
||||||
|
|
||||||
bool exec(){
|
s = conf->getenv("QC_WITH_LIBCURL_LIB");
|
||||||
QString s;
|
if(!s.isEmpty()) {
|
||||||
s = conf->getenv("QC_WITH_QTSINGLEAPPLICATION");
|
if(!QFile::exists(s+QString("/libcurl.so")))
|
||||||
if(s.compare("system", Qt::CaseInsensitive) == 0) {
|
return false;
|
||||||
// System
|
conf->addLib(QString("-L") + s);
|
||||||
conf->addExtra("CONFIG += usesystemqtsingleapplication");
|
}else{
|
||||||
printf(" [system] ");
|
QStringList sl;
|
||||||
} else {
|
sl << "/usr/lib/";
|
||||||
printf(" [shipped] ");
|
sl << "/usr/lib64/";
|
||||||
}
|
sl << "/usr/local/lib/";
|
||||||
return true;
|
sl << "/usr/local/lib64/";
|
||||||
}
|
bool found = false;
|
||||||
|
foreach(s, sl){
|
||||||
|
if(QFile::exists(s+QString("libcurl.so"))){
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!found) return false;
|
||||||
|
conf->addLib(QString("-L") + s);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#line 1 "libzzip.qcm"
|
||||||
|
/*
|
||||||
|
-----BEGIN QCMOD-----
|
||||||
|
name: libzzip
|
||||||
|
arg: with-libzzip-inc=[path], Path to libzzip++ include files
|
||||||
|
arg: with-libzzip-lib=[path], Path to libzzip++ library files
|
||||||
|
-----END QCMOD-----
|
||||||
|
*/
|
||||||
|
#include <QProcess>
|
||||||
|
class qc_libzzip : public ConfObj
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
qc_libzzip(Conf *c) : ConfObj(c) {}
|
||||||
|
QString name() const { return "Zzip library (libzzip)"; }
|
||||||
|
QString shortname() const { return "libzzip"; }
|
||||||
|
QString checkString() const {
|
||||||
|
if(!conf->getenv("QC_DISABLE_LIBZZIP").isEmpty())
|
||||||
|
return "";
|
||||||
|
return ConfObj::checkString();
|
||||||
|
}
|
||||||
|
bool exec(){
|
||||||
|
if(!conf->getenv("QC_DISABLE_LIBZZIP").isEmpty())
|
||||||
|
return false;
|
||||||
|
QString s;
|
||||||
|
s = conf->getenv("QC_WITH_LIBZZIP_INC");
|
||||||
|
if(!s.isEmpty()) {
|
||||||
|
if(!conf->checkHeader(s, "zzip/zzip.h")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
QStringList sl;
|
||||||
|
sl << "/usr/include";
|
||||||
|
sl << "/usr/local/include";
|
||||||
|
bool found = false;
|
||||||
|
foreach(s, sl){
|
||||||
|
if(conf->checkHeader(s, "zzip/zzip.h")){
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!found)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
conf->addIncludePath(s);
|
||||||
|
|
||||||
|
s = conf->getenv("QC_WITH_LIBZZIP_LIB");
|
||||||
|
if(!s.isEmpty()) {
|
||||||
|
if(!QFile::exists(s+QString("/libzzip.so"))){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
QStringList sl;
|
||||||
|
sl << "/usr/lib/";
|
||||||
|
sl << "/usr/lib64/";
|
||||||
|
sl << "/usr/local/lib/";
|
||||||
|
sl << "/usr/local/lib64/";
|
||||||
|
bool found = false;
|
||||||
|
foreach(s, sl){
|
||||||
|
if(QFile::exists(s+QString("libzzip.so"))){
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!found)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
conf->addLib(QString("-L") + s);
|
||||||
|
conf->addLib("-lzzip");
|
||||||
|
conf->addDefine("HAVE_ZZIP");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
EOT
|
EOT
|
||||||
@@ -602,24 +546,18 @@ 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_qt_dbus(conf);
|
|
||||||
o->required = false;
|
|
||||||
o->disabled = false;
|
|
||||||
o = new qc_pkg_config(conf);
|
|
||||||
o->required = true;
|
|
||||||
o->disabled = false;
|
|
||||||
o = new qc_libtorrent_rasterbar(conf);
|
o = new qc_libtorrent_rasterbar(conf);
|
||||||
o->required = true;
|
o->required = true;
|
||||||
o->disabled = false;
|
o->disabled = false;
|
||||||
o = new qc_libboost(conf);
|
o = new qc_libboost(conf);
|
||||||
o->required = true;
|
o->required = true;
|
||||||
o->disabled = false;
|
o->disabled = false;
|
||||||
o = new qc_geoip_database(conf);
|
o = new qc_libcurl(conf);
|
||||||
o->required = false;
|
|
||||||
o->disabled = false;
|
|
||||||
o = new qc_qtsingleapplication(conf);
|
|
||||||
o->required = true;
|
o->required = true;
|
||||||
o->disabled = false;
|
o->disabled = false;
|
||||||
|
o = new qc_libzzip(conf);
|
||||||
|
o->required = false;
|
||||||
|
o->disabled = false;
|
||||||
|
|
||||||
EOT
|
EOT
|
||||||
cat >$1/conf4.h <<EOT
|
cat >$1/conf4.h <<EOT
|
||||||
@@ -1565,14 +1503,12 @@ export PREFIX
|
|||||||
export BINDIR
|
export BINDIR
|
||||||
export DATADIR
|
export DATADIR
|
||||||
export EX_QTDIR
|
export EX_QTDIR
|
||||||
export QC_ENABLE_DEBUG
|
|
||||||
export QC_DISABLE_GUI
|
|
||||||
export QC_DISABLE_qt_dbus
|
|
||||||
export QC_WITH_LIBBOOST_INC
|
export QC_WITH_LIBBOOST_INC
|
||||||
export QC_WITH_LIBBOOST_LIB
|
export QC_WITH_LIBCURL_INC
|
||||||
export QC_DISABLE_geoip_database
|
export QC_WITH_LIBCURL_LIB
|
||||||
export QC_WITH_GEOIP_DATABASE_EMBEDDED
|
export QC_DISABLE_libzzip
|
||||||
export QC_WITH_QTSINGLEAPPLICATION
|
export QC_WITH_LIBZZIP_INC
|
||||||
|
export QC_WITH_LIBZZIP_LIB
|
||||||
export QC_VERBOSE
|
export QC_VERBOSE
|
||||||
rm -rf .qconftemp
|
rm -rf .qconftemp
|
||||||
(
|
(
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
.\" 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\-NOX" "1" "January 16th 2010" "Command line Bittorrent client written in C++ / Qt4" ""
|
|
||||||
|
|
||||||
.SH "NAME"
|
|
||||||
qBittorrent\-nox \- a command line Bittorrent client written in C++ / Qt4
|
|
||||||
|
|
||||||
.SH "SYNOPSIS"
|
|
||||||
|
|
||||||
\fBqbittorrent\-nox\fR [\-\-webui-port=x] [TORRENT_FILE | URL]...
|
|
||||||
|
|
||||||
\fBqbittorrent\-nox\fR \-\-help
|
|
||||||
|
|
||||||
\fBqbittorrent\-nox\fR \-\-version
|
|
||||||
|
|
||||||
.PP
|
|
||||||
.SH "DESCRIPTION"
|
|
||||||
|
|
||||||
\fBqBittorrent-nox\fR is an advanced command-line Bittorrent client written in C++ / Qt4,
|
|
||||||
using the \fBlibtorrent-rasterbar\fR library by Arvid Norberg. qBittorrent\-nox aims
|
|
||||||
to be a good alternative to other command line bittorrent clients and provides features similar to popular graphical clients.
|
|
||||||
|
|
||||||
qBittorrent\-nox is fast, stable, light and it supports unicode.
|
|
||||||
It also comes with UPnP port forwarding / NAT-PMP, encryption (Vuze compatible),
|
|
||||||
FAST extension (mainline) and PeX support (utorrent compatible).
|
|
||||||
|
|
||||||
qBittorrent\-nox is meant to be controlled via its feature-rich Web UI which is accessible as a default on http://localhost:8080. The Web UI access is secured and the default account user name is "admin" with "adminadmin" as a password.
|
|
||||||
|
|
||||||
.SH "OPTIONS"
|
|
||||||
|
|
||||||
\fB--help\fR Prints the command line options.
|
|
||||||
|
|
||||||
\fB--version\fR Prints qbittorrent program version number.
|
|
||||||
|
|
||||||
\fB--webui-port=x\fR Changes Web UI port to x (default: 8080).
|
|
||||||
|
|
||||||
.SH "BUGS"
|
|
||||||
|
|
||||||
If you find a bug, please report it at http://bugs.qbittorrent.org
|
|
||||||
|
|
||||||
.SH "AUTHOR"
|
|
||||||
|
|
||||||
Christophe Dumez <chris@qbittorrent.org>
|
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
.\" This manpage has been automatically generated by docbook2man
|
.\" This manpage has been automatically generated by docbook2man
|
||||||
.\" from a DocBook document. This tool can be found at:
|
.\" from a DocBook document. This tool can be found at:
|
||||||
.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>.
|
.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>.
|
||||||
.TH "QBITTORRENT" "1" "January 16th 2010" "Bittorrent client written in C++ / Qt4" ""
|
.TH "QBITTORRENT" "1" "September 30th 2009" "Bittorrent client written in C++ / Qt4" ""
|
||||||
|
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
qBittorrent \- a Bittorrent client written in C++ / Qt4
|
qBittorrent \- a Bittorrent client written in C++ / Qt4
|
||||||
|
|
||||||
.SH "SYNOPSIS"
|
.SH "SYNOPSIS"
|
||||||
|
|
||||||
\fBqbittorrent\fR [\-\-no-splash] [\-\-webui-port=x] [TORRENT_FILE | URL]...
|
\fBqbittorrent\fR [--no-splash] [TORRENT_FILE | URL]...
|
||||||
|
|
||||||
\fBqbittorrent\fR \-\-help
|
\fBqbittorrent\fR \-\-help
|
||||||
|
|
||||||
@@ -18,9 +18,10 @@ qBittorrent \- a Bittorrent client written in C++ / Qt4
|
|||||||
.SH "DESCRIPTION"
|
.SH "DESCRIPTION"
|
||||||
|
|
||||||
\fBqBittorrent\fR is an advanced Bittorrent client written in C++ / Qt4,
|
\fBqBittorrent\fR is an advanced Bittorrent client written in C++ / Qt4,
|
||||||
using the \fBlibtorrent-rasterbar\fR library by Arvid Norberg. qBittorrent is similar to uTorrent. qBittorrent
|
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.
|
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 (Vuze compatible),
|
It also comes with UPnP port forwarding / NAT-PMP, encryption (Azureus compatible),
|
||||||
FAST extension (mainline) and PeX support (utorrent compatible).
|
FAST extension (mainline) and PeX support (utorrent compatible).
|
||||||
|
|
||||||
.SH "OPTIONS"
|
.SH "OPTIONS"
|
||||||
@@ -31,8 +32,6 @@ FAST extension (mainline) and PeX support (utorrent compatible).
|
|||||||
|
|
||||||
\fB--no-splash\fR Disables splash screen on startup.
|
\fB--no-splash\fR Disables splash screen on startup.
|
||||||
|
|
||||||
\fB--webui-port=x\fR Changes Web UI port to x (default: 8080).
|
|
||||||
|
|
||||||
.SH "BUGS"
|
.SH "BUGS"
|
||||||
|
|
||||||
If you find a bug, please report it at http://bugs.qbittorrent.org
|
If you find a bug, please report it at http://bugs.qbittorrent.org
|
||||||
|
|||||||
174
install.os2
@@ -1,174 +0,0 @@
|
|||||||
QBittorrent installation
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
0. CONTENTS OF THIS FILE
|
|
||||||
========================
|
|
||||||
|
|
||||||
1. INTRODUCTION
|
|
||||||
|
|
||||||
2. REQUIREMENTS
|
|
||||||
|
|
||||||
3. INSTALLATION
|
|
||||||
|
|
||||||
4. BUGREPORTS
|
|
||||||
|
|
||||||
5. CREDITS
|
|
||||||
|
|
||||||
6. SUPPORT AND DONATIONS
|
|
||||||
|
|
||||||
7. HISTORY
|
|
||||||
|
|
||||||
|
|
||||||
1. INTRODUCTION
|
|
||||||
===============
|
|
||||||
|
|
||||||
Welcome to QBittorrent port for OS/2 and eComStation.
|
|
||||||
|
|
||||||
|
|
||||||
2. REQUIREMENTS
|
|
||||||
===============
|
|
||||||
|
|
||||||
The following requirements can be installed either by rpm or by zip files.
|
|
||||||
|
|
||||||
RPM Installation:
|
|
||||||
|
|
||||||
klibc
|
|
||||||
-----
|
|
||||||
|
|
||||||
1. yum install libc
|
|
||||||
|
|
||||||
openssl 1.0
|
|
||||||
-----------
|
|
||||||
|
|
||||||
1. yum install openssl
|
|
||||||
|
|
||||||
pthread
|
|
||||||
-------
|
|
||||||
|
|
||||||
1. yum install pthread
|
|
||||||
|
|
||||||
GCC4Core
|
|
||||||
--------
|
|
||||||
|
|
||||||
1. yum install libgcc
|
|
||||||
2. yum install gcc-stack-protector
|
|
||||||
3. yum install gcc-stdc++-shared-library
|
|
||||||
4. yum install gcc-supc++-shared-library
|
|
||||||
|
|
||||||
Qt4 dll
|
|
||||||
-------
|
|
||||||
|
|
||||||
1. yum install libqt4
|
|
||||||
|
|
||||||
|
|
||||||
ZIP Installation:
|
|
||||||
|
|
||||||
klibc
|
|
||||||
-----
|
|
||||||
|
|
||||||
1. Download klibc 0.6.4 or better (see http://svn.netlabs.org/libc for more information)
|
|
||||||
2. Install the files to your libpath eg x:\ecs\dll
|
|
||||||
|
|
||||||
openssl 1.0
|
|
||||||
-----------
|
|
||||||
|
|
||||||
1. Download the zip file from http://rpm.netlabs.org/release/00/zip
|
|
||||||
2. Install the files to your libpath eg. x:\ecs\dll
|
|
||||||
|
|
||||||
pthread
|
|
||||||
-------
|
|
||||||
|
|
||||||
1. Download pthread 2012-03-13 or better from http://rpm.netlabs.org/release/00/zip
|
|
||||||
2. Install the files to your libpath eg. x:\ecs\dll
|
|
||||||
|
|
||||||
GCC4Core
|
|
||||||
--------
|
|
||||||
|
|
||||||
1. Download GCC4Core 1.2.1 or better from http://ftp.netlabs.org/pub/gcc
|
|
||||||
2. Install the files to your libpath eg. x:\ecs\dll
|
|
||||||
|
|
||||||
Qt4 dll
|
|
||||||
-------
|
|
||||||
|
|
||||||
1. Download Qt4 4.7.3 or better (see http://svn.netlabs.org/qt4 for more information)
|
|
||||||
2. Install the files according to the readme
|
|
||||||
|
|
||||||
|
|
||||||
3. INSTALLATION
|
|
||||||
===============
|
|
||||||
|
|
||||||
To install QBittorrent, do the following:
|
|
||||||
|
|
||||||
1. Create a directory for QBittorrent.
|
|
||||||
2. Extract the QBittorrent package to the new directory.
|
|
||||||
3. Create a WPS object for QBittorrent.exe.
|
|
||||||
4. Start QBittorrent
|
|
||||||
5. Happy torrenting
|
|
||||||
|
|
||||||
|
|
||||||
4. BUGREPORTS
|
|
||||||
=============
|
|
||||||
|
|
||||||
Please create bugreports at http://svn.netlabs.org/qtapps
|
|
||||||
Only bug reports with a reproducable bug are accepted. :-)
|
|
||||||
|
|
||||||
|
|
||||||
5. CREDITS
|
|
||||||
==========
|
|
||||||
|
|
||||||
The port was done by:
|
|
||||||
|
|
||||||
Silvan Scherrer aka _diver
|
|
||||||
|
|
||||||
Thanks go to:
|
|
||||||
|
|
||||||
* Dmitry A. Kuminov
|
|
||||||
|
|
||||||
They either helped me when I had some nasty questions or did some testing for
|
|
||||||
me.
|
|
||||||
|
|
||||||
|
|
||||||
6. SUPPORT AND DONATIONS
|
|
||||||
========================
|
|
||||||
|
|
||||||
QBittorrent port is based on volunteer work. If you would like to support further
|
|
||||||
development, you can do so in one of the following ways:
|
|
||||||
|
|
||||||
|
|
||||||
* Donate to the Qt4 project: see qt.netlabs.org for more information
|
|
||||||
|
|
||||||
* Contribute to the project: Besides actual development, this also includes
|
|
||||||
maintaining the documentation and the project web site as well as help
|
|
||||||
for users.
|
|
||||||
|
|
||||||
|
|
||||||
7. HISTORY
|
|
||||||
==========
|
|
||||||
|
|
||||||
2012-03-15
|
|
||||||
|
|
||||||
* updated to 2.9.5 code level of QBittorrent
|
|
||||||
|
|
||||||
2011-09-26
|
|
||||||
|
|
||||||
* updated to 2.8.5 code level of QBittorrent
|
|
||||||
* updated to Qt 4.7.3
|
|
||||||
|
|
||||||
2011-06-20
|
|
||||||
|
|
||||||
* updated to 2.7.3 code level of QBittorrent
|
|
||||||
* updated libtorrent to 0.15.6 level
|
|
||||||
|
|
||||||
2010-12-23
|
|
||||||
|
|
||||||
* updated to 2.5.2 code level of QBittorrent
|
|
||||||
|
|
||||||
2010-11-22
|
|
||||||
|
|
||||||
* updated to 2.4.11 code level of QBittorrent
|
|
||||||
|
|
||||||
2010-xx-xx
|
|
||||||
|
|
||||||
* initial port
|
|
||||||
|
|
||||||
31
macxconf.pri
@@ -1,31 +0,0 @@
|
|||||||
PREFIX = /usr/local
|
|
||||||
BINDIR = /usr/local/bin
|
|
||||||
DATADIR = /usr/local/share
|
|
||||||
|
|
||||||
# Use pkg-config to get all necessary libtorrent DEFINES
|
|
||||||
CONFIG += link_pkgconfig
|
|
||||||
PKGCONFIG += libtorrent-rasterbar
|
|
||||||
DEFINES += BOOST_ASIO_DYN_LINK
|
|
||||||
|
|
||||||
# Special include/libs paths (macports)
|
|
||||||
INCLUDEPATH += /usr/include/openssl /usr/include /opt/local/include/boost /opt/local/include
|
|
||||||
LIBS += -L/opt/local/lib
|
|
||||||
|
|
||||||
# OpenSSL lib
|
|
||||||
LIBS += -lssl -lcrypto
|
|
||||||
# Boost system lib
|
|
||||||
LIBS += -lboost_system-mt
|
|
||||||
# Boost filesystem lib (Not needed for libtorrent >= 0.16.0)
|
|
||||||
LIBS += -lboost_filesystem-mt
|
|
||||||
# Carbon
|
|
||||||
LIBS += -framework Carbon -framework IOKit
|
|
||||||
|
|
||||||
document_icon.path = Contents/Resources
|
|
||||||
document_icon.files = Icons/qBitTorrentDocument.icns
|
|
||||||
|
|
||||||
QMAKE_BUNDLE_DATA += document_icon
|
|
||||||
ICON = Icons/qbittorrent_mac.icns
|
|
||||||
QMAKE_INFO_PLIST = Info.plist
|
|
||||||
|
|
||||||
DEFINES += WITH_GEOIP_EMBEDDED
|
|
||||||
message("On Mac OS X, GeoIP database must be embedded.")
|
|
||||||
18
os2conf.pri
@@ -1,18 +0,0 @@
|
|||||||
exists(conf.pri) {
|
|
||||||
# to the conf.pri goes all system dependent stuff
|
|
||||||
include(conf.pri)
|
|
||||||
}
|
|
||||||
|
|
||||||
LIBS += -ltorrent-rasterbar \
|
|
||||||
-lboost_thread \
|
|
||||||
-lboost_system \
|
|
||||||
-lboost_filesystem \
|
|
||||||
-lssl -lcrypto -lidn -lpthread
|
|
||||||
|
|
||||||
RC_FILE = qbittorrent_os2.rc
|
|
||||||
|
|
||||||
# LIBTORRENT DEFINES
|
|
||||||
DEFINES += WITH_SHIPPED_GEOIP_H
|
|
||||||
|
|
||||||
DEFINES += WITH_GEOIP_EMBEDDED
|
|
||||||
message("On eCS(OS/2), GeoIP database must be embedded.")
|
|
||||||
199
qBittorrent.kdevelop
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
<?xml version = '1.0'?>
|
||||||
|
<kdevelop>
|
||||||
|
<general>
|
||||||
|
<author>Christophe Dumez</author>
|
||||||
|
<email>chris@qbittorrent.org</email>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<projectmanagement>KDevTrollProject</projectmanagement>
|
||||||
|
<primarylanguage>C++</primarylanguage>
|
||||||
|
<keywords>
|
||||||
|
<keyword>Qt</keyword>
|
||||||
|
</keywords>
|
||||||
|
<projectname>qBittorrent</projectname>
|
||||||
|
<ignoreparts/>
|
||||||
|
<projectdirectory>.</projectdirectory>
|
||||||
|
<absoluteprojectpath>false</absoluteprojectpath>
|
||||||
|
<description/>
|
||||||
|
<defaultencoding/>
|
||||||
|
<versioncontrol>kdevsubversion</versioncontrol>
|
||||||
|
</general>
|
||||||
|
<kdevfileview>
|
||||||
|
<groups>
|
||||||
|
<group pattern="*.cpp;*.cxx;*.h" name="Sources" />
|
||||||
|
<group pattern="*.ui" name="User Interface" />
|
||||||
|
<group pattern="*.png" name="Icons" />
|
||||||
|
<group pattern="*" name="Others" />
|
||||||
|
<hidenonprojectfiles>false</hidenonprojectfiles>
|
||||||
|
<hidenonlocation>false</hidenonlocation>
|
||||||
|
</groups>
|
||||||
|
<tree>
|
||||||
|
<hidepatterns>*.o,*.lo,CVS</hidepatterns>
|
||||||
|
<hidenonprojectfiles>false</hidenonprojectfiles>
|
||||||
|
<showvcsfields>false</showvcsfields>
|
||||||
|
</tree>
|
||||||
|
</kdevfileview>
|
||||||
|
<kdevdoctreeview>
|
||||||
|
<ignoretocs>
|
||||||
|
<toc>bash</toc>
|
||||||
|
<toc>bash_bugs</toc>
|
||||||
|
<toc>clanlib</toc>
|
||||||
|
<toc>w3c-dom-level2-html</toc>
|
||||||
|
<toc>fortran_bugs_gcc</toc>
|
||||||
|
<toc>gnome1</toc>
|
||||||
|
<toc>gnustep</toc>
|
||||||
|
<toc>gtk</toc>
|
||||||
|
<toc>gtk_bugs</toc>
|
||||||
|
<toc>haskell</toc>
|
||||||
|
<toc>haskell_bugs_ghc</toc>
|
||||||
|
<toc>java_bugs_gcc</toc>
|
||||||
|
<toc>java_bugs_sun</toc>
|
||||||
|
<toc>kde2book</toc>
|
||||||
|
<toc>opengl</toc>
|
||||||
|
<toc>pascal_bugs_fp</toc>
|
||||||
|
<toc>php</toc>
|
||||||
|
<toc>php_bugs</toc>
|
||||||
|
<toc>perl</toc>
|
||||||
|
<toc>perl_bugs</toc>
|
||||||
|
<toc>python</toc>
|
||||||
|
<toc>python_bugs</toc>
|
||||||
|
<toc>qt-kdev3</toc>
|
||||||
|
<toc>ruby</toc>
|
||||||
|
<toc>ruby_bugs</toc>
|
||||||
|
<toc>sdl</toc>
|
||||||
|
<toc>stl</toc>
|
||||||
|
<toc>w3c-svg</toc>
|
||||||
|
<toc>sw</toc>
|
||||||
|
<toc>w3c-uaag10</toc>
|
||||||
|
<toc>wxwidgets_bugs</toc>
|
||||||
|
</ignoretocs>
|
||||||
|
<ignoredoxygen>
|
||||||
|
<toc>KDE Libraries (Doxygen)</toc>
|
||||||
|
</ignoredoxygen>
|
||||||
|
</kdevdoctreeview>
|
||||||
|
<kdevdebugger>
|
||||||
|
<general>
|
||||||
|
<dbgshell/>
|
||||||
|
<gdbpath/>
|
||||||
|
<configGdbScript/>
|
||||||
|
<runShellScript/>
|
||||||
|
<runGdbScript/>
|
||||||
|
<breakonloadinglibs>true</breakonloadinglibs>
|
||||||
|
<separatetty>false</separatetty>
|
||||||
|
<floatingtoolbar>false</floatingtoolbar>
|
||||||
|
</general>
|
||||||
|
<display>
|
||||||
|
<staticmembers>false</staticmembers>
|
||||||
|
<demanglenames>true</demanglenames>
|
||||||
|
<outputradix>10</outputradix>
|
||||||
|
</display>
|
||||||
|
</kdevdebugger>
|
||||||
|
<kdevcppsupport>
|
||||||
|
<qt>
|
||||||
|
<version>4</version>
|
||||||
|
<used>true</used>
|
||||||
|
<includestyle>4</includestyle>
|
||||||
|
<designerintegration>ExternalDesigner</designerintegration>
|
||||||
|
<root>/usr/lib/qt4</root>
|
||||||
|
<qmake>/usr/bin/qmake</qmake>
|
||||||
|
<designer>/usr/bin/designer</designer>
|
||||||
|
<designerpluginpaths/>
|
||||||
|
</qt>
|
||||||
|
<references>
|
||||||
|
<pcs>automatic_%2Fhome%2Fishanarora%2Fprojects%2Fqbittorrent</pcs>
|
||||||
|
</references>
|
||||||
|
<codecompletion>
|
||||||
|
<automaticCodeCompletion>true</automaticCodeCompletion>
|
||||||
|
<automaticArgumentsHint>true</automaticArgumentsHint>
|
||||||
|
<automaticHeaderCompletion>true</automaticHeaderCompletion>
|
||||||
|
<codeCompletionDelay>250</codeCompletionDelay>
|
||||||
|
<argumentsHintDelay>400</argumentsHintDelay>
|
||||||
|
<headerCompletionDelay>250</headerCompletionDelay>
|
||||||
|
<showOnlyAccessibleItems>false</showOnlyAccessibleItems>
|
||||||
|
<completionBoxItemOrder>0</completionBoxItemOrder>
|
||||||
|
<howEvaluationContextMenu>true</howEvaluationContextMenu>
|
||||||
|
<showCommentWithArgumentHint>true</showCommentWithArgumentHint>
|
||||||
|
<statusBarTypeEvaluation>false</statusBarTypeEvaluation>
|
||||||
|
<namespaceAliases>std=_GLIBCXX_STD;__gnu_cxx=std</namespaceAliases>
|
||||||
|
<processPrimaryTypes>true</processPrimaryTypes>
|
||||||
|
<processFunctionArguments>true</processFunctionArguments>
|
||||||
|
<preProcessAllHeaders>true</preProcessAllHeaders>
|
||||||
|
<parseMissingHeadersExperimental>true</parseMissingHeadersExperimental>
|
||||||
|
<resolveIncludePathsUsingMakeExperimental>true</resolveIncludePathsUsingMakeExperimental>
|
||||||
|
<alwaysParseInBackground>true</alwaysParseInBackground>
|
||||||
|
<usePermanentCaching>true</usePermanentCaching>
|
||||||
|
<alwaysIncludeNamespaces>false</alwaysIncludeNamespaces>
|
||||||
|
<includePaths>.;</includePaths>
|
||||||
|
</codecompletion>
|
||||||
|
<creategettersetter>
|
||||||
|
<prefixGet>get</prefixGet>
|
||||||
|
<prefixSet>set</prefixSet>
|
||||||
|
<prefixVariable>m_,_</prefixVariable>
|
||||||
|
<parameterName>theValue</parameterName>
|
||||||
|
<inlineGet>true</inlineGet>
|
||||||
|
<inlineSet>true</inlineSet>
|
||||||
|
</creategettersetter>
|
||||||
|
<splitheadersource>
|
||||||
|
<enabled>false</enabled>
|
||||||
|
<synchronize>true</synchronize>
|
||||||
|
<orientation>Vertical</orientation>
|
||||||
|
</splitheadersource>
|
||||||
|
</kdevcppsupport>
|
||||||
|
<kdevfilecreate>
|
||||||
|
<filetypes/>
|
||||||
|
<useglobaltypes>
|
||||||
|
<type ext="ui" />
|
||||||
|
<type ext="cpp" />
|
||||||
|
<type ext="h" />
|
||||||
|
</useglobaltypes>
|
||||||
|
</kdevfilecreate>
|
||||||
|
<kdevtrollproject>
|
||||||
|
<general>
|
||||||
|
<activedir>src</activedir>
|
||||||
|
</general>
|
||||||
|
<run>
|
||||||
|
<directoryradio>executable</directoryradio>
|
||||||
|
<mainprogram>/home/ishanarora/projects/qbittorrent/src/qbittorrent</mainprogram>
|
||||||
|
<programargs/>
|
||||||
|
<globaldebugarguments/>
|
||||||
|
<globalcwd>/home/ishanarora/projects/qbittorrent</globalcwd>
|
||||||
|
<useglobalprogram>true</useglobalprogram>
|
||||||
|
<terminal>false</terminal>
|
||||||
|
<autocompile>true</autocompile>
|
||||||
|
<autoinstall>false</autoinstall>
|
||||||
|
<autokdesu>false</autokdesu>
|
||||||
|
<envvars/>
|
||||||
|
</run>
|
||||||
|
<make>
|
||||||
|
<abortonerror>true</abortonerror>
|
||||||
|
<runmultiplejobs>false</runmultiplejobs>
|
||||||
|
<numberofjobs>1</numberofjobs>
|
||||||
|
<dontact>false</dontact>
|
||||||
|
<makebin/>
|
||||||
|
<prio>0</prio>
|
||||||
|
<envvars/>
|
||||||
|
</make>
|
||||||
|
<qmake>
|
||||||
|
<savebehaviour>2</savebehaviour>
|
||||||
|
<replacePaths>false</replacePaths>
|
||||||
|
<disableDefaultOpts>true</disableDefaultOpts>
|
||||||
|
</qmake>
|
||||||
|
</kdevtrollproject>
|
||||||
|
<cppsupportpart>
|
||||||
|
<filetemplates>
|
||||||
|
<interfacesuffix>.h</interfacesuffix>
|
||||||
|
<implementationsuffix>.cpp</implementationsuffix>
|
||||||
|
</filetemplates>
|
||||||
|
</cppsupportpart>
|
||||||
|
<ctagspart>
|
||||||
|
<customArguments/>
|
||||||
|
<customTagfilePath>/home/ishanarora/projects/qbittorrent/tags</customTagfilePath>
|
||||||
|
<activeTagsFiles/>
|
||||||
|
</ctagspart>
|
||||||
|
<kdevdocumentation>
|
||||||
|
<projectdoc>
|
||||||
|
<docsystem/>
|
||||||
|
<docurl/>
|
||||||
|
<usermanualurl/>
|
||||||
|
</projectdoc>
|
||||||
|
</kdevdocumentation>
|
||||||
|
</kdevelop>
|
||||||
@@ -1,18 +1,6 @@
|
|||||||
TEMPLATE = subdirs
|
TEMPLATE = subdirs
|
||||||
|
|
||||||
|
include(conf.pri)
|
||||||
|
|
||||||
SUBDIRS += src
|
SUBDIRS += src
|
||||||
|
|
||||||
include(version.pri)
|
|
||||||
|
|
||||||
# Dist
|
|
||||||
dist.commands += rm -fR ../$${PROJECT_NAME}-$${PROJECT_VERSION}/ &&
|
|
||||||
dist.commands += git clone . ../$${PROJECT_NAME}-$${PROJECT_VERSION} &&
|
|
||||||
dist.commands += rm -fR ../$${PROJECT_NAME}-$${PROJECT_VERSION}/.git &&
|
|
||||||
dist.commands += rm -f ../$${PROJECT_NAME}-$${PROJECT_VERSION}/.gitignore &&
|
|
||||||
dist.commands += cd .. &&
|
|
||||||
dist.commands += tar czf $${PROJECT_NAME}-$${PROJECT_VERSION}.tar.gz $${PROJECT_NAME}-$${PROJECT_VERSION} &&
|
|
||||||
dist.commands += tar cf $${PROJECT_NAME}-$${PROJECT_VERSION}.tar $${PROJECT_NAME}-$${PROJECT_VERSION} &&
|
|
||||||
dist.commands += xz -f $${PROJECT_NAME}-$${PROJECT_VERSION}.tar &&
|
|
||||||
dist.commands += rm -fR $${PROJECT_NAME}-$${PROJECT_VERSION}
|
|
||||||
|
|
||||||
QMAKE_EXTRA_TARGETS += dist
|
|
||||||
|
|||||||
@@ -6,20 +6,14 @@
|
|||||||
<dep type='qt4'>
|
<dep type='qt4'>
|
||||||
<required/>
|
<required/>
|
||||||
</dep>
|
</dep>
|
||||||
<dep type='qt-dbus'>
|
|
||||||
</dep>
|
|
||||||
<dep type='pkg-config'>
|
|
||||||
<required/>
|
|
||||||
</dep>
|
|
||||||
<dep type='libtorrent-rasterbar'>
|
<dep type='libtorrent-rasterbar'>
|
||||||
<required/>
|
<required/>
|
||||||
</dep>
|
</dep>
|
||||||
<dep type='libboost'>
|
<dep type='libboost'>
|
||||||
<required/>
|
<required/>
|
||||||
</dep>
|
</dep>
|
||||||
<dep type='geoip-database'>
|
<dep type='libcurl'>
|
||||||
</dep>
|
|
||||||
<dep type='qtsingleapplication'>
|
|
||||||
<required/>
|
<required/>
|
||||||
</dep>
|
</dep>
|
||||||
|
<dep type='libzzip'/>
|
||||||
</qconf>
|
</qconf>
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
-----BEGIN QCMOD-----
|
|
||||||
name: geoip-database
|
|
||||||
arg: with-geoip-database-embedded, Geoip Database will be embedded in qBittorrent executable (please follow instructions in src/geoip/README)
|
|
||||||
-----END QCMOD-----
|
|
||||||
*/
|
|
||||||
// see Conf::findPkgConfig
|
|
||||||
class qc_geoip_database : public ConfObj
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
qc_geoip_database(Conf *c) : ConfObj(c) {}
|
|
||||||
QString name() const { return "GeoIP Database (optional)"; }
|
|
||||||
QString shortname() const { return "GeoIP Database"; }
|
|
||||||
QString checkString() const {
|
|
||||||
if(!conf->getenv("QC_DISABLE_geoip_database").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty())
|
|
||||||
return "";
|
|
||||||
return ConfObj::checkString();
|
|
||||||
}
|
|
||||||
bool exec() {
|
|
||||||
if(!conf->getenv("QC_DISABLE_geoip_database").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#ifdef Q_WS_X11
|
|
||||||
if(!conf->getenv("QC_WITH_GEOIP_DATABASE_EMBEDDED").isEmpty()) {
|
|
||||||
#endif
|
|
||||||
conf->addDefine("WITH_GEOIP_EMBEDDED");
|
|
||||||
printf(" embedded and");
|
|
||||||
return true;
|
|
||||||
#ifdef Q_WS_X11
|
|
||||||
}
|
|
||||||
if(QFile::exists("/usr/share/GeoIP/GeoIP.dat") || QFile::exists("/usr/local/share/GeoIP/GeoIP.dat") || QFile::exists("/var/lib/GeoIP/GeoIP.dat"))
|
|
||||||
return true;
|
|
||||||
printf("\nWarning: GeoIP database was not found at /usr/share/GeoIP/GeoIP.dat or /var/lib/GeoIP/GeoIP.dat\nCountry resolution will be slow.");
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
};
|
|
||||||
133
qcm/libboost.qcm
@@ -2,96 +2,55 @@
|
|||||||
-----BEGIN QCMOD-----
|
-----BEGIN QCMOD-----
|
||||||
name: libboost
|
name: libboost
|
||||||
arg: with-libboost-inc=[path], Path to libboost include files
|
arg: with-libboost-inc=[path], Path to libboost include files
|
||||||
arg: with-libboost-lib=[path], Path to libboost library files
|
|
||||||
-----END QCMOD-----
|
-----END QCMOD-----
|
||||||
*/
|
*/
|
||||||
#include <boost/version.hpp>
|
|
||||||
#include <libtorrent/version.hpp>
|
|
||||||
|
|
||||||
class qc_libboost : public ConfObj
|
class qc_libboost : public ConfObj
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
qc_libboost(Conf *c) : ConfObj(c) {}
|
qc_libboost(Conf *c) : ConfObj(c) {}
|
||||||
QString name() const { return "libboost"; }
|
QString name() const { return "libboost"; }
|
||||||
QString shortname() const { return "libboost"; }
|
QString shortname() const { return "libboost"; }
|
||||||
|
bool exec(){
|
||||||
QString findBoostLib(QString path, QString lib) const {
|
QString s;
|
||||||
QString name;
|
s = conf->getenv("QC_WITH_LIBBOOST_INC");
|
||||||
QDir libDir(path);
|
if(!s.isEmpty()) {
|
||||||
QStringList filters;
|
if(!conf->checkHeader(s, "boost/format.hpp")) {
|
||||||
filters << "libboost_"+lib+"*-mt*.so";
|
return false;
|
||||||
QStringList result = libDir.entryList(filters, QDir::Files);
|
}
|
||||||
if(!result.empty()) {
|
if(!conf->checkHeader(s, "boost/date_time/posix_time/posix_time.hpp")) {
|
||||||
name = result.first().mid(3);
|
return false;
|
||||||
// Remove .so
|
}
|
||||||
name.chop(3);
|
if(!conf->checkHeader(s, "boost/filesystem/path.hpp")) {
|
||||||
} else {
|
return false;
|
||||||
// Fall back to non -mt boost lib
|
}
|
||||||
filters.clear();
|
if(!conf->checkHeader(s, "boost/thread.hpp")) {
|
||||||
filters << "libboost_"+lib+"*.so";
|
return false;
|
||||||
result = libDir.entryList(filters, QDir::Files);
|
}
|
||||||
if(!result.empty()) {
|
}else{
|
||||||
name = result.first().mid(3);
|
QStringList sl;
|
||||||
// Remove .so
|
sl << "/usr/include";
|
||||||
name.chop(3);
|
sl << "/usr/local/include";
|
||||||
}
|
bool found = false;
|
||||||
}
|
foreach(s, sl){
|
||||||
return name;
|
if(conf->checkHeader(s, "boost/format.hpp")){
|
||||||
}
|
found = true;
|
||||||
|
break;
|
||||||
bool exec(){
|
}
|
||||||
QStringList sl;
|
}
|
||||||
QString s = conf->getenv("QC_WITH_LIBBOOST_INC");
|
if(!found) {
|
||||||
if (!s.isEmpty())
|
return false;
|
||||||
sl << s;
|
}
|
||||||
sl << "/usr/include";
|
if(!conf->checkHeader(s, "boost/date_time/posix_time/posix_time.hpp")) {
|
||||||
sl << "/usr/local/include";
|
return false;
|
||||||
bool found = false;
|
}
|
||||||
foreach (s, sl) {
|
if(!conf->checkHeader(s, "boost/filesystem/path.hpp")) {
|
||||||
if (conf->checkHeader(s, "boost/format.hpp")
|
return false;
|
||||||
#if LIBTORRENT_VERSION_MAJOR == 0 && LIBTORRENT_VERSION_MINOR < 16
|
}
|
||||||
&& conf->checkHeader(s, "boost/filesystem/path.hpp")
|
if(!conf->checkHeader(s, "boost/thread.hpp")) {
|
||||||
#endif
|
return false;
|
||||||
) {
|
}
|
||||||
found = true;
|
}
|
||||||
break;
|
conf->addIncludePath(s);
|
||||||
}
|
return true;
|
||||||
}
|
}
|
||||||
if (!found)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
conf->addIncludePath(s);
|
|
||||||
|
|
||||||
// Find library
|
|
||||||
s = conf->getenv("QC_WITH_LIBBOOST_LIB");
|
|
||||||
QStringList required_libs;
|
|
||||||
#if BOOST_VERSION >= 103500
|
|
||||||
required_libs << "system";
|
|
||||||
#endif
|
|
||||||
#if LIBTORRENT_VERSION_MAJOR == 0 && LIBTORRENT_VERSION_MINOR < 16
|
|
||||||
required_libs << "filesystem" ;
|
|
||||||
#endif
|
|
||||||
required_libs << "thread";
|
|
||||||
QStringList libDirs;
|
|
||||||
if (!s.isEmpty())
|
|
||||||
libDirs << s;
|
|
||||||
libDirs << "/usr/lib/" << "/usr/lib64/" << "/usr/local/lib/" << "/usr/local/lib64/";
|
|
||||||
|
|
||||||
foreach(const QString& lib, required_libs) {
|
|
||||||
bool found = false;
|
|
||||||
foreach(const QString& libDir, libDirs) {
|
|
||||||
QString detected_name = findBoostLib(libDir, lib);
|
|
||||||
if(!detected_name.isEmpty()) {
|
|
||||||
conf->addLib("-l"+detected_name);
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!found) {
|
|
||||||
printf("Could not find boost %s library!\n", qPrintable(lib));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|||||||
61
qcm/libcurl.qcm
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
-----BEGIN QCMOD-----
|
||||||
|
name: libcommoncpp2
|
||||||
|
arg: with-libcurl-inc=[path], Path to libcurl include files
|
||||||
|
arg: with-libcurl-lib=[path], Path to libcurl library files
|
||||||
|
-----END QCMOD-----
|
||||||
|
*/
|
||||||
|
class qc_libcurl : public ConfObj
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
qc_libcurl(Conf *c) : ConfObj(c) {}
|
||||||
|
QString name() const { return "libcurl"; }
|
||||||
|
QString shortname() const { return "libcurl"; }
|
||||||
|
bool exec(){
|
||||||
|
QString s;
|
||||||
|
s = conf->getenv("QC_WITH_LIBCURL_INC");
|
||||||
|
if(!s.isEmpty()) {
|
||||||
|
if(!conf->checkHeader(s, "curl/curl.h")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
QStringList sl;
|
||||||
|
sl << "/usr/include";
|
||||||
|
sl << "/usr/local/include";
|
||||||
|
bool found = false;
|
||||||
|
foreach(s, sl){
|
||||||
|
if(conf->checkHeader(s, "curl/curl.h")){
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!found) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
conf->addIncludePath(s);
|
||||||
|
|
||||||
|
s = conf->getenv("QC_WITH_LIBCURL_LIB");
|
||||||
|
if(!s.isEmpty()) {
|
||||||
|
if(!QFile::exists(s+QString("/libcurl.so")))
|
||||||
|
return false;
|
||||||
|
conf->addLib(QString("-L") + s);
|
||||||
|
}else{
|
||||||
|
QStringList sl;
|
||||||
|
sl << "/usr/lib/";
|
||||||
|
sl << "/usr/lib64/";
|
||||||
|
sl << "/usr/local/lib/";
|
||||||
|
sl << "/usr/local/lib64/";
|
||||||
|
bool found = false;
|
||||||
|
foreach(s, sl){
|
||||||
|
if(QFile::exists(s+QString("libcurl.so"))){
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!found) return false;
|
||||||
|
conf->addLib(QString("-L") + s);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
/*
|
|
||||||
-----BEGIN QCMOD-----
|
|
||||||
name: libnotify
|
|
||||||
-----END QCMOD-----
|
|
||||||
*/
|
|
||||||
// see Conf::findPkgConfig
|
|
||||||
class qc_libnotify : public ConfObj
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
qc_libnotify(Conf *c) : ConfObj(c) {}
|
|
||||||
QString name() const { return "libnotify >= 0.4.2 (optional)"; }
|
|
||||||
QString shortname() const { return "libnotify"; }
|
|
||||||
QString checkString() const {
|
|
||||||
if(!conf->getenv("QC_DISABLE_libnotify").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty())
|
|
||||||
return "";
|
|
||||||
return ConfObj::checkString();
|
|
||||||
}
|
|
||||||
bool exec(){
|
|
||||||
if(!conf->getenv("QC_DISABLE_libnotify").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
QStringList incs;
|
|
||||||
QString req_ver = "0.4.2";
|
|
||||||
QString version, libs, other;
|
|
||||||
VersionMode mode = VersionMin;
|
|
||||||
if(conf->findPkgConfig("libnotify", mode, req_ver, &version, &incs, &libs, &other)) {
|
|
||||||
conf->addExtra("CONFIG += libnotify");
|
|
||||||
for(int n = 0; n < incs.count(); ++n)
|
|
||||||
conf->addIncludePath(incs[n]);
|
|
||||||
if(!libs.isEmpty())
|
|
||||||
conf->addLib(libs);
|
|
||||||
QStringList incs2;
|
|
||||||
QString req_ver2 = "2.0";
|
|
||||||
QString version2, libs2, other2;
|
|
||||||
if(conf->findPkgConfig("glib-2.0", mode, req_ver2, &version2, &incs2, &libs2, &other2)) {
|
|
||||||
for(int n = 0; n < incs2.count(); ++n)
|
|
||||||
conf->addIncludePath(incs2[n]);
|
|
||||||
if(!libs2.isEmpty())
|
|
||||||
conf->addLib(libs2);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
QStringList incs3;
|
|
||||||
QString req_ver3 = "2.0";
|
|
||||||
QString version3, libs3, other3;
|
|
||||||
if(conf->findPkgConfig("gtk+-2.0", mode, req_ver3, &version3, &incs3, &libs3, &other3)) {
|
|
||||||
for(int n = 0; n < incs3.count(); ++n)
|
|
||||||
conf->addIncludePath(incs3[n]);
|
|
||||||
if(!libs3.isEmpty())
|
|
||||||
conf->addLib(libs3);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -8,17 +8,22 @@ class qc_libtorrent_rasterbar : public ConfObj
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {}
|
qc_libtorrent_rasterbar(Conf *c) : ConfObj(c) {}
|
||||||
QString name() const { return "libtorrent-rasterbar >= 0.15.0"; }
|
QString name() const { return "libtorrent-rasterbar >= 0.14.0 (>= 0.14.4 advised)"; }
|
||||||
QString shortname() const { return "libtorrent-rasterbar"; }
|
QString shortname() const { return "libtorrent-rasterbar"; }
|
||||||
bool exec(){
|
bool exec(){
|
||||||
QStringList incs;
|
QStringList incs;
|
||||||
QString req_ver = "0.15.0";
|
QString req_ver = "0.14.0";
|
||||||
|
QString adv_ver = "0.14.4";
|
||||||
QString version, libs, other;
|
QString version, libs, other;
|
||||||
VersionMode mode = VersionMin;
|
VersionMode mode = VersionMin;
|
||||||
if(!conf->findPkgConfig("libtorrent-rasterbar", mode, req_ver, &version, &incs, &libs, &other))
|
if(!conf->findPkgConfig("libtorrent-rasterbar", mode, req_ver, &version, &incs, &libs, &other))
|
||||||
return false;
|
return false;
|
||||||
for(int n = 0; n < incs.count(); ++n)
|
for(int n = 0; n < incs.count(); ++n)
|
||||||
conf->addIncludePath(incs[n]);
|
conf->addIncludePath(incs[n]);
|
||||||
|
if(!libs.isEmpty())
|
||||||
|
conf->addLib(libs);
|
||||||
|
if(!conf->findPkgConfig("libtorrent-rasterbar", mode, adv_ver, &version, &incs, &libs, &other))
|
||||||
|
printf("\nWarning: libtorrent-rasterbar v%s was detected. Although it will compile and run, you will probably experience some bugs. Please consider updating to v%s!\n", version.toLocal8Bit().data(), adv_ver.toUtf8().data());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
71
qcm/libzzip.qcm
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
-----BEGIN QCMOD-----
|
||||||
|
name: libzzip
|
||||||
|
arg: with-libzzip-inc=[path], Path to libzzip++ include files
|
||||||
|
arg: with-libzzip-lib=[path], Path to libzzip++ library files
|
||||||
|
-----END QCMOD-----
|
||||||
|
*/
|
||||||
|
#include <QProcess>
|
||||||
|
class qc_libzzip : public ConfObj
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
qc_libzzip(Conf *c) : ConfObj(c) {}
|
||||||
|
QString name() const { return "Zzip library (libzzip)"; }
|
||||||
|
QString shortname() const { return "libzzip"; }
|
||||||
|
QString checkString() const {
|
||||||
|
if(!conf->getenv("QC_DISABLE_LIBZZIP").isEmpty())
|
||||||
|
return "";
|
||||||
|
return ConfObj::checkString();
|
||||||
|
}
|
||||||
|
bool exec(){
|
||||||
|
if(!conf->getenv("QC_DISABLE_LIBZZIP").isEmpty())
|
||||||
|
return false;
|
||||||
|
QString s;
|
||||||
|
s = conf->getenv("QC_WITH_LIBZZIP_INC");
|
||||||
|
if(!s.isEmpty()) {
|
||||||
|
if(!conf->checkHeader(s, "zzip/zzip.h")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
QStringList sl;
|
||||||
|
sl << "/usr/include";
|
||||||
|
sl << "/usr/local/include";
|
||||||
|
bool found = false;
|
||||||
|
foreach(s, sl){
|
||||||
|
if(conf->checkHeader(s, "zzip/zzip.h")){
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!found)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
conf->addIncludePath(s);
|
||||||
|
|
||||||
|
s = conf->getenv("QC_WITH_LIBZZIP_LIB");
|
||||||
|
if(!s.isEmpty()) {
|
||||||
|
if(!QFile::exists(s+QString("/libzzip.so"))){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
QStringList sl;
|
||||||
|
sl << "/usr/lib/";
|
||||||
|
sl << "/usr/lib64/";
|
||||||
|
sl << "/usr/local/lib/";
|
||||||
|
sl << "/usr/local/lib64/";
|
||||||
|
bool found = false;
|
||||||
|
foreach(s, sl){
|
||||||
|
if(QFile::exists(s+QString("libzzip.so"))){
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!found)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
conf->addLib(QString("-L") + s);
|
||||||
|
conf->addLib("-lzzip");
|
||||||
|
conf->addDefine("HAVE_ZZIP");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
/*
|
|
||||||
-----BEGIN QCMOD-----
|
|
||||||
name: pkg-config
|
|
||||||
-----END QCMOD-----
|
|
||||||
*/
|
|
||||||
#include <QProcess>
|
|
||||||
class qc_pkg_config : public ConfObj
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
qc_pkg_config(Conf *c) : ConfObj(c) {}
|
|
||||||
QString name() const { return "pkg-config executable"; }
|
|
||||||
QString shortname() const { return "pkg-config"; }
|
|
||||||
bool exec(){
|
|
||||||
return !conf->findProgram("pkg-config").isEmpty();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
-----BEGIN QCMOD-----
|
|
||||||
name: qt-dbus
|
|
||||||
-----END QCMOD-----
|
|
||||||
*/
|
|
||||||
// see Conf::findPkgConfig
|
|
||||||
class qc_qt_dbus : public ConfObj
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
qc_qt_dbus(Conf *c) : ConfObj(c) {}
|
|
||||||
QString name() const { return "QtDBus >= 4.5"; }
|
|
||||||
QString shortname() const { return "qt-dbus"; }
|
|
||||||
QString checkString() const {
|
|
||||||
if(!conf->getenv("QC_DISABLE_qt_dbus").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty())
|
|
||||||
return "";
|
|
||||||
return ConfObj::checkString();
|
|
||||||
}
|
|
||||||
bool exec(){
|
|
||||||
if(!conf->getenv("QC_DISABLE_qt_dbus").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty())
|
|
||||||
return false;
|
|
||||||
QStringList incs;
|
|
||||||
QString req_ver = "4.5.0";
|
|
||||||
QString version, libs, other;
|
|
||||||
VersionMode mode = VersionMin;
|
|
||||||
if(conf->findPkgConfig("QtDBus", mode, req_ver, &version, &incs, &libs, &other)) {
|
|
||||||
conf->addExtra("CONFIG += dbus");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
-----BEGIN QCMOD-----
|
|
||||||
name: qt-svg
|
|
||||||
-----END QCMOD-----
|
|
||||||
*/
|
|
||||||
// see Conf::findPkgConfig
|
|
||||||
class qc_qt_svg : public ConfObj
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
qc_qt_svg(Conf *c) : ConfObj(c) {}
|
|
||||||
QString name() const { return "QtSvg >= 4.5"; }
|
|
||||||
QString shortname() const { return "qt-svg"; }
|
|
||||||
QString checkString() const {
|
|
||||||
if(!conf->getenv("QC_DISABLE_qt_svg").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty())
|
|
||||||
return "";
|
|
||||||
return ConfObj::checkString();
|
|
||||||
}
|
|
||||||
bool exec(){
|
|
||||||
if(!conf->getenv("QC_DISABLE_qt_svg").isEmpty() || !conf->getenv("QC_DISABLE_GUI").isEmpty())
|
|
||||||
return false;
|
|
||||||
QStringList incs;
|
|
||||||
QString req_ver = "4.5.0";
|
|
||||||
QString version, libs, other;
|
|
||||||
VersionMode mode = VersionMin;
|
|
||||||
if(conf->findPkgConfig("QtSvg", mode, req_ver, &version, &incs, &libs, &other)) {
|
|
||||||
conf->addExtra("CONFIG += svg");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
30
qcm/qt4.qcm
@@ -1,36 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
-----BEGIN QCMOD-----
|
-----BEGIN QCMOD-----
|
||||||
name: Qt >= 4.6
|
name: Qt >= 4.3
|
||||||
arg: enable-debug, Enable debug mode
|
|
||||||
arg: disable-gui, Disable qBittorrent Graphical user interface for headless running
|
|
||||||
-----END QCMOD-----
|
-----END QCMOD-----
|
||||||
*/
|
*/
|
||||||
class qc_qt4 : public ConfObj
|
class qc_qt4 : public ConfObj
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
qc_qt4(Conf *c) : ConfObj(c) {}
|
qc_qt4(Conf *c) : ConfObj(c) {}
|
||||||
QString name() const { return "Qt >= 4.6"; }
|
QString name() const { return "Qt >= 4.3"; }
|
||||||
QString shortname() const { return "Qt 4.6"; }
|
QString shortname() const { return "Qt 4.3"; }
|
||||||
bool exec()
|
bool exec()
|
||||||
{
|
{
|
||||||
// NOX mode
|
if(QT_VERSION >= 0x040400) {
|
||||||
if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) {
|
conf->addDefine("QT_4_4");
|
||||||
conf->addExtra("CONFIG += nox");
|
|
||||||
}
|
}
|
||||||
// Debug mode
|
return(QT_VERSION >= 0x040300);
|
||||||
if(!conf->getenv("QC_ENABLE_DEBUG").isEmpty()) {
|
|
||||||
conf->addExtra("CONFIG -= release");
|
|
||||||
conf->addExtra("CONFIG += debug");
|
|
||||||
} else {
|
|
||||||
conf->addExtra("CONFIG -= debug");
|
|
||||||
conf->addExtra("CONFIG += release");
|
|
||||||
}
|
|
||||||
#ifdef Q_OS_FREEBSD
|
|
||||||
conf->addLib("-lexecinfo");
|
|
||||||
conf->addExtra("MANPREFIX = $$PREFIX");
|
|
||||||
#else
|
|
||||||
conf->addExtra("MANPREFIX = $$PREFIX/share");
|
|
||||||
#endif
|
|
||||||
return(QT_VERSION >= 0x040600);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
-----BEGIN QCMOD-----
|
|
||||||
name: qtsingleapplication
|
|
||||||
arg: with-qtsingleapplication=[system|shipped], Use the shipped qtsingleapplication library or the system one
|
|
||||||
-----END QCMOD-----
|
|
||||||
*/
|
|
||||||
class qc_qtsingleapplication : public ConfObj
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
qc_qtsingleapplication(Conf *c) : ConfObj(c) {}
|
|
||||||
QString name() const { return "qtsingleapplication library"; }
|
|
||||||
QString shortname() const { return "qtsingleapplication"; }
|
|
||||||
|
|
||||||
bool exec(){
|
|
||||||
QString s;
|
|
||||||
s = conf->getenv("QC_WITH_QTSINGLEAPPLICATION");
|
|
||||||
if(s.compare("system", Qt::CaseInsensitive) == 0) {
|
|
||||||
// System
|
|
||||||
conf->addExtra("CONFIG += usesystemqtsingleapplication");
|
|
||||||
printf(" [system] ");
|
|
||||||
} else {
|
|
||||||
printf(" [shipped] ");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
116
src/DLListDelegate.h
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*
|
||||||
|
* Contact : chris@qbittorrent.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DLLISTDELEGATE_H
|
||||||
|
#define DLLISTDELEGATE_H
|
||||||
|
|
||||||
|
#include <QItemDelegate>
|
||||||
|
#include <QModelIndex>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QStyleOptionProgressBarV2>
|
||||||
|
#include <QStyleOptionViewItemV2>
|
||||||
|
#include <QProgressBar>
|
||||||
|
#include <QApplication>
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
// Defines for download list list columns
|
||||||
|
#define NAME 0
|
||||||
|
#define SIZE 1
|
||||||
|
#define PROGRESS 2
|
||||||
|
#define DLSPEED 3
|
||||||
|
#define UPSPEED 4
|
||||||
|
#define SEEDSLEECH 5
|
||||||
|
#define RATIO 6
|
||||||
|
#define ETA 7
|
||||||
|
#define PRIORITY 8
|
||||||
|
#define HASH 9
|
||||||
|
|
||||||
|
class DLListDelegate: public QItemDelegate {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
DLListDelegate(QObject *parent) : QItemDelegate(parent){}
|
||||||
|
|
||||||
|
~DLListDelegate(){}
|
||||||
|
|
||||||
|
void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const{
|
||||||
|
QStyleOptionViewItemV2 opt = QItemDelegate::setOptions(index, option);
|
||||||
|
switch(index.column()){
|
||||||
|
case SIZE:
|
||||||
|
QItemDelegate::drawBackground(painter, opt, index);
|
||||||
|
QItemDelegate::drawDisplay(painter, opt, option.rect, misc::friendlyUnit(index.data().toLongLong()));
|
||||||
|
break;
|
||||||
|
case ETA:
|
||||||
|
QItemDelegate::drawBackground(painter, opt, index);
|
||||||
|
QItemDelegate::drawDisplay(painter, opt, option.rect, misc::userFriendlyDuration(index.data().toLongLong()));
|
||||||
|
break;
|
||||||
|
case UPSPEED:
|
||||||
|
case DLSPEED:{
|
||||||
|
QItemDelegate::drawBackground(painter, opt, index);
|
||||||
|
double speed = index.data().toDouble();
|
||||||
|
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString(QByteArray::number(speed/1024., 'f', 1))+QString::fromUtf8(" ")+tr("KiB/s"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RATIO:{
|
||||||
|
QItemDelegate::drawBackground(painter, opt, index);
|
||||||
|
double ratio = index.data().toDouble();
|
||||||
|
if(ratio > 100.)
|
||||||
|
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::fromUtf8("∞"));
|
||||||
|
else
|
||||||
|
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString(QByteArray::number(ratio, 'f', 1)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 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:
|
||||||
|
QItemDelegate::paint(painter, option, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* createEditor(QWidget*, const QStyleOptionViewItem &, const QModelIndex &) const {
|
||||||
|
// No editor here
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
480
src/FeedDownloader.h
Normal file
@@ -0,0 +1,480 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*
|
||||||
|
* Contact : chris@qbittorrent.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FEEDDOWNLOADER_H
|
||||||
|
#define FEEDDOWNLOADER_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QListWidgetItem>
|
||||||
|
#include <QInputDialog>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QRegExp>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QDataStream>
|
||||||
|
#include <QFileDialog>
|
||||||
|
|
||||||
|
#include "bittorrent.h"
|
||||||
|
#include "ui_FeedDownloader.h"
|
||||||
|
|
||||||
|
class FeedFilter: public QHash<QString, QVariant> {
|
||||||
|
private:
|
||||||
|
bool valid;
|
||||||
|
public:
|
||||||
|
FeedFilter():valid(true) {}
|
||||||
|
FeedFilter(bool valid): valid(valid) {}
|
||||||
|
FeedFilter(QHash<QString, QVariant> filter): QHash<QString, QVariant>(filter), valid(true) {}
|
||||||
|
|
||||||
|
bool matches(QString s) {
|
||||||
|
QStringList match_tokens = getMatchingTokens();
|
||||||
|
foreach(const QString& token, match_tokens) {
|
||||||
|
if(token.isEmpty() || token == "")
|
||||||
|
continue;
|
||||||
|
QRegExp reg(token, Qt::CaseInsensitive);
|
||||||
|
if(reg.indexIn(s) < 0) return false;
|
||||||
|
}
|
||||||
|
// Checking not matching
|
||||||
|
QStringList notmatch_tokens = getNotMatchingTokens();
|
||||||
|
foreach(const QString& token, notmatch_tokens) {
|
||||||
|
if(token.isEmpty()) continue;
|
||||||
|
QRegExp reg(token, Qt::CaseInsensitive);
|
||||||
|
if(reg.indexIn(s) > -1) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isValid() const {
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList getMatchingTokens() const {
|
||||||
|
QString matches = this->value("matches", "").toString();
|
||||||
|
return matches.split(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString getMatchingTokens_str() const {
|
||||||
|
return this->value("matches", "").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMatchingTokens(QString tokens) {
|
||||||
|
tokens = tokens.trimmed();
|
||||||
|
if(tokens.isEmpty())
|
||||||
|
(*this)["matches"] = "";
|
||||||
|
else
|
||||||
|
(*this)["matches"] = tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList getNotMatchingTokens() const {
|
||||||
|
QString notmatching = this->value("not", "").toString();
|
||||||
|
return notmatching.split(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString getNotMatchingTokens_str() const {
|
||||||
|
return this->value("not", "").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setNotMatchingTokens(QString tokens) {
|
||||||
|
(*this)["not"] = tokens.trimmed();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString getSavePath() const {
|
||||||
|
return this->value("save_path", "").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSavePath(QString save_path) {
|
||||||
|
(*this)["save_path"] = save_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class FeedFilters : public QHash<QString, QVariant> {
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString feed_url;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FeedFilters() {}
|
||||||
|
FeedFilters(QString feed_url, QHash<QString, QVariant> filters): QHash<QString, QVariant>(filters), feed_url(feed_url) {}
|
||||||
|
|
||||||
|
bool hasFilter(QString name) const {
|
||||||
|
return this->contains(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
FeedFilter* matches(QString s) {
|
||||||
|
if(!isDownloadingEnabled()) return 0;
|
||||||
|
if(this->size() == 0) return new FeedFilter(false);
|
||||||
|
foreach(QVariant var_hash_filter, this->values()) {
|
||||||
|
QHash<QString, QVariant> hash_filter = var_hash_filter.toHash();
|
||||||
|
FeedFilter *filter = new FeedFilter(hash_filter);
|
||||||
|
if(filter->matches(s))
|
||||||
|
return filter;
|
||||||
|
else
|
||||||
|
delete filter;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList names() const {
|
||||||
|
return this->keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
FeedFilter getFilter(QString name) const {
|
||||||
|
if(this->contains(name))
|
||||||
|
return FeedFilter(this->value(name).toHash());
|
||||||
|
return FeedFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFilter(QString name, FeedFilter f) {
|
||||||
|
(*this)[name] = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isDownloadingEnabled() const {
|
||||||
|
QSettings qBTRSS("qBittorrent", "qBittorrent-rss");
|
||||||
|
QHash<QString, QVariant> feeds_w_downloader = qBTRSS.value("downloader_on", QHash<QString, QVariant>()).toHash();
|
||||||
|
return feeds_w_downloader.value(feed_url, false).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDownloadingEnabled(bool enabled) {
|
||||||
|
QSettings qBTRSS("qBittorrent", "qBittorrent-rss");
|
||||||
|
QHash<QString, QVariant> feeds_w_downloader = qBTRSS.value("downloader_on", QHash<QString, QVariant>()).toHash();
|
||||||
|
feeds_w_downloader[feed_url] = enabled;
|
||||||
|
qBTRSS.setValue("downloader_on", feeds_w_downloader);
|
||||||
|
}
|
||||||
|
|
||||||
|
static FeedFilters getFeedFilters(QString url) {
|
||||||
|
QSettings qBTRSS("qBittorrent", "qBittorrent-rss");
|
||||||
|
QHash<QString, QVariant> all_feeds_filters = qBTRSS.value("feed_filters", QHash<QString, QVariant>()).toHash();
|
||||||
|
return FeedFilters(url, all_feeds_filters.value(url, QHash<QString, QVariant>()).toHash());
|
||||||
|
}
|
||||||
|
|
||||||
|
void rename(QString old_name, QString new_name) {
|
||||||
|
Q_ASSERT(this->contains(old_name));
|
||||||
|
(*this)[new_name] = this->take(old_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool serialize(QString path) {
|
||||||
|
QFile f(path);
|
||||||
|
if(f.open(QIODevice::WriteOnly)) {
|
||||||
|
QDataStream out(&f);
|
||||||
|
out.setVersion(QDataStream::Qt_4_3);
|
||||||
|
out << (QHash<QString, QVariant>)(*this);
|
||||||
|
f.close();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool unserialize(QString path) {
|
||||||
|
QFile f(path);
|
||||||
|
if(f.open(QIODevice::ReadOnly)) {
|
||||||
|
QDataStream in(&f);
|
||||||
|
in.setVersion(QDataStream::Qt_4_3);
|
||||||
|
QHash<QString, QVariant> tmp;
|
||||||
|
in >> tmp;
|
||||||
|
qDebug("Unserialized %d filters", tmp.size());
|
||||||
|
foreach(const QString& key, tmp.keys()) {
|
||||||
|
(*this)[key] = tmp[key];
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void save() {
|
||||||
|
QSettings qBTRSS("qBittorrent", "qBittorrent-rss");
|
||||||
|
QHash<QString, QVariant> all_feeds_filters = qBTRSS.value("feed_filters", QHash<QString, QVariant>()).toHash();
|
||||||
|
qDebug("Saving filters for feed: %s (%d filters)", feed_url.toLocal8Bit().data(), (*this).size());
|
||||||
|
all_feeds_filters[feed_url] = *this;
|
||||||
|
qBTRSS.setValue("feed_filters", all_feeds_filters);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class FeedDownloaderDlg : public QDialog, private Ui_FeedDownloader{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString feed_url;
|
||||||
|
QString feed_name;
|
||||||
|
FeedFilters filters;
|
||||||
|
bittorrent *BTSession;
|
||||||
|
QString selected_filter; // name
|
||||||
|
|
||||||
|
public:
|
||||||
|
FeedDownloaderDlg(QWidget *parent, QString feed_url, QString feed_name, bittorrent* BTSession): QDialog(parent), feed_url(feed_url), feed_name(feed_name), BTSession(BTSession), selected_filter(QString::null){
|
||||||
|
setupUi(this);
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
Q_ASSERT(!feed_name.isEmpty());
|
||||||
|
rssfeed_lbl->setText(feed_name);
|
||||||
|
filters = FeedFilters::getFeedFilters(feed_url);
|
||||||
|
// Connect Signals/Slots
|
||||||
|
connect(filtersList, SIGNAL(currentItemChanged(QListWidgetItem* , QListWidgetItem *)), this, SLOT(showFilterSettings(QListWidgetItem *)));
|
||||||
|
connect(filtersList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFiltersListMenu(const QPoint&)));
|
||||||
|
connect(actionAdd_filter, SIGNAL(triggered()), this, SLOT(addFilter()));
|
||||||
|
connect(actionRemove_filter, SIGNAL(triggered()), this, SLOT(deleteFilter()));
|
||||||
|
connect(actionRename_filter, SIGNAL(triggered()), this, SLOT(renameFilter()));
|
||||||
|
connect(del_button, SIGNAL(clicked(bool)), this, SLOT(deleteFilter()));
|
||||||
|
connect(add_button, SIGNAL(clicked(bool)), this, SLOT(addFilter()));
|
||||||
|
connect(enableDl_cb, SIGNAL(stateChanged(int)), this, SLOT(enableFilterBox(int)));
|
||||||
|
// Restore saved info
|
||||||
|
enableDl_cb->setChecked(filters.isDownloadingEnabled());
|
||||||
|
fillFiltersList();
|
||||||
|
if(filters.size() > 0) {
|
||||||
|
// Select first filter
|
||||||
|
filtersList->setCurrentItem(filtersList->item(0));
|
||||||
|
//showFilterSettings(filtersList->item(0));
|
||||||
|
}
|
||||||
|
// Show
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
|
~FeedDownloaderDlg() {
|
||||||
|
// Make sure we save everything
|
||||||
|
saveCurrentFilterSettings();
|
||||||
|
filters.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void saveCurrentFilterSettings() {
|
||||||
|
if(!selected_filter.isEmpty()) {
|
||||||
|
FeedFilter filter = filters.getFilter(selected_filter);
|
||||||
|
filter.setMatchingTokens(match_line->text());
|
||||||
|
filter.setNotMatchingTokens(notmatch_line->text());
|
||||||
|
QString save_path = savepath_line->text().trimmed();
|
||||||
|
if(save_path.isEmpty())
|
||||||
|
save_path = BTSession->getDefaultSavePath();
|
||||||
|
filter.setSavePath(save_path);
|
||||||
|
// Save updated filter
|
||||||
|
filters.setFilter(selected_filter, filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fillFiltersList() {
|
||||||
|
// Fill filter list
|
||||||
|
foreach(QString filter_name, filters.names()) {
|
||||||
|
new QListWidgetItem(filter_name, filtersList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayFiltersListMenu(const QPoint&) {
|
||||||
|
QMenu myFiltersListMenu(this);
|
||||||
|
if(filtersList->selectedItems().size() > 0) {
|
||||||
|
myFiltersListMenu.addAction(actionRename_filter);
|
||||||
|
myFiltersListMenu.addAction(actionRemove_filter);
|
||||||
|
} else {
|
||||||
|
myFiltersListMenu.addAction(actionAdd_filter);
|
||||||
|
}
|
||||||
|
// Call menu
|
||||||
|
myFiltersListMenu.exec(QCursor::pos());
|
||||||
|
}
|
||||||
|
|
||||||
|
void showFilterSettings(QListWidgetItem *item) {
|
||||||
|
// First, save current filter settings
|
||||||
|
saveCurrentFilterSettings();
|
||||||
|
// Clear all fields
|
||||||
|
clearFields();
|
||||||
|
if(!item) {
|
||||||
|
qDebug("No new selected item");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Actually show filter settings
|
||||||
|
QString filter_name = item->text();
|
||||||
|
FeedFilter filter = filters.getFilter(filter_name);
|
||||||
|
filterSettingsBox->setEnabled(true);
|
||||||
|
match_line->setText(filter.getMatchingTokens_str());
|
||||||
|
if(match_line->text().trimmed().isEmpty()) {
|
||||||
|
match_line->setText(filter_name);
|
||||||
|
}
|
||||||
|
notmatch_line->setText(filter.getNotMatchingTokens_str());
|
||||||
|
QString save_path = filter.getSavePath();
|
||||||
|
if(save_path.isEmpty())
|
||||||
|
save_path = BTSession->getDefaultSavePath();
|
||||||
|
savepath_line->setText(save_path);
|
||||||
|
// Update selected filter
|
||||||
|
selected_filter = filter_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteFilter() {
|
||||||
|
QList<QListWidgetItem *> items = filtersList->selectedItems();
|
||||||
|
if(items.size() == 1) {
|
||||||
|
QListWidgetItem * item = items.first();
|
||||||
|
filters.remove(item->text());
|
||||||
|
selected_filter = QString::null;
|
||||||
|
delete item;
|
||||||
|
// Reset Filter settings view
|
||||||
|
if(filters.size() == 0) {
|
||||||
|
clearFields();
|
||||||
|
filterSettingsBox->setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void renameFilter() {
|
||||||
|
QList<QListWidgetItem *> items = filtersList->selectedItems();
|
||||||
|
if(items.size() == 1) {
|
||||||
|
QListWidgetItem *item = items.first();
|
||||||
|
QString current_name = item->text();
|
||||||
|
QString new_name;
|
||||||
|
bool validated = false;
|
||||||
|
do {
|
||||||
|
new_name = askFilterName(current_name);
|
||||||
|
if(new_name.isNull() || new_name == current_name) return;
|
||||||
|
if(!filters.hasFilter(new_name)) {
|
||||||
|
validated = true;
|
||||||
|
} else {
|
||||||
|
QMessageBox::warning(0, tr("Invalid filter name"), tr("This filter name is already in use."));
|
||||||
|
}
|
||||||
|
}while(!validated);
|
||||||
|
// Rename the filter
|
||||||
|
filters.rename(current_name, new_name);
|
||||||
|
if(selected_filter == current_name)
|
||||||
|
selected_filter = new_name;
|
||||||
|
item->setText(new_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void enableFilterBox(int state) {
|
||||||
|
if(state == Qt::Checked) {
|
||||||
|
filtersBox->setEnabled(true);
|
||||||
|
filters.setDownloadingEnabled(true);
|
||||||
|
} else {
|
||||||
|
filtersBox->setEnabled(false);
|
||||||
|
filters.setDownloadingEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString askFilterName(QString name=QString::null) {
|
||||||
|
QString name_prop;
|
||||||
|
if(name.isEmpty())
|
||||||
|
name_prop = tr("New filter");
|
||||||
|
else
|
||||||
|
name_prop = name;
|
||||||
|
QString new_name;
|
||||||
|
bool validated = false;
|
||||||
|
do {
|
||||||
|
bool ok;
|
||||||
|
new_name = QInputDialog::getText(this, tr("Please choose a name for this filter"), tr("Filter name:"), QLineEdit::Normal, name_prop, &ok);
|
||||||
|
if(!ok) {
|
||||||
|
return QString::null;
|
||||||
|
}
|
||||||
|
// Validate filter name
|
||||||
|
new_name = new_name.trimmed();
|
||||||
|
if(new_name.isEmpty()) {
|
||||||
|
// Cannot be left empty
|
||||||
|
QMessageBox::warning(0, tr("Invalid filter name"), tr("The filter name cannot be left empty."));
|
||||||
|
} else {
|
||||||
|
validated = true;
|
||||||
|
}
|
||||||
|
} while(!validated);
|
||||||
|
return new_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addFilter() {
|
||||||
|
QString filter_name = QString::null;
|
||||||
|
bool validated = false;
|
||||||
|
do {
|
||||||
|
filter_name = askFilterName();
|
||||||
|
if(filter_name.isNull()) return;
|
||||||
|
if(filters.hasFilter(filter_name)) {
|
||||||
|
// Filter alread exists
|
||||||
|
QMessageBox::warning(0, tr("Invalid filter name"), tr("This filter name is already in use."));
|
||||||
|
} else {
|
||||||
|
validated = true;
|
||||||
|
}
|
||||||
|
}while(!validated);
|
||||||
|
QListWidgetItem *it = new QListWidgetItem(filter_name, filtersList);
|
||||||
|
filtersList->setCurrentItem(it);
|
||||||
|
//showFilterSettings(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearFields() {
|
||||||
|
match_line->clear();
|
||||||
|
notmatch_line->clear();
|
||||||
|
savepath_line->clear();
|
||||||
|
test_res_lbl->setText("");
|
||||||
|
test_line->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_testButton_clicked(bool) {
|
||||||
|
if(selected_filter.isEmpty()) return;
|
||||||
|
QString s = test_line->text().trimmed();
|
||||||
|
if(s.isEmpty()) {
|
||||||
|
QMessageBox::warning(0, tr("Filter testing error"), tr("Please specify a test torrent name."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Get current filter
|
||||||
|
saveCurrentFilterSettings();
|
||||||
|
FeedFilter f = filters.getFilter(selected_filter);
|
||||||
|
if(f.matches(s))
|
||||||
|
test_res_lbl->setText("<b><font color=\"green\">"+tr("matches")+"</font></b>");
|
||||||
|
else
|
||||||
|
test_res_lbl->setText("<b><font color=\"red\">"+tr("does not match")+"</font></b>");
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_importButton_clicked(bool) {
|
||||||
|
QString source = QFileDialog::getOpenFileName(0, tr("Select file to import"), QDir::homePath(), tr("Filters Files")+QString::fromUtf8(" (*.filters)"));
|
||||||
|
if(source.isEmpty()) return;
|
||||||
|
if(filters.unserialize(source)) {
|
||||||
|
// Clean up first
|
||||||
|
clearFields();
|
||||||
|
filtersList->clear();
|
||||||
|
selected_filter = QString::null;
|
||||||
|
fillFiltersList();
|
||||||
|
if(filters.size() > 0)
|
||||||
|
filtersList->setCurrentItem(filtersList->item(0));
|
||||||
|
QMessageBox::information(0, tr("Import successful"), tr("Filters import was successful."));
|
||||||
|
} else {
|
||||||
|
QMessageBox::warning(0, tr("Import failure"), tr("Filters could not be imported due to an I/O error."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_exportButton_clicked(bool) {
|
||||||
|
QString destination = QFileDialog::getSaveFileName(this, tr("Select destination file"), QDir::homePath(), tr("Filters Files")+QString::fromUtf8(" (*.filters)"));
|
||||||
|
if(destination.isEmpty()) return;
|
||||||
|
// Append file extension
|
||||||
|
if(!destination.endsWith(".filters"))
|
||||||
|
destination += ".filters";
|
||||||
|
if(QFile::exists(destination)) {
|
||||||
|
int ret = QMessageBox::question(0, tr("Overwriting confirmation"), tr("Are you sure you want to overwrite existing file?"), QMessageBox::Yes|QMessageBox::No);
|
||||||
|
if(ret != QMessageBox::Yes) return;
|
||||||
|
}
|
||||||
|
if(filters.serialize(destination))
|
||||||
|
QMessageBox::information(0, tr("Export successful"), tr("Filters export was successful."));
|
||||||
|
else
|
||||||
|
QMessageBox::warning(0, tr("Export failure"), tr("Filters could not be exported due to an I/O error."));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FEEDDOWNLOADER_H
|
||||||
546
src/FeedDownloader.ui
Normal file
@@ -0,0 +1,546 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>FeedDownloader</class>
|
||||||
|
<widget class="QDialog" name="FeedDownloader">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>737</width>
|
||||||
|
<height>415</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>RSS Feed downloader</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>16</pointsize>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>RSS feed:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="rssfeed_lbl">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>16</pointsize>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Feed name</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_5">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="enableDl_cb">
|
||||||
|
<property name="text">
|
||||||
|
<string>Automatically download torrents from this feed</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="filtersBox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Download filters</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Filters:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QListWidget" name="filtersList">
|
||||||
|
<property name="contextMenuPolicy">
|
||||||
|
<enum>Qt::CustomContextMenu</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="del_button">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="icons.qrc">
|
||||||
|
<normaloff>:/Icons/oxygen/list-remove.png</normaloff>:/Icons/oxygen/list-remove.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Fixed</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>10</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="add_button">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="icons.qrc">
|
||||||
|
<normaloff>:/Icons/oxygen/list-add.png</normaloff>:/Icons/oxygen/list-add.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="filterSettingsBox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Filter settings</string>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>50</weight>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Matches:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>50</weight>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Does not match:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>50</weight>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Destination folder:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="match_line">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="notmatch_line"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="savepath_line">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>300</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="browse_button">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>50</weight>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="testerBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Filter testing</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>28</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>50</weight>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Torrent title:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>50</weight>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Result:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="test_line"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="testButton">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>50</weight>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Test</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="test_res_lbl">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>50</weight>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string> </string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_6">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>9</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="importButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Import...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="exportButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Export...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Close</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
<action name="actionRename_filter">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="icons.qrc">
|
||||||
|
<normaloff>:/Icons/oxygen/edit_clear.png</normaloff>:/Icons/oxygen/edit_clear.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Rename filter</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Rename filter</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionRemove_filter">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="icons.qrc">
|
||||||
|
<normaloff>:/Icons/oxygen/list-remove.png</normaloff>:/Icons/oxygen/list-remove.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Remove filter</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Remove filter</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionAdd_filter">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="icons.qrc">
|
||||||
|
<normaloff>:/Icons/oxygen/list-add.png</normaloff>:/Icons/oxygen/list-add.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Add filter</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="icons.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>FeedDownloader</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>FeedDownloader</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
||||||
98
src/FinishedListDelegate.h
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*
|
||||||
|
* Contact : chris@qbittorrent.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FINISHEDLISTDELEGATE_H
|
||||||
|
#define FINISHEDLISTDELEGATE_H
|
||||||
|
|
||||||
|
#include <QItemDelegate>
|
||||||
|
#include <QModelIndex>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QStyleOptionProgressBarV2>
|
||||||
|
#include <QStyleOptionViewItemV2>
|
||||||
|
#include <QProgressBar>
|
||||||
|
#include <QApplication>
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
// Defines for download list list columns
|
||||||
|
#define F_NAME 0
|
||||||
|
#define F_SIZE 1
|
||||||
|
#define F_UPSPEED 2
|
||||||
|
#define F_SWARM 3
|
||||||
|
#define F_PEERS 4
|
||||||
|
#define F_UPLOAD 5
|
||||||
|
#define F_RATIO 6
|
||||||
|
#define F_HASH 7
|
||||||
|
|
||||||
|
#define MAX_RATIO 100.
|
||||||
|
|
||||||
|
class FinishedListDelegate: public QItemDelegate {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
FinishedListDelegate(QObject *parent) : QItemDelegate(parent){}
|
||||||
|
|
||||||
|
~FinishedListDelegate(){}
|
||||||
|
|
||||||
|
void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const{
|
||||||
|
QStyleOptionViewItemV2 opt = QItemDelegate::setOptions(index, option);
|
||||||
|
switch(index.column()){
|
||||||
|
case F_SIZE:
|
||||||
|
case F_UPLOAD:
|
||||||
|
QItemDelegate::drawBackground(painter, opt, index);
|
||||||
|
QItemDelegate::drawDisplay(painter, opt, option.rect, misc::friendlyUnit(index.data().toLongLong()));
|
||||||
|
break;
|
||||||
|
case F_UPSPEED:{
|
||||||
|
QItemDelegate::drawBackground(painter, opt, index);
|
||||||
|
double speed = index.data().toDouble();
|
||||||
|
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString(QByteArray::number(speed/1024., 'f', 1))+QString::fromUtf8(" ")+tr("KiB/s"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case F_RATIO:{
|
||||||
|
QItemDelegate::drawBackground(painter, opt, index);
|
||||||
|
double ratio = index.data().toDouble();
|
||||||
|
if(ratio > MAX_RATIO)
|
||||||
|
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString::fromUtf8("∞"));
|
||||||
|
else
|
||||||
|
QItemDelegate::drawDisplay(painter, opt, opt.rect, QString(QByteArray::number(ratio, 'f', 1)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
QItemDelegate::paint(painter, option, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* createEditor(QWidget*, const QStyleOptionViewItem &, const QModelIndex &) const {
|
||||||
|
// No editor here
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
640
src/FinishedTorrents.cpp
Normal file
@@ -0,0 +1,640 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*
|
||||||
|
* Contact : chris@qbittorrent.org
|
||||||
|
*/
|
||||||
|
#include "FinishedTorrents.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "properties_imp.h"
|
||||||
|
#include "bittorrent.h"
|
||||||
|
#include "allocationDlg.h"
|
||||||
|
#include "FinishedListDelegate.h"
|
||||||
|
#include "GUI.h"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
FinishedTorrents::FinishedTorrents(QObject *parent, bittorrent *BTSession) : parent(parent), BTSession(BTSession), nbFinished(0){
|
||||||
|
setupUi(this);
|
||||||
|
actionStart->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/play.png")));
|
||||||
|
actionPause->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/pause.png")));
|
||||||
|
finishedListModel = new QStandardItemModel(0,8);
|
||||||
|
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_UPSPEED, Qt::Horizontal, tr("UP Speed", "i.e: Upload speed"));
|
||||||
|
finishedListModel->setHeaderData(F_SWARM, Qt::Horizontal, tr("Seeds / Leechers"));
|
||||||
|
finishedListModel->setHeaderData(F_PEERS, Qt::Horizontal, tr("Connected peers"));
|
||||||
|
finishedListModel->setHeaderData(F_UPLOAD, Qt::Horizontal, tr("Total uploaded", "i.e: Total amount of uploaded data"));
|
||||||
|
finishedListModel->setHeaderData(F_RATIO, Qt::Horizontal, tr("Ratio"));
|
||||||
|
|
||||||
|
proxyModel = new QSortFilterProxyModel();
|
||||||
|
proxyModel->setDynamicSortFilter(true);
|
||||||
|
proxyModel->setSourceModel(finishedListModel);
|
||||||
|
finishedList->setModel(proxyModel);
|
||||||
|
|
||||||
|
finishedList->setRootIsDecorated(false);
|
||||||
|
finishedList->setAllColumnsShowFocus(true);
|
||||||
|
finishedList->setSortingEnabled(true);
|
||||||
|
|
||||||
|
loadHiddenColumns();
|
||||||
|
// Hide hash column
|
||||||
|
finishedList->hideColumn(F_HASH);
|
||||||
|
// Load last columns width for download list
|
||||||
|
if(!loadColWidthFinishedList()){
|
||||||
|
finishedList->header()->resizeSection(0, 200);
|
||||||
|
}
|
||||||
|
// Connect BTSession signals
|
||||||
|
connect(BTSession, SIGNAL(metadataReceived(QTorrentHandle&)), this, SLOT(updateMetadata(QTorrentHandle&)));
|
||||||
|
// Make download list header clickable for sorting
|
||||||
|
finishedList->header()->setClickable(true);
|
||||||
|
finishedList->header()->setSortIndicatorShown(true);
|
||||||
|
finishedListDelegate = new FinishedListDelegate(finishedList);
|
||||||
|
finishedList->setItemDelegate(finishedListDelegate);
|
||||||
|
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&)));
|
||||||
|
actionDelete->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete.png")));
|
||||||
|
actionPreview_file->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/preview.png")));
|
||||||
|
actionDelete_Permanently->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/delete_perm.png")));
|
||||||
|
actionTorrent_Properties->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/properties.png")));
|
||||||
|
actionSet_upload_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png")));
|
||||||
|
actionCopy_magnet_link->setIcon(QIcon(QString::fromUtf8(":/Icons/magnet.png")));
|
||||||
|
|
||||||
|
connect(actionPause, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionPause_triggered()));
|
||||||
|
connect(actionStart, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionStart_triggered()));
|
||||||
|
connect(actionDelete, SIGNAL(triggered()), (GUI*)parent, SLOT(on_actionDelete_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(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(actionForce_recheck, SIGNAL(triggered()), this, SLOT(forceRecheck()));
|
||||||
|
connect(actionCopy_magnet_link, SIGNAL(triggered()), (GUI*)parent, SLOT(copyMagnetURI()));
|
||||||
|
|
||||||
|
connect(actionHOSColName, SIGNAL(triggered()), this, SLOT(hideOrShowColumnName()));
|
||||||
|
connect(actionHOSColSize, SIGNAL(triggered()), this, SLOT(hideOrShowColumnSize()));
|
||||||
|
connect(actionHOSColUpSpeed, SIGNAL(triggered()), this, SLOT(hideOrShowColumnUpSpeed()));
|
||||||
|
connect(actionHOSColSwarm, SIGNAL(triggered()), this, SLOT(hideOrShowColumnSwarm()));
|
||||||
|
connect(actionHOSColPeers, SIGNAL(triggered()), this, SLOT(hideOrShowColumnPeers()));
|
||||||
|
connect(actionHOSColUpload, SIGNAL(triggered()), this, SLOT(hideOrShowColumnUpload()));
|
||||||
|
connect(actionHOSColRatio, SIGNAL(triggered()), this, SLOT(hideOrShowColumnRatio()));
|
||||||
|
}
|
||||||
|
|
||||||
|
FinishedTorrents::~FinishedTorrents(){
|
||||||
|
saveLastSortedColumn();
|
||||||
|
saveColWidthFinishedList();
|
||||||
|
saveHiddenColumns();
|
||||||
|
delete finishedListDelegate;
|
||||||
|
delete proxyModel;
|
||||||
|
delete finishedListModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FinishedTorrents::notifyTorrentDoubleClicked(const QModelIndex& index) {
|
||||||
|
unsigned int row = index.row();
|
||||||
|
QString hash = getHashFromRow(row);
|
||||||
|
emit torrentDoubleClicked(hash, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FinishedTorrents::addTorrent(QString hash){
|
||||||
|
int row = getRowFromHash(hash);
|
||||||
|
if(row != -1) return;
|
||||||
|
row = finishedListModel->rowCount();
|
||||||
|
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
||||||
|
// Adding torrent to download list
|
||||||
|
finishedListModel->insertRow(row);
|
||||||
|
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_UPSPEED), QVariant((double)0.));
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_SWARM), QVariant("-1/-1"));
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_PEERS), QVariant("0"));
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_UPLOAD), QVariant((qlonglong)h.all_time_upload()));
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_RATIO), QVariant(QString::fromUtf8(misc::toString(BTSession->getRealRatio(hash)).c_str())));
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_HASH), QVariant(hash));
|
||||||
|
if(h.is_paused()) {
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_NAME), QIcon(":/Icons/skin/paused.png"), Qt::DecorationRole);
|
||||||
|
setRowColor(row, "red");
|
||||||
|
}else{
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(":/Icons/skin/seeding.png")), Qt::DecorationRole);
|
||||||
|
setRowColor(row, "orange");
|
||||||
|
}
|
||||||
|
// Update the number of finished torrents
|
||||||
|
++nbFinished;
|
||||||
|
emit finishedTorrentsNumberChanged(nbFinished);
|
||||||
|
|
||||||
|
loadLastSortedColumn();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the color of a row in data model
|
||||||
|
void FinishedTorrents::setRowColor(int row, QString color){
|
||||||
|
unsigned int nbColumns = finishedListModel->columnCount()-1;
|
||||||
|
for(unsigned int i=0; i<nbColumns; ++i){
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, i), QVariant(QColor(color)), Qt::ForegroundRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList FinishedTorrents::getSelectedTorrents(bool only_one) const{
|
||||||
|
QStringList res;
|
||||||
|
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
|
||||||
|
foreach(const QModelIndex &index, selectedIndexes) {
|
||||||
|
if(index.column() == F_NAME) {
|
||||||
|
// Get the file hash
|
||||||
|
QString hash = getHashFromRow(index.row());
|
||||||
|
res << hash;
|
||||||
|
if(only_one) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int FinishedTorrents::getNbTorrentsInList() const {
|
||||||
|
return nbFinished;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load columns width in a file that were saved previously
|
||||||
|
// (finished list)
|
||||||
|
bool FinishedTorrents::loadColWidthFinishedList(){
|
||||||
|
qDebug("Loading columns width for finished list");
|
||||||
|
QSettings settings("qBittorrent", "qBittorrent");
|
||||||
|
QString line = settings.value("FinishedListColsWidth", QString()).toString();
|
||||||
|
if(line.isEmpty())
|
||||||
|
return false;
|
||||||
|
QStringList width_list = line.split(' ');
|
||||||
|
if(width_list.size() < finishedListModel->columnCount()-1)
|
||||||
|
return false;
|
||||||
|
unsigned int listSize = width_list.size();
|
||||||
|
for(unsigned int i=0; i<listSize; ++i){
|
||||||
|
finishedList->header()->resizeSection(i, width_list.at(i).toInt());
|
||||||
|
}
|
||||||
|
loadLastSortedColumn();
|
||||||
|
QVariantList visualIndexes = settings.value(QString::fromUtf8("FinishedListVisualIndexes"), QVariantList()).toList();
|
||||||
|
if(visualIndexes.size() != finishedListModel->columnCount()-1) {
|
||||||
|
qDebug("Corrupted values for download list columns sizes");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool change = false;
|
||||||
|
do {
|
||||||
|
change = false;
|
||||||
|
for(int i=0;i<visualIndexes.size(); ++i) {
|
||||||
|
int new_visual_index = visualIndexes.at(finishedList->header()->logicalIndex(i)).toInt();
|
||||||
|
if(i != new_visual_index) {
|
||||||
|
qDebug("Moving column from %d to %d", finishedList->header()->logicalIndex(i), new_visual_index);
|
||||||
|
finishedList->header()->moveSection(i, new_visual_index);
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}while(change);
|
||||||
|
qDebug("Finished list columns width loaded");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FinishedTorrents::saveLastSortedColumn() {
|
||||||
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||||
|
Qt::SortOrder sortOrder = finishedList->header()->sortIndicatorOrder();
|
||||||
|
QString sortOrderLetter;
|
||||||
|
if(sortOrder == Qt::AscendingOrder)
|
||||||
|
sortOrderLetter = QString::fromUtf8("a");
|
||||||
|
else
|
||||||
|
sortOrderLetter = QString::fromUtf8("d");
|
||||||
|
int index = finishedList->header()->sortIndicatorSection();
|
||||||
|
settings.setValue(QString::fromUtf8("FinishedListSortedCol"), misc::toQString(index)+sortOrderLetter);
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
finishedList->sortByColumn(index, sortOrder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save columns width in a file to remember them
|
||||||
|
// (finished list)
|
||||||
|
void FinishedTorrents::saveColWidthFinishedList() const{
|
||||||
|
qDebug("Saving columns width in finished list");
|
||||||
|
QSettings settings("qBittorrent", "qBittorrent");
|
||||||
|
QStringList width_list;
|
||||||
|
QStringList new_width_list;
|
||||||
|
short nbColumns = finishedListModel->columnCount()-1;
|
||||||
|
|
||||||
|
QString line = settings.value("FinishedListColsWidth", QString()).toString();
|
||||||
|
if(!line.isEmpty()) {
|
||||||
|
width_list = line.split(' ');
|
||||||
|
}
|
||||||
|
for(short i=0; i<nbColumns; ++i){
|
||||||
|
if(finishedList->columnWidth(i)<1 && width_list.size() == nbColumns && 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(" "));
|
||||||
|
QVariantList visualIndexes;
|
||||||
|
for(int i=0; i<nbColumns; ++i) {
|
||||||
|
visualIndexes.append(finishedList->header()->visualIndex(i));
|
||||||
|
}
|
||||||
|
settings.setValue(QString::fromUtf8("FinishedListVisualIndexes"), visualIndexes);
|
||||||
|
qDebug("Finished list columns width saved");
|
||||||
|
}
|
||||||
|
|
||||||
|
void FinishedTorrents::on_actionSet_upload_limit_triggered(){
|
||||||
|
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
|
||||||
|
QStringList hashes;
|
||||||
|
foreach(const QModelIndex &index, selectedIndexes){
|
||||||
|
if(index.column() == F_NAME){
|
||||||
|
// Get the file hash
|
||||||
|
hashes << getHashFromRow(index.row());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new BandwidthAllocationDialog(this, true, BTSession, hashes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FinishedTorrents::updateMetadata(QTorrentHandle &h) {
|
||||||
|
QString hash = h.hash();
|
||||||
|
int row = getRowFromHash(hash);
|
||||||
|
if(row != -1) {
|
||||||
|
qDebug("Updating torrent metadata in download list");
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(h.name()));
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_SIZE), QVariant((qlonglong)h.actual_size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FinishedTorrents::updateTorrent(QTorrentHandle h) {
|
||||||
|
if(!h.is_valid()) return;
|
||||||
|
QString hash = h.hash();
|
||||||
|
int row = getRowFromHash(hash);
|
||||||
|
if(row == -1){
|
||||||
|
qDebug("Cannot find torrent in finished list, adding it");
|
||||||
|
addTorrent(hash);
|
||||||
|
row = getRowFromHash(hash);
|
||||||
|
}
|
||||||
|
Q_ASSERT(row != -1);
|
||||||
|
if(!finishedList->isColumnHidden(F_SWARM)) {
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_SWARM), misc::toQString(h.num_complete())+QString("/")+misc::toQString(h.num_incomplete()));
|
||||||
|
}
|
||||||
|
if(h.is_paused()) return;
|
||||||
|
// Update queued torrent
|
||||||
|
if(BTSession->isQueueingEnabled() && h.is_queued()) {
|
||||||
|
if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking){
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/oxygen/time.png"))), Qt::DecorationRole);
|
||||||
|
} else {
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/skin/queued.png"))), Qt::DecorationRole);
|
||||||
|
}
|
||||||
|
// Reset upload speed and seeds/leech
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_UPSPEED), 0.);
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_PEERS), "0");
|
||||||
|
setRowColor(row, QString::fromUtf8("grey"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(h.state() == torrent_status::checking_files || h.state() == torrent_status::queued_for_checking){
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_NAME), QVariant(QIcon(QString::fromUtf8(":/Icons/oxygen/time.png"))), Qt::DecorationRole);
|
||||||
|
setRowColor(row, QString::fromUtf8("grey"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setRowColor(row, QString::fromUtf8("orange"));
|
||||||
|
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()));
|
||||||
|
}
|
||||||
|
if(!finishedList->isColumnHidden(F_PEERS)) {
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_PEERS), misc::toQString(h.num_peers() - h.num_seeds(), true));
|
||||||
|
}
|
||||||
|
if(!finishedList->isColumnHidden(F_UPLOAD)) {
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_UPLOAD), QVariant((double)h.all_time_upload()));
|
||||||
|
}
|
||||||
|
if(!finishedList->isColumnHidden(F_RATIO)) {
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_RATIO), QVariant(misc::toQString(BTSession->getRealRatio(hash))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int FinishedTorrents::getRowFromHash(QString hash) const{
|
||||||
|
unsigned int nbRows = finishedListModel->rowCount();
|
||||||
|
for(unsigned int i=0; i<nbRows; ++i){
|
||||||
|
if(finishedListModel->data(finishedListModel->index(i, F_HASH)) == hash){
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: does not actually pause the torrent in BT Session
|
||||||
|
void FinishedTorrents::pauseTorrent(QString hash) {
|
||||||
|
int row = getRowFromHash(hash);
|
||||||
|
if(row == -1)
|
||||||
|
return;
|
||||||
|
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_PEERS), QVariant(QString::fromUtf8("0")));
|
||||||
|
setRowColor(row, QString::fromUtf8("red"));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FinishedTorrents::getHashFromRow(unsigned int row) const {
|
||||||
|
Q_ASSERT(row < (unsigned int)proxyModel->rowCount());
|
||||||
|
return proxyModel->data(proxyModel->index(row, F_HASH)).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Will move it to download tab
|
||||||
|
void FinishedTorrents::deleteTorrent(QString hash){
|
||||||
|
int row = getRowFromHash(hash);
|
||||||
|
if(row == -1){
|
||||||
|
qDebug("Torrent is not in finished list, nothing to delete");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Select item just under (or above nothing under) the one that was deleted
|
||||||
|
QModelIndex current_prox_index = proxyModel->mapFromSource(finishedListModel->index(row, 0, finishedList->rootIndex()));
|
||||||
|
bool was_selected = finishedList->selectionModel()->isSelected(current_prox_index);
|
||||||
|
if(finishedListModel->rowCount() > 1 && was_selected) {
|
||||||
|
QModelIndex under_prox_index;
|
||||||
|
if(current_prox_index.row() == finishedListModel->rowCount()-1)
|
||||||
|
under_prox_index = proxyModel->index(current_prox_index.row()-1, 0);
|
||||||
|
else
|
||||||
|
under_prox_index = proxyModel->index(current_prox_index.row()+1, 0);
|
||||||
|
//downloadList->selectionModel()->select(under_prox_index, QItemSelectionModel::Current|QItemSelectionModel::Columns|QItemSelectionModel::Select);
|
||||||
|
finishedList->setCurrentIndex(under_prox_index);
|
||||||
|
finishedList->update();
|
||||||
|
}
|
||||||
|
// Actually delete the row
|
||||||
|
finishedListModel->removeRow(row);
|
||||||
|
--nbFinished;
|
||||||
|
emit finishedTorrentsNumberChanged(nbFinished);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show torrent properties dialog
|
||||||
|
void FinishedTorrents::showProperties(const QModelIndex &index){
|
||||||
|
showPropertiesFromHash(getHashFromRow(index.row()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FinishedTorrents::showPropertiesFromHash(QString hash){
|
||||||
|
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
||||||
|
properties *prop = new properties(this, BTSession, h);
|
||||||
|
connect(prop, SIGNAL(filteredFilesChanged(QString)), this, SLOT(updateFileSize(QString)));
|
||||||
|
connect(prop, SIGNAL(trackersChanged(QString)), BTSession, SLOT(saveTrackerFile(QString)));
|
||||||
|
prop->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FinishedTorrents::updateFileSize(QString hash){
|
||||||
|
int row = getRowFromHash(hash);
|
||||||
|
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
||||||
|
finishedListModel->setData(finishedListModel->index(row, F_SIZE), QVariant((qlonglong)h.actual_size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// display properties of selected items
|
||||||
|
void FinishedTorrents::propertiesSelection(){
|
||||||
|
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
|
||||||
|
foreach(const QModelIndex &index, selectedIndexes){
|
||||||
|
if(index.column() == F_NAME){
|
||||||
|
showProperties(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FinishedTorrents::forceRecheck(){
|
||||||
|
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
|
||||||
|
foreach(const QModelIndex &index, selectedIndexes){
|
||||||
|
if(index.column() == F_NAME){
|
||||||
|
QString hash = getHashFromRow(index.row());
|
||||||
|
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
||||||
|
qDebug("Forcing recheck for torrent %s", hash.toLocal8Bit().data());
|
||||||
|
h.force_recheck();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FinishedTorrents::displayFinishedListMenu(const QPoint&){
|
||||||
|
QMenu myFinishedListMenu(this);
|
||||||
|
// Enable/disable pause/start action given the DL state
|
||||||
|
QModelIndexList selectedIndexes = finishedList->selectionModel()->selectedIndexes();
|
||||||
|
bool has_pause = false, has_start = false, has_preview = false;
|
||||||
|
foreach(const QModelIndex &index, selectedIndexes) {
|
||||||
|
if(index.column() == F_NAME) {
|
||||||
|
// Get the file name
|
||||||
|
QString hash = getHashFromRow(index.row());
|
||||||
|
// Get handle and pause the torrent
|
||||||
|
QTorrentHandle h = BTSession->getTorrentHandle(hash);
|
||||||
|
if(!h.is_valid()) continue;
|
||||||
|
if(h.is_paused()) {
|
||||||
|
if(!has_start) {
|
||||||
|
myFinishedListMenu.addAction(actionStart);
|
||||||
|
has_start = true;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(!has_pause) {
|
||||||
|
myFinishedListMenu.addAction(actionPause);
|
||||||
|
has_pause = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(BTSession->isFilePreviewPossible(hash) && !has_preview) {
|
||||||
|
myFinishedListMenu.addAction(actionPreview_file);
|
||||||
|
has_preview = true;
|
||||||
|
}
|
||||||
|
if(has_pause && has_start && has_preview) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
myFinishedListMenu.addSeparator();
|
||||||
|
myFinishedListMenu.addAction(actionDelete);
|
||||||
|
myFinishedListMenu.addAction(actionDelete_Permanently);
|
||||||
|
myFinishedListMenu.addSeparator();
|
||||||
|
myFinishedListMenu.addAction(actionSet_upload_limit);
|
||||||
|
myFinishedListMenu.addSeparator();
|
||||||
|
myFinishedListMenu.addAction(actionForce_recheck);
|
||||||
|
myFinishedListMenu.addSeparator();
|
||||||
|
myFinishedListMenu.addAction(actionOpen_destination_folder);
|
||||||
|
myFinishedListMenu.addAction(actionTorrent_Properties);
|
||||||
|
myFinishedListMenu.addSeparator();
|
||||||
|
myFinishedListMenu.addAction(actionCopy_magnet_link);
|
||||||
|
myFinishedListMenu.addAction(actionBuy_it);
|
||||||
|
|
||||||
|
// Call menu
|
||||||
|
myFinishedListMenu.exec(QCursor::pos());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hiding Columns functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
// hide/show columns menu
|
||||||
|
void FinishedTorrents::displayFinishedHoSMenu(const QPoint&){
|
||||||
|
QMenu hideshowColumn(this);
|
||||||
|
hideshowColumn.setTitle(tr("Hide or Show Column"));
|
||||||
|
int lastCol = F_RATIO;
|
||||||
|
for(int i=0; i<=lastCol; i++) {
|
||||||
|
hideshowColumn.addAction(getActionHoSCol(i));
|
||||||
|
}
|
||||||
|
// Call menu
|
||||||
|
hideshowColumn.exec(QCursor::pos());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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/oxygen/button_cancel.png")));
|
||||||
|
--nbVisibleColumns;
|
||||||
|
} else {
|
||||||
|
// User want to display the column
|
||||||
|
finishedList->setColumnHidden(index, false);
|
||||||
|
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/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::hideOrShowColumnSwarm() {
|
||||||
|
hideOrShowColumn(F_SWARM);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FinishedTorrents::hideOrShowColumnPeers() {
|
||||||
|
hideOrShowColumn(F_PEERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FinishedTorrents::hideOrShowColumnUpload() {
|
||||||
|
hideOrShowColumn(F_UPLOAD);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FinishedTorrents::hideOrShowColumnRatio() {
|
||||||
|
hideOrShowColumn(F_RATIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// load the previous settings, and hide the columns
|
||||||
|
bool FinishedTorrents::loadHiddenColumns() {
|
||||||
|
bool loaded = false;
|
||||||
|
QSettings settings("qBittorrent", "qBittorrent");
|
||||||
|
QString line = settings.value("FinishedListColsHoS", QString()).toString();
|
||||||
|
QStringList ishidden_list;
|
||||||
|
if(!line.isEmpty()) {
|
||||||
|
ishidden_list = line.split(' ');
|
||||||
|
if(ishidden_list.size() == finishedListModel->columnCount()-1) {
|
||||||
|
unsigned int listSize = ishidden_list.size();
|
||||||
|
for(unsigned int i=0; i<listSize; ++i){
|
||||||
|
finishedList->header()->resizeSection(i, ishidden_list.at(i).toInt());
|
||||||
|
}
|
||||||
|
loaded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int i=0; i<finishedListModel->columnCount()-1; i++) {
|
||||||
|
if(loaded && ishidden_list.at(i) == "0") {
|
||||||
|
finishedList->setColumnHidden(i, true);
|
||||||
|
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/button_cancel.png")));
|
||||||
|
} else {
|
||||||
|
getActionHoSCol(i)->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/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_SWARM :
|
||||||
|
return actionHOSColSwarm;
|
||||||
|
break;
|
||||||
|
case F_PEERS :
|
||||||
|
return actionHOSColPeers;
|
||||||
|
break;
|
||||||
|
case F_UPLOAD :
|
||||||
|
return actionHOSColUpload;
|
||||||
|
break;
|
||||||
|
case F_RATIO :
|
||||||
|
return actionHOSColRatio;
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
104
src/FinishedTorrents.h
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*
|
||||||
|
* Contact : chris@qbittorrent.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SEEDING_H
|
||||||
|
#define SEEDING_H
|
||||||
|
|
||||||
|
#include "ui_seeding.h"
|
||||||
|
#include "qtorrenthandle.h"
|
||||||
|
|
||||||
|
class QStandardItemModel;
|
||||||
|
class QSortFilterProxyModel;
|
||||||
|
class bittorrent;
|
||||||
|
class FinishedListDelegate;
|
||||||
|
|
||||||
|
using namespace libtorrent;
|
||||||
|
|
||||||
|
class FinishedTorrents : public QWidget, public Ui::seeding {
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
QObject *parent;
|
||||||
|
bittorrent *BTSession;
|
||||||
|
FinishedListDelegate *finishedListDelegate;
|
||||||
|
QStandardItemModel *finishedListModel;
|
||||||
|
QSortFilterProxyModel *proxyModel;
|
||||||
|
unsigned int nbFinished;
|
||||||
|
void hideOrShowColumn(int index);
|
||||||
|
bool loadHiddenColumns();
|
||||||
|
void saveHiddenColumns();
|
||||||
|
QAction* getActionHoSCol(int index);
|
||||||
|
|
||||||
|
public:
|
||||||
|
FinishedTorrents(QObject *parent, bittorrent *BTSession);
|
||||||
|
~FinishedTorrents();
|
||||||
|
// Methods
|
||||||
|
bool loadColWidthFinishedList();
|
||||||
|
int getRowFromHash(QString hash) const;
|
||||||
|
QStringList getSelectedTorrents(bool only_one=false) const;
|
||||||
|
unsigned int getNbTorrentsInList() const;
|
||||||
|
QString getHashFromRow(unsigned int row) const;
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void showProperties(const QModelIndex &index);
|
||||||
|
void displayFinishedListMenu(const QPoint&);
|
||||||
|
void displayFinishedHoSMenu(const QPoint&);
|
||||||
|
void setRowColor(int row, QString color);
|
||||||
|
void saveColWidthFinishedList() const;
|
||||||
|
void updateFileSize(QString hash);
|
||||||
|
void on_actionSet_upload_limit_triggered();
|
||||||
|
void notifyTorrentDoubleClicked(const QModelIndex& index);
|
||||||
|
void hideOrShowColumnName();
|
||||||
|
void hideOrShowColumnSize();
|
||||||
|
void hideOrShowColumnUpSpeed();
|
||||||
|
void hideOrShowColumnSwarm();
|
||||||
|
void hideOrShowColumnPeers();
|
||||||
|
void hideOrShowColumnUpload();
|
||||||
|
void hideOrShowColumnRatio();
|
||||||
|
void forceRecheck();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void addTorrent(QString hash);
|
||||||
|
void updateTorrent(QTorrentHandle h);
|
||||||
|
void pauseTorrent(QString hash);
|
||||||
|
void propertiesSelection();
|
||||||
|
void deleteTorrent(QString hash);
|
||||||
|
void showPropertiesFromHash(QString hash);
|
||||||
|
void loadLastSortedColumn();
|
||||||
|
void saveLastSortedColumn();
|
||||||
|
void updateMetadata(QTorrentHandle &h);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void torrentMovedFromFinishedList(QString);
|
||||||
|
void torrentDoubleClicked(QString hash, bool finished);
|
||||||
|
void finishedTorrentsNumberChanged(unsigned int);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
1670
src/GUI.cpp
Normal file
213
src/GUI.h
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the copyright holders give permission to
|
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||||
|
* and distribute the linked executables. You must obey the GNU General Public
|
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||||
|
* modify file(s), you may extend this exception to your version of the file(s),
|
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||||
|
* exception statement from your version.
|
||||||
|
*
|
||||||
|
* Contact : chris@qbittorrent.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GUI_H
|
||||||
|
#define GUI_H
|
||||||
|
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QSystemTrayIcon>
|
||||||
|
#include <QPointer>
|
||||||
|
#include "ui_MainWindow.h"
|
||||||
|
#include "qtorrenthandle.h"
|
||||||
|
|
||||||
|
class bittorrent;
|
||||||
|
class createtorrent;
|
||||||
|
class QTimer;
|
||||||
|
class DownloadingTorrents;
|
||||||
|
class FinishedTorrents;
|
||||||
|
class downloadFromURL;
|
||||||
|
class SearchEngine;
|
||||||
|
#ifdef QT_4_4
|
||||||
|
class QLocalServer;
|
||||||
|
class QLocalSocket;
|
||||||
|
#else
|
||||||
|
class QTcpServer;
|
||||||
|
class QTcpSocket;
|
||||||
|
#endif
|
||||||
|
class QCloseEvent;
|
||||||
|
class RSSImp;
|
||||||
|
class QShortcut;
|
||||||
|
class about;
|
||||||
|
class previewSelect;
|
||||||
|
class options_imp;
|
||||||
|
class QTabWidget;
|
||||||
|
class QLabel;
|
||||||
|
class QModelIndex;
|
||||||
|
class HttpServer;
|
||||||
|
class QFrame;
|
||||||
|
|
||||||
|
class GUI : public QMainWindow, private Ui::MainWindow{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Bittorrent
|
||||||
|
bittorrent *BTSession;
|
||||||
|
QTimer *checkConnect;
|
||||||
|
QTimer *scrapeTimer;
|
||||||
|
QList<QPair<QTorrentHandle,QString> > unauthenticated_trackers;
|
||||||
|
// GUI related
|
||||||
|
QTabWidget *tabs;
|
||||||
|
QPointer<options_imp> options;
|
||||||
|
QSystemTrayIcon *myTrayIcon;
|
||||||
|
QPointer<QTimer> systrayCreator;
|
||||||
|
QMenu *myTrayIconMenu;
|
||||||
|
DownloadingTorrents *downloadingTorrentTab;
|
||||||
|
FinishedTorrents *finishedTorrentTab;
|
||||||
|
QLabel *connecStatusLblIcon;
|
||||||
|
bool systrayIntegration;
|
||||||
|
bool displaySpeedInTitle;
|
||||||
|
bool force_exit;
|
||||||
|
unsigned int refreshInterval;
|
||||||
|
QTimer *refresher;
|
||||||
|
QLabel *dlSpeedLbl;
|
||||||
|
QLabel *upSpeedLbl;
|
||||||
|
QLabel *ratioLbl;
|
||||||
|
QLabel *DHTLbl;
|
||||||
|
QFrame *statusSep1;
|
||||||
|
QFrame *statusSep2;
|
||||||
|
QFrame *statusSep3;
|
||||||
|
QFrame *statusSep4;
|
||||||
|
// Keyboard shortcuts
|
||||||
|
QShortcut *switchSearchShortcut;
|
||||||
|
QShortcut *switchSearchShortcut2;
|
||||||
|
QShortcut *switchDownShortcut;
|
||||||
|
QShortcut *switchUpShortcut;
|
||||||
|
QShortcut *switchRSSShortcut;
|
||||||
|
QAction *prioSeparator;
|
||||||
|
QAction *prioSeparator2;
|
||||||
|
// Search
|
||||||
|
SearchEngine *searchEngine;
|
||||||
|
// RSS
|
||||||
|
RSSImp *rssWidget;
|
||||||
|
// Web UI
|
||||||
|
QPointer<HttpServer> httpServer;
|
||||||
|
// Misc
|
||||||
|
#ifdef QT_4_4
|
||||||
|
QLocalServer *localServer;
|
||||||
|
QLocalSocket *clientConnection;
|
||||||
|
#else
|
||||||
|
QTcpServer *localServer;
|
||||||
|
QTcpSocket *clientConnection;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
// GUI related slots
|
||||||
|
void dropEvent(QDropEvent *event);
|
||||||
|
void dragEnterEvent(QDragEnterEvent *event);
|
||||||
|
void toggleVisibility(QSystemTrayIcon::ActivationReason e);
|
||||||
|
void on_actionAbout_triggered();
|
||||||
|
void on_actionCreate_torrent_triggered();
|
||||||
|
void on_actionWebsite_triggered() const;
|
||||||
|
void on_actionBugReport_triggered() const;
|
||||||
|
void on_actionShow_console_triggered();
|
||||||
|
void readParamsOnSocket();
|
||||||
|
void acceptConnection();
|
||||||
|
void togglePausedState(QString hash);
|
||||||
|
void torrentDoubleClicked(QString hash, bool finished);
|
||||||
|
void on_actionPreview_file_triggered();
|
||||||
|
void previewFile(QString filePath);
|
||||||
|
void balloonClicked();
|
||||||
|
void writeSettings();
|
||||||
|
void readSettings();
|
||||||
|
void on_actionExit_triggered();
|
||||||
|
void createTrayIcon();
|
||||||
|
void updateUnfinishedTorrentNumber(unsigned int nb);
|
||||||
|
void updateFinishedTorrentNumber(unsigned int nb);
|
||||||
|
void fullDiskError(QTorrentHandle& h, QString msg) const;
|
||||||
|
void handleDownloadFromUrlFailure(QString, QString) const;
|
||||||
|
void createSystrayDelayed();
|
||||||
|
void setPaused(QTorrentHandle &h) const;
|
||||||
|
// Keyboard shortcuts
|
||||||
|
void createKeyboardShortcuts();
|
||||||
|
void displayDownTab() const;
|
||||||
|
void displayUpTab() const;
|
||||||
|
void displaySearchTab() const;
|
||||||
|
void displayRSSTab() const;
|
||||||
|
// Torrent actions
|
||||||
|
void on_actionTorrent_Properties_triggered();
|
||||||
|
void on_actionPause_triggered();
|
||||||
|
void on_actionPause_All_triggered();
|
||||||
|
void on_actionStart_triggered();
|
||||||
|
void on_actionStart_All_triggered();
|
||||||
|
void on_actionOpen_triggered();
|
||||||
|
void on_actionDelete_Permanently_triggered();
|
||||||
|
void on_actionDelete_triggered();
|
||||||
|
void on_actionSet_global_upload_limit_triggered();
|
||||||
|
void on_actionSet_global_download_limit_triggered();
|
||||||
|
void on_actionDocumentation_triggered() const;
|
||||||
|
void checkConnectionStatus();
|
||||||
|
void configureSession(bool deleteOptions);
|
||||||
|
void processParams(const QStringList& params);
|
||||||
|
void addTorrent(QString path);
|
||||||
|
void addUnauthenticatedTracker(QPair<QTorrentHandle,QString> tracker);
|
||||||
|
void processDownloadedFiles(QString path, QString url);
|
||||||
|
void downloadFromURLList(const QStringList& urls);
|
||||||
|
void deleteTorrent(QString hash);
|
||||||
|
void finishedTorrent(QTorrentHandle& h) const;
|
||||||
|
void addedTorrent(QTorrentHandle& h) const;
|
||||||
|
void checkedTorrent(QTorrentHandle& h) const;
|
||||||
|
void pausedTorrent(QTorrentHandle& h) const;
|
||||||
|
void resumedTorrent(QTorrentHandle& h) const;
|
||||||
|
void updateLists(bool force=false);
|
||||||
|
bool initWebUi(QString username, QString password, int port);
|
||||||
|
void on_actionIncreasePriority_triggered();
|
||||||
|
void on_actionDecreasePriority_triggered();
|
||||||
|
void scrapeTrackers();
|
||||||
|
// Options slots
|
||||||
|
void on_actionOptions_triggered();
|
||||||
|
void OptionsSaved(bool deleteOptions);
|
||||||
|
// HTTP slots
|
||||||
|
void on_actionDownload_from_URL_triggered();
|
||||||
|
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void trackerAuthenticationRequired(QTorrentHandle& h);
|
||||||
|
void setTabText(int index, QString text) const;
|
||||||
|
void openDestinationFolder() const;
|
||||||
|
void goBuyPage() const;
|
||||||
|
void copyMagnetURI() const;
|
||||||
|
void updateRatio();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void closeEvent(QCloseEvent *);
|
||||||
|
void showEvent(QShowEvent *);
|
||||||
|
bool event(QEvent * event);
|
||||||
|
void displayRSSTab(bool enable);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Construct / Destruct
|
||||||
|
GUI(QWidget *parent=0, QStringList torrentCmdLine=QStringList());
|
||||||
|
~GUI();
|
||||||
|
// Methods
|
||||||
|
int getCurrentTabIndex() const;
|
||||||
|
QPoint screenCenter() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
Before Width: | Height: | Size: 322 B |
BIN
src/Icons/L.gif
|
Before Width: | Height: | Size: 66 B |
BIN
src/Icons/downarrow.png
Normal file
|
After Width: | Height: | Size: 722 B |
|
Before Width: | Height: | Size: 643 B |
|
Before Width: | Height: | Size: 408 B |
|
Before Width: | Height: | Size: 604 B |
|
Before Width: | Height: | Size: 591 B |
|
Before Width: | Height: | Size: 643 B |
|
Before Width: | Height: | Size: 600 B |
|
Before Width: | Height: | Size: 497 B |
|
Before Width: | Height: | Size: 488 B |
|
Before Width: | Height: | Size: 428 B |
|
Before Width: | Height: | Size: 506 B |
|
Before Width: | Height: | Size: 647 B |
|
Before Width: | Height: | Size: 403 B |
|
Before Width: | Height: | Size: 673 B |
|
Before Width: | Height: | Size: 524 B |
|
Before Width: | Height: | Size: 663 B |
|
Before Width: | Height: | Size: 589 B |
|
Before Width: | Height: | Size: 593 B |
|
Before Width: | Height: | Size: 585 B |
|
Before Width: | Height: | Size: 504 B |
|
Before Width: | Height: | Size: 449 B |
|
Before Width: | Height: | Size: 497 B |
|
Before Width: | Height: | Size: 462 B |
|
Before Width: | Height: | Size: 457 B |
|
Before Width: | Height: | Size: 675 B |
|
Before Width: | Height: | Size: 486 B |
|
Before Width: | Height: | Size: 611 B |
|
Before Width: | Height: | Size: 639 B |
|
Before Width: | Height: | Size: 500 B |
|
Before Width: | Height: | Size: 593 B |
BIN
src/Icons/flags/brazil.png
Normal file
|
After Width: | Height: | Size: 799 B |
|
Before Width: | Height: | Size: 526 B |
|
Before Width: | Height: | Size: 631 B |
BIN
src/Icons/flags/bulgaria.png
Normal file
|
After Width: | Height: | Size: 200 B |
|
Before Width: | Height: | Size: 512 B |
|
Before Width: | Height: | Size: 443 B |
|
Before Width: | Height: | Size: 514 B |
|
Before Width: | Height: | Size: 600 B |
|
Before Width: | Height: | Size: 628 B |
|
Before Width: | Height: | Size: 625 B |
|
Before Width: | Height: | Size: 528 B |
|
Before Width: | Height: | Size: 614 B |
|
Before Width: | Height: | Size: 521 B |
|
Before Width: | Height: | Size: 367 B |
BIN
src/Icons/flags/china.png
Normal file
|
After Width: | Height: | Size: 329 B |
|
Before Width: | Height: | Size: 453 B |
|
Before Width: | Height: | Size: 586 B |
|
Before Width: | Height: | Size: 450 B |
|
Before Width: | Height: | Size: 525 B |
|
Before Width: | Height: | Size: 472 B |
|
Before Width: | Height: | Size: 483 B |
|
Before Width: | Height: | Size: 477 B |
|
Before Width: | Height: | Size: 423 B |
|
Before Width: | Height: | Size: 563 B |
|
Before Width: | Height: | Size: 529 B |
|
Before Width: | Height: | Size: 608 B |
|
Before Width: | Height: | Size: 428 B |
|
Before Width: | Height: | Size: 476 B |
BIN
src/Icons/flags/czech.png
Normal file
|
After Width: | Height: | Size: 455 B |
|
Before Width: | Height: | Size: 545 B |
BIN
src/Icons/flags/denmark.png
Normal file
|
After Width: | Height: | Size: 270 B |
|
Before Width: | Height: | Size: 572 B |
|
Before Width: | Height: | Size: 495 B |
|
Before Width: | Height: | Size: 620 B |