Compare commits
209 Commits
release-2.
...
release-2.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89906d16d5 | ||
|
|
a83fbf5a98 | ||
|
|
328e4fd860 | ||
|
|
b98d0282ce | ||
|
|
166dad51d5 | ||
|
|
e3ccea3b17 | ||
|
|
8a64a6441e | ||
|
|
c34000ab17 | ||
|
|
90dd337069 | ||
|
|
31e4b8dc31 | ||
|
|
5145abe5c8 | ||
|
|
7ec842929a | ||
|
|
39778baaf5 | ||
|
|
0a510db95e | ||
|
|
c73243b0d2 | ||
|
|
46b75b760f | ||
|
|
fc3ae51122 | ||
|
|
05d9f28f8b | ||
|
|
b1b2a2c775 | ||
|
|
105de3161a | ||
|
|
354d968a94 | ||
|
|
f617b74bac | ||
|
|
3664134e02 | ||
|
|
1875846326 | ||
|
|
64f0adc813 | ||
|
|
a9d4b38bd3 | ||
|
|
44fa7388d5 | ||
|
|
24df142b02 | ||
|
|
958b73f2cb | ||
|
|
1962898e24 | ||
|
|
56b88661bc | ||
|
|
5b47a762ac | ||
|
|
a5c6bcceea | ||
|
|
290932e128 | ||
|
|
f53fe96191 | ||
|
|
fc8a822dac | ||
|
|
b7a3ae2b4c | ||
|
|
26d19b33e6 | ||
|
|
4ba9dc1fed | ||
|
|
2c3f99692d | ||
|
|
a27d2dcac2 | ||
|
|
f7cb6a7da5 | ||
|
|
6855edf649 | ||
|
|
aff27558dd | ||
|
|
f6172f8c77 | ||
|
|
1562088bc8 | ||
|
|
67973515d5 | ||
|
|
7867cf68f9 | ||
|
|
1eb26bd78b | ||
|
|
a8d635f7ac | ||
|
|
289ad37f06 | ||
|
|
94de42bf2e | ||
|
|
ca9f40eb7f | ||
|
|
4013f9fefd | ||
|
|
ccf0002c0f | ||
|
|
86fb4a323a | ||
|
|
38c56a2b5f | ||
|
|
2d1286158a | ||
|
|
6e7309316c | ||
|
|
593fdad426 | ||
|
|
933a831eb1 | ||
|
|
7c55082464 | ||
|
|
fa3e70316e | ||
|
|
c9c2ab320d | ||
|
|
53d9817d8a | ||
|
|
828ecb6b3c | ||
|
|
af61ed7c72 | ||
|
|
1e86ea8c0a | ||
|
|
129bfac549 | ||
|
|
4815bb9f11 | ||
|
|
81eb8b1341 | ||
|
|
1596dc5206 | ||
|
|
76a22fabcd | ||
|
|
3d7bf26f85 | ||
|
|
69661406a0 | ||
|
|
74fba0fb7e | ||
|
|
d56fc9fcd4 | ||
|
|
124dcee7b8 | ||
|
|
b5b06ce36d | ||
|
|
ef01088411 | ||
|
|
bc87c1c409 | ||
|
|
bbe4328c06 | ||
|
|
d557410156 | ||
|
|
a150e24ce4 | ||
|
|
261d02863c | ||
|
|
c64f02c9bf | ||
|
|
790db14b51 | ||
|
|
2500ac2cb7 | ||
|
|
cd8a7cf0e0 | ||
|
|
b3be32126d | ||
|
|
643bc5516c | ||
|
|
eb94c59892 | ||
|
|
72f4c81f4c | ||
|
|
9543bd63f9 | ||
|
|
7ae7a71782 | ||
|
|
8994ca6dd5 | ||
|
|
354dceeaf0 | ||
|
|
50c7225c1e | ||
|
|
44d945b5c0 | ||
|
|
4ff6104601 | ||
|
|
80760dd7af | ||
|
|
7835a13573 | ||
|
|
9b26fd50b2 | ||
|
|
eb54d81c5e | ||
|
|
431d2f082c | ||
|
|
a0ff0cdc7e | ||
|
|
fb91558261 | ||
|
|
fc2a47ca31 | ||
|
|
dcccbaad59 | ||
|
|
99d040de3f | ||
|
|
ee30a75b57 | ||
|
|
8c001aa478 | ||
|
|
849bc11a01 | ||
|
|
5024e0b092 | ||
|
|
d93447489b | ||
|
|
33988e70ab | ||
|
|
d2b41d70c8 | ||
|
|
8e1e51d268 | ||
|
|
53500ea005 | ||
|
|
e048389dea | ||
|
|
fa7b1a205d | ||
|
|
7dd6b7e9bb | ||
|
|
78b96accda | ||
|
|
73d0e2568a | ||
|
|
92fc212a0e | ||
|
|
6f4d7b7c1b | ||
|
|
63ee1c36e8 | ||
|
|
7d07debcb5 | ||
|
|
dd67e1ee9d | ||
|
|
493efdbf10 | ||
|
|
e323175275 | ||
|
|
c1fa7f8645 | ||
|
|
275b962363 | ||
|
|
3847c33017 | ||
|
|
9e21f52213 | ||
|
|
25cf9b33ec | ||
|
|
c7a2d3589f | ||
|
|
d8dd3834c3 | ||
|
|
ee01c2c745 | ||
|
|
e7e5a2b4e9 | ||
|
|
ff16f59be1 | ||
|
|
2cd4937ddc | ||
|
|
0e9abc1762 | ||
|
|
e24ce87946 | ||
|
|
308e358d3f | ||
|
|
d15e6a4847 | ||
|
|
e311239a28 | ||
|
|
df677789d2 | ||
|
|
0af44eadb6 | ||
|
|
85cafe530e | ||
|
|
7609db28f1 | ||
|
|
fefda39284 | ||
|
|
b2f98bd059 | ||
|
|
26c69fe6d4 | ||
|
|
bf4f1a7c37 | ||
|
|
9b0dd39d9d | ||
|
|
66d4cc2ab8 | ||
|
|
0bcbaf6521 | ||
|
|
e074872b24 | ||
|
|
63ec1e618e | ||
|
|
331c15b76c | ||
|
|
d2089c9aad | ||
|
|
3c8326d3b6 | ||
|
|
2d0713ca1d | ||
|
|
afaca423cc | ||
|
|
ff08abe177 | ||
|
|
159be479cc | ||
|
|
f3066b07b5 | ||
|
|
aa58636832 | ||
|
|
5d1a584eac | ||
|
|
7ee9abd646 | ||
|
|
4d977a8d46 | ||
|
|
5c891724c4 | ||
|
|
185af18790 | ||
|
|
fa6da97cf9 | ||
|
|
9503d9b024 | ||
|
|
de7b6ca553 | ||
|
|
1788078594 | ||
|
|
3caf473424 | ||
|
|
5435bd2354 | ||
|
|
1cdb22a7e3 | ||
|
|
95a9424ae7 | ||
|
|
902196a176 | ||
|
|
dbfef8665b | ||
|
|
b3d8f2400f | ||
|
|
c12ae58868 | ||
|
|
4b77bb57ad | ||
|
|
a6b1d308c2 | ||
|
|
b483f09d11 | ||
|
|
bbb5ad31c4 | ||
|
|
3d4c1fe7da | ||
|
|
7a2c0d5d5a | ||
|
|
39d86c5f61 | ||
|
|
e2cdbbb184 | ||
|
|
e83f9245a9 | ||
|
|
52f25c44eb | ||
|
|
1ed565d8e5 | ||
|
|
10801f111b | ||
|
|
efe1655834 | ||
|
|
7f71e3981e | ||
|
|
8113f8df63 | ||
|
|
62f579fdbe | ||
|
|
1d4454c6eb | ||
|
|
310433fb54 | ||
|
|
c0520146e9 | ||
|
|
35f6675d86 | ||
|
|
9494b15bd5 | ||
|
|
3b82120923 | ||
|
|
b9a0adc311 |
2
AUTHORS
@@ -12,7 +12,7 @@ Contributors:
|
||||
* Silvan Scherrer <silvan.scherrer@aroa.ch>
|
||||
|
||||
Code from other projects:
|
||||
* files src/qtsingleapp/*
|
||||
* files src/qtsingleapp/* src/lineedit/*
|
||||
copyright: Nokia Corporation
|
||||
license: LGPL
|
||||
|
||||
|
||||
22
Changelog
@@ -1,4 +1,22 @@
|
||||
* Unreleased - Christophe Dumez <chris@qbittorrent.org> - v2.3.0
|
||||
* Unreleased - Christophe Dumez <chris@qbittorrent.org> - v2.5.0
|
||||
- FEATURE: qBittorrent can now act as a tracker
|
||||
- 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
|
||||
- COSMETIC: Replaced message box by on-screen notification for download errors
|
||||
|
||||
* 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
|
||||
@@ -15,10 +33,12 @@
|
||||
- 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
|
||||
|
||||
2
INSTALL
@@ -10,7 +10,7 @@ qBittorrent - A BitTorrent client in C++ / Qt4
|
||||
will install and execute qBittorrent hopefully without any problems.
|
||||
|
||||
Dependencies:
|
||||
- Qt >= 4.4.0 (libqt-devel, libqtgui, libqtcore, libqtnetwork, libqtxml)
|
||||
- Qt >= 4.5.0 (libqt-devel, libqtgui, libqtcore, libqtnetwork, libqtxml)
|
||||
|
||||
- pkg-config executable
|
||||
|
||||
|
||||
26
configure
vendored
@@ -325,7 +325,7 @@ cat >$1/modules.cpp <<EOT
|
||||
#line 1 "qt4.qcm"
|
||||
/*
|
||||
-----BEGIN QCMOD-----
|
||||
name: Qt >= 4.4
|
||||
name: Qt >= 4.5
|
||||
arg: disable-gui, Disable qBittorrent Graphical user interface for headless running
|
||||
-----END QCMOD-----
|
||||
*/
|
||||
@@ -333,14 +333,14 @@ class qc_qt4 : public ConfObj
|
||||
{
|
||||
public:
|
||||
qc_qt4(Conf *c) : ConfObj(c) {}
|
||||
QString name() const { return "Qt >= 4.4"; }
|
||||
QString shortname() const { return "Qt 4.4"; }
|
||||
QString name() const { return "Qt >= 4.5"; }
|
||||
QString shortname() const { return "Qt 4.5"; }
|
||||
bool exec()
|
||||
{
|
||||
if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) {
|
||||
conf->addDefine("DISABLE_GUI");
|
||||
}
|
||||
return(QT_VERSION >= 0x040400);
|
||||
return(QT_VERSION >= 0x040500);
|
||||
}
|
||||
};
|
||||
#line 1 "pkg-config.qcm"
|
||||
@@ -616,22 +616,22 @@ arg: with-qtsingleapplication=[system|shipped], Use the shipped qtsingleapplicat
|
||||
class qc_qtsingleapplication : public ConfObj
|
||||
{
|
||||
public:
|
||||
qc_qtsingleapplication(Conf *c) : ConfObj(c) {}
|
||||
QString name() const { return "qtsingleapplication library"; }
|
||||
QString shortname() const { return "qtsingleapplication"; }
|
||||
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");
|
||||
bool exec(){
|
||||
QString s;
|
||||
s = conf->getenv("QC_WITH_QTSINGLEAPPLICATION");
|
||||
if(s.compare("system", Qt::CaseInsensitive) == 0) {
|
||||
// System
|
||||
conf->addDefine("USE_SYSTEM_QTSINGLEAPPLICATION");
|
||||
printf(" [system] ");
|
||||
} else {
|
||||
printf(" [shipped] ");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
EOT
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
-----BEGIN QCMOD-----
|
||||
name: Qt >= 4.4
|
||||
name: Qt >= 4.5
|
||||
arg: disable-gui, Disable qBittorrent Graphical user interface for headless running
|
||||
-----END QCMOD-----
|
||||
*/
|
||||
@@ -8,13 +8,13 @@ class qc_qt4 : public ConfObj
|
||||
{
|
||||
public:
|
||||
qc_qt4(Conf *c) : ConfObj(c) {}
|
||||
QString name() const { return "Qt >= 4.4"; }
|
||||
QString shortname() const { return "Qt 4.4"; }
|
||||
QString name() const { return "Qt >= 4.5"; }
|
||||
QString shortname() const { return "Qt 4.5"; }
|
||||
bool exec()
|
||||
{
|
||||
if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) {
|
||||
conf->addDefine("DISABLE_GUI");
|
||||
}
|
||||
return(QT_VERSION >= 0x040400);
|
||||
return(QT_VERSION >= 0x040500);
|
||||
}
|
||||
};
|
||||
|
||||
26
qcm/qtsingleapplication.qcm
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
-----BEGIN QCMOD-----
|
||||
name: libboost
|
||||
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->addDefine("USE_SYSTEM_QTSINGLEAPPLICATION");
|
||||
printf(" [system] ");
|
||||
} else {
|
||||
printf(" [shipped] ");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
298
src/GUI.cpp
27
src/GUI.h
@@ -37,7 +37,7 @@
|
||||
#include "ui_mainwindow.h"
|
||||
#include "qtorrenthandle.h"
|
||||
|
||||
class Bittorrent;
|
||||
class QBtSession;
|
||||
class QTimer;
|
||||
class downloadFromURL;
|
||||
class SearchEngine;
|
||||
@@ -54,9 +54,11 @@ class PropertiesWidget;
|
||||
class StatusBar;
|
||||
class consoleDlg;
|
||||
class about;
|
||||
class createtorrent;
|
||||
class TorrentCreatorDlg;
|
||||
class downloadFromURL;
|
||||
class HidableTabWidget;
|
||||
class LineEdit;
|
||||
class QFileSystemWatcher;
|
||||
|
||||
class GUI : public QMainWindow, private Ui::MainWindow{
|
||||
Q_OBJECT
|
||||
@@ -69,6 +71,7 @@ public:
|
||||
QWidget* getCurrentTabWidget() const;
|
||||
TransferListWidget* getTransferList() const { return transferList; }
|
||||
QMenu* getTrayIconMenu();
|
||||
PropertiesWidget *getProperties() const { return properties; }
|
||||
|
||||
public slots:
|
||||
void trackerAuthenticationRequired(QTorrentHandle& h);
|
||||
@@ -77,6 +80,7 @@ public slots:
|
||||
void downloadFromURLList(const QStringList& urls);
|
||||
void updateAltSpeedsBtn(bool alternative);
|
||||
void updateNbTorrents(unsigned int nb_downloading, unsigned int nb_seeding, unsigned int nb_active, unsigned int nb_inactive, unsigned int nb_paused);
|
||||
void deleteBTSession();
|
||||
|
||||
protected slots:
|
||||
// GUI related slots
|
||||
@@ -97,6 +101,10 @@ protected slots:
|
||||
void handleDownloadFromUrlFailure(QString, QString) const;
|
||||
void createSystrayDelayed();
|
||||
void tab_changed(int);
|
||||
void on_actionLock_qBittorrent_triggered();
|
||||
void defineUILockPassword();
|
||||
bool unlockUI();
|
||||
void notifyOfUpdate(QString);
|
||||
// Keyboard shortcuts
|
||||
void createKeyboardShortcuts();
|
||||
void displayTransferTab() const;
|
||||
@@ -121,6 +129,10 @@ protected slots:
|
||||
void optionsSaved();
|
||||
// HTTP slots
|
||||
void on_actionDownload_from_URL_triggered();
|
||||
#if defined(Q_WS_WIN) || defined(Q_WS_MAC)
|
||||
void handleUpdateCheckFinished(bool update_available, QString new_version);
|
||||
void handleUpdateInstalled(QString error_msg);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *);
|
||||
@@ -130,8 +142,9 @@ protected:
|
||||
void displaySearchTab(bool enable);
|
||||
|
||||
private:
|
||||
QFileSystemWatcher *executable_watcher;
|
||||
// Bittorrent
|
||||
Bittorrent *BTSession;
|
||||
QBtSession *BTSession;
|
||||
QList<QPair<QTorrentHandle,QString> > unauthenticated_trackers; // Still needed?
|
||||
// GUI related
|
||||
QTimer *guiUpdater;
|
||||
@@ -140,7 +153,7 @@ private:
|
||||
QPointer<options_imp> options;
|
||||
QPointer<consoleDlg> console;
|
||||
QPointer<about> aboutDlg;
|
||||
QPointer<createtorrent> createTorrentDlg;
|
||||
QPointer<TorrentCreatorDlg> createTorrentDlg;
|
||||
QPointer<downloadFromURL> downloadFromURLDialog;
|
||||
QPointer<QSystemTrayIcon> systrayIcon;
|
||||
QPointer<QTimer> systrayCreator;
|
||||
@@ -150,6 +163,8 @@ private:
|
||||
PropertiesWidget *properties;
|
||||
bool displaySpeedInTitle;
|
||||
bool force_exit;
|
||||
bool ui_locked;
|
||||
LineEdit *search_filter;
|
||||
// Keyboard shortcuts
|
||||
QShortcut *switchSearchShortcut;
|
||||
QShortcut *switchSearchShortcut2;
|
||||
@@ -160,6 +175,7 @@ private:
|
||||
QAction *prioSeparator2;
|
||||
QSplitter *hSplitter;
|
||||
QSplitter *vSplitter;
|
||||
QMenu *lockMenu;
|
||||
// Search
|
||||
QPointer<SearchEngine> searchEngine;
|
||||
// RSS
|
||||
@@ -170,6 +186,9 @@ private slots:
|
||||
void on_actionRSS_Reader_triggered();
|
||||
void on_actionSpeed_in_title_bar_triggered();
|
||||
void on_actionTop_tool_bar_triggered();
|
||||
void on_actionShutdown_when_downloads_complete_triggered();
|
||||
void on_actionShutdown_qBittorrent_when_downloads_complete_triggered();
|
||||
void on_action_Import_Torrent_triggered();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
BIN
src/Icons/oxygen/encrypted32.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
src/Icons/oxygen/go-bottom.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
src/Icons/oxygen/go-down.png
Normal file
|
After Width: | Height: | Size: 892 B |
BIN
src/Icons/oxygen/go-top.png
Normal file
|
After Width: | Height: | Size: 996 B |
BIN
src/Icons/oxygen/go-up.png
Normal file
|
After Width: | Height: | Size: 929 B |
BIN
src/Icons/qBitTorrentDocument.icns
Normal file
@@ -1,6 +1,6 @@
|
||||
[Desktop Entry]
|
||||
Categories=Qt;Network;P2P;
|
||||
Comment=V2.3.0
|
||||
Comment=V2.5.0
|
||||
Exec=qbittorrent %f
|
||||
GenericName=Bittorrent client
|
||||
GenericName[ar]=العميل Bittorrent
|
||||
|
||||
BIN
src/Icons/skin/arrow-right.gif
Normal file
|
After Width: | Height: | Size: 54 B |
BIN
src/Icons/skin/delete_perm22.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
@@ -10,13 +10,13 @@
|
||||
<string>torrent</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>qbittorrentDocument</string>
|
||||
<string>qBitTorrentDocument</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>BitTorrent Document</string>
|
||||
<key>CFBundleTypeMIMETypes</key>
|
||||
<array>
|
||||
<string>application/x-bittorrent</string>
|
||||
</array>
|
||||
<key>CFBundleTypeMIMETypes</key>
|
||||
<array>
|
||||
<string>application/x-bittorrent</string>
|
||||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSHandlerRank</key>
|
||||
@@ -47,7 +47,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>2.3.0</string>
|
||||
<string>2.5.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
|
||||
6
src/about.qrc
Normal file
@@ -0,0 +1,6 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file>gpl.html</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
439
src/about_imp.h
@@ -11,15 +11,15 @@
|
||||
#include "preferences.h"
|
||||
|
||||
enum AdvSettingsCols {PROPERTY, VALUE};
|
||||
enum AdvSettingsRows {DISK_CACHE, OUTGOING_PORT_MIN, OUTGOING_PORT_MAX, IGNORE_LIMIT_LAN, COUNT_OVERHEAD, RECHECK_COMPLETED, LIST_REFRESH, RESOLVE_COUNTRIES, RESOLVE_HOSTS, MAX_HALF_OPEN, SUPER_SEEDING, NETWORK_IFACE };
|
||||
#define ROW_COUNT 12
|
||||
enum AdvSettingsRows {DISK_CACHE, OUTGOING_PORT_MIN, OUTGOING_PORT_MAX, IGNORE_LIMIT_LAN, COUNT_OVERHEAD, RECHECK_COMPLETED, LIST_REFRESH, RESOLVE_COUNTRIES, RESOLVE_HOSTS, MAX_HALF_OPEN, SUPER_SEEDING, NETWORK_IFACE, PROGRAM_NOTIFICATIONS, TRACKER_STATUS, TRACKER_PORT };
|
||||
#define ROW_COUNT 15
|
||||
|
||||
class AdvancedSettings: public QTableWidget {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QSpinBox *spin_cache, *outgoing_ports_min, *outgoing_ports_max, *spin_list_refresh, *spin_maxhalfopen;
|
||||
QCheckBox *cb_ignore_limits_lan, *cb_count_overhead, *cb_recheck_completed, *cb_resolve_countries, *cb_resolve_hosts, *cb_super_seeding;
|
||||
QSpinBox *spin_cache, *outgoing_ports_min, *outgoing_ports_max, *spin_list_refresh, *spin_maxhalfopen, *spin_tracker_port;
|
||||
QCheckBox *cb_ignore_limits_lan, *cb_count_overhead, *cb_recheck_completed, *cb_resolve_countries, *cb_resolve_hosts, *cb_super_seeding, *cb_program_notifications, *cb_tracker_status;
|
||||
QComboBox *combo_iface;
|
||||
|
||||
public:
|
||||
@@ -52,6 +52,9 @@ public:
|
||||
delete spin_maxhalfopen;
|
||||
delete cb_super_seeding;
|
||||
delete combo_iface;
|
||||
delete cb_program_notifications;
|
||||
delete spin_tracker_port;
|
||||
delete cb_tracker_status;
|
||||
}
|
||||
|
||||
public slots:
|
||||
@@ -85,6 +88,11 @@ public slots:
|
||||
} else {
|
||||
Preferences::setNetworkInterface(combo_iface->currentText());
|
||||
}
|
||||
// Program notification
|
||||
Preferences::useProgramNotification(cb_program_notifications->isChecked());
|
||||
// Tracker
|
||||
Preferences::setTrackerEnabled(cb_tracker_status->isChecked());
|
||||
Preferences::setTrackerPort(spin_tracker_port->value());
|
||||
}
|
||||
|
||||
protected slots:
|
||||
@@ -175,7 +183,7 @@ protected slots:
|
||||
setItem(NETWORK_IFACE, PROPERTY, new QTableWidgetItem(tr("Network Interface (requires restart)")));
|
||||
combo_iface = new QComboBox;
|
||||
combo_iface->addItem(tr("Any interface", "i.e. Any network interface"));
|
||||
const QString ¤t_iface = Preferences::getNetworkInterface();
|
||||
const QString current_iface = Preferences::getNetworkInterface();
|
||||
int i = 1;
|
||||
foreach(const QNetworkInterface& iface, QNetworkInterface::allInterfaces()) {
|
||||
if(iface.name() == "lo") continue;
|
||||
@@ -186,6 +194,26 @@ protected slots:
|
||||
}
|
||||
connect(combo_iface, SIGNAL(currentIndexChanged(int)), this, SLOT(emitSettingsChanged()));
|
||||
setCellWidget(NETWORK_IFACE, VALUE, combo_iface);
|
||||
// Program notifications
|
||||
setItem(PROGRAM_NOTIFICATIONS, PROPERTY, new QTableWidgetItem(tr("Display program notification balloons")));
|
||||
cb_program_notifications = new QCheckBox();
|
||||
connect(cb_program_notifications, SIGNAL(toggled(bool)), this, SLOT(emitSettingsChanged()));
|
||||
cb_program_notifications->setChecked(Preferences::useProgramNotification());
|
||||
setCellWidget(PROGRAM_NOTIFICATIONS, VALUE, cb_program_notifications);
|
||||
// Tracker State
|
||||
setItem(TRACKER_STATUS, PROPERTY, new QTableWidgetItem(tr("Enable embedded tracker")));
|
||||
cb_tracker_status = new QCheckBox();
|
||||
connect(cb_tracker_status, SIGNAL(toggled(bool)), this, SLOT(emitSettingsChanged()));
|
||||
cb_tracker_status->setChecked(Preferences::isTrackerEnabled());
|
||||
setCellWidget(TRACKER_STATUS, VALUE, cb_tracker_status);
|
||||
// Tracker port
|
||||
setItem(TRACKER_PORT, PROPERTY, new QTableWidgetItem(tr("Embedded tracker port")));
|
||||
spin_tracker_port = new QSpinBox();
|
||||
connect(spin_tracker_port, SIGNAL(valueChanged(int)), this, SLOT(emitSettingsChanged()));
|
||||
spin_tracker_port->setMinimum(1);
|
||||
spin_tracker_port->setMaximum(65535);
|
||||
spin_tracker_port->setValue(Preferences::getTrackerPort());
|
||||
setCellWidget(TRACKER_PORT, VALUE, spin_tracker_port);
|
||||
}
|
||||
|
||||
void emitSettingsChanged() {
|
||||
|
||||
2606
src/bittorrent.cpp
@@ -31,7 +31,7 @@
|
||||
#ifndef CONSOLE_H
|
||||
#define CONSOLE_H
|
||||
|
||||
#include "bittorrent.h"
|
||||
#include "qbtsession.h"
|
||||
#include "ui_console.h"
|
||||
|
||||
using namespace libtorrent;
|
||||
@@ -40,10 +40,10 @@ class consoleDlg : public QDialog, private Ui_ConsoleDlg{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
Bittorrent *BTSession;
|
||||
QBtSession *BTSession;
|
||||
|
||||
public:
|
||||
consoleDlg(QWidget *parent, Bittorrent* _BTSession) : QDialog(parent) {
|
||||
consoleDlg(QWidget *parent, QBtSession* _BTSession) : QDialog(parent) {
|
||||
setupUi(this);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setModal(true);
|
||||
|
||||
@@ -51,7 +51,7 @@ class downloadFromURL : public QDialog, private Ui::downloadFromURL{
|
||||
show();
|
||||
// Paste clipboard if there is an URL in it
|
||||
QString clip_txt = qApp->clipboard()->text();
|
||||
if(clip_txt.startsWith("http://", Qt::CaseInsensitive) || clip_txt.startsWith("https://", Qt::CaseInsensitive) || clip_txt.startsWith("ftp://", Qt::CaseInsensitive) || clip_txt.startsWith("magnet:", Qt::CaseInsensitive)) {
|
||||
if(clip_txt.startsWith("http://", Qt::CaseInsensitive) || clip_txt.startsWith("https://", Qt::CaseInsensitive) || clip_txt.startsWith("ftp://", Qt::CaseInsensitive) || clip_txt.startsWith("magnet:", Qt::CaseInsensitive) || clip_txt.startsWith("bc://bt/", Qt::CaseInsensitive)) {
|
||||
textUrls->setText(clip_txt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,8 +39,6 @@
|
||||
#include "preferences.h"
|
||||
#include "qinisettings.h"
|
||||
|
||||
enum ProxyType {HTTP=1, SOCKS5=2, HTTP_PW=3, SOCKS5_PW=4, SOCKS4=5};
|
||||
|
||||
/** Download Thread **/
|
||||
|
||||
downloadThread::downloadThread(QObject* parent) : QObject(parent) {
|
||||
@@ -101,7 +99,7 @@ void downloadThread::processDlFinished(QNetworkReply* reply) {
|
||||
}
|
||||
|
||||
void downloadThread::loadCookies(const QString &host_name, QString url) {
|
||||
const QList<QByteArray> &raw_cookies = Preferences::getHostNameCookies(host_name);
|
||||
const QList<QByteArray> raw_cookies = Preferences::getHostNameCookies(host_name);
|
||||
QNetworkCookieJar *cookie_jar = networkManager.cookieJar();
|
||||
QList<QNetworkCookie> cookies;
|
||||
qDebug("Loading cookies for host name: %s", qPrintable(host_name));
|
||||
@@ -135,7 +133,7 @@ QNetworkReply* downloadThread::downloadUrl(QString url){
|
||||
loadCookies(host_name, url);
|
||||
// Process download request
|
||||
qDebug("url is %s", qPrintable(url));
|
||||
const QUrl &qurl = QUrl::fromEncoded(url.toLocal8Bit());
|
||||
const QUrl qurl = QUrl::fromEncoded(url.toLocal8Bit());
|
||||
QNetworkRequest request(qurl);
|
||||
// Spoof Firefox 3.5 user agent to avoid
|
||||
// Web server banning
|
||||
@@ -180,7 +178,7 @@ void downloadThread::applyProxySettings() {
|
||||
qDebug("Using proxy: %s", qPrintable(IP));
|
||||
proxy.setPort(port.toUShort());
|
||||
// Default proxy type is HTTP, we must change if it is SOCKS5
|
||||
if(intValue == SOCKS5 || intValue == SOCKS5_PW) {
|
||||
if(intValue == Proxy::SOCKS5 || intValue == Proxy::SOCKS5_PW) {
|
||||
qDebug("Proxy is SOCKS5, not HTTP");
|
||||
proxy.setType(QNetworkProxy::Socks5Proxy);
|
||||
} else {
|
||||
|
||||
221
src/feedList.h
@@ -1,221 +0,0 @@
|
||||
#ifndef FEEDLIST_H
|
||||
#define FEEDLIST_H
|
||||
|
||||
#include <QTreeWidget>
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QDropEvent>
|
||||
#include <QDragMoveEvent>
|
||||
#include <QStringList>
|
||||
#include <QHash>
|
||||
#include <QUrl>
|
||||
#include "rss.h"
|
||||
|
||||
class FeedList: public QTreeWidget {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
RssManager *rssmanager;
|
||||
QHash<QTreeWidgetItem*, RssFile*> mapping;
|
||||
QHash<QString, QTreeWidgetItem*> feeds_items;
|
||||
QTreeWidgetItem* current_feed;
|
||||
QTreeWidgetItem *unread_item;
|
||||
|
||||
public:
|
||||
FeedList(QWidget *parent, RssManager *rssmanager): QTreeWidget(parent), rssmanager(rssmanager) {
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
setDragDropMode(QAbstractItemView::InternalMove);
|
||||
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
setColumnCount(1);
|
||||
QTreeWidgetItem *___qtreewidgetitem = headerItem();
|
||||
___qtreewidgetitem->setText(0, QApplication::translate("RSS", "RSS feeds", 0, QApplication::UnicodeUTF8));
|
||||
unread_item = new QTreeWidgetItem(this);
|
||||
unread_item->setText(0, tr("Unread") + QString::fromUtf8(" (") + QString::number(rssmanager->getNbUnRead(), 10)+ QString(")"));
|
||||
unread_item->setData(0,Qt::DecorationRole, QVariant(QIcon(":/Icons/oxygen/mail-folder-inbox.png")));
|
||||
itemAdded(unread_item, rssmanager);
|
||||
connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(updateCurrentFeed(QTreeWidgetItem*)));
|
||||
setCurrentItem(unread_item);
|
||||
}
|
||||
|
||||
~FeedList() {
|
||||
disconnect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(updateCurrentFeed(QTreeWidgetItem*)));
|
||||
delete unread_item;
|
||||
}
|
||||
|
||||
void itemAdded(QTreeWidgetItem *item, RssFile* file) {
|
||||
mapping[item] = file;
|
||||
if(file->getType() == RssFile::STREAM) {
|
||||
feeds_items[file->getID()] = item;
|
||||
}
|
||||
}
|
||||
|
||||
void itemAboutToBeRemoved(QTreeWidgetItem *item) {
|
||||
RssFile* file = mapping.take(item);
|
||||
if(file->getType() == RssFile::STREAM) {
|
||||
feeds_items.remove(file->getID());
|
||||
} else {
|
||||
QList<RssStream*> feeds = ((RssFolder*)file)->getAllFeeds();
|
||||
foreach(RssStream* feed, feeds) {
|
||||
feeds_items.remove(feed->getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool hasFeed(QString url) const {
|
||||
return feeds_items.contains(QUrl(url).toString());
|
||||
}
|
||||
|
||||
QList<QTreeWidgetItem*> getAllFeedItems() const {
|
||||
return feeds_items.values();
|
||||
}
|
||||
|
||||
QTreeWidgetItem* getUnreadItem() const {
|
||||
return unread_item;
|
||||
}
|
||||
|
||||
QStringList getItemPath(QTreeWidgetItem* item) const {
|
||||
QStringList path;
|
||||
if(item) {
|
||||
if(item->parent())
|
||||
path << getItemPath(item->parent());
|
||||
path.append(getRSSItem(item)->getID());
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
QList<QTreeWidgetItem*> getAllOpenFolders(QTreeWidgetItem *parent=0) const {
|
||||
QList<QTreeWidgetItem*> open_folders;
|
||||
int nbChildren;
|
||||
if(parent)
|
||||
nbChildren = parent->childCount();
|
||||
else
|
||||
nbChildren = topLevelItemCount();
|
||||
for(int i=0; i<nbChildren; ++i) {
|
||||
QTreeWidgetItem *item;
|
||||
if(parent)
|
||||
item = parent->child(i);
|
||||
else
|
||||
item = topLevelItem(i);
|
||||
if(getItemType(item) == RssFile::FOLDER && item->isExpanded()) {
|
||||
QList<QTreeWidgetItem*> open_subfolders = getAllOpenFolders(item);
|
||||
if(!open_subfolders.empty()) {
|
||||
open_folders << open_subfolders;
|
||||
} else {
|
||||
open_folders << item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return open_folders;
|
||||
}
|
||||
|
||||
QList<QTreeWidgetItem*> getAllFeedItems(QTreeWidgetItem* folder) {
|
||||
QList<QTreeWidgetItem*> feeds;
|
||||
int nbChildren = folder->childCount();
|
||||
for(int i=0; i<nbChildren; ++i) {
|
||||
QTreeWidgetItem *item = folder->child(i);
|
||||
if(getItemType(item) == RssFile::STREAM) {
|
||||
feeds << item;
|
||||
} else {
|
||||
feeds << getAllFeedItems(item);
|
||||
}
|
||||
}
|
||||
return feeds;
|
||||
}
|
||||
|
||||
RssFile* getRSSItem(QTreeWidgetItem *item) const {
|
||||
return mapping.value(item, 0);
|
||||
}
|
||||
|
||||
RssFile::FileType getItemType(QTreeWidgetItem *item) const {
|
||||
return mapping.value(item)->getType();
|
||||
}
|
||||
|
||||
QString getItemID(QTreeWidgetItem *item) const {
|
||||
return mapping.value(item)->getID();
|
||||
}
|
||||
|
||||
QTreeWidgetItem* getTreeItemFromUrl(QString url) const{
|
||||
return feeds_items.value(url, 0);
|
||||
}
|
||||
|
||||
RssStream* getRSSItemFromUrl(QString url) const {
|
||||
return (RssStream*)getRSSItem(getTreeItemFromUrl(url));
|
||||
}
|
||||
|
||||
QTreeWidgetItem* currentItem() const {
|
||||
return current_feed;
|
||||
}
|
||||
|
||||
QTreeWidgetItem* currentFeed() const {
|
||||
return current_feed;
|
||||
}
|
||||
|
||||
signals:
|
||||
void foldersAltered(QList<QTreeWidgetItem*> folders);
|
||||
void overwriteAttempt(QString filename);
|
||||
|
||||
protected slots:
|
||||
void updateCurrentFeed(QTreeWidgetItem* new_item) {
|
||||
if(!new_item) return;
|
||||
if(!mapping.contains(new_item)) return;
|
||||
if((getItemType(new_item) == RssFile::STREAM) || new_item == unread_item)
|
||||
current_feed = new_item;
|
||||
}
|
||||
|
||||
protected:
|
||||
void dragMoveEvent(QDragMoveEvent * event) {
|
||||
QTreeWidgetItem *item = itemAt(event->pos());
|
||||
if(item == unread_item) {
|
||||
event->ignore();
|
||||
} else {
|
||||
if(item && getItemType(item) != RssFile::FOLDER)
|
||||
event->ignore();
|
||||
else {
|
||||
if(selectedItems().contains(unread_item)) {
|
||||
event->ignore();
|
||||
} else {
|
||||
QTreeWidget::dragMoveEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dropEvent(QDropEvent *event) {
|
||||
qDebug("dropEvent");
|
||||
QList<QTreeWidgetItem*> folders_altered;
|
||||
QTreeWidgetItem *dest_folder_item = itemAt(event->pos());
|
||||
RssFolder *dest_folder;
|
||||
if(dest_folder_item) {
|
||||
dest_folder = (RssFolder*)getRSSItem(dest_folder_item);
|
||||
folders_altered << dest_folder_item;
|
||||
} else {
|
||||
dest_folder = rssmanager;
|
||||
}
|
||||
QList<QTreeWidgetItem *> src_items = selectedItems();
|
||||
// Check if there is not going to overwrite another file
|
||||
foreach(QTreeWidgetItem *src_item, src_items) {
|
||||
RssFile *file = getRSSItem(src_item);
|
||||
if(dest_folder->hasChild(file->getID())) {
|
||||
emit overwriteAttempt(file->getID());
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Proceed with the move
|
||||
foreach(QTreeWidgetItem *src_item, src_items) {
|
||||
QTreeWidgetItem *parent_folder = src_item->parent();
|
||||
if(parent_folder && !folders_altered.contains(parent_folder))
|
||||
folders_altered << parent_folder;
|
||||
// Actually move the file
|
||||
RssFile *file = getRSSItem(src_item);
|
||||
rssmanager->moveFile(file, dest_folder);
|
||||
}
|
||||
QTreeWidget::dropEvent(event);
|
||||
if(dest_folder_item)
|
||||
dest_folder_item->setExpanded(true);
|
||||
// Emit signal for update
|
||||
if(!folders_altered.empty())
|
||||
emit foldersAltered(folders_altered);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // FEEDLIST_H
|
||||
@@ -201,9 +201,14 @@ signals:
|
||||
|
||||
private:
|
||||
void addTorrentsFromDir(const QDir &dir, QStringList &torrents) {
|
||||
const QStringList &files = dir.entryList(filters, QDir::Files, QDir::Unsorted);
|
||||
foreach(const QString &file, files)
|
||||
torrents << dir.canonicalPath() + '/' + file;
|
||||
const QStringList files = dir.entryList(filters, QDir::Files, QDir::Unsorted);
|
||||
foreach(const QString &file, files) {
|
||||
#if defined(Q_WS_WIN) || defined(Q_OS_OS2)
|
||||
torrents << dir.absoluteFilePath(file).replace("/", "\\");
|
||||
#else
|
||||
torrents << dir.absoluteFilePath(file);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -407,9 +407,12 @@ class FilterParserThread : public QThread {
|
||||
// First, import current filter
|
||||
ip_filter filter = s->get_ip_filter();
|
||||
foreach(const QString &ip, IPs) {
|
||||
qDebug("Manual ban of peer %s", ip.toLocal8Bit().data());
|
||||
address_v4 addr = address_v4::from_string(ip.toLocal8Bit().data());
|
||||
filter.add_rule(addr, addr, ip_filter::blocked);
|
||||
qDebug("Manual ban of peer %s", ip.toLocal8Bit().constData());
|
||||
boost::system::error_code ec;
|
||||
address_v4 addr = address_v4::from_string(ip.toLocal8Bit().constData(), ec);
|
||||
Q_ASSERT(!ec);
|
||||
if(!ec)
|
||||
filter.add_rule(addr, addr, ip_filter::blocked);
|
||||
}
|
||||
s->set_ip_filter(filter);
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
using namespace libtorrent;
|
||||
|
||||
class GeoIP : public QObject {
|
||||
Q_OBJECT
|
||||
protected:
|
||||
#ifdef WITH_GEOIP_EMBEDDED
|
||||
static QString geoipFolder(bool embedded=false) {
|
||||
@@ -75,7 +76,7 @@ protected:
|
||||
}
|
||||
// Remove destination files
|
||||
if(QFile::exists(geoipDBpath(false)))
|
||||
QFile::remove(geoipDBpath(false));
|
||||
misc::safeRemove(geoipDBpath(false));
|
||||
// Copy from executable to hard disk
|
||||
qDebug("%s -> %s", qPrintable(geoipDBpath(true)), qPrintable(geoipDBpath(false)));
|
||||
if(!QFile::copy(geoipDBpath(true), geoipDBpath(false))) {
|
||||
|
||||